2 * Copyright (c) 2016 Oleksandr Tymoshenko <gonzo@FreeBSD.org>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
32 #include <sys/param.h>
35 #include <sys/kernel.h>
36 #include <sys/module.h>
40 #include <machine/bus.h>
41 #include <machine/resource.h>
43 #include <contrib/dev/acpica/include/acpi.h>
44 #include <contrib/dev/acpica/include/accommon.h>
46 #include <dev/acpica/acpivar.h>
47 #include <dev/gpio/gpiobusvar.h>
52 * Macros for driver mutex locking
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), \
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)
68 /* Ignore function check, no info is available at the moment */
69 #define PADCONF_FUNC_ANY -1
71 #define GPIO_PIN_MAP(r, f) { .reg = (r), .pad_func = (f) }
73 struct bytgpio_softc {
74 ACPI_HANDLE sc_handle;
79 struct resource *sc_mem_res;
81 const char* sc_bank_prefix;
82 const struct pinmap_info *sc_pinpad_map;
83 /* List of current functions for pads shared by GPIO */
87 static int bytgpio_probe(device_t dev);
88 static int bytgpio_attach(device_t dev);
89 static int bytgpio_detach(device_t dev);
92 #define SCORE_BANK_PREFIX "GPIO_S0_SC"
93 const struct pinmap_info bytgpio_score_pins[] = {
101 GPIO_PIN_MAP(101, 0),
135 GPIO_PIN_MAP(105, 0),
148 GPIO_PIN_MAP(103, 0),
190 GPIO_PIN_MAP(106, 0),
193 GPIO_PIN_MAP(104, 0),
198 #define SCORE_PINS nitems(bytgpio_score_pins)
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)
232 #define NCORE_PINS nitems(bytgpio_ncore_pins)
235 #define SUS_BANK_PREFIX "GPIO_S5_"
236 const struct pinmap_info bytgpio_sus_pins[] = {
283 #define SUS_PINS nitems(bytgpio_sus_pins)
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)
294 static inline uint32_t
295 bytgpio_read_4(struct bytgpio_softc *sc, bus_size_t off)
297 return (bus_read_4(sc->sc_mem_res, off));
301 bytgpio_write_4(struct bytgpio_softc *sc, bus_size_t off,
304 bus_write_4(sc->sc_mem_res, off, val);
308 bytgpio_get_bus(device_t dev)
310 struct bytgpio_softc *sc;
312 sc = device_get_softc(dev);
314 return (sc->sc_busdev);
318 bytgpio_pin_max(device_t dev, int *maxpin)
320 struct bytgpio_softc *sc;
322 sc = device_get_softc(dev);
324 *maxpin = sc->sc_npins - 1;
330 bytgpio_valid_pin(struct bytgpio_softc *sc, int pin)
333 if (pin >= sc->sc_npins || sc->sc_mem_res == NULL)
340 * Returns true if pad configured to be used as GPIO
343 bytgpio_pad_is_gpio(struct bytgpio_softc *sc, int pin)
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))
353 bytgpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
355 struct bytgpio_softc *sc;
357 sc = device_get_softc(dev);
358 if (bytgpio_valid_pin(sc, pin) != 0)
362 if (bytgpio_pad_is_gpio(sc, pin))
363 *caps = GPIO_PIN_INPUT | GPIO_PIN_OUTPUT;
369 bytgpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
371 struct bytgpio_softc *sc;
374 sc = device_get_softc(dev);
375 if (bytgpio_valid_pin(sc, pin) != 0)
379 if (!bytgpio_pad_is_gpio(sc, pin))
382 /* Get the current pin state */
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;
389 * this bit can be cleared to read current output value
390 * sou output bit takes precedense
392 else if ((val & BYTGPIO_PAD_VAL_I_INPUT_ENABLED) == 0)
393 *flags |= GPIO_PIN_INPUT;
400 bytgpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
402 struct bytgpio_softc *sc;
406 sc = device_get_softc(dev);
407 if (bytgpio_valid_pin(sc, pin) != 0)
410 if (bytgpio_pad_is_gpio(sc, pin))
411 allowed = GPIO_PIN_INPUT | GPIO_PIN_OUTPUT;
416 * Only directtion flag allowed
418 if (flags & ~allowed)
422 * Not both directions simultaneously
424 if ((flags & allowed) == allowed)
427 /* Set the GPIO mode and state */
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);
443 bytgpio_pin_getname(device_t dev, uint32_t pin, char *name)
445 struct bytgpio_softc *sc;
447 sc = device_get_softc(dev);
448 if (bytgpio_valid_pin(sc, pin) != 0)
451 /* Set a very simple name */
452 snprintf(name, GPIOMAXNAME, "%s%u", sc->sc_bank_prefix, pin);
453 name[GPIOMAXNAME - 1] = '\0';
459 bytgpio_pin_set(device_t dev, uint32_t pin, unsigned int value)
461 struct bytgpio_softc *sc;
464 sc = device_get_softc(dev);
465 if (bytgpio_valid_pin(sc, pin) != 0)
468 if (!bytgpio_pad_is_gpio(sc, pin))
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;
477 val = val | BYTGPIO_PAD_VAL_LEVEL;
478 bytgpio_write_4(sc, reg, val);
485 bytgpio_pin_get(device_t dev, uint32_t pin, unsigned int *value)
487 struct bytgpio_softc *sc;
490 sc = device_get_softc(dev);
491 if (bytgpio_valid_pin(sc, pin) != 0)
494 * Report non-GPIO pads as pin LOW
496 if (!bytgpio_pad_is_gpio(sc, pin)) {
497 *value = GPIO_PIN_LOW;
502 reg = BYGPIO_PIN_REGISTER(sc, pin, BYTGPIO_PAD_VAL);
504 * And read actual value
506 val = bytgpio_read_4(sc, reg);
507 if (val & BYTGPIO_PAD_VAL_LEVEL)
508 *value = GPIO_PIN_HIGH;
510 *value = GPIO_PIN_LOW;
517 bytgpio_pin_toggle(device_t dev, uint32_t pin)
519 struct bytgpio_softc *sc;
522 sc = device_get_softc(dev);
523 if (bytgpio_valid_pin(sc, pin) != 0)
526 if (!bytgpio_pad_is_gpio(sc, pin))
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);
541 bytgpio_probe(device_t dev)
543 static char *gpio_ids[] = { "INT33FC", NULL };
546 if (acpi_disabled("gpio"))
548 rv = ACPI_ID_PROBE(device_get_parent(dev), dev, gpio_ids, NULL);
550 device_set_desc(dev, "Intel Baytrail GPIO Controller");
555 bytgpio_attach(device_t dev)
557 struct bytgpio_softc *sc;
563 sc = device_get_softc(dev);
565 sc->sc_handle = acpi_get_handle(dev);
566 status = acpi_GetInteger(sc->sc_handle, "_UID", &uid);
567 if (ACPI_FAILURE(status)) {
568 device_printf(dev, "failed to read _UID\n");
572 BYTGPIO_LOCK_INIT(sc);
576 sc->sc_npins = SCORE_PINS;
577 sc->sc_bank_prefix = SCORE_BANK_PREFIX;
578 sc->sc_pinpad_map = bytgpio_score_pins;
581 sc->sc_npins = NCORE_PINS;
582 sc->sc_bank_prefix = NCORE_BANK_PREFIX;
583 sc->sc_pinpad_map = bytgpio_ncore_pins;
586 sc->sc_npins = SUS_PINS;
587 sc->sc_bank_prefix = SUS_BANK_PREFIX;
588 sc->sc_pinpad_map = bytgpio_sus_pins;
591 device_printf(dev, "invalid _UID value: %d\n", uid);
595 sc->sc_pad_funcs = malloc(sizeof(int)*sc->sc_npins, M_DEVBUF,
599 sc->sc_mem_res = bus_alloc_resource_any(sc->sc_dev,
600 SYS_RES_MEMORY, &sc->sc_mem_rid, RF_ACTIVE);
601 if (sc->sc_mem_res == NULL) {
602 device_printf(dev, "can't allocate resource\n");
606 for (pin = 0; pin < sc->sc_npins; pin++) {
607 reg = BYGPIO_PIN_REGISTER(sc, pin, BYTGPIO_PCONF0);
608 val = bytgpio_read_4(sc, reg);
609 sc->sc_pad_funcs[pin] = val & BYTGPIO_PCONF0_FUNC_MASK;
612 sc->sc_busdev = gpiobus_attach_bus(dev);
613 if (sc->sc_busdev == NULL) {
614 BYTGPIO_LOCK_DESTROY(sc);
615 bus_release_resource(dev, SYS_RES_MEMORY,
616 sc->sc_mem_rid, sc->sc_mem_res);
623 BYTGPIO_LOCK_DESTROY(sc);
630 bytgpio_detach(device_t dev)
632 struct bytgpio_softc *sc;
634 sc = device_get_softc(dev);
637 gpiobus_detach_bus(dev);
639 BYTGPIO_LOCK_DESTROY(sc);
641 if (sc->sc_pad_funcs)
642 free(sc->sc_pad_funcs, M_DEVBUF);
644 if (sc->sc_mem_res != NULL)
645 bus_release_resource(dev, SYS_RES_MEMORY,
646 sc->sc_mem_rid, sc->sc_mem_res);
651 static device_method_t bytgpio_methods[] = {
652 /* Device interface */
653 DEVMETHOD(device_probe, bytgpio_probe),
654 DEVMETHOD(device_attach, bytgpio_attach),
655 DEVMETHOD(device_detach, bytgpio_detach),
658 DEVMETHOD(gpio_get_bus, bytgpio_get_bus),
659 DEVMETHOD(gpio_pin_max, bytgpio_pin_max),
660 DEVMETHOD(gpio_pin_getname, bytgpio_pin_getname),
661 DEVMETHOD(gpio_pin_getflags, bytgpio_pin_getflags),
662 DEVMETHOD(gpio_pin_getcaps, bytgpio_pin_getcaps),
663 DEVMETHOD(gpio_pin_setflags, bytgpio_pin_setflags),
664 DEVMETHOD(gpio_pin_get, bytgpio_pin_get),
665 DEVMETHOD(gpio_pin_set, bytgpio_pin_set),
666 DEVMETHOD(gpio_pin_toggle, bytgpio_pin_toggle),
671 static driver_t bytgpio_driver = {
674 sizeof(struct bytgpio_softc),
677 static devclass_t bytgpio_devclass;
678 DRIVER_MODULE(bytgpio, acpi, bytgpio_driver, bytgpio_devclass, 0, 0);
679 MODULE_DEPEND(bytgpio, acpi, 1, 1, 1);
680 MODULE_DEPEND(bytgpio, gpiobus, 1, 1, 1);