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