colibri_imx6: fix video stdout in default environment
[oweals/u-boot.git] / drivers / gpio / sandbox.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (c) 2011 The Chromium OS Authors.
4  */
5
6 #include <common.h>
7 #include <dm.h>
8 #include <fdtdec.h>
9 #include <log.h>
10 #include <malloc.h>
11 #include <asm/gpio.h>
12 #include <dm/device_compat.h>
13 #include <dm/lists.h>
14 #include <dm/of.h>
15 #include <dm/pinctrl.h>
16 #include <dt-bindings/gpio/gpio.h>
17 #include <dt-bindings/gpio/sandbox-gpio.h>
18
19
20 struct gpio_state {
21         const char *label;      /* label given by requester */
22         ulong dir_flags;        /* dir_flags (GPIOD_...) */
23 };
24
25 /* Access routines for GPIO dir flags */
26 static ulong *get_gpio_dir_flags(struct udevice *dev, unsigned int offset)
27 {
28         struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
29         struct gpio_state *state = dev_get_priv(dev);
30
31         if (offset >= uc_priv->gpio_count) {
32                 static ulong invalid_dir_flags;
33                 printf("sandbox_gpio: error: invalid gpio %u\n", offset);
34                 return &invalid_dir_flags;
35         }
36
37         return &state[offset].dir_flags;
38
39 }
40
41 static int get_gpio_flag(struct udevice *dev, unsigned int offset, ulong flag)
42 {
43         return (*get_gpio_dir_flags(dev, offset) & flag) != 0;
44 }
45
46 static int set_gpio_flag(struct udevice *dev, unsigned int offset, ulong flag,
47                          int value)
48 {
49         ulong *gpio = get_gpio_dir_flags(dev, offset);
50
51         if (value)
52                 *gpio |= flag;
53         else
54                 *gpio &= ~flag;
55
56         return 0;
57 }
58
59 /*
60  * Back-channel sandbox-internal-only access to GPIO state
61  */
62
63 int sandbox_gpio_get_value(struct udevice *dev, unsigned offset)
64 {
65         if (get_gpio_flag(dev, offset, GPIOD_IS_OUT))
66                 debug("sandbox_gpio: get_value on output gpio %u\n", offset);
67         return get_gpio_flag(dev, offset, GPIOD_IS_OUT_ACTIVE);
68 }
69
70 int sandbox_gpio_set_value(struct udevice *dev, unsigned offset, int value)
71 {
72         return set_gpio_flag(dev, offset, GPIOD_IS_OUT_ACTIVE, value);
73 }
74
75 int sandbox_gpio_get_direction(struct udevice *dev, unsigned offset)
76 {
77         return get_gpio_flag(dev, offset, GPIOD_IS_OUT);
78 }
79
80 int sandbox_gpio_set_direction(struct udevice *dev, unsigned offset, int output)
81 {
82         set_gpio_flag(dev, offset, GPIOD_IS_OUT, output);
83         set_gpio_flag(dev, offset, GPIOD_IS_IN, !(output));
84
85         return 0;
86 }
87
88 ulong sandbox_gpio_get_dir_flags(struct udevice *dev, unsigned int offset)
89 {
90         return *get_gpio_dir_flags(dev, offset);
91 }
92
93 int sandbox_gpio_set_dir_flags(struct udevice *dev, unsigned int offset,
94                                ulong flags)
95 {
96         *get_gpio_dir_flags(dev, offset) = flags;
97
98         return 0;
99 }
100
101 /*
102  * These functions implement the public interface within U-Boot
103  */
104
105 /* set GPIO port 'offset' as an input */
106 static int sb_gpio_direction_input(struct udevice *dev, unsigned offset)
107 {
108         debug("%s: offset:%u\n", __func__, offset);
109
110         return sandbox_gpio_set_direction(dev, offset, 0);
111 }
112
113 /* set GPIO port 'offset' as an output, with polarity 'value' */
114 static int sb_gpio_direction_output(struct udevice *dev, unsigned offset,
115                                     int value)
116 {
117         debug("%s: offset:%u, value = %d\n", __func__, offset, value);
118
119         return sandbox_gpio_set_direction(dev, offset, 1) |
120                 sandbox_gpio_set_value(dev, offset, value);
121 }
122
123 /* read GPIO IN value of port 'offset' */
124 static int sb_gpio_get_value(struct udevice *dev, unsigned offset)
125 {
126         debug("%s: offset:%u\n", __func__, offset);
127
128         return sandbox_gpio_get_value(dev, offset);
129 }
130
131 /* write GPIO OUT value to port 'offset' */
132 static int sb_gpio_set_value(struct udevice *dev, unsigned offset, int value)
133 {
134         debug("%s: offset:%u, value = %d\n", __func__, offset, value);
135
136         if (!sandbox_gpio_get_direction(dev, offset)) {
137                 printf("sandbox_gpio: error: set_value on input gpio %u\n",
138                        offset);
139                 return -1;
140         }
141
142         return sandbox_gpio_set_value(dev, offset, value);
143 }
144
145 static int sb_gpio_get_function(struct udevice *dev, unsigned offset)
146 {
147         if (get_gpio_flag(dev, offset, GPIOD_IS_OUT))
148                 return GPIOF_OUTPUT;
149         if (get_gpio_flag(dev, offset, GPIOD_IS_IN))
150                 return GPIOF_INPUT;
151
152         return GPIOF_INPUT; /*GPIO is not configurated */
153 }
154
155 static int sb_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
156                          struct ofnode_phandle_args *args)
157 {
158         desc->offset = args->args[0];
159         if (args->args_count < 2)
160                 return 0;
161         /* treat generic binding with gpio uclass */
162         gpio_xlate_offs_flags(dev, desc, args);
163
164         /* sandbox test specific, not defined in gpio.h */
165         if (args->args[1] & GPIO_IN)
166                 desc->flags |= GPIOD_IS_IN;
167
168         if (args->args[1] & GPIO_OUT)
169                 desc->flags |= GPIOD_IS_OUT;
170
171         if (args->args[1] & GPIO_OUT_ACTIVE)
172                 desc->flags |= GPIOD_IS_OUT_ACTIVE;
173
174         return 0;
175 }
176
177 static int sb_gpio_set_dir_flags(struct udevice *dev, unsigned int offset,
178                                  ulong flags)
179 {
180         ulong *dir_flags;
181
182         debug("%s: offset:%u, dir_flags = %lx\n", __func__, offset, flags);
183
184         dir_flags = get_gpio_dir_flags(dev, offset);
185
186         *dir_flags = flags;
187
188         return 0;
189 }
190
191 static int sb_gpio_get_dir_flags(struct udevice *dev, unsigned int offset,
192                                  ulong *flags)
193 {
194         debug("%s: offset:%u\n", __func__, offset);
195         *flags = *get_gpio_dir_flags(dev, offset);
196
197         return 0;
198 }
199
200 static const struct dm_gpio_ops gpio_sandbox_ops = {
201         .direction_input        = sb_gpio_direction_input,
202         .direction_output       = sb_gpio_direction_output,
203         .get_value              = sb_gpio_get_value,
204         .set_value              = sb_gpio_set_value,
205         .get_function           = sb_gpio_get_function,
206         .xlate                  = sb_gpio_xlate,
207         .set_dir_flags          = sb_gpio_set_dir_flags,
208         .get_dir_flags          = sb_gpio_get_dir_flags,
209 };
210
211 static int sandbox_gpio_ofdata_to_platdata(struct udevice *dev)
212 {
213         struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
214
215         uc_priv->gpio_count = dev_read_u32_default(dev, "sandbox,gpio-count",
216                                                    0);
217         uc_priv->bank_name = dev_read_string(dev, "gpio-bank-name");
218
219         return 0;
220 }
221
222 static int gpio_sandbox_probe(struct udevice *dev)
223 {
224         struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
225
226         if (!dev_of_valid(dev))
227                 /* Tell the uclass how many GPIOs we have */
228                 uc_priv->gpio_count = CONFIG_SANDBOX_GPIO_COUNT;
229
230         dev->priv = calloc(sizeof(struct gpio_state), uc_priv->gpio_count);
231
232         return 0;
233 }
234
235 static int gpio_sandbox_remove(struct udevice *dev)
236 {
237         free(dev->priv);
238
239         return 0;
240 }
241
242 static const struct udevice_id sandbox_gpio_ids[] = {
243         { .compatible = "sandbox,gpio" },
244         { }
245 };
246
247 U_BOOT_DRIVER(gpio_sandbox) = {
248         .name   = "gpio_sandbox",
249         .id     = UCLASS_GPIO,
250         .of_match = sandbox_gpio_ids,
251         .ofdata_to_platdata = sandbox_gpio_ofdata_to_platdata,
252         .probe  = gpio_sandbox_probe,
253         .remove = gpio_sandbox_remove,
254         .ops    = &gpio_sandbox_ops,
255 };
256
257 /* pincontrol: used only to check GPIO pin configuration (pinmux command) */
258
259 struct sb_pinctrl_priv {
260         int pinctrl_ngpios;
261         struct list_head gpio_dev;
262 };
263
264 struct sb_gpio_bank {
265         struct udevice *gpio_dev;
266         struct list_head list;
267 };
268
269 static int sb_populate_gpio_dev_list(struct udevice *dev)
270 {
271         struct sb_pinctrl_priv *priv = dev_get_priv(dev);
272         struct udevice *gpio_dev;
273         struct udevice *child;
274         struct sb_gpio_bank *gpio_bank;
275         int ret;
276
277         /*
278          * parse pin-controller sub-nodes (ie gpio bank nodes) and fill
279          * a list with all gpio device reference which belongs to the
280          * current pin-controller. This list is used to find pin_name and
281          * pin muxing
282          */
283         list_for_each_entry(child, &dev->child_head, sibling_node) {
284                 ret = uclass_get_device_by_name(UCLASS_GPIO, child->name,
285                                                 &gpio_dev);
286                 if (ret < 0)
287                         continue;
288
289                 gpio_bank = malloc(sizeof(*gpio_bank));
290                 if (!gpio_bank) {
291                         dev_err(dev, "Not enough memory\n");
292                         return -ENOMEM;
293                 }
294
295                 gpio_bank->gpio_dev = gpio_dev;
296                 list_add_tail(&gpio_bank->list, &priv->gpio_dev);
297         }
298
299         return 0;
300 }
301
302 static int sb_pinctrl_get_pins_count(struct udevice *dev)
303 {
304         struct sb_pinctrl_priv *priv = dev_get_priv(dev);
305         struct gpio_dev_priv *uc_priv;
306         struct sb_gpio_bank *gpio_bank;
307
308         /*
309          * if get_pins_count has already been executed once on this
310          * pin-controller, no need to run it again
311          */
312         if (priv->pinctrl_ngpios)
313                 return priv->pinctrl_ngpios;
314
315         if (list_empty(&priv->gpio_dev))
316                 sb_populate_gpio_dev_list(dev);
317         /*
318          * walk through all banks to retrieve the pin-controller
319          * pins number
320          */
321         list_for_each_entry(gpio_bank, &priv->gpio_dev, list) {
322                 uc_priv = dev_get_uclass_priv(gpio_bank->gpio_dev);
323
324                 priv->pinctrl_ngpios += uc_priv->gpio_count;
325         }
326
327         return priv->pinctrl_ngpios;
328 }
329
330 static struct udevice *sb_pinctrl_get_gpio_dev(struct udevice *dev,
331                                                unsigned int selector,
332                                                unsigned int *idx)
333 {
334         struct sb_pinctrl_priv *priv = dev_get_priv(dev);
335         struct sb_gpio_bank *gpio_bank;
336         struct gpio_dev_priv *uc_priv;
337         int pin_count = 0;
338
339         if (list_empty(&priv->gpio_dev))
340                 sb_populate_gpio_dev_list(dev);
341
342         /* look up for the bank which owns the requested pin */
343         list_for_each_entry(gpio_bank, &priv->gpio_dev, list) {
344                 uc_priv = dev_get_uclass_priv(gpio_bank->gpio_dev);
345
346                 if (selector < (pin_count + uc_priv->gpio_count)) {
347                         /*
348                          * we found the bank, convert pin selector to
349                          * gpio bank index
350                          */
351                         *idx = selector - pin_count;
352
353                         return gpio_bank->gpio_dev;
354                 }
355                 pin_count += uc_priv->gpio_count;
356         }
357
358         return NULL;
359 }
360
361 static const char *sb_pinctrl_get_pin_name(struct udevice *dev,
362                                            unsigned int selector)
363 {
364         struct gpio_dev_priv *uc_priv;
365         struct udevice *gpio_dev;
366         unsigned int gpio_idx;
367         static char pin_name[PINNAME_SIZE];
368
369         /* look up for the bank which owns the requested pin */
370         gpio_dev = sb_pinctrl_get_gpio_dev(dev, selector, &gpio_idx);
371         if (!gpio_dev) {
372                 snprintf(pin_name, PINNAME_SIZE, "Error");
373         } else {
374                 uc_priv = dev_get_uclass_priv(gpio_dev);
375
376                 snprintf(pin_name, PINNAME_SIZE, "%s%d",
377                          uc_priv->bank_name,
378                          gpio_idx);
379         }
380
381         return pin_name;
382 }
383
384 static char *get_dir_flags_string(ulong flags)
385 {
386         if (flags & GPIOD_OPEN_DRAIN)
387                 return "drive-open-drain";
388         if (flags & GPIOD_OPEN_SOURCE)
389                 return "drive-open-source";
390         if (flags & GPIOD_PULL_UP)
391                 return "bias-pull-up";
392         if (flags & GPIOD_PULL_DOWN)
393                 return "bias-pull-down";
394         return ".";
395 }
396
397 static int sb_pinctrl_get_pin_muxing(struct udevice *dev,
398                                      unsigned int selector,
399                                      char *buf, int size)
400 {
401         struct udevice *gpio_dev;
402         unsigned int gpio_idx;
403         ulong dir_flags;
404         int function;
405
406         /* look up for the bank which owns the requested pin */
407         gpio_dev = sb_pinctrl_get_gpio_dev(dev, selector, &gpio_idx);
408         if (!gpio_dev) {
409                 snprintf(buf, size, "Error");
410         } else {
411                 function = sb_gpio_get_function(gpio_dev, gpio_idx);
412                 dir_flags = *get_gpio_dir_flags(gpio_dev, gpio_idx);
413
414                 snprintf(buf, size, "gpio %s %s",
415                          function == GPIOF_OUTPUT ? "output" : "input",
416                          get_dir_flags_string(dir_flags));
417         }
418
419         return 0;
420 }
421
422 static int sandbox_pinctrl_probe(struct udevice *dev)
423 {
424         struct sb_pinctrl_priv *priv = dev_get_priv(dev);
425
426         INIT_LIST_HEAD(&priv->gpio_dev);
427
428         return 0;
429 }
430
431 static struct pinctrl_ops sandbox_pinctrl_gpio_ops = {
432         .get_pin_name           = sb_pinctrl_get_pin_name,
433         .get_pins_count         = sb_pinctrl_get_pins_count,
434         .get_pin_muxing         = sb_pinctrl_get_pin_muxing,
435 };
436
437 static const struct udevice_id sandbox_pinctrl_gpio_match[] = {
438         { .compatible = "sandbox,pinctrl-gpio" },
439         { /* sentinel */ }
440 };
441
442 U_BOOT_DRIVER(sandbox_pinctrl_gpio) = {
443         .name = "sandbox_pinctrl_gpio",
444         .id = UCLASS_PINCTRL,
445         .of_match = sandbox_pinctrl_gpio_match,
446         .ops = &sandbox_pinctrl_gpio_ops,
447         .bind = dm_scan_fdt_dev,
448         .probe = sandbox_pinctrl_probe,
449         .priv_auto_alloc_size   = sizeof(struct sb_pinctrl_priv),
450 };