linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/2] extends PWM framework to support PWM dead-times
@ 2017-05-09  8:19 Claudiu Beznea
  2017-05-09  8:19 ` [PATCH v2 1/2] drivers: pwm: core: implement pwm dead-times Claudiu Beznea
  2017-05-09  8:19 ` [PATCH v2 2/2] drivers: pwm: pwm-atmel: " Claudiu Beznea
  0 siblings, 2 replies; 5+ messages in thread
From: Claudiu Beznea @ 2017-05-09  8:19 UTC (permalink / raw)
  To: thierry.reding, corbet, alexandre.belloni, boris.brezillon,
	linux-pwm, linux-doc, linux-kernel, linux-arm-kernel
  Cc: nicolas.ferre, claudiu.beznea

Hi all,

Please give feedback on these patches which extends PWM framework
in order to support PWM dead-times.
Since I didn't receive any inputs on RFC series I'm resending it as
normal patch series.

For a PWM controller with more than one output signals per PWM channel
dead-times are the delays introduced between the edges of the output
signals and the original signal introduced in dead-time generator
engine.
E.g. consider a PWM controller with a dead-time engine as in the following
diagram:

                        -----------------
                       |                 |---> PWMH
        PWM signal --->| Dead-time engine|
                       |                 |---> PWML
                        -----------------

With no dead-time configured, the PWMH and PWML signals will be
complementary signals (rising and falling edges of PWMH and PWML
have opposite leves, same duration and same starting time) as
follows:

                      ____0    D____P     ____      ____      ____
        PWM signal __|    |____|    |____|    |____|    |____|    |___
                      ____      ____      ____      ____      ____
              PWMH __|    |____|    |____|    |____|    |____|    |___
                   __      ____      ____      ____      ____      ___
              PWML   |____|    |____|    |____|    |____|    |____|

Where - 0 is the starting point of the signal
      - D is the starting point of the duty-cycle
      - P is the signal period

Based on the above diagram:
- rising edge dead-time - is the delay introduced in one of the
dead-time engine output signals; the delay is introduced after
rising edge of the original PWM signal
- falling edge dead-time - is the delay introduced in one of the
dead-time engine output signals; the delay is introduced after
the end of falling edge of the original PWM signal

The following diagram explain how PWM dead-times falls on some signals:

                      ____0    D____P     ____      ____      ____
        PWM signal __|    |____|    |____|    |____|    |____|    |___
                        __        __        __        __        __
              PWMH ____|  |____re|  |______|  |______|  |______|  |___
                   __        __        __        __        __        __
              PWML   |______|  |____fe|  |______|  |______|  |______|

In the upper diagram:
- re = rising edge = the delay between D point of the original PWM signal
(rising edge) and the starting point of the next edge of one of the PWM
dead-time engine output
- fe = falling edge = the delay between P point of the original PWM signal
(falling edge) and the starting point of the next edge of one of the PWM
dead-time engine output

To configure the PWM dead-times new inputs were added to sysfs,
in PWM subsystem, one for rising edge dead-time, one for falling
edge deadtime.

root@sama5d2-xplained:/sys/devices/platform/ahb/ahb:apb/f802c000.pwm/pwm/pwmchip0/pwm2# ls -l
-r--r--r--    1 root     root          4096 Feb 10 10:00 capture
-rw-r--r--    1 root     root          4096 Feb 10 10:01 deadtime_fe
-rw-r--r--    1 root     root          4096 Feb 10 10:02 deadtime_re
-rw-r--r--    1 root     root          4096 Feb 10 10:00 duty_cycle
-rw-r--r--    1 root     root          4096 Feb 10 10:00 enable
-rw-r--r--    1 root     root          4096 Feb 10 10:00 period
-rw-r--r--    1 root     root          4096 Feb 10 10:00 polarity
drwxr-xr-x    2 root     root             0 Feb 10 10:00 power
-rw-r--r--    1 root     root          4096 Feb 10 10:00 uevent

