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

Reply via email to