lkml.org 
[lkml]   [2022]   [Jun]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.18 198/879] hwmon: (pmbus) Add get_voltage/set_voltage ops
    Date
    From: Mårten Lindahl <marten.lindahl@axis.com>

    [ Upstream commit 28bf22ef93eceb42c7583f0909bc9dedc07770e3 ]

    The pmbus core does not have operations for getting or setting voltage.
    Add functions get/set voltage for the dynamic regulator framework.

    Signed-off-by: Mårten Lindahl <marten.lindahl@axis.com>
    Link: https://lore.kernel.org/r/20220503104631.3515715-5-marten.lindahl@axis.com
    [groeck: cosmetic alignment / empty line fixes]
    Signed-off-by: Guenter Roeck <linux@roeck-us.net>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/hwmon/pmbus/pmbus_core.c | 67 ++++++++++++++++++++++++++++++++
    1 file changed, 67 insertions(+)

    diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c
    index d93574d6a1fb..5a1796650f5b 100644
    --- a/drivers/hwmon/pmbus/pmbus_core.c
    +++ b/drivers/hwmon/pmbus/pmbus_core.c
    @@ -2548,11 +2548,78 @@ static int pmbus_regulator_get_error_flags(struct regulator_dev *rdev, unsigned
    return 0;
    }

    +static int pmbus_regulator_get_voltage(struct regulator_dev *rdev)
    +{
    + struct device *dev = rdev_get_dev(rdev);
    + struct i2c_client *client = to_i2c_client(dev->parent);
    + struct pmbus_data *data = i2c_get_clientdata(client);
    + struct pmbus_sensor s = {
    + .page = rdev_get_id(rdev),
    + .class = PSC_VOLTAGE_OUT,
    + .convert = true,
    + };
    +
    + s.data = _pmbus_read_word_data(client, s.page, 0xff, PMBUS_READ_VOUT);
    + if (s.data < 0)
    + return s.data;
    +
    + return (int)pmbus_reg2data(data, &s) * 1000; /* unit is uV */
    +}
    +
    +static int pmbus_regulator_set_voltage(struct regulator_dev *rdev, int min_uv,
    + int max_uv, unsigned int *selector)
    +{
    + struct device *dev = rdev_get_dev(rdev);
    + struct i2c_client *client = to_i2c_client(dev->parent);
    + struct pmbus_data *data = i2c_get_clientdata(client);
    + struct pmbus_sensor s = {
    + .page = rdev_get_id(rdev),
    + .class = PSC_VOLTAGE_OUT,
    + .convert = true,
    + .data = -1,
    + };
    + int val = DIV_ROUND_CLOSEST(min_uv, 1000); /* convert to mV */
    + int low, high;
    +
    + *selector = 0;
    +
    + if (pmbus_check_word_register(client, s.page, PMBUS_MFR_VOUT_MIN))
    + s.data = _pmbus_read_word_data(client, s.page, 0xff, PMBUS_MFR_VOUT_MIN);
    + if (s.data < 0) {
    + s.data = _pmbus_read_word_data(client, s.page, 0xff, PMBUS_VOUT_MARGIN_LOW);
    + if (s.data < 0)
    + return s.data;
    + }
    + low = pmbus_reg2data(data, &s);
    +
    + s.data = -1;
    + if (pmbus_check_word_register(client, s.page, PMBUS_MFR_VOUT_MAX))
    + s.data = _pmbus_read_word_data(client, s.page, 0xff, PMBUS_MFR_VOUT_MAX);
    + if (s.data < 0) {
    + s.data = _pmbus_read_word_data(client, s.page, 0xff, PMBUS_VOUT_MARGIN_HIGH);
    + if (s.data < 0)
    + return s.data;
    + }
    + high = pmbus_reg2data(data, &s);
    +
    + /* Make sure we are within margins */
    + if (low > val)
    + val = low;
    + if (high < val)
    + val = high;
    +
    + val = pmbus_data2reg(data, &s, val);
    +
    + return _pmbus_write_word_data(client, s.page, PMBUS_VOUT_COMMAND, (u16)val);
    +}
    +
    const struct regulator_ops pmbus_regulator_ops = {
    .enable = pmbus_regulator_enable,
    .disable = pmbus_regulator_disable,
    .is_enabled = pmbus_regulator_is_enabled,
    .get_error_flags = pmbus_regulator_get_error_flags,
    + .get_voltage = pmbus_regulator_get_voltage,
    + .set_voltage = pmbus_regulator_set_voltage,
    };
    EXPORT_SYMBOL_NS_GPL(pmbus_regulator_ops, PMBUS);

    --
    2.35.1


    \
     
     \ /
      Last update: 2022-06-08 00:33    [W:4.050 / U:0.324 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site