All of lore.kernel.org
 help / color / mirror / Atom feed
* pwm: imx: support output polarity inversion
@ 2014-03-19 13:22 Lothar Waßmann
  2014-03-19 13:22 ` [PATCHv3 1/3] pwm: make the PWM_POLARITY flag in DTB optional Lothar Waßmann
                   ` (3 more replies)
  0 siblings, 4 replies; 19+ messages in thread
From: Lothar Waßmann @ 2014-03-19 13:22 UTC (permalink / raw)
  To: Thierry Reding, linux-kernel, linux-pwm, Lothar Waßmann

This patch series adds support for polarity inversion to the pwm-imx
driver. 

Changes wrt. v2:
- make the use of '#pwm-cells = <3>' optional, so that the change does
  not break existing DT blobs as suggested by Arnd Bergmann and Sascha
  Hauer.


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

* [PATCHv3 1/3] pwm: make the PWM_POLARITY flag in DTB optional
  2014-03-19 13:22 pwm: imx: support output polarity inversion Lothar Waßmann
@ 2014-03-19 13:22 ` Lothar Waßmann
  2014-03-19 13:22 ` [PATCHv3 2/3] pwm: imx: indentation cleanup Lothar Waßmann
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 19+ messages in thread
From: Lothar Waßmann @ 2014-03-19 13:22 UTC (permalink / raw)
  To: Thierry Reding, linux-kernel, linux-pwm, Lothar Waßmann

Change the pwm chip driver registration, so that a chip driver that
supports polarity inversion can still be used with DTBs that don't
provide the 'PWM_POLARITY' flag.

This is done to provide polarity inversion support for the pwm-imx
driver without having to modify all existing DTS files.

Signed-off-by: Lothar Waßmann <LW@KARO-electronics.de>
---
 drivers/pwm/core.c |   46 ++++++++++++++++------------------------------
 1 file changed, 16 insertions(+), 30 deletions(-)

diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index a804713..dc15543 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -131,12 +131,12 @@ static int pwm_device_request(struct pwm_device *pwm, const char *label)
 	return 0;
 }
 
-struct pwm_device *
-of_pwm_xlate_with_flags(struct pwm_chip *pc, const struct of_phandle_args *args)
+struct pwm_device *of_pwm_xlate(struct pwm_chip *pc,
+				const struct of_phandle_args *args)
 {
 	struct pwm_device *pwm;
 
-	if (pc->of_pwm_n_cells < 3)
+	if (pc->of_pwm_n_cells < 2)
 		return ERR_PTR(-EINVAL);
 
 	if (args->args[0] >= pc->npwm)
@@ -148,6 +148,9 @@ of_pwm_xlate_with_flags(struct pwm_chip *pc, const struct of_phandle_args *args)
 
 	pwm_set_period(pwm, args->args[1]);
 
+	if (pc->of_pwm_n_cells < 3)
+		return pwm;
+
 	if (args->args[2] & PWM_POLARITY_INVERTED)
 		pwm_set_polarity(pwm, PWM_POLARITY_INVERSED);
 	else
@@ -155,27 +158,14 @@ of_pwm_xlate_with_flags(struct pwm_chip *pc, const struct of_phandle_args *args)
 
 	return pwm;
 }
-EXPORT_SYMBOL_GPL(of_pwm_xlate_with_flags);
 
-static struct pwm_device *
-of_pwm_simple_xlate(struct pwm_chip *pc, const struct of_phandle_args *args)
+struct pwm_device *
+of_pwm_xlate_with_flags(struct pwm_chip *pc,
+			const struct of_phandle_args *args)
 {
-	struct pwm_device *pwm;
-
-	if (pc->of_pwm_n_cells < 2)
-		return ERR_PTR(-EINVAL);
-
-	if (args->args[0] >= pc->npwm)
-		return ERR_PTR(-EINVAL);
-
-	pwm = pwm_request_from_chip(pc, args->args[0], NULL);
-	if (IS_ERR(pwm))
-		return pwm;
-
-	pwm_set_period(pwm, args->args[1]);
-
-	return pwm;
+	return of_pwm_xlate(pc, args);
 }
+EXPORT_SYMBOL_GPL(of_pwm_xlate_with_flags);
 
 static void of_pwmchip_add(struct pwm_chip *chip)
 {
@@ -183,8 +173,11 @@ static void of_pwmchip_add(struct pwm_chip *chip)
 		return;
 
 	if (!chip->of_xlate) {
-		chip->of_xlate = of_pwm_simple_xlate;
-		chip->of_pwm_n_cells = 2;
+		chip->of_xlate = of_pwm_xlate;
+		if (chip->ops->set_polarity)
+			chip->of_pwm_n_cells = 3;
+		else
+			chip->of_pwm_n_cells = 2;
 	}
 
 	of_node_get(chip->dev->of_node);
@@ -536,13 +529,6 @@ struct pwm_device *of_pwm_get(struct device_node *np, const char *con_id)
 		goto put;
 	}
 
-	if (args.args_count != pc->of_pwm_n_cells) {
-		pr_debug("%s: wrong #pwm-cells for %s\n", np->full_name,
-			 args.np->full_name);
-		pwm = ERR_PTR(-EINVAL);
-		goto put;
-	}
-
 	pwm = pc->of_xlate(pc, &args);
 	if (IS_ERR(pwm))
 		goto put;
-- 
1.7.10.4


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

* [PATCHv3 2/3] pwm: imx: indentation cleanup
  2014-03-19 13:22 pwm: imx: support output polarity inversion Lothar Waßmann
  2014-03-19 13:22 ` [PATCHv3 1/3] pwm: make the PWM_POLARITY flag in DTB optional Lothar Waßmann
@ 2014-03-19 13:22 ` Lothar Waßmann
  2014-03-19 13:22 ` [PATCHv3 3/3] pwm: imx: support output polarity inversion Lothar Waßmann
  2014-03-28  8:48 ` [PATCHv3 0/3] " Lothar Waßmann
  3 siblings, 0 replies; 19+ messages in thread
From: Lothar Waßmann @ 2014-03-19 13:22 UTC (permalink / raw)
  To: Thierry Reding, linux-kernel, linux-pwm, Lothar Waßmann


Signed-off-by: Lothar Waßmann <LW@KARO-electronics.de>
---
 drivers/pwm/pwm-imx.c |   21 +++++++++++----------
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/pwm/pwm-imx.c b/drivers/pwm/pwm-imx.c
index cc47733..52aac5e 100644
--- a/drivers/pwm/pwm-imx.c
+++ b/drivers/pwm/pwm-imx.c
@@ -25,20 +25,21 @@
 #define MX1_PWMS    0x04   /* PWM Sample Register */
 #define MX1_PWMP    0x08   /* PWM Period Register */
 
-#define MX1_PWMC_EN		(1 << 4)
+#define MX1_PWMC_EN			(1 << 4)
 
 /* i.MX27, i.MX31, i.MX35 share the same PWM function block: */
 
