diff options
| author | Martin Blumenstingl <martin.blumenstingl@googlemail.com> | 2019-06-12 21:59:05 +0200 | 
|---|---|---|
| committer | Thierry Reding <thierry.reding@gmail.com> | 2019-06-26 11:39:09 +0200 | 
| commit | 8bbf316453818a47468702f26804e4ced3065c0f (patch) | |
| tree | da9214502c4d5d2a1cf51cdd5b3c761cb57e50b4 /drivers/pwm/pwm-meson.c | |
| parent | a50a49a45140a85e3cb8d02859e13b78fafd030b (diff) | |
| download | blackbird-op-linux-8bbf316453818a47468702f26804e4ced3065c0f.tar.gz blackbird-op-linux-8bbf316453818a47468702f26804e4ced3065c0f.zip | |
pwm: meson: Add the per-channel register offsets and bits in a struct
Introduce struct meson_pwm_channel_data which contains the per-channel
offsets for the PWM register and REG_MISC_AB bits. Replace the existing
switch (pwm->hwpwm) statements with an access to the new struct.
This simplifies the code and will make it easier to implement
pwm_ops.get_state() because the switch-case which all per-channel
registers and offsets (as previously implemented in meson_pwm_enable())
doesn't have to be duplicated.
No functional changes intended.
Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
Diffstat (limited to 'drivers/pwm/pwm-meson.c')
| -rw-r--r-- | drivers/pwm/pwm-meson.c | 90 | 
1 files changed, 34 insertions, 56 deletions
| diff --git a/drivers/pwm/pwm-meson.c b/drivers/pwm/pwm-meson.c index 207e594c2d99..56f603e8023a 100644 --- a/drivers/pwm/pwm-meson.c +++ b/drivers/pwm/pwm-meson.c @@ -39,9 +39,27 @@  #define MESON_NUM_PWMS		2 -static const unsigned int mux_reg_shifts[] = { -	MISC_A_CLK_SEL_SHIFT, -	MISC_B_CLK_SEL_SHIFT +static struct meson_pwm_channel_data { +	u8		reg_offset; +	u8		clk_sel_shift; +	u8		clk_div_shift; +	u32		clk_en_mask; +	u32		pwm_en_mask; +} meson_pwm_per_channel_data[MESON_NUM_PWMS] = { +	{ +		.reg_offset	= REG_PWM_A, +		.clk_sel_shift	= MISC_A_CLK_SEL_SHIFT, +		.clk_div_shift	= MISC_A_CLK_DIV_SHIFT, +		.clk_en_mask	= MISC_A_CLK_EN, +		.pwm_en_mask	= MISC_A_EN, +	}, +	{ +		.reg_offset	= REG_PWM_B, +		.clk_sel_shift	= MISC_B_CLK_SEL_SHIFT, +		.clk_div_shift	= MISC_B_CLK_DIV_SHIFT, +		.clk_en_mask	= MISC_B_CLK_EN, +		.pwm_en_mask	= MISC_B_EN, +	}  };  struct meson_pwm_channel { @@ -194,43 +212,26 @@ static int meson_pwm_calc(struct meson_pwm *meson, struct pwm_device *pwm,  static void meson_pwm_enable(struct meson_pwm *meson, struct pwm_device *pwm)  {  	struct meson_pwm_channel *channel = pwm_get_chip_data(pwm); -	u32 value, clk_shift, clk_enable, enable; -	unsigned int offset; +	struct meson_pwm_channel_data *channel_data;  	unsigned long flags; +	u32 value; -	switch (pwm->hwpwm) { -	case 0: -		clk_shift = MISC_A_CLK_DIV_SHIFT; -		clk_enable = MISC_A_CLK_EN; -		enable = MISC_A_EN; -		offset = REG_PWM_A; -		break; - -	case 1: -		clk_shift = MISC_B_CLK_DIV_SHIFT; -		clk_enable = MISC_B_CLK_EN; -		enable = MISC_B_EN; -		offset = REG_PWM_B; -		break; - -	default: -		return; -	} +	channel_data = &meson_pwm_per_channel_data[pwm->hwpwm];  	spin_lock_irqsave(&meson->lock, flags);  	value = readl(meson->base + REG_MISC_AB); -	value &= ~(MISC_CLK_DIV_MASK << clk_shift); -	value |= channel->pre_div << clk_shift; -	value |= clk_enable; +	value &= ~(MISC_CLK_DIV_MASK << channel_data->clk_div_shift); +	value |= channel->pre_div << channel_data->clk_div_shift; +	value |= channel_data->clk_en_mask;  	writel(value, meson->base + REG_MISC_AB);  	value = FIELD_PREP(PWM_HIGH_MASK, channel->hi) |  		FIELD_PREP(PWM_LOW_MASK, channel->lo); -	writel(value, meson->base + offset); +	writel(value, meson->base + channel_data->reg_offset);  	value = readl(meson->base + REG_MISC_AB); -	value |= enable; +	value |= channel_data->pwm_en_mask;  	writel(value, meson->base + REG_MISC_AB);  	spin_unlock_irqrestore(&meson->lock, flags); @@ -238,26 +239,13 @@ static void meson_pwm_enable(struct meson_pwm *meson, struct pwm_device *pwm)  static void meson_pwm_disable(struct meson_pwm *meson, struct pwm_device *pwm)  { -	u32 value, enable;  	unsigned long flags; - -	switch (pwm->hwpwm) { -	case 0: -		enable = MISC_A_EN; -		break; - -	case 1: -		enable = MISC_B_EN; -		break; - -	default: -		return; -	} +	u32 value;  	spin_lock_irqsave(&meson->lock, flags);  	value = readl(meson->base + REG_MISC_AB); -	value &= ~enable; +	value &= ~meson_pwm_per_channel_data[pwm->hwpwm].pwm_en_mask;  	writel(value, meson->base + REG_MISC_AB);  	spin_unlock_irqrestore(&meson->lock, flags); @@ -309,18 +297,7 @@ static void meson_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,  	if (!state)  		return; -	switch (pwm->hwpwm) { -	case 0: -		mask = MISC_A_EN; -		break; - -	case 1: -		mask = MISC_B_EN; -		break; - -	default: -		return; -	} +	mask = meson_pwm_per_channel_data[pwm->hwpwm].pwm_en_mask;  	value = readl(meson->base + REG_MISC_AB);  	state->enabled = (value & mask) != 0; @@ -467,7 +444,8 @@ static int meson_pwm_init_channels(struct meson_pwm *meson)  		init.num_parents = meson->data->num_parents;  		channel->mux.reg = meson->base + REG_MISC_AB; -		channel->mux.shift = mux_reg_shifts[i]; +		channel->mux.shift = +				meson_pwm_per_channel_data[i].clk_sel_shift;  		channel->mux.mask = MISC_CLK_SEL_MASK;  		channel->mux.flags = 0;  		channel->mux.lock = &meson->lock; | 

