xref: /openbmc/u-boot/drivers/gpio/tegra_gpio.c (revision cd23aac4)
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 }
267