Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

pwm: mtk-disp: Implement atomic API .get_state()

Switch the driver to support the .get_state() method.

Signed-off-by: Jitao Shi <jitao.shi@mediatek.com>
[thierry.reding@gmail.com: add missing linux/bitfield.h include]
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>

authored by

Jitao Shi and committed by
Thierry Reding
3f2b1673 331e049d

+43
+43
drivers/pwm/pwm-mtk-disp.c
··· 5 5 * Author: YH Huang <yh.huang@mediatek.com> 6 6 */ 7 7 8 + #include <linux/bitfield.h> 8 9 #include <linux/clk.h> 9 10 #include <linux/err.h> 10 11 #include <linux/io.h> ··· 172 171 return 0; 173 172 } 174 173 174 + static void mtk_disp_pwm_get_state(struct pwm_chip *chip, 175 + struct pwm_device *pwm, 176 + struct pwm_state *state) 177 + { 178 + struct mtk_disp_pwm *mdp = to_mtk_disp_pwm(chip); 179 + u64 rate, period, high_width; 180 + u32 clk_div, con0, con1; 181 + int err; 182 + 183 + err = clk_prepare_enable(mdp->clk_main); 184 + if (err < 0) { 185 + dev_err(chip->dev, "Can't enable mdp->clk_main: %pe\n", ERR_PTR(err)); 186 + return; 187 + } 188 + 189 + err = clk_prepare_enable(mdp->clk_mm); 190 + if (err < 0) { 191 + dev_err(chip->dev, "Can't enable mdp->clk_mm: %pe\n", ERR_PTR(err)); 192 + clk_disable_unprepare(mdp->clk_main); 193 + return; 194 + } 195 + 196 + rate = clk_get_rate(mdp->clk_main); 197 + con0 = readl(mdp->base + mdp->data->con0); 198 + con1 = readl(mdp->base + mdp->data->con1); 199 + state->enabled = !!(con0 & BIT(0)); 200 + clk_div = FIELD_GET(PWM_CLKDIV_MASK, con0); 201 + period = FIELD_GET(PWM_PERIOD_MASK, con1); 202 + /* 203 + * period has 12 bits, clk_div 11 and NSEC_PER_SEC has 30, 204 + * so period * (clk_div + 1) * NSEC_PER_SEC doesn't overflow. 205 + */ 206 + state->period = DIV64_U64_ROUND_UP(period * (clk_div + 1) * NSEC_PER_SEC, rate); 207 + high_width = FIELD_GET(PWM_HIGH_WIDTH_MASK, con1); 208 + state->duty_cycle = DIV64_U64_ROUND_UP(high_width * (clk_div + 1) * NSEC_PER_SEC, 209 + rate); 210 + state->polarity = PWM_POLARITY_NORMAL; 211 + clk_disable_unprepare(mdp->clk_mm); 212 + clk_disable_unprepare(mdp->clk_main); 213 + } 214 + 175 215 static const struct pwm_ops mtk_disp_pwm_ops = { 176 216 .apply = mtk_disp_pwm_apply, 217 + .get_state = mtk_disp_pwm_get_state, 177 218 .owner = THIS_MODULE, 178 219 }; 179 220