hwmon: (pmbus) Introduce and use write_byte_data callback
authorMårten Lindahl <marten.lindahl@axis.com>
Thu, 28 Apr 2022 14:40:36 +0000 (16:40 +0200)
committerGuenter Roeck <linux@roeck-us.net>
Fri, 20 May 2022 17:57:06 +0000 (10:57 -0700)
Some of the pmbus core functions uses pmbus_write_byte_data, which does
not support driver callbacks for chip specific write operations. This
could potentially influence some specific regulator chips that for
example need a time delay before each data access.

Lets add support for driver callback with _pmbus_write_byte_data.

Signed-off-by: Mårten Lindahl <marten.lindahl@axis.com>
Link: https://lore.kernel.org/r/20220428144039.2464667-2-marten.lindahl@axis.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
drivers/hwmon/pmbus/pmbus.h
drivers/hwmon/pmbus/pmbus_core.c

index e74b6ef..c031a97 100644 (file)
@@ -438,6 +438,8 @@ struct pmbus_driver_info {
        int (*read_byte_data)(struct i2c_client *client, int page, int reg);
        int (*read_word_data)(struct i2c_client *client, int page, int phase,
                              int reg);
+       int (*write_byte_data)(struct i2c_client *client, int page, int reg,
+                             u8 byte);
        int (*write_word_data)(struct i2c_client *client, int page, int reg,
                               u16 word);
        int (*write_byte)(struct i2c_client *client, int page, u8 value);
index d93574d..e7235d5 100644 (file)
@@ -276,6 +276,24 @@ static int _pmbus_write_word_data(struct i2c_client *client, int page, int reg,
        return pmbus_write_word_data(client, page, reg, word);
 }
 
+/*
+ * _pmbus_write_byte_data() is similar to pmbus_write_byte_data(), but checks if
+ * a device specific mapping function exists and calls it if necessary.
+ */
+static int _pmbus_write_byte_data(struct i2c_client *client, int page, int reg, u8 value)
+{
+       struct pmbus_data *data = i2c_get_clientdata(client);
+       const struct pmbus_driver_info *info = data->info;
+       int status;
+
+       if (info->write_byte_data) {
+               status = info->write_byte_data(client, page, reg, value);
+               if (status != -ENODATA)
+                       return status;
+       }
+       return pmbus_write_byte_data(client, page, reg, value);
+}
+
 int pmbus_update_fan(struct i2c_client *client, int page, int id,
                     u8 config, u8 mask, u16 command)
 {
@@ -290,7 +308,7 @@ int pmbus_update_fan(struct i2c_client *client, int page, int id,
 
        to = (from & ~mask) | (config & mask);
        if (to != from) {
-               rv = pmbus_write_byte_data(client, page,
+               rv = _pmbus_write_byte_data(client, page,
                                           pmbus_fan_config_registers[id], to);
                if (rv < 0)
                        return rv;
@@ -397,7 +415,7 @@ int pmbus_update_byte_data(struct i2c_client *client, int page, u8 reg,
        tmp = (rv & ~mask) | (value & mask);
 
        if (tmp != rv)
-               rv = pmbus_write_byte_data(client, page, reg, tmp);
+               rv = _pmbus_write_byte_data(client, page, reg, tmp);
 
        return rv;
 }
@@ -912,7 +930,7 @@ static int pmbus_get_boolean(struct i2c_client *client, struct pmbus_boolean *b,
 
        regval = status & mask;
        if (regval) {
-               ret = pmbus_write_byte_data(client, page, reg, regval);
+               ret = _pmbus_write_byte_data(client, page, reg, regval);
                if (ret)
                        goto unlock;
        }