]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/demo/demo-shape.c
pci: Allow debug message output in pci_auto.c
[karo-tx-uboot.git] / drivers / demo / demo-shape.c
1 /*
2  * Copyright (c) 2013 Google, Inc
3  *
4  * SPDX-License-Identifier:     GPL-2.0+
5  */
6
7 #include <common.h>
8 #include <dm.h>
9 #include <errno.h>
10 #include <fdtdec.h>
11 #include <malloc.h>
12 #include <dm-demo.h>
13 #include <asm/io.h>
14 #include <asm/gpio.h>
15
16 DECLARE_GLOBAL_DATA_PTR;
17
18 /* Shape size */
19 #define WIDTH   8
20 #define HEIGHT  6
21
22 struct shape_data {
23         int num_chars;  /* Number of non-space characters output so far */
24         struct gpio_desc gpio_desc[8];
25         int gpio_count;
26 };
27
28 /* Crazy little function to draw shapes on the console */
29 static int shape_hello(struct udevice *dev, int ch)
30 {
31         const struct dm_demo_pdata *pdata = dev_get_platdata(dev);
32         struct shape_data *data = dev_get_priv(dev);
33         static const struct shape {
34                 int start;
35                 int end;
36                 int dstart;
37                 int dend;
38         } shapes[3] = {
39                 { 0, 1, 0, 1 },
40                 { 0, WIDTH, 0, 0 },
41                 { HEIGHT / 2 - 1, WIDTH - HEIGHT / 2 + 1, -1, 1},
42         };
43         struct shape shape;
44         unsigned int index;
45         int line, pos, inside;
46         const char *colour = pdata->colour;
47         int first = 0;
48
49         if (!ch)
50                 ch = pdata->default_char;
51         if (!ch)
52                 ch = '@';
53
54         index = (pdata->sides / 2) - 1;
55         if (index >= ARRAY_SIZE(shapes))
56                 return -EIO;
57         shape = shapes[index];
58
59         for (line = 0; line < HEIGHT; line++) {
60                 first = 1;
61                 for (pos = 0; pos < WIDTH; pos++) {
62                         inside = pos >= shape.start && pos < shape.end;
63                         if (inside) {
64                                 putc(first ? *colour++ : ch);
65                                 data->num_chars++;
66                                 first = 0;
67                                 if (!*colour)
68                                         colour = pdata->colour;
69                         } else {
70                                 putc(' ');
71                         }
72                 }
73                 putc('\n');
74                 shape.start += shape.dstart;
75                 shape.end += shape.dend;
76                 if (shape.start < 0) {
77                         shape.dstart = -shape.dstart;
78                         shape.dend = -shape.dend;
79                         shape.start += shape.dstart;
80                         shape.end += shape.dend;
81                 }
82         }
83
84         return 0;
85 }
86
87 static int shape_status(struct udevice *dev, int *status)
88 {
89         struct shape_data *data = dev_get_priv(dev);
90
91         *status = data->num_chars;
92         return 0;
93 }
94
95 static int set_light(struct udevice *dev, int light)
96 {
97         struct shape_data *priv = dev_get_priv(dev);
98         struct gpio_desc *desc;
99         int ret;
100         int i;
101
102         desc = priv->gpio_desc;
103         for (i = 0; i < priv->gpio_count; i++, desc++) {
104                 uint mask = 1 << i;
105
106                 ret = dm_gpio_set_value(desc, light & mask);
107                 if (ret < 0)
108                         return ret;
109         }
110
111         return 0;
112 }
113
114 static int get_light(struct udevice *dev)
115 {
116         struct shape_data *priv = dev_get_priv(dev);
117         struct gpio_desc *desc;
118         uint value = 0;
119         int ret;
120         int i;
121
122         desc = priv->gpio_desc;
123         for (i = 0; i < priv->gpio_count; i++, desc++) {
124                 uint mask = 1 << i;
125
126                 ret = dm_gpio_get_value(desc);
127                 if (ret < 0)
128                         return ret;
129                 if (ret)
130                         value |= mask;
131         }
132
133         return value;
134 }
135
136 static const struct demo_ops shape_ops = {
137         .hello = shape_hello,
138         .status = shape_status,
139         .get_light = get_light,
140         .set_light = set_light,
141 };
142
143 static int shape_ofdata_to_platdata(struct udevice *dev)
144 {
145         struct dm_demo_pdata *pdata = dev_get_platdata(dev);
146         int ret;
147
148         /* Parse the data that is common with all demo devices */
149         ret = demo_parse_dt(dev);
150         if (ret)
151                 return ret;
152
153         /* Parse the data that only we need */
154         pdata->default_char = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
155                                              "character", '@');
156
157         return 0;
158 }
159
160 static int dm_shape_probe(struct udevice *dev)
161 {
162         struct shape_data *priv = dev_get_priv(dev);
163         int ret;
164
165         ret = gpio_request_list_by_name(dev, "light-gpios", priv->gpio_desc,
166                                         ARRAY_SIZE(priv->gpio_desc),
167                                         GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
168         if (ret < 0)
169                 return ret;
170         priv->gpio_count = ret;
171         debug("%s: %d GPIOs\n", __func__, priv->gpio_count);
172
173         return 0;
174 }
175
176 static int dm_shape_remove(struct udevice *dev)
177 {
178         struct shape_data *priv = dev_get_priv(dev);
179
180         return gpio_free_list(dev, priv->gpio_desc, priv->gpio_count);
181 }
182
183 static const struct udevice_id demo_shape_id[] = {
184         { "demo-shape", 0 },
185         { },
186 };
187
188 U_BOOT_DRIVER(demo_shape_drv) = {
189         .name   = "demo_shape_drv",
190         .of_match = demo_shape_id,
191         .id     = UCLASS_DEMO,
192         .ofdata_to_platdata = shape_ofdata_to_platdata,
193         .ops    = &shape_ops,
194         .probe = dm_shape_probe,
195         .remove = dm_shape_remove,
196         .priv_auto_alloc_size = sizeof(struct shape_data),
197         .platdata_auto_alloc_size = sizeof(struct dm_demo_pdata),
198 };