From 40b11d75f8f8716e5e155fc6357c9dc54418e503 Mon Sep 17 00:00:00 2001 From: Eric Zhu Date: Thu, 23 Mar 2023 20:07:30 -0500 Subject: [PATCH] enable emc2305 fan controller timeout feature Why I did it There is rare condition, emc2305 hold SMBus and cause SMBus completion wait timed out. How I did it Enable EMC2305 SMBus timeout feature, 30ms period of inactivity will reset the interface. How to verify it Use 'i2cget -y -f 23 0x4d 0x20 b' to read EMC2305 configuration register and check DIS_TO bit not set. Signed-off-by: Eric Zhu --- .../haliburton/modules/emc2305.c | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/platform/broadcom/sonic-platform-modules-cel/haliburton/modules/emc2305.c b/platform/broadcom/sonic-platform-modules-cel/haliburton/modules/emc2305.c index f08033e080c..c32f5dffbc2 100644 --- a/platform/broadcom/sonic-platform-modules-cel/haliburton/modules/emc2305.c +++ b/platform/broadcom/sonic-platform-modules-cel/haliburton/modules/emc2305.c @@ -407,6 +407,35 @@ emc2305_set_pwm(struct i2c_client *client, int fan_idx, long pwm) mutex_unlock(&data->update_lock); return status; } + +static int +emc2305_enable_timeout(struct i2c_client *client, bool enable) +{ + struct emc2305_data *data = i2c_get_clientdata(client); + int status = 0; + u8 conf_val = 0; + + mutex_lock(&data->update_lock); + + status = read_u8_from_i2c(client, REG_CONFIGURATION, &conf_val); + if (status < 0) { + mutex_unlock(&data->update_lock); + return status; + } + + // Section 6.2: CONFIG REGISTER DIS_TO bit(bit 6) + if (enable) { + conf_val &= ~(1 << 6); + } else { + conf_val |= (1 << 6); + } + + status = i2c_smbus_write_byte_data(client, REG_CONFIGURATION, conf_val); + + mutex_unlock(&data->update_lock); + return status; +} + /* * sysfs callback functions * @@ -744,6 +773,9 @@ emc2305_probe(struct i2c_client *client, const struct i2c_device_id *id) i2c_set_clientdata(client, data); mutex_init(&data->update_lock); + // Enable SMBus timeout feature + emc2305_enable_timeout(client, true); + status = i2c_smbus_read_byte_data(client, REG_PRODUCT_ID); switch (status) { case 0x34: /* EMC2305 */