2014-04-02 05:53:56

by Sascha Hauer

[permalink] [raw]
Subject: Re: [PATCHv3 1/3] pwm: make the PWM_POLARITY flag in DTB optional

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 <[email protected]>
> ---
> 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 |


2014-04-07 11:37:47

by Thierry Reding

[permalink] [raw]
Subject: Re: [PATCHv3 1/3] pwm: make the PWM_POLARITY flag in DTB optional

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


Attachments:
(No filename) (1.10 kB)
(No filename) (836.00 B)
Download all attachments

2014-04-08 05:03:15

by Lothar Waßmann

[permalink] [raw]
Subject: Re: [PATCHv3 1/3] pwm: make the PWM_POLARITY flag in DTB optional

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

http://www.karo-electronics.de | [email protected]
___________________________________________________________

2014-04-08 20:43:24

by Tim Kryger

[permalink] [raw]
Subject: Re: [PATCHv3 1/3] pwm: make the PWM_POLARITY flag in DTB optional

On Mon, Apr 7, 2014 at 10:02 PM, Lothar Wa?mann <[email protected]> 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

2014-04-09 06:12:25

by Sascha Hauer

[permalink] [raw]
Subject: Re: [PATCHv3 1/3] pwm: make the PWM_POLARITY flag in DTB optional

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 <[email protected]> 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 |

2014-04-09 07:23:48

by Thierry Reding

[permalink] [raw]
Subject: Re: [PATCHv3 1/3] pwm: make the PWM_POLARITY flag in DTB optional

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 <[email protected]> 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


Attachments:
(No filename) (1.91 kB)
(No filename) (836.00 B)
Download all attachments

2014-04-10 05:55:31

by Sascha Hauer

[permalink] [raw]
Subject: Re: [PATCHv3 1/3] pwm: make the PWM_POLARITY flag in DTB optional

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 <[email protected]> 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 |