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: 0ab88e2394 ("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>
This commit is contained in:
Cryolitia PukNgae
2025-10-30 22:30:06 +08:00
committed by Guenter Roeck
parent 9efb297c52
commit c55a8e24cd

View File

@@ -276,31 +276,6 @@ static int gpd_generic_read_rpm(void)
return (u16)high << 8 | low; 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) static int gpd_wm2_read_rpm(void)
{ {
for (u16 pwm_ctr_offset = GPD_PWM_CTR_OFFSET; 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) static int gpd_read_rpm(void)
{ {
switch (gpd_driver_priv.drvdata->board) { switch (gpd_driver_priv.drvdata->board) {
case win4_6800u:
case win_mini: case win_mini:
case duo: case duo:
return gpd_generic_read_rpm(); return gpd_generic_read_rpm();
case win4_6800u:
return gpd_win4_read_rpm();
case win_max_2: case win_max_2:
return gpd_wm2_read_rpm(); return gpd_wm2_read_rpm();
} }
@@ -607,6 +581,28 @@ static struct hwmon_chip_info gpd_fan_chip_info = {
.info = gpd_fan_hwmon_channel_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) static int gpd_fan_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; 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), return dev_err_probe(dev, PTR_ERR(hwdev),
"Failed to register hwmon device\n"); "Failed to register hwmon device\n");
gpd_init_ec();
return 0; return 0;
} }