xref: /linux/drivers/hwmon/ltc2991.c (revision 99bf7c2eccff82760fa23ce967cc67c8c219c6a6)
12b9ea426SAntoniu Miclaus // SPDX-License-Identifier: GPL-2.0
22b9ea426SAntoniu Miclaus /*
32b9ea426SAntoniu Miclaus  * Copyright (C) 2023 Analog Devices, Inc.
42b9ea426SAntoniu Miclaus  * Author: Antoniu Miclaus <antoniu.miclaus@analog.com>
52b9ea426SAntoniu Miclaus  */
62b9ea426SAntoniu Miclaus 
72b9ea426SAntoniu Miclaus #include <linux/bitops.h>
82b9ea426SAntoniu Miclaus #include <linux/err.h>
92b9ea426SAntoniu Miclaus #include <linux/hwmon.h>
102b9ea426SAntoniu Miclaus #include <linux/i2c.h>
112b9ea426SAntoniu Miclaus #include <linux/kernel.h>
122b9ea426SAntoniu Miclaus #include <linux/module.h>
132b9ea426SAntoniu Miclaus #include <linux/property.h>
142b9ea426SAntoniu Miclaus #include <linux/regmap.h>
152b9ea426SAntoniu Miclaus #include <linux/regulator/consumer.h>
162b9ea426SAntoniu Miclaus 
172b9ea426SAntoniu Miclaus #define LTC2991_STATUS_LOW		0x00
182b9ea426SAntoniu Miclaus #define LTC2991_CH_EN_TRIGGER		0x01
192b9ea426SAntoniu Miclaus #define LTC2991_V1_V4_CTRL		0x06
202b9ea426SAntoniu Miclaus #define LTC2991_V5_V8_CTRL		0x07
212b9ea426SAntoniu Miclaus #define LTC2991_PWM_TH_LSB_T_INT	0x08
222b9ea426SAntoniu Miclaus #define LTC2991_PWM_TH_MSB		0x09
232b9ea426SAntoniu Miclaus #define LTC2991_CHANNEL_V_MSB(x)	(0x0A + ((x) * 2))
242b9ea426SAntoniu Miclaus #define LTC2991_CHANNEL_T_MSB(x)	(0x0A + ((x) * 4))
252b9ea426SAntoniu Miclaus #define LTC2991_CHANNEL_C_MSB(x)	(0x0C + ((x) * 4))
262b9ea426SAntoniu Miclaus #define LTC2991_T_INT_MSB		0x1A
272b9ea426SAntoniu Miclaus #define LTC2991_VCC_MSB			0x1C
282b9ea426SAntoniu Miclaus 
292b9ea426SAntoniu Miclaus #define LTC2991_V7_V8_EN		BIT(7)
302b9ea426SAntoniu Miclaus #define LTC2991_V5_V6_EN		BIT(6)
312b9ea426SAntoniu Miclaus #define LTC2991_V3_V4_EN		BIT(5)
322b9ea426SAntoniu Miclaus #define LTC2991_V1_V2_EN		BIT(4)
332b9ea426SAntoniu Miclaus #define LTC2991_T_INT_VCC_EN		BIT(3)
342b9ea426SAntoniu Miclaus 
352b9ea426SAntoniu Miclaus #define LTC2991_V3_V4_FILT_EN		BIT(7)
362b9ea426SAntoniu Miclaus #define LTC2991_V3_V4_TEMP_EN		BIT(5)
372b9ea426SAntoniu Miclaus #define LTC2991_V3_V4_DIFF_EN		BIT(4)
382b9ea426SAntoniu Miclaus #define LTC2991_V1_V2_FILT_EN		BIT(3)
392b9ea426SAntoniu Miclaus #define LTC2991_V1_V2_TEMP_EN		BIT(1)
402b9ea426SAntoniu Miclaus #define LTC2991_V1_V2_DIFF_EN		BIT(0)
412b9ea426SAntoniu Miclaus 
422b9ea426SAntoniu Miclaus #define LTC2991_V7_V8_FILT_EN		BIT(7)
432b9ea426SAntoniu Miclaus #define LTC2991_V7_V8_TEMP_EN		BIT(5)
442b9ea426SAntoniu Miclaus #define LTC2991_V7_V8_DIFF_EN		BIT(4)
452b9ea426SAntoniu Miclaus #define LTC2991_V5_V6_FILT_EN		BIT(7)
462b9ea426SAntoniu Miclaus #define LTC2991_V5_V6_TEMP_EN		BIT(5)
472b9ea426SAntoniu Miclaus #define LTC2991_V5_V6_DIFF_EN		BIT(4)
482b9ea426SAntoniu Miclaus 
492b9ea426SAntoniu Miclaus #define LTC2991_REPEAT_ACQ_EN		BIT(4)
502b9ea426SAntoniu Miclaus #define LTC2991_T_INT_FILT_EN		BIT(3)
512b9ea426SAntoniu Miclaus 
522b9ea426SAntoniu Miclaus #define LTC2991_MAX_CHANNEL		4
532b9ea426SAntoniu Miclaus #define LTC2991_T_INT_CH_NR		4
542b9ea426SAntoniu Miclaus #define LTC2991_VCC_CH_NR		0
552b9ea426SAntoniu Miclaus 
562b9ea426SAntoniu Miclaus struct ltc2991_state {
572b9ea426SAntoniu Miclaus 	struct regmap		*regmap;
582b9ea426SAntoniu Miclaus 	u32			r_sense_uohm[LTC2991_MAX_CHANNEL];
592b9ea426SAntoniu Miclaus 	bool			temp_en[LTC2991_MAX_CHANNEL];
602b9ea426SAntoniu Miclaus };
612b9ea426SAntoniu Miclaus 
622b9ea426SAntoniu Miclaus static int ltc2991_read_reg(struct ltc2991_state *st, u8 addr, u8 reg_len,
632b9ea426SAntoniu Miclaus 			    int *val)
642b9ea426SAntoniu Miclaus {
652b9ea426SAntoniu Miclaus 	__be16 regvals;
662b9ea426SAntoniu Miclaus 	int ret;
672b9ea426SAntoniu Miclaus 
682b9ea426SAntoniu Miclaus 	if (reg_len < 2)
692b9ea426SAntoniu Miclaus 		return regmap_read(st->regmap, addr, val);
702b9ea426SAntoniu Miclaus 
712b9ea426SAntoniu Miclaus 	ret = regmap_bulk_read(st->regmap, addr, &regvals, reg_len);
722b9ea426SAntoniu Miclaus 	if (ret)
732b9ea426SAntoniu Miclaus 		return ret;
742b9ea426SAntoniu Miclaus 
752b9ea426SAntoniu Miclaus 	*val = be16_to_cpu(regvals);
762b9ea426SAntoniu Miclaus 
772b9ea426SAntoniu Miclaus 	return 0;
782b9ea426SAntoniu Miclaus }
792b9ea426SAntoniu Miclaus 
802b9ea426SAntoniu Miclaus static int ltc2991_get_voltage(struct ltc2991_state *st, u32 reg, long *val)
812b9ea426SAntoniu Miclaus {
822b9ea426SAntoniu Miclaus 	int reg_val, ret, offset = 0;
832b9ea426SAntoniu Miclaus 
842b9ea426SAntoniu Miclaus 	ret = ltc2991_read_reg(st, reg, 2, &reg_val);
852b9ea426SAntoniu Miclaus 	if (ret)
862b9ea426SAntoniu Miclaus 		return ret;
872b9ea426SAntoniu Miclaus 
882b9ea426SAntoniu Miclaus 	if (reg == LTC2991_VCC_MSB)
892b9ea426SAntoniu Miclaus 		/* Vcc 2.5V offset */
902b9ea426SAntoniu Miclaus 		offset = 2500;
912b9ea426SAntoniu Miclaus 
922b9ea426SAntoniu Miclaus 	/* Vx, 305.18uV/LSB */
932b9ea426SAntoniu Miclaus 	*val = DIV_ROUND_CLOSEST(sign_extend32(reg_val, 14) * 30518,
942b9ea426SAntoniu Miclaus 				 1000 * 100) + offset;
952b9ea426SAntoniu Miclaus 
962b9ea426SAntoniu Miclaus 	return 0;
972b9ea426SAntoniu Miclaus }
982b9ea426SAntoniu Miclaus 
992b9ea426SAntoniu Miclaus static int ltc2991_read_in(struct device *dev, u32 attr, int channel, long *val)
1002b9ea426SAntoniu Miclaus {
1012b9ea426SAntoniu Miclaus 	struct ltc2991_state *st = dev_get_drvdata(dev);
1022b9ea426SAntoniu Miclaus 	u32 reg;
1032b9ea426SAntoniu Miclaus 
1042b9ea426SAntoniu Miclaus 	switch (attr) {
1052b9ea426SAntoniu Miclaus 	case hwmon_in_input:
1062b9ea426SAntoniu Miclaus 		if (channel == LTC2991_VCC_CH_NR)
1072b9ea426SAntoniu Miclaus 			reg = LTC2991_VCC_MSB;
1082b9ea426SAntoniu Miclaus 		else
1092b9ea426SAntoniu Miclaus 			reg = LTC2991_CHANNEL_V_MSB(channel - 1);
1102b9ea426SAntoniu Miclaus 
1112b9ea426SAntoniu Miclaus 		return ltc2991_get_voltage(st, reg, val);
1122b9ea426SAntoniu Miclaus 	default:
1132b9ea426SAntoniu Miclaus 		return -EOPNOTSUPP;
1142b9ea426SAntoniu Miclaus 	}
1152b9ea426SAntoniu Miclaus }
1162b9ea426SAntoniu Miclaus 
1172b9ea426SAntoniu Miclaus static int ltc2991_get_curr(struct ltc2991_state *st, u32 reg, int channel,
1182b9ea426SAntoniu Miclaus 			    long *val)
1192b9ea426SAntoniu Miclaus {
1202b9ea426SAntoniu Miclaus 	int reg_val, ret;
1212b9ea426SAntoniu Miclaus 
1222b9ea426SAntoniu Miclaus 	ret = ltc2991_read_reg(st, reg, 2, &reg_val);
1232b9ea426SAntoniu Miclaus 	if (ret)
1242b9ea426SAntoniu Miclaus 		return ret;
1252b9ea426SAntoniu Miclaus 
1262b9ea426SAntoniu Miclaus 	/* Vx-Vy, 19.075uV/LSB */
1272b9ea426SAntoniu Miclaus 	*val = DIV_ROUND_CLOSEST(sign_extend32(reg_val, 14) * 19075,
1282b9ea426SAntoniu Miclaus 				 st->r_sense_uohm[channel]);
1292b9ea426SAntoniu Miclaus 
1302b9ea426SAntoniu Miclaus 	return 0;
1312b9ea426SAntoniu Miclaus }
1322b9ea426SAntoniu Miclaus 
1332b9ea426SAntoniu Miclaus static int ltc2991_read_curr(struct device *dev, u32 attr, int channel,
1342b9ea426SAntoniu Miclaus 			     long *val)
1352b9ea426SAntoniu Miclaus {
1362b9ea426SAntoniu Miclaus 	struct ltc2991_state *st = dev_get_drvdata(dev);
1372b9ea426SAntoniu Miclaus 	u32 reg;
1382b9ea426SAntoniu Miclaus 
1392b9ea426SAntoniu Miclaus 	switch (attr) {
1402b9ea426SAntoniu Miclaus 	case hwmon_curr_input:
1412b9ea426SAntoniu Miclaus 		reg = LTC2991_CHANNEL_C_MSB(channel);
1422b9ea426SAntoniu Miclaus 		return ltc2991_get_curr(st, reg, channel, val);
1432b9ea426SAntoniu Miclaus 	default:
1442b9ea426SAntoniu Miclaus 		return -EOPNOTSUPP;
1452b9ea426SAntoniu Miclaus 	}
1462b9ea426SAntoniu Miclaus }
1472b9ea426SAntoniu Miclaus 
1482b9ea426SAntoniu Miclaus static int ltc2991_get_temp(struct ltc2991_state *st, u32 reg, int channel,
1492b9ea426SAntoniu Miclaus 			    long *val)
1502b9ea426SAntoniu Miclaus {
1512b9ea426SAntoniu Miclaus 	int reg_val, ret;
1522b9ea426SAntoniu Miclaus 
1532b9ea426SAntoniu Miclaus 	ret = ltc2991_read_reg(st, reg, 2, &reg_val);
1542b9ea426SAntoniu Miclaus 	if (ret)
1552b9ea426SAntoniu Miclaus 		return ret;
1562b9ea426SAntoniu Miclaus 
1572b9ea426SAntoniu Miclaus 	/* Temp LSB = 0.0625 Degrees */
1582b9ea426SAntoniu Miclaus 	*val = DIV_ROUND_CLOSEST(sign_extend32(reg_val, 12) * 1000, 16);
1592b9ea426SAntoniu Miclaus 
1602b9ea426SAntoniu Miclaus 	return 0;
1612b9ea426SAntoniu Miclaus }
1622b9ea426SAntoniu Miclaus 
1632b9ea426SAntoniu Miclaus static int ltc2991_read_temp(struct device *dev, u32 attr, int channel,
1642b9ea426SAntoniu Miclaus 			     long *val)
1652b9ea426SAntoniu Miclaus {
1662b9ea426SAntoniu Miclaus 	struct ltc2991_state *st = dev_get_drvdata(dev);
1672b9ea426SAntoniu Miclaus 	u32 reg;
1682b9ea426SAntoniu Miclaus 
1692b9ea426SAntoniu Miclaus 	switch (attr) {
1702b9ea426SAntoniu Miclaus 	case hwmon_temp_input:
1712b9ea426SAntoniu Miclaus 		if (channel == LTC2991_T_INT_CH_NR)
1722b9ea426SAntoniu Miclaus 			reg = LTC2991_T_INT_MSB;
1732b9ea426SAntoniu Miclaus 		else
1742b9ea426SAntoniu Miclaus 			reg = LTC2991_CHANNEL_T_MSB(channel);
1752b9ea426SAntoniu Miclaus 
1762b9ea426SAntoniu Miclaus 		return ltc2991_get_temp(st, reg, channel, val);
1772b9ea426SAntoniu Miclaus 	default:
1782b9ea426SAntoniu Miclaus 		return -EOPNOTSUPP;
1792b9ea426SAntoniu Miclaus 	}
1802b9ea426SAntoniu Miclaus }
1812b9ea426SAntoniu Miclaus 
1822b9ea426SAntoniu Miclaus static int ltc2991_read(struct device *dev, enum hwmon_sensor_types type,
1832b9ea426SAntoniu Miclaus 			u32 attr, int channel, long *val)
1842b9ea426SAntoniu Miclaus {
1852b9ea426SAntoniu Miclaus 	switch (type) {
1862b9ea426SAntoniu Miclaus 	case hwmon_in:
1872b9ea426SAntoniu Miclaus 		return ltc2991_read_in(dev, attr, channel, val);
1882b9ea426SAntoniu Miclaus 	case hwmon_curr:
1892b9ea426SAntoniu Miclaus 		return ltc2991_read_curr(dev, attr, channel, val);
1902b9ea426SAntoniu Miclaus 	case hwmon_temp:
1912b9ea426SAntoniu Miclaus 		return ltc2991_read_temp(dev, attr, channel, val);
1922b9ea426SAntoniu Miclaus 	default:
1932b9ea426SAntoniu Miclaus 		return -EOPNOTSUPP;
1942b9ea426SAntoniu Miclaus 	}
1952b9ea426SAntoniu Miclaus }
1962b9ea426SAntoniu Miclaus 
1972b9ea426SAntoniu Miclaus static umode_t ltc2991_is_visible(const void *data,
1982b9ea426SAntoniu Miclaus 				  enum hwmon_sensor_types type, u32 attr,
1992b9ea426SAntoniu Miclaus 				  int channel)
2002b9ea426SAntoniu Miclaus {
2012b9ea426SAntoniu Miclaus 	const struct ltc2991_state *st = data;
2022b9ea426SAntoniu Miclaus 
2032b9ea426SAntoniu Miclaus 	switch (type) {
2042b9ea426SAntoniu Miclaus 	case hwmon_in:
2052b9ea426SAntoniu Miclaus 		switch (attr) {
2062b9ea426SAntoniu Miclaus 		case hwmon_in_input:
2072b9ea426SAntoniu Miclaus 			if (channel == LTC2991_VCC_CH_NR)
2082b9ea426SAntoniu Miclaus 				return 0444;
2092b9ea426SAntoniu Miclaus 			if (st->temp_en[(channel - 1) / 2])
2102b9ea426SAntoniu Miclaus 				break;
2112b9ea426SAntoniu Miclaus 			if (channel % 2)
2122b9ea426SAntoniu Miclaus 				return 0444;
2132b9ea426SAntoniu Miclaus 			if (!st->r_sense_uohm[(channel - 1) / 2])
2142b9ea426SAntoniu Miclaus 				return 0444;
2152b9ea426SAntoniu Miclaus 		}
2162b9ea426SAntoniu Miclaus 		break;
2172b9ea426SAntoniu Miclaus 	case hwmon_curr:
2182b9ea426SAntoniu Miclaus 		switch (attr) {
2192b9ea426SAntoniu Miclaus 		case hwmon_curr_input:
2202b9ea426SAntoniu Miclaus 			if (st->r_sense_uohm[channel])
2212b9ea426SAntoniu Miclaus 				return 0444;
2222b9ea426SAntoniu Miclaus 			break;
2232b9ea426SAntoniu Miclaus 		}
2242b9ea426SAntoniu Miclaus 		break;
2252b9ea426SAntoniu Miclaus 	case hwmon_temp:
2262b9ea426SAntoniu Miclaus 		switch (attr) {
2272b9ea426SAntoniu Miclaus 		case hwmon_temp_input:
228*99bf7c2eSDan Carpenter 			if (channel == LTC2991_T_INT_CH_NR ||
229*99bf7c2eSDan Carpenter 			    st->temp_en[channel])
2302b9ea426SAntoniu Miclaus 				return 0444;
2312b9ea426SAntoniu Miclaus 			break;
2322b9ea426SAntoniu Miclaus 		}
2332b9ea426SAntoniu Miclaus 		break;
2342b9ea426SAntoniu Miclaus 	default:
2352b9ea426SAntoniu Miclaus 		break;
2362b9ea426SAntoniu Miclaus 	}
2372b9ea426SAntoniu Miclaus 
2382b9ea426SAntoniu Miclaus 	return 0;
2392b9ea426SAntoniu Miclaus }
2402b9ea426SAntoniu Miclaus 
2412b9ea426SAntoniu Miclaus static const struct hwmon_ops ltc2991_hwmon_ops = {
2422b9ea426SAntoniu Miclaus 	.is_visible = ltc2991_is_visible,
2432b9ea426SAntoniu Miclaus 	.read = ltc2991_read,
2442b9ea426SAntoniu Miclaus };
2452b9ea426SAntoniu Miclaus 
2462b9ea426SAntoniu Miclaus static const struct hwmon_channel_info *ltc2991_info[] = {
2472b9ea426SAntoniu Miclaus 	HWMON_CHANNEL_INFO(temp,
2482b9ea426SAntoniu Miclaus 			   HWMON_T_INPUT,
2492b9ea426SAntoniu Miclaus 			   HWMON_T_INPUT,
2502b9ea426SAntoniu Miclaus 			   HWMON_T_INPUT,
2512b9ea426SAntoniu Miclaus 			   HWMON_T_INPUT,
2522b9ea426SAntoniu Miclaus 			   HWMON_T_INPUT
2532b9ea426SAntoniu Miclaus 			   ),
2542b9ea426SAntoniu Miclaus 	HWMON_CHANNEL_INFO(curr,
2552b9ea426SAntoniu Miclaus 			   HWMON_C_INPUT,
2562b9ea426SAntoniu Miclaus 			   HWMON_C_INPUT,
2572b9ea426SAntoniu Miclaus 			   HWMON_C_INPUT,
2582b9ea426SAntoniu Miclaus 			   HWMON_C_INPUT
2592b9ea426SAntoniu Miclaus 			   ),
2602b9ea426SAntoniu Miclaus 	HWMON_CHANNEL_INFO(in,
2612b9ea426SAntoniu Miclaus 			   HWMON_I_INPUT,
2622b9ea426SAntoniu Miclaus 			   HWMON_I_INPUT,
2632b9ea426SAntoniu Miclaus 			   HWMON_I_INPUT,
2642b9ea426SAntoniu Miclaus 			   HWMON_I_INPUT,
2652b9ea426SAntoniu Miclaus 			   HWMON_I_INPUT,
2662b9ea426SAntoniu Miclaus 			   HWMON_I_INPUT,
2672b9ea426SAntoniu Miclaus 			   HWMON_I_INPUT,
2682b9ea426SAntoniu Miclaus 			   HWMON_I_INPUT,
2692b9ea426SAntoniu Miclaus 			   HWMON_I_INPUT
2702b9ea426SAntoniu Miclaus 			   ),
2712b9ea426SAntoniu Miclaus 	NULL
2722b9ea426SAntoniu Miclaus };
2732b9ea426SAntoniu Miclaus 
2742b9ea426SAntoniu Miclaus static const struct hwmon_chip_info ltc2991_chip_info = {
2752b9ea426SAntoniu Miclaus 	.ops = &ltc2991_hwmon_ops,
2762b9ea426SAntoniu Miclaus 	.info = ltc2991_info,
2772b9ea426SAntoniu Miclaus };
2782b9ea426SAntoniu Miclaus 
2792b9ea426SAntoniu Miclaus static const struct regmap_config ltc2991_regmap_config = {
2802b9ea426SAntoniu Miclaus 	.reg_bits = 8,
2812b9ea426SAntoniu Miclaus 	.val_bits = 8,
2822b9ea426SAntoniu Miclaus 	.max_register = 0x1D,
2832b9ea426SAntoniu Miclaus };
2842b9ea426SAntoniu Miclaus 
28534c76a51SAntoniu Miclaus static int ltc2991_init(struct ltc2991_state *st, struct device *dev)
2862b9ea426SAntoniu Miclaus {
2872b9ea426SAntoniu Miclaus 	int ret;
2882b9ea426SAntoniu Miclaus 	u32 val, addr;
2892b9ea426SAntoniu Miclaus 	u8 v5_v8_reg_data = 0, v1_v4_reg_data = 0;
2902b9ea426SAntoniu Miclaus 
29134c76a51SAntoniu Miclaus 	ret = devm_regulator_get_enable(dev, "vcc");
2922b9ea426SAntoniu Miclaus 	if (ret)
29334c76a51SAntoniu Miclaus 		return dev_err_probe(dev, ret,
2942b9ea426SAntoniu Miclaus 				     "failed to enable regulator\n");
2952b9ea426SAntoniu Miclaus 
296234c0740SJavier Carrasco 	device_for_each_child_node_scoped(dev, child) {
2972b9ea426SAntoniu Miclaus 		ret = fwnode_property_read_u32(child, "reg", &addr);
298234c0740SJavier Carrasco 		if (ret < 0)
2992b9ea426SAntoniu Miclaus 			return ret;
3002b9ea426SAntoniu Miclaus 
301234c0740SJavier Carrasco 		if (addr > 3)
3022b9ea426SAntoniu Miclaus 			return -EINVAL;
3032b9ea426SAntoniu Miclaus 
3042b9ea426SAntoniu Miclaus 		ret = fwnode_property_read_u32(child,
3052b9ea426SAntoniu Miclaus 					       "shunt-resistor-micro-ohms",
3062b9ea426SAntoniu Miclaus 					       &val);
3072b9ea426SAntoniu Miclaus 		if (!ret) {
3082b9ea426SAntoniu Miclaus 			if (!val)
30934c76a51SAntoniu Miclaus 				return dev_err_probe(dev, -EINVAL,
3102b9ea426SAntoniu Miclaus 						     "shunt resistor value cannot be zero\n");
3112b9ea426SAntoniu Miclaus 
3122b9ea426SAntoniu Miclaus 			st->r_sense_uohm[addr] = val;
3132b9ea426SAntoniu Miclaus 
3142b9ea426SAntoniu Miclaus 			switch (addr) {
3152b9ea426SAntoniu Miclaus 			case 0:
3162b9ea426SAntoniu Miclaus 				v1_v4_reg_data |= LTC2991_V1_V2_DIFF_EN;
3172b9ea426SAntoniu Miclaus 				break;
3182b9ea426SAntoniu Miclaus 			case 1:
3192b9ea426SAntoniu Miclaus 				v1_v4_reg_data |= LTC2991_V3_V4_DIFF_EN;
3202b9ea426SAntoniu Miclaus 				break;
3212b9ea426SAntoniu Miclaus 			case 2:
3222b9ea426SAntoniu Miclaus 				v5_v8_reg_data |= LTC2991_V5_V6_DIFF_EN;
3232b9ea426SAntoniu Miclaus 				break;
3242b9ea426SAntoniu Miclaus 			case 3:
3252b9ea426SAntoniu Miclaus 				v5_v8_reg_data |= LTC2991_V7_V8_DIFF_EN;
3262b9ea426SAntoniu Miclaus 				break;
3272b9ea426SAntoniu Miclaus 			default:
3282b9ea426SAntoniu Miclaus 				break;
3292b9ea426SAntoniu Miclaus 			}
3302b9ea426SAntoniu Miclaus 		}
3312b9ea426SAntoniu Miclaus 
3322b9ea426SAntoniu Miclaus 		ret = fwnode_property_read_bool(child,
3332b9ea426SAntoniu Miclaus 						"adi,temperature-enable");
3342b9ea426SAntoniu Miclaus 		if (ret) {
3352b9ea426SAntoniu Miclaus 			st->temp_en[addr] = ret;
3362b9ea426SAntoniu Miclaus 
3372b9ea426SAntoniu Miclaus 			switch (addr) {
3382b9ea426SAntoniu Miclaus 			case 0:
3392b9ea426SAntoniu Miclaus 				v1_v4_reg_data |= LTC2991_V1_V2_TEMP_EN;
3402b9ea426SAntoniu Miclaus 				break;
3412b9ea426SAntoniu Miclaus 			case 1:
3422b9ea426SAntoniu Miclaus 				v1_v4_reg_data |= LTC2991_V3_V4_TEMP_EN;
3432b9ea426SAntoniu Miclaus 				break;
3442b9ea426SAntoniu Miclaus 			case 2:
3452b9ea426SAntoniu Miclaus 				v5_v8_reg_data |= LTC2991_V5_V6_TEMP_EN;
3462b9ea426SAntoniu Miclaus 				break;
3472b9ea426SAntoniu Miclaus 			case 3:
3482b9ea426SAntoniu Miclaus 				v5_v8_reg_data |= LTC2991_V7_V8_TEMP_EN;
3492b9ea426SAntoniu Miclaus 				break;
3502b9ea426SAntoniu Miclaus 			default:
3512b9ea426SAntoniu Miclaus 				break;
3522b9ea426SAntoniu Miclaus 			}
3532b9ea426SAntoniu Miclaus 		}
3542b9ea426SAntoniu Miclaus 	}
3552b9ea426SAntoniu Miclaus 
3562b9ea426SAntoniu Miclaus 	ret = regmap_write(st->regmap, LTC2991_V5_V8_CTRL, v5_v8_reg_data);
3572b9ea426SAntoniu Miclaus 	if (ret)
35834c76a51SAntoniu Miclaus 		return dev_err_probe(dev, ret,
3592b9ea426SAntoniu Miclaus 				     "Error: Failed to set V5-V8 CTRL reg.\n");
3602b9ea426SAntoniu Miclaus 
3612b9ea426SAntoniu Miclaus 	ret = regmap_write(st->regmap, LTC2991_V1_V4_CTRL, v1_v4_reg_data);
3622b9ea426SAntoniu Miclaus 	if (ret)
36334c76a51SAntoniu Miclaus 		return dev_err_probe(dev, ret,
3642b9ea426SAntoniu Miclaus 				     "Error: Failed to set V1-V4 CTRL reg.\n");
3652b9ea426SAntoniu Miclaus 
3662b9ea426SAntoniu Miclaus 	ret = regmap_write(st->regmap, LTC2991_PWM_TH_LSB_T_INT,
3672b9ea426SAntoniu Miclaus 			   LTC2991_REPEAT_ACQ_EN);
3682b9ea426SAntoniu Miclaus 	if (ret)
36934c76a51SAntoniu Miclaus 		return dev_err_probe(dev, ret,
370d9995cd9SColin Ian King 				     "Error: Failed to set continuous mode.\n");
3712b9ea426SAntoniu Miclaus 
3722b9ea426SAntoniu Miclaus 	/* Enable all channels and trigger conversions */
3732b9ea426SAntoniu Miclaus 	return regmap_write(st->regmap, LTC2991_CH_EN_TRIGGER,
3742b9ea426SAntoniu Miclaus 			    LTC2991_V7_V8_EN | LTC2991_V5_V6_EN |
3752b9ea426SAntoniu Miclaus 			    LTC2991_V3_V4_EN | LTC2991_V1_V2_EN |
3762b9ea426SAntoniu Miclaus 			    LTC2991_T_INT_VCC_EN);
3772b9ea426SAntoniu Miclaus }
3782b9ea426SAntoniu Miclaus 
3792b9ea426SAntoniu Miclaus static int ltc2991_i2c_probe(struct i2c_client *client)
3802b9ea426SAntoniu Miclaus {
3812b9ea426SAntoniu Miclaus 	int ret;
3822b9ea426SAntoniu Miclaus 	struct device *hwmon_dev;
3832b9ea426SAntoniu Miclaus 	struct ltc2991_state *st;
3842b9ea426SAntoniu Miclaus 
3852b9ea426SAntoniu Miclaus 	st = devm_kzalloc(&client->dev, sizeof(*st), GFP_KERNEL);
3862b9ea426SAntoniu Miclaus 	if (!st)
3872b9ea426SAntoniu Miclaus 		return -ENOMEM;
3882b9ea426SAntoniu Miclaus 
3892b9ea426SAntoniu Miclaus 	st->regmap = devm_regmap_init_i2c(client, &ltc2991_regmap_config);
3902b9ea426SAntoniu Miclaus 	if (IS_ERR(st->regmap))
3912b9ea426SAntoniu Miclaus 		return PTR_ERR(st->regmap);
3922b9ea426SAntoniu Miclaus 
39334c76a51SAntoniu Miclaus 	ret = ltc2991_init(st, &client->dev);
3942b9ea426SAntoniu Miclaus 	if (ret)
3952b9ea426SAntoniu Miclaus 		return ret;
3962b9ea426SAntoniu Miclaus 
3972b9ea426SAntoniu Miclaus 	hwmon_dev = devm_hwmon_device_register_with_info(&client->dev,
3982b9ea426SAntoniu Miclaus 							 client->name, st,
3992b9ea426SAntoniu Miclaus 							 &ltc2991_chip_info,
4002b9ea426SAntoniu Miclaus 							 NULL);
4012b9ea426SAntoniu Miclaus 
4022b9ea426SAntoniu Miclaus 	return PTR_ERR_OR_ZERO(hwmon_dev);
4032b9ea426SAntoniu Miclaus }
4042b9ea426SAntoniu Miclaus 
4052b9ea426SAntoniu Miclaus static const struct of_device_id ltc2991_of_match[] = {
4062b9ea426SAntoniu Miclaus 	{ .compatible = "adi,ltc2991" },
4072b9ea426SAntoniu Miclaus 	{ }
4082b9ea426SAntoniu Miclaus };
4092b9ea426SAntoniu Miclaus MODULE_DEVICE_TABLE(of, ltc2991_of_match);
4102b9ea426SAntoniu Miclaus 
4112b9ea426SAntoniu Miclaus static const struct i2c_device_id ltc2991_i2c_id[] = {
412d8a66f36SUwe Kleine-König 	{ "ltc2991" },
4132b9ea426SAntoniu Miclaus 	{}
4142b9ea426SAntoniu Miclaus };
4152b9ea426SAntoniu Miclaus MODULE_DEVICE_TABLE(i2c, ltc2991_i2c_id);
4162b9ea426SAntoniu Miclaus 
4172b9ea426SAntoniu Miclaus static struct i2c_driver ltc2991_i2c_driver = {
4182b9ea426SAntoniu Miclaus 	.driver = {
4192b9ea426SAntoniu Miclaus 		.name = "ltc2991",
4202b9ea426SAntoniu Miclaus 		.of_match_table = ltc2991_of_match,
4212b9ea426SAntoniu Miclaus 	},
4222b9ea426SAntoniu Miclaus 	.probe = ltc2991_i2c_probe,
4232b9ea426SAntoniu Miclaus 	.id_table = ltc2991_i2c_id,
4242b9ea426SAntoniu Miclaus };
4252b9ea426SAntoniu Miclaus 
4262b9ea426SAntoniu Miclaus module_i2c_driver(ltc2991_i2c_driver);
4272b9ea426SAntoniu Miclaus 
4282b9ea426SAntoniu Miclaus MODULE_AUTHOR("Antoniu Miclaus <antoniu.miclaus@analog.com>");
4292b9ea426SAntoniu Miclaus MODULE_DESCRIPTION("Analog Devices LTC2991 HWMON Driver");
4302b9ea426SAntoniu Miclaus MODULE_LICENSE("GPL");
431