diff mbox series

[7/7] pinctrl: mediatek: paris: Support generic PIN_CONFIG_DRIVE_STRENGTH_UA

Message ID 20220111112244.1483783-8-wenst@chromium.org
State New
Headers show
Series [1/7] pinctrl: pinconf-generic: Print arguments for bias-pull-* | expand

Commit Message

Chen-Yu Tsai Jan. 11, 2022, 11:22 a.m. UTC
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(+)

Comments

Chen-Yu Tsai Jan. 12, 2022, 8:53 a.m. UTC | #1
On Tue, Jan 11, 2022 at 7:23 PM Chen-Yu Tsai <wenst@chromium.org> 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.

So I am actually unsure how to implement support for this properly.
My intention was to map "mediatek,drive-strength-adv" to
"drive-strength-microamp". This implies using the advanced mode if
the property is present, and vice versa.

(Also unsure if such a binding would be acceptable.)

However the pin configs are passed in one-by-one within the driver, so
it doesn't seem viable to check for the absence of a certain parameter.
This might involve a bit more rewriting.

ChenYu

> 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.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;
> +                               }
> +                       }
> +               }
> +
>                 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;
>         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) ?
> --
> 2.34.1.575.g55b058a8bb-goog
>
diff mbox series

Patch

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;
+				}
+			}
+		}
+
 		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;
 	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) ?