diff options
author | Boris Brezillon <boris.brezillon@free-electrons.com> | 2016-06-14 05:13:10 -0400 |
---|---|---|
committer | Thierry Reding <thierry.reding@gmail.com> | 2016-07-08 11:52:19 -0400 |
commit | f6f3bddf7b2b994a927808fcc5a3d07069c35956 (patch) | |
tree | ea4b977c05eee37a08393720a22e69e5c100c0f5 | |
parent | a6a0dbbcfa469cf3e5c4d9522106c0b7b9e9e373 (diff) |
pwm: Add relative duty cycle manipulation helpers
The PWM framework expects PWM users to configure the duty cycle in nano-
seconds, but many users want to express the duty cycle relatively to the
period value (i.e. duty_cycle = 33% of the period).
Add the pwm_{get,set}_relative_duty_cycle() helpers to ease this kind of
conversion.
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
Tested-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
-rw-r--r-- | include/linux/pwm.h | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/include/linux/pwm.h b/include/linux/pwm.h index a100f6e80738..fd1092729ed6 100644 --- a/include/linux/pwm.h +++ b/include/linux/pwm.h | |||
@@ -181,6 +181,61 @@ static inline void pwm_init_state(const struct pwm_device *pwm, | |||
181 | } | 181 | } |
182 | 182 | ||
183 | /** | 183 | /** |
184 | * pwm_get_relative_duty_cycle() - Get a relative duty cycle value | ||
185 | * @state: PWM state to extract the duty cycle from | ||
186 | * @scale: target scale of the relative duty cycle | ||
187 | * | ||
188 | * This functions converts the absolute duty cycle stored in @state (expressed | ||
189 | * in nanosecond) into a value relative to the period. | ||
190 | * | ||
191 | * For example if you want to get the duty_cycle expressed in percent, call: | ||
192 | * | ||
193 | * pwm_get_state(pwm, &state); | ||
194 | * duty = pwm_get_relative_duty_cycle(&state, 100); | ||
195 | */ | ||
196 | static inline unsigned int | ||
197 | pwm_get_relative_duty_cycle(const struct pwm_state *state, unsigned int scale) | ||
198 | { | ||
199 | if (!state->period) | ||
200 | return 0; | ||
201 | |||
202 | return DIV_ROUND_CLOSEST_ULL((u64)state->duty_cycle * scale, | ||
203 | state->period); | ||
204 | } | ||
205 | |||
206 | /** | ||
207 | * pwm_set_relative_duty_cycle() - Set a relative duty cycle value | ||
208 | * @state: PWM state to fill | ||
209 | * @duty_cycle: relative duty cycle value | ||
210 | * @scale: scale in which @duty_cycle is expressed | ||
211 | * | ||
212 | * This functions converts a relative into an absolute duty cycle (expressed | ||
213 | * in nanoseconds), and puts the result in state->duty_cycle. | ||
214 | * | ||
215 | * For example if you want to configure a 50% duty cycle, call: | ||
216 | * | ||
217 | * pwm_init_state(pwm, &state); | ||
218 | * pwm_set_relative_duty_cycle(&state, 50, 100); | ||
219 | * pwm_apply_state(pwm, &state); | ||
220 | * | ||
221 | * This functions returns -EINVAL if @duty_cycle and/or @scale are | ||
222 | * inconsistent (@scale == 0 or @duty_cycle > @scale). | ||
223 | */ | ||
224 | static inline int | ||
225 | pwm_set_relative_duty_cycle(struct pwm_state *state, unsigned int duty_cycle, | ||
226 | unsigned int scale) | ||
227 | { | ||
228 | if (!scale || duty_cycle > scale) | ||
229 | return -EINVAL; | ||
230 | |||
231 | state->duty_cycle = DIV_ROUND_CLOSEST_ULL((u64)duty_cycle * | ||
232 | state->period, | ||
233 | scale); | ||
234 | |||
235 | return 0; | ||
236 | } | ||
237 | |||
238 | /** | ||
184 | * struct pwm_ops - PWM controller operations | 239 | * struct pwm_ops - PWM controller operations |
185 | * @request: optional hook for requesting a PWM | 240 | * @request: optional hook for requesting a PWM |
186 | * @free: optional hook for freeing a PWM | 241 | * @free: optional hook for freeing a PWM |