Loading...
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * nct6775 - Platform driver for the hardware monitoring
4 * functionality of Nuvoton NCT677x Super-I/O chips
5 *
6 * Copyright (C) 2012 Guenter Roeck <linux@roeck-us.net>
7 */
8
9#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
10
11#include <linux/acpi.h>
12#include <linux/dmi.h>
13#include <linux/hwmon-sysfs.h>
14#include <linux/hwmon-vid.h>
15#include <linux/init.h>
16#include <linux/io.h>
17#include <linux/module.h>
18#include <linux/platform_device.h>
19#include <linux/regmap.h>
20
21#include "nct6775.h"
22
23enum sensor_access { access_direct, access_asuswmi };
24
25static const char * const nct6775_sio_names[] __initconst = {
26 [nct6106] = "NCT6106D",
27 [nct6116] = "NCT6116D",
28 [nct6775] = "NCT6775F",
29 [nct6776] = "NCT6776D/F",
30 [nct6779] = "NCT6779D",
31 [nct6791] = "NCT6791D",
32 [nct6792] = "NCT6792D",
33 [nct6793] = "NCT6793D",
34 [nct6795] = "NCT6795D",
35 [nct6796] = "NCT6796D",
36 [nct6797] = "NCT6797D",
37 [nct6798] = "NCT6798D",
38 [nct6799] = "NCT6796D-S/NCT6799D-R",
39};
40
41static unsigned short force_id;
42module_param(force_id, ushort, 0);
43MODULE_PARM_DESC(force_id, "Override the detected device ID");
44
45static unsigned short fan_debounce;
46module_param(fan_debounce, ushort, 0);
47MODULE_PARM_DESC(fan_debounce, "Enable debouncing for fan RPM signal");
48
49#define DRVNAME "nct6775"
50
51#define NCT6775_PORT_CHIPID 0x58
52
53/*
54 * ISA constants
55 */
56
57#define IOREGION_ALIGNMENT (~7)
58#define IOREGION_OFFSET 5
59#define IOREGION_LENGTH 2
60#define ADDR_REG_OFFSET 0
61#define DATA_REG_OFFSET 1
62
63/*
64 * Super-I/O constants and functions
65 */
66
67#define NCT6775_LD_ACPI 0x0a
68#define NCT6775_LD_HWM 0x0b
69#define NCT6775_LD_VID 0x0d
70#define NCT6775_LD_12 0x12
71
72#define SIO_REG_LDSEL 0x07 /* Logical device select */
73#define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */
74#define SIO_REG_ENABLE 0x30 /* Logical device enable */
75#define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */
76
77#define SIO_NCT6106_ID 0xc450
78#define SIO_NCT6116_ID 0xd280
79#define SIO_NCT6775_ID 0xb470
80#define SIO_NCT6776_ID 0xc330
81#define SIO_NCT6779_ID 0xc560
82#define SIO_NCT6791_ID 0xc800
83#define SIO_NCT6792_ID 0xc910
84#define SIO_NCT6793_ID 0xd120
85#define SIO_NCT6795_ID 0xd350
86#define SIO_NCT6796_ID 0xd420
87#define SIO_NCT6797_ID 0xd450
88#define SIO_NCT6798_ID 0xd428
89#define SIO_NCT6799_ID 0xd800
90#define SIO_ID_MASK 0xFFF8
91
92/*
93 * Control registers
94 */
95#define NCT6775_REG_CR_FAN_DEBOUNCE 0xf0
96
97struct nct6775_sio_data {
98 int sioreg;
99 int ld;
100 enum kinds kind;
101 enum sensor_access access;
102
103 /* superio_() callbacks */
104 void (*sio_outb)(struct nct6775_sio_data *sio_data, int reg, int val);
105 int (*sio_inb)(struct nct6775_sio_data *sio_data, int reg);
106 void (*sio_select)(struct nct6775_sio_data *sio_data, int ld);
107 int (*sio_enter)(struct nct6775_sio_data *sio_data);
108 void (*sio_exit)(struct nct6775_sio_data *sio_data);
109};
110
111#define ASUSWMI_METHOD "WMBD"
112#define ASUSWMI_METHODID_RSIO 0x5253494F
113#define ASUSWMI_METHODID_WSIO 0x5753494F
114#define ASUSWMI_METHODID_RHWM 0x5248574D
115#define ASUSWMI_METHODID_WHWM 0x5748574D
116#define ASUSWMI_UNSUPPORTED_METHOD 0xFFFFFFFE
117#define ASUSWMI_DEVICE_HID "PNP0C14"
118#define ASUSWMI_DEVICE_UID "ASUSWMI"
119#define ASUSMSI_DEVICE_UID "AsusMbSwInterface"
120
121#if IS_ENABLED(CONFIG_ACPI)
122/*
123 * ASUS boards have only one device with WMI "WMBD" method and have provided
124 * access to only one SuperIO chip at 0x0290.
125 */
126static struct acpi_device *asus_acpi_dev;
127#endif
128
129static int nct6775_asuswmi_evaluate_method(u32 method_id, u8 bank, u8 reg, u8 val, u32 *retval)
130{
131#if IS_ENABLED(CONFIG_ACPI)
132 acpi_handle handle = acpi_device_handle(asus_acpi_dev);
133 u32 args = bank | (reg << 8) | (val << 16);
134 struct acpi_object_list input;
135 union acpi_object params[3];
136 unsigned long long result;
137 acpi_status status;
138
139 params[0].type = ACPI_TYPE_INTEGER;
140 params[0].integer.value = 0;
141 params[1].type = ACPI_TYPE_INTEGER;
142 params[1].integer.value = method_id;
143 params[2].type = ACPI_TYPE_BUFFER;
144 params[2].buffer.length = sizeof(args);
145 params[2].buffer.pointer = (void *)&args;
146 input.count = 3;
147 input.pointer = params;
148
149 status = acpi_evaluate_integer(handle, ASUSWMI_METHOD, &input, &result);
150 if (ACPI_FAILURE(status))
151 return -EIO;
152
153 if (retval)
154 *retval = result;
155
156 return 0;
157#else
158 return -EOPNOTSUPP;
159#endif
160}
161
162static inline int nct6775_asuswmi_write(u8 bank, u8 reg, u8 val)
163{
164 return nct6775_asuswmi_evaluate_method(ASUSWMI_METHODID_WHWM, bank,
165 reg, val, NULL);
166}
167
168static inline int nct6775_asuswmi_read(u8 bank, u8 reg, u8 *val)
169{
170 u32 ret, tmp = 0;
171
172 ret = nct6775_asuswmi_evaluate_method(ASUSWMI_METHODID_RHWM, bank,
173 reg, 0, &tmp);
174 *val = tmp;
175 return ret;
176}
177
178static int superio_wmi_inb(struct nct6775_sio_data *sio_data, int reg)
179{
180 int tmp = 0;
181
182 nct6775_asuswmi_evaluate_method(ASUSWMI_METHODID_RSIO, sio_data->ld,
183 reg, 0, &tmp);
184 return tmp;
185}
186
187static void superio_wmi_outb(struct nct6775_sio_data *sio_data, int reg, int val)
188{
189 nct6775_asuswmi_evaluate_method(ASUSWMI_METHODID_WSIO, sio_data->ld,
190 reg, val, NULL);
191}
192
193static void superio_wmi_select(struct nct6775_sio_data *sio_data, int ld)
194{
195 sio_data->ld = ld;
196}
197
198static int superio_wmi_enter(struct nct6775_sio_data *sio_data)
199{
200 return 0;
201}
202
203static void superio_wmi_exit(struct nct6775_sio_data *sio_data)
204{
205}
206
207static void superio_outb(struct nct6775_sio_data *sio_data, int reg, int val)
208{
209 int ioreg = sio_data->sioreg;
210
211 outb(reg, ioreg);
212 outb(val, ioreg + 1);
213}
214
215static int superio_inb(struct nct6775_sio_data *sio_data, int reg)
216{
217 int ioreg = sio_data->sioreg;
218
219 outb(reg, ioreg);
220 return inb(ioreg + 1);
221}
222
223static void superio_select(struct nct6775_sio_data *sio_data, int ld)
224{
225 int ioreg = sio_data->sioreg;
226
227 outb(SIO_REG_LDSEL, ioreg);
228 outb(ld, ioreg + 1);
229}
230
231static int superio_enter(struct nct6775_sio_data *sio_data)
232{
233 int ioreg = sio_data->sioreg;
234
235 /*
236 * Try to reserve <ioreg> and <ioreg + 1> for exclusive access.
237 */
238 if (!request_muxed_region(ioreg, 2, DRVNAME))
239 return -EBUSY;
240
241 outb(0x87, ioreg);
242 outb(0x87, ioreg);
243
244 return 0;
245}
246
247static void superio_exit(struct nct6775_sio_data *sio_data)
248{
249 int ioreg = sio_data->sioreg;
250
251 outb(0xaa, ioreg);
252 outb(0x02, ioreg);
253 outb(0x02, ioreg + 1);
254 release_region(ioreg, 2);
255}
256
257static inline void nct6775_wmi_set_bank(struct nct6775_data *data, u16 reg)
258{
259 u8 bank = reg >> 8;
260
261 data->bank = bank;
262}
263
264static int nct6775_wmi_reg_read(void *ctx, unsigned int reg, unsigned int *val)
265{
266 struct nct6775_data *data = ctx;
267 int err, word_sized = nct6775_reg_is_word_sized(data, reg);
268 u8 tmp = 0;
269 u16 res;
270
271 nct6775_wmi_set_bank(data, reg);
272
273 err = nct6775_asuswmi_read(data->bank, reg & 0xff, &tmp);
274 if (err)
275 return err;
276
277 res = tmp;
278 if (word_sized) {
279 err = nct6775_asuswmi_read(data->bank, (reg & 0xff) + 1, &tmp);
280 if (err)
281 return err;
282
283 res = (res << 8) + tmp;
284 }
285 *val = res;
286 return 0;
287}
288
289static int nct6775_wmi_reg_write(void *ctx, unsigned int reg, unsigned int value)
290{
291 struct nct6775_data *data = ctx;
292 int res, word_sized = nct6775_reg_is_word_sized(data, reg);
293
294 nct6775_wmi_set_bank(data, reg);
295
296 if (word_sized) {
297 res = nct6775_asuswmi_write(data->bank, reg & 0xff, value >> 8);
298 if (res)
299 return res;
300
301 res = nct6775_asuswmi_write(data->bank, (reg & 0xff) + 1, value);
302 } else {
303 res = nct6775_asuswmi_write(data->bank, reg & 0xff, value);
304 }
305
306 return res;
307}
308
309/*
310 * On older chips, only registers 0x50-0x5f are banked.
311 * On more recent chips, all registers are banked.
312 * Assume that is the case and set the bank number for each access.
313 * Cache the bank number so it only needs to be set if it changes.
314 */
315static inline void nct6775_set_bank(struct nct6775_data *data, u16 reg)
316{
317 u8 bank = reg >> 8;
318
319 if (data->bank != bank) {
320 outb_p(NCT6775_REG_BANK, data->addr + ADDR_REG_OFFSET);
321 outb_p(bank, data->addr + DATA_REG_OFFSET);
322 data->bank = bank;
323 }
324}
325
326static int nct6775_reg_read(void *ctx, unsigned int reg, unsigned int *val)
327{
328 struct nct6775_data *data = ctx;
329 int word_sized = nct6775_reg_is_word_sized(data, reg);
330
331 nct6775_set_bank(data, reg);
332 outb_p(reg & 0xff, data->addr + ADDR_REG_OFFSET);
333 *val = inb_p(data->addr + DATA_REG_OFFSET);
334 if (word_sized) {
335 outb_p((reg & 0xff) + 1,
336 data->addr + ADDR_REG_OFFSET);
337 *val = (*val << 8) + inb_p(data->addr + DATA_REG_OFFSET);
338 }
339 return 0;
340}
341
342static int nct6775_reg_write(void *ctx, unsigned int reg, unsigned int value)
343{
344 struct nct6775_data *data = ctx;
345 int word_sized = nct6775_reg_is_word_sized(data, reg);
346
347 nct6775_set_bank(data, reg);
348 outb_p(reg & 0xff, data->addr + ADDR_REG_OFFSET);
349 if (word_sized) {
350 outb_p(value >> 8, data->addr + DATA_REG_OFFSET);
351 outb_p((reg & 0xff) + 1,
352 data->addr + ADDR_REG_OFFSET);
353 }
354 outb_p(value & 0xff, data->addr + DATA_REG_OFFSET);
355 return 0;
356}
357
358static void nct6791_enable_io_mapping(struct nct6775_sio_data *sio_data)
359{
360 int val;
361
362 val = sio_data->sio_inb(sio_data, NCT6791_REG_HM_IO_SPACE_LOCK_ENABLE);
363 if (val & 0x10) {
364 pr_info("Enabling hardware monitor logical device mappings.\n");
365 sio_data->sio_outb(sio_data, NCT6791_REG_HM_IO_SPACE_LOCK_ENABLE,
366 val & ~0x10);
367 }
368}
369
370static int nct6775_suspend(struct device *dev)
371{
372 int err;
373 u16 tmp;
374 struct nct6775_data *data = nct6775_update_device(dev);
375
376 if (IS_ERR(data))
377 return PTR_ERR(data);
378
379 mutex_lock(&data->update_lock);
380 err = nct6775_read_value(data, data->REG_VBAT, &tmp);
381 if (err)
382 goto out;
383 data->vbat = tmp;
384 if (data->kind == nct6775) {
385 err = nct6775_read_value(data, NCT6775_REG_FANDIV1, &tmp);
386 if (err)
387 goto out;
388 data->fandiv1 = tmp;
389
390 err = nct6775_read_value(data, NCT6775_REG_FANDIV2, &tmp);
391 if (err)
392 goto out;
393 data->fandiv2 = tmp;
394 }
395out:
396 mutex_unlock(&data->update_lock);
397
398 return err;
399}
400
401static int nct6775_resume(struct device *dev)
402{
403 struct nct6775_data *data = dev_get_drvdata(dev);
404 struct nct6775_sio_data *sio_data = dev_get_platdata(dev);
405 int i, j, err = 0;
406 u8 reg;
407
408 mutex_lock(&data->update_lock);
409 data->bank = 0xff; /* Force initial bank selection */
410
411 err = sio_data->sio_enter(sio_data);
412 if (err)
413 goto abort;
414
415 sio_data->sio_select(sio_data, NCT6775_LD_HWM);
416 reg = sio_data->sio_inb(sio_data, SIO_REG_ENABLE);
417 if (reg != data->sio_reg_enable)
418 sio_data->sio_outb(sio_data, SIO_REG_ENABLE, data->sio_reg_enable);
419
420 if (data->kind == nct6791 || data->kind == nct6792 ||
421 data->kind == nct6793 || data->kind == nct6795 ||
422 data->kind == nct6796 || data->kind == nct6797 ||
423 data->kind == nct6798 || data->kind == nct6799)
424 nct6791_enable_io_mapping(sio_data);
425
426 sio_data->sio_exit(sio_data);
427
428 /* Restore limits */
429 for (i = 0; i < data->in_num; i++) {
430 if (!(data->have_in & BIT(i)))
431 continue;
432
433 err = nct6775_write_value(data, data->REG_IN_MINMAX[0][i], data->in[i][1]);
434 if (err)
435 goto abort;
436 err = nct6775_write_value(data, data->REG_IN_MINMAX[1][i], data->in[i][2]);
437 if (err)
438 goto abort;
439 }
440
441 for (i = 0; i < ARRAY_SIZE(data->fan_min); i++) {
442 if (!(data->has_fan_min & BIT(i)))
443 continue;
444
445 err = nct6775_write_value(data, data->REG_FAN_MIN[i], data->fan_min[i]);
446 if (err)
447 goto abort;
448 }
449
450 for (i = 0; i < NUM_TEMP; i++) {
451 if (!(data->have_temp & BIT(i)))
452 continue;
453
454 for (j = 1; j < ARRAY_SIZE(data->reg_temp); j++)
455 if (data->reg_temp[j][i]) {
456 err = nct6775_write_temp(data, data->reg_temp[j][i],
457 data->temp[j][i]);
458 if (err)
459 goto abort;
460 }
461 }
462
463 /* Restore other settings */
464 err = nct6775_write_value(data, data->REG_VBAT, data->vbat);
465 if (err)
466 goto abort;
467 if (data->kind == nct6775) {
468 err = nct6775_write_value(data, NCT6775_REG_FANDIV1, data->fandiv1);
469 if (err)
470 goto abort;
471 err = nct6775_write_value(data, NCT6775_REG_FANDIV2, data->fandiv2);
472 }
473
474abort:
475 /* Force re-reading all values */
476 data->valid = false;
477 mutex_unlock(&data->update_lock);
478
479 return err;
480}
481
482static DEFINE_SIMPLE_DEV_PM_OPS(nct6775_dev_pm_ops, nct6775_suspend, nct6775_resume);
483
484static void
485nct6775_check_fan_inputs(struct nct6775_data *data, struct nct6775_sio_data *sio_data)
486{
487 bool fan3pin = false, fan4pin = false, fan4min = false;
488 bool fan5pin = false, fan6pin = false, fan7pin = false;
489 bool pwm3pin = false, pwm4pin = false, pwm5pin = false;
490 bool pwm6pin = false, pwm7pin = false;
491
492 /* Store SIO_REG_ENABLE for use during resume */
493 sio_data->sio_select(sio_data, NCT6775_LD_HWM);
494 data->sio_reg_enable = sio_data->sio_inb(sio_data, SIO_REG_ENABLE);
495
496 /* fan4 and fan5 share some pins with the GPIO and serial flash */
497 if (data->kind == nct6775) {
498 int cr2c = sio_data->sio_inb(sio_data, 0x2c);
499
500 fan3pin = cr2c & BIT(6);
501 pwm3pin = cr2c & BIT(7);
502
503 /* On NCT6775, fan4 shares pins with the fdc interface */
504 fan4pin = !(sio_data->sio_inb(sio_data, 0x2A) & 0x80);
505 } else if (data->kind == nct6776) {
506 bool gpok = sio_data->sio_inb(sio_data, 0x27) & 0x80;
507 const char *board_vendor, *board_name;
508
509 board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR);
510 board_name = dmi_get_system_info(DMI_BOARD_NAME);
511
512 if (board_name && board_vendor &&
513 !strcmp(board_vendor, "ASRock")) {
514 /*
515 * Auxiliary fan monitoring is not enabled on ASRock
516 * Z77 Pro4-M if booted in UEFI Ultra-FastBoot mode.
517 * Observed with BIOS version 2.00.
518 */
519 if (!strcmp(board_name, "Z77 Pro4-M")) {
520 if ((data->sio_reg_enable & 0xe0) != 0xe0) {
521 data->sio_reg_enable |= 0xe0;
522 sio_data->sio_outb(sio_data, SIO_REG_ENABLE,
523 data->sio_reg_enable);
524 }
525 }
526 }
527
528 if (data->sio_reg_enable & 0x80)
529 fan3pin = gpok;
530 else
531 fan3pin = !(sio_data->sio_inb(sio_data, 0x24) & 0x40);
532
533 if (data->sio_reg_enable & 0x40)
534 fan4pin = gpok;
535 else
536 fan4pin = sio_data->sio_inb(sio_data, 0x1C) & 0x01;
537
538 if (data->sio_reg_enable & 0x20)
539 fan5pin = gpok;
540 else
541 fan5pin = sio_data->sio_inb(sio_data, 0x1C) & 0x02;
542
543 fan4min = fan4pin;
544 pwm3pin = fan3pin;
545 } else if (data->kind == nct6106) {
546 int cr24 = sio_data->sio_inb(sio_data, 0x24);
547
548 fan3pin = !(cr24 & 0x80);
549 pwm3pin = cr24 & 0x08;
550 } else if (data->kind == nct6116) {
551 int cr1a = sio_data->sio_inb(sio_data, 0x1a);
552 int cr1b = sio_data->sio_inb(sio_data, 0x1b);
553 int cr24 = sio_data->sio_inb(sio_data, 0x24);
554 int cr2a = sio_data->sio_inb(sio_data, 0x2a);
555 int cr2b = sio_data->sio_inb(sio_data, 0x2b);
556 int cr2f = sio_data->sio_inb(sio_data, 0x2f);
557
558 fan3pin = !(cr2b & 0x10);
559 fan4pin = (cr2b & 0x80) || // pin 1(2)
560 (!(cr2f & 0x10) && (cr1a & 0x04)); // pin 65(66)
561 fan5pin = (cr2b & 0x80) || // pin 126(127)
562 (!(cr1b & 0x03) && (cr2a & 0x02)); // pin 94(96)
563
564 pwm3pin = fan3pin && (cr24 & 0x08);
565 pwm4pin = fan4pin;
566 pwm5pin = fan5pin;
567 } else {
568 /*
569 * NCT6779D, NCT6791D, NCT6792D, NCT6793D, NCT6795D, NCT6796D,
570 * NCT6797D, NCT6798D, NCT6799D
571 */
572 int cr1a = sio_data->sio_inb(sio_data, 0x1a);
573 int cr1b = sio_data->sio_inb(sio_data, 0x1b);
574 int cr1c = sio_data->sio_inb(sio_data, 0x1c);
575 int cr1d = sio_data->sio_inb(sio_data, 0x1d);
576 int cr2a = sio_data->sio_inb(sio_data, 0x2a);
577 int cr2b = sio_data->sio_inb(sio_data, 0x2b);
578 int cr2d = sio_data->sio_inb(sio_data, 0x2d);
579 int cr2f = sio_data->sio_inb(sio_data, 0x2f);
580 bool vsb_ctl_en = cr2f & BIT(0);
581 bool dsw_en = cr2f & BIT(3);
582 bool ddr4_en = cr2f & BIT(4);
583 bool as_seq1_en = cr2f & BIT(7);
584 int cre0;
585 int cre6;
586 int creb;
587 int cred;
588
589 cre6 = sio_data->sio_inb(sio_data, 0xe6);
590
591 sio_data->sio_select(sio_data, NCT6775_LD_12);
592 cre0 = sio_data->sio_inb(sio_data, 0xe0);
593 creb = sio_data->sio_inb(sio_data, 0xeb);
594 cred = sio_data->sio_inb(sio_data, 0xed);
595
596 fan3pin = !(cr1c & BIT(5));
597 fan4pin = !(cr1c & BIT(6));
598 fan5pin = !(cr1c & BIT(7));
599
600 pwm3pin = !(cr1c & BIT(0));
601 pwm4pin = !(cr1c & BIT(1));
602 pwm5pin = !(cr1c & BIT(2));
603
604 switch (data->kind) {
605 case nct6791:
606 fan6pin = cr2d & BIT(1);
607 pwm6pin = cr2d & BIT(0);
608 break;
609 case nct6792:
610 fan6pin = !dsw_en && (cr2d & BIT(1));
611 pwm6pin = !dsw_en && (cr2d & BIT(0));
612 break;
613 case nct6793:
614 fan5pin |= cr1b & BIT(5);
615 fan5pin |= creb & BIT(5);
616
617 fan6pin = !dsw_en && (cr2d & BIT(1));
618 fan6pin |= creb & BIT(3);
619
620 pwm5pin |= cr2d & BIT(7);
621 pwm5pin |= (creb & BIT(4)) && !(cr2a & BIT(0));
622
623 pwm6pin = !dsw_en && (cr2d & BIT(0));
624 pwm6pin |= creb & BIT(2);
625 break;
626 case nct6795:
627 fan5pin |= cr1b & BIT(5);
628 fan5pin |= creb & BIT(5);
629
630 fan6pin = (cr2a & BIT(4)) &&
631 (!dsw_en || (cred & BIT(4)));
632 fan6pin |= creb & BIT(3);
633
634 pwm5pin |= cr2d & BIT(7);
635 pwm5pin |= (creb & BIT(4)) && !(cr2a & BIT(0));
636
637 pwm6pin = (cr2a & BIT(3)) && (cred & BIT(2));
638 pwm6pin |= creb & BIT(2);
639 break;
640 case nct6796:
641 fan5pin |= cr1b & BIT(5);
642 fan5pin |= (cre0 & BIT(3)) && !(cr1b & BIT(0));
643 fan5pin |= creb & BIT(5);
644
645 fan6pin = (cr2a & BIT(4)) &&
646 (!dsw_en || (cred & BIT(4)));
647 fan6pin |= creb & BIT(3);
648
649 fan7pin = !(cr2b & BIT(2));
650
651 pwm5pin |= cr2d & BIT(7);
652 pwm5pin |= (cre0 & BIT(4)) && !(cr1b & BIT(0));
653 pwm5pin |= (creb & BIT(4)) && !(cr2a & BIT(0));
654
655 pwm6pin = (cr2a & BIT(3)) && (cred & BIT(2));
656 pwm6pin |= creb & BIT(2);
657
658 pwm7pin = !(cr1d & (BIT(2) | BIT(3)));
659 break;
660 case nct6797:
661 fan5pin |= !ddr4_en && (cr1b & BIT(5));
662 fan5pin |= creb & BIT(5);
663
664 fan6pin = cr2a & BIT(4);
665 fan6pin |= creb & BIT(3);
666
667 fan7pin = cr1a & BIT(1);
668
669 pwm5pin |= (creb & BIT(4)) && !(cr2a & BIT(0));
670 pwm5pin |= !ddr4_en && (cr2d & BIT(7));
671
672 pwm6pin = creb & BIT(2);
673 pwm6pin |= cred & BIT(2);
674
675 pwm7pin = cr1d & BIT(4);
676 break;
677 case nct6798:
678 fan6pin = !(cr1b & BIT(0)) && (cre0 & BIT(3));
679 fan6pin |= cr2a & BIT(4);
680 fan6pin |= creb & BIT(5);
681
682 fan7pin = cr1b & BIT(5);
683 fan7pin |= !(cr2b & BIT(2));
684 fan7pin |= creb & BIT(3);
685
686 pwm6pin = !(cr1b & BIT(0)) && (cre0 & BIT(4));
687 pwm6pin |= !(cred & BIT(2)) && (cr2a & BIT(3));
688 pwm6pin |= (creb & BIT(4)) && !(cr2a & BIT(0));
689
690 pwm7pin = !(cr1d & (BIT(2) | BIT(3)));
691 pwm7pin |= cr2d & BIT(7);
692 pwm7pin |= creb & BIT(2);
693 break;
694 case nct6799:
695 fan4pin = cr1c & BIT(6);
696 fan5pin = cr1c & BIT(7);
697
698 fan6pin = !(cr1b & BIT(0)) && (cre0 & BIT(3));
699 fan6pin |= cre6 & BIT(5);
700 fan6pin |= creb & BIT(5);
701 fan6pin |= !as_seq1_en && (cr2a & BIT(4));
702
703 fan7pin = cr1b & BIT(5);
704 fan7pin |= !vsb_ctl_en && !(cr2b & BIT(2));
705 fan7pin |= creb & BIT(3);
706
707 pwm6pin = !(cr1b & BIT(0)) && (cre0 & BIT(4));
708 pwm6pin |= !as_seq1_en && !(cred & BIT(2)) && (cr2a & BIT(3));
709 pwm6pin |= (creb & BIT(4)) && !(cr2a & BIT(0));
710 pwm6pin |= cre6 & BIT(3);
711
712 pwm7pin = !vsb_ctl_en && !(cr1d & (BIT(2) | BIT(3)));
713 pwm7pin |= creb & BIT(2);
714 pwm7pin |= cr2d & BIT(7);
715
716 break;
717 default: /* NCT6779D */
718 break;
719 }
720
721 fan4min = fan4pin;
722 }
723
724 /* fan 1 and 2 (0x03) are always present */
725 data->has_fan = 0x03 | (fan3pin << 2) | (fan4pin << 3) |
726 (fan5pin << 4) | (fan6pin << 5) | (fan7pin << 6);
727 data->has_fan_min = 0x03 | (fan3pin << 2) | (fan4min << 3) |
728 (fan5pin << 4) | (fan6pin << 5) | (fan7pin << 6);
729 data->has_pwm = 0x03 | (pwm3pin << 2) | (pwm4pin << 3) |
730 (pwm5pin << 4) | (pwm6pin << 5) | (pwm7pin << 6);
731}
732
733static ssize_t
734cpu0_vid_show(struct device *dev, struct device_attribute *attr, char *buf)
735{
736 struct nct6775_data *data = dev_get_drvdata(dev);
737
738 return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm));
739}
740
741static DEVICE_ATTR_RO(cpu0_vid);
742
743/* Case open detection */
744
745static const u8 NCT6775_REG_CR_CASEOPEN_CLR[] = { 0xe6, 0xee };
746static const u8 NCT6775_CR_CASEOPEN_CLR_MASK[] = { 0x20, 0x01 };
747
748static ssize_t
749clear_caseopen(struct device *dev, struct device_attribute *attr,
750 const char *buf, size_t count)
751{
752 struct nct6775_data *data = dev_get_drvdata(dev);
753 struct nct6775_sio_data *sio_data = data->driver_data;
754 int nr = to_sensor_dev_attr(attr)->index - INTRUSION_ALARM_BASE;
755 unsigned long val;
756 u8 reg;
757 int ret;
758
759 if (kstrtoul(buf, 10, &val) || val != 0)
760 return -EINVAL;
761
762 mutex_lock(&data->update_lock);
763
764 /*
765 * Use CR registers to clear caseopen status.
766 * The CR registers are the same for all chips, and not all chips
767 * support clearing the caseopen status through "regular" registers.
768 */
769 ret = sio_data->sio_enter(sio_data);
770 if (ret) {
771 count = ret;
772 goto error;
773 }
774
775 sio_data->sio_select(sio_data, NCT6775_LD_ACPI);
776 reg = sio_data->sio_inb(sio_data, NCT6775_REG_CR_CASEOPEN_CLR[nr]);
777 reg |= NCT6775_CR_CASEOPEN_CLR_MASK[nr];
778 sio_data->sio_outb(sio_data, NCT6775_REG_CR_CASEOPEN_CLR[nr], reg);
779 reg &= ~NCT6775_CR_CASEOPEN_CLR_MASK[nr];
780 sio_data->sio_outb(sio_data, NCT6775_REG_CR_CASEOPEN_CLR[nr], reg);
781 sio_data->sio_exit(sio_data);
782
783 data->valid = false; /* Force cache refresh */
784error:
785 mutex_unlock(&data->update_lock);
786 return count;
787}
788
789static SENSOR_DEVICE_ATTR(intrusion0_alarm, 0644, nct6775_show_alarm,
790 clear_caseopen, INTRUSION_ALARM_BASE);
791static SENSOR_DEVICE_ATTR(intrusion1_alarm, 0644, nct6775_show_alarm,
792 clear_caseopen, INTRUSION_ALARM_BASE + 1);
793static SENSOR_DEVICE_ATTR(intrusion0_beep, 0644, nct6775_show_beep,
794 nct6775_store_beep, INTRUSION_ALARM_BASE);
795static SENSOR_DEVICE_ATTR(intrusion1_beep, 0644, nct6775_show_beep,
796 nct6775_store_beep, INTRUSION_ALARM_BASE + 1);
797static SENSOR_DEVICE_ATTR(beep_enable, 0644, nct6775_show_beep,
798 nct6775_store_beep, BEEP_ENABLE_BASE);
799
800static umode_t nct6775_other_is_visible(struct kobject *kobj,
801 struct attribute *attr, int index)
802{
803 struct device *dev = kobj_to_dev(kobj);
804 struct nct6775_data *data = dev_get_drvdata(dev);
805
806 if (index == 0 && !data->have_vid)
807 return 0;
808
809 if (index == 1 || index == 2) {
810 if (data->ALARM_BITS[INTRUSION_ALARM_BASE + index - 1] < 0)
811 return 0;
812 }
813
814 if (index == 3 || index == 4) {
815 if (data->BEEP_BITS[INTRUSION_ALARM_BASE + index - 3] < 0)
816 return 0;
817 }
818
819 return nct6775_attr_mode(data, attr);
820}
821
822/*
823 * nct6775_other_is_visible uses the index into the following array
824 * to determine if attributes should be created or not.
825 * Any change in order or content must be matched.
826 */
827static struct attribute *nct6775_attributes_other[] = {
828 &dev_attr_cpu0_vid.attr, /* 0 */
829 &sensor_dev_attr_intrusion0_alarm.dev_attr.attr, /* 1 */
830 &sensor_dev_attr_intrusion1_alarm.dev_attr.attr, /* 2 */
831 &sensor_dev_attr_intrusion0_beep.dev_attr.attr, /* 3 */
832 &sensor_dev_attr_intrusion1_beep.dev_attr.attr, /* 4 */
833 &sensor_dev_attr_beep_enable.dev_attr.attr, /* 5 */
834
835 NULL
836};
837
838static const struct attribute_group nct6775_group_other = {
839 .attrs = nct6775_attributes_other,
840 .is_visible = nct6775_other_is_visible,
841};
842
843static int nct6775_platform_probe_init(struct nct6775_data *data)
844{
845 int err;
846 u8 cr2a;
847 struct nct6775_sio_data *sio_data = data->driver_data;
848
849 err = sio_data->sio_enter(sio_data);
850 if (err)
851 return err;
852
853 cr2a = sio_data->sio_inb(sio_data, 0x2a);
854 switch (data->kind) {
855 case nct6775:
856 data->have_vid = (cr2a & 0x40);
857 break;
858 case nct6776:
859 data->have_vid = (cr2a & 0x60) == 0x40;
860 break;
861 case nct6106:
862 case nct6116:
863 case nct6779:
864 case nct6791:
865 case nct6792:
866 case nct6793:
867 case nct6795:
868 case nct6796:
869 case nct6797:
870 case nct6798:
871 case nct6799:
872 break;
873 }
874
875 /*
876 * Read VID value
877 * We can get the VID input values directly at logical device D 0xe3.
878 */
879 if (data->have_vid) {
880 sio_data->sio_select(sio_data, NCT6775_LD_VID);
881 data->vid = sio_data->sio_inb(sio_data, 0xe3);
882 data->vrm = vid_which_vrm();
883 }
884
885 if (fan_debounce) {
886 u8 tmp;
887
888 sio_data->sio_select(sio_data, NCT6775_LD_HWM);
889 tmp = sio_data->sio_inb(sio_data,
890 NCT6775_REG_CR_FAN_DEBOUNCE);
891 switch (data->kind) {
892 case nct6106:
893 case nct6116:
894 tmp |= 0xe0;
895 break;
896 case nct6775:
897 tmp |= 0x1e;
898 break;
899 case nct6776:
900 case nct6779:
901 tmp |= 0x3e;
902 break;
903 case nct6791:
904 case nct6792:
905 case nct6793:
906 case nct6795:
907 case nct6796:
908 case nct6797:
909 case nct6798:
910 case nct6799:
911 tmp |= 0x7e;
912 break;
913 }
914 sio_data->sio_outb(sio_data, NCT6775_REG_CR_FAN_DEBOUNCE,
915 tmp);
916 pr_info("Enabled fan debounce for chip %s\n", data->name);
917 }
918
919 nct6775_check_fan_inputs(data, sio_data);
920
921 sio_data->sio_exit(sio_data);
922
923 return nct6775_add_attr_group(data, &nct6775_group_other);
924}
925
926static const struct regmap_config nct6775_regmap_config = {
927 .reg_bits = 16,
928 .val_bits = 16,
929 .reg_read = nct6775_reg_read,
930 .reg_write = nct6775_reg_write,
931};
932
933static const struct regmap_config nct6775_wmi_regmap_config = {
934 .reg_bits = 16,
935 .val_bits = 16,
936 .reg_read = nct6775_wmi_reg_read,
937 .reg_write = nct6775_wmi_reg_write,
938};
939
940static int nct6775_platform_probe(struct platform_device *pdev)
941{
942 struct device *dev = &pdev->dev;
943 struct nct6775_sio_data *sio_data = dev_get_platdata(dev);
944 struct nct6775_data *data;
945 struct resource *res;
946 const struct regmap_config *regmapcfg;
947
948 if (sio_data->access == access_direct) {
949 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
950 if (!devm_request_region(&pdev->dev, res->start, IOREGION_LENGTH, DRVNAME))
951 return -EBUSY;
952 }
953
954 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
955 if (!data)
956 return -ENOMEM;
957
958 data->kind = sio_data->kind;
959 data->sioreg = sio_data->sioreg;
960
961 if (sio_data->access == access_direct) {
962 data->addr = res->start;
963 regmapcfg = &nct6775_regmap_config;
964 } else {
965 regmapcfg = &nct6775_wmi_regmap_config;
966 }
967
968 platform_set_drvdata(pdev, data);
969
970 data->driver_data = sio_data;
971 data->driver_init = nct6775_platform_probe_init;
972
973 return nct6775_probe(&pdev->dev, data, regmapcfg);
974}
975
976static struct platform_driver nct6775_driver = {
977 .driver = {
978 .name = DRVNAME,
979 .pm = pm_sleep_ptr(&nct6775_dev_pm_ops),
980 },
981 .probe = nct6775_platform_probe,
982};
983
984/* nct6775_find() looks for a '627 in the Super-I/O config space */
985static int __init nct6775_find(int sioaddr, struct nct6775_sio_data *sio_data)
986{
987 u16 val;
988 int err;
989 int addr;
990
991 sio_data->access = access_direct;
992 sio_data->sioreg = sioaddr;
993
994 err = sio_data->sio_enter(sio_data);
995 if (err)
996 return err;
997
998 val = (sio_data->sio_inb(sio_data, SIO_REG_DEVID) << 8) |
999 sio_data->sio_inb(sio_data, SIO_REG_DEVID + 1);
1000 if (force_id && val != 0xffff)
1001 val = force_id;
1002
1003 switch (val & SIO_ID_MASK) {
1004 case SIO_NCT6106_ID:
1005 sio_data->kind = nct6106;
1006 break;
1007 case SIO_NCT6116_ID:
1008 sio_data->kind = nct6116;
1009 break;
1010 case SIO_NCT6775_ID:
1011 sio_data->kind = nct6775;
1012 break;
1013 case SIO_NCT6776_ID:
1014 sio_data->kind = nct6776;
1015 break;
1016 case SIO_NCT6779_ID:
1017 sio_data->kind = nct6779;
1018 break;
1019 case SIO_NCT6791_ID:
1020 sio_data->kind = nct6791;
1021 break;
1022 case SIO_NCT6792_ID:
1023 sio_data->kind = nct6792;
1024 break;
1025 case SIO_NCT6793_ID:
1026 sio_data->kind = nct6793;
1027 break;
1028 case SIO_NCT6795_ID:
1029 sio_data->kind = nct6795;
1030 break;
1031 case SIO_NCT6796_ID:
1032 sio_data->kind = nct6796;
1033 break;
1034 case SIO_NCT6797_ID:
1035 sio_data->kind = nct6797;
1036 break;
1037 case SIO_NCT6798_ID:
1038 sio_data->kind = nct6798;
1039 break;
1040 case SIO_NCT6799_ID:
1041 sio_data->kind = nct6799;
1042 break;
1043 default:
1044 if (val != 0xffff)
1045 pr_debug("unsupported chip ID: 0x%04x\n", val);
1046 sio_data->sio_exit(sio_data);
1047 return -ENODEV;
1048 }
1049
1050 /* We have a known chip, find the HWM I/O address */
1051 sio_data->sio_select(sio_data, NCT6775_LD_HWM);
1052 val = (sio_data->sio_inb(sio_data, SIO_REG_ADDR) << 8)
1053 | sio_data->sio_inb(sio_data, SIO_REG_ADDR + 1);
1054 addr = val & IOREGION_ALIGNMENT;
1055 if (addr == 0) {
1056 pr_err("Refusing to enable a Super-I/O device with a base I/O port 0\n");
1057 sio_data->sio_exit(sio_data);
1058 return -ENODEV;
1059 }
1060
1061 /* Activate logical device if needed */
1062 val = sio_data->sio_inb(sio_data, SIO_REG_ENABLE);
1063 if (!(val & 0x01)) {
1064 pr_warn("Forcibly enabling Super-I/O. Sensor is probably unusable.\n");
1065 sio_data->sio_outb(sio_data, SIO_REG_ENABLE, val | 0x01);
1066 }
1067
1068 if (sio_data->kind == nct6791 || sio_data->kind == nct6792 ||
1069 sio_data->kind == nct6793 || sio_data->kind == nct6795 ||
1070 sio_data->kind == nct6796 || sio_data->kind == nct6797 ||
1071 sio_data->kind == nct6798 || sio_data->kind == nct6799)
1072 nct6791_enable_io_mapping(sio_data);
1073
1074 sio_data->sio_exit(sio_data);
1075 pr_info("Found %s or compatible chip at %#x:%#x\n",
1076 nct6775_sio_names[sio_data->kind], sioaddr, addr);
1077
1078 return addr;
1079}
1080
1081/*
1082 * when Super-I/O functions move to a separate file, the Super-I/O
1083 * bus will manage the lifetime of the device and this module will only keep
1084 * track of the nct6775 driver. But since we use platform_device_alloc(), we
1085 * must keep track of the device
1086 */
1087static struct platform_device *pdev[2];
1088
1089static const char * const asus_wmi_boards[] = {
1090 "B360M-BASALT",
1091 "B360M-D3H",
1092 "EX-B360M-V",
1093 "EX-B360M-V3",
1094 "EX-B360M-V5",
1095 "EX-B460M-V5",
1096 "EX-H410M-V3",
1097 "PRIME A520M-A",
1098 "PRIME A520M-A II",
1099 "PRIME A520M-E",
1100 "PRIME A520M-K",
1101 "PRIME B360-PLUS",
1102 "PRIME B360M-A",
1103 "PRIME B360M-C",
1104 "PRIME B360M-D",
1105 "PRIME B360M-K",
1106 "PRIME B460-PLUS",
1107 "PRIME B460I-PLUS",
1108 "PRIME B460M-A",
1109 "PRIME B460M-A R2.0",
1110 "PRIME B460M-K",
1111 "PRIME B550-PLUS",
1112 "PRIME B550-PLUS AC-HES",
1113 "PRIME B550M-A",
1114 "PRIME B550M-A (WI-FI)",
1115 "PRIME B550M-A AC",
1116 "PRIME B550M-A WIFI II",
1117 "PRIME B550M-K",
1118 "PRIME H310-PLUS",
1119 "PRIME H310I-PLUS",
1120 "PRIME H310M-A",
1121 "PRIME H310M-C",
1122 "PRIME H310M-D",
1123 "PRIME H310M-DASH",
1124 "PRIME H310M-E",
1125 "PRIME H310M-E/BR",
1126 "PRIME H310M-F",
1127 "PRIME H310M-K",
1128 "PRIME H310T",
1129 "PRIME H370-A",
1130 "PRIME H370-PLUS",
1131 "PRIME H370M-PLUS",
1132 "PRIME H410I-PLUS",
1133 "PRIME H410M-A",
1134 "PRIME H410M-D",
1135 "PRIME H410M-E",
1136 "PRIME H410M-F",
1137 "PRIME H410M-K",
1138 "PRIME H410M-K R2.0",
1139 "PRIME H410M-R",
1140 "PRIME H470-PLUS",
1141 "PRIME H470M-PLUS",
1142 "PRIME H510M-K R2.0",
1143 "PRIME Q370M-C",
1144 "PRIME X570-P",
1145 "PRIME X570-PRO",
1146 "PRIME Z390-A",
1147 "PRIME Z390-A/H10",
1148 "PRIME Z390-P",
1149 "PRIME Z390M-PLUS",
1150 "PRIME Z490-A",
1151 "PRIME Z490-P",
1152 "PRIME Z490-V",
1153 "PRIME Z490M-PLUS",
1154 "PRO B460M-C",
1155 "PRO H410M-C",
1156 "PRO H410T",
1157 "PRO Q470M-C",
1158 "Pro A520M-C",
1159 "Pro A520M-C II",
1160 "Pro B550M-C",
1161 "Pro WS X570-ACE",
1162 "ProArt B550-CREATOR",
1163 "ProArt X570-CREATOR WIFI",
1164 "ProArt Z490-CREATOR 10G",
1165 "ROG CROSSHAIR VIII DARK HERO",
1166 "ROG CROSSHAIR VIII EXTREME",
1167 "ROG CROSSHAIR VIII FORMULA",
1168 "ROG CROSSHAIR VIII HERO",
1169 "ROG CROSSHAIR VIII HERO (WI-FI)",
1170 "ROG CROSSHAIR VIII IMPACT",
1171 "ROG MAXIMUS XI APEX",
1172 "ROG MAXIMUS XI CODE",
1173 "ROG MAXIMUS XI EXTREME",
1174 "ROG MAXIMUS XI FORMULA",
1175 "ROG MAXIMUS XI GENE",
1176 "ROG MAXIMUS XI HERO",
1177 "ROG MAXIMUS XI HERO (WI-FI)",
1178 "ROG MAXIMUS XII APEX",
1179 "ROG MAXIMUS XII EXTREME",
1180 "ROG MAXIMUS XII FORMULA",
1181 "ROG MAXIMUS XII HERO (WI-FI)",
1182 "ROG STRIX B360-F GAMING",
1183 "ROG STRIX B360-G GAMING",
1184 "ROG STRIX B360-H GAMING",
1185 "ROG STRIX B360-H GAMING/OPTANE",
1186 "ROG STRIX B360-I GAMING",
1187 "ROG STRIX B460-F GAMING",
1188 "ROG STRIX B460-G GAMING",
1189 "ROG STRIX B460-H GAMING",
1190 "ROG STRIX B460-I GAMING",
1191 "ROG STRIX B550-A GAMING",
1192 "ROG STRIX B550-E GAMING",
1193 "ROG STRIX B550-F GAMING",
1194 "ROG STRIX B550-F GAMING (WI-FI)",
1195 "ROG STRIX B550-F GAMING WIFI II",
1196 "ROG STRIX B550-I GAMING",
1197 "ROG STRIX B550-XE GAMING WIFI",
1198 "ROG STRIX H370-F GAMING",
1199 "ROG STRIX H370-I GAMING",
1200 "ROG STRIX H470-I GAMING",
1201 "ROG STRIX X570-E GAMING",
1202 "ROG STRIX X570-E GAMING WIFI II",
1203 "ROG STRIX X570-F GAMING",
1204 "ROG STRIX X570-I GAMING",
1205 "ROG STRIX Z390-E GAMING",
1206 "ROG STRIX Z390-F GAMING",
1207 "ROG STRIX Z390-H GAMING",
1208 "ROG STRIX Z390-I GAMING",
1209 "ROG STRIX Z490-A GAMING",
1210 "ROG STRIX Z490-E GAMING",
1211 "ROG STRIX Z490-F GAMING",
1212 "ROG STRIX Z490-G GAMING",
1213 "ROG STRIX Z490-G GAMING (WI-FI)",
1214 "ROG STRIX Z490-H GAMING",
1215 "ROG STRIX Z490-I GAMING",
1216 "TUF B360-PLUS GAMING",
1217 "TUF B360-PRO GAMING",
1218 "TUF B360-PRO GAMING (WI-FI)",
1219 "TUF B360M-E GAMING",
1220 "TUF B360M-PLUS GAMING",
1221 "TUF B360M-PLUS GAMING S",
1222 "TUF B360M-PLUS GAMING/BR",
1223 "TUF GAMING A520M-PLUS",
1224 "TUF GAMING A520M-PLUS II",
1225 "TUF GAMING A520M-PLUS WIFI",
1226 "TUF GAMING B460-PLUS",
1227 "TUF GAMING B460-PRO (WI-FI)",
1228 "TUF GAMING B460M-PLUS",
1229 "TUF GAMING B460M-PLUS (WI-FI)",
1230 "TUF GAMING B460M-PRO",
1231 "TUF GAMING B550-PLUS",
1232 "TUF GAMING B550-PLUS (WI-FI)",
1233 "TUF GAMING B550-PLUS WIFI II",
1234 "TUF GAMING B550-PRO",
1235 "TUF GAMING B550M ZAKU (WI-FI)",
1236 "TUF GAMING B550M-E",
1237 "TUF GAMING B550M-E WIFI",
1238 "TUF GAMING B550M-PLUS",
1239 "TUF GAMING B550M-PLUS (WI-FI)",
1240 "TUF GAMING B550M-PLUS WIFI II",
1241 "TUF GAMING H470-PRO",
1242 "TUF GAMING H470-PRO (WI-FI)",
1243 "TUF GAMING X570-PLUS",
1244 "TUF GAMING X570-PLUS (WI-FI)",
1245 "TUF GAMING X570-PLUS_BR",
1246 "TUF GAMING X570-PRO (WI-FI)",
1247 "TUF GAMING X570-PRO WIFI II",
1248 "TUF GAMING Z490-PLUS",
1249 "TUF GAMING Z490-PLUS (WI-FI)",
1250 "TUF H310-PLUS GAMING",
1251 "TUF H310M-PLUS GAMING",
1252 "TUF H310M-PLUS GAMING/BR",
1253 "TUF H370-PRO GAMING",
1254 "TUF H370-PRO GAMING (WI-FI)",
1255 "TUF Z390-PLUS GAMING",
1256 "TUF Z390-PLUS GAMING (WI-FI)",
1257 "TUF Z390-PRO GAMING",
1258 "TUF Z390M-PRO GAMING",
1259 "TUF Z390M-PRO GAMING (WI-FI)",
1260 "WS Z390 PRO",
1261 "Z490-GUNDAM (WI-FI)",
1262};
1263
1264static const char * const asus_msi_boards[] = {
1265 "B560M-P",
1266 "EX-B560M-V5",
1267 "EX-B660M-V5 D4",
1268 "EX-B660M-V5 PRO D4",
1269 "EX-B760M-V5 D4",
1270 "EX-H510M-V3",
1271 "EX-H610M-V3 D4",
1272 "PRIME A620M-A",
1273 "PRIME B560-PLUS",
1274 "PRIME B560-PLUS AC-HES",
1275 "PRIME B560M-A",
1276 "PRIME B560M-A AC",
1277 "PRIME B560M-K",
1278 "PRIME B650-PLUS",
1279 "PRIME B650M-A",
1280 "PRIME B650M-A AX",
1281 "PRIME B650M-A AX II",
1282 "PRIME B650M-A II",
1283 "PRIME B650M-A WIFI",
1284 "PRIME B650M-A WIFI II",
1285 "PRIME B660-PLUS D4",
1286 "PRIME B660M-A AC D4",
1287 "PRIME B660M-A D4",
1288 "PRIME B660M-A WIFI D4",
1289 "PRIME B760-PLUS",
1290 "PRIME B760-PLUS D4",
1291 "PRIME B760M-A",
1292 "PRIME B760M-A AX D4",
1293 "PRIME B760M-A D4",
1294 "PRIME B760M-A WIFI",
1295 "PRIME B760M-A WIFI D4",
1296 "PRIME B760M-AJ D4",
1297 "PRIME B760M-K D4",
1298 "PRIME H510M-A",
1299 "PRIME H510M-A WIFI",
1300 "PRIME H510M-D",
1301 "PRIME H510M-E",
1302 "PRIME H510M-F",
1303 "PRIME H510M-K",
1304 "PRIME H510M-R",
1305 "PRIME H510T2/CSM",
1306 "PRIME H570-PLUS",
1307 "PRIME H570M-PLUS",
1308 "PRIME H610I-PLUS D4",
1309 "PRIME H610M-A D4",
1310 "PRIME H610M-A WIFI D4",
1311 "PRIME H610M-D D4",
1312 "PRIME H610M-E D4",
1313 "PRIME H610M-F D4",
1314 "PRIME H610M-K D4",
1315 "PRIME H610M-R D4",
1316 "PRIME H670-PLUS D4",
1317 "PRIME H770-PLUS D4",
1318 "PRIME X670-P",
1319 "PRIME X670-P WIFI",
1320 "PRIME X670E-PRO WIFI",
1321 "PRIME Z590-A",
1322 "PRIME Z590-P",
1323 "PRIME Z590-P WIFI",
1324 "PRIME Z590-V",
1325 "PRIME Z590M-PLUS",
1326 "PRIME Z690-A",
1327 "PRIME Z690-P",
1328 "PRIME Z690-P D4",
1329 "PRIME Z690-P WIFI",
1330 "PRIME Z690-P WIFI D4",
1331 "PRIME Z690M-PLUS D4",
1332 "PRIME Z790-A WIFI",
1333 "PRIME Z790-P",
1334 "PRIME Z790-P D4",
1335 "PRIME Z790-P WIFI",
1336 "PRIME Z790-P WIFI D4",
1337 "PRIME Z790M-PLUS",
1338 "PRIME Z790M-PLUS D4",
1339 "Pro B560M-C",
1340 "Pro B560M-CT",
1341 "Pro B660M-C",
1342 "Pro B660M-C D4",
1343 "Pro B760M-C",
1344 "Pro B760M-CT",
1345 "Pro H510M-C",
1346 "Pro H510M-CT",
1347 "Pro H610M-C",
1348 "Pro H610M-C D4",
1349 "Pro H610M-CT D4",
1350 "Pro H610T D4",
1351 "Pro Q670M-C",
1352 "Pro WS W680-ACE",
1353 "Pro WS W680-ACE IPMI",
1354 "Pro WS W790-ACE",
1355 "Pro WS W790E-SAGE SE",
1356 "ProArt B650-CREATOR",
1357 "ProArt B660-CREATOR D4",
1358 "ProArt B760-CREATOR D4",
1359 "ProArt X670E-CREATOR WIFI",
1360 "ProArt Z690-CREATOR WIFI",
1361 "ProArt Z790-CREATOR WIFI",
1362 "ROG CROSSHAIR X670E EXTREME",
1363 "ROG CROSSHAIR X670E GENE",
1364 "ROG CROSSHAIR X670E HERO",
1365 "ROG MAXIMUS XIII APEX",
1366 "ROG MAXIMUS XIII EXTREME",
1367 "ROG MAXIMUS XIII EXTREME GLACIAL",
1368 "ROG MAXIMUS XIII HERO",
1369 "ROG MAXIMUS Z690 APEX",
1370 "ROG MAXIMUS Z690 EXTREME",
1371 "ROG MAXIMUS Z690 EXTREME GLACIAL",
1372 "ROG MAXIMUS Z690 FORMULA",
1373 "ROG MAXIMUS Z690 HERO",
1374 "ROG MAXIMUS Z690 HERO EVA",
1375 "ROG MAXIMUS Z790 APEX",
1376 "ROG MAXIMUS Z790 EXTREME",
1377 "ROG MAXIMUS Z790 HERO",
1378 "ROG STRIX B560-A GAMING WIFI",
1379 "ROG STRIX B560-E GAMING WIFI",
1380 "ROG STRIX B560-F GAMING WIFI",
1381 "ROG STRIX B560-G GAMING WIFI",
1382 "ROG STRIX B560-I GAMING WIFI",
1383 "ROG STRIX B650-A GAMING WIFI",
1384 "ROG STRIX B650E-E GAMING WIFI",
1385 "ROG STRIX B650E-F GAMING WIFI",
1386 "ROG STRIX B650E-I GAMING WIFI",
1387 "ROG STRIX B660-A GAMING WIFI",
1388 "ROG STRIX B660-A GAMING WIFI D4",
1389 "ROG STRIX B660-F GAMING WIFI",
1390 "ROG STRIX B660-G GAMING WIFI",
1391 "ROG STRIX B660-I GAMING WIFI",
1392 "ROG STRIX B760-A GAMING WIFI",
1393 "ROG STRIX B760-A GAMING WIFI D4",
1394 "ROG STRIX B760-F GAMING WIFI",
1395 "ROG STRIX B760-G GAMING WIFI",
1396 "ROG STRIX B760-G GAMING WIFI D4",
1397 "ROG STRIX B760-I GAMING WIFI",
1398 "ROG STRIX X670E-A GAMING WIFI",
1399 "ROG STRIX X670E-E GAMING WIFI",
1400 "ROG STRIX X670E-F GAMING WIFI",
1401 "ROG STRIX X670E-I GAMING WIFI",
1402 "ROG STRIX Z590-A GAMING WIFI",
1403 "ROG STRIX Z590-A GAMING WIFI II",
1404 "ROG STRIX Z590-E GAMING WIFI",
1405 "ROG STRIX Z590-F GAMING WIFI",
1406 "ROG STRIX Z590-I GAMING WIFI",
1407 "ROG STRIX Z690-A GAMING WIFI",
1408 "ROG STRIX Z690-A GAMING WIFI D4",
1409 "ROG STRIX Z690-E GAMING WIFI",
1410 "ROG STRIX Z690-F GAMING WIFI",
1411 "ROG STRIX Z690-G GAMING WIFI",
1412 "ROG STRIX Z690-I GAMING WIFI",
1413 "ROG STRIX Z790-A GAMING WIFI",
1414 "ROG STRIX Z790-A GAMING WIFI D4",
1415 "ROG STRIX Z790-E GAMING WIFI",
1416 "ROG STRIX Z790-F GAMING WIFI",
1417 "ROG STRIX Z790-H GAMING WIFI",
1418 "ROG STRIX Z790-I GAMING WIFI",
1419 "TUF GAMING A620M-PLUS",
1420 "TUF GAMING A620M-PLUS WIFI",
1421 "TUF GAMING B560-PLUS WIFI",
1422 "TUF GAMING B560M-E",
1423 "TUF GAMING B560M-PLUS",
1424 "TUF GAMING B560M-PLUS WIFI",
1425 "TUF GAMING B650-PLUS",
1426 "TUF GAMING B650-PLUS WIFI",
1427 "TUF GAMING B650M-PLUS",
1428 "TUF GAMING B650M-PLUS WIFI",
1429 "TUF GAMING B660-PLUS WIFI D4",
1430 "TUF GAMING B660M-E D4",
1431 "TUF GAMING B660M-PLUS D4",
1432 "TUF GAMING B660M-PLUS WIFI",
1433 "TUF GAMING B660M-PLUS WIFI D4",
1434 "TUF GAMING B760-PLUS WIFI",
1435 "TUF GAMING B760-PLUS WIFI D4",
1436 "TUF GAMING B760M-BTF WIFI D4",
1437 "TUF GAMING B760M-E D4",
1438 "TUF GAMING B760M-PLUS",
1439 "TUF GAMING B760M-PLUS D4",
1440 "TUF GAMING B760M-PLUS WIFI",
1441 "TUF GAMING B760M-PLUS WIFI D4",
1442 "TUF GAMING H570-PRO",
1443 "TUF GAMING H570-PRO WIFI",
1444 "TUF GAMING H670-PRO WIFI D4",
1445 "TUF GAMING H770-PRO WIFI",
1446 "TUF GAMING X670E-PLUS",
1447 "TUF GAMING X670E-PLUS WIFI",
1448 "TUF GAMING Z590-PLUS",
1449 "TUF GAMING Z590-PLUS WIFI",
1450 "TUF GAMING Z690-PLUS",
1451 "TUF GAMING Z690-PLUS D4",
1452 "TUF GAMING Z690-PLUS WIFI",
1453 "TUF GAMING Z690-PLUS WIFI D4",
1454 "TUF GAMING Z790-PLUS D4",
1455 "TUF GAMING Z790-PLUS WIFI",
1456 "TUF GAMING Z790-PLUS WIFI D4",
1457 "Z590 WIFI GUNDAM EDITION",
1458};
1459
1460#if IS_ENABLED(CONFIG_ACPI)
1461/*
1462 * Callback for acpi_bus_for_each_dev() to find the right device
1463 * by _UID and _HID and return 1 to stop iteration.
1464 */
1465static int nct6775_asuswmi_device_match(struct device *dev, void *data)
1466{
1467 struct acpi_device *adev = to_acpi_device(dev);
1468
1469 if (acpi_dev_hid_uid_match(adev, ASUSWMI_DEVICE_HID, data)) {
1470 asus_acpi_dev = adev;
1471 return 1;
1472 }
1473
1474 return 0;
1475}
1476#endif
1477
1478static enum sensor_access nct6775_determine_access(const char *device_uid)
1479{
1480#if IS_ENABLED(CONFIG_ACPI)
1481 u8 tmp;
1482
1483 acpi_bus_for_each_dev(nct6775_asuswmi_device_match, (void *)device_uid);
1484 if (!asus_acpi_dev)
1485 return access_direct;
1486
1487 /* if reading chip id via ACPI succeeds, use WMI "WMBD" method for access */
1488 if (!nct6775_asuswmi_read(0, NCT6775_PORT_CHIPID, &tmp) && tmp) {
1489 pr_debug("Using Asus WMBD method of %s to access %#x chip.\n", device_uid, tmp);
1490 return access_asuswmi;
1491 }
1492#endif
1493
1494 return access_direct;
1495}
1496
1497static int __init sensors_nct6775_platform_init(void)
1498{
1499 int i, err;
1500 bool found = false;
1501 int address;
1502 struct resource res;
1503 struct nct6775_sio_data sio_data;
1504 int sioaddr[2] = { 0x2e, 0x4e };
1505 enum sensor_access access = access_direct;
1506 const char *board_vendor, *board_name;
1507
1508 err = platform_driver_register(&nct6775_driver);
1509 if (err)
1510 return err;
1511
1512 board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR);
1513 board_name = dmi_get_system_info(DMI_BOARD_NAME);
1514
1515 if (board_name && board_vendor &&
1516 !strcmp(board_vendor, "ASUSTeK COMPUTER INC.")) {
1517 err = match_string(asus_wmi_boards, ARRAY_SIZE(asus_wmi_boards),
1518 board_name);
1519 if (err >= 0)
1520 access = nct6775_determine_access(ASUSWMI_DEVICE_UID);
1521
1522 err = match_string(asus_msi_boards, ARRAY_SIZE(asus_msi_boards),
1523 board_name);
1524 if (err >= 0)
1525 access = nct6775_determine_access(ASUSMSI_DEVICE_UID);
1526 }
1527
1528 /*
1529 * initialize sio_data->kind and sio_data->sioreg.
1530 *
1531 * when Super-I/O functions move to a separate file, the Super-I/O
1532 * driver will probe 0x2e and 0x4e and auto-detect the presence of a
1533 * nct6775 hardware monitor, and call probe()
1534 */
1535 for (i = 0; i < ARRAY_SIZE(pdev); i++) {
1536 sio_data.sio_outb = superio_outb;
1537 sio_data.sio_inb = superio_inb;
1538 sio_data.sio_select = superio_select;
1539 sio_data.sio_enter = superio_enter;
1540 sio_data.sio_exit = superio_exit;
1541
1542 address = nct6775_find(sioaddr[i], &sio_data);
1543 if (address <= 0)
1544 continue;
1545
1546 found = true;
1547
1548 sio_data.access = access;
1549
1550 if (access == access_asuswmi) {
1551 sio_data.sio_outb = superio_wmi_outb;
1552 sio_data.sio_inb = superio_wmi_inb;
1553 sio_data.sio_select = superio_wmi_select;
1554 sio_data.sio_enter = superio_wmi_enter;
1555 sio_data.sio_exit = superio_wmi_exit;
1556 }
1557
1558 pdev[i] = platform_device_alloc(DRVNAME, address);
1559 if (!pdev[i]) {
1560 err = -ENOMEM;
1561 goto exit_device_unregister;
1562 }
1563
1564 err = platform_device_add_data(pdev[i], &sio_data,
1565 sizeof(struct nct6775_sio_data));
1566 if (err)
1567 goto exit_device_put;
1568
1569 if (sio_data.access == access_direct) {
1570 memset(&res, 0, sizeof(res));
1571 res.name = DRVNAME;
1572 res.start = address + IOREGION_OFFSET;
1573 res.end = address + IOREGION_OFFSET + IOREGION_LENGTH - 1;
1574 res.flags = IORESOURCE_IO;
1575
1576 err = acpi_check_resource_conflict(&res);
1577 if (err) {
1578 platform_device_put(pdev[i]);
1579 pdev[i] = NULL;
1580 continue;
1581 }
1582
1583 err = platform_device_add_resources(pdev[i], &res, 1);
1584 if (err)
1585 goto exit_device_put;
1586 }
1587
1588 /* platform_device_add calls probe() */
1589 err = platform_device_add(pdev[i]);
1590 if (err)
1591 goto exit_device_put;
1592 }
1593 if (!found) {
1594 err = -ENODEV;
1595 goto exit_unregister;
1596 }
1597
1598 return 0;
1599
1600exit_device_put:
1601 platform_device_put(pdev[i]);
1602exit_device_unregister:
1603 while (i--)
1604 platform_device_unregister(pdev[i]);
1605exit_unregister:
1606 platform_driver_unregister(&nct6775_driver);
1607 return err;
1608}
1609
1610static void __exit sensors_nct6775_platform_exit(void)
1611{
1612 int i;
1613
1614 for (i = 0; i < ARRAY_SIZE(pdev); i++)
1615 platform_device_unregister(pdev[i]);
1616 platform_driver_unregister(&nct6775_driver);
1617}
1618
1619MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>");
1620MODULE_DESCRIPTION("Platform driver for NCT6775F and compatible chips");
1621MODULE_LICENSE("GPL");
1622MODULE_IMPORT_NS(HWMON_NCT6775);
1623
1624module_init(sensors_nct6775_platform_init);
1625module_exit(sensors_nct6775_platform_exit);
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * nct6775 - Platform driver for the hardware monitoring
4 * functionality of Nuvoton NCT677x Super-I/O chips
5 *
6 * Copyright (C) 2012 Guenter Roeck <linux@roeck-us.net>
7 */
8
9#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
10
11#include <linux/acpi.h>
12#include <linux/dmi.h>
13#include <linux/hwmon-sysfs.h>
14#include <linux/hwmon-vid.h>
15#include <linux/init.h>
16#include <linux/io.h>
17#include <linux/module.h>
18#include <linux/platform_device.h>
19#include <linux/regmap.h>
20#include <linux/wmi.h>
21
22#include "nct6775.h"
23
24enum sensor_access { access_direct, access_asuswmi };
25
26static const char * const nct6775_sio_names[] __initconst = {
27 "NCT6106D",
28 "NCT6116D",
29 "NCT6775F",
30 "NCT6776D/F",
31 "NCT6779D",
32 "NCT6791D",
33 "NCT6792D",
34 "NCT6793D",
35 "NCT6795D",
36 "NCT6796D",
37 "NCT6797D",
38 "NCT6798D",
39};
40
41static unsigned short force_id;
42module_param(force_id, ushort, 0);
43MODULE_PARM_DESC(force_id, "Override the detected device ID");
44
45static unsigned short fan_debounce;
46module_param(fan_debounce, ushort, 0);
47MODULE_PARM_DESC(fan_debounce, "Enable debouncing for fan RPM signal");
48
49#define DRVNAME "nct6775"
50
51#define NCT6775_PORT_CHIPID 0x58
52
53/*
54 * ISA constants
55 */
56
57#define IOREGION_ALIGNMENT (~7)
58#define IOREGION_OFFSET 5
59#define IOREGION_LENGTH 2
60#define ADDR_REG_OFFSET 0
61#define DATA_REG_OFFSET 1
62
63/*
64 * Super-I/O constants and functions
65 */
66
67#define NCT6775_LD_ACPI 0x0a
68#define NCT6775_LD_HWM 0x0b
69#define NCT6775_LD_VID 0x0d
70#define NCT6775_LD_12 0x12
71
72#define SIO_REG_LDSEL 0x07 /* Logical device select */
73#define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */
74#define SIO_REG_ENABLE 0x30 /* Logical device enable */
75#define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */
76
77#define SIO_NCT6106_ID 0xc450
78#define SIO_NCT6116_ID 0xd280
79#define SIO_NCT6775_ID 0xb470
80#define SIO_NCT6776_ID 0xc330
81#define SIO_NCT6779_ID 0xc560
82#define SIO_NCT6791_ID 0xc800
83#define SIO_NCT6792_ID 0xc910
84#define SIO_NCT6793_ID 0xd120
85#define SIO_NCT6795_ID 0xd350
86#define SIO_NCT6796_ID 0xd420
87#define SIO_NCT6797_ID 0xd450
88#define SIO_NCT6798_ID 0xd428
89#define SIO_ID_MASK 0xFFF8
90
91/*
92 * Control registers
93 */
94#define NCT6775_REG_CR_FAN_DEBOUNCE 0xf0
95
96struct nct6775_sio_data {
97 int sioreg;
98 int ld;
99 enum kinds kind;
100 enum sensor_access access;
101
102 /* superio_() callbacks */
103 void (*sio_outb)(struct nct6775_sio_data *sio_data, int reg, int val);
104 int (*sio_inb)(struct nct6775_sio_data *sio_data, int reg);
105 void (*sio_select)(struct nct6775_sio_data *sio_data, int ld);
106 int (*sio_enter)(struct nct6775_sio_data *sio_data);
107 void (*sio_exit)(struct nct6775_sio_data *sio_data);
108};
109
110#define ASUSWMI_MONITORING_GUID "466747A0-70EC-11DE-8A39-0800200C9A66"
111#define ASUSWMI_METHODID_RSIO 0x5253494F
112#define ASUSWMI_METHODID_WSIO 0x5753494F
113#define ASUSWMI_METHODID_RHWM 0x5248574D
114#define ASUSWMI_METHODID_WHWM 0x5748574D
115#define ASUSWMI_UNSUPPORTED_METHOD 0xFFFFFFFE
116
117static int nct6775_asuswmi_evaluate_method(u32 method_id, u8 bank, u8 reg, u8 val, u32 *retval)
118{
119#if IS_ENABLED(CONFIG_ACPI_WMI)
120 u32 args = bank | (reg << 8) | (val << 16);
121 struct acpi_buffer input = { (acpi_size) sizeof(args), &args };
122 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
123 acpi_status status;
124 union acpi_object *obj;
125 u32 tmp = ASUSWMI_UNSUPPORTED_METHOD;
126
127 status = wmi_evaluate_method(ASUSWMI_MONITORING_GUID, 0,
128 method_id, &input, &output);
129
130 if (ACPI_FAILURE(status))
131 return -EIO;
132
133 obj = output.pointer;
134 if (obj && obj->type == ACPI_TYPE_INTEGER)
135 tmp = obj->integer.value;
136
137 if (retval)
138 *retval = tmp;
139
140 kfree(obj);
141
142 if (tmp == ASUSWMI_UNSUPPORTED_METHOD)
143 return -ENODEV;
144 return 0;
145#else
146 return -EOPNOTSUPP;
147#endif
148}
149
150static inline int nct6775_asuswmi_write(u8 bank, u8 reg, u8 val)
151{
152 return nct6775_asuswmi_evaluate_method(ASUSWMI_METHODID_WHWM, bank,
153 reg, val, NULL);
154}
155
156static inline int nct6775_asuswmi_read(u8 bank, u8 reg, u8 *val)
157{
158 u32 ret, tmp = 0;
159
160 ret = nct6775_asuswmi_evaluate_method(ASUSWMI_METHODID_RHWM, bank,
161 reg, 0, &tmp);
162 *val = tmp;
163 return ret;
164}
165
166static int superio_wmi_inb(struct nct6775_sio_data *sio_data, int reg)
167{
168 int tmp = 0;
169
170 nct6775_asuswmi_evaluate_method(ASUSWMI_METHODID_RSIO, sio_data->ld,
171 reg, 0, &tmp);
172 return tmp;
173}
174
175static void superio_wmi_outb(struct nct6775_sio_data *sio_data, int reg, int val)
176{
177 nct6775_asuswmi_evaluate_method(ASUSWMI_METHODID_WSIO, sio_data->ld,
178 reg, val, NULL);
179}
180
181static void superio_wmi_select(struct nct6775_sio_data *sio_data, int ld)
182{
183 sio_data->ld = ld;
184}
185
186static int superio_wmi_enter(struct nct6775_sio_data *sio_data)
187{
188 return 0;
189}
190
191static void superio_wmi_exit(struct nct6775_sio_data *sio_data)
192{
193}
194
195static void superio_outb(struct nct6775_sio_data *sio_data, int reg, int val)
196{
197 int ioreg = sio_data->sioreg;
198
199 outb(reg, ioreg);
200 outb(val, ioreg + 1);
201}
202
203static int superio_inb(struct nct6775_sio_data *sio_data, int reg)
204{
205 int ioreg = sio_data->sioreg;
206
207 outb(reg, ioreg);
208 return inb(ioreg + 1);
209}
210
211static void superio_select(struct nct6775_sio_data *sio_data, int ld)
212{
213 int ioreg = sio_data->sioreg;
214
215 outb(SIO_REG_LDSEL, ioreg);
216 outb(ld, ioreg + 1);
217}
218
219static int superio_enter(struct nct6775_sio_data *sio_data)
220{
221 int ioreg = sio_data->sioreg;
222
223 /*
224 * Try to reserve <ioreg> and <ioreg + 1> for exclusive access.
225 */
226 if (!request_muxed_region(ioreg, 2, DRVNAME))
227 return -EBUSY;
228
229 outb(0x87, ioreg);
230 outb(0x87, ioreg);
231
232 return 0;
233}
234
235static void superio_exit(struct nct6775_sio_data *sio_data)
236{
237 int ioreg = sio_data->sioreg;
238
239 outb(0xaa, ioreg);
240 outb(0x02, ioreg);
241 outb(0x02, ioreg + 1);
242 release_region(ioreg, 2);
243}
244
245static inline void nct6775_wmi_set_bank(struct nct6775_data *data, u16 reg)
246{
247 u8 bank = reg >> 8;
248
249 data->bank = bank;
250}
251
252static int nct6775_wmi_reg_read(void *ctx, unsigned int reg, unsigned int *val)
253{
254 struct nct6775_data *data = ctx;
255 int err, word_sized = nct6775_reg_is_word_sized(data, reg);
256 u8 tmp = 0;
257 u16 res;
258
259 nct6775_wmi_set_bank(data, reg);
260
261 err = nct6775_asuswmi_read(data->bank, reg & 0xff, &tmp);
262 if (err)
263 return err;
264
265 res = tmp;
266 if (word_sized) {
267 err = nct6775_asuswmi_read(data->bank, (reg & 0xff) + 1, &tmp);
268 if (err)
269 return err;
270
271 res = (res << 8) + tmp;
272 }
273 *val = res;
274 return 0;
275}
276
277static int nct6775_wmi_reg_write(void *ctx, unsigned int reg, unsigned int value)
278{
279 struct nct6775_data *data = ctx;
280 int res, word_sized = nct6775_reg_is_word_sized(data, reg);
281
282 nct6775_wmi_set_bank(data, reg);
283
284 if (word_sized) {
285 res = nct6775_asuswmi_write(data->bank, reg & 0xff, value >> 8);
286 if (res)
287 return res;
288
289 res = nct6775_asuswmi_write(data->bank, (reg & 0xff) + 1, value);
290 } else {
291 res = nct6775_asuswmi_write(data->bank, reg & 0xff, value);
292 }
293
294 return res;
295}
296
297/*
298 * On older chips, only registers 0x50-0x5f are banked.
299 * On more recent chips, all registers are banked.
300 * Assume that is the case and set the bank number for each access.
301 * Cache the bank number so it only needs to be set if it changes.
302 */
303static inline void nct6775_set_bank(struct nct6775_data *data, u16 reg)
304{
305 u8 bank = reg >> 8;
306
307 if (data->bank != bank) {
308 outb_p(NCT6775_REG_BANK, data->addr + ADDR_REG_OFFSET);
309 outb_p(bank, data->addr + DATA_REG_OFFSET);
310 data->bank = bank;
311 }
312}
313
314static int nct6775_reg_read(void *ctx, unsigned int reg, unsigned int *val)
315{
316 struct nct6775_data *data = ctx;
317 int word_sized = nct6775_reg_is_word_sized(data, reg);
318
319 nct6775_set_bank(data, reg);
320 outb_p(reg & 0xff, data->addr + ADDR_REG_OFFSET);
321 *val = inb_p(data->addr + DATA_REG_OFFSET);
322 if (word_sized) {
323 outb_p((reg & 0xff) + 1,
324 data->addr + ADDR_REG_OFFSET);
325 *val = (*val << 8) + inb_p(data->addr + DATA_REG_OFFSET);
326 }
327 return 0;
328}
329
330static int nct6775_reg_write(void *ctx, unsigned int reg, unsigned int value)
331{
332 struct nct6775_data *data = ctx;
333 int word_sized = nct6775_reg_is_word_sized(data, reg);
334
335 nct6775_set_bank(data, reg);
336 outb_p(reg & 0xff, data->addr + ADDR_REG_OFFSET);
337 if (word_sized) {
338 outb_p(value >> 8, data->addr + DATA_REG_OFFSET);
339 outb_p((reg & 0xff) + 1,
340 data->addr + ADDR_REG_OFFSET);
341 }
342 outb_p(value & 0xff, data->addr + DATA_REG_OFFSET);
343 return 0;
344}
345
346static void nct6791_enable_io_mapping(struct nct6775_sio_data *sio_data)
347{
348 int val;
349
350 val = sio_data->sio_inb(sio_data, NCT6791_REG_HM_IO_SPACE_LOCK_ENABLE);
351 if (val & 0x10) {
352 pr_info("Enabling hardware monitor logical device mappings.\n");
353 sio_data->sio_outb(sio_data, NCT6791_REG_HM_IO_SPACE_LOCK_ENABLE,
354 val & ~0x10);
355 }
356}
357
358static int nct6775_suspend(struct device *dev)
359{
360 int err;
361 u16 tmp;
362 struct nct6775_data *data = nct6775_update_device(dev);
363
364 if (IS_ERR(data))
365 return PTR_ERR(data);
366
367 mutex_lock(&data->update_lock);
368 err = nct6775_read_value(data, data->REG_VBAT, &tmp);
369 if (err)
370 goto out;
371 data->vbat = tmp;
372 if (data->kind == nct6775) {
373 err = nct6775_read_value(data, NCT6775_REG_FANDIV1, &tmp);
374 if (err)
375 goto out;
376 data->fandiv1 = tmp;
377
378 err = nct6775_read_value(data, NCT6775_REG_FANDIV2, &tmp);
379 if (err)
380 goto out;
381 data->fandiv2 = tmp;
382 }
383out:
384 mutex_unlock(&data->update_lock);
385
386 return err;
387}
388
389static int nct6775_resume(struct device *dev)
390{
391 struct nct6775_data *data = dev_get_drvdata(dev);
392 struct nct6775_sio_data *sio_data = dev_get_platdata(dev);
393 int i, j, err = 0;
394 u8 reg;
395
396 mutex_lock(&data->update_lock);
397 data->bank = 0xff; /* Force initial bank selection */
398
399 err = sio_data->sio_enter(sio_data);
400 if (err)
401 goto abort;
402
403 sio_data->sio_select(sio_data, NCT6775_LD_HWM);
404 reg = sio_data->sio_inb(sio_data, SIO_REG_ENABLE);
405 if (reg != data->sio_reg_enable)
406 sio_data->sio_outb(sio_data, SIO_REG_ENABLE, data->sio_reg_enable);
407
408 if (data->kind == nct6791 || data->kind == nct6792 ||
409 data->kind == nct6793 || data->kind == nct6795 ||
410 data->kind == nct6796 || data->kind == nct6797 ||
411 data->kind == nct6798)
412 nct6791_enable_io_mapping(sio_data);
413
414 sio_data->sio_exit(sio_data);
415
416 /* Restore limits */
417 for (i = 0; i < data->in_num; i++) {
418 if (!(data->have_in & BIT(i)))
419 continue;
420
421 err = nct6775_write_value(data, data->REG_IN_MINMAX[0][i], data->in[i][1]);
422 if (err)
423 goto abort;
424 err = nct6775_write_value(data, data->REG_IN_MINMAX[1][i], data->in[i][2]);
425 if (err)
426 goto abort;
427 }
428
429 for (i = 0; i < ARRAY_SIZE(data->fan_min); i++) {
430 if (!(data->has_fan_min & BIT(i)))
431 continue;
432
433 err = nct6775_write_value(data, data->REG_FAN_MIN[i], data->fan_min[i]);
434 if (err)
435 goto abort;
436 }
437
438 for (i = 0; i < NUM_TEMP; i++) {
439 if (!(data->have_temp & BIT(i)))
440 continue;
441
442 for (j = 1; j < ARRAY_SIZE(data->reg_temp); j++)
443 if (data->reg_temp[j][i]) {
444 err = nct6775_write_temp(data, data->reg_temp[j][i],
445 data->temp[j][i]);
446 if (err)
447 goto abort;
448 }
449 }
450
451 /* Restore other settings */
452 err = nct6775_write_value(data, data->REG_VBAT, data->vbat);
453 if (err)
454 goto abort;
455 if (data->kind == nct6775) {
456 err = nct6775_write_value(data, NCT6775_REG_FANDIV1, data->fandiv1);
457 if (err)
458 goto abort;
459 err = nct6775_write_value(data, NCT6775_REG_FANDIV2, data->fandiv2);
460 }
461
462abort:
463 /* Force re-reading all values */
464 data->valid = false;
465 mutex_unlock(&data->update_lock);
466
467 return err;
468}
469
470static DEFINE_SIMPLE_DEV_PM_OPS(nct6775_dev_pm_ops, nct6775_suspend, nct6775_resume);
471
472static void
473nct6775_check_fan_inputs(struct nct6775_data *data, struct nct6775_sio_data *sio_data)
474{
475 bool fan3pin = false, fan4pin = false, fan4min = false;
476 bool fan5pin = false, fan6pin = false, fan7pin = false;
477 bool pwm3pin = false, pwm4pin = false, pwm5pin = false;
478 bool pwm6pin = false, pwm7pin = false;
479
480 /* Store SIO_REG_ENABLE for use during resume */
481 sio_data->sio_select(sio_data, NCT6775_LD_HWM);
482 data->sio_reg_enable = sio_data->sio_inb(sio_data, SIO_REG_ENABLE);
483
484 /* fan4 and fan5 share some pins with the GPIO and serial flash */
485 if (data->kind == nct6775) {
486 int cr2c = sio_data->sio_inb(sio_data, 0x2c);
487
488 fan3pin = cr2c & BIT(6);
489 pwm3pin = cr2c & BIT(7);
490
491 /* On NCT6775, fan4 shares pins with the fdc interface */
492 fan4pin = !(sio_data->sio_inb(sio_data, 0x2A) & 0x80);
493 } else if (data->kind == nct6776) {
494 bool gpok = sio_data->sio_inb(sio_data, 0x27) & 0x80;
495 const char *board_vendor, *board_name;
496
497 board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR);
498 board_name = dmi_get_system_info(DMI_BOARD_NAME);
499
500 if (board_name && board_vendor &&
501 !strcmp(board_vendor, "ASRock")) {
502 /*
503 * Auxiliary fan monitoring is not enabled on ASRock
504 * Z77 Pro4-M if booted in UEFI Ultra-FastBoot mode.
505 * Observed with BIOS version 2.00.
506 */
507 if (!strcmp(board_name, "Z77 Pro4-M")) {
508 if ((data->sio_reg_enable & 0xe0) != 0xe0) {
509 data->sio_reg_enable |= 0xe0;
510 sio_data->sio_outb(sio_data, SIO_REG_ENABLE,
511 data->sio_reg_enable);
512 }
513 }
514 }
515
516 if (data->sio_reg_enable & 0x80)
517 fan3pin = gpok;
518 else
519 fan3pin = !(sio_data->sio_inb(sio_data, 0x24) & 0x40);
520
521 if (data->sio_reg_enable & 0x40)
522 fan4pin = gpok;
523 else
524 fan4pin = sio_data->sio_inb(sio_data, 0x1C) & 0x01;
525
526 if (data->sio_reg_enable & 0x20)
527 fan5pin = gpok;
528 else
529 fan5pin = sio_data->sio_inb(sio_data, 0x1C) & 0x02;
530
531 fan4min = fan4pin;
532 pwm3pin = fan3pin;
533 } else if (data->kind == nct6106) {
534 int cr24 = sio_data->sio_inb(sio_data, 0x24);
535
536 fan3pin = !(cr24 & 0x80);
537 pwm3pin = cr24 & 0x08;
538 } else if (data->kind == nct6116) {
539 int cr1a = sio_data->sio_inb(sio_data, 0x1a);
540 int cr1b = sio_data->sio_inb(sio_data, 0x1b);
541 int cr24 = sio_data->sio_inb(sio_data, 0x24);
542 int cr2a = sio_data->sio_inb(sio_data, 0x2a);
543 int cr2b = sio_data->sio_inb(sio_data, 0x2b);
544 int cr2f = sio_data->sio_inb(sio_data, 0x2f);
545
546 fan3pin = !(cr2b & 0x10);
547 fan4pin = (cr2b & 0x80) || // pin 1(2)
548 (!(cr2f & 0x10) && (cr1a & 0x04)); // pin 65(66)
549 fan5pin = (cr2b & 0x80) || // pin 126(127)
550 (!(cr1b & 0x03) && (cr2a & 0x02)); // pin 94(96)
551
552 pwm3pin = fan3pin && (cr24 & 0x08);
553 pwm4pin = fan4pin;
554 pwm5pin = fan5pin;
555 } else {
556 /*
557 * NCT6779D, NCT6791D, NCT6792D, NCT6793D, NCT6795D, NCT6796D,
558 * NCT6797D, NCT6798D
559 */
560 int cr1a = sio_data->sio_inb(sio_data, 0x1a);
561 int cr1b = sio_data->sio_inb(sio_data, 0x1b);
562 int cr1c = sio_data->sio_inb(sio_data, 0x1c);
563 int cr1d = sio_data->sio_inb(sio_data, 0x1d);
564 int cr2a = sio_data->sio_inb(sio_data, 0x2a);
565 int cr2b = sio_data->sio_inb(sio_data, 0x2b);
566 int cr2d = sio_data->sio_inb(sio_data, 0x2d);
567 int cr2f = sio_data->sio_inb(sio_data, 0x2f);
568 bool dsw_en = cr2f & BIT(3);
569 bool ddr4_en = cr2f & BIT(4);
570 int cre0;
571 int creb;
572 int cred;
573
574 sio_data->sio_select(sio_data, NCT6775_LD_12);
575 cre0 = sio_data->sio_inb(sio_data, 0xe0);
576 creb = sio_data->sio_inb(sio_data, 0xeb);
577 cred = sio_data->sio_inb(sio_data, 0xed);
578
579 fan3pin = !(cr1c & BIT(5));
580 fan4pin = !(cr1c & BIT(6));
581 fan5pin = !(cr1c & BIT(7));
582
583 pwm3pin = !(cr1c & BIT(0));
584 pwm4pin = !(cr1c & BIT(1));
585 pwm5pin = !(cr1c & BIT(2));
586
587 switch (data->kind) {
588 case nct6791:
589 fan6pin = cr2d & BIT(1);
590 pwm6pin = cr2d & BIT(0);
591 break;
592 case nct6792:
593 fan6pin = !dsw_en && (cr2d & BIT(1));
594 pwm6pin = !dsw_en && (cr2d & BIT(0));
595 break;
596 case nct6793:
597 fan5pin |= cr1b & BIT(5);
598 fan5pin |= creb & BIT(5);
599
600 fan6pin = !dsw_en && (cr2d & BIT(1));
601 fan6pin |= creb & BIT(3);
602
603 pwm5pin |= cr2d & BIT(7);
604 pwm5pin |= (creb & BIT(4)) && !(cr2a & BIT(0));
605
606 pwm6pin = !dsw_en && (cr2d & BIT(0));
607 pwm6pin |= creb & BIT(2);
608 break;
609 case nct6795:
610 fan5pin |= cr1b & BIT(5);
611 fan5pin |= creb & BIT(5);
612
613 fan6pin = (cr2a & BIT(4)) &&
614 (!dsw_en || (cred & BIT(4)));
615 fan6pin |= creb & BIT(3);
616
617 pwm5pin |= cr2d & BIT(7);
618 pwm5pin |= (creb & BIT(4)) && !(cr2a & BIT(0));
619
620 pwm6pin = (cr2a & BIT(3)) && (cred & BIT(2));
621 pwm6pin |= creb & BIT(2);
622 break;
623 case nct6796:
624 fan5pin |= cr1b & BIT(5);
625 fan5pin |= (cre0 & BIT(3)) && !(cr1b & BIT(0));
626 fan5pin |= creb & BIT(5);
627
628 fan6pin = (cr2a & BIT(4)) &&
629 (!dsw_en || (cred & BIT(4)));
630 fan6pin |= creb & BIT(3);
631
632 fan7pin = !(cr2b & BIT(2));
633
634 pwm5pin |= cr2d & BIT(7);
635 pwm5pin |= (cre0 & BIT(4)) && !(cr1b & BIT(0));
636 pwm5pin |= (creb & BIT(4)) && !(cr2a & BIT(0));
637
638 pwm6pin = (cr2a & BIT(3)) && (cred & BIT(2));
639 pwm6pin |= creb & BIT(2);
640
641 pwm7pin = !(cr1d & (BIT(2) | BIT(3)));
642 break;
643 case nct6797:
644 fan5pin |= !ddr4_en && (cr1b & BIT(5));
645 fan5pin |= creb & BIT(5);
646
647 fan6pin = cr2a & BIT(4);
648 fan6pin |= creb & BIT(3);
649
650 fan7pin = cr1a & BIT(1);
651
652 pwm5pin |= (creb & BIT(4)) && !(cr2a & BIT(0));
653 pwm5pin |= !ddr4_en && (cr2d & BIT(7));
654
655 pwm6pin = creb & BIT(2);
656 pwm6pin |= cred & BIT(2);
657
658 pwm7pin = cr1d & BIT(4);
659 break;
660 case nct6798:
661 fan6pin = !(cr1b & BIT(0)) && (cre0 & BIT(3));
662 fan6pin |= cr2a & BIT(4);
663 fan6pin |= creb & BIT(5);
664
665 fan7pin = cr1b & BIT(5);
666 fan7pin |= !(cr2b & BIT(2));
667 fan7pin |= creb & BIT(3);
668
669 pwm6pin = !(cr1b & BIT(0)) && (cre0 & BIT(4));
670 pwm6pin |= !(cred & BIT(2)) && (cr2a & BIT(3));
671 pwm6pin |= (creb & BIT(4)) && !(cr2a & BIT(0));
672
673 pwm7pin = !(cr1d & (BIT(2) | BIT(3)));
674 pwm7pin |= cr2d & BIT(7);
675 pwm7pin |= creb & BIT(2);
676 break;
677 default: /* NCT6779D */
678 break;
679 }
680
681 fan4min = fan4pin;
682 }
683
684 /* fan 1 and 2 (0x03) are always present */
685 data->has_fan = 0x03 | (fan3pin << 2) | (fan4pin << 3) |
686 (fan5pin << 4) | (fan6pin << 5) | (fan7pin << 6);
687 data->has_fan_min = 0x03 | (fan3pin << 2) | (fan4min << 3) |
688 (fan5pin << 4) | (fan6pin << 5) | (fan7pin << 6);
689 data->has_pwm = 0x03 | (pwm3pin << 2) | (pwm4pin << 3) |
690 (pwm5pin << 4) | (pwm6pin << 5) | (pwm7pin << 6);
691}
692
693static ssize_t
694cpu0_vid_show(struct device *dev, struct device_attribute *attr, char *buf)
695{
696 struct nct6775_data *data = dev_get_drvdata(dev);
697
698 return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm));
699}
700
701static DEVICE_ATTR_RO(cpu0_vid);
702
703/* Case open detection */
704
705static const u8 NCT6775_REG_CR_CASEOPEN_CLR[] = { 0xe6, 0xee };
706static const u8 NCT6775_CR_CASEOPEN_CLR_MASK[] = { 0x20, 0x01 };
707
708static ssize_t
709clear_caseopen(struct device *dev, struct device_attribute *attr,
710 const char *buf, size_t count)
711{
712 struct nct6775_data *data = dev_get_drvdata(dev);
713 struct nct6775_sio_data *sio_data = data->driver_data;
714 int nr = to_sensor_dev_attr(attr)->index - INTRUSION_ALARM_BASE;
715 unsigned long val;
716 u8 reg;
717 int ret;
718
719 if (kstrtoul(buf, 10, &val) || val != 0)
720 return -EINVAL;
721
722 mutex_lock(&data->update_lock);
723
724 /*
725 * Use CR registers to clear caseopen status.
726 * The CR registers are the same for all chips, and not all chips
727 * support clearing the caseopen status through "regular" registers.
728 */
729 ret = sio_data->sio_enter(sio_data);
730 if (ret) {
731 count = ret;
732 goto error;
733 }
734
735 sio_data->sio_select(sio_data, NCT6775_LD_ACPI);
736 reg = sio_data->sio_inb(sio_data, NCT6775_REG_CR_CASEOPEN_CLR[nr]);
737 reg |= NCT6775_CR_CASEOPEN_CLR_MASK[nr];
738 sio_data->sio_outb(sio_data, NCT6775_REG_CR_CASEOPEN_CLR[nr], reg);
739 reg &= ~NCT6775_CR_CASEOPEN_CLR_MASK[nr];
740 sio_data->sio_outb(sio_data, NCT6775_REG_CR_CASEOPEN_CLR[nr], reg);
741 sio_data->sio_exit(sio_data);
742
743 data->valid = false; /* Force cache refresh */
744error:
745 mutex_unlock(&data->update_lock);
746 return count;
747}
748
749static SENSOR_DEVICE_ATTR(intrusion0_alarm, 0644, nct6775_show_alarm,
750 clear_caseopen, INTRUSION_ALARM_BASE);
751static SENSOR_DEVICE_ATTR(intrusion1_alarm, 0644, nct6775_show_alarm,
752 clear_caseopen, INTRUSION_ALARM_BASE + 1);
753static SENSOR_DEVICE_ATTR(intrusion0_beep, 0644, nct6775_show_beep,
754 nct6775_store_beep, INTRUSION_ALARM_BASE);
755static SENSOR_DEVICE_ATTR(intrusion1_beep, 0644, nct6775_show_beep,
756 nct6775_store_beep, INTRUSION_ALARM_BASE + 1);
757static SENSOR_DEVICE_ATTR(beep_enable, 0644, nct6775_show_beep,
758 nct6775_store_beep, BEEP_ENABLE_BASE);
759
760static umode_t nct6775_other_is_visible(struct kobject *kobj,
761 struct attribute *attr, int index)
762{
763 struct device *dev = kobj_to_dev(kobj);
764 struct nct6775_data *data = dev_get_drvdata(dev);
765
766 if (index == 0 && !data->have_vid)
767 return 0;
768
769 if (index == 1 || index == 2) {
770 if (data->ALARM_BITS[INTRUSION_ALARM_BASE + index - 1] < 0)
771 return 0;
772 }
773
774 if (index == 3 || index == 4) {
775 if (data->BEEP_BITS[INTRUSION_ALARM_BASE + index - 3] < 0)
776 return 0;
777 }
778
779 return nct6775_attr_mode(data, attr);
780}
781
782/*
783 * nct6775_other_is_visible uses the index into the following array
784 * to determine if attributes should be created or not.
785 * Any change in order or content must be matched.
786 */
787static struct attribute *nct6775_attributes_other[] = {
788 &dev_attr_cpu0_vid.attr, /* 0 */
789 &sensor_dev_attr_intrusion0_alarm.dev_attr.attr, /* 1 */
790 &sensor_dev_attr_intrusion1_alarm.dev_attr.attr, /* 2 */
791 &sensor_dev_attr_intrusion0_beep.dev_attr.attr, /* 3 */
792 &sensor_dev_attr_intrusion1_beep.dev_attr.attr, /* 4 */
793 &sensor_dev_attr_beep_enable.dev_attr.attr, /* 5 */
794
795 NULL
796};
797
798static const struct attribute_group nct6775_group_other = {
799 .attrs = nct6775_attributes_other,
800 .is_visible = nct6775_other_is_visible,
801};
802
803static int nct6775_platform_probe_init(struct nct6775_data *data)
804{
805 int err;
806 u8 cr2a;
807 struct nct6775_sio_data *sio_data = data->driver_data;
808
809 err = sio_data->sio_enter(sio_data);
810 if (err)
811 return err;
812
813 cr2a = sio_data->sio_inb(sio_data, 0x2a);
814 switch (data->kind) {
815 case nct6775:
816 data->have_vid = (cr2a & 0x40);
817 break;
818 case nct6776:
819 data->have_vid = (cr2a & 0x60) == 0x40;
820 break;
821 case nct6106:
822 case nct6116:
823 case nct6779:
824 case nct6791:
825 case nct6792:
826 case nct6793:
827 case nct6795:
828 case nct6796:
829 case nct6797:
830 case nct6798:
831 break;
832 }
833
834 /*
835 * Read VID value
836 * We can get the VID input values directly at logical device D 0xe3.
837 */
838 if (data->have_vid) {
839 sio_data->sio_select(sio_data, NCT6775_LD_VID);
840 data->vid = sio_data->sio_inb(sio_data, 0xe3);
841 data->vrm = vid_which_vrm();
842 }
843
844 if (fan_debounce) {
845 u8 tmp;
846
847 sio_data->sio_select(sio_data, NCT6775_LD_HWM);
848 tmp = sio_data->sio_inb(sio_data,
849 NCT6775_REG_CR_FAN_DEBOUNCE);
850 switch (data->kind) {
851 case nct6106:
852 case nct6116:
853 tmp |= 0xe0;
854 break;
855 case nct6775:
856 tmp |= 0x1e;
857 break;
858 case nct6776:
859 case nct6779:
860 tmp |= 0x3e;
861 break;
862 case nct6791:
863 case nct6792:
864 case nct6793:
865 case nct6795:
866 case nct6796:
867 case nct6797:
868 case nct6798:
869 tmp |= 0x7e;
870 break;
871 }
872 sio_data->sio_outb(sio_data, NCT6775_REG_CR_FAN_DEBOUNCE,
873 tmp);
874 pr_info("Enabled fan debounce for chip %s\n", data->name);
875 }
876
877 nct6775_check_fan_inputs(data, sio_data);
878
879 sio_data->sio_exit(sio_data);
880
881 return nct6775_add_attr_group(data, &nct6775_group_other);
882}
883
884static const struct regmap_config nct6775_regmap_config = {
885 .reg_bits = 16,
886 .val_bits = 16,
887 .reg_read = nct6775_reg_read,
888 .reg_write = nct6775_reg_write,
889};
890
891static const struct regmap_config nct6775_wmi_regmap_config = {
892 .reg_bits = 16,
893 .val_bits = 16,
894 .reg_read = nct6775_wmi_reg_read,
895 .reg_write = nct6775_wmi_reg_write,
896};
897
898static int nct6775_platform_probe(struct platform_device *pdev)
899{
900 struct device *dev = &pdev->dev;
901 struct nct6775_sio_data *sio_data = dev_get_platdata(dev);
902 struct nct6775_data *data;
903 struct resource *res;
904 const struct regmap_config *regmapcfg;
905
906 if (sio_data->access == access_direct) {
907 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
908 if (!devm_request_region(&pdev->dev, res->start, IOREGION_LENGTH, DRVNAME))
909 return -EBUSY;
910 }
911
912 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
913 if (!data)
914 return -ENOMEM;
915
916 data->kind = sio_data->kind;
917 data->sioreg = sio_data->sioreg;
918
919 if (sio_data->access == access_direct) {
920 data->addr = res->start;
921 regmapcfg = &nct6775_regmap_config;
922 } else {
923 regmapcfg = &nct6775_wmi_regmap_config;
924 }
925
926 platform_set_drvdata(pdev, data);
927
928 data->driver_data = sio_data;
929 data->driver_init = nct6775_platform_probe_init;
930
931 return nct6775_probe(&pdev->dev, data, regmapcfg);
932}
933
934static struct platform_driver nct6775_driver = {
935 .driver = {
936 .name = DRVNAME,
937 .pm = pm_sleep_ptr(&nct6775_dev_pm_ops),
938 },
939 .probe = nct6775_platform_probe,
940};
941
942/* nct6775_find() looks for a '627 in the Super-I/O config space */
943static int __init nct6775_find(int sioaddr, struct nct6775_sio_data *sio_data)
944{
945 u16 val;
946 int err;
947 int addr;
948
949 sio_data->access = access_direct;
950 sio_data->sioreg = sioaddr;
951
952 err = sio_data->sio_enter(sio_data);
953 if (err)
954 return err;
955
956 val = (sio_data->sio_inb(sio_data, SIO_REG_DEVID) << 8) |
957 sio_data->sio_inb(sio_data, SIO_REG_DEVID + 1);
958 if (force_id && val != 0xffff)
959 val = force_id;
960
961 switch (val & SIO_ID_MASK) {
962 case SIO_NCT6106_ID:
963 sio_data->kind = nct6106;
964 break;
965 case SIO_NCT6116_ID:
966 sio_data->kind = nct6116;
967 break;
968 case SIO_NCT6775_ID:
969 sio_data->kind = nct6775;
970 break;
971 case SIO_NCT6776_ID:
972 sio_data->kind = nct6776;
973 break;
974 case SIO_NCT6779_ID:
975 sio_data->kind = nct6779;
976 break;
977 case SIO_NCT6791_ID:
978 sio_data->kind = nct6791;
979 break;
980 case SIO_NCT6792_ID:
981 sio_data->kind = nct6792;
982 break;
983 case SIO_NCT6793_ID:
984 sio_data->kind = nct6793;
985 break;
986 case SIO_NCT6795_ID:
987 sio_data->kind = nct6795;
988 break;
989 case SIO_NCT6796_ID:
990 sio_data->kind = nct6796;
991 break;
992 case SIO_NCT6797_ID:
993 sio_data->kind = nct6797;
994 break;
995 case SIO_NCT6798_ID:
996 sio_data->kind = nct6798;
997 break;
998 default:
999 if (val != 0xffff)
1000 pr_debug("unsupported chip ID: 0x%04x\n", val);
1001 sio_data->sio_exit(sio_data);
1002 return -ENODEV;
1003 }
1004
1005 /* We have a known chip, find the HWM I/O address */
1006 sio_data->sio_select(sio_data, NCT6775_LD_HWM);
1007 val = (sio_data->sio_inb(sio_data, SIO_REG_ADDR) << 8)
1008 | sio_data->sio_inb(sio_data, SIO_REG_ADDR + 1);
1009 addr = val & IOREGION_ALIGNMENT;
1010 if (addr == 0) {
1011 pr_err("Refusing to enable a Super-I/O device with a base I/O port 0\n");
1012 sio_data->sio_exit(sio_data);
1013 return -ENODEV;
1014 }
1015
1016 /* Activate logical device if needed */
1017 val = sio_data->sio_inb(sio_data, SIO_REG_ENABLE);
1018 if (!(val & 0x01)) {
1019 pr_warn("Forcibly enabling Super-I/O. Sensor is probably unusable.\n");
1020 sio_data->sio_outb(sio_data, SIO_REG_ENABLE, val | 0x01);
1021 }
1022
1023 if (sio_data->kind == nct6791 || sio_data->kind == nct6792 ||
1024 sio_data->kind == nct6793 || sio_data->kind == nct6795 ||
1025 sio_data->kind == nct6796 || sio_data->kind == nct6797 ||
1026 sio_data->kind == nct6798)
1027 nct6791_enable_io_mapping(sio_data);
1028
1029 sio_data->sio_exit(sio_data);
1030 pr_info("Found %s or compatible chip at %#x:%#x\n",
1031 nct6775_sio_names[sio_data->kind], sioaddr, addr);
1032
1033 return addr;
1034}
1035
1036/*
1037 * when Super-I/O functions move to a separate file, the Super-I/O
1038 * bus will manage the lifetime of the device and this module will only keep
1039 * track of the nct6775 driver. But since we use platform_device_alloc(), we
1040 * must keep track of the device
1041 */
1042static struct platform_device *pdev[2];
1043
1044static const char * const asus_wmi_boards[] = {
1045 "PRO H410T",
1046 "ProArt B550-CREATOR",
1047 "ProArt X570-CREATOR WIFI",
1048 "ProArt Z490-CREATOR 10G",
1049 "Pro B550M-C",
1050 "Pro WS X570-ACE",
1051 "PRIME B360-PLUS",
1052 "PRIME B460-PLUS",
1053 "PRIME B550-PLUS",
1054 "PRIME B550M-A",
1055 "PRIME B550M-A (WI-FI)",
1056 "PRIME H410M-R",
1057 "PRIME X570-P",
1058 "PRIME X570-PRO",
1059 "ROG CROSSHAIR VIII DARK HERO",
1060 "ROG CROSSHAIR VIII EXTREME",
1061 "ROG CROSSHAIR VIII FORMULA",
1062 "ROG CROSSHAIR VIII HERO",
1063 "ROG CROSSHAIR VIII HERO (WI-FI)",
1064 "ROG CROSSHAIR VIII IMPACT",
1065 "ROG STRIX B550-A GAMING",
1066 "ROG STRIX B550-E GAMING",
1067 "ROG STRIX B550-F GAMING",
1068 "ROG STRIX B550-F GAMING (WI-FI)",
1069 "ROG STRIX B550-F GAMING WIFI II",
1070 "ROG STRIX B550-I GAMING",
1071 "ROG STRIX B550-XE GAMING (WI-FI)",
1072 "ROG STRIX X570-E GAMING",
1073 "ROG STRIX X570-E GAMING WIFI II",
1074 "ROG STRIX X570-F GAMING",
1075 "ROG STRIX X570-I GAMING",
1076 "ROG STRIX Z390-E GAMING",
1077 "ROG STRIX Z390-F GAMING",
1078 "ROG STRIX Z390-H GAMING",
1079 "ROG STRIX Z390-I GAMING",
1080 "ROG STRIX Z490-A GAMING",
1081 "ROG STRIX Z490-E GAMING",
1082 "ROG STRIX Z490-F GAMING",
1083 "ROG STRIX Z490-G GAMING",
1084 "ROG STRIX Z490-G GAMING (WI-FI)",
1085 "ROG STRIX Z490-H GAMING",
1086 "ROG STRIX Z490-I GAMING",
1087 "TUF GAMING B550M-E",
1088 "TUF GAMING B550M-E (WI-FI)",
1089 "TUF GAMING B550M-PLUS",
1090 "TUF GAMING B550M-PLUS (WI-FI)",
1091 "TUF GAMING B550M-PLUS WIFI II",
1092 "TUF GAMING B550-PLUS",
1093 "TUF GAMING B550-PLUS WIFI II",
1094 "TUF GAMING B550-PRO",
1095 "TUF GAMING X570-PLUS",
1096 "TUF GAMING X570-PLUS (WI-FI)",
1097 "TUF GAMING X570-PRO (WI-FI)",
1098 "TUF GAMING Z490-PLUS",
1099 "TUF GAMING Z490-PLUS (WI-FI)",
1100};
1101
1102static int __init sensors_nct6775_platform_init(void)
1103{
1104 int i, err;
1105 bool found = false;
1106 int address;
1107 struct resource res;
1108 struct nct6775_sio_data sio_data;
1109 int sioaddr[2] = { 0x2e, 0x4e };
1110 enum sensor_access access = access_direct;
1111 const char *board_vendor, *board_name;
1112 u8 tmp;
1113
1114 err = platform_driver_register(&nct6775_driver);
1115 if (err)
1116 return err;
1117
1118 board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR);
1119 board_name = dmi_get_system_info(DMI_BOARD_NAME);
1120
1121 if (board_name && board_vendor &&
1122 !strcmp(board_vendor, "ASUSTeK COMPUTER INC.")) {
1123 err = match_string(asus_wmi_boards, ARRAY_SIZE(asus_wmi_boards),
1124 board_name);
1125 if (err >= 0) {
1126 /* if reading chip id via WMI succeeds, use WMI */
1127 if (!nct6775_asuswmi_read(0, NCT6775_PORT_CHIPID, &tmp) && tmp) {
1128 pr_info("Using Asus WMI to access %#x chip.\n", tmp);
1129 access = access_asuswmi;
1130 } else {
1131 pr_err("Can't read ChipID by Asus WMI.\n");
1132 }
1133 }
1134 }
1135
1136 /*
1137 * initialize sio_data->kind and sio_data->sioreg.
1138 *
1139 * when Super-I/O functions move to a separate file, the Super-I/O
1140 * driver will probe 0x2e and 0x4e and auto-detect the presence of a
1141 * nct6775 hardware monitor, and call probe()
1142 */
1143 for (i = 0; i < ARRAY_SIZE(pdev); i++) {
1144 sio_data.sio_outb = superio_outb;
1145 sio_data.sio_inb = superio_inb;
1146 sio_data.sio_select = superio_select;
1147 sio_data.sio_enter = superio_enter;
1148 sio_data.sio_exit = superio_exit;
1149
1150 address = nct6775_find(sioaddr[i], &sio_data);
1151 if (address <= 0)
1152 continue;
1153
1154 found = true;
1155
1156 sio_data.access = access;
1157
1158 if (access == access_asuswmi) {
1159 sio_data.sio_outb = superio_wmi_outb;
1160 sio_data.sio_inb = superio_wmi_inb;
1161 sio_data.sio_select = superio_wmi_select;
1162 sio_data.sio_enter = superio_wmi_enter;
1163 sio_data.sio_exit = superio_wmi_exit;
1164 }
1165
1166 pdev[i] = platform_device_alloc(DRVNAME, address);
1167 if (!pdev[i]) {
1168 err = -ENOMEM;
1169 goto exit_device_unregister;
1170 }
1171
1172 err = platform_device_add_data(pdev[i], &sio_data,
1173 sizeof(struct nct6775_sio_data));
1174 if (err)
1175 goto exit_device_put;
1176
1177 if (sio_data.access == access_direct) {
1178 memset(&res, 0, sizeof(res));
1179 res.name = DRVNAME;
1180 res.start = address + IOREGION_OFFSET;
1181 res.end = address + IOREGION_OFFSET + IOREGION_LENGTH - 1;
1182 res.flags = IORESOURCE_IO;
1183
1184 err = acpi_check_resource_conflict(&res);
1185 if (err) {
1186 platform_device_put(pdev[i]);
1187 pdev[i] = NULL;
1188 continue;
1189 }
1190
1191 err = platform_device_add_resources(pdev[i], &res, 1);
1192 if (err)
1193 goto exit_device_put;
1194 }
1195
1196 /* platform_device_add calls probe() */
1197 err = platform_device_add(pdev[i]);
1198 if (err)
1199 goto exit_device_put;
1200 }
1201 if (!found) {
1202 err = -ENODEV;
1203 goto exit_unregister;
1204 }
1205
1206 return 0;
1207
1208exit_device_put:
1209 platform_device_put(pdev[i]);
1210exit_device_unregister:
1211 while (i--)
1212 platform_device_unregister(pdev[i]);
1213exit_unregister:
1214 platform_driver_unregister(&nct6775_driver);
1215 return err;
1216}
1217
1218static void __exit sensors_nct6775_platform_exit(void)
1219{
1220 int i;
1221
1222 for (i = 0; i < ARRAY_SIZE(pdev); i++)
1223 platform_device_unregister(pdev[i]);
1224 platform_driver_unregister(&nct6775_driver);
1225}
1226
1227MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>");
1228MODULE_DESCRIPTION("Platform driver for NCT6775F and compatible chips");
1229MODULE_LICENSE("GPL");
1230MODULE_IMPORT_NS(HWMON_NCT6775);
1231
1232module_init(sensors_nct6775_platform_init);
1233module_exit(sensors_nct6775_platform_exit);