]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
platform/x86: lenovo-wmi-capdata: Add support for Capability Data 00
authorRong Zhang <i@rong.moe>
Tue, 20 Jan 2026 18:20:05 +0000 (02:20 +0800)
committerIlpo Järvinen <ilpo.jarvinen@linux.intel.com>
Wed, 21 Jan 2026 08:49:54 +0000 (10:49 +0200)
Add support for LENOVO_CAPABILITY_DATA_00 WMI data block that comes on
"Other Mode" enabled hardware. Provides an interface for querying if a
given attribute is supported by the hardware, as well as its default
value.

capdata00 always presents on devices with capdata01. lenovo-wmi-other
now binds to both (no functional change intended).

Signed-off-by: Rong Zhang <i@rong.moe>
Reviewed-by: Derek J. Clark <derekjohn.clark@gmail.com>
Tested-by: Derek J. Clark <derekjohn.clark@gmail.com>
Link: https://patch.msgid.link/20260120182104.163424-5-i@rong.moe
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Documentation/wmi/devices/lenovo-wmi-other.rst
drivers/platform/x86/lenovo/wmi-capdata.c
drivers/platform/x86/lenovo/wmi-capdata.h

index d7928b8dfb4b599231fb912d5470515cf2078d65..fcad595d49af24af95123d385f45ccedd18128de 100644 (file)
@@ -31,13 +31,22 @@ under the following path:
 
   /sys/class/firmware-attributes/lenovo-wmi-other/attributes/<attribute>/
 
+LENOVO_CAPABILITY_DATA_00
+-------------------------
+
+WMI GUID ``362A3AFE-3D96-4665-8530-96DAD5BB300E``
+
+The LENOVO_CAPABILITY_DATA_00 interface provides various information that
+does not rely on the gamezone thermal mode.
+
 LENOVO_CAPABILITY_DATA_01
 -------------------------
 
 WMI GUID ``7A8F5407-CB67-4D6E-B547-39B3BE018154``
 
-The LENOVO_CAPABILITY_DATA_01 interface provides information on various
-power limits of integrated CPU and GPU components.
+The LENOVO_CAPABILITY_DATA_01 interface provides various information that
+relies on the gamezone thermal mode, including power limits of integrated
+CPU and GPU components.
 
 Each attribute has the following properties:
  - current_value
@@ -48,7 +57,7 @@ Each attribute has the following properties:
  - scalar_increment
  - type
 
-The following attributes are implemented:
+The following firmware-attributes are implemented:
  - ppt_pl1_spl: Platform Profile Tracking Sustained Power Limit
  - ppt_pl2_sppt: Platform Profile Tracking Slow Package Power Tracking
  - ppt_pl3_fppt: Platform Profile Tracking Fast Package Power Tracking
index 93ecb49c4c73a09b4c6e255c309ec63bc3c2e512..4ed5b73d430dcbe7741a1ba7dc408a5d12bf050c 100644 (file)
@@ -5,6 +5,9 @@
  * Lenovo Capability Data provides information on tunable attributes used by
  * the "Other Mode" WMI interface.
  *
+ * Capability Data 00 includes if the attribute is supported by the hardware,
+ * and the default_value. All attributes are independent of thermal modes.
+ *
  * Capability Data 01 includes if the attribute is supported by the hardware,
  * and the default_value, max_value, min_value, and step increment. Each
  * attribute has multiple pages, one for each of the thermal modes managed by
 
 #include "wmi-capdata.h"
 
+#define LENOVO_CAPABILITY_DATA_00_GUID "362A3AFE-3D96-4665-8530-96DAD5BB300E"
 #define LENOVO_CAPABILITY_DATA_01_GUID "7A8F5407-CB67-4D6E-B547-39B3BE018154"
 
 #define ACPI_AC_CLASS "ac_adapter"
 #define ACPI_AC_NOTIFY_STATUS 0x80
 
 enum lwmi_cd_type {
+       LENOVO_CAPABILITY_DATA_00,
        LENOVO_CAPABILITY_DATA_01,
 };
 
@@ -59,6 +64,7 @@ static const struct lwmi_cd_info {
        const char *name;
        enum lwmi_cd_type type;
 } lwmi_cd_table[] = {
+       LWMI_CD_TABLE_ITEM(LENOVO_CAPABILITY_DATA_00),
        LWMI_CD_TABLE_ITEM(LENOVO_CAPABILITY_DATA_01),
 };
 
@@ -74,6 +80,7 @@ struct cd_list {
        u8 count;
 
        union {
+               DECLARE_FLEX_ARRAY(struct capdata00, cd00);
                DECLARE_FLEX_ARRAY(struct capdata01, cd01);
        };
 };
@@ -141,6 +148,9 @@ static int lwmi_cd_component_bind(struct device *cd_dev,
        struct lwmi_cd_binder *binder = data;
 
        switch (priv->list->type) {
+       case LENOVO_CAPABILITY_DATA_00:
+               binder->cd00_list = priv->list;
+               break;
        case LENOVO_CAPABILITY_DATA_01:
                binder->cd01_list = priv->list;
                break;
@@ -184,6 +194,9 @@ static const struct component_ops lwmi_cd_component_ops = {
                return -EINVAL;                                                                 \
        }
 
+DEF_LWMI_CDXX_GET_DATA(cd00, LENOVO_CAPABILITY_DATA_00, struct capdata00);
+EXPORT_SYMBOL_NS_GPL(lwmi_cd00_get_data, "LENOVO_WMI_CAPDATA");
+
 DEF_LWMI_CDXX_GET_DATA(cd01, LENOVO_CAPABILITY_DATA_01, struct capdata01);
 EXPORT_SYMBOL_NS_GPL(lwmi_cd01_get_data, "LENOVO_WMI_CAPDATA");
 
@@ -202,6 +215,10 @@ static int lwmi_cd_cache(struct lwmi_cd_priv *priv)
        void *p;
 
        switch (priv->list->type) {
+       case LENOVO_CAPABILITY_DATA_00:
+               p = &priv->list->cd00[0];
+               size = sizeof(priv->list->cd00[0]);
+               break;
        case LENOVO_CAPABILITY_DATA_01:
                p = &priv->list->cd01[0];
                size = sizeof(priv->list->cd01[0]);
@@ -247,6 +264,9 @@ static int lwmi_cd_alloc(struct lwmi_cd_priv *priv, enum lwmi_cd_type type)
        count = wmidev_instance_count(priv->wdev);
 
        switch (type) {
+       case LENOVO_CAPABILITY_DATA_00:
+               list_size = struct_size(list, cd00, count);
+               break;
        case LENOVO_CAPABILITY_DATA_01:
                list_size = struct_size(list, cd01, count);
                break;
@@ -359,6 +379,9 @@ static int lwmi_cd_probe(struct wmi_device *wdev, const void *context)
                goto out;
 
        switch (info->type) {
+       case LENOVO_CAPABILITY_DATA_00:
+               ret = component_add(&wdev->dev, &lwmi_cd_component_ops);
+               goto out;
        case LENOVO_CAPABILITY_DATA_01:
                priv->acpi_nb.notifier_call = lwmi_cd01_notifier_call;
 
@@ -392,6 +415,7 @@ static void lwmi_cd_remove(struct wmi_device *wdev)
        struct lwmi_cd_priv *priv = dev_get_drvdata(&wdev->dev);
 
        switch (priv->list->type) {
+       case LENOVO_CAPABILITY_DATA_00:
        case LENOVO_CAPABILITY_DATA_01:
                component_del(&wdev->dev, &lwmi_cd_component_ops);
                break;
@@ -405,6 +429,7 @@ static void lwmi_cd_remove(struct wmi_device *wdev)
        .context = &lwmi_cd_table[_type],
 
 static const struct wmi_device_id lwmi_cd_id_table[] = {
+       { LWMI_CD_WDEV_ID(LENOVO_CAPABILITY_DATA_00) },
        { LWMI_CD_WDEV_ID(LENOVO_CAPABILITY_DATA_01) },
        {}
 };
index d326f9d2d16593735fbcc4359493f43587ae6c24..a6d006ef458f63f14562592fee864ce6d92e406d 100644 (file)
@@ -11,6 +11,12 @@ struct component_match;
 struct device;
 struct cd_list;
 
+struct capdata00 {
+       u32 id;
+       u32 supported;
+       u32 default_value;
+};
+
 struct capdata01 {
        u32 id;
        u32 supported;
@@ -21,10 +27,12 @@ struct capdata01 {
 };
 
 struct lwmi_cd_binder {
+       struct cd_list *cd00_list;
        struct cd_list *cd01_list;
 };
 
 void lwmi_cd_match_add_all(struct device *master, struct component_match **matchptr);
+int lwmi_cd00_get_data(struct cd_list *list, u32 attribute_id, struct capdata00 *output);
 int lwmi_cd01_get_data(struct cd_list *list, u32 attribute_id, struct capdata01 *output);
 
 #endif /* !_LENOVO_WMI_CAPDATA_H_ */