All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/4] Add the Allwinner A31/A31s PWM driver
@ 2017-02-07 17:50 ` lis8215-Re5JQEeQqe8AvxtiuMwx3w
  0 siblings, 0 replies; 26+ messages in thread
From: lis8215 @ 2017-02-07 17:50 UTC (permalink / raw)
  To: linux-sunxi
  Cc: thierry.reding, robh+dt, mark.rutland, maxime.ripard, wens,
	linux-pwm, devicetree, linux-arm-kernel, linux-kernel,
	Siarhei Volkau

From: Siarhei Volkau <lis8215@gmail.com>

First of all im sorry for accidentally sent old patch,
please ignore them.

This is the second version of the sun6i PWM patchset.
 - added missing documentation changes
 - dts changes in separate patch

Thanks to Julian Calaby for tips.

--------------------------
This series of patches introduces support for Allwinner A31 PWM, which
is significantly differ from PWM founded in other Allwinner SoCs.
Patches 1/4 and 2/4 refactors existing code for easier A31 PWM integration.
Patch 3/4 adds support for A31 PWM on top of existing Allwinner PWM driver.
Patch 4/4 adds the PWM block to A31/A31s device tree.

Siarhei Volkau (4):
  ARM: pwm: sun4i: unification of register operations for support sun6i.
  ARM: pwm: sun4i: selectable prescaler table for support sun6i.
  ARM: pwm: sun6i: add support the Allwinner A31 PWM.
  ARM: dts: sun6i: Add the PWM block to the A31/A31s.

 .../devicetree/bindings/pwm/pwm-sun4i.txt          |   3 +-
 arch/arm/boot/dts/sun6i-a31.dtsi                   |   8 +
 drivers/pwm/pwm-sun4i.c                            | 193 ++++++++++++++++++---
 3 files changed, 176 insertions(+), 28 deletions(-)

-- 
2.4.11

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH v2 0/4] Add the Allwinner A31/A31s PWM driver
@ 2017-02-07 17:50 ` lis8215-Re5JQEeQqe8AvxtiuMwx3w
  0 siblings, 0 replies; 26+ messages in thread
From: lis8215-Re5JQEeQqe8AvxtiuMwx3w @ 2017-02-07 17:50 UTC (permalink / raw)
  To: linux-sunxi-/JYPxA39Uh5TLH3MbocFFw
  Cc: thierry.reding-Re5JQEeQqe8AvxtiuMwx3w,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
	maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8, wens-jdAy2FN1RRM,
	linux-pwm-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Siarhei Volkau

From: Siarhei Volkau <lis8215-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

First of all im sorry for accidentally sent old patch,
please ignore them.

This is the second version of the sun6i PWM patchset.
 - added missing documentation changes
 - dts changes in separate patch

Thanks to Julian Calaby for tips.

--------------------------
This series of patches introduces support for Allwinner A31 PWM, which
is significantly differ from PWM founded in other Allwinner SoCs.
Patches 1/4 and 2/4 refactors existing code for easier A31 PWM integration.
Patch 3/4 adds support for A31 PWM on top of existing Allwinner PWM driver.
Patch 4/4 adds the PWM block to A31/A31s device tree.

Siarhei Volkau (4):
  ARM: pwm: sun4i: unification of register operations for support sun6i.
  ARM: pwm: sun4i: selectable prescaler table for support sun6i.
  ARM: pwm: sun6i: add support the Allwinner A31 PWM.
  ARM: dts: sun6i: Add the PWM block to the A31/A31s.

 .../devicetree/bindings/pwm/pwm-sun4i.txt          |   3 +-
 arch/arm/boot/dts/sun6i-a31.dtsi                   |   8 +
 drivers/pwm/pwm-sun4i.c                            | 193 ++++++++++++++++++---
 3 files changed, 176 insertions(+), 28 deletions(-)

-- 
2.4.11

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH v2 0/4] Add the Allwinner A31/A31s PWM driver
@ 2017-02-07 17:50 ` lis8215-Re5JQEeQqe8AvxtiuMwx3w
  0 siblings, 0 replies; 26+ messages in thread
From: lis8215 at gmail.com @ 2017-02-07 17:50 UTC (permalink / raw)
  To: linux-arm-kernel

From: Siarhei Volkau <lis8215@gmail.com>

First of all im sorry for accidentally sent old patch,
please ignore them.

This is the second version of the sun6i PWM patchset.
 - added missing documentation changes
 - dts changes in separate patch

Thanks to Julian Calaby for tips.

--------------------------
This series of patches introduces support for Allwinner A31 PWM, which
is significantly differ from PWM founded in other Allwinner SoCs.
Patches 1/4 and 2/4 refactors existing code for easier A31 PWM integration.
Patch 3/4 adds support for A31 PWM on top of existing Allwinner PWM driver.
Patch 4/4 adds the PWM block to A31/A31s device tree.

Siarhei Volkau (4):
  ARM: pwm: sun4i: unification of register operations for support sun6i.
  ARM: pwm: sun4i: selectable prescaler table for support sun6i.
  ARM: pwm: sun6i: add support the Allwinner A31 PWM.
  ARM: dts: sun6i: Add the PWM block to the A31/A31s.

 .../devicetree/bindings/pwm/pwm-sun4i.txt          |   3 +-
 arch/arm/boot/dts/sun6i-a31.dtsi                   |   8 +
 drivers/pwm/pwm-sun4i.c                            | 193 ++++++++++++++++++---
 3 files changed, 176 insertions(+), 28 deletions(-)

-- 
2.4.11

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH v2 1/4] ARM: pwm: sun4i: unification of register operations for support sun6i.
@ 2017-02-07 17:50   ` lis8215-Re5JQEeQqe8AvxtiuMwx3w
  0 siblings, 0 replies; 26+ messages in thread
From: lis8215 @ 2017-02-07 17:50 UTC (permalink / raw)
  To: linux-sunxi
  Cc: thierry.reding, robh+dt, mark.rutland, maxime.ripard, wens,
	linux-pwm, devicetree, linux-arm-kernel, linux-kernel,
	Siarhei Volkau

From: Siarhei Volkau <lis8215@gmail.com>

This patch not introduce new features, just prepare code for
adding sun6i PWM driver in next commits.

A31 SoC have a different map of PWM registers than others ASoCs,
but register bits purposes are very similar.

This patch introduce set of register access routines, which
are common for existing in driver ASoCs:
 - ctl_rdy   - checks the ready bit of specified PWM channel,
 - ctl_read  - reads value from control register of specified PWM channel,
 - ctl_write - writes significant bits to control register of specified PWM channel,
 - prd_read  - reads value from period register of specified PWM channel,
 - prd_write - writes value to period register of specified PWM channel.
Driver code redesigned to use the new routines.

Signed-off-by: Siarhei Volkau <lis8215@gmail.com>
---
 drivers/pwm/pwm-sun4i.c | 113 +++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 87 insertions(+), 26 deletions(-)

diff --git a/drivers/pwm/pwm-sun4i.c b/drivers/pwm/pwm-sun4i.c
index b0803f6..04ad3b4 100644
--- a/drivers/pwm/pwm-sun4i.c
+++ b/drivers/pwm/pwm-sun4i.c
@@ -34,6 +34,7 @@
 #define PWM_MODE		BIT(7)
 #define PWM_PULSE		BIT(8)
 #define PWM_BYPASS		BIT(9)
+#define PWM_CHCTL_MASK		GENMASK(9, 0)
 
 #define PWM_RDY_BASE		28
 #define PWM_RDY_OFFSET		1
@@ -46,6 +47,8 @@
 
 #define BIT_CH(bit, chan)	((bit) << ((chan) * PWMCH_OFFSET))
 
+struct sun4i_pwm_chip;
+
 static const u32 prescaler_table[] = {
 	120,
 	180,
@@ -65,10 +68,19 @@ static const u32 prescaler_table[] = {
 	0, /* Actually 1 but tested separately */
 };
 
+struct sunxi_reg_ops {
+	int (*ctl_rdy)(struct sun4i_pwm_chip *chip, int npwm);
+	u32 (*ctl_read)(struct sun4i_pwm_chip *chip, int npwm);
+	void (*ctl_write)(struct sun4i_pwm_chip *chip, int npwm, u32 val);
+	u32 (*prd_read)(struct sun4i_pwm_chip *chip, int npwm);
+	void (*prd_write)(struct sun4i_pwm_chip *chip, int npwm, u32 val);
+};
+
 struct sun4i_pwm_data {
 	bool has_prescaler_bypass;
 	bool has_rdy;
 	unsigned int npwm;
+	const struct sunxi_reg_ops *ops;
 };
 
 struct sun4i_pwm_chip {
@@ -96,10 +108,42 @@ static inline void sun4i_pwm_writel(struct sun4i_pwm_chip *chip,
 	writel(val, chip->base + offset);
 }
 
+static int sun4i_reg_ctl_rdy(struct sun4i_pwm_chip *chip, int npwm)
+{
+	return PWM_RDY(npwm) & sun4i_pwm_readl(chip, PWM_CTRL_REG);
+}
+
+static u32 sun4i_reg_ctl_read(struct sun4i_pwm_chip *chip, int npwm)
+{
+	u32 val = sun4i_pwm_readl(chip, PWM_CTRL_REG);
+
+	return val >> (PWMCH_OFFSET * (npwm));
+}
+
+static void sun4i_reg_ctl_write(struct sun4i_pwm_chip *chip, int npwm, u32 val)
+{
+	u32 rd = sun4i_pwm_readl(chip, PWM_CTRL_REG);
+
+	rd &= ~(PWM_CHCTL_MASK << (PWMCH_OFFSET * npwm));
+	val &= (PWM_CHCTL_MASK << (PWMCH_OFFSET * npwm));
+	sun4i_pwm_writel(chip, rd | val, PWM_CTRL_REG);
+}
+
+static u32 sun4i_reg_prd_read(struct sun4i_pwm_chip *chip, int npwm)
+{
+	return sun4i_pwm_readl(chip, PWM_CH_PRD(npwm));
+}
+
+static void sun4i_reg_prd_write(struct sun4i_pwm_chip *chip, int npwm, u32 val)
+{
+	sun4i_pwm_writel(chip, val, PWM_CH_PRD(npwm));
+}
+
 static int sun4i_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
 			    int duty_ns, int period_ns)
 {
 	struct sun4i_pwm_chip *sun4i_pwm = to_sun4i_pwm_chip(chip);
+	const struct sunxi_reg_ops *reg_ops = sun4i_pwm->data->ops;
 	u32 prd, dty, val, clk_gate;
 	u64 clk_rate, div = 0;
 	unsigned int prescaler = 0;
@@ -152,32 +196,31 @@ static int sun4i_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
 	}
 
 	spin_lock(&sun4i_pwm->ctrl_lock);
-	val = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG);
 
-	if (sun4i_pwm->data->has_rdy && (val & PWM_RDY(pwm->hwpwm))) {
+	if (sun4i_pwm->data->has_rdy &&
+	    reg_ops->ctl_rdy(sun4i_pwm, pwm->hwpwm)) {
 		spin_unlock(&sun4i_pwm->ctrl_lock);
 		clk_disable_unprepare(sun4i_pwm->clk);
 		return -EBUSY;
 	}
 
-	clk_gate = val & BIT_CH(PWM_CLK_GATING, pwm->hwpwm);
+	val = reg_ops->ctl_read(sun4i_pwm, pwm->hwpwm);
+	clk_gate = val & PWM_CLK_GATING;
 	if (clk_gate) {
-		val &= ~BIT_CH(PWM_CLK_GATING, pwm->hwpwm);
-		sun4i_pwm_writel(sun4i_pwm, val, PWM_CTRL_REG);
+		val &= ~PWM_CLK_GATING;
+		reg_ops->ctl_write(sun4i_pwm, pwm->hwpwm, val);
 	}
 
-	val = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG);
 	val &= ~BIT_CH(PWM_PRESCAL_MASK, pwm->hwpwm);
 	val |= BIT_CH(prescaler, pwm->hwpwm);
-	sun4i_pwm_writel(sun4i_pwm, val, PWM_CTRL_REG);
+	reg_ops->ctl_write(sun4i_pwm, pwm->hwpwm, val);
 
-	val = (dty & PWM_DTY_MASK) | PWM_PRD(prd);
-	sun4i_pwm_writel(sun4i_pwm, val, PWM_CH_PRD(pwm->hwpwm));
+	reg_ops->prd_write(sun4i_pwm, pwm->hwpwm,
+			   (dty & PWM_DTY_MASK) | PWM_PRD(prd));
 
 	if (clk_gate) {
-		val = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG);
 		val |= clk_gate;
-		sun4i_pwm_writel(sun4i_pwm, val, PWM_CTRL_REG);
+		reg_ops->ctl_write(sun4i_pwm, pwm->hwpwm, val);
 	}
 
 	spin_unlock(&sun4i_pwm->ctrl_lock);
@@ -190,6 +233,7 @@ static int sun4i_pwm_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm,
 				  enum pwm_polarity polarity)
 {
 	struct sun4i_pwm_chip *sun4i_pwm = to_sun4i_pwm_chip(chip);
+	const struct sunxi_reg_ops *reg_ops = sun4i_pwm->data->ops;
 	u32 val;
 	int ret;
 
@@ -200,14 +244,14 @@ static int sun4i_pwm_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm,
 	}
 
 	spin_lock(&sun4i_pwm->ctrl_lock);
-	val = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG);
+	val = reg_ops->ctl_read(sun4i_pwm, pwm->hwpwm);
 
 	if (polarity != PWM_POLARITY_NORMAL)
-		val &= ~BIT_CH(PWM_ACT_STATE, pwm->hwpwm);
+		val &= ~PWM_ACT_STATE;
 	else
-		val |= BIT_CH(PWM_ACT_STATE, pwm->hwpwm);
+		val |= PWM_ACT_STATE;
 
-	sun4i_pwm_writel(sun4i_pwm, val, PWM_CTRL_REG);
+	reg_ops->ctl_write(sun4i_pwm, pwm->hwpwm, val);
 
 	spin_unlock(&sun4i_pwm->ctrl_lock);
 	clk_disable_unprepare(sun4i_pwm->clk);
