[PATCH 7/7] pinctrl: mediatek: paris: Support generic PIN_CONFIG_DRIVE_STRENGTH_UA
zhiyong.tao
zhiyong.tao at mediatek.com
Mon Jan 17 18:36:47 PST 2022
On Tue, 2022-01-11 at 19:22 +0800, Chen-Yu Tsai wrote:
> 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 at 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.c
> b/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 custom
> MTK_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.
> 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) ?
More information about the Linux-mediatek
mailing list