]> Git Repo - J-linux.git/blob - drivers/hwmon/ltc2991.c
Merge tag 'vfs-6.13-rc7.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
[J-linux.git] / drivers / hwmon / ltc2991.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2023 Analog Devices, Inc.
4  * Author: Antoniu Miclaus <[email protected]>
5  */
6
7 #include <linux/bitops.h>
8 #include <linux/err.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>
16
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
28
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)
34
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)
41
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)
48
49 #define LTC2991_REPEAT_ACQ_EN           BIT(4)
50 #define LTC2991_T_INT_FILT_EN           BIT(3)
51
52 #define LTC2991_MAX_CHANNEL             4
53 #define LTC2991_T_INT_CH_NR             4
54 #define LTC2991_VCC_CH_NR               0
55
56 struct ltc2991_state {
57         struct regmap           *regmap;
58         u32                     r_sense_uohm[LTC2991_MAX_CHANNEL];
59         bool                    temp_en[LTC2991_MAX_CHANNEL];
60 };
61
62 static int ltc2991_read_reg(struct ltc2991_state *st, u8 addr, u8 reg_len,
63                             int *val)
64 {
65         __be16 regvals;
66         int ret;
67
68         if (reg_len < 2)
69                 return regmap_read(st->regmap, addr, val);
70
71         ret = regmap_bulk_read(st->regmap, addr, &regvals, reg_len);
72         if (ret)
73                 return ret;
74
75         *val = be16_to_cpu(regvals);
76
77         return 0;
78 }
79
80 static int ltc2991_get_voltage(struct ltc2991_state *st, u32 reg, long *val)
81 {
82         int reg_val, ret, offset = 0;
83
84         ret = ltc2991_read_reg(st, reg, 2, &reg_val);
85         if (ret)
86                 return ret;
87
88         if (reg == LTC2991_VCC_MSB)
89                 /* Vcc 2.5V offset */
90                 offset = 2500;
91
92         /* Vx, 305.18uV/LSB */
93         *val = DIV_ROUND_CLOSEST(sign_extend32(reg_val, 14) * 30518,
94                                  1000 * 100) + offset;
95
96         return 0;
97 }
98
99 static int ltc2991_read_in(struct device *dev, u32 attr, int channel, long *val)
100 {
101         struct ltc2991_state *st = dev_get_drvdata(dev);
102         u32 reg;
103
104         switch (attr) {
105         case hwmon_in_input:
106                 if (channel == LTC2991_VCC_CH_NR)
107                         reg = LTC2991_VCC_MSB;
108                 else
109                         reg = LTC2991_CHANNEL_V_MSB(channel - 1);
110
111                 return ltc2991_get_voltage(st, reg, val);
112         default:
113                 return -EOPNOTSUPP;
114         }
115 }
116
117 static int ltc2991_get_curr(struct ltc2991_state *st, u32 reg, int channel,
118                             long *val)
119 {
120         int reg_val, ret;
121
122         ret = ltc2991_read_reg(st, reg, 2, &reg_val);
123         if (ret)
124                 return ret;
125
126         /* Vx-Vy, 19.075uV/LSB */
127         *val = DIV_ROUND_CLOSEST(sign_extend32(reg_val, 14) * 19075,
128                                  st->r_sense_uohm[channel]);
129
130         return 0;
131 }
132
133 static int ltc2991_read_curr(struct device *dev, u32 attr, int channel,
134                              long *val)
135 {
136         struct ltc2991_state *st = dev_get_drvdata(dev);
137         u32 reg;
138
139         switch (attr) {
140         case hwmon_curr_input:
141                 reg = LTC2991_CHANNEL_C_MSB(channel);
142                 return ltc2991_get_curr(st, reg, channel, val);
143         default:
144                 return -EOPNOTSUPP;
145         }
146 }
147
148 static int ltc2991_get_temp(struct ltc2991_state *st, u32 reg, int channel,
149                             long *val)
150 {
151         int reg_val, ret;
152
153         ret = ltc2991_read_reg(st, reg, 2, &reg_val);
154         if (ret)
155                 return ret;
156
157         /* Temp LSB = 0.0625 Degrees */
158         *val = DIV_ROUND_CLOSEST(sign_extend32(reg_val, 12) * 1000, 16);
159
160         return 0;
161 }
162
163 static int ltc2991_read_temp(struct device *dev, u32 attr, int channel,
164                              long *val)
165 {
166         struct ltc2991_state *st = dev_get_drvdata(dev);
167         u32 reg;
168
169         switch (attr) {
170         case hwmon_temp_input:
171                 if (channel == LTC2991_T_INT_CH_NR)
172                         reg = LTC2991_T_INT_MSB;
173                 else
174                         reg = LTC2991_CHANNEL_T_MSB(channel);
175
176                 return ltc2991_get_temp(st, reg, channel, val);
177         default:
178                 return -EOPNOTSUPP;
179         }
180 }
181
182 static int ltc2991_read(struct device *dev, enum hwmon_sensor_types type,
183                         u32 attr, int channel, long *val)
184 {
185         switch (type) {
186         case hwmon_in:
187                 return ltc2991_read_in(dev, attr, channel, val);
188         case hwmon_curr:
189                 return ltc2991_read_curr(dev, attr, channel, val);
190         case hwmon_temp:
191                 return ltc2991_read_temp(dev, attr, channel, val);
192         default:
193                 return -EOPNOTSUPP;
194         }
195 }
196
197 static umode_t ltc2991_is_visible(const void *data,
198                                   enum hwmon_sensor_types type, u32 attr,
199                                   int channel)
200 {
201         const struct ltc2991_state *st = data;
202
203         switch (type) {
204         case hwmon_in:
205                 switch (attr) {
206                 case hwmon_in_input:
207                         if (channel == LTC2991_VCC_CH_NR)
208                                 return 0444;
209                         if (st->temp_en[(channel - 1) / 2])
210                                 break;
211                         if (channel % 2)
212                                 return 0444;
213                         if (!st->r_sense_uohm[(channel - 1) / 2])
214                                 return 0444;
215                 }
216                 break;
217         case hwmon_curr:
218                 switch (attr) {
219                 case hwmon_curr_input:
220                         if (st->r_sense_uohm[channel])
221                                 return 0444;
222                         break;
223                 }
224                 break;
225         case hwmon_temp:
226                 switch (attr) {
227                 case hwmon_temp_input:
228                         if (channel == LTC2991_T_INT_CH_NR ||
229                             st->temp_en[channel])
230                                 return 0444;
231                         break;
232                 }
233                 break;
234         default:
235                 break;
236         }
237
238         return 0;
239 }
240
241 static const struct hwmon_ops ltc2991_hwmon_ops = {
242         .is_visible = ltc2991_is_visible,
243         .read = ltc2991_read,
244 };
245
246 static const struct hwmon_channel_info *ltc2991_info[] = {
247         HWMON_CHANNEL_INFO(temp,
248                            HWMON_T_INPUT,
249                            HWMON_T_INPUT,
250                            HWMON_T_INPUT,
251                            HWMON_T_INPUT,
252                            HWMON_T_INPUT
253                            ),
254         HWMON_CHANNEL_INFO(curr,
255                            HWMON_C_INPUT,
256                            HWMON_C_INPUT,
257                            HWMON_C_INPUT,
258                            HWMON_C_INPUT
259                            ),
260         HWMON_CHANNEL_INFO(in,
261                            HWMON_I_INPUT,
262                            HWMON_I_INPUT,
263                            HWMON_I_INPUT,
264                            HWMON_I_INPUT,
265                            HWMON_I_INPUT,
266                            HWMON_I_INPUT,
267                            HWMON_I_INPUT,
268                            HWMON_I_INPUT,
269                            HWMON_I_INPUT
270                            ),
271         NULL
272 };
273
274 static const struct hwmon_chip_info ltc2991_chip_info = {
275         .ops = &ltc2991_hwmon_ops,
276         .info = ltc2991_info,
277 };
278
279 static const struct regmap_config ltc2991_regmap_config = {
280         .reg_bits = 8,
281         .val_bits = 8,
282         .max_register = 0x1D,
283 };
284
285 static int ltc2991_init(struct ltc2991_state *st, struct device *dev)
286 {
287         int ret;
288         u32 val, addr;
289         u8 v5_v8_reg_data = 0, v1_v4_reg_data = 0;
290
291         ret = devm_regulator_get_enable(dev, "vcc");
292         if (ret)
293                 return dev_err_probe(dev, ret,
294                                      "failed to enable regulator\n");
295
296         device_for_each_child_node_scoped(dev, child) {
297                 ret = fwnode_property_read_u32(child, "reg", &addr);
298                 if (ret < 0)
299                         return ret;
300
301                 if (addr > 3)
302                         return -EINVAL;
303
304                 ret = fwnode_property_read_u32(child,
305                                                "shunt-resistor-micro-ohms",
306                                                &val);
307                 if (!ret) {
308                         if (!val)
309                                 return dev_err_probe(dev, -EINVAL,
310                                                      "shunt resistor value cannot be zero\n");
311
312                         st->r_sense_uohm[addr] = val;
313
314                         switch (addr) {
315                         case 0:
316                                 v1_v4_reg_data |= LTC2991_V1_V2_DIFF_EN;
317                                 break;
318                         case 1:
319                                 v1_v4_reg_data |= LTC2991_V3_V4_DIFF_EN;
320                                 break;
321                         case 2:
322                                 v5_v8_reg_data |= LTC2991_V5_V6_DIFF_EN;
323                                 break;
324                         case 3:
325                                 v5_v8_reg_data |= LTC2991_V7_V8_DIFF_EN;
326                                 break;
327                         default:
328                                 break;
329                         }
330                 }
331
332                 ret = fwnode_property_read_bool(child,
333                                                 "adi,temperature-enable");
334                 if (ret) {
335                         st->temp_en[addr] = ret;
336
337                         switch (addr) {
338                         case 0:
339                                 v1_v4_reg_data |= LTC2991_V1_V2_TEMP_EN;
340                                 break;
341                         case 1:
342                                 v1_v4_reg_data |= LTC2991_V3_V4_TEMP_EN;
343                                 break;
344                         case 2:
345                                 v5_v8_reg_data |= LTC2991_V5_V6_TEMP_EN;
346                                 break;
347                         case 3:
348                                 v5_v8_reg_data |= LTC2991_V7_V8_TEMP_EN;
349                                 break;
350                         default:
351                                 break;
352                         }
353                 }
354         }
355
356         ret = regmap_write(st->regmap, LTC2991_V5_V8_CTRL, v5_v8_reg_data);
357         if (ret)
358                 return dev_err_probe(dev, ret,
359                                      "Error: Failed to set V5-V8 CTRL reg.\n");
360
361         ret = regmap_write(st->regmap, LTC2991_V1_V4_CTRL, v1_v4_reg_data);
362         if (ret)
363                 return dev_err_probe(dev, ret,
364                                      "Error: Failed to set V1-V4 CTRL reg.\n");
365
366         ret = regmap_write(st->regmap, LTC2991_PWM_TH_LSB_T_INT,
367                            LTC2991_REPEAT_ACQ_EN);
368         if (ret)
369                 return dev_err_probe(dev, ret,
370                                      "Error: Failed to set continuous mode.\n");
371
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);
377 }
378
379 static int ltc2991_i2c_probe(struct i2c_client *client)
380 {
381         int ret;
382         struct device *hwmon_dev;
383         struct ltc2991_state *st;
384
385         st = devm_kzalloc(&client->dev, sizeof(*st), GFP_KERNEL);
386         if (!st)
387                 return -ENOMEM;
388
389         st->regmap = devm_regmap_init_i2c(client, &ltc2991_regmap_config);
390         if (IS_ERR(st->regmap))
391                 return PTR_ERR(st->regmap);
392
393         ret = ltc2991_init(st, &client->dev);
394         if (ret)
395                 return ret;
396
397         hwmon_dev = devm_hwmon_device_register_with_info(&client->dev,
398                                                          client->name, st,
399                                                          &ltc2991_chip_info,
400                                                          NULL);
401
402         return PTR_ERR_OR_ZERO(hwmon_dev);
403 }
404
405 static const struct of_device_id ltc2991_of_match[] = {
406         { .compatible = "adi,ltc2991" },
407         { }
408 };
409 MODULE_DEVICE_TABLE(of, ltc2991_of_match);
410
411 static const struct i2c_device_id ltc2991_i2c_id[] = {
412         { "ltc2991" },
413         {}
414 };
415 MODULE_DEVICE_TABLE(i2c, ltc2991_i2c_id);
416
417 static struct i2c_driver ltc2991_i2c_driver = {
418         .driver = {
419                 .name = "ltc2991",
420                 .of_match_table = ltc2991_of_match,
421         },
422         .probe = ltc2991_i2c_probe,
423         .id_table = ltc2991_i2c_id,
424 };
425
426 module_i2c_driver(ltc2991_i2c_driver);
427
428 MODULE_AUTHOR("Antoniu Miclaus <[email protected]>");
429 MODULE_DESCRIPTION("Analog Devices LTC2991 HWMON Driver");
430 MODULE_LICENSE("GPL");
This page took 0.050638 seconds and 4 git commands to generate.