The PWM dead-times are used in half bridge converters applications.

Thank you,
Claudiu Beznea

Changes since v1:
- fixed compilation warning

Changes since RFC patches:
- corrected the Documentation/pwm.txt
- in atmel-pwm.c check atmel_pwm->regs->dt before computing
dead-times or setting specific registers since the driver is
used by controllers witch supports dead-time configuration and
controller which does not.

Claudiu Beznea (2):
  drivers: pwm: core: implement pwm dead-times
  drivers: pwm: pwm-atmel: implement pwm dead-times

 Documentation/pwm.txt   | 55 ++++++++++++++++++++++++++++++++++++
 drivers/pwm/core.c      | 10 ++++++-
 drivers/pwm/pwm-atmel.c | 62 ++++++++++++++++++++++++++++++++++++++---
 drivers/pwm/sysfs.c     | 74 +++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/pwm.h     | 36 ++++++++++++++++++++++++
 5 files changed, 232 insertions(+), 5 deletions(-)

-- 
2.7.4

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

* [PATCH v2 1/2] drivers: pwm: core: implement pwm dead-times
  2017-05-09  8:19 [PATCH v2 0/2] extends PWM framework to support PWM dead-times Claudiu Beznea
@ 2017-05-09  8:19 ` Claudiu Beznea
  2017-05-27 22:28   ` Andy Shevchenko
  2017-05-09  8:19 ` [PATCH v2 2/2] drivers: pwm: pwm-atmel: " Claudiu Beznea
  1 sibling, 1 reply; 5+ messages in thread
From: Claudiu Beznea @ 2017-05-09  8:19 UTC (permalink / raw)
  To: thierry.reding, corbet, alexandre.belloni, boris.brezillon,
	linux-pwm, linux-doc, linux-kernel, linux-arm-kernel
  Cc: nicolas.ferre, claudiu.beznea

Extends PWM framework to support PWM dead-times.
The notions introduced are rising edge dead-time
and falling edge dead-time. These are useful for
PWM controllers with channels that have more than
one outputs.
The implementation add sysfs interface for
configuration. It extends the pwm_state structure
with two new members which keeps the values for
dead-times.
There were no additions in device tree for PWM channels
initialized by device tree.

Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
---
 Documentation/pwm.txt | 55 ++++++++++++++++++++++++++++++++++++++
 drivers/pwm/core.c    | 10 ++++++-
 drivers/pwm/sysfs.c   | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/pwm.h   | 36 +++++++++++++++++++++++++
 4 files changed, 174 insertions(+), 1 deletion(-)

diff --git a/Documentation/pwm.txt b/Documentation/pwm.txt
index 789b27c..61de0f9 100644
--- a/Documentation/pwm.txt
+++ b/Documentation/pwm.txt
@@ -100,6 +100,61 @@ enable - Enable/disable the PWM signal (read/write).
 	0 - disabled
 	1 - enabled
 
+deadtime_re -The rising edge dead-time
+deadtime_fe - the falling edge dead-time
+	For a PWM controller with more than one output signals per PWM channel
+	dead-times are the delays introduced between the edges of the output
+	signals and the original signal introduced in dead-time generator
+	engine.
+	E.g. consider a PWM controller with a dead-time engine as in the following
+	diagram:
+
+                        -----------------
+                       |                 |---> PWMH
+        PWM signal --->| Dead-time engine|
+                       |                 |---> PWML
+                        -----------------
+
+	With no dead-time configured, the PWMH and PWML signals will be
+	complementary signals (rising and falling edges of PWMH and PWML
+	have opposite leves, same duration and same starting time) as
+	follows:
+
+                      ____0    D____P     ____      ____      ____
+        PWM signal __|    |____|    |____|    |____|    |____|    |___
+                      ____      ____      ____      ____      ____
+              PWMH __|    |____|    |____|    |____|    |____|    |___
+                   __      ____      ____      ____      ____      ___
+              PWML   |____|    |____|    |____|    |____|    |____|
+
+	Where - 0 is the starting point of the signal
+	      - D is the starting point of the duty-cycle
+	      - P is the signal period
+
+	Based on the above diagram:
+	- rising edge dead-time - is the delay introduced in one of the
+	dead-time engine output signals; the delay is introduced after
+	rising edge of the original PWM signal
+	- falling edge dead-time - is the delay introduced in one of the
+	dead-time engine output signals; the delay is introduced after
+	the end of falling edge of the original PWM signal
+	See the following diagram:
+
+                      ____0    D____P     ____      ____      ____
+        PWM signal __|    |____|    |____|    |____|    |____|    |___
+                        __        __        __        __        __
+              PWMH ____|  |____re|  |______|  |______|  |______|  |___
+                   __        __        __        __        __        __
+              PWML   |______|  |____fe|  |______|  |______|  |______|
+
+	In the upper diagram:
+	- re = rising edge = the delay between D point of the original PWM signal
+	(rising edge) and the starting point of the next edge of one of the PWM
+	dead-time engine output
+	- fe = falling edge = the delay between P point of the original PWM signal
+	(falling edge) and the starting point of the next edge of one of the PWM
+	dead-time engine output
+
 Implementing a PWM driver
 -------------------------
 
diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index a0860b3..c1a9828 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -469,7 +469,8 @@ int pwm_apply_state(struct pwm_device *pwm, struct pwm_state *state)
 	int err;
 
 	if (!pwm || !state || !state->period ||
-	    state->duty_cycle > state->period)
+	    state->duty_cycle > state->period ||
+	    state->deadtime_re + state->deadtime_fe > state->period)
 		return -EINVAL;
 
 	if (!memcmp(state, &pwm->state, sizeof(*state)))
@@ -579,6 +580,9 @@ int pwm_adjust_config(struct pwm_device *pwm)
 	pwm_get_args(pwm, &pargs);
 	pwm_get_state(pwm, &state);
 
+	state.deadtime_re = 0;
+	state.deadtime_fe = 0;
+
 	/*
 	 * If the current period is zero it means that either the PWM driver
 	 * does not support initial state retrieval or the PWM has not yet
@@ -997,6 +1001,10 @@ static void pwm_dbg_show(struct pwm_chip *chip, struct seq_file *s)
 		seq_printf(s, " duty: %u ns", state.duty_cycle);
 		seq_printf(s, " polarity: %s",
 			   state.polarity ? "inverse" : "normal");
+		seq_printf(s, " dead-time rising edge: %u ns",
+			   state.deadtime_re);
+		seq_printf(s, " dead-time falling edge: %u ns",
+			   state.deadtime_fe);
 
 		seq_puts(s, "\n");
 	}
diff --git a/drivers/pwm/sysfs.c b/drivers/pwm/sysfs.c
index a813239..f91686e 100644
--- a/drivers/pwm/sysfs.c
+++ b/drivers/pwm/sysfs.c
@@ -223,11 +223,83 @@ static ssize_t capture_show(struct device *child,
 	return sprintf(buf, "%u %u\n", result.period, result.duty_cycle);
 }
 
+static ssize_t deadtime_re_show(struct device *child,
+				struct device_attribute *attr,
+				char *buf)
+{
+	const struct pwm_device *pwm = child_to_pwm_device(child);
+	struct pwm_state state;
+
+	pwm_get_state(pwm, &state);
+
+	return sprintf(buf, "%u\n", state.deadtime_re);
+}
+
+static ssize_t deadtime_re_store(struct device *child,
+				 struct device_attribute *attr,
+				 const char *buf, size_t size)
+{
+	struct pwm_export *export = child_to_pwm_export(child);
+	struct pwm_device *pwm = export->pwm;
+	struct pwm_state state;
+	unsigned int val;
+	int ret;
+
+	ret = kstrtouint(buf, 0, &val);
+	if (ret)
+		return ret;
+
+	mutex_lock(&export->lock);
+	pwm_get_state(pwm, &state);
+	state.deadtime_re = val;
+	ret = pwm_apply_state(pwm, &state);
+	mutex_unlock(&export->lock);
+
+	return ret ? : size;
+}
+
+static ssize_t deadtime_fe_show(struct device *child,
+				struct device_attribute *attr,
+				char *buf)
+{
+	const struct pwm_device *pwm = child_to_pwm_device(child);
+	struct pwm_state state;
+
+	pwm_get_state(pwm, &state);
+
+	return sprintf(buf, "%u\n", state.deadtime_fe);
+}
+
+static ssize_t deadtime_fe_store(struct device *child,
+				 struct device_attribute *attr,
+				 const char *buf, size_t size)
+{
+	struct pwm_export *export = child_to_pwm_export(child);
+	struct pwm_device *pwm = export->pwm;
+	struct pwm_state state;
+	unsigned int val;
+	int ret;
+
+	ret = kstrtouint(buf, 0, &val);
+	if (ret)
+		return ret;
+
+	mutex_lock(&export->lock);
+	pwm_get_state(pwm, &state);
+	state.deadtime_fe = val;
+	ret = pwm_apply_state(pwm, &state);
+	mutex_unlock(&export->lock);
+
+	return ret ? : size;
+}
+
 static DEVICE_ATTR_RW(period);
 static DEVICE_ATTR_RW(duty_cycle);
 static DEVICE_ATTR_RW(enable);
 static DEVICE_ATTR_RW(polarity);
 static DEVICE_ATTR_RO(capture);
+static DEVICE_ATTR_RW(deadtime_re);
+static DEVICE_ATTR_RW(deadtime_fe);
 
 static struct attribute *pwm_attrs[] = {
 	&dev_attr_period.attr,
@@ -235,6 +307,8 @@ static struct attribute *pwm_attrs[] = {
 	&dev_attr_enable.attr,
 	&dev_attr_polarity.attr,
 	&dev_attr_capture.attr,
+	&dev_attr_deadtime_re.attr,
+	&dev_attr_deadtime_fe.attr,
 	NULL
 };
 ATTRIBUTE_GROUPS(pwm);
diff --git a/include/linux/pwm.h b/include/linux/pwm.h
index 08fad7c..7547053 100644
--- a/include/linux/pwm.h
+++ b/include/linux/pwm.h
@@ -53,10 +53,14 @@ enum {
  * @duty_cycle: PWM duty cycle (in nanoseconds)
  * @polarity: PWM polarity
  * @enabled: PWM enabled status
+ * @deadtime_re: PWM rising edge deadtime
+ * @deadtime_fe: PWM falling edge deadtime
  */
 struct pwm_state {
 	unsigned int period;
 	unsigned int duty_cycle;
+	unsigned int deadtime_re;
+	unsigned int deadtime_fe;
 	enum pwm_polarity polarity;
 	bool enabled;
 };
@@ -143,6 +147,36 @@ static inline enum pwm_polarity pwm_get_polarity(const struct pwm_device *pwm)
 	return state.polarity;
 }
 
+static inline void pwm_set_deadtime_re(struct pwm_device *pwm, unsigned int dt)
+{
+	if (pwm)
+		pwm->state.deadtime_re = dt;
+}
+
+static inline unsigned int pwm_get_deadtime_re(const struct pwm_device *pwm)
+{
+	struct pwm_state state;
+
+	pwm_get_state(pwm, &state);
+
+	return state.deadtime_re;
+}
+
+static inline void pwm_set_deadtime_fe(struct pwm_device *pwm, unsigned int dt)
+{
+	if (pwm)
+		pwm->state.deadtime_fe = dt;
+}
+
+static inline unsigned int pwm_get_deadtime_fe(const struct pwm_device *pwm)
+{
+	struct pwm_state state;
+
+	pwm_get_state(pwm, &state);
+
+	return state.deadtime_fe;
+}
+
 static inline void pwm_get_args(const struct pwm_device *pwm,
 				struct pwm_args *args)
 {
@@ -180,6 +214,8 @@ static inline void pwm_init_state(const struct pwm_device *pwm,
 	state->period = args.period;
 	state->polarity = args.polarity;
 	state->duty_cycle = 0;
+	state->deadtime_re = 0;
+	state->deadtime_fe = 0;
 }
 
 /**
-- 
2.7.4

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

* [PATCH v2 2/2] drivers: pwm: pwm-atmel: implement pwm dead-times
  2017-05-09  8:19 [PATCH v2 0/2] extends PWM framework to support PWM dead-times Claudiu Beznea
  2017-05-09  8:19 ` [PATCH v2 1/2] drivers: pwm: core: implement pwm dead-times Claudiu Beznea
