xref: /netbsd-src/sys/arch/arm/samsung/exynos_gpio.c (revision 61169b39c6fe0fa7d83d5b1cfceeaa085e9a0c94)
1 /*	$NetBSD: exynos_gpio.c,v 1.33 2022/02/11 23:48:50 riastradh Exp $ */
2 
3 /*-
4 * Copyright (c) 2014, 2020 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Reinoud Zandijk, and by Nick Hudson
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31 
32 #include "opt_exynos.h"
33 #include "opt_arm_debug.h"
34 #include "gpio.h"
35 
36 #include <sys/cdefs.h>
37 __KERNEL_RCSID(1, "$NetBSD: exynos_gpio.c,v 1.33 2022/02/11 23:48:50 riastradh Exp $");
38 
39 #include <sys/param.h>
40 #include <sys/bus.h>
41 #include <sys/device.h>
42 #include <sys/intr.h>
43 #include <sys/systm.h>
44 #include <sys/kmem.h>
45 #include <sys/gpio.h>
46 
47 #include <dev/gpio/gpiovar.h>
48 
49 #include <arm/samsung/exynos_reg.h>
50 #include <arm/samsung/exynos_var.h>
51 #include <arm/samsung/exynos_intr.h>
52 #include <arm/samsung/exynos_pinctrl.h>
53 
54 #include <dev/fdt/fdtvar.h>
55 
56 struct exynos_gpio_bank {
57 	const char		bank_name[6];
58 	device_t		bank_dev;
59 	struct gpio_chipset_tag	bank_gc;
60 	struct exynos_gpio_softc *bank_sc;
61 	gpio_pin_t		bank_pins[8];
62 
63 	const bus_addr_t	bank_core_offset;
64 	const uint8_t		bank_bits;
65 
66 	struct exynos_gpio_pin_cfg bank_cfg;
67 };
68 
69 struct exynos_gpio_pin {
70 	struct exynos_gpio_softc *pin_sc;
71 	int			  pin_no;
72 	u_int			  pin_flags;
73 	int			  pin_actlo;
74 	const struct exynos_gpio_bank   *pin_bank;
75 };
76 
77 
78 //#define GPIO_REG(v,s,o) (EXYNOS##v##_GPIO_##s##_OFFSET + (o))
79 #define GPIO_REG(v,s,o) ((o))
80 #define GPIO_GRP(v, s, o, n, b)	\
81 	{ \
82 		.bank_name = #n, \
83 		.bank_core_offset = GPIO_REG(v,s,o), \
84 		.bank_bits = b, \
85 	}
86 
87 #define GPIO_GRP_INTR(o, n, b, i)			\
88 	{ 						\
89 		.bank_name = #n,			\
90 		.bank_core_offset = GPIO_REG(v,s,o),	\
91 		.bank_bits = b,				\
92 	}
93 
94 #define GPIO_GRP_NONE(o, n, b)	\
95 	{ \
96 		.bank_name = #n, \
97 		.bank_core_offset = GPIO_REG(v,s,o), \
98 		.bank_bits = b, \
99 	}
100 
101 #define GPIO_GRP_WAKEUP(o, n, b, i)			\
102 	{ 						\
103 		.bank_name = #n,			\
104 		.bank_core_offset = GPIO_REG(v,s,o),	\
105 		.bank_bits = b,				\
106 	}
107 
108 
109 
110 static struct exynos_gpio_bank exynos5420_banks[] = {
111 	GPIO_GRP(5, MUXA, 0x0000, gpy7, 8),
112 	GPIO_GRP(5, MUXA, 0x0C00, gpx0, 8),
113 	GPIO_GRP(5, MUXA, 0x0C20, gpx1, 8),
114 	GPIO_GRP(5, MUXA, 0x0C40, gpx2, 8),
115 	GPIO_GRP(5, MUXA, 0x0C60, gpx3, 8),
116 
117 	GPIO_GRP(5, MUXB, 0x0000, gpc0, 8),
118 	GPIO_GRP(5, MUXB, 0x0020, gpc1, 8),
119 	GPIO_GRP(5, MUXB, 0x0040, gpc2, 7),
120 	GPIO_GRP(5, MUXB, 0x0060, gpc3, 4),
121 	GPIO_GRP(5, MUXB, 0x0080, gpc4, 2),
122 	GPIO_GRP(5, MUXB, 0x00A0, gpd1, 8),
123 	GPIO_GRP(5, MUXB, 0x00C0, gpy0, 6),
124 	GPIO_GRP(5, MUXB, 0x00E0, gpy1, 4),
125 	GPIO_GRP(5, MUXB, 0x0100, gpy2, 6),
126 	GPIO_GRP(5, MUXB, 0x0120, gpy3, 8),
127 	GPIO_GRP(5, MUXB, 0x0140, gpy4, 8),
128 	GPIO_GRP(5, MUXB, 0x0160, gpy5, 8),
129 	GPIO_GRP(5, MUXB, 0x0180, gpy6, 8),
130 
131 	GPIO_GRP(5, MUXC, 0x0000, gpe0, 8),
132 	GPIO_GRP(5, MUXC, 0x0020, gpe1, 2),
133 	GPIO_GRP(5, MUXC, 0x0040, gpf0, 6),
134 	GPIO_GRP(5, MUXC, 0x0060, gpf1, 8),
135 	GPIO_GRP(5, MUXC, 0x0080, gpg0, 8),
136 	GPIO_GRP(5, MUXC, 0x00A0, gpg1, 8),
137 	GPIO_GRP(5, MUXC, 0x00C0, gpg2, 2),
138 	GPIO_GRP(5, MUXC, 0x00E0, gpj4, 4),
139 
140 	GPIO_GRP(5, MUXD, 0x0000, gpa0, 8),
141 	GPIO_GRP(5, MUXD, 0x0020, gpa1, 6),
142 	GPIO_GRP(5, MUXD, 0x0040, gpa2, 8),
143 	GPIO_GRP(5, MUXD, 0x0060, gpb0, 5),
144 	GPIO_GRP(5, MUXD, 0x0080, gpb1, 5),
145 	GPIO_GRP(5, MUXD, 0x00A0, gpb2, 4),
146 	GPIO_GRP(5, MUXD, 0x00C0, gpb3, 8),
147 	GPIO_GRP(5, MUXD, 0x00E0, gpb4, 2),
148 	GPIO_GRP(5, MUXD, 0x0100, gph0, 4),
149 
150 	GPIO_GRP(5, MUXE, 0x0000, gpz, 7),
151 };
152 
153 struct exynos_pinctrl_banks exynos5420_pinctrl_banks = {
154 	.epb_banks = exynos5420_banks,
155 	.epb_nbanks = __arraycount(exynos5420_banks)
156 };
157 
158 static struct exynos_gpio_bank exynos5410_banks[] = {
159 	/* pin-controller 0 */
160 	GPIO_GRP_INTR(0x000, gpa0, 8, 0x00),
161 	GPIO_GRP_INTR(0x020, gpa1, 6, 0x04),
162 	GPIO_GRP_INTR(0x040, gpa2, 8, 0x08),
163 	GPIO_GRP_INTR(0x060, gpb0, 5, 0x0c),
164 	GPIO_GRP_INTR(0x080, gpb1, 5, 0x10),
165 	GPIO_GRP_INTR(0x0A0, gpb2, 4, 0x14),
166 	GPIO_GRP_INTR(0x0C0, gpb3, 4, 0x18),
167 	GPIO_GRP_INTR(0x0E0, gpc0, 7, 0x1c),
168 	GPIO_GRP_INTR(0x100, gpc3, 4, 0x20),
169 	GPIO_GRP_INTR(0x120, gpc1, 7, 0x24),
170 	GPIO_GRP_INTR(0x140, gpc2, 7, 0x28),
171 	GPIO_GRP_INTR(0x180, gpd1, 8, 0x2c),
172 	GPIO_GRP_INTR(0x1A0, gpe0, 8, 0x30),
173 	GPIO_GRP_INTR(0x1C0, gpe1, 2, 0x34),
174 	GPIO_GRP_INTR(0x1E0, gpf0, 6, 0x38),
175 	GPIO_GRP_INTR(0x200, gpf1, 8, 0x3c),
176 	GPIO_GRP_INTR(0x220, gpg0, 8, 0x40),
177 	GPIO_GRP_INTR(0x240, gpg1, 8, 0x44),
178 	GPIO_GRP_INTR(0x260, gpg2, 2, 0x48),
179 	GPIO_GRP_INTR(0x280, gph0, 4, 0x4c),
180 	GPIO_GRP_INTR(0x2A0, gph1, 8, 0x50),
181 	GPIO_GRP_NONE(0x160, gpm5, 2),
182 	GPIO_GRP_NONE(0x2C0, gpm7, 8),
183 	GPIO_GRP_NONE(0x2E0, gpy0, 6),
184 	GPIO_GRP_NONE(0x300, gpy1, 4),
185 	GPIO_GRP_NONE(0x320, gpy2, 6),
186 	GPIO_GRP_NONE(0x340, gpy3, 8),
187 	GPIO_GRP_NONE(0x360, gpy4, 8),
188 	GPIO_GRP_NONE(0x380, gpy5, 8),
189 	GPIO_GRP_NONE(0x3A0, gpy6, 8),
190 	GPIO_GRP_NONE(0x3C0, gpy7, 8),
191 	GPIO_GRP_WAKEUP(0xC00, gpx0, 8, 0x00),
192 	GPIO_GRP_WAKEUP(0xC20, gpx1, 8, 0x04),
193 	GPIO_GRP_WAKEUP(0xC40, gpx2, 8, 0x08),
194 	GPIO_GRP_WAKEUP(0xC60, gpx3, 8, 0x0c),
195 
196 	/* pin-controller 1 */
197 	GPIO_GRP_INTR(0x000, gpj0, 5, 0x00),
198 	GPIO_GRP_INTR(0x020, gpj1, 8, 0x04),
199 	GPIO_GRP_INTR(0x040, gpj2, 8, 0x08),
200 	GPIO_GRP_INTR(0x060, gpj3, 8, 0x0c),
201 	GPIO_GRP_INTR(0x080, gpj4, 2, 0x10),
202 	GPIO_GRP_INTR(0x0A0, gpk0, 8, 0x14),
203 	GPIO_GRP_INTR(0x0C0, gpk1, 8, 0x18),
204 	GPIO_GRP_INTR(0x0E0, gpk2, 8, 0x1c),
205 	GPIO_GRP_INTR(0x100, gpk3, 7, 0x20),
206 
207 	/* pin-controller 2 */
208 	GPIO_GRP_INTR(0x000, gpv0, 8, 0x00),
209 	GPIO_GRP_INTR(0x020, gpv1, 8, 0x04),
210 	GPIO_GRP_INTR(0x060, gpv2, 8, 0x08),
211 	GPIO_GRP_INTR(0x080, gpv3, 8, 0x0c),
212 	GPIO_GRP_INTR(0x0C0, gpv4, 2, 0x10),
213 
214 	/* pin-controller 2 */
215 	GPIO_GRP_INTR(0x000, gpz, 7, 0x00),
216 };
217 
218 struct exynos_pinctrl_banks exynos5410_pinctrl_banks = {
219 	.epb_banks = exynos5410_banks,
220 	.epb_nbanks = __arraycount(exynos5410_banks)
221 };
222 
223 
224 static int exynos_gpio_pin_read(void *, int);
225 static void exynos_gpio_pin_write(void *, int, int);
226 static void exynos_gpio_pin_ctl(void *, int, int);
227 static void *exynos_gpio_fdt_acquire(device_t, const void *,
228 				     size_t, int);
229 static void exynos_gpio_fdt_release(device_t, void *);
230 
231 static int exynos_gpio_fdt_read(device_t, void *, bool);
232 static void exynos_gpio_fdt_write(device_t, void *, int, bool);
233 static int exynos_gpio_cfprint(void *, const char *);
234 
235 struct fdtbus_gpio_controller_func exynos_gpio_funcs = {
236 	.acquire = exynos_gpio_fdt_acquire,
237 	.release = exynos_gpio_fdt_release,
238 	.read = exynos_gpio_fdt_read,
239 	.write = exynos_gpio_fdt_write
240 };
241 #define GPIO_WRITE(bank, reg, val) \
242 	bus_space_write_4((bank)->bank_sc->sc_bst, \
243 	    (bank)->bank_sc->sc_bsh, \
244 	    (bank)->bank_core_offset + (reg), (val))
245 #define GPIO_READ(bank, reg) \
246 	bus_space_read_4((bank)->bank_sc->sc_bst, \
247 	    (bank)->bank_sc->sc_bsh, \
248 	    (bank)->bank_core_offset + (reg))
249 
250 static int
exynos_gpio_cfprint(void * priv,const char * pnp)251 exynos_gpio_cfprint(void *priv, const char *pnp)
252 {
253 	struct gpiobus_attach_args *gba = priv;
254 	struct exynos_gpio_bank *bank = gba->gba_gc->gp_cookie;
255 	const char *bankname = bank->bank_name;
256 
257 	if (pnp)
258 		aprint_normal("gpiobus at %s", pnp);
259 
260 	aprint_normal(" (%s)", bankname);
261 
262 	return UNCONF;
263 }
264 
265 static int
exynos_gpio_pin_read(void * cookie,int pin)266 exynos_gpio_pin_read(void *cookie, int pin)
267 {
268 	struct exynos_gpio_bank * const bank = cookie;
269 	uint8_t val;
270 
271 	KASSERT(pin < bank->bank_bits);
272 	val = bus_space_read_1(bank->bank_sc->sc_bst, bank->bank_sc->sc_bsh,
273 	    EXYNOS_GPIO_DAT);
274 
275 	return __SHIFTOUT(val, __BIT(pin));
276 }
277 
278 static void
exynos_gpio_pin_write(void * cookie,int pin,int value)279 exynos_gpio_pin_write(void *cookie, int pin, int value)
280 {
281 	struct exynos_gpio_bank * const bank = cookie;
282 	int val;
283 
284 	KASSERT(pin < bank->bank_bits);
285 	val = bus_space_read_1(bank->bank_sc->sc_bst, bank->bank_sc->sc_bsh,
286 	    EXYNOS_GPIO_DAT);
287 	val &= ~__BIT(pin);
288 	if (value)
289 		val |= __BIT(pin);
290 	bus_space_write_1(bank->bank_sc->sc_bst, bank->bank_sc->sc_bsh,
291 	    EXYNOS_GPIO_DAT, val);
292 }
293 
294 static void
exynos_gpio_pin_ctl(void * cookie,int pin,int flags)295 exynos_gpio_pin_ctl(void *cookie, int pin, int flags)
296 {
297 	struct exynos_gpio_bank * const bank = cookie;
298 	struct exynos_gpio_pin_cfg ncfg = { 0 };
299 
300 	/* honour pullup requests */
301 	if (flags & GPIO_PIN_PULLUP) {
302 		ncfg.pud = EXYNOS_GPIO_PIN_PULL_UP;
303 		ncfg.pud_valid = true;
304 	}
305 	if (flags & GPIO_PIN_PULLDOWN) {
306 		ncfg.pud = EXYNOS_GPIO_PIN_PULL_DOWN;
307 		ncfg.pud_valid = true;
308 	}
309 
310 	/* honour i/o */
311 	if (flags & GPIO_PIN_INPUT) {
312 		ncfg.cfg = EXYNOS_GPIO_FUNC_INPUT;
313 		ncfg.cfg_valid = true;
314 	} else if (flags & GPIO_PIN_OUTPUT) {
315 		ncfg.cfg = EXYNOS_GPIO_FUNC_OUTPUT;
316 		ncfg.cfg_valid = true;
317 	}
318 
319 	/* update any config registers that changed */
320 	exynos_gpio_pin_ctl_write(bank, &ncfg, pin);
321 }
322 
exynos_gpio_pin_ctl_write(const struct exynos_gpio_bank * bank,const struct exynos_gpio_pin_cfg * cfg,int pin)323 void exynos_gpio_pin_ctl_write(const struct exynos_gpio_bank *bank,
324 			       const struct exynos_gpio_pin_cfg *cfg,
325 			       int pin)
326 {
327 	uint32_t val;
328 
329 	if (cfg->cfg_valid) {
330 		val = GPIO_READ(bank, EXYNOS_GPIO_CON);
331 		val &= ~(0xf << (pin * 4));
332 		val |= (cfg->cfg << (pin * 4));
333 		GPIO_WRITE(bank, EXYNOS_GPIO_CON, val);
334 	}
335 
336 	if (cfg->pud_valid) {
337 		val = GPIO_READ(bank, EXYNOS_GPIO_PUD);
338 		val &= ~(0x3 << (pin * 2));
339 		val |= (cfg->pud << (pin * 2));
340 		GPIO_WRITE(bank, EXYNOS_GPIO_PUD, val);
341 	}
342 
343 	if (cfg->drv_valid) {
344 		val = GPIO_READ(bank, EXYNOS_GPIO_DRV);
345 		val &= ~(0x3 << (pin * 2));
346 		val |= (cfg->drv << (pin * 2));
347 		GPIO_WRITE(bank, EXYNOS_GPIO_DRV, val);
348 	}
349 
350 	if (cfg->conpwd_valid) {
351 		val = GPIO_READ(bank, EXYNOS_GPIO_CONPWD);
352 		val &= ~(0x3 << (pin * 2));
353 		val |= (cfg->conpwd << (pin * 2));
354 		GPIO_WRITE(bank, EXYNOS_GPIO_CONPWD, val);
355 	}
356 
357 	if (cfg->pudpwd_valid) {
358 		val = GPIO_READ(bank, EXYNOS_GPIO_PUDPWD);
359 		val &= ~(0x3 << (pin * 2));
360 		val |= (cfg->pudpwd << (pin * 2));
361 		GPIO_WRITE(bank, EXYNOS_GPIO_PUDPWD, val);
362 	}
363 }
364 
365 struct exynos_gpio_softc *
exynos_gpio_bank_config(struct exynos_pinctrl_softc * parent,const struct fdt_attach_args * faa,int node)366 exynos_gpio_bank_config(struct exynos_pinctrl_softc * parent,
367 			const struct fdt_attach_args *faa, int node)
368 {
369 	struct exynos_gpio_softc *sc = kmem_zalloc(sizeof(*sc), KM_SLEEP);
370 	struct gpiobus_attach_args gba;
371 	struct gpio_chipset_tag *gc_tag;
372 	char result[64];
373 
374 	OF_getprop(node, "name", result, sizeof(result));
375 	struct exynos_gpio_bank *bank =
376 	    exynos_gpio_bank_lookup(parent->sc_epb, result);
377 	if (bank == NULL) {
378 		aprint_error_dev(parent->sc_dev, "no bank found for %s\n",
379 		    result);
380 		return NULL;
381 	}
382 
383 	sc->sc_dev = parent->sc_dev;
384 	sc->sc_bst = &armv7_generic_bs_tag;
385 	sc->sc_bsh = parent->sc_bsh;
386 	sc->sc_bank = bank;
387 
388 	gc_tag = &bank->bank_gc;
389 	gc_tag->gp_cookie = bank;
390 	gc_tag->gp_pin_read  = exynos_gpio_pin_read;
391 	gc_tag->gp_pin_write = exynos_gpio_pin_write;
392 	gc_tag->gp_pin_ctl   = exynos_gpio_pin_ctl;
393 	memset(&gba, 0, sizeof(gba));
394 	gba.gba_gc = &bank->bank_gc;
395 	gba.gba_pins = bank->bank_pins;
396 	gba.gba_npins = bank->bank_bits;
397 
398 	bank->bank_sc = sc;
399 	bank->bank_dev =
400 	    config_found(parent->sc_dev, &gba, exynos_gpio_cfprint, CFARGS_NONE);
401 
402 	/* read in our initial settings */
403 	bank->bank_cfg.cfg = GPIO_READ(bank, EXYNOS_GPIO_CON);
404 	bank->bank_cfg.pud = GPIO_READ(bank, EXYNOS_GPIO_PUD);
405 	bank->bank_cfg.drv = GPIO_READ(bank, EXYNOS_GPIO_DRV);
406 	bank->bank_cfg.conpwd = GPIO_READ(bank, EXYNOS_GPIO_CONPWD);
407 	bank->bank_cfg.pudpwd = GPIO_READ(bank, EXYNOS_GPIO_PUDPWD);
408 
409 	fdtbus_register_gpio_controller(bank->bank_dev, node,
410 					&exynos_gpio_funcs);
411 	return sc;
412 }
413 
414 /*
415  * This function is a bit funky.  Given a string that may look like
416  * 'gpAN' or 'gpAN-P' it is meant to find a match to the part before
417  * the '-', or the four character string if the dash is not present.
418  */
419 struct exynos_gpio_bank *
exynos_gpio_bank_lookup(const struct exynos_pinctrl_banks * epb,const char * name)420 exynos_gpio_bank_lookup(const struct exynos_pinctrl_banks *epb,
421     const char *name)
422 {
423 	struct exynos_gpio_bank *bank;
424 
425 	for (u_int n = 0; n < epb->epb_nbanks; n++) {
426 		bank = &epb->epb_banks[n];
427 		if (!strncmp(bank->bank_name, name,
428 			     strlen(bank->bank_name))) {
429 			return bank;
430 		}
431 	}
432 
433 	return NULL;
434 }
435 
436 #if notyet
437 static int
exynos_gpio_pin_lookup(const char * name)438 exynos_gpio_pin_lookup(const char *name)
439 {
440 	char *p;
441 
442 	p = strchr(name, '-');
443 	if (p == NULL || p[1] < '0' || p[1] > '9')
444 		return -1;
445 
446 	return p[1] - '0';
447 }
448 #endif
449 
450 static void *
exynos_gpio_fdt_acquire(device_t dev,const void * data,size_t len,int flags)451 exynos_gpio_fdt_acquire(device_t dev, const void *data, size_t len, int flags)
452 {
453 	device_t parent = device_parent(dev);
454 	struct exynos_pinctrl_softc *sc = device_private(parent);
455 	const struct exynos_pinctrl_banks *epb = sc->sc_epb;
456 	struct exynos_gpio_bank *bank = NULL;
457 	struct exynos_gpio_pin *gpin;
458 	u_int n;
459 
460 	KASSERT(device_is_a(parent, "exyopctl"));
461 
462 	if (len != 12)
463 		return NULL;
464 
465 	const u_int *cells = data;
466 	const int pin = be32toh(cells[1]) & 0x0f;
467 	const int actlo = be32toh(cells[2]) & 0x01;
468 
469 	for (n = 0; n < epb->epb_nbanks; n++) {
470 		if (epb->epb_banks[n].bank_dev == dev) {
471 			bank = &epb->epb_banks[n];
472 			break;
473 		}
474 	}
475 	KASSERTMSG(bank != NULL, "no such gpio bank child of %s @ %p: %s @ %p",
476 	    device_xname(parent), parent, device_xname(dev), dev);
477 
478 	gpin = kmem_alloc(sizeof(*gpin), KM_SLEEP);
479 	gpin->pin_sc = bank->bank_sc;
480 	gpin->pin_bank = bank;
481 	gpin->pin_no = pin;
482 	gpin->pin_flags = flags;
483 	gpin->pin_actlo = actlo;
484 
485 	exynos_gpio_pin_ctl(bank, gpin->pin_no, gpin->pin_flags);
486 
487 	return gpin;
488 }
489 
490 static void
exynos_gpio_fdt_release(device_t dev,void * priv)491 exynos_gpio_fdt_release(device_t dev, void *priv)
492 {
493 	struct exynos_gpio_pin *gpin = priv;
494 
495 	kmem_free(gpin, sizeof(*gpin));
496 }
497 
498 static int
exynos_gpio_fdt_read(device_t dev,void * priv,bool raw)499 exynos_gpio_fdt_read(device_t dev, void *priv, bool raw)
500 {
501 	struct exynos_gpio_pin *gpin = priv;
502 	int val;
503 
504 	val = (bus_space_read_1(gpin->pin_sc->sc_bst,
505 				 gpin->pin_sc->sc_bsh,
506 				 EXYNOS_GPIO_DAT) >> gpin->pin_no) & 1;
507 
508 	if (!raw && gpin->pin_actlo)
509 		val = !val;
510 
511 	return val;
512 }
513 
514 static void
exynos_gpio_fdt_write(device_t dev,void * priv,int val,bool raw)515 exynos_gpio_fdt_write(device_t dev, void *priv, int val, bool raw)
516 {
517 	struct exynos_gpio_pin *gpin = priv;
518 
519 	if (!raw && gpin->pin_actlo)
520 		val = !val;
521 
522 	val = bus_space_read_1(gpin->pin_sc->sc_bst,
523 			       gpin->pin_sc->sc_bsh,
524 			       EXYNOS_GPIO_DAT);
525 	val &= ~__BIT(gpin->pin_no);
526 	if (val)
527 		val |= __BIT(gpin->pin_no);
528 	bus_space_write_1(gpin->pin_sc->sc_bst,
529 			  gpin->pin_sc->sc_bsh,
530 			  EXYNOS_GPIO_DAT, val);
531 
532 }
533