diff mbox

[1/3] pwm: lpss: Add support for multiple PWMs

Message ID 1445349187-114759-1-git-send-email-mika.westerberg@linux.intel.com
State Accepted
Headers show

Commit Message

Mika Westerberg Oct. 20, 2015, 1:53 p.m. UTC
New Intel SoCs such as Broxton will have four PWMs per PCI (or ACPI)
device. Each PWM has 1k of register space allocated from the parent device.
Add support for this.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 drivers/pwm/pwm-lpss.c | 48 +++++++++++++++++++++++++++---------------------
 drivers/pwm/pwm-lpss.h |  1 +
 2 files changed, 28 insertions(+), 21 deletions(-)

Comments

Mika Westerberg Nov. 6, 2015, 9:15 a.m. UTC | #1
On Tue, Oct 20, 2015 at 04:53:05PM +0300, Mika Westerberg wrote:
> New Intel SoCs such as Broxton will have four PWMs per PCI (or ACPI)
> device. Each PWM has 1k of register space allocated from the parent device.
> Add support for this.

Hi Thierry,

Are you going to pick these up to PWM tree?

Thanks.
--
To unsubscribe from this list: send the line "unsubscribe linux-pwm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Thierry Reding Nov. 6, 2015, 1:29 p.m. UTC | #2
On Tue, Oct 20, 2015 at 04:53:05PM +0300, Mika Westerberg wrote:
> New Intel SoCs such as Broxton will have four PWMs per PCI (or ACPI)
> device. Each PWM has 1k of register space allocated from the parent device.
> Add support for this.
> 
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> ---
>  drivers/pwm/pwm-lpss.c | 48 +++++++++++++++++++++++++++---------------------
>  drivers/pwm/pwm-lpss.h |  1 +
>  2 files changed, 28 insertions(+), 21 deletions(-)

Applied all three patches, with a minor cleanup, see below.

> diff --git a/drivers/pwm/pwm-lpss.h b/drivers/pwm/pwm-lpss.h
> index aa041bb1b67d..ef2419f47c57 100644
> --- a/drivers/pwm/pwm-lpss.h
> +++ b/drivers/pwm/pwm-lpss.h
> @@ -20,6 +20,7 @@ struct pwm_lpss_chip;
>  
>  struct pwm_lpss_boardinfo {
>  	unsigned long clk_rate;
> +	size_t npwm;
>  };

I changed the type of npwm to unsigned int to match the definition of
the pwm_chip.npwm field.

Thanks,
Thierry
Mika Westerberg Nov. 6, 2015, 1:36 p.m. UTC | #3
On Fri, Nov 06, 2015 at 02:29:53PM +0100, Thierry Reding wrote:
> On Tue, Oct 20, 2015 at 04:53:05PM +0300, Mika Westerberg wrote:
> > New Intel SoCs such as Broxton will have four PWMs per PCI (or ACPI)
> > device. Each PWM has 1k of register space allocated from the parent device.
> > Add support for this.
> > 
> > Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> > ---
> >  drivers/pwm/pwm-lpss.c | 48 +++++++++++++++++++++++++++---------------------
> >  drivers/pwm/pwm-lpss.h |  1 +
> >  2 files changed, 28 insertions(+), 21 deletions(-)
> 
> Applied all three patches, with a minor cleanup, see below.
> 
> > diff --git a/drivers/pwm/pwm-lpss.h b/drivers/pwm/pwm-lpss.h
> > index aa041bb1b67d..ef2419f47c57 100644
> > --- a/drivers/pwm/pwm-lpss.h
> > +++ b/drivers/pwm/pwm-lpss.h
> > @@ -20,6 +20,7 @@ struct pwm_lpss_chip;
> >  
> >  struct pwm_lpss_boardinfo {
> >  	unsigned long clk_rate;
> > +	size_t npwm;
> >  };
> 
> I changed the type of npwm to unsigned int to match the definition of
> the pwm_chip.npwm field.

Thanks!
--
To unsubscribe from this list: send the line "unsubscribe linux-pwm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/pwm/pwm-lpss.c b/drivers/pwm/pwm-lpss.c
index e9798253a16f..e7392bdfdd18 100644
--- a/drivers/pwm/pwm-lpss.c
+++ b/drivers/pwm/pwm-lpss.c
@@ -29,6 +29,9 @@ 
 #define PWM_LIMIT			(0x8000 + PWM_DIVISION_CORRECTION)
 #define NSECS_PER_SEC			1000000000UL
 
