Linux Audio

Check our new training course

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