xref: /openbmc/linux/drivers/hwmon/lm85.c (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
174ba9207SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
28d5d45fbSJean Delvare /*
309770b26SGuenter Roeck  * lm85.c - Part of lm_sensors, Linux kernel modules for hardware
409770b26SGuenter Roeck  *	    monitoring
509770b26SGuenter Roeck  * Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl>
609770b26SGuenter Roeck  * Copyright (c) 2002, 2003  Philip Pokorny <ppokorny@penguincomputing.com>
709770b26SGuenter Roeck  * Copyright (c) 2003        Margit Schubert-While <margitsw@t-online.de>
809770b26SGuenter Roeck  * Copyright (c) 2004        Justin Thiessen <jthiessen@penguincomputing.com>
9590e8534SJean Delvare  * Copyright (C) 2007--2014  Jean Delvare <jdelvare@suse.de>
1009770b26SGuenter Roeck  *
1109770b26SGuenter Roeck  * Chip details at	      <http://www.national.com/ds/LM/LM85.pdf>
128d5d45fbSJean Delvare  */
138d5d45fbSJean Delvare 
148d5d45fbSJean Delvare #include <linux/module.h>
1539f03438SRob Herring #include <linux/of.h>
168d5d45fbSJean Delvare #include <linux/init.h>
178d5d45fbSJean Delvare #include <linux/slab.h>
188d5d45fbSJean Delvare #include <linux/jiffies.h>
198d5d45fbSJean Delvare #include <linux/i2c.h>
20943b0830SMark M. Hoffman #include <linux/hwmon.h>
21303760b4SJean Delvare #include <linux/hwmon-vid.h>
22b353a487SJean Delvare #include <linux/hwmon-sysfs.h>
23943b0830SMark M. Hoffman #include <linux/err.h>
249a61bf63SIngo Molnar #include <linux/mutex.h>
250f3721c5SBartosz Golaszewski #include <linux/util_macros.h>
268d5d45fbSJean Delvare 
278d5d45fbSJean Delvare /* Addresses to scan */
2825e9c86dSMark M. Hoffman static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
298d5d45fbSJean Delvare 
30e5e9f44cSJean Delvare enum chips {
3111650cf0SJeremy Gebben 	lm85, lm96000,
32e5e9f44cSJean Delvare 	adm1027, adt7463, adt7468,
3306923f84SGuenter Roeck 	emc6d100, emc6d102, emc6d103, emc6d103s
34e5e9f44cSJean Delvare };
358d5d45fbSJean Delvare 
368d5d45fbSJean Delvare /* The LM85 registers */
378d5d45fbSJean Delvare 
388d5d45fbSJean Delvare #define LM85_REG_IN(nr)			(0x20 + (nr))
398d5d45fbSJean Delvare #define LM85_REG_IN_MIN(nr)		(0x44 + (nr) * 2)
408d5d45fbSJean Delvare #define LM85_REG_IN_MAX(nr)		(0x45 + (nr) * 2)
418d5d45fbSJean Delvare 
428d5d45fbSJean Delvare #define LM85_REG_TEMP(nr)		(0x25 + (nr))
438d5d45fbSJean Delvare #define LM85_REG_TEMP_MIN(nr)		(0x4e + (nr) * 2)
448d5d45fbSJean Delvare #define LM85_REG_TEMP_MAX(nr)		(0x4f + (nr) * 2)
458d5d45fbSJean Delvare 
468d5d45fbSJean Delvare /* Fan speeds are LSB, MSB (2 bytes) */
478d5d45fbSJean Delvare #define LM85_REG_FAN(nr)		(0x28 + (nr) * 2)
488d5d45fbSJean Delvare #define LM85_REG_FAN_MIN(nr)		(0x54 + (nr) * 2)
498d5d45fbSJean Delvare 
508d5d45fbSJean Delvare #define LM85_REG_PWM(nr)		(0x30 + (nr))
518d5d45fbSJean Delvare 
528d5d45fbSJean Delvare #define LM85_REG_COMPANY		0x3e
538d5d45fbSJean Delvare #define LM85_REG_VERSTEP		0x3f
5479b92f2bSDarrick J. Wong 
5579b92f2bSDarrick J. Wong #define ADT7468_REG_CFG5		0x7c
56f6c61cffSJean Delvare #define ADT7468_OFF64			(1 << 0)
57f6c61cffSJean Delvare #define ADT7468_HFPWM			(1 << 1)
5879b92f2bSDarrick J. Wong #define IS_ADT7468_OFF64(data)		\
5979b92f2bSDarrick J. Wong 	((data)->type == adt7468 && !((data)->cfg5 & ADT7468_OFF64))
60f6c61cffSJean Delvare #define IS_ADT7468_HFPWM(data)		\
61f6c61cffSJean Delvare 	((data)->type == adt7468 && !((data)->cfg5 & ADT7468_HFPWM))
6279b92f2bSDarrick J. Wong 
638d5d45fbSJean Delvare /* These are the recognized values for the above regs */
648d5d45fbSJean Delvare #define LM85_COMPANY_NATIONAL		0x01
658d5d45fbSJean Delvare #define LM85_COMPANY_ANALOG_DEV		0x41
668d5d45fbSJean Delvare #define LM85_COMPANY_SMSC		0x5c
678d5d45fbSJean Delvare #define LM85_VERSTEP_LM85C		0x60
688d5d45fbSJean Delvare #define LM85_VERSTEP_LM85B		0x62
695cfaf338SJean Delvare #define LM85_VERSTEP_LM96000_1		0x68
705cfaf338SJean Delvare #define LM85_VERSTEP_LM96000_2		0x69
718d5d45fbSJean Delvare #define LM85_VERSTEP_ADM1027		0x60
728d5d45fbSJean Delvare #define LM85_VERSTEP_ADT7463		0x62
738d5d45fbSJean Delvare #define LM85_VERSTEP_ADT7463C		0x6A
7479b92f2bSDarrick J. Wong #define LM85_VERSTEP_ADT7468_1		0x71
7579b92f2bSDarrick J. Wong #define LM85_VERSTEP_ADT7468_2		0x72
768d5d45fbSJean Delvare #define LM85_VERSTEP_EMC6D100_A0        0x60
778d5d45fbSJean Delvare #define LM85_VERSTEP_EMC6D100_A1        0x61
788d5d45fbSJean Delvare #define LM85_VERSTEP_EMC6D102		0x65
79f065a93eSJan Beulich #define LM85_VERSTEP_EMC6D103_A0	0x68
80f065a93eSJan Beulich #define LM85_VERSTEP_EMC6D103_A1	0x69
81f065a93eSJan Beulich #define LM85_VERSTEP_EMC6D103S		0x6A	/* Also known as EMC6D103:A2 */
828d5d45fbSJean Delvare 
838d5d45fbSJean Delvare #define LM85_REG_CONFIG			0x40
848d5d45fbSJean Delvare 
858d5d45fbSJean Delvare #define LM85_REG_ALARM1			0x41
868d5d45fbSJean Delvare #define LM85_REG_ALARM2			0x42
878d5d45fbSJean Delvare 
888d5d45fbSJean Delvare #define LM85_REG_VID			0x43
898d5d45fbSJean Delvare 
908d5d45fbSJean Delvare /* Automated FAN control */
918d5d45fbSJean Delvare #define LM85_REG_AFAN_CONFIG(nr)	(0x5c + (nr))
928d5d45fbSJean Delvare #define LM85_REG_AFAN_RANGE(nr)		(0x5f + (nr))
938d5d45fbSJean Delvare #define LM85_REG_AFAN_SPIKE1		0x62
948d5d45fbSJean Delvare #define LM85_REG_AFAN_MINPWM(nr)	(0x64 + (nr))
958d5d45fbSJean Delvare #define LM85_REG_AFAN_LIMIT(nr)		(0x67 + (nr))
968d5d45fbSJean Delvare #define LM85_REG_AFAN_CRITICAL(nr)	(0x6a + (nr))
978d5d45fbSJean Delvare #define LM85_REG_AFAN_HYST1		0x6d
988d5d45fbSJean Delvare #define LM85_REG_AFAN_HYST2		0x6e
998d5d45fbSJean Delvare 
1008d5d45fbSJean Delvare #define ADM1027_REG_EXTEND_ADC1		0x76
1018d5d45fbSJean Delvare #define ADM1027_REG_EXTEND_ADC2		0x77
1028d5d45fbSJean Delvare 
1038d5d45fbSJean Delvare #define EMC6D100_REG_ALARM3             0x7d
1048d5d45fbSJean Delvare /* IN5, IN6 and IN7 */
1058d5d45fbSJean Delvare #define EMC6D100_REG_IN(nr)             (0x70 + ((nr) - 5))
1068d5d45fbSJean Delvare #define EMC6D100_REG_IN_MIN(nr)         (0x73 + ((nr) - 5) * 2)
1078d5d45fbSJean Delvare #define EMC6D100_REG_IN_MAX(nr)         (0x74 + ((nr) - 5) * 2)
1088d5d45fbSJean Delvare #define EMC6D102_REG_EXTEND_ADC1	0x85
1098d5d45fbSJean Delvare #define EMC6D102_REG_EXTEND_ADC2	0x86
1108d5d45fbSJean Delvare #define EMC6D102_REG_EXTEND_ADC3	0x87
1118d5d45fbSJean Delvare #define EMC6D102_REG_EXTEND_ADC4	0x88
1128d5d45fbSJean Delvare 
11309770b26SGuenter Roeck /*
11409770b26SGuenter Roeck  * Conversions. Rounding and limit checking is only done on the TO_REG
11509770b26SGuenter Roeck  * variants. Note that you should be a bit careful with which arguments
11609770b26SGuenter Roeck  * these macros are called: arguments may be evaluated more than once.
1178d5d45fbSJean Delvare  */
1188d5d45fbSJean Delvare 
11925985edcSLucas De Marchi /* IN are scaled according to built-in resistors */
120e89e22b2SJean Delvare static const int lm85_scaling[] = {  /* .001 Volts */
1218d5d45fbSJean Delvare 	2500, 2250, 3300, 5000, 12000,
1228d5d45fbSJean Delvare 	3300, 1500, 1800 /*EMC6D100*/
1238d5d45fbSJean Delvare };
1248d5d45fbSJean Delvare #define SCALE(val, from, to)	(((val) * (to) + ((from) / 2)) / (from))
1258d5d45fbSJean Delvare 
1268d5d45fbSJean Delvare #define INS_TO_REG(n, val)	\
12767b20034SGuenter Roeck 		SCALE(clamp_val(val, 0, 255 * lm85_scaling[n] / 192), \
12867b20034SGuenter Roeck 		      lm85_scaling[n], 192)
1298d5d45fbSJean Delvare 
1305a4d3ef3SJean Delvare #define INSEXT_FROM_REG(n, val, ext)	\
1315a4d3ef3SJean Delvare 		SCALE(((val) << 4) + (ext), 192 << 4, lm85_scaling[n])
1328d5d45fbSJean Delvare 
1335a4d3ef3SJean Delvare #define INS_FROM_REG(n, val)	SCALE((val), 192, lm85_scaling[n])
1348d5d45fbSJean Delvare 
1358d5d45fbSJean Delvare /* FAN speed is measured using 90kHz clock */
FAN_TO_REG(unsigned long val)13663f281a6SJean Delvare static inline u16 FAN_TO_REG(unsigned long val)
13763f281a6SJean Delvare {
13863f281a6SJean Delvare 	if (!val)
13963f281a6SJean Delvare 		return 0xffff;
1402a844c14SGuenter Roeck 	return clamp_val(5400000 / val, 1, 0xfffe);
14163f281a6SJean Delvare }
1421f44809aSJean Delvare #define FAN_FROM_REG(val)	((val) == 0 ? -1 : (val) == 0xffff ? 0 : \
1431f44809aSJean Delvare 				 5400000 / (val))
1448d5d45fbSJean Delvare 
1458d5d45fbSJean Delvare /* Temperature is reported in .001 degC increments */
1468d5d45fbSJean Delvare #define TEMP_TO_REG(val)	\
1473248c3b7SGuenter Roeck 		DIV_ROUND_CLOSEST(clamp_val((val), -127000, 127000), 1000)
1485a4d3ef3SJean Delvare #define TEMPEXT_FROM_REG(val, ext)	\
1495a4d3ef3SJean Delvare 		SCALE(((val) << 4) + (ext), 16, 1000)
1505a4d3ef3SJean Delvare #define TEMP_FROM_REG(val)	((val) * 1000)
1518d5d45fbSJean Delvare 
1522a844c14SGuenter Roeck #define PWM_TO_REG(val)			clamp_val(val, 0, 255)
1538d5d45fbSJean Delvare #define PWM_FROM_REG(val)		(val)
1548d5d45fbSJean Delvare 
15509770b26SGuenter Roeck /*
15609770b26SGuenter Roeck  * ZONEs have the following parameters:
1578d5d45fbSJean Delvare  *    Limit (low) temp,           1. degC
1588d5d45fbSJean Delvare  *    Hysteresis (below limit),   1. degC (0-15)
1598d5d45fbSJean Delvare  *    Range of speed control,     .1 degC (2-80)
1608d5d45fbSJean Delvare  *    Critical (high) temp,       1. degC
1618d5d45fbSJean Delvare  *
1628d5d45fbSJean Delvare  * FAN PWMs have the following parameters:
1638d5d45fbSJean Delvare  *    Reference Zone,                 1, 2, 3, etc.
1648d5d45fbSJean Delvare  *    Spinup time,                    .05 sec
1658d5d45fbSJean Delvare  *    PWM value at limit/low temp,    1 count
1668d5d45fbSJean Delvare  *    PWM Frequency,                  1. Hz
1678d5d45fbSJean Delvare  *    PWM is Min or OFF below limit,  flag
1688d5d45fbSJean Delvare  *    Invert PWM output,              flag
1698d5d45fbSJean Delvare  *
1708d5d45fbSJean Delvare  * Some chips filter the temp, others the fan.
1718d5d45fbSJean Delvare  *    Filter constant (or disabled)   .1 seconds
1728d5d45fbSJean Delvare  */
1738d5d45fbSJean Delvare 
1748d5d45fbSJean Delvare /* These are the zone temperature range encodings in .001 degree C */
175e89e22b2SJean Delvare static const int lm85_range_map[] = {
1761f44809aSJean Delvare 	2000, 2500, 3300, 4000, 5000, 6600, 8000, 10000,
1771f44809aSJean Delvare 	13300, 16000, 20000, 26600, 32000, 40000, 53300, 80000
1788d5d45fbSJean Delvare };
1791f44809aSJean Delvare 
RANGE_TO_REG(long range)1803248c3b7SGuenter Roeck static int RANGE_TO_REG(long range)
1818d5d45fbSJean Delvare {
1820f3721c5SBartosz Golaszewski 	return find_closest(range, lm85_range_map, ARRAY_SIZE(lm85_range_map));
1838d5d45fbSJean Delvare }
1841f44809aSJean Delvare #define RANGE_FROM_REG(val)	lm85_range_map[(val) & 0x0f]
1858d5d45fbSJean Delvare 
1868d5d45fbSJean Delvare /* These are the PWM frequency encodings */
18757bc3019SJeremy Gebben static const int lm85_freq_map[] = { /* 1 Hz */
1888a0795d9SJean Delvare 	10, 15, 23, 30, 38, 47, 61, 94
1898a0795d9SJean Delvare };
19057bc3019SJeremy Gebben 
191e9b95485SJeremy Gebben static const int lm96000_freq_map[] = { /* 1 Hz */
192e9b95485SJeremy Gebben 	10, 15, 23, 30, 38, 47, 61, 94,
193e9b95485SJeremy Gebben 	22500, 24000, 25700, 25700, 27700, 27700, 30000, 30000
194e9b95485SJeremy Gebben };
195e9b95485SJeremy Gebben 
19657bc3019SJeremy Gebben static const int adm1027_freq_map[] = { /* 1 Hz */
1978a0795d9SJean Delvare 	11, 15, 22, 29, 35, 44, 59, 88
1988d5d45fbSJean Delvare };
1991f44809aSJean Delvare 
FREQ_TO_REG(const int * map,unsigned int map_size,unsigned long freq)2000f3721c5SBartosz Golaszewski static int FREQ_TO_REG(const int *map,
2010f3721c5SBartosz Golaszewski 		       unsigned int map_size, unsigned long freq)
2028d5d45fbSJean Delvare {
2030f3721c5SBartosz Golaszewski 	return find_closest(freq, map, map_size);
2048d5d45fbSJean Delvare }
2058a0795d9SJean Delvare 
FREQ_FROM_REG(const int * map,unsigned int map_size,u8 reg)20657bc3019SJeremy Gebben static int FREQ_FROM_REG(const int *map, unsigned int map_size, u8 reg)
2078a0795d9SJean Delvare {
20857bc3019SJeremy Gebben 	return map[reg % map_size];
2098a0795d9SJean Delvare }
2108d5d45fbSJean Delvare 
21109770b26SGuenter Roeck /*
21209770b26SGuenter Roeck  * Since we can't use strings, I'm abusing these numbers
2138d5d45fbSJean Delvare  *   to stand in for the following meanings:
2148d5d45fbSJean Delvare  *      1 -- PWM responds to Zone 1
2158d5d45fbSJean Delvare  *      2 -- PWM responds to Zone 2
2168d5d45fbSJean Delvare  *      3 -- PWM responds to Zone 3
2178d5d45fbSJean Delvare  *     23 -- PWM responds to the higher temp of Zone 2 or 3
2188d5d45fbSJean Delvare  *    123 -- PWM responds to highest of Zone 1, 2, or 3
2198d5d45fbSJean Delvare  *      0 -- PWM is always at 0% (ie, off)
2208d5d45fbSJean Delvare  *     -1 -- PWM is always at 100%
2218d5d45fbSJean Delvare  *     -2 -- PWM responds to manual control
2228d5d45fbSJean Delvare  */
2238d5d45fbSJean Delvare 
224e89e22b2SJean Delvare static const int lm85_zone_map[] = { 1, 2, 3, -1, 0, 23, 123, -2 };
225e89e22b2SJean Delvare #define ZONE_FROM_REG(val)	lm85_zone_map[(val) >> 5]
2268d5d45fbSJean Delvare 
ZONE_TO_REG(int zone)2278d5d45fbSJean Delvare static int ZONE_TO_REG(int zone)
2288d5d45fbSJean Delvare {
2298d5d45fbSJean Delvare 	int i;
2308d5d45fbSJean Delvare 
2318d5d45fbSJean Delvare 	for (i = 0; i <= 7; ++i)
2328d5d45fbSJean Delvare 		if (zone == lm85_zone_map[i])
2338d5d45fbSJean Delvare 			break;
2348d5d45fbSJean Delvare 	if (i > 7)   /* Not found. */
2358d5d45fbSJean Delvare 		i = 3;  /* Always 100% */
236e89e22b2SJean Delvare 	return i << 5;
2378d5d45fbSJean Delvare }
2388d5d45fbSJean Delvare 
2392a844c14SGuenter Roeck #define HYST_TO_REG(val)	clamp_val(((val) + 500) / 1000, 0, 15)
2408d5d45fbSJean Delvare #define HYST_FROM_REG(val)	((val) * 1000)
2418d5d45fbSJean Delvare 
24209770b26SGuenter Roeck /*
24309770b26SGuenter Roeck  * Chip sampling rates
2448d5d45fbSJean Delvare  *
2458d5d45fbSJean Delvare  * Some sensors are not updated more frequently than once per second
2468d5d45fbSJean Delvare  *    so it doesn't make sense to read them more often than that.
2478d5d45fbSJean Delvare  *    We cache the results and return the saved data if the driver
2488d5d45fbSJean Delvare  *    is called again before a second has elapsed.
2498d5d45fbSJean Delvare  *
2508d5d45fbSJean Delvare  * Also, there is significant configuration data for this chip
2518d5d45fbSJean Delvare  *    given the automatic PWM fan control that is possible.  There
2528d5d45fbSJean Delvare  *    are about 47 bytes of config data to only 22 bytes of actual
2538d5d45fbSJean Delvare  *    readings.  So, we keep the config data up to date in the cache
2548d5d45fbSJean Delvare  *    when it is written and only sample it once every 1 *minute*
2558d5d45fbSJean Delvare  */
2568d5d45fbSJean Delvare #define LM85_DATA_INTERVAL  (HZ + HZ / 2)
2578d5d45fbSJean Delvare #define LM85_CONFIG_INTERVAL  (1 * 60 * HZ)
2588d5d45fbSJean Delvare 
25909770b26SGuenter Roeck /*
26009770b26SGuenter Roeck  * LM85 can automatically adjust fan speeds based on temperature
2618d5d45fbSJean Delvare  * This structure encapsulates an entire Zone config.  There are
2628d5d45fbSJean Delvare  * three zones (one for each temperature input) on the lm85
2638d5d45fbSJean Delvare  */
2648d5d45fbSJean Delvare struct lm85_zone {
2658d5d45fbSJean Delvare 	s8 limit;	/* Low temp limit */
2668d5d45fbSJean Delvare 	u8 hyst;	/* Low limit hysteresis. (0-15) */
2678d5d45fbSJean Delvare 	u8 range;	/* Temp range, encoded */
2688d5d45fbSJean Delvare 	s8 critical;	/* "All fans ON" temp limit */
26909770b26SGuenter Roeck 	u8 max_desired; /*
27009770b26SGuenter Roeck 			 * Actual "max" temperature specified.  Preserved
2718d5d45fbSJean Delvare 			 * to prevent "drift" as other autofan control
2728d5d45fbSJean Delvare 			 * values change.
2738d5d45fbSJean Delvare 			 */
2748d5d45fbSJean Delvare };
2758d5d45fbSJean Delvare 
2768d5d45fbSJean Delvare struct lm85_autofan {
2778d5d45fbSJean Delvare 	u8 config;	/* Register value */
2788d5d45fbSJean Delvare 	u8 min_pwm;	/* Minimum PWM value, encoded */
2798d5d45fbSJean Delvare 	u8 min_off;	/* Min PWM or OFF below "limit", flag */
2808d5d45fbSJean Delvare };
2818d5d45fbSJean Delvare 
28209770b26SGuenter Roeck /*
28309770b26SGuenter Roeck  * For each registered chip, we need to keep some data in memory.
28409770b26SGuenter Roeck  * The structure is dynamically allocated.
28509770b26SGuenter Roeck  */
2868d5d45fbSJean Delvare struct lm85_data {
287746f6884SAxel Lin 	struct i2c_client *client;
288746f6884SAxel Lin 	const struct attribute_group *groups[6];
2898a0795d9SJean Delvare 	const int *freq_map;
29057bc3019SJeremy Gebben 	unsigned int freq_map_size;
29157bc3019SJeremy Gebben 
2928d5d45fbSJean Delvare 	enum chips type;
2938d5d45fbSJean Delvare 
294de248805SGuenter Roeck 	bool has_vid5;	/* true if VID5 is configured for ADT7463 or ADT7468 */
295de248805SGuenter Roeck 
2969a61bf63SIngo Molnar 	struct mutex update_lock;
297952a11caSPaul Fertser 	bool valid;		/* true if following fields are valid */
2988d5d45fbSJean Delvare 	unsigned long last_reading;	/* In jiffies */
2998d5d45fbSJean Delvare 	unsigned long last_config;	/* In jiffies */
3008d5d45fbSJean Delvare 
3018d5d45fbSJean Delvare 	u8 in[8];		/* Register value */
3028d5d45fbSJean Delvare 	u8 in_max[8];		/* Register value */
3038d5d45fbSJean Delvare 	u8 in_min[8];		/* Register value */
3048d5d45fbSJean Delvare 	s8 temp[3];		/* Register value */
3058d5d45fbSJean Delvare 	s8 temp_min[3];		/* Register value */
3068d5d45fbSJean Delvare 	s8 temp_max[3];		/* Register value */
3078d5d45fbSJean Delvare 	u16 fan[4];		/* Register value */
3088d5d45fbSJean Delvare 	u16 fan_min[4];		/* Register value */
3098d5d45fbSJean Delvare 	u8 pwm[3];		/* Register value */
31034e7dc6cSJean Delvare 	u8 pwm_freq[3];		/* Register encoding */
3118d5d45fbSJean Delvare 	u8 temp_ext[3];		/* Decoded values */
3128d5d45fbSJean Delvare 	u8 in_ext[8];		/* Decoded values */
3138d5d45fbSJean Delvare 	u8 vid;			/* Register value */
3148d5d45fbSJean Delvare 	u8 vrm;			/* VRM version */
3158d5d45fbSJean Delvare 	u32 alarms;		/* Register encoding, combined */
31679b92f2bSDarrick J. Wong 	u8 cfg5;		/* Config Register 5 on ADT7468 */
3178d5d45fbSJean Delvare 	struct lm85_autofan autofan[3];
3188d5d45fbSJean Delvare 	struct lm85_zone zone[3];
3198d5d45fbSJean Delvare };
3208d5d45fbSJean Delvare 
lm85_read_value(struct i2c_client * client,u8 reg)3216fd5dd58SAxel Lin static int lm85_read_value(struct i2c_client *client, u8 reg)
3226fd5dd58SAxel Lin {
3236fd5dd58SAxel Lin 	int res;
3248d5d45fbSJean Delvare 
3256fd5dd58SAxel Lin 	/* What size location is it? */
3266fd5dd58SAxel Lin 	switch (reg) {
3276fd5dd58SAxel Lin 	case LM85_REG_FAN(0):  /* Read WORD data */
3286fd5dd58SAxel Lin 	case LM85_REG_FAN(1):
3296fd5dd58SAxel Lin 	case LM85_REG_FAN(2):
3306fd5dd58SAxel Lin 	case LM85_REG_FAN(3):
3316fd5dd58SAxel Lin 	case LM85_REG_FAN_MIN(0):
3326fd5dd58SAxel Lin 	case LM85_REG_FAN_MIN(1):
3336fd5dd58SAxel Lin 	case LM85_REG_FAN_MIN(2):
3346fd5dd58SAxel Lin 	case LM85_REG_FAN_MIN(3):
3356fd5dd58SAxel Lin 	case LM85_REG_ALARM1:	/* Read both bytes at once */
3366fd5dd58SAxel Lin 		res = i2c_smbus_read_byte_data(client, reg) & 0xff;
3376fd5dd58SAxel Lin 		res |= i2c_smbus_read_byte_data(client, reg + 1) << 8;
3386fd5dd58SAxel Lin 		break;
3396fd5dd58SAxel Lin 	default:	/* Read BYTE data */
3406fd5dd58SAxel Lin 		res = i2c_smbus_read_byte_data(client, reg);
3416fd5dd58SAxel Lin 		break;
3426fd5dd58SAxel Lin 	}
3438d5d45fbSJean Delvare 
3446fd5dd58SAxel Lin 	return res;
3456fd5dd58SAxel Lin }
3468d5d45fbSJean Delvare 
lm85_write_value(struct i2c_client * client,u8 reg,int value)3476fd5dd58SAxel Lin static void lm85_write_value(struct i2c_client *client, u8 reg, int value)
3486fd5dd58SAxel Lin {
3496fd5dd58SAxel Lin 	switch (reg) {
3506fd5dd58SAxel Lin 	case LM85_REG_FAN(0):  /* Write WORD data */
3516fd5dd58SAxel Lin 	case LM85_REG_FAN(1):
3526fd5dd58SAxel Lin 	case LM85_REG_FAN(2):
3536fd5dd58SAxel Lin 	case LM85_REG_FAN(3):
3546fd5dd58SAxel Lin 	case LM85_REG_FAN_MIN(0):
3556fd5dd58SAxel Lin 	case LM85_REG_FAN_MIN(1):
3566fd5dd58SAxel Lin 	case LM85_REG_FAN_MIN(2):
3576fd5dd58SAxel Lin 	case LM85_REG_FAN_MIN(3):
3586fd5dd58SAxel Lin 	/* NOTE: ALARM is read only, so not included here */
3596fd5dd58SAxel Lin 		i2c_smbus_write_byte_data(client, reg, value & 0xff);
3606fd5dd58SAxel Lin 		i2c_smbus_write_byte_data(client, reg + 1, value >> 8);
3616fd5dd58SAxel Lin 		break;
3626fd5dd58SAxel Lin 	default:	/* Write BYTE data */
3636fd5dd58SAxel Lin 		i2c_smbus_write_byte_data(client, reg, value);
3646fd5dd58SAxel Lin 		break;
3656fd5dd58SAxel Lin 	}
3666fd5dd58SAxel Lin }
36767712d01SJean Delvare 
lm85_update_device(struct device * dev)3686fd5dd58SAxel Lin static struct lm85_data *lm85_update_device(struct device *dev)
3696fd5dd58SAxel Lin {
370746f6884SAxel Lin 	struct lm85_data *data = dev_get_drvdata(dev);
371746f6884SAxel Lin 	struct i2c_client *client = data->client;
3726fd5dd58SAxel Lin 	int i;
3738d5d45fbSJean Delvare 
3746fd5dd58SAxel Lin 	mutex_lock(&data->update_lock);
3756fd5dd58SAxel Lin 
3766fd5dd58SAxel Lin 	if (!data->valid ||
3776fd5dd58SAxel Lin 	     time_after(jiffies, data->last_reading + LM85_DATA_INTERVAL)) {
3786fd5dd58SAxel Lin 		/* Things that change quickly */
3796fd5dd58SAxel Lin 		dev_dbg(&client->dev, "Reading sensor values\n");
3806fd5dd58SAxel Lin 
3816fd5dd58SAxel Lin 		/*
3826fd5dd58SAxel Lin 		 * Have to read extended bits first to "freeze" the
3836fd5dd58SAxel Lin 		 * more significant bits that are read later.
3846fd5dd58SAxel Lin 		 * There are 2 additional resolution bits per channel and we
3856fd5dd58SAxel Lin 		 * have room for 4, so we shift them to the left.
3866fd5dd58SAxel Lin 		 */
3876fd5dd58SAxel Lin 		if (data->type == adm1027 || data->type == adt7463 ||
3886fd5dd58SAxel Lin 		    data->type == adt7468) {
3896fd5dd58SAxel Lin 			int ext1 = lm85_read_value(client,
3906fd5dd58SAxel Lin 						   ADM1027_REG_EXTEND_ADC1);
3916fd5dd58SAxel Lin 			int ext2 =  lm85_read_value(client,
3926fd5dd58SAxel Lin 						    ADM1027_REG_EXTEND_ADC2);
3936fd5dd58SAxel Lin 			int val = (ext1 << 8) + ext2;
3946fd5dd58SAxel Lin 
3956fd5dd58SAxel Lin 			for (i = 0; i <= 4; i++)
3966fd5dd58SAxel Lin 				data->in_ext[i] =
3976fd5dd58SAxel Lin 					((val >> (i * 2)) & 0x03) << 2;
3986fd5dd58SAxel Lin 
3996fd5dd58SAxel Lin 			for (i = 0; i <= 2; i++)
4006fd5dd58SAxel Lin 				data->temp_ext[i] =
4016fd5dd58SAxel Lin 					(val >> ((i + 4) * 2)) & 0x0c;
4026fd5dd58SAxel Lin 		}
4036fd5dd58SAxel Lin 
4046fd5dd58SAxel Lin 		data->vid = lm85_read_value(client, LM85_REG_VID);
4056fd5dd58SAxel Lin 
4066fd5dd58SAxel Lin 		for (i = 0; i <= 3; ++i) {
4076fd5dd58SAxel Lin 			data->in[i] =
4086fd5dd58SAxel Lin 			    lm85_read_value(client, LM85_REG_IN(i));
4096fd5dd58SAxel Lin 			data->fan[i] =
4106fd5dd58SAxel Lin 			    lm85_read_value(client, LM85_REG_FAN(i));
4116fd5dd58SAxel Lin 		}
4126fd5dd58SAxel Lin 
4136fd5dd58SAxel Lin 		if (!data->has_vid5)
4146fd5dd58SAxel Lin 			data->in[4] = lm85_read_value(client, LM85_REG_IN(4));
4156fd5dd58SAxel Lin 
4166fd5dd58SAxel Lin 		if (data->type == adt7468)
4176fd5dd58SAxel Lin 			data->cfg5 = lm85_read_value(client, ADT7468_REG_CFG5);
4186fd5dd58SAxel Lin 
4196fd5dd58SAxel Lin 		for (i = 0; i <= 2; ++i) {
4206fd5dd58SAxel Lin 			data->temp[i] =
4216fd5dd58SAxel Lin 			    lm85_read_value(client, LM85_REG_TEMP(i));
4226fd5dd58SAxel Lin 			data->pwm[i] =
4236fd5dd58SAxel Lin 			    lm85_read_value(client, LM85_REG_PWM(i));
4246fd5dd58SAxel Lin 
4256fd5dd58SAxel Lin 			if (IS_ADT7468_OFF64(data))
4266fd5dd58SAxel Lin 				data->temp[i] -= 64;
4276fd5dd58SAxel Lin 		}
4286fd5dd58SAxel Lin 
4296fd5dd58SAxel Lin 		data->alarms = lm85_read_value(client, LM85_REG_ALARM1);
4306fd5dd58SAxel Lin 
4316fd5dd58SAxel Lin 		if (data->type == emc6d100) {
4326fd5dd58SAxel Lin 			/* Three more voltage sensors */
4336fd5dd58SAxel Lin 			for (i = 5; i <= 7; ++i) {
4346fd5dd58SAxel Lin 				data->in[i] = lm85_read_value(client,
4356fd5dd58SAxel Lin 							EMC6D100_REG_IN(i));
4366fd5dd58SAxel Lin 			}
4376fd5dd58SAxel Lin 			/* More alarm bits */
4386fd5dd58SAxel Lin 			data->alarms |= lm85_read_value(client,
4396fd5dd58SAxel Lin 						EMC6D100_REG_ALARM3) << 16;
4406fd5dd58SAxel Lin 		} else if (data->type == emc6d102 || data->type == emc6d103 ||
4416fd5dd58SAxel Lin 			   data->type == emc6d103s) {
4426fd5dd58SAxel Lin 			/*
4436fd5dd58SAxel Lin 			 * Have to read LSB bits after the MSB ones because
4446fd5dd58SAxel Lin 			 * the reading of the MSB bits has frozen the
4456fd5dd58SAxel Lin 			 * LSBs (backward from the ADM1027).
4466fd5dd58SAxel Lin 			 */
4476fd5dd58SAxel Lin 			int ext1 = lm85_read_value(client,
4486fd5dd58SAxel Lin 						   EMC6D102_REG_EXTEND_ADC1);
4496fd5dd58SAxel Lin 			int ext2 = lm85_read_value(client,
4506fd5dd58SAxel Lin 						   EMC6D102_REG_EXTEND_ADC2);
4516fd5dd58SAxel Lin 			int ext3 = lm85_read_value(client,
4526fd5dd58SAxel Lin 						   EMC6D102_REG_EXTEND_ADC3);
4536fd5dd58SAxel Lin 			int ext4 = lm85_read_value(client,
4546fd5dd58SAxel Lin 						   EMC6D102_REG_EXTEND_ADC4);
4556fd5dd58SAxel Lin 			data->in_ext[0] = ext3 & 0x0f;
4566fd5dd58SAxel Lin 			data->in_ext[1] = ext4 & 0x0f;
4576fd5dd58SAxel Lin 			data->in_ext[2] = ext4 >> 4;
4586fd5dd58SAxel Lin 			data->in_ext[3] = ext3 >> 4;
4596fd5dd58SAxel Lin 			data->in_ext[4] = ext2 >> 4;
4606fd5dd58SAxel Lin 
4616fd5dd58SAxel Lin 			data->temp_ext[0] = ext1 & 0x0f;
4626fd5dd58SAxel Lin 			data->temp_ext[1] = ext2 & 0x0f;
4636fd5dd58SAxel Lin 			data->temp_ext[2] = ext1 >> 4;
4646fd5dd58SAxel Lin 		}
4656fd5dd58SAxel Lin 
4666fd5dd58SAxel Lin 		data->last_reading = jiffies;
4676fd5dd58SAxel Lin 	}  /* last_reading */
4686fd5dd58SAxel Lin 
4696fd5dd58SAxel Lin 	if (!data->valid ||
4706fd5dd58SAxel Lin 	     time_after(jiffies, data->last_config + LM85_CONFIG_INTERVAL)) {
4716fd5dd58SAxel Lin 		/* Things that don't change often */
4726fd5dd58SAxel Lin 		dev_dbg(&client->dev, "Reading config values\n");
4736fd5dd58SAxel Lin 
4746fd5dd58SAxel Lin 		for (i = 0; i <= 3; ++i) {
4756fd5dd58SAxel Lin 			data->in_min[i] =
4766fd5dd58SAxel Lin 			    lm85_read_value(client, LM85_REG_IN_MIN(i));
4776fd5dd58SAxel Lin 			data->in_max[i] =
4786fd5dd58SAxel Lin 			    lm85_read_value(client, LM85_REG_IN_MAX(i));
4796fd5dd58SAxel Lin 			data->fan_min[i] =
4806fd5dd58SAxel Lin 			    lm85_read_value(client, LM85_REG_FAN_MIN(i));
4816fd5dd58SAxel Lin 		}
4826fd5dd58SAxel Lin 
4836fd5dd58SAxel Lin 		if (!data->has_vid5)  {
4846fd5dd58SAxel Lin 			data->in_min[4] = lm85_read_value(client,
4856fd5dd58SAxel Lin 					  LM85_REG_IN_MIN(4));
4866fd5dd58SAxel Lin 			data->in_max[4] = lm85_read_value(client,
4876fd5dd58SAxel Lin 					  LM85_REG_IN_MAX(4));
4886fd5dd58SAxel Lin 		}
4896fd5dd58SAxel Lin 
4906fd5dd58SAxel Lin 		if (data->type == emc6d100) {
4916fd5dd58SAxel Lin 			for (i = 5; i <= 7; ++i) {
4926fd5dd58SAxel Lin 				data->in_min[i] = lm85_read_value(client,
4936fd5dd58SAxel Lin 						EMC6D100_REG_IN_MIN(i));
4946fd5dd58SAxel Lin 				data->in_max[i] = lm85_read_value(client,
4956fd5dd58SAxel Lin 						EMC6D100_REG_IN_MAX(i));
4966fd5dd58SAxel Lin 			}
4976fd5dd58SAxel Lin 		}
4986fd5dd58SAxel Lin 
4996fd5dd58SAxel Lin 		for (i = 0; i <= 2; ++i) {
5006fd5dd58SAxel Lin 			int val;
5016fd5dd58SAxel Lin 
5026fd5dd58SAxel Lin 			data->temp_min[i] =
5036fd5dd58SAxel Lin 			    lm85_read_value(client, LM85_REG_TEMP_MIN(i));
5046fd5dd58SAxel Lin 			data->temp_max[i] =
5056fd5dd58SAxel Lin 			    lm85_read_value(client, LM85_REG_TEMP_MAX(i));
5066fd5dd58SAxel Lin 
5076fd5dd58SAxel Lin 			data->autofan[i].config =
5086fd5dd58SAxel Lin 			    lm85_read_value(client, LM85_REG_AFAN_CONFIG(i));
5096fd5dd58SAxel Lin 			val = lm85_read_value(client, LM85_REG_AFAN_RANGE(i));
51057bc3019SJeremy Gebben 			data->pwm_freq[i] = val % data->freq_map_size;
5116fd5dd58SAxel Lin 			data->zone[i].range = val >> 4;
5126fd5dd58SAxel Lin 			data->autofan[i].min_pwm =
5136fd5dd58SAxel Lin 			    lm85_read_value(client, LM85_REG_AFAN_MINPWM(i));
5146fd5dd58SAxel Lin 			data->zone[i].limit =
5156fd5dd58SAxel Lin 			    lm85_read_value(client, LM85_REG_AFAN_LIMIT(i));
5166fd5dd58SAxel Lin 			data->zone[i].critical =
5176fd5dd58SAxel Lin 			    lm85_read_value(client, LM85_REG_AFAN_CRITICAL(i));
5186fd5dd58SAxel Lin 
5196fd5dd58SAxel Lin 			if (IS_ADT7468_OFF64(data)) {
5206fd5dd58SAxel Lin 				data->temp_min[i] -= 64;
5216fd5dd58SAxel Lin 				data->temp_max[i] -= 64;
5226fd5dd58SAxel Lin 				data->zone[i].limit -= 64;
5236fd5dd58SAxel Lin 				data->zone[i].critical -= 64;
5246fd5dd58SAxel Lin 			}
5256fd5dd58SAxel Lin 		}
5266fd5dd58SAxel Lin 
5276fd5dd58SAxel Lin 		if (data->type != emc6d103s) {
5286fd5dd58SAxel Lin 			i = lm85_read_value(client, LM85_REG_AFAN_SPIKE1);
5296fd5dd58SAxel Lin 			data->autofan[0].min_off = (i & 0x20) != 0;
5306fd5dd58SAxel Lin 			data->autofan[1].min_off = (i & 0x40) != 0;
5316fd5dd58SAxel Lin 			data->autofan[2].min_off = (i & 0x80) != 0;
5326fd5dd58SAxel Lin 
5336fd5dd58SAxel Lin 			i = lm85_read_value(client, LM85_REG_AFAN_HYST1);
5346fd5dd58SAxel Lin 			data->zone[0].hyst = i >> 4;
5356fd5dd58SAxel Lin 			data->zone[1].hyst = i & 0x0f;
5366fd5dd58SAxel Lin 
5376fd5dd58SAxel Lin 			i = lm85_read_value(client, LM85_REG_AFAN_HYST2);
5386fd5dd58SAxel Lin 			data->zone[2].hyst = i >> 4;
5396fd5dd58SAxel Lin 		}
5406fd5dd58SAxel Lin 
5416fd5dd58SAxel Lin 		data->last_config = jiffies;
5426fd5dd58SAxel Lin 	}  /* last_config */
5436fd5dd58SAxel Lin 
544952a11caSPaul Fertser 	data->valid = true;
5456fd5dd58SAxel Lin 
5466fd5dd58SAxel Lin 	mutex_unlock(&data->update_lock);
5476fd5dd58SAxel Lin 
5486fd5dd58SAxel Lin 	return data;
5496fd5dd58SAxel Lin }
5508d5d45fbSJean Delvare 
5518d5d45fbSJean Delvare /* 4 Fans */
fan_show(struct device * dev,struct device_attribute * attr,char * buf)5527bc85e49SGuenter Roeck static ssize_t fan_show(struct device *dev, struct device_attribute *attr,
553b353a487SJean Delvare 			char *buf)
5548d5d45fbSJean Delvare {
555b353a487SJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
5568d5d45fbSJean Delvare 	struct lm85_data *data = lm85_update_device(dev);
5578d5d45fbSJean Delvare 	return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr]));
5588d5d45fbSJean Delvare }
559b353a487SJean Delvare 
fan_min_show(struct device * dev,struct device_attribute * attr,char * buf)5607bc85e49SGuenter Roeck static ssize_t fan_min_show(struct device *dev, struct device_attribute *attr,
561b353a487SJean Delvare 			    char *buf)
5628d5d45fbSJean Delvare {
563b353a487SJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
5648d5d45fbSJean Delvare 	struct lm85_data *data = lm85_update_device(dev);
5658d5d45fbSJean Delvare 	return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_min[nr]));
5668d5d45fbSJean Delvare }
567b353a487SJean Delvare 
fan_min_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)5687bc85e49SGuenter Roeck static ssize_t fan_min_store(struct device *dev,
5697bc85e49SGuenter Roeck 			     struct device_attribute *attr, const char *buf,
5707bc85e49SGuenter Roeck 			     size_t count)
5718d5d45fbSJean Delvare {
572b353a487SJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
573746f6884SAxel Lin 	struct lm85_data *data = dev_get_drvdata(dev);
574746f6884SAxel Lin 	struct i2c_client *client = data->client;
57509770b26SGuenter Roeck 	unsigned long val;
57609770b26SGuenter Roeck 	int err;
57709770b26SGuenter Roeck 
57809770b26SGuenter Roeck 	err = kstrtoul(buf, 10, &val);
57909770b26SGuenter Roeck 	if (err)
58009770b26SGuenter Roeck 		return err;
5818d5d45fbSJean Delvare 
5829a61bf63SIngo Molnar 	mutex_lock(&data->update_lock);
5838d5d45fbSJean Delvare 	data->fan_min[nr] = FAN_TO_REG(val);
5848d5d45fbSJean Delvare 	lm85_write_value(client, LM85_REG_FAN_MIN(nr), data->fan_min[nr]);
5859a61bf63SIngo Molnar 	mutex_unlock(&data->update_lock);
5868d5d45fbSJean Delvare 	return count;
5878d5d45fbSJean Delvare }
5888d5d45fbSJean Delvare 
5897bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(fan1_input, fan, 0);
5907bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(fan1_min, fan_min, 0);
5917bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(fan2_input, fan, 1);
5927bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(fan2_min, fan_min, 1);
5937bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(fan3_input, fan, 2);
5947bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(fan3_min, fan_min, 2);
5957bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(fan4_input, fan, 3);
5967bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(fan4_min, fan_min, 3);
5978d5d45fbSJean Delvare 
5988d5d45fbSJean Delvare /* vid, vrm, alarms */
5998d5d45fbSJean Delvare 
cpu0_vid_show(struct device * dev,struct device_attribute * attr,char * buf)600d0ed69d5SJulia Lawall static ssize_t cpu0_vid_show(struct device *dev,
601d0ed69d5SJulia Lawall 			     struct device_attribute *attr, char *buf)
6028d5d45fbSJean Delvare {
6038d5d45fbSJean Delvare 	struct lm85_data *data = lm85_update_device(dev);
6049c516ef4SJean Delvare 	int vid;
6059c516ef4SJean Delvare 
606de248805SGuenter Roeck 	if (data->has_vid5) {
6079c516ef4SJean Delvare 		/* 6-pin VID (VRM 10) */
6089c516ef4SJean Delvare 		vid = vid_from_reg(data->vid & 0x3f, data->vrm);
6099c516ef4SJean Delvare 	} else {
6109c516ef4SJean Delvare 		/* 5-pin VID (VRM 9) */
6119c516ef4SJean Delvare 		vid = vid_from_reg(data->vid & 0x1f, data->vrm);
6129c516ef4SJean Delvare 	}
6139c516ef4SJean Delvare 
6149c516ef4SJean Delvare 	return sprintf(buf, "%d\n", vid);
6158d5d45fbSJean Delvare }
6168d5d45fbSJean Delvare 
617d0ed69d5SJulia Lawall static DEVICE_ATTR_RO(cpu0_vid);
6188d5d45fbSJean Delvare 
vrm_show(struct device * dev,struct device_attribute * attr,char * buf)619d0ed69d5SJulia Lawall static ssize_t vrm_show(struct device *dev, struct device_attribute *attr,
6201f44809aSJean Delvare 			char *buf)
6218d5d45fbSJean Delvare {
62290d6619aSJean Delvare 	struct lm85_data *data = dev_get_drvdata(dev);
6238d5d45fbSJean Delvare 	return sprintf(buf, "%ld\n", (long) data->vrm);
6248d5d45fbSJean Delvare }
6258d5d45fbSJean Delvare 
vrm_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)626d0ed69d5SJulia Lawall static ssize_t vrm_store(struct device *dev, struct device_attribute *attr,
6271f44809aSJean Delvare 			 const char *buf, size_t count)
6288d5d45fbSJean Delvare {
6298f74efe8SJean Delvare 	struct lm85_data *data = dev_get_drvdata(dev);
63009770b26SGuenter Roeck 	unsigned long val;
63109770b26SGuenter Roeck 	int err;
63209770b26SGuenter Roeck 
63309770b26SGuenter Roeck 	err = kstrtoul(buf, 10, &val);
63409770b26SGuenter Roeck 	if (err)
63509770b26SGuenter Roeck 		return err;
63609770b26SGuenter Roeck 
6373248c3b7SGuenter Roeck 	if (val > 255)
6383248c3b7SGuenter Roeck 		return -EINVAL;
6393248c3b7SGuenter Roeck 
64009770b26SGuenter Roeck 	data->vrm = val;
6418d5d45fbSJean Delvare 	return count;
6428d5d45fbSJean Delvare }
6438d5d45fbSJean Delvare 
644d0ed69d5SJulia Lawall static DEVICE_ATTR_RW(vrm);
6458d5d45fbSJean Delvare 
alarms_show(struct device * dev,struct device_attribute * attr,char * buf)646d0ed69d5SJulia Lawall static ssize_t alarms_show(struct device *dev, struct device_attribute *attr,
647d0ed69d5SJulia Lawall 			   char *buf)
6488d5d45fbSJean Delvare {
6498d5d45fbSJean Delvare 	struct lm85_data *data = lm85_update_device(dev);
6508d5d45fbSJean Delvare 	return sprintf(buf, "%u\n", data->alarms);
6518d5d45fbSJean Delvare }
6528d5d45fbSJean Delvare 
653d0ed69d5SJulia Lawall static DEVICE_ATTR_RO(alarms);
6548d5d45fbSJean Delvare 
alarm_show(struct device * dev,struct device_attribute * attr,char * buf)6557bc85e49SGuenter Roeck static ssize_t alarm_show(struct device *dev, struct device_attribute *attr,
656bf76e9d3SJean Delvare 			  char *buf)
657bf76e9d3SJean Delvare {
658bf76e9d3SJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
659bf76e9d3SJean Delvare 	struct lm85_data *data = lm85_update_device(dev);
660bf76e9d3SJean Delvare 	return sprintf(buf, "%u\n", (data->alarms >> nr) & 1);
661bf76e9d3SJean Delvare }
662bf76e9d3SJean Delvare 
6637bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(in0_alarm, alarm, 0);
6647bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(in1_alarm, alarm, 1);
6657bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(in2_alarm, alarm, 2);
6667bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(in3_alarm, alarm, 3);
6677bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(in4_alarm, alarm, 8);
6687bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(in5_alarm, alarm, 18);
6697bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(in6_alarm, alarm, 16);
6707bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(in7_alarm, alarm, 17);
6717bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(temp1_alarm, alarm, 4);
6727bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(temp1_fault, alarm, 14);
6737bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(temp2_alarm, alarm, 5);
6747bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(temp3_alarm, alarm, 6);
6757bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(temp3_fault, alarm, 15);
6767bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(fan1_alarm, alarm, 10);
6777bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(fan2_alarm, alarm, 11);
6787bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(fan3_alarm, alarm, 12);
6797bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(fan4_alarm, alarm, 13);
680bf76e9d3SJean Delvare 
6818d5d45fbSJean Delvare /* pwm */
6828d5d45fbSJean Delvare 
pwm_show(struct device * dev,struct device_attribute * attr,char * buf)6837bc85e49SGuenter Roeck static ssize_t pwm_show(struct device *dev, struct device_attribute *attr,
684b353a487SJean Delvare 			char *buf)
6858d5d45fbSJean Delvare {
686b353a487SJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
6878d5d45fbSJean Delvare 	struct lm85_data *data = lm85_update_device(dev);
6888d5d45fbSJean Delvare 	return sprintf(buf, "%d\n", PWM_FROM_REG(data->pwm[nr]));
6898d5d45fbSJean Delvare }
690b353a487SJean Delvare 
pwm_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)6917bc85e49SGuenter Roeck static ssize_t pwm_store(struct device *dev, struct device_attribute *attr,
692b353a487SJean Delvare 			 const char *buf, size_t count)
6938d5d45fbSJean Delvare {
694b353a487SJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
695746f6884SAxel Lin 	struct lm85_data *data = dev_get_drvdata(dev);
696746f6884SAxel Lin 	struct i2c_client *client = data->client;
69709770b26SGuenter Roeck 	unsigned long val;
69809770b26SGuenter Roeck 	int err;
69909770b26SGuenter Roeck 
70009770b26SGuenter Roeck 	err = kstrtoul(buf, 10, &val);
70109770b26SGuenter Roeck 	if (err)
70209770b26SGuenter Roeck 		return err;
7038d5d45fbSJean Delvare 
7049a61bf63SIngo Molnar 	mutex_lock(&data->update_lock);
7058d5d45fbSJean Delvare 	data->pwm[nr] = PWM_TO_REG(val);
7068d5d45fbSJean Delvare 	lm85_write_value(client, LM85_REG_PWM(nr), data->pwm[nr]);
7079a61bf63SIngo Molnar 	mutex_unlock(&data->update_lock);
7088d5d45fbSJean Delvare 	return count;
7098d5d45fbSJean Delvare }
710b353a487SJean Delvare 
pwm_enable_show(struct device * dev,struct device_attribute * attr,char * buf)7117bc85e49SGuenter Roeck static ssize_t pwm_enable_show(struct device *dev,
7127bc85e49SGuenter Roeck 			       struct device_attribute *attr, char *buf)
7138d5d45fbSJean Delvare {
714b353a487SJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
7158d5d45fbSJean Delvare 	struct lm85_data *data = lm85_update_device(dev);
7164b4df95dSJean Delvare 	int pwm_zone, enable;
7178d5d45fbSJean Delvare 
7188d5d45fbSJean Delvare 	pwm_zone = ZONE_FROM_REG(data->autofan[nr].config);
7194b4df95dSJean Delvare 	switch (pwm_zone) {
7204b4df95dSJean Delvare 	case -1:	/* PWM is always at 100% */
7214b4df95dSJean Delvare 		enable = 0;
7224b4df95dSJean Delvare 		break;
7234b4df95dSJean Delvare 	case 0:		/* PWM is always at 0% */
7244b4df95dSJean Delvare 	case -2:	/* PWM responds to manual control */
7254b4df95dSJean Delvare 		enable = 1;
7264b4df95dSJean Delvare 		break;
7274b4df95dSJean Delvare 	default:	/* PWM in automatic mode */
7284b4df95dSJean Delvare 		enable = 2;
7294b4df95dSJean Delvare 	}
7304b4df95dSJean Delvare 	return sprintf(buf, "%d\n", enable);
7318d5d45fbSJean Delvare }
7328d5d45fbSJean Delvare 
pwm_enable_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)7337bc85e49SGuenter Roeck static ssize_t pwm_enable_store(struct device *dev,
7347bc85e49SGuenter Roeck 				struct device_attribute *attr,
7357bc85e49SGuenter Roeck 				const char *buf, size_t count)
736455f791eSJean Delvare {
737455f791eSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
738746f6884SAxel Lin 	struct lm85_data *data = dev_get_drvdata(dev);
739746f6884SAxel Lin 	struct i2c_client *client = data->client;
740455f791eSJean Delvare 	u8 config;
74109770b26SGuenter Roeck 	unsigned long val;
74209770b26SGuenter Roeck 	int err;
74309770b26SGuenter Roeck 
74409770b26SGuenter Roeck 	err = kstrtoul(buf, 10, &val);
74509770b26SGuenter Roeck 	if (err)
74609770b26SGuenter Roeck 		return err;
747455f791eSJean Delvare 
748455f791eSJean Delvare 	switch (val) {
749455f791eSJean Delvare 	case 0:
750455f791eSJean Delvare 		config = 3;
751455f791eSJean Delvare 		break;
752455f791eSJean Delvare 	case 1:
753455f791eSJean Delvare 		config = 7;
754455f791eSJean Delvare 		break;
755455f791eSJean Delvare 	case 2:
75609770b26SGuenter Roeck 		/*
75709770b26SGuenter Roeck 		 * Here we have to choose arbitrarily one of the 5 possible
75809770b26SGuenter Roeck 		 * configurations; I go for the safest
75909770b26SGuenter Roeck 		 */
760455f791eSJean Delvare 		config = 6;
761455f791eSJean Delvare 		break;
762455f791eSJean Delvare 	default:
763455f791eSJean Delvare 		return -EINVAL;
764455f791eSJean Delvare 	}
765455f791eSJean Delvare 
766455f791eSJean Delvare 	mutex_lock(&data->update_lock);
767455f791eSJean Delvare 	data->autofan[nr].config = lm85_read_value(client,
768455f791eSJean Delvare 		LM85_REG_AFAN_CONFIG(nr));
769455f791eSJean Delvare 	data->autofan[nr].config = (data->autofan[nr].config & ~0xe0)
770455f791eSJean Delvare 		| (config << 5);
771455f791eSJean Delvare 	lm85_write_value(client, LM85_REG_AFAN_CONFIG(nr),
772455f791eSJean Delvare 		data->autofan[nr].config);
773455f791eSJean Delvare 	mutex_unlock(&data->update_lock);
774455f791eSJean Delvare 	return count;
775455f791eSJean Delvare }
776455f791eSJean Delvare 
pwm_freq_show(struct device * dev,struct device_attribute * attr,char * buf)7777bc85e49SGuenter Roeck static ssize_t pwm_freq_show(struct device *dev,
77834e7dc6cSJean Delvare 			     struct device_attribute *attr, char *buf)
77934e7dc6cSJean Delvare {
78034e7dc6cSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
78134e7dc6cSJean Delvare 	struct lm85_data *data = lm85_update_device(dev);
782f6c61cffSJean Delvare 	int freq;
783f6c61cffSJean Delvare 
784f6c61cffSJean Delvare 	if (IS_ADT7468_HFPWM(data))
785f6c61cffSJean Delvare 		freq = 22500;
786f6c61cffSJean Delvare 	else
78757bc3019SJeremy Gebben 		freq = FREQ_FROM_REG(data->freq_map, data->freq_map_size,
78857bc3019SJeremy Gebben 				     data->pwm_freq[nr]);
789f6c61cffSJean Delvare 
790f6c61cffSJean Delvare 	return sprintf(buf, "%d\n", freq);
79134e7dc6cSJean Delvare }
79234e7dc6cSJean Delvare 
pwm_freq_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)7937bc85e49SGuenter Roeck static ssize_t pwm_freq_store(struct device *dev,
7947bc85e49SGuenter Roeck 			      struct device_attribute *attr, const char *buf,
7957bc85e49SGuenter Roeck 			      size_t count)
79634e7dc6cSJean Delvare {
79734e7dc6cSJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
798746f6884SAxel Lin 	struct lm85_data *data = dev_get_drvdata(dev);
799746f6884SAxel Lin 	struct i2c_client *client = data->client;
80009770b26SGuenter Roeck 	unsigned long val;
80109770b26SGuenter Roeck 	int err;
80209770b26SGuenter Roeck 
80309770b26SGuenter Roeck 	err = kstrtoul(buf, 10, &val);
80409770b26SGuenter Roeck 	if (err)
80509770b26SGuenter Roeck 		return err;
80634e7dc6cSJean Delvare 
80734e7dc6cSJean Delvare 	mutex_lock(&data->update_lock);
80809770b26SGuenter Roeck 	/*
80909770b26SGuenter Roeck 	 * The ADT7468 has a special high-frequency PWM output mode,
810f6c61cffSJean Delvare 	 * where all PWM outputs are driven by a 22.5 kHz clock.
81109770b26SGuenter Roeck 	 * This might confuse the user, but there's not much we can do.
81209770b26SGuenter Roeck 	 */
813f6c61cffSJean Delvare 	if (data->type == adt7468 && val >= 11300) {	/* High freq. mode */
814f6c61cffSJean Delvare 		data->cfg5 &= ~ADT7468_HFPWM;
815f6c61cffSJean Delvare 		lm85_write_value(client, ADT7468_REG_CFG5, data->cfg5);
816f6c61cffSJean Delvare 	} else {					/* Low freq. mode */
8170f3721c5SBartosz Golaszewski 		data->pwm_freq[nr] = FREQ_TO_REG(data->freq_map,
81857bc3019SJeremy Gebben 						 data->freq_map_size, val);
81934e7dc6cSJean Delvare 		lm85_write_value(client, LM85_REG_AFAN_RANGE(nr),
82034e7dc6cSJean Delvare 				 (data->zone[nr].range << 4)
82134e7dc6cSJean Delvare 				 | data->pwm_freq[nr]);
822f6c61cffSJean Delvare 		if (data->type == adt7468) {
823f6c61cffSJean Delvare 			data->cfg5 |= ADT7468_HFPWM;
824f6c61cffSJean Delvare 			lm85_write_value(client, ADT7468_REG_CFG5, data->cfg5);
825f6c61cffSJean Delvare 		}
826f6c61cffSJean Delvare 	}
82734e7dc6cSJean Delvare 	mutex_unlock(&data->update_lock);
82834e7dc6cSJean Delvare 	return count;
82934e7dc6cSJean Delvare }
83034e7dc6cSJean Delvare 
8317bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(pwm1, pwm, 0);
8327bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(pwm1_enable, pwm_enable, 0);
8337bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(pwm1_freq, pwm_freq, 0);
8347bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(pwm2, pwm, 1);
8357bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(pwm2_enable, pwm_enable, 1);
8367bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(pwm2_freq, pwm_freq, 1);
8377bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(pwm3, pwm, 2);
8387bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(pwm3_enable, pwm_enable, 2);
8397bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(pwm3_freq, pwm_freq, 2);
8408d5d45fbSJean Delvare 
8418d5d45fbSJean Delvare /* Voltages */
8428d5d45fbSJean Delvare 
in_show(struct device * dev,struct device_attribute * attr,char * buf)8437bc85e49SGuenter Roeck static ssize_t in_show(struct device *dev, struct device_attribute *attr,
844b353a487SJean Delvare 		       char *buf)
8458d5d45fbSJean Delvare {
846b353a487SJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
8478d5d45fbSJean Delvare 	struct lm85_data *data = lm85_update_device(dev);
8481f44809aSJean Delvare 	return sprintf(buf, "%d\n", INSEXT_FROM_REG(nr, data->in[nr],
8495a4d3ef3SJean Delvare 						    data->in_ext[nr]));
8508d5d45fbSJean Delvare }
851b353a487SJean Delvare 
in_min_show(struct device * dev,struct device_attribute * attr,char * buf)8527bc85e49SGuenter Roeck static ssize_t in_min_show(struct device *dev, struct device_attribute *attr,
853b353a487SJean Delvare 			   char *buf)
8548d5d45fbSJean Delvare {
855b353a487SJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
8568d5d45fbSJean Delvare 	struct lm85_data *data = lm85_update_device(dev);
8578d5d45fbSJean Delvare 	return sprintf(buf, "%d\n", INS_FROM_REG(nr, data->in_min[nr]));
8588d5d45fbSJean Delvare }
859b353a487SJean Delvare 
in_min_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)8607bc85e49SGuenter Roeck static ssize_t in_min_store(struct device *dev, struct device_attribute *attr,
861b353a487SJean Delvare 			    const char *buf, size_t count)
8628d5d45fbSJean Delvare {
863b353a487SJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
864746f6884SAxel Lin 	struct lm85_data *data = dev_get_drvdata(dev);
865746f6884SAxel Lin 	struct i2c_client *client = data->client;
86609770b26SGuenter Roeck 	long val;
86709770b26SGuenter Roeck 	int err;
86809770b26SGuenter Roeck 
86909770b26SGuenter Roeck 	err = kstrtol(buf, 10, &val);
87009770b26SGuenter Roeck 	if (err)
87109770b26SGuenter Roeck 		return err;
8728d5d45fbSJean Delvare 
8739a61bf63SIngo Molnar 	mutex_lock(&data->update_lock);
8748d5d45fbSJean Delvare 	data->in_min[nr] = INS_TO_REG(nr, val);
8758d5d45fbSJean Delvare 	lm85_write_value(client, LM85_REG_IN_MIN(nr), data->in_min[nr]);
8769a61bf63SIngo Molnar 	mutex_unlock(&data->update_lock);
8778d5d45fbSJean Delvare 	return count;
8788d5d45fbSJean Delvare }
879b353a487SJean Delvare 
in_max_show(struct device * dev,struct device_attribute * attr,char * buf)8807bc85e49SGuenter Roeck static ssize_t in_max_show(struct device *dev, struct device_attribute *attr,
881b353a487SJean Delvare 			   char *buf)
8828d5d45fbSJean Delvare {
883b353a487SJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
8848d5d45fbSJean Delvare 	struct lm85_data *data = lm85_update_device(dev);
8858d5d45fbSJean Delvare 	return sprintf(buf, "%d\n", INS_FROM_REG(nr, data->in_max[nr]));
8868d5d45fbSJean Delvare }
887b353a487SJean Delvare 
in_max_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)8887bc85e49SGuenter Roeck static ssize_t in_max_store(struct device *dev, struct device_attribute *attr,
889b353a487SJean Delvare 			    const char *buf, size_t count)
8908d5d45fbSJean Delvare {
891b353a487SJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
892746f6884SAxel Lin 	struct lm85_data *data = dev_get_drvdata(dev);
893746f6884SAxel Lin 	struct i2c_client *client = data->client;
89409770b26SGuenter Roeck 	long val;
89509770b26SGuenter Roeck 	int err;
89609770b26SGuenter Roeck 
89709770b26SGuenter Roeck 	err = kstrtol(buf, 10, &val);
89809770b26SGuenter Roeck 	if (err)
89909770b26SGuenter Roeck 		return err;
9008d5d45fbSJean Delvare 
9019a61bf63SIngo Molnar 	mutex_lock(&data->update_lock);
9028d5d45fbSJean Delvare 	data->in_max[nr] = INS_TO_REG(nr, val);
9038d5d45fbSJean Delvare 	lm85_write_value(client, LM85_REG_IN_MAX(nr), data->in_max[nr]);
9049a61bf63SIngo Molnar 	mutex_unlock(&data->update_lock);
9058d5d45fbSJean Delvare 	return count;
9068d5d45fbSJean Delvare }
907b353a487SJean Delvare 
9087bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(in0_input, in, 0);
9097bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(in0_min, in_min, 0);
9107bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(in0_max, in_max, 0);
9117bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(in1_input, in, 1);
9127bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(in1_min, in_min, 1);
9137bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(in1_max, in_max, 1);
9147bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(in2_input, in, 2);
9157bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(in2_min, in_min, 2);
9167bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(in2_max, in_max, 2);
9177bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(in3_input, in, 3);
9187bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(in3_min, in_min, 3);
9197bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(in3_max, in_max, 3);
9207bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(in4_input, in, 4);
9217bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(in4_min, in_min, 4);
9227bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(in4_max, in_max, 4);
9237bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(in5_input, in, 5);
9247bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(in5_min, in_min, 5);
9257bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(in5_max, in_max, 5);
9267bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(in6_input, in, 6);
9277bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(in6_min, in_min, 6);
9287bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(in6_max, in_max, 6);
9297bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(in7_input, in, 7);
9307bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(in7_min, in_min, 7);
9317bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(in7_max, in_max, 7);
9328d5d45fbSJean Delvare 
9338d5d45fbSJean Delvare /* Temps */
9348d5d45fbSJean Delvare 
temp_show(struct device * dev,struct device_attribute * attr,char * buf)9357bc85e49SGuenter Roeck static ssize_t temp_show(struct device *dev, struct device_attribute *attr,
936b353a487SJean Delvare 			 char *buf)
9378d5d45fbSJean Delvare {
938b353a487SJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
9398d5d45fbSJean Delvare 	struct lm85_data *data = lm85_update_device(dev);
9408d5d45fbSJean Delvare 	return sprintf(buf, "%d\n", TEMPEXT_FROM_REG(data->temp[nr],
9415a4d3ef3SJean Delvare 						     data->temp_ext[nr]));
9428d5d45fbSJean Delvare }
943b353a487SJean Delvare 
temp_min_show(struct device * dev,struct device_attribute * attr,char * buf)9447bc85e49SGuenter Roeck static ssize_t temp_min_show(struct device *dev,
9457bc85e49SGuenter Roeck 			     struct device_attribute *attr, char *buf)
9468d5d45fbSJean Delvare {
947b353a487SJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
9488d5d45fbSJean Delvare 	struct lm85_data *data = lm85_update_device(dev);
9498d5d45fbSJean Delvare 	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_min[nr]));
9508d5d45fbSJean Delvare }
951b353a487SJean Delvare 
temp_min_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)9527bc85e49SGuenter Roeck static ssize_t temp_min_store(struct device *dev,
9537bc85e49SGuenter Roeck 			      struct device_attribute *attr, const char *buf,
9547bc85e49SGuenter Roeck 			      size_t count)
9558d5d45fbSJean Delvare {
956b353a487SJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
957746f6884SAxel Lin 	struct lm85_data *data = dev_get_drvdata(dev);
958746f6884SAxel Lin 	struct i2c_client *client = data->client;
95909770b26SGuenter Roeck 	long val;
96009770b26SGuenter Roeck 	int err;
96109770b26SGuenter Roeck 
96209770b26SGuenter Roeck 	err = kstrtol(buf, 10, &val);
96309770b26SGuenter Roeck 	if (err)
96409770b26SGuenter Roeck 		return err;
9658d5d45fbSJean Delvare 
96679b92f2bSDarrick J. Wong 	if (IS_ADT7468_OFF64(data))
96779b92f2bSDarrick J. Wong 		val += 64;
96879b92f2bSDarrick J. Wong 
9699a61bf63SIngo Molnar 	mutex_lock(&data->update_lock);
9708d5d45fbSJean Delvare 	data->temp_min[nr] = TEMP_TO_REG(val);
9718d5d45fbSJean Delvare 	lm85_write_value(client, LM85_REG_TEMP_MIN(nr), data->temp_min[nr]);
9729a61bf63SIngo Molnar 	mutex_unlock(&data->update_lock);
9738d5d45fbSJean Delvare 	return count;
9748d5d45fbSJean Delvare }
975b353a487SJean Delvare 
temp_max_show(struct device * dev,struct device_attribute * attr,char * buf)9767bc85e49SGuenter Roeck static ssize_t temp_max_show(struct device *dev,
9777bc85e49SGuenter Roeck 			     struct device_attribute *attr, char *buf)
9788d5d45fbSJean Delvare {
979b353a487SJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
9808d5d45fbSJean Delvare 	struct lm85_data *data = lm85_update_device(dev);
9818d5d45fbSJean Delvare 	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_max[nr]));
9828d5d45fbSJean Delvare }
983b353a487SJean Delvare 
temp_max_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)9847bc85e49SGuenter Roeck static ssize_t temp_max_store(struct device *dev,
9857bc85e49SGuenter Roeck 			      struct device_attribute *attr, const char *buf,
9867bc85e49SGuenter Roeck 			      size_t count)
9878d5d45fbSJean Delvare {
988b353a487SJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
989746f6884SAxel Lin 	struct lm85_data *data = dev_get_drvdata(dev);
990746f6884SAxel Lin 	struct i2c_client *client = data->client;
99109770b26SGuenter Roeck 	long val;
99209770b26SGuenter Roeck 	int err;
99309770b26SGuenter Roeck 
99409770b26SGuenter Roeck 	err = kstrtol(buf, 10, &val);
99509770b26SGuenter Roeck 	if (err)
99609770b26SGuenter Roeck 		return err;
9978d5d45fbSJean Delvare 
99879b92f2bSDarrick J. Wong 	if (IS_ADT7468_OFF64(data))
99979b92f2bSDarrick J. Wong 		val += 64;
100079b92f2bSDarrick J. Wong 
10019a61bf63SIngo Molnar 	mutex_lock(&data->update_lock);
10028d5d45fbSJean Delvare 	data->temp_max[nr] = TEMP_TO_REG(val);
10038d5d45fbSJean Delvare 	lm85_write_value(client, LM85_REG_TEMP_MAX(nr), data->temp_max[nr]);
10049a61bf63SIngo Molnar 	mutex_unlock(&data->update_lock);
10058d5d45fbSJean Delvare 	return count;
10068d5d45fbSJean Delvare }
1007b353a487SJean Delvare 
10087bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(temp1_input, temp, 0);
10097bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(temp1_min, temp_min, 0);
10107bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(temp1_max, temp_max, 0);
10117bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(temp2_input, temp, 1);
10127bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(temp2_min, temp_min, 1);
10137bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(temp2_max, temp_max, 1);
10147bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RO(temp3_input, temp, 2);
10157bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(temp3_min, temp_min, 2);
10167bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(temp3_max, temp_max, 2);
10178d5d45fbSJean Delvare 
10188d5d45fbSJean Delvare /* Automatic PWM control */
10198d5d45fbSJean Delvare 
pwm_auto_channels_show(struct device * dev,struct device_attribute * attr,char * buf)10207bc85e49SGuenter Roeck static ssize_t pwm_auto_channels_show(struct device *dev,
10217bc85e49SGuenter Roeck 				      struct device_attribute *attr,
10227bc85e49SGuenter Roeck 				      char *buf)
10238d5d45fbSJean Delvare {
1024b353a487SJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
10258d5d45fbSJean Delvare 	struct lm85_data *data = lm85_update_device(dev);
10268d5d45fbSJean Delvare 	return sprintf(buf, "%d\n", ZONE_FROM_REG(data->autofan[nr].config));
10278d5d45fbSJean Delvare }
1028b353a487SJean Delvare 
pwm_auto_channels_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)10297bc85e49SGuenter Roeck static ssize_t pwm_auto_channels_store(struct device *dev,
10307bc85e49SGuenter Roeck 				       struct device_attribute *attr,
10317bc85e49SGuenter Roeck 				       const char *buf, size_t count)
10328d5d45fbSJean Delvare {
1033b353a487SJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
1034746f6884SAxel Lin 	struct lm85_data *data = dev_get_drvdata(dev);
1035746f6884SAxel Lin 	struct i2c_client *client = data->client;
103609770b26SGuenter Roeck 	long val;
103709770b26SGuenter Roeck 	int err;
103809770b26SGuenter Roeck 
103909770b26SGuenter Roeck 	err = kstrtol(buf, 10, &val);
104009770b26SGuenter Roeck 	if (err)
104109770b26SGuenter Roeck 		return err;
10428d5d45fbSJean Delvare 
10439a61bf63SIngo Molnar 	mutex_lock(&data->update_lock);
10448d5d45fbSJean Delvare 	data->autofan[nr].config = (data->autofan[nr].config & (~0xe0))
10458d5d45fbSJean Delvare 		| ZONE_TO_REG(val);
10468d5d45fbSJean Delvare 	lm85_write_value(client, LM85_REG_AFAN_CONFIG(nr),
10478d5d45fbSJean Delvare 		data->autofan[nr].config);
10489a61bf63SIngo Molnar 	mutex_unlock(&data->update_lock);
10498d5d45fbSJean Delvare 	return count;
10508d5d45fbSJean Delvare }
1051b353a487SJean Delvare 
pwm_auto_pwm_min_show(struct device * dev,struct device_attribute * attr,char * buf)10527bc85e49SGuenter Roeck static ssize_t pwm_auto_pwm_min_show(struct device *dev,
1053b353a487SJean Delvare 				     struct device_attribute *attr, char *buf)
10548d5d45fbSJean Delvare {
1055b353a487SJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
10568d5d45fbSJean Delvare 	struct lm85_data *data = lm85_update_device(dev);
10578d5d45fbSJean Delvare 	return sprintf(buf, "%d\n", PWM_FROM_REG(data->autofan[nr].min_pwm));
10588d5d45fbSJean Delvare }
1059b353a487SJean Delvare 
pwm_auto_pwm_min_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)10607bc85e49SGuenter Roeck static ssize_t pwm_auto_pwm_min_store(struct device *dev,
10617bc85e49SGuenter Roeck 				      struct device_attribute *attr,
10627bc85e49SGuenter Roeck 				      const char *buf, size_t count)
10638d5d45fbSJean Delvare {
1064b353a487SJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
1065746f6884SAxel Lin 	struct lm85_data *data = dev_get_drvdata(dev);
1066746f6884SAxel Lin 	struct i2c_client *client = data->client;
106709770b26SGuenter Roeck 	unsigned long val;
106809770b26SGuenter Roeck 	int err;
106909770b26SGuenter Roeck 
107009770b26SGuenter Roeck 	err = kstrtoul(buf, 10, &val);
107109770b26SGuenter Roeck 	if (err)
107209770b26SGuenter Roeck 		return err;
10738d5d45fbSJean Delvare 
10749a61bf63SIngo Molnar 	mutex_lock(&data->update_lock);
10758d5d45fbSJean Delvare 	data->autofan[nr].min_pwm = PWM_TO_REG(val);
10768d5d45fbSJean Delvare 	lm85_write_value(client, LM85_REG_AFAN_MINPWM(nr),
10778d5d45fbSJean Delvare 		data->autofan[nr].min_pwm);
10789a61bf63SIngo Molnar 	mutex_unlock(&data->update_lock);
10798d5d45fbSJean Delvare 	return count;
10808d5d45fbSJean Delvare }
1081b353a487SJean Delvare 
pwm_auto_pwm_minctl_show(struct device * dev,struct device_attribute * attr,char * buf)10827bc85e49SGuenter Roeck static ssize_t pwm_auto_pwm_minctl_show(struct device *dev,
10837bc85e49SGuenter Roeck 					struct device_attribute *attr,
10847bc85e49SGuenter Roeck 					char *buf)
10858d5d45fbSJean Delvare {
1086b353a487SJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
10878d5d45fbSJean Delvare 	struct lm85_data *data = lm85_update_device(dev);
10888d5d45fbSJean Delvare 	return sprintf(buf, "%d\n", data->autofan[nr].min_off);
10898d5d45fbSJean Delvare }
1090b353a487SJean Delvare 
pwm_auto_pwm_minctl_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)10917bc85e49SGuenter Roeck static ssize_t pwm_auto_pwm_minctl_store(struct device *dev,
10927bc85e49SGuenter Roeck 					 struct device_attribute *attr,
10937bc85e49SGuenter Roeck 					 const char *buf, size_t count)
10948d5d45fbSJean Delvare {
1095b353a487SJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
1096746f6884SAxel Lin 	struct lm85_data *data = dev_get_drvdata(dev);
1097746f6884SAxel Lin 	struct i2c_client *client = data->client;
10987133e56fSJean Delvare 	u8 tmp;
109909770b26SGuenter Roeck 	long val;
110009770b26SGuenter Roeck 	int err;
110109770b26SGuenter Roeck 
110209770b26SGuenter Roeck 	err = kstrtol(buf, 10, &val);
110309770b26SGuenter Roeck 	if (err)
110409770b26SGuenter Roeck 		return err;
11058d5d45fbSJean Delvare 
11069a61bf63SIngo Molnar 	mutex_lock(&data->update_lock);
11078d5d45fbSJean Delvare 	data->autofan[nr].min_off = val;
11087133e56fSJean Delvare 	tmp = lm85_read_value(client, LM85_REG_AFAN_SPIKE1);
11097133e56fSJean Delvare 	tmp &= ~(0x20 << nr);
11107133e56fSJean Delvare 	if (data->autofan[nr].min_off)
11117133e56fSJean Delvare 		tmp |= 0x20 << nr;
11127133e56fSJean Delvare 	lm85_write_value(client, LM85_REG_AFAN_SPIKE1, tmp);
11139a61bf63SIngo Molnar 	mutex_unlock(&data->update_lock);
11148d5d45fbSJean Delvare 	return count;
11158d5d45fbSJean Delvare }
1116b353a487SJean Delvare 
11177bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(pwm1_auto_channels, pwm_auto_channels, 0);
11187bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(pwm1_auto_pwm_min, pwm_auto_pwm_min, 0);
11197bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(pwm1_auto_pwm_minctl, pwm_auto_pwm_minctl, 0);
11207bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(pwm2_auto_channels, pwm_auto_channels, 1);
11217bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(pwm2_auto_pwm_min, pwm_auto_pwm_min, 1);
11227bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(pwm2_auto_pwm_minctl, pwm_auto_pwm_minctl, 1);
11237bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(pwm3_auto_channels, pwm_auto_channels, 2);
11247bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(pwm3_auto_pwm_min, pwm_auto_pwm_min, 2);
11257bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(pwm3_auto_pwm_minctl, pwm_auto_pwm_minctl, 2);
11268d5d45fbSJean Delvare 
11278d5d45fbSJean Delvare /* Temperature settings for automatic PWM control */
11288d5d45fbSJean Delvare 
temp_auto_temp_off_show(struct device * dev,struct device_attribute * attr,char * buf)11297bc85e49SGuenter Roeck static ssize_t temp_auto_temp_off_show(struct device *dev,
11307bc85e49SGuenter Roeck 				       struct device_attribute *attr,
11317bc85e49SGuenter Roeck 				       char *buf)
11328d5d45fbSJean Delvare {
1133b353a487SJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
11348d5d45fbSJean Delvare 	struct lm85_data *data = lm85_update_device(dev);
11358d5d45fbSJean Delvare 	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->zone[nr].limit) -
11368d5d45fbSJean Delvare 		HYST_FROM_REG(data->zone[nr].hyst));
11378d5d45fbSJean Delvare }
1138b353a487SJean Delvare 
temp_auto_temp_off_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)11397bc85e49SGuenter Roeck static ssize_t temp_auto_temp_off_store(struct device *dev,
11407bc85e49SGuenter Roeck 					struct device_attribute *attr,
11417bc85e49SGuenter Roeck 					const char *buf, size_t count)
11428d5d45fbSJean Delvare {
1143b353a487SJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
1144746f6884SAxel Lin 	struct lm85_data *data = dev_get_drvdata(dev);
1145746f6884SAxel Lin 	struct i2c_client *client = data->client;
11468d5d45fbSJean Delvare 	int min;
114709770b26SGuenter Roeck 	long val;
114809770b26SGuenter Roeck 	int err;
114909770b26SGuenter Roeck 
115009770b26SGuenter Roeck 	err = kstrtol(buf, 10, &val);
115109770b26SGuenter Roeck 	if (err)
115209770b26SGuenter Roeck 		return err;
11538d5d45fbSJean Delvare 
11549a61bf63SIngo Molnar 	mutex_lock(&data->update_lock);
11558d5d45fbSJean Delvare 	min = TEMP_FROM_REG(data->zone[nr].limit);
11568d5d45fbSJean Delvare 	data->zone[nr].hyst = HYST_TO_REG(min - val);
11578d5d45fbSJean Delvare 	if (nr == 0 || nr == 1) {
11588d5d45fbSJean Delvare 		lm85_write_value(client, LM85_REG_AFAN_HYST1,
11598d5d45fbSJean Delvare 			(data->zone[0].hyst << 4)
11601f44809aSJean Delvare 			| data->zone[1].hyst);
11618d5d45fbSJean Delvare 	} else {
11628d5d45fbSJean Delvare 		lm85_write_value(client, LM85_REG_AFAN_HYST2,
11631f44809aSJean Delvare 			(data->zone[2].hyst << 4));
11648d5d45fbSJean Delvare 	}
11659a61bf63SIngo Molnar 	mutex_unlock(&data->update_lock);
11668d5d45fbSJean Delvare 	return count;
11678d5d45fbSJean Delvare }
1168b353a487SJean Delvare 
temp_auto_temp_min_show(struct device * dev,struct device_attribute * attr,char * buf)11697bc85e49SGuenter Roeck static ssize_t temp_auto_temp_min_show(struct device *dev,
11707bc85e49SGuenter Roeck 				       struct device_attribute *attr,
11717bc85e49SGuenter Roeck 				       char *buf)
11728d5d45fbSJean Delvare {
1173b353a487SJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
11748d5d45fbSJean Delvare 	struct lm85_data *data = lm85_update_device(dev);
11758d5d45fbSJean Delvare 	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->zone[nr].limit));
11768d5d45fbSJean Delvare }
1177b353a487SJean Delvare 
temp_auto_temp_min_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)11787bc85e49SGuenter Roeck static ssize_t temp_auto_temp_min_store(struct device *dev,
11797bc85e49SGuenter Roeck 					struct device_attribute *attr,
11807bc85e49SGuenter Roeck 					const char *buf, size_t count)
11818d5d45fbSJean Delvare {
1182b353a487SJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
1183746f6884SAxel Lin 	struct lm85_data *data = dev_get_drvdata(dev);
1184746f6884SAxel Lin 	struct i2c_client *client = data->client;
118509770b26SGuenter Roeck 	long val;
118609770b26SGuenter Roeck 	int err;
118709770b26SGuenter Roeck 
118809770b26SGuenter Roeck 	err = kstrtol(buf, 10, &val);
118909770b26SGuenter Roeck 	if (err)
119009770b26SGuenter Roeck 		return err;
11918d5d45fbSJean Delvare 
11929a61bf63SIngo Molnar 	mutex_lock(&data->update_lock);
11938d5d45fbSJean Delvare 	data->zone[nr].limit = TEMP_TO_REG(val);
11948d5d45fbSJean Delvare 	lm85_write_value(client, LM85_REG_AFAN_LIMIT(nr),
11958d5d45fbSJean Delvare 		data->zone[nr].limit);
11968d5d45fbSJean Delvare 
11978d5d45fbSJean Delvare /* Update temp_auto_max and temp_auto_range */
11988d5d45fbSJean Delvare 	data->zone[nr].range = RANGE_TO_REG(
11998d5d45fbSJean Delvare 		TEMP_FROM_REG(data->zone[nr].max_desired) -
12008d5d45fbSJean Delvare 		TEMP_FROM_REG(data->zone[nr].limit));
12018d5d45fbSJean Delvare 	lm85_write_value(client, LM85_REG_AFAN_RANGE(nr),
12028d5d45fbSJean Delvare 		((data->zone[nr].range & 0x0f) << 4)
120357bc3019SJeremy Gebben 		| data->pwm_freq[nr]);
12048d5d45fbSJean Delvare 
12059a61bf63SIngo Molnar 	mutex_unlock(&data->update_lock);
12068d5d45fbSJean Delvare 	return count;
12078d5d45fbSJean Delvare }
1208b353a487SJean Delvare 
temp_auto_temp_max_show(struct device * dev,struct device_attribute * attr,char * buf)12097bc85e49SGuenter Roeck static ssize_t temp_auto_temp_max_show(struct device *dev,
12107bc85e49SGuenter Roeck 				       struct device_attribute *attr,
12117bc85e49SGuenter Roeck 				       char *buf)
12128d5d45fbSJean Delvare {
1213b353a487SJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
12148d5d45fbSJean Delvare 	struct lm85_data *data = lm85_update_device(dev);
12158d5d45fbSJean Delvare 	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->zone[nr].limit) +
12168d5d45fbSJean Delvare 		RANGE_FROM_REG(data->zone[nr].range));
12178d5d45fbSJean Delvare }
1218b353a487SJean Delvare 
temp_auto_temp_max_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)12197bc85e49SGuenter Roeck static ssize_t temp_auto_temp_max_store(struct device *dev,
12207bc85e49SGuenter Roeck 					struct device_attribute *attr,
12217bc85e49SGuenter Roeck 					const char *buf, size_t count)
12228d5d45fbSJean Delvare {
1223b353a487SJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
1224746f6884SAxel Lin 	struct lm85_data *data = dev_get_drvdata(dev);
1225746f6884SAxel Lin 	struct i2c_client *client = data->client;
12268d5d45fbSJean Delvare 	int min;
122709770b26SGuenter Roeck 	long val;
122809770b26SGuenter Roeck 	int err;
122909770b26SGuenter Roeck 
123009770b26SGuenter Roeck 	err = kstrtol(buf, 10, &val);
123109770b26SGuenter Roeck 	if (err)
123209770b26SGuenter Roeck 		return err;
12338d5d45fbSJean Delvare 
12349a61bf63SIngo Molnar 	mutex_lock(&data->update_lock);
12358d5d45fbSJean Delvare 	min = TEMP_FROM_REG(data->zone[nr].limit);
12368d5d45fbSJean Delvare 	data->zone[nr].max_desired = TEMP_TO_REG(val);
12378d5d45fbSJean Delvare 	data->zone[nr].range = RANGE_TO_REG(
12388d5d45fbSJean Delvare 		val - min);
12398d5d45fbSJean Delvare 	lm85_write_value(client, LM85_REG_AFAN_RANGE(nr),
12408d5d45fbSJean Delvare 		((data->zone[nr].range & 0x0f) << 4)
124157bc3019SJeremy Gebben 		| data->pwm_freq[nr]);
12429a61bf63SIngo Molnar 	mutex_unlock(&data->update_lock);
12438d5d45fbSJean Delvare 	return count;
12448d5d45fbSJean Delvare }
1245b353a487SJean Delvare 
temp_auto_temp_crit_show(struct device * dev,struct device_attribute * attr,char * buf)12467bc85e49SGuenter Roeck static ssize_t temp_auto_temp_crit_show(struct device *dev,
12477bc85e49SGuenter Roeck 					struct device_attribute *attr,
12487bc85e49SGuenter Roeck 					char *buf)
12498d5d45fbSJean Delvare {
1250b353a487SJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
12518d5d45fbSJean Delvare 	struct lm85_data *data = lm85_update_device(dev);
12528d5d45fbSJean Delvare 	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->zone[nr].critical));
12538d5d45fbSJean Delvare }
1254b353a487SJean Delvare 
temp_auto_temp_crit_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)12557bc85e49SGuenter Roeck static ssize_t temp_auto_temp_crit_store(struct device *dev,
12567bc85e49SGuenter Roeck 					 struct device_attribute *attr,
12577bc85e49SGuenter Roeck 					 const char *buf, size_t count)
12588d5d45fbSJean Delvare {
1259b353a487SJean Delvare 	int nr = to_sensor_dev_attr(attr)->index;
1260746f6884SAxel Lin 	struct lm85_data *data = dev_get_drvdata(dev);
1261746f6884SAxel Lin 	struct i2c_client *client = data->client;
126209770b26SGuenter Roeck 	long val;
126309770b26SGuenter Roeck 	int err;
126409770b26SGuenter Roeck 
126509770b26SGuenter Roeck 	err = kstrtol(buf, 10, &val);
126609770b26SGuenter Roeck 	if (err)
126709770b26SGuenter Roeck 		return err;
12688d5d45fbSJean Delvare 
12699a61bf63SIngo Molnar 	mutex_lock(&data->update_lock);
12708d5d45fbSJean Delvare 	data->zone[nr].critical = TEMP_TO_REG(val);
12718d5d45fbSJean Delvare 	lm85_write_value(client, LM85_REG_AFAN_CRITICAL(nr),
12728d5d45fbSJean Delvare 		data->zone[nr].critical);
12739a61bf63SIngo Molnar 	mutex_unlock(&data->update_lock);
12748d5d45fbSJean Delvare 	return count;
12758d5d45fbSJean Delvare }
1276b353a487SJean Delvare 
12777bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(temp1_auto_temp_off, temp_auto_temp_off, 0);
12787bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(temp1_auto_temp_min, temp_auto_temp_min, 0);
12797bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(temp1_auto_temp_max, temp_auto_temp_max, 0);
12807bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(temp1_auto_temp_crit, temp_auto_temp_crit, 0);
12817bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(temp2_auto_temp_off, temp_auto_temp_off, 1);
12827bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(temp2_auto_temp_min, temp_auto_temp_min, 1);
12837bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(temp2_auto_temp_max, temp_auto_temp_max, 1);
12847bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(temp2_auto_temp_crit, temp_auto_temp_crit, 1);
12857bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(temp3_auto_temp_off, temp_auto_temp_off, 2);
12867bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(temp3_auto_temp_min, temp_auto_temp_min, 2);
12877bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(temp3_auto_temp_max, temp_auto_temp_max, 2);
12887bc85e49SGuenter Roeck static SENSOR_DEVICE_ATTR_RW(temp3_auto_temp_crit, temp_auto_temp_crit, 2);
12898d5d45fbSJean Delvare 
12900501a381SMark M. Hoffman static struct attribute *lm85_attributes[] = {
1291b353a487SJean Delvare 	&sensor_dev_attr_fan1_input.dev_attr.attr,
1292b353a487SJean Delvare 	&sensor_dev_attr_fan2_input.dev_attr.attr,
1293b353a487SJean Delvare 	&sensor_dev_attr_fan3_input.dev_attr.attr,
1294b353a487SJean Delvare 	&sensor_dev_attr_fan4_input.dev_attr.attr,
1295b353a487SJean Delvare 	&sensor_dev_attr_fan1_min.dev_attr.attr,
1296b353a487SJean Delvare 	&sensor_dev_attr_fan2_min.dev_attr.attr,
1297b353a487SJean Delvare 	&sensor_dev_attr_fan3_min.dev_attr.attr,
1298b353a487SJean Delvare 	&sensor_dev_attr_fan4_min.dev_attr.attr,
1299bf76e9d3SJean Delvare 	&sensor_dev_attr_fan1_alarm.dev_attr.attr,
1300bf76e9d3SJean Delvare 	&sensor_dev_attr_fan2_alarm.dev_attr.attr,
1301bf76e9d3SJean Delvare 	&sensor_dev_attr_fan3_alarm.dev_attr.attr,
1302bf76e9d3SJean Delvare 	&sensor_dev_attr_fan4_alarm.dev_attr.attr,
1303b353a487SJean Delvare 
1304b353a487SJean Delvare 	&sensor_dev_attr_pwm1.dev_attr.attr,
1305b353a487SJean Delvare 	&sensor_dev_attr_pwm2.dev_attr.attr,
1306b353a487SJean Delvare 	&sensor_dev_attr_pwm3.dev_attr.attr,
1307b353a487SJean Delvare 	&sensor_dev_attr_pwm1_enable.dev_attr.attr,
1308b353a487SJean Delvare 	&sensor_dev_attr_pwm2_enable.dev_attr.attr,
1309b353a487SJean Delvare 	&sensor_dev_attr_pwm3_enable.dev_attr.attr,
131034e7dc6cSJean Delvare 	&sensor_dev_attr_pwm1_freq.dev_attr.attr,
131134e7dc6cSJean Delvare 	&sensor_dev_attr_pwm2_freq.dev_attr.attr,
131234e7dc6cSJean Delvare 	&sensor_dev_attr_pwm3_freq.dev_attr.attr,
1313b353a487SJean Delvare 
1314b353a487SJean Delvare 	&sensor_dev_attr_in0_input.dev_attr.attr,
1315b353a487SJean Delvare 	&sensor_dev_attr_in1_input.dev_attr.attr,
1316b353a487SJean Delvare 	&sensor_dev_attr_in2_input.dev_attr.attr,
1317b353a487SJean Delvare 	&sensor_dev_attr_in3_input.dev_attr.attr,
1318b353a487SJean Delvare 	&sensor_dev_attr_in0_min.dev_attr.attr,
1319b353a487SJean Delvare 	&sensor_dev_attr_in1_min.dev_attr.attr,
1320b353a487SJean Delvare 	&sensor_dev_attr_in2_min.dev_attr.attr,
1321b353a487SJean Delvare 	&sensor_dev_attr_in3_min.dev_attr.attr,
1322b353a487SJean Delvare 	&sensor_dev_attr_in0_max.dev_attr.attr,
1323b353a487SJean Delvare 	&sensor_dev_attr_in1_max.dev_attr.attr,
1324b353a487SJean Delvare 	&sensor_dev_attr_in2_max.dev_attr.attr,
1325b353a487SJean Delvare 	&sensor_dev_attr_in3_max.dev_attr.attr,
1326bf76e9d3SJean Delvare 	&sensor_dev_attr_in0_alarm.dev_attr.attr,
1327bf76e9d3SJean Delvare 	&sensor_dev_attr_in1_alarm.dev_attr.attr,
1328bf76e9d3SJean Delvare 	&sensor_dev_attr_in2_alarm.dev_attr.attr,
1329bf76e9d3SJean Delvare 	&sensor_dev_attr_in3_alarm.dev_attr.attr,
1330b353a487SJean Delvare 
1331b353a487SJean Delvare 	&sensor_dev_attr_temp1_input.dev_attr.attr,
1332b353a487SJean Delvare 	&sensor_dev_attr_temp2_input.dev_attr.attr,
1333b353a487SJean Delvare 	&sensor_dev_attr_temp3_input.dev_attr.attr,
1334b353a487SJean Delvare 	&sensor_dev_attr_temp1_min.dev_attr.attr,
1335b353a487SJean Delvare 	&sensor_dev_attr_temp2_min.dev_attr.attr,
1336b353a487SJean Delvare 	&sensor_dev_attr_temp3_min.dev_attr.attr,
1337b353a487SJean Delvare 	&sensor_dev_attr_temp1_max.dev_attr.attr,
1338b353a487SJean Delvare 	&sensor_dev_attr_temp2_max.dev_attr.attr,
1339b353a487SJean Delvare 	&sensor_dev_attr_temp3_max.dev_attr.attr,
1340bf76e9d3SJean Delvare 	&sensor_dev_attr_temp1_alarm.dev_attr.attr,
1341bf76e9d3SJean Delvare 	&sensor_dev_attr_temp2_alarm.dev_attr.attr,
1342bf76e9d3SJean Delvare 	&sensor_dev_attr_temp3_alarm.dev_attr.attr,
1343bf76e9d3SJean Delvare 	&sensor_dev_attr_temp1_fault.dev_attr.attr,
1344bf76e9d3SJean Delvare 	&sensor_dev_attr_temp3_fault.dev_attr.attr,
1345b353a487SJean Delvare 
1346b353a487SJean Delvare 	&sensor_dev_attr_pwm1_auto_channels.dev_attr.attr,
1347b353a487SJean Delvare 	&sensor_dev_attr_pwm2_auto_channels.dev_attr.attr,
1348b353a487SJean Delvare 	&sensor_dev_attr_pwm3_auto_channels.dev_attr.attr,
1349b353a487SJean Delvare 	&sensor_dev_attr_pwm1_auto_pwm_min.dev_attr.attr,
1350b353a487SJean Delvare 	&sensor_dev_attr_pwm2_auto_pwm_min.dev_attr.attr,
1351b353a487SJean Delvare 	&sensor_dev_attr_pwm3_auto_pwm_min.dev_attr.attr,
1352b353a487SJean Delvare 
1353b353a487SJean Delvare 	&sensor_dev_attr_temp1_auto_temp_min.dev_attr.attr,
1354b353a487SJean Delvare 	&sensor_dev_attr_temp2_auto_temp_min.dev_attr.attr,
1355b353a487SJean Delvare 	&sensor_dev_attr_temp3_auto_temp_min.dev_attr.attr,
1356b353a487SJean Delvare 	&sensor_dev_attr_temp1_auto_temp_max.dev_attr.attr,
1357b353a487SJean Delvare 	&sensor_dev_attr_temp2_auto_temp_max.dev_attr.attr,
1358b353a487SJean Delvare 	&sensor_dev_attr_temp3_auto_temp_max.dev_attr.attr,
1359b353a487SJean Delvare 	&sensor_dev_attr_temp1_auto_temp_crit.dev_attr.attr,
1360b353a487SJean Delvare 	&sensor_dev_attr_temp2_auto_temp_crit.dev_attr.attr,
1361b353a487SJean Delvare 	&sensor_dev_attr_temp3_auto_temp_crit.dev_attr.attr,
1362b353a487SJean Delvare 
13630501a381SMark M. Hoffman 	&dev_attr_vrm.attr,
13640501a381SMark M. Hoffman 	&dev_attr_cpu0_vid.attr,
13650501a381SMark M. Hoffman 	&dev_attr_alarms.attr,
13660501a381SMark M. Hoffman 	NULL
13670501a381SMark M. Hoffman };
13680501a381SMark M. Hoffman 
13690501a381SMark M. Hoffman static const struct attribute_group lm85_group = {
13700501a381SMark M. Hoffman 	.attrs = lm85_attributes,
13710501a381SMark M. Hoffman };
13720501a381SMark M. Hoffman 
137306923f84SGuenter Roeck static struct attribute *lm85_attributes_minctl[] = {
137406923f84SGuenter Roeck 	&sensor_dev_attr_pwm1_auto_pwm_minctl.dev_attr.attr,
137506923f84SGuenter Roeck 	&sensor_dev_attr_pwm2_auto_pwm_minctl.dev_attr.attr,
137606923f84SGuenter Roeck 	&sensor_dev_attr_pwm3_auto_pwm_minctl.dev_attr.attr,
13775f441e22SJean Delvare 	NULL
137806923f84SGuenter Roeck };
137906923f84SGuenter Roeck 
138006923f84SGuenter Roeck static const struct attribute_group lm85_group_minctl = {
138106923f84SGuenter Roeck 	.attrs = lm85_attributes_minctl,
138206923f84SGuenter Roeck };
138306923f84SGuenter Roeck 
138406923f84SGuenter Roeck static struct attribute *lm85_attributes_temp_off[] = {
138506923f84SGuenter Roeck 	&sensor_dev_attr_temp1_auto_temp_off.dev_attr.attr,
138606923f84SGuenter Roeck 	&sensor_dev_attr_temp2_auto_temp_off.dev_attr.attr,
138706923f84SGuenter Roeck 	&sensor_dev_attr_temp3_auto_temp_off.dev_attr.attr,
13885f441e22SJean Delvare 	NULL
138906923f84SGuenter Roeck };
139006923f84SGuenter Roeck 
139106923f84SGuenter Roeck static const struct attribute_group lm85_group_temp_off = {
139206923f84SGuenter Roeck 	.attrs = lm85_attributes_temp_off,
139306923f84SGuenter Roeck };
139406923f84SGuenter Roeck 
13956b9aad2dSJean Delvare static struct attribute *lm85_attributes_in4[] = {
1396b353a487SJean Delvare 	&sensor_dev_attr_in4_input.dev_attr.attr,
1397b353a487SJean Delvare 	&sensor_dev_attr_in4_min.dev_attr.attr,
1398b353a487SJean Delvare 	&sensor_dev_attr_in4_max.dev_attr.attr,
1399bf76e9d3SJean Delvare 	&sensor_dev_attr_in4_alarm.dev_attr.attr,
14000501a381SMark M. Hoffman 	NULL
14010501a381SMark M. Hoffman };
14020501a381SMark M. Hoffman 
14036b9aad2dSJean Delvare static const struct attribute_group lm85_group_in4 = {
14046b9aad2dSJean Delvare 	.attrs = lm85_attributes_in4,
14056b9aad2dSJean Delvare };
14066b9aad2dSJean Delvare 
14076b9aad2dSJean Delvare static struct attribute *lm85_attributes_in567[] = {
14086b9aad2dSJean Delvare 	&sensor_dev_attr_in5_input.dev_attr.attr,
14096b9aad2dSJean Delvare 	&sensor_dev_attr_in6_input.dev_attr.attr,
14106b9aad2dSJean Delvare 	&sensor_dev_attr_in7_input.dev_attr.attr,
14116b9aad2dSJean Delvare 	&sensor_dev_attr_in5_min.dev_attr.attr,
14126b9aad2dSJean Delvare 	&sensor_dev_attr_in6_min.dev_attr.attr,
14136b9aad2dSJean Delvare 	&sensor_dev_attr_in7_min.dev_attr.attr,
14146b9aad2dSJean Delvare 	&sensor_dev_attr_in5_max.dev_attr.attr,
14156b9aad2dSJean Delvare 	&sensor_dev_attr_in6_max.dev_attr.attr,
14166b9aad2dSJean Delvare 	&sensor_dev_attr_in7_max.dev_attr.attr,
1417bf76e9d3SJean Delvare 	&sensor_dev_attr_in5_alarm.dev_attr.attr,
1418bf76e9d3SJean Delvare 	&sensor_dev_attr_in6_alarm.dev_attr.attr,
1419bf76e9d3SJean Delvare 	&sensor_dev_attr_in7_alarm.dev_attr.attr,
14206b9aad2dSJean Delvare 	NULL
14216b9aad2dSJean Delvare };
14226b9aad2dSJean Delvare 
14236b9aad2dSJean Delvare static const struct attribute_group lm85_group_in567 = {
14246b9aad2dSJean Delvare 	.attrs = lm85_attributes_in567,
14250501a381SMark M. Hoffman };
14260501a381SMark M. Hoffman 
lm85_init_client(struct i2c_client * client)14275f447594SJean Delvare static void lm85_init_client(struct i2c_client *client)
14285f447594SJean Delvare {
14295f447594SJean Delvare 	int value;
14305f447594SJean Delvare 
14315f447594SJean Delvare 	/* Start monitoring if needed */
14325f447594SJean Delvare 	value = lm85_read_value(client, LM85_REG_CONFIG);
14335f447594SJean Delvare 	if (!(value & 0x01)) {
14345f447594SJean Delvare 		dev_info(&client->dev, "Starting monitoring\n");
14355f447594SJean Delvare 		lm85_write_value(client, LM85_REG_CONFIG, value | 0x01);
14365f447594SJean Delvare 	}
14375f447594SJean Delvare 
14385f447594SJean Delvare 	/* Warn about unusual configuration bits */
14395f447594SJean Delvare 	if (value & 0x02)
14405f447594SJean Delvare 		dev_warn(&client->dev, "Device configuration is locked\n");
14415f447594SJean Delvare 	if (!(value & 0x04))
14425f447594SJean Delvare 		dev_warn(&client->dev, "Device is not ready\n");
14435f447594SJean Delvare }
14445f447594SJean Delvare 
lm85_is_fake(struct i2c_client * client)14455cfaf338SJean Delvare static int lm85_is_fake(struct i2c_client *client)
14465cfaf338SJean Delvare {
14475cfaf338SJean Delvare 	/*
14485cfaf338SJean Delvare 	 * Differenciate between real LM96000 and Winbond WPCD377I. The latter
14495cfaf338SJean Delvare 	 * emulate the former except that it has no hardware monitoring function
14505cfaf338SJean Delvare 	 * so the readings are always 0.
14515cfaf338SJean Delvare 	 */
14525cfaf338SJean Delvare 	int i;
14535cfaf338SJean Delvare 	u8 in_temp, fan;
14545cfaf338SJean Delvare 
14555cfaf338SJean Delvare 	for (i = 0; i < 8; i++) {
14565cfaf338SJean Delvare 		in_temp = i2c_smbus_read_byte_data(client, 0x20 + i);
14575cfaf338SJean Delvare 		fan = i2c_smbus_read_byte_data(client, 0x28 + i);
14585cfaf338SJean Delvare 		if (in_temp != 0x00 || fan != 0xff)
14595cfaf338SJean Delvare 			return 0;
14605cfaf338SJean Delvare 	}
14615cfaf338SJean Delvare 
14625cfaf338SJean Delvare 	return 1;
14635cfaf338SJean Delvare }
14645cfaf338SJean Delvare 
146567712d01SJean Delvare /* Return 0 if detection is successful, -ENODEV otherwise */
lm85_detect(struct i2c_client * client,struct i2c_board_info * info)1466310ec792SJean Delvare static int lm85_detect(struct i2c_client *client, struct i2c_board_info *info)
14678d5d45fbSJean Delvare {
146867712d01SJean Delvare 	struct i2c_adapter *adapter = client->adapter;
146967712d01SJean Delvare 	int address = client->addr;
1470590e8534SJean Delvare 	const char *type_name = NULL;
1471d42a2eb5SJean Delvare 	int company, verstep;
14728d5d45fbSJean Delvare 
1473e89e22b2SJean Delvare 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
14748d5d45fbSJean Delvare 		/* We need to be able to do byte I/O */
147567712d01SJean Delvare 		return -ENODEV;
14761f44809aSJean Delvare 	}
14778d5d45fbSJean Delvare 
1478d42a2eb5SJean Delvare 	/* Determine the chip type */
1479d42a2eb5SJean Delvare 	company = lm85_read_value(client, LM85_REG_COMPANY);
1480d42a2eb5SJean Delvare 	verstep = lm85_read_value(client, LM85_REG_VERSTEP);
14818d5d45fbSJean Delvare 
1482b55f3757SGuenter Roeck 	dev_dbg(&adapter->dev,
1483b55f3757SGuenter Roeck 		"Detecting device at 0x%02x with COMPANY: 0x%02x and VERSTEP: 0x%02x\n",
148469fc1febSJean Delvare 		address, company, verstep);
14858d5d45fbSJean Delvare 
148669fc1febSJean Delvare 	if (company == LM85_COMPANY_NATIONAL) {
148769fc1febSJean Delvare 		switch (verstep) {
148869fc1febSJean Delvare 		case LM85_VERSTEP_LM85C:
1489d42a2eb5SJean Delvare 			type_name = "lm85c";
149069fc1febSJean Delvare 			break;
149169fc1febSJean Delvare 		case LM85_VERSTEP_LM85B:
1492d42a2eb5SJean Delvare 			type_name = "lm85b";
149369fc1febSJean Delvare 			break;
14945cfaf338SJean Delvare 		case LM85_VERSTEP_LM96000_1:
14955cfaf338SJean Delvare 		case LM85_VERSTEP_LM96000_2:
14965cfaf338SJean Delvare 			/* Check for Winbond WPCD377I */
14975cfaf338SJean Delvare 			if (lm85_is_fake(client)) {
14985cfaf338SJean Delvare 				dev_dbg(&adapter->dev,
1499d42a2eb5SJean Delvare 					"Found Winbond WPCD377I, ignoring\n");
15005cfaf338SJean Delvare 				return -ENODEV;
15015cfaf338SJean Delvare 			}
150211650cf0SJeremy Gebben 			type_name = "lm96000";
15035cfaf338SJean Delvare 			break;
150469fc1febSJean Delvare 		}
150569fc1febSJean Delvare 	} else if (company == LM85_COMPANY_ANALOG_DEV) {
150669fc1febSJean Delvare 		switch (verstep) {
150769fc1febSJean Delvare 		case LM85_VERSTEP_ADM1027:
1508d42a2eb5SJean Delvare 			type_name = "adm1027";
150969fc1febSJean Delvare 			break;
151069fc1febSJean Delvare 		case LM85_VERSTEP_ADT7463:
151169fc1febSJean Delvare 		case LM85_VERSTEP_ADT7463C:
1512d42a2eb5SJean Delvare 			type_name = "adt7463";
151369fc1febSJean Delvare 			break;
151479b92f2bSDarrick J. Wong 		case LM85_VERSTEP_ADT7468_1:
151579b92f2bSDarrick J. Wong 		case LM85_VERSTEP_ADT7468_2:
1516d42a2eb5SJean Delvare 			type_name = "adt7468";
151779b92f2bSDarrick J. Wong 			break;
151869fc1febSJean Delvare 		}
151969fc1febSJean Delvare 	} else if (company == LM85_COMPANY_SMSC) {
152069fc1febSJean Delvare 		switch (verstep) {
152169fc1febSJean Delvare 		case LM85_VERSTEP_EMC6D100_A0:
152269fc1febSJean Delvare 		case LM85_VERSTEP_EMC6D100_A1:
152369fc1febSJean Delvare 			/* Note: we can't tell a '100 from a '101 */
1524d42a2eb5SJean Delvare 			type_name = "emc6d100";
152569fc1febSJean Delvare 			break;
152669fc1febSJean Delvare 		case LM85_VERSTEP_EMC6D102:
1527d42a2eb5SJean Delvare 			type_name = "emc6d102";
152869fc1febSJean Delvare 			break;
1529f065a93eSJan Beulich 		case LM85_VERSTEP_EMC6D103_A0:
1530f065a93eSJan Beulich 		case LM85_VERSTEP_EMC6D103_A1:
1531f065a93eSJan Beulich 			type_name = "emc6d103";
1532f065a93eSJan Beulich 			break;
1533f065a93eSJan Beulich 		case LM85_VERSTEP_EMC6D103S:
1534f065a93eSJan Beulich 			type_name = "emc6d103s";
1535f065a93eSJan Beulich 			break;
153669fc1febSJean Delvare 		}
15378d5d45fbSJean Delvare 	}
15388d5d45fbSJean Delvare 
1539590e8534SJean Delvare 	if (!type_name)
1540590e8534SJean Delvare 		return -ENODEV;
1541590e8534SJean Delvare 
1542f2f394dbSWolfram Sang 	strscpy(info->type, type_name, I2C_NAME_SIZE);
15438d5d45fbSJean Delvare 
154467712d01SJean Delvare 	return 0;
154567712d01SJean Delvare }
154667712d01SJean Delvare 
154767487038SStephen Kitt static const struct i2c_device_id lm85_id[];
154867487038SStephen Kitt 
lm85_probe(struct i2c_client * client)154967487038SStephen Kitt static int lm85_probe(struct i2c_client *client)
1550bc6db2b5SGuenter Roeck {
1551746f6884SAxel Lin 	struct device *dev = &client->dev;
1552746f6884SAxel Lin 	struct device *hwmon_dev;
155367712d01SJean Delvare 	struct lm85_data *data;
1554746f6884SAxel Lin 	int idx = 0;
155567712d01SJean Delvare 
1556746f6884SAxel Lin 	data = devm_kzalloc(dev, sizeof(struct lm85_data), GFP_KERNEL);
155767712d01SJean Delvare 	if (!data)
155867712d01SJean Delvare 		return -ENOMEM;
155967712d01SJean Delvare 
1560746f6884SAxel Lin 	data->client = client;
156100c0f9d3SJavier Martinez Canillas 	if (client->dev.of_node)
1562*8d84910aSKrzysztof Kozlowski 		data->type = (uintptr_t)of_device_get_match_data(&client->dev);
156300c0f9d3SJavier Martinez Canillas 	else
156467487038SStephen Kitt 		data->type = i2c_match_id(lm85_id, client)->driver_data;
15659a61bf63SIngo Molnar 	mutex_init(&data->update_lock);
15668d5d45fbSJean Delvare 
156767712d01SJean Delvare 	/* Fill in the chip specific driver values */
156867712d01SJean Delvare 	switch (data->type) {
156967712d01SJean Delvare 	case adm1027:
157067712d01SJean Delvare 	case adt7463:
1571fa7a5797SJean Delvare 	case adt7468:
157267712d01SJean Delvare 	case emc6d100:
157367712d01SJean Delvare 	case emc6d102:
1574f065a93eSJan Beulich 	case emc6d103:
157506923f84SGuenter Roeck 	case emc6d103s:
157667712d01SJean Delvare 		data->freq_map = adm1027_freq_map;
157757bc3019SJeremy Gebben 		data->freq_map_size = ARRAY_SIZE(adm1027_freq_map);
157867712d01SJean Delvare 		break;
1579e9b95485SJeremy Gebben 	case lm96000:
1580e9b95485SJeremy Gebben 		data->freq_map = lm96000_freq_map;
1581e9b95485SJeremy Gebben 		data->freq_map_size = ARRAY_SIZE(lm96000_freq_map);
1582e9b95485SJeremy Gebben 		break;
158367712d01SJean Delvare 	default:
158467712d01SJean Delvare 		data->freq_map = lm85_freq_map;
158557bc3019SJeremy Gebben 		data->freq_map_size = ARRAY_SIZE(lm85_freq_map);
158667712d01SJean Delvare 	}
15878d5d45fbSJean Delvare 
15888d5d45fbSJean Delvare 	/* Set the VRM version */
1589303760b4SJean Delvare 	data->vrm = vid_which_vrm();
15908d5d45fbSJean Delvare 
15918d5d45fbSJean Delvare 	/* Initialize the LM85 chip */
1592e89e22b2SJean Delvare 	lm85_init_client(client);
15938d5d45fbSJean Delvare 
1594746f6884SAxel Lin 	/* sysfs hooks */
1595746f6884SAxel Lin 	data->groups[idx++] = &lm85_group;
15968d5d45fbSJean Delvare 
159706923f84SGuenter Roeck 	/* minctl and temp_off exist on all chips except emc6d103s */
159806923f84SGuenter Roeck 	if (data->type != emc6d103s) {
1599746f6884SAxel Lin 		data->groups[idx++] = &lm85_group_minctl;
1600746f6884SAxel Lin 		data->groups[idx++] = &lm85_group_temp_off;
160106923f84SGuenter Roeck 	}
160206923f84SGuenter Roeck 
160309770b26SGuenter Roeck 	/*
160409770b26SGuenter Roeck 	 * The ADT7463/68 have an optional VRM 10 mode where pin 21 is used
160509770b26SGuenter Roeck 	 * as a sixth digital VID input rather than an analog input.
160609770b26SGuenter Roeck 	 */
1607de248805SGuenter Roeck 	if (data->type == adt7463 || data->type == adt7468) {
1608de248805SGuenter Roeck 		u8 vid = lm85_read_value(client, LM85_REG_VID);
1609de248805SGuenter Roeck 		if (vid & 0x80)
1610de248805SGuenter Roeck 			data->has_vid5 = true;
1611de248805SGuenter Roeck 	}
1612de248805SGuenter Roeck 
1613746f6884SAxel Lin 	if (!data->has_vid5)
1614746f6884SAxel Lin 		data->groups[idx++] = &lm85_group_in4;
16156b9aad2dSJean Delvare 
16166b9aad2dSJean Delvare 	/* The EMC6D100 has 3 additional voltage inputs */
1617746f6884SAxel Lin 	if (data->type == emc6d100)
1618746f6884SAxel Lin 		data->groups[idx++] = &lm85_group_in567;
16190501a381SMark M. Hoffman 
1620746f6884SAxel Lin 	hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
1621746f6884SAxel Lin 							   data, data->groups);
1622746f6884SAxel Lin 	return PTR_ERR_OR_ZERO(hwmon_dev);
16238d5d45fbSJean Delvare }
16248d5d45fbSJean Delvare 
16256fd5dd58SAxel Lin static const struct i2c_device_id lm85_id[] = {
16266fd5dd58SAxel Lin 	{ "adm1027", adm1027 },
16276fd5dd58SAxel Lin 	{ "adt7463", adt7463 },
16286fd5dd58SAxel Lin 	{ "adt7468", adt7468 },
16296fd5dd58SAxel Lin 	{ "lm85", lm85 },
16306fd5dd58SAxel Lin 	{ "lm85b", lm85 },
16316fd5dd58SAxel Lin 	{ "lm85c", lm85 },
163211650cf0SJeremy Gebben 	{ "lm96000", lm96000 },
16336fd5dd58SAxel Lin 	{ "emc6d100", emc6d100 },
16346fd5dd58SAxel Lin 	{ "emc6d101", emc6d100 },
16356fd5dd58SAxel Lin 	{ "emc6d102", emc6d102 },
16366fd5dd58SAxel Lin 	{ "emc6d103", emc6d103 },
16376fd5dd58SAxel Lin 	{ "emc6d103s", emc6d103s },
16386fd5dd58SAxel Lin 	{ }
16396fd5dd58SAxel Lin };
16406fd5dd58SAxel Lin MODULE_DEVICE_TABLE(i2c, lm85_id);
16418d5d45fbSJean Delvare 
164220b497abSGuenter Roeck static const struct of_device_id __maybe_unused lm85_of_match[] = {
164300c0f9d3SJavier Martinez Canillas 	{
164400c0f9d3SJavier Martinez Canillas 		.compatible = "adi,adm1027",
164500c0f9d3SJavier Martinez Canillas 		.data = (void *)adm1027
164600c0f9d3SJavier Martinez Canillas 	},
164700c0f9d3SJavier Martinez Canillas 	{
164800c0f9d3SJavier Martinez Canillas 		.compatible = "adi,adt7463",
164900c0f9d3SJavier Martinez Canillas 		.data = (void *)adt7463
165000c0f9d3SJavier Martinez Canillas 	},
165100c0f9d3SJavier Martinez Canillas 	{
165200c0f9d3SJavier Martinez Canillas 		.compatible = "adi,adt7468",
165300c0f9d3SJavier Martinez Canillas 		.data = (void *)adt7468
165400c0f9d3SJavier Martinez Canillas 	},
165500c0f9d3SJavier Martinez Canillas 	{
165600c0f9d3SJavier Martinez Canillas 		.compatible = "national,lm85",
165700c0f9d3SJavier Martinez Canillas 		.data = (void *)lm85
165800c0f9d3SJavier Martinez Canillas 	},
165900c0f9d3SJavier Martinez Canillas 	{
166000c0f9d3SJavier Martinez Canillas 		.compatible = "national,lm85b",
166100c0f9d3SJavier Martinez Canillas 		.data = (void *)lm85
166200c0f9d3SJavier Martinez Canillas 	},
166300c0f9d3SJavier Martinez Canillas 	{
166400c0f9d3SJavier Martinez Canillas 		.compatible = "national,lm85c",
166500c0f9d3SJavier Martinez Canillas 		.data = (void *)lm85
166600c0f9d3SJavier Martinez Canillas 	},
166700c0f9d3SJavier Martinez Canillas 	{
166811650cf0SJeremy Gebben 		.compatible = "ti,lm96000",
166911650cf0SJeremy Gebben 		.data = (void *)lm96000
167011650cf0SJeremy Gebben 	},
167111650cf0SJeremy Gebben 	{
167200c0f9d3SJavier Martinez Canillas 		.compatible = "smsc,emc6d100",
167300c0f9d3SJavier Martinez Canillas 		.data = (void *)emc6d100
167400c0f9d3SJavier Martinez Canillas 	},
167500c0f9d3SJavier Martinez Canillas 	{
167600c0f9d3SJavier Martinez Canillas 		.compatible = "smsc,emc6d101",
167700c0f9d3SJavier Martinez Canillas 		.data = (void *)emc6d100
167800c0f9d3SJavier Martinez Canillas 	},
167900c0f9d3SJavier Martinez Canillas 	{
168000c0f9d3SJavier Martinez Canillas 		.compatible = "smsc,emc6d102",
168100c0f9d3SJavier Martinez Canillas 		.data = (void *)emc6d102
168200c0f9d3SJavier Martinez Canillas 	},
168300c0f9d3SJavier Martinez Canillas 	{
168400c0f9d3SJavier Martinez Canillas 		.compatible = "smsc,emc6d103",
168500c0f9d3SJavier Martinez Canillas 		.data = (void *)emc6d103
168600c0f9d3SJavier Martinez Canillas 	},
168700c0f9d3SJavier Martinez Canillas 	{
168800c0f9d3SJavier Martinez Canillas 		.compatible = "smsc,emc6d103s",
168900c0f9d3SJavier Martinez Canillas 		.data = (void *)emc6d103s
169000c0f9d3SJavier Martinez Canillas 	},
169100c0f9d3SJavier Martinez Canillas 	{ },
169200c0f9d3SJavier Martinez Canillas };
169300c0f9d3SJavier Martinez Canillas MODULE_DEVICE_TABLE(of, lm85_of_match);
169400c0f9d3SJavier Martinez Canillas 
16956fd5dd58SAxel Lin static struct i2c_driver lm85_driver = {
16966fd5dd58SAxel Lin 	.class		= I2C_CLASS_HWMON,
16976fd5dd58SAxel Lin 	.driver = {
16986fd5dd58SAxel Lin 		.name   = "lm85",
169900c0f9d3SJavier Martinez Canillas 		.of_match_table = of_match_ptr(lm85_of_match),
17006fd5dd58SAxel Lin 	},
17011975d167SUwe Kleine-König 	.probe		= lm85_probe,
17026fd5dd58SAxel Lin 	.id_table	= lm85_id,
17036fd5dd58SAxel Lin 	.detect		= lm85_detect,
17046fd5dd58SAxel Lin 	.address_list	= normal_i2c,
17056fd5dd58SAxel Lin };
17068d5d45fbSJean Delvare 
1707f0967eeaSAxel Lin module_i2c_driver(lm85_driver);
17088d5d45fbSJean Delvare 
17098d5d45fbSJean Delvare MODULE_LICENSE("GPL");
17101f44809aSJean Delvare MODULE_AUTHOR("Philip Pokorny <ppokorny@penguincomputing.com>, "
17111f44809aSJean Delvare 	"Margit Schubert-While <margitsw@t-online.de>, "
1712e89e22b2SJean Delvare 	"Justin Thiessen <jthiessen@penguincomputing.com>");
17138d5d45fbSJean Delvare MODULE_DESCRIPTION("LM85-B, LM85-C driver");
1714