@ 2017-05-09  8:19 ` Claudiu Beznea
  1 sibling, 0 replies; 5+ messages in thread
From: Claudiu Beznea @ 2017-05-09  8:19 UTC (permalink / raw)
  To: thierry.reding, corbet, alexandre.belloni, boris.brezillon,
	linux-pwm, linux-doc, linux-kernel, linux-arm-kernel
  Cc: nicolas.ferre, claudiu.beznea

Implement PWM dead-times for atmel PWM controllers.
Since this driver is used by PWM controllers which
supports dead-times and PWM controllers which doesn't,
add specific input for dead-time register in atmel
register private data structure.

Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
---
 drivers/pwm/pwm-atmel.c | 61 +++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 57 insertions(+), 4 deletions(-)

diff --git a/drivers/pwm/pwm-atmel.c b/drivers/pwm/pwm-atmel.c
index 530d7dc..dababa6 100644
--- a/drivers/pwm/pwm-atmel.c
+++ b/drivers/pwm/pwm-atmel.c
@@ -33,8 +33,9 @@
 
 #define PWM_CMR			0x0
 /* Bit field in CMR */
-#define PWM_CMR_CPOL		(1 << 9)
-#define PWM_CMR_UPD_CDTY	(1 << 10)
+#define PWM_CMR_CPOL		BIT(9)
+#define PWM_CMR_UPD_CDTY	BIT(10)
+#define PWM_CMR_DTE		BIT(16)
 #define PWM_CMR_CPRE_MSK	0xF
 
 /* The following registers for PWM v1 */
@@ -47,6 +48,7 @@
 #define PWMV2_CDTYUPD		0x08
 #define PWMV2_CPRD		0x0C
 #define PWMV2_CPRDUPD		0x10
+#define PWMV2_DT		0x18
 
 /*
  * Max value for duty and period
@@ -63,6 +65,7 @@ struct atmel_pwm_registers {
 	u8 period_upd;
 	u8 duty;
 	u8 duty_upd;
+	u8 dt;
 };
 
 struct atmel_pwm_chip {
@@ -161,6 +164,31 @@ static void atmel_pwm_update_cdty(struct pwm_chip *chip, struct pwm_device *pwm,
 			    atmel_pwm->regs->duty_upd, cdty);
 }
 
+static int atmel_pwm_calculate_deadtime(struct pwm_chip *chip,
+					struct pwm_state *state,
+					unsigned long cprd, unsigned long *dt)
+{
+	unsigned long long cycles;
+
+	if (state->deadtime_fe > state->duty_cycle ||
+	    state->deadtime_re > state->period - state->duty_cycle)
+		return -EINVAL;
+
+	if (state->deadtime_fe) {
+		cycles = (unsigned long long)state->deadtime_fe * cprd;
+		do_div(cycles, state->period);
+		*dt = (cycles << 16);
+	}
+
+	if (state->deadtime_re) {
+		cycles = (unsigned long long)state->deadtime_re * cprd;
+		do_div(cycles, state->period);
+		*dt |= cycles;
+	}
+
+	return 0;
+}
+
 static void atmel_pwm_set_cprd_cdty(struct pwm_chip *chip,
 				    struct pwm_device *pwm,
 				    unsigned long cprd, unsigned long cdty)
@@ -214,7 +242,7 @@ static int atmel_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 {
 	struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip);
 	struct pwm_state cstate;
-	unsigned long cprd, cdty;
+	unsigned long cprd, cdty, dt = 0;
 	u32 pres, val;
 	int ret;
 
@@ -223,7 +251,9 @@ static int atmel_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 	if (state->enabled) {
 		if (cstate.enabled &&
 		    cstate.polarity == state->polarity &&
-		    cstate.period == state->period) {
+		    cstate.period == state->period &&
+		    cstate.deadtime_re == state->deadtime_re &&
+		    cstate.deadtime_fe == state->deadtime_fe) {
 			cprd = atmel_pwm_ch_readl(atmel_pwm, pwm->hwpwm,
 						  atmel_pwm->regs->period);
 			atmel_pwm_calculate_cdty(state, cprd, &cdty);
@@ -239,6 +269,16 @@ static int atmel_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 			return ret;
 		}
 
+		if (atmel_pwm->regs->dt) {
+			ret = atmel_pwm_calculate_deadtime(chip, state, cprd,
+							   &dt);
+			if (ret) {
+				dev_err(chip->dev,
+					"failed to calculate dead-time\n");
+				return ret;
+			}
+		}
+
 		atmel_pwm_calculate_cdty(state, cprd, &cdty);
 
 		if (cstate.enabled) {
@@ -258,8 +298,19 @@ static int atmel_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 			val &= ~PWM_CMR_CPOL;
 		else
 			val |= PWM_CMR_CPOL;
+
+		if (atmel_pwm->regs->dt) {
+			if (dt)
+				val |= PWM_CMR_DTE;
+			else
+				val &= ~PWM_CMR_DTE;
+		}
+
 		atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm, PWM_CMR, val);
 		atmel_pwm_set_cprd_cdty(chip, pwm, cprd, cdty);
+		if (atmel_pwm->regs->dt)
+			atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm,
+					    atmel_pwm->regs->dt, dt);
 		mutex_lock(&atmel_pwm->isr_lock);
 		atmel_pwm->updated_pwms |= atmel_pwm_readl(atmel_pwm, PWM_ISR);
 		atmel_pwm->updated_pwms &= ~(1 << pwm->hwpwm);
@@ -282,6 +333,7 @@ static const struct atmel_pwm_registers atmel_pwm_regs_v1 = {
 	.period_upd	= PWMV1_CUPD,
 	.duty		= PWMV1_CDTY,
 	.duty_upd	= PWMV1_CUPD,
+	.dt		= 0,
 };
 
 static const struct atmel_pwm_registers atmel_pwm_regs_v2 = {
@@ -289,6 +341,7 @@ static const struct atmel_pwm_registers atmel_pwm_regs_v2 = {
 	.period_upd	= PWMV2_CPRDUPD,
 	.duty		= PWMV2_CDTY,
 	.duty_upd	= PWMV2_CDTYUPD,
+	.dt		= PWMV2_DT,
 };
 
 static const struct platform_device_id atmel_pwm_devtypes[] = {
-- 
2.7.4

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

* Re: [PATCH v2 1/2] drivers: pwm: core: implement pwm dead-times
  2017-05-09  8:19 ` [PATCH v2 1/2] drivers: pwm: core: implement pwm dead-times Claudiu Beznea
