From: Armin Wolf <W_Armin@gmx.de>
To: Kurt Borja <kuurtb@gmail.com>,
hdegoede@redhat.com, ilpo.jarvinen@linux.intel.com
Cc: platform-driver-x86@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH] Dell AWCC platform_profile support
Date: Mon, 7 Oct 2024 14:24:52 +0200 [thread overview]
Message-ID: <771d20f1-ebf3-48d9-98ef-ec79b94c7949@gmx.de> (raw)
In-Reply-To: <20241007093324.49631-3-kuurtb@gmail.com>
Am 07.10.24 um 11:33 schrieb Kurt Borja:
> This patch adds platform_profile support for Dell devices which implement
> User Selectable Thermal Tables (USTT) that are meant to be controlled by
> Alienware Command Center (AWCC). These devices may include newer Alienware
> M-Series, Alienware X-Series and Dell's G-Series. This patch, was tested
> by me on an Alienware x15 R1.
>
> It is suspected that Alienware Command Center manages thermal profiles
> through the WMI interface, specifically through a device with identifier
> \_SB_.AMW1.WMAX. This device was reverse engineered and the relevant
> functionality is documented here [1]. This driver interacts with this
> WMI device and thus is able to mimic AWCC's thermal profiles functionality
> through the platform_profile API. In consequence the user would be able
> to set and retrieve thermal profiles, which are just fan speed profiles.
>
> This driver was heavily inspired on inspur_platform_profile, special
> thanks.
>
> Notes:
> - Performance (FullSpeed) profile is a special profile which has it's own
> entry in the Firmware Settings of the Alienware x15 R1. It also changes
> the color of the F1 key. I suspect this behavior would be replicated in
> other X-Series or M-Series laptops.
> - G-Mode is a profile documented on [1] which mimics the behavior of
> FullSpeed mode but it does not have an entry on the Firmware Settings of
> the Alienware x15 R1, this may correspond to the G-Mode functionality on
> G-Series laptops (activated by a special button) but I cannot test it. I
> did not include this code in the driver as G-Mode causes unexpected
> behavior on X-Series laptops.
>
> Thanks for your time and patiente in advance.
>
> Regards,
>
> Kurt
>
> [1] https://gist.github.com/kuu-rt/b22328ff2b454be505387e2a38c61ee4
Hi,
this WMI device is already handled by the alienware-wmi driver. Could you please integrate
this functionality into this driver instead of creating a new one?
Thanks,
Armin Wolf
> Signed-off-by: Kurt Borja <kuurtb@gmail.com>
> ---
> drivers/platform/x86/dell/Kconfig | 9 +
> drivers/platform/x86/dell/Makefile | 1 +
> drivers/platform/x86/dell/dell-wmi-awcc.c | 204 ++++++++++++++++++++++
> 3 files changed, 214 insertions(+)
> create mode 100644 drivers/platform/x86/dell/dell-wmi-awcc.c
>
> diff --git a/drivers/platform/x86/dell/Kconfig b/drivers/platform/x86/dell/Kconfig
> index 68a49788a..20300ff98 100644
> --- a/drivers/platform/x86/dell/Kconfig
> +++ b/drivers/platform/x86/dell/Kconfig
> @@ -27,6 +27,15 @@ config ALIENWARE_WMI
> zones on Alienware machines that don't contain a dedicated AlienFX
> USB MCU such as the X51 and X51-R2.
>
> +config AWCC_PLATFORM_PROFILE
> + tristate "AWCC Platform Profile support"
> + depends on ACPI_WMI
> + select ACPI_PLATFORM_PROFILE
> + help
> + This driver provides platform_profile support for selecting thermal
> + profiles on Dell devices with User Selectable Thermal Tables,
> + controlled by AWCC's WMI interface.
> +
> config DCDBAS
> tristate "Dell Systems Management Base Driver"
> default m
> diff --git a/drivers/platform/x86/dell/Makefile b/drivers/platform/x86/dell/Makefile
> index 79d60f1bf..bfef99580 100644
> --- a/drivers/platform/x86/dell/Makefile
> +++ b/drivers/platform/x86/dell/Makefile
> @@ -23,4 +23,5 @@ obj-$(CONFIG_DELL_WMI_AIO) += dell-wmi-aio.o
> obj-$(CONFIG_DELL_WMI_DESCRIPTOR) += dell-wmi-descriptor.o
> obj-$(CONFIG_DELL_WMI_DDV) += dell-wmi-ddv.o
> obj-$(CONFIG_DELL_WMI_LED) += dell-wmi-led.o
> +obj-$(CONFIG_AWCC_PLATFORM_PROFILE) += dell-wmi-awcc.o
> obj-$(CONFIG_DELL_WMI_SYSMAN) += dell-wmi-sysman/
> diff --git a/drivers/platform/x86/dell/dell-wmi-awcc.c b/drivers/platform/x86/dell/dell-wmi-awcc.c
> new file mode 100644
> index 000000000..0837d1bc6
> --- /dev/null
> +++ b/drivers/platform/x86/dell/dell-wmi-awcc.c
> @@ -0,0 +1,204 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * WMI driver for Dell's AWCC platform_profile
> + *
> + * Copyright (c) Kurt Borja <kuurtb@gmail.com>
> + *
> + */
> +
> +#include <linux/acpi.h>
> +#include <linux/device.h>
> +#include <linux/module.h>
> +#include <linux/platform_profile.h>
> +#include <linux/wmi.h>
> +
> +#define PROF_TO_ARG(mode) ((mode << 8) | 1)
> +
> +#define DELL_AWCC_GUID "A70591CE-A997-11DA-B012-B622A1EF5492"
> +
> +enum awcc_wmi_method {
> + AWCC_WMI_THERMAL_INFORMATION = 0x14,
> + AWCC_WMI_THERMAL_CONTROL = 0x15,
> +};
> +
> +enum awcc_tmp_profile {
> + AWCC_TMP_PROFILE_BALANCED = 0xA0,
> + AWCC_TMP_PROFILE_BALANCED_PERFORMANCE = 0xA1,
> + AWCC_TMP_PROFILE_COOL = 0xA2,
> + AWCC_TMP_PROFILE_QUIET = 0xA3,
> + AWCC_TMP_PROFILE_PERFORMANCE = 0xA4,
> + AWCC_TMP_PROFILE_LOW_POWER = 0xA5,
> +};
> +
> +struct awcc_wmi_priv {
> + struct wmi_device *wdev;
> + struct platform_profile_handler handler;
> +};
> +
> +static int awcc_wmi_query(struct wmi_device *wdev, enum awcc_wmi_method method,
> + u32 arg, u32 *res)
> +{
> + struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL };
> + const struct acpi_buffer in = { sizeof(arg), &arg };
> + union acpi_object *obj;
> + acpi_status status;
> + int ret = 0;
> +
> + status = wmidev_evaluate_method(wdev, 0x0, method, &in, &out);
> +
> + if (ACPI_FAILURE(status))
> + return -EIO;
> +
> + obj = out.pointer;
> + if (!obj)
> + return -ENODATA;
> +
> + if (obj->type != ACPI_TYPE_INTEGER) {
> + ret = -EINVAL;
> + goto out_free;
> + }
> +
> + if (obj->integer.value <= U32_MAX)
> + *res = (u32)obj->integer.value;
> + else
> + ret = -ERANGE;
> +
> +out_free:
> + kfree(obj);
> +
> + return ret;
> +}
> +
> +static int awcc_platform_profile_get(struct platform_profile_handler *pprof,
> + enum platform_profile_option *profile)
> +{
> + struct awcc_wmi_priv *priv =
> + container_of(pprof, struct awcc_wmi_priv, handler);
> +
> + u32 res;
> + int ret;
> +
> + ret = awcc_wmi_query(priv->wdev, AWCC_WMI_THERMAL_INFORMATION, 0x0B,
> + &res);
> +
> + if (ret < 0)
> + return ret;
> +
> + if (res < 0)
> + return -EBADRQC;
> +
> + switch (res) {
> + case AWCC_TMP_PROFILE_LOW_POWER:
> + *profile = PLATFORM_PROFILE_LOW_POWER;
> + break;
> + case AWCC_TMP_PROFILE_QUIET:
> + *profile = PLATFORM_PROFILE_QUIET;
> + break;
> + case AWCC_TMP_PROFILE_BALANCED:
> + *profile = PLATFORM_PROFILE_BALANCED;
> + break;
> + case AWCC_TMP_PROFILE_BALANCED_PERFORMANCE:
> + *profile = PLATFORM_PROFILE_BALANCED_PERFORMANCE;
> + break;
> + case AWCC_TMP_PROFILE_PERFORMANCE:
> + *profile = PLATFORM_PROFILE_PERFORMANCE;
> + break;
> + default:
> + return -ENODATA;
> + }
> +
> + return 0;
> +}
> +
> +static int awcc_platform_profile_set(struct platform_profile_handler *pprof,
> + enum platform_profile_option profile)
> +{
> + struct awcc_wmi_priv *priv =
> + container_of(pprof, struct awcc_wmi_priv, handler);
> +
> + u32 arg;
> + u32 res;
> + int ret;
> +
> + switch (profile) {
> + case PLATFORM_PROFILE_LOW_POWER:
> + arg = PROF_TO_ARG(AWCC_TMP_PROFILE_LOW_POWER);
> + break;
> + case PLATFORM_PROFILE_QUIET:
> + arg = PROF_TO_ARG(AWCC_TMP_PROFILE_QUIET);
> + break;
> + case PLATFORM_PROFILE_BALANCED:
> + arg = PROF_TO_ARG(AWCC_TMP_PROFILE_BALANCED);
> + break;
> + case PLATFORM_PROFILE_BALANCED_PERFORMANCE:
> + arg = PROF_TO_ARG(AWCC_TMP_PROFILE_BALANCED_PERFORMANCE);
> + break;
> + case PLATFORM_PROFILE_PERFORMANCE:
> + arg = PROF_TO_ARG(AWCC_TMP_PROFILE_PERFORMANCE);
> + break;
> + default:
> + return -EOPNOTSUPP;
> + }
> +
> + ret = awcc_wmi_query(priv->wdev, AWCC_WMI_THERMAL_CONTROL, arg, &res);
> +
> + if (ret < 0)
> + return ret;
> +
> + if (res < 0)
> + return -EBADRQC;
> +
> + return 0;
> +}
> +
> +static int awcc_wmi_probe(struct wmi_device *wdev, const void *context)
> +{
> + struct awcc_wmi_priv *priv;
> +
> + priv = devm_kzalloc(&wdev->dev, sizeof(*priv), GFP_KERNEL);
> + if (!priv)
> + return -ENOMEM;
> +
> + priv->wdev = wdev;
> + dev_set_drvdata(&wdev->dev, priv);
> +
> + priv->handler.profile_set = awcc_platform_profile_set;
> + priv->handler.profile_get = awcc_platform_profile_get;
> +
> + set_bit(PLATFORM_PROFILE_LOW_POWER, priv->handler.choices);
> + set_bit(PLATFORM_PROFILE_QUIET, priv->handler.choices);
> + set_bit(PLATFORM_PROFILE_BALANCED, priv->handler.choices);
> + set_bit(PLATFORM_PROFILE_BALANCED_PERFORMANCE, priv->handler.choices);
> + set_bit(PLATFORM_PROFILE_PERFORMANCE, priv->handler.choices);
> +
> + return platform_profile_register(&priv->handler);
> +}
> +
> +static void awcc_wmi_remove(struct wmi_device *wdev)
> +{
> + platform_profile_remove();
> +}
> +
> +static const struct wmi_device_id awcc_wmi_id_table[] = {
> + { .guid_string = DELL_AWCC_GUID },
> + {},
> +};
> +
> +MODULE_DEVICE_TABLE(wmi, awcc_wmi_id_table);
> +
> +static struct wmi_driver awcc_wmi_driver = {
> + .driver = {
> + .name = "dell-wmi-awcc-platform-profile",
> + .probe_type = PROBE_PREFER_ASYNCHRONOUS,
> + },
> + .id_table = awcc_wmi_id_table,
> + .probe = awcc_wmi_probe,
> + .remove = awcc_wmi_remove,
> + .no_singleton = true,
> +};
> +
> +module_wmi_driver(awcc_wmi_driver);
> +
> +MODULE_AUTHOR("Kurt Borja");
> +MODULE_DESCRIPTION("Dell AWCC WMI driver");
> +MODULE_LICENSE("GPL");
next prev parent reply other threads:[~2024-10-07 12:25 UTC|newest]
Thread overview: 42+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-10-07 9:33 [PATCH] Dell AWCC platform_profile support Kurt Borja
2024-10-07 12:24 ` Armin Wolf [this message]
2024-10-07 17:24 ` Kurt Borja
2024-10-08 4:42 ` [PATCH v2] alienware-wmi: " Kurt Borja
2024-10-08 10:18 ` Ilpo Järvinen
2024-10-08 19:34 ` Kurt Borja
2024-10-08 19:37 ` [PATCH] " Kurt Borja
2024-10-08 20:04 ` Kurt Borja
2024-10-08 19:56 ` [PATCH v3] " Kurt Borja
2024-10-09 8:42 ` Armin Wolf
2024-10-09 14:48 ` Kurt Borja
2024-10-09 15:48 ` Armin Wolf
2024-10-09 8:56 ` Ilpo Järvinen
2024-10-09 15:39 ` Kurt Borja
2024-10-10 3:44 ` kernel test robot
2024-10-10 9:46 ` Ilpo Järvinen
2024-10-10 18:39 ` Kurt Borja
2024-10-15 1:35 ` kernel test robot
2024-10-11 6:40 ` [PATCH 0/4] " Kurt Borja
2024-10-11 6:43 ` [PATCH v4 " Kurt Borja
2024-10-11 6:46 ` [PATCH v4 1/4] alienware-wmi: fixed indentation and clean up Kurt Borja
2024-10-11 11:04 ` Ilpo Järvinen
2024-10-12 1:57 ` Kurt Borja
2024-10-11 6:47 ` [PATCH v4 2/4] alienware-wmi: alienware_wmax_command() is now input size agnostic Kurt Borja
2024-10-11 11:07 ` Ilpo Järvinen
2024-10-11 6:47 ` [PATCH v4 3/4] alienware-wmi: added platform profile support Kurt Borja
2024-10-11 6:48 ` [PATCH v4 4/4] alienware-wmi: WMAX interface documentation Kurt Borja
2024-10-11 11:11 ` Ilpo Järvinen
2024-10-12 1:58 ` [PATCH v5 0/4] Dell AWCC platform_profile support Kurt Borja
2024-10-12 2:01 ` [PATCH v5 1/4] alienware-wmi: fixed indentation and clean up Kurt Borja
2024-10-14 16:26 ` Armin Wolf
2024-10-15 2:12 ` Kurt Borja
2024-10-12 2:01 ` [PATCH v5 2/4] alienware-wmi: alienware_wmax_command() is now input size agnostic Kurt Borja
2024-10-14 16:30 ` Armin Wolf
2024-10-15 2:14 ` Kurt Borja
2024-10-12 2:02 ` [PATCH v5 3/4] alienware-wmi: added platform profile support Kurt Borja
2024-10-14 16:40 ` Armin Wolf
2024-10-15 2:22 ` Kurt Borja
2024-10-15 8:20 ` Ilpo Järvinen
2024-10-12 2:03 ` [PATCH v5 4/4] alienware-wmi: WMAX interface documentation Kurt Borja
2024-10-14 17:10 ` Armin Wolf
2024-10-15 2:26 ` Kurt Borja
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=771d20f1-ebf3-48d9-98ef-ec79b94c7949@gmx.de \
--to=w_armin@gmx.de \
--cc=hdegoede@redhat.com \
--cc=ilpo.jarvinen@linux.intel.com \
--cc=kuurtb@gmail.com \
--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