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