xref: /linux/drivers/hwmon/ina238.c (revision c1ead4b4dfe0f643cfc66571ca7d2fa332eddd35)
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, &regval);
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, &regval);
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, &regval);
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, &regval);
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, &regval);
366 		if (err)
367 			return err;
368 		lsb /= 16;	/* Adjust accuracy */
369 	} else {
370 		err = regmap_read(data->regmap, INA238_CURRENT, &regval);
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, &regval);
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, &regval);
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, &regval);
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, &regval);
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, &regval);
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, &regval);
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, &regval);
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, &regval);
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, &regval);
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