summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitri Fedrau <dimitri.fedrau@liebherr.com>2025-01-16 09:04:29 +0100
committerSebastian Reichel <sebastian.reichel@collabora.com>2025-01-17 22:33:04 +0100
commitb4a95b8fd3e67c1222c76bdd1078d43c9a11d132 (patch)
treeadda98dd40e649c3f409fdba83748192b81ebeb1
parent92c71aa1a8942057e228c09d37f8513abbab5fea (diff)
power: supply: max1720x: add support for reading internal and thermistor temperatures
If enabled in the nPackCfg register, the Temp1, Temp2 and IntTemp registers contain the temperature readings from the AIN1 thermistor, AIN2 thermistor and internal die temperature respectively. Registers are shared between SBS and normal IC functions and are always readable regardless of IC settings. Signed-off-by: Dimitri Fedrau <dimitri.fedrau@liebherr.com> Link: https://lore.kernel.org/r/20250116-max1720x-temperature-v2-1-9638969d091a@liebherr.com Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
-rw-r--r--Documentation/ABI/testing/sysfs-class-power-max1720x32
-rw-r--r--drivers/power/supply/max1720x_battery.c60
2 files changed, 91 insertions, 1 deletions
diff --git a/Documentation/ABI/testing/sysfs-class-power-max1720x b/Documentation/ABI/testing/sysfs-class-power-max1720x
new file mode 100644
index 000000000000..7d895bfda9ce
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-class-power-max1720x
@@ -0,0 +1,32 @@
+What: /sys/class/power_supply/max1720x/temp_ain1
+Date: January 2025
+KernelVersion: 6.14
+Contact: Dimitri Fedrau <dimitri.fedrau@liebherr.com>
+Description:
+ Reports the current temperature reading from AIN1 thermistor.
+
+ Access: Read
+
+ Valid values: Represented in 1/10 Degrees Celsius
+
+What: /sys/class/power_supply/max1720x/temp_ain2
+Date: January 2025
+KernelVersion: 6.14
+Contact: Dimitri Fedrau <dimitri.fedrau@liebherr.com>
+Description:
+ Reports the current temperature reading from AIN2 thermistor.
+
+ Access: Read
+
+ Valid values: Represented in 1/10 Degrees Celsius
+
+What: /sys/class/power_supply/max1720x/temp_int
+Date: January 2025
+KernelVersion: 6.14
+Contact: Dimitri Fedrau <dimitri.fedrau@liebherr.com>
+Description:
+ Reports the current temperature reading from internal die.
+
+ Access: Read
+
+ Valid values: Represented in 1/10 Degrees Celsius
diff --git a/drivers/power/supply/max1720x_battery.c b/drivers/power/supply/max1720x_battery.c
index 9c7e14d2c7b8..11580e414713 100644
--- a/drivers/power/supply/max1720x_battery.c
+++ b/drivers/power/supply/max1720x_battery.c
@@ -16,6 +16,11 @@
#include <linux/unaligned.h>
+/* SBS compliant registers */
+#define MAX172XX_TEMP1 0x34
+#define MAX172XX_INT_TEMP 0x35
+#define MAX172XX_TEMP2 0x3B
+
/* Nonvolatile registers */
#define MAX1720X_NXTABLE0 0x80
#define MAX1720X_NRSENSE 0xCF /* RSense in 10^-5 Ohm */
@@ -113,11 +118,15 @@ static const struct regmap_config max1720x_regmap_cfg = {
};
static const struct regmap_range max1720x_nvmem_allow[] = {
+ regmap_reg_range(MAX172XX_TEMP1, MAX172XX_INT_TEMP),
+ regmap_reg_range(MAX172XX_TEMP2, MAX172XX_TEMP2),
regmap_reg_range(MAX1720X_NXTABLE0, MAX1720X_NDEVICE_NAME4),
};
static const struct regmap_range max1720x_nvmem_deny[] = {
- regmap_reg_range(0x00, 0x7F),
+ regmap_reg_range(0x00, 0x33),
+ regmap_reg_range(0x36, 0x3A),
+ regmap_reg_range(0x3C, 0x7F),
regmap_reg_range(0xE0, 0xFF),
};
@@ -388,6 +397,54 @@ static int max1720x_battery_get_property(struct power_supply *psy,
return ret;
}
+static int max1720x_read_temp(struct device *dev, u8 reg, char *buf)
+{
+ struct power_supply *psy = dev_get_drvdata(dev);
+ struct max1720x_device_info *info = power_supply_get_drvdata(psy);
+ unsigned int val;
+ int ret;
+
+ ret = regmap_read(info->regmap_nv, reg, &val);
+ if (ret < 0)
+ return ret;
+
+ /*
+ * Temperature in degrees Celsius starting at absolute zero, -273C or
+ * 0K with an LSb of 0.1C
+ */
+ return sysfs_emit(buf, "%d\n", val - 2730);
+}
+
+static ssize_t temp_ain1_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ return max1720x_read_temp(dev, MAX172XX_TEMP1, buf);
+}
+
+static ssize_t temp_ain2_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ return max1720x_read_temp(dev, MAX172XX_TEMP2, buf);
+}
+
+static ssize_t temp_int_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ return max1720x_read_temp(dev, MAX172XX_INT_TEMP, buf);
+}
+
+static DEVICE_ATTR_RO(temp_ain1);
+static DEVICE_ATTR_RO(temp_ain2);
+static DEVICE_ATTR_RO(temp_int);
+
+static struct attribute *max1720x_attrs[] = {
+ &dev_attr_temp_ain1.attr,
+ &dev_attr_temp_ain2.attr,
+ &dev_attr_temp_int.attr,
+ NULL
+};
+ATTRIBUTE_GROUPS(max1720x);
+
static
int max1720x_nvmem_reg_read(void *priv, unsigned int off, void *val, size_t len)
{
@@ -488,6 +545,7 @@ static int max1720x_probe(struct i2c_client *client)
psy_cfg.drv_data = info;
psy_cfg.fwnode = dev_fwnode(dev);
+ psy_cfg.attr_grp = max1720x_groups;
i2c_set_clientdata(client, info);
info->regmap = devm_regmap_init_i2c(client, &max1720x_regmap_cfg);
if (IS_ERR(info->regmap))