brintos

brintos / linux-shallow public Read only

0
0
Text · 79.9 KiB · 7c941d3 Raw
2705 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/***************************************************************************3 *   Copyright (C) 2006 by Hans Edgington <hans@edgington.nl>              *4 *   Copyright (C) 2007-2011 Hans de Goede <hdegoede@redhat.com>           *5 *                                                                         *6 ***************************************************************************/7 8#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt9 10#include <linux/module.h>11#include <linux/init.h>12#include <linux/slab.h>13#include <linux/jiffies.h>14#include <linux/platform_device.h>15#include <linux/hwmon.h>16#include <linux/hwmon-sysfs.h>17#include <linux/err.h>18#include <linux/mutex.h>19#include <linux/io.h>20#include <linux/acpi.h>21 22#define DRVNAME "f71882fg"23 24#define SIO_F71858FG_LD_HWM	0x02	/* Hardware monitor logical device */25#define SIO_F71882FG_LD_HWM	0x04	/* Hardware monitor logical device */26#define SIO_UNLOCK_KEY		0x87	/* Key to enable Super-I/O */27#define SIO_LOCK_KEY		0xAA	/* Key to disable Super-I/O */28 29#define SIO_REG_LDSEL		0x07	/* Logical device select */30#define SIO_REG_DEVID		0x20	/* Device ID (2 bytes) */31#define SIO_REG_DEVREV		0x22	/* Device revision */32#define SIO_REG_MANID		0x23	/* Fintek ID (2 bytes) */33#define SIO_REG_ENABLE		0x30	/* Logical device enable */34#define SIO_REG_ADDR		0x60	/* Logical device address (2 bytes) */35 36#define SIO_FINTEK_ID		0x1934	/* Manufacturers ID */37#define SIO_F71808E_ID		0x0901	/* Chipset ID */38#define SIO_F71808A_ID		0x1001	/* Chipset ID */39#define SIO_F71858_ID		0x0507  /* Chipset ID */40#define SIO_F71862_ID		0x0601	/* Chipset ID */41#define SIO_F71868_ID		0x1106	/* Chipset ID */42#define SIO_F71869_ID		0x0814	/* Chipset ID */43#define SIO_F71869A_ID		0x1007	/* Chipset ID */44#define SIO_F71882_ID		0x0541	/* Chipset ID */45#define SIO_F71889_ID		0x0723	/* Chipset ID */46#define SIO_F71889E_ID		0x0909	/* Chipset ID */47#define SIO_F71889A_ID		0x1005	/* Chipset ID */48#define SIO_F8000_ID		0x0581	/* Chipset ID */49#define SIO_F81768D_ID		0x1210	/* Chipset ID */50#define SIO_F81865_ID		0x0704	/* Chipset ID */51#define SIO_F81866_ID		0x1010	/* Chipset ID */52#define SIO_F71858AD_ID		0x0903	/* Chipset ID */53#define SIO_F81966_ID		0x1502	/* Chipset ID */54 55#define REGION_LENGTH		856#define ADDR_REG_OFFSET		557#define DATA_REG_OFFSET		658 59#define F71882FG_REG_IN_STATUS		0x12 /* f7188x only */60#define F71882FG_REG_IN_BEEP		0x13 /* f7188x only */61#define F71882FG_REG_IN(nr)		(0x20  + (nr))62#define F71882FG_REG_IN1_HIGH		0x32 /* f7188x only */63 64#define F81866_REG_IN_STATUS		0x16 /* F81866 only */65#define F81866_REG_IN_BEEP			0x17 /* F81866 only */66#define F81866_REG_IN1_HIGH		0x3a /* F81866 only */67 68#define F71882FG_REG_FAN(nr)		(0xA0 + (16 * (nr)))69#define F71882FG_REG_FAN_TARGET(nr)	(0xA2 + (16 * (nr)))70#define F71882FG_REG_FAN_FULL_SPEED(nr)	(0xA4 + (16 * (nr)))71#define F71882FG_REG_FAN_STATUS		0x9272#define F71882FG_REG_FAN_BEEP		0x9373 74#define F71882FG_REG_TEMP(nr)		(0x70 + 2 * (nr))75#define F71882FG_REG_TEMP_OVT(nr)	(0x80 + 2 * (nr))76#define F71882FG_REG_TEMP_HIGH(nr)	(0x81 + 2 * (nr))77#define F71882FG_REG_TEMP_STATUS	0x6278#define F71882FG_REG_TEMP_BEEP		0x6379#define F71882FG_REG_TEMP_CONFIG	0x6980#define F71882FG_REG_TEMP_HYST(nr)	(0x6C + (nr))81#define F71882FG_REG_TEMP_TYPE		0x6B82#define F71882FG_REG_TEMP_DIODE_OPEN	0x6F83 84#define F71882FG_REG_PWM(nr)		(0xA3 + (16 * (nr)))85#define F71882FG_REG_PWM_TYPE		0x9486#define F71882FG_REG_PWM_ENABLE		0x9687 88#define F71882FG_REG_FAN_HYST(nr)	(0x98 + (nr))89 90#define F71882FG_REG_FAN_FAULT_T	0x9F91#define F71882FG_FAN_NEG_TEMP_EN	0x2092#define F71882FG_FAN_PROG_SEL		0x8093 94#define F71882FG_REG_POINT_PWM(pwm, point)	(0xAA + (point) + (16 * (pwm)))95#define F71882FG_REG_POINT_TEMP(pwm, point)	(0xA6 + (point) + (16 * (pwm)))96#define F71882FG_REG_POINT_MAPPING(nr)		(0xAF + 16 * (nr))97 98#define	F71882FG_REG_START		0x0199 100#define F71882FG_MAX_INS		11101 102#define FAN_MIN_DETECT			366 /* Lowest detectable fanspeed */103 104static unsigned short force_id;105module_param(force_id, ushort, 0);106MODULE_PARM_DESC(force_id, "Override the detected device ID");107 108enum chips { f71808e, f71808a, f71858fg, f71862fg, f71868a, f71869, f71869a,109	f71882fg, f71889fg, f71889ed, f71889a, f8000, f81768d, f81865f,110	f81866a};111 112static const char *const f71882fg_names[] = {113	"f71808e",114	"f71808a",115	"f71858fg",116	"f71862fg",117	"f71868a",118	"f71869", /* Both f71869f and f71869e, reg. compatible and same id */119	"f71869a",120	"f71882fg",121	"f71889fg", /* f81801u too, same id */122	"f71889ed",123	"f71889a",124	"f8000",125	"f81768d",126	"f81865f",127	"f81866a",128};129 130static const char f71882fg_has_in[][F71882FG_MAX_INS] = {131	[f71808e]	= { 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0 },132	[f71808a]	= { 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0 },133	[f71858fg]	= { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 },134	[f71862fg]	= { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 },135	[f71868a]	= { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 },136	[f71869]	= { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 },137	[f71869a]	= { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 },138	[f71882fg]	= { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 },139	[f71889fg]	= { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 },140	[f71889ed]	= { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 },141	[f71889a]	= { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 },142	[f8000]		= { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 },143	[f81768d]	= { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },144	[f81865f]	= { 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0 },145	[f81866a]	= { 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 },146};147 148static const char f71882fg_has_in1_alarm[] = {149	[f71808e]	= 0,150	[f71808a]	= 0,151	[f71858fg]	= 0,152	[f71862fg]	= 0,153	[f71868a]	= 0,154	[f71869]	= 0,155	[f71869a]	= 0,156	[f71882fg]	= 1,157	[f71889fg]	= 1,158	[f71889ed]	= 1,159	[f71889a]	= 1,160	[f8000]		= 0,161	[f81768d]	= 1,162	[f81865f]	= 1,163	[f81866a]	= 1,164};165 166static const char f71882fg_fan_has_beep[] = {167	[f71808e]	= 0,168	[f71808a]	= 0,169	[f71858fg]	= 0,170	[f71862fg]	= 1,171	[f71868a]	= 1,172	[f71869]	= 1,173	[f71869a]	= 1,174	[f71882fg]	= 1,175	[f71889fg]	= 1,176	[f71889ed]	= 1,177	[f71889a]	= 1,178	[f8000]		= 0,179	[f81768d]	= 1,180	[f81865f]	= 1,181	[f81866a]	= 1,182};183 184static const char f71882fg_nr_fans[] = {185	[f71808e]	= 3,186	[f71808a]	= 2, /* +1 fan which is monitor + simple pwm only */187	[f71858fg]	= 3,188	[f71862fg]	= 3,189	[f71868a]	= 3,190	[f71869]	= 3,191	[f71869a]	= 3,192	[f71882fg]	= 4,193	[f71889fg]	= 3,194	[f71889ed]	= 3,195	[f71889a]	= 3,196	[f8000]		= 3, /* +1 fan which is monitor only */197	[f81768d]	= 3,198	[f81865f]	= 2,199	[f81866a]	= 3,200};201 202static const char f71882fg_temp_has_beep[] = {203	[f71808e]	= 0,204	[f71808a]	= 1,205	[f71858fg]	= 0,206	[f71862fg]	= 1,207	[f71868a]	= 1,208	[f71869]	= 1,209	[f71869a]	= 1,210	[f71882fg]	= 1,211	[f71889fg]	= 1,212	[f71889ed]	= 1,213	[f71889a]	= 1,214	[f8000]		= 0,215	[f81768d]	= 1,216	[f81865f]	= 1,217	[f81866a]	= 1,218};219 220static const char f71882fg_nr_temps[] = {221	[f71808e]	= 2,222	[f71808a]	= 2,223	[f71858fg]	= 3,224	[f71862fg]	= 3,225	[f71868a]	= 3,226	[f71869]	= 3,227	[f71869a]	= 3,228	[f71882fg]	= 3,229	[f71889fg]	= 3,230	[f71889ed]	= 3,231	[f71889a]	= 3,232	[f8000]		= 3,233	[f81768d]	= 3,234	[f81865f]	= 2,235	[f81866a]	= 3,236};237 238static struct platform_device *f71882fg_pdev;239 240struct f71882fg_sio_data {241	enum chips type;242};243 244struct f71882fg_data {245	unsigned short addr;246	enum chips type;247	struct device *hwmon_dev;248 249	struct mutex update_lock;250	int temp_start;			/* temp numbering start (0 or 1) */251	bool valid;			/* true if following fields are valid */252	char auto_point_temp_signed;253	unsigned long last_updated;	/* In jiffies */254	unsigned long last_limits;	/* In jiffies */255 256	/* Register Values */257	u8	in[F71882FG_MAX_INS];258	u8	in1_max;259	u8	in_status;260	u8	in_beep;261	u16	fan[4];262	u16	fan_target[4];263	u16	fan_full_speed[4];264	u8	fan_status;265	u8	fan_beep;266	/*267	 * Note: all models have max 3 temperature channels, but on some268	 * they are addressed as 0-2 and on others as 1-3, so for coding269	 * convenience we reserve space for 4 channels270	 */271	u16	temp[4];272	u8	temp_ovt[4];273	u8	temp_high[4];274	u8	temp_hyst[2]; /* 2 hysts stored per reg */275	u8	temp_type[4];276	u8	temp_status;277	u8	temp_beep;278	u8	temp_diode_open;279	u8	temp_config;280	u8	pwm[4];281	u8	pwm_enable;282	u8	pwm_auto_point_hyst[2];283	u8	pwm_auto_point_mapping[4];284	u8	pwm_auto_point_pwm[4][5];285	s8	pwm_auto_point_temp[4][4];286};287 288static u8 f71882fg_read8(struct f71882fg_data *data, u8 reg)289{290	u8 val;291 292	outb(reg, data->addr + ADDR_REG_OFFSET);293	val = inb(data->addr + DATA_REG_OFFSET);294 295	return val;296}297 298static u16 f71882fg_read16(struct f71882fg_data *data, u8 reg)299{300	u16 val;301 302	val  = f71882fg_read8(data, reg) << 8;303	val |= f71882fg_read8(data, reg + 1);304 305	return val;306}307 308static inline int fan_from_reg(u16 reg)309{310	return reg ? (1500000 / reg) : 0;311}312 313static inline u16 fan_to_reg(int fan)314{315	return fan ? (1500000 / fan) : 0;316}317 318static void f71882fg_write8(struct f71882fg_data *data, u8 reg, u8 val)319{320	outb(reg, data->addr + ADDR_REG_OFFSET);321	outb(val, data->addr + DATA_REG_OFFSET);322}323 324static void f71882fg_write16(struct f71882fg_data *data, u8 reg, u16 val)325{326	f71882fg_write8(data, reg,     val >> 8);327	f71882fg_write8(data, reg + 1, val & 0xff);328}329 330static u16 f71882fg_read_temp(struct f71882fg_data *data, int nr)331{332	if (data->type == f71858fg)333		return f71882fg_read16(data, F71882FG_REG_TEMP(nr));334	else335		return f71882fg_read8(data, F71882FG_REG_TEMP(nr));336}337 338static struct f71882fg_data *f71882fg_update_device(struct device *dev)339{340	struct f71882fg_data *data = dev_get_drvdata(dev);341	int nr_fans = f71882fg_nr_fans[data->type];342	int nr_temps = f71882fg_nr_temps[data->type];343	int nr, reg, point;344 345	mutex_lock(&data->update_lock);346 347	/* Update once every 60 seconds */348	if (time_after(jiffies, data->last_limits + 60 * HZ) ||349			!data->valid) {350		if (f71882fg_has_in1_alarm[data->type]) {351			if (data->type == f81866a) {352				data->in1_max =353					f71882fg_read8(data,354						       F81866_REG_IN1_HIGH);355				data->in_beep =356					f71882fg_read8(data,357						       F81866_REG_IN_BEEP);358			} else {359				data->in1_max =360					f71882fg_read8(data,361						       F71882FG_REG_IN1_HIGH);362				data->in_beep =363					f71882fg_read8(data,364						       F71882FG_REG_IN_BEEP);365			}366		}367 368		/* Get High & boundary temps*/369		for (nr = data->temp_start; nr < nr_temps + data->temp_start;370									nr++) {371			data->temp_ovt[nr] = f71882fg_read8(data,372						F71882FG_REG_TEMP_OVT(nr));373			data->temp_high[nr] = f71882fg_read8(data,374						F71882FG_REG_TEMP_HIGH(nr));375		}376 377		if (data->type != f8000) {378			data->temp_hyst[0] = f71882fg_read8(data,379						F71882FG_REG_TEMP_HYST(0));380			data->temp_hyst[1] = f71882fg_read8(data,381						F71882FG_REG_TEMP_HYST(1));382		}383		/* All but the f71858fg / f8000 have this register */384		if ((data->type != f71858fg) && (data->type != f8000)) {385			reg  = f71882fg_read8(data, F71882FG_REG_TEMP_TYPE);386			data->temp_type[1] = (reg & 0x02) ? 2 : 4;387			data->temp_type[2] = (reg & 0x04) ? 2 : 4;388			data->temp_type[3] = (reg & 0x08) ? 2 : 4;389		}390 391		if (f71882fg_fan_has_beep[data->type])392			data->fan_beep = f71882fg_read8(data,393						F71882FG_REG_FAN_BEEP);394 395		if (f71882fg_temp_has_beep[data->type])396			data->temp_beep = f71882fg_read8(data,397						F71882FG_REG_TEMP_BEEP);398 399		data->pwm_enable = f71882fg_read8(data,400						  F71882FG_REG_PWM_ENABLE);401		data->pwm_auto_point_hyst[0] =402			f71882fg_read8(data, F71882FG_REG_FAN_HYST(0));403		data->pwm_auto_point_hyst[1] =404			f71882fg_read8(data, F71882FG_REG_FAN_HYST(1));405 406		for (nr = 0; nr < nr_fans; nr++) {407			data->pwm_auto_point_mapping[nr] =408			    f71882fg_read8(data,409					   F71882FG_REG_POINT_MAPPING(nr));410 411			switch (data->type) {412			default:413				for (point = 0; point < 5; point++) {414					data->pwm_auto_point_pwm[nr][point] =415						f71882fg_read8(data,416							F71882FG_REG_POINT_PWM417							(nr, point));418				}419				for (point = 0; point < 4; point++) {420					data->pwm_auto_point_temp[nr][point] =421						f71882fg_read8(data,422							F71882FG_REG_POINT_TEMP423							(nr, point));424				}425				break;426			case f71808e:427			case f71869:428				data->pwm_auto_point_pwm[nr][0] =429					f71882fg_read8(data,430						F71882FG_REG_POINT_PWM(nr, 0));431				fallthrough;432			case f71862fg:433				data->pwm_auto_point_pwm[nr][1] =434					f71882fg_read8(data,435						F71882FG_REG_POINT_PWM436						(nr, 1));437				data->pwm_auto_point_pwm[nr][4] =438					f71882fg_read8(data,439						F71882FG_REG_POINT_PWM440						(nr, 4));441				data->pwm_auto_point_temp[nr][0] =442					f71882fg_read8(data,443						F71882FG_REG_POINT_TEMP444						(nr, 0));445				data->pwm_auto_point_temp[nr][3] =446					f71882fg_read8(data,447						F71882FG_REG_POINT_TEMP448						(nr, 3));449				break;450			}451		}452		data->last_limits = jiffies;453	}454 455	/* Update every second */456	if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {457		data->temp_status = f71882fg_read8(data,458						F71882FG_REG_TEMP_STATUS);459		data->temp_diode_open = f71882fg_read8(data,460						F71882FG_REG_TEMP_DIODE_OPEN);461		for (nr = data->temp_start; nr < nr_temps + data->temp_start;462									nr++)463			data->temp[nr] = f71882fg_read_temp(data, nr);464 465		data->fan_status = f71882fg_read8(data,466						F71882FG_REG_FAN_STATUS);467		for (nr = 0; nr < nr_fans; nr++) {468			data->fan[nr] = f71882fg_read16(data,469						F71882FG_REG_FAN(nr));470			data->fan_target[nr] =471			    f71882fg_read16(data, F71882FG_REG_FAN_TARGET(nr));472			data->fan_full_speed[nr] =473			    f71882fg_read16(data,474					    F71882FG_REG_FAN_FULL_SPEED(nr));475			data->pwm[nr] =476			    f71882fg_read8(data, F71882FG_REG_PWM(nr));477		}478		/* Some models have 1 more fan with limited capabilities */479		if (data->type == f71808a) {480			data->fan[2] = f71882fg_read16(data,481						F71882FG_REG_FAN(2));482			data->pwm[2] = f71882fg_read8(data,483							F71882FG_REG_PWM(2));484		}485		if (data->type == f8000)486			data->fan[3] = f71882fg_read16(data,487						F71882FG_REG_FAN(3));488 489		if (f71882fg_has_in1_alarm[data->type]) {490			if (data->type == f81866a)491				data->in_status = f71882fg_read8(data,492						F81866_REG_IN_STATUS);493 494			else495				data->in_status = f71882fg_read8(data,496						F71882FG_REG_IN_STATUS);497		}498 499		for (nr = 0; nr < F71882FG_MAX_INS; nr++)500			if (f71882fg_has_in[data->type][nr])501				data->in[nr] = f71882fg_read8(data,502							F71882FG_REG_IN(nr));503 504		data->last_updated = jiffies;505		data->valid = true;506	}507 508	mutex_unlock(&data->update_lock);509 510	return data;511}512 513static ssize_t name_show(struct device *dev, struct device_attribute *devattr,514	char *buf)515{516	struct f71882fg_data *data = dev_get_drvdata(dev);517	return sprintf(buf, "%s\n", f71882fg_names[data->type]);518}519 520static DEVICE_ATTR_RO(name);521 522static ssize_t show_temp(struct device *dev, struct device_attribute *devattr,523	char *buf)524{525	struct f71882fg_data *data = f71882fg_update_device(dev);526	int nr = to_sensor_dev_attr_2(devattr)->index;527	int sign, temp;528 529	if (data->type == f71858fg) {530		/* TEMP_TABLE_SEL 1 or 3 ? */531		if (data->temp_config & 1) {532			sign = data->temp[nr] & 0x0001;533			temp = (data->temp[nr] >> 5) & 0x7ff;534		} else {535			sign = data->temp[nr] & 0x8000;536			temp = (data->temp[nr] >> 5) & 0x3ff;537		}538		temp *= 125;539		if (sign)540			temp -= 128000;541	} else {542		temp = ((s8)data->temp[nr]) * 1000;543	}544 545	return sprintf(buf, "%d\n", temp);546}547 548static ssize_t show_temp_max(struct device *dev, struct device_attribute549	*devattr, char *buf)550{551	struct f71882fg_data *data = f71882fg_update_device(dev);552	int nr = to_sensor_dev_attr_2(devattr)->index;553 554	return sprintf(buf, "%d\n", data->temp_high[nr] * 1000);555}556 557static ssize_t store_temp_max(struct device *dev, struct device_attribute558	*devattr, const char *buf, size_t count)559{560	struct f71882fg_data *data = dev_get_drvdata(dev);561	int err, nr = to_sensor_dev_attr_2(devattr)->index;562	long val;563 564	err = kstrtol(buf, 10, &val);565	if (err)566		return err;567 568	val /= 1000;569	val = clamp_val(val, 0, 255);570 571	mutex_lock(&data->update_lock);572	f71882fg_write8(data, F71882FG_REG_TEMP_HIGH(nr), val);573	data->temp_high[nr] = val;574	mutex_unlock(&data->update_lock);575 576	return count;577}578 579static ssize_t show_temp_max_hyst(struct device *dev, struct device_attribute580	*devattr, char *buf)581{582	struct f71882fg_data *data = f71882fg_update_device(dev);583	int nr = to_sensor_dev_attr_2(devattr)->index;584	int temp_max_hyst;585 586	mutex_lock(&data->update_lock);587	if (nr & 1)588		temp_max_hyst = data->temp_hyst[nr / 2] >> 4;589	else590		temp_max_hyst = data->temp_hyst[nr / 2] & 0x0f;591	temp_max_hyst = (data->temp_high[nr] - temp_max_hyst) * 1000;592	mutex_unlock(&data->update_lock);593 594	return sprintf(buf, "%d\n", temp_max_hyst);595}596 597static ssize_t store_temp_max_hyst(struct device *dev, struct device_attribute598	*devattr, const char *buf, size_t count)599{600	struct f71882fg_data *data = dev_get_drvdata(dev);601	int err, nr = to_sensor_dev_attr_2(devattr)->index;602	ssize_t ret = count;603	u8 reg;604	long val;605 606	err = kstrtol(buf, 10, &val);607	if (err)608		return err;609 610	val /= 1000;611 612	mutex_lock(&data->update_lock);613 614	/* convert abs to relative and check */615	data->temp_high[nr] = f71882fg_read8(data, F71882FG_REG_TEMP_HIGH(nr));616	val = clamp_val(val, data->temp_high[nr] - 15, data->temp_high[nr]);617	val = data->temp_high[nr] - val;618 619	/* convert value to register contents */620	reg = f71882fg_read8(data, F71882FG_REG_TEMP_HYST(nr / 2));621	if (nr & 1)622		reg = (reg & 0x0f) | (val << 4);623	else624		reg = (reg & 0xf0) | val;625	f71882fg_write8(data, F71882FG_REG_TEMP_HYST(nr / 2), reg);626	data->temp_hyst[nr / 2] = reg;627 628	mutex_unlock(&data->update_lock);629	return ret;630}631 632static ssize_t show_temp_alarm(struct device *dev, struct device_attribute633	*devattr, char *buf)634{635	struct f71882fg_data *data = f71882fg_update_device(dev);636	int nr = to_sensor_dev_attr_2(devattr)->index;637 638	if (data->temp_status & (1 << nr))639		return sprintf(buf, "1\n");640	else641		return sprintf(buf, "0\n");642}643 644static ssize_t show_temp_crit(struct device *dev, struct device_attribute645	*devattr, char *buf)646{647	struct f71882fg_data *data = f71882fg_update_device(dev);648	int nr = to_sensor_dev_attr_2(devattr)->index;649 650	return sprintf(buf, "%d\n", data->temp_ovt[nr] * 1000);651}652 653static ssize_t store_temp_crit(struct device *dev, struct device_attribute654	*devattr, const char *buf, size_t count)655{656	struct f71882fg_data *data = dev_get_drvdata(dev);657	int err, nr = to_sensor_dev_attr_2(devattr)->index;658	long val;659 660	err = kstrtol(buf, 10, &val);661	if (err)662		return err;663 664	val /= 1000;665	val = clamp_val(val, 0, 255);666 667	mutex_lock(&data->update_lock);668	f71882fg_write8(data, F71882FG_REG_TEMP_OVT(nr), val);669	data->temp_ovt[nr] = val;670	mutex_unlock(&data->update_lock);671 672	return count;673}674 675static ssize_t show_temp_crit_hyst(struct device *dev, struct device_attribute676	*devattr, char *buf)677{678	struct f71882fg_data *data = f71882fg_update_device(dev);679	int nr = to_sensor_dev_attr_2(devattr)->index;680	int temp_crit_hyst;681 682	mutex_lock(&data->update_lock);683	if (nr & 1)684		temp_crit_hyst = data->temp_hyst[nr / 2] >> 4;685	else686		temp_crit_hyst = data->temp_hyst[nr / 2] & 0x0f;687	temp_crit_hyst = (data->temp_ovt[nr] - temp_crit_hyst) * 1000;688	mutex_unlock(&data->update_lock);689 690	return sprintf(buf, "%d\n", temp_crit_hyst);691}692 693static ssize_t show_temp_fault(struct device *dev, struct device_attribute694	*devattr, char *buf)695{696	struct f71882fg_data *data = f71882fg_update_device(dev);697	int nr = to_sensor_dev_attr_2(devattr)->index;698 699	if (data->temp_diode_open & (1 << nr))700		return sprintf(buf, "1\n");701	else702		return sprintf(buf, "0\n");703}704 705/*706 * Temp attr for the f71858fg, the f71858fg is special as it has its707 * temperature indexes start at 0 (the others start at 1)708 */709static struct sensor_device_attribute_2 f71858fg_temp_attr[] = {710	SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0),711	SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_max,712		store_temp_max, 0, 0),713	SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,714		store_temp_max_hyst, 0, 0),715	SENSOR_ATTR_2(temp1_max_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 0),716	SENSOR_ATTR_2(temp1_crit, S_IRUGO|S_IWUSR, show_temp_crit,717		store_temp_crit, 0, 0),718	SENSOR_ATTR_2(temp1_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,719		0, 0),720	SENSOR_ATTR_2(temp1_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 4),721	SENSOR_ATTR_2(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0, 0),722	SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 1),723	SENSOR_ATTR_2(temp2_max, S_IRUGO|S_IWUSR, show_temp_max,724		store_temp_max, 0, 1),725	SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,726		store_temp_max_hyst, 0, 1),727	SENSOR_ATTR_2(temp2_max_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 1),728	SENSOR_ATTR_2(temp2_crit, S_IRUGO|S_IWUSR, show_temp_crit,729		store_temp_crit, 0, 1),730	SENSOR_ATTR_2(temp2_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,731		0, 1),732	SENSOR_ATTR_2(temp2_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 5),733	SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 1),734	SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 2),735	SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_max,736		store_temp_max, 0, 2),737	SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,738		store_temp_max_hyst, 0, 2),739	SENSOR_ATTR_2(temp3_max_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 2),740	SENSOR_ATTR_2(temp3_crit, S_IRUGO|S_IWUSR, show_temp_crit,741		store_temp_crit, 0, 2),742	SENSOR_ATTR_2(temp3_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,743		0, 2),744	SENSOR_ATTR_2(temp3_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 6),745	SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 2),746};747 748static ssize_t show_temp_type(struct device *dev, struct device_attribute749	*devattr, char *buf)750{751	struct f71882fg_data *data = f71882fg_update_device(dev);752	int nr = to_sensor_dev_attr_2(devattr)->index;753 754	return sprintf(buf, "%d\n", data->temp_type[nr]);755}756 757/* Temp attr for the standard models */758static struct sensor_device_attribute_2 fxxxx_temp_attr[3][9] = { {759	SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 1),760	SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_max,761		store_temp_max, 0, 1),762	SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,763		store_temp_max_hyst, 0, 1),764	/*765	 * Should really be temp1_max_alarm, but older versions did not handle766	 * the max and crit alarms separately and lm_sensors v2 depends on the767	 * presence of temp#_alarm files. The same goes for temp2/3 _alarm.768	 */769	SENSOR_ATTR_2(temp1_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 1),770	SENSOR_ATTR_2(temp1_crit, S_IRUGO|S_IWUSR, show_temp_crit,771		store_temp_crit, 0, 1),772	SENSOR_ATTR_2(temp1_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,773		0, 1),774	SENSOR_ATTR_2(temp1_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 5),775	SENSOR_ATTR_2(temp1_type, S_IRUGO, show_temp_type, NULL, 0, 1),776	SENSOR_ATTR_2(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0, 1),777}, {778	SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 2),779	SENSOR_ATTR_2(temp2_max, S_IRUGO|S_IWUSR, show_temp_max,780		store_temp_max, 0, 2),781	SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,782		store_temp_max_hyst, 0, 2),783	/* Should be temp2_max_alarm, see temp1_alarm note */784	SENSOR_ATTR_2(temp2_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 2),785	SENSOR_ATTR_2(temp2_crit, S_IRUGO|S_IWUSR, show_temp_crit,786		store_temp_crit, 0, 2),787	SENSOR_ATTR_2(temp2_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,788		0, 2),789	SENSOR_ATTR_2(temp2_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 6),790	SENSOR_ATTR_2(temp2_type, S_IRUGO, show_temp_type, NULL, 0, 2),791	SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 2),792}, {793	SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 3),794	SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_max,795		store_temp_max, 0, 3),796	SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,797		store_temp_max_hyst, 0, 3),798	/* Should be temp3_max_alarm, see temp1_alarm note */799	SENSOR_ATTR_2(temp3_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 3),800	SENSOR_ATTR_2(temp3_crit, S_IRUGO|S_IWUSR, show_temp_crit,801		store_temp_crit, 0, 3),802	SENSOR_ATTR_2(temp3_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,803		0, 3),804	SENSOR_ATTR_2(temp3_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 7),805	SENSOR_ATTR_2(temp3_type, S_IRUGO, show_temp_type, NULL, 0, 3),806	SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 3),807} };808 809static ssize_t show_temp_beep(struct device *dev, struct device_attribute810	*devattr, char *buf)811{812	struct f71882fg_data *data = f71882fg_update_device(dev);813	int nr = to_sensor_dev_attr_2(devattr)->index;814 815	if (data->temp_beep & (1 << nr))816		return sprintf(buf, "1\n");817	else818		return sprintf(buf, "0\n");819}820 821static ssize_t store_temp_beep(struct device *dev, struct device_attribute822	*devattr, const char *buf, size_t count)823{824	struct f71882fg_data *data = dev_get_drvdata(dev);825	int err, nr = to_sensor_dev_attr_2(devattr)->index;826	unsigned long val;827 828	err = kstrtoul(buf, 10, &val);829	if (err)830		return err;831 832	mutex_lock(&data->update_lock);833	data->temp_beep = f71882fg_read8(data, F71882FG_REG_TEMP_BEEP);834	if (val)835		data->temp_beep |= 1 << nr;836	else837		data->temp_beep &= ~(1 << nr);838 839	f71882fg_write8(data, F71882FG_REG_TEMP_BEEP, data->temp_beep);840	mutex_unlock(&data->update_lock);841 842	return count;843}844 845/* Temp attr for models which can beep on temp alarm */846static struct sensor_device_attribute_2 fxxxx_temp_beep_attr[3][2] = { {847	SENSOR_ATTR_2(temp1_max_beep, S_IRUGO|S_IWUSR, show_temp_beep,848		store_temp_beep, 0, 1),849	SENSOR_ATTR_2(temp1_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep,850		store_temp_beep, 0, 5),851}, {852	SENSOR_ATTR_2(temp2_max_beep, S_IRUGO|S_IWUSR, show_temp_beep,853		store_temp_beep, 0, 2),854	SENSOR_ATTR_2(temp2_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep,855		store_temp_beep, 0, 6),856}, {857	SENSOR_ATTR_2(temp3_max_beep, S_IRUGO|S_IWUSR, show_temp_beep,858		store_temp_beep, 0, 3),859	SENSOR_ATTR_2(temp3_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep,860		store_temp_beep, 0, 7),861} };862 863static struct sensor_device_attribute_2 f81866_temp_beep_attr[3][2] = { {864	SENSOR_ATTR_2(temp1_max_beep, S_IRUGO|S_IWUSR, show_temp_beep,865		store_temp_beep, 0, 0),866	SENSOR_ATTR_2(temp1_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep,867		store_temp_beep, 0, 4),868}, {869	SENSOR_ATTR_2(temp2_max_beep, S_IRUGO|S_IWUSR, show_temp_beep,870		store_temp_beep, 0, 1),871	SENSOR_ATTR_2(temp2_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep,872		store_temp_beep, 0, 5),873}, {874	SENSOR_ATTR_2(temp3_max_beep, S_IRUGO|S_IWUSR, show_temp_beep,875		store_temp_beep, 0, 2),876	SENSOR_ATTR_2(temp3_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep,877		store_temp_beep, 0, 6),878} };879 880/*881 * Temp attr for the f8000882 * Note on the f8000 temp_ovt (crit) is used as max, and temp_high (max)883 * is used as hysteresis value to clear alarms884 * Also like the f71858fg its temperature indexes start at 0885 */886static struct sensor_device_attribute_2 f8000_temp_attr[] = {887	SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0),888	SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_crit,889		store_temp_crit, 0, 0),890	SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO|S_IWUSR, show_temp_max,891		store_temp_max, 0, 0),892	SENSOR_ATTR_2(temp1_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 4),893	SENSOR_ATTR_2(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0, 0),894	SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 1),895	SENSOR_ATTR_2(temp2_max, S_IRUGO|S_IWUSR, show_temp_crit,896		store_temp_crit, 0, 1),897	SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO|S_IWUSR, show_temp_max,898		store_temp_max, 0, 1),899	SENSOR_ATTR_2(temp2_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 5),900	SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 1),901	SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 2),902	SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_crit,903		store_temp_crit, 0, 2),904	SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO|S_IWUSR, show_temp_max,905		store_temp_max, 0, 2),906	SENSOR_ATTR_2(temp3_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 6),907	SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 2),908};909 910static ssize_t show_in(struct device *dev, struct device_attribute *devattr,911	char *buf)912{913	struct f71882fg_data *data = f71882fg_update_device(dev);914	int nr = to_sensor_dev_attr_2(devattr)->index;915 916	return sprintf(buf, "%d\n", data->in[nr] * 8);917}918 919/* in attr for all models */920static struct sensor_device_attribute_2 fxxxx_in_attr[] = {921	SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),922	SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1),923	SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2),924	SENSOR_ATTR_2(in3_input, S_IRUGO, show_in, NULL, 0, 3),925	SENSOR_ATTR_2(in4_input, S_IRUGO, show_in, NULL, 0, 4),926	SENSOR_ATTR_2(in5_input, S_IRUGO, show_in, NULL, 0, 5),927	SENSOR_ATTR_2(in6_input, S_IRUGO, show_in, NULL, 0, 6),928	SENSOR_ATTR_2(in7_input, S_IRUGO, show_in, NULL, 0, 7),929	SENSOR_ATTR_2(in8_input, S_IRUGO, show_in, NULL, 0, 8),930	SENSOR_ATTR_2(in9_input, S_IRUGO, show_in, NULL, 0, 9),931	SENSOR_ATTR_2(in10_input, S_IRUGO, show_in, NULL, 0, 10),932};933 934static ssize_t show_in_max(struct device *dev, struct device_attribute935	*devattr, char *buf)936{937	struct f71882fg_data *data = f71882fg_update_device(dev);938 939	return sprintf(buf, "%d\n", data->in1_max * 8);940}941 942static ssize_t store_in_max(struct device *dev, struct device_attribute943	*devattr, const char *buf, size_t count)944{945	struct f71882fg_data *data = dev_get_drvdata(dev);946	int err;947	long val;948 949	err = kstrtol(buf, 10, &val);950	if (err)951		return err;952 953	val /= 8;954	val = clamp_val(val, 0, 255);955 956	mutex_lock(&data->update_lock);957	if (data->type == f81866a)958		f71882fg_write8(data, F81866_REG_IN1_HIGH, val);959	else960		f71882fg_write8(data, F71882FG_REG_IN1_HIGH, val);961	data->in1_max = val;962	mutex_unlock(&data->update_lock);963 964	return count;965}966 967static ssize_t show_in_beep(struct device *dev, struct device_attribute968	*devattr, char *buf)969{970	struct f71882fg_data *data = f71882fg_update_device(dev);971	int nr = to_sensor_dev_attr_2(devattr)->index;972 973	if (data->in_beep & (1 << nr))974		return sprintf(buf, "1\n");975	else976		return sprintf(buf, "0\n");977}978 979static ssize_t store_in_beep(struct device *dev, struct device_attribute980	*devattr, const char *buf, size_t count)981{982	struct f71882fg_data *data = dev_get_drvdata(dev);983	int err, nr = to_sensor_dev_attr_2(devattr)->index;984	unsigned long val;985 986	err = kstrtoul(buf, 10, &val);987	if (err)988		return err;989 990	mutex_lock(&data->update_lock);991	if (data->type == f81866a)992		data->in_beep = f71882fg_read8(data, F81866_REG_IN_BEEP);993	else994		data->in_beep = f71882fg_read8(data, F71882FG_REG_IN_BEEP);995 996	if (val)997		data->in_beep |= 1 << nr;998	else999		data->in_beep &= ~(1 << nr);1000 1001	if (data->type == f81866a)1002		f71882fg_write8(data, F81866_REG_IN_BEEP, data->in_beep);1003	else1004		f71882fg_write8(data, F71882FG_REG_IN_BEEP, data->in_beep);1005	mutex_unlock(&data->update_lock);1006 1007	return count;1008}1009 1010static ssize_t show_in_alarm(struct device *dev, struct device_attribute1011	*devattr, char *buf)1012{1013	struct f71882fg_data *data = f71882fg_update_device(dev);1014	int nr = to_sensor_dev_attr_2(devattr)->index;1015 1016	if (data->in_status & (1 << nr))1017		return sprintf(buf, "1\n");1018	else1019		return sprintf(buf, "0\n");1020}1021 1022/* For models with in1 alarm capability */1023static struct sensor_device_attribute_2 fxxxx_in1_alarm_attr[] = {1024	SENSOR_ATTR_2(in1_max, S_IRUGO|S_IWUSR, show_in_max, store_in_max,1025		0, 1),1026	SENSOR_ATTR_2(in1_beep, S_IRUGO|S_IWUSR, show_in_beep, store_in_beep,1027		0, 1),1028	SENSOR_ATTR_2(in1_alarm, S_IRUGO, show_in_alarm, NULL, 0, 1),1029};1030 1031static ssize_t show_fan(struct device *dev, struct device_attribute *devattr,1032	char *buf)1033{1034	struct f71882fg_data *data = f71882fg_update_device(dev);1035	int nr = to_sensor_dev_attr_2(devattr)->index;1036	int speed = fan_from_reg(data->fan[nr]);1037 1038	if (speed == FAN_MIN_DETECT)1039		speed = 0;1040 1041	return sprintf(buf, "%d\n", speed);1042}1043 1044static ssize_t show_fan_full_speed(struct device *dev,1045				   struct device_attribute *devattr, char *buf)1046{1047	struct f71882fg_data *data = f71882fg_update_device(dev);1048	int nr = to_sensor_dev_attr_2(devattr)->index;1049	int speed = fan_from_reg(data->fan_full_speed[nr]);1050	return sprintf(buf, "%d\n", speed);1051}1052 1053static ssize_t store_fan_full_speed(struct device *dev,1054				    struct device_attribute *devattr,1055				    const char *buf, size_t count)1056{1057	struct f71882fg_data *data = dev_get_drvdata(dev);1058	int err, nr = to_sensor_dev_attr_2(devattr)->index;1059	long val;1060 1061	err = kstrtol(buf, 10, &val);1062	if (err)1063		return err;1064 1065	val = clamp_val(val, 23, 1500000);1066	val = fan_to_reg(val);1067 1068	mutex_lock(&data->update_lock);1069	f71882fg_write16(data, F71882FG_REG_FAN_FULL_SPEED(nr), val);1070	data->fan_full_speed[nr] = val;1071	mutex_unlock(&data->update_lock);1072 1073	return count;1074}1075 1076static ssize_t show_fan_alarm(struct device *dev, struct device_attribute1077	*devattr, char *buf)1078{1079	struct f71882fg_data *data = f71882fg_update_device(dev);1080	int nr = to_sensor_dev_attr_2(devattr)->index;1081 1082	if (data->fan_status & (1 << nr))1083		return sprintf(buf, "1\n");1084	else1085		return sprintf(buf, "0\n");1086}1087 1088static ssize_t show_pwm(struct device *dev,1089			struct device_attribute *devattr, char *buf)1090{1091	struct f71882fg_data *data = f71882fg_update_device(dev);1092	int val, nr = to_sensor_dev_attr_2(devattr)->index;1093	mutex_lock(&data->update_lock);1094	if (data->pwm_enable & (1 << (2 * nr)))1095		/* PWM mode */1096		val = data->pwm[nr];1097	else {1098		/* RPM mode */1099		if (fan_from_reg(data->fan_full_speed[nr]))1100			val = 255 * fan_from_reg(data->fan_target[nr])1101				/ fan_from_reg(data->fan_full_speed[nr]);1102		else1103			val = 0;1104	}1105	mutex_unlock(&data->update_lock);1106	return sprintf(buf, "%d\n", val);1107}1108 1109static ssize_t store_pwm(struct device *dev,1110			 struct device_attribute *devattr, const char *buf,1111			 size_t count)1112{1113	struct f71882fg_data *data = dev_get_drvdata(dev);1114	int err, nr = to_sensor_dev_attr_2(devattr)->index;1115	long val;1116 1117	err = kstrtol(buf, 10, &val);1118	if (err)1119		return err;1120 1121	val = clamp_val(val, 0, 255);1122 1123	mutex_lock(&data->update_lock);1124	data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);1125	if ((data->type == f8000 && ((data->pwm_enable >> 2 * nr) & 3) != 2) ||1126	    (data->type != f8000 && !((data->pwm_enable >> 2 * nr) & 2))) {1127		count = -EROFS;1128		goto leave;1129	}1130	if (data->pwm_enable & (1 << (2 * nr))) {1131		/* PWM mode */1132		f71882fg_write8(data, F71882FG_REG_PWM(nr), val);1133		data->pwm[nr] = val;1134	} else {1135		/* RPM mode */1136		int target, full_speed;1137		full_speed = f71882fg_read16(data,1138					     F71882FG_REG_FAN_FULL_SPEED(nr));1139		target = fan_to_reg(val * fan_from_reg(full_speed) / 255);1140		f71882fg_write16(data, F71882FG_REG_FAN_TARGET(nr), target);1141		data->fan_target[nr] = target;1142		data->fan_full_speed[nr] = full_speed;1143	}1144leave:1145	mutex_unlock(&data->update_lock);1146 1147	return count;1148}1149 1150static ssize_t show_pwm_enable(struct device *dev,1151			       struct device_attribute *devattr, char *buf)1152{1153	int result = 0;1154	struct f71882fg_data *data = f71882fg_update_device(dev);1155	int nr = to_sensor_dev_attr_2(devattr)->index;1156 1157	switch ((data->pwm_enable >> 2 * nr) & 3) {1158	case 0:1159	case 1:1160		result = 2; /* Normal auto mode */1161		break;1162	case 2:1163		result = 1; /* Manual mode */1164		break;1165	case 3:1166		if (data->type == f8000)1167			result = 3; /* Thermostat mode */1168		else1169			result = 1; /* Manual mode */1170		break;1171	}1172 1173	return sprintf(buf, "%d\n", result);1174}1175 1176static ssize_t store_pwm_enable(struct device *dev, struct device_attribute1177				*devattr, const char *buf, size_t count)1178{1179	struct f71882fg_data *data = dev_get_drvdata(dev);1180	int err, nr = to_sensor_dev_attr_2(devattr)->index;1181	long val;1182 1183	err = kstrtol(buf, 10, &val);1184	if (err)1185		return err;1186 1187	/* Special case for F8000 pwm channel 3 which only does auto mode */1188	if (data->type == f8000 && nr == 2 && val != 2)1189		return -EINVAL;1190 1191	mutex_lock(&data->update_lock);1192	data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);1193	/* Special case for F8000 auto PWM mode / Thermostat mode */1194	if (data->type == f8000 && ((data->pwm_enable >> 2 * nr) & 1)) {1195		switch (val) {1196		case 2:1197			data->pwm_enable &= ~(2 << (2 * nr));1198			break;		/* Normal auto mode */1199		case 3:1200			data->pwm_enable |= 2 << (2 * nr);1201			break;		/* Thermostat mode */1202		default:1203			count = -EINVAL;1204			goto leave;1205		}1206	} else {1207		switch (val) {1208		case 1:1209			/* The f71858fg does not support manual RPM mode */1210			if (data->type == f71858fg &&1211			    ((data->pwm_enable >> (2 * nr)) & 1)) {1212				count = -EINVAL;1213				goto leave;1214			}1215			data->pwm_enable |= 2 << (2 * nr);1216			break;		/* Manual */1217		case 2:1218			data->pwm_enable &= ~(2 << (2 * nr));1219			break;		/* Normal auto mode */1220		default:1221			count = -EINVAL;1222			goto leave;1223		}1224	}1225	f71882fg_write8(data, F71882FG_REG_PWM_ENABLE, data->pwm_enable);1226leave:1227	mutex_unlock(&data->update_lock);1228 1229	return count;1230}1231 1232static ssize_t show_pwm_interpolate(struct device *dev,1233				    struct device_attribute *devattr, char *buf)1234{1235	int result;1236	struct f71882fg_data *data = f71882fg_update_device(dev);1237	int nr = to_sensor_dev_attr_2(devattr)->index;1238 1239	result = (data->pwm_auto_point_mapping[nr] >> 4) & 1;1240 1241	return sprintf(buf, "%d\n", result);1242}1243 1244static ssize_t store_pwm_interpolate(struct device *dev,1245				     struct device_attribute *devattr,1246				     const char *buf, size_t count)1247{1248	struct f71882fg_data *data = dev_get_drvdata(dev);1249	int err, nr = to_sensor_dev_attr_2(devattr)->index;1250	unsigned long val;1251 1252	err = kstrtoul(buf, 10, &val);1253	if (err)1254		return err;1255 1256	mutex_lock(&data->update_lock);1257	data->pwm_auto_point_mapping[nr] =1258		f71882fg_read8(data, F71882FG_REG_POINT_MAPPING(nr));1259	if (val)1260		val = data->pwm_auto_point_mapping[nr] | (1 << 4);1261	else1262		val = data->pwm_auto_point_mapping[nr] & (~(1 << 4));1263	f71882fg_write8(data, F71882FG_REG_POINT_MAPPING(nr), val);1264	data->pwm_auto_point_mapping[nr] = val;1265	mutex_unlock(&data->update_lock);1266 1267	return count;1268}1269 1270/* Fan / PWM attr common to all models */1271static struct sensor_device_attribute_2 fxxxx_fan_attr[4][6] = { {1272	SENSOR_ATTR_2(fan1_input, S_IRUGO, show_fan, NULL, 0, 0),1273	SENSOR_ATTR_2(fan1_full_speed, S_IRUGO|S_IWUSR,1274		      show_fan_full_speed,1275		      store_fan_full_speed, 0, 0),1276	SENSOR_ATTR_2(fan1_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 0),1277	SENSOR_ATTR_2(pwm1, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 0),1278	SENSOR_ATTR_2(pwm1_enable, S_IRUGO|S_IWUSR, show_pwm_enable,1279		      store_pwm_enable, 0, 0),1280	SENSOR_ATTR_2(pwm1_interpolate, S_IRUGO|S_IWUSR,1281		      show_pwm_interpolate, store_pwm_interpolate, 0, 0),1282}, {1283	SENSOR_ATTR_2(fan2_input, S_IRUGO, show_fan, NULL, 0, 1),1284	SENSOR_ATTR_2(fan2_full_speed, S_IRUGO|S_IWUSR,1285		      show_fan_full_speed,1286		      store_fan_full_speed, 0, 1),1287	SENSOR_ATTR_2(fan2_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 1),1288	SENSOR_ATTR_2(pwm2, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 1),1289	SENSOR_ATTR_2(pwm2_enable, S_IRUGO|S_IWUSR, show_pwm_enable,1290		      store_pwm_enable, 0, 1),1291	SENSOR_ATTR_2(pwm2_interpolate, S_IRUGO|S_IWUSR,1292		      show_pwm_interpolate, store_pwm_interpolate, 0, 1),1293}, {1294	SENSOR_ATTR_2(fan3_input, S_IRUGO, show_fan, NULL, 0, 2),1295	SENSOR_ATTR_2(fan3_full_speed, S_IRUGO|S_IWUSR,1296		      show_fan_full_speed,1297		      store_fan_full_speed, 0, 2),1298	SENSOR_ATTR_2(fan3_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 2),1299	SENSOR_ATTR_2(pwm3, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 2),1300	SENSOR_ATTR_2(pwm3_enable, S_IRUGO|S_IWUSR, show_pwm_enable,1301		      store_pwm_enable, 0, 2),1302	SENSOR_ATTR_2(pwm3_interpolate, S_IRUGO|S_IWUSR,1303		      show_pwm_interpolate, store_pwm_interpolate, 0, 2),1304}, {1305	SENSOR_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 0, 3),1306	SENSOR_ATTR_2(fan4_full_speed, S_IRUGO|S_IWUSR,1307		      show_fan_full_speed,1308		      store_fan_full_speed, 0, 3),1309	SENSOR_ATTR_2(fan4_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 3),1310	SENSOR_ATTR_2(pwm4, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 3),1311	SENSOR_ATTR_2(pwm4_enable, S_IRUGO|S_IWUSR, show_pwm_enable,1312		      store_pwm_enable, 0, 3),1313	SENSOR_ATTR_2(pwm4_interpolate, S_IRUGO|S_IWUSR,1314		      show_pwm_interpolate, store_pwm_interpolate, 0, 3),1315} };1316 1317static ssize_t show_simple_pwm(struct device *dev,1318			       struct device_attribute *devattr, char *buf)1319{1320	struct f71882fg_data *data = f71882fg_update_device(dev);1321	int val, nr = to_sensor_dev_attr_2(devattr)->index;1322 1323	val = data->pwm[nr];1324	return sprintf(buf, "%d\n", val);1325}1326 1327static ssize_t store_simple_pwm(struct device *dev,1328				struct device_attribute *devattr,1329				const char *buf, size_t count)1330{1331	struct f71882fg_data *data = dev_get_drvdata(dev);1332	int err, nr = to_sensor_dev_attr_2(devattr)->index;1333	long val;1334 1335	err = kstrtol(buf, 10, &val);1336	if (err)1337		return err;1338 1339	val = clamp_val(val, 0, 255);1340 1341	mutex_lock(&data->update_lock);1342	f71882fg_write8(data, F71882FG_REG_PWM(nr), val);1343	data->pwm[nr] = val;1344	mutex_unlock(&data->update_lock);1345 1346	return count;1347}1348 1349/* Attr for the third fan of the f71808a, which only has manual pwm */1350static struct sensor_device_attribute_2 f71808a_fan3_attr[] = {1351	SENSOR_ATTR_2(fan3_input, S_IRUGO, show_fan, NULL, 0, 2),1352	SENSOR_ATTR_2(fan3_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 2),1353	SENSOR_ATTR_2(pwm3, S_IRUGO|S_IWUSR,1354		      show_simple_pwm, store_simple_pwm, 0, 2),1355};1356 1357static ssize_t show_fan_beep(struct device *dev, struct device_attribute1358	*devattr, char *buf)1359{1360	struct f71882fg_data *data = f71882fg_update_device(dev);1361	int nr = to_sensor_dev_attr_2(devattr)->index;1362 1363	if (data->fan_beep & (1 << nr))1364		return sprintf(buf, "1\n");1365	else1366		return sprintf(buf, "0\n");1367}1368 1369static ssize_t store_fan_beep(struct device *dev, struct device_attribute1370	*devattr, const char *buf, size_t count)1371{1372	struct f71882fg_data *data = dev_get_drvdata(dev);1373	int err, nr = to_sensor_dev_attr_2(devattr)->index;1374	unsigned long val;1375 1376	err = kstrtoul(buf, 10, &val);1377	if (err)1378		return err;1379 1380	mutex_lock(&data->update_lock);1381	data->fan_beep = f71882fg_read8(data, F71882FG_REG_FAN_BEEP);1382	if (val)1383		data->fan_beep |= 1 << nr;1384	else1385		data->fan_beep &= ~(1 << nr);1386 1387	f71882fg_write8(data, F71882FG_REG_FAN_BEEP, data->fan_beep);1388	mutex_unlock(&data->update_lock);1389 1390	return count;1391}1392 1393/* Attr for models which can beep on Fan alarm */1394static struct sensor_device_attribute_2 fxxxx_fan_beep_attr[] = {1395	SENSOR_ATTR_2(fan1_beep, S_IRUGO|S_IWUSR, show_fan_beep,1396		store_fan_beep, 0, 0),1397	SENSOR_ATTR_2(fan2_beep, S_IRUGO|S_IWUSR, show_fan_beep,1398		store_fan_beep, 0, 1),1399	SENSOR_ATTR_2(fan3_beep, S_IRUGO|S_IWUSR, show_fan_beep,1400		store_fan_beep, 0, 2),1401	SENSOR_ATTR_2(fan4_beep, S_IRUGO|S_IWUSR, show_fan_beep,1402		store_fan_beep, 0, 3),1403};1404 1405static ssize_t show_pwm_auto_point_channel(struct device *dev,1406					   struct device_attribute *devattr,1407					   char *buf)1408{1409	int result;1410	struct f71882fg_data *data = f71882fg_update_device(dev);1411	int nr = to_sensor_dev_attr_2(devattr)->index;1412 1413	result = 1 << ((data->pwm_auto_point_mapping[nr] & 3) -1414		       data->temp_start);1415 1416	return sprintf(buf, "%d\n", result);1417}1418 1419static ssize_t store_pwm_auto_point_channel(struct device *dev,1420					    struct device_attribute *devattr,1421					    const char *buf, size_t count)1422{1423	struct f71882fg_data *data = dev_get_drvdata(dev);1424	int err, nr = to_sensor_dev_attr_2(devattr)->index;1425	long val;1426 1427	err = kstrtol(buf, 10, &val);1428	if (err)1429		return err;1430 1431	switch (val) {1432	case 1:1433		val = 0;1434		break;1435	case 2:1436		val = 1;1437		break;1438	case 4:1439		val = 2;1440		break;1441	default:1442		return -EINVAL;1443	}1444	val += data->temp_start;1445	mutex_lock(&data->update_lock);1446	data->pwm_auto_point_mapping[nr] =1447		f71882fg_read8(data, F71882FG_REG_POINT_MAPPING(nr));1448	val = (data->pwm_auto_point_mapping[nr] & 0xfc) | val;1449	f71882fg_write8(data, F71882FG_REG_POINT_MAPPING(nr), val);1450	data->pwm_auto_point_mapping[nr] = val;1451	mutex_unlock(&data->update_lock);1452 1453	return count;1454}1455 1456static ssize_t show_pwm_auto_point_pwm(struct device *dev,1457				       struct device_attribute *devattr,1458				       char *buf)1459{1460	int result;1461	struct f71882fg_data *data = f71882fg_update_device(dev);1462	int pwm = to_sensor_dev_attr_2(devattr)->index;1463	int point = to_sensor_dev_attr_2(devattr)->nr;1464 1465	mutex_lock(&data->update_lock);1466	if (data->pwm_enable & (1 << (2 * pwm))) {1467		/* PWM mode */1468		result = data->pwm_auto_point_pwm[pwm][point];1469	} else {1470		/* RPM mode */1471		result = 32 * 255 / (32 + data->pwm_auto_point_pwm[pwm][point]);1472	}1473	mutex_unlock(&data->update_lock);1474 1475	return sprintf(buf, "%d\n", result);1476}1477 1478static ssize_t store_pwm_auto_point_pwm(struct device *dev,1479					struct device_attribute *devattr,1480					const char *buf, size_t count)1481{1482	struct f71882fg_data *data = dev_get_drvdata(dev);1483	int err, pwm = to_sensor_dev_attr_2(devattr)->index;1484	int point = to_sensor_dev_attr_2(devattr)->nr;1485	long val;1486 1487	err = kstrtol(buf, 10, &val);1488	if (err)1489		return err;1490 1491	val = clamp_val(val, 0, 255);1492 1493	mutex_lock(&data->update_lock);1494	data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);1495	if (data->pwm_enable & (1 << (2 * pwm))) {1496		/* PWM mode */1497	} else {1498		/* RPM mode */1499		if (val < 29)	/* Prevent negative numbers */1500			val = 255;1501		else1502			val = (255 - val) * 32 / val;1503	}1504	f71882fg_write8(data, F71882FG_REG_POINT_PWM(pwm, point), val);1505	data->pwm_auto_point_pwm[pwm][point] = val;1506	mutex_unlock(&data->update_lock);1507 1508	return count;1509}1510 1511static ssize_t show_pwm_auto_point_temp(struct device *dev,1512					struct device_attribute *devattr,1513					char *buf)1514{1515	int result;1516	struct f71882fg_data *data = f71882fg_update_device(dev);1517	int pwm = to_sensor_dev_attr_2(devattr)->index;1518	int point = to_sensor_dev_attr_2(devattr)->nr;1519 1520	result = data->pwm_auto_point_temp[pwm][point];1521	return sprintf(buf, "%d\n", 1000 * result);1522}1523 1524static ssize_t store_pwm_auto_point_temp(struct device *dev,1525					 struct device_attribute *devattr,1526					 const char *buf, size_t count)1527{1528	struct f71882fg_data *data = dev_get_drvdata(dev);1529	int err, pwm = to_sensor_dev_attr_2(devattr)->index;1530	int point = to_sensor_dev_attr_2(devattr)->nr;1531	long val;1532 1533	err = kstrtol(buf, 10, &val);1534	if (err)1535		return err;1536 1537	val /= 1000;1538 1539	if (data->auto_point_temp_signed)1540		val = clamp_val(val, -128, 127);1541	else1542		val = clamp_val(val, 0, 127);1543 1544	mutex_lock(&data->update_lock);1545	f71882fg_write8(data, F71882FG_REG_POINT_TEMP(pwm, point), val);1546	data->pwm_auto_point_temp[pwm][point] = val;1547	mutex_unlock(&data->update_lock);1548 1549	return count;1550}1551 1552static ssize_t show_pwm_auto_point_temp_hyst(struct device *dev,1553					     struct device_attribute *devattr,1554					     char *buf)1555{1556	int result = 0;1557	struct f71882fg_data *data = f71882fg_update_device(dev);1558	int nr = to_sensor_dev_attr_2(devattr)->index;1559	int point = to_sensor_dev_attr_2(devattr)->nr;1560 1561	mutex_lock(&data->update_lock);1562	if (nr & 1)1563		result = data->pwm_auto_point_hyst[nr / 2] >> 4;1564	else1565		result = data->pwm_auto_point_hyst[nr / 2] & 0x0f;1566	result = 1000 * (data->pwm_auto_point_temp[nr][point] - result);1567	mutex_unlock(&data->update_lock);1568 1569	return sprintf(buf, "%d\n", result);1570}1571 1572static ssize_t store_pwm_auto_point_temp_hyst(struct device *dev,1573					      struct device_attribute *devattr,1574					      const char *buf, size_t count)1575{1576	struct f71882fg_data *data = dev_get_drvdata(dev);1577	int err, nr = to_sensor_dev_attr_2(devattr)->index;1578	int point = to_sensor_dev_attr_2(devattr)->nr;1579	u8 reg;1580	long val;1581 1582	err = kstrtol(buf, 10, &val);1583	if (err)1584		return err;1585 1586	val /= 1000;1587 1588	mutex_lock(&data->update_lock);1589	data->pwm_auto_point_temp[nr][point] =1590		f71882fg_read8(data, F71882FG_REG_POINT_TEMP(nr, point));1591	val = clamp_val(val, data->pwm_auto_point_temp[nr][point] - 15,1592			data->pwm_auto_point_temp[nr][point]);1593	val = data->pwm_auto_point_temp[nr][point] - val;1594 1595	reg = f71882fg_read8(data, F71882FG_REG_FAN_HYST(nr / 2));1596	if (nr & 1)1597		reg = (reg & 0x0f) | (val << 4);1598	else1599		reg = (reg & 0xf0) | val;1600 1601	f71882fg_write8(data, F71882FG_REG_FAN_HYST(nr / 2), reg);1602	data->pwm_auto_point_hyst[nr / 2] = reg;1603	mutex_unlock(&data->update_lock);1604 1605	return count;1606}1607 1608/*1609 * PWM attr for the f71862fg, fewer pwms and fewer zones per pwm than the1610 * standard models1611 */1612static struct sensor_device_attribute_2 f71862fg_auto_pwm_attr[3][7] = { {1613	SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR,1614		      show_pwm_auto_point_channel,1615		      store_pwm_auto_point_channel, 0, 0),1616	SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO|S_IWUSR,1617		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,1618		      1, 0),1619	SENSOR_ATTR_2(pwm1_auto_point2_pwm, S_IRUGO|S_IWUSR,1620		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,1621		      4, 0),1622	SENSOR_ATTR_2(pwm1_auto_point1_temp, S_IRUGO|S_IWUSR,1623		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,1624		      0, 0),1625	SENSOR_ATTR_2(pwm1_auto_point2_temp, S_IRUGO|S_IWUSR,1626		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,1627		      3, 0),1628	SENSOR_ATTR_2(pwm1_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,1629		      show_pwm_auto_point_temp_hyst,1630		      store_pwm_auto_point_temp_hyst,1631		      0, 0),1632	SENSOR_ATTR_2(pwm1_auto_point2_temp_hyst, S_IRUGO,1633		      show_pwm_auto_point_temp_hyst, NULL, 3, 0),1634}, {1635	SENSOR_ATTR_2(pwm2_auto_channels_temp, S_IRUGO|S_IWUSR,1636		      show_pwm_auto_point_channel,1637		      store_pwm_auto_point_channel, 0, 1),1638	SENSOR_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO|S_IWUSR,1639		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,1640		      1, 1),1641	SENSOR_ATTR_2(pwm2_auto_point2_pwm, S_IRUGO|S_IWUSR,1642		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,1643		      4, 1),1644	SENSOR_ATTR_2(pwm2_auto_point1_temp, S_IRUGO|S_IWUSR,1645		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,1646		      0, 1),1647	SENSOR_ATTR_2(pwm2_auto_point2_temp, S_IRUGO|S_IWUSR,1648		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,1649		      3, 1),1650	SENSOR_ATTR_2(pwm2_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,1651		      show_pwm_auto_point_temp_hyst,1652		      store_pwm_auto_point_temp_hyst,1653		      0, 1),1654	SENSOR_ATTR_2(pwm2_auto_point2_temp_hyst, S_IRUGO,1655		      show_pwm_auto_point_temp_hyst, NULL, 3, 1),1656}, {1657	SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR,1658		      show_pwm_auto_point_channel,1659		      store_pwm_auto_point_channel, 0, 2),1660	SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO|S_IWUSR,1661		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,1662		      1, 2),1663	SENSOR_ATTR_2(pwm3_auto_point2_pwm, S_IRUGO|S_IWUSR,1664		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,1665		      4, 2),1666	SENSOR_ATTR_2(pwm3_auto_point1_temp, S_IRUGO|S_IWUSR,1667		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,1668		      0, 2),1669	SENSOR_ATTR_2(pwm3_auto_point2_temp, S_IRUGO|S_IWUSR,1670		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,1671		      3, 2),1672	SENSOR_ATTR_2(pwm3_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,1673		      show_pwm_auto_point_temp_hyst,1674		      store_pwm_auto_point_temp_hyst,1675		      0, 2),1676	SENSOR_ATTR_2(pwm3_auto_point2_temp_hyst, S_IRUGO,1677		      show_pwm_auto_point_temp_hyst, NULL, 3, 2),1678} };1679 1680/*1681 * PWM attr for the f71808e/f71869, almost identical to the f71862fg, but the1682 * pwm setting when the temperature is above the pwmX_auto_point1_temp can be1683 * programmed instead of being hardcoded to 0xff1684 */1685static struct sensor_device_attribute_2 f71869_auto_pwm_attr[3][8] = { {1686	SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR,1687		      show_pwm_auto_point_channel,1688		      store_pwm_auto_point_channel, 0, 0),1689	SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO|S_IWUSR,1690		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,1691		      0, 0),1692	SENSOR_ATTR_2(pwm1_auto_point2_pwm, S_IRUGO|S_IWUSR,1693		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,1694		      1, 0),1695	SENSOR_ATTR_2(pwm1_auto_point3_pwm, S_IRUGO|S_IWUSR,1696		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,1697		      4, 0),1698	SENSOR_ATTR_2(pwm1_auto_point1_temp, S_IRUGO|S_IWUSR,1699		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,1700		      0, 0),1701	SENSOR_ATTR_2(pwm1_auto_point2_temp, S_IRUGO|S_IWUSR,1702		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,1703		      3, 0),1704	SENSOR_ATTR_2(pwm1_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,1705		      show_pwm_auto_point_temp_hyst,1706		      store_pwm_auto_point_temp_hyst,1707		      0, 0),1708	SENSOR_ATTR_2(pwm1_auto_point2_temp_hyst, S_IRUGO,1709		      show_pwm_auto_point_temp_hyst, NULL, 3, 0),1710}, {1711	SENSOR_ATTR_2(pwm2_auto_channels_temp, S_IRUGO|S_IWUSR,1712		      show_pwm_auto_point_channel,1713		      store_pwm_auto_point_channel, 0, 1),1714	SENSOR_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO|S_IWUSR,1715		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,1716		      0, 1),1717	SENSOR_ATTR_2(pwm2_auto_point2_pwm, S_IRUGO|S_IWUSR,1718		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,1719		      1, 1),1720	SENSOR_ATTR_2(pwm2_auto_point3_pwm, S_IRUGO|S_IWUSR,1721		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,1722		      4, 1),1723	SENSOR_ATTR_2(pwm2_auto_point1_temp, S_IRUGO|S_IWUSR,1724		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,1725		      0, 1),1726	SENSOR_ATTR_2(pwm2_auto_point2_temp, S_IRUGO|S_IWUSR,1727		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,1728		      3, 1),1729	SENSOR_ATTR_2(pwm2_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,1730		      show_pwm_auto_point_temp_hyst,1731		      store_pwm_auto_point_temp_hyst,1732		      0, 1),1733	SENSOR_ATTR_2(pwm2_auto_point2_temp_hyst, S_IRUGO,1734		      show_pwm_auto_point_temp_hyst, NULL, 3, 1),1735}, {1736	SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR,1737		      show_pwm_auto_point_channel,1738		      store_pwm_auto_point_channel, 0, 2),1739	SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO|S_IWUSR,1740		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,1741		      0, 2),1742	SENSOR_ATTR_2(pwm3_auto_point2_pwm, S_IRUGO|S_IWUSR,1743		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,1744		      1, 2),1745	SENSOR_ATTR_2(pwm3_auto_point3_pwm, S_IRUGO|S_IWUSR,1746		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,1747		      4, 2),1748	SENSOR_ATTR_2(pwm3_auto_point1_temp, S_IRUGO|S_IWUSR,1749		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,1750		      0, 2),1751	SENSOR_ATTR_2(pwm3_auto_point2_temp, S_IRUGO|S_IWUSR,1752		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,1753		      3, 2),1754	SENSOR_ATTR_2(pwm3_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,1755		      show_pwm_auto_point_temp_hyst,1756		      store_pwm_auto_point_temp_hyst,1757		      0, 2),1758	SENSOR_ATTR_2(pwm3_auto_point2_temp_hyst, S_IRUGO,1759		      show_pwm_auto_point_temp_hyst, NULL, 3, 2),1760} };1761 1762/* PWM attr for the standard models */1763static struct sensor_device_attribute_2 fxxxx_auto_pwm_attr[4][14] = { {1764	SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR,1765		      show_pwm_auto_point_channel,1766		      store_pwm_auto_point_channel, 0, 0),1767	SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO|S_IWUSR,1768		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,1769		      0, 0),1770	SENSOR_ATTR_2(pwm1_auto_point2_pwm, S_IRUGO|S_IWUSR,1771		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,1772		      1, 0),1773	SENSOR_ATTR_2(pwm1_auto_point3_pwm, S_IRUGO|S_IWUSR,1774		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,1775		      2, 0),1776	SENSOR_ATTR_2(pwm1_auto_point4_pwm, S_IRUGO|S_IWUSR,1777		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,1778		      3, 0),1779	SENSOR_ATTR_2(pwm1_auto_point5_pwm, S_IRUGO|S_IWUSR,1780		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,1781		      4, 0),1782	SENSOR_ATTR_2(pwm1_auto_point1_temp, S_IRUGO|S_IWUSR,1783		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,1784		      0, 0),1785	SENSOR_ATTR_2(pwm1_auto_point2_temp, S_IRUGO|S_IWUSR,1786		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,1787		      1, 0),1788	SENSOR_ATTR_2(pwm1_auto_point3_temp, S_IRUGO|S_IWUSR,1789		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,1790		      2, 0),1791	SENSOR_ATTR_2(pwm1_auto_point4_temp, S_IRUGO|S_IWUSR,1792		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,1793		      3, 0),1794	SENSOR_ATTR_2(pwm1_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,1795		      show_pwm_auto_point_temp_hyst,1796		      store_pwm_auto_point_temp_hyst,1797		      0, 0),1798	SENSOR_ATTR_2(pwm1_auto_point2_temp_hyst, S_IRUGO,1799		      show_pwm_auto_point_temp_hyst, NULL, 1, 0),1800	SENSOR_ATTR_2(pwm1_auto_point3_temp_hyst, S_IRUGO,1801		      show_pwm_auto_point_temp_hyst, NULL, 2, 0),1802	SENSOR_ATTR_2(pwm1_auto_point4_temp_hyst, S_IRUGO,1803		      show_pwm_auto_point_temp_hyst, NULL, 3, 0),1804}, {1805	SENSOR_ATTR_2(pwm2_auto_channels_temp, S_IRUGO|S_IWUSR,1806		      show_pwm_auto_point_channel,1807		      store_pwm_auto_point_channel, 0, 1),1808	SENSOR_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO|S_IWUSR,1809		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,1810		      0, 1),1811	SENSOR_ATTR_2(pwm2_auto_point2_pwm, S_IRUGO|S_IWUSR,1812		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,1813		      1, 1),1814	SENSOR_ATTR_2(pwm2_auto_point3_pwm, S_IRUGO|S_IWUSR,1815		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,1816		      2, 1),1817	SENSOR_ATTR_2(pwm2_auto_point4_pwm, S_IRUGO|S_IWUSR,1818		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,1819		      3, 1),1820	SENSOR_ATTR_2(pwm2_auto_point5_pwm, S_IRUGO|S_IWUSR,1821		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,1822		      4, 1),1823	SENSOR_ATTR_2(pwm2_auto_point1_temp, S_IRUGO|S_IWUSR,1824		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,1825		      0, 1),1826	SENSOR_ATTR_2(pwm2_auto_point2_temp, S_IRUGO|S_IWUSR,1827		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,1828		      1, 1),1829	SENSOR_ATTR_2(pwm2_auto_point3_temp, S_IRUGO|S_IWUSR,1830		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,1831		      2, 1),1832	SENSOR_ATTR_2(pwm2_auto_point4_temp, S_IRUGO|S_IWUSR,1833		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,1834		      3, 1),1835	SENSOR_ATTR_2(pwm2_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,1836		      show_pwm_auto_point_temp_hyst,1837		      store_pwm_auto_point_temp_hyst,1838		      0, 1),1839	SENSOR_ATTR_2(pwm2_auto_point2_temp_hyst, S_IRUGO,1840		      show_pwm_auto_point_temp_hyst, NULL, 1, 1),1841	SENSOR_ATTR_2(pwm2_auto_point3_temp_hyst, S_IRUGO,1842		      show_pwm_auto_point_temp_hyst, NULL, 2, 1),1843	SENSOR_ATTR_2(pwm2_auto_point4_temp_hyst, S_IRUGO,1844		      show_pwm_auto_point_temp_hyst, NULL, 3, 1),1845}, {1846	SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR,1847		      show_pwm_auto_point_channel,1848		      store_pwm_auto_point_channel, 0, 2),1849	SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO|S_IWUSR,1850		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,1851		      0, 2),1852	SENSOR_ATTR_2(pwm3_auto_point2_pwm, S_IRUGO|S_IWUSR,1853		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,1854		      1, 2),1855	SENSOR_ATTR_2(pwm3_auto_point3_pwm, S_IRUGO|S_IWUSR,1856		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,1857		      2, 2),1858	SENSOR_ATTR_2(pwm3_auto_point4_pwm, S_IRUGO|S_IWUSR,1859		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,1860		      3, 2),1861	SENSOR_ATTR_2(pwm3_auto_point5_pwm, S_IRUGO|S_IWUSR,1862		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,1863		      4, 2),1864	SENSOR_ATTR_2(pwm3_auto_point1_temp, S_IRUGO|S_IWUSR,1865		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,1866		      0, 2),1867	SENSOR_ATTR_2(pwm3_auto_point2_temp, S_IRUGO|S_IWUSR,1868		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,1869		      1, 2),1870	SENSOR_ATTR_2(pwm3_auto_point3_temp, S_IRUGO|S_IWUSR,1871		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,1872		      2, 2),1873	SENSOR_ATTR_2(pwm3_auto_point4_temp, S_IRUGO|S_IWUSR,1874		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,1875		      3, 2),1876	SENSOR_ATTR_2(pwm3_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,1877		      show_pwm_auto_point_temp_hyst,1878		      store_pwm_auto_point_temp_hyst,1879		      0, 2),1880	SENSOR_ATTR_2(pwm3_auto_point2_temp_hyst, S_IRUGO,1881		      show_pwm_auto_point_temp_hyst, NULL, 1, 2),1882	SENSOR_ATTR_2(pwm3_auto_point3_temp_hyst, S_IRUGO,1883		      show_pwm_auto_point_temp_hyst, NULL, 2, 2),1884	SENSOR_ATTR_2(pwm3_auto_point4_temp_hyst, S_IRUGO,1885		      show_pwm_auto_point_temp_hyst, NULL, 3, 2),1886}, {1887	SENSOR_ATTR_2(pwm4_auto_channels_temp, S_IRUGO|S_IWUSR,1888		      show_pwm_auto_point_channel,1889		      store_pwm_auto_point_channel, 0, 3),1890	SENSOR_ATTR_2(pwm4_auto_point1_pwm, S_IRUGO|S_IWUSR,1891		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,1892		      0, 3),1893	SENSOR_ATTR_2(pwm4_auto_point2_pwm, S_IRUGO|S_IWUSR,1894		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,1895		      1, 3),1896	SENSOR_ATTR_2(pwm4_auto_point3_pwm, S_IRUGO|S_IWUSR,1897		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,1898		      2, 3),1899	SENSOR_ATTR_2(pwm4_auto_point4_pwm, S_IRUGO|S_IWUSR,1900		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,1901		      3, 3),1902	SENSOR_ATTR_2(pwm4_auto_point5_pwm, S_IRUGO|S_IWUSR,1903		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,1904		      4, 3),1905	SENSOR_ATTR_2(pwm4_auto_point1_temp, S_IRUGO|S_IWUSR,1906		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,1907		      0, 3),1908	SENSOR_ATTR_2(pwm4_auto_point2_temp, S_IRUGO|S_IWUSR,1909		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,1910		      1, 3),1911	SENSOR_ATTR_2(pwm4_auto_point3_temp, S_IRUGO|S_IWUSR,1912		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,1913		      2, 3),1914	SENSOR_ATTR_2(pwm4_auto_point4_temp, S_IRUGO|S_IWUSR,1915		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,1916		      3, 3),1917	SENSOR_ATTR_2(pwm4_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,1918		      show_pwm_auto_point_temp_hyst,1919		      store_pwm_auto_point_temp_hyst,1920		      0, 3),1921	SENSOR_ATTR_2(pwm4_auto_point2_temp_hyst, S_IRUGO,1922		      show_pwm_auto_point_temp_hyst, NULL, 1, 3),1923	SENSOR_ATTR_2(pwm4_auto_point3_temp_hyst, S_IRUGO,1924		      show_pwm_auto_point_temp_hyst, NULL, 2, 3),1925	SENSOR_ATTR_2(pwm4_auto_point4_temp_hyst, S_IRUGO,1926		      show_pwm_auto_point_temp_hyst, NULL, 3, 3),1927} };1928 1929/* Fan attr specific to the f8000 (4th fan input can only measure speed) */1930static struct sensor_device_attribute_2 f8000_fan_attr[] = {1931	SENSOR_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 0, 3),1932};1933 1934/*1935 * PWM attr for the f8000, zones mapped to temp instead of to pwm!1936 * Also the register block at offset A0 maps to TEMP1 (so our temp2, as the1937 * F8000 starts counting temps at 0), B0 maps the TEMP2 and C0 maps to TEMP01938 */1939static struct sensor_device_attribute_2 f8000_auto_pwm_attr[3][14] = { {1940	SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR,1941		      show_pwm_auto_point_channel,1942		      store_pwm_auto_point_channel, 0, 0),1943	SENSOR_ATTR_2(temp1_auto_point1_pwm, S_IRUGO|S_IWUSR,1944		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,1945		      0, 2),1946	SENSOR_ATTR_2(temp1_auto_point2_pwm, S_IRUGO|S_IWUSR,1947		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,1948		      1, 2),1949	SENSOR_ATTR_2(temp1_auto_point3_pwm, S_IRUGO|S_IWUSR,1950		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,1951		      2, 2),1952	SENSOR_ATTR_2(temp1_auto_point4_pwm, S_IRUGO|S_IWUSR,1953		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,1954		      3, 2),1955	SENSOR_ATTR_2(temp1_auto_point5_pwm, S_IRUGO|S_IWUSR,1956		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,1957		      4, 2),1958	SENSOR_ATTR_2(temp1_auto_point1_temp, S_IRUGO|S_IWUSR,1959		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,1960		      0, 2),1961	SENSOR_ATTR_2(temp1_auto_point2_temp, S_IRUGO|S_IWUSR,1962		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,1963		      1, 2),1964	SENSOR_ATTR_2(temp1_auto_point3_temp, S_IRUGO|S_IWUSR,1965		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,1966		      2, 2),1967	SENSOR_ATTR_2(temp1_auto_point4_temp, S_IRUGO|S_IWUSR,1968		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,1969		      3, 2),1970	SENSOR_ATTR_2(temp1_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,1971		      show_pwm_auto_point_temp_hyst,1972		      store_pwm_auto_point_temp_hyst,1973		      0, 2),1974	SENSOR_ATTR_2(temp1_auto_point2_temp_hyst, S_IRUGO,1975		      show_pwm_auto_point_temp_hyst, NULL, 1, 2),1976	SENSOR_ATTR_2(temp1_auto_point3_temp_hyst, S_IRUGO,1977		      show_pwm_auto_point_temp_hyst, NULL, 2, 2),1978	SENSOR_ATTR_2(temp1_auto_point4_temp_hyst, S_IRUGO,1979		      show_pwm_auto_point_temp_hyst, NULL, 3, 2),1980}, {1981	SENSOR_ATTR_2(pwm2_auto_channels_temp, S_IRUGO|S_IWUSR,1982		      show_pwm_auto_point_channel,1983		      store_pwm_auto_point_channel, 0, 1),1984	SENSOR_ATTR_2(temp2_auto_point1_pwm, S_IRUGO|S_IWUSR,1985		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,1986		      0, 0),1987	SENSOR_ATTR_2(temp2_auto_point2_pwm, S_IRUGO|S_IWUSR,1988		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,1989		      1, 0),1990	SENSOR_ATTR_2(temp2_auto_point3_pwm, S_IRUGO|S_IWUSR,1991		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,1992		      2, 0),1993	SENSOR_ATTR_2(temp2_auto_point4_pwm, S_IRUGO|S_IWUSR,1994		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,1995		      3, 0),1996	SENSOR_ATTR_2(temp2_auto_point5_pwm, S_IRUGO|S_IWUSR,1997		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,1998		      4, 0),1999	SENSOR_ATTR_2(temp2_auto_point1_temp, S_IRUGO|S_IWUSR,2000		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,2001		      0, 0),2002	SENSOR_ATTR_2(temp2_auto_point2_temp, S_IRUGO|S_IWUSR,2003		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,2004		      1, 0),2005	SENSOR_ATTR_2(temp2_auto_point3_temp, S_IRUGO|S_IWUSR,2006		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,2007		      2, 0),2008	SENSOR_ATTR_2(temp2_auto_point4_temp, S_IRUGO|S_IWUSR,2009		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,2010		      3, 0),2011	SENSOR_ATTR_2(temp2_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,2012		      show_pwm_auto_point_temp_hyst,2013		      store_pwm_auto_point_temp_hyst,2014		      0, 0),2015	SENSOR_ATTR_2(temp2_auto_point2_temp_hyst, S_IRUGO,2016		      show_pwm_auto_point_temp_hyst, NULL, 1, 0),2017	SENSOR_ATTR_2(temp2_auto_point3_temp_hyst, S_IRUGO,2018		      show_pwm_auto_point_temp_hyst, NULL, 2, 0),2019	SENSOR_ATTR_2(temp2_auto_point4_temp_hyst, S_IRUGO,2020		      show_pwm_auto_point_temp_hyst, NULL, 3, 0),2021}, {2022	SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR,2023		      show_pwm_auto_point_channel,2024		      store_pwm_auto_point_channel, 0, 2),2025	SENSOR_ATTR_2(temp3_auto_point1_pwm, S_IRUGO|S_IWUSR,2026		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,2027		      0, 1),2028	SENSOR_ATTR_2(temp3_auto_point2_pwm, S_IRUGO|S_IWUSR,2029		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,2030		      1, 1),2031	SENSOR_ATTR_2(temp3_auto_point3_pwm, S_IRUGO|S_IWUSR,2032		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,2033		      2, 1),2034	SENSOR_ATTR_2(temp3_auto_point4_pwm, S_IRUGO|S_IWUSR,2035		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,2036		      3, 1),2037	SENSOR_ATTR_2(temp3_auto_point5_pwm, S_IRUGO|S_IWUSR,2038		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,2039		      4, 1),2040	SENSOR_ATTR_2(temp3_auto_point1_temp, S_IRUGO|S_IWUSR,2041		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,2042		      0, 1),2043	SENSOR_ATTR_2(temp3_auto_point2_temp, S_IRUGO|S_IWUSR,2044		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,2045		      1, 1),2046	SENSOR_ATTR_2(temp3_auto_point3_temp, S_IRUGO|S_IWUSR,2047		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,2048		      2, 1),2049	SENSOR_ATTR_2(temp3_auto_point4_temp, S_IRUGO|S_IWUSR,2050		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,2051		      3, 1),2052	SENSOR_ATTR_2(temp3_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,2053		      show_pwm_auto_point_temp_hyst,2054		      store_pwm_auto_point_temp_hyst,2055		      0, 1),2056	SENSOR_ATTR_2(temp3_auto_point2_temp_hyst, S_IRUGO,2057		      show_pwm_auto_point_temp_hyst, NULL, 1, 1),2058	SENSOR_ATTR_2(temp3_auto_point3_temp_hyst, S_IRUGO,2059		      show_pwm_auto_point_temp_hyst, NULL, 2, 1),2060	SENSOR_ATTR_2(temp3_auto_point4_temp_hyst, S_IRUGO,2061		      show_pwm_auto_point_temp_hyst, NULL, 3, 1),2062} };2063 2064/* Super I/O functions */2065static inline int superio_inb(int base, int reg)2066{2067	outb(reg, base);2068	return inb(base + 1);2069}2070 2071static int superio_inw(int base, int reg)2072{2073	int val;2074	val  = superio_inb(base, reg) << 8;2075	val |= superio_inb(base, reg + 1);2076	return val;2077}2078 2079static inline int superio_enter(int base)2080{2081	/* Don't step on other drivers' I/O space by accident */2082	if (!request_muxed_region(base, 2, DRVNAME)) {2083		pr_err("I/O address 0x%04x already in use\n", base);2084		return -EBUSY;2085	}2086 2087	/* according to the datasheet the key must be send twice! */2088	outb(SIO_UNLOCK_KEY, base);2089	outb(SIO_UNLOCK_KEY, base);2090 2091	return 0;2092}2093 2094static inline void superio_select(int base, int ld)2095{2096	outb(SIO_REG_LDSEL, base);2097	outb(ld, base + 1);2098}2099 2100static inline void superio_exit(int base)2101{2102	outb(SIO_LOCK_KEY, base);2103	release_region(base, 2);2104}2105 2106static int f71882fg_create_sysfs_files(struct platform_device *pdev,2107	struct sensor_device_attribute_2 *attr, int count)2108{2109	int err, i;2110 2111	for (i = 0; i < count; i++) {2112		err = device_create_file(&pdev->dev, &attr[i].dev_attr);2113		if (err)2114			return err;2115	}2116	return 0;2117}2118 2119static void f71882fg_remove_sysfs_files(struct platform_device *pdev,2120	struct sensor_device_attribute_2 *attr, int count)2121{2122	int i;2123 2124	for (i = 0; i < count; i++)2125		device_remove_file(&pdev->dev, &attr[i].dev_attr);2126}2127 2128static int f71882fg_create_fan_sysfs_files(2129	struct platform_device *pdev, int idx)2130{2131	struct f71882fg_data *data = platform_get_drvdata(pdev);2132	int err;2133 2134	/* Sanity check the pwm setting */2135	err = 0;2136	switch (data->type) {2137	case f71858fg:2138		if (((data->pwm_enable >> (idx * 2)) & 3) == 3)2139			err = 1;2140		break;2141	case f71862fg:2142		if (((data->pwm_enable >> (idx * 2)) & 1) != 1)2143			err = 1;2144		break;2145	case f8000:2146		if (idx == 2)2147			err = data->pwm_enable & 0x20;2148		break;2149	default:2150		break;2151	}2152	if (err) {2153		dev_err(&pdev->dev,2154			"Invalid (reserved) pwm settings: 0x%02x, "2155			"skipping fan %d\n",2156			(data->pwm_enable >> (idx * 2)) & 3, idx + 1);2157		return 0; /* This is a non fatal condition */2158	}2159 2160	err = f71882fg_create_sysfs_files(pdev, &fxxxx_fan_attr[idx][0],2161					  ARRAY_SIZE(fxxxx_fan_attr[0]));2162	if (err)2163		return err;2164 2165	if (f71882fg_fan_has_beep[data->type]) {2166		err = f71882fg_create_sysfs_files(pdev,2167						  &fxxxx_fan_beep_attr[idx],2168						  1);2169		if (err)2170			return err;2171	}2172 2173	dev_info(&pdev->dev, "Fan: %d is in %s mode\n", idx + 1,2174		 (data->pwm_enable & (1 << (2 * idx))) ? "duty-cycle" : "RPM");2175 2176	/* Check for unsupported auto pwm settings */2177	switch (data->type) {2178	case f71808e:2179	case f71808a:2180	case f71869:2181	case f71869a:2182	case f71889fg:2183	case f71889ed:2184	case f71889a:2185		data->pwm_auto_point_mapping[idx] =2186			f71882fg_read8(data, F71882FG_REG_POINT_MAPPING(idx));2187		if ((data->pwm_auto_point_mapping[idx] & 0x80) ||2188		    (data->pwm_auto_point_mapping[idx] & 3) == 0) {2189			dev_warn(&pdev->dev,2190				 "Auto pwm controlled by raw digital "2191				 "data, disabling pwm auto_point "2192				 "sysfs attributes for fan %d\n", idx + 1);2193			return 0; /* This is a non fatal condition */2194		}2195		break;2196	default:2197		break;2198	}2199 2200	switch (data->type) {2201	case f71862fg:2202		err = f71882fg_create_sysfs_files(pdev,2203					&f71862fg_auto_pwm_attr[idx][0],2204					ARRAY_SIZE(f71862fg_auto_pwm_attr[0]));2205		break;2206	case f71808e:2207	case f71869:2208		err = f71882fg_create_sysfs_files(pdev,2209					&f71869_auto_pwm_attr[idx][0],2210					ARRAY_SIZE(f71869_auto_pwm_attr[0]));2211		break;2212	case f8000:2213		err = f71882fg_create_sysfs_files(pdev,2214					&f8000_auto_pwm_attr[idx][0],2215					ARRAY_SIZE(f8000_auto_pwm_attr[0]));2216		break;2217	default:2218		err = f71882fg_create_sysfs_files(pdev,2219					&fxxxx_auto_pwm_attr[idx][0],2220					ARRAY_SIZE(fxxxx_auto_pwm_attr[0]));2221	}2222 2223	return err;2224}2225 2226static void f71882fg_remove(struct platform_device *pdev)2227{2228	struct f71882fg_data *data = platform_get_drvdata(pdev);2229	int nr_fans = f71882fg_nr_fans[data->type];2230	int nr_temps = f71882fg_nr_temps[data->type];2231	int i;2232	u8 start_reg = f71882fg_read8(data, F71882FG_REG_START);2233 2234	if (data->hwmon_dev)2235		hwmon_device_unregister(data->hwmon_dev);2236 2237	device_remove_file(&pdev->dev, &dev_attr_name);2238 2239	if (start_reg & 0x01) {2240		switch (data->type) {2241		case f71858fg:2242			if (data->temp_config & 0x10)2243				f71882fg_remove_sysfs_files(pdev,2244					f8000_temp_attr,2245					ARRAY_SIZE(f8000_temp_attr));2246			else2247				f71882fg_remove_sysfs_files(pdev,2248					f71858fg_temp_attr,2249					ARRAY_SIZE(f71858fg_temp_attr));2250			break;2251		case f8000:2252			f71882fg_remove_sysfs_files(pdev,2253					f8000_temp_attr,2254					ARRAY_SIZE(f8000_temp_attr));2255			break;2256		case f81866a:2257			f71882fg_remove_sysfs_files(pdev,2258					f71858fg_temp_attr,2259					ARRAY_SIZE(f71858fg_temp_attr));2260			break;2261		default:2262			f71882fg_remove_sysfs_files(pdev,2263				&fxxxx_temp_attr[0][0],2264				ARRAY_SIZE(fxxxx_temp_attr[0]) * nr_temps);2265		}2266		if (f71882fg_temp_has_beep[data->type]) {2267			if (data->type == f81866a)2268				f71882fg_remove_sysfs_files(pdev,2269					&f81866_temp_beep_attr[0][0],2270					ARRAY_SIZE(f81866_temp_beep_attr[0])2271						* nr_temps);2272			else2273				f71882fg_remove_sysfs_files(pdev,2274					&fxxxx_temp_beep_attr[0][0],2275					ARRAY_SIZE(fxxxx_temp_beep_attr[0])2276						* nr_temps);2277		}2278 2279		for (i = 0; i < F71882FG_MAX_INS; i++) {2280			if (f71882fg_has_in[data->type][i]) {2281				device_remove_file(&pdev->dev,2282						&fxxxx_in_attr[i].dev_attr);2283			}2284		}2285		if (f71882fg_has_in1_alarm[data->type]) {2286			f71882fg_remove_sysfs_files(pdev,2287					fxxxx_in1_alarm_attr,2288					ARRAY_SIZE(fxxxx_in1_alarm_attr));2289		}2290	}2291 2292	if (start_reg & 0x02) {2293		f71882fg_remove_sysfs_files(pdev, &fxxxx_fan_attr[0][0],2294				ARRAY_SIZE(fxxxx_fan_attr[0]) * nr_fans);2295 2296		if (f71882fg_fan_has_beep[data->type]) {2297			f71882fg_remove_sysfs_files(pdev,2298					fxxxx_fan_beep_attr, nr_fans);2299		}2300 2301		switch (data->type) {2302		case f71808a:2303			f71882fg_remove_sysfs_files(pdev,2304				&fxxxx_auto_pwm_attr[0][0],2305				ARRAY_SIZE(fxxxx_auto_pwm_attr[0]) * nr_fans);2306			f71882fg_remove_sysfs_files(pdev,2307					f71808a_fan3_attr,2308					ARRAY_SIZE(f71808a_fan3_attr));2309			break;2310		case f71862fg:2311			f71882fg_remove_sysfs_files(pdev,2312				&f71862fg_auto_pwm_attr[0][0],2313				ARRAY_SIZE(f71862fg_auto_pwm_attr[0]) *2314					nr_fans);2315			break;2316		case f71808e:2317		case f71869:2318			f71882fg_remove_sysfs_files(pdev,2319				&f71869_auto_pwm_attr[0][0],2320				ARRAY_SIZE(f71869_auto_pwm_attr[0]) * nr_fans);2321			break;2322		case f8000:2323			f71882fg_remove_sysfs_files(pdev,2324					f8000_fan_attr,2325					ARRAY_SIZE(f8000_fan_attr));2326			f71882fg_remove_sysfs_files(pdev,2327				&f8000_auto_pwm_attr[0][0],2328				ARRAY_SIZE(f8000_auto_pwm_attr[0]) * nr_fans);2329			break;2330		default:2331			f71882fg_remove_sysfs_files(pdev,2332				&fxxxx_auto_pwm_attr[0][0],2333				ARRAY_SIZE(fxxxx_auto_pwm_attr[0]) * nr_fans);2334		}2335	}2336}2337 2338static int f71882fg_probe(struct platform_device *pdev)2339{2340	struct f71882fg_data *data;2341	struct f71882fg_sio_data *sio_data = dev_get_platdata(&pdev->dev);2342	int nr_fans = f71882fg_nr_fans[sio_data->type];2343	int nr_temps = f71882fg_nr_temps[sio_data->type];2344	int err, i;2345	int size;2346	u8 start_reg, reg;2347 2348	data = devm_kzalloc(&pdev->dev, sizeof(struct f71882fg_data),2349			    GFP_KERNEL);2350	if (!data)2351		return -ENOMEM;2352 2353	data->addr = platform_get_resource(pdev, IORESOURCE_IO, 0)->start;2354	data->type = sio_data->type;2355	data->temp_start =2356	    (data->type == f71858fg || data->type == f8000 ||2357		data->type == f81866a) ? 0 : 1;2358	mutex_init(&data->update_lock);2359	platform_set_drvdata(pdev, data);2360 2361	start_reg = f71882fg_read8(data, F71882FG_REG_START);2362	if (start_reg & 0x04) {2363		dev_warn(&pdev->dev, "Hardware monitor is powered down\n");2364		return -ENODEV;2365	}2366	if (!(start_reg & 0x03)) {2367		dev_warn(&pdev->dev, "Hardware monitoring not activated\n");2368		return -ENODEV;2369	}2370 2371	/* Register sysfs interface files */2372	err = device_create_file(&pdev->dev, &dev_attr_name);2373	if (err)2374		goto exit_unregister_sysfs;2375 2376	if (start_reg & 0x01) {2377		switch (data->type) {2378		case f71858fg:2379			data->temp_config =2380				f71882fg_read8(data, F71882FG_REG_TEMP_CONFIG);2381			if (data->temp_config & 0x10)2382				/*2383				 * The f71858fg temperature alarms behave as2384				 * the f8000 alarms in this mode2385				 */2386				err = f71882fg_create_sysfs_files(pdev,2387					f8000_temp_attr,2388					ARRAY_SIZE(f8000_temp_attr));2389			else2390				err = f71882fg_create_sysfs_files(pdev,2391					f71858fg_temp_attr,2392					ARRAY_SIZE(f71858fg_temp_attr));2393			break;2394		case f8000:2395			err = f71882fg_create_sysfs_files(pdev,2396					f8000_temp_attr,2397					ARRAY_SIZE(f8000_temp_attr));2398			break;2399		case f81866a:2400			err = f71882fg_create_sysfs_files(pdev,2401					f71858fg_temp_attr,2402					ARRAY_SIZE(f71858fg_temp_attr));2403			break;2404		default:2405			err = f71882fg_create_sysfs_files(pdev,2406				&fxxxx_temp_attr[0][0],2407				ARRAY_SIZE(fxxxx_temp_attr[0]) * nr_temps);2408		}2409		if (err)2410			goto exit_unregister_sysfs;2411 2412		if (f71882fg_temp_has_beep[data->type]) {2413			if (data->type == f81866a) {2414				size = ARRAY_SIZE(f81866_temp_beep_attr[0]);2415				err = f71882fg_create_sysfs_files(pdev,2416						&f81866_temp_beep_attr[0][0],2417						size * nr_temps);2418 2419			} else {2420				size = ARRAY_SIZE(fxxxx_temp_beep_attr[0]);2421				err = f71882fg_create_sysfs_files(pdev,2422						&fxxxx_temp_beep_attr[0][0],2423						size * nr_temps);2424			}2425			if (err)2426				goto exit_unregister_sysfs;2427		}2428 2429		for (i = 0; i < F71882FG_MAX_INS; i++) {2430			if (f71882fg_has_in[data->type][i]) {2431				err = device_create_file(&pdev->dev,2432						&fxxxx_in_attr[i].dev_attr);2433				if (err)2434					goto exit_unregister_sysfs;2435			}2436		}2437		if (f71882fg_has_in1_alarm[data->type]) {2438			err = f71882fg_create_sysfs_files(pdev,2439					fxxxx_in1_alarm_attr,2440					ARRAY_SIZE(fxxxx_in1_alarm_attr));2441			if (err)2442				goto exit_unregister_sysfs;2443		}2444	}2445 2446	if (start_reg & 0x02) {2447		switch (data->type) {2448		case f71808e:2449		case f71808a:2450		case f71869:2451		case f71869a:2452			/* These always have signed auto point temps */2453			data->auto_point_temp_signed = 1;2454			fallthrough;	/* to select correct fan/pwm reg bank! */2455		case f71889fg:2456		case f71889ed:2457		case f71889a:2458			reg = f71882fg_read8(data, F71882FG_REG_FAN_FAULT_T);2459			if (reg & F71882FG_FAN_NEG_TEMP_EN)2460				data->auto_point_temp_signed = 1;2461			/* Ensure banked pwm registers point to right bank */2462			reg &= ~F71882FG_FAN_PROG_SEL;2463			f71882fg_write8(data, F71882FG_REG_FAN_FAULT_T, reg);2464			break;2465		default:2466			break;2467		}2468 2469		data->pwm_enable =2470			f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);2471 2472		for (i = 0; i < nr_fans; i++) {2473			err = f71882fg_create_fan_sysfs_files(pdev, i);2474			if (err)2475				goto exit_unregister_sysfs;2476		}2477 2478		/* Some types have 1 extra fan with limited functionality */2479		switch (data->type) {2480		case f71808a:2481			err = f71882fg_create_sysfs_files(pdev,2482					f71808a_fan3_attr,2483					ARRAY_SIZE(f71808a_fan3_attr));2484			break;2485		case f8000:2486			err = f71882fg_create_sysfs_files(pdev,2487					f8000_fan_attr,2488					ARRAY_SIZE(f8000_fan_attr));2489			break;2490		default:2491			break;2492		}2493		if (err)2494			goto exit_unregister_sysfs;2495	}2496 2497	data->hwmon_dev = hwmon_device_register(&pdev->dev);2498	if (IS_ERR(data->hwmon_dev)) {2499		err = PTR_ERR(data->hwmon_dev);2500		data->hwmon_dev = NULL;2501		goto exit_unregister_sysfs;2502	}2503 2504	return 0;2505 2506exit_unregister_sysfs:2507	f71882fg_remove(pdev); /* Will unregister the sysfs files for us */2508	return err; /* f71882fg_remove() also frees our data */2509}2510 2511static int __init f71882fg_find(int sioaddr, struct f71882fg_sio_data *sio_data)2512{2513	u16 devid;2514	unsigned short address;2515	int err = superio_enter(sioaddr);2516	if (err)2517		return err;2518 2519	devid = superio_inw(sioaddr, SIO_REG_MANID);2520	if (devid != SIO_FINTEK_ID) {2521		pr_debug("Not a Fintek device\n");2522		err = -ENODEV;2523		goto exit;2524	}2525 2526	devid = force_id ? force_id : superio_inw(sioaddr, SIO_REG_DEVID);2527	switch (devid) {2528	case SIO_F71808E_ID:2529		sio_data->type = f71808e;2530		break;2531	case SIO_F71808A_ID:2532		sio_data->type = f71808a;2533		break;2534	case SIO_F71858_ID:2535	case SIO_F71858AD_ID:2536		sio_data->type = f71858fg;2537		break;2538	case SIO_F71862_ID:2539		sio_data->type = f71862fg;2540		break;2541	case SIO_F71868_ID:2542		sio_data->type = f71868a;2543		break;2544	case SIO_F71869_ID:2545		sio_data->type = f71869;2546		break;2547	case SIO_F71869A_ID:2548		sio_data->type = f71869a;2549		break;2550	case SIO_F71882_ID:2551		sio_data->type = f71882fg;2552		break;2553	case SIO_F71889_ID:2554		sio_data->type = f71889fg;2555		break;2556	case SIO_F71889E_ID:2557		sio_data->type = f71889ed;2558		break;2559	case SIO_F71889A_ID:2560		sio_data->type = f71889a;2561		break;2562	case SIO_F8000_ID:2563		sio_data->type = f8000;2564		break;2565	case SIO_F81768D_ID:2566		sio_data->type = f81768d;2567		break;2568	case SIO_F81865_ID:2569		sio_data->type = f81865f;2570		break;2571	case SIO_F81866_ID:2572	case SIO_F81966_ID:2573		sio_data->type = f81866a;2574		break;2575	default:2576		pr_info("Unsupported Fintek device: %04x\n",2577			(unsigned int)devid);2578		err = -ENODEV;2579		goto exit;2580	}2581 2582	if (sio_data->type == f71858fg)2583		superio_select(sioaddr, SIO_F71858FG_LD_HWM);2584	else2585		superio_select(sioaddr, SIO_F71882FG_LD_HWM);2586 2587	if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) {2588		pr_warn("Device not activated\n");2589		err = -ENODEV;2590		goto exit;2591	}2592 2593	address = superio_inw(sioaddr, SIO_REG_ADDR);2594	if (address == 0) {2595		pr_warn("Base address not set\n");2596		err = -ENODEV;2597		goto exit;2598	}2599	address &= ~(REGION_LENGTH - 1);	/* Ignore 3 LSB */2600 2601	err = address;2602	pr_info("Found %s chip at %#x, revision %d\n",2603		f71882fg_names[sio_data->type],	(unsigned int)address,2604		(int)superio_inb(sioaddr, SIO_REG_DEVREV));2605exit:2606	superio_exit(sioaddr);2607	return err;2608}2609 2610static int __init f71882fg_device_add(int address,2611				      const struct f71882fg_sio_data *sio_data)2612{2613	struct resource res = {2614		.start	= address,2615		.end	= address + REGION_LENGTH - 1,2616		.flags	= IORESOURCE_IO,2617	};2618	int err;2619 2620	f71882fg_pdev = platform_device_alloc(DRVNAME, address);2621	if (!f71882fg_pdev)2622		return -ENOMEM;2623 2624	res.name = f71882fg_pdev->name;2625	err = acpi_check_resource_conflict(&res);2626	if (err)2627		goto exit_device_put;2628 2629	err = platform_device_add_resources(f71882fg_pdev, &res, 1);2630	if (err) {2631		pr_err("Device resource addition failed\n");2632		goto exit_device_put;2633	}2634 2635	err = platform_device_add_data(f71882fg_pdev, sio_data,2636				       sizeof(struct f71882fg_sio_data));2637	if (err) {2638		pr_err("Platform data allocation failed\n");2639		goto exit_device_put;2640	}2641 2642	err = platform_device_add(f71882fg_pdev);2643	if (err) {2644		pr_err("Device addition failed\n");2645		goto exit_device_put;2646	}2647 2648	return 0;2649 2650exit_device_put:2651	platform_device_put(f71882fg_pdev);2652 2653	return err;2654}2655 2656static struct platform_driver f71882fg_driver = {2657	.driver = {2658		.name	= DRVNAME,2659	},2660	.probe		= f71882fg_probe,2661	.remove_new	= f71882fg_remove,2662};2663 2664static int __init f71882fg_init(void)2665{2666	int err;2667	int address;2668	struct f71882fg_sio_data sio_data;2669 2670	memset(&sio_data, 0, sizeof(sio_data));2671 2672	address = f71882fg_find(0x2e, &sio_data);2673	if (address < 0)2674		address = f71882fg_find(0x4e, &sio_data);2675	if (address < 0)2676		return address;2677 2678	err = platform_driver_register(&f71882fg_driver);2679	if (err)2680		return err;2681 2682	err = f71882fg_device_add(address, &sio_data);2683	if (err)2684		goto exit_driver;2685 2686	return 0;2687 2688exit_driver:2689	platform_driver_unregister(&f71882fg_driver);2690	return err;2691}2692 2693static void __exit f71882fg_exit(void)2694{2695	platform_device_unregister(f71882fg_pdev);2696	platform_driver_unregister(&f71882fg_driver);2697}2698 2699MODULE_DESCRIPTION("F71882FG Hardware Monitoring Driver");2700MODULE_AUTHOR("Hans Edgington, Hans de Goede <hdegoede@redhat.com>");2701MODULE_LICENSE("GPL");2702 2703module_init(f71882fg_init);2704module_exit(f71882fg_exit);2705