Skip to content

Commit 888a623

Browse files
mediatek-jitaothierryreding
authored andcommitted
pwm: mtk-disp: Implement atomic API .apply()
Switch the driver to support the .apply() method. Signed-off-by: Jitao Shi <[email protected]> Signed-off-by: Thierry Reding <[email protected]>
1 parent d7a4e58 commit 888a623

File tree

1 file changed

+41
-54
lines changed

1 file changed

+41
-54
lines changed

drivers/pwm/pwm-mtk-disp.c

Lines changed: 41 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ struct mtk_disp_pwm {
4747
struct clk *clk_main;
4848
struct clk *clk_mm;
4949
void __iomem *base;
50+
bool enabled;
5051
};
5152

5253
static inline struct mtk_disp_pwm *to_mtk_disp_pwm(struct pwm_chip *chip)
@@ -66,25 +67,45 @@ static void mtk_disp_pwm_update_bits(struct mtk_disp_pwm *mdp, u32 offset,
6667
writel(value, address);
6768
}
6869

69-
static int mtk_disp_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
70-
int duty_ns, int period_ns)
70+
static int mtk_disp_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
71+
const struct pwm_state *state)
7172
{
7273
struct mtk_disp_pwm *mdp = to_mtk_disp_pwm(chip);
7374
u32 clk_div, period, high_width, value;
7475
u64 div, rate;
7576
int err;
7677

77-
err = clk_prepare_enable(mdp->clk_main);
78-
if (err < 0) {
79-
dev_err(chip->dev, "Can't enable mdp->clk_main: %pe\n", ERR_PTR(err));
80-
return err;
78+
if (state->polarity != PWM_POLARITY_NORMAL)
79+
return -EINVAL;
80+
81+
if (!state->enabled) {
82+
mtk_disp_pwm_update_bits(mdp, DISP_PWM_EN, mdp->data->enable_mask,
83+
0x0);
84+
85+
if (mdp->enabled) {
86+
clk_disable_unprepare(mdp->clk_mm);
87+
clk_disable_unprepare(mdp->clk_main);
88+
}
89+
90+
mdp->enabled = false;
91+
return 0;
8192
}
8293

83-
err = clk_prepare_enable(mdp->clk_mm);
84-
if (err < 0) {
85-
dev_err(chip->dev, "Can't enable mdp->clk_mm: %pe\n", ERR_PTR(err));
86-
clk_disable_unprepare(mdp->clk_main);
87-
return err;
94+
if (!mdp->enabled) {
95+
err = clk_prepare_enable(mdp->clk_main);
96+
if (err < 0) {
97+
dev_err(chip->dev, "Can't enable mdp->clk_main: %pe\n",
98+
ERR_PTR(err));
99+
return err;
100+
}
101+
102+
err = clk_prepare_enable(mdp->clk_mm);
103+
if (err < 0) {
104+
dev_err(chip->dev, "Can't enable mdp->clk_mm: %pe\n",
105+
ERR_PTR(err));
106+
clk_disable_unprepare(mdp->clk_main);
107+
return err;
108+
}
88109
}
89110

90111
/*
@@ -98,20 +119,22 @@ static int mtk_disp_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
98119
* high_width = (PWM_CLK_RATE * duty_ns) / (10^9 * (clk_div + 1))
99120
*/
100121
rate = clk_get_rate(mdp->clk_main);
101-
clk_div = div_u64(rate * period_ns, NSEC_PER_SEC) >>
122+
clk_div = div_u64(rate * state->period, NSEC_PER_SEC) >>
102123
PWM_PERIOD_BIT_WIDTH;
103124
if (clk_div > PWM_CLKDIV_MAX) {
104-
clk_disable_unprepare(mdp->clk_mm);
105-
clk_disable_unprepare(mdp->clk_main);
125+
if (!mdp->enabled) {
126+
clk_disable_unprepare(mdp->clk_mm);
127+
clk_disable_unprepare(mdp->clk_main);
128+
}
106129
return -EINVAL;
107130
}
108131

109132
div = NSEC_PER_SEC * (clk_div + 1);
110-
period = div64_u64(rate * period_ns, div);
133+
period = div64_u64(rate * state->period, div);
111134
if (period > 0)
112135
period--;
113136

114-
high_width = div64_u64(rate * duty_ns, div);
137+
high_width = div64_u64(rate * state->duty_cycle, div);
115138
value = period | (high_width << PWM_HIGH_WIDTH_SHIFT);
116139

117140
mtk_disp_pwm_update_bits(mdp, mdp->data->con0,
@@ -141,51 +164,15 @@ static int mtk_disp_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
141164
mdp->data->con0_sel);
142165
}
143166

144-
clk_disable_unprepare(mdp->clk_mm);
145-
clk_disable_unprepare(mdp->clk_main);
146-
147-
return 0;
148-
}
149-
150-
static int mtk_disp_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
151-
{
152-
struct mtk_disp_pwm *mdp = to_mtk_disp_pwm(chip);
153-
int err;
154-
155-
err = clk_prepare_enable(mdp->clk_main);
156-
if (err < 0) {
157-
dev_err(chip->dev, "Can't enable mdp->clk_main: %pe\n", ERR_PTR(err));
158-
return err;
159-
}
160-
161-
err = clk_prepare_enable(mdp->clk_mm);
162-
if (err < 0) {
163-
dev_err(chip->dev, "Can't enable mdp->clk_mm: %pe\n", ERR_PTR(err));
164-
clk_disable_unprepare(mdp->clk_main);
165-
return err;
166-
}
167-
168167
mtk_disp_pwm_update_bits(mdp, DISP_PWM_EN, mdp->data->enable_mask,
169168
mdp->data->enable_mask);
169+
mdp->enabled = true;
170170

171171
return 0;
172172
}
173173

174-
static void mtk_disp_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
175-
{
176-
struct mtk_disp_pwm *mdp = to_mtk_disp_pwm(chip);
177-
178-
mtk_disp_pwm_update_bits(mdp, DISP_PWM_EN, mdp->data->enable_mask,
179-
0x0);
180-
181-
clk_disable_unprepare(mdp->clk_mm);
182-
clk_disable_unprepare(mdp->clk_main);
183-
}
184-
185174
static const struct pwm_ops mtk_disp_pwm_ops = {
186-
.config = mtk_disp_pwm_config,
187-
.enable = mtk_disp_pwm_enable,
188-
.disable = mtk_disp_pwm_disable,
175+
.apply = mtk_disp_pwm_apply,
189176
.owner = THIS_MODULE,
190177
};
191178

0 commit comments

Comments
 (0)