aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform/x86/toshiba_acpi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/platform/x86/toshiba_acpi.c')
-rw-r--r--drivers/platform/x86/toshiba_acpi.c475
1 files changed, 352 insertions, 123 deletions
diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c
index 51c0a8bee414..37aa14798551 100644
--- a/drivers/platform/x86/toshiba_acpi.c
+++ b/drivers/platform/x86/toshiba_acpi.c
@@ -42,9 +42,12 @@
42#include <linux/init.h> 42#include <linux/init.h>
43#include <linux/types.h> 43#include <linux/types.h>
44#include <linux/proc_fs.h> 44#include <linux/proc_fs.h>
45#include <linux/seq_file.h>
45#include <linux/backlight.h> 46#include <linux/backlight.h>
46#include <linux/platform_device.h> 47#include <linux/platform_device.h>
47#include <linux/rfkill.h> 48#include <linux/rfkill.h>
49#include <linux/input.h>
50#include <linux/slab.h>
48 51
49#include <asm/uaccess.h> 52#include <asm/uaccess.h>
50 53
@@ -61,9 +64,10 @@ MODULE_LICENSE("GPL");
61 64
62/* Toshiba ACPI method paths */ 65/* Toshiba ACPI method paths */
63#define METHOD_LCD_BRIGHTNESS "\\_SB_.PCI0.VGA_.LCD_._BCM" 66#define METHOD_LCD_BRIGHTNESS "\\_SB_.PCI0.VGA_.LCD_._BCM"
64#define METHOD_HCI_1 "\\_SB_.VALD.GHCI" 67#define TOSH_INTERFACE_1 "\\_SB_.VALD"
65#define METHOD_HCI_2 "\\_SB_.VALZ.GHCI" 68#define TOSH_INTERFACE_2 "\\_SB_.VALZ"
66#define METHOD_VIDEO_OUT "\\_SB_.VALX.DSSX" 69#define METHOD_VIDEO_OUT "\\_SB_.VALX.DSSX"
70#define GHCI_METHOD ".GHCI"
67 71
68/* Toshiba HCI interface definitions 72/* Toshiba HCI interface definitions
69 * 73 *
@@ -115,6 +119,36 @@ static const struct acpi_device_id toshiba_device_ids[] = {
115}; 119};
116MODULE_DEVICE_TABLE(acpi, toshiba_device_ids); 120MODULE_DEVICE_TABLE(acpi, toshiba_device_ids);
117 121
122struct key_entry {
123 char type;
124 u16 code;
125 u16 keycode;
126};
127
128enum {KE_KEY, KE_END};
129
130static struct key_entry toshiba_acpi_keymap[] = {
131 {KE_KEY, 0x101, KEY_MUTE},
132 {KE_KEY, 0x13b, KEY_COFFEE},
133 {KE_KEY, 0x13c, KEY_BATTERY},
134 {KE_KEY, 0x13d, KEY_SLEEP},
135 {KE_KEY, 0x13e, KEY_SUSPEND},
136 {KE_KEY, 0x13f, KEY_SWITCHVIDEOMODE},
137 {KE_KEY, 0x140, KEY_BRIGHTNESSDOWN},
138 {KE_KEY, 0x141, KEY_BRIGHTNESSUP},
139 {KE_KEY, 0x142, KEY_WLAN},
140 {KE_KEY, 0x143, KEY_PROG1},
141 {KE_KEY, 0xb05, KEY_PROG2},
142 {KE_KEY, 0xb06, KEY_WWW},
143 {KE_KEY, 0xb07, KEY_MAIL},
144 {KE_KEY, 0xb30, KEY_STOP},
145 {KE_KEY, 0xb31, KEY_PREVIOUSSONG},
146 {KE_KEY, 0xb32, KEY_NEXTSONG},
147 {KE_KEY, 0xb33, KEY_PLAYPAUSE},
148 {KE_KEY, 0xb5a, KEY_MEDIA},
149 {KE_END, 0, 0},
150};
151
118/* utility 152/* utility
119 */ 153 */
120 154
@@ -250,6 +284,8 @@ static acpi_status hci_read2(u32 reg, u32 *out1, u32 *out2, u32 *result)
250struct toshiba_acpi_dev { 284struct toshiba_acpi_dev {
251 struct platform_device *p_dev; 285 struct platform_device *p_dev;
252 struct rfkill *bt_rfk; 286 struct rfkill *bt_rfk;
287 struct input_dev *hotkey_dev;
288 acpi_handle handle;
253 289
254 const char *bt_name; 290 const char *bt_name;
255 291
@@ -357,63 +393,6 @@ static int force_fan;
357static int last_key_event; 393static int last_key_event;
358static int key_event_valid; 394static int key_event_valid;
359 395
360typedef struct _ProcItem {
361 const char *name;
362 char *(*read_func) (char *);
363 unsigned long (*write_func) (const char *, unsigned long);
364} ProcItem;
365
366/* proc file handlers
367 */
368
369static int
370dispatch_read(char *page, char **start, off_t off, int count, int *eof,
371 ProcItem * item)
372{
373 char *p = page;
374 int len;
375
376 if (off == 0)
377 p = item->read_func(p);
378
379 /* ISSUE: I don't understand this code */
380 len = (p - page);
381 if (len <= off + count)
382 *eof = 1;
383 *start = page + off;
384 len -= off;
385 if (len > count)
386 len = count;
387 if (len < 0)
388 len = 0;
389 return len;
390}
391
392static int
393dispatch_write(struct file *file, const char __user * buffer,
394 unsigned long count, ProcItem * item)
395{
396 int result;
397 char *tmp_buffer;
398
399 /* Arg buffer points to userspace memory, which can't be accessed
400 * directly. Since we're making a copy, zero-terminate the
401 * destination so that sscanf can be used on it safely.
402 */
403 tmp_buffer = kmalloc(count + 1, GFP_KERNEL);
404 if (!tmp_buffer)
405 return -ENOMEM;
406
407 if (copy_from_user(tmp_buffer, buffer, count)) {
408 result = -EFAULT;
409 } else {
410 tmp_buffer[count] = 0;
411 result = item->write_func(tmp_buffer, count);
412 }
413 kfree(tmp_buffer);
414 return result;
415}
416
417static int get_lcd(struct backlight_device *bd) 396static int get_lcd(struct backlight_device *bd)
418{ 397{
419 u32 hci_result; 398 u32 hci_result;
@@ -426,19 +405,24 @@ static int get_lcd(struct backlight_device *bd)
426 return -EFAULT; 405 return -EFAULT;
427} 406}
428 407
429static char *read_lcd(char *p) 408static int lcd_proc_show(struct seq_file *m, void *v)
430{ 409{
431 int value = get_lcd(NULL); 410 int value = get_lcd(NULL);
432 411
433 if (value >= 0) { 412 if (value >= 0) {
434 p += sprintf(p, "brightness: %d\n", value); 413 seq_printf(m, "brightness: %d\n", value);
435 p += sprintf(p, "brightness_levels: %d\n", 414 seq_printf(m, "brightness_levels: %d\n",
436 HCI_LCD_BRIGHTNESS_LEVELS); 415 HCI_LCD_BRIGHTNESS_LEVELS);
437 } else { 416 } else {
438 printk(MY_ERR "Error reading LCD brightness\n"); 417 printk(MY_ERR "Error reading LCD brightness\n");
439 } 418 }
440 419
441 return p; 420 return 0;
421}
422
423static int lcd_proc_open(struct inode *inode, struct file *file)
424{
425 return single_open(file, lcd_proc_show, NULL);
442} 426}
443 427
444static int set_lcd(int value) 428static int set_lcd(int value)
@@ -458,12 +442,20 @@ static int set_lcd_status(struct backlight_device *bd)
458 return set_lcd(bd->props.brightness); 442 return set_lcd(bd->props.brightness);
459} 443}
460 444
461static unsigned long write_lcd(const char *buffer, unsigned long count) 445static ssize_t lcd_proc_write(struct file *file, const char __user *buf,
446 size_t count, loff_t *pos)
462{ 447{
448 char cmd[42];
449 size_t len;
463 int value; 450 int value;
464 int ret; 451 int ret;
465 452
466 if (sscanf(buffer, " brightness : %i", &value) == 1 && 453 len = min(count, sizeof(cmd) - 1);
454 if (copy_from_user(cmd, buf, len))
455 return -EFAULT;
456 cmd[len] = '\0';
457
458 if (sscanf(cmd, " brightness : %i", &value) == 1 &&
467 value >= 0 && value < HCI_LCD_BRIGHTNESS_LEVELS) { 459 value >= 0 && value < HCI_LCD_BRIGHTNESS_LEVELS) {
468 ret = set_lcd(value); 460 ret = set_lcd(value);
469 if (ret == 0) 461 if (ret == 0)
@@ -474,7 +466,16 @@ static unsigned long write_lcd(const char *buffer, unsigned long count)
474 return ret; 466 return ret;
475} 467}
476 468
477static char *read_video(char *p) 469static const struct file_operations lcd_proc_fops = {
470 .owner = THIS_MODULE,
471 .open = lcd_proc_open,
472 .read = seq_read,
473 .llseek = seq_lseek,
474 .release = single_release,
475 .write = lcd_proc_write,
476};
477
478static int video_proc_show(struct seq_file *m, void *v)
478{ 479{
479 u32 hci_result; 480 u32 hci_result;
480 u32 value; 481 u32 value;
@@ -484,18 +485,25 @@ static char *read_video(char *p)
484 int is_lcd = (value & HCI_VIDEO_OUT_LCD) ? 1 : 0; 485 int is_lcd = (value & HCI_VIDEO_OUT_LCD) ? 1 : 0;
485 int is_crt = (value & HCI_VIDEO_OUT_CRT) ? 1 : 0; 486 int is_crt = (value & HCI_VIDEO_OUT_CRT) ? 1 : 0;
486 int is_tv = (value & HCI_VIDEO_OUT_TV) ? 1 : 0; 487 int is_tv = (value & HCI_VIDEO_OUT_TV) ? 1 : 0;
487 p += sprintf(p, "lcd_out: %d\n", is_lcd); 488 seq_printf(m, "lcd_out: %d\n", is_lcd);
488 p += sprintf(p, "crt_out: %d\n", is_crt); 489 seq_printf(m, "crt_out: %d\n", is_crt);
489 p += sprintf(p, "tv_out: %d\n", is_tv); 490 seq_printf(m, "tv_out: %d\n", is_tv);
490 } else { 491 } else {
491 printk(MY_ERR "Error reading video out status\n"); 492 printk(MY_ERR "Error reading video out status\n");
492 } 493 }
493 494
494 return p; 495 return 0;
495} 496}
496 497
497static unsigned long write_video(const char *buffer, unsigned long count) 498static int video_proc_open(struct inode *inode, struct file *file)
498{ 499{
500 return single_open(file, video_proc_show, NULL);
501}
502
503static ssize_t video_proc_write(struct file *file, const char __user *buf,
504 size_t count, loff_t *pos)
505{
506 char *cmd, *buffer;
499 int value; 507 int value;
500 int remain = count; 508 int remain = count;
501 int lcd_out = -1; 509 int lcd_out = -1;
@@ -504,6 +512,17 @@ static unsigned long write_video(const char *buffer, unsigned long count)
504 u32 hci_result; 512 u32 hci_result;
505 u32 video_out; 513 u32 video_out;
506 514
515 cmd = kmalloc(count + 1, GFP_KERNEL);
516 if (!cmd)
517 return -ENOMEM;
518 if (copy_from_user(cmd, buf, count)) {
519 kfree(cmd);
520 return -EFAULT;
521 }
522 cmd[count] = '\0';
523
524 buffer = cmd;
525
507 /* scan expression. Multiple expressions may be delimited with ; 526 /* scan expression. Multiple expressions may be delimited with ;
508 * 527 *
509 * NOTE: to keep scanning simple, invalid fields are ignored 528 * NOTE: to keep scanning simple, invalid fields are ignored
@@ -523,6 +542,8 @@ static unsigned long write_video(const char *buffer, unsigned long count)
523 while (remain && *(buffer - 1) != ';'); 542 while (remain && *(buffer - 1) != ';');
524 } 543 }
525 544
545 kfree(cmd);
546
526 hci_read1(HCI_VIDEO_OUT, &video_out, &hci_result); 547 hci_read1(HCI_VIDEO_OUT, &video_out, &hci_result);
527 if (hci_result == HCI_SUCCESS) { 548 if (hci_result == HCI_SUCCESS) {
528 unsigned int new_video_out = video_out; 549 unsigned int new_video_out = video_out;
@@ -543,28 +564,50 @@ static unsigned long write_video(const char *buffer, unsigned long count)
543 return count; 564 return count;
544} 565}
545 566
546static char *read_fan(char *p) 567static const struct file_operations video_proc_fops = {
568 .owner = THIS_MODULE,
569 .open = video_proc_open,
570 .read = seq_read,
571 .llseek = seq_lseek,
572 .release = single_release,
573 .write = video_proc_write,
574};
575
576static int fan_proc_show(struct seq_file *m, void *v)
547{ 577{
548 u32 hci_result; 578 u32 hci_result;
549 u32 value; 579 u32 value;
550 580
551 hci_read1(HCI_FAN, &value, &hci_result); 581 hci_read1(HCI_FAN, &value, &hci_result);
552 if (hci_result == HCI_SUCCESS) { 582 if (hci_result == HCI_SUCCESS) {
553 p += sprintf(p, "running: %d\n", (value > 0)); 583 seq_printf(m, "running: %d\n", (value > 0));
554 p += sprintf(p, "force_on: %d\n", force_fan); 584 seq_printf(m, "force_on: %d\n", force_fan);
555 } else { 585 } else {
556 printk(MY_ERR "Error reading fan status\n"); 586 printk(MY_ERR "Error reading fan status\n");
557 } 587 }
558 588
559 return p; 589 return 0;
590}
591
592static int fan_proc_open(struct inode *inode, struct file *file)
593{
594 return single_open(file, fan_proc_show, NULL);
560} 595}
561 596
562static unsigned long write_fan(const char *buffer, unsigned long count) 597static ssize_t fan_proc_write(struct file *file, const char __user *buf,
598 size_t count, loff_t *pos)
563{ 599{
600 char cmd[42];
601 size_t len;
564 int value; 602 int value;
565 u32 hci_result; 603 u32 hci_result;
566 604
567 if (sscanf(buffer, " force_on : %i", &value) == 1 && 605 len = min(count, sizeof(cmd) - 1);
606 if (copy_from_user(cmd, buf, len))
607 return -EFAULT;
608 cmd[len] = '\0';
609
610 if (sscanf(cmd, " force_on : %i", &value) == 1 &&
568 value >= 0 && value <= 1) { 611 value >= 0 && value <= 1) {
569 hci_write1(HCI_FAN, value, &hci_result); 612 hci_write1(HCI_FAN, value, &hci_result);
570 if (hci_result != HCI_SUCCESS) 613 if (hci_result != HCI_SUCCESS)
@@ -578,7 +621,16 @@ static unsigned long write_fan(const char *buffer, unsigned long count)
578 return count; 621 return count;
579} 622}
580 623
581static char *read_keys(char *p) 624static const struct file_operations fan_proc_fops = {
625 .owner = THIS_MODULE,
626 .open = fan_proc_open,
627 .read = seq_read,
628 .llseek = seq_lseek,
629 .release = single_release,
630 .write = fan_proc_write,
631};
632
633static int keys_proc_show(struct seq_file *m, void *v)
582{ 634{
583 u32 hci_result; 635 u32 hci_result;
584 u32 value; 636 u32 value;
@@ -602,18 +654,30 @@ static char *read_keys(char *p)
602 } 654 }
603 } 655 }
604 656
605 p += sprintf(p, "hotkey_ready: %d\n", key_event_valid); 657 seq_printf(m, "hotkey_ready: %d\n", key_event_valid);
606 p += sprintf(p, "hotkey: 0x%04x\n", last_key_event); 658 seq_printf(m, "hotkey: 0x%04x\n", last_key_event);
659end:
660 return 0;
661}
607 662
608 end: 663static int keys_proc_open(struct inode *inode, struct file *file)
609 return p; 664{
665 return single_open(file, keys_proc_show, NULL);
610} 666}
611 667
612static unsigned long write_keys(const char *buffer, unsigned long count) 668static ssize_t keys_proc_write(struct file *file, const char __user *buf,
669 size_t count, loff_t *pos)
613{ 670{
671 char cmd[42];
672 size_t len;
614 int value; 673 int value;
615 674
616 if (sscanf(buffer, " hotkey_ready : %i", &value) == 1 && value == 0) { 675 len = min(count, sizeof(cmd) - 1);
676 if (copy_from_user(cmd, buf, len))
677 return -EFAULT;
678 cmd[len] = '\0';
679
680 if (sscanf(cmd, " hotkey_ready : %i", &value) == 1 && value == 0) {
617 key_event_valid = 0; 681 key_event_valid = 0;
618 } else { 682 } else {
619 return -EINVAL; 683 return -EINVAL;
@@ -622,52 +686,58 @@ static unsigned long write_keys(const char *buffer, unsigned long count)
622 return count; 686 return count;
623} 687}
624 688
625static char *read_version(char *p) 689static const struct file_operations keys_proc_fops = {
690 .owner = THIS_MODULE,
691 .open = keys_proc_open,
692 .read = seq_read,
693 .llseek = seq_lseek,
694 .release = single_release,
695 .write = keys_proc_write,
696};
697
698static int version_proc_show(struct seq_file *m, void *v)
699{
700 seq_printf(m, "driver: %s\n", TOSHIBA_ACPI_VERSION);
701 seq_printf(m, "proc_interface: %d\n", PROC_INTERFACE_VERSION);
702 return 0;
703}
704
705static int version_proc_open(struct inode *inode, struct file *file)
626{ 706{
627 p += sprintf(p, "driver: %s\n", TOSHIBA_ACPI_VERSION); 707 return single_open(file, version_proc_show, PDE(inode)->data);
628 p += sprintf(p, "proc_interface: %d\n",
629 PROC_INTERFACE_VERSION);
630 return p;
631} 708}
632 709
710static const struct file_operations version_proc_fops = {
711 .owner = THIS_MODULE,
712 .open = version_proc_open,
713 .read = seq_read,
714 .llseek = seq_lseek,
715 .release = single_release,
716};
717
633/* proc and module init 718/* proc and module init
634 */ 719 */
635 720
636#define PROC_TOSHIBA "toshiba" 721#define PROC_TOSHIBA "toshiba"
637 722
638static ProcItem proc_items[] = {
639 {"lcd", read_lcd, write_lcd},
640 {"video", read_video, write_video},
641 {"fan", read_fan, write_fan},
642 {"keys", read_keys, write_keys},
643 {"version", read_version, NULL},
644 {NULL}
645};
646
647static acpi_status __init add_device(void) 723static acpi_status __init add_device(void)
648{ 724{
649 struct proc_dir_entry *proc; 725 proc_create("lcd", S_IRUGO | S_IWUSR, toshiba_proc_dir, &lcd_proc_fops);
650 ProcItem *item; 726 proc_create("video", S_IRUGO | S_IWUSR, toshiba_proc_dir, &video_proc_fops);
651 727 proc_create("fan", S_IRUGO | S_IWUSR, toshiba_proc_dir, &fan_proc_fops);
652 for (item = proc_items; item->name; ++item) { 728 proc_create("keys", S_IRUGO | S_IWUSR, toshiba_proc_dir, &keys_proc_fops);
653 proc = create_proc_read_entry(item->name, 729 proc_create("version", S_IRUGO, toshiba_proc_dir, &version_proc_fops);
654 S_IFREG | S_IRUGO | S_IWUSR,
655 toshiba_proc_dir,
656 (read_proc_t *) dispatch_read,
657 item);
658 if (proc && item->write_func)
659 proc->write_proc = (write_proc_t *) dispatch_write;
660 }
661 730
662 return AE_OK; 731 return AE_OK;
663} 732}
664 733
665static acpi_status remove_device(void) 734static acpi_status remove_device(void)
666{ 735{
667 ProcItem *item; 736 remove_proc_entry("lcd", toshiba_proc_dir);
668 737 remove_proc_entry("video", toshiba_proc_dir);
669 for (item = proc_items; item->name; ++item) 738 remove_proc_entry("fan", toshiba_proc_dir);
670 remove_proc_entry(item->name, toshiba_proc_dir); 739 remove_proc_entry("keys", toshiba_proc_dir);
740 remove_proc_entry("version", toshiba_proc_dir);
671 return AE_OK; 741 return AE_OK;
672} 742}
673 743
@@ -676,8 +746,158 @@ static struct backlight_ops toshiba_backlight_data = {
676 .update_status = set_lcd_status, 746 .update_status = set_lcd_status,
677}; 747};
678 748
749static struct key_entry *toshiba_acpi_get_entry_by_scancode(unsigned int code)
750{
751 struct key_entry *key;
752
753 for (key = toshiba_acpi_keymap; key->type != KE_END; key++)
754 if (code == key->code)
755 return key;
756
757 return NULL;
758}
759
760static struct key_entry *toshiba_acpi_get_entry_by_keycode(unsigned int code)
761{
762 struct key_entry *key;
763
764 for (key = toshiba_acpi_keymap; key->type != KE_END; key++)
765 if (code == key->keycode && key->type == KE_KEY)
766 return key;
767
768 return NULL;
769}
770
771static int toshiba_acpi_getkeycode(struct input_dev *dev,
772 unsigned int scancode, unsigned int *keycode)
773{
774 struct key_entry *key = toshiba_acpi_get_entry_by_scancode(scancode);
775
776 if (key && key->type == KE_KEY) {
777 *keycode = key->keycode;
778 return 0;
779 }
780
781 return -EINVAL;
782}
783
784static int toshiba_acpi_setkeycode(struct input_dev *dev,
785 unsigned int scancode, unsigned int keycode)
786{
787 struct key_entry *key;
788 unsigned int old_keycode;
789
790 key = toshiba_acpi_get_entry_by_scancode(scancode);
791 if (key && key->type == KE_KEY) {
792 old_keycode = key->keycode;
793 key->keycode = keycode;
794 set_bit(keycode, dev->keybit);
795 if (!toshiba_acpi_get_entry_by_keycode(old_keycode))
796 clear_bit(old_keycode, dev->keybit);
797 return 0;
798 }
799
800 return -EINVAL;
801}
802
803static void toshiba_acpi_notify(acpi_handle handle, u32 event, void *context)
804{
805 u32 hci_result, value;
806 struct key_entry *key;
807
808 if (event != 0x80)
809 return;
810 do {
811 hci_read1(HCI_SYSTEM_EVENT, &value, &hci_result);
812 if (hci_result == HCI_SUCCESS) {
813 if (value == 0x100)
814 continue;
815 /* act on key press; ignore key release */
816 if (value & 0x80)
817 continue;
818
819 key = toshiba_acpi_get_entry_by_scancode
820 (value);
821 if (!key) {
822 printk(MY_INFO "Unknown key %x\n",
823 value);
824 continue;
825 }
826 input_report_key(toshiba_acpi.hotkey_dev,
827 key->keycode, 1);
828 input_sync(toshiba_acpi.hotkey_dev);
829 input_report_key(toshiba_acpi.hotkey_dev,
830 key->keycode, 0);
831 input_sync(toshiba_acpi.hotkey_dev);
832 } else if (hci_result == HCI_NOT_SUPPORTED) {
833 /* This is a workaround for an unresolved issue on
834 * some machines where system events sporadically
835 * become disabled. */
836 hci_write1(HCI_SYSTEM_EVENT, 1, &hci_result);
837 printk(MY_NOTICE "Re-enabled hotkeys\n");
838 }
839 } while (hci_result != HCI_EMPTY);
840}
841
842static int toshiba_acpi_setup_keyboard(char *device)
843{
844 acpi_status status;
845 acpi_handle handle;
846 int result;
847 const struct key_entry *key;
848
849 status = acpi_get_handle(NULL, device, &handle);
850 if (ACPI_FAILURE(status)) {
851 printk(MY_INFO "Unable to get notification device\n");
852 return -ENODEV;
853 }
854
855 toshiba_acpi.handle = handle;
856
857 status = acpi_evaluate_object(handle, "ENAB", NULL, NULL);
858 if (ACPI_FAILURE(status)) {
859 printk(MY_INFO "Unable to enable hotkeys\n");
860 return -ENODEV;
861 }
862
863 status = acpi_install_notify_handler(handle, ACPI_DEVICE_NOTIFY,
864 toshiba_acpi_notify, NULL);
865 if (ACPI_FAILURE(status)) {
866 printk(MY_INFO "Unable to install hotkey notification\n");
867 return -ENODEV;
868 }
869
870 toshiba_acpi.hotkey_dev = input_allocate_device();
871 if (!toshiba_acpi.hotkey_dev) {
872 printk(MY_INFO "Unable to register input device\n");
873 return -ENOMEM;
874 }
875
876 toshiba_acpi.hotkey_dev->name = "Toshiba input device";
877 toshiba_acpi.hotkey_dev->phys = device;
878 toshiba_acpi.hotkey_dev->id.bustype = BUS_HOST;
879 toshiba_acpi.hotkey_dev->getkeycode = toshiba_acpi_getkeycode;
880 toshiba_acpi.hotkey_dev->setkeycode = toshiba_acpi_setkeycode;
881
882 for (key = toshiba_acpi_keymap; key->type != KE_END; key++) {
883 set_bit(EV_KEY, toshiba_acpi.hotkey_dev->evbit);
884 set_bit(key->keycode, toshiba_acpi.hotkey_dev->keybit);
885 }
886
887 result = input_register_device(toshiba_acpi.hotkey_dev);
888 if (result) {
889 printk(MY_INFO "Unable to register input device\n");
890 return result;
891 }
892
893 return 0;
894}
895
679static void toshiba_acpi_exit(void) 896static void toshiba_acpi_exit(void)
680{ 897{
898 if (toshiba_acpi.hotkey_dev)
899 input_unregister_device(toshiba_acpi.hotkey_dev);
900
681 if (toshiba_acpi.bt_rfk) { 901 if (toshiba_acpi.bt_rfk) {
682 rfkill_unregister(toshiba_acpi.bt_rfk); 902 rfkill_unregister(toshiba_acpi.bt_rfk);
683 rfkill_destroy(toshiba_acpi.bt_rfk); 903 rfkill_destroy(toshiba_acpi.bt_rfk);
@@ -691,6 +911,9 @@ static void toshiba_acpi_exit(void)
691 if (toshiba_proc_dir) 911 if (toshiba_proc_dir)
692 remove_proc_entry(PROC_TOSHIBA, acpi_root_dir); 912 remove_proc_entry(PROC_TOSHIBA, acpi_root_dir);
693 913
914 acpi_remove_notify_handler(toshiba_acpi.handle, ACPI_DEVICE_NOTIFY,
915 toshiba_acpi_notify);
916
694 platform_device_unregister(toshiba_acpi.p_dev); 917 platform_device_unregister(toshiba_acpi.p_dev);
695 918
696 return; 919 return;
@@ -702,16 +925,21 @@ static int __init toshiba_acpi_init(void)
702 u32 hci_result; 925 u32 hci_result;
703 bool bt_present; 926 bool bt_present;
704 int ret = 0; 927 int ret = 0;
928 struct backlight_properties props;
705 929
706 if (acpi_disabled) 930 if (acpi_disabled)
707 return -ENODEV; 931 return -ENODEV;
708 932
709 /* simple device detection: look for HCI method */ 933 /* simple device detection: look for HCI method */
710 if (is_valid_acpi_path(METHOD_HCI_1)) 934 if (is_valid_acpi_path(TOSH_INTERFACE_1 GHCI_METHOD)) {
711 method_hci = METHOD_HCI_1; 935 method_hci = TOSH_INTERFACE_1 GHCI_METHOD;
712 else if (is_valid_acpi_path(METHOD_HCI_2)) 936 if (toshiba_acpi_setup_keyboard(TOSH_INTERFACE_1))
713 method_hci = METHOD_HCI_2; 937 printk(MY_INFO "Unable to activate hotkeys\n");
714 else 938 } else if (is_valid_acpi_path(TOSH_INTERFACE_2 GHCI_METHOD)) {
939 method_hci = TOSH_INTERFACE_2 GHCI_METHOD;
940 if (toshiba_acpi_setup_keyboard(TOSH_INTERFACE_2))
941 printk(MY_INFO "Unable to activate hotkeys\n");
942 } else
715 return -ENODEV; 943 return -ENODEV;
716 944
717 printk(MY_INFO "Toshiba Laptop ACPI Extras version %s\n", 945 printk(MY_INFO "Toshiba Laptop ACPI Extras version %s\n",
@@ -748,10 +976,12 @@ static int __init toshiba_acpi_init(void)
748 } 976 }
749 } 977 }
750 978
979 props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1;
751 toshiba_backlight_device = backlight_device_register("toshiba", 980 toshiba_backlight_device = backlight_device_register("toshiba",
752 &toshiba_acpi.p_dev->dev, 981 &toshiba_acpi.p_dev->dev,
753 NULL, 982 NULL,
754 &toshiba_backlight_data); 983 &toshiba_backlight_data,
984 &props);
755 if (IS_ERR(toshiba_backlight_device)) { 985 if (IS_ERR(toshiba_backlight_device)) {
756 ret = PTR_ERR(toshiba_backlight_device); 986 ret = PTR_ERR(toshiba_backlight_device);
757 987
@@ -760,7 +990,6 @@ static int __init toshiba_acpi_init(void)
760 toshiba_acpi_exit(); 990 toshiba_acpi_exit();
761 return ret; 991 return ret;
762 } 992 }
763 toshiba_backlight_device->props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1;
764 993
765 /* Register rfkill switch for Bluetooth */ 994 /* Register rfkill switch for Bluetooth */
766 if (hci_get_bt_present(&bt_present) == HCI_SUCCESS && bt_present) { 995 if (hci_get_bt_present(&bt_present) == HCI_SUCCESS && bt_present) {