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.c254
1 files changed, 213 insertions, 41 deletions
diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c
index dcdc1f4a4624..ee79ce64d9df 100644
--- a/drivers/platform/x86/toshiba_acpi.c
+++ b/drivers/platform/x86/toshiba_acpi.c
@@ -52,6 +52,8 @@
52#include <linux/input/sparse-keymap.h> 52#include <linux/input/sparse-keymap.h>
53#include <linux/leds.h> 53#include <linux/leds.h>
54#include <linux/slab.h> 54#include <linux/slab.h>
55#include <linux/workqueue.h>
56#include <linux/i8042.h>
55 57
56#include <asm/uaccess.h> 58#include <asm/uaccess.h>
57 59
@@ -61,6 +63,11 @@ MODULE_AUTHOR("John Belmonte");
61MODULE_DESCRIPTION("Toshiba Laptop ACPI Extras Driver"); 63MODULE_DESCRIPTION("Toshiba Laptop ACPI Extras Driver");
62MODULE_LICENSE("GPL"); 64MODULE_LICENSE("GPL");
63 65
66#define TOSHIBA_WMI_EVENT_GUID "59142400-C6A3-40FA-BADB-8A2652834100"
67
68/* Scan code for Fn key on TOS1900 models */
69#define TOS1900_FN_SCAN 0x6e
70
64/* Toshiba ACPI method paths */ 71/* Toshiba ACPI method paths */
65#define METHOD_VIDEO_OUT "\\_SB_.VALX.DSSX" 72#define METHOD_VIDEO_OUT "\\_SB_.VALX.DSSX"
66 73
@@ -95,6 +102,8 @@ MODULE_LICENSE("GPL");
95#define HCI_WIRELESS 0x0056 102#define HCI_WIRELESS 0x0056
96 103
97/* field definitions */ 104/* field definitions */
105#define HCI_HOTKEY_DISABLE 0x0b
106#define HCI_HOTKEY_ENABLE 0x09
98#define HCI_LCD_BRIGHTNESS_BITS 3 107#define HCI_LCD_BRIGHTNESS_BITS 3
99#define HCI_LCD_BRIGHTNESS_SHIFT (16-HCI_LCD_BRIGHTNESS_BITS) 108#define HCI_LCD_BRIGHTNESS_SHIFT (16-HCI_LCD_BRIGHTNESS_BITS)
100#define HCI_LCD_BRIGHTNESS_LEVELS (1 << HCI_LCD_BRIGHTNESS_BITS) 109#define HCI_LCD_BRIGHTNESS_LEVELS (1 << HCI_LCD_BRIGHTNESS_BITS)
@@ -111,6 +120,7 @@ struct toshiba_acpi_dev {
111 const char *method_hci; 120 const char *method_hci;
112 struct rfkill *bt_rfk; 121 struct rfkill *bt_rfk;
113 struct input_dev *hotkey_dev; 122 struct input_dev *hotkey_dev;
123 struct work_struct hotkey_work;
114 struct backlight_device *backlight_dev; 124 struct backlight_device *backlight_dev;
115 struct led_classdev led_dev; 125 struct led_classdev led_dev;
116 126
@@ -118,14 +128,18 @@ struct toshiba_acpi_dev {
118 int last_key_event; 128 int last_key_event;
119 int key_event_valid; 129 int key_event_valid;
120 130
121 int illumination_supported:1; 131 unsigned int illumination_supported:1;
122 int video_supported:1; 132 unsigned int video_supported:1;
123 int fan_supported:1; 133 unsigned int fan_supported:1;
124 int system_event_supported:1; 134 unsigned int system_event_supported:1;
135 unsigned int ntfy_supported:1;
136 unsigned int info_supported:1;
125 137
126 struct mutex mutex; 138 struct mutex mutex;
127}; 139};
128 140
141static struct toshiba_acpi_dev *toshiba_acpi;
142
129static const struct acpi_device_id toshiba_device_ids[] = { 143static const struct acpi_device_id toshiba_device_ids[] = {
130 {"TOS6200", 0}, 144 {"TOS6200", 0},
131 {"TOS6208", 0}, 145 {"TOS6208", 0},
@@ -138,6 +152,8 @@ static const struct key_entry toshiba_acpi_keymap[] __devinitconst = {
138 { KE_KEY, 0x101, { KEY_MUTE } }, 152 { KE_KEY, 0x101, { KEY_MUTE } },
139 { KE_KEY, 0x102, { KEY_ZOOMOUT } }, 153 { KE_KEY, 0x102, { KEY_ZOOMOUT } },
140 { KE_KEY, 0x103, { KEY_ZOOMIN } }, 154 { KE_KEY, 0x103, { KEY_ZOOMIN } },
155 { KE_KEY, 0x12c, { KEY_KBDILLUMTOGGLE } },
156 { KE_KEY, 0x139, { KEY_ZOOMRESET } },
141 { KE_KEY, 0x13b, { KEY_COFFEE } }, 157 { KE_KEY, 0x13b, { KEY_COFFEE } },
142 { KE_KEY, 0x13c, { KEY_BATTERY } }, 158 { KE_KEY, 0x13c, { KEY_BATTERY } },
143 { KE_KEY, 0x13d, { KEY_SLEEP } }, 159 { KE_KEY, 0x13d, { KEY_SLEEP } },
@@ -146,7 +162,7 @@ static const struct key_entry toshiba_acpi_keymap[] __devinitconst = {
146 { KE_KEY, 0x140, { KEY_BRIGHTNESSDOWN } }, 162 { KE_KEY, 0x140, { KEY_BRIGHTNESSDOWN } },
147 { KE_KEY, 0x141, { KEY_BRIGHTNESSUP } }, 163 { KE_KEY, 0x141, { KEY_BRIGHTNESSUP } },
148 { KE_KEY, 0x142, { KEY_WLAN } }, 164 { KE_KEY, 0x142, { KEY_WLAN } },
149 { KE_KEY, 0x143, { KEY_PROG1 } }, 165 { KE_KEY, 0x143, { KEY_TOUCHPAD_TOGGLE } },
150 { KE_KEY, 0x17f, { KEY_FN } }, 166 { KE_KEY, 0x17f, { KEY_FN } },
151 { KE_KEY, 0xb05, { KEY_PROG2 } }, 167 { KE_KEY, 0xb05, { KEY_PROG2 } },
152 { KE_KEY, 0xb06, { KEY_WWW } }, 168 { KE_KEY, 0xb06, { KEY_WWW } },
@@ -156,6 +172,7 @@ static const struct key_entry toshiba_acpi_keymap[] __devinitconst = {
156 { KE_KEY, 0xb32, { KEY_NEXTSONG } }, 172 { KE_KEY, 0xb32, { KEY_NEXTSONG } },
157 { KE_KEY, 0xb33, { KEY_PLAYPAUSE } }, 173 { KE_KEY, 0xb33, { KEY_PLAYPAUSE } },
158 { KE_KEY, 0xb5a, { KEY_MEDIA } }, 174 { KE_KEY, 0xb5a, { KEY_MEDIA } },
175 { KE_IGNORE, 0x1430, { KEY_RESERVED } },
159 { KE_END, 0 }, 176 { KE_END, 0 },
160}; 177};
161 178
@@ -847,10 +864,78 @@ static const struct backlight_ops toshiba_backlight_data = {
847 .update_status = set_lcd_status, 864 .update_status = set_lcd_status,
848}; 865};
849 866
867static bool toshiba_acpi_i8042_filter(unsigned char data, unsigned char str,
868 struct serio *port)
869{
870 if (str & 0x20)
871 return false;
872
873 if (unlikely(data == 0xe0))
874 return false;
875
876 if ((data & 0x7f) == TOS1900_FN_SCAN) {
877 schedule_work(&toshiba_acpi->hotkey_work);
878 return true;
879 }
880
881 return false;
882}
883
884static void toshiba_acpi_hotkey_work(struct work_struct *work)
885{
886 acpi_handle ec_handle = ec_get_handle();
887 acpi_status status;
888
889 if (!ec_handle)
890 return;
891
892 status = acpi_evaluate_object(ec_handle, "NTFY", NULL, NULL);
893 if (ACPI_FAILURE(status))
894 pr_err("ACPI NTFY method execution failed\n");
895}
896
897/*
898 * Returns hotkey scancode, or < 0 on failure.
899 */
900static int toshiba_acpi_query_hotkey(struct toshiba_acpi_dev *dev)
901{
902 struct acpi_buffer buf;
903 union acpi_object out_obj;
904 acpi_status status;
905
906 buf.pointer = &out_obj;
907 buf.length = sizeof(out_obj);
908
909 status = acpi_evaluate_object(dev->acpi_dev->handle, "INFO",
910 NULL, &buf);
911 if (ACPI_FAILURE(status) || out_obj.type != ACPI_TYPE_INTEGER) {
912 pr_err("ACPI INFO method execution failed\n");
913 return -EIO;
914 }
915
916 return out_obj.integer.value;
917}
918
919static void toshiba_acpi_report_hotkey(struct toshiba_acpi_dev *dev,
920 int scancode)
921{
922 if (scancode == 0x100)
923 return;
924
925 /* act on key press; ignore key release */
926 if (scancode & 0x80)
927 return;
928
929 if (!sparse_keymap_report_event(dev->hotkey_dev, scancode, 1, true))
930 pr_info("Unknown key %x\n", scancode);
931}
932
850static int __devinit toshiba_acpi_setup_keyboard(struct toshiba_acpi_dev *dev) 933static int __devinit toshiba_acpi_setup_keyboard(struct toshiba_acpi_dev *dev)
851{ 934{
852 acpi_status status; 935 acpi_status status;
936 acpi_handle ec_handle, handle;
853 int error; 937 int error;
938 u32 hci_result;
854 939
855 dev->hotkey_dev = input_allocate_device(); 940 dev->hotkey_dev = input_allocate_device();
856 if (!dev->hotkey_dev) { 941 if (!dev->hotkey_dev) {
@@ -866,21 +951,67 @@ static int __devinit toshiba_acpi_setup_keyboard(struct toshiba_acpi_dev *dev)
866 if (error) 951 if (error)
867 goto err_free_dev; 952 goto err_free_dev;
868 953
954 /*
955 * For some machines the SCI responsible for providing hotkey
956 * notification doesn't fire. We can trigger the notification
957 * whenever the Fn key is pressed using the NTFY method, if
958 * supported, so if it's present set up an i8042 key filter
959 * for this purpose.
960 */
961 status = AE_ERROR;
962 ec_handle = ec_get_handle();
963 if (ec_handle)
964 status = acpi_get_handle(ec_handle, "NTFY", &handle);
965
966 if (ACPI_SUCCESS(status)) {
967 INIT_WORK(&dev->hotkey_work, toshiba_acpi_hotkey_work);
968
969 error = i8042_install_filter(toshiba_acpi_i8042_filter);
970 if (error) {
971 pr_err("Error installing key filter\n");
972 goto err_free_keymap;
973 }
974
975 dev->ntfy_supported = 1;
976 }
977
978 /*
979 * Determine hotkey query interface. Prefer using the INFO
980 * method when it is available.
981 */
982 status = acpi_get_handle(dev->acpi_dev->handle, "INFO", &handle);
983 if (ACPI_SUCCESS(status)) {
984 dev->info_supported = 1;
985 } else {
986 hci_write1(dev, HCI_SYSTEM_EVENT, 1, &hci_result);
987 if (hci_result == HCI_SUCCESS)
988 dev->system_event_supported = 1;
989 }
990
991 if (!dev->info_supported && !dev->system_event_supported) {
992 pr_warn("No hotkey query interface found\n");
993 goto err_remove_filter;
994 }
995
869 status = acpi_evaluate_object(dev->acpi_dev->handle, "ENAB", NULL, NULL); 996 status = acpi_evaluate_object(dev->acpi_dev->handle, "ENAB", NULL, NULL);
870 if (ACPI_FAILURE(status)) { 997 if (ACPI_FAILURE(status)) {
871 pr_info("Unable to enable hotkeys\n"); 998 pr_info("Unable to enable hotkeys\n");
872 error = -ENODEV; 999 error = -ENODEV;
873 goto err_free_keymap; 1000 goto err_remove_filter;
874 } 1001 }
875 1002
876 error = input_register_device(dev->hotkey_dev); 1003 error = input_register_device(dev->hotkey_dev);
877 if (error) { 1004 if (error) {
878 pr_info("Unable to register input device\n"); 1005 pr_info("Unable to register input device\n");
879 goto err_free_keymap; 1006 goto err_remove_filter;
880 } 1007 }
881 1008
1009 hci_write1(dev, HCI_HOTKEY_EVENT, HCI_HOTKEY_ENABLE, &hci_result);
882 return 0; 1010 return 0;
883 1011
1012 err_remove_filter:
1013 if (dev->ntfy_supported)
1014 i8042_remove_filter(toshiba_acpi_i8042_filter);
884 err_free_keymap: 1015 err_free_keymap:
885 sparse_keymap_free(dev->hotkey_dev); 1016 sparse_keymap_free(dev->hotkey_dev);
886 err_free_dev: 1017 err_free_dev:
@@ -895,6 +1026,11 @@ static int toshiba_acpi_remove(struct acpi_device *acpi_dev, int type)
895 1026
896 remove_toshiba_proc_entries(dev); 1027 remove_toshiba_proc_entries(dev);
897 1028
1029 if (dev->ntfy_supported) {
1030 i8042_remove_filter(toshiba_acpi_i8042_filter);
1031 cancel_work_sync(&dev->hotkey_work);
1032 }
1033
898 if (dev->hotkey_dev) { 1034 if (dev->hotkey_dev) {
899 input_unregister_device(dev->hotkey_dev); 1035 input_unregister_device(dev->hotkey_dev);
900 sparse_keymap_free(dev->hotkey_dev); 1036 sparse_keymap_free(dev->hotkey_dev);
@@ -911,6 +1047,9 @@ static int toshiba_acpi_remove(struct acpi_device *acpi_dev, int type)
911 if (dev->illumination_supported) 1047 if (dev->illumination_supported)
912 led_classdev_unregister(&dev->led_dev); 1048 led_classdev_unregister(&dev->led_dev);
913 1049
1050 if (toshiba_acpi)
1051 toshiba_acpi = NULL;
1052
914 kfree(dev); 1053 kfree(dev);
915 1054
916 return 0; 1055 return 0;
@@ -936,12 +1075,14 @@ static int __devinit toshiba_acpi_add(struct acpi_device *acpi_dev)
936{ 1075{
937 struct toshiba_acpi_dev *dev; 1076 struct toshiba_acpi_dev *dev;
938 const char *hci_method; 1077 const char *hci_method;
939 u32 hci_result;
940 u32 dummy; 1078 u32 dummy;
941 bool bt_present; 1079 bool bt_present;
942 int ret = 0; 1080 int ret = 0;
943 struct backlight_properties props; 1081 struct backlight_properties props;
944 1082
1083 if (toshiba_acpi)
1084 return -EBUSY;
1085
945 pr_info("Toshiba Laptop ACPI Extras version %s\n", 1086 pr_info("Toshiba Laptop ACPI Extras version %s\n",
946 TOSHIBA_ACPI_VERSION); 1087 TOSHIBA_ACPI_VERSION);
947 1088
@@ -963,11 +1104,6 @@ static int __devinit toshiba_acpi_add(struct acpi_device *acpi_dev)
963 1104
964 mutex_init(&dev->mutex); 1105 mutex_init(&dev->mutex);
965 1106
966 /* enable event fifo */
967 hci_write1(dev, HCI_SYSTEM_EVENT, 1, &hci_result);
968 if (hci_result == HCI_SUCCESS)
969 dev->system_event_supported = 1;
970
971 props.type = BACKLIGHT_PLATFORM; 1107 props.type = BACKLIGHT_PLATFORM;
972 props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1; 1108 props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1;
973 dev->backlight_dev = backlight_device_register("toshiba", 1109 dev->backlight_dev = backlight_device_register("toshiba",
@@ -1024,6 +1160,8 @@ static int __devinit toshiba_acpi_add(struct acpi_device *acpi_dev)
1024 1160
1025 create_toshiba_proc_entries(dev); 1161 create_toshiba_proc_entries(dev);
1026 1162
1163 toshiba_acpi = dev;
1164
1027 return 0; 1165 return 0;
1028 1166
1029error: 1167error:
@@ -1036,40 +1174,64 @@ static void toshiba_acpi_notify(struct acpi_device *acpi_dev, u32 event)
1036 struct toshiba_acpi_dev *dev = acpi_driver_data(acpi_dev); 1174 struct toshiba_acpi_dev *dev = acpi_driver_data(acpi_dev);
1037 u32 hci_result, value; 1175 u32 hci_result, value;
1038 int retries = 3; 1176 int retries = 3;
1177 int scancode;
1039 1178
1040 if (!dev->system_event_supported || event != 0x80) 1179 if (event != 0x80)
1041 return; 1180 return;
1042 1181
1043 do { 1182 if (dev->info_supported) {
1044 hci_read1(dev, HCI_SYSTEM_EVENT, &value, &hci_result); 1183 scancode = toshiba_acpi_query_hotkey(dev);
1045 switch (hci_result) { 1184 if (scancode < 0)
1046 case HCI_SUCCESS: 1185 pr_err("Failed to query hotkey event\n");
1047 if (value == 0x100) 1186 else if (scancode != 0)
1048 continue; 1187 toshiba_acpi_report_hotkey(dev, scancode);
1049 /* act on key press; ignore key release */ 1188 } else if (dev->system_event_supported) {
1050 if (value & 0x80) 1189 do {
1051 continue; 1190 hci_read1(dev, HCI_SYSTEM_EVENT, &value, &hci_result);
1052 1191 switch (hci_result) {
1053 if (!sparse_keymap_report_event(dev->hotkey_dev, 1192 case HCI_SUCCESS:
1054 value, 1, true)) { 1193 toshiba_acpi_report_hotkey(dev, (int)value);
1055 pr_info("Unknown key %x\n", 1194 break;
1056 value); 1195 case HCI_NOT_SUPPORTED:
1196 /*
1197 * This is a workaround for an unresolved
1198 * issue on some machines where system events
1199 * sporadically become disabled.
1200 */
1201 hci_write1(dev, HCI_SYSTEM_EVENT, 1,
1202 &hci_result);
1203 pr_notice("Re-enabled hotkeys\n");
1204 /* fall through */
1205 default:
1206 retries--;
1207 break;
1057 } 1208 }
1058 break; 1209 } while (retries && hci_result != HCI_EMPTY);
1059 case HCI_NOT_SUPPORTED: 1210 }
1060 /* This is a workaround for an unresolved issue on 1211}
1061 * some machines where system events sporadically 1212
1062 * become disabled. */ 1213static int toshiba_acpi_suspend(struct acpi_device *acpi_dev,
1063 hci_write1(dev, HCI_SYSTEM_EVENT, 1, &hci_result); 1214 pm_message_t state)
1064 pr_notice("Re-enabled hotkeys\n"); 1215{
1065 /* fall through */ 1216 struct toshiba_acpi_dev *dev = acpi_driver_data(acpi_dev);
1066 default: 1217 u32 result;
1067 retries--; 1218
1068 break; 1219 if (dev->hotkey_dev)
1069 } 1220 hci_write1(dev, HCI_HOTKEY_EVENT, HCI_HOTKEY_DISABLE, &result);
1070 } while (retries && hci_result != HCI_EMPTY); 1221
1222 return 0;
1071} 1223}
1072 1224
1225static int toshiba_acpi_resume(struct acpi_device *acpi_dev)
1226{
1227 struct toshiba_acpi_dev *dev = acpi_driver_data(acpi_dev);
1228 u32 result;
1229
1230 if (dev->hotkey_dev)
1231 hci_write1(dev, HCI_HOTKEY_EVENT, HCI_HOTKEY_ENABLE, &result);
1232
1233 return 0;
1234}
1073 1235
1074static struct acpi_driver toshiba_acpi_driver = { 1236static struct acpi_driver toshiba_acpi_driver = {
1075 .name = "Toshiba ACPI driver", 1237 .name = "Toshiba ACPI driver",
@@ -1080,6 +1242,8 @@ static struct acpi_driver toshiba_acpi_driver = {
1080 .add = toshiba_acpi_add, 1242 .add = toshiba_acpi_add,
1081 .remove = toshiba_acpi_remove, 1243 .remove = toshiba_acpi_remove,
1082 .notify = toshiba_acpi_notify, 1244 .notify = toshiba_acpi_notify,
1245 .suspend = toshiba_acpi_suspend,
1246 .resume = toshiba_acpi_resume,
1083 }, 1247 },
1084}; 1248};
1085 1249
@@ -1087,6 +1251,14 @@ static int __init toshiba_acpi_init(void)
1087{ 1251{
1088 int ret; 1252 int ret;
1089 1253
1254 /*
1255 * Machines with this WMI guid aren't supported due to bugs in
1256 * their AML. This check relies on wmi initializing before
1257 * toshiba_acpi to guarantee guids have been identified.
1258 */
1259 if (wmi_has_guid(TOSHIBA_WMI_EVENT_GUID))
1260 return -ENODEV;
1261
1090 toshiba_proc_dir = proc_mkdir(PROC_TOSHIBA, acpi_root_dir); 1262 toshiba_proc_dir = proc_mkdir(PROC_TOSHIBA, acpi_root_dir);
1091 if (!toshiba_proc_dir) { 1263 if (!toshiba_proc_dir) {
1092 pr_err("Unable to create proc dir " PROC_TOSHIBA "\n"); 1264 pr_err("Unable to create proc dir " PROC_TOSHIBA "\n");