]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/gpio/xilinx_gpio.c
Merge branch 'master' of git://git.denx.de/u-boot-video
[karo-tx-uboot.git] / drivers / gpio / xilinx_gpio.c
1 /*
2  * Copyright (c) 2013 Xilinx, Michal Simek
3  *
4  * See file CREDITS for list of people who contributed to this
5  * project.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License as
9  * published by the Free Software Foundation; either version 2 of
10  * the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20  * MA 02111-1307 USA
21  */
22
23 #include <common.h>
24 #include <errno.h>
25 #include <malloc.h>
26 #include <linux/list.h>
27 #include <asm/io.h>
28 #include <asm/gpio.h>
29
30 static LIST_HEAD(gpio_list);
31
32 enum gpio_direction {
33         GPIO_DIRECTION_OUT = 0,
34         GPIO_DIRECTION_IN = 1,
35 };
36
37 /* Gpio simple map */
38 struct gpio_regs {
39         u32 gpiodata;
40         u32 gpiodir;
41 };
42
43 #define GPIO_NAME_SIZE  10
44
45 struct gpio_names {
46         char name[GPIO_NAME_SIZE];
47 };
48
49 /* Initialized, rxbd_current, rx_first_buf must be 0 after init */
50 struct xilinx_gpio_priv {
51         struct gpio_regs *regs;
52         u32 gpio_min;
53         u32 gpio_max;
54         u32 gpiodata_store;
55         char name[GPIO_NAME_SIZE];
56         struct list_head list;
57         struct gpio_names *gpio_name;
58 };
59
60 /* Store number of allocated gpio pins */
61 static u32 xilinx_gpio_max;
62
63 /* Get associated gpio controller */
64 static struct xilinx_gpio_priv *gpio_get_controller(unsigned gpio)
65 {
66         struct list_head *entry;
67         struct xilinx_gpio_priv *priv = NULL;
68
69         list_for_each(entry, &gpio_list) {
70                 priv = list_entry(entry, struct xilinx_gpio_priv, list);
71                 if (gpio >= priv->gpio_min && gpio <= priv->gpio_max) {
72                         debug("%s: reg: %x, min-max: %d-%d\n", __func__,
73                               (u32)priv->regs, priv->gpio_min, priv->gpio_max);
74                         return priv;
75                 }
76         }
77         puts("!!!Can't get gpio controller!!!\n");
78         return NULL;
79 }
80
81 /* Get gpio pin name if used/setup */
82 static char *get_name(unsigned gpio)
83 {
84         u32 gpio_priv;
85         struct xilinx_gpio_priv *priv;
86
87         debug("%s\n", __func__);
88
89         priv = gpio_get_controller(gpio);
90         if (priv) {
91                 gpio_priv = gpio - priv->gpio_min;
92
93                 return *priv->gpio_name[gpio_priv].name ?
94                         priv->gpio_name[gpio_priv].name : "UNKNOWN";
95         }
96         return "UNKNOWN";
97 }
98
99 /* Get output value */
100 static int gpio_get_output_value(unsigned gpio)
101 {
102         u32 val, gpio_priv;
103         struct xilinx_gpio_priv *priv = gpio_get_controller(gpio);
104
105         if (priv) {
106                 gpio_priv = gpio - priv->gpio_min;
107                 val = !!(priv->gpiodata_store & (1 << gpio_priv));
108                 debug("%s: reg: %x, gpio_no: %d, dir: %d\n", __func__,
109                       (u32)priv->regs, gpio_priv, val);
110
111                 return val;
112         }
113         return -1;
114 }
115
116 /* Get input value */
117 static int gpio_get_input_value(unsigned gpio)
118 {
119         u32 val, gpio_priv;
120         struct gpio_regs *regs;
121         struct xilinx_gpio_priv *priv = gpio_get_controller(gpio);
122
123         if (priv) {
124                 regs = priv->regs;
125                 gpio_priv = gpio - priv->gpio_min;
126                 val = readl(&regs->gpiodata);
127                 val = !!(val & (1 << gpio_priv));
128                 debug("%s: reg: %x, gpio_no: %d, dir: %d\n", __func__,
129                       (u32)priv->regs, gpio_priv, val);
130
131                 return val;
132         }
133         return -1;
134 }
135
136 /* Set gpio direction */
137 static int gpio_set_direction(unsigned gpio, enum gpio_direction direction)
138 {
139         u32 val, gpio_priv;
140         struct gpio_regs *regs;
141         struct xilinx_gpio_priv *priv = gpio_get_controller(gpio);
142
143         if (priv) {
144                 regs = priv->regs;
145                 val = readl(&regs->gpiodir);
146
147                 gpio_priv = gpio - priv->gpio_min;
148                 if (direction == GPIO_DIRECTION_OUT)
149                         val &= ~(1 << gpio_priv);
150                 else
151                         val |= 1 << gpio_priv;
152
153                 writel(val, &regs->gpiodir);
154                 debug("%s: reg: %x, gpio_no: %d, dir: %d\n", __func__,
155                       (u32)priv->regs, gpio_priv, val);
156
157                 return 0;
158         }
159
160         return -1;
161 }
162
163 /* Get gpio direction */
164 static int gpio_get_direction(unsigned gpio)
165 {
166         u32 val, gpio_priv;
167         struct gpio_regs *regs;
168         struct xilinx_gpio_priv *priv = gpio_get_controller(gpio);
169
170         if (priv) {
171                 regs = priv->regs;
172                 gpio_priv = gpio - priv->gpio_min;
173                 val = readl(&regs->gpiodir);
174                 val = !!(val & (1 << gpio_priv));
175                 debug("%s: reg: %x, gpio_no: %d, dir: %d\n", __func__,
176                       (u32)priv->regs, gpio_priv, val);
177
178                 return val;
179         }
180
181         return -1;
182 }
183
184 /*
185  * Get input value
186  * for example gpio setup to output only can't get input value
187  * which is breaking gpio toggle command
188  */
189 int gpio_get_value(unsigned gpio)
190 {
191         u32 val;
192
193         if (gpio_get_direction(gpio) == GPIO_DIRECTION_OUT)
194                 val = gpio_get_output_value(gpio);
195         else
196                 val = gpio_get_input_value(gpio);
197
198         return val;
199 }
200
201 /* Set output value */
202 static int gpio_set_output_value(unsigned gpio, int value)
203 {
204         u32 val, gpio_priv;
205         struct gpio_regs *regs;
206         struct xilinx_gpio_priv *priv = gpio_get_controller(gpio);
207
208         if (priv) {
209                 regs = priv->regs;
210                 gpio_priv = gpio - priv->gpio_min;
211                 val = priv->gpiodata_store;
212                 if (value)
213                         val |= 1 << gpio_priv;
214                 else
215                         val &= ~(1 << gpio_priv);
216
217                 writel(val, &regs->gpiodata);
218                 debug("%s: reg: %x, gpio_no: %d, output_val: %d\n", __func__,
219                       (u32)priv->regs, gpio_priv, val);
220                 priv->gpiodata_store = val;
221
222                 return 0;
223         }
224
225         return -1;
226 }
227
228 int gpio_set_value(unsigned gpio, int value)
229 {
230         if (gpio_get_direction(gpio) == GPIO_DIRECTION_OUT)
231                 return gpio_set_output_value(gpio, value);
232
233         return -1;
234 }
235
236 /* Set GPIO as input */
237 int gpio_direction_input(unsigned gpio)
238 {
239         debug("%s\n", __func__);
240         return gpio_set_direction(gpio, GPIO_DIRECTION_IN);
241 }
242
243 /* Setup GPIO as output and set output value */
244 int gpio_direction_output(unsigned gpio, int value)
245 {
246         int ret = gpio_set_direction(gpio, GPIO_DIRECTION_OUT);
247
248         debug("%s\n", __func__);
249
250         if (ret < 0)
251                 return ret;
252
253         return gpio_set_output_value(gpio, value);
254 }
255
256 /* Show gpio status */
257 void gpio_info(void)
258 {
259         unsigned gpio;
260
261         struct list_head *entry;
262         struct xilinx_gpio_priv *priv = NULL;
263
264         list_for_each(entry, &gpio_list) {
265                 priv = list_entry(entry, struct xilinx_gpio_priv, list);
266                 printf("\n%s: %s/%x (%d-%d)\n", __func__, priv->name,
267                        (u32)priv->regs, priv->gpio_min, priv->gpio_max);
268
269                 for (gpio = priv->gpio_min; gpio <= priv->gpio_max; gpio++) {
270                         printf("GPIO_%d:\t%s is an ", gpio, get_name(gpio));
271                         if (gpio_get_direction(gpio) == GPIO_DIRECTION_OUT)
272                                 printf("OUTPUT value = %d\n",
273                                        gpio_get_output_value(gpio));
274                         else
275                                 printf("INPUT value = %d\n",
276                                        gpio_get_input_value(gpio));
277                 }
278         }
279 }
280
281 int gpio_request(unsigned gpio, const char *label)
282 {
283         u32 gpio_priv;
284         struct xilinx_gpio_priv *priv;
285
286         if (gpio >= xilinx_gpio_max)
287                 return -EINVAL;
288
289         priv = gpio_get_controller(gpio);
290         if (priv) {
291                 gpio_priv = gpio - priv->gpio_min;
292
293                 if (label != NULL) {
294                         strncpy(priv->gpio_name[gpio_priv].name, label,
295                                 GPIO_NAME_SIZE);
296                         priv->gpio_name[gpio_priv].name[GPIO_NAME_SIZE - 1] =
297                                         '\0';
298                 }
299                 return 0;
300         }
301
302         return -1;
303 }
304
305 int gpio_free(unsigned gpio)
306 {
307         u32 gpio_priv;
308         struct xilinx_gpio_priv *priv;
309
310         if (gpio >= xilinx_gpio_max)
311                 return -EINVAL;
312
313         priv = gpio_get_controller(gpio);
314         if (priv) {
315                 gpio_priv = gpio - priv->gpio_min;
316                 priv->gpio_name[gpio_priv].name[0] = '\0';
317
318                 /* Do nothing here */
319                 return 0;
320         }
321
322         return -1;
323 }
324
325 int gpio_alloc(u32 baseaddr, const char *name, u32 gpio_no)
326 {
327         struct xilinx_gpio_priv *priv;
328
329         priv = calloc(1, sizeof(struct xilinx_gpio_priv));
330
331         /* Setup gpio name */
332         if (name != NULL) {
333                 strncpy(priv->name, name, GPIO_NAME_SIZE);
334                 priv->name[GPIO_NAME_SIZE - 1] = '\0';
335         }
336         priv->regs = (struct gpio_regs *)baseaddr;
337
338         priv->gpio_min = xilinx_gpio_max;
339         xilinx_gpio_max = priv->gpio_min + gpio_no;
340         priv->gpio_max = xilinx_gpio_max - 1;
341
342         priv->gpio_name = calloc(gpio_no, sizeof(struct gpio_names));
343
344         INIT_LIST_HEAD(&priv->list);
345         list_add_tail(&priv->list, &gpio_list);
346
347         printf("%s: Add %s (%d-%d)\n", __func__, name,
348                priv->gpio_min, priv->gpio_max);
349
350         /* Return the first gpio allocated for this device */
351         return priv->gpio_min;
352 }
353
354 /* Dual channel gpio is one IP with two independent channels */
355 int gpio_alloc_dual(u32 baseaddr, const char *name, u32 gpio_no0, u32 gpio_no1)
356 {
357         int ret;
358
359         ret = gpio_alloc(baseaddr, name, gpio_no0);
360         gpio_alloc(baseaddr + 8, strcat((char *)name, "_1"), gpio_no1);
361
362         /* Return the first gpio allocated for this device */
363         return ret;
364 }