@@ -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,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);
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;
+ 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