summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/pwm/pwm-mediatek.c21
1 files changed, 14 insertions, 7 deletions
diff --git a/drivers/pwm/pwm-mediatek.c b/drivers/pwm/pwm-mediatek.c
index b6560e52c803..e4b595fc5a5e 100644
--- a/drivers/pwm/pwm-mediatek.c
+++ b/drivers/pwm/pwm-mediatek.c
@@ -170,7 +170,10 @@ static int pwm_mediatek_config(struct pwm_chip *chip, struct pwm_device *pwm,
do_div(resolution, clk_rate);
cnt_period = DIV_ROUND_CLOSEST_ULL((u64)period_ns * 1000, resolution);
- while (cnt_period > 8191) {
+ if (!cnt_period)
+ return -EINVAL;
+
+ while (cnt_period > 8192) {
resolution *= 2;
clkdiv++;
cnt_period = DIV_ROUND_CLOSEST_ULL((u64)period_ns * 1000,
@@ -193,9 +196,16 @@ static int pwm_mediatek_config(struct pwm_chip *chip, struct pwm_device *pwm,
}
cnt_duty = DIV_ROUND_CLOSEST_ULL((u64)duty_ns * 1000, resolution);
+
pwm_mediatek_writel(pc, pwm->hwpwm, PWMCON, BIT(15) | clkdiv);
- pwm_mediatek_writel(pc, pwm->hwpwm, reg_width, cnt_period);
- pwm_mediatek_writel(pc, pwm->hwpwm, reg_thres, cnt_duty);
+ pwm_mediatek_writel(pc, pwm->hwpwm, reg_width, cnt_period - 1);
+
+ if (cnt_duty) {
+ pwm_mediatek_writel(pc, pwm->hwpwm, reg_thres, cnt_duty - 1);
+ pwm_mediatek_enable(chip, pwm);
+ } else {
+ pwm_mediatek_disable(chip, pwm);
+ }
out:
pwm_mediatek_clk_disable(chip, pwm);
@@ -224,11 +234,8 @@ static int pwm_mediatek_apply(struct pwm_chip *chip, struct pwm_device *pwm,
if (err)
return err;
- if (!pwm->state.enabled) {
+ if (!pwm->state.enabled)
err = pwm_mediatek_clk_enable(chip, pwm);
- if (!err)
- pwm_mediatek_enable(chip, pwm);
- }
return err;
}