lkml.org 
[lkml]   [2021]   [Jul]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.13 320/800] hwmon: (pmbus/bpa-rs600) Handle Vin readings >= 256V
    Date
    From: Chris Packham <chris.packham@alliedtelesis.co.nz>

    [ Upstream commit 6e9ef8ca687e69e9d4cc89033d98e06350b0f3e0 ]

    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: 15b2703e5e02 ("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>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/hwmon/pmbus/bpa-rs600.c | 29 +++++++++++++++++++++++++++++
    1 file changed, 29 insertions(+)

    diff --git a/drivers/hwmon/pmbus/bpa-rs600.c b/drivers/hwmon/pmbus/bpa-rs600.c
    index f6558ee9dec3..2be69fedfa36 100644
    --- a/drivers/hwmon/pmbus/bpa-rs600.c
    +++ b/drivers/hwmon/pmbus/bpa-rs600.c
    @@ -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;
    --
    2.30.2


    \
     
     \ /
      Last update: 2021-07-12 10:30    [W:2.109 / U:0.408 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site