staging: greybus: introduce pwm_ops::apply

Introduce newer .apply function in pwm_ops to replace legacy operations
including enable, disable, config and set_polarity.

This guarantees atomic changes of the pwm controller configuration.

Reviewed-by: Alex Elder <elder@linaro.org>
Signed-off-by: Song Chen <chensong_2000@189.cn>
Link: https://lore.kernel.org/r/1647597432-27586-1-git-send-email-chensong_2000@189.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Song Chen 2022-03-18 17:57:12 +08:00 committed by Greg Kroah-Hartman
parent 56bd392be5
commit 832ce36f44

View File

@ -204,43 +204,59 @@ static void gb_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
gb_pwm_deactivate_operation(pwmc, pwm->hwpwm); gb_pwm_deactivate_operation(pwmc, pwm->hwpwm);
} }
static int gb_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, static int gb_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
int duty_ns, int period_ns) const struct pwm_state *state)
{ {
int err;
bool enabled = pwm->state.enabled;
u64 period = state->period;
u64 duty_cycle = state->duty_cycle;
struct gb_pwm_chip *pwmc = pwm_chip_to_gb_pwm_chip(chip); struct gb_pwm_chip *pwmc = pwm_chip_to_gb_pwm_chip(chip);
return gb_pwm_config_operation(pwmc, pwm->hwpwm, duty_ns, period_ns); /* Set polarity */
}; if (state->polarity != pwm->state.polarity) {
if (enabled) {
gb_pwm_disable_operation(pwmc, pwm->hwpwm);
enabled = false;
}
err = gb_pwm_set_polarity_operation(pwmc, pwm->hwpwm, state->polarity);
if (err)
return err;
}
static int gb_pwm_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm, if (!state->enabled) {
enum pwm_polarity polarity) if (enabled)
{ gb_pwm_disable_operation(pwmc, pwm->hwpwm);
struct gb_pwm_chip *pwmc = pwm_chip_to_gb_pwm_chip(chip); return 0;
}
return gb_pwm_set_polarity_operation(pwmc, pwm->hwpwm, polarity); /*
}; * Set period and duty cycle
*
* PWM privodes 64-bit period and duty_cycle, but greybus only accepts
* 32-bit, so their values have to be limited to U32_MAX.
*/
if (period > U32_MAX)
period = U32_MAX;
static int gb_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) if (duty_cycle > period)
{ duty_cycle = period;
struct gb_pwm_chip *pwmc = pwm_chip_to_gb_pwm_chip(chip);
return gb_pwm_enable_operation(pwmc, pwm->hwpwm); err = gb_pwm_config_operation(pwmc, pwm->hwpwm, duty_cycle, period);
}; if (err)
return err;
static void gb_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) /* enable/disable */
{ if (!enabled)
struct gb_pwm_chip *pwmc = pwm_chip_to_gb_pwm_chip(chip); return gb_pwm_enable_operation(pwmc, pwm->hwpwm);
gb_pwm_disable_operation(pwmc, pwm->hwpwm); return 0;
}; }
static const struct pwm_ops gb_pwm_ops = { static const struct pwm_ops gb_pwm_ops = {
.request = gb_pwm_request, .request = gb_pwm_request,
.free = gb_pwm_free, .free = gb_pwm_free,
.config = gb_pwm_config, .apply = gb_pwm_apply,
.set_polarity = gb_pwm_set_polarity,
.enable = gb_pwm_enable,
.disable = gb_pwm_disable,
.owner = THIS_MODULE, .owner = THIS_MODULE,
}; };