devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3] PWM: PXA: add device tree support to PWM driver
@ 2013-09-13 16:54 Mike Dunn
       [not found] ` <1379091281-23662-1-git-send-email-mikedunn-kFrNdAxtuftBDgjK7y7TUQ@public.gmane.org>
  0 siblings, 1 reply; 13+ messages in thread
From: Mike Dunn @ 2013-09-13 16:54 UTC (permalink / raw)
  To: linux-pwm-u79uwXL29TY76Z2rM5mHXA
  Cc: Mike Dunn, Grant Likely, Thierry Reding, Rob Herring,
	Haojian Zhuang, Robert Jarzmik, Marek Vasut,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Dmitry Torokhov, Chao Xie, Sergei Shtylyov, Pawel Moll,
	Mark Rutland, Stephen Warren, Ian Campbell

This patch adds device tree support to the PXA's PWM driver.  Only an OF match
table is added; nothing needs to be extracted from the device tree node.  The
existing ID table is reused for the match table data.

Tested on a Palm Treo 680 (both platform data and DT cases).

Signed-off-by: Mike Dunn <mikedunn-kFrNdAxtuftBDgjK7y7TUQ@public.gmane.org>
---
Changle log:
v3:
- remove support for the polarity flag
- remove per-chip pwm index cell; define custom of_xlate()
   (now #pwm-cells = <1>)
- "compatible" strings for all devices added to OF match table
- various stylistic changes recommended by reviewers

v2:
- of_match_table contains only the "pxa250-pwm" compatible string; require one
  device instance per pwm
- add Documentation/devicetree/bindings/pwm/pxa-pwm.txt
- add support for polarity flag in DT and implement set_polarity() method
  (the treo 680 inverts the signal between pwm out and backlight)
- return -EINVAL instead of -ENODEV if platform data or DT node not found
- output dev_info string if platform data missing
- expanded CC list of patch

 Documentation/devicetree/bindings/pwm/pxa-pwm.txt | 31 ++++++++++++
 arch/arm/boot/dts/pxa27x.dtsi                     | 24 +++++++++
 drivers/pwm/pwm-pxa.c                             | 62 +++++++++++++++++++++++
 3 files changed, 117 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pwm/pxa-pwm.txt

diff --git a/Documentation/devicetree/bindings/pwm/pxa-pwm.txt b/Documentation/devicetree/bindings/pwm/pxa-pwm.txt
new file mode 100644
index 0000000..6fcf90c
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/pxa-pwm.txt
@@ -0,0 +1,31 @@
+Marvell PWM controller
+
+Required properties:
+- compatible: should be one of:
+  - "marvell,pxa250-pwm"
+  - "marvell,pxa270-pwm"
+  - "marvell,pxa168-pwm"
+  - "marvell,pxa910-pwm"
+- reg: physical base address and length of the registers used by the PWM channel
+  NB: One device instance must be created for each PWM that is used, so the
+  length covers only the register window for one PWM output, not that of the
+  entire PWM controller.  Currently length is 0x10 for all supported devices.
+- #pwm-cells: should be 1.  This cell is used to specify the period in
+  nanoseconds.  (Because one device instance is created for each PWM output,
+  the per-chip index is superflous and not used.)
+
+Example PWM device node:
+
+pwm0: pwm@40b00000 {
+	compatible = "marvell,pxa250-pwm";
+	reg = <0x40b00000 0x10>;
+	#pwm-cells = <1>;
+};
+
+Example PWM client node:
+
+backlight {
+	compatible = "pwm-backlight";
+	pwms = <&pwm0 5000000>;
+	...
+}
diff --git a/arch/arm/boot/dts/pxa27x.dtsi b/arch/arm/boot/dts/pxa27x.dtsi
index d7c5d72..5057c41 100644
--- a/arch/arm/boot/dts/pxa27x.dtsi
+++ b/arch/arm/boot/dts/pxa27x.dtsi
@@ -10,5 +10,29 @@
 			marvell,intc-priority;
 			marvell,intc-nr-irqs = <34>;
 		};
+
+		pwm0: pwm@40b00000 {
+			compatible = "marvell,pxa270-pwm";
+			reg = <0x40b00000 0x10>;
+			#pwm-cells = <1>;
+		};
+
+		pwm1: pwm@40b00010 {
+			compatible = "marvell,pxa270-pwm";
+			reg = <0x40b00010 0x10>;
+			#pwm-cells = <1>;
+		};
+
+		pwm2: pwm@40c00000 {
+			compatible = "marvell,pxa270-pwm";
+			reg = <0x40c00000 0x10>;
+			#pwm-cells = <1>;
+		};
+
+		pwm3: pwm@40c00010 {
+			compatible = "marvell,pxa270-pwm";
+			reg = <0x40c00010 0x10>;
+			#pwm-cells = <1>;
+		};
 	};
 };
diff --git a/drivers/pwm/pwm-pxa.c b/drivers/pwm/pwm-pxa.c
index a4d2164..91b1cff 100644
--- a/drivers/pwm/pwm-pxa.c
+++ b/drivers/pwm/pwm-pxa.c
@@ -19,6 +19,7 @@
 #include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/pwm.h>
+#include <linux/of_device.h>
 
 #include <asm/div64.h>
 
@@ -124,6 +125,59 @@ static struct pwm_ops pxa_pwm_ops = {
 	.owner = THIS_MODULE,
 };
 
+#ifdef CONFIG_OF
+/*
+ * Device tree users must create one device instance for each pwm channel.
+ * Hence we dispense with the HAS_SECONDARY_PWM and "tell" the original driver
+ * code that this is a single channel pxa25x-pwm.  Currently all devices are
+ * supported identically.
+ */
+static struct of_device_id pwm_of_match[] = {
+	{ .compatible = "marvell,pxa250-pwm", .data = &pwm_id_table[0]},
+	{ .compatible = "marvell,pxa270-pwm", .data = &pwm_id_table[0]},
+	{ .compatible = "marvell,pxa168-pwm", .data = &pwm_id_table[0]},
+	{ .compatible = "marvell,pxa910-pwm", .data = &pwm_id_table[0]},
+	{ }
+};
+MODULE_DEVICE_TABLE(of, pwm_of_match);
+
+static const struct platform_device_id *pxa_pwm_get_id_dt(struct device *dev)
+{
+	const struct of_device_id *id = of_match_device(pwm_of_match, dev);
+	if (id)
+		return (const struct platform_device_id *)id->data;
+	else
+		return NULL;
+}
+
+struct pwm_device *
+pxa_pwm_of_xlate(struct pwm_chip *pc, const struct of_phandle_args *args)
+{
+	struct pwm_device *pwm;
+
+	pwm = pwm_request_from_chip(pc, 0, NULL);
+	if (IS_ERR(pwm))
+		return pwm;
+
+	pwm_set_period(pwm, args->args[0]);
+
+	return pwm;
+}
+
+#else  /* !CONFIG_OF */
+static const struct platform_device_id *pxa_pwm_get_id_dt(struct device *dev)
+{
+	dev_err(dev, "missing platform data\n");
+	return NULL;
+}
+
+struct pwm_device *
+pxa_pwm_of_xlate(struct pwm_chip *pc, const struct of_phandle_args *args)
+{
+	return NULL;
+}
+#endif
+
 static int pwm_probe(struct platform_device *pdev)
 {
 	const struct platform_device_id *id = platform_get_device_id(pdev);
@@ -131,6 +185,11 @@ static int pwm_probe(struct platform_device *pdev)
 	struct resource *r;
 	int ret = 0;
 
+	if (id == NULL)		/* using device tree */
+		id = pxa_pwm_get_id_dt(&pdev->dev);
+	if (id == NULL)
+		return -EINVAL;
+
 	pwm = devm_kzalloc(&pdev->dev, sizeof(*pwm), GFP_KERNEL);
 	if (pwm == NULL) {
 		dev_err(&pdev->dev, "failed to allocate memory\n");
@@ -145,6 +204,8 @@ static int pwm_probe(struct platform_device *pdev)
 	pwm->chip.ops = &pxa_pwm_ops;
 	pwm->chip.base = -1;
 	pwm->chip.npwm = (id->driver_data & HAS_SECONDARY_PWM) ? 2 : 1;
+	pwm->chip.of_xlate = pxa_pwm_of_xlate;
+	pwm->chip.of_pwm_n_cells = 1;
 
 	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	pwm->mmio_base = devm_ioremap_resource(&pdev->dev, r);
@@ -176,6 +237,7 @@ static struct platform_driver pwm_driver = {
 	.driver		= {
 		.name	= "pxa25x-pwm",
 		.owner	= THIS_MODULE,
+		.of_match_table	= of_match_ptr(pwm_of_match),
 	},
 	.probe		= pwm_probe,
 	.remove		= pwm_remove,
-- 
1.8.1.5

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

end of thread, other threads:[~2013-09-17 19:26 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-09-13 16:54 [PATCH v3] PWM: PXA: add device tree support to PWM driver Mike Dunn
     [not found] ` <1379091281-23662-1-git-send-email-mikedunn-kFrNdAxtuftBDgjK7y7TUQ@public.gmane.org>
