-----Original Message----- From: Sugumar Natarajan [mailto:sugu...@ti.com] Sent: Thursday, September 09, 2010 4:11 PM To: davinci-linux-open-source@linux.davincidsp.com Cc: Sugumar Natarajan Subject: [PATCH v4 1/2] davinci: Add generic PWM support for PWM control
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 <sugu...@ti.com> --- 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. Regards, N.Sugumar. 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 Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source