From 486478282e537f0e594ec68d6d7481e3220a7b47 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 21 Jan 2016 19:44:09 -0700 Subject: [PATCH] rockchip: gpio: Implement the get_function() method Provide this method so that 'gpio status' works fully. It now shows whether a pin is used for input, output or some other function. Signed-off-by: Simon Glass --- drivers/gpio/rk_gpio.c | 40 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/drivers/gpio/rk_gpio.c b/drivers/gpio/rk_gpio.c index a22e2195e4..c62f0251c4 100644 --- a/drivers/gpio/rk_gpio.c +++ b/drivers/gpio/rk_gpio.c @@ -8,11 +8,16 @@ */ #include +#include #include +#include #include #include #include +#include +#include #include +#include enum { ROCKCHIP_GPIOS_PER_BANK = 32, @@ -22,6 +27,8 @@ enum { struct rockchip_gpio_priv { struct rockchip_gpio_regs *regs; + struct udevice *pinctrl; + int bank; char name[2]; }; @@ -70,7 +77,25 @@ static int rockchip_gpio_set_value(struct udevice *dev, unsigned offset, static int rockchip_gpio_get_function(struct udevice *dev, unsigned offset) { - return -ENOSYS; +#ifdef CONFIG_SPL_BUILD + return -ENODATA; +#else + struct rockchip_gpio_priv *priv = dev_get_priv(dev); + struct rockchip_gpio_regs *regs = priv->regs; + bool is_output; + int ret; + + ret = pinctrl_get_gpio_mux(priv->pinctrl, priv->bank, offset); + if (ret) + return ret; + + /* If it's not 0, then it is not a GPIO */ + if (ret) + return GPIOF_FUNC; + is_output = readl(®s->swport_ddr) & OFFSET_TO_BIT(offset); + + return is_output ? GPIOF_OUTPUT : GPIOF_INPUT; +#endif } static int rockchip_gpio_xlate(struct udevice *dev, struct gpio_desc *desc, @@ -87,13 +112,20 @@ static int rockchip_gpio_probe(struct udevice *dev) struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); struct rockchip_gpio_priv *priv = dev_get_priv(dev); char *end; - int bank; + int ret; + /* This only supports RK3288 at present */ priv->regs = (struct rockchip_gpio_regs *)dev_get_addr(dev); + ret = uclass_first_device(UCLASS_PINCTRL, &priv->pinctrl); + if (ret) + return ret; + if (!priv->pinctrl) + return -ENODEV; + uc_priv->gpio_count = ROCKCHIP_GPIOS_PER_BANK; end = strrchr(dev->name, '@'); - bank = trailing_strtoln(dev->name, end); - priv->name[0] = 'A' + bank; + priv->bank = trailing_strtoln(dev->name, end); + priv->name[0] = 'A' + priv->bank; uc_priv->bank_name = priv->name; return 0; -- 2.39.5