The hwmon core now has a new optional mode interface. So this patch just implements this mode support so that user space can check and configure via sysfs node its operating modes: power-down, one-shot, and continuous modes. Signed-off-by: Nicolin Chen <nicoleotsuka@xxxxxxxxx> --- drivers/hwmon/ina3221.c | 64 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/drivers/hwmon/ina3221.c b/drivers/hwmon/ina3221.c index d61688f04594..5218fd85506d 100644 --- a/drivers/hwmon/ina3221.c +++ b/drivers/hwmon/ina3221.c @@ -77,6 +77,28 @@ enum ina3221_channels { INA3221_NUM_CHANNELS }; +enum ina3221_modes { + INA3221_MODE_POWERDOWN, + INA3221_MODE_ONESHOT, + INA3221_MODE_CONTINUOUS, + INA3221_NUM_MODES, +}; + +static const char *ina3221_mode_names[INA3221_NUM_MODES] = { + [INA3221_MODE_POWERDOWN] = "power-down", + [INA3221_MODE_ONESHOT] = "one-shot", + [INA3221_MODE_CONTINUOUS] = "continuous", +}; + +static const u16 ina3221_mode_val[] = { + [INA3221_MODE_POWERDOWN] = INA3221_CONFIG_MODE_POWERDOWN, + [INA3221_MODE_ONESHOT] = INA3221_CONFIG_MODE_SHUNT | + INA3221_CONFIG_MODE_BUS, + [INA3221_MODE_CONTINUOUS] = INA3221_CONFIG_MODE_CONTINUOUS | + INA3221_CONFIG_MODE_SHUNT | + INA3221_CONFIG_MODE_BUS, +}; + /** * struct ina3221_input - channel input source specific information * @label: label of channel input source @@ -386,9 +408,51 @@ static const struct hwmon_ops ina3221_hwmon_ops = { .write = ina3221_write, }; +static int ina3221_mode_get_index(struct device *dev, unsigned int *index) +{ + struct ina3221_data *ina = dev_get_drvdata(dev); + u16 mode = ina->reg_config & INA3221_CONFIG_MODE_MASK; + + if (mode == INA3221_CONFIG_MODE_POWERDOWN) + *index = INA3221_MODE_POWERDOWN; + if (mode & INA3221_CONFIG_MODE_CONTINUOUS) + *index = INA3221_MODE_CONTINUOUS; + else + *index = INA3221_MODE_ONESHOT; + + return 0; +} + +static int ina3221_mode_set_index(struct device *dev, unsigned int index) +{ + struct ina3221_data *ina = dev_get_drvdata(dev); + int ret; + + ret = regmap_update_bits(ina->regmap, INA3221_CONFIG, + INA3221_CONFIG_MODE_MASK, + ina3221_mode_val[index]); + if (ret) + return ret; + + /* Cache the latest config register value */ + ret = regmap_read(ina->regmap, INA3221_CONFIG, &ina->reg_config); + if (ret) + return ret; + + return 0; +} + +static const struct hwmon_mode ina3221_hwmon_mode = { + .names = ina3221_mode_names, + .list_size = INA3221_NUM_MODES, + .get_index = ina3221_mode_get_index, + .set_index = ina3221_mode_set_index, +}; + static const struct hwmon_chip_info ina3221_chip_info = { .ops = &ina3221_hwmon_ops, .info = ina3221_info, + .mode = &ina3221_hwmon_mode, }; /* Extra attribute groups */ -- 2.17.1