pwm: lpss: Add get_state callback
authorHans de Goede <hdegoede@redhat.com>
Fri, 12 Oct 2018 10:12:29 +0000 (12:12 +0200)
committerThierry Reding <thierry.reding@gmail.com>
Fri, 12 Oct 2018 10:33:02 +0000 (12:33 +0200)
Add a get_state callback so that the initial state correctly reflects
the actual hardware state.

Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: Jani Nikula <jani.nikula@intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
drivers/pwm/pwm-lpss.c

index 723ca9de83256bea374e41037dca81cd1b04fbb2..ea93ef9f3672f684400d972bb68b578bbbee6408 100644 (file)
@@ -159,8 +159,42 @@ static int pwm_lpss_apply(struct pwm_chip *chip, struct pwm_device *pwm,
        return 0;
 }
 
+/* This function gets called once from pwmchip_add to get the initial state */
+static void pwm_lpss_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
+                              struct pwm_state *state)
+{
+       struct pwm_lpss_chip *lpwm = to_lpwm(chip);
+       unsigned long base_unit_range;
+       unsigned long long base_unit, freq, on_time_div;
+       u32 ctrl;
+
+       base_unit_range = BIT(lpwm->info->base_unit_bits);
+
+       ctrl = pwm_lpss_read(pwm);
+       on_time_div = 255 - (ctrl & PWM_ON_TIME_DIV_MASK);
+       base_unit = (ctrl >> PWM_BASE_UNIT_SHIFT) & (base_unit_range - 1);
+
+       freq = base_unit * lpwm->info->clk_rate;
+       do_div(freq, base_unit_range);
+       if (freq == 0)
+               state->period = NSEC_PER_SEC;
+       else
+               state->period = NSEC_PER_SEC / (unsigned long)freq;
+
+       on_time_div *= state->period;
+       do_div(on_time_div, 255);
+       state->duty_cycle = on_time_div;
+
+       state->polarity = PWM_POLARITY_NORMAL;
+       state->enabled = !!(ctrl & PWM_ENABLE);
+
+       if (state->enabled)
+               pm_runtime_get(chip->dev);
+}
+
 static const struct pwm_ops pwm_lpss_ops = {
        .apply = pwm_lpss_apply,
+       .get_state = pwm_lpss_get_state,
        .owner = THIS_MODULE,
 };