From: Guenter Roeck <linux@roeck-us.net>
To: Hardware Monitoring <linux-hwmon@vger.kernel.org>
Cc: Tzung-Bi Shih <tzungbi@kernel.org>, Guenter Roeck <linux@roeck-us.net>
Subject: [PATCH v2 13/14] hwmon: (ina2xx) Add support for current limits
Date: Thu, 29 Aug 2024 18:05:53 -0700 [thread overview]
Message-ID: <20240830010554.1462861-14-linux@roeck-us.net> (raw)
In-Reply-To: <20240830010554.1462861-1-linux@roeck-us.net>
While the chips supported by this driver do not directly support current
limits, they do support setting shunt voltage limits. The shunt voltage
divided by the shunt resistor value is the current. On top of that,
calibration values are set such that in the shunt voltage register and
the current register report the same values. That means we can report and
configure current limits based on shunt voltage limits, and we can do so
with much better accuracy than by setting shunt voltage limits.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
v2: New patch
Documentation/hwmon/ina2xx.rst | 4 +++
drivers/hwmon/ina2xx.c | 61 ++++++++++++++++++++++++++++++++--
2 files changed, 63 insertions(+), 2 deletions(-)
diff --git a/Documentation/hwmon/ina2xx.rst b/Documentation/hwmon/ina2xx.rst
index 27d2e39bc8ac..7f1939b40f74 100644
--- a/Documentation/hwmon/ina2xx.rst
+++ b/Documentation/hwmon/ina2xx.rst
@@ -99,6 +99,10 @@ Sysfs entries for ina226, ina230 and ina231 only
------------------------------------------------
======================= ====================================================
+curr1_lcrit Critical low current
+curr1_crit Critical high current
+curr1_lcrit_alarm Current critical low alarm
+curr1_crit_alarm Current critical high alarm
in0_lcrit Critical low shunt voltage
in0_crit Critical high shunt voltage
in0_lcrit_alarm Shunt voltage critical low alarm
diff --git a/drivers/hwmon/ina2xx.c b/drivers/hwmon/ina2xx.c
index 1cd6fffb1495..10c8c475c634 100644
--- a/drivers/hwmon/ina2xx.c
+++ b/drivers/hwmon/ina2xx.c
@@ -306,7 +306,7 @@ static int ina2xx_read_init(struct device *dev, int reg, long *val)
* Turns alert limit values into register values.
* Opposite of the formula in ina2xx_get_value().
*/
-static u16 ina226_alert_to_reg(struct ina2xx_data *data, int reg, unsigned long val)
+static u16 ina226_alert_to_reg(struct ina2xx_data *data, int reg, long val)
{
switch (reg) {
case INA2XX_SHUNT_VOLTAGE:
@@ -322,6 +322,11 @@ static u16 ina226_alert_to_reg(struct ina2xx_data *data, int reg, unsigned long
val = clamp_val(val, 0, UINT_MAX - data->power_lsb_uW);
val = DIV_ROUND_CLOSEST(val, data->power_lsb_uW);
return clamp_val(val, 0, USHRT_MAX);
+ case INA2XX_CURRENT:
+ val = clamp_val(val, INT_MIN / 1000, INT_MAX / 1000);
+ /* signed register, result in mA */
+ val = DIV_ROUND_CLOSEST(val * 1000, data->current_lsb_uA);
+ return clamp_val(val, SHRT_MIN, SHRT_MAX);
default:
/* programmer goofed */
WARN_ON_ONCE(1);
@@ -473,9 +478,31 @@ static int ina2xx_power_read(struct device *dev, u32 attr, long *val)
static int ina2xx_curr_read(struct device *dev, u32 attr, long *val)
{
+ struct ina2xx_data *data = dev_get_drvdata(dev);
+ struct regmap *regmap = data->regmap;
+
+ /*
+ * While the chips supported by this driver do not directly support
+ * current limits, they do support setting shunt voltage limits.
+ * The shunt voltage divided by the shunt resistor value is the current.
+ * On top of that, calibration values are set such that in the shunt
+ * voltage register and the current register report the same values.
+ * That means we can report and configure current limits based on shunt
+ * voltage limits.
+ */
switch (attr) {
case hwmon_curr_input:
return ina2xx_read_init(dev, INA2XX_CURRENT, val);
+ case hwmon_curr_lcrit:
+ return ina226_alert_limit_read(data, INA226_SHUNT_UNDER_VOLTAGE_MASK,
+ INA2XX_CURRENT, val);
+ case hwmon_curr_crit:
+ return ina226_alert_limit_read(data, INA226_SHUNT_OVER_VOLTAGE_MASK,
+ INA2XX_CURRENT, val);
+ case hwmon_curr_lcrit_alarm:
+ return ina226_alert_read(regmap, INA226_SHUNT_UNDER_VOLTAGE_MASK, val);
+ case hwmon_curr_crit_alarm:
+ return ina226_alert_read(regmap, INA226_SHUNT_OVER_VOLTAGE_MASK, val);
default:
return -EOPNOTSUPP;
}
@@ -547,6 +574,23 @@ static int ina2xx_power_write(struct device *dev, u32 attr, long val)
return 0;
}
+static int ina2xx_curr_write(struct device *dev, u32 attr, long val)
+{
+ struct ina2xx_data *data = dev_get_drvdata(dev);
+
+ switch (attr) {
+ case hwmon_curr_lcrit:
+ return ina226_alert_limit_write(data, INA226_SHUNT_UNDER_VOLTAGE_MASK,
+ INA2XX_CURRENT, val);
+ case hwmon_curr_crit:
+ return ina226_alert_limit_write(data, INA226_SHUNT_OVER_VOLTAGE_MASK,
+ INA2XX_CURRENT, val);
+ default:
+ return -EOPNOTSUPP;
+ }
+ return 0;
+}
+
static int ina2xx_write(struct device *dev, enum hwmon_sensor_types type,
u32 attr, int channel, long val)
{
@@ -557,6 +601,8 @@ static int ina2xx_write(struct device *dev, enum hwmon_sensor_types type,
return ina2xx_in_write(dev, attr, channel, val);
case hwmon_power:
return ina2xx_power_write(dev, attr, val);
+ case hwmon_curr:
+ return ina2xx_curr_write(dev, attr, val);
default:
return -EOPNOTSUPP;
}
@@ -591,6 +637,16 @@ static umode_t ina2xx_is_visible(const void *_data, enum hwmon_sensor_types type
switch (attr) {
case hwmon_curr_input:
return 0444;
+ case hwmon_curr_lcrit:
+ case hwmon_curr_crit:
+ if (chip == ina226)
+ return 0644;
+ break;
+ case hwmon_curr_lcrit_alarm:
+ case hwmon_curr_crit_alarm:
+ if (chip == ina226)
+ return 0444;
+ break;
default:
break;
}
@@ -636,7 +692,8 @@ static const struct hwmon_channel_info * const ina2xx_info[] = {
HWMON_I_INPUT | HWMON_I_CRIT | HWMON_I_CRIT_ALARM |
HWMON_I_LCRIT | HWMON_I_LCRIT_ALARM
),
- HWMON_CHANNEL_INFO(curr, HWMON_C_INPUT),
+ HWMON_CHANNEL_INFO(curr, HWMON_C_INPUT | HWMON_C_CRIT | HWMON_C_CRIT_ALARM |
+ HWMON_C_LCRIT | HWMON_C_LCRIT_ALARM),
HWMON_CHANNEL_INFO(power,
HWMON_P_INPUT | HWMON_P_CRIT | HWMON_P_CRIT_ALARM),
NULL
--
2.45.2
next prev parent reply other threads:[~2024-08-30 1:06 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-08-30 1:05 [PATCH v2 00/14] hwmon: (ina2xx) Cleanup and convert to use with_info API Guenter Roeck
2024-08-30 1:05 ` [PATCH v2 01/14] hwmon: (ina2xx) Reorder include files to alphabetic order Guenter Roeck
2024-08-30 1:05 ` [PATCH v2 02/14] hwmon: (ina2xx) Replace platform data with device properties Guenter Roeck
2024-08-30 1:05 ` [PATCH v2 03/14] hwmon: (ina2xx) Use bit operations Guenter Roeck
2024-08-30 1:05 ` [PATCH v2 04/14] hwmon: (ina2xx) Mark regmap_config as const Guenter Roeck
2024-08-30 12:28 ` Tzung-Bi Shih
2024-08-30 1:05 ` [PATCH v2 05/14] hwmon: (ina2xx) Use local regmap pointer if used more than once Guenter Roeck
2024-08-30 1:05 ` [PATCH v2 06/14] hwmon: (ina2xx) Re-initialize chip using regmap functions Guenter Roeck
2024-08-30 12:29 ` Tzung-Bi Shih
2024-08-30 1:05 ` [PATCH v2 07/14] hwmon: (ina2xx) Fix various overflow issues Guenter Roeck
2024-08-30 1:05 ` [PATCH v2 08/14] hwmon: (ina2xx) Consolidate chip initialization code Guenter Roeck
2024-08-30 12:29 ` Tzung-Bi Shih
2024-08-30 1:05 ` [PATCH v2 09/14] hwmon: (ina2xx) Set alert latch Guenter Roeck
2024-08-30 12:29 ` Tzung-Bi Shih
2024-08-30 1:05 ` [PATCH v2 10/14] hwmon: (ina2xx) Move ina2xx_get_value() Guenter Roeck
2024-08-30 1:05 ` [PATCH v2 11/14] hwmon: (ina2xx) Convert to use with_info hwmon API Guenter Roeck
2024-08-30 12:30 ` Tzung-Bi Shih
2024-08-30 15:32 ` Guenter Roeck
2024-08-30 1:05 ` [PATCH v2 12/14] hwmon: (ina2xx) Pass register to alert limit write functions Guenter Roeck
2024-08-30 12:30 ` Tzung-Bi Shih
2024-08-30 1:05 ` Guenter Roeck [this message]
2024-08-30 12:30 ` [PATCH v2 13/14] hwmon: (ina2xx) Add support for current limits Tzung-Bi Shih
2024-08-30 1:05 ` [PATCH v2 14/14] hwmon: (ina2xx) Use shunt voltage to calculate current Guenter Roeck
2024-08-30 12:30 ` Tzung-Bi Shih
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240830010554.1462861-14-linux@roeck-us.net \
--to=linux@roeck-us.net \
--cc=linux-hwmon@vger.kernel.org \
--cc=tzungbi@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox