Skip to content

Commit

Permalink
pwm: tiecap: Implement .apply() callback
Browse files Browse the repository at this point in the history
To eventually get rid of all legacy drivers convert this driver to the
modern world implementing .apply(). This just pushes down a slightly
optimized variant of how legacy drivers are handled in the core.

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
  • Loading branch information
Uwe Kleine-König authored and Thierry Reding committed Jun 28, 2021
1 parent ec67fba commit 0ca7acd
Showing 1 changed file with 45 additions and 10 deletions.
55 changes: 45 additions & 10 deletions drivers/pwm/pwm-tiecap.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,13 @@ static inline struct ecap_pwm_chip *to_ecap_pwm_chip(struct pwm_chip *chip)
* duty_ns = 10^9 * duty_cycles / PWM_CLK_RATE
*/
static int ecap_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
int duty_ns, int period_ns)
int duty_ns, int period_ns, int enabled)
{
struct ecap_pwm_chip *pc = to_ecap_pwm_chip(chip);
u32 period_cycles, duty_cycles;
unsigned long long c;
u16 value;

if (period_ns > NSEC_PER_SEC)
return -ERANGE;

c = pc->clk_rate;
c = c * period_ns;
do_div(c, NSEC_PER_SEC);
Expand All @@ -82,7 +79,7 @@ static int ecap_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,

writew(value, pc->mmio_base + ECCTL2);

if (!pwm_is_enabled(pwm)) {
if (!enabled) {
/* Update active registers if not running */
writel(duty_cycles, pc->mmio_base + CAP2);
writel(period_cycles, pc->mmio_base + CAP1);
Expand All @@ -96,7 +93,7 @@ static int ecap_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
writel(period_cycles, pc->mmio_base + CAP3);
}

if (!pwm_is_enabled(pwm)) {
if (!enabled) {
value = readw(pc->mmio_base + ECCTL2);
/* Disable APWM mode to put APWM output Low */
value &= ~ECCTL2_APWM_MODE;
Expand Down Expand Up @@ -168,11 +165,49 @@ static void ecap_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
pm_runtime_put_sync(pc->chip.dev);
}

static int ecap_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
const struct pwm_state *state)
{
int err;
int enabled = pwm->state.enabled;

if (state->polarity != pwm->state.polarity) {

if (enabled) {
ecap_pwm_disable(chip, pwm);
enabled = false;
}

err = ecap_pwm_set_polarity(chip, pwm, state->polarity);
if (err)
return err;
}

if (!state->enabled) {
if (enabled)
ecap_pwm_disable(chip, pwm);
return 0;
}

if (state->period != pwm->state.period ||
state->duty_cycle != pwm->state.duty_cycle) {
if (state->period > NSEC_PER_SEC)
return -ERANGE;

err = ecap_pwm_config(chip, pwm, state->duty_cycle,
state->period, enabled);
if (err)
return err;
}

if (!enabled)
return ecap_pwm_enable(chip, pwm);

return 0;
}

static const struct pwm_ops ecap_pwm_ops = {
.config = ecap_pwm_config,
.set_polarity = ecap_pwm_set_polarity,
.enable = ecap_pwm_enable,
.disable = ecap_pwm_disable,
.apply = ecap_pwm_apply,
.owner = THIS_MODULE,
};

Expand Down

0 comments on commit 0ca7acd

Please sign in to comment.