1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * nct6775 - Platform driver for the hardware monitoring
4 * functionality of Nuvoton NCT677x Super-I/O chips
6 * Copyright (C) 2012 Guenter Roeck <linux@roeck-us.net>
9 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
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>
17 #include <linux/module.h>
18 #include <linux/platform_device.h>
19 #include <linux/regmap.h>
23 enum sensor_access { access_direct, access_asuswmi };
25 static const char * const nct6775_sio_names[] __initconst = {
41 static unsigned short force_id;
42 module_param(force_id, ushort, 0);
43 MODULE_PARM_DESC(force_id, "Override the detected device ID");
45 static unsigned short fan_debounce;
46 module_param(fan_debounce, ushort, 0);
47 MODULE_PARM_DESC(fan_debounce, "Enable debouncing for fan RPM signal");
49 #define DRVNAME "nct6775"
51 #define NCT6775_PORT_CHIPID 0x58
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
64 * Super-I/O constants and functions
67 #define NCT6775_LD_ACPI 0x0a
68 #define NCT6775_LD_HWM 0x0b
69 #define NCT6775_LD_VID 0x0d
70 #define NCT6775_LD_12 0x12
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) */
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
95 #define NCT6775_REG_CR_FAN_DEBOUNCE 0xf0
97 struct nct6775_sio_data {
101 enum sensor_access access;
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);
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"
121 #if IS_ENABLED(CONFIG_ACPI)
123 * ASUS boards have only one device with WMI "WMBD" method and have provided
124 * access to only one SuperIO chip at 0x0290.
126 static struct acpi_device *asus_acpi_dev;
129 static int nct6775_asuswmi_evaluate_method(u32 method_id, u8 bank, u8 reg, u8 val, u32 *retval)
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;
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;
147 input.pointer = params;
149 status = acpi_evaluate_integer(handle, ASUSWMI_METHOD, &input, &result);
150 if (ACPI_FAILURE(status))
162 static inline int nct6775_asuswmi_write(u8 bank, u8 reg, u8 val)
164 return nct6775_asuswmi_evaluate_method(ASUSWMI_METHODID_WHWM, bank,
168 static inline int nct6775_asuswmi_read(u8 bank, u8 reg, u8 *val)
172 ret = nct6775_asuswmi_evaluate_method(ASUSWMI_METHODID_RHWM, bank,
178 static int superio_wmi_inb(struct nct6775_sio_data *sio_data, int reg)
182 nct6775_asuswmi_evaluate_method(ASUSWMI_METHODID_RSIO, sio_data->ld,
187 static void superio_wmi_outb(struct nct6775_sio_data *sio_data, int reg, int val)
189 nct6775_asuswmi_evaluate_method(ASUSWMI_METHODID_WSIO, sio_data->ld,
193 static void superio_wmi_select(struct nct6775_sio_data *sio_data, int ld)
198 static int superio_wmi_enter(struct nct6775_sio_data *sio_data)
203 static void superio_wmi_exit(struct nct6775_sio_data *sio_data)
207 static void superio_outb(struct nct6775_sio_data *sio_data, int reg, int val)
209 int ioreg = sio_data->sioreg;
212 outb(val, ioreg + 1);
215 static int superio_inb(struct nct6775_sio_data *sio_data, int reg)
217 int ioreg = sio_data->sioreg;
220 return inb(ioreg + 1);
223 static void superio_select(struct nct6775_sio_data *sio_data, int ld)
225 int ioreg = sio_data->sioreg;
227 outb(SIO_REG_LDSEL, ioreg);
231 static int superio_enter(struct nct6775_sio_data *sio_data)
233 int ioreg = sio_data->sioreg;
236 * Try to reserve <ioreg> and <ioreg + 1> for exclusive access.
238 if (!request_muxed_region(ioreg, 2, DRVNAME))
247 static void superio_exit(struct nct6775_sio_data *sio_data)
249 int ioreg = sio_data->sioreg;
253 outb(0x02, ioreg + 1);
254 release_region(ioreg, 2);
257 static inline void nct6775_wmi_set_bank(struct nct6775_data *data, u16 reg)
264 static int nct6775_wmi_reg_read(void *ctx, unsigned int reg, unsigned int *val)
266 struct nct6775_data *data = ctx;
267 int err, word_sized = nct6775_reg_is_word_sized(data, reg);
271 nct6775_wmi_set_bank(data, reg);
273 err = nct6775_asuswmi_read(data->bank, reg & 0xff, &tmp);
279 err = nct6775_asuswmi_read(data->bank, (reg & 0xff) + 1, &tmp);
283 res = (res << 8) + tmp;
289 static int nct6775_wmi_reg_write(void *ctx, unsigned int reg, unsigned int value)
291 struct nct6775_data *data = ctx;
292 int res, word_sized = nct6775_reg_is_word_sized(data, reg);
294 nct6775_wmi_set_bank(data, reg);
297 res = nct6775_asuswmi_write(data->bank, reg & 0xff, value >> 8);
301 res = nct6775_asuswmi_write(data->bank, (reg & 0xff) + 1, value);
303 res = nct6775_asuswmi_write(data->bank, reg & 0xff, value);
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.
315 static inline void nct6775_set_bank(struct nct6775_data *data, u16 reg)
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);
326 static int nct6775_reg_read(void *ctx, unsigned int reg, unsigned int *val)
328 struct nct6775_data *data = ctx;
329 int word_sized = nct6775_reg_is_word_sized(data, reg);
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);
335 outb_p((reg & 0xff) + 1,
336 data->addr + ADDR_REG_OFFSET);
337 *val = (*val << 8) + inb_p(data->addr + DATA_REG_OFFSET);
342 static int nct6775_reg_write(void *ctx, unsigned int reg, unsigned int value)
344 struct nct6775_data *data = ctx;
345 int word_sized = nct6775_reg_is_word_sized(data, reg);
347 nct6775_set_bank(data, reg);
348 outb_p(reg & 0xff, data->addr + ADDR_REG_OFFSET);
350 outb_p(value >> 8, data->addr + DATA_REG_OFFSET);
351 outb_p((reg & 0xff) + 1,
352 data->addr + ADDR_REG_OFFSET);
354 outb_p(value & 0xff, data->addr + DATA_REG_OFFSET);
358 static void nct6791_enable_io_mapping(struct nct6775_sio_data *sio_data)
362 val = sio_data->sio_inb(sio_data, NCT6791_REG_HM_IO_SPACE_LOCK_ENABLE);
364 pr_info("Enabling hardware monitor logical device mappings.\n");
365 sio_data->sio_outb(sio_data, NCT6791_REG_HM_IO_SPACE_LOCK_ENABLE,
370 static int nct6775_suspend(struct device *dev)
374 struct nct6775_data *data = nct6775_update_device(dev);
377 return PTR_ERR(data);
379 mutex_lock(&data->update_lock);
380 err = nct6775_read_value(data, data->REG_VBAT, &tmp);
384 if (data->kind == nct6775) {
385 err = nct6775_read_value(data, NCT6775_REG_FANDIV1, &tmp);
390 err = nct6775_read_value(data, NCT6775_REG_FANDIV2, &tmp);
396 mutex_unlock(&data->update_lock);
401 static int nct6775_resume(struct device *dev)
403 struct nct6775_data *data = dev_get_drvdata(dev);
404 struct nct6775_sio_data *sio_data = dev_get_platdata(dev);
408 mutex_lock(&data->update_lock);
409 data->bank = 0xff; /* Force initial bank selection */
411 err = sio_data->sio_enter(sio_data);
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);
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);
426 sio_data->sio_exit(sio_data);
429 for (i = 0; i < data->in_num; i++) {
430 if (!(data->have_in & BIT(i)))
433 err = nct6775_write_value(data, data->REG_IN_MINMAX[0][i], data->in[i][1]);
436 err = nct6775_write_value(data, data->REG_IN_MINMAX[1][i], data->in[i][2]);
441 for (i = 0; i < ARRAY_SIZE(data->fan_min); i++) {
442 if (!(data->has_fan_min & BIT(i)))
445 err = nct6775_write_value(data, data->REG_FAN_MIN[i], data->fan_min[i]);
450 for (i = 0; i < NUM_TEMP; i++) {
451 if (!(data->have_temp & BIT(i)))
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],
463 /* Restore other settings */
464 err = nct6775_write_value(data, data->REG_VBAT, data->vbat);
467 if (data->kind == nct6775) {
468 err = nct6775_write_value(data, NCT6775_REG_FANDIV1, data->fandiv1);
471 err = nct6775_write_value(data, NCT6775_REG_FANDIV2, data->fandiv2);
475 /* Force re-reading all values */
477 mutex_unlock(&data->update_lock);
482 static DEFINE_SIMPLE_DEV_PM_OPS(nct6775_dev_pm_ops, nct6775_suspend, nct6775_resume);
485 nct6775_check_fan_inputs(struct nct6775_data *data, struct nct6775_sio_data *sio_data)
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;
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);
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);
500 fan3pin = cr2c & BIT(6);
501 pwm3pin = cr2c & BIT(7);
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;
509 board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR);
510 board_name = dmi_get_system_info(DMI_BOARD_NAME);
512 if (board_name && board_vendor &&
513 !strcmp(board_vendor, "ASRock")) {
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.
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);
528 if (data->sio_reg_enable & 0x80)
531 fan3pin = !(sio_data->sio_inb(sio_data, 0x24) & 0x40);
533 if (data->sio_reg_enable & 0x40)
536 fan4pin = sio_data->sio_inb(sio_data, 0x1C) & 0x01;
538 if (data->sio_reg_enable & 0x20)
541 fan5pin = sio_data->sio_inb(sio_data, 0x1C) & 0x02;
545 } else if (data->kind == nct6106) {
546 int cr24 = sio_data->sio_inb(sio_data, 0x24);
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);
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)
564 pwm3pin = fan3pin && (cr24 & 0x08);
569 * NCT6779D, NCT6791D, NCT6792D, NCT6793D, NCT6795D, NCT6796D,
570 * NCT6797D, NCT6798D, NCT6799D
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);
589 cre6 = sio_data->sio_inb(sio_data, 0xe0);
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);
596 fan3pin = !(cr1c & BIT(5));
597 fan4pin = !(cr1c & BIT(6));
598 fan5pin = !(cr1c & BIT(7));
600 pwm3pin = !(cr1c & BIT(0));
601 pwm4pin = !(cr1c & BIT(1));
602 pwm5pin = !(cr1c & BIT(2));
604 switch (data->kind) {
606 fan6pin = cr2d & BIT(1);
607 pwm6pin = cr2d & BIT(0);
610 fan6pin = !dsw_en && (cr2d & BIT(1));
611 pwm6pin = !dsw_en && (cr2d & BIT(0));
614 fan5pin |= cr1b & BIT(5);
615 fan5pin |= creb & BIT(5);
617 fan6pin = !dsw_en && (cr2d & BIT(1));
618 fan6pin |= creb & BIT(3);
620 pwm5pin |= cr2d & BIT(7);
621 pwm5pin |= (creb & BIT(4)) && !(cr2a & BIT(0));
623 pwm6pin = !dsw_en && (cr2d & BIT(0));
624 pwm6pin |= creb & BIT(2);
627 fan5pin |= cr1b & BIT(5);
628 fan5pin |= creb & BIT(5);
630 fan6pin = (cr2a & BIT(4)) &&
631 (!dsw_en || (cred & BIT(4)));
632 fan6pin |= creb & BIT(3);
634 pwm5pin |= cr2d & BIT(7);
635 pwm5pin |= (creb & BIT(4)) && !(cr2a & BIT(0));
637 pwm6pin = (cr2a & BIT(3)) && (cred & BIT(2));
638 pwm6pin |= creb & BIT(2);
641 fan5pin |= cr1b & BIT(5);
642 fan5pin |= (cre0 & BIT(3)) && !(cr1b & BIT(0));
643 fan5pin |= creb & BIT(5);
645 fan6pin = (cr2a & BIT(4)) &&
646 (!dsw_en || (cred & BIT(4)));
647 fan6pin |= creb & BIT(3);
649 fan7pin = !(cr2b & BIT(2));
651 pwm5pin |= cr2d & BIT(7);
652 pwm5pin |= (cre0 & BIT(4)) && !(cr1b & BIT(0));
653 pwm5pin |= (creb & BIT(4)) && !(cr2a & BIT(0));
655 pwm6pin = (cr2a & BIT(3)) && (cred & BIT(2));
656 pwm6pin |= creb & BIT(2);
658 pwm7pin = !(cr1d & (BIT(2) | BIT(3)));
661 fan5pin |= !ddr4_en && (cr1b & BIT(5));
662 fan5pin |= creb & BIT(5);
664 fan6pin = cr2a & BIT(4);
665 fan6pin |= creb & BIT(3);
667 fan7pin = cr1a & BIT(1);
669 pwm5pin |= (creb & BIT(4)) && !(cr2a & BIT(0));
670 pwm5pin |= !ddr4_en && (cr2d & BIT(7));
672 pwm6pin = creb & BIT(2);
673 pwm6pin |= cred & BIT(2);
675 pwm7pin = cr1d & BIT(4);
678 fan6pin = !(cr1b & BIT(0)) && (cre0 & BIT(3));
679 fan6pin |= cr2a & BIT(4);
680 fan6pin |= creb & BIT(5);
682 fan7pin = cr1b & BIT(5);
683 fan7pin |= !(cr2b & BIT(2));
684 fan7pin |= creb & BIT(3);
686 pwm6pin = !(cr1b & BIT(0)) && (cre0 & BIT(4));
687 pwm6pin |= !(cred & BIT(2)) && (cr2a & BIT(3));
688 pwm6pin |= (creb & BIT(4)) && !(cr2a & BIT(0));
690 pwm7pin = !(cr1d & (BIT(2) | BIT(3)));
691 pwm7pin |= cr2d & BIT(7);
692 pwm7pin |= creb & BIT(2);
695 fan4pin = cr1c & BIT(6);
696 fan5pin = cr1c & BIT(7);
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));
703 fan7pin = cr1b & BIT(5);
704 fan7pin |= !vsb_ctl_en && !(cr2b & BIT(2));
705 fan7pin |= creb & BIT(3);
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);
712 pwm7pin = !vsb_ctl_en && !(cr1d & (BIT(2) | BIT(3)));
713 pwm7pin |= creb & BIT(2);
714 pwm7pin |= cr2d & BIT(7);
717 default: /* NCT6779D */
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);
734 cpu0_vid_show(struct device *dev, struct device_attribute *attr, char *buf)
736 struct nct6775_data *data = dev_get_drvdata(dev);
738 return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm));
741 static DEVICE_ATTR_RO(cpu0_vid);
743 /* Case open detection */
745 static const u8 NCT6775_REG_CR_CASEOPEN_CLR[] = { 0xe6, 0xee };
746 static const u8 NCT6775_CR_CASEOPEN_CLR_MASK[] = { 0x20, 0x01 };
749 clear_caseopen(struct device *dev, struct device_attribute *attr,
750 const char *buf, size_t count)
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;
759 if (kstrtoul(buf, 10, &val) || val != 0)
762 mutex_lock(&data->update_lock);
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.
769 ret = sio_data->sio_enter(sio_data);
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);
783 data->valid = false; /* Force cache refresh */
785 mutex_unlock(&data->update_lock);
789 static SENSOR_DEVICE_ATTR(intrusion0_alarm, 0644, nct6775_show_alarm,
790 clear_caseopen, INTRUSION_ALARM_BASE);
791 static SENSOR_DEVICE_ATTR(intrusion1_alarm, 0644, nct6775_show_alarm,
792 clear_caseopen, INTRUSION_ALARM_BASE + 1);
793 static SENSOR_DEVICE_ATTR(intrusion0_beep, 0644, nct6775_show_beep,
794 nct6775_store_beep, INTRUSION_ALARM_BASE);
795 static SENSOR_DEVICE_ATTR(intrusion1_beep, 0644, nct6775_show_beep,
796 nct6775_store_beep, INTRUSION_ALARM_BASE + 1);
797 static SENSOR_DEVICE_ATTR(beep_enable, 0644, nct6775_show_beep,
798 nct6775_store_beep, BEEP_ENABLE_BASE);
800 static umode_t nct6775_other_is_visible(struct kobject *kobj,
801 struct attribute *attr, int index)
803 struct device *dev = kobj_to_dev(kobj);
804 struct nct6775_data *data = dev_get_drvdata(dev);
806 if (index == 0 && !data->have_vid)
809 if (index == 1 || index == 2) {
810 if (data->ALARM_BITS[INTRUSION_ALARM_BASE + index - 1] < 0)
814 if (index == 3 || index == 4) {
815 if (data->BEEP_BITS[INTRUSION_ALARM_BASE + index - 3] < 0)
819 return nct6775_attr_mode(data, attr);
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.
827 static 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 */
838 static const struct attribute_group nct6775_group_other = {
839 .attrs = nct6775_attributes_other,
840 .is_visible = nct6775_other_is_visible,
843 static int nct6775_platform_probe_init(struct nct6775_data *data)
847 struct nct6775_sio_data *sio_data = data->driver_data;
849 err = sio_data->sio_enter(sio_data);
853 cr2a = sio_data->sio_inb(sio_data, 0x2a);
854 switch (data->kind) {
856 data->have_vid = (cr2a & 0x40);
859 data->have_vid = (cr2a & 0x60) == 0x40;
877 * We can get the VID input values directly at logical device D 0xe3.
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();
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) {
914 sio_data->sio_outb(sio_data, NCT6775_REG_CR_FAN_DEBOUNCE,
916 pr_info("Enabled fan debounce for chip %s\n", data->name);
919 nct6775_check_fan_inputs(data, sio_data);
921 sio_data->sio_exit(sio_data);
923 return nct6775_add_attr_group(data, &nct6775_group_other);
926 static const struct regmap_config nct6775_regmap_config = {
929 .reg_read = nct6775_reg_read,
930 .reg_write = nct6775_reg_write,
933 static const struct regmap_config nct6775_wmi_regmap_config = {
936 .reg_read = nct6775_wmi_reg_read,
937 .reg_write = nct6775_wmi_reg_write,
940 static int nct6775_platform_probe(struct platform_device *pdev)
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;
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))
954 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
958 data->kind = sio_data->kind;
959 data->sioreg = sio_data->sioreg;
961 if (sio_data->access == access_direct) {
962 data->addr = res->start;
963 regmapcfg = &nct6775_regmap_config;
965 regmapcfg = &nct6775_wmi_regmap_config;
968 platform_set_drvdata(pdev, data);
970 data->driver_data = sio_data;
971 data->driver_init = nct6775_platform_probe_init;
973 return nct6775_probe(&pdev->dev, data, regmapcfg);
976 static struct platform_driver nct6775_driver = {
979 .pm = pm_sleep_ptr(&nct6775_dev_pm_ops),
981 .probe = nct6775_platform_probe,
984 /* nct6775_find() looks for a '627 in the Super-I/O config space */
985 static int __init nct6775_find(int sioaddr, struct nct6775_sio_data *sio_data)
991 sio_data->access = access_direct;
992 sio_data->sioreg = sioaddr;
994 err = sio_data->sio_enter(sio_data);
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)
1003 switch (val & SIO_ID_MASK) {
1004 case SIO_NCT6106_ID:
1005 sio_data->kind = nct6106;
1007 case SIO_NCT6116_ID:
1008 sio_data->kind = nct6116;
1010 case SIO_NCT6775_ID:
1011 sio_data->kind = nct6775;
1013 case SIO_NCT6776_ID:
1014 sio_data->kind = nct6776;
1016 case SIO_NCT6779_ID:
1017 sio_data->kind = nct6779;
1019 case SIO_NCT6791_ID:
1020 sio_data->kind = nct6791;
1022 case SIO_NCT6792_ID:
1023 sio_data->kind = nct6792;
1025 case SIO_NCT6793_ID:
1026 sio_data->kind = nct6793;
1028 case SIO_NCT6795_ID:
1029 sio_data->kind = nct6795;
1031 case SIO_NCT6796_ID:
1032 sio_data->kind = nct6796;
1034 case SIO_NCT6797_ID:
1035 sio_data->kind = nct6797;
1037 case SIO_NCT6798_ID:
1038 sio_data->kind = nct6798;
1040 case SIO_NCT6799_ID:
1041 sio_data->kind = nct6799;
1045 pr_debug("unsupported chip ID: 0x%04x\n", val);
1046 sio_data->sio_exit(sio_data);
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;
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);
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);
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);
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);
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
1087 static struct platform_device *pdev[2];
1089 static const char * const asus_wmi_boards[] = {
1109 "PRIME B460M-A R2.0",
1112 "PRIME B550-PLUS AC-HES",
1114 "PRIME B550M-A (WI-FI)",
1116 "PRIME B550M-A WIFI II",
1138 "PRIME H410M-K R2.0",
1142 "PRIME H510M-K R2.0",
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)",
1261 "Z490-GUNDAM (WI-FI)",
1264 static const char * const asus_msi_boards[] = {
1268 "EX-B660M-V5 PRO D4",
1274 "PRIME B560-PLUS AC-HES",
1281 "PRIME B650M-A AX II",
1283 "PRIME B650M-A WIFI",
1284 "PRIME B650M-A WIFI II",
1285 "PRIME B660-PLUS D4",
1286 "PRIME B660M-A AC D4",
1288 "PRIME B660M-A WIFI D4",
1290 "PRIME B760-PLUS D4",
1292 "PRIME B760M-A AX D4",
1294 "PRIME B760M-A WIFI",
1295 "PRIME B760M-A WIFI D4",
1296 "PRIME B760M-AJ D4",
1299 "PRIME H510M-A WIFI",
1308 "PRIME H610I-PLUS D4",
1310 "PRIME H610M-A WIFI D4",
1316 "PRIME H670-PLUS D4",
1317 "PRIME H770-PLUS D4",
1319 "PRIME X670-P WIFI",
1320 "PRIME X670E-PRO WIFI",
1323 "PRIME Z590-P WIFI",
1329 "PRIME Z690-P WIFI",
1330 "PRIME Z690-P WIFI D4",
1331 "PRIME Z690M-PLUS D4",
1332 "PRIME Z790-A WIFI",
1335 "PRIME Z790-P WIFI",
1336 "PRIME Z790-P WIFI D4",
1338 "PRIME Z790M-PLUS D4",
1353 "Pro WS W680-ACE IPMI",
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",
1460 #if IS_ENABLED(CONFIG_ACPI)
1462 * Callback for acpi_bus_for_each_dev() to find the right device
1463 * by _UID and _HID and return 1 to stop iteration.
1465 static int nct6775_asuswmi_device_match(struct device *dev, void *data)
1467 struct acpi_device *adev = to_acpi_device(dev);
1468 const char *uid = acpi_device_uid(adev);
1469 const char *hid = acpi_device_hid(adev);
1471 if (hid && !strcmp(hid, ASUSWMI_DEVICE_HID) && uid && !strcmp(uid, data)) {
1472 asus_acpi_dev = adev;
1480 static enum sensor_access nct6775_determine_access(const char *device_uid)
1482 #if IS_ENABLED(CONFIG_ACPI)
1485 acpi_bus_for_each_dev(nct6775_asuswmi_device_match, (void *)device_uid);
1487 return access_direct;
1489 /* if reading chip id via ACPI succeeds, use WMI "WMBD" method for access */
1490 if (!nct6775_asuswmi_read(0, NCT6775_PORT_CHIPID, &tmp) && tmp) {
1491 pr_debug("Using Asus WMBD method of %s to access %#x chip.\n", device_uid, tmp);
1492 return access_asuswmi;
1496 return access_direct;
1499 static int __init sensors_nct6775_platform_init(void)
1504 struct resource res;
1505 struct nct6775_sio_data sio_data;
1506 int sioaddr[2] = { 0x2e, 0x4e };
1507 enum sensor_access access = access_direct;
1508 const char *board_vendor, *board_name;
1510 err = platform_driver_register(&nct6775_driver);
1514 board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR);
1515 board_name = dmi_get_system_info(DMI_BOARD_NAME);
1517 if (board_name && board_vendor &&
1518 !strcmp(board_vendor, "ASUSTeK COMPUTER INC.")) {
1519 err = match_string(asus_wmi_boards, ARRAY_SIZE(asus_wmi_boards),
1522 access = nct6775_determine_access(ASUSWMI_DEVICE_UID);
1524 err = match_string(asus_msi_boards, ARRAY_SIZE(asus_msi_boards),
1527 access = nct6775_determine_access(ASUSMSI_DEVICE_UID);
1531 * initialize sio_data->kind and sio_data->sioreg.
1533 * when Super-I/O functions move to a separate file, the Super-I/O
1534 * driver will probe 0x2e and 0x4e and auto-detect the presence of a
1535 * nct6775 hardware monitor, and call probe()
1537 for (i = 0; i < ARRAY_SIZE(pdev); i++) {
1538 sio_data.sio_outb = superio_outb;
1539 sio_data.sio_inb = superio_inb;
1540 sio_data.sio_select = superio_select;
1541 sio_data.sio_enter = superio_enter;
1542 sio_data.sio_exit = superio_exit;
1544 address = nct6775_find(sioaddr[i], &sio_data);
1550 sio_data.access = access;
1552 if (access == access_asuswmi) {
1553 sio_data.sio_outb = superio_wmi_outb;
1554 sio_data.sio_inb = superio_wmi_inb;
1555 sio_data.sio_select = superio_wmi_select;
1556 sio_data.sio_enter = superio_wmi_enter;
1557 sio_data.sio_exit = superio_wmi_exit;
1560 pdev[i] = platform_device_alloc(DRVNAME, address);
1563 goto exit_device_unregister;
1566 err = platform_device_add_data(pdev[i], &sio_data,
1567 sizeof(struct nct6775_sio_data));
1569 goto exit_device_put;
1571 if (sio_data.access == access_direct) {
1572 memset(&res, 0, sizeof(res));
1574 res.start = address + IOREGION_OFFSET;
1575 res.end = address + IOREGION_OFFSET + IOREGION_LENGTH - 1;
1576 res.flags = IORESOURCE_IO;
1578 err = acpi_check_resource_conflict(&res);
1580 platform_device_put(pdev[i]);
1585 err = platform_device_add_resources(pdev[i], &res, 1);
1587 goto exit_device_put;
1590 /* platform_device_add calls probe() */
1591 err = platform_device_add(pdev[i]);
1593 goto exit_device_put;
1597 goto exit_unregister;
1603 platform_device_put(pdev[i]);
1604 exit_device_unregister:
1606 platform_device_unregister(pdev[i]);
1608 platform_driver_unregister(&nct6775_driver);
1612 static void __exit sensors_nct6775_platform_exit(void)
1616 for (i = 0; i < ARRAY_SIZE(pdev); i++)
1617 platform_device_unregister(pdev[i]);
1618 platform_driver_unregister(&nct6775_driver);
1621 MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>");
1622 MODULE_DESCRIPTION("Platform driver for NCT6775F and compatible chips");
1623 MODULE_LICENSE("GPL");
1624 MODULE_IMPORT_NS(HWMON_NCT6775);
1626 module_init(sensors_nct6775_platform_init);
1627 module_exit(sensors_nct6775_platform_exit);