Linux Audio

Check our new training course

Loading...
Note: File does not exist in v5.9.
   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#include <linux/wmi.h>
  21
  22#include "nct6775.h"
  23
  24enum sensor_access { access_direct, access_asuswmi };
  25
  26static const char * const nct6775_sio_names[] __initconst = {
  27	"NCT6106D",
  28	"NCT6116D",
  29	"NCT6775F",
  30	"NCT6776D/F",
  31	"NCT6779D",
  32	"NCT6791D",
  33	"NCT6792D",
  34	"NCT6793D",
  35	"NCT6795D",
  36	"NCT6796D",
  37	"NCT6797D",
  38	"NCT6798D",
  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_ID_MASK		0xFFF8
  90
  91/*
  92 * Control registers
  93 */
  94#define NCT6775_REG_CR_FAN_DEBOUNCE	0xf0
  95
  96struct nct6775_sio_data {
  97	int sioreg;
  98	int ld;
  99	enum kinds kind;
 100	enum sensor_access access;
 101
 102	/* superio_() callbacks  */
 103	void (*sio_outb)(struct nct6775_sio_data *sio_data, int reg, int val);
 104	int (*sio_inb)(struct nct6775_sio_data *sio_data, int reg);
 105	void (*sio_select)(struct nct6775_sio_data *sio_data, int ld);
 106	int (*sio_enter)(struct nct6775_sio_data *sio_data);
 107	void (*sio_exit)(struct nct6775_sio_data *sio_data);
 108};
 109
 110#define ASUSWMI_MONITORING_GUID		"466747A0-70EC-11DE-8A39-0800200C9A66"
 111#define ASUSWMI_METHODID_RSIO		0x5253494F
 112#define ASUSWMI_METHODID_WSIO		0x5753494F
 113#define ASUSWMI_METHODID_RHWM		0x5248574D
 114#define ASUSWMI_METHODID_WHWM		0x5748574D
 115#define ASUSWMI_UNSUPPORTED_METHOD	0xFFFFFFFE
 116
 117static int nct6775_asuswmi_evaluate_method(u32 method_id, u8 bank, u8 reg, u8 val, u32 *retval)
 118{
 119#if IS_ENABLED(CONFIG_ACPI_WMI)
 120	u32 args = bank | (reg << 8) | (val << 16);
 121	struct acpi_buffer input = { (acpi_size) sizeof(args), &args };
 122	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
 123	acpi_status status;
 124	union acpi_object *obj;
 125	u32 tmp = ASUSWMI_UNSUPPORTED_METHOD;
 126
 127	status = wmi_evaluate_method(ASUSWMI_MONITORING_GUID, 0,
 128				     method_id, &input, &output);
 129
 130	if (ACPI_FAILURE(status))
 131		return -EIO;
 132
 133	obj = output.pointer;
 134	if (obj && obj->type == ACPI_TYPE_INTEGER)
 135		tmp = obj->integer.value;
 136
 137	if (retval)
 138		*retval = tmp;
 139
 140	kfree(obj);
 141
 142	if (tmp == ASUSWMI_UNSUPPORTED_METHOD)
 143		return -ENODEV;
 144	return 0;
 145#else
 146	return -EOPNOTSUPP;
 147#endif
 148}
 149
 150static inline int nct6775_asuswmi_write(u8 bank, u8 reg, u8 val)
 151{
 152	return nct6775_asuswmi_evaluate_method(ASUSWMI_METHODID_WHWM, bank,
 153					      reg, val, NULL);
 154}
 155
 156static inline int nct6775_asuswmi_read(u8 bank, u8 reg, u8 *val)
 157{
 158	u32 ret, tmp = 0;
 159
 160	ret = nct6775_asuswmi_evaluate_method(ASUSWMI_METHODID_RHWM, bank,
 161					      reg, 0, &tmp);
 162	*val = tmp;
 163	return ret;
 164}
 165
 166static int superio_wmi_inb(struct nct6775_sio_data *sio_data, int reg)
 167{
 168	int tmp = 0;
 169
 170	nct6775_asuswmi_evaluate_method(ASUSWMI_METHODID_RSIO, sio_data->ld,
 171					reg, 0, &tmp);
 172	return tmp;
 173}
 174
 175static void superio_wmi_outb(struct nct6775_sio_data *sio_data, int reg, int val)
 176{
 177	nct6775_asuswmi_evaluate_method(ASUSWMI_METHODID_WSIO, sio_data->ld,
 178					reg, val, NULL);
 179}
 180
 181static void superio_wmi_select(struct nct6775_sio_data *sio_data, int ld)
 182{
 183	sio_data->ld = ld;
 184}
 185
 186static int superio_wmi_enter(struct nct6775_sio_data *sio_data)
 187{
 188	return 0;
 189}
 190
 191static void superio_wmi_exit(struct nct6775_sio_data *sio_data)
 192{
 193}
 194
 195static void superio_outb(struct nct6775_sio_data *sio_data, int reg, int val)
 196{
 197	int ioreg = sio_data->sioreg;
 198
 199	outb(reg, ioreg);
 200	outb(val, ioreg + 1);
 201}
 202
 203static int superio_inb(struct nct6775_sio_data *sio_data, int reg)
 204{
 205	int ioreg = sio_data->sioreg;
 206
 207	outb(reg, ioreg);
 208	return inb(ioreg + 1);
 209}
 210
 211static void superio_select(struct nct6775_sio_data *sio_data, int ld)
 212{
 213	int ioreg = sio_data->sioreg;
 214
 215	outb(SIO_REG_LDSEL, ioreg);
 216	outb(ld, ioreg + 1);
 217}
 218
 219static int superio_enter(struct nct6775_sio_data *sio_data)
 220{
 221	int ioreg = sio_data->sioreg;
 222
 223	/*
 224	 * Try to reserve <ioreg> and <ioreg + 1> for exclusive access.
 225	 */
 226	if (!request_muxed_region(ioreg, 2, DRVNAME))
 227		return -EBUSY;
 228
 229	outb(0x87, ioreg);
 230	outb(0x87, ioreg);
 231
 232	return 0;
 233}
 234
 235static void superio_exit(struct nct6775_sio_data *sio_data)
 236{
 237	int ioreg = sio_data->sioreg;
 238
 239	outb(0xaa, ioreg);
 240	outb(0x02, ioreg);
 241	outb(0x02, ioreg + 1);
 242	release_region(ioreg, 2);
 243}
 244
 245static inline void nct6775_wmi_set_bank(struct nct6775_data *data, u16 reg)
 246{
 247	u8 bank = reg >> 8;
 248
 249	data->bank = bank;
 250}
 251
 252static int nct6775_wmi_reg_read(void *ctx, unsigned int reg, unsigned int *val)
 253{
 254	struct nct6775_data *data = ctx;
 255	int err, word_sized = nct6775_reg_is_word_sized(data, reg);
 256	u8 tmp = 0;
 257	u16 res;
 258
 259	nct6775_wmi_set_bank(data, reg);
 260
 261	err = nct6775_asuswmi_read(data->bank, reg & 0xff, &tmp);
 262	if (err)
 263		return err;
 264
 265	res = tmp;
 266	if (word_sized) {
 267		err = nct6775_asuswmi_read(data->bank, (reg & 0xff) + 1, &tmp);
 268		if (err)
 269			return err;
 270
 271		res = (res << 8) + tmp;
 272	}
 273	*val = res;
 274	return 0;
 275}
 276
 277static int nct6775_wmi_reg_write(void *ctx, unsigned int reg, unsigned int value)
 278{
 279	struct nct6775_data *data = ctx;
 280	int res, word_sized = nct6775_reg_is_word_sized(data, reg);
 281
 282	nct6775_wmi_set_bank(data, reg);
 283
 284	if (word_sized) {
 285		res = nct6775_asuswmi_write(data->bank, reg & 0xff, value >> 8);
 286		if (res)
 287			return res;
 288
 289		res = nct6775_asuswmi_write(data->bank, (reg & 0xff) + 1, value);
 290	} else {
 291		res = nct6775_asuswmi_write(data->bank, reg & 0xff, value);
 292	}
 293
 294	return res;
 295}
 296
 297/*
 298 * On older chips, only registers 0x50-0x5f are banked.
 299 * On more recent chips, all registers are banked.
 300 * Assume that is the case and set the bank number for each access.
 301 * Cache the bank number so it only needs to be set if it changes.
 302 */
 303static inline void nct6775_set_bank(struct nct6775_data *data, u16 reg)
 304{
 305	u8 bank = reg >> 8;
 306
 307	if (data->bank != bank) {
 308		outb_p(NCT6775_REG_BANK, data->addr + ADDR_REG_OFFSET);
 309		outb_p(bank, data->addr + DATA_REG_OFFSET);
 310		data->bank = bank;
 311	}
 312}
 313
 314static int nct6775_reg_read(void *ctx, unsigned int reg, unsigned int *val)
 315{
 316	struct nct6775_data *data = ctx;
 317	int word_sized = nct6775_reg_is_word_sized(data, reg);
 318
 319	nct6775_set_bank(data, reg);
 320	outb_p(reg & 0xff, data->addr + ADDR_REG_OFFSET);
 321	*val = inb_p(data->addr + DATA_REG_OFFSET);
 322	if (word_sized) {
 323		outb_p((reg & 0xff) + 1,
 324		       data->addr + ADDR_REG_OFFSET);
 325		*val = (*val << 8) + inb_p(data->addr + DATA_REG_OFFSET);
 326	}
 327	return 0;
 328}
 329
 330static int nct6775_reg_write(void *ctx, unsigned int reg, unsigned int value)
 331{
 332	struct nct6775_data *data = ctx;
 333	int word_sized = nct6775_reg_is_word_sized(data, reg);
 334
 335	nct6775_set_bank(data, reg);
 336	outb_p(reg & 0xff, data->addr + ADDR_REG_OFFSET);
 337	if (word_sized) {
 338		outb_p(value >> 8, data->addr + DATA_REG_OFFSET);
 339		outb_p((reg & 0xff) + 1,
 340		       data->addr + ADDR_REG_OFFSET);
 341	}
 342	outb_p(value & 0xff, data->addr + DATA_REG_OFFSET);
 343	return 0;
 344}
 345
 346static void nct6791_enable_io_mapping(struct nct6775_sio_data *sio_data)
 347{
 348	int val;
 349
 350	val = sio_data->sio_inb(sio_data, NCT6791_REG_HM_IO_SPACE_LOCK_ENABLE);
 351	if (val & 0x10) {
 352		pr_info("Enabling hardware monitor logical device mappings.\n");
 353		sio_data->sio_outb(sio_data, NCT6791_REG_HM_IO_SPACE_LOCK_ENABLE,
 354			       val & ~0x10);
 355	}
 356}
 357
 358static int nct6775_suspend(struct device *dev)
 359{
 360	int err;
 361	u16 tmp;
 362	struct nct6775_data *data = nct6775_update_device(dev);
 363
 364	if (IS_ERR(data))
 365		return PTR_ERR(data);
 366
 367	mutex_lock(&data->update_lock);
 368	err = nct6775_read_value(data, data->REG_VBAT, &tmp);
 369	if (err)
 370		goto out;
 371	data->vbat = tmp;
 372	if (data->kind == nct6775) {
 373		err = nct6775_read_value(data, NCT6775_REG_FANDIV1, &tmp);
 374		if (err)
 375			goto out;
 376		data->fandiv1 = tmp;
 377
 378		err = nct6775_read_value(data, NCT6775_REG_FANDIV2, &tmp);
 379		if (err)
 380			goto out;
 381		data->fandiv2 = tmp;
 382	}
 383out:
 384	mutex_unlock(&data->update_lock);
 385
 386	return err;
 387}
 388
 389static int nct6775_resume(struct device *dev)
 390{
 391	struct nct6775_data *data = dev_get_drvdata(dev);
 392	struct nct6775_sio_data *sio_data = dev_get_platdata(dev);
 393	int i, j, err = 0;
 394	u8 reg;
 395
 396	mutex_lock(&data->update_lock);
 397	data->bank = 0xff;		/* Force initial bank selection */
 398
 399	err = sio_data->sio_enter(sio_data);
 400	if (err)
 401		goto abort;
 402
 403	sio_data->sio_select(sio_data, NCT6775_LD_HWM);
 404	reg = sio_data->sio_inb(sio_data, SIO_REG_ENABLE);
 405	if (reg != data->sio_reg_enable)
 406		sio_data->sio_outb(sio_data, SIO_REG_ENABLE, data->sio_reg_enable);
 407
 408	if (data->kind == nct6791 || data->kind == nct6792 ||
 409	    data->kind == nct6793 || data->kind == nct6795 ||
 410	    data->kind == nct6796 || data->kind == nct6797 ||
 411	    data->kind == nct6798)
 412		nct6791_enable_io_mapping(sio_data);
 413
 414	sio_data->sio_exit(sio_data);
 415
 416	/* Restore limits */
 417	for (i = 0; i < data->in_num; i++) {
 418		if (!(data->have_in & BIT(i)))
 419			continue;
 420
 421		err = nct6775_write_value(data, data->REG_IN_MINMAX[0][i], data->in[i][1]);
 422		if (err)
 423			goto abort;
 424		err = nct6775_write_value(data, data->REG_IN_MINMAX[1][i], data->in[i][2]);
 425		if (err)
 426			goto abort;
 427	}
 428
 429	for (i = 0; i < ARRAY_SIZE(data->fan_min); i++) {
 430		if (!(data->has_fan_min & BIT(i)))
 431			continue;
 432
 433		err = nct6775_write_value(data, data->REG_FAN_MIN[i], data->fan_min[i]);
 434		if (err)
 435			goto abort;
 436	}
 437
 438	for (i = 0; i < NUM_TEMP; i++) {
 439		if (!(data->have_temp & BIT(i)))
 440			continue;
 441
 442		for (j = 1; j < ARRAY_SIZE(data->reg_temp); j++)
 443			if (data->reg_temp[j][i]) {
 444				err = nct6775_write_temp(data, data->reg_temp[j][i],
 445							 data->temp[j][i]);
 446				if (err)
 447					goto abort;
 448			}
 449	}
 450
 451	/* Restore other settings */
 452	err = nct6775_write_value(data, data->REG_VBAT, data->vbat);
 453	if (err)
 454		goto abort;
 455	if (data->kind == nct6775) {
 456		err = nct6775_write_value(data, NCT6775_REG_FANDIV1, data->fandiv1);
 457		if (err)
 458			goto abort;
 459		err = nct6775_write_value(data, NCT6775_REG_FANDIV2, data->fandiv2);
 460	}
 461
 462abort:
 463	/* Force re-reading all values */
 464	data->valid = false;
 465	mutex_unlock(&data->update_lock);
 466
 467	return err;
 468}
 469
 470static DEFINE_SIMPLE_DEV_PM_OPS(nct6775_dev_pm_ops, nct6775_suspend, nct6775_resume);
 471
 472static void
 473nct6775_check_fan_inputs(struct nct6775_data *data, struct nct6775_sio_data *sio_data)
 474{
 475	bool fan3pin = false, fan4pin = false, fan4min = false;
 476	bool fan5pin = false, fan6pin = false, fan7pin = false;
 477	bool pwm3pin = false, pwm4pin = false, pwm5pin = false;
 478	bool pwm6pin = false, pwm7pin = false;
 479
 480	/* Store SIO_REG_ENABLE for use during resume */
 481	sio_data->sio_select(sio_data, NCT6775_LD_HWM);
 482	data->sio_reg_enable = sio_data->sio_inb(sio_data, SIO_REG_ENABLE);
 483
 484	/* fan4 and fan5 share some pins with the GPIO and serial flash */
 485	if (data->kind == nct6775) {
 486		int cr2c = sio_data->sio_inb(sio_data, 0x2c);
 487
 488		fan3pin = cr2c & BIT(6);
 489		pwm3pin = cr2c & BIT(7);
 490
 491		/* On NCT6775, fan4 shares pins with the fdc interface */
 492		fan4pin = !(sio_data->sio_inb(sio_data, 0x2A) & 0x80);
 493	} else if (data->kind == nct6776) {
 494		bool gpok = sio_data->sio_inb(sio_data, 0x27) & 0x80;
 495		const char *board_vendor, *board_name;
 496
 497		board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR);
 498		board_name = dmi_get_system_info(DMI_BOARD_NAME);
 499
 500		if (board_name && board_vendor &&
 501		    !strcmp(board_vendor, "ASRock")) {
 502			/*
 503			 * Auxiliary fan monitoring is not enabled on ASRock
 504			 * Z77 Pro4-M if booted in UEFI Ultra-FastBoot mode.
 505			 * Observed with BIOS version 2.00.
 506			 */
 507			if (!strcmp(board_name, "Z77 Pro4-M")) {
 508				if ((data->sio_reg_enable & 0xe0) != 0xe0) {
 509					data->sio_reg_enable |= 0xe0;
 510					sio_data->sio_outb(sio_data, SIO_REG_ENABLE,
 511						     data->sio_reg_enable);
 512				}
 513			}
 514		}
 515
 516		if (data->sio_reg_enable & 0x80)
 517			fan3pin = gpok;
 518		else
 519			fan3pin = !(sio_data->sio_inb(sio_data, 0x24) & 0x40);
 520
 521		if (data->sio_reg_enable & 0x40)
 522			fan4pin = gpok;
 523		else
 524			fan4pin = sio_data->sio_inb(sio_data, 0x1C) & 0x01;
 525
 526		if (data->sio_reg_enable & 0x20)
 527			fan5pin = gpok;
 528		else
 529			fan5pin = sio_data->sio_inb(sio_data, 0x1C) & 0x02;
 530
 531		fan4min = fan4pin;
 532		pwm3pin = fan3pin;
 533	} else if (data->kind == nct6106) {
 534		int cr24 = sio_data->sio_inb(sio_data, 0x24);
 535
 536		fan3pin = !(cr24 & 0x80);
 537		pwm3pin = cr24 & 0x08;
 538	} else if (data->kind == nct6116) {
 539		int cr1a = sio_data->sio_inb(sio_data, 0x1a);
 540		int cr1b = sio_data->sio_inb(sio_data, 0x1b);
 541		int cr24 = sio_data->sio_inb(sio_data, 0x24);
 542		int cr2a = sio_data->sio_inb(sio_data, 0x2a);
 543		int cr2b = sio_data->sio_inb(sio_data, 0x2b);
 544		int cr2f = sio_data->sio_inb(sio_data, 0x2f);
 545
 546		fan3pin = !(cr2b & 0x10);
 547		fan4pin = (cr2b & 0x80) ||			// pin 1(2)
 548			(!(cr2f & 0x10) && (cr1a & 0x04));	// pin 65(66)
 549		fan5pin = (cr2b & 0x80) ||			// pin 126(127)
 550			(!(cr1b & 0x03) && (cr2a & 0x02));	// pin 94(96)
 551
 552		pwm3pin = fan3pin && (cr24 & 0x08);
 553		pwm4pin = fan4pin;
 554		pwm5pin = fan5pin;
 555	} else {
 556		/*
 557		 * NCT6779D, NCT6791D, NCT6792D, NCT6793D, NCT6795D, NCT6796D,
 558		 * NCT6797D, NCT6798D
 559		 */
 560		int cr1a = sio_data->sio_inb(sio_data, 0x1a);
 561		int cr1b = sio_data->sio_inb(sio_data, 0x1b);
 562		int cr1c = sio_data->sio_inb(sio_data, 0x1c);
 563		int cr1d = sio_data->sio_inb(sio_data, 0x1d);
 564		int cr2a = sio_data->sio_inb(sio_data, 0x2a);
 565		int cr2b = sio_data->sio_inb(sio_data, 0x2b);
 566		int cr2d = sio_data->sio_inb(sio_data, 0x2d);
 567		int cr2f = sio_data->sio_inb(sio_data, 0x2f);
 568		bool dsw_en = cr2f & BIT(3);
 569		bool ddr4_en = cr2f & BIT(4);
 570		int cre0;
 571		int creb;
 572		int cred;
 573
 574		sio_data->sio_select(sio_data, NCT6775_LD_12);
 575		cre0 = sio_data->sio_inb(sio_data, 0xe0);
 576		creb = sio_data->sio_inb(sio_data, 0xeb);
 577		cred = sio_data->sio_inb(sio_data, 0xed);
 578
 579		fan3pin = !(cr1c & BIT(5));
 580		fan4pin = !(cr1c & BIT(6));
 581		fan5pin = !(cr1c & BIT(7));
 582
 583		pwm3pin = !(cr1c & BIT(0));
 584		pwm4pin = !(cr1c & BIT(1));
 585		pwm5pin = !(cr1c & BIT(2));
 586
 587		switch (data->kind) {
 588		case nct6791:
 589			fan6pin = cr2d & BIT(1);
 590			pwm6pin = cr2d & BIT(0);
 591			break;
 592		case nct6792:
 593			fan6pin = !dsw_en && (cr2d & BIT(1));
 594			pwm6pin = !dsw_en && (cr2d & BIT(0));
 595			break;
 596		case nct6793:
 597			fan5pin |= cr1b & BIT(5);
 598			fan5pin |= creb & BIT(5);
 599
 600			fan6pin = !dsw_en && (cr2d & BIT(1));
 601			fan6pin |= creb & BIT(3);
 602
 603			pwm5pin |= cr2d & BIT(7);
 604			pwm5pin |= (creb & BIT(4)) && !(cr2a & BIT(0));
 605
 606			pwm6pin = !dsw_en && (cr2d & BIT(0));
 607			pwm6pin |= creb & BIT(2);
 608			break;
 609		case nct6795:
 610			fan5pin |= cr1b & BIT(5);
 611			fan5pin |= creb & BIT(5);
 612
 613			fan6pin = (cr2a & BIT(4)) &&
 614					(!dsw_en || (cred & BIT(4)));
 615			fan6pin |= creb & BIT(3);
 616
 617			pwm5pin |= cr2d & BIT(7);
 618			pwm5pin |= (creb & BIT(4)) && !(cr2a & BIT(0));
 619
 620			pwm6pin = (cr2a & BIT(3)) && (cred & BIT(2));
 621			pwm6pin |= creb & BIT(2);
 622			break;
 623		case nct6796:
 624			fan5pin |= cr1b & BIT(5);
 625			fan5pin |= (cre0 & BIT(3)) && !(cr1b & BIT(0));
 626			fan5pin |= creb & BIT(5);
 627
 628			fan6pin = (cr2a & BIT(4)) &&
 629					(!dsw_en || (cred & BIT(4)));
 630			fan6pin |= creb & BIT(3);
 631
 632			fan7pin = !(cr2b & BIT(2));
 633
 634			pwm5pin |= cr2d & BIT(7);
 635			pwm5pin |= (cre0 & BIT(4)) && !(cr1b & BIT(0));
 636			pwm5pin |= (creb & BIT(4)) && !(cr2a & BIT(0));
 637
 638			pwm6pin = (cr2a & BIT(3)) && (cred & BIT(2));
 639			pwm6pin |= creb & BIT(2);
 640
 641			pwm7pin = !(cr1d & (BIT(2) | BIT(3)));
 642			break;
 643		case nct6797:
 644			fan5pin |= !ddr4_en && (cr1b & BIT(5));
 645			fan5pin |= creb & BIT(5);
 646
 647			fan6pin = cr2a & BIT(4);
 648			fan6pin |= creb & BIT(3);
 649
 650			fan7pin = cr1a & BIT(1);
 651
 652			pwm5pin |= (creb & BIT(4)) && !(cr2a & BIT(0));
 653			pwm5pin |= !ddr4_en && (cr2d & BIT(7));
 654
 655			pwm6pin = creb & BIT(2);
 656			pwm6pin |= cred & BIT(2);
 657
 658			pwm7pin = cr1d & BIT(4);
 659			break;
 660		case nct6798:
 661			fan6pin = !(cr1b & BIT(0)) && (cre0 & BIT(3));
 662			fan6pin |= cr2a & BIT(4);
 663			fan6pin |= creb & BIT(5);
 664
 665			fan7pin = cr1b & BIT(5);
 666			fan7pin |= !(cr2b & BIT(2));
 667			fan7pin |= creb & BIT(3);
 668
 669			pwm6pin = !(cr1b & BIT(0)) && (cre0 & BIT(4));
 670			pwm6pin |= !(cred & BIT(2)) && (cr2a & BIT(3));
 671			pwm6pin |= (creb & BIT(4)) && !(cr2a & BIT(0));
 672
 673			pwm7pin = !(cr1d & (BIT(2) | BIT(3)));
 674			pwm7pin |= cr2d & BIT(7);
 675			pwm7pin |= creb & BIT(2);
 676			break;
 677		default:	/* NCT6779D */
 678			break;
 679		}
 680
 681		fan4min = fan4pin;
 682	}
 683
 684	/* fan 1 and 2 (0x03) are always present */
 685	data->has_fan = 0x03 | (fan3pin << 2) | (fan4pin << 3) |
 686		(fan5pin << 4) | (fan6pin << 5) | (fan7pin << 6);
 687	data->has_fan_min = 0x03 | (fan3pin << 2) | (fan4min << 3) |
 688		(fan5pin << 4) | (fan6pin << 5) | (fan7pin << 6);
 689	data->has_pwm = 0x03 | (pwm3pin << 2) | (pwm4pin << 3) |
 690		(pwm5pin << 4) | (pwm6pin << 5) | (pwm7pin << 6);
 691}
 692
 693static ssize_t
 694cpu0_vid_show(struct device *dev, struct device_attribute *attr, char *buf)
 695{
 696	struct nct6775_data *data = dev_get_drvdata(dev);
 697
 698	return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm));
 699}
 700
 701static DEVICE_ATTR_RO(cpu0_vid);
 702
 703/* Case open detection */
 704
 705static const u8 NCT6775_REG_CR_CASEOPEN_CLR[] = { 0xe6, 0xee };
 706static const u8 NCT6775_CR_CASEOPEN_CLR_MASK[] = { 0x20, 0x01 };
 707
 708static ssize_t
 709clear_caseopen(struct device *dev, struct device_attribute *attr,
 710	       const char *buf, size_t count)
 711{
 712	struct nct6775_data *data = dev_get_drvdata(dev);
 713	struct nct6775_sio_data *sio_data = data->driver_data;
 714	int nr = to_sensor_dev_attr(attr)->index - INTRUSION_ALARM_BASE;
 715	unsigned long val;
 716	u8 reg;
 717	int ret;
 718
 719	if (kstrtoul(buf, 10, &val) || val != 0)
 720		return -EINVAL;
 721
 722	mutex_lock(&data->update_lock);
 723
 724	/*
 725	 * Use CR registers to clear caseopen status.
 726	 * The CR registers are the same for all chips, and not all chips
 727	 * support clearing the caseopen status through "regular" registers.
 728	 */
 729	ret = sio_data->sio_enter(sio_data);
 730	if (ret) {
 731		count = ret;
 732		goto error;
 733	}
 734
 735	sio_data->sio_select(sio_data, NCT6775_LD_ACPI);
 736	reg = sio_data->sio_inb(sio_data, NCT6775_REG_CR_CASEOPEN_CLR[nr]);
 737	reg |= NCT6775_CR_CASEOPEN_CLR_MASK[nr];
 738	sio_data->sio_outb(sio_data, NCT6775_REG_CR_CASEOPEN_CLR[nr], reg);
 739	reg &= ~NCT6775_CR_CASEOPEN_CLR_MASK[nr];
 740	sio_data->sio_outb(sio_data, NCT6775_REG_CR_CASEOPEN_CLR[nr], reg);
 741	sio_data->sio_exit(sio_data);
 742
 743	data->valid = false;	/* Force cache refresh */
 744error:
 745	mutex_unlock(&data->update_lock);
 746	return count;
 747}
 748
 749static SENSOR_DEVICE_ATTR(intrusion0_alarm, 0644, nct6775_show_alarm,
 750			  clear_caseopen, INTRUSION_ALARM_BASE);
 751static SENSOR_DEVICE_ATTR(intrusion1_alarm, 0644, nct6775_show_alarm,
 752			  clear_caseopen, INTRUSION_ALARM_BASE + 1);
 753static SENSOR_DEVICE_ATTR(intrusion0_beep, 0644, nct6775_show_beep,
 754			  nct6775_store_beep, INTRUSION_ALARM_BASE);
 755static SENSOR_DEVICE_ATTR(intrusion1_beep, 0644, nct6775_show_beep,
 756			  nct6775_store_beep, INTRUSION_ALARM_BASE + 1);
 757static SENSOR_DEVICE_ATTR(beep_enable, 0644, nct6775_show_beep,
 758			  nct6775_store_beep, BEEP_ENABLE_BASE);
 759
 760static umode_t nct6775_other_is_visible(struct kobject *kobj,
 761					struct attribute *attr, int index)
 762{
 763	struct device *dev = kobj_to_dev(kobj);
 764	struct nct6775_data *data = dev_get_drvdata(dev);
 765
 766	if (index == 0 && !data->have_vid)
 767		return 0;
 768
 769	if (index == 1 || index == 2) {
 770		if (data->ALARM_BITS[INTRUSION_ALARM_BASE + index - 1] < 0)
 771			return 0;
 772	}
 773
 774	if (index == 3 || index == 4) {
 775		if (data->BEEP_BITS[INTRUSION_ALARM_BASE + index - 3] < 0)
 776			return 0;
 777	}
 778
 779	return nct6775_attr_mode(data, attr);
 780}
 781
 782/*
 783 * nct6775_other_is_visible uses the index into the following array
 784 * to determine if attributes should be created or not.
 785 * Any change in order or content must be matched.
 786 */
 787static struct attribute *nct6775_attributes_other[] = {
 788	&dev_attr_cpu0_vid.attr,				/* 0 */
 789	&sensor_dev_attr_intrusion0_alarm.dev_attr.attr,	/* 1 */
 790	&sensor_dev_attr_intrusion1_alarm.dev_attr.attr,	/* 2 */
 791	&sensor_dev_attr_intrusion0_beep.dev_attr.attr,		/* 3 */
 792	&sensor_dev_attr_intrusion1_beep.dev_attr.attr,		/* 4 */
 793	&sensor_dev_attr_beep_enable.dev_attr.attr,		/* 5 */
 794
 795	NULL
 796};
 797
 798static const struct attribute_group nct6775_group_other = {
 799	.attrs = nct6775_attributes_other,
 800	.is_visible = nct6775_other_is_visible,
 801};
 802
 803static int nct6775_platform_probe_init(struct nct6775_data *data)
 804{
 805	int err;
 806	u8 cr2a;
 807	struct nct6775_sio_data *sio_data = data->driver_data;
 808
 809	err = sio_data->sio_enter(sio_data);
 810	if (err)
 811		return err;
 812
 813	cr2a = sio_data->sio_inb(sio_data, 0x2a);
 814	switch (data->kind) {
 815	case nct6775:
 816		data->have_vid = (cr2a & 0x40);
 817		break;
 818	case nct6776:
 819		data->have_vid = (cr2a & 0x60) == 0x40;
 820		break;
 821	case nct6106:
 822	case nct6116:
 823	case nct6779:
 824	case nct6791:
 825	case nct6792:
 826	case nct6793:
 827	case nct6795:
 828	case nct6796:
 829	case nct6797:
 830	case nct6798:
 831		break;
 832	}
 833
 834	/*
 835	 * Read VID value
 836	 * We can get the VID input values directly at logical device D 0xe3.
 837	 */
 838	if (data->have_vid) {
 839		sio_data->sio_select(sio_data, NCT6775_LD_VID);
 840		data->vid = sio_data->sio_inb(sio_data, 0xe3);
 841		data->vrm = vid_which_vrm();
 842	}
 843
 844	if (fan_debounce) {
 845		u8 tmp;
 846
 847		sio_data->sio_select(sio_data, NCT6775_LD_HWM);
 848		tmp = sio_data->sio_inb(sio_data,
 849				    NCT6775_REG_CR_FAN_DEBOUNCE);
 850		switch (data->kind) {
 851		case nct6106:
 852		case nct6116:
 853			tmp |= 0xe0;
 854			break;
 855		case nct6775:
 856			tmp |= 0x1e;
 857			break;
 858		case nct6776:
 859		case nct6779:
 860			tmp |= 0x3e;
 861			break;
 862		case nct6791:
 863		case nct6792:
 864		case nct6793:
 865		case nct6795:
 866		case nct6796:
 867		case nct6797:
 868		case nct6798:
 869			tmp |= 0x7e;
 870			break;
 871		}
 872		sio_data->sio_outb(sio_data, NCT6775_REG_CR_FAN_DEBOUNCE,
 873			     tmp);
 874		pr_info("Enabled fan debounce for chip %s\n", data->name);
 875	}
 876
 877	nct6775_check_fan_inputs(data, sio_data);
 878
 879	sio_data->sio_exit(sio_data);
 880
 881	return nct6775_add_attr_group(data, &nct6775_group_other);
 882}
 883
 884static const struct regmap_config nct6775_regmap_config = {
 885	.reg_bits = 16,
 886	.val_bits = 16,
 887	.reg_read = nct6775_reg_read,
 888	.reg_write = nct6775_reg_write,
 889};
 890
 891static const struct regmap_config nct6775_wmi_regmap_config = {
 892	.reg_bits = 16,
 893	.val_bits = 16,
 894	.reg_read = nct6775_wmi_reg_read,
 895	.reg_write = nct6775_wmi_reg_write,
 896};
 897
 898static int nct6775_platform_probe(struct platform_device *pdev)
 899{
 900	struct device *dev = &pdev->dev;
 901	struct nct6775_sio_data *sio_data = dev_get_platdata(dev);
 902	struct nct6775_data *data;
 903	struct resource *res;
 904	const struct regmap_config *regmapcfg;
 905
 906	if (sio_data->access == access_direct) {
 907		res = platform_get_resource(pdev, IORESOURCE_IO, 0);
 908		if (!devm_request_region(&pdev->dev, res->start, IOREGION_LENGTH, DRVNAME))
 909			return -EBUSY;
 910	}
 911
 912	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
 913	if (!data)
 914		return -ENOMEM;
 915
 916	data->kind = sio_data->kind;
 917	data->sioreg = sio_data->sioreg;
 918
 919	if (sio_data->access == access_direct) {
 920		data->addr = res->start;
 921		regmapcfg = &nct6775_regmap_config;
 922	} else {
 923		regmapcfg = &nct6775_wmi_regmap_config;
 924	}
 925
 926	platform_set_drvdata(pdev, data);
 927
 928	data->driver_data = sio_data;
 929	data->driver_init = nct6775_platform_probe_init;
 930
 931	return nct6775_probe(&pdev->dev, data, regmapcfg);
 932}
 933
 934static struct platform_driver nct6775_driver = {
 935	.driver = {
 936		.name	= DRVNAME,
 937		.pm	= pm_sleep_ptr(&nct6775_dev_pm_ops),
 938	},
 939	.probe		= nct6775_platform_probe,
 940};
 941
 942/* nct6775_find() looks for a '627 in the Super-I/O config space */
 943static int __init nct6775_find(int sioaddr, struct nct6775_sio_data *sio_data)
 944{
 945	u16 val;
 946	int err;
 947	int addr;
 948
 949	sio_data->access = access_direct;
 950	sio_data->sioreg = sioaddr;
 951
 952	err = sio_data->sio_enter(sio_data);
 953	if (err)
 954		return err;
 955
 956	val = (sio_data->sio_inb(sio_data, SIO_REG_DEVID) << 8) |
 957		sio_data->sio_inb(sio_data, SIO_REG_DEVID + 1);
 958	if (force_id && val != 0xffff)
 959		val = force_id;
 960
 961	switch (val & SIO_ID_MASK) {
 962	case SIO_NCT6106_ID:
 963		sio_data->kind = nct6106;
 964		break;
 965	case SIO_NCT6116_ID:
 966		sio_data->kind = nct6116;
 967		break;
 968	case SIO_NCT6775_ID:
 969		sio_data->kind = nct6775;
 970		break;
 971	case SIO_NCT6776_ID:
 972		sio_data->kind = nct6776;
 973		break;
 974	case SIO_NCT6779_ID:
 975		sio_data->kind = nct6779;
 976		break;
 977	case SIO_NCT6791_ID:
 978		sio_data->kind = nct6791;
 979		break;
 980	case SIO_NCT6792_ID:
 981		sio_data->kind = nct6792;
 982		break;
 983	case SIO_NCT6793_ID:
 984		sio_data->kind = nct6793;
 985		break;
 986	case SIO_NCT6795_ID:
 987		sio_data->kind = nct6795;
 988		break;
 989	case SIO_NCT6796_ID:
 990		sio_data->kind = nct6796;
 991		break;
 992	case SIO_NCT6797_ID:
 993		sio_data->kind = nct6797;
 994		break;
 995	case SIO_NCT6798_ID:
 996		sio_data->kind = nct6798;
 997		break;
 998	default:
 999		if (val != 0xffff)
1000			pr_debug("unsupported chip ID: 0x%04x\n", val);
1001		sio_data->sio_exit(sio_data);
1002		return -ENODEV;
1003	}
1004
1005	/* We have a known chip, find the HWM I/O address */
1006	sio_data->sio_select(sio_data, NCT6775_LD_HWM);
1007	val = (sio_data->sio_inb(sio_data, SIO_REG_ADDR) << 8)
1008	    | sio_data->sio_inb(sio_data, SIO_REG_ADDR + 1);
1009	addr = val & IOREGION_ALIGNMENT;
1010	if (addr == 0) {
1011		pr_err("Refusing to enable a Super-I/O device with a base I/O port 0\n");
1012		sio_data->sio_exit(sio_data);
1013		return -ENODEV;
1014	}
1015
1016	/* Activate logical device if needed */
1017	val = sio_data->sio_inb(sio_data, SIO_REG_ENABLE);
1018	if (!(val & 0x01)) {
1019		pr_warn("Forcibly enabling Super-I/O. Sensor is probably unusable.\n");
1020		sio_data->sio_outb(sio_data, SIO_REG_ENABLE, val | 0x01);
1021	}
1022
1023	if (sio_data->kind == nct6791 || sio_data->kind == nct6792 ||
1024	    sio_data->kind == nct6793 || sio_data->kind == nct6795 ||
1025	    sio_data->kind == nct6796 || sio_data->kind == nct6797 ||
1026	    sio_data->kind == nct6798)
1027		nct6791_enable_io_mapping(sio_data);
1028
1029	sio_data->sio_exit(sio_data);
1030	pr_info("Found %s or compatible chip at %#x:%#x\n",
1031		nct6775_sio_names[sio_data->kind], sioaddr, addr);
1032
1033	return addr;
1034}
1035
1036/*
1037 * when Super-I/O functions move to a separate file, the Super-I/O
1038 * bus will manage the lifetime of the device and this module will only keep
1039 * track of the nct6775 driver. But since we use platform_device_alloc(), we
1040 * must keep track of the device
1041 */
1042static struct platform_device *pdev[2];
1043
1044static const char * const asus_wmi_boards[] = {
1045	"PRO H410T",
1046	"ProArt B550-CREATOR",
1047	"ProArt X570-CREATOR WIFI",
1048	"ProArt Z490-CREATOR 10G",
1049	"Pro B550M-C",
1050	"Pro WS X570-ACE",
1051	"PRIME B360-PLUS",
1052	"PRIME B460-PLUS",
1053	"PRIME B550-PLUS",
1054	"PRIME B550M-A",
1055	"PRIME B550M-A (WI-FI)",
1056	"PRIME H410M-R",
1057	"PRIME X570-P",
1058	"PRIME X570-PRO",
1059	"ROG CROSSHAIR VIII DARK HERO",
1060	"ROG CROSSHAIR VIII EXTREME",
1061	"ROG CROSSHAIR VIII FORMULA",
1062	"ROG CROSSHAIR VIII HERO",
1063	"ROG CROSSHAIR VIII HERO (WI-FI)",
1064	"ROG CROSSHAIR VIII IMPACT",
1065	"ROG STRIX B550-A GAMING",
1066	"ROG STRIX B550-E GAMING",
1067	"ROG STRIX B550-F GAMING",
1068	"ROG STRIX B550-F GAMING (WI-FI)",
1069	"ROG STRIX B550-F GAMING WIFI II",
1070	"ROG STRIX B550-I GAMING",
1071	"ROG STRIX B550-XE GAMING (WI-FI)",
1072	"ROG STRIX X570-E GAMING",
1073	"ROG STRIX X570-E GAMING WIFI II",
1074	"ROG STRIX X570-F GAMING",
1075	"ROG STRIX X570-I GAMING",
1076	"ROG STRIX Z390-E GAMING",
1077	"ROG STRIX Z390-F GAMING",
1078	"ROG STRIX Z390-H GAMING",
1079	"ROG STRIX Z390-I GAMING",
1080	"ROG STRIX Z490-A GAMING",
1081	"ROG STRIX Z490-E GAMING",
1082	"ROG STRIX Z490-F GAMING",
1083	"ROG STRIX Z490-G GAMING",
1084	"ROG STRIX Z490-G GAMING (WI-FI)",
1085	"ROG STRIX Z490-H GAMING",
1086	"ROG STRIX Z490-I GAMING",
1087	"TUF GAMING B550M-E",
1088	"TUF GAMING B550M-E (WI-FI)",
1089	"TUF GAMING B550M-PLUS",
1090	"TUF GAMING B550M-PLUS (WI-FI)",
1091	"TUF GAMING B550M-PLUS WIFI II",
1092	"TUF GAMING B550-PLUS",
1093	"TUF GAMING B550-PLUS WIFI II",
1094	"TUF GAMING B550-PRO",
1095	"TUF GAMING X570-PLUS",
1096	"TUF GAMING X570-PLUS (WI-FI)",
1097	"TUF GAMING X570-PRO (WI-FI)",
1098	"TUF GAMING Z490-PLUS",
1099	"TUF GAMING Z490-PLUS (WI-FI)",
1100};
1101
1102static int __init sensors_nct6775_platform_init(void)
1103{
1104	int i, err;
1105	bool found = false;
1106	int address;
1107	struct resource res;
1108	struct nct6775_sio_data sio_data;
1109	int sioaddr[2] = { 0x2e, 0x4e };
1110	enum sensor_access access = access_direct;
1111	const char *board_vendor, *board_name;
1112	u8 tmp;
1113
1114	err = platform_driver_register(&nct6775_driver);
1115	if (err)
1116		return err;
1117
1118	board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR);
1119	board_name = dmi_get_system_info(DMI_BOARD_NAME);
1120
1121	if (board_name && board_vendor &&
1122	    !strcmp(board_vendor, "ASUSTeK COMPUTER INC.")) {
1123		err = match_string(asus_wmi_boards, ARRAY_SIZE(asus_wmi_boards),
1124				   board_name);
1125		if (err >= 0) {
1126			/* if reading chip id via WMI succeeds, use WMI */
1127			if (!nct6775_asuswmi_read(0, NCT6775_PORT_CHIPID, &tmp) && tmp) {
1128				pr_info("Using Asus WMI to access %#x chip.\n", tmp);
1129				access = access_asuswmi;
1130			} else {
1131				pr_err("Can't read ChipID by Asus WMI.\n");
1132			}
1133		}
1134	}
1135
1136	/*
1137	 * initialize sio_data->kind and sio_data->sioreg.
1138	 *
1139	 * when Super-I/O functions move to a separate file, the Super-I/O
1140	 * driver will probe 0x2e and 0x4e and auto-detect the presence of a
1141	 * nct6775 hardware monitor, and call probe()
1142	 */
1143	for (i = 0; i < ARRAY_SIZE(pdev); i++) {
1144		sio_data.sio_outb = superio_outb;
1145		sio_data.sio_inb = superio_inb;
1146		sio_data.sio_select = superio_select;
1147		sio_data.sio_enter = superio_enter;
1148		sio_data.sio_exit = superio_exit;
1149
1150		address = nct6775_find(sioaddr[i], &sio_data);
1151		if (address <= 0)
1152			continue;
1153
1154		found = true;
1155
1156		sio_data.access = access;
1157
1158		if (access == access_asuswmi) {
1159			sio_data.sio_outb = superio_wmi_outb;
1160			sio_data.sio_inb = superio_wmi_inb;
1161			sio_data.sio_select = superio_wmi_select;
1162			sio_data.sio_enter = superio_wmi_enter;
1163			sio_data.sio_exit = superio_wmi_exit;
1164		}
1165
1166		pdev[i] = platform_device_alloc(DRVNAME, address);
1167		if (!pdev[i]) {
1168			err = -ENOMEM;
1169			goto exit_device_unregister;
1170		}
1171
1172		err = platform_device_add_data(pdev[i], &sio_data,
1173					       sizeof(struct nct6775_sio_data));
1174		if (err)
1175			goto exit_device_put;
1176
1177		if (sio_data.access == access_direct) {
1178			memset(&res, 0, sizeof(res));
1179			res.name = DRVNAME;
1180			res.start = address + IOREGION_OFFSET;
1181			res.end = address + IOREGION_OFFSET + IOREGION_LENGTH - 1;
1182			res.flags = IORESOURCE_IO;
1183
1184			err = acpi_check_resource_conflict(&res);
1185			if (err) {
1186				platform_device_put(pdev[i]);
1187				pdev[i] = NULL;
1188				continue;
1189			}
1190
1191			err = platform_device_add_resources(pdev[i], &res, 1);
1192			if (err)
1193				goto exit_device_put;
1194		}
1195
1196		/* platform_device_add calls probe() */
1197		err = platform_device_add(pdev[i]);
1198		if (err)
1199			goto exit_device_put;
1200	}
1201	if (!found) {
1202		err = -ENODEV;
1203		goto exit_unregister;
1204	}
1205
1206	return 0;
1207
1208exit_device_put:
1209	platform_device_put(pdev[i]);
1210exit_device_unregister:
1211	while (i--)
1212		platform_device_unregister(pdev[i]);
1213exit_unregister:
1214	platform_driver_unregister(&nct6775_driver);
1215	return err;
1216}
1217
1218static void __exit sensors_nct6775_platform_exit(void)
1219{
1220	int i;
1221
1222	for (i = 0; i < ARRAY_SIZE(pdev); i++)
1223		platform_device_unregister(pdev[i]);
1224	platform_driver_unregister(&nct6775_driver);
1225}
1226
1227MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>");
1228MODULE_DESCRIPTION("Platform driver for NCT6775F and compatible chips");
1229MODULE_LICENSE("GPL");
1230MODULE_IMPORT_NS(HWMON_NCT6775);
1231
1232module_init(sensors_nct6775_platform_init);
1233module_exit(sensors_nct6775_platform_exit);