@@ -218,6 +262,7 @@ static int sun4i_pwm_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm,
 static int sun4i_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
 {
 	struct sun4i_pwm_chip *sun4i_pwm = to_sun4i_pwm_chip(chip);
+	const struct sunxi_reg_ops *reg_ops = sun4i_pwm->data->ops;
 	u32 val;
 	int ret;
 
@@ -228,10 +273,9 @@ static int sun4i_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
 	}
 
 	spin_lock(&sun4i_pwm->ctrl_lock);
-	val = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG);
-	val |= BIT_CH(PWM_EN, pwm->hwpwm);
-	val |= BIT_CH(PWM_CLK_GATING, pwm->hwpwm);
-	sun4i_pwm_writel(sun4i_pwm, val, PWM_CTRL_REG);
+	val = reg_ops->ctl_rdy(sun4i_pwm, pwm->hwpwm);
+	val |= PWM_EN | PWM_CLK_GATING;
+	reg_ops->ctl_write(sun4i_pwm, pwm->hwpwm, val);
 	spin_unlock(&sun4i_pwm->ctrl_lock);
 
 	return 0;
@@ -240,18 +284,26 @@ static int sun4i_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
 static void sun4i_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
 {
 	struct sun4i_pwm_chip *sun4i_pwm = to_sun4i_pwm_chip(chip);
+	const struct sunxi_reg_ops *reg_ops = sun4i_pwm->data->ops;
 	u32 val;
 
 	spin_lock(&sun4i_pwm->ctrl_lock);
-	val = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG);
-	val &= ~BIT_CH(PWM_EN, pwm->hwpwm);
-	val &= ~BIT_CH(PWM_CLK_GATING, pwm->hwpwm);
-	sun4i_pwm_writel(sun4i_pwm, val, PWM_CTRL_REG);
+	val = reg_ops->ctl_rdy(sun4i_pwm, pwm->hwpwm);
+	val &= ~(PWM_EN | PWM_CLK_GATING);
+	reg_ops->ctl_write(sun4i_pwm, pwm->hwpwm, val);
 	spin_unlock(&sun4i_pwm->ctrl_lock);
 
 	clk_disable_unprepare(sun4i_pwm->clk);
 }
 
+static const struct sunxi_reg_ops sun4i_reg_ops = {
+	.ctl_rdy   = sun4i_reg_ctl_rdy,
+	.ctl_read  = sun4i_reg_ctl_read,
+	.ctl_write = sun4i_reg_ctl_write,
+	.prd_read  = sun4i_reg_prd_read,
+	.prd_write = sun4i_reg_prd_write,
+};
+
 static const struct pwm_ops sun4i_pwm_ops = {
 	.config = sun4i_pwm_config,
 	.set_polarity = sun4i_pwm_set_polarity,
@@ -264,30 +316,35 @@ static const struct sun4i_pwm_data sun4i_pwm_data_a10 = {
 	.has_prescaler_bypass = false,
 	.has_rdy = false,
 	.npwm = 2,
+	.ops = &sun4i_reg_ops,
 };
 
 static const struct sun4i_pwm_data sun4i_pwm_data_a10s = {
 	.has_prescaler_bypass = true,
 	.has_rdy = true,
 	.npwm = 2,
+	.ops = &sun4i_reg_ops,
 };
 
 static const struct sun4i_pwm_data sun4i_pwm_data_a13 = {
 	.has_prescaler_bypass = true,
 	.has_rdy = true,
 	.npwm = 1,
+	.ops = &sun4i_reg_ops,
 };
 
 static const struct sun4i_pwm_data sun4i_pwm_data_a20 = {
 	.has_prescaler_bypass = true,
 	.has_rdy = true,
 	.npwm = 2,
+	.ops = &sun4i_reg_ops,
 };
 
 static const struct sun4i_pwm_data sun4i_pwm_data_h3 = {
 	.has_prescaler_bypass = true,
 	.has_rdy = true,
 	.npwm = 1,
+	.ops = &sun4i_reg_ops,
 };
 
 static const struct of_device_id sun4i_pwm_dt_ids[] = {
@@ -319,6 +376,7 @@ static int sun4i_pwm_probe(struct platform_device *pdev)
 	u32 val;
 	int i, ret;
 	const struct of_device_id *match;
+	const struct sunxi_reg_ops *reg_ops;
 
 	match = of_match_device(sun4i_pwm_dt_ids, &pdev->dev);
 
@@ -360,11 +418,14 @@ static int sun4i_pwm_probe(struct platform_device *pdev)
 		goto clk_error;
 	}
 
-	val = sun4i_pwm_readl(pwm, PWM_CTRL_REG);
-	for (i = 0; i < pwm->chip.npwm; i++)
-		if (!(val & BIT_CH(PWM_ACT_STATE, i)))
+	reg_ops = pwm->data->ops;
+
+	for (i = 0; i < pwm->chip.npwm; i++) {
+		val = reg_ops->ctl_read(pwm, i);
+		if (!(val & PWM_ACT_STATE))
 			pwm_set_polarity(&pwm->chip.pwms[i],
 					 PWM_POLARITY_INVERSED);
+	}
 	clk_disable_unprepare(pwm->clk);
 
 	return 0;
-- 
2.4.11

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 1/4] ARM: pwm: sun4i: unification of register operations for support sun6i.
@ 2017-02-07 17:50   ` lis8215-Re5JQEeQqe8AvxtiuMwx3w
  0 siblings, 0 replies; 26+ messages in thread
From: lis8215-Re5JQEeQqe8AvxtiuMwx3w @ 2017-02-07 17:50 UTC (permalink / raw)
  To: linux-sunxi-/JYPxA39Uh5TLH3MbocFFw
  Cc: thierry.reding-Re5JQEeQqe8AvxtiuMwx3w,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
	maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8, wens-jdAy2FN1RRM,
	linux-pwm-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Siarhei Volkau

From: Siarhei Volkau <lis8215-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

This patch not introduce new features, just prepare code for
adding sun6i PWM driver in next commits.

A31 SoC have a different map of PWM registers than others ASoCs,
but register bits purposes are very similar.

This patch introduce set of register access routines, which
are common for existing in driver ASoCs:
 - ctl_rdy   - checks the ready bit of specified PWM channel,
 - ctl_read  - reads value from control register of specified PWM channel,
 - ctl_write - writes significant bits to control register of specified PWM channel,
 - prd_read  - reads value from period register of specified PWM channel,
 - prd_write - writes value to period register of specified PWM channel.
Driver code redesigned to use the new routines.

Signed-off-by: Siarhei Volkau <lis8215-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 drivers/pwm/pwm-sun4i.c | 113 +++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 87 insertions(+), 26 deletions(-)

diff --git a/drivers/pwm/pwm-sun4i.c b/drivers/pwm/pwm-sun4i.c
index b0803f6..04ad3b4 100644
--- a/drivers/pwm/pwm-sun4i.c
+++ b/drivers/pwm/pwm-sun4i.c
@@ -34,6 +34,7 @@
 #define PWM_MODE		BIT(7)
 #define PWM_PULSE		BIT(8)
 #define PWM_BYPASS		BIT(9)
+#define PWM_CHCTL_MASK		GENMASK(9, 0)
 
 #define PWM_RDY_BASE		28
 #define PWM_RDY_OFFSET		1
@@ -46,6 +47,8 @@
 
 #define BIT_CH(bit, chan)	((bit) << ((chan) * PWMCH_OFFSET))
 
+struct sun4i_pwm_chip;
+
 static const u32 prescaler_table[] = {
 	120,
 	180,
@@ -65,10 +68,19 @@ static const u32 prescaler_table[] = {
 	0, /* Actually 1 but tested separately */
 };
 
+struct sunxi_reg_ops {
+	int (*ctl_rdy)(struct sun4i_pwm_chip *chip, int npwm);
+	u32 (*ctl_read)(struct sun4i_pwm_chip *chip, int npwm);
+	void (*ctl_write)(struct sun4i_pwm_chip *chip, int npwm, u32 val);
+	u32 (*prd_read)(struct sun4i_pwm_chip *chip, int npwm);
+	void (*prd_write)(struct sun4i_pwm_chip *chip, int npwm, u32 val);
+};
+
 struct sun4i_pwm_data {
 	bool has_prescaler_bypass;
 	bool has_rdy;
 	unsigned int npwm;
+	const struct sunxi_reg_ops *ops;
 };
 
 struct sun4i_pwm_chip {
@@ -96,10 +108,42 @@ static inline void sun4i_pwm_writel(struct sun4i_pwm_chip *chip,
 	writel(val, chip->base + offset);
 }
 
+static int sun4i_reg_ctl_rdy(struct sun4i_pwm_chip *chip, int npwm)
+{
+	return PWM_RDY(npwm) & sun4i_pwm_readl(chip, PWM_CTRL_REG);
+}
+
+static u32 sun4i_reg_ctl_read(struct sun4i_pwm_chip *chip, int npwm)
+{
+	u32 val = sun4i_pwm_readl(chip, PWM_CTRL_REG);
+
+	return val >> (PWMCH_OFFSET * (npwm));
+}
+
+static void sun4i_reg_ctl_write(struct sun4i_pwm_chip *chip, int npwm, u32 val)
+{
+	u32 rd = sun4i_pwm_readl(chip, PWM_CTRL_REG);
+
+	rd &= ~(PWM_CHCTL_MASK << (PWMCH_OFFSET * npwm));
+	val &= (PWM_CHCTL_MASK << (PWMCH_OFFSET * npwm));
+	sun4i_pwm_writel(chip, rd | val, PWM_CTRL_REG);
+}
+
+static u32 sun4i_reg_prd_read(struct sun4i_pwm_chip *chip, int npwm)
+{
+	return sun4i_pwm_readl(chip, PWM_CH_PRD(npwm));
+}
+
+static void sun4i_reg_prd_write(struct sun4i_pwm_chip *chip, int npwm, u32 val)
+{
+	sun4i_pwm_writel(chip, val, PWM_CH_PRD(npwm));
+}
+
 static int sun4i_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
 			    int duty_ns, int period_ns)
 {
 	struct sun4i_pwm_chip *sun4i_pwm = to_sun4i_pwm_chip(chip);
+	const struct sunxi_reg_ops *reg_ops = sun4i_pwm->data->ops;
 	u32 prd, dty, val, clk_gate;
 	u64 clk_rate, div = 0;
 	unsigned int prescaler = 0;
@@ -152,32 +196,31 @@ static int sun4i_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
 	}
 
 	spin_lock(&sun4i_pwm->ctrl_lock);
-	val = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG);
 
-	if (sun4i_pwm->data->has_rdy && (val & PWM_RDY(pwm->hwpwm))) {
+	if (sun4i_pwm->data->has_rdy &&
+	    reg_ops->ctl_rdy(sun4i_pwm, pwm->hwpwm)) {
 		spin_unlock(&sun4i_pwm->ctrl_lock);
 		clk_disable_unprepare(sun4i_pwm->clk);
 		return -EBUSY;
 	}
 
-	clk_gate = val & BIT_CH(PWM_CLK_GATING, pwm->hwpwm);
+	val = reg_ops->ctl_read(sun4i_pwm, pwm->hwpwm);
+	clk_gate = val & PWM_CLK_GATING;
 	if (clk_gate) {
-		val &= ~BIT_CH(PWM_CLK_GATING, pwm->hwpwm);
-		sun4i_pwm_writel(sun4i_pwm, val, PWM_CTRL_REG);
+		val &= ~PWM_CLK_GATING;
+		reg_ops->ctl_write(sun4i_pwm, pwm->hwpwm, val);
 	}
 
-	val = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG);
 	val &= ~BIT_CH(PWM_PRESCAL_MASK, pwm->hwpwm);
 	val |= BIT_CH(prescaler, pwm->hwpwm);
-	sun4i_pwm_writel(sun4i_pwm, val, PWM_CTRL_REG);
+	reg_ops->ctl_write(sun4i_pwm, pwm->hwpwm, val);
 
-	val = (dty & PWM_DTY_MASK) | PWM_PRD(prd);
-	sun4i_pwm_writel(sun4i_pwm, val, PWM_CH_PRD(pwm->hwpwm));
+	reg_ops->prd_write(sun4i_pwm, pwm->hwpwm,
+			   (dty & PWM_DTY_MASK) | PWM_PRD(prd));
 
 	if (clk_gate) {
-		val = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG);
 		val |= clk_gate;
-		sun4i_pwm_writel(sun4i_pwm, val, PWM_CTRL_REG);
+		reg_ops->ctl_write(sun4i_pwm, pwm->hwpwm, val);
 	}
 
 	spin_unlock(&sun4i_pwm->ctrl_lock);
@@ -190,6 +233,7 @@ static int sun4i_pwm_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm,
 				  enum pwm_polarity polarity)
 {
 	struct sun4i_pwm_chip *sun4i_pwm = to_sun4i_pwm_chip(chip);
+	const struct sunxi_reg_ops *reg_ops = sun4i_pwm->data->ops;
 	u32 val;
 	int ret;
 
@@ -200,14 +244,14 @@ static int sun4i_pwm_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm,
 	}
 
 	spin_lock(&sun4i_pwm->ctrl_lock);
-	val = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG);
+	val = reg_ops->ctl_read(sun4i_pwm, pwm->hwpwm);
 
 	if (polarity != PWM_POLARITY_NORMAL)
-		val &= ~BIT_CH(PWM_ACT_STATE, pwm->hwpwm);
+		val &= ~PWM_ACT_STATE;
 	else
-		val |= BIT_CH(PWM_ACT_STATE, pwm->hwpwm);
+		val |= PWM_ACT_STATE;
 
-	sun4i_pwm_writel(sun4i_pwm, val, PWM_CTRL_REG);
+	reg_ops->ctl_write(sun4i_pwm, pwm->hwpwm, val);
 
 	spin_unlock(&sun4i_pwm->ctrl_lock);
 	clk_disable_unprepare(sun4i_pwm->clk);
@@ -218,6 +262,7 @@ static int sun4i_pwm_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm,
 static int sun4i_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
 {
 	struct sun4i_pwm_chip *sun4i_pwm = to_sun4i_pwm_chip(chip);
+	const struct sunxi_reg_ops *reg_ops = sun4i_pwm->data->ops;
 	u32 val;
 	int ret;
 
@@ -228,10 +273,9 @@ static int sun4i_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
 	}
 
 	spin_lock(&sun4i_pwm->ctrl_lock);
-	val = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG);
-	val |= BIT_CH(PWM_EN, pwm->hwpwm);
-	val |= BIT_CH(PWM_CLK_GATING, pwm->hwpwm);
-	sun4i_pwm_writel(sun4i_pwm, val, PWM_CTRL_REG);
+	val = reg_ops->ctl_rdy(sun4i_pwm, pwm->hwpwm);
+	val |= PWM_EN | PWM_CLK_GATING;
+	reg_ops->ctl_write(sun4i_pwm, pwm->hwpwm, val);
 	spin_unlock(&sun4i_pwm->ctrl_lock);
 
 	return 0;
@@ -240,18 +284,26 @@ static int sun4i_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
 static void sun4i_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
 {
 	struct sun4i_pwm_chip *sun4i_pwm = to_sun4i_pwm_chip(chip);
+	const struct sunxi_reg_ops *reg_ops = sun4i_pwm->data->ops;
 	u32 val;
 
 	spin_lock(&sun4i_pwm->ctrl_lock);
-	val = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG);
-	val &= ~BIT_CH(PWM_EN, pwm->hwpwm);
-	val &= ~BIT_CH(PWM_CLK_GATING, pwm->hwpwm);
-	sun4i_pwm_writel(sun4i_pwm, val, PWM_CTRL_REG);
+	val = reg_ops->ctl_rdy(sun4i_pwm, pwm->hwpwm);
+	val &= ~(PWM_EN | PWM_CLK_GATING);
+	reg_ops->ctl_write(sun4i_pwm, pwm->hwpwm, val);
 	spin_unlock(&sun4i_pwm->ctrl_lock);
 
 	clk_disable_unprepare(sun4i_pwm->clk);
 }
 
+static const struct sunxi_reg_ops sun4i_reg_ops = {
+	.ctl_rdy   = sun4i_reg_ctl_rdy,
+	.ctl_read  = sun4i_reg_ctl_read,
+	.ctl_write = sun4i_reg_ctl_write,
+	.prd_read  = sun4i_reg_prd_read,
+	.prd_write = sun4i_reg_prd_write,
+};
+
 static const struct pwm_ops sun4i_pwm_ops = {
 	.config = sun4i_pwm_config,
 	.set_polarity = sun4i_pwm_set_polarity,
@@ -264,30 +316,35 @@ static const struct sun4i_pwm_data sun4i_pwm_data_a10 = {
 	.has_prescaler_bypass = false,
 	.has_rdy = false,
 	.npwm = 2,
+	.ops = &sun4i_reg_ops,
 };
 
 static const struct sun4i_pwm_data sun4i_pwm_data_a10s = {
 	.has_prescaler_bypass = true,
 	.has_rdy = true,
 	.npwm = 2,
+	.ops = &sun4i_reg_ops,
 };
 
 static const struct sun4i_pwm_data sun4i_pwm_data_a13 = {
 	.has_prescaler_bypass = true,
 	.has_rdy = true,
 	.npwm = 1,
+	.ops = &sun4i_reg_ops,
 };
 
 static const struct sun4i_pwm_data sun4i_pwm_data_a20 = {
 	.has_prescaler_bypass = true,
 	.has_rdy = true,
 	.npwm = 2,
+	.ops = &sun4i_reg_ops,
 };
 
 static const struct sun4i_pwm_data sun4i_pwm_data_h3 = {
 	.has_prescaler_bypass = true,
 	.has_rdy = true,
 	.npwm = 1,
+	.ops = &sun4i_reg_ops,
 };
 
 static const struct of_device_id sun4i_pwm_dt_ids[] = {
@@ -319,6 +376,7 @@ static int sun4i_pwm_probe(struct platform_device *pdev)
 	u32 val;
 	int i, ret;
 	const struct of_device_id *match;
+	const struct sunxi_reg_ops *reg_ops;
 
 	match = of_match_device(sun4i_pwm_dt_ids, &pdev->dev);
 
@@ -360,11 +418,14 @@ static int sun4i_pwm_probe(struct platform_device *pdev)
 		goto clk_error;
 	}
 
-	val = sun4i_pwm_readl(pwm, PWM_CTRL_REG);
-	for (i = 0; i < pwm->chip.npwm; i++)
-		if (!(val & BIT_CH(PWM_ACT_STATE, i)))
+	reg_ops = pwm->data->ops;
+
+	for (i = 0; i < pwm->chip.npwm; i++) {
+		val = reg_ops->ctl_read(pwm, i);
+		if (!(val & PWM_ACT_STATE))
 			pwm_set_polarity(&pwm->chip.pwms[i],
 					 PWM_POLARITY_INVERSED);
+	}
 	clk_disable_unprepare(pwm->clk);
 
 	return 0;
-- 
2.4.11

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 1/4] ARM: pwm: sun4i: unification of register operations for support sun6i.
@ 2017-02-07 17:50   ` lis8215-Re5JQEeQqe8AvxtiuMwx3w
  0 siblings, 0 replies; 26+ messages in thread
