summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNaga Radhesh <naga.radheshy@stericsson.com>2012-02-27 20:44:33 +0530
committerPhilippe Langlais <philippe.langlais@stericsson.com>2012-05-22 11:01:39 +0200
commit5ef65ec433d008af4918114642ddfc207cf95af0 (patch)
treedc4396eefc36e75924e2cd3832dd0910c4e91a47
parentdde2702b6dec26717c0badd0878144c5e3f23470 (diff)
ab8500-pwm:Add sysfs path to disable LED blinking
Add sysfs path to disable LED blinking functionality ST-Ericsson ID: 366316 ST-Ericsson Linux next: NA ST-Ericsson FOSS-OUT ID: Trivial Change-Id:I3f4c62525defe948459cf74c3ae18f4cf81945bf Signed-off-by: Naga Radhesh <naga.radheshy@stericsson.com> Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/50621 Reviewed-by: Arun MURTHY <arun.murthy@stericsson.com> Reviewed-by: Srinidhi KASAGAR <srinidhi.kasagar@stericsson.com>
-rw-r--r--drivers/misc/ab8500-pwm.c76
1 files changed, 75 insertions, 1 deletions
diff --git a/drivers/misc/ab8500-pwm.c b/drivers/misc/ab8500-pwm.c
index 01d329ba76c..9d864e4db5a 100644
--- a/drivers/misc/ab8500-pwm.c
+++ b/drivers/misc/ab8500-pwm.c
@@ -36,6 +36,7 @@ struct pwm_device {
struct clk *clk;
const char *label;
unsigned int pwm_id;
+ unsigned int num_pwm;
unsigned int blink_en;
struct ab8500 *parent;
bool clk_enabled;
@@ -74,6 +75,7 @@ int pwm_config_blink(struct pwm_device *pwm, int duty_ns, int period_ns)
pwm->label, ret);
return ret;
}
+EXPORT_SYMBOL(pwm_config_blink);
int pwm_blink_ctrl(struct pwm_device *pwm , int enable)
{
@@ -96,6 +98,7 @@ int pwm_blink_ctrl(struct pwm_device *pwm , int enable)
pwm->label, ret);
return ret;
}
+EXPORT_SYMBOL(pwm_blink_ctrl);
int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
{
@@ -202,6 +205,46 @@ void pwm_free(struct pwm_device *pwm)
}
EXPORT_SYMBOL(pwm_free);
+static ssize_t store_blink_status(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct pwm_device *pwm;
+ unsigned long val;
+
+ if (strict_strtoul(buf, 0, &val))
+ return -EINVAL;
+ list_for_each_entry(pwm, &pwm_list, node) {
+ if (pwm->pwm_id == val)
+ break;
+ else {
+ /* check if PWM ID is valid*/
+ if (val > pwm->num_pwm) {
+ dev_err(pwm->dev, "Invalid PWM ID\n");
+ return -EINVAL;
+ }
+ }
+ }
+ if ((!is_ab8505(pwm->parent)) || (!pwm->blink_en)) {
+ dev_err(pwm->dev, "setting blinking for this "
+ "device not supported\n");
+ return -EINVAL;
+ }
+ /*Disable blink functionlity */
+ pwm_blink_ctrl(pwm, 0);
+ return count;
+}
+
+static DEVICE_ATTR(disable_blink, S_IWUGO, NULL, store_blink_status);
+
+static struct attribute *pwmled_attributes[] = {
+ &dev_attr_disable_blink.attr,
+ NULL
+};
+
+static const struct attribute_group pwmled_attr_group = {
+ .attrs = pwmled_attributes,
+};
+
static int __devinit ab8500_pwm_probe(struct platform_device *pdev)
{
struct ab8500 *parent = dev_get_drvdata(pdev->dev.parent);
@@ -231,19 +274,42 @@ static int __devinit ab8500_pwm_probe(struct platform_device *pdev)
pwm[i].parent = parent;
pwm[i].blink_en = pdata->leds[i].blink_en;
pwm[i].pwm_id = pdata->leds[i].pwm_id;
+ pwm[i].num_pwm = pdata->num_pwm;
list_add_tail(&pwm[i].node, &pwm_list);
}
+ for (i = 0; i < pdata->num_pwm; i++) {
+ /*Implement sysfs only if blink is enabled*/
+ if ((is_ab8505(pwm[i].parent)) && (pwm[i].blink_en)) {
+ /* sysfs implementation to disable the blink */
+ ret = sysfs_create_group(&pdev->dev.kobj,
+ &pwmled_attr_group);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to create"
+ " sysfs entries\n");
+ goto fail;
+ }
+ break;
+ }
+ }
pwm->clk = clk_get(pwm->dev, NULL);
if (IS_ERR(pwm->clk)) {
dev_err(pwm->dev, "clock request failed\n");
ret = PTR_ERR(pwm->clk);
- goto fail;
+ goto err_clk;
}
platform_set_drvdata(pdev, pwm);
pwm->clk_enabled = false;
dev_dbg(pwm->dev, "pwm probe successful\n");
return ret;
+err_clk:
+ for (i = 0; i < pdata->num_pwm; i++) {
+ if ((is_ab8505(pwm[i].parent)) && (pwm[i].blink_en)) {
+ sysfs_remove_group(&pdev->dev.kobj,
+ &pwmled_attr_group);
+ break;
+ }
+ }
fail:
list_del(&pwm->node);
kfree(pwm);
@@ -253,7 +319,15 @@ fail:
static int __devexit ab8500_pwm_remove(struct platform_device *pdev)
{
struct pwm_device *pwm = platform_get_drvdata(pdev);
+ int i;
+ for (i = 0; i < pwm->num_pwm; i++) {
+ if ((is_ab8505(pwm[i].parent)) && (pwm[i].blink_en)) {
+ sysfs_remove_group(&pdev->dev.kobj,
+ &pwmled_attr_group);
+ break;
+ }
+ }
list_del(&pwm->node);
clk_put(pwm->clk);
dev_dbg(&pdev->dev, "pwm driver removed\n");