Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754138Ab2EZXTH (ORCPT ); Sat, 26 May 2012 19:19:07 -0400 Received: from mail-wi0-f178.google.com ([209.85.212.178]:52554 "EHLO mail-wi0-f178.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753391Ab2EZXTB (ORCPT ); Sat, 26 May 2012 19:19:01 -0400 From: Fabio Baltieri To: Bryan Wu Cc: linux-leds@vger.kernel.org, linux-kernel@vger.kernel.org, Richard Purdie , Fabio Baltieri , Shuah Khan Subject: [PATCH 3/3] led: add oneshot trigger Date: Sun, 27 May 2012 01:19:24 +0200 Message-Id: <1338074364-1829-3-git-send-email-fabio.baltieri@gmail.com> X-Mailer: git-send-email 1.7.5.1 In-Reply-To: <1338074364-1829-1-git-send-email-fabio.baltieri@gmail.com> References: <1338074364-1829-1-git-send-email-fabio.baltieri@gmail.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 7280 Lines: 256 Add oneshot trigger to blink a led with configurable parameters via sysfs. Signed-off-by: Fabio Baltieri Cc: Bryan Wu Cc: Shuah Khan --- That's (a cleaned up version of) what I used to test the first patch. Should we also consider this one for integration? Shuah Khan was working on something similar, I'll add him in CC. Fabio drivers/leds/Kconfig | 9 ++ drivers/leds/Makefile | 1 + drivers/leds/ledtrig-oneshot.c | 190 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 200 insertions(+) create mode 100644 drivers/leds/ledtrig-oneshot.c diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index ff4b8cf..17c3cf2 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -422,6 +422,15 @@ config LEDS_TRIGGER_TIMER If unsure, say Y. +config LEDS_TRIGGER_ONESHOT + tristate "One-Shot Trigger" + depends on LEDS_TRIGGERS + help + This allows LEDs to blink in one-shot pulses with parameters + controlled via sysfs. + + If unsure, say Y. + config LEDS_TRIGGER_IDE_DISK bool "LED IDE Disk Trigger" depends on IDE_GD_ATA diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index 890481c..ec8ff79 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile @@ -51,6 +51,7 @@ obj-$(CONFIG_LEDS_DAC124S085) += leds-dac124s085.o # LED Triggers obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o +obj-$(CONFIG_LEDS_TRIGGER_ONESHOT) += ledtrig-oneshot.o obj-$(CONFIG_LEDS_TRIGGER_IDE_DISK) += ledtrig-ide-disk.o obj-$(CONFIG_LEDS_TRIGGER_HEARTBEAT) += ledtrig-heartbeat.o obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT) += ledtrig-backlight.o diff --git a/drivers/leds/ledtrig-oneshot.c b/drivers/leds/ledtrig-oneshot.c new file mode 100644 index 0000000..7d9a052 --- /dev/null +++ b/drivers/leds/ledtrig-oneshot.c @@ -0,0 +1,190 @@ +/* + * One-Shot LED Trigger + * + * Copyright 2012, Fabio Baltieri + * + * Based on ledtrig-timer.c by Richard Purdie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +struct oneshot_trig_data { + unsigned int invert; +}; + +static ssize_t led_shot(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + struct led_classdev *led_cdev = dev_get_drvdata(dev); + struct oneshot_trig_data *oneshot_data = led_cdev->trigger_data; + + led_blink_set_oneshot(led_cdev, + &led_cdev->blink_delay_on, &led_cdev->blink_delay_off, + oneshot_data->invert); + + /* content is ignored */ + return size; +} +static ssize_t led_invert_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct led_classdev *led_cdev = dev_get_drvdata(dev); + struct oneshot_trig_data *oneshot_data = led_cdev->trigger_data; + + return sprintf(buf, "%u\n", oneshot_data->invert); +} + +static ssize_t led_invert_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + struct led_classdev *led_cdev = dev_get_drvdata(dev); + struct oneshot_trig_data *oneshot_data = led_cdev->trigger_data; + unsigned long state; + int ret = -EINVAL; + + ret = kstrtoul(buf, 0, &state); + if (ret) + return ret; + + oneshot_data->invert = !!state; + + return size; +} + +static ssize_t led_delay_on_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct led_classdev *led_cdev = dev_get_drvdata(dev); + + return sprintf(buf, "%lu\n", led_cdev->blink_delay_on); +} + +static ssize_t led_delay_on_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + struct led_classdev *led_cdev = dev_get_drvdata(dev); + unsigned long state; + int ret = -EINVAL; + + ret = kstrtoul(buf, 0, &state); + if (ret) + return ret; + + led_cdev->blink_delay_on = state; + + return size; +} +static ssize_t led_delay_off_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct led_classdev *led_cdev = dev_get_drvdata(dev); + + return sprintf(buf, "%lu\n", led_cdev->blink_delay_off); +} + +static ssize_t led_delay_off_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + struct led_classdev *led_cdev = dev_get_drvdata(dev); + unsigned long state; + int ret = -EINVAL; + + ret = kstrtoul(buf, 0, &state); + if (ret) + return ret; + + led_cdev->blink_delay_off = state; + + return size; +} + +static DEVICE_ATTR(delay_on, 0644, led_delay_on_show, led_delay_on_store); +static DEVICE_ATTR(delay_off, 0644, led_delay_off_show, led_delay_off_store); +static DEVICE_ATTR(invert, 0644, led_invert_show, led_invert_store); +static DEVICE_ATTR(shot, 0200, NULL, led_shot); + +static void oneshot_trig_activate(struct led_classdev *led_cdev) +{ + struct oneshot_trig_data *oneshot_data; + int rc; + + oneshot_data = kzalloc(sizeof(*oneshot_data), GFP_KERNEL); + if (!oneshot_data) + return; + + led_cdev->trigger_data = oneshot_data; + + rc = device_create_file(led_cdev->dev, &dev_attr_delay_on); + if (rc) + goto err_out_trig_data; + rc = device_create_file(led_cdev->dev, &dev_attr_delay_off); + if (rc) + goto err_out_delayon; + rc = device_create_file(led_cdev->dev, &dev_attr_invert); + if (rc) + goto err_out_delayoff; + rc = device_create_file(led_cdev->dev, &dev_attr_shot); + if (rc) + goto err_out_invert; + + return; + +err_out_invert: + device_remove_file(led_cdev->dev, &dev_attr_invert); +err_out_delayoff: + device_remove_file(led_cdev->dev, &dev_attr_delay_off); +err_out_delayon: + device_remove_file(led_cdev->dev, &dev_attr_delay_on); +err_out_trig_data: + kfree(led_cdev->trigger_data); +} + +static void oneshot_trig_deactivate(struct led_classdev *led_cdev) +{ + struct oneshot_trig_data *oneshot_data = led_cdev->trigger_data; + + if (oneshot_data) { + device_remove_file(led_cdev->dev, &dev_attr_delay_on); + device_remove_file(led_cdev->dev, &dev_attr_delay_off); + device_remove_file(led_cdev->dev, &dev_attr_invert); + device_remove_file(led_cdev->dev, &dev_attr_shot); + kfree(led_cdev->trigger_data); + } + + /* Stop blinking */ + led_brightness_set(led_cdev, LED_OFF); +} + +static struct led_trigger oneshot_led_trigger = { + .name = "oneshot", + .activate = oneshot_trig_activate, + .deactivate = oneshot_trig_deactivate, +}; + +static int __init oneshot_trig_init(void) +{ + return led_trigger_register(&oneshot_led_trigger); +} + +static void __exit oneshot_trig_exit(void) +{ + led_trigger_unregister(&oneshot_led_trigger); +} + +module_init(oneshot_trig_init); +module_exit(oneshot_trig_exit); + +MODULE_AUTHOR("Fabio Baltieri "); +MODULE_DESCRIPTION("One-Shot LED trigger"); +MODULE_LICENSE("GPL"); -- 1.7.10.2.520.g6a4a482.dirty -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/