On Thu, Apr 29, 2021 at 09:53:38AM +0200, Václav Kubernát wrote: > I didn't properly test the driver for YH-5151E, so it was completely > broken. Firstly, the log/real mapping was incorrect in one case. > Secondly, PMBus specifies that output voltages should be in the linear16 > encoding. However, the YH-5151E is non-compliant and uses linear11. > YM-2151E isn't affected by this. Fix this by converting the values > inside the read functions. linear16 gets the exponent from the VOUT_MODE > command. The device doesn't support it, so I have to manually supply the > value for it. > > Both supported devices have now been tested to report correct vout > values. > > Fixes: 1734b4135a62 ("hwmon: Add driver for fsp-3y PSUs and PDUs") > Signed-off-by: Václav Kubernát <kubernat@xxxxxxxxx> Applied. Thanks, Guenter > --- > drivers/hwmon/pmbus/fsp-3y.c | 27 +++++++++++++++++++++++++-- > 1 file changed, 25 insertions(+), 2 deletions(-) > > diff --git a/drivers/hwmon/pmbus/fsp-3y.c b/drivers/hwmon/pmbus/fsp-3y.c > index 564649e87e34..655690dde4d7 100644 > --- a/drivers/hwmon/pmbus/fsp-3y.c > +++ b/drivers/hwmon/pmbus/fsp-3y.c > @@ -57,7 +57,7 @@ static int page_log_to_page_real(int page_log, enum chips chip) > case YH5151E_PAGE_12V_LOG: > return YH5151E_PAGE_12V_REAL; > case YH5151E_PAGE_5V_LOG: > - return YH5151E_PAGE_5V_LOG; > + return YH5151E_PAGE_5V_REAL; > case YH5151E_PAGE_3V3_LOG: > return YH5151E_PAGE_3V3_REAL; > } > @@ -103,8 +103,18 @@ static int set_page(struct i2c_client *client, int page_log) > > static int fsp3y_read_byte_data(struct i2c_client *client, int page, int reg) > { > + const struct pmbus_driver_info *info = pmbus_get_driver_info(client); > + struct fsp3y_data *data = to_fsp3y_data(info); > int rv; > > + /* > + * YH5151-E outputs vout in linear11. The conversion is done when > + * reading. Here, we have to inject pmbus_core with the correct > + * exponent (it is -6). > + */ > + if (data->chip == yh5151e && reg == PMBUS_VOUT_MODE) > + return 0x1A; > + > rv = set_page(client, page); > if (rv < 0) > return rv; > @@ -114,6 +124,8 @@ static int fsp3y_read_byte_data(struct i2c_client *client, int page, int reg) > > static int fsp3y_read_word_data(struct i2c_client *client, int page, int phase, int reg) > { > + const struct pmbus_driver_info *info = pmbus_get_driver_info(client); > + struct fsp3y_data *data = to_fsp3y_data(info); > int rv; > > /* > @@ -144,7 +156,18 @@ static int fsp3y_read_word_data(struct i2c_client *client, int page, int phase, > if (rv < 0) > return rv; > > - return i2c_smbus_read_word_data(client, reg); > + rv = i2c_smbus_read_word_data(client, reg); > + if (rv < 0) > + return rv; > + > + /* > + * YH-5151E is non-compliant and outputs output voltages in linear11 > + * instead of linear16. > + */ > + if (data->chip == yh5151e && reg == PMBUS_READ_VOUT) > + rv = sign_extend32(rv, 10) & 0xffff; > + > + return rv; > } > > struct pmbus_driver_info fsp3y_info[] = {