diff options
-rw-r--r-- | drivers/acpi/Kconfig | 1 | ||||
-rw-r--r-- | drivers/acpi/toshiba_acpi.c | 88 |
2 files changed, 66 insertions, 23 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 9b64c4e6c63e..59f9def21720 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig | |||
@@ -227,6 +227,7 @@ config ACPI_IBM_DOCK | |||
227 | config ACPI_TOSHIBA | 227 | config ACPI_TOSHIBA |
228 | tristate "Toshiba Laptop Extras" | 228 | tristate "Toshiba Laptop Extras" |
229 | depends on X86 | 229 | depends on X86 |
230 | select BACKLIGHT_CLASS_DEVICE | ||
230 | ---help--- | 231 | ---help--- |
231 | This driver adds support for access to certain system settings | 232 | This driver adds support for access to certain system settings |
232 | on "legacy free" Toshiba laptops. These laptops can be recognized by | 233 | on "legacy free" Toshiba laptops. These laptops can be recognized by |
diff --git a/drivers/acpi/toshiba_acpi.c b/drivers/acpi/toshiba_acpi.c index 7fe0b7ae9733..2f35f891593f 100644 --- a/drivers/acpi/toshiba_acpi.c +++ b/drivers/acpi/toshiba_acpi.c | |||
@@ -41,6 +41,8 @@ | |||
41 | #include <linux/init.h> | 41 | #include <linux/init.h> |
42 | #include <linux/types.h> | 42 | #include <linux/types.h> |
43 | #include <linux/proc_fs.h> | 43 | #include <linux/proc_fs.h> |
44 | #include <linux/backlight.h> | ||
45 | |||
44 | #include <asm/uaccess.h> | 46 | #include <asm/uaccess.h> |
45 | 47 | ||
46 | #include <acpi/acpi_drivers.h> | 48 | #include <acpi/acpi_drivers.h> |
@@ -210,6 +212,7 @@ static acpi_status hci_read1(u32 reg, u32 * out1, u32 * result) | |||
210 | } | 212 | } |
211 | 213 | ||
212 | static struct proc_dir_entry *toshiba_proc_dir /*= 0*/ ; | 214 | static struct proc_dir_entry *toshiba_proc_dir /*= 0*/ ; |
215 | static struct backlight_device *toshiba_backlight_device; | ||
213 | static int force_fan; | 216 | static int force_fan; |
214 | static int last_key_event; | 217 | static int last_key_event; |
215 | static int key_event_valid; | 218 | static int key_event_valid; |
@@ -271,14 +274,23 @@ dispatch_write(struct file *file, const char __user * buffer, | |||
271 | return result; | 274 | return result; |
272 | } | 275 | } |
273 | 276 | ||
274 | static char *read_lcd(char *p) | 277 | static int get_lcd(struct backlight_device *bd) |
275 | { | 278 | { |
276 | u32 hci_result; | 279 | u32 hci_result; |
277 | u32 value; | 280 | u32 value; |
278 | 281 | ||
279 | hci_read1(HCI_LCD_BRIGHTNESS, &value, &hci_result); | 282 | hci_read1(HCI_LCD_BRIGHTNESS, &value, &hci_result); |
280 | if (hci_result == HCI_SUCCESS) { | 283 | if (hci_result == HCI_SUCCESS) { |
281 | value = value >> HCI_LCD_BRIGHTNESS_SHIFT; | 284 | return (value >> HCI_LCD_BRIGHTNESS_SHIFT); |
285 | } else | ||
286 | return -EFAULT; | ||
287 | } | ||
288 | |||
289 | static char *read_lcd(char *p) | ||
290 | { | ||
291 | int value = get_lcd(NULL); | ||
292 | |||
293 | if (value >= 0) { | ||
282 | p += sprintf(p, "brightness: %d\n", value); | 294 | p += sprintf(p, "brightness: %d\n", value); |
283 | p += sprintf(p, "brightness_levels: %d\n", | 295 | p += sprintf(p, "brightness_levels: %d\n", |
284 | HCI_LCD_BRIGHTNESS_LEVELS); | 296 | HCI_LCD_BRIGHTNESS_LEVELS); |
@@ -289,22 +301,34 @@ static char *read_lcd(char *p) | |||
289 | return p; | 301 | return p; |
290 | } | 302 | } |
291 | 303 | ||
304 | static int set_lcd(int value) | ||
305 | { | ||
306 | u32 hci_result; | ||
307 | |||
308 | value = value << HCI_LCD_BRIGHTNESS_SHIFT; | ||
309 | hci_write1(HCI_LCD_BRIGHTNESS, value, &hci_result); | ||
310 | if (hci_result != HCI_SUCCESS) | ||
311 | return -EFAULT; | ||
312 | |||
313 | return 0; | ||
314 | } | ||
315 | |||
316 | static int set_lcd_status(struct backlight_device *bd) | ||
317 | { | ||
318 | return set_lcd(bd->props->brightness); | ||
319 | } | ||
320 | |||
292 | static unsigned long write_lcd(const char *buffer, unsigned long count) | 321 | static unsigned long write_lcd(const char *buffer, unsigned long count) |
293 | { | 322 | { |
294 | int value; | 323 | int value; |
295 | u32 hci_result; | 324 | int ret = count; |
296 | 325 | ||
297 | if (sscanf(buffer, " brightness : %i", &value) == 1 && | 326 | if (sscanf(buffer, " brightness : %i", &value) == 1 && |
298 | value >= 0 && value < HCI_LCD_BRIGHTNESS_LEVELS) { | 327 | value >= 0 && value < HCI_LCD_BRIGHTNESS_LEVELS) |
299 | value = value << HCI_LCD_BRIGHTNESS_SHIFT; | 328 | ret = set_lcd(value); |
300 | hci_write1(HCI_LCD_BRIGHTNESS, value, &hci_result); | 329 | else |
301 | if (hci_result != HCI_SUCCESS) | 330 | ret = -EINVAL; |
302 | return -EFAULT; | 331 | return ret; |
303 | } else { | ||
304 | return -EINVAL; | ||
305 | } | ||
306 | |||
307 | return count; | ||
308 | } | 332 | } |
309 | 333 | ||
310 | static char *read_video(char *p) | 334 | static char *read_video(char *p) |
@@ -506,6 +530,26 @@ static acpi_status __exit remove_device(void) | |||
506 | return AE_OK; | 530 | return AE_OK; |
507 | } | 531 | } |
508 | 532 | ||
533 | static struct backlight_properties toshiba_backlight_data = { | ||
534 | .owner = THIS_MODULE, | ||
535 | .get_brightness = get_lcd, | ||
536 | .update_status = set_lcd_status, | ||
537 | .max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1, | ||
538 | }; | ||
539 | |||
540 | static void __exit toshiba_acpi_exit(void) | ||
541 | { | ||
542 | if (toshiba_backlight_device) | ||
543 | backlight_device_unregister(toshiba_backlight_device); | ||
544 | |||
545 | remove_device(); | ||
546 | |||
547 | if (toshiba_proc_dir) | ||
548 | remove_proc_entry(PROC_TOSHIBA, acpi_root_dir); | ||
549 | |||
550 | return; | ||
551 | } | ||
552 | |||
509 | static int __init toshiba_acpi_init(void) | 553 | static int __init toshiba_acpi_init(void) |
510 | { | 554 | { |
511 | acpi_status status = AE_OK; | 555 | acpi_status status = AE_OK; |
@@ -546,17 +590,15 @@ static int __init toshiba_acpi_init(void) | |||
546 | remove_proc_entry(PROC_TOSHIBA, acpi_root_dir); | 590 | remove_proc_entry(PROC_TOSHIBA, acpi_root_dir); |
547 | } | 591 | } |
548 | 592 | ||
549 | return (ACPI_SUCCESS(status)) ? 0 : -ENODEV; | 593 | toshiba_backlight_device = backlight_device_register("toshiba", NULL, |
550 | } | 594 | &toshiba_backlight_data); |
551 | 595 | if (IS_ERR(toshiba_backlight_device)) { | |
552 | static void __exit toshiba_acpi_exit(void) | 596 | printk(KERN_ERR "Could not register toshiba backlight device\n"); |
553 | { | 597 | toshiba_backlight_device = NULL; |
554 | remove_device(); | 598 | toshiba_acpi_exit(); |
555 | 599 | } | |
556 | if (toshiba_proc_dir) | ||
557 | remove_proc_entry(PROC_TOSHIBA, acpi_root_dir); | ||
558 | 600 | ||
559 | return; | 601 | return (ACPI_SUCCESS(status)) ? 0 : -ENODEV; |
560 | } | 602 | } |
561 | 603 | ||
562 | module_init(toshiba_acpi_init); | 604 | module_init(toshiba_acpi_init); |