aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pwm/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pwm/core.c')
-rw-r--r--drivers/pwm/core.c82
1 files changed, 81 insertions, 1 deletions
diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index c6e05078d3ad..f5acdaa52707 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -371,7 +371,7 @@ EXPORT_SYMBOL_GPL(pwm_free);
371 */ 371 */
372int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns) 372int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
373{ 373{
374 if (!pwm || period_ns == 0 || duty_ns > period_ns) 374 if (!pwm || duty_ns < 0 || period_ns <= 0 || duty_ns > period_ns)
375 return -EINVAL; 375 return -EINVAL;
376 376
377 return pwm->chip->ops->config(pwm->chip, pwm, duty_ns, period_ns); 377 return pwm->chip->ops->config(pwm->chip, pwm, duty_ns, period_ns);
@@ -379,6 +379,28 @@ int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
379EXPORT_SYMBOL_GPL(pwm_config); 379EXPORT_SYMBOL_GPL(pwm_config);
380 380
381/** 381/**
382 * pwm_set_polarity() - configure the polarity of a PWM signal
383 * @pwm: PWM device
384 * @polarity: new polarity of the PWM signal
385 *
386 * Note that the polarity cannot be configured while the PWM device is enabled
387 */
388int pwm_set_polarity(struct pwm_device *pwm, enum pwm_polarity polarity)
389{
390 if (!pwm || !pwm->chip->ops)
391 return -EINVAL;
392
393 if (!pwm->chip->ops->set_polarity)
394 return -ENOSYS;
395
396 if (test_bit(PWMF_ENABLED, &pwm->flags))
397 return -EBUSY;
398
399 return pwm->chip->ops->set_polarity(pwm->chip, pwm, polarity);
400}
401EXPORT_SYMBOL_GPL(pwm_set_polarity);
402
403/**
382 * pwm_enable() - start a PWM output toggling 404 * pwm_enable() - start a PWM output toggling
383 * @pwm: PWM device 405 * @pwm: PWM device
384 */ 406 */
@@ -624,6 +646,64 @@ out:
624} 646}
625EXPORT_SYMBOL_GPL(pwm_put); 647EXPORT_SYMBOL_GPL(pwm_put);
626 648
649static void devm_pwm_release(struct device *dev, void *res)
650{
651 pwm_put(*(struct pwm_device **)res);
652}
653
654/**
655 * devm_pwm_get() - resource managed pwm_get()
656 * @dev: device for PWM consumer
657 * @con_id: consumer name
658 *
659 * This function performs like pwm_get() but the acquired PWM device will
660 * automatically be released on driver detach.
661 */
662struct pwm_device *devm_pwm_get(struct device *dev, const char *con_id)
663{
664 struct pwm_device **ptr, *pwm;
665
666 ptr = devres_alloc(devm_pwm_release, sizeof(**ptr), GFP_KERNEL);
667 if (!ptr)
668 return ERR_PTR(-ENOMEM);
669
670 pwm = pwm_get(dev, con_id);
671 if (!IS_ERR(pwm)) {
672 *ptr = pwm;
673 devres_add(dev, ptr);
674 } else {
675 devres_free(ptr);
676 }
677
678 return pwm;
679}
680EXPORT_SYMBOL_GPL(devm_pwm_get);
681
682static int devm_pwm_match(struct device *dev, void *res, void *data)
683{
684 struct pwm_device **p = res;
685
686 if (WARN_ON(!p || !*p))
687 return 0;
688
689 return *p == data;
690}
691
692/**
693 * devm_pwm_put() - resource managed pwm_put()
694 * @dev: device for PWM consumer
695 * @pwm: PWM device
696 *
697 * Release a PWM previously allocated using devm_pwm_get(). Calling this
698 * function is usually not needed because devm-allocated resources are
699 * automatically released on driver detach.
700 */
701void devm_pwm_put(struct device *dev, struct pwm_device *pwm)
702{
703 WARN_ON(devres_release(dev, devm_pwm_release, devm_pwm_match, pwm));
704}
705EXPORT_SYMBOL_GPL(devm_pwm_put);
706
627#ifdef CONFIG_DEBUG_FS 707#ifdef CONFIG_DEBUG_FS
628static void pwm_dbg_show(struct pwm_chip *chip, struct seq_file *s) 708static void pwm_dbg_show(struct pwm_chip *chip, struct seq_file *s)
629{ 709{