summaryrefslogtreecommitdiffstats
path: root/drivers/pwm/pwm-sun4i.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pwm/pwm-sun4i.c')
-rw-r--r--drivers/pwm/pwm-sun4i.c27
1 files changed, 24 insertions, 3 deletions
diff --git a/drivers/pwm/pwm-sun4i.c b/drivers/pwm/pwm-sun4i.c
index cd9dde563018..67af9f62361f 100644
--- a/drivers/pwm/pwm-sun4i.c
+++ b/drivers/pwm/pwm-sun4i.c
@@ -68,6 +68,7 @@ static const u32 prescaler_table[] = {
68struct sun4i_pwm_data { 68struct sun4i_pwm_data {
69 bool has_prescaler_bypass; 69 bool has_prescaler_bypass;
70 bool has_rdy; 70 bool has_rdy;
71 unsigned int npwm;
71}; 72};
72 73
73struct sun4i_pwm_chip { 74struct sun4i_pwm_chip {
@@ -114,7 +115,7 @@ static int sun4i_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
114 * is not an integer so round it half up instead of 115 * is not an integer so round it half up instead of
115 * truncating to get less surprising values. 116 * truncating to get less surprising values.
116 */ 117 */
117 div = clk_rate * period_ns + NSEC_PER_SEC/2; 118 div = clk_rate * period_ns + NSEC_PER_SEC / 2;
118 do_div(div, NSEC_PER_SEC); 119 do_div(div, NSEC_PER_SEC);
119 if (div - 1 > PWM_PRD_MASK) 120 if (div - 1 > PWM_PRD_MASK)
120 prescaler = 0; 121 prescaler = 0;
@@ -262,11 +263,25 @@ static const struct pwm_ops sun4i_pwm_ops = {
262static const struct sun4i_pwm_data sun4i_pwm_data_a10 = { 263static const struct sun4i_pwm_data sun4i_pwm_data_a10 = {
263 .has_prescaler_bypass = false, 264 .has_prescaler_bypass = false,
264 .has_rdy = false, 265 .has_rdy = false,
266 .npwm = 2,
267};
268
269static const struct sun4i_pwm_data sun4i_pwm_data_a10s = {
270 .has_prescaler_bypass = true,
271 .has_rdy = true,
272 .npwm = 2,
273};
274
275static const struct sun4i_pwm_data sun4i_pwm_data_a13 = {
276 .has_prescaler_bypass = true,
277 .has_rdy = true,
278 .npwm = 1,
265}; 279};
266 280
267static const struct sun4i_pwm_data sun4i_pwm_data_a20 = { 281static const struct sun4i_pwm_data sun4i_pwm_data_a20 = {
268 .has_prescaler_bypass = true, 282 .has_prescaler_bypass = true,
269 .has_rdy = true, 283 .has_rdy = true,
284 .npwm = 2,
270}; 285};
271 286
272static const struct of_device_id sun4i_pwm_dt_ids[] = { 287static const struct of_device_id sun4i_pwm_dt_ids[] = {
@@ -274,6 +289,12 @@ static const struct of_device_id sun4i_pwm_dt_ids[] = {
274 .compatible = "allwinner,sun4i-a10-pwm", 289 .compatible = "allwinner,sun4i-a10-pwm",
275 .data = &sun4i_pwm_data_a10, 290 .data = &sun4i_pwm_data_a10,
276 }, { 291 }, {
292 .compatible = "allwinner,sun5i-a10s-pwm",
293 .data = &sun4i_pwm_data_a10s,
294 }, {
295 .compatible = "allwinner,sun5i-a13-pwm",
296 .data = &sun4i_pwm_data_a13,
297 }, {
277 .compatible = "allwinner,sun7i-a20-pwm", 298 .compatible = "allwinner,sun7i-a20-pwm",
278 .data = &sun4i_pwm_data_a20, 299 .data = &sun4i_pwm_data_a20,
279 }, { 300 }, {
@@ -305,14 +326,14 @@ static int sun4i_pwm_probe(struct platform_device *pdev)
305 if (IS_ERR(pwm->clk)) 326 if (IS_ERR(pwm->clk))
306 return PTR_ERR(pwm->clk); 327 return PTR_ERR(pwm->clk);
307 328
329 pwm->data = match->data;
308 pwm->chip.dev = &pdev->dev; 330 pwm->chip.dev = &pdev->dev;
309 pwm->chip.ops = &sun4i_pwm_ops; 331 pwm->chip.ops = &sun4i_pwm_ops;
310 pwm->chip.base = -1; 332 pwm->chip.base = -1;
311 pwm->chip.npwm = 2; 333 pwm->chip.npwm = pwm->data->npwm;
312 pwm->chip.can_sleep = true; 334 pwm->chip.can_sleep = true;
313 pwm->chip.of_xlate = of_pwm_xlate_with_flags; 335 pwm->chip.of_xlate = of_pwm_xlate_with_flags;
314 pwm->chip.of_pwm_n_cells = 3; 336 pwm->chip.of_pwm_n_cells = 3;
315 pwm->data = match->data;
316 337
317 spin_lock_init(&pwm->ctrl_lock); 338 spin_lock_init(&pwm->ctrl_lock);
318 339