aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/platform/x86/toshiba_acpi.c206
1 files changed, 199 insertions, 7 deletions
diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c
index 77bf5d8f893a..26c211724acf 100644
--- a/drivers/platform/x86/toshiba_acpi.c
+++ b/drivers/platform/x86/toshiba_acpi.c
@@ -46,6 +46,7 @@
46#include <linux/backlight.h> 46#include <linux/backlight.h>
47#include <linux/platform_device.h> 47#include <linux/platform_device.h>
48#include <linux/rfkill.h> 48#include <linux/rfkill.h>
49#include <linux/input.h>
49 50
50#include <asm/uaccess.h> 51#include <asm/uaccess.h>
51 52
@@ -62,9 +63,10 @@ MODULE_LICENSE("GPL");
62 63
63/* Toshiba ACPI method paths */ 64/* Toshiba ACPI method paths */
64#define METHOD_LCD_BRIGHTNESS "\\_SB_.PCI0.VGA_.LCD_._BCM" 65#define METHOD_LCD_BRIGHTNESS "\\_SB_.PCI0.VGA_.LCD_._BCM"
65#define METHOD_HCI_1 "\\_SB_.VALD.GHCI" 66#define TOSH_INTERFACE_1 "\\_SB_.VALD"
66#define METHOD_HCI_2 "\\_SB_.VALZ.GHCI" 67#define TOSH_INTERFACE_2 "\\_SB_.VALZ"
67#define METHOD_VIDEO_OUT "\\_SB_.VALX.DSSX" 68#define METHOD_VIDEO_OUT "\\_SB_.VALX.DSSX"
69#define GHCI_METHOD ".GHCI"
68 70
69/* Toshiba HCI interface definitions 71/* Toshiba HCI interface definitions
70 * 72 *
@@ -116,6 +118,36 @@ static const struct acpi_device_id toshiba_device_ids[] = {
116}; 118};
117MODULE_DEVICE_TABLE(acpi, toshiba_device_ids); 119MODULE_DEVICE_TABLE(acpi, toshiba_device_ids);
118 120
121struct key_entry {
122 char type;
123 u16 code;
124 u16 keycode;
125};
126
127enum {KE_KEY, KE_END};
128
129static struct key_entry toshiba_acpi_keymap[] = {
130 {KE_KEY, 0x101, KEY_MUTE},
131 {KE_KEY, 0x13b, KEY_COFFEE},
132 {KE_KEY, 0x13c, KEY_BATTERY},
133 {KE_KEY, 0x13d, KEY_SLEEP},
134 {KE_KEY, 0x13e, KEY_SUSPEND},
135 {KE_KEY, 0x13f, KEY_SWITCHVIDEOMODE},
136 {KE_KEY, 0x140, KEY_BRIGHTNESSDOWN},
137 {KE_KEY, 0x141, KEY_BRIGHTNESSUP},
138 {KE_KEY, 0x142, KEY_WLAN},
139 {KE_KEY, 0x143, KEY_PROG1},
140 {KE_KEY, 0xb05, KEY_PROG2},
141 {KE_KEY, 0xb06, KEY_WWW},
142 {KE_KEY, 0xb07, KEY_MAIL},
143 {KE_KEY, 0xb30, KEY_STOP},
144 {KE_KEY, 0xb31, KEY_PREVIOUSSONG},
145 {KE_KEY, 0xb32, KEY_NEXTSONG},
146 {KE_KEY, 0xb33, KEY_PLAYPAUSE},
147 {KE_KEY, 0xb5a, KEY_MEDIA},
148 {KE_END, 0, 0},
149};
150
119/* utility 151/* utility
120 */ 152 */
121 153
@@ -251,6 +283,8 @@ static acpi_status hci_read2(u32 reg, u32 *out1, u32 *out2, u32 *result)
251struct toshiba_acpi_dev { 283struct toshiba_acpi_dev {
252 struct platform_device *p_dev; 284 struct platform_device *p_dev;
253 struct rfkill *bt_rfk; 285 struct rfkill *bt_rfk;
286 struct input_dev *hotkey_dev;
287 acpi_handle handle;
254 288
255 const char *bt_name; 289 const char *bt_name;
256 290
@@ -711,8 +745,159 @@ static struct backlight_ops toshiba_backlight_data = {
711 .update_status = set_lcd_status, 745 .update_status = set_lcd_status,
712}; 746};
713 747
748static struct key_entry *toshiba_acpi_get_entry_by_scancode(int code)
749{
750 struct key_entry *key;
751
752 for (key = toshiba_acpi_keymap; key->type != KE_END; key++)
753 if (code == key->code)
754 return key;
755
756 return NULL;
757}
758
759static struct key_entry *toshiba_acpi_get_entry_by_keycode(int code)
760{
761 struct key_entry *key;
762
763 for (key = toshiba_acpi_keymap; key->type != KE_END; key++)
764 if (code == key->keycode && key->type == KE_KEY)
765 return key;
766
767 return NULL;
768}
769
770static int toshiba_acpi_getkeycode(struct input_dev *dev, int scancode,
771 int *keycode)
772{
773 struct key_entry *key = toshiba_acpi_get_entry_by_scancode(scancode);
774
775 if (key && key->type == KE_KEY) {
776 *keycode = key->keycode;
777 return 0;
778 }
779
780 return -EINVAL;
781}
782
783static int toshiba_acpi_setkeycode(struct input_dev *dev, int scancode,
784 int keycode)
785{
786 struct key_entry *key;
787 int old_keycode;
788
789 if (keycode < 0 || keycode > KEY_MAX)
790 return -EINVAL;
791
792 key = toshiba_acpi_get_entry_by_scancode(scancode);
793 if (key && key->type == KE_KEY) {
794 old_keycode = key->keycode;
795 key->keycode = keycode;
796 set_bit(keycode, dev->keybit);
797 if (!toshiba_acpi_get_entry_by_keycode(old_keycode))
798 clear_bit(old_keycode, dev->keybit);
799 return 0;
800 }
801
802 return -EINVAL;
803}
804
805static void toshiba_acpi_notify(acpi_handle handle, u32 event, void *context)
806{
807 u32 hci_result, value;
808 struct key_entry *key;
809
810 if (event != 0x80)
811 return;
812 do {
813 hci_read1(HCI_SYSTEM_EVENT, &value, &hci_result);
814 if (hci_result == HCI_SUCCESS) {
815 if (value == 0x100)
816 continue;
817 else if (value & 0x80) {
818 key = toshiba_acpi_get_entry_by_scancode
819 (value & ~0x80);
820 if (!key) {
821 printk(MY_INFO "Unknown key %x\n",
822 value & ~0x80);
823 continue;
824 }
825 input_report_key(toshiba_acpi.hotkey_dev,
826 key->keycode, 1);
827 input_sync(toshiba_acpi.hotkey_dev);
828 input_report_key(toshiba_acpi.hotkey_dev,
829 key->keycode, 0);
830 input_sync(toshiba_acpi.hotkey_dev);
831 }
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
714static void toshiba_acpi_exit(void) 896static void toshiba_acpi_exit(void)
715{ 897{
898 if (toshiba_acpi.hotkey_dev)
899 input_unregister_device(toshiba_acpi.hotkey_dev);
900
716 if (toshiba_acpi.bt_rfk) { 901 if (toshiba_acpi.bt_rfk) {
717 rfkill_unregister(toshiba_acpi.bt_rfk); 902 rfkill_unregister(toshiba_acpi.bt_rfk);
718 rfkill_destroy(toshiba_acpi.bt_rfk); 903 rfkill_destroy(toshiba_acpi.bt_rfk);
@@ -726,6 +911,9 @@ static void toshiba_acpi_exit(void)
726 if (toshiba_proc_dir) 911 if (toshiba_proc_dir)
727 remove_proc_entry(PROC_TOSHIBA, acpi_root_dir); 912 remove_proc_entry(PROC_TOSHIBA, acpi_root_dir);
728 913
914 acpi_remove_notify_handler(toshiba_acpi.handle, ACPI_DEVICE_NOTIFY,
915 toshiba_acpi_notify);
916
729 platform_device_unregister(toshiba_acpi.p_dev); 917 platform_device_unregister(toshiba_acpi.p_dev);
730 918
731 return; 919 return;
@@ -742,11 +930,15 @@ static int __init toshiba_acpi_init(void)
742 return -ENODEV; 930 return -ENODEV;
743 931
744 /* simple device detection: look for HCI method */ 932 /* simple device detection: look for HCI method */
745 if (is_valid_acpi_path(METHOD_HCI_1)) 933 if (is_valid_acpi_path(TOSH_INTERFACE_1 GHCI_METHOD)) {
746 method_hci = METHOD_HCI_1; 934 method_hci = TOSH_INTERFACE_1 GHCI_METHOD;
747 else if (is_valid_acpi_path(METHOD_HCI_2)) 935 if (toshiba_acpi_setup_keyboard(TOSH_INTERFACE_1))
748 method_hci = METHOD_HCI_2; 936 printk(MY_INFO "Unable to activate hotkeys\n");
749 else 937 } else if (is_valid_acpi_path(TOSH_INTERFACE_2 GHCI_METHOD)) {
938 method_hci = TOSH_INTERFACE_2 GHCI_METHOD;
939 if (toshiba_acpi_setup_keyboard(TOSH_INTERFACE_2))
940 printk(MY_INFO "Unable to activate hotkeys\n");
941 } else
750 return -ENODEV; 942 return -ENODEV;
751 943
752 printk(MY_INFO "Toshiba Laptop ACPI Extras version %s\n", 944 printk(MY_INFO "Toshiba Laptop ACPI Extras version %s\n",