xref: /linux/drivers/hwmon/adm1031.c (revision 6748703856d461f8cd62b72ebca51040e06cb310)
174ba9207SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
28d5d45fbSJean Delvare /*
3fbb6670dSGuenter Roeck  * adm1031.c - Part of lm_sensors, Linux kernel modules for hardware
4fbb6670dSGuenter Roeck  *	       monitoring
5fbb6670dSGuenter Roeck  * Based on lm75.c and lm85.c
6fbb6670dSGuenter Roeck  * Supports adm1030 / adm1031
7fbb6670dSGuenter Roeck  * Copyright (C) 2004 Alexandre d'Alton <alex@alexdalton.org>
87c81c60fSJean Delvare  * Reworked by Jean Delvare <jdelvare@suse.de>
98d5d45fbSJean Delvare  */
108d5d45fbSJean Delvare 
118d5d45fbSJean Delvare #include <linux/module.h>
128d5d45fbSJean Delvare #include <linux/init.h>
138d5d45fbSJean Delvare #include <linux/slab.h>
148d5d45fbSJean Delvare #include <linux/jiffies.h>
158d5d45fbSJean Delvare #include <linux/i2c.h>
16943b0830SMark M. Hoffman #include <linux/hwmon.h>
17c801082dSJean Delvare #include <linux/hwmon-sysfs.h>
18943b0830SMark M. Hoffman #include <linux/err.h>
199a61bf63SIngo Molnar #include <linux/mutex.h>
208d5d45fbSJean Delvare 
218d5d45fbSJean Delvare /* Following macros takes channel parameter starting from 0 to 2 */
228d5d45fbSJean Delvare #define ADM1031_REG_FAN_SPEED(nr)	(0x08 + (nr))
238d5d45fbSJean Delvare #define ADM1031_REG_FAN_DIV(nr)		(0x20 + (nr))
248d5d45fbSJean Delvare #define ADM1031_REG_PWM			(0x22)
258d5d45fbSJean Delvare #define ADM1031_REG_FAN_MIN(nr)		(0x10 + (nr))
2687c33daaSJean Delvare #define ADM1031_REG_FAN_FILTER		(0x23)
278d5d45fbSJean Delvare 
2849dc9efeSIra Snyder #define ADM1031_REG_TEMP_OFFSET(nr)	(0x0d + (nr))
298d5d45fbSJean Delvare #define ADM1031_REG_TEMP_MAX(nr)	(0x14 + 4 * (nr))
308d5d45fbSJean Delvare #define ADM1031_REG_TEMP_MIN(nr)	(0x15 + 4 * (nr))
318d5d45fbSJean Delvare #define ADM1031_REG_TEMP_CRIT(nr)	(0x16 + 4 * (nr))
328d5d45fbSJean Delvare 
336d6006b8SJean Delvare #define ADM1031_REG_TEMP(nr)		(0x0a + (nr))
348d5d45fbSJean Delvare #define ADM1031_REG_AUTO_TEMP(nr)	(0x24 + (nr))
358d5d45fbSJean Delvare 
368d5d45fbSJean Delvare #define ADM1031_REG_STATUS(nr)		(0x2 + (nr))
378d5d45fbSJean Delvare 
386d6006b8SJean Delvare #define ADM1031_REG_CONF1		0x00
396d6006b8SJean Delvare #define ADM1031_REG_CONF2		0x01
406d6006b8SJean Delvare #define ADM1031_REG_EXT_TEMP		0x06
418d5d45fbSJean Delvare 
428d5d45fbSJean Delvare #define ADM1031_CONF1_MONITOR_ENABLE	0x01	/* Monitoring enable */
438d5d45fbSJean Delvare #define ADM1031_CONF1_PWM_INVERT	0x08	/* PWM Invert */
448d5d45fbSJean Delvare #define ADM1031_CONF1_AUTO_MODE		0x80	/* Auto FAN */
458d5d45fbSJean Delvare 
468d5d45fbSJean Delvare #define ADM1031_CONF2_PWM1_ENABLE	0x01
478d5d45fbSJean Delvare #define ADM1031_CONF2_PWM2_ENABLE	0x02
488d5d45fbSJean Delvare #define ADM1031_CONF2_TACH1_ENABLE	0x04
498d5d45fbSJean Delvare #define ADM1031_CONF2_TACH2_ENABLE	0x08
508d5d45fbSJean Delvare #define ADM1031_CONF2_TEMP_ENABLE(chan)	(0x10 << (chan))
518d5d45fbSJean Delvare 
5287c33daaSJean Delvare #define ADM1031_UPDATE_RATE_MASK	0x1c
5387c33daaSJean Delvare #define ADM1031_UPDATE_RATE_SHIFT	2
5487c33daaSJean Delvare 
558d5d45fbSJean Delvare /* Addresses to scan */
5625e9c86dSMark M. Hoffman static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
578d5d45fbSJean Delvare 
58e5e9f44cSJean Delvare enum chips { adm1030, adm1031 };
598d5d45fbSJean Delvare 
608d5d45fbSJean Delvare typedef u8 auto_chan_table_t[8][2];
618d5d45fbSJean Delvare 
628d5d45fbSJean Delvare /* Each client has this additional data */
638d5d45fbSJean Delvare struct adm1031_data {
64b060f3c4SAxel Lin 	struct i2c_client *client;
65b060f3c4SAxel Lin 	const struct attribute_group *groups[3];
669a61bf63SIngo Molnar 	struct mutex update_lock;
678d5d45fbSJean Delvare 	int chip_type;
688d5d45fbSJean Delvare 	char valid;		/* !=0 if following fields are valid */
698d5d45fbSJean Delvare 	unsigned long last_updated;	/* In jiffies */
70a51b9944SGuenter Roeck 	unsigned int update_interval;	/* In milliseconds */
71fbb6670dSGuenter Roeck 	/*
72fbb6670dSGuenter Roeck 	 * The chan_select_table contains the possible configurations for
738d5d45fbSJean Delvare 	 * auto fan control.
748d5d45fbSJean Delvare 	 */
756d6006b8SJean Delvare 	const auto_chan_table_t *chan_select_table;
768d5d45fbSJean Delvare 	u16 alarm;
778d5d45fbSJean Delvare 	u8 conf1;
788d5d45fbSJean Delvare 	u8 conf2;
798d5d45fbSJean Delvare 	u8 fan[2];
808d5d45fbSJean Delvare 	u8 fan_div[2];
818d5d45fbSJean Delvare 	u8 fan_min[2];
828d5d45fbSJean Delvare 	u8 pwm[2];
838d5d45fbSJean Delvare 	u8 old_pwm[2];
848d5d45fbSJean Delvare 	s8 temp[3];
858d5d45fbSJean Delvare 	u8 ext_temp[3];
868d5d45fbSJean Delvare 	u8 auto_temp[3];
878d5d45fbSJean Delvare 	u8 auto_temp_min[3];
888d5d45fbSJean Delvare 	u8 auto_temp_off[3];
898d5d45fbSJean Delvare 	u8 auto_temp_max[3];
9049dc9efeSIra Snyder 	s8 temp_offset[3];
918d5d45fbSJean Delvare 	s8 temp_min[3];
928d5d45fbSJean Delvare 	s8 temp_max[3];
938d5d45fbSJean Delvare 	s8 temp_crit[3];
948d5d45fbSJean Delvare };
958d5d45fbSJean Delvare 
968d5d45fbSJean Delvare static inline u8 adm1031_read_value(struct i2c_client *client, u8 reg)
978d5d45fbSJean Delvare {
988d5d45fbSJean Delvare 	return i2c_smbus_read_byte_data(client, reg);
998d5d45fbSJean Delvare }
1008d5d45fbSJean Delvare 
1018d5d45fbSJean Delvare static inline int
1028d5d45fbSJean Delvare adm1031_write_value(struct i2c_client *client, u8 reg, unsigned int value)
1038d5d45fbSJean Delvare {
1048d5d45fbSJean Delvare 	return i2c_smbus_write_byte_data(client, reg, value);
1058d5d45fbSJean Delvare }
1068d5d45fbSJean Delvare 
107278ee1c8SAxel Lin static struct adm1031_data *adm1031_update_device(struct device *dev)
108278ee1c8SAxel Lin {
109b060f3c4SAxel Lin 	struct adm1031_data *data = dev_get_drvdata(dev);
110b060f3c4SAxel Lin 	struct i2c_client *client = data->client;
111278ee1c8SAxel Lin 	unsigned long next_update;
112278ee1c8SAxel Lin 	int chan;
113278ee1c8SAxel Lin 
114278ee1c8SAxel Lin 	mutex_lock(&data->update_lock);
115278ee1c8SAxel Lin 
116278ee1c8SAxel Lin 	next_update = data->last_updated
117278ee1c8SAxel Lin 	  + msecs_to_jiffies(data->update_interval);
118278ee1c8SAxel Lin 	if (time_after(jiffies, next_update) || !data->valid) {
119278ee1c8SAxel Lin 
120278ee1c8SAxel Lin 		dev_dbg(&client->dev, "Starting adm1031 update\n");
121278ee1c8SAxel Lin 		for (chan = 0;
122278ee1c8SAxel Lin 		     chan < ((data->chip_type == adm1031) ? 3 : 2); chan++) {
123278ee1c8SAxel Lin 			u8 oldh, newh;
124278ee1c8SAxel Lin 
125278ee1c8SAxel Lin 			oldh =
126278ee1c8SAxel Lin 			    adm1031_read_value(client, ADM1031_REG_TEMP(chan));
127278ee1c8SAxel Lin 			data->ext_temp[chan] =
128278ee1c8SAxel Lin 			    adm1031_read_value(client, ADM1031_REG_EXT_TEMP);
129278ee1c8SAxel Lin 			newh =
130278ee1c8SAxel Lin 			    adm1031_read_value(client, ADM1031_REG_TEMP(chan));
131278ee1c8SAxel Lin 			if (newh != oldh) {
132278ee1c8SAxel Lin 				data->ext_temp[chan] =
133278ee1c8SAxel Lin 				    adm1031_read_value(client,
134278ee1c8SAxel Lin 						       ADM1031_REG_EXT_TEMP);
135278ee1c8SAxel Lin #ifdef DEBUG
136278ee1c8SAxel Lin 				oldh =
137278ee1c8SAxel Lin 				    adm1031_read_value(client,
138278ee1c8SAxel Lin 						       ADM1031_REG_TEMP(chan));
139278ee1c8SAxel Lin 
140278ee1c8SAxel Lin 				/* oldh is actually newer */
141278ee1c8SAxel Lin 				if (newh != oldh)
142278ee1c8SAxel Lin 					dev_warn(&client->dev,
143278ee1c8SAxel Lin 					  "Remote temperature may be wrong.\n");
144278ee1c8SAxel Lin #endif
145278ee1c8SAxel Lin 			}
146278ee1c8SAxel Lin 			data->temp[chan] = newh;
147278ee1c8SAxel Lin 
148278ee1c8SAxel Lin 			data->temp_offset[chan] =
149278ee1c8SAxel Lin 			    adm1031_read_value(client,
150278ee1c8SAxel Lin 					       ADM1031_REG_TEMP_OFFSET(chan));
151278ee1c8SAxel Lin 			data->temp_min[chan] =
152278ee1c8SAxel Lin 			    adm1031_read_value(client,
153278ee1c8SAxel Lin 					       ADM1031_REG_TEMP_MIN(chan));
154278ee1c8SAxel Lin 			data->temp_max[chan] =
155278ee1c8SAxel Lin 			    adm1031_read_value(client,
156278ee1c8SAxel Lin 					       ADM1031_REG_TEMP_MAX(chan));
157278ee1c8SAxel Lin 			data->temp_crit[chan] =
158278ee1c8SAxel Lin 			    adm1031_read_value(client,
159278ee1c8SAxel Lin 					       ADM1031_REG_TEMP_CRIT(chan));
160278ee1c8SAxel Lin 			data->auto_temp[chan] =
161278ee1c8SAxel Lin 			    adm1031_read_value(client,
162278ee1c8SAxel Lin 					       ADM1031_REG_AUTO_TEMP(chan));
163278ee1c8SAxel Lin 
164278ee1c8SAxel Lin 		}
165278ee1c8SAxel Lin 
166278ee1c8SAxel Lin 		data->conf1 = adm1031_read_value(client, ADM1031_REG_CONF1);
167278ee1c8SAxel Lin 		data->conf2 = adm1031_read_value(client, ADM1031_REG_CONF2);
168278ee1c8SAxel Lin 
169278ee1c8SAxel Lin 		data->alarm = adm1031_read_value(client, ADM1031_REG_STATUS(0))
170278ee1c8SAxel Lin 		    | (adm1031_read_value(client, ADM1031_REG_STATUS(1)) << 8);
171278ee1c8SAxel Lin 		if (data->chip_type == adm1030)
172278ee1c8SAxel Lin 			data->alarm &= 0xc0ff;
173278ee1c8SAxel Lin 
174278ee1c8SAxel Lin 		for (chan = 0; chan < (data->chip_type == adm1030 ? 1 : 2);
175278ee1c8SAxel Lin 		     chan++) {
176278ee1c8SAxel Lin 			data->fan_div[chan] =
177278ee1c8SAxel Lin 			    adm1031_read_value(client,
178278ee1c8SAxel Lin 					       ADM1031_REG_FAN_DIV(chan));
179278ee1c8SAxel Lin 			data->fan_min[chan] =
180278ee1c8SAxel Lin 			    adm1031_read_value(client,
181278ee1c8SAxel Lin 					       ADM1031_REG_FAN_MIN(chan));
182278ee1c8SAxel Lin 			data->fan[chan] =
183278ee1c8SAxel Lin 			    adm1031_read_value(client,
184278ee1c8SAxel Lin 					       ADM1031_REG_FAN_SPEED(chan));
185278ee1c8SAxel Lin 			data->pwm[chan] =
186278ee1c8SAxel Lin 			  (adm1031_read_value(client,
187278ee1c8SAxel Lin 					ADM1031_REG_PWM) >> (4 * chan)) & 0x0f;
188278ee1c8SAxel Lin 		}
189278ee1c8SAxel Lin 		data->last_updated = jiffies;
190278ee1c8SAxel Lin 		data->valid = 1;
191278ee1c8SAxel Lin 	}
192278ee1c8SAxel Lin 
193278ee1c8SAxel Lin 	mutex_unlock(&data->update_lock);
194278ee1c8SAxel Lin 
195278ee1c8SAxel Lin 	return data;
196278ee1c8SAxel Lin }
1978d5d45fbSJean Delvare 
1988d5d45fbSJean Delvare #define TEMP_TO_REG(val)		(((val) < 0 ? ((val - 500) / 1000) : \
1998d5d45fbSJean Delvare 					((val + 500) / 1000)))
2008d5d45fbSJean Delvare 
2018d5d45fbSJean Delvare #define TEMP_FROM_REG(val)		((val) * 1000)
2028d5d45fbSJean Delvare 
2038d5d45fbSJean Delvare #define TEMP_FROM_REG_EXT(val, ext)	(TEMP_FROM_REG(val) + (ext) * 125)
2048d5d45fbSJean Delvare 
20549dc9efeSIra Snyder #define TEMP_OFFSET_TO_REG(val)		(TEMP_TO_REG(val) & 0x8f)
20649dc9efeSIra Snyder #define TEMP_OFFSET_FROM_REG(val)	TEMP_FROM_REG((val) < 0 ? \
20749dc9efeSIra Snyder 						      (val) | 0x70 : (val))
20849dc9efeSIra Snyder 
2091c720093SGuenter Roeck #define FAN_FROM_REG(reg, div)		((reg) ? \
2101c720093SGuenter Roeck 					 (11250 * 60) / ((reg) * (div)) : 0)
2118d5d45fbSJean Delvare 
2128d5d45fbSJean Delvare static int FAN_TO_REG(int reg, int div)
2138d5d45fbSJean Delvare {
2148d5d45fbSJean Delvare 	int tmp;
2152a844c14SGuenter Roeck 	tmp = FAN_FROM_REG(clamp_val(reg, 0, 65535), div);
2168d5d45fbSJean Delvare 	return tmp > 255 ? 255 : tmp;
2178d5d45fbSJean Delvare }
2188d5d45fbSJean Delvare 
2198d5d45fbSJean Delvare #define FAN_DIV_FROM_REG(reg)		(1<<(((reg)&0xc0)>>6))
2208d5d45fbSJean Delvare 
2212a844c14SGuenter Roeck #define PWM_TO_REG(val)			(clamp_val((val), 0, 255) >> 4)
2228d5d45fbSJean Delvare #define PWM_FROM_REG(val)		((val) << 4)
2238d5d45fbSJean Delvare 
2248d5d45fbSJean Delvare #define FAN_CHAN_FROM_REG(reg)		(((reg) >> 5) & 7)
2258d5d45fbSJean Delvare #define FAN_CHAN_TO_REG(val, reg)	\
2268d5d45fbSJean Delvare 	(((reg) & 0x1F) | (((val) << 5) & 0xe0))
2278d5d45fbSJean Delvare 
2288d5d45fbSJean Delvare #define AUTO_TEMP_MIN_TO_REG(val, reg)	\
2298d5d45fbSJean Delvare 	((((val) / 500) & 0xf8) | ((reg) & 0x7))
2308d5d45fbSJean Delvare #define AUTO_TEMP_RANGE_FROM_REG(reg)	(5000 * (1 << ((reg) & 0x7)))
2318d5d45fbSJean Delvare #define AUTO_TEMP_MIN_FROM_REG(reg)	(1000 * ((((reg) >> 3) & 0x1f) << 2))
2328d5d45fbSJean Delvare 
2338d5d45fbSJean Delvare #define AUTO_TEMP_MIN_FROM_REG_DEG(reg)	((((reg) >> 3) & 0x1f) << 2)
2348d5d45fbSJean Delvare 
2358d5d45fbSJean Delvare #define AUTO_TEMP_OFF_FROM_REG(reg)		\
2368d5d45fbSJean Delvare 	(AUTO_TEMP_MIN_FROM_REG(reg) - 5000)
2378d5d45fbSJean Delvare 
2388d5d45fbSJean Delvare #define AUTO_TEMP_MAX_FROM_REG(reg)		\
2398d5d45fbSJean Delvare 	(AUTO_TEMP_RANGE_FROM_REG(reg) +	\
2408d5d45fbSJean Delvare 	AUTO_TEMP_MIN_FROM_REG(reg))
2418d5d45fbSJean Delvare 
2428d5d45fbSJean Delvare static int AUTO_TEMP_MAX_TO_REG(int val, int reg, int pwm)
2438d5d45fbSJean Delvare {
2448d5d45fbSJean Delvare 	int ret;
2458d5d45fbSJean Delvare 	int range = val - AUTO_TEMP_MIN_FROM_REG(reg);
2468d5d45fbSJean Delvare 
2478d5d45fbSJean Delvare 	range = ((val - AUTO_TEMP_MIN_FROM_REG(reg))*10)/(16 - pwm);
2488d5d45fbSJean Delvare 	ret = ((reg & 0xf8) |
2498d5d45fbSJean Delvare 	       (range < 10000 ? 0 :
2508d5d45fbSJean Delvare 		range < 20000 ? 1 :
2518d5d45fbSJean Delvare 		range < 40000 ? 2 : range < 80000 ? 3 : 4));
2528d5d45fbSJean Delvare 	return ret;
2538d5d45fbSJean Delvare }
2548d5d45fbSJean Delvare 
2558d5d45fbSJean Delvare /* FAN auto control */
2568d5d45fbSJean Delvare #define GET_FAN_AUTO_BITFIELD(data, idx)	\
2578d5d45fbSJean Delvare 	(*(data)->chan_select_table)[FAN_CHAN_FROM_REG((data)->conf1)][idx % 2]
2588d5d45fbSJean Delvare 
259fbb6670dSGuenter Roeck /*
260fbb6670dSGuenter Roeck  * The tables below contains the possible values for the auto fan
2618d5d45fbSJean Delvare  * control bitfields. the index in the table is the register value.
2628d5d45fbSJean Delvare  * MSb is the auto fan control enable bit, so the four first entries
2638d5d45fbSJean Delvare  * in the table disables auto fan control when both bitfields are zero.
2648d5d45fbSJean Delvare  */
2656d6006b8SJean Delvare static const auto_chan_table_t auto_channel_select_table_adm1031 = {
2668d5d45fbSJean Delvare 	{ 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 },
2678d5d45fbSJean Delvare 	{ 2 /* 0b010 */ , 4 /* 0b100 */ },
2688d5d45fbSJean Delvare 	{ 2 /* 0b010 */ , 2 /* 0b010 */ },
2698d5d45fbSJean Delvare 	{ 4 /* 0b100 */ , 4 /* 0b100 */ },
2708d5d45fbSJean Delvare 	{ 7 /* 0b111 */ , 7 /* 0b111 */ },
2718d5d45fbSJean Delvare };
2728d5d45fbSJean Delvare 
2736d6006b8SJean Delvare static const auto_chan_table_t auto_channel_select_table_adm1030 = {
2748d5d45fbSJean Delvare 	{ 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 },
2758d5d45fbSJean Delvare 	{ 2 /* 0b10 */		, 0 },
2768d5d45fbSJean Delvare 	{ 0xff /* invalid */	, 0 },
2778d5d45fbSJean Delvare 	{ 0xff /* invalid */	, 0 },
2788d5d45fbSJean Delvare 	{ 3 /* 0b11 */		, 0 },
2798d5d45fbSJean Delvare };
2808d5d45fbSJean Delvare 
281fbb6670dSGuenter Roeck /*
282fbb6670dSGuenter Roeck  * That function checks if a bitfield is valid and returns the other bitfield
2838d5d45fbSJean Delvare  * nearest match if no exact match where found.
2848d5d45fbSJean Delvare  */
2858d5d45fbSJean Delvare static int
286ce15a81dSGuenter Roeck get_fan_auto_nearest(struct adm1031_data *data, int chan, u8 val, u8 reg)
2878d5d45fbSJean Delvare {
2888d5d45fbSJean Delvare 	int i;
2898d5d45fbSJean Delvare 	int first_match = -1, exact_match = -1;
2908d5d45fbSJean Delvare 	u8 other_reg_val =
2918d5d45fbSJean Delvare 	    (*data->chan_select_table)[FAN_CHAN_FROM_REG(reg)][chan ? 0 : 1];
2928d5d45fbSJean Delvare 
293ce15a81dSGuenter Roeck 	if (val == 0)
2948d5d45fbSJean Delvare 		return 0;
2958d5d45fbSJean Delvare 
2968d5d45fbSJean Delvare 	for (i = 0; i < 8; i++) {
2978d5d45fbSJean Delvare 		if ((val == (*data->chan_select_table)[i][chan]) &&
2988d5d45fbSJean Delvare 		    ((*data->chan_select_table)[i][chan ? 0 : 1] ==
2998d5d45fbSJean Delvare 		     other_reg_val)) {
3008d5d45fbSJean Delvare 			/* We found an exact match */
3018d5d45fbSJean Delvare 			exact_match = i;
3028d5d45fbSJean Delvare 			break;
3038d5d45fbSJean Delvare 		} else if (val == (*data->chan_select_table)[i][chan] &&
3048d5d45fbSJean Delvare 			   first_match == -1) {
305fbb6670dSGuenter Roeck 			/*
306fbb6670dSGuenter Roeck 			 * Save the first match in case of an exact match has
3076d6006b8SJean Delvare 			 * not been found
3088d5d45fbSJean Delvare 			 */
3098d5d45fbSJean Delvare 			first_match = i;
3108d5d45fbSJean Delvare 		}
3118d5d45fbSJean Delvare 	}
3128d5d45fbSJean Delvare 
3131c720093SGuenter Roeck 	if (exact_match >= 0)
314ce15a81dSGuenter Roeck 		return exact_match;
3151c720093SGuenter Roeck 	else if (first_match >= 0)
316ce15a81dSGuenter Roeck 		return first_match;
3171c720093SGuenter Roeck 
318ce15a81dSGuenter Roeck 	return -EINVAL;
3198d5d45fbSJean Delvare }
3208d5d45fbSJean Delvare 
3218e757e15SGuenter Roeck static ssize_t fan_auto_channel_show(struct device *dev,
322c801082dSJean Delvare 				     struct device_attribute *attr, char *buf)
3238d5d45fbSJean Delvare {
324c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
3258d5d45fbSJean Delvare 	struct adm1031_data *data = adm1031_update_device(dev);
3268d5d45fbSJean Delvare 	return sprintf(buf, "%d\n", GET_FAN_AUTO_BITFIELD(data, nr));
3278d5d45fbSJean Delvare }
3288d5d45fbSJean Delvare 
3298d5d45fbSJean Delvare static ssize_t
3308e757e15SGuenter Roeck fan_auto_channel_store(struct device *dev, struct device_attribute *attr,
331c801082dSJean Delvare 		       const char *buf, size_t count)
3328d5d45fbSJean Delvare {
333b060f3c4SAxel Lin 	struct adm1031_data *data = dev_get_drvdata(dev);
334b060f3c4SAxel Lin 	struct i2c_client *client = data->client;
335c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
3361c720093SGuenter Roeck 	long val;
3378d5d45fbSJean Delvare 	u8 reg;
3388d5d45fbSJean Delvare 	int ret;
3398d5d45fbSJean Delvare 	u8 old_fan_mode;
3408d5d45fbSJean Delvare 
3411c720093SGuenter Roeck 	ret = kstrtol(buf, 10, &val);
3421c720093SGuenter Roeck 	if (ret)
3431c720093SGuenter Roeck 		return ret;
3441c720093SGuenter Roeck 
3458d5d45fbSJean Delvare 	old_fan_mode = data->conf1;
3468d5d45fbSJean Delvare 
3479a61bf63SIngo Molnar 	mutex_lock(&data->update_lock);
3488d5d45fbSJean Delvare 
349ce15a81dSGuenter Roeck 	ret = get_fan_auto_nearest(data, nr, val, data->conf1);
350ce15a81dSGuenter Roeck 	if (ret < 0) {
3519a61bf63SIngo Molnar 		mutex_unlock(&data->update_lock);
3528d5d45fbSJean Delvare 		return ret;
3538d5d45fbSJean Delvare 	}
354ce15a81dSGuenter Roeck 	reg = ret;
3556d6006b8SJean Delvare 	data->conf1 = FAN_CHAN_TO_REG(reg, data->conf1);
3566d6006b8SJean Delvare 	if ((data->conf1 & ADM1031_CONF1_AUTO_MODE) ^
3578d5d45fbSJean Delvare 	    (old_fan_mode & ADM1031_CONF1_AUTO_MODE)) {
3588d5d45fbSJean Delvare 		if (data->conf1 & ADM1031_CONF1_AUTO_MODE) {
359fbb6670dSGuenter Roeck 			/*
360fbb6670dSGuenter Roeck 			 * Switch to Auto Fan Mode
3618d5d45fbSJean Delvare 			 * Save PWM registers
362fbb6670dSGuenter Roeck 			 * Set PWM registers to 33% Both
363fbb6670dSGuenter Roeck 			 */
3648d5d45fbSJean Delvare 			data->old_pwm[0] = data->pwm[0];
3658d5d45fbSJean Delvare 			data->old_pwm[1] = data->pwm[1];
3668d5d45fbSJean Delvare 			adm1031_write_value(client, ADM1031_REG_PWM, 0x55);
3678d5d45fbSJean Delvare 		} else {
3688d5d45fbSJean Delvare 			/* Switch to Manual Mode */
3698d5d45fbSJean Delvare 			data->pwm[0] = data->old_pwm[0];
3708d5d45fbSJean Delvare 			data->pwm[1] = data->old_pwm[1];
3718d5d45fbSJean Delvare 			/* Restore PWM registers */
3728d5d45fbSJean Delvare 			adm1031_write_value(client, ADM1031_REG_PWM,
3738d5d45fbSJean Delvare 					    data->pwm[0] | (data->pwm[1] << 4));
3748d5d45fbSJean Delvare 		}
3758d5d45fbSJean Delvare 	}
3768d5d45fbSJean Delvare 	data->conf1 = FAN_CHAN_TO_REG(reg, data->conf1);
3778d5d45fbSJean Delvare 	adm1031_write_value(client, ADM1031_REG_CONF1, data->conf1);
3789a61bf63SIngo Molnar 	mutex_unlock(&data->update_lock);
3798d5d45fbSJean Delvare 	return count;
3808d5d45fbSJean Delvare }
3818d5d45fbSJean Delvare 
3828e757e15SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(auto_fan1_channel, fan_auto_channel, 0);
3838e757e15SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(auto_fan2_channel, fan_auto_channel, 1);
3848d5d45fbSJean Delvare 
3858d5d45fbSJean Delvare /* Auto Temps */
3868e757e15SGuenter Roeck static ssize_t auto_temp_off_show(struct device *dev,
387c801082dSJean Delvare 				  struct device_attribute *attr, char *buf)
3888d5d45fbSJean Delvare {
389c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
3908d5d45fbSJean Delvare 	struct adm1031_data *data = adm1031_update_device(dev);
3918d5d45fbSJean Delvare 	return sprintf(buf, "%d\n",
3928d5d45fbSJean Delvare 		       AUTO_TEMP_OFF_FROM_REG(data->auto_temp[nr]));
3938d5d45fbSJean Delvare }
3948e757e15SGuenter Roeck static ssize_t auto_temp_min_show(struct device *dev,
395c801082dSJean Delvare 				  struct device_attribute *attr, char *buf)
3968d5d45fbSJean Delvare {
397c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
3988d5d45fbSJean Delvare 	struct adm1031_data *data = adm1031_update_device(dev);
3998d5d45fbSJean Delvare 	return sprintf(buf, "%d\n",
4008d5d45fbSJean Delvare 		       AUTO_TEMP_MIN_FROM_REG(data->auto_temp[nr]));
4018d5d45fbSJean Delvare }
4028d5d45fbSJean Delvare static ssize_t
4038e757e15SGuenter Roeck auto_temp_min_store(struct device *dev, struct device_attribute *attr,
404c801082dSJean Delvare 		    const char *buf, size_t count)
4058d5d45fbSJean Delvare {
406b060f3c4SAxel Lin 	struct adm1031_data *data = dev_get_drvdata(dev);
407b060f3c4SAxel Lin 	struct i2c_client *client = data->client;
408c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
4091c720093SGuenter Roeck 	long val;
4101c720093SGuenter Roeck 	int ret;
4111c720093SGuenter Roeck 
4121c720093SGuenter Roeck 	ret = kstrtol(buf, 10, &val);
4131c720093SGuenter Roeck 	if (ret)
4141c720093SGuenter Roeck 		return ret;
4158d5d45fbSJean Delvare 
416145e74a4SGuenter Roeck 	val = clamp_val(val, 0, 127000);
4179a61bf63SIngo Molnar 	mutex_lock(&data->update_lock);
4188d5d45fbSJean Delvare 	data->auto_temp[nr] = AUTO_TEMP_MIN_TO_REG(val, data->auto_temp[nr]);
4198d5d45fbSJean Delvare 	adm1031_write_value(client, ADM1031_REG_AUTO_TEMP(nr),
4208d5d45fbSJean Delvare 			    data->auto_temp[nr]);
4219a61bf63SIngo Molnar 	mutex_unlock(&data->update_lock);
4228d5d45fbSJean Delvare 	return count;
4238d5d45fbSJean Delvare }
4248e757e15SGuenter Roeck static ssize_t auto_temp_max_show(struct device *dev,
425c801082dSJean Delvare 				  struct device_attribute *attr, char *buf)
4268d5d45fbSJean Delvare {
427c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
4288d5d45fbSJean Delvare 	struct adm1031_data *data = adm1031_update_device(dev);
4298d5d45fbSJean Delvare 	return sprintf(buf, "%d\n",
4308d5d45fbSJean Delvare 		       AUTO_TEMP_MAX_FROM_REG(data->auto_temp[nr]));
4318d5d45fbSJean Delvare }
4328d5d45fbSJean Delvare static ssize_t
4338e757e15SGuenter Roeck auto_temp_max_store(struct device *dev, struct device_attribute *attr,
434c801082dSJean Delvare 		    const char *buf, size_t count)
4358d5d45fbSJean Delvare {
436b060f3c4SAxel Lin 	struct adm1031_data *data = dev_get_drvdata(dev);
437b060f3c4SAxel Lin 	struct i2c_client *client = data->client;
438c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
4391c720093SGuenter Roeck 	long val;
4401c720093SGuenter Roeck 	int ret;
4411c720093SGuenter Roeck 
4421c720093SGuenter Roeck 	ret = kstrtol(buf, 10, &val);
4431c720093SGuenter Roeck 	if (ret)
4441c720093SGuenter Roeck 		return ret;
4458d5d45fbSJean Delvare 
446145e74a4SGuenter Roeck 	val = clamp_val(val, 0, 127000);
4479a61bf63SIngo Molnar 	mutex_lock(&data->update_lock);
4481c720093SGuenter Roeck 	data->temp_max[nr] = AUTO_TEMP_MAX_TO_REG(val, data->auto_temp[nr],
4491c720093SGuenter Roeck 						  data->pwm[nr]);
4508d5d45fbSJean Delvare 	adm1031_write_value(client, ADM1031_REG_AUTO_TEMP(nr),
4518d5d45fbSJean Delvare 			    data->temp_max[nr]);
4529a61bf63SIngo Molnar 	mutex_unlock(&data->update_lock);
4538d5d45fbSJean Delvare 	return count;
4548d5d45fbSJean Delvare }
4558d5d45fbSJean Delvare 
4568e757e15SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(auto_temp1_off, auto_temp_off, 0);
4578e757e15SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(auto_temp1_min, auto_temp_min, 0);
4588e757e15SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(auto_temp1_max, auto_temp_max, 0);
4598e757e15SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(auto_temp2_off, auto_temp_off, 1);
4608e757e15SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(auto_temp2_min, auto_temp_min, 1);
4618e757e15SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(auto_temp2_max, auto_temp_max, 1);
4628e757e15SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(auto_temp3_off, auto_temp_off, 2);
4638e757e15SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(auto_temp3_min, auto_temp_min, 2);
4648e757e15SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(auto_temp3_max, auto_temp_max, 2);
4658d5d45fbSJean Delvare 
4668d5d45fbSJean Delvare /* pwm */
4678e757e15SGuenter Roeck static ssize_t pwm_show(struct device *dev, struct device_attribute *attr,
4688e757e15SGuenter Roeck 			char *buf)
4698d5d45fbSJean Delvare {
470c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
4718d5d45fbSJean Delvare 	struct adm1031_data *data = adm1031_update_device(dev);
4728d5d45fbSJean Delvare 	return sprintf(buf, "%d\n", PWM_FROM_REG(data->pwm[nr]));
4738d5d45fbSJean Delvare }
4748e757e15SGuenter Roeck static ssize_t pwm_store(struct device *dev, struct device_attribute *attr,
475c801082dSJean Delvare 			 const char *buf, size_t count)
4768d5d45fbSJean Delvare {
477b060f3c4SAxel Lin 	struct adm1031_data *data = dev_get_drvdata(dev);
478b060f3c4SAxel Lin 	struct i2c_client *client = data->client;
479c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
4801c720093SGuenter Roeck 	long val;
4811c720093SGuenter Roeck 	int ret, reg;
4821c720093SGuenter Roeck 
4831c720093SGuenter Roeck 	ret = kstrtol(buf, 10, &val);
4841c720093SGuenter Roeck 	if (ret)
4851c720093SGuenter Roeck 		return ret;
4868d5d45fbSJean Delvare 
4879a61bf63SIngo Molnar 	mutex_lock(&data->update_lock);
4888d5d45fbSJean Delvare 	if ((data->conf1 & ADM1031_CONF1_AUTO_MODE) &&
4898d5d45fbSJean Delvare 	    (((val>>4) & 0xf) != 5)) {
4908d5d45fbSJean Delvare 		/* In automatic mode, the only PWM accepted is 33% */
4919a61bf63SIngo Molnar 		mutex_unlock(&data->update_lock);
4928d5d45fbSJean Delvare 		return -EINVAL;
4938d5d45fbSJean Delvare 	}
4948d5d45fbSJean Delvare 	data->pwm[nr] = PWM_TO_REG(val);
4958d5d45fbSJean Delvare 	reg = adm1031_read_value(client, ADM1031_REG_PWM);
4968d5d45fbSJean Delvare 	adm1031_write_value(client, ADM1031_REG_PWM,
4978d5d45fbSJean Delvare 			    nr ? ((data->pwm[nr] << 4) & 0xf0) | (reg & 0xf)
4988d5d45fbSJean Delvare 			    : (data->pwm[nr] & 0xf) | (reg & 0xf0));
4999a61bf63SIngo Molnar 	mutex_unlock(&data->update_lock);
5008d5d45fbSJean Delvare 	return count;
5018d5d45fbSJean Delvare }
5028d5d45fbSJean Delvare 
5038e757e15SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(pwm1, pwm, 0);
5048e757e15SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(pwm2, pwm, 1);
5058e757e15SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(auto_fan1_min_pwm, pwm, 0);
5068e757e15SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(auto_fan2_min_pwm, pwm, 1);
5078d5d45fbSJean Delvare 
5088d5d45fbSJean Delvare /* Fans */
5098d5d45fbSJean Delvare 
5108d5d45fbSJean Delvare /*
5118d5d45fbSJean Delvare  * That function checks the cases where the fan reading is not
5128d5d45fbSJean Delvare  * relevant.  It is used to provide 0 as fan reading when the fan is
5138d5d45fbSJean Delvare  * not supposed to run
5148d5d45fbSJean Delvare  */
5158d5d45fbSJean Delvare static int trust_fan_readings(struct adm1031_data *data, int chan)
5168d5d45fbSJean Delvare {
5178d5d45fbSJean Delvare 	int res = 0;
5188d5d45fbSJean Delvare 
5198d5d45fbSJean Delvare 	if (data->conf1 & ADM1031_CONF1_AUTO_MODE) {
5208d5d45fbSJean Delvare 		switch (data->conf1 & 0x60) {
5211c720093SGuenter Roeck 		case 0x00:
5221c720093SGuenter Roeck 			/*
5231c720093SGuenter Roeck 			 * remote temp1 controls fan1,
5241c720093SGuenter Roeck 			 * remote temp2 controls fan2
5251c720093SGuenter Roeck 			 */
5268d5d45fbSJean Delvare 			res = data->temp[chan+1] >=
5278d5d45fbSJean Delvare 			    AUTO_TEMP_MIN_FROM_REG_DEG(data->auto_temp[chan+1]);
5288d5d45fbSJean Delvare 			break;
5298d5d45fbSJean Delvare 		case 0x20:	/* remote temp1 controls both fans */
5308d5d45fbSJean Delvare 			res =
5318d5d45fbSJean Delvare 			    data->temp[1] >=
5328d5d45fbSJean Delvare 			    AUTO_TEMP_MIN_FROM_REG_DEG(data->auto_temp[1]);
5338d5d45fbSJean Delvare 			break;
5348d5d45fbSJean Delvare 		case 0x40:	/* remote temp2 controls both fans */
5358d5d45fbSJean Delvare 			res =
5368d5d45fbSJean Delvare 			    data->temp[2] >=
5378d5d45fbSJean Delvare 			    AUTO_TEMP_MIN_FROM_REG_DEG(data->auto_temp[2]);
5388d5d45fbSJean Delvare 			break;
5398d5d45fbSJean Delvare 		case 0x60:	/* max controls both fans */
5408d5d45fbSJean Delvare 			res =
5418d5d45fbSJean Delvare 			    data->temp[0] >=
5428d5d45fbSJean Delvare 			    AUTO_TEMP_MIN_FROM_REG_DEG(data->auto_temp[0])
5438d5d45fbSJean Delvare 			    || data->temp[1] >=
5448d5d45fbSJean Delvare 			    AUTO_TEMP_MIN_FROM_REG_DEG(data->auto_temp[1])
5458d5d45fbSJean Delvare 			    || (data->chip_type == adm1031
5468d5d45fbSJean Delvare 				&& data->temp[2] >=
5478d5d45fbSJean Delvare 				AUTO_TEMP_MIN_FROM_REG_DEG(data->auto_temp[2]));
5488d5d45fbSJean Delvare 			break;
5498d5d45fbSJean Delvare 		}
5508d5d45fbSJean Delvare 	} else {
5518d5d45fbSJean Delvare 		res = data->pwm[chan] > 0;
5528d5d45fbSJean Delvare 	}
5538d5d45fbSJean Delvare 	return res;
5548d5d45fbSJean Delvare }
5558d5d45fbSJean Delvare 
5568e757e15SGuenter Roeck static ssize_t fan_show(struct device *dev, struct device_attribute *attr,
5578e757e15SGuenter Roeck 			char *buf)
5588d5d45fbSJean Delvare {
559c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
5608d5d45fbSJean Delvare 	struct adm1031_data *data = adm1031_update_device(dev);
5618d5d45fbSJean Delvare 	int value;
5628d5d45fbSJean Delvare 
5638d5d45fbSJean Delvare 	value = trust_fan_readings(data, nr) ? FAN_FROM_REG(data->fan[nr],
5648d5d45fbSJean Delvare 				 FAN_DIV_FROM_REG(data->fan_div[nr])) : 0;
5658d5d45fbSJean Delvare 	return sprintf(buf, "%d\n", value);
5668d5d45fbSJean Delvare }
5678d5d45fbSJean Delvare 
5688e757e15SGuenter Roeck static ssize_t fan_div_show(struct device *dev, struct device_attribute *attr,
5698e757e15SGuenter Roeck 			    char *buf)
5708d5d45fbSJean Delvare {
571c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
5728d5d45fbSJean Delvare 	struct adm1031_data *data = adm1031_update_device(dev);
5738d5d45fbSJean Delvare 	return sprintf(buf, "%d\n", FAN_DIV_FROM_REG(data->fan_div[nr]));
5748d5d45fbSJean Delvare }
5758e757e15SGuenter Roeck static ssize_t fan_min_show(struct device *dev, struct device_attribute *attr,
5768e757e15SGuenter Roeck 			    char *buf)
5778d5d45fbSJean Delvare {
578c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
5798d5d45fbSJean Delvare 	struct adm1031_data *data = adm1031_update_device(dev);
5808d5d45fbSJean Delvare 	return sprintf(buf, "%d\n",
5818d5d45fbSJean Delvare 		       FAN_FROM_REG(data->fan_min[nr],
5828d5d45fbSJean Delvare 				    FAN_DIV_FROM_REG(data->fan_div[nr])));
5838d5d45fbSJean Delvare }
5848e757e15SGuenter Roeck static ssize_t fan_min_store(struct device *dev,
5858e757e15SGuenter Roeck 			     struct device_attribute *attr, const char *buf,
5868e757e15SGuenter Roeck 			     size_t count)
5878d5d45fbSJean Delvare {
588b060f3c4SAxel Lin 	struct adm1031_data *data = dev_get_drvdata(dev);
589b060f3c4SAxel Lin 	struct i2c_client *client = data->client;
590c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
5911c720093SGuenter Roeck 	long val;
5921c720093SGuenter Roeck 	int ret;
5931c720093SGuenter Roeck 
5941c720093SGuenter Roeck 	ret = kstrtol(buf, 10, &val);
5951c720093SGuenter Roeck 	if (ret)
5961c720093SGuenter Roeck 		return ret;
5978d5d45fbSJean Delvare 
5989a61bf63SIngo Molnar 	mutex_lock(&data->update_lock);
5998d5d45fbSJean Delvare 	if (val) {
6008d5d45fbSJean Delvare 		data->fan_min[nr] =
6018d5d45fbSJean Delvare 			FAN_TO_REG(val, FAN_DIV_FROM_REG(data->fan_div[nr]));
6028d5d45fbSJean Delvare 	} else {
6038d5d45fbSJean Delvare 		data->fan_min[nr] = 0xff;
6048d5d45fbSJean Delvare 	}
6058d5d45fbSJean Delvare 	adm1031_write_value(client, ADM1031_REG_FAN_MIN(nr), data->fan_min[nr]);
6069a61bf63SIngo Molnar 	mutex_unlock(&data->update_lock);
6078d5d45fbSJean Delvare 	return count;
6088d5d45fbSJean Delvare }
6098e757e15SGuenter Roeck static ssize_t fan_div_store(struct device *dev,
6108e757e15SGuenter Roeck 			     struct device_attribute *attr, const char *buf,
6118e757e15SGuenter Roeck 			     size_t count)
6128d5d45fbSJean Delvare {
613b060f3c4SAxel Lin 	struct adm1031_data *data = dev_get_drvdata(dev);
614b060f3c4SAxel Lin 	struct i2c_client *client = data->client;
615c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
6161c720093SGuenter Roeck 	long val;
6178d5d45fbSJean Delvare 	u8 tmp;
6188d5d45fbSJean Delvare 	int old_div;
6198d5d45fbSJean Delvare 	int new_min;
6201c720093SGuenter Roeck 	int ret;
6211c720093SGuenter Roeck 
6221c720093SGuenter Roeck 	ret = kstrtol(buf, 10, &val);
6231c720093SGuenter Roeck 	if (ret)
6241c720093SGuenter Roeck 		return ret;
6258d5d45fbSJean Delvare 
6268d5d45fbSJean Delvare 	tmp = val == 8 ? 0xc0 :
6278d5d45fbSJean Delvare 	      val == 4 ? 0x80 :
6288d5d45fbSJean Delvare 	      val == 2 ? 0x40 :
6298d5d45fbSJean Delvare 	      val == 1 ? 0x00 :
6308d5d45fbSJean Delvare 	      0xff;
6318d5d45fbSJean Delvare 	if (tmp == 0xff)
6328d5d45fbSJean Delvare 		return -EINVAL;
6338d5d45fbSJean Delvare 
6349a61bf63SIngo Molnar 	mutex_lock(&data->update_lock);
63538a1f0e9SJean Delvare 	/* Get fresh readings */
63638a1f0e9SJean Delvare 	data->fan_div[nr] = adm1031_read_value(client,
63738a1f0e9SJean Delvare 					       ADM1031_REG_FAN_DIV(nr));
63838a1f0e9SJean Delvare 	data->fan_min[nr] = adm1031_read_value(client,
63938a1f0e9SJean Delvare 					       ADM1031_REG_FAN_MIN(nr));
64038a1f0e9SJean Delvare 
64138a1f0e9SJean Delvare 	/* Write the new clock divider and fan min */
6428d5d45fbSJean Delvare 	old_div = FAN_DIV_FROM_REG(data->fan_div[nr]);
6436d6006b8SJean Delvare 	data->fan_div[nr] = tmp | (0x3f & data->fan_div[nr]);
6446d6006b8SJean Delvare 	new_min = data->fan_min[nr] * old_div / val;
6458d5d45fbSJean Delvare 	data->fan_min[nr] = new_min > 0xff ? 0xff : new_min;
6468d5d45fbSJean Delvare 
6478d5d45fbSJean Delvare 	adm1031_write_value(client, ADM1031_REG_FAN_DIV(nr),
6488d5d45fbSJean Delvare 			    data->fan_div[nr]);
6498d5d45fbSJean Delvare 	adm1031_write_value(client, ADM1031_REG_FAN_MIN(nr),
6508d5d45fbSJean Delvare 			    data->fan_min[nr]);
65138a1f0e9SJean Delvare 
65238a1f0e9SJean Delvare 	/* Invalidate the cache: fan speed is no longer valid */
65338a1f0e9SJean Delvare 	data->valid = 0;
6549a61bf63SIngo Molnar 	mutex_unlock(&data->update_lock);
6558d5d45fbSJean Delvare 	return count;
6568d5d45fbSJean Delvare }
6578d5d45fbSJean Delvare 
6588e757e15SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(fan1_input, fan, 0);
6598e757e15SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(fan1_min, fan_min, 0);
6608e757e15SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(fan1_div, fan_div, 0);
6618e757e15SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(fan2_input, fan, 1);
6628e757e15SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(fan2_min, fan_min, 1);
6638e757e15SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(fan2_div, fan_div, 1);
6648d5d45fbSJean Delvare 
6658d5d45fbSJean Delvare /* Temps */
6668e757e15SGuenter Roeck static ssize_t temp_show(struct device *dev, struct device_attribute *attr,
6678e757e15SGuenter Roeck 			 char *buf)
6688d5d45fbSJean Delvare {
669c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
6708d5d45fbSJean Delvare 	struct adm1031_data *data = adm1031_update_device(dev);
6718d5d45fbSJean Delvare 	int ext;
6728d5d45fbSJean Delvare 	ext = nr == 0 ?
6738d5d45fbSJean Delvare 	    ((data->ext_temp[nr] >> 6) & 0x3) * 2 :
6748d5d45fbSJean Delvare 	    (((data->ext_temp[nr] >> ((nr - 1) * 3)) & 7));
6758d5d45fbSJean Delvare 	return sprintf(buf, "%d\n", TEMP_FROM_REG_EXT(data->temp[nr], ext));
6768d5d45fbSJean Delvare }
6778e757e15SGuenter Roeck static ssize_t temp_offset_show(struct device *dev,
67849dc9efeSIra Snyder 				struct device_attribute *attr, char *buf)
67949dc9efeSIra Snyder {
68049dc9efeSIra Snyder 	int nr = to_sensor_dev_attr(attr)->index;
68149dc9efeSIra Snyder 	struct adm1031_data *data = adm1031_update_device(dev);
68249dc9efeSIra Snyder 	return sprintf(buf, "%d\n",
68349dc9efeSIra Snyder 		       TEMP_OFFSET_FROM_REG(data->temp_offset[nr]));
68449dc9efeSIra Snyder }
6858e757e15SGuenter Roeck static ssize_t temp_min_show(struct device *dev,
686c801082dSJean Delvare 			     struct device_attribute *attr, char *buf)
6878d5d45fbSJean Delvare {
688c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
6898d5d45fbSJean Delvare 	struct adm1031_data *data = adm1031_update_device(dev);
6908d5d45fbSJean Delvare 	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_min[nr]));
6918d5d45fbSJean Delvare }
6928e757e15SGuenter Roeck static ssize_t temp_max_show(struct device *dev,
693c801082dSJean Delvare 			     struct device_attribute *attr, char *buf)
6948d5d45fbSJean Delvare {
695c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
6968d5d45fbSJean Delvare 	struct adm1031_data *data = adm1031_update_device(dev);
6978d5d45fbSJean Delvare 	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_max[nr]));
6988d5d45fbSJean Delvare }
6998e757e15SGuenter Roeck static ssize_t temp_crit_show(struct device *dev,
700c801082dSJean Delvare 			      struct device_attribute *attr, char *buf)
7018d5d45fbSJean Delvare {
702c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
7038d5d45fbSJean Delvare 	struct adm1031_data *data = adm1031_update_device(dev);
7048d5d45fbSJean Delvare 	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_crit[nr]));
7058d5d45fbSJean Delvare }
7068e757e15SGuenter Roeck static ssize_t temp_offset_store(struct device *dev,
7078e757e15SGuenter Roeck 				 struct device_attribute *attr,
7088e757e15SGuenter Roeck 				 const char *buf, size_t count)
70949dc9efeSIra Snyder {
710b060f3c4SAxel Lin 	struct adm1031_data *data = dev_get_drvdata(dev);
711b060f3c4SAxel Lin 	struct i2c_client *client = data->client;
71249dc9efeSIra Snyder 	int nr = to_sensor_dev_attr(attr)->index;
7131c720093SGuenter Roeck 	long val;
7141c720093SGuenter Roeck 	int ret;
71549dc9efeSIra Snyder 
7161c720093SGuenter Roeck 	ret = kstrtol(buf, 10, &val);
7171c720093SGuenter Roeck 	if (ret)
7181c720093SGuenter Roeck 		return ret;
7191c720093SGuenter Roeck 
7202a844c14SGuenter Roeck 	val = clamp_val(val, -15000, 15000);
72149dc9efeSIra Snyder 	mutex_lock(&data->update_lock);
72249dc9efeSIra Snyder 	data->temp_offset[nr] = TEMP_OFFSET_TO_REG(val);
72349dc9efeSIra Snyder 	adm1031_write_value(client, ADM1031_REG_TEMP_OFFSET(nr),
72449dc9efeSIra Snyder 			    data->temp_offset[nr]);
72549dc9efeSIra Snyder 	mutex_unlock(&data->update_lock);
72649dc9efeSIra Snyder 	return count;
72749dc9efeSIra Snyder }
7288e757e15SGuenter Roeck static ssize_t temp_min_store(struct device *dev,
7298e757e15SGuenter Roeck 			      struct device_attribute *attr, const char *buf,
7308e757e15SGuenter Roeck 			      size_t count)
7318d5d45fbSJean Delvare {
732b060f3c4SAxel Lin 	struct adm1031_data *data = dev_get_drvdata(dev);
733b060f3c4SAxel Lin 	struct i2c_client *client = data->client;
734c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
7351c720093SGuenter Roeck 	long val;
7361c720093SGuenter Roeck 	int ret;
7378d5d45fbSJean Delvare 
7381c720093SGuenter Roeck 	ret = kstrtol(buf, 10, &val);
7391c720093SGuenter Roeck 	if (ret)
7401c720093SGuenter Roeck 		return ret;
7411c720093SGuenter Roeck 
742145e74a4SGuenter Roeck 	val = clamp_val(val, -55000, 127000);
7439a61bf63SIngo Molnar 	mutex_lock(&data->update_lock);
7448d5d45fbSJean Delvare 	data->temp_min[nr] = TEMP_TO_REG(val);
7458d5d45fbSJean Delvare 	adm1031_write_value(client, ADM1031_REG_TEMP_MIN(nr),
7468d5d45fbSJean Delvare 			    data->temp_min[nr]);
7479a61bf63SIngo Molnar 	mutex_unlock(&data->update_lock);
7488d5d45fbSJean Delvare 	return count;
7498d5d45fbSJean Delvare }
7508e757e15SGuenter Roeck static ssize_t temp_max_store(struct device *dev,
7518e757e15SGuenter Roeck 			      struct device_attribute *attr, const char *buf,
7528e757e15SGuenter Roeck 			      size_t count)
7538d5d45fbSJean Delvare {
754b060f3c4SAxel Lin 	struct adm1031_data *data = dev_get_drvdata(dev);
755b060f3c4SAxel Lin 	struct i2c_client *client = data->client;
756c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
7571c720093SGuenter Roeck 	long val;
7581c720093SGuenter Roeck 	int ret;
7598d5d45fbSJean Delvare 
7601c720093SGuenter Roeck 	ret = kstrtol(buf, 10, &val);
7611c720093SGuenter Roeck 	if (ret)
7621c720093SGuenter Roeck 		return ret;
7631c720093SGuenter Roeck 
764145e74a4SGuenter Roeck 	val = clamp_val(val, -55000, 127000);
7659a61bf63SIngo Molnar 	mutex_lock(&data->update_lock);
7668d5d45fbSJean Delvare 	data->temp_max[nr] = TEMP_TO_REG(val);
7678d5d45fbSJean Delvare 	adm1031_write_value(client, ADM1031_REG_TEMP_MAX(nr),
7688d5d45fbSJean Delvare 			    data->temp_max[nr]);
7699a61bf63SIngo Molnar 	mutex_unlock(&data->update_lock);
7708d5d45fbSJean Delvare 	return count;
7718d5d45fbSJean Delvare }
7728e757e15SGuenter Roeck static ssize_t temp_crit_store(struct device *dev,
7738e757e15SGuenter Roeck 			       struct device_attribute *attr, const char *buf,
7748e757e15SGuenter Roeck 			       size_t count)
7758d5d45fbSJean Delvare {
776b060f3c4SAxel Lin 	struct adm1031_data *data = dev_get_drvdata(dev);
777b060f3c4SAxel Lin 	struct i2c_client *client = data->client;
778c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
7791c720093SGuenter Roeck 	long val;
7801c720093SGuenter Roeck 	int ret;
7818d5d45fbSJean Delvare 
7821c720093SGuenter Roeck 	ret = kstrtol(buf, 10, &val);
7831c720093SGuenter Roeck 	if (ret)
7841c720093SGuenter Roeck 		return ret;
7851c720093SGuenter Roeck 
786145e74a4SGuenter Roeck 	val = clamp_val(val, -55000, 127000);
7879a61bf63SIngo Molnar 	mutex_lock(&data->update_lock);
7888d5d45fbSJean Delvare 	data->temp_crit[nr] = TEMP_TO_REG(val);
7898d5d45fbSJean Delvare 	adm1031_write_value(client, ADM1031_REG_TEMP_CRIT(nr),
7908d5d45fbSJean Delvare 			    data->temp_crit[nr]);
7919a61bf63SIngo Molnar 	mutex_unlock(&data->update_lock);
7928d5d45fbSJean Delvare 	return count;
7938d5d45fbSJean Delvare }
7948d5d45fbSJean Delvare 
7958e757e15SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(temp1_input, temp, 0);
7968e757e15SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(temp1_offset, temp_offset, 0);
7978e757e15SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(temp1_min, temp_min, 0);
7988e757e15SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(temp1_max, temp_max, 0);
7998e757e15SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(temp1_crit, temp_crit, 0);
8008e757e15SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(temp2_input, temp, 1);
8018e757e15SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(temp2_offset, temp_offset, 1);
8028e757e15SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(temp2_min, temp_min, 1);
8038e757e15SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(temp2_max, temp_max, 1);
8048e757e15SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(temp2_crit, temp_crit, 1);
8058e757e15SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(temp3_input, temp, 2);
8068e757e15SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(temp3_offset, temp_offset, 2);
8078e757e15SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(temp3_min, temp_min, 2);
8088e757e15SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(temp3_max, temp_max, 2);
8098e757e15SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(temp3_crit, temp_crit, 2);
8108d5d45fbSJean Delvare 
8118d5d45fbSJean Delvare /* Alarms */
812bfb6b173SJulia Lawall static ssize_t alarms_show(struct device *dev, struct device_attribute *attr,
8131c720093SGuenter Roeck 			   char *buf)
8148d5d45fbSJean Delvare {
8158d5d45fbSJean Delvare 	struct adm1031_data *data = adm1031_update_device(dev);
8168d5d45fbSJean Delvare 	return sprintf(buf, "%d\n", data->alarm);
8178d5d45fbSJean Delvare }
8188d5d45fbSJean Delvare 
819bfb6b173SJulia Lawall static DEVICE_ATTR_RO(alarms);
8208d5d45fbSJean Delvare 
8218e757e15SGuenter Roeck static ssize_t alarm_show(struct device *dev, struct device_attribute *attr,
8228e757e15SGuenter Roeck 			  char *buf)
823050ab878SJean Delvare {
824050ab878SJean Delvare 	int bitnr = to_sensor_dev_attr(attr)->index;
825050ab878SJean Delvare 	struct adm1031_data *data = adm1031_update_device(dev);
826050ab878SJean Delvare 	return sprintf(buf, "%d\n", (data->alarm >> bitnr) & 1);
827050ab878SJean Delvare }
828050ab878SJean Delvare 
8298e757e15SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(fan1_alarm, alarm, 0);
8308e757e15SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(fan1_fault, alarm, 1);
8318e757e15SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(temp2_max_alarm, alarm, 2);
8328e757e15SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(temp2_min_alarm, alarm, 3);
8338e757e15SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(temp2_crit_alarm, alarm, 4);
8348e757e15SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(temp2_fault, alarm, 5);
8358e757e15SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(temp1_max_alarm, alarm, 6);
8368e757e15SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(temp1_min_alarm, alarm, 7);
8378e757e15SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(fan2_alarm, alarm, 8);
8388e757e15SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(fan2_fault, alarm, 9);
8398e757e15SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(temp3_max_alarm, alarm, 10);
8408e757e15SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(temp3_min_alarm, alarm, 11);
8418e757e15SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(temp3_crit_alarm, alarm, 12);
8428e757e15SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(temp3_fault, alarm, 13);
8438e757e15SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(temp1_crit_alarm, alarm, 14);
8448d5d45fbSJean Delvare 
845a51b9944SGuenter Roeck /* Update Interval */
846a51b9944SGuenter Roeck static const unsigned int update_intervals[] = {
84787c33daaSJean Delvare 	16000, 8000, 4000, 2000, 1000, 500, 250, 125,
84887c33daaSJean Delvare };
84987c33daaSJean Delvare 
850bfb6b173SJulia Lawall static ssize_t update_interval_show(struct device *dev,
85187c33daaSJean Delvare 				    struct device_attribute *attr, char *buf)
85287c33daaSJean Delvare {
853b060f3c4SAxel Lin 	struct adm1031_data *data = dev_get_drvdata(dev);
85487c33daaSJean Delvare 
855a51b9944SGuenter Roeck 	return sprintf(buf, "%u\n", data->update_interval);
85687c33daaSJean Delvare }
85787c33daaSJean Delvare 
858bfb6b173SJulia Lawall static ssize_t update_interval_store(struct device *dev,
85987c33daaSJean Delvare 				     struct device_attribute *attr,
86087c33daaSJean Delvare 				     const char *buf, size_t count)
86187c33daaSJean Delvare {
862b060f3c4SAxel Lin 	struct adm1031_data *data = dev_get_drvdata(dev);
863b060f3c4SAxel Lin 	struct i2c_client *client = data->client;
86487c33daaSJean Delvare 	unsigned long val;
86587c33daaSJean Delvare 	int i, err;
86687c33daaSJean Delvare 	u8 reg;
86787c33daaSJean Delvare 
868179c4fdbSFrans Meulenbroeks 	err = kstrtoul(buf, 10, &val);
86987c33daaSJean Delvare 	if (err)
87087c33daaSJean Delvare 		return err;
87187c33daaSJean Delvare 
872a51b9944SGuenter Roeck 	/*
873a51b9944SGuenter Roeck 	 * Find the nearest update interval from the table.
874a51b9944SGuenter Roeck 	 * Use it to determine the matching update rate.
875a51b9944SGuenter Roeck 	 */
876a51b9944SGuenter Roeck 	for (i = 0; i < ARRAY_SIZE(update_intervals) - 1; i++) {
877a51b9944SGuenter Roeck 		if (val >= update_intervals[i])
87887c33daaSJean Delvare 			break;
87987c33daaSJean Delvare 	}
880a51b9944SGuenter Roeck 	/* if not found, we point to the last entry (lowest update interval) */
88187c33daaSJean Delvare 
88287c33daaSJean Delvare 	/* set the new update rate while preserving other settings */
88387c33daaSJean Delvare 	reg = adm1031_read_value(client, ADM1031_REG_FAN_FILTER);
88487c33daaSJean Delvare 	reg &= ~ADM1031_UPDATE_RATE_MASK;
88587c33daaSJean Delvare 	reg |= i << ADM1031_UPDATE_RATE_SHIFT;
88687c33daaSJean Delvare 	adm1031_write_value(client, ADM1031_REG_FAN_FILTER, reg);
88787c33daaSJean Delvare 
88887c33daaSJean Delvare 	mutex_lock(&data->update_lock);
889a51b9944SGuenter Roeck 	data->update_interval = update_intervals[i];
89087c33daaSJean Delvare 	mutex_unlock(&data->update_lock);
89187c33daaSJean Delvare 
89287c33daaSJean Delvare 	return count;
89387c33daaSJean Delvare }
89487c33daaSJean Delvare 
895bfb6b173SJulia Lawall static DEVICE_ATTR_RW(update_interval);
89687c33daaSJean Delvare 
897681c6f7aSMark M. Hoffman static struct attribute *adm1031_attributes[] = {
898c801082dSJean Delvare 	&sensor_dev_attr_fan1_input.dev_attr.attr,
899c801082dSJean Delvare 	&sensor_dev_attr_fan1_div.dev_attr.attr,
900c801082dSJean Delvare 	&sensor_dev_attr_fan1_min.dev_attr.attr,
901050ab878SJean Delvare 	&sensor_dev_attr_fan1_alarm.dev_attr.attr,
902050ab878SJean Delvare 	&sensor_dev_attr_fan1_fault.dev_attr.attr,
903c801082dSJean Delvare 	&sensor_dev_attr_pwm1.dev_attr.attr,
904c801082dSJean Delvare 	&sensor_dev_attr_auto_fan1_channel.dev_attr.attr,
905c801082dSJean Delvare 	&sensor_dev_attr_temp1_input.dev_attr.attr,
90649dc9efeSIra Snyder 	&sensor_dev_attr_temp1_offset.dev_attr.attr,
907c801082dSJean Delvare 	&sensor_dev_attr_temp1_min.dev_attr.attr,
908050ab878SJean Delvare 	&sensor_dev_attr_temp1_min_alarm.dev_attr.attr,
909c801082dSJean Delvare 	&sensor_dev_attr_temp1_max.dev_attr.attr,
910050ab878SJean Delvare 	&sensor_dev_attr_temp1_max_alarm.dev_attr.attr,
911c801082dSJean Delvare 	&sensor_dev_attr_temp1_crit.dev_attr.attr,
912050ab878SJean Delvare 	&sensor_dev_attr_temp1_crit_alarm.dev_attr.attr,
913c801082dSJean Delvare 	&sensor_dev_attr_temp2_input.dev_attr.attr,
91449dc9efeSIra Snyder 	&sensor_dev_attr_temp2_offset.dev_attr.attr,
915c801082dSJean Delvare 	&sensor_dev_attr_temp2_min.dev_attr.attr,
916050ab878SJean Delvare 	&sensor_dev_attr_temp2_min_alarm.dev_attr.attr,
917c801082dSJean Delvare 	&sensor_dev_attr_temp2_max.dev_attr.attr,
918050ab878SJean Delvare 	&sensor_dev_attr_temp2_max_alarm.dev_attr.attr,
919c801082dSJean Delvare 	&sensor_dev_attr_temp2_crit.dev_attr.attr,
920050ab878SJean Delvare 	&sensor_dev_attr_temp2_crit_alarm.dev_attr.attr,
921050ab878SJean Delvare 	&sensor_dev_attr_temp2_fault.dev_attr.attr,
922681c6f7aSMark M. Hoffman 
923c801082dSJean Delvare 	&sensor_dev_attr_auto_temp1_off.dev_attr.attr,
924c801082dSJean Delvare 	&sensor_dev_attr_auto_temp1_min.dev_attr.attr,
925c801082dSJean Delvare 	&sensor_dev_attr_auto_temp1_max.dev_attr.attr,
926681c6f7aSMark M. Hoffman 
927c801082dSJean Delvare 	&sensor_dev_attr_auto_temp2_off.dev_attr.attr,
928c801082dSJean Delvare 	&sensor_dev_attr_auto_temp2_min.dev_attr.attr,
929c801082dSJean Delvare 	&sensor_dev_attr_auto_temp2_max.dev_attr.attr,
930681c6f7aSMark M. Hoffman 
931c801082dSJean Delvare 	&sensor_dev_attr_auto_fan1_min_pwm.dev_attr.attr,
932681c6f7aSMark M. Hoffman 
933a51b9944SGuenter Roeck 	&dev_attr_update_interval.attr,
934681c6f7aSMark M. Hoffman 	&dev_attr_alarms.attr,
935681c6f7aSMark M. Hoffman 
936681c6f7aSMark M. Hoffman 	NULL
937681c6f7aSMark M. Hoffman };
938681c6f7aSMark M. Hoffman 
939681c6f7aSMark M. Hoffman static const struct attribute_group adm1031_group = {
940681c6f7aSMark M. Hoffman 	.attrs = adm1031_attributes,
941681c6f7aSMark M. Hoffman };
942681c6f7aSMark M. Hoffman 
943681c6f7aSMark M. Hoffman static struct attribute *adm1031_attributes_opt[] = {
944c801082dSJean Delvare 	&sensor_dev_attr_fan2_input.dev_attr.attr,
945c801082dSJean Delvare 	&sensor_dev_attr_fan2_div.dev_attr.attr,
946c801082dSJean Delvare 	&sensor_dev_attr_fan2_min.dev_attr.attr,
947050ab878SJean Delvare 	&sensor_dev_attr_fan2_alarm.dev_attr.attr,
948050ab878SJean Delvare 	&sensor_dev_attr_fan2_fault.dev_attr.attr,
949c801082dSJean Delvare 	&sensor_dev_attr_pwm2.dev_attr.attr,
950c801082dSJean Delvare 	&sensor_dev_attr_auto_fan2_channel.dev_attr.attr,
951c801082dSJean Delvare 	&sensor_dev_attr_temp3_input.dev_attr.attr,
95249dc9efeSIra Snyder 	&sensor_dev_attr_temp3_offset.dev_attr.attr,
953c801082dSJean Delvare 	&sensor_dev_attr_temp3_min.dev_attr.attr,
954050ab878SJean Delvare 	&sensor_dev_attr_temp3_min_alarm.dev_attr.attr,
955c801082dSJean Delvare 	&sensor_dev_attr_temp3_max.dev_attr.attr,
956050ab878SJean Delvare 	&sensor_dev_attr_temp3_max_alarm.dev_attr.attr,
957c801082dSJean Delvare 	&sensor_dev_attr_temp3_crit.dev_attr.attr,
958050ab878SJean Delvare 	&sensor_dev_attr_temp3_crit_alarm.dev_attr.attr,
959050ab878SJean Delvare 	&sensor_dev_attr_temp3_fault.dev_attr.attr,
960c801082dSJean Delvare 	&sensor_dev_attr_auto_temp3_off.dev_attr.attr,
961c801082dSJean Delvare 	&sensor_dev_attr_auto_temp3_min.dev_attr.attr,
962c801082dSJean Delvare 	&sensor_dev_attr_auto_temp3_max.dev_attr.attr,
963c801082dSJean Delvare 	&sensor_dev_attr_auto_fan2_min_pwm.dev_attr.attr,
964681c6f7aSMark M. Hoffman 	NULL
965681c6f7aSMark M. Hoffman };
966681c6f7aSMark M. Hoffman 
967681c6f7aSMark M. Hoffman static const struct attribute_group adm1031_group_opt = {
968681c6f7aSMark M. Hoffman 	.attrs = adm1031_attributes_opt,
969681c6f7aSMark M. Hoffman };
970681c6f7aSMark M. Hoffman 
971af200f88SJean Delvare /* Return 0 if detection is successful, -ENODEV otherwise */
972310ec792SJean Delvare static int adm1031_detect(struct i2c_client *client,
973af200f88SJean Delvare 			  struct i2c_board_info *info)
9748d5d45fbSJean Delvare {
975af200f88SJean Delvare 	struct i2c_adapter *adapter = client->adapter;
97652df6440SJean Delvare 	const char *name;
97752df6440SJean Delvare 	int id, co;
9788d5d45fbSJean Delvare 
9798d5d45fbSJean Delvare 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
980af200f88SJean Delvare 		return -ENODEV;
9818d5d45fbSJean Delvare 
9826d6006b8SJean Delvare 	id = i2c_smbus_read_byte_data(client, 0x3d);
9836d6006b8SJean Delvare 	co = i2c_smbus_read_byte_data(client, 0x3e);
9848d5d45fbSJean Delvare 
9858d5d45fbSJean Delvare 	if (!((id == 0x31 || id == 0x30) && co == 0x41))
986af200f88SJean Delvare 		return -ENODEV;
98752df6440SJean Delvare 	name = (id == 0x30) ? "adm1030" : "adm1031";
9888d5d45fbSJean Delvare 
989af200f88SJean Delvare 	strlcpy(info->type, name, I2C_NAME_SIZE);
9908d5d45fbSJean Delvare 
991af200f88SJean Delvare 	return 0;
992af200f88SJean Delvare }
993af200f88SJean Delvare 
994278ee1c8SAxel Lin static void adm1031_init_client(struct i2c_client *client)
995278ee1c8SAxel Lin {
996278ee1c8SAxel Lin 	unsigned int read_val;
997278ee1c8SAxel Lin 	unsigned int mask;
998278ee1c8SAxel Lin 	int i;
999278ee1c8SAxel Lin 	struct adm1031_data *data = i2c_get_clientdata(client);
1000278ee1c8SAxel Lin 
1001278ee1c8SAxel Lin 	mask = (ADM1031_CONF2_PWM1_ENABLE | ADM1031_CONF2_TACH1_ENABLE);
1002278ee1c8SAxel Lin 	if (data->chip_type == adm1031) {
1003278ee1c8SAxel Lin 		mask |= (ADM1031_CONF2_PWM2_ENABLE |
1004278ee1c8SAxel Lin 			ADM1031_CONF2_TACH2_ENABLE);
1005278ee1c8SAxel Lin 	}
1006278ee1c8SAxel Lin 	/* Initialize the ADM1031 chip (enables fan speed reading ) */
1007278ee1c8SAxel Lin 	read_val = adm1031_read_value(client, ADM1031_REG_CONF2);
1008278ee1c8SAxel Lin 	if ((read_val | mask) != read_val)
1009278ee1c8SAxel Lin 		adm1031_write_value(client, ADM1031_REG_CONF2, read_val | mask);
1010278ee1c8SAxel Lin 
1011278ee1c8SAxel Lin 	read_val = adm1031_read_value(client, ADM1031_REG_CONF1);
1012278ee1c8SAxel Lin 	if ((read_val | ADM1031_CONF1_MONITOR_ENABLE) != read_val) {
1013278ee1c8SAxel Lin 		adm1031_write_value(client, ADM1031_REG_CONF1,
1014278ee1c8SAxel Lin 				    read_val | ADM1031_CONF1_MONITOR_ENABLE);
1015278ee1c8SAxel Lin 	}
1016278ee1c8SAxel Lin 
1017278ee1c8SAxel Lin 	/* Read the chip's update rate */
1018278ee1c8SAxel Lin 	mask = ADM1031_UPDATE_RATE_MASK;
1019278ee1c8SAxel Lin 	read_val = adm1031_read_value(client, ADM1031_REG_FAN_FILTER);
1020278ee1c8SAxel Lin 	i = (read_val & mask) >> ADM1031_UPDATE_RATE_SHIFT;
1021278ee1c8SAxel Lin 	/* Save it as update interval */
1022278ee1c8SAxel Lin 	data->update_interval = update_intervals[i];
1023278ee1c8SAxel Lin }
1024278ee1c8SAxel Lin 
1025*67487038SStephen Kitt static const struct i2c_device_id adm1031_id[];
1026*67487038SStephen Kitt 
1027*67487038SStephen Kitt static int adm1031_probe(struct i2c_client *client)
1028af200f88SJean Delvare {
1029b060f3c4SAxel Lin 	struct device *dev = &client->dev;
1030b060f3c4SAxel Lin 	struct device *hwmon_dev;
1031af200f88SJean Delvare 	struct adm1031_data *data;
1032af200f88SJean Delvare 
1033b060f3c4SAxel Lin 	data = devm_kzalloc(dev, sizeof(struct adm1031_data), GFP_KERNEL);
1034dc2fd663SGuenter Roeck 	if (!data)
1035dc2fd663SGuenter Roeck 		return -ENOMEM;
1036af200f88SJean Delvare 
1037af200f88SJean Delvare 	i2c_set_clientdata(client, data);
1038b060f3c4SAxel Lin 	data->client = client;
1039*67487038SStephen Kitt 	data->chip_type = i2c_match_id(adm1031_id, client)->driver_data;
10409a61bf63SIngo Molnar 	mutex_init(&data->update_lock);
10418d5d45fbSJean Delvare 
1042af200f88SJean Delvare 	if (data->chip_type == adm1030)
1043af200f88SJean Delvare 		data->chan_select_table = &auto_channel_select_table_adm1030;
1044af200f88SJean Delvare 	else
1045af200f88SJean Delvare 		data->chan_select_table = &auto_channel_select_table_adm1031;
10468d5d45fbSJean Delvare 
10478d5d45fbSJean Delvare 	/* Initialize the ADM1031 chip */
10486d6006b8SJean Delvare 	adm1031_init_client(client);
10498d5d45fbSJean Delvare 
1050b060f3c4SAxel Lin 	/* sysfs hooks */
1051b060f3c4SAxel Lin 	data->groups[0] = &adm1031_group;
1052b060f3c4SAxel Lin 	if (data->chip_type == adm1031)
1053b060f3c4SAxel Lin 		data->groups[1] = &adm1031_group_opt;
1054681c6f7aSMark M. Hoffman 
1055b060f3c4SAxel Lin 	hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
1056b060f3c4SAxel Lin 							   data, data->groups);
1057b060f3c4SAxel Lin 	return PTR_ERR_OR_ZERO(hwmon_dev);
10588d5d45fbSJean Delvare }
10598d5d45fbSJean Delvare 
1060278ee1c8SAxel Lin static const struct i2c_device_id adm1031_id[] = {
1061278ee1c8SAxel Lin 	{ "adm1030", adm1030 },
1062278ee1c8SAxel Lin 	{ "adm1031", adm1031 },
1063278ee1c8SAxel Lin 	{ }
1064278ee1c8SAxel Lin };
1065278ee1c8SAxel Lin MODULE_DEVICE_TABLE(i2c, adm1031_id);
10668d5d45fbSJean Delvare 
1067278ee1c8SAxel Lin static struct i2c_driver adm1031_driver = {
1068278ee1c8SAxel Lin 	.class		= I2C_CLASS_HWMON,
1069278ee1c8SAxel Lin 	.driver = {
1070278ee1c8SAxel Lin 		.name = "adm1031",
1071278ee1c8SAxel Lin 	},
1072*67487038SStephen Kitt 	.probe_new	= adm1031_probe,
1073278ee1c8SAxel Lin 	.id_table	= adm1031_id,
1074278ee1c8SAxel Lin 	.detect		= adm1031_detect,
1075278ee1c8SAxel Lin 	.address_list	= normal_i2c,
1076278ee1c8SAxel Lin };
10778d5d45fbSJean Delvare 
1078f0967eeaSAxel Lin module_i2c_driver(adm1031_driver);
10798d5d45fbSJean Delvare 
10808d5d45fbSJean Delvare MODULE_AUTHOR("Alexandre d'Alton <alex@alexdalton.org>");
10818d5d45fbSJean Delvare MODULE_DESCRIPTION("ADM1031/ADM1030 driver");
10828d5d45fbSJean Delvare MODULE_LICENSE("GPL");
1083