From: lis8215 at gmail.com @ 2017-02-07 17:50 UTC (permalink / raw)
  To: linux-arm-kernel

From: Siarhei Volkau <lis8215@gmail.com>

This patch not introduce new features, just prepare code for
adding sun6i PWM driver in next commits.

A31 SoC have a different map of PWM registers than others ASoCs,
but register bits purposes are very similar.

This patch introduce set of register access routines, which
are common for existing in driver ASoCs:
 - ctl_rdy   - checks the ready bit of specified PWM channel,
 - ctl_read  - reads value from control register of specified PWM channel,
 - ctl_write - writes significant bits to control register of specified PWM channel,
 - prd_read  - reads value from period register of specified PWM channel,
 - prd_write - writes value to period register of specified PWM channel.
Driver code redesigned to use the new routines.

Signed-off-by: Siarhei Volkau <lis8215@gmail.com>
---
 drivers/pwm/pwm-sun4i.c | 113 +++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 87 insertions(+), 26 deletions(-)

diff --git a/drivers/pwm/pwm-sun4i.c b/drivers/pwm/pwm-sun4i.c
index b0803f6..04ad3b4 100644
--- a/drivers/pwm/pwm-sun4i.c
+++ b/drivers/pwm/pwm-sun4i.c
@@ -34,6 +34,7 @@
 #define PWM_MODE		BIT(7)
 #define PWM_PULSE		BIT(8)
 #define PWM_BYPASS		BIT(9)
+#define PWM_CHCTL_MASK		GENMASK(9, 0)
 
 #define PWM_RDY_BASE		28
 #define PWM_RDY_OFFSET		1
@@ -46,6 +47,8 @@
 
 #define BIT_CH(bit, chan)	((bit) << ((chan) * PWMCH_OFFSET))
 
+struct sun4i_pwm_chip;
+
 static const u32 prescaler_table[] = {
 	120,
 	180,
@@ -65,10 +68,19 @@ static const u32 prescaler_table[] = {
 	0, /* Actually 1 but tested separately */
 };
 
+struct sunxi_reg_ops {
+	int (*ctl_rdy)(struct sun4i_pwm_chip *chip, int npwm);
+	u32 (*ctl_read)(struct sun4i_pwm_chip *chip, int npwm);
+	void (*ctl_write)(struct sun4i_pwm_chip *chip, int npwm, u32 val);
+	u32 (*prd_read)(struct sun4i_pwm_chip *chip, int npwm);
+	void (*prd_write)(struct sun4i_pwm_chip *chip, int npwm, u32 val);
+};
+
 struct sun4i_pwm_data {
 	bool has_prescaler_bypass;
 	bool has_rdy;
 	unsigned int npwm;
+	const struct sunxi_reg_ops *ops;
 };
 
 struct sun4i_pwm_chip {
@@ -96,10 +108,42 @@ static inline void sun4i_pwm_writel(struct sun4i_pwm_chip *chip,
 	writel(val, chip->base + offset);
 }
 
+static int sun4i_reg_ctl_rdy(struct sun4i_pwm_chip *chip, int npwm)
+{
+	return PWM_RDY(npwm) & sun4i_pwm_readl(chip, PWM_CTRL_REG);
+}
+
+static u32 sun4i_reg_ctl_read(struct sun4i_pwm_chip *chip, int npwm)
+{
+	u32 val = sun4i_pwm_readl(chip, PWM_CTRL_REG);
+
+	return val >> (PWMCH_OFFSET * (npwm));
+}
+
+static void sun4i_reg_ctl_write(struct sun4i_pwm_chip *chip, int npwm, u32 val)
+{
+	u32 rd = sun4i_pwm_readl(chip, PWM_CTRL_REG);
+
+	rd &= ~(PWM_CHCTL_MASK << (PWMCH_OFFSET * npwm));
+	val &= (PWM_CHCTL_MASK << (PWMCH_OFFSET * npwm));
+	sun4i_pwm_writel(chip, rd | val, PWM_CTRL_REG);
+}
+
+static u32 sun4i_reg_prd_read(struct sun4i_pwm_chip *chip, int npwm)
+{
+	return sun4i_pwm_readl(chip, PWM_CH_PRD(npwm));
+}
+
+static void sun4i_reg_prd_write(struct sun4i_pwm_chip *chip, int npwm, u32 val)
+{
+	sun4i_pwm_writel(chip, val, PWM_CH_PRD(npwm));
+}
+
 static int sun4i_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
 			    int duty_ns, int period_ns)
 {
 	struct sun4i_pwm_chip *sun4i_pwm = to_sun4i_pwm_chip(chip);
+	const struct sunxi_reg_ops *reg_ops = sun4i_pwm->data->ops;
 	u32 prd, dty, val, clk_gate;
 	u64 clk_rate, div = 0;
 	unsigned int prescaler = 0;
@@ -152,32 +196,31 @@ static int sun4i_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
 	}
 
 	spin_lock(&sun4i_pwm->ctrl_lock);
-	val = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG);
 
-	if (sun4i_pwm->data->has_rdy && (val & PWM_RDY(pwm->hwpwm))) {
+	if (sun4i_pwm->data->has_rdy &&
+	    reg_ops->ctl_rdy(sun4i_pwm, pwm->hwpwm)) {
 		spin_unlock(&sun4i_pwm->ctrl_lock);
 		clk_disable_unprepare(sun4i_pwm->clk);
 		return -EBUSY;
 	}
 
-	clk_gate = val & BIT_CH(PWM_CLK_GATING, pwm->hwpwm);
+	val = reg_ops->ctl_read(sun4i_pwm, pwm->hwpwm);
+	clk_gate = val & PWM_CLK_GATING;
 	if (clk_gate) {
-		val &= ~BIT_CH(PWM_CLK_GATING, pwm->hwpwm);
-		sun4i_pwm_writel(sun4i_pwm, val, PWM_CTRL_REG);
+		val &= ~PWM_CLK_GATING;
+		reg_ops->ctl_write(sun4i_pwm, pwm->hwpwm, val);
 	}
 
-	val = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG);
 	val &= ~BIT_CH(PWM_PRESCAL_MASK, pwm->hwpwm);
 	val |= BIT_CH(prescaler, pwm->hwpwm);
-	sun4i_pwm_writel(sun4i_pwm, val, PWM_CTRL_REG);
+	reg_ops->ctl_write(sun4i_pwm, pwm->hwpwm, val);
 
-	val = (dty & PWM_DTY_MASK) | PWM_PRD(prd);
-	sun4i_pwm_writel(sun4i_pwm, val, PWM_CH_PRD(pwm->hwpwm));
+	reg_ops->prd_write(sun4i_pwm, pwm->hwpwm,
+			   (dty & PWM_DTY_MASK) | PWM_PRD(prd));
 
 	if (clk_gate) {
-		val = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG);
 		val |= clk_gate;
-		sun4i_pwm_writel(sun4i_pwm, val, PWM_CTRL_REG);
+		reg_ops->ctl_write(sun4i_pwm, pwm->hwpwm, val);
 	}
 
 	spin_unlock(&sun4i_pwm->ctrl_lock);
@@ -190,6 +233,7 @@ static int sun4i_pwm_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm,
 				  enum pwm_polarity polarity)
 {
 	struct sun4i_pwm_chip *sun4i_pwm = to_sun4i_pwm_chip(chip);
+	const struct sunxi_reg_ops *reg_ops = sun4i_pwm->data->ops;
 	u32 val;
 	int ret;
 
@@ -200,14 +244,14 @@ static int sun4i_pwm_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm,
 	}
 
 	spin_lock(&sun4i_pwm->ctrl_lock);
-	val = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG);
+	val = reg_ops->ctl_read(sun4i_pwm, pwm->hwpwm);
 
 	if (polarity != PWM_POLARITY_NORMAL)
-		val &= ~BIT_CH(PWM_ACT_STATE, pwm->hwpwm);
+		val &= ~PWM_ACT_STATE;
 	else
-		val |= BIT_CH(PWM_ACT_STATE, pwm->hwpwm);
+		val |= PWM_ACT_STATE;
 
-	sun4i_pwm_writel(sun4i_pwm, val, PWM_CTRL_REG);
+	reg_ops->ctl_write(sun4i_pwm, pwm->hwpwm, val);
 
 	spin_unlock(&sun4i_pwm->ctrl_lock);
 	clk_disable_unprepare(sun4i_pwm->clk);
@@ -218,6 +262,7 @@ static int sun4i_pwm_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm,
 static int sun4i_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
 {
 	struct sun4i_pwm_chip *sun4i_pwm = to_sun4i_pwm_chip(chip);
+	const struct sunxi_reg_ops *reg_ops = sun4i_pwm->data->ops;
 	u32 val;
 	int ret;
 
@@ -228,10 +273,9 @@ static int sun4i_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
 	}
 
 	spin_lock(&sun4i_pwm->ctrl_lock);
