1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Driver for Texas Instruments INA238 power monitor chip
4 * Datasheet: https://www.ti.com/product/ina238
5 *
6 * Copyright (C) 2021 Nathan Rossi <nathan.rossi@digi.com>
7 */
8
9 #include <linux/bitops.h>
10 #include <linux/err.h>
11 #include <linux/hwmon.h>
12 #include <linux/i2c.h>
13 #include <linux/init.h>
14 #include <linux/kernel.h>
15 #include <linux/module.h>
16 #include <linux/of.h>
17 #include <linux/regmap.h>
18
19 /* INA238 register definitions */
20 #define INA238_CONFIG 0x0
21 #define INA238_ADC_CONFIG 0x1
22 #define INA238_SHUNT_CALIBRATION 0x2
23 #define SQ52206_SHUNT_TEMPCO 0x3
24 #define INA238_SHUNT_VOLTAGE 0x4
25 #define INA238_BUS_VOLTAGE 0x5
26 #define INA238_DIE_TEMP 0x6
27 #define INA238_CURRENT 0x7
28 #define INA238_POWER 0x8
29 #define SQ52206_ENERGY 0x9
30 #define SQ52206_CHARGE 0xa
31 #define INA238_DIAG_ALERT 0xb
32 #define INA238_SHUNT_OVER_VOLTAGE 0xc
33 #define INA238_SHUNT_UNDER_VOLTAGE 0xd
34 #define INA238_BUS_OVER_VOLTAGE 0xe
35 #define INA238_BUS_UNDER_VOLTAGE 0xf
36 #define INA238_TEMP_LIMIT 0x10
37 #define INA238_POWER_LIMIT 0x11
38 #define SQ52206_POWER_PEAK 0x20
39 #define INA238_DEVICE_ID 0x3f /* not available on INA237 */
40
41 #define INA238_CONFIG_ADCRANGE BIT(4)
42 #define SQ52206_CONFIG_ADCRANGE_HIGH BIT(4)
43 #define SQ52206_CONFIG_ADCRANGE_LOW BIT(3)
44
45 #define INA238_DIAG_ALERT_TMPOL BIT(7)
46 #define INA238_DIAG_ALERT_SHNTOL BIT(6)
47 #define INA238_DIAG_ALERT_SHNTUL BIT(5)
48 #define INA238_DIAG_ALERT_BUSOL BIT(4)
49 #define INA238_DIAG_ALERT_BUSUL BIT(3)
50 #define INA238_DIAG_ALERT_POL BIT(2)
51
52 #define INA238_REGISTERS 0x20
53
54 #define INA238_RSHUNT_DEFAULT 2500 /* uOhm */
55
56 /* Default configuration of device on reset. */
57 #define INA238_CONFIG_DEFAULT 0
58 #define SQ52206_CONFIG_DEFAULT 0x0005
59 /* 16 sample averaging, 1052us conversion time, continuous mode */
60 #define INA238_ADC_CONFIG_DEFAULT 0xfb6a
61 /* Configure alerts to be based on averaged value (SLOWALERT) */
62 #define INA238_DIAG_ALERT_DEFAULT 0x2000
63 #define INA238_DIAG_ALERT_APOL BIT(12)
64 /*
65 * This driver uses a fixed calibration value in order to scale current/power
66 * based on a fixed shunt resistor value. This allows for conversion within the
67 * device to avoid integer limits whilst current/power accuracy is scaled
68 * relative to the shunt resistor value within the driver. This is similar to
69 * how the ina2xx driver handles current/power scaling.
70 *
71 * To achieve the best possible dynamic range, the value of the shunt voltage
72 * register should match the value of the current register. With that, the shunt
73 * voltage of 0x7fff = 32,767 uV = 163,785 uV matches the maximum current,
74 * and no accuracy is lost. Experiments with a real chip show that this is
75 * achieved by setting the SHUNT_CAL register to a value of 0x1000 = 4,096.
76 * Per datasheet,
77 * SHUNT_CAL = 819.2 x 10^6 x CURRENT_LSB x Rshunt
78 * = 819,200,000 x CURRENT_LSB x Rshunt
79 * With SHUNT_CAL set to 4,096, we get
80 * CURRENT_LSB = 4,096 / (819,200,000 x Rshunt)
81 * Assuming an Rshunt value of 5 mOhm, we get
82 * CURRENT_LSB = 4,096 / (819,200,000 x 0.005) = 1mA
83 * and thus a dynamic range of 1mA ... 32,767mA, which is sufficient for most
84 * applications. The actual dynamic range is of course determined by the actual
85 * shunt resistor value.
86 *
87 * Power and energy values are scaled accordingly.
88 */
89 #define INA238_CALIBRATION_VALUE 4096
90 #define INA238_FIXED_SHUNT 5000
91
92 #define INA238_SHUNT_VOLTAGE_LSB 5000 /* 5 uV/lsb, in nV */
93 #define INA238_BUS_VOLTAGE_LSB 3125000 /* 3.125 mV/lsb, in nV */
94 #define SQ52206_BUS_VOLTAGE_LSB 3750000 /* 3.75 mV/lsb, in nV */
95
96 #define NUNIT_PER_MUNIT 1000000 /* n[AV] -> m[AV] */
97
98 static const struct regmap_config ina238_regmap_config = {
99 .max_register = INA238_REGISTERS,
100 .reg_bits = 8,
101 .val_bits = 16,
102 };
103
104 enum ina238_ids { ina228, ina237, ina238, ina700, ina780, sq52206 };
105
106 struct ina238_config {
107 bool has_20bit_voltage_current; /* vshunt, vbus and current are 20-bit fields */
108 bool has_power_highest; /* chip detection power peak */
109 bool has_energy; /* chip detection energy */
110 u8 temp_resolution; /* temperature register resolution in bit */
111 u16 config_default; /* Power-on default state */
112 u32 power_calculate_factor; /* fixed parameter for power calculation, from datasheet */
113 u32 bus_voltage_lsb; /* bus voltage LSB, in nV */
114 int current_lsb; /* current LSB, in uA */
115 };
116
117 struct ina238_data {
118 const struct ina238_config *config;
119 struct i2c_client *client;
120 struct mutex config_lock;
121 struct regmap *regmap;
122 u32 rshunt;
123 int gain;
124 u32 voltage_lsb[2]; /* shunt, bus voltage LSB, in nV */
125 int current_lsb; /* current LSB, in uA */
126 int power_lsb; /* power LSB, in uW */
127 int energy_lsb; /* energy LSB, in uJ */
128 };
129
130 static const struct ina238_config ina238_config[] = {
131 [ina228] = {
132 .has_20bit_voltage_current = true,
133 .has_energy = true,
134 .has_power_highest = false,
135 .power_calculate_factor = 20,
136 .config_default = INA238_CONFIG_DEFAULT,
137 .bus_voltage_lsb = INA238_BUS_VOLTAGE_LSB,
138 .temp_resolution = 16,
139 },
140 [ina237] = {
141 .has_20bit_voltage_current = false,
142 .has_energy = false,
143 .has_power_highest = false,
144 .power_calculate_factor = 20,
145 .config_default = INA238_CONFIG_DEFAULT,
146 .bus_voltage_lsb = INA238_BUS_VOLTAGE_LSB,
147 .temp_resolution = 12,
148 },
149 [ina238] = {
150 .has_20bit_voltage_current = false,
151 .has_energy = false,
152 .has_power_highest = false,
153 .power_calculate_factor = 20,
154 .config_default = INA238_CONFIG_DEFAULT,
155 .bus_voltage_lsb = INA238_BUS_VOLTAGE_LSB,
156 .temp_resolution = 12,
157 },
158 [ina700] = {
159 .has_20bit_voltage_current = false,
160 .has_energy = true,
161 .has_power_highest = false,
162 .power_calculate_factor = 20,
163 .config_default = INA238_CONFIG_DEFAULT,
164 .bus_voltage_lsb = INA238_BUS_VOLTAGE_LSB,
165 .temp_resolution = 12,
166 .current_lsb = 480,
167 },
168 [ina780] = {
169 .has_20bit_voltage_current = false,
170 .has_energy = true,
171 .has_power_highest = false,
172 .power_calculate_factor = 20,
173 .config_default = INA238_CONFIG_DEFAULT,
174 .bus_voltage_lsb = INA238_BUS_VOLTAGE_LSB,
175 .temp_resolution = 12,
176 .current_lsb = 2400,
177 },
178 [sq52206] = {
179 .has_20bit_voltage_current = false,
180 .has_energy = true,
181 .has_power_highest = true,
182 .power_calculate_factor = 24,
183 .config_default = SQ52206_CONFIG_DEFAULT,
184 .bus_voltage_lsb = SQ52206_BUS_VOLTAGE_LSB,
185 .temp_resolution = 16,
186 },
187 };
188
ina238_read_reg24(const struct i2c_client * client,u8 reg,u32 * val)189 static int ina238_read_reg24(const struct i2c_client *client, u8 reg, u32 *val)
190 {
191 u8 data[3];
192 int err;
193
194 /* 24-bit register read */
195 err = i2c_smbus_read_i2c_block_data(client, reg, 3, data);
196 if (err < 0)
197 return err;
198 if (err != 3)
199 return -EIO;
200 *val = (data[0] << 16) | (data[1] << 8) | data[2];
201
202 return 0;
203 }
204
ina238_read_reg40(const struct i2c_client * client,u8 reg,u64 * val)205 static int ina238_read_reg40(const struct i2c_client *client, u8 reg, u64 *val)
206 {
207 u8 data[5];
208 u32 low;
209 int err;
210
211 /* 40-bit register read */
212 err = i2c_smbus_read_i2c_block_data(client, reg, 5, data);
213 if (err < 0)
214 return err;
215 if (err != 5)
216 return -EIO;
217 low = (data[1] << 24) | (data[2] << 16) | (data[3] << 8) | data[4];
218 *val = ((long long)data[0] << 32) | low;
219
220 return 0;
221 }
222
ina238_read_field_s20(const struct i2c_client * client,u8 reg,s32 * val)223 static int ina238_read_field_s20(const struct i2c_client *client, u8 reg, s32 *val)
224 {
225 u32 regval;
226 int err;
227
228 err = ina238_read_reg24(client, reg, ®val);
229 if (err)
230 return err;
231
232 /* bits 3-0 Reserved, always zero */
233 regval >>= 4;
234
235 *val = sign_extend32(regval, 19);
236
237 return 0;
238 }
239
ina228_read_voltage(struct ina238_data * data,int channel,long * val)240 static int ina228_read_voltage(struct ina238_data *data, int channel, long *val)
241 {
242 int reg = channel ? INA238_BUS_VOLTAGE : INA238_CURRENT;
243 u32 lsb = data->voltage_lsb[channel];
244 u32 factor = NUNIT_PER_MUNIT;
245 int err, regval;
246
247 if (data->config->has_20bit_voltage_current) {
248 err = ina238_read_field_s20(data->client, reg, ®val);
249 if (err)
250 return err;
251 /* Adjust accuracy: LSB in units of 500 pV */
252 lsb /= 8;
253 factor *= 2;
254 } else {
255 err = regmap_read(data->regmap, reg, ®val);
256 if (err)
257 return err;
258 regval = (s16)regval;
259 }
260
261 *val = DIV_S64_ROUND_CLOSEST((s64)regval * lsb, factor);
262 return 0;
263 }
264
ina238_read_in(struct device * dev,u32 attr,int channel,long * val)265 static int ina238_read_in(struct device *dev, u32 attr, int channel,
266 long *val)
267 {
268 struct ina238_data *data = dev_get_drvdata(dev);
269 int reg, mask = 0;
270 int regval;
271 int err;
272
273 if (attr == hwmon_in_input)
274 return ina228_read_voltage(data, channel, val);
275
276 switch (channel) {
277 case 0:
278 switch (attr) {
279 case hwmon_in_max:
280 reg = INA238_SHUNT_OVER_VOLTAGE;
281 break;
282 case hwmon_in_min:
283 reg = INA238_SHUNT_UNDER_VOLTAGE;
284 break;
285 case hwmon_in_max_alarm:
286 reg = INA238_DIAG_ALERT;
287 mask = INA238_DIAG_ALERT_SHNTOL;
288 break;
289 case hwmon_in_min_alarm:
290 reg = INA238_DIAG_ALERT;
291 mask = INA238_DIAG_ALERT_SHNTUL;
292 break;
293 default:
294 return -EOPNOTSUPP;
295 }
296 break;
297 case 1:
298 switch (attr) {
299 case hwmon_in_max:
300 reg = INA238_BUS_OVER_VOLTAGE;
301 break;
302 case hwmon_in_min:
303 reg = INA238_BUS_UNDER_VOLTAGE;
304 break;
305 case hwmon_in_max_alarm:
306 reg = INA238_DIAG_ALERT;
307 mask = INA238_DIAG_ALERT_BUSOL;
308 break;
309 case hwmon_in_min_alarm:
310 reg = INA238_DIAG_ALERT;
311 mask = INA238_DIAG_ALERT_BUSUL;
312 break;
313 default:
314 return -EOPNOTSUPP;
315 }
316 break;
317 default:
318 return -EOPNOTSUPP;
319 }
320
321 err = regmap_read(data->regmap, reg, ®val);
322 if (err < 0)
323 return err;
324
325 if (mask)
326 *val = !!(regval & mask);
327 else
328 *val = DIV_S64_ROUND_CLOSEST((s64)(s16)regval * data->voltage_lsb[channel],
329 NUNIT_PER_MUNIT);
330
331 return 0;
332 }
333
ina238_write_in(struct device * dev,u32 attr,int channel,long val)334 static int ina238_write_in(struct device *dev, u32 attr, int channel, long val)
335 {
336 struct ina238_data *data = dev_get_drvdata(dev);
337 static const int low_limits[2] = {-164, 0};
338 static const int high_limits[2] = {164, 150000};
339 static const u8 low_regs[2] = {INA238_SHUNT_UNDER_VOLTAGE, INA238_BUS_UNDER_VOLTAGE};
340 static const u8 high_regs[2] = {INA238_SHUNT_OVER_VOLTAGE, INA238_BUS_OVER_VOLTAGE};
341 int regval;
342
343 /* Initial clamp to avoid overflows */
344 val = clamp_val(val, low_limits[channel], high_limits[channel]);
345 val = DIV_S64_ROUND_CLOSEST((s64)val * NUNIT_PER_MUNIT, data->voltage_lsb[channel]);
346 /* Final clamp to register limits */
347 regval = clamp_val(val, S16_MIN, S16_MAX) & 0xffff;
348
349 switch (attr) {
350 case hwmon_in_min:
351 return regmap_write(data->regmap, low_regs[channel], regval);
352 case hwmon_in_max:
353 return regmap_write(data->regmap, high_regs[channel], regval);
354 default:
355 return -EOPNOTSUPP;
356 }
357 }
358
__ina238_read_curr(struct ina238_data * data,long * val)359 static int __ina238_read_curr(struct ina238_data *data, long *val)
360 {
361 u32 lsb = data->current_lsb;
362 int err, regval;
363
364 if (data->config->has_20bit_voltage_current) {
365 err = ina238_read_field_s20(data->client, INA238_CURRENT, ®val);
366 if (err)
367 return err;
368 lsb /= 16; /* Adjust accuracy */
369 } else {
370 err = regmap_read(data->regmap, INA238_CURRENT, ®val);
371 if (err)
372 return err;
373 regval = (s16)regval;
374 }
375
376 *val = DIV_S64_ROUND_CLOSEST((s64)regval * lsb, 1000);
377 return 0;
378 }
379
ina238_read_curr(struct device * dev,u32 attr,long * val)380 static int ina238_read_curr(struct device *dev, u32 attr, long *val)
381 {
382 struct ina238_data *data = dev_get_drvdata(dev);
383 int reg, mask = 0;
384 int regval;
385 int err;
386
387 if (attr == hwmon_curr_input)
388 return __ina238_read_curr(data, val);
389
390 switch (attr) {
391 case hwmon_curr_min:
392 reg = INA238_SHUNT_UNDER_VOLTAGE;
393 break;
394 case hwmon_curr_min_alarm:
395 reg = INA238_DIAG_ALERT;
396 mask = INA238_DIAG_ALERT_SHNTUL;
397 break;
398 case hwmon_curr_max:
399 reg = INA238_SHUNT_OVER_VOLTAGE;
400 break;
401 case hwmon_curr_max_alarm:
402 reg = INA238_DIAG_ALERT;
403 mask = INA238_DIAG_ALERT_SHNTOL;
404 break;
405 default:
406 return -EOPNOTSUPP;
407 }
408
409 err = regmap_read(data->regmap, reg, ®val);
410 if (err < 0)
411 return err;
412
413 if (mask)
414 *val = !!(regval & mask);
415 else
416 *val = DIV_S64_ROUND_CLOSEST((s64)(s16)regval * data->current_lsb, 1000);
417
418 return 0;
419 }
420
ina238_write_curr(struct device * dev,u32 attr,long val)421 static int ina238_write_curr(struct device *dev, u32 attr, long val)
422 {
423 struct ina238_data *data = dev_get_drvdata(dev);
424 int regval;
425
426 /* Set baseline range to avoid over/underflows */
427 val = clamp_val(val, -1000000, 1000000);
428 /* Scale */
429 val = DIV_ROUND_CLOSEST(val * 1000, data->current_lsb);
430 /* Clamp to register size */
431 regval = clamp_val(val, S16_MIN, S16_MAX) & 0xffff;
432
433 switch (attr) {
434 case hwmon_curr_min:
435 return regmap_write(data->regmap, INA238_SHUNT_UNDER_VOLTAGE,
436 regval);
437 case hwmon_curr_max:
438 return regmap_write(data->regmap, INA238_SHUNT_OVER_VOLTAGE,
439 regval);
440 default:
441 return -EOPNOTSUPP;
442 }
443 }
444
ina238_read_power(struct device * dev,u32 attr,long * val)445 static int ina238_read_power(struct device *dev, u32 attr, long *val)
446 {
447 struct ina238_data *data = dev_get_drvdata(dev);
448 long long power;
449 int regval;
450 int err;
451
452 switch (attr) {
453 case hwmon_power_input:
454 err = ina238_read_reg24(data->client, INA238_POWER, ®val);
455 if (err)
456 return err;
457
458 power = (long long)regval * data->power_lsb;
459 /* Clamp value to maximum value of long */
460 *val = clamp_val(power, 0, LONG_MAX);
461 break;
462 case hwmon_power_input_highest:
463 err = ina238_read_reg24(data->client, SQ52206_POWER_PEAK, ®val);
464 if (err)
465 return err;
466
467 power = (long long)regval * data->power_lsb;
468 /* Clamp value to maximum value of long */
469 *val = clamp_val(power, 0, LONG_MAX);
470 break;
471 case hwmon_power_max:
472 err = regmap_read(data->regmap, INA238_POWER_LIMIT, ®val);
473 if (err)
474 return err;
475
476 /*
477 * Truncated 24-bit compare register, lower 8-bits are
478 * truncated. Same conversion to/from uW as POWER register.
479 */
480 power = ((long long)regval << 8) * data->power_lsb;
481 /* Clamp value to maximum value of long */
482 *val = clamp_val(power, 0, LONG_MAX);
483 break;
484 case hwmon_power_max_alarm:
485 err = regmap_read(data->regmap, INA238_DIAG_ALERT, ®val);
486 if (err)
487 return err;
488
489 *val = !!(regval & INA238_DIAG_ALERT_POL);
490 break;
491 default:
492 return -EOPNOTSUPP;
493 }
494
495 return 0;
496 }
497
ina238_write_power_max(struct device * dev,long val)498 static int ina238_write_power_max(struct device *dev, long val)
499 {
500 struct ina238_data *data = dev_get_drvdata(dev);
501
502 /*
503 * Unsigned postive values. Compared against the 24-bit power register,
504 * lower 8-bits are truncated. Same conversion to/from uW as POWER
505 * register.
506 * The first clamp_val() is to establish a baseline to avoid overflows.
507 */
508 val = clamp_val(val, 0, LONG_MAX / 2);
509 val = DIV_ROUND_CLOSEST(val, data->power_lsb);
510 val = clamp_val(val >> 8, 0, U16_MAX);
511
512 return regmap_write(data->regmap, INA238_POWER_LIMIT, val);
513 }
514
ina238_temp_from_reg(s16 regval,u8 resolution)515 static int ina238_temp_from_reg(s16 regval, u8 resolution)
516 {
517 return ((regval >> (16 - resolution)) * 1000) >> (resolution - 9);
518 }
519
ina238_read_temp(struct device * dev,u32 attr,long * val)520 static int ina238_read_temp(struct device *dev, u32 attr, long *val)
521 {
522 struct ina238_data *data = dev_get_drvdata(dev);
523 int regval;
524 int err;
525
526 switch (attr) {
527 case hwmon_temp_input:
528 err = regmap_read(data->regmap, INA238_DIE_TEMP, ®val);
529 if (err)
530 return err;
531 *val = ina238_temp_from_reg(regval, data->config->temp_resolution);
532 break;
533 case hwmon_temp_max:
534 err = regmap_read(data->regmap, INA238_TEMP_LIMIT, ®val);
535 if (err)
536 return err;
537 /* Signed, result in mC */
538 *val = ina238_temp_from_reg(regval, data->config->temp_resolution);
539 break;
540 case hwmon_temp_max_alarm:
541 err = regmap_read(data->regmap, INA238_DIAG_ALERT, ®val);
542 if (err)
543 return err;
544
545 *val = !!(regval & INA238_DIAG_ALERT_TMPOL);
546 break;
547 default:
548 return -EOPNOTSUPP;
549 }
550
551 return 0;
552 }
553
ina238_temp_to_reg(long val,u8 resolution)554 static u16 ina238_temp_to_reg(long val, u8 resolution)
555 {
556 int fraction = 1000 - DIV_ROUND_CLOSEST(1000, BIT(resolution - 9));
557
558 val = clamp_val(val, -255000 - fraction, 255000 + fraction);
559
560 return (DIV_ROUND_CLOSEST(val << (resolution - 9), 1000) << (16 - resolution)) & 0xffff;
561 }
562
ina238_write_temp_max(struct device * dev,long val)563 static int ina238_write_temp_max(struct device *dev, long val)
564 {
565 struct ina238_data *data = dev_get_drvdata(dev);
566 int regval;
567
568 regval = ina238_temp_to_reg(val, data->config->temp_resolution);
569 return regmap_write(data->regmap, INA238_TEMP_LIMIT, regval);
570 }
571
ina238_read_energy(struct device * dev,s64 * energy)572 static int ina238_read_energy(struct device *dev, s64 *energy)
573 {
574 struct ina238_data *data = dev_get_drvdata(dev);
575 u64 regval;
576 int ret;
577
578 ret = ina238_read_reg40(data->client, SQ52206_ENERGY, ®val);
579 if (ret)
580 return ret;
581
582 /* result in uJ */
583 *energy = regval * data->energy_lsb;
584 return 0;
585 }
586
ina238_read(struct device * dev,enum hwmon_sensor_types type,u32 attr,int channel,long * val)587 static int ina238_read(struct device *dev, enum hwmon_sensor_types type,
588 u32 attr, int channel, long *val)
589 {
590 switch (type) {
591 case hwmon_in:
592 return ina238_read_in(dev, attr, channel, val);
593 case hwmon_curr:
594 return ina238_read_curr(dev, attr, val);
595 case hwmon_power:
596 return ina238_read_power(dev, attr, val);
597 case hwmon_energy64:
598 return ina238_read_energy(dev, (s64 *)val);
599 case hwmon_temp:
600 return ina238_read_temp(dev, attr, val);
601 default:
602 return -EOPNOTSUPP;
603 }
604 return 0;
605 }
606
ina238_write(struct device * dev,enum hwmon_sensor_types type,u32 attr,int channel,long val)607 static int ina238_write(struct device *dev, enum hwmon_sensor_types type,
608 u32 attr, int channel, long val)
609 {
610 struct ina238_data *data = dev_get_drvdata(dev);
611 int err;
612
613 mutex_lock(&data->config_lock);
614
615 switch (type) {
616 case hwmon_in:
617 err = ina238_write_in(dev, attr, channel, val);
618 break;
619 case hwmon_curr:
620 err = ina238_write_curr(dev, attr, val);
621 break;
622 case hwmon_power:
623 err = ina238_write_power_max(dev, val);
624 break;
625 case hwmon_temp:
626 err = ina238_write_temp_max(dev, val);
627 break;
628 default:
629 err = -EOPNOTSUPP;
630 break;
631 }
632
633 mutex_unlock(&data->config_lock);
634 return err;
635 }
636
ina238_is_visible(const void * drvdata,enum hwmon_sensor_types type,u32 attr,int channel)637 static umode_t ina238_is_visible(const void *drvdata,
638 enum hwmon_sensor_types type,
639 u32 attr, int channel)
640 {
641 const struct ina238_data *data = drvdata;
642 bool has_power_highest = data->config->has_power_highest;
643 bool has_energy = data->config->has_energy;
644
645 switch (type) {
646 case hwmon_in:
647 switch (attr) {
648 case hwmon_in_input:
649 case hwmon_in_max_alarm:
650 case hwmon_in_min_alarm:
651 return 0444;
652 case hwmon_in_max:
653 case hwmon_in_min:
654 return 0644;
655 default:
656 return 0;
657 }
658 case hwmon_curr:
659 switch (attr) {
660 case hwmon_curr_input:
661 case hwmon_curr_max_alarm:
662 case hwmon_curr_min_alarm:
663 return 0444;
664 case hwmon_curr_max:
665 case hwmon_curr_min:
666 return 0644;
667 default:
668 return 0;
669 }
670 case hwmon_power:
671 switch (attr) {
672 case hwmon_power_input:
673 case hwmon_power_max_alarm:
674 return 0444;
675 case hwmon_power_max:
676 return 0644;
677 case hwmon_power_input_highest:
678 if (has_power_highest)
679 return 0444;
680 return 0;
681 default:
682 return 0;
683 }
684 case hwmon_energy64:
685 /* hwmon_energy_input */
686 if (has_energy)
687 return 0444;
688 return 0;
689 case hwmon_temp:
690 switch (attr) {
691 case hwmon_temp_input:
692 case hwmon_temp_max_alarm:
693 return 0444;
694 case hwmon_temp_max:
695 return 0644;
696 default:
697 return 0;
698 }
699 default:
700 return 0;
701 }
702 }
703
704 #define INA238_HWMON_IN_CONFIG (HWMON_I_INPUT | \
705 HWMON_I_MAX | HWMON_I_MAX_ALARM | \
706 HWMON_I_MIN | HWMON_I_MIN_ALARM)
707
708 static const struct hwmon_channel_info * const ina238_info[] = {
709 HWMON_CHANNEL_INFO(in,
710 /* 0: shunt voltage */
711 INA238_HWMON_IN_CONFIG,
712 /* 1: bus voltage */
713 INA238_HWMON_IN_CONFIG),
714 HWMON_CHANNEL_INFO(curr,
715 /* 0: current through shunt */
716 HWMON_C_INPUT | HWMON_C_MIN | HWMON_C_MIN_ALARM |
717 HWMON_C_MAX | HWMON_C_MAX_ALARM),
718 HWMON_CHANNEL_INFO(power,
719 /* 0: power */
720 HWMON_P_INPUT | HWMON_P_MAX |
721 HWMON_P_MAX_ALARM | HWMON_P_INPUT_HIGHEST),
722 HWMON_CHANNEL_INFO(energy64,
723 HWMON_E_INPUT),
724 HWMON_CHANNEL_INFO(temp,
725 /* 0: die temperature */
726 HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_ALARM),
727 NULL
728 };
729
730 static const struct hwmon_ops ina238_hwmon_ops = {
731 .is_visible = ina238_is_visible,
732 .read = ina238_read,
733 .write = ina238_write,
734 };
735
736 static const struct hwmon_chip_info ina238_chip_info = {
737 .ops = &ina238_hwmon_ops,
738 .info = ina238_info,
739 };
740
ina238_probe(struct i2c_client * client)741 static int ina238_probe(struct i2c_client *client)
742 {
743 struct device *dev = &client->dev;
744 struct device *hwmon_dev;
745 struct ina238_data *data;
746 enum ina238_ids chip;
747 int config;
748 int ret;
749
750 chip = (uintptr_t)i2c_get_match_data(client);
751
752 data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
753 if (!data)
754 return -ENOMEM;
755
756 data->client = client;
757 /* set the device type */
758 data->config = &ina238_config[chip];
759
760 mutex_init(&data->config_lock);
761
762 data->regmap = devm_regmap_init_i2c(client, &ina238_regmap_config);
763 if (IS_ERR(data->regmap)) {
764 dev_err(dev, "failed to allocate register map\n");
765 return PTR_ERR(data->regmap);
766 }
767
768 /* Setup CONFIG register */
769 config = data->config->config_default;
770 if (data->config->current_lsb) {
771 data->voltage_lsb[0] = INA238_SHUNT_VOLTAGE_LSB;
772 data->current_lsb = data->config->current_lsb;
773 } else {
774 /* load shunt value */
775 if (device_property_read_u32(dev, "shunt-resistor", &data->rshunt) < 0)
776 data->rshunt = INA238_RSHUNT_DEFAULT;
777 if (data->rshunt == 0) {
778 dev_err(dev, "invalid shunt resister value %u\n", data->rshunt);
779 return -EINVAL;
780 }
781
782 /* load shunt gain value */
783 if (device_property_read_u32(dev, "ti,shunt-gain", &data->gain) < 0)
784 data->gain = 4; /* Default of ADCRANGE = 0 */
785 if (data->gain != 1 && data->gain != 2 && data->gain != 4) {
786 dev_err(dev, "invalid shunt gain value %u\n", data->gain);
787 return -EINVAL;
788 }
789
790 /* Setup SHUNT_CALIBRATION register with fixed value */
791 ret = regmap_write(data->regmap, INA238_SHUNT_CALIBRATION,
792 INA238_CALIBRATION_VALUE);
793 if (ret < 0) {
794 dev_err(dev, "error configuring the device: %d\n", ret);
795 return -ENODEV;
796 }
797 if (chip == sq52206) {
798 if (data->gain == 1) /* ADCRANGE = 10/11 is /1 */
799 config |= SQ52206_CONFIG_ADCRANGE_HIGH;
800 else if (data->gain == 2) /* ADCRANGE = 01 is /2 */
801 config |= SQ52206_CONFIG_ADCRANGE_LOW;
802 } else if (data->gain == 1) { /* ADCRANGE = 1 is /1 */
803 config |= INA238_CONFIG_ADCRANGE;
804 }
805 data->voltage_lsb[0] = INA238_SHUNT_VOLTAGE_LSB * data->gain / 4;
806 data->current_lsb = DIV_U64_ROUND_CLOSEST(250ULL * INA238_FIXED_SHUNT * data->gain,
807 data->rshunt);
808 }
809
810 ret = regmap_write(data->regmap, INA238_CONFIG, config);
811 if (ret < 0) {
812 dev_err(dev, "error configuring the device: %d\n", ret);
813 return -ENODEV;
814 }
815
816 /* Setup ADC_CONFIG register */
817 ret = regmap_write(data->regmap, INA238_ADC_CONFIG,
818 INA238_ADC_CONFIG_DEFAULT);
819 if (ret < 0) {
820 dev_err(dev, "error configuring the device: %d\n", ret);
821 return -ENODEV;
822 }
823
824 /* Setup alert/alarm configuration */
825 config = INA238_DIAG_ALERT_DEFAULT;
826 if (device_property_read_bool(dev, "ti,alert-polarity-active-high"))
827 config |= INA238_DIAG_ALERT_APOL;
828
829 ret = regmap_write(data->regmap, INA238_DIAG_ALERT, config);
830 if (ret < 0) {
831 dev_err(dev, "error configuring the device: %d\n", ret);
832 return -ENODEV;
833 }
834
835 data->voltage_lsb[1] = data->config->bus_voltage_lsb;
836
837 data->power_lsb = DIV_ROUND_CLOSEST(data->current_lsb *
838 data->config->power_calculate_factor,
839 100);
840
841 data->energy_lsb = data->power_lsb * 16;
842
843 hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, data,
844 &ina238_chip_info, NULL);
845 if (IS_ERR(hwmon_dev))
846 return PTR_ERR(hwmon_dev);
847
848 if (data->rshunt)
849 dev_info(dev, "power monitor %s (Rshunt = %u uOhm, gain = %u)\n",
850 client->name, data->rshunt, data->gain);
851
852 return 0;
853 }
854
855 static const struct i2c_device_id ina238_id[] = {
856 { "ina228", ina228 },
857 { "ina237", ina237 },
858 { "ina238", ina238 },
859 { "ina700", ina700 },
860 { "ina780", ina780 },
861 { "sq52206", sq52206 },
862 { }
863 };
864 MODULE_DEVICE_TABLE(i2c, ina238_id);
865
866 static const struct of_device_id __maybe_unused ina238_of_match[] = {
867 {
868 .compatible = "ti,ina228",
869 .data = (void *)ina228
870 },
871 {
872 .compatible = "ti,ina237",
873 .data = (void *)ina237
874 },
875 {
876 .compatible = "ti,ina238",
877 .data = (void *)ina238
878 },
879 {
880 .compatible = "ti,ina700",
881 .data = (void *)ina700
882 },
883 {
884 .compatible = "ti,ina780",
885 .data = (void *)ina780
886 },
887 {
888 .compatible = "silergy,sq52206",
889 .data = (void *)sq52206
890 },
891 { }
892 };
893 MODULE_DEVICE_TABLE(of, ina238_of_match);
894
895 static struct i2c_driver ina238_driver = {
896 .driver = {
897 .name = "ina238",
898 .of_match_table = of_match_ptr(ina238_of_match),
899 },
900 .probe = ina238_probe,
901 .id_table = ina238_id,
902 };
903
904 module_i2c_driver(ina238_driver);
905
906 MODULE_AUTHOR("Nathan Rossi <nathan.rossi@digi.com>");
907 MODULE_DESCRIPTION("ina238 driver");
908 MODULE_LICENSE("GPL");
909