summarylogtreecommitdiffstats
path: root/0001-v4-platform-x86-asus-wmi-add-support-for-2024-ROG-Mini-LED.patch
diff options
context:
space:
mode:
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.patch219
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