1 | // SPDX-License-Identifier: GPL-2.0-or-later |
---|---|
2 | /* |
3 | * Hardware monitoring driver for PMBus devices |
4 | * |
5 | * Copyright (c) 2010, 2011 Ericsson AB. |
6 | * Copyright (c) 2012 Guenter Roeck |
7 | */ |
8 | |
9 | #include <linux/debugfs.h> |
10 | #include <linux/delay.h> |
11 | #include <linux/dcache.h> |
12 | #include <linux/kernel.h> |
13 | #include <linux/math64.h> |
14 | #include <linux/module.h> |
15 | #include <linux/init.h> |
16 | #include <linux/err.h> |
17 | #include <linux/slab.h> |
18 | #include <linux/i2c.h> |
19 | #include <linux/hwmon.h> |
20 | #include <linux/hwmon-sysfs.h> |
21 | #include <linux/pmbus.h> |
22 | #include <linux/regulator/driver.h> |
23 | #include <linux/regulator/machine.h> |
24 | #include <linux/of.h> |
25 | #include <linux/thermal.h> |
26 | #include "pmbus.h" |
27 | |
28 | /* |
29 | * Number of additional attribute pointers to allocate |
30 | * with each call to krealloc |
31 | */ |
32 | #define PMBUS_ATTR_ALLOC_SIZE 32 |
33 | #define PMBUS_NAME_SIZE 24 |
34 | |
35 | /* |
36 | * The type of operation used for picking the delay between |
37 | * successive pmbus operations. |
38 | */ |
39 | #define PMBUS_OP_WRITE BIT(0) |
40 | #define PMBUS_OP_PAGE_CHANGE BIT(1) |
41 | |
42 | static int wp = -1; |
43 | module_param(wp, int, 0444); |
44 | |
45 | struct pmbus_sensor { |
46 | struct pmbus_sensor *next; |
47 | char name[PMBUS_NAME_SIZE]; /* sysfs sensor name */ |
48 | struct device_attribute attribute; |
49 | u8 page; /* page number */ |
50 | u8 phase; /* phase number, 0xff for all phases */ |
51 | u16 reg; /* register */ |
52 | enum pmbus_sensor_classes class; /* sensor class */ |
53 | bool update; /* runtime sensor update needed */ |
54 | bool convert; /* Whether or not to apply linear/vid/direct */ |
55 | int data; /* Sensor data; negative if there was a read error */ |
56 | }; |
57 | #define to_pmbus_sensor(_attr) \ |
58 | container_of(_attr, struct pmbus_sensor, attribute) |
59 | |
60 | struct pmbus_boolean { |
61 | char name[PMBUS_NAME_SIZE]; /* sysfs boolean name */ |
62 | struct sensor_device_attribute attribute; |
63 | struct pmbus_sensor *s1; |
64 | struct pmbus_sensor *s2; |
65 | }; |
66 | #define to_pmbus_boolean(_attr) \ |
67 | container_of(_attr, struct pmbus_boolean, attribute) |
68 | |
69 | struct pmbus_label { |
70 | char name[PMBUS_NAME_SIZE]; /* sysfs label name */ |
71 | struct device_attribute attribute; |
72 | char label[PMBUS_NAME_SIZE]; /* label */ |
73 | }; |
74 | #define to_pmbus_label(_attr) \ |
75 | container_of(_attr, struct pmbus_label, attribute) |
76 | |
77 | /* Macros for converting between sensor index and register/page/status mask */ |
78 | |
79 | #define PB_STATUS_MASK 0xffff |
80 | #define PB_REG_SHIFT 16 |
81 | #define PB_REG_MASK 0x3ff |
82 | #define PB_PAGE_SHIFT 26 |
83 | #define PB_PAGE_MASK 0x3f |
84 | |
85 | #define pb_reg_to_index(page, reg, mask) (((page) << PB_PAGE_SHIFT) | \ |
86 | ((reg) << PB_REG_SHIFT) | (mask)) |
87 | |
88 | #define pb_index_to_page(index) (((index) >> PB_PAGE_SHIFT) & PB_PAGE_MASK) |
89 | #define pb_index_to_reg(index) (((index) >> PB_REG_SHIFT) & PB_REG_MASK) |
90 | #define pb_index_to_mask(index) ((index) & PB_STATUS_MASK) |
91 | |
92 | struct pmbus_data { |
93 | struct device *dev; |
94 | struct device *hwmon_dev; |
95 | struct regulator_dev **rdevs; |
96 | |
97 | u32 flags; /* from platform data */ |
98 | |
99 | u8 revision; /* The PMBus revision the device is compliant with */ |
100 | |
101 | int exponent[PMBUS_PAGES]; |
102 | /* linear mode: exponent for output voltages */ |
103 | |
104 | const struct pmbus_driver_info *info; |
105 | |
106 | int max_attributes; |
107 | int num_attributes; |
108 | struct attribute_group group; |
109 | const struct attribute_group **groups; |
110 | |
111 | struct pmbus_sensor *sensors; |
112 | |
113 | struct mutex update_lock; |
114 | |
115 | bool has_status_word; /* device uses STATUS_WORD register */ |
116 | int (*read_status)(struct i2c_client *client, int page); |
117 | |
118 | s16 currpage; /* current page, -1 for unknown/unset */ |
119 | s16 currphase; /* current phase, 0xff for all, -1 for unknown/unset */ |
120 | |
121 | int vout_low[PMBUS_PAGES]; /* voltage low margin */ |
122 | int vout_high[PMBUS_PAGES]; /* voltage high margin */ |
123 | |
124 | ktime_t next_access_backoff; /* Wait until at least this time */ |
125 | }; |
126 | |
127 | struct pmbus_debugfs_entry { |
128 | struct i2c_client *client; |
129 | u8 page; |
130 | u8 reg; |
131 | }; |
132 | |
133 | static const int pmbus_fan_rpm_mask[] = { |
134 | PB_FAN_1_RPM, |
135 | PB_FAN_2_RPM, |
136 | PB_FAN_1_RPM, |
137 | PB_FAN_2_RPM, |
138 | }; |
139 | |
140 | static const int pmbus_fan_config_registers[] = { |
141 | PMBUS_FAN_CONFIG_12, |
142 | PMBUS_FAN_CONFIG_12, |
143 | PMBUS_FAN_CONFIG_34, |
144 | PMBUS_FAN_CONFIG_34 |
145 | }; |
146 | |
147 | static const int pmbus_fan_command_registers[] = { |
148 | PMBUS_FAN_COMMAND_1, |
149 | PMBUS_FAN_COMMAND_2, |
150 | PMBUS_FAN_COMMAND_3, |
151 | PMBUS_FAN_COMMAND_4, |
152 | }; |
153 | |
154 | void pmbus_clear_cache(struct i2c_client *client) |
155 | { |
156 | struct pmbus_data *data = i2c_get_clientdata(client); |
157 | struct pmbus_sensor *sensor; |
158 | |
159 | for (sensor = data->sensors; sensor; sensor = sensor->next) |
160 | sensor->data = -ENODATA; |
161 | } |
162 | EXPORT_SYMBOL_NS_GPL(pmbus_clear_cache, "PMBUS"); |
163 | |
164 | void pmbus_set_update(struct i2c_client *client, u8 reg, bool update) |
165 | { |
166 | struct pmbus_data *data = i2c_get_clientdata(client); |
167 | struct pmbus_sensor *sensor; |
168 | |
169 | for (sensor = data->sensors; sensor; sensor = sensor->next) |
170 | if (sensor->reg == reg) |
171 | sensor->update = update; |
172 | } |
173 | EXPORT_SYMBOL_NS_GPL(pmbus_set_update, "PMBUS"); |
174 | |
175 | /* Some chips need a delay between accesses. */ |
176 | static void pmbus_wait(struct i2c_client *client) |
177 | { |
178 | struct pmbus_data *data = i2c_get_clientdata(client); |
179 | s64 delay = ktime_us_delta(later: data->next_access_backoff, earlier: ktime_get()); |
180 | |
181 | if (delay > 0) |
182 | fsleep(usecs: delay); |
183 | } |
184 | |
185 | /* Sets the last operation timestamp for pmbus_wait */ |
186 | static void pmbus_update_ts(struct i2c_client *client, int op) |
187 | { |
188 | struct pmbus_data *data = i2c_get_clientdata(client); |
189 | const struct pmbus_driver_info *info = data->info; |
190 | int delay = info->access_delay; |
191 | |
192 | if (op & PMBUS_OP_WRITE) |
193 | delay = max(delay, info->write_delay); |
194 | if (op & PMBUS_OP_PAGE_CHANGE) |
195 | delay = max(delay, info->page_change_delay); |
196 | |
197 | if (delay > 0) |
198 | data->next_access_backoff = ktime_add_us(kt: ktime_get(), usec: delay); |
199 | } |
200 | |
201 | int pmbus_set_page(struct i2c_client *client, int page, int phase) |
202 | { |
203 | struct pmbus_data *data = i2c_get_clientdata(client); |
204 | int rv; |
205 | |
206 | if (page < 0) |
207 | return 0; |
208 | |
209 | if (!(data->info->func[page] & PMBUS_PAGE_VIRTUAL) && |
210 | data->info->pages > 1 && page != data->currpage) { |
211 | pmbus_wait(client); |
212 | rv = i2c_smbus_write_byte_data(client, command: PMBUS_PAGE, value: page); |
213 | pmbus_update_ts(client, PMBUS_OP_WRITE | PMBUS_OP_PAGE_CHANGE); |
214 | if (rv < 0) |
215 | return rv; |
216 | |
217 | pmbus_wait(client); |
218 | rv = i2c_smbus_read_byte_data(client, command: PMBUS_PAGE); |
219 | pmbus_update_ts(client, op: 0); |
220 | if (rv < 0) |
221 | return rv; |
222 | |
223 | if (rv != page) |
224 | return -EIO; |
225 | } |
226 | data->currpage = page; |
227 | |
228 | if (data->info->phases[page] && data->currphase != phase && |
229 | !(data->info->func[page] & PMBUS_PHASE_VIRTUAL)) { |
230 | pmbus_wait(client); |
231 | rv = i2c_smbus_write_byte_data(client, command: PMBUS_PHASE, |
232 | value: phase); |
233 | pmbus_update_ts(client, PMBUS_OP_WRITE); |
234 | if (rv) |
235 | return rv; |
236 | } |
237 | data->currphase = phase; |
238 | |
239 | return 0; |
240 | } |
241 | EXPORT_SYMBOL_NS_GPL(pmbus_set_page, "PMBUS"); |
242 | |
243 | int pmbus_write_byte(struct i2c_client *client, int page, u8 value) |
244 | { |
245 | int rv; |
246 | |
247 | rv = pmbus_set_page(client, page, 0xff); |
248 | if (rv < 0) |
249 | return rv; |
250 | |
251 | pmbus_wait(client); |
252 | rv = i2c_smbus_write_byte(client, value); |
253 | pmbus_update_ts(client, PMBUS_OP_WRITE); |
254 | |
255 | return rv; |
256 | } |
257 | EXPORT_SYMBOL_NS_GPL(pmbus_write_byte, "PMBUS"); |
258 | |
259 | /* |
260 | * _pmbus_write_byte() is similar to pmbus_write_byte(), but checks if |
261 | * a device specific mapping function exists and calls it if necessary. |
262 | */ |
263 | static int _pmbus_write_byte(struct i2c_client *client, int page, u8 value) |
264 | { |
265 | struct pmbus_data *data = i2c_get_clientdata(client); |
266 | const struct pmbus_driver_info *info = data->info; |
267 | int status; |
268 | |
269 | if (info->write_byte) { |
270 | status = info->write_byte(client, page, value); |
271 | if (status != -ENODATA) |
272 | return status; |
273 | } |
274 | return pmbus_write_byte(client, page, value); |
275 | } |
276 | |
277 | int pmbus_write_word_data(struct i2c_client *client, int page, u8 reg, |
278 | u16 word) |
279 | { |
280 | int rv; |
281 | |
282 | rv = pmbus_set_page(client, page, 0xff); |
283 | if (rv < 0) |
284 | return rv; |
285 | |
286 | pmbus_wait(client); |
287 | rv = i2c_smbus_write_word_data(client, command: reg, value: word); |
288 | pmbus_update_ts(client, PMBUS_OP_WRITE); |
289 | |
290 | return rv; |
291 | } |
292 | EXPORT_SYMBOL_NS_GPL(pmbus_write_word_data, "PMBUS"); |
293 | |
294 | static int pmbus_write_virt_reg(struct i2c_client *client, int page, int reg, |
295 | u16 word) |
296 | { |
297 | int bit; |
298 | int id; |
299 | int rv; |
300 | |
301 | switch (reg) { |
302 | case PMBUS_VIRT_FAN_TARGET_1 ... PMBUS_VIRT_FAN_TARGET_4: |
303 | id = reg - PMBUS_VIRT_FAN_TARGET_1; |
304 | bit = pmbus_fan_rpm_mask[id]; |
305 | rv = pmbus_update_fan(client, page, id, config: bit, mask: bit, command: word); |
306 | break; |
307 | default: |
308 | rv = -ENXIO; |
309 | break; |
310 | } |
311 | |
312 | return rv; |
313 | } |
314 | |
315 | /* |
316 | * _pmbus_write_word_data() is similar to pmbus_write_word_data(), but checks if |
317 | * a device specific mapping function exists and calls it if necessary. |
318 | */ |
319 | static int _pmbus_write_word_data(struct i2c_client *client, int page, int reg, |
320 | u16 word) |
321 | { |
322 | struct pmbus_data *data = i2c_get_clientdata(client); |
323 | const struct pmbus_driver_info *info = data->info; |
324 | int status; |
325 | |
326 | if (info->write_word_data) { |
327 | status = info->write_word_data(client, page, reg, word); |
328 | if (status != -ENODATA) |
329 | return status; |
330 | } |
331 | |
332 | if (reg >= PMBUS_VIRT_BASE) |
333 | return pmbus_write_virt_reg(client, page, reg, word); |
334 | |
335 | return pmbus_write_word_data(client, page, reg, word); |
336 | } |
337 | |
338 | /* |
339 | * _pmbus_write_byte_data() is similar to pmbus_write_byte_data(), but checks if |
340 | * a device specific mapping function exists and calls it if necessary. |
341 | */ |
342 | static int _pmbus_write_byte_data(struct i2c_client *client, int page, int reg, u8 value) |
343 | { |
344 | struct pmbus_data *data = i2c_get_clientdata(client); |
345 | const struct pmbus_driver_info *info = data->info; |
346 | int status; |
347 | |
348 | if (info->write_byte_data) { |
349 | status = info->write_byte_data(client, page, reg, value); |
350 | if (status != -ENODATA) |
351 | return status; |
352 | } |
353 | return pmbus_write_byte_data(client, page, reg, value); |
354 | } |
355 | |
356 | /* |
357 | * _pmbus_read_byte_data() is similar to pmbus_read_byte_data(), but checks if |
358 | * a device specific mapping function exists and calls it if necessary. |
359 | */ |
360 | static int _pmbus_read_byte_data(struct i2c_client *client, int page, int reg) |
361 | { |
362 | struct pmbus_data *data = i2c_get_clientdata(client); |
363 | const struct pmbus_driver_info *info = data->info; |
364 | int status; |
365 | |
366 | if (info->read_byte_data) { |
367 | status = info->read_byte_data(client, page, reg); |
368 | if (status != -ENODATA) |
369 | return status; |
370 | } |
371 | return pmbus_read_byte_data(client, page, reg); |
372 | } |
373 | |
374 | int pmbus_update_fan(struct i2c_client *client, int page, int id, |
375 | u8 config, u8 mask, u16 command) |
376 | { |
377 | int from; |
378 | int rv; |
379 | u8 to; |
380 | |
381 | from = _pmbus_read_byte_data(client, page, |
382 | reg: pmbus_fan_config_registers[id]); |
383 | if (from < 0) |
384 | return from; |
385 | |
386 | to = (from & ~mask) | (config & mask); |
387 | if (to != from) { |
388 | rv = _pmbus_write_byte_data(client, page, |
389 | reg: pmbus_fan_config_registers[id], value: to); |
390 | if (rv < 0) |
391 | return rv; |
392 | } |
393 | |
394 | return _pmbus_write_word_data(client, page, |
395 | reg: pmbus_fan_command_registers[id], word: command); |
396 | } |
397 | EXPORT_SYMBOL_NS_GPL(pmbus_update_fan, "PMBUS"); |
398 | |
399 | int pmbus_read_word_data(struct i2c_client *client, int page, int phase, u8 reg) |
400 | { |
401 | int rv; |
402 | |
403 | rv = pmbus_set_page(client, page, phase); |
404 | if (rv < 0) |
405 | return rv; |
406 | |
407 | pmbus_wait(client); |
408 | rv = i2c_smbus_read_word_data(client, command: reg); |
409 | pmbus_update_ts(client, op: 0); |
410 | |
411 | return rv; |
412 | } |
413 | EXPORT_SYMBOL_NS_GPL(pmbus_read_word_data, "PMBUS"); |
414 | |
415 | static int pmbus_read_virt_reg(struct i2c_client *client, int page, int reg) |
416 | { |
417 | int rv; |
418 | int id; |
419 | |
420 | switch (reg) { |
421 | case PMBUS_VIRT_FAN_TARGET_1 ... PMBUS_VIRT_FAN_TARGET_4: |
422 | id = reg - PMBUS_VIRT_FAN_TARGET_1; |
423 | rv = pmbus_get_fan_rate_device(client, page, id, mode: rpm); |
424 | break; |
425 | default: |
426 | rv = -ENXIO; |
427 | break; |
428 | } |
429 | |
430 | return rv; |
431 | } |
432 | |
433 | /* |
434 | * _pmbus_read_word_data() is similar to pmbus_read_word_data(), but checks if |
435 | * a device specific mapping function exists and calls it if necessary. |
436 | */ |
437 | static int _pmbus_read_word_data(struct i2c_client *client, int page, |
438 | int phase, int reg) |
439 | { |
440 | struct pmbus_data *data = i2c_get_clientdata(client); |
441 | const struct pmbus_driver_info *info = data->info; |
442 | int status; |
443 | |
444 | if (info->read_word_data) { |
445 | status = info->read_word_data(client, page, phase, reg); |
446 | if (status != -ENODATA) |
447 | return status; |
448 | } |
449 | |
450 | if (reg >= PMBUS_VIRT_BASE) |
451 | return pmbus_read_virt_reg(client, page, reg); |
452 | |
453 | return pmbus_read_word_data(client, page, phase, reg); |
454 | } |
455 | |
456 | /* Same as above, but without phase parameter, for use in check functions */ |
457 | static int __pmbus_read_word_data(struct i2c_client *client, int page, int reg) |
458 | { |
459 | return _pmbus_read_word_data(client, page, phase: 0xff, reg); |
460 | } |
461 | |
462 | int pmbus_read_byte_data(struct i2c_client *client, int page, u8 reg) |
463 | { |
464 | int rv; |
465 | |
466 | rv = pmbus_set_page(client, page, 0xff); |
467 | if (rv < 0) |
468 | return rv; |
469 | |
470 | pmbus_wait(client); |
471 | rv = i2c_smbus_read_byte_data(client, command: reg); |
472 | pmbus_update_ts(client, op: 0); |
473 | |
474 | return rv; |
475 | } |
476 | EXPORT_SYMBOL_NS_GPL(pmbus_read_byte_data, "PMBUS"); |
477 | |
478 | int pmbus_write_byte_data(struct i2c_client *client, int page, u8 reg, u8 value) |
479 | { |
480 | int rv; |
481 | |
482 | rv = pmbus_set_page(client, page, 0xff); |
483 | if (rv < 0) |
484 | return rv; |
485 | |
486 | pmbus_wait(client); |
487 | rv = i2c_smbus_write_byte_data(client, command: reg, value); |
488 | pmbus_update_ts(client, PMBUS_OP_WRITE); |
489 | |
490 | return rv; |
491 | } |
492 | EXPORT_SYMBOL_NS_GPL(pmbus_write_byte_data, "PMBUS"); |
493 | |
494 | int pmbus_update_byte_data(struct i2c_client *client, int page, u8 reg, |
495 | u8 mask, u8 value) |
496 | { |
497 | unsigned int tmp; |
498 | int rv; |
499 | |
500 | rv = _pmbus_read_byte_data(client, page, reg); |
501 | if (rv < 0) |
502 | return rv; |
503 | |
504 | tmp = (rv & ~mask) | (value & mask); |
505 | |
506 | if (tmp != rv) |
507 | rv = _pmbus_write_byte_data(client, page, reg, value: tmp); |
508 | |
509 | return rv; |
510 | } |
511 | EXPORT_SYMBOL_NS_GPL(pmbus_update_byte_data, "PMBUS"); |
512 | |
513 | static int pmbus_read_block_data(struct i2c_client *client, int page, u8 reg, |
514 | char *data_buf) |
515 | { |
516 | int rv; |
517 | |
518 | rv = pmbus_set_page(client, page, 0xff); |
519 | if (rv < 0) |
520 | return rv; |
521 | |
522 | pmbus_wait(client); |
523 | rv = i2c_smbus_read_block_data(client, command: reg, values: data_buf); |
524 | pmbus_update_ts(client, op: 0); |
525 | |
526 | return rv; |
527 | } |
528 | |
529 | static struct pmbus_sensor *pmbus_find_sensor(struct pmbus_data *data, int page, |
530 | int reg) |
531 | { |
532 | struct pmbus_sensor *sensor; |
533 | |
534 | for (sensor = data->sensors; sensor; sensor = sensor->next) { |
535 | if (sensor->page == page && sensor->reg == reg) |
536 | return sensor; |
537 | } |
538 | |
539 | return ERR_PTR(error: -EINVAL); |
540 | } |
541 | |
542 | static int pmbus_get_fan_rate(struct i2c_client *client, int page, int id, |
543 | enum pmbus_fan_mode mode, |
544 | bool from_cache) |
545 | { |
546 | struct pmbus_data *data = i2c_get_clientdata(client); |
547 | bool want_rpm, have_rpm; |
548 | struct pmbus_sensor *s; |
549 | int config; |
550 | int reg; |
551 | |
552 | want_rpm = (mode == rpm); |
553 | |
554 | if (from_cache) { |
555 | reg = want_rpm ? PMBUS_VIRT_FAN_TARGET_1 : PMBUS_VIRT_PWM_1; |
556 | s = pmbus_find_sensor(data, page, reg: reg + id); |
557 | if (IS_ERR(ptr: s)) |
558 | return PTR_ERR(ptr: s); |
559 | |
560 | return s->data; |
561 | } |
562 | |
563 | config = _pmbus_read_byte_data(client, page, |
564 | reg: pmbus_fan_config_registers[id]); |
565 | if (config < 0) |
566 | return config; |
567 | |
568 | have_rpm = !!(config & pmbus_fan_rpm_mask[id]); |
569 | if (want_rpm == have_rpm) |
570 | return pmbus_read_word_data(client, page, 0xff, |
571 | pmbus_fan_command_registers[id]); |
572 | |
573 | /* Can't sensibly map between RPM and PWM, just return zero */ |
574 | return 0; |
575 | } |
576 | |
577 | int pmbus_get_fan_rate_device(struct i2c_client *client, int page, int id, |
578 | enum pmbus_fan_mode mode) |
579 | { |
580 | return pmbus_get_fan_rate(client, page, id, mode, from_cache: false); |
581 | } |
582 | EXPORT_SYMBOL_NS_GPL(pmbus_get_fan_rate_device, "PMBUS"); |
583 | |
584 | int pmbus_get_fan_rate_cached(struct i2c_client *client, int page, int id, |
585 | enum pmbus_fan_mode mode) |
586 | { |
587 | return pmbus_get_fan_rate(client, page, id, mode, from_cache: true); |
588 | } |
589 | EXPORT_SYMBOL_NS_GPL(pmbus_get_fan_rate_cached, "PMBUS"); |
590 | |
591 | static void pmbus_clear_fault_page(struct i2c_client *client, int page) |
592 | { |
593 | _pmbus_write_byte(client, page, value: PMBUS_CLEAR_FAULTS); |
594 | } |
595 | |
596 | void pmbus_clear_faults(struct i2c_client *client) |
597 | { |
598 | struct pmbus_data *data = i2c_get_clientdata(client); |
599 | int i; |
600 | |
601 | for (i = 0; i < data->info->pages; i++) |
602 | pmbus_clear_fault_page(client, page: i); |
603 | } |
604 | EXPORT_SYMBOL_NS_GPL(pmbus_clear_faults, "PMBUS"); |
605 | |
606 | static int pmbus_check_status_cml(struct i2c_client *client) |
607 | { |
608 | struct pmbus_data *data = i2c_get_clientdata(client); |
609 | int status, status2; |
610 | |
611 | status = data->read_status(client, -1); |
612 | if (status < 0 || (status & PB_STATUS_CML)) { |
613 | status2 = _pmbus_read_byte_data(client, page: -1, reg: PMBUS_STATUS_CML); |
614 | if (status2 < 0 || (status2 & PB_CML_FAULT_INVALID_COMMAND)) |
615 | return -EIO; |
616 | } |
617 | return 0; |
618 | } |
619 | |
620 | static bool pmbus_check_register(struct i2c_client *client, |
621 | int (*func)(struct i2c_client *client, |
622 | int page, int reg), |
623 | int page, int reg) |
624 | { |
625 | int rv; |
626 | struct pmbus_data *data = i2c_get_clientdata(client); |
627 | |
628 | rv = func(client, page, reg); |
629 | if (rv >= 0 && !(data->flags & PMBUS_SKIP_STATUS_CHECK)) |
630 | rv = pmbus_check_status_cml(client); |
631 | if (rv < 0 && (data->flags & PMBUS_READ_STATUS_AFTER_FAILED_CHECK)) |
632 | data->read_status(client, -1); |
633 | if (reg < PMBUS_VIRT_BASE) |
634 | pmbus_clear_fault_page(client, page: -1); |
635 | return rv >= 0; |
636 | } |
637 | |
638 | static bool pmbus_check_status_register(struct i2c_client *client, int page) |
639 | { |
640 | int status; |
641 | struct pmbus_data *data = i2c_get_clientdata(client); |
642 | |
643 | status = data->read_status(client, page); |
644 | if (status >= 0 && !(data->flags & PMBUS_SKIP_STATUS_CHECK) && |
645 | (status & PB_STATUS_CML)) { |
646 | status = _pmbus_read_byte_data(client, page: -1, reg: PMBUS_STATUS_CML); |
647 | if (status < 0 || (status & PB_CML_FAULT_INVALID_COMMAND)) |
648 | status = -EIO; |
649 | } |
650 | |
651 | pmbus_clear_fault_page(client, page: -1); |
652 | return status >= 0; |
653 | } |
654 | |
655 | bool pmbus_check_byte_register(struct i2c_client *client, int page, int reg) |
656 | { |
657 | return pmbus_check_register(client, func: _pmbus_read_byte_data, page, reg); |
658 | } |
659 | EXPORT_SYMBOL_NS_GPL(pmbus_check_byte_register, "PMBUS"); |
660 | |
661 | bool pmbus_check_word_register(struct i2c_client *client, int page, int reg) |
662 | { |
663 | return pmbus_check_register(client, func: __pmbus_read_word_data, page, reg); |
664 | } |
665 | EXPORT_SYMBOL_NS_GPL(pmbus_check_word_register, "PMBUS"); |
666 | |
667 | static bool __maybe_unused pmbus_check_block_register(struct i2c_client *client, |
668 | int page, int reg) |
669 | { |
670 | int rv; |
671 | struct pmbus_data *data = i2c_get_clientdata(client); |
672 | char data_buf[I2C_SMBUS_BLOCK_MAX + 2]; |
673 | |
674 | rv = pmbus_read_block_data(client, page, reg, data_buf); |
675 | if (rv >= 0 && !(data->flags & PMBUS_SKIP_STATUS_CHECK)) |
676 | rv = pmbus_check_status_cml(client); |
677 | if (rv < 0 && (data->flags & PMBUS_READ_STATUS_AFTER_FAILED_CHECK)) |
678 | data->read_status(client, -1); |
679 | pmbus_clear_fault_page(client, page: -1); |
680 | return rv >= 0; |
681 | } |
682 | |
683 | const struct pmbus_driver_info *pmbus_get_driver_info(struct i2c_client *client) |
684 | { |
685 | struct pmbus_data *data = i2c_get_clientdata(client); |
686 | |
687 | return data->info; |
688 | } |
689 | EXPORT_SYMBOL_NS_GPL(pmbus_get_driver_info, "PMBUS"); |
690 | |
691 | static int pmbus_get_status(struct i2c_client *client, int page, int reg) |
692 | { |
693 | struct pmbus_data *data = i2c_get_clientdata(client); |
694 | int status; |
695 | |
696 | switch (reg) { |
697 | case PMBUS_STATUS_WORD: |
698 | status = data->read_status(client, page); |
699 | break; |
700 | default: |
701 | status = _pmbus_read_byte_data(client, page, reg); |
702 | break; |
703 | } |
704 | if (status < 0) |
705 | pmbus_clear_faults(client); |
706 | return status; |
707 | } |
708 | |
709 | static void pmbus_update_sensor_data(struct i2c_client *client, struct pmbus_sensor *sensor) |
710 | { |
711 | if (sensor->data < 0 || sensor->update) |
712 | sensor->data = _pmbus_read_word_data(client, page: sensor->page, |
713 | phase: sensor->phase, reg: sensor->reg); |
714 | } |
715 | |
716 | /* |
717 | * Convert ieee754 sensor values to milli- or micro-units |
718 | * depending on sensor type. |
719 | * |
720 | * ieee754 data format: |
721 | * bit 15: sign |
722 | * bit 10..14: exponent |
723 | * bit 0..9: mantissa |
724 | * exponent=0: |
725 | * v=(−1)^signbit * 2^(−14) * 0.significantbits |
726 | * exponent=1..30: |
727 | * v=(−1)^signbit * 2^(exponent - 15) * 1.significantbits |
728 | * exponent=31: |
729 | * v=NaN |
730 | * |
731 | * Add the number mantissa bits into the calculations for simplicity. |
732 | * To do that, add '10' to the exponent. By doing that, we can just add |
733 | * 0x400 to normal values and get the expected result. |
734 | */ |
735 | static long pmbus_reg2data_ieee754(struct pmbus_data *data, |
736 | struct pmbus_sensor *sensor) |
737 | { |
738 | int exponent; |
739 | bool sign; |
740 | long val; |
741 | |
742 | /* only support half precision for now */ |
743 | sign = sensor->data & 0x8000; |
744 | exponent = (sensor->data >> 10) & 0x1f; |
745 | val = sensor->data & 0x3ff; |
746 | |
747 | if (exponent == 0) { /* subnormal */ |
748 | exponent = -(14 + 10); |
749 | } else if (exponent == 0x1f) { /* NaN, convert to min/max */ |
750 | exponent = 0; |
751 | val = 65504; |
752 | } else { |
753 | exponent -= (15 + 10); /* normal */ |
754 | val |= 0x400; |
755 | } |
756 | |
757 | /* scale result to milli-units for all sensors except fans */ |
758 | if (sensor->class != PSC_FAN) |
759 | val = val * 1000L; |
760 | |
761 | /* scale result to micro-units for power sensors */ |
762 | if (sensor->class == PSC_POWER) |
763 | val = val * 1000L; |
764 | |
765 | if (exponent >= 0) |
766 | val <<= exponent; |
767 | else |
768 | val >>= -exponent; |
769 | |
770 | if (sign) |
771 | val = -val; |
772 | |
773 | return val; |
774 | } |
775 | |
776 | /* |
777 | * Convert linear sensor values to milli- or micro-units |
778 | * depending on sensor type. |
779 | */ |
780 | static s64 pmbus_reg2data_linear(struct pmbus_data *data, |
781 | struct pmbus_sensor *sensor) |
782 | { |
783 | s16 exponent; |
784 | s32 mantissa; |
785 | s64 val; |
786 | |
787 | if (sensor->class == PSC_VOLTAGE_OUT) { /* LINEAR16 */ |
788 | exponent = data->exponent[sensor->page]; |
789 | mantissa = (u16)sensor->data; |
790 | } else { /* LINEAR11 */ |
791 | exponent = ((s16)sensor->data) >> 11; |
792 | mantissa = ((s16)((sensor->data & 0x7ff) << 5)) >> 5; |
793 | } |
794 | |
795 | val = mantissa; |
796 | |
797 | /* scale result to milli-units for all sensors except fans */ |
798 | if (sensor->class != PSC_FAN) |
799 | val = val * 1000LL; |
800 | |
801 | /* scale result to micro-units for power sensors */ |
802 | if (sensor->class == PSC_POWER) |
803 | val = val * 1000LL; |
804 | |
805 | if (exponent >= 0) |
806 | val <<= exponent; |
807 | else |
808 | val >>= -exponent; |
809 | |
810 | return val; |
811 | } |
812 | |
813 | /* |
814 | * Convert direct sensor values to milli- or micro-units |
815 | * depending on sensor type. |
816 | */ |
817 | static s64 pmbus_reg2data_direct(struct pmbus_data *data, |
818 | struct pmbus_sensor *sensor) |
819 | { |
820 | s64 b, val = (s16)sensor->data; |
821 | s32 m, R; |
822 | |
823 | m = data->info->m[sensor->class]; |
824 | b = data->info->b[sensor->class]; |
825 | R = data->info->R[sensor->class]; |
826 | |
827 | if (m == 0) |
828 | return 0; |
829 | |
830 | /* X = 1/m * (Y * 10^-R - b) */ |
831 | R = -R; |
832 | /* scale result to milli-units for everything but fans */ |
833 | if (!(sensor->class == PSC_FAN || sensor->class == PSC_PWM)) { |
834 | R += 3; |
835 | b *= 1000; |
836 | } |
837 | |
838 | /* scale result to micro-units for power sensors */ |
839 | if (sensor->class == PSC_POWER) { |
840 | R += 3; |
841 | b *= 1000; |
842 | } |
843 | |
844 | while (R > 0) { |
845 | val *= 10; |
846 | R--; |
847 | } |
848 | while (R < 0) { |
849 | val = div_s64(dividend: val + 5LL, divisor: 10L); /* round closest */ |
850 | R++; |
851 | } |
852 | |
853 | val = div_s64(dividend: val - b, divisor: m); |
854 | return val; |
855 | } |
856 | |
857 | /* |
858 | * Convert VID sensor values to milli- or micro-units |
859 | * depending on sensor type. |
860 | */ |
861 | static s64 pmbus_reg2data_vid(struct pmbus_data *data, |
862 | struct pmbus_sensor *sensor) |
863 | { |
864 | long val = sensor->data; |
865 | long rv = 0; |
866 | |
867 | switch (data->info->vrm_version[sensor->page]) { |
868 | case vr11: |
869 | if (val >= 0x02 && val <= 0xb2) |
870 | rv = DIV_ROUND_CLOSEST(160000 - (val - 2) * 625, 100); |
871 | break; |
872 | case vr12: |
873 | if (val >= 0x01) |
874 | rv = 250 + (val - 1) * 5; |
875 | break; |
876 | case vr13: |
877 | if (val >= 0x01) |
878 | rv = 500 + (val - 1) * 10; |
879 | break; |
880 | case imvp9: |
881 | if (val >= 0x01) |
882 | rv = 200 + (val - 1) * 10; |
883 | break; |
884 | case amd625mv: |
885 | if (val >= 0x0 && val <= 0xd8) |
886 | rv = DIV_ROUND_CLOSEST(155000 - val * 625, 100); |
887 | break; |
888 | } |
889 | return rv; |
890 | } |
891 | |
892 | static s64 pmbus_reg2data(struct pmbus_data *data, struct pmbus_sensor *sensor) |
893 | { |
894 | s64 val; |
895 | |
896 | if (!sensor->convert) |
897 | return sensor->data; |
898 | |
899 | switch (data->info->format[sensor->class]) { |
900 | case direct: |
901 | val = pmbus_reg2data_direct(data, sensor); |
902 | break; |
903 | case vid: |
904 | val = pmbus_reg2data_vid(data, sensor); |
905 | break; |
906 | case ieee754: |
907 | val = pmbus_reg2data_ieee754(data, sensor); |
908 | break; |
909 | case linear: |
910 | default: |
911 | val = pmbus_reg2data_linear(data, sensor); |
912 | break; |
913 | } |
914 | return val; |
915 | } |
916 | |
917 | #define MAX_IEEE_MANTISSA (0x7ff * 1000) |
918 | #define MIN_IEEE_MANTISSA (0x400 * 1000) |
919 | |
920 | static u16 pmbus_data2reg_ieee754(struct pmbus_data *data, |
921 | struct pmbus_sensor *sensor, long val) |
922 | { |
923 | u16 exponent = (15 + 10); |
924 | long mantissa; |
925 | u16 sign = 0; |
926 | |
927 | /* simple case */ |
928 | if (val == 0) |
929 | return 0; |
930 | |
931 | if (val < 0) { |
932 | sign = 0x8000; |
933 | val = -val; |
934 | } |
935 | |
936 | /* Power is in uW. Convert to mW before converting. */ |
937 | if (sensor->class == PSC_POWER) |
938 | val = DIV_ROUND_CLOSEST(val, 1000L); |
939 | |
940 | /* |
941 | * For simplicity, convert fan data to milli-units |
942 | * before calculating the exponent. |
943 | */ |
944 | if (sensor->class == PSC_FAN) |
945 | val = val * 1000; |
946 | |
947 | /* Reduce large mantissa until it fits into 10 bit */ |
948 | while (val > MAX_IEEE_MANTISSA && exponent < 30) { |
949 | exponent++; |
950 | val >>= 1; |
951 | } |
952 | /* |
953 | * Increase small mantissa to generate valid 'normal' |
954 | * number |
955 | */ |
956 | while (val < MIN_IEEE_MANTISSA && exponent > 1) { |
957 | exponent--; |
958 | val <<= 1; |
959 | } |
960 | |
961 | /* Convert mantissa from milli-units to units */ |
962 | mantissa = DIV_ROUND_CLOSEST(val, 1000); |
963 | |
964 | /* |
965 | * Ensure that the resulting number is within range. |
966 | * Valid range is 0x400..0x7ff, where bit 10 reflects |
967 | * the implied high bit in normalized ieee754 numbers. |
968 | * Set the range to 0x400..0x7ff to reflect this. |
969 | * The upper bit is then removed by the mask against |
970 | * 0x3ff in the final assignment. |
971 | */ |
972 | if (mantissa > 0x7ff) |
973 | mantissa = 0x7ff; |
974 | else if (mantissa < 0x400) |
975 | mantissa = 0x400; |
976 | |
977 | /* Convert to sign, 5 bit exponent, 10 bit mantissa */ |
978 | return sign | (mantissa & 0x3ff) | ((exponent << 10) & 0x7c00); |
979 | } |
980 | |
981 | #define MAX_LIN_MANTISSA (1023 * 1000) |
982 | #define MIN_LIN_MANTISSA (511 * 1000) |
983 | |
984 | static u16 pmbus_data2reg_linear(struct pmbus_data *data, |
985 | struct pmbus_sensor *sensor, s64 val) |
986 | { |
987 | s16 exponent = 0, mantissa; |
988 | bool negative = false; |
989 | |
990 | /* simple case */ |
991 | if (val == 0) |
992 | return 0; |
993 | |
994 | if (sensor->class == PSC_VOLTAGE_OUT) { |
995 | /* LINEAR16 does not support negative voltages */ |
996 | if (val < 0) |
997 | return 0; |
998 | |
999 | /* |
1000 | * For a static exponents, we don't have a choice |
1001 | * but to adjust the value to it. |
1002 | */ |
1003 | if (data->exponent[sensor->page] < 0) |
1004 | val <<= -data->exponent[sensor->page]; |
1005 | else |
1006 | val >>= data->exponent[sensor->page]; |
1007 | val = DIV_ROUND_CLOSEST_ULL(val, 1000); |
1008 | return clamp_val(val, 0, 0xffff); |
1009 | } |
1010 | |
1011 | if (val < 0) { |
1012 | negative = true; |
1013 | val = -val; |
1014 | } |
1015 | |
1016 | /* Power is in uW. Convert to mW before converting. */ |
1017 | if (sensor->class == PSC_POWER) |
1018 | val = DIV_ROUND_CLOSEST_ULL(val, 1000); |
1019 | |
1020 | /* |
1021 | * For simplicity, convert fan data to milli-units |
1022 | * before calculating the exponent. |
1023 | */ |
1024 | if (sensor->class == PSC_FAN) |
1025 | val = val * 1000LL; |
1026 | |
1027 | /* Reduce large mantissa until it fits into 10 bit */ |
1028 | while (val >= MAX_LIN_MANTISSA && exponent < 15) { |
1029 | exponent++; |
1030 | val >>= 1; |
1031 | } |
1032 | /* Increase small mantissa to improve precision */ |
1033 | while (val < MIN_LIN_MANTISSA && exponent > -15) { |
1034 | exponent--; |
1035 | val <<= 1; |
1036 | } |
1037 | |
1038 | /* Convert mantissa from milli-units to units */ |
1039 | mantissa = clamp_val(DIV_ROUND_CLOSEST_ULL(val, 1000), 0, 0x3ff); |
1040 | |
1041 | /* restore sign */ |
1042 | if (negative) |
1043 | mantissa = -mantissa; |
1044 | |
1045 | /* Convert to 5 bit exponent, 11 bit mantissa */ |
1046 | return (mantissa & 0x7ff) | ((exponent << 11) & 0xf800); |
1047 | } |
1048 | |
1049 | static u16 pmbus_data2reg_direct(struct pmbus_data *data, |
1050 | struct pmbus_sensor *sensor, s64 val) |
1051 | { |
1052 | s64 b; |
1053 | s32 m, R; |
1054 | |
1055 | m = data->info->m[sensor->class]; |
1056 | b = data->info->b[sensor->class]; |
1057 | R = data->info->R[sensor->class]; |
1058 | |
1059 | /* Power is in uW. Adjust R and b. */ |
1060 | if (sensor->class == PSC_POWER) { |
1061 | R -= 3; |
1062 | b *= 1000; |
1063 | } |
1064 | |
1065 | /* Calculate Y = (m * X + b) * 10^R */ |
1066 | if (!(sensor->class == PSC_FAN || sensor->class == PSC_PWM)) { |
1067 | R -= 3; /* Adjust R and b for data in milli-units */ |
1068 | b *= 1000; |
1069 | } |
1070 | val = val * m + b; |
1071 | |
1072 | while (R > 0) { |
1073 | val *= 10; |
1074 | R--; |
1075 | } |
1076 | while (R < 0) { |
1077 | val = div_s64(dividend: val + 5LL, divisor: 10L); /* round closest */ |
1078 | R++; |
1079 | } |
1080 | |
1081 | return (u16)clamp_val(val, S16_MIN, S16_MAX); |
1082 | } |
1083 | |
1084 | static u16 pmbus_data2reg_vid(struct pmbus_data *data, |
1085 | struct pmbus_sensor *sensor, s64 val) |
1086 | { |
1087 | val = clamp_val(val, 500, 1600); |
1088 | |
1089 | return 2 + DIV_ROUND_CLOSEST_ULL((1600LL - val) * 100LL, 625); |
1090 | } |
1091 | |
1092 | static u16 pmbus_data2reg(struct pmbus_data *data, |
1093 | struct pmbus_sensor *sensor, s64 val) |
1094 | { |
1095 | u16 regval; |
1096 | |
1097 | if (!sensor->convert) |
1098 | return val; |
1099 | |
1100 | switch (data->info->format[sensor->class]) { |
1101 | case direct: |
1102 | regval = pmbus_data2reg_direct(data, sensor, val); |
1103 | break; |
1104 | case vid: |
1105 | regval = pmbus_data2reg_vid(data, sensor, val); |
1106 | break; |
1107 | case ieee754: |
1108 | regval = pmbus_data2reg_ieee754(data, sensor, val); |
1109 | break; |
1110 | case linear: |
1111 | default: |
1112 | regval = pmbus_data2reg_linear(data, sensor, val); |
1113 | break; |
1114 | } |
1115 | return regval; |
1116 | } |
1117 | |
1118 | /* |
1119 | * Return boolean calculated from converted data. |
1120 | * <index> defines a status register index and mask. |
1121 | * The mask is in the lower 8 bits, the register index is in bits 8..23. |
1122 | * |
1123 | * The associated pmbus_boolean structure contains optional pointers to two |
1124 | * sensor attributes. If specified, those attributes are compared against each |
1125 | * other to determine if a limit has been exceeded. |
1126 | * |
1127 | * If the sensor attribute pointers are NULL, the function returns true if |
1128 | * (status[reg] & mask) is true. |
1129 | * |
1130 | * If sensor attribute pointers are provided, a comparison against a specified |
1131 | * limit has to be performed to determine the boolean result. |
1132 | * In this case, the function returns true if v1 >= v2 (where v1 and v2 are |
1133 | * sensor values referenced by sensor attribute pointers s1 and s2). |
1134 | * |
1135 | * To determine if an object exceeds upper limits, specify <s1,s2> = <v,limit>. |
1136 | * To determine if an object exceeds lower limits, specify <s1,s2> = <limit,v>. |
1137 | * |
1138 | * If a negative value is stored in any of the referenced registers, this value |
1139 | * reflects an error code which will be returned. |
1140 | */ |
1141 | static int pmbus_get_boolean(struct i2c_client *client, struct pmbus_boolean *b, |
1142 | int index) |
1143 | { |
1144 | struct pmbus_data *data = i2c_get_clientdata(client); |
1145 | struct pmbus_sensor *s1 = b->s1; |
1146 | struct pmbus_sensor *s2 = b->s2; |
1147 | u16 mask = pb_index_to_mask(index); |
1148 | u8 page = pb_index_to_page(index); |
1149 | u16 reg = pb_index_to_reg(index); |
1150 | int ret, status; |
1151 | u16 regval; |
1152 | |
1153 | mutex_lock(&data->update_lock); |
1154 | status = pmbus_get_status(client, page, reg); |
1155 | if (status < 0) { |
1156 | ret = status; |
1157 | goto unlock; |
1158 | } |
1159 | |
1160 | if (s1) |
1161 | pmbus_update_sensor_data(client, sensor: s1); |
1162 | if (s2) |
1163 | pmbus_update_sensor_data(client, sensor: s2); |
1164 | |
1165 | regval = status & mask; |
1166 | if (regval) { |
1167 | if (data->revision >= PMBUS_REV_12) { |
1168 | ret = _pmbus_write_byte_data(client, page, reg, value: regval); |
1169 | if (ret) |
1170 | goto unlock; |
1171 | } else { |
1172 | pmbus_clear_fault_page(client, page); |
1173 | } |
1174 | } |
1175 | if (s1 && s2) { |
1176 | s64 v1, v2; |
1177 | |
1178 | if (s1->data < 0) { |
1179 | ret = s1->data; |
1180 | goto unlock; |
1181 | } |
1182 | if (s2->data < 0) { |
1183 | ret = s2->data; |
1184 | goto unlock; |
1185 | } |
1186 | |
1187 | v1 = pmbus_reg2data(data, sensor: s1); |
1188 | v2 = pmbus_reg2data(data, sensor: s2); |
1189 | ret = !!(regval && v1 >= v2); |
1190 | } else { |
1191 | ret = !!regval; |
1192 | } |
1193 | unlock: |
1194 | mutex_unlock(lock: &data->update_lock); |
1195 | return ret; |
1196 | } |
1197 | |
1198 | static ssize_t pmbus_show_boolean(struct device *dev, |
1199 | struct device_attribute *da, char *buf) |
1200 | { |
1201 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); |
1202 | struct pmbus_boolean *boolean = to_pmbus_boolean(attr); |
1203 | struct i2c_client *client = to_i2c_client(dev->parent); |
1204 | int val; |
1205 | |
1206 | val = pmbus_get_boolean(client, b: boolean, index: attr->index); |
1207 | if (val < 0) |
1208 | return val; |
1209 | return sysfs_emit(buf, fmt: "%d\n", val); |
1210 | } |
1211 | |
1212 | static ssize_t pmbus_show_sensor(struct device *dev, |
1213 | struct device_attribute *devattr, char *buf) |
1214 | { |
1215 | struct i2c_client *client = to_i2c_client(dev->parent); |
1216 | struct pmbus_sensor *sensor = to_pmbus_sensor(devattr); |
1217 | struct pmbus_data *data = i2c_get_clientdata(client); |
1218 | ssize_t ret; |
1219 | |
1220 | mutex_lock(&data->update_lock); |
1221 | pmbus_update_sensor_data(client, sensor); |
1222 | if (sensor->data < 0) |
1223 | ret = sensor->data; |
1224 | else |
1225 | ret = sysfs_emit(buf, fmt: "%lld\n", pmbus_reg2data(data, sensor)); |
1226 | mutex_unlock(lock: &data->update_lock); |
1227 | return ret; |
1228 | } |
1229 | |
1230 | static ssize_t pmbus_set_sensor(struct device *dev, |
1231 | struct device_attribute *devattr, |
1232 | const char *buf, size_t count) |
1233 | { |
1234 | struct i2c_client *client = to_i2c_client(dev->parent); |
1235 | struct pmbus_data *data = i2c_get_clientdata(client); |
1236 | struct pmbus_sensor *sensor = to_pmbus_sensor(devattr); |
1237 | ssize_t rv = count; |
1238 | s64 val; |
1239 | int ret; |
1240 | u16 regval; |
1241 | |
1242 | if (kstrtos64(s: buf, base: 10, res: &val) < 0) |
1243 | return -EINVAL; |
1244 | |
1245 | mutex_lock(&data->update_lock); |
1246 | regval = pmbus_data2reg(data, sensor, val); |
1247 | ret = _pmbus_write_word_data(client, page: sensor->page, reg: sensor->reg, word: regval); |
1248 | if (ret < 0) |
1249 | rv = ret; |
1250 | else |
1251 | sensor->data = -ENODATA; |
1252 | mutex_unlock(lock: &data->update_lock); |
1253 | return rv; |
1254 | } |
1255 | |
1256 | static ssize_t pmbus_show_label(struct device *dev, |
1257 | struct device_attribute *da, char *buf) |
1258 | { |
1259 | struct pmbus_label *label = to_pmbus_label(da); |
1260 | |
1261 | return sysfs_emit(buf, fmt: "%s\n", label->label); |
1262 | } |
1263 | |
1264 | static int pmbus_add_attribute(struct pmbus_data *data, struct attribute *attr) |
1265 | { |
1266 | if (data->num_attributes >= data->max_attributes - 1) { |
1267 | int new_max_attrs = data->max_attributes + PMBUS_ATTR_ALLOC_SIZE; |
1268 | void *new_attrs = devm_krealloc_array(dev: data->dev, p: data->group.attrs, |
1269 | new_n: new_max_attrs, new_size: sizeof(void *), |
1270 | GFP_KERNEL); |
1271 | if (!new_attrs) |
1272 | return -ENOMEM; |
1273 | data->group.attrs = new_attrs; |
1274 | data->max_attributes = new_max_attrs; |
1275 | } |
1276 | |
1277 | data->group.attrs[data->num_attributes++] = attr; |
1278 | data->group.attrs[data->num_attributes] = NULL; |
1279 | return 0; |
1280 | } |
1281 | |
1282 | static void pmbus_dev_attr_init(struct device_attribute *dev_attr, |
1283 | const char *name, |
1284 | umode_t mode, |
1285 | ssize_t (*show)(struct device *dev, |
1286 | struct device_attribute *attr, |
1287 | char *buf), |
1288 | ssize_t (*store)(struct device *dev, |
1289 | struct device_attribute *attr, |
1290 | const char *buf, size_t count)) |
1291 | { |
1292 | sysfs_attr_init(&dev_attr->attr); |
1293 | dev_attr->attr.name = name; |
1294 | dev_attr->attr.mode = mode; |
1295 | dev_attr->show = show; |
1296 | dev_attr->store = store; |
1297 | } |
1298 | |
1299 | static void pmbus_attr_init(struct sensor_device_attribute *a, |
1300 | const char *name, |
1301 | umode_t mode, |
1302 | ssize_t (*show)(struct device *dev, |
1303 | struct device_attribute *attr, |
1304 | char *buf), |
1305 | ssize_t (*store)(struct device *dev, |
1306 | struct device_attribute *attr, |
1307 | const char *buf, size_t count), |
1308 | int idx) |
1309 | { |
1310 | pmbus_dev_attr_init(dev_attr: &a->dev_attr, name, mode, show, store); |
1311 | a->index = idx; |
1312 | } |
1313 | |
1314 | static int pmbus_add_boolean(struct pmbus_data *data, |
1315 | const char *name, const char *type, int seq, |
1316 | struct pmbus_sensor *s1, |
1317 | struct pmbus_sensor *s2, |
1318 | u8 page, u16 reg, u16 mask) |
1319 | { |
1320 | struct pmbus_boolean *boolean; |
1321 | struct sensor_device_attribute *a; |
1322 | |
1323 | if (WARN((s1 && !s2) || (!s1 && s2), "Bad s1/s2 parameters\n")) |
1324 | return -EINVAL; |
1325 | |
1326 | boolean = devm_kzalloc(dev: data->dev, size: sizeof(*boolean), GFP_KERNEL); |
1327 | if (!boolean) |
1328 | return -ENOMEM; |
1329 | |
1330 | a = &boolean->attribute; |
1331 | |
1332 | snprintf(buf: boolean->name, size: sizeof(boolean->name), fmt: "%s%d_%s", |
1333 | name, seq, type); |
1334 | boolean->s1 = s1; |
1335 | boolean->s2 = s2; |
1336 | pmbus_attr_init(a, name: boolean->name, mode: 0444, show: pmbus_show_boolean, NULL, |
1337 | pb_reg_to_index(page, reg, mask)); |
1338 | |
1339 | return pmbus_add_attribute(data, attr: &a->dev_attr.attr); |
1340 | } |
1341 | |
1342 | /* of thermal for pmbus temperature sensors */ |
1343 | struct pmbus_thermal_data { |
1344 | struct pmbus_data *pmbus_data; |
1345 | struct pmbus_sensor *sensor; |
1346 | }; |
1347 | |
1348 | static int pmbus_thermal_get_temp(struct thermal_zone_device *tz, int *temp) |
1349 | { |
1350 | struct pmbus_thermal_data *tdata = thermal_zone_device_priv(tzd: tz); |
1351 | struct pmbus_sensor *sensor = tdata->sensor; |
1352 | struct pmbus_data *pmbus_data = tdata->pmbus_data; |
1353 | struct i2c_client *client = to_i2c_client(pmbus_data->dev); |
1354 | struct device *dev = pmbus_data->hwmon_dev; |
1355 | int ret = 0; |
1356 | |
1357 | if (!dev) { |
1358 | /* May not even get to hwmon yet */ |
1359 | *temp = 0; |
1360 | return 0; |
1361 | } |
1362 | |
1363 | mutex_lock(&pmbus_data->update_lock); |
1364 | pmbus_update_sensor_data(client, sensor); |
1365 | if (sensor->data < 0) |
1366 | ret = sensor->data; |
1367 | else |
1368 | *temp = (int)pmbus_reg2data(data: pmbus_data, sensor); |
1369 | mutex_unlock(lock: &pmbus_data->update_lock); |
1370 | |
1371 | return ret; |
1372 | } |
1373 | |
1374 | static const struct thermal_zone_device_ops pmbus_thermal_ops = { |
1375 | .get_temp = pmbus_thermal_get_temp, |
1376 | }; |
1377 | |
1378 | static int pmbus_thermal_add_sensor(struct pmbus_data *pmbus_data, |
1379 | struct pmbus_sensor *sensor, int index) |
1380 | { |
1381 | struct device *dev = pmbus_data->dev; |
1382 | struct pmbus_thermal_data *tdata; |
1383 | struct thermal_zone_device *tzd; |
1384 | |
1385 | tdata = devm_kzalloc(dev, size: sizeof(*tdata), GFP_KERNEL); |
1386 | if (!tdata) |
1387 | return -ENOMEM; |
1388 | |
1389 | tdata->sensor = sensor; |
1390 | tdata->pmbus_data = pmbus_data; |
1391 | |
1392 | tzd = devm_thermal_of_zone_register(dev, id: index, data: tdata, |
1393 | ops: &pmbus_thermal_ops); |
1394 | /* |
1395 | * If CONFIG_THERMAL_OF is disabled, this returns -ENODEV, |
1396 | * so ignore that error but forward any other error. |
1397 | */ |
1398 | if (IS_ERR(ptr: tzd) && (PTR_ERR(ptr: tzd) != -ENODEV)) |
1399 | return PTR_ERR(ptr: tzd); |
1400 | |
1401 | return 0; |
1402 | } |
1403 | |
1404 | static struct pmbus_sensor *pmbus_add_sensor(struct pmbus_data *data, |
1405 | const char *name, const char *type, |
1406 | int seq, int page, int phase, |
1407 | int reg, |
1408 | enum pmbus_sensor_classes class, |
1409 | bool update, bool readonly, |
1410 | bool convert) |
1411 | { |
1412 | struct pmbus_sensor *sensor; |
1413 | struct device_attribute *a; |
1414 | |
1415 | sensor = devm_kzalloc(dev: data->dev, size: sizeof(*sensor), GFP_KERNEL); |
1416 | if (!sensor) |
1417 | return NULL; |
1418 | a = &sensor->attribute; |
1419 | |
1420 | if (type) |
1421 | snprintf(buf: sensor->name, size: sizeof(sensor->name), fmt: "%s%d_%s", |
1422 | name, seq, type); |
1423 | else |
1424 | snprintf(buf: sensor->name, size: sizeof(sensor->name), fmt: "%s%d", |
1425 | name, seq); |
1426 | |
1427 | if (data->flags & PMBUS_WRITE_PROTECTED) |
1428 | readonly = true; |
1429 | |
1430 | sensor->page = page; |
1431 | sensor->phase = phase; |
1432 | sensor->reg = reg; |
1433 | sensor->class = class; |
1434 | sensor->update = update; |
1435 | sensor->convert = convert; |
1436 | sensor->data = -ENODATA; |
1437 | pmbus_dev_attr_init(dev_attr: a, name: sensor->name, |
1438 | mode: readonly ? 0444 : 0644, |
1439 | show: pmbus_show_sensor, store: pmbus_set_sensor); |
1440 | |
1441 | if (pmbus_add_attribute(data, attr: &a->attr)) |
1442 | return NULL; |
1443 | |
1444 | sensor->next = data->sensors; |
1445 | data->sensors = sensor; |
1446 | |
1447 | /* temperature sensors with _input values are registered with thermal */ |
1448 | if (class == PSC_TEMPERATURE && strcmp(type, "input") == 0) |
1449 | pmbus_thermal_add_sensor(pmbus_data: data, sensor, index: seq); |
1450 | |
1451 | return sensor; |
1452 | } |
1453 | |
1454 | static int pmbus_add_label(struct pmbus_data *data, |
1455 | const char *name, int seq, |
1456 | const char *lstring, int index, int phase) |
1457 | { |
1458 | struct pmbus_label *label; |
1459 | struct device_attribute *a; |
1460 | |
1461 | label = devm_kzalloc(dev: data->dev, size: sizeof(*label), GFP_KERNEL); |
1462 | if (!label) |
1463 | return -ENOMEM; |
1464 | |
1465 | a = &label->attribute; |
1466 | |
1467 | snprintf(buf: label->name, size: sizeof(label->name), fmt: "%s%d_label", name, seq); |
1468 | if (!index) { |
1469 | if (phase == 0xff) |
1470 | strscpy(label->label, lstring); |
1471 | else |
1472 | snprintf(buf: label->label, size: sizeof(label->label), fmt: "%s.%d", |
1473 | lstring, phase); |
1474 | } else { |
1475 | if (phase == 0xff) |
1476 | snprintf(buf: label->label, size: sizeof(label->label), fmt: "%s%d", |
1477 | lstring, index); |
1478 | else |
1479 | snprintf(buf: label->label, size: sizeof(label->label), fmt: "%s%d.%d", |
1480 | lstring, index, phase); |
1481 | } |
1482 | |
1483 | pmbus_dev_attr_init(dev_attr: a, name: label->name, mode: 0444, show: pmbus_show_label, NULL); |
1484 | return pmbus_add_attribute(data, attr: &a->attr); |
1485 | } |
1486 | |
1487 | /* |
1488 | * Search for attributes. Allocate sensors, booleans, and labels as needed. |
1489 | */ |
1490 | |
1491 | /* |
1492 | * The pmbus_limit_attr structure describes a single limit attribute |
1493 | * and its associated alarm attribute. |
1494 | */ |
1495 | struct pmbus_limit_attr { |
1496 | u16 reg; /* Limit register */ |
1497 | u16 sbit; /* Alarm attribute status bit */ |
1498 | bool update; /* True if register needs updates */ |
1499 | bool low; /* True if low limit; for limits with compare functions only */ |
1500 | const char *attr; /* Attribute name */ |
1501 | const char *alarm; /* Alarm attribute name */ |
1502 | }; |
1503 | |
1504 | /* |
1505 | * The pmbus_sensor_attr structure describes one sensor attribute. This |
1506 | * description includes a reference to the associated limit attributes. |
1507 | */ |
1508 | struct pmbus_sensor_attr { |
1509 | u16 reg; /* sensor register */ |
1510 | u16 gbit; /* generic status bit */ |
1511 | u8 nlimit; /* # of limit registers */ |
1512 | enum pmbus_sensor_classes class;/* sensor class */ |
1513 | const char *label; /* sensor label */ |
1514 | bool paged; /* true if paged sensor */ |
1515 | bool update; /* true if update needed */ |
1516 | bool compare; /* true if compare function needed */ |
1517 | u32 func; /* sensor mask */ |
1518 | u32 sfunc; /* sensor status mask */ |
1519 | int sreg; /* status register */ |
1520 | const struct pmbus_limit_attr *limit;/* limit registers */ |
1521 | }; |
1522 | |
1523 | /* |
1524 | * Add a set of limit attributes and, if supported, the associated |
1525 | * alarm attributes. |
1526 | * returns 0 if no alarm register found, 1 if an alarm register was found, |
1527 | * < 0 on errors. |
1528 | */ |
1529 | static int pmbus_add_limit_attrs(struct i2c_client *client, |
1530 | struct pmbus_data *data, |
1531 | const struct pmbus_driver_info *info, |
1532 | const char *name, int index, int page, |
1533 | struct pmbus_sensor *base, |
1534 | const struct pmbus_sensor_attr *attr) |
1535 | { |
1536 | const struct pmbus_limit_attr *l = attr->limit; |
1537 | int nlimit = attr->nlimit; |
1538 | int have_alarm = 0; |
1539 | int i, ret; |
1540 | struct pmbus_sensor *curr; |
1541 | |
1542 | for (i = 0; i < nlimit; i++) { |
1543 | if (pmbus_check_word_register(client, page, l->reg)) { |
1544 | curr = pmbus_add_sensor(data, name, type: l->attr, seq: index, |
1545 | page, phase: 0xff, reg: l->reg, class: attr->class, |
1546 | update: attr->update || l->update, |
1547 | readonly: false, convert: true); |
1548 | if (!curr) |
1549 | return -ENOMEM; |
1550 | if (l->sbit && (info->func[page] & attr->sfunc)) { |
1551 | ret = pmbus_add_boolean(data, name, |
1552 | type: l->alarm, seq: index, |
1553 | s1: attr->compare ? l->low ? curr : base |
1554 | : NULL, |
1555 | s2: attr->compare ? l->low ? base : curr |
1556 | : NULL, |
1557 | page, reg: attr->sreg, mask: l->sbit); |
1558 | if (ret) |
1559 | return ret; |
1560 | have_alarm = 1; |
1561 | } |
1562 | } |
1563 | l++; |
1564 | } |
1565 | return have_alarm; |
1566 | } |
1567 | |
1568 | static int pmbus_add_sensor_attrs_one(struct i2c_client *client, |
1569 | struct pmbus_data *data, |
1570 | const struct pmbus_driver_info *info, |
1571 | const char *name, |
1572 | int index, int page, int phase, |
1573 | const struct pmbus_sensor_attr *attr, |
1574 | bool paged) |
1575 | { |
1576 | struct pmbus_sensor *base; |
1577 | bool upper = !!(attr->gbit & 0xff00); /* need to check STATUS_WORD */ |
1578 | int ret; |
1579 | |
1580 | if (attr->label) { |
1581 | ret = pmbus_add_label(data, name, seq: index, lstring: attr->label, |
1582 | index: paged ? page + 1 : 0, phase); |
1583 | if (ret) |
1584 | return ret; |
1585 | } |
1586 | base = pmbus_add_sensor(data, name, type: "input", seq: index, page, phase, |
1587 | reg: attr->reg, class: attr->class, update: true, readonly: true, convert: true); |
1588 | if (!base) |
1589 | return -ENOMEM; |
1590 | /* No limit and alarm attributes for phase specific sensors */ |
1591 | if (attr->sfunc && phase == 0xff) { |
1592 | ret = pmbus_add_limit_attrs(client, data, info, name, |
1593 | index, page, base, attr); |
1594 | if (ret < 0) |
1595 | return ret; |
1596 | /* |
1597 | * Add generic alarm attribute only if there are no individual |
1598 | * alarm attributes, if there is a global alarm bit, and if |
1599 | * the generic status register (word or byte, depending on |
1600 | * which global bit is set) for this page is accessible. |
1601 | */ |
1602 | if (!ret && attr->gbit && |
1603 | (!upper || data->has_status_word) && |
1604 | pmbus_check_status_register(client, page)) { |
1605 | ret = pmbus_add_boolean(data, name, type: "alarm", seq: index, |
1606 | NULL, NULL, |
1607 | page, reg: PMBUS_STATUS_WORD, |
1608 | mask: attr->gbit); |
1609 | if (ret) |
1610 | return ret; |
1611 | } |
1612 | } |
1613 | return 0; |
1614 | } |
1615 | |
1616 | static bool pmbus_sensor_is_paged(const struct pmbus_driver_info *info, |
1617 | const struct pmbus_sensor_attr *attr) |
1618 | { |
1619 | int p; |
1620 | |
1621 | if (attr->paged) |
1622 | return true; |
1623 | |
1624 | /* |
1625 | * Some attributes may be present on more than one page despite |
1626 | * not being marked with the paged attribute. If that is the case, |
1627 | * then treat the sensor as being paged and add the page suffix to the |
1628 | * attribute name. |
1629 | * We don't just add the paged attribute to all such attributes, in |
1630 | * order to maintain the un-suffixed labels in the case where the |
1631 | * attribute is only on page 0. |
1632 | */ |
1633 | for (p = 1; p < info->pages; p++) { |
1634 | if (info->func[p] & attr->func) |
1635 | return true; |
1636 | } |
1637 | return false; |
1638 | } |
1639 | |
1640 | static int pmbus_add_sensor_attrs(struct i2c_client *client, |
1641 | struct pmbus_data *data, |
1642 | const char *name, |
1643 | const struct pmbus_sensor_attr *attrs, |
1644 | int nattrs) |
1645 | { |
1646 | const struct pmbus_driver_info *info = data->info; |
1647 | int index, i; |
1648 | int ret; |
1649 | |
1650 | index = 1; |
1651 | for (i = 0; i < nattrs; i++) { |
1652 | int page, pages; |
1653 | bool paged = pmbus_sensor_is_paged(info, attr: attrs); |
1654 | |
1655 | pages = paged ? info->pages : 1; |
1656 | for (page = 0; page < pages; page++) { |
1657 | if (info->func[page] & attrs->func) { |
1658 | ret = pmbus_add_sensor_attrs_one(client, data, info, |
1659 | name, index, page, |
1660 | phase: 0xff, attr: attrs, paged); |
1661 | if (ret) |
1662 | return ret; |
1663 | index++; |
1664 | } |
1665 | if (info->phases[page]) { |
1666 | int phase; |
1667 | |
1668 | for (phase = 0; phase < info->phases[page]; |
1669 | phase++) { |
1670 | if (!(info->pfunc[phase] & attrs->func)) |
1671 | continue; |
1672 | ret = pmbus_add_sensor_attrs_one(client, |
1673 | data, info, name, index, page, |
1674 | phase, attr: attrs, paged); |
1675 | if (ret) |
1676 | return ret; |
1677 | index++; |
1678 | } |
1679 | } |
1680 | } |
1681 | attrs++; |
1682 | } |
1683 | return 0; |
1684 | } |
1685 | |
1686 | static const struct pmbus_limit_attr vin_limit_attrs[] = { |
1687 | { |
1688 | .reg = PMBUS_VIN_UV_WARN_LIMIT, |
1689 | .attr = "min", |
1690 | .alarm = "min_alarm", |
1691 | .sbit = PB_VOLTAGE_UV_WARNING, |
1692 | }, { |
1693 | .reg = PMBUS_VIN_UV_FAULT_LIMIT, |
1694 | .attr = "lcrit", |
1695 | .alarm = "lcrit_alarm", |
1696 | .sbit = PB_VOLTAGE_UV_FAULT | PB_VOLTAGE_VIN_OFF, |
1697 | }, { |
1698 | .reg = PMBUS_VIN_OV_WARN_LIMIT, |
1699 | .attr = "max", |
1700 | .alarm = "max_alarm", |
1701 | .sbit = PB_VOLTAGE_OV_WARNING, |
1702 | }, { |
1703 | .reg = PMBUS_VIN_OV_FAULT_LIMIT, |
1704 | .attr = "crit", |
1705 | .alarm = "crit_alarm", |
1706 | .sbit = PB_VOLTAGE_OV_FAULT, |
1707 | }, { |
1708 | .reg = PMBUS_VIRT_READ_VIN_AVG, |
1709 | .update = true, |
1710 | .attr = "average", |
1711 | }, { |
1712 | .reg = PMBUS_VIRT_READ_VIN_MIN, |
1713 | .update = true, |
1714 | .attr = "lowest", |
1715 | }, { |
1716 | .reg = PMBUS_VIRT_READ_VIN_MAX, |
1717 | .update = true, |
1718 | .attr = "highest", |
1719 | }, { |
1720 | .reg = PMBUS_VIRT_RESET_VIN_HISTORY, |
1721 | .attr = "reset_history", |
1722 | }, { |
1723 | .reg = PMBUS_MFR_VIN_MIN, |
1724 | .attr = "rated_min", |
1725 | }, { |
1726 | .reg = PMBUS_MFR_VIN_MAX, |
1727 | .attr = "rated_max", |
1728 | }, |
1729 | }; |
1730 | |
1731 | static const struct pmbus_limit_attr vmon_limit_attrs[] = { |
1732 | { |
1733 | .reg = PMBUS_VIRT_VMON_UV_WARN_LIMIT, |
1734 | .attr = "min", |
1735 | .alarm = "min_alarm", |
1736 | .sbit = PB_VOLTAGE_UV_WARNING, |
1737 | }, { |
1738 | .reg = PMBUS_VIRT_VMON_UV_FAULT_LIMIT, |
1739 | .attr = "lcrit", |
1740 | .alarm = "lcrit_alarm", |
1741 | .sbit = PB_VOLTAGE_UV_FAULT, |
1742 | }, { |
1743 | .reg = PMBUS_VIRT_VMON_OV_WARN_LIMIT, |
1744 | .attr = "max", |
1745 | .alarm = "max_alarm", |
1746 | .sbit = PB_VOLTAGE_OV_WARNING, |
1747 | }, { |
1748 | .reg = PMBUS_VIRT_VMON_OV_FAULT_LIMIT, |
1749 | .attr = "crit", |
1750 | .alarm = "crit_alarm", |
1751 | .sbit = PB_VOLTAGE_OV_FAULT, |
1752 | } |
1753 | }; |
1754 | |
1755 | static const struct pmbus_limit_attr vout_limit_attrs[] = { |
1756 | { |
1757 | .reg = PMBUS_VOUT_UV_WARN_LIMIT, |
1758 | .attr = "min", |
1759 | .alarm = "min_alarm", |
1760 | .sbit = PB_VOLTAGE_UV_WARNING, |
1761 | }, { |
1762 | .reg = PMBUS_VOUT_UV_FAULT_LIMIT, |
1763 | .attr = "lcrit", |
1764 | .alarm = "lcrit_alarm", |
1765 | .sbit = PB_VOLTAGE_UV_FAULT, |
1766 | }, { |
1767 | .reg = PMBUS_VOUT_OV_WARN_LIMIT, |
1768 | .attr = "max", |
1769 | .alarm = "max_alarm", |
1770 | .sbit = PB_VOLTAGE_OV_WARNING, |
1771 | }, { |
1772 | .reg = PMBUS_VOUT_OV_FAULT_LIMIT, |
1773 | .attr = "crit", |
1774 | .alarm = "crit_alarm", |
1775 | .sbit = PB_VOLTAGE_OV_FAULT, |
1776 | }, { |
1777 | .reg = PMBUS_VIRT_READ_VOUT_AVG, |
1778 | .update = true, |
1779 | .attr = "average", |
1780 | }, { |
1781 | .reg = PMBUS_VIRT_READ_VOUT_MIN, |
1782 | .update = true, |
1783 | .attr = "lowest", |
1784 | }, { |
1785 | .reg = PMBUS_VIRT_READ_VOUT_MAX, |
1786 | .update = true, |
1787 | .attr = "highest", |
1788 | }, { |
1789 | .reg = PMBUS_VIRT_RESET_VOUT_HISTORY, |
1790 | .attr = "reset_history", |
1791 | }, { |
1792 | .reg = PMBUS_MFR_VOUT_MIN, |
1793 | .attr = "rated_min", |
1794 | }, { |
1795 | .reg = PMBUS_MFR_VOUT_MAX, |
1796 | .attr = "rated_max", |
1797 | }, |
1798 | }; |
1799 | |
1800 | static const struct pmbus_sensor_attr voltage_attributes[] = { |
1801 | { |
1802 | .reg = PMBUS_READ_VIN, |
1803 | .class = PSC_VOLTAGE_IN, |
1804 | .label = "vin", |
1805 | .func = PMBUS_HAVE_VIN, |
1806 | .sfunc = PMBUS_HAVE_STATUS_INPUT, |
1807 | .sreg = PMBUS_STATUS_INPUT, |
1808 | .gbit = PB_STATUS_VIN_UV, |
1809 | .limit = vin_limit_attrs, |
1810 | .nlimit = ARRAY_SIZE(vin_limit_attrs), |
1811 | }, { |
1812 | .reg = PMBUS_VIRT_READ_VMON, |
1813 | .class = PSC_VOLTAGE_IN, |
1814 | .label = "vmon", |
1815 | .func = PMBUS_HAVE_VMON, |
1816 | .sfunc = PMBUS_HAVE_STATUS_VMON, |
1817 | .sreg = PMBUS_VIRT_STATUS_VMON, |
1818 | .limit = vmon_limit_attrs, |
1819 | .nlimit = ARRAY_SIZE(vmon_limit_attrs), |
1820 | }, { |
1821 | .reg = PMBUS_READ_VCAP, |
1822 | .class = PSC_VOLTAGE_IN, |
1823 | .label = "vcap", |
1824 | .func = PMBUS_HAVE_VCAP, |
1825 | }, { |
1826 | .reg = PMBUS_READ_VOUT, |
1827 | .class = PSC_VOLTAGE_OUT, |
1828 | .label = "vout", |
1829 | .paged = true, |
1830 | .func = PMBUS_HAVE_VOUT, |
1831 | .sfunc = PMBUS_HAVE_STATUS_VOUT, |
1832 | .sreg = PMBUS_STATUS_VOUT, |
1833 | .gbit = PB_STATUS_VOUT_OV, |
1834 | .limit = vout_limit_attrs, |
1835 | .nlimit = ARRAY_SIZE(vout_limit_attrs), |
1836 | } |
1837 | }; |
1838 | |
1839 | /* Current attributes */ |
1840 | |
1841 | static const struct pmbus_limit_attr iin_limit_attrs[] = { |
1842 | { |
1843 | .reg = PMBUS_IIN_OC_WARN_LIMIT, |
1844 | .attr = "max", |
1845 | .alarm = "max_alarm", |
1846 | .sbit = PB_IIN_OC_WARNING, |
1847 | }, { |
1848 | .reg = PMBUS_IIN_OC_FAULT_LIMIT, |
1849 | .attr = "crit", |
1850 | .alarm = "crit_alarm", |
1851 | .sbit = PB_IIN_OC_FAULT, |
1852 | }, { |
1853 | .reg = PMBUS_VIRT_READ_IIN_AVG, |
1854 | .update = true, |
1855 | .attr = "average", |
1856 | }, { |
1857 | .reg = PMBUS_VIRT_READ_IIN_MIN, |
1858 | .update = true, |
1859 | .attr = "lowest", |
1860 | }, { |
1861 | .reg = PMBUS_VIRT_READ_IIN_MAX, |
1862 | .update = true, |
1863 | .attr = "highest", |
1864 | }, { |
1865 | .reg = PMBUS_VIRT_RESET_IIN_HISTORY, |
1866 | .attr = "reset_history", |
1867 | }, { |
1868 | .reg = PMBUS_MFR_IIN_MAX, |
1869 | .attr = "rated_max", |
1870 | }, |
1871 | }; |
1872 | |
1873 | static const struct pmbus_limit_attr iout_limit_attrs[] = { |
1874 | { |
1875 | .reg = PMBUS_IOUT_OC_WARN_LIMIT, |
1876 | .attr = "max", |
1877 | .alarm = "max_alarm", |
1878 | .sbit = PB_IOUT_OC_WARNING, |
1879 | }, { |
1880 | .reg = PMBUS_IOUT_UC_FAULT_LIMIT, |
1881 | .attr = "lcrit", |
1882 | .alarm = "lcrit_alarm", |
1883 | .sbit = PB_IOUT_UC_FAULT, |
1884 | }, { |
1885 | .reg = PMBUS_IOUT_OC_FAULT_LIMIT, |
1886 | .attr = "crit", |
1887 | .alarm = "crit_alarm", |
1888 | .sbit = PB_IOUT_OC_FAULT, |
1889 | }, { |
1890 | .reg = PMBUS_VIRT_READ_IOUT_AVG, |
1891 | .update = true, |
1892 | .attr = "average", |
1893 | }, { |
1894 | .reg = PMBUS_VIRT_READ_IOUT_MIN, |
1895 | .update = true, |
1896 | .attr = "lowest", |
1897 | }, { |
1898 | .reg = PMBUS_VIRT_READ_IOUT_MAX, |
1899 | .update = true, |
1900 | .attr = "highest", |
1901 | }, { |
1902 | .reg = PMBUS_VIRT_RESET_IOUT_HISTORY, |
1903 | .attr = "reset_history", |
1904 | }, { |
1905 | .reg = PMBUS_MFR_IOUT_MAX, |
1906 | .attr = "rated_max", |
1907 | }, |
1908 | }; |
1909 | |
1910 | static const struct pmbus_sensor_attr current_attributes[] = { |
1911 | { |
1912 | .reg = PMBUS_READ_IIN, |
1913 | .class = PSC_CURRENT_IN, |
1914 | .label = "iin", |
1915 | .func = PMBUS_HAVE_IIN, |
1916 | .sfunc = PMBUS_HAVE_STATUS_INPUT, |
1917 | .sreg = PMBUS_STATUS_INPUT, |
1918 | .gbit = PB_STATUS_INPUT, |
1919 | .limit = iin_limit_attrs, |
1920 | .nlimit = ARRAY_SIZE(iin_limit_attrs), |
1921 | }, { |
1922 | .reg = PMBUS_READ_IOUT, |
1923 | .class = PSC_CURRENT_OUT, |
1924 | .label = "iout", |
1925 | .paged = true, |
1926 | .func = PMBUS_HAVE_IOUT, |
1927 | .sfunc = PMBUS_HAVE_STATUS_IOUT, |
1928 | .sreg = PMBUS_STATUS_IOUT, |
1929 | .gbit = PB_STATUS_IOUT_OC, |
1930 | .limit = iout_limit_attrs, |
1931 | .nlimit = ARRAY_SIZE(iout_limit_attrs), |
1932 | } |
1933 | }; |
1934 | |
1935 | /* Power attributes */ |
1936 | |
1937 | static const struct pmbus_limit_attr pin_limit_attrs[] = { |
1938 | { |
1939 | .reg = PMBUS_PIN_OP_WARN_LIMIT, |
1940 | .attr = "max", |
1941 | .alarm = "alarm", |
1942 | .sbit = PB_PIN_OP_WARNING, |
1943 | }, { |
1944 | .reg = PMBUS_VIRT_READ_PIN_AVG, |
1945 | .update = true, |
1946 | .attr = "average", |
1947 | }, { |
1948 | .reg = PMBUS_VIRT_READ_PIN_MIN, |
1949 | .update = true, |
1950 | .attr = "input_lowest", |
1951 | }, { |
1952 | .reg = PMBUS_VIRT_READ_PIN_MAX, |
1953 | .update = true, |
1954 | .attr = "input_highest", |
1955 | }, { |
1956 | .reg = PMBUS_VIRT_RESET_PIN_HISTORY, |
1957 | .attr = "reset_history", |
1958 | }, { |
1959 | .reg = PMBUS_MFR_PIN_MAX, |
1960 | .attr = "rated_max", |
1961 | }, |
1962 | }; |
1963 | |
1964 | static const struct pmbus_limit_attr pout_limit_attrs[] = { |
1965 | { |
1966 | .reg = PMBUS_POUT_MAX, |
1967 | .attr = "cap", |
1968 | .alarm = "cap_alarm", |
1969 | .sbit = PB_POWER_LIMITING, |
1970 | }, { |
1971 | .reg = PMBUS_POUT_OP_WARN_LIMIT, |
1972 | .attr = "max", |
1973 | .alarm = "max_alarm", |
1974 | .sbit = PB_POUT_OP_WARNING, |
1975 | }, { |
1976 | .reg = PMBUS_POUT_OP_FAULT_LIMIT, |
1977 | .attr = "crit", |
1978 | .alarm = "crit_alarm", |
1979 | .sbit = PB_POUT_OP_FAULT, |
1980 | }, { |
1981 | .reg = PMBUS_VIRT_READ_POUT_AVG, |
1982 | .update = true, |
1983 | .attr = "average", |
1984 | }, { |
1985 | .reg = PMBUS_VIRT_READ_POUT_MIN, |
1986 | .update = true, |
1987 | .attr = "input_lowest", |
1988 | }, { |
1989 | .reg = PMBUS_VIRT_READ_POUT_MAX, |
1990 | .update = true, |
1991 | .attr = "input_highest", |
1992 | }, { |
1993 | .reg = PMBUS_VIRT_RESET_POUT_HISTORY, |
1994 | .attr = "reset_history", |
1995 | }, { |
1996 | .reg = PMBUS_MFR_POUT_MAX, |
1997 | .attr = "rated_max", |
1998 | }, |
1999 | }; |
2000 | |
2001 | static const struct pmbus_sensor_attr power_attributes[] = { |
2002 | { |
2003 | .reg = PMBUS_READ_PIN, |
2004 | .class = PSC_POWER, |
2005 | .label = "pin", |
2006 | .func = PMBUS_HAVE_PIN, |
2007 | .sfunc = PMBUS_HAVE_STATUS_INPUT, |
2008 | .sreg = PMBUS_STATUS_INPUT, |
2009 | .gbit = PB_STATUS_INPUT, |
2010 | .limit = pin_limit_attrs, |
2011 | .nlimit = ARRAY_SIZE(pin_limit_attrs), |
2012 | }, { |
2013 | .reg = PMBUS_READ_POUT, |
2014 | .class = PSC_POWER, |
2015 | .label = "pout", |
2016 | .paged = true, |
2017 | .func = PMBUS_HAVE_POUT, |
2018 | .sfunc = PMBUS_HAVE_STATUS_IOUT, |
2019 | .sreg = PMBUS_STATUS_IOUT, |
2020 | .limit = pout_limit_attrs, |
2021 | .nlimit = ARRAY_SIZE(pout_limit_attrs), |
2022 | } |
2023 | }; |
2024 | |
2025 | /* Temperature atributes */ |
2026 | |
2027 | static const struct pmbus_limit_attr temp_limit_attrs[] = { |
2028 | { |
2029 | .reg = PMBUS_UT_WARN_LIMIT, |
2030 | .low = true, |
2031 | .attr = "min", |
2032 | .alarm = "min_alarm", |
2033 | .sbit = PB_TEMP_UT_WARNING, |
2034 | }, { |
2035 | .reg = PMBUS_UT_FAULT_LIMIT, |
2036 | .low = true, |
2037 | .attr = "lcrit", |
2038 | .alarm = "lcrit_alarm", |
2039 | .sbit = PB_TEMP_UT_FAULT, |
2040 | }, { |
2041 | .reg = PMBUS_OT_WARN_LIMIT, |
2042 | .attr = "max", |
2043 | .alarm = "max_alarm", |
2044 | .sbit = PB_TEMP_OT_WARNING, |
2045 | }, { |
2046 | .reg = PMBUS_OT_FAULT_LIMIT, |
2047 | .attr = "crit", |
2048 | .alarm = "crit_alarm", |
2049 | .sbit = PB_TEMP_OT_FAULT, |
2050 | }, { |
2051 | .reg = PMBUS_VIRT_READ_TEMP_MIN, |
2052 | .attr = "lowest", |
2053 | }, { |
2054 | .reg = PMBUS_VIRT_READ_TEMP_AVG, |
2055 | .attr = "average", |
2056 | }, { |
2057 | .reg = PMBUS_VIRT_READ_TEMP_MAX, |
2058 | .attr = "highest", |
2059 | }, { |
2060 | .reg = PMBUS_VIRT_RESET_TEMP_HISTORY, |
2061 | .attr = "reset_history", |
2062 | }, { |
2063 | .reg = PMBUS_MFR_MAX_TEMP_1, |
2064 | .attr = "rated_max", |
2065 | }, |
2066 | }; |
2067 | |
2068 | static const struct pmbus_limit_attr temp_limit_attrs2[] = { |
2069 | { |
2070 | .reg = PMBUS_UT_WARN_LIMIT, |
2071 | .low = true, |
2072 | .attr = "min", |
2073 | .alarm = "min_alarm", |
2074 | .sbit = PB_TEMP_UT_WARNING, |
2075 | }, { |
2076 | .reg = PMBUS_UT_FAULT_LIMIT, |
2077 | .low = true, |
2078 | .attr = "lcrit", |
2079 | .alarm = "lcrit_alarm", |
2080 | .sbit = PB_TEMP_UT_FAULT, |
2081 | }, { |
2082 | .reg = PMBUS_OT_WARN_LIMIT, |
2083 | .attr = "max", |
2084 | .alarm = "max_alarm", |
2085 | .sbit = PB_TEMP_OT_WARNING, |
2086 | }, { |
2087 | .reg = PMBUS_OT_FAULT_LIMIT, |
2088 | .attr = "crit", |
2089 | .alarm = "crit_alarm", |
2090 | .sbit = PB_TEMP_OT_FAULT, |
2091 | }, { |
2092 | .reg = PMBUS_VIRT_READ_TEMP2_MIN, |
2093 | .attr = "lowest", |
2094 | }, { |
2095 | .reg = PMBUS_VIRT_READ_TEMP2_AVG, |
2096 | .attr = "average", |
2097 | }, { |
2098 | .reg = PMBUS_VIRT_READ_TEMP2_MAX, |
2099 | .attr = "highest", |
2100 | }, { |
2101 | .reg = PMBUS_VIRT_RESET_TEMP2_HISTORY, |
2102 | .attr = "reset_history", |
2103 | }, { |
2104 | .reg = PMBUS_MFR_MAX_TEMP_2, |
2105 | .attr = "rated_max", |
2106 | }, |
2107 | }; |
2108 | |
2109 | static const struct pmbus_limit_attr temp_limit_attrs3[] = { |
2110 | { |
2111 | .reg = PMBUS_UT_WARN_LIMIT, |
2112 | .low = true, |
2113 | .attr = "min", |
2114 | .alarm = "min_alarm", |
2115 | .sbit = PB_TEMP_UT_WARNING, |
2116 | }, { |
2117 | .reg = PMBUS_UT_FAULT_LIMIT, |
2118 | .low = true, |
2119 | .attr = "lcrit", |
2120 | .alarm = "lcrit_alarm", |
2121 | .sbit = PB_TEMP_UT_FAULT, |
2122 | }, { |
2123 | .reg = PMBUS_OT_WARN_LIMIT, |
2124 | .attr = "max", |
2125 | .alarm = "max_alarm", |
2126 | .sbit = PB_TEMP_OT_WARNING, |
2127 | }, { |
2128 | .reg = PMBUS_OT_FAULT_LIMIT, |
2129 | .attr = "crit", |
2130 | .alarm = "crit_alarm", |
2131 | .sbit = PB_TEMP_OT_FAULT, |
2132 | }, { |
2133 | .reg = PMBUS_MFR_MAX_TEMP_3, |
2134 | .attr = "rated_max", |
2135 | }, |
2136 | }; |
2137 | |
2138 | static const struct pmbus_sensor_attr temp_attributes[] = { |
2139 | { |
2140 | .reg = PMBUS_READ_TEMPERATURE_1, |
2141 | .class = PSC_TEMPERATURE, |
2142 | .paged = true, |
2143 | .update = true, |
2144 | .compare = true, |
2145 | .func = PMBUS_HAVE_TEMP, |
2146 | .sfunc = PMBUS_HAVE_STATUS_TEMP, |
2147 | .sreg = PMBUS_STATUS_TEMPERATURE, |
2148 | .gbit = PB_STATUS_TEMPERATURE, |
2149 | .limit = temp_limit_attrs, |
2150 | .nlimit = ARRAY_SIZE(temp_limit_attrs), |
2151 | }, { |
2152 | .reg = PMBUS_READ_TEMPERATURE_2, |
2153 | .class = PSC_TEMPERATURE, |
2154 | .paged = true, |
2155 | .update = true, |
2156 | .compare = true, |
2157 | .func = PMBUS_HAVE_TEMP2, |
2158 | .sfunc = PMBUS_HAVE_STATUS_TEMP, |
2159 | .sreg = PMBUS_STATUS_TEMPERATURE, |
2160 | .gbit = PB_STATUS_TEMPERATURE, |
2161 | .limit = temp_limit_attrs2, |
2162 | .nlimit = ARRAY_SIZE(temp_limit_attrs2), |
2163 | }, { |
2164 | .reg = PMBUS_READ_TEMPERATURE_3, |
2165 | .class = PSC_TEMPERATURE, |
2166 | .paged = true, |
2167 | .update = true, |
2168 | .compare = true, |
2169 | .func = PMBUS_HAVE_TEMP3, |
2170 | .sfunc = PMBUS_HAVE_STATUS_TEMP, |
2171 | .sreg = PMBUS_STATUS_TEMPERATURE, |
2172 | .gbit = PB_STATUS_TEMPERATURE, |
2173 | .limit = temp_limit_attrs3, |
2174 | .nlimit = ARRAY_SIZE(temp_limit_attrs3), |
2175 | } |
2176 | }; |
2177 | |
2178 | static const int pmbus_fan_registers[] = { |
2179 | PMBUS_READ_FAN_SPEED_1, |
2180 | PMBUS_READ_FAN_SPEED_2, |
2181 | PMBUS_READ_FAN_SPEED_3, |
2182 | PMBUS_READ_FAN_SPEED_4 |
2183 | }; |
2184 | |
2185 | static const int pmbus_fan_status_registers[] = { |
2186 | PMBUS_STATUS_FAN_12, |
2187 | PMBUS_STATUS_FAN_12, |
2188 | PMBUS_STATUS_FAN_34, |
2189 | PMBUS_STATUS_FAN_34 |
2190 | }; |
2191 | |
2192 | static const u32 pmbus_fan_flags[] = { |
2193 | PMBUS_HAVE_FAN12, |
2194 | PMBUS_HAVE_FAN12, |
2195 | PMBUS_HAVE_FAN34, |
2196 | PMBUS_HAVE_FAN34 |
2197 | }; |
2198 | |
2199 | static const u32 pmbus_fan_status_flags[] = { |
2200 | PMBUS_HAVE_STATUS_FAN12, |
2201 | PMBUS_HAVE_STATUS_FAN12, |
2202 | PMBUS_HAVE_STATUS_FAN34, |
2203 | PMBUS_HAVE_STATUS_FAN34 |
2204 | }; |
2205 | |
2206 | /* Fans */ |
2207 | |
2208 | /* Precondition: FAN_CONFIG_x_y and FAN_COMMAND_x must exist for the fan ID */ |
2209 | static int pmbus_add_fan_ctrl(struct i2c_client *client, |
2210 | struct pmbus_data *data, int index, int page, |
2211 | int id, u8 config) |
2212 | { |
2213 | struct pmbus_sensor *sensor; |
2214 | |
2215 | sensor = pmbus_add_sensor(data, name: "fan", type: "target", seq: index, page, |
2216 | phase: 0xff, reg: PMBUS_VIRT_FAN_TARGET_1 + id, class: PSC_FAN, |
2217 | update: false, readonly: false, convert: true); |
2218 | |
2219 | if (!sensor) |
2220 | return -ENOMEM; |
2221 | |
2222 | if (!((data->info->func[page] & PMBUS_HAVE_PWM12) || |
2223 | (data->info->func[page] & PMBUS_HAVE_PWM34))) |
2224 | return 0; |
2225 | |
2226 | sensor = pmbus_add_sensor(data, name: "pwm", NULL, seq: index, page, |
2227 | phase: 0xff, reg: PMBUS_VIRT_PWM_1 + id, class: PSC_PWM, |
2228 | update: false, readonly: false, convert: true); |
2229 | |
2230 | if (!sensor) |
2231 | return -ENOMEM; |
2232 | |
2233 | sensor = pmbus_add_sensor(data, name: "pwm", type: "enable", seq: index, page, |
2234 | phase: 0xff, reg: PMBUS_VIRT_PWM_ENABLE_1 + id, class: PSC_PWM, |
2235 | update: true, readonly: false, convert: false); |
2236 | |
2237 | if (!sensor) |
2238 | return -ENOMEM; |
2239 | |
2240 | return 0; |
2241 | } |
2242 | |
2243 | static int pmbus_add_fan_attributes(struct i2c_client *client, |
2244 | struct pmbus_data *data) |
2245 | { |
2246 | const struct pmbus_driver_info *info = data->info; |
2247 | int index = 1; |
2248 | int page; |
2249 | int ret; |
2250 | |
2251 | for (page = 0; page < info->pages; page++) { |
2252 | int f; |
2253 | |
2254 | for (f = 0; f < ARRAY_SIZE(pmbus_fan_registers); f++) { |
2255 | int regval; |
2256 | |
2257 | if (!(info->func[page] & pmbus_fan_flags[f])) |
2258 | break; |
2259 | |
2260 | if (!pmbus_check_word_register(client, page, |
2261 | pmbus_fan_registers[f])) |
2262 | break; |
2263 | |
2264 | /* |
2265 | * Skip fan if not installed. |
2266 | * Each fan configuration register covers multiple fans, |
2267 | * so we have to do some magic. |
2268 | */ |
2269 | regval = _pmbus_read_byte_data(client, page, |
2270 | reg: pmbus_fan_config_registers[f]); |
2271 | if (regval < 0 || |
2272 | (!(regval & (PB_FAN_1_INSTALLED >> ((f & 1) * 4))))) |
2273 | continue; |
2274 | |
2275 | if (pmbus_add_sensor(data, name: "fan", type: "input", seq: index, |
2276 | page, phase: 0xff, reg: pmbus_fan_registers[f], |
2277 | class: PSC_FAN, update: true, readonly: true, convert: true) == NULL) |
2278 | return -ENOMEM; |
2279 | |
2280 | /* Fan control */ |
2281 | if (pmbus_check_word_register(client, page, |
2282 | pmbus_fan_command_registers[f])) { |
2283 | ret = pmbus_add_fan_ctrl(client, data, index, |
2284 | page, id: f, config: regval); |
2285 | if (ret < 0) |
2286 | return ret; |
2287 | } |
2288 | |
2289 | /* |
2290 | * Each fan status register covers multiple fans, |
2291 | * so we have to do some magic. |
2292 | */ |
2293 | if ((info->func[page] & pmbus_fan_status_flags[f]) && |
2294 | pmbus_check_byte_register(client, |
2295 | page, pmbus_fan_status_registers[f])) { |
2296 | int reg; |
2297 | |
2298 | if (f > 1) /* fan 3, 4 */ |
2299 | reg = PMBUS_STATUS_FAN_34; |
2300 | else |
2301 | reg = PMBUS_STATUS_FAN_12; |
2302 | ret = pmbus_add_boolean(data, name: "fan", |
2303 | type: "alarm", seq: index, NULL, NULL, page, reg, |
2304 | PB_FAN_FAN1_WARNING >> (f & 1)); |
2305 | if (ret) |
2306 | return ret; |
2307 | ret = pmbus_add_boolean(data, name: "fan", |
2308 | type: "fault", seq: index, NULL, NULL, page, reg, |
2309 | PB_FAN_FAN1_FAULT >> (f & 1)); |
2310 | if (ret) |
2311 | return ret; |
2312 | } |
2313 | index++; |
2314 | } |
2315 | } |
2316 | return 0; |
2317 | } |
2318 | |
2319 | struct pmbus_samples_attr { |
2320 | int reg; |
2321 | char *name; |
2322 | }; |
2323 | |
2324 | struct pmbus_samples_reg { |
2325 | int page; |
2326 | struct pmbus_samples_attr *attr; |
2327 | struct device_attribute dev_attr; |
2328 | }; |
2329 | |
2330 | static struct pmbus_samples_attr pmbus_samples_registers[] = { |
2331 | { |
2332 | .reg = PMBUS_VIRT_SAMPLES, |
2333 | .name = "samples", |
2334 | }, { |
2335 | .reg = PMBUS_VIRT_IN_SAMPLES, |
2336 | .name = "in_samples", |
2337 | }, { |
2338 | .reg = PMBUS_VIRT_CURR_SAMPLES, |
2339 | .name = "curr_samples", |
2340 | }, { |
2341 | .reg = PMBUS_VIRT_POWER_SAMPLES, |
2342 | .name = "power_samples", |
2343 | }, { |
2344 | .reg = PMBUS_VIRT_TEMP_SAMPLES, |
2345 | .name = "temp_samples", |
2346 | } |
2347 | }; |
2348 | |
2349 | #define to_samples_reg(x) container_of(x, struct pmbus_samples_reg, dev_attr) |
2350 | |
2351 | static ssize_t pmbus_show_samples(struct device *dev, |
2352 | struct device_attribute *devattr, char *buf) |
2353 | { |
2354 | int val; |
2355 | struct i2c_client *client = to_i2c_client(dev->parent); |
2356 | struct pmbus_samples_reg *reg = to_samples_reg(devattr); |
2357 | struct pmbus_data *data = i2c_get_clientdata(client); |
2358 | |
2359 | mutex_lock(&data->update_lock); |
2360 | val = _pmbus_read_word_data(client, page: reg->page, phase: 0xff, reg: reg->attr->reg); |
2361 | mutex_unlock(lock: &data->update_lock); |
2362 | if (val < 0) |
2363 | return val; |
2364 | |
2365 | return sysfs_emit(buf, fmt: "%d\n", val); |
2366 | } |
2367 | |
2368 | static ssize_t pmbus_set_samples(struct device *dev, |
2369 | struct device_attribute *devattr, |
2370 | const char *buf, size_t count) |
2371 | { |
2372 | int ret; |
2373 | long val; |
2374 | struct i2c_client *client = to_i2c_client(dev->parent); |
2375 | struct pmbus_samples_reg *reg = to_samples_reg(devattr); |
2376 | struct pmbus_data *data = i2c_get_clientdata(client); |
2377 | |
2378 | if (kstrtol(s: buf, base: 0, res: &val) < 0) |
2379 | return -EINVAL; |
2380 | |
2381 | mutex_lock(&data->update_lock); |
2382 | ret = _pmbus_write_word_data(client, page: reg->page, reg: reg->attr->reg, word: val); |
2383 | mutex_unlock(lock: &data->update_lock); |
2384 | |
2385 | return ret ? : count; |
2386 | } |
2387 | |
2388 | static int pmbus_add_samples_attr(struct pmbus_data *data, int page, |
2389 | struct pmbus_samples_attr *attr) |
2390 | { |
2391 | struct pmbus_samples_reg *reg; |
2392 | |
2393 | reg = devm_kzalloc(dev: data->dev, size: sizeof(*reg), GFP_KERNEL); |
2394 | if (!reg) |
2395 | return -ENOMEM; |
2396 | |
2397 | reg->attr = attr; |
2398 | reg->page = page; |
2399 | |
2400 | pmbus_dev_attr_init(dev_attr: ®->dev_attr, name: attr->name, mode: 0644, |
2401 | show: pmbus_show_samples, store: pmbus_set_samples); |
2402 | |
2403 | return pmbus_add_attribute(data, attr: ®->dev_attr.attr); |
2404 | } |
2405 | |
2406 | static int pmbus_add_samples_attributes(struct i2c_client *client, |
2407 | struct pmbus_data *data) |
2408 | { |
2409 | const struct pmbus_driver_info *info = data->info; |
2410 | int s; |
2411 | |
2412 | if (!(info->func[0] & PMBUS_HAVE_SAMPLES)) |
2413 | return 0; |
2414 | |
2415 | for (s = 0; s < ARRAY_SIZE(pmbus_samples_registers); s++) { |
2416 | struct pmbus_samples_attr *attr; |
2417 | int ret; |
2418 | |
2419 | attr = &pmbus_samples_registers[s]; |
2420 | if (!pmbus_check_word_register(client, 0, attr->reg)) |
2421 | continue; |
2422 | |
2423 | ret = pmbus_add_samples_attr(data, page: 0, attr); |
2424 | if (ret) |
2425 | return ret; |
2426 | } |
2427 | |
2428 | return 0; |
2429 | } |
2430 | |
2431 | static int pmbus_find_attributes(struct i2c_client *client, |
2432 | struct pmbus_data *data) |
2433 | { |
2434 | int ret; |
2435 | |
2436 | /* Voltage sensors */ |
2437 | ret = pmbus_add_sensor_attrs(client, data, name: "in", attrs: voltage_attributes, |
2438 | ARRAY_SIZE(voltage_attributes)); |
2439 | if (ret) |
2440 | return ret; |
2441 | |
2442 | /* Current sensors */ |
2443 | ret = pmbus_add_sensor_attrs(client, data, name: "curr", attrs: current_attributes, |
2444 | ARRAY_SIZE(current_attributes)); |
2445 | if (ret) |
2446 | return ret; |
2447 | |
2448 | /* Power sensors */ |
2449 | ret = pmbus_add_sensor_attrs(client, data, name: "power", attrs: power_attributes, |
2450 | ARRAY_SIZE(power_attributes)); |
2451 | if (ret) |
2452 | return ret; |
2453 | |
2454 | /* Temperature sensors */ |
2455 | ret = pmbus_add_sensor_attrs(client, data, name: "temp", attrs: temp_attributes, |
2456 | ARRAY_SIZE(temp_attributes)); |
2457 | if (ret) |
2458 | return ret; |
2459 | |
2460 | /* Fans */ |
2461 | ret = pmbus_add_fan_attributes(client, data); |
2462 | if (ret) |
2463 | return ret; |
2464 | |
2465 | ret = pmbus_add_samples_attributes(client, data); |
2466 | return ret; |
2467 | } |
2468 | |
2469 | /* |
2470 | * The pmbus_class_attr_map structure maps one sensor class to |
2471 | * it's corresponding sensor attributes array. |
2472 | */ |
2473 | struct pmbus_class_attr_map { |
2474 | enum pmbus_sensor_classes class; |
2475 | int nattr; |
2476 | const struct pmbus_sensor_attr *attr; |
2477 | }; |
2478 | |
2479 | static const struct pmbus_class_attr_map class_attr_map[] = { |
2480 | { |
2481 | .class = PSC_VOLTAGE_IN, |
2482 | .attr = voltage_attributes, |
2483 | .nattr = ARRAY_SIZE(voltage_attributes), |
2484 | }, { |
2485 | .class = PSC_VOLTAGE_OUT, |
2486 | .attr = voltage_attributes, |
2487 | .nattr = ARRAY_SIZE(voltage_attributes), |
2488 | }, { |
2489 | .class = PSC_CURRENT_IN, |
2490 | .attr = current_attributes, |
2491 | .nattr = ARRAY_SIZE(current_attributes), |
2492 | }, { |
2493 | .class = PSC_CURRENT_OUT, |
2494 | .attr = current_attributes, |
2495 | .nattr = ARRAY_SIZE(current_attributes), |
2496 | }, { |
2497 | .class = PSC_POWER, |
2498 | .attr = power_attributes, |
2499 | .nattr = ARRAY_SIZE(power_attributes), |
2500 | }, { |
2501 | .class = PSC_TEMPERATURE, |
2502 | .attr = temp_attributes, |
2503 | .nattr = ARRAY_SIZE(temp_attributes), |
2504 | } |
2505 | }; |
2506 | |
2507 | /* |
2508 | * Read the coefficients for direct mode. |
2509 | */ |
2510 | static int pmbus_read_coefficients(struct i2c_client *client, |
2511 | struct pmbus_driver_info *info, |
2512 | const struct pmbus_sensor_attr *attr) |
2513 | { |
2514 | int rv; |
2515 | union i2c_smbus_data data; |
2516 | enum pmbus_sensor_classes class = attr->class; |
2517 | s8 R; |
2518 | s16 m, b; |
2519 | |
2520 | data.block[0] = 2; |
2521 | data.block[1] = attr->reg; |
2522 | data.block[2] = 0x01; |
2523 | |
2524 | pmbus_wait(client); |
2525 | rv = i2c_smbus_xfer(adapter: client->adapter, addr: client->addr, flags: client->flags, |
2526 | I2C_SMBUS_WRITE, command: PMBUS_COEFFICIENTS, |
2527 | I2C_SMBUS_BLOCK_PROC_CALL, data: &data); |
2528 | pmbus_update_ts(client, PMBUS_OP_WRITE); |
2529 | |
2530 | if (rv < 0) |
2531 | return rv; |
2532 | |
2533 | if (data.block[0] != 5) |
2534 | return -EIO; |
2535 | |
2536 | m = data.block[1] | (data.block[2] << 8); |
2537 | b = data.block[3] | (data.block[4] << 8); |
2538 | R = data.block[5]; |
2539 | info->m[class] = m; |
2540 | info->b[class] = b; |
2541 | info->R[class] = R; |
2542 | |
2543 | return rv; |
2544 | } |
2545 | |
2546 | static int pmbus_init_coefficients(struct i2c_client *client, |
2547 | struct pmbus_driver_info *info) |
2548 | { |
2549 | int i, n, ret = -EINVAL; |
2550 | const struct pmbus_class_attr_map *map; |
2551 | const struct pmbus_sensor_attr *attr; |
2552 | |
2553 | for (i = 0; i < ARRAY_SIZE(class_attr_map); i++) { |
2554 | map = &class_attr_map[i]; |
2555 | if (info->format[map->class] != direct) |
2556 | continue; |
2557 | for (n = 0; n < map->nattr; n++) { |
2558 | attr = &map->attr[n]; |
2559 | if (map->class != attr->class) |
2560 | continue; |
2561 | ret = pmbus_read_coefficients(client, info, attr); |
2562 | if (ret >= 0) |
2563 | break; |
2564 | } |
2565 | if (ret < 0) { |
2566 | dev_err(&client->dev, |
2567 | "No coefficients found for sensor class %d\n", |
2568 | map->class); |
2569 | return -EINVAL; |
2570 | } |
2571 | } |
2572 | |
2573 | return 0; |
2574 | } |
2575 | |
2576 | /* |
2577 | * Identify chip parameters. |
2578 | * This function is called for all chips. |
2579 | */ |
2580 | static int pmbus_identify_common(struct i2c_client *client, |
2581 | struct pmbus_data *data, int page) |
2582 | { |
2583 | int vout_mode = -1; |
2584 | |
2585 | if (pmbus_check_byte_register(client, page, PMBUS_VOUT_MODE)) |
2586 | vout_mode = _pmbus_read_byte_data(client, page, |
2587 | reg: PMBUS_VOUT_MODE); |
2588 | if (vout_mode >= 0 && vout_mode != 0xff) { |
2589 | /* |
2590 | * Not all chips support the VOUT_MODE command, |
2591 | * so a failure to read it is not an error. |
2592 | */ |
2593 | switch (vout_mode >> 5) { |
2594 | case 0: /* linear mode */ |
2595 | if (data->info->format[PSC_VOLTAGE_OUT] != linear) |
2596 | return -ENODEV; |
2597 | |
2598 | data->exponent[page] = ((s8)(vout_mode << 3)) >> 3; |
2599 | break; |
2600 | case 1: /* VID mode */ |
2601 | if (data->info->format[PSC_VOLTAGE_OUT] != vid) |
2602 | return -ENODEV; |
2603 | break; |
2604 | case 2: /* direct mode */ |
2605 | if (data->info->format[PSC_VOLTAGE_OUT] != direct) |
2606 | return -ENODEV; |
2607 | break; |
2608 | case 3: /* ieee 754 half precision */ |
2609 | if (data->info->format[PSC_VOLTAGE_OUT] != ieee754) |
2610 | return -ENODEV; |
2611 | break; |
2612 | default: |
2613 | return -ENODEV; |
2614 | } |
2615 | } |
2616 | |
2617 | return 0; |
2618 | } |
2619 | |
2620 | static int pmbus_read_status_byte(struct i2c_client *client, int page) |
2621 | { |
2622 | return _pmbus_read_byte_data(client, page, reg: PMBUS_STATUS_BYTE); |
2623 | } |
2624 | |
2625 | static int pmbus_read_status_word(struct i2c_client *client, int page) |
2626 | { |
2627 | return _pmbus_read_word_data(client, page, phase: 0xff, reg: PMBUS_STATUS_WORD); |
2628 | } |
2629 | |
2630 | /* PEC attribute support */ |
2631 | |
2632 | static ssize_t pec_show(struct device *dev, struct device_attribute *dummy, |
2633 | char *buf) |
2634 | { |
2635 | struct i2c_client *client = to_i2c_client(dev); |
2636 | |
2637 | return sysfs_emit(buf, fmt: "%d\n", !!(client->flags & I2C_CLIENT_PEC)); |
2638 | } |
2639 | |
2640 | static ssize_t pec_store(struct device *dev, struct device_attribute *dummy, |
2641 | const char *buf, size_t count) |
2642 | { |
2643 | struct i2c_client *client = to_i2c_client(dev); |
2644 | bool enable; |
2645 | int err; |
2646 | |
2647 | err = kstrtobool(s: buf, res: &enable); |
2648 | if (err < 0) |
2649 | return err; |
2650 | |
2651 | if (enable) |
2652 | client->flags |= I2C_CLIENT_PEC; |
2653 | else |
2654 | client->flags &= ~I2C_CLIENT_PEC; |
2655 | |
2656 | return count; |
2657 | } |
2658 | |
2659 | static DEVICE_ATTR_RW(pec); |
2660 | |
2661 | static void pmbus_remove_pec(void *dev) |
2662 | { |
2663 | device_remove_file(dev, attr: &dev_attr_pec); |
2664 | } |
2665 | |
2666 | static void pmbus_init_wp(struct i2c_client *client, struct pmbus_data *data) |
2667 | { |
2668 | int ret; |
2669 | |
2670 | switch (wp) { |
2671 | case 0: |
2672 | _pmbus_write_byte_data(client, page: -1, |
2673 | reg: PMBUS_WRITE_PROTECT, value: 0); |
2674 | break; |
2675 | |
2676 | case 1: |
2677 | _pmbus_write_byte_data(client, page: -1, |
2678 | reg: PMBUS_WRITE_PROTECT, PB_WP_VOUT); |
2679 | break; |
2680 | |
2681 | case 2: |
2682 | _pmbus_write_byte_data(client, page: -1, |
2683 | reg: PMBUS_WRITE_PROTECT, PB_WP_OP); |
2684 | break; |
2685 | |
2686 | case 3: |
2687 | _pmbus_write_byte_data(client, page: -1, |
2688 | reg: PMBUS_WRITE_PROTECT, PB_WP_ALL); |
2689 | break; |
2690 | |
2691 | default: |
2692 | /* Ignore the other values */ |
2693 | break; |
2694 | } |
2695 | |
2696 | ret = _pmbus_read_byte_data(client, page: -1, reg: PMBUS_WRITE_PROTECT); |
2697 | if (ret < 0) |
2698 | return; |
2699 | |
2700 | switch (ret & PB_WP_ANY) { |
2701 | case PB_WP_ALL: |
2702 | data->flags |= PMBUS_OP_PROTECTED; |
2703 | fallthrough; |
2704 | case PB_WP_OP: |
2705 | data->flags |= PMBUS_VOUT_PROTECTED; |
2706 | fallthrough; |
2707 | case PB_WP_VOUT: |
2708 | data->flags |= PMBUS_WRITE_PROTECTED | PMBUS_SKIP_STATUS_CHECK; |
2709 | break; |
2710 | |
2711 | default: |
2712 | break; |
2713 | } |
2714 | } |
2715 | |
2716 | static int pmbus_init_common(struct i2c_client *client, struct pmbus_data *data, |
2717 | struct pmbus_driver_info *info) |
2718 | { |
2719 | struct device *dev = &client->dev; |
2720 | int page, ret; |
2721 | |
2722 | /* |
2723 | * Figure out if PEC is enabled before accessing any other register. |
2724 | * Make sure PEC is disabled, will be enabled later if needed. |
2725 | */ |
2726 | client->flags &= ~I2C_CLIENT_PEC; |
2727 | |
2728 | /* Enable PEC if the controller and bus supports it */ |
2729 | if (!(data->flags & PMBUS_NO_CAPABILITY)) { |
2730 | pmbus_wait(client); |
2731 | ret = i2c_smbus_read_byte_data(client, command: PMBUS_CAPABILITY); |
2732 | pmbus_update_ts(client, op: 0); |
2733 | |
2734 | if (ret >= 0 && (ret & PB_CAPABILITY_ERROR_CHECK)) { |
2735 | if (i2c_check_functionality(adap: client->adapter, I2C_FUNC_SMBUS_PEC)) |
2736 | client->flags |= I2C_CLIENT_PEC; |
2737 | } |
2738 | } |
2739 | |
2740 | /* |
2741 | * Some PMBus chips don't support PMBUS_STATUS_WORD, so try |
2742 | * to use PMBUS_STATUS_BYTE instead if that is the case. |
2743 | * Bail out if both registers are not supported. |
2744 | */ |
2745 | data->read_status = pmbus_read_status_word; |
2746 | pmbus_wait(client); |
2747 | ret = i2c_smbus_read_word_data(client, command: PMBUS_STATUS_WORD); |
2748 | pmbus_update_ts(client, op: 0); |
2749 | |
2750 | if (ret < 0 || ret == 0xffff) { |
2751 | data->read_status = pmbus_read_status_byte; |
2752 | pmbus_wait(client); |
2753 | ret = i2c_smbus_read_byte_data(client, command: PMBUS_STATUS_BYTE); |
2754 | pmbus_update_ts(client, op: 0); |
2755 | |
2756 | if (ret < 0 || ret == 0xff) { |
2757 | dev_err(dev, "PMBus status register not found\n"); |
2758 | return -ENODEV; |
2759 | } |
2760 | } else { |
2761 | data->has_status_word = true; |
2762 | } |
2763 | |
2764 | /* |
2765 | * Check if the chip is write protected. If it is, we can not clear |
2766 | * faults, and we should not try it. Also, in that case, writes into |
2767 | * limit registers need to be disabled. |
2768 | */ |
2769 | if (!(data->flags & PMBUS_NO_WRITE_PROTECT)) |
2770 | pmbus_init_wp(client, data); |
2771 | |
2772 | ret = i2c_smbus_read_byte_data(client, command: PMBUS_REVISION); |
2773 | if (ret >= 0) |
2774 | data->revision = ret; |
2775 | |
2776 | if (data->info->pages) |
2777 | pmbus_clear_faults(client); |
2778 | else |
2779 | pmbus_clear_fault_page(client, page: -1); |
2780 | |
2781 | if (info->identify) { |
2782 | ret = (*info->identify)(client, info); |
2783 | if (ret < 0) { |
2784 | dev_err(dev, "Chip identification failed\n"); |
2785 | return ret; |
2786 | } |
2787 | } |
2788 | |
2789 | if (info->pages <= 0 || info->pages > PMBUS_PAGES) { |
2790 | dev_err(dev, "Bad number of PMBus pages: %d\n", info->pages); |
2791 | return -ENODEV; |
2792 | } |
2793 | |
2794 | for (page = 0; page < info->pages; page++) { |
2795 | ret = pmbus_identify_common(client, data, page); |
2796 | if (ret < 0) { |
2797 | dev_err(dev, "Failed to identify chip capabilities\n"); |
2798 | return ret; |
2799 | } |
2800 | } |
2801 | |
2802 | if (data->flags & PMBUS_USE_COEFFICIENTS_CMD) { |
2803 | if (!i2c_check_functionality(adap: client->adapter, |
2804 | I2C_FUNC_SMBUS_BLOCK_PROC_CALL)) |
2805 | return -ENODEV; |
2806 | |
2807 | ret = pmbus_init_coefficients(client, info); |
2808 | if (ret < 0) |
2809 | return ret; |
2810 | } |
2811 | |
2812 | if (client->flags & I2C_CLIENT_PEC) { |
2813 | /* |
2814 | * If I2C_CLIENT_PEC is set here, both the I2C adapter and the |
2815 | * chip support PEC. Add 'pec' attribute to client device to let |
2816 | * the user control it. |
2817 | */ |
2818 | ret = device_create_file(device: dev, entry: &dev_attr_pec); |
2819 | if (ret) |
2820 | return ret; |
2821 | ret = devm_add_action_or_reset(dev, pmbus_remove_pec, dev); |
2822 | if (ret) |
2823 | return ret; |
2824 | } |
2825 | |
2826 | return 0; |
2827 | } |
2828 | |
2829 | /* A PMBus status flag and the corresponding REGULATOR_ERROR_* and REGULATOR_EVENTS_* flag */ |
2830 | struct pmbus_status_assoc { |
2831 | int pflag, rflag, eflag; |
2832 | }; |
2833 | |
2834 | /* PMBus->regulator bit mappings for a PMBus status register */ |
2835 | struct pmbus_status_category { |
2836 | int func; |
2837 | int reg; |
2838 | const struct pmbus_status_assoc *bits; /* zero-terminated */ |
2839 | }; |
2840 | |
2841 | static const struct pmbus_status_category __maybe_unused pmbus_status_flag_map[] = { |
2842 | { |
2843 | .func = PMBUS_HAVE_STATUS_VOUT, |
2844 | .reg = PMBUS_STATUS_VOUT, |
2845 | .bits = (const struct pmbus_status_assoc[]) { |
2846 | { PB_VOLTAGE_UV_WARNING, REGULATOR_ERROR_UNDER_VOLTAGE_WARN, |
2847 | REGULATOR_EVENT_UNDER_VOLTAGE_WARN }, |
2848 | { PB_VOLTAGE_UV_FAULT, REGULATOR_ERROR_UNDER_VOLTAGE, |
2849 | REGULATOR_EVENT_UNDER_VOLTAGE }, |
2850 | { PB_VOLTAGE_OV_WARNING, REGULATOR_ERROR_OVER_VOLTAGE_WARN, |
2851 | REGULATOR_EVENT_OVER_VOLTAGE_WARN }, |
2852 | { PB_VOLTAGE_OV_FAULT, REGULATOR_ERROR_REGULATION_OUT, |
2853 | REGULATOR_EVENT_OVER_VOLTAGE_WARN }, |
2854 | { }, |
2855 | }, |
2856 | }, { |
2857 | .func = PMBUS_HAVE_STATUS_IOUT, |
2858 | .reg = PMBUS_STATUS_IOUT, |
2859 | .bits = (const struct pmbus_status_assoc[]) { |
2860 | { PB_IOUT_OC_WARNING, REGULATOR_ERROR_OVER_CURRENT_WARN, |
2861 | REGULATOR_EVENT_OVER_CURRENT_WARN }, |
2862 | { PB_IOUT_OC_FAULT, REGULATOR_ERROR_OVER_CURRENT, |
2863 | REGULATOR_EVENT_OVER_CURRENT }, |
2864 | { PB_IOUT_OC_LV_FAULT, REGULATOR_ERROR_OVER_CURRENT, |
2865 | REGULATOR_EVENT_OVER_CURRENT }, |
2866 | { }, |
2867 | }, |
2868 | }, { |
2869 | .func = PMBUS_HAVE_STATUS_TEMP, |
2870 | .reg = PMBUS_STATUS_TEMPERATURE, |
2871 | .bits = (const struct pmbus_status_assoc[]) { |
2872 | { PB_TEMP_OT_WARNING, REGULATOR_ERROR_OVER_TEMP_WARN, |
2873 | REGULATOR_EVENT_OVER_TEMP_WARN }, |
2874 | { PB_TEMP_OT_FAULT, REGULATOR_ERROR_OVER_TEMP, |
2875 | REGULATOR_EVENT_OVER_TEMP }, |
2876 | { }, |
2877 | }, |
2878 | }, |
2879 | }; |
2880 | |
2881 | static int _pmbus_is_enabled(struct i2c_client *client, u8 page) |
2882 | { |
2883 | int ret; |
2884 | |
2885 | ret = _pmbus_read_byte_data(client, page, reg: PMBUS_OPERATION); |
2886 | |
2887 | if (ret < 0) |
2888 | return ret; |
2889 | |
2890 | return !!(ret & PB_OPERATION_CONTROL_ON); |
2891 | } |
2892 | |
2893 | static int __maybe_unused pmbus_is_enabled(struct i2c_client *client, u8 page) |
2894 | { |
2895 | struct pmbus_data *data = i2c_get_clientdata(client); |
2896 | int ret; |
2897 | |
2898 | mutex_lock(&data->update_lock); |
2899 | ret = _pmbus_is_enabled(client, page); |
2900 | mutex_unlock(lock: &data->update_lock); |
2901 | |
2902 | return ret; |
2903 | } |
2904 | |
2905 | #define to_dev_attr(_dev_attr) \ |
2906 | container_of(_dev_attr, struct device_attribute, attr) |
2907 | |
2908 | static void pmbus_notify(struct pmbus_data *data, int page, int reg, int flags) |
2909 | { |
2910 | int i; |
2911 | |
2912 | for (i = 0; i < data->num_attributes; i++) { |
2913 | struct device_attribute *da = to_dev_attr(data->group.attrs[i]); |
2914 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); |
2915 | int index = attr->index; |
2916 | u16 smask = pb_index_to_mask(index); |
2917 | u8 spage = pb_index_to_page(index); |
2918 | u16 sreg = pb_index_to_reg(index); |
2919 | |
2920 | if (reg == sreg && page == spage && (smask & flags)) { |
2921 | dev_dbg(data->dev, "sysfs notify: %s", da->attr.name); |
2922 | sysfs_notify(kobj: &data->dev->kobj, NULL, attr: da->attr.name); |
2923 | kobject_uevent(kobj: &data->dev->kobj, action: KOBJ_CHANGE); |
2924 | flags &= ~smask; |
2925 | } |
2926 | |
2927 | if (!flags) |
2928 | break; |
2929 | } |
2930 | } |
2931 | |
2932 | static int _pmbus_get_flags(struct pmbus_data *data, u8 page, unsigned int *flags, |
2933 | unsigned int *event, bool notify) |
2934 | { |
2935 | int i, status; |
2936 | const struct pmbus_status_category *cat; |
2937 | const struct pmbus_status_assoc *bit; |
2938 | struct device *dev = data->dev; |
2939 | struct i2c_client *client = to_i2c_client(dev); |
2940 | int func = data->info->func[page]; |
2941 | |
2942 | *flags = 0; |
2943 | *event = 0; |
2944 | |
2945 | for (i = 0; i < ARRAY_SIZE(pmbus_status_flag_map); i++) { |
2946 | cat = &pmbus_status_flag_map[i]; |
2947 | if (!(func & cat->func)) |
2948 | continue; |
2949 | |
2950 | status = _pmbus_read_byte_data(client, page, reg: cat->reg); |
2951 | if (status < 0) |
2952 | return status; |
2953 | |
2954 | for (bit = cat->bits; bit->pflag; bit++) |
2955 | if (status & bit->pflag) { |
2956 | *flags |= bit->rflag; |
2957 | *event |= bit->eflag; |
2958 | } |
2959 | |
2960 | if (notify && status) |
2961 | pmbus_notify(data, page, reg: cat->reg, flags: status); |
2962 | } |
2963 | |
2964 | /* |
2965 | * Map what bits of STATUS_{WORD,BYTE} we can to REGULATOR_ERROR_* |
2966 | * bits. Some of the other bits are tempting (especially for cases |
2967 | * where we don't have the relevant PMBUS_HAVE_STATUS_* |
2968 | * functionality), but there's an unfortunate ambiguity in that |
2969 | * they're defined as indicating a fault *or* a warning, so we can't |
2970 | * easily determine whether to report REGULATOR_ERROR_<foo> or |
2971 | * REGULATOR_ERROR_<foo>_WARN. |
2972 | */ |
2973 | status = pmbus_get_status(client, page, reg: PMBUS_STATUS_WORD); |
2974 | if (status < 0) |
2975 | return status; |
2976 | |
2977 | if (_pmbus_is_enabled(client, page)) { |
2978 | if (status & PB_STATUS_OFF) { |
2979 | *flags |= REGULATOR_ERROR_FAIL; |
2980 | *event |= REGULATOR_EVENT_FAIL; |
2981 | } |
2982 | |
2983 | if (status & PB_STATUS_POWER_GOOD_N) { |
2984 | *flags |= REGULATOR_ERROR_REGULATION_OUT; |
2985 | *event |= REGULATOR_EVENT_REGULATION_OUT; |
2986 | } |
2987 | } |
2988 | /* |
2989 | * Unlike most other status bits, PB_STATUS_{IOUT_OC,VOUT_OV} are |
2990 | * defined strictly as fault indicators (not warnings). |
2991 | */ |
2992 | if (status & PB_STATUS_IOUT_OC) { |
2993 | *flags |= REGULATOR_ERROR_OVER_CURRENT; |
2994 | *event |= REGULATOR_EVENT_OVER_CURRENT; |
2995 | } |
2996 | if (status & PB_STATUS_VOUT_OV) { |
2997 | *flags |= REGULATOR_ERROR_REGULATION_OUT; |
2998 | *event |= REGULATOR_EVENT_FAIL; |
2999 | } |
3000 | |
3001 | /* |
3002 | * If we haven't discovered any thermal faults or warnings via |
3003 | * PMBUS_STATUS_TEMPERATURE, map PB_STATUS_TEMPERATURE to a warning as |
3004 | * a (conservative) best-effort interpretation. |
3005 | */ |
3006 | if (!(*flags & (REGULATOR_ERROR_OVER_TEMP | REGULATOR_ERROR_OVER_TEMP_WARN)) && |
3007 | (status & PB_STATUS_TEMPERATURE)) { |
3008 | *flags |= REGULATOR_ERROR_OVER_TEMP_WARN; |
3009 | *event |= REGULATOR_EVENT_OVER_TEMP_WARN; |
3010 | } |
3011 | |
3012 | return 0; |
3013 | } |
3014 | |
3015 | static int __maybe_unused pmbus_get_flags(struct pmbus_data *data, u8 page, unsigned int *flags, |
3016 | unsigned int *event, bool notify) |
3017 | { |
3018 | int ret; |
3019 | |
3020 | mutex_lock(&data->update_lock); |
3021 | ret = _pmbus_get_flags(data, page, flags, event, notify); |
3022 | mutex_unlock(lock: &data->update_lock); |
3023 | |
3024 | return ret; |
3025 | } |
3026 | |
3027 | #if IS_ENABLED(CONFIG_REGULATOR) |
3028 | static int pmbus_regulator_is_enabled(struct regulator_dev *rdev) |
3029 | { |
3030 | struct device *dev = rdev_get_dev(rdev); |
3031 | struct i2c_client *client = to_i2c_client(dev->parent); |
3032 | |
3033 | return pmbus_is_enabled(client, page: rdev_get_id(rdev)); |
3034 | } |
3035 | |
3036 | static int _pmbus_regulator_on_off(struct regulator_dev *rdev, bool enable) |
3037 | { |
3038 | struct device *dev = rdev_get_dev(rdev); |
3039 | struct i2c_client *client = to_i2c_client(dev->parent); |
3040 | struct pmbus_data *data = i2c_get_clientdata(client); |
3041 | u8 page = rdev_get_id(rdev); |
3042 | int ret; |
3043 | |
3044 | mutex_lock(&data->update_lock); |
3045 | ret = pmbus_update_byte_data(client, page, PMBUS_OPERATION, |
3046 | PB_OPERATION_CONTROL_ON, |
3047 | enable ? PB_OPERATION_CONTROL_ON : 0); |
3048 | mutex_unlock(lock: &data->update_lock); |
3049 | |
3050 | return ret; |
3051 | } |
3052 | |
3053 | static int pmbus_regulator_enable(struct regulator_dev *rdev) |
3054 | { |
3055 | return _pmbus_regulator_on_off(rdev, enable: 1); |
3056 | } |
3057 | |
3058 | static int pmbus_regulator_disable(struct regulator_dev *rdev) |
3059 | { |
3060 | return _pmbus_regulator_on_off(rdev, enable: 0); |
3061 | } |
3062 | |
3063 | static int pmbus_regulator_get_error_flags(struct regulator_dev *rdev, unsigned int *flags) |
3064 | { |
3065 | struct device *dev = rdev_get_dev(rdev); |
3066 | struct i2c_client *client = to_i2c_client(dev->parent); |
3067 | struct pmbus_data *data = i2c_get_clientdata(client); |
3068 | int event; |
3069 | |
3070 | return pmbus_get_flags(data, page: rdev_get_id(rdev), flags, event: &event, notify: false); |
3071 | } |
3072 | |
3073 | static int pmbus_regulator_get_status(struct regulator_dev *rdev) |
3074 | { |
3075 | struct device *dev = rdev_get_dev(rdev); |
3076 | struct i2c_client *client = to_i2c_client(dev->parent); |
3077 | struct pmbus_data *data = i2c_get_clientdata(client); |
3078 | u8 page = rdev_get_id(rdev); |
3079 | int status, ret; |
3080 | int event; |
3081 | |
3082 | mutex_lock(&data->update_lock); |
3083 | status = pmbus_get_status(client, page, reg: PMBUS_STATUS_WORD); |
3084 | if (status < 0) { |
3085 | ret = status; |
3086 | goto unlock; |
3087 | } |
3088 | |
3089 | if (status & PB_STATUS_OFF) { |
3090 | ret = REGULATOR_STATUS_OFF; |
3091 | goto unlock; |
3092 | } |
3093 | |
3094 | /* If regulator is ON & reports power good then return ON */ |
3095 | if (!(status & PB_STATUS_POWER_GOOD_N)) { |
3096 | ret = REGULATOR_STATUS_ON; |
3097 | goto unlock; |
3098 | } |
3099 | |
3100 | ret = _pmbus_get_flags(data, page: rdev_get_id(rdev), flags: &status, event: &event, notify: false); |
3101 | if (ret) |
3102 | goto unlock; |
3103 | |
3104 | if (status & (REGULATOR_ERROR_UNDER_VOLTAGE | REGULATOR_ERROR_OVER_CURRENT | |
3105 | REGULATOR_ERROR_REGULATION_OUT | REGULATOR_ERROR_FAIL | REGULATOR_ERROR_OVER_TEMP)) { |
3106 | ret = REGULATOR_STATUS_ERROR; |
3107 | goto unlock; |
3108 | } |
3109 | |
3110 | ret = REGULATOR_STATUS_UNDEFINED; |
3111 | |
3112 | unlock: |
3113 | mutex_unlock(lock: &data->update_lock); |
3114 | return ret; |
3115 | } |
3116 | |
3117 | static int pmbus_regulator_get_low_margin(struct i2c_client *client, int page) |
3118 | { |
3119 | struct pmbus_data *data = i2c_get_clientdata(client); |
3120 | struct pmbus_sensor s = { |
3121 | .page = page, |
3122 | .class = PSC_VOLTAGE_OUT, |
3123 | .convert = true, |
3124 | .data = -1, |
3125 | }; |
3126 | |
3127 | if (data->vout_low[page] < 0) { |
3128 | if (pmbus_check_word_register(client, page, PMBUS_MFR_VOUT_MIN)) |
3129 | s.data = _pmbus_read_word_data(client, page, phase: 0xff, |
3130 | reg: PMBUS_MFR_VOUT_MIN); |
3131 | if (s.data < 0) { |
3132 | s.data = _pmbus_read_word_data(client, page, phase: 0xff, |
3133 | reg: PMBUS_VOUT_MARGIN_LOW); |
3134 | if (s.data < 0) |
3135 | return s.data; |
3136 | } |
3137 | data->vout_low[page] = pmbus_reg2data(data, sensor: &s); |
3138 | } |
3139 | |
3140 | return data->vout_low[page]; |
3141 | } |
3142 | |
3143 | static int pmbus_regulator_get_high_margin(struct i2c_client *client, int page) |
3144 | { |
3145 | struct pmbus_data *data = i2c_get_clientdata(client); |
3146 | struct pmbus_sensor s = { |
3147 | .page = page, |
3148 | .class = PSC_VOLTAGE_OUT, |
3149 | .convert = true, |
3150 | .data = -1, |
3151 | }; |
3152 | |
3153 | if (data->vout_high[page] < 0) { |
3154 | if (pmbus_check_word_register(client, page, PMBUS_MFR_VOUT_MAX)) |
3155 | s.data = _pmbus_read_word_data(client, page, phase: 0xff, |
3156 | reg: PMBUS_MFR_VOUT_MAX); |
3157 | if (s.data < 0) { |
3158 | s.data = _pmbus_read_word_data(client, page, phase: 0xff, |
3159 | reg: PMBUS_VOUT_MARGIN_HIGH); |
3160 | if (s.data < 0) |
3161 | return s.data; |
3162 | } |
3163 | data->vout_high[page] = pmbus_reg2data(data, sensor: &s); |
3164 | } |
3165 | |
3166 | return data->vout_high[page]; |
3167 | } |
3168 | |
3169 | static int pmbus_regulator_get_voltage(struct regulator_dev *rdev) |
3170 | { |
3171 | struct device *dev = rdev_get_dev(rdev); |
3172 | struct i2c_client *client = to_i2c_client(dev->parent); |
3173 | struct pmbus_data *data = i2c_get_clientdata(client); |
3174 | struct pmbus_sensor s = { |
3175 | .page = rdev_get_id(rdev), |
3176 | .class = PSC_VOLTAGE_OUT, |
3177 | .convert = true, |
3178 | }; |
3179 | |
3180 | s.data = _pmbus_read_word_data(client, page: s.page, phase: 0xff, reg: PMBUS_READ_VOUT); |
3181 | if (s.data < 0) |
3182 | return s.data; |
3183 | |
3184 | return (int)pmbus_reg2data(data, sensor: &s) * 1000; /* unit is uV */ |
3185 | } |
3186 | |
3187 | static int pmbus_regulator_set_voltage(struct regulator_dev *rdev, int min_uv, |
3188 | int max_uv, unsigned int *selector) |
3189 | { |
3190 | struct device *dev = rdev_get_dev(rdev); |
3191 | struct i2c_client *client = to_i2c_client(dev->parent); |
3192 | struct pmbus_data *data = i2c_get_clientdata(client); |
3193 | struct pmbus_sensor s = { |
3194 | .page = rdev_get_id(rdev), |
3195 | .class = PSC_VOLTAGE_OUT, |
3196 | .convert = true, |
3197 | .data = -1, |
3198 | }; |
3199 | int val = DIV_ROUND_CLOSEST(min_uv, 1000); /* convert to mV */ |
3200 | int low, high; |
3201 | |
3202 | *selector = 0; |
3203 | |
3204 | low = pmbus_regulator_get_low_margin(client, page: s.page); |
3205 | if (low < 0) |
3206 | return low; |
3207 | |
3208 | high = pmbus_regulator_get_high_margin(client, page: s.page); |
3209 | if (high < 0) |
3210 | return high; |
3211 | |
3212 | /* Make sure we are within margins */ |
3213 | if (low > val) |
3214 | val = low; |
3215 | if (high < val) |
3216 | val = high; |
3217 | |
3218 | val = pmbus_data2reg(data, sensor: &s, val); |
3219 | |
3220 | return _pmbus_write_word_data(client, page: s.page, reg: PMBUS_VOUT_COMMAND, word: (u16)val); |
3221 | } |
3222 | |
3223 | static int pmbus_regulator_list_voltage(struct regulator_dev *rdev, |
3224 | unsigned int selector) |
3225 | { |
3226 | struct device *dev = rdev_get_dev(rdev); |
3227 | struct i2c_client *client = to_i2c_client(dev->parent); |
3228 | struct pmbus_data *data = i2c_get_clientdata(client); |
3229 | int val, low, high; |
3230 | |
3231 | if (data->flags & PMBUS_VOUT_PROTECTED) |
3232 | return 0; |
3233 | |
3234 | if (selector >= rdev->desc->n_voltages || |
3235 | selector < rdev->desc->linear_min_sel) |
3236 | return -EINVAL; |
3237 | |
3238 | selector -= rdev->desc->linear_min_sel; |
3239 | val = DIV_ROUND_CLOSEST(rdev->desc->min_uV + |
3240 | (rdev->desc->uV_step * selector), 1000); /* convert to mV */ |
3241 | |
3242 | low = pmbus_regulator_get_low_margin(client, page: rdev_get_id(rdev)); |
3243 | if (low < 0) |
3244 | return low; |
3245 | |
3246 | high = pmbus_regulator_get_high_margin(client, page: rdev_get_id(rdev)); |
3247 | if (high < 0) |
3248 | return high; |
3249 | |
3250 | if (val >= low && val <= high) |
3251 | return val * 1000; /* unit is uV */ |
3252 | |
3253 | return 0; |
3254 | } |
3255 | |
3256 | const struct regulator_ops pmbus_regulator_ops = { |
3257 | .enable = pmbus_regulator_enable, |
3258 | .disable = pmbus_regulator_disable, |
3259 | .is_enabled = pmbus_regulator_is_enabled, |
3260 | .get_error_flags = pmbus_regulator_get_error_flags, |
3261 | .get_status = pmbus_regulator_get_status, |
3262 | .get_voltage = pmbus_regulator_get_voltage, |
3263 | .set_voltage = pmbus_regulator_set_voltage, |
3264 | .list_voltage = pmbus_regulator_list_voltage, |
3265 | }; |
3266 | EXPORT_SYMBOL_NS_GPL(pmbus_regulator_ops, "PMBUS"); |
3267 | |
3268 | int pmbus_regulator_init_cb(struct regulator_dev *rdev, |
3269 | struct regulator_config *config) |
3270 | { |
3271 | struct pmbus_data *data = config->driver_data; |
3272 | struct regulation_constraints *constraints = rdev->constraints; |
3273 | |
3274 | if (data->flags & PMBUS_OP_PROTECTED) |
3275 | constraints->valid_ops_mask &= ~REGULATOR_CHANGE_STATUS; |
3276 | |
3277 | if (data->flags & PMBUS_VOUT_PROTECTED) |
3278 | constraints->valid_ops_mask &= ~REGULATOR_CHANGE_VOLTAGE; |
3279 | |
3280 | return 0; |
3281 | } |
3282 | EXPORT_SYMBOL_NS_GPL(pmbus_regulator_init_cb, "PMBUS"); |
3283 | |
3284 | static int pmbus_regulator_register(struct pmbus_data *data) |
3285 | { |
3286 | struct device *dev = data->dev; |
3287 | const struct pmbus_driver_info *info = data->info; |
3288 | const struct pmbus_platform_data *pdata = dev_get_platdata(dev); |
3289 | int i; |
3290 | |
3291 | data->rdevs = devm_kzalloc(dev, size: sizeof(struct regulator_dev *) * info->num_regulators, |
3292 | GFP_KERNEL); |
3293 | if (!data->rdevs) |
3294 | return -ENOMEM; |
3295 | |
3296 | for (i = 0; i < info->num_regulators; i++) { |
3297 | struct regulator_config config = { }; |
3298 | |
3299 | config.dev = dev; |
3300 | config.driver_data = data; |
3301 | |
3302 | if (pdata && pdata->reg_init_data) |
3303 | config.init_data = &pdata->reg_init_data[i]; |
3304 | |
3305 | data->rdevs[i] = devm_regulator_register(dev, regulator_desc: &info->reg_desc[i], |
3306 | config: &config); |
3307 | if (IS_ERR(ptr: data->rdevs[i])) |
3308 | return dev_err_probe(dev, err: PTR_ERR(ptr: data->rdevs[i]), |
3309 | fmt: "Failed to register %s regulator\n", |
3310 | info->reg_desc[i].name); |
3311 | } |
3312 | |
3313 | return 0; |
3314 | } |
3315 | |
3316 | static void pmbus_regulator_notify(struct pmbus_data *data, int page, int event) |
3317 | { |
3318 | int j; |
3319 | |
3320 | for (j = 0; j < data->info->num_regulators; j++) { |
3321 | if (page == rdev_get_id(rdev: data->rdevs[j])) { |
3322 | regulator_notifier_call_chain(rdev: data->rdevs[j], event, NULL); |
3323 | break; |
3324 | } |
3325 | } |
3326 | } |
3327 | #else |
3328 | static int pmbus_regulator_register(struct pmbus_data *data) |
3329 | { |
3330 | return 0; |
3331 | } |
3332 | |
3333 | static void pmbus_regulator_notify(struct pmbus_data *data, int page, int event) |
3334 | { |
3335 | } |
3336 | #endif |
3337 | |
3338 | static int pmbus_write_smbalert_mask(struct i2c_client *client, u8 page, u8 reg, u8 val) |
3339 | { |
3340 | int ret; |
3341 | |
3342 | ret = _pmbus_write_word_data(client, page, reg: PMBUS_SMBALERT_MASK, word: reg | (val << 8)); |
3343 | |
3344 | /* |
3345 | * Clear fault systematically in case writing PMBUS_SMBALERT_MASK |
3346 | * is not supported by the chip. |
3347 | */ |
3348 | pmbus_clear_fault_page(client, page); |
3349 | |
3350 | return ret; |
3351 | } |
3352 | |
3353 | static irqreturn_t pmbus_fault_handler(int irq, void *pdata) |
3354 | { |
3355 | struct pmbus_data *data = pdata; |
3356 | struct i2c_client *client = to_i2c_client(data->dev); |
3357 | int i, status, event; |
3358 | |
3359 | mutex_lock(&data->update_lock); |
3360 | for (i = 0; i < data->info->pages; i++) { |
3361 | _pmbus_get_flags(data, page: i, flags: &status, event: &event, notify: true); |
3362 | |
3363 | if (event) |
3364 | pmbus_regulator_notify(data, page: i, event); |
3365 | } |
3366 | |
3367 | pmbus_clear_faults(client); |
3368 | mutex_unlock(lock: &data->update_lock); |
3369 | |
3370 | return IRQ_HANDLED; |
3371 | } |
3372 | |
3373 | static int pmbus_irq_setup(struct i2c_client *client, struct pmbus_data *data) |
3374 | { |
3375 | struct device *dev = &client->dev; |
3376 | const struct pmbus_status_category *cat; |
3377 | const struct pmbus_status_assoc *bit; |
3378 | int i, j, err, func; |
3379 | u8 mask; |
3380 | |
3381 | static const u8 misc_status[] = {PMBUS_STATUS_CML, PMBUS_STATUS_OTHER, |
3382 | PMBUS_STATUS_MFR_SPECIFIC, PMBUS_STATUS_FAN_12, |
3383 | PMBUS_STATUS_FAN_34}; |
3384 | |
3385 | if (!client->irq) |
3386 | return 0; |
3387 | |
3388 | for (i = 0; i < data->info->pages; i++) { |
3389 | func = data->info->func[i]; |
3390 | |
3391 | for (j = 0; j < ARRAY_SIZE(pmbus_status_flag_map); j++) { |
3392 | cat = &pmbus_status_flag_map[j]; |
3393 | if (!(func & cat->func)) |
3394 | continue; |
3395 | mask = 0; |
3396 | for (bit = cat->bits; bit->pflag; bit++) |
3397 | mask |= bit->pflag; |
3398 | |
3399 | err = pmbus_write_smbalert_mask(client, page: i, reg: cat->reg, val: ~mask); |
3400 | if (err) |
3401 | dev_dbg_once(dev, "Failed to set smbalert for reg 0x%02x\n", |
3402 | cat->reg); |
3403 | } |
3404 | |
3405 | for (j = 0; j < ARRAY_SIZE(misc_status); j++) |
3406 | pmbus_write_smbalert_mask(client, page: i, reg: misc_status[j], val: 0xff); |
3407 | } |
3408 | |
3409 | /* Register notifiers */ |
3410 | err = devm_request_threaded_irq(dev, irq: client->irq, NULL, thread_fn: pmbus_fault_handler, |
3411 | IRQF_ONESHOT, devname: "pmbus-irq", dev_id: data); |
3412 | if (err) { |
3413 | dev_err(dev, "failed to request an irq %d\n", err); |
3414 | return err; |
3415 | } |
3416 | |
3417 | return 0; |
3418 | } |
3419 | |
3420 | static struct dentry *pmbus_debugfs_dir; /* pmbus debugfs directory */ |
3421 | |
3422 | static int pmbus_debugfs_get(void *data, u64 *val) |
3423 | { |
3424 | int rc; |
3425 | struct pmbus_debugfs_entry *entry = data; |
3426 | struct pmbus_data *pdata = i2c_get_clientdata(client: entry->client); |
3427 | |
3428 | rc = mutex_lock_interruptible(&pdata->update_lock); |
3429 | if (rc) |
3430 | return rc; |
3431 | rc = _pmbus_read_byte_data(client: entry->client, page: entry->page, reg: entry->reg); |
3432 | mutex_unlock(lock: &pdata->update_lock); |
3433 | if (rc < 0) |
3434 | return rc; |
3435 | |
3436 | *val = rc; |
3437 | |
3438 | return 0; |
3439 | } |
3440 | DEFINE_DEBUGFS_ATTRIBUTE(pmbus_debugfs_ops, pmbus_debugfs_get, NULL, |
3441 | "0x%02llx\n"); |
3442 | |
3443 | static int pmbus_debugfs_get_status(void *data, u64 *val) |
3444 | { |
3445 | int rc; |
3446 | struct pmbus_debugfs_entry *entry = data; |
3447 | struct pmbus_data *pdata = i2c_get_clientdata(client: entry->client); |
3448 | |
3449 | rc = mutex_lock_interruptible(&pdata->update_lock); |
3450 | if (rc) |
3451 | return rc; |
3452 | rc = pdata->read_status(entry->client, entry->page); |
3453 | mutex_unlock(lock: &pdata->update_lock); |
3454 | if (rc < 0) |
3455 | return rc; |
3456 | |
3457 | *val = rc; |
3458 | |
3459 | return 0; |
3460 | } |
3461 | DEFINE_DEBUGFS_ATTRIBUTE(pmbus_debugfs_ops_status, pmbus_debugfs_get_status, |
3462 | NULL, "0x%04llx\n"); |
3463 | |
3464 | static ssize_t pmbus_debugfs_block_read(struct file *file, char __user *buf, |
3465 | size_t count, loff_t *ppos) |
3466 | { |
3467 | int rc; |
3468 | struct pmbus_debugfs_entry *entry = file->private_data; |
3469 | struct pmbus_data *pdata = i2c_get_clientdata(client: entry->client); |
3470 | char data[I2C_SMBUS_BLOCK_MAX + 2] = { 0 }; |
3471 | |
3472 | rc = mutex_lock_interruptible(&pdata->update_lock); |
3473 | if (rc) |
3474 | return rc; |
3475 | rc = pmbus_read_block_data(client: entry->client, page: entry->page, reg: entry->reg, |
3476 | data_buf: data); |
3477 | mutex_unlock(lock: &pdata->update_lock); |
3478 | if (rc < 0) |
3479 | return rc; |
3480 | |
3481 | /* Add newline at the end of a read data */ |
3482 | data[rc] = '\n'; |
3483 | |
3484 | /* Include newline into the length */ |
3485 | rc += 1; |
3486 | |
3487 | return simple_read_from_buffer(to: buf, count, ppos, from: data, available: rc); |
3488 | } |
3489 | |
3490 | static const struct file_operations pmbus_debugfs_block_ops = { |
3491 | .llseek = noop_llseek, |
3492 | .read = pmbus_debugfs_block_read, |
3493 | .write = NULL, |
3494 | .open = simple_open, |
3495 | }; |
3496 | |
3497 | static void pmbus_remove_symlink(void *symlink) |
3498 | { |
3499 | debugfs_remove(dentry: symlink); |
3500 | } |
3501 | |
3502 | struct pmbus_debugfs_data { |
3503 | u8 reg; |
3504 | u32 flag; |
3505 | const char *name; |
3506 | }; |
3507 | |
3508 | static const struct pmbus_debugfs_data pmbus_debugfs_block_data[] = { |
3509 | { .reg = PMBUS_MFR_ID, .name = "mfr_id"}, |
3510 | { .reg = PMBUS_MFR_MODEL, .name = "mfr_model"}, |
3511 | { .reg = PMBUS_MFR_REVISION, .name = "mfr_revision"}, |
3512 | { .reg = PMBUS_MFR_LOCATION, .name = "mfr_location"}, |
3513 | { .reg = PMBUS_MFR_DATE, .name = "mfr_date"}, |
3514 | { .reg = PMBUS_MFR_SERIAL, .name = "mfr_serial"}, |
3515 | }; |
3516 | |
3517 | static const struct pmbus_debugfs_data pmbus_debugfs_status_data[] = { |
3518 | { .reg = PMBUS_STATUS_VOUT, .flag = PMBUS_HAVE_STATUS_VOUT, .name = "status%d_vout"}, |
3519 | { .reg = PMBUS_STATUS_IOUT, .flag = PMBUS_HAVE_STATUS_IOUT, .name = "status%d_iout"}, |
3520 | { .reg = PMBUS_STATUS_INPUT, .flag = PMBUS_HAVE_STATUS_INPUT, .name = "status%d_input"}, |
3521 | { .reg = PMBUS_STATUS_TEMPERATURE, .flag = PMBUS_HAVE_STATUS_TEMP, |
3522 | .name = "status%d_temp"}, |
3523 | { .reg = PMBUS_STATUS_FAN_12, .flag = PMBUS_HAVE_STATUS_FAN12, .name = "status%d_fan12"}, |
3524 | { .reg = PMBUS_STATUS_FAN_34, .flag = PMBUS_HAVE_STATUS_FAN34, .name = "status%d_fan34"}, |
3525 | { .reg = PMBUS_STATUS_CML, .name = "status%d_cml"}, |
3526 | { .reg = PMBUS_STATUS_OTHER, .name = "status%d_other"}, |
3527 | { .reg = PMBUS_STATUS_MFR_SPECIFIC, .name = "status%d_mfr"}, |
3528 | }; |
3529 | |
3530 | static void pmbus_init_debugfs(struct i2c_client *client, |
3531 | struct pmbus_data *data) |
3532 | { |
3533 | struct dentry *symlink_d, *debugfs = client->debugfs; |
3534 | struct pmbus_debugfs_entry *entries; |
3535 | const char *pathname, *symlink; |
3536 | char name[PMBUS_NAME_SIZE]; |
3537 | int page, i, idx = 0; |
3538 | |
3539 | /* |
3540 | * client->debugfs may be NULL or an ERR_PTR(). dentry_path_raw() |
3541 | * does not check if its parameters are valid, so validate |
3542 | * client->debugfs before using it. |
3543 | */ |
3544 | if (!pmbus_debugfs_dir || IS_ERR_OR_NULL(ptr: debugfs)) |
3545 | return; |
3546 | |
3547 | /* |
3548 | * Backwards compatibility: Create symlink from /pmbus/<hwmon_device> |
3549 | * to i2c debugfs directory. |
3550 | */ |
3551 | pathname = dentry_path_raw(debugfs, name, sizeof(name)); |
3552 | if (IS_ERR(ptr: pathname)) |
3553 | return; |
3554 | |
3555 | /* |
3556 | * The path returned by dentry_path_raw() starts with '/'. Prepend it |
3557 | * with ".." to get the symlink relative to the pmbus root directory. |
3558 | */ |
3559 | symlink = kasprintf(GFP_KERNEL, fmt: "..%s", pathname); |
3560 | if (!symlink) |
3561 | return; |
3562 | |
3563 | symlink_d = debugfs_create_symlink(name: dev_name(dev: data->hwmon_dev), |
3564 | parent: pmbus_debugfs_dir, dest: symlink); |
3565 | kfree(objp: symlink); |
3566 | |
3567 | devm_add_action_or_reset(data->dev, pmbus_remove_symlink, symlink_d); |
3568 | |
3569 | /* |
3570 | * Allocate the max possible entries we need. |
3571 | * device specific: |
3572 | * ARRAY_SIZE(pmbus_debugfs_block_data) + 2 |
3573 | * page specific: |
3574 | * ARRAY_SIZE(pmbus_debugfs_status_data) + 1 |
3575 | */ |
3576 | entries = devm_kcalloc(dev: data->dev, |
3577 | ARRAY_SIZE(pmbus_debugfs_block_data) + 2 + |
3578 | data->info->pages * (ARRAY_SIZE(pmbus_debugfs_status_data) + 1), |
3579 | size: sizeof(*entries), GFP_KERNEL); |
3580 | if (!entries) |
3581 | return; |
3582 | |
3583 | /* |
3584 | * Add device-specific entries. |
3585 | * Please note that the PMBUS standard allows all registers to be |
3586 | * page-specific. |
3587 | * To reduce the number of debugfs entries for devices with many pages |
3588 | * assume that values of the following registers are the same for all |
3589 | * pages and report values only for page 0. |
3590 | */ |
3591 | if (!(data->flags & PMBUS_NO_CAPABILITY) && |
3592 | pmbus_check_byte_register(client, 0, PMBUS_CAPABILITY)) { |
3593 | entries[idx].client = client; |
3594 | entries[idx].page = 0; |
3595 | entries[idx].reg = PMBUS_CAPABILITY; |
3596 | debugfs_create_file("capability", 0444, debugfs, |
3597 | &entries[idx++], |
3598 | &pmbus_debugfs_ops); |
3599 | } |
3600 | if (pmbus_check_byte_register(client, 0, PMBUS_REVISION)) { |
3601 | entries[idx].client = client; |
3602 | entries[idx].page = 0; |
3603 | entries[idx].reg = PMBUS_REVISION; |
3604 | debugfs_create_file("pmbus_revision", 0444, debugfs, |
3605 | &entries[idx++], |
3606 | &pmbus_debugfs_ops); |
3607 | } |
3608 | |
3609 | for (i = 0; i < ARRAY_SIZE(pmbus_debugfs_block_data); i++) { |
3610 | const struct pmbus_debugfs_data *d = &pmbus_debugfs_block_data[i]; |
3611 | |
3612 | if (pmbus_check_block_register(client, page: 0, reg: d->reg)) { |
3613 | entries[idx].client = client; |
3614 | entries[idx].page = 0; |
3615 | entries[idx].reg = d->reg; |
3616 | debugfs_create_file(d->name, 0444, debugfs, |
3617 | &entries[idx++], |
3618 | &pmbus_debugfs_block_ops); |
3619 | } |
3620 | } |
3621 | |
3622 | /* Add page specific entries */ |
3623 | for (page = 0; page < data->info->pages; ++page) { |
3624 | /* Check accessibility of status register if it's not page 0 */ |
3625 | if (!page || pmbus_check_status_register(client, page)) { |
3626 | /* No need to set reg as we have special read op. */ |
3627 | entries[idx].client = client; |
3628 | entries[idx].page = page; |
3629 | scnprintf(buf: name, PMBUS_NAME_SIZE, fmt: "status%d", page); |
3630 | debugfs_create_file(name, 0444, debugfs, |
3631 | &entries[idx++], |
3632 | &pmbus_debugfs_ops_status); |
3633 | } |
3634 | |
3635 | for (i = 0; i < ARRAY_SIZE(pmbus_debugfs_status_data); i++) { |
3636 | const struct pmbus_debugfs_data *d = |
3637 | &pmbus_debugfs_status_data[i]; |
3638 | |
3639 | if ((data->info->func[page] & d->flag) || |
3640 | (!d->flag && pmbus_check_byte_register(client, page, d->reg))) { |
3641 | entries[idx].client = client; |
3642 | entries[idx].page = page; |
3643 | entries[idx].reg = d->reg; |
3644 | scnprintf(buf: name, PMBUS_NAME_SIZE, fmt: d->name, page); |
3645 | debugfs_create_file(name, 0444, debugfs, |
3646 | &entries[idx++], |
3647 | &pmbus_debugfs_ops); |
3648 | } |
3649 | } |
3650 | } |
3651 | } |
3652 | |
3653 | int pmbus_do_probe(struct i2c_client *client, struct pmbus_driver_info *info) |
3654 | { |
3655 | struct device *dev = &client->dev; |
3656 | const struct pmbus_platform_data *pdata = dev_get_platdata(dev); |
3657 | struct pmbus_data *data; |
3658 | size_t groups_num = 0; |
3659 | int ret; |
3660 | int i; |
3661 | char *name; |
3662 | |
3663 | if (!info) |
3664 | return -ENODEV; |
3665 | |
3666 | if (!i2c_check_functionality(adap: client->adapter, I2C_FUNC_SMBUS_WRITE_BYTE |
3667 | | I2C_FUNC_SMBUS_BYTE_DATA |
3668 | | I2C_FUNC_SMBUS_WORD_DATA)) |
3669 | return -ENODEV; |
3670 | |
3671 | data = devm_kzalloc(dev, size: sizeof(*data), GFP_KERNEL); |
3672 | if (!data) |
3673 | return -ENOMEM; |
3674 | |
3675 | if (info->groups) |
3676 | while (info->groups[groups_num]) |
3677 | groups_num++; |
3678 | |
3679 | data->groups = devm_kcalloc(dev, n: groups_num + 2, size: sizeof(void *), |
3680 | GFP_KERNEL); |
3681 | if (!data->groups) |
3682 | return -ENOMEM; |
3683 | |
3684 | i2c_set_clientdata(client, data); |
3685 | mutex_init(&data->update_lock); |
3686 | data->dev = dev; |
3687 | |
3688 | if (pdata) |
3689 | data->flags = pdata->flags; |
3690 | data->info = info; |
3691 | data->currpage = -1; |
3692 | data->currphase = -1; |
3693 | |
3694 | for (i = 0; i < ARRAY_SIZE(data->vout_low); i++) { |
3695 | data->vout_low[i] = -1; |
3696 | data->vout_high[i] = -1; |
3697 | } |
3698 | |
3699 | ret = pmbus_init_common(client, data, info); |
3700 | if (ret < 0) |
3701 | return ret; |
3702 | |
3703 | ret = pmbus_find_attributes(client, data); |
3704 | if (ret) |
3705 | return ret; |
3706 | |
3707 | /* |
3708 | * If there are no attributes, something is wrong. |
3709 | * Bail out instead of trying to register nothing. |
3710 | */ |
3711 | if (!data->num_attributes) { |
3712 | dev_err(dev, "No attributes found\n"); |
3713 | return -ENODEV; |
3714 | } |
3715 | |
3716 | name = devm_kstrdup(dev, s: client->name, GFP_KERNEL); |
3717 | if (!name) |
3718 | return -ENOMEM; |
3719 | strreplace(str: name, old: '-', new: '_'); |
3720 | |
3721 | data->groups[0] = &data->group; |
3722 | memcpy(data->groups + 1, info->groups, sizeof(void *) * groups_num); |
3723 | data->hwmon_dev = devm_hwmon_device_register_with_groups(dev, name, |
3724 | drvdata: data, groups: data->groups); |
3725 | if (IS_ERR(ptr: data->hwmon_dev)) { |
3726 | dev_err(dev, "Failed to register hwmon device\n"); |
3727 | return PTR_ERR(ptr: data->hwmon_dev); |
3728 | } |
3729 | |
3730 | ret = pmbus_regulator_register(data); |
3731 | if (ret) |
3732 | return ret; |
3733 | |
3734 | ret = pmbus_irq_setup(client, data); |
3735 | if (ret) |
3736 | return ret; |
3737 | |
3738 | pmbus_init_debugfs(client, data); |
3739 | |
3740 | return 0; |
3741 | } |
3742 | EXPORT_SYMBOL_NS_GPL(pmbus_do_probe, "PMBUS"); |
3743 | |
3744 | struct dentry *pmbus_get_debugfs_dir(struct i2c_client *client) |
3745 | { |
3746 | /* |
3747 | * client->debugfs may be an ERR_PTR(). Returning that to |
3748 | * the calling code would potentially require additional |
3749 | * complexity in the calling code and otherwise add no |
3750 | * value. Return NULL in that case. |
3751 | */ |
3752 | if (IS_ERR_OR_NULL(ptr: client->debugfs)) |
3753 | return NULL; |
3754 | return client->debugfs; |
3755 | } |
3756 | EXPORT_SYMBOL_NS_GPL(pmbus_get_debugfs_dir, "PMBUS"); |
3757 | |
3758 | int pmbus_lock_interruptible(struct i2c_client *client) |
3759 | { |
3760 | struct pmbus_data *data = i2c_get_clientdata(client); |
3761 | |
3762 | return mutex_lock_interruptible(&data->update_lock); |
3763 | } |
3764 | EXPORT_SYMBOL_NS_GPL(pmbus_lock_interruptible, "PMBUS"); |
3765 | |
3766 | void pmbus_unlock(struct i2c_client *client) |
3767 | { |
3768 | struct pmbus_data *data = i2c_get_clientdata(client); |
3769 | |
3770 | mutex_unlock(lock: &data->update_lock); |
3771 | } |
3772 | EXPORT_SYMBOL_NS_GPL(pmbus_unlock, "PMBUS"); |
3773 | |
3774 | static int __init pmbus_core_init(void) |
3775 | { |
3776 | pmbus_debugfs_dir = debugfs_create_dir(name: "pmbus", NULL); |
3777 | if (IS_ERR(ptr: pmbus_debugfs_dir)) |
3778 | pmbus_debugfs_dir = NULL; |
3779 | |
3780 | return 0; |
3781 | } |
3782 | |
3783 | static void __exit pmbus_core_exit(void) |
3784 | { |
3785 | debugfs_remove_recursive(dentry: pmbus_debugfs_dir); |
3786 | } |
3787 | |
3788 | module_init(pmbus_core_init); |
3789 | module_exit(pmbus_core_exit); |
3790 | |
3791 | MODULE_AUTHOR("Guenter Roeck"); |
3792 | MODULE_DESCRIPTION("PMBus core driver"); |
3793 | MODULE_LICENSE("GPL"); |
3794 |
Definitions
- wp
- pmbus_sensor
- pmbus_boolean
- pmbus_label
- pmbus_data
- pmbus_debugfs_entry
- pmbus_fan_rpm_mask
- pmbus_fan_config_registers
- pmbus_fan_command_registers
- pmbus_clear_cache
- pmbus_set_update
- pmbus_wait
- pmbus_update_ts
- pmbus_set_page
- pmbus_write_byte
- _pmbus_write_byte
- pmbus_write_word_data
- pmbus_write_virt_reg
- _pmbus_write_word_data
- _pmbus_write_byte_data
- _pmbus_read_byte_data
- pmbus_update_fan
- pmbus_read_word_data
- pmbus_read_virt_reg
- _pmbus_read_word_data
- __pmbus_read_word_data
- pmbus_read_byte_data
- pmbus_write_byte_data
- pmbus_update_byte_data
- pmbus_read_block_data
- pmbus_find_sensor
- pmbus_get_fan_rate
- pmbus_get_fan_rate_device
- pmbus_get_fan_rate_cached
- pmbus_clear_fault_page
- pmbus_clear_faults
- pmbus_check_status_cml
- pmbus_check_register
- pmbus_check_status_register
- pmbus_check_byte_register
- pmbus_check_word_register
- pmbus_check_block_register
- pmbus_get_driver_info
- pmbus_get_status
- pmbus_update_sensor_data
- pmbus_reg2data_ieee754
- pmbus_reg2data_linear
- pmbus_reg2data_direct
- pmbus_reg2data_vid
- pmbus_reg2data
- pmbus_data2reg_ieee754
- pmbus_data2reg_linear
- pmbus_data2reg_direct
- pmbus_data2reg_vid
- pmbus_data2reg
- pmbus_get_boolean
- pmbus_show_boolean
- pmbus_show_sensor
- pmbus_set_sensor
- pmbus_show_label
- pmbus_add_attribute
- pmbus_dev_attr_init
- pmbus_attr_init
- pmbus_add_boolean
- pmbus_thermal_data
- pmbus_thermal_get_temp
- pmbus_thermal_ops
- pmbus_thermal_add_sensor
- pmbus_add_sensor
- pmbus_add_label
- pmbus_limit_attr
- pmbus_sensor_attr
- pmbus_add_limit_attrs
- pmbus_add_sensor_attrs_one
- pmbus_sensor_is_paged
- pmbus_add_sensor_attrs
- vin_limit_attrs
- vmon_limit_attrs
- vout_limit_attrs
- voltage_attributes
- iin_limit_attrs
- iout_limit_attrs
- current_attributes
- pin_limit_attrs
- pout_limit_attrs
- power_attributes
- temp_limit_attrs
- temp_limit_attrs2
- temp_limit_attrs3
- temp_attributes
- pmbus_fan_registers
- pmbus_fan_status_registers
- pmbus_fan_flags
- pmbus_fan_status_flags
- pmbus_add_fan_ctrl
- pmbus_add_fan_attributes
- pmbus_samples_attr
- pmbus_samples_reg
- pmbus_samples_registers
- pmbus_show_samples
- pmbus_set_samples
- pmbus_add_samples_attr
- pmbus_add_samples_attributes
- pmbus_find_attributes
- pmbus_class_attr_map
- class_attr_map
- pmbus_read_coefficients
- pmbus_init_coefficients
- pmbus_identify_common
- pmbus_read_status_byte
- pmbus_read_status_word
- pec_show
- pec_store
- pmbus_remove_pec
- pmbus_init_wp
- pmbus_init_common
- pmbus_status_assoc
- pmbus_status_category
- pmbus_status_flag_map
- _pmbus_is_enabled
- pmbus_is_enabled
- pmbus_notify
- _pmbus_get_flags
- pmbus_get_flags
- pmbus_regulator_is_enabled
- _pmbus_regulator_on_off
- pmbus_regulator_enable
- pmbus_regulator_disable
- pmbus_regulator_get_error_flags
- pmbus_regulator_get_status
- pmbus_regulator_get_low_margin
- pmbus_regulator_get_high_margin
- pmbus_regulator_get_voltage
- pmbus_regulator_set_voltage
- pmbus_regulator_list_voltage
- pmbus_regulator_ops
- pmbus_regulator_init_cb
- pmbus_regulator_register
- pmbus_regulator_notify
- pmbus_write_smbalert_mask
- pmbus_fault_handler
- pmbus_irq_setup
- pmbus_debugfs_dir
- pmbus_debugfs_get
- pmbus_debugfs_ops
- pmbus_debugfs_get_status
- pmbus_debugfs_ops_status
- pmbus_debugfs_block_read
- pmbus_debugfs_block_ops
- pmbus_remove_symlink
- pmbus_debugfs_data
- pmbus_debugfs_block_data
- pmbus_debugfs_status_data
- pmbus_init_debugfs
- pmbus_do_probe
- pmbus_get_debugfs_dir
- pmbus_lock_interruptible
- pmbus_unlock
- pmbus_core_init
Improve your Profiling and Debugging skills
Find out more