Skip to content

Commit 3f2b167

Browse files
mediatek-jitaothierryreding
authored andcommitted
pwm: mtk-disp: Implement atomic API .get_state()
Switch the driver to support the .get_state() method. Signed-off-by: Jitao Shi <[email protected]> [[email protected]: add missing linux/bitfield.h include] Signed-off-by: Thierry Reding <[email protected]>
1 parent 331e049 commit 3f2b167

File tree

1 file changed

+43
-0
lines changed

1 file changed

+43
-0
lines changed

drivers/pwm/pwm-mtk-disp.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* Author: YH Huang <[email protected]>
66
*/
77

8+
#include <linux/bitfield.h>
89
#include <linux/clk.h>
910
#include <linux/err.h>
1011
#include <linux/io.h>
@@ -171,8 +172,50 @@ static int mtk_disp_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
171172
return 0;
172173
}
173174

175+
static void mtk_disp_pwm_get_state(struct pwm_chip *chip,
176+
struct pwm_device *pwm,
177+
struct pwm_state *state)
178+
{
179+
struct mtk_disp_pwm *mdp = to_mtk_disp_pwm(chip);
180+
u64 rate, period, high_width;
181+
u32 clk_div, con0, con1;
182+
int err;
183+
184+
err = clk_prepare_enable(mdp->clk_main);
185+
if (err < 0) {
186+
dev_err(chip->dev, "Can't enable mdp->clk_main: %pe\n", ERR_PTR(err));
187+
return;
188+
}
189+
190+
err = clk_prepare_enable(mdp->clk_mm);
191+
if (err < 0) {
192+
dev_err(chip->dev, "Can't enable mdp->clk_mm: %pe\n", ERR_PTR(err));
193+
clk_disable_unprepare(mdp->clk_main);
194+
return;
195+
}
196+
197+
rate = clk_get_rate(mdp->clk_main);
198+
con0 = readl(mdp->base + mdp->data->con0);
199+
con1 = readl(mdp->base + mdp->data->con1);
200+
state->enabled = !!(con0 & BIT(0));
201+
clk_div = FIELD_GET(PWM_CLKDIV_MASK, con0);
202+
period = FIELD_GET(PWM_PERIOD_MASK, con1);
203+
/*
204+
* period has 12 bits, clk_div 11 and NSEC_PER_SEC has 30,
205+
* so period * (clk_div + 1) * NSEC_PER_SEC doesn't overflow.
206+
*/
207+
state->period = DIV64_U64_ROUND_UP(period * (clk_div + 1) * NSEC_PER_SEC, rate);
208+
high_width = FIELD_GET(PWM_HIGH_WIDTH_MASK, con1);
209+
state->duty_cycle = DIV64_U64_ROUND_UP(high_width * (clk_div + 1) * NSEC_PER_SEC,
210+
rate);
211+
state->polarity = PWM_POLARITY_NORMAL;
212+
clk_disable_unprepare(mdp->clk_mm);
213+
clk_disable_unprepare(mdp->clk_main);
214+
}
215+
174216
static const struct pwm_ops mtk_disp_pwm_ops = {
175217
.apply = mtk_disp_pwm_apply,
218+
.get_state = mtk_disp_pwm_get_state,
176219
.owner = THIS_MODULE,
177220
};
178221

0 commit comments

Comments
 (0)