2013-09-15 14:07   ` Marek Vasut
     [not found]     ` <201309151607.04244.marex-ynQEQJNshbs@public.gmane.org>
2013-09-16 14:42       ` Mike Dunn
     [not found]         ` <523718D3.4050003-kFrNdAxtuftBDgjK7y7TUQ@public.gmane.org>
2013-09-16 15:10           ` Marek Vasut
     [not found]             ` <201309161710.15800.marex-ynQEQJNshbs@public.gmane.org>
2013-09-16 19:45               ` Stephen Warren
     [not found]                 ` <52375FDB.8090405-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2013-09-16 23:00                   ` Marek Vasut
2013-09-16 19:44   ` Stephen Warren
     [not found]     ` <52375FB1.5050700-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2013-09-16 23:01       ` Marek Vasut
     [not found]         ` <201309170101.06640.marex-ynQEQJNshbs@public.gmane.org>
2013-09-16 23:03           ` Stephen Warren
2013-09-17 14:07       ` Mike Dunn
     [not found]         ` <5238621D.3050504-kFrNdAxtuftBDgjK7y7TUQ@public.gmane.org>
2013-09-17 16:17           ` Stephen Warren
     [not found]             ` <52388093.2000401-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2013-09-17 18:56               ` Mike Dunn
     [not found]                 ` <5238A5C2.4080902-kFrNdAxtuftBDgjK7y7TUQ@public.gmane.org>
2013-09-17 19:26                   ` Stephen Warren

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).