1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2023 Analog Devices, Inc.
4 * Author: Antoniu Miclaus <antoniu.miclaus@analog.com>
7 #include <linux/bitops.h>
9 #include <linux/hwmon.h>
10 #include <linux/i2c.h>
11 #include <linux/kernel.h>
12 #include <linux/module.h>
13 #include <linux/property.h>
14 #include <linux/regmap.h>
15 #include <linux/regulator/consumer.h>
17 #define LTC2991_STATUS_LOW 0x00
18 #define LTC2991_CH_EN_TRIGGER 0x01
19 #define LTC2991_V1_V4_CTRL 0x06
20 #define LTC2991_V5_V8_CTRL 0x07
21 #define LTC2991_PWM_TH_LSB_T_INT 0x08
22 #define LTC2991_PWM_TH_MSB 0x09
23 #define LTC2991_CHANNEL_V_MSB(x) (0x0A + ((x) * 2))
24 #define LTC2991_CHANNEL_T_MSB(x) (0x0A + ((x) * 4))
25 #define LTC2991_CHANNEL_C_MSB(x) (0x0C + ((x) * 4))
26 #define LTC2991_T_INT_MSB 0x1A
27 #define LTC2991_VCC_MSB 0x1C
29 #define LTC2991_V7_V8_EN BIT(7)
30 #define LTC2991_V5_V6_EN BIT(6)
31 #define LTC2991_V3_V4_EN BIT(5)
32 #define LTC2991_V1_V2_EN BIT(4)
33 #define LTC2991_T_INT_VCC_EN BIT(3)
35 #define LTC2991_V3_V4_FILT_EN BIT(7)
36 #define LTC2991_V3_V4_TEMP_EN BIT(5)
37 #define LTC2991_V3_V4_DIFF_EN BIT(4)
38 #define LTC2991_V1_V2_FILT_EN BIT(3)
39 #define LTC2991_V1_V2_TEMP_EN BIT(1)
40 #define LTC2991_V1_V2_DIFF_EN BIT(0)
42 #define LTC2991_V7_V8_FILT_EN BIT(7)
43 #define LTC2991_V7_V8_TEMP_EN BIT(5)
44 #define LTC2991_V7_V8_DIFF_EN BIT(4)
45 #define LTC2991_V5_V6_FILT_EN BIT(3)
46 #define LTC2991_V5_V6_TEMP_EN BIT(1)
47 #define LTC2991_V5_V6_DIFF_EN BIT(0)
49 #define LTC2991_REPEAT_ACQ_EN BIT(4)
50 #define LTC2991_T_INT_FILT_EN BIT(3)
52 #define LTC2991_MAX_CHANNEL 4
53 #define LTC2991_T_INT_CH_NR 4
54 #define LTC2991_VCC_CH_NR 0
56 struct ltc2991_state
{
57 struct regmap
*regmap
;
58 u32 r_sense_uohm
[LTC2991_MAX_CHANNEL
];
59 bool temp_en
[LTC2991_MAX_CHANNEL
];
62 static int ltc2991_read_reg(struct ltc2991_state
*st
, u8 addr
, u8 reg_len
,
69 return regmap_read(st
->regmap
, addr
, val
);
71 ret
= regmap_bulk_read(st
->regmap
, addr
, ®vals
, reg_len
);
75 *val
= be16_to_cpu(regvals
);
80 static int ltc2991_get_voltage(struct ltc2991_state
*st
, u32 reg
, long *val
)
82 int reg_val
, ret
, offset
= 0;
84 ret
= ltc2991_read_reg(st
, reg
, 2, ®_val
);
88 if (reg
== LTC2991_VCC_MSB
)
92 /* Vx, 305.18uV/LSB */
93 *val
= DIV_ROUND_CLOSEST(sign_extend32(reg_val
, 14) * 30518,
99 static int ltc2991_read_in(struct device
*dev
, u32 attr
, int channel
, long *val
)
101 struct ltc2991_state
*st
= dev_get_drvdata(dev
);
106 if (channel
== LTC2991_VCC_CH_NR
)
107 reg
= LTC2991_VCC_MSB
;
109 reg
= LTC2991_CHANNEL_V_MSB(channel
- 1);
111 return ltc2991_get_voltage(st
, reg
, val
);
117 static int ltc2991_get_curr(struct ltc2991_state
*st
, u32 reg
, int channel
,
122 ret
= ltc2991_read_reg(st
, reg
, 2, ®_val
);
126 /* Vx-Vy, 19.075uV/LSB */
127 *val
= DIV_ROUND_CLOSEST(sign_extend32(reg_val
, 14) * 19075,
128 st
->r_sense_uohm
[channel
]);
133 static int ltc2991_read_curr(struct device
*dev
, u32 attr
, int channel
,
136 struct ltc2991_state
*st
= dev_get_drvdata(dev
);
140 case hwmon_curr_input
:
141 reg
= LTC2991_CHANNEL_C_MSB(channel
);
142 return ltc2991_get_curr(st
, reg
, channel
, val
);
148 static int ltc2991_get_temp(struct ltc2991_state
*st
, u32 reg
, int channel
,
153 ret
= ltc2991_read_reg(st
, reg
, 2, ®_val
);
157 /* Temp LSB = 0.0625 Degrees */
158 *val
= DIV_ROUND_CLOSEST(sign_extend32(reg_val
, 12) * 1000, 16);
163 static int ltc2991_read_temp(struct device
*dev
, u32 attr
, int channel
,
166 struct ltc2991_state
*st
= dev_get_drvdata(dev
);
170 case hwmon_temp_input
:
171 if (channel
== LTC2991_T_INT_CH_NR
)
172 reg
= LTC2991_T_INT_MSB
;
174 reg
= LTC2991_CHANNEL_T_MSB(channel
);
176 return ltc2991_get_temp(st
, reg
, channel
, val
);
182 static int ltc2991_read(struct device
*dev
, enum hwmon_sensor_types type
,
183 u32 attr
, int channel
, long *val
)
187 return ltc2991_read_in(dev
, attr
, channel
, val
);
189 return ltc2991_read_curr(dev
, attr
, channel
, val
);
191 return ltc2991_read_temp(dev
, attr
, channel
, val
);
197 static umode_t
ltc2991_is_visible(const void *data
,
198 enum hwmon_sensor_types type
, u32 attr
,
201 const struct ltc2991_state
*st
= data
;
207 if (channel
== LTC2991_VCC_CH_NR
)
209 if (st
->temp_en
[(channel
- 1) / 2])
213 if (!st
->r_sense_uohm
[(channel
- 1) / 2])
219 case hwmon_curr_input
:
220 if (st
->r_sense_uohm
[channel
])
227 case hwmon_temp_input
:
228 if (channel
== LTC2991_T_INT_CH_NR
||
229 st
->temp_en
[channel
])
241 static const struct hwmon_ops ltc2991_hwmon_ops
= {
242 .is_visible
= ltc2991_is_visible
,
243 .read
= ltc2991_read
,
246 static const struct hwmon_channel_info
*ltc2991_info
[] = {
247 HWMON_CHANNEL_INFO(temp
,
254 HWMON_CHANNEL_INFO(curr
,
260 HWMON_CHANNEL_INFO(in
,
274 static const struct hwmon_chip_info ltc2991_chip_info
= {
275 .ops
= <c2991_hwmon_ops
,
276 .info
= ltc2991_info
,
279 static const struct regmap_config ltc2991_regmap_config
= {
282 .max_register
= 0x1D,
285 static int ltc2991_init(struct ltc2991_state
*st
, struct device
*dev
)
289 u8 v5_v8_reg_data
= 0, v1_v4_reg_data
= 0;
291 ret
= devm_regulator_get_enable(dev
, "vcc");
293 return dev_err_probe(dev
, ret
,
294 "failed to enable regulator\n");
296 device_for_each_child_node_scoped(dev
, child
) {
297 ret
= fwnode_property_read_u32(child
, "reg", &addr
);
304 ret
= fwnode_property_read_u32(child
,
305 "shunt-resistor-micro-ohms",
309 return dev_err_probe(dev
, -EINVAL
,
310 "shunt resistor value cannot be zero\n");
312 st
->r_sense_uohm
[addr
] = val
;
316 v1_v4_reg_data
|= LTC2991_V1_V2_DIFF_EN
;
319 v1_v4_reg_data
|= LTC2991_V3_V4_DIFF_EN
;
322 v5_v8_reg_data
|= LTC2991_V5_V6_DIFF_EN
;
325 v5_v8_reg_data
|= LTC2991_V7_V8_DIFF_EN
;
332 ret
= fwnode_property_read_bool(child
,
333 "adi,temperature-enable");
335 st
->temp_en
[addr
] = ret
;
339 v1_v4_reg_data
|= LTC2991_V1_V2_TEMP_EN
;
342 v1_v4_reg_data
|= LTC2991_V3_V4_TEMP_EN
;
345 v5_v8_reg_data
|= LTC2991_V5_V6_TEMP_EN
;
348 v5_v8_reg_data
|= LTC2991_V7_V8_TEMP_EN
;
356 ret
= regmap_write(st
->regmap
, LTC2991_V5_V8_CTRL
, v5_v8_reg_data
);
358 return dev_err_probe(dev
, ret
,
359 "Error: Failed to set V5-V8 CTRL reg.\n");
361 ret
= regmap_write(st
->regmap
, LTC2991_V1_V4_CTRL
, v1_v4_reg_data
);
363 return dev_err_probe(dev
, ret
,
364 "Error: Failed to set V1-V4 CTRL reg.\n");
366 ret
= regmap_write(st
->regmap
, LTC2991_PWM_TH_LSB_T_INT
,
367 LTC2991_REPEAT_ACQ_EN
);
369 return dev_err_probe(dev
, ret
,
370 "Error: Failed to set continuous mode.\n");
372 /* Enable all channels and trigger conversions */
373 return regmap_write(st
->regmap
, LTC2991_CH_EN_TRIGGER
,
374 LTC2991_V7_V8_EN
| LTC2991_V5_V6_EN
|
375 LTC2991_V3_V4_EN
| LTC2991_V1_V2_EN
|
376 LTC2991_T_INT_VCC_EN
);
379 static int ltc2991_i2c_probe(struct i2c_client
*client
)
382 struct device
*hwmon_dev
;
383 struct ltc2991_state
*st
;
385 st
= devm_kzalloc(&client
->dev
, sizeof(*st
), GFP_KERNEL
);
389 st
->regmap
= devm_regmap_init_i2c(client
, <c2991_regmap_config
);
390 if (IS_ERR(st
->regmap
))
391 return PTR_ERR(st
->regmap
);
393 ret
= ltc2991_init(st
, &client
->dev
);
397 hwmon_dev
= devm_hwmon_device_register_with_info(&client
->dev
,
402 return PTR_ERR_OR_ZERO(hwmon_dev
);
405 static const struct of_device_id ltc2991_of_match
[] = {
406 { .compatible
= "adi,ltc2991" },
409 MODULE_DEVICE_TABLE(of
, ltc2991_of_match
);
411 static const struct i2c_device_id ltc2991_i2c_id
[] = {
415 MODULE_DEVICE_TABLE(i2c
, ltc2991_i2c_id
);
417 static struct i2c_driver ltc2991_i2c_driver
= {
420 .of_match_table
= ltc2991_of_match
,
422 .probe
= ltc2991_i2c_probe
,
423 .id_table
= ltc2991_i2c_id
,
426 module_i2c_driver(ltc2991_i2c_driver
);
428 MODULE_AUTHOR("Antoniu Miclaus <antoniu.miclaus@analog.com>");
429 MODULE_DESCRIPTION("Analog Devices LTC2991 HWMON Driver");
430 MODULE_LICENSE("GPL");