-#define MX3_PWMCR                 0x00    /* PWM Control Register */
-#define MX3_PWMSAR                0x0C    /* PWM Sample Register */
-#define MX3_PWMPR                 0x10    /* PWM Period Register */
-#define MX3_PWMCR_PRESCALER(x)    (((x - 1) & 0xFFF) << 4)
-#define MX3_PWMCR_DOZEEN                (1 << 24)
-#define MX3_PWMCR_WAITEN                (1 << 23)
+#define MX3_PWMCR			0x00	  /* PWM Control Register */
+#define MX3_PWMSAR			0x0C	  /* PWM Sample Register */
+#define MX3_PWMPR			0x10	  /* PWM Period Register */
+#define MX3_PWMCR_PRESCALER(x)		((((x) - 1) & 0xFFF) << 4)
+#define MX3_PWMCR_DOZEEN		(1 << 24)
+#define MX3_PWMCR_WAITEN		(1 << 23)
 #define MX3_PWMCR_DBGEN			(1 << 22)
-#define MX3_PWMCR_CLKSRC_IPG_HIGH (2 << 16)
-#define MX3_PWMCR_CLKSRC_IPG      (1 << 16)
-#define MX3_PWMCR_EN              (1 << 0)
+#define MX3_PWMCR_POUTC			(1 << 18)
+#define MX3_PWMCR_CLKSRC_IPG_HIGH	(2 << 16)
+#define MX3_PWMCR_CLKSRC_IPG		(1 << 16)
+#define MX3_PWMCR_EN			(1 << 0)
 
 struct imx_chip {
 	struct clk	*clk_per;
-- 
1.7.10.4


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

* [PATCHv3 3/3] pwm: imx: support output polarity inversion
  2014-03-19 13:22 pwm: imx: support output polarity inversion Lothar Waßmann
  2014-03-19 13:22 ` [PATCHv3 1/3] pwm: make the PWM_POLARITY flag in DTB optional Lothar Waßmann
  2014-03-19 13:22 ` [PATCHv3 2/3] pwm: imx: indentation cleanup Lothar Waßmann
@ 2014-03-19 13:22 ` Lothar Waßmann
  2014-03-28  8:48 ` [PATCHv3 0/3] " Lothar Waßmann
  3 siblings, 0 replies; 19+ messages in thread
From: Lothar Waßmann @ 2014-03-19 13:22 UTC (permalink / raw)
  To: Thierry Reding, linux-kernel, linux-pwm, Lothar Waßmann

The i.MX pwm unit on i.MX27 and newer SoCs provides a configurable
output polarity. This patch adds support to utilize this feature where
available.

Signed-off-by: Lothar Waßmann <LW@KARO-electronics.de>
---
 drivers/pwm/pwm-imx.c |   25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/drivers/pwm/pwm-imx.c b/drivers/pwm/pwm-imx.c
index 52aac5e..a43410a 100644
--- a/drivers/pwm/pwm-imx.c
+++ b/drivers/pwm/pwm-imx.c
@@ -138,6 +138,8 @@ static int imx_pwm_config_v2(struct pwm_chip *chip,
 
 	if (test_bit(PWMF_ENABLED, &pwm->flags))
 		cr |= MX3_PWMCR_EN;
+	if (pwm->polarity == PWM_POLARITY_INVERSED)
+		cr |= MX3_PWMCR_POUTC;
 
 	writel(cr, imx->mmio_base + MX3_PWMCR);
 
@@ -156,6 +158,11 @@ static void imx_pwm_set_enable_v2(struct pwm_chip *chip, bool enable)
 	else
 		val &= ~MX3_PWMCR_EN;
 
+	if (chip->pwms[0].polarity == PWM_POLARITY_INVERSED)
+		val |= MX3_PWMCR_POUTC;
+	else
+		val &= ~MX3_PWMCR_POUTC;
+
 	writel(val, imx->mmio_base + MX3_PWMCR);
 }
 
@@ -199,6 +206,17 @@ static void imx_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
 	clk_disable_unprepare(imx->clk_per);
 }
 
