// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * nct6683 - Driver for the hardware monitoring functionality of
 *	     Nuvoton NCT6683D/NCT6686D/NCT6687D eSIO
 *
 * Copyright (C) 2013  Guenter Roeck <linux@roeck-us.net>
 *
 * Derived from nct6775 driver
 * Copyright (C) 2012, 2013  Guenter Roeck <linux@roeck-us.net>
 *
 * Supports the following chips:
 *
 * Chip        #vin    #fan    #pwm    #temp  chip ID
 * nct6683d     21(1)   16      8       32(1) 0xc730
 * nct6686d     21(1)   16      8       32(1) 0xd440
 * nct6687d     21(1)   16      8       32(1) 0xd590
 *
 * Notes:
 *	(1) Total number of vin and temp inputs is 32.
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/acpi.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/jiffies.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/platform_device.h>
#include <linux/slab.h>

enum kinds { nct6683, nct6686, nct6687 };

static bool force;
module_param(force, bool, 0);
MODULE_PARM_DESC(force, "Set to one to enable support for unknown vendors");

static const char * const nct6683_device_names[] = {
	"nct6683",
	"nct6686",
	"nct6687",
};

static const char * const nct6683_chip_names[] = {
	"NCT6683D",
	"NCT6686D",
	"NCT6687D",
};

#define DRVNAME "nct6683"

/*
 * Super-I/O constants and functions
 */

#define NCT6683_LD_ACPI		0x0a
#define NCT6683_LD_HWM		0x0b
#define NCT6683_LD_VID		0x0d

#define SIO_REG_LDSEL		0x07	/* Logical device select */
#define SIO_REG_DEVID		0x20	/* Device ID (2 bytes) */
#define SIO_REG_ENABLE		0x30	/* Logical device enable */
#define SIO_REG_ADDR		0x60	/* Logical device address (2 bytes) */

#define SIO_NCT6681_ID		0xb270	/* for later */
#define SIO_NCT6683_ID		0xc730
#define SIO_NCT6686_ID		0xd440
#define SIO_NCT6687_ID		0xd590
#define SIO_ID_MASK		0xFFF0

static inline void
superio_outb(int ioreg, int reg, int val)
{
	outb(reg, ioreg);
	outb(val, ioreg + 1);
}

static inline int
superio_inb(int ioreg, int reg)
{
	outb(reg, ioreg);
	return inb(ioreg + 1);
}

static inline void
superio_select(int ioreg, int ld)
{
	outb(SIO_REG_LDSEL, ioreg);
	outb(ld, ioreg + 1);
}

static inline int
superio_enter(int ioreg)
{
	/*
	 * Try to reserve <ioreg> and <ioreg + 1> for exclusive access.
	 */
	if (!request_muxed_region(ioreg, 2, DRVNAME))
		return -EBUSY;

	outb(0x87, ioreg);
	outb(0x87, ioreg);

	return 0;
}

static inline void
superio_exit(int ioreg)
{
	outb(0xaa, ioreg);
	outb(0x02, ioreg);
	outb(0x02, ioreg + 1);
	release_region(ioreg, 2);
}

/*
 * ISA constants
 */

#define IOREGION_ALIGNMENT	(~7)
#define IOREGION_OFFSET		4	/* Use EC port 1 */
#define IOREGION_LENGTH		4

#define EC_PAGE_REG		0
#define EC_INDEX_REG		1
#define EC_DATA_REG		2
#define EC_EVENT_REG		3

/* Common and NCT6683 specific data */

#define NCT6683_NUM_REG_MON		32
#define NCT6683_NUM_REG_FAN		16
#define NCT6683_NUM_REG_PWM		8

#define NCT6683_REG_MON(x)		(0x100 + (x) * 2)
#define NCT6683_REG_FAN_RPM(x)		(0x140 + (x) * 2)
#define NCT6683_REG_PWM(x)		(0x160 + (x))
#define NCT6683_REG_PWM_WRITE(x)	(0xa28 + (x))

#define NCT6683_REG_MON_STS(x)		(0x174 + (x))
#define NCT6683_REG_IDLE(x)		(0x178 + (x))

#define NCT6683_REG_FAN_STS(x)		(0x17c + (x))
#define NCT6683_REG_FAN_ERRSTS		0x17e
#define NCT6683_REG_FAN_INITSTS		0x17f

#define NCT6683_HWM_CFG			0x180

#define NCT6683_REG_MON_CFG(x)		(0x1a0 + (x))
#define NCT6683_REG_FANIN_CFG(x)	(0x1c0 + (x))
#define NCT6683_REG_FANOUT_CFG(x)	(0x1d0 + (x))

#define NCT6683_REG_INTEL_TEMP_MAX(x)	(0x901 + (x) * 16)
#define NCT6683_REG_INTEL_TEMP_CRIT(x)	(0x90d + (x) * 16)

#define NCT6683_REG_TEMP_HYST(x)	(0x330 + (x))		/* 8 bit */
#define NCT6683_REG_TEMP_MAX(x)		(0x350 + (x))		/* 8 bit */
#define NCT6683_REG_MON_HIGH(x)		(0x370 + (x) * 2)	/* 8 bit */
#define NCT6683_REG_MON_LOW(x)		(0x371 + (x) * 2)	/* 8 bit */

#define NCT6683_REG_FAN_MIN(x)		(0x3b8 + (x) * 2)	/* 16 bit */

#define NCT6683_REG_FAN_CFG_CTRL	0xa01
#define NCT6683_FAN_CFG_REQ		0x80
#define NCT6683_FAN_CFG_DONE		0x40

#define NCT6683_REG_CUSTOMER_ID		0x602
#define NCT6683_CUSTOMER_ID_INTEL	0x805
#define NCT6683_CUSTOMER_ID_MITAC	0xa0e
#define NCT6683_CUSTOMER_ID_MSI		0x201
#define NCT6683_CUSTOMER_ID_MSI2	0x200
#define NCT6683_CUSTOMER_ID_MSI3	0x207
#define NCT6683_CUSTOMER_ID_ASROCK		0xe2c
#define NCT6683_CUSTOMER_ID_ASROCK2	0xe1b
#define NCT6683_CUSTOMER_ID_ASROCK3	0x1631

#define NCT6683_REG_BUILD_YEAR		0x604
#define NCT6683_REG_BUILD_MONTH		0x605
#define NCT6683_REG_BUILD_DAY		0x606
#define NCT6683_REG_SERIAL		0x607
#define NCT6683_REG_VERSION_HI		0x608
#define NCT6683_REG_VERSION_LO		0x609

#define NCT6683_REG_CR_CASEOPEN		0xe8
#define NCT6683_CR_CASEOPEN_MASK	(1 << 7)

#define NCT6683_REG_CR_BEEP		0xe0
#define NCT6683_CR_BEEP_MASK		(1 << 6)

static const char *const nct6683_mon_label[] = {
	NULL,	/* disabled */
	"Local",
	"Diode 0 (curr)",
	"Diode 1 (curr)",
	"Diode 2 (curr)",
	"Diode 0 (volt)",
	"Diode 1 (volt)",
	"Diode 2 (volt)",
	"Thermistor 14",
	"Thermistor 15",
	"Thermistor 16",
	"Thermistor 0",
	"Thermistor 1",
	"Thermistor 2",
	"Thermistor 3",
	"Thermistor 4",
	"Thermistor 5",		/* 0x10 */
	"Thermistor 6",
	"Thermistor 7",
	"Thermistor 8",
	"Thermistor 9",
	"Thermistor 10",
	"Thermistor 11",
	"Thermistor 12",
	"Thermistor 13",
	NULL, NULL, NULL, NULL, NULL, NULL, NULL,
	"PECI 0.0",		/* 0x20 */
	"PECI 1.0",
	"PECI 2.0",
	"PECI 3.0",
	"PECI 0.1",
	"PECI 1.1",
	"PECI 2.1",
	"PECI 3.1",
	"PECI DIMM 0",
	"PECI DIMM 1",
	"PECI DIMM 2",
	"PECI DIMM 3",
	NULL, NULL, NULL, NULL,
	"PCH CPU",		/* 0x30 */
	"PCH CHIP",
	"PCH CHIP CPU MAX",
	"PCH MCH",
	"PCH DIMM 0",
	"PCH DIMM 1",
	"PCH DIMM 2",
	"PCH DIMM 3",
	"SMBus 0",
	"SMBus 1",
	"SMBus 2",
	"SMBus 3",
	"SMBus 4",
	"SMBus 5",
	"DIMM 0",
	"DIMM 1",
	"DIMM 2",		/* 0x40 */
	"DIMM 3",
	"AMD TSI Addr 90h",
	"AMD TSI Addr 92h",
	"AMD TSI Addr 94h",
	"AMD TSI Addr 96h",
	"AMD TSI Addr 98h",
	"AMD TSI Addr 9ah",
	"AMD TSI Addr 9ch",
	"AMD TSI Addr 9dh",
	NULL, NULL, NULL, NULL, NULL, NULL,
	"Virtual 0",		/* 0x50 */
	"Virtual 1",
	"Virtual 2",
	"Virtual 3",
	"Virtual 4",
	"Virtual 5",
	"Virtual 6",
	"Virtual 7",
	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
	"VCC",			/* 0x60 voltage sensors */
	"VSB",
	"AVSB",
	"VTT",
	"VBAT",
	"VREF",
	"VIN0",
	"VIN1",
	"VIN2",
	"VIN3",
	"VIN4",
	"VIN5",
	"VIN6",
	"VIN7",
	"VIN8",
	"VIN9",
	"VIN10",
	"VIN11",
	"VIN12",
	"VIN13",
	"VIN14",
	"VIN15",
	"VIN16",
};

#define NUM_MON_LABELS		ARRAY_SIZE(nct6683_mon_label)
#define MON_VOLTAGE_START	0x60

/* ------------------------------------------------------- */

struct nct6683_data {
	int addr;		/* IO base of EC space */
	int sioreg;		/* SIO register */
	enum kinds kind;
	u16 customer_id;

	struct device *hwmon_dev;
	const struct attribute_group *groups[6];

	int temp_num;			/* number of temperature attributes */
	u8 temp_index[NCT6683_NUM_REG_MON];
	u8 temp_src[NCT6683_NUM_REG_MON];

	u8 in_num;			/* number of voltage attributes */
	u8 in_index[NCT6683_NUM_REG_MON];
	u8 in_src[NCT6683_NUM_REG_MON];

	struct mutex update_lock;	/* used to protect sensor updates */
	bool valid;			/* true if following fields are valid */
	unsigned long last_updated;	/* In jiffies */

	/* Voltage attribute values */
	u8 in[3][NCT6683_NUM_REG_MON];	/* [0]=in, [1]=in_max, [2]=in_min */

	/* Temperature attribute values */
	s16 temp_in[NCT6683_NUM_REG_MON];
	s8 temp[4][NCT6683_NUM_REG_MON];/* [0]=min, [1]=max, [2]=hyst,
					 * [3]=crit
					 */

	/* Fan attribute values */
	unsigned int rpm[NCT6683_NUM_REG_FAN];
	u16 fan_min[NCT6683_NUM_REG_FAN];
	u8 fanin_cfg[NCT6683_NUM_REG_FAN];
	u8 fanout_cfg[NCT6683_NUM_REG_FAN];
	u16 have_fan;			/* some fan inputs can be disabled */

	u8 have_pwm;
	u8 pwm[NCT6683_NUM_REG_PWM];

#ifdef CONFIG_PM
	/* Remember extra register values over suspend/resume */
	u8 hwm_cfg;
#endif
};

struct nct6683_sio_data {
	int sioreg;
	enum kinds kind;
};

struct sensor_device_template {
	struct device_attribute dev_attr;
	union {
		struct {
			u8 nr;
			u8 index;
		} s;
		int index;
	} u;
	bool s2;	/* true if both index and nr are used */
};

struct sensor_device_attr_u {
	union {
		struct sensor_device_attribute a1;
		struct sensor_device_attribute_2 a2;
	} u;
	char name[32];
};

#define __TEMPLATE_ATTR(_template, _mode, _show, _store) {	\
	.attr = {.name = _template, .mode = _mode },		\
	.show	= _show,					\
	.store	= _store,					\
}

#define SENSOR_DEVICE_TEMPLATE(_template, _mode, _show, _store, _index)	\
	{ .dev_attr = __TEMPLATE_ATTR(_template, _mode, _show, _store),	\
	  .u.index = _index,						\
	  .s2 = false }

#define SENSOR_DEVICE_TEMPLATE_2(_template, _mode, _show, _store,	\
				 _nr, _index)				\
	{ .dev_attr = __TEMPLATE_ATTR(_template, _mode, _show, _store),	\
	  .u.s.index = _index,						\
	  .u.s.nr = _nr,						\
	  .s2 = true }

#define SENSOR_TEMPLATE(_name, _template, _mode, _show, _store, _index)	\
static struct sensor_device_template sensor_dev_template_##_name	\
	= SENSOR_DEVICE_TEMPLATE(_template, _mode, _show, _store,	\
				 _index)

#define SENSOR_TEMPLATE_2(_name, _template, _mode, _show, _store,	\
			  _nr, _index)					\
static struct sensor_device_template sensor_dev_template_##_name	\
	= SENSOR_DEVICE_TEMPLATE_2(_template, _mode, _show, _store,	\
				 _nr, _index)

struct sensor_template_group {
	struct sensor_device_template **templates;
	umode_t (*is_visible)(struct kobject *, struct attribute *, int);
	int base;
};

static struct attribute_group *
nct6683_create_attr_group(struct device *dev,
			  const struct sensor_template_group *tg,
			  int repeat)
{
	struct sensor_device_attribute_2 *a2;
	struct sensor_device_attribute *a;
	struct sensor_device_template **t;
	struct sensor_device_attr_u *su;
	struct attribute_group *group;
	struct attribute **attrs;
	int i, count;

	if (repeat <= 0)
		return ERR_PTR(-EINVAL);

	t = tg->templates;
	for (count = 0; *t; t++, count++)
		;

	if (count == 0)
		return ERR_PTR(-EINVAL);

	group = devm_kzalloc(dev, sizeof(*group), GFP_KERNEL);
	if (group == NULL)
		return ERR_PTR(-ENOMEM);

	attrs = devm_kcalloc(dev, repeat * count + 1, sizeof(*attrs),
			     GFP_KERNEL);
	if (attrs == NULL)
		return ERR_PTR(-ENOMEM);

	su = devm_kzalloc(dev, array3_size(repeat, count, sizeof(*su)),
			  GFP_KERNEL);
	if (su == NULL)
		return ERR_PTR(-ENOMEM);

	group->attrs = attrs;
	group->is_visible = tg->is_visible;

	for (i = 0; i < repeat; i++) {
		t = tg->templates;
		while (*t) {
			snprintf(su->name, sizeof(su->name),
				 (*t)->dev_attr.attr.name, tg->base + i);
			if ((*t)->s2) {
				a2 = &su->u.a2;
				sysfs_attr_init(&a2->dev_attr.attr);
				a2->dev_attr.attr.name = su->name;
				a2->nr = (*t)->u.s.nr + i;
				a2->index = (*t)->u.s.index;
				a2->dev_attr.attr.mode =
				  (*t)->dev_attr.attr.mode;
				a2->dev_attr.show = (*t)->dev_attr.show;
				a2->dev_attr.store = (*t)->dev_attr.store;
				*attrs = &a2->dev_attr.attr;
			} else {
				a = &su->u.a1;
				sysfs_attr_init(&a->dev_attr.attr);
				a->dev_attr.attr.name = su->name;
				a->index = (*t)->u.index + i;
				a->dev_attr.attr.mode =
				  (*t)->dev_attr.attr.mode;
				a->dev_attr.show = (*t)->dev_attr.show;
				a->dev_attr.store = (*t)->dev_attr.store;
				*attrs = &a->dev_attr.attr;
			}
			attrs++;
			su++;
			t++;
		}
	}

	return group;
}

/* LSB is 16 mV, except for the following sources, where it is 32 mV */
#define MON_SRC_VCC	0x60
#define MON_SRC_VSB	0x61
#define MON_SRC_AVSB	0x62
#define MON_SRC_VBAT	0x64

static inline long in_from_reg(u16 reg, u8 src)
{
	int scale = 16;

	if (src == MON_SRC_VCC || src == MON_SRC_VSB || src == MON_SRC_AVSB ||
	    src == MON_SRC_VBAT)
		scale <<= 1;
	return reg * scale;
}

static u16 nct6683_read(struct nct6683_data *data, u16 reg)
{
	int res;

	outb_p(0xff, data->addr + EC_PAGE_REG);		/* unlock */
	outb_p(reg >> 8, data->addr + EC_PAGE_REG);
	outb_p(reg & 0xff, data->addr + EC_INDEX_REG);
	res = inb_p(data->addr + EC_DATA_REG);
	return res;
}

static u16 nct6683_read16(struct nct6683_data *data, u16 reg)
{
	return (nct6683_read(data, reg) << 8) | nct6683_read(data, reg + 1);
}

static void nct6683_write(struct nct6683_data *data, u16 reg, u16 value)
{
	outb_p(0xff, data->addr + EC_PAGE_REG);		/* unlock */
	outb_p(reg >> 8, data->addr + EC_PAGE_REG);
	outb_p(reg & 0xff, data->addr + EC_INDEX_REG);
	outb_p(value & 0xff, data->addr + EC_DATA_REG);
}

static int get_in_reg(struct nct6683_data *data, int nr, int index)
{
	int ch = data->in_index[index];
	int reg = -EINVAL;

	switch (nr) {
	case 0:
		reg = NCT6683_REG_MON(ch);
		break;
	case 1:
		if (data->customer_id != NCT6683_CUSTOMER_ID_INTEL)
			reg = NCT6683_REG_MON_LOW(ch);
		break;
	case 2:
		if (data->customer_id != NCT6683_CUSTOMER_ID_INTEL)
			reg = NCT6683_REG_MON_HIGH(ch);
		break;
	default:
		break;
	}
	return reg;
}

static int get_temp_reg(struct nct6683_data *data, int nr, int index)
{
	int ch = data->temp_index[index];
	int reg = -EINVAL;

	switch (data->customer_id) {
	case NCT6683_CUSTOMER_ID_INTEL:
		switch (nr) {
		default:
		case 1:	/* max */
			reg = NCT6683_REG_INTEL_TEMP_MAX(ch);
			break;
		case 3:	/* crit */
			reg = NCT6683_REG_INTEL_TEMP_CRIT(ch);
			break;
		}
		break;
	case NCT6683_CUSTOMER_ID_MITAC:
	default:
		switch (nr) {
		default:
		case 0:	/* min */
			reg = NCT6683_REG_MON_LOW(ch);
			break;
		case 1:	/* max */
			reg = NCT6683_REG_TEMP_MAX(ch);
			break;
		case 2:	/* hyst */
			reg = NCT6683_REG_TEMP_HYST(ch);
			break;
		case 3:	/* crit */
			reg = NCT6683_REG_MON_HIGH(ch);
			break;
		}
		break;
	}
	return reg;
}

static void nct6683_update_pwm(struct device *dev)
{
	struct nct6683_data *data = dev_get_drvdata(dev);
	int i;

	for (i = 0; i < NCT6683_NUM_REG_PWM; i++) {
		if (!(data->have_pwm & (1 << i)))
			continue;
		data->pwm[i] = nct6683_read(data, NCT6683_REG_PWM(i));
	}
}

static struct nct6683_data *nct6683_update_device(struct device *dev)
{
	struct nct6683_data *data = dev_get_drvdata(dev);
	int i, j;

	mutex_lock(&data->update_lock);

	if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
		/* Measured voltages and limits */
		for (i = 0; i < data->in_num; i++) {
			for (j = 0; j < 3; j++) {
				int reg = get_in_reg(data, j, i);

				if (reg >= 0)
					data->in[j][i] =
						nct6683_read(data, reg);
			}
		}

		/* Measured temperatures and limits */
		for (i = 0; i < data->temp_num; i++) {
			u8 ch = data->temp_index[i];

			data->temp_in[i] = nct6683_read16(data,
							  NCT6683_REG_MON(ch));
			for (j = 0; j < 4; j++) {
				int reg = get_temp_reg(data, j, i);

				if (reg >= 0)
					data->temp[j][i] =
						nct6683_read(data, reg);
			}
		}

		/* Measured fan speeds and limits */
		for (i = 0; i < ARRAY_SIZE(data->rpm); i++) {
			if (!(data->have_fan & (1 << i)))
				continue;

			data->rpm[i] = nct6683_read16(data,
						NCT6683_REG_FAN_RPM(i));
			data->fan_min[i] = nct6683_read16(data,
						NCT6683_REG_FAN_MIN(i));
		}

		nct6683_update_pwm(dev);

		data->last_updated = jiffies;
		data->valid = true;
	}

	mutex_unlock(&data->update_lock);
	return data;
}

/*
 * Sysfs callback functions
 */
static ssize_t
show_in_label(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
	struct nct6683_data *data = nct6683_update_device(dev);
	int nr = sattr->index;

	return sprintf(buf, "%s\n", nct6683_mon_label[data->in_src[nr]]);
}

static ssize_t
show_in_reg(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
	struct nct6683_data *data = nct6683_update_device(dev);
	int index = sattr->index;
	int nr = sattr->nr;

	return sprintf(buf, "%ld\n",
		       in_from_reg(data->in[index][nr], data->in_index[index]));
}

static umode_t nct6683_in_is_visible(struct kobject *kobj,
				     struct attribute *attr, int index)
{
	struct device *dev = kobj_to_dev(kobj);
	struct nct6683_data *data = dev_get_drvdata(dev);
	int nr = index % 4;	/* attribute */

	/*
	 * Voltage limits exist for Intel boards,
	 * but register location and encoding is unknown
	 */
	if ((nr == 2 || nr == 3) &&
	    data->customer_id == NCT6683_CUSTOMER_ID_INTEL)
		return 0;

	return attr->mode;
}

SENSOR_TEMPLATE(in_label, "in%d_label", S_IRUGO, show_in_label, NULL, 0);
SENSOR_TEMPLATE_2(in_input, "in%d_input", S_IRUGO, show_in_reg, NULL, 0, 0);
SENSOR_TEMPLATE_2(in_min, "in%d_min", S_IRUGO, show_in_reg, NULL, 0, 1);
SENSOR_TEMPLATE_2(in_max, "in%d_max", S_IRUGO, show_in_reg, NULL, 0, 2);

static struct sensor_device_template *nct6683_attributes_in_template[] = {
	&sensor_dev_template_in_label,
	&sensor_dev_template_in_input,
	&sensor_dev_template_in_min,
	&sensor_dev_template_in_max,
	NULL
};

static const struct sensor_template_group nct6683_in_template_group = {
	.templates = nct6683_attributes_in_template,
	.is_visible = nct6683_in_is_visible,
};

static ssize_t
show_fan(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
	struct nct6683_data *data = nct6683_update_device(dev);

	return sprintf(buf, "%d\n", data->rpm[sattr->index]);
}

static ssize_t
show_fan_min(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct nct6683_data *data = nct6683_update_device(dev);
	struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
	int nr = sattr->index;

	return sprintf(buf, "%d\n", data->fan_min[nr]);
}

static ssize_t
show_fan_pulses(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
	struct nct6683_data *data = nct6683_update_device(dev);

	return sprintf(buf, "%d\n",
		       ((data->fanin_cfg[sattr->index] >> 5) & 0x03) + 1);
}

static umode_t nct6683_fan_is_visible(struct kobject *kobj,
				      struct attribute *attr, int index)
{
	struct device *dev = kobj_to_dev(kobj);
	struct nct6683_data *data = dev_get_drvdata(dev);
	int fan = index / 3;	/* fan index */
	int nr = index % 3;	/* attribute index */

	if (!(data->have_fan & (1 << fan)))
		return 0;

	/*
	 * Intel may have minimum fan speed limits,
	 * but register location and encoding are unknown.
	 */
	if (nr == 2 && data->customer_id == NCT6683_CUSTOMER_ID_INTEL)
		return 0;

	return attr->mode;
}

SENSOR_TEMPLATE(fan_input, "fan%d_input", S_IRUGO, show_fan, NULL, 0);
SENSOR_TEMPLATE(fan_pulses, "fan%d_pulses", S_IRUGO, show_fan_pulses, NULL, 0);
SENSOR_TEMPLATE(fan_min, "fan%d_min", S_IRUGO, show_fan_min, NULL, 0);

/*
 * nct6683_fan_is_visible uses the index into the following array
 * to determine if attributes should be created or not.
 * Any change in order or content must be matched.
 */
static struct sensor_device_template *nct6683_attributes_fan_template[] = {
	&sensor_dev_template_fan_input,
	&sensor_dev_template_fan_pulses,
	&sensor_dev_template_fan_min,
	NULL
};

static const struct sensor_template_group nct6683_fan_template_group = {
	.templates = nct6683_attributes_fan_template,
	.is_visible = nct6683_fan_is_visible,
	.base = 1,
};

static ssize_t
show_temp_label(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
	struct nct6683_data *data = nct6683_update_device(dev);
	int nr = sattr->index;

	return sprintf(buf, "%s\n", nct6683_mon_label[data->temp_src[nr]]);
}

static ssize_t
show_temp8(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
	struct nct6683_data *data = nct6683_update_device(dev);
	int index = sattr->index;
	int nr = sattr->nr;

	return sprintf(buf, "%d\n", data->temp[index][nr] * 1000);
}

static ssize_t
show_temp_hyst(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
	struct nct6683_data *data = nct6683_update_device(dev);
	int nr = sattr->index;
	int temp = data->temp[1][nr] - data->temp[2][nr];

	return sprintf(buf, "%d\n", temp * 1000);
}

static ssize_t
show_temp16(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
	struct nct6683_data *data = nct6683_update_device(dev);
	int index = sattr->index;

	return sprintf(buf, "%d\n", (data->temp_in[index] / 128) * 500);
}

/*
 * Temperature sensor type is determined by temperature source
 * and can not be modified.
 * 0x02..0x07: Thermal diode
 * 0x08..0x18: Thermistor
 * 0x20..0x2b: Intel PECI
 * 0x42..0x49: AMD TSI
 * Others are unspecified (not visible)
 */

static int get_temp_type(u8 src)
{
	if (src >= 0x02 && src <= 0x07)
		return 3;	/* thermal diode */
	else if (src >= 0x08 && src <= 0x18)
		return 4;	/* thermistor */
	else if (src >= 0x20 && src <= 0x2b)
		return 6;	/* PECI */
	else if (src >= 0x42 && src <= 0x49)
		return 5;

	return 0;
}

static ssize_t
show_temp_type(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct nct6683_data *data = nct6683_update_device(dev);
	struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
	int nr = sattr->index;
	return sprintf(buf, "%d\n", get_temp_type(data->temp_src[nr]));
}

static umode_t nct6683_temp_is_visible(struct kobject *kobj,
				       struct attribute *attr, int index)
{
	struct device *dev = kobj_to_dev(kobj);
	struct nct6683_data *data = dev_get_drvdata(dev);
	int temp = index / 7;	/* temp index */
	int nr = index % 7;	/* attribute index */

	/*
	 * Intel does not have low temperature limits or temperature hysteresis
	 * registers, or at least register location and encoding is unknown.
	 */
	if ((nr == 2 || nr == 4) &&
	    data->customer_id == NCT6683_CUSTOMER_ID_INTEL)
		return 0;

	if (nr == 6 && get_temp_type(data->temp_src[temp]) == 0)
		return 0;				/* type */

	return attr->mode;
}

SENSOR_TEMPLATE(temp_input, "temp%d_input", S_IRUGO, show_temp16, NULL, 0);
SENSOR_TEMPLATE(temp_label, "temp%d_label", S_IRUGO, show_temp_label, NULL, 0);
SENSOR_TEMPLATE_2(temp_min, "temp%d_min", S_IRUGO, show_temp8, NULL, 0, 0);
SENSOR_TEMPLATE_2(temp_max, "temp%d_max", S_IRUGO, show_temp8, NULL, 0, 1);
SENSOR_TEMPLATE(temp_max_hyst, "temp%d_max_hyst", S_IRUGO, show_temp_hyst, NULL,
		0);
SENSOR_TEMPLATE_2(temp_crit, "temp%d_crit", S_IRUGO, show_temp8, NULL, 0, 3);
SENSOR_TEMPLATE(temp_type, "temp%d_type", S_IRUGO, show_temp_type, NULL, 0);

/*
 * nct6683_temp_is_visible uses the index into the following array
 * to determine if attributes should be created or not.
 * Any change in order or content must be matched.
 */
static struct sensor_device_template *nct6683_attributes_temp_template[] = {
	&sensor_dev_template_temp_input,
	&sensor_dev_template_temp_label,
	&sensor_dev_template_temp_min,		/* 2 */
	&sensor_dev_template_temp_max,		/* 3 */
	&sensor_dev_template_temp_max_hyst,	/* 4 */
	&sensor_dev_template_temp_crit,		/* 5 */
	&sensor_dev_template_temp_type,		/* 6 */
	NULL
};

static const struct sensor_template_group nct6683_temp_template_group = {
	.templates = nct6683_attributes_temp_template,
	.is_visible = nct6683_temp_is_visible,
	.base = 1,
};

static ssize_t
show_pwm(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct nct6683_data *data = nct6683_update_device(dev);
	struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
	int index = sattr->index;

	return sprintf(buf, "%d\n", data->pwm[index]);
}

static ssize_t
store_pwm(struct device *dev, struct device_attribute *attr, const char *buf,
	  size_t count)
{
	struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
	struct nct6683_data *data = dev_get_drvdata(dev);
	int index = sattr->index;
	unsigned long val;

	if (kstrtoul(buf, 10, &val) || val > 255)
		return -EINVAL;

	mutex_lock(&data->update_lock);
	nct6683_write(data, NCT6683_REG_FAN_CFG_CTRL, NCT6683_FAN_CFG_REQ);
	usleep_range(1000, 2000);
	nct6683_write(data, NCT6683_REG_PWM_WRITE(index), val);
	nct6683_write(data, NCT6683_REG_FAN_CFG_CTRL, NCT6683_FAN_CFG_DONE);
	mutex_unlock(&data->update_lock);

	return count;
}

SENSOR_TEMPLATE(pwm, "pwm%d", S_IRUGO, show_pwm, store_pwm, 0);

static umode_t nct6683_pwm_is_visible(struct kobject *kobj,
				      struct attribute *attr, int index)
{
	struct device *dev = kobj_to_dev(kobj);
	struct nct6683_data *data = dev_get_drvdata(dev);
	int pwm = index;	/* pwm index */

	if (!(data->have_pwm & (1 << pwm)))
		return 0;

	/* Only update pwm values for Mitac boards */
	if (data->customer_id == NCT6683_CUSTOMER_ID_MITAC)
		return attr->mode | S_IWUSR;

	return attr->mode;
}

static struct sensor_device_template *nct6683_attributes_pwm_template[] = {
	&sensor_dev_template_pwm,
	NULL
};

static const struct sensor_template_group nct6683_pwm_template_group = {
	.templates = nct6683_attributes_pwm_template,
	.is_visible = nct6683_pwm_is_visible,
	.base = 1,
};

static ssize_t
beep_enable_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct nct6683_data *data = dev_get_drvdata(dev);
	int ret;
	u8 reg;

	mutex_lock(&data->update_lock);

	ret = superio_enter(data->sioreg);
	if (ret)
		goto error;
	superio_select(data->sioreg, NCT6683_LD_HWM);
	reg = superio_inb(data->sioreg, NCT6683_REG_CR_BEEP);
	superio_exit(data->sioreg);

	mutex_unlock(&data->update_lock);

	return sprintf(buf, "%u\n", !!(reg & NCT6683_CR_BEEP_MASK));

error:
	mutex_unlock(&data->update_lock);
	return ret;
}

static ssize_t
beep_enable_store(struct device *dev, struct device_attribute *attr,
		  const char *buf, size_t count)
{
	struct nct6683_data *data = dev_get_drvdata(dev);
	unsigned long val;
	u8 reg;
	int ret;

	if (kstrtoul(buf, 10, &val) || (val != 0 && val != 1))
		return -EINVAL;

	mutex_lock(&data->update_lock);

	ret = superio_enter(data->sioreg);
	if (ret) {
		count = ret;
		goto error;
	}

	superio_select(data->sioreg, NCT6683_LD_HWM);
	reg = superio_inb(data->sioreg, NCT6683_REG_CR_BEEP);
	if (val)
		reg |= NCT6683_CR_BEEP_MASK;
	else
		reg &= ~NCT6683_CR_BEEP_MASK;
	superio_outb(data->sioreg, NCT6683_REG_CR_BEEP, reg);
	superio_exit(data->sioreg);
error:
	mutex_unlock(&data->update_lock);
	return count;
}

/* Case open detection */

static ssize_t
intrusion0_alarm_show(struct device *dev, struct device_attribute *attr,
		      char *buf)
{
	struct nct6683_data *data = dev_get_drvdata(dev);
	int ret;
	u8 reg;

	mutex_lock(&data->update_lock);

	ret = superio_enter(data->sioreg);
	if (ret)
		goto error;
	superio_select(data->sioreg, NCT6683_LD_ACPI);
	reg = superio_inb(data->sioreg, NCT6683_REG_CR_CASEOPEN);
	superio_exit(data->sioreg);

	mutex_unlock(&data->update_lock);

	return sprintf(buf, "%u\n", !(reg & NCT6683_CR_CASEOPEN_MASK));

error:
	mutex_unlock(&data->update_lock);
	return ret;
}

static ssize_t
intrusion0_alarm_store(struct device *dev, struct device_attribute *attr,
		       const char *buf, size_t count)
{
	struct nct6683_data *data = dev_get_drvdata(dev);
	unsigned long val;
	u8 reg;
	int ret;

	if (kstrtoul(buf, 10, &val) || val != 0)
		return -EINVAL;

	mutex_lock(&data->update_lock);

	/*
	 * Use CR registers to clear caseopen status.
	 * Caseopen is activ low, clear by writing 1 into the register.
	 */

	ret = superio_enter(data->sioreg);
	if (ret) {
		count = ret;
		goto error;
	}

	superio_select(data->sioreg, NCT6683_LD_ACPI);
	reg = superio_inb(data->sioreg, NCT6683_REG_CR_CASEOPEN);
	reg |= NCT6683_CR_CASEOPEN_MASK;
	superio_outb(data->sioreg, NCT6683_REG_CR_CASEOPEN, reg);
	reg &= ~NCT6683_CR_CASEOPEN_MASK;
	superio_outb(data->sioreg, NCT6683_REG_CR_CASEOPEN, reg);
	superio_exit(data->sioreg);

	data->valid = false;	/* Force cache refresh */
error:
	mutex_unlock(&data->update_lock);
	return count;
}

static DEVICE_ATTR_RW(intrusion0_alarm);
static DEVICE_ATTR_RW(beep_enable);

static struct attribute *nct6683_attributes_other[] = {
	&dev_attr_intrusion0_alarm.attr,
	&dev_attr_beep_enable.attr,
	NULL
};

static const struct attribute_group nct6683_group_other = {
	.attrs = nct6683_attributes_other,
};

/* Get the monitoring functions started */
static inline void nct6683_init_device(struct nct6683_data *data)
{
	u8 tmp;

	/* Start hardware monitoring if needed */
	tmp = nct6683_read(data, NCT6683_HWM_CFG);
	if (!(tmp & 0x80))
		nct6683_write(data, NCT6683_HWM_CFG, tmp | 0x80);
}

/*
 * There are a total of 24 fan inputs. Each can be configured as input
 * or as output. A maximum of 16 inputs and 8 outputs is configurable.
 */
static void
nct6683_setup_fans(struct nct6683_data *data)
{
	int i;
	u8 reg;

	for (i = 0; i < NCT6683_NUM_REG_FAN; i++) {
		reg = nct6683_read(data, NCT6683_REG_FANIN_CFG(i));
		if (reg & 0x80)
			data->have_fan |= 1 << i;
		data->fanin_cfg[i] = reg;
	}
	for (i = 0; i < NCT6683_NUM_REG_PWM; i++) {
		reg = nct6683_read(data, NCT6683_REG_FANOUT_CFG(i));
		if (reg & 0x80)
			data->have_pwm |= 1 << i;
		data->fanout_cfg[i] = reg;
	}
}

/*
 * Translation from monitoring register to temperature and voltage attributes
 * ==========================================================================
 *
 * There are a total of 32 monitoring registers. Each can be assigned to either
 * a temperature or voltage monitoring source.
 * NCT6683_REG_MON_CFG(x) defines assignment for each monitoring source.
 *
 * Temperature and voltage attribute mapping is determined by walking through
 * the NCT6683_REG_MON_CFG registers. If the assigned source is
 * a temperature, temp_index[n] is set to the monitor register index, and
 * temp_src[n] is set to the temperature source. If the assigned source is
 * a voltage, the respective values are stored in in_index[] and in_src[],
 * respectively.
 */

static void nct6683_setup_sensors(struct nct6683_data *data)
{
	u8 reg;
	int i;

	data->temp_num = 0;
	data->in_num = 0;
	for (i = 0; i < NCT6683_NUM_REG_MON; i++) {
		reg = nct6683_read(data, NCT6683_REG_MON_CFG(i)) & 0x7f;
		/* Ignore invalid assignments */
		if (reg >= NUM_MON_LABELS)
			continue;
		/* Skip if disabled or reserved */
		if (nct6683_mon_label[reg] == NULL)
			continue;
		if (reg < MON_VOLTAGE_START) {
			data->temp_index[data->temp_num] = i;
			data->temp_src[data->temp_num] = reg;
			data->temp_num++;
		} else {
			data->in_index[data->in_num] = i;
			data->in_src[data->in_num] = reg;
			data->in_num++;
		}
	}
}

static int nct6683_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct nct6683_sio_data *sio_data = dev->platform_data;
	struct attribute_group *group;
	struct nct6683_data *data;
	struct device *hwmon_dev;
	struct resource *res;
	int groups = 0;
	char build[16];

	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
	if (!devm_request_region(dev, res->start, IOREGION_LENGTH, DRVNAME))
		return -EBUSY;

	data = devm_kzalloc(dev, sizeof(struct nct6683_data), GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	data->kind = sio_data->kind;
	data->sioreg = sio_data->sioreg;
	data->addr = res->start;
	mutex_init(&data->update_lock);
	platform_set_drvdata(pdev, data);

	data->customer_id = nct6683_read16(data, NCT6683_REG_CUSTOMER_ID);

	/* By default only instantiate driver if the customer ID is known */
	switch (data->customer_id) {
	case NCT6683_CUSTOMER_ID_INTEL:
		break;
	case NCT6683_CUSTOMER_ID_MITAC:
		break;
	case NCT6683_CUSTOMER_ID_MSI:
		break;
	case NCT6683_CUSTOMER_ID_MSI2:
		break;
	case NCT6683_CUSTOMER_ID_MSI3:
		break;
	case NCT6683_CUSTOMER_ID_ASROCK:
		break;
	case NCT6683_CUSTOMER_ID_ASROCK2:
		break;
	case NCT6683_CUSTOMER_ID_ASROCK3:
		break;
	default:
		if (!force)
			return -ENODEV;
		dev_warn(dev, "Enabling support for unknown customer ID 0x%04x\n", data->customer_id);
		break;
	}

	nct6683_init_device(data);
	nct6683_setup_fans(data);
	nct6683_setup_sensors(data);

	/* Register sysfs hooks */

	if (data->have_pwm) {
		group = nct6683_create_attr_group(dev,
						  &nct6683_pwm_template_group,
						  fls(data->have_pwm));
		if (IS_ERR(group))
			return PTR_ERR(group);
		data->groups[groups++] = group;
	}

	if (data->in_num) {
		group = nct6683_create_attr_group(dev,
						  &nct6683_in_template_group,
						  data->in_num);
		if (IS_ERR(group))
			return PTR_ERR(group);
		data->groups[groups++] = group;
	}

	if (data->have_fan) {
		group = nct6683_create_attr_group(dev,
						  &nct6683_fan_template_group,
						  fls(data->have_fan));
		if (IS_ERR(group))
			return PTR_ERR(group);
		data->groups[groups++] = group;
	}

	if (data->temp_num) {
		group = nct6683_create_attr_group(dev,
						  &nct6683_temp_template_group,
						  data->temp_num);
		if (IS_ERR(group))
			return PTR_ERR(group);
		data->groups[groups++] = group;
	}
	data->groups[groups++] = &nct6683_group_other;

	if (data->customer_id == NCT6683_CUSTOMER_ID_INTEL)
		scnprintf(build, sizeof(build), "%02x/%02x/%02x",
			  nct6683_read(data, NCT6683_REG_BUILD_MONTH),
			  nct6683_read(data, NCT6683_REG_BUILD_DAY),
			  nct6683_read(data, NCT6683_REG_BUILD_YEAR));
	else
		scnprintf(build, sizeof(build), "%02d/%02d/%02d",
			  nct6683_read(data, NCT6683_REG_BUILD_MONTH),
			  nct6683_read(data, NCT6683_REG_BUILD_DAY),
			  nct6683_read(data, NCT6683_REG_BUILD_YEAR));

	dev_info(dev, "%s EC firmware version %d.%d build %s\n",
		 nct6683_chip_names[data->kind],
		 nct6683_read(data, NCT6683_REG_VERSION_HI),
		 nct6683_read(data, NCT6683_REG_VERSION_LO),
		 build);

	hwmon_dev = devm_hwmon_device_register_with_groups(dev,
			nct6683_device_names[data->kind], data, data->groups);
	return PTR_ERR_OR_ZERO(hwmon_dev);
}

#ifdef CONFIG_PM
static int nct6683_suspend(struct device *dev)
{
	struct nct6683_data *data = nct6683_update_device(dev);

	mutex_lock(&data->update_lock);
	data->hwm_cfg = nct6683_read(data, NCT6683_HWM_CFG);
	mutex_unlock(&data->update_lock);

	return 0;
}

static int nct6683_resume(struct device *dev)
{
	struct nct6683_data *data = dev_get_drvdata(dev);

	mutex_lock(&data->update_lock);

	nct6683_write(data, NCT6683_HWM_CFG, data->hwm_cfg);

	/* Force re-reading all values */
	data->valid = false;
	mutex_unlock(&data->update_lock);

	return 0;
}

static const struct dev_pm_ops nct6683_dev_pm_ops = {
	.suspend = nct6683_suspend,
	.resume = nct6683_resume,
	.freeze = nct6683_suspend,
	.restore = nct6683_resume,
};

#define NCT6683_DEV_PM_OPS	(&nct6683_dev_pm_ops)
#else
#define NCT6683_DEV_PM_OPS	NULL
#endif /* CONFIG_PM */

static struct platform_driver nct6683_driver = {
	.driver = {
		.name	= DRVNAME,
		.pm	= NCT6683_DEV_PM_OPS,
	},
	.probe		= nct6683_probe,
};

static int __init nct6683_find(int sioaddr, struct nct6683_sio_data *sio_data)
{
	int addr;
	u16 val;
	int err;

	err = superio_enter(sioaddr);
	if (err)
		return err;

	val = (superio_inb(sioaddr, SIO_REG_DEVID) << 8)
	       | superio_inb(sioaddr, SIO_REG_DEVID + 1);

	switch (val & SIO_ID_MASK) {
	case SIO_NCT6683_ID:
		sio_data->kind = nct6683;
		break;
	case SIO_NCT6686_ID:
		sio_data->kind = nct6686;
		break;
	case SIO_NCT6687_ID:
		sio_data->kind = nct6687;
		break;
	default:
		if (val != 0xffff)
			pr_debug("unsupported chip ID: 0x%04x\n", val);
		goto fail;
	}

	/* We have a known chip, find the HWM I/O address */
	superio_select(sioaddr, NCT6683_LD_HWM);
	val = (superio_inb(sioaddr, SIO_REG_ADDR) << 8)
	    | superio_inb(sioaddr, SIO_REG_ADDR + 1);
	addr = val & IOREGION_ALIGNMENT;
	if (addr == 0) {
		pr_err("EC base I/O port unconfigured\n");
		goto fail;
	}

	/* Activate logical device if needed */
	val = superio_inb(sioaddr, SIO_REG_ENABLE);
	if (!(val & 0x01)) {
		pr_warn("Forcibly enabling EC access. Data may be unusable.\n");
		superio_outb(sioaddr, SIO_REG_ENABLE, val | 0x01);
	}

	superio_exit(sioaddr);
	pr_info("Found %s or compatible chip at %#x:%#x\n",
		nct6683_chip_names[sio_data->kind], sioaddr, addr);
	sio_data->sioreg = sioaddr;

	return addr;

fail:
	superio_exit(sioaddr);
	return -ENODEV;
}

/*
 * when Super-I/O functions move to a separate file, the Super-I/O
 * bus will manage the lifetime of the device and this module will only keep
 * track of the nct6683 driver. But since we use platform_device_alloc(), we
 * must keep track of the device
 */
static struct platform_device *pdev[2];

static int __init sensors_nct6683_init(void)
{
	struct nct6683_sio_data sio_data;
	int sioaddr[2] = { 0x2e, 0x4e };
	struct resource res;
	bool found = false;
	int address;
	int i, err;

	err = platform_driver_register(&nct6683_driver);
	if (err)
		return err;

	/*
	 * initialize sio_data->kind and sio_data->sioreg.
	 *
	 * when Super-I/O functions move to a separate file, the Super-I/O
	 * driver will probe 0x2e and 0x4e and auto-detect the presence of a
	 * nct6683 hardware monitor, and call probe()
	 */
	for (i = 0; i < ARRAY_SIZE(pdev); i++) {
		address = nct6683_find(sioaddr[i], &sio_data);
		if (address <= 0)
			continue;

		found = true;

		pdev[i] = platform_device_alloc(DRVNAME, address);
		if (!pdev[i]) {
			err = -ENOMEM;
			goto exit_device_unregister;
		}

		err = platform_device_add_data(pdev[i], &sio_data,
					       sizeof(struct nct6683_sio_data));
		if (err)
			goto exit_device_put;

		memset(&res, 0, sizeof(res));
		res.name = DRVNAME;
		res.start = address + IOREGION_OFFSET;
		res.end = address + IOREGION_OFFSET + IOREGION_LENGTH - 1;
		res.flags = IORESOURCE_IO;

		err = acpi_check_resource_conflict(&res);
		if (err) {
			platform_device_put(pdev[i]);
			pdev[i] = NULL;
			continue;
		}

		err = platform_device_add_resources(pdev[i], &res, 1);
		if (err)
			goto exit_device_put;

		/* platform_device_add calls probe() */
		err = platform_device_add(pdev[i]);
		if (err)
			goto exit_device_put;
	}
	if (!found) {
		err = -ENODEV;
		goto exit_unregister;
	}

	return 0;

exit_device_put:
	platform_device_put(pdev[i]);
exit_device_unregister:
	while (--i >= 0) {
		if (pdev[i])
			platform_device_unregister(pdev[i]);
	}
exit_unregister:
	platform_driver_unregister(&nct6683_driver);
	return err;
}

static void __exit sensors_nct6683_exit(void)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(pdev); i++) {
		if (pdev[i])
			platform_device_unregister(pdev[i]);
	}
	platform_driver_unregister(&nct6683_driver);
}

MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>");
MODULE_DESCRIPTION("NCT6683D driver");
MODULE_LICENSE("GPL");

module_init(sensors_nct6683_init);
module_exit(sensors_nct6683_exit);
