summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/hwmon/ina3221.rst13
-rw-r--r--drivers/hwmon/ina3221.c58
2 files changed, 63 insertions, 8 deletions
diff --git a/Documentation/hwmon/ina3221.rst b/Documentation/hwmon/ina3221.rst
index 1e34abb38b59..f6007ae8f4e2 100644
--- a/Documentation/hwmon/ina3221.rst
+++ b/Documentation/hwmon/ina3221.rst
@@ -46,4 +46,17 @@ samples Number of samples using in the averaging mode.
46 Supports the list of number of samples: 46 Supports the list of number of samples:
47 47
48 1, 4, 16, 64, 128, 256, 512, 1024 48 1, 4, 16, 64, 128, 256, 512, 1024
49
50update_interval Data conversion time in millisecond, following:
51
52 update_interval = C x S x (BC + SC)
53
54 * C: number of enabled channels
55 * S: number of samples
56 * BC: bus-voltage conversion time in millisecond
57 * SC: shunt-voltage conversion time in millisecond
58
59 Affects both Bus- and Shunt-voltage conversion time.
60 Note that setting update_interval to 0ms sets both BC
61 and SC to 140 us (minimum conversion time).
49======================= ======================================================= 62======================= =======================================================
diff --git a/drivers/hwmon/ina3221.c b/drivers/hwmon/ina3221.c
index 62040aac653c..e0637fed9585 100644
--- a/drivers/hwmon/ina3221.c
+++ b/drivers/hwmon/ina3221.c
@@ -144,19 +144,37 @@ static const int ina3221_avg_samples[] = {
144 1, 4, 16, 64, 128, 256, 512, 1024, 144 1, 4, 16, 64, 128, 256, 512, 1024,
145}; 145};
146 146
147static inline int ina3221_wait_for_data(struct ina3221_data *ina) 147/* Converting update_interval in msec to conversion time in usec */
148static inline u32 ina3221_interval_ms_to_conv_time(u16 config, int interval)
149{
150 u32 channels = hweight16(config & INA3221_CONFIG_CHs_EN_MASK);
151 u32 samples_idx = INA3221_CONFIG_AVG(config);
152 u32 samples = ina3221_avg_samples[samples_idx];
153
154 /* Bisect the result to Bus and Shunt conversion times */
155 return DIV_ROUND_CLOSEST(interval * 1000 / 2, channels * samples);
156}
157
158/* Converting CONFIG register value to update_interval in usec */
159static inline u32 ina3221_reg_to_interval_us(u16 config)
148{ 160{
149 u32 channels = hweight16(ina->reg_config & INA3221_CONFIG_CHs_EN_MASK); 161 u32 channels = hweight16(config & INA3221_CONFIG_CHs_EN_MASK);
150 u32 vbus_ct_idx = INA3221_CONFIG_VBUS_CT(ina->reg_config); 162 u32 vbus_ct_idx = INA3221_CONFIG_VBUS_CT(config);
151 u32 vsh_ct_idx = INA3221_CONFIG_VSH_CT(ina->reg_config); 163 u32 vsh_ct_idx = INA3221_CONFIG_VSH_CT(config);
152 u32 samples_idx = INA3221_CONFIG_AVG(ina->reg_config); 164 u32 samples_idx = INA3221_CONFIG_AVG(config);
153 u32 samples = ina3221_avg_samples[samples_idx]; 165 u32 samples = ina3221_avg_samples[samples_idx];
154 u32 vbus_ct = ina3221_conv_time[vbus_ct_idx]; 166 u32 vbus_ct = ina3221_conv_time[vbus_ct_idx];
155 u32 vsh_ct = ina3221_conv_time[vsh_ct_idx]; 167 u32 vsh_ct = ina3221_conv_time[vsh_ct_idx];
156 u32 wait, cvrf;
157 168
158 /* Calculate total conversion time */ 169 /* Calculate total conversion time */
159 wait = channels * (vbus_ct + vsh_ct) * samples; 170 return channels * (vbus_ct + vsh_ct) * samples;
171}
172
173static inline int ina3221_wait_for_data(struct ina3221_data *ina)
174{
175 u32 wait, cvrf;
176
177 wait = ina3221_reg_to_interval_us(ina->reg_config);
160 178
161 /* Polling the CVRF bit to make sure read data is ready */ 179 /* Polling the CVRF bit to make sure read data is ready */
162 return regmap_field_read_poll_timeout(ina->fields[F_CVRF], 180 return regmap_field_read_poll_timeout(ina->fields[F_CVRF],
@@ -197,6 +215,11 @@ static int ina3221_read_chip(struct device *dev, u32 attr, long *val)
197 regval = INA3221_CONFIG_AVG(ina->reg_config); 215 regval = INA3221_CONFIG_AVG(ina->reg_config);
198 *val = ina3221_avg_samples[regval]; 216 *val = ina3221_avg_samples[regval];
199 return 0; 217 return 0;
218 case hwmon_chip_update_interval:
219 /* Return in msec */
220 *val = ina3221_reg_to_interval_us(ina->reg_config);
221 *val = DIV_ROUND_CLOSEST(*val, 1000);
222 return 0;
200 default: 223 default:
201 return -EOPNOTSUPP; 224 return -EOPNOTSUPP;
202 } 225 }
@@ -325,6 +348,23 @@ static int ina3221_write_chip(struct device *dev, u32 attr, long val)
325 /* Update reg_config accordingly */ 348 /* Update reg_config accordingly */
326 ina->reg_config = tmp; 349 ina->reg_config = tmp;
327 return 0; 350 return 0;
351 case hwmon_chip_update_interval:
352 tmp = ina3221_interval_ms_to_conv_time(ina->reg_config, val);
353 idx = find_closest(tmp, ina3221_conv_time,
354 ARRAY_SIZE(ina3221_conv_time));
355
356 /* Update Bus and Shunt voltage conversion times */
357 tmp = INA3221_CONFIG_VBUS_CT_MASK | INA3221_CONFIG_VSH_CT_MASK;
358 tmp = (ina->reg_config & ~tmp) |
359 (idx << INA3221_CONFIG_VBUS_CT_SHIFT) |
360 (idx << INA3221_CONFIG_VSH_CT_SHIFT);
361 ret = regmap_write(ina->regmap, INA3221_CONFIG, tmp);
362 if (ret)
363 return ret;
364
365 /* Update reg_config accordingly */
366 ina->reg_config = tmp;
367 return 0;
328 default: 368 default:
329 return -EOPNOTSUPP; 369 return -EOPNOTSUPP;
330 } 370 }
@@ -483,6 +523,7 @@ static umode_t ina3221_is_visible(const void *drvdata,
483 case hwmon_chip: 523 case hwmon_chip:
484 switch (attr) { 524 switch (attr) {
485 case hwmon_chip_samples: 525 case hwmon_chip_samples:
526 case hwmon_chip_update_interval:
486 return 0644; 527 return 0644;
487 default: 528 default:
488 return 0; 529 return 0;
@@ -528,7 +569,8 @@ static umode_t ina3221_is_visible(const void *drvdata,
528 569
529static const struct hwmon_channel_info *ina3221_info[] = { 570static const struct hwmon_channel_info *ina3221_info[] = {
530 HWMON_CHANNEL_INFO(chip, 571 HWMON_CHANNEL_INFO(chip,
531 HWMON_C_SAMPLES), 572 HWMON_C_SAMPLES,
573 HWMON_C_UPDATE_INTERVAL),
532 HWMON_CHANNEL_INFO(in, 574 HWMON_CHANNEL_INFO(in,
533 /* 0: dummy, skipped in is_visible */ 575 /* 0: dummy, skipped in is_visible */
534 HWMON_I_INPUT, 576 HWMON_I_INPUT,