]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
pinctrl: intel: Implement high impedance support
authorAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Thu, 29 Aug 2024 13:59:18 +0000 (16:59 +0300)
committerAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Fri, 30 Aug 2024 18:44:38 +0000 (21:44 +0300)
Implement high impedance support for Intel pin control hardware.
It allows to set high impedance and check it.

Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
drivers/pinctrl/intel/pinctrl-intel.c

index c6013d967fa66d5a8a50da2ffcea02882b097349..46530ee6e92df2545b3ebfca7ffa450706b74140 100644 (file)
@@ -652,6 +652,23 @@ static int intel_config_get_pull(struct intel_pinctrl *pctrl, unsigned int pin,
        return 0;
 }
 
+static int intel_config_get_high_impedance(struct intel_pinctrl *pctrl, unsigned int pin,
+                                          enum pin_config_param param, u32 *arg)
+{
+       void __iomem *padcfg0;
+       u32 value;
+
+       padcfg0 = intel_get_padcfg(pctrl, pin, PADCFG0);
+
+       scoped_guard(raw_spinlock_irqsave, &pctrl->lock)
+               value = readl(padcfg0);
+
+       if (__intel_gpio_get_direction(value) != PAD_CONNECT_NONE)
+               return -EINVAL;
+
+       return 0;
+}
+
 static int intel_config_get_debounce(struct intel_pinctrl *pctrl, unsigned int pin,
                                     enum pin_config_param param, u32 *arg)
 {
@@ -695,6 +712,12 @@ static int intel_config_get(struct pinctrl_dev *pctldev, unsigned int pin,
                        return ret;
                break;
 
+       case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
+               ret = intel_config_get_high_impedance(pctrl, pin, param, &arg);
+               if (ret)
+                       return ret;
+               break;
+
        case PIN_CONFIG_INPUT_DEBOUNCE:
                ret = intel_config_get_debounce(pctrl, pin, param, &arg);
                if (ret)
@@ -793,6 +816,20 @@ static int intel_config_set_pull(struct intel_pinctrl *pctrl, unsigned int pin,
        return 0;
 }
 
+static void intel_gpio_set_high_impedance(struct intel_pinctrl *pctrl, unsigned int pin)
+{
+       void __iomem *padcfg0;
+       u32 value;
+
+       padcfg0 = intel_get_padcfg(pctrl, pin, PADCFG0);
+
+       guard(raw_spinlock_irqsave)(&pctrl->lock);
+
+       value = readl(padcfg0);
+       value = __intel_gpio_set_direction(value, false, false);
+       writel(value, padcfg0);
+}
+
 static int intel_config_set_debounce(struct intel_pinctrl *pctrl,
                                     unsigned int pin, unsigned int debounce)
 {
@@ -855,6 +892,10 @@ static int intel_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
                                return ret;
                        break;
 
+               case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
+                       intel_gpio_set_high_impedance(pctrl, pin);
+                       break;
+
                case PIN_CONFIG_INPUT_DEBOUNCE:
                        ret = intel_config_set_debounce(pctrl, pin,
                                pinconf_to_config_argument(configs[i]));