pinctrl: intel: Enumerate PWM device when community has a capability
authorAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Thu, 17 Nov 2022 11:08:06 +0000 (13:08 +0200)
committerAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Tue, 22 Nov 2022 18:34:02 +0000 (20:34 +0200)
Some of the Communities may have PWM capability. In such cases,
enumerate the PWM device via respective driver. A user is still
responsible for setting correct pin muxing for the line that
needs to output the signal.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: Thierry Reding <thierry.reding@gmail.com>
Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Acked-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
drivers/pinctrl/intel/pinctrl-intel.c

index 52ecd66ce357fceaabbd4e5980c6e9c36994af81..d74c8b650aa788ed21fc0a263e965f9b35e7db3a 100644 (file)
@@ -21,6 +21,8 @@
 #include <linux/pinctrl/pinconf.h>
 #include <linux/pinctrl/pinconf-generic.h>
 
+#include <linux/platform_data/x86/pwm-lpss.h>
+
 #include "../core.h"
 #include "pinctrl-intel.h"
 
@@ -46,6 +48,8 @@
 #define PADOWN_MASK(p)                 (GENMASK(3, 0) << PADOWN_SHIFT(p))
 #define PADOWN_GPP(p)                  ((p) / 8)
 
+#define PWMC                           0x204
+
 /* Offset from pad_regs */
 #define PADCFG0                                0x000
 #define PADCFG0_RXEVCFG_SHIFT          25
@@ -1499,6 +1503,27 @@ static int intel_pinctrl_pm_init(struct intel_pinctrl *pctrl)
        return 0;
 }
 
+static int intel_pinctrl_probe_pwm(struct intel_pinctrl *pctrl,
+                                  struct intel_community *community)
+{
+       static const struct pwm_lpss_boardinfo info = {
+               .clk_rate = 19200000,
+               .npwm = 1,
+               .base_unit_bits = 22,
+               .bypass = true,
+       };
+       struct pwm_lpss_chip *pwm;
+
+       if (!(community->features & PINCTRL_FEATURE_PWM))
+               return 0;
+
+       if (!IS_REACHABLE(CONFIG_PWM_LPSS))
+               return 0;
+
+       pwm = devm_pwm_lpss_probe(pctrl->dev, community->regs + PWMC, &info);
+       return PTR_ERR_OR_ZERO(pwm);
+}
+
 static int intel_pinctrl_probe(struct platform_device *pdev,
                               const struct intel_pinctrl_soc_data *soc_data)
 {
@@ -1584,6 +1609,10 @@ static int intel_pinctrl_probe(struct platform_device *pdev,
                        ret = intel_pinctrl_add_padgroups_by_size(pctrl, community);
                if (ret)
                        return ret;
+
+               ret = intel_pinctrl_probe_pwm(pctrl, community);
+               if (ret)
+                       return ret;
        }
 
        irq = platform_get_irq(pdev, 0);