@ 2017-05-27 22:28   ` Andy Shevchenko
  2017-05-30 10:20     ` m18063
  0 siblings, 1 reply; 5+ messages in thread
From: Andy Shevchenko @ 2017-05-27 22:28 UTC (permalink / raw)
  To: Claudiu Beznea
  Cc: Thierry Reding, Jonathan Corbet, Alexandre Belloni,
	Boris Brezillon, linux-pwm, Linux Documentation List,
	linux-kernel, linux-arm Mailing List, nicolas.ferre

On Tue, May 9, 2017 at 11:19 AM, Claudiu Beznea
<claudiu.beznea@microchip.com> wrote:
> Extends PWM framework to support PWM dead-times.
> The notions introduced are rising edge dead-time
> and falling edge dead-time. These are useful for
> PWM controllers with channels that have more than
> one outputs.
> The implementation add sysfs interface for
> configuration. It extends the pwm_state structure
> with two new members which keeps the values for
> dead-times.
> There were no additions in device tree for PWM channels
> initialized by device tree.

AFAIU it's effectively called phase of the signal.
It looks to me much simpler if you allow to have linked / virtual
channels instead of creating a lot of (duplicated) properties.

-- 
With Best Regards,
Andy Shevchenko

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

* Re: [PATCH v2 1/2] drivers: pwm: core: implement pwm dead-times
  2017-05-27 22:28   ` Andy Shevchenko
@ 2017-05-30 10:20     ` m18063
  0 siblings, 0 replies; 5+ messages in thread
