Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/leds/ledtrig-backlight.c
15112 views
1
/*
2
* Backlight emulation LED trigger
3
*
4
* Copyright 2008 (C) Rodolfo Giometti <[email protected]>
5
* Copyright 2008 (C) Eurotech S.p.A. <[email protected]>
6
*
7
* This program is free software; you can redistribute it and/or modify
8
* it under the terms of the GNU General Public License version 2 as
9
* published by the Free Software Foundation.
10
*
11
*/
12
13
#include <linux/module.h>
14
#include <linux/kernel.h>
15
#include <linux/slab.h>
16
#include <linux/init.h>
17
#include <linux/fb.h>
18
#include <linux/leds.h>
19
#include "leds.h"
20
21
#define BLANK 1
22
#define UNBLANK 0
23
24
struct bl_trig_notifier {
25
struct led_classdev *led;
26
int brightness;
27
int old_status;
28
struct notifier_block notifier;
29
unsigned invert;
30
};
31
32
static int fb_notifier_callback(struct notifier_block *p,
33
unsigned long event, void *data)
34
{
35
struct bl_trig_notifier *n = container_of(p,
36
struct bl_trig_notifier, notifier);
37
struct led_classdev *led = n->led;
38
struct fb_event *fb_event = data;
39
int *blank = fb_event->data;
40
int new_status = *blank ? BLANK : UNBLANK;
41
42
switch (event) {
43
case FB_EVENT_BLANK :
44
if (new_status == n->old_status)
45
break;
46
47
if ((n->old_status == UNBLANK) ^ n->invert) {
48
n->brightness = led->brightness;
49
led_set_brightness(led, LED_OFF);
50
} else {
51
led_set_brightness(led, n->brightness);
52
}
53
54
n->old_status = new_status;
55
56
break;
57
}
58
59
return 0;
60
}
61
62
static ssize_t bl_trig_invert_show(struct device *dev,
63
struct device_attribute *attr, char *buf)
64
{
65
struct led_classdev *led = dev_get_drvdata(dev);
66
struct bl_trig_notifier *n = led->trigger_data;
67
68
return sprintf(buf, "%u\n", n->invert);
69
}
70
71
static ssize_t bl_trig_invert_store(struct device *dev,
72
struct device_attribute *attr, const char *buf, size_t num)
73
{
74
struct led_classdev *led = dev_get_drvdata(dev);
75
struct bl_trig_notifier *n = led->trigger_data;
76
unsigned long invert;
77
int ret;
78
79
ret = strict_strtoul(buf, 10, &invert);
80
if (ret < 0)
81
return ret;
82
83
if (invert > 1)
84
return -EINVAL;
85
86
n->invert = invert;
87
88
/* After inverting, we need to update the LED. */
89
if ((n->old_status == BLANK) ^ n->invert)
90
led_set_brightness(led, LED_OFF);
91
else
92
led_set_brightness(led, n->brightness);
93
94
return num;
95
}
96
static DEVICE_ATTR(inverted, 0644, bl_trig_invert_show, bl_trig_invert_store);
97
98
static void bl_trig_activate(struct led_classdev *led)
99
{
100
int ret;
101
102
struct bl_trig_notifier *n;
103
104
n = kzalloc(sizeof(struct bl_trig_notifier), GFP_KERNEL);
105
led->trigger_data = n;
106
if (!n) {
107
dev_err(led->dev, "unable to allocate backlight trigger\n");
108
return;
109
}
110
111
ret = device_create_file(led->dev, &dev_attr_inverted);
112
if (ret)
113
goto err_invert;
114
115
n->led = led;
116
n->brightness = led->brightness;
117
n->old_status = UNBLANK;
118
n->notifier.notifier_call = fb_notifier_callback;
119
120
ret = fb_register_client(&n->notifier);
121
if (ret)
122
dev_err(led->dev, "unable to register backlight trigger\n");
123
124
return;
125
126
err_invert:
127
led->trigger_data = NULL;
128
kfree(n);
129
}
130
131
static void bl_trig_deactivate(struct led_classdev *led)
132
{
133
struct bl_trig_notifier *n =
134
(struct bl_trig_notifier *) led->trigger_data;
135
136
if (n) {
137
device_remove_file(led->dev, &dev_attr_inverted);
138
fb_unregister_client(&n->notifier);
139
kfree(n);
140
}
141
}
142
143
static struct led_trigger bl_led_trigger = {
144
.name = "backlight",
145
.activate = bl_trig_activate,
146
.deactivate = bl_trig_deactivate
147
};
148
149
static int __init bl_trig_init(void)
150
{
151
return led_trigger_register(&bl_led_trigger);
152
}
153
154
static void __exit bl_trig_exit(void)
155
{
156
led_trigger_unregister(&bl_led_trigger);
157
}
158
159
module_init(bl_trig_init);
160
module_exit(bl_trig_exit);
161
162
MODULE_AUTHOR("Rodolfo Giometti <[email protected]>");
163
MODULE_DESCRIPTION("Backlight emulation LED trigger");
164
MODULE_LICENSE("GPL v2");
165
166