aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/pwm.h88
1 files changed, 88 insertions, 0 deletions
diff --git a/include/linux/pwm.h b/include/linux/pwm.h
index 17018f3c066e..fd1092729ed6 100644
--- a/include/linux/pwm.h
+++ b/include/linux/pwm.h
@@ -148,6 +148,94 @@ static inline void pwm_get_args(const struct pwm_device *pwm,
148} 148}
149 149
150/** 150/**
151 * pwm_init_state() - prepare a new state to be applied with pwm_apply_state()
152 * @pwm: PWM device
153 * @state: state to fill with the prepared PWM state
154 *
155 * This functions prepares a state that can later be tweaked and applied
156 * to the PWM device with pwm_apply_state(). This is a convenient function
157 * that first retrieves the current PWM state and the replaces the period
158 * and polarity fields with the reference values defined in pwm->args.
159 * Once the function returns, you can adjust the ->enabled and ->duty_cycle
160 * fields according to your needs before calling pwm_apply_state().
161 *
162 * ->duty_cycle is initially set to zero to avoid cases where the current
163 * ->duty_cycle value exceed the pwm_args->period one, which would trigger
164 * an error if the user calls pwm_apply_state() without adjusting ->duty_cycle
165 * first.
166 */
167static inline void pwm_init_state(const struct pwm_device *pwm,
168 struct pwm_state *state)
169{
170 struct pwm_args args;
171
172 /* First get the current state. */
173 pwm_get_state(pwm, state);
174
175 /* Then fill it with the reference config */
176 pwm_get_args(pwm, &args);
177
178 state->period = args.period;
179 state->polarity = args.polarity;
180 state->duty_cycle = 0;
181}
182
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 */
196static inline unsigned int
197pwm_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 */
224static inline int
225pwm_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/**
151 * struct pwm_ops - PWM controller operations 239 * struct pwm_ops - PWM controller operations
152 * @request: optional hook for requesting a PWM 240 * @request: optional hook for requesting a PWM
153 * @free: optional hook for freeing a PWM 241 * @free: optional hook for freeing a PWM