+static int imx_pwm_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm,
+				enum pwm_polarity polarity)
+{
+	struct imx_chip *imx = to_imx_chip(chip);
+
+	dev_dbg(imx->chip.dev, "%s: polarity set to %s\n", __func__,
+		polarity == PWM_POLARITY_INVERSED ? "inverted" : "normal");
+
+	return 0;
+}
+
 static struct pwm_ops imx_pwm_ops = {
 	.enable = imx_pwm_enable,
 	.disable = imx_pwm_disable,
@@ -210,6 +228,7 @@ struct imx_pwm_data {
 	int (*config)(struct pwm_chip *chip,
 		struct pwm_device *pwm, int duty_ns, int period_ns);
 	void (*set_enable)(struct pwm_chip *chip, bool enable);
+	unsigned output_polarity:1;
 };
 
 static struct imx_pwm_data imx_pwm_data_v1 = {
@@ -220,6 +239,7 @@ static struct imx_pwm_data imx_pwm_data_v1 = {
 static struct imx_pwm_data imx_pwm_data_v2 = {
 	.config = imx_pwm_config_v2,
 	.set_enable = imx_pwm_set_enable_v2,
+	.output_polarity = 1,
 };
 
 static const struct of_device_id imx_pwm_dt_ids[] = {
@@ -272,6 +292,11 @@ static int imx_pwm_probe(struct platform_device *pdev)
 		return PTR_ERR(imx->mmio_base);
 
 	data = of_id->data;
+	if (data->output_polarity) {
+		dev_dbg(&pdev->dev, "PWM supports output inversion\n");
+		imx_pwm_ops.set_polarity = imx_pwm_set_polarity;
+	}
+
 	imx->config = data->config;
 	imx->set_enable = data->set_enable;
 
-- 
1.7.10.4


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

* [PATCHv3 0/3] pwm: imx: support output polarity inversion
  2014-03-19 13:22 pwm: imx: support output polarity inversion Lothar Waßmann
                   ` (2 preceding siblings ...)
  2014-03-19 13:22 ` [PATCHv3 3/3] pwm: imx: support output polarity inversion Lothar Waßmann
@ 2014-03-28  8:48 ` Lothar Waßmann
  2014-03-28  8:48   ` [PATCHv3 1/3] pwm: make the PWM_POLARITY flag in DTB optional Lothar Waßmann
                     ` (2 more replies)
  3 siblings, 3 replies; 19+ messages in thread
From: Lothar Waßmann @ 2014-03-28  8:48 UTC (permalink / raw)
  To: Thierry Reding, linux-kernel, linux-pwm, Lothar Waßmann,
	Shawn Guo, Sascha Hauer, Arnd Bergmann

This patch series adds support for polarity inversion to the pwm-imx
driver. 

Changes wrt. v2:
- make the use of '#pwm-cells = <3>' optional, so that the change does
  not break existing DT blobs as suggested by Arnd Bergmann and Sascha
  Hauer.


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

* [PATCHv3 1/3] pwm: make the PWM_POLARITY flag in DTB optional
  2014-03-28  8:48 ` [PATCHv3 0/3] " Lothar Waßmann
@ 2014-03-28  8:48   ` Lothar Waßmann
  2014-04-02  5:53     ` Sascha Hauer
  2014-03-28  8:48   ` [PATCHv3 2/3] pwm: imx: indentation cleanup Lothar Waßmann
  2014-03-28  8:49   ` [PATCHv3 3/3] pwm: imx: support output polarity inversion Lothar Waßmann
  2 siblings, 1 reply; 19+ messages in thread
From: Lothar Waßmann @ 2014-03-28  8:48 UTC (permalink / raw)
  To: Thierry Reding, linux-kernel, linux-pwm, Lothar Waßmann,
	Shawn Guo, Sascha Hauer, Arnd Bergmann

Change the pwm chip driver registration, so that a chip driver that
supports polarity inversion can still be used with DTBs that don't
provide the 'PWM_POLARITY' flag.

This is done to provide polarity inversion support for the pwm-imx
driver without having to modify all existing DTS files.

Signed-off-by: Lothar Waßmann <LW@KARO-electronics.de>
---
 drivers/pwm/core.c |   46 ++++++++++++++++------------------------------
 1 file changed, 16 insertions(+), 30 deletions(-)

diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index a804713..dc15543 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -131,12 +131,12 @@ static int pwm_device_request(struct pwm_device *pwm, const char *label)
 	return 0;
 }
 
-struct pwm_device *
-of_pwm_xlate_with_flags(struct pwm_chip *pc, const struct of_phandle_args *args)
+struct pwm_device *of_pwm_xlate(struct pwm_chip *pc,
+				const struct of_phandle_args *args)
 {
 	struct pwm_device *pwm;
 
-	if (pc->of_pwm_n_cells < 3)
+	if (pc->of_pwm_n_cells < 2)
 		return ERR_PTR(-EINVAL);
 
 	if (args->args[0] >= pc->npwm)
@@ -148,6 +148,9 @@ of_pwm_xlate_with_flags(struct pwm_chip *pc, const struct of_phandle_args *args)
 
 	pwm_set_period(pwm, args->args[1]);
 
+	if (pc->of_pwm_n_cells < 3)
+		return pwm;
+
 	if (args->args[2] & PWM_POLARITY_INVERTED)
 		pwm_set_polarity(pwm, PWM_POLARITY_INVERSED);
 	else
@@ -155,27 +158,14 @@ of_pwm_xlate_with_flags(struct pwm_chip *pc, const struct of_phandle_args *args)
 
 	return pwm;
 }
-EXPORT_SYMBOL_GPL(of_pwm_xlate_with_flags);
 
-static struct pwm_device *
-of_pwm_simple_xlate(struct pwm_chip *pc, const struct of_phandle_args *args)
+struct pwm_device *
+of_pwm_xlate_with_flags(struct pwm_chip *pc,
+			const struct of_phandle_args *args)
 {
-	struct pwm_device *pwm;
-
-	if (pc->of_pwm_n_cells < 2)
-		return ERR_PTR(-EINVAL);
-
-	if (args->args[0] >= pc->npwm)
-		return ERR_PTR(-EINVAL);
-
-	pwm = pwm_request_from_chip(pc, args->args[0], NULL);
-	if (IS_ERR(pwm))
-		return pwm;
-
-	pwm_set_period(pwm, args->args[1]);
-
-	return pwm;
+	return of_pwm_xlate(pc, args);
 }
+EXPORT_SYMBOL_GPL(of_pwm_xlate_with_flags);
 
 static void of_pwmchip_add(struct pwm_chip *chip)
 {
@@ -183,8 +173,11 @@ static void of_pwmchip_add(struct pwm_chip *chip)
 		return;
 
 	if (!chip->of_xlate) {
-		chip->of_xlate = of_pwm_simple_xlate;
-		chip->of_pwm_n_cells = 2;
+		chip->of_xlate = of_pwm_xlate;
+		if (chip->ops->set_polarity)
+			chip->of_pwm_n_cells = 3;
+		else
+			chip->of_pwm_n_cells = 2;
 	}
 
 	of_node_get(chip->dev->of_node);
@@ -536,13 +529,6 @@ struct pwm_device *of_pwm_get(struct device_node *np, const char *con_id)
 		goto put;
 	}
 
-	if (args.args_count != pc->of_pwm_n_cells) {
-		pr_debug("%s: wrong #pwm-cells for %s\n", np->full_name,
-			 args.np->full_name);
-		pwm = ERR_PTR(-EINVAL);
-		goto put;
-	}
-
 	pwm = pc->of_xlate(pc, &args);
 	if (IS_ERR(pwm))
 		goto put;
-- 
1.7.10.4


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

* [PATCHv3 2/3] pwm: imx: indentation cleanup
  2014-03-28  8:48 ` [PATCHv3 0/3] " Lothar Waßmann
  2014-03-28  8:48   ` [PATCHv3 1/3] pwm: make the PWM_POLARITY flag in DTB optional Lothar Waßmann
@ 2014-03-28  8:48   ` Lothar Waßmann
  2014-03-28  8:49   ` [PATCHv3 3/3] pwm: imx: support output polarity inversion Lothar Waßmann
  2 siblings, 0 replies; 19+ messages in thread
From: Lothar Waßmann @ 2014-03-28  8:48 UTC (permalink / raw)
  To: Thierry Reding, linux-kernel, linux-pwm, Lothar Waßmann,
	Shawn Guo, Sascha Hauer, Arnd Bergmann


Signed-off-by: Lothar Waßmann <LW@KARO-electronics.de>
---
 drivers/pwm/pwm-imx.c |   21 +++++++++++----------
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/pwm/pwm-imx.c b/drivers/pwm/pwm-imx.c
index cc47733..52aac5e 100644
--- a/drivers/pwm/pwm-imx.c
+++ b/drivers/pwm/pwm-imx.c
@@ -25,20 +25,21 @@
 #define MX1_PWMS    0x04   /* PWM Sample Register */
 #define MX1_PWMP    0x08   /* PWM Period Register */
 
-#define MX1_PWMC_EN		(1 << 4)
+#define MX1_PWMC_EN			(1 << 4)
 
 /* i.MX27, i.MX31, i.MX35 share the same PWM function block: */
 
-#define MX3_PWMCR                 0x00    /* PWM Control Register */
-#define MX3_PWMSAR                0x0C    /* PWM Sample Register */
-#define MX3_PWMPR                 0x10    /* PWM Period Register */
-#define MX3_PWMCR_PRESCALER(x)    (((x - 1) & 0xFFF) << 4)
-#define MX3_PWMCR_DOZEEN                (1 << 24)
-#define MX3_PWMCR_WAITEN                (1 << 23)
+#define MX3_PWMCR			0x00	  /* PWM Control Register */
+#define MX3_PWMSAR			0x0C	  /* PWM Sample Register */
+#define MX3_PWMPR			0x10	  /* PWM Period Register */
+#define MX3_PWMCR_PRESCALER(x)		((((x) - 1) & 0xFFF) << 4)
+#define MX3_PWMCR_DOZEEN		(1 << 24)
+#define MX3_PWMCR_WAITEN		(1 << 23)
 #define MX3_PWMCR_DBGEN			(1 << 22)
-#define MX3_PWMCR_CLKSRC_IPG_HIGH (2 << 16)
-#define MX3_PWMCR_CLKSRC_IPG      (1 << 16)
-#define MX3_PWMCR_EN              (1 << 0)
+#define MX3_PWMCR_POUTC			(1 << 18)
+#define MX3_PWMCR_CLKSRC_IPG_HIGH	(2 << 16)
+#define MX3_PWMCR_CLKSRC_IPG		(1 << 16)
+#define MX3_PWMCR_EN			(1 << 0)
 
 struct imx_chip {
 	struct clk	*clk_per;
-- 
1.7.10.4


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

* [PATCHv3 3/3] pwm: imx: support output polarity inversion
  2014-03-28  8:48 ` [PATCHv3 0/3] " Lothar Waßmann
  2014-03-28  8:48   ` [PATCHv3 1/3] pwm: make the PWM_POLARITY flag in DTB optional Lothar Waßmann
  2014-03-28  8:48   ` [PATCHv3 2/3] pwm: imx: indentation cleanup Lothar Waßmann
@ 2014-03-28  8:49   ` Lothar Waßmann
  2014-04-02  5:45     ` Sascha Hauer
  2 siblings, 1 reply; 19+ messages in thread
From: Lothar Waßmann @ 2014-03-28  8:49 UTC (permalink / raw)
  To: Thierry Reding, linux-kernel, linux-pwm, Lothar Waßmann,
	Shawn Guo, Sascha Hauer, Arnd Bergmann

The i.MX pwm unit on i.MX27 and newer SoCs provides a configurable
output polarity. This patch adds support to utilize this feature where
available.

Signed-off-by: Lothar Waßmann <LW@KARO-electronics.de>
---
 drivers/pwm/pwm-imx.c |   25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/drivers/pwm/pwm-imx.c b/drivers/pwm/pwm-imx.c
index 52aac5e..a43410a 100644
--- a/drivers/pwm/pwm-imx.c
+++ b/drivers/pwm/pwm-imx.c
@@ -138,6 +138,8 @@ static int imx_pwm_config_v2(struct pwm_chip *chip,
 
 	if (test_bit(PWMF_ENABLED, &pwm->flags))
 		cr |= MX3_PWMCR_EN;
+	if (pwm->polarity == PWM_POLARITY_INVERSED)
+		cr |= MX3_PWMCR_POUTC;
 
 	writel(cr, imx->mmio_base + MX3_PWMCR);
 
@@ -156,6 +158,11 @@ static void imx_pwm_set_enable_v2(struct pwm_chip *chip, bool enable)
 	else
 		val &= ~MX3_PWMCR_EN;
 
+	if (chip->pwms[0].polarity == PWM_POLARITY_INVERSED)
+		val |= MX3_PWMCR_POUTC;
+	else
+		val &= ~MX3_PWMCR_POUTC;
+
 	writel(val, imx->mmio_base + MX3_PWMCR);
 }
 
@@ -199,6 +206,17 @@ static void imx_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
 	clk_disable_unprepare(imx->clk_per);
 }
 
+static int imx_pwm_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm,
+				enum pwm_polarity polarity)
+{
+	struct imx_chip *imx = to_imx_chip(chip);
+
+	dev_dbg(imx->chip.dev, "%s: polarity set to %s\n", __func__,
+		polarity == PWM_POLARITY_INVERSED ? "inverted" : "normal");
+
+	return 0;
+}
+
 static struct pwm_ops imx_pwm_ops = {
 	.enable = imx_pwm_enable,
 	.disable = imx_pwm_disable,
@@ -210,6 +228,7 @@ struct imx_pwm_data {
 	int (*config)(struct pwm_chip *chip,
 		struct pwm_device *pwm, int duty_ns, int period_ns);
 	void (*set_enable)(struct pwm_chip *chip, bool enable);
+	unsigned output_polarity:1;
 };
 
 static struct imx_pwm_data imx_pwm_data_v1 = {
@@ -220,6 +239,7 @@ static struct imx_pwm_data imx_pwm_data_v1 = {
 static struct imx_pwm_data imx_pwm_data_v2 = {
 	.config = imx_pwm_config_v2,
 	.set_enable = imx_pwm_set_enable_v2,
+	.output_polarity = 1,
 };
 
 static const struct of_device_id imx_pwm_dt_ids[] = {
@@ -272,6 +292,11 @@ static int imx_pwm_probe(struct platform_device *pdev)
 		return PTR_ERR(imx->mmio_base);
 
 	data = of_id->data;
+	if (data->output_polarity) {
+		dev_dbg(&pdev->dev, "PWM supports output inversion\n");
+		imx_pwm_ops.set_polarity = imx_pwm_set_polarity;
+	}
+
 	imx->config = data->config;
 	imx->set_enable = data->set_enable;
 
-- 
1.7.10.4


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

* Re: [PATCHv3 3/3] pwm: imx: support output polarity inversion
  2014-03-28  8:49   ` [PATCHv3 3/3] pwm: imx: support output polarity inversion Lothar Waßmann
@ 2014-04-02  5:45     ` Sascha Hauer
  0 siblings, 0 replies; 19+ messages in thread
From: Sascha Hauer @ 2014-04-02  5:45 UTC (permalink / raw)
  To: Lothar Waßmann
  Cc: Thierry Reding, linux-kernel, linux-pwm, Shawn Guo, Sascha Hauer,
	Arnd Bergmann

Hi Lothar,

On Fri, Mar 28, 2014 at 09:49:00AM +0100, Lothar Waßmann wrote:
>  static struct pwm_ops imx_pwm_ops = {
>  	.enable = imx_pwm_enable,
>  	.disable = imx_pwm_disable,
> @@ -210,6 +228,7 @@ struct imx_pwm_data {
>  	int (*config)(struct pwm_chip *chip,
>  		struct pwm_device *pwm, int duty_ns, int period_ns);
>  	void (*set_enable)(struct pwm_chip *chip, bool enable);
> +	unsigned output_polarity:1;
>  };
>  
>  static struct imx_pwm_data imx_pwm_data_v1 = {
> @@ -220,6 +239,7 @@ static struct imx_pwm_data imx_pwm_data_v1 = {
>  static struct imx_pwm_data imx_pwm_data_v2 = {
>  	.config = imx_pwm_config_v2,
>  	.set_enable = imx_pwm_set_enable_v2,
> +	.output_polarity = 1,
>  };
>  
>  static const struct of_device_id imx_pwm_dt_ids[] = {
> @@ -272,6 +292,11 @@ static int imx_pwm_probe(struct platform_device *pdev)
>  		return PTR_ERR(imx->mmio_base);
>  
>  	data = of_id->data;
> +	if (data->output_polarity) {
> +		dev_dbg(&pdev->dev, "PWM supports output inversion\n");
> +		imx_pwm_ops.set_polarity = imx_pwm_set_polarity;
> +	}

You shouldn't modify imx_pwm_ops in the probe function, it's not good
style and prevents us from making the ops const.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

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

* Re: [PATCHv3 1/3] pwm: make the PWM_POLARITY flag in DTB optional
  2014-03-28  8:48   ` [PATCHv3 1/3] pwm: make the PWM_POLARITY flag in DTB optional Lothar Waßmann
@ 2014-04-02  5:53     ` Sascha Hauer
  2014-04-07 11:36       ` Thierry Reding
  0 siblings, 1 reply; 19+ messages in thread
From: Sascha Hauer @ 2014-04-02  5:53 UTC (permalink / raw)
  To: Lothar Waßmann
  Cc: Thierry Reding, linux-kernel, linux-pwm, Shawn Guo, Sascha Hauer,
	Arnd Bergmann

On Fri, Mar 28, 2014 at 09:48:58AM +0100, Lothar Waßmann wrote:
> Change the pwm chip driver registration, so that a chip driver that
> supports polarity inversion can still be used with DTBs that don't
> provide the 'PWM_POLARITY' flag.
> 
> This is done to provide polarity inversion support for the pwm-imx
> driver without having to modify all existing DTS files.
> 
> Signed-off-by: Lothar Waßmann <LW@KARO-electronics.de>
> ---
>  drivers/pwm/core.c |   46 ++++++++++++++++------------------------------
>  1 file changed, 16 insertions(+), 30 deletions(-)
> diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
> index a804713..dc15543 100644
> --- a/drivers/pwm/core.c
> +++ b/drivers/pwm/core.c
> @@ -131,12 +131,12 @@ static int pwm_device_request(struct pwm_device *pwm, const char *label)
>  	return 0;
>  }
>  
> -struct pwm_device *
> -of_pwm_xlate_with_flags(struct pwm_chip *pc, const struct of_phandle_args *args)
> +struct pwm_device *of_pwm_xlate(struct pwm_chip *pc,
> +				const struct of_phandle_args *args)
>  {
>  	struct pwm_device *pwm;
>  
> -	if (pc->of_pwm_n_cells < 3)
> +	if (pc->of_pwm_n_cells < 2)
>  		return ERR_PTR(-EINVAL);
>  
>  	if (args->args[0] >= pc->npwm)
> @@ -148,6 +148,9 @@ of_pwm_xlate_with_flags(struct pwm_chip *pc, const struct of_phandle_args *args)
>  
>  	pwm_set_period(pwm, args->args[1]);
>  
> +	if (pc->of_pwm_n_cells < 3)
> +		return pwm;
> +
>  	if (args->args[2] & PWM_POLARITY_INVERTED)
>  		pwm_set_polarity(pwm, PWM_POLARITY_INVERSED);
>  	else
> @@ -155,27 +158,14 @@ of_pwm_xlate_with_flags(struct pwm_chip *pc, const struct of_phandle_args *args)
>  
>  	return pwm;
>  }
> -EXPORT_SYMBOL_GPL(of_pwm_xlate_with_flags);
>  
> -static struct pwm_device *
> -of_pwm_simple_xlate(struct pwm_chip *pc, const struct of_phandle_args *args)
> +struct pwm_device *
> +of_pwm_xlate_with_flags(struct pwm_chip *pc,
> +			const struct of_phandle_args *args)
>  {
> -	struct pwm_device *pwm;
> -
> -	if (pc->of_pwm_n_cells < 2)
> -		return ERR_PTR(-EINVAL);
> -
> -	if (args->args[0] >= pc->npwm)
> -		return ERR_PTR(-EINVAL);
> -
> -	pwm = pwm_request_from_chip(pc, args->args[0], NULL);
> -	if (IS_ERR(pwm))
> -		return pwm;
> -
> -	pwm_set_period(pwm, args->args[1]);
> -
> -	return pwm;
> +	return of_pwm_xlate(pc, args);
>  }
> +EXPORT_SYMBOL_GPL(of_pwm_xlate_with_flags);
>  
>  static void of_pwmchip_add(struct pwm_chip *chip)
>  {
> @@ -183,8 +173,11 @@ static void of_pwmchip_add(struct pwm_chip *chip)
>  		return;
>  
>  	if (!chip->of_xlate) {
> -		chip->of_xlate = of_pwm_simple_xlate;
> -		chip->of_pwm_n_cells = 2;
> +		chip->of_xlate = of_pwm_xlate;
> +		if (chip->ops->set_polarity)
> +			chip->of_pwm_n_cells = 3;
> +		else
> +			chip->of_pwm_n_cells = 2;

I think the presence of the set_polarity callback shouldn't influence
the number of cells the parser expects. As commented on 2/2 this doesn't
actually mean the device actually support polarity inversion. Also,
polarity inversion could still be done in software for hardware that
doesn't support it.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

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

* Re: [PATCHv3 1/3] pwm: make the PWM_POLARITY flag in DTB optional
  2014-04-02  5:53     ` Sascha Hauer
@ 2014-04-07 11:36       ` Thierry Reding
  2014-04-08  5:02         ` Lothar Waßmann
  0 siblings, 1 reply; 19+ messages in thread
From: Thierry Reding @ 2014-04-07 11:36 UTC (permalink / raw)
  To: Sascha Hauer
  Cc: Lothar Waßmann, linux-kernel, linux-pwm, Shawn Guo,
	Sascha Hauer, Arnd Bergmann

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

On Wed, Apr 02, 2014 at 07:53:50AM +0200, Sascha Hauer wrote:
> On Fri, Mar 28, 2014 at 09:48:58AM +0100, Lothar Waßmann wrote:
[...]
> > @@ -183,8 +173,11 @@ static void of_pwmchip_add(struct pwm_chip *chip)
> >  		return;
> >  
> >  	if (!chip->of_xlate) {
> > -		chip->of_xlate = of_pwm_simple_xlate;
> > -		chip->of_pwm_n_cells = 2;
> > +		chip->of_xlate = of_pwm_xlate;
> > +		if (chip->ops->set_polarity)
> > +			chip->of_pwm_n_cells = 3;
> > +		else
> > +			chip->of_pwm_n_cells = 2;
> 
> I think the presence of the set_polarity callback shouldn't influence
> the number of cells the parser expects. As commented on 2/2 this doesn't
> actually mean the device actually support polarity inversion.

How so? A driver should only implement .set_polarity() if it supports
changing the polarity.

That said, I agree that the presence of .set_polarity() shouldn't
determine the number of cells. You could have any number of other flags
set via the third cell.

> Also, polarity inversion could still be done in software for hardware
> that doesn't support it.

No. You cannot emulate polarity inversion in software.

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

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

* Re: [PATCHv3 1/3] pwm: make the PWM_POLARITY flag in DTB optional
  2014-04-07 11:36       ` Thierry Reding
@ 2014-04-08  5:02         ` Lothar Waßmann
  2014-04-08 20:37           ` Tim Kryger
  2014-04-08 20:43           ` Tim Kryger
  0 siblings, 2 replies; 19+ messages in thread
From: Lothar Waßmann @ 2014-04-08  5:02 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Sascha Hauer, linux-kernel, linux-pwm, Shawn Guo, Sascha Hauer,
	Arnd Bergmann

Hi,

Thierry Reding wrote:
> On Wed, Apr 02, 2014 at 07:53:50AM +0200, Sascha Hauer wrote:
> > On Fri, Mar 28, 2014 at 09:48:58AM +0100, Lothar Waßmann wrote:
> [...]
> > > @@ -183,8 +173,11 @@ static void of_pwmchip_add(struct pwm_chip *chip)
> > >  		return;
> > >  
> > >  	if (!chip->of_xlate) {
> > > -		chip->of_xlate = of_pwm_simple_xlate;
> > > -		chip->of_pwm_n_cells = 2;
> > > +		chip->of_xlate = of_pwm_xlate;
> > > +		if (chip->ops->set_polarity)
> > > +			chip->of_pwm_n_cells = 3;
> > > +		else
> > > +			chip->of_pwm_n_cells = 2;
> > 
> > I think the presence of the set_polarity callback shouldn't influence
> > the number of cells the parser expects. As commented on 2/2 this doesn't
> > actually mean the device actually support polarity inversion.
> 
> How so? A driver should only implement .set_polarity() if it supports
> changing the polarity.
> 
> That said, I agree that the presence of .set_polarity() shouldn't
> determine the number of cells. You could have any number of other flags
> set via the third cell.
> 
> > Also, polarity inversion could still be done in software for hardware
> > that doesn't support it.
> 
> No. You cannot emulate polarity inversion in software.
> 
Why not?

duty_ns = period_ns - duty_ns;


Lothar Waßmann
-- 
___________________________________________________________

Ka-Ro electronics GmbH | Pascalstraße 22 | D - 52076 Aachen
Phone: +49 2408 1402-0 | Fax: +49 2408 1402-10
Geschäftsführer: Matthias Kaussen
Handelsregistereintrag: Amtsgericht Aachen, HRB 4996

www.karo-electronics.de | info@karo-electronics.de
___________________________________________________________

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

* Re: [PATCHv3 1/3] pwm: make the PWM_POLARITY flag in DTB optional
  2014-04-08  5:02         ` Lothar Waßmann
@ 2014-04-08 20:37           ` Tim Kryger
  2014-04-09  6:04             ` Lothar Waßmann
  2014-04-08 20:43           ` Tim Kryger
  1 sibling, 1 reply; 19+ messages in thread
From: Tim Kryger @ 2014-04-08 20:37 UTC (permalink / raw)
  To: Lothar Waßmann
  Cc: Thierry Reding, Sascha Hauer, linux-kernel, Linux PWM List,
	Shawn Guo, Sascha Hauer, Arnd Bergmann

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

On Mon, Apr 7, 2014 at 10:02 PM, Lothar Waßmann <LW@karo-electronics.de>wrote:
>
>
> Thierry Reding wrote:
>
> > No. You cannot emulate polarity inversion in software.
> >
> Why not?
>
> duty_ns = period_ns - duty_ns;
>

Since I made the same mistake, I will pass along the pointer Thierry gave
me.

In include/linux/pwm.h the second difference for an inverted signal is
described.

/**
 * enum pwm_polarity - polarity of a PWM signal
 * @PWM_POLARITY_NORMAL: a high signal for the duration of the duty-
 * cycle, followed by a low signal for the remainder of the pulse
 * period
 * @PWM_POLARITY_INVERSED: a low signal for the duration of the duty-
 * cycle, followed by a high signal for the remainder of the pulse
 * period
 */
enum pwm_polarity {
PWM_POLARITY_NORMAL,
PWM_POLARITY_INVERSED,
};

Of course, I suspect not all PWM hardware respects this definition of
inverted output.

Either way, hacking the duty in software certainly would get the high/low
order wrong.

-Tim

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

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

* Re: [PATCHv3 1/3] pwm: make the PWM_POLARITY flag in DTB optional
  2014-04-08  5:02         ` Lothar Waßmann
  2014-04-08 20:37           ` Tim Kryger
@ 2014-04-08 20:43           ` Tim Kryger
  2014-04-09  6:12             ` Sascha Hauer
  1 sibling, 1 reply; 19+ messages in thread
From: Tim Kryger @ 2014-04-08 20:43 UTC (permalink / raw)
  To: Lothar Waßmann
  Cc: Thierry Reding, Sascha Hauer, linux-kernel, Linux PWM List,
	Shawn Guo, Sascha Hauer, Arnd Bergmann

On Mon, Apr 7, 2014 at 10:02 PM, Lothar Waßmann <LW@karo-electronics.de> wrote:
> Thierry Reding wrote:

>> No. You cannot emulate polarity inversion in software.
>>
> Why not?
>
> duty_ns = period_ns - duty_ns;

Since I made the same mistake, I will pass along the pointer Thierry gave me.

In include/linux/pwm.h the second difference for an inverted signal is
described.

/**
 * enum pwm_polarity - polarity of a PWM signal
 * @PWM_POLARITY_NORMAL: a high signal for the duration of the duty-
 * cycle, followed by a low signal for the remainder of the pulse
 * period
 * @PWM_POLARITY_INVERSED: a low signal for the duration of the duty-
 * cycle, followed by a high signal for the remainder of the pulse
 * period
 */
enum pwm_polarity {
PWM_POLARITY_NORMAL,
PWM_POLARITY_INVERSED,
};

Of course, I suspect not all PWM hardware respects this definition of
inverted output.

Either way, hacking the duty in software certainly would get the
high/low order wrong.

-Tim

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

* Re: [PATCHv3 1/3] pwm: make the PWM_POLARITY flag in DTB optional
  2014-04-08 20:37           ` Tim Kryger
@ 2014-04-09  6:04             ` Lothar Waßmann
  2014-04-09  7:16               ` Thierry Reding
  0 siblings, 1 reply; 19+ messages in thread
From: Lothar Waßmann @ 2014-04-09  6:04 UTC (permalink / raw)
  To: Tim Kryger
  Cc: Thierry Reding, Sascha Hauer, linux-kernel, Linux PWM List,
	Shawn Guo, Sascha Hauer, Arnd Bergmann

Hi,

Tim Kryger wrote:
> On Mon, Apr 7, 2014 at 10:02 PM, Lothar Waßmann <LW@karo-electronics.de>wrote:
> >
> >
> > Thierry Reding wrote:
> >
> > > No. You cannot emulate polarity inversion in software.
> > >
> > Why not?
> >
> > duty_ns = period_ns - duty_ns;
> >
> 
> Since I made the same mistake, I will pass along the pointer Thierry gave
> me.
> 
> In include/linux/pwm.h the second difference for an inverted signal is
> described.
> 
> /**
>  * enum pwm_polarity - polarity of a PWM signal
>  * @PWM_POLARITY_NORMAL: a high signal for the duration of the duty-
>  * cycle, followed by a low signal for the remainder of the pulse
>  * period
>  * @PWM_POLARITY_INVERSED: a low signal for the duration of the duty-
>  * cycle, followed by a high signal for the remainder of the pulse
>  * period
>  */
> enum pwm_polarity {
> PWM_POLARITY_NORMAL,
> PWM_POLARITY_INVERSED,
> };
> 
> Of course, I suspect not all PWM hardware respects this definition of
> inverted output.
> 
> Either way, hacking the duty in software certainly would get the high/low
> order wrong.
> 
OK. But for a periodic signal this doesn't make any difference. It's
just a matter of where you set your reference point.
Only if you program the PWM to create a single cycle you would see the
difference. I wonder if this is a real life usecase though.


Lothar Waßmann
-- 
___________________________________________________________

Ka-Ro electronics GmbH | Pascalstraße 22 | D - 52076 Aachen
Phone: +49 2408 1402-0 | Fax: +49 2408 1402-10
Geschäftsführer: Matthias Kaussen
Handelsregistereintrag: Amtsgericht Aachen, HRB 4996

www.karo-electronics.de | info@karo-electronics.de
___________________________________________________________

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

* Re: [PATCHv3 1/3] pwm: make the PWM_POLARITY flag in DTB optional
  2014-04-08 20:43           ` Tim Kryger
@ 2014-04-09  6:12             ` Sascha Hauer
  2014-04-09  7:22               ` Thierry Reding
  0 siblings, 1 reply; 19+ messages in thread
From: Sascha Hauer @ 2014-04-09  6:12 UTC (permalink / raw)
  To: Tim Kryger
  Cc: Lothar Waßmann, Thierry Reding, linux-kernel,
	Linux PWM List, Shawn Guo, Sascha Hauer, Arnd Bergmann

On Tue, Apr 08, 2014 at 01:43:22PM -0700, Tim Kryger wrote:
> On Mon, Apr 7, 2014 at 10:02 PM, Lothar Waßmann <LW@karo-electronics.de> wrote:
> > Thierry Reding wrote:
> 
> >> No. You cannot emulate polarity inversion in software.
> >>
> > Why not?
> >
> > duty_ns = period_ns - duty_ns;
> 
> Since I made the same mistake, I will pass along the pointer Thierry gave me.
> 
> In include/linux/pwm.h the second difference for an inverted signal is
> described.
> 
> /**
>  * enum pwm_polarity - polarity of a PWM signal
>  * @PWM_POLARITY_NORMAL: a high signal for the duration of the duty-
>  * cycle, followed by a low signal for the remainder of the pulse
>  * period
>  * @PWM_POLARITY_INVERSED: a low signal for the duration of the duty-
>  * cycle, followed by a high signal for the remainder of the pulse
>  * period
>  */
> enum pwm_polarity {
> PWM_POLARITY_NORMAL,
> PWM_POLARITY_INVERSED,
> };
> 
> Of course, I suspect not all PWM hardware respects this definition of
> inverted output.
> 
> Either way, hacking the duty in software certainly would get the
> high/low order wrong.

This only relevant if you have some reference signal the PWM must be
relative to, for example if you combine multiple PWMs for motor control.
For PWMs used for backlight or beepers a signal inversion in software is
perfectly fine. And I also think that it makes sense to put it once into
the framework instead of bothering all consumer drivers with the
inversion.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

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

* Re: [PATCHv3 1/3] pwm: make the PWM_POLARITY flag in DTB optional
  2014-04-09  6:04             ` Lothar Waßmann
@ 2014-04-09  7:16               ` Thierry Reding
  0 siblings, 0 replies; 19+ messages in thread
From: Thierry Reding @ 2014-04-09  7:16 UTC (permalink / raw)
  To: Lothar Waßmann
  Cc: Tim Kryger, Sascha Hauer, linux-kernel, Linux PWM List,
	Shawn Guo, Sascha Hauer, Arnd Bergmann

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

On Wed, Apr 09, 2014 at 08:04:50AM +0200, Lothar Waßmann wrote:
> Hi,
> 
> Tim Kryger wrote:
> > On Mon, Apr 7, 2014 at 10:02 PM, Lothar Waßmann <LW@karo-electronics.de>wrote:
> > >
> > >
> > > Thierry Reding wrote:
> > >
> > > > No. You cannot emulate polarity inversion in software.
> > > >
> > > Why not?
> > >
> > > duty_ns = period_ns - duty_ns;
> > >
> > 
> > Since I made the same mistake, I will pass along the pointer Thierry gave
> > me.
> > 
> > In include/linux/pwm.h the second difference for an inverted signal is
> > described.
> > 
> > /**
> >  * enum pwm_polarity - polarity of a PWM signal
> >  * @PWM_POLARITY_NORMAL: a high signal for the duration of the duty-
> >  * cycle, followed by a low signal for the remainder of the pulse
> >  * period
> >  * @PWM_POLARITY_INVERSED: a low signal for the duration of the duty-
> >  * cycle, followed by a high signal for the remainder of the pulse
> >  * period
> >  */
> > enum pwm_polarity {
> > PWM_POLARITY_NORMAL,
> > PWM_POLARITY_INVERSED,
> > };
> > 
> > Of course, I suspect not all PWM hardware respects this definition of
> > inverted output.
> > 
> > Either way, hacking the duty in software certainly would get the high/low
> > order wrong.
> > 
> OK. But for a periodic signal this doesn't make any difference. It's
> just a matter of where you set your reference point.
> Only if you program the PWM to create a single cycle you would see the
> difference. I wonder if this is a real life usecase though.

It doesn't make a difference if all you're concerned about is the signal
power (which happens to be the case for LED and backlight use-cases).

Currently any in-kernel users only care about the signal power, but
there's no guarantee that it will stay that way. Furthermore, PWM
channels are exposed to userspace via sysfs, so code that we don't
actually see may rely on this behaviour.

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

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

* Re: [PATCHv3 1/3] pwm: make the PWM_POLARITY flag in DTB optional
  2014-04-09  6:12             ` Sascha Hauer
@ 2014-04-09  7:22               ` Thierry Reding
  2014-04-10  5:55                 ` Sascha Hauer
  0 siblings, 1 reply; 19+ messages in thread
From: Thierry Reding @ 2014-04-09  7:22 UTC (permalink / raw)
  To: Sascha Hauer
  Cc: Tim Kryger, Lothar Waßmann, linux-kernel, Linux PWM List,
	Shawn Guo, Sascha Hauer, Arnd Bergmann

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

On Wed, Apr 09, 2014 at 08:12:09AM +0200, Sascha Hauer wrote:
> On Tue, Apr 08, 2014 at 01:43:22PM -0700, Tim Kryger wrote:
> > On Mon, Apr 7, 2014 at 10:02 PM, Lothar Waßmann <LW@karo-electronics.de> wrote:
> > > Thierry Reding wrote:
> > 
> > >> No. You cannot emulate polarity inversion in software.
> > >>
> > > Why not?
> > >
> > > duty_ns = period_ns - duty_ns;
> > 
> > Since I made the same mistake, I will pass along the pointer Thierry gave me.
> > 
> > In include/linux/pwm.h the second difference for an inverted signal is
> > described.
> > 
> > /**
> >  * enum pwm_polarity - polarity of a PWM signal
> >  * @PWM_POLARITY_NORMAL: a high signal for the duration of the duty-
> >  * cycle, followed by a low signal for the remainder of the pulse
> >  * period
> >  * @PWM_POLARITY_INVERSED: a low signal for the duration of the duty-
> >  * cycle, followed by a high signal for the remainder of the pulse
> >  * period
> >  */
> > enum pwm_polarity {
> > PWM_POLARITY_NORMAL,
> > PWM_POLARITY_INVERSED,
> > };
> > 
> > Of course, I suspect not all PWM hardware respects this definition of
> > inverted output.
> > 
> > Either way, hacking the duty in software certainly would get the
> > high/low order wrong.
> 
> This only relevant if you have some reference signal the PWM must be
> relative to, for example if you combine multiple PWMs for motor control.
> For PWMs used for backlight or beepers a signal inversion in software is
> perfectly fine. And I also think that it makes sense to put it once into
> the framework instead of bothering all consumer drivers with the
> inversion.

The PWM framework itself doesn't have enough knowledge about what a PWM
is being used for. Therefore it cannot determine whether emulating
polarity inversion by reversing the duty cycle will be appropriate.

Putting such functionality into the core will prevent PWM channels from
being used for cases where the signal polarity does matter.

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

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

* Re: [PATCHv3 1/3] pwm: make the PWM_POLARITY flag in DTB optional
  2014-04-09  7:22               ` Thierry Reding
@ 2014-04-10  5:55                 ` Sascha Hauer
  0 siblings, 0 replies; 19+ messages in thread
From: Sascha Hauer @ 2014-04-10  5:55 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Tim Kryger, Lothar Waßmann, linux-kernel, Linux PWM List,
	Shawn Guo, Sascha Hauer, Arnd Bergmann

On Wed, Apr 09, 2014 at 09:22:50AM +0200, Thierry Reding wrote:
> On Wed, Apr 09, 2014 at 08:12:09AM +0200, Sascha Hauer wrote:
> > On Tue, Apr 08, 2014 at 01:43:22PM -0700, Tim Kryger wrote:
> > > On Mon, Apr 7, 2014 at 10:02 PM, Lothar Waßmann <LW@karo-electronics.de> wrote:
> > > > Thierry Reding wrote:
> > > 
> > > >> No. You cannot emulate polarity inversion in software.
> > > >>
> > > > Why not?
> > > >
> > > > duty_ns = period_ns - duty_ns;
> > > 
> > > Since I made the same mistake, I will pass along the pointer Thierry gave me.
> > > 
> > > In include/linux/pwm.h the second difference for an inverted signal is
> > > described.
> > > 
> > > /**
> > >  * enum pwm_polarity - polarity of a PWM signal
> > >  * @PWM_POLARITY_NORMAL: a high signal for the duration of the duty-
> > >  * cycle, followed by a low signal for the remainder of the pulse
> > >  * period
> > >  * @PWM_POLARITY_INVERSED: a low signal for the duration of the duty-
> > >  * cycle, followed by a high signal for the remainder of the pulse
> > >  * period
> > >  */
> > > enum pwm_polarity {
> > > PWM_POLARITY_NORMAL,
> > > PWM_POLARITY_INVERSED,
> > > };
> > > 
> > > Of course, I suspect not all PWM hardware respects this definition of
> > > inverted output.
> > > 
> > > Either way, hacking the duty in software certainly would get the
> > > high/low order wrong.
> > 
> > This only relevant if you have some reference signal the PWM must be
> > relative to, for example if you combine multiple PWMs for motor control.
> > For PWMs used for backlight or beepers a signal inversion in software is
> > perfectly fine. And I also think that it makes sense to put it once into
> > the framework instead of bothering all consumer drivers with the
> > inversion.
> 
> The PWM framework itself doesn't have enough knowledge about what a PWM
> is being used for. Therefore it cannot determine whether emulating
> polarity inversion by reversing the duty cycle will be appropriate.
> 
> Putting such functionality into the core will prevent PWM channels from
> being used for cases where the signal polarity does matter

The PWM core is in no way prepared for handling such situations. Should
we want to add support it a PWM_POLARITY_INVERSED flag would be the
least of our problems. It could be renamed to
PWM_POLARITY_INVERSED_ASYNC for the beeper/led drivers which do not need
synchronization.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

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

end of thread, other threads:[~2014-04-10  5:55 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-03-19 13:22 pwm: imx: support output polarity inversion Lothar Waßmann
2014-03-19 13:22 ` [PATCHv3 1/3] pwm: make the PWM_POLARITY flag in DTB optional Lothar Waßmann
2014-03-19 13:22 ` [PATCHv3 2/3] pwm: imx: indentation cleanup Lothar Waßmann
2014-03-19 13:22 ` [PATCHv3 3/3] pwm: imx: support output polarity inversion Lothar Waßmann
2014-03-28  8:48 ` [PATCHv3 0/3] " Lothar Waßmann
2014-03-28  8:48   ` [PATCHv3 1/3] pwm: make the PWM_POLARITY flag in DTB optional Lothar Waßmann
2014-04-02  5:53     ` Sascha Hauer
2014-04-07 11:36       ` Thierry Reding
2014-04-08  5:02         ` Lothar Waßmann
2014-04-08 20:37           ` Tim Kryger
2014-04-09  6:04             ` Lothar Waßmann
2014-04-09  7:16               ` Thierry Reding
2014-04-08 20:43           ` Tim Kryger
2014-04-09  6:12             ` Sascha Hauer
2014-04-09  7:22               ` Thierry Reding
2014-04-10  5:55                 ` Sascha Hauer
2014-03-28  8:48   ` [PATCHv3 2/3] pwm: imx: indentation cleanup Lothar Waßmann
2014-03-28  8:49   ` [PATCHv3 3/3] pwm: imx: support output polarity inversion Lothar Waßmann
2014-04-02  5:45     ` Sascha Hauer

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.