mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-28 21:33:52 +00:00
hwmon: (pmbus/bpa-rs600) Handle Vin readings >= 256V
The BPA-RS600 doesn't follow the PMBus spec for linear data.
Specifically it treats the mantissa as an unsigned 11-bit value instead
of a two's complement 11-bit value. At this point it's unclear whether
this only affects Vin or if Pin/Pout1 are affected as well. Erring on
the side of caution only Vin is dealt with here.
Fixes: 15b2703e5e
("hwmon: (pmbus) Add driver for BluTek BPA-RS600")
Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
Link: https://lore.kernel.org/r/20210616034218.25821-1-chris.packham@alliedtelesis.co.nz
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
This commit is contained in:
parent
009c9aa5be
commit
6e9ef8ca68
1 changed files with 29 additions and 0 deletions
|
@ -46,6 +46,32 @@ static int bpa_rs600_read_byte_data(struct i2c_client *client, int page, int reg
|
|||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* The BPA-RS600 violates the PMBus spec. Specifically it treats the
|
||||
* mantissa as unsigned. Deal with this here to allow the PMBus core
|
||||
* to work with correctly encoded data.
|
||||
*/
|
||||
static int bpa_rs600_read_vin(struct i2c_client *client)
|
||||
{
|
||||
int ret, exponent, mantissa;
|
||||
|
||||
ret = pmbus_read_word_data(client, 0, 0xff, PMBUS_READ_VIN);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (ret & BIT(10)) {
|
||||
exponent = ret >> 11;
|
||||
mantissa = ret & 0x7ff;
|
||||
|
||||
exponent++;
|
||||
mantissa >>= 1;
|
||||
|
||||
ret = (exponent << 11) | mantissa;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int bpa_rs600_read_word_data(struct i2c_client *client, int page, int phase, int reg)
|
||||
{
|
||||
int ret;
|
||||
|
@ -85,6 +111,9 @@ static int bpa_rs600_read_word_data(struct i2c_client *client, int page, int pha
|
|||
/* These commands return data but it is invalid/un-documented */
|
||||
ret = -ENXIO;
|
||||
break;
|
||||
case PMBUS_READ_VIN:
|
||||
ret = bpa_rs600_read_vin(client);
|
||||
break;
|
||||
default:
|
||||
if (reg >= PMBUS_VIRT_BASE)
|
||||
ret = -ENXIO;
|
||||
|
|
Loading…
Reference in a new issue