Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

hwmon: (gpd-fan) initialize EC on driver load for Win 4

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>

authored by

Cryolitia PukNgae and committed by
Guenter Roeck
c55a8e24 9efb297c

+25 -27
+25 -27
drivers/hwmon/gpd-fan.c
··· 276 276 return (u16)high << 8 | low; 277 277 } 278 278 279 - static void gpd_win4_init_ec(void) 280 - { 281 - u8 chip_id, chip_ver; 282 - 283 - gpd_ecram_read(0x2000, &chip_id); 284 - 285 - if (chip_id == 0x55) { 286 - gpd_ecram_read(0x1060, &chip_ver); 287 - gpd_ecram_write(0x1060, chip_ver | 0x80); 288 - } 289 - } 290 - 291 - static int gpd_win4_read_rpm(void) 292 - { 293 - int ret; 294 - 295 - ret = gpd_generic_read_rpm(); 296 - 297 - if (ret == 0) 298 - // Re-init EC when speed is 0 299 - gpd_win4_init_ec(); 300 - 301 - return ret; 302 - } 303 - 304 279 static int gpd_wm2_read_rpm(void) 305 280 { 306 281 for (u16 pwm_ctr_offset = GPD_PWM_CTR_OFFSET; ··· 295 320 static int gpd_read_rpm(void) 296 321 { 297 322 switch (gpd_driver_priv.drvdata->board) { 323 + case win4_6800u: 298 324 case win_mini: 299 325 case duo: 300 326 return gpd_generic_read_rpm(); 301 - case win4_6800u: 302 - return gpd_win4_read_rpm(); 303 327 case win_max_2: 304 328 return gpd_wm2_read_rpm(); 305 329 } ··· 581 607 .info = gpd_fan_hwmon_channel_info 582 608 }; 583 609 610 + static void gpd_win4_init_ec(void) 611 + { 612 + u8 chip_id, chip_ver; 613 + 614 + gpd_ecram_read(0x2000, &chip_id); 615 + 616 + if (chip_id == 0x55) { 617 + gpd_ecram_read(0x1060, &chip_ver); 618 + gpd_ecram_write(0x1060, chip_ver | 0x80); 619 + } 620 + } 621 + 622 + static void gpd_init_ec(void) 623 + { 624 + // The buggy firmware won't initialize EC properly on boot. 625 + // Before its initialization, reading RPM will always return 0, 626 + // and writing PWM will have no effect. 627 + // Initialize it manually on driver load. 628 + if (gpd_driver_priv.drvdata->board == win4_6800u) 629 + gpd_win4_init_ec(); 630 + } 631 + 584 632 static int gpd_fan_probe(struct platform_device *pdev) 585 633 { 586 634 struct device *dev = &pdev->dev; ··· 629 633 if (IS_ERR(hwdev)) 630 634 return dev_err_probe(dev, PTR_ERR(hwdev), 631 635 "Failed to register hwmon device\n"); 636 + 637 + gpd_init_ec(); 632 638 633 639 return 0; 634 640 }