Module Name: src Committed By: jmcneill Date: Mon Jul 2 23:54:53 UTC 2018
Modified Files: src/sys/arch/arm/samsung: exynos_gpio.c exynos_pinctrl.c exynos_var.h Log Message: Make the pinctrl driver actually work. To generate a diff of this commit: cvs rdiff -u -r1.23 -r1.24 src/sys/arch/arm/samsung/exynos_gpio.c \ src/sys/arch/arm/samsung/exynos_var.h cvs rdiff -u -r1.12 -r1.13 src/sys/arch/arm/samsung/exynos_pinctrl.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/arm/samsung/exynos_gpio.c diff -u src/sys/arch/arm/samsung/exynos_gpio.c:1.23 src/sys/arch/arm/samsung/exynos_gpio.c:1.24 --- src/sys/arch/arm/samsung/exynos_gpio.c:1.23 Thu Dec 31 03:50:34 2015 +++ src/sys/arch/arm/samsung/exynos_gpio.c Mon Jul 2 23:54:52 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: exynos_gpio.c,v 1.23 2015/12/31 03:50:34 marty Exp $ */ +/* $NetBSD: exynos_gpio.c,v 1.24 2018/07/02 23:54:52 jmcneill Exp $ */ /*- * Copyright (c) 2014 The NetBSD Foundation, Inc. @@ -34,7 +34,7 @@ #include "gpio.h" #include <sys/cdefs.h> -__KERNEL_RCSID(1, "$NetBSD: exynos_gpio.c,v 1.23 2015/12/31 03:50:34 marty Exp $"); +__KERNEL_RCSID(1, "$NetBSD: exynos_gpio.c,v 1.24 2018/07/02 23:54:52 jmcneill Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -262,24 +262,46 @@ exynos_gpio_pin_ctl(void *cookie, int pi exynos_gpio_update_cfg_regs(bank, &ncfg); } -void exynos_gpio_pin_ctl_read(const struct exynos_gpio_bank *bank, - struct exynos_gpio_pin_cfg *cfg) -{ - cfg->cfg = GPIO_READ(bank, EXYNOS_GPIO_CON); - cfg->pud = GPIO_READ(bank, EXYNOS_GPIO_PUD); - cfg->drv = GPIO_READ(bank, EXYNOS_GPIO_DRV); - cfg->conpwd = GPIO_READ(bank, EXYNOS_GPIO_CONPWD); - cfg->pudpwd = GPIO_READ(bank, EXYNOS_GPIO_PUDPWD); -} - void exynos_gpio_pin_ctl_write(const struct exynos_gpio_bank *bank, - const struct exynos_gpio_pin_cfg *cfg) + const struct exynos_gpio_pin_cfg *cfg, + int pin) { - GPIO_WRITE(bank, EXYNOS_GPIO_CON, cfg->cfg); - GPIO_WRITE(bank, EXYNOS_GPIO_PUD, cfg->pud); - GPIO_WRITE(bank, EXYNOS_GPIO_DRV, cfg->drv); - GPIO_WRITE(bank, EXYNOS_GPIO_CONPWD, cfg->conpwd); - GPIO_WRITE(bank, EXYNOS_GPIO_PUDPWD, cfg->pudpwd); + uint32_t val; + + if (cfg->cfg_valid) { + val = GPIO_READ(bank, EXYNOS_GPIO_CON); + val &= ~(0xf << (pin * 4)); + val |= (cfg->cfg << (pin * 4)); + GPIO_WRITE(bank, EXYNOS_GPIO_CON, val); + } + + if (cfg->pud_valid) { + val = GPIO_READ(bank, EXYNOS_GPIO_PUD); + val &= ~(0x3 << (pin * 2)); + val |= (cfg->pud << (pin * 2)); + GPIO_WRITE(bank, EXYNOS_GPIO_PUD, val); + } + + if (cfg->drv_valid) { + val = GPIO_READ(bank, EXYNOS_GPIO_DRV); + val &= ~(0x3 << (pin * 2)); + val |= (cfg->drv << (pin * 2)); + GPIO_WRITE(bank, EXYNOS_GPIO_DRV, val); + } + + if (cfg->conpwd_valid) { + val = GPIO_READ(bank, EXYNOS_GPIO_CONPWD); + val &= ~(0x3 << (pin * 2)); + val |= (cfg->conpwd << (pin * 2)); + GPIO_WRITE(bank, EXYNOS_GPIO_CONPWD, val); + } + + if (cfg->pudpwd_valid) { + val = GPIO_READ(bank, EXYNOS_GPIO_PUDPWD); + val &= ~(0x3 << (pin * 2)); + val |= (cfg->pudpwd << (pin * 2)); + GPIO_WRITE(bank, EXYNOS_GPIO_PUDPWD, val); + } } struct exynos_gpio_softc * Index: src/sys/arch/arm/samsung/exynos_var.h diff -u src/sys/arch/arm/samsung/exynos_var.h:1.23 src/sys/arch/arm/samsung/exynos_var.h:1.24 --- src/sys/arch/arm/samsung/exynos_var.h:1.23 Wed Dec 30 04:30:27 2015 +++ src/sys/arch/arm/samsung/exynos_var.h Mon Jul 2 23:54:52 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: exynos_var.h,v 1.23 2015/12/30 04:30:27 marty Exp $ */ +/* $NetBSD: exynos_var.h,v 1.24 2018/07/02 23:54:52 jmcneill Exp $ */ /*- * Copyright (c) 2013, 2014 The NetBSD Foundation, Inc. @@ -106,10 +106,15 @@ struct exynos_gpio_pindata { struct exynos_gpio_pin_cfg { uint32_t cfg; + int cfg_valid; uint32_t pud; + int pud_valid; uint32_t drv; + int drv_valid; uint32_t conpwd; + int conpwd_valid; uint32_t pudpwd; + int pudpwd_valid; }; struct exynos_gpio_softc { @@ -170,10 +175,9 @@ extern void exynos_gpio_pinset_release(c extern void exynos_gpio_pinset_to_pindata(const struct exynos_gpio_pinset *, int pinnr, struct exynos_gpio_pindata *); extern bool exynos_gpio_pin_reserve(const char *, struct exynos_gpio_pindata *); -extern void exynos_gpio_pin_ctl_read(const struct exynos_gpio_bank *, - struct exynos_gpio_pin_cfg *); extern void exynos_gpio_pin_ctl_write(const struct exynos_gpio_bank *, - const struct exynos_gpio_pin_cfg *); + const struct exynos_gpio_pin_cfg *, + int); static inline void exynos_gpio_pindata_write(const struct exynos_gpio_pindata *pd, int value) { Index: src/sys/arch/arm/samsung/exynos_pinctrl.c diff -u src/sys/arch/arm/samsung/exynos_pinctrl.c:1.12 src/sys/arch/arm/samsung/exynos_pinctrl.c:1.13 --- src/sys/arch/arm/samsung/exynos_pinctrl.c:1.12 Sun Jul 2 18:21:52 2017 +++ src/sys/arch/arm/samsung/exynos_pinctrl.c Mon Jul 2 23:54:52 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: exynos_pinctrl.c,v 1.12 2017/07/02 18:21:52 jmcneill Exp $ */ +/* $NetBSD: exynos_pinctrl.c,v 1.13 2018/07/02 23:54:52 jmcneill Exp $ */ /*- * Copyright (c) 2015 The NetBSD Foundation, Inc. @@ -34,7 +34,7 @@ #include "gpio.h" #include <sys/cdefs.h> -__KERNEL_RCSID(1, "$NetBSD: exynos_pinctrl.c,v 1.12 2017/07/02 18:21:52 jmcneill Exp $"); +__KERNEL_RCSID(1, "$NetBSD: exynos_pinctrl.c,v 1.13 2018/07/02 23:54:52 jmcneill Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -83,13 +83,6 @@ exynos_pinctrl_match(device_t parent, cf return of_match_compatible(faa->faa_phandle, compatible); } -static bool -is_pinctrl(int phandle) -{ - int len = OF_getproplen(phandle, "samsung,pins"); - return len > 0; -} - static void exynos_pinctrl_attach(device_t parent, device_t self, void *aux) { @@ -122,11 +115,11 @@ exynos_pinctrl_attach(device_t parent, d for (child = OF_child(faa->faa_phandle); child; child = OF_peer(child)) { - if (of_getprop_bool(child, "gpio-controller")) { + if (of_hasprop(child, "gpio-controller")) { exynos_gpio_bank_config(sc, faa, child); } - if (is_pinctrl(child)) { + if (of_hasprop(child, "samsung,pins")) { fdtbus_register_pinctrl_config(self, child, &exynos_pinctrl_controller_func); } @@ -138,11 +131,26 @@ exynos_pinctrl_attach(device_t parent, d static void exynos_parse_config(int phandle, struct exynos_gpio_pin_cfg *gc) { - of_getprop_uint32(phandle, "samsung,pin-function", &gc->cfg); - of_getprop_uint32(phandle, "samsung,pin-pud", &gc->pud); - of_getprop_uint32(phandle, "samsung,pin-drv", &gc->drv); - of_getprop_uint32(phandle, "samsung,pin-conpwd", &gc->conpwd); - of_getprop_uint32(phandle, "samsung,pin-pudpwd", &gc->pudpwd); + gc->cfg_valid = of_getprop_uint32(phandle, "samsung,pin-function", &gc->cfg) == 0; + gc->pud_valid = of_getprop_uint32(phandle, "samsung,pin-pud", &gc->pud) == 0; + gc->drv_valid = of_getprop_uint32(phandle, "samsung,pin-drv", &gc->drv) == 0; + gc->conpwd_valid = of_getprop_uint32(phandle, "samsung,pin-conpwd", &gc->conpwd) == 0; + gc->pudpwd_valid = of_getprop_uint32(phandle, "samsung,pin-pudpwd", &gc->pudpwd) == 0; +} + +static int +exynos_parse_pin(const char *pinname) +{ + + const int len = strlen(pinname); + + if (len == 0) + return -1; + + if (pinname[len - 1] < '0' || pinname[len - 1] > '9') + return -1; + + return pinname[len - 1] - '0'; } static int @@ -151,6 +159,7 @@ exynos_do_config(struct exynos_pinctrl_c struct exynos_gpio_pin_cfg *gc = &pc->pc_pincfg; struct exynos_gpio_bank *bank; const char *pins; + int pin; int pins_len = OF_getproplen(pc->pc_phandle, "samsung,pins"); if (pins_len <= 0) @@ -160,12 +169,13 @@ exynos_do_config(struct exynos_pinctrl_c pins_len > 0; pins_len -= strlen(pins) + 1, pins += strlen(pins) + 1) { bank = exynos_gpio_bank_lookup(pins); + pin = exynos_parse_pin(pins); if (bank == NULL) { aprint_error_dev(pc->pc_sc->sc_dev, "unknown pin name '%s'\n", pins); continue; } - exynos_gpio_pin_ctl_write(bank, gc); + exynos_gpio_pin_ctl_write(bank, gc, pin); } return 0;