]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/gpio/tegra_gpio.c
Merge branch 'u-boot-ti/master' into 'u-boot-arm/master'
[karo-tx-uboot.git] / drivers / gpio / tegra_gpio.c
1 /*
2  * NVIDIA Tegra20 GPIO handling.
3  *  (C) Copyright 2010-2012
4  *  NVIDIA Corporation <www.nvidia.com>
5  *
6  * SPDX-License-Identifier:     GPL-2.0+
7  */
8
9 /*
10  * Based on (mostly copied from) kw_gpio.c based Linux 2.6 kernel driver.
11  * Tom Warren (twarren@nvidia.com)
12  */
13
14 #include <common.h>
15 #include <asm/io.h>
16 #include <asm/bitops.h>
17 #include <asm/arch/tegra.h>
18 #include <asm/gpio.h>
19
20 enum {
21         TEGRA_CMD_INFO,
22         TEGRA_CMD_PORT,
23         TEGRA_CMD_OUTPUT,
24         TEGRA_CMD_INPUT,
25 };
26
27 static struct gpio_names {
28         char name[GPIO_NAME_SIZE];
29 } gpio_names[MAX_NUM_GPIOS];
30
31 static char *get_name(int i)
32 {
33         return *gpio_names[i].name ? gpio_names[i].name : "UNKNOWN";
34 }
35
36 /* Return config of pin 'gpio' as GPIO (1) or SFPIO (0) */
37 static int get_config(unsigned gpio)
38 {
39         struct gpio_ctlr *ctlr = (struct gpio_ctlr *)NV_PA_GPIO_BASE;
40         struct gpio_ctlr_bank *bank = &ctlr->gpio_bank[GPIO_BANK(gpio)];
41         u32 u;
42         int type;
43
44         u = readl(&bank->gpio_config[GPIO_PORT(gpio)]);
45         type =  (u >> GPIO_BIT(gpio)) & 1;
46
47         debug("get_config: port = %d, bit = %d is %s\n",
48                 GPIO_FULLPORT(gpio), GPIO_BIT(gpio), type ? "GPIO" : "SFPIO");
49
50         return type;
51 }
52
53 /* Config pin 'gpio' as GPIO or SFPIO, based on 'type' */
54 static void set_config(unsigned gpio, int type)
55 {
56         struct gpio_ctlr *ctlr = (struct gpio_ctlr *)NV_PA_GPIO_BASE;
57         struct gpio_ctlr_bank *bank = &ctlr->gpio_bank[GPIO_BANK(gpio)];
58         u32 u;
59
60         debug("set_config: port = %d, bit = %d, %s\n",
61                 GPIO_FULLPORT(gpio), GPIO_BIT(gpio), type ? "GPIO" : "SFPIO");
62
63         u = readl(&bank->gpio_config[GPIO_PORT(gpio)]);
64         if (type)                               /* GPIO */
65                 u |= 1 << GPIO_BIT(gpio);
66         else
67                 u &= ~(1 << GPIO_BIT(gpio));
68         writel(u, &bank->gpio_config[GPIO_PORT(gpio)]);
69 }
70
71 /* Return GPIO pin 'gpio' direction - 0 = input or 1 = output */
72 static int get_direction(unsigned gpio)
73 {
74         struct gpio_ctlr *ctlr = (struct gpio_ctlr *)NV_PA_GPIO_BASE;
75         struct gpio_ctlr_bank *bank = &ctlr->gpio_bank[GPIO_BANK(gpio)];
76         u32 u;
77         int dir;
78
79         u = readl(&bank->gpio_dir_out[GPIO_PORT(gpio)]);
80         dir =  (u >> GPIO_BIT(gpio)) & 1;
81
82         debug("get_direction: port = %d, bit = %d, %s\n",
83                 GPIO_FULLPORT(gpio), GPIO_BIT(gpio), dir ? "OUT" : "IN");
84
85         return dir;
86 }
87
88 /* Config GPIO pin 'gpio' as input or output (OE) as per 'output' */
89 static void set_direction(unsigned gpio, int output)
90 {
91         struct gpio_ctlr *ctlr = (struct gpio_ctlr *)NV_PA_GPIO_BASE;
92         struct gpio_ctlr_bank *bank = &ctlr->gpio_bank[GPIO_BANK(gpio)];
93         u32 u;
94
95         debug("set_direction: port = %d, bit = %d, %s\n",
96                 GPIO_FULLPORT(gpio), GPIO_BIT(gpio), output ? "OUT" : "IN");
97
98         u = readl(&bank->gpio_dir_out[GPIO_PORT(gpio)]);
99         if (output)
100                 u |= 1 << GPIO_BIT(gpio);
101         else
102                 u &= ~(1 << GPIO_BIT(gpio));
103         writel(u, &bank->gpio_dir_out[GPIO_PORT(gpio)]);
104 }
105
106 /* set GPIO pin 'gpio' output bit as 0 or 1 as per 'high' */
107 static void set_level(unsigned gpio, int high)
108 {
109         struct gpio_ctlr *ctlr = (struct gpio_ctlr *)NV_PA_GPIO_BASE;
110         struct gpio_ctlr_bank *bank = &ctlr->gpio_bank[GPIO_BANK(gpio)];
111         u32 u;
112
113         debug("set_level: port = %d, bit %d == %d\n",
114                 GPIO_FULLPORT(gpio), GPIO_BIT(gpio), high);
115
116         u = readl(&bank->gpio_out[GPIO_PORT(gpio)]);
117         if (high)
118                 u |= 1 << GPIO_BIT(gpio);
119         else
120                 u &= ~(1 << GPIO_BIT(gpio));
121         writel(u, &bank->gpio_out[GPIO_PORT(gpio)]);
122 }
123
124 /*
125  * Generic_GPIO primitives.
126  */
127
128 int gpio_request(unsigned gpio, const char *label)
129 {
130         if (gpio >= MAX_NUM_GPIOS)
131                 return -1;
132
133         if (label != NULL) {
134                 strncpy(gpio_names[gpio].name, label, GPIO_NAME_SIZE);
135                 gpio_names[gpio].name[GPIO_NAME_SIZE - 1] = '\0';
136         }
137
138         /* Configure as a GPIO */
139         set_config(gpio, 1);
140
141         return 0;
142 }
143
144 int gpio_free(unsigned gpio)
145 {
146         if (gpio >= MAX_NUM_GPIOS)
147                 return -1;
148
149         gpio_names[gpio].name[0] = '\0';
150         /* Do not configure as input or change pin mux here */
151         return 0;
152 }
153
154 /* read GPIO OUT value of pin 'gpio' */
155 static int gpio_get_output_value(unsigned gpio)
156 {
157         struct gpio_ctlr *ctlr = (struct gpio_ctlr *)NV_PA_GPIO_BASE;
158         struct gpio_ctlr_bank *bank = &ctlr->gpio_bank[GPIO_BANK(gpio)];
159         int val;
160
161         debug("gpio_get_output_value: pin = %d (port %d:bit %d)\n",
162                 gpio, GPIO_FULLPORT(gpio), GPIO_BIT(gpio));
163
164         val = readl(&bank->gpio_out[GPIO_PORT(gpio)]);
165
166         return (val >> GPIO_BIT(gpio)) & 1;
167 }
168
169 /* set GPIO pin 'gpio' as an input */
170 int gpio_direction_input(unsigned gpio)
171 {
172         debug("gpio_direction_input: pin = %d (port %d:bit %d)\n",
173                 gpio, GPIO_FULLPORT(gpio), GPIO_BIT(gpio));
174
175         /* Configure GPIO direction as input. */
176         set_direction(gpio, 0);
177
178         return 0;
179 }
180
181 /* set GPIO pin 'gpio' as an output, with polarity 'value' */
182 int gpio_direction_output(unsigned gpio, int value)
183 {
184         debug("gpio_direction_output: pin = %d (port %d:bit %d) = %s\n",
185                 gpio, GPIO_FULLPORT(gpio), GPIO_BIT(gpio),
186                 value ? "HIGH" : "LOW");
187
188         /* Configure GPIO output value. */
189         set_level(gpio, value);
190
191         /* Configure GPIO direction as output. */
192         set_direction(gpio, 1);
193
194         return 0;
195 }
196
197 /* read GPIO IN value of pin 'gpio' */
198 int gpio_get_value(unsigned gpio)
199 {
200         struct gpio_ctlr *ctlr = (struct gpio_ctlr *)NV_PA_GPIO_BASE;
201         struct gpio_ctlr_bank *bank = &ctlr->gpio_bank[GPIO_BANK(gpio)];
202         int val;
203
204         debug("gpio_get_value: pin = %d (port %d:bit %d)\n",
205                 gpio, GPIO_FULLPORT(gpio), GPIO_BIT(gpio));
206
207         val = readl(&bank->gpio_in[GPIO_PORT(gpio)]);
208
209         return (val >> GPIO_BIT(gpio)) & 1;
210 }
211
212 /* write GPIO OUT value to pin 'gpio' */
213 int gpio_set_value(unsigned gpio, int value)
214 {
215         debug("gpio_set_value: pin = %d (port %d:bit %d), value = %d\n",
216                 gpio, GPIO_FULLPORT(gpio), GPIO_BIT(gpio), value);
217
218         /* Configure GPIO output value. */
219         set_level(gpio, value);
220
221         return 0;
222 }
223
224 void gpio_config_table(const struct tegra_gpio_config *config, int len)
225 {
226         int i;
227
228         for (i = 0; i < len; i++) {
229                 switch (config[i].init) {
230                 case TEGRA_GPIO_INIT_IN:
231                         gpio_direction_input(config[i].gpio);
232                         break;
233                 case TEGRA_GPIO_INIT_OUT0:
234                         gpio_direction_output(config[i].gpio, 0);
235                         break;
236                 case TEGRA_GPIO_INIT_OUT1:
237                         gpio_direction_output(config[i].gpio, 1);
238                         break;
239                 }
240                 set_config(config[i].gpio, 1);
241         }
242 }
243
244 /*
245  * Display Tegra GPIO information
246  */
247 void gpio_info(void)
248 {
249         unsigned c;
250         int type;
251
252         for (c = 0; c < MAX_NUM_GPIOS; c++) {
253                 type = get_config(c);           /* GPIO, not SFPIO */
254                 if (type) {
255                         printf("GPIO_%d:\t%s is an %s, ", c,
256                                 get_name(c),
257                                 get_direction(c) ? "OUTPUT" : "INPUT");
258                         if (get_direction(c))
259                                 printf("value = %d", gpio_get_output_value(c));
260                         else
261                                 printf("value = %d", gpio_get_value(c));
262                         printf("\n");
263                 } else
264                         continue;
265         }
266 }