Commit Graph

24 Commits

Author SHA1 Message Date
Nicolin Chen 2057bdfb71 hwmon: (ina3221) Add summation feature support
This patch implements the summation feature of INA3221, mainly the
SCC (enabling) and SF (warning flag) bits of MASK_ENABLE register,
INA3221_SHUNT_SUM (summation of shunt voltages) register, and the
INA3221_CRIT_SUM (its critical alert setting) register.

Although the summation feature allows user to select which channels
to be added to the result, as an initial support, this patch simply
selects all channels by default, with one only condition: all shunt
resistor values need to be the same. This is because the summation
of current channels can be only accurately calculated, using shunt
voltage sum register, if all shunt resistors are equivalent.

Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
Link: https://lore.kernel.org/r/20191016235702.22039-1-nicoleotsuka@gmail.com
[groeck: summation->sum in documentation and label]
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2019-11-06 14:37:19 -08:00
Nicolin Chen 2ccb4f16d0 hwmon: (ina3221) Fix read timeout issue
After introducing "samples" to the calculation of wait time, the
driver might timeout at the regmap_field_read_poll_timeout call,
because the wait time could be longer than the 100000 usec limit
due to a large "samples" number.

So this patch sets the timeout limit to 2 times of the wait time
in order to fix this issue.

Fixes: 5c090abf94 ("hwmon: (ina3221) Add averaging mode support")
Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
Link: https://lore.kernel.org/r/20191022005922.30239-1-nicoleotsuka@gmail.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2019-10-28 18:46:55 -07:00
Nishka Dasgupta 9f7546570b hwmon: (ina3221) Add of_node_put() before return
Each iteration of for_each_child_of_node puts the previous
node, but in the case of a return from the middle of the loop, there is
no put, thus causing a memory leak. Hence add an of_node_put before the
return.
Issue found with Coccinelle.

Signed-off-by: Nishka Dasgupta <nishkadg.linux@gmail.com>
Link: https://lore.kernel.org/r/20190706132130.3129-1-nishkadg.linux@gmail.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2019-07-08 18:11:32 -07:00
Thomas Gleixner 1802d0beec treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 174
Based on 1 normalized pattern(s):

  this program is free software you can redistribute it and or modify
  it under the terms of the gnu general public license version 2 as
  published by the free software foundation this program is
  distributed in the hope that it will be useful but without any
  warranty without even the implied warranty of merchantability or
  fitness for a particular purpose see the gnu general public license
  for more details

extracted by the scancode license scanner the SPDX license identifier

  GPL-2.0-only

has been chosen to replace the boilerplate/reference in 655 file(s).

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Allison Randal <allison@lohutok.net>
Reviewed-by: Kate Stewart <kstewart@linuxfoundation.org>
Reviewed-by: Richard Fontana <rfontana@redhat.com>
Cc: linux-spdx@vger.kernel.org
Link: https://lkml.kernel.org/r/20190527070034.575739538@linutronix.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2019-05-30 11:26:41 -07:00
Nicolin Chen 023912dbb8 hwmon: (ina3221) Add voltage conversion time settings
The CONFIG register has two 3-bit fields for conversion time
settings of Bus-voltage and Shunt-voltage, respectively. The
conversion settings, along with averaging mode, allow users
to optimize available timing requirement.

This patch adds an 'update_interval' sysfs node through the
hwmon_chip_info of hwmon core. It reflects a total hardware
conversion time:
    samples * channels * (Bus + Shunt conversion times)

Though INA3221 supports different conversion time setups for
Bus and Shunt voltages, this patch only adds the support of
a unified setting for both conversion times, by dividing the
conversion time into two equal values.

Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
[groeck: .rst related formatting changes in documentation]
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2019-04-18 06:44:11 -07:00
Nicolin Chen 521c0b6116 hwmon: (ina3221) Do not read-back to cache reg_config
Reading back the CONFIG register increases an extra I2C
transaction. This's not necessary and could be replaced
with a local variable caching the register settings.

So this patch replaces two readback regmap_read() calls
with a tmp variable.

Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2019-04-18 06:37:25 -07:00
Nicolin Chen 5c090abf94 hwmon: (ina3221) Add averaging mode support
The CONFIG register has a 3-bit averaging mode field for users
to setup the number of samples that are collected and averaged
together. This is very useful to filter noise from sensor data.

This patch adds a 'samples' sysfs node using hwmon_chip_samples
of hwmon core, and updates wait time calculation by taking this
samples value into account.

Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2019-04-16 13:10:20 -07:00
Guenter Roeck 6f307b7c2b hwmon: (ina3221) Use HWMON_CHANNEL_INFO macro
The HWMON_CHANNEL_INFO macro simplifies the code, reduces the likelihood
of errors, and makes the code easier to read.

The conversion was done automatically with coccinelle. The semantic patch
used to make this change is as follows.

@r@
initializer list elements;
identifier i;
@@

