When disabling a PWM channel, the PWM clock was being stopped
immediately after writing to PWM_DIS. As a result, the disabling
of the PWM channel did not complete properly, and the PWM output
might be left at the wrong level.
Fix this by waiting for the channel to be effectively disabled
(by checking the PWM_SR register) before disabling the clock.
Signed-off-by: Guillermo Rodriguez <guille.rodriguez@gmail.com>
Acked-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
Use the pwm_get_xxx() helpers instead of directly accessing the fields
in struct pwm_device. This will allow us to smoothly move to the atomic
update approach.
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
Some PWM drivers are testing the PWMF_ENABLED flag. Create a helper
function to hide the logic behind enabled test. This will allow us to
smoothly move from the current approach to an atomic PWM update
approach.
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
pwm-leds calls .config() and .disable() in a row. This exhibits that it
may happen that the channel gets disabled before CDTY has been updated
with CUPD. The issue gets quite worse with long periods. So, ensure that
at least one period has past before disabling the channel by polling
ISR.
Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Acked-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Tested-by: Gaël PORTAY <gael.portay@gmail.com>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
CUPD is not flushed before enabling the channel so it will update
CDTY/CPRD just after one period. So we always set CUPD, even when the
channel is not enabled.
Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Acked-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
The prescale value used for calculating the period was incremented
afterwards, thus the resulting prescale value is by one too high.
This resulted in a PWM frequency only half as high as requested.
This patch moves the 64 bit division out of the prescale loop to
correct the above issue and make the calculation more efficient.
Signed-off-by: Nikolaus Voss <n.voss@weinmann-emt.de>
Tested-by: Bo Shen <voice.shen@atmel.com>
Acked-by: Bo Shen <voice.shen@atmel.com>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
atmel_pwm_config() calls clk_get_rate() which might sleep, so we need to
set pwm_chip can_sleep flag.
Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Acked-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
From the datasheet, the actual duty cycle is:
(period - (1 / clk) * CDTY) / period
This actually correct the polarity of the PWM and solves the issue that
pwm-leds exhibits: when setting a duty cycle of 0 and then disabling a
channel, the level was wrong (1 when the polarity was normal and 0 when
the polarity was inversed).
Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Acked-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
When atmel_pwm_config() calculates and then sets the prescaler, it is
overwriting the channel's CMR register so we are losing the CPOL
configuration.
As atmel_pwm_config() is always called before enabling a channel,
inverting the polarity doesn't work.
Fix that by reading CMR first and only overwriting the prescaler bits.
Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Acked-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
When the PWM controller is registered successfully, the clock can not
unprepare, so fix it.
Signed-off-by: Bo Shen <voice.shen@atmel.com>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
Add a PWM framework driver for the PWM controller found on Atmel SoCs.
Signed-off-by: Bo Shen <voice.shen@atmel.com>
Acked-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Acked-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
[thierry.reding: coding style and other minor cleanups]
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>