diff mbox

[1/2] davinci: Add generic PWM support for the PWM control

Message ID 1283841390-27071-1-git-send-email-sugumar@ti.com (mailing list archive)
State Changes Requested, archived
Headers show

Commit Message

Sugumar Natarajan Sept. 7, 2010, 6:36 a.m. UTC
None
diff mbox

Patch

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..378f4f0
--- /dev/null
+++ b/arch/arm/mach-davinci/davinci_pwm.c
@@ -0,0 +1,116 @@ 
+/*
+ * 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;
+
+	if (pwm == NULL || pwm->pwm_config_device == NULL || period_ns == 0 ||
+		 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;
+	pwm->pwm_config_device(pwm, period_cycles, duty_cycle);
+	return 0;
+}
+EXPORT_SYMBOL(pwm_config);
+
+int pwm_enable(struct pwm_device *pwm)
+{
+	clk_enable(pwm->clk);
+	return 0;
+}
+EXPORT_SYMBOL(pwm_enable);
+
+void pwm_disable(struct pwm_device *pwm)
+{
+	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;
+	int found = 0;
+
+	mutex_lock(&pwm_lock);
+
+	list_for_each_entry(pwm, &pwm_list, node) {
+		if (pwm->pwm_id == pwm_id) {
+			found = 1;
+			break;
+		}
+	}
+
+	if (found) {
+		if (pwm->use_count == 0) {
+			pwm->use_count++;
+			pwm->label = label;
+		} else {
+			pwm = ERR_PTR(-EBUSY);
+		}
+	} else {
+		pwm = ERR_PTR(-ENOENT);
+	}
+
+	mutex_unlock(&pwm_lock);
+	return pwm;
+}
+EXPORT_SYMBOL(pwm_request);
+
+void pwm_free(struct pwm_device *pwm)
+{
+	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 add_pwm(struct pwm_device *pwm)
+{
+	mutex_lock(&pwm_lock);
+	list_add_tail(&pwm->node, &pwm_list);
+	mutex_unlock(&pwm_lock);
+}
+EXPORT_SYMBOL(add_pwm);
+
+void remove_pwm(struct pwm_device *pwm)
+{
+	mutex_lock(&pwm_lock);
+	list_del(&pwm->node);
+	mutex_unlock(&pwm_lock);
+}
+EXPORT_SYMBOL(remove_pwm);
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..b89e823
--- /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;
+	void (*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 add_pwm(struct pwm_device *pwm);
+void remove_pwm(struct pwm_device *pwm);
+
+#endif