|
5 | 5 | * Author: YH Huang <[email protected]>
|
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>
|
@@ -171,8 +172,50 @@ static int mtk_disp_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
|
171 | 172 | return 0;
|
172 | 173 | }
|
173 | 174 |
|
| 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 | + |
174 | 216 | static const struct pwm_ops mtk_disp_pwm_ops = {
|
175 | 217 | .apply = mtk_disp_pwm_apply,
|
| 218 | + .get_state = mtk_disp_pwm_get_state, |
176 | 219 | .owner = THIS_MODULE,
|
177 | 220 | };
|
178 | 221 |
|
|
0 commit comments