* [PATCH v12] hwmon: (yogafan) Add support for Lenovo Yoga/Legion fan monitoring
@ 2026-08-03 18:42 Sergio Melas
2026-08-03 19:04 ` sashiko-bot
2026-08-05 21:42 ` Guenter Roeck
0 siblings, 2 replies; 3+ messages in thread
From: Sergio Melas @ 2026-08-03 18:42 UTC (permalink / raw)
To: Guenter Roeck; +Cc: linux-hwmon, linux-kernel, Sergio Melas
This driver provides fan speed monitoring for modern Lenovo consumer
laptops by interfacing with the Embedded Controller (EC) via ACPI.
To address low-resolution sampling in Lenovo EC firmware, a Rate-Limited
Lag (RLLag) filter is implemented. The filter ensures a consistent physical
curve regardless of userspace polling frequency.
Hardware identification is performed via DMI-based quirk tables, which
map specific ACPI object paths and register widths (8-bit vs 16-bit)
deterministically. This patch introduces specific quirks for the Lenovo
LOQ 15IAX9, IdeaPad 3 15ALC6, Legion Pro 7 16AFR10H, Yoga Pro 7 14IAH10,
and Yoga 7 16ARP8.
Signed-off-by: Sergio Melas <sergiomelas@gmail.com>
---
v12:
- Reordered yogafan_quirks table so exact model matches are evaluated
before generic family fallbacks, preventing DMI shadowing.
- Added support and proper DMI/ACPI mappings for Lenovo LOQ 15IAX9,
IdeaPad 3 15ALC6, Legion Pro 7 16AFR10H, Yoga Pro 7 14IAH10, and
Yoga 7 16ARP8 (with thanks to community DSDT contributors).
- Updated Documentation/hwmon/yogafan.rst reference database and credits.
v11.1:
- Fixed Documentation formatting (0-day robot warnings).
- Fixed yogafan.c header comment
v11:
- Mapped ACPI paths directly via DMI quirks.
- Fixed Documentation formatting (0-day robot warnings).
- Implemented 100ms MIN_SAMPLING to address rapid polling concerns.
- Removed redundant platform_set_drvdata() in probe.
- Explicitly defined platform device ID as -1 for cleaner sysfs naming.
v9/10:
- Implement ACPI handle resolution during probe for better performance (O(1) read).
- Add MODULE_DEVICE_TABLE(dmi, ...) to enable module autoloading.
- Refine RLLag filter documentation and suspend/resume logic.
- Include comprehensive EC architecture research database (8-bit vs 16-bit).
- Validated efficiency on kernels 6.18, 6.19, and 7.0-rc5: 'perf top'
confirms negligible CPU overhead (<0.01%) during active polling.
v8:
- Replaced heuristic multiplier with deterministic DMI Quirk Table.
- Added 'depends on DMI' to Kconfig.
- Verified FOPTD model (1000ms TAU / 1500 RPM/s slew) against hardware traces.
- Increased filter precision to 12-bit fixed-point.
v7:
- Fixed Kconfig: Removed non-existent 'select MATH64'.
- Fixed unused macro: Utilized RPM_FLOOR_LIMIT to implement an
immediate 0-RPM bypass in the filter.
- Clarification: Previous "unified structure" comment meant that all
6 files (driver, docs, metadata) are now in this single atomic patch.
v6:
- Unified patch structure (6 files changed).
- Verified FOPTD (First-Order Plus Time Delay) model against hardware
traces (Yoga 14c) to ensure physical accuracy of the 1000ms time constant.
- Fixed a rounding stall: added a +/- 1 RPM floor to the step calculation
to ensure convergence even at high polling frequencies.
- Set MAX_SLEW_RPM_S to 1500 to match physical motor inertia.
- Documentation: Updated to clarify 100-RPM hardware step resolution.
- 32-bit safety: Implemented div64_s64 for coefficient precision.
v5:
- Fixed 32-bit build failures by using div64_s64 for 64-bit division.
- Extracted magic numbers into constants (RPM_UNIT_THRESHOLD, etc.).
- Fixed filter stall by ensuring a minimum slew limit (limit = 1).
- Refined RPM floor logic to trigger only when hardware reports 0 RPM.
- Resolved 255/256 unit-jump bug by adjusting heuristic thresholds.
v4:
- Rebased on groeck/hwmon-next branch for clean application.
- Corrected alphabetical sorting in Kconfig and Makefile.
- Technical Validation & FOPTD Verification:
- Implemented RLLag (Rate-Limited Lag) first-order modeling.
- Used 10-bit fixed-point math for alpha calculation to avoid
floating point overhead in the kernel.
- Added 5000ms filter reset for resume/long-polling sanitation.
v3:
- Added MAINTAINERS entry and full Documentation/hwmon/yogafan.rst.
- Fixed integer overflow in filter math.
- Added support for secondary fan paths (FA2S) for Legion laptops.
v2:
- Migrated from background worker to passive multirate filtering.
- Implemented dt-based scaling to maximize CPU sleep states.
- Restricted driver to Lenovo hardware via DMI matching.
v1:
- Initial submission with basic ACPI fan path support.
---
---
Documentation/hwmon/yogafan.rst | 27 ++++++++++++-
drivers/hwmon/yogafan.c | 71 +++++++++++++++++++++++++++++----
2 files changed, 89 insertions(+), 9 deletions(-)
diff --git a/Documentation/hwmon/yogafan.rst b/Documentation/hwmon/yogafan.rst
index 68761947a..6395c94f4 100644
--- a/Documentation/hwmon/yogafan.rst
+++ b/Documentation/hwmon/yogafan.rst
@@ -99,6 +99,11 @@ immediately to ensure the user knows the fan has stopped.
82XV / 83DV | LOQ 15/16 | 0xFE/0xFF | \_SB.PCI0.LPC0.EC0.FANS /FA2S | 16-bit | 1
83AK | ThinkBook G6 | 0x06 | \_SB.PCI0.LPC0.EC0.FAN0 | 8-bit | 100
81X1 | Flex 5 | 0x06 | \_SB.PCI0.LPC0.EC0.FAN0 | 8-bit | 100
+ 83KF | XiaoXinPro 13ARE | 0x06/0xFE | \_SB.PCI0.LPC0.EC0.FANS/FA2S | 8-bit | 100
+ 82KU | IdeaPad 3 15ALC6 | 0x06 | \_SB.PCI0.LPC0.EC0.FAN0 | 8-bit | 100
+ 83RU | Legion Pro 7 16 | 0x03/0x06 | \_SB.PCI0.LPC0.EC0.FANS/FA2S | 8-bit | 100
+ 83KF | Yoga Pro 7 14IAH | 0x06 | \_SB.PC00.LPCB.EC0.FANS | 8-bit | 100
+ 83BS | Yoga 7 16ARP8 | 0x03/0x06 | \_SB.PCI0.LPC0.EC0.FANS/FA2S | 8-bit | 100
*Legacy* | Pre-2020 Models | 0x06 | \_SB.PCI0.LPC.EC.FAN0 | 8-bit | 100
----------------------------------------------------------------------------------------------------
@@ -117,7 +122,6 @@ METHODOLOGY & IDENTIFICATION:
- 8-bit (Multiplier 100): Standard for Yoga/IdeaPad. Raw values (0-255).
- 16-bit (Multiplier 1): Standard for Legion/LOQ. Two registers (0xFE/0xFF).
-
References
----------
@@ -136,3 +140,24 @@ References
4. **Lenovo IdeaPad Laptop Driver:** Reference for DMI-based hardware
feature gating in Lenovo laptops.
https://github.com/torvalds/linux/blob/master/drivers/platform/x86/lenovo/ideapad-laptop.c
+
+5. **Lenovo Product Specifications Reference (PSREF):** Official hardware layout index
+ and spec sheets for active and withdrawn Lenovo laptop models.
+ https://psref.lenovo.com/l/withdrawn/
+
+6. **Yogafan Master Quirk Database:** Master spreadsheet mapping Lenovo Product
+ Specifications Reference (PSREF) to explicit EC offsets, register widths, paths, and multipliers.
+ https://github.com/sergiomelas/lenovo-linux-drivers/blob/main/Lenovo_Drivers/Prototype/PSREF/yogafan_v3_quirks_database.ods
+
+7. **Yogafan ACPI DSDT Repository:** Central repository containing user-contributed raw
+ and decompiled ACPI DSDT firmware dumps used for path verification and hardware expansions.
+ https://github.com/sergiomelas/lenovo-linux-drivers/tree/main/Lenovo_Drivers/Prototype/DSDT
+
+Contributors & DSDT Providers:
+------------------------------
+- **Sarbajit Sarkar** (Lenovo LOQ 15IAX9)
+- **HinataKato** (XiaoXin Pro 13ARE 2020 - 83KF)
+- **PenPenIsGod** (IdeaPad 3 15ALC6 - 82KU & Legion Pro 7 16AFR10H - 83RU)
+- **unlockxiaom** (Legion Pro 7 16AFR10H - 83RU, Yoga Pro 7 14IAH10 - 83KF, ThinkCentre M80q)
+- **Phani Pavan K** (Yoga Pro 7 14IAH10 - 83KF)
+- **Splarkszter** (Yoga 7 16ARP8 - 83BS)
diff --git a/drivers/hwmon/yogafan.c b/drivers/hwmon/yogafan.c
index 0a41b8672..371e35895 100644
--- a/drivers/hwmon/yogafan.c
+++ b/drivers/hwmon/yogafan.c
@@ -53,6 +53,7 @@ struct yoga_fan_data {
};
/* Specific configurations mapped via DMI */
+
static const struct yogafan_config yoga_8bit_fans_cfg = {
.multiplier = 100,
.fan_count = 1,
@@ -77,6 +78,18 @@ static const struct yogafan_config loq_15iax9_8bit_dual_cfg = {
.paths = { "\\_SB.PC00.LPCB.EC0.FA1S", "\\_SB.PC00.LPCB.EC0.FA2S" }
};
+static const struct yogafan_config xiaoxin_8bit_dual_cfg = {
+ .multiplier = 100,
+ .fan_count = 2,
+ .paths = { "\\_SB.PCI0.LPC0.EC0.FANS", "\\_SB.PCI0.LPC0.EC0.FA2S" }
+};
+
+static const struct yogafan_config yoga_pro_7_14iah10_cfg = {
+ .multiplier = 100,
+ .fan_count = 1,
+ .paths = { "\\_SB.PC00.LPCB.EC0.FANS", NULL }
+};
+
static void apply_rllag_filter(struct yoga_fan_data *data, int idx, long raw_rpm)
{
ktime_t now = ktime_get_boottime();
@@ -176,6 +189,56 @@ static const struct hwmon_chip_info yoga_fan_chip_info = {
};
static const struct dmi_system_id yogafan_quirks[] = {
+ /* 1. Particular first */
+ {
+ .ident = "Lenovo LOQ 15IAX9",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_FAMILY, "LOQ 15IAX9"),
+ },
+ .driver_data = (void *)&loq_15iax9_8bit_dual_cfg,
+ },
+ {
+ .ident = "Lenovo XiaoXin Pro 13ARE 2020",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_FAMILY, "XiaoXinPro-13ARE 2020"),
+ },
+ .driver_data = (void *)&xiaoxin_8bit_dual_cfg,
+ },
+ {
+ .ident = "Lenovo IdeaPad 3 15ALC6",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_FAMILY, "IdeaPad 3 15ALC6"),
+ },
+ .driver_data = (void *)&ideapad_8bit_fan0_cfg,
+ },
+ {
+ .ident = "Lenovo Legion Pro 7 16AFR10H",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_FAMILY, "Legion Pro 7 16AFR10H"),
+ },
+ .driver_data = (void *)&xiaoxin_8bit_dual_cfg,
+ },
+ {
+ .ident = "Lenovo Yoga Pro 7 14IAH10",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_FAMILY, "Yoga Pro 7 14IAH10"),
+ },
+ .driver_data = (void *)&yoga_pro_7_14iah10_cfg,
+ },
+ {
+ .ident = "Lenovo Yoga 7 16ARP8",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_FAMILY, "Yoga 7 16ARP8"),
+ },
+ .driver_data = (void *)&xiaoxin_8bit_dual_cfg,
+ },
+ /* 2. Generic Family Fallbacks LAST */
{
.ident = "Lenovo Yoga",
.matches = {
@@ -200,14 +263,6 @@ static const struct dmi_system_id yogafan_quirks[] = {
},
.driver_data = (void *)&ideapad_8bit_fan0_cfg,
},
- {
- .ident = "Lenovo LOQ 15IAX9",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
- DMI_MATCH(DMI_PRODUCT_FAMILY, "LOQ 15IAX9"),
- },
- .driver_data = (void *)&loq_15iax9_8bit_dual_cfg,
- },
{ }
};
MODULE_DEVICE_TABLE(dmi, yogafan_quirks);
--
2.55.0
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: [PATCH v12] hwmon: (yogafan) Add support for Lenovo Yoga/Legion fan monitoring
2026-08-03 18:42 [PATCH v12] hwmon: (yogafan) Add support for Lenovo Yoga/Legion fan monitoring Sergio Melas
@ 2026-08-03 19:04 ` sashiko-bot
2026-08-05 21:42 ` Guenter Roeck
1 sibling, 0 replies; 3+ messages in thread
From: sashiko-bot @ 2026-08-03 19:04 UTC (permalink / raw)
To: Sergio Melas; +Cc: linux-hwmon
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] The MIN_SAMPLING rate limit fails to prevent excessive ACPI queries to the EC because the check occurs after the ACPI evaluation.
--
--- Patch [1]: [PATCH v12] hwmon: (yogafan) Add support for Lenovo Yoga/Legion fan monitoring ---
commit c15f7b338b1cdd81a16c2f92f8d5807ac9a0b7da
Author: Sergio Melas <sergiomelas@gmail.com>
hwmon: (yogafan) Add support for Lenovo Yoga/Legion fan monitoring
This driver provides fan speed monitoring for modern Lenovo consumer
laptops by interfacing with the Embedded Controller (EC) via ACPI.
To address low-resolution sampling in Lenovo EC firmware, a Rate-Limited
Lag (RLLag) filter is implemented. The filter ensures a consistent physical
curve regardless of userspace polling frequency.
> diff --git a/drivers/hwmon/yogafan.c b/drivers/hwmon/yogafan.c
> index 0a41b8672b56e..371e35895f584 100644
> --- a/drivers/hwmon/yogafan.c
> +++ b/drivers/hwmon/yogafan.c
[ ... ]
> @@ -77,6 +78,18 @@ static const struct yogafan_config loq_15iax9_8bit_dual_cfg = {
> .paths = { "\\_SB.PC00.LPCB.EC0.FA1S", "\\_SB.PC00.LPCB.EC0.FA2S" }
> };
>
> +static const struct yogafan_config xiaoxin_8bit_dual_cfg = {
> + .multiplier = 100,
> + .fan_count = 2,
> + .paths = { "\\_SB.PCI0.LPC0.EC0.FANS", "\\_SB.PCI0.LPC0.EC0.FA2S" }
> +};
> +
> +static const struct yogafan_config yoga_pro_7_14iah10_cfg = {
> + .multiplier = 100,
> + .fan_count = 1,
> + .paths = { "\\_SB.PC00.LPCB.EC0.FANS", NULL }
> +};
> +
> static void apply_rllag_filter(struct yoga_fan_data *data, int idx, long raw_rpm)
> {
[Severity: High]
Does the MIN_SAMPLING rate limit effectively prevent excessive ACPI queries?
Looking at yoga_fan_read(), it appears the expensive ACPI evaluation happens
unconditionally before the filter is applied:
drivers/hwmon/yogafan.c:yoga_fan_read() {
...
status = acpi_evaluate_integer(data->active_handles[channel], NULL, NULL, &raw_acpi);
if (ACPI_FAILURE(status))
return -EIO;
apply_rllag_filter(data, channel, (long)raw_acpi * data->multiplier);
...
}
Even though apply_rllag_filter() skips math updates when dt_ms < MIN_SAMPLING,
the hardware ACPI query has already been executed.
Since the sysfs fanX_input file has 0444 permissions, could an unprivileged
local user continuously read it in a tight loop and cause an EC saturation,
leading to system stalls and keyboard/mouse lag?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260803184206.18465-1-sergiomelas@gmail.com?part=1
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [PATCH v12] hwmon: (yogafan) Add support for Lenovo Yoga/Legion fan monitoring
2026-08-03 18:42 [PATCH v12] hwmon: (yogafan) Add support for Lenovo Yoga/Legion fan monitoring Sergio Melas
2026-08-03 19:04 ` sashiko-bot
@ 2026-08-05 21:42 ` Guenter Roeck
1 sibling, 0 replies; 3+ messages in thread
From: Guenter Roeck @ 2026-08-05 21:42 UTC (permalink / raw)
To: Sergio Melas; +Cc: linux-hwmon, linux-kernel
On 8/3/26 11:42, Sergio Melas wrote:
> This driver provides fan speed monitoring for modern Lenovo consumer
> laptops by interfacing with the Embedded Controller (EC) via ACPI.
>
Wording (imperative mood required). Also, the above (including the subject)
is not what this patch is doing. You are supposed to describe what the patch
does, and why the change is needed, not the driver functionality.
Why is this v12 anyway ? The driver has long since been applied to the
upstream kernel. Keeping the entire history is just confusing and annoying,
and makes it all but impossible to determine if this is really a new
version of a follow-up patch to the upstream driver or a first-time
submission.
> To address low-resolution sampling in Lenovo EC firmware, a Rate-Limited
> Lag (RLLag) filter is implemented. The filter ensures a consistent physical
> curve regardless of userspace polling frequency.
>
That filter is already implemented and not added here.
> Hardware identification is performed via DMI-based quirk tables, which
> map specific ACPI object paths and register widths (8-bit vs 16-bit)
> deterministically. This patch introduces specific quirks for the Lenovo
> LOQ 15IAX9, IdeaPad 3 15ALC6, Legion Pro 7 16AFR10H, Yoga Pro 7 14IAH10,
> and Yoga 7 16ARP8.
>
The above has little to do with the actual patch, which improves support
for existing models. Again, please describe (in imperative mood) what the
patch is doing and why.
> Signed-off-by: Sergio Melas <sergiomelas@gmail.com>
Not sure I understand what Sashiko's feedback has to do with this patch.
Maybe it gets confused with the patch description. Feel free to ignore
its feedback (and any change would have to be a separate patch anyway).
Please either drop the whitespace changes, or provide a rationale for making
them. Also, drop the comment enumeration at "Particular first" and "Generic
Family Fallbacks LAST" as well as the "LAST" since that is obvious.
Thanks,
Guenter
> ---
> v12:
> - Reordered yogafan_quirks table so exact model matches are evaluated
> before generic family fallbacks, preventing DMI shadowing.
> - Added support and proper DMI/ACPI mappings for Lenovo LOQ 15IAX9,
> IdeaPad 3 15ALC6, Legion Pro 7 16AFR10H, Yoga Pro 7 14IAH10, and
> Yoga 7 16ARP8 (with thanks to community DSDT contributors).
> - Updated Documentation/hwmon/yogafan.rst reference database and credits.
> v11.1:
> - Fixed Documentation formatting (0-day robot warnings).
> - Fixed yogafan.c header comment
> v11:
> - Mapped ACPI paths directly via DMI quirks.
> - Fixed Documentation formatting (0-day robot warnings).
> - Implemented 100ms MIN_SAMPLING to address rapid polling concerns.
> - Removed redundant platform_set_drvdata() in probe.
> - Explicitly defined platform device ID as -1 for cleaner sysfs naming.
> v9/10:
> - Implement ACPI handle resolution during probe for better performance (O(1) read).
> - Add MODULE_DEVICE_TABLE(dmi, ...) to enable module autoloading.
> - Refine RLLag filter documentation and suspend/resume logic.
> - Include comprehensive EC architecture research database (8-bit vs 16-bit).
> - Validated efficiency on kernels 6.18, 6.19, and 7.0-rc5: 'perf top'
> confirms negligible CPU overhead (<0.01%) during active polling.
> v8:
> - Replaced heuristic multiplier with deterministic DMI Quirk Table.
> - Added 'depends on DMI' to Kconfig.
> - Verified FOPTD model (1000ms TAU / 1500 RPM/s slew) against hardware traces.
> - Increased filter precision to 12-bit fixed-point.
> v7:
> - Fixed Kconfig: Removed non-existent 'select MATH64'.
> - Fixed unused macro: Utilized RPM_FLOOR_LIMIT to implement an
> immediate 0-RPM bypass in the filter.
> - Clarification: Previous "unified structure" comment meant that all
> 6 files (driver, docs, metadata) are now in this single atomic patch.
> v6:
> - Unified patch structure (6 files changed).
> - Verified FOPTD (First-Order Plus Time Delay) model against hardware
> traces (Yoga 14c) to ensure physical accuracy of the 1000ms time constant.
> - Fixed a rounding stall: added a +/- 1 RPM floor to the step calculation
> to ensure convergence even at high polling frequencies.
> - Set MAX_SLEW_RPM_S to 1500 to match physical motor inertia.
> - Documentation: Updated to clarify 100-RPM hardware step resolution.
> - 32-bit safety: Implemented div64_s64 for coefficient precision.
> v5:
> - Fixed 32-bit build failures by using div64_s64 for 64-bit division.
> - Extracted magic numbers into constants (RPM_UNIT_THRESHOLD, etc.).
> - Fixed filter stall by ensuring a minimum slew limit (limit = 1).
> - Refined RPM floor logic to trigger only when hardware reports 0 RPM.
> - Resolved 255/256 unit-jump bug by adjusting heuristic thresholds.
> v4:
> - Rebased on groeck/hwmon-next branch for clean application.
> - Corrected alphabetical sorting in Kconfig and Makefile.
> - Technical Validation & FOPTD Verification:
> - Implemented RLLag (Rate-Limited Lag) first-order modeling.
> - Used 10-bit fixed-point math for alpha calculation to avoid
> floating point overhead in the kernel.
> - Added 5000ms filter reset for resume/long-polling sanitation.
> v3:
> - Added MAINTAINERS entry and full Documentation/hwmon/yogafan.rst.
> - Fixed integer overflow in filter math.
> - Added support for secondary fan paths (FA2S) for Legion laptops.
> v2:
> - Migrated from background worker to passive multirate filtering.
> - Implemented dt-based scaling to maximize CPU sleep states.
> - Restricted driver to Lenovo hardware via DMI matching.
> v1:
> - Initial submission with basic ACPI fan path support.
> ---
> ---
> Documentation/hwmon/yogafan.rst | 27 ++++++++++++-
> drivers/hwmon/yogafan.c | 71 +++++++++++++++++++++++++++++----
> 2 files changed, 89 insertions(+), 9 deletions(-)
>
> diff --git a/Documentation/hwmon/yogafan.rst b/Documentation/hwmon/yogafan.rst
> index 68761947a..6395c94f4 100644
> --- a/Documentation/hwmon/yogafan.rst
> +++ b/Documentation/hwmon/yogafan.rst
> @@ -99,6 +99,11 @@ immediately to ensure the user knows the fan has stopped.
> 82XV / 83DV | LOQ 15/16 | 0xFE/0xFF | \_SB.PCI0.LPC0.EC0.FANS /FA2S | 16-bit | 1
> 83AK | ThinkBook G6 | 0x06 | \_SB.PCI0.LPC0.EC0.FAN0 | 8-bit | 100
> 81X1 | Flex 5 | 0x06 | \_SB.PCI0.LPC0.EC0.FAN0 | 8-bit | 100
> + 83KF | XiaoXinPro 13ARE | 0x06/0xFE | \_SB.PCI0.LPC0.EC0.FANS/FA2S | 8-bit | 100
> + 82KU | IdeaPad 3 15ALC6 | 0x06 | \_SB.PCI0.LPC0.EC0.FAN0 | 8-bit | 100
> + 83RU | Legion Pro 7 16 | 0x03/0x06 | \_SB.PCI0.LPC0.EC0.FANS/FA2S | 8-bit | 100
> + 83KF | Yoga Pro 7 14IAH | 0x06 | \_SB.PC00.LPCB.EC0.FANS | 8-bit | 100
> + 83BS | Yoga 7 16ARP8 | 0x03/0x06 | \_SB.PCI0.LPC0.EC0.FANS/FA2S | 8-bit | 100
> *Legacy* | Pre-2020 Models | 0x06 | \_SB.PCI0.LPC.EC.FAN0 | 8-bit | 100
> ----------------------------------------------------------------------------------------------------
>
> @@ -117,7 +122,6 @@ METHODOLOGY & IDENTIFICATION:
> - 8-bit (Multiplier 100): Standard for Yoga/IdeaPad. Raw values (0-255).
> - 16-bit (Multiplier 1): Standard for Legion/LOQ. Two registers (0xFE/0xFF).
>
> -
> References
> ----------
>
> @@ -136,3 +140,24 @@ References
> 4. **Lenovo IdeaPad Laptop Driver:** Reference for DMI-based hardware
> feature gating in Lenovo laptops.
> https://github.com/torvalds/linux/blob/master/drivers/platform/x86/lenovo/ideapad-laptop.c
> +
> +5. **Lenovo Product Specifications Reference (PSREF):** Official hardware layout index
> + and spec sheets for active and withdrawn Lenovo laptop models.
> + https://psref.lenovo.com/l/withdrawn/
> +
> +6. **Yogafan Master Quirk Database:** Master spreadsheet mapping Lenovo Product
> + Specifications Reference (PSREF) to explicit EC offsets, register widths, paths, and multipliers.
> + https://github.com/sergiomelas/lenovo-linux-drivers/blob/main/Lenovo_Drivers/Prototype/PSREF/yogafan_v3_quirks_database.ods
> +
> +7. **Yogafan ACPI DSDT Repository:** Central repository containing user-contributed raw
> + and decompiled ACPI DSDT firmware dumps used for path verification and hardware expansions.
> + https://github.com/sergiomelas/lenovo-linux-drivers/tree/main/Lenovo_Drivers/Prototype/DSDT
> +
> +Contributors & DSDT Providers:
> +------------------------------
> +- **Sarbajit Sarkar** (Lenovo LOQ 15IAX9)
> +- **HinataKato** (XiaoXin Pro 13ARE 2020 - 83KF)
> +- **PenPenIsGod** (IdeaPad 3 15ALC6 - 82KU & Legion Pro 7 16AFR10H - 83RU)
> +- **unlockxiaom** (Legion Pro 7 16AFR10H - 83RU, Yoga Pro 7 14IAH10 - 83KF, ThinkCentre M80q)
> +- **Phani Pavan K** (Yoga Pro 7 14IAH10 - 83KF)
> +- **Splarkszter** (Yoga 7 16ARP8 - 83BS)
> diff --git a/drivers/hwmon/yogafan.c b/drivers/hwmon/yogafan.c
> index 0a41b8672..371e35895 100644
> --- a/drivers/hwmon/yogafan.c
> +++ b/drivers/hwmon/yogafan.c
> @@ -53,6 +53,7 @@ struct yoga_fan_data {
> };
>
> /* Specific configurations mapped via DMI */
> +
> static const struct yogafan_config yoga_8bit_fans_cfg = {
> .multiplier = 100,
> .fan_count = 1,
> @@ -77,6 +78,18 @@ static const struct yogafan_config loq_15iax9_8bit_dual_cfg = {
> .paths = { "\\_SB.PC00.LPCB.EC0.FA1S", "\\_SB.PC00.LPCB.EC0.FA2S" }
> };
>
> +static const struct yogafan_config xiaoxin_8bit_dual_cfg = {
> + .multiplier = 100,
> + .fan_count = 2,
> + .paths = { "\\_SB.PCI0.LPC0.EC0.FANS", "\\_SB.PCI0.LPC0.EC0.FA2S" }
> +};
> +
> +static const struct yogafan_config yoga_pro_7_14iah10_cfg = {
> + .multiplier = 100,
> + .fan_count = 1,
> + .paths = { "\\_SB.PC00.LPCB.EC0.FANS", NULL }
> +};
> +
> static void apply_rllag_filter(struct yoga_fan_data *data, int idx, long raw_rpm)
> {
> ktime_t now = ktime_get_boottime();
> @@ -176,6 +189,56 @@ static const struct hwmon_chip_info yoga_fan_chip_info = {
> };
>
> static const struct dmi_system_id yogafan_quirks[] = {
> + /* 1. Particular first */
> + {
> + .ident = "Lenovo LOQ 15IAX9",
> + .matches = {
> + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
> + DMI_MATCH(DMI_PRODUCT_FAMILY, "LOQ 15IAX9"),
> + },
> + .driver_data = (void *)&loq_15iax9_8bit_dual_cfg,
> + },
> + {
> + .ident = "Lenovo XiaoXin Pro 13ARE 2020",
> + .matches = {
> + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
> + DMI_MATCH(DMI_PRODUCT_FAMILY, "XiaoXinPro-13ARE 2020"),
> + },
> + .driver_data = (void *)&xiaoxin_8bit_dual_cfg,
> + },
> + {
> + .ident = "Lenovo IdeaPad 3 15ALC6",
> + .matches = {
> + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
> + DMI_MATCH(DMI_PRODUCT_FAMILY, "IdeaPad 3 15ALC6"),
> + },
> + .driver_data = (void *)&ideapad_8bit_fan0_cfg,
> + },
> + {
> + .ident = "Lenovo Legion Pro 7 16AFR10H",
> + .matches = {
> + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
> + DMI_MATCH(DMI_PRODUCT_FAMILY, "Legion Pro 7 16AFR10H"),
> + },
> + .driver_data = (void *)&xiaoxin_8bit_dual_cfg,
> + },
> + {
> + .ident = "Lenovo Yoga Pro 7 14IAH10",
> + .matches = {
> + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
> + DMI_MATCH(DMI_PRODUCT_FAMILY, "Yoga Pro 7 14IAH10"),
> + },
> + .driver_data = (void *)&yoga_pro_7_14iah10_cfg,
> + },
> + {
> + .ident = "Lenovo Yoga 7 16ARP8",
> + .matches = {
> + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
> + DMI_MATCH(DMI_PRODUCT_FAMILY, "Yoga 7 16ARP8"),
> + },
> + .driver_data = (void *)&xiaoxin_8bit_dual_cfg,
> + },
> + /* 2. Generic Family Fallbacks LAST */
> {
> .ident = "Lenovo Yoga",
> .matches = {
> @@ -200,14 +263,6 @@ static const struct dmi_system_id yogafan_quirks[] = {
> },
> .driver_data = (void *)&ideapad_8bit_fan0_cfg,
> },
> - {
> - .ident = "Lenovo LOQ 15IAX9",
> - .matches = {
> - DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
> - DMI_MATCH(DMI_PRODUCT_FAMILY, "LOQ 15IAX9"),
> - },
> - .driver_data = (void *)&loq_15iax9_8bit_dual_cfg,
> - },
> { }
> };
> MODULE_DEVICE_TABLE(dmi, yogafan_quirks);
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-08-05 21:42 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-03 18:42 [PATCH v12] hwmon: (yogafan) Add support for Lenovo Yoga/Legion fan monitoring Sergio Melas
2026-08-03 19:04 ` sashiko-bot
2026-08-05 21:42 ` Guenter Roeck
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox