]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
platform/x86: toshiba_acpi: Add quirk for buttons on Z830
authorArvid Norlander <lkml@vorpal.se>
Wed, 31 Jan 2024 11:16:41 +0000 (12:16 +0100)
committerHans de Goede <hdegoede@redhat.com>
Mon, 8 Apr 2024 13:22:23 +0000 (15:22 +0200)
The Z830 has some buttons that will only work properly as "quickstart"
buttons. To enable them in that mode, a value between 1 and 7 must be
used for HCI_HOTKEY_EVENT. Windows uses 0x5 on this laptop so use that for
maximum predictability and compatibility.

As there is not yet a known way of auto detection, this patch uses a DMI
quirk table. A module parameter is exposed to allow setting this on other
models for testing.

Signed-off-by: Arvid Norlander <lkml@vorpal.se>
Tested-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Link: https://lore.kernel.org/r/20240131111641.4418-3-W_Armin@gmx.de
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
drivers/platform/x86/toshiba_acpi.c

index 291f14ef67024a35befa2ab2418e69b8c94c8302..2a5a651235fe6d48ccf17d00c0bbde3ae2e19c0a 100644 (file)
@@ -57,6 +57,11 @@ module_param(turn_on_panel_on_resume, int, 0644);
 MODULE_PARM_DESC(turn_on_panel_on_resume,
        "Call HCI_PANEL_POWER_ON on resume (-1 = auto, 0 = no, 1 = yes");
 
+static int hci_hotkey_quickstart = -1;
+module_param(hci_hotkey_quickstart, int, 0644);
+MODULE_PARM_DESC(hci_hotkey_quickstart,
+                "Call HCI_HOTKEY_EVENT with value 0x5 for quickstart button support (-1 = auto, 0 = no, 1 = yes");
+
 #define TOSHIBA_WMI_EVENT_GUID "59142400-C6A3-40FA-BADB-8A2652834100"
 
 /* Scan code for Fn key on TOS1900 models */
@@ -136,6 +141,7 @@ MODULE_PARM_DESC(turn_on_panel_on_resume,
 #define HCI_ACCEL_MASK                 0x7fff
 #define HCI_ACCEL_DIRECTION_MASK       0x8000
 #define HCI_HOTKEY_DISABLE             0x0b
+#define HCI_HOTKEY_ENABLE_QUICKSTART   0x05
 #define HCI_HOTKEY_ENABLE              0x09
 #define HCI_HOTKEY_SPECIAL_FUNCTIONS   0x10
 #define HCI_LCD_BRIGHTNESS_BITS                3
@@ -2730,10 +2736,15 @@ static int toshiba_acpi_enable_hotkeys(struct toshiba_acpi_dev *dev)
                return -ENODEV;
 
        /*
+        * Enable quickstart buttons if supported.
+        *
         * Enable the "Special Functions" mode only if they are
         * supported and if they are activated.
         */
-       if (dev->kbd_function_keys_supported && dev->special_functions)
+       if (hci_hotkey_quickstart)
+               result = hci_write(dev, HCI_HOTKEY_EVENT,
+                                  HCI_HOTKEY_ENABLE_QUICKSTART);
+       else if (dev->kbd_function_keys_supported && dev->special_functions)
                result = hci_write(dev, HCI_HOTKEY_EVENT,
                                   HCI_HOTKEY_SPECIAL_FUNCTIONS);
        else
@@ -3257,7 +3268,14 @@ static const char *find_hci_method(acpi_handle handle)
  * works. toshiba_acpi_resume() uses HCI_PANEL_POWER_ON to avoid changing
  * the configured brightness level.
  */
-static const struct dmi_system_id turn_on_panel_on_resume_dmi_ids[] = {
+#define QUIRK_TURN_ON_PANEL_ON_RESUME          BIT(0)
+/*
+ * Some Toshibas use "quickstart" keys. On these, HCI_HOTKEY_EVENT must use
+ * the value HCI_HOTKEY_ENABLE_QUICKSTART.
+ */
+#define QUIRK_HCI_HOTKEY_QUICKSTART            BIT(1)
+
+static const struct dmi_system_id toshiba_dmi_quirks[] = {
        {
         /* Toshiba Portégé R700 */
         /* https://bugzilla.kernel.org/show_bug.cgi?id=21012 */
@@ -3265,6 +3283,7 @@ static const struct dmi_system_id turn_on_panel_on_resume_dmi_ids[] = {
                DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
                DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE R700"),
                },
+        .driver_data = (void *)QUIRK_TURN_ON_PANEL_ON_RESUME,
        },
        {
         /* Toshiba Satellite/Portégé R830 */
@@ -3274,6 +3293,7 @@ static const struct dmi_system_id turn_on_panel_on_resume_dmi_ids[] = {
                DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
                DMI_MATCH(DMI_PRODUCT_NAME, "R830"),
                },
+        .driver_data = (void *)QUIRK_TURN_ON_PANEL_ON_RESUME,
        },
        {
         /* Toshiba Satellite/Portégé Z830 */
@@ -3281,6 +3301,7 @@ static const struct dmi_system_id turn_on_panel_on_resume_dmi_ids[] = {
                DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
                DMI_MATCH(DMI_PRODUCT_NAME, "Z830"),
                },
+        .driver_data = (void *)(QUIRK_TURN_ON_PANEL_ON_RESUME | QUIRK_HCI_HOTKEY_QUICKSTART),
        },
 };
 
@@ -3289,6 +3310,8 @@ static int toshiba_acpi_add(struct acpi_device *acpi_dev)
        struct toshiba_acpi_dev *dev;
        const char *hci_method;
        u32 dummy;
+       const struct dmi_system_id *dmi_id;
+       long quirks = 0;
        int ret = 0;
 
        if (toshiba_acpi)
@@ -3441,8 +3464,15 @@ iio_error:
        }
 #endif
 
+       dmi_id = dmi_first_match(toshiba_dmi_quirks);
+       if (dmi_id)
+               quirks = (long)dmi_id->driver_data;
+
        if (turn_on_panel_on_resume == -1)
-               turn_on_panel_on_resume = dmi_check_system(turn_on_panel_on_resume_dmi_ids);
+               turn_on_panel_on_resume = !!(quirks & QUIRK_TURN_ON_PANEL_ON_RESUME);
+
+       if (hci_hotkey_quickstart == -1)
+               hci_hotkey_quickstart = !!(quirks & QUIRK_HCI_HOTKEY_QUICKSTART);
 
        toshiba_wwan_available(dev);
        if (dev->wwan_supported)