All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Add pwm core support
@ 2012-01-31  9:36 Sascha Hauer
  2012-02-01  8:20 ` Robert Jarzmik
  2012-02-01 22:42 ` [PATCH] drivers/pwm: add PXA pulse width modulator controller Robert Jarzmik
  0 siblings, 2 replies; 19+ messages in thread
From: Sascha Hauer @ 2012-01-31  9:36 UTC (permalink / raw)
  To: barebox

This patch adds framework support for PWM (pulse width modulation)
devices.
A new pwm can be registered from a hardware driver using
pwmchip_add(). It can then be requested from a client driver using
pwm_request(). A string is used as a unique identifier for the
pwms. It should usually be initialized by the hardware drivers
using dev_name(dev). The client API is the same as currently
in the Linux Kernel.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---

This patch is currently compile tested only due to the lack of
client drivers.

 drivers/Kconfig      |    2 +
 drivers/Makefile     |    1 +
 drivers/pwm/Kconfig  |   12 ++++
 drivers/pwm/Makefile |    1 +
 drivers/pwm/core.c   |  163 ++++++++++++++++++++++++++++++++++++++++++++++++++
 include/pwm.h        |   63 +++++++++++++++++++
 6 files changed, 242 insertions(+), 0 deletions(-)
 create mode 100644 drivers/pwm/Kconfig
 create mode 100644 drivers/pwm/Makefile
 create mode 100644 drivers/pwm/core.c
 create mode 100644 include/pwm.h

diff --git a/drivers/Kconfig b/drivers/Kconfig
index c4e1517..52eedd9 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -15,4 +15,6 @@ source "drivers/mfd/Kconfig"
 source "drivers/led/Kconfig"
 source "drivers/eeprom/Kconfig"
 
+source "drivers/pwm/Kconfig"
+
 endmenu
diff --git a/drivers/Makefile b/drivers/Makefile
index 592c39e..380c2f1 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -13,3 +13,4 @@ obj-y	+= clk/
 obj-y	+= mfd/
 obj-$(CONFIG_LED) += led/
 obj-y	+= eeprom/
