1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Analog Devices LTC2947 high precision power and energy monitor |
4 | * |
5 | * Copyright 2019 Analog Devices Inc. |
6 | */ |
7 | #include <linux/bitfield.h> |
8 | #include <linux/bits.h> |
9 | #include <linux/clk.h> |
10 | #include <linux/device.h> |
11 | #include <linux/hwmon.h> |
12 | #include <linux/hwmon-sysfs.h> |
13 | #include <linux/module.h> |
14 | #include <linux/of.h> |
15 | #include <linux/regmap.h> |
16 | |
17 | #include "ltc2947.h" |
18 | |
19 | /* register's */ |
20 | #define LTC2947_REG_PAGE_CTRL 0xFF |
21 | #define LTC2947_REG_CTRL 0xF0 |
22 | #define LTC2947_REG_TBCTL 0xE9 |
23 | #define LTC2947_CONT_MODE_MASK BIT(3) |
24 | #define LTC2947_CONT_MODE(x) FIELD_PREP(LTC2947_CONT_MODE_MASK, x) |
25 | #define LTC2947_PRE_MASK GENMASK(2, 0) |
26 | #define LTC2947_PRE(x) FIELD_PREP(LTC2947_PRE_MASK, x) |
27 | #define LTC2947_DIV_MASK GENMASK(7, 3) |
28 | #define LTC2947_DIV(x) FIELD_PREP(LTC2947_DIV_MASK, x) |
29 | #define LTC2947_SHUTDOWN_MASK BIT(0) |
30 | #define LTC2947_REG_ACCUM_POL 0xE1 |
31 | #define LTC2947_ACCUM_POL_1_MASK GENMASK(1, 0) |
32 | #define LTC2947_ACCUM_POL_1(x) FIELD_PREP(LTC2947_ACCUM_POL_1_MASK, x) |
33 | #define LTC2947_ACCUM_POL_2_MASK GENMASK(3, 2) |
34 | #define LTC2947_ACCUM_POL_2(x) FIELD_PREP(LTC2947_ACCUM_POL_2_MASK, x) |
35 | #define LTC2947_REG_ACCUM_DEADBAND 0xE4 |
36 | #define LTC2947_REG_GPIOSTATCTL 0x67 |
37 | #define LTC2947_GPIO_EN_MASK BIT(0) |
38 | #define LTC2947_GPIO_EN(x) FIELD_PREP(LTC2947_GPIO_EN_MASK, x) |
39 | #define LTC2947_GPIO_FAN_EN_MASK BIT(6) |
40 | #define LTC2947_GPIO_FAN_EN(x) FIELD_PREP(LTC2947_GPIO_FAN_EN_MASK, x) |
41 | #define LTC2947_GPIO_FAN_POL_MASK BIT(7) |
42 | #define LTC2947_GPIO_FAN_POL(x) FIELD_PREP(LTC2947_GPIO_FAN_POL_MASK, x) |
43 | #define LTC2947_REG_GPIO_ACCUM 0xE3 |
44 | /* 200Khz */ |
45 | #define LTC2947_CLK_MIN 200000 |
46 | /* 25Mhz */ |
47 | #define LTC2947_CLK_MAX 25000000 |
48 | #define LTC2947_PAGE0 0 |
49 | #define LTC2947_PAGE1 1 |
50 | /* Voltage registers */ |
51 | #define LTC2947_REG_VOLTAGE 0xA0 |
52 | #define LTC2947_REG_VOLTAGE_MAX 0x50 |
53 | #define LTC2947_REG_VOLTAGE_MIN 0x52 |
54 | #define LTC2947_REG_VOLTAGE_THRE_H 0x90 |
55 | #define LTC2947_REG_VOLTAGE_THRE_L 0x92 |
56 | #define LTC2947_REG_DVCC 0xA4 |
57 | #define LTC2947_REG_DVCC_MAX 0x58 |
58 | #define LTC2947_REG_DVCC_MIN 0x5A |
59 | #define LTC2947_REG_DVCC_THRE_H 0x98 |
60 | #define LTC2947_REG_DVCC_THRE_L 0x9A |
61 | #define LTC2947_VOLTAGE_GEN_CHAN 0 |
62 | #define LTC2947_VOLTAGE_DVCC_CHAN 1 |
63 | /* in mV */ |
64 | #define VOLTAGE_MAX 15500 |
65 | #define VOLTAGE_MIN -300 |
66 | #define VDVCC_MAX 15000 |
67 | #define VDVCC_MIN 4750 |
68 | /* Current registers */ |
69 | #define LTC2947_REG_CURRENT 0x90 |
70 | #define LTC2947_REG_CURRENT_MAX 0x40 |
71 | #define LTC2947_REG_CURRENT_MIN 0x42 |
72 | #define LTC2947_REG_CURRENT_THRE_H 0x80 |
73 | #define LTC2947_REG_CURRENT_THRE_L 0x82 |
74 | /* in mA */ |
75 | #define CURRENT_MAX 30000 |
76 | #define CURRENT_MIN -30000 |
77 | /* Power registers */ |
78 | #define LTC2947_REG_POWER 0x93 |
79 | #define LTC2947_REG_POWER_MAX 0x44 |
80 | #define LTC2947_REG_POWER_MIN 0x46 |
81 | #define LTC2947_REG_POWER_THRE_H 0x84 |
82 | #define LTC2947_REG_POWER_THRE_L 0x86 |
83 | /* in uW */ |
84 | #define POWER_MAX 450000000 |
85 | #define POWER_MIN -450000000 |
86 | /* Temperature registers */ |
87 | #define LTC2947_REG_TEMP 0xA2 |
88 | #define LTC2947_REG_TEMP_MAX 0x54 |
89 | #define LTC2947_REG_TEMP_MIN 0x56 |
90 | #define LTC2947_REG_TEMP_THRE_H 0x94 |
91 | #define LTC2947_REG_TEMP_THRE_L 0x96 |
92 | #define LTC2947_REG_TEMP_FAN_THRE_H 0x9C |
93 | #define LTC2947_REG_TEMP_FAN_THRE_L 0x9E |
94 | #define LTC2947_TEMP_FAN_CHAN 1 |
95 | /* in millidegress Celsius */ |
96 | #define TEMP_MAX 85000 |
97 | #define TEMP_MIN -40000 |
98 | /* Energy registers */ |
99 | #define LTC2947_REG_ENERGY1 0x06 |
100 | #define LTC2947_REG_ENERGY2 0x16 |
101 | /* Status/Alarm/Overflow registers */ |
102 | #define LTC2947_REG_STATUS 0x80 |
103 | #define LTC2947_REG_STATVT 0x81 |
104 | #define LTC2947_REG_STATIP 0x82 |
105 | #define LTC2947_REG_STATVDVCC 0x87 |
106 | |
107 | #define LTC2947_ALERTS_SIZE (LTC2947_REG_STATVDVCC - LTC2947_REG_STATUS) |
108 | #define LTC2947_MAX_VOLTAGE_MASK BIT(0) |
109 | #define LTC2947_MIN_VOLTAGE_MASK BIT(1) |
110 | #define LTC2947_MAX_CURRENT_MASK BIT(0) |
111 | #define LTC2947_MIN_CURRENT_MASK BIT(1) |
112 | #define LTC2947_MAX_POWER_MASK BIT(2) |
113 | #define LTC2947_MIN_POWER_MASK BIT(3) |
114 | #define LTC2947_MAX_TEMP_MASK BIT(2) |
115 | #define LTC2947_MIN_TEMP_MASK BIT(3) |
116 | #define LTC2947_MAX_TEMP_FAN_MASK BIT(4) |
117 | #define LTC2947_MIN_TEMP_FAN_MASK BIT(5) |
118 | |
119 | struct ltc2947_data { |
120 | struct regmap *map; |
121 | struct device *dev; |
122 | /* |
123 | * The mutex is needed because the device has 2 memory pages. When |
124 | * reading/writing the correct page needs to be set so that, the |
125 | * complete sequence select_page->read/write needs to be protected. |
126 | */ |
127 | struct mutex lock; |
128 | u32 lsb_energy; |
129 | bool gpio_out; |
130 | }; |
131 | |
132 | static int __ltc2947_val_read16(const struct ltc2947_data *st, const u8 reg, |
133 | u64 *val) |
134 | { |
135 | __be16 __val = 0; |
136 | int ret; |
137 | |
138 | ret = regmap_bulk_read(map: st->map, reg, val: &__val, val_count: 2); |
139 | if (ret) |
140 | return ret; |
141 | |
142 | *val = be16_to_cpu(__val); |
143 | |
144 | return 0; |
145 | } |
146 | |
147 | static int __ltc2947_val_read24(const struct ltc2947_data *st, const u8 reg, |
148 | u64 *val) |
149 | { |
150 | __be32 __val = 0; |
151 | int ret; |
152 | |
153 | ret = regmap_bulk_read(map: st->map, reg, val: &__val, val_count: 3); |
154 | if (ret) |
155 | return ret; |
156 | |
157 | *val = be32_to_cpu(__val) >> 8; |
158 | |
159 | return 0; |
160 | } |
161 | |
162 | static int __ltc2947_val_read64(const struct ltc2947_data *st, const u8 reg, |
163 | u64 *val) |
164 | { |
165 | __be64 __val = 0; |
166 | int ret; |
167 | |
168 | ret = regmap_bulk_read(map: st->map, reg, val: &__val, val_count: 6); |
169 | if (ret) |
170 | return ret; |
171 | |
172 | *val = be64_to_cpu(__val) >> 16; |
173 | |
174 | return 0; |
175 | } |
176 | |
177 | static int ltc2947_val_read(struct ltc2947_data *st, const u8 reg, |
178 | const u8 page, const size_t size, s64 *val) |
179 | { |
180 | int ret; |
181 | u64 __val = 0; |
182 | |
183 | mutex_lock(&st->lock); |
184 | |
185 | ret = regmap_write(map: st->map, LTC2947_REG_PAGE_CTRL, val: page); |
186 | if (ret) { |
187 | mutex_unlock(lock: &st->lock); |
188 | return ret; |
189 | } |
190 | |
191 | dev_dbg(st->dev, "Read val, reg:%02X, p:%d sz:%zu\n" , reg, page, |
192 | size); |
193 | |
194 | switch (size) { |
195 | case 2: |
196 | ret = __ltc2947_val_read16(st, reg, val: &__val); |
197 | break; |
198 | case 3: |
199 | ret = __ltc2947_val_read24(st, reg, val: &__val); |
200 | break; |
201 | case 6: |
202 | ret = __ltc2947_val_read64(st, reg, val: &__val); |
203 | break; |
204 | default: |
205 | ret = -EINVAL; |
206 | break; |
207 | } |
208 | |
209 | mutex_unlock(lock: &st->lock); |
210 | |
211 | if (ret) |
212 | return ret; |
213 | |
214 | *val = sign_extend64(value: __val, index: (8 * size) - 1); |
215 | |
216 | dev_dbg(st->dev, "Got s:%lld, u:%016llX\n" , *val, __val); |
217 | |
218 | return 0; |
219 | } |
220 | |
221 | static int __ltc2947_val_write64(const struct ltc2947_data *st, const u8 reg, |
222 | const u64 val) |
223 | { |
224 | __be64 __val; |
225 | |
226 | __val = cpu_to_be64(val << 16); |
227 | return regmap_bulk_write(map: st->map, reg, val: &__val, val_count: 6); |
228 | } |
229 | |
230 | static int __ltc2947_val_write16(const struct ltc2947_data *st, const u8 reg, |
231 | const u16 val) |
232 | { |
233 | __be16 __val; |
234 | |
235 | __val = cpu_to_be16(val); |
236 | return regmap_bulk_write(map: st->map, reg, val: &__val, val_count: 2); |
237 | } |
238 | |
239 | static int ltc2947_val_write(struct ltc2947_data *st, const u8 reg, |
240 | const u8 page, const size_t size, const u64 val) |
241 | { |
242 | int ret; |
243 | |
244 | mutex_lock(&st->lock); |
245 | /* set device on correct page */ |
246 | ret = regmap_write(map: st->map, LTC2947_REG_PAGE_CTRL, val: page); |
247 | if (ret) { |
248 | mutex_unlock(lock: &st->lock); |
249 | return ret; |
250 | } |
251 | |
252 | dev_dbg(st->dev, "Write val, r:%02X, p:%d, sz:%zu, val:%016llX\n" , |
253 | reg, page, size, val); |
254 | |
255 | switch (size) { |
256 | case 2: |
257 | ret = __ltc2947_val_write16(st, reg, val); |
258 | break; |
259 | case 6: |
260 | ret = __ltc2947_val_write64(st, reg, val); |
261 | break; |
262 | default: |
263 | ret = -EINVAL; |
264 | break; |
265 | } |
266 | |
267 | mutex_unlock(lock: &st->lock); |
268 | |
269 | return ret; |
270 | } |
271 | |
272 | static int ltc2947_reset_history(struct ltc2947_data *st, const u8 reg_h, |
273 | const u8 reg_l) |
274 | { |
275 | int ret; |
276 | /* |
277 | * let's reset the tracking register's. Tracking register's have all |
278 | * 2 bytes size |
279 | */ |
280 | ret = ltc2947_val_write(st, reg: reg_h, LTC2947_PAGE0, size: 2, val: 0x8000U); |
281 | if (ret) |
282 | return ret; |
283 | |
284 | return ltc2947_val_write(st, reg: reg_l, LTC2947_PAGE0, size: 2, val: 0x7FFFU); |
285 | } |
286 | |
287 | static int ltc2947_alarm_read(struct ltc2947_data *st, const u8 reg, |
288 | const u32 mask, long *val) |
289 | { |
290 | u8 offset = reg - LTC2947_REG_STATUS; |
291 | /* +1 to include status reg */ |
292 | char alarms[LTC2947_ALERTS_SIZE + 1]; |
293 | int ret = 0; |
294 | |
295 | memset(alarms, 0, sizeof(alarms)); |
296 | |
297 | mutex_lock(&st->lock); |
298 | |
299 | ret = regmap_write(map: st->map, LTC2947_REG_PAGE_CTRL, LTC2947_PAGE0); |
300 | if (ret) |
301 | goto unlock; |
302 | |
303 | dev_dbg(st->dev, "Read alarm, reg:%02X, mask:%02X\n" , reg, mask); |
304 | /* |
305 | * As stated in the datasheet, when Threshold and Overflow registers |
306 | * are used, the status and all alert registers must be read in one |
307 | * multi-byte transaction. |
308 | */ |
309 | ret = regmap_bulk_read(map: st->map, LTC2947_REG_STATUS, val: alarms, |
310 | val_count: sizeof(alarms)); |
311 | if (ret) |
312 | goto unlock; |
313 | |
314 | /* get the alarm */ |
315 | *val = !!(alarms[offset] & mask); |
316 | unlock: |
317 | mutex_unlock(lock: &st->lock); |
318 | return ret; |
319 | } |
320 | |
321 | static ssize_t ltc2947_show_value(struct device *dev, |
322 | struct device_attribute *da, char *buf) |
323 | { |
324 | struct ltc2947_data *st = dev_get_drvdata(dev); |
325 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); |
326 | int ret; |
327 | s64 val = 0; |
328 | |
329 | ret = ltc2947_val_read(st, reg: attr->index, LTC2947_PAGE0, size: 6, val: &val); |
330 | if (ret) |
331 | return ret; |
332 | |
333 | /* value in microJoule. st->lsb_energy was multiplied by 10E9 */ |
334 | val = div_s64(dividend: val * st->lsb_energy, divisor: 1000); |
335 | |
336 | return sprintf(buf, fmt: "%lld\n" , val); |
337 | } |
338 | |
339 | static int ltc2947_read_temp(struct device *dev, const u32 attr, long *val, |
340 | const int channel) |
341 | { |
342 | int ret; |
343 | struct ltc2947_data *st = dev_get_drvdata(dev); |
344 | s64 __val = 0; |
345 | |
346 | switch (attr) { |
347 | case hwmon_temp_input: |
348 | ret = ltc2947_val_read(st, LTC2947_REG_TEMP, LTC2947_PAGE0, |
349 | size: 2, val: &__val); |
350 | break; |
351 | case hwmon_temp_highest: |
352 | ret = ltc2947_val_read(st, LTC2947_REG_TEMP_MAX, LTC2947_PAGE0, |
353 | size: 2, val: &__val); |
354 | break; |
355 | case hwmon_temp_lowest: |
356 | ret = ltc2947_val_read(st, LTC2947_REG_TEMP_MIN, LTC2947_PAGE0, |
357 | size: 2, val: &__val); |
358 | break; |
359 | case hwmon_temp_max_alarm: |
360 | if (channel == LTC2947_TEMP_FAN_CHAN) |
361 | return ltc2947_alarm_read(st, LTC2947_REG_STATVT, |
362 | LTC2947_MAX_TEMP_FAN_MASK, |
363 | val); |
364 | |
365 | return ltc2947_alarm_read(st, LTC2947_REG_STATVT, |
366 | LTC2947_MAX_TEMP_MASK, val); |
367 | case hwmon_temp_min_alarm: |
368 | if (channel == LTC2947_TEMP_FAN_CHAN) |
369 | return ltc2947_alarm_read(st, LTC2947_REG_STATVT, |
370 | LTC2947_MIN_TEMP_FAN_MASK, |
371 | val); |
372 | |
373 | return ltc2947_alarm_read(st, LTC2947_REG_STATVT, |
374 | LTC2947_MIN_TEMP_MASK, val); |
375 | case hwmon_temp_max: |
376 | if (channel == LTC2947_TEMP_FAN_CHAN) |
377 | ret = ltc2947_val_read(st, LTC2947_REG_TEMP_FAN_THRE_H, |
378 | LTC2947_PAGE1, size: 2, val: &__val); |
379 | else |
380 | ret = ltc2947_val_read(st, LTC2947_REG_TEMP_THRE_H, |
381 | LTC2947_PAGE1, size: 2, val: &__val); |
382 | break; |
383 | case hwmon_temp_min: |
384 | if (channel == LTC2947_TEMP_FAN_CHAN) |
385 | ret = ltc2947_val_read(st, LTC2947_REG_TEMP_FAN_THRE_L, |
386 | LTC2947_PAGE1, size: 2, val: &__val); |
387 | else |
388 | ret = ltc2947_val_read(st, LTC2947_REG_TEMP_THRE_L, |
389 | LTC2947_PAGE1, size: 2, val: &__val); |
390 | break; |
391 | default: |
392 | return -ENOTSUPP; |
393 | } |
394 | |
395 | if (ret) |
396 | return ret; |
397 | |
398 | /* in milidegrees celcius, temp is given by: */ |
399 | *val = (__val * 204) + 5500; |
400 | |
401 | return 0; |
402 | } |
403 | |
404 | static int ltc2947_read_power(struct device *dev, const u32 attr, long *val) |
405 | { |
406 | struct ltc2947_data *st = dev_get_drvdata(dev); |
407 | int ret; |
408 | u32 lsb = 200000; /* in uW */ |
409 | s64 __val = 0; |
410 | |
411 | switch (attr) { |
412 | case hwmon_power_input: |
413 | ret = ltc2947_val_read(st, LTC2947_REG_POWER, LTC2947_PAGE0, |
414 | size: 3, val: &__val); |
415 | lsb = 50000; |
416 | break; |
417 | case hwmon_power_input_highest: |
418 | ret = ltc2947_val_read(st, LTC2947_REG_POWER_MAX, LTC2947_PAGE0, |
419 | size: 2, val: &__val); |
420 | break; |
421 | case hwmon_power_input_lowest: |
422 | ret = ltc2947_val_read(st, LTC2947_REG_POWER_MIN, LTC2947_PAGE0, |
423 | size: 2, val: &__val); |
424 | break; |
425 | case hwmon_power_max_alarm: |
426 | return ltc2947_alarm_read(st, LTC2947_REG_STATIP, |
427 | LTC2947_MAX_POWER_MASK, val); |
428 | case hwmon_power_min_alarm: |
429 | return ltc2947_alarm_read(st, LTC2947_REG_STATIP, |
430 | LTC2947_MIN_POWER_MASK, val); |
431 | case hwmon_power_max: |
432 | ret = ltc2947_val_read(st, LTC2947_REG_POWER_THRE_H, |
433 | LTC2947_PAGE1, size: 2, val: &__val); |
434 | break; |
435 | case hwmon_power_min: |
436 | ret = ltc2947_val_read(st, LTC2947_REG_POWER_THRE_L, |
437 | LTC2947_PAGE1, size: 2, val: &__val); |
438 | break; |
439 | default: |
440 | return -ENOTSUPP; |
441 | } |
442 | |
443 | if (ret) |
444 | return ret; |
445 | |
446 | *val = __val * lsb; |
447 | |
448 | return 0; |
449 | } |
450 | |
451 | static int ltc2947_read_curr(struct device *dev, const u32 attr, long *val) |
452 | { |
453 | struct ltc2947_data *st = dev_get_drvdata(dev); |
454 | int ret; |
455 | u8 lsb = 12; /* in mA */ |
456 | s64 __val = 0; |
457 | |
458 | switch (attr) { |
459 | case hwmon_curr_input: |
460 | ret = ltc2947_val_read(st, LTC2947_REG_CURRENT, |
461 | LTC2947_PAGE0, size: 3, val: &__val); |
462 | lsb = 3; |
463 | break; |
464 | case hwmon_curr_highest: |
465 | ret = ltc2947_val_read(st, LTC2947_REG_CURRENT_MAX, |
466 | LTC2947_PAGE0, size: 2, val: &__val); |
467 | break; |
468 | case hwmon_curr_lowest: |
469 | ret = ltc2947_val_read(st, LTC2947_REG_CURRENT_MIN, |
470 | LTC2947_PAGE0, size: 2, val: &__val); |
471 | break; |
472 | case hwmon_curr_max_alarm: |
473 | return ltc2947_alarm_read(st, LTC2947_REG_STATIP, |
474 | LTC2947_MAX_CURRENT_MASK, val); |
475 | case hwmon_curr_min_alarm: |
476 | return ltc2947_alarm_read(st, LTC2947_REG_STATIP, |
477 | LTC2947_MIN_CURRENT_MASK, val); |
478 | case hwmon_curr_max: |
479 | ret = ltc2947_val_read(st, LTC2947_REG_CURRENT_THRE_H, |
480 | LTC2947_PAGE1, size: 2, val: &__val); |
481 | break; |
482 | case hwmon_curr_min: |
483 | ret = ltc2947_val_read(st, LTC2947_REG_CURRENT_THRE_L, |
484 | LTC2947_PAGE1, size: 2, val: &__val); |
485 | break; |
486 | default: |
487 | return -ENOTSUPP; |
488 | } |
489 | |
490 | if (ret) |
491 | return ret; |
492 | |
493 | *val = __val * lsb; |
494 | |
495 | return 0; |
496 | } |
497 | |
498 | static int ltc2947_read_in(struct device *dev, const u32 attr, long *val, |
499 | const int channel) |
500 | { |
501 | struct ltc2947_data *st = dev_get_drvdata(dev); |
502 | int ret; |
503 | u8 lsb = 2; /* in mV */ |
504 | s64 __val = 0; |
505 | |
506 | if (channel < 0 || channel > LTC2947_VOLTAGE_DVCC_CHAN) { |
507 | dev_err(st->dev, "Invalid chan%d for voltage" , channel); |
508 | return -EINVAL; |
509 | } |
510 | |
511 | switch (attr) { |
512 | case hwmon_in_input: |
513 | if (channel == LTC2947_VOLTAGE_DVCC_CHAN) { |
514 | ret = ltc2947_val_read(st, LTC2947_REG_DVCC, |
515 | LTC2947_PAGE0, size: 2, val: &__val); |
516 | lsb = 145; |
517 | } else { |
518 | ret = ltc2947_val_read(st, LTC2947_REG_VOLTAGE, |
519 | LTC2947_PAGE0, size: 2, val: &__val); |
520 | } |
521 | break; |
522 | case hwmon_in_highest: |
523 | if (channel == LTC2947_VOLTAGE_DVCC_CHAN) { |
524 | ret = ltc2947_val_read(st, LTC2947_REG_DVCC_MAX, |
525 | LTC2947_PAGE0, size: 2, val: &__val); |
526 | lsb = 145; |
527 | } else { |
528 | ret = ltc2947_val_read(st, LTC2947_REG_VOLTAGE_MAX, |
529 | LTC2947_PAGE0, size: 2, val: &__val); |
530 | } |
531 | break; |
532 | case hwmon_in_lowest: |
533 | if (channel == LTC2947_VOLTAGE_DVCC_CHAN) { |
534 | ret = ltc2947_val_read(st, LTC2947_REG_DVCC_MIN, |
535 | LTC2947_PAGE0, size: 2, val: &__val); |
536 | lsb = 145; |
537 | } else { |
538 | ret = ltc2947_val_read(st, LTC2947_REG_VOLTAGE_MIN, |
539 | LTC2947_PAGE0, size: 2, val: &__val); |
540 | } |
541 | break; |
542 | case hwmon_in_max_alarm: |
543 | if (channel == LTC2947_VOLTAGE_DVCC_CHAN) |
544 | return ltc2947_alarm_read(st, LTC2947_REG_STATVDVCC, |
545 | LTC2947_MAX_VOLTAGE_MASK, |
546 | val); |
547 | |
548 | return ltc2947_alarm_read(st, LTC2947_REG_STATVT, |
549 | LTC2947_MAX_VOLTAGE_MASK, val); |
550 | case hwmon_in_min_alarm: |
551 | if (channel == LTC2947_VOLTAGE_DVCC_CHAN) |
552 | return ltc2947_alarm_read(st, LTC2947_REG_STATVDVCC, |
553 | LTC2947_MIN_VOLTAGE_MASK, |
554 | val); |
555 | |
556 | return ltc2947_alarm_read(st, LTC2947_REG_STATVT, |
557 | LTC2947_MIN_VOLTAGE_MASK, val); |
558 | case hwmon_in_max: |
559 | if (channel == LTC2947_VOLTAGE_DVCC_CHAN) { |
560 | ret = ltc2947_val_read(st, LTC2947_REG_DVCC_THRE_H, |
561 | LTC2947_PAGE1, size: 2, val: &__val); |
562 | lsb = 145; |
563 | } else { |
564 | ret = ltc2947_val_read(st, LTC2947_REG_VOLTAGE_THRE_H, |
565 | LTC2947_PAGE1, size: 2, val: &__val); |
566 | } |
567 | break; |
568 | case hwmon_in_min: |
569 | if (channel == LTC2947_VOLTAGE_DVCC_CHAN) { |
570 | ret = ltc2947_val_read(st, LTC2947_REG_DVCC_THRE_L, |
571 | LTC2947_PAGE1, size: 2, val: &__val); |
572 | lsb = 145; |
573 | } else { |
574 | ret = ltc2947_val_read(st, LTC2947_REG_VOLTAGE_THRE_L, |
575 | LTC2947_PAGE1, size: 2, val: &__val); |
576 | } |
577 | break; |
578 | default: |
579 | return -ENOTSUPP; |
580 | } |
581 | |
582 | if (ret) |
583 | return ret; |
584 | |
585 | *val = __val * lsb; |
586 | |
587 | return 0; |
588 | } |
589 | |
590 | static int ltc2947_read(struct device *dev, enum hwmon_sensor_types type, |
591 | u32 attr, int channel, long *val) |
592 | { |
593 | switch (type) { |
594 | case hwmon_in: |
595 | return ltc2947_read_in(dev, attr, val, channel); |
596 | case hwmon_curr: |
597 | return ltc2947_read_curr(dev, attr, val); |
598 | case hwmon_power: |
599 | return ltc2947_read_power(dev, attr, val); |
600 | case hwmon_temp: |
601 | return ltc2947_read_temp(dev, attr, val, channel); |
602 | default: |
603 | return -ENOTSUPP; |
604 | } |
605 | } |
606 | |
607 | static int ltc2947_write_temp(struct device *dev, const u32 attr, |
608 | long val, const int channel) |
609 | { |
610 | struct ltc2947_data *st = dev_get_drvdata(dev); |
611 | |
612 | if (channel < 0 || channel > LTC2947_TEMP_FAN_CHAN) { |
613 | dev_err(st->dev, "Invalid chan%d for temperature" , channel); |
614 | return -EINVAL; |
615 | } |
616 | |
617 | switch (attr) { |
618 | case hwmon_temp_reset_history: |
619 | if (val != 1) |
620 | return -EINVAL; |
621 | return ltc2947_reset_history(st, LTC2947_REG_TEMP_MAX, |
622 | LTC2947_REG_TEMP_MIN); |
623 | case hwmon_temp_max: |
624 | val = clamp_val(val, TEMP_MIN, TEMP_MAX); |
625 | if (channel == LTC2947_TEMP_FAN_CHAN) { |
626 | if (!st->gpio_out) |
627 | return -ENOTSUPP; |
628 | |
629 | return ltc2947_val_write(st, |
630 | LTC2947_REG_TEMP_FAN_THRE_H, |
631 | LTC2947_PAGE1, size: 2, |
632 | DIV_ROUND_CLOSEST(val - 550, 204)); |
633 | } |
634 | |
635 | return ltc2947_val_write(st, LTC2947_REG_TEMP_THRE_H, |
636 | LTC2947_PAGE1, size: 2, |
637 | DIV_ROUND_CLOSEST(val - 550, 204)); |
638 | case hwmon_temp_min: |
639 | val = clamp_val(val, TEMP_MIN, TEMP_MAX); |
640 | if (channel == LTC2947_TEMP_FAN_CHAN) { |
641 | if (!st->gpio_out) |
642 | return -ENOTSUPP; |
643 | |
644 | return ltc2947_val_write(st, |
645 | LTC2947_REG_TEMP_FAN_THRE_L, |
646 | LTC2947_PAGE1, size: 2, |
647 | DIV_ROUND_CLOSEST(val - 550, 204)); |
648 | } |
649 | |
650 | return ltc2947_val_write(st, LTC2947_REG_TEMP_THRE_L, |
651 | LTC2947_PAGE1, size: 2, |
652 | DIV_ROUND_CLOSEST(val - 550, 204)); |
653 | default: |
654 | return -ENOTSUPP; |
655 | } |
656 | } |
657 | |
658 | static int ltc2947_write_power(struct device *dev, const u32 attr, |
659 | long val) |
660 | { |
661 | struct ltc2947_data *st = dev_get_drvdata(dev); |
662 | |
663 | switch (attr) { |
664 | case hwmon_power_reset_history: |
665 | if (val != 1) |
666 | return -EINVAL; |
667 | return ltc2947_reset_history(st, LTC2947_REG_POWER_MAX, |
668 | LTC2947_REG_POWER_MIN); |
669 | case hwmon_power_max: |
670 | val = clamp_val(val, POWER_MIN, POWER_MAX); |
671 | return ltc2947_val_write(st, LTC2947_REG_POWER_THRE_H, |
672 | LTC2947_PAGE1, size: 2, |
673 | DIV_ROUND_CLOSEST(val, 200000)); |
674 | case hwmon_power_min: |
675 | val = clamp_val(val, POWER_MIN, POWER_MAX); |
676 | return ltc2947_val_write(st, LTC2947_REG_POWER_THRE_L, |
677 | LTC2947_PAGE1, size: 2, |
678 | DIV_ROUND_CLOSEST(val, 200000)); |
679 | default: |
680 | return -ENOTSUPP; |
681 | } |
682 | } |
683 | |
684 | static int ltc2947_write_curr(struct device *dev, const u32 attr, |
685 | long val) |
686 | { |
687 | struct ltc2947_data *st = dev_get_drvdata(dev); |
688 | |
689 | switch (attr) { |
690 | case hwmon_curr_reset_history: |
691 | if (val != 1) |
692 | return -EINVAL; |
693 | return ltc2947_reset_history(st, LTC2947_REG_CURRENT_MAX, |
694 | LTC2947_REG_CURRENT_MIN); |
695 | case hwmon_curr_max: |
696 | val = clamp_val(val, CURRENT_MIN, CURRENT_MAX); |
697 | return ltc2947_val_write(st, LTC2947_REG_CURRENT_THRE_H, |
698 | LTC2947_PAGE1, size: 2, |
699 | DIV_ROUND_CLOSEST(val, 12)); |
700 | case hwmon_curr_min: |
701 | val = clamp_val(val, CURRENT_MIN, CURRENT_MAX); |
702 | return ltc2947_val_write(st, LTC2947_REG_CURRENT_THRE_L, |
703 | LTC2947_PAGE1, size: 2, |
704 | DIV_ROUND_CLOSEST(val, 12)); |
705 | default: |
706 | return -ENOTSUPP; |
707 | } |
708 | } |
709 | |
710 | static int ltc2947_write_in(struct device *dev, const u32 attr, long val, |
711 | const int channel) |
712 | { |
713 | struct ltc2947_data *st = dev_get_drvdata(dev); |
714 | |
715 | if (channel > LTC2947_VOLTAGE_DVCC_CHAN) { |
716 | dev_err(st->dev, "Invalid chan%d for voltage" , channel); |
717 | return -EINVAL; |
718 | } |
719 | |
720 | switch (attr) { |
721 | case hwmon_in_reset_history: |
722 | if (val != 1) |
723 | return -EINVAL; |
724 | |
725 | if (channel == LTC2947_VOLTAGE_DVCC_CHAN) |
726 | return ltc2947_reset_history(st, LTC2947_REG_DVCC_MAX, |
727 | LTC2947_REG_DVCC_MIN); |
728 | |
729 | return ltc2947_reset_history(st, LTC2947_REG_VOLTAGE_MAX, |
730 | LTC2947_REG_VOLTAGE_MIN); |
731 | case hwmon_in_max: |
732 | if (channel == LTC2947_VOLTAGE_DVCC_CHAN) { |
733 | val = clamp_val(val, VDVCC_MIN, VDVCC_MAX); |
734 | return ltc2947_val_write(st, LTC2947_REG_DVCC_THRE_H, |
735 | LTC2947_PAGE1, size: 2, |
736 | DIV_ROUND_CLOSEST(val, 145)); |
737 | } |
738 | |
739 | val = clamp_val(val, VOLTAGE_MIN, VOLTAGE_MAX); |
740 | return ltc2947_val_write(st, LTC2947_REG_VOLTAGE_THRE_H, |
741 | LTC2947_PAGE1, size: 2, |
742 | DIV_ROUND_CLOSEST(val, 2)); |
743 | case hwmon_in_min: |
744 | if (channel == LTC2947_VOLTAGE_DVCC_CHAN) { |
745 | val = clamp_val(val, VDVCC_MIN, VDVCC_MAX); |
746 | return ltc2947_val_write(st, LTC2947_REG_DVCC_THRE_L, |
747 | LTC2947_PAGE1, size: 2, |
748 | DIV_ROUND_CLOSEST(val, 145)); |
749 | } |
750 | |
751 | val = clamp_val(val, VOLTAGE_MIN, VOLTAGE_MAX); |
752 | return ltc2947_val_write(st, LTC2947_REG_VOLTAGE_THRE_L, |
753 | LTC2947_PAGE1, size: 2, |
754 | DIV_ROUND_CLOSEST(val, 2)); |
755 | default: |
756 | return -ENOTSUPP; |
757 | } |
758 | } |
759 | |
760 | static int ltc2947_write(struct device *dev, |
761 | enum hwmon_sensor_types type, |
762 | u32 attr, int channel, long val) |
763 | { |
764 | switch (type) { |
765 | case hwmon_in: |
766 | return ltc2947_write_in(dev, attr, val, channel); |
767 | case hwmon_curr: |
768 | return ltc2947_write_curr(dev, attr, val); |
769 | case hwmon_power: |
770 | return ltc2947_write_power(dev, attr, val); |
771 | case hwmon_temp: |
772 | return ltc2947_write_temp(dev, attr, val, channel); |
773 | default: |
774 | return -ENOTSUPP; |
775 | } |
776 | } |
777 | |
778 | static int ltc2947_read_labels(struct device *dev, |
779 | enum hwmon_sensor_types type, |
780 | u32 attr, int channel, const char **str) |
781 | { |
782 | switch (type) { |
783 | case hwmon_in: |
784 | if (channel == LTC2947_VOLTAGE_DVCC_CHAN) |
785 | *str = "DVCC" ; |
786 | else |
787 | *str = "VP-VM" ; |
788 | return 0; |
789 | case hwmon_curr: |
790 | *str = "IP-IM" ; |
791 | return 0; |
792 | case hwmon_temp: |
793 | if (channel == LTC2947_TEMP_FAN_CHAN) |
794 | *str = "TEMPFAN" ; |
795 | else |
796 | *str = "Ambient" ; |
797 | return 0; |
798 | case hwmon_power: |
799 | *str = "Power" ; |
800 | return 0; |
801 | default: |
802 | return -ENOTSUPP; |
803 | } |
804 | } |
805 | |
806 | static int ltc2947_in_is_visible(const u32 attr) |
807 | { |
808 | switch (attr) { |
809 | case hwmon_in_input: |
810 | case hwmon_in_highest: |
811 | case hwmon_in_lowest: |
812 | case hwmon_in_max_alarm: |
813 | case hwmon_in_min_alarm: |
814 | case hwmon_in_label: |
815 | return 0444; |
816 | case hwmon_in_reset_history: |
817 | return 0200; |
818 | case hwmon_in_max: |
819 | case hwmon_in_min: |
820 | return 0644; |
821 | default: |
822 | return 0; |
823 | } |
824 | } |
825 | |
826 | static int ltc2947_curr_is_visible(const u32 attr) |
827 | { |
828 | switch (attr) { |
829 | case hwmon_curr_input: |
830 | case hwmon_curr_highest: |
831 | case hwmon_curr_lowest: |
832 | case hwmon_curr_max_alarm: |
833 | case hwmon_curr_min_alarm: |
834 | case hwmon_curr_label: |
835 | return 0444; |
836 | case hwmon_curr_reset_history: |
837 | return 0200; |
838 | case hwmon_curr_max: |
839 | case hwmon_curr_min: |
840 | return 0644; |
841 | default: |
842 | return 0; |
843 | } |
844 | } |
845 | |
846 | static int ltc2947_power_is_visible(const u32 attr) |
847 | { |
848 | switch (attr) { |
849 | case hwmon_power_input: |
850 | case hwmon_power_input_highest: |
851 | case hwmon_power_input_lowest: |
852 | case hwmon_power_label: |
853 | case hwmon_power_max_alarm: |
854 | case hwmon_power_min_alarm: |
855 | return 0444; |
856 | case hwmon_power_reset_history: |
857 | return 0200; |
858 | case hwmon_power_max: |
859 | case hwmon_power_min: |
860 | return 0644; |
861 | default: |
862 | return 0; |
863 | } |
864 | } |
865 | |
866 | static int ltc2947_temp_is_visible(const u32 attr) |
867 | { |
868 | switch (attr) { |
869 | case hwmon_temp_input: |
870 | case hwmon_temp_highest: |
871 | case hwmon_temp_lowest: |
872 | case hwmon_temp_max_alarm: |
873 | case hwmon_temp_min_alarm: |
874 | case hwmon_temp_label: |
875 | return 0444; |
876 | case hwmon_temp_reset_history: |
877 | return 0200; |
878 | case hwmon_temp_max: |
879 | case hwmon_temp_min: |
880 | return 0644; |
881 | default: |
882 | return 0; |
883 | } |
884 | } |
885 | |
886 | static umode_t ltc2947_is_visible(const void *data, |
887 | enum hwmon_sensor_types type, |
888 | u32 attr, int channel) |
889 | { |
890 | switch (type) { |
891 | case hwmon_in: |
892 | return ltc2947_in_is_visible(attr); |
893 | case hwmon_curr: |
894 | return ltc2947_curr_is_visible(attr); |
895 | case hwmon_power: |
896 | return ltc2947_power_is_visible(attr); |
897 | case hwmon_temp: |
898 | return ltc2947_temp_is_visible(attr); |
899 | default: |
900 | return 0; |
901 | } |
902 | } |
903 | |
904 | static const struct hwmon_channel_info * const ltc2947_info[] = { |
905 | HWMON_CHANNEL_INFO(in, |
906 | HWMON_I_INPUT | HWMON_I_LOWEST | HWMON_I_HIGHEST | |
907 | HWMON_I_MAX | HWMON_I_MIN | HWMON_I_RESET_HISTORY | |
908 | HWMON_I_MIN_ALARM | HWMON_I_MAX_ALARM | |
909 | HWMON_I_LABEL, |
910 | HWMON_I_INPUT | HWMON_I_LOWEST | HWMON_I_HIGHEST | |
911 | HWMON_I_MAX | HWMON_I_MIN | HWMON_I_RESET_HISTORY | |
912 | HWMON_I_MIN_ALARM | HWMON_I_MAX_ALARM | |
913 | HWMON_I_LABEL), |
914 | HWMON_CHANNEL_INFO(curr, |
915 | HWMON_C_INPUT | HWMON_C_LOWEST | HWMON_C_HIGHEST | |
916 | HWMON_C_MAX | HWMON_C_MIN | HWMON_C_RESET_HISTORY | |
917 | HWMON_C_MIN_ALARM | HWMON_C_MAX_ALARM | |
918 | HWMON_C_LABEL), |
919 | HWMON_CHANNEL_INFO(power, |
920 | HWMON_P_INPUT | HWMON_P_INPUT_LOWEST | |
921 | HWMON_P_INPUT_HIGHEST | HWMON_P_MAX | HWMON_P_MIN | |
922 | HWMON_P_RESET_HISTORY | HWMON_P_MAX_ALARM | |
923 | HWMON_P_MIN_ALARM | HWMON_P_LABEL), |
924 | HWMON_CHANNEL_INFO(temp, |
925 | HWMON_T_INPUT | HWMON_T_LOWEST | HWMON_T_HIGHEST | |
926 | HWMON_T_MAX | HWMON_T_MIN | HWMON_T_RESET_HISTORY | |
927 | HWMON_T_MIN_ALARM | HWMON_T_MAX_ALARM | |
928 | HWMON_T_LABEL, |
929 | HWMON_T_MAX_ALARM | HWMON_T_MIN_ALARM | HWMON_T_MAX | |
930 | HWMON_T_MIN | HWMON_T_LABEL), |
931 | NULL |
932 | }; |
933 | |
934 | static const struct hwmon_ops ltc2947_hwmon_ops = { |
935 | .is_visible = ltc2947_is_visible, |
936 | .read = ltc2947_read, |
937 | .write = ltc2947_write, |
938 | .read_string = ltc2947_read_labels, |
939 | }; |
940 | |
941 | static const struct hwmon_chip_info ltc2947_chip_info = { |
942 | .ops = <c2947_hwmon_ops, |
943 | .info = ltc2947_info, |
944 | }; |
945 | |
946 | /* energy attributes are 6bytes wide so we need u64 */ |
947 | static SENSOR_DEVICE_ATTR(energy1_input, 0444, ltc2947_show_value, NULL, |
948 | LTC2947_REG_ENERGY1); |
949 | static SENSOR_DEVICE_ATTR(energy2_input, 0444, ltc2947_show_value, NULL, |
950 | LTC2947_REG_ENERGY2); |
951 | |
952 | static struct attribute *ltc2947_attrs[] = { |
953 | &sensor_dev_attr_energy1_input.dev_attr.attr, |
954 | &sensor_dev_attr_energy2_input.dev_attr.attr, |
955 | NULL, |
956 | }; |
957 | ATTRIBUTE_GROUPS(ltc2947); |
958 | |
959 | static int ltc2947_setup(struct ltc2947_data *st) |
960 | { |
961 | int ret; |
962 | struct clk *extclk; |
963 | u32 dummy, deadband, pol; |
964 | u32 accum[2]; |
965 | |
966 | /* clear status register by reading it */ |
967 | ret = regmap_read(map: st->map, LTC2947_REG_STATUS, val: &dummy); |
968 | if (ret) |
969 | return ret; |
970 | /* |
971 | * Set max/min for power here since the default values x scale |
972 | * would overflow on 32bit arch |
973 | */ |
974 | ret = ltc2947_val_write(st, LTC2947_REG_POWER_THRE_H, LTC2947_PAGE1, size: 2, |
975 | POWER_MAX / 200000); |
976 | if (ret) |
977 | return ret; |
978 | |
979 | ret = ltc2947_val_write(st, LTC2947_REG_POWER_THRE_L, LTC2947_PAGE1, size: 2, |
980 | POWER_MIN / 200000); |
981 | if (ret) |
982 | return ret; |
983 | |
984 | /* check external clock presence */ |
985 | extclk = devm_clk_get_optional_enabled(dev: st->dev, NULL); |
986 | if (IS_ERR(ptr: extclk)) |
987 | return dev_err_probe(dev: st->dev, err: PTR_ERR(ptr: extclk), |
988 | fmt: "Failed to get external clock\n" ); |
989 | |
990 | if (extclk) { |
991 | unsigned long rate_hz; |
992 | u8 pre = 0, div, tbctl; |
993 | u64 aux; |
994 | |
995 | /* let's calculate and set the right valus in TBCTL */ |
996 | rate_hz = clk_get_rate(clk: extclk); |
997 | if (rate_hz < LTC2947_CLK_MIN || rate_hz > LTC2947_CLK_MAX) { |
998 | dev_err(st->dev, "Invalid rate:%lu for external clock" , |
999 | rate_hz); |
1000 | return -EINVAL; |
1001 | } |
1002 | |
1003 | /* as in table 1 of the datasheet */ |
1004 | if (rate_hz >= LTC2947_CLK_MIN && rate_hz <= 1000000) |
1005 | pre = 0; |
1006 | else if (rate_hz > 1000000 && rate_hz <= 2000000) |
1007 | pre = 1; |
1008 | else if (rate_hz > 2000000 && rate_hz <= 4000000) |
1009 | pre = 2; |
1010 | else if (rate_hz > 4000000 && rate_hz <= 8000000) |
1011 | pre = 3; |
1012 | else if (rate_hz > 8000000 && rate_hz <= 16000000) |
1013 | pre = 4; |
1014 | else if (rate_hz > 16000000 && rate_hz <= LTC2947_CLK_MAX) |
1015 | pre = 5; |
1016 | /* |
1017 | * Div is given by: |
1018 | * floor(fref / (2^PRE * 32768)) |
1019 | */ |
1020 | div = rate_hz / ((1 << pre) * 32768); |
1021 | tbctl = LTC2947_PRE(pre) | LTC2947_DIV(div); |
1022 | |
1023 | ret = regmap_write(map: st->map, LTC2947_REG_TBCTL, val: tbctl); |
1024 | if (ret) |
1025 | return ret; |
1026 | /* |
1027 | * The energy lsb is given by (in W*s): |
1028 | * 06416 * (1/fref) * 2^PRE * (DIV + 1) |
1029 | * The value is multiplied by 10E9 |
1030 | */ |
1031 | aux = (div + 1) * ((1 << pre) * 641600000ULL); |
1032 | st->lsb_energy = DIV_ROUND_CLOSEST_ULL(aux, rate_hz); |
1033 | } else { |
1034 | /* 19.89E-6 * 10E9 */ |
1035 | st->lsb_energy = 19890; |
1036 | } |
1037 | ret = of_property_read_u32_array(np: st->dev->of_node, |
1038 | propname: "adi,accumulator-ctl-pol" , out_values: accum, |
1039 | ARRAY_SIZE(accum)); |
1040 | if (!ret) { |
1041 | u32 accum_reg = LTC2947_ACCUM_POL_1(accum[0]) | |
1042 | LTC2947_ACCUM_POL_2(accum[1]); |
1043 | |
1044 | ret = regmap_write(map: st->map, LTC2947_REG_ACCUM_POL, val: accum_reg); |
1045 | if (ret) |
1046 | return ret; |
1047 | } |
1048 | ret = of_property_read_u32(np: st->dev->of_node, |
1049 | propname: "adi,accumulation-deadband-microamp" , |
1050 | out_value: &deadband); |
1051 | if (!ret) { |
1052 | /* the LSB is the same as the current, so 3mA */ |
1053 | ret = regmap_write(map: st->map, LTC2947_REG_ACCUM_DEADBAND, |
1054 | val: deadband / (1000 * 3)); |
1055 | if (ret) |
1056 | return ret; |
1057 | } |
1058 | /* check gpio cfg */ |
1059 | ret = of_property_read_u32(np: st->dev->of_node, propname: "adi,gpio-out-pol" , out_value: &pol); |
1060 | if (!ret) { |
1061 | /* setup GPIO as output */ |
1062 | u32 gpio_ctl = LTC2947_GPIO_EN(1) | LTC2947_GPIO_FAN_EN(1) | |
1063 | LTC2947_GPIO_FAN_POL(pol); |
1064 | |
1065 | st->gpio_out = true; |
1066 | ret = regmap_write(map: st->map, LTC2947_REG_GPIOSTATCTL, val: gpio_ctl); |
1067 | if (ret) |
1068 | return ret; |
1069 | } |
1070 | ret = of_property_read_u32_array(np: st->dev->of_node, propname: "adi,gpio-in-accum" , |
1071 | out_values: accum, ARRAY_SIZE(accum)); |
1072 | if (!ret) { |
1073 | /* |
1074 | * Setup the accum options. The gpioctl is already defined as |
1075 | * input by default. |
1076 | */ |
1077 | u32 accum_val = LTC2947_ACCUM_POL_1(accum[0]) | |
1078 | LTC2947_ACCUM_POL_2(accum[1]); |
1079 | |
1080 | if (st->gpio_out) { |
1081 | dev_err(st->dev, |
1082 | "Cannot have input gpio config if already configured as output" ); |
1083 | return -EINVAL; |
1084 | } |
1085 | |
1086 | ret = regmap_write(map: st->map, LTC2947_REG_GPIO_ACCUM, val: accum_val); |
1087 | if (ret) |
1088 | return ret; |
1089 | } |
1090 | |
1091 | /* set continuos mode */ |
1092 | return regmap_update_bits(map: st->map, LTC2947_REG_CTRL, |
1093 | LTC2947_CONT_MODE_MASK, LTC2947_CONT_MODE(1)); |
1094 | } |
1095 | |
1096 | int ltc2947_core_probe(struct regmap *map, const char *name) |
1097 | { |
1098 | struct ltc2947_data *st; |
1099 | struct device *dev = regmap_get_device(map); |
1100 | struct device *hwmon; |
1101 | int ret; |
1102 | |
1103 | st = devm_kzalloc(dev, size: sizeof(*st), GFP_KERNEL); |
1104 | if (!st) |
1105 | return -ENOMEM; |
1106 | |
1107 | st->map = map; |
1108 | st->dev = dev; |
1109 | dev_set_drvdata(dev, data: st); |
1110 | mutex_init(&st->lock); |
1111 | |
1112 | ret = ltc2947_setup(st); |
1113 | if (ret) |
1114 | return ret; |
1115 | |
1116 | hwmon = devm_hwmon_device_register_with_info(dev, name, drvdata: st, |
1117 | info: <c2947_chip_info, |
1118 | extra_groups: ltc2947_groups); |
1119 | return PTR_ERR_OR_ZERO(ptr: hwmon); |
1120 | } |
1121 | EXPORT_SYMBOL_GPL(ltc2947_core_probe); |
1122 | |
1123 | static int ltc2947_resume(struct device *dev) |
1124 | { |
1125 | struct ltc2947_data *st = dev_get_drvdata(dev); |
1126 | u32 ctrl = 0; |
1127 | int ret; |
1128 | |
1129 | /* dummy read to wake the device */ |
1130 | ret = regmap_read(map: st->map, LTC2947_REG_CTRL, val: &ctrl); |
1131 | if (ret) |
1132 | return ret; |
1133 | /* |
1134 | * Wait for the device. It takes 100ms to wake up so, 10ms extra |
1135 | * should be enough. |
1136 | */ |
1137 | msleep(msecs: 110); |
1138 | ret = regmap_read(map: st->map, LTC2947_REG_CTRL, val: &ctrl); |
1139 | if (ret) |
1140 | return ret; |
1141 | /* ctrl should be 0 */ |
1142 | if (ctrl != 0) { |
1143 | dev_err(st->dev, "Device failed to wake up, ctl:%02X\n" , ctrl); |
1144 | return -ETIMEDOUT; |
1145 | } |
1146 | |
1147 | /* set continuous mode */ |
1148 | return regmap_update_bits(map: st->map, LTC2947_REG_CTRL, |
1149 | LTC2947_CONT_MODE_MASK, LTC2947_CONT_MODE(1)); |
1150 | } |
1151 | |
1152 | static int ltc2947_suspend(struct device *dev) |
1153 | { |
1154 | struct ltc2947_data *st = dev_get_drvdata(dev); |
1155 | |
1156 | return regmap_update_bits(map: st->map, LTC2947_REG_CTRL, |
1157 | LTC2947_SHUTDOWN_MASK, val: 1); |
1158 | } |
1159 | |
1160 | EXPORT_SIMPLE_DEV_PM_OPS(ltc2947_pm_ops, ltc2947_suspend, ltc2947_resume); |
1161 | |
1162 | const struct of_device_id ltc2947_of_match[] = { |
1163 | { .compatible = "adi,ltc2947" }, |
1164 | {} |
1165 | }; |
1166 | EXPORT_SYMBOL_GPL(ltc2947_of_match); |
1167 | MODULE_DEVICE_TABLE(of, ltc2947_of_match); |
1168 | |
1169 | MODULE_AUTHOR("Nuno Sa <nuno.sa@analog.com>" ); |
1170 | MODULE_DESCRIPTION("LTC2947 power and energy monitor core driver" ); |
1171 | MODULE_LICENSE("GPL" ); |
1172 | |