1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | |
3 | #include <linux/bitfield.h> |
4 | #include <linux/bits.h> |
5 | #include <linux/err.h> |
6 | #include <linux/hwmon.h> |
7 | #include <linux/hwmon-sysfs.h> |
8 | #include <linux/i2c.h> |
9 | #include <linux/regmap.h> |
10 | #include <linux/util_macros.h> |
11 | |
12 | #define REG_CR1 0x00 |
13 | #define CR1_HYST BIT(5) |
14 | #define CR1_DRV GENMASK(4, 3) |
15 | #define CR1_TEMP_SRC GENMASK(1, 0) |
16 | #define REG_CR2 0x01 |
17 | #define CR2_STBY BIT(7) |
18 | #define CR2_ALERTS BIT(6) |
19 | #define CR2_DFC BIT(0) |
20 | #define REG_CR3 0x02 |
21 | #define REG_PWMR 0x50 |
22 | #define REG_PWMV 0x51 |
23 | #define REG_STATUS 0x5A |
24 | #define STATUS_ALARM_CRIT(ch) BIT(2 + 2 * (ch)) |
25 | #define STATUS_ALARM_MAX(ch) BIT(3 + 2 * (ch)) |
26 | #define STATUS_RDFA BIT(6) |
27 | |
28 | #define REG_TACH(ch) (0x52 + (ch) * 2) |
29 | #define REG_TEMP_INPUT(ch) (0x56 + (ch) * 2) |
30 | #define REG_TEMP_MAX(ch) (0x06 + (ch) * 2) |
31 | #define REG_TEMP_CRIT(ch) (0x0A + (ch) * 2) |
32 | |
33 | #define TEMP11_FROM_REG(reg) ((reg) / 32 * 125) |
34 | #define TEMP11_TO_REG(val) (DIV_ROUND_CLOSEST(clamp_val((val), -128000, \ |
35 | 127875), 125) * 32) |
36 | |
37 | #define LUT_SIZE 48 |
38 | |
39 | #define REG_LUT(index) (0x20 + (index)) |
40 | |
41 | struct max31760_state { |
42 | struct regmap *regmap; |
43 | |
44 | struct lut_attribute { |
45 | char name[24]; |
46 | struct sensor_device_attribute sda; |
47 | } lut[LUT_SIZE]; |
48 | |
49 | struct attribute *attrs[LUT_SIZE + 2]; |
50 | struct attribute_group group; |
51 | const struct attribute_group *groups[2]; |
52 | }; |
53 | |
54 | static bool max31760_volatile_reg(struct device *dev, unsigned int reg) |
55 | { |
56 | return reg > 0x50; |
57 | } |
58 | |
59 | static const struct regmap_config regmap_config = { |
60 | .reg_bits = 8, |
61 | .val_bits = 8, |
62 | .max_register = 0x5B, |
63 | .cache_type = REGCACHE_MAPLE, |
64 | .volatile_reg = max31760_volatile_reg, |
65 | }; |
66 | |
67 | static const int max31760_pwm_freq[] = {33, 150, 1500, 25000}; |
68 | |
69 | static int tach_to_rpm(u16 tach) |
70 | { |
71 | if (tach == 0) |
72 | tach = 1; |
73 | |
74 | return 60 * 100000 / tach / 2; |
75 | } |
76 | |
77 | static int max31760_read(struct device *dev, enum hwmon_sensor_types type, |
78 | u32 attr, int channel, long *val) |
79 | { |
80 | struct max31760_state *state = dev_get_drvdata(dev); |
81 | unsigned int regval; |
82 | unsigned int reg_temp; |
83 | s16 temp; |
84 | u8 reg[2]; |
85 | int ret; |
86 | |
87 | switch (type) { |
88 | case hwmon_temp: |
89 | switch (attr) { |
90 | case hwmon_temp_fault: |
91 | ret = regmap_read(map: state->regmap, REG_STATUS, val: ®val); |
92 | if (ret) |
93 | return ret; |
94 | |
95 | *val = FIELD_GET(STATUS_RDFA, regval); |
96 | |
97 | return 0; |
98 | case hwmon_temp_max_alarm: |
99 | ret = regmap_read(map: state->regmap, REG_STATUS, val: ®val); |
100 | if (ret) |
101 | return ret; |
102 | |
103 | if (channel) |
104 | *val = FIELD_GET(STATUS_ALARM_MAX(1), regval); |
105 | else |
106 | *val = FIELD_GET(STATUS_ALARM_MAX(0), regval); |
107 | |
108 | return 0; |
109 | case hwmon_temp_crit_alarm: |
110 | ret = regmap_read(map: state->regmap, REG_STATUS, val: ®val); |
111 | if (ret) |
112 | return ret; |
113 | |
114 | if (channel) |
115 | *val = FIELD_GET(STATUS_ALARM_CRIT(1), regval); |
116 | else |
117 | *val = FIELD_GET(STATUS_ALARM_CRIT(0), regval); |
118 | |
119 | return 0; |
120 | case hwmon_temp_input: |
121 | reg_temp = REG_TEMP_INPUT(channel); |
122 | break; |
123 | case hwmon_temp_max: |
124 | reg_temp = REG_TEMP_MAX(channel); |
125 | break; |
126 | case hwmon_temp_crit: |
127 | reg_temp = REG_TEMP_CRIT(channel); |
128 | break; |
129 | default: |
130 | return -EOPNOTSUPP; |
131 | } |
132 | |
133 | ret = regmap_bulk_read(map: state->regmap, reg: reg_temp, val: reg, val_count: 2); |
134 | if (ret) |
135 | return ret; |
136 | |
137 | temp = (reg[0] << 8) | reg[1]; |
138 | |
139 | *val = TEMP11_FROM_REG(temp); |
140 | |
141 | return 0; |
142 | case hwmon_fan: |
143 | switch (attr) { |
144 | case hwmon_fan_input: |
145 | ret = regmap_bulk_read(map: state->regmap, REG_TACH(channel), val: reg, val_count: 2); |
146 | if (ret) |
147 | return ret; |
148 | |
149 | *val = tach_to_rpm(tach: reg[0] * 256 + reg[1]); |
150 | |
151 | return 0; |
152 | case hwmon_fan_fault: |
153 | ret = regmap_read(map: state->regmap, REG_STATUS, val: ®val); |
154 | if (ret) |
155 | return ret; |
156 | |
157 | if (channel) |
158 | *val = FIELD_GET(BIT(1), regval); |
159 | else |
160 | *val = FIELD_GET(BIT(0), regval); |
161 | |
162 | return 0; |
163 | case hwmon_fan_enable: |
164 | ret = regmap_read(map: state->regmap, REG_CR3, val: ®val); |
165 | if (ret) |
166 | return ret; |
167 | |
168 | if (channel) |
169 | *val = FIELD_GET(BIT(1), regval); |
170 | else |
171 | *val = FIELD_GET(BIT(0), regval); |
172 | |
173 | return 0; |
174 | default: |
175 | return -EOPNOTSUPP; |
176 | } |
177 | case hwmon_pwm: |
178 | switch (attr) { |
179 | case hwmon_pwm_input: |
180 | ret = regmap_read(map: state->regmap, REG_PWMV, val: ®val); |
181 | if (ret) |
182 | return ret; |
183 | |
184 | *val = regval; |
185 | |
186 | return 0; |
187 | case hwmon_pwm_freq: |
188 | ret = regmap_read(map: state->regmap, REG_CR1, val: ®val); |
189 | if (ret) |
190 | return ret; |
191 | |
192 | regval = FIELD_GET(CR1_DRV, regval); |
193 | if (regval >= ARRAY_SIZE(max31760_pwm_freq)) |
194 | return -EINVAL; |
195 | |
196 | *val = max31760_pwm_freq[regval]; |
197 | |
198 | return 0; |
199 | case hwmon_pwm_enable: |
200 | ret = regmap_read(map: state->regmap, REG_CR2, val: ®val); |
201 | if (ret) |
202 | return ret; |
203 | |
204 | *val = 2 - FIELD_GET(CR2_DFC, regval); |
205 | |
206 | return 0; |
207 | case hwmon_pwm_auto_channels_temp: |
208 | ret = regmap_read(map: state->regmap, REG_CR1, val: ®val); |
209 | if (ret) |
210 | return ret; |
211 | |
212 | switch (FIELD_GET(CR1_TEMP_SRC, regval)) { |
213 | case 0: |
214 | *val = 2; |
215 | break; |
216 | case 1: |
217 | *val = 1; |
218 | break; |
219 | case 2: |
220 | case 3: |
221 | *val = 3; |
222 | break; |
223 | default: |
224 | return -EINVAL; |
225 | } |
226 | |
227 | return 0; |
228 | default: |
229 | return -EOPNOTSUPP; |
230 | } |
231 | default: |
232 | return -EOPNOTSUPP; |
233 | } |
234 | } |
235 | |
236 | static int max31760_write(struct device *dev, enum hwmon_sensor_types type, |
237 | u32 attr, int channel, long val) |
238 | { |
239 | struct max31760_state *state = dev_get_drvdata(dev); |
240 | unsigned int pwm_index; |
241 | unsigned int reg_temp; |
242 | int temp; |
243 | u8 reg_val[2]; |
244 | |
245 | switch (type) { |
246 | case hwmon_temp: |
247 | switch (attr) { |
248 | case hwmon_temp_max: |
249 | reg_temp = REG_TEMP_MAX(channel); |
250 | break; |
251 | case hwmon_temp_crit: |
252 | reg_temp = REG_TEMP_CRIT(channel); |
253 | break; |
254 | default: |
255 | return -EOPNOTSUPP; |
256 | } |
257 | |
258 | temp = TEMP11_TO_REG(val); |
259 | reg_val[0] = temp >> 8; |
260 | reg_val[1] = temp & 0xFF; |
261 | |
262 | return regmap_bulk_write(map: state->regmap, reg: reg_temp, val: reg_val, val_count: 2); |
263 | case hwmon_fan: |
264 | switch (attr) { |
265 | case hwmon_fan_enable: |
266 | if (val == 0) |
267 | return regmap_clear_bits(map: state->regmap, REG_CR3, BIT(channel)); |
268 | |
269 | if (val == 1) |
270 | return regmap_set_bits(map: state->regmap, REG_CR3, BIT(channel)); |
271 | |
272 | return -EINVAL; |
273 | default: |
274 | return -EOPNOTSUPP; |
275 | } |
276 | case hwmon_pwm: |
277 | switch (attr) { |
278 | case hwmon_pwm_input: |
279 | if (val < 0 || val > 255) |
280 | return -EINVAL; |
281 | |
282 | return regmap_write(map: state->regmap, REG_PWMR, val); |
283 | case hwmon_pwm_enable: |
284 | if (val == 1) |
285 | return regmap_set_bits(map: state->regmap, REG_CR2, CR2_DFC); |
286 | |
287 | if (val == 2) |
288 | return regmap_clear_bits(map: state->regmap, REG_CR2, CR2_DFC); |
289 | |
290 | return -EINVAL; |
291 | case hwmon_pwm_freq: |
292 | pwm_index = find_closest(val, max31760_pwm_freq, |
293 | ARRAY_SIZE(max31760_pwm_freq)); |
294 | |
295 | return regmap_update_bits(map: state->regmap, |
296 | REG_CR1, CR1_DRV, |
297 | FIELD_PREP(CR1_DRV, pwm_index)); |
298 | case hwmon_pwm_auto_channels_temp: |
299 | switch (val) { |
300 | case 1: |
301 | break; |
302 | case 2: |
303 | val = 0; |
304 | break; |
305 | case 3: |
306 | val = 2; |
307 | break; |
308 | default: |
309 | return -EINVAL; |
310 | } |
311 | |
312 | return regmap_update_bits(map: state->regmap, REG_CR1, CR1_TEMP_SRC, val); |
313 | default: |
314 | return -EOPNOTSUPP; |
315 | } |
316 | default: |
317 | return -EOPNOTSUPP; |
318 | } |
319 | } |
320 | |
321 | static const struct hwmon_channel_info * const max31760_info[] = { |
322 | HWMON_CHANNEL_INFO(chip, |
323 | HWMON_C_REGISTER_TZ), |
324 | HWMON_CHANNEL_INFO(fan, |
325 | HWMON_F_INPUT | HWMON_F_FAULT | HWMON_F_ENABLE, |
326 | HWMON_F_INPUT | HWMON_F_FAULT | HWMON_F_ENABLE), |
327 | HWMON_CHANNEL_INFO(temp, |
328 | HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT | HWMON_T_FAULT | |
329 | HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM | HWMON_T_LABEL, |
330 | HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT | |
331 | HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM | HWMON_T_LABEL), |
332 | HWMON_CHANNEL_INFO(pwm, |
333 | HWMON_PWM_ENABLE | HWMON_PWM_FREQ | HWMON_PWM_INPUT | |
334 | HWMON_PWM_AUTO_CHANNELS_TEMP), |
335 | NULL |
336 | }; |
337 | |
338 | static umode_t max31760_is_visible(const void *data, |
339 | enum hwmon_sensor_types type, |
340 | u32 attr, int channel) |
341 | { |
342 | switch (type) { |
343 | case hwmon_temp: |
344 | switch (attr) { |
345 | case hwmon_temp_input: |
346 | case hwmon_temp_max_alarm: |
347 | case hwmon_temp_crit_alarm: |
348 | case hwmon_temp_fault: |
349 | case hwmon_temp_label: |
350 | return 0444; |
351 | case hwmon_temp_max: |
352 | case hwmon_temp_crit: |
353 | return 0644; |
354 | default: |
355 | return 0; |
356 | } |
357 | case hwmon_fan: |
358 | switch (attr) { |
359 | case hwmon_fan_input: |
360 | case hwmon_fan_fault: |
361 | return 0444; |
362 | case hwmon_fan_enable: |
363 | return 0644; |
364 | default: |
365 | return 0; |
366 | } |
367 | case hwmon_pwm: |
368 | switch (attr) { |
369 | case hwmon_pwm_enable: |
370 | case hwmon_pwm_input: |
371 | case hwmon_pwm_freq: |
372 | case hwmon_pwm_auto_channels_temp: |
373 | return 0644; |
374 | default: |
375 | return 0; |
376 | } |
377 | default: |
378 | return 0; |
379 | } |
380 | } |
381 | |
382 | static int max31760_read_string(struct device *dev, |
383 | enum hwmon_sensor_types type, |
384 | u32 attr, int channel, const char **str) |
385 | { |
386 | switch (type) { |
387 | case hwmon_temp: |
388 | if (attr != hwmon_temp_label) |
389 | return -EOPNOTSUPP; |
390 | |
391 | *str = channel ? "local" : "remote" ; |
392 | |
393 | return 0; |
394 | default: |
395 | return -EOPNOTSUPP; |
396 | } |
397 | } |
398 | |
399 | static const struct hwmon_ops max31760_hwmon_ops = { |
400 | .is_visible = max31760_is_visible, |
401 | .read = max31760_read, |
402 | .write = max31760_write, |
403 | .read_string = max31760_read_string |
404 | }; |
405 | |
406 | static const struct hwmon_chip_info max31760_chip_info = { |
407 | .ops = &max31760_hwmon_ops, |
408 | .info = max31760_info, |
409 | }; |
410 | |
411 | static ssize_t lut_show(struct device *dev, |
412 | struct device_attribute *devattr, char *buf) |
413 | { |
414 | struct sensor_device_attribute *sda = to_sensor_dev_attr(devattr); |
415 | struct max31760_state *state = dev_get_drvdata(dev); |
416 | int ret; |
417 | unsigned int regval; |
418 | |
419 | ret = regmap_read(map: state->regmap, REG_LUT(sda->index), val: ®val); |
420 | if (ret) |
421 | return ret; |
422 | |
423 | return sysfs_emit(buf, fmt: "%d\n" , regval); |
424 | } |
425 | |
426 | static ssize_t lut_store(struct device *dev, |
427 | struct device_attribute *devattr, |
428 | const char *buf, size_t count) |
429 | { |
430 | struct sensor_device_attribute *sda = to_sensor_dev_attr(devattr); |
431 | struct max31760_state *state = dev_get_drvdata(dev); |
432 | int ret; |
433 | u8 pwm; |
434 | |
435 | ret = kstrtou8(s: buf, base: 10, res: &pwm); |
436 | if (ret) |
437 | return ret; |
438 | |
439 | ret = regmap_write(map: state->regmap, REG_LUT(sda->index), val: pwm); |
440 | if (ret) |
441 | return ret; |
442 | |
443 | return count; |
444 | } |
445 | |
446 | static ssize_t pwm1_auto_point_temp_hyst_show(struct device *dev, |
447 | struct device_attribute *attr, |
448 | char *buf) |
449 | { |
450 | struct max31760_state *state = dev_get_drvdata(dev); |
451 | unsigned int regval; |
452 | int ret; |
453 | |
454 | ret = regmap_read(map: state->regmap, REG_CR1, val: ®val); |
455 | if (ret) |
456 | return ret; |
457 | |
458 | return sysfs_emit(buf, fmt: "%d\n" , (1 + (int)FIELD_GET(CR1_HYST, regval)) * 2000); |
459 | } |
460 | |
461 | static ssize_t pwm1_auto_point_temp_hyst_store(struct device *dev, |
462 | struct device_attribute *attr, |
463 | const char *buf, |
464 | size_t count) |
465 | { |
466 | struct max31760_state *state = dev_get_drvdata(dev); |
467 | unsigned int hyst; |
468 | int ret; |
469 | |
470 | ret = kstrtou32(s: buf, base: 10, res: &hyst); |
471 | if (ret) |
472 | return ret; |
473 | |
474 | if (hyst < 3000) |
475 | ret = regmap_clear_bits(map: state->regmap, REG_CR1, CR1_HYST); |
476 | else |
477 | ret = regmap_set_bits(map: state->regmap, REG_CR1, CR1_HYST); |
478 | |
479 | if (ret) |
480 | return ret; |
481 | |
482 | return count; |
483 | } |
484 | |
485 | static DEVICE_ATTR_RW(pwm1_auto_point_temp_hyst); |
486 | |
487 | static void max31760_create_lut_nodes(struct max31760_state *state) |
488 | { |
489 | int i; |
490 | struct sensor_device_attribute *sda; |
491 | struct lut_attribute *lut; |
492 | |
493 | for (i = 0; i < LUT_SIZE; ++i) { |
494 | lut = &state->lut[i]; |
495 | sda = &lut->sda; |
496 | |
497 | snprintf(buf: lut->name, size: sizeof(lut->name), |
498 | fmt: "pwm1_auto_point%d_pwm" , i + 1); |
499 | |
500 | sda->dev_attr.attr.mode = 0644; |
501 | sda->index = i; |
502 | sda->dev_attr.show = lut_show; |
503 | sda->dev_attr.store = lut_store; |
504 | sda->dev_attr.attr.name = lut->name; |
505 | |
506 | sysfs_attr_init(&sda->dev_attr.attr); |
507 | |
508 | state->attrs[i] = &sda->dev_attr.attr; |
509 | } |
510 | |
511 | state->attrs[i] = &dev_attr_pwm1_auto_point_temp_hyst.attr; |
512 | |
513 | state->group.attrs = state->attrs; |
514 | state->groups[0] = &state->group; |
515 | } |
516 | |
517 | static int max31760_probe(struct i2c_client *client) |
518 | { |
519 | struct device *dev = &client->dev; |
520 | struct max31760_state *state; |
521 | struct device *hwmon_dev; |
522 | int ret; |
523 | |
524 | state = devm_kzalloc(dev, size: sizeof(*state), GFP_KERNEL); |
525 | if (!state) |
526 | return -ENOMEM; |
527 | |
528 | state->regmap = devm_regmap_init_i2c(client, ®map_config); |
529 | if (IS_ERR(ptr: state->regmap)) |
530 | return dev_err_probe(dev, |
531 | err: PTR_ERR(ptr: state->regmap), |
532 | fmt: "regmap initialization failed\n" ); |
533 | |
534 | dev_set_drvdata(dev, data: state); |
535 | |
536 | /* Set alert output to comparator mode */ |
537 | ret = regmap_set_bits(map: state->regmap, REG_CR2, CR2_ALERTS); |
538 | if (ret) |
539 | return dev_err_probe(dev, err: ret, fmt: "cannot write register\n" ); |
540 | |
541 | max31760_create_lut_nodes(state); |
542 | |
543 | hwmon_dev = devm_hwmon_device_register_with_info(dev, name: client->name, |
544 | drvdata: state, |
545 | info: &max31760_chip_info, |
546 | extra_groups: state->groups); |
547 | |
548 | return PTR_ERR_OR_ZERO(ptr: hwmon_dev); |
549 | } |
550 | |
551 | static const struct of_device_id max31760_of_match[] = { |
552 | {.compatible = "adi,max31760" }, |
553 | { } |
554 | }; |
555 | MODULE_DEVICE_TABLE(of, max31760_of_match); |
556 | |
557 | static const struct i2c_device_id max31760_id[] = { |
558 | {"max31760" }, |
559 | { } |
560 | }; |
561 | MODULE_DEVICE_TABLE(i2c, max31760_id); |
562 | |
563 | static int max31760_suspend(struct device *dev) |
564 | { |
565 | struct max31760_state *state = dev_get_drvdata(dev); |
566 | |
567 | return regmap_set_bits(map: state->regmap, REG_CR2, CR2_STBY); |
568 | } |
569 | |
570 | static int max31760_resume(struct device *dev) |
571 | { |
572 | struct max31760_state *state = dev_get_drvdata(dev); |
573 | |
574 | return regmap_clear_bits(map: state->regmap, REG_CR2, CR2_STBY); |
575 | } |
576 | |
577 | static DEFINE_SIMPLE_DEV_PM_OPS(max31760_pm_ops, max31760_suspend, |
578 | max31760_resume); |
579 | |
580 | static struct i2c_driver max31760_driver = { |
581 | .driver = { |
582 | .name = "max31760" , |
583 | .of_match_table = max31760_of_match, |
584 | .pm = pm_ptr(&max31760_pm_ops) |
585 | }, |
586 | .probe = max31760_probe, |
587 | .id_table = max31760_id |
588 | }; |
589 | module_i2c_driver(max31760_driver); |
590 | |
591 | MODULE_AUTHOR("Ibrahim Tilki <Ibrahim.Tilki@analog.com>" ); |
592 | MODULE_DESCRIPTION("Analog Devices MAX31760 Fan Speed Controller" ); |
593 | MODULE_SOFTDEP("pre: regmap_i2c" ); |
594 | MODULE_VERSION("1.0" ); |
595 | MODULE_LICENSE("GPL" ); |
596 | |