File Index
Files and directories
Sign in
FILE

nct6775-platform.c

File preview with syntax highlighting.

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