diff options
Diffstat (limited to 'drivers/platform/x86/toshiba_acpi.c')
-rw-r--r-- | drivers/platform/x86/toshiba_acpi.c | 256 |
1 files changed, 196 insertions, 60 deletions
diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index dbcb7a8915b8..9956b9902bb4 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c | |||
@@ -51,6 +51,7 @@ | |||
51 | #include <linux/acpi.h> | 51 | #include <linux/acpi.h> |
52 | #include <linux/dmi.h> | 52 | #include <linux/dmi.h> |
53 | #include <linux/uaccess.h> | 53 | #include <linux/uaccess.h> |
54 | #include <acpi/video.h> | ||
54 | 55 | ||
55 | MODULE_AUTHOR("John Belmonte"); | 56 | MODULE_AUTHOR("John Belmonte"); |
56 | MODULE_DESCRIPTION("Toshiba Laptop ACPI Extras Driver"); | 57 | MODULE_DESCRIPTION("Toshiba Laptop ACPI Extras Driver"); |
@@ -116,6 +117,7 @@ MODULE_LICENSE("GPL"); | |||
116 | #define HCI_KBD_ILLUMINATION 0x0095 | 117 | #define HCI_KBD_ILLUMINATION 0x0095 |
117 | #define HCI_ECO_MODE 0x0097 | 118 | #define HCI_ECO_MODE 0x0097 |
118 | #define HCI_ACCELEROMETER2 0x00a6 | 119 | #define HCI_ACCELEROMETER2 0x00a6 |
120 | #define HCI_SYSTEM_INFO 0xc000 | ||
119 | #define SCI_PANEL_POWER_ON 0x010d | 121 | #define SCI_PANEL_POWER_ON 0x010d |
120 | #define SCI_ILLUMINATION 0x014e | 122 | #define SCI_ILLUMINATION 0x014e |
121 | #define SCI_USB_SLEEP_CHARGE 0x0150 | 123 | #define SCI_USB_SLEEP_CHARGE 0x0150 |
@@ -129,10 +131,13 @@ MODULE_LICENSE("GPL"); | |||
129 | #define HCI_ACCEL_MASK 0x7fff | 131 | #define HCI_ACCEL_MASK 0x7fff |
130 | #define HCI_HOTKEY_DISABLE 0x0b | 132 | #define HCI_HOTKEY_DISABLE 0x0b |
131 | #define HCI_HOTKEY_ENABLE 0x09 | 133 | #define HCI_HOTKEY_ENABLE 0x09 |
134 | #define HCI_HOTKEY_SPECIAL_FUNCTIONS 0x10 | ||
132 | #define HCI_LCD_BRIGHTNESS_BITS 3 | 135 | #define HCI_LCD_BRIGHTNESS_BITS 3 |
133 | #define HCI_LCD_BRIGHTNESS_SHIFT (16-HCI_LCD_BRIGHTNESS_BITS) | 136 | #define HCI_LCD_BRIGHTNESS_SHIFT (16-HCI_LCD_BRIGHTNESS_BITS) |
134 | #define HCI_LCD_BRIGHTNESS_LEVELS (1 << HCI_LCD_BRIGHTNESS_BITS) | 137 | #define HCI_LCD_BRIGHTNESS_LEVELS (1 << HCI_LCD_BRIGHTNESS_BITS) |
135 | #define HCI_MISC_SHIFT 0x10 | 138 | #define HCI_MISC_SHIFT 0x10 |
139 | #define HCI_SYSTEM_TYPE1 0x10 | ||
140 | #define HCI_SYSTEM_TYPE2 0x11 | ||
136 | #define HCI_VIDEO_OUT_LCD 0x1 | 141 | #define HCI_VIDEO_OUT_LCD 0x1 |
137 | #define HCI_VIDEO_OUT_CRT 0x2 | 142 | #define HCI_VIDEO_OUT_CRT 0x2 |
138 | #define HCI_VIDEO_OUT_TV 0x4 | 143 | #define HCI_VIDEO_OUT_TV 0x4 |
@@ -147,9 +152,10 @@ MODULE_LICENSE("GPL"); | |||
147 | #define SCI_KBD_MODE_OFF 0x10 | 152 | #define SCI_KBD_MODE_OFF 0x10 |
148 | #define SCI_KBD_TIME_MAX 0x3c001a | 153 | #define SCI_KBD_TIME_MAX 0x3c001a |
149 | #define SCI_USB_CHARGE_MODE_MASK 0xff | 154 | #define SCI_USB_CHARGE_MODE_MASK 0xff |
150 | #define SCI_USB_CHARGE_DISABLED 0x30000 | 155 | #define SCI_USB_CHARGE_DISABLED 0x00 |
151 | #define SCI_USB_CHARGE_ALTERNATE 0x30009 | 156 | #define SCI_USB_CHARGE_ALTERNATE 0x09 |
152 | #define SCI_USB_CHARGE_AUTO 0x30021 | 157 | #define SCI_USB_CHARGE_TYPICAL 0x11 |
158 | #define SCI_USB_CHARGE_AUTO 0x21 | ||
153 | #define SCI_USB_CHARGE_BAT_MASK 0x7 | 159 | #define SCI_USB_CHARGE_BAT_MASK 0x7 |
154 | #define SCI_USB_CHARGE_BAT_LVL_OFF 0x1 | 160 | #define SCI_USB_CHARGE_BAT_LVL_OFF 0x1 |
155 | #define SCI_USB_CHARGE_BAT_LVL_ON 0x4 | 161 | #define SCI_USB_CHARGE_BAT_LVL_ON 0x4 |
@@ -174,6 +180,8 @@ struct toshiba_acpi_dev { | |||
174 | int kbd_mode; | 180 | int kbd_mode; |
175 | int kbd_time; | 181 | int kbd_time; |
176 | int usbsc_bat_level; | 182 | int usbsc_bat_level; |
183 | int usbsc_mode_base; | ||
184 | int hotkey_event_type; | ||
177 | 185 | ||
178 | unsigned int illumination_supported:1; | 186 | unsigned int illumination_supported:1; |
179 | unsigned int video_supported:1; | 187 | unsigned int video_supported:1; |
@@ -243,29 +251,6 @@ static const struct key_entry toshiba_acpi_keymap[] = { | |||
243 | { KE_END, 0 }, | 251 | { KE_END, 0 }, |
244 | }; | 252 | }; |
245 | 253 | ||
246 | /* alternative keymap */ | ||
247 | static const struct dmi_system_id toshiba_alt_keymap_dmi[] = { | ||
248 | { | ||
249 | .matches = { | ||
250 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | ||
251 | DMI_MATCH(DMI_PRODUCT_NAME, "Satellite M840"), | ||
252 | }, | ||
253 | }, | ||
254 | { | ||
255 | .matches = { | ||
256 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | ||
257 | DMI_MATCH(DMI_PRODUCT_NAME, "Qosmio X75-A"), | ||
258 | }, | ||
259 | }, | ||
260 | { | ||
261 | .matches = { | ||
262 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | ||
263 | DMI_MATCH(DMI_PRODUCT_NAME, "TECRA A50-A"), | ||
264 | }, | ||
265 | }, | ||
266 | {} | ||
267 | }; | ||
268 | |||
269 | static const struct key_entry toshiba_acpi_alt_keymap[] = { | 254 | static const struct key_entry toshiba_acpi_alt_keymap[] = { |
270 | { KE_KEY, 0x157, { KEY_MUTE } }, | 255 | { KE_KEY, 0x157, { KEY_MUTE } }, |
271 | { KE_KEY, 0x102, { KEY_ZOOMOUT } }, | 256 | { KE_KEY, 0x102, { KEY_ZOOMOUT } }, |
@@ -281,6 +266,14 @@ static const struct key_entry toshiba_acpi_alt_keymap[] = { | |||
281 | }; | 266 | }; |
282 | 267 | ||
283 | /* | 268 | /* |
269 | * List of models which have a broken acpi-video backlight interface and thus | ||
270 | * need to use the toshiba (vendor) interface instead. | ||
271 | */ | ||
272 | static const struct dmi_system_id toshiba_vendor_backlight_dmi[] = { | ||
273 | {} | ||
274 | }; | ||
275 | |||
276 | /* | ||
284 | * Utility | 277 | * Utility |
285 | */ | 278 | */ |
286 | 279 | ||
@@ -819,6 +812,54 @@ static int toshiba_accelerometer_get(struct toshiba_acpi_dev *dev, | |||
819 | } | 812 | } |
820 | 813 | ||
821 | /* Sleep (Charge and Music) utilities support */ | 814 | /* Sleep (Charge and Music) utilities support */ |
815 | static void toshiba_usb_sleep_charge_available(struct toshiba_acpi_dev *dev) | ||
816 | { | ||
817 | u32 in[TCI_WORDS] = { SCI_GET, SCI_USB_SLEEP_CHARGE, 0, 0, 0, 0 }; | ||
818 | u32 out[TCI_WORDS]; | ||
819 | acpi_status status; | ||
820 | |||
821 | /* Set the feature to "not supported" in case of error */ | ||
822 | dev->usb_sleep_charge_supported = 0; | ||
823 | |||
824 | if (!sci_open(dev)) | ||
825 | return; | ||
826 | |||
827 | status = tci_raw(dev, in, out); | ||
828 | if (ACPI_FAILURE(status) || out[0] == TOS_FAILURE) { | ||
829 | pr_err("ACPI call to get USB Sleep and Charge mode failed\n"); | ||
830 | sci_close(dev); | ||
831 | return; | ||
832 | } else if (out[0] == TOS_NOT_SUPPORTED) { | ||
833 | pr_info("USB Sleep and Charge not supported\n"); | ||
834 | sci_close(dev); | ||
835 | return; | ||
836 | } else if (out[0] == TOS_SUCCESS) { | ||
837 | dev->usbsc_mode_base = out[4]; | ||
838 | } | ||
839 | |||
840 | in[5] = SCI_USB_CHARGE_BAT_LVL; | ||
841 | status = tci_raw(dev, in, out); | ||
842 | if (ACPI_FAILURE(status) || out[0] == TOS_FAILURE) { | ||
843 | pr_err("ACPI call to get USB Sleep and Charge mode failed\n"); | ||
844 | sci_close(dev); | ||
845 | return; | ||
846 | } else if (out[0] == TOS_NOT_SUPPORTED) { | ||
847 | pr_info("USB Sleep and Charge not supported\n"); | ||
848 | sci_close(dev); | ||
849 | return; | ||
850 | } else if (out[0] == TOS_SUCCESS) { | ||
851 | dev->usbsc_bat_level = out[2]; | ||
852 | /* | ||
853 | * If we reach this point, it means that the laptop has support | ||
854 | * for this feature and all values are initialized. | ||
855 | * Set it as supported. | ||
856 | */ | ||
857 | dev->usb_sleep_charge_supported = 1; | ||
858 | } | ||
859 | |||
860 | sci_close(dev); | ||
861 | } | ||
862 | |||
822 | static int toshiba_usb_sleep_charge_get(struct toshiba_acpi_dev *dev, | 863 | static int toshiba_usb_sleep_charge_get(struct toshiba_acpi_dev *dev, |
823 | u32 *mode) | 864 | u32 *mode) |
824 | { | 865 | { |
@@ -934,11 +975,11 @@ static int toshiba_usb_rapid_charge_get(struct toshiba_acpi_dev *dev, | |||
934 | status = tci_raw(dev, in, out); | 975 | status = tci_raw(dev, in, out); |
935 | sci_close(dev); | 976 | sci_close(dev); |
936 | if (ACPI_FAILURE(status) || out[0] == TOS_FAILURE) { | 977 | if (ACPI_FAILURE(status) || out[0] == TOS_FAILURE) { |
937 | pr_err("ACPI call to get USB S&C battery level failed\n"); | 978 | pr_err("ACPI call to get USB Rapid Charge failed\n"); |
938 | return -EIO; | 979 | return -EIO; |
939 | } else if (out[0] == TOS_NOT_SUPPORTED || | 980 | } else if (out[0] == TOS_NOT_SUPPORTED || |
940 | out[0] == TOS_INPUT_DATA_ERROR) { | 981 | out[0] == TOS_INPUT_DATA_ERROR) { |
941 | pr_info("USB Sleep and Charge not supported\n"); | 982 | pr_info("USB Rapid Charge not supported\n"); |
942 | return -ENODEV; | 983 | return -ENODEV; |
943 | } | 984 | } |
944 | 985 | ||
@@ -962,10 +1003,10 @@ static int toshiba_usb_rapid_charge_set(struct toshiba_acpi_dev *dev, | |||
962 | status = tci_raw(dev, in, out); | 1003 | status = tci_raw(dev, in, out); |
963 | sci_close(dev); | 1004 | sci_close(dev); |
964 | if (ACPI_FAILURE(status) || out[0] == TOS_FAILURE) { | 1005 | if (ACPI_FAILURE(status) || out[0] == TOS_FAILURE) { |
965 | pr_err("ACPI call to set USB S&C battery level failed\n"); | 1006 | pr_err("ACPI call to set USB Rapid Charge failed\n"); |
966 | return -EIO; | 1007 | return -EIO; |
967 | } else if (out[0] == TOS_NOT_SUPPORTED) { | 1008 | } else if (out[0] == TOS_NOT_SUPPORTED) { |
968 | pr_info("USB Sleep and Charge not supported\n"); | 1009 | pr_info("USB Rapid Charge not supported\n"); |
969 | return -ENODEV; | 1010 | return -ENODEV; |
970 | } else if (out[0] == TOS_INPUT_DATA_ERROR) { | 1011 | } else if (out[0] == TOS_INPUT_DATA_ERROR) { |
971 | return -EIO; | 1012 | return -EIO; |
@@ -984,10 +1025,10 @@ static int toshiba_usb_sleep_music_get(struct toshiba_acpi_dev *dev, u32 *state) | |||
984 | result = sci_read(dev, SCI_USB_SLEEP_MUSIC, state); | 1025 | result = sci_read(dev, SCI_USB_SLEEP_MUSIC, state); |
985 | sci_close(dev); | 1026 | sci_close(dev); |
986 | if (result == TOS_FAILURE) { | 1027 | if (result == TOS_FAILURE) { |
987 | pr_err("ACPI call to set USB S&C mode failed\n"); | 1028 | pr_err("ACPI call to get Sleep and Music failed\n"); |
988 | return -EIO; | 1029 | return -EIO; |
989 | } else if (result == TOS_NOT_SUPPORTED) { | 1030 | } else if (result == TOS_NOT_SUPPORTED) { |
990 | pr_info("USB Sleep and Charge not supported\n"); | 1031 | pr_info("Sleep and Music not supported\n"); |
991 | return -ENODEV; | 1032 | return -ENODEV; |
992 | } else if (result == TOS_INPUT_DATA_ERROR) { | 1033 | } else if (result == TOS_INPUT_DATA_ERROR) { |
993 | return -EIO; | 1034 | return -EIO; |
@@ -1006,10 +1047,10 @@ static int toshiba_usb_sleep_music_set(struct toshiba_acpi_dev *dev, u32 state) | |||
1006 | result = sci_write(dev, SCI_USB_SLEEP_MUSIC, state); | 1047 | result = sci_write(dev, SCI_USB_SLEEP_MUSIC, state); |
1007 | sci_close(dev); | 1048 | sci_close(dev); |
1008 | if (result == TOS_FAILURE) { | 1049 | if (result == TOS_FAILURE) { |
1009 | pr_err("ACPI call to set USB S&C mode failed\n"); | 1050 | pr_err("ACPI call to set Sleep and Music failed\n"); |
1010 | return -EIO; | 1051 | return -EIO; |
1011 | } else if (result == TOS_NOT_SUPPORTED) { | 1052 | } else if (result == TOS_NOT_SUPPORTED) { |
1012 | pr_info("USB Sleep and Charge not supported\n"); | 1053 | pr_info("Sleep and Music not supported\n"); |
1013 | return -ENODEV; | 1054 | return -ENODEV; |
1014 | } else if (result == TOS_INPUT_DATA_ERROR) { | 1055 | } else if (result == TOS_INPUT_DATA_ERROR) { |
1015 | return -EIO; | 1056 | return -EIO; |
@@ -1149,6 +1190,28 @@ static int toshiba_usb_three_set(struct toshiba_acpi_dev *dev, u32 state) | |||
1149 | return 0; | 1190 | return 0; |
1150 | } | 1191 | } |
1151 | 1192 | ||
1193 | /* Hotkey Event type */ | ||
1194 | static int toshiba_hotkey_event_type_get(struct toshiba_acpi_dev *dev, | ||
1195 | u32 *type) | ||
1196 | { | ||
1197 | u32 val1 = 0x03; | ||
1198 | u32 val2 = 0; | ||
1199 | u32 result; | ||
1200 | |||
1201 | result = hci_read2(dev, HCI_SYSTEM_INFO, &val1, &val2); | ||
1202 | if (result == TOS_FAILURE) { | ||
1203 | pr_err("ACPI call to get System type failed\n"); | ||
1204 | return -EIO; | ||
1205 | } else if (result == TOS_NOT_SUPPORTED) { | ||
1206 | pr_info("System type not supported\n"); | ||
1207 | return -ENODEV; | ||
1208 | } | ||
1209 | |||
1210 | *type = val2; | ||
1211 | |||
1212 | return 0; | ||
1213 | } | ||
1214 | |||
1152 | /* Bluetooth rfkill handlers */ | 1215 | /* Bluetooth rfkill handlers */ |
1153 | 1216 | ||
1154 | static u32 hci_get_bt_present(struct toshiba_acpi_dev *dev, bool *present) | 1217 | static u32 hci_get_bt_present(struct toshiba_acpi_dev *dev, bool *present) |
@@ -1973,17 +2036,21 @@ static ssize_t usb_sleep_charge_store(struct device *dev, | |||
1973 | * 0 - Disabled | 2036 | * 0 - Disabled |
1974 | * 1 - Alternate (Non USB conformant devices that require more power) | 2037 | * 1 - Alternate (Non USB conformant devices that require more power) |
1975 | * 2 - Auto (USB conformant devices) | 2038 | * 2 - Auto (USB conformant devices) |
2039 | * 3 - Typical | ||
1976 | */ | 2040 | */ |
1977 | if (state != 0 && state != 1 && state != 2) | 2041 | if (state != 0 && state != 1 && state != 2 && state != 3) |
1978 | return -EINVAL; | 2042 | return -EINVAL; |
1979 | 2043 | ||
1980 | /* Set the USB charging mode to internal value */ | 2044 | /* Set the USB charging mode to internal value */ |
2045 | mode = toshiba->usbsc_mode_base; | ||
1981 | if (state == 0) | 2046 | if (state == 0) |
1982 | mode = SCI_USB_CHARGE_DISABLED; | 2047 | mode |= SCI_USB_CHARGE_DISABLED; |
1983 | else if (state == 1) | 2048 | else if (state == 1) |
1984 | mode = SCI_USB_CHARGE_ALTERNATE; | 2049 | mode |= SCI_USB_CHARGE_ALTERNATE; |
1985 | else if (state == 2) | 2050 | else if (state == 2) |
1986 | mode = SCI_USB_CHARGE_AUTO; | 2051 | mode |= SCI_USB_CHARGE_AUTO; |
2052 | else if (state == 3) | ||
2053 | mode |= SCI_USB_CHARGE_TYPICAL; | ||
1987 | 2054 | ||
1988 | ret = toshiba_usb_sleep_charge_set(toshiba, mode); | 2055 | ret = toshiba_usb_sleep_charge_set(toshiba, mode); |
1989 | if (ret) | 2056 | if (ret) |
@@ -2333,6 +2400,20 @@ static int toshiba_acpi_enable_hotkeys(struct toshiba_acpi_dev *dev) | |||
2333 | return 0; | 2400 | return 0; |
2334 | } | 2401 | } |
2335 | 2402 | ||
2403 | static void toshiba_acpi_enable_special_functions(struct toshiba_acpi_dev *dev) | ||
2404 | { | ||
2405 | u32 result; | ||
2406 | |||
2407 | /* | ||
2408 | * Re-activate the hotkeys, but this time, we are using the | ||
2409 | * "Special Functions" mode. | ||
2410 | */ | ||
2411 | result = hci_write1(dev, HCI_HOTKEY_EVENT, | ||
2412 | HCI_HOTKEY_SPECIAL_FUNCTIONS); | ||
2413 | if (result != TOS_SUCCESS) | ||
2414 | pr_err("Could not enable the Special Function mode\n"); | ||
2415 | } | ||
2416 | |||
2336 | static bool toshiba_acpi_i8042_filter(unsigned char data, unsigned char str, | 2417 | static bool toshiba_acpi_i8042_filter(unsigned char data, unsigned char str, |
2337 | struct serio *port) | 2418 | struct serio *port) |
2338 | { | 2419 | { |
@@ -2434,10 +2515,22 @@ static void toshiba_acpi_process_hotkeys(struct toshiba_acpi_dev *dev) | |||
2434 | 2515 | ||
2435 | static int toshiba_acpi_setup_keyboard(struct toshiba_acpi_dev *dev) | 2516 | static int toshiba_acpi_setup_keyboard(struct toshiba_acpi_dev *dev) |
2436 | { | 2517 | { |
2518 | const struct key_entry *keymap = toshiba_acpi_keymap; | ||
2437 | acpi_handle ec_handle; | 2519 | acpi_handle ec_handle; |
2438 | int error; | 2520 | u32 events_type; |
2439 | u32 hci_result; | 2521 | u32 hci_result; |
2440 | const struct key_entry *keymap = toshiba_acpi_keymap; | 2522 | int error; |
2523 | |||
2524 | error = toshiba_acpi_enable_hotkeys(dev); | ||
2525 | if (error) | ||
2526 | return error; | ||
2527 | |||
2528 | error = toshiba_hotkey_event_type_get(dev, &events_type); | ||
2529 | if (error) { | ||
2530 | pr_err("Unable to query Hotkey Event Type\n"); | ||
2531 | return error; | ||
2532 | } | ||
2533 | dev->hotkey_event_type = events_type; | ||
2441 | 2534 | ||
2442 | dev->hotkey_dev = input_allocate_device(); | 2535 | dev->hotkey_dev = input_allocate_device(); |
2443 | if (!dev->hotkey_dev) | 2536 | if (!dev->hotkey_dev) |
@@ -2447,8 +2540,14 @@ static int toshiba_acpi_setup_keyboard(struct toshiba_acpi_dev *dev) | |||
2447 | dev->hotkey_dev->phys = "toshiba_acpi/input0"; | 2540 | dev->hotkey_dev->phys = "toshiba_acpi/input0"; |
2448 | dev->hotkey_dev->id.bustype = BUS_HOST; | 2541 | dev->hotkey_dev->id.bustype = BUS_HOST; |
2449 | 2542 | ||
2450 | if (dmi_check_system(toshiba_alt_keymap_dmi)) | 2543 | if (events_type == HCI_SYSTEM_TYPE1 || |
2544 | !dev->kbd_function_keys_supported) | ||
2545 | keymap = toshiba_acpi_keymap; | ||
2546 | else if (events_type == HCI_SYSTEM_TYPE2 || | ||
2547 | dev->kbd_function_keys_supported) | ||
2451 | keymap = toshiba_acpi_alt_keymap; | 2548 | keymap = toshiba_acpi_alt_keymap; |
2549 | else | ||
2550 | pr_info("Unknown event type received %x\n", events_type); | ||
2452 | error = sparse_keymap_setup(dev->hotkey_dev, keymap, NULL); | 2551 | error = sparse_keymap_setup(dev->hotkey_dev, keymap, NULL); |
2453 | if (error) | 2552 | if (error) |
2454 | goto err_free_dev; | 2553 | goto err_free_dev; |
@@ -2490,12 +2589,6 @@ static int toshiba_acpi_setup_keyboard(struct toshiba_acpi_dev *dev) | |||
2490 | goto err_remove_filter; | 2589 | goto err_remove_filter; |
2491 | } | 2590 | } |
2492 | 2591 | ||
2493 | error = toshiba_acpi_enable_hotkeys(dev); | ||
2494 | if (error) { | ||
2495 | pr_info("Unable to enable hotkeys\n"); | ||
2496 | goto err_remove_filter; | ||
2497 | } | ||
2498 | |||
2499 | error = input_register_device(dev->hotkey_dev); | 2592 | error = input_register_device(dev->hotkey_dev); |
2500 | if (error) { | 2593 | if (error) { |
2501 | pr_info("Unable to register input device\n"); | 2594 | pr_info("Unable to register input device\n"); |
@@ -2541,6 +2634,20 @@ static int toshiba_acpi_setup_backlight(struct toshiba_acpi_dev *dev) | |||
2541 | ret = get_tr_backlight_status(dev, &enabled); | 2634 | ret = get_tr_backlight_status(dev, &enabled); |
2542 | dev->tr_backlight_supported = !ret; | 2635 | dev->tr_backlight_supported = !ret; |
2543 | 2636 | ||
2637 | /* | ||
2638 | * Tell acpi-video-detect code to prefer vendor backlight on all | ||
2639 | * systems with transflective backlight and on dmi matched systems. | ||
2640 | */ | ||
2641 | if (dev->tr_backlight_supported || | ||
2642 | dmi_check_system(toshiba_vendor_backlight_dmi)) | ||
2643 | acpi_video_dmi_promote_vendor(); | ||
2644 | |||
2645 | if (acpi_video_backlight_support()) | ||
2646 | return 0; | ||
2647 | |||
2648 | /* acpi-video may have loaded before we called dmi_promote_vendor() */ | ||
2649 | acpi_video_unregister_backlight(); | ||
2650 | |||
2544 | memset(&props, 0, sizeof(props)); | 2651 | memset(&props, 0, sizeof(props)); |
2545 | props.type = BACKLIGHT_PLATFORM; | 2652 | props.type = BACKLIGHT_PLATFORM; |
2546 | props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1; | 2653 | props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1; |
@@ -2624,6 +2731,7 @@ static int toshiba_acpi_add(struct acpi_device *acpi_dev) | |||
2624 | { | 2731 | { |
2625 | struct toshiba_acpi_dev *dev; | 2732 | struct toshiba_acpi_dev *dev; |
2626 | const char *hci_method; | 2733 | const char *hci_method; |
2734 | u32 special_functions; | ||
2627 | u32 dummy; | 2735 | u32 dummy; |
2628 | bool bt_present; | 2736 | bool bt_present; |
2629 | int ret = 0; | 2737 | int ret = 0; |
@@ -2648,6 +2756,16 @@ static int toshiba_acpi_add(struct acpi_device *acpi_dev) | |||
2648 | acpi_dev->driver_data = dev; | 2756 | acpi_dev->driver_data = dev; |
2649 | dev_set_drvdata(&acpi_dev->dev, dev); | 2757 | dev_set_drvdata(&acpi_dev->dev, dev); |
2650 | 2758 | ||
2759 | /* Query the BIOS for supported features */ | ||
2760 | |||
2761 | /* | ||
2762 | * The "Special Functions" are always supported by the laptops | ||
2763 | * with the new keyboard layout, query for its presence to help | ||
2764 | * determine the keymap layout to use. | ||
2765 | */ | ||
2766 | ret = toshiba_function_keys_get(dev, &special_functions); | ||
2767 | dev->kbd_function_keys_supported = !ret; | ||
2768 | |||
2651 | if (toshiba_acpi_setup_keyboard(dev)) | 2769 | if (toshiba_acpi_setup_keyboard(dev)) |
2652 | pr_info("Unable to activate hotkeys\n"); | 2770 | pr_info("Unable to activate hotkeys\n"); |
2653 | 2771 | ||
@@ -2716,8 +2834,7 @@ static int toshiba_acpi_add(struct acpi_device *acpi_dev) | |||
2716 | ret = toshiba_accelerometer_supported(dev); | 2834 | ret = toshiba_accelerometer_supported(dev); |
2717 | dev->accelerometer_supported = !ret; | 2835 | dev->accelerometer_supported = !ret; |
2718 | 2836 | ||
2719 | ret = toshiba_usb_sleep_charge_get(dev, &dummy); | 2837 | toshiba_usb_sleep_charge_available(dev); |
2720 | dev->usb_sleep_charge_supported = !ret; | ||
2721 | 2838 | ||
2722 | ret = toshiba_usb_rapid_charge_get(dev, &dummy); | 2839 | ret = toshiba_usb_rapid_charge_get(dev, &dummy); |
2723 | dev->usb_rapid_charge_supported = !ret; | 2840 | dev->usb_rapid_charge_supported = !ret; |
@@ -2725,23 +2842,25 @@ static int toshiba_acpi_add(struct acpi_device *acpi_dev) | |||
2725 | ret = toshiba_usb_sleep_music_get(dev, &dummy); | 2842 | ret = toshiba_usb_sleep_music_get(dev, &dummy); |
2726 | dev->usb_sleep_music_supported = !ret; | 2843 | dev->usb_sleep_music_supported = !ret; |
2727 | 2844 | ||
2728 | ret = toshiba_function_keys_get(dev, &dummy); | ||
2729 | dev->kbd_function_keys_supported = !ret; | ||
2730 | |||
2731 | ret = toshiba_panel_power_on_get(dev, &dummy); | 2845 | ret = toshiba_panel_power_on_get(dev, &dummy); |
2732 | dev->panel_power_on_supported = !ret; | 2846 | dev->panel_power_on_supported = !ret; |
2733 | 2847 | ||
2734 | ret = toshiba_usb_three_get(dev, &dummy); | 2848 | ret = toshiba_usb_three_get(dev, &dummy); |
2735 | dev->usb_three_supported = !ret; | 2849 | dev->usb_three_supported = !ret; |
2736 | 2850 | ||
2737 | /* Determine whether or not BIOS supports fan and video interfaces */ | ||
2738 | |||
2739 | ret = get_video_status(dev, &dummy); | 2851 | ret = get_video_status(dev, &dummy); |
2740 | dev->video_supported = !ret; | 2852 | dev->video_supported = !ret; |
2741 | 2853 | ||
2742 | ret = get_fan_status(dev, &dummy); | 2854 | ret = get_fan_status(dev, &dummy); |
2743 | dev->fan_supported = !ret; | 2855 | dev->fan_supported = !ret; |
2744 | 2856 | ||
2857 | /* | ||
2858 | * Enable the "Special Functions" mode only if they are | ||
2859 | * supported and if they are activated. | ||
2860 | */ | ||
2861 | if (dev->kbd_function_keys_supported && special_functions) | ||
2862 | toshiba_acpi_enable_special_functions(dev); | ||
2863 | |||
2745 | ret = sysfs_create_group(&dev->acpi_dev->dev.kobj, | 2864 | ret = sysfs_create_group(&dev->acpi_dev->dev.kobj, |
2746 | &toshiba_attr_group); | 2865 | &toshiba_attr_group); |
2747 | if (ret) { | 2866 | if (ret) { |
@@ -2770,6 +2889,21 @@ static void toshiba_acpi_notify(struct acpi_device *acpi_dev, u32 event) | |||
2770 | case 0x80: /* Hotkeys and some system events */ | 2889 | case 0x80: /* Hotkeys and some system events */ |
2771 | toshiba_acpi_process_hotkeys(dev); | 2890 | toshiba_acpi_process_hotkeys(dev); |
2772 | break; | 2891 | break; |
2892 | case 0x81: /* Dock events */ | ||
2893 | case 0x82: | ||
2894 | case 0x83: | ||
2895 | pr_info("Dock event received %x\n", event); | ||
2896 | break; | ||
2897 | case 0x88: /* Thermal events */ | ||
2898 | pr_info("Thermal event received\n"); | ||
2899 | break; | ||
2900 | case 0x8f: /* LID closed */ | ||
2901 | case 0x90: /* LID is closed and Dock has been ejected */ | ||
2902 | break; | ||
2903 | case 0x8c: /* SATA power events */ | ||
2904 | case 0x8b: | ||
2905 | pr_info("SATA power event received %x\n", event); | ||
2906 | break; | ||
2773 | case 0x92: /* Keyboard backlight mode changed */ | 2907 | case 0x92: /* Keyboard backlight mode changed */ |
2774 | /* Update sysfs entries */ | 2908 | /* Update sysfs entries */ |
2775 | ret = sysfs_update_group(&acpi_dev->dev.kobj, | 2909 | ret = sysfs_update_group(&acpi_dev->dev.kobj, |
@@ -2777,17 +2911,19 @@ static void toshiba_acpi_notify(struct acpi_device *acpi_dev, u32 event) | |||
2777 | if (ret) | 2911 | if (ret) |
2778 | pr_err("Unable to update sysfs entries\n"); | 2912 | pr_err("Unable to update sysfs entries\n"); |
2779 | break; | 2913 | break; |
2780 | case 0x81: /* Unknown */ | 2914 | case 0x85: /* Unknown */ |
2781 | case 0x82: /* Unknown */ | 2915 | case 0x8d: /* Unknown */ |
2782 | case 0x83: /* Unknown */ | ||
2783 | case 0x8c: /* Unknown */ | ||
2784 | case 0x8e: /* Unknown */ | 2916 | case 0x8e: /* Unknown */ |
2785 | case 0x8f: /* Unknown */ | 2917 | case 0x94: /* Unknown */ |
2786 | case 0x90: /* Unknown */ | 2918 | case 0x95: /* Unknown */ |
2787 | default: | 2919 | default: |
2788 | pr_info("Unknown event received %x\n", event); | 2920 | pr_info("Unknown event received %x\n", event); |
2789 | break; | 2921 | break; |
2790 | } | 2922 | } |
2923 | |||
2924 | acpi_bus_generate_netlink_event(acpi_dev->pnp.device_class, | ||
2925 | dev_name(&acpi_dev->dev), | ||
2926 | event, 0); | ||
2791 | } | 2927 | } |
2792 | 2928 | ||
2793 | #ifdef CONFIG_PM_SLEEP | 2929 | #ifdef CONFIG_PM_SLEEP |