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(-) @ drivers/pwm/pwm_test.c:29 @ #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; }; @ drivers/pwm/pwm_test.c:56 @ 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; } @ drivers/pwm/pwm_test.c:88 @ 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; } @ drivers/pwm/pwm_test.c:180 @ 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)) { @ drivers/pwm/pwm_test.c:196 @ 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; } @ drivers/pwm/pwm_test.c:217 @ 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, @ drivers/pwm/pwm_test.c:243 @ 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); @ drivers/pwm/pwm_test.c:263 @ 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; } @ drivers/pwm/pwm_test.c:339 @ 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