summaryrefslogtreecommitdiffstats
path: root/drivers/pwm/pwm-rockchip.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pwm/pwm-rockchip.c')
-rw-r--r--drivers/pwm/pwm-rockchip.c48
1 files changed, 24 insertions, 24 deletions
diff --git a/drivers/pwm/pwm-rockchip.c b/drivers/pwm/pwm-rockchip.c
index 4f7ebe132ee9..911329a15da0 100644
--- a/drivers/pwm/pwm-rockchip.c
+++ b/drivers/pwm/pwm-rockchip.c
@@ -27,6 +27,7 @@
27#define PWM_DUTY_NEGATIVE (0 << 3) 27#define PWM_DUTY_NEGATIVE (0 << 3)
28#define PWM_INACTIVE_NEGATIVE (0 << 4) 28#define PWM_INACTIVE_NEGATIVE (0 << 4)
29#define PWM_INACTIVE_POSITIVE (1 << 4) 29#define PWM_INACTIVE_POSITIVE (1 << 4)
30#define PWM_POLARITY_MASK (PWM_DUTY_POSITIVE | PWM_INACTIVE_POSITIVE)
30#define PWM_OUTPUT_LEFT (0 << 5) 31#define PWM_OUTPUT_LEFT (0 << 5)
31#define PWM_LP_DISABLE (0 << 8) 32#define PWM_LP_DISABLE (0 << 8)
32 33
@@ -123,11 +124,12 @@ static void rockchip_pwm_get_state(struct pwm_chip *chip,
123} 124}
124 125
125static void rockchip_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, 126static void rockchip_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
126 int duty_ns, int period_ns) 127 struct pwm_state *state)
127{ 128{
128 struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip); 129 struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
129 unsigned long period, duty; 130 unsigned long period, duty;
130 u64 clk_rate, div; 131 u64 clk_rate, div;
132 u32 ctrl;
131 133
132 clk_rate = clk_get_rate(pc->clk); 134 clk_rate = clk_get_rate(pc->clk);
133 135
@@ -136,22 +138,31 @@ static void rockchip_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
136 * bits, every possible input period can be obtained using the 138 * bits, every possible input period can be obtained using the
137 * default prescaler value for all practical clock rate values. 139 * default prescaler value for all practical clock rate values.
138 */ 140 */
139 div = clk_rate * period_ns; 141 div = clk_rate * state->period;
140 period = DIV_ROUND_CLOSEST_ULL(div, 142 period = DIV_ROUND_CLOSEST_ULL(div,
141 pc->data->prescaler * NSEC_PER_SEC); 143 pc->data->prescaler * NSEC_PER_SEC);
142 144
143 div = clk_rate * duty_ns; 145 div = clk_rate * state->duty_cycle;
144 duty = DIV_ROUND_CLOSEST_ULL(div, pc->data->prescaler * NSEC_PER_SEC); 146 duty = DIV_ROUND_CLOSEST_ULL(div, pc->data->prescaler * NSEC_PER_SEC);
145 147
146 writel(period, pc->base + pc->data->regs.period); 148 writel(period, pc->base + pc->data->regs.period);
147 writel(duty, pc->base + pc->data->regs.duty); 149 writel(duty, pc->base + pc->data->regs.duty);
150
151 ctrl = readl_relaxed(pc->base + pc->data->regs.ctrl);
152 if (pc->data->supports_polarity) {
153 ctrl &= ~PWM_POLARITY_MASK;
154 if (state->polarity == PWM_POLARITY_INVERSED)
155 ctrl |= PWM_DUTY_NEGATIVE | PWM_INACTIVE_POSITIVE;
156 else
157 ctrl |= PWM_DUTY_POSITIVE | PWM_INACTIVE_NEGATIVE;
158 }
159 writel(ctrl, pc->base + pc->data->regs.ctrl);
148} 160}
149 161
150static int rockchip_pwm_enable(struct pwm_chip *chip, 162static int rockchip_pwm_enable(struct pwm_chip *chip,
151 struct pwm_device *pwm, 163 struct pwm_device *pwm,
152 bool enable, 164 bool enable,
153 enum pwm_polarity polarity, 165 u32 enable_conf)
154 u32 enable_conf)
155{ 166{
156 struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip); 167 struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
157 int ret; 168 int ret;
@@ -163,15 +174,6 @@ static int rockchip_pwm_enable(struct pwm_chip *chip,
163 return ret; 174 return ret;
164 } 175 }
165 176
166 if (pc->data->supports_polarity) {
167 if (polarity == PWM_POLARITY_INVERSED)
168 enable_conf |= PWM_DUTY_NEGATIVE |
169 PWM_INACTIVE_POSITIVE;
170 else
171 enable_conf |= PWM_DUTY_POSITIVE |
172 PWM_INACTIVE_NEGATIVE;
173 }
174
175 val = readl_relaxed(pc->base + pc->data->regs.ctrl); 177 val = readl_relaxed(pc->base + pc->data->regs.ctrl);
176 178
177 if (enable) 179 if (enable)
@@ -199,18 +201,17 @@ static int rockchip_pwm_apply_v1(struct pwm_chip *chip, struct pwm_device *pwm,
199 enabled = curstate.enabled; 201 enabled = curstate.enabled;
200 202
201 if (state->polarity != curstate.polarity && enabled) { 203 if (state->polarity != curstate.polarity && enabled) {
202 ret = rockchip_pwm_enable(chip, pwm, false, state->polarity, 204 ret = rockchip_pwm_enable(chip, pwm, false, enable_conf);
203 enable_conf);
204 if (ret) 205 if (ret)
205 return ret; 206 return ret;
206 enabled = false; 207 enabled = false;
207 } 208 }
208 209
209 rockchip_pwm_config(chip, pwm, state->duty_cycle, state->period); 210 rockchip_pwm_config(chip, pwm, state);
210 211
211 if (state->enabled != enabled) 212 if (state->enabled != enabled)
212 ret = rockchip_pwm_enable(chip, pwm, state->enabled, 213 ret = rockchip_pwm_enable(chip, pwm, state->enabled,
213 state->polarity, enable_conf); 214 enable_conf);
214 215
215 return ret; 216 return ret;
216} 217}
@@ -228,18 +229,17 @@ static int rockchip_pwm_apply_v2(struct pwm_chip *chip, struct pwm_device *pwm,
228 enabled = curstate.enabled; 229 enabled = curstate.enabled;
229 230
230 if (state->polarity != curstate.polarity && enabled) { 231 if (state->polarity != curstate.polarity && enabled) {
231 ret = rockchip_pwm_enable(chip, pwm, false, state->polarity, 232 ret = rockchip_pwm_enable(chip, pwm, false, enable_conf);
232 enable_conf);
233 if (ret) 233 if (ret)
234 return ret; 234 return ret;
235 enabled = false; 235 enabled = false;
236 } 236 }
237 237
238 rockchip_pwm_config(chip, pwm, state->duty_cycle, state->period); 238 rockchip_pwm_config(chip, pwm, state);
239 239
240 if (state->enabled != enabled) 240 if (state->enabled != enabled)
241 ret = rockchip_pwm_enable(chip, pwm, state->enabled, 241 ret = rockchip_pwm_enable(chip, pwm, state->enabled,
242 state->polarity, enable_conf); 242 enable_conf);
243 243
244 return ret; 244 return ret;
245} 245}