diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-04-26 16:44:46 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-04-26 16:44:46 -0400 |
commit | 78d425677217b655ed36c492a070b5002832fc73 (patch) | |
tree | a178a3bf773027f3a70ecec1ad6f9d35074e4263 /drivers/platform/x86/thinkpad_acpi.c | |
parent | 36a8032d77649430f5ef11fbf0df2bb026be0b04 (diff) | |
parent | 358d6a2c3ecae2b22c7d7e61f9d5672557446dfb (diff) |
Merge tag 'platform-drivers-x86-v4.1-1' of git://git.infradead.org/users/dvhart/linux-platform-drivers-x86
Pull x86 platform driver updates from Darren Hart:
"This series includes significant updates to the toshiba_acpi driver
and the reintroduction of the dell-laptop keyboard backlight additions
I had to revert previously. Also included are various fixes for
typos, warnings, correctness, and minor bugs.
Specifics:
dell-laptop:
- add support for keyboard backlight.
toshiba_acpi:
- adaptive keyboard, hotkey, USB sleep and charge, and backlight
updates. Update sysfs documentation.
toshiba_bluetooth:
- fix enabling/disabling loop on recent devices
apple-gmux:
- lock iGP IO to protect from vgaarb changes
other:
- Fix typos, clear gcc warnings, clarify pr_* messages, correct
return types, update MAINTAINERS"
* tag 'platform-drivers-x86-v4.1-1' of git://git.infradead.org/users/dvhart/linux-platform-drivers-x86: (25 commits)
toshiba_acpi: Do not register vendor backlight when acpi_video bl is available
MAINTAINERS: Add me on list of Dell laptop drivers
platform: x86: dell-laptop: Add support for keyboard backlight
Documentation/ABI: Update sysfs-driver-toshiba_acpi entry
toshiba_acpi: Fix pr_* messages from USB Sleep Functions
toshiba_acpi: Update and fix USB Sleep and Charge modes
wmi: Use bool function return values of true/false not 1/0
toshiba_bluetooth: Fix enabling/disabling loop on recent devices
toshiba_bluetooth: Clean up *_add function and disable BT device at removal
toshiba_bluetooth: Add three new functions to the driver
toshiba_acpi: Fix the enabling of the Special Functions
toshiba_acpi: Use the Hotkey Event Type function for keymap choosing
toshiba_acpi: Add Hotkey Event Type function and definitions
x86/wmi: delete unused wmi_data_lock mutex causing gcc warning
apple-gmux: lock iGP IO to protect from vgaarb changes
MAINTAINERS: Add missing Toshiba devices and add myself as maintainer
toshiba_acpi: Update events in toshiba_acpi_notify
intel-oaktrail: Fix trivial typo in comment
thinkpad_acpi: off by one in adaptive_keyboard_hotkey_notify_hotkey()
thinkpad_acpi: signedness bugs getting current_mode
...
Diffstat (limited to 'drivers/platform/x86/thinkpad_acpi.c')
-rw-r--r-- | drivers/platform/x86/thinkpad_acpi.c | 320 |
1 files changed, 216 insertions, 104 deletions
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 3b8ceee7c5cb..7769575345d8 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c | |||
@@ -319,6 +319,7 @@ static struct { | |||
319 | u32 sensors_pdrv_attrs_registered:1; | 319 | u32 sensors_pdrv_attrs_registered:1; |
320 | u32 sensors_pdev_attrs_registered:1; | 320 | u32 sensors_pdev_attrs_registered:1; |
321 | u32 hotkey_poll_active:1; | 321 | u32 hotkey_poll_active:1; |
322 | u32 has_adaptive_kbd:1; | ||
322 | } tp_features; | 323 | } tp_features; |
323 | 324 | ||
324 | static struct { | 325 | static struct { |
@@ -1911,6 +1912,27 @@ enum { /* hot key scan codes (derived from ACPI DSDT) */ | |||
1911 | TP_ACPI_HOTKEYSCAN_UNK7, | 1912 | TP_ACPI_HOTKEYSCAN_UNK7, |
1912 | TP_ACPI_HOTKEYSCAN_UNK8, | 1913 | TP_ACPI_HOTKEYSCAN_UNK8, |
1913 | 1914 | ||
1915 | TP_ACPI_HOTKEYSCAN_MUTE2, | ||
1916 | TP_ACPI_HOTKEYSCAN_BRIGHTNESS_ZERO, | ||
1917 | TP_ACPI_HOTKEYSCAN_CLIPPING_TOOL, | ||
1918 | TP_ACPI_HOTKEYSCAN_CLOUD, | ||
1919 | TP_ACPI_HOTKEYSCAN_UNK9, | ||
1920 | TP_ACPI_HOTKEYSCAN_VOICE, | ||
1921 | TP_ACPI_HOTKEYSCAN_UNK10, | ||
1922 | TP_ACPI_HOTKEYSCAN_GESTURES, | ||
1923 | TP_ACPI_HOTKEYSCAN_UNK11, | ||
1924 | TP_ACPI_HOTKEYSCAN_UNK12, | ||
1925 | TP_ACPI_HOTKEYSCAN_UNK13, | ||
1926 | TP_ACPI_HOTKEYSCAN_CONFIG, | ||
1927 | TP_ACPI_HOTKEYSCAN_NEW_TAB, | ||
1928 | TP_ACPI_HOTKEYSCAN_RELOAD, | ||
1929 | TP_ACPI_HOTKEYSCAN_BACK, | ||
1930 | TP_ACPI_HOTKEYSCAN_MIC_DOWN, | ||
1931 | TP_ACPI_HOTKEYSCAN_MIC_UP, | ||
1932 | TP_ACPI_HOTKEYSCAN_MIC_CANCELLATION, | ||
1933 | TP_ACPI_HOTKEYSCAN_CAMERA_MODE, | ||
1934 | TP_ACPI_HOTKEYSCAN_ROTATE_DISPLAY, | ||
1935 | |||
1914 | /* Hotkey keymap size */ | 1936 | /* Hotkey keymap size */ |
1915 | TPACPI_HOTKEY_MAP_LEN | 1937 | TPACPI_HOTKEY_MAP_LEN |
1916 | }; | 1938 | }; |
@@ -2647,9 +2669,7 @@ static ssize_t hotkey_enable_store(struct device *dev, | |||
2647 | return count; | 2669 | return count; |
2648 | } | 2670 | } |
2649 | 2671 | ||
2650 | static struct device_attribute dev_attr_hotkey_enable = | 2672 | static DEVICE_ATTR_RW(hotkey_enable); |
2651 | __ATTR(hotkey_enable, S_IWUSR | S_IRUGO, | ||
2652 | hotkey_enable_show, hotkey_enable_store); | ||
2653 | 2673 | ||
2654 | /* sysfs hotkey mask --------------------------------------------------- */ | 2674 | /* sysfs hotkey mask --------------------------------------------------- */ |
2655 | static ssize_t hotkey_mask_show(struct device *dev, | 2675 | static ssize_t hotkey_mask_show(struct device *dev, |
@@ -2685,9 +2705,7 @@ static ssize_t hotkey_mask_store(struct device *dev, | |||
2685 | return (res) ? res : count; | 2705 | return (res) ? res : count; |
2686 | } | 2706 | } |
2687 | 2707 | ||
2688 | static struct device_attribute dev_attr_hotkey_mask = | 2708 | static DEVICE_ATTR_RW(hotkey_mask); |
2689 | __ATTR(hotkey_mask, S_IWUSR | S_IRUGO, | ||
2690 | hotkey_mask_show, hotkey_mask_store); | ||
2691 | 2709 | ||
2692 | /* sysfs hotkey bios_enabled ------------------------------------------- */ | 2710 | /* sysfs hotkey bios_enabled ------------------------------------------- */ |
2693 | static ssize_t hotkey_bios_enabled_show(struct device *dev, | 2711 | static ssize_t hotkey_bios_enabled_show(struct device *dev, |
@@ -2697,8 +2715,7 @@ static ssize_t hotkey_bios_enabled_show(struct device *dev, | |||
2697 | return sprintf(buf, "0\n"); | 2715 | return sprintf(buf, "0\n"); |
2698 | } | 2716 | } |
2699 | 2717 | ||
2700 | static struct device_attribute dev_attr_hotkey_bios_enabled = | 2718 | static DEVICE_ATTR_RO(hotkey_bios_enabled); |
2701 | __ATTR(hotkey_bios_enabled, S_IRUGO, hotkey_bios_enabled_show, NULL); | ||
2702 | 2719 | ||
2703 | /* sysfs hotkey bios_mask ---------------------------------------------- */ | 2720 | /* sysfs hotkey bios_mask ---------------------------------------------- */ |
2704 | static ssize_t hotkey_bios_mask_show(struct device *dev, | 2721 | static ssize_t hotkey_bios_mask_show(struct device *dev, |
@@ -2710,8 +2727,7 @@ static ssize_t hotkey_bios_mask_show(struct device *dev, | |||
2710 | return snprintf(buf, PAGE_SIZE, "0x%08x\n", hotkey_orig_mask); | 2727 | return snprintf(buf, PAGE_SIZE, "0x%08x\n", hotkey_orig_mask); |
2711 | } | 2728 | } |
2712 | 2729 | ||
2713 | static struct device_attribute dev_attr_hotkey_bios_mask = | 2730 | static DEVICE_ATTR_RO(hotkey_bios_mask); |
2714 | __ATTR(hotkey_bios_mask, S_IRUGO, hotkey_bios_mask_show, NULL); | ||
2715 | 2731 | ||
2716 | /* sysfs hotkey all_mask ----------------------------------------------- */ | 2732 | /* sysfs hotkey all_mask ----------------------------------------------- */ |
2717 | static ssize_t hotkey_all_mask_show(struct device *dev, | 2733 | static ssize_t hotkey_all_mask_show(struct device *dev, |
@@ -2722,8 +2738,7 @@ static ssize_t hotkey_all_mask_show(struct device *dev, | |||
2722 | hotkey_all_mask | hotkey_source_mask); | 2738 | hotkey_all_mask | hotkey_source_mask); |
2723 | } | 2739 | } |
2724 | 2740 | ||
2725 | static struct device_attribute dev_attr_hotkey_all_mask = | 2741 | static DEVICE_ATTR_RO(hotkey_all_mask); |
2726 | __ATTR(hotkey_all_mask, S_IRUGO, hotkey_all_mask_show, NULL); | ||
2727 | 2742 | ||
2728 | /* sysfs hotkey recommended_mask --------------------------------------- */ | 2743 | /* sysfs hotkey recommended_mask --------------------------------------- */ |
2729 | static ssize_t hotkey_recommended_mask_show(struct device *dev, | 2744 | static ssize_t hotkey_recommended_mask_show(struct device *dev, |
@@ -2735,9 +2750,7 @@ static ssize_t hotkey_recommended_mask_show(struct device *dev, | |||
2735 | & ~hotkey_reserved_mask); | 2750 | & ~hotkey_reserved_mask); |
2736 | } | 2751 | } |
2737 | 2752 | ||
2738 | static struct device_attribute dev_attr_hotkey_recommended_mask = | 2753 | static DEVICE_ATTR_RO(hotkey_recommended_mask); |
2739 | __ATTR(hotkey_recommended_mask, S_IRUGO, | ||
2740 | hotkey_recommended_mask_show, NULL); | ||
2741 | 2754 | ||
2742 | #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL | 2755 | #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL |
2743 | 2756 | ||
@@ -2792,9 +2805,7 @@ static ssize_t hotkey_source_mask_store(struct device *dev, | |||
2792 | return (rc < 0) ? rc : count; | 2805 | return (rc < 0) ? rc : count; |
2793 | } | 2806 | } |
2794 | 2807 | ||
2795 | static struct device_attribute dev_attr_hotkey_source_mask = | 2808 | static DEVICE_ATTR_RW(hotkey_source_mask); |
2796 | __ATTR(hotkey_source_mask, S_IWUSR | S_IRUGO, | ||
2797 | hotkey_source_mask_show, hotkey_source_mask_store); | ||
2798 | 2809 | ||
2799 | /* sysfs hotkey hotkey_poll_freq --------------------------------------- */ | 2810 | /* sysfs hotkey hotkey_poll_freq --------------------------------------- */ |
2800 | static ssize_t hotkey_poll_freq_show(struct device *dev, | 2811 | static ssize_t hotkey_poll_freq_show(struct device *dev, |
@@ -2826,9 +2837,7 @@ static ssize_t hotkey_poll_freq_store(struct device *dev, | |||
2826 | return count; | 2837 | return count; |
2827 | } | 2838 | } |
2828 | 2839 | ||
2829 | static struct device_attribute dev_attr_hotkey_poll_freq = | 2840 | static DEVICE_ATTR_RW(hotkey_poll_freq); |
2830 | __ATTR(hotkey_poll_freq, S_IWUSR | S_IRUGO, | ||
2831 | hotkey_poll_freq_show, hotkey_poll_freq_store); | ||
2832 | 2841 | ||
2833 | #endif /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */ | 2842 | #endif /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */ |
2834 | 2843 | ||
@@ -2849,8 +2858,7 @@ static ssize_t hotkey_radio_sw_show(struct device *dev, | |||
2849 | (res == TPACPI_RFK_RADIO_OFF) ? 0 : 1); | 2858 | (res == TPACPI_RFK_RADIO_OFF) ? 0 : 1); |
2850 | } | 2859 | } |
2851 | 2860 | ||
2852 | static struct device_attribute dev_attr_hotkey_radio_sw = | 2861 | static DEVICE_ATTR_RO(hotkey_radio_sw); |
2853 | __ATTR(hotkey_radio_sw, S_IRUGO, hotkey_radio_sw_show, NULL); | ||
2854 | 2862 | ||
2855 | static void hotkey_radio_sw_notify_change(void) | 2863 | static void hotkey_radio_sw_notify_change(void) |
2856 | { | 2864 | { |
@@ -2872,8 +2880,7 @@ static ssize_t hotkey_tablet_mode_show(struct device *dev, | |||
2872 | return snprintf(buf, PAGE_SIZE, "%d\n", !!s); | 2880 | return snprintf(buf, PAGE_SIZE, "%d\n", !!s); |
2873 | } | 2881 | } |
2874 | 2882 | ||
2875 | static struct device_attribute dev_attr_hotkey_tablet_mode = | 2883 | static DEVICE_ATTR_RO(hotkey_tablet_mode); |
2876 | __ATTR(hotkey_tablet_mode, S_IRUGO, hotkey_tablet_mode_show, NULL); | ||
2877 | 2884 | ||
2878 | static void hotkey_tablet_mode_notify_change(void) | 2885 | static void hotkey_tablet_mode_notify_change(void) |
2879 | { | 2886 | { |
@@ -2890,8 +2897,7 @@ static ssize_t hotkey_wakeup_reason_show(struct device *dev, | |||
2890 | return snprintf(buf, PAGE_SIZE, "%d\n", hotkey_wakeup_reason); | 2897 | return snprintf(buf, PAGE_SIZE, "%d\n", hotkey_wakeup_reason); |
2891 | } | 2898 | } |
2892 | 2899 | ||
2893 | static struct device_attribute dev_attr_hotkey_wakeup_reason = | 2900 | static DEVICE_ATTR_RO(hotkey_wakeup_reason); |
2894 | __ATTR(wakeup_reason, S_IRUGO, hotkey_wakeup_reason_show, NULL); | ||
2895 | 2901 | ||
2896 | static void hotkey_wakeup_reason_notify_change(void) | 2902 | static void hotkey_wakeup_reason_notify_change(void) |
2897 | { | 2903 | { |
@@ -2907,9 +2913,7 @@ static ssize_t hotkey_wakeup_hotunplug_complete_show(struct device *dev, | |||
2907 | return snprintf(buf, PAGE_SIZE, "%d\n", hotkey_autosleep_ack); | 2913 | return snprintf(buf, PAGE_SIZE, "%d\n", hotkey_autosleep_ack); |
2908 | } | 2914 | } |
2909 | 2915 | ||
2910 | static struct device_attribute dev_attr_hotkey_wakeup_hotunplug_complete = | 2916 | static DEVICE_ATTR_RO(hotkey_wakeup_hotunplug_complete); |
2911 | __ATTR(wakeup_hotunplug_complete, S_IRUGO, | ||
2912 | hotkey_wakeup_hotunplug_complete_show, NULL); | ||
2913 | 2917 | ||
2914 | static void hotkey_wakeup_hotunplug_complete_notify_change(void) | 2918 | static void hotkey_wakeup_hotunplug_complete_notify_change(void) |
2915 | { | 2919 | { |
@@ -2917,6 +2921,57 @@ static void hotkey_wakeup_hotunplug_complete_notify_change(void) | |||
2917 | "wakeup_hotunplug_complete"); | 2921 | "wakeup_hotunplug_complete"); |
2918 | } | 2922 | } |
2919 | 2923 | ||
2924 | /* sysfs adaptive kbd mode --------------------------------------------- */ | ||
2925 | |||
2926 | static int adaptive_keyboard_get_mode(void); | ||
2927 | static int adaptive_keyboard_set_mode(int new_mode); | ||
2928 | |||
2929 | enum ADAPTIVE_KEY_MODE { | ||
2930 | HOME_MODE, | ||
2931 | WEB_BROWSER_MODE, | ||
2932 | WEB_CONFERENCE_MODE, | ||
2933 | FUNCTION_MODE, | ||
2934 | LAYFLAT_MODE | ||
2935 | }; | ||
2936 | |||
2937 | static ssize_t adaptive_kbd_mode_show(struct device *dev, | ||
2938 | struct device_attribute *attr, | ||
2939 | char *buf) | ||
2940 | { | ||
2941 | int current_mode; | ||
2942 | |||
2943 | current_mode = adaptive_keyboard_get_mode(); | ||
2944 | if (current_mode < 0) | ||
2945 | return current_mode; | ||
2946 | |||
2947 | return snprintf(buf, PAGE_SIZE, "%d\n", current_mode); | ||
2948 | } | ||
2949 | |||
2950 | static ssize_t adaptive_kbd_mode_store(struct device *dev, | ||
2951 | struct device_attribute *attr, | ||
2952 | const char *buf, size_t count) | ||
2953 | { | ||
2954 | unsigned long t; | ||
2955 | int res; | ||
2956 | |||
2957 | if (parse_strtoul(buf, LAYFLAT_MODE, &t)) | ||
2958 | return -EINVAL; | ||
2959 | |||
2960 | res = adaptive_keyboard_set_mode(t); | ||
2961 | return (res < 0) ? res : count; | ||
2962 | } | ||
2963 | |||
2964 | static DEVICE_ATTR_RW(adaptive_kbd_mode); | ||
2965 | |||
2966 | static struct attribute *adaptive_kbd_attributes[] = { | ||
2967 | &dev_attr_adaptive_kbd_mode.attr, | ||
2968 | NULL | ||
2969 | }; | ||
2970 | |||
2971 | static const struct attribute_group adaptive_kbd_attr_group = { | ||
2972 | .attrs = adaptive_kbd_attributes, | ||
2973 | }; | ||
2974 | |||
2920 | /* --------------------------------------------------------------------- */ | 2975 | /* --------------------------------------------------------------------- */ |
2921 | 2976 | ||
2922 | static struct attribute *hotkey_attributes[] __initdata = { | 2977 | static struct attribute *hotkey_attributes[] __initdata = { |
@@ -3118,6 +3173,13 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
3118 | /* (assignments unknown, please report if found) */ | 3173 | /* (assignments unknown, please report if found) */ |
3119 | KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, | 3174 | KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, |
3120 | KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, | 3175 | KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, |
3176 | |||
3177 | /* No assignments, only used for Adaptive keyboards. */ | ||
3178 | KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, | ||
3179 | KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, | ||
3180 | KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, | ||
3181 | KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, | ||
3182 | KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, | ||
3121 | }, | 3183 | }, |
3122 | 3184 | ||
3123 | /* Generic keymap for Lenovo ThinkPads */ | 3185 | /* Generic keymap for Lenovo ThinkPads */ |
@@ -3174,6 +3236,35 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
3174 | 3236 | ||
3175 | /* Extra keys in use since the X240 / T440 / T540 */ | 3237 | /* Extra keys in use since the X240 / T440 / T540 */ |
3176 | KEY_CONFIG, KEY_SEARCH, KEY_SCALE, KEY_FILE, | 3238 | KEY_CONFIG, KEY_SEARCH, KEY_SCALE, KEY_FILE, |
3239 | |||
3240 | /* | ||
3241 | * These are the adaptive keyboard keycodes for Carbon X1 2014. | ||
3242 | * The first item in this list is the Mute button which is | ||
3243 | * emitted with 0x103 through | ||
3244 | * adaptive_keyboard_hotkey_notify_hotkey() when the sound | ||
3245 | * symbol is held. | ||
3246 | * We'll need to offset those by 0x20. | ||
3247 | */ | ||
3248 | KEY_RESERVED, /* Mute held, 0x103 */ | ||
3249 | KEY_BRIGHTNESS_MIN, /* Backlight off */ | ||
3250 | KEY_RESERVED, /* Clipping tool */ | ||
3251 | KEY_RESERVED, /* Cloud */ | ||
3252 | KEY_RESERVED, | ||
3253 | KEY_VOICECOMMAND, /* Voice */ | ||
3254 | KEY_RESERVED, | ||
3255 | KEY_RESERVED, /* Gestures */ | ||
3256 | KEY_RESERVED, | ||
3257 | KEY_RESERVED, | ||
3258 | KEY_RESERVED, | ||
3259 | KEY_CONFIG, /* Settings */ | ||
3260 | KEY_RESERVED, /* New tab */ | ||
3261 | KEY_REFRESH, /* Reload */ | ||
3262 | KEY_BACK, /* Back */ | ||
3263 | KEY_RESERVED, /* Microphone down */ | ||
3264 | KEY_RESERVED, /* Microphone up */ | ||
3265 | KEY_RESERVED, /* Microphone cancellation */ | ||
3266 | KEY_RESERVED, /* Camera mode */ | ||
3267 | KEY_RESERVED, /* Rotate display, 0x116 */ | ||
3177 | }, | 3268 | }, |
3178 | }; | 3269 | }; |
3179 | 3270 | ||
@@ -3227,6 +3318,20 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
3227 | if (!tp_features.hotkey) | 3318 | if (!tp_features.hotkey) |
3228 | return 1; | 3319 | return 1; |
3229 | 3320 | ||
3321 | /* | ||
3322 | * Check if we have an adaptive keyboard, like on the | ||
3323 | * Lenovo Carbon X1 2014 (2nd Gen). | ||
3324 | */ | ||
3325 | if (acpi_evalf(hkey_handle, &hkeyv, "MHKV", "qd")) { | ||
3326 | if ((hkeyv >> 8) == 2) { | ||
3327 | tp_features.has_adaptive_kbd = true; | ||
3328 | res = sysfs_create_group(&tpacpi_pdev->dev.kobj, | ||
3329 | &adaptive_kbd_attr_group); | ||
3330 | if (res) | ||
3331 | goto err_exit; | ||
3332 | } | ||
3333 | } | ||
3334 | |||
3230 | quirks = tpacpi_check_quirks(tpacpi_hotkey_qtable, | 3335 | quirks = tpacpi_check_quirks(tpacpi_hotkey_qtable, |
3231 | ARRAY_SIZE(tpacpi_hotkey_qtable)); | 3336 | ARRAY_SIZE(tpacpi_hotkey_qtable)); |
3232 | 3337 | ||
@@ -3437,6 +3542,9 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
3437 | 3542 | ||
3438 | err_exit: | 3543 | err_exit: |
3439 | delete_attr_set(hotkey_dev_attributes, &tpacpi_pdev->dev.kobj); | 3544 | delete_attr_set(hotkey_dev_attributes, &tpacpi_pdev->dev.kobj); |
3545 | sysfs_remove_group(&tpacpi_pdev->dev.kobj, | ||
3546 | &adaptive_kbd_attr_group); | ||
3547 | |||
3440 | hotkey_dev_attributes = NULL; | 3548 | hotkey_dev_attributes = NULL; |
3441 | 3549 | ||
3442 | return (res < 0) ? res : 1; | 3550 | return (res < 0) ? res : 1; |
@@ -3449,14 +3557,6 @@ err_exit: | |||
3449 | * Will consider support rest of modes in future. | 3557 | * Will consider support rest of modes in future. |
3450 | * | 3558 | * |
3451 | */ | 3559 | */ |
3452 | enum ADAPTIVE_KEY_MODE { | ||
3453 | HOME_MODE, | ||
3454 | WEB_BROWSER_MODE, | ||
3455 | WEB_CONFERENCE_MODE, | ||
3456 | FUNCTION_MODE, | ||
3457 | LAYFLAT_MODE | ||
3458 | }; | ||
3459 | |||
3460 | static const int adaptive_keyboard_modes[] = { | 3560 | static const int adaptive_keyboard_modes[] = { |
3461 | HOME_MODE, | 3561 | HOME_MODE, |
3462 | /* WEB_BROWSER_MODE = 2, | 3562 | /* WEB_BROWSER_MODE = 2, |
@@ -3466,6 +3566,8 @@ static const int adaptive_keyboard_modes[] = { | |||
3466 | 3566 | ||
3467 | #define DFR_CHANGE_ROW 0x101 | 3567 | #define DFR_CHANGE_ROW 0x101 |
3468 | #define DFR_SHOW_QUICKVIEW_ROW 0x102 | 3568 | #define DFR_SHOW_QUICKVIEW_ROW 0x102 |
3569 | #define FIRST_ADAPTIVE_KEY 0x103 | ||
3570 | #define ADAPTIVE_KEY_OFFSET 0x020 | ||
3469 | 3571 | ||
3470 | /* press Fn key a while second, it will switch to Function Mode. Then | 3572 | /* press Fn key a while second, it will switch to Function Mode. Then |
3471 | * release Fn key, previous mode be restored. | 3573 | * release Fn key, previous mode be restored. |
@@ -3473,6 +3575,32 @@ static const int adaptive_keyboard_modes[] = { | |||
3473 | static bool adaptive_keyboard_mode_is_saved; | 3575 | static bool adaptive_keyboard_mode_is_saved; |
3474 | static int adaptive_keyboard_prev_mode; | 3576 | static int adaptive_keyboard_prev_mode; |
3475 | 3577 | ||
3578 | static int adaptive_keyboard_get_mode(void) | ||
3579 | { | ||
3580 | int mode = 0; | ||
3581 | |||
3582 | if (!acpi_evalf(hkey_handle, &mode, "GTRW", "dd", 0)) { | ||
3583 | pr_err("Cannot read adaptive keyboard mode\n"); | ||
3584 | return -EIO; | ||
3585 | } | ||
3586 | |||
3587 | return mode; | ||
3588 | } | ||
3589 | |||
3590 | static int adaptive_keyboard_set_mode(int new_mode) | ||
3591 | { | ||
3592 | if (new_mode < 0 || | ||
3593 | new_mode > LAYFLAT_MODE) | ||
3594 | return -EINVAL; | ||
3595 | |||
3596 | if (!acpi_evalf(hkey_handle, NULL, "STRW", "vd", new_mode)) { | ||
3597 | pr_err("Cannot set adaptive keyboard mode\n"); | ||
3598 | return -EIO; | ||
3599 | } | ||
3600 | |||
3601 | return 0; | ||
3602 | } | ||
3603 | |||
3476 | static int adaptive_keyboard_get_next_mode(int mode) | 3604 | static int adaptive_keyboard_get_next_mode(int mode) |
3477 | { | 3605 | { |
3478 | size_t i; | 3606 | size_t i; |
@@ -3493,8 +3621,9 @@ static int adaptive_keyboard_get_next_mode(int mode) | |||
3493 | 3621 | ||
3494 | static bool adaptive_keyboard_hotkey_notify_hotkey(unsigned int scancode) | 3622 | static bool adaptive_keyboard_hotkey_notify_hotkey(unsigned int scancode) |
3495 | { | 3623 | { |
3496 | u32 current_mode = 0; | 3624 | int current_mode = 0; |
3497 | int new_mode = 0; | 3625 | int new_mode = 0; |
3626 | int keycode; | ||
3498 | 3627 | ||
3499 | switch (scancode) { | 3628 | switch (scancode) { |
3500 | case DFR_CHANGE_ROW: | 3629 | case DFR_CHANGE_ROW: |
@@ -3502,43 +3631,51 @@ static bool adaptive_keyboard_hotkey_notify_hotkey(unsigned int scancode) | |||
3502 | new_mode = adaptive_keyboard_prev_mode; | 3631 | new_mode = adaptive_keyboard_prev_mode; |
3503 | adaptive_keyboard_mode_is_saved = false; | 3632 | adaptive_keyboard_mode_is_saved = false; |
3504 | } else { | 3633 | } else { |
3505 | if (!acpi_evalf( | 3634 | current_mode = adaptive_keyboard_get_mode(); |
3506 | hkey_handle, ¤t_mode, | 3635 | if (current_mode < 0) |
3507 | "GTRW", "dd", 0)) { | ||
3508 | pr_err("Cannot read adaptive keyboard mode\n"); | ||
3509 | return false; | 3636 | return false; |
3510 | } else { | 3637 | new_mode = adaptive_keyboard_get_next_mode( |
3511 | new_mode = adaptive_keyboard_get_next_mode( | 3638 | current_mode); |
3512 | current_mode); | ||
3513 | } | ||
3514 | } | 3639 | } |
3515 | 3640 | ||
3516 | if (!acpi_evalf(hkey_handle, NULL, "STRW", "vd", new_mode)) { | 3641 | if (adaptive_keyboard_set_mode(new_mode) < 0) |
3517 | pr_err("Cannot set adaptive keyboard mode\n"); | ||
3518 | return false; | 3642 | return false; |
3519 | } | ||
3520 | 3643 | ||
3521 | return true; | 3644 | return true; |
3522 | 3645 | ||
3523 | case DFR_SHOW_QUICKVIEW_ROW: | 3646 | case DFR_SHOW_QUICKVIEW_ROW: |
3524 | if (!acpi_evalf(hkey_handle, | 3647 | current_mode = adaptive_keyboard_get_mode(); |
3525 | &adaptive_keyboard_prev_mode, | 3648 | if (current_mode < 0) |
3526 | "GTRW", "dd", 0)) { | ||
3527 | pr_err("Cannot read adaptive keyboard mode\n"); | ||
3528 | return false; | 3649 | return false; |
3529 | } else { | ||
3530 | adaptive_keyboard_mode_is_saved = true; | ||
3531 | 3650 | ||
3532 | if (!acpi_evalf(hkey_handle, | 3651 | adaptive_keyboard_prev_mode = current_mode; |
3533 | NULL, "STRW", "vd", FUNCTION_MODE)) { | 3652 | adaptive_keyboard_mode_is_saved = true; |
3534 | pr_err("Cannot set adaptive keyboard mode\n"); | 3653 | |
3535 | return false; | 3654 | if (adaptive_keyboard_set_mode (FUNCTION_MODE) < 0) |
3536 | } | 3655 | return false; |
3537 | } | ||
3538 | return true; | 3656 | return true; |
3539 | 3657 | ||
3540 | default: | 3658 | default: |
3541 | return false; | 3659 | if (scancode < FIRST_ADAPTIVE_KEY || |
3660 | scancode >= FIRST_ADAPTIVE_KEY + TPACPI_HOTKEY_MAP_LEN - | ||
3661 | ADAPTIVE_KEY_OFFSET) { | ||
3662 | pr_info("Unhandled adaptive keyboard key: 0x%x\n", | ||
3663 | scancode); | ||
3664 | return false; | ||
3665 | } | ||
3666 | keycode = hotkey_keycode_map[scancode - FIRST_ADAPTIVE_KEY + ADAPTIVE_KEY_OFFSET]; | ||
3667 | if (keycode != KEY_RESERVED) { | ||
3668 | mutex_lock(&tpacpi_inputdev_send_mutex); | ||
3669 | |||
3670 | input_report_key(tpacpi_inputdev, keycode, 1); | ||
3671 | input_sync(tpacpi_inputdev); | ||
3672 | |||
3673 | input_report_key(tpacpi_inputdev, keycode, 0); | ||
3674 | input_sync(tpacpi_inputdev); | ||
3675 | |||
3676 | mutex_unlock(&tpacpi_inputdev_send_mutex); | ||
3677 | } | ||
3678 | return true; | ||
3542 | } | 3679 | } |
3543 | } | 3680 | } |
3544 | 3681 | ||
@@ -3836,28 +3973,21 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event) | |||
3836 | 3973 | ||
3837 | static void hotkey_suspend(void) | 3974 | static void hotkey_suspend(void) |
3838 | { | 3975 | { |
3839 | int hkeyv; | ||
3840 | |||
3841 | /* Do these on suspend, we get the events on early resume! */ | 3976 | /* Do these on suspend, we get the events on early resume! */ |
3842 | hotkey_wakeup_reason = TP_ACPI_WAKEUP_NONE; | 3977 | hotkey_wakeup_reason = TP_ACPI_WAKEUP_NONE; |
3843 | hotkey_autosleep_ack = 0; | 3978 | hotkey_autosleep_ack = 0; |
3844 | 3979 | ||
3845 | /* save previous mode of adaptive keyboard of X1 Carbon */ | 3980 | /* save previous mode of adaptive keyboard of X1 Carbon */ |
3846 | if (acpi_evalf(hkey_handle, &hkeyv, "MHKV", "qd")) { | 3981 | if (tp_features.has_adaptive_kbd) { |
3847 | if ((hkeyv >> 8) == 2) { | 3982 | if (!acpi_evalf(hkey_handle, &adaptive_keyboard_prev_mode, |
3848 | if (!acpi_evalf(hkey_handle, | 3983 | "GTRW", "dd", 0)) { |
3849 | &adaptive_keyboard_prev_mode, | 3984 | pr_err("Cannot read adaptive keyboard mode.\n"); |
3850 | "GTRW", "dd", 0)) { | ||
3851 | pr_err("Cannot read adaptive keyboard mode.\n"); | ||
3852 | } | ||
3853 | } | 3985 | } |
3854 | } | 3986 | } |
3855 | } | 3987 | } |
3856 | 3988 | ||
3857 | static void hotkey_resume(void) | 3989 | static void hotkey_resume(void) |
3858 | { | 3990 | { |
3859 | int hkeyv; | ||
3860 | |||
3861 | tpacpi_disable_brightness_delay(); | 3991 | tpacpi_disable_brightness_delay(); |
3862 | 3992 | ||
3863 | if (hotkey_status_set(true) < 0 || | 3993 | if (hotkey_status_set(true) < 0 || |
@@ -3872,14 +4002,10 @@ static void hotkey_resume(void) | |||
3872 | hotkey_poll_setup_safe(false); | 4002 | hotkey_poll_setup_safe(false); |
3873 | 4003 | ||
3874 | /* restore previous mode of adapive keyboard of X1 Carbon */ | 4004 | /* restore previous mode of adapive keyboard of X1 Carbon */ |
3875 | if (acpi_evalf(hkey_handle, &hkeyv, "MHKV", "qd")) { | 4005 | if (tp_features.has_adaptive_kbd) { |
3876 | if ((hkeyv >> 8) == 2) { | 4006 | if (!acpi_evalf(hkey_handle, NULL, "STRW", "vd", |
3877 | if (!acpi_evalf(hkey_handle, | 4007 | adaptive_keyboard_prev_mode)) { |
3878 | NULL, | 4008 | pr_err("Cannot set adaptive keyboard mode.\n"); |
3879 | "STRW", "vd", | ||
3880 | adaptive_keyboard_prev_mode)) { | ||
3881 | pr_err("Cannot set adaptive keyboard mode.\n"); | ||
3882 | } | ||
3883 | } | 4009 | } |
3884 | } | 4010 | } |
3885 | } | 4011 | } |
@@ -4079,9 +4205,7 @@ static ssize_t bluetooth_enable_store(struct device *dev, | |||
4079 | attr, buf, count); | 4205 | attr, buf, count); |
4080 | } | 4206 | } |
4081 | 4207 | ||
4082 | static struct device_attribute dev_attr_bluetooth_enable = | 4208 | static DEVICE_ATTR_RW(bluetooth_enable); |
4083 | __ATTR(bluetooth_enable, S_IWUSR | S_IRUGO, | ||
4084 | bluetooth_enable_show, bluetooth_enable_store); | ||
4085 | 4209 | ||
4086 | /* --------------------------------------------------------------------- */ | 4210 | /* --------------------------------------------------------------------- */ |
4087 | 4211 | ||
@@ -4269,9 +4393,7 @@ static ssize_t wan_enable_store(struct device *dev, | |||
4269 | attr, buf, count); | 4393 | attr, buf, count); |
4270 | } | 4394 | } |
4271 | 4395 | ||
4272 | static struct device_attribute dev_attr_wan_enable = | 4396 | static DEVICE_ATTR_RW(wan_enable); |
4273 | __ATTR(wwan_enable, S_IWUSR | S_IRUGO, | ||
4274 | wan_enable_show, wan_enable_store); | ||
4275 | 4397 | ||
4276 | /* --------------------------------------------------------------------- */ | 4398 | /* --------------------------------------------------------------------- */ |
4277 | 4399 | ||
@@ -5048,8 +5170,7 @@ static ssize_t cmos_command_store(struct device *dev, | |||
5048 | return (res) ? res : count; | 5170 | return (res) ? res : count; |
5049 | } | 5171 | } |
5050 | 5172 | ||
5051 | static struct device_attribute dev_attr_cmos_command = | 5173 | static DEVICE_ATTR_WO(cmos_command); |
5052 | __ATTR(cmos_command, S_IWUSR, NULL, cmos_command_store); | ||
5053 | 5174 | ||
5054 | /* --------------------------------------------------------------------- */ | 5175 | /* --------------------------------------------------------------------- */ |
5055 | 5176 | ||
@@ -8017,9 +8138,7 @@ static ssize_t fan_pwm1_enable_store(struct device *dev, | |||
8017 | return count; | 8138 | return count; |
8018 | } | 8139 | } |
8019 | 8140 | ||
8020 | static struct device_attribute dev_attr_fan_pwm1_enable = | 8141 | static DEVICE_ATTR_RW(fan_pwm1_enable); |
8021 | __ATTR(pwm1_enable, S_IWUSR | S_IRUGO, | ||
8022 | fan_pwm1_enable_show, fan_pwm1_enable_store); | ||
8023 | 8142 | ||
8024 | /* sysfs fan pwm1 ------------------------------------------------------ */ | 8143 | /* sysfs fan pwm1 ------------------------------------------------------ */ |
8025 | static ssize_t fan_pwm1_show(struct device *dev, | 8144 | static ssize_t fan_pwm1_show(struct device *dev, |
@@ -8079,9 +8198,7 @@ static ssize_t fan_pwm1_store(struct device *dev, | |||
8079 | return (rc) ? rc : count; | 8198 | return (rc) ? rc : count; |
8080 | } | 8199 | } |
8081 | 8200 | ||
8082 | static struct device_attribute dev_attr_fan_pwm1 = | 8201 | static DEVICE_ATTR_RW(fan_pwm1); |
8083 | __ATTR(pwm1, S_IWUSR | S_IRUGO, | ||
8084 | fan_pwm1_show, fan_pwm1_store); | ||
8085 | 8202 | ||
8086 | /* sysfs fan fan1_input ------------------------------------------------ */ | 8203 | /* sysfs fan fan1_input ------------------------------------------------ */ |
8087 | static ssize_t fan_fan1_input_show(struct device *dev, | 8204 | static ssize_t fan_fan1_input_show(struct device *dev, |
@@ -8098,9 +8215,7 @@ static ssize_t fan_fan1_input_show(struct device *dev, | |||
8098 | return snprintf(buf, PAGE_SIZE, "%u\n", speed); | 8215 | return snprintf(buf, PAGE_SIZE, "%u\n", speed); |
8099 | } | 8216 | } |
8100 | 8217 | ||
8101 | static struct device_attribute dev_attr_fan_fan1_input = | 8218 | static DEVICE_ATTR_RO(fan_fan1_input); |
8102 | __ATTR(fan1_input, S_IRUGO, | ||
8103 | fan_fan1_input_show, NULL); | ||
8104 | 8219 | ||
8105 | /* sysfs fan fan2_input ------------------------------------------------ */ | 8220 | /* sysfs fan fan2_input ------------------------------------------------ */ |
8106 | static ssize_t fan_fan2_input_show(struct device *dev, | 8221 | static ssize_t fan_fan2_input_show(struct device *dev, |
@@ -8117,9 +8232,7 @@ static ssize_t fan_fan2_input_show(struct device *dev, | |||
8117 | return snprintf(buf, PAGE_SIZE, "%u\n", speed); | 8232 | return snprintf(buf, PAGE_SIZE, "%u\n", speed); |
8118 | } | 8233 | } |
8119 | 8234 | ||
8120 | static struct device_attribute dev_attr_fan_fan2_input = | 8235 | static DEVICE_ATTR_RO(fan_fan2_input); |
8121 | __ATTR(fan2_input, S_IRUGO, | ||
8122 | fan_fan2_input_show, NULL); | ||
8123 | 8236 | ||
8124 | /* sysfs fan fan_watchdog (hwmon driver) ------------------------------- */ | 8237 | /* sysfs fan fan_watchdog (hwmon driver) ------------------------------- */ |
8125 | static ssize_t fan_fan_watchdog_show(struct device_driver *drv, | 8238 | static ssize_t fan_fan_watchdog_show(struct device_driver *drv, |
@@ -8735,8 +8848,7 @@ static ssize_t thinkpad_acpi_pdev_name_show(struct device *dev, | |||
8735 | return snprintf(buf, PAGE_SIZE, "%s\n", TPACPI_NAME); | 8848 | return snprintf(buf, PAGE_SIZE, "%s\n", TPACPI_NAME); |
8736 | } | 8849 | } |
8737 | 8850 | ||
8738 | static struct device_attribute dev_attr_thinkpad_acpi_pdev_name = | 8851 | static DEVICE_ATTR_RO(thinkpad_acpi_pdev_name); |
8739 | __ATTR(name, S_IRUGO, thinkpad_acpi_pdev_name_show, NULL); | ||
8740 | 8852 | ||
8741 | /* --------------------------------------------------------------------- */ | 8853 | /* --------------------------------------------------------------------- */ |
8742 | 8854 | ||