@@ -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
new file mode 100644
@@ -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);
new file mode 100644
@@ -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