-u32 i[] = {
-  elements,
-  0
-};

@s@
identifier r.i,j,ty;
@@

-struct hwmon_channel_info j = {
-       .type = ty,
-       .config = i,
-};

@script:ocaml t@
ty << s.ty;
elements << r.elements;
shorter;
elems;
@@

shorter :=
   make_ident (List.hd(List.rev (Str.split (Str.regexp "_") ty)));
elems :=
   make_ident
    (String.concat ","
     (List.map (fun x -> Printf.sprintf "\n\t\t\t   %s" x)
       (Str.split (Str.regexp " , ") elements)))

@@
identifier s.j,t.shorter;
identifier t.elems;
@@

- &j
+ HWMON_CHANNEL_INFO(shorter,elems)

This patch does not introduce functional changes. Many thanks to
Julia Lawall for providing the semantic patch.

The patch was post-edited to retain comments.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2019-04-15 17:19:53 -07:00
Nicolin Chen 43dece162d hwmon: (ina3221) Implement ti,single-shot DT property
By default, ina3221, as a hardware monitor, continuously measures
the inputs and generates corresponding data. However, for battery
powered devices, this mode might be power consuming.

The DT binding doc is updated with a new boolean type property to
allow changing the default operating mode from consuming mode to
single-shot mode, which will measure input on demand and then shut
down to save power.

So this patch implements the DT property accordingly.

Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2019-02-18 14:23:29 -08:00
Guenter Roeck a4ec92ed8b hwmon: (ina3221) Use permission specific SENSOR[_DEVICE]_ATTR variants
Use SENSOR[_DEVICE]_ATTR[_2]_{RO,RW,WO} to simplify the source code,
to improve readability, and to reduce the chance of inconsistencies.

Also replace any remaining S_<PERMS> in the driver with octal values.

The conversion was done automatically with coccinelle. The semantic patches
and the scripts used to generate this commit log are available at
https://github.com/groeck/coccinelle-patches/hwmon/.

This patch does not introduce functional changes. It was verified by
compiling the old and new files and comparing text and data sizes.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2019-02-18 14:23:29 -08:00
Rob Herring 1b1f4efab0 hwmon: (ina3221) Convert to using %pOFn instead of device_node.name
In preparation to remove the node name pointer from struct device_node,
convert printf users to use the %pOFn format specifier.

Cc: Jean Delvare <jdelvare@suse.com>
Cc: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Rob Herring <robh@kernel.org>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2018-12-16 15:13:14 -08:00
Nicolin Chen 323aeb0eb5 hwmon: (ina3221) Add PM runtime support
If all three channels are disabled via in[123]_enable ABI,
the driver could suspend the chip for power saving purpose.

So this patch adds the PM runtime support in order to gain
more power control than system suspend and resume use case.

For PM runtime, there are a few related changes happening:
1) Added a new pm_dev device pointer for all the PM runtime
   callbacks. This is because hwmon core registers a child
   device for each hwmon driver and passes it back to each
   driver. So there might be a mismatch between two device
   pointers in the driver if mixing using them.
2) Added a check in ina3221_is_enabled() to make sure that
   the chip is resumed.
3) Bypassed the unchanged status in ina3221_write_enable()
   in order to keep the PM runtime refcount being matched.
4) Removed the reset routine in the probe() by calling the
   resume() via pm_runtime_get_sync() instead, as they're
   similar. It's also necessary to do so to match initial
   PM refcount with the number of enabled channels.

Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2018-12-16 15:13:13 -08:00
Nicolin Chen 4c0415a371 hwmon: (ina3221) Make sure data is ready before reading
The data might need some time to get ready after channel enabling,
although the data register is always readable. The CVRF bit is to
indicate that data conversion is finished, so polling the CVRF bit
before data reading could ensure the result being valid.

An alternative way could be to wait for expected time between the
channel enabling and the data reading. And this could avoid extra
I2C communications. However, INA3221 seemly takes longer time than
what's stated in the datasheet. Test results show that sometimes
it couldn't finish data conversion in time.

So this patch plays safe by adding a CVRF polling to make sure the
data register is updated with the new data.

Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2018-12-16 15:13:12 -08:00
Nicolin Chen 87625b2498 hwmon: (ina3221) Serialize sysfs ABI accesses
This change adds a mutex to serialize accesses of sysfs attributes.

This is required when polling CVRF bit of the MASK/ENABLE register
because this bit is cleared on a read of this MASK/ENABLE register
or a write to CONFIG register, which means that this bit might be
accidentally cleared by reading other fields like alert flags.

