Update lenovo-legion-laptop.patch
This commit is contained in:
parent
8580833649
commit
1f88b2fc25
@ -1,14 +1,14 @@
|
|||||||
From cc20a3c74424b7fd78a650803bc06b822e8b1e56 Mon Sep 17 00:00:00 2001
|
From 26077d270f462eaf3da592ed047956df3436ed36 Mon Sep 17 00:00:00 2001
|
||||||
From: John Martens <john.martens4@proton.me>
|
From: John Martens <john.martens4@proton.me>
|
||||||
Date: Wed, 30 Aug 2023 15:42:09 +0000
|
Date: Fri, 29 Mar 2024 20:18:47 +0000
|
||||||
Subject: [PATCH] Add legion-laptop v0.0.7
|
Subject: [PATCH] Add legion-laptop v0.0.12
|
||||||
|
|
||||||
Add extra support for Lenovo Legion laptops.
|
Add extra support for Lenovo Legion laptops.
|
||||||
---
|
---
|
||||||
drivers/platform/x86/Kconfig | 10 +
|
drivers/platform/x86/Kconfig | 10 +
|
||||||
drivers/platform/x86/Makefile | 1 +
|
drivers/platform/x86/Makefile | 1 +
|
||||||
drivers/platform/x86/legion-laptop.c | 5858 ++++++++++++++++++++++++++
|
drivers/platform/x86/legion-laptop.c | 6089 ++++++++++++++++++++++++++
|
||||||
3 files changed, 5869 insertions(+)
|
3 files changed, 6100 insertions(+)
|
||||||
create mode 100644 drivers/platform/x86/legion-laptop.c
|
create mode 100644 drivers/platform/x86/legion-laptop.c
|
||||||
|
|
||||||
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
|
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
|
||||||
@ -46,10 +46,10 @@ index 52dfdf574..5f32dd9df 100644
|
|||||||
# Intel
|
# Intel
|
||||||
diff --git a/drivers/platform/x86/legion-laptop.c b/drivers/platform/x86/legion-laptop.c
|
diff --git a/drivers/platform/x86/legion-laptop.c b/drivers/platform/x86/legion-laptop.c
|
||||||
new file mode 100644
|
new file mode 100644
|
||||||
index 000000000..727510507
|
index 000000000..5ec0a518f
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/drivers/platform/x86/legion-laptop.c
|
+++ b/drivers/platform/x86/legion-laptop.c
|
||||||
@@ -0,0 +1,5858 @@
|
@@ -0,0 +1,6089 @@
|
||||||
+// SPDX-License-Identifier: GPL-2.0-or-later
|
+// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
+/*
|
+/*
|
||||||
+ * legion-laptop.c - Extra Lenovo Legion laptop support, in
|
+ * legion-laptop.c - Extra Lenovo Legion laptop support, in
|
||||||
@ -64,14 +64,14 @@ index 000000000..727510507
|
|||||||
+ * data doesn't match the model AND FIRMWARE.
|
+ * data doesn't match the model AND FIRMWARE.
|
||||||
+ *
|
+ *
|
||||||
+ * Support for other hardware of this model is already partially
|
+ * Support for other hardware of this model is already partially
|
||||||
+ * provided by the module ideapd-laptop.
|
+ * provided by the module ideapad-laptop.
|
||||||
+ *
|
+ *
|
||||||
+ * The development page for this driver is located at
|
+ * The development page for this driver is located at
|
||||||
+ * https://github.com/johnfanv2/LenovoLegionLinux
|
+ * https://github.com/johnfanv2/LenovoLegionLinux
|
||||||
+ *
|
+ *
|
||||||
+ * This driver exports the files:
|
+ * This driver exports the files:
|
||||||
+ * - /sys/kernel/debug/legion/fancurve (ro)
|
+ * - /sys/kernel/debug/legion/fancurve (ro)
|
||||||
+ * The fan curve in the form stored in the firmware in an
|
+ * The fan curve stored in the firmware in the form of a
|
||||||
+ * human readable table.
|
+ * human readable table.
|
||||||
+ *
|
+ *
|
||||||
+ * - /sys/module/legion_laptop/drivers/platform\:legion/PNP0C09\:00/powermode (rw)
|
+ * - /sys/module/legion_laptop/drivers/platform\:legion/PNP0C09\:00/powermode (rw)
|
||||||
@ -176,13 +176,13 @@ index 000000000..727510507
|
|||||||
+ * to part of it (first 0xFF bytes?)
|
+ * to part of it (first 0xFF bytes?)
|
||||||
+ *
|
+ *
|
||||||
+ * In later models the firmware directly exposes ACPI methods to
|
+ * In later models the firmware directly exposes ACPI methods to
|
||||||
+ * set the fan curve direclty, without writing to EC RAM. This
|
+ * set the fan curve directly, without writing to EC RAM. This
|
||||||
+ * is done inside the ACPI method.
|
+ * is done inside the ACPI method.
|
||||||
+ */
|
+ */
|
||||||
+
|
+
|
||||||
+/**
|
+/**
|
||||||
+ * Offsets for interseting values inside the EC RAM (0 = start of
|
+ * Offsets for interesting values inside the EC RAM (0 = start of
|
||||||
+ * EC RAM. These might change depending on the software inside of
|
+ * EC RAM) These might change depending on the software inside of
|
||||||
+ * the EC, which can be updated by a BIOS update from Lenovo.
|
+ * the EC, which can be updated by a BIOS update from Lenovo.
|
||||||
+ */
|
+ */
|
||||||
+// TODO: same order as in initialization
|
+// TODO: same order as in initialization
|
||||||
@ -192,7 +192,7 @@ index 000000000..727510507
|
|||||||
+ // General Control (GCTRL)
|
+ // General Control (GCTRL)
|
||||||
+ // (see EC Interface Registers and 6.2 Plug and Play Configuration (PNPCFG)) in datasheet
|
+ // (see EC Interface Registers and 6.2 Plug and Play Configuration (PNPCFG)) in datasheet
|
||||||
+ // note: these are in two places saved
|
+ // note: these are in two places saved
|
||||||
+ // in EC Interface Registers and in super io configuraion registers
|
+ // in EC Interface Registers and in super io configuration registers
|
||||||
+ // Chip ID
|
+ // Chip ID
|
||||||
+ u16 ECHIPID1;
|
+ u16 ECHIPID1;
|
||||||
+ u16 ECHIPID2;
|
+ u16 ECHIPID2;
|
||||||
@ -225,9 +225,9 @@ index 000000000..727510507
|
|||||||
+ u16 EXT_POWERMODE;
|
+ u16 EXT_POWERMODE;
|
||||||
+ u16 EXT_MINIFANCURVE_ON_COOL;
|
+ u16 EXT_MINIFANCURVE_ON_COOL;
|
||||||
+ // values
|
+ // values
|
||||||
+ // 0x04: enable mini fan curve if very long on cool level
|
+ // 0x04: enable mini fan curve if left for too long on cool level
|
||||||
+ // - this might be due to potential temp failure
|
+ // - this might be due to potential temp failure
|
||||||
+ // - or just because really so cool
|
+ // - or just because of really cool temps
|
||||||
+ // 0xA0: disable it
|
+ // 0xA0: disable it
|
||||||
+ u16 EXT_LOCKFANCONTROLLER;
|
+ u16 EXT_LOCKFANCONTROLLER;
|
||||||
+ u16 EXT_MAXIMUMFANSPEED;
|
+ u16 EXT_MAXIMUMFANSPEED;
|
||||||
@ -245,6 +245,7 @@ index 000000000..727510507
|
|||||||
+ ACCESS_METHOD_WMI2 = 4,
|
+ ACCESS_METHOD_WMI2 = 4,
|
||||||
+ ACCESS_METHOD_WMI3 = 5,
|
+ ACCESS_METHOD_WMI3 = 5,
|
||||||
+ ACCESS_METHOD_EC2 = 10, // ideapad fancurve method
|
+ ACCESS_METHOD_EC2 = 10, // ideapad fancurve method
|
||||||
|
+ ACCESS_METHOD_EC3 = 11, // loq
|
||||||
+};
|
+};
|
||||||
+
|
+
|
||||||
+struct model_config {
|
+struct model_config {
|
||||||
@ -413,6 +414,39 @@ index 000000000..727510507
|
|||||||
+ .EXT_WHITE_KEYBOARD_BACKLIGHT = 0xC5a0 // not found yet
|
+ .EXT_WHITE_KEYBOARD_BACKLIGHT = 0xC5a0 // not found yet
|
||||||
+};
|
+};
|
||||||
+
|
+
|
||||||
|
+static const struct ec_register_offsets ec_register_offsets_loq_v0 = {
|
||||||
|
+ .ECHIPID1 = 0x2000,
|
||||||
|
+ .ECHIPID2 = 0x2001,
|
||||||
|
+ .ECHIPVER = 0x2002,
|
||||||
|
+ .ECDEBUG = 0x2003,
|
||||||
|
+ .EXT_FAN_CUR_POINT = 0xC5a0,
|
||||||
|
+ .EXT_FAN_POINTS_SIZE = 0xC5a0, // constant 0
|
||||||
|
+ .EXT_FAN1_BASE = 0xC530,
|
||||||
|
+ .EXT_FAN2_BASE = 0xC530, // same rpm as cpu
|
||||||
|
+ .EXT_FAN_ACC_BASE = 0xC5a0, // not found yet
|
||||||
|
+ .EXT_FAN_DEC_BASE = 0xC5a0, // not found yet
|
||||||
|
+ .EXT_CPU_TEMP = 0xC52F,
|
||||||
|
+ .EXT_CPU_TEMP_HYST = 0xC5a0, // not found yet
|
||||||
|
+ .EXT_GPU_TEMP = 0xC531,
|
||||||
|
+ .EXT_GPU_TEMP_HYST = 0xC5a0, // not found yet
|
||||||
|
+ .EXT_VRM_TEMP = 0xC5a0, // not found yet
|
||||||
|
+ .EXT_VRM_TEMP_HYST = 0xC5a0, // not found yet
|
||||||
|
+ .EXT_FAN1_RPM_LSB = 0xC5a0, // not found yet
|
||||||
|
+ .EXT_FAN1_RPM_MSB = 0xC5a0, // not found yet
|
||||||
|
+ .EXT_FAN2_RPM_LSB = 0xC5a0, // not found yet
|
||||||
|
+ .EXT_FAN2_RPM_MSB = 0xC5a0, // not found yet
|
||||||
|
+ .EXT_MINIFANCURVE_ON_COOL = 0xC5a0, // not found yet
|
||||||
|
+ .EXT_LOCKFANCONTROLLER = 0xC5a0, // not found yet
|
||||||
|
+ .EXT_CPU_TEMP_INPUT = 0xC5a0, // not found yet
|
||||||
|
+ .EXT_GPU_TEMP_INPUT = 0xC5a0, // not found yet
|
||||||
|
+ .EXT_IC_TEMP_INPUT = 0xC5a0, // not found yet
|
||||||
|
+ .EXT_POWERMODE = 0xc41D,
|
||||||
|
+ .EXT_FAN1_TARGET_RPM = 0xC5a0, // not found yet
|
||||||
|
+ .EXT_FAN2_TARGET_RPM = 0xC5a0, // not found yet
|
||||||
|
+ .EXT_MAXIMUMFANSPEED = 0xC5a0, // not found yet
|
||||||
|
+ .EXT_WHITE_KEYBOARD_BACKLIGHT = 0xC5a0 // not found yet
|
||||||
|
+};
|
||||||
|
+
|
||||||
+static const struct model_config model_v0 = {
|
+static const struct model_config model_v0 = {
|
||||||
+ .registers = &ec_register_offsets_v0,
|
+ .registers = &ec_register_offsets_v0,
|
||||||
+ .check_embedded_controller_id = true,
|
+ .check_embedded_controller_id = true,
|
||||||
@ -565,13 +599,70 @@ index 000000000..727510507
|
|||||||
+ .ramio_size = 0x600
|
+ .ramio_size = 0x600
|
||||||
+};
|
+};
|
||||||
+
|
+
|
||||||
|
+static const struct model_config model_m0cn = {
|
||||||
|
+ .registers = &ec_register_offsets_v0,
|
||||||
|
+ .check_embedded_controller_id = true,
|
||||||
|
+ .embedded_controller_id = 0x5507,
|
||||||
|
+ .memoryio_physical_ec_start = 0xC400,
|
||||||
|
+ .memoryio_size = 0x300,
|
||||||
|
+ .has_minifancurve = true,
|
||||||
|
+ .has_custom_powermode = true,
|
||||||
|
+ .access_method_powermode = ACCESS_METHOD_WMI,
|
||||||
|
+ .access_method_keyboard = ACCESS_METHOD_WMI,
|
||||||
|
+ .access_method_fanspeed = ACCESS_METHOD_WMI3,
|
||||||
|
+ .access_method_temperature = ACCESS_METHOD_WMI3,
|
||||||
|
+ .access_method_fancurve = ACCESS_METHOD_WMI3,
|
||||||
|
+ .access_method_fanfullspeed = ACCESS_METHOD_WMI,
|
||||||
|
+ .acpi_check_dev = false,
|
||||||
|
+ .ramio_physical_start = 0xFE0B0400,
|
||||||
|
+ .ramio_size = 0x600
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static const struct model_config model_m1cn = {
|
||||||
|
+ .registers = &ec_register_offsets_v0,
|
||||||
|
+ .check_embedded_controller_id = true,
|
||||||
|
+ .embedded_controller_id = 0x5507,
|
||||||
|
+ .memoryio_physical_ec_start = 0xC400,
|
||||||
|
+ .memoryio_size = 0x300,
|
||||||
|
+ .has_minifancurve = true,
|
||||||
|
+ .has_custom_powermode = true,
|
||||||
|
+ .access_method_powermode = ACCESS_METHOD_WMI,
|
||||||
|
+ .access_method_keyboard = ACCESS_METHOD_WMI,
|
||||||
|
+ .access_method_fanspeed = ACCESS_METHOD_WMI3,
|
||||||
|
+ .access_method_temperature = ACCESS_METHOD_WMI3,
|
||||||
|
+ .access_method_fancurve = ACCESS_METHOD_WMI3,
|
||||||
|
+ .access_method_fanfullspeed = ACCESS_METHOD_WMI,
|
||||||
|
+ .acpi_check_dev = false,
|
||||||
|
+ .ramio_physical_start = 0xFE0B0400,
|
||||||
|
+ .ramio_size = 0x600
|
||||||
|
+};
|
||||||
|
+
|
||||||
+static const struct model_config model_m2cn = {
|
+static const struct model_config model_m2cn = {
|
||||||
+ .registers = &ec_register_offsets_v0,
|
+ .registers = &ec_register_offsets_v0,
|
||||||
+ .check_embedded_controller_id = true,
|
+ .check_embedded_controller_id = true,
|
||||||
+ .embedded_controller_id = 0x8227,
|
+ .embedded_controller_id = 0x8227,
|
||||||
+ .memoryio_physical_ec_start = 0xC400,
|
+ .memoryio_physical_ec_start = 0xC400,
|
||||||
+ .memoryio_size = 0x300,
|
+ .memoryio_size = 0x300,
|
||||||
+ .has_minifancurve = false,
|
+ .has_minifancurve = true,
|
||||||
|
+ .has_custom_powermode = true,
|
||||||
|
+ .access_method_powermode = ACCESS_METHOD_WMI,
|
||||||
|
+ .access_method_keyboard = ACCESS_METHOD_WMI,
|
||||||
|
+ .access_method_fanspeed = ACCESS_METHOD_WMI3,
|
||||||
|
+ .access_method_temperature = ACCESS_METHOD_WMI3,
|
||||||
|
+ .access_method_fancurve = ACCESS_METHOD_WMI3,
|
||||||
|
+ .access_method_fanfullspeed = ACCESS_METHOD_WMI,
|
||||||
|
+ .acpi_check_dev = false,
|
||||||
|
+ .ramio_physical_start = 0xFE0B0400,
|
||||||
|
+ .ramio_size = 0x600
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static const struct model_config model_m6cn = {
|
||||||
|
+ .registers = &ec_register_offsets_v0,
|
||||||
|
+ .check_embedded_controller_id = true,
|
||||||
|
+ .embedded_controller_id = 0x8227,
|
||||||
|
+ .memoryio_physical_ec_start = 0xC400,
|
||||||
|
+ .memoryio_size = 0x300,
|
||||||
|
+ .has_minifancurve = true,
|
||||||
+ .has_custom_powermode = true,
|
+ .has_custom_powermode = true,
|
||||||
+ .access_method_powermode = ACCESS_METHOD_WMI,
|
+ .access_method_powermode = ACCESS_METHOD_WMI,
|
||||||
+ .access_method_keyboard = ACCESS_METHOD_WMI,
|
+ .access_method_keyboard = ACCESS_METHOD_WMI,
|
||||||
@ -863,14 +954,33 @@ index 000000000..727510507
|
|||||||
+ .ramio_size = 0x600
|
+ .ramio_size = 0x600
|
||||||
+};
|
+};
|
||||||
+
|
+
|
||||||
|
+// LOQ Model
|
||||||
|
+static const struct model_config model_lzcn = {
|
||||||
|
+ .registers = &ec_register_offsets_loq_v0,
|
||||||
|
+ .check_embedded_controller_id = true,
|
||||||
|
+ .embedded_controller_id = 0x8227,
|
||||||
|
+ .memoryio_physical_ec_start = 0xC400,
|
||||||
|
+ .memoryio_size = 0x300,
|
||||||
|
+ .has_minifancurve = true,
|
||||||
|
+ .has_custom_powermode = true,
|
||||||
|
+ .access_method_powermode = ACCESS_METHOD_WMI,
|
||||||
|
+ .access_method_keyboard = ACCESS_METHOD_WMI2,
|
||||||
|
+ .access_method_fanspeed = ACCESS_METHOD_WMI3,
|
||||||
|
+ .access_method_temperature = ACCESS_METHOD_WMI3,
|
||||||
|
+ .access_method_fancurve = ACCESS_METHOD_EC3,
|
||||||
|
+ .access_method_fanfullspeed = ACCESS_METHOD_WMI3,
|
||||||
|
+ .acpi_check_dev = false,
|
||||||
|
+ .ramio_physical_start = 0xFE0B0400,
|
||||||
|
+ .ramio_size = 0x600
|
||||||
|
+};
|
||||||
+
|
+
|
||||||
+static const struct dmi_system_id denylist[] = { {} };
|
+static const struct dmi_system_id denylist[] = { {} };
|
||||||
+
|
+
|
||||||
+static const struct dmi_system_id optimistic_allowlist[] = {
|
+static const struct dmi_system_id optimistic_allowlist[] = {
|
||||||
+ {
|
+ {
|
||||||
+ // modelyear: 2021
|
+ // Release year: 2021
|
||||||
+ // generation: 6
|
+ // Generation: 6
|
||||||
+ // name: Legion 5, Legion 5 pro, Legion 7
|
+ // Name: Legion 5, Legion 5 pro, Legion 7
|
||||||
+ // Family: Legion 5 15ACH6H, ...
|
+ // Family: Legion 5 15ACH6H, ...
|
||||||
+ .ident = "GKCN",
|
+ .ident = "GKCN",
|
||||||
+ .matches = {
|
+ .matches = {
|
||||||
@ -880,7 +990,7 @@ index 000000000..727510507
|
|||||||
+ .driver_data = (void *)&model_v0
|
+ .driver_data = (void *)&model_v0
|
||||||
+ },
|
+ },
|
||||||
+ {
|
+ {
|
||||||
+ // modelyear: 2020
|
+ // Release year: 2020
|
||||||
+ .ident = "EUCN",
|
+ .ident = "EUCN",
|
||||||
+ .matches = {
|
+ .matches = {
|
||||||
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||||
@ -889,7 +999,7 @@ index 000000000..727510507
|
|||||||
+ .driver_data = (void *)&model_eucn
|
+ .driver_data = (void *)&model_eucn
|
||||||
+ },
|
+ },
|
||||||
+ {
|
+ {
|
||||||
+ // modelyear: 2020
|
+ // Release year: 2020
|
||||||
+ .ident = "EFCN",
|
+ .ident = "EFCN",
|
||||||
+ .matches = {
|
+ .matches = {
|
||||||
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||||
@ -898,7 +1008,7 @@ index 000000000..727510507
|
|||||||
+ .driver_data = (void *)&model_v0
|
+ .driver_data = (void *)&model_v0
|
||||||
+ },
|
+ },
|
||||||
+ {
|
+ {
|
||||||
+ // modelyear: 2020
|
+ // Release year: 2020
|
||||||
+ .ident = "FSCN",
|
+ .ident = "FSCN",
|
||||||
+ .matches = {
|
+ .matches = {
|
||||||
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||||
@ -907,7 +1017,7 @@ index 000000000..727510507
|
|||||||
+ .driver_data = (void *)&model_v0
|
+ .driver_data = (void *)&model_v0
|
||||||
+ },
|
+ },
|
||||||
+ {
|
+ {
|
||||||
+ // modelyear: 2021
|
+ // Release year: 2021
|
||||||
+ .ident = "HHCN",
|
+ .ident = "HHCN",
|
||||||
+ .matches = {
|
+ .matches = {
|
||||||
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||||
@ -916,7 +1026,7 @@ index 000000000..727510507
|
|||||||
+ .driver_data = (void *)&model_v0
|
+ .driver_data = (void *)&model_v0
|
||||||
+ },
|
+ },
|
||||||
+ {
|
+ {
|
||||||
+ // modelyear: 2022
|
+ // Release year: 2022
|
||||||
+ .ident = "H1CN",
|
+ .ident = "H1CN",
|
||||||
+ .matches = {
|
+ .matches = {
|
||||||
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||||
@ -925,7 +1035,7 @@ index 000000000..727510507
|
|||||||
+ .driver_data = (void *)&model_v0
|
+ .driver_data = (void *)&model_v0
|
||||||
+ },
|
+ },
|
||||||
+ {
|
+ {
|
||||||
+ // modelyear: 2022
|
+ // Release year: 2022
|
||||||
+ .ident = "J2CN",
|
+ .ident = "J2CN",
|
||||||
+ .matches = {
|
+ .matches = {
|
||||||
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||||
@ -934,7 +1044,7 @@ index 000000000..727510507
|
|||||||
+ .driver_data = (void *)&model_v0
|
+ .driver_data = (void *)&model_v0
|
||||||
+ },
|
+ },
|
||||||
+ {
|
+ {
|
||||||
+ // modelyear: 2022
|
+ // Release year: 2022
|
||||||
+ .ident = "JUCN",
|
+ .ident = "JUCN",
|
||||||
+ .matches = {
|
+ .matches = {
|
||||||
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||||
@ -943,7 +1053,7 @@ index 000000000..727510507
|
|||||||
+ .driver_data = (void *)&model_v0
|
+ .driver_data = (void *)&model_v0
|
||||||
+ },
|
+ },
|
||||||
+ {
|
+ {
|
||||||
+ // modelyear: 2022
|
+ // Release year: 2022
|
||||||
+ .ident = "KFCN",
|
+ .ident = "KFCN",
|
||||||
+ .matches = {
|
+ .matches = {
|
||||||
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||||
@ -952,7 +1062,7 @@ index 000000000..727510507
|
|||||||
+ .driver_data = (void *)&model_kfcn
|
+ .driver_data = (void *)&model_kfcn
|
||||||
+ },
|
+ },
|
||||||
+ {
|
+ {
|
||||||
+ // modelyear: 2021
|
+ // Release year: 2021
|
||||||
+ .ident = "HACN",
|
+ .ident = "HACN",
|
||||||
+ .matches = {
|
+ .matches = {
|
||||||
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||||
@ -961,7 +1071,7 @@ index 000000000..727510507
|
|||||||
+ .driver_data = (void *)&model_hacn
|
+ .driver_data = (void *)&model_hacn
|
||||||
+ },
|
+ },
|
||||||
+ {
|
+ {
|
||||||
+ // modelyear: 2021
|
+ // Release year: 2021
|
||||||
+ .ident = "G9CN",
|
+ .ident = "G9CN",
|
||||||
+ .matches = {
|
+ .matches = {
|
||||||
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||||
@ -970,7 +1080,7 @@ index 000000000..727510507
|
|||||||
+ .driver_data = (void *)&model_v0
|
+ .driver_data = (void *)&model_v0
|
||||||
+ },
|
+ },
|
||||||
+ {
|
+ {
|
||||||
+ // modelyear: 2022
|
+ // Release year: 2022
|
||||||
+ .ident = "K9CN",
|
+ .ident = "K9CN",
|
||||||
+ .matches = {
|
+ .matches = {
|
||||||
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||||
@ -988,6 +1098,15 @@ index 000000000..727510507
|
|||||||
+ .driver_data = (void *)&model_fccn
|
+ .driver_data = (void *)&model_fccn
|
||||||
+ },
|
+ },
|
||||||
+ {
|
+ {
|
||||||
|
+ // e.g. IdeaPad Gaming 3 15ARH05 (8K21)
|
||||||
|
+ .ident = "H4CN",
|
||||||
|
+ .matches = {
|
||||||
|
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||||
|
+ DMI_MATCH(DMI_BIOS_VERSION, "H4CN"),
|
||||||
|
+ },
|
||||||
|
+ .driver_data = (void *)&model_fccn
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
+ // e.g. Ideapad Gaming 3 15ACH6
|
+ // e.g. Ideapad Gaming 3 15ACH6
|
||||||
+ .ident = "H3CN",
|
+ .ident = "H3CN",
|
||||||
+ .matches = {
|
+ .matches = {
|
||||||
@ -1123,6 +1242,24 @@ index 000000000..727510507
|
|||||||
+ .driver_data = (void *)&model_j1cn
|
+ .driver_data = (void *)&model_j1cn
|
||||||
+ },
|
+ },
|
||||||
+ {
|
+ {
|
||||||
|
+ // e.g. Legion Slim 7 16IRH8 (2023) with RTX 4070
|
||||||
|
+ .ident = "M0CN",
|
||||||
|
+ .matches = {
|
||||||
|
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||||
|
+ DMI_MATCH(DMI_BIOS_VERSION, "M0CN"),
|
||||||
|
+ },
|
||||||
|
+ .driver_data = (void *)&model_m0cn
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ // e.g. Legion Slim 7 16IRH8 (2023) AMD Ryzen 7 7840HS with RTX 4060
|
||||||
|
+ .ident = "M1CN",
|
||||||
|
+ .matches = {
|
||||||
|
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||||
|
+ DMI_MATCH(DMI_BIOS_VERSION, "M1CN"),
|
||||||
|
+ },
|
||||||
|
+ .driver_data = (void *)&model_m1cn
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
+ // e.g. Legion Slim 5 16IRH8 (2023) with RTX 4070
|
+ // e.g. Legion Slim 5 16IRH8 (2023) with RTX 4070
|
||||||
+ .ident = "M2CN",
|
+ .ident = "M2CN",
|
||||||
+ .matches = {
|
+ .matches = {
|
||||||
@ -1132,6 +1269,15 @@ index 000000000..727510507
|
|||||||
+ .driver_data = (void *)&model_m2cn
|
+ .driver_data = (void *)&model_m2cn
|
||||||
+ },
|
+ },
|
||||||
+ {
|
+ {
|
||||||
|
+ // e.g. Lenovo Yoga Slim 7 gen 8 (2023)
|
||||||
|
+ .ident = "M6CN",
|
||||||
|
+ .matches = {
|
||||||
|
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||||
|
+ DMI_MATCH(DMI_BIOS_VERSION, "M6CN"),
|
||||||
|
+ },
|
||||||
|
+ .driver_data = (void *)&model_m6cn
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
+ // e.g. Yoga Slim 7-14ARE05
|
+ // e.g. Yoga Slim 7-14ARE05
|
||||||
+ .ident = "DMCN",
|
+ .ident = "DMCN",
|
||||||
+ .matches = {
|
+ .matches = {
|
||||||
@ -1149,6 +1295,15 @@ index 000000000..727510507
|
|||||||
+ },
|
+ },
|
||||||
+ .driver_data = (void *)&model_khcn
|
+ .driver_data = (void *)&model_khcn
|
||||||
+ },
|
+ },
|
||||||
|
+ {
|
||||||
|
+ // e.g. LOQ 15IRH8
|
||||||
|
+ .ident = "LZCN",
|
||||||
|
+ .matches = {
|
||||||
|
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||||
|
+ DMI_MATCH(DMI_BIOS_VERSION, "LZCN"),
|
||||||
|
+ },
|
||||||
|
+ .driver_data = (void *)&model_lzcn
|
||||||
|
+ },
|
||||||
+ {}
|
+ {}
|
||||||
+};
|
+};
|
||||||
+
|
+
|
||||||
@ -1235,8 +1390,10 @@ index 000000000..727510507
|
|||||||
+ error = -AE_ERROR;
|
+ error = -AE_ERROR;
|
||||||
+ goto err;
|
+ goto err;
|
||||||
+ }
|
+ }
|
||||||
+ pr_info("ACPI result for %s:%d: ACPI buffer length: %u\n", id_name,
|
+
|
||||||
+ id_nr, out->buffer.length);
|
+// Reduced verbosity (only printing when ACPI result have bad parameters)
|
||||||
|
+// pr_info("ACPI result for %s:%d: ACPI buffer length: %u\n", id_name,
|
||||||
|
+// id_nr, out->buffer.length);
|
||||||
+
|
+
|
||||||
+ for (i = 0; i < ressize; ++i)
|
+ for (i = 0; i < ressize; ++i)
|
||||||
+ res[i] = out->buffer.pointer[i];
|
+ res[i] = out->buffer.pointer[i];
|
||||||
@ -1278,7 +1435,7 @@ index 000000000..727510507
|
|||||||
+{
|
+{
|
||||||
+ acpi_status status;
|
+ acpi_status status;
|
||||||
+ struct acpi_buffer out_buffer = { ACPI_ALLOCATE_BUFFER, NULL };
|
+ struct acpi_buffer out_buffer = { ACPI_ALLOCATE_BUFFER, NULL };
|
||||||
+ // seto to NULL call kfree on NULL if next function call fails
|
+ // set to NULL and call kfree on NULL if next function call fails
|
||||||
+ union acpi_object *out = NULL;
|
+ union acpi_object *out = NULL;
|
||||||
+ int error = 0;
|
+ int error = 0;
|
||||||
+
|
+
|
||||||
@ -1356,8 +1513,8 @@ index 000000000..727510507
|
|||||||
+#define WMI_METHOD_ID_ISSUPPORTGPUOC 4
|
+#define WMI_METHOD_ID_ISSUPPORTGPUOC 4
|
||||||
+
|
+
|
||||||
+// Fan speed
|
+// Fan speed
|
||||||
+// only completely implemented only for some models here
|
+// only fully implemented for some models here
|
||||||
+// often implemted also in other class and other method
|
+// often implemented in other classes and methods too
|
||||||
+// below
|
+// below
|
||||||
+#define WMI_METHOD_ID_GETFAN1SPEED 8
|
+#define WMI_METHOD_ID_GETFAN1SPEED 8
|
||||||
+#define WMI_METHOD_ID_GETFAN2SPEED 9
|
+#define WMI_METHOD_ID_GETFAN2SPEED 9
|
||||||
@ -1367,8 +1524,8 @@ index 000000000..727510507
|
|||||||
+// Does it support CPU overclock?
|
+// Does it support CPU overclock?
|
||||||
+#define WMI_METHOD_ID_ISSUPPORTCPUOC 14
|
+#define WMI_METHOD_ID_ISSUPPORTCPUOC 14
|
||||||
+// Temperatures
|
+// Temperatures
|
||||||
+// only completely implemented only for some models here
|
+// only fully implemented for some models here
|
||||||
+// often implemted also in other class and other method
|
+// often implemented in other classes and methods too
|
||||||
+// below
|
+// below
|
||||||
+#define WMI_METHOD_ID_GETCPUTEMP 18
|
+#define WMI_METHOD_ID_GETCPUTEMP 18
|
||||||
+#define WMI_METHOD_ID_GETGPUTEMP 19
|
+#define WMI_METHOD_ID_GETGPUTEMP 19
|
||||||
@ -1376,17 +1533,17 @@ index 000000000..727510507
|
|||||||
+// two state keyboard light
|
+// two state keyboard light
|
||||||
+#define WMI_METHOD_ID_GETKEYBOARDLIGHT 37
|
+#define WMI_METHOD_ID_GETKEYBOARDLIGHT 37
|
||||||
+#define WMI_METHOD_ID_SETKEYBOARDLIGHT 36
|
+#define WMI_METHOD_ID_SETKEYBOARDLIGHT 36
|
||||||
+// disable win key
|
+// toggle win key
|
||||||
+// 0 = win key enabled; 1 = win key disabled
|
+// 0 = win key enabled; 1 = win key disabled
|
||||||
+#define WMI_METHOD_ID_ISSUPPORTDISABLEWINKEY 21
|
+#define WMI_METHOD_ID_ISSUPPORTDISABLEWINKEY 21
|
||||||
+#define WMI_METHOD_ID_GETWINKEYSTATUS 23
|
+#define WMI_METHOD_ID_GETWINKEYSTATUS 23
|
||||||
+#define WMI_METHOD_ID_SETWINKEYSTATUS 22
|
+#define WMI_METHOD_ID_SETWINKEYSTATUS 22
|
||||||
+// disable touchpad
|
+// toggle touchpad
|
||||||
+//0 = touchpad enabled; 1 = touchpad disabled
|
+//0 = touchpad enabled; 1 = touchpad disabled
|
||||||
+#define WMI_METHOD_ID_ISSUPPORTDISABLETP 24
|
+#define WMI_METHOD_ID_ISSUPPORTDISABLETP 24
|
||||||
+#define WMI_METHOD_ID_GETTPSTATUS 26
|
+#define WMI_METHOD_ID_GETTPSTATUS 26
|
||||||
+#define WMI_METHOD_ID_SETTPSTATUS 25
|
+#define WMI_METHOD_ID_SETTPSTATUS 25
|
||||||
+// gSync
|
+// GSync
|
||||||
+#define WMI_METHOD_ID_ISSUPPORTGSYNC 40
|
+#define WMI_METHOD_ID_ISSUPPORTGSYNC 40
|
||||||
+#define WMI_METHOD_ID_GETGSYNCSTATUS 41
|
+#define WMI_METHOD_ID_GETGSYNCSTATUS 41
|
||||||
+#define WMI_METHOD_ID_SETGSYNCSTATUS 42
|
+#define WMI_METHOD_ID_SETGSYNCSTATUS 42
|
||||||
@ -1572,7 +1729,7 @@ index 000000000..727510507
|
|||||||
+ ec_memoryio->physical_start = physical_start;
|
+ ec_memoryio->physical_start = physical_start;
|
||||||
+ ec_memoryio->physical_ec_start = physical_ec_start;
|
+ ec_memoryio->physical_ec_start = physical_ec_start;
|
||||||
+ ec_memoryio->size = size;
|
+ ec_memoryio->size = size;
|
||||||
+ pr_info("Succeffuly mapped embedded controller: 0x%llx (in RAM)/0x%llx (in EC) to virtual 0x%p\n",
|
+ pr_info("Successfully mapped embedded controller: 0x%llx (in RAM)/0x%llx (in EC) to virtual 0x%p\n",
|
||||||
+ ec_memoryio->physical_start,
|
+ ec_memoryio->physical_start,
|
||||||
+ ec_memoryio->physical_ec_start,
|
+ ec_memoryio->physical_ec_start,
|
||||||
+ ec_memoryio->virtual_start);
|
+ ec_memoryio->virtual_start);
|
||||||
@ -1660,8 +1817,8 @@ index 000000000..727510507
|
|||||||
+// Number of used ports
|
+// Number of used ports
|
||||||
+#define ECRAM_PORTIO_PORTS_SIZE 2
|
+#define ECRAM_PORTIO_PORTS_SIZE 2
|
||||||
+// Port used to specify address in EC RAM to read/write
|
+// Port used to specify address in EC RAM to read/write
|
||||||
+// 0x4E/0x4F is the usual port for IO super controler
|
+// 0x4E/0x4F is the usual port for IO super controller
|
||||||
+// 0x2E/0x2F also common (ITE can also be configure to use these)
|
+// 0x2E/0x2F also common (ITE can also be configured to use these)
|
||||||
+#define ECRAM_PORTIO_ADDR_PORT 0x4E
|
+#define ECRAM_PORTIO_ADDR_PORT 0x4E
|
||||||
+// Port to send/receive the value to write/read
|
+// Port to send/receive the value to write/read
|
||||||
+#define ECRAM_PORTIO_DATA_PORT 0x4F
|
+#define ECRAM_PORTIO_DATA_PORT 0x4F
|
||||||
@ -1802,7 +1959,7 @@ index 000000000..727510507
|
|||||||
+
|
+
|
||||||
+ err = ecram_portio_read(&ecram->portio, ecram_offset, &value);
|
+ err = ecram_portio_read(&ecram->portio, ecram_offset, &value);
|
||||||
+ if (err)
|
+ if (err)
|
||||||
+ pr_info("Error reading EC RAM at 0x%x\n", ecram_offset);
|
+ pr_info("Error reading EC RAM at 0x%x.\n", ecram_offset);
|
||||||
+ return value;
|
+ return value;
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
@ -1811,13 +1968,13 @@ index 000000000..727510507
|
|||||||
+ int err;
|
+ int err;
|
||||||
+
|
+
|
||||||
+ if (ec_readonly) {
|
+ if (ec_readonly) {
|
||||||
+ pr_info("Skipping writing EC RAM at 0x%x because readonly.\n",
|
+ pr_info("Skipping writing EC RAM to 0x%x: Read-Only.\n",
|
||||||
+ ecram_offset);
|
+ ecram_offset);
|
||||||
+ return;
|
+ return;
|
||||||
+ }
|
+ }
|
||||||
+ err = ecram_portio_write(&ecram->portio, ecram_offset, value);
|
+ err = ecram_portio_write(&ecram->portio, ecram_offset, value);
|
||||||
+ if (err)
|
+ if (err)
|
||||||
+ pr_info("Error writing EC RAM at 0x%x\n", ecram_offset);
|
+ pr_info("Error writing EC RAM to 0x%x: Read-Only.\n", ecram_offset);
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+/* =============================== */
|
+/* =============================== */
|
||||||
@ -1874,24 +2031,24 @@ index 000000000..727510507
|
|||||||
+ u8 rpm1_raw;
|
+ u8 rpm1_raw;
|
||||||
+ // rpm2 devided by 100
|
+ // rpm2 devided by 100
|
||||||
+ u8 rpm2_raw;
|
+ u8 rpm2_raw;
|
||||||
+ // >=2 , <=5 (lower is faster); must be increasing by level
|
+ // >=2 , <=5 (lower is faster); must increase by level
|
||||||
+ u8 accel;
|
+ u8 accel;
|
||||||
+ // >=2 , <=5 (lower is faster); must be increasing by level
|
+ // >=2 , <=5 (lower is faster); must increase by level
|
||||||
+ u8 decel;
|
+ u8 decel;
|
||||||
+
|
+
|
||||||
+ // min must be lower or equal than max
|
+ // min must be lower than or equal to max
|
||||||
+ // last level max must be 127
|
+ // last level max must be 127
|
||||||
+ // <=127 cpu max temp for this level; must be increasing by level
|
+ // <=127 cpu max temp for this level; must increase by level
|
||||||
+ u8 cpu_max_temp_celsius;
|
+ u8 cpu_max_temp_celsius;
|
||||||
+ // <=127 cpu min temp for this level; must be increasing by level
|
+ // <=127 cpu min temp for this level; must increase by level
|
||||||
+ u8 cpu_min_temp_celsius;
|
+ u8 cpu_min_temp_celsius;
|
||||||
+ // <=127 gpu min temp for this level; must be increasing by level
|
+ // <=127 gpu min temp for this level; must increase by level
|
||||||
+ u8 gpu_max_temp_celsius;
|
+ u8 gpu_max_temp_celsius;
|
||||||
+ // <=127 gpu max temp for this level; must be increasing by level
|
+ // <=127 gpu max temp for this level; must increase by level
|
||||||
+ u8 gpu_min_temp_celsius;
|
+ u8 gpu_min_temp_celsius;
|
||||||
+ // <=127 ic max temp for this level; must be increasing by level
|
+ // <=127 ic max temp for this level; must increase by level
|
||||||
+ u8 ic_max_temp_celsius;
|
+ u8 ic_max_temp_celsius;
|
||||||
+ // <=127 ic max temp for this level; must be increasing by level
|
+ // <=127 ic max temp for this level; must increase by level
|
||||||
+ u8 ic_min_temp_celsius;
|
+ u8 ic_min_temp_celsius;
|
||||||
+};
|
+};
|
||||||
+
|
+
|
||||||
@ -1918,7 +2075,7 @@ index 000000000..727510507
|
|||||||
+ struct fancurve_point points[MAXFANCURVESIZE];
|
+ struct fancurve_point points[MAXFANCURVESIZE];
|
||||||
+ // number of points used; must be <= MAXFANCURVESIZE
|
+ // number of points used; must be <= MAXFANCURVESIZE
|
||||||
+ size_t size;
|
+ size_t size;
|
||||||
+ // the point that at which fans are run currently
|
+ // the point at which fans are run currently
|
||||||
+ size_t current_point_i;
|
+ size_t current_point_i;
|
||||||
+};
|
+};
|
||||||
+
|
+
|
||||||
@ -2047,7 +2204,7 @@ index 000000000..727510507
|
|||||||
+ if (!valid)
|
+ if (!valid)
|
||||||
+ return false;
|
+ return false;
|
||||||
+ if (init_values && size < fancurve->size) {
|
+ if (init_values && size < fancurve->size) {
|
||||||
+ // fancurve size is decreased, but last etnry alwasy needs 127 temperatures
|
+ // fancurve size is decreased, but last entry always needs 127 temperatures
|
||||||
+ // Note: size >=1
|
+ // Note: size >=1
|
||||||
+ fancurve->points[size - 1].cpu_max_temp_celsius = 127;
|
+ fancurve->points[size - 1].cpu_max_temp_celsius = 127;
|
||||||
+ fancurve->points[size - 1].ic_max_temp_celsius = 127;
|
+ fancurve->points[size - 1].ic_max_temp_celsius = 127;
|
||||||
@ -2100,8 +2257,8 @@ index 000000000..727510507
|
|||||||
+/* Global and shared data between */
|
+/* Global and shared data between */
|
||||||
+/* all calls to this module */
|
+/* all calls to this module */
|
||||||
+/* ============================= */
|
+/* ============================= */
|
||||||
+// Implemented like ideapad-laptop.c but currenlty still
|
+// Implemented like ideapad-laptop.c but currently still
|
||||||
+// wihtout dynamic memory allocation (instead global _priv)
|
+// without dynamic memory allocation (instead global _priv)
|
||||||
+struct legion_private {
|
+struct legion_private {
|
||||||
+ struct platform_device *platform_device;
|
+ struct platform_device *platform_device;
|
||||||
+ // TODO: remove or keep? init?
|
+ // TODO: remove or keep? init?
|
||||||
@ -2109,10 +2266,10 @@ index 000000000..727510507
|
|||||||
+
|
+
|
||||||
+ // Method to access ECRAM
|
+ // Method to access ECRAM
|
||||||
+ struct ecram ecram;
|
+ struct ecram ecram;
|
||||||
+ // Configuration with registers an ECRAM access method
|
+ // Configuration with registers and ECRAM access method
|
||||||
+ const struct model_config *conf;
|
+ const struct model_config *conf;
|
||||||
+
|
+
|
||||||
+ // TODO: maybe refactor an keep only local to each function
|
+ // TODO: maybe refactor and keep only local to each function
|
||||||
+ // last known fan curve
|
+ // last known fan curve
|
||||||
+ struct fancurve fancurve;
|
+ struct fancurve fancurve;
|
||||||
+ // configured fan curve from user space
|
+ // configured fan curve from user space
|
||||||
@ -2137,7 +2294,7 @@ index 000000000..727510507
|
|||||||
+ struct ecram_memoryio ec_memoryio;
|
+ struct ecram_memoryio ec_memoryio;
|
||||||
+};
|
+};
|
||||||
+
|
+
|
||||||
+// shared between different drivers: WMI, platform and proteced by mutex
|
+// shared between different drivers: WMI, platform and protected by mutex
|
||||||
+static struct legion_private *legion_shared;
|
+static struct legion_private *legion_shared;
|
||||||
+static struct legion_private _priv;
|
+static struct legion_private _priv;
|
||||||
+static DEFINE_MUTEX(legion_shared_mutex);
|
+static DEFINE_MUTEX(legion_shared_mutex);
|
||||||
@ -2238,7 +2395,7 @@ index 000000000..727510507
|
|||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+/* ============================= */
|
+/* ============================= */
|
||||||
+/* Sensor values reading/writing */
|
+/* Sensor value reading/writing */
|
||||||
+/* ============================= */
|
+/* ============================= */
|
||||||
+
|
+
|
||||||
+static int ec_read_sensor_values(struct ecram *ecram,
|
+static int ec_read_sensor_values(struct ecram *ecram,
|
||||||
@ -2673,7 +2830,7 @@ index 000000000..727510507
|
|||||||
+/* Read the fan curve from the EC.
|
+/* Read the fan curve from the EC.
|
||||||
+ *
|
+ *
|
||||||
+ * In newer models (>=2022) there is an ACPI/WMI to read fan curve as
|
+ * In newer models (>=2022) there is an ACPI/WMI to read fan curve as
|
||||||
+ * a whole. So read/write fan table as a whole to use
|
+ * a whole. So read/write fan table as a whole to use the
|
||||||
+ * same interface for both cases.
|
+ * same interface for both cases.
|
||||||
+ *
|
+ *
|
||||||
+ * It reads all points from EC memory, even if stored fancurve is smaller, so
|
+ * It reads all points from EC memory, even if stored fancurve is smaller, so
|
||||||
@ -2711,7 +2868,7 @@ index 000000000..727510507
|
|||||||
+ ecram, model->registers->EXT_VRM_TEMP_HYST + i);
|
+ ecram, model->registers->EXT_VRM_TEMP_HYST + i);
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ // Do not trust that hardware; It might suddendly report
|
+ // Do not trust that hardware; It might suddenly report
|
||||||
+ // a larger size, so clamp it.
|
+ // a larger size, so clamp it.
|
||||||
+ fancurve->size =
|
+ fancurve->size =
|
||||||
+ ecram_read(ecram, model->registers->EXT_FAN_POINTS_SIZE);
|
+ ecram_read(ecram, model->registers->EXT_FAN_POINTS_SIZE);
|
||||||
@ -2731,9 +2888,6 @@ index 000000000..727510507
|
|||||||
+{
|
+{
|
||||||
+ size_t i;
|
+ size_t i;
|
||||||
+
|
+
|
||||||
+ //TODO: remove again
|
|
||||||
+ pr_info("Set fancurve\n");
|
|
||||||
+
|
|
||||||
+ // Reset fan update counters (try to avoid any race conditions)
|
+ // Reset fan update counters (try to avoid any race conditions)
|
||||||
+ ecram_write(ecram, 0xC5FE, 0);
|
+ ecram_write(ecram, 0xC5FE, 0);
|
||||||
+ ecram_write(ecram, 0xC5FF, 0);
|
+ ecram_write(ecram, 0xC5FF, 0);
|
||||||
@ -2816,7 +2970,7 @@ index 000000000..727510507
|
|||||||
+ point->ic_min_temp_celsius = 0;
|
+ point->ic_min_temp_celsius = 0;
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ // Do not trust that hardware; It might suddendly report
|
+ // Do not trust that hardware; It might suddenly report
|
||||||
+ // a larger size, so clamp it.
|
+ // a larger size, so clamp it.
|
||||||
+ fancurve->size = FANCURVESIZE_IDEAPDAD;
|
+ fancurve->size = FANCURVESIZE_IDEAPDAD;
|
||||||
+ fancurve->current_point_i =
|
+ fancurve->current_point_i =
|
||||||
@ -2835,7 +2989,7 @@ index 000000000..727510507
|
|||||||
+ int valr2;
|
+ int valr2;
|
||||||
+
|
+
|
||||||
+ // add this later: maybe other addresses needed
|
+ // add this later: maybe other addresses needed
|
||||||
+ // therefore, fan curve might not be effective immediatley but
|
+ // therefore, fan curve might not be effective immediately but
|
||||||
+ // only after temp change
|
+ // only after temp change
|
||||||
+ // Reset fan update counters (try to avoid any race conditions)
|
+ // Reset fan update counters (try to avoid any race conditions)
|
||||||
+ ecram_write(ecram, 0xC5FE, 0);
|
+ ecram_write(ecram, 0xC5FE, 0);
|
||||||
@ -2877,7 +3031,7 @@ index 000000000..727510507
|
|||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ // add this later: maybe other addresses needed
|
+ // add this later: maybe other addresses needed
|
||||||
+ // therefore, fan curve might not be effective immediatley but
|
+ // therefore, fan curve might not be effective immediately but
|
||||||
+ // only after temp change
|
+ // only after temp change
|
||||||
+ // // Reset current fan level to 0, so algorithm in EC
|
+ // // Reset current fan level to 0, so algorithm in EC
|
||||||
+ // // selects fan curve point again and resetting hysterisis
|
+ // // selects fan curve point again and resetting hysterisis
|
||||||
@ -2892,6 +3046,77 @@ index 000000000..727510507
|
|||||||
+ return 0;
|
+ return 0;
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
|
+#define FANCURVESIZE_LOQ 10
|
||||||
|
+
|
||||||
|
+static int ec_read_fancurve_loq(struct ecram *ecram,
|
||||||
|
+ const struct model_config *model,
|
||||||
|
+ struct fancurve *fancurve)
|
||||||
|
+{
|
||||||
|
+ size_t i = 0;
|
||||||
|
+ size_t struct_offset = 3; // {cpu_temp: u8, rpm: u8, gpu_temp?: u8}
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < FANCURVESIZE_LOQ; ++i) {
|
||||||
|
+ struct fancurve_point *point = &fancurve->points[i];
|
||||||
|
+
|
||||||
|
+ point->rpm1_raw =
|
||||||
|
+ ecram_read(ecram, model->registers->EXT_FAN1_BASE + (i * struct_offset));
|
||||||
|
+ point->rpm2_raw =
|
||||||
|
+ ecram_read(ecram, model->registers->EXT_FAN2_BASE + (i * struct_offset));
|
||||||
|
+
|
||||||
|
+ point->accel = 0;
|
||||||
|
+ point->decel = 0;
|
||||||
|
+ point->cpu_max_temp_celsius =
|
||||||
|
+ ecram_read(ecram, model->registers->EXT_CPU_TEMP + (i * struct_offset));
|
||||||
|
+ point->gpu_max_temp_celsius =
|
||||||
|
+ ecram_read(ecram, model->registers->EXT_GPU_TEMP + (i * struct_offset));
|
||||||
|
+ point->cpu_min_temp_celsius = 0;
|
||||||
|
+ point->gpu_min_temp_celsius = 0;
|
||||||
|
+ point->ic_max_temp_celsius = 0;
|
||||||
|
+ point->ic_min_temp_celsius = 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ fancurve->size = FANCURVESIZE_LOQ;
|
||||||
|
+ fancurve->current_point_i =
|
||||||
|
+ ecram_read(ecram, model->registers->EXT_FAN_CUR_POINT);
|
||||||
|
+ fancurve->current_point_i =
|
||||||
|
+ min(fancurve->current_point_i, fancurve->size);
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int ec_write_fancurve_loq(struct ecram *ecram,
|
||||||
|
+ const struct model_config *model,
|
||||||
|
+ const struct fancurve *fancurve)
|
||||||
|
+{
|
||||||
|
+ size_t i;
|
||||||
|
+ int valr1;
|
||||||
|
+ int valr2;
|
||||||
|
+ size_t struct_offset = 3; // {cpu_temp: u8, rpm: u8, gpu_temp?: u8}
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < FANCURVESIZE_LOQ; ++i) {
|
||||||
|
+ const struct fancurve_point *point = &fancurve->points[i];
|
||||||
|
+
|
||||||
|
+ ecram_write(ecram, model->registers->EXT_FAN1_BASE + (i * struct_offset),
|
||||||
|
+ point->rpm1_raw);
|
||||||
|
+ valr1 = ecram_read(ecram, model->registers->EXT_FAN1_BASE + (i * struct_offset));
|
||||||
|
+ ecram_write(ecram, model->registers->EXT_FAN2_BASE + (i * struct_offset),
|
||||||
|
+ point->rpm2_raw);
|
||||||
|
+ valr2 = ecram_read(ecram, model->registers->EXT_FAN2_BASE + (i * struct_offset));
|
||||||
|
+ pr_info("Writing fan1: %d; reading fan1: %d\n", point->rpm1_raw,
|
||||||
|
+ valr1);
|
||||||
|
+ pr_info("Writing fan2: %d; reading fan2: %d\n", point->rpm2_raw,
|
||||||
|
+ valr2);
|
||||||
|
+
|
||||||
|
+ // write to memory and repeat 8 bytes later again
|
||||||
|
+ ecram_write(ecram, model->registers->EXT_CPU_TEMP + (i * struct_offset),
|
||||||
|
+ point->cpu_max_temp_celsius);
|
||||||
|
+ // write to memory and repeat 8 bytes later again
|
||||||
|
+ ecram_write(ecram, model->registers->EXT_GPU_TEMP + (i * struct_offset),
|
||||||
|
+ point->gpu_max_temp_celsius);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
+static int read_fancurve(struct legion_private *priv, struct fancurve *fancurve)
|
+static int read_fancurve(struct legion_private *priv, struct fancurve *fancurve)
|
||||||
+{
|
+{
|
||||||
+ // TODO: use enums or function pointers?
|
+ // TODO: use enums or function pointers?
|
||||||
@ -2902,6 +3127,9 @@ index 000000000..727510507
|
|||||||
+ case ACCESS_METHOD_EC2:
|
+ case ACCESS_METHOD_EC2:
|
||||||
+ return ec_read_fancurve_ideapad(&priv->ecram, priv->conf,
|
+ return ec_read_fancurve_ideapad(&priv->ecram, priv->conf,
|
||||||
+ fancurve);
|
+ fancurve);
|
||||||
|
+ case ACCESS_METHOD_EC3:
|
||||||
|
+ return ec_read_fancurve_loq(&priv->ecram, priv->conf,
|
||||||
|
+ fancurve);
|
||||||
+ case ACCESS_METHOD_WMI3:
|
+ case ACCESS_METHOD_WMI3:
|
||||||
+ return wmi_read_fancurve_custom(priv->conf, fancurve);
|
+ return wmi_read_fancurve_custom(priv->conf, fancurve);
|
||||||
+ default:
|
+ default:
|
||||||
@ -2922,6 +3150,9 @@ index 000000000..727510507
|
|||||||
+ case ACCESS_METHOD_EC2:
|
+ case ACCESS_METHOD_EC2:
|
||||||
+ return ec_write_fancurve_ideapad(&priv->ecram, priv->conf,
|
+ return ec_write_fancurve_ideapad(&priv->ecram, priv->conf,
|
||||||
+ fancurve);
|
+ fancurve);
|
||||||
|
+ case ACCESS_METHOD_EC3:
|
||||||
|
+ return ec_write_fancurve_loq(&priv->ecram, priv->conf,
|
||||||
|
+ fancurve);
|
||||||
+ case ACCESS_METHOD_WMI3:
|
+ case ACCESS_METHOD_WMI3:
|
||||||
+ return wmi_write_fancurve_custom(priv->conf, fancurve);
|
+ return wmi_write_fancurve_custom(priv->conf, fancurve);
|
||||||
+ default:
|
+ default:
|
||||||
@ -3150,7 +3381,7 @@ index 000000000..727510507
|
|||||||
+ unsigned long acpi_powermode;
|
+ unsigned long acpi_powermode;
|
||||||
+ int err;
|
+ int err;
|
||||||
+
|
+
|
||||||
+ // spmo method not alwasy available
|
+ // spmo method not always available
|
||||||
+ // \_SB.PCI0.LPC0.EC0.SPMO
|
+ // \_SB.PCI0.LPC0.EC0.SPMO
|
||||||
+ err = eval_spmo(priv->adev->handle, &acpi_powermode);
|
+ err = eval_spmo(priv->adev->handle, &acpi_powermode);
|
||||||
+ *powermode = (int)acpi_powermode;
|
+ *powermode = (int)acpi_powermode;
|
||||||
@ -3255,7 +3486,7 @@ index 000000000..727510507
|
|||||||
+ unsigned long result;
|
+ unsigned long result;
|
||||||
+ int err;
|
+ int err;
|
||||||
+
|
+
|
||||||
+ //also works? what is better?
|
+ //also works? which one is better?
|
||||||
+ /*
|
+ /*
|
||||||
+ * err = eval_qcho(adev->handle, &result);
|
+ * err = eval_qcho(adev->handle, &result);
|
||||||
+ * if (err)
|
+ * if (err)
|
||||||
@ -3543,7 +3774,7 @@ index 000000000..727510507
|
|||||||
+ seq_printf(s, "WMI light IO port: %d\n",
|
+ seq_printf(s, "WMI light IO port: %d\n",
|
||||||
+ legion_wmi_light_get(priv, LIGHT_ID_IOPORT, 0, 4));
|
+ legion_wmi_light_get(priv, LIGHT_ID_IOPORT, 0, 4));
|
||||||
+
|
+
|
||||||
+ seq_printf(s, "WMI light y logo/lid: %d\n",
|
+ seq_printf(s, "WMI light Y logo/lid: %d\n",
|
||||||
+ legion_wmi_light_get(priv, LIGHT_ID_YLOGO, 0, 4));
|
+ legion_wmi_light_get(priv, LIGHT_ID_YLOGO, 0, 4));
|
||||||
+
|
+
|
||||||
+ seq_printf(s, "EC minifancurve feature enabled: %d\n",
|
+ seq_printf(s, "EC minifancurve feature enabled: %d\n",
|
||||||
@ -3591,7 +3822,7 @@ index 000000000..727510507
|
|||||||
+ struct dentry *dir;
|
+ struct dentry *dir;
|
||||||
+
|
+
|
||||||
+ // TODO: remove this note
|
+ // TODO: remove this note
|
||||||
+ // Note: as other kernel modules, do not catch errors here
|
+ // Note: like other kernel modules, do not catch errors here
|
||||||
+ // because if kernel is build without debugfs this
|
+ // because if kernel is build without debugfs this
|
||||||
+ // will return an error but module still has to
|
+ // will return an error but module still has to
|
||||||
+ // work, just without debugfs
|
+ // work, just without debugfs
|
||||||
@ -3655,7 +3886,7 @@ index 000000000..727510507
|
|||||||
+ struct legion_private *priv = dev_get_drvdata(dev);
|
+ struct legion_private *priv = dev_get_drvdata(dev);
|
||||||
+
|
+
|
||||||
+ if (ressize > ARRAY_SIZE(res)) {
|
+ if (ressize > ARRAY_SIZE(res)) {
|
||||||
+ pr_info("Buffer to small for WMI result\n");
|
+ pr_info("Buffer too small for WMI result\n");
|
||||||
+ return -EINVAL;
|
+ return -EINVAL;
|
||||||
+ }
|
+ }
|
||||||
+ if (i >= ressize) {
|
+ if (i >= ressize) {
|
||||||
@ -4402,8 +4633,8 @@ index 000000000..727510507
|
|||||||
+unlock:
|
+unlock:
|
||||||
+ mutex_unlock(&legion_shared_mutex);
|
+ mutex_unlock(&legion_shared_mutex);
|
||||||
+ // todo; fix that!
|
+ // todo; fix that!
|
||||||
+ // problem: we get a event just before the powermode change (from the key?),
|
+ // problem: we get an event just before the powermode change (from the key?),
|
||||||
+ // so if we notify to early, it will read the old power mode/platform profile
|
+ // so if we notify too early, it will read the old power mode/platform profile
|
||||||
+ msleep(500);
|
+ msleep(500);
|
||||||
+ legion_platform_profile_notify();
|
+ legion_platform_profile_notify();
|
||||||
+}
|
+}
|
||||||
@ -4752,11 +4983,11 @@ index 000000000..727510507
|
|||||||
+ mutex_unlock(&priv->fancurve_mutex);
|
+ mutex_unlock(&priv->fancurve_mutex);
|
||||||
+
|
+
|
||||||
+ if (err) {
|
+ if (err) {
|
||||||
+ pr_info("Reading fancurve failed\n");
|
+ pr_info("Failed to read fancurve\n");
|
||||||
+ return -EOPNOTSUPP;
|
+ return -EOPNOTSUPP;
|
||||||
+ }
|
+ }
|
||||||
+ if (!(point_id >= 0 && point_id < MAXFANCURVESIZE)) {
|
+ if (!(point_id >= 0 && point_id < MAXFANCURVESIZE)) {
|
||||||
+ pr_info("Reading fancurve failed due to wrong point id: %d\n",
|
+ pr_info("Failed to read fancurve due to wrong point id: %d\n",
|
||||||
+ point_id);
|
+ point_id);
|
||||||
+ return -EOPNOTSUPP;
|
+ return -EOPNOTSUPP;
|
||||||
+ }
|
+ }
|
||||||
@ -4796,7 +5027,7 @@ index 000000000..727510507
|
|||||||
+ value = fancurve.size;
|
+ value = fancurve.size;
|
||||||
+ break;
|
+ break;
|
||||||
+ default:
|
+ default:
|
||||||
+ pr_info("Reading fancurve failed due to wrong attribute id: %d\n",
|
+ pr_info("Failed to read fancurve due to wrong attribute id: %d\n",
|
||||||
+ fancurve_attr_id);
|
+ fancurve_attr_id);
|
||||||
+ return -EOPNOTSUPP;
|
+ return -EOPNOTSUPP;
|
||||||
+ }
|
+ }
|
||||||
@ -4818,7 +5049,7 @@ index 000000000..727510507
|
|||||||
+ bool write_fancurve_size = false;
|
+ bool write_fancurve_size = false;
|
||||||
+
|
+
|
||||||
+ if (!(point_id >= 0 && point_id < MAXFANCURVESIZE)) {
|
+ if (!(point_id >= 0 && point_id < MAXFANCURVESIZE)) {
|
||||||
+ pr_info("Reading fancurve failed due to wrong point id: %d\n",
|
+ pr_info("Failed to read fancurve due to wrong point id: %d\n",
|
||||||
+ point_id);
|
+ point_id);
|
||||||
+ err = -EOPNOTSUPP;
|
+ err = -EOPNOTSUPP;
|
||||||
+ goto error;
|
+ goto error;
|
||||||
@ -4826,7 +5057,7 @@ index 000000000..727510507
|
|||||||
+
|
+
|
||||||
+ err = kstrtoint(buf, 0, &value);
|
+ err = kstrtoint(buf, 0, &value);
|
||||||
+ if (err) {
|
+ if (err) {
|
||||||
+ pr_info("Parse for hwmon store is not succesful: error:%d; point_id: %d; fancurve_attr_id: %d\\n",
|
+ pr_info("Parsing hwmon store failed: error: %d; point_id: %d; fancurve_attr_id: %d\\n",
|
||||||
+ err, point_id, fancurve_attr_id);
|
+ err, point_id, fancurve_attr_id);
|
||||||
+ goto error;
|
+ goto error;
|
||||||
+ }
|
+ }
|
||||||
@ -4835,7 +5066,7 @@ index 000000000..727510507
|
|||||||
+ err = read_fancurve(priv, &fancurve);
|
+ err = read_fancurve(priv, &fancurve);
|
||||||
+
|
+
|
||||||
+ if (err) {
|
+ if (err) {
|
||||||
+ pr_info("Reading fancurve failed\n");
|
+ pr_info("Failed to read fancurve\n");
|
||||||
+ err = -EOPNOTSUPP;
|
+ err = -EOPNOTSUPP;
|
||||||
+ goto error_mutex;
|
+ goto error_mutex;
|
||||||
+ }
|
+ }
|
||||||
@ -4876,7 +5107,7 @@ index 000000000..727510507
|
|||||||
+ write_fancurve_size = true;
|
+ write_fancurve_size = true;
|
||||||
+ break;
|
+ break;
|
||||||
+ default:
|
+ default:
|
||||||
+ pr_info("Writing fancurve failed due to wrong attribute id: %d\n",
|
+ pr_info("Failed to write fancurve due to wrong attribute id: %d\n",
|
||||||
+ fancurve_attr_id);
|
+ fancurve_attr_id);
|
||||||
+ err = -EOPNOTSUPP;
|
+ err = -EOPNOTSUPP;
|
||||||
+ goto error_mutex;
|
+ goto error_mutex;
|
||||||
@ -4891,7 +5122,7 @@ index 000000000..727510507
|
|||||||
+
|
+
|
||||||
+ err = write_fancurve(priv, &fancurve, write_fancurve_size);
|
+ err = write_fancurve(priv, &fancurve, write_fancurve_size);
|
||||||
+ if (err) {
|
+ if (err) {
|
||||||
+ pr_info("Writing fancurve failed for accessing hwmon at point_id: %d\n",
|
+ pr_info("Failed to write fancurve for accessing hwmon at point_id: %d\n",
|
||||||
+ point_id);
|
+ point_id);
|
||||||
+ err = -EOPNOTSUPP;
|
+ err = -EOPNOTSUPP;
|
||||||
+ goto error_mutex;
|
+ goto error_mutex;
|
||||||
@ -5130,7 +5361,7 @@ index 000000000..727510507
|
|||||||
+ err = ec_read_minifancurve(&priv->ecram, priv->conf, &value);
|
+ err = ec_read_minifancurve(&priv->ecram, priv->conf, &value);
|
||||||
+ if (err) {
|
+ if (err) {
|
||||||
+ err = -1;
|
+ err = -1;
|
||||||
+ pr_info("Reading minifancurve not succesful\n");
|
+ pr_info("Failed to read minifancurve\n");
|
||||||
+ goto error_unlock;
|
+ goto error_unlock;
|
||||||
+ }
|
+ }
|
||||||
+ mutex_unlock(&priv->fancurve_mutex);
|
+ mutex_unlock(&priv->fancurve_mutex);
|
||||||
@ -5152,7 +5383,7 @@ index 000000000..727510507
|
|||||||
+ err = kstrtoint(buf, 0, &value);
|
+ err = kstrtoint(buf, 0, &value);
|
||||||
+ if (err) {
|
+ if (err) {
|
||||||
+ err = -1;
|
+ err = -1;
|
||||||
+ pr_info("Parse for hwmon store is not succesful: error:%d\n",
|
+ pr_info("Parsing hwmon store failed: error:%d\n",
|
||||||
+ err);
|
+ err);
|
||||||
+ goto error;
|
+ goto error;
|
||||||
+ }
|
+ }
|
||||||
@ -5161,7 +5392,7 @@ index 000000000..727510507
|
|||||||
+ err = ec_write_minifancurve(&priv->ecram, priv->conf, value);
|
+ err = ec_write_minifancurve(&priv->ecram, priv->conf, value);
|
||||||
+ if (err) {
|
+ if (err) {
|
||||||
+ err = -1;
|
+ err = -1;
|
||||||
+ pr_info("Writing minifancurve not succesful\n");
|
+ pr_info("Failed to write minifancurve\n");
|
||||||
+ goto error_unlock;
|
+ goto error_unlock;
|
||||||
+ }
|
+ }
|
||||||
+ mutex_unlock(&priv->fancurve_mutex);
|
+ mutex_unlock(&priv->fancurve_mutex);
|
||||||
@ -5186,7 +5417,7 @@ index 000000000..727510507
|
|||||||
+ err = ec_read_fanfullspeed(&priv->ecram, priv->conf, &value);
|
+ err = ec_read_fanfullspeed(&priv->ecram, priv->conf, &value);
|
||||||
+ if (err) {
|
+ if (err) {
|
||||||
+ err = -1;
|
+ err = -1;
|
||||||
+ pr_info("Reading pwm1_mode/maximumfanspeed not succesful\n");
|
+ pr_info("Failed to pwm1_mode/maximumfanspeed\n");
|
||||||
+ goto error_unlock;
|
+ goto error_unlock;
|
||||||
+ }
|
+ }
|
||||||
+ mutex_unlock(&priv->fancurve_mutex);
|
+ mutex_unlock(&priv->fancurve_mutex);
|
||||||
@ -5210,7 +5441,7 @@ index 000000000..727510507
|
|||||||
+ err = kstrtoint(buf, 0, &value);
|
+ err = kstrtoint(buf, 0, &value);
|
||||||
+ if (err) {
|
+ if (err) {
|
||||||
+ err = -1;
|
+ err = -1;
|
||||||
+ pr_info("Parse for hwmon store is not succesful: error:%d\n",
|
+ pr_info("Parsing hwmon store failed: error:%d\n",
|
||||||
+ err);
|
+ err);
|
||||||
+ goto error;
|
+ goto error;
|
||||||
+ }
|
+ }
|
||||||
@ -5221,7 +5452,7 @@ index 000000000..727510507
|
|||||||
+ is_maximumfanspeed);
|
+ is_maximumfanspeed);
|
||||||
+ if (err) {
|
+ if (err) {
|
||||||
+ err = -1;
|
+ err = -1;
|
||||||
+ pr_info("Writing pwm1_mode/maximumfanspeed not succesful\n");
|
+ pr_info("Failed to write pwm1_mode/maximumfanspeed\n");
|
||||||
+ goto error_unlock;
|
+ goto error_unlock;
|
||||||
+ }
|
+ }
|
||||||
+ mutex_unlock(&priv->fancurve_mutex);
|
+ mutex_unlock(&priv->fancurve_mutex);
|
||||||
@ -5480,7 +5711,7 @@ index 000000000..727510507
|
|||||||
+
|
+
|
||||||
+ brightness = legion_kbd_bl_brightness_get(priv);
|
+ brightness = legion_kbd_bl_brightness_get(priv);
|
||||||
+ if (brightness < 0) {
|
+ if (brightness < 0) {
|
||||||
+ pr_info("Error reading keyboard brighntess\n");
|
+ pr_info("Error reading keyboard brightness\n");
|
||||||
+ return brightness;
|
+ return brightness;
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
@ -5568,7 +5799,7 @@ index 000000000..727510507
|
|||||||
+ light_ins->lower_limit,
|
+ light_ins->lower_limit,
|
||||||
+ light_ins->upper_limit);
|
+ light_ins->upper_limit);
|
||||||
+ if (brightness < 0) {
|
+ if (brightness < 0) {
|
||||||
+ pr_info("Error reading brighntess for light: %u\n",
|
+ pr_info("Error reading brightness for light: %u\n",
|
||||||
+ light_ins->light_id);
|
+ light_ins->light_id);
|
||||||
+ return brightness;
|
+ return brightness;
|
||||||
+ }
|
+ }
|
||||||
@ -5663,7 +5894,7 @@ index 000000000..727510507
|
|||||||
+ if (!(do_load)) {
|
+ if (!(do_load)) {
|
||||||
+ dev_info(
|
+ dev_info(
|
||||||
+ &pdev->dev,
|
+ &pdev->dev,
|
||||||
+ "Module not useable for this laptop because it is not in allowlist. Notify maintainer if you want to add your device or force load with param force.\n");
|
+ "Module not usable for this laptop because it is not in allowlist. Notify the maintainer if you want to add your device or force load with param force.\n");
|
||||||
+ err = -ENOMEM;
|
+ err = -ENOMEM;
|
||||||
+ goto err_model_mismtach;
|
+ goto err_model_mismtach;
|
||||||
+ }
|
+ }
|
||||||
@ -5674,7 +5905,7 @@ index 000000000..727510507
|
|||||||
+ if (!do_load_by_list && do_load) {
|
+ if (!do_load_by_list && do_load) {
|
||||||
+ dev_info(
|
+ dev_info(
|
||||||
+ &pdev->dev,
|
+ &pdev->dev,
|
||||||
+ "legion_laptop is forced to load and would otherwise be not loaded\n");
|
+ "legion_laptop is forced to load and would otherwise not be loaded\n");
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ // if forced and no module found, use config for first model
|
+ // if forced and no module found, use config for first model
|
||||||
@ -5729,13 +5960,13 @@ index 000000000..727510507
|
|||||||
+ "Skipped checking embedded controller id\n");
|
+ "Skipped checking embedded controller id\n");
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ dev_info(&pdev->dev, "Creating debugfs inteface\n");
|
+ dev_info(&pdev->dev, "Creating debugfs interface\n");
|
||||||
+ legion_debugfs_init(priv);
|
+ legion_debugfs_init(priv);
|
||||||
+
|
+
|
||||||
+ pr_info("Creating sysfs inteface\n");
|
+ pr_info("Creating sysfs interface\n");
|
||||||
+ err = legion_sysfs_init(priv);
|
+ err = legion_sysfs_init(priv);
|
||||||
+ if (err) {
|
+ if (err) {
|
||||||
+ dev_info(&pdev->dev, "Creating sysfs interface failed: %d\n",
|
+ dev_info(&pdev->dev, "Failed to create sysfs interface: %d\n",
|
||||||
+ err);
|
+ err);
|
||||||
+ goto err_sysfs_init;
|
+ goto err_sysfs_init;
|
||||||
+ }
|
+ }
|
||||||
@ -5743,7 +5974,7 @@ index 000000000..727510507
|
|||||||
+ pr_info("Creating hwmon interface");
|
+ pr_info("Creating hwmon interface");
|
||||||
+ err = legion_hwmon_init(priv);
|
+ err = legion_hwmon_init(priv);
|
||||||
+ if (err) {
|
+ if (err) {
|
||||||
+ dev_info(&pdev->dev, "Creating hwmon interface failed: %d\n",
|
+ dev_info(&pdev->dev, "Failed to create hwmon interface: %d\n",
|
||||||
+ err);
|
+ err);
|
||||||
+ goto err_hwmon_init;
|
+ goto err_hwmon_init;
|
||||||
+ }
|
+ }
|
||||||
@ -5751,7 +5982,7 @@ index 000000000..727510507
|
|||||||
+ pr_info("Creating platform profile support\n");
|
+ pr_info("Creating platform profile support\n");
|
||||||
+ err = legion_platform_profile_init(priv);
|
+ err = legion_platform_profile_init(priv);
|
||||||
+ if (err) {
|
+ if (err) {
|
||||||
+ dev_info(&pdev->dev, "Creating platform profile failed: %d\n",
|
+ dev_info(&pdev->dev, "Failed to create platform profile: %d\n",
|
||||||
+ err);
|
+ err);
|
||||||
+ goto err_platform_profile;
|
+ goto err_platform_profile;
|
||||||
+ }
|
+ }
|
||||||
@ -5759,7 +5990,7 @@ index 000000000..727510507
|
|||||||
+ pr_info("Init WMI driver support\n");
|
+ pr_info("Init WMI driver support\n");
|
||||||
+ err = legion_wmi_init();
|
+ err = legion_wmi_init();
|
||||||
+ if (err) {
|
+ if (err) {
|
||||||
+ dev_info(&pdev->dev, "Init WMI driver failed: %d\n", err);
|
+ dev_info(&pdev->dev, "Failed to init WMI driver: %d\n", err);
|
||||||
+ goto err_wmi;
|
+ goto err_wmi;
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
@ -5768,7 +5999,7 @@ index 000000000..727510507
|
|||||||
+ if (err) {
|
+ if (err) {
|
||||||
+ dev_info(
|
+ dev_info(
|
||||||
+ &pdev->dev,
|
+ &pdev->dev,
|
||||||
+ "Init keyboard backlight LED driver failed. Skipping ...\n");
|
+ "Failed to init keyboard backlight LED driver. Skipping ...\n");
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ pr_info("Init Y-Logo LED driver\n");
|
+ pr_info("Init Y-Logo LED driver\n");
|
||||||
@ -5776,7 +6007,7 @@ index 000000000..727510507
|
|||||||
+ "platform::ylogo");
|
+ "platform::ylogo");
|
||||||
+ if (err) {
|
+ if (err) {
|
||||||
+ dev_info(&pdev->dev,
|
+ dev_info(&pdev->dev,
|
||||||
+ "Init Y-Logo LED driver failed. Skipping ...\n");
|
+ "Failed to init Y-Logo LED driver. Skipping ...\n");
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ pr_info("Init IO-Port LED driver\n");
|
+ pr_info("Init IO-Port LED driver\n");
|
||||||
@ -5784,7 +6015,7 @@ index 000000000..727510507
|
|||||||
+ "platform::ioport");
|
+ "platform::ioport");
|
||||||
+ if (err) {
|
+ if (err) {
|
||||||
+ dev_info(&pdev->dev,
|
+ dev_info(&pdev->dev,
|
||||||
+ "Init IO-Port LED driver failed. Skipping ...\n");
|
+ "Failed to init IO-Port LED driver. Skipping ...\n");
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ dev_info(&pdev->dev, "legion_laptop loaded for this device\n");
|
+ dev_info(&pdev->dev, "legion_laptop loaded for this device\n");
|
||||||
@ -5889,7 +6120,7 @@ index 000000000..727510507
|
|||||||
+{
|
+{
|
||||||
+ int err;
|
+ int err;
|
||||||
+
|
+
|
||||||
+ pr_info("legion_laptop starts loading\n");
|
+ pr_info("Loading legion_laptop\n");
|
||||||
+ err = platform_driver_register(&legion_driver);
|
+ err = platform_driver_register(&legion_driver);
|
||||||
+ if (err) {
|
+ if (err) {
|
||||||
+ pr_info("legion_laptop: platform_driver_register failed\n");
|
+ pr_info("legion_laptop: platform_driver_register failed\n");
|
||||||
@ -5909,5 +6140,4 @@ index 000000000..727510507
|
|||||||
+
|
+
|
||||||
+module_exit(legion_exit);
|
+module_exit(legion_exit);
|
||||||
--
|
--
|
||||||
2.41.0
|
2.43.2
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user