blob: 7d8237a46f5c46160f5e5f4493daf1f05ec62c23 [file] [log] [blame]
yuezonghe824eb0c2024-06-27 02:32:26 -07001/*
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
14#include <linux/module.h>
15#include <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/device.h>
18#include <linux/ctype.h>
19#include <linux/leds.h>
20#include "leds.h"
21
22static ssize_t led_delay_on_show(struct device *dev,
23 struct device_attribute *attr, char *buf)
24{
25 struct led_classdev *led_cdev = dev_get_drvdata(dev);
26
27 if(NULL==led_cdev)
28 return -EINVAL;
29 return sprintf(buf, "%lu\n", led_cdev->blink_delay_on);
30}
31
32static ssize_t led_delay_on_store(struct device *dev,
33 struct device_attribute *attr, const char *buf, size_t size)
34{
35 struct led_classdev *led_cdev = dev_get_drvdata(dev);
36 int ret = -EINVAL;
37 char *after;
38 unsigned long state = simple_strtoul(buf, &after, 10);
39 size_t count = after - buf;
40
41 if(NULL==led_cdev)
42 return -EINVAL;
43
44 if (isspace(*after))
45 count++;
46
47 if (count == size) {
48 led_blink_set(led_cdev, &state, &led_cdev->blink_delay_off);
49 led_cdev->blink_delay_on = state;
50 ret = count;
51 }
52
53 return ret;
54}
55
56static ssize_t led_delay_off_show(struct device *dev,
57 struct device_attribute *attr, char *buf)
58{
59 struct led_classdev *led_cdev = dev_get_drvdata(dev);
60
61 if(NULL==led_cdev)
62 return -EINVAL;
63
64 return sprintf(buf, "%lu\n", led_cdev->blink_delay_off);
65}
66
67static ssize_t led_delay_off_store(struct device *dev,
68 struct device_attribute *attr, const char *buf, size_t size)
69{
70 struct led_classdev *led_cdev = dev_get_drvdata(dev);
71 int ret = -EINVAL;
72 char *after;
73 unsigned long state = simple_strtoul(buf, &after, 10);
74 size_t count = after - buf;
75
76 if(!led_cdev)
77 return -EINVAL;
78
79 if (isspace(*after))
80 count++;
81
82 if (count == size) {
83 led_blink_set(led_cdev, &led_cdev->blink_delay_on, &state);
84 led_cdev->blink_delay_off = state;
85 ret = count;
86 }
87
88 return ret;
89}
90
91static DEVICE_ATTR(delay_on, 0644, led_delay_on_show, led_delay_on_store);
92static DEVICE_ATTR(delay_off, 0644, led_delay_off_show, led_delay_off_store);
93
94static void timer_trig_activate(struct led_classdev *led_cdev)
95{
96 int rc;
97
98 led_cdev->trigger_data = NULL;
99
100 rc = device_create_file(led_cdev->dev, &dev_attr_delay_on);
101 if (rc)
102 return;
103 rc = device_create_file(led_cdev->dev, &dev_attr_delay_off);
104 if (rc)
105 goto err_out_delayon;
106
107 led_blink_set(led_cdev, &led_cdev->blink_delay_on,
108 &led_cdev->blink_delay_off);
109
110 led_cdev->trigger_data = (void *)1;
111
112 return;
113
114err_out_delayon:
115 device_remove_file(led_cdev->dev, &dev_attr_delay_on);
116}
117
118static void timer_trig_deactivate(struct led_classdev *led_cdev)
119{
120 if (led_cdev->trigger_data) {
121 device_remove_file(led_cdev->dev, &dev_attr_delay_on);
122 device_remove_file(led_cdev->dev, &dev_attr_delay_off);
123 }
124
125 /* Stop blinking */
126 led_brightness_set(led_cdev, LED_OFF);
127}
128
129static struct led_trigger timer_led_trigger = {
130 .name = "timer",
131 .activate = timer_trig_activate,
132 .deactivate = timer_trig_deactivate,
133};
134
135static int __init timer_trig_init(void)
136{
137 return led_trigger_register(&timer_led_trigger);
138}
139
140static void __exit timer_trig_exit(void)
141{
142 led_trigger_unregister(&timer_led_trigger);
143}
144
145module_init(timer_trig_init);
146module_exit(timer_trig_exit);
147
148MODULE_AUTHOR("Richard Purdie <rpurdie@openedhand.com>");
149MODULE_DESCRIPTION("Timer LED trigger");
150MODULE_LICENSE("GPL");