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);
}
static int gb_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
int duty_ns, int period_ns)
static int gb_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
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);
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,
enum pwm_polarity polarity)
{
struct gb_pwm_chip *pwmc = pwm_chip_to_gb_pwm_chip(chip);
if (!state->enabled) {
if (enabled)
gb_pwm_disable_operation(pwmc, pwm->hwpwm);
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)
{
struct gb_pwm_chip *pwmc = pwm_chip_to_gb_pwm_chip(chip);
if (duty_cycle > period)
duty_cycle = period;
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)
{
struct gb_pwm_chip *pwmc = pwm_chip_to_gb_pwm_chip(chip);
/* enable/disable */
if (!enabled)
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 = {
.request = gb_pwm_request,
.free = gb_pwm_free,
.config = gb_pwm_config,
.set_polarity = gb_pwm_set_polarity,
.enable = gb_pwm_enable,
.disable = gb_pwm_disable,
.apply = gb_pwm_apply,
.owner = THIS_MODULE,
};