195a36367SOleksandr Tymoshenko /*- 295a36367SOleksandr Tymoshenko * Copyright (c) 2016 Oleksandr Tymoshenko <gonzo@FreeBSD.org> 395a36367SOleksandr Tymoshenko * All rights reserved. 495a36367SOleksandr Tymoshenko * 595a36367SOleksandr Tymoshenko * Redistribution and use in source and binary forms, with or without 695a36367SOleksandr Tymoshenko * modification, are permitted provided that the following conditions 795a36367SOleksandr Tymoshenko * are met: 895a36367SOleksandr Tymoshenko * 1. Redistributions of source code must retain the above copyright 995a36367SOleksandr Tymoshenko * notice, this list of conditions and the following disclaimer. 1095a36367SOleksandr Tymoshenko * 2. Redistributions in binary form must reproduce the above copyright 1195a36367SOleksandr Tymoshenko * notice, this list of conditions and the following disclaimer in the 1295a36367SOleksandr Tymoshenko * documentation and/or other materials provided with the distribution. 1395a36367SOleksandr Tymoshenko * 1495a36367SOleksandr Tymoshenko * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1595a36367SOleksandr Tymoshenko * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1695a36367SOleksandr Tymoshenko * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1795a36367SOleksandr Tymoshenko * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1895a36367SOleksandr Tymoshenko * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1995a36367SOleksandr Tymoshenko * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2095a36367SOleksandr Tymoshenko * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2195a36367SOleksandr Tymoshenko * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2295a36367SOleksandr Tymoshenko * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2395a36367SOleksandr Tymoshenko * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2495a36367SOleksandr Tymoshenko * SUCH DAMAGE. 2595a36367SOleksandr Tymoshenko */ 2695a36367SOleksandr Tymoshenko 2795a36367SOleksandr Tymoshenko #include <sys/cdefs.h> 2895a36367SOleksandr Tymoshenko #include "opt_acpi.h" 2995a36367SOleksandr Tymoshenko 3095a36367SOleksandr Tymoshenko #include <sys/param.h> 3195a36367SOleksandr Tymoshenko #include <sys/bus.h> 3295a36367SOleksandr Tymoshenko #include <sys/gpio.h> 3395a36367SOleksandr Tymoshenko #include <sys/kernel.h> 3495a36367SOleksandr Tymoshenko #include <sys/module.h> 3595a36367SOleksandr Tymoshenko #include <sys/proc.h> 3695a36367SOleksandr Tymoshenko #include <sys/rman.h> 3795a36367SOleksandr Tymoshenko 3895a36367SOleksandr Tymoshenko #include <machine/bus.h> 3995a36367SOleksandr Tymoshenko #include <machine/resource.h> 4095a36367SOleksandr Tymoshenko 4195a36367SOleksandr Tymoshenko #include <contrib/dev/acpica/include/acpi.h> 4295a36367SOleksandr Tymoshenko #include <contrib/dev/acpica/include/accommon.h> 4395a36367SOleksandr Tymoshenko 4495a36367SOleksandr Tymoshenko #include <dev/acpica/acpivar.h> 4595a36367SOleksandr Tymoshenko #include <dev/gpio/gpiobusvar.h> 4695a36367SOleksandr Tymoshenko 4795a36367SOleksandr Tymoshenko #include "gpio_if.h" 4895a36367SOleksandr Tymoshenko 4995a36367SOleksandr Tymoshenko /** 5095a36367SOleksandr Tymoshenko * Macros for driver mutex locking 5195a36367SOleksandr Tymoshenko */ 5295a36367SOleksandr Tymoshenko #define BYTGPIO_LOCK(_sc) mtx_lock_spin(&(_sc)->sc_mtx) 5395a36367SOleksandr Tymoshenko #define BYTGPIO_UNLOCK(_sc) mtx_unlock_spin(&(_sc)->sc_mtx) 5495a36367SOleksandr Tymoshenko #define BYTGPIO_LOCK_INIT(_sc) \ 5595a36367SOleksandr Tymoshenko mtx_init(&_sc->sc_mtx, device_get_nameunit((_sc)->sc_dev), \ 5695a36367SOleksandr Tymoshenko "bytgpio", MTX_SPIN) 5795a36367SOleksandr Tymoshenko #define BYTGPIO_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_mtx) 5895a36367SOleksandr Tymoshenko #define BYTGPIO_ASSERT_LOCKED(_sc) mtx_assert(&(_sc)->sc_mtx, MA_OWNED) 5995a36367SOleksandr Tymoshenko #define BYTGPIO_ASSERT_UNLOCKED(_sc) mtx_assert(&(_sc)->sc_mtx, MA_NOTOWNED) 6095a36367SOleksandr Tymoshenko 6106ae3ba3SOleksandr Tymoshenko struct pinmap_info { 6206ae3ba3SOleksandr Tymoshenko int reg; 6306ae3ba3SOleksandr Tymoshenko int pad_func; 6406ae3ba3SOleksandr Tymoshenko }; 6506ae3ba3SOleksandr Tymoshenko 6606ae3ba3SOleksandr Tymoshenko /* Ignore function check, no info is available at the moment */ 6706ae3ba3SOleksandr Tymoshenko #define PADCONF_FUNC_ANY -1 6806ae3ba3SOleksandr Tymoshenko 6906ae3ba3SOleksandr Tymoshenko #define GPIO_PIN_MAP(r, f) { .reg = (r), .pad_func = (f) } 7006ae3ba3SOleksandr Tymoshenko 7195a36367SOleksandr Tymoshenko struct bytgpio_softc { 7295a36367SOleksandr Tymoshenko ACPI_HANDLE sc_handle; 7395a36367SOleksandr Tymoshenko device_t sc_dev; 7495a36367SOleksandr Tymoshenko device_t sc_busdev; 7595a36367SOleksandr Tymoshenko struct mtx sc_mtx; 7695a36367SOleksandr Tymoshenko int sc_mem_rid; 7795a36367SOleksandr Tymoshenko struct resource *sc_mem_res; 7895a36367SOleksandr Tymoshenko int sc_npins; 7995a36367SOleksandr Tymoshenko const char* sc_bank_prefix; 8006ae3ba3SOleksandr Tymoshenko const struct pinmap_info *sc_pinpad_map; 8106ae3ba3SOleksandr Tymoshenko /* List of current functions for pads shared by GPIO */ 8206ae3ba3SOleksandr Tymoshenko int *sc_pad_funcs; 8395a36367SOleksandr Tymoshenko }; 8495a36367SOleksandr Tymoshenko 8595a36367SOleksandr Tymoshenko static int bytgpio_probe(device_t dev); 8695a36367SOleksandr Tymoshenko static int bytgpio_attach(device_t dev); 87fd980511SOleksandr Tymoshenko static int bytgpio_detach(device_t dev); 8895a36367SOleksandr Tymoshenko 8995a36367SOleksandr Tymoshenko #define SCORE_UID 1 9095a36367SOleksandr Tymoshenko #define SCORE_BANK_PREFIX "GPIO_S0_SC" 9106ae3ba3SOleksandr Tymoshenko const struct pinmap_info bytgpio_score_pins[] = { 9206ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(85, 0), 9306ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(89, 0), 9406ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(93, 0), 9506ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(96, 0), 9606ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(99, 0), 9706ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(102, 0), 9806ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(98, 0), 9906ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(101, 0), 10006ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(34, 0), 10106ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(37, 0), 10206ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(36, 0), 10306ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(38, 0), 10406ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(39, 0), 10506ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(35, 0), 10606ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(40, 0), 10706ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(84, 0), 10806ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(62, 0), 10906ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(61, 0), 11006ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(64, 0), 11106ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(59, 0), 11206ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(54, 0), 11306ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(56, 0), 11406ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(60, 0), 11506ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(55, 0), 11606ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(63, 0), 11706ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(57, 0), 11806ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(51, 0), 11906ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(50, 0), 12006ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(53, 0), 12106ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(47, 0), 12206ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(52, 0), 12306ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(49, 0), 12406ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(48, 0), 12506ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(43, 0), 12606ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(46, 0), 12706ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(41, 0), 12806ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(45, 0), 12906ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(42, 0), 13006ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(58, 0), 13106ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(44, 0), 13206ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(95, 0), 13306ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(105, 0), 13406ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(70, 0), 13506ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(68, 0), 13606ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(67, 0), 13706ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(66, 0), 13806ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(69, 0), 13906ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(71, 0), 14006ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(65, 0), 14106ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(72, 0), 14206ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(86, 0), 14306ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(90, 0), 14406ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(88, 0), 14506ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(92, 0), 14606ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(103, 0), 14706ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(77, 0), 14806ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(79, 0), 14906ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(83, 0), 15006ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(78, 0), 15106ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(81, 0), 15206ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(80, 0), 15306ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(82, 0), 15406ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(13, 0), 15506ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(12, 0), 15606ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(15, 0), 15706ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(14, 0), 15806ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(17, 0), 15906ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(18, 0), 16006ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(19, 0), 16106ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(16, 0), 16206ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(2, 0), 16306ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(1, 0), 16406ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(0, 0), 16506ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(4, 0), 16606ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(6, 0), 16706ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(7, 0), 16806ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(9, 0), 16906ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(8, 0), 17006ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(33, 0), 17106ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(32, 0), 17206ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(31, 0), 17306ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(30, 0), 17406ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(29, 0), 17506ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(27, 0), 17606ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(25, 0), 17706ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(28, 0), 17806ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(26, 0), 17906ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(23, 0), 18006ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(21, 0), 18106ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(20, 0), 18206ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(24, 0), 18306ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(22, 0), 18406ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(5, 1), 18506ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(3, 1), 18606ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(10, 0), 18706ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(11, 0), 18806ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(106, 0), 18906ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(87, 0), 19006ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(91, 0), 19106ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(104, 0), 19206ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(97, 0), 19306ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(100, 0) 19495a36367SOleksandr Tymoshenko }; 19506ae3ba3SOleksandr Tymoshenko 19695a36367SOleksandr Tymoshenko #define SCORE_PINS nitems(bytgpio_score_pins) 19795a36367SOleksandr Tymoshenko 19895a36367SOleksandr Tymoshenko #define NCORE_UID 2 19995a36367SOleksandr Tymoshenko #define NCORE_BANK_PREFIX "GPIO_S0_NC" 20006ae3ba3SOleksandr Tymoshenko const struct pinmap_info bytgpio_ncore_pins[] = { 20106ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(19, PADCONF_FUNC_ANY), 20206ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(18, PADCONF_FUNC_ANY), 20306ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(17, PADCONF_FUNC_ANY), 20406ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(20, PADCONF_FUNC_ANY), 20506ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(21, PADCONF_FUNC_ANY), 20606ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(22, PADCONF_FUNC_ANY), 20706ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(24, PADCONF_FUNC_ANY), 20806ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(25, PADCONF_FUNC_ANY), 20906ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(23, PADCONF_FUNC_ANY), 21006ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(16, PADCONF_FUNC_ANY), 21106ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(14, PADCONF_FUNC_ANY), 21206ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(15, PADCONF_FUNC_ANY), 21306ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(12, PADCONF_FUNC_ANY), 21406ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(26, PADCONF_FUNC_ANY), 21506ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(27, PADCONF_FUNC_ANY), 21606ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(1, PADCONF_FUNC_ANY), 21706ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(4, PADCONF_FUNC_ANY), 21806ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(8, PADCONF_FUNC_ANY), 21906ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(11, PADCONF_FUNC_ANY), 22006ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(0, PADCONF_FUNC_ANY), 22106ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(3, PADCONF_FUNC_ANY), 22206ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(6, PADCONF_FUNC_ANY), 22306ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(10, PADCONF_FUNC_ANY), 22406ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(13, PADCONF_FUNC_ANY), 22506ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(2, PADCONF_FUNC_ANY), 22606ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(5, PADCONF_FUNC_ANY), 22706ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(9, PADCONF_FUNC_ANY), 22806ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(7, PADCONF_FUNC_ANY) 22995a36367SOleksandr Tymoshenko }; 23095a36367SOleksandr Tymoshenko #define NCORE_PINS nitems(bytgpio_ncore_pins) 23195a36367SOleksandr Tymoshenko 23295a36367SOleksandr Tymoshenko #define SUS_UID 3 23395a36367SOleksandr Tymoshenko #define SUS_BANK_PREFIX "GPIO_S5_" 23406ae3ba3SOleksandr Tymoshenko const struct pinmap_info bytgpio_sus_pins[] = { 23506ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(29, 0), 23606ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(33, 0), 23706ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(30, 0), 23806ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(31, 0), 23906ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(32, 0), 24006ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(34, 0), 24106ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(36, 0), 24206ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(35, 0), 24306ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(38, 0), 24406ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(37, 0), 24506ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(18, 0), 24606ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(7, 1), 24706ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(11, 1), 24806ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(20, 1), 24906ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(17, 1), 25006ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(1, 1), 25106ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(8, 1), 25206ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(10, 1), 25306ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(19, 1), 25406ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(12, 1), 25506ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(0, 1), 25606ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(2, 1), 25706ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(23, 0), 25806ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(39, 0), 25906ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(28, 0), 26006ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(27, 0), 26106ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(22, 0), 26206ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(21, 0), 26306ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(24, 0), 26406ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(25, 0), 26506ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(26, 0), 26606ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(51, 0), 26706ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(56, 0), 26806ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(54, 0), 26906ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(49, 0), 27006ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(55, 0), 27106ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(48, 0), 27206ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(57, 0), 27306ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(50, 0), 27406ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(58, 0), 27506ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(52, 0), 27606ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(53, 0), 27706ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(59, 0), 27806ae3ba3SOleksandr Tymoshenko GPIO_PIN_MAP(40, 0) 27995a36367SOleksandr Tymoshenko }; 28006ae3ba3SOleksandr Tymoshenko 281*969484b5SAhmad Khalifa static char *bytgpio_gpio_ids[] = { "INT33FC", NULL }; 282*969484b5SAhmad Khalifa 28395a36367SOleksandr Tymoshenko #define SUS_PINS nitems(bytgpio_sus_pins) 28495a36367SOleksandr Tymoshenko 28506ae3ba3SOleksandr Tymoshenko #define BYGPIO_PIN_REGISTER(sc, pin, r) ((sc)->sc_pinpad_map[(pin)].reg * 16 + (r)) 28695a36367SOleksandr Tymoshenko #define BYTGPIO_PCONF0 0x0000 28706ae3ba3SOleksandr Tymoshenko #define BYTGPIO_PCONF0_FUNC_MASK 7 28895a36367SOleksandr Tymoshenko #define BYTGPIO_PAD_VAL 0x0008 28995a36367SOleksandr Tymoshenko #define BYTGPIO_PAD_VAL_LEVEL (1 << 0) 29095a36367SOleksandr Tymoshenko #define BYTGPIO_PAD_VAL_I_OUTPUT_ENABLED (1 << 1) 29195a36367SOleksandr Tymoshenko #define BYTGPIO_PAD_VAL_I_INPUT_ENABLED (1 << 2) 29295a36367SOleksandr Tymoshenko #define BYTGPIO_PAD_VAL_DIR_MASK (3 << 1) 29395a36367SOleksandr Tymoshenko 29495a36367SOleksandr Tymoshenko static inline uint32_t 29595a36367SOleksandr Tymoshenko bytgpio_read_4(struct bytgpio_softc *sc, bus_size_t off) 29695a36367SOleksandr Tymoshenko { 29795a36367SOleksandr Tymoshenko return (bus_read_4(sc->sc_mem_res, off)); 29895a36367SOleksandr Tymoshenko } 29995a36367SOleksandr Tymoshenko 30095a36367SOleksandr Tymoshenko static inline void 30195a36367SOleksandr Tymoshenko bytgpio_write_4(struct bytgpio_softc *sc, bus_size_t off, 30295a36367SOleksandr Tymoshenko uint32_t val) 30395a36367SOleksandr Tymoshenko { 30495a36367SOleksandr Tymoshenko bus_write_4(sc->sc_mem_res, off, val); 30595a36367SOleksandr Tymoshenko } 30695a36367SOleksandr Tymoshenko 30795a36367SOleksandr Tymoshenko static device_t 30895a36367SOleksandr Tymoshenko bytgpio_get_bus(device_t dev) 30995a36367SOleksandr Tymoshenko { 31095a36367SOleksandr Tymoshenko struct bytgpio_softc *sc; 31195a36367SOleksandr Tymoshenko 31295a36367SOleksandr Tymoshenko sc = device_get_softc(dev); 31395a36367SOleksandr Tymoshenko 31495a36367SOleksandr Tymoshenko return (sc->sc_busdev); 31595a36367SOleksandr Tymoshenko } 31695a36367SOleksandr Tymoshenko 31795a36367SOleksandr Tymoshenko static int 31895a36367SOleksandr Tymoshenko bytgpio_pin_max(device_t dev, int *maxpin) 31995a36367SOleksandr Tymoshenko { 32095a36367SOleksandr Tymoshenko struct bytgpio_softc *sc; 32195a36367SOleksandr Tymoshenko 32295a36367SOleksandr Tymoshenko sc = device_get_softc(dev); 32395a36367SOleksandr Tymoshenko 32495a36367SOleksandr Tymoshenko *maxpin = sc->sc_npins - 1; 32595a36367SOleksandr Tymoshenko 32695a36367SOleksandr Tymoshenko return (0); 32795a36367SOleksandr Tymoshenko } 32895a36367SOleksandr Tymoshenko 32995a36367SOleksandr Tymoshenko static int 33095a36367SOleksandr Tymoshenko bytgpio_valid_pin(struct bytgpio_softc *sc, int pin) 33195a36367SOleksandr Tymoshenko { 33295a36367SOleksandr Tymoshenko 33395a36367SOleksandr Tymoshenko if (pin >= sc->sc_npins || sc->sc_mem_res == NULL) 33495a36367SOleksandr Tymoshenko return (EINVAL); 33595a36367SOleksandr Tymoshenko 33695a36367SOleksandr Tymoshenko return (0); 33795a36367SOleksandr Tymoshenko } 33895a36367SOleksandr Tymoshenko 33906ae3ba3SOleksandr Tymoshenko /* 34006ae3ba3SOleksandr Tymoshenko * Returns true if pad configured to be used as GPIO 34106ae3ba3SOleksandr Tymoshenko */ 34206ae3ba3SOleksandr Tymoshenko static bool 34306ae3ba3SOleksandr Tymoshenko bytgpio_pad_is_gpio(struct bytgpio_softc *sc, int pin) 34406ae3ba3SOleksandr Tymoshenko { 34506ae3ba3SOleksandr Tymoshenko if ((sc->sc_pinpad_map[pin].pad_func == PADCONF_FUNC_ANY) || 34606ae3ba3SOleksandr Tymoshenko (sc->sc_pad_funcs[pin] == sc->sc_pinpad_map[pin].pad_func)) 34706ae3ba3SOleksandr Tymoshenko return (true); 34806ae3ba3SOleksandr Tymoshenko else 34906ae3ba3SOleksandr Tymoshenko return (false); 35006ae3ba3SOleksandr Tymoshenko } 35106ae3ba3SOleksandr Tymoshenko 35295a36367SOleksandr Tymoshenko static int 35395a36367SOleksandr Tymoshenko bytgpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps) 35495a36367SOleksandr Tymoshenko { 35595a36367SOleksandr Tymoshenko struct bytgpio_softc *sc; 35695a36367SOleksandr Tymoshenko 35795a36367SOleksandr Tymoshenko sc = device_get_softc(dev); 35895a36367SOleksandr Tymoshenko if (bytgpio_valid_pin(sc, pin) != 0) 35995a36367SOleksandr Tymoshenko return (EINVAL); 36095a36367SOleksandr Tymoshenko 36106ae3ba3SOleksandr Tymoshenko *caps = 0; 36206ae3ba3SOleksandr Tymoshenko if (bytgpio_pad_is_gpio(sc, pin)) 36395a36367SOleksandr Tymoshenko *caps = GPIO_PIN_INPUT | GPIO_PIN_OUTPUT; 36495a36367SOleksandr Tymoshenko 36595a36367SOleksandr Tymoshenko return (0); 36695a36367SOleksandr Tymoshenko } 36795a36367SOleksandr Tymoshenko 36895a36367SOleksandr Tymoshenko static int 36995a36367SOleksandr Tymoshenko bytgpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags) 37095a36367SOleksandr Tymoshenko { 37195a36367SOleksandr Tymoshenko struct bytgpio_softc *sc; 37295a36367SOleksandr Tymoshenko uint32_t reg, val; 37395a36367SOleksandr Tymoshenko 37495a36367SOleksandr Tymoshenko sc = device_get_softc(dev); 37595a36367SOleksandr Tymoshenko if (bytgpio_valid_pin(sc, pin) != 0) 37695a36367SOleksandr Tymoshenko return (EINVAL); 37795a36367SOleksandr Tymoshenko 37806ae3ba3SOleksandr Tymoshenko *flags = 0; 37906ae3ba3SOleksandr Tymoshenko if (!bytgpio_pad_is_gpio(sc, pin)) 38006ae3ba3SOleksandr Tymoshenko return (0); 38106ae3ba3SOleksandr Tymoshenko 38295a36367SOleksandr Tymoshenko /* Get the current pin state */ 38395a36367SOleksandr Tymoshenko BYTGPIO_LOCK(sc); 38495a36367SOleksandr Tymoshenko reg = BYGPIO_PIN_REGISTER(sc, pin, BYTGPIO_PAD_VAL); 38595a36367SOleksandr Tymoshenko val = bytgpio_read_4(sc, reg); 38695a36367SOleksandr Tymoshenko if ((val & BYTGPIO_PAD_VAL_I_OUTPUT_ENABLED) == 0) 38795a36367SOleksandr Tymoshenko *flags |= GPIO_PIN_OUTPUT; 38895a36367SOleksandr Tymoshenko /* 38995a36367SOleksandr Tymoshenko * this bit can be cleared to read current output value 39095a36367SOleksandr Tymoshenko * sou output bit takes precedense 39195a36367SOleksandr Tymoshenko */ 39295a36367SOleksandr Tymoshenko else if ((val & BYTGPIO_PAD_VAL_I_INPUT_ENABLED) == 0) 39395a36367SOleksandr Tymoshenko *flags |= GPIO_PIN_INPUT; 39495a36367SOleksandr Tymoshenko BYTGPIO_UNLOCK(sc); 39595a36367SOleksandr Tymoshenko 39695a36367SOleksandr Tymoshenko return (0); 39795a36367SOleksandr Tymoshenko } 39895a36367SOleksandr Tymoshenko 39995a36367SOleksandr Tymoshenko static int 40095a36367SOleksandr Tymoshenko bytgpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags) 40195a36367SOleksandr Tymoshenko { 40295a36367SOleksandr Tymoshenko struct bytgpio_softc *sc; 40395a36367SOleksandr Tymoshenko uint32_t reg, val; 40495a36367SOleksandr Tymoshenko uint32_t allowed; 40595a36367SOleksandr Tymoshenko 40695a36367SOleksandr Tymoshenko sc = device_get_softc(dev); 40795a36367SOleksandr Tymoshenko if (bytgpio_valid_pin(sc, pin) != 0) 40895a36367SOleksandr Tymoshenko return (EINVAL); 40995a36367SOleksandr Tymoshenko 41006ae3ba3SOleksandr Tymoshenko if (bytgpio_pad_is_gpio(sc, pin)) 41195a36367SOleksandr Tymoshenko allowed = GPIO_PIN_INPUT | GPIO_PIN_OUTPUT; 41206ae3ba3SOleksandr Tymoshenko else 41306ae3ba3SOleksandr Tymoshenko allowed = 0; 41495a36367SOleksandr Tymoshenko 41595a36367SOleksandr Tymoshenko /* 41695a36367SOleksandr Tymoshenko * Only directtion flag allowed 41795a36367SOleksandr Tymoshenko */ 41895a36367SOleksandr Tymoshenko if (flags & ~allowed) 41995a36367SOleksandr Tymoshenko return (EINVAL); 42095a36367SOleksandr Tymoshenko 42195a36367SOleksandr Tymoshenko /* 42295a36367SOleksandr Tymoshenko * Not both directions simultaneously 42395a36367SOleksandr Tymoshenko */ 42495a36367SOleksandr Tymoshenko if ((flags & allowed) == allowed) 42595a36367SOleksandr Tymoshenko return (EINVAL); 42695a36367SOleksandr Tymoshenko 42795a36367SOleksandr Tymoshenko /* Set the GPIO mode and state */ 42895a36367SOleksandr Tymoshenko BYTGPIO_LOCK(sc); 42995a36367SOleksandr Tymoshenko reg = BYGPIO_PIN_REGISTER(sc, pin, BYTGPIO_PAD_VAL); 43095a36367SOleksandr Tymoshenko val = bytgpio_read_4(sc, reg); 43195a36367SOleksandr Tymoshenko val = val | BYTGPIO_PAD_VAL_DIR_MASK; 43295a36367SOleksandr Tymoshenko if (flags & GPIO_PIN_INPUT) 43395a36367SOleksandr Tymoshenko val = val & ~BYTGPIO_PAD_VAL_I_INPUT_ENABLED; 43495a36367SOleksandr Tymoshenko if (flags & GPIO_PIN_OUTPUT) 43595a36367SOleksandr Tymoshenko val = val & ~BYTGPIO_PAD_VAL_I_OUTPUT_ENABLED; 43695a36367SOleksandr Tymoshenko bytgpio_write_4(sc, reg, val); 43795a36367SOleksandr Tymoshenko BYTGPIO_UNLOCK(sc); 43895a36367SOleksandr Tymoshenko 43995a36367SOleksandr Tymoshenko return (0); 44095a36367SOleksandr Tymoshenko } 44195a36367SOleksandr Tymoshenko 44295a36367SOleksandr Tymoshenko static int 44395a36367SOleksandr Tymoshenko bytgpio_pin_getname(device_t dev, uint32_t pin, char *name) 44495a36367SOleksandr Tymoshenko { 44595a36367SOleksandr Tymoshenko struct bytgpio_softc *sc; 44695a36367SOleksandr Tymoshenko 44795a36367SOleksandr Tymoshenko sc = device_get_softc(dev); 44895a36367SOleksandr Tymoshenko if (bytgpio_valid_pin(sc, pin) != 0) 44995a36367SOleksandr Tymoshenko return (EINVAL); 45095a36367SOleksandr Tymoshenko 45195a36367SOleksandr Tymoshenko /* Set a very simple name */ 45295a36367SOleksandr Tymoshenko snprintf(name, GPIOMAXNAME, "%s%u", sc->sc_bank_prefix, pin); 45395a36367SOleksandr Tymoshenko name[GPIOMAXNAME - 1] = '\0'; 45495a36367SOleksandr Tymoshenko 45595a36367SOleksandr Tymoshenko return (0); 45695a36367SOleksandr Tymoshenko } 45795a36367SOleksandr Tymoshenko 45895a36367SOleksandr Tymoshenko static int 45995a36367SOleksandr Tymoshenko bytgpio_pin_set(device_t dev, uint32_t pin, unsigned int value) 46095a36367SOleksandr Tymoshenko { 46195a36367SOleksandr Tymoshenko struct bytgpio_softc *sc; 46295a36367SOleksandr Tymoshenko uint32_t reg, val; 46395a36367SOleksandr Tymoshenko 46495a36367SOleksandr Tymoshenko sc = device_get_softc(dev); 46595a36367SOleksandr Tymoshenko if (bytgpio_valid_pin(sc, pin) != 0) 46695a36367SOleksandr Tymoshenko return (EINVAL); 46795a36367SOleksandr Tymoshenko 46806ae3ba3SOleksandr Tymoshenko if (!bytgpio_pad_is_gpio(sc, pin)) 46906ae3ba3SOleksandr Tymoshenko return (EINVAL); 47006ae3ba3SOleksandr Tymoshenko 47195a36367SOleksandr Tymoshenko BYTGPIO_LOCK(sc); 47295a36367SOleksandr Tymoshenko reg = BYGPIO_PIN_REGISTER(sc, pin, BYTGPIO_PAD_VAL); 47395a36367SOleksandr Tymoshenko val = bytgpio_read_4(sc, reg); 47495a36367SOleksandr Tymoshenko if (value == GPIO_PIN_LOW) 47595a36367SOleksandr Tymoshenko val = val & ~BYTGPIO_PAD_VAL_LEVEL; 47695a36367SOleksandr Tymoshenko else 47795a36367SOleksandr Tymoshenko val = val | BYTGPIO_PAD_VAL_LEVEL; 47895a36367SOleksandr Tymoshenko bytgpio_write_4(sc, reg, val); 47995a36367SOleksandr Tymoshenko BYTGPIO_UNLOCK(sc); 48095a36367SOleksandr Tymoshenko 48195a36367SOleksandr Tymoshenko return (0); 48295a36367SOleksandr Tymoshenko } 48395a36367SOleksandr Tymoshenko 48495a36367SOleksandr Tymoshenko static int 48595a36367SOleksandr Tymoshenko bytgpio_pin_get(device_t dev, uint32_t pin, unsigned int *value) 48695a36367SOleksandr Tymoshenko { 48795a36367SOleksandr Tymoshenko struct bytgpio_softc *sc; 48895a36367SOleksandr Tymoshenko uint32_t reg, val; 48995a36367SOleksandr Tymoshenko 49095a36367SOleksandr Tymoshenko sc = device_get_softc(dev); 49195a36367SOleksandr Tymoshenko if (bytgpio_valid_pin(sc, pin) != 0) 49295a36367SOleksandr Tymoshenko return (EINVAL); 49306ae3ba3SOleksandr Tymoshenko /* 49406ae3ba3SOleksandr Tymoshenko * Report non-GPIO pads as pin LOW 49506ae3ba3SOleksandr Tymoshenko */ 49606ae3ba3SOleksandr Tymoshenko if (!bytgpio_pad_is_gpio(sc, pin)) { 49706ae3ba3SOleksandr Tymoshenko *value = GPIO_PIN_LOW; 49806ae3ba3SOleksandr Tymoshenko return (0); 49906ae3ba3SOleksandr Tymoshenko } 50095a36367SOleksandr Tymoshenko 50195a36367SOleksandr Tymoshenko BYTGPIO_LOCK(sc); 50295a36367SOleksandr Tymoshenko reg = BYGPIO_PIN_REGISTER(sc, pin, BYTGPIO_PAD_VAL); 50395a36367SOleksandr Tymoshenko /* 50495a36367SOleksandr Tymoshenko * And read actual value 50595a36367SOleksandr Tymoshenko */ 50695a36367SOleksandr Tymoshenko val = bytgpio_read_4(sc, reg); 50795a36367SOleksandr Tymoshenko if (val & BYTGPIO_PAD_VAL_LEVEL) 50895a36367SOleksandr Tymoshenko *value = GPIO_PIN_HIGH; 50995a36367SOleksandr Tymoshenko else 51095a36367SOleksandr Tymoshenko *value = GPIO_PIN_LOW; 51195a36367SOleksandr Tymoshenko BYTGPIO_UNLOCK(sc); 51295a36367SOleksandr Tymoshenko 51395a36367SOleksandr Tymoshenko return (0); 51495a36367SOleksandr Tymoshenko } 51595a36367SOleksandr Tymoshenko 51695a36367SOleksandr Tymoshenko static int 51795a36367SOleksandr Tymoshenko bytgpio_pin_toggle(device_t dev, uint32_t pin) 51895a36367SOleksandr Tymoshenko { 51995a36367SOleksandr Tymoshenko struct bytgpio_softc *sc; 52095a36367SOleksandr Tymoshenko uint32_t reg, val; 52195a36367SOleksandr Tymoshenko 52295a36367SOleksandr Tymoshenko sc = device_get_softc(dev); 52395a36367SOleksandr Tymoshenko if (bytgpio_valid_pin(sc, pin) != 0) 52495a36367SOleksandr Tymoshenko return (EINVAL); 52595a36367SOleksandr Tymoshenko 52606ae3ba3SOleksandr Tymoshenko if (!bytgpio_pad_is_gpio(sc, pin)) 52706ae3ba3SOleksandr Tymoshenko return (EINVAL); 52806ae3ba3SOleksandr Tymoshenko 52995a36367SOleksandr Tymoshenko /* Toggle the pin */ 53095a36367SOleksandr Tymoshenko BYTGPIO_LOCK(sc); 53195a36367SOleksandr Tymoshenko reg = BYGPIO_PIN_REGISTER(sc, pin, BYTGPIO_PAD_VAL); 53295a36367SOleksandr Tymoshenko val = bytgpio_read_4(sc, reg); 53395a36367SOleksandr Tymoshenko val = val ^ BYTGPIO_PAD_VAL_LEVEL; 53495a36367SOleksandr Tymoshenko bytgpio_write_4(sc, reg, val); 53595a36367SOleksandr Tymoshenko BYTGPIO_UNLOCK(sc); 53695a36367SOleksandr Tymoshenko 53795a36367SOleksandr Tymoshenko return (0); 53895a36367SOleksandr Tymoshenko } 53995a36367SOleksandr Tymoshenko 54095a36367SOleksandr Tymoshenko static int 54195a36367SOleksandr Tymoshenko bytgpio_probe(device_t dev) 54295a36367SOleksandr Tymoshenko { 5435efca36fSTakanori Watanabe int rv; 54495a36367SOleksandr Tymoshenko 5455efca36fSTakanori Watanabe if (acpi_disabled("gpio")) 54695a36367SOleksandr Tymoshenko return (ENXIO); 547*969484b5SAhmad Khalifa rv = ACPI_ID_PROBE(device_get_parent(dev), dev, bytgpio_gpio_ids, NULL); 5485efca36fSTakanori Watanabe if (rv <= 0) 54995a36367SOleksandr Tymoshenko device_set_desc(dev, "Intel Baytrail GPIO Controller"); 5505efca36fSTakanori Watanabe return (rv); 55195a36367SOleksandr Tymoshenko } 55295a36367SOleksandr Tymoshenko 55395a36367SOleksandr Tymoshenko static int 55495a36367SOleksandr Tymoshenko bytgpio_attach(device_t dev) 55595a36367SOleksandr Tymoshenko { 55695a36367SOleksandr Tymoshenko struct bytgpio_softc *sc; 55795a36367SOleksandr Tymoshenko ACPI_STATUS status; 55895a36367SOleksandr Tymoshenko int uid; 55906ae3ba3SOleksandr Tymoshenko int pin; 56006ae3ba3SOleksandr Tymoshenko uint32_t reg, val; 56195a36367SOleksandr Tymoshenko 56295a36367SOleksandr Tymoshenko sc = device_get_softc(dev); 56395a36367SOleksandr Tymoshenko sc->sc_dev = dev; 56495a36367SOleksandr Tymoshenko sc->sc_handle = acpi_get_handle(dev); 56595a36367SOleksandr Tymoshenko status = acpi_GetInteger(sc->sc_handle, "_UID", &uid); 56695a36367SOleksandr Tymoshenko if (ACPI_FAILURE(status)) { 56795a36367SOleksandr Tymoshenko device_printf(dev, "failed to read _UID\n"); 56895a36367SOleksandr Tymoshenko return (ENXIO); 56995a36367SOleksandr Tymoshenko } 57095a36367SOleksandr Tymoshenko 571fd980511SOleksandr Tymoshenko BYTGPIO_LOCK_INIT(sc); 572fd980511SOleksandr Tymoshenko 57395a36367SOleksandr Tymoshenko switch (uid) { 57495a36367SOleksandr Tymoshenko case SCORE_UID: 57595a36367SOleksandr Tymoshenko sc->sc_npins = SCORE_PINS; 57695a36367SOleksandr Tymoshenko sc->sc_bank_prefix = SCORE_BANK_PREFIX; 57795a36367SOleksandr Tymoshenko sc->sc_pinpad_map = bytgpio_score_pins; 57895a36367SOleksandr Tymoshenko break; 57995a36367SOleksandr Tymoshenko case NCORE_UID: 58095a36367SOleksandr Tymoshenko sc->sc_npins = NCORE_PINS; 58195a36367SOleksandr Tymoshenko sc->sc_bank_prefix = NCORE_BANK_PREFIX; 58295a36367SOleksandr Tymoshenko sc->sc_pinpad_map = bytgpio_ncore_pins; 58395a36367SOleksandr Tymoshenko break; 58495a36367SOleksandr Tymoshenko case SUS_UID: 58595a36367SOleksandr Tymoshenko sc->sc_npins = SUS_PINS; 58695a36367SOleksandr Tymoshenko sc->sc_bank_prefix = SUS_BANK_PREFIX; 58795a36367SOleksandr Tymoshenko sc->sc_pinpad_map = bytgpio_sus_pins; 58895a36367SOleksandr Tymoshenko break; 58995a36367SOleksandr Tymoshenko default: 59095a36367SOleksandr Tymoshenko device_printf(dev, "invalid _UID value: %d\n", uid); 59106ae3ba3SOleksandr Tymoshenko goto error; 59295a36367SOleksandr Tymoshenko } 59395a36367SOleksandr Tymoshenko 59406ae3ba3SOleksandr Tymoshenko sc->sc_pad_funcs = malloc(sizeof(int)*sc->sc_npins, M_DEVBUF, 59506ae3ba3SOleksandr Tymoshenko M_WAITOK | M_ZERO); 59606ae3ba3SOleksandr Tymoshenko 59795a36367SOleksandr Tymoshenko sc->sc_mem_rid = 0; 59895a36367SOleksandr Tymoshenko sc->sc_mem_res = bus_alloc_resource_any(sc->sc_dev, 59995a36367SOleksandr Tymoshenko SYS_RES_MEMORY, &sc->sc_mem_rid, RF_ACTIVE); 60095a36367SOleksandr Tymoshenko if (sc->sc_mem_res == NULL) { 60195a36367SOleksandr Tymoshenko device_printf(dev, "can't allocate resource\n"); 60295a36367SOleksandr Tymoshenko goto error; 60395a36367SOleksandr Tymoshenko } 60495a36367SOleksandr Tymoshenko 60506ae3ba3SOleksandr Tymoshenko for (pin = 0; pin < sc->sc_npins; pin++) { 60606ae3ba3SOleksandr Tymoshenko reg = BYGPIO_PIN_REGISTER(sc, pin, BYTGPIO_PCONF0); 60706ae3ba3SOleksandr Tymoshenko val = bytgpio_read_4(sc, reg); 60806ae3ba3SOleksandr Tymoshenko sc->sc_pad_funcs[pin] = val & BYTGPIO_PCONF0_FUNC_MASK; 60906ae3ba3SOleksandr Tymoshenko } 61006ae3ba3SOleksandr Tymoshenko 61195a36367SOleksandr Tymoshenko sc->sc_busdev = gpiobus_attach_bus(dev); 61295a36367SOleksandr Tymoshenko if (sc->sc_busdev == NULL) { 61395a36367SOleksandr Tymoshenko BYTGPIO_LOCK_DESTROY(sc); 61495a36367SOleksandr Tymoshenko bus_release_resource(dev, SYS_RES_MEMORY, 61595a36367SOleksandr Tymoshenko sc->sc_mem_rid, sc->sc_mem_res); 61695a36367SOleksandr Tymoshenko return (ENXIO); 61795a36367SOleksandr Tymoshenko } 61895a36367SOleksandr Tymoshenko 61995a36367SOleksandr Tymoshenko return (0); 62095a36367SOleksandr Tymoshenko 62195a36367SOleksandr Tymoshenko error: 622fd980511SOleksandr Tymoshenko BYTGPIO_LOCK_DESTROY(sc); 623fd980511SOleksandr Tymoshenko 62495a36367SOleksandr Tymoshenko return (ENXIO); 62595a36367SOleksandr Tymoshenko } 62695a36367SOleksandr Tymoshenko 627fd980511SOleksandr Tymoshenko 628fd980511SOleksandr Tymoshenko static int 629fd980511SOleksandr Tymoshenko bytgpio_detach(device_t dev) 630fd980511SOleksandr Tymoshenko { 631fd980511SOleksandr Tymoshenko struct bytgpio_softc *sc; 632fd980511SOleksandr Tymoshenko 633fd980511SOleksandr Tymoshenko sc = device_get_softc(dev); 634fd980511SOleksandr Tymoshenko 635fd980511SOleksandr Tymoshenko if (sc->sc_busdev) 636fd980511SOleksandr Tymoshenko gpiobus_detach_bus(dev); 637fd980511SOleksandr Tymoshenko 638fd980511SOleksandr Tymoshenko BYTGPIO_LOCK_DESTROY(sc); 639fd980511SOleksandr Tymoshenko 640fd980511SOleksandr Tymoshenko if (sc->sc_pad_funcs) 641fd980511SOleksandr Tymoshenko free(sc->sc_pad_funcs, M_DEVBUF); 642fd980511SOleksandr Tymoshenko 643fd980511SOleksandr Tymoshenko if (sc->sc_mem_res != NULL) 644fd980511SOleksandr Tymoshenko bus_release_resource(dev, SYS_RES_MEMORY, 645fd980511SOleksandr Tymoshenko sc->sc_mem_rid, sc->sc_mem_res); 646fd980511SOleksandr Tymoshenko 647fd980511SOleksandr Tymoshenko return (0); 648fd980511SOleksandr Tymoshenko } 649fd980511SOleksandr Tymoshenko 65095a36367SOleksandr Tymoshenko static device_method_t bytgpio_methods[] = { 65195a36367SOleksandr Tymoshenko /* Device interface */ 65295a36367SOleksandr Tymoshenko DEVMETHOD(device_probe, bytgpio_probe), 65395a36367SOleksandr Tymoshenko DEVMETHOD(device_attach, bytgpio_attach), 654fd980511SOleksandr Tymoshenko DEVMETHOD(device_detach, bytgpio_detach), 65595a36367SOleksandr Tymoshenko 65695a36367SOleksandr Tymoshenko /* GPIO protocol */ 65795a36367SOleksandr Tymoshenko DEVMETHOD(gpio_get_bus, bytgpio_get_bus), 65895a36367SOleksandr Tymoshenko DEVMETHOD(gpio_pin_max, bytgpio_pin_max), 65995a36367SOleksandr Tymoshenko DEVMETHOD(gpio_pin_getname, bytgpio_pin_getname), 66095a36367SOleksandr Tymoshenko DEVMETHOD(gpio_pin_getflags, bytgpio_pin_getflags), 66195a36367SOleksandr Tymoshenko DEVMETHOD(gpio_pin_getcaps, bytgpio_pin_getcaps), 66295a36367SOleksandr Tymoshenko DEVMETHOD(gpio_pin_setflags, bytgpio_pin_setflags), 66395a36367SOleksandr Tymoshenko DEVMETHOD(gpio_pin_get, bytgpio_pin_get), 66495a36367SOleksandr Tymoshenko DEVMETHOD(gpio_pin_set, bytgpio_pin_set), 66595a36367SOleksandr Tymoshenko DEVMETHOD(gpio_pin_toggle, bytgpio_pin_toggle), 66695a36367SOleksandr Tymoshenko 66795a36367SOleksandr Tymoshenko DEVMETHOD_END 66895a36367SOleksandr Tymoshenko }; 66995a36367SOleksandr Tymoshenko 67095a36367SOleksandr Tymoshenko static driver_t bytgpio_driver = { 67195a36367SOleksandr Tymoshenko "gpio", 67295a36367SOleksandr Tymoshenko bytgpio_methods, 67395a36367SOleksandr Tymoshenko sizeof(struct bytgpio_softc), 67495a36367SOleksandr Tymoshenko }; 67595a36367SOleksandr Tymoshenko 67684c5f982SJohn Baldwin DRIVER_MODULE(bytgpio, acpi, bytgpio_driver, 0, 0); 67795a36367SOleksandr Tymoshenko MODULE_DEPEND(bytgpio, acpi, 1, 1, 1); 678fd980511SOleksandr Tymoshenko MODULE_DEPEND(bytgpio, gpiobus, 1, 1, 1); 679*969484b5SAhmad Khalifa ACPI_PNP_INFO(bytgpio_gpio_ids); 680