Issue: When binding adm1272 to the adm1275 driver, PEC error is reported. See blow: adm1275: probe of xxxx failed with error -74
Diagnosis: Per the datasheet of adm1272 and adm1278 (www.analog.com), PMON_CONFIG (0xd4) is 16bits wide. On the other hand, PMON_CONFIG (0xd4) for adm1275 is 8bits wide. The driver should not assume everything is 8bits wide and read only 8bits from it. Solution: if it is adm1272 or adm1278, use i2c_read_word. Else, use i2c_read_byte Signed-off-by: Chu Lin <linchuy...@google.com> --- drivers/hwmon/pmbus/adm1275.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/drivers/hwmon/pmbus/adm1275.c b/drivers/hwmon/pmbus/adm1275.c index e25f541227da..a0d547d20358 100644 --- a/drivers/hwmon/pmbus/adm1275.c +++ b/drivers/hwmon/pmbus/adm1275.c @@ -472,6 +472,7 @@ static int adm1275_probe(struct i2c_client *client, struct adm1275_data *data; const struct i2c_device_id *mid; const struct coefficients *coefficients; + s32 (*config_read_fn_ptr)(const struct i2c_client *client, u8 reg); int vindex = -1, voindex = -1, cindex = -1, pindex = -1; int tindex = -1; u32 shunt; @@ -510,14 +511,6 @@ static int adm1275_probe(struct i2c_client *client, "Device mismatch: Configured %s, detected %s\n", id->name, mid->name); - config = i2c_smbus_read_byte_data(client, ADM1275_PMON_CONFIG); - if (config < 0) - return config; - - device_config = i2c_smbus_read_byte_data(client, ADM1275_DEVICE_CONFIG); - if (device_config < 0) - return device_config; - data = devm_kzalloc(&client->dev, sizeof(struct adm1275_data), GFP_KERNEL); if (!data) @@ -532,6 +525,21 @@ static int adm1275_probe(struct i2c_client *client, data->id = mid->driver_data; + /* adm1272 and adm1278 supports temperature monitoring. The config and device config + * are 16bits wide for these two devices. On the other hand, other devices are 8 bits wide + */ + if (data->id == adm1272 || data->id == adm1278) + config_read_fn_ptr = &i2c_smbus_read_word_data; + else + config_read_fn_ptr = &i2c_smbus_read_byte_data; + config = config_read_fn_ptr(client, ADM1275_PMON_CONFIG); + if (config < 0) + return config; + + device_config = config_read_fn_ptr(client, ADM1275_DEVICE_CONFIG); + if (device_config < 0) + return device_config; + info = &data->info; info->pages = 1; -- 2.27.0.383.g050319c2ae-goog