xref: /openbmc/linux/drivers/hwmon/adm1031.c (revision f0967eea80ec2a19a4fe1ad27e3ff1b22c79a3c7)
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))
3987c33daaSJean Delvare #define ADM1031_REG_FAN_FILTER		(0x23)
408d5d45fbSJean Delvare 
4149dc9efeSIra Snyder #define ADM1031_REG_TEMP_OFFSET(nr)	(0x0d + (nr))
428d5d45fbSJean Delvare #define ADM1031_REG_TEMP_MAX(nr)	(0x14 + 4 * (nr))
438d5d45fbSJean Delvare #define ADM1031_REG_TEMP_MIN(nr)	(0x15 + 4 * (nr))
448d5d45fbSJean Delvare #define ADM1031_REG_TEMP_CRIT(nr)	(0x16 + 4 * (nr))
458d5d45fbSJean Delvare 
466d6006b8SJean Delvare #define ADM1031_REG_TEMP(nr)		(0x0a + (nr))
478d5d45fbSJean Delvare #define ADM1031_REG_AUTO_TEMP(nr)	(0x24 + (nr))
488d5d45fbSJean Delvare 
498d5d45fbSJean Delvare #define ADM1031_REG_STATUS(nr)		(0x2 + (nr))
508d5d45fbSJean Delvare 
516d6006b8SJean Delvare #define ADM1031_REG_CONF1		0x00
526d6006b8SJean Delvare #define ADM1031_REG_CONF2		0x01
536d6006b8SJean Delvare #define ADM1031_REG_EXT_TEMP		0x06
548d5d45fbSJean Delvare 
558d5d45fbSJean Delvare #define ADM1031_CONF1_MONITOR_ENABLE	0x01	/* Monitoring enable */
568d5d45fbSJean Delvare #define ADM1031_CONF1_PWM_INVERT	0x08	/* PWM Invert */
578d5d45fbSJean Delvare #define ADM1031_CONF1_AUTO_MODE		0x80	/* Auto FAN */
588d5d45fbSJean Delvare 
598d5d45fbSJean Delvare #define ADM1031_CONF2_PWM1_ENABLE	0x01
608d5d45fbSJean Delvare #define ADM1031_CONF2_PWM2_ENABLE	0x02
618d5d45fbSJean Delvare #define ADM1031_CONF2_TACH1_ENABLE	0x04
628d5d45fbSJean Delvare #define ADM1031_CONF2_TACH2_ENABLE	0x08
638d5d45fbSJean Delvare #define ADM1031_CONF2_TEMP_ENABLE(chan)	(0x10 << (chan))
648d5d45fbSJean Delvare 
6587c33daaSJean Delvare #define ADM1031_UPDATE_RATE_MASK	0x1c
6687c33daaSJean Delvare #define ADM1031_UPDATE_RATE_SHIFT	2
6787c33daaSJean Delvare 
688d5d45fbSJean Delvare /* Addresses to scan */
6925e9c86dSMark M. Hoffman static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
708d5d45fbSJean Delvare 
71e5e9f44cSJean Delvare enum chips { adm1030, adm1031 };
728d5d45fbSJean Delvare 
738d5d45fbSJean Delvare typedef u8 auto_chan_table_t[8][2];
748d5d45fbSJean Delvare 
758d5d45fbSJean Delvare /* Each client has this additional data */
768d5d45fbSJean Delvare struct adm1031_data {
771beeffe4STony Jones 	struct device *hwmon_dev;
789a61bf63SIngo Molnar 	struct mutex update_lock;
798d5d45fbSJean Delvare 	int chip_type;
808d5d45fbSJean Delvare 	char valid;		/* !=0 if following fields are valid */
818d5d45fbSJean Delvare 	unsigned long last_updated;	/* In jiffies */
82a51b9944SGuenter Roeck 	unsigned int update_interval;	/* In milliseconds */
838d5d45fbSJean Delvare 	/* The chan_select_table contains the possible configurations for
848d5d45fbSJean Delvare 	 * auto fan control.
858d5d45fbSJean Delvare 	 */
866d6006b8SJean Delvare 	const auto_chan_table_t *chan_select_table;
878d5d45fbSJean Delvare 	u16 alarm;
888d5d45fbSJean Delvare 	u8 conf1;
898d5d45fbSJean Delvare 	u8 conf2;
908d5d45fbSJean Delvare 	u8 fan[2];
918d5d45fbSJean Delvare 	u8 fan_div[2];
928d5d45fbSJean Delvare 	u8 fan_min[2];
938d5d45fbSJean Delvare 	u8 pwm[2];
948d5d45fbSJean Delvare 	u8 old_pwm[2];
958d5d45fbSJean Delvare 	s8 temp[3];
968d5d45fbSJean Delvare 	u8 ext_temp[3];
978d5d45fbSJean Delvare 	u8 auto_temp[3];
988d5d45fbSJean Delvare 	u8 auto_temp_min[3];
998d5d45fbSJean Delvare 	u8 auto_temp_off[3];
1008d5d45fbSJean Delvare 	u8 auto_temp_max[3];
10149dc9efeSIra Snyder 	s8 temp_offset[3];
1028d5d45fbSJean Delvare 	s8 temp_min[3];
1038d5d45fbSJean Delvare 	s8 temp_max[3];
1048d5d45fbSJean Delvare 	s8 temp_crit[3];
1058d5d45fbSJean Delvare };
1068d5d45fbSJean Delvare 
107af200f88SJean Delvare static int adm1031_probe(struct i2c_client *client,
108af200f88SJean Delvare 			 const struct i2c_device_id *id);
109310ec792SJean Delvare static int adm1031_detect(struct i2c_client *client,
110af200f88SJean Delvare 			  struct i2c_board_info *info);
1118d5d45fbSJean Delvare static void adm1031_init_client(struct i2c_client *client);
112af200f88SJean Delvare static int adm1031_remove(struct i2c_client *client);
1138d5d45fbSJean Delvare static struct adm1031_data *adm1031_update_device(struct device *dev);
1148d5d45fbSJean Delvare 
115af200f88SJean Delvare static const struct i2c_device_id adm1031_id[] = {
116af200f88SJean Delvare 	{ "adm1030", adm1030 },
117af200f88SJean Delvare 	{ "adm1031", adm1031 },
118af200f88SJean Delvare 	{ }
119af200f88SJean Delvare };
120af200f88SJean Delvare MODULE_DEVICE_TABLE(i2c, adm1031_id);
121af200f88SJean Delvare 
1228d5d45fbSJean Delvare /* This is the driver that will be inserted */
1238d5d45fbSJean Delvare static struct i2c_driver adm1031_driver = {
124af200f88SJean Delvare 	.class		= I2C_CLASS_HWMON,
125cdaf7934SLaurent Riffard 	.driver = {
1268d5d45fbSJean Delvare 		.name = "adm1031",
127cdaf7934SLaurent Riffard 	},
128af200f88SJean Delvare 	.probe		= adm1031_probe,
129af200f88SJean Delvare 	.remove		= adm1031_remove,
130af200f88SJean Delvare 	.id_table	= adm1031_id,
131af200f88SJean Delvare 	.detect		= adm1031_detect,
132c3813d6aSJean Delvare 	.address_list	= normal_i2c,
1338d5d45fbSJean Delvare };
1348d5d45fbSJean Delvare 
1358d5d45fbSJean Delvare static inline u8 adm1031_read_value(struct i2c_client *client, u8 reg)
1368d5d45fbSJean Delvare {
1378d5d45fbSJean Delvare 	return i2c_smbus_read_byte_data(client, reg);
1388d5d45fbSJean Delvare }
1398d5d45fbSJean Delvare 
1408d5d45fbSJean Delvare static inline int
1418d5d45fbSJean Delvare adm1031_write_value(struct i2c_client *client, u8 reg, unsigned int value)
1428d5d45fbSJean Delvare {
1438d5d45fbSJean Delvare 	return i2c_smbus_write_byte_data(client, reg, value);
1448d5d45fbSJean Delvare }
1458d5d45fbSJean Delvare 
1468d5d45fbSJean Delvare 
1478d5d45fbSJean Delvare #define TEMP_TO_REG(val)		(((val) < 0 ? ((val - 500) / 1000) : \
1488d5d45fbSJean Delvare 					((val + 500) / 1000)))
1498d5d45fbSJean Delvare 
1508d5d45fbSJean Delvare #define TEMP_FROM_REG(val)		((val) * 1000)
1518d5d45fbSJean Delvare 
1528d5d45fbSJean Delvare #define TEMP_FROM_REG_EXT(val, ext)	(TEMP_FROM_REG(val) + (ext) * 125)
1538d5d45fbSJean Delvare 
15449dc9efeSIra Snyder #define TEMP_OFFSET_TO_REG(val)		(TEMP_TO_REG(val) & 0x8f)
15549dc9efeSIra Snyder #define TEMP_OFFSET_FROM_REG(val)	TEMP_FROM_REG((val) < 0 ? \
15649dc9efeSIra Snyder 						      (val) | 0x70 : (val))
15749dc9efeSIra Snyder 
1581c720093SGuenter Roeck #define FAN_FROM_REG(reg, div)		((reg) ? \
1591c720093SGuenter Roeck 					 (11250 * 60) / ((reg) * (div)) : 0)
1608d5d45fbSJean Delvare 
1618d5d45fbSJean Delvare static int FAN_TO_REG(int reg, int div)
1628d5d45fbSJean Delvare {
1638d5d45fbSJean Delvare 	int tmp;
1648d5d45fbSJean Delvare 	tmp = FAN_FROM_REG(SENSORS_LIMIT(reg, 0, 65535), div);
1658d5d45fbSJean Delvare 	return tmp > 255 ? 255 : tmp;
1668d5d45fbSJean Delvare }
1678d5d45fbSJean Delvare 
1688d5d45fbSJean Delvare #define FAN_DIV_FROM_REG(reg)		(1<<(((reg)&0xc0)>>6))
1698d5d45fbSJean Delvare 
1708d5d45fbSJean Delvare #define PWM_TO_REG(val)			(SENSORS_LIMIT((val), 0, 255) >> 4)
1718d5d45fbSJean Delvare #define PWM_FROM_REG(val)		((val) << 4)
1728d5d45fbSJean Delvare 
1738d5d45fbSJean Delvare #define FAN_CHAN_FROM_REG(reg)		(((reg) >> 5) & 7)
1748d5d45fbSJean Delvare #define FAN_CHAN_TO_REG(val, reg)	\
1758d5d45fbSJean Delvare 	(((reg) & 0x1F) | (((val) << 5) & 0xe0))
1768d5d45fbSJean Delvare 
1778d5d45fbSJean Delvare #define AUTO_TEMP_MIN_TO_REG(val, reg)	\
1788d5d45fbSJean Delvare 	((((val) / 500) & 0xf8) | ((reg) & 0x7))
1798d5d45fbSJean Delvare #define AUTO_TEMP_RANGE_FROM_REG(reg)	(5000 * (1 << ((reg) & 0x7)))
1808d5d45fbSJean Delvare #define AUTO_TEMP_MIN_FROM_REG(reg)	(1000 * ((((reg) >> 3) & 0x1f) << 2))
1818d5d45fbSJean Delvare 
1828d5d45fbSJean Delvare #define AUTO_TEMP_MIN_FROM_REG_DEG(reg)	((((reg) >> 3) & 0x1f) << 2)
1838d5d45fbSJean Delvare 
1848d5d45fbSJean Delvare #define AUTO_TEMP_OFF_FROM_REG(reg)		\
1858d5d45fbSJean Delvare 	(AUTO_TEMP_MIN_FROM_REG(reg) - 5000)
1868d5d45fbSJean Delvare 
1878d5d45fbSJean Delvare #define AUTO_TEMP_MAX_FROM_REG(reg)		\
1888d5d45fbSJean Delvare 	(AUTO_TEMP_RANGE_FROM_REG(reg) +	\
1898d5d45fbSJean Delvare 	AUTO_TEMP_MIN_FROM_REG(reg))
1908d5d45fbSJean Delvare 
1918d5d45fbSJean Delvare static int AUTO_TEMP_MAX_TO_REG(int val, int reg, int pwm)
1928d5d45fbSJean Delvare {
1938d5d45fbSJean Delvare 	int ret;
1948d5d45fbSJean Delvare 	int range = val - AUTO_TEMP_MIN_FROM_REG(reg);
1958d5d45fbSJean Delvare 
1968d5d45fbSJean Delvare 	range = ((val - AUTO_TEMP_MIN_FROM_REG(reg))*10)/(16 - pwm);
1978d5d45fbSJean Delvare 	ret = ((reg & 0xf8) |
1988d5d45fbSJean Delvare 	       (range < 10000 ? 0 :
1998d5d45fbSJean Delvare 		range < 20000 ? 1 :
2008d5d45fbSJean Delvare 		range < 40000 ? 2 : range < 80000 ? 3 : 4));
2018d5d45fbSJean Delvare 	return ret;
2028d5d45fbSJean Delvare }
2038d5d45fbSJean Delvare 
2048d5d45fbSJean Delvare /* FAN auto control */
2058d5d45fbSJean Delvare #define GET_FAN_AUTO_BITFIELD(data, idx)	\
2068d5d45fbSJean Delvare 	(*(data)->chan_select_table)[FAN_CHAN_FROM_REG((data)->conf1)][idx % 2]
2078d5d45fbSJean Delvare 
2088d5d45fbSJean Delvare /* The tables below contains the possible values for the auto fan
2098d5d45fbSJean Delvare  * control bitfields. the index in the table is the register value.
2108d5d45fbSJean Delvare  * MSb is the auto fan control enable bit, so the four first entries
2118d5d45fbSJean Delvare  * in the table disables auto fan control when both bitfields are zero.
2128d5d45fbSJean Delvare  */
2136d6006b8SJean Delvare static const auto_chan_table_t auto_channel_select_table_adm1031 = {
2148d5d45fbSJean Delvare 	{ 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 },
2158d5d45fbSJean Delvare 	{ 2 /* 0b010 */ , 4 /* 0b100 */ },
2168d5d45fbSJean Delvare 	{ 2 /* 0b010 */ , 2 /* 0b010 */ },
2178d5d45fbSJean Delvare 	{ 4 /* 0b100 */ , 4 /* 0b100 */ },
2188d5d45fbSJean Delvare 	{ 7 /* 0b111 */ , 7 /* 0b111 */ },
2198d5d45fbSJean Delvare };
2208d5d45fbSJean Delvare 
2216d6006b8SJean Delvare static const auto_chan_table_t auto_channel_select_table_adm1030 = {
2228d5d45fbSJean Delvare 	{ 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 },
2238d5d45fbSJean Delvare 	{ 2 /* 0b10 */		, 0 },
2248d5d45fbSJean Delvare 	{ 0xff /* invalid */	, 0 },
2258d5d45fbSJean Delvare 	{ 0xff /* invalid */	, 0 },
2268d5d45fbSJean Delvare 	{ 3 /* 0b11 */		, 0 },
2278d5d45fbSJean Delvare };
2288d5d45fbSJean Delvare 
2298d5d45fbSJean Delvare /* That function checks if a bitfield is valid and returns the other bitfield
2308d5d45fbSJean Delvare  * nearest match if no exact match where found.
2318d5d45fbSJean Delvare  */
2328d5d45fbSJean Delvare static int
2338d5d45fbSJean Delvare get_fan_auto_nearest(struct adm1031_data *data,
2348d5d45fbSJean Delvare 		     int chan, u8 val, u8 reg, u8 *new_reg)
2358d5d45fbSJean Delvare {
2368d5d45fbSJean Delvare 	int i;
2378d5d45fbSJean Delvare 	int first_match = -1, exact_match = -1;
2388d5d45fbSJean Delvare 	u8 other_reg_val =
2398d5d45fbSJean Delvare 	    (*data->chan_select_table)[FAN_CHAN_FROM_REG(reg)][chan ? 0 : 1];
2408d5d45fbSJean Delvare 
2418d5d45fbSJean Delvare 	if (val == 0) {
2428d5d45fbSJean Delvare 		*new_reg = 0;
2438d5d45fbSJean Delvare 		return 0;
2448d5d45fbSJean Delvare 	}
2458d5d45fbSJean Delvare 
2468d5d45fbSJean Delvare 	for (i = 0; i < 8; i++) {
2478d5d45fbSJean Delvare 		if ((val == (*data->chan_select_table)[i][chan]) &&
2488d5d45fbSJean Delvare 		    ((*data->chan_select_table)[i][chan ? 0 : 1] ==
2498d5d45fbSJean Delvare 		     other_reg_val)) {
2508d5d45fbSJean Delvare 			/* We found an exact match */
2518d5d45fbSJean Delvare 			exact_match = i;
2528d5d45fbSJean Delvare 			break;
2538d5d45fbSJean Delvare 		} else if (val == (*data->chan_select_table)[i][chan] &&
2548d5d45fbSJean Delvare 			   first_match == -1) {
2556d6006b8SJean Delvare 			/* Save the first match in case of an exact match has
2566d6006b8SJean Delvare 			 * not been found
2578d5d45fbSJean Delvare 			 */
2588d5d45fbSJean Delvare 			first_match = i;
2598d5d45fbSJean Delvare 		}
2608d5d45fbSJean Delvare 	}
2618d5d45fbSJean Delvare 
2621c720093SGuenter Roeck 	if (exact_match >= 0)
2638d5d45fbSJean Delvare 		*new_reg = exact_match;
2641c720093SGuenter Roeck 	else if (first_match >= 0)
2658d5d45fbSJean Delvare 		*new_reg = first_match;
2661c720093SGuenter Roeck 	else
2678d5d45fbSJean Delvare 		return -EINVAL;
2681c720093SGuenter Roeck 
2698d5d45fbSJean Delvare 	return 0;
2708d5d45fbSJean Delvare }
2718d5d45fbSJean Delvare 
272c801082dSJean Delvare static ssize_t show_fan_auto_channel(struct device *dev,
273c801082dSJean Delvare 				     struct device_attribute *attr, char *buf)
2748d5d45fbSJean Delvare {
275c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
2768d5d45fbSJean Delvare 	struct adm1031_data *data = adm1031_update_device(dev);
2778d5d45fbSJean Delvare 	return sprintf(buf, "%d\n", GET_FAN_AUTO_BITFIELD(data, nr));
2788d5d45fbSJean Delvare }
2798d5d45fbSJean Delvare 
2808d5d45fbSJean Delvare static ssize_t
281c801082dSJean Delvare set_fan_auto_channel(struct device *dev, struct device_attribute *attr,
282c801082dSJean Delvare 		     const char *buf, size_t count)
2838d5d45fbSJean Delvare {
2848d5d45fbSJean Delvare 	struct i2c_client *client = to_i2c_client(dev);
2858d5d45fbSJean Delvare 	struct adm1031_data *data = i2c_get_clientdata(client);
286c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
2871c720093SGuenter Roeck 	long val;
2888d5d45fbSJean Delvare 	u8 reg;
2898d5d45fbSJean Delvare 	int ret;
2908d5d45fbSJean Delvare 	u8 old_fan_mode;
2918d5d45fbSJean Delvare 
2921c720093SGuenter Roeck 	ret = kstrtol(buf, 10, &val);
2931c720093SGuenter Roeck 	if (ret)
2941c720093SGuenter Roeck 		return ret;
2951c720093SGuenter Roeck 
2968d5d45fbSJean Delvare 	old_fan_mode = data->conf1;
2978d5d45fbSJean Delvare 
2989a61bf63SIngo Molnar 	mutex_lock(&data->update_lock);
2998d5d45fbSJean Delvare 
3001c720093SGuenter Roeck 	ret = get_fan_auto_nearest(data, nr, val, data->conf1, &reg);
3011c720093SGuenter Roeck 	if (ret) {
3029a61bf63SIngo Molnar 		mutex_unlock(&data->update_lock);
3038d5d45fbSJean Delvare 		return ret;
3048d5d45fbSJean Delvare 	}
3056d6006b8SJean Delvare 	data->conf1 = FAN_CHAN_TO_REG(reg, data->conf1);
3066d6006b8SJean Delvare 	if ((data->conf1 & ADM1031_CONF1_AUTO_MODE) ^
3078d5d45fbSJean Delvare 	    (old_fan_mode & ADM1031_CONF1_AUTO_MODE)) {
3088d5d45fbSJean Delvare 		if (data->conf1 & ADM1031_CONF1_AUTO_MODE) {
3098d5d45fbSJean Delvare 			/* Switch to Auto Fan Mode
3108d5d45fbSJean Delvare 			 * Save PWM registers
3118d5d45fbSJean Delvare 			 * Set PWM registers to 33% Both */
3128d5d45fbSJean Delvare 			data->old_pwm[0] = data->pwm[0];
3138d5d45fbSJean Delvare 			data->old_pwm[1] = data->pwm[1];
3148d5d45fbSJean Delvare 			adm1031_write_value(client, ADM1031_REG_PWM, 0x55);
3158d5d45fbSJean Delvare 		} else {
3168d5d45fbSJean Delvare 			/* Switch to Manual Mode */
3178d5d45fbSJean Delvare 			data->pwm[0] = data->old_pwm[0];
3188d5d45fbSJean Delvare 			data->pwm[1] = data->old_pwm[1];
3198d5d45fbSJean Delvare 			/* Restore PWM registers */
3208d5d45fbSJean Delvare 			adm1031_write_value(client, ADM1031_REG_PWM,
3218d5d45fbSJean Delvare 					    data->pwm[0] | (data->pwm[1] << 4));
3228d5d45fbSJean Delvare 		}
3238d5d45fbSJean Delvare 	}
3248d5d45fbSJean Delvare 	data->conf1 = FAN_CHAN_TO_REG(reg, data->conf1);
3258d5d45fbSJean Delvare 	adm1031_write_value(client, ADM1031_REG_CONF1, data->conf1);
3269a61bf63SIngo Molnar 	mutex_unlock(&data->update_lock);
3278d5d45fbSJean Delvare 	return count;
3288d5d45fbSJean Delvare }
3298d5d45fbSJean Delvare 
330c801082dSJean Delvare static SENSOR_DEVICE_ATTR(auto_fan1_channel, S_IRUGO | S_IWUSR,
331c801082dSJean Delvare 		show_fan_auto_channel, set_fan_auto_channel, 0);
332c801082dSJean Delvare static SENSOR_DEVICE_ATTR(auto_fan2_channel, S_IRUGO | S_IWUSR,
333c801082dSJean Delvare 		show_fan_auto_channel, set_fan_auto_channel, 1);
3348d5d45fbSJean Delvare 
3358d5d45fbSJean Delvare /* Auto Temps */
336c801082dSJean Delvare static ssize_t show_auto_temp_off(struct device *dev,
337c801082dSJean Delvare 				  struct device_attribute *attr, char *buf)
3388d5d45fbSJean Delvare {
339c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
3408d5d45fbSJean Delvare 	struct adm1031_data *data = adm1031_update_device(dev);
3418d5d45fbSJean Delvare 	return sprintf(buf, "%d\n",
3428d5d45fbSJean Delvare 		       AUTO_TEMP_OFF_FROM_REG(data->auto_temp[nr]));
3438d5d45fbSJean Delvare }
344c801082dSJean Delvare static ssize_t show_auto_temp_min(struct device *dev,
345c801082dSJean Delvare 				  struct device_attribute *attr, char *buf)
3468d5d45fbSJean Delvare {
347c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
3488d5d45fbSJean Delvare 	struct adm1031_data *data = adm1031_update_device(dev);
3498d5d45fbSJean Delvare 	return sprintf(buf, "%d\n",
3508d5d45fbSJean Delvare 		       AUTO_TEMP_MIN_FROM_REG(data->auto_temp[nr]));
3518d5d45fbSJean Delvare }
3528d5d45fbSJean Delvare static ssize_t
353c801082dSJean Delvare set_auto_temp_min(struct device *dev, struct device_attribute *attr,
354c801082dSJean Delvare 		  const char *buf, size_t count)
3558d5d45fbSJean Delvare {
3568d5d45fbSJean Delvare 	struct i2c_client *client = to_i2c_client(dev);
3578d5d45fbSJean Delvare 	struct adm1031_data *data = i2c_get_clientdata(client);
358c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
3591c720093SGuenter Roeck 	long val;
3601c720093SGuenter Roeck 	int ret;
3611c720093SGuenter Roeck 
3621c720093SGuenter Roeck 	ret = kstrtol(buf, 10, &val);
3631c720093SGuenter Roeck 	if (ret)
3641c720093SGuenter Roeck 		return ret;
3658d5d45fbSJean Delvare 
3669a61bf63SIngo Molnar 	mutex_lock(&data->update_lock);
3678d5d45fbSJean Delvare 	data->auto_temp[nr] = AUTO_TEMP_MIN_TO_REG(val, data->auto_temp[nr]);
3688d5d45fbSJean Delvare 	adm1031_write_value(client, ADM1031_REG_AUTO_TEMP(nr),
3698d5d45fbSJean Delvare 			    data->auto_temp[nr]);
3709a61bf63SIngo Molnar 	mutex_unlock(&data->update_lock);
3718d5d45fbSJean Delvare 	return count;
3728d5d45fbSJean Delvare }
373c801082dSJean Delvare static ssize_t show_auto_temp_max(struct device *dev,
374c801082dSJean Delvare 				  struct device_attribute *attr, char *buf)
3758d5d45fbSJean Delvare {
376c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
3778d5d45fbSJean Delvare 	struct adm1031_data *data = adm1031_update_device(dev);
3788d5d45fbSJean Delvare 	return sprintf(buf, "%d\n",
3798d5d45fbSJean Delvare 		       AUTO_TEMP_MAX_FROM_REG(data->auto_temp[nr]));
3808d5d45fbSJean Delvare }
3818d5d45fbSJean Delvare static ssize_t
382c801082dSJean Delvare set_auto_temp_max(struct device *dev, struct device_attribute *attr,
383c801082dSJean Delvare 		  const char *buf, size_t count)
3848d5d45fbSJean Delvare {
3858d5d45fbSJean Delvare 	struct i2c_client *client = to_i2c_client(dev);
3868d5d45fbSJean Delvare 	struct adm1031_data *data = i2c_get_clientdata(client);
387c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
3881c720093SGuenter Roeck 	long val;
3891c720093SGuenter Roeck 	int ret;
3901c720093SGuenter Roeck 
3911c720093SGuenter Roeck 	ret = kstrtol(buf, 10, &val);
3921c720093SGuenter Roeck 	if (ret)
3931c720093SGuenter Roeck 		return ret;
3948d5d45fbSJean Delvare 
3959a61bf63SIngo Molnar 	mutex_lock(&data->update_lock);
3961c720093SGuenter Roeck 	data->temp_max[nr] = AUTO_TEMP_MAX_TO_REG(val, data->auto_temp[nr],
3971c720093SGuenter Roeck 						  data->pwm[nr]);
3988d5d45fbSJean Delvare 	adm1031_write_value(client, ADM1031_REG_AUTO_TEMP(nr),
3998d5d45fbSJean Delvare 			    data->temp_max[nr]);
4009a61bf63SIngo Molnar 	mutex_unlock(&data->update_lock);
4018d5d45fbSJean Delvare 	return count;
4028d5d45fbSJean Delvare }
4038d5d45fbSJean Delvare 
4048d5d45fbSJean Delvare #define auto_temp_reg(offset)						\
405c801082dSJean Delvare static SENSOR_DEVICE_ATTR(auto_temp##offset##_off, S_IRUGO,		\
406c801082dSJean Delvare 		show_auto_temp_off, NULL, offset - 1);			\
407c801082dSJean Delvare static SENSOR_DEVICE_ATTR(auto_temp##offset##_min, S_IRUGO | S_IWUSR,	\
408c801082dSJean Delvare 		show_auto_temp_min, set_auto_temp_min, offset - 1);	\
409c801082dSJean Delvare static SENSOR_DEVICE_ATTR(auto_temp##offset##_max, S_IRUGO | S_IWUSR,	\
410c801082dSJean Delvare 		show_auto_temp_max, set_auto_temp_max, offset - 1)
4118d5d45fbSJean Delvare 
4128d5d45fbSJean Delvare auto_temp_reg(1);
4138d5d45fbSJean Delvare auto_temp_reg(2);
4148d5d45fbSJean Delvare auto_temp_reg(3);
4158d5d45fbSJean Delvare 
4168d5d45fbSJean Delvare /* pwm */
417c801082dSJean Delvare static ssize_t show_pwm(struct device *dev,
418c801082dSJean Delvare 			struct device_attribute *attr, char *buf)
4198d5d45fbSJean Delvare {
420c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
4218d5d45fbSJean Delvare 	struct adm1031_data *data = adm1031_update_device(dev);
4228d5d45fbSJean Delvare 	return sprintf(buf, "%d\n", PWM_FROM_REG(data->pwm[nr]));
4238d5d45fbSJean Delvare }
424c801082dSJean Delvare static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
425c801082dSJean Delvare 		       const char *buf, size_t count)
4268d5d45fbSJean Delvare {
4278d5d45fbSJean Delvare 	struct i2c_client *client = to_i2c_client(dev);
4288d5d45fbSJean Delvare 	struct adm1031_data *data = i2c_get_clientdata(client);
429c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
4301c720093SGuenter Roeck 	long val;
4311c720093SGuenter Roeck 	int ret, reg;
4321c720093SGuenter Roeck 
4331c720093SGuenter Roeck 	ret = kstrtol(buf, 10, &val);
4341c720093SGuenter Roeck 	if (ret)
4351c720093SGuenter Roeck 		return ret;
4368d5d45fbSJean Delvare 
4379a61bf63SIngo Molnar 	mutex_lock(&data->update_lock);
4388d5d45fbSJean Delvare 	if ((data->conf1 & ADM1031_CONF1_AUTO_MODE) &&
4398d5d45fbSJean Delvare 	    (((val>>4) & 0xf) != 5)) {
4408d5d45fbSJean Delvare 		/* In automatic mode, the only PWM accepted is 33% */
4419a61bf63SIngo Molnar 		mutex_unlock(&data->update_lock);
4428d5d45fbSJean Delvare 		return -EINVAL;
4438d5d45fbSJean Delvare 	}
4448d5d45fbSJean Delvare 	data->pwm[nr] = PWM_TO_REG(val);
4458d5d45fbSJean Delvare 	reg = adm1031_read_value(client, ADM1031_REG_PWM);
4468d5d45fbSJean Delvare 	adm1031_write_value(client, ADM1031_REG_PWM,
4478d5d45fbSJean Delvare 			    nr ? ((data->pwm[nr] << 4) & 0xf0) | (reg & 0xf)
4488d5d45fbSJean Delvare 			    : (data->pwm[nr] & 0xf) | (reg & 0xf0));
4499a61bf63SIngo Molnar 	mutex_unlock(&data->update_lock);
4508d5d45fbSJean Delvare 	return count;
4518d5d45fbSJean Delvare }
4528d5d45fbSJean Delvare 
453c801082dSJean Delvare static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 0);
454c801082dSJean Delvare static SENSOR_DEVICE_ATTR(pwm2, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 1);
455c801082dSJean Delvare static SENSOR_DEVICE_ATTR(auto_fan1_min_pwm, S_IRUGO | S_IWUSR,
456c801082dSJean Delvare 		show_pwm, set_pwm, 0);
457c801082dSJean Delvare static SENSOR_DEVICE_ATTR(auto_fan2_min_pwm, S_IRUGO | S_IWUSR,
458c801082dSJean Delvare 		show_pwm, set_pwm, 1);
4598d5d45fbSJean Delvare 
4608d5d45fbSJean Delvare /* Fans */
4618d5d45fbSJean Delvare 
4628d5d45fbSJean Delvare /*
4638d5d45fbSJean Delvare  * That function checks the cases where the fan reading is not
4648d5d45fbSJean Delvare  * relevant.  It is used to provide 0 as fan reading when the fan is
4658d5d45fbSJean Delvare  * not supposed to run
4668d5d45fbSJean Delvare  */
4678d5d45fbSJean Delvare static int trust_fan_readings(struct adm1031_data *data, int chan)
4688d5d45fbSJean Delvare {
4698d5d45fbSJean Delvare 	int res = 0;
4708d5d45fbSJean Delvare 
4718d5d45fbSJean Delvare 	if (data->conf1 & ADM1031_CONF1_AUTO_MODE) {
4728d5d45fbSJean Delvare 		switch (data->conf1 & 0x60) {
4731c720093SGuenter Roeck 		case 0x00:
4741c720093SGuenter Roeck 			/*
4751c720093SGuenter Roeck 			 * remote temp1 controls fan1,
4761c720093SGuenter Roeck 			 * remote temp2 controls fan2
4771c720093SGuenter Roeck 			 */
4788d5d45fbSJean Delvare 			res = data->temp[chan+1] >=
4798d5d45fbSJean Delvare 			    AUTO_TEMP_MIN_FROM_REG_DEG(data->auto_temp[chan+1]);
4808d5d45fbSJean Delvare 			break;
4818d5d45fbSJean Delvare 		case 0x20:	/* remote temp1 controls both fans */
4828d5d45fbSJean Delvare 			res =
4838d5d45fbSJean Delvare 			    data->temp[1] >=
4848d5d45fbSJean Delvare 			    AUTO_TEMP_MIN_FROM_REG_DEG(data->auto_temp[1]);
4858d5d45fbSJean Delvare 			break;
4868d5d45fbSJean Delvare 		case 0x40:	/* remote temp2 controls both fans */
4878d5d45fbSJean Delvare 			res =
4888d5d45fbSJean Delvare 			    data->temp[2] >=
4898d5d45fbSJean Delvare 			    AUTO_TEMP_MIN_FROM_REG_DEG(data->auto_temp[2]);
4908d5d45fbSJean Delvare 			break;
4918d5d45fbSJean Delvare 		case 0x60:	/* max controls both fans */
4928d5d45fbSJean Delvare 			res =
4938d5d45fbSJean Delvare 			    data->temp[0] >=
4948d5d45fbSJean Delvare 			    AUTO_TEMP_MIN_FROM_REG_DEG(data->auto_temp[0])
4958d5d45fbSJean Delvare 			    || data->temp[1] >=
4968d5d45fbSJean Delvare 			    AUTO_TEMP_MIN_FROM_REG_DEG(data->auto_temp[1])
4978d5d45fbSJean Delvare 			    || (data->chip_type == adm1031
4988d5d45fbSJean Delvare 				&& data->temp[2] >=
4998d5d45fbSJean Delvare 				AUTO_TEMP_MIN_FROM_REG_DEG(data->auto_temp[2]));
5008d5d45fbSJean Delvare 			break;
5018d5d45fbSJean Delvare 		}
5028d5d45fbSJean Delvare 	} else {
5038d5d45fbSJean Delvare 		res = data->pwm[chan] > 0;
5048d5d45fbSJean Delvare 	}
5058d5d45fbSJean Delvare 	return res;
5068d5d45fbSJean Delvare }
5078d5d45fbSJean Delvare 
5088d5d45fbSJean Delvare 
509c801082dSJean Delvare static ssize_t show_fan(struct device *dev,
510c801082dSJean Delvare 			struct device_attribute *attr, char *buf)
5118d5d45fbSJean Delvare {
512c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
5138d5d45fbSJean Delvare 	struct adm1031_data *data = adm1031_update_device(dev);
5148d5d45fbSJean Delvare 	int value;
5158d5d45fbSJean Delvare 
5168d5d45fbSJean Delvare 	value = trust_fan_readings(data, nr) ? FAN_FROM_REG(data->fan[nr],
5178d5d45fbSJean Delvare 				 FAN_DIV_FROM_REG(data->fan_div[nr])) : 0;
5188d5d45fbSJean Delvare 	return sprintf(buf, "%d\n", value);
5198d5d45fbSJean Delvare }
5208d5d45fbSJean Delvare 
521c801082dSJean Delvare static ssize_t show_fan_div(struct device *dev,
522c801082dSJean Delvare 			    struct device_attribute *attr, char *buf)
5238d5d45fbSJean Delvare {
524c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
5258d5d45fbSJean Delvare 	struct adm1031_data *data = adm1031_update_device(dev);
5268d5d45fbSJean Delvare 	return sprintf(buf, "%d\n", FAN_DIV_FROM_REG(data->fan_div[nr]));
5278d5d45fbSJean Delvare }
528c801082dSJean Delvare static ssize_t show_fan_min(struct device *dev,
529c801082dSJean Delvare 			    struct device_attribute *attr, char *buf)
5308d5d45fbSJean Delvare {
531c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
5328d5d45fbSJean Delvare 	struct adm1031_data *data = adm1031_update_device(dev);
5338d5d45fbSJean Delvare 	return sprintf(buf, "%d\n",
5348d5d45fbSJean Delvare 		       FAN_FROM_REG(data->fan_min[nr],
5358d5d45fbSJean Delvare 				    FAN_DIV_FROM_REG(data->fan_div[nr])));
5368d5d45fbSJean Delvare }
537c801082dSJean Delvare static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
538c801082dSJean Delvare 			   const char *buf, size_t count)
5398d5d45fbSJean Delvare {
5408d5d45fbSJean Delvare 	struct i2c_client *client = to_i2c_client(dev);
5418d5d45fbSJean Delvare 	struct adm1031_data *data = i2c_get_clientdata(client);
542c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
5431c720093SGuenter Roeck 	long val;
5441c720093SGuenter Roeck 	int ret;
5451c720093SGuenter Roeck 
5461c720093SGuenter Roeck 	ret = kstrtol(buf, 10, &val);
5471c720093SGuenter Roeck 	if (ret)
5481c720093SGuenter Roeck 		return ret;
5498d5d45fbSJean Delvare 
5509a61bf63SIngo Molnar 	mutex_lock(&data->update_lock);
5518d5d45fbSJean Delvare 	if (val) {
5528d5d45fbSJean Delvare 		data->fan_min[nr] =
5538d5d45fbSJean Delvare 			FAN_TO_REG(val, FAN_DIV_FROM_REG(data->fan_div[nr]));
5548d5d45fbSJean Delvare 	} else {
5558d5d45fbSJean Delvare 		data->fan_min[nr] = 0xff;
5568d5d45fbSJean Delvare 	}
5578d5d45fbSJean Delvare 	adm1031_write_value(client, ADM1031_REG_FAN_MIN(nr), data->fan_min[nr]);
5589a61bf63SIngo Molnar 	mutex_unlock(&data->update_lock);
5598d5d45fbSJean Delvare 	return count;
5608d5d45fbSJean Delvare }
561c801082dSJean Delvare static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
562c801082dSJean Delvare 			   const char *buf, size_t count)
5638d5d45fbSJean Delvare {
5648d5d45fbSJean Delvare 	struct i2c_client *client = to_i2c_client(dev);
5658d5d45fbSJean Delvare 	struct adm1031_data *data = i2c_get_clientdata(client);
566c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
5671c720093SGuenter Roeck 	long val;
5688d5d45fbSJean Delvare 	u8 tmp;
5698d5d45fbSJean Delvare 	int old_div;
5708d5d45fbSJean Delvare 	int new_min;
5711c720093SGuenter Roeck 	int ret;
5721c720093SGuenter Roeck 
5731c720093SGuenter Roeck 	ret = kstrtol(buf, 10, &val);
5741c720093SGuenter Roeck 	if (ret)
5751c720093SGuenter Roeck 		return ret;
5768d5d45fbSJean Delvare 
5778d5d45fbSJean Delvare 	tmp = val == 8 ? 0xc0 :
5788d5d45fbSJean Delvare 	      val == 4 ? 0x80 :
5798d5d45fbSJean Delvare 	      val == 2 ? 0x40 :
5808d5d45fbSJean Delvare 	      val == 1 ? 0x00 :
5818d5d45fbSJean Delvare 	      0xff;
5828d5d45fbSJean Delvare 	if (tmp == 0xff)
5838d5d45fbSJean Delvare 		return -EINVAL;
5848d5d45fbSJean Delvare 
5859a61bf63SIngo Molnar 	mutex_lock(&data->update_lock);
58638a1f0e9SJean Delvare 	/* Get fresh readings */
58738a1f0e9SJean Delvare 	data->fan_div[nr] = adm1031_read_value(client,
58838a1f0e9SJean Delvare 					       ADM1031_REG_FAN_DIV(nr));
58938a1f0e9SJean Delvare 	data->fan_min[nr] = adm1031_read_value(client,
59038a1f0e9SJean Delvare 					       ADM1031_REG_FAN_MIN(nr));
59138a1f0e9SJean Delvare 
59238a1f0e9SJean Delvare 	/* Write the new clock divider and fan min */
5938d5d45fbSJean Delvare 	old_div = FAN_DIV_FROM_REG(data->fan_div[nr]);
5946d6006b8SJean Delvare 	data->fan_div[nr] = tmp | (0x3f & data->fan_div[nr]);
5956d6006b8SJean Delvare 	new_min = data->fan_min[nr] * old_div / val;
5968d5d45fbSJean Delvare 	data->fan_min[nr] = new_min > 0xff ? 0xff : new_min;
5978d5d45fbSJean Delvare 
5988d5d45fbSJean Delvare 	adm1031_write_value(client, ADM1031_REG_FAN_DIV(nr),
5998d5d45fbSJean Delvare 			    data->fan_div[nr]);
6008d5d45fbSJean Delvare 	adm1031_write_value(client, ADM1031_REG_FAN_MIN(nr),
6018d5d45fbSJean Delvare 			    data->fan_min[nr]);
60238a1f0e9SJean Delvare 
60338a1f0e9SJean Delvare 	/* Invalidate the cache: fan speed is no longer valid */
60438a1f0e9SJean Delvare 	data->valid = 0;
6059a61bf63SIngo Molnar 	mutex_unlock(&data->update_lock);
6068d5d45fbSJean Delvare 	return count;
6078d5d45fbSJean Delvare }
6088d5d45fbSJean Delvare 
6098d5d45fbSJean Delvare #define fan_offset(offset)						\
610c801082dSJean Delvare static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO,			\
611c801082dSJean Delvare 		show_fan, NULL, offset - 1);				\
612c801082dSJean Delvare static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR,		\
613c801082dSJean Delvare 		show_fan_min, set_fan_min, offset - 1);			\
614c801082dSJean Delvare static SENSOR_DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR,		\
615c801082dSJean Delvare 		show_fan_div, set_fan_div, offset - 1)
6168d5d45fbSJean Delvare 
6178d5d45fbSJean Delvare fan_offset(1);
6188d5d45fbSJean Delvare fan_offset(2);
6198d5d45fbSJean Delvare 
6208d5d45fbSJean Delvare 
6218d5d45fbSJean Delvare /* Temps */
622c801082dSJean Delvare static ssize_t show_temp(struct device *dev,
623c801082dSJean Delvare 			 struct device_attribute *attr, char *buf)
6248d5d45fbSJean Delvare {
625c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
6268d5d45fbSJean Delvare 	struct adm1031_data *data = adm1031_update_device(dev);
6278d5d45fbSJean Delvare 	int ext;
6288d5d45fbSJean Delvare 	ext = nr == 0 ?
6298d5d45fbSJean Delvare 	    ((data->ext_temp[nr] >> 6) & 0x3) * 2 :
6308d5d45fbSJean Delvare 	    (((data->ext_temp[nr] >> ((nr - 1) * 3)) & 7));
6318d5d45fbSJean Delvare 	return sprintf(buf, "%d\n", TEMP_FROM_REG_EXT(data->temp[nr], ext));
6328d5d45fbSJean Delvare }
63349dc9efeSIra Snyder static ssize_t show_temp_offset(struct device *dev,
63449dc9efeSIra Snyder 				struct device_attribute *attr, char *buf)
63549dc9efeSIra Snyder {
63649dc9efeSIra Snyder 	int nr = to_sensor_dev_attr(attr)->index;
63749dc9efeSIra Snyder 	struct adm1031_data *data = adm1031_update_device(dev);
63849dc9efeSIra Snyder 	return sprintf(buf, "%d\n",
63949dc9efeSIra Snyder 		       TEMP_OFFSET_FROM_REG(data->temp_offset[nr]));
64049dc9efeSIra Snyder }
641c801082dSJean Delvare static ssize_t show_temp_min(struct device *dev,
642c801082dSJean Delvare 			     struct device_attribute *attr, char *buf)
6438d5d45fbSJean Delvare {
644c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
6458d5d45fbSJean Delvare 	struct adm1031_data *data = adm1031_update_device(dev);
6468d5d45fbSJean Delvare 	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_min[nr]));
6478d5d45fbSJean Delvare }
648c801082dSJean Delvare static ssize_t show_temp_max(struct device *dev,
649c801082dSJean Delvare 			     struct device_attribute *attr, char *buf)
6508d5d45fbSJean Delvare {
651c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
6528d5d45fbSJean Delvare 	struct adm1031_data *data = adm1031_update_device(dev);
6538d5d45fbSJean Delvare 	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_max[nr]));
6548d5d45fbSJean Delvare }
655c801082dSJean Delvare static ssize_t show_temp_crit(struct device *dev,
656c801082dSJean Delvare 			      struct device_attribute *attr, char *buf)
6578d5d45fbSJean Delvare {
658c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
6598d5d45fbSJean Delvare 	struct adm1031_data *data = adm1031_update_device(dev);
6608d5d45fbSJean Delvare 	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_crit[nr]));
6618d5d45fbSJean Delvare }
66249dc9efeSIra Snyder static ssize_t set_temp_offset(struct device *dev,
66349dc9efeSIra Snyder 			       struct device_attribute *attr, const char *buf,
66449dc9efeSIra Snyder 			       size_t count)
66549dc9efeSIra Snyder {
66649dc9efeSIra Snyder 	struct i2c_client *client = to_i2c_client(dev);
66749dc9efeSIra Snyder 	struct adm1031_data *data = i2c_get_clientdata(client);
66849dc9efeSIra Snyder 	int nr = to_sensor_dev_attr(attr)->index;
6691c720093SGuenter Roeck 	long val;
6701c720093SGuenter Roeck 	int ret;
67149dc9efeSIra Snyder 
6721c720093SGuenter Roeck 	ret = kstrtol(buf, 10, &val);
6731c720093SGuenter Roeck 	if (ret)
6741c720093SGuenter Roeck 		return ret;
6751c720093SGuenter Roeck 
67649dc9efeSIra Snyder 	val = SENSORS_LIMIT(val, -15000, 15000);
67749dc9efeSIra Snyder 	mutex_lock(&data->update_lock);
67849dc9efeSIra Snyder 	data->temp_offset[nr] = TEMP_OFFSET_TO_REG(val);
67949dc9efeSIra Snyder 	adm1031_write_value(client, ADM1031_REG_TEMP_OFFSET(nr),
68049dc9efeSIra Snyder 			    data->temp_offset[nr]);
68149dc9efeSIra Snyder 	mutex_unlock(&data->update_lock);
68249dc9efeSIra Snyder 	return count;
68349dc9efeSIra Snyder }
684c801082dSJean Delvare static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr,
685c801082dSJean Delvare 			    const char *buf, size_t count)
6868d5d45fbSJean Delvare {
6878d5d45fbSJean Delvare 	struct i2c_client *client = to_i2c_client(dev);
6888d5d45fbSJean Delvare 	struct adm1031_data *data = i2c_get_clientdata(client);
689c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
6901c720093SGuenter Roeck 	long val;
6911c720093SGuenter Roeck 	int ret;
6928d5d45fbSJean Delvare 
6931c720093SGuenter Roeck 	ret = kstrtol(buf, 10, &val);
6941c720093SGuenter Roeck 	if (ret)
6951c720093SGuenter Roeck 		return ret;
6961c720093SGuenter Roeck 
6978d5d45fbSJean Delvare 	val = SENSORS_LIMIT(val, -55000, nr == 0 ? 127750 : 127875);
6989a61bf63SIngo Molnar 	mutex_lock(&data->update_lock);
6998d5d45fbSJean Delvare 	data->temp_min[nr] = TEMP_TO_REG(val);
7008d5d45fbSJean Delvare 	adm1031_write_value(client, ADM1031_REG_TEMP_MIN(nr),
7018d5d45fbSJean Delvare 			    data->temp_min[nr]);
7029a61bf63SIngo Molnar 	mutex_unlock(&data->update_lock);
7038d5d45fbSJean Delvare 	return count;
7048d5d45fbSJean Delvare }
705c801082dSJean Delvare static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
706c801082dSJean Delvare 			    const char *buf, size_t count)
7078d5d45fbSJean Delvare {
7088d5d45fbSJean Delvare 	struct i2c_client *client = to_i2c_client(dev);
7098d5d45fbSJean Delvare 	struct adm1031_data *data = i2c_get_clientdata(client);
710c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
7111c720093SGuenter Roeck 	long val;
7121c720093SGuenter Roeck 	int ret;
7138d5d45fbSJean Delvare 
7141c720093SGuenter Roeck 	ret = kstrtol(buf, 10, &val);
7151c720093SGuenter Roeck 	if (ret)
7161c720093SGuenter Roeck 		return ret;
7171c720093SGuenter Roeck 
7188d5d45fbSJean Delvare 	val = SENSORS_LIMIT(val, -55000, nr == 0 ? 127750 : 127875);
7199a61bf63SIngo Molnar 	mutex_lock(&data->update_lock);
7208d5d45fbSJean Delvare 	data->temp_max[nr] = TEMP_TO_REG(val);
7218d5d45fbSJean Delvare 	adm1031_write_value(client, ADM1031_REG_TEMP_MAX(nr),
7228d5d45fbSJean Delvare 			    data->temp_max[nr]);
7239a61bf63SIngo Molnar 	mutex_unlock(&data->update_lock);
7248d5d45fbSJean Delvare 	return count;
7258d5d45fbSJean Delvare }
726c801082dSJean Delvare static ssize_t set_temp_crit(struct device *dev, struct device_attribute *attr,
727c801082dSJean Delvare 			     const char *buf, size_t count)
7288d5d45fbSJean Delvare {
7298d5d45fbSJean Delvare 	struct i2c_client *client = to_i2c_client(dev);
7308d5d45fbSJean Delvare 	struct adm1031_data *data = i2c_get_clientdata(client);
731c801082dSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
7321c720093SGuenter Roeck 	long val;
7331c720093SGuenter Roeck 	int ret;
7348d5d45fbSJean Delvare 
7351c720093SGuenter Roeck 	ret = kstrtol(buf, 10, &val);
7361c720093SGuenter Roeck 	if (ret)
7371c720093SGuenter Roeck 		return ret;
7381c720093SGuenter Roeck 
7398d5d45fbSJean Delvare 	val = SENSORS_LIMIT(val, -55000, nr == 0 ? 127750 : 127875);
7409a61bf63SIngo Molnar 	mutex_lock(&data->update_lock);
7418d5d45fbSJean Delvare 	data->temp_crit[nr] = TEMP_TO_REG(val);
7428d5d45fbSJean Delvare 	adm1031_write_value(client, ADM1031_REG_TEMP_CRIT(nr),
7438d5d45fbSJean Delvare 			    data->temp_crit[nr]);
7449a61bf63SIngo Molnar 	mutex_unlock(&data->update_lock);
7458d5d45fbSJean Delvare 	return count;
7468d5d45fbSJean Delvare }
7478d5d45fbSJean Delvare 
7488d5d45fbSJean Delvare #define temp_reg(offset)						\
749c801082dSJean Delvare static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO,		\
750c801082dSJean Delvare 		show_temp, NULL, offset - 1);				\
75149dc9efeSIra Snyder static SENSOR_DEVICE_ATTR(temp##offset##_offset, S_IRUGO | S_IWUSR,	\
75249dc9efeSIra Snyder 		show_temp_offset, set_temp_offset, offset - 1);		\
753c801082dSJean Delvare static SENSOR_DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR,	\
754c801082dSJean Delvare 		show_temp_min, set_temp_min, offset - 1);		\
755c801082dSJean Delvare static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR,	\
756c801082dSJean Delvare 		show_temp_max, set_temp_max, offset - 1);		\
757c801082dSJean Delvare static SENSOR_DEVICE_ATTR(temp##offset##_crit, S_IRUGO | S_IWUSR,	\
758c801082dSJean Delvare 		show_temp_crit, set_temp_crit, offset - 1)
7598d5d45fbSJean Delvare 
7608d5d45fbSJean Delvare temp_reg(1);
7618d5d45fbSJean Delvare temp_reg(2);
7628d5d45fbSJean Delvare temp_reg(3);
7638d5d45fbSJean Delvare 
7648d5d45fbSJean Delvare /* Alarms */
7651c720093SGuenter Roeck static ssize_t show_alarms(struct device *dev, struct device_attribute *attr,
7661c720093SGuenter Roeck 			   char *buf)
7678d5d45fbSJean Delvare {
7688d5d45fbSJean Delvare 	struct adm1031_data *data = adm1031_update_device(dev);
7698d5d45fbSJean Delvare 	return sprintf(buf, "%d\n", data->alarm);
7708d5d45fbSJean Delvare }
7718d5d45fbSJean Delvare 
7728d5d45fbSJean Delvare static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
7738d5d45fbSJean Delvare 
774050ab878SJean Delvare static ssize_t show_alarm(struct device *dev,
775050ab878SJean Delvare 			  struct device_attribute *attr, char *buf)
776050ab878SJean Delvare {
777050ab878SJean Delvare 	int bitnr = to_sensor_dev_attr(attr)->index;
778050ab878SJean Delvare 	struct adm1031_data *data = adm1031_update_device(dev);
779050ab878SJean Delvare 	return sprintf(buf, "%d\n", (data->alarm >> bitnr) & 1);
780050ab878SJean Delvare }
781050ab878SJean Delvare 
782050ab878SJean Delvare static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 0);
783050ab878SJean Delvare static SENSOR_DEVICE_ATTR(fan1_fault, S_IRUGO, show_alarm, NULL, 1);
784050ab878SJean Delvare static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_alarm, NULL, 2);
785050ab878SJean Delvare static SENSOR_DEVICE_ATTR(temp2_min_alarm, S_IRUGO, show_alarm, NULL, 3);
786050ab878SJean Delvare static SENSOR_DEVICE_ATTR(temp2_crit_alarm, S_IRUGO, show_alarm, NULL, 4);
787050ab878SJean Delvare static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_alarm, NULL, 5);
788050ab878SJean Delvare static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 6);
789050ab878SJean Delvare static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, show_alarm, NULL, 7);
790050ab878SJean Delvare static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 8);
791050ab878SJean Delvare static SENSOR_DEVICE_ATTR(fan2_fault, S_IRUGO, show_alarm, NULL, 9);
792050ab878SJean Delvare static SENSOR_DEVICE_ATTR(temp3_max_alarm, S_IRUGO, show_alarm, NULL, 10);
793050ab878SJean Delvare static SENSOR_DEVICE_ATTR(temp3_min_alarm, S_IRUGO, show_alarm, NULL, 11);
794050ab878SJean Delvare static SENSOR_DEVICE_ATTR(temp3_crit_alarm, S_IRUGO, show_alarm, NULL, 12);
795050ab878SJean Delvare static SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_alarm, NULL, 13);
796050ab878SJean Delvare static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 14);
7978d5d45fbSJean Delvare 
798a51b9944SGuenter Roeck /* Update Interval */
799a51b9944SGuenter Roeck static const unsigned int update_intervals[] = {
80087c33daaSJean Delvare 	16000, 8000, 4000, 2000, 1000, 500, 250, 125,
80187c33daaSJean Delvare };
80287c33daaSJean Delvare 
803a51b9944SGuenter Roeck static ssize_t show_update_interval(struct device *dev,
80487c33daaSJean Delvare 				    struct device_attribute *attr, char *buf)
80587c33daaSJean Delvare {
80687c33daaSJean Delvare 	struct i2c_client *client = to_i2c_client(dev);
80787c33daaSJean Delvare 	struct adm1031_data *data = i2c_get_clientdata(client);
80887c33daaSJean Delvare 
809a51b9944SGuenter Roeck 	return sprintf(buf, "%u\n", data->update_interval);
81087c33daaSJean Delvare }
81187c33daaSJean Delvare 
812a51b9944SGuenter Roeck static ssize_t set_update_interval(struct device *dev,
81387c33daaSJean Delvare 				   struct device_attribute *attr,
81487c33daaSJean Delvare 				   const char *buf, size_t count)
81587c33daaSJean Delvare {
81687c33daaSJean Delvare 	struct i2c_client *client = to_i2c_client(dev);
81787c33daaSJean Delvare 	struct adm1031_data *data = i2c_get_clientdata(client);
81887c33daaSJean Delvare 	unsigned long val;
81987c33daaSJean Delvare 	int i, err;
82087c33daaSJean Delvare 	u8 reg;
82187c33daaSJean Delvare 
822179c4fdbSFrans Meulenbroeks 	err = kstrtoul(buf, 10, &val);
82387c33daaSJean Delvare 	if (err)
82487c33daaSJean Delvare 		return err;
82587c33daaSJean Delvare 
826a51b9944SGuenter Roeck 	/*
827a51b9944SGuenter Roeck 	 * Find the nearest update interval from the table.
828a51b9944SGuenter Roeck 	 * Use it to determine the matching update rate.
829a51b9944SGuenter Roeck 	 */
830a51b9944SGuenter Roeck 	for (i = 0; i < ARRAY_SIZE(update_intervals) - 1; i++) {
831a51b9944SGuenter Roeck 		if (val >= update_intervals[i])
83287c33daaSJean Delvare 			break;
83387c33daaSJean Delvare 	}
834a51b9944SGuenter Roeck 	/* if not found, we point to the last entry (lowest update interval) */
83587c33daaSJean Delvare 
83687c33daaSJean Delvare 	/* set the new update rate while preserving other settings */
83787c33daaSJean Delvare 	reg = adm1031_read_value(client, ADM1031_REG_FAN_FILTER);
83887c33daaSJean Delvare 	reg &= ~ADM1031_UPDATE_RATE_MASK;
83987c33daaSJean Delvare 	reg |= i << ADM1031_UPDATE_RATE_SHIFT;
84087c33daaSJean Delvare 	adm1031_write_value(client, ADM1031_REG_FAN_FILTER, reg);
84187c33daaSJean Delvare 
84287c33daaSJean Delvare 	mutex_lock(&data->update_lock);
843a51b9944SGuenter Roeck 	data->update_interval = update_intervals[i];
84487c33daaSJean Delvare 	mutex_unlock(&data->update_lock);
84587c33daaSJean Delvare 
84687c33daaSJean Delvare 	return count;
84787c33daaSJean Delvare }
84887c33daaSJean Delvare 
849a51b9944SGuenter Roeck static DEVICE_ATTR(update_interval, S_IRUGO | S_IWUSR, show_update_interval,
850a51b9944SGuenter Roeck 		   set_update_interval);
85187c33daaSJean Delvare 
852681c6f7aSMark M. Hoffman static struct attribute *adm1031_attributes[] = {
853c801082dSJean Delvare 	&sensor_dev_attr_fan1_input.dev_attr.attr,
854c801082dSJean Delvare 	&sensor_dev_attr_fan1_div.dev_attr.attr,
855c801082dSJean Delvare 	&sensor_dev_attr_fan1_min.dev_attr.attr,
856050ab878SJean Delvare 	&sensor_dev_attr_fan1_alarm.dev_attr.attr,
857050ab878SJean Delvare 	&sensor_dev_attr_fan1_fault.dev_attr.attr,
858c801082dSJean Delvare 	&sensor_dev_attr_pwm1.dev_attr.attr,
859c801082dSJean Delvare 	&sensor_dev_attr_auto_fan1_channel.dev_attr.attr,
860c801082dSJean Delvare 	&sensor_dev_attr_temp1_input.dev_attr.attr,
86149dc9efeSIra Snyder 	&sensor_dev_attr_temp1_offset.dev_attr.attr,
862c801082dSJean Delvare 	&sensor_dev_attr_temp1_min.dev_attr.attr,
863050ab878SJean Delvare 	&sensor_dev_attr_temp1_min_alarm.dev_attr.attr,
864c801082dSJean Delvare 	&sensor_dev_attr_temp1_max.dev_attr.attr,
865050ab878SJean Delvare 	&sensor_dev_attr_temp1_max_alarm.dev_attr.attr,
866c801082dSJean Delvare 	&sensor_dev_attr_temp1_crit.dev_attr.attr,
867050ab878SJean Delvare 	&sensor_dev_attr_temp1_crit_alarm.dev_attr.attr,
868c801082dSJean Delvare 	&sensor_dev_attr_temp2_input.dev_attr.attr,
86949dc9efeSIra Snyder 	&sensor_dev_attr_temp2_offset.dev_attr.attr,
870c801082dSJean Delvare 	&sensor_dev_attr_temp2_min.dev_attr.attr,
871050ab878SJean Delvare 	&sensor_dev_attr_temp2_min_alarm.dev_attr.attr,
872c801082dSJean Delvare 	&sensor_dev_attr_temp2_max.dev_attr.attr,
873050ab878SJean Delvare 	&sensor_dev_attr_temp2_max_alarm.dev_attr.attr,
874c801082dSJean Delvare 	&sensor_dev_attr_temp2_crit.dev_attr.attr,
875050ab878SJean Delvare 	&sensor_dev_attr_temp2_crit_alarm.dev_attr.attr,
876050ab878SJean Delvare 	&sensor_dev_attr_temp2_fault.dev_attr.attr,
877681c6f7aSMark M. Hoffman 
878c801082dSJean Delvare 	&sensor_dev_attr_auto_temp1_off.dev_attr.attr,
879c801082dSJean Delvare 	&sensor_dev_attr_auto_temp1_min.dev_attr.attr,
880c801082dSJean Delvare 	&sensor_dev_attr_auto_temp1_max.dev_attr.attr,
881681c6f7aSMark M. Hoffman 
882c801082dSJean Delvare 	&sensor_dev_attr_auto_temp2_off.dev_attr.attr,
883c801082dSJean Delvare 	&sensor_dev_attr_auto_temp2_min.dev_attr.attr,
884c801082dSJean Delvare 	&sensor_dev_attr_auto_temp2_max.dev_attr.attr,
885681c6f7aSMark M. Hoffman 
886c801082dSJean Delvare 	&sensor_dev_attr_auto_fan1_min_pwm.dev_attr.attr,
887681c6f7aSMark M. Hoffman 
888a51b9944SGuenter Roeck 	&dev_attr_update_interval.attr,
889681c6f7aSMark M. Hoffman 	&dev_attr_alarms.attr,
890681c6f7aSMark M. Hoffman 
891681c6f7aSMark M. Hoffman 	NULL
892681c6f7aSMark M. Hoffman };
893681c6f7aSMark M. Hoffman 
894681c6f7aSMark M. Hoffman static const struct attribute_group adm1031_group = {
895681c6f7aSMark M. Hoffman 	.attrs = adm1031_attributes,
896681c6f7aSMark M. Hoffman };
897681c6f7aSMark M. Hoffman 
898681c6f7aSMark M. Hoffman static struct attribute *adm1031_attributes_opt[] = {
899c801082dSJean Delvare 	&sensor_dev_attr_fan2_input.dev_attr.attr,
900c801082dSJean Delvare 	&sensor_dev_attr_fan2_div.dev_attr.attr,
901c801082dSJean Delvare 	&sensor_dev_attr_fan2_min.dev_attr.attr,
902050ab878SJean Delvare 	&sensor_dev_attr_fan2_alarm.dev_attr.attr,
903050ab878SJean Delvare 	&sensor_dev_attr_fan2_fault.dev_attr.attr,
904c801082dSJean Delvare 	&sensor_dev_attr_pwm2.dev_attr.attr,
905c801082dSJean Delvare 	&sensor_dev_attr_auto_fan2_channel.dev_attr.attr,
906c801082dSJean Delvare 	&sensor_dev_attr_temp3_input.dev_attr.attr,
90749dc9efeSIra Snyder 	&sensor_dev_attr_temp3_offset.dev_attr.attr,
908c801082dSJean Delvare 	&sensor_dev_attr_temp3_min.dev_attr.attr,
909050ab878SJean Delvare 	&sensor_dev_attr_temp3_min_alarm.dev_attr.attr,
910c801082dSJean Delvare 	&sensor_dev_attr_temp3_max.dev_attr.attr,
911050ab878SJean Delvare 	&sensor_dev_attr_temp3_max_alarm.dev_attr.attr,
912c801082dSJean Delvare 	&sensor_dev_attr_temp3_crit.dev_attr.attr,
913050ab878SJean Delvare 	&sensor_dev_attr_temp3_crit_alarm.dev_attr.attr,
914050ab878SJean Delvare 	&sensor_dev_attr_temp3_fault.dev_attr.attr,
915c801082dSJean Delvare 	&sensor_dev_attr_auto_temp3_off.dev_attr.attr,
916c801082dSJean Delvare 	&sensor_dev_attr_auto_temp3_min.dev_attr.attr,
917c801082dSJean Delvare 	&sensor_dev_attr_auto_temp3_max.dev_attr.attr,
918c801082dSJean Delvare 	&sensor_dev_attr_auto_fan2_min_pwm.dev_attr.attr,
919681c6f7aSMark M. Hoffman 	NULL
920681c6f7aSMark M. Hoffman };
921681c6f7aSMark M. Hoffman 
922681c6f7aSMark M. Hoffman static const struct attribute_group adm1031_group_opt = {
923681c6f7aSMark M. Hoffman 	.attrs = adm1031_attributes_opt,
924681c6f7aSMark M. Hoffman };
925681c6f7aSMark M. Hoffman 
926af200f88SJean Delvare /* Return 0 if detection is successful, -ENODEV otherwise */
927310ec792SJean Delvare static int adm1031_detect(struct i2c_client *client,
928af200f88SJean Delvare 			  struct i2c_board_info *info)
9298d5d45fbSJean Delvare {
930af200f88SJean Delvare 	struct i2c_adapter *adapter = client->adapter;
93152df6440SJean Delvare 	const char *name;
93252df6440SJean Delvare 	int id, co;
9338d5d45fbSJean Delvare 
9348d5d45fbSJean Delvare 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
935af200f88SJean Delvare 		return -ENODEV;
9368d5d45fbSJean Delvare 
9376d6006b8SJean Delvare 	id = i2c_smbus_read_byte_data(client, 0x3d);
9386d6006b8SJean Delvare 	co = i2c_smbus_read_byte_data(client, 0x3e);
9398d5d45fbSJean Delvare 
9408d5d45fbSJean Delvare 	if (!((id == 0x31 || id == 0x30) && co == 0x41))
941af200f88SJean Delvare 		return -ENODEV;
94252df6440SJean Delvare 	name = (id == 0x30) ? "adm1030" : "adm1031";
9438d5d45fbSJean Delvare 
944af200f88SJean Delvare 	strlcpy(info->type, name, I2C_NAME_SIZE);
9458d5d45fbSJean Delvare 
946af200f88SJean Delvare 	return 0;
947af200f88SJean Delvare }
948af200f88SJean Delvare 
949af200f88SJean Delvare static int adm1031_probe(struct i2c_client *client,
950af200f88SJean Delvare 			 const struct i2c_device_id *id)
951af200f88SJean Delvare {
952af200f88SJean Delvare 	struct adm1031_data *data;
953af200f88SJean Delvare 	int err;
954af200f88SJean Delvare 
955af200f88SJean Delvare 	data = kzalloc(sizeof(struct adm1031_data), GFP_KERNEL);
956af200f88SJean Delvare 	if (!data) {
957af200f88SJean Delvare 		err = -ENOMEM;
958af200f88SJean Delvare 		goto exit;
959af200f88SJean Delvare 	}
960af200f88SJean Delvare 
961af200f88SJean Delvare 	i2c_set_clientdata(client, data);
962af200f88SJean Delvare 	data->chip_type = id->driver_data;
9639a61bf63SIngo Molnar 	mutex_init(&data->update_lock);
9648d5d45fbSJean Delvare 
965af200f88SJean Delvare 	if (data->chip_type == adm1030)
966af200f88SJean Delvare 		data->chan_select_table = &auto_channel_select_table_adm1030;
967af200f88SJean Delvare 	else
968af200f88SJean Delvare 		data->chan_select_table = &auto_channel_select_table_adm1031;
9698d5d45fbSJean Delvare 
9708d5d45fbSJean Delvare 	/* Initialize the ADM1031 chip */
9716d6006b8SJean Delvare 	adm1031_init_client(client);
9728d5d45fbSJean Delvare 
9738d5d45fbSJean Delvare 	/* Register sysfs hooks */
9741c720093SGuenter Roeck 	err = sysfs_create_group(&client->dev.kobj, &adm1031_group);
9751c720093SGuenter Roeck 	if (err)
976af200f88SJean Delvare 		goto exit_free;
977681c6f7aSMark M. Hoffman 
978af200f88SJean Delvare 	if (data->chip_type == adm1031) {
9791c720093SGuenter Roeck 		err = sysfs_create_group(&client->dev.kobj, &adm1031_group_opt);
9801c720093SGuenter Roeck 		if (err)
981681c6f7aSMark M. Hoffman 			goto exit_remove;
982681c6f7aSMark M. Hoffman 	}
983681c6f7aSMark M. Hoffman 
9846d6006b8SJean Delvare 	data->hwmon_dev = hwmon_device_register(&client->dev);
9851beeffe4STony Jones 	if (IS_ERR(data->hwmon_dev)) {
9861beeffe4STony Jones 		err = PTR_ERR(data->hwmon_dev);
987681c6f7aSMark M. Hoffman 		goto exit_remove;
9888d5d45fbSJean Delvare 	}
9898d5d45fbSJean Delvare 
9908d5d45fbSJean Delvare 	return 0;
9918d5d45fbSJean Delvare 
992681c6f7aSMark M. Hoffman exit_remove:
9936d6006b8SJean Delvare 	sysfs_remove_group(&client->dev.kobj, &adm1031_group);
9946d6006b8SJean Delvare 	sysfs_remove_group(&client->dev.kobj, &adm1031_group_opt);
9958d5d45fbSJean Delvare exit_free:
9961f57ff89SAlexey Dobriyan 	kfree(data);
9978d5d45fbSJean Delvare exit:
9988d5d45fbSJean Delvare 	return err;
9998d5d45fbSJean Delvare }
10008d5d45fbSJean Delvare 
1001af200f88SJean Delvare static int adm1031_remove(struct i2c_client *client)
10028d5d45fbSJean Delvare {
1003943b0830SMark M. Hoffman 	struct adm1031_data *data = i2c_get_clientdata(client);
1004943b0830SMark M. Hoffman 
10051beeffe4STony Jones 	hwmon_device_unregister(data->hwmon_dev);
1006681c6f7aSMark M. Hoffman 	sysfs_remove_group(&client->dev.kobj, &adm1031_group);
1007681c6f7aSMark M. Hoffman 	sysfs_remove_group(&client->dev.kobj, &adm1031_group_opt);
1008943b0830SMark M. Hoffman 	kfree(data);
10098d5d45fbSJean Delvare 	return 0;
10108d5d45fbSJean Delvare }
10118d5d45fbSJean Delvare 
10128d5d45fbSJean Delvare static void adm1031_init_client(struct i2c_client *client)
10138d5d45fbSJean Delvare {
10148d5d45fbSJean Delvare 	unsigned int read_val;
10158d5d45fbSJean Delvare 	unsigned int mask;
101687c33daaSJean Delvare 	int i;
10178d5d45fbSJean Delvare 	struct adm1031_data *data = i2c_get_clientdata(client);
10188d5d45fbSJean Delvare 
10198d5d45fbSJean Delvare 	mask = (ADM1031_CONF2_PWM1_ENABLE | ADM1031_CONF2_TACH1_ENABLE);
10208d5d45fbSJean Delvare 	if (data->chip_type == adm1031) {
10218d5d45fbSJean Delvare 		mask |= (ADM1031_CONF2_PWM2_ENABLE |
10228d5d45fbSJean Delvare 			ADM1031_CONF2_TACH2_ENABLE);
10238d5d45fbSJean Delvare 	}
10248d5d45fbSJean Delvare 	/* Initialize the ADM1031 chip (enables fan speed reading ) */
10258d5d45fbSJean Delvare 	read_val = adm1031_read_value(client, ADM1031_REG_CONF2);
10261c720093SGuenter Roeck 	if ((read_val | mask) != read_val)
10278d5d45fbSJean Delvare 		adm1031_write_value(client, ADM1031_REG_CONF2, read_val | mask);
10288d5d45fbSJean Delvare 
10298d5d45fbSJean Delvare 	read_val = adm1031_read_value(client, ADM1031_REG_CONF1);
10308d5d45fbSJean Delvare 	if ((read_val | ADM1031_CONF1_MONITOR_ENABLE) != read_val) {
10311c720093SGuenter Roeck 		adm1031_write_value(client, ADM1031_REG_CONF1,
10321c720093SGuenter Roeck 				    read_val | ADM1031_CONF1_MONITOR_ENABLE);
10338d5d45fbSJean Delvare 	}
10348d5d45fbSJean Delvare 
103587c33daaSJean Delvare 	/* Read the chip's update rate */
103687c33daaSJean Delvare 	mask = ADM1031_UPDATE_RATE_MASK;
103787c33daaSJean Delvare 	read_val = adm1031_read_value(client, ADM1031_REG_FAN_FILTER);
103887c33daaSJean Delvare 	i = (read_val & mask) >> ADM1031_UPDATE_RATE_SHIFT;
1039a51b9944SGuenter Roeck 	/* Save it as update interval */
1040a51b9944SGuenter Roeck 	data->update_interval = update_intervals[i];
10418d5d45fbSJean Delvare }
10428d5d45fbSJean Delvare 
10438d5d45fbSJean Delvare static struct adm1031_data *adm1031_update_device(struct device *dev)
10448d5d45fbSJean Delvare {
10458d5d45fbSJean Delvare 	struct i2c_client *client = to_i2c_client(dev);
10468d5d45fbSJean Delvare 	struct adm1031_data *data = i2c_get_clientdata(client);
104787c33daaSJean Delvare 	unsigned long next_update;
10488d5d45fbSJean Delvare 	int chan;
10498d5d45fbSJean Delvare 
10509a61bf63SIngo Molnar 	mutex_lock(&data->update_lock);
10518d5d45fbSJean Delvare 
1052a51b9944SGuenter Roeck 	next_update = data->last_updated
1053a51b9944SGuenter Roeck 	  + msecs_to_jiffies(data->update_interval);
105487c33daaSJean Delvare 	if (time_after(jiffies, next_update) || !data->valid) {
10558d5d45fbSJean Delvare 
10568d5d45fbSJean Delvare 		dev_dbg(&client->dev, "Starting adm1031 update\n");
10578d5d45fbSJean Delvare 		for (chan = 0;
10588d5d45fbSJean Delvare 		     chan < ((data->chip_type == adm1031) ? 3 : 2); chan++) {
10598d5d45fbSJean Delvare 			u8 oldh, newh;
10608d5d45fbSJean Delvare 
10618d5d45fbSJean Delvare 			oldh =
10628d5d45fbSJean Delvare 			    adm1031_read_value(client, ADM1031_REG_TEMP(chan));
10638d5d45fbSJean Delvare 			data->ext_temp[chan] =
10648d5d45fbSJean Delvare 			    adm1031_read_value(client, ADM1031_REG_EXT_TEMP);
10658d5d45fbSJean Delvare 			newh =
10668d5d45fbSJean Delvare 			    adm1031_read_value(client, ADM1031_REG_TEMP(chan));
10678d5d45fbSJean Delvare 			if (newh != oldh) {
10688d5d45fbSJean Delvare 				data->ext_temp[chan] =
10698d5d45fbSJean Delvare 				    adm1031_read_value(client,
10708d5d45fbSJean Delvare 						       ADM1031_REG_EXT_TEMP);
10718d5d45fbSJean Delvare #ifdef DEBUG
10728d5d45fbSJean Delvare 				oldh =
10738d5d45fbSJean Delvare 				    adm1031_read_value(client,
10748d5d45fbSJean Delvare 						       ADM1031_REG_TEMP(chan));
10758d5d45fbSJean Delvare 
10768d5d45fbSJean Delvare 				/* oldh is actually newer */
10778d5d45fbSJean Delvare 				if (newh != oldh)
10788d5d45fbSJean Delvare 					dev_warn(&client->dev,
10791c720093SGuenter Roeck 					  "Remote temperature may be wrong.\n");
10808d5d45fbSJean Delvare #endif
10818d5d45fbSJean Delvare 			}
10828d5d45fbSJean Delvare 			data->temp[chan] = newh;
10838d5d45fbSJean Delvare 
108449dc9efeSIra Snyder 			data->temp_offset[chan] =
108549dc9efeSIra Snyder 			    adm1031_read_value(client,
108649dc9efeSIra Snyder 					       ADM1031_REG_TEMP_OFFSET(chan));
10878d5d45fbSJean Delvare 			data->temp_min[chan] =
10888d5d45fbSJean Delvare 			    adm1031_read_value(client,
10898d5d45fbSJean Delvare 					       ADM1031_REG_TEMP_MIN(chan));
10908d5d45fbSJean Delvare 			data->temp_max[chan] =
10918d5d45fbSJean Delvare 			    adm1031_read_value(client,
10928d5d45fbSJean Delvare 					       ADM1031_REG_TEMP_MAX(chan));
10938d5d45fbSJean Delvare 			data->temp_crit[chan] =
10948d5d45fbSJean Delvare 			    adm1031_read_value(client,
10958d5d45fbSJean Delvare 					       ADM1031_REG_TEMP_CRIT(chan));
10968d5d45fbSJean Delvare 			data->auto_temp[chan] =
10978d5d45fbSJean Delvare 			    adm1031_read_value(client,
10988d5d45fbSJean Delvare 					       ADM1031_REG_AUTO_TEMP(chan));
10998d5d45fbSJean Delvare 
11008d5d45fbSJean Delvare 		}
11018d5d45fbSJean Delvare 
11028d5d45fbSJean Delvare 		data->conf1 = adm1031_read_value(client, ADM1031_REG_CONF1);
11038d5d45fbSJean Delvare 		data->conf2 = adm1031_read_value(client, ADM1031_REG_CONF2);
11048d5d45fbSJean Delvare 
11058d5d45fbSJean Delvare 		data->alarm = adm1031_read_value(client, ADM1031_REG_STATUS(0))
11061c720093SGuenter Roeck 		    | (adm1031_read_value(client, ADM1031_REG_STATUS(1)) << 8);
11071c720093SGuenter Roeck 		if (data->chip_type == adm1030)
11088d5d45fbSJean Delvare 			data->alarm &= 0xc0ff;
11098d5d45fbSJean Delvare 
11101c720093SGuenter Roeck 		for (chan = 0; chan < (data->chip_type == adm1030 ? 1 : 2);
11111c720093SGuenter Roeck 		     chan++) {
11128d5d45fbSJean Delvare 			data->fan_div[chan] =
11131c720093SGuenter Roeck 			    adm1031_read_value(client,
11141c720093SGuenter Roeck 					       ADM1031_REG_FAN_DIV(chan));
11158d5d45fbSJean Delvare 			data->fan_min[chan] =
11161c720093SGuenter Roeck 			    adm1031_read_value(client,
11171c720093SGuenter Roeck 					       ADM1031_REG_FAN_MIN(chan));
11188d5d45fbSJean Delvare 			data->fan[chan] =
11191c720093SGuenter Roeck 			    adm1031_read_value(client,
11201c720093SGuenter Roeck 					       ADM1031_REG_FAN_SPEED(chan));
11218d5d45fbSJean Delvare 			data->pwm[chan] =
11221c720093SGuenter Roeck 			  (adm1031_read_value(client,
11231c720093SGuenter Roeck 					ADM1031_REG_PWM) >> (4 * chan)) & 0x0f;
11248d5d45fbSJean Delvare 		}
11258d5d45fbSJean Delvare 		data->last_updated = jiffies;
11268d5d45fbSJean Delvare 		data->valid = 1;
11278d5d45fbSJean Delvare 	}
11288d5d45fbSJean Delvare 
11299a61bf63SIngo Molnar 	mutex_unlock(&data->update_lock);
11308d5d45fbSJean Delvare 
11318d5d45fbSJean Delvare 	return data;
11328d5d45fbSJean Delvare }
11338d5d45fbSJean Delvare 
1134*f0967eeaSAxel Lin module_i2c_driver(adm1031_driver);
11358d5d45fbSJean Delvare 
11368d5d45fbSJean Delvare MODULE_AUTHOR("Alexandre d'Alton <alex@alexdalton.org>");
11378d5d45fbSJean Delvare MODULE_DESCRIPTION("ADM1031/ADM1030 driver");
11388d5d45fbSJean Delvare MODULE_LICENSE("GPL");
1139