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