diff options
| -rw-r--r-- | drivers/pwm/pwm-tiecap.c | 7 | ||||
| -rw-r--r-- | drivers/pwm/pwm-tiehrpwm.c | 29 |
2 files changed, 36 insertions, 0 deletions
diff --git a/drivers/pwm/pwm-tiecap.c b/drivers/pwm/pwm-tiecap.c index 0b66d0f25922..4b6688909fee 100644 --- a/drivers/pwm/pwm-tiecap.c +++ b/drivers/pwm/pwm-tiecap.c | |||
| @@ -100,6 +100,13 @@ static int ecap_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, | |||
| 100 | writel(period_cycles, pc->mmio_base + CAP3); | 100 | writel(period_cycles, pc->mmio_base + CAP3); |
| 101 | } | 101 | } |
| 102 | 102 | ||
| 103 | if (!test_bit(PWMF_ENABLED, &pwm->flags)) { | ||
| 104 | reg_val = readw(pc->mmio_base + ECCTL2); | ||
| 105 | /* Disable APWM mode to put APWM output Low */ | ||
| 106 | reg_val &= ~ECCTL2_APWM_MODE; | ||
| 107 | writew(reg_val, pc->mmio_base + ECCTL2); | ||
| 108 | } | ||
| 109 | |||
| 103 | pm_runtime_put_sync(pc->chip.dev); | 110 | pm_runtime_put_sync(pc->chip.dev); |
| 104 | return 0; | 111 | return 0; |
| 105 | } | 112 | } |
diff --git a/drivers/pwm/pwm-tiehrpwm.c b/drivers/pwm/pwm-tiehrpwm.c index c3756d1be194..b1996bcd5b78 100644 --- a/drivers/pwm/pwm-tiehrpwm.c +++ b/drivers/pwm/pwm-tiehrpwm.c | |||
| @@ -104,6 +104,7 @@ struct ehrpwm_pwm_chip { | |||
| 104 | struct pwm_chip chip; | 104 | struct pwm_chip chip; |
| 105 | unsigned int clk_rate; | 105 | unsigned int clk_rate; |
| 106 | void __iomem *mmio_base; | 106 | void __iomem *mmio_base; |
| 107 | unsigned long period_cycles[NUM_PWM_CHANNEL]; | ||
| 107 | }; | 108 | }; |
| 108 | 109 | ||
| 109 | static inline struct ehrpwm_pwm_chip *to_ehrpwm_pwm_chip(struct pwm_chip *chip) | 110 | static inline struct ehrpwm_pwm_chip *to_ehrpwm_pwm_chip(struct pwm_chip *chip) |
| @@ -210,6 +211,7 @@ static int ehrpwm_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, | |||
| 210 | unsigned long long c; | 211 | unsigned long long c; |
| 211 | unsigned long period_cycles, duty_cycles; | 212 | unsigned long period_cycles, duty_cycles; |
| 212 | unsigned short ps_divval, tb_divval; | 213 | unsigned short ps_divval, tb_divval; |
| 214 | int i; | ||
| 213 | 215 | ||
| 214 | if (period_ns < 0 || duty_ns < 0 || period_ns > NSEC_PER_SEC) | 216 | if (period_ns < 0 || duty_ns < 0 || period_ns > NSEC_PER_SEC) |
| 215 | return -ERANGE; | 217 | return -ERANGE; |
| @@ -229,6 +231,28 @@ static int ehrpwm_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, | |||
| 229 | duty_cycles = (unsigned long)c; | 231 | duty_cycles = (unsigned long)c; |
| 230 | } | 232 | } |
| 231 | 233 | ||
| 234 | /* | ||
| 235 | * Period values should be same for multiple PWM channels as IP uses | ||
| 236 | * same period register for multiple channels. | ||
| 237 | */ | ||
| 238 | for (i = 0; i < NUM_PWM_CHANNEL; i++) { | ||
| 239 | if (pc->period_cycles[i] && | ||
| 240 | (pc->period_cycles[i] != period_cycles)) { | ||
| 241 | /* | ||
| 242 | * Allow channel to reconfigure period if no other | ||
| 243 | * channels being configured. | ||
| 244 | */ | ||
| 245 | if (i == pwm->hwpwm) | ||
| 246 | continue; | ||
| 247 | |||
| 248 | dev_err(chip->dev, "Period value conflicts with channel %d\n", | ||
| 249 | i); | ||
| 250 | return -EINVAL; | ||
| 251 | } | ||
| 252 | } | ||
| 253 | |||
| 254 | pc->period_cycles[pwm->hwpwm] = period_cycles; | ||
| 255 | |||
| 232 | /* Configure clock prescaler to support Low frequency PWM wave */ | 256 | /* Configure clock prescaler to support Low frequency PWM wave */ |
| 233 | if (set_prescale_div(period_cycles/PERIOD_MAX, &ps_divval, | 257 | if (set_prescale_div(period_cycles/PERIOD_MAX, &ps_divval, |
| 234 | &tb_divval)) { | 258 | &tb_divval)) { |
| @@ -320,10 +344,15 @@ static void ehrpwm_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) | |||
| 320 | 344 | ||
| 321 | static void ehrpwm_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) | 345 | static void ehrpwm_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) |
| 322 | { | 346 | { |
| 347 | struct ehrpwm_pwm_chip *pc = to_ehrpwm_pwm_chip(chip); | ||
| 348 | |||
| 323 | if (test_bit(PWMF_ENABLED, &pwm->flags)) { | 349 | if (test_bit(PWMF_ENABLED, &pwm->flags)) { |
| 324 | dev_warn(chip->dev, "Removing PWM device without disabling\n"); | 350 | dev_warn(chip->dev, "Removing PWM device without disabling\n"); |
| 325 | pm_runtime_put_sync(chip->dev); | 351 | pm_runtime_put_sync(chip->dev); |
| 326 | } | 352 | } |
| 353 | |||
| 354 | /* set period value to zero on free */ | ||
| 355 | pc->period_cycles[pwm->hwpwm] = 0; | ||
| 327 | } | 356 | } |
| 328 | 357 | ||
| 329 | static const struct pwm_ops ehrpwm_pwm_ops = { | 358 | static const struct pwm_ops ehrpwm_pwm_ops = { |