-	val = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG);
-	val |= BIT_CH(PWM_EN, pwm->hwpwm);
-	val |= BIT_CH(PWM_CLK_GATING, pwm->hwpwm);
-	sun4i_pwm_writel(sun4i_pwm, val, PWM_CTRL_REG);
+	val = reg_ops->ctl_rdy(sun4i_pwm, pwm->hwpwm);
+	val |= PWM_EN | PWM_CLK_GATING;
+	reg_ops->ctl_write(sun4i_pwm, pwm->hwpwm, val);
 	spin_unlock(&sun4i_pwm->ctrl_lock);
 
 	return 0;
@@ -240,18 +284,26 @@ static int sun4i_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
 static void sun4i_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
 {
 	struct sun4i_pwm_chip *sun4i_pwm = to_sun4i_pwm_chip(chip);
+	const struct sunxi_reg_ops *reg_ops = sun4i_pwm->data->ops;
 	u32 val;
 
 	spin_lock(&sun4i_pwm->ctrl_lock);
-	val = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG);
-	val &= ~BIT_CH(PWM_EN, pwm->hwpwm);
-	val &= ~BIT_CH(PWM_CLK_GATING, pwm->hwpwm);
-	sun4i_pwm_writel(sun4i_pwm, val, PWM_CTRL_REG);
+	val = reg_ops->ctl_rdy(sun4i_pwm, pwm->hwpwm);
+	val &= ~(PWM_EN | PWM_CLK_GATING);
+	reg_ops->ctl_write(sun4i_pwm, pwm->hwpwm, val);
 	spin_unlock(&sun4i_pwm->ctrl_lock);
 
 	clk_disable_unprepare(sun4i_pwm->clk);
 }
 
+static const struct sunxi_reg_ops sun4i_reg_ops = {
+	.ctl_rdy   = sun4i_reg_ctl_rdy,
+	.ctl_read  = sun4i_reg_ctl_read,
+	.ctl_write = sun4i_reg_ctl_write,
+	.prd_read  = sun4i_reg_prd_read,
+	.prd_write = sun4i_reg_prd_write,
+};
+
 static const struct pwm_ops sun4i_pwm_ops = {
 	.config = sun4i_pwm_config,
 	.set_polarity = sun4i_pwm_set_polarity,
@@ -264,30 +316,35 @@ static const struct sun4i_pwm_data sun4i_pwm_data_a10 = {
 	.has_prescaler_bypass = false,
 	.has_rdy = false,
 	.npwm = 2,
+	.ops = &sun4i_reg_ops,
 };
 
 static const struct sun4i_pwm_data sun4i_pwm_data_a10s = {
 	.has_prescaler_bypass = true,
 	.has_rdy = true,
 	.npwm = 2,
+	.ops = &sun4i_reg_ops,
 };
 
 static const struct sun4i_pwm_data sun4i_pwm_data_a13 = {
 	.has_prescaler_bypass = true,
 	.has_rdy = true,
 	.npwm = 1,
+	.ops = &sun4i_reg_ops,
 };
 
 static const struct sun4i_pwm_data sun4i_pwm_data_a20 = {
 	.has_prescaler_bypass = true,
 	.has_rdy = true,
 	.npwm = 2,
+	.ops = &sun4i_reg_ops,
 };
 
 static const struct sun4i_pwm_data sun4i_pwm_data_h3 = {
 	.has_prescaler_bypass = true,
 	.has_rdy = true,
 	.npwm = 1,
+	.ops = &sun4i_reg_ops,
 };
 
 static const struct of_device_id sun4i_pwm_dt_ids[] = {
@@ -319,6 +376,7 @@ static int sun4i_pwm_probe(struct platform_device *pdev)
 	u32 val;
 	int i, ret;
 	const struct of_device_id *match;
+	const struct sunxi_reg_ops *reg_ops;
 
 	match = of_match_device(sun4i_pwm_dt_ids, &pdev->dev);
 
@@ -360,11 +418,14 @@ static int sun4i_pwm_probe(struct platform_device *pdev)
 		goto clk_error;
 	}
 
-	val = sun4i_pwm_readl(pwm, PWM_CTRL_REG);
-	for (i = 0; i < pwm->chip.npwm; i++)
-		if (!(val & BIT_CH(PWM_ACT_STATE, i)))
+	reg_ops = pwm->data->ops;
+
+	for (i = 0; i < pwm->chip.npwm; i++) {
+		val = reg_ops->ctl_read(pwm, i);
+		if (!(val & PWM_ACT_STATE))
 			pwm_set_polarity(&pwm->chip.pwms[i],
 					 PWM_POLARITY_INVERSED);
+	}
 	clk_disable_unprepare(pwm->clk);
 
 	return 0;
-- 
2.4.11

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 2/4] ARM: pwm: sun4i: selectable prescaler table for support sun6i.
  2017-02-07 17:50 ` lis8215-Re5JQEeQqe8AvxtiuMwx3w
@ 2017-02-07 17:50   ` lis8215 at gmail.com
  -1 siblings, 0 replies; 26+ messages in thread
From: lis8215 @ 2017-02-07 17:50 UTC (permalink / raw)
  To: linux-sunxi
  Cc: thierry.reding, robh+dt, mark.rutland, maxime.ripard, wens,
	linux-pwm, devicetree, linux-arm-kernel, linux-kernel,
	Siarhei Volkau

From: Siarhei Volkau <lis8215@gmail.com>

This patch not introduce new features, just prepare code for
adding sun6i PWM driver in next commit.

A31 SoC have a different set of prescalers than others ASoCs, but
its position and count in the control register are the same.

This patch make the table of prescalers customizable.

Signed-off-by: Siarhei Volkau <lis8215@gmail.com>
---
 drivers/pwm/pwm-sun4i.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/pwm/pwm-sun4i.c b/drivers/pwm/pwm-sun4i.c
index 04ad3b4..39912fc 100644
--- a/drivers/pwm/pwm-sun4i.c
+++ b/drivers/pwm/pwm-sun4i.c
@@ -49,7 +49,7 @@
 
 struct sun4i_pwm_chip;
 
