diff options
author | Simon Glass <sjg@chromium.org> | 2016-01-21 19:44:07 -0700 |
---|---|---|
committer | Simon Glass <sjg@chromium.org> | 2016-01-21 20:42:35 -0700 |
commit | 78a10b66566f313a2933ee5169494d44a1442578 (patch) | |
tree | c445d61ade5134053d6595203e7f9514ef0e52b9 | |
parent | 63c52648e42288db3bf44f41d19522b48af38978 (diff) |
rockchip: pinctrl: Implement the get_gpio_mux() method
Implement this so that the GPIO command will be able to report whether a
GPIO is used for input or output.
Signed-off-by: Simon Glass <sjg@chromium.org>
-rw-r--r-- | drivers/pinctrl/rockchip/pinctrl_rk3288.c | 68 |
1 files changed, 52 insertions, 16 deletions
diff --git a/drivers/pinctrl/rockchip/pinctrl_rk3288.c b/drivers/pinctrl/rockchip/pinctrl_rk3288.c index 53b8cf22cf..8356786b12 100644 --- a/drivers/pinctrl/rockchip/pinctrl_rk3288.c +++ b/drivers/pinctrl/rockchip/pinctrl_rk3288.c @@ -520,18 +520,16 @@ static int rk3288_pinctrl_set_state_simple(struct udevice *dev, } #ifndef CONFIG_SPL_BUILD -static int rk3288_pinctrl_set_pins(struct udevice *dev, int banknum, int index, - int muxval, int flags) +int rk3288_pinctrl_get_pin_info(struct rk3288_pinctrl_priv *priv, + int banknum, int ind, u32 **addrp, uint *shiftp, + uint *maskp) { - struct rk3288_pinctrl_priv *priv = dev_get_priv(dev); struct rockchip_pin_bank *bank = &rk3288_pin_banks[banknum]; - uint shift, muxnum, ind = index; + uint muxnum; u32 *addr; - debug("%s: %x %x %x %x\n", __func__, banknum, index, muxval, flags); for (muxnum = 0; muxnum < 4; muxnum++) { struct rockchip_iomux *mux = &bank->iomux[muxnum]; - uint mask; if (ind >= 8) { ind -= 8; @@ -543,24 +541,61 @@ static int rk3288_pinctrl_set_pins(struct udevice *dev, int banknum, int index, else addr = (u32 *)priv->grf - 4; addr += mux->offset; - shift = ind & 7; + *shiftp = ind & 7; if (mux->type & IOMUX_WIDTH_4BIT) { - mask = 0xf; - shift *= 4; - if (shift >= 16) { - shift -= 16; + *maskp = 0xf; + *shiftp *= 4; + if (*shiftp >= 16) { + *shiftp -= 16; addr++; } } else { - mask = 3; - shift *= 2; + *maskp = 3; + *shiftp *= 2; } debug("%s: addr=%p, mask=%x, shift=%x\n", __func__, addr, - mask, shift); - rk_clrsetreg(addr, mask << shift, muxval << shift); - break; + *maskp, *shiftp); + *addrp = addr; + return 0; } + + return -EINVAL; +} + +static int rk3288_pinctrl_get_gpio_mux(struct udevice *dev, int banknum, + int index) +{ + struct rk3288_pinctrl_priv *priv = dev_get_priv(dev); + uint shift; + uint mask; + u32 *addr; + int ret; + + ret = rk3288_pinctrl_get_pin_info(priv, banknum, index, &addr, &shift, + &mask); + if (ret) + return ret; + return (readl(addr) & mask) >> shift; +} + +static int rk3288_pinctrl_set_pins(struct udevice *dev, int banknum, int index, + int muxval, int flags) +{ + struct rk3288_pinctrl_priv *priv = dev_get_priv(dev); + uint shift, ind = index; + uint mask; + u32 *addr; + int ret; + + debug("%s: %x %x %x %x\n", __func__, banknum, index, muxval, flags); + ret = rk3288_pinctrl_get_pin_info(priv, banknum, index, &addr, &shift, + &mask); + if (ret) + return ret; + rk_clrsetreg(addr, mask << shift, muxval << shift); + + /* Handle pullup/pulldown */ if (flags) { uint val = 0; @@ -618,6 +653,7 @@ static int rk3288_pinctrl_set_state(struct udevice *dev, struct udevice *config) static struct pinctrl_ops rk3288_pinctrl_ops = { #ifndef CONFIG_SPL_BUILD .set_state = rk3288_pinctrl_set_state, + .get_gpio_mux = rk3288_pinctrl_get_gpio_mux, #endif .set_state_simple = rk3288_pinctrl_set_state_simple, .request = rk3288_pinctrl_request, |