From nobody Sun Feb 8 09:11:16 2026 Received: from mail-ua1-f51.google.com (mail-ua1-f51.google.com [209.85.222.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 204A241C69; Thu, 6 Mar 2025 00:58:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.222.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741222687; cv=none; b=Cjf+LVKrI5cyjEh0urhIt4SxsWJEucTrFOXugUP6ZsVhm0cCmYGXQZYJnwsQlHBenOLNmlqax5u+zHOYckZ16zuPJO1Mj1ICaRhNBVfMt5Mn1j+LGW4QCSKh2SLx2ztH9ISGqLOW61cZDuYkgFE3utxqHxIaClZku9ZgkEALNF4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741222687; c=relaxed/simple; bh=W3245L2StKIvemIozL1BX/WJzgLB3uNjsg77Bwf+aQc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=YA3TCb0RRYs17c3wkDp6CfghTHRpwxMYQtEBNLGVedgK5qIOV/MbWUwYG9lLw3eyAOBQqlHzSEZMvVxLkXag3xWcdxqHJ3dvnZU4N+iuVKP2917oaHP9CXOwB77QDpKw/w77Yo3ToBAR/7eJB4fluufOL9hF5Xbh7vwaa6XUaUA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=LZrahYaR; arc=none smtp.client-ip=209.85.222.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="LZrahYaR" Received: by mail-ua1-f51.google.com with SMTP id a1e0cc1a2514c-86718c2c3b9so28896241.2; Wed, 05 Mar 2025 16:58:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741222684; x=1741827484; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=3Iwv9GoGUQi5x68b8OratsnyLt/cCmcP1mUBYKH22PI=; b=LZrahYaR6uNjEYY4ySWDDL4jRTV/zGEibdtOOH7wdJIBNfut1XLtBOJlh8hod8Wzyv kOfO/N5IWAuNHeesUf6suYliVTnEStuF5utmVTKDf3WBHu5ZcyzXNMRFHTAAjCJk32fF IZ2/VZkxYsBu8Mr/EaKdiybEDpe92bqT1o6eY62mVRJ04E4mVowZMUH2XH0gWWyFW/SV PhohwhW5N9Lzffz7wczBgBfH7+3u8z47z/3vXjbmLgoPWRf4uMSyoepbW4e+ZytovMuD GC+kvXpL/M8kE+DN0zjFpMPgcDKbh/74tsyw4GEOS9gP3lKK/eq30OAnVEAMlNkv43hO IHqQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741222684; x=1741827484; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=3Iwv9GoGUQi5x68b8OratsnyLt/cCmcP1mUBYKH22PI=; b=rAkuBGIigPCqtxJWeje4jHf+SOFbwls3mcZLqvRcVnC/FGRtJYjUE12lXruKY/YA3W BvmSNaTOoqyPZluf/GYE39BlCaygA3r77YI/HaFOXaXiEggkgdhR0pmk0WTPv6UDOb6Z ErOSyvQdFuDz/yL0r92Lo/l9bAeyxtAlafsH3THcOdvY/IZgYuXCKvvylGIb05uCwsOe yQui0Oygf5oOuHHQmHW/lFvIispx2Mbs8O01A7uSj+k92ugu+Edyh/mn/qHgj7p2sIop rk9c/OguPsrHryHvIMcdO0mj2qHf8McaNzTjY1pibDSQ12BqiVkfxjAvNy3DynFuaiRe ufaw== X-Forwarded-Encrypted: i=1; AJvYcCWdG5rI884lKjRNkrDJv0vFY25fB6iFyR+MAycSASV9m06R/sq3VYVlKahXFij6E6c94oEzGOmk/cZxZG9oP2kP1RBDqg==@vger.kernel.org, AJvYcCWkPizDIRRlg2ANDrultSxyvvZE2RpcHEfQ2tQqT/aOtFb+khTNunTrUJzuvvq/sc66ZcygAUDPXakXzwA=@vger.kernel.org X-Gm-Message-State: AOJu0YwfI7rR5JCdY4rCwWK+ma9T2Uf8jTkQTMeKFAi+QsQ+zb0945JT xNDq1tgre1nZCc+Rg3Il+ghtpV88b0QRBkFdbe3IyMI2DpqQHiZs X-Gm-Gg: ASbGncuvkWgWNz4UMnwB+EqO7H1O/7yIqCTnsOKmE9reWZsA6jJagPqj6xYSzXwpkvM iQiW2YMCfYAkjWpM23XvM+OjSeJUAzBdUV7Ol9EaFb+FJ+Yjc5JDs+b0XQM6pu8/TDi6QOfiCBu eaKGgmLWfegOLCeZVUTZWatI2nMvfg94bBeQKrDdjMuqeaAV3nC5A5rfuhY3yWx5H8zaiuSNDq3 sqVNaUAV/Wy2tvHRn+d1f+u3CPJSqqTEF0tyBWEuzdR3HhCFyAbURTR09E4Fok9KmMR5pOLX/DP C4jGcyow8j2kLUT3HQJZpyn8XiqlsH7tiUtDVVs3CsHqXA== X-Google-Smtp-Source: AGHT+IHjLxyT9JcOEoiYFp2yKEZD2idSw44lvceEsAmLNiS6GDBP8w+FPMek6FcVSgTh6nDbrdgJAg== X-Received: by 2002:a05:6102:1607:b0:4ba:eb24:fb28 with SMTP id ada2fe7eead31-4c2e274c502mr3900924137.3.1741222683866; Wed, 05 Mar 2025 16:58:03 -0800 (PST) Received: from [192.168.100.70] ([2800:bf0:82:3d2:9e61:1a62:1a8c:3e62]) by smtp.gmail.com with ESMTPSA id a1e0cc1a2514c-86d33bc0065sm25925241.4.2025.03.05.16.58.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 05 Mar 2025 16:58:03 -0800 (PST) From: Kurt Borja Date: Wed, 05 Mar 2025 19:56:52 -0500 Subject: [PATCH v3 01/10] platform/x86: alienware-wmi-wmax: Rename thermal related symbols Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250305-hwm-v3-1-395e7a1407e2@gmail.com> References: <20250305-hwm-v3-0-395e7a1407e2@gmail.com> In-Reply-To: <20250305-hwm-v3-0-395e7a1407e2@gmail.com> To: =?utf-8?q?Ilpo_J=C3=A4rvinen?= , Armin Wolf Cc: Kurt Borja , Hans de Goede , platform-driver-x86@vger.kernel.org, Dell.Client.Kernel@dell.com, linux-kernel@vger.kernel.org X-Mailer: b4 0.14.2 The "thermal" features of the WMAX WMI device are only present on the host device if the ACPI _UID is "AWCC". Replace WMAX prefixes with "AWCC" to reflect this relationship. Thermal profiles with WMAX_PROFILE_BASIC prefix are also renamed to WMAX_PROFILE_LEGACY because they are only supported in older versions of this WMI device. Reviewed-by: Armin Wolf Signed-off-by: Kurt Borja --- drivers/platform/x86/dell/alienware-wmi-wmax.c | 173 +++++++++++++--------= ---- 1 file changed, 87 insertions(+), 86 deletions(-) diff --git a/drivers/platform/x86/dell/alienware-wmi-wmax.c b/drivers/platf= orm/x86/dell/alienware-wmi-wmax.c index 3d3014b5adf046c94c1ebf39a0e28a92622b40d6..ed70e12d73d7fe5d89f3364c536= 7820bf47e3c1e 100644 --- a/drivers/platform/x86/dell/alienware-wmi-wmax.c +++ b/drivers/platform/x86/dell/alienware-wmi-wmax.c @@ -24,16 +24,17 @@ #define WMAX_METHOD_DEEP_SLEEP_STATUS 0x0C #define WMAX_METHOD_BRIGHTNESS 0x3 #define WMAX_METHOD_ZONE_CONTROL 0x4 -#define WMAX_METHOD_THERMAL_INFORMATION 0x14 -#define WMAX_METHOD_THERMAL_CONTROL 0x15 -#define WMAX_METHOD_GAME_SHIFT_STATUS 0x25 =20 -#define WMAX_THERMAL_MODE_GMODE 0xAB +#define AWCC_METHOD_THERMAL_INFORMATION 0x14 +#define AWCC_METHOD_THERMAL_CONTROL 0x15 +#define AWCC_METHOD_GAME_SHIFT_STATUS 0x25 =20 -#define WMAX_FAILURE_CODE 0xFFFFFFFF -#define WMAX_THERMAL_TABLE_MASK GENMASK(7, 4) -#define WMAX_THERMAL_MODE_MASK GENMASK(3, 0) -#define WMAX_SENSOR_ID_MASK BIT(8) +#define AWCC_THERMAL_MODE_GMODE 0xAB + +#define AWCC_FAILURE_CODE 0xFFFFFFFF +#define AWCC_THERMAL_TABLE_MASK GENMASK(7, 4) +#define AWCC_THERMAL_MODE_MASK GENMASK(3, 0) +#define AWCC_SENSOR_ID_MASK BIT(8) =20 static bool force_platform_profile; module_param_unsafe(force_platform_profile, bool, 0); @@ -151,38 +152,38 @@ static const struct dmi_system_id awcc_dmi_table[] __= initconst =3D { }, }; =20 -enum WMAX_THERMAL_INFORMATION_OPERATIONS { - WMAX_OPERATION_SYS_DESCRIPTION =3D 0x02, - WMAX_OPERATION_LIST_IDS =3D 0x03, - WMAX_OPERATION_CURRENT_PROFILE =3D 0x0B, +enum AWCC_THERMAL_INFORMATION_OPERATIONS { + AWCC_OP_GET_SYSTEM_DESCRIPTION =3D 0x02, + AWCC_OP_GET_RESOURCE_ID =3D 0x03, + AWCC_OP_GET_CURRENT_PROFILE =3D 0x0B, }; =20 -enum WMAX_THERMAL_CONTROL_OPERATIONS { - WMAX_OPERATION_ACTIVATE_PROFILE =3D 0x01, +enum AWCC_THERMAL_CONTROL_OPERATIONS { + AWCC_OP_ACTIVATE_PROFILE =3D 0x01, }; =20 -enum WMAX_GAME_SHIFT_STATUS_OPERATIONS { - WMAX_OPERATION_TOGGLE_GAME_SHIFT =3D 0x01, - WMAX_OPERATION_GET_GAME_SHIFT_STATUS =3D 0x02, +enum AWCC_GAME_SHIFT_STATUS_OPERATIONS { + AWCC_OP_TOGGLE_GAME_SHIFT =3D 0x01, + AWCC_OP_GET_GAME_SHIFT_STATUS =3D 0x02, }; =20 -enum WMAX_THERMAL_TABLES { - WMAX_THERMAL_TABLE_BASIC =3D 0x90, - WMAX_THERMAL_TABLE_USTT =3D 0xA0, +enum AWCC_THERMAL_TABLES { + AWCC_THERMAL_TABLE_LEGACY =3D 0x90, + AWCC_THERMAL_TABLE_USTT =3D 0xA0, }; =20 -enum wmax_thermal_mode { - THERMAL_MODE_USTT_BALANCED, - THERMAL_MODE_USTT_BALANCED_PERFORMANCE, - THERMAL_MODE_USTT_COOL, - THERMAL_MODE_USTT_QUIET, - THERMAL_MODE_USTT_PERFORMANCE, - THERMAL_MODE_USTT_LOW_POWER, - THERMAL_MODE_BASIC_QUIET, - THERMAL_MODE_BASIC_BALANCED, - THERMAL_MODE_BASIC_BALANCED_PERFORMANCE, - THERMAL_MODE_BASIC_PERFORMANCE, - THERMAL_MODE_LAST, +enum awcc_thermal_profile { + AWCC_PROFILE_USTT_BALANCED, + AWCC_PROFILE_USTT_BALANCED_PERFORMANCE, + AWCC_PROFILE_USTT_COOL, + AWCC_PROFILE_USTT_QUIET, + AWCC_PROFILE_USTT_PERFORMANCE, + AWCC_PROFILE_USTT_LOW_POWER, + AWCC_PROFILE_LEGACY_QUIET, + AWCC_PROFILE_LEGACY_BALANCED, + AWCC_PROFILE_LEGACY_BALANCED_PERFORMANCE, + AWCC_PROFILE_LEGACY_PERFORMANCE, + AWCC_PROFILE_LAST, }; =20 struct wmax_led_args { @@ -210,20 +211,20 @@ struct wmax_u32_args { struct awcc_priv { struct wmi_device *wdev; struct device *ppdev; - enum wmax_thermal_mode supported_thermal_profiles[PLATFORM_PROFILE_LAST]; + enum awcc_thermal_profile supported_thermal_profiles[PLATFORM_PROFILE_LAS= T]; }; =20 -static const enum platform_profile_option wmax_mode_to_platform_profile[TH= ERMAL_MODE_LAST] =3D { - [THERMAL_MODE_USTT_BALANCED] =3D PLATFORM_PROFILE_BALANCED, - [THERMAL_MODE_USTT_BALANCED_PERFORMANCE] =3D PLATFORM_PROFILE_BALANCED_PE= RFORMANCE, - [THERMAL_MODE_USTT_COOL] =3D PLATFORM_PROFILE_COOL, - [THERMAL_MODE_USTT_QUIET] =3D PLATFORM_PROFILE_QUIET, - [THERMAL_MODE_USTT_PERFORMANCE] =3D PLATFORM_PROFILE_PERFORMANCE, - [THERMAL_MODE_USTT_LOW_POWER] =3D PLATFORM_PROFILE_LOW_POWER, - [THERMAL_MODE_BASIC_QUIET] =3D PLATFORM_PROFILE_QUIET, - [THERMAL_MODE_BASIC_BALANCED] =3D PLATFORM_PROFILE_BALANCED, - [THERMAL_MODE_BASIC_BALANCED_PERFORMANCE] =3D PLATFORM_PROFILE_BALANCED_P= ERFORMANCE, - [THERMAL_MODE_BASIC_PERFORMANCE] =3D PLATFORM_PROFILE_PERFORMANCE, +static const enum platform_profile_option awcc_mode_to_platform_profile[AW= CC_PROFILE_LAST] =3D { + [AWCC_PROFILE_USTT_BALANCED] =3D PLATFORM_PROFILE_BALANCED, + [AWCC_PROFILE_USTT_BALANCED_PERFORMANCE] =3D PLATFORM_PROFILE_BALANCED_PE= RFORMANCE, + [AWCC_PROFILE_USTT_COOL] =3D PLATFORM_PROFILE_COOL, + [AWCC_PROFILE_USTT_QUIET] =3D PLATFORM_PROFILE_QUIET, + [AWCC_PROFILE_USTT_PERFORMANCE] =3D PLATFORM_PROFILE_PERFORMANCE, + [AWCC_PROFILE_USTT_LOW_POWER] =3D PLATFORM_PROFILE_LOW_POWER, + [AWCC_PROFILE_LEGACY_QUIET] =3D PLATFORM_PROFILE_QUIET, + [AWCC_PROFILE_LEGACY_BALANCED] =3D PLATFORM_PROFILE_BALANCED, + [AWCC_PROFILE_LEGACY_BALANCED_PERFORMANCE] =3D PLATFORM_PROFILE_BALANCED_= PERFORMANCE, + [AWCC_PROFILE_LEGACY_PERFORMANCE] =3D PLATFORM_PROFILE_PERFORMANCE, }; =20 static struct awcc_quirks *awcc; @@ -444,26 +445,26 @@ const struct attribute_group wmax_deepsleep_attribute= _group =3D { * Thermal Profile control * - Provides thermal profile control through the Platform Profile API */ -static bool is_wmax_thermal_code(u32 code) +static bool is_awcc_thermal_mode(u32 code) { - if (code & WMAX_SENSOR_ID_MASK) + if (code & AWCC_SENSOR_ID_MASK) return false; =20 - if ((code & WMAX_THERMAL_MODE_MASK) >=3D THERMAL_MODE_LAST) + if ((code & AWCC_THERMAL_MODE_MASK) >=3D AWCC_PROFILE_LAST) return false; =20 - if ((code & WMAX_THERMAL_TABLE_MASK) =3D=3D WMAX_THERMAL_TABLE_BASIC && - (code & WMAX_THERMAL_MODE_MASK) >=3D THERMAL_MODE_BASIC_QUIET) + if ((code & AWCC_THERMAL_TABLE_MASK) =3D=3D AWCC_THERMAL_TABLE_LEGACY && + (code & AWCC_THERMAL_MODE_MASK) >=3D AWCC_PROFILE_LEGACY_QUIET) return true; =20 - if ((code & WMAX_THERMAL_TABLE_MASK) =3D=3D WMAX_THERMAL_TABLE_USTT && - (code & WMAX_THERMAL_MODE_MASK) <=3D THERMAL_MODE_USTT_LOW_POWER) + if ((code & AWCC_THERMAL_TABLE_MASK) =3D=3D AWCC_THERMAL_TABLE_USTT && + (code & AWCC_THERMAL_MODE_MASK) <=3D AWCC_PROFILE_USTT_LOW_POWER) return true; =20 return false; } =20 -static int wmax_thermal_information(struct wmi_device *wdev, u8 operation, +static int awcc_thermal_information(struct wmi_device *wdev, u8 operation, u8 arg, u32 *out_data) { struct wmax_u32_args in_args =3D { @@ -474,21 +475,21 @@ static int wmax_thermal_information(struct wmi_device= *wdev, u8 operation, }; int ret; =20 - ret =3D alienware_wmi_command(wdev, WMAX_METHOD_THERMAL_INFORMATION, + ret =3D alienware_wmi_command(wdev, AWCC_METHOD_THERMAL_INFORMATION, &in_args, sizeof(in_args), out_data); if (ret < 0) return ret; =20 - if (*out_data =3D=3D WMAX_FAILURE_CODE) + if (*out_data =3D=3D AWCC_FAILURE_CODE) return -EBADRQC; =20 return 0; } =20 -static int wmax_thermal_control(struct wmi_device *wdev, u8 profile) +static int awcc_thermal_control(struct wmi_device *wdev, u8 profile) { struct wmax_u32_args in_args =3D { - .operation =3D WMAX_OPERATION_ACTIVATE_PROFILE, + .operation =3D AWCC_OP_ACTIVATE_PROFILE, .arg1 =3D profile, .arg2 =3D 0, .arg3 =3D 0, @@ -496,18 +497,18 @@ static int wmax_thermal_control(struct wmi_device *wd= ev, u8 profile) u32 out_data; int ret; =20 - ret =3D alienware_wmi_command(wdev, WMAX_METHOD_THERMAL_CONTROL, + ret =3D alienware_wmi_command(wdev, AWCC_METHOD_THERMAL_CONTROL, &in_args, sizeof(in_args), &out_data); if (ret) return ret; =20 - if (out_data =3D=3D WMAX_FAILURE_CODE) + if (out_data =3D=3D AWCC_FAILURE_CODE) return -EBADRQC; =20 return 0; } =20 -static int wmax_game_shift_status(struct wmi_device *wdev, u8 operation, +static int awcc_game_shift_status(struct wmi_device *wdev, u8 operation, u32 *out_data) { struct wmax_u32_args in_args =3D { @@ -518,46 +519,46 @@ static int wmax_game_shift_status(struct wmi_device *= wdev, u8 operation, }; int ret; =20 - ret =3D alienware_wmi_command(wdev, WMAX_METHOD_GAME_SHIFT_STATUS, + ret =3D alienware_wmi_command(wdev, AWCC_METHOD_GAME_SHIFT_STATUS, &in_args, sizeof(in_args), out_data); if (ret < 0) return ret; =20 - if (*out_data =3D=3D WMAX_FAILURE_CODE) + if (*out_data =3D=3D AWCC_FAILURE_CODE) return -EOPNOTSUPP; =20 return 0; } =20 -static int thermal_profile_get(struct device *dev, - enum platform_profile_option *profile) +static int awcc_platform_profile_get(struct device *dev, + enum platform_profile_option *profile) { struct awcc_priv *priv =3D dev_get_drvdata(dev); u32 out_data; int ret; =20 - ret =3D wmax_thermal_information(priv->wdev, WMAX_OPERATION_CURRENT_PROFI= LE, + ret =3D awcc_thermal_information(priv->wdev, AWCC_OP_GET_CURRENT_PROFILE, 0, &out_data); =20 if (ret < 0) return ret; =20 - if (out_data =3D=3D WMAX_THERMAL_MODE_GMODE) { + if (out_data =3D=3D AWCC_THERMAL_MODE_GMODE) { *profile =3D PLATFORM_PROFILE_PERFORMANCE; return 0; } =20 - if (!is_wmax_thermal_code(out_data)) + if (!is_awcc_thermal_mode(out_data)) return -ENODATA; =20 - out_data &=3D WMAX_THERMAL_MODE_MASK; - *profile =3D wmax_mode_to_platform_profile[out_data]; + out_data &=3D AWCC_THERMAL_MODE_MASK; + *profile =3D awcc_mode_to_platform_profile[out_data]; =20 return 0; } =20 -static int thermal_profile_set(struct device *dev, - enum platform_profile_option profile) +static int awcc_platform_profile_set(struct device *dev, + enum platform_profile_option profile) { struct awcc_priv *priv =3D dev_get_drvdata(dev); =20 @@ -565,8 +566,8 @@ static int thermal_profile_set(struct device *dev, u32 gmode_status; int ret; =20 - ret =3D wmax_game_shift_status(priv->wdev, - WMAX_OPERATION_GET_GAME_SHIFT_STATUS, + ret =3D awcc_game_shift_status(priv->wdev, + AWCC_OP_GET_GAME_SHIFT_STATUS, &gmode_status); =20 if (ret < 0) @@ -574,8 +575,8 @@ static int thermal_profile_set(struct device *dev, =20 if ((profile =3D=3D PLATFORM_PROFILE_PERFORMANCE && !gmode_status) || (profile !=3D PLATFORM_PROFILE_PERFORMANCE && gmode_status)) { - ret =3D wmax_game_shift_status(priv->wdev, - WMAX_OPERATION_TOGGLE_GAME_SHIFT, + ret =3D awcc_game_shift_status(priv->wdev, + AWCC_OP_TOGGLE_GAME_SHIFT, &gmode_status); =20 if (ret < 0) @@ -583,21 +584,21 @@ static int thermal_profile_set(struct device *dev, } } =20 - return wmax_thermal_control(priv->wdev, + return awcc_thermal_control(priv->wdev, priv->supported_thermal_profiles[profile]); } =20 -static int thermal_profile_probe(void *drvdata, unsigned long *choices) +static int awcc_platform_profile_probe(void *drvdata, unsigned long *choic= es) { enum platform_profile_option profile; struct awcc_priv *priv =3D drvdata; - enum wmax_thermal_mode mode; + enum awcc_thermal_profile mode; u8 sys_desc[4]; u32 first_mode; u32 out_data; int ret; =20 - ret =3D wmax_thermal_information(priv->wdev, WMAX_OPERATION_SYS_DESCRIPTI= ON, + ret =3D awcc_thermal_information(priv->wdev, AWCC_OP_GET_SYSTEM_DESCRIPTI= ON, 0, (u32 *) &sys_desc); if (ret < 0) return ret; @@ -605,7 +606,7 @@ static int thermal_profile_probe(void *drvdata, unsigne= d long *choices) first_mode =3D sys_desc[0] + sys_desc[1]; =20 for (u32 i =3D 0; i < sys_desc[3]; i++) { - ret =3D wmax_thermal_information(priv->wdev, WMAX_OPERATION_LIST_IDS, + ret =3D awcc_thermal_information(priv->wdev, AWCC_OP_GET_RESOURCE_ID, i + first_mode, &out_data); =20 if (ret =3D=3D -EIO) @@ -614,11 +615,11 @@ static int thermal_profile_probe(void *drvdata, unsig= ned long *choices) if (ret =3D=3D -EBADRQC) break; =20 - if (!is_wmax_thermal_code(out_data)) + if (!is_awcc_thermal_mode(out_data)) continue; =20 - mode =3D out_data & WMAX_THERMAL_MODE_MASK; - profile =3D wmax_mode_to_platform_profile[mode]; + mode =3D out_data & AWCC_THERMAL_MODE_MASK; + profile =3D awcc_mode_to_platform_profile[mode]; priv->supported_thermal_profiles[profile] =3D out_data; =20 set_bit(profile, choices); @@ -629,7 +630,7 @@ static int thermal_profile_probe(void *drvdata, unsigne= d long *choices) =20 if (awcc->gmode) { priv->supported_thermal_profiles[PLATFORM_PROFILE_PERFORMANCE] =3D - WMAX_THERMAL_MODE_GMODE; + AWCC_THERMAL_MODE_GMODE; =20 set_bit(PLATFORM_PROFILE_PERFORMANCE, choices); } @@ -638,9 +639,9 @@ static int thermal_profile_probe(void *drvdata, unsigne= d long *choices) } =20 static const struct platform_profile_ops awcc_platform_profile_ops =3D { - .probe =3D thermal_profile_probe, - .profile_get =3D thermal_profile_get, - .profile_set =3D thermal_profile_set, + .probe =3D awcc_platform_profile_probe, + .profile_get =3D awcc_platform_profile_get, + .profile_set =3D awcc_platform_profile_set, }; =20 static int awcc_platform_profile_init(struct wmi_device *wdev) --=20 2.48.1 From nobody Sun Feb 8 09:11:16 2026 Received: from mail-ua1-f54.google.com (mail-ua1-f54.google.com [209.85.222.54]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B28D078F5F; Thu, 6 Mar 2025 00:58:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.222.54 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741222689; cv=none; b=r1IBQdLOAov4kGL+ISUvHSp0cEw1sMOmJl6JEk8HZF0jbRbrFhdGTuNEJeYYYNpU9VGYeRpcOaLqvvCLWGZ50dAjL1DkrX3ZvVftteF8Fr/5PSEu84dxiXAiUwypNcH+NH9Iuw+1Qcv1yg8Y/Gp+q7ceoeEuE3IyiRkIgkkCso8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741222689; c=relaxed/simple; bh=b6I4LW2lXRr4zSKyCgVo5hQkgsNPWVdZQx2aOlTduKg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=aFhfzqnhmSAcVJgCeMqeB6ikp81uoYsOw2hBxnA81K9seCu3RQxHZYwNTCBjyu10P5kCqczxwbaWR5HWKUsy1Gp+C7ip1uhW0HwP9S76csX3n8yl7ufAPWsmog4gaRocnb1QZFrYobV8sKSh6bkQtrWa94lYCOJmZCbVnwOPPB4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=jghDMRvF; arc=none smtp.client-ip=209.85.222.54 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="jghDMRvF" Received: by mail-ua1-f54.google.com with SMTP id a1e0cc1a2514c-866e8ca2e07so26286241.2; Wed, 05 Mar 2025 16:58:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741222686; x=1741827486; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=ki8JJlqvtQ1DWozBXa70s7Vleuhvzvt2Tgc/aHkAO4s=; b=jghDMRvFyL2uJC1VyJWvIyAhKDNh1aNd1WcJWEgFWXryOCwxBfMaP1T0ILiClNk2f6 MxAICMJmWrGtyzuuPu7JjM/cAKhZzX2uXqEGq1v4TVwJd5GsnadlmXjUnV8+PQ2wnUJd YJ0vesUd3VOk6rFvrMJAAhkmOkDHEz8IgCNXJn/jjBX+XoFqkatrSZNgXJphpvQM7FlO Ec4zyMLbegUZgqtGmyOKuY1tX3MeIaG1Dnr/9C2uEGCf9UpeR25KWZBRZdk7m8CJNuFs uhcQ1ax7aaPYhphLy0DcfK0MgO4qSiyiUGoJuy4H23/uGLSBlEXh7LyAFitjPluYTLG9 25hQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741222686; x=1741827486; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ki8JJlqvtQ1DWozBXa70s7Vleuhvzvt2Tgc/aHkAO4s=; b=aHTw3kdz1mGVscIk9QplOCriR/LkXO0jbidyMXLUmmzsATv/GbGtnkzaksSbpK0+kk 0nJhoc9EZqiFCMjdafESEK6+5jzAjPr5cG7eftwC+M9CF45aR2uQBcPWrWluYBOBop9X m8QqN/vkIjjGPv1nFp1FjY1hITaB3oYtrrXkzSkWifmbxVsibfNCbgg5DMrdpeYFiv0o Qp5fL6MEqXskW090vHCp6WUsUHiK/8c3dtmlbECEzpL/gLyXTAZFHXvrSHRznE83X+Kc 1wqs0qk/d7jcPt40M6OPmfy0ohTWg+zHKtUIrM8+NBBZS9oGb3Nc6/V2YDNehHZFboZV hrfQ== X-Forwarded-Encrypted: i=1; AJvYcCU5WTyzDvxJ729fFiqKYP60LrBm5UzFpuUNDClEFzPh7TpmavXT0o81n0MdeXOIO/SNgvESWdihqUs5qsc=@vger.kernel.org, AJvYcCWWDLfSiPafYxh7hpsWjHKq8agyHV+3xpRnOEpmlVZgE4QuLBn2f4B7GAC3SnZ7tMXClW3EBhhgaps2VS5VqglNd00yGA==@vger.kernel.org X-Gm-Message-State: AOJu0Yy9rJdde5SxNCI/nnpmFJr4g3O5iAngWNNlGNpso2wcavwfekYZ yjzRvD5YonhfBHZJoL4TTL/l2QBiSjIogpyQutT4eiPJJrVzY8kv X-Gm-Gg: ASbGnctbtzyCHYC81/RPFVrIldrLZ1EmX1vREPdKxB8FcImx07d2kTcCTLWTw8XpeaU h/PzJtRf2ySCBEqEy2Ivwtg+2pU6ZdCEC002q0otxd5V3f1P7nSGivLeDwek7ccgHFAG2Nf9DTv ZY8IMnfQyd/jGeOyhpvfjPRYzH72n7gtBC3yUvnsDu36dUlTP+IZs/m1uflKv5REQRuuL+vplNm 0t1D9GAQRSkbu5rBp0NzhZyaNhQ2Fa663GZtwWcLdfgAwBqSpdtaO1nG1yOtrOVTFuftOoSu29e lUY6g7lbemiAOvKDcixa9/OFPYpOENz3Dl9uzDKPiFEX0Q== X-Google-Smtp-Source: AGHT+IGYJ2Kwm94NxvxLE3z8rOGG4vI0Idfd8cmaBbsHi4SYa421/zLC3APTGFGjeMZkyPoZcoO/Eg== X-Received: by 2002:a05:6102:808f:b0:4bd:3924:44c3 with SMTP id ada2fe7eead31-4c2e276730bmr3270170137.6.1741222686492; Wed, 05 Mar 2025 16:58:06 -0800 (PST) Received: from [192.168.100.70] ([2800:bf0:82:3d2:9e61:1a62:1a8c:3e62]) by smtp.gmail.com with ESMTPSA id a1e0cc1a2514c-86d33bc0065sm25925241.4.2025.03.05.16.58.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 05 Mar 2025 16:58:05 -0800 (PST) From: Kurt Borja Date: Wed, 05 Mar 2025 19:56:53 -0500 Subject: [PATCH v3 02/10] platform/x86: alienware-wmi-wmax: Refactor is_awcc_thermal_mode() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250305-hwm-v3-2-395e7a1407e2@gmail.com> References: <20250305-hwm-v3-0-395e7a1407e2@gmail.com> In-Reply-To: <20250305-hwm-v3-0-395e7a1407e2@gmail.com> To: =?utf-8?q?Ilpo_J=C3=A4rvinen?= , Armin Wolf Cc: Kurt Borja , Hans de Goede , platform-driver-x86@vger.kernel.org, Dell.Client.Kernel@dell.com, linux-kernel@vger.kernel.org X-Mailer: b4 0.14.2 Refactor is_awcc_thermal_mode() to use FIELD_GET() instead of bitwise operations. Drop the check for BIT(8) sensor flag and rename it to is_awcc_thermal_profile_id(). Reviewed-by: Armin Wolf Signed-off-by: Kurt Borja --- drivers/platform/x86/dell/alienware-wmi-wmax.c | 33 +++++++++++++---------= ---- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/drivers/platform/x86/dell/alienware-wmi-wmax.c b/drivers/platf= orm/x86/dell/alienware-wmi-wmax.c index ed70e12d73d7fe5d89f3364c5367820bf47e3c1e..80aefba5b22d6b4ac18aeb2ca35= 6f8c911150abd 100644 --- a/drivers/platform/x86/dell/alienware-wmi-wmax.c +++ b/drivers/platform/x86/dell/alienware-wmi-wmax.c @@ -34,7 +34,8 @@ #define AWCC_FAILURE_CODE 0xFFFFFFFF #define AWCC_THERMAL_TABLE_MASK GENMASK(7, 4) #define AWCC_THERMAL_MODE_MASK GENMASK(3, 0) -#define AWCC_SENSOR_ID_MASK BIT(8) +/* Some IDs have a BIT(8) flag that we ignore */ +#define AWCC_RESOURCE_ID_MASK GENMASK(7, 0) =20 static bool force_platform_profile; module_param_unsafe(force_platform_profile, bool, 0); @@ -168,8 +169,8 @@ enum AWCC_GAME_SHIFT_STATUS_OPERATIONS { }; =20 enum AWCC_THERMAL_TABLES { - AWCC_THERMAL_TABLE_LEGACY =3D 0x90, - AWCC_THERMAL_TABLE_USTT =3D 0xA0, + AWCC_THERMAL_TABLE_LEGACY =3D 0x9, + AWCC_THERMAL_TABLE_USTT =3D 0xA, }; =20 enum awcc_thermal_profile { @@ -445,20 +446,18 @@ const struct attribute_group wmax_deepsleep_attribute= _group =3D { * Thermal Profile control * - Provides thermal profile control through the Platform Profile API */ -static bool is_awcc_thermal_mode(u32 code) +static bool is_awcc_thermal_profile_id(u8 code) { - if (code & AWCC_SENSOR_ID_MASK) + u8 table =3D FIELD_GET(AWCC_THERMAL_TABLE_MASK, code); + u8 mode =3D FIELD_GET(AWCC_THERMAL_MODE_MASK, code); + + if (mode >=3D AWCC_PROFILE_LAST) return false; =20 - if ((code & AWCC_THERMAL_MODE_MASK) >=3D AWCC_PROFILE_LAST) - return false; - - if ((code & AWCC_THERMAL_TABLE_MASK) =3D=3D AWCC_THERMAL_TABLE_LEGACY && - (code & AWCC_THERMAL_MODE_MASK) >=3D AWCC_PROFILE_LEGACY_QUIET) + if (table =3D=3D AWCC_THERMAL_TABLE_LEGACY && mode >=3D AWCC_PROFILE_LEGA= CY_QUIET) return true; =20 - if ((code & AWCC_THERMAL_TABLE_MASK) =3D=3D AWCC_THERMAL_TABLE_USTT && - (code & AWCC_THERMAL_MODE_MASK) <=3D AWCC_PROFILE_USTT_LOW_POWER) + if (table =3D=3D AWCC_THERMAL_TABLE_USTT && mode <=3D AWCC_PROFILE_USTT_L= OW_POWER) return true; =20 return false; @@ -548,7 +547,7 @@ static int awcc_platform_profile_get(struct device *dev, return 0; } =20 - if (!is_awcc_thermal_mode(out_data)) + if (!is_awcc_thermal_profile_id(out_data)) return -ENODATA; =20 out_data &=3D AWCC_THERMAL_MODE_MASK; @@ -597,6 +596,7 @@ static int awcc_platform_profile_probe(void *drvdata, u= nsigned long *choices) u32 first_mode; u32 out_data; int ret; + u8 id; =20 ret =3D awcc_thermal_information(priv->wdev, AWCC_OP_GET_SYSTEM_DESCRIPTI= ON, 0, (u32 *) &sys_desc); @@ -615,12 +615,13 @@ static int awcc_platform_profile_probe(void *drvdata,= unsigned long *choices) if (ret =3D=3D -EBADRQC) break; =20 - if (!is_awcc_thermal_mode(out_data)) + id =3D FIELD_GET(AWCC_RESOURCE_ID_MASK, out_data); + if (!is_awcc_thermal_profile_id(id)) continue; =20 - mode =3D out_data & AWCC_THERMAL_MODE_MASK; + mode =3D FIELD_GET(AWCC_THERMAL_MODE_MASK, id); profile =3D awcc_mode_to_platform_profile[mode]; - priv->supported_thermal_profiles[profile] =3D out_data; + priv->supported_thermal_profiles[profile] =3D id; =20 set_bit(profile, choices); } --=20 2.48.1 From nobody Sun Feb 8 09:11:16 2026 Received: from mail-ua1-f41.google.com (mail-ua1-f41.google.com [209.85.222.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 947CB12DD8A; Thu, 6 Mar 2025 00:58:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.222.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741222691; cv=none; b=uTb2uCKlUsg4+if4iDd7GB51sWuK97VzJxizhFkQY+5s1IUvrgY11Ne8uMyKA+LhvSRoTsot/mvIN8xQbA92iraiZLRFATTNWMmz/93Og8ZcERAohxpxfoPEHiG6dMS67jn0PpYSA4Kh0riqCzzv5Jmj6lZ448O/SIIPlGtgOas= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741222691; c=relaxed/simple; bh=6pz4VhrhIGqny7cbRCTOhDTaZOjL/S2VzUcxV3dliOw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=He3EUdx9u6NmHh5CBjRRJi3uB7bMkQ4e/1aE1BDGchnFW2wbI1vb9PmZNxIthdNnTizxbiyo0bbMWJM4smWQEZgpOS9dtAKItEM16OL+kkNTaTBS4UgcWJTdrmiQLAx0Rmrqd3VNpTnI1odF80DrY7AyNo9unAA4sX3E7vbZ3Ho= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=QMQrKQwt; arc=none smtp.client-ip=209.85.222.41 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="QMQrKQwt" Received: by mail-ua1-f41.google.com with SMTP id a1e0cc1a2514c-866de72bb82so26320241.1; Wed, 05 Mar 2025 16:58:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741222688; x=1741827488; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=jLcOSdpVynHXpxSTVSEYzflauiFisNmhaYmXFaXmnXU=; b=QMQrKQwtLWfrhfE18nuMRVX7/TbMJ0h4guDC/vENwX7gIsKKD/LIJBcheIor/tj4fX ykzhGIG7beLPHhhMp9V/6uoLSl5n6XfWCyZuwiObrEkCY/wVzwA0FsJCsNMoqYmmcu1B DJ5UY4IrKlwmGZZLGrtDVEIAZwkAW8qgGpsh+1mPNhDmpcGCPywWG1JLgpBA23MsVrFV khBFj0rhKnahKmtj8CdQ0XLJ9Z4zNQRp9f7sNSdbqWxGCaB/hGCwHPLyuq14e7jdP7Pt XXs46xZmjYR5Lkyc+M4rUpoIukkTIzIV06qGCvZq4maTp4lKBp5X+xbf/rY2ey1QPkdz i0hQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741222688; x=1741827488; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=jLcOSdpVynHXpxSTVSEYzflauiFisNmhaYmXFaXmnXU=; b=qDQLVyUaw5gx0/y4O8FokSBqCNr3EoOplKBbfvfj0OvyGP0P6IxjGOK8k5HAQ10RHn LYl69of13bIfv0AjjXH9X5KYTUfbvf4ZufJP9tyOo2kgv/9qMoeFJEe7IEAxFSw1dL0b Tq6xxD4ZnBTymxE8oKoJS/7kenMZJv1PH4ttQ/tDkJMnuecQd6TO9ZaMrafWAE4V4QkR SoVUReOZmIHuGj+GSeEDRD+FILw6tf2l2B50uib0FdJrjvZiDIs3s7A8EJZ7pbDUoreP weNjE/IaZZnsRhThGUN141yhzvHvDlL/BpgzicYOsPt6+P28/wQc/yd06ltyaNldr/Bh IM0Q== X-Forwarded-Encrypted: i=1; AJvYcCWlDQQ0Qru6IOlvNIF88DMuZ4Bw16tIixvhPKO7Lia5JmJQnrgtcWGCOv6x/2/3zYnqr6wUtpE+NiwJJoElp7U8Gi5xiQ==@vger.kernel.org, AJvYcCWxTKRTjw1JDOi6AEkLLWetY2+8x6sMqTGHUj0U7ceJRgo2R+QAtrnCWJ9lReYjtaUoY43kkkBU/3fOyXU=@vger.kernel.org X-Gm-Message-State: AOJu0YwmM9pcB/6ZWdLJg8y1UEhOHJvLcEmDMNIizTk7r6cBR4PsfvJu 75vYDwSXwaXdHXmma9zCq3iL+TBXDUnRcIpHDHOVbxe5/tGfcvDo/8FWZ4ISWQk= X-Gm-Gg: ASbGncuknF1/vk4A4wfCVeFPGCRA9SWj2WivKGM/s+7DtAGZJqsayuT+3PSiSfwRjND PPImT5lE16BD+peRYgvEG6/EKYHWyZnNSliaBE7c506jGHVoBi2nMq5fg/+22n+ap5qNsAbJBEv Zh0ZlFtXwcjGVek1Qc6qOjHxkM03fLjhBmlV5Ta7rSo9LQqDvrFrcL4xsMsUm+rX+j9H08H07+9 5fqO1/G78s7k7BejWp9ixVtuCC3yjKpMR87M7jEcUfK46SA1InZ8m/tz7pVqYeBoOl/+thDwnuw ADsVgAB1OiqvHqAm9e8DSBAsYqWSEXDAEqNEEx0sqIsVag== X-Google-Smtp-Source: AGHT+IEA4CvVgbhSSn/nzSb6KKTYeXTB3ZzLUC5fM2np95GjGLaAwbjmHoFBcpUSL1ACRK3BegyDPg== X-Received: by 2002:a05:6102:a49:b0:4b1:14f3:5d6d with SMTP id ada2fe7eead31-4c2e27b9483mr3186041137.6.1741222688389; Wed, 05 Mar 2025 16:58:08 -0800 (PST) Received: from [192.168.100.70] ([2800:bf0:82:3d2:9e61:1a62:1a8c:3e62]) by smtp.gmail.com with ESMTPSA id a1e0cc1a2514c-86d33bc0065sm25925241.4.2025.03.05.16.58.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 05 Mar 2025 16:58:08 -0800 (PST) From: Kurt Borja Date: Wed, 05 Mar 2025 19:56:54 -0500 Subject: [PATCH v3 03/10] platform/x86: alienware-wmi-wmax: Improve internal AWCC API Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250305-hwm-v3-3-395e7a1407e2@gmail.com> References: <20250305-hwm-v3-0-395e7a1407e2@gmail.com> In-Reply-To: <20250305-hwm-v3-0-395e7a1407e2@gmail.com> To: =?utf-8?q?Ilpo_J=C3=A4rvinen?= , Armin Wolf Cc: Kurt Borja , Hans de Goede , platform-driver-x86@vger.kernel.org, Dell.Client.Kernel@dell.com, linux-kernel@vger.kernel.org X-Mailer: b4 0.14.2 Inline all AWCC WMI helper methods and directly return the newly introduced __awcc_wmi_command() helper to simplify implementation. Drop awcc_thermal_control() in favor of awcc_op_activate_profile(). Add awcc_op_get_resource_id() and awcc_profile_id_to_pprof() helpers to support upcoming changes, as well as a new failure code. Signed-off-by: Kurt Borja Reviewed-by: Armin Wolf --- drivers/platform/x86/dell/alienware-wmi-wmax.c | 176 +++++++++++++++------= ---- 1 file changed, 110 insertions(+), 66 deletions(-) diff --git a/drivers/platform/x86/dell/alienware-wmi-wmax.c b/drivers/platf= orm/x86/dell/alienware-wmi-wmax.c index 80aefba5b22d6b4ac18aeb2ca356f8c911150abd..a43373717bd4580e8f62a7263e6= 7664630165e28 100644 --- a/drivers/platform/x86/dell/alienware-wmi-wmax.c +++ b/drivers/platform/x86/dell/alienware-wmi-wmax.c @@ -32,6 +32,7 @@ #define AWCC_THERMAL_MODE_GMODE 0xAB =20 #define AWCC_FAILURE_CODE 0xFFFFFFFF +#define AWCC_FAILURE_CODE_2 0xFFFFFFFE #define AWCC_THERMAL_TABLE_MASK GENMASK(7, 4) #define AWCC_THERMAL_MODE_MASK GENMASK(3, 0) /* Some IDs have a BIT(8) flag that we ignore */ @@ -443,8 +444,7 @@ const struct attribute_group wmax_deepsleep_attribute_g= roup =3D { }; =20 /* - * Thermal Profile control - * - Provides thermal profile control through the Platform Profile API + * AWCC Helpers */ static bool is_awcc_thermal_profile_id(u8 code) { @@ -463,95 +463,140 @@ static bool is_awcc_thermal_profile_id(u8 code) return false; } =20 -static int awcc_thermal_information(struct wmi_device *wdev, u8 operation, - u8 arg, u32 *out_data) +static int __awcc_wmi_command(struct wmi_device *wdev, u32 method_id, + struct wmax_u32_args *args, u32 *out) { - struct wmax_u32_args in_args =3D { + int ret; + + ret =3D alienware_wmi_command(wdev, method_id, args, sizeof(*args), out); + if (ret) + return ret; + + if (*out =3D=3D AWCC_FAILURE_CODE || *out =3D=3D AWCC_FAILURE_CODE_2) + return -EBADRQC; + + return 0; +} + +static inline int awcc_thermal_information(struct wmi_device *wdev, u8 ope= ration, + u8 arg, u32 *out) +{ + struct wmax_u32_args args =3D { .operation =3D operation, .arg1 =3D arg, .arg2 =3D 0, .arg3 =3D 0, }; - int ret; =20 - ret =3D alienware_wmi_command(wdev, AWCC_METHOD_THERMAL_INFORMATION, - &in_args, sizeof(in_args), out_data); - if (ret < 0) - return ret; - - if (*out_data =3D=3D AWCC_FAILURE_CODE) - return -EBADRQC; - - return 0; + return __awcc_wmi_command(wdev, AWCC_METHOD_THERMAL_INFORMATION, &args, o= ut); } =20 -static int awcc_thermal_control(struct wmi_device *wdev, u8 profile) +static inline int awcc_game_shift_status(struct wmi_device *wdev, u8 opera= tion, + u32 *out) { - struct wmax_u32_args in_args =3D { - .operation =3D AWCC_OP_ACTIVATE_PROFILE, - .arg1 =3D profile, - .arg2 =3D 0, - .arg3 =3D 0, - }; - u32 out_data; - int ret; - - ret =3D alienware_wmi_command(wdev, AWCC_METHOD_THERMAL_CONTROL, - &in_args, sizeof(in_args), &out_data); - if (ret) - return ret; - - if (out_data =3D=3D AWCC_FAILURE_CODE) - return -EBADRQC; - - return 0; -} - -static int awcc_game_shift_status(struct wmi_device *wdev, u8 operation, - u32 *out_data) -{ - struct wmax_u32_args in_args =3D { + struct wmax_u32_args args =3D { .operation =3D operation, .arg1 =3D 0, .arg2 =3D 0, .arg3 =3D 0, }; - int ret; =20 - ret =3D alienware_wmi_command(wdev, AWCC_METHOD_GAME_SHIFT_STATUS, - &in_args, sizeof(in_args), out_data); - if (ret < 0) - return ret; + return __awcc_wmi_command(wdev, AWCC_METHOD_GAME_SHIFT_STATUS, &args, out= ); +} =20 - if (*out_data =3D=3D AWCC_FAILURE_CODE) - return -EOPNOTSUPP; +/** + * awcc_op_get_resource_id - Get the resource ID at a given index + * @wdev: AWCC WMI device + * @index: Index + * @out: Value returned by the WMI call + * + * Get the resource ID at a given index. Resource IDs are listed in the + * following order: + * + * - Fan IDs + * - Sensor IDs + * - Unknown IDs + * - Thermal Profile IDs + * + * The total number of IDs of a given type can be obtained with + * AWCC_OP_GET_SYSTEM_DESCRIPTION. + * + * Return: 0 on success, -errno on failure + */ +static inline int awcc_op_get_resource_id(struct wmi_device *wdev, u8 inde= x, u32 *out) +{ + struct wmax_u32_args args =3D { + .operation =3D AWCC_OP_GET_RESOURCE_ID, + .arg1 =3D index, + .arg2 =3D 0, + .arg3 =3D 0, + }; + + return __awcc_wmi_command(wdev, AWCC_METHOD_THERMAL_INFORMATION, &args, o= ut); +} + +static inline int awcc_op_get_current_profile(struct wmi_device *wdev, u32= *out) +{ + struct wmax_u32_args args =3D { + .operation =3D AWCC_OP_GET_CURRENT_PROFILE, + .arg1 =3D 0, + .arg2 =3D 0, + .arg3 =3D 0, + }; + + return __awcc_wmi_command(wdev, AWCC_METHOD_THERMAL_INFORMATION, &args, o= ut); +} + +static inline int awcc_op_activate_profile(struct wmi_device *wdev, u8 pro= file) +{ + struct wmax_u32_args args =3D { + .operation =3D AWCC_OP_ACTIVATE_PROFILE, + .arg1 =3D profile, + .arg2 =3D 0, + .arg3 =3D 0, + }; + u32 out; + + return __awcc_wmi_command(wdev, AWCC_METHOD_THERMAL_CONTROL, &args, &out); +} + +static int awcc_profile_id_to_pprof(u32 id, enum platform_profile_option *= profile) +{ + switch (id) { + case AWCC_THERMAL_MODE_GMODE: + *profile =3D PLATFORM_PROFILE_PERFORMANCE; + return 0; + default: + break; + } + + if (!is_awcc_thermal_profile_id(id)) + return -ENODATA; + + id =3D FIELD_GET(AWCC_THERMAL_MODE_MASK, id); + *profile =3D awcc_mode_to_platform_profile[id]; =20 return 0; } =20 +/* + * Thermal Profile control + * - Provides thermal profile control through the Platform Profile API + */ static int awcc_platform_profile_get(struct device *dev, enum platform_profile_option *profile) { struct awcc_priv *priv =3D dev_get_drvdata(dev); - u32 out_data; + u32 profile_id; int ret; =20 - ret =3D awcc_thermal_information(priv->wdev, AWCC_OP_GET_CURRENT_PROFILE, - 0, &out_data); - - if (ret < 0) + ret =3D awcc_op_get_current_profile(priv->wdev, &profile_id); + if (ret) return ret; =20 - if (out_data =3D=3D AWCC_THERMAL_MODE_GMODE) { - *profile =3D PLATFORM_PROFILE_PERFORMANCE; - return 0; - } - - if (!is_awcc_thermal_profile_id(out_data)) - return -ENODATA; - - out_data &=3D AWCC_THERMAL_MODE_MASK; - *profile =3D awcc_mode_to_platform_profile[out_data]; + ret =3D awcc_profile_id_to_pprof(profile_id, profile); + if (ret) + return ret; =20 return 0; } @@ -583,8 +628,8 @@ static int awcc_platform_profile_set(struct device *dev, } } =20 - return awcc_thermal_control(priv->wdev, - priv->supported_thermal_profiles[profile]); + return awcc_op_activate_profile(priv->wdev, + priv->supported_thermal_profiles[profile]); } =20 static int awcc_platform_profile_probe(void *drvdata, unsigned long *choic= es) @@ -606,8 +651,7 @@ static int awcc_platform_profile_probe(void *drvdata, u= nsigned long *choices) first_mode =3D sys_desc[0] + sys_desc[1]; =20 for (u32 i =3D 0; i < sys_desc[3]; i++) { - ret =3D awcc_thermal_information(priv->wdev, AWCC_OP_GET_RESOURCE_ID, - i + first_mode, &out_data); + ret =3D awcc_op_get_resource_id(priv->wdev, i + first_mode, &out_data); =20 if (ret =3D=3D -EIO) return ret; --=20 2.48.1 From nobody Sun Feb 8 09:11:16 2026 Received: from mail-vk1-f182.google.com (mail-vk1-f182.google.com [209.85.221.182]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id ED07113D509; Thu, 6 Mar 2025 00:58:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741222693; cv=none; b=MxNn+ooi1Qi9xq+TdfRWo+zXhzBUcR1ZIGJryqDA2Kmfg++VcoH5hFUwOw4F1q0ePPLIJ4VflL8B7fV+E0/HtgGtPCKU8ZgraBF8D36iz/NpsxEMns4YL8TKlwUZCs3VVkxzWV9IbPGowhL3qR3jn0FkL/h7GD3DVNT9Ugn3zOo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741222693; c=relaxed/simple; bh=8U4ihaIIp3NI7j6SGITav4hp8DoUwXulxF0G7jdyFEE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=qM6at5rmHtD+ZiLpt5CwW5TogdyA90Srvcnc4iBuSlZROqcn41VzNrkJZ3B0LPEbZ++YoxerZVxWUZSTKKeRUCq9Yv0xndiJ5hkO20bsmslDz+XADaFLaiO1XcdvWZh4Xhskq50wc4WJ8bi7nI2YrvSkwjb+Nk2oVRVf4CCuy14= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=VEZ+FCtG; arc=none smtp.client-ip=209.85.221.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="VEZ+FCtG" Received: by mail-vk1-f182.google.com with SMTP id 71dfb90a1353d-51eb1a6ca1bso46685e0c.1; Wed, 05 Mar 2025 16:58:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741222691; x=1741827491; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=sqj+xl520LWWbYcDKIbFTGCJcSVK9Yty0PIVI9ICJGo=; b=VEZ+FCtG9an3Hz7YPdCFoWrPXnfJPT4Hf16MI59TVPWHYIh8Y2L0Aevtminy0o73Lk f+i9iiGVYDjD4q2pvtvdA/YigpjoaAJs3XKx6uuqzjeVMAJzquRgkuIKUlnDjL9ekVCs GvQ67TgWF0hFFuGVGR2Y6T/EOl2AREtM0kYyi3vjrSiro3r2bI/5k+VkLA/s6dszcsiQ BwiCNCFj3BZt3X/IBCe84G+eQOe5+WhFz8dyLfFWdQl7tDtVjcac8j32izDxOIHRr5U8 cSlAFl65jZHGtkFfs3gidesWFQ6bvQXRWGbvPqC8PiLlNai1V9uyoiRSE2JKr+IjRrPZ na9g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741222691; x=1741827491; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=sqj+xl520LWWbYcDKIbFTGCJcSVK9Yty0PIVI9ICJGo=; b=l1iylzos75f2CoAnq8MPSzJSEndWgBBi4y9E+ICbe1UHuAzCLaaPvwn/BxSAvcAB8e Zg0PbxxYIhKbQNtX39xRm2ERrmUYl3vqTa5nGoq+D49yKfhiZgWvV7WGLtTjNMc7e3Lb yUduiFJczTnYjUC9eELu6K0CRG4q2ev3P1I4fmFU3X84vgUokYJv5s5yml1SPvBF3Es1 JsBInoKegiHk2BdGnPqlafpkAgB1OjxlfyeSzL0KJUyEDTkTAmcWLue2hguqTJXS/5Ys QA0BEQZtb4TUrFYK+p/sf/URxMofUI6aTb+Fyw6cvmEaOAe7qZw5DjkTyzSkGqaZJEr/ eahw== X-Forwarded-Encrypted: i=1; AJvYcCUoNJ3s5kG3IUpYDowx8qAZ9wuFb8Jm9TFwskysuF5BvAC1yHks+pTsyDW4U7PVj1mO063kE/VOgZgnIJE=@vger.kernel.org, AJvYcCVeazOy8xymLAwOE/EZ9SPIMZpDuw9JwAeMRoSwG/9Y63I4GiqDAHfBtG3ebFFEXQ0q2CkGqhXAn76VjsAfLSKFwstV1Q==@vger.kernel.org X-Gm-Message-State: AOJu0YxLsE1J0ubjVAdWBC8n67/WsvUEX1ESbHmHX43MZxKDziL9Odrs 3cRSzk8K9Ks6wT9Xlcl/T2Z6bzqiBHh6MFuIeVtcrgV4B5KDkg0YhHG/4f+GG+E= X-Gm-Gg: ASbGnct2W4tYJC7+gDYGEiUhxwPoOvvf7hqTj3mH506xn1YV8m+WcbzSSuZikWfFqYb Cag5mNwwAwfSDm83zYjBQZy9yrPDsLQlsNeUtifIUBEZIRbQd643RNxrkvlAv5HY+xAoBZGX2Qe cvf/iH1lwaFCZi1eMCTKgIB7gCiAySWKPkzbyIKTQEjWgSRq0N3v/BdCvlxSwB8UNwLxMpPCBq/ DTPZBurzg83ZY1J7q0A7+D/2dvqAyjkySZdiWmD6/Gy9dQ0c/Gsl14db+Vj2DIwl4DzDp5MzPS7 YNmPYsiVfjucMu+imQ3T4J//viNbUYyHaPD/QbA02lpzew== X-Google-Smtp-Source: AGHT+IHKmZT8j/BZaNfmNR280fp/6acUEQbafFFWYqVE0FwYpqVYB08th8svfdT07cOFjvFKSS2K5Q== X-Received: by 2002:a05:6102:41a2:b0:4c1:9cb2:8389 with SMTP id ada2fe7eead31-4c2e27661f5mr4328594137.2.1741222690773; Wed, 05 Mar 2025 16:58:10 -0800 (PST) Received: from [192.168.100.70] ([2800:bf0:82:3d2:9e61:1a62:1a8c:3e62]) by smtp.gmail.com with ESMTPSA id a1e0cc1a2514c-86d33bc0065sm25925241.4.2025.03.05.16.58.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 05 Mar 2025 16:58:09 -0800 (PST) From: Kurt Borja Date: Wed, 05 Mar 2025 19:56:55 -0500 Subject: [PATCH v3 04/10] platform/x86: alienware-wmi-wmax: Modify supported_thermal_profiles[] Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250305-hwm-v3-4-395e7a1407e2@gmail.com> References: <20250305-hwm-v3-0-395e7a1407e2@gmail.com> In-Reply-To: <20250305-hwm-v3-0-395e7a1407e2@gmail.com> To: =?utf-8?q?Ilpo_J=C3=A4rvinen?= , Armin Wolf Cc: Kurt Borja , Hans de Goede , platform-driver-x86@vger.kernel.org, Dell.Client.Kernel@dell.com, linux-kernel@vger.kernel.org X-Mailer: b4 0.14.2 Rename supported_thermal_profiles[] -> supported_profiles[] and change it's type to u8 because it stores AWCC thermal IDs. Reviewed-by: Armin Wolf Reviewed-by: Ilpo J=C3=A4rvinen Signed-off-by: Kurt Borja --- drivers/platform/x86/dell/alienware-wmi-wmax.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/platform/x86/dell/alienware-wmi-wmax.c b/drivers/platf= orm/x86/dell/alienware-wmi-wmax.c index a43373717bd4580e8f62a7263e67664630165e28..8e91fb4b349b7b62b6f914ac68d= 5eb1cd30a606e 100644 --- a/drivers/platform/x86/dell/alienware-wmi-wmax.c +++ b/drivers/platform/x86/dell/alienware-wmi-wmax.c @@ -213,7 +213,7 @@ struct wmax_u32_args { struct awcc_priv { struct wmi_device *wdev; struct device *ppdev; - enum awcc_thermal_profile supported_thermal_profiles[PLATFORM_PROFILE_LAS= T]; + u8 supported_profiles[PLATFORM_PROFILE_LAST]; }; =20 static const enum platform_profile_option awcc_mode_to_platform_profile[AW= CC_PROFILE_LAST] =3D { @@ -628,8 +628,7 @@ static int awcc_platform_profile_set(struct device *dev, } } =20 - return awcc_op_activate_profile(priv->wdev, - priv->supported_thermal_profiles[profile]); + return awcc_op_activate_profile(priv->wdev, priv->supported_profiles[prof= ile]); } =20 static int awcc_platform_profile_probe(void *drvdata, unsigned long *choic= es) @@ -665,7 +664,7 @@ static int awcc_platform_profile_probe(void *drvdata, u= nsigned long *choices) =20 mode =3D FIELD_GET(AWCC_THERMAL_MODE_MASK, id); profile =3D awcc_mode_to_platform_profile[mode]; - priv->supported_thermal_profiles[profile] =3D id; + priv->supported_profiles[profile] =3D id; =20 set_bit(profile, choices); } @@ -674,7 +673,7 @@ static int awcc_platform_profile_probe(void *drvdata, u= nsigned long *choices) return -ENODEV; =20 if (awcc->gmode) { - priv->supported_thermal_profiles[PLATFORM_PROFILE_PERFORMANCE] =3D + priv->supported_profiles[PLATFORM_PROFILE_PERFORMANCE] =3D AWCC_THERMAL_MODE_GMODE; =20 set_bit(PLATFORM_PROFILE_PERFORMANCE, choices); --=20 2.48.1 From nobody Sun Feb 8 09:11:16 2026 Received: from mail-ua1-f46.google.com (mail-ua1-f46.google.com [209.85.222.46]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 43CA614831C; Thu, 6 Mar 2025 00:58:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.222.46 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741222695; cv=none; b=Ec9kYFJG6O6GRSV+lhtFB3ZgghTuGNVCzWVq4Wc5bCHqQ6LvQg5eJlQAIpKklZTlGLQhzdVc36ARvTTYpoJXOwUUOq0ucJFaczTDSjtLsVcJld4c4Ez9sfLrjvr3tcLV3tTEVPdyBJRKkIxKHagyZTPLc7800hWqux1LZYyS0ak= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741222695; c=relaxed/simple; bh=HSddJ4u2EeUmqQkj/4pdfLTCTeH+AqHJpKz+ERkQ4Ug=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Ks7RZ3+7LI2MK3zcl5Y2eCzuxrXy7OkgK9HR+wUcxmisqGtPUhS17WWSRfeSRzQ6Oy5pcPPLpsmX7DY/34VBzHGJUOrXDrDV55dWH+pkLBcJxMS/Qc9/6LtWvdZZyiabr95AZqyghe2GsaEQZUIsM3WjHsmMlhz0Uko7XC7qvcg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=VJF2KBUZ; arc=none smtp.client-ip=209.85.222.46 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="VJF2KBUZ" Received: by mail-ua1-f46.google.com with SMTP id a1e0cc1a2514c-86b7185d653so27777241.0; Wed, 05 Mar 2025 16:58:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741222693; x=1741827493; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=lYu11Ks2/ykMetK4IPyEkkQITTjZX6WFAwoWnv7cViE=; b=VJF2KBUZ50dko1Y0/+wJ5ryFIS9c3V3H3BjbNgmI1AAyfbIXQ+N1DAtea52/iNmqX4 sMLQDZEFiryeLo39vBSW5OXjfhI0G3edjeLtJPXlcgIYz+BuuD0jK8LcDSguJK5M1jqC zTfHE4fVew3AOFzihC5P3rqvvsWXHFy+whNRE6VrUb/tQcKCe/DaujybC/Jlb7C0UGnD IzenzzlPoX4j8BoAEhRvQWUQWdvAa2XmFSrhecPW3qM+GWP7sCUfSxfU3S1U6bIwZ/RF jOUJzcEfYsFA4a7jihI4jioU9L4JhR/HPrqRxfdqlzwER3lwSEO9PC8lSDhc+cKZTQNk bpxg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741222693; x=1741827493; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=lYu11Ks2/ykMetK4IPyEkkQITTjZX6WFAwoWnv7cViE=; b=m6pEJLJ7HvTzd9Tgz+YGmqSl0SzGIKmqgA7aS/clahMNfusx5fDoi6z3LXRcN4iQgq Q1WRd3RwvWUMWUZfn51gvgnHU+qhUJWjOqm9WCr1pphWazYYXNsYzAVI+6o4vrUyp/Ty QR55FSQl5f7aYbxlhUluqxq2iUDN7DjZ4/a+B0a7MzANRH6vMtm5+YQONPZeXzS18t9S mu10ziyzRCewW1kNtmGdYEdfKLMCr5APwKrMYldfc6OFPosk614qe9xLF4sHn+gtrkDA EfrgF9M5Wljmm7oxU6Tq7LV9ZRyzVgxk2xkOvx7Wzldl8x6oMIgz+qhO/GE1wyLhprny oKuw== X-Forwarded-Encrypted: i=1; AJvYcCWkqCCofWHEKrvpw5UNqoXgG8uwB5rDwMVIcyCyVcF/Otzdnb5yS/403nuuOUWMZ8torjkSDf9J2rOjPFk=@vger.kernel.org, AJvYcCWuEFjBYJEtTpqfTghTEhhF98qzm/Dl9bOaRemrFTePQjO39OE3f5Ri3HCiEpQgE6xDNzL+KwXfg4AcY0lKYqf37b3lLw==@vger.kernel.org X-Gm-Message-State: AOJu0YzrKxcpCRhD61Th7Z2+uOgvnalHXHwG91x8/+j0jI8NoaGFmc/e JPXOhuinVFVk+2uKwAs10CFTaLL+nIuhj/tlxKG1tIt4pEZ6z6Hr X-Gm-Gg: ASbGncu5c4NcH9FkPoWw5kV0QCGWpCYCkhePfMlq8BaBMi1st7VpFvf+rRlcYQgGWUf BrP7KKOnIkLoXg/NjU3jdTw+LuPaZK06bl+OauJyODC3QPrsu3unRKXoRJICaEyvHXu40Gw1QQD K2DUSxBwyqwrSSZEZML2COC8c13Qn8VMua1m6BCKEItFPVz/5AxLYu+LEBpzQ4lClO8fvkmkEr6 yTz4JxP8DGLx3/g3iSUZEIbya2VRQU09uW044oP2eOQ2qkzyyMnXqcppV2M+nu4L07w+tLDCdl8 6z5oLbnX+CqED5+YGiLih3cMANLU84ezj1MZPU1o8ypQ1g== X-Google-Smtp-Source: AGHT+IEbbiQIJwuvicyFa+IN0N2du42kscWhhbufga27C0UdZpyPhCcD3M/cinnOmNG4zLBiETOR9A== X-Received: by 2002:a05:6102:508f:b0:4bb:c527:aacd with SMTP id ada2fe7eead31-4c2e299a2d3mr3470947137.23.1741222693198; Wed, 05 Mar 2025 16:58:13 -0800 (PST) Received: from [192.168.100.70] ([2800:bf0:82:3d2:9e61:1a62:1a8c:3e62]) by smtp.gmail.com with ESMTPSA id a1e0cc1a2514c-86d33bc0065sm25925241.4.2025.03.05.16.58.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 05 Mar 2025 16:58:12 -0800 (PST) From: Kurt Borja Date: Wed, 05 Mar 2025 19:56:56 -0500 Subject: [PATCH v3 05/10] platform/x86: alienware-wmi-wmax: Improve platform profile probe Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250305-hwm-v3-5-395e7a1407e2@gmail.com> References: <20250305-hwm-v3-0-395e7a1407e2@gmail.com> In-Reply-To: <20250305-hwm-v3-0-395e7a1407e2@gmail.com> To: =?utf-8?q?Ilpo_J=C3=A4rvinen?= , Armin Wolf Cc: Kurt Borja , Hans de Goede , platform-driver-x86@vger.kernel.org, Dell.Client.Kernel@dell.com, linux-kernel@vger.kernel.org X-Mailer: b4 0.14.2 Get and store the AWCC system description in alienware_awcc_setup() instead of awcc_platform_profile_probe() and add a check for integer overflows to avoid misbehaviors. While at it, replace set_bit() with it's non-atomic version __set_bit() because `choices` belong to this thread only. Reviewed-by: Armin Wolf Signed-off-by: Kurt Borja --- drivers/platform/x86/dell/alienware-wmi-wmax.c | 61 +++++++++++++++++++---= ---- 1 file changed, 46 insertions(+), 15 deletions(-) diff --git a/drivers/platform/x86/dell/alienware-wmi-wmax.c b/drivers/platf= orm/x86/dell/alienware-wmi-wmax.c index 8e91fb4b349b7b62b6f914ac68d5eb1cd30a606e..a89fac80fa9e819e042f3807eb6= 9dc8ddd9a4841 100644 --- a/drivers/platform/x86/dell/alienware-wmi-wmax.c +++ b/drivers/platform/x86/dell/alienware-wmi-wmax.c @@ -38,6 +38,9 @@ /* Some IDs have a BIT(8) flag that we ignore */ #define AWCC_RESOURCE_ID_MASK GENMASK(7, 0) =20 +/* Arbitrary limit based on supported models */ +#define AWCC_MAX_RES_COUNT 16 + static bool force_platform_profile; module_param_unsafe(force_platform_profile, bool, 0); MODULE_PARM_DESC(force_platform_profile, "Forces auto-detecting thermal pr= ofiles without checking if WMI thermal backend is available"); @@ -212,6 +215,17 @@ struct wmax_u32_args { =20 struct awcc_priv { struct wmi_device *wdev; + union { + u32 system_description; + struct { + u8 fan_count; + u8 temp_count; + u8 unknown_count; + u8 profile_count; + }; + u8 res_count[4]; + }; + struct device *ppdev; u8 supported_profiles[PLATFORM_PROFILE_LAST]; }; @@ -636,37 +650,40 @@ static int awcc_platform_profile_probe(void *drvdata,= unsigned long *choices) enum platform_profile_option profile; struct awcc_priv *priv =3D drvdata; enum awcc_thermal_profile mode; - u8 sys_desc[4]; - u32 first_mode; + u8 id, offset =3D 0; u32 out_data; int ret; - u8 id; =20 - ret =3D awcc_thermal_information(priv->wdev, AWCC_OP_GET_SYSTEM_DESCRIPTI= ON, - 0, (u32 *) &sys_desc); - if (ret < 0) - return ret; - - first_mode =3D sys_desc[0] + sys_desc[1]; - - for (u32 i =3D 0; i < sys_desc[3]; i++) { - ret =3D awcc_op_get_resource_id(priv->wdev, i + first_mode, &out_data); + /* + * Thermal profile IDs are listed last at offset + * fan_count + temp_count + unknown_count + */ + for (unsigned int i =3D 0; i < ARRAY_SIZE(priv->res_count) - 1; i++) + offset +=3D priv->res_count[i]; =20 + for (unsigned int i =3D 0; i < priv->profile_count; i++) { + ret =3D awcc_op_get_resource_id(priv->wdev, i + offset, &out_data); if (ret =3D=3D -EIO) return ret; =20 + /* + * Some devices report an incorrect number of thermal profiles + * so the resource ID list may end prematurely + */ if (ret =3D=3D -EBADRQC) break; =20 id =3D FIELD_GET(AWCC_RESOURCE_ID_MASK, out_data); - if (!is_awcc_thermal_profile_id(id)) + if (!is_awcc_thermal_profile_id(id)) { + dev_dbg(&priv->wdev->dev, "Unmapped thermal profile ID 0x%02x\n", id); continue; + } =20 mode =3D FIELD_GET(AWCC_THERMAL_MODE_MASK, id); profile =3D awcc_mode_to_platform_profile[mode]; priv->supported_profiles[profile] =3D id; =20 - set_bit(profile, choices); + __set_bit(profile, choices); } =20 if (bitmap_empty(choices, PLATFORM_PROFILE_LAST)) @@ -676,7 +693,7 @@ static int awcc_platform_profile_probe(void *drvdata, u= nsigned long *choices) priv->supported_profiles[PLATFORM_PROFILE_PERFORMANCE] =3D AWCC_THERMAL_MODE_GMODE; =20 - set_bit(PLATFORM_PROFILE_PERFORMANCE, choices); + __set_bit(PLATFORM_PROFILE_PERFORMANCE, choices); } =20 return 0; @@ -707,6 +724,20 @@ static int alienware_awcc_setup(struct wmi_device *wde= v) if (!priv) return -ENOMEM; =20 + ret =3D awcc_thermal_information(wdev, AWCC_OP_GET_SYSTEM_DESCRIPTION, + 0, &priv->system_description); + if (ret < 0) + return ret; + + /* Sanity check */ + for (unsigned int i =3D 0; i < ARRAY_SIZE(priv->res_count); i++) { + if (priv->res_count[i] > AWCC_MAX_RES_COUNT) { + dev_err(&wdev->dev, "Malformed system description: 0x%08x\n", + priv->system_description); + return -ENXIO; + } + } + priv->wdev =3D wdev; dev_set_drvdata(&wdev->dev, priv); =20 --=20 2.48.1 From nobody Sun Feb 8 09:11:16 2026 Received: from mail-ua1-f53.google.com (mail-ua1-f53.google.com [209.85.222.53]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AD79E15383D; Thu, 6 Mar 2025 00:58:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.222.53 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741222700; cv=none; b=YUM9RWHVhYzCWm9cGTT+k0ci8aJz2A5YXcFjNR4itOA80ozjaycpyugBA9I6iW6Zxzsjn4TwOygaCGBAU3efOZk8jGAKud3H/b6nU+L0RMbZPFGKcYMUzeCKNanROX73aXRFhziS9oekCQfAL8YJFcDIeMCxUluWvEEwS9Nyg3w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741222700; c=relaxed/simple; bh=DcRXWRac1PvW+T1CPw2St2sfblMHRa99Gb0r4bB8SaQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=MaSct4zfvTK1GJ8otVO/oi3wZetXDNkb71pQvWr3nf3RhiRo3NTHVhFYy7czHyp68y7TTh3KblLuyagQYhVnCvuM3yVQtX0vEh/yKPYGuergjjKP02RMVSWYUbr4OpYLm26r6xPA8MUGHhXuDbZV74KXth/hX/1fdti56MeRpoo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=W3R3sv69; arc=none smtp.client-ip=209.85.222.53 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="W3R3sv69" Received: by mail-ua1-f53.google.com with SMTP id a1e0cc1a2514c-86d30787263so34898241.1; Wed, 05 Mar 2025 16:58:16 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741222695; x=1741827495; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=jeW9jjPJ9A+VG5BvvYKHWDIzx5AtWJe9yPCzeW/GQ7Q=; b=W3R3sv69d09YsjsSGsKC/nz08/JkvtkpgKybUFiV0qN35IudYtPj7KkRr3keGofgsl 4sB80FOhBEXCCGRk0xHRwcIZA1wvvFPqfJU9pNmGu7Zt1lvajvaz6llVecz3F6oHsKeq ywOa0Sm5ck6mgLB+ELgfuck50qe1qSVwQBJc5ItxiUsUhFDJrx2R5axytdIR0t3Kl+4G QC4YPN4Q21G+wBZCIrba1AJZPCAsNH7/vkDCawoaLIZNMk1v7fc4ObAa9roI8xXbFCmK 6Gr8yucUTP42sLOvZNALt6GHiLs2kc4WYnAjpwyKah3TE4duq/NPfNiAFNLzAhY2CJ/B CQtA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741222695; x=1741827495; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=jeW9jjPJ9A+VG5BvvYKHWDIzx5AtWJe9yPCzeW/GQ7Q=; b=xOZH2ZvLHKNwLpG2QSHclgJA6XLWdUCn17swG7KUjZhESA+coAwKl95ciDClDYjHKy DIOYkqPh/wnSkMKTCVHNuNND0vFZP5hAtacaSmnC0kuqloTM9HH1ubMWB0idBlvHQdg6 yQe6cYNzjXeMRBK3OQWMRETJfLmY204BekdV9KVHiw0+k6RqPBAANzWGYCiiwiVDVLYF 6cxuXC7xmMjRVxnbE11h+Hn5zMarfSglSBAKAwosMNFoc1EWZfAhPV0vGX9CweZ8ZZOM vefv9lRcILnsNKYhUkdoWcxnEssF1ozLSm/Re7i4dcA7SWKyEPlaiJAIOpe6y2z8kslx YgCg== X-Forwarded-Encrypted: i=1; AJvYcCUaYeLBMR5CkNXEakuHe9DjQUSUJEb0pzQrwzhkGm9GwRvswN5xjhKJCmmS3nUDXDPJqZUoJCFAwo9udHXyg9tmQJFv+A==@vger.kernel.org, AJvYcCXAeinBGIO6bfXSMIoSZkOqbjtRr1I23iq1lLdv7aqN8tYtDGfCjxJ3fie2CLxGbaFMbhWcncGPgu/SLf0=@vger.kernel.org X-Gm-Message-State: AOJu0YwUc22nB5sEox57rZzwIA+2RgbRxVe9C1r6U9ccSmsQGstNK0wO 9egEm1AskyzLD6o1wEmUtrvJ+i4dyarDYKTNwf5Ps906NMgRBV5Q X-Gm-Gg: ASbGncvgKpRi+wbgm0URPr8wTtrCXGGtfefie+vksOtQYG0azPXqYU4f2zFCE0DPnSV 6Oxv160JKApDjIDPru/N0+H0/yliW3OhY6HZCFwgRjGtcDE+Nc5gYCl/WtWaMLQvm10lL0SBSQe nrKor4Kb3gTD4c60n79IsFrkGWlUAobVPVzrZbGmO1veKEI/0X0gR4Lp/a0QTf9AzaHR8FQlbAq nXXsxBAc9RiCe5bXcNer1kyVMu/nApkbm3/2P3/HVSU3AXSWQcUZXtBceqS/lTcd7s/aZmcJn0T RwNtouambyow37cB9srZKcQeUFjmD8VC5EgzhuL8KdAeiQ== X-Google-Smtp-Source: AGHT+IFGyzHCzbT2iBAD+6faSIpe2YDQM6J6GhX2MNIXEjyioMqdXvwDn4OLiBk9ZvQGDE9MJOFHgA== X-Received: by 2002:a05:6102:3594:b0:4c1:9e13:827c with SMTP id ada2fe7eead31-4c2e270969bmr3522493137.5.1741222695554; Wed, 05 Mar 2025 16:58:15 -0800 (PST) Received: from [192.168.100.70] ([2800:bf0:82:3d2:9e61:1a62:1a8c:3e62]) by smtp.gmail.com with ESMTPSA id a1e0cc1a2514c-86d33bc0065sm25925241.4.2025.03.05.16.58.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 05 Mar 2025 16:58:14 -0800 (PST) From: Kurt Borja Date: Wed, 05 Mar 2025 19:56:57 -0500 Subject: [PATCH v3 06/10] platform/x86: alienware-wmi-wmax: Add support for the "custom" thermal profile Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250305-hwm-v3-6-395e7a1407e2@gmail.com> References: <20250305-hwm-v3-0-395e7a1407e2@gmail.com> In-Reply-To: <20250305-hwm-v3-0-395e7a1407e2@gmail.com> To: =?utf-8?q?Ilpo_J=C3=A4rvinen?= , Armin Wolf Cc: Kurt Borja , Hans de Goede , platform-driver-x86@vger.kernel.org, Dell.Client.Kernel@dell.com, linux-kernel@vger.kernel.org X-Mailer: b4 0.14.2 All models with the "AWCC" WMAX device support a "custom" thermal profile. In some models this profile signals user-space that the user wants to manually control the fans, which are always unlocked. In other models it actually unlocks manual fan control. Reviewed-by: Armin Wolf Signed-off-by: Kurt Borja --- drivers/platform/x86/dell/alienware-wmi-wmax.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/drivers/platform/x86/dell/alienware-wmi-wmax.c b/drivers/platf= orm/x86/dell/alienware-wmi-wmax.c index a89fac80fa9e819e042f3807eb69dc8ddd9a4841..71fc17e8d103146b8edf53a552a= e5ba64414e873 100644 --- a/drivers/platform/x86/dell/alienware-wmi-wmax.c +++ b/drivers/platform/x86/dell/alienware-wmi-wmax.c @@ -29,8 +29,6 @@ #define AWCC_METHOD_THERMAL_CONTROL 0x15 #define AWCC_METHOD_GAME_SHIFT_STATUS 0x25 =20 -#define AWCC_THERMAL_MODE_GMODE 0xAB - #define AWCC_FAILURE_CODE 0xFFFFFFFF #define AWCC_FAILURE_CODE_2 0xFFFFFFFE #define AWCC_THERMAL_TABLE_MASK GENMASK(7, 4) @@ -177,6 +175,11 @@ enum AWCC_THERMAL_TABLES { AWCC_THERMAL_TABLE_USTT =3D 0xA, }; =20 +enum AWCC_SPECIAL_THERMAL_CODES { + AWCC_SPECIAL_PROFILE_CUSTOM =3D 0x00, + AWCC_SPECIAL_PROFILE_GMODE =3D 0xAB, +}; + enum awcc_thermal_profile { AWCC_PROFILE_USTT_BALANCED, AWCC_PROFILE_USTT_BALANCED_PERFORMANCE, @@ -577,7 +580,10 @@ static inline int awcc_op_activate_profile(struct wmi_= device *wdev, u8 profile) static int awcc_profile_id_to_pprof(u32 id, enum platform_profile_option *= profile) { switch (id) { - case AWCC_THERMAL_MODE_GMODE: + case AWCC_SPECIAL_PROFILE_CUSTOM: + *profile =3D PLATFORM_PROFILE_CUSTOM; + return 0; + case AWCC_SPECIAL_PROFILE_GMODE: *profile =3D PLATFORM_PROFILE_PERFORMANCE; return 0; default: @@ -691,11 +697,17 @@ static int awcc_platform_profile_probe(void *drvdata,= unsigned long *choices) =20 if (awcc->gmode) { priv->supported_profiles[PLATFORM_PROFILE_PERFORMANCE] =3D - AWCC_THERMAL_MODE_GMODE; + AWCC_SPECIAL_PROFILE_GMODE; =20 __set_bit(PLATFORM_PROFILE_PERFORMANCE, choices); } =20 + /* Every model supports the "custom" profile */ + priv->supported_profiles[PLATFORM_PROFILE_CUSTOM] =3D + AWCC_SPECIAL_PROFILE_CUSTOM; + + __set_bit(PLATFORM_PROFILE_CUSTOM, choices); + return 0; } =20 --=20 2.48.1 From nobody Sun Feb 8 09:11:16 2026 Received: from mail-ua1-f43.google.com (mail-ua1-f43.google.com [209.85.222.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E0DB46F31E; Thu, 6 Mar 2025 00:58:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.222.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741222700; cv=none; b=qA6nTWY+xk6oQ49xhUXMf29MAcsCLMnlW3bpWDihjPSUEHFwgmZhoLQUUhpIZ0lTojpgC6y0/aJcXRyTMCSED3Gih0V00IU/IQyNHDjpW7FLOwPf04ej736OvTutbmebHx1KUq+R4ui4lVfITHD/fDlesofxXol8YxAR7Wk8Vxw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741222700; c=relaxed/simple; bh=8CGjNcSxJObvcYxkua+oAPqDnLTQSgB1KD0yu/DuXmo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=SK0CGYYP25JYOfqw5tckXFBnngM+GL4dr3IkSyxq4o6SXbOMdPSZlQQduJSd7qj3SB7zBUjXLHXZwuNWe+gMbCVfnPA8Gb2Y8ye+Lq69P8Y/N5yMb2fi1c0+0C1SoQSj8OFk7q83vcTCjaIf+bHPibZGm0Zu+k9Z1e2LLp/TUwc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=eeV5p/gW; arc=none smtp.client-ip=209.85.222.43 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="eeV5p/gW" Received: by mail-ua1-f43.google.com with SMTP id a1e0cc1a2514c-86715793b1fso31465241.0; Wed, 05 Mar 2025 16:58:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741222698; x=1741827498; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=TP4DuREGD4142MYOEnJT0mlfxYRnERTRzB9IczVkCeY=; b=eeV5p/gWa6DqtwD3EVGPyiY3v3RhNlJoDDttYGp0Cs4pdDCrpH0zKdAnDUbaDnjxzd XV/giUGXTjSgSu+ryIZTXJ3J//2+O+Uz23LxiFeIvMG/glaTtTLcdauQZW0affavN2YT f4JwB2QEae8KCOxOSmTJO1xx0DAOsjV5DcJ/9CORbRSgSrO7vyW174M+K4AkXlYnFypA Gyan60JwJZ/Xg46/WHFQUVqMI6EehUeFDdzN2GKJXStegrI9rZjsQ1/l8FrPvoOjlLTn kx7ksPI3ozgQYPGNGLXx9hafyJxwXhB3ixbHY3iRSKjw4ztn8jKAAV/n6NJybs0lTopa tX9w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741222698; x=1741827498; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=TP4DuREGD4142MYOEnJT0mlfxYRnERTRzB9IczVkCeY=; b=ET96Oo1X0RykgdbwojXdYcniFOKGfXNV/Yddn4+wvHDJRa5R9yvz5CKkvhk519HeCy CX1um8lYlFXMizaGftH+fFwt7zGuvysWPE5YK6OArj7I1EQdgsDXp/Uhcpoiunrui/Gg spO9vKUIlW/Tr8ETBHS3X8RUyewej0sHxsn8a3mcS2ZkKguKAkqxywV4GFpyr1IKy9jS cwN7ZQlmW09MxiXy/+edMzIqnWhbfAUg2MC9m0WY8BDEftRFGYAxScTzgqZaO2udWfnu 7iPojDxKN/6xZbgOyVG0neXn61CvZMSwGV1JNDrUKnEqGzQwP9c3LkJsxnzZVyQn5Vgh oZMA== X-Forwarded-Encrypted: i=1; AJvYcCUThmdVAAsoYwFeJRY7FcHGfmd0L9TkpX0sStZe11QUVNGigoKTcf26ijRdvpOHPZPToRzJqkmt3How1A==@vger.kernel.org, AJvYcCXaSeac/oS/wHHP8eWrmOJLCXCd8uu0O+fzioEoKI7Pd0cGLuNwVVoyRpzoEQ15UZiWO+LnFyVlMWIoNAYb@vger.kernel.org, AJvYcCXhbeHPV16SLNmBae+UF5k1cG7zUeGav/DYDhN4CgKW/IvgSkyhBlHI2ROkn3ldALC9w7bhgk3U9zLy6Li8VodRp2rZpw==@vger.kernel.org X-Gm-Message-State: AOJu0Yz5bkCpO6b3m1qwpgFgRiAf2xFAkB1/E2q7cUb9Az2cler3+MV7 ydOEXDRQpdvcCFxiUH31dCzClVaYIBjpQdbYYjdJWzZyv4M7K4s9dsdZwC7UECo= X-Gm-Gg: ASbGncs0E9U8pRJ3+qMZjuPNqN+Jlikw5UtnmgYhKM26NpnJN/+X/yixiQbZ3XKI5SJ VtIoQDP1tZRV4P3k/iUg/0nhFusescXmkLbla33J+HpqdLF7Hf7lGHoDtXEo+s1uIuHYCvRG7FY kTqctuk8dDwgaOV5ZzqawoZVmftV9tiETARiCuzaOlfGAsqOtPuPQ7z1Igv01hfz1JKTOe4e8LQ Zd0XZHov8HAADKTounhi0UXkwh/sSjh2GsB87NC//Jkpu0MoOto9oOPJ/lXN7WvWzqBccHIpAAW iL+TRu9shheZqkTjj+spyk7rHTNGPTVVC1pVt64pL1uLHQ== X-Google-Smtp-Source: AGHT+IHMpvP5xzQiR/B8F8nIFw5XFSmZyCfR94swhOUPG9U1WUb4tEFVfYai/V99VH1Kjp0AjlVMXg== X-Received: by 2002:a05:6102:3c9f:b0:4c1:a2fb:c207 with SMTP id ada2fe7eead31-4c2e293d0aemr3692451137.25.1741222697749; Wed, 05 Mar 2025 16:58:17 -0800 (PST) Received: from [192.168.100.70] ([2800:bf0:82:3d2:9e61:1a62:1a8c:3e62]) by smtp.gmail.com with ESMTPSA id a1e0cc1a2514c-86d33bc0065sm25925241.4.2025.03.05.16.58.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 05 Mar 2025 16:58:16 -0800 (PST) From: Kurt Borja Date: Wed, 05 Mar 2025 19:56:58 -0500 Subject: [PATCH v3 07/10] platform/x86: alienware-wmi-wmax: Add HWMON support Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250305-hwm-v3-7-395e7a1407e2@gmail.com> References: <20250305-hwm-v3-0-395e7a1407e2@gmail.com> In-Reply-To: <20250305-hwm-v3-0-395e7a1407e2@gmail.com> To: =?utf-8?q?Ilpo_J=C3=A4rvinen?= , Armin Wolf Cc: Kurt Borja , Hans de Goede , platform-driver-x86@vger.kernel.org, Dell.Client.Kernel@dell.com, linux-kernel@vger.kernel.org, Guenter Roeck , Jean Delvare , linux-hwmon@vger.kernel.org X-Mailer: b4 0.14.2 All models with the "AWCC" WMAX device support monitoring fan speed and temperature sensors. Expose this feature through the HWMON interface. Cc: Guenter Roeck Cc: Jean Delvare Cc: linux-hwmon@vger.kernel.org Signed-off-by: Kurt Borja --- drivers/platform/x86/dell/Kconfig | 1 + drivers/platform/x86/dell/alienware-wmi-wmax.c | 431 +++++++++++++++++++++= ++++ 2 files changed, 432 insertions(+) diff --git a/drivers/platform/x86/dell/Kconfig b/drivers/platform/x86/dell/= Kconfig index f8a0dffcaab7c3b423472c5b9093011334a698c8..85a57c01aaada5d899cd8252e77= ed6043da5cbdf 100644 --- a/drivers/platform/x86/dell/Kconfig +++ b/drivers/platform/x86/dell/Kconfig @@ -43,6 +43,7 @@ config ALIENWARE_WMI_WMAX bool "Alienware WMAX WMI device driver" default y depends on ALIENWARE_WMI + depends on HWMON select ACPI_PLATFORM_PROFILE help Alienware WMI driver with AlienFX LED, HDMI, amplifier, deep sleep and diff --git a/drivers/platform/x86/dell/alienware-wmi-wmax.c b/drivers/platf= orm/x86/dell/alienware-wmi-wmax.c index 71fc17e8d103146b8edf53a552ae5ba64414e873..20cf3371ee3c0e1ea038b3ca517= e831f3b30dc29 100644 --- a/drivers/platform/x86/dell/alienware-wmi-wmax.c +++ b/drivers/platform/x86/dell/alienware-wmi-wmax.c @@ -9,10 +9,13 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt =20 #include +#include #include #include +#include #include #include +#include #include #include "alienware-wmi.h" =20 @@ -25,6 +28,7 @@ #define WMAX_METHOD_BRIGHTNESS 0x3 #define WMAX_METHOD_ZONE_CONTROL 0x4 =20 +#define AWCC_METHOD_GET_FAN_SENSORS 0x13 #define AWCC_METHOD_THERMAL_INFORMATION 0x14 #define AWCC_METHOD_THERMAL_CONTROL 0x15 #define AWCC_METHOD_GAME_SHIFT_STATUS 0x25 @@ -39,6 +43,10 @@ /* Arbitrary limit based on supported models */ #define AWCC_MAX_RES_COUNT 16 =20 +static bool force_hwmon; +module_param_unsafe(force_hwmon, bool, 0); +MODULE_PARM_DESC(force_hwmon, "Force probing for HWMON support without che= cking if the WMI backend is available"); + static bool force_platform_profile; module_param_unsafe(force_platform_profile, bool, 0); MODULE_PARM_DESC(force_platform_profile, "Forces auto-detecting thermal pr= ofiles without checking if WMI thermal backend is available"); @@ -48,16 +56,19 @@ module_param_unsafe(force_gmode, bool, 0); MODULE_PARM_DESC(force_gmode, "Forces G-Mode when performance profile is s= elected"); =20 struct awcc_quirks { + bool hwmon; bool pprof; bool gmode; }; =20 static struct awcc_quirks g_series_quirks =3D { + .hwmon =3D true, .pprof =3D true, .gmode =3D true, }; =20 static struct awcc_quirks generic_quirks =3D { + .hwmon =3D true, .pprof =3D true, .gmode =3D false, }; @@ -155,9 +166,18 @@ static const struct dmi_system_id awcc_dmi_table[] __i= nitconst =3D { }, }; =20 +enum AWCC_GET_FAN_SENSORS_OPERATIONS { + AWCC_OP_GET_TOTAL_FAN_TEMPS =3D 0x01, + AWCC_OP_GET_FAN_TEMP_ID =3D 0x02, +}; + enum AWCC_THERMAL_INFORMATION_OPERATIONS { AWCC_OP_GET_SYSTEM_DESCRIPTION =3D 0x02, AWCC_OP_GET_RESOURCE_ID =3D 0x03, + AWCC_OP_GET_TEMPERATURE =3D 0x04, + AWCC_OP_GET_FAN_RPM =3D 0x05, + AWCC_OP_GET_FAN_MIN_RPM =3D 0x08, + AWCC_OP_GET_FAN_MAX_RPM =3D 0x09, AWCC_OP_GET_CURRENT_PROFILE =3D 0x0B, }; =20 @@ -180,6 +200,12 @@ enum AWCC_SPECIAL_THERMAL_CODES { AWCC_SPECIAL_PROFILE_GMODE =3D 0xAB, }; =20 +enum AWCC_TEMP_SENSOR_TYPES { + AWCC_TEMP_SENSOR_CPU =3D 0x01, + AWCC_TEMP_SENSOR_GPU =3D 0x06, + AWCC_TEMP_SENSOR_LAST +}; + enum awcc_thermal_profile { AWCC_PROFILE_USTT_BALANCED, AWCC_PROFILE_USTT_BALANCED_PERFORMANCE, @@ -216,6 +242,15 @@ struct wmax_u32_args { u8 arg3; }; =20 +struct awcc_fan_data { + unsigned long *related_temps; + unsigned long *auto_channels_temp; + u32 total_temps; + u32 min_rpm; + u32 max_rpm; + u8 id; +}; + struct awcc_priv { struct wmi_device *wdev; union { @@ -231,6 +266,11 @@ struct awcc_priv { =20 struct device *ppdev; u8 supported_profiles[PLATFORM_PROFILE_LAST]; + + struct device *hwdev; + struct awcc_fan_data **fan_data; + unsigned int temp_sensors_size; + unsigned long *temp_sensors; }; =20 static const enum platform_profile_option awcc_mode_to_platform_profile[AW= CC_PROFILE_LAST] =3D { @@ -495,6 +535,19 @@ static int __awcc_wmi_command(struct wmi_device *wdev,= u32 method_id, return 0; } =20 +static inline int awcc_get_fan_sensors(struct wmi_device *wdev, u8 operati= on, + u8 fan_id, u8 index, u32 *out) +{ + struct wmax_u32_args args =3D { + .operation =3D operation, + .arg1 =3D fan_id, + .arg2 =3D index, + .arg3 =3D 0, + }; + + return __awcc_wmi_command(wdev, AWCC_METHOD_GET_FAN_SENSORS, &args, out); +} + static inline int awcc_thermal_information(struct wmi_device *wdev, u8 ope= ration, u8 arg, u32 *out) { @@ -552,6 +605,32 @@ static inline int awcc_op_get_resource_id(struct wmi_d= evice *wdev, u8 index, u32 return __awcc_wmi_command(wdev, AWCC_METHOD_THERMAL_INFORMATION, &args, o= ut); } =20 +static inline int awcc_op_get_fan_rpm(struct wmi_device *wdev, u8 fan_id, = u32 *out) +{ + struct wmax_u32_args args =3D { + .operation =3D AWCC_OP_GET_FAN_RPM, + .arg1 =3D fan_id, + .arg2 =3D 0, + .arg3 =3D 0, + }; + + + return __awcc_wmi_command(wdev, AWCC_METHOD_THERMAL_INFORMATION, &args, o= ut); +} + +static inline int awcc_op_get_temperature(struct wmi_device *wdev, u8 temp= _id, u32 *out) +{ + struct wmax_u32_args args =3D { + .operation =3D AWCC_OP_GET_TEMPERATURE, + .arg1 =3D temp_id, + .arg2 =3D 0, + .arg3 =3D 0, + }; + + + return __awcc_wmi_command(wdev, AWCC_METHOD_THERMAL_INFORMATION, &args, o= ut); +} + static inline int awcc_op_get_current_profile(struct wmi_device *wdev, u32= *out) { struct wmax_u32_args args =3D { @@ -599,6 +678,345 @@ static int awcc_profile_id_to_pprof(u32 id, enum plat= form_profile_option *profil return 0; } =20 +/* + * HWMON + * - Provides temperature and fan speed monitoring as well as manual fan + * control + */ +static umode_t awcc_hwmon_is_visible(const void *drvdata, enum hwmon_senso= r_types type, + u32 attr, int channel) +{ + const struct awcc_priv *priv =3D drvdata; + unsigned int temp_count; + + switch (type) { + case hwmon_temp: + temp_count =3D bitmap_weight(priv->temp_sensors, priv->temp_sensors_size= ); + + return channel < temp_count ? 0444 : 0; + case hwmon_fan: + return channel < priv->fan_count ? 0444 : 0; + case hwmon_pwm: + if (channel >=3D priv->fan_count) + return 0; + + switch (attr) { + case hwmon_pwm_enable: + return 0644; + case hwmon_pwm_auto_channels_temp: + return 0444; + default: + return 0; + } + default: + return 0; + } +} + +static int awcc_hwmon_read(struct device *dev, enum hwmon_sensor_types typ= e, + u32 attr, int channel, long *val) +{ + struct awcc_priv *priv =3D dev_get_drvdata(dev); + struct awcc_fan_data *fan; + u32 state; + int ret; + u8 temp; + + switch (type) { + case hwmon_temp: + temp =3D find_nth_bit(priv->temp_sensors, priv->temp_sensors_size, chann= el); + + switch (attr) { + case hwmon_temp_input: + ret =3D awcc_op_get_temperature(priv->wdev, temp, &state); + if (ret) + return ret; + + *val =3D state * MILLIDEGREE_PER_DEGREE; + break; + default: + return -EOPNOTSUPP; + } + + break; + case hwmon_fan: + fan =3D priv->fan_data[channel]; + + switch (attr) { + case hwmon_fan_input: + ret =3D awcc_op_get_fan_rpm(priv->wdev, fan->id, &state); + if (ret) + return ret; + + *val =3D state; + break; + case hwmon_fan_min: + *val =3D fan->min_rpm; + break; + case hwmon_fan_max: + *val =3D fan->max_rpm; + break; + default: + return -EOPNOTSUPP; + } + + break; + case hwmon_pwm: + fan =3D priv->fan_data[channel]; + + switch (attr) { + case hwmon_pwm_auto_channels_temp: + bitmap_copy(val, fan->auto_channels_temp, BITS_PER_LONG); + break; + default: + return -EOPNOTSUPP; + } + + break; + default: + return -EOPNOTSUPP; + } + + return 0; +} + +static int awcc_hwmon_read_string(struct device *dev, enum hwmon_sensor_ty= pes type, + u32 attr, int channel, const char **str) +{ + struct awcc_priv *priv =3D dev_get_drvdata(dev); + struct awcc_fan_data *fan; + u8 temp; + + switch (type) { + case hwmon_temp: + temp =3D find_nth_bit(priv->temp_sensors, priv->temp_sensors_size, chann= el); + + switch (temp) { + case AWCC_TEMP_SENSOR_CPU: + *str =3D "CPU"; + break; + case AWCC_TEMP_SENSOR_GPU: + *str =3D "GPU"; + break; + default: + *str =3D "Unknown"; + break; + } + + break; + case hwmon_fan: + fan =3D priv->fan_data[channel]; + + switch (fan->total_temps) { + case 0: + *str =3D "Independent Fan"; + break; + case 1: + temp =3D find_first_bit(fan->related_temps, priv->temp_sensors_size); + + switch (temp) { + case AWCC_TEMP_SENSOR_CPU: + *str =3D "Processor Fan"; + break; + case AWCC_TEMP_SENSOR_GPU: + *str =3D "Video Fan"; + break; + default: + *str =3D "Unknown Fan"; + break; + } + + break; + default: + *str =3D "Shared Fan"; + break; + } + + break; + default: + return -EOPNOTSUPP; + } + + return 0; +} + +static const struct hwmon_ops awcc_hwmon_ops =3D { + .is_visible =3D awcc_hwmon_is_visible, + .read =3D awcc_hwmon_read, + .read_string =3D awcc_hwmon_read_string, +}; + +static const struct hwmon_channel_info * const awcc_hwmon_info[] =3D { + HWMON_CHANNEL_INFO(temp, + HWMON_T_LABEL | HWMON_T_INPUT, + HWMON_T_LABEL | HWMON_T_INPUT, + HWMON_T_LABEL | HWMON_T_INPUT, + HWMON_T_LABEL | HWMON_T_INPUT, + HWMON_T_LABEL | HWMON_T_INPUT, + HWMON_T_LABEL | HWMON_T_INPUT + ), + HWMON_CHANNEL_INFO(fan, + HWMON_F_LABEL | HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_MAX, + HWMON_F_LABEL | HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_MAX, + HWMON_F_LABEL | HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_MAX, + HWMON_F_LABEL | HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_MAX, + HWMON_F_LABEL | HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_MAX, + HWMON_F_LABEL | HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_MAX + ), + HWMON_CHANNEL_INFO(pwm, + HWMON_PWM_AUTO_CHANNELS_TEMP, + HWMON_PWM_AUTO_CHANNELS_TEMP, + HWMON_PWM_AUTO_CHANNELS_TEMP, + HWMON_PWM_AUTO_CHANNELS_TEMP, + HWMON_PWM_AUTO_CHANNELS_TEMP, + HWMON_PWM_AUTO_CHANNELS_TEMP + ), + NULL +}; + +static const struct hwmon_chip_info awcc_hwmon_chip_info =3D { + .ops =3D &awcc_hwmon_ops, + .info =3D awcc_hwmon_info, +}; + +static int awcc_hwmon_temps_init(struct wmi_device *wdev) +{ + struct awcc_priv *priv =3D dev_get_drvdata(&wdev->dev); + unsigned long temp_sensors[BITS_TO_LONGS(U8_MAX)]; + unsigned int i, max_sensor_id =3D 0; + int ret; + u32 id; + + for (i =3D 0; i < priv->temp_count; i++) { + /* + * Temperature sensors IDs are listed after the fan IDs at + * offset `fan_count` + */ + ret =3D awcc_op_get_resource_id(wdev, i + priv->fan_count, &id); + if (ret) + return ret; + + id =3D FIELD_GET(AWCC_RESOURCE_ID_MASK, id); + if (id > max_sensor_id) + max_sensor_id =3D id; + + __set_bit(id, temp_sensors); + } + + /* + * We prefer to allocate the bitmap dynamically because usually temp IDs + * are small (< 0x30) and only one UL is needed to store it, but there + * may be unknown devices that break this rule + */ + priv->temp_sensors_size =3D max_sensor_id + 1; + priv->temp_sensors =3D devm_bitmap_zalloc(&wdev->dev, priv->temp_sensors_= size, + GFP_KERNEL); + if (!priv->temp_sensors) + return -ENOMEM; + + bitmap_copy(priv->temp_sensors, temp_sensors, priv->temp_sensors_size); + + return 0; +} + +static int awcc_hwmon_fans_init(struct wmi_device *wdev) +{ + struct awcc_priv *priv =3D dev_get_drvdata(&wdev->dev); + u32 id, min_rpm, max_rpm, temp_count, temp_id; + unsigned long gather[BITS_TO_LONGS(U8_MAX)]; + struct awcc_fan_data *fan_data; + unsigned int i, j; + int ret; + + for (i =3D 0; i < priv->fan_count; i++) { + fan_data =3D devm_kzalloc(&wdev->dev, sizeof(*fan_data), GFP_KERNEL); + if (!fan_data) + return -ENOMEM; + + fan_data->related_temps =3D devm_bitmap_zalloc(&wdev->dev, + priv->temp_sensors_size, + GFP_KERNEL); + if (!priv->temp_sensors) + return -ENOMEM; + + fan_data->auto_channels_temp =3D devm_bitmap_zalloc(&wdev->dev, + priv->temp_count, + GFP_KERNEL); + if (!priv->temp_sensors) + return -ENOMEM; + + /* + * Fan IDs are listed first at offset 0 + */ + ret =3D awcc_op_get_resource_id(wdev, i, &id); + if (ret) + return ret; + id =3D FIELD_GET(AWCC_RESOURCE_ID_MASK, id); + + ret =3D awcc_thermal_information(wdev, AWCC_OP_GET_FAN_MIN_RPM, id, + &min_rpm); + if (ret) + return ret; + + ret =3D awcc_thermal_information(wdev, AWCC_OP_GET_FAN_MAX_RPM, id, + &max_rpm); + if (ret) + return ret; + + ret =3D awcc_get_fan_sensors(wdev, AWCC_OP_GET_TOTAL_FAN_TEMPS, id, + 0, &temp_count); + if (ret) + return ret; + + for (j =3D 0; j < temp_count; j++) { + ret =3D awcc_get_fan_sensors(wdev, AWCC_OP_GET_FAN_TEMP_ID, + id, j, &temp_id); + if (ret) + break; + + temp_id =3D FIELD_GET(AWCC_RESOURCE_ID_MASK, temp_id); + if (temp_id < priv->temp_sensors_size) + __set_bit(temp_id, fan_data->related_temps); + } + + fan_data->id =3D id; + fan_data->min_rpm =3D min_rpm; + fan_data->max_rpm =3D max_rpm; + fan_data->total_temps =3D bitmap_weight(fan_data->related_temps, + priv->temp_sensors_size); + bitmap_gather(gather, fan_data->related_temps, priv->temp_sensors, + priv->temp_sensors_size); + bitmap_copy(fan_data->auto_channels_temp, gather, priv->temp_count); + priv->fan_data[i] =3D fan_data; + } + + return 0; +} + +static int awcc_hwmon_init(struct wmi_device *wdev) +{ + struct awcc_priv *priv =3D dev_get_drvdata(&wdev->dev); + int ret; + + priv->fan_data =3D devm_kcalloc(&wdev->dev, priv->fan_count, + sizeof(*priv->fan_data), GFP_KERNEL); + if (!priv->fan_data) + return -ENOMEM; + + ret =3D awcc_hwmon_temps_init(wdev); + if (ret) + return ret; + + ret =3D awcc_hwmon_fans_init(wdev); + if (ret) + return ret; + + priv->hwdev =3D devm_hwmon_device_register_with_info(&wdev->dev, "alienwa= re_wmi", priv, + &awcc_hwmon_chip_info, NULL); + + return PTR_ERR_OR_ZERO(priv->hwdev); +} + /* * Thermal Profile control * - Provides thermal profile control through the Platform Profile API @@ -753,6 +1171,12 @@ static int alienware_awcc_setup(struct wmi_device *wd= ev) priv->wdev =3D wdev; dev_set_drvdata(&wdev->dev, priv); =20 + if (awcc->hwmon) { + ret =3D awcc_hwmon_init(wdev); + if (ret) + return ret; + } + if (awcc->pprof) { ret =3D awcc_platform_profile_init(wdev); if (ret) @@ -833,6 +1257,13 @@ int __init alienware_wmax_wmi_init(void) if (id) awcc =3D id->driver_data; =20 + if (force_hwmon) { + if (!awcc) + awcc =3D &empty_quirks; + + awcc->hwmon =3D true; + } + if (force_platform_profile) { if (!awcc) awcc =3D &empty_quirks; --=20 2.48.1 From nobody Sun Feb 8 09:11:16 2026 Received: from mail-ua1-f45.google.com (mail-ua1-f45.google.com [209.85.222.45]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CABA6155744; Thu, 6 Mar 2025 00:58:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.222.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741222703; cv=none; b=a2IoQrJZE6sMJbspwmXO5mWlrXW8pFLLRO5J1mH7/y0vkbGY5Ax0GRtgV+A/usfazuTHO7w0CfA5IDU4zyVoA6Gu5v//2iD4hYiGD0gEfGjbeO1j9CAuBBxjuJAG9jeKcQFK4OZO2TuWvJO49qLnFZsqDhVypuZACpYxEEY9bII= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741222703; c=relaxed/simple; bh=s5x4lOTGnw5Q8PcWF713UcfigAEI1V9LQ9nULH9mSyM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Hm7//RQJYqLLGqxYwVhPKL0yzWSpcvmMUN3daRr6c7Q7gQYv4byIXP7PUpirQ0Fr43FIwV+ow0hDTpFiYHuUZHqj3OuULxMAmo8NTdvDVZAjxAVtimuZTTh6Iwdm88anYIE+5a+UqkFCByCgRmRcBd1tBKY68s6PRbfBxBeRrMQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=Rp0pU9z/; arc=none smtp.client-ip=209.85.222.45 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Rp0pU9z/" Received: by mail-ua1-f45.google.com with SMTP id a1e0cc1a2514c-86b3bd4d0faso27488241.3; Wed, 05 Mar 2025 16:58:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741222700; x=1741827500; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=8D9ztAwLAQxr3py/ju2NfZMZuFaZlpOJBPfxMkVBJQY=; b=Rp0pU9z/VUpm8Ug/tGS4mirGugbGipsDzvBWNaYUwDeMCPd920CVa+HBliJnEE52ig TqwPHCplRijnwmMAKF1REL6VMn7HHpHpI/Y6eksn2qOq1qahQxxXylpl6KkaY+/6mOru La3Hw7K7tuUIccQJKWSHGo3MJgfwOEr/pejWAu2N9XRB8BiX3mK/ygW6VeMYD9X4tzV0 vIDnQUK3KUTHKmxnPrZ31mi9N8Jhc6AgFX/dV0ASnH+nsSj5yGZ9VGJ7Y9PFESiv1iLU tEbGLpbijEIIWn9apxiGu8j5aa5ncvGYaZH3yA8Eprhsyhg7yYXaQXXJkj+wORSi9+78 G4ig== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741222700; x=1741827500; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=8D9ztAwLAQxr3py/ju2NfZMZuFaZlpOJBPfxMkVBJQY=; b=BBbsC9faxYaJk1qai+5LvkTFy7piXye+p7dCWTZx1nJFZ6vFgpjFsDmQWm1l7gTsdz NEALQE2oYx2mb9eDh2Qg8fTPhMEyQuOvkesDgaq9UpMN2fL9tA1B6tqxIt+NRJG7R0YO U4cYuDKyfq1JNU2mVtxDkaGCJ23Vb3SgzngEWbhiZ0Urbq2MUmf0ghaI9stsSiRepbKM sXee6umrvQmdGP8frDYBqt1Hv8/MpdcOuWzMO+REsWkjNQjmY0G7t4JFwWITC2rkpvwl iPybIACpuPkZGCm7rmipK1VjnfTWY98xu1wbDlTGri3nUGap3gVy869VwxoGnbU4fsiQ XM4Q== X-Forwarded-Encrypted: i=1; AJvYcCWoCaIm56umtp+aaaX/bm+YNwaMF4Kcx25UAWxWnbyigEV3o/xP9WzRvv8p3w0B96qPNJpnt1emi8uAhFja@vger.kernel.org, AJvYcCXgbUnAgFCIxCossWC0SbPrSUXyw5xle1/gDydogqWty+s8IoOwA77p5Y00pO1GV8X3qDhC/Pl0gPeWY1qGwLY30ww15g==@vger.kernel.org, AJvYcCXqeEV/nR5Mk89fvtCGEbAFjr/GW5u3N2YgAD2AVlhRPbFxiDOqzML7VT/ZChXes4fe4YtFpZcIhkBlog==@vger.kernel.org X-Gm-Message-State: AOJu0Yyw1GK+0Ou9+Wr0tTAyDw0sI9hg+rqU53eLRHyMekqy6sdMRaYv c8rB0wep15TSfIkGrOzZtgISHxnO+YFj8salra/X9xdV9lIiww+I X-Gm-Gg: ASbGncvE3oOISzPpojYzX49z0sx2nqOS/8lW7r0Nnmmg73zm0e6Q2NJh1Go5rTNK4s6 1wOUg/eP2y6wbYnurnt1VlP72Q/rP5hglQ9i4IDYOeroMcR03xxHqt+e3+9+8qZYF1qts3A1q5E qQvk6TpalrjfPl7rldsGu48vmONPIUT2ZvOuIVrv5M5GG8RmAPsZwhtAfM0RYx9eM38FeBDPtKq 4f1rpHXNzwe2T8zwDUd2hxG5HYWz/NrZeg5WaLFZWsEglIoydSxUtZkx9MkuR5gJYHf0lDZXijI QXiuomCK+ZGx9EXPE2jkHAwwuBxtwBpFzeRF9ioVW09KFw== X-Google-Smtp-Source: AGHT+IHPMKJbIvbaBv2eaZtZLIjqgplQijv6/Jo8dNH7iTEbbrnL/fQ2vOAluuH2DiD0ddlBMnrVXw== X-Received: by 2002:a05:6102:440e:b0:4c1:a66f:a468 with SMTP id ada2fe7eead31-4c2e299f78amr3548363137.22.1741222700519; Wed, 05 Mar 2025 16:58:20 -0800 (PST) Received: from [192.168.100.70] ([2800:bf0:82:3d2:9e61:1a62:1a8c:3e62]) by smtp.gmail.com with ESMTPSA id a1e0cc1a2514c-86d33bc0065sm25925241.4.2025.03.05.16.58.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 05 Mar 2025 16:58:19 -0800 (PST) From: Kurt Borja Date: Wed, 05 Mar 2025 19:56:59 -0500 Subject: [PATCH v3 08/10] platform/x86: alienware-wmi-wmax: Add support for manual fan control Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250305-hwm-v3-8-395e7a1407e2@gmail.com> References: <20250305-hwm-v3-0-395e7a1407e2@gmail.com> In-Reply-To: <20250305-hwm-v3-0-395e7a1407e2@gmail.com> To: =?utf-8?q?Ilpo_J=C3=A4rvinen?= , Armin Wolf Cc: Kurt Borja , Hans de Goede , platform-driver-x86@vger.kernel.org, Dell.Client.Kernel@dell.com, linux-kernel@vger.kernel.org, Guenter Roeck , Jean Delvare , linux-hwmon@vger.kernel.org X-Mailer: b4 0.14.2 All models with the "AWCC" WMAX device support a way of manually controlling fans. The PWM duty cycle of a fan can't be controlled directly. Instead the AWCC interface let's us tune a PWM `boost` value, which has the following empirically discovered, aproximate behavior over the PWM value: pwm =3D pwm_base + (pwm_boost / 255) * (pwm_max - pwm_base) Where the pwm_base is the locked PWM value controlled by the FW and pwm_boost is a value between 0 and 255. Expose this pwm_boost knob as a custom HWMON attribute. Cc: Guenter Roeck Cc: Jean Delvare Cc: linux-hwmon@vger.kernel.org Signed-off-by: Kurt Borja --- drivers/platform/x86/dell/alienware-wmi-wmax.c | 223 +++++++++++++++++++++= +++- 1 file changed, 220 insertions(+), 3 deletions(-) diff --git a/drivers/platform/x86/dell/alienware-wmi-wmax.c b/drivers/platf= orm/x86/dell/alienware-wmi-wmax.c index 20cf3371ee3c0e1ea038b3ca517e831f3b30dc29..de4e8f177aadc9552b05cc732e4= 1ee458b761143 100644 --- a/drivers/platform/x86/dell/alienware-wmi-wmax.c +++ b/drivers/platform/x86/dell/alienware-wmi-wmax.c @@ -13,8 +13,11 @@ #include #include #include +#include +#include #include #include +#include #include #include #include "alienware-wmi.h" @@ -179,10 +182,12 @@ enum AWCC_THERMAL_INFORMATION_OPERATIONS { AWCC_OP_GET_FAN_MIN_RPM =3D 0x08, AWCC_OP_GET_FAN_MAX_RPM =3D 0x09, AWCC_OP_GET_CURRENT_PROFILE =3D 0x0B, + AWCC_OP_GET_FAN_BOOST =3D 0x0C, }; =20 enum AWCC_THERMAL_CONTROL_OPERATIONS { AWCC_OP_ACTIVATE_PROFILE =3D 0x01, + AWCC_OP_SET_FAN_BOOST =3D 0x02, }; =20 enum AWCC_GAME_SHIFT_STATUS_OPERATIONS { @@ -248,6 +253,7 @@ struct awcc_fan_data { u32 total_temps; u32 min_rpm; u32 max_rpm; + u8 suspend_cache; u8 id; }; =20 @@ -627,6 +633,17 @@ static inline int awcc_op_get_temperature(struct wmi_d= evice *wdev, u8 temp_id, u .arg3 =3D 0, }; =20 + return __awcc_wmi_command(wdev, AWCC_METHOD_THERMAL_INFORMATION, &args, o= ut); +} + +static inline int awcc_op_get_fan_boost(struct wmi_device *wdev, u8 fan_id= , u32 *out) +{ + struct wmax_u32_args args =3D { + .operation =3D AWCC_OP_GET_FAN_BOOST, + .arg1 =3D fan_id, + .arg2 =3D 0, + .arg3 =3D 0, + }; =20 return __awcc_wmi_command(wdev, AWCC_METHOD_THERMAL_INFORMATION, &args, o= ut); } @@ -656,6 +673,19 @@ static inline int awcc_op_activate_profile(struct wmi_= device *wdev, u8 profile) return __awcc_wmi_command(wdev, AWCC_METHOD_THERMAL_CONTROL, &args, &out); } =20 +static int awcc_op_set_fan_boost(struct wmi_device *wdev, u8 fan_id, u8 bo= ost) +{ + struct wmax_u32_args args =3D { + .operation =3D AWCC_OP_SET_FAN_BOOST, + .arg1 =3D fan_id, + .arg2 =3D boost, + .arg3 =3D 0, + }; + u32 out; + + return __awcc_wmi_command(wdev, AWCC_METHOD_THERMAL_CONTROL, &args, &out); +} + static int awcc_profile_id_to_pprof(u32 id, enum platform_profile_option *= profile) { switch (id) { @@ -717,6 +747,7 @@ static int awcc_hwmon_read(struct device *dev, enum hwm= on_sensor_types type, u32 attr, int channel, long *val) { struct awcc_priv *priv =3D dev_get_drvdata(dev); + enum platform_profile_option profile; struct awcc_fan_data *fan; u32 state; int ret; @@ -765,6 +796,28 @@ static int awcc_hwmon_read(struct device *dev, enum hw= mon_sensor_types type, fan =3D priv->fan_data[channel]; =20 switch (attr) { + case hwmon_pwm_enable: + ret =3D awcc_op_get_current_profile(priv->wdev, &state); + if (ret) + return ret; + + ret =3D awcc_profile_id_to_pprof(state, &profile); + if (ret) + return ret; + + switch (profile) { + case PLATFORM_PROFILE_PERFORMANCE: + *val =3D 0; + break; + case PLATFORM_PROFILE_CUSTOM: + *val =3D 1; + break; + default: + *val =3D 2; + break; + } + + break; case hwmon_pwm_auto_channels_temp: bitmap_copy(val, fan->auto_channels_temp, BITS_PER_LONG); break; @@ -840,10 +893,48 @@ static int awcc_hwmon_read_string(struct device *dev,= enum hwmon_sensor_types ty return 0; } =20 + +static int awcc_hwmon_write(struct device *dev, enum hwmon_sensor_types ty= pe, + u32 attr, int channel, long val) +{ + struct awcc_priv *priv =3D dev_get_drvdata(dev); + int ret; + + switch (type) { + case hwmon_pwm: + switch (attr) { + case hwmon_pwm_enable: + /* + * We don't want to duplicate platform profile logic, so + * we only allow enabling manual fan control + */ + if (val !=3D 1) + return -EINVAL; + + ret =3D awcc_op_activate_profile(priv->wdev, AWCC_SPECIAL_PROFILE_CUSTO= M); + if (ret) + return ret; + + if (priv->ppdev) + platform_profile_notify(priv->ppdev); + break; + default: + return -EOPNOTSUPP; + } + + break; + default: + return -EOPNOTSUPP; + } + + return 0; +} + static const struct hwmon_ops awcc_hwmon_ops =3D { .is_visible =3D awcc_hwmon_is_visible, .read =3D awcc_hwmon_read, .read_string =3D awcc_hwmon_read_string, + .write =3D awcc_hwmon_write, }; =20 static const struct hwmon_channel_info * const awcc_hwmon_info[] =3D { @@ -864,7 +955,7 @@ static const struct hwmon_channel_info * const awcc_hwm= on_info[] =3D { HWMON_F_LABEL | HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_MAX ), HWMON_CHANNEL_INFO(pwm, - HWMON_PWM_AUTO_CHANNELS_TEMP, + HWMON_PWM_AUTO_CHANNELS_TEMP | HWMON_PWM_ENABLE, HWMON_PWM_AUTO_CHANNELS_TEMP, HWMON_PWM_AUTO_CHANNELS_TEMP, HWMON_PWM_AUTO_CHANNELS_TEMP, @@ -879,6 +970,75 @@ static const struct hwmon_chip_info awcc_hwmon_chip_in= fo =3D { .info =3D awcc_hwmon_info, }; =20 +static ssize_t pwm_boost_show(struct device *dev, struct device_attribute = *attr, + char *buf) +{ + int ret, index =3D to_sensor_dev_attr(attr)->index; + struct awcc_priv *priv =3D dev_get_drvdata(dev); + struct awcc_fan_data *fan =3D priv->fan_data[index]; + u32 boost; + + ret =3D awcc_op_get_fan_boost(priv->wdev, fan->id, &boost); + if (ret) + return ret; + + return sysfs_emit(buf, "%u\n", boost); +} + +static ssize_t pwm_boost_store(struct device *dev, struct device_attribute= *attr, + const char *buf, size_t count) +{ + int ret, index =3D to_sensor_dev_attr(attr)->index; + struct awcc_priv *priv =3D dev_get_drvdata(dev); + struct awcc_fan_data *fan =3D priv->fan_data[index]; + unsigned long val; + + ret =3D kstrtoul(buf, 0, &val); + if (ret) + return ret; + + ret =3D awcc_op_set_fan_boost(priv->wdev, fan->id, clamp_val(val, 0, 255)= ); + + return ret ? ret : count; +} + +static SENSOR_DEVICE_ATTR_RW(pwm1_boost, pwm_boost, 0); +static SENSOR_DEVICE_ATTR_RW(pwm2_boost, pwm_boost, 1); +static SENSOR_DEVICE_ATTR_RW(pwm3_boost, pwm_boost, 2); +static SENSOR_DEVICE_ATTR_RW(pwm4_boost, pwm_boost, 3); + +static umode_t pwm_boost_attr_visible(struct kobject *kobj, struct attribu= te *attr, int n) +{ + struct awcc_priv *priv =3D dev_get_drvdata(kobj_to_dev(kobj)); + + return n < priv->fan_count ? attr->mode : 0; +} + +static bool pwm_boost_group_visible(struct kobject *kobj) +{ + return true; +} + +DEFINE_SYSFS_GROUP_VISIBLE(pwm_boost); + +static struct attribute *fan_boost_attrs[] =3D { + &sensor_dev_attr_pwm1_boost.dev_attr.attr, + &sensor_dev_attr_pwm2_boost.dev_attr.attr, + &sensor_dev_attr_pwm3_boost.dev_attr.attr, + &sensor_dev_attr_pwm4_boost.dev_attr.attr, + NULL +}; + +static const struct attribute_group pwm_boost_group =3D { + .attrs =3D fan_boost_attrs, + .is_visible =3D SYSFS_GROUP_VISIBLE(pwm_boost), +}; + +static const struct attribute_group *awcc_hwmon_groups[] =3D { + &pwm_boost_group, + NULL +}; + static int awcc_hwmon_temps_init(struct wmi_device *wdev) { struct awcc_priv *priv =3D dev_get_drvdata(&wdev->dev); @@ -1011,12 +1171,50 @@ static int awcc_hwmon_init(struct wmi_device *wdev) if (ret) return ret; =20 - priv->hwdev =3D devm_hwmon_device_register_with_info(&wdev->dev, "alienwa= re_wmi", priv, - &awcc_hwmon_chip_info, NULL); + priv->hwdev =3D devm_hwmon_device_register_with_info(&wdev->dev, "alienwa= re_wmi", + priv, &awcc_hwmon_chip_info, + awcc_hwmon_groups); =20 return PTR_ERR_OR_ZERO(priv->hwdev); } =20 +static void awcc_hwmon_suspend(struct device *dev) +{ + struct awcc_priv *priv =3D dev_get_drvdata(dev); + struct awcc_fan_data *fan; + unsigned int i; + u32 boost; + int ret; + + for (i =3D 0; i < priv->fan_count; i++) { + fan =3D priv->fan_data[i]; + + ret =3D awcc_thermal_information(priv->wdev, AWCC_OP_GET_FAN_BOOST, + fan->id, &boost); + if (ret) + fan->suspend_cache =3D 0; + else + fan->suspend_cache =3D clamp_val(boost, 0, 255); + + awcc_op_set_fan_boost(priv->wdev, fan->id, 0); + } +} + +static void awcc_hwmon_resume(struct device *dev) +{ + + struct awcc_priv *priv =3D dev_get_drvdata(dev); + struct awcc_fan_data *fan; + unsigned int i; + + for (i =3D 0; i < priv->fan_count; i++) { + fan =3D priv->fan_data[i]; + + if (fan->suspend_cache) + awcc_op_set_fan_boost(priv->wdev, fan->id, fan->suspend_cache); + } +} + /* * Thermal Profile control * - Provides thermal profile control through the Platform Profile API @@ -1233,6 +1431,24 @@ static int wmax_wmi_probe(struct wmi_device *wdev, c= onst void *context) return ret; } =20 +static int wmax_wmi_suspend(struct device *dev) +{ + if (awcc->hwmon) + awcc_hwmon_suspend(dev); + + return 0; +} + +static int wmax_wmi_resume(struct device *dev) +{ + if (awcc->hwmon) + awcc_hwmon_resume(dev); + + return 0; +} + +DEFINE_SIMPLE_DEV_PM_OPS(wmax_wmi_pm_ops, wmax_wmi_suspend, wmax_wmi_resum= e); + static const struct wmi_device_id alienware_wmax_device_id_table[] =3D { { WMAX_CONTROL_GUID, NULL }, { }, @@ -1243,6 +1459,7 @@ static struct wmi_driver alienware_wmax_wmi_driver = =3D { .driver =3D { .name =3D "alienware-wmi-wmax", .probe_type =3D PROBE_PREFER_ASYNCHRONOUS, + .pm =3D pm_sleep_ptr(&wmax_wmi_pm_ops), }, .id_table =3D alienware_wmax_device_id_table, .probe =3D wmax_wmi_probe, --=20 2.48.1 From nobody Sun Feb 8 09:11:16 2026 Received: from mail-vk1-f182.google.com (mail-vk1-f182.google.com [209.85.221.182]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 96A3E1591E3; Thu, 6 Mar 2025 00:58:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741222705; cv=none; b=CXW42rzwjodrSbNaulQOShvLeP/ijFHVAnpjjiPGkBaxyUIZy3kMri1VUCYHs3RfDoLmEVEeZ7Tr6kZkNnS3snie/hkZl3hAgQkn9tLMq31YxIqaac2dgqg9+ThbljhTFIMPjpP2dN+gFa9a3/RZMlYCu7CIGWyyghRQ/1sc0vM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741222705; c=relaxed/simple; bh=chp/F8Y6++Gx+STgHaqN3GAqSE8+yKLRRtC/dnQoEf0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=mcWHRY6XWWmVeefkCh0Qlzo3uxaifcLL87QtnWeXrhaCn7CqEfYCm7w57pUKJGtbUMmdLmwdMP8hPAJrd/nV5aDTcbZ/L16ZSC1eDeJDxuY+wrEqFOn8gXYwq+cW0ZqYTrmCmYOIk9zelUMkWqbePbELFcyIC98cO1PpRM1YCs4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=QgXwcB4+; arc=none smtp.client-ip=209.85.221.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="QgXwcB4+" Received: by mail-vk1-f182.google.com with SMTP id 71dfb90a1353d-523b8881d31so42653e0c.2; Wed, 05 Mar 2025 16:58:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741222702; x=1741827502; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=TI0lDHvpkiROiD8ucwvU9Fu6HnI1c33Ny10vRXqT7Qo=; b=QgXwcB4+CPv5xKeJ6Z9+8QTdz0qgKSxk8xoEW/VDzySH5FbaVfKr/Rws+W8nvwItix vh7TYK01iT73UJ9GzzUkMP8shbuNl8jM1Gl/8McWePwnMX/zMH5HZE+4PdFD55bsEYJN m1sipeyypZxPl1dydMLNdvH9aUMiURa1sAkQYKiB56Dc3RupTNpQGKkIneJ2BUUNX+mG +a0ZSNoF9iYa4t2OjbTyiFa/pbhcLFknt6K+7Q6C8i047k2hH5/nZOBBsQVxUF8moJGN mrF6mTyly0IqAmSMhlxyhx8LQtu3GzYvC3x4/QndikAU5GQzHA51kpQFDg9fIrqW0ozm N2+Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741222702; x=1741827502; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=TI0lDHvpkiROiD8ucwvU9Fu6HnI1c33Ny10vRXqT7Qo=; b=JGYTcGvqh+ppET9Frg5TQUg/8BK+ZSG1HYNyjzQwzHgd73hxfB2lJIpm7H4Q42NCP/ Xf2kddfuqtz86Wo7VqXeRNiTi06x2S8NHsJaRSrKAaO2ZImxMrdJ4NQUUpy59usqtCpD nwSsTAMI7f5qTimRLGhoUUFuMdxP7cSSN/SlME3OagCvB748hYvTkph6h9xO68msl9fx wsYuhjobw4CqURfOluJqyseHSX650jytL/H9ZpOwAwf8O17uboEdC3hGhiiiyLzi2hg6 hGKxlIZoRjvoWksrCq8VESQrh6SrSoNGqNA3cHM//y2iwSvcqzR2gEBHiEZ2xfnYGy8h 4Ytg== X-Forwarded-Encrypted: i=1; AJvYcCUgOtAGQ/EPtEyZvgnGERkvJ5XYbA8PPI4BYavMno8ebzT7rGzRuVqdoM/ME/xS5ckKFCwEKjKrg83uN9jYbWG/28g8EA==@vger.kernel.org, AJvYcCUtuHlAzQIepBvyDQpZ9nWLmeLamSjc2+hYNbrqgg+uol9j6B3y7Jz9v0BVCe52XJk1dTng7EE9nJiEFIo=@vger.kernel.org X-Gm-Message-State: AOJu0YxxIuahwaEOP86dVlXzKATlxwnQywT6t0ojci8XjF/ckU3ph8f5 f/aKmuSD8HRKal597130ZJYasVmzEaVER6yM4mqdrBYORu9/JjlN X-Gm-Gg: ASbGnculDotvdyqLdklvD9Y+r9XArDfbn5aj83nl1Vc/1b/17ylFyYr71fe/oPGyCyc A1eVboCGT6x+apRCPGyJY70CD8lFd2Kya5Eku6V6aIMSFEFYbNe0QGvDw/KHscJqf+rhWt0CJga fZV+H1OArDlFAMS8/hlSRGFuqKLp+DMEj7BqLQZfC2Kz+5K3EM0iMVIX+resVJKHfSOMEX+HkxS mA5bupaBTJO6tCdmueTSh9LAYHNkPTtK6ZJBLj6Qj9ptE3PmZBt0GsNhT+51Z/1+Q72dloZKxIl W1hWSOMPggYN9H9J0hlbAhcnQRCW3wbIx4pWqpPVRUyi1Q== X-Google-Smtp-Source: AGHT+IHSP/wPQY1MOgpK6eN2qRWvOtKdySUE6FO2WSm3x2YJ+60ZsvqRdTYqhblt2l4T3wT4bSkj6Q== X-Received: by 2002:a05:6122:3208:b0:520:6773:e5bf with SMTP id 71dfb90a1353d-523c611e608mr3202308e0c.1.1741222702505; Wed, 05 Mar 2025 16:58:22 -0800 (PST) Received: from [192.168.100.70] ([2800:bf0:82:3d2:9e61:1a62:1a8c:3e62]) by smtp.gmail.com with ESMTPSA id a1e0cc1a2514c-86d33bc0065sm25925241.4.2025.03.05.16.58.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 05 Mar 2025 16:58:22 -0800 (PST) From: Kurt Borja Date: Wed, 05 Mar 2025 19:57:00 -0500 Subject: [PATCH v3 09/10] platform/x86: alienware-wmi-wmax: Add a DebugFS interface Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250305-hwm-v3-9-395e7a1407e2@gmail.com> References: <20250305-hwm-v3-0-395e7a1407e2@gmail.com> In-Reply-To: <20250305-hwm-v3-0-395e7a1407e2@gmail.com> To: =?utf-8?q?Ilpo_J=C3=A4rvinen?= , Armin Wolf Cc: Kurt Borja , Hans de Goede , platform-driver-x86@vger.kernel.org, Dell.Client.Kernel@dell.com, linux-kernel@vger.kernel.org X-Mailer: b4 0.14.2 Add a debugfs interface which exposes thermal private data. Signed-off-by: Kurt Borja Reviewed-by: Armin Wolf --- drivers/platform/x86/dell/alienware-wmi-wmax.c | 92 ++++++++++++++++++++++= ++++ 1 file changed, 92 insertions(+) diff --git a/drivers/platform/x86/dell/alienware-wmi-wmax.c b/drivers/platf= orm/x86/dell/alienware-wmi-wmax.c index de4e8f177aadc9552b05cc732e41ee458b761143..23f8680a212fb9ef2a6f23aafcc= 2d25738ae4364 100644 --- a/drivers/platform/x86/dell/alienware-wmi-wmax.c +++ b/drivers/platform/x86/dell/alienware-wmi-wmax.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -18,6 +19,7 @@ #include #include #include +#include #include #include #include "alienware-wmi.h" @@ -1343,6 +1345,94 @@ static int awcc_platform_profile_init(struct wmi_dev= ice *wdev) return PTR_ERR_OR_ZERO(priv->ppdev); } =20 +/* + * DebugFS + */ +static int awcc_debugfs_system_description_read(struct seq_file *seq, void= *data) +{ + struct device *dev =3D seq->private; + struct awcc_priv *priv =3D dev_get_drvdata(dev); + + seq_printf(seq, "0x%08x\n", priv->system_description); + + return 0; +} + +static int awcc_debugfs_hwmon_data_read(struct seq_file *seq, void *data) +{ + struct device *dev =3D seq->private; + struct awcc_priv *priv =3D dev_get_drvdata(dev); + struct awcc_fan_data *fan_data; + u8 bit; + + seq_printf(seq, "Number of fans: %u\n", priv->fan_count); + seq_printf(seq, "Number of temperature sensors: %u\n\n", priv->temp_count= ); + + for (u32 i =3D 0; i < priv->fan_count; i++) { + fan_data =3D priv->fan_data[i]; + + seq_printf(seq, "Fan %u:\n", i); + seq_printf(seq, " ID: 0x%02x\n", fan_data->id); + seq_printf(seq, " Related temperature sensors: "); + for_each_set_bit(bit, fan_data->related_temps, priv->temp_sensors_size) + seq_printf(seq, "0x%02x ", bit); + seq_puts(seq, "\n"); + } + + seq_puts(seq, "\n"); + + seq_printf(seq, "Temperature sensor IDs:\n"); + for_each_set_bit(bit, priv->temp_sensors, priv->temp_sensors_size) + seq_printf(seq, " 0x%02x\n", bit); + + return 0; +} + +static int awcc_debugfs_pprof_data_read(struct seq_file *seq, void *data) +{ + struct device *dev =3D seq->private; + struct awcc_priv *priv =3D dev_get_drvdata(dev); + + seq_printf(seq, "Number of thermal profiles: %u\n\n", priv->profile_count= ); + + for (u32 i =3D 0; i < PLATFORM_PROFILE_LAST; i++) { + if (!priv->supported_profiles[i]) + continue; + + seq_printf(seq, "Platform profile %u:\n", i); + seq_printf(seq, " ID: 0x%02x\n", priv->supported_profiles[i]); + } + + return 0; +} + +static void awcc_debugfs_remove(void *data) +{ + struct dentry *root =3D data; + + debugfs_remove(root); +} + +static void awcc_debugfs_init(struct wmi_device *wdev) +{ + struct dentry *root; + + root =3D debugfs_create_dir("alienware-wmi", NULL); + + debugfs_create_devm_seqfile(&wdev->dev, "system_description", root, + awcc_debugfs_system_description_read); + + if (awcc->hwmon) + debugfs_create_devm_seqfile(&wdev->dev, "hwmon_data", root, + awcc_debugfs_hwmon_data_read); + + if (awcc->pprof) + debugfs_create_devm_seqfile(&wdev->dev, "pprof_data", root, + awcc_debugfs_pprof_data_read); + + devm_add_action_or_reset(&wdev->dev, awcc_debugfs_remove, root); +} + static int alienware_awcc_setup(struct wmi_device *wdev) { struct awcc_priv *priv; @@ -1381,6 +1471,8 @@ static int alienware_awcc_setup(struct wmi_device *wd= ev) return ret; } =20 + awcc_debugfs_init(wdev); + return 0; } =20 --=20 2.48.1 From nobody Sun Feb 8 09:11:16 2026 Received: from mail-ua1-f46.google.com (mail-ua1-f46.google.com [209.85.222.46]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6FC421624E7; Thu, 6 Mar 2025 00:58:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.222.46 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741222708; cv=none; b=PKCGbqkyiUDIFRz4YUPr9styRxzx6PKhA4KZzk6V3pe1/HYIHVEGaM6mkhstVSKyIvQ+UXYuU/v7ggrVCGUs7dFJMqdd5IPi9faLNOwEFAFS9nqgGYP3KLbIAp4v2GbvS/yYjONL07coqQcRnTiv37B7DhX8O0ijJhsx4vhZDrU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741222708; c=relaxed/simple; bh=XRV0zZFon1XQEumSkex9XSyauZr93N1bucXCTV3S/yA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=dZte5r2ql6xALlc637MUMVeoHVRiZbUN+OG9nvvf5GHsVEg3Ic9j6Y3r2WnCdLu3jVfWMt+CIMJipRVAg4W3SVPyu35RdD0vzRQctMUfhp7s629e2wOQdkY5NT1Lv8SUgGo+5YKxUHwOzhhhzGuOzuk8iuaqePnNq+dzkxxdsWM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=lL2B4H7T; arc=none smtp.client-ip=209.85.222.46 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="lL2B4H7T" Received: by mail-ua1-f46.google.com with SMTP id a1e0cc1a2514c-86718c2c3b9so29016241.2; Wed, 05 Mar 2025 16:58:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741222705; x=1741827505; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=JVA5ilFoaMQw3HqnmEfUDcS38rAH3c06PSqheuCrEO8=; b=lL2B4H7TBvD6E+mNBIGbx0sno/3AhSLLX7kEpExUSs0V8IrifCfZ1WrVkgptIIEkh5 0s8lAF73rqTJ01CIEaDJWyuVFpuiMMqn60xVLJHntJRmeug1YOVUlvpHD6pkVOk0A1fI 4qqHc9E9fUwtPki0tgihs36tdynx+D0ogBDAJJSAvn3yzFMhGjXobSeCUUotzd8CPFrD ctZpOAb8aEXlIRTTpq1A9NvM+pgzkwyzl5cjdfIEZTAhnU3iRS3bF8t6DAhkJ4NXYsEM abMECWZWpL/YQQ2A21AJrgnRbrhrDtMqpFAVNSAM4VMgDkPisqa5E9BbOu91BGdWzMJH GcUA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741222705; x=1741827505; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=JVA5ilFoaMQw3HqnmEfUDcS38rAH3c06PSqheuCrEO8=; b=tnWVwm8DWGq01JwMk7DYmwPcmLt5IsCEqcWCnhcvI7HhVOt0GEvDmyRno9da7+vt+X 1OQ4E9uOOLFf9LEUmYPbQl/iAQLxZi95xpWY75bLoN2JmPYzuPBhaVh2pvNInquzqOPU NvBLg4wk4zmELUeGkz6Umq4q4ETwctHR7CCYOnQd8x/DaLIp6C/s6Z4zQ3nzMY6q2j4M QcdbX01BJdcR9ryGM3qHQbklQpyuoK3ONjQDPXHIpcL8BAtNIXrY3Aa39TQilUy+MqG1 sHyNrl5wRMj0f44ELGfquIvoKt+PN4hWf1C34aXOQJMHim1iVjXCkGY3X/i/aFILUXIt 3xog== X-Forwarded-Encrypted: i=1; AJvYcCUOtMp9H3JEGUd7p71cKaHy2KMjsNpUSABDHeCqwlT+wzIxT32IhRmcwFTTkMFNGeWK90Lgsrvr8lwPoNl2WphkGGGKsg==@vger.kernel.org, AJvYcCXsKUDd1cPyrPgXeGeffsXbwQX8BoubKY2dA5eCaf7WrBQkzZQUpTePCRDbFUOlfrrOOG0a6V5Ekq+Qvqc=@vger.kernel.org X-Gm-Message-State: AOJu0YwHmYq2lxTK58pkCLfD/ko51uIKpP4fHcPMr/pnCQjj6LDrO7Sn cPSax6p3oQYFpP/AGopuQuY2siUueKqeDfNk55QXayZ/JRWPY/ni X-Gm-Gg: ASbGncv7wQh1liMOQv9aiQYGU/MlPMR2q1SAgZui1ABEUMUOlOt0BTOL5LExit1qMyW 0tBszxenytqZXJDKjDvu5Z9Ai3q2f2isNvPtCzmdMTutGUJErg4C0oq5GlAvZDN6XcGArPKXl0N BOPaiYr+Zp+2JmQ2Bm0A4TJyNUOZvXZpmHWywS9gx4uvXQ4IwnhT02QqdubRHl0N++aSZ0OVO1Y LejSFIQ0/gNEACML+4HEyug6bHAKTRdIvPAqfvKQvodgJ4GJ/Odwe48RCsBbXyjhICEQHgO8KJi M1yb8wVQL3/Ew+ILNgqk3tvH9G0okmQN6wu9BZuH6Nenpw== X-Google-Smtp-Source: AGHT+IELi45HMzcDjlGTddzatYtqtXBTkTmaob5XSMSR+tllwENC7UeP5TQFzu5XSqtbhxYTddSpgw== X-Received: by 2002:a05:6102:c09:b0:4bb:bf49:9088 with SMTP id ada2fe7eead31-4c2e29108a0mr3004259137.16.1741222705248; Wed, 05 Mar 2025 16:58:25 -0800 (PST) Received: from [192.168.100.70] ([2800:bf0:82:3d2:9e61:1a62:1a8c:3e62]) by smtp.gmail.com with ESMTPSA id a1e0cc1a2514c-86d33bc0065sm25925241.4.2025.03.05.16.58.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 05 Mar 2025 16:58:24 -0800 (PST) From: Kurt Borja Date: Wed, 05 Mar 2025 19:57:01 -0500 Subject: [PATCH v3 10/10] Documentation: wmi: Improve and update alienware-wmi documentation Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250305-hwm-v3-10-395e7a1407e2@gmail.com> References: <20250305-hwm-v3-0-395e7a1407e2@gmail.com> In-Reply-To: <20250305-hwm-v3-0-395e7a1407e2@gmail.com> To: =?utf-8?q?Ilpo_J=C3=A4rvinen?= , Armin Wolf Cc: Kurt Borja , Hans de Goede , platform-driver-x86@vger.kernel.org, Dell.Client.Kernel@dell.com, linux-kernel@vger.kernel.org X-Mailer: b4 0.14.2 Use tables to describe method operations instead of using pseudo-code. Drop unknown method descriptions to avoid redundancy. Drop GPIO section as it is currently irrelevant to this driver. Update Thermal_Information method documentation. Add one more helpful developer to the kudos section. Signed-off-by: Kurt Borja Reviewed-by: Armin Wolf Reviewed-by: Bagas Sanjaya --- Documentation/wmi/devices/alienware-wmi.rst | 383 +++++++++---------------= ---- 1 file changed, 117 insertions(+), 266 deletions(-) diff --git a/Documentation/wmi/devices/alienware-wmi.rst b/Documentation/wm= i/devices/alienware-wmi.rst index ddc5e561960e05fc7cffe700d7d278e32ff2e7b2..79238051b18bc5de9b502325017= cd5c5fcf41748 100644 --- a/Documentation/wmi/devices/alienware-wmi.rst +++ b/Documentation/wmi/devices/alienware-wmi.rst @@ -11,7 +11,7 @@ The WMI device WMAX has been implemented for many Alienwa= re and Dell's G-Series models. Throughout these models, two implementations have been identified.= The first one, used by older systems, deals with HDMI, brightness, RGB, amplif= ier and deep sleep control. The second one used by newer systems deals primari= ly -with thermal, overclocking, and GPIO control. +with thermal control and overclocking. =20 It is suspected that the latter is used by Alienware Command Center (AWCC)= to manage manufacturer predefined thermal profiles. The alienware-wmi driver @@ -69,9 +69,6 @@ data using the `bmfdec `_= utility: [WmiMethodId(164), Implemented, read, write, Description("Tobii Camera = Power Off.")] void TobiiCameraPowerOff([out] uint32 argr); }; =20 -Some of these methods get quite intricate so we will describe them using -pseudo-code that vaguely resembles the original ASL code. - Methods not described in the following document have unknown behavior. =20 Argument Structure @@ -87,175 +84,133 @@ ID 0xA0, the argument you would pass to the method is= 0xA001. Thermal Methods =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 +WMI method GetFanSensors([in] uint32 arg2, [out] uint32 argr) +------------------------------------------------------------- + ++--------------------+------------------------------------+---------------= -----+ +| Operation (Byte 0) | Description | Arguments = | ++=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D+ +| 0x01 | Get the number of temperature | - Byte 1: Fan = ID | +| | sensors related with a fan ID | = | ++--------------------+------------------------------------+---------------= -----+ +| 0x02 | Get the temperature sensor IDs | - Byte 1: Fan = ID | +| | related to a fan sensor ID | - Byte 2: Inde= x | ++--------------------+------------------------------------+---------------= -----+ + WMI method Thermal_Information([in] uint32 arg2, [out] uint32 argr) ------------------------------------------------------------------- =20 -:: - - if BYTE_0(arg2) =3D=3D 0x01: - argr =3D 1 - - if BYTE_0(arg2) =3D=3D 0x02: - argr =3D SYSTEM_DESCRIPTION - - if BYTE_0(arg2) =3D=3D 0x03: - if BYTE_1(arg2) =3D=3D 0x00: - argr =3D FAN_ID_0 - - if BYTE_1(arg2) =3D=3D 0x01: - argr =3D FAN_ID_1 - - if BYTE_1(arg2) =3D=3D 0x02: - argr =3D FAN_ID_2 - - if BYTE_1(arg2) =3D=3D 0x03: - argr =3D FAN_ID_3 - - if BYTE_1(arg2) =3D=3D 0x04: - argr =3D SENSOR_ID_CPU | 0x0100 - - if BYTE_1(arg2) =3D=3D 0x05: - argr =3D SENSOR_ID_GPU | 0x0100 - - if BYTE_1(arg2) =3D=3D 0x06: - argr =3D THERMAL_MODE_QUIET_ID - - if BYTE_1(arg2) =3D=3D 0x07: - argr =3D THERMAL_MODE_BALANCED_ID - - if BYTE_1(arg2) =3D=3D 0x08: - argr =3D THERMAL_MODE_BALANCED_PERFORMANCE_ID - - if BYTE_1(arg2) =3D=3D 0x09: - argr =3D THERMAL_MODE_PERFORMANCE_ID - - if BYTE_1(arg2) =3D=3D 0x0A: - argr =3D THERMAL_MODE_LOW_POWER_ID - - if BYTE_1(arg2) =3D=3D 0x0B: - argr =3D THERMAL_MODE_GMODE_ID - - else: - argr =3D 0xFFFFFFFF - - if BYTE_0(arg2) =3D=3D 0x04: - if is_valid_sensor(BYTE_1(arg2)): - argr =3D SENSOR_TEMP_C - else: - argr =3D 0xFFFFFFFF - - if BYTE_0(arg2) =3D=3D 0x05: - if is_valid_fan(BYTE_1(arg2)): - argr =3D FAN_RPM() - - if BYTE_0(arg2) =3D=3D 0x06: - skip - - if BYTE_0(arg2) =3D=3D 0x07: - argr =3D 0 - - If BYTE_0(arg2) =3D=3D 0x08: - if is_valid_fan(BYTE_1(arg2)): - argr =3D 0 - else: - argr =3D 0xFFFFFFFF - - if BYTE_0(arg2) =3D=3D 0x09: - if is_valid_fan(BYTE_1(arg2)): - argr =3D FAN_UNKNOWN_STAT_0() - - else: - argr =3D 0xFFFFFFFF - - if BYTE_0(arg2) =3D=3D 0x0A: - argr =3D THERMAL_MODE_BALANCED_ID - - if BYTE_0(arg2) =3D=3D 0x0B: - argr =3D CURRENT_THERMAL_MODE() - - if BYTE_0(arg2) =3D=3D 0x0C: - if is_valid_fan(BYTE_1(arg2)): - argr =3D FAN_UNKNOWN_STAT_1() - else: - argr =3D 0xFFFFFFFF - -Operation 0x02 returns a *system description* buffer with the following -structure: - -:: - - out[0] -> Number of fans - out[1] -> Number of sensors - out[2] -> 0x00 - out[3] -> Number of thermal modes - -Operation 0x03 list all available fan IDs, sensor IDs and thermal profile -codes in order, but different models may have different number of fans and -thermal profiles. These are the known ranges: - -* Fan IDs: from 2 up to 4 -* Sensor IDs: 2 -* Thermal profile codes: from 1 up to 7 - -In total BYTE_1(ARG2) may range from 0x5 up to 0xD depending on the model. ++--------------------+------------------------------------+---------------= -----+ +| Operation (Byte 0) | Description | Arguments = | ++=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D+ +| 0x01 | Unknown. | - None = | ++--------------------+------------------------------------+---------------= -----+ +| 0x02 | Get system description number with | - None = | +| | the following structure: | = | +| | | = | +| | - Byte 0: Number of fans | = | +| | - Byte 1: Number of temperature | = | +| | sensors | = | +| | - Byte 2: Unknown | = | +| | - Byte 3: Number of thermal | = | +| | profiles | = | ++--------------------+------------------------------------+---------------= -----+ +| 0x03 | List an ID or resource at a given | - Byte 1: Inde= x | +| | index. Fan IDs, temperature IDs, | = | +| | unknown IDs and thermal profile | = | +| | IDs are listed in that exact | = | +| | order. | = | +| | | = | +| | Operation 0x02 is used to know | = | +| | which indexes map to which | = | +| | resources. | = | +| | | = | +| | **Returns:** ID at a given index | = | ++--------------------+------------------------------------+---------------= -----+ +| 0x04 | Get the current temperature for a | - Byte 1: Sens= or | +| | given temperature sensor. | ID = | ++--------------------+------------------------------------+---------------= -----+ +| 0x05 | Get the current RPM for a given | - Byte 1: Fan = ID | +| | fan. | = | ++--------------------+------------------------------------+---------------= -----+ +| 0x06 | Get fan speed percentage. (not | - Byte 1: Fan = ID | +| | implemented in every model) | = | ++--------------------+------------------------------------+---------------= -----+ +| 0x07 | Unknown. | - Unknown = | ++--------------------+------------------------------------+---------------= -----+ +| 0x08 | Get minimum RPM for a given FAN | - Byte 1: Fan = ID | +| | ID. | = | ++--------------------+------------------------------------+---------------= -----+ +| 0x09 | Get maximum RPM for a given FAN | - Byte 1: Fan = ID | +| | ID. | = | ++--------------------+------------------------------------+---------------= -----+ +| 0x0A | Get balanced thermal profile ID. | - None = | ++--------------------+------------------------------------+---------------= -----+ +| 0x0B | Get current thermal profile ID. | - None = | ++--------------------+------------------------------------+---------------= -----+ +| 0x0C | Get current `boost` value for a | - Byte 1: Fan = ID | +| | given fan ID. | = | ++--------------------+------------------------------------+---------------= -----+ =20 WMI method Thermal_Control([in] uint32 arg2, [out] uint32 argr) --------------------------------------------------------------- =20 -:: - - if BYTE_0(arg2) =3D=3D 0x01: - if is_valid_thermal_profile(BYTE_1(arg2)): - SET_THERMAL_PROFILE(BYTE_1(arg2)) - argr =3D 0 - - if BYTE_0(arg2) =3D=3D 0x02: - if is_valid_fan(BYTE_1(arg2)): - SET_FAN_SPEED_MULTIPLIER(BYTE_2(arg2)) - argr =3D 0 - else: - argr =3D 0xFFFFFFFF - -.. note:: - While you can manually change the fan speed multiplier with this method, - Dell's BIOS tends to overwrite this changes anyway. ++--------------------+------------------------------------+---------------= -----+ +| Operation (Byte 0) | Description | Arguments = | ++=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D+ +| 0x01 | Activate a given thermal profile. | - Byte 1: Ther= mal | +| | | profile ID = | ++--------------------+------------------------------------+---------------= -----+ +| 0x02 | Set a `boost` value for a given | - Byte 1: Fan = ID | +| | fan ID. | - Byte 2: Boos= t | ++--------------------+------------------------------------+---------------= -----+ =20 These are the known thermal profile codes: =20 -:: ++------------------------------+----------+------+ +| Thermal Profile | Type | ID | ++=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+=3D=3D=3D=3D=3D=3D+ +| Custom | Special | 0x00 | ++------------------------------+----------+------+ +| G-Mode | Special | 0xAB | ++------------------------------+----------+------+ +| Quiet | Legacy | 0x96 | ++------------------------------+----------+------+ +| Balanced | Legacy | 0x97 | ++------------------------------+----------+------+ +| Balanced Performance | Legacy | 0x98 | ++------------------------------+----------+------+ +| Performance | Legacy | 0x99 | ++------------------------------+----------+------+ +| Balanced | USTT | 0xA0 | ++------------------------------+----------+------+ +| Balanced Performance | USTT | 0xA1 | ++------------------------------+----------+------+ +| Cool | USTT | 0xA2 | ++------------------------------+----------+------+ +| Quiet | USTT | 0xA3 | ++------------------------------+----------+------+ +| Performance | USTT | 0xA4 | ++------------------------------+----------+------+ +| Low Power | USTT | 0xA5 | ++------------------------------+----------+------+ =20 - CUSTOM 0x00 +If a model supports the User Selectable Thermal Tables (USTT) profiles, it= will +not support the Legacy profiles and vice-versa. =20 - BALANCED_USTT 0xA0 - BALANCED_PERFORMANCE_USTT 0xA1 - COOL_USTT 0xA2 - QUIET_USTT 0xA3 - PERFORMANCE_USTT 0xA4 - LOW_POWER_USTT 0xA5 - - QUIET 0x96 - BALANCED 0x97 - BALANCED_PERFORMANCE 0x98 - PERFORMANCE 0x99 - - GMODE 0xAB - -Usually if a model doesn't support the first four profiles they will suppo= rt -the User Selectable Thermal Tables (USTT) profiles and vice-versa. - -GMODE replaces PERFORMANCE in G-Series laptops. +Every model supports the CUSTOM (0x00) thermal profile. GMODE replaces +PERFORMANCE in G-Series laptops. =20 WMI method GameShiftStatus([in] uint32 arg2, [out] uint32 argr) --------------------------------------------------------------- =20 -:: - - if BYTE_0(arg2) =3D=3D 0x1: - TOGGLE_GAME_SHIFT() - argr =3D GET_GAME_SHIFT_STATUS() - - if BYTE_0(arg2) =3D=3D 0x2: - argr =3D GET_GAME_SHIFT_STATUS() ++--------------------+------------------------------------+---------------= -----+ +| Operation (Byte 0) | Description | Arguments = | ++=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D+ +| 0x01 | Toggle *Game Shift*. | - None = | ++--------------------+------------------------------------+---------------= -----+ +| 0x02 | Get *Game Shift* status. | - None = | ++--------------------+------------------------------------+---------------= -----+ =20 Game Shift Status does not change the fan speed profile but it could be so= me sort of CPU/GPU power profile. Benchmarks have not been done. @@ -267,131 +222,27 @@ Thermal_Information does not list it. G-key on Dell's G-Series laptops also changes Game Shift status, so both a= re directly related. =20 -WMI method GetFanSensors([in] uint32 arg2, [out] uint32 argr) -------------------------------------------------------------- - -:: - - if BYTE_0(arg2) =3D=3D 0x1: - if is_valid_fan(BYTE_1(arg2)): - argr =3D 1 - else: - argr =3D 0 - - if BYTE_0(arg2) =3D=3D 0x2: - if is_valid_fan(BYTE_1(arg2)): - if BYTE_2(arg2) =3D=3D 0: - argr =3D=3D SENSOR_ID - else - argr =3D=3D 0xFFFFFFFF - else: - argr =3D 0 - Overclocking Methods =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 -.. warning:: - These methods have not been tested and are only partially reverse - engineered. - -WMI method Return_OverclockingReport([out] uint32 argr) -------------------------------------------------------- - -:: - - CSMI (0xE3, 0x99) - argr =3D 0 - -CSMI is an unknown operation. - -WMI method Set_OCUIBIOSControl([in] uint32 arg2, [out] uint32 argr) -------------------------------------------------------------------- - -:: - - CSMI (0xE3, 0x99) - argr =3D 0 - -CSMI is an unknown operation. - -WMI method Clear_OCFailSafeFlag([out] uint32 argr) --------------------------------------------------- - -:: - - CSMI (0xE3, 0x99) - argr =3D 0 - -CSMI is an unknown operation. - - WMI method MemoryOCControl([in] uint32 arg2, [out] uint32 argr) --------------------------------------------------------------- =20 AWCC supports memory overclocking, but this method is very intricate and h= as not been deciphered yet. =20 -GPIO methods -=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - -These methods are probably related to some kind of firmware update system, -through a GPIO device. - -.. warning:: - These methods have not been tested and are only partially reverse - engineered. - -WMI method FWUpdateGPIOtoggle([in] uint32 arg2, [out] uint32 argr) ------------------------------------------------------------------- - -:: - - if BYTE_0(arg2) =3D=3D 0: - if BYTE_1(arg2) =3D=3D 1: - SET_PIN_A_HIGH() - else: - SET_PIN_A_LOW() - - if BYTE_0(arg2) =3D=3D 1: - if BYTE_1(arg2) =3D=3D 1: - SET_PIN_B_HIGH() - - else: - SET_PIN_B_LOW() - - else: - argr =3D 1 - -WMI method ReadTotalofGPIOs([out] uint32 argr) ----------------------------------------------- - -:: - - argr =3D 0x02 - -WMI method ReadGPIOpPinStatus([in] uint32 arg2, [out] uint32 argr) ------------------------------------------------------------------- - -:: - - if BYTE_0(arg2) =3D=3D 0: - argr =3D PIN_A_STATUS - - if BYTE_0(arg2) =3D=3D 1: - argr =3D PIN_B_STATUS - Other information Methods =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D =20 WMI method ReadChassisColor([out] uint32 argr) ---------------------------------------------- =20 -:: - - argr =3D CHASSIS_COLOR_ID +Returns the chassis color internal ID. =20 Acknowledgements =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 -Kudos to `AlexIII `_ for documenting -and testing available thermal profile codes. +Kudos to `AlexIII `_ and +`T-Troll `_ for documenting and +testing some of this device's functionality, making it possible to general= ize +this driver. --=20 2.48.1