The calculated values are the same with the modified algorithm. The only
difference is that the calculation is a bit more efficient.
Acked-by: Claudiu Beznea <claudiu.beznea@microchip.com>
Signed-off-by: Uwe Kleine-König <uwe@kleine-koenig.org>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
};
struct atmel_pwm_config {
};
struct atmel_pwm_config {
};
struct atmel_pwm_data {
};
struct atmel_pwm_data {
{
struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip);
unsigned long long cycles = state->period;
{
struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip);
unsigned long long cycles = state->period;
/* Calculate the period cycles and prescale value */
cycles *= clk_get_rate(atmel_pwm->clk);
do_div(cycles, NSEC_PER_SEC);
/* Calculate the period cycles and prescale value */
cycles *= clk_get_rate(atmel_pwm->clk);
do_div(cycles, NSEC_PER_SEC);
- for (*pres = 0; cycles > atmel_pwm->data->cfg.max_period; cycles >>= 1)
- (*pres)++;
+ /*
+ * The register for the period length is cfg.period_bits bits wide.
+ * So for each bit the number of clock cycles is wider divide the input
+ * clock frequency by two using pres and shift cprd accordingly.
+ */
+ shift = fls(cycles) - atmel_pwm->data->cfg.period_bits;
- if (*pres > PWM_MAX_PRES) {
+ if (shift > PWM_MAX_PRES) {
dev_err(chip->dev, "pres exceeds the maximum value\n");
return -EINVAL;
dev_err(chip->dev, "pres exceeds the maximum value\n");
return -EINVAL;
+ } else if (shift > 0) {
+ *pres = shift;
+ cycles >>= *pres;
+ } else {
+ *pres = 0;
},
.cfg = {
/* 16 bits to keep period and duty. */
},
.cfg = {
/* 16 bits to keep period and duty. */
},
.cfg = {
/* 16 bits to keep period and duty. */
},
.cfg = {
/* 16 bits to keep period and duty. */
},
.cfg = {
/* 32 bits to keep period and duty. */
},
.cfg = {
/* 32 bits to keep period and duty. */
- .max_period = 0xffffffff,