On Thu, Sep 09, 2010 at 16:10:49, Sugumar Natarajan wrote: > This patch adds generic PWM support where it maintains the list of PWM > control devices that can be added or removed. > > The interface provides a list of functions that can be accessed by the PWM > control driver module and the generic PWM driver. > > The PWM control driver module such as eCAP uses the interface to register and > add itself to the list as a PWM control device. > The generic PWM driver uses the interface to search for a PWM control device > and if present, uses the device for PWM control. > > Signed-off-by: Sugumar Natarajan <[email protected]> > ---
Kevin, I have implemented the eHRPWM driver and the basic pwm infrastructure has undergone some changes. So please don't merge these changes. I will send the updated patch soon. > Changes since v2: > a) pwm_config_device callback is made more flexible. > b) pwm_request function code has been made more cleaner. > c) Sanity-check/warn has been included. > > arch/arm/mach-davinci/Makefile | 3 + > arch/arm/mach-davinci/davinci_pwm.c | 130 > ++++++++++++++++++++++ > arch/arm/mach-davinci/include/mach/davinci_pwm.h | 32 ++++++ > 3 files changed, 165 insertions(+), 0 deletions(-) create mode 100644 > arch/arm/mach-davinci/davinci_pwm.c > create mode 100644 arch/arm/mach-davinci/include/mach/davinci_pwm.h > > diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile > index a7a70d1..90ca821 100644 > --- a/arch/arm/mach-davinci/Makefile > +++ b/arch/arm/mach-davinci/Makefile > @@ -39,3 +39,6 @@ obj-$(CONFIG_MACH_MITYOMAPL138) += > board-mityomapl138.o > obj-$(CONFIG_CPU_FREQ) += cpufreq.o > obj-$(CONFIG_CPU_IDLE) += cpuidle.o > obj-$(CONFIG_SUSPEND) += pm.o sleep.o > + > +# Generic PWM control support > +obj-$(CONFIG_HAVE_PWM) += davinci_pwm.o > diff --git a/arch/arm/mach-davinci/davinci_pwm.c > b/arch/arm/mach-davinci/davinci_pwm.c > new file mode 100644 > index 0000000..c2b8b9a > --- /dev/null > +++ b/arch/arm/mach-davinci/davinci_pwm.c > @@ -0,0 +1,130 @@ > +/* > + * Copyright (C) 2010 Texas Instruments Incorporated - > +http://www.ti.com/ > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License as > + * published by the Free Software Foundation version 2. > + * > + * This program is distributed .as is. WITHOUT ANY WARRANTY of any > + * kind, whether express or implied; without even the implied warranty > + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + */ > + > +#include <linux/module.h> > +#include <linux/kernel.h> > +#include <linux/platform_device.h> > +#include <linux/err.h> > +#include <linux/clk.h> > +#include <linux/io.h> > +#include <linux/pwm.h> > +#include <mach/davinci_pwm.h> > + > +int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns) { > + unsigned int clock_freq; > + unsigned int period_cycles; > + unsigned int duty_cycle; > + int ret = 0; > + > + if (WARN_ON(!pwm)) > + return -EINVAL; > + > + if (pwm->pwm_config_device) { > + if (!period_ns || duty_ns > period_ns) > + return -EINVAL; > + > + clock_freq = clk_get_rate(pwm->clk) / USEC_PER_SEC; > + period_cycles = (clock_freq * period_ns) / MSEC_PER_SEC; > + duty_cycle = (clock_freq * duty_ns) / MSEC_PER_SEC; > + ret = pwm->pwm_config_device(pwm, period_cycles, duty_cycle); > + } > + > + return ret; > +} > +EXPORT_SYMBOL(pwm_config); > + > +int pwm_enable(struct pwm_device *pwm) > +{ > + if (WARN_ON(!pwm)) > + return -EINVAL; > + > + return clk_enable(pwm->clk); > +} > +EXPORT_SYMBOL(pwm_enable); > + > +void pwm_disable(struct pwm_device *pwm) { > + if (WARN_ON(!pwm)) > + return; > + > + clk_disable(pwm->clk); > +} > +EXPORT_SYMBOL(pwm_disable); > + > +static DEFINE_MUTEX(pwm_lock); > +static LIST_HEAD(pwm_list); > + > +struct pwm_device *pwm_request(int pwm_id, const char *label) { > + struct pwm_device *pwm, *tmp_pwm = ERR_PTR(-ENOENT); > + > + mutex_lock(&pwm_lock); > + > + list_for_each_entry(pwm, &pwm_list, node) { > + if (pwm->pwm_id == pwm_id) { > + if (pwm->use_count == 0) { > + pwm->use_count++; > + pwm->label = label; > + } else { > + pwm = ERR_PTR(-EBUSY); > + } > + tmp_pwm = pwm; > + break; > + } > + } > + > + mutex_unlock(&pwm_lock); > + return tmp_pwm; > +} > +EXPORT_SYMBOL(pwm_request); > + > +void pwm_free(struct pwm_device *pwm) > +{ > + if (WARN_ON(!pwm)) > + return; > + > + mutex_lock(&pwm_lock); > + > + if (pwm->use_count) { > + pwm->use_count--; > + pwm->label = NULL; > + } else { > + dev_warn(&pwm->pdev->dev, "PWM device already freed\n"); > + } > + > + mutex_unlock(&pwm_lock); > +} > +EXPORT_SYMBOL(pwm_free); > + > +void pwm_add(struct pwm_device *pwm) > +{ > + if (WARN_ON(!pwm)) > + return; > + > + mutex_lock(&pwm_lock); > + list_add_tail(&pwm->node, &pwm_list); > + mutex_unlock(&pwm_lock); > +} > +EXPORT_SYMBOL(pwm_add); > + > +void pwm_remove(struct pwm_device *pwm) { > + if (WARN_ON(!pwm)) > + return; > + > + mutex_lock(&pwm_lock); > + list_del(&pwm->node); > + mutex_unlock(&pwm_lock); > +} > +EXPORT_SYMBOL(pwm_remove); > diff --git a/arch/arm/mach-davinci/include/mach/davinci_pwm.h > b/arch/arm/mach-davinci/include/mach/davinci_pwm.h > new file mode 100644 > index 0000000..3b7a3c8 > --- /dev/null > +++ b/arch/arm/mach-davinci/include/mach/davinci_pwm.h > @@ -0,0 +1,32 @@ > +/* > + * Copyright (C) 2010 Texas Instruments Incorporated - > +http://www.ti.com/ > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License as > + * published by the Free Software Foundation version 2. > + * > + * This program is distributed .as is. WITHOUT ANY WARRANTY of any > + * kind, whether express or implied; without even the implied warranty > + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + */ > + > +#ifndef __DAVINCI_PWM_H > +#define __DAVINCI_PWM_H > + > +struct pwm_device { > + struct list_head node; > + struct platform_device *pdev; > + int (*pwm_config_device)(struct pwm_device *pwm, > + unsigned int period, unsigned int dutycycle); > + const char *label; > + struct clk *clk; > + unsigned int use_count; > + unsigned int pwm_id; > +}; > + > +void pwm_add(struct pwm_device *pwm); > +void pwm_remove(struct pwm_device *pwm); > + > +#endif > -- > 1.5.6 > _______________________________________________ Davinci-linux-open-source mailing list [email protected] http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
