Hi 2020. december 3., csütörtök 22:21 keltezéssel, Elia Devito írta: > [...] > diff --git a/drivers/platform/x86/intel-hid.c b/drivers/platform/x86/intel-hid.c > index 86261970bd8f..fed24d4f28b8 100644 > --- a/drivers/platform/x86/intel-hid.c > +++ b/drivers/platform/x86/intel-hid.c > @@ -15,6 +15,9 @@ > #include <linux/platform_device.h> > #include <linux/suspend.h> > > +/* When NOT in tablet mode, VGBS returns with the flag 0x40 */ > +#define TABLET_MODE_FLAG 0x40 I think `BIT(6)` would be better (linux/bits.h). > + > MODULE_LICENSE("GPL"); > MODULE_AUTHOR("Alex Hung"); > > @@ -89,9 +92,26 @@ static const struct dmi_system_id button_array_table[] = { > { } > }; > [...] > +static void detect_tablet_mode(struct platform_device *device) I believe `report_tablet_mode_state()` or something similar would be a more apt name. > +{ > + struct intel_hid_priv *priv = dev_get_drvdata(&device->dev); > + acpi_handle handle = ACPI_HANDLE(&device->dev); > + unsigned long long vgbs; > + int m; > + > + if (!intel_hid_evaluate_method(handle, INTEL_HID_DSM_VGBS_FN, &vgbs)) > + return; > + > + m = !(vgbs & TABLET_MODE_FLAG); > + input_report_switch(priv->switches, SW_TABLET_MODE, m); > + input_sync(priv->switches); > +} > + > static void notify_handler(acpi_handle handle, u32 event, void *context) > { > struct platform_device *device = context; > @@ -363,6 +415,13 @@ static void notify_handler(acpi_handle handle, u32 event, void *context) > if (event == 0xce) > goto wakeup; > > + /* > + * Switch events will wake the device and report the new switch > + * position to the input subsystem. > + */ > + if (priv->switches && (event == 0xcc || event == 0xcd)) > + goto wakeup; > + > /* Wake up on 5-button array events only. */ > if (event == 0xc0 || !priv->array) > return; > @@ -374,6 +433,21 @@ static void notify_handler(acpi_handle handle, u32 event, void *context) > > wakeup: > pm_wakeup_hard_event(&device->dev); > + > + if (priv->switches) { > + if (event == 0xcc) { > + input_report_switch(priv->switches, SW_TABLET_MODE, 1); > + input_sync(priv->switches); > + return; > + } > + > + if (event == 0xcd) { > + input_report_switch(priv->switches, SW_TABLET_MODE, 0); > + input_sync(priv->switches); > + return; > + } > + } > + > return; > } > > @@ -398,6 +472,20 @@ static void notify_handler(acpi_handle handle, u32 event, void *context) > } > } > > + if (priv->switches) { > + if (event == 0xcc) { > + input_report_switch(priv->switches, SW_TABLET_MODE, 1); > + input_sync(priv->switches); > + return; > + } > + > + if (event == 0xcd) { > + input_report_switch(priv->switches, SW_TABLET_MODE, 0); > + input_sync(priv->switches); > + return; > + } > + } Wouldn't be better to create a new function `bool report_tablet_mode_event()` which would basically contain the above `if` or better, a `switch`, and then you could use it here and in the wake-up path like the following: ``` if (report_tablet_mode_event(priv->switches, event)) return; ``` (or similarly) > + > /* 0xC0 is for HID events, other values are for 5 button array */ > if (event != 0xc0) { > if (!priv->array || > @@ -485,6 +573,16 @@ static int intel_hid_probe(struct platform_device *device) > pr_err("Failed to setup Intel 5 button array hotkeys\n"); > } > > + /* Setup switches for devices that we know VGBS return correctly */ > + if (dmi_check_system(dmi_vgbs_allow_list)) { > + dev_info(&device->dev, "platform supports switches\n"); > + err = intel_hid_switches_setup(device); > + if (err) > + pr_err("Failed to setup Intel HID switches\n"); > + else > + detect_tablet_mode(device); > + } > + > status = acpi_install_notify_handler(handle, > ACPI_DEVICE_NOTIFY, > notify_handler, > -- > 2.28.0 Regards, Barnabás Pőcze