Register custom sysfs attribute to be registered by pmbus allowing read/write access to the manufacturer specific SAMPLES_FOR_AVG register. This register allows setting the number of samples used in computing the average values (PMBUS_VIRT_READ_*_AVG). The number we write is an exponent of base 2 of the number of samples so for example writing 3 will result in 8 samples average. Signed-off-by: Krzysztof Adamski <krzysztof.adamski@xxxxxxxxx> --- drivers/hwmon/pmbus/lm25066.c | 45 +++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/drivers/hwmon/pmbus/lm25066.c b/drivers/hwmon/pmbus/lm25066.c index 53db78753a0d..c78af0a7e5ff 100644 --- a/drivers/hwmon/pmbus/lm25066.c +++ b/drivers/hwmon/pmbus/lm25066.c @@ -26,6 +26,7 @@ #include <linux/err.h> #include <linux/slab.h> #include <linux/i2c.h> +#include <linux/log2.h> #include "pmbus.h" enum chips { lm25056, lm25066, lm5064, lm5066, lm5066i }; @@ -38,6 +39,7 @@ enum chips { lm25056, lm25066, lm5064, lm5066, lm5066i }; #define LM25066_READ_PIN_PEAK 0xd5 #define LM25066_CLEAR_PIN_PEAK 0xd6 #define LM25066_DEVICE_SETUP 0xd9 +#define LM25066_SAMPLES_FOR_AVG 0xdb #define LM25066_READ_AVG_VIN 0xdc #define LM25066_READ_AVG_VOUT 0xdd #define LM25066_READ_AVG_IIN 0xde @@ -405,6 +407,47 @@ static int lm25066_write_word_data(struct i2c_client *client, int page, int reg, return ret; } +static ssize_t samples_for_avg_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev->parent); + int ret; + + ret = pmbus_read_byte_data(client, 0, LM25066_SAMPLES_FOR_AVG); + if (ret < 0) + return ret; + + return sprintf(buf, "%d\n", 1 << ret); +} + +static ssize_t samples_for_avg_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev->parent); + int ret, val; + + ret = kstrtoint(buf, 0, &val); + if (ret < 0) + return ret; + + ret = pmbus_write_byte_data(client, 0, LM25066_SAMPLES_FOR_AVG, + ilog2(val)); + if (ret < 0) + return ret; + + return count; +} + +static DEVICE_ATTR_RW(samples_for_avg); + +static struct attribute *lm25056_attrs[] = { + &dev_attr_samples_for_avg.attr, + NULL, +}; +ATTRIBUTE_GROUPS(lm25056); // should we set a name of this group to put all + // those attributes in subdirectory? Like "custom" ? + static int lm25066_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -476,6 +519,8 @@ static int lm25066_probe(struct i2c_client *client, info->b[PSC_POWER] = coeff[PSC_POWER].b; } + info->groups = lm25056_groups; + return pmbus_do_probe(client, id, info); } -- 2.20.1