Module Name: src Committed By: marty Date: Fri Jan 1 22:37:07 UTC 2016
Modified Files: src/sys/arch/arm/samsung: exynos_i2c.c exynos_pinctrl.c Log Message: XU4 FDT pinctrl Rewrite the use of pinctrl to reflect the new model from Jared. To generate a diff of this commit: cvs rdiff -u -r1.9 -r1.10 src/sys/arch/arm/samsung/exynos_i2c.c cvs rdiff -u -r1.8 -r1.9 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_i2c.c diff -u src/sys/arch/arm/samsung/exynos_i2c.c:1.9 src/sys/arch/arm/samsung/exynos_i2c.c:1.10 --- src/sys/arch/arm/samsung/exynos_i2c.c:1.9 Wed Dec 30 04:30:27 2015 +++ src/sys/arch/arm/samsung/exynos_i2c.c Fri Jan 1 22:37:07 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: exynos_i2c.c,v 1.9 2015/12/30 04:30:27 marty Exp $ */ +/* $NetBSD: exynos_i2c.c,v 1.10 2016/01/01 22:37:07 marty Exp $ */ /* * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca> @@ -31,7 +31,7 @@ #include "opt_arm_debug.h" #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: exynos_i2c.c,v 1.9 2015/12/30 04:30:27 marty Exp $"); +__KERNEL_RCSID(0, "$NetBSD: exynos_i2c.c,v 1.10 2016/01/01 22:37:07 marty Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -144,18 +144,11 @@ exynos_i2c_attach(device_t parent, devic bus_size_t size; int error; - char result[64]; - int i2c_handle; - int len; - int handle; - int func, pud, drv; - if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { aprint_error(": couldn't get registers\n"); return; } - sc->sc_dev = self; sc->sc_bst = faa->faa_bst; error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh); @@ -182,66 +175,8 @@ exynos_i2c_attach(device_t parent, devic return; } aprint_normal_dev(self, "interrupting on %s\n", intrstr); - - len = OF_getprop(phandle, "pinctrl-0", (char *)&handle, - sizeof(handle)); - if (len != sizeof(int)) { - aprint_error_dev(self, "couldn't get pinctrl-0.\n"); - return; - } - - i2c_handle = fdtbus_get_phandle_from_native(be32toh(handle)); - len = OF_getprop(i2c_handle, "samsung,pins", result, sizeof(result)); - if (len <= 0) { - aprint_error_dev(self, "couldn't get pins.\n"); - return; - } - len = OF_getprop(i2c_handle, "samsung,pin-function", - &handle, sizeof(handle)); - if (len <= 0) { - aprint_error_dev(self, "couldn't get pin-function.\n"); - return; - } else - func = be32toh(handle); - - sc->sc_sda = fdtbus_pinctrl_acquire(phandle, &result[0]); - if (sc->sc_sda == NULL) { - printf("could not acquire sda gpio %s\n", &result[0]); - return; - } - - sc->sc_scl = fdtbus_pinctrl_acquire(phandle, &result[7]); - if (sc->sc_scl == NULL) { - printf("could not acquire scl gpio %s\n", &result[7]); - return; - } - - len = OF_getprop(i2c_handle, "samsung,pin-pud", &handle, - sizeof(&handle)); - if (len <= 0) { - aprint_error_dev(self, "couldn't get pin-pud.\n"); - return; - } else - pud = be32toh(handle); - - len = OF_getprop(i2c_handle, "samsung,pin-drv", &handle, - sizeof(&handle)); - if (len <= 0) { - aprint_error_dev(self, "couldn't get pin-drv.\n"); - return; - } else - drv = be32toh(handle); - - struct exynos_gpio_pin_cfg cfg; - cfg.cfg = func; - cfg.pud = pud; - cfg.drv = drv; - cfg.conpwd = 0; - cfg.pudpwd = 0; - - fdtbus_pinctrl_set_cfg(sc->sc_scl, &cfg); - fdtbus_pinctrl_set_cfg(sc->sc_sda, &cfg); + fdtbus_pinctrl_set_config_index(phandle, 0); sc->sc_ic.ic_cookie = sc; sc->sc_ic.ic_acquire_bus = exynos_i2c_acquire_bus; Index: src/sys/arch/arm/samsung/exynos_pinctrl.c diff -u src/sys/arch/arm/samsung/exynos_pinctrl.c:1.8 src/sys/arch/arm/samsung/exynos_pinctrl.c:1.9 --- src/sys/arch/arm/samsung/exynos_pinctrl.c:1.8 Wed Dec 30 04:30:27 2015 +++ src/sys/arch/arm/samsung/exynos_pinctrl.c Fri Jan 1 22:37:07 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: exynos_pinctrl.c,v 1.8 2015/12/30 04:30:27 marty Exp $ */ +/* $NetBSD: exynos_pinctrl.c,v 1.9 2016/01/01 22:37:07 marty 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.8 2015/12/30 04:30:27 marty Exp $"); +__KERNEL_RCSID(1, "$NetBSD: exynos_pinctrl.c,v 1.9 2016/01/01 22:37:07 marty Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -53,19 +53,21 @@ __KERNEL_RCSID(1, "$NetBSD: exynos_pinct #include <dev/fdt/fdtvar.h> +struct exynos_pinctrl_config { + int pc_phandle; + struct exynos_gpio_pin_cfg *pc_pincfg; + struct exynos_pinctrl_softc *pc_sc; +}; + static int exynos_pinctrl_match(device_t, cfdata_t, void *); static void exynos_pinctrl_attach(device_t, device_t, void *); -static void *exynos_pinctrl_acquire(device_t, const char *); -static void exynos_pinctrl_release(device_t, void *); -static void exynos_pinctrl_get_cfg(struct fdtbus_pinctrl_pin *, void *); -static void exynos_pinctrl_set_cfg(struct fdtbus_pinctrl_pin *, void *); +static int exynos_pinctrl_set_cfg(void *); +static struct exynos_gpio_pin_cfg * +exynos_parse_config(struct exynos_pinctrl_config *pc); static struct fdtbus_pinctrl_controller_func exynos_pinctrl_controller_func = { - .acquire = exynos_pinctrl_acquire, - .release = exynos_pinctrl_release, - .get = exynos_pinctrl_get_cfg, - .set = exynos_pinctrl_set_cfg, + .set_config = exynos_pinctrl_set_cfg }; CFATTACH_DECL_NEW(exynos_pinctrl, sizeof(struct exynos_pinctrl_softc), @@ -80,13 +82,19 @@ 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) { struct exynos_pinctrl_softc * const sc = kmem_zalloc(sizeof(*sc), KM_SLEEP); struct fdt_attach_args * const faa = aux; - struct exynos_gpio_softc *child_sc; bus_addr_t addr; bus_size_t size; int error; @@ -112,43 +120,96 @@ 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") == false) - continue; - child_sc = exynos_gpio_bank_config(sc, faa, child); - fdtbus_register_pinctrl_controller(child_sc->sc_dev, child, - &exynos_pinctrl_controller_func); + + if (of_getprop_bool(child, "gpio-controller")) { + exynos_gpio_bank_config(sc, faa, child); + } + + if (is_pinctrl(child)) { + struct exynos_pinctrl_config *pc; + pc = kmem_alloc(sizeof(*pc), KM_SLEEP); + pc->pc_phandle = child; + pc->pc_sc = sc; + pc->pc_pincfg = exynos_parse_config(pc); + fdtbus_register_pinctrl_config(pc, child, + &exynos_pinctrl_controller_func); + } } } - -static void *exynos_pinctrl_acquire(device_t self, const char *name) +static struct exynos_gpio_pin_cfg * +exynos_parse_config(struct exynos_pinctrl_config *pc) { - return exynos_gpio_bank_lookup(name); -} + struct exynos_gpio_pin_cfg *gc = kmem_zalloc(sizeof(*gc), KM_SLEEP); + int len; + int value; + + len = OF_getprop(pc->pc_phandle, "samsung,pin-function", + &value, sizeof(value)); + if (len > 0) { + gc->cfg = be32toh(value); + } -static void exynos_pinctrl_release(device_t self, void *cookie) -{ + len = OF_getprop(pc->pc_phandle, "samsung,pin-pud", &value, + sizeof(&value)); + if (len > 0) { + gc->pud = be32toh(value); + } + + len = OF_getprop(pc->pc_phandle, "samsung,pin-drv", &value, + sizeof(&value)); + if (len > 0) { + gc->drv = be32toh(value); + } + + len = OF_getprop(pc->pc_phandle, "samsung,pin-conpwd", &value, + sizeof(&value)); + if (len > 0) { + gc->conpwd = be32toh(value); + } + + len = OF_getprop(pc->pc_phandle, "samsung,pin-pudpwd", &value, + sizeof(&value)); + if (len > 0) { + gc->pudpwd = be32toh(value); + } + return gc; } -static void exynos_pinctrl_get_cfg(struct fdtbus_pinctrl_pin *pin, - void *cookie) +static int +exynos_do_config(struct exynos_pinctrl_config *pc) { - struct exynos_gpio_bank *bank = pin->pp_priv; - struct exynos_gpio_pin_cfg *cfg = cookie; - struct exynos_gpio_pin_cfg **cfgp = &cfg; - struct exynos_gpio_pin_cfg *newcfg = kmem_zalloc(sizeof(*newcfg), - KM_SLEEP); - if (newcfg == NULL) - return; - exynos_gpio_pin_ctl_read(bank, newcfg); - *cfgp = newcfg; - return; -} + struct exynos_gpio_pin_cfg *gc = pc->pc_pincfg; + struct exynos_gpio_bank *bank; + int len; + char result[20]; + + if (gc == NULL) { + printf("%s: No configuration available\n", __func__); + return -1; + } -static void exynos_pinctrl_set_cfg(struct fdtbus_pinctrl_pin *pin, - void *cookie) + len = OF_getprop(pc->pc_phandle, "samsung,pins", result, + sizeof(result)); + if (len <= 0) { + printf("%s: couldn't get pins. (%d)\n", __func__, + pc->pc_phandle); + return -1; + } + + bank = exynos_gpio_bank_lookup(&result[0]); + if (!bank) { + printf("%s: Couldn't get bank \"%s\".\n", __func__, result); + return -1; + } + + exynos_gpio_pin_ctl_write(bank, gc); + return 0; +} + +static int +exynos_pinctrl_set_cfg(void *cookie) { - struct exynos_gpio_bank *bank = pin->pp_priv; - struct exynos_gpio_pin_cfg *cfg = cookie; - exynos_gpio_pin_ctl_write(bank, cfg); + struct exynos_pinctrl_config *pc = cookie; + return exynos_do_config(pc); }