From: m18063 @ 2017-05-30 10:20 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Thierry Reding, Jonathan Corbet, Alexandre Belloni,
	Boris Brezillon, linux-pwm, Linux Documentation List,
	linux-kernel, linux-arm Mailing List, nicolas.ferre

Hi Andy,

On 28.05.2017 01:28, Andy Shevchenko wrote:
> On Tue, May 9, 2017 at 11:19 AM, Claudiu Beznea
> <claudiu.beznea@microchip.com> wrote:
>> Extends PWM framework to support PWM dead-times.
>> The notions introduced are rising edge dead-time
>> and falling edge dead-time. These are useful for
>> PWM controllers with channels that have more than
>> one outputs.
>> The implementation add sysfs interface for
>> configuration. It extends the pwm_state structure
>> with two new members which keeps the values for
>> dead-times.
>> There were no additions in device tree for PWM channels
>> initialized by device tree.
> 
> AFAIU it's effectively called phase of the signal.
It is actually a delay introduce by the PWM controller
between it's outputs. As I said in cover letter, for
PWM controllers with 2 output signals per channel
(these signals are on different physical pins), this
dead-time is the delay introduced b/w these two outputs.
The term is a PWM literature specific.
These delays are useful when PWM drives a half bridge
converter where you need delays b/w positive edges of
the signals which drivers the transistors to avoid
shoot through scenarios.