-static const u32 prescaler_table[] = {
+static const u32 sun4i_prescaler_table[] = {
 	120,
 	180,
 	240,
@@ -81,6 +81,7 @@ struct sun4i_pwm_data {
 	bool has_rdy;
 	unsigned int npwm;
 	const struct sunxi_reg_ops *ops;
+	const u32 *prescaler_table;
 };
 
 struct sun4i_pwm_chip {
@@ -144,6 +145,7 @@ static int sun4i_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
 {
 	struct sun4i_pwm_chip *sun4i_pwm = to_sun4i_pwm_chip(chip);
 	const struct sunxi_reg_ops *reg_ops = sun4i_pwm->data->ops;
+	const u32 *prescaler_table = sun4i_pwm->data->prescaler_table;
 	u32 prd, dty, val, clk_gate;
 	u64 clk_rate, div = 0;
 	unsigned int prescaler = 0;
@@ -317,6 +319,7 @@ static const struct sun4i_pwm_data sun4i_pwm_data_a10 = {
 	.has_rdy = false,
 	.npwm = 2,
 	.ops = &sun4i_reg_ops,
+	.prescaler_table = sun4i_prescaler_table,
 };
 
 static const struct sun4i_pwm_data sun4i_pwm_data_a10s = {
@@ -324,6 +327,7 @@ static const struct sun4i_pwm_data sun4i_pwm_data_a10s = {
 	.has_rdy = true,
 	.npwm = 2,
 	.ops = &sun4i_reg_ops,
+	.prescaler_table = sun4i_prescaler_table,
 };
 
 static const struct sun4i_pwm_data sun4i_pwm_data_a13 = {
@@ -331,6 +335,7 @@ static const struct sun4i_pwm_data sun4i_pwm_data_a13 = {
 	.has_rdy = true,
 	.npwm = 1,
 	.ops = &sun4i_reg_ops,
+	.prescaler_table = sun4i_prescaler_table,
 };
 
 static const struct sun4i_pwm_data sun4i_pwm_data_a20 = {
@@ -338,6 +343,7 @@ static const struct sun4i_pwm_data sun4i_pwm_data_a20 = {
 	.has_rdy = true,
 	.npwm = 2,
 	.ops = &sun4i_reg_ops,
+	.prescaler_table = sun4i_prescaler_table,
 };
 
 static const struct sun4i_pwm_data sun4i_pwm_data_h3 = {
@@ -345,6 +351,7 @@ static const struct sun4i_pwm_data sun4i_pwm_data_h3 = {
 	.has_rdy = true,
 	.npwm = 1,
 	.ops = &sun4i_reg_ops,
+	.prescaler_table = sun4i_prescaler_table,
 };
 
 static const struct of_device_id sun4i_pwm_dt_ids[] = {
-- 
2.4.11

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 2/4] ARM: pwm: sun4i: selectable prescaler table for support sun6i.
@ 2017-02-07 17:50   ` lis8215 at gmail.com
  0 siblings, 0 replies; 26+ messages in thread
From: lis8215 at gmail.com @ 2017-02-07 17:50 UTC (permalink / raw)
  To: linux-arm-kernel

From: Siarhei Volkau <lis8215@gmail.com>

This patch not introduce new features, just prepare code for
adding sun6i PWM driver in next commit.

A31 SoC have a different set of prescalers than others ASoCs, but
its position and count in the control register are the same.

This patch make the table of prescalers customizable.

Signed-off-by: Siarhei Volkau <lis8215@gmail.com>
---
 drivers/pwm/pwm-sun4i.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/pwm/pwm-sun4i.c b/drivers/pwm/pwm-sun4i.c
index 04ad3b4..39912fc 100644
--- a/drivers/pwm/pwm-sun4i.c
+++ b/drivers/pwm/pwm-sun4i.c
@@ -49,7 +49,7 @@
 
 struct sun4i_pwm_chip;
 
-static const u32 prescaler_table[] = {
+static const u32 sun4i_prescaler_table[] = {
 	120,
 	180,
 	240,
@@ -81,6 +81,7 @@ struct sun4i_pwm_data {
 	bool has_rdy;
 	unsigned int npwm;
 	const struct sunxi_reg_ops *ops;
+	const u32 *prescaler_table;
 };
 
 struct sun4i_pwm_chip {
@@ -144,6 +145,7 @@ static int sun4i_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
 {
 	struct sun4i_pwm_chip *sun4i_pwm = to_sun4i_pwm_chip(chip);
 	const struct sunxi_reg_ops *reg_ops = sun4i_pwm->data->ops;
+	const u32 *prescaler_table = sun4i_pwm->data->prescaler_table;
 	u32 prd, dty, val, clk_gate;
 	u64 clk_rate, div = 0;
 	unsigned int prescaler = 0;
@@ -317,6 +319,7 @@ static const struct sun4i_pwm_data sun4i_pwm_data_a10 = {
 	.has_rdy = false,
 	.npwm = 2,
 	.ops = &sun4i_reg_ops,
+	.prescaler_table = sun4i_prescaler_table,
 };
 
 static const struct sun4i_pwm_data sun4i_pwm_data_a10s = {
@@ -324,6 +327,7 @@ static const struct sun4i_pwm_data sun4i_pwm_data_a10s = {
 	.has_rdy = true,
 	.npwm = 2,
 	.ops = &sun4i_reg_ops,
+	.prescaler_table = sun4i_prescaler_table,
 };
 
 static const struct sun4i_pwm_data sun4i_pwm_data_a13 = {
@@ -331,6 +335,7 @@ static const struct sun4i_pwm_data sun4i_pwm_data_a13 = {
 	.has_rdy = true,
 	.npwm = 1,
 	.ops = &sun4i_reg_ops,
+	.prescaler_table = sun4i_prescaler_table,
 };
 
 static const struct sun4i_pwm_data sun4i_pwm_data_a20 = {
@@ -338,6 +343,7 @@ static const struct sun4i_pwm_data sun4i_pwm_data_a20 = {
 	.has_rdy = true,
 	.npwm = 2,
 	.ops = &sun4i_reg_ops,
+	.prescaler_table = sun4i_prescaler_table,
 };
 
 static const struct sun4i_pwm_data sun4i_pwm_data_h3 = {
@@ -345,6 +351,7 @@ static const struct sun4i_pwm_data sun4i_pwm_data_h3 = {
 	.has_rdy = true,
 	.npwm = 1,
 	.ops = &sun4i_reg_ops,
+	.prescaler_table = sun4i_prescaler_table,
 };
 
 static const struct of_device_id sun4i_pwm_dt_ids[] = {
-- 
2.4.11

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 3/4] ARM: pwm: sun6i: add support the Allwinner A31 PWM.
@ 2017-02-07 17:50   ` lis8215-Re5JQEeQqe8AvxtiuMwx3w
  0 siblings, 0 replies; 26+ messages in thread
From: lis8215 @ 2017-02-07 17:50 UTC (permalink / raw)
  To: linux-sunxi
  Cc: thierry.reding, robh+dt, mark.rutland, maxime.ripard, wens,
	linux-pwm, devicetree, linux-arm-kernel, linux-kernel,
	Siarhei Volkau

From: Siarhei Volkau <lis8215@gmail.com>

This patch introduce the sun6i PWM driver itself:
 - sun6i register operations,
 - sun6i prescaler table,
 - DT bindings for A31 SoC,
 - documentation update.

Signed-off-by: Siarhei Volkau <lis8215@gmail.com>
---
 .../devicetree/bindings/pwm/pwm-sun4i.txt          |  3 +-
 drivers/pwm/pwm-sun4i.c                            | 71 ++++++++++++++++++++++
 2 files changed, 73 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt b/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt
index f1cbeef..b737934 100644
--- a/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt
+++ b/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt
@@ -1,10 +1,11 @@
-Allwinner sun4i and sun7i SoC PWM controller
+Allwinner sun4i, sun6i and sun7i SoC PWM controller
 
 Required properties:
   - compatible: should be one of:
     - "allwinner,sun4i-a10-pwm"
     - "allwinner,sun5i-a10s-pwm"
     - "allwinner,sun5i-a13-pwm"
+    - "allwinner,sun6i-a31-pwm"
     - "allwinner,sun7i-a20-pwm"
     - "allwinner,sun8i-h3-pwm"
   - reg: physical base address and length of the controller's registers
diff --git a/drivers/pwm/pwm-sun4i.c b/drivers/pwm/pwm-sun4i.c
index 39912fc..0c1c372 100644
--- a/drivers/pwm/pwm-sun4i.c
+++ b/drivers/pwm/pwm-sun4i.c
@@ -47,6 +47,12 @@
 
 #define BIT_CH(bit, chan)	((bit) << ((chan) * PWMCH_OFFSET))
 
+#define SUN6I_PWM_RDY_BIT	PWM_RDY_BASE
+#define SUN6I_PWM_CTL_OFFS	0x0
+#define SUN6I_PWM_PRD_OFFS	0x4
+#define SUN6I_PWM_CH_CTL(ch)	(0x10 * (ch) + SUN6I_PWM_CTL_OFFS)
+#define SUN6I_PWM_CH_PRD(ch)	(0x10 * (ch) + SUN6I_PWM_PRD_OFFS)
+
 struct sun4i_pwm_chip;
 
 static const u32 sun4i_prescaler_table[] = {
@@ -68,6 +74,25 @@ static const u32 sun4i_prescaler_table[] = {
 	0, /* Actually 1 but tested separately */
 };
 
+static const u32 sun6i_prescaler_table[] = {
+	1,
+	2,
+	4,
+	8,
+	16,
+	32,
+	64,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+};
+
 struct sunxi_reg_ops {
 	int (*ctl_rdy)(struct sun4i_pwm_chip *chip, int npwm);
 	u32 (*ctl_read)(struct sun4i_pwm_chip *chip, int npwm);
@@ -140,6 +165,33 @@ static void sun4i_reg_prd_write(struct sun4i_pwm_chip *chip, int npwm, u32 val)
 	sun4i_pwm_writel(chip, val, PWM_CH_PRD(npwm));
 }
 
+static int sun6i_reg_ctl_rdy(struct sun4i_pwm_chip *chip, int npwm)
+{
+	u32 val = sun4i_pwm_readl(chip, SUN6I_PWM_CH_CTL(npwm));
+
+	return val & BIT(SUN6I_PWM_RDY_BIT);
+}
+
+static u32 sun6i_reg_ctl_read(struct sun4i_pwm_chip *chip, int npwm)
+{
+	return sun4i_pwm_readl(chip, SUN6I_PWM_CH_CTL(npwm));
+}
+
+static void sun6i_reg_ctl_write(struct sun4i_pwm_chip *chip, int npwm, u32 val)
+{
+	return sun4i_pwm_writel(chip, val, SUN6I_PWM_CH_CTL(npwm));
+}
+
+static u32 sun6i_reg_prd_read(struct sun4i_pwm_chip *chip, int npwm)
+{
+	return sun4i_pwm_readl(chip, SUN6I_PWM_CH_PRD(npwm));
+}
+
+static void sun6i_reg_prd_write(struct sun4i_pwm_chip *chip, int npwm, u32 val)
+{
+	return sun4i_pwm_writel(chip, val, SUN6I_PWM_CH_PRD(npwm));
+}
+
 static int sun4i_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
 			    int duty_ns, int period_ns)
 {
@@ -306,6 +358,14 @@ static const struct sunxi_reg_ops sun4i_reg_ops = {
 	.prd_write = sun4i_reg_prd_write,
 };
 
+static const struct sunxi_reg_ops sun6i_reg_ops = {
+	.ctl_rdy   = sun6i_reg_ctl_rdy,
+	.ctl_read  = sun6i_reg_ctl_read,
+	.ctl_write = sun6i_reg_ctl_write,
+	.prd_read  = sun6i_reg_prd_read,
+	.prd_write = sun6i_reg_prd_write,
+};
+
 static const struct pwm_ops sun4i_pwm_ops = {
 	.config = sun4i_pwm_config,
 	.set_polarity = sun4i_pwm_set_polarity,
@@ -338,6 +398,14 @@ static const struct sun4i_pwm_data sun4i_pwm_data_a13 = {
 	.prescaler_table = sun4i_prescaler_table,
 };
 
+static const struct sun4i_pwm_data sun6i_pwm_data_a31 = {
+	.has_prescaler_bypass = false,
+	.has_rdy = true,
+	.npwm = 4,
+	.ops = &sun6i_reg_ops,
+	.prescaler_table = sun6i_prescaler_table,
+};
+
 static const struct sun4i_pwm_data sun4i_pwm_data_a20 = {
 	.has_prescaler_bypass = true,
 	.has_rdy = true,
@@ -365,6 +433,9 @@ static const struct of_device_id sun4i_pwm_dt_ids[] = {
 		.compatible = "allwinner,sun5i-a13-pwm",
 		.data = &sun4i_pwm_data_a13,
 	}, {
+		.compatible = "allwinner,sun6i-a31-pwm",
+		.data = &sun6i_pwm_data_a31,
+	}, {
 		.compatible = "allwinner,sun7i-a20-pwm",
 		.data = &sun4i_pwm_data_a20,
 	}, {
-- 
2.4.11

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 3/4] ARM: pwm: sun6i: add support the Allwinner A31 PWM.
@ 2017-02-07 17:50   ` lis8215-Re5JQEeQqe8AvxtiuMwx3w
  0 siblings, 0 replies; 26+ messages in thread
From: lis8215-Re5JQEeQqe8AvxtiuMwx3w @ 2017-02-07 17:50 UTC (permalink / raw)
  To: linux-sunxi-/JYPxA39Uh5TLH3MbocFFw
  Cc: thierry.reding-Re5JQEeQqe8AvxtiuMwx3w,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
	maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8, wens-jdAy2FN1RRM,
	linux-pwm-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Siarhei Volkau

From: Siarhei Volkau <lis8215-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

This patch introduce the sun6i PWM driver itself:
 - sun6i register operations,
 - sun6i prescaler table,
 - DT bindings for A31 SoC,
 - documentation update.

Signed-off-by: Siarhei Volkau <lis8215-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 .../devicetree/bindings/pwm/pwm-sun4i.txt          |  3 +-
 drivers/pwm/pwm-sun4i.c                            | 71 ++++++++++++++++++++++
 2 files changed, 73 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt b/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt
index f1cbeef..b737934 100644
--- a/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt
+++ b/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt
@@ -1,10 +1,11 @@
-Allwinner sun4i and sun7i SoC PWM controller
+Allwinner sun4i, sun6i and sun7i SoC PWM controller
 
 Required properties:
   - compatible: should be one of:
     - "allwinner,sun4i-a10-pwm"
     - "allwinner,sun5i-a10s-pwm"
     - "allwinner,sun5i-a13-pwm"
+    - "allwinner,sun6i-a31-pwm"
     - "allwinner,sun7i-a20-pwm"
     - "allwinner,sun8i-h3-pwm"
   - reg: physical base address and length of the controller's registers
diff --git a/drivers/pwm/pwm-sun4i.c b/drivers/pwm/pwm-sun4i.c
index 39912fc..0c1c372 100644
--- a/drivers/pwm/pwm-sun4i.c
+++ b/drivers/pwm/pwm-sun4i.c
@@ -47,6 +47,12 @@
 
 #define BIT_CH(bit, chan)	((bit) << ((chan) * PWMCH_OFFSET))
 
+#define SUN6I_PWM_RDY_BIT	PWM_RDY_BASE
+#define SUN6I_PWM_CTL_OFFS	0x0
+#define SUN6I_PWM_PRD_OFFS	0x4
+#define SUN6I_PWM_CH_CTL(ch)	(0x10 * (ch) + SUN6I_PWM_CTL_OFFS)
+#define SUN6I_PWM_CH_PRD(ch)	(0x10 * (ch) + SUN6I_PWM_PRD_OFFS)
+
 struct sun4i_pwm_chip;
 
 static const u32 sun4i_prescaler_table[] = {
@@ -68,6 +74,25 @@ static const u32 sun4i_prescaler_table[] = {
 	0, /* Actually 1 but tested separately */
 };
 
+static const u32 sun6i_prescaler_table[] = {
+	1,
+	2,
+	4,
+	8,
+	16,
+	32,
+	64,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+};
+
 struct sunxi_reg_ops {
 	int (*ctl_rdy)(struct sun4i_pwm_chip *chip, int npwm);
 	u32 (*ctl_read)(struct sun4i_pwm_chip *chip, int npwm);
@@ -140,6 +165,33 @@ static void sun4i_reg_prd_write(struct sun4i_pwm_chip *chip, int npwm, u32 val)
 	sun4i_pwm_writel(chip, val, PWM_CH_PRD(npwm));
 }
 
+static int sun6i_reg_ctl_rdy(struct sun4i_pwm_chip *chip, int npwm)
+{
+	u32 val = sun4i_pwm_readl(chip, SUN6I_PWM_CH_CTL(npwm));
+
+	return val & BIT(SUN6I_PWM_RDY_BIT);
+}
+
+static u32 sun6i_reg_ctl_read(struct sun4i_pwm_chip *chip, int npwm)
+{
+	return sun4i_pwm_readl(chip, SUN6I_PWM_CH_CTL(npwm));
+}
+
+static void sun6i_reg_ctl_write(struct sun4i_pwm_chip *chip, int npwm, u32 val)
+{
+	return sun4i_pwm_writel(chip, val, SUN6I_PWM_CH_CTL(npwm));
+}
+
+static u32 sun6i_reg_prd_read(struct sun4i_pwm_chip *chip, int npwm)
+{
+	return sun4i_pwm_readl(chip, SUN6I_PWM_CH_PRD(npwm));
+}
+
+static void sun6i_reg_prd_write(struct sun4i_pwm_chip *chip, int npwm, u32 val)
+{
+	return sun4i_pwm_writel(chip, val, SUN6I_PWM_CH_PRD(npwm));
+}
+
 static int sun4i_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
 			    int duty_ns, int period_ns)
 {
@@ -306,6 +358,14 @@ static const struct sunxi_reg_ops sun4i_reg_ops = {
 	.prd_write = sun4i_reg_prd_write,
 };
 
+static const struct sunxi_reg_ops sun6i_reg_ops = {
+	.ctl_rdy   = sun6i_reg_ctl_rdy,
+	.ctl_read  = sun6i_reg_ctl_read,
+	.ctl_write = sun6i_reg_ctl_write,
+	.prd_read  = sun6i_reg_prd_read,
+	.prd_write = sun6i_reg_prd_write,
+};
+
 static const struct pwm_ops sun4i_pwm_ops = {
 	.config = sun4i_pwm_config,
 	.set_polarity = sun4i_pwm_set_polarity,
@@ -338,6 +398,14 @@ static const struct sun4i_pwm_data sun4i_pwm_data_a13 = {
 	.prescaler_table = sun4i_prescaler_table,
 };
 
+static const struct sun4i_pwm_data sun6i_pwm_data_a31 = {
+	.has_prescaler_bypass = false,
+	.has_rdy = true,
+	.npwm = 4,
+	.ops = &sun6i_reg_ops,
+	.prescaler_table = sun6i_prescaler_table,
+};
+
 static const struct sun4i_pwm_data sun4i_pwm_data_a20 = {
 	.has_prescaler_bypass = true,
 	.has_rdy = true,
@@ -365,6 +433,9 @@ static const struct of_device_id sun4i_pwm_dt_ids[] = {
 		.compatible = "allwinner,sun5i-a13-pwm",
 		.data = &sun4i_pwm_data_a13,
 	}, {
+		.compatible = "allwinner,sun6i-a31-pwm",
+		.data = &sun6i_pwm_data_a31,
+	}, {
 		.compatible = "allwinner,sun7i-a20-pwm",
 		.data = &sun4i_pwm_data_a20,
 	}, {
-- 
2.4.11

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 3/4] ARM: pwm: sun6i: add support the Allwinner A31 PWM.
@ 2017-02-07 17:50   ` lis8215-Re5JQEeQqe8AvxtiuMwx3w
  0 siblings, 0 replies; 26+ messages in thread
From: lis8215 at gmail.com @ 2017-02-07 17:50 UTC (permalink / raw)
  To: linux-arm-kernel

From: Siarhei Volkau <lis8215@gmail.com>

This patch introduce the sun6i PWM driver itself:
 - sun6i register operations,
 - sun6i prescaler table,
 - DT bindings for A31 SoC,
 - documentation update.

Signed-off-by: Siarhei Volkau <lis8215@gmail.com>
---
 .../devicetree/bindings/pwm/pwm-sun4i.txt          |  3 +-
 drivers/pwm/pwm-sun4i.c                            | 71 ++++++++++++++++++++++
 2 files changed, 73 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt b/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt
index f1cbeef..b737934 100644
--- a/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt
+++ b/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt
@@ -1,10 +1,11 @@
-Allwinner sun4i and sun7i SoC PWM controller
+Allwinner sun4i, sun6i and sun7i SoC PWM controller
 
 Required properties:
   - compatible: should be one of:
     - "allwinner,sun4i-a10-pwm"
     - "allwinner,sun5i-a10s-pwm"
     - "allwinner,sun5i-a13-pwm"
+    - "allwinner,sun6i-a31-pwm"
     - "allwinner,sun7i-a20-pwm"
     - "allwinner,sun8i-h3-pwm"
   - reg: physical base address and length of the controller's registers
diff --git a/drivers/pwm/pwm-sun4i.c b/drivers/pwm/pwm-sun4i.c
index 39912fc..0c1c372 100644
--- a/drivers/pwm/pwm-sun4i.c
+++ b/drivers/pwm/pwm-sun4i.c
@@ -47,6 +47,12 @@
 
 #define BIT_CH(bit, chan)	((bit) << ((chan) * PWMCH_OFFSET))
 
+#define SUN6I_PWM_RDY_BIT	PWM_RDY_BASE
+#define SUN6I_PWM_CTL_OFFS	0x0
+#define SUN6I_PWM_PRD_OFFS	0x4
+#define SUN6I_PWM_CH_CTL(ch)	(0x10 * (ch) + SUN6I_PWM_CTL_OFFS)
+#define SUN6I_PWM_CH_PRD(ch)	(0x10 * (ch) + SUN6I_PWM_PRD_OFFS)
+
 struct sun4i_pwm_chip;
 
 static const u32 sun4i_prescaler_table[] = {
@@ -68,6 +74,25 @@ static const u32 sun4i_prescaler_table[] = {
 	0, /* Actually 1 but tested separately */
 };
 
+static const u32 sun6i_prescaler_table[] = {
+	1,
+	2,
+	4,
+	8,
+	16,
+	32,
+	64,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+};
+
 struct sunxi_reg_ops {
 	int (*ctl_rdy)(struct sun4i_pwm_chip *chip, int npwm);
 	u32 (*ctl_read)(struct sun4i_pwm_chip *chip, int npwm);
@@ -140,6 +165,33 @@ static void sun4i_reg_prd_write(struct sun4i_pwm_chip *chip, int npwm, u32 val)
 	sun4i_pwm_writel(chip, val, PWM_CH_PRD(npwm));
 }
 
+static int sun6i_reg_ctl_rdy(struct sun4i_pwm_chip *chip, int npwm)
+{
+	u32 val = sun4i_pwm_readl(chip, SUN6I_PWM_CH_CTL(npwm));
+
+	return val & BIT(SUN6I_PWM_RDY_BIT);
+}
+
+static u32 sun6i_reg_ctl_read(struct sun4i_pwm_chip *chip, int npwm)
+{
+	return sun4i_pwm_readl(chip, SUN6I_PWM_CH_CTL(npwm));
+}
+
+static void sun6i_reg_ctl_write(struct sun4i_pwm_chip *chip, int npwm, u32 val)
+{
+	return sun4i_pwm_writel(chip, val, SUN6I_PWM_CH_CTL(npwm));
+}
+
+static u32 sun6i_reg_prd_read(struct sun4i_pwm_chip *chip, int npwm)
+{
+	return sun4i_pwm_readl(chip, SUN6I_PWM_CH_PRD(npwm));
+}
+
+static void sun6i_reg_prd_write(struct sun4i_pwm_chip *chip, int npwm, u32 val)
+{
+	return sun4i_pwm_writel(chip, val, SUN6I_PWM_CH_PRD(npwm));
+}
+
 static int sun4i_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
 			    int duty_ns, int period_ns)
 {
@@ -306,6 +358,14 @@ static const struct sunxi_reg_ops sun4i_reg_ops = {
 	.prd_write = sun4i_reg_prd_write,
 };
 
+static const struct sunxi_reg_ops sun6i_reg_ops = {
+	.ctl_rdy   = sun6i_reg_ctl_rdy,
+	.ctl_read  = sun6i_reg_ctl_read,
+	.ctl_write = sun6i_reg_ctl_write,
+	.prd_read  = sun6i_reg_prd_read,
+	.prd_write = sun6i_reg_prd_write,
+};
+
 static const struct pwm_ops sun4i_pwm_ops = {
 	.config = sun4i_pwm_config,
 	.set_polarity = sun4i_pwm_set_polarity,
@@ -338,6 +398,14 @@ static const struct sun4i_pwm_data sun4i_pwm_data_a13 = {
 	.prescaler_table = sun4i_prescaler_table,
 };
 
+static const struct sun4i_pwm_data sun6i_pwm_data_a31 = {
+	.has_prescaler_bypass = false,
+	.has_rdy = true,
+	.npwm = 4,
+	.ops = &sun6i_reg_ops,
+	.prescaler_table = sun6i_prescaler_table,
+};
+
 static const struct sun4i_pwm_data sun4i_pwm_data_a20 = {
 	.has_prescaler_bypass = true,
 	.has_rdy = true,
@@ -365,6 +433,9 @@ static const struct of_device_id sun4i_pwm_dt_ids[] = {
 		.compatible = "allwinner,sun5i-a13-pwm",
 		.data = &sun4i_pwm_data_a13,
 	}, {
+		.compatible = "allwinner,sun6i-a31-pwm",
+		.data = &sun6i_pwm_data_a31,
+	}, {
 		.compatible = "allwinner,sun7i-a20-pwm",
 		.data = &sun4i_pwm_data_a20,
 	}, {
-- 
2.4.11

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 4/4] ARM: dts: sun6i: Add the PWM block to the A31/A31s.
@ 2017-02-07 17:50   ` lis8215-Re5JQEeQqe8AvxtiuMwx3w
  0 siblings, 0 replies; 26+ messages in thread
From: lis8215 @ 2017-02-07 17:50 UTC (permalink / raw)
  To: linux-sunxi
  Cc: thierry.reding, robh+dt, mark.rutland, maxime.ripard, wens,
	linux-pwm, devicetree, linux-arm-kernel, linux-kernel,
	Siarhei Volkau

From: Siarhei Volkau <lis8215@gmail.com>

Signed-off-by: Siarhei Volkau <lis8215@gmail.com>
---
 arch/arm/boot/dts/sun6i-a31.dtsi | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/boot/dts/sun6i-a31.dtsi b/arch/arm/boot/dts/sun6i-a31.dtsi
index ee1eb6d..fcba129 100644
--- a/arch/arm/boot/dts/sun6i-a31.dtsi
+++ b/arch/arm/boot/dts/sun6i-a31.dtsi
@@ -627,6 +627,14 @@
 			status = "disabled";
 		};
 
+		pwm: pwm@01c21400 {
+			compatible = "allwinner,sun6i-a31-pwm";
+			reg = <0x01c21400 0x400>;
+			clocks = <&osc24M>;
+			#pwm-cells = <3>;
+			status = "disabled";
+		};
+
 		lradc: lradc@01c22800 {
 			compatible = "allwinner,sun4i-a10-lradc-keys";
 			reg = <0x01c22800 0x100>;
-- 
2.4.11

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 4/4] ARM: dts: sun6i: Add the PWM block to the A31/A31s.
@ 2017-02-07 17:50   ` lis8215-Re5JQEeQqe8AvxtiuMwx3w
  0 siblings, 0 replies; 26+ messages in thread
From: lis8215-Re5JQEeQqe8AvxtiuMwx3w @ 2017-02-07 17:50 UTC (permalink / raw)
  To: linux-sunxi-/JYPxA39Uh5TLH3MbocFFw
  Cc: thierry.reding-Re5JQEeQqe8AvxtiuMwx3w,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
	maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8, wens-jdAy2FN1RRM,
	linux-pwm-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Siarhei Volkau

From: Siarhei Volkau <lis8215-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

Signed-off-by: Siarhei Volkau <lis8215-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 arch/arm/boot/dts/sun6i-a31.dtsi | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/boot/dts/sun6i-a31.dtsi b/arch/arm/boot/dts/sun6i-a31.dtsi
index ee1eb6d..fcba129 100644
--- a/arch/arm/boot/dts/sun6i-a31.dtsi
+++ b/arch/arm/boot/dts/sun6i-a31.dtsi
@@ -627,6 +627,14 @@
 			status = "disabled";
 		};
 
+		pwm: pwm@01c21400 {
+			compatible = "allwinner,sun6i-a31-pwm";
+			reg = <0x01c21400 0x400>;
+			clocks = <&osc24M>;
+			#pwm-cells = <3>;
+			status = "disabled";
+		};
+
 		lradc: lradc@01c22800 {
 			compatible = "allwinner,sun4i-a10-lradc-keys";
 			reg = <0x01c22800 0x100>;
-- 
2.4.11

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 4/4] ARM: dts: sun6i: Add the PWM block to the A31/A31s.
@ 2017-02-07 17:50   ` lis8215-Re5JQEeQqe8AvxtiuMwx3w
  0 siblings, 0 replies; 26+ messages in thread
From: lis8215 at gmail.com @ 2017-02-07 17:50 UTC (permalink / raw)
  To: linux-arm-kernel

From: Siarhei Volkau <lis8215@gmail.com>

Signed-off-by: Siarhei Volkau <lis8215@gmail.com>
---
 arch/arm/boot/dts/sun6i-a31.dtsi | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/boot/dts/sun6i-a31.dtsi b/arch/arm/boot/dts/sun6i-a31.dtsi
index ee1eb6d..fcba129 100644
--- a/arch/arm/boot/dts/sun6i-a31.dtsi
+++ b/arch/arm/boot/dts/sun6i-a31.dtsi
@@ -627,6 +627,14 @@
 			status = "disabled";
 		};
 
+		pwm: pwm at 01c21400 {
+			compatible = "allwinner,sun6i-a31-pwm";
+			reg = <0x01c21400 0x400>;
+			clocks = <&osc24M>;
+			#pwm-cells = <3>;
+			status = "disabled";
+		};
+
 		lradc: lradc at 01c22800 {
 			compatible = "allwinner,sun4i-a10-lradc-keys";
 			reg = <0x01c22800 0x100>;
-- 
2.4.11

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 1/4] ARM: pwm: sun4i: unification of register operations for support sun6i.
@ 2017-02-08  7:52     ` Maxime Ripard
  0 siblings, 0 replies; 26+ messages in thread
From: Maxime Ripard @ 2017-02-08  7:52 UTC (permalink / raw)
  To: lis8215
  Cc: linux-sunxi, thierry.reding, robh+dt, mark.rutland, wens,
	linux-pwm, devicetree, linux-arm-kernel, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1058 bytes --]

Hi,

On Tue, Feb 07, 2017 at 08:50:43PM +0300, lis8215@gmail.com wrote:
> From: Siarhei Volkau <lis8215@gmail.com>
> 
> This patch not introduce new features, just prepare code for
> adding sun6i PWM driver in next commits.
> 
> A31 SoC have a different map of PWM registers than others ASoCs,
> but register bits purposes are very similar.
> 
> This patch introduce set of register access routines, which
> are common for existing in driver ASoCs:
>  - ctl_rdy   - checks the ready bit of specified PWM channel,
>  - ctl_read  - reads value from control register of specified PWM channel,
>  - ctl_write - writes significant bits to control register of specified PWM channel,
>  - prd_read  - reads value from period register of specified PWM channel,
>  - prd_write - writes value to period register of specified PWM channel.
> Driver code redesigned to use the new routines.

Why don't you use regmap for that?

Thanks,
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 1/4] ARM: pwm: sun4i: unification of register operations for support sun6i.
@ 2017-02-08  7:52     ` Maxime Ripard
  0 siblings, 0 replies; 26+ messages in thread
From: Maxime Ripard @ 2017-02-08  7:52 UTC (permalink / raw)
  To: lis8215-Re5JQEeQqe8AvxtiuMwx3w
  Cc: linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	thierry.reding-Re5JQEeQqe8AvxtiuMwx3w,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
	wens-jdAy2FN1RRM, linux-pwm-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

[-- Attachment #1: Type: text/plain, Size: 1088 bytes --]

Hi,

On Tue, Feb 07, 2017 at 08:50:43PM +0300, lis8215-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org wrote:
> From: Siarhei Volkau <lis8215-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> 
> This patch not introduce new features, just prepare code for
> adding sun6i PWM driver in next commits.
> 
> A31 SoC have a different map of PWM registers than others ASoCs,
> but register bits purposes are very similar.
> 
> This patch introduce set of register access routines, which
> are common for existing in driver ASoCs:
>  - ctl_rdy   - checks the ready bit of specified PWM channel,
>  - ctl_read  - reads value from control register of specified PWM channel,
>  - ctl_write - writes significant bits to control register of specified PWM channel,
>  - prd_read  - reads value from period register of specified PWM channel,
>  - prd_write - writes value to period register of specified PWM channel.
> Driver code redesigned to use the new routines.

Why don't you use regmap for that?

Thanks,
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH v2 1/4] ARM: pwm: sun4i: unification of register operations for support sun6i.
@ 2017-02-08  7:52     ` Maxime Ripard
  0 siblings, 0 replies; 26+ messages in thread
From: Maxime Ripard @ 2017-02-08  7:52 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On Tue, Feb 07, 2017 at 08:50:43PM +0300, lis8215 at gmail.com wrote:
> From: Siarhei Volkau <lis8215@gmail.com>
> 
> This patch not introduce new features, just prepare code for
> adding sun6i PWM driver in next commits.
> 
> A31 SoC have a different map of PWM registers than others ASoCs,
> but register bits purposes are very similar.
> 
> This patch introduce set of register access routines, which
> are common for existing in driver ASoCs:
>  - ctl_rdy   - checks the ready bit of specified PWM channel,
>  - ctl_read  - reads value from control register of specified PWM channel,
>  - ctl_write - writes significant bits to control register of specified PWM channel,
>  - prd_read  - reads value from period register of specified PWM channel,
>  - prd_write - writes value to period register of specified PWM channel.
> Driver code redesigned to use the new routines.

Why don't you use regmap for that?

Thanks,
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20170208/e431d57c/attachment-0001.sig>

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 3/4] ARM: pwm: sun6i: add support the Allwinner A31 PWM.
@ 2017-02-08  7:53     ` Maxime Ripard
  0 siblings, 0 replies; 26+ messages in thread
From: Maxime Ripard @ 2017-02-08  7:53 UTC (permalink / raw)
  To: lis8215
  Cc: linux-sunxi, thierry.reding, robh+dt, mark.rutland, wens,
	linux-pwm, devicetree, linux-arm-kernel, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 4124 bytes --]

On Tue, Feb 07, 2017 at 08:50:45PM +0300, lis8215@gmail.com wrote:
> From: Siarhei Volkau <lis8215@gmail.com>
> 
> This patch introduce the sun6i PWM driver itself:
>  - sun6i register operations,
>  - sun6i prescaler table,
>  - DT bindings for A31 SoC,
>  - documentation update.
> 
> Signed-off-by: Siarhei Volkau <lis8215@gmail.com>
> ---
>  .../devicetree/bindings/pwm/pwm-sun4i.txt          |  3 +-
>  drivers/pwm/pwm-sun4i.c                            | 71 ++++++++++++++++++++++
>  2 files changed, 73 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt b/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt
> index f1cbeef..b737934 100644
> --- a/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt
> +++ b/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt
> @@ -1,10 +1,11 @@
> -Allwinner sun4i and sun7i SoC PWM controller
> +Allwinner sun4i, sun6i and sun7i SoC PWM controller
>  
>  Required properties:
>    - compatible: should be one of:
>      - "allwinner,sun4i-a10-pwm"
>      - "allwinner,sun5i-a10s-pwm"
>      - "allwinner,sun5i-a13-pwm"
> +    - "allwinner,sun6i-a31-pwm"
>      - "allwinner,sun7i-a20-pwm"
>      - "allwinner,sun8i-h3-pwm"
>    - reg: physical base address and length of the controller's registers
> diff --git a/drivers/pwm/pwm-sun4i.c b/drivers/pwm/pwm-sun4i.c
> index 39912fc..0c1c372 100644
> --- a/drivers/pwm/pwm-sun4i.c
> +++ b/drivers/pwm/pwm-sun4i.c
> @@ -47,6 +47,12 @@
>  
>  #define BIT_CH(bit, chan)	((bit) << ((chan) * PWMCH_OFFSET))
>  
> +#define SUN6I_PWM_RDY_BIT	PWM_RDY_BASE
> +#define SUN6I_PWM_CTL_OFFS	0x0
> +#define SUN6I_PWM_PRD_OFFS	0x4
> +#define SUN6I_PWM_CH_CTL(ch)	(0x10 * (ch) + SUN6I_PWM_CTL_OFFS)
> +#define SUN6I_PWM_CH_PRD(ch)	(0x10 * (ch) + SUN6I_PWM_PRD_OFFS)
> +
>  struct sun4i_pwm_chip;
>  
>  static const u32 sun4i_prescaler_table[] = {
> @@ -68,6 +74,25 @@ static const u32 sun4i_prescaler_table[] = {
>  	0, /* Actually 1 but tested separately */
>  };
>  
> +static const u32 sun6i_prescaler_table[] = {
> +	1,
> +	2,
> +	4,
> +	8,
> +	16,
> +	32,
> +	64,
> +	0,
> +	0,
> +	0,
> +	0,
> +	0,
> +	0,
> +	0,
> +	0,
> +	0,
> +};
> +
>  struct sunxi_reg_ops {
>  	int (*ctl_rdy)(struct sun4i_pwm_chip *chip, int npwm);
>  	u32 (*ctl_read)(struct sun4i_pwm_chip *chip, int npwm);
> @@ -140,6 +165,33 @@ static void sun4i_reg_prd_write(struct sun4i_pwm_chip *chip, int npwm, u32 val)
>  	sun4i_pwm_writel(chip, val, PWM_CH_PRD(npwm));
>  }
>  
> +static int sun6i_reg_ctl_rdy(struct sun4i_pwm_chip *chip, int npwm)
> +{
> +	u32 val = sun4i_pwm_readl(chip, SUN6I_PWM_CH_CTL(npwm));
> +
> +	return val & BIT(SUN6I_PWM_RDY_BIT);
> +}
> +
> +static u32 sun6i_reg_ctl_read(struct sun4i_pwm_chip *chip, int npwm)
> +{
> +	return sun4i_pwm_readl(chip, SUN6I_PWM_CH_CTL(npwm));
> +}
> +
> +static void sun6i_reg_ctl_write(struct sun4i_pwm_chip *chip, int npwm, u32 val)
> +{
> +	return sun4i_pwm_writel(chip, val, SUN6I_PWM_CH_CTL(npwm));
> +}
> +
> +static u32 sun6i_reg_prd_read(struct sun4i_pwm_chip *chip, int npwm)
> +{
> +	return sun4i_pwm_readl(chip, SUN6I_PWM_CH_PRD(npwm));
> +}
> +
> +static void sun6i_reg_prd_write(struct sun4i_pwm_chip *chip, int npwm, u32 val)
> +{
> +	return sun4i_pwm_writel(chip, val, SUN6I_PWM_CH_PRD(npwm));
> +}
> +
>  static int sun4i_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
>  			    int duty_ns, int period_ns)
>  {
> @@ -306,6 +358,14 @@ static const struct sunxi_reg_ops sun4i_reg_ops = {
>  	.prd_write = sun4i_reg_prd_write,
>  };
>  
> +static const struct sunxi_reg_ops sun6i_reg_ops = {
> +	.ctl_rdy   = sun6i_reg_ctl_rdy,
> +	.ctl_read  = sun6i_reg_ctl_read,
> +	.ctl_write = sun6i_reg_ctl_write,
> +	.prd_read  = sun6i_reg_prd_read,
> +	.prd_write = sun6i_reg_prd_write,
> +};
> +

... And use regmap's reg_field to deal with the different offsets in
that case ?

Looks quite good otherwise, thanks!
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 3/4] ARM: pwm: sun6i: add support the Allwinner A31 PWM.
@ 2017-02-08  7:53     ` Maxime Ripard
  0 siblings, 0 replies; 26+ messages in thread
From: Maxime Ripard @ 2017-02-08  7:53 UTC (permalink / raw)
  To: lis8215-Re5JQEeQqe8AvxtiuMwx3w
  Cc: linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	thierry.reding-Re5JQEeQqe8AvxtiuMwx3w,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
	wens-jdAy2FN1RRM, linux-pwm-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

[-- Attachment #1: Type: text/plain, Size: 4081 bytes --]

On Tue, Feb 07, 2017 at 08:50:45PM +0300, lis8215-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org wrote:
> From: Siarhei Volkau <lis8215-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> 
> This patch introduce the sun6i PWM driver itself:
>  - sun6i register operations,
>  - sun6i prescaler table,
>  - DT bindings for A31 SoC,
>  - documentation update.
> 
> Signed-off-by: Siarhei Volkau <lis8215-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> ---
>  .../devicetree/bindings/pwm/pwm-sun4i.txt          |  3 +-
>  drivers/pwm/pwm-sun4i.c                            | 71 ++++++++++++++++++++++
>  2 files changed, 73 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt b/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt
> index f1cbeef..b737934 100644
> --- a/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt
> +++ b/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt
> @@ -1,10 +1,11 @@
> -Allwinner sun4i and sun7i SoC PWM controller
> +Allwinner sun4i, sun6i and sun7i SoC PWM controller
>  
>  Required properties:
>    - compatible: should be one of:
>      - "allwinner,sun4i-a10-pwm"
>      - "allwinner,sun5i-a10s-pwm"
>      - "allwinner,sun5i-a13-pwm"
> +    - "allwinner,sun6i-a31-pwm"
>      - "allwinner,sun7i-a20-pwm"
>      - "allwinner,sun8i-h3-pwm"
>    - reg: physical base address and length of the controller's registers
> diff --git a/drivers/pwm/pwm-sun4i.c b/drivers/pwm/pwm-sun4i.c
> index 39912fc..0c1c372 100644
> --- a/drivers/pwm/pwm-sun4i.c
> +++ b/drivers/pwm/pwm-sun4i.c
> @@ -47,6 +47,12 @@
>  
>  #define BIT_CH(bit, chan)	((bit) << ((chan) * PWMCH_OFFSET))
>  
> +#define SUN6I_PWM_RDY_BIT	PWM_RDY_BASE
> +#define SUN6I_PWM_CTL_OFFS	0x0
> +#define SUN6I_PWM_PRD_OFFS	0x4
> +#define SUN6I_PWM_CH_CTL(ch)	(0x10 * (ch) + SUN6I_PWM_CTL_OFFS)
> +#define SUN6I_PWM_CH_PRD(ch)	(0x10 * (ch) + SUN6I_PWM_PRD_OFFS)
> +
>  struct sun4i_pwm_chip;
>  
>  static const u32 sun4i_prescaler_table[] = {
> @@ -68,6 +74,25 @@ static const u32 sun4i_prescaler_table[] = {
>  	0, /* Actually 1 but tested separately */
>  };
>  
> +static const u32 sun6i_prescaler_table[] = {
> +	1,
> +	2,
> +	4,
> +	8,
> +	16,
> +	32,
> +	64,
> +	0,
> +	0,
> +	0,
> +	0,
> +	0,
> +	0,
> +	0,
> +	0,
> +	0,
> +};
> +
>  struct sunxi_reg_ops {
>  	int (*ctl_rdy)(struct sun4i_pwm_chip *chip, int npwm);
>  	u32 (*ctl_read)(struct sun4i_pwm_chip *chip, int npwm);
> @@ -140,6 +165,33 @@ static void sun4i_reg_prd_write(struct sun4i_pwm_chip *chip, int npwm, u32 val)
>  	sun4i_pwm_writel(chip, val, PWM_CH_PRD(npwm));
>  }
>  
> +static int sun6i_reg_ctl_rdy(struct sun4i_pwm_chip *chip, int npwm)
> +{
> +	u32 val = sun4i_pwm_readl(chip, SUN6I_PWM_CH_CTL(npwm));
> +
> +	return val & BIT(SUN6I_PWM_RDY_BIT);
> +}
> +
> +static u32 sun6i_reg_ctl_read(struct sun4i_pwm_chip *chip, int npwm)
> +{
> +	return sun4i_pwm_readl(chip, SUN6I_PWM_CH_CTL(npwm));
> +}
> +
> +static void sun6i_reg_ctl_write(struct sun4i_pwm_chip *chip, int npwm, u32 val)
> +{
> +	return sun4i_pwm_writel(chip, val, SUN6I_PWM_CH_CTL(npwm));
> +}
> +
> +static u32 sun6i_reg_prd_read(struct sun4i_pwm_chip *chip, int npwm)
> +{
> +	return sun4i_pwm_readl(chip, SUN6I_PWM_CH_PRD(npwm));
> +}
> +
> +static void sun6i_reg_prd_write(struct sun4i_pwm_chip *chip, int npwm, u32 val)
> +{
> +	return sun4i_pwm_writel(chip, val, SUN6I_PWM_CH_PRD(npwm));
> +}
> +
>  static int sun4i_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
>  			    int duty_ns, int period_ns)
>  {
> @@ -306,6 +358,14 @@ static const struct sunxi_reg_ops sun4i_reg_ops = {
>  	.prd_write = sun4i_reg_prd_write,
>  };
>  
> +static const struct sunxi_reg_ops sun6i_reg_ops = {
> +	.ctl_rdy   = sun6i_reg_ctl_rdy,
> +	.ctl_read  = sun6i_reg_ctl_read,
> +	.ctl_write = sun6i_reg_ctl_write,
> +	.prd_read  = sun6i_reg_prd_read,
> +	.prd_write = sun6i_reg_prd_write,
> +};
> +

... And use regmap's reg_field to deal with the different offsets in
that case ?

Looks quite good otherwise, thanks!
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH v2 3/4] ARM: pwm: sun6i: add support the Allwinner A31 PWM.
@ 2017-02-08  7:53     ` Maxime Ripard
  0 siblings, 0 replies; 26+ messages in thread
From: Maxime Ripard @ 2017-02-08  7:53 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Feb 07, 2017 at 08:50:45PM +0300, lis8215 at gmail.com wrote:
> From: Siarhei Volkau <lis8215@gmail.com>
> 
> This patch introduce the sun6i PWM driver itself:
>  - sun6i register operations,
>  - sun6i prescaler table,
>  - DT bindings for A31 SoC,
>  - documentation update.
> 
> Signed-off-by: Siarhei Volkau <lis8215@gmail.com>
> ---
>  .../devicetree/bindings/pwm/pwm-sun4i.txt          |  3 +-
>  drivers/pwm/pwm-sun4i.c                            | 71 ++++++++++++++++++++++
>  2 files changed, 73 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt b/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt
> index f1cbeef..b737934 100644
> --- a/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt
> +++ b/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt
> @@ -1,10 +1,11 @@
> -Allwinner sun4i and sun7i SoC PWM controller
> +Allwinner sun4i, sun6i and sun7i SoC PWM controller
>  
>  Required properties:
>    - compatible: should be one of:
>      - "allwinner,sun4i-a10-pwm"
>      - "allwinner,sun5i-a10s-pwm"
>      - "allwinner,sun5i-a13-pwm"
> +    - "allwinner,sun6i-a31-pwm"
>      - "allwinner,sun7i-a20-pwm"
>      - "allwinner,sun8i-h3-pwm"
>    - reg: physical base address and length of the controller's registers
> diff --git a/drivers/pwm/pwm-sun4i.c b/drivers/pwm/pwm-sun4i.c
> index 39912fc..0c1c372 100644
> --- a/drivers/pwm/pwm-sun4i.c
> +++ b/drivers/pwm/pwm-sun4i.c
> @@ -47,6 +47,12 @@
>  
>  #define BIT_CH(bit, chan)	((bit) << ((chan) * PWMCH_OFFSET))
>  
> +#define SUN6I_PWM_RDY_BIT	PWM_RDY_BASE
> +#define SUN6I_PWM_CTL_OFFS	0x0
> +#define SUN6I_PWM_PRD_OFFS	0x4
> +#define SUN6I_PWM_CH_CTL(ch)	(0x10 * (ch) + SUN6I_PWM_CTL_OFFS)
> +#define SUN6I_PWM_CH_PRD(ch)	(0x10 * (ch) + SUN6I_PWM_PRD_OFFS)
> +
>  struct sun4i_pwm_chip;
>  
>  static const u32 sun4i_prescaler_table[] = {
> @@ -68,6 +74,25 @@ static const u32 sun4i_prescaler_table[] = {
>  	0, /* Actually 1 but tested separately */
>  };
>  
> +static const u32 sun6i_prescaler_table[] = {
> +	1,
> +	2,
> +	4,
> +	8,
> +	16,
> +	32,
> +	64,
> +	0,
> +	0,
> +	0,
> +	0,
> +	0,
> +	0,
> +	0,
> +	0,
> +	0,
> +};
> +
>  struct sunxi_reg_ops {
>  	int (*ctl_rdy)(struct sun4i_pwm_chip *chip, int npwm);
>  	u32 (*ctl_read)(struct sun4i_pwm_chip *chip, int npwm);
> @@ -140,6 +165,33 @@ static void sun4i_reg_prd_write(struct sun4i_pwm_chip *chip, int npwm, u32 val)
>  	sun4i_pwm_writel(chip, val, PWM_CH_PRD(npwm));
>  }
>  
> +static int sun6i_reg_ctl_rdy(struct sun4i_pwm_chip *chip, int npwm)
> +{
> +	u32 val = sun4i_pwm_readl(chip, SUN6I_PWM_CH_CTL(npwm));
> +
> +	return val & BIT(SUN6I_PWM_RDY_BIT);
> +}
> +
> +static u32 sun6i_reg_ctl_read(struct sun4i_pwm_chip *chip, int npwm)
> +{
> +	return sun4i_pwm_readl(chip, SUN6I_PWM_CH_CTL(npwm));
> +}
> +
> +static void sun6i_reg_ctl_write(struct sun4i_pwm_chip *chip, int npwm, u32 val)
> +{
> +	return sun4i_pwm_writel(chip, val, SUN6I_PWM_CH_CTL(npwm));
> +}
> +
> +static u32 sun6i_reg_prd_read(struct sun4i_pwm_chip *chip, int npwm)
> +{
> +	return sun4i_pwm_readl(chip, SUN6I_PWM_CH_PRD(npwm));
> +}
> +
> +static void sun6i_reg_prd_write(struct sun4i_pwm_chip *chip, int npwm, u32 val)
> +{
> +	return sun4i_pwm_writel(chip, val, SUN6I_PWM_CH_PRD(npwm));
> +}
> +
>  static int sun4i_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
>  			    int duty_ns, int period_ns)
>  {
> @@ -306,6 +358,14 @@ static const struct sunxi_reg_ops sun4i_reg_ops = {
>  	.prd_write = sun4i_reg_prd_write,
>  };
>  
> +static const struct sunxi_reg_ops sun6i_reg_ops = {
> +	.ctl_rdy   = sun6i_reg_ctl_rdy,
> +	.ctl_read  = sun6i_reg_ctl_read,
> +	.ctl_write = sun6i_reg_ctl_write,
> +	.prd_read  = sun6i_reg_prd_read,
> +	.prd_write = sun6i_reg_prd_write,
> +};
> +

... And use regmap's reg_field to deal with the different offsets in
that case ?

Looks quite good otherwise, thanks!
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20170208/865e28f2/attachment-0001.sig>

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 1/4] ARM: pwm: sun4i: unification of register operations for support sun6i.
  2017-02-08  7:52     ` Maxime Ripard
  (?)
  (?)
@ 2017-02-08 16:41     ` Волков Сергей
  2017-02-10  8:38         ` Maxime Ripard
  -1 siblings, 1 reply; 26+ messages in thread
From: Волков Сергей @ 2017-02-08 16:41 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Thierry Reding,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
	Chen-Yu Tsai, linux-pwm-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

[-- Attachment #1: Type: text/plain, Size: 1586 bytes --]

Hello all,

>> This patch not introduce new features, just prepare code for
>> adding sun6i PWM driver in next commits.
>>
>> A31 SoC have a different map of PWM registers than others ASoCs,
>> but register bits purposes are very similar.
>>
>> This patch introduce set of register access routines, which
>> are common for existing in driver ASoCs:
>>  - ctl_rdy   - checks the ready bit of specified PWM channel,
>>  - ctl_read  - reads value from control register of specified PWM
channel,
>>  - ctl_write - writes significant bits to control register of specified
PWM channel,
>>  - prd_read  - reads value from period register of specified PWM channel,
>>  - prd_write - writes value to period register of specified PWM channel.
>> Driver code redesigned to use the new routines.
>
> Why don't you use regmap for that?

First of all, i'm newbie and its my first patchset. I just remake what i
see in the driver. I even don't suspect about use regmap here.

Second thing - i can't test these driver on all existing sunxi SoCs, i have
only A31 and A20 based boards where only pwm0 is accessible. Huge redesign
cause bigger chance to make a mistake.

If you think regmap solution is a must, then i will do that. This will be a
good experience for me.

Thanks,
Siarhei

-- 
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.

[-- Attachment #2: Type: text/html, Size: 2188 bytes --]

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 1/4] ARM: pwm: sun4i: unification of register operations for support sun6i.
@ 2017-02-10  8:38         ` Maxime Ripard
  0 siblings, 0 replies; 26+ messages in thread
From: Maxime Ripard @ 2017-02-10  8:38 UTC (permalink / raw)
  To: Волков
	Сергей
  Cc: linux-sunxi, Thierry Reding, robh+dt, mark.rutland, Chen-Yu Tsai,
	linux-pwm, devicetree, linux-arm-kernel, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 2024 bytes --]

Hi,

On Wed, Feb 08, 2017 at 07:41:55PM +0300, Волков Сергей wrote:
> Hello all,
> 
> >> This patch not introduce new features, just prepare code for
> >> adding sun6i PWM driver in next commits.
> >>
> >> A31 SoC have a different map of PWM registers than others ASoCs,
> >> but register bits purposes are very similar.
> >>
> >> This patch introduce set of register access routines, which
> >> are common for existing in driver ASoCs:
> >>  - ctl_rdy   - checks the ready bit of specified PWM channel,
> >>  - ctl_read  - reads value from control register of specified PWM
> channel,
> >>  - ctl_write - writes significant bits to control register of specified
> PWM channel,
> >>  - prd_read  - reads value from period register of specified PWM channel,
> >>  - prd_write - writes value to period register of specified PWM channel.
> >> Driver code redesigned to use the new routines.
> >
> > Why don't you use regmap for that?
> 
> First of all, i'm newbie and its my first patchset. I just remake
> what i see in the driver. I even don't suspect about use regmap
> here.

Don't worry, a review is here to point where things could be better,
which doesn't mean that you did wrong :)

> Second thing - i can't test these driver on all existing sunxi SoCs,
> i have only A31 and A20 based boards where only pwm0 is
> accessible. Huge redesign cause bigger chance to make a mistake.

Don't worry about that either. We have a good number of platforms
using the PWMs already. If there's something broken at some point,
we'll catch it as well.

> If you think regmap solution is a must, then i will do that. This
> will be a good experience for me.

Yes, this really should cover what you're trying to do here,
especially reg_field.

You can have a look at drivers/reset/sti/reset-syscfg.c if you want to
have a look at a rather simple driver using it.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 1/4] ARM: pwm: sun4i: unification of register operations for support sun6i.
@ 2017-02-10  8:38         ` Maxime Ripard
  0 siblings, 0 replies; 26+ messages in thread
From: Maxime Ripard @ 2017-02-10  8:38 UTC (permalink / raw)
  To: Волков
	Сергей
  Cc: linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Thierry Reding,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
	Chen-Yu Tsai, linux-pwm-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

[-- Attachment #1: Type: text/plain, Size: 2346 bytes --]

Hi,

On Wed, Feb 08, 2017 at 07:41:55PM +0300, Волков Сергей wrote:
> Hello all,
> 
> >> This patch not introduce new features, just prepare code for
> >> adding sun6i PWM driver in next commits.
> >>
> >> A31 SoC have a different map of PWM registers than others ASoCs,
> >> but register bits purposes are very similar.
> >>
> >> This patch introduce set of register access routines, which
> >> are common for existing in driver ASoCs:
> >>  - ctl_rdy   - checks the ready bit of specified PWM channel,
> >>  - ctl_read  - reads value from control register of specified PWM
> channel,
> >>  - ctl_write - writes significant bits to control register of specified
> PWM channel,
> >>  - prd_read  - reads value from period register of specified PWM channel,
> >>  - prd_write - writes value to period register of specified PWM channel.
> >> Driver code redesigned to use the new routines.
> >
> > Why don't you use regmap for that?
> 
> First of all, i'm newbie and its my first patchset. I just remake
> what i see in the driver. I even don't suspect about use regmap
> here.

Don't worry, a review is here to point where things could be better,
which doesn't mean that you did wrong :)

> Second thing - i can't test these driver on all existing sunxi SoCs,
> i have only A31 and A20 based boards where only pwm0 is
> accessible. Huge redesign cause bigger chance to make a mistake.

Don't worry about that either. We have a good number of platforms
using the PWMs already. If there's something broken at some point,
we'll catch it as well.

> If you think regmap solution is a must, then i will do that. This
> will be a good experience for me.

Yes, this really should cover what you're trying to do here,
especially reg_field.

You can have a look at drivers/reset/sti/reset-syscfg.c if you want to
have a look at a rather simple driver using it.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

-- 
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH v2 1/4] ARM: pwm: sun4i: unification of register operations for support sun6i.
@ 2017-02-10  8:38         ` Maxime Ripard
  0 siblings, 0 replies; 26+ messages in thread
From: Maxime Ripard @ 2017-02-10  8:38 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On Wed, Feb 08, 2017 at 07:41:55PM +0300, ?????? ?????? wrote:
> Hello all,
> 
> >> This patch not introduce new features, just prepare code for
> >> adding sun6i PWM driver in next commits.
> >>
> >> A31 SoC have a different map of PWM registers than others ASoCs,
> >> but register bits purposes are very similar.
> >>
> >> This patch introduce set of register access routines, which
> >> are common for existing in driver ASoCs:
> >>  - ctl_rdy   - checks the ready bit of specified PWM channel,
> >>  - ctl_read  - reads value from control register of specified PWM
> channel,
> >>  - ctl_write - writes significant bits to control register of specified
> PWM channel,
> >>  - prd_read  - reads value from period register of specified PWM channel,
> >>  - prd_write - writes value to period register of specified PWM channel.
> >> Driver code redesigned to use the new routines.
> >
> > Why don't you use regmap for that?
> 
> First of all, i'm newbie and its my first patchset. I just remake
> what i see in the driver. I even don't suspect about use regmap
> here.

Don't worry, a review is here to point where things could be better,
which doesn't mean that you did wrong :)

> Second thing - i can't test these driver on all existing sunxi SoCs,
> i have only A31 and A20 based boards where only pwm0 is
> accessible. Huge redesign cause bigger chance to make a mistake.

Don't worry about that either. We have a good number of platforms
using the PWMs already. If there's something broken at some point,
we'll catch it as well.

> If you think regmap solution is a must, then i will do that. This
> will be a good experience for me.

Yes, this really should cover what you're trying to do here,
especially reg_field.

You can have a look at drivers/reset/sti/reset-syscfg.c if you want to
have a look at a rather simple driver using it.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20170210/12cba1ce/attachment.sig>

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 3/4] ARM: pwm: sun6i: add support the Allwinner A31 PWM.
  2017-02-07 17:50   ` lis8215-Re5JQEeQqe8AvxtiuMwx3w
@ 2017-02-15 22:16     ` Rob Herring
  -1 siblings, 0 replies; 26+ messages in thread
From: Rob Herring @ 2017-02-15 22:16 UTC (permalink / raw)
  To: lis8215
  Cc: linux-sunxi, thierry.reding, mark.rutland, maxime.ripard, wens,
	linux-pwm, devicetree, linux-arm-kernel, linux-kernel

On Tue, Feb 07, 2017 at 08:50:45PM +0300, lis8215@gmail.com wrote:
> From: Siarhei Volkau <lis8215@gmail.com>
> 
> This patch introduce the sun6i PWM driver itself:
>  - sun6i register operations,
>  - sun6i prescaler table,
>  - DT bindings for A31 SoC,
>  - documentation update.
> 
> Signed-off-by: Siarhei Volkau <lis8215@gmail.com>
> ---
>  .../devicetree/bindings/pwm/pwm-sun4i.txt          |  3 +-
>  drivers/pwm/pwm-sun4i.c                            | 71 ++++++++++++++++++++++
>  2 files changed, 73 insertions(+), 1 deletion(-)

Acked-by: Rob Herring <robh@kernel.org> 

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH v2 3/4] ARM: pwm: sun6i: add support the Allwinner A31 PWM.
@ 2017-02-15 22:16     ` Rob Herring
  0 siblings, 0 replies; 26+ messages in thread
From: Rob Herring @ 2017-02-15 22:16 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Feb 07, 2017 at 08:50:45PM +0300, lis8215 at gmail.com wrote:
> From: Siarhei Volkau <lis8215@gmail.com>
> 
> This patch introduce the sun6i PWM driver itself:
>  - sun6i register operations,
>  - sun6i prescaler table,
>  - DT bindings for A31 SoC,
>  - documentation update.
> 
> Signed-off-by: Siarhei Volkau <lis8215@gmail.com>
> ---
>  .../devicetree/bindings/pwm/pwm-sun4i.txt          |  3 +-
>  drivers/pwm/pwm-sun4i.c                            | 71 ++++++++++++++++++++++
>  2 files changed, 73 insertions(+), 1 deletion(-)

Acked-by: Rob Herring <robh@kernel.org> 

^ permalink raw reply	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2017-02-15 22:16 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-02-07 17:50 [PATCH v2 0/4] Add the Allwinner A31/A31s PWM driver lis8215
2017-02-07 17:50 ` lis8215 at gmail.com
2017-02-07 17:50 ` lis8215-Re5JQEeQqe8AvxtiuMwx3w
2017-02-07 17:50 ` [PATCH v2 1/4] ARM: pwm: sun4i: unification of register operations for support sun6i lis8215
2017-02-07 17:50   ` lis8215 at gmail.com
2017-02-07 17:50   ` lis8215-Re5JQEeQqe8AvxtiuMwx3w
2017-02-08  7:52   ` Maxime Ripard
2017-02-08  7:52     ` Maxime Ripard
2017-02-08  7:52     ` Maxime Ripard
2017-02-08 16:41     ` Волков Сергей
2017-02-10  8:38       ` Maxime Ripard
2017-02-10  8:38         ` Maxime Ripard
2017-02-10  8:38         ` Maxime Ripard
2017-02-07 17:50 ` [PATCH v2 2/4] ARM: pwm: sun4i: selectable prescaler table " lis8215
2017-02-07 17:50   ` lis8215 at gmail.com
2017-02-07 17:50 ` [PATCH v2 3/4] ARM: pwm: sun6i: add support the Allwinner A31 PWM lis8215
2017-02-07 17:50   ` lis8215 at gmail.com
2017-02-07 17:50   ` lis8215-Re5JQEeQqe8AvxtiuMwx3w
2017-02-08  7:53   ` Maxime Ripard
2017-02-08  7:53     ` Maxime Ripard
2017-02-08  7:53     ` Maxime Ripard
2017-02-15 22:16   ` Rob Herring
2017-02-15 22:16     ` Rob Herring
2017-02-07 17:50 ` [PATCH v2 4/4] ARM: dts: sun6i: Add the PWM block to the A31/A31s lis8215
2017-02-07 17:50   ` lis8215 at gmail.com
2017-02-07 17:50   ` lis8215-Re5JQEeQqe8AvxtiuMwx3w

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.