From: Yurii Pavlovskyi <yurii.pavlovskyi@gmail.com>
To: unlisted-recipients:; (no To-header on input)
Cc: Corentin Chary <corentin.chary@gmail.com>,
Darren Hart <dvhart@infradead.org>,
Andy Shevchenko <andy@infradead.org>,
Daniel Drake <drake@endlessm.com>,
acpi4asus-user@lists.sourceforge.net,
platform-driver-x86@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-api@vger.kernel.org
Subject: [PATCH 10/11] platform/x86: asus-wmi: Switch fan boost mode
Date: Wed, 10 Apr 2019 22:34:55 +0200 [thread overview]
Message-ID: <72b3e0aa-d53a-8a82-1505-f4f00aa2bb46@gmail.com> (raw)
In-Reply-To: <a8dd77f3-1e28-6416-5f04-aff44d5bb6d6@gmail.com>
The WMI exposes a write-only device ID where three modes can be switched
on some laptops (TUF Gaming FX505GM). There is a hotkey combination Fn-F5
that does have a fan icon which is designed to toggle between these 3
modes.
Add a SysFS entry that reads the last written value and updates value in
WMI on write and a hotkey handler that toggles the modes. The
corresponding DEVS device handler does obviously take 3 possible
argument values.
Method (SFBM, 1, NotSerialized)
{
If ((Arg0 == Zero) { .. }
If ((Arg0 == One)) { .. }
If ((Arg0 == 0x02)) { .. }
}
... // DEVS
If ((IIA0 == 0x00110018))
{
SFBM (IIA1)
Return (One)
}
* 0x00 - is normal,
* 0x01 - is obviously turbo by the amount of noise, might be useful to
avoid CPU frequency throttling on high load,
* 0x02 - the meaning is unknown at the time as modes are not named
in the vendor documentation, but it does look like a quiet mode as CPU
temperature does increase about 10 degrees on maximum load.
Signed-off-by: Yurii Pavlovskyi <yurii.pavlovskyi@gmail.com>
---
.../ABI/testing/sysfs-platform-asus-wmi | 10 ++
drivers/platform/x86/asus-wmi.c | 119 ++++++++++++++++--
include/linux/platform_data/x86/asus-wmi.h | 1 +
3 files changed, 117 insertions(+), 13 deletions(-)
diff --git a/Documentation/ABI/testing/sysfs-platform-asus-wmi b/Documentation/ABI/testing/sysfs-platform-asus-wmi
index 300a40519695..2b3184e297a7 100644
--- a/Documentation/ABI/testing/sysfs-platform-asus-wmi
+++ b/Documentation/ABI/testing/sysfs-platform-asus-wmi
@@ -97,3 +97,13 @@ Description:
Write changed RGB keyboard backlight parameters:
* 1 - permanently,
* 2 - temporarily.
+
+What: /sys/devices/platform/<platform>/fan_mode
+Date: Apr 2019
+KernelVersion: 5.1
+Contact: "Yurii Pavlovskyi" <yurii.pavlovskyi@gmail.com>
+Description:
+ Fan boost mode:
+ * 0 - normal,
+ * 1 - turbo,
+ * 2 - quiet?
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
index f4323a57f22f..941c628945ac 100644
--- a/drivers/platform/x86/asus-wmi.c
+++ b/drivers/platform/x86/asus-wmi.c
@@ -69,6 +69,7 @@ MODULE_LICENSE("GPL");
#define NOTIFY_KBD_BRTUP 0xc4
#define NOTIFY_KBD_BRTDWN 0xc5
#define NOTIFY_KBD_BRTTOGGLE 0xc7
+#define NOTIFY_KBD_FBM 0x99
#define ASUS_FAN_DESC "cpu_fan"
#define ASUS_FAN_MFUN 0x13
@@ -77,6 +78,8 @@ MODULE_LICENSE("GPL");
#define ASUS_FAN_CTRL_MANUAL 1
#define ASUS_FAN_CTRL_AUTO 2
+#define ASUS_FAN_MODE_COUNT 3
+
#define USB_INTEL_XUSB2PR 0xD0
#define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI 0x9c31
@@ -196,6 +199,9 @@ struct asus_wmi {
int asus_hwmon_num_fans;
int asus_hwmon_pwm;
+ bool fan_mode_available;
+ u8 fan_mode;
+
bool kbbl_rgb_available;
struct asus_kbbl_rgb kbbl_rgb;
@@ -1833,6 +1839,87 @@ static int asus_wmi_fan_init(struct asus_wmi *asus)
return 0;
}
+/* Fan mode *******************************************************************/
+
+static int fan_mode_check_present(struct asus_wmi *asus)
+{
+ u32 result;
+ int err;
+
+ asus->fan_mode_available = false;
+
+ err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_FAN_MODE, &result);
+ if (err) {
+ if (err == -ENODEV)
+ return 0;
+ else
+ return err;
+ }
+
+ if (result & ASUS_WMI_DSTS_PRESENCE_BIT)
+ asus->fan_mode_available = true;
+
+ return 0;
+}
+
+static int fan_mode_write(struct asus_wmi *asus)
+{
+ int err;
+ u8 value;
+ u32 retval;
+
+ value = asus->fan_mode % ASUS_FAN_MODE_COUNT;
+ pr_info(PR "Set fan mode: %u\n", value);
+ err = asus_wmi_set_devstate(ASUS_WMI_DEVID_FAN_MODE, value, &retval);
+
+ if (err) {
+ pr_warn(PR "Failed to set fan mode: %d\n", err);
+ return err;
+ }
+
+ if (retval != 1) {
+ pr_warn(PR "Failed to set fan mode (retval): 0x%x\n", retval);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int fan_mode_switch_next(struct asus_wmi *asus)
+{
+ asus->fan_mode = (asus->fan_mode + 1) % ASUS_FAN_MODE_COUNT;
+ return fan_mode_write(asus);
+}
+
+static ssize_t fan_mode_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct asus_wmi *asus = dev_get_drvdata(dev);
+
+ return show_u8(asus->fan_mode, buf);
+}
+
+static ssize_t fan_mode_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int result;
+ u8 new_mode;
+
+ struct asus_wmi *asus = dev_get_drvdata(dev);
+
+ result = store_u8(&new_mode, buf, count);
+ if (result < 0)
+ return result;
+
+ asus->fan_mode = new_mode % ASUS_FAN_MODE_COUNT;
+ fan_mode_write(asus);
+
+ return result;
+}
+
+// Fan mode: 0 - normal, 1 - turbo, 2 - quiet?
+static DEVICE_ATTR_RW(fan_mode);
+
/* Backlight ******************************************************************/
static int read_backlight_power(struct asus_wmi *asus)
@@ -2084,6 +2171,9 @@ static void asus_wmi_handle_notify(int code, struct asus_wmi *asus)
return;
}
+ if (asus->fan_mode_available && code == NOTIFY_KBD_FBM)
+ fan_mode_switch_next(asus);
+
if (is_display_toggle(code) && asus->driver->quirks->no_display_toggle)
return;
@@ -2237,6 +2327,7 @@ static struct attribute *platform_attributes[] = {
&dev_attr_touchpad.attr,
&dev_attr_lid_resume.attr,
&dev_attr_als_enable.attr,
+ &dev_attr_fan_mode.attr,
NULL
};
@@ -2258,6 +2349,8 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj,
devid = ASUS_WMI_DEVID_LID_RESUME;
else if (attr == &dev_attr_als_enable.attr)
devid = ASUS_WMI_DEVID_ALS_ENABLE;
+ else if (attr == &dev_attr_fan_mode.attr)
+ ok = asus->fan_mode_available;
if (devid != -1)
ok = !(asus_wmi_get_devstate_simple(asus, devid) < 0);
@@ -2282,7 +2375,7 @@ static int asus_wmi_sysfs_init(struct platform_device *device)
/* Platform device ************************************************************/
-static int asus_wmi_platform_init(struct asus_wmi *asus)
+static void asus_wmi_platform_init(struct asus_wmi *asus)
{
int rv;
@@ -2334,13 +2427,6 @@ static int asus_wmi_platform_init(struct asus_wmi *asus)
if (asus->driver->quirks->wapf >= 0)
asus_wmi_set_devstate(ASUS_WMI_DEVID_CWAP,
asus->driver->quirks->wapf, NULL);
-
- return asus_wmi_sysfs_init(asus->platform_device);
-}
-
-static void asus_wmi_platform_exit(struct asus_wmi *asus)
-{
- asus_wmi_sysfs_exit(asus->platform_device);
}
/* debugfs ********************************************************************/
@@ -2515,9 +2601,15 @@ static int asus_wmi_add(struct platform_device *pdev)
if (wdrv->detect_quirks)
wdrv->detect_quirks(asus->driver);
- err = asus_wmi_platform_init(asus);
+ asus_wmi_platform_init(asus);
+
+ err = fan_mode_check_present(asus);
if (err)
- goto fail_platform;
+ goto fail_fan_mode;
+
+ err = asus_wmi_sysfs_init(asus->platform_device);
+ if (err)
+ goto fail_sysfs;
err = asus_wmi_input_init(asus);
if (err)
@@ -2612,8 +2704,9 @@ static int asus_wmi_add(struct platform_device *pdev)
fail_hwmon:
asus_wmi_input_exit(asus);
fail_input:
- asus_wmi_platform_exit(asus);
-fail_platform:
+ asus_wmi_sysfs_exit(asus->platform_device);
+fail_sysfs:
+fail_fan_mode:
kfree(asus);
return err;
}
@@ -2630,7 +2723,7 @@ static int asus_wmi_remove(struct platform_device *device)
kbbl_rgb_exit(asus);
asus_wmi_rfkill_exit(asus);
asus_wmi_debugfs_exit(asus);
- asus_wmi_platform_exit(asus);
+ asus_wmi_sysfs_exit(asus->platform_device);
asus_wmi_hwmon_exit(asus);
kfree(asus);
diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h
index 25b7b653e6d2..0f3654b7b8a8 100644
--- a/include/linux/platform_data/x86/asus-wmi.h
+++ b/include/linux/platform_data/x86/asus-wmi.h
@@ -59,6 +59,7 @@
#define ASUS_WMI_DEVID_LIGHTBAR 0x00050025
#define ASUS_WMI_DEVID_KBD_RGB 0x00100056
#define ASUS_WMI_DEVID_KBD_RGB2 0x00100057
+#define ASUS_WMI_DEVID_FAN_MODE 0x00110018
/* Misc */
#define ASUS_WMI_DEVID_CAMERA 0x00060013
--
2.17.1
next prev parent reply other threads:[~2019-04-10 20:35 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-04-10 20:11 [PATCH 00/11] asus-wmi: Support of ASUS TUF Gaming series laptops Yurii Pavlovskyi
2019-04-10 20:20 ` [PATCH 01/11] platform/x86: asus-wmi: Fix hwmon device cleanup Yurii Pavlovskyi
2019-04-11 8:21 ` Daniel Drake
2019-04-12 17:49 ` Yurii Pavlovskyi
2019-04-10 20:26 ` [PATCH 02/11] platform/x86: asus-wmi: Fix preserving keyboard, backlight intensity on load Yurii Pavlovskyi
2019-04-10 20:27 ` [PATCH 03/11] platform/x86: asus-wmi: Increase input buffer size of WMI methods Yurii Pavlovskyi
2019-04-10 20:28 ` [PATCH 04/11] platform/x86: asus-wmi: Add quirk to force DSTS WMI method detection Yurii Pavlovskyi
2019-04-11 5:42 ` [PATCH v2 " Yurii Pavlovskyi
2019-04-11 10:55 ` [PATCH " Daniel Drake
2019-04-12 20:04 ` Yurii Pavlovskyi
2019-04-10 20:29 ` [PATCH 05/11] platform/x86: asus-wmi: Support queued WMI event codes Yurii Pavlovskyi
2019-04-11 5:44 ` [PATCH v2 " Yurii Pavlovskyi
2019-04-12 7:48 ` Daniel Drake
2019-04-12 20:32 ` Yurii Pavlovskyi
2019-04-10 20:30 ` [PATCH 06/11] platform/x86: asus-nb-wmi: Add microphone mute key code Yurii Pavlovskyi
2019-04-11 5:44 ` [PATCH v2 " Yurii Pavlovskyi
2019-04-10 20:31 ` [PATCH 07/11] platform/x86: asus-wmi: Organize code into sections Yurii Pavlovskyi
2019-04-11 5:45 ` [PATCH v2 " Yurii Pavlovskyi
2019-04-10 20:32 ` [PATCH 08/11] platform/x86: asus-wmi: Enhance detection of thermal data Yurii Pavlovskyi
2019-04-11 5:45 ` [PATCH v2 " Yurii Pavlovskyi
2019-04-10 20:33 ` [PATCH 09/11] platform/x86: asus-wmi: Control RGB keyboard backlight Yurii Pavlovskyi
2019-04-11 5:46 ` [PATCH v2 " Yurii Pavlovskyi
2019-04-10 20:34 ` Yurii Pavlovskyi [this message]
2019-04-11 5:47 ` [PATCH v2 10/11] platform/x86: asus-wmi: Switch fan boost mode Yurii Pavlovskyi
2019-04-12 8:03 ` Daniel Drake
2019-04-12 20:50 ` Yurii Pavlovskyi
2019-04-10 20:36 ` [PATCH 11/11] platform/x86: asus-wmi: Do not disable keyboard backlight on unload Yurii Pavlovskyi
2019-04-11 5:48 ` [PATCH v2 " Yurii Pavlovskyi
2019-04-11 5:38 ` [PATCH 00/11] asus-wmi: Support of ASUS TUF Gaming series laptops Yurii Pavlovskyi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=72b3e0aa-d53a-8a82-1505-f4f00aa2bb46@gmail.com \
--to=yurii.pavlovskyi@gmail.com \
--cc=acpi4asus-user@lists.sourceforge.net \
--cc=andy@infradead.org \
--cc=corentin.chary@gmail.com \
--cc=drake@endlessm.com \
--cc=dvhart@infradead.org \
--cc=linux-api@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=platform-driver-x86@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).