blob: 37fb0c50b0bb63786183177f7ac0bb1c0a1f744e [file] [log] [blame]
Michal Simek4e779ad2013-04-24 10:01:20 +02001/*
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
30static LIST_HEAD(gpio_list);
31
32enum gpio_direction {
33 GPIO_DIRECTION_OUT = 0,
34 GPIO_DIRECTION_IN = 1,
35};
36
37/* Gpio simple map */
38struct gpio_regs {
39 u32 gpiodata;
40 u32 gpiodir;
41};
42
43#define GPIO_NAME_SIZE 10
44
45struct gpio_names {
46 char name[GPIO_NAME_SIZE];
47};
48
49/* Initialized, rxbd_current, rx_first_buf must be 0 after init */
50struct 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 */
61static u32 xilinx_gpio_max;
62
63/* Get associated gpio controller */
64static 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 */
82static 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 */
100static 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 */
117static 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 */
137static 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 */
164static 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 */
189int 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 */
202static 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
228int 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 */
237int 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 */
244int 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 */
257void 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
281int 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
305int 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
325int 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 */
355int 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}