projects/linux·blob master · refs

1654 lines · 41.5 KiB

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