+/* Size of each PWM register space if multiple */
+#define PWM_SIZE			0x400
+
 struct pwm_lpss_chip {
 	struct pwm_chip chip;
 	void __iomem *regs;
@@ -37,13 +40,15 @@  struct pwm_lpss_chip {
 
 /* BayTrail */
 const struct pwm_lpss_boardinfo pwm_lpss_byt_info = {
-	.clk_rate = 25000000
+	.clk_rate = 25000000,
+	.npwm = 1,
 };
 EXPORT_SYMBOL_GPL(pwm_lpss_byt_info);
 
 /* Braswell */
 const struct pwm_lpss_boardinfo pwm_lpss_bsw_info = {
-	.clk_rate = 19200000
+	.clk_rate = 19200000,
+	.npwm = 1,
 };
 EXPORT_SYMBOL_GPL(pwm_lpss_bsw_info);
 
@@ -52,6 +57,20 @@  static inline struct pwm_lpss_chip *to_lpwm(struct pwm_chip *chip)
 	return container_of(chip, struct pwm_lpss_chip, chip);
 }
 
+static inline u32 pwm_lpss_read(const struct pwm_device *pwm)
+{
+	struct pwm_lpss_chip *lpwm = to_lpwm(pwm->chip);
+
+	return readl(lpwm->regs + pwm->hwpwm * PWM_SIZE + PWM);
+}
+
+static inline void pwm_lpss_write(const struct pwm_device *pwm, u32 value)
+{
+	struct pwm_lpss_chip *lpwm = to_lpwm(pwm->chip);
+
+	writel(value, lpwm->regs + pwm->hwpwm * PWM_SIZE + PWM);
+}
+
 static int pwm_lpss_config(struct pwm_chip *chip, struct pwm_device *pwm,
 			   int duty_ns, int period_ns)
 {
@@ -79,38 +98,30 @@  static int pwm_lpss_config(struct pwm_chip *chip, struct pwm_device *pwm,
 		duty_ns = 1;
 	on_time_div = 255 - (255 * duty_ns / period_ns);
 
-	ctrl = readl(lpwm->regs + PWM);
+	ctrl = pwm_lpss_read(pwm);
 	ctrl &= ~(PWM_BASE_UNIT_MASK | PWM_ON_TIME_DIV_MASK);
 	ctrl |= (u16) base_unit << PWM_BASE_UNIT_SHIFT;
 	ctrl |= on_time_div;
 	/* request PWM to update on next cycle */
 	ctrl |= PWM_SW_UPDATE;
-	writel(ctrl, lpwm->regs + PWM);
+	pwm_lpss_write(pwm, ctrl);
 
 	return 0;
 }
 
 static int pwm_lpss_enable(struct pwm_chip *chip, struct pwm_device *pwm)
 {
-	struct pwm_lpss_chip *lpwm = to_lpwm(chip);
-	u32 ctrl;
-
-	ctrl = readl(lpwm->regs + PWM);
-	writel(ctrl | PWM_ENABLE, lpwm->regs + PWM);
-
+	pwm_lpss_write(pwm, pwm_lpss_read(pwm) | PWM_ENABLE);
 	return 0;
 }
 
 static void pwm_lpss_disable(struct pwm_chip *chip, struct pwm_device *pwm)
 {
-	struct pwm_lpss_chip *lpwm = to_lpwm(chip);
-	u32 ctrl;
-
-	ctrl = readl(lpwm->regs + PWM);
-	writel(ctrl & ~PWM_ENABLE, lpwm->regs + PWM);
+	pwm_lpss_write(pwm, pwm_lpss_read(pwm) & ~PWM_ENABLE);
 }
 
 static const struct pwm_ops pwm_lpss_ops = {
+	.free = pwm_lpss_disable,
 	.config = pwm_lpss_config,
 	.enable = pwm_lpss_enable,
 	.disable = pwm_lpss_disable,
@@ -135,7 +146,7 @@  struct pwm_lpss_chip *pwm_lpss_probe(struct device *dev, struct resource *r,
 	lpwm->chip.dev = dev;
 	lpwm->chip.ops = &pwm_lpss_ops;
 	lpwm->chip.base = -1;
-	lpwm->chip.npwm = 1;
+	lpwm->chip.npwm = info->npwm;
 
 	ret = pwmchip_add(&lpwm->chip);
 	if (ret) {
@@ -149,11 +160,6 @@  EXPORT_SYMBOL_GPL(pwm_lpss_probe);
 
 int pwm_lpss_remove(struct pwm_lpss_chip *lpwm)
 {
-	u32 ctrl;
-
-	ctrl = readl(lpwm->regs + PWM);
-	writel(ctrl & ~PWM_ENABLE, lpwm->regs + PWM);
-
 	return pwmchip_remove(&lpwm->chip);
 }
 EXPORT_SYMBOL_GPL(pwm_lpss_remove);
diff --git a/drivers/pwm/pwm-lpss.h b/drivers/pwm/pwm-lpss.h
index aa041bb1b67d..ef2419f47c57 100644
--- a/drivers/pwm/pwm-lpss.h
+++ b/drivers/pwm/pwm-lpss.h
@@ -20,6 +20,7 @@  struct pwm_lpss_chip;
 
 struct pwm_lpss_boardinfo {
 	unsigned long clk_rate;
+	size_t npwm;
 };
 
 extern const struct pwm_lpss_boardinfo pwm_lpss_byt_info;