> It looks to me much simpler if you allow to have linked / virtual
> channels instead of creating a lot of (duplicated) properties.My linked channels (the 2 outputs per PWM channel) are PWM controller
specifics. The standard output of these linked channels is as
follows:
              __    __    __    __
channel Xa __|  |__|  |__|  |__|  |__
           __    __    __    __    __
channel Xb   |__|  |__|  |__|  |__|
             <--T-->

This is the default output. To be able to use the controller
in applications which needs delays b/w the fronts of this outputs
I introduced the dead-time configuration. This allow the user
to set it's PWM output as he needs in his setup (these dead-times,
delays, if PWM is used e.g. in half bridge converters, depends
on the transistors used).

Thank you,
Claudiu Beznea

> 

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

end of thread, other threads:[~2017-05-30 10:20 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-05-09  8:19 [PATCH v2 0/2] extends PWM framework to support PWM dead-times Claudiu Beznea
2017-05-09  8:19 ` [PATCH v2 1/2] drivers: pwm: core: implement pwm dead-times Claudiu Beznea
2017-05-27 22:28   ` Andy Shevchenko
2017-05-30 10:20     ` m18063
2017-05-09  8:19 ` [PATCH v2 2/2] drivers: pwm: pwm-atmel: " Claudiu Beznea

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).