diff options
author | Hans de Goede <hdegoede@redhat.com> | 2018-10-12 06:12:29 -0400 |
---|---|---|
committer | Thierry Reding <thierry.reding@gmail.com> | 2018-10-12 06:33:02 -0400 |
commit | 280fec4c3ad6701567d7d840506b9b1463a48b71 (patch) | |
tree | a0bdc970d208ffbb84b420fcc2b1a055b336819d /drivers/pwm | |
parent | 42885551cedb45961879d2fc3dc3c4dc545cc23e (diff) |
pwm: lpss: Add get_state callback
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>
Diffstat (limited to 'drivers/pwm')
-rw-r--r-- | drivers/pwm/pwm-lpss.c | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/drivers/pwm/pwm-lpss.c b/drivers/pwm/pwm-lpss.c index 723ca9de8325..ea93ef9f3672 100644 --- a/drivers/pwm/pwm-lpss.c +++ b/drivers/pwm/pwm-lpss.c | |||
@@ -159,8 +159,42 @@ static int pwm_lpss_apply(struct pwm_chip *chip, struct pwm_device *pwm, | |||
159 | return 0; | 159 | return 0; |
160 | } | 160 | } |
161 | 161 | ||
162 | /* This function gets called once from pwmchip_add to get the initial state */ | ||
163 | static void pwm_lpss_get_state(struct pwm_chip *chip, struct pwm_device *pwm, | ||
164 | struct pwm_state *state) | ||
165 | { | ||
166 | struct pwm_lpss_chip *lpwm = to_lpwm(chip); | ||
167 | unsigned long base_unit_range; | ||
168 | unsigned long long base_unit, freq, on_time_div; | ||
169 | u32 ctrl; | ||
170 | |||
171 | base_unit_range = BIT(lpwm->info->base_unit_bits); | ||
172 | |||
173 | ctrl = pwm_lpss_read(pwm); | ||
174 | on_time_div = 255 - (ctrl & PWM_ON_TIME_DIV_MASK); | ||
175 | base_unit = (ctrl >> PWM_BASE_UNIT_SHIFT) & (base_unit_range - 1); | ||
176 | |||
177 | freq = base_unit * lpwm->info->clk_rate; | ||
178 | do_div(freq, base_unit_range); | ||
179 | if (freq == 0) | ||
180 | state->period = NSEC_PER_SEC; | ||
181 | else | ||
182 | state->period = NSEC_PER_SEC / (unsigned long)freq; | ||
183 | |||
184 | on_time_div *= state->period; | ||
185 | do_div(on_time_div, 255); | ||
186 | state->duty_cycle = on_time_div; | ||
187 | |||
188 | state->polarity = PWM_POLARITY_NORMAL; | ||
189 | state->enabled = !!(ctrl & PWM_ENABLE); | ||
190 | |||
191 | if (state->enabled) | ||
192 | pm_runtime_get(chip->dev); | ||
193 | } | ||
194 | |||
162 | static const struct pwm_ops pwm_lpss_ops = { | 195 | static const struct pwm_ops pwm_lpss_ops = { |
163 | .apply = pwm_lpss_apply, | 196 | .apply = pwm_lpss_apply, |
197 | .get_state = pwm_lpss_get_state, | ||
164 | .owner = THIS_MODULE, | 198 | .owner = THIS_MODULE, |
165 | }; | 199 | }; |
166 | 200 | ||