[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <1743.192.168.1.10.1178627225.squirrel@eggplant.ddo.jp>
Date: Tue, 8 May 2007 21:27:05 +0900 (JST)
From: "kogiidena" <kogiidena@...plant.ddo.jp>
To: rpurdie@...ys.net
Cc: linux-kernel@...r.kernel.org, lethal@...ux-sh.org
Subject: [PATCH 2/2] leds:arch/sh/boards/landisk LEDs supports
To:Richard-san
CC:all
I wrote LED Blink Trigger. Pleas apply if there is no problem.
This allows LEDs to be controlled by a programmable timer.
"blink" blinks LED at a constant cycle.
"bitshift" turns LED or Buzzer on and off by the value of pattern.
Kernel version: linux-2.6.21-rc4
Signed-off-by: kogiidena <kogiidena@...plant.ddo.jp>
---
diff -urpN OLD/drivers/leds/Kconfig NEW/drivers/leds/Kconfig
--- OLD/drivers/leds/Kconfig 2007-03-27 18:30:44.000000000 +0900
+++ NEW/drivers/leds/Kconfig 2007-03-27 18:52:42.000000000 +0900
@@ -134,5 +134,14 @@ config LEDS_TRIGGER_HEARTBEAT
load average.
If unsure, say Y.
+config LEDS_TRIGGER_BLINK
+ tristate "LED Blink Trigger"
+ depends on LEDS_TRIGGERS
+ help
+ This allows LEDs to be controlled by a programmable timer.
+ "blink" blinks LED at a constant cycle.
+ "bitshift" turns LED on and off by the value of pattern.
+ If unsure, say Y.
+
endmenu
diff -urpN OLD/drivers/leds/Makefile NEW/drivers/leds/Makefile
--- OLD/drivers/leds/Makefile 2007-03-27 18:27:18.000000000 +0900
+++ NEW/drivers/leds/Makefile 2007-03-27 18:36:02.000000000 +0900
@@ -22,3 +22,4 @@ obj-$(CONFIG_LEDS_LANDISK) += leds-land
obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o
obj-$(CONFIG_LEDS_TRIGGER_IDE_DISK) += ledtrig-ide-disk.o
obj-$(CONFIG_LEDS_TRIGGER_HEARTBEAT) += ledtrig-heartbeat.o
+obj-$(CONFIG_LEDS_TRIGGER_BLINK) += ledtrig-blink.o
diff -urpN OLD/drivers/leds/ledtrig-blink.c NEW/drivers/leds/ledtrig-blink.c
--- OLD/drivers/leds/ledtrig-blink.c 1970-01-01 09:00:00.000000000 +0900
+++ NEW/drivers/leds/ledtrig-blink.c 2007-03-27 18:16:55.000000000 +0900
@@ -0,0 +1,235 @@
+/*
+ * LED Blink Trigger
+ *
+ * Copyright (C) 2007 kogiidena
+ *
+ * Based on drivers/leds/ledtrig-heartbeat.c by:
+ * Copyright (C) 2006 Atsushi Nemoto <anemo@....ocn.ne.jp>
+ *
+ * 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 <linux/module.h>
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/timer.h>
+#include <linux/sched.h>
+#include <linux/leds.h>
+#include <linux/device.h>
+#include <linux/ctype.h>
+#include "leds.h"
+
+struct blink_trig_data {
+ unsigned int mode;
+ signed int phase;
+ unsigned long interval;
+ struct timer_list timer;
+};
+
+static void led_blink_function(unsigned long data)
+{
+ struct led_classdev *led_cdev = (struct led_classdev *)data;
+ struct blink_trig_data *blink_data = led_cdev->trigger_data;
+ unsigned long delay = blink_data->interval;
+
+ led_set_brightness(led_cdev,
+ blink_data->phase & 0x1 ? LED_FULL : LED_OFF);
+
+ if ((blink_data->mode != 0) ||
+ ((blink_data->phase != 0) && (blink_data->phase != 0xffffffff))) {
+ mod_timer(&blink_data->timer,
+ jiffies + msecs_to_jiffies(delay));
+ }
+ if (blink_data->mode != 0)
+ blink_data->phase++;
+ else
+ blink_data->phase >>= 1;
+}
+
+static ssize_t led_interval_show(struct class_device *dev, char *buf)
+{
+ struct led_classdev *led_cdev = class_get_devdata(dev);
+ struct blink_trig_data *blink_data = led_cdev->trigger_data;
+
+ sprintf(buf, "%lu\n", blink_data->interval);
+
+ return strlen(buf) + 1;
+}
+
+static ssize_t led_interval_store(struct class_device *dev, const char *buf,
+ size_t size)
+{
+ struct led_classdev *led_cdev = class_get_devdata(dev);
+ struct blink_trig_data *blink_data = led_cdev->trigger_data;
+ int ret = -EINVAL;
+ char *after;
+ unsigned long state = simple_strtoul(buf, &after, 10);
+ size_t count = after - buf;
+
+ if (*after && isspace(*after))
+ count++;
+
+ if (count == size) {
+ blink_data->interval = state;
+ mod_timer(&blink_data->timer, jiffies + 1);
+ ret = count;
+ }
+ return ret;
+}
+
+static ssize_t led_pattern_show(struct class_device *dev, char *buf)
+{
+ struct led_classdev *led_cdev = class_get_devdata(dev);
+ struct blink_trig_data *blink_data = led_cdev->trigger_data;
+
+ sprintf(buf, "0x%08x\n", blink_data->phase);
+
+ return strlen(buf) + 1;
+}
+
+static ssize_t led_pattern_store(struct class_device *dev, const char *buf,
+ size_t size)
+{
+ struct led_classdev *led_cdev = class_get_devdata(dev);
+ struct blink_trig_data *blink_data = led_cdev->trigger_data;
+ int ret = -EINVAL;
+ char *after;
+ unsigned long state = simple_strtoul(buf, &after, 16);
+ size_t count = after - buf;
+
+ if (*after && isspace(*after))
+ count++;
+
+ if (count == size) {
+ blink_data->phase = state;
+ mod_timer(&blink_data->timer, jiffies + 1);
+ ret = count;
+ }
+ return ret;
+}
+
+static CLASS_DEVICE_ATTR(interval, 0644, led_interval_show, led_interval_store);
+static CLASS_DEVICE_ATTR(pattern, 0644, led_pattern_show, led_pattern_store);
+
+static void blink_trig_activate(struct led_classdev *led_cdev)
+{
+ struct blink_trig_data *blink_data;
+ int rc;
+
+ blink_data = kzalloc(sizeof(*blink_data), GFP_KERNEL);
+ if (!blink_data)
+ return;
+
+ led_cdev->trigger_data = blink_data;
+
+ blink_data->mode = 1;
+ blink_data->phase = 1;
+ blink_data->interval = 250;
+
+ rc = class_device_create_file(led_cdev->class_dev,
+ &class_device_attr_interval);
+ if (rc)
+ goto err_out;
+
+ setup_timer(&blink_data->timer,
+ led_blink_function, (unsigned long)led_cdev);
+
+ led_blink_function(blink_data->timer.data);
+
+ return;
+
+err_out:
+ led_cdev->trigger_data = NULL;
+ kfree(blink_data);
+}
+
+static void bitshift_trig_activate(struct led_classdev *led_cdev)
+{
+ struct blink_trig_data *blink_data;
+ int rc;
+
+ blink_data = kzalloc(sizeof(*blink_data), GFP_KERNEL);
+ if (!blink_data)
+ return;
+
+ led_cdev->trigger_data = blink_data;
+
+ blink_data->mode = 0;
+ blink_data->phase = 0;
+ blink_data->interval = 250;
+
+ rc = class_device_create_file(led_cdev->class_dev,
+ &class_device_attr_interval);
+ if (rc)
+ goto err_out;
+
+ rc = class_device_create_file(led_cdev->class_dev,
+ &class_device_attr_pattern);
+ if (rc)
+ goto err_out_interval;
+
+ setup_timer(&blink_data->timer,
+ led_blink_function, (unsigned long)led_cdev);
+
+ led_blink_function(blink_data->timer.data);
+
+ return;
+
+err_out_interval:
+ class_device_remove_file(led_cdev->class_dev,
+ &class_device_attr_interval);
+err_out:
+ led_cdev->trigger_data = NULL;
+ kfree(blink_data);
+}
+
+static void blink_trig_deactivate(struct led_classdev *led_cdev)
+{
+ struct blink_trig_data *blink_data = led_cdev->trigger_data;
+
+ if (blink_data) {
+ class_device_remove_file(led_cdev->class_dev,
+ &class_device_attr_interval);
+ if (blink_data->mode == 0) {
+ class_device_remove_file(led_cdev->class_dev,
+ &class_device_attr_pattern);
+ }
+ del_timer_sync(&blink_data->timer);
+ kfree(blink_data);
+ }
+}
+
+static struct led_trigger blink_led_trigger = {
+ .name = "blink",
+ .activate = blink_trig_activate,
+ .deactivate = blink_trig_deactivate,
+};
+
+static struct led_trigger bitshift_led_trigger = {
+ .name = "bitshift",
+ .activate = bitshift_trig_activate,
+ .deactivate = blink_trig_deactivate,
+};
+
+static int __init blink_trig_init(void)
+{
+ led_trigger_register(&blink_led_trigger);
+ led_trigger_register(&bitshift_led_trigger);
+ return 0;
+}
+
+static void __exit blink_trig_exit(void)
+{
+ led_trigger_unregister(&blink_led_trigger);
+ led_trigger_unregister(&bitshift_led_trigger);
+}
+
+module_init(blink_trig_init);
+module_exit(blink_trig_exit);
+
+MODULE_AUTHOR("kogiidena <kogiidena@...plant.ddo.jp>");
+MODULE_DESCRIPTION("Blink LED trigger");
+MODULE_LICENSE("GPL");
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists