/*
 * nct6683 - Driver for the hardware monitoring functionality of
 *	     Nuvoton NCT6683D eSIO
 *
 * Copyright (C) 2013  Guenter Roeck <linux@roeck-us.net>
 *
 * Derived from nct6775 driver
 * Copyright (C) 2012, 2013  Guenter Roeck <linux@roeck-us.net>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * Supports the following chips:
 *
 * Chip        #vin    #fan    #pwm    #temp  chip ID
 * nct6683d     21(1)   16      8       32(1) 0xc730
 *
 * 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 };

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",
};

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

#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_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_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, j, 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_kzalloc(dev, sizeof(*attrs) * (repeat * count + 1),
			     GFP_KERNEL);
	if (attrs == NULL)
		return ERR_PTR(-ENOMEM);

	su = devm_kzalloc(dev, sizeof(*su) * repeat * count,
			  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;
		for (j = 0; *t != NULL; j++) {
			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 inline u16 in_to_reg(u32 val, 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 clamp_val(DIV_ROUND_CLOSEST(val, scale), 0, 127);
}

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 = container_of(kobj, struct device, 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 = container_of(kobj, struct device, 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 = container_of(kobj, struct device, 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 = container_of(kobj, struct device, 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;
	default:
		if (!force)
			return -ENODEV;
	}

	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;
	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_err("EC is disabled\n");
		goto fail;
	}

	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);
