mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-14 16:23:51 +08:00
pwm: clps71xx: Implement .apply() callback
To eventually get rid of all legacy drivers convert this driver to the modern world implementing .apply(). This fixes a small issue in clps711x_get_duty() en passant: the multiplication v * 0xf might have overflown. Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
This commit is contained in:
parent
09f688f071
commit
4225cd01d3
@ -23,29 +23,6 @@ static inline struct clps711x_chip *to_clps711x_chip(struct pwm_chip *chip)
|
|||||||
return container_of(chip, struct clps711x_chip, chip);
|
return container_of(chip, struct clps711x_chip, chip);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clps711x_pwm_update_val(struct clps711x_chip *priv, u32 n, u32 v)
|
|
||||||
{
|
|
||||||
/* PWM0 - bits 4..7, PWM1 - bits 8..11 */
|
|
||||||
u32 shift = (n + 1) * 4;
|
|
||||||
unsigned long flags;
|
|
||||||
u32 tmp;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&priv->lock, flags);
|
|
||||||
|
|
||||||
tmp = readl(priv->pmpcon);
|
|
||||||
tmp &= ~(0xf << shift);
|
|
||||||
tmp |= v << shift;
|
|
||||||
writel(tmp, priv->pmpcon);
|
|
||||||
|
|
||||||
spin_unlock_irqrestore(&priv->lock, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned int clps711x_get_duty(struct pwm_device *pwm, unsigned int v)
|
|
||||||
{
|
|
||||||
/* Duty cycle 0..15 max */
|
|
||||||
return DIV64_U64_ROUND_CLOSEST(v * 0xf, pwm->args.period);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int clps711x_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
|
static int clps711x_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
|
||||||
{
|
{
|
||||||
struct clps711x_chip *priv = to_clps711x_chip(chip);
|
struct clps711x_chip *priv = to_clps711x_chip(chip);
|
||||||
@ -60,44 +37,41 @@ static int clps711x_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int clps711x_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
|
static int clps711x_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||||
int duty_ns, int period_ns)
|
const struct pwm_state *state)
|
||||||
{
|
{
|
||||||
struct clps711x_chip *priv = to_clps711x_chip(chip);
|
struct clps711x_chip *priv = to_clps711x_chip(chip);
|
||||||
unsigned int duty;
|
/* PWM0 - bits 4..7, PWM1 - bits 8..11 */
|
||||||
|
u32 shift = (pwm->hwpwm + 1) * 4;
|
||||||
|
unsigned long flags;
|
||||||
|
u32 pmpcon, val;
|
||||||
|
|
||||||
if (period_ns != pwm->args.period)
|
if (state->polarity != PWM_POLARITY_NORMAL)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
duty = clps711x_get_duty(pwm, duty_ns);
|
if (state->period != pwm->args.period)
|
||||||
clps711x_pwm_update_val(priv, pwm->hwpwm, duty);
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (state->enabled)
|
||||||
|
val = mul_u64_u64_div_u64(state->duty_cycle, 0xf, state->period);
|
||||||
|
else
|
||||||
|
val = 0;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&priv->lock, flags);
|
||||||
|
|
||||||
|
pmpcon = readl(priv->pmpcon);
|
||||||
|
pmpcon &= ~(0xf << shift);
|
||||||
|
pmpcon |= val << shift;
|
||||||
|
writel(pmpcon, priv->pmpcon);
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&priv->lock, flags);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int clps711x_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
|
|
||||||
{
|
|
||||||
struct clps711x_chip *priv = to_clps711x_chip(chip);
|
|
||||||
unsigned int duty;
|
|
||||||
|
|
||||||
duty = clps711x_get_duty(pwm, pwm_get_duty_cycle(pwm));
|
|
||||||
clps711x_pwm_update_val(priv, pwm->hwpwm, duty);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void clps711x_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
|
|
||||||
{
|
|
||||||
struct clps711x_chip *priv = to_clps711x_chip(chip);
|
|
||||||
|
|
||||||
clps711x_pwm_update_val(priv, pwm->hwpwm, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct pwm_ops clps711x_pwm_ops = {
|
static const struct pwm_ops clps711x_pwm_ops = {
|
||||||
.request = clps711x_pwm_request,
|
.request = clps711x_pwm_request,
|
||||||
.config = clps711x_pwm_config,
|
.apply = clps711x_pwm_apply,
|
||||||
.enable = clps711x_pwm_enable,
|
|
||||||
.disable = clps711x_pwm_disable,
|
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user