summaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl/renesas/pinctrl.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pinctrl/renesas/pinctrl.c')
-rw-r--r--drivers/pinctrl/renesas/pinctrl.c68
1 files changed, 54 insertions, 14 deletions
diff --git a/drivers/pinctrl/renesas/pinctrl.c b/drivers/pinctrl/renesas/pinctrl.c
index 212a4a9c3a8f..ac542d278a38 100644
--- a/drivers/pinctrl/renesas/pinctrl.c
+++ b/drivers/pinctrl/renesas/pinctrl.c
@@ -26,9 +26,8 @@
#include "../pinconf.h"
struct sh_pfc_pin_config {
- unsigned int mux_mark;
- bool mux_set;
- bool gpio_enabled;
+ u16 gpio_enabled:1;
+ u16 mux_mark:15;
};
struct sh_pfc_pinctrl {
@@ -371,12 +370,11 @@ static int sh_pfc_func_set_mux(struct pinctrl_dev *pctldev, unsigned selector,
goto done;
}
- /* All group pins are configured, mark the pins as mux_set */
+ /* All group pins are configured, mark the pins as muxed */
for (i = 0; i < grp->nr_pins; ++i) {
int idx = sh_pfc_get_pin_index(pfc, grp->pins[i]);
struct sh_pfc_pin_config *cfg = &pmx->configs[idx];
- cfg->mux_set = true;
cfg->mux_mark = grp->mux[i];
}
@@ -399,7 +397,7 @@ static int sh_pfc_gpio_request_enable(struct pinctrl_dev *pctldev,
spin_lock_irqsave(&pfc->lock, flags);
if (!pfc->gpio) {
- /* If GPIOs are handled externally the pin mux type need to be
+ /* If GPIOs are handled externally the pin mux type needs to be
* set to GPIO here.
*/
const struct sh_pfc_pin *pin = &pfc->info->pins[idx];
@@ -432,11 +430,12 @@ static void sh_pfc_gpio_disable_free(struct pinctrl_dev *pctldev,
spin_lock_irqsave(&pfc->lock, flags);
cfg->gpio_enabled = false;
/* If mux is already set, this configures it here */
- if (cfg->mux_set)
+ if (cfg->mux_mark)
sh_pfc_config_mux(pfc, cfg->mux_mark, PINMUX_TYPE_FUNCTION);
spin_unlock_irqrestore(&pfc->lock, flags);
}
+#ifdef CONFIG_PINCTRL_SH_PFC_GPIO
static int sh_pfc_gpio_set_direction(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned offset, bool input)
@@ -450,8 +449,8 @@ static int sh_pfc_gpio_set_direction(struct pinctrl_dev *pctldev,
unsigned int dir;
int ret;
- /* Check if the requested direction is supported by the pin. Not all SoC
- * provide pin config data, so perform the check conditionally.
+ /* Check if the requested direction is supported by the pin. Not all
+ * SoCs provide pin config data, so perform the check conditionally.
*/
if (pin->configs) {
dir = input ? SH_PFC_PIN_CFG_INPUT : SH_PFC_PIN_CFG_OUTPUT;
@@ -460,15 +459,13 @@ static int sh_pfc_gpio_set_direction(struct pinctrl_dev *pctldev,
}
spin_lock_irqsave(&pfc->lock, flags);
-
ret = sh_pfc_config_mux(pfc, pin->enum_id, new_type);
- if (ret < 0)
- goto done;
-
-done:
spin_unlock_irqrestore(&pfc->lock, flags);
return ret;
}
+#else
+#define sh_pfc_gpio_set_direction NULL
+#endif
static const struct pinmux_ops sh_pfc_pinmux_ops = {
.get_functions_count = sh_pfc_get_functions_count,
@@ -830,3 +827,46 @@ int sh_pfc_register_pinctrl(struct sh_pfc *pfc)
return pinctrl_enable(pmx->pctl);
}
+
+unsigned int rcar_pinmux_get_bias(struct sh_pfc *pfc, unsigned int pin)
+{
+ const struct pinmux_bias_reg *reg;
+ unsigned int bit;
+
+ reg = sh_pfc_pin_to_bias_reg(pfc, pin, &bit);
+ if (!reg)
+ return PIN_CONFIG_BIAS_DISABLE;
+
+ if (!(sh_pfc_read(pfc, reg->puen) & BIT(bit)))
+ return PIN_CONFIG_BIAS_DISABLE;
+ else if (!reg->pud || (sh_pfc_read(pfc, reg->pud) & BIT(bit)))
+ return PIN_CONFIG_BIAS_PULL_UP;
+ else
+ return PIN_CONFIG_BIAS_PULL_DOWN;
+}
+
+void rcar_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin,
+ unsigned int bias)
+{
+ const struct pinmux_bias_reg *reg;
+ u32 enable, updown;
+ unsigned int bit;
+
+ reg = sh_pfc_pin_to_bias_reg(pfc, pin, &bit);
+ if (!reg)
+ return;
+
+ enable = sh_pfc_read(pfc, reg->puen) & ~BIT(bit);
+ if (bias != PIN_CONFIG_BIAS_DISABLE)
+ enable |= BIT(bit);
+
+ if (reg->pud) {
+ updown = sh_pfc_read(pfc, reg->pud) & ~BIT(bit);
+ if (bias == PIN_CONFIG_BIAS_PULL_UP)
+ updown |= BIT(bit);
+
+ sh_pfc_write(pfc, reg->pud, updown);
+ }
+
+ sh_pfc_write(pfc, reg->puen, enable);
+}