1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * max31827.c - Support for Maxim Low-Power Switch |
4 | * |
5 | * Copyright (c) 2023 Daniel Matyas <daniel.matyas@analog.com> |
6 | */ |
7 | |
8 | #include <linux/bitfield.h> |
9 | #include <linux/bitops.h> |
10 | #include <linux/delay.h> |
11 | #include <linux/hwmon.h> |
12 | #include <linux/i2c.h> |
13 | #include <linux/mutex.h> |
14 | #include <linux/of_device.h> |
15 | #include <linux/regmap.h> |
16 | #include <linux/regulator/consumer.h> |
17 | |
18 | #define MAX31827_T_REG 0x0 |
19 | #define MAX31827_CONFIGURATION_REG 0x2 |
20 | #define MAX31827_TH_REG 0x4 |
21 | #define MAX31827_TL_REG 0x6 |
22 | #define MAX31827_TH_HYST_REG 0x8 |
23 | #define MAX31827_TL_HYST_REG 0xA |
24 | |
25 | #define MAX31827_CONFIGURATION_1SHOT_MASK BIT(0) |
26 | #define MAX31827_CONFIGURATION_CNV_RATE_MASK GENMASK(3, 1) |
27 | #define MAX31827_CONFIGURATION_TIMEOUT_MASK BIT(5) |
28 | #define MAX31827_CONFIGURATION_RESOLUTION_MASK GENMASK(7, 6) |
29 | #define MAX31827_CONFIGURATION_ALRM_POL_MASK BIT(8) |
30 | #define MAX31827_CONFIGURATION_COMP_INT_MASK BIT(9) |
31 | #define MAX31827_CONFIGURATION_FLT_Q_MASK GENMASK(11, 10) |
32 | #define MAX31827_CONFIGURATION_U_TEMP_STAT_MASK BIT(14) |
33 | #define MAX31827_CONFIGURATION_O_TEMP_STAT_MASK BIT(15) |
34 | |
35 | #define MAX31827_ALRM_POL_LOW 0x0 |
36 | #define MAX31827_ALRM_POL_HIGH 0x1 |
37 | #define MAX31827_FLT_Q_1 0x0 |
38 | #define MAX31827_FLT_Q_4 0x2 |
39 | |
40 | #define MAX31827_8_BIT_CNV_TIME 9 |
41 | #define MAX31827_9_BIT_CNV_TIME 18 |
42 | #define MAX31827_10_BIT_CNV_TIME 35 |
43 | #define MAX31827_12_BIT_CNV_TIME 140 |
44 | |
45 | #define MAX31827_16_BIT_TO_M_DGR(x) (sign_extend32(x, 15) * 1000 / 16) |
46 | #define MAX31827_M_DGR_TO_16_BIT(x) (((x) << 4) / 1000) |
47 | #define MAX31827_DEVICE_ENABLE(x) ((x) ? 0xA : 0x0) |
48 | |
49 | enum chips { max31827 = 1, max31828, max31829 }; |
50 | |
51 | enum max31827_cnv { |
52 | MAX31827_CNV_1_DIV_64_HZ = 1, |
53 | MAX31827_CNV_1_DIV_32_HZ, |
54 | MAX31827_CNV_1_DIV_16_HZ, |
55 | MAX31827_CNV_1_DIV_4_HZ, |
56 | MAX31827_CNV_1_HZ, |
57 | MAX31827_CNV_4_HZ, |
58 | MAX31827_CNV_8_HZ, |
59 | }; |
60 | |
61 | static const u16 max31827_conversions[] = { |
62 | [MAX31827_CNV_1_DIV_64_HZ] = 64000, |
63 | [MAX31827_CNV_1_DIV_32_HZ] = 32000, |
64 | [MAX31827_CNV_1_DIV_16_HZ] = 16000, |
65 | [MAX31827_CNV_1_DIV_4_HZ] = 4000, |
66 | [MAX31827_CNV_1_HZ] = 1000, |
67 | [MAX31827_CNV_4_HZ] = 250, |
68 | [MAX31827_CNV_8_HZ] = 125, |
69 | }; |
70 | |
71 | enum max31827_resolution { |
72 | MAX31827_RES_8_BIT = 0, |
73 | MAX31827_RES_9_BIT, |
74 | MAX31827_RES_10_BIT, |
75 | MAX31827_RES_12_BIT, |
76 | }; |
77 | |
78 | static const u16 max31827_resolutions[] = { |
79 | [MAX31827_RES_8_BIT] = 1000, |
80 | [MAX31827_RES_9_BIT] = 500, |
81 | [MAX31827_RES_10_BIT] = 250, |
82 | [MAX31827_RES_12_BIT] = 62, |
83 | }; |
84 | |
85 | static const u16 max31827_conv_times[] = { |
86 | [MAX31827_RES_8_BIT] = MAX31827_8_BIT_CNV_TIME, |
87 | [MAX31827_RES_9_BIT] = MAX31827_9_BIT_CNV_TIME, |
88 | [MAX31827_RES_10_BIT] = MAX31827_10_BIT_CNV_TIME, |
89 | [MAX31827_RES_12_BIT] = MAX31827_12_BIT_CNV_TIME, |
90 | }; |
91 | |
92 | struct max31827_state { |
93 | /* |
94 | * Prevent simultaneous access to the i2c client. |
95 | */ |
96 | struct mutex lock; |
97 | struct regmap *regmap; |
98 | bool enable; |
99 | unsigned int resolution; |
100 | unsigned int update_interval; |
101 | }; |
102 | |
103 | static const struct regmap_config max31827_regmap = { |
104 | .reg_bits = 8, |
105 | .val_bits = 16, |
106 | .max_register = 0xA, |
107 | }; |
108 | |
109 | static int shutdown_write(struct max31827_state *st, unsigned int reg, |
110 | unsigned int mask, unsigned int val) |
111 | { |
112 | unsigned int cfg; |
113 | unsigned int cnv_rate; |
114 | int ret; |
115 | |
116 | /* |
117 | * Before the Temperature Threshold Alarm, Alarm Hysteresis Threshold |
118 | * and Resolution bits from Configuration register are changed over I2C, |
119 | * the part must be in shutdown mode. |
120 | * |
121 | * Mutex is used to ensure, that some other process doesn't change the |
122 | * configuration register. |
123 | */ |
124 | mutex_lock(&st->lock); |
125 | |
126 | if (!st->enable) { |
127 | if (!mask) |
128 | ret = regmap_write(map: st->regmap, reg, val); |
129 | else |
130 | ret = regmap_update_bits(map: st->regmap, reg, mask, val); |
131 | goto unlock; |
132 | } |
133 | |
134 | ret = regmap_read(map: st->regmap, MAX31827_CONFIGURATION_REG, val: &cfg); |
135 | if (ret) |
136 | goto unlock; |
137 | |
138 | cnv_rate = MAX31827_CONFIGURATION_CNV_RATE_MASK & cfg; |
139 | cfg = cfg & ~(MAX31827_CONFIGURATION_1SHOT_MASK | |
140 | MAX31827_CONFIGURATION_CNV_RATE_MASK); |
141 | ret = regmap_write(map: st->regmap, MAX31827_CONFIGURATION_REG, val: cfg); |
142 | if (ret) |
143 | goto unlock; |
144 | |
145 | if (!mask) |
146 | ret = regmap_write(map: st->regmap, reg, val); |
147 | else |
148 | ret = regmap_update_bits(map: st->regmap, reg, mask, val); |
149 | |
150 | if (ret) |
151 | goto unlock; |
152 | |
153 | ret = regmap_update_bits(map: st->regmap, MAX31827_CONFIGURATION_REG, |
154 | MAX31827_CONFIGURATION_CNV_RATE_MASK, |
155 | val: cnv_rate); |
156 | |
157 | unlock: |
158 | mutex_unlock(lock: &st->lock); |
159 | return ret; |
160 | } |
161 | |
162 | static int write_alarm_val(struct max31827_state *st, unsigned int reg, |
163 | long val) |
164 | { |
165 | val = MAX31827_M_DGR_TO_16_BIT(val); |
166 | |
167 | return shutdown_write(st, reg, mask: 0, val); |
168 | } |
169 | |
170 | static umode_t max31827_is_visible(const void *state, |
171 | enum hwmon_sensor_types type, u32 attr, |
172 | int channel) |
173 | { |
174 | if (type == hwmon_temp) { |
175 | switch (attr) { |
176 | case hwmon_temp_enable: |
177 | case hwmon_temp_max: |
178 | case hwmon_temp_min: |
179 | case hwmon_temp_max_hyst: |
180 | case hwmon_temp_min_hyst: |
181 | return 0644; |
182 | case hwmon_temp_input: |
183 | case hwmon_temp_min_alarm: |
184 | case hwmon_temp_max_alarm: |
185 | return 0444; |
186 | default: |
187 | return 0; |
188 | } |
189 | } else if (type == hwmon_chip) { |
190 | if (attr == hwmon_chip_update_interval) |
191 | return 0644; |
192 | } |
193 | |
194 | return 0; |
195 | } |
196 | |
197 | static int max31827_read(struct device *dev, enum hwmon_sensor_types type, |
198 | u32 attr, int channel, long *val) |
199 | { |
200 | struct max31827_state *st = dev_get_drvdata(dev); |
201 | unsigned int uval; |
202 | int ret = 0; |
203 | |
204 | switch (type) { |
205 | case hwmon_temp: |
206 | switch (attr) { |
207 | case hwmon_temp_enable: |
208 | ret = regmap_read(map: st->regmap, |
209 | MAX31827_CONFIGURATION_REG, val: &uval); |
210 | if (ret) |
211 | break; |
212 | |
213 | uval = FIELD_GET(MAX31827_CONFIGURATION_1SHOT_MASK | |
214 | MAX31827_CONFIGURATION_CNV_RATE_MASK, |
215 | uval); |
216 | *val = !!uval; |
217 | |
218 | break; |
219 | case hwmon_temp_input: |
220 | mutex_lock(&st->lock); |
221 | |
222 | if (!st->enable) { |
223 | /* |
224 | * This operation requires mutex protection, |
225 | * because the chip configuration should not |
226 | * be changed during the conversion process. |
227 | */ |
228 | |
229 | ret = regmap_update_bits(map: st->regmap, |
230 | MAX31827_CONFIGURATION_REG, |
231 | MAX31827_CONFIGURATION_1SHOT_MASK, |
232 | val: 1); |
233 | if (ret) { |
234 | mutex_unlock(lock: &st->lock); |
235 | return ret; |
236 | } |
237 | msleep(msecs: max31827_conv_times[st->resolution]); |
238 | } |
239 | |
240 | /* |
241 | * For 12-bit resolution the conversion time is 140 ms, |
242 | * thus an additional 15 ms is needed to complete the |
243 | * conversion: 125 ms + 15 ms = 140 ms |
244 | */ |
245 | if (max31827_resolutions[st->resolution] == 12 && |
246 | st->update_interval == 125) |
247 | usleep_range(min: 15000, max: 20000); |
248 | |
249 | ret = regmap_read(map: st->regmap, MAX31827_T_REG, val: &uval); |
250 | |
251 | mutex_unlock(lock: &st->lock); |
252 | |
253 | if (ret) |
254 | break; |
255 | |
256 | *val = MAX31827_16_BIT_TO_M_DGR(uval); |
257 | |
258 | break; |
259 | case hwmon_temp_max: |
260 | ret = regmap_read(map: st->regmap, MAX31827_TH_REG, val: &uval); |
261 | if (ret) |
262 | break; |
263 | |
264 | *val = MAX31827_16_BIT_TO_M_DGR(uval); |
265 | break; |
266 | case hwmon_temp_max_hyst: |
267 | ret = regmap_read(map: st->regmap, MAX31827_TH_HYST_REG, |
268 | val: &uval); |
269 | if (ret) |
270 | break; |
271 | |
272 | *val = MAX31827_16_BIT_TO_M_DGR(uval); |
273 | break; |
274 | case hwmon_temp_max_alarm: |
275 | ret = regmap_read(map: st->regmap, |
276 | MAX31827_CONFIGURATION_REG, val: &uval); |
277 | if (ret) |
278 | break; |
279 | |
280 | *val = FIELD_GET(MAX31827_CONFIGURATION_O_TEMP_STAT_MASK, |
281 | uval); |
282 | break; |
283 | case hwmon_temp_min: |
284 | ret = regmap_read(map: st->regmap, MAX31827_TL_REG, val: &uval); |
285 | if (ret) |
286 | break; |
287 | |
288 | *val = MAX31827_16_BIT_TO_M_DGR(uval); |
289 | break; |
290 | case hwmon_temp_min_hyst: |
291 | ret = regmap_read(map: st->regmap, MAX31827_TL_HYST_REG, |
292 | val: &uval); |
293 | if (ret) |
294 | break; |
295 | |
296 | *val = MAX31827_16_BIT_TO_M_DGR(uval); |
297 | break; |
298 | case hwmon_temp_min_alarm: |
299 | ret = regmap_read(map: st->regmap, |
300 | MAX31827_CONFIGURATION_REG, val: &uval); |
301 | if (ret) |
302 | break; |
303 | |
304 | *val = FIELD_GET(MAX31827_CONFIGURATION_U_TEMP_STAT_MASK, |
305 | uval); |
306 | break; |
307 | default: |
308 | ret = -EOPNOTSUPP; |
309 | break; |
310 | } |
311 | |
312 | break; |
313 | |
314 | case hwmon_chip: |
315 | if (attr == hwmon_chip_update_interval) { |
316 | ret = regmap_read(map: st->regmap, |
317 | MAX31827_CONFIGURATION_REG, val: &uval); |
318 | if (ret) |
319 | break; |
320 | |
321 | uval = FIELD_GET(MAX31827_CONFIGURATION_CNV_RATE_MASK, |
322 | uval); |
323 | *val = max31827_conversions[uval]; |
324 | } |
325 | break; |
326 | |
327 | default: |
328 | ret = -EOPNOTSUPP; |
329 | break; |
330 | } |
331 | |
332 | return ret; |
333 | } |
334 | |
335 | static int max31827_write(struct device *dev, enum hwmon_sensor_types type, |
336 | u32 attr, int channel, long val) |
337 | { |
338 | struct max31827_state *st = dev_get_drvdata(dev); |
339 | int res = 1; |
340 | int ret; |
341 | |
342 | switch (type) { |
343 | case hwmon_temp: |
344 | switch (attr) { |
345 | case hwmon_temp_enable: |
346 | if (val >> 1) |
347 | return -EINVAL; |
348 | |
349 | mutex_lock(&st->lock); |
350 | /** |
351 | * The chip should not be enabled while a conversion is |
352 | * performed. Neither should the chip be enabled when |
353 | * the alarm values are changed. |
354 | */ |
355 | |
356 | st->enable = val; |
357 | |
358 | ret = regmap_update_bits(map: st->regmap, |
359 | MAX31827_CONFIGURATION_REG, |
360 | MAX31827_CONFIGURATION_1SHOT_MASK | |
361 | MAX31827_CONFIGURATION_CNV_RATE_MASK, |
362 | MAX31827_DEVICE_ENABLE(val)); |
363 | |
364 | mutex_unlock(lock: &st->lock); |
365 | |
366 | return ret; |
367 | |
368 | case hwmon_temp_max: |
369 | return write_alarm_val(st, MAX31827_TH_REG, val); |
370 | |
371 | case hwmon_temp_max_hyst: |
372 | return write_alarm_val(st, MAX31827_TH_HYST_REG, val); |
373 | |
374 | case hwmon_temp_min: |
375 | return write_alarm_val(st, MAX31827_TL_REG, val); |
376 | |
377 | case hwmon_temp_min_hyst: |
378 | return write_alarm_val(st, MAX31827_TL_HYST_REG, val); |
379 | |
380 | default: |
381 | return -EOPNOTSUPP; |
382 | } |
383 | |
384 | case hwmon_chip: |
385 | if (attr == hwmon_chip_update_interval) { |
386 | if (!st->enable) |
387 | return -EINVAL; |
388 | |
389 | /* |
390 | * Convert the desired conversion rate into register |
391 | * bits. res is already initialized with 1. |
392 | * |
393 | * This was inspired by lm73 driver. |
394 | */ |
395 | while (res < ARRAY_SIZE(max31827_conversions) && |
396 | val < max31827_conversions[res]) |
397 | res++; |
398 | |
399 | if (res == ARRAY_SIZE(max31827_conversions)) |
400 | res = ARRAY_SIZE(max31827_conversions) - 1; |
401 | |
402 | res = FIELD_PREP(MAX31827_CONFIGURATION_CNV_RATE_MASK, |
403 | res); |
404 | |
405 | ret = regmap_update_bits(map: st->regmap, |
406 | MAX31827_CONFIGURATION_REG, |
407 | MAX31827_CONFIGURATION_CNV_RATE_MASK, |
408 | val: res); |
409 | if (ret) |
410 | return ret; |
411 | |
412 | st->update_interval = val; |
413 | } |
414 | break; |
415 | |
416 | default: |
417 | return -EOPNOTSUPP; |
418 | } |
419 | |
420 | return 0; |
421 | } |
422 | |
423 | static ssize_t temp1_resolution_show(struct device *dev, |
424 | struct device_attribute *devattr, |
425 | char *buf) |
426 | { |
427 | struct max31827_state *st = dev_get_drvdata(dev); |
428 | unsigned int val; |
429 | int ret; |
430 | |
431 | ret = regmap_read(map: st->regmap, MAX31827_CONFIGURATION_REG, val: &val); |
432 | if (ret) |
433 | return ret; |
434 | |
435 | val = FIELD_GET(MAX31827_CONFIGURATION_RESOLUTION_MASK, val); |
436 | |
437 | return scnprintf(buf, PAGE_SIZE, fmt: "%u\n" , max31827_resolutions[val]); |
438 | } |
439 | |
440 | static ssize_t temp1_resolution_store(struct device *dev, |
441 | struct device_attribute *devattr, |
442 | const char *buf, size_t count) |
443 | { |
444 | struct max31827_state *st = dev_get_drvdata(dev); |
445 | unsigned int idx = 0; |
446 | unsigned int val; |
447 | int ret; |
448 | |
449 | ret = kstrtouint(s: buf, base: 10, res: &val); |
450 | if (ret) |
451 | return ret; |
452 | |
453 | /* |
454 | * Convert the desired resolution into register |
455 | * bits. idx is already initialized with 0. |
456 | * |
457 | * This was inspired by lm73 driver. |
458 | */ |
459 | while (idx < ARRAY_SIZE(max31827_resolutions) && |
460 | val < max31827_resolutions[idx]) |
461 | idx++; |
462 | |
463 | if (idx == ARRAY_SIZE(max31827_resolutions)) |
464 | idx = ARRAY_SIZE(max31827_resolutions) - 1; |
465 | |
466 | st->resolution = idx; |
467 | |
468 | ret = shutdown_write(st, MAX31827_CONFIGURATION_REG, |
469 | MAX31827_CONFIGURATION_RESOLUTION_MASK, |
470 | FIELD_PREP(MAX31827_CONFIGURATION_RESOLUTION_MASK, |
471 | idx)); |
472 | |
473 | return ret ? ret : count; |
474 | } |
475 | |
476 | static DEVICE_ATTR_RW(temp1_resolution); |
477 | |
478 | static struct attribute *max31827_attrs[] = { |
479 | &dev_attr_temp1_resolution.attr, |
480 | NULL |
481 | }; |
482 | ATTRIBUTE_GROUPS(max31827); |
483 | |
484 | static const struct i2c_device_id max31827_i2c_ids[] = { |
485 | { "max31827" , max31827 }, |
486 | { "max31828" , max31828 }, |
487 | { "max31829" , max31829 }, |
488 | { } |
489 | }; |
490 | MODULE_DEVICE_TABLE(i2c, max31827_i2c_ids); |
491 | |
492 | static int max31827_init_client(struct max31827_state *st, |
493 | struct device *dev) |
494 | { |
495 | struct fwnode_handle *fwnode; |
496 | unsigned int res = 0; |
497 | u32 data, lsb_idx; |
498 | enum chips type; |
499 | bool prop; |
500 | int ret; |
501 | |
502 | fwnode = dev_fwnode(dev); |
503 | |
504 | st->enable = true; |
505 | res |= MAX31827_DEVICE_ENABLE(1); |
506 | |
507 | res |= MAX31827_CONFIGURATION_RESOLUTION_MASK; |
508 | |
509 | prop = fwnode_property_read_bool(fwnode, propname: "adi,comp-int" ); |
510 | res |= FIELD_PREP(MAX31827_CONFIGURATION_COMP_INT_MASK, prop); |
511 | |
512 | prop = fwnode_property_read_bool(fwnode, propname: "adi,timeout-enable" ); |
513 | res |= FIELD_PREP(MAX31827_CONFIGURATION_TIMEOUT_MASK, !prop); |
514 | |
515 | type = (enum chips)(uintptr_t)device_get_match_data(dev); |
516 | |
517 | if (fwnode_property_present(fwnode, propname: "adi,alarm-pol" )) { |
518 | ret = fwnode_property_read_u32(fwnode, propname: "adi,alarm-pol" , val: &data); |
519 | if (ret) |
520 | return ret; |
521 | |
522 | res |= FIELD_PREP(MAX31827_CONFIGURATION_ALRM_POL_MASK, !!data); |
523 | } else { |
524 | /* |
525 | * Set default value. |
526 | */ |
527 | switch (type) { |
528 | case max31827: |
529 | case max31828: |
530 | res |= FIELD_PREP(MAX31827_CONFIGURATION_ALRM_POL_MASK, |
531 | MAX31827_ALRM_POL_LOW); |
532 | break; |
533 | case max31829: |
534 | res |= FIELD_PREP(MAX31827_CONFIGURATION_ALRM_POL_MASK, |
535 | MAX31827_ALRM_POL_HIGH); |
536 | break; |
537 | default: |
538 | return -EOPNOTSUPP; |
539 | } |
540 | } |
541 | |
542 | if (fwnode_property_present(fwnode, propname: "adi,fault-q" )) { |
543 | ret = fwnode_property_read_u32(fwnode, propname: "adi,fault-q" , val: &data); |
544 | if (ret) |
545 | return ret; |
546 | |
547 | /* |
548 | * Convert the desired fault queue into register bits. |
549 | */ |
550 | if (data != 0) |
551 | lsb_idx = __ffs(data); |
552 | |
553 | if (hweight32(data) != 1 || lsb_idx > 4) { |
554 | dev_err(dev, "Invalid data in adi,fault-q\n" ); |
555 | return -EINVAL; |
556 | } |
557 | |
558 | res |= FIELD_PREP(MAX31827_CONFIGURATION_FLT_Q_MASK, lsb_idx); |
559 | } else { |
560 | /* |
561 | * Set default value. |
562 | */ |
563 | switch (type) { |
564 | case max31827: |
565 | res |= FIELD_PREP(MAX31827_CONFIGURATION_FLT_Q_MASK, |
566 | MAX31827_FLT_Q_1); |
567 | break; |
568 | case max31828: |
569 | case max31829: |
570 | res |= FIELD_PREP(MAX31827_CONFIGURATION_FLT_Q_MASK, |
571 | MAX31827_FLT_Q_4); |
572 | break; |
573 | default: |
574 | return -EOPNOTSUPP; |
575 | } |
576 | } |
577 | |
578 | return regmap_write(map: st->regmap, MAX31827_CONFIGURATION_REG, val: res); |
579 | } |
580 | |
581 | static const struct hwmon_channel_info *max31827_info[] = { |
582 | HWMON_CHANNEL_INFO(temp, HWMON_T_ENABLE | HWMON_T_INPUT | HWMON_T_MIN | |
583 | HWMON_T_MIN_HYST | HWMON_T_MIN_ALARM | |
584 | HWMON_T_MAX | HWMON_T_MAX_HYST | |
585 | HWMON_T_MAX_ALARM), |
586 | HWMON_CHANNEL_INFO(chip, HWMON_C_UPDATE_INTERVAL), |
587 | NULL, |
588 | }; |
589 | |
590 | static const struct hwmon_ops max31827_hwmon_ops = { |
591 | .is_visible = max31827_is_visible, |
592 | .read = max31827_read, |
593 | .write = max31827_write, |
594 | }; |
595 | |
596 | static const struct hwmon_chip_info max31827_chip_info = { |
597 | .ops = &max31827_hwmon_ops, |
598 | .info = max31827_info, |
599 | }; |
600 | |
601 | static int max31827_probe(struct i2c_client *client) |
602 | { |
603 | struct device *dev = &client->dev; |
604 | struct device *hwmon_dev; |
605 | struct max31827_state *st; |
606 | int err; |
607 | |
608 | if (!i2c_check_functionality(adap: client->adapter, I2C_FUNC_SMBUS_WORD_DATA)) |
609 | return -EOPNOTSUPP; |
610 | |
611 | st = devm_kzalloc(dev, size: sizeof(*st), GFP_KERNEL); |
612 | if (!st) |
613 | return -ENOMEM; |
614 | |
615 | mutex_init(&st->lock); |
616 | |
617 | st->regmap = devm_regmap_init_i2c(client, &max31827_regmap); |
618 | if (IS_ERR(ptr: st->regmap)) |
619 | return dev_err_probe(dev, err: PTR_ERR(ptr: st->regmap), |
620 | fmt: "Failed to allocate regmap.\n" ); |
621 | |
622 | err = devm_regulator_get_enable(dev, id: "vref" ); |
623 | if (err) |
624 | return dev_err_probe(dev, err, fmt: "failed to enable regulator\n" ); |
625 | |
626 | err = max31827_init_client(st, dev); |
627 | if (err) |
628 | return err; |
629 | |
630 | hwmon_dev = devm_hwmon_device_register_with_info(dev, name: client->name, drvdata: st, |
631 | info: &max31827_chip_info, |
632 | extra_groups: max31827_groups); |
633 | |
634 | return PTR_ERR_OR_ZERO(ptr: hwmon_dev); |
635 | } |
636 | |
637 | static const struct of_device_id max31827_of_match[] = { |
638 | { |
639 | .compatible = "adi,max31827" , |
640 | .data = (void *)max31827 |
641 | }, |
642 | { |
643 | .compatible = "adi,max31828" , |
644 | .data = (void *)max31828 |
645 | }, |
646 | { |
647 | .compatible = "adi,max31829" , |
648 | .data = (void *)max31829 |
649 | }, |
650 | { } |
651 | }; |
652 | MODULE_DEVICE_TABLE(of, max31827_of_match); |
653 | |
654 | static struct i2c_driver max31827_driver = { |
655 | .driver = { |
656 | .name = "max31827" , |
657 | .of_match_table = max31827_of_match, |
658 | }, |
659 | .probe = max31827_probe, |
660 | .id_table = max31827_i2c_ids, |
661 | }; |
662 | module_i2c_driver(max31827_driver); |
663 | |
664 | MODULE_AUTHOR("Daniel Matyas <daniel.matyas@analog.com>" ); |
665 | MODULE_DESCRIPTION("Maxim MAX31827 low-power temperature switch driver" ); |
666 | MODULE_LICENSE("GPL" ); |
667 | |