diff options
author | Eric Piel <eric.piel@tremplin-utc.net> | 2009-01-15 16:51:23 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-01-15 19:39:40 -0500 |
commit | 9e0c79782143a816ba7d7f0f6e195091a97053f6 (patch) | |
tree | 109a347061a1e2d1e08aa3908b893e2ee55f9732 /drivers/hwmon/hp_accel.c | |
parent | 5b019e99016f3a692ba45bf68fba73a402d7c01a (diff) |
lis3lv02d: merge with leds hp disk
Move the second part of the HP laptop disk protection functionality (a red
led) to the same driver. From a purely Linux developer's point of view,
the led and the accelerometer have nothing related. However, they
correspond to the same ACPI functionality, and so will always be used
together, moreover as they share the same ACPI PNP alias, there is no
other simple to allow to have same loaded at the same time if they are not
in the same module. Also make it requires the led class to compile and
update the Kconfig text.
Signed-off-by: Pavel Machek <pavel@suse.cz>
Signed-off-by: Eric Piel <eric.piel@tremplin-utc.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/hwmon/hp_accel.c')
-rw-r--r-- | drivers/hwmon/hp_accel.c | 43 |
1 files changed, 41 insertions, 2 deletions
diff --git a/drivers/hwmon/hp_accel.c b/drivers/hwmon/hp_accel.c index bf8d40580577..86a0f51d99d6 100644 --- a/drivers/hwmon/hp_accel.c +++ b/drivers/hwmon/hp_accel.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/freezer.h> | 36 | #include <linux/freezer.h> |
37 | #include <linux/version.h> | 37 | #include <linux/version.h> |
38 | #include <linux/uaccess.h> | 38 | #include <linux/uaccess.h> |
39 | #include <linux/leds.h> | ||
39 | #include <acpi/acpi_drivers.h> | 40 | #include <acpi/acpi_drivers.h> |
40 | #include <asm/atomic.h> | 41 | #include <asm/atomic.h> |
41 | #include "lis3lv02d.h" | 42 | #include "lis3lv02d.h" |
@@ -154,10 +155,34 @@ static struct dmi_system_id lis3lv02d_dmi_ids[] = { | |||
154 | */ | 155 | */ |
155 | }; | 156 | }; |
156 | 157 | ||
158 | static acpi_status hpled_acpi_write(acpi_handle handle, int reg) | ||
159 | { | ||
160 | unsigned long long ret; /* Not used when writing */ | ||
161 | union acpi_object in_obj[1]; | ||
162 | struct acpi_object_list args = { 1, in_obj }; | ||
163 | |||
164 | in_obj[0].type = ACPI_TYPE_INTEGER; | ||
165 | in_obj[0].integer.value = reg; | ||
166 | |||
167 | return acpi_evaluate_integer(handle, "ALED", &args, &ret); | ||
168 | } | ||
169 | |||
170 | static void hpled_set(struct led_classdev *led_cdev, | ||
171 | enum led_brightness value) | ||
172 | { | ||
173 | hpled_acpi_write(adev.device->handle, !!value); | ||
174 | } | ||
175 | |||
176 | static struct led_classdev hpled_led = { | ||
177 | .name = "hp:red:hddprotection", | ||
178 | .default_trigger = "none", | ||
179 | .brightness_set = hpled_set, | ||
180 | }; | ||
157 | 181 | ||
158 | static int lis3lv02d_add(struct acpi_device *device) | 182 | static int lis3lv02d_add(struct acpi_device *device) |
159 | { | 183 | { |
160 | u8 val; | 184 | u8 val; |
185 | int ret; | ||
161 | 186 | ||
162 | if (!device) | 187 | if (!device) |
163 | return -EINVAL; | 188 | return -EINVAL; |
@@ -183,7 +208,17 @@ static int lis3lv02d_add(struct acpi_device *device) | |||
183 | adev.ac = lis3lv02d_axis_normal; | 208 | adev.ac = lis3lv02d_axis_normal; |
184 | } | 209 | } |
185 | 210 | ||
186 | return lis3lv02d_init_device(&adev); | 211 | ret = led_classdev_register(NULL, &hpled_led); |
212 | if (ret) | ||
213 | return ret; | ||
214 | |||
215 | ret = lis3lv02d_init_device(&adev); | ||
216 | if (ret) { | ||
217 | led_classdev_unregister(&hpled_led); | ||
218 | return ret; | ||
219 | } | ||
220 | |||
221 | return ret; | ||
187 | } | 222 | } |
188 | 223 | ||
189 | static int lis3lv02d_remove(struct acpi_device *device, int type) | 224 | static int lis3lv02d_remove(struct acpi_device *device, int type) |
@@ -194,6 +229,8 @@ static int lis3lv02d_remove(struct acpi_device *device, int type) | |||
194 | lis3lv02d_joystick_disable(); | 229 | lis3lv02d_joystick_disable(); |
195 | lis3lv02d_poweroff(device->handle); | 230 | lis3lv02d_poweroff(device->handle); |
196 | 231 | ||
232 | led_classdev_unregister(&hpled_led); | ||
233 | |||
197 | return lis3lv02d_remove_fs(); | 234 | return lis3lv02d_remove_fs(); |
198 | } | 235 | } |
199 | 236 | ||
@@ -203,6 +240,7 @@ static int lis3lv02d_suspend(struct acpi_device *device, pm_message_t state) | |||
203 | { | 240 | { |
204 | /* make sure the device is off when we suspend */ | 241 | /* make sure the device is off when we suspend */ |
205 | lis3lv02d_poweroff(device->handle); | 242 | lis3lv02d_poweroff(device->handle); |
243 | led_classdev_suspend(&hpled_led); | ||
206 | return 0; | 244 | return 0; |
207 | } | 245 | } |
208 | 246 | ||
@@ -215,6 +253,7 @@ static int lis3lv02d_resume(struct acpi_device *device) | |||
215 | else | 253 | else |
216 | lis3lv02d_poweroff(device->handle); | 254 | lis3lv02d_poweroff(device->handle); |
217 | mutex_unlock(&adev.lock); | 255 | mutex_unlock(&adev.lock); |
256 | led_classdev_resume(&hpled_led); | ||
218 | return 0; | 257 | return 0; |
219 | } | 258 | } |
220 | #else | 259 | #else |
@@ -256,7 +295,7 @@ static void __exit lis3lv02d_exit_module(void) | |||
256 | acpi_bus_unregister_driver(&lis3lv02d_driver); | 295 | acpi_bus_unregister_driver(&lis3lv02d_driver); |
257 | } | 296 | } |
258 | 297 | ||
259 | MODULE_DESCRIPTION("Glue between LIS3LV02Dx and HP ACPI BIOS"); | 298 | MODULE_DESCRIPTION("Glue between LIS3LV02Dx and HP ACPI BIOS and support for disk protection LED."); |
260 | MODULE_AUTHOR("Yan Burman, Eric Piel, Pavel Machek"); | 299 | MODULE_AUTHOR("Yan Burman, Eric Piel, Pavel Machek"); |
261 | MODULE_LICENSE("GPL"); | 300 | MODULE_LICENSE("GPL"); |
262 | 301 | ||