xref: /freebsd/sys/dev/gpio/bytgpio.c (revision 4928135658a9d0eaee37003df6137ab363fcb0b4)
1 /*-
2  * Copyright (c) 2016 Oleksandr Tymoshenko <gonzo@FreeBSD.org>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26 
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
29 
30 #include "opt_acpi.h"
31 
32 #include <sys/param.h>
33 #include <sys/bus.h>
34 #include <sys/gpio.h>
35 #include <sys/kernel.h>
36 #include <sys/module.h>
37 #include <sys/proc.h>
38 #include <sys/rman.h>
39 
40 #include <machine/bus.h>
41 #include <machine/resource.h>
42 
43 #include <contrib/dev/acpica/include/acpi.h>
44 #include <contrib/dev/acpica/include/accommon.h>
45 
46 #include <dev/acpica/acpivar.h>
47 #include <dev/gpio/gpiobusvar.h>
48 
49 #include "gpio_if.h"
50 
51 /**
52  *	Macros for driver mutex locking
53  */
54 #define	BYTGPIO_LOCK(_sc)		mtx_lock_spin(&(_sc)->sc_mtx)
55 #define	BYTGPIO_UNLOCK(_sc)		mtx_unlock_spin(&(_sc)->sc_mtx)
56 #define	BYTGPIO_LOCK_INIT(_sc)		\
57 	mtx_init(&_sc->sc_mtx, device_get_nameunit((_sc)->sc_dev), \
58 	    "bytgpio", MTX_SPIN)
59 #define	BYTGPIO_LOCK_DESTROY(_sc)	mtx_destroy(&(_sc)->sc_mtx)
60 #define	BYTGPIO_ASSERT_LOCKED(_sc)	mtx_assert(&(_sc)->sc_mtx, MA_OWNED)
61 #define	BYTGPIO_ASSERT_UNLOCKED(_sc)	mtx_assert(&(_sc)->sc_mtx, MA_NOTOWNED)
62 
63 struct pinmap_info {
64     int reg;
65     int pad_func;
66 };
67 
68 /* Ignore function check, no info is available at the moment */
69 #define	PADCONF_FUNC_ANY	-1
70 
71 #define	GPIO_PIN_MAP(r, f) { .reg = (r), .pad_func = (f) }
72 
73 struct bytgpio_softc {
74 	ACPI_HANDLE		sc_handle;
75 	device_t		sc_dev;
76 	device_t		sc_busdev;
77 	struct mtx		sc_mtx;
78 	int			sc_mem_rid;
79 	struct resource		*sc_mem_res;
80 	int			sc_npins;
81 	const char*		sc_bank_prefix;
82 	const struct pinmap_info	*sc_pinpad_map;
83 	/* List of current functions for pads shared by GPIO */
84 	int			*sc_pad_funcs;
85 };
86 
87 static int	bytgpio_probe(device_t dev);
88 static int	bytgpio_attach(device_t dev);
89 static int	bytgpio_detach(device_t dev);
90 
91 #define	SCORE_UID		1
92 #define	SCORE_BANK_PREFIX	"GPIO_S0_SC"
93 const struct pinmap_info bytgpio_score_pins[] = {
94 	GPIO_PIN_MAP(85, 0),
95 	GPIO_PIN_MAP(89, 0),
96 	GPIO_PIN_MAP(93, 0),
97 	GPIO_PIN_MAP(96, 0),
98 	GPIO_PIN_MAP(99, 0),
99 	GPIO_PIN_MAP(102, 0),
100 	GPIO_PIN_MAP(98, 0),
101 	GPIO_PIN_MAP(101, 0),
102 	GPIO_PIN_MAP(34, 0),
103 	GPIO_PIN_MAP(37, 0),
104 	GPIO_PIN_MAP(36, 0),
105 	GPIO_PIN_MAP(38, 0),
106 	GPIO_PIN_MAP(39, 0),
107 	GPIO_PIN_MAP(35, 0),
108 	GPIO_PIN_MAP(40, 0),
109 	GPIO_PIN_MAP(84, 0),
110 	GPIO_PIN_MAP(62, 0),
111 	GPIO_PIN_MAP(61, 0),
112 	GPIO_PIN_MAP(64, 0),
113 	GPIO_PIN_MAP(59, 0),
114 	GPIO_PIN_MAP(54, 0),
115 	GPIO_PIN_MAP(56, 0),
116 	GPIO_PIN_MAP(60, 0),
117 	GPIO_PIN_MAP(55, 0),
118 	GPIO_PIN_MAP(63, 0),
119 	GPIO_PIN_MAP(57, 0),
120 	GPIO_PIN_MAP(51, 0),
121 	GPIO_PIN_MAP(50, 0),
122 	GPIO_PIN_MAP(53, 0),
123 	GPIO_PIN_MAP(47, 0),
124 	GPIO_PIN_MAP(52, 0),
125 	GPIO_PIN_MAP(49, 0),
126 	GPIO_PIN_MAP(48, 0),
127 	GPIO_PIN_MAP(43, 0),
128 	GPIO_PIN_MAP(46, 0),
129 	GPIO_PIN_MAP(41, 0),
130 	GPIO_PIN_MAP(45, 0),
131 	GPIO_PIN_MAP(42, 0),
132 	GPIO_PIN_MAP(58, 0),
133 	GPIO_PIN_MAP(44, 0),
134 	GPIO_PIN_MAP(95, 0),
135 	GPIO_PIN_MAP(105, 0),
136 	GPIO_PIN_MAP(70, 0),
137 	GPIO_PIN_MAP(68, 0),
138 	GPIO_PIN_MAP(67, 0),
139 	GPIO_PIN_MAP(66, 0),
140 	GPIO_PIN_MAP(69, 0),
141 	GPIO_PIN_MAP(71, 0),
142 	GPIO_PIN_MAP(65, 0),
143 	GPIO_PIN_MAP(72, 0),
144 	GPIO_PIN_MAP(86, 0),
145 	GPIO_PIN_MAP(90, 0),
146 	GPIO_PIN_MAP(88, 0),
147 	GPIO_PIN_MAP(92, 0),
148 	GPIO_PIN_MAP(103, 0),
149 	GPIO_PIN_MAP(77, 0),
150 	GPIO_PIN_MAP(79, 0),
151 	GPIO_PIN_MAP(83, 0),
152 	GPIO_PIN_MAP(78, 0),
153 	GPIO_PIN_MAP(81, 0),
154 	GPIO_PIN_MAP(80, 0),
155 	GPIO_PIN_MAP(82, 0),
156 	GPIO_PIN_MAP(13, 0),
157 	GPIO_PIN_MAP(12, 0),
158 	GPIO_PIN_MAP(15, 0),
159 	GPIO_PIN_MAP(14, 0),
160 	GPIO_PIN_MAP(17, 0),
161 	GPIO_PIN_MAP(18, 0),
162 	GPIO_PIN_MAP(19, 0),
163 	GPIO_PIN_MAP(16, 0),
164 	GPIO_PIN_MAP(2, 0),
165 	GPIO_PIN_MAP(1, 0),
166 	GPIO_PIN_MAP(0, 0),
167 	GPIO_PIN_MAP(4, 0),
168 	GPIO_PIN_MAP(6, 0),
169 	GPIO_PIN_MAP(7, 0),
170 	GPIO_PIN_MAP(9, 0),
171 	GPIO_PIN_MAP(8, 0),
172 	GPIO_PIN_MAP(33, 0),
173 	GPIO_PIN_MAP(32, 0),
174 	GPIO_PIN_MAP(31, 0),
175 	GPIO_PIN_MAP(30, 0),
176 	GPIO_PIN_MAP(29, 0),
177 	GPIO_PIN_MAP(27, 0),
178 	GPIO_PIN_MAP(25, 0),
179 	GPIO_PIN_MAP(28, 0),
180 	GPIO_PIN_MAP(26, 0),
181 	GPIO_PIN_MAP(23, 0),
182 	GPIO_PIN_MAP(21, 0),
183 	GPIO_PIN_MAP(20, 0),
184 	GPIO_PIN_MAP(24, 0),
185 	GPIO_PIN_MAP(22, 0),
186 	GPIO_PIN_MAP(5, 1),
187 	GPIO_PIN_MAP(3, 1),
188 	GPIO_PIN_MAP(10, 0),
189 	GPIO_PIN_MAP(11, 0),
190 	GPIO_PIN_MAP(106, 0),
191 	GPIO_PIN_MAP(87, 0),
192 	GPIO_PIN_MAP(91, 0),
193 	GPIO_PIN_MAP(104, 0),
194 	GPIO_PIN_MAP(97, 0),
195 	GPIO_PIN_MAP(100, 0)
196 };
197 
198 #define	SCORE_PINS	nitems(bytgpio_score_pins)
199 
200 #define	NCORE_UID		2
201 #define	NCORE_BANK_PREFIX	"GPIO_S0_NC"
202 const struct pinmap_info bytgpio_ncore_pins[] = {
203 	GPIO_PIN_MAP(19, PADCONF_FUNC_ANY),
204 	GPIO_PIN_MAP(18, PADCONF_FUNC_ANY),
205 	GPIO_PIN_MAP(17, PADCONF_FUNC_ANY),
206 	GPIO_PIN_MAP(20, PADCONF_FUNC_ANY),
207 	GPIO_PIN_MAP(21, PADCONF_FUNC_ANY),
208 	GPIO_PIN_MAP(22, PADCONF_FUNC_ANY),
209 	GPIO_PIN_MAP(24, PADCONF_FUNC_ANY),
210 	GPIO_PIN_MAP(25, PADCONF_FUNC_ANY),
211 	GPIO_PIN_MAP(23, PADCONF_FUNC_ANY),
212 	GPIO_PIN_MAP(16, PADCONF_FUNC_ANY),
213 	GPIO_PIN_MAP(14, PADCONF_FUNC_ANY),
214 	GPIO_PIN_MAP(15, PADCONF_FUNC_ANY),
215 	GPIO_PIN_MAP(12, PADCONF_FUNC_ANY),
216 	GPIO_PIN_MAP(26, PADCONF_FUNC_ANY),
217 	GPIO_PIN_MAP(27, PADCONF_FUNC_ANY),
218 	GPIO_PIN_MAP(1, PADCONF_FUNC_ANY),
219 	GPIO_PIN_MAP(4, PADCONF_FUNC_ANY),
220 	GPIO_PIN_MAP(8, PADCONF_FUNC_ANY),
221 	GPIO_PIN_MAP(11, PADCONF_FUNC_ANY),
222 	GPIO_PIN_MAP(0, PADCONF_FUNC_ANY),
223 	GPIO_PIN_MAP(3, PADCONF_FUNC_ANY),
224 	GPIO_PIN_MAP(6, PADCONF_FUNC_ANY),
225 	GPIO_PIN_MAP(10, PADCONF_FUNC_ANY),
226 	GPIO_PIN_MAP(13, PADCONF_FUNC_ANY),
227 	GPIO_PIN_MAP(2, PADCONF_FUNC_ANY),
228 	GPIO_PIN_MAP(5, PADCONF_FUNC_ANY),
229 	GPIO_PIN_MAP(9, PADCONF_FUNC_ANY),
230 	GPIO_PIN_MAP(7, PADCONF_FUNC_ANY)
231 };
232 #define	NCORE_PINS	nitems(bytgpio_ncore_pins)
233 
234 #define	SUS_UID		3
235 #define	SUS_BANK_PREFIX	"GPIO_S5_"
236 const struct pinmap_info bytgpio_sus_pins[] = {
237 	GPIO_PIN_MAP(29, 0),
238 	GPIO_PIN_MAP(33, 0),
239 	GPIO_PIN_MAP(30, 0),
240 	GPIO_PIN_MAP(31, 0),
241 	GPIO_PIN_MAP(32, 0),
242 	GPIO_PIN_MAP(34, 0),
243 	GPIO_PIN_MAP(36, 0),
244 	GPIO_PIN_MAP(35, 0),
245 	GPIO_PIN_MAP(38, 0),
246 	GPIO_PIN_MAP(37, 0),
247 	GPIO_PIN_MAP(18, 0),
248 	GPIO_PIN_MAP(7, 1),
249 	GPIO_PIN_MAP(11, 1),
250 	GPIO_PIN_MAP(20, 1),
251 	GPIO_PIN_MAP(17, 1),
252 	GPIO_PIN_MAP(1, 1),
253 	GPIO_PIN_MAP(8, 1),
254 	GPIO_PIN_MAP(10, 1),
255 	GPIO_PIN_MAP(19, 1),
256 	GPIO_PIN_MAP(12, 1),
257 	GPIO_PIN_MAP(0, 1),
258 	GPIO_PIN_MAP(2, 1),
259 	GPIO_PIN_MAP(23, 0),
260 	GPIO_PIN_MAP(39, 0),
261 	GPIO_PIN_MAP(28, 0),
262 	GPIO_PIN_MAP(27, 0),
263 	GPIO_PIN_MAP(22, 0),
264 	GPIO_PIN_MAP(21, 0),
265 	GPIO_PIN_MAP(24, 0),
266 	GPIO_PIN_MAP(25, 0),
267 	GPIO_PIN_MAP(26, 0),
268 	GPIO_PIN_MAP(51, 0),
269 	GPIO_PIN_MAP(56, 0),
270 	GPIO_PIN_MAP(54, 0),
271 	GPIO_PIN_MAP(49, 0),
272 	GPIO_PIN_MAP(55, 0),
273 	GPIO_PIN_MAP(48, 0),
274 	GPIO_PIN_MAP(57, 0),
275 	GPIO_PIN_MAP(50, 0),
276 	GPIO_PIN_MAP(58, 0),
277 	GPIO_PIN_MAP(52, 0),
278 	GPIO_PIN_MAP(53, 0),
279 	GPIO_PIN_MAP(59, 0),
280 	GPIO_PIN_MAP(40, 0)
281 };
282 
283 #define	SUS_PINS	nitems(bytgpio_sus_pins)
284 
285 #define	BYGPIO_PIN_REGISTER(sc, pin, r)	((sc)->sc_pinpad_map[(pin)].reg * 16 + (r))
286 #define	BYTGPIO_PCONF0		0x0000
287 #define		BYTGPIO_PCONF0_FUNC_MASK	7
288 #define	BYTGPIO_PAD_VAL		0x0008
289 #define		BYTGPIO_PAD_VAL_LEVEL		(1 << 0)
290 #define		BYTGPIO_PAD_VAL_I_OUTPUT_ENABLED	(1 << 1)
291 #define		BYTGPIO_PAD_VAL_I_INPUT_ENABLED	(1 << 2)
292 #define		BYTGPIO_PAD_VAL_DIR_MASK		(3 << 1)
293 
294 static inline uint32_t
295 bytgpio_read_4(struct bytgpio_softc *sc, bus_size_t off)
296 {
297 	return (bus_read_4(sc->sc_mem_res, off));
298 }
299 
300 static inline void
301 bytgpio_write_4(struct bytgpio_softc *sc, bus_size_t off,
302     uint32_t val)
303 {
304 	bus_write_4(sc->sc_mem_res, off, val);
305 }
306 
307 static device_t
308 bytgpio_get_bus(device_t dev)
309 {
310 	struct bytgpio_softc *sc;
311 
312 	sc = device_get_softc(dev);
313 
314 	return (sc->sc_busdev);
315 }
316 
317 static int
318 bytgpio_pin_max(device_t dev, int *maxpin)
319 {
320 	struct bytgpio_softc *sc;
321 
322 	sc = device_get_softc(dev);
323 
324 	*maxpin = sc->sc_npins - 1;
325 
326 	return (0);
327 }
328 
329 static int
330 bytgpio_valid_pin(struct bytgpio_softc *sc, int pin)
331 {
332 
333 	if (pin >= sc->sc_npins || sc->sc_mem_res == NULL)
334 		return (EINVAL);
335 
336 	return (0);
337 }
338 
339 /*
340  * Returns true if pad configured to be used as GPIO
341  */
342 static bool
343 bytgpio_pad_is_gpio(struct bytgpio_softc *sc, int pin)
344 {
345 	if ((sc->sc_pinpad_map[pin].pad_func == PADCONF_FUNC_ANY) ||
346 	    (sc->sc_pad_funcs[pin] == sc->sc_pinpad_map[pin].pad_func))
347 		return (true);
348 	else
349 		return (false);
350 }
351 
352 static int
353 bytgpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
354 {
355 	struct bytgpio_softc *sc;
356 
357 	sc = device_get_softc(dev);
358 	if (bytgpio_valid_pin(sc, pin) != 0)
359 		return (EINVAL);
360 
361 	*caps = 0;
362 	if (bytgpio_pad_is_gpio(sc, pin))
363 		*caps = GPIO_PIN_INPUT | GPIO_PIN_OUTPUT;
364 
365 	return (0);
366 }
367 
368 static int
369 bytgpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
370 {
371 	struct bytgpio_softc *sc;
372 	uint32_t reg, val;
373 
374 	sc = device_get_softc(dev);
375 	if (bytgpio_valid_pin(sc, pin) != 0)
376 		return (EINVAL);
377 
378 	*flags = 0;
379 	if (!bytgpio_pad_is_gpio(sc, pin))
380 		return (0);
381 
382 	/* Get the current pin state */
383 	BYTGPIO_LOCK(sc);
384 	reg = BYGPIO_PIN_REGISTER(sc, pin, BYTGPIO_PAD_VAL);
385 	val = bytgpio_read_4(sc, reg);
386 	if ((val & BYTGPIO_PAD_VAL_I_OUTPUT_ENABLED) == 0)
387 		*flags |= GPIO_PIN_OUTPUT;
388 	/*
389 	 * this bit can be cleared to read current output value
390 	 * sou output bit takes precedense
391 	 */
392 	else if ((val & BYTGPIO_PAD_VAL_I_INPUT_ENABLED) == 0)
393 		*flags |= GPIO_PIN_INPUT;
394 	BYTGPIO_UNLOCK(sc);
395 
396 	return (0);
397 }
398 
399 static int
400 bytgpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
401 {
402 	struct bytgpio_softc *sc;
403 	uint32_t reg, val;
404 	uint32_t allowed;
405 
406 	sc = device_get_softc(dev);
407 	if (bytgpio_valid_pin(sc, pin) != 0)
408 		return (EINVAL);
409 
410 	if (bytgpio_pad_is_gpio(sc, pin))
411 		allowed = GPIO_PIN_INPUT | GPIO_PIN_OUTPUT;
412 	else
413 		allowed = 0;
414 
415 	/*
416 	 * Only directtion flag allowed
417 	 */
418 	if (flags & ~allowed)
419 		return (EINVAL);
420 
421 	/*
422 	 * Not both directions simultaneously
423 	 */
424 	if ((flags & allowed) == allowed)
425 		return (EINVAL);
426 
427 	/* Set the GPIO mode and state */
428 	BYTGPIO_LOCK(sc);
429 	reg = BYGPIO_PIN_REGISTER(sc, pin, BYTGPIO_PAD_VAL);
430 	val = bytgpio_read_4(sc, reg);
431 	val = val | BYTGPIO_PAD_VAL_DIR_MASK;
432 	if (flags & GPIO_PIN_INPUT)
433 		val = val & ~BYTGPIO_PAD_VAL_I_INPUT_ENABLED;
434 	if (flags & GPIO_PIN_OUTPUT)
435 		val = val & ~BYTGPIO_PAD_VAL_I_OUTPUT_ENABLED;
436 	bytgpio_write_4(sc, reg, val);
437 	BYTGPIO_UNLOCK(sc);
438 
439 	return (0);
440 }
441 
442 static int
443 bytgpio_pin_getname(device_t dev, uint32_t pin, char *name)
444 {
445 	struct bytgpio_softc *sc;
446 
447 	sc = device_get_softc(dev);
448 	if (bytgpio_valid_pin(sc, pin) != 0)
449 		return (EINVAL);
450 
451 	/* Set a very simple name */
452 	snprintf(name, GPIOMAXNAME, "%s%u", sc->sc_bank_prefix, pin);
453 	name[GPIOMAXNAME - 1] = '\0';
454 
455 	return (0);
456 }
457 
458 static int
459 bytgpio_pin_set(device_t dev, uint32_t pin, unsigned int value)
460 {
461 	struct bytgpio_softc *sc;
462 	uint32_t reg, val;
463 
464 	sc = device_get_softc(dev);
465 	if (bytgpio_valid_pin(sc, pin) != 0)
466 		return (EINVAL);
467 
468 	if (!bytgpio_pad_is_gpio(sc, pin))
469 		return (EINVAL);
470 
471 	BYTGPIO_LOCK(sc);
472 	reg = BYGPIO_PIN_REGISTER(sc, pin, BYTGPIO_PAD_VAL);
473 	val = bytgpio_read_4(sc, reg);
474 	if (value == GPIO_PIN_LOW)
475 		val = val & ~BYTGPIO_PAD_VAL_LEVEL;
476 	else
477 		val = val | BYTGPIO_PAD_VAL_LEVEL;
478 	bytgpio_write_4(sc, reg, val);
479 	BYTGPIO_UNLOCK(sc);
480 
481 	return (0);
482 }
483 
484 static int
485 bytgpio_pin_get(device_t dev, uint32_t pin, unsigned int *value)
486 {
487 	struct bytgpio_softc *sc;
488 	uint32_t reg, val;
489 
490 	sc = device_get_softc(dev);
491 	if (bytgpio_valid_pin(sc, pin) != 0)
492 		return (EINVAL);
493 	/*
494 	 * Report non-GPIO pads as pin LOW
495 	 */
496 	if (!bytgpio_pad_is_gpio(sc, pin)) {
497 		*value = GPIO_PIN_LOW;
498 		return (0);
499 	}
500 
501 	BYTGPIO_LOCK(sc);
502 	reg = BYGPIO_PIN_REGISTER(sc, pin, BYTGPIO_PAD_VAL);
503 	/*
504 	 * And read actual value
505 	 */
506 	val = bytgpio_read_4(sc, reg);
507 	if (val & BYTGPIO_PAD_VAL_LEVEL)
508 		*value = GPIO_PIN_HIGH;
509 	else
510 		*value = GPIO_PIN_LOW;
511 	BYTGPIO_UNLOCK(sc);
512 
513 	return (0);
514 }
515 
516 static int
517 bytgpio_pin_toggle(device_t dev, uint32_t pin)
518 {
519 	struct bytgpio_softc *sc;
520 	uint32_t reg, val;
521 
522 	sc = device_get_softc(dev);
523 	if (bytgpio_valid_pin(sc, pin) != 0)
524 		return (EINVAL);
525 
526 	if (!bytgpio_pad_is_gpio(sc, pin))
527 		return (EINVAL);
528 
529 	/* Toggle the pin */
530 	BYTGPIO_LOCK(sc);
531 	reg = BYGPIO_PIN_REGISTER(sc, pin, BYTGPIO_PAD_VAL);
532 	val = bytgpio_read_4(sc, reg);
533 	val = val ^ BYTGPIO_PAD_VAL_LEVEL;
534 	bytgpio_write_4(sc, reg, val);
535 	BYTGPIO_UNLOCK(sc);
536 
537 	return (0);
538 }
539 
540 static int
541 bytgpio_probe(device_t dev)
542 {
543 	static char *gpio_ids[] = { "INT33FC", NULL };
544 
545 	if (acpi_disabled("gpio") ||
546 	    ACPI_ID_PROBE(device_get_parent(dev), dev, gpio_ids) == NULL)
547 	return (ENXIO);
548 
549 	device_set_desc(dev, "Intel Baytrail GPIO Controller");
550 	return (0);
551 }
552 
553 static int
554 bytgpio_attach(device_t dev)
555 {
556 	struct bytgpio_softc	*sc;
557 	ACPI_STATUS status;
558 	int uid;
559 	int pin;
560 	uint32_t reg, val;
561 
562 	sc = device_get_softc(dev);
563 	sc->sc_dev = dev;
564 	sc->sc_handle = acpi_get_handle(dev);
565 	status = acpi_GetInteger(sc->sc_handle, "_UID", &uid);
566 	if (ACPI_FAILURE(status)) {
567 		device_printf(dev, "failed to read _UID\n");
568 		return (ENXIO);
569 	}
570 
571 	BYTGPIO_LOCK_INIT(sc);
572 
573 	switch (uid) {
574 	case SCORE_UID:
575 		sc->sc_npins = SCORE_PINS;
576 		sc->sc_bank_prefix = SCORE_BANK_PREFIX;
577 		sc->sc_pinpad_map = bytgpio_score_pins;
578 		break;
579 	case NCORE_UID:
580 		sc->sc_npins = NCORE_PINS;
581 		sc->sc_bank_prefix = NCORE_BANK_PREFIX;
582 		sc->sc_pinpad_map = bytgpio_ncore_pins;
583 		break;
584 	case SUS_UID:
585 		sc->sc_npins = SUS_PINS;
586 		sc->sc_bank_prefix = SUS_BANK_PREFIX;
587 		sc->sc_pinpad_map = bytgpio_sus_pins;
588 		break;
589 	default:
590 		device_printf(dev, "invalid _UID value: %d\n", uid);
591 		goto error;
592 	}
593 
594 	sc->sc_pad_funcs = malloc(sizeof(int)*sc->sc_npins, M_DEVBUF,
595 	    M_WAITOK | M_ZERO);
596 
597 	sc->sc_mem_rid = 0;
598 	sc->sc_mem_res = bus_alloc_resource_any(sc->sc_dev,
599 	    SYS_RES_MEMORY, &sc->sc_mem_rid, RF_ACTIVE);
600 	if (sc->sc_mem_res == NULL) {
601 		device_printf(dev, "can't allocate resource\n");
602 		goto error;
603 	}
604 
605 	for (pin = 0; pin < sc->sc_npins; pin++) {
606 	    reg = BYGPIO_PIN_REGISTER(sc, pin, BYTGPIO_PCONF0);
607 	    val = bytgpio_read_4(sc, reg);
608 	    sc->sc_pad_funcs[pin] = val & BYTGPIO_PCONF0_FUNC_MASK;
609 	}
610 
611 	sc->sc_busdev = gpiobus_attach_bus(dev);
612 	if (sc->sc_busdev == NULL) {
613 		BYTGPIO_LOCK_DESTROY(sc);
614 		bus_release_resource(dev, SYS_RES_MEMORY,
615 		    sc->sc_mem_rid, sc->sc_mem_res);
616 		return (ENXIO);
617 	}
618 
619 	return (0);
620 
621 error:
622 	BYTGPIO_LOCK_DESTROY(sc);
623 
624 	return (ENXIO);
625 }
626 
627 
628 static int
629 bytgpio_detach(device_t dev)
630 {
631 	struct bytgpio_softc	*sc;
632 
633 	sc = device_get_softc(dev);
634 
635 	if (sc->sc_busdev)
636 		gpiobus_detach_bus(dev);
637 
638 	BYTGPIO_LOCK_DESTROY(sc);
639 
640 	if (sc->sc_pad_funcs)
641 		free(sc->sc_pad_funcs, M_DEVBUF);
642 
643 	if (sc->sc_mem_res != NULL)
644 		bus_release_resource(dev, SYS_RES_MEMORY,
645 		    sc->sc_mem_rid, sc->sc_mem_res);
646 
647 	return (0);
648 }
649 
650 static device_method_t bytgpio_methods[] = {
651 	/* Device interface */
652 	DEVMETHOD(device_probe, bytgpio_probe),
653 	DEVMETHOD(device_attach, bytgpio_attach),
654 	DEVMETHOD(device_detach, bytgpio_detach),
655 
656 	/* GPIO protocol */
657 	DEVMETHOD(gpio_get_bus, bytgpio_get_bus),
658 	DEVMETHOD(gpio_pin_max, bytgpio_pin_max),
659 	DEVMETHOD(gpio_pin_getname, bytgpio_pin_getname),
660 	DEVMETHOD(gpio_pin_getflags, bytgpio_pin_getflags),
661 	DEVMETHOD(gpio_pin_getcaps, bytgpio_pin_getcaps),
662 	DEVMETHOD(gpio_pin_setflags, bytgpio_pin_setflags),
663 	DEVMETHOD(gpio_pin_get, bytgpio_pin_get),
664 	DEVMETHOD(gpio_pin_set, bytgpio_pin_set),
665 	DEVMETHOD(gpio_pin_toggle, bytgpio_pin_toggle),
666 
667 	DEVMETHOD_END
668 };
669 
670 static driver_t bytgpio_driver = {
671 	"gpio",
672 	bytgpio_methods,
673 	sizeof(struct bytgpio_softc),
674 };
675 
676 static devclass_t bytgpio_devclass;
677 DRIVER_MODULE(bytgpio, acpi, bytgpio_driver, bytgpio_devclass, 0, 0);
678 MODULE_DEPEND(bytgpio, acpi, 1, 1, 1);
679 MODULE_DEPEND(bytgpio, gpiobus, 1, 1, 1);
680