xref: /linux/drivers/hwmon/nct6775-platform.c (revision 34dc1baba215b826e454b8d19e4f24adbeb7d00d)
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 
23 enum sensor_access { access_direct, access_asuswmi };
24 
25 static const char * const nct6775_sio_names[] __initconst = {
26 	"NCT6106D",
27 	"NCT6116D",
28 	"NCT6775F",
29 	"NCT6776D/F",
30 	"NCT6779D",
31 	"NCT6791D",
32 	"NCT6792D",
33 	"NCT6793D",
34 	"NCT6795D",
35 	"NCT6796D",
36 	"NCT6797D",
37 	"NCT6798D",
38 	"NCT6796D-S/NCT6799D-R",
39 };
40 
41 static unsigned short force_id;
42 module_param(force_id, ushort, 0);
43 MODULE_PARM_DESC(force_id, "Override the detected device ID");
44 
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");
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 
97 struct 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  */
126 static struct acpi_device *asus_acpi_dev;
127 #endif
128 
129 static 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 
162 static 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 
168 static 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 
178 static 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 
187 static 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 
193 static void superio_wmi_select(struct nct6775_sio_data *sio_data, int ld)
194 {
195 	sio_data->ld = ld;
196 }
197 
198 static int superio_wmi_enter(struct nct6775_sio_data *sio_data)
199 {
200 	return 0;
201 }
202 
203 static void superio_wmi_exit(struct nct6775_sio_data *sio_data)
204 {
205 }
206 
207 static 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 
215 static 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 
223 static 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 
231 static 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 
247 static 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 
257 static 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 
264 static 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 
289 static 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  */
315 static 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 
326 static 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 
342 static 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 
358 static 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 
370 static 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 	}
395 out:
396 	mutex_unlock(&data->update_lock);
397 
398 	return err;
399 }
400 
401 static 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 
474 abort:
475 	/* Force re-reading all values */
476 	data->valid = false;
477 	mutex_unlock(&data->update_lock);
478 
479 	return err;
480 }
481 
482 static DEFINE_SIMPLE_DEV_PM_OPS(nct6775_dev_pm_ops, nct6775_suspend, nct6775_resume);
483 
484 static void
485 nct6775_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 
733 static ssize_t
734 cpu0_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 
741 static DEVICE_ATTR_RO(cpu0_vid);
742 
743 /* Case open detection */
744 
745 static const u8 NCT6775_REG_CR_CASEOPEN_CLR[] = { 0xe6, 0xee };
746 static const u8 NCT6775_CR_CASEOPEN_CLR_MASK[] = { 0x20, 0x01 };
747 
748 static ssize_t
749 clear_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 */
784 error:
785 	mutex_unlock(&data->update_lock);
786 	return count;
787 }
788 
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);
799 
800 static 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  */
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 */
834 
835 	NULL
836 };
837 
838 static const struct attribute_group nct6775_group_other = {
839 	.attrs = nct6775_attributes_other,
840 	.is_visible = nct6775_other_is_visible,
841 };
842 
843 static 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 
926 static 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 
933 static 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 
940 static 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 
976 static 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 */
985 static 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  */
1087 static struct platform_device *pdev[2];
1088 
1089 static 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 
1264 static 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  */
1465 static int nct6775_asuswmi_device_match(struct device *dev, void *data)
1466 {
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);
1470 
1471 	if (hid && !strcmp(hid, ASUSWMI_DEVICE_HID) && uid && !strcmp(uid, data)) {
1472 		asus_acpi_dev = adev;
1473 		return 1;
1474 	}
1475 
1476 	return 0;
1477 }
1478 #endif
1479 
1480 static enum sensor_access nct6775_determine_access(const char *device_uid)
1481 {
1482 #if IS_ENABLED(CONFIG_ACPI)
1483 	u8 tmp;
1484 
1485 	acpi_bus_for_each_dev(nct6775_asuswmi_device_match, (void *)device_uid);
1486 	if (!asus_acpi_dev)
1487 		return access_direct;
1488 
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;
1493 	}
1494 #endif
1495 
1496 	return access_direct;
1497 }
1498 
1499 static int __init sensors_nct6775_platform_init(void)
1500 {
1501 	int i, err;
1502 	bool found = false;
1503 	int address;
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;
1509 
1510 	err = platform_driver_register(&nct6775_driver);
1511 	if (err)
1512 		return err;
1513 
1514 	board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR);
1515 	board_name = dmi_get_system_info(DMI_BOARD_NAME);
1516 
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),
1520 				   board_name);
1521 		if (err >= 0)
1522 			access = nct6775_determine_access(ASUSWMI_DEVICE_UID);
1523 
1524 		err = match_string(asus_msi_boards, ARRAY_SIZE(asus_msi_boards),
1525 				   board_name);
1526 		if (err >= 0)
1527 			access = nct6775_determine_access(ASUSMSI_DEVICE_UID);
1528 	}
1529 
1530 	/*
1531 	 * initialize sio_data->kind and sio_data->sioreg.
1532 	 *
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()
1536 	 */
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;
1543 
1544 		address = nct6775_find(sioaddr[i], &sio_data);
1545 		if (address <= 0)
1546 			continue;
1547 
1548 		found = true;
1549 
1550 		sio_data.access = access;
1551 
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;
1558 		}
1559 
1560 		pdev[i] = platform_device_alloc(DRVNAME, address);
1561 		if (!pdev[i]) {
1562 			err = -ENOMEM;
1563 			goto exit_device_unregister;
1564 		}
1565 
1566 		err = platform_device_add_data(pdev[i], &sio_data,
1567 					       sizeof(struct nct6775_sio_data));
1568 		if (err)
1569 			goto exit_device_put;
1570 
1571 		if (sio_data.access == access_direct) {
1572 			memset(&res, 0, sizeof(res));
1573 			res.name = DRVNAME;
1574 			res.start = address + IOREGION_OFFSET;
1575 			res.end = address + IOREGION_OFFSET + IOREGION_LENGTH - 1;
1576 			res.flags = IORESOURCE_IO;
1577 
1578 			err = acpi_check_resource_conflict(&res);
1579 			if (err) {
1580 				platform_device_put(pdev[i]);
1581 				pdev[i] = NULL;
1582 				continue;
1583 			}
1584 
1585 			err = platform_device_add_resources(pdev[i], &res, 1);
1586 			if (err)
1587 				goto exit_device_put;
1588 		}
1589 
1590 		/* platform_device_add calls probe() */
1591 		err = platform_device_add(pdev[i]);
1592 		if (err)
1593 			goto exit_device_put;
1594 	}
1595 	if (!found) {
1596 		err = -ENODEV;
1597 		goto exit_unregister;
1598 	}
1599 
1600 	return 0;
1601 
1602 exit_device_put:
1603 	platform_device_put(pdev[i]);
1604 exit_device_unregister:
1605 	while (i--)
1606 		platform_device_unregister(pdev[i]);
1607 exit_unregister:
1608 	platform_driver_unregister(&nct6775_driver);
1609 	return err;
1610 }
1611 
1612 static void __exit sensors_nct6775_platform_exit(void)
1613 {
1614 	int i;
1615 
1616 	for (i = 0; i < ARRAY_SIZE(pdev); i++)
1617 		platform_device_unregister(pdev[i]);
1618 	platform_driver_unregister(&nct6775_driver);
1619 }
1620 
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);
1625 
1626 module_init(sensors_nct6775_platform_init);
1627 module_exit(sensors_nct6775_platform_exit);
1628