Lines Matching +full:pwm +full:- +full:channels +full:- +full:mask
2 * EHRPWM PWM driver
4 * Copyright (C) 2012 Texas Instruments, Inc. - http://www.ti.com/
23 #include <linux/pwm.h>
107 #define NUM_PWM_CHANNEL 2 /* EHRPWM channels */
146 static void ehrpwm_modify(void __iomem *base, unsigned int offset, u16 mask, in ehrpwm_modify() argument
152 val &= ~mask; in ehrpwm_modify()
153 val |= value & mask; in ehrpwm_modify()
158 * set_prescale_div - Set up the prescaler divider function
200 * Configure PWM output to HIGH/LOW level on counter in configure_polarity()
209 if (pc->polarity[chan] == PWM_POLARITY_INVERSED) in configure_polarity()
217 if (pc->polarity[chan] == PWM_POLARITY_INVERSED) in configure_polarity()
224 ehrpwm_modify(pc->mmio_base, aqctl_reg, aqctl_mask, aqctl_val); in configure_polarity()
231 static int ehrpwm_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, in ehrpwm_pwm_config() argument
241 return -ERANGE; in ehrpwm_pwm_config()
243 c = pc->clk_rate; in ehrpwm_pwm_config()
252 c = pc->clk_rate; in ehrpwm_pwm_config()
259 * Period values should be same for multiple PWM channels as IP uses in ehrpwm_pwm_config()
260 * same period register for multiple channels. in ehrpwm_pwm_config()
263 if (pc->period_cycles[i] && in ehrpwm_pwm_config()
264 (pc->period_cycles[i] != period_cycles)) { in ehrpwm_pwm_config()
267 * channels being configured. in ehrpwm_pwm_config()
269 if (i == pwm->hwpwm) in ehrpwm_pwm_config()
272 dev_err(chip->dev, in ehrpwm_pwm_config()
275 return -EINVAL; in ehrpwm_pwm_config()
279 pc->period_cycles[pwm->hwpwm] = period_cycles; in ehrpwm_pwm_config()
281 /* Configure clock prescaler to support Low frequency PWM wave */ in ehrpwm_pwm_config()
284 dev_err(chip->dev, "Unsupported values\n"); in ehrpwm_pwm_config()
285 return -EINVAL; in ehrpwm_pwm_config()
288 pm_runtime_get_sync(chip->dev); in ehrpwm_pwm_config()
291 ehrpwm_modify(pc->mmio_base, TBCTL, TBCTL_CLKDIV_MASK, tb_divval); in ehrpwm_pwm_config()
298 ehrpwm_modify(pc->mmio_base, TBCTL, TBCTL_PRDLD_MASK, TBCTL_PRDLD_SHDW); in ehrpwm_pwm_config()
300 ehrpwm_write(pc->mmio_base, TBPRD, period_cycles); in ehrpwm_pwm_config()
302 /* Configure ehrpwm counter for up-count mode */ in ehrpwm_pwm_config()
303 ehrpwm_modify(pc->mmio_base, TBCTL, TBCTL_CTRMODE_MASK, in ehrpwm_pwm_config()
306 if (pwm->hwpwm == 1) in ehrpwm_pwm_config()
313 ehrpwm_write(pc->mmio_base, cmp_reg, duty_cycles); in ehrpwm_pwm_config()
315 pm_runtime_put_sync(chip->dev); in ehrpwm_pwm_config()
321 struct pwm_device *pwm, in ehrpwm_pwm_set_polarity() argument
327 pc->polarity[pwm->hwpwm] = polarity; in ehrpwm_pwm_set_polarity()
332 static int ehrpwm_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) in ehrpwm_pwm_enable() argument
338 /* Leave clock enabled on enabling PWM */ in ehrpwm_pwm_enable()
339 pm_runtime_get_sync(chip->dev); in ehrpwm_pwm_enable()
341 /* Disabling Action Qualifier on PWM output */ in ehrpwm_pwm_enable()
342 if (pwm->hwpwm) { in ehrpwm_pwm_enable()
351 ehrpwm_modify(pc->mmio_base, AQSFRC, AQSFRC_RLDCSF_MASK, in ehrpwm_pwm_enable()
354 ehrpwm_modify(pc->mmio_base, AQCSFRC, aqcsfrc_mask, aqcsfrc_val); in ehrpwm_pwm_enable()
356 /* Channels polarity can be configured from action qualifier module */ in ehrpwm_pwm_enable()
357 configure_polarity(pc, pwm->hwpwm); in ehrpwm_pwm_enable()
360 ret = clk_enable(pc->tbclk); in ehrpwm_pwm_enable()
362 dev_err(chip->dev, "Failed to enable TBCLK for %s: %d\n", in ehrpwm_pwm_enable()
363 dev_name(pc->chip.dev), ret); in ehrpwm_pwm_enable()
370 static void ehrpwm_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) in ehrpwm_pwm_disable() argument
375 /* Action Qualifier puts PWM output low forcefully */ in ehrpwm_pwm_disable()
376 if (pwm->hwpwm) { in ehrpwm_pwm_disable()
385 ehrpwm_modify(pc->mmio_base, AQSFRC, AQSFRC_RLDCSF_MASK, in ehrpwm_pwm_disable()
387 ehrpwm_modify(pc->mmio_base, AQCSFRC, aqcsfrc_mask, aqcsfrc_val); in ehrpwm_pwm_disable()
390 * Action Qualifier control on PWM output from next TBCLK in ehrpwm_pwm_disable()
392 ehrpwm_modify(pc->mmio_base, AQSFRC, AQSFRC_RLDCSF_MASK, in ehrpwm_pwm_disable()
395 ehrpwm_modify(pc->mmio_base, AQCSFRC, aqcsfrc_mask, aqcsfrc_val); in ehrpwm_pwm_disable()
397 /* Disabling TBCLK on PWM disable */ in ehrpwm_pwm_disable()
398 clk_disable(pc->tbclk); in ehrpwm_pwm_disable()
400 /* Disable clock on PWM disable */ in ehrpwm_pwm_disable()
401 pm_runtime_put_sync(chip->dev); in ehrpwm_pwm_disable()
404 static void ehrpwm_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) in ehrpwm_pwm_free() argument
408 if (pwm_is_enabled(pwm)) { in ehrpwm_pwm_free()
409 dev_warn(chip->dev, "Removing PWM device without disabling\n"); in ehrpwm_pwm_free()
410 pm_runtime_put_sync(chip->dev); in ehrpwm_pwm_free()
414 pc->period_cycles[pwm->hwpwm] = 0; in ehrpwm_pwm_free()
427 { .compatible = "ti,am3352-ehrpwm" },
428 { .compatible = "ti,am33xx-ehrpwm" },
435 struct device_node *np = pdev->dev.of_node; in ehrpwm_pwm_probe()
441 pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL); in ehrpwm_pwm_probe()
443 return -ENOMEM; in ehrpwm_pwm_probe()
445 clk = devm_clk_get(&pdev->dev, "fck"); in ehrpwm_pwm_probe()
447 if (of_device_is_compatible(np, "ti,am33xx-ecap")) { in ehrpwm_pwm_probe()
448 dev_warn(&pdev->dev, "Binding is obsolete.\n"); in ehrpwm_pwm_probe()
449 clk = devm_clk_get(pdev->dev.parent, "fck"); in ehrpwm_pwm_probe()
454 dev_err(&pdev->dev, "failed to get clock\n"); in ehrpwm_pwm_probe()
458 pc->clk_rate = clk_get_rate(clk); in ehrpwm_pwm_probe()
459 if (!pc->clk_rate) { in ehrpwm_pwm_probe()
460 dev_err(&pdev->dev, "failed to get clock rate\n"); in ehrpwm_pwm_probe()
461 return -EINVAL; in ehrpwm_pwm_probe()
464 pc->chip.dev = &pdev->dev; in ehrpwm_pwm_probe()
465 pc->chip.ops = &ehrpwm_pwm_ops; in ehrpwm_pwm_probe()
466 pc->chip.of_xlate = of_pwm_xlate_with_flags; in ehrpwm_pwm_probe()
467 pc->chip.of_pwm_n_cells = 3; in ehrpwm_pwm_probe()
468 pc->chip.base = -1; in ehrpwm_pwm_probe()
469 pc->chip.npwm = NUM_PWM_CHANNEL; in ehrpwm_pwm_probe()
472 pc->mmio_base = devm_ioremap_resource(&pdev->dev, r); in ehrpwm_pwm_probe()
473 if (IS_ERR(pc->mmio_base)) in ehrpwm_pwm_probe()
474 return PTR_ERR(pc->mmio_base); in ehrpwm_pwm_probe()
477 pc->tbclk = devm_clk_get(&pdev->dev, "tbclk"); in ehrpwm_pwm_probe()
478 if (IS_ERR(pc->tbclk)) { in ehrpwm_pwm_probe()
479 dev_err(&pdev->dev, "Failed to get tbclk\n"); in ehrpwm_pwm_probe()
480 return PTR_ERR(pc->tbclk); in ehrpwm_pwm_probe()
483 ret = clk_prepare(pc->tbclk); in ehrpwm_pwm_probe()
485 dev_err(&pdev->dev, "clk_prepare() failed: %d\n", ret); in ehrpwm_pwm_probe()
489 ret = pwmchip_add(&pc->chip); in ehrpwm_pwm_probe()
491 dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret); in ehrpwm_pwm_probe()
496 pm_runtime_enable(&pdev->dev); in ehrpwm_pwm_probe()
501 clk_unprepare(pc->tbclk); in ehrpwm_pwm_probe()
510 clk_unprepare(pc->tbclk); in ehrpwm_pwm_remove()
512 pm_runtime_disable(&pdev->dev); in ehrpwm_pwm_remove()
514 return pwmchip_remove(&pc->chip); in ehrpwm_pwm_remove()
520 pm_runtime_get_sync(pc->chip.dev); in ehrpwm_pwm_save_context()
522 pc->ctx.tbctl = ehrpwm_read(pc->mmio_base, TBCTL); in ehrpwm_pwm_save_context()
523 pc->ctx.tbprd = ehrpwm_read(pc->mmio_base, TBPRD); in ehrpwm_pwm_save_context()
524 pc->ctx.cmpa = ehrpwm_read(pc->mmio_base, CMPA); in ehrpwm_pwm_save_context()
525 pc->ctx.cmpb = ehrpwm_read(pc->mmio_base, CMPB); in ehrpwm_pwm_save_context()
526 pc->ctx.aqctla = ehrpwm_read(pc->mmio_base, AQCTLA); in ehrpwm_pwm_save_context()
527 pc->ctx.aqctlb = ehrpwm_read(pc->mmio_base, AQCTLB); in ehrpwm_pwm_save_context()
528 pc->ctx.aqsfrc = ehrpwm_read(pc->mmio_base, AQSFRC); in ehrpwm_pwm_save_context()
529 pc->ctx.aqcsfrc = ehrpwm_read(pc->mmio_base, AQCSFRC); in ehrpwm_pwm_save_context()
531 pm_runtime_put_sync(pc->chip.dev); in ehrpwm_pwm_save_context()
536 ehrpwm_write(pc->mmio_base, TBPRD, pc->ctx.tbprd); in ehrpwm_pwm_restore_context()
537 ehrpwm_write(pc->mmio_base, CMPA, pc->ctx.cmpa); in ehrpwm_pwm_restore_context()
538 ehrpwm_write(pc->mmio_base, CMPB, pc->ctx.cmpb); in ehrpwm_pwm_restore_context()
539 ehrpwm_write(pc->mmio_base, AQCTLA, pc->ctx.aqctla); in ehrpwm_pwm_restore_context()
540 ehrpwm_write(pc->mmio_base, AQCTLB, pc->ctx.aqctlb); in ehrpwm_pwm_restore_context()
541 ehrpwm_write(pc->mmio_base, AQSFRC, pc->ctx.aqsfrc); in ehrpwm_pwm_restore_context()
542 ehrpwm_write(pc->mmio_base, AQCSFRC, pc->ctx.aqcsfrc); in ehrpwm_pwm_restore_context()
543 ehrpwm_write(pc->mmio_base, TBCTL, pc->ctx.tbctl); in ehrpwm_pwm_restore_context()
553 for (i = 0; i < pc->chip.npwm; i++) { in ehrpwm_pwm_suspend()
554 struct pwm_device *pwm = &pc->chip.pwms[i]; in ehrpwm_pwm_suspend() local
556 if (!pwm_is_enabled(pwm)) in ehrpwm_pwm_suspend()
559 /* Disable explicitly if PWM is running */ in ehrpwm_pwm_suspend()
571 for (i = 0; i < pc->chip.npwm; i++) { in ehrpwm_pwm_resume()
572 struct pwm_device *pwm = &pc->chip.pwms[i]; in ehrpwm_pwm_resume() local
574 if (!pwm_is_enabled(pwm)) in ehrpwm_pwm_resume()
577 /* Enable explicitly if PWM was running */ in ehrpwm_pwm_resume()
601 MODULE_DESCRIPTION("EHRPWM PWM driver");