1313#include <linux/kernel.h>
1414#include <linux/module.h>
1515#include <linux/platform_device.h>
16+ #include <linux/string_choices.h>
1617#include <linux/suspend.h>
1718#include "../dual_accel_detect.h"
1819
20+ enum intel_hid_tablet_sw_mode {
21+ TABLET_SW_AUTO = -1 ,
22+ TABLET_SW_OFF = 0 ,
23+ TABLET_SW_AT_EVENT ,
24+ TABLET_SW_AT_PROBE ,
25+ };
26+
27+ static bool enable_5_button_array ;
28+ module_param (enable_5_button_array , bool , 0444 );
29+ MODULE_PARM_DESC (enable_5_button_array ,
30+ "Enable 5 Button Array support. "
31+ "If you need this please report this to: platform-driver-x86@vger.kernel.org" );
32+
33+ static int enable_sw_tablet_mode = TABLET_SW_AUTO ;
34+ module_param (enable_sw_tablet_mode , int , 0444 );
35+ MODULE_PARM_DESC (enable_sw_tablet_mode ,
36+ "Enable SW_TABLET_MODE reporting -1:auto 0:off 1:at-first-event 2:at-probe. "
37+ "If you need this please report this to: platform-driver-x86@vger.kernel.org" );
38+
1939/* When NOT in tablet mode, VGBS returns with the flag 0x40 */
2040#define TABLET_MODE_FLAG BIT(6)
2141
@@ -24,14 +44,18 @@ MODULE_LICENSE("GPL");
2444MODULE_AUTHOR ("Alex Hung" );
2545
2646static const struct acpi_device_id intel_hid_ids [] = {
27- {"INT33D5" , 0 },
28- {"INTC1051" , 0 },
29- {"INTC1054" , 0 },
30- {"INTC1070" , 0 },
31- {"INTC1076" , 0 },
32- {"INTC1077" , 0 },
33- {"INTC1078" , 0 },
34- {"" , 0 },
47+ { "INT33D5" },
48+ { "INTC1051" },
49+ { "INTC1054" },
50+ { "INTC1070" },
51+ { "INTC1076" },
52+ { "INTC1077" },
53+ { "INTC1078" },
54+ { "INTC107B" },
55+ { "INTC10CB" },
56+ { "INTC10CC" },
57+ { "INTC10F1" },
58+ { }
3559};
3660MODULE_DEVICE_TABLE (acpi , intel_hid_ids );
3761
@@ -96,13 +120,34 @@ static const struct dmi_system_id button_array_table[] = {
96120 DMI_MATCH (DMI_PRODUCT_NAME , "HP Spectre x2 Detachable" ),
97121 },
98122 },
123+ {
124+ .ident = "Lenovo ThinkPad X1 Tablet Gen 1" ,
125+ .matches = {
126+ DMI_MATCH (DMI_SYS_VENDOR , "LENOVO" ),
127+ DMI_MATCH (DMI_PRODUCT_FAMILY , "ThinkPad X12 Detachable Gen 1" ),
128+ },
129+ },
99130 {
100131 .ident = "Lenovo ThinkPad X1 Tablet Gen 2" ,
101132 .matches = {
102133 DMI_MATCH (DMI_SYS_VENDOR , "LENOVO" ),
103134 DMI_MATCH (DMI_PRODUCT_FAMILY , "ThinkPad X1 Tablet Gen 2" ),
104135 },
105136 },
137+ {
138+ .ident = "Microsoft Surface Go 3" ,
139+ .matches = {
140+ DMI_MATCH (DMI_SYS_VENDOR , "Microsoft Corporation" ),
141+ DMI_MATCH (DMI_PRODUCT_NAME , "Surface Go 3" ),
142+ },
143+ },
144+ {
145+ .ident = "Microsoft Surface Go 4" ,
146+ .matches = {
147+ DMI_MATCH (DMI_SYS_VENDOR , "Microsoft Corporation" ),
148+ DMI_MATCH (DMI_PRODUCT_NAME , "Surface Go 4" ),
149+ },
150+ },
106151 { }
107152};
108153
@@ -119,15 +164,44 @@ static const struct dmi_system_id dmi_vgbs_allow_list[] = {
119164 DMI_MATCH (DMI_PRODUCT_NAME , "HP Spectre x360 Convertible 15-df0xxx" ),
120165 },
121166 },
167+ {
168+ .matches = {
169+ DMI_MATCH (DMI_SYS_VENDOR , "Microsoft Corporation" ),
170+ DMI_MATCH (DMI_PRODUCT_NAME , "Surface Go" ),
171+ },
172+ },
173+ {
174+ .matches = {
175+ DMI_MATCH (DMI_SYS_VENDOR , "HP" ),
176+ DMI_MATCH (DMI_PRODUCT_NAME , "HP Elite Dragonfly G2 Notebook PC" ),
177+ },
178+ },
122179 { }
123180};
124181
182+ /*
183+ * Some devices, even non convertible ones, can send incorrect SW_TABLET_MODE
184+ * reports. Accept such reports only from devices in this list.
185+ */
186+ static const struct dmi_system_id dmi_auto_add_switch [] = {
187+ {
188+ .matches = {
189+ DMI_EXACT_MATCH (DMI_CHASSIS_TYPE , "31" /* Convertible */ ),
190+ },
191+ },
192+ {
193+ .matches = {
194+ DMI_EXACT_MATCH (DMI_CHASSIS_TYPE , "32" /* Detachable */ ),
195+ },
196+ },
197+ {} /* Array terminator */
198+ };
199+
125200struct intel_hid_priv {
126201 struct input_dev * input_dev ;
127202 struct input_dev * array ;
128203 struct input_dev * switches ;
129204 bool wakeup_mode ;
130- bool dual_accel ;
131205};
132206
133207#define HID_EVENT_FILTER_UUID "eeec56b3-4442-408f-a792-4edd4d758054"
@@ -217,7 +291,7 @@ static bool intel_hid_evaluate_method(acpi_handle handle,
217291
218292 method_name = (char * )intel_hid_dsm_fn_to_method [fn_index ];
219293
220- if (!(intel_hid_dsm_fn_mask & fn_index ))
294+ if (!(intel_hid_dsm_fn_mask & BIT ( fn_index ) ))
221295 goto skip_dsm_eval ;
222296
223297 obj = acpi_evaluate_dsm_typed (handle , & intel_dsm_guid ,
@@ -274,10 +348,8 @@ static int intel_hid_set_enable(struct device *device, bool enable)
274348 acpi_handle handle = ACPI_HANDLE (device );
275349
276350 /* Enable|disable features - power button is always enabled */
277- if (!intel_hid_execute_method (handle , INTEL_HID_DSM_HDSM_FN ,
278- enable )) {
279- dev_warn (device , "failed to %sable hotkeys\n" ,
280- enable ? "en" : "dis" );
351+ if (!intel_hid_execute_method (handle , INTEL_HID_DSM_HDSM_FN , enable )) {
352+ dev_warn (device , "failed to %s hotkeys\n" , str_enable_disable (enable ));
281353 return - EIO ;
282354 }
283355
@@ -450,16 +522,16 @@ static void notify_handler(acpi_handle handle, u32 event, void *context)
450522 struct platform_device * device = context ;
451523 struct intel_hid_priv * priv = dev_get_drvdata (& device -> dev );
452524 unsigned long long ev_index ;
525+ struct key_entry * ke ;
453526 int err ;
454527
455528 /*
456529 * Some convertible have unreliable VGBS return which could cause incorrect
457530 * SW_TABLET_MODE report, in these cases we enable support when receiving
458531 * the first event instead of during driver setup.
459- *
460- * See dual_accel_detect.h for more info on the dual_accel check.
461532 */
462- if (!priv -> switches && !priv -> dual_accel && (event == 0xcc || event == 0xcd )) {
533+ if (!priv -> switches && enable_sw_tablet_mode == TABLET_SW_AT_EVENT &&
534+ (event == 0xcc || event == 0xcd )) {
463535 dev_info (& device -> dev , "switch event received, enable switches supports\n" );
464536 err = intel_hid_switches_setup (device );
465537 if (err )
@@ -492,11 +564,15 @@ static void notify_handler(acpi_handle handle, u32 event, void *context)
492564 if (event == 0xc0 || !priv -> array )
493565 return ;
494566
495- if (!sparse_keymap_entry_from_scancode (priv -> array , event )) {
567+ ke = sparse_keymap_entry_from_scancode (priv -> array , event );
568+ if (!ke ) {
496569 dev_info (& device -> dev , "unknown event 0x%x\n" , event );
497570 return ;
498571 }
499572
573+ if (ke -> type == KE_IGNORE )
574+ return ;
575+
500576wakeup :
501577 pm_wakeup_hard_event (& device -> dev );
502578
@@ -564,7 +640,7 @@ static bool button_array_present(struct platform_device *device)
564640 return true;
565641 }
566642
567- if (dmi_check_system (button_array_table ))
643+ if (enable_5_button_array || dmi_check_system (button_array_table ))
568644 return true;
569645
570646 return false;
@@ -573,7 +649,7 @@ static bool button_array_present(struct platform_device *device)
573649static int intel_hid_probe (struct platform_device * device )
574650{
575651 acpi_handle handle = ACPI_HANDLE (& device -> dev );
576- unsigned long long mode ;
652+ unsigned long long mode , dummy ;
577653 struct intel_hid_priv * priv ;
578654 acpi_status status ;
579655 int err ;
@@ -600,7 +676,15 @@ static int intel_hid_probe(struct platform_device *device)
600676 return - ENOMEM ;
601677 dev_set_drvdata (& device -> dev , priv );
602678
603- priv -> dual_accel = dual_accel_detect ();
679+ /* See dual_accel_detect.h for more info on the dual_accel check. */
680+ if (enable_sw_tablet_mode == TABLET_SW_AUTO ) {
681+ if (dmi_check_system (dmi_vgbs_allow_list ))
682+ enable_sw_tablet_mode = TABLET_SW_AT_PROBE ;
683+ else if (dmi_check_system (dmi_auto_add_switch ) && !dual_accel_detect ())
684+ enable_sw_tablet_mode = TABLET_SW_AT_EVENT ;
685+ else
686+ enable_sw_tablet_mode = TABLET_SW_OFF ;
687+ }
604688
605689 err = intel_hid_input_setup (device );
606690 if (err ) {
@@ -617,7 +701,7 @@ static int intel_hid_probe(struct platform_device *device)
617701 }
618702
619703 /* Setup switches for devices that we know VGBS return correctly */
620- if (dmi_check_system ( dmi_vgbs_allow_list ) ) {
704+ if (enable_sw_tablet_mode == TABLET_SW_AT_PROBE ) {
621705 dev_info (& device -> dev , "platform supports switches\n" );
622706 err = intel_hid_switches_setup (device );
623707 if (err )
@@ -637,18 +721,15 @@ static int intel_hid_probe(struct platform_device *device)
637721 if (err )
638722 goto err_remove_notify ;
639723
640- if (priv -> array ) {
641- unsigned long long dummy ;
642-
643- intel_button_array_enable (& device -> dev , true);
724+ intel_button_array_enable (& device -> dev , true);
644725
645- /* Call button load method to enable HID power button */
646- if (! intel_hid_evaluate_method ( handle , INTEL_HID_DSM_BTNL_FN ,
647- & dummy )) {
648- dev_warn ( & device -> dev ,
649- "failed to enable HID power button\n" );
650- }
651- }
726+ /*
727+ * Call button load method to enable HID power button
728+ * Always do this since it activates events on some devices without
729+ * a button array too.
730+ */
731+ if (! intel_hid_evaluate_method ( handle , INTEL_HID_DSM_BTNL_FN , & dummy ))
732+ dev_warn ( & device -> dev , "failed to enable HID power button\n" );
652733
653734 device_init_wakeup (& device -> dev , true);
654735 /*
@@ -665,20 +746,14 @@ static int intel_hid_probe(struct platform_device *device)
665746 return err ;
666747}
667748
668- static int intel_hid_remove (struct platform_device * device )
749+ static void intel_hid_remove (struct platform_device * device )
669750{
670751 acpi_handle handle = ACPI_HANDLE (& device -> dev );
671752
672753 device_init_wakeup (& device -> dev , false);
673754 acpi_remove_notify_handler (handle , ACPI_DEVICE_NOTIFY , notify_handler );
674755 intel_hid_set_enable (& device -> dev , false);
675756 intel_button_array_enable (& device -> dev , false);
676-
677- /*
678- * Even if we failed to shut off the event stream, we can still
679- * safely detach from the device.
680- */
681- return 0 ;
682757}
683758
684759static struct platform_driver intel_hid_pl_driver = {
@@ -688,7 +763,7 @@ static struct platform_driver intel_hid_pl_driver = {
688763 .pm = & intel_hid_pl_pm_ops ,
689764 },
690765 .probe = intel_hid_probe ,
691- .remove = intel_hid_remove ,
766+ .remove_new = intel_hid_remove ,
692767};
693768
694769/*
@@ -706,12 +781,9 @@ static acpi_status __init
706781check_acpi_dev (acpi_handle handle , u32 lvl , void * context , void * * rv )
707782{
708783 const struct acpi_device_id * ids = context ;
709- struct acpi_device * dev ;
710-
711- if (acpi_bus_get_device (handle , & dev ) != 0 )
712- return AE_OK ;
784+ struct acpi_device * dev = acpi_fetch_acpi_dev (handle );
713785
714- if (acpi_match_device_ids (dev , ids ) == 0 )
786+ if (dev && acpi_match_device_ids (dev , ids ) == 0 )
715787 if (!IS_ERR_OR_NULL (acpi_create_platform_device (dev , NULL )))
716788 dev_info (& dev -> dev ,
717789 "intel-hid: created platform device\n" );
0 commit comments