File Index
Files and directories
Sign in
FILE

ina3221.c

File preview with syntax highlighting.

linux-6.19.14/drivers/hwmon/ina3221.c C
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * INA3221 Triple Current/Voltage Monitor
   4 *
   5 * Copyright (C) 2016 Texas Instruments Incorporated - https://www.ti.com/
   6 *	Andrew F. Davis <afd@ti.com>
   7 */
   8
   9#include <linux/debugfs.h>
  10#include <linux/hwmon.h>
  11#include <linux/hwmon-sysfs.h>
  12#include <linux/i2c.h>
  13#include <linux/module.h>
  14#include <linux/of.h>
  15#include <linux/pm_runtime.h>
  16#include <linux/regmap.h>
  17#include <linux/util_macros.h>
  18
  19#define INA3221_DRIVER_NAME		"ina3221"
  20
  21#define INA3221_CONFIG			0x00
  22#define INA3221_SHUNT1			0x01
  23#define INA3221_BUS1			0x02
  24#define INA3221_SHUNT2			0x03
  25#define INA3221_BUS2			0x04
  26#define INA3221_SHUNT3			0x05
  27#define INA3221_BUS3			0x06
  28#define INA3221_CRIT1			0x07
  29#define INA3221_WARN1			0x08
  30#define INA3221_CRIT2			0x09
  31#define INA3221_WARN2			0x0a
  32#define INA3221_CRIT3			0x0b
  33#define INA3221_WARN3			0x0c
  34#define INA3221_SHUNT_SUM		0x0d
  35#define INA3221_CRIT_SUM		0x0e
  36#define INA3221_MASK_ENABLE		0x0f
  37
  38#define INA3221_CONFIG_MODE_MASK	GENMASK(2, 0)
  39#define INA3221_CONFIG_MODE_POWERDOWN	0
  40#define INA3221_CONFIG_MODE_SHUNT	BIT(0)
  41#define INA3221_CONFIG_MODE_BUS		BIT(1)
  42#define INA3221_CONFIG_MODE_CONTINUOUS	BIT(2)
  43#define INA3221_CONFIG_VSH_CT_SHIFT	3
  44#define INA3221_CONFIG_VSH_CT_MASK	GENMASK(5, 3)
  45#define INA3221_CONFIG_VSH_CT(x)	(((x) & GENMASK(5, 3)) >> 3)
  46#define INA3221_CONFIG_VBUS_CT_SHIFT	6
  47#define INA3221_CONFIG_VBUS_CT_MASK	GENMASK(8, 6)
  48#define INA3221_CONFIG_VBUS_CT(x)	(((x) & GENMASK(8, 6)) >> 6)
  49#define INA3221_CONFIG_AVG_SHIFT	9
  50#define INA3221_CONFIG_AVG_MASK		GENMASK(11, 9)
  51#define INA3221_CONFIG_AVG(x)		(((x) & GENMASK(11, 9)) >> 9)
  52#define INA3221_CONFIG_CHs_EN_MASK	GENMASK(14, 12)
  53#define INA3221_CONFIG_CHx_EN(x)	BIT(14 - (x))
  54
  55#define INA3221_MASK_ENABLE_SCC_MASK	GENMASK(14, 12)
  56
  57#define INA3221_CONFIG_DEFAULT		0x7127
  58#define INA3221_RSHUNT_DEFAULT		10000
  59
  60enum ina3221_fields {
  61	/* Configuration */
  62	F_RST,
  63
  64	/* Status Flags */
  65	F_CVRF,
  66
  67	/* Warning Flags */
  68	F_WF3, F_WF2, F_WF1,
  69
  70	/* Alert Flags: SF is the summation-alert flag */
  71	F_SF, F_CF3, F_CF2, F_CF1,
  72
  73	/* sentinel */
  74	F_MAX_FIELDS
  75};
  76
  77static const struct reg_field ina3221_reg_fields[] = {
  78	[F_RST] = REG_FIELD(INA3221_CONFIG, 15, 15),
  79
  80	[F_CVRF] = REG_FIELD(INA3221_MASK_ENABLE, 0, 0),
  81	[F_WF3] = REG_FIELD(INA3221_MASK_ENABLE, 3, 3),
  82	[F_WF2] = REG_FIELD(INA3221_MASK_ENABLE, 4, 4),
  83	[F_WF1] = REG_FIELD(INA3221_MASK_ENABLE, 5, 5),
  84	[F_SF] = REG_FIELD(INA3221_MASK_ENABLE, 6, 6),
  85	[F_CF3] = REG_FIELD(INA3221_MASK_ENABLE, 7, 7),
  86	[F_CF2] = REG_FIELD(INA3221_MASK_ENABLE, 8, 8),
  87	[F_CF1] = REG_FIELD(INA3221_MASK_ENABLE, 9, 9),
  88};
  89
  90enum ina3221_channels {
  91	INA3221_CHANNEL1,
  92	INA3221_CHANNEL2,
  93	INA3221_CHANNEL3,
  94	INA3221_NUM_CHANNELS
  95};
  96
  97/**
  98 * struct ina3221_input - channel input source specific information
  99 * @label: label of channel input source
 100 * @shunt_resistor: shunt resistor value of channel input source
 101 * @disconnected: connection status of channel input source
 102 * @summation_disable: channel summation status of input source
 103 */
 104struct ina3221_input {
 105	const char *label;
 106	int shunt_resistor;
 107	bool disconnected;
 108	bool summation_disable;
 109};
 110
 111/**
 112 * struct ina3221_data - device specific information
 113 * @pm_dev: Device pointer for pm runtime
 114 * @regmap: Register map of the device
 115 * @fields: Register fields of the device
 116 * @inputs: Array of channel input source specific structures
 117 * @reg_config: Register value of INA3221_CONFIG
 118 * @summation_shunt_resistor: equivalent shunt resistor value for summation
 119 * @summation_channel_control: Value written to SCC field in INA3221_MASK_ENABLE
 120 * @single_shot: running in single-shot operating mode
 121 */
 122struct ina3221_data {
 123	struct device *pm_dev;
 124	struct regmap *regmap;
 125	struct regmap_field *fields[F_MAX_FIELDS];
 126	struct ina3221_input inputs[INA3221_NUM_CHANNELS];
 127	u32 reg_config;
 128	int summation_shunt_resistor;
 129	u32 summation_channel_control;
 130
 131	bool single_shot;
 132};
 133
 134static inline bool ina3221_is_enabled(struct ina3221_data *ina, int channel)
 135{
 136	/* Summation channel checks shunt resistor values */
 137	if (channel > INA3221_CHANNEL3)
 138		return ina->summation_shunt_resistor != 0;
 139
 140	return pm_runtime_active(ina->pm_dev) &&
 141	       (ina->reg_config & INA3221_CONFIG_CHx_EN(channel));
 142}
 143
 144/*
 145 * Helper function to return the resistor value for current summation.
 146 *
 147 * There is a condition to calculate current summation -- all the shunt
 148 * resistor values should be the same, so as to simply fit the formula:
 149 *     current summation = shunt voltage summation / shunt resistor
 150 *
 151 * Returns the equivalent shunt resistor value on success or 0 on failure
 152 */
 153static inline int ina3221_summation_shunt_resistor(struct ina3221_data *ina)
 154{
 155	struct ina3221_input *input = ina->inputs;
 156	int i, shunt_resistor = 0;
 157
 158	for (i = 0; i < INA3221_NUM_CHANNELS; i++) {
 159		if (input[i].disconnected || !input[i].shunt_resistor ||
 160		    input[i].summation_disable)
 161			continue;
 162		if (!shunt_resistor) {
 163			/* Found the reference shunt resistor value */
 164			shunt_resistor = input[i].shunt_resistor;
 165		} else {
 166			/* No summation if resistor values are different */
 167			if (shunt_resistor != input[i].shunt_resistor)
 168				return 0;
 169		}
 170	}
 171
 172	return shunt_resistor;
 173}
 174
 175/* Lookup table for Bus and Shunt conversion times in usec */
 176static const u16 ina3221_conv_time[] = {
 177	140, 204, 332, 588, 1100, 2116, 4156, 8244,
 178};
 179
 180/* Lookup table for number of samples using in averaging mode */
 181static const int ina3221_avg_samples[] = {
 182	1, 4, 16, 64, 128, 256, 512, 1024,
 183};
 184
 185/* Converting update_interval in msec to conversion time in usec */
 186static inline u32 ina3221_interval_ms_to_conv_time(u16 config, int interval)
 187{
 188	u32 channels = hweight16(config & INA3221_CONFIG_CHs_EN_MASK);
 189	u32 samples_idx = INA3221_CONFIG_AVG(config);
 190	u32 samples = ina3221_avg_samples[samples_idx];
 191
 192	/* Bisect the result to Bus and Shunt conversion times */
 193	return DIV_ROUND_CLOSEST(interval * 1000 / 2, channels * samples);
 194}
 195
 196/* Converting CONFIG register value to update_interval in usec */
 197static inline u32 ina3221_reg_to_interval_us(u16 config)
 198{
 199	u32 channels = hweight16(config & INA3221_CONFIG_CHs_EN_MASK);
 200	u32 vbus_ct_idx = INA3221_CONFIG_VBUS_CT(config);
 201	u32 vsh_ct_idx = INA3221_CONFIG_VSH_CT(config);
 202	u32 vbus_ct = ina3221_conv_time[vbus_ct_idx];
 203	u32 vsh_ct = ina3221_conv_time[vsh_ct_idx];
 204
 205	/* Calculate total conversion time */
 206	return channels * (vbus_ct + vsh_ct);
 207}
 208
 209static inline int ina3221_wait_for_data(struct ina3221_data *ina)
 210{
 211	u32 wait, cvrf;
 212
 213	wait = ina3221_reg_to_interval_us(ina->reg_config);
 214
 215	/* Polling the CVRF bit to make sure read data is ready */
 216	return regmap_field_read_poll_timeout(ina->fields[F_CVRF],
 217					      cvrf, cvrf, wait, wait * 2);
 218}
 219
 220static int ina3221_read_value(struct ina3221_data *ina, unsigned int reg,
 221			      int *val)
 222{
 223	unsigned int regval;
 224	int ret;
 225
 226	ret = regmap_read(ina->regmap, reg, &regval);
 227	if (ret)
 228		return ret;
 229
 230	/*
 231	 * Shunt Voltage Sum register has 14-bit value with 1-bit shift
 232	 * Other Shunt Voltage registers have 12 bits with 3-bit shift
 233	 */
 234	if (reg == INA3221_SHUNT_SUM || reg == INA3221_CRIT_SUM)
 235		*val = sign_extend32(regval >> 1, 14);
 236	else
 237		*val = sign_extend32(regval >> 3, 12);
 238
 239	return 0;
 240}
 241
 242static const u8 ina3221_in_reg[] = {
 243	INA3221_BUS1,
 244	INA3221_BUS2,
 245	INA3221_BUS3,
 246	INA3221_SHUNT1,
 247	INA3221_SHUNT2,
 248	INA3221_SHUNT3,
 249	INA3221_SHUNT_SUM,
 250};
 251
 252static int ina3221_read_chip(struct device *dev, u32 attr, long *val)
 253{
 254	struct ina3221_data *ina = dev_get_drvdata(dev);
 255	int regval;
 256
 257	switch (attr) {
 258	case hwmon_chip_samples:
 259		regval = INA3221_CONFIG_AVG(ina->reg_config);
 260		*val = ina3221_avg_samples[regval];
 261		return 0;
 262	case hwmon_chip_update_interval:
 263		/* Return in msec */
 264		*val = ina3221_reg_to_interval_us(ina->reg_config);
 265		*val = DIV_ROUND_CLOSEST(*val, 1000);
 266		return 0;
 267	default:
 268		return -EOPNOTSUPP;
 269	}
 270}
 271
 272static int ina3221_read_in(struct device *dev, u32 attr, int channel, long *val)
 273{
 274	const bool is_shunt = channel > INA3221_CHANNEL3;
 275	struct ina3221_data *ina = dev_get_drvdata(dev);
 276	u8 reg = ina3221_in_reg[channel];
 277	int regval, ret;
 278
 279	/*
 280	 * Translate shunt channel index to sensor channel index except
 281	 * the 7th channel (6 since being 0-aligned) is for summation.
 282	 */
 283	if (channel != 6)
 284		channel %= INA3221_NUM_CHANNELS;
 285
 286	switch (attr) {
 287	case hwmon_in_input:
 288		if (!ina3221_is_enabled(ina, channel))
 289			return -ENODATA;
 290
 291		/* Write CONFIG register to trigger a single-shot measurement */
 292		if (ina->single_shot) {
 293			regmap_write(ina->regmap, INA3221_CONFIG,
 294				     ina->reg_config);
 295
 296			ret = ina3221_wait_for_data(ina);
 297			if (ret)
 298				return ret;
 299		}
 300
 301		ret = ina3221_read_value(ina, reg, &regval);
 302		if (ret)
 303			return ret;
 304
 305		/*
 306		 * Scale of shunt voltage (uV): LSB is 40uV
 307		 * Scale of bus voltage (mV): LSB is 8mV
 308		 */
 309		*val = regval * (is_shunt ? 40 : 8);
 310		return 0;
 311	case hwmon_in_enable:
 312		*val = ina3221_is_enabled(ina, channel);
 313		return 0;
 314	default:
 315		return -EOPNOTSUPP;
 316	}
 317}
 318
 319static const u8 ina3221_curr_reg[][INA3221_NUM_CHANNELS + 1] = {
 320	[hwmon_curr_input] = { INA3221_SHUNT1, INA3221_SHUNT2,
 321			       INA3221_SHUNT3, INA3221_SHUNT_SUM },
 322	[hwmon_curr_max] = { INA3221_WARN1, INA3221_WARN2, INA3221_WARN3, 0 },
 323	[hwmon_curr_crit] = { INA3221_CRIT1, INA3221_CRIT2,
 324			      INA3221_CRIT3, INA3221_CRIT_SUM },
 325	[hwmon_curr_max_alarm] = { F_WF1, F_WF2, F_WF3, 0 },
 326	[hwmon_curr_crit_alarm] = { F_CF1, F_CF2, F_CF3, F_SF },
 327};
 328
 329static int ina3221_read_curr(struct device *dev, u32 attr,
 330			     int channel, long *val)
 331{
 332	struct ina3221_data *ina = dev_get_drvdata(dev);
 333	struct ina3221_input *input = ina->inputs;
 334	u8 reg = ina3221_curr_reg[attr][channel];
 335	int resistance_uo, voltage_nv;
 336	int regval, ret;
 337
 338	if (channel > INA3221_CHANNEL3)
 339		resistance_uo = ina->summation_shunt_resistor;
 340	else
 341		resistance_uo = input[channel].shunt_resistor;
 342
 343	switch (attr) {
 344	case hwmon_curr_input:
 345		if (!ina3221_is_enabled(ina, channel))
 346			return -ENODATA;
 347
 348		/* Write CONFIG register to trigger a single-shot measurement */
 349		if (ina->single_shot) {
 350			regmap_write(ina->regmap, INA3221_CONFIG,
 351				     ina->reg_config);
 352
 353			ret = ina3221_wait_for_data(ina);
 354			if (ret)
 355				return ret;
 356		}
 357
 358		fallthrough;
 359	case hwmon_curr_crit:
 360	case hwmon_curr_max:
 361		if (!resistance_uo)
 362			return -ENODATA;
 363
 364		ret = ina3221_read_value(ina, reg, &regval);
 365		if (ret)
 366			return ret;
 367
 368		/* Scale of shunt voltage: LSB is 40uV (40000nV) */
 369		voltage_nv = regval * 40000;
 370		/* Return current in mA */
 371		*val = DIV_ROUND_CLOSEST(voltage_nv, resistance_uo);
 372		return 0;
 373	case hwmon_curr_crit_alarm:
 374	case hwmon_curr_max_alarm:
 375		/* No actual register read if channel is disabled */
 376		if (!ina3221_is_enabled(ina, channel)) {
 377			/* Return 0 for alert flags */
 378			*val = 0;
 379			return 0;
 380		}
 381		ret = regmap_field_read(ina->fields[reg], &regval);
 382		if (ret)
 383			return ret;
 384		*val = regval;
 385		return 0;
 386	default:
 387		return -EOPNOTSUPP;
 388	}
 389}
 390
 391static int ina3221_write_chip(struct device *dev, u32 attr, long val)
 392{
 393	struct ina3221_data *ina = dev_get_drvdata(dev);
 394	int ret, idx;
 395	u32 tmp;
 396
 397	switch (attr) {
 398	case hwmon_chip_samples:
 399		idx = find_closest(val, ina3221_avg_samples,
 400				   ARRAY_SIZE(ina3221_avg_samples));
 401
 402		tmp = (ina->reg_config & ~INA3221_CONFIG_AVG_MASK) |
 403		      (idx << INA3221_CONFIG_AVG_SHIFT);
 404		ret = regmap_write(ina->regmap, INA3221_CONFIG, tmp);
 405		if (ret)
 406			return ret;
 407
 408		/* Update reg_config accordingly */
 409		ina->reg_config = tmp;
 410		return 0;
 411	case hwmon_chip_update_interval:
 412		tmp = ina3221_interval_ms_to_conv_time(ina->reg_config, val);
 413		idx = find_closest(tmp, ina3221_conv_time,
 414				   ARRAY_SIZE(ina3221_conv_time));
 415
 416		/* Update Bus and Shunt voltage conversion times */
 417		tmp = INA3221_CONFIG_VBUS_CT_MASK | INA3221_CONFIG_VSH_CT_MASK;
 418		tmp = (ina->reg_config & ~tmp) |
 419		      (idx << INA3221_CONFIG_VBUS_CT_SHIFT) |
 420		      (idx << INA3221_CONFIG_VSH_CT_SHIFT);
 421		ret = regmap_write(ina->regmap, INA3221_CONFIG, tmp);
 422		if (ret)
 423			return ret;
 424
 425		/* Update reg_config accordingly */
 426		ina->reg_config = tmp;
 427		return 0;
 428	default:
 429		return -EOPNOTSUPP;
 430	}
 431}
 432
 433static int ina3221_write_curr(struct device *dev, u32 attr,
 434			      int channel, long val)
 435{
 436	struct ina3221_data *ina = dev_get_drvdata(dev);
 437	struct ina3221_input *input = ina->inputs;
 438	u8 reg = ina3221_curr_reg[attr][channel];
 439	int resistance_uo, current_ma, voltage_uv;
 440	int regval;
 441
 442	if (channel > INA3221_CHANNEL3)
 443		resistance_uo = ina->summation_shunt_resistor;
 444	else
 445		resistance_uo = input[channel].shunt_resistor;
 446
 447	if (!resistance_uo)
 448		return -EOPNOTSUPP;
 449
 450	/* clamp current */
 451	current_ma = clamp_val(val,
 452			       INT_MIN / resistance_uo,
 453			       INT_MAX / resistance_uo);
 454
 455	voltage_uv = DIV_ROUND_CLOSEST(current_ma * resistance_uo, 1000);
 456
 457	/* clamp voltage */
 458	voltage_uv = clamp_val(voltage_uv, -163800, 163800);
 459
 460	/*
 461	 * Formula to convert voltage_uv to register value:
 462	 *     regval = (voltage_uv / scale) << shift
 463	 * Note:
 464	 *     The scale is 40uV for all shunt voltage registers
 465	 *     Shunt Voltage Sum register left-shifts 1 bit
 466	 *     All other Shunt Voltage registers shift 3 bits
 467	 * Results:
 468	 *     SHUNT_SUM: (1 / 40uV) << 1 = 1 / 20uV
 469	 *     SHUNT[1-3]: (1 / 40uV) << 3 = 1 / 5uV
 470	 */
 471	if (reg == INA3221_SHUNT_SUM || reg == INA3221_CRIT_SUM)
 472		regval = DIV_ROUND_CLOSEST(voltage_uv, 20) & 0xfffe;
 473	else
 474		regval = DIV_ROUND_CLOSEST(voltage_uv, 5) & 0xfff8;
 475
 476	return regmap_write(ina->regmap, reg, regval);
 477}
 478
 479static int ina3221_write_enable(struct device *dev, int channel, bool enable)
 480{
 481	struct ina3221_data *ina = dev_get_drvdata(dev);
 482	u16 config, mask = INA3221_CONFIG_CHx_EN(channel);
 483	u16 config_old = ina->reg_config & mask;
 484	u32 tmp;
 485	int ret;
 486
 487	config = enable ? mask : 0;
 488
 489	/* Bypass if enable status is not being changed */
 490	if (config_old == config)
 491		return 0;
 492
 493	/* For enabling routine, increase refcount and resume() at first */
 494	if (enable) {
 495		ret = pm_runtime_resume_and_get(ina->pm_dev);
 496		if (ret < 0) {
 497			dev_err(dev, "Failed to get PM runtime\n");
 498			return ret;
 499		}
 500	}
 501
 502	/* Enable or disable the channel */
 503	tmp = (ina->reg_config & ~mask) | (config & mask);
 504	ret = regmap_write(ina->regmap, INA3221_CONFIG, tmp);
 505	if (ret)
 506		goto fail;
 507
 508	/* Cache the latest config register value */
 509	ina->reg_config = tmp;
 510
 511	/* For disabling routine, decrease refcount or suspend() at last */
 512	if (!enable)
 513		pm_runtime_put_sync(ina->pm_dev);
 514
 515	return 0;
 516
 517fail:
 518	if (enable) {
 519		dev_err(dev, "Failed to enable channel %d: error %d\n",
 520			channel, ret);
 521		pm_runtime_put_sync(ina->pm_dev);
 522	}
 523
 524	return ret;
 525}
 526
 527static int ina3221_read(struct device *dev, enum hwmon_sensor_types type,
 528			u32 attr, int channel, long *val)
 529{
 530	int ret;
 531
 532	switch (type) {
 533	case hwmon_chip:
 534		ret = ina3221_read_chip(dev, attr, val);
 535		break;
 536	case hwmon_in:
 537		/* 0-align channel ID */
 538		ret = ina3221_read_in(dev, attr, channel - 1, val);
 539		break;
 540	case hwmon_curr:
 541		ret = ina3221_read_curr(dev, attr, channel, val);
 542		break;
 543	default:
 544		ret = -EOPNOTSUPP;
 545		break;
 546	}
 547	return ret;
 548}
 549
 550static int ina3221_write(struct device *dev, enum hwmon_sensor_types type,
 551			 u32 attr, int channel, long val)
 552{
 553	int ret;
 554
 555	switch (type) {
 556	case hwmon_chip:
 557		ret = ina3221_write_chip(dev, attr, val);
 558		break;
 559	case hwmon_in:
 560		/* 0-align channel ID */
 561		ret = ina3221_write_enable(dev, channel - 1, val);
 562		break;
 563	case hwmon_curr:
 564		ret = ina3221_write_curr(dev, attr, channel, val);
 565		break;
 566	default:
 567		ret = -EOPNOTSUPP;
 568		break;
 569	}
 570	return ret;
 571}
 572
 573static int ina3221_read_string(struct device *dev, enum hwmon_sensor_types type,
 574			       u32 attr, int channel, const char **str)
 575{
 576	struct ina3221_data *ina = dev_get_drvdata(dev);
 577	int index = channel - 1;
 578
 579	if (channel == 7)
 580		*str = "sum of shunt voltages";
 581	else
 582		*str = ina->inputs[index].label;
 583
 584	return 0;
 585}
 586
 587static umode_t ina3221_is_visible(const void *drvdata,
 588				  enum hwmon_sensor_types type,
 589				  u32 attr, int channel)
 590{
 591	const struct ina3221_data *ina = drvdata;
 592	const struct ina3221_input *input = NULL;
 593
 594	switch (type) {
 595	case hwmon_chip:
 596		switch (attr) {
 597		case hwmon_chip_samples:
 598		case hwmon_chip_update_interval:
 599			return 0644;
 600		default:
 601			return 0;
 602		}
 603	case hwmon_in:
 604		/* Ignore in0_ */
 605		if (channel == 0)
 606			return 0;
 607
 608		switch (attr) {
 609		case hwmon_in_label:
 610			if (channel - 1 <= INA3221_CHANNEL3)
 611				input = &ina->inputs[channel - 1];
 612			else if (channel == 7)
 613				return 0444;
 614			/* Hide label node if label is not provided */
 615			return (input && input->label) ? 0444 : 0;
 616		case hwmon_in_input:
 617			return 0444;
 618		case hwmon_in_enable:
 619			return 0644;
 620		default:
 621			return 0;
 622		}
 623	case hwmon_curr:
 624		switch (attr) {
 625		case hwmon_curr_input:
 626		case hwmon_curr_crit_alarm:
 627		case hwmon_curr_max_alarm:
 628			return 0444;
 629		case hwmon_curr_crit:
 630		case hwmon_curr_max:
 631			return 0644;
 632		default:
 633			return 0;
 634		}
 635	default:
 636		return 0;
 637	}
 638}
 639
 640#define INA3221_HWMON_CURR_CONFIG (HWMON_C_INPUT | \
 641				   HWMON_C_CRIT | HWMON_C_CRIT_ALARM | \
 642				   HWMON_C_MAX | HWMON_C_MAX_ALARM)
 643
 644static const struct hwmon_channel_info * const ina3221_info[] = {
 645	HWMON_CHANNEL_INFO(chip,
 646			   HWMON_C_SAMPLES,
 647			   HWMON_C_UPDATE_INTERVAL),
 648	HWMON_CHANNEL_INFO(in,
 649			   /* 0: dummy, skipped in is_visible */
 650			   HWMON_I_INPUT,
 651			   /* 1-3: input voltage Channels */
 652			   HWMON_I_INPUT | HWMON_I_ENABLE | HWMON_I_LABEL,
 653			   HWMON_I_INPUT | HWMON_I_ENABLE | HWMON_I_LABEL,
 654			   HWMON_I_INPUT | HWMON_I_ENABLE | HWMON_I_LABEL,
 655			   /* 4-6: shunt voltage Channels */
 656			   HWMON_I_INPUT,
 657			   HWMON_I_INPUT,
 658			   HWMON_I_INPUT,
 659			   /* 7: summation of shunt voltage channels */
 660			   HWMON_I_INPUT | HWMON_I_LABEL),
 661	HWMON_CHANNEL_INFO(curr,
 662			   /* 1-3: current channels*/
 663			   INA3221_HWMON_CURR_CONFIG,
 664			   INA3221_HWMON_CURR_CONFIG,
 665			   INA3221_HWMON_CURR_CONFIG,
 666			   /* 4: summation of current channels */
 667			   HWMON_C_INPUT | HWMON_C_CRIT | HWMON_C_CRIT_ALARM),
 668	NULL
 669};
 670
 671static const struct hwmon_ops ina3221_hwmon_ops = {
 672	.is_visible = ina3221_is_visible,
 673	.read_string = ina3221_read_string,
 674	.read = ina3221_read,
 675	.write = ina3221_write,
 676};
 677
 678static const struct hwmon_chip_info ina3221_chip_info = {
 679	.ops = &ina3221_hwmon_ops,
 680	.info = ina3221_info,
 681};
 682
 683/* Extra attribute groups */
 684static ssize_t ina3221_shunt_show(struct device *dev,
 685				  struct device_attribute *attr, char *buf)
 686{
 687	struct sensor_device_attribute *sd_attr = to_sensor_dev_attr(attr);
 688	struct ina3221_data *ina = dev_get_drvdata(dev);
 689	unsigned int channel = sd_attr->index;
 690	struct ina3221_input *input = &ina->inputs[channel];
 691
 692	return sysfs_emit(buf, "%d\n", input->shunt_resistor);
 693}
 694
 695static ssize_t ina3221_shunt_store(struct device *dev,
 696				   struct device_attribute *attr,
 697				   const char *buf, size_t count)
 698{
 699	struct sensor_device_attribute *sd_attr = to_sensor_dev_attr(attr);
 700	struct ina3221_data *ina = dev_get_drvdata(dev);
 701	unsigned int channel = sd_attr->index;
 702	struct ina3221_input *input = &ina->inputs[channel];
 703	int val;
 704	int ret;
 705
 706	ret = kstrtoint(buf, 0, &val);
 707	if (ret)
 708		return ret;
 709
 710	val = clamp_val(val, 1, INT_MAX);
 711
 712	input->shunt_resistor = val;
 713
 714	/* Update summation_shunt_resistor for summation channel */
 715	ina->summation_shunt_resistor = ina3221_summation_shunt_resistor(ina);
 716
 717	return count;
 718}
 719
 720/* shunt resistance */
 721static SENSOR_DEVICE_ATTR_RW(shunt1_resistor, ina3221_shunt, INA3221_CHANNEL1);
 722static SENSOR_DEVICE_ATTR_RW(shunt2_resistor, ina3221_shunt, INA3221_CHANNEL2);
 723static SENSOR_DEVICE_ATTR_RW(shunt3_resistor, ina3221_shunt, INA3221_CHANNEL3);
 724
 725static struct attribute *ina3221_attrs[] = {
 726	&sensor_dev_attr_shunt1_resistor.dev_attr.attr,
 727	&sensor_dev_attr_shunt2_resistor.dev_attr.attr,
 728	&sensor_dev_attr_shunt3_resistor.dev_attr.attr,
 729	NULL,
 730};
 731ATTRIBUTE_GROUPS(ina3221);
 732
 733static const struct regmap_range ina3221_yes_ranges[] = {
 734	regmap_reg_range(INA3221_CONFIG, INA3221_BUS3),
 735	regmap_reg_range(INA3221_SHUNT_SUM, INA3221_SHUNT_SUM),
 736	regmap_reg_range(INA3221_MASK_ENABLE, INA3221_MASK_ENABLE),
 737};
 738
 739static const struct regmap_access_table ina3221_volatile_table = {
 740	.yes_ranges = ina3221_yes_ranges,
 741	.n_yes_ranges = ARRAY_SIZE(ina3221_yes_ranges),
 742};
 743
 744static const struct regmap_config ina3221_regmap_config = {
 745	.reg_bits = 8,
 746	.val_bits = 16,
 747
 748	.cache_type = REGCACHE_MAPLE,
 749	.volatile_table = &ina3221_volatile_table,
 750};
 751
 752static int ina3221_probe_child_from_dt(struct device *dev,
 753				       struct device_node *child,
 754				       struct ina3221_data *ina)
 755{
 756	struct ina3221_input *input;
 757	u32 val;
 758	int ret;
 759
 760	ret = of_property_read_u32(child, "reg", &val);
 761	if (ret) {
 762		dev_err(dev, "missing reg property of %pOFn\n", child);
 763		return ret;
 764	} else if (val > INA3221_CHANNEL3) {
 765		dev_err(dev, "invalid reg %d of %pOFn\n", val, child);
 766		return -EINVAL;
 767	}
 768
 769	input = &ina->inputs[val];
 770
 771	/* Log the disconnected channel input */
 772	if (!of_device_is_available(child)) {
 773		input->disconnected = true;
 774		return 0;
 775	}
 776
 777	/* Save the connected input label if available */
 778	of_property_read_string(child, "label", &input->label);
 779
 780	/* summation channel control */
 781	input->summation_disable = of_property_read_bool(child, "ti,summation-disable");
 782
 783	/* Overwrite default shunt resistor value optionally */
 784	if (!of_property_read_u32(child, "shunt-resistor-micro-ohms", &val)) {
 785		if (val < 1 || val > INT_MAX) {
 786			dev_err(dev, "invalid shunt resistor value %u of %pOFn\n",
 787				val, child);
 788			return -EINVAL;
 789		}
 790		input->shunt_resistor = val;
 791	}
 792
 793	return 0;
 794}
 795
 796static int ina3221_probe_from_dt(struct device *dev, struct ina3221_data *ina)
 797{
 798	const struct device_node *np = dev->of_node;
 799	int ret;
 800
 801	/* Compatible with non-DT platforms */
 802	if (!np)
 803		return 0;
 804
 805	ina->single_shot = of_property_read_bool(np, "ti,single-shot");
 806
 807	for_each_child_of_node_scoped(np, child) {
 808		ret = ina3221_probe_child_from_dt(dev, child, ina);
 809		if (ret)
 810			return ret;
 811	}
 812
 813	return 0;
 814}
 815
 816static int ina3221_probe(struct i2c_client *client)
 817{
 818	struct device *dev = &client->dev;
 819	struct ina3221_data *ina;
 820	struct device *hwmon_dev;
 821	char name[32];
 822	int i, ret;
 823
 824	ina = devm_kzalloc(dev, sizeof(*ina), GFP_KERNEL);
 825	if (!ina)
 826		return -ENOMEM;
 827
 828	ina->regmap = devm_regmap_init_i2c(client, &ina3221_regmap_config);
 829	if (IS_ERR(ina->regmap)) {
 830		dev_err(dev, "Unable to allocate register map\n");
 831		return PTR_ERR(ina->regmap);
 832	}
 833
 834	for (i = 0; i < F_MAX_FIELDS; i++) {
 835		ina->fields[i] = devm_regmap_field_alloc(dev,
 836							 ina->regmap,
 837							 ina3221_reg_fields[i]);
 838		if (IS_ERR(ina->fields[i])) {
 839			dev_err(dev, "Unable to allocate regmap fields\n");
 840			return PTR_ERR(ina->fields[i]);
 841		}
 842	}
 843
 844	for (i = 0; i < INA3221_NUM_CHANNELS; i++)
 845		ina->inputs[i].shunt_resistor = INA3221_RSHUNT_DEFAULT;
 846
 847	ret = ina3221_probe_from_dt(dev, ina);
 848	if (ret) {
 849		dev_err(dev, "Unable to probe from device tree\n");
 850		return ret;
 851	}
 852
 853	/* The driver will be reset, so use reset value */
 854	ina->reg_config = INA3221_CONFIG_DEFAULT;
 855
 856	/* Clear continuous bit to use single-shot mode */
 857	if (ina->single_shot)
 858		ina->reg_config &= ~INA3221_CONFIG_MODE_CONTINUOUS;
 859
 860	/* Disable channels if their inputs are disconnected */
 861	for (i = 0; i < INA3221_NUM_CHANNELS; i++) {
 862		if (ina->inputs[i].disconnected)
 863			ina->reg_config &= ~INA3221_CONFIG_CHx_EN(i);
 864	}
 865
 866	/* Initialize summation_shunt_resistor for summation channel control */
 867	ina->summation_shunt_resistor = ina3221_summation_shunt_resistor(ina);
 868	for (i = 0; i < INA3221_NUM_CHANNELS; i++) {
 869		if (!ina->inputs[i].summation_disable)
 870			ina->summation_channel_control |= BIT(14 - i);
 871	}
 872
 873	ina->pm_dev = dev;
 874	dev_set_drvdata(dev, ina);
 875
 876	/* Enable PM runtime -- status is suspended by default */
 877	pm_runtime_enable(ina->pm_dev);
 878
 879	/* Initialize (resume) the device */
 880	for (i = 0; i < INA3221_NUM_CHANNELS; i++) {
 881		if (ina->inputs[i].disconnected)
 882			continue;
 883		/* Match the refcount with number of enabled channels */
 884		ret = pm_runtime_get_sync(ina->pm_dev);
 885		if (ret < 0)
 886			goto fail;
 887	}
 888
 889	hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, ina,
 890							 &ina3221_chip_info,
 891							 ina3221_groups);
 892	if (IS_ERR(hwmon_dev)) {
 893		dev_err(dev, "Unable to register hwmon device\n");
 894		ret = PTR_ERR(hwmon_dev);
 895		goto fail;
 896	}
 897
 898	for (i = 0; i < INA3221_NUM_CHANNELS; i++) {
 899		scnprintf(name, sizeof(name), "in%d_summation_disable", i);
 900		debugfs_create_bool(name, 0400, client->debugfs,
 901				    &ina->inputs[i].summation_disable);
 902	}
 903
 904	return 0;
 905
 906fail:
 907	pm_runtime_disable(ina->pm_dev);
 908	pm_runtime_set_suspended(ina->pm_dev);
 909	/* pm_runtime_put_noidle() will decrease the PM refcount until 0 */
 910	for (i = 0; i < INA3221_NUM_CHANNELS; i++)
 911		pm_runtime_put_noidle(ina->pm_dev);
 912
 913	return ret;
 914}
 915
 916static void ina3221_remove(struct i2c_client *client)
 917{
 918	struct ina3221_data *ina = dev_get_drvdata(&client->dev);
 919	int i;
 920
 921	pm_runtime_disable(ina->pm_dev);
 922	pm_runtime_set_suspended(ina->pm_dev);
 923
 924	/* pm_runtime_put_noidle() will decrease the PM refcount until 0 */
 925	for (i = 0; i < INA3221_NUM_CHANNELS; i++)
 926		pm_runtime_put_noidle(ina->pm_dev);
 927}
 928
 929static int ina3221_suspend(struct device *dev)
 930{
 931	struct ina3221_data *ina = dev_get_drvdata(dev);
 932	int ret;
 933
 934	/* Save config register value and enable cache-only */
 935	ret = regmap_read(ina->regmap, INA3221_CONFIG, &ina->reg_config);
 936	if (ret)
 937		return ret;
 938
 939	/* Set to power-down mode for power saving */
 940	ret = regmap_update_bits(ina->regmap, INA3221_CONFIG,
 941				 INA3221_CONFIG_MODE_MASK,
 942				 INA3221_CONFIG_MODE_POWERDOWN);
 943	if (ret)
 944		return ret;
 945
 946	regcache_cache_only(ina->regmap, true);
 947	regcache_mark_dirty(ina->regmap);
 948
 949	return 0;
 950}
 951
 952static int ina3221_resume(struct device *dev)
 953{
 954	struct ina3221_data *ina = dev_get_drvdata(dev);
 955	int ret;
 956
 957	regcache_cache_only(ina->regmap, false);
 958
 959	/* Software reset the chip */
 960	ret = regmap_field_write(ina->fields[F_RST], true);
 961	if (ret) {
 962		dev_err(dev, "Unable to reset device\n");
 963		return ret;
 964	}
 965
 966	/* Restore cached register values to hardware */
 967	ret = regcache_sync(ina->regmap);
 968	if (ret)
 969		return ret;
 970
 971	/* Restore config register value to hardware */
 972	ret = regmap_write(ina->regmap, INA3221_CONFIG, ina->reg_config);
 973	if (ret)
 974		return ret;
 975
 976	/* Initialize summation channel control */
 977	if (ina->summation_shunt_resistor) {
 978		/*
 979		 * Sum only channels that are not disabled for summation.
 980		 * Shunt measurements of disconnected channels should
 981		 * be 0, so it does not matter for summation.
 982		 */
 983		ret = regmap_update_bits(ina->regmap, INA3221_MASK_ENABLE,
 984					 INA3221_MASK_ENABLE_SCC_MASK,
 985					 ina->summation_channel_control);
 986		if (ret) {
 987			dev_err(dev, "Unable to control summation channel\n");
 988			return ret;
 989		}
 990	}
 991
 992	return 0;
 993}
 994
 995static DEFINE_RUNTIME_DEV_PM_OPS(ina3221_pm, ina3221_suspend, ina3221_resume,
 996				 NULL);
 997
 998static const struct of_device_id ina3221_of_match_table[] = {
 999	{ .compatible = "ti,ina3221", },
1000	{ /* sentinel */ }
1001};
1002MODULE_DEVICE_TABLE(of, ina3221_of_match_table);
1003
1004static const struct i2c_device_id ina3221_ids[] = {
1005	{ "ina3221" },
1006	{ /* sentinel */ }
1007};
1008MODULE_DEVICE_TABLE(i2c, ina3221_ids);
1009
1010static struct i2c_driver ina3221_i2c_driver = {
1011	.probe = ina3221_probe,
1012	.remove = ina3221_remove,
1013	.driver = {
1014		.name = INA3221_DRIVER_NAME,
1015		.of_match_table = ina3221_of_match_table,
1016		.pm = pm_ptr(&ina3221_pm),
1017	},
1018	.id_table = ina3221_ids,
1019};
1020module_i2c_driver(ina3221_i2c_driver);
1021
1022MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>");
1023MODULE_DESCRIPTION("Texas Instruments INA3221 HWMon Driver");
1024MODULE_LICENSE("GPL v2");
~/ Read-only file preview.