Loading include/linux/pwm.h +88 −0 Original line number Diff line number Diff line Loading @@ -147,6 +147,94 @@ static inline void pwm_get_args(const struct pwm_device *pwm, *args = pwm->args; } /** * pwm_init_state() - prepare a new state to be applied with pwm_apply_state() * @pwm: PWM device * @state: state to fill with the prepared PWM state * * This functions prepares a state that can later be tweaked and applied * to the PWM device with pwm_apply_state(). This is a convenient function * that first retrieves the current PWM state and the replaces the period * and polarity fields with the reference values defined in pwm->args. * Once the function returns, you can adjust the ->enabled and ->duty_cycle * fields according to your needs before calling pwm_apply_state(). * * ->duty_cycle is initially set to zero to avoid cases where the current * ->duty_cycle value exceed the pwm_args->period one, which would trigger * an error if the user calls pwm_apply_state() without adjusting ->duty_cycle * first. */ static inline void pwm_init_state(const struct pwm_device *pwm, struct pwm_state *state) { struct pwm_args args; /* First get the current state. */ pwm_get_state(pwm, state); /* Then fill it with the reference config */ pwm_get_args(pwm, &args); state->period = args.period; state->polarity = args.polarity; state->duty_cycle = 0; } /** * pwm_get_relative_duty_cycle() - Get a relative duty cycle value * @state: PWM state to extract the duty cycle from * @scale: target scale of the relative duty cycle * * This functions converts the absolute duty cycle stored in @state (expressed * in nanosecond) into a value relative to the period. * * For example if you want to get the duty_cycle expressed in percent, call: * * pwm_get_state(pwm, &state); * duty = pwm_get_relative_duty_cycle(&state, 100); */ static inline unsigned int pwm_get_relative_duty_cycle(const struct pwm_state *state, unsigned int scale) { if (!state->period) return 0; return DIV_ROUND_CLOSEST_ULL((u64)state->duty_cycle * scale, state->period); } /** * pwm_set_relative_duty_cycle() - Set a relative duty cycle value * @state: PWM state to fill * @duty_cycle: relative duty cycle value * @scale: scale in which @duty_cycle is expressed * * This functions converts a relative into an absolute duty cycle (expressed * in nanoseconds), and puts the result in state->duty_cycle. * * For example if you want to configure a 50% duty cycle, call: * * pwm_init_state(pwm, &state); * pwm_set_relative_duty_cycle(&state, 50, 100); * pwm_apply_state(pwm, &state); * * This functions returns -EINVAL if @duty_cycle and/or @scale are * inconsistent (@scale == 0 or @duty_cycle > @scale). */ static inline int pwm_set_relative_duty_cycle(struct pwm_state *state, unsigned int duty_cycle, unsigned int scale) { if (!scale || duty_cycle > scale) return -EINVAL; state->duty_cycle = DIV_ROUND_CLOSEST_ULL((u64)duty_cycle * state->period, scale); return 0; } /** * struct pwm_ops - PWM controller operations * @request: optional hook for requesting a PWM Loading Loading
include/linux/pwm.h +88 −0 Original line number Diff line number Diff line Loading @@ -147,6 +147,94 @@ static inline void pwm_get_args(const struct pwm_device *pwm, *args = pwm->args; } /** * pwm_init_state() - prepare a new state to be applied with pwm_apply_state() * @pwm: PWM device * @state: state to fill with the prepared PWM state * * This functions prepares a state that can later be tweaked and applied * to the PWM device with pwm_apply_state(). This is a convenient function * that first retrieves the current PWM state and the replaces the period * and polarity fields with the reference values defined in pwm->args. * Once the function returns, you can adjust the ->enabled and ->duty_cycle * fields according to your needs before calling pwm_apply_state(). * * ->duty_cycle is initially set to zero to avoid cases where the current * ->duty_cycle value exceed the pwm_args->period one, which would trigger * an error if the user calls pwm_apply_state() without adjusting ->duty_cycle * first. */ static inline void pwm_init_state(const struct pwm_device *pwm, struct pwm_state *state) { struct pwm_args args; /* First get the current state. */ pwm_get_state(pwm, state); /* Then fill it with the reference config */ pwm_get_args(pwm, &args); state->period = args.period; state->polarity = args.polarity; state->duty_cycle = 0; } /** * pwm_get_relative_duty_cycle() - Get a relative duty cycle value * @state: PWM state to extract the duty cycle from * @scale: target scale of the relative duty cycle * * This functions converts the absolute duty cycle stored in @state (expressed * in nanosecond) into a value relative to the period. * * For example if you want to get the duty_cycle expressed in percent, call: * * pwm_get_state(pwm, &state); * duty = pwm_get_relative_duty_cycle(&state, 100); */ static inline unsigned int pwm_get_relative_duty_cycle(const struct pwm_state *state, unsigned int scale) { if (!state->period) return 0; return DIV_ROUND_CLOSEST_ULL((u64)state->duty_cycle * scale, state->period); } /** * pwm_set_relative_duty_cycle() - Set a relative duty cycle value * @state: PWM state to fill * @duty_cycle: relative duty cycle value * @scale: scale in which @duty_cycle is expressed * * This functions converts a relative into an absolute duty cycle (expressed * in nanoseconds), and puts the result in state->duty_cycle. * * For example if you want to configure a 50% duty cycle, call: * * pwm_init_state(pwm, &state); * pwm_set_relative_duty_cycle(&state, 50, 100); * pwm_apply_state(pwm, &state); * * This functions returns -EINVAL if @duty_cycle and/or @scale are * inconsistent (@scale == 0 or @duty_cycle > @scale). */ static inline int pwm_set_relative_duty_cycle(struct pwm_state *state, unsigned int duty_cycle, unsigned int scale) { if (!scale || duty_cycle > scale) return -EINVAL; state->duty_cycle = DIV_ROUND_CLOSEST_ULL((u64)duty_cycle * state->period, scale); return 0; } /** * struct pwm_ops - PWM controller operations * @request: optional hook for requesting a PWM Loading