]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
hwmon: (gpd-fan) initialize EC on driver load for Win 4
authorCryolitia PukNgae <cryolitia@uniontech.com>
Thu, 30 Oct 2025 14:30:06 +0000 (22:30 +0800)
committerGuenter Roeck <linux@roeck-us.net>
Wed, 12 Nov 2025 19:54:37 +0000 (11:54 -0800)
The original implement will re-init the EC when it reports a zero
value, and it's a workaround for the black box buggy firmware.

Now a contributer test and report that, the bug is that, the firmware
won't initialize the EC on boot, so the EC ramains in unusable status.
And it won't need to re-init it during runtime. The original implement
is not perfect, any write command will be ignored until we first read
it. Just re-init it unconditionally when the driver load could work.

Fixes: 0ab88e239439 ("hwmon: add GPD devices sensor driver")
Co-developed-by: kylon <3252255+kylon@users.noreply.github.com>
Signed-off-by: kylon <3252255+kylon@users.noreply.github.com>
Link: https://github.com/Cryolitia/gpd-fan-driver/pull/20
Signed-off-by: Cryolitia PukNgae <cryolitia@uniontech.com>
Link: https://lore.kernel.org/r/20251030-win4-v1-1-c374dcb86985@uniontech.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
drivers/hwmon/gpd-fan.c

index 48c84e3e99398f98d03a629f8fe39b115e3fbf98..f81c3bc422f4ce866795fb78bc5d4193ba1a6752 100644 (file)
@@ -276,31 +276,6 @@ static int gpd_generic_read_rpm(void)
        return (u16)high << 8 | low;
 }
 
-static void gpd_win4_init_ec(void)
-{
-       u8 chip_id, chip_ver;
-
-       gpd_ecram_read(0x2000, &chip_id);
-
-       if (chip_id == 0x55) {
-               gpd_ecram_read(0x1060, &chip_ver);
-               gpd_ecram_write(0x1060, chip_ver | 0x80);
-       }
-}
-
-static int gpd_win4_read_rpm(void)
-{
-       int ret;
-
-       ret = gpd_generic_read_rpm();
-
-       if (ret == 0)
-               // Re-init EC when speed is 0
-               gpd_win4_init_ec();
-
-       return ret;
-}
-
 static int gpd_wm2_read_rpm(void)
 {
        for (u16 pwm_ctr_offset = GPD_PWM_CTR_OFFSET;
@@ -320,11 +295,10 @@ static int gpd_wm2_read_rpm(void)
 static int gpd_read_rpm(void)
 {
        switch (gpd_driver_priv.drvdata->board) {
+       case win4_6800u:
        case win_mini:
        case duo:
                return gpd_generic_read_rpm();
-       case win4_6800u:
-               return gpd_win4_read_rpm();
        case win_max_2:
                return gpd_wm2_read_rpm();
        }
@@ -607,6 +581,28 @@ static struct hwmon_chip_info gpd_fan_chip_info = {
        .info = gpd_fan_hwmon_channel_info
 };
 
+static void gpd_win4_init_ec(void)
+{
+       u8 chip_id, chip_ver;
+
+       gpd_ecram_read(0x2000, &chip_id);
+
+       if (chip_id == 0x55) {
+               gpd_ecram_read(0x1060, &chip_ver);
+               gpd_ecram_write(0x1060, chip_ver | 0x80);
+       }
+}
+
+static void gpd_init_ec(void)
+{
+       // The buggy firmware won't initialize EC properly on boot.
+       // Before its initialization, reading RPM will always return 0,
+       // and writing PWM will have no effect.
+       // Initialize it manually on driver load.
+       if (gpd_driver_priv.drvdata->board == win4_6800u)
+               gpd_win4_init_ec();
+}
+
 static int gpd_fan_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
@@ -634,6 +630,8 @@ static int gpd_fan_probe(struct platform_device *pdev)
                return dev_err_probe(dev, PTR_ERR(hwdev),
                                     "Failed to register hwmon device\n");
 
+       gpd_init_ec();
+
        return 0;
 }