On Thu, 08 Nov 2012 11:44:48 +0100 Roland Stigge <sti...@antcom.de> wrote:
> On 08/11/12 11:33, Alban Bedel wrote: > > On Thu, 08 Nov 2012 10:51:35 +0100 > > Roland Stigge <sti...@antcom.de> wrote: > > > >> On 07/11/12 16:25, Alban Bedel wrote: > >>> Signed-off-by: Alban Bedel <alban.be...@avionic-design.de> > >>> --- > >>> drivers/pwm/pwm-lpc32xx.c | 6 +++++- > >>> 1 files changed, 5 insertions(+), 1 deletions(-) > >>> > >>> diff --git a/drivers/pwm/pwm-lpc32xx.c b/drivers/pwm/pwm-lpc32xx.c > >>> index adb87f0..0dc278d 100644 > >>> --- a/drivers/pwm/pwm-lpc32xx.c > >>> +++ b/drivers/pwm/pwm-lpc32xx.c > >>> @@ -51,7 +51,11 @@ static int lpc32xx_pwm_config(struct pwm_chip *chip, > >>> struct pwm_device *pwm, > >>> > >>> c = 256 * duty_ns; > >>> do_div(c, period_ns); > >>> - duty_cycles = c; > >>> + if (c == 0) > >>> + c = 256; > >>> + if (c > 255) > >>> + c = 255; > >>> + duty_cycles = 256 - c; > >> > >> Except for the range check (for the original c > 255), this results in: > >> > >> duty_cycles = 256 - c > >> > >> except for (c == 0) where > >> > >> duty_cycles = 1 > > > > No it lead to duty_cycles = 0 > > Let's do it step by step with the above code: > > c == 0 > > >>> + if (c == 0) > >>> + c = 256; > > c == 256 > > >>> + if (c > 255) > >>> + c = 255; > > c == 255 > > >>> + duty_cycles = 256 - c; > > c == 1 > > See? Right, my bad. > > > >> which actually is > >> > >> duty_cycles = (256 - c) - 255 > >> > >> (think with the original c) > >> > >> i.e. nearly a polarity inversion in the case of (c == 0). > >> > >> Why is the case (c == 0) so special here? Maybe you can document this, > >> if it is really intended? > > > > It is intended, the formular for duty value in the register is: > > > > duty = (256 - 256*duty_ns/period_ns) % 256 > > Where does this modulo defined? In the Manual, there is sth. like this > defined for RELOADV (tables 606+607), but not for DUTY. > > Maybe I missed sth. in the manual. Link or hint appreciated! The manual doesn't mention this explicitly but you can see that without the modulo when duty_ns==0 DUTY would be 256, but the register is only 8 bits wide (ie. modulo 256). I made a few test and looked at the PWM output on a scope they confirm this: DUTY HIGH LEVEL 1 99.9% 25 90.0% 128 50.0% 220 10.0% 255 0.1% 0 0.0% I'll resubmit the patch with the clamping in the correct order. Alban -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/