pwm: lp3943: Implement .apply() callback
authorUwe Kleine-König <u.kleine-koenig@pengutronix.de>
Fri, 8 Apr 2022 15:22:39 +0000 (17:22 +0200)
committerThierry Reding <thierry.reding@gmail.com>
Fri, 22 Apr 2022 16:43:09 +0000 (18:43 +0200)
To eventually get rid of all legacy drivers convert this driver to the
modern world implementing .apply().

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
drivers/pwm/pwm-lp3943.c

index 2bd04ec..215ef90 100644 (file)
@@ -93,7 +93,7 @@ static void lp3943_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
 }
 
 static int lp3943_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
-                            int duty_ns, int period_ns)
+                            u64 duty_ns, u64 period_ns)
 {
        struct lp3943_pwm *lp3943_pwm = to_lp3943_pwm(chip);
        struct lp3943 *lp3943 = lp3943_pwm->lp3943;
@@ -118,15 +118,20 @@ static int lp3943_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
                reg_duty     = LP3943_REG_PWM1;
        }
 
-       period_ns = clamp(period_ns, LP3943_MIN_PERIOD, LP3943_MAX_PERIOD);
-       val       = (u8)(period_ns / LP3943_MIN_PERIOD - 1);
+       /*
+        * Note that after this clamping, period_ns fits into an int. This is
+        * helpful because we can resort to integer division below instead of
+        * the (more expensive) 64 bit division.
+        */
+       period_ns = clamp(period_ns, (u64)LP3943_MIN_PERIOD, (u64)LP3943_MAX_PERIOD);
+       val       = (u8)((int)period_ns / LP3943_MIN_PERIOD - 1);
 
        err = lp3943_write_byte(lp3943, reg_prescale, val);
        if (err)
                return err;
 
        duty_ns = min(duty_ns, period_ns);
-       val = (u8)(duty_ns * LP3943_MAX_DUTY / period_ns);
+       val = (u8)((int)duty_ns * LP3943_MAX_DUTY / (int)period_ns);
 
        return lp3943_write_byte(lp3943, reg_duty, val);
 }
@@ -183,12 +188,34 @@ static void lp3943_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
        lp3943_pwm_set_mode(lp3943_pwm, pwm_map, LP3943_GPIO_OUT_HIGH);
 }
 
+static int lp3943_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
+                           const struct pwm_state *state)
+{
+       int err;
+
+       if (state->polarity != PWM_POLARITY_NORMAL)
+               return -EINVAL;
+
+       if (!state->enabled) {
+               if (pwm->state.enabled)
+                       lp3943_pwm_disable(chip, pwm);
+               return 0;
+       }
+
+       err = lp3943_pwm_config(chip, pwm, state->duty_cycle, state->period);
+       if (err)
+               return err;
+
+       if (!pwm->state.enabled)
+               err = lp3943_pwm_enable(chip, pwm);
+
+       return err;
+}
+
 static const struct pwm_ops lp3943_pwm_ops = {
        .request        = lp3943_pwm_request,
        .free           = lp3943_pwm_free,
-       .config         = lp3943_pwm_config,
-       .enable         = lp3943_pwm_enable,
-       .disable        = lp3943_pwm_disable,
+       .apply          = lp3943_pwm_apply,
        .owner          = THIS_MODULE,
 };