From patchwork Tue Sep 14 10:36:15 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sugumar Natarajan X-Patchwork-Id: 179052 Received: from bear.ext.ti.com (bear.ext.ti.com [192.94.94.41]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id o8EB9es5007135 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Tue, 14 Sep 2010 11:10:02 GMT Received: from dlep36.itg.ti.com ([157.170.170.91]) by bear.ext.ti.com (8.13.7/8.13.7) with ESMTP id o8EB9dTh019251 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Tue, 14 Sep 2010 06:09:39 -0500 Received: from linux.omap.com (localhost [127.0.0.1]) by dlep36.itg.ti.com (8.13.8/8.13.8) with ESMTP id o8EB9dgp020746 for ; Tue, 14 Sep 2010 06:09:39 -0500 (CDT) Received: from linux.omap.com (localhost [127.0.0.1]) by linux.omap.com (Postfix) with ESMTP id 3CF5B80637 for ; Tue, 14 Sep 2010 06:09:37 -0500 (CDT) X-Original-To: davinci-linux-open-source@linux.davincidsp.com Delivered-To: davinci-linux-open-source@linux.davincidsp.com Received: from dflp53.itg.ti.com (dflp53.itg.ti.com [128.247.5.6]) by linux.omap.com (Postfix) with ESMTP id 4EE9680626 for ; Tue, 14 Sep 2010 06:09:31 -0500 (CDT) Received: from tidmzi-ftp.india.ext.ti.com (localhost [127.0.0.1]) by dflp53.itg.ti.com (8.13.8/8.13.8) with SMTP id o8EB9TR4004057 for ; Tue, 14 Sep 2010 06:09:30 -0500 (CDT) Received: from symphonyindia.ti.com (symphony-ftp [192.168.247.11]) by tidmzi-ftp.india.ext.ti.com (Postfix) with SMTP id 78FCF3887A for ; Tue, 14 Sep 2010 16:39:25 +0530 (IST) Received: from localhost.localdomain ([192.168.247.76]) by symphonyindia.ti.com (8.13.1/8.12.10) with ESMTP id o8EB2NLq030815; Tue, 14 Sep 2010 16:32:23 +0530 From: Sugumar Natarajan To: davinci-linux-open-source@linux.davincidsp.com Subject: [PATCH v5 1/2] davinci: Add generic PWM support for PWM control Date: Tue, 14 Sep 2010 16:06:15 +0530 Message-Id: <1284460575-24746-1-git-send-email-sugumar@ti.com> X-Mailer: git-send-email 1.5.6 X-BeenThere: davinci-linux-open-source@linux.davincidsp.com X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: davinci-linux-open-source-bounces+patchwork-davinci=patchwork.kernel.org@linux.davincidsp.com Errors-To: davinci-linux-open-source-bounces+patchwork-davinci=patchwork.kernel.org@linux.davincidsp.com X-Greylist: Sender succeeded STARTTLS authentication, not delayed by milter-greylist-4.2.3 (demeter1.kernel.org [140.211.167.41]); Tue, 14 Sep 2010 11:10:02 +0000 (UTC) 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..5a5b332 --- /dev/null +++ b/arch/arm/mach-davinci/davinci_pwm.c @@ -0,0 +1,140 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include + +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) +{ + int rc = 0; + + if (WARN_ON(!pwm)) + return -EINVAL; + + if (!pwm->clk_enabled) { + rc = clk_enable(pwm->clk); + if (!rc) + pwm->clk_enabled = 1; + } + return rc; +} +EXPORT_SYMBOL(pwm_enable); + +void pwm_disable(struct pwm_device *pwm) +{ + if (WARN_ON(!pwm)) + return; + + if (pwm->clk_enabled) { + clk_disable(pwm->clk); + pwm->clk_enabled = 0; + } +} +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..6dd8fb2 --- /dev/null +++ b/arch/arm/mach-davinci/include/mach/davinci_pwm.h @@ -0,0 +1,33 @@ +/* + * 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 clk_enabled; + 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