diff options
Diffstat (limited to 'drivers/pinctrl/mediatek/pinctrl-mtk-common.c')
-rw-r--r-- | drivers/pinctrl/mediatek/pinctrl-mtk-common.c | 122 |
1 files changed, 105 insertions, 17 deletions
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c index 3004335c57..c7351f32bb 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c @@ -294,7 +294,72 @@ static const struct pinconf_param mtk_conf_params[] = { { "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 0 }, }; -int mtk_pinconf_drive_set(struct udevice *dev, u32 pin, u32 arg) + +int mtk_pinconf_bias_set_v0(struct udevice *dev, u32 pin, u32 arg) +{ + int err, disable, pullup; + + disable = (arg == PIN_CONFIG_BIAS_DISABLE); + pullup = (arg == PIN_CONFIG_BIAS_PULL_UP); + + if (disable) { + err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_PU, 0); + if (err) + return err; + err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_PD, 0); + if (err) + return err; + + } else { + err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_PU, pullup); + if (err) + return err; + err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_PD, !pullup); + if (err) + return err; + } + + return 0; +} + +int mtk_pinconf_bias_set_v1(struct udevice *dev, u32 pin, u32 arg) +{ + int err, disable, pullup; + + disable = (arg == PIN_CONFIG_BIAS_DISABLE); + pullup = (arg == PIN_CONFIG_BIAS_PULL_UP); + + if (disable) { + err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_PULLEN, 0); + if (err) + return err; + } else { + err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_PULLEN, 1); + if (err) + return err; + err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_PULLSEL, + pullup); + if (err) + return err; + } + + return 0; +} + +int mtk_pinconf_input_enable_v1(struct udevice *dev, u32 pin, u32 arg) +{ + int err; + + err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_IES, 1); + if (err) + return err; + err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_DIR, 0); + if (err) + return err; + return 0; +} + +int mtk_pinconf_drive_set_v0(struct udevice *dev, u32 pin, u32 arg) { struct mtk_pinctrl_priv *priv = dev_get_priv(dev); const struct mtk_pin_desc *desc = &priv->soc->pins[pin]; @@ -309,7 +374,30 @@ int mtk_pinconf_drive_set(struct udevice *dev, u32 pin, u32 arg) */ if ((arg >= tb->min && arg <= tb->max) && !(arg % tb->step)) { arg = (arg / tb->step - 1) * tb->scal; + err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_E4, + arg & 0x1); + if (err) + return err; + err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_E8, + (arg & 0x2) >> 1); + if (err) + return err; + } + + return 0; +} + + +int mtk_pinconf_drive_set_v1(struct udevice *dev, u32 pin, u32 arg) +{ + struct mtk_pinctrl_priv *priv = dev_get_priv(dev); + const struct mtk_pin_desc *desc = &priv->soc->pins[pin]; + const struct mtk_drive_desc *tb; + int err = -ENOTSUPP; + tb = &mtk_drive[desc->drv_n]; + if ((arg >= tb->min && arg <= tb->max) && !(arg % tb->step)) { + arg = (arg / tb->step - 1) * tb->scal; err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_DRV, arg); if (err) return err; @@ -322,21 +410,17 @@ static int mtk_pinconf_set(struct udevice *dev, unsigned int pin, unsigned int param, unsigned int arg) { int err = 0; + struct mtk_pinctrl_priv *priv = dev_get_priv(dev); + int rev = priv->soc->rev; switch (param) { case PIN_CONFIG_BIAS_DISABLE: case PIN_CONFIG_BIAS_PULL_UP: case PIN_CONFIG_BIAS_PULL_DOWN: - arg = (param == PIN_CONFIG_BIAS_DISABLE) ? 0 : - (param == PIN_CONFIG_BIAS_PULL_UP) ? 3 : 2; - - err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_PULLSEL, - arg & 1); - if (err) - goto err; - - err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_PULLEN, - !!(arg & 2)); + if (rev == MTK_PINCTRL_V0) + err = mtk_pinconf_bias_set_v0(dev, pin, param); + else + err = mtk_pinconf_bias_set_v1(dev, pin, param); if (err) goto err; break; @@ -349,10 +433,8 @@ static int mtk_pinconf_set(struct udevice *dev, unsigned int pin, goto err; break; case PIN_CONFIG_INPUT_ENABLE: - err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_IES, 1); - if (err) - goto err; - err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_DIR, 0); + if (rev == MTK_PINCTRL_V1) + err = mtk_pinconf_input_enable_v1(dev, pin, param); if (err) goto err; break; @@ -381,7 +463,10 @@ static int mtk_pinconf_set(struct udevice *dev, unsigned int pin, goto err; break; case PIN_CONFIG_DRIVE_STRENGTH: - err = mtk_pinconf_drive_set(dev, pin, arg); + if (rev == MTK_PINCTRL_V0) + err = mtk_pinconf_drive_set_v0(dev, pin, arg); + else + err = mtk_pinconf_drive_set_v1(dev, pin, arg); if (err) goto err; break; @@ -475,7 +560,10 @@ static int mtk_gpio_direction_output(struct udevice *dev, static int mtk_gpio_request(struct udevice *dev, unsigned int off, const char *label) { - return mtk_hw_set_value(dev->parent, off, PINCTRL_PIN_REG_MODE, 0); + struct mtk_pinctrl_priv *priv = dev_get_priv(dev->parent); + + return mtk_hw_set_value(dev->parent, off, PINCTRL_PIN_REG_MODE, + priv->soc->gpio_mode); } static int mtk_gpio_probe(struct udevice *dev) |