Merge https://gitlab.denx.de/u-boot/custodians/u-boot-spi into next
[platform/kernel/u-boot.git] / drivers / gpio / omap_gpio.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2009 Wind River Systems, Inc.
4  * Tom Rix <Tom.Rix@windriver.com>
5  *
6  * This work is derived from the linux 2.6.27 kernel source
7  * To fetch, use the kernel repository
8  * git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
9  * Use the v2.6.27 tag.
10  *
11  * Below is the original's header including its copyright
12  *
13  *  linux/arch/arm/plat-omap/gpio.c
14  *
15  * Support functions for OMAP GPIO
16  *
17  * Copyright (C) 2003-2005 Nokia Corporation
18  * Written by Juha Yrjölä <juha.yrjola@nokia.com>
19  */
20 #include <common.h>
21 #include <dm.h>
22 #include <fdtdec.h>
23 #include <asm/gpio.h>
24 #include <asm/io.h>
25 #include <linux/errno.h>
26 #include <malloc.h>
27
28 DECLARE_GLOBAL_DATA_PTR;
29
30 #define OMAP_GPIO_DIR_OUT       0
31 #define OMAP_GPIO_DIR_IN        1
32
33 #if CONFIG_IS_ENABLED(DM_GPIO)
34
35 #define GPIO_PER_BANK                   32
36
37 struct gpio_bank {
38         /* TODO(sjg@chromium.org): Can we use a struct here? */
39         void *base;     /* address of registers in physical memory */
40 };
41
42 #endif
43
44 int gpio_is_valid(int gpio)
45 {
46         return (gpio >= 0) && (gpio < OMAP_MAX_GPIO);
47 }
48
49 static void _set_gpio_direction(const struct gpio_bank *bank, int gpio,
50                                 int is_input)
51 {
52         void *reg = bank->base;
53         u32 l;
54
55         reg += OMAP_GPIO_OE;
56
57         l = __raw_readl(reg);
58         if (is_input)
59                 l |= 1 << gpio;
60         else
61                 l &= ~(1 << gpio);
62         __raw_writel(l, reg);
63 }
64
65 /**
66  * Get the direction of the GPIO by reading the GPIO_OE register
67  * corresponding to the specified bank.
68  */
69 static int _get_gpio_direction(const struct gpio_bank *bank, int gpio)
70 {
71         void *reg = bank->base;
72         u32 v;
73
74         reg += OMAP_GPIO_OE;
75
76         v = __raw_readl(reg);
77
78         if (v & (1 << gpio))
79                 return OMAP_GPIO_DIR_IN;
80         else
81                 return OMAP_GPIO_DIR_OUT;
82 }
83
84 static void _set_gpio_dataout(const struct gpio_bank *bank, int gpio,
85                                 int enable)
86 {
87         void *reg = bank->base;
88         u32 l = 0;
89
90         if (enable)
91                 reg += OMAP_GPIO_SETDATAOUT;
92         else
93                 reg += OMAP_GPIO_CLEARDATAOUT;
94
95         l = 1 << gpio;
96         __raw_writel(l, reg);
97 }
98
99 static int _get_gpio_value(const struct gpio_bank *bank, int gpio)
100 {
101         void *reg = bank->base;
102         int input;
103
104         input = _get_gpio_direction(bank, gpio);
105         switch (input) {
106         case OMAP_GPIO_DIR_IN:
107                 reg += OMAP_GPIO_DATAIN;
108                 break;
109         case OMAP_GPIO_DIR_OUT:
110                 reg += OMAP_GPIO_DATAOUT;
111                 break;
112         default:
113                 return -1;
114         }
115
116         return (__raw_readl(reg) & (1 << gpio)) != 0;
117 }
118
119 #if !CONFIG_IS_ENABLED(DM_GPIO)
120 static inline int get_gpio_index(int gpio)
121 {
122         return gpio & 0x1f;
123 }
124
125 static inline const struct gpio_bank *get_gpio_bank(int gpio)
126 {
127         return &omap_gpio_bank[gpio >> 5];
128 }
129
130 static int check_gpio(int gpio)
131 {
132         if (!gpio_is_valid(gpio)) {
133                 printf("ERROR : check_gpio: invalid GPIO %d\n", gpio);
134                 return -1;
135         }
136         return 0;
137 }
138
139 /**
140  * Set value of the specified gpio
141  */
142 int gpio_set_value(unsigned gpio, int value)
143 {
144         const struct gpio_bank *bank;
145
146         if (check_gpio(gpio) < 0)
147                 return -1;
148         bank = get_gpio_bank(gpio);
149         _set_gpio_dataout(bank, get_gpio_index(gpio), value);
150
151         return 0;
152 }
153
154 /**
155  * Get value of the specified gpio
156  */
157 int gpio_get_value(unsigned gpio)
158 {
159         const struct gpio_bank *bank;
160
161         if (check_gpio(gpio) < 0)
162                 return -1;
163         bank = get_gpio_bank(gpio);
164
165         return _get_gpio_value(bank, get_gpio_index(gpio));
166 }
167
168 /**
169  * Set gpio direction as input
170  */
171 int gpio_direction_input(unsigned gpio)
172 {
173         const struct gpio_bank *bank;
174
175         if (check_gpio(gpio) < 0)
176                 return -1;
177
178         bank = get_gpio_bank(gpio);
179         _set_gpio_direction(bank, get_gpio_index(gpio), 1);
180
181         return 0;
182 }
183
184 /**
185  * Set gpio direction as output
186  */
187 int gpio_direction_output(unsigned gpio, int value)
188 {
189         const struct gpio_bank *bank;
190
191         if (check_gpio(gpio) < 0)
192                 return -1;
193
194         bank = get_gpio_bank(gpio);
195         _set_gpio_dataout(bank, get_gpio_index(gpio), value);
196         _set_gpio_direction(bank, get_gpio_index(gpio), 0);
197
198         return 0;
199 }
200
201 /**
202  * Request a gpio before using it.
203  *
204  * NOTE: Argument 'label' is unused.
205  */
206 int gpio_request(unsigned gpio, const char *label)
207 {
208         if (check_gpio(gpio) < 0)
209                 return -1;
210
211         return 0;
212 }
213
214 /**
215  * Reset and free the gpio after using it.
216  */
217 int gpio_free(unsigned gpio)
218 {
219         return 0;
220 }
221
222 #else /* new driver model interface CONFIG_DM_GPIO */
223
224 /* set GPIO pin 'gpio' as an input */
225 static int omap_gpio_direction_input(struct udevice *dev, unsigned offset)
226 {
227         struct gpio_bank *bank = dev_get_priv(dev);
228
229         /* Configure GPIO direction as input. */
230         _set_gpio_direction(bank, offset, 1);
231
232         return 0;
233 }
234
235 /* set GPIO pin 'gpio' as an output, with polarity 'value' */
236 static int omap_gpio_direction_output(struct udevice *dev, unsigned offset,
237                                        int value)
238 {
239         struct gpio_bank *bank = dev_get_priv(dev);
240
241         _set_gpio_dataout(bank, offset, value);
242         _set_gpio_direction(bank, offset, 0);
243
244         return 0;
245 }
246
247 /* read GPIO IN value of pin 'gpio' */
248 static int omap_gpio_get_value(struct udevice *dev, unsigned offset)
249 {
250         struct gpio_bank *bank = dev_get_priv(dev);
251
252         return _get_gpio_value(bank, offset);
253 }
254
255 /* write GPIO OUT value to pin 'gpio' */
256 static int omap_gpio_set_value(struct udevice *dev, unsigned offset,
257                                  int value)
258 {
259         struct gpio_bank *bank = dev_get_priv(dev);
260
261         _set_gpio_dataout(bank, offset, value);
262
263         return 0;
264 }
265
266 static int omap_gpio_get_function(struct udevice *dev, unsigned offset)
267 {
268         struct gpio_bank *bank = dev_get_priv(dev);
269
270         /* GPIOF_FUNC is not implemented yet */
271         if (_get_gpio_direction(bank, offset) == OMAP_GPIO_DIR_OUT)
272                 return GPIOF_OUTPUT;
273         else
274                 return GPIOF_INPUT;
275 }
276
277 static const struct dm_gpio_ops gpio_omap_ops = {
278         .direction_input        = omap_gpio_direction_input,
279         .direction_output       = omap_gpio_direction_output,
280         .get_value              = omap_gpio_get_value,
281         .set_value              = omap_gpio_set_value,
282         .get_function           = omap_gpio_get_function,
283 };
284
285 static int omap_gpio_probe(struct udevice *dev)
286 {
287         struct gpio_bank *bank = dev_get_priv(dev);
288         struct omap_gpio_platdata *plat = dev_get_platdata(dev);
289         struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
290         char name[18], *str;
291
292         sprintf(name, "gpio@%4x_", (unsigned int)plat->base);
293         str = strdup(name);
294         if (!str)
295                 return -ENOMEM;
296         uc_priv->bank_name = str;
297         uc_priv->gpio_count = GPIO_PER_BANK;
298         bank->base = (void *)plat->base;
299         return 0;
300 }
301
302 #if !CONFIG_IS_ENABLED(OF_CONTROL)
303 static int omap_gpio_bind(struct udevice *dev)
304 {
305         struct omap_gpio_platdata *plat = dev_get_platdata(dev);
306         fdt_addr_t base_addr;
307
308         if (plat)
309                 return 0;
310
311         base_addr = devfdt_get_addr(dev);
312         if (base_addr == FDT_ADDR_T_NONE)
313                 return -EINVAL;
314
315         /*
316         * TODO:
317         * When every board is converted to driver model and DT is
318         * supported, this can be done by auto-alloc feature, but
319         * not using calloc to alloc memory for platdata.
320         *
321         * For example am33xx_gpio uses platform data rather than device tree.
322         *
323         * NOTE: DO NOT COPY this code if you are using device tree.
324         */
325         plat = calloc(1, sizeof(*plat));
326         if (!plat)
327                 return -ENOMEM;
328
329         plat->base = base_addr;
330         plat->port_name = fdt_get_name(gd->fdt_blob, dev_of_offset(dev), NULL);
331         dev->platdata = plat;
332
333         return 0;
334 }
335 #endif
336
337 #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
338 static const struct udevice_id omap_gpio_ids[] = {
339         { .compatible = "ti,omap3-gpio" },
340         { .compatible = "ti,omap4-gpio" },
341         { .compatible = "ti,am4372-gpio" },
342         { }
343 };
344
345 static int omap_gpio_ofdata_to_platdata(struct udevice *dev)
346 {
347         struct omap_gpio_platdata *plat = dev_get_platdata(dev);
348         fdt_addr_t addr;
349
350         addr = devfdt_get_addr(dev);
351         if (addr == FDT_ADDR_T_NONE)
352                 return -EINVAL;
353
354         plat->base = addr;
355         return 0;
356 }
357 #endif
358
359 U_BOOT_DRIVER(gpio_omap) = {
360         .name   = "gpio_omap",
361         .id     = UCLASS_GPIO,
362 #if CONFIG_IS_ENABLED(OF_CONTROL)
363 #if !CONFIG_IS_ENABLED(OF_PLATDATA)
364         .of_match = omap_gpio_ids,
365         .ofdata_to_platdata = of_match_ptr(omap_gpio_ofdata_to_platdata),
366         .platdata_auto_alloc_size = sizeof(struct omap_gpio_platdata),
367 #endif
368 #else
369         .bind   = omap_gpio_bind,
370 #endif
371         .ops    = &gpio_omap_ops,
372         .probe  = omap_gpio_probe,
373         .priv_auto_alloc_size = sizeof(struct gpio_bank),
374 #if !CONFIG_IS_ENABLED(OF_CONTROL)
375         .flags = DM_FLAG_PRE_RELOC,
376 #endif
377 };
378
379 #endif /* !DM_GPIO */