From 5b79c57d5039649d7033d0b0ffe80b5dceb1cf78 Mon Sep 17 00:00:00 2001
From: Elias Bakken <elias.bakken@gmail.com>
Date: Tue, 2 Apr 2013 12:10:28 -0500
Subject: [PATCH 20/51] pwm: fix the pwm_test driver to work with device-tree

Hi, I have a patch for the pwm_test.c driver to make it work with device tree.

Signed-off-by: Elias Bakken <elias.bakken@gmail.com>
Signed-off-by: Robert Nelson <robertcnelson@gmail.com>
---
 drivers/pwm/pwm_test.c |  122 ++++++++++++++++++++++++++++--------------------
 1 file changed, 72 insertions(+), 50 deletions(-)

diff --git a/drivers/pwm/pwm_test.c b/drivers/pwm/pwm_test.c
index d9948db..1318d5d 100644
--- a/drivers/pwm/pwm_test.c
+++ b/drivers/pwm/pwm_test.c
@@ -26,13 +26,14 @@
 #include <linux/err.h>
 #include <linux/clk.h>
 #include <linux/pm_runtime.h>
+#include <linux/pinctrl/consumer.h>
 
 struct pwm_test {
 	struct pwm_device *pwm;
 	int ret;
 	struct class *pwm_test_class;
-	unsigned long period, duty, run, polarity, config, requested;
-	unsigned long period_s, duty_s, run_s, polarity_s, config_s, requested_s;
+	unsigned long period, duty, run, polarity, requested;
+	unsigned long period_s, duty_s, run_s, polarity_s, requested_s;
 	struct device *dev;
 };
 
@@ -52,6 +53,17 @@ static ssize_t pwm_test_store_duty(struct device *dev,
 	rc = kstrtoul(buf, 0, &pwm_test->duty_s);
 	if (rc)
 		return rc;
+
+	rc = pwm_config(pwm_test->pwm, pwm_test->duty_s, pwm_test->period);
+	if (rc) {
+		pr_err("Unable to set pwm duty %d\n", rc);
+		pwm_test->duty_s = pwm_test->duty;
+		pwm_test->period_s = pwm_test->period;
+		return rc;
+	}
+	pwm_test->duty = pwm_test->duty_s;
+	pwm_test->period = pwm_test->period_s;
+
 	return count;
 }
 