+obj-$(CONFIG_PWM) += pwm/
diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
new file mode 100644
index 0000000..93c1052
--- /dev/null
+++ b/drivers/pwm/Kconfig
@@ -0,0 +1,12 @@
+menuconfig PWM
+	bool "PWM Support"
+	help
+	  This enables PWM support through the generic PWM framework.
+	  You only need to enable this, if you also want to enable
+	  one or more of the PWM drivers below.
+
+	  If unsure, say N.
+
+if PWM
+
+endif
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
new file mode 100644
index 0000000..3469c3d
--- /dev/null
+++ b/drivers/pwm/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_PWM)		+= core.o
diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
new file mode 100644
index 0000000..af30edf
--- /dev/null
+++ b/drivers/pwm/core.c
@@ -0,0 +1,163 @@
+/*
+ * Generic pwmlib implementation
+ *
+ * Copyright (C) 2011 Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ *  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; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <common.h>
+#include <errno.h>
+#include <malloc.h>
+#include <pwm.h>
+#include <linux/list.h>
+
+struct pwm_device {
+	struct			pwm_chip *chip;
+	unsigned long		flags;
+#define FLAG_REQUESTED	0
+#define FLAG_ENABLED	1
+	struct list_head	node;
+};
+
+static LIST_HEAD(pwm_list);
+
+static struct pwm_device *_find_pwm(const char *devname)
+{
+	struct pwm_device *pwm;
+
+	list_for_each_entry(pwm, &pwm_list, node) {
+		if (!strcmp(pwm->chip->devname, devname))
+			return pwm;
+	}
+
+	return NULL;
+}
+
+/**
+ * pwmchip_add() - register a new pwm
+ * @chip: the pwm
+ *
+ * register a new pwm. pwm->devname must be initialized, usually
+ * from dev_name(dev) from the hardware driver.
+ */
+int pwmchip_add(struct pwm_chip *chip)
+{
+	struct pwm_device *pwm;
+	int ret = 0;
+
+	if (_find_pwm(chip->devname))
+		return -EBUSY;
+
+	pwm = xzalloc(sizeof(*pwm));
+	pwm->chip = chip;
+
+	list_add_tail(&pwm->node, &pwm_list);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(pwmchip_add);
+
+/**
+ * pwmchip_remove() - remove a pwm
+ * @chip: the pwm
+ *
+ * remove a pwm. This function may return busy if the pwm is still requested.
+ */
+int pwmchip_remove(struct pwm_chip *chip)
+{
+	struct pwm_device *pwm;
+
+	pwm = _find_pwm(chip->devname);
+	if (!pwm)
+		return -ENOENT;
+
+	if (test_bit(FLAG_REQUESTED, &pwm->flags))
+		return -EBUSY;
+
+	list_del(&pwm->node);
+
+	kfree(pwm);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(pwmchip_remove);
+
+/*
+ * pwm_request - request a PWM device
+ */
+struct pwm_device *pwm_request(const char *devname)
+{
+	struct pwm_device *pwm;
+	int ret;
+
+	pwm = _find_pwm(devname);
+	if (!pwm)
+		return NULL;
+
+	if (test_bit(FLAG_REQUESTED, &pwm->flags))
+		return NULL;
+
+	if (pwm->chip->ops->request) {
+		ret = pwm->chip->ops->request(pwm->chip);
+		if (ret)
+			return NULL;
+	}
+
+	set_bit(FLAG_REQUESTED, &pwm->flags);
+
+	return pwm;
+}
+EXPORT_SYMBOL_GPL(pwm_request);
+
+/*
+ * pwm_free - free a PWM device
+ */
+void pwm_free(struct pwm_device *pwm)
+{
+	if (!test_and_clear_bit(FLAG_REQUESTED, &pwm->flags))
+		return;
+}
+EXPORT_SYMBOL_GPL(pwm_free);
+
+/*
+ * pwm_config - change a PWM device configuration
+ */
+int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
+{
+	return pwm->chip->ops->config(pwm->chip, duty_ns, period_ns);
+}
+EXPORT_SYMBOL_GPL(pwm_config);
+
+/*
+ * pwm_enable - start a PWM output toggling
+ */
+int pwm_enable(struct pwm_device *pwm)
+{
+	if (!test_and_set_bit(FLAG_ENABLED, &pwm->flags))
+		return pwm->chip->ops->enable(pwm->chip);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(pwm_enable);
+
+/*
+ * pwm_disable - stop a PWM output toggling
+ */
+void pwm_disable(struct pwm_device *pwm)
+{
+	if (test_and_clear_bit(FLAG_ENABLED, &pwm->flags))
+		pwm->chip->ops->disable(pwm->chip);
+}
+EXPORT_SYMBOL_GPL(pwm_disable);
diff --git a/include/pwm.h b/include/pwm.h
new file mode 100644
index 0000000..80f88b1
--- /dev/null
+++ b/include/pwm.h
@@ -0,0 +1,63 @@
+#ifndef __PWM_H
+#define __PWM_H
+
+struct pwm_device;
+
+/*
+ * pwm_request - request a PWM device
+ */
+struct pwm_device *pwm_request(const char *pwmname);
+
+/*
+ * pwm_free - free a PWM device
+ */
+void pwm_free(struct pwm_device *pwm);
+
+/*
+ * pwm_config - change a PWM device configuration
+ */
+int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns);
+
+/*
+ * pwm_enable - start a PWM output toggling
+ */
+int pwm_enable(struct pwm_device *pwm);
+
+/*
+ * pwm_disable - stop a PWM output toggling
+ */
+void pwm_disable(struct pwm_device *pwm);
+
+struct pwm_chip;
+
+/**
+ * struct pwm_ops - PWM operations
+ * @request: optional hook for requesting a PWM
+ * @free: optional hook for freeing a PWM
+ * @config: configure duty cycles and period length for this PWM
+ * @enable: enable PWM output toggling
+ * @disable: disable PWM output toggling
+ */
+struct pwm_ops {
+	int (*request)(struct pwm_chip *chip);
+	void (*free)(struct pwm_chip *chip);
+	int (*config)(struct pwm_chip *chip, int duty_ns,
+						int period_ns);
+	int (*enable)(struct pwm_chip *chip);
+	void (*disable)(struct pwm_chip *chip);
+};
+
+/**
+ * struct pwm_chip - abstract a PWM
+ * @devname: unique identifier for this pwm
+ * @ops: The callbacks for this PWM
+ */
+struct pwm_chip {
+	const char		*devname;
+	struct pwm_ops		*ops;
+};
+
+int pwmchip_add(struct pwm_chip *chip);
+int pwmchip_remove(struct pwm_chip *chip);
+
+#endif /* __PWM_H */
-- 
1.7.8.3


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply related	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2012-02-16 18:24 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-01-31  9:36 [PATCH] Add pwm core support Sascha Hauer
2012-02-01  8:20 ` Robert Jarzmik
2012-02-01 22:42 ` [PATCH] drivers/pwm: add PXA pulse width modulator controller Robert Jarzmik
2012-02-03  9:52   ` Sascha Hauer
2012-02-03 15:39     ` Robert Jarzmik
2012-02-08 15:26       ` Robert Jarzmik
2012-02-09  8:10         ` Sascha Hauer
2012-02-09 11:50           ` Robert Jarzmik
2012-02-09 13:44             ` Sascha Hauer
2012-02-09 14:30               ` Robert Jarzmik
2012-02-14 12:58             ` [PATCH V2 1/2] " Robert Jarzmik
2012-02-14 12:58               ` [PATCH V2 2/2] drivers/video: remove pxafb enable on load Robert Jarzmik
2012-02-15  8:32               ` [PATCH V2 1/2] drivers/pwm: add PXA pulse width modulator controller Sascha Hauer
2012-02-15 11:22                 ` Robert Jarzmik
2012-02-15 15:21                 ` Robert Jarzmik
2012-02-16  7:40                   ` Sascha Hauer
2012-02-16 18:23                     ` [PATCH V3 1/3] drivers/pwm: add duty_ns and period_ns to core pwm chip Robert Jarzmik
2012-02-16 18:23                       ` [PATCH V3 2/3] drivers/pwm: add PXA pulse width modulator controller Robert Jarzmik
2012-02-16 18:23                       ` [PATCH V3 3/3] drivers/video: remove pxafb enable on load Robert Jarzmik

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.