xref: /netbsd-src/sys/arch/arm/nvidia/tegra_gpio.c (revision d909946ca08dceb44d7d0f22ec9488679695d976)
1 /* $NetBSD: tegra_gpio.c,v 1.7 2016/03/13 17:38:44 christos Exp $ */
2 
3 /*-
4  * Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca>
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 
29 #include <sys/cdefs.h>
30 __KERNEL_RCSID(0, "$NetBSD: tegra_gpio.c,v 1.7 2016/03/13 17:38:44 christos Exp $");
31 
32 #include <sys/param.h>
33 #include <sys/bus.h>
34 #include <sys/device.h>
35 #include <sys/intr.h>
36 #include <sys/systm.h>
37 #include <sys/kernel.h>
38 #include <sys/kmem.h>
39 #include <sys/gpio.h>
40 
41 #include <dev/gpio/gpiovar.h>
42 
43 #include <arm/nvidia/tegra_reg.h>
44 #include <arm/nvidia/tegra_gpioreg.h>
45 #include <arm/nvidia/tegra_var.h>
46 
47 #include <dev/fdt/fdtvar.h>
48 
49 const struct tegra_gpio_pinbank {
50 	const char *name;
51 	bus_size_t base;
52 } tegra_gpio_pinbanks [] = {
53 	{ "A", 0x000 },
54 	{ "B", 0x004 },
55 	{ "C", 0x008 },
56 	{ "D", 0x00c },
57 	{ "E", 0x100 },
58 	{ "F", 0x104 },
59 	{ "G", 0x108 },
60 	{ "H", 0x10c },
61 	{ "I", 0x200 },
62 	{ "J", 0x204 },
63 	{ "K", 0x208 },
64 	{ "L", 0x20c },
65 	{ "M", 0x300 },
66 	{ "N", 0x304 },
67 	{ "O", 0x308 },
68 	{ "P", 0x30c },
69 	{ "Q", 0x400 },
70 	{ "R", 0x404 },
71 	{ "S", 0x408 },
72 	{ "T", 0x40c },
73 	{ "U", 0x500 },
74 	{ "V", 0x504 },
75 	{ "W", 0x508 },
76 	{ "X", 0x50c },
77 	{ "Y", 0x600 },
78 	{ "Z", 0x604 },
79 	{ "AA", 0x608 },
80 	{ "BB", 0x60c },
81 	{ "CC", 0x700 },
82 	{ "DD", 0x704 },
83 	{ "EE", 0x708 }
84 };
85 
86 static int	tegra_gpio_match(device_t, cfdata_t, void *);
87 static void	tegra_gpio_attach(device_t, device_t, void *);
88 
89 static void *	tegra_gpio_fdt_acquire(device_t, const void *,
90 		    size_t, int);
91 static void	tegra_gpio_fdt_release(device_t, void *);
92 static int	tegra_gpio_fdt_read(device_t, void *, bool);
93 static void	tegra_gpio_fdt_write(device_t, void *, int, bool);
94 
95 struct fdtbus_gpio_controller_func tegra_gpio_funcs = {
96 	.acquire = tegra_gpio_fdt_acquire,
97 	.release = tegra_gpio_fdt_release,
98 	.read = tegra_gpio_fdt_read,
99 	.write = tegra_gpio_fdt_write
100 };
101 
102 struct tegra_gpio_softc;
103 
104 struct tegra_gpio_bank {
105 	struct tegra_gpio_softc *bank_sc;
106 	const struct tegra_gpio_pinbank *bank_pb;
107 	device_t		bank_dev;
108 	struct gpio_chipset_tag	bank_gc;
109 	gpio_pin_t		bank_pins[8];
110 };
111 
112 struct tegra_gpio_softc {
113 	device_t		sc_dev;
114 	bus_space_tag_t		sc_bst;
115 	bus_space_handle_t	sc_bsh;
116 
117 	struct tegra_gpio_bank *sc_banks;
118 };
119 
120 struct tegra_gpio_pin {
121 	struct tegra_gpio_softc *pin_sc;
122 	struct tegra_gpio_bank	pin_bank;
123 	int			pin_no;
124 	u_int			pin_flags;
125 	bool			pin_actlo;
126 };
127 
128 static void	tegra_gpio_attach_bank(struct tegra_gpio_softc *, u_int);
129 
130 static int	tegra_gpio_pin_read(void *, int);
131 static void	tegra_gpio_pin_write(void *, int, int);
132 static void	tegra_gpio_pin_ctl(void *, int, int);
133 
134 static int	tegra_gpio_cfprint(void *, const char *);
135 
136 CFATTACH_DECL_NEW(tegra_gpio, sizeof(struct tegra_gpio_softc),
137 	tegra_gpio_match, tegra_gpio_attach, NULL, NULL);
138 
139 #define GPIO_WRITE(bank, reg, val) \
140 	bus_space_write_4((bank)->bank_sc->sc_bst, \
141 	    (bank)->bank_sc->sc_bsh, \
142 	    (bank)->bank_pb->base + (reg), (val))
143 #define GPIO_READ(bank, reg) \
144 	bus_space_read_4((bank)->bank_sc->sc_bst, \
145 	    (bank)->bank_sc->sc_bsh, \
146 	    (bank)->bank_pb->base + (reg))
147 
148 static int
149 tegra_gpio_match(device_t parent, cfdata_t cf, void *aux)
150 {
151 	const char * const compatible[] = { "nvidia,tegra124-gpio", NULL };
152 	struct fdt_attach_args * const faa = aux;
153 
154 	return of_match_compatible(faa->faa_phandle, compatible);
155 }
156 
157 static void
158 tegra_gpio_attach(device_t parent, device_t self, void *aux)
159 {
160 	struct tegra_gpio_softc * const sc = device_private(self);
161 	struct fdt_attach_args * const faa = aux;
162 	bus_addr_t addr;
163 	bus_size_t size;
164 	int error;
165 	u_int n;
166 
167 	if (fdtbus_get_reg(faa->faa_phandle, 0, &addr, &size) != 0) {
168 		aprint_error(": couldn't get registers\n");
169 		return;
170 	}
171 
172 	sc->sc_dev = self;
173 	sc->sc_bst = faa->faa_bst;
174 	error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh);
175 	if (error) {
176 		aprint_error(": couldn't map %#llx: %d", (uint64_t)addr, error);
177 		return;
178 	}
179 
180 	aprint_naive("\n");
181 	aprint_normal(": GPIO\n");
182 
183 	const u_int nbank = __arraycount(tegra_gpio_pinbanks);
184 	sc->sc_banks = kmem_zalloc(sizeof(*sc->sc_banks) * nbank, KM_SLEEP);
185 	for (n = 0; n < nbank; n++) {
186 		tegra_gpio_attach_bank(sc, n);
187 	}
188 
189 	fdtbus_register_gpio_controller(self, faa->faa_phandle,
190 	    &tegra_gpio_funcs);
191 }
192 
193 static void
194 tegra_gpio_attach_bank(struct tegra_gpio_softc *sc, u_int bankno)
195 {
196 	struct tegra_gpio_bank *bank = &sc->sc_banks[bankno];
197 	struct gpiobus_attach_args gba;
198 	u_int pin;
199 
200 	bank->bank_sc = sc;
201 	bank->bank_pb = &tegra_gpio_pinbanks[bankno];
202 	bank->bank_gc.gp_cookie = bank;
203 	bank->bank_gc.gp_pin_read = tegra_gpio_pin_read;
204 	bank->bank_gc.gp_pin_write = tegra_gpio_pin_write;
205 	bank->bank_gc.gp_pin_ctl = tegra_gpio_pin_ctl;
206 
207 	const uint32_t cnf = GPIO_READ(bank, GPIO_CNF_REG);
208 
209 	for (pin = 0; pin < __arraycount(bank->bank_pins); pin++) {
210 		bank->bank_pins[pin].pin_num = pin;
211 		/* skip pins in SFIO mode */
212 		if ((cnf & __BIT(pin)) == 0)
213 			continue;
214 		bank->bank_pins[pin].pin_caps =
215 		    GPIO_PIN_INPUT | GPIO_PIN_OUTPUT |
216 		    GPIO_PIN_TRISTATE;
217 		bank->bank_pins[pin].pin_state =
218 		    tegra_gpio_pin_read(bank, pin);
219 	}
220 
221 	memset(&gba, 0, sizeof(gba));
222 	gba.gba_gc = &bank->bank_gc;
223 	gba.gba_pins = bank->bank_pins;
224 	gba.gba_npins = __arraycount(bank->bank_pins);
225 
226 	bank->bank_dev = config_found_ia(sc->sc_dev, "gpiobus", &gba,
227 	    tegra_gpio_cfprint);
228 }
229 
230 static int
231 tegra_gpio_cfprint(void *priv, const char *pnp)
232 {
233 	struct gpiobus_attach_args *gba = priv;
234 	struct tegra_gpio_bank *bank = gba->gba_gc->gp_cookie;
235 	const char *bankname = bank->bank_pb->name;
236 
237 	if (pnp)
238 		aprint_normal("gpiobus at %s", pnp);
239 
240 	aprint_normal(" (%s)", bankname);
241 
242 	return UNCONF;
243 }
244 
245 static int
246 tegra_gpio_pin_read(void *priv, int pin)
247 {
248 	struct tegra_gpio_bank *bank = priv;
249 
250 	const uint32_t v = GPIO_READ(bank, GPIO_IN_REG);
251 
252 	return (v >> pin) & 1;
253 }
254 
255 static void
256 tegra_gpio_pin_write(void *priv, int pin, int val)
257 {
258 	struct tegra_gpio_bank *bank = priv;
259 	uint32_t v;
260 
261 	v = (1 << (pin + 8));
262 	v |= (val << pin);
263 	GPIO_WRITE(bank, GPIO_MSK_OUT_REG, v);
264 }
265 
266 static void
267 tegra_gpio_pin_ctl(void *priv, int pin, int flags)
268 {
269 	struct tegra_gpio_bank *bank = priv;
270 	uint32_t v;
271 
272 	if (flags & GPIO_PIN_INPUT) {
273 		v = (1 << (pin + 8));
274 		GPIO_WRITE(bank, GPIO_MSK_OE_REG, v);
275 	} else if (flags & GPIO_PIN_OUTPUT) {
276 		v = (1 << (pin + 8));
277 		v |= (1 << pin);
278 		GPIO_WRITE(bank, GPIO_MSK_OE_REG, v);
279 	}
280 }
281 
282 static void *
283 tegra_gpio_fdt_acquire(device_t dev, const void *data, size_t len, int flags)
284 {
285 	struct tegra_gpio_bank gbank;
286 	struct tegra_gpio_pin *gpin;
287 	const u_int *gpio = data;
288 
289 	if (len != 12)
290 		return NULL;
291 
292 	const u_int bank = be32toh(gpio[1]) >> 3;
293 	const u_int pin = be32toh(gpio[1]) & 7;
294 	const bool actlo = be32toh(gpio[2]) & 1;
295 
296 	if (bank >= __arraycount(tegra_gpio_pinbanks) || pin > 8)
297 		return NULL;
298 
299 	gbank.bank_sc = device_private(dev);
300 	gbank.bank_pb = &tegra_gpio_pinbanks[bank];
301 
302 	const uint32_t cnf = GPIO_READ(&gbank, GPIO_CNF_REG);
303 	if ((cnf & __BIT(pin)) == 0)
304 		GPIO_WRITE(&gbank, GPIO_CNF_REG, cnf | __BIT(pin));
305 
306 	gpin = kmem_zalloc(sizeof(*gpin), KM_SLEEP);
307 	gpin->pin_bank = gbank;
308 	gpin->pin_no = pin;
309 	gpin->pin_flags = flags;
310 	gpin->pin_actlo = actlo;
311 
312 	tegra_gpio_pin_ctl(&gpin->pin_bank, gpin->pin_no, gpin->pin_flags);
313 
314 	return gpin;
315 }
316 
317 static void
318 tegra_gpio_fdt_release(device_t dev, void *priv)
319 {
320 	struct tegra_gpio_pin *gpin = priv;
321 
322 	tegra_gpio_release(gpin);
323 }
324 
325 static int
326 tegra_gpio_fdt_read(device_t dev, void *priv, bool raw)
327 {
328 	struct tegra_gpio_pin *gpin = priv;
329 	int val;
330 
331 	val = tegra_gpio_read(gpin);
332 
333 	if (!raw && gpin->pin_actlo)
334 		val = !val;
335 
336 	return val;
337 }
338 
339 static void
340 tegra_gpio_fdt_write(device_t dev, void *priv, int val, bool raw)
341 {
342 	struct tegra_gpio_pin *gpin = priv;
343 
344 	if (!raw && gpin->pin_actlo)
345 		val = !val;
346 
347 	tegra_gpio_write(gpin, val);
348 }
349 
350 static const struct tegra_gpio_pinbank *
351 tegra_gpio_pin_lookup(const char *pinname, int *ppin)
352 {
353 	char bankname[3];
354 	u_int n;
355 	int pin;
356 
357 	KASSERT(strlen(pinname) == 2 || strlen(pinname) == 3);
358 
359 	memset(bankname, 0, sizeof(bankname));
360 	bankname[0] = pinname[0];
361 	if (strlen(pinname) == 2) {
362 		pin = pinname[1] - '0';
363 	} else {
364 		bankname[1] = pinname[1];
365 		pin = pinname[2] - '0';
366 	}
367 
368 	for (n = 0; n < __arraycount(tegra_gpio_pinbanks); n++) {
369 		const struct tegra_gpio_pinbank *pb =
370 		    &tegra_gpio_pinbanks[n];
371 		if (strcmp(pb->name, bankname) == 0) {
372 			*ppin = pin;
373 			return pb;
374 		}
375 	}
376 
377 	return NULL;
378 }
379 
380 struct tegra_gpio_pin *
381 tegra_gpio_acquire(const char *pinname, u_int flags)
382 {
383 	struct tegra_gpio_bank bank;
384 	struct tegra_gpio_pin *gpin;
385 	int pin;
386 	device_t dev;
387 
388 	dev = device_find_by_driver_unit("tegragpio", 0);
389 	if (dev == NULL)
390 		return NULL;
391 
392 	bank.bank_sc = device_private(dev);
393 	bank.bank_pb = tegra_gpio_pin_lookup(pinname, &pin);
394 	if (bank.bank_pb == NULL)
395 		return NULL;
396 
397 	const uint32_t cnf = GPIO_READ(&bank, GPIO_CNF_REG);
398 	if ((cnf & __BIT(pin)) == 0)
399 		GPIO_WRITE(&bank, GPIO_CNF_REG, cnf | __BIT(pin));
400 
401 	gpin = kmem_alloc(sizeof(*gpin), KM_SLEEP);
402 	gpin->pin_bank = bank;
403 	gpin->pin_no = pin;
404 	gpin->pin_flags = flags;
405 
406 	tegra_gpio_pin_ctl(&gpin->pin_bank, gpin->pin_no, gpin->pin_flags);
407 
408 	return gpin;
409 }
410 
411 void
412 tegra_gpio_release(struct tegra_gpio_pin *gpin)
413 {
414 	tegra_gpio_pin_ctl(&gpin->pin_bank, gpin->pin_no, GPIO_PIN_INPUT);
415 	kmem_free(gpin, sizeof(*gpin));
416 }
417 
418 int
419 tegra_gpio_read(struct tegra_gpio_pin *gpin)
420 {
421 	int ret;
422 
423 	if (gpin->pin_flags & GPIO_PIN_INPUT) {
424 		ret = tegra_gpio_pin_read(&gpin->pin_bank, gpin->pin_no);
425 	} else {
426 		const uint32_t v = GPIO_READ(&gpin->pin_bank, GPIO_OUT_REG);
427 		ret = (v >> gpin->pin_no) & 1;
428 	}
429 
430 	return ret;
431 }
432 
433 void
434 tegra_gpio_write(struct tegra_gpio_pin *gpin, int val)
435 {
436 	KASSERT((gpin->pin_flags & GPIO_PIN_OUTPUT) != 0);
437 
438 	tegra_gpio_pin_write(&gpin->pin_bank, gpin->pin_no, val);
439 }
440