@@ -73,50 +85,16 @@ static ssize_t pwm_test_store_period(struct device *dev,
 	if (rc)
 		return rc;
 
-	return count;
-}
-
-static ssize_t pwm_test_show_config(struct device *dev,
-		struct device_attribute *attr, char *buf)
-{
-	struct pwm_test *pwm_test = dev_get_drvdata(dev);
-	if (pwm_test->config)
-		return sprintf(buf, "config Done\n");
-	else
-		return sprintf(buf, "config Failed\n");
-}
-static ssize_t pwm_test_store_config(struct device *dev,
-		struct device_attribute *attr, const char *buf, size_t count)
-{
-	struct pwm_test *pwm_test = dev_get_drvdata(dev);
-	int ret;
-
-	if (pwm_test->duty_s == 0) {
-		ret = pwm_config(pwm_test->pwm, 0, pwm_test->period_s);
-		if (ret) {
-			pwm_test->config = 0;
-			pr_err("operation failed %d\n", ret);
-			pwm_test->duty_s = pwm_test->duty;
-			pwm_test->period_s = pwm_test->period;
-			return ret;
-		}
-		pwm_test->duty = pwm_test->duty_s;
-		pwm_test->period = pwm_test->period_s;
-		pwm_test->config = 1;
-	} else {
-		ret = pwm_config(pwm_test->pwm, pwm_test->duty_s,
-				pwm_test->period_s);
-		if (ret) {
-			pwm_test->config = 0;
-			pr_err("operation failed %d\n", ret);
-			pwm_test->duty_s = pwm_test->duty;
-			pwm_test->period_s = pwm_test->period;
-			return ret;
-		}
-		pwm_test->duty = pwm_test->duty_s;
-		pwm_test->period = pwm_test->period_s;
-		pwm_test->config = 1;
+	rc = pwm_config(pwm_test->pwm, pwm_test->duty, pwm_test->period_s);
+	if (rc) {
+		pr_err("Unable to set pwm period %d\n", rc);
+		pwm_test->duty_s = pwm_test->duty;
+		pwm_test->period_s = pwm_test->period;
+		return rc;
 	}
+	pwm_test->duty = pwm_test->duty_s;
+	pwm_test->period = pwm_test->period_s;
+
 	return count;
 }
 
@@ -199,6 +177,9 @@ static ssize_t pwm_test_store_request(struct device *dev,
 		return rc;
 
 	if (pwm_test->requested_s) {
+		if(pwm_test->requested) // Allready requested
+			return count;
+
 		pwm_test->pwm = pwm_get(dev, NULL);
 
 		if (IS_ERR(pwm_test->pwm)) {
@@ -212,12 +193,10 @@ static ssize_t pwm_test_store_request(struct device *dev,
 		pwm_test->run = 0;
 		pwm_test->duty = 0;
 		pwm_test->period = 0;
-		pwm_test->config = 0;
 		pwm_test->polarity_s = 0;
 		pwm_test->run_s = 0;
 		pwm_test->duty_s = 0;
 		pwm_test->period_s = 0;
-		pwm_test->config_s = 0;
 		rc = 0;
 	}
 
@@ -235,14 +214,12 @@ static DEVICE_ATTR(duty, 0644, pwm_test_show_duty, pwm_test_store_duty);
 static DEVICE_ATTR(period, 0644, pwm_test_show_period, pwm_test_store_period);
 static DEVICE_ATTR(polarity, 0644, pwm_test_show_polarity,
 		pwm_test_store_polarity);
-static DEVICE_ATTR(config, 0644 , pwm_test_show_config, pwm_test_store_config);
 static DEVICE_ATTR(run, 0644 , pwm_test_show_run, pwm_test_store_run);
 static DEVICE_ATTR(request, 0644 , pwm_test_show_request, pwm_test_store_request);
 
 static const struct attribute *pwm_attrs[] = {
 	&dev_attr_duty.attr,
 	&dev_attr_period.attr,
-	&dev_attr_config.attr,
 	&dev_attr_run.attr,
 	&dev_attr_request.attr,
 	&dev_attr_polarity.attr,
@@ -263,6 +240,14 @@ static int __init pwm_test_class_init(struct device *dev)
 static int pwm_test_probe(struct platform_device *pdev)
 {
 	struct pwm_test *pwm_test;
+	struct pinctrl *pinctrl;
+	struct device_node *node = (&pdev->dev)->of_node;
+	int rc;
+
+	pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
+	if (IS_ERR(pinctrl))
+		dev_warn(&pdev->dev, "unable to select pin group. PWM not muxed right\n");
+
 
 	pwm_test = devm_kzalloc(&pdev->dev, sizeof(*pwm_test), GFP_KERNEL);
 
@@ -275,7 +260,43 @@ static int pwm_test_probe(struct platform_device *pdev)
 		dev_err(&pdev->dev, "sysfs creation failed\n");
 		return -EINVAL;
 	}
-	dev_set_drvdata(&pdev->dev, pwm_test);
+
+	pwm_test->pwm = devm_pwm_get(&pdev->dev, NULL);
+	if (IS_ERR(pwm_test->pwm)) {
+		dev_err(&pdev->dev, "unable to request PWM\n");
+		return -EINVAL;
+	}
+
+	pwm_test->requested = 1;
+
+	pr_debug("pwm_test got PWM\n");
+
+	/* Get the properties of the pwm. This is set in the device driver (tiehrpwm) */
+	pwm_test->period = pwm_get_period(pwm_test->pwm);
+
+	/* Determine running or not from the device tree */
+	rc = of_property_read_u32(node, "enabled", (u32*) &(pwm_test->run));
+	if (rc < 0)
+		return rc;
+
+	if(pwm_test->run){
+		rc = pwm_enable(pwm_test->pwm);
+		if (rc < 0)
+				return rc;
+	}
+
+	/* Determine the duty from the device tree */
+	rc = of_property_read_u32(node, "duty", (u32*) &(pwm_test->duty_s));
+	if (rc < 0)
+		return rc;
+
+	rc = pwm_config(pwm_test->pwm, pwm_test->duty_s, pwm_test->period);
+	if (rc) {
+		pr_err("Unable to set pwm duty %d\n", rc);
+		return rc;
+	}
+
+
 	platform_set_drvdata(pdev, pwm_test);
 	return 0;
 }
@@ -315,6 +336,7 @@ static struct platform_driver pwm_test_driver = {
 	.remove		= pwm_test_remove,
 };
 
+
 module_platform_driver(pwm_test_driver);
 
 MODULE_DESCRIPTION("pwm_test Driver");
-- 
1.7.10.4