xref: /openbmc/linux/drivers/hwmon/adm1031.c (revision e5e9f44c246fbafe723e579e9fe887677beb40e4)
18d5d45fbSJean Delvare /*
28d5d45fbSJean Delvare   adm1031.c - Part of lm_sensors, Linux kernel modules for hardware
38d5d45fbSJean Delvare   monitoring
48d5d45fbSJean Delvare   Based on lm75.c and lm85.c
58d5d45fbSJean Delvare   Supports adm1030 / adm1031
68d5d45fbSJean Delvare   Copyright (C) 2004 Alexandre d'Alton <alex@alexdalton.org>
78d5d45fbSJean Delvare   Reworked by Jean Delvare <khali@linux-fr.org>
88d5d45fbSJean Delvare 
98d5d45fbSJean Delvare   This program is free software; you can redistribute it and/or modify
108d5d45fbSJean Delvare   it under the terms of the GNU General Public License as published by
118d5d45fbSJean Delvare   the Free Software Foundation; either version 2 of the License, or
128d5d45fbSJean Delvare   (at your option) any later version.
138d5d45fbSJean Delvare 
148d5d45fbSJean Delvare   This program is distributed in the hope that it will be useful,
158d5d45fbSJean Delvare   but WITHOUT ANY WARRANTY; without even the implied warranty of
168d5d45fbSJean Delvare   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
178d5d45fbSJean Delvare   GNU General Public License for more details.
188d5d45fbSJean Delvare 
198d5d45fbSJean Delvare   You should have received a copy of the GNU General Public License
208d5d45fbSJean Delvare   along with this program; if not, write to the Free Software
218d5d45fbSJean Delvare   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
228d5d45fbSJean Delvare */
238d5d45fbSJean Delvare 
248d5d45fbSJean Delvare #include <linux/module.h>
258d5d45fbSJean Delvare #include <linux/init.h>
268d5d45fbSJean Delvare #include <linux/slab.h>
278d5d45fbSJean Delvare #include <linux/jiffies.h>
288d5d45fbSJean Delvare #include <linux/i2c.h>
29943b0830SMark M. Hoffman #include <linux/hwmon.h>
30c801082dSJean Delvare #include <linux/hwmon-sysfs.h>
31943b0830SMark M. Hoffman #include <linux/err.h>
329a61bf63SIngo Molnar #include <linux/mutex.h>
338d5d45fbSJean Delvare 
348d5d45fbSJean Delvare /* Following macros takes channel parameter starting from 0 to 2 */
358d5d45fbSJean Delvare #define ADM1031_REG_FAN_SPEED(nr)	(0x08 + (nr))
368d5d45fbSJean Delvare #define ADM1031_REG_FAN_DIV(nr)		(0x20 + (nr))
378d5d45fbSJean Delvare #define ADM1031_REG_PWM			(0x22)
388d5d45fbSJean Delvare #define ADM1031_REG_FAN_MIN(nr)		(0x10 + (nr))
398d5d45fbSJean Delvare 
4049dc9efeSIra Snyder #define ADM1031_REG_TEMP_OFFSET(nr)	(0x0d + (nr))
418d5d45fbSJean Delvare #define ADM1031_REG_TEMP_MAX(nr)	(0x14 + 4 * (nr))
428d5d45fbSJean Delvare #define ADM1031_REG_TEMP_MIN(nr)	(0x15 + 4 * (nr))
438d5d45fbSJean Delvare #define ADM1031_REG_TEMP_CRIT(nr)	(0x16 + 4 * (nr))
448d5d45fbSJean Delvare 
456d6006b8SJean Delvare #define ADM1031_REG_TEMP(nr)		(0x0a + (nr))
468d5d45fbSJean Delvare #define ADM1031_REG_AUTO_TEMP(nr)	(0x24 + (nr))
478d5d45fbSJean Delvare 
488d5d45fbSJean Delvare #define ADM1031_REG_STATUS(nr)		(0x2 + (nr))
498d5d45fbSJean Delvare 
506d6006b8SJean Delvare #define ADM1031_REG_CONF1		0x00
516d6006b8SJean Delvare #define ADM1031_REG_CONF2		0x01
526d6006b8SJean Delvare #define ADM1031_REG_EXT_TEMP		0x06
538d5d45fbSJean Delvare 
548d5d45fbSJean Delvare #define ADM1031_CONF1_MONITOR_ENABLE	0x01	/* Monitoring enable */
558d5d45fbSJean Delvare #define ADM1031_CONF1_PWM_INVERT	0x08	/* PWM Invert */
568d5d45fbSJean Delvare #define ADM1031_CONF1_AUTO_MODE		0x80	/* Auto FAN */
578d5d45fbSJean Delvare 
588d5d45fbSJean Delvare #define ADM1031_CONF2_PWM1_ENABLE	0x01
598d5d45fbSJean Delvare #define ADM1031_CONF2_PWM2_ENABLE	0x02
608d5d45fbSJean Delvare #define ADM1031_CONF2_TACH1_ENABLE	0x04
618d5d45fbSJean Delvare #define ADM1031_CONF2_TACH2_ENABLE	0x08
628d5d45fbSJean Delvare #define ADM1031_CONF2_TEMP_ENABLE(chan)	(0x10 << (chan))
638d5d45fbSJean Delvare 
648d5d45fbSJean Delvare /* Addresses to scan */
6525e9c86dSMark M. Hoffman static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
668d5d45fbSJean Delvare 
67*e5e9f44cSJean Delvare enum chips { adm1030, adm1031 };
688d5d45fbSJean Delvare 
698d5d45fbSJean Delvare typedef u8 auto_chan_table_t[8][2];
708d5d45fbSJean Delvare 
718d5d45fbSJean Delvare /* Each client has this additional data */
728d5d45fbSJean Delvare struct adm1031_data {
731beeffe4STony Jones 	struct device *hwmon_dev;
749a61bf63SIngo Molnar 	struct mutex update_lock;
758d5d45fbSJean Delvare 	int chip_type;
768d5d45fbSJean Delvare 	char valid;		/* !=0 if following fields are valid */
778d5d45fbSJean Delvare 	unsigned long last_updated;	/* In jiffies */
788d5d45fbSJean Delvare 	/* The chan_select_table contains the possible configurations for
798d5d45fbSJean Delvare 	 * auto fan control.
808d5d45fbSJean Delvare 	 */
816d6006b8SJean Delvare 	const auto_chan_table_t *chan_select_table;
828d5d45fbSJean Delvare 	u16 alarm;
838d5d45fbSJean Delvare 	u8 conf1;
848d5d45fbSJean Delvare 	u8 conf2;
858d5d45fbSJean Delvare 	u8 fan[2];
868d5d45fbSJean Delvare 	u8 fan_div[2];
878d5d45fbSJean Delvare 	u8 fan_min[2];
888d5d45fbSJean Delvare 	u8 pwm[2];
898d5d45fbSJean Delvare 	u8 old_pwm[2];
908d5d45fbSJean Delvare 	s8 temp[3];
918d5d45fbSJean Delvare 	u8 ext_temp[3];
928d5d45fbSJean Delvare 	u8 auto_temp[3];
938d5d45fbSJean Delvare 	u8 auto_temp_min[3];
948d5d45fbSJean Delvare 	u8 auto_temp_off[3];
958d5d45fbSJean Delvare 	u8 auto_temp_max[3];
9649dc9efeSIra Snyder 	s8 temp_offset[3];
978d5d45fbSJean Delvare 	s8 temp_min[3];
988d5d45fbSJean Delvare 	s8 temp_max[3];
998d5d45fbSJean Delvare 	s8 temp_crit[3];
1008d5d45fbSJean Delvare };
1018d5d45fbSJean Delvare 
102af200f88SJean Delvare static int adm1031_probe(struct i2c_client *client,
103af200f88SJean Delvare 			 const struct i2c_device_id *id);
104310ec792SJean Delvare static int adm1031_detect(struct i2c_client *client,
105af200f88SJean Delvare 			  struct i2c_board_info *info);
1068d5d45fbSJean Delvare static void adm1031_init_client(struct i2c_client *client);
107af200f88SJean Delvare static int adm1031_remove(struct i2c_client *client);
1088d5d45fbSJean Delvare static struct adm1031_data *adm1031_update_device(struct device *dev);
1098d5d45fbSJean Delvare 
110af200f88SJean Delvare static const struct i2c_device_id adm1031_id[] = {
111af200f88SJean Delvare 	{ "adm1030", adm1030 },
112af200f88SJean Delvare 	{ "adm1031", adm1031 },
113af200f88SJean Delvare 	{ }
114af200f88SJean Delvare };
115af200f88SJean Delvare MODULE_DEVICE_TABLE(i2c, adm1031_id);
116af200f88SJean Delvare 
1178d5d45fbSJean Delvare /* This is the driver that will be inserted */
1188d5d45fbSJean Delvare static struct i2c_driver adm1031_driver = {
119af200f88SJean Delvare 	.class		= I2C_CLASS_HWMON,
120cdaf7934SLaurent Riffard 	.driver = {
1218d5d45fbSJean Delvare 		.name = "adm1031",
122cdaf7934SLaurent Riffard 	},
123af200f88SJean Delvare 	.probe		= adm1031_probe,
124af200f88SJean Delvare 	.remove		= adm1031_remove,
125af200f88SJean Delvare 	.id_table	= adm1031_id,
126af200f88SJean Delvare 	.detect		= adm1031_detect,
127c3813d6aSJean Delvare 	.address_list	= normal_i2c,
1288d5d45fbSJean Delvare };
1298d5d45fbSJean Delvare 
1308d5d45fbSJean Delvare static inline u8 adm1031_read_value(struct i2c_client *client, u8 reg)
1318d5d45fbSJean Delvare {
1328d5d45fbSJean Delvare 	return i2c_smbus_read_byte_data(client, reg);
1338d5d45fbSJean Delvare }
1348d5d45fbSJean Delvare 
1358d5d45fbSJean Delvare static inline int
1368d5d45fbSJean Delvare adm1031_write_value(struct i2c_client *client, u8 reg, unsigned int value)
1378d5d45fbSJean Delvare {
1388d5d45fbSJean Delvare 	return i2c_smbus_write_byte_data(client, reg, value);
1398d5d45fbSJean Delvare }
1408d5d45fbSJean Delvare 
1418d5d45fbSJean Delvare 
1428d5d45fbSJean Delvare #define TEMP_TO_REG(val)		(((val) < 0 ? ((val - 500) / 1000) : \
1438d5d45fbSJean Delvare 					((val + 500) / 1000)))
1448d5d45fbSJean Delvare 
1458d5d45fbSJean Delvare #define TEMP_FROM_REG(val)		((val) * 1000)
1468d5d45fbSJean Delvare 
1478d5d45fbSJean Delvare #define TEMP_FROM_REG_EXT(val, ext)	(TEMP_FROM_REG(val) + (ext) * 125)
1488d5d45fbSJean Delvare 
14949dc9efeSIra Snyder #define TEMP_OFFSET_TO_REG(val)		(TEMP_TO_REG(val) & 0x8f)
15049dc9efeSIra Snyder #define TEMP_OFFSET_FROM_REG(val)	TEMP_FROM_REG((val) < 0 ? \
15149dc9efeSIra Snyder 						      (val) | 0x70 : (val))
15249dc9efeSIra Snyder 
1538d5d45fbSJean Delvare #define FAN_FROM_REG(reg, div)		((reg) ? (11250 * 60) / ((reg) * (div)) : 0)
1548d5d45fbSJean Delvare 
1558d5d45fbSJean Delvare static int FAN_TO_REG(int reg, int div)
1568d5d45fbSJean Delvare {
1578d5d45fbSJean Delvare 	int tmp;
1588d5d45fbSJean Delvare 	tmp = FAN_FROM_REG(SENSORS_LIMIT(reg, 0, 65535), div);
1598d5d45fbSJean Delvare 	return tmp > 255 ? 255 : tmp;
1608d5d45fbSJean Delvare }
1618d5d45fbSJean Delvare 
1628d5d45fbSJean Delvare #define FAN_DIV_FROM_REG(reg)		(1<<(((reg)&0xc0)>>6))
1638d5d45fbSJean Delvare 
1648d5d45fbSJean Delvare #define PWM_TO_REG(val)			(SENSORS_LIMIT((val), 0, 255) >> 4)
1658d5d45fbSJean Delvare #define PWM_FROM_REG(val)		((val) << 4)
1668d5d45fbSJean Delvare 
1678d5d45fbSJean Delvare #define FAN_CHAN_FROM_REG(reg)		(((reg) >> 5) & 7)
1688d5d45fbSJean Delvare #define FAN_CHAN_TO_REG(val, reg)	\
1698d5d45fbSJean Delvare 	(((reg) & 0x1F) | (((val) << 5) & 0xe0))
1708d5d45fbSJean Delvare 
1718d5d45fbSJean Delvare #define AUTO_TEMP_MIN_TO_REG(val, reg)	\
1728d5d45fbSJean Delvare 	((((val)/500) & 0xf8)|((reg) & 0x7))
1738d5d45fbSJean Delvare #define AUTO_TEMP_RANGE_FROM_REG(reg)	(5000 * (1<< ((reg)&0x7)))
1748d5d45fbSJean Delvare #define AUTO_TEMP_MIN_FROM_REG(reg)	(1000 * ((((reg) >> 3) & 0x1f) << 2))
1758d5d45fbSJean Delvare 
1768d5d45fbSJean Delvare #define AUTO_TEMP_MIN_FROM_REG_DEG(reg)	((((reg) >> 3) & 0x1f) << 2)
1778d5d45fbSJean Delvare 
1788d5d45fbSJean Delvare #define AUTO_TEMP_OFF_FROM_REG(reg)		\
1798d5d45fbSJean Delvare 	(AUTO_TEMP_MIN_FROM_REG(reg) - 5000)
1808d5d45fbSJean Delvare 
1818d5d45fbSJean Delvare #define AUTO_TEMP_MAX_FROM_REG(reg)		\
1828d5d45fbSJean Delvare 	(AUTO_TEMP_RANGE_FROM_REG(reg) +	\
1838d5d45fbSJean Delvare 	AUTO_TEMP_MIN_FROM_REG(reg))
1848d5d45fbSJean Delvare 
1858d5d45fbSJean Delvare static int AUTO_TEMP_MAX_TO_REG(int val, int reg, int pwm)
1868d5d45fbSJean Delvare {
1878d5d45fbSJean Delvare 	int ret;
1888d5d45fbSJean Delvare 	int range = val - AUTO_TEMP_MIN_FROM_REG(reg);
1898d5d45fbSJean Delvare 
1908d5d45fbSJean Delvare 	range = ((val - AUTO_TEMP_MIN_FROM_REG(reg))*10)/(16 - pwm);
1918d5d45fbSJean Delvare 	ret = ((reg & 0xf8) |
1928d5d45fbSJean Delvare 	       (range < 10000 ? 0 :
1938d5d45fbSJean Delvare 		range < 20000 ? 1 :
1948d5d45fbSJean Delvare 		range < 40000 ? 2 : range < 80000 ? 3 : 4));
1958d5d45fbSJean Delvare 	return ret;
1968d5d45fbSJean Delvare }
1978d5d45fbSJean Delvare 
1988d5d45fbSJean Delvare /* FAN auto control */
1998d5d45fbSJean Delvare #define GET_FAN_AUTO_BITFIELD(data, idx)	\
2008d5d45fbSJean Delvare 	(*(data)->chan_select_table)[FAN_CHAN_FROM_REG((data)->conf1)][idx%2]
2018d5d45fbSJean Delvare 
2028d5d45fbSJean Delvare /* The tables below contains the possible values for the auto fan
2038d5d45fbSJean Delvare  * control bitfields. the index in the table is the register value.
2048d5d45fbSJean Delvare  * MSb is the auto fan control enable bit, so the four first entries
2058d5d45fbSJean Delvare  * in the table disables auto fan control when both bitfields are zero.
2068d5d45fbSJean Delvare  */
2076d6006b8SJean Delvare static const auto_chan_table_t auto_channel_select_table_adm1031 = {
2088d5d45fbSJean Delvare 	{ 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 },
2098d5d45fbSJean Delvare 	{ 2 /* 0b010 */ , 4 /* 0b100 */ },
2108d5d45fbSJean Delvare 	{ 2 /* 0b010 */ , 2 /* 0b010 */ },
2118d5d45fbSJean Delvare 	{ 4 /* 0b100 */ , 4 /* 0b100 */ },
2128d5d45fbSJean Delvare 	{ 7 /* 0b111 */ , 7 /* 0b111 */ },
2138d5d45fbSJean Delvare };
2148d5d45fbSJean Delvare 
2156d6006b8SJean Delvare static const auto_chan_table_t auto_channel_select_table_adm1030 = {
2168d5d45fbSJean Delvare 	{ 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 },
2178d5d45fbSJean Delvare 	{ 2 /* 0b10 */		, 0 },
2188d5d45fbSJean Delvare 	{ 0xff /* invalid */	, 0 },
2198d5d45fbSJean Delvare 	{ 0xff /* invalid */	, 0 },
2208d5d45fbSJean Delvare 	{ 3 /* 0b11 */		, 0 },
2218d5d45fbSJean Delvare };
2228d5d45fbSJean Delvare 
2238d5d45fbSJean Delvare /* That function checks if a bitfield is valid and returns the other bitfield
2248d5d45fbSJean Delvare  * nearest match if no exact match where found.
2258d5d45fbSJean Delvare  */
2268d5d45fbSJean Delvare static int
2278d5d45fbSJean Delvare get_fan_auto_nearest(struct adm1031_data *data,
2288d5d45fbSJean Delvare 		     int chan, u8 val, u8 reg, u8 * new_reg)
2298d5d45fbSJean Delvare {
2308d5d45fbSJean Delvare 	int i;
2318d5d45fbSJean Delvare 	int first_match = -1, exact_match = -1;
2328d5d45fbSJean Delvare 	u8 other_reg_val =
2338d5d45fbSJean Delvare 	    (*data->chan_select_table)[FAN_CHAN_FROM_REG(reg)][chan ? 0 : 1];
2348d5d45fbSJean Delvare 
2358d5d45fbSJean Delvare 	if (val == 0) {
2368d5d45fbSJean Delvare 		*new_reg = 0;
2378d5d45fbSJean Delvare 		return 0;
2388d5d45fbSJean Delvare 	}
2398d5d45fbSJean Delvare 
2408d5d45fbSJean Delvare 	for (i = 0; i < 8; i++) {
2418d5d45fbSJean Delvare 		if ((val == (*data->chan_select_table)[i][chan]) &&
2428d5d45fbSJean Delvare 		    ((*data->chan_select_table)[i][chan ? 0 : 1] ==
2438d5d45fbSJean Delvare 		     other_reg_val)) {
2448d5d45fbSJean Delvare 			/* We found an exact match */
2458d5d45fbSJean Delvare 			exact_match = i;
2468d5d45fbSJean Delvare 			break;
2478d5d45fbSJean Delvare 		} else if (val == (*data->chan_select_table)[i][chan] &&
2488d5d45fbSJean Delvare 			   first_match == -1) {
2496d6006b8SJean Delvare 			/* Save the first match in case of an exact match has
2506d6006b8SJean Delvare 			 * not been found
2518d5d45fbSJean Delvare 			 */
2528d5d45fbSJean Delvare 			first_match = i;
2538d5d45fbSJean Delvare 		}
2548d5d45fbSJean Delvare 	}
2558d5d45fbSJean Delvare 
2568d5d45fbSJean Delvare 	if (exact_match >= 0) {
2578d5d45fbSJean Delvare 		*new_reg = exact_match;
2588d5d45fbSJean Delvare 	} else if (first_match >= 0) {
2598d5d45fbSJean Delvare 		*new_reg = first_match;
2608d5d45fbSJean Delvare 	} else {
2618d5d45fbSJean Delvare 		return -EINVAL;
2628d5d45fbSJean Delvare 	}
2638d5d45fbSJean Delvare 	return 0;
2648d5d45fbSJean Delvare }
2658d5d45fbSJean Delvare 
266c801082dSJean Delvare static ssize_t show_fan_auto_channel(struct device *dev,
267c801082dSJean Delvare 				     struct device_attribute *attr, char *buf)
2688d5d45fbSJean Delvare {
269c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
2708d5d45fbSJean Delvare 	struct adm1031_data *data = adm1031_update_device(dev);
2718d5d45fbSJean Delvare 	return sprintf(buf, "%d\n", GET_FAN_AUTO_BITFIELD(data, nr));
2728d5d45fbSJean Delvare }
2738d5d45fbSJean Delvare 
2748d5d45fbSJean Delvare static ssize_t
275c801082dSJean Delvare set_fan_auto_channel(struct device *dev, struct device_attribute *attr,
276c801082dSJean Delvare 		     const char *buf, size_t count)
2778d5d45fbSJean Delvare {
2788d5d45fbSJean Delvare 	struct i2c_client *client = to_i2c_client(dev);
2798d5d45fbSJean Delvare 	struct adm1031_data *data = i2c_get_clientdata(client);
280c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
2818d5d45fbSJean Delvare 	int val = simple_strtol(buf, NULL, 10);
2828d5d45fbSJean Delvare 	u8 reg;
2838d5d45fbSJean Delvare 	int ret;
2848d5d45fbSJean Delvare 	u8 old_fan_mode;
2858d5d45fbSJean Delvare 
2868d5d45fbSJean Delvare 	old_fan_mode = data->conf1;
2878d5d45fbSJean Delvare 
2889a61bf63SIngo Molnar 	mutex_lock(&data->update_lock);
2898d5d45fbSJean Delvare 
2908d5d45fbSJean Delvare 	if ((ret = get_fan_auto_nearest(data, nr, val, data->conf1, &reg))) {
2919a61bf63SIngo Molnar 		mutex_unlock(&data->update_lock);
2928d5d45fbSJean Delvare 		return ret;
2938d5d45fbSJean Delvare 	}
2946d6006b8SJean Delvare 	data->conf1 = FAN_CHAN_TO_REG(reg, data->conf1);
2956d6006b8SJean Delvare 	if ((data->conf1 & ADM1031_CONF1_AUTO_MODE) ^
2968d5d45fbSJean Delvare 	    (old_fan_mode & ADM1031_CONF1_AUTO_MODE)) {
2978d5d45fbSJean Delvare 		if (data->conf1 & ADM1031_CONF1_AUTO_MODE){
2988d5d45fbSJean Delvare 			/* Switch to Auto Fan Mode
2998d5d45fbSJean Delvare 			 * Save PWM registers
3008d5d45fbSJean Delvare 			 * Set PWM registers to 33% Both */
3018d5d45fbSJean Delvare 			data->old_pwm[0] = data->pwm[0];
3028d5d45fbSJean Delvare 			data->old_pwm[1] = data->pwm[1];
3038d5d45fbSJean Delvare 			adm1031_write_value(client, ADM1031_REG_PWM, 0x55);
3048d5d45fbSJean Delvare 		} else {
3058d5d45fbSJean Delvare 			/* Switch to Manual Mode */
3068d5d45fbSJean Delvare 			data->pwm[0] = data->old_pwm[0];
3078d5d45fbSJean Delvare 			data->pwm[1] = data->old_pwm[1];
3088d5d45fbSJean Delvare 			/* Restore PWM registers */
3098d5d45fbSJean Delvare 			adm1031_write_value(client, ADM1031_REG_PWM,
3108d5d45fbSJean Delvare 					    data->pwm[0] | (data->pwm[1] << 4));
3118d5d45fbSJean Delvare 		}
3128d5d45fbSJean Delvare 	}
3138d5d45fbSJean Delvare 	data->conf1 = FAN_CHAN_TO_REG(reg, data->conf1);
3148d5d45fbSJean Delvare 	adm1031_write_value(client, ADM1031_REG_CONF1, data->conf1);
3159a61bf63SIngo Molnar 	mutex_unlock(&data->update_lock);
3168d5d45fbSJean Delvare 	return count;
3178d5d45fbSJean Delvare }
3188d5d45fbSJean Delvare 
319c801082dSJean Delvare static SENSOR_DEVICE_ATTR(auto_fan1_channel, S_IRUGO | S_IWUSR,
320c801082dSJean Delvare 		show_fan_auto_channel, set_fan_auto_channel, 0);
321c801082dSJean Delvare static SENSOR_DEVICE_ATTR(auto_fan2_channel, S_IRUGO | S_IWUSR,
322c801082dSJean Delvare 		show_fan_auto_channel, set_fan_auto_channel, 1);
3238d5d45fbSJean Delvare 
3248d5d45fbSJean Delvare /* Auto Temps */
325c801082dSJean Delvare static ssize_t show_auto_temp_off(struct device *dev,
326c801082dSJean Delvare 				  struct device_attribute *attr, char *buf)
3278d5d45fbSJean Delvare {
328c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
3298d5d45fbSJean Delvare 	struct adm1031_data *data = adm1031_update_device(dev);
3308d5d45fbSJean Delvare 	return sprintf(buf, "%d\n",
3318d5d45fbSJean Delvare 		       AUTO_TEMP_OFF_FROM_REG(data->auto_temp[nr]));
3328d5d45fbSJean Delvare }
333c801082dSJean Delvare static ssize_t show_auto_temp_min(struct device *dev,
334c801082dSJean Delvare 				  struct device_attribute *attr, char *buf)
3358d5d45fbSJean Delvare {
336c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
3378d5d45fbSJean Delvare 	struct adm1031_data *data = adm1031_update_device(dev);
3388d5d45fbSJean Delvare 	return sprintf(buf, "%d\n",
3398d5d45fbSJean Delvare 		       AUTO_TEMP_MIN_FROM_REG(data->auto_temp[nr]));
3408d5d45fbSJean Delvare }
3418d5d45fbSJean Delvare static ssize_t
342c801082dSJean Delvare set_auto_temp_min(struct device *dev, struct device_attribute *attr,
343c801082dSJean Delvare 		  const char *buf, size_t count)
3448d5d45fbSJean Delvare {
3458d5d45fbSJean Delvare 	struct i2c_client *client = to_i2c_client(dev);
3468d5d45fbSJean Delvare 	struct adm1031_data *data = i2c_get_clientdata(client);
347c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
3488d5d45fbSJean Delvare 	int val = simple_strtol(buf, NULL, 10);
3498d5d45fbSJean Delvare 
3509a61bf63SIngo Molnar 	mutex_lock(&data->update_lock);
3518d5d45fbSJean Delvare 	data->auto_temp[nr] = AUTO_TEMP_MIN_TO_REG(val, data->auto_temp[nr]);
3528d5d45fbSJean Delvare 	adm1031_write_value(client, ADM1031_REG_AUTO_TEMP(nr),
3538d5d45fbSJean Delvare 			    data->auto_temp[nr]);
3549a61bf63SIngo Molnar 	mutex_unlock(&data->update_lock);
3558d5d45fbSJean Delvare 	return count;
3568d5d45fbSJean Delvare }
357c801082dSJean Delvare static ssize_t show_auto_temp_max(struct device *dev,
358c801082dSJean Delvare 				  struct device_attribute *attr, char *buf)
3598d5d45fbSJean Delvare {
360c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
3618d5d45fbSJean Delvare 	struct adm1031_data *data = adm1031_update_device(dev);
3628d5d45fbSJean Delvare 	return sprintf(buf, "%d\n",
3638d5d45fbSJean Delvare 		       AUTO_TEMP_MAX_FROM_REG(data->auto_temp[nr]));
3648d5d45fbSJean Delvare }
3658d5d45fbSJean Delvare static ssize_t
366c801082dSJean Delvare set_auto_temp_max(struct device *dev, struct device_attribute *attr,
367c801082dSJean Delvare 		  const char *buf, size_t count)
3688d5d45fbSJean Delvare {
3698d5d45fbSJean Delvare 	struct i2c_client *client = to_i2c_client(dev);
3708d5d45fbSJean Delvare 	struct adm1031_data *data = i2c_get_clientdata(client);
371c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
3728d5d45fbSJean Delvare 	int val = simple_strtol(buf, NULL, 10);
3738d5d45fbSJean Delvare 
3749a61bf63SIngo Molnar 	mutex_lock(&data->update_lock);
3758d5d45fbSJean Delvare 	data->temp_max[nr] = AUTO_TEMP_MAX_TO_REG(val, data->auto_temp[nr], data->pwm[nr]);
3768d5d45fbSJean Delvare 	adm1031_write_value(client, ADM1031_REG_AUTO_TEMP(nr),
3778d5d45fbSJean Delvare 			    data->temp_max[nr]);
3789a61bf63SIngo Molnar 	mutex_unlock(&data->update_lock);
3798d5d45fbSJean Delvare 	return count;
3808d5d45fbSJean Delvare }
3818d5d45fbSJean Delvare 
3828d5d45fbSJean Delvare #define auto_temp_reg(offset)						\
383c801082dSJean Delvare static SENSOR_DEVICE_ATTR(auto_temp##offset##_off, S_IRUGO,		\
384c801082dSJean Delvare 		show_auto_temp_off, NULL, offset - 1);			\
385c801082dSJean Delvare static SENSOR_DEVICE_ATTR(auto_temp##offset##_min, S_IRUGO | S_IWUSR,	\
386c801082dSJean Delvare 		show_auto_temp_min, set_auto_temp_min, offset - 1);	\
387c801082dSJean Delvare static SENSOR_DEVICE_ATTR(auto_temp##offset##_max, S_IRUGO | S_IWUSR,	\
388c801082dSJean Delvare 		show_auto_temp_max, set_auto_temp_max, offset - 1)
3898d5d45fbSJean Delvare 
3908d5d45fbSJean Delvare auto_temp_reg(1);
3918d5d45fbSJean Delvare auto_temp_reg(2);
3928d5d45fbSJean Delvare auto_temp_reg(3);
3938d5d45fbSJean Delvare 
3948d5d45fbSJean Delvare /* pwm */
395c801082dSJean Delvare static ssize_t show_pwm(struct device *dev,
396c801082dSJean Delvare 			struct device_attribute *attr, char *buf)
3978d5d45fbSJean Delvare {
398c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
3998d5d45fbSJean Delvare 	struct adm1031_data *data = adm1031_update_device(dev);
4008d5d45fbSJean Delvare 	return sprintf(buf, "%d\n", PWM_FROM_REG(data->pwm[nr]));
4018d5d45fbSJean Delvare }
402c801082dSJean Delvare static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
403c801082dSJean Delvare 		       const char *buf, size_t count)
4048d5d45fbSJean Delvare {
4058d5d45fbSJean Delvare 	struct i2c_client *client = to_i2c_client(dev);
4068d5d45fbSJean Delvare 	struct adm1031_data *data = i2c_get_clientdata(client);
407c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
4088d5d45fbSJean Delvare 	int val = simple_strtol(buf, NULL, 10);
4098d5d45fbSJean Delvare 	int reg;
4108d5d45fbSJean Delvare 
4119a61bf63SIngo Molnar 	mutex_lock(&data->update_lock);
4128d5d45fbSJean Delvare 	if ((data->conf1 & ADM1031_CONF1_AUTO_MODE) &&
4138d5d45fbSJean Delvare 	    (((val>>4) & 0xf) != 5)) {
4148d5d45fbSJean Delvare 		/* In automatic mode, the only PWM accepted is 33% */
4159a61bf63SIngo Molnar 		mutex_unlock(&data->update_lock);
4168d5d45fbSJean Delvare 		return -EINVAL;
4178d5d45fbSJean Delvare 	}
4188d5d45fbSJean Delvare 	data->pwm[nr] = PWM_TO_REG(val);
4198d5d45fbSJean Delvare 	reg = adm1031_read_value(client, ADM1031_REG_PWM);
4208d5d45fbSJean Delvare 	adm1031_write_value(client, ADM1031_REG_PWM,
4218d5d45fbSJean Delvare 			    nr ? ((data->pwm[nr] << 4) & 0xf0) | (reg & 0xf)
4228d5d45fbSJean Delvare 			    : (data->pwm[nr] & 0xf) | (reg & 0xf0));
4239a61bf63SIngo Molnar 	mutex_unlock(&data->update_lock);
4248d5d45fbSJean Delvare 	return count;
4258d5d45fbSJean Delvare }
4268d5d45fbSJean Delvare 
427c801082dSJean Delvare static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 0);
428c801082dSJean Delvare static SENSOR_DEVICE_ATTR(pwm2, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 1);
429c801082dSJean Delvare static SENSOR_DEVICE_ATTR(auto_fan1_min_pwm, S_IRUGO | S_IWUSR,
430c801082dSJean Delvare 		show_pwm, set_pwm, 0);
431c801082dSJean Delvare static SENSOR_DEVICE_ATTR(auto_fan2_min_pwm, S_IRUGO | S_IWUSR,
432c801082dSJean Delvare 		show_pwm, set_pwm, 1);
4338d5d45fbSJean Delvare 
4348d5d45fbSJean Delvare /* Fans */
4358d5d45fbSJean Delvare 
4368d5d45fbSJean Delvare /*
4378d5d45fbSJean Delvare  * That function checks the cases where the fan reading is not
4388d5d45fbSJean Delvare  * relevant.  It is used to provide 0 as fan reading when the fan is
4398d5d45fbSJean Delvare  * not supposed to run
4408d5d45fbSJean Delvare  */
4418d5d45fbSJean Delvare static int trust_fan_readings(struct adm1031_data *data, int chan)
4428d5d45fbSJean Delvare {
4438d5d45fbSJean Delvare 	int res = 0;
4448d5d45fbSJean Delvare 
4458d5d45fbSJean Delvare 	if (data->conf1 & ADM1031_CONF1_AUTO_MODE) {
4468d5d45fbSJean Delvare 		switch (data->conf1 & 0x60) {
4478d5d45fbSJean Delvare 		case 0x00:	/* remote temp1 controls fan1 remote temp2 controls fan2 */
4488d5d45fbSJean Delvare 			res = data->temp[chan+1] >=
4498d5d45fbSJean Delvare 			      AUTO_TEMP_MIN_FROM_REG_DEG(data->auto_temp[chan+1]);
4508d5d45fbSJean Delvare 			break;
4518d5d45fbSJean Delvare 		case 0x20:	/* remote temp1 controls both fans */
4528d5d45fbSJean Delvare 			res =
4538d5d45fbSJean Delvare 			    data->temp[1] >=
4548d5d45fbSJean Delvare 			    AUTO_TEMP_MIN_FROM_REG_DEG(data->auto_temp[1]);
4558d5d45fbSJean Delvare 			break;
4568d5d45fbSJean Delvare 		case 0x40:	/* remote temp2 controls both fans */
4578d5d45fbSJean Delvare 			res =
4588d5d45fbSJean Delvare 			    data->temp[2] >=
4598d5d45fbSJean Delvare 			    AUTO_TEMP_MIN_FROM_REG_DEG(data->auto_temp[2]);
4608d5d45fbSJean Delvare 			break;
4618d5d45fbSJean Delvare 		case 0x60:	/* max controls both fans */
4628d5d45fbSJean Delvare 			res =
4638d5d45fbSJean Delvare 			    data->temp[0] >=
4648d5d45fbSJean Delvare 			    AUTO_TEMP_MIN_FROM_REG_DEG(data->auto_temp[0])
4658d5d45fbSJean Delvare 			    || data->temp[1] >=
4668d5d45fbSJean Delvare 			    AUTO_TEMP_MIN_FROM_REG_DEG(data->auto_temp[1])
4678d5d45fbSJean Delvare 			    || (data->chip_type == adm1031
4688d5d45fbSJean Delvare 				&& data->temp[2] >=
4698d5d45fbSJean Delvare 				AUTO_TEMP_MIN_FROM_REG_DEG(data->auto_temp[2]));
4708d5d45fbSJean Delvare 			break;
4718d5d45fbSJean Delvare 		}
4728d5d45fbSJean Delvare 	} else {
4738d5d45fbSJean Delvare 		res = data->pwm[chan] > 0;
4748d5d45fbSJean Delvare 	}
4758d5d45fbSJean Delvare 	return res;
4768d5d45fbSJean Delvare }
4778d5d45fbSJean Delvare 
4788d5d45fbSJean Delvare 
479c801082dSJean Delvare static ssize_t show_fan(struct device *dev,
480c801082dSJean Delvare 			struct device_attribute *attr, char *buf)
4818d5d45fbSJean Delvare {
482c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
4838d5d45fbSJean Delvare 	struct adm1031_data *data = adm1031_update_device(dev);
4848d5d45fbSJean Delvare 	int value;
4858d5d45fbSJean Delvare 
4868d5d45fbSJean Delvare 	value = trust_fan_readings(data, nr) ? FAN_FROM_REG(data->fan[nr],
4878d5d45fbSJean Delvare 				 FAN_DIV_FROM_REG(data->fan_div[nr])) : 0;
4888d5d45fbSJean Delvare 	return sprintf(buf, "%d\n", value);
4898d5d45fbSJean Delvare }
4908d5d45fbSJean Delvare 
491c801082dSJean Delvare static ssize_t show_fan_div(struct device *dev,
492c801082dSJean Delvare 			    struct device_attribute *attr, char *buf)
4938d5d45fbSJean Delvare {
494c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
4958d5d45fbSJean Delvare 	struct adm1031_data *data = adm1031_update_device(dev);
4968d5d45fbSJean Delvare 	return sprintf(buf, "%d\n", FAN_DIV_FROM_REG(data->fan_div[nr]));
4978d5d45fbSJean Delvare }
498c801082dSJean Delvare static ssize_t show_fan_min(struct device *dev,
499c801082dSJean Delvare 			    struct device_attribute *attr, char *buf)
5008d5d45fbSJean Delvare {
501c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
5028d5d45fbSJean Delvare 	struct adm1031_data *data = adm1031_update_device(dev);
5038d5d45fbSJean Delvare 	return sprintf(buf, "%d\n",
5048d5d45fbSJean Delvare 		       FAN_FROM_REG(data->fan_min[nr],
5058d5d45fbSJean Delvare 				    FAN_DIV_FROM_REG(data->fan_div[nr])));
5068d5d45fbSJean Delvare }
507c801082dSJean Delvare static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
508c801082dSJean Delvare 			   const char *buf, size_t count)
5098d5d45fbSJean Delvare {
5108d5d45fbSJean Delvare 	struct i2c_client *client = to_i2c_client(dev);
5118d5d45fbSJean Delvare 	struct adm1031_data *data = i2c_get_clientdata(client);
512c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
5138d5d45fbSJean Delvare 	int val = simple_strtol(buf, NULL, 10);
5148d5d45fbSJean Delvare 
5159a61bf63SIngo Molnar 	mutex_lock(&data->update_lock);
5168d5d45fbSJean Delvare 	if (val) {
5178d5d45fbSJean Delvare 		data->fan_min[nr] =
5188d5d45fbSJean Delvare 			FAN_TO_REG(val, FAN_DIV_FROM_REG(data->fan_div[nr]));
5198d5d45fbSJean Delvare 	} else {
5208d5d45fbSJean Delvare 		data->fan_min[nr] = 0xff;
5218d5d45fbSJean Delvare 	}
5228d5d45fbSJean Delvare 	adm1031_write_value(client, ADM1031_REG_FAN_MIN(nr), data->fan_min[nr]);
5239a61bf63SIngo Molnar 	mutex_unlock(&data->update_lock);
5248d5d45fbSJean Delvare 	return count;
5258d5d45fbSJean Delvare }
526c801082dSJean Delvare static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
527c801082dSJean Delvare 			   const char *buf, size_t count)
5288d5d45fbSJean Delvare {
5298d5d45fbSJean Delvare 	struct i2c_client *client = to_i2c_client(dev);
5308d5d45fbSJean Delvare 	struct adm1031_data *data = i2c_get_clientdata(client);
531c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
5328d5d45fbSJean Delvare 	int val = simple_strtol(buf, NULL, 10);
5338d5d45fbSJean Delvare 	u8 tmp;
5348d5d45fbSJean Delvare 	int old_div;
5358d5d45fbSJean Delvare 	int new_min;
5368d5d45fbSJean Delvare 
5378d5d45fbSJean Delvare 	tmp = val == 8 ? 0xc0 :
5388d5d45fbSJean Delvare 	      val == 4 ? 0x80 :
5398d5d45fbSJean Delvare 	      val == 2 ? 0x40 :
5408d5d45fbSJean Delvare 	      val == 1 ? 0x00 :
5418d5d45fbSJean Delvare 	      0xff;
5428d5d45fbSJean Delvare 	if (tmp == 0xff)
5438d5d45fbSJean Delvare 		return -EINVAL;
5448d5d45fbSJean Delvare 
5459a61bf63SIngo Molnar 	mutex_lock(&data->update_lock);
54638a1f0e9SJean Delvare 	/* Get fresh readings */
54738a1f0e9SJean Delvare 	data->fan_div[nr] = adm1031_read_value(client,
54838a1f0e9SJean Delvare 					       ADM1031_REG_FAN_DIV(nr));
54938a1f0e9SJean Delvare 	data->fan_min[nr] = adm1031_read_value(client,
55038a1f0e9SJean Delvare 					       ADM1031_REG_FAN_MIN(nr));
55138a1f0e9SJean Delvare 
55238a1f0e9SJean Delvare 	/* Write the new clock divider and fan min */
5538d5d45fbSJean Delvare 	old_div = FAN_DIV_FROM_REG(data->fan_div[nr]);
5546d6006b8SJean Delvare 	data->fan_div[nr] = tmp | (0x3f & data->fan_div[nr]);
5556d6006b8SJean Delvare 	new_min = data->fan_min[nr] * old_div / val;
5568d5d45fbSJean Delvare 	data->fan_min[nr] = new_min > 0xff ? 0xff : new_min;
5578d5d45fbSJean Delvare 
5588d5d45fbSJean Delvare 	adm1031_write_value(client, ADM1031_REG_FAN_DIV(nr),
5598d5d45fbSJean Delvare 			    data->fan_div[nr]);
5608d5d45fbSJean Delvare 	adm1031_write_value(client, ADM1031_REG_FAN_MIN(nr),
5618d5d45fbSJean Delvare 			    data->fan_min[nr]);
56238a1f0e9SJean Delvare 
56338a1f0e9SJean Delvare 	/* Invalidate the cache: fan speed is no longer valid */
56438a1f0e9SJean Delvare 	data->valid = 0;
5659a61bf63SIngo Molnar 	mutex_unlock(&data->update_lock);
5668d5d45fbSJean Delvare 	return count;
5678d5d45fbSJean Delvare }
5688d5d45fbSJean Delvare 
5698d5d45fbSJean Delvare #define fan_offset(offset)						\
570c801082dSJean Delvare static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO,			\
571c801082dSJean Delvare 		show_fan, NULL, offset - 1);				\
572c801082dSJean Delvare static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR,		\
573c801082dSJean Delvare 		show_fan_min, set_fan_min, offset - 1);			\
574c801082dSJean Delvare static SENSOR_DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR,		\
575c801082dSJean Delvare 		show_fan_div, set_fan_div, offset - 1)
5768d5d45fbSJean Delvare 
5778d5d45fbSJean Delvare fan_offset(1);
5788d5d45fbSJean Delvare fan_offset(2);
5798d5d45fbSJean Delvare 
5808d5d45fbSJean Delvare 
5818d5d45fbSJean Delvare /* Temps */
582c801082dSJean Delvare static ssize_t show_temp(struct device *dev,
583c801082dSJean Delvare 			 struct device_attribute *attr, char *buf)
5848d5d45fbSJean Delvare {
585c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
5868d5d45fbSJean Delvare 	struct adm1031_data *data = adm1031_update_device(dev);
5878d5d45fbSJean Delvare 	int ext;
5888d5d45fbSJean Delvare 	ext = nr == 0 ?
5898d5d45fbSJean Delvare 	    ((data->ext_temp[nr] >> 6) & 0x3) * 2 :
5908d5d45fbSJean Delvare 	    (((data->ext_temp[nr] >> ((nr - 1) * 3)) & 7));
5918d5d45fbSJean Delvare 	return sprintf(buf, "%d\n", TEMP_FROM_REG_EXT(data->temp[nr], ext));
5928d5d45fbSJean Delvare }
59349dc9efeSIra Snyder static ssize_t show_temp_offset(struct device *dev,
59449dc9efeSIra Snyder 				struct device_attribute *attr, char *buf)
59549dc9efeSIra Snyder {
59649dc9efeSIra Snyder 	int nr = to_sensor_dev_attr(attr)->index;
59749dc9efeSIra Snyder 	struct adm1031_data *data = adm1031_update_device(dev);
59849dc9efeSIra Snyder 	return sprintf(buf, "%d\n",
59949dc9efeSIra Snyder 		       TEMP_OFFSET_FROM_REG(data->temp_offset[nr]));
60049dc9efeSIra Snyder }
601c801082dSJean Delvare static ssize_t show_temp_min(struct device *dev,
602c801082dSJean Delvare 			     struct device_attribute *attr, char *buf)
6038d5d45fbSJean Delvare {
604c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
6058d5d45fbSJean Delvare 	struct adm1031_data *data = adm1031_update_device(dev);
6068d5d45fbSJean Delvare 	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_min[nr]));
6078d5d45fbSJean Delvare }
608c801082dSJean Delvare static ssize_t show_temp_max(struct device *dev,
609c801082dSJean Delvare 			     struct device_attribute *attr, char *buf)
6108d5d45fbSJean Delvare {
611c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
6128d5d45fbSJean Delvare 	struct adm1031_data *data = adm1031_update_device(dev);
6138d5d45fbSJean Delvare 	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_max[nr]));
6148d5d45fbSJean Delvare }
615c801082dSJean Delvare static ssize_t show_temp_crit(struct device *dev,
616c801082dSJean Delvare 			      struct device_attribute *attr, char *buf)
6178d5d45fbSJean Delvare {
618c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
6198d5d45fbSJean Delvare 	struct adm1031_data *data = adm1031_update_device(dev);
6208d5d45fbSJean Delvare 	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_crit[nr]));
6218d5d45fbSJean Delvare }
62249dc9efeSIra Snyder static ssize_t set_temp_offset(struct device *dev,
62349dc9efeSIra Snyder 			       struct device_attribute *attr, const char *buf,
62449dc9efeSIra Snyder 			       size_t count)
62549dc9efeSIra Snyder {
62649dc9efeSIra Snyder 	struct i2c_client *client = to_i2c_client(dev);
62749dc9efeSIra Snyder 	struct adm1031_data *data = i2c_get_clientdata(client);
62849dc9efeSIra Snyder 	int nr = to_sensor_dev_attr(attr)->index;
62949dc9efeSIra Snyder 	int val;
63049dc9efeSIra Snyder 
63149dc9efeSIra Snyder 	val = simple_strtol(buf, NULL, 10);
63249dc9efeSIra Snyder 	val = SENSORS_LIMIT(val, -15000, 15000);
63349dc9efeSIra Snyder 	mutex_lock(&data->update_lock);
63449dc9efeSIra Snyder 	data->temp_offset[nr] = TEMP_OFFSET_TO_REG(val);
63549dc9efeSIra Snyder 	adm1031_write_value(client, ADM1031_REG_TEMP_OFFSET(nr),
63649dc9efeSIra Snyder 			    data->temp_offset[nr]);
63749dc9efeSIra Snyder 	mutex_unlock(&data->update_lock);
63849dc9efeSIra Snyder 	return count;
63949dc9efeSIra Snyder }
640c801082dSJean Delvare static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr,
641c801082dSJean Delvare 			    const char *buf, size_t count)
6428d5d45fbSJean Delvare {
6438d5d45fbSJean Delvare 	struct i2c_client *client = to_i2c_client(dev);
6448d5d45fbSJean Delvare 	struct adm1031_data *data = i2c_get_clientdata(client);
645c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
6468d5d45fbSJean Delvare 	int val;
6478d5d45fbSJean Delvare 
6488d5d45fbSJean Delvare 	val = simple_strtol(buf, NULL, 10);
6498d5d45fbSJean Delvare 	val = SENSORS_LIMIT(val, -55000, nr == 0 ? 127750 : 127875);
6509a61bf63SIngo Molnar 	mutex_lock(&data->update_lock);
6518d5d45fbSJean Delvare 	data->temp_min[nr] = TEMP_TO_REG(val);
6528d5d45fbSJean Delvare 	adm1031_write_value(client, ADM1031_REG_TEMP_MIN(nr),
6538d5d45fbSJean Delvare 			    data->temp_min[nr]);
6549a61bf63SIngo Molnar 	mutex_unlock(&data->update_lock);
6558d5d45fbSJean Delvare 	return count;
6568d5d45fbSJean Delvare }
657c801082dSJean Delvare static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
658c801082dSJean Delvare 			    const char *buf, size_t count)
6598d5d45fbSJean Delvare {
6608d5d45fbSJean Delvare 	struct i2c_client *client = to_i2c_client(dev);
6618d5d45fbSJean Delvare 	struct adm1031_data *data = i2c_get_clientdata(client);
662c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
6638d5d45fbSJean Delvare 	int val;
6648d5d45fbSJean Delvare 
6658d5d45fbSJean Delvare 	val = simple_strtol(buf, NULL, 10);
6668d5d45fbSJean Delvare 	val = SENSORS_LIMIT(val, -55000, nr == 0 ? 127750 : 127875);
6679a61bf63SIngo Molnar 	mutex_lock(&data->update_lock);
6688d5d45fbSJean Delvare 	data->temp_max[nr] = TEMP_TO_REG(val);
6698d5d45fbSJean Delvare 	adm1031_write_value(client, ADM1031_REG_TEMP_MAX(nr),
6708d5d45fbSJean Delvare 			    data->temp_max[nr]);
6719a61bf63SIngo Molnar 	mutex_unlock(&data->update_lock);
6728d5d45fbSJean Delvare 	return count;
6738d5d45fbSJean Delvare }
674c801082dSJean Delvare static ssize_t set_temp_crit(struct device *dev, struct device_attribute *attr,
675c801082dSJean Delvare 			     const char *buf, size_t count)
6768d5d45fbSJean Delvare {
6778d5d45fbSJean Delvare 	struct i2c_client *client = to_i2c_client(dev);
6788d5d45fbSJean Delvare 	struct adm1031_data *data = i2c_get_clientdata(client);
679c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
6808d5d45fbSJean Delvare 	int val;
6818d5d45fbSJean Delvare 
6828d5d45fbSJean Delvare 	val = simple_strtol(buf, NULL, 10);
6838d5d45fbSJean Delvare 	val = SENSORS_LIMIT(val, -55000, nr == 0 ? 127750 : 127875);
6849a61bf63SIngo Molnar 	mutex_lock(&data->update_lock);
6858d5d45fbSJean Delvare 	data->temp_crit[nr] = TEMP_TO_REG(val);
6868d5d45fbSJean Delvare 	adm1031_write_value(client, ADM1031_REG_TEMP_CRIT(nr),
6878d5d45fbSJean Delvare 			    data->temp_crit[nr]);
6889a61bf63SIngo Molnar 	mutex_unlock(&data->update_lock);
6898d5d45fbSJean Delvare 	return count;
6908d5d45fbSJean Delvare }
6918d5d45fbSJean Delvare 
6928d5d45fbSJean Delvare #define temp_reg(offset)						\
693c801082dSJean Delvare static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO,		\
694c801082dSJean Delvare 		show_temp, NULL, offset - 1);				\
69549dc9efeSIra Snyder static SENSOR_DEVICE_ATTR(temp##offset##_offset, S_IRUGO | S_IWUSR,	\
69649dc9efeSIra Snyder 		show_temp_offset, set_temp_offset, offset - 1);		\
697c801082dSJean Delvare static SENSOR_DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR,	\
698c801082dSJean Delvare 		show_temp_min, set_temp_min, offset - 1);		\
699c801082dSJean Delvare static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR,	\
700c801082dSJean Delvare 		show_temp_max, set_temp_max, offset - 1);		\
701c801082dSJean Delvare static SENSOR_DEVICE_ATTR(temp##offset##_crit, S_IRUGO | S_IWUSR,	\
702c801082dSJean Delvare 		show_temp_crit, set_temp_crit, offset - 1)
7038d5d45fbSJean Delvare 
7048d5d45fbSJean Delvare temp_reg(1);
7058d5d45fbSJean Delvare temp_reg(2);
7068d5d45fbSJean Delvare temp_reg(3);
7078d5d45fbSJean Delvare 
7088d5d45fbSJean Delvare /* Alarms */
7098d5d45fbSJean Delvare static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf)
7108d5d45fbSJean Delvare {
7118d5d45fbSJean Delvare 	struct adm1031_data *data = adm1031_update_device(dev);
7128d5d45fbSJean Delvare 	return sprintf(buf, "%d\n", data->alarm);
7138d5d45fbSJean Delvare }
7148d5d45fbSJean Delvare 
7158d5d45fbSJean Delvare static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
7168d5d45fbSJean Delvare 
717050ab878SJean Delvare static ssize_t show_alarm(struct device *dev,
718050ab878SJean Delvare 			  struct device_attribute *attr, char *buf)
719050ab878SJean Delvare {
720050ab878SJean Delvare 	int bitnr = to_sensor_dev_attr(attr)->index;
721050ab878SJean Delvare 	struct adm1031_data *data = adm1031_update_device(dev);
722050ab878SJean Delvare 	return sprintf(buf, "%d\n", (data->alarm >> bitnr) & 1);
723050ab878SJean Delvare }
724050ab878SJean Delvare 
725050ab878SJean Delvare static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 0);
726050ab878SJean Delvare static SENSOR_DEVICE_ATTR(fan1_fault, S_IRUGO, show_alarm, NULL, 1);
727050ab878SJean Delvare static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_alarm, NULL, 2);
728050ab878SJean Delvare static SENSOR_DEVICE_ATTR(temp2_min_alarm, S_IRUGO, show_alarm, NULL, 3);
729050ab878SJean Delvare static SENSOR_DEVICE_ATTR(temp2_crit_alarm, S_IRUGO, show_alarm, NULL, 4);
730050ab878SJean Delvare static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_alarm, NULL, 5);
731050ab878SJean Delvare static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 6);
732050ab878SJean Delvare static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, show_alarm, NULL, 7);
733050ab878SJean Delvare static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 8);
734050ab878SJean Delvare static SENSOR_DEVICE_ATTR(fan2_fault, S_IRUGO, show_alarm, NULL, 9);
735050ab878SJean Delvare static SENSOR_DEVICE_ATTR(temp3_max_alarm, S_IRUGO, show_alarm, NULL, 10);
736050ab878SJean Delvare static SENSOR_DEVICE_ATTR(temp3_min_alarm, S_IRUGO, show_alarm, NULL, 11);
737050ab878SJean Delvare static SENSOR_DEVICE_ATTR(temp3_crit_alarm, S_IRUGO, show_alarm, NULL, 12);
738050ab878SJean Delvare static SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_alarm, NULL, 13);
739050ab878SJean Delvare static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 14);
7408d5d45fbSJean Delvare 
741681c6f7aSMark M. Hoffman static struct attribute *adm1031_attributes[] = {
742c801082dSJean Delvare 	&sensor_dev_attr_fan1_input.dev_attr.attr,
743c801082dSJean Delvare 	&sensor_dev_attr_fan1_div.dev_attr.attr,
744c801082dSJean Delvare 	&sensor_dev_attr_fan1_min.dev_attr.attr,
745050ab878SJean Delvare 	&sensor_dev_attr_fan1_alarm.dev_attr.attr,
746050ab878SJean Delvare 	&sensor_dev_attr_fan1_fault.dev_attr.attr,
747c801082dSJean Delvare 	&sensor_dev_attr_pwm1.dev_attr.attr,
748c801082dSJean Delvare 	&sensor_dev_attr_auto_fan1_channel.dev_attr.attr,
749c801082dSJean Delvare 	&sensor_dev_attr_temp1_input.dev_attr.attr,
75049dc9efeSIra Snyder 	&sensor_dev_attr_temp1_offset.dev_attr.attr,
751c801082dSJean Delvare 	&sensor_dev_attr_temp1_min.dev_attr.attr,
752050ab878SJean Delvare 	&sensor_dev_attr_temp1_min_alarm.dev_attr.attr,
753c801082dSJean Delvare 	&sensor_dev_attr_temp1_max.dev_attr.attr,
754050ab878SJean Delvare 	&sensor_dev_attr_temp1_max_alarm.dev_attr.attr,
755c801082dSJean Delvare 	&sensor_dev_attr_temp1_crit.dev_attr.attr,
756050ab878SJean Delvare 	&sensor_dev_attr_temp1_crit_alarm.dev_attr.attr,
757c801082dSJean Delvare 	&sensor_dev_attr_temp2_input.dev_attr.attr,
75849dc9efeSIra Snyder 	&sensor_dev_attr_temp2_offset.dev_attr.attr,
759c801082dSJean Delvare 	&sensor_dev_attr_temp2_min.dev_attr.attr,
760050ab878SJean Delvare 	&sensor_dev_attr_temp2_min_alarm.dev_attr.attr,
761c801082dSJean Delvare 	&sensor_dev_attr_temp2_max.dev_attr.attr,
762050ab878SJean Delvare 	&sensor_dev_attr_temp2_max_alarm.dev_attr.attr,
763c801082dSJean Delvare 	&sensor_dev_attr_temp2_crit.dev_attr.attr,
764050ab878SJean Delvare 	&sensor_dev_attr_temp2_crit_alarm.dev_attr.attr,
765050ab878SJean Delvare 	&sensor_dev_attr_temp2_fault.dev_attr.attr,
766681c6f7aSMark M. Hoffman 
767c801082dSJean Delvare 	&sensor_dev_attr_auto_temp1_off.dev_attr.attr,
768c801082dSJean Delvare 	&sensor_dev_attr_auto_temp1_min.dev_attr.attr,
769c801082dSJean Delvare 	&sensor_dev_attr_auto_temp1_max.dev_attr.attr,
770681c6f7aSMark M. Hoffman 
771c801082dSJean Delvare 	&sensor_dev_attr_auto_temp2_off.dev_attr.attr,
772c801082dSJean Delvare 	&sensor_dev_attr_auto_temp2_min.dev_attr.attr,
773c801082dSJean Delvare 	&sensor_dev_attr_auto_temp2_max.dev_attr.attr,
774681c6f7aSMark M. Hoffman 
775c801082dSJean Delvare 	&sensor_dev_attr_auto_fan1_min_pwm.dev_attr.attr,
776681c6f7aSMark M. Hoffman 
777681c6f7aSMark M. Hoffman 	&dev_attr_alarms.attr,
778681c6f7aSMark M. Hoffman 
779681c6f7aSMark M. Hoffman 	NULL
780681c6f7aSMark M. Hoffman };
781681c6f7aSMark M. Hoffman 
782681c6f7aSMark M. Hoffman static const struct attribute_group adm1031_group = {
783681c6f7aSMark M. Hoffman 	.attrs = adm1031_attributes,
784681c6f7aSMark M. Hoffman };
785681c6f7aSMark M. Hoffman 
786681c6f7aSMark M. Hoffman static struct attribute *adm1031_attributes_opt[] = {
787c801082dSJean Delvare 	&sensor_dev_attr_fan2_input.dev_attr.attr,
788c801082dSJean Delvare 	&sensor_dev_attr_fan2_div.dev_attr.attr,
789c801082dSJean Delvare 	&sensor_dev_attr_fan2_min.dev_attr.attr,
790050ab878SJean Delvare 	&sensor_dev_attr_fan2_alarm.dev_attr.attr,
791050ab878SJean Delvare 	&sensor_dev_attr_fan2_fault.dev_attr.attr,
792c801082dSJean Delvare 	&sensor_dev_attr_pwm2.dev_attr.attr,
793c801082dSJean Delvare 	&sensor_dev_attr_auto_fan2_channel.dev_attr.attr,
794c801082dSJean Delvare 	&sensor_dev_attr_temp3_input.dev_attr.attr,
79549dc9efeSIra Snyder 	&sensor_dev_attr_temp3_offset.dev_attr.attr,
796c801082dSJean Delvare 	&sensor_dev_attr_temp3_min.dev_attr.attr,
797050ab878SJean Delvare 	&sensor_dev_attr_temp3_min_alarm.dev_attr.attr,
798c801082dSJean Delvare 	&sensor_dev_attr_temp3_max.dev_attr.attr,
799050ab878SJean Delvare 	&sensor_dev_attr_temp3_max_alarm.dev_attr.attr,
800c801082dSJean Delvare 	&sensor_dev_attr_temp3_crit.dev_attr.attr,
801050ab878SJean Delvare 	&sensor_dev_attr_temp3_crit_alarm.dev_attr.attr,
802050ab878SJean Delvare 	&sensor_dev_attr_temp3_fault.dev_attr.attr,
803c801082dSJean Delvare 	&sensor_dev_attr_auto_temp3_off.dev_attr.attr,
804c801082dSJean Delvare 	&sensor_dev_attr_auto_temp3_min.dev_attr.attr,
805c801082dSJean Delvare 	&sensor_dev_attr_auto_temp3_max.dev_attr.attr,
806c801082dSJean Delvare 	&sensor_dev_attr_auto_fan2_min_pwm.dev_attr.attr,
807681c6f7aSMark M. Hoffman 	NULL
808681c6f7aSMark M. Hoffman };
809681c6f7aSMark M. Hoffman 
810681c6f7aSMark M. Hoffman static const struct attribute_group adm1031_group_opt = {
811681c6f7aSMark M. Hoffman 	.attrs = adm1031_attributes_opt,
812681c6f7aSMark M. Hoffman };
813681c6f7aSMark M. Hoffman 
814af200f88SJean Delvare /* Return 0 if detection is successful, -ENODEV otherwise */
815310ec792SJean Delvare static int adm1031_detect(struct i2c_client *client,
816af200f88SJean Delvare 			  struct i2c_board_info *info)
8178d5d45fbSJean Delvare {
818af200f88SJean Delvare 	struct i2c_adapter *adapter = client->adapter;
81952df6440SJean Delvare 	const char *name;
82052df6440SJean Delvare 	int id, co;
8218d5d45fbSJean Delvare 
8228d5d45fbSJean Delvare 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
823af200f88SJean Delvare 		return -ENODEV;
8248d5d45fbSJean Delvare 
8256d6006b8SJean Delvare 	id = i2c_smbus_read_byte_data(client, 0x3d);
8266d6006b8SJean Delvare 	co = i2c_smbus_read_byte_data(client, 0x3e);
8278d5d45fbSJean Delvare 
8288d5d45fbSJean Delvare 	if (!((id == 0x31 || id == 0x30) && co == 0x41))
829af200f88SJean Delvare 		return -ENODEV;
83052df6440SJean Delvare 	name = (id == 0x30) ? "adm1030" : "adm1031";
8318d5d45fbSJean Delvare 
832af200f88SJean Delvare 	strlcpy(info->type, name, I2C_NAME_SIZE);
8338d5d45fbSJean Delvare 
834af200f88SJean Delvare 	return 0;
835af200f88SJean Delvare }
836af200f88SJean Delvare 
837af200f88SJean Delvare static int adm1031_probe(struct i2c_client *client,
838af200f88SJean Delvare 			 const struct i2c_device_id *id)
839af200f88SJean Delvare {
840af200f88SJean Delvare 	struct adm1031_data *data;
841af200f88SJean Delvare 	int err;
842af200f88SJean Delvare 
843af200f88SJean Delvare 	data = kzalloc(sizeof(struct adm1031_data), GFP_KERNEL);
844af200f88SJean Delvare 	if (!data) {
845af200f88SJean Delvare 		err = -ENOMEM;
846af200f88SJean Delvare 		goto exit;
847af200f88SJean Delvare 	}
848af200f88SJean Delvare 
849af200f88SJean Delvare 	i2c_set_clientdata(client, data);
850af200f88SJean Delvare 	data->chip_type = id->driver_data;
8519a61bf63SIngo Molnar 	mutex_init(&data->update_lock);
8528d5d45fbSJean Delvare 
853af200f88SJean Delvare 	if (data->chip_type == adm1030)
854af200f88SJean Delvare 		data->chan_select_table = &auto_channel_select_table_adm1030;
855af200f88SJean Delvare 	else
856af200f88SJean Delvare 		data->chan_select_table = &auto_channel_select_table_adm1031;
8578d5d45fbSJean Delvare 
8588d5d45fbSJean Delvare 	/* Initialize the ADM1031 chip */
8596d6006b8SJean Delvare 	adm1031_init_client(client);
8608d5d45fbSJean Delvare 
8618d5d45fbSJean Delvare 	/* Register sysfs hooks */
8626d6006b8SJean Delvare 	if ((err = sysfs_create_group(&client->dev.kobj, &adm1031_group)))
863af200f88SJean Delvare 		goto exit_free;
864681c6f7aSMark M. Hoffman 
865af200f88SJean Delvare 	if (data->chip_type == adm1031) {
8666d6006b8SJean Delvare 		if ((err = sysfs_create_group(&client->dev.kobj,
867681c6f7aSMark M. Hoffman 						&adm1031_group_opt)))
868681c6f7aSMark M. Hoffman 			goto exit_remove;
869681c6f7aSMark M. Hoffman 	}
870681c6f7aSMark M. Hoffman 
8716d6006b8SJean Delvare 	data->hwmon_dev = hwmon_device_register(&client->dev);
8721beeffe4STony Jones 	if (IS_ERR(data->hwmon_dev)) {
8731beeffe4STony Jones 		err = PTR_ERR(data->hwmon_dev);
874681c6f7aSMark M. Hoffman 		goto exit_remove;
8758d5d45fbSJean Delvare 	}
8768d5d45fbSJean Delvare 
8778d5d45fbSJean Delvare 	return 0;
8788d5d45fbSJean Delvare 
879681c6f7aSMark M. Hoffman exit_remove:
8806d6006b8SJean Delvare 	sysfs_remove_group(&client->dev.kobj, &adm1031_group);
8816d6006b8SJean Delvare 	sysfs_remove_group(&client->dev.kobj, &adm1031_group_opt);
8828d5d45fbSJean Delvare exit_free:
8831f57ff89SAlexey Dobriyan 	kfree(data);
8848d5d45fbSJean Delvare exit:
8858d5d45fbSJean Delvare 	return err;
8868d5d45fbSJean Delvare }
8878d5d45fbSJean Delvare 
888af200f88SJean Delvare static int adm1031_remove(struct i2c_client *client)
8898d5d45fbSJean Delvare {
890943b0830SMark M. Hoffman 	struct adm1031_data *data = i2c_get_clientdata(client);
891943b0830SMark M. Hoffman 
8921beeffe4STony Jones 	hwmon_device_unregister(data->hwmon_dev);
893681c6f7aSMark M. Hoffman 	sysfs_remove_group(&client->dev.kobj, &adm1031_group);
894681c6f7aSMark M. Hoffman 	sysfs_remove_group(&client->dev.kobj, &adm1031_group_opt);
895943b0830SMark M. Hoffman 	kfree(data);
8968d5d45fbSJean Delvare 	return 0;
8978d5d45fbSJean Delvare }
8988d5d45fbSJean Delvare 
8998d5d45fbSJean Delvare static void adm1031_init_client(struct i2c_client *client)
9008d5d45fbSJean Delvare {
9018d5d45fbSJean Delvare 	unsigned int read_val;
9028d5d45fbSJean Delvare 	unsigned int mask;
9038d5d45fbSJean Delvare 	struct adm1031_data *data = i2c_get_clientdata(client);
9048d5d45fbSJean Delvare 
9058d5d45fbSJean Delvare 	mask = (ADM1031_CONF2_PWM1_ENABLE | ADM1031_CONF2_TACH1_ENABLE);
9068d5d45fbSJean Delvare 	if (data->chip_type == adm1031) {
9078d5d45fbSJean Delvare 		mask |= (ADM1031_CONF2_PWM2_ENABLE |
9088d5d45fbSJean Delvare 			ADM1031_CONF2_TACH2_ENABLE);
9098d5d45fbSJean Delvare 	}
9108d5d45fbSJean Delvare 	/* Initialize the ADM1031 chip (enables fan speed reading ) */
9118d5d45fbSJean Delvare 	read_val = adm1031_read_value(client, ADM1031_REG_CONF2);
9128d5d45fbSJean Delvare 	if ((read_val | mask) != read_val) {
9138d5d45fbSJean Delvare 	    adm1031_write_value(client, ADM1031_REG_CONF2, read_val | mask);
9148d5d45fbSJean Delvare 	}
9158d5d45fbSJean Delvare 
9168d5d45fbSJean Delvare 	read_val = adm1031_read_value(client, ADM1031_REG_CONF1);
9178d5d45fbSJean Delvare 	if ((read_val | ADM1031_CONF1_MONITOR_ENABLE) != read_val) {
9188d5d45fbSJean Delvare 	    adm1031_write_value(client, ADM1031_REG_CONF1, read_val |
9198d5d45fbSJean Delvare 				ADM1031_CONF1_MONITOR_ENABLE);
9208d5d45fbSJean Delvare 	}
9218d5d45fbSJean Delvare 
9228d5d45fbSJean Delvare }
9238d5d45fbSJean Delvare 
9248d5d45fbSJean Delvare static struct adm1031_data *adm1031_update_device(struct device *dev)
9258d5d45fbSJean Delvare {
9268d5d45fbSJean Delvare 	struct i2c_client *client = to_i2c_client(dev);
9278d5d45fbSJean Delvare 	struct adm1031_data *data = i2c_get_clientdata(client);
9288d5d45fbSJean Delvare 	int chan;
9298d5d45fbSJean Delvare 
9309a61bf63SIngo Molnar 	mutex_lock(&data->update_lock);
9318d5d45fbSJean Delvare 
9328d5d45fbSJean Delvare 	if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
9338d5d45fbSJean Delvare 	    || !data->valid) {
9348d5d45fbSJean Delvare 
9358d5d45fbSJean Delvare 		dev_dbg(&client->dev, "Starting adm1031 update\n");
9368d5d45fbSJean Delvare 		for (chan = 0;
9378d5d45fbSJean Delvare 		     chan < ((data->chip_type == adm1031) ? 3 : 2); chan++) {
9388d5d45fbSJean Delvare 			u8 oldh, newh;
9398d5d45fbSJean Delvare 
9408d5d45fbSJean Delvare 			oldh =
9418d5d45fbSJean Delvare 			    adm1031_read_value(client, ADM1031_REG_TEMP(chan));
9428d5d45fbSJean Delvare 			data->ext_temp[chan] =
9438d5d45fbSJean Delvare 			    adm1031_read_value(client, ADM1031_REG_EXT_TEMP);
9448d5d45fbSJean Delvare 			newh =
9458d5d45fbSJean Delvare 			    adm1031_read_value(client, ADM1031_REG_TEMP(chan));
9468d5d45fbSJean Delvare 			if (newh != oldh) {
9478d5d45fbSJean Delvare 				data->ext_temp[chan] =
9488d5d45fbSJean Delvare 				    adm1031_read_value(client,
9498d5d45fbSJean Delvare 						       ADM1031_REG_EXT_TEMP);
9508d5d45fbSJean Delvare #ifdef DEBUG
9518d5d45fbSJean Delvare 				oldh =
9528d5d45fbSJean Delvare 				    adm1031_read_value(client,
9538d5d45fbSJean Delvare 						       ADM1031_REG_TEMP(chan));
9548d5d45fbSJean Delvare 
9558d5d45fbSJean Delvare 				/* oldh is actually newer */
9568d5d45fbSJean Delvare 				if (newh != oldh)
9578d5d45fbSJean Delvare 					dev_warn(&client->dev,
9588d5d45fbSJean Delvare 						 "Remote temperature may be "
9598d5d45fbSJean Delvare 						 "wrong.\n");
9608d5d45fbSJean Delvare #endif
9618d5d45fbSJean Delvare 			}
9628d5d45fbSJean Delvare 			data->temp[chan] = newh;
9638d5d45fbSJean Delvare 
96449dc9efeSIra Snyder 			data->temp_offset[chan] =
96549dc9efeSIra Snyder 			    adm1031_read_value(client,
96649dc9efeSIra Snyder 					       ADM1031_REG_TEMP_OFFSET(chan));
9678d5d45fbSJean Delvare 			data->temp_min[chan] =
9688d5d45fbSJean Delvare 			    adm1031_read_value(client,
9698d5d45fbSJean Delvare 					       ADM1031_REG_TEMP_MIN(chan));
9708d5d45fbSJean Delvare 			data->temp_max[chan] =
9718d5d45fbSJean Delvare 			    adm1031_read_value(client,
9728d5d45fbSJean Delvare 					       ADM1031_REG_TEMP_MAX(chan));
9738d5d45fbSJean Delvare 			data->temp_crit[chan] =
9748d5d45fbSJean Delvare 			    adm1031_read_value(client,
9758d5d45fbSJean Delvare 					       ADM1031_REG_TEMP_CRIT(chan));
9768d5d45fbSJean Delvare 			data->auto_temp[chan] =
9778d5d45fbSJean Delvare 			    adm1031_read_value(client,
9788d5d45fbSJean Delvare 					       ADM1031_REG_AUTO_TEMP(chan));
9798d5d45fbSJean Delvare 
9808d5d45fbSJean Delvare 		}
9818d5d45fbSJean Delvare 
9828d5d45fbSJean Delvare 		data->conf1 = adm1031_read_value(client, ADM1031_REG_CONF1);
9838d5d45fbSJean Delvare 		data->conf2 = adm1031_read_value(client, ADM1031_REG_CONF2);
9848d5d45fbSJean Delvare 
9858d5d45fbSJean Delvare 		data->alarm = adm1031_read_value(client, ADM1031_REG_STATUS(0))
9868d5d45fbSJean Delvare 			     | (adm1031_read_value(client, ADM1031_REG_STATUS(1))
9878d5d45fbSJean Delvare 				<< 8);
9888d5d45fbSJean Delvare 		if (data->chip_type == adm1030) {
9898d5d45fbSJean Delvare 			data->alarm &= 0xc0ff;
9908d5d45fbSJean Delvare 		}
9918d5d45fbSJean Delvare 
9928d5d45fbSJean Delvare 		for (chan=0; chan<(data->chip_type == adm1030 ? 1 : 2); chan++) {
9938d5d45fbSJean Delvare 			data->fan_div[chan] =
9948d5d45fbSJean Delvare 			    adm1031_read_value(client, ADM1031_REG_FAN_DIV(chan));
9958d5d45fbSJean Delvare 			data->fan_min[chan] =
9968d5d45fbSJean Delvare 			    adm1031_read_value(client, ADM1031_REG_FAN_MIN(chan));
9978d5d45fbSJean Delvare 			data->fan[chan] =
9988d5d45fbSJean Delvare 			    adm1031_read_value(client, ADM1031_REG_FAN_SPEED(chan));
9998d5d45fbSJean Delvare 			data->pwm[chan] =
10008d5d45fbSJean Delvare 			    0xf & (adm1031_read_value(client, ADM1031_REG_PWM) >>
10018d5d45fbSJean Delvare 				   (4*chan));
10028d5d45fbSJean Delvare 		}
10038d5d45fbSJean Delvare 		data->last_updated = jiffies;
10048d5d45fbSJean Delvare 		data->valid = 1;
10058d5d45fbSJean Delvare 	}
10068d5d45fbSJean Delvare 
10079a61bf63SIngo Molnar 	mutex_unlock(&data->update_lock);
10088d5d45fbSJean Delvare 
10098d5d45fbSJean Delvare 	return data;
10108d5d45fbSJean Delvare }
10118d5d45fbSJean Delvare 
10128d5d45fbSJean Delvare static int __init sensors_adm1031_init(void)
10138d5d45fbSJean Delvare {
10148d5d45fbSJean Delvare 	return i2c_add_driver(&adm1031_driver);
10158d5d45fbSJean Delvare }
10168d5d45fbSJean Delvare 
10178d5d45fbSJean Delvare static void __exit sensors_adm1031_exit(void)
10188d5d45fbSJean Delvare {
10198d5d45fbSJean Delvare 	i2c_del_driver(&adm1031_driver);
10208d5d45fbSJean Delvare }
10218d5d45fbSJean Delvare 
10228d5d45fbSJean Delvare MODULE_AUTHOR("Alexandre d'Alton <alex@alexdalton.org>");
10238d5d45fbSJean Delvare MODULE_DESCRIPTION("ADM1031/ADM1030 driver");
10248d5d45fbSJean Delvare MODULE_LICENSE("GPL");
10258d5d45fbSJean Delvare 
10268d5d45fbSJean Delvare module_init(sensors_adm1031_init);
10278d5d45fbSJean Delvare module_exit(sensors_adm1031_exit);
1028