diff options
author | Heiko Stübner <heiko@sntech.de> | 2014-04-23 14:28:59 +0200 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2014-04-23 23:19:40 +0200 |
commit | a076e2ed3fd26f8877a3a010e3fae6b5306ba1b0 (patch) | |
tree | f9b0c39a742c6627f546d91b3bf7fee92f9110b4 /drivers/pinctrl/pinctrl-rockchip.c | |
parent | pinctrl: rockchip: return a complete config in pinconf_get (diff) | |
download | linux-a076e2ed3fd26f8877a3a010e3fae6b5306ba1b0.tar.xz linux-a076e2ed3fd26f8877a3a010e3fae6b5306ba1b0.zip |
pinctrl: rockchip: implement PIN_CONFIG_OUTPUT handling
In some cases it is nice to be able to simply control a gpio output
via the PIN_CONFIG_OUTPUT option without having a driver control it.
Thus add support for it to the rockchip pinctrl driver.
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to '')
-rw-r--r-- | drivers/pinctrl/pinctrl-rockchip.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index ae3dfe7642f1..2e198a41c7bb 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -329,6 +329,23 @@ static const struct pinctrl_ops rockchip_pctrl_ops = { * Hardware access */ +static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin) +{ + struct rockchip_pinctrl *info = bank->drvdata; + void __iomem *reg = info->reg_base + info->ctrl->mux_offset; + u8 bit; + + if (bank->bank_type == RK3188_BANK0 && pin < 16) + return RK_FUNC_GPIO; + + /* get basic quadrupel of mux registers and the correct reg inside */ + reg += bank->bank_num * 0x10; + reg += (pin / 8) * 4; + bit = (pin % 8) * 2; + + return ((readl(reg) >> bit) & 3); +} + /* * Set a new mux function for a pin. * @@ -687,6 +704,10 @@ static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl, return false; } +static int rockchip_gpio_direction_output(struct gpio_chip *gc, + unsigned offset, int value); +static int rockchip_gpio_get(struct gpio_chip *gc, unsigned offset); + /* set the pin config settings for a specified pin */ static int rockchip_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, unsigned long *configs, unsigned num_configs) @@ -724,6 +745,13 @@ static int rockchip_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, if (rc) return rc; break; + case PIN_CONFIG_OUTPUT: + rc = rockchip_gpio_direction_output(&bank->gpio_chip, + pin - bank->pin_base, + arg); + if (rc) + return rc; + break; default: return -ENOTSUPP; break; @@ -741,6 +769,7 @@ static int rockchip_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin, struct rockchip_pin_bank *bank = pin_to_bank(info, pin); enum pin_config_param param = pinconf_to_config_param(*config); u16 arg; + int rc; switch (param) { case PIN_CONFIG_BIAS_DISABLE: @@ -761,6 +790,17 @@ static int rockchip_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin, arg = 1; break; + case PIN_CONFIG_OUTPUT: + rc = rockchip_get_mux(bank, pin - bank->pin_base); + if (rc != RK_FUNC_GPIO) + return -EINVAL; + + rc = rockchip_gpio_get(&bank->gpio_chip, pin - bank->pin_base); + if (rc < 0) + return rc; + + arg = rc ? 1 : 0; + break; default: return -ENOTSUPP; break; |