diff options
Diffstat (limited to '0001-v4-platform-x86-asus-wmi-add-support-for-2024-ROG-Mini-LED.patch')
-rw-r--r-- | 0001-v4-platform-x86-asus-wmi-add-support-for-2024-ROG-Mini-LED.patch | 219 |
1 files changed, 219 insertions, 0 deletions
diff --git a/0001-v4-platform-x86-asus-wmi-add-support-for-2024-ROG-Mini-LED.patch b/0001-v4-platform-x86-asus-wmi-add-support-for-2024-ROG-Mini-LED.patch new file mode 100644 index 000000000000..cc5026904dd3 --- /dev/null +++ b/0001-v4-platform-x86-asus-wmi-add-support-for-2024-ROG-Mini-LED.patch @@ -0,0 +1,219 @@ +From: "Luke D. Jones" <luke@ljones.dev> +To: hdegoede@redhat.com +Cc: corentin.chary@gmail.com, ilpo.jarvinen@linux.intel.com, + platform-driver-x86@vger.kernel.org, + linux-kernel@vger.kernel.org, "Luke D. Jones" <luke@ljones.dev> +Subject: [PATCH v4 1/9] platform/x86: asus-wmi: add support for 2024 ROG Mini-LED +Date: Thu, 4 Apr 2024 13:16:44 +1300 [thread overview] +Message-ID: <20240404001652.86207-2-luke@ljones.dev> (raw) +In-Reply-To: <20240404001652.86207-1-luke@ljones.dev> + +Support the 2024 mini-led backlight and adjust the related functions +to select the relevant dev-id. Also add `available_mini_led_mode` to the +platform sysfs since the available mini-led levels can be different. + +Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> +signed-off-by: Luke D. Jones <luke@ljones.dev> +--- + .../ABI/testing/sysfs-platform-asus-wmi | 8 ++ + drivers/platform/x86/asus-wmi.c | 96 +++++++++++++++++-- + include/linux/platform_data/x86/asus-wmi.h | 1 + + 3 files changed, 95 insertions(+), 10 deletions(-) + +diff --git a/Documentation/ABI/testing/sysfs-platform-asus-wmi b/Documentation/ABI/testing/sysfs-platform-asus-wmi +index 8a7e25bde085..ef1ac1a20a71 100644 +--- a/Documentation/ABI/testing/sysfs-platform-asus-wmi ++++ b/Documentation/ABI/testing/sysfs-platform-asus-wmi +@@ -126,6 +126,14 @@ Description: + Change the mini-LED mode: + * 0 - Single-zone, + * 1 - Multi-zone ++ * 2 - Multi-zone strong (available on newer generation mini-led) ++ ++What: /sys/devices/platform/<platform>/available_mini_led_mode ++Date: Apr 2024 ++KernelVersion: 6.10 ++Contact: "Luke Jones" <luke@ljones.dev> ++Description: ++ List the available mini-led modes. + + What: /sys/devices/platform/<platform>/ppt_pl1_spl + Date: Jun 2023 +diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c +index 3f07bbf809ef..aa2a3b402e33 100644 +--- a/drivers/platform/x86/asus-wmi.c ++++ b/drivers/platform/x86/asus-wmi.c +@@ -126,6 +126,17 @@ module_param(fnlock_default, bool, 0444); + #define ASUS_SCREENPAD_BRIGHT_MAX 255 + #define ASUS_SCREENPAD_BRIGHT_DEFAULT 60 + ++#define ASUS_MINI_LED_MODE_MASK 0x03 ++/* Standard modes for devices with only on/off */ ++#define ASUS_MINI_LED_OFF 0x00 ++#define ASUS_MINI_LED_ON 0x01 ++/* New mode on some devices, define here to clarify remapping later */ ++#define ASUS_MINI_LED_STRONG_MODE 0x02 ++/* New modes for devices with 3 mini-led mode types */ ++#define ASUS_MINI_LED_2024_WEAK 0x00 ++#define ASUS_MINI_LED_2024_STRONG 0x01 ++#define ASUS_MINI_LED_2024_OFF 0x02 ++ + /* Controls the power state of the USB0 hub on ROG Ally which input is on */ + #define ASUS_USB0_PWR_EC0_CSEE "\\_SB.PCI0.SBRG.EC0.CSEE" + /* 300ms so far seems to produce a reliable result on AC and battery */ +@@ -288,7 +299,7 @@ struct asus_wmi { + bool battery_rsoc_available; + + bool panel_overdrive_available; +- bool mini_led_mode_available; ++ u32 mini_led_dev_id; + + struct hotplug_slot hotplug_slot; + struct mutex hotplug_lock; +@@ -2108,13 +2119,33 @@ static ssize_t mini_led_mode_show(struct device *dev, + struct device_attribute *attr, char *buf) + { + struct asus_wmi *asus = dev_get_drvdata(dev); +- int result; ++ u32 value; ++ int err; + +- result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_MINI_LED_MODE); +- if (result < 0) +- return result; ++ err = asus_wmi_get_devstate(asus, asus->mini_led_dev_id, &value); ++ if (err < 0) ++ return err; ++ value = value & ASUS_MINI_LED_MODE_MASK; + +- return sysfs_emit(buf, "%d\n", result); ++ /* ++ * Remap the mode values to match previous generation mini-led. The last gen ++ * WMI 0 == off, while on this version WMI 2 ==off (flipped). ++ */ ++ if (asus->mini_led_dev_id == ASUS_WMI_DEVID_MINI_LED_MODE2) { ++ switch (value) { ++ case ASUS_MINI_LED_2024_WEAK: ++ value = ASUS_MINI_LED_ON; ++ break; ++ case ASUS_MINI_LED_2024_STRONG: ++ value = ASUS_MINI_LED_STRONG_MODE; ++ break; ++ case ASUS_MINI_LED_2024_OFF: ++ value = ASUS_MINI_LED_OFF; ++ break; ++ } ++ } ++ ++ return sysfs_emit(buf, "%d\n", value); + } + + static ssize_t mini_led_mode_store(struct device *dev, +@@ -2130,11 +2161,32 @@ static ssize_t mini_led_mode_store(struct device *dev, + if (result) + return result; + +- if (mode > 1) ++ if (asus->mini_led_dev_id == ASUS_WMI_DEVID_MINI_LED_MODE && ++ mode > ASUS_MINI_LED_ON) ++ return -EINVAL; ++ if (asus->mini_led_dev_id == ASUS_WMI_DEVID_MINI_LED_MODE2 && ++ mode > ASUS_MINI_LED_STRONG_MODE) + return -EINVAL; + +- err = asus_wmi_set_devstate(ASUS_WMI_DEVID_MINI_LED_MODE, mode, &result); ++ /* ++ * Remap the mode values so expected behaviour is the same as the last ++ * generation of mini-LED with 0 == off, 1 == on. ++ */ ++ if (asus->mini_led_dev_id == ASUS_WMI_DEVID_MINI_LED_MODE2) { ++ switch (mode) { ++ case ASUS_MINI_LED_OFF: ++ mode = ASUS_MINI_LED_2024_OFF; ++ break; ++ case ASUS_MINI_LED_ON: ++ mode = ASUS_MINI_LED_2024_WEAK; ++ break; ++ case ASUS_MINI_LED_STRONG_MODE: ++ mode = ASUS_MINI_LED_2024_STRONG; ++ break; ++ } ++ } + ++ err = asus_wmi_set_devstate(asus->mini_led_dev_id, mode, &result); + if (err) { + pr_warn("Failed to set mini-LED: %d\n", err); + return err; +@@ -2151,6 +2203,23 @@ static ssize_t mini_led_mode_store(struct device *dev, + } + static DEVICE_ATTR_RW(mini_led_mode); + ++static ssize_t available_mini_led_mode_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct asus_wmi *asus = dev_get_drvdata(dev); ++ ++ switch (asus->mini_led_dev_id) { ++ case ASUS_WMI_DEVID_MINI_LED_MODE: ++ return sysfs_emit(buf, "0 1\n"); ++ case ASUS_WMI_DEVID_MINI_LED_MODE2: ++ return sysfs_emit(buf, "0 1 2\n"); ++ } ++ ++ return sysfs_emit(buf, "0\n"); ++} ++ ++static DEVICE_ATTR_RO(available_mini_led_mode); ++ + /* Quirks *********************************************************************/ + + static void asus_wmi_set_xusb2pr(struct asus_wmi *asus) +@@ -4139,6 +4208,7 @@ static struct attribute *platform_attributes[] = { + &dev_attr_nv_temp_target.attr, + &dev_attr_panel_od.attr, + &dev_attr_mini_led_mode.attr, ++ &dev_attr_available_mini_led_mode.attr, + NULL + }; + +@@ -4191,7 +4261,9 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj, + else if (attr == &dev_attr_panel_od.attr) + ok = asus->panel_overdrive_available; + else if (attr == &dev_attr_mini_led_mode.attr) +- ok = asus->mini_led_mode_available; ++ ok = asus->mini_led_dev_id != 0; ++ else if (attr == &dev_attr_available_mini_led_mode.attr) ++ ok = asus->mini_led_dev_id != 0; + + if (devid != -1) + ok = !(asus_wmi_get_devstate_simple(asus, devid) < 0); +@@ -4444,10 +4516,14 @@ static int asus_wmi_add(struct platform_device *pdev) + asus->nv_dyn_boost_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_NV_DYN_BOOST); + asus->nv_temp_tgt_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_NV_THERM_TARGET); + asus->panel_overdrive_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PANEL_OD); +- asus->mini_led_mode_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_MINI_LED_MODE); + asus->ally_mcu_usb_switch = acpi_has_method(NULL, ASUS_USB0_PWR_EC0_CSEE) + && dmi_match(DMI_BOARD_NAME, "RC71L"); + ++ if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_MINI_LED_MODE)) ++ asus->mini_led_dev_id = ASUS_WMI_DEVID_MINI_LED_MODE; ++ else if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_MINI_LED_MODE2)) ++ asus->mini_led_dev_id = ASUS_WMI_DEVID_MINI_LED_MODE2; ++ + err = fan_boost_mode_check_present(asus); + if (err) + goto fail_fan_boost_mode; +diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h +index ab1c7deff118..9cadce10ad9a 100644 +--- a/include/linux/platform_data/x86/asus-wmi.h ++++ b/include/linux/platform_data/x86/asus-wmi.h +@@ -71,6 +71,7 @@ + #define ASUS_WMI_DEVID_LID_FLIP 0x00060062 + #define ASUS_WMI_DEVID_LID_FLIP_ROG 0x00060077 + #define ASUS_WMI_DEVID_MINI_LED_MODE 0x0005001E ++#define ASUS_WMI_DEVID_MINI_LED_MODE2 0x0005002E + + /* Storage */ + #define ASUS_WMI_DEVID_CARDREADER 0x00080013 +-- +2.44.0 |