1 /* 2 * LED Kernel Timer Trigger 3 * 4 * Copyright 2005-2006 Openedhand Ltd. 5 * 6 * Author: Richard Purdie <rpurdie@openedhand.com> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License version 2 as 10 * published by the Free Software Foundation. 11 */ 12 13 #include <linux/module.h> 14 #include <linux/kernel.h> 15 #include <linux/init.h> 16 #include <linux/device.h> 17 #include <linux/ctype.h> 18 #include <linux/leds.h> 19 20 static ssize_t led_delay_on_show(struct device *dev, 21 struct device_attribute *attr, char *buf) 22 { 23 struct led_classdev *led_cdev = dev_get_drvdata(dev); 24 25 return sprintf(buf, "%lu\n", led_cdev->blink_delay_on); 26 } 27 28 static ssize_t led_delay_on_store(struct device *dev, 29 struct device_attribute *attr, const char *buf, size_t size) 30 { 31 struct led_classdev *led_cdev = dev_get_drvdata(dev); 32 unsigned long state; 33 ssize_t ret = -EINVAL; 34 35 ret = kstrtoul(buf, 10, &state); 36 if (ret) 37 return ret; 38 39 led_blink_set(led_cdev, &state, &led_cdev->blink_delay_off); 40 led_cdev->blink_delay_on = state; 41 42 return size; 43 } 44 45 static ssize_t led_delay_off_show(struct device *dev, 46 struct device_attribute *attr, char *buf) 47 { 48 struct led_classdev *led_cdev = dev_get_drvdata(dev); 49 50 return sprintf(buf, "%lu\n", led_cdev->blink_delay_off); 51 } 52 53 static ssize_t led_delay_off_store(struct device *dev, 54 struct device_attribute *attr, const char *buf, size_t size) 55 { 56 struct led_classdev *led_cdev = dev_get_drvdata(dev); 57 unsigned long state; 58 ssize_t ret = -EINVAL; 59 60 ret = kstrtoul(buf, 10, &state); 61 if (ret) 62 return ret; 63 64 led_blink_set(led_cdev, &led_cdev->blink_delay_on, &state); 65 led_cdev->blink_delay_off = state; 66 67 return size; 68 } 69 70 static DEVICE_ATTR(delay_on, 0644, led_delay_on_show, led_delay_on_store); 71 static DEVICE_ATTR(delay_off, 0644, led_delay_off_show, led_delay_off_store); 72 73 static int timer_trig_activate(struct led_classdev *led_cdev) 74 { 75 int rc; 76 77 led_cdev->trigger_data = NULL; 78 79 rc = device_create_file(led_cdev->dev, &dev_attr_delay_on); 80 if (rc) 81 return 0; 82 rc = device_create_file(led_cdev->dev, &dev_attr_delay_off); 83 if (rc) 84 goto err_out_delayon; 85 86 led_blink_set(led_cdev, &led_cdev->blink_delay_on, 87 &led_cdev->blink_delay_off); 88 led_cdev->activated = true; 89 90 return 0; 91 92 err_out_delayon: 93 device_remove_file(led_cdev->dev, &dev_attr_delay_on); 94 95 return 0; 96 } 97 98 static void timer_trig_deactivate(struct led_classdev *led_cdev) 99 { 100 if (led_cdev->activated) { 101 device_remove_file(led_cdev->dev, &dev_attr_delay_on); 102 device_remove_file(led_cdev->dev, &dev_attr_delay_off); 103 led_cdev->activated = false; 104 } 105 106 /* Stop blinking */ 107 led_set_brightness(led_cdev, LED_OFF); 108 } 109 110 static struct led_trigger timer_led_trigger = { 111 .name = "timer", 112 .activate = timer_trig_activate, 113 .deactivate = timer_trig_deactivate, 114 }; 115 116 static int __init timer_trig_init(void) 117 { 118 return led_trigger_register(&timer_led_trigger); 119 } 120 121 static void __exit timer_trig_exit(void) 122 { 123 led_trigger_unregister(&timer_led_trigger); 124 } 125 126 module_init(timer_trig_init); 127 module_exit(timer_trig_exit); 128 129 MODULE_AUTHOR("Richard Purdie <rpurdie@openedhand.com>"); 130 MODULE_DESCRIPTION("Timer LED trigger"); 131 MODULE_LICENSE("GPL v2"); 132