So this patch adds a mutex lock to protect the write() and read()
callbacks. The read_string() callback won't need the lock since it
just returns the label without touching any hardware register.

Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2018-12-16 15:13:11 -08:00
Nicolin Chen efb0489ea8 hwmon: (ina3221) Check channel status for alarms attribute read
There is nothing critically wrong to read these two attributes
without having a is_enabled() check at this point. But reading
the MASK_ENABLE register would clear the CVRF bit according to
the datasheet. So it'd be safer to fence for disabled channels
in order to add pm runtime feature.

Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2018-12-16 15:13:11 -08:00
Nicolin Chen d4b0166d28 hwmon: (ina3221) Use _info API to register hwmon device
The hwmon core has a newer API which abstracts most of common
things in the core so as to simplify the hwmon device drivers.

This patch implements this _info API to ina3221 hwmon driver.

It also reduces the binary size:
   text	   data	    bss	    dec	    hex	filename
   5114	   1712	      0	   6826	   1aaa	drivers/hwmon/ina3221_before.o
   4456	    440	      0	   4896	   1320	drivers/hwmon/ina3221.o

Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2018-10-10 20:37:13 -07:00
Nicolin Chen a6e43263ed hwmon: (ina3221) Validate shunt resistor value from DT
The input->shunt_resistor is int type while the value from DT is
unsigned int. Meanwhile, a divide-by-zero error would happen if
the value is 0. So this patch just simply validates the value.

Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2018-10-10 20:37:13 -07:00
Arnd Bergmann ead21c77d7 hwmon: (ina3221) mark PM functions as __maybe_unused
When CONFIG_PM_SLEEP is disabled, we get a warning about unused
suspend/resume functions:

drivers/hwmon/ina3221.c:451:12: error: 'ina3221_resume' defined but not used [-Werror=unused-function]
 static int ina3221_resume(struct device *dev)
drivers/hwmon/ina3221.c:428:12: error: 'ina3221_suspend' defined but not used [-Werror=unused-function]
 static int ina3221_suspend(struct device *dev)

Picking the correct #ifdef check is hard, so let's remove
that check and instead mark the functions as __maybe_unused
to let the compiler silently drop them instead.

Fixes: 7de1ab9dac8e ("hwmon: (ina3221) Add suspend and resume functions")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2018-10-10 20:37:13 -07:00
Nicolin Chen a9e9dd9c6d hwmon: (ina3221) Read channel input source info from DT
An ina3221 chip has three input ports. Each port is used
to measure the voltage and current of its input source.

The DT binding now has defined bindings for their input
sources, so the driver should read these information and
handle accordingly.

This patch adds a new structure of input source specific
information including input source label, shunt resistor
value and its connection status. It exposes these labels
via in[123]_label sysfs nodes upon available, and also
disables those channels where there are no input source
being connected. Meanwhile, it also adds in[123]_enable
sysfs nodes for users to get control of three channels,
and returns -ENODATA code for any sensor read according
to hwmon ABI.

Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2018-10-10 20:37:13 -07:00
Nicolin Chen 59d608e152 hwmon: (ina3221) Add suspend and resume functions
Depending on the hardware design, an INA3221 chip might lose
its power during system suspend/resume. So this patch adds
a set of suspend and resume functions to cache the register
values including config register value and limit settings.

Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
[groeck: Moved call to dev_set_drvdata()]
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2018-10-10 20:37:13 -07:00
Nicolin Chen 791ebc9d34 hwmon: (ina3221) Fix INA3221_CONFIG_MODE macros
The three INA3221_CONFIG_MODE macros are not correctly defined here.
The MODE3-1 bits are located at BIT 2-0 according to the datasheet.

So this patch just fixes them by shifting all of them with a correct
offset. However, this isn't a crital bug fix as the driver does not
use any of them at this point.

Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2018-10-10 20:37:13 -07:00
Nicolin Chen c20217b30d hwmon: (ina3221) Add INA3221_CONFIG to volatile_table
The MSB (15th bit) of INA3221_CONFIG is a self-clear reset bit.
So this register should be added to the volatile_table of the
regmap_config. Otherwise, we will see this bit is sticky in the
regcache which might accidentally reset the chip when an actual
write happens to the register.

This might not be a severe bug for the current code line since
there's no second place touching the INA3221_CONFIG except the
reset routine in the probe().

Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2018-10-10 20:37:13 -07:00
Guenter Roeck 9ad0df1ada hwmon: (ina3221) Fix negative limits
The result of an integer divide by an unsigned is undefined.
This causes unexpected results when writing negative values
into the limit registers.

Maintain the shunt_resistors variables as signed integer to avoid
the problem. Also, for simplicity and ease of use, clamp shunt
resistor value on writes instead of rejecting bad values.

Cc: Andrew F. Davis <afd@ti.com>
Acked-by: Andrew F. Davis <afd@ti.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2016-06-27 18:58:04 -07:00
Andrew F. Davis 7cb6dcff19 hwmon: Add support for INA3221 Triple Current/Voltage Monitors
Add support for the the INA3221 26v capable, Triple channel,
Bi-Directional, Zero-Drift, Low-/High-Side, Current/Voltage Monitor
with I2C interface.

Signed-off-by: Andrew F. Davis <afd@ti.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2016-06-27 18:58:03 -07:00