diff options
Diffstat (limited to 'drivers/pwm/pwm-atmel.c')
-rw-r--r-- | drivers/pwm/pwm-atmel.c | 34 |
1 files changed, 23 insertions, 11 deletions
diff --git a/drivers/pwm/pwm-atmel.c b/drivers/pwm/pwm-atmel.c index 7e86a5266eb6..647d063562db 100644 --- a/drivers/pwm/pwm-atmel.c +++ b/drivers/pwm/pwm-atmel.c | |||
@@ -48,15 +48,11 @@ | |||
48 | #define PWMV2_CPRD 0x0C | 48 | #define PWMV2_CPRD 0x0C |
49 | #define PWMV2_CPRDUPD 0x10 | 49 | #define PWMV2_CPRDUPD 0x10 |
50 | 50 | ||
51 | /* | 51 | /* Max values for period and prescaler */ |
52 | * Max value for duty and period | 52 | |
53 | * | 53 | /* Only the LSB 16 bits are significant. */ |
54 | * Although the duty and period register is 32 bit, | 54 | #define PWM_MAXV1_PRD 0xFFFF |
55 | * however only the LSB 16 bits are significant. | 55 | #define PRD_MAXV1_PRES 10 |
56 | */ | ||
57 | #define PWM_MAX_DTY 0xFFFF | ||
58 | #define PWM_MAX_PRD 0xFFFF | ||
59 | #define PRD_MAX_PRES 10 | ||
60 | 56 | ||
61 | struct atmel_pwm_registers { | 57 | struct atmel_pwm_registers { |
62 | u8 period; | 58 | u8 period; |
@@ -65,8 +61,14 @@ struct atmel_pwm_registers { | |||
65 | u8 duty_upd; | 61 | u8 duty_upd; |
66 | }; | 62 | }; |
67 | 63 | ||
64 | struct atmel_pwm_config { | ||
65 | u32 max_period; | ||
66 | u32 max_pres; | ||
67 | }; | ||
68 | |||
68 | struct atmel_pwm_data { | 69 | struct atmel_pwm_data { |
69 | struct atmel_pwm_registers regs; | 70 | struct atmel_pwm_registers regs; |
71 | struct atmel_pwm_config cfg; | ||
70 | }; | 72 | }; |
71 | 73 | ||
72 | struct atmel_pwm_chip { | 74 | struct atmel_pwm_chip { |
@@ -125,10 +127,10 @@ static int atmel_pwm_calculate_cprd_and_pres(struct pwm_chip *chip, | |||
125 | cycles *= clk_get_rate(atmel_pwm->clk); | 127 | cycles *= clk_get_rate(atmel_pwm->clk); |
126 | do_div(cycles, NSEC_PER_SEC); | 128 | do_div(cycles, NSEC_PER_SEC); |
127 | 129 | ||
128 | for (*pres = 0; cycles > PWM_MAX_PRD; cycles >>= 1) | 130 | for (*pres = 0; cycles > atmel_pwm->data->cfg.max_period; cycles >>= 1) |
129 | (*pres)++; | 131 | (*pres)++; |
130 | 132 | ||
131 | if (*pres > PRD_MAX_PRES) { | 133 | if (*pres > atmel_pwm->data->cfg.max_pres) { |
132 | dev_err(chip->dev, "pres exceeds the maximum value\n"); | 134 | dev_err(chip->dev, "pres exceeds the maximum value\n"); |
133 | return -EINVAL; | 135 | return -EINVAL; |
134 | } | 136 | } |
@@ -288,6 +290,11 @@ static const struct atmel_pwm_data atmel_pwm_data_v1 = { | |||
288 | .duty = PWMV1_CDTY, | 290 | .duty = PWMV1_CDTY, |
289 | .duty_upd = PWMV1_CUPD, | 291 | .duty_upd = PWMV1_CUPD, |
290 | }, | 292 | }, |
293 | .cfg = { | ||
294 | /* 16 bits to keep period and duty. */ | ||
295 | .max_period = PWM_MAXV1_PRD, | ||
296 | .max_pres = PRD_MAXV1_PRES, | ||
297 | }, | ||
291 | }; | 298 | }; |
292 | 299 | ||
293 | static const struct atmel_pwm_data atmel_pwm_data_v2 = { | 300 | static const struct atmel_pwm_data atmel_pwm_data_v2 = { |
@@ -297,6 +304,11 @@ static const struct atmel_pwm_data atmel_pwm_data_v2 = { | |||
297 | .duty = PWMV2_CDTY, | 304 | .duty = PWMV2_CDTY, |
298 | .duty_upd = PWMV2_CDTYUPD, | 305 | .duty_upd = PWMV2_CDTYUPD, |
299 | }, | 306 | }, |
307 | .cfg = { | ||
308 | /* 16 bits to keep period and duty. */ | ||
309 | .max_period = PWM_MAXV1_PRD, | ||
310 | .max_pres = PRD_MAXV1_PRES, | ||
311 | }, | ||
300 | }; | 312 | }; |
301 | 313 | ||
302 | static const struct platform_device_id atmel_pwm_devtypes[] = { | 314 | static const struct platform_device_id atmel_pwm_devtypes[] = { |