2 * INA3221 Triple Current/Voltage Monitor
4 * Copyright (C) 2016 Texas Instruments Incorporated - http://www.ti.com/
5 * Andrew F. Davis <afd@ti.com>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
17 #include <linux/hwmon.h>
18 #include <linux/hwmon-sysfs.h>
19 #include <linux/i2c.h>
20 #include <linux/module.h>
22 #include <linux/regmap.h>
24 #define INA3221_DRIVER_NAME "ina3221"
26 #define INA3221_CONFIG 0x00
27 #define INA3221_SHUNT1 0x01
28 #define INA3221_BUS1 0x02
29 #define INA3221_SHUNT2 0x03
30 #define INA3221_BUS2 0x04
31 #define INA3221_SHUNT3 0x05
32 #define INA3221_BUS3 0x06
33 #define INA3221_CRIT1 0x07
34 #define INA3221_WARN1 0x08
35 #define INA3221_CRIT2 0x09
36 #define INA3221_WARN2 0x0a
37 #define INA3221_CRIT3 0x0b
38 #define INA3221_WARN3 0x0c
39 #define INA3221_MASK_ENABLE 0x0f
41 #define INA3221_CONFIG_MODE_SHUNT BIT(1)
42 #define INA3221_CONFIG_MODE_BUS BIT(2)
43 #define INA3221_CONFIG_MODE_CONTINUOUS BIT(3)
45 #define INA3221_RSHUNT_DEFAULT 10000
59 static const struct reg_field ina3221_reg_fields
[] = {
60 [F_RST
] = REG_FIELD(INA3221_CONFIG
, 15, 15),
62 [F_WF3
] = REG_FIELD(INA3221_MASK_ENABLE
, 3, 3),
63 [F_WF2
] = REG_FIELD(INA3221_MASK_ENABLE
, 4, 4),
64 [F_WF1
] = REG_FIELD(INA3221_MASK_ENABLE
, 5, 5),
65 [F_CF3
] = REG_FIELD(INA3221_MASK_ENABLE
, 7, 7),
66 [F_CF2
] = REG_FIELD(INA3221_MASK_ENABLE
, 8, 8),
67 [F_CF1
] = REG_FIELD(INA3221_MASK_ENABLE
, 9, 9),
70 enum ina3221_channels
{
77 static const unsigned int register_channel
[] = {
78 [INA3221_SHUNT1
] = INA3221_CHANNEL1
,
79 [INA3221_SHUNT2
] = INA3221_CHANNEL2
,
80 [INA3221_SHUNT3
] = INA3221_CHANNEL3
,
81 [INA3221_CRIT1
] = INA3221_CHANNEL1
,
82 [INA3221_CRIT2
] = INA3221_CHANNEL2
,
83 [INA3221_CRIT3
] = INA3221_CHANNEL3
,
84 [INA3221_WARN1
] = INA3221_CHANNEL1
,
85 [INA3221_WARN2
] = INA3221_CHANNEL2
,
86 [INA3221_WARN3
] = INA3221_CHANNEL3
,
90 * struct ina3221_data - device specific information
91 * @regmap: Register map of the device
92 * @fields: Register fields of the device
93 * @shunt_resistors: Array of resistor values per channel
96 struct regmap
*regmap
;
97 struct regmap_field
*fields
[F_MAX_FIELDS
];
98 int shunt_resistors
[INA3221_NUM_CHANNELS
];
101 static int ina3221_read_value(struct ina3221_data
*ina
, unsigned int reg
,
107 ret
= regmap_read(ina
->regmap
, reg
, ®val
);
111 *val
= sign_extend32(regval
>> 3, 12);
116 static ssize_t
ina3221_show_bus_voltage(struct device
*dev
,
117 struct device_attribute
*attr
,
120 struct sensor_device_attribute
*sd_attr
= to_sensor_dev_attr(attr
);
121 struct ina3221_data
*ina
= dev_get_drvdata(dev
);
122 unsigned int reg
= sd_attr
->index
;
123 int val
, voltage_mv
, ret
;
125 ret
= ina3221_read_value(ina
, reg
, &val
);
129 voltage_mv
= val
* 8;
131 return snprintf(buf
, PAGE_SIZE
, "%d\n", voltage_mv
);
134 static ssize_t
ina3221_show_shunt_voltage(struct device
*dev
,
135 struct device_attribute
*attr
,
138 struct sensor_device_attribute
*sd_attr
= to_sensor_dev_attr(attr
);
139 struct ina3221_data
*ina
= dev_get_drvdata(dev
);
140 unsigned int reg
= sd_attr
->index
;
141 int val
, voltage_uv
, ret
;
143 ret
= ina3221_read_value(ina
, reg
, &val
);
146 voltage_uv
= val
* 40;
148 return snprintf(buf
, PAGE_SIZE
, "%d\n", voltage_uv
);
151 static ssize_t
ina3221_show_current(struct device
*dev
,
152 struct device_attribute
*attr
, char *buf
)
154 struct sensor_device_attribute
*sd_attr
= to_sensor_dev_attr(attr
);
155 struct ina3221_data
*ina
= dev_get_drvdata(dev
);
156 unsigned int reg
= sd_attr
->index
;
157 unsigned int channel
= register_channel
[reg
];
158 int resistance_uo
= ina
->shunt_resistors
[channel
];
159 int val
, current_ma
, voltage_nv
, ret
;
161 ret
= ina3221_read_value(ina
, reg
, &val
);
164 voltage_nv
= val
* 40000;
166 current_ma
= DIV_ROUND_CLOSEST(voltage_nv
, resistance_uo
);
168 return snprintf(buf
, PAGE_SIZE
, "%d\n", current_ma
);
171 static ssize_t
ina3221_set_current(struct device
*dev
,
172 struct device_attribute
*attr
,
173 const char *buf
, size_t count
)
175 struct sensor_device_attribute
*sd_attr
= to_sensor_dev_attr(attr
);
176 struct ina3221_data
*ina
= dev_get_drvdata(dev
);
177 unsigned int reg
= sd_attr
->index
;
178 unsigned int channel
= register_channel
[reg
];
179 int resistance_uo
= ina
->shunt_resistors
[channel
];
180 int val
, current_ma
, voltage_uv
, ret
;
182 ret
= kstrtoint(buf
, 0, ¤t_ma
);
187 current_ma
= clamp_val(current_ma
,
188 INT_MIN
/ resistance_uo
,
189 INT_MAX
/ resistance_uo
);
191 voltage_uv
= DIV_ROUND_CLOSEST(current_ma
* resistance_uo
, 1000);
194 voltage_uv
= clamp_val(voltage_uv
, -163800, 163800);
196 /* 1 / 40uV(scale) << 3(register shift) = 5 */
197 val
= DIV_ROUND_CLOSEST(voltage_uv
, 5) & 0xfff8;
199 ret
= regmap_write(ina
->regmap
, reg
, val
);
206 static ssize_t
ina3221_show_shunt(struct device
*dev
,
207 struct device_attribute
*attr
, char *buf
)
209 struct sensor_device_attribute
*sd_attr
= to_sensor_dev_attr(attr
);
210 struct ina3221_data
*ina
= dev_get_drvdata(dev
);
211 unsigned int channel
= sd_attr
->index
;
212 unsigned int resistance_uo
;
214 resistance_uo
= ina
->shunt_resistors
[channel
];
216 return snprintf(buf
, PAGE_SIZE
, "%d\n", resistance_uo
);
219 static ssize_t
ina3221_set_shunt(struct device
*dev
,
220 struct device_attribute
*attr
,
221 const char *buf
, size_t count
)
223 struct sensor_device_attribute
*sd_attr
= to_sensor_dev_attr(attr
);
224 struct ina3221_data
*ina
= dev_get_drvdata(dev
);
225 unsigned int channel
= sd_attr
->index
;
229 ret
= kstrtoint(buf
, 0, &val
);
233 val
= clamp_val(val
, 1, INT_MAX
);
235 ina
->shunt_resistors
[channel
] = val
;
240 static ssize_t
ina3221_show_alert(struct device
*dev
,
241 struct device_attribute
*attr
, char *buf
)
243 struct sensor_device_attribute
*sd_attr
= to_sensor_dev_attr(attr
);
244 struct ina3221_data
*ina
= dev_get_drvdata(dev
);
245 unsigned int field
= sd_attr
->index
;
249 ret
= regmap_field_read(ina
->fields
[field
], ®val
);
253 return snprintf(buf
, PAGE_SIZE
, "%d\n", regval
);
257 static SENSOR_DEVICE_ATTR(in1_input
, S_IRUGO
,
258 ina3221_show_bus_voltage
, NULL
, INA3221_BUS1
);
259 static SENSOR_DEVICE_ATTR(in2_input
, S_IRUGO
,
260 ina3221_show_bus_voltage
, NULL
, INA3221_BUS2
);
261 static SENSOR_DEVICE_ATTR(in3_input
, S_IRUGO
,
262 ina3221_show_bus_voltage
, NULL
, INA3221_BUS3
);
264 /* calculated current */
265 static SENSOR_DEVICE_ATTR(curr1_input
, S_IRUGO
,
266 ina3221_show_current
, NULL
, INA3221_SHUNT1
);
267 static SENSOR_DEVICE_ATTR(curr2_input
, S_IRUGO
,
268 ina3221_show_current
, NULL
, INA3221_SHUNT2
);
269 static SENSOR_DEVICE_ATTR(curr3_input
, S_IRUGO
,
270 ina3221_show_current
, NULL
, INA3221_SHUNT3
);
272 /* shunt resistance */
273 static SENSOR_DEVICE_ATTR(shunt1_resistor
, S_IRUGO
| S_IWUSR
,
274 ina3221_show_shunt
, ina3221_set_shunt
, INA3221_CHANNEL1
);
275 static SENSOR_DEVICE_ATTR(shunt2_resistor
, S_IRUGO
| S_IWUSR
,
276 ina3221_show_shunt
, ina3221_set_shunt
, INA3221_CHANNEL2
);
277 static SENSOR_DEVICE_ATTR(shunt3_resistor
, S_IRUGO
| S_IWUSR
,
278 ina3221_show_shunt
, ina3221_set_shunt
, INA3221_CHANNEL3
);
280 /* critical current */
281 static SENSOR_DEVICE_ATTR(curr1_crit
, S_IRUGO
| S_IWUSR
,
282 ina3221_show_current
, ina3221_set_current
, INA3221_CRIT1
);
283 static SENSOR_DEVICE_ATTR(curr2_crit
, S_IRUGO
| S_IWUSR
,
284 ina3221_show_current
, ina3221_set_current
, INA3221_CRIT2
);
285 static SENSOR_DEVICE_ATTR(curr3_crit
, S_IRUGO
| S_IWUSR
,
286 ina3221_show_current
, ina3221_set_current
, INA3221_CRIT3
);
288 /* critical current alert */
289 static SENSOR_DEVICE_ATTR(curr1_crit_alarm
, S_IRUGO
,
290 ina3221_show_alert
, NULL
, F_CF1
);
291 static SENSOR_DEVICE_ATTR(curr2_crit_alarm
, S_IRUGO
,
292 ina3221_show_alert
, NULL
, F_CF2
);
293 static SENSOR_DEVICE_ATTR(curr3_crit_alarm
, S_IRUGO
,
294 ina3221_show_alert
, NULL
, F_CF3
);
296 /* warning current */
297 static SENSOR_DEVICE_ATTR(curr1_max
, S_IRUGO
| S_IWUSR
,
298 ina3221_show_current
, ina3221_set_current
, INA3221_WARN1
);
299 static SENSOR_DEVICE_ATTR(curr2_max
, S_IRUGO
| S_IWUSR
,
300 ina3221_show_current
, ina3221_set_current
, INA3221_WARN2
);
301 static SENSOR_DEVICE_ATTR(curr3_max
, S_IRUGO
| S_IWUSR
,
302 ina3221_show_current
, ina3221_set_current
, INA3221_WARN3
);
304 /* warning current alert */
305 static SENSOR_DEVICE_ATTR(curr1_max_alarm
, S_IRUGO
,
306 ina3221_show_alert
, NULL
, F_WF1
);
307 static SENSOR_DEVICE_ATTR(curr2_max_alarm
, S_IRUGO
,
308 ina3221_show_alert
, NULL
, F_WF2
);
309 static SENSOR_DEVICE_ATTR(curr3_max_alarm
, S_IRUGO
,
310 ina3221_show_alert
, NULL
, F_WF3
);
313 static SENSOR_DEVICE_ATTR(in4_input
, S_IRUGO
,
314 ina3221_show_shunt_voltage
, NULL
, INA3221_SHUNT1
);
315 static SENSOR_DEVICE_ATTR(in5_input
, S_IRUGO
,
316 ina3221_show_shunt_voltage
, NULL
, INA3221_SHUNT2
);
317 static SENSOR_DEVICE_ATTR(in6_input
, S_IRUGO
,
318 ina3221_show_shunt_voltage
, NULL
, INA3221_SHUNT3
);
320 static struct attribute
*ina3221_attrs
[] = {
322 &sensor_dev_attr_in1_input
.dev_attr
.attr
,
323 &sensor_dev_attr_curr1_input
.dev_attr
.attr
,
324 &sensor_dev_attr_shunt1_resistor
.dev_attr
.attr
,
325 &sensor_dev_attr_curr1_crit
.dev_attr
.attr
,
326 &sensor_dev_attr_curr1_crit_alarm
.dev_attr
.attr
,
327 &sensor_dev_attr_curr1_max
.dev_attr
.attr
,
328 &sensor_dev_attr_curr1_max_alarm
.dev_attr
.attr
,
329 &sensor_dev_attr_in4_input
.dev_attr
.attr
,
332 &sensor_dev_attr_in2_input
.dev_attr
.attr
,
333 &sensor_dev_attr_curr2_input
.dev_attr
.attr
,
334 &sensor_dev_attr_shunt2_resistor
.dev_attr
.attr
,
335 &sensor_dev_attr_curr2_crit
.dev_attr
.attr
,
336 &sensor_dev_attr_curr2_crit_alarm
.dev_attr
.attr
,
337 &sensor_dev_attr_curr2_max
.dev_attr
.attr
,
338 &sensor_dev_attr_curr2_max_alarm
.dev_attr
.attr
,
339 &sensor_dev_attr_in5_input
.dev_attr
.attr
,
342 &sensor_dev_attr_in3_input
.dev_attr
.attr
,
343 &sensor_dev_attr_curr3_input
.dev_attr
.attr
,
344 &sensor_dev_attr_shunt3_resistor
.dev_attr
.attr
,
345 &sensor_dev_attr_curr3_crit
.dev_attr
.attr
,
346 &sensor_dev_attr_curr3_crit_alarm
.dev_attr
.attr
,
347 &sensor_dev_attr_curr3_max
.dev_attr
.attr
,
348 &sensor_dev_attr_curr3_max_alarm
.dev_attr
.attr
,
349 &sensor_dev_attr_in6_input
.dev_attr
.attr
,
353 ATTRIBUTE_GROUPS(ina3221
);
355 static const struct regmap_range ina3221_yes_ranges
[] = {
356 regmap_reg_range(INA3221_SHUNT1
, INA3221_BUS3
),
357 regmap_reg_range(INA3221_MASK_ENABLE
, INA3221_MASK_ENABLE
),
360 static const struct regmap_access_table ina3221_volatile_table
= {
361 .yes_ranges
= ina3221_yes_ranges
,
362 .n_yes_ranges
= ARRAY_SIZE(ina3221_yes_ranges
),
365 static const struct regmap_config ina3221_regmap_config
= {
369 .cache_type
= REGCACHE_RBTREE
,
370 .volatile_table
= &ina3221_volatile_table
,
373 static int ina3221_probe(struct i2c_client
*client
,
374 const struct i2c_device_id
*id
)
376 struct device
*dev
= &client
->dev
;
377 struct ina3221_data
*ina
;
378 struct device
*hwmon_dev
;
381 ina
= devm_kzalloc(dev
, sizeof(*ina
), GFP_KERNEL
);
385 ina
->regmap
= devm_regmap_init_i2c(client
, &ina3221_regmap_config
);
386 if (IS_ERR(ina
->regmap
)) {
387 dev_err(dev
, "Unable to allocate register map\n");
388 return PTR_ERR(ina
->regmap
);
391 for (i
= 0; i
< F_MAX_FIELDS
; i
++) {
392 ina
->fields
[i
] = devm_regmap_field_alloc(dev
,
394 ina3221_reg_fields
[i
]);
395 if (IS_ERR(ina
->fields
[i
])) {
396 dev_err(dev
, "Unable to allocate regmap fields\n");
397 return PTR_ERR(ina
->fields
[i
]);
401 for (i
= 0; i
< INA3221_NUM_CHANNELS
; i
++)
402 ina
->shunt_resistors
[i
] = INA3221_RSHUNT_DEFAULT
;
404 ret
= regmap_field_write(ina
->fields
[F_RST
], true);
406 dev_err(dev
, "Unable to reset device\n");
410 hwmon_dev
= devm_hwmon_device_register_with_groups(dev
,
412 ina
, ina3221_groups
);
413 if (IS_ERR(hwmon_dev
)) {
414 dev_err(dev
, "Unable to register hwmon device\n");
415 return PTR_ERR(hwmon_dev
);
421 static const struct of_device_id ina3221_of_match_table
[] = {
422 { .compatible
= "ti,ina3221", },
425 MODULE_DEVICE_TABLE(of
, ina3221_of_match_table
);
427 static const struct i2c_device_id ina3221_ids
[] = {
431 MODULE_DEVICE_TABLE(i2c
, ina3221_ids
);
433 static struct i2c_driver ina3221_i2c_driver
= {
434 .probe
= ina3221_probe
,
436 .name
= INA3221_DRIVER_NAME
,
437 .of_match_table
= ina3221_of_match_table
,
439 .id_table
= ina3221_ids
,
441 module_i2c_driver(ina3221_i2c_driver
);
443 MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>");
444 MODULE_DESCRIPTION("Texas Instruments INA3221 HWMon Driver");
445 MODULE_LICENSE("GPL v2");