From 9dff07512666ed5009d92495bd76e32a747e5330 Mon Sep 17 00:00:00 2001 From: Jianqun Xu Date: Tue, 15 Mar 2022 12:48:30 +0800 Subject: [PATCH] pinctrl: rockchip: introduce rk_iomux_set/get Add rk_iomux_set and rk_iomux_get functions and export them, which can set or get iomux by bank and pin index. Signed-off-by: Jianqun Xu Change-Id: I2fa94c9fe7d28c545fc31033e70c26cd5c57fed7 --- drivers/pinctrl/pinctrl-rockchip.c | 102 +++++++++++++++++++++++++++++ drivers/pinctrl/pinctrl-rockchip.h | 17 +++++ 2 files changed, 119 insertions(+) diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index 0fe32087deb7..5436808f4b0f 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -235,6 +235,9 @@ #define RK3588_PIN_BANK_FLAGS(ID, PIN, LABEL, M, P) \ PIN_BANK_IOMUX_FLAGS_PULL_FLAGS(ID, PIN, LABEL, M, M, M, M, P, P, P, P) +static struct pinctrl_dev *g_pctldev; +static DEFINE_MUTEX(iomux_lock); + static struct regmap_config rockchip_regmap_config = { .reg_bits = 32, .val_bits = 32, @@ -3820,6 +3823,7 @@ static int rockchip_pinctrl_probe(struct platform_device *pdev) return ret; platform_set_drvdata(pdev, info); + g_pctldev = info->pctl_dev; ret = of_platform_populate(np, rockchip_bank_match, NULL, NULL); if (ret) { @@ -3838,6 +3842,7 @@ static int rockchip_pinctrl_remove(struct platform_device *pdev) struct rockchip_pin_output_deferred *cfg; int i; + g_pctldev = NULL; of_platform_depopulate(&pdev->dev); for (i = 0; i < info->ctrl->nr_banks; i++) { @@ -4519,6 +4524,103 @@ static void __exit rockchip_pinctrl_drv_unregister(void) } module_exit(rockchip_pinctrl_drv_unregister); +/** + * rk_iomux_set - set the rockchip iomux by pin number. + * + * @bank: the gpio bank index, from 0 to the max bank num. + * @pin: the gpio pin index, from 0 to 31. + * @mux: the pointer to store mux value. + * + * Return 0 if set success, else return error code. + */ +int rk_iomux_set(int bank, int pin, int mux) +{ + struct pinctrl_dev *pctldev = g_pctldev; + struct rockchip_pinctrl *info; + struct rockchip_pin_bank *gpio; + struct rockchip_pin_group *grp = NULL; + struct rockchip_pin_config *cfg = NULL; + int i, j, ret; + + if (!g_pctldev) + return -ENODEV; + + info = pinctrl_dev_get_drvdata(pctldev); + if (bank >= info->ctrl->nr_banks) + return -EINVAL; + + if (pin > 31 || pin < 0) + return -EINVAL; + + gpio = &info->ctrl->pin_banks[bank]; + + mutex_lock(&iomux_lock); + for (i = 0; i < info->ngroups; i++) { + grp = &info->groups[i]; + for (j = 0; j < grp->npins; i++) { + if (grp->pins[i] == (gpio->pin_base + pin)) { + cfg = grp->data; + break; + } + } + } + + ret = rockchip_set_mux(gpio, pin, mux); + if (ret) { + dev_err(info->dev, "mux GPIO%d-%d %d fail\n", bank, pin, mux); + goto out; + } + + if (cfg && (cfg->func != mux)) + cfg->func = mux; + +out: + mutex_unlock(&iomux_lock); + + return ret; +} +EXPORT_SYMBOL_GPL(rk_iomux_set); + +/** + * rk_iomux_get - get the rockchip iomux by pin number. + * + * @bank: the gpio bank index, from 0 to the max bank num. + * @pin: the gpio pin index, from 0 to 31. + * @mux: the pointer to store mux value. + * + * Return 0 if get success, else return error code. + */ +int rk_iomux_get(int bank, int pin, int *mux) +{ + struct pinctrl_dev *pctldev = g_pctldev; + struct rockchip_pinctrl *info; + struct rockchip_pin_bank *gpio; + int ret; + + if (!g_pctldev) + return -ENODEV; + if (!mux) + return -EINVAL; + + info = pinctrl_dev_get_drvdata(pctldev); + if (bank >= info->ctrl->nr_banks) + return -EINVAL; + + if (pin > 31 || pin < 0) + return -EINVAL; + + gpio = &info->ctrl->pin_banks[bank]; + + mutex_lock(&iomux_lock); + ret = rockchip_get_mux(gpio, pin); + mutex_unlock(&iomux_lock); + + *mux = ret; + + return (ret >= 0) ? 0 : ret; +} +EXPORT_SYMBOL_GPL(rk_iomux_get); + MODULE_DESCRIPTION("ROCKCHIP Pin Controller Driver"); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:pinctrl-rockchip"); diff --git a/drivers/pinctrl/pinctrl-rockchip.h b/drivers/pinctrl/pinctrl-rockchip.h index 35b39139e91c..2dfc7de84287 100644 --- a/drivers/pinctrl/pinctrl-rockchip.h +++ b/drivers/pinctrl/pinctrl-rockchip.h @@ -18,6 +18,8 @@ #ifndef _PINCTRL_ROCKCHIP_H #define _PINCTRL_ROCKCHIP_H +#include + #define RK_GPIO0_A0 0 #define RK_GPIO0_A1 1 #define RK_GPIO0_A2 2 @@ -470,4 +472,19 @@ struct rockchip_pinctrl { unsigned int nfunctions; }; +#if IS_ENABLED(CONFIG_PINCTRL_ROCKCHIP) +int rk_iomux_set(int bank, int pin, int mux); +int rk_iomux_get(int bank, int pin, int *mux); +#else +static inline int rk_iomux_set(int bank, int pin, int mux) +{ + return -EINVAL; +} + +static inline int rk_iomux_get(int bank, int pin, int *mux) +{ + return -EINVAL; +} +#endif + #endif