Re: [PATCH 7/7] pinctrl: mediatek: paris: Support generic PIN_CONFIG_DRIVE_STRENGTH_UA
From: zhiyong.tao <hidden>
Date: 2022-01-18 03:09:58
Also in:
linux-mediatek
On Tue, 2022-01-11 at 19:22 +0800, Chen-Yu Tsai wrote:
quoted hunk ↗ jump to hunk
Some of the MediaTek chips that utilize the Paris pinctrl driver library support a lower drive strength (<= 1mA) than the standard drive strength settings (2~16 mA) on certain pins. This was previously supported by the custom MTK_PIN_CONFIG_DRV_ADV parameter along with the "mediatek,drive-strength-adv" device tree property. The drive strength values for this hardware are 125, 250, 500, and 1000 mA, and can be readily described by the existing "drive-strength- microamp", which then gets parsed by the generic pinconf library into the parameter PIN_CONFIG_DRIVE_STRENGTH_UA. Add support for PIN_CONFIG_DRIVE_STRENGTH_UA while keeping the old custom parameter around for backward compatibility. Signed-off-by: Chen-Yu Tsai <wenst@chromium.org> --- The indentation in the switch/case blocks is getting somewhat out of control. I also have some cleanup changes to reverse the logic of the if/break statements. Not sure if it should be done before or after this patch though. --- drivers/pinctrl/mediatek/pinctrl-paris.c | 84 ++++++++++++++++++++++++ 1 file changed, 84 insertions(+)diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.cb/drivers/pinctrl/mediatek/pinctrl-paris.c index 678c8aa33012..5a94903ae372 100644--- a/drivers/pinctrl/mediatek/pinctrl-paris.c +++ b/drivers/pinctrl/mediatek/pinctrl-paris.c@@ -48,6 +48,53 @@ static const char * const mtk_gpio_functions[] = { "func12", "func13", "func14", "func15", }; +/* + * This section supports converting to/from customMTK_PIN_CONFIG_DRV_ADV + * and standard PIN_CONFIG_DRIVE_STRENGTH_UA pin configs. + * + * The custom value encodes three hardware bits as follows: + * + * | Bits | + * | 2 (E1) | 1 (E0) | 0 (EN) | drive strength (uA) + * ------------------------------------------------ + * | x | x | 0 | disabled, use standard drive strength + * ------------------------------------- + * | 0 | 0 | 1 | 125 uA + * | 0 | 1 | 1 | 250 uA + * | 1 | 0 | 1 | 500 uA + * | 1 | 1 | 1 | 1000 uA + */ +static const int mtk_drv_adv_uA[] = { 125, 250, 500, 1000 }; + +static int mtk_drv_adv_to_uA(int val) +{ + /* This should never happen. */ + if (WARN_ON_ONCE(val < 0 || val > 7)) + return -EINVAL; + + /* Bit 0 simply enables this hardware part */ + if (!(val & BIT(0))) + return -EINVAL; + + return mtk_drv_adv_uA[(val >> 1)]; +} + +static int mtk_drv_uA_to_adv(int val) +{ + switch (val) { + case 125: + return 0x1; + case 250: + return 0x3; + case 500: + return 0x5; + case 1000: + return 0x7; + } + + return -EINVAL; +} + static int mtk_pinmux_gpio_request_enable(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range, unsigned int pin)@@ -151,11 +198,38 @@ static int mtk_pinconf_get(struct pinctrl_dev*pctldev, break; case PIN_CONFIG_DRIVE_STRENGTH: + if (hw->soc->adv_drive_get) { + err = hw->soc->adv_drive_get(hw, desc, &ret); + if (!err) { + err = mtk_drv_adv_to_uA(ret); + if (err > 0) { + /* PIN_CONFIG_DRIVE_STRENGTH_UA used */ + err = -EINVAL; + break; + } + } + } +
Hi Chen-Yu, PIN_CONFIG_DRIVE_STRENGTH is seems used for 2/4/6/8ma, it is not used for 125/250/500/1000ma. why you change here? Thanks.
if (hw->soc->drive_get)
err = hw->soc->drive_get(hw, desc, &ret);
else
err = -ENOTSUPP;
break;
+ case PIN_CONFIG_DRIVE_STRENGTH_UA:
+ if (hw->soc->adv_drive_get) {
+ err = hw->soc->adv_drive_get(hw, desc, &ret);
+ if (err)
+ break;
+ err = mtk_drv_adv_to_uA(ret);
+ if (err < 0)
+ break;
+
+ ret = err;
+ err = 0;
+ } else {
+ err = -ENOTSUPP;
+ }
+ break;Hi Chen-Yu, For PIN_CONFIG_DRIVE_STRENGTH_UA case, How can we use in dts node ? Thanks.
quoted hunk ↗ jump to hunk
case MTK_PIN_CONFIG_TDSEL: case MTK_PIN_CONFIG_RDSEL: reg = (param == MTK_PIN_CONFIG_TDSEL) ?@@ -271,6 +345,16 @@ static int mtk_pinconf_set(struct pinctrl_dev*pctldev, unsigned int pin, else err = -ENOTSUPP; break; + case PIN_CONFIG_DRIVE_STRENGTH_UA: + if (hw->soc->adv_drive_set) { + err = mtk_drv_uA_to_adv(arg); + if (err < 0) + break; + err = hw->soc->adv_drive_set(hw, desc, err); + } else { + err = -ENOTSUPP; + } + break; case MTK_PIN_CONFIG_TDSEL: case MTK_PIN_CONFIG_RDSEL: reg = (param == MTK_PIN_CONFIG_TDSEL) ?
_______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel