xref: /linux/drivers/hwmon/adt7462.c (revision b94793b4da1011f24321e2ecc5e173a7198358a5)
1c0b4e3abSDarrick J. Wong /*
2c0b4e3abSDarrick J. Wong  * A hwmon driver for the Analog Devices ADT7462
3c0b4e3abSDarrick J. Wong  * Copyright (C) 2008 IBM
4c0b4e3abSDarrick J. Wong  *
55407e051SDarrick J. Wong  * Author: Darrick J. Wong <darrick.wong@oracle.com>
6c0b4e3abSDarrick J. Wong  *
7c0b4e3abSDarrick J. Wong  * This program is free software; you can redistribute it and/or modify
8c0b4e3abSDarrick J. Wong  * it under the terms of the GNU General Public License as published by
9c0b4e3abSDarrick J. Wong  * the Free Software Foundation; either version 2 of the License, or
10c0b4e3abSDarrick J. Wong  * (at your option) any later version.
11c0b4e3abSDarrick J. Wong  *
12c0b4e3abSDarrick J. Wong  * This program is distributed in the hope that it will be useful,
13c0b4e3abSDarrick J. Wong  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14c0b4e3abSDarrick J. Wong  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15c0b4e3abSDarrick J. Wong  * GNU General Public License for more details.
16c0b4e3abSDarrick J. Wong  *
17c0b4e3abSDarrick J. Wong  * You should have received a copy of the GNU General Public License
18c0b4e3abSDarrick J. Wong  * along with this program; if not, write to the Free Software
19c0b4e3abSDarrick J. Wong  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20c0b4e3abSDarrick J. Wong  */
21c0b4e3abSDarrick J. Wong 
22c0b4e3abSDarrick J. Wong #include <linux/module.h>
23c0b4e3abSDarrick J. Wong #include <linux/jiffies.h>
24c0b4e3abSDarrick J. Wong #include <linux/i2c.h>
25c0b4e3abSDarrick J. Wong #include <linux/hwmon.h>
26c0b4e3abSDarrick J. Wong #include <linux/hwmon-sysfs.h>
27c0b4e3abSDarrick J. Wong #include <linux/err.h>
28c0b4e3abSDarrick J. Wong #include <linux/mutex.h>
29c0b4e3abSDarrick J. Wong #include <linux/log2.h>
305a0e3ad6STejun Heo #include <linux/slab.h>
31c0b4e3abSDarrick J. Wong 
32c0b4e3abSDarrick J. Wong /* Addresses to scan */
33c0b4e3abSDarrick J. Wong static const unsigned short normal_i2c[] = { 0x58, 0x5C, I2C_CLIENT_END };
34c0b4e3abSDarrick J. Wong 
35c0b4e3abSDarrick J. Wong /* ADT7462 registers */
36c0b4e3abSDarrick J. Wong #define ADT7462_REG_DEVICE			0x3D
37c0b4e3abSDarrick J. Wong #define ADT7462_REG_VENDOR			0x3E
38c0b4e3abSDarrick J. Wong #define ADT7462_REG_REVISION			0x3F
39c0b4e3abSDarrick J. Wong 
40c0b4e3abSDarrick J. Wong #define ADT7462_REG_MIN_TEMP_BASE_ADDR		0x44
41c0b4e3abSDarrick J. Wong #define ADT7462_REG_MIN_TEMP_MAX_ADDR		0x47
42c0b4e3abSDarrick J. Wong #define ADT7462_REG_MAX_TEMP_BASE_ADDR		0x48
43c0b4e3abSDarrick J. Wong #define ADT7462_REG_MAX_TEMP_MAX_ADDR		0x4B
44c0b4e3abSDarrick J. Wong #define ADT7462_REG_TEMP_BASE_ADDR		0x88
45c0b4e3abSDarrick J. Wong #define ADT7462_REG_TEMP_MAX_ADDR		0x8F
46c0b4e3abSDarrick J. Wong 
47c0b4e3abSDarrick J. Wong #define ADT7462_REG_FAN_BASE_ADDR		0x98
48c0b4e3abSDarrick J. Wong #define ADT7462_REG_FAN_MAX_ADDR		0x9F
49c0b4e3abSDarrick J. Wong #define ADT7462_REG_FAN2_BASE_ADDR		0xA2
50c0b4e3abSDarrick J. Wong #define ADT7462_REG_FAN2_MAX_ADDR		0xA9
51c0b4e3abSDarrick J. Wong #define ADT7462_REG_FAN_ENABLE			0x07
52c0b4e3abSDarrick J. Wong #define ADT7462_REG_FAN_MIN_BASE_ADDR		0x78
53c0b4e3abSDarrick J. Wong #define ADT7462_REG_FAN_MIN_MAX_ADDR		0x7F
54c0b4e3abSDarrick J. Wong 
55c0b4e3abSDarrick J. Wong #define ADT7462_REG_CFG2			0x02
56c0b4e3abSDarrick J. Wong #define		ADT7462_FSPD_MASK		0x20
57c0b4e3abSDarrick J. Wong 
58c0b4e3abSDarrick J. Wong #define ADT7462_REG_PWM_BASE_ADDR		0xAA
59c0b4e3abSDarrick J. Wong #define ADT7462_REG_PWM_MAX_ADDR		0xAD
60c0b4e3abSDarrick J. Wong #define	ADT7462_REG_PWM_MIN_BASE_ADDR		0x28
61c0b4e3abSDarrick J. Wong #define ADT7462_REG_PWM_MIN_MAX_ADDR		0x2B
62c0b4e3abSDarrick J. Wong #define ADT7462_REG_PWM_MAX			0x2C
63c0b4e3abSDarrick J. Wong #define ADT7462_REG_PWM_TEMP_MIN_BASE_ADDR	0x5C
64c0b4e3abSDarrick J. Wong #define ADT7462_REG_PWM_TEMP_MIN_MAX_ADDR	0x5F
65c0b4e3abSDarrick J. Wong #define ADT7462_REG_PWM_TEMP_RANGE_BASE_ADDR	0x60
66c0b4e3abSDarrick J. Wong #define ADT7462_REG_PWM_TEMP_RANGE_MAX_ADDR	0x63
67c0b4e3abSDarrick J. Wong #define	ADT7462_PWM_HYST_MASK			0x0F
68c0b4e3abSDarrick J. Wong #define	ADT7462_PWM_RANGE_MASK			0xF0
69c0b4e3abSDarrick J. Wong #define		ADT7462_PWM_RANGE_SHIFT		4
70c0b4e3abSDarrick J. Wong #define ADT7462_REG_PWM_CFG_BASE_ADDR		0x21
71c0b4e3abSDarrick J. Wong #define ADT7462_REG_PWM_CFG_MAX_ADDR		0x24
72c0b4e3abSDarrick J. Wong #define		ADT7462_PWM_CHANNEL_MASK	0xE0
73c0b4e3abSDarrick J. Wong #define		ADT7462_PWM_CHANNEL_SHIFT	5
74c0b4e3abSDarrick J. Wong 
75c0b4e3abSDarrick J. Wong #define ADT7462_REG_PIN_CFG_BASE_ADDR		0x10
76c0b4e3abSDarrick J. Wong #define ADT7462_REG_PIN_CFG_MAX_ADDR		0x13
77c0b4e3abSDarrick J. Wong #define		ADT7462_PIN7_INPUT		0x01	/* cfg0 */
78c0b4e3abSDarrick J. Wong #define		ADT7462_DIODE3_INPUT		0x20
79c0b4e3abSDarrick J. Wong #define		ADT7462_DIODE1_INPUT		0x40
80c0b4e3abSDarrick J. Wong #define		ADT7462_VID_INPUT		0x80
81c0b4e3abSDarrick J. Wong #define		ADT7462_PIN22_INPUT		0x04	/* cfg1 */
82c0b4e3abSDarrick J. Wong #define		ADT7462_PIN21_INPUT		0x08
83c0b4e3abSDarrick J. Wong #define		ADT7462_PIN19_INPUT		0x10
84c0b4e3abSDarrick J. Wong #define		ADT7462_PIN15_INPUT		0x20
85c0b4e3abSDarrick J. Wong #define		ADT7462_PIN13_INPUT		0x40
86c0b4e3abSDarrick J. Wong #define		ADT7462_PIN8_INPUT		0x80
87c0b4e3abSDarrick J. Wong #define		ADT7462_PIN23_MASK		0x03
88c0b4e3abSDarrick J. Wong #define		ADT7462_PIN23_SHIFT		0
89c0b4e3abSDarrick J. Wong #define		ADT7462_PIN26_MASK		0x0C	/* cfg2 */
90c0b4e3abSDarrick J. Wong #define		ADT7462_PIN26_SHIFT		2
91c0b4e3abSDarrick J. Wong #define		ADT7462_PIN25_MASK		0x30
92c0b4e3abSDarrick J. Wong #define		ADT7462_PIN25_SHIFT		4
93c0b4e3abSDarrick J. Wong #define		ADT7462_PIN24_MASK		0xC0
94c0b4e3abSDarrick J. Wong #define		ADT7462_PIN24_SHIFT		6
95c0b4e3abSDarrick J. Wong #define		ADT7462_PIN26_VOLT_INPUT	0x08
96c0b4e3abSDarrick J. Wong #define		ADT7462_PIN25_VOLT_INPUT	0x20
97bb595c92SRoger Blofeld #define		ADT7462_PIN28_SHIFT		4	/* cfg3 */
98c0b4e3abSDarrick J. Wong #define		ADT7462_PIN28_VOLT		0x5
99c0b4e3abSDarrick J. Wong 
100c0b4e3abSDarrick J. Wong #define ADT7462_REG_ALARM1			0xB8
101c0b4e3abSDarrick J. Wong #define	ADT7462_LT_ALARM			0x02
102c0b4e3abSDarrick J. Wong #define		ADT7462_R1T_ALARM		0x04
103c0b4e3abSDarrick J. Wong #define		ADT7462_R2T_ALARM		0x08
104c0b4e3abSDarrick J. Wong #define		ADT7462_R3T_ALARM		0x10
105c0b4e3abSDarrick J. Wong #define ADT7462_REG_ALARM2			0xBB
106c0b4e3abSDarrick J. Wong #define		ADT7462_V0_ALARM		0x01
107c0b4e3abSDarrick J. Wong #define		ADT7462_V1_ALARM		0x02
108c0b4e3abSDarrick J. Wong #define		ADT7462_V2_ALARM		0x04
109c0b4e3abSDarrick J. Wong #define		ADT7462_V3_ALARM		0x08
110c0b4e3abSDarrick J. Wong #define		ADT7462_V4_ALARM		0x10
111c0b4e3abSDarrick J. Wong #define		ADT7462_V5_ALARM		0x20
112c0b4e3abSDarrick J. Wong #define		ADT7462_V6_ALARM		0x40
113c0b4e3abSDarrick J. Wong #define		ADT7462_V7_ALARM		0x80
114c0b4e3abSDarrick J. Wong #define ADT7462_REG_ALARM3			0xBC
115c0b4e3abSDarrick J. Wong #define		ADT7462_V8_ALARM		0x08
116c0b4e3abSDarrick J. Wong #define		ADT7462_V9_ALARM		0x10
117c0b4e3abSDarrick J. Wong #define		ADT7462_V10_ALARM		0x20
118c0b4e3abSDarrick J. Wong #define		ADT7462_V11_ALARM		0x40
119c0b4e3abSDarrick J. Wong #define		ADT7462_V12_ALARM		0x80
120c0b4e3abSDarrick J. Wong #define ADT7462_REG_ALARM4			0xBD
121c0b4e3abSDarrick J. Wong #define		ADT7462_F0_ALARM		0x01
122c0b4e3abSDarrick J. Wong #define		ADT7462_F1_ALARM		0x02
123c0b4e3abSDarrick J. Wong #define		ADT7462_F2_ALARM		0x04
124c0b4e3abSDarrick J. Wong #define		ADT7462_F3_ALARM		0x08
125c0b4e3abSDarrick J. Wong #define		ADT7462_F4_ALARM		0x10
126c0b4e3abSDarrick J. Wong #define		ADT7462_F5_ALARM		0x20
127c0b4e3abSDarrick J. Wong #define		ADT7462_F6_ALARM		0x40
128c0b4e3abSDarrick J. Wong #define		ADT7462_F7_ALARM		0x80
129c0b4e3abSDarrick J. Wong #define ADT7462_ALARM1				0x0000
130c0b4e3abSDarrick J. Wong #define ADT7462_ALARM2				0x0100
131c0b4e3abSDarrick J. Wong #define ADT7462_ALARM3				0x0200
132c0b4e3abSDarrick J. Wong #define ADT7462_ALARM4				0x0300
133c0b4e3abSDarrick J. Wong #define ADT7462_ALARM_REG_SHIFT			8
134c0b4e3abSDarrick J. Wong #define ADT7462_ALARM_FLAG_MASK			0x0F
135c0b4e3abSDarrick J. Wong 
136c0b4e3abSDarrick J. Wong #define ADT7462_TEMP_COUNT		4
137724cc331SGuenter Roeck #define ADT7462_TEMP_REG(x)		(ADT7462_REG_TEMP_BASE_ADDR + ((x) * 2))
138c0b4e3abSDarrick J. Wong #define ADT7462_TEMP_MIN_REG(x)		(ADT7462_REG_MIN_TEMP_BASE_ADDR + (x))
139c0b4e3abSDarrick J. Wong #define ADT7462_TEMP_MAX_REG(x)		(ADT7462_REG_MAX_TEMP_BASE_ADDR + (x))
140c0b4e3abSDarrick J. Wong #define TEMP_FRAC_OFFSET		6
141c0b4e3abSDarrick J. Wong 
142c0b4e3abSDarrick J. Wong #define ADT7462_FAN_COUNT		8
143c0b4e3abSDarrick J. Wong #define ADT7462_REG_FAN_MIN(x)		(ADT7462_REG_FAN_MIN_BASE_ADDR + (x))
144c0b4e3abSDarrick J. Wong 
145c0b4e3abSDarrick J. Wong #define ADT7462_PWM_COUNT		4
146c0b4e3abSDarrick J. Wong #define ADT7462_REG_PWM(x)		(ADT7462_REG_PWM_BASE_ADDR + (x))
147c0b4e3abSDarrick J. Wong #define ADT7462_REG_PWM_MIN(x)		(ADT7462_REG_PWM_MIN_BASE_ADDR + (x))
148c0b4e3abSDarrick J. Wong #define ADT7462_REG_PWM_TMIN(x)		\
149c0b4e3abSDarrick J. Wong 	(ADT7462_REG_PWM_TEMP_MIN_BASE_ADDR + (x))
150c0b4e3abSDarrick J. Wong #define ADT7462_REG_PWM_TRANGE(x)	\
151c0b4e3abSDarrick J. Wong 	(ADT7462_REG_PWM_TEMP_RANGE_BASE_ADDR + (x))
152c0b4e3abSDarrick J. Wong 
153c0b4e3abSDarrick J. Wong #define ADT7462_PIN_CFG_REG_COUNT	4
154c0b4e3abSDarrick J. Wong #define ADT7462_REG_PIN_CFG(x)		(ADT7462_REG_PIN_CFG_BASE_ADDR + (x))
155c0b4e3abSDarrick J. Wong #define ADT7462_REG_PWM_CFG(x)		(ADT7462_REG_PWM_CFG_BASE_ADDR + (x))
156c0b4e3abSDarrick J. Wong 
157c0b4e3abSDarrick J. Wong #define ADT7462_ALARM_REG_COUNT		4
158c0b4e3abSDarrick J. Wong 
159c0b4e3abSDarrick J. Wong /*
160c0b4e3abSDarrick J. Wong  * The chip can measure 13 different voltage sources:
161c0b4e3abSDarrick J. Wong  *
162c0b4e3abSDarrick J. Wong  * 1. +12V1 (pin 7)
163c0b4e3abSDarrick J. Wong  * 2. Vccp1/+2.5V/+1.8V/+1.5V (pin 23)
164c0b4e3abSDarrick J. Wong  * 3. +12V3 (pin 22)
165c0b4e3abSDarrick J. Wong  * 4. +5V (pin 21)
166c0b4e3abSDarrick J. Wong  * 5. +1.25V/+0.9V (pin 19)
167c0b4e3abSDarrick J. Wong  * 6. +2.5V/+1.8V (pin 15)
168c0b4e3abSDarrick J. Wong  * 7. +3.3v (pin 13)
169c0b4e3abSDarrick J. Wong  * 8. +12V2 (pin 8)
170c0b4e3abSDarrick J. Wong  * 9. Vbatt/FSB_Vtt (pin 26)
171c0b4e3abSDarrick J. Wong  * A. +3.3V/+1.2V1 (pin 25)
172c0b4e3abSDarrick J. Wong  * B. Vccp2/+2.5V/+1.8V/+1.5V (pin 24)
173c0b4e3abSDarrick J. Wong  * C. +1.5V ICH (only if BOTH pin 28/29 are set to +1.5V)
174c0b4e3abSDarrick J. Wong  * D. +1.5V 3GPIO (only if BOTH pin 28/29 are set to +1.5V)
175c0b4e3abSDarrick J. Wong  *
176c0b4e3abSDarrick J. Wong  * Each of these 13 has a factor to convert raw to voltage.  Even better,
177c0b4e3abSDarrick J. Wong  * the pins can be connected to other sensors (tach/gpio/hot/etc), which
178c0b4e3abSDarrick J. Wong  * makes the bookkeeping tricky.
179c0b4e3abSDarrick J. Wong  *
180c0b4e3abSDarrick J. Wong  * Some, but not all, of these voltages have low/high limits.
181c0b4e3abSDarrick J. Wong  */
18285f8d3e5SRay Copeland #define ADT7462_VOLT_COUNT	13
183c0b4e3abSDarrick J. Wong 
184c0b4e3abSDarrick J. Wong #define ADT7462_VENDOR		0x41
185c0b4e3abSDarrick J. Wong #define ADT7462_DEVICE		0x62
186c0b4e3abSDarrick J. Wong /* datasheet only mentions a revision 4 */
187c0b4e3abSDarrick J. Wong #define ADT7462_REVISION	0x04
188c0b4e3abSDarrick J. Wong 
189c0b4e3abSDarrick J. Wong /* How often do we reread sensors values? (In jiffies) */
190c0b4e3abSDarrick J. Wong #define SENSOR_REFRESH_INTERVAL	(2 * HZ)
191c0b4e3abSDarrick J. Wong 
192c0b4e3abSDarrick J. Wong /* How often do we reread sensor limit values? (In jiffies) */
193c0b4e3abSDarrick J. Wong #define LIMIT_REFRESH_INTERVAL	(60 * HZ)
194c0b4e3abSDarrick J. Wong 
195c0b4e3abSDarrick J. Wong /* datasheet says to divide this number by the fan reading to get fan rpm */
196c0b4e3abSDarrick J. Wong #define FAN_PERIOD_TO_RPM(x)	((90000 * 60) / (x))
197c0b4e3abSDarrick J. Wong #define FAN_RPM_TO_PERIOD	FAN_PERIOD_TO_RPM
198c0b4e3abSDarrick J. Wong #define FAN_PERIOD_INVALID	65535
199c0b4e3abSDarrick J. Wong #define FAN_DATA_VALID(x)	((x) && (x) != FAN_PERIOD_INVALID)
200c0b4e3abSDarrick J. Wong 
201c0b4e3abSDarrick J. Wong #define MASK_AND_SHIFT(value, prefix)	\
202c0b4e3abSDarrick J. Wong 	(((value) & prefix##_MASK) >> prefix##_SHIFT)
203c0b4e3abSDarrick J. Wong 
204c0b4e3abSDarrick J. Wong struct adt7462_data {
205573bfe67SAxel Lin 	struct i2c_client	*client;
206c0b4e3abSDarrick J. Wong 	struct mutex		lock;
207c0b4e3abSDarrick J. Wong 	char			sensors_valid;
208c0b4e3abSDarrick J. Wong 	char			limits_valid;
209c0b4e3abSDarrick J. Wong 	unsigned long		sensors_last_updated;	/* In jiffies */
210c0b4e3abSDarrick J. Wong 	unsigned long		limits_last_updated;	/* In jiffies */
211c0b4e3abSDarrick J. Wong 
212c0b4e3abSDarrick J. Wong 	u8			temp[ADT7462_TEMP_COUNT];
213c0b4e3abSDarrick J. Wong 				/* bits 6-7 are quarter pieces of temp */
214c0b4e3abSDarrick J. Wong 	u8			temp_frac[ADT7462_TEMP_COUNT];
215c0b4e3abSDarrick J. Wong 	u8			temp_min[ADT7462_TEMP_COUNT];
216c0b4e3abSDarrick J. Wong 	u8			temp_max[ADT7462_TEMP_COUNT];
217c0b4e3abSDarrick J. Wong 	u16			fan[ADT7462_FAN_COUNT];
218c0b4e3abSDarrick J. Wong 	u8			fan_enabled;
219c0b4e3abSDarrick J. Wong 	u8			fan_min[ADT7462_FAN_COUNT];
220c0b4e3abSDarrick J. Wong 	u8			cfg2;
221c0b4e3abSDarrick J. Wong 	u8			pwm[ADT7462_PWM_COUNT];
222c0b4e3abSDarrick J. Wong 	u8			pin_cfg[ADT7462_PIN_CFG_REG_COUNT];
223c0b4e3abSDarrick J. Wong 	u8			voltages[ADT7462_VOLT_COUNT];
224c0b4e3abSDarrick J. Wong 	u8			volt_max[ADT7462_VOLT_COUNT];
225c0b4e3abSDarrick J. Wong 	u8			volt_min[ADT7462_VOLT_COUNT];
226c0b4e3abSDarrick J. Wong 	u8			pwm_min[ADT7462_PWM_COUNT];
227c0b4e3abSDarrick J. Wong 	u8			pwm_tmin[ADT7462_PWM_COUNT];
228c0b4e3abSDarrick J. Wong 	u8			pwm_trange[ADT7462_PWM_COUNT];
229c0b4e3abSDarrick J. Wong 	u8			pwm_max;	/* only one per chip */
230c0b4e3abSDarrick J. Wong 	u8			pwm_cfg[ADT7462_PWM_COUNT];
231c0b4e3abSDarrick J. Wong 	u8			alarms[ADT7462_ALARM_REG_COUNT];
232c0b4e3abSDarrick J. Wong };
233c0b4e3abSDarrick J. Wong 
234c0b4e3abSDarrick J. Wong /*
235c0b4e3abSDarrick J. Wong  * 16-bit registers on the ADT7462 are low-byte first.  The data sheet says
236c0b4e3abSDarrick J. Wong  * that the low byte must be read before the high byte.
237c0b4e3abSDarrick J. Wong  */
238c0b4e3abSDarrick J. Wong static inline int adt7462_read_word_data(struct i2c_client *client, u8 reg)
239c0b4e3abSDarrick J. Wong {
240c0b4e3abSDarrick J. Wong 	u16 foo;
241c0b4e3abSDarrick J. Wong 	foo = i2c_smbus_read_byte_data(client, reg);
242c0b4e3abSDarrick J. Wong 	foo |= ((u16)i2c_smbus_read_byte_data(client, reg + 1) << 8);
243c0b4e3abSDarrick J. Wong 	return foo;
244c0b4e3abSDarrick J. Wong }
245c0b4e3abSDarrick J. Wong 
246c0b4e3abSDarrick J. Wong /* For some reason these registers are not contiguous. */
247c0b4e3abSDarrick J. Wong static int ADT7462_REG_FAN(int fan)
248c0b4e3abSDarrick J. Wong {
249c0b4e3abSDarrick J. Wong 	if (fan < 4)
250c0b4e3abSDarrick J. Wong 		return ADT7462_REG_FAN_BASE_ADDR + (2 * fan);
251c0b4e3abSDarrick J. Wong 	return ADT7462_REG_FAN2_BASE_ADDR + (2 * (fan - 4));
252c0b4e3abSDarrick J. Wong }
253c0b4e3abSDarrick J. Wong 
254c0b4e3abSDarrick J. Wong /* Voltage registers are scattered everywhere */
255c0b4e3abSDarrick J. Wong static int ADT7462_REG_VOLT_MAX(struct adt7462_data *data, int which)
256c0b4e3abSDarrick J. Wong {
257c0b4e3abSDarrick J. Wong 	switch (which) {
258c0b4e3abSDarrick J. Wong 	case 0:
259c0b4e3abSDarrick J. Wong 		if (!(data->pin_cfg[0] & ADT7462_PIN7_INPUT))
260c0b4e3abSDarrick J. Wong 			return 0x7C;
261c0b4e3abSDarrick J. Wong 		break;
262c0b4e3abSDarrick J. Wong 	case 1:
263c0b4e3abSDarrick J. Wong 		return 0x69;
264c0b4e3abSDarrick J. Wong 	case 2:
265c0b4e3abSDarrick J. Wong 		if (!(data->pin_cfg[1] & ADT7462_PIN22_INPUT))
266c0b4e3abSDarrick J. Wong 			return 0x7F;
267c0b4e3abSDarrick J. Wong 		break;
268c0b4e3abSDarrick J. Wong 	case 3:
269c0b4e3abSDarrick J. Wong 		if (!(data->pin_cfg[1] & ADT7462_PIN21_INPUT))
270c0b4e3abSDarrick J. Wong 			return 0x7E;
271c0b4e3abSDarrick J. Wong 		break;
272c0b4e3abSDarrick J. Wong 	case 4:
273c0b4e3abSDarrick J. Wong 		if (!(data->pin_cfg[0] & ADT7462_DIODE3_INPUT))
274c0b4e3abSDarrick J. Wong 			return 0x4B;
275c0b4e3abSDarrick J. Wong 		break;
276c0b4e3abSDarrick J. Wong 	case 5:
277c0b4e3abSDarrick J. Wong 		if (!(data->pin_cfg[0] & ADT7462_DIODE1_INPUT))
278c0b4e3abSDarrick J. Wong 			return 0x49;
279c0b4e3abSDarrick J. Wong 		break;
280c0b4e3abSDarrick J. Wong 	case 6:
281c0b4e3abSDarrick J. Wong 		if (!(data->pin_cfg[1] & ADT7462_PIN13_INPUT))
282c0b4e3abSDarrick J. Wong 			return 0x68;
283c0b4e3abSDarrick J. Wong 		break;
284c0b4e3abSDarrick J. Wong 	case 7:
285c0b4e3abSDarrick J. Wong 		if (!(data->pin_cfg[1] & ADT7462_PIN8_INPUT))
286c0b4e3abSDarrick J. Wong 			return 0x7D;
287c0b4e3abSDarrick J. Wong 		break;
288c0b4e3abSDarrick J. Wong 	case 8:
289c0b4e3abSDarrick J. Wong 		if (!(data->pin_cfg[2] & ADT7462_PIN26_VOLT_INPUT))
290c0b4e3abSDarrick J. Wong 			return 0x6C;
291c0b4e3abSDarrick J. Wong 		break;
292c0b4e3abSDarrick J. Wong 	case 9:
293c0b4e3abSDarrick J. Wong 		if (!(data->pin_cfg[2] & ADT7462_PIN25_VOLT_INPUT))
294c0b4e3abSDarrick J. Wong 			return 0x6B;
295c0b4e3abSDarrick J. Wong 		break;
296c0b4e3abSDarrick J. Wong 	case 10:
297c0b4e3abSDarrick J. Wong 		return 0x6A;
298c0b4e3abSDarrick J. Wong 	case 11:
299c0b4e3abSDarrick J. Wong 		if (data->pin_cfg[3] >> ADT7462_PIN28_SHIFT ==
300c0b4e3abSDarrick J. Wong 					ADT7462_PIN28_VOLT &&
301c0b4e3abSDarrick J. Wong 		    !(data->pin_cfg[0] & ADT7462_VID_INPUT))
302c0b4e3abSDarrick J. Wong 			return 0x50;
303c0b4e3abSDarrick J. Wong 		break;
304c0b4e3abSDarrick J. Wong 	case 12:
305c0b4e3abSDarrick J. Wong 		if (data->pin_cfg[3] >> ADT7462_PIN28_SHIFT ==
306c0b4e3abSDarrick J. Wong 					ADT7462_PIN28_VOLT &&
307c0b4e3abSDarrick J. Wong 		    !(data->pin_cfg[0] & ADT7462_VID_INPUT))
308c0b4e3abSDarrick J. Wong 			return 0x4C;
309c0b4e3abSDarrick J. Wong 		break;
310c0b4e3abSDarrick J. Wong 	}
311a4bf06d5SDan Carpenter 	return 0;
312c0b4e3abSDarrick J. Wong }
313c0b4e3abSDarrick J. Wong 
314c0b4e3abSDarrick J. Wong static int ADT7462_REG_VOLT_MIN(struct adt7462_data *data, int which)
315c0b4e3abSDarrick J. Wong {
316c0b4e3abSDarrick J. Wong 	switch (which) {
317c0b4e3abSDarrick J. Wong 	case 0:
318c0b4e3abSDarrick J. Wong 		if (!(data->pin_cfg[0] & ADT7462_PIN7_INPUT))
319c0b4e3abSDarrick J. Wong 			return 0x6D;
320c0b4e3abSDarrick J. Wong 		break;
321c0b4e3abSDarrick J. Wong 	case 1:
322c0b4e3abSDarrick J. Wong 		return 0x72;
323c0b4e3abSDarrick J. Wong 	case 2:
324c0b4e3abSDarrick J. Wong 		if (!(data->pin_cfg[1] & ADT7462_PIN22_INPUT))
325c0b4e3abSDarrick J. Wong 			return 0x6F;
326c0b4e3abSDarrick J. Wong 		break;
327c0b4e3abSDarrick J. Wong 	case 3:
328c0b4e3abSDarrick J. Wong 		if (!(data->pin_cfg[1] & ADT7462_PIN21_INPUT))
329c0b4e3abSDarrick J. Wong 			return 0x71;
330c0b4e3abSDarrick J. Wong 		break;
331c0b4e3abSDarrick J. Wong 	case 4:
332c0b4e3abSDarrick J. Wong 		if (!(data->pin_cfg[0] & ADT7462_DIODE3_INPUT))
333c0b4e3abSDarrick J. Wong 			return 0x47;
334c0b4e3abSDarrick J. Wong 		break;
335c0b4e3abSDarrick J. Wong 	case 5:
336c0b4e3abSDarrick J. Wong 		if (!(data->pin_cfg[0] & ADT7462_DIODE1_INPUT))
337c0b4e3abSDarrick J. Wong 			return 0x45;
338c0b4e3abSDarrick J. Wong 		break;
339c0b4e3abSDarrick J. Wong 	case 6:
340c0b4e3abSDarrick J. Wong 		if (!(data->pin_cfg[1] & ADT7462_PIN13_INPUT))
341c0b4e3abSDarrick J. Wong 			return 0x70;
342c0b4e3abSDarrick J. Wong 		break;
343c0b4e3abSDarrick J. Wong 	case 7:
344c0b4e3abSDarrick J. Wong 		if (!(data->pin_cfg[1] & ADT7462_PIN8_INPUT))
345c0b4e3abSDarrick J. Wong 			return 0x6E;
346c0b4e3abSDarrick J. Wong 		break;
347c0b4e3abSDarrick J. Wong 	case 8:
348c0b4e3abSDarrick J. Wong 		if (!(data->pin_cfg[2] & ADT7462_PIN26_VOLT_INPUT))
349c0b4e3abSDarrick J. Wong 			return 0x75;
350c0b4e3abSDarrick J. Wong 		break;
351c0b4e3abSDarrick J. Wong 	case 9:
352c0b4e3abSDarrick J. Wong 		if (!(data->pin_cfg[2] & ADT7462_PIN25_VOLT_INPUT))
353c0b4e3abSDarrick J. Wong 			return 0x74;
354c0b4e3abSDarrick J. Wong 		break;
355c0b4e3abSDarrick J. Wong 	case 10:
356c0b4e3abSDarrick J. Wong 		return 0x73;
357c0b4e3abSDarrick J. Wong 	case 11:
358c0b4e3abSDarrick J. Wong 		if (data->pin_cfg[3] >> ADT7462_PIN28_SHIFT ==
359c0b4e3abSDarrick J. Wong 					ADT7462_PIN28_VOLT &&
360c0b4e3abSDarrick J. Wong 		    !(data->pin_cfg[0] & ADT7462_VID_INPUT))
361c0b4e3abSDarrick J. Wong 			return 0x76;
362c0b4e3abSDarrick J. Wong 		break;
363c0b4e3abSDarrick J. Wong 	case 12:
364c0b4e3abSDarrick J. Wong 		if (data->pin_cfg[3] >> ADT7462_PIN28_SHIFT ==
365c0b4e3abSDarrick J. Wong 					ADT7462_PIN28_VOLT &&
366c0b4e3abSDarrick J. Wong 		    !(data->pin_cfg[0] & ADT7462_VID_INPUT))
367c0b4e3abSDarrick J. Wong 			return 0x77;
368c0b4e3abSDarrick J. Wong 		break;
369c0b4e3abSDarrick J. Wong 	}
370a4bf06d5SDan Carpenter 	return 0;
371c0b4e3abSDarrick J. Wong }
372c0b4e3abSDarrick J. Wong 
373c0b4e3abSDarrick J. Wong static int ADT7462_REG_VOLT(struct adt7462_data *data, int which)
374c0b4e3abSDarrick J. Wong {
375c0b4e3abSDarrick J. Wong 	switch (which) {
376c0b4e3abSDarrick J. Wong 	case 0:
377c0b4e3abSDarrick J. Wong 		if (!(data->pin_cfg[0] & ADT7462_PIN7_INPUT))
378c0b4e3abSDarrick J. Wong 			return 0xA3;
379c0b4e3abSDarrick J. Wong 		break;
380c0b4e3abSDarrick J. Wong 	case 1:
381c0b4e3abSDarrick J. Wong 		return 0x90;
382c0b4e3abSDarrick J. Wong 	case 2:
383c0b4e3abSDarrick J. Wong 		if (!(data->pin_cfg[1] & ADT7462_PIN22_INPUT))
384c0b4e3abSDarrick J. Wong 			return 0xA9;
385c0b4e3abSDarrick J. Wong 		break;
386c0b4e3abSDarrick J. Wong 	case 3:
387c0b4e3abSDarrick J. Wong 		if (!(data->pin_cfg[1] & ADT7462_PIN21_INPUT))
388c0b4e3abSDarrick J. Wong 			return 0xA7;
389c0b4e3abSDarrick J. Wong 		break;
390c0b4e3abSDarrick J. Wong 	case 4:
391c0b4e3abSDarrick J. Wong 		if (!(data->pin_cfg[0] & ADT7462_DIODE3_INPUT))
392c0b4e3abSDarrick J. Wong 			return 0x8F;
393c0b4e3abSDarrick J. Wong 		break;
394c0b4e3abSDarrick J. Wong 	case 5:
395c0b4e3abSDarrick J. Wong 		if (!(data->pin_cfg[0] & ADT7462_DIODE1_INPUT))
396c0b4e3abSDarrick J. Wong 			return 0x8B;
397c0b4e3abSDarrick J. Wong 		break;
398c0b4e3abSDarrick J. Wong 	case 6:
399c0b4e3abSDarrick J. Wong 		if (!(data->pin_cfg[1] & ADT7462_PIN13_INPUT))
400c0b4e3abSDarrick J. Wong 			return 0x96;
401c0b4e3abSDarrick J. Wong 		break;
402c0b4e3abSDarrick J. Wong 	case 7:
403c0b4e3abSDarrick J. Wong 		if (!(data->pin_cfg[1] & ADT7462_PIN8_INPUT))
404c0b4e3abSDarrick J. Wong 			return 0xA5;
405c0b4e3abSDarrick J. Wong 		break;
406c0b4e3abSDarrick J. Wong 	case 8:
407c0b4e3abSDarrick J. Wong 		if (!(data->pin_cfg[2] & ADT7462_PIN26_VOLT_INPUT))
408c0b4e3abSDarrick J. Wong 			return 0x93;
409c0b4e3abSDarrick J. Wong 		break;
410c0b4e3abSDarrick J. Wong 	case 9:
411c0b4e3abSDarrick J. Wong 		if (!(data->pin_cfg[2] & ADT7462_PIN25_VOLT_INPUT))
412c0b4e3abSDarrick J. Wong 			return 0x92;
413c0b4e3abSDarrick J. Wong 		break;
414c0b4e3abSDarrick J. Wong 	case 10:
415c0b4e3abSDarrick J. Wong 		return 0x91;
416c0b4e3abSDarrick J. Wong 	case 11:
417c0b4e3abSDarrick J. Wong 		if (data->pin_cfg[3] >> ADT7462_PIN28_SHIFT ==
418c0b4e3abSDarrick J. Wong 					ADT7462_PIN28_VOLT &&
419c0b4e3abSDarrick J. Wong 		    !(data->pin_cfg[0] & ADT7462_VID_INPUT))
420c0b4e3abSDarrick J. Wong 			return 0x94;
421c0b4e3abSDarrick J. Wong 		break;
422c0b4e3abSDarrick J. Wong 	case 12:
423c0b4e3abSDarrick J. Wong 		if (data->pin_cfg[3] >> ADT7462_PIN28_SHIFT ==
424c0b4e3abSDarrick J. Wong 					ADT7462_PIN28_VOLT &&
425c0b4e3abSDarrick J. Wong 		    !(data->pin_cfg[0] & ADT7462_VID_INPUT))
426c0b4e3abSDarrick J. Wong 			return 0x95;
427c0b4e3abSDarrick J. Wong 		break;
428c0b4e3abSDarrick J. Wong 	}
429c0b4e3abSDarrick J. Wong 	return -ENODEV;
430c0b4e3abSDarrick J. Wong }
431c0b4e3abSDarrick J. Wong 
432c0b4e3abSDarrick J. Wong /* Provide labels for sysfs */
433c0b4e3abSDarrick J. Wong static const char *voltage_label(struct adt7462_data *data, int which)
434c0b4e3abSDarrick J. Wong {
435c0b4e3abSDarrick J. Wong 	switch (which) {
436c0b4e3abSDarrick J. Wong 	case 0:
437c0b4e3abSDarrick J. Wong 		if (!(data->pin_cfg[0] & ADT7462_PIN7_INPUT))
438c0b4e3abSDarrick J. Wong 			return "+12V1";
439c0b4e3abSDarrick J. Wong 		break;
440c0b4e3abSDarrick J. Wong 	case 1:
441c0b4e3abSDarrick J. Wong 		switch (MASK_AND_SHIFT(data->pin_cfg[1], ADT7462_PIN23)) {
442c0b4e3abSDarrick J. Wong 		case 0:
443c0b4e3abSDarrick J. Wong 			return "Vccp1";
444c0b4e3abSDarrick J. Wong 		case 1:
445c0b4e3abSDarrick J. Wong 			return "+2.5V";
446c0b4e3abSDarrick J. Wong 		case 2:
447c0b4e3abSDarrick J. Wong 			return "+1.8V";
448c0b4e3abSDarrick J. Wong 		case 3:
449c0b4e3abSDarrick J. Wong 			return "+1.5V";
450c0b4e3abSDarrick J. Wong 		}
451c0b4e3abSDarrick J. Wong 	case 2:
452c0b4e3abSDarrick J. Wong 		if (!(data->pin_cfg[1] & ADT7462_PIN22_INPUT))
453c0b4e3abSDarrick J. Wong 			return "+12V3";
454c0b4e3abSDarrick J. Wong 		break;
455c0b4e3abSDarrick J. Wong 	case 3:
456c0b4e3abSDarrick J. Wong 		if (!(data->pin_cfg[1] & ADT7462_PIN21_INPUT))
457c0b4e3abSDarrick J. Wong 			return "+5V";
458c0b4e3abSDarrick J. Wong 		break;
459c0b4e3abSDarrick J. Wong 	case 4:
460c0b4e3abSDarrick J. Wong 		if (!(data->pin_cfg[0] & ADT7462_DIODE3_INPUT)) {
461c0b4e3abSDarrick J. Wong 			if (data->pin_cfg[1] & ADT7462_PIN19_INPUT)
462c0b4e3abSDarrick J. Wong 				return "+0.9V";
463c0b4e3abSDarrick J. Wong 			return "+1.25V";
464c0b4e3abSDarrick J. Wong 		}
465c0b4e3abSDarrick J. Wong 		break;
466c0b4e3abSDarrick J. Wong 	case 5:
467c0b4e3abSDarrick J. Wong 		if (!(data->pin_cfg[0] & ADT7462_DIODE1_INPUT)) {
468c0b4e3abSDarrick J. Wong 			if (data->pin_cfg[1] & ADT7462_PIN19_INPUT)
469c0b4e3abSDarrick J. Wong 				return "+1.8V";
470c0b4e3abSDarrick J. Wong 			return "+2.5V";
471c0b4e3abSDarrick J. Wong 		}
472c0b4e3abSDarrick J. Wong 		break;
473c0b4e3abSDarrick J. Wong 	case 6:
474c0b4e3abSDarrick J. Wong 		if (!(data->pin_cfg[1] & ADT7462_PIN13_INPUT))
475c0b4e3abSDarrick J. Wong 			return "+3.3V";
476c0b4e3abSDarrick J. Wong 		break;
477c0b4e3abSDarrick J. Wong 	case 7:
478c0b4e3abSDarrick J. Wong 		if (!(data->pin_cfg[1] & ADT7462_PIN8_INPUT))
479c0b4e3abSDarrick J. Wong 			return "+12V2";
480c0b4e3abSDarrick J. Wong 		break;
481c0b4e3abSDarrick J. Wong 	case 8:
482c0b4e3abSDarrick J. Wong 		switch (MASK_AND_SHIFT(data->pin_cfg[2], ADT7462_PIN26)) {
483c0b4e3abSDarrick J. Wong 		case 0:
484c0b4e3abSDarrick J. Wong 			return "Vbatt";
485c0b4e3abSDarrick J. Wong 		case 1:
486c0b4e3abSDarrick J. Wong 			return "FSB_Vtt";
487c0b4e3abSDarrick J. Wong 		}
488c0b4e3abSDarrick J. Wong 		break;
489c0b4e3abSDarrick J. Wong 	case 9:
490c0b4e3abSDarrick J. Wong 		switch (MASK_AND_SHIFT(data->pin_cfg[2], ADT7462_PIN25)) {
491c0b4e3abSDarrick J. Wong 		case 0:
492c0b4e3abSDarrick J. Wong 			return "+3.3V";
493c0b4e3abSDarrick J. Wong 		case 1:
494c0b4e3abSDarrick J. Wong 			return "+1.2V1";
495c0b4e3abSDarrick J. Wong 		}
496c0b4e3abSDarrick J. Wong 		break;
497c0b4e3abSDarrick J. Wong 	case 10:
498c0b4e3abSDarrick J. Wong 		switch (MASK_AND_SHIFT(data->pin_cfg[2], ADT7462_PIN24)) {
499c0b4e3abSDarrick J. Wong 		case 0:
500c0b4e3abSDarrick J. Wong 			return "Vccp2";
501c0b4e3abSDarrick J. Wong 		case 1:
502c0b4e3abSDarrick J. Wong 			return "+2.5V";
503c0b4e3abSDarrick J. Wong 		case 2:
504c0b4e3abSDarrick J. Wong 			return "+1.8V";
505c0b4e3abSDarrick J. Wong 		case 3:
506c0b4e3abSDarrick J. Wong 			return "+1.5";
507c0b4e3abSDarrick J. Wong 		}
508c0b4e3abSDarrick J. Wong 	case 11:
509c0b4e3abSDarrick J. Wong 		if (data->pin_cfg[3] >> ADT7462_PIN28_SHIFT ==
510c0b4e3abSDarrick J. Wong 					ADT7462_PIN28_VOLT &&
511c0b4e3abSDarrick J. Wong 		    !(data->pin_cfg[0] & ADT7462_VID_INPUT))
512c0b4e3abSDarrick J. Wong 			return "+1.5V ICH";
513c0b4e3abSDarrick J. Wong 		break;
514c0b4e3abSDarrick J. Wong 	case 12:
515c0b4e3abSDarrick J. Wong 		if (data->pin_cfg[3] >> ADT7462_PIN28_SHIFT ==
516c0b4e3abSDarrick J. Wong 					ADT7462_PIN28_VOLT &&
517c0b4e3abSDarrick J. Wong 		    !(data->pin_cfg[0] & ADT7462_VID_INPUT))
518c0b4e3abSDarrick J. Wong 			return "+1.5V 3GPIO";
519c0b4e3abSDarrick J. Wong 		break;
520c0b4e3abSDarrick J. Wong 	}
521c0b4e3abSDarrick J. Wong 	return "N/A";
522c0b4e3abSDarrick J. Wong }
523c0b4e3abSDarrick J. Wong 
524c0b4e3abSDarrick J. Wong /* Multipliers are actually in uV, not mV. */
525c0b4e3abSDarrick J. Wong static int voltage_multiplier(struct adt7462_data *data, int which)
526c0b4e3abSDarrick J. Wong {
527c0b4e3abSDarrick J. Wong 	switch (which) {
528c0b4e3abSDarrick J. Wong 	case 0:
529c0b4e3abSDarrick J. Wong 		if (!(data->pin_cfg[0] & ADT7462_PIN7_INPUT))
530c0b4e3abSDarrick J. Wong 			return 62500;
531c0b4e3abSDarrick J. Wong 		break;
532c0b4e3abSDarrick J. Wong 	case 1:
533c0b4e3abSDarrick J. Wong 		switch (MASK_AND_SHIFT(data->pin_cfg[1], ADT7462_PIN23)) {
534c0b4e3abSDarrick J. Wong 		case 0:
535c0b4e3abSDarrick J. Wong 			if (data->pin_cfg[0] & ADT7462_VID_INPUT)
536c0b4e3abSDarrick J. Wong 				return 12500;
537c0b4e3abSDarrick J. Wong 			return 6250;
538c0b4e3abSDarrick J. Wong 		case 1:
539c0b4e3abSDarrick J. Wong 			return 13000;
540c0b4e3abSDarrick J. Wong 		case 2:
541c0b4e3abSDarrick J. Wong 			return 9400;
542c0b4e3abSDarrick J. Wong 		case 3:
543c0b4e3abSDarrick J. Wong 			return 7800;
544c0b4e3abSDarrick J. Wong 		}
545c0b4e3abSDarrick J. Wong 	case 2:
546c0b4e3abSDarrick J. Wong 		if (!(data->pin_cfg[1] & ADT7462_PIN22_INPUT))
547c0b4e3abSDarrick J. Wong 			return 62500;
548c0b4e3abSDarrick J. Wong 		break;
549c0b4e3abSDarrick J. Wong 	case 3:
550c0b4e3abSDarrick J. Wong 		if (!(data->pin_cfg[1] & ADT7462_PIN21_INPUT))
551c0b4e3abSDarrick J. Wong 			return 26000;
552c0b4e3abSDarrick J. Wong 		break;
553c0b4e3abSDarrick J. Wong 	case 4:
554c0b4e3abSDarrick J. Wong 		if (!(data->pin_cfg[0] & ADT7462_DIODE3_INPUT)) {
555c0b4e3abSDarrick J. Wong 			if (data->pin_cfg[1] & ADT7462_PIN19_INPUT)
556c0b4e3abSDarrick J. Wong 				return 4690;
557c0b4e3abSDarrick J. Wong 			return 6500;
558c0b4e3abSDarrick J. Wong 		}
559c0b4e3abSDarrick J. Wong 		break;
560c0b4e3abSDarrick J. Wong 	case 5:
561c0b4e3abSDarrick J. Wong 		if (!(data->pin_cfg[0] & ADT7462_DIODE1_INPUT)) {
562c0b4e3abSDarrick J. Wong 			if (data->pin_cfg[1] & ADT7462_PIN15_INPUT)
563c0b4e3abSDarrick J. Wong 				return 9400;
564c0b4e3abSDarrick J. Wong 			return 13000;
565c0b4e3abSDarrick J. Wong 		}
566c0b4e3abSDarrick J. Wong 		break;
567c0b4e3abSDarrick J. Wong 	case 6:
568c0b4e3abSDarrick J. Wong 		if (!(data->pin_cfg[1] & ADT7462_PIN13_INPUT))
569c0b4e3abSDarrick J. Wong 			return 17200;
570c0b4e3abSDarrick J. Wong 		break;
571c0b4e3abSDarrick J. Wong 	case 7:
572c0b4e3abSDarrick J. Wong 		if (!(data->pin_cfg[1] & ADT7462_PIN8_INPUT))
573c0b4e3abSDarrick J. Wong 			return 62500;
574c0b4e3abSDarrick J. Wong 		break;
575c0b4e3abSDarrick J. Wong 	case 8:
576c0b4e3abSDarrick J. Wong 		switch (MASK_AND_SHIFT(data->pin_cfg[2], ADT7462_PIN26)) {
577c0b4e3abSDarrick J. Wong 		case 0:
578c0b4e3abSDarrick J. Wong 			return 15600;
579c0b4e3abSDarrick J. Wong 		case 1:
580c0b4e3abSDarrick J. Wong 			return 6250;
581c0b4e3abSDarrick J. Wong 		}
582c0b4e3abSDarrick J. Wong 		break;
583c0b4e3abSDarrick J. Wong 	case 9:
584c0b4e3abSDarrick J. Wong 		switch (MASK_AND_SHIFT(data->pin_cfg[2], ADT7462_PIN25)) {
585c0b4e3abSDarrick J. Wong 		case 0:
586c0b4e3abSDarrick J. Wong 			return 17200;
587c0b4e3abSDarrick J. Wong 		case 1:
588c0b4e3abSDarrick J. Wong 			return 6250;
589c0b4e3abSDarrick J. Wong 		}
590c0b4e3abSDarrick J. Wong 		break;
591c0b4e3abSDarrick J. Wong 	case 10:
592c0b4e3abSDarrick J. Wong 		switch (MASK_AND_SHIFT(data->pin_cfg[2], ADT7462_PIN24)) {
593c0b4e3abSDarrick J. Wong 		case 0:
594c0b4e3abSDarrick J. Wong 			return 6250;
595c0b4e3abSDarrick J. Wong 		case 1:
596c0b4e3abSDarrick J. Wong 			return 13000;
597c0b4e3abSDarrick J. Wong 		case 2:
598c0b4e3abSDarrick J. Wong 			return 9400;
599c0b4e3abSDarrick J. Wong 		case 3:
600c0b4e3abSDarrick J. Wong 			return 7800;
601c0b4e3abSDarrick J. Wong 		}
602c0b4e3abSDarrick J. Wong 	case 11:
603c0b4e3abSDarrick J. Wong 	case 12:
604c0b4e3abSDarrick J. Wong 		if (data->pin_cfg[3] >> ADT7462_PIN28_SHIFT ==
605c0b4e3abSDarrick J. Wong 					ADT7462_PIN28_VOLT &&
606c0b4e3abSDarrick J. Wong 		    !(data->pin_cfg[0] & ADT7462_VID_INPUT))
607c0b4e3abSDarrick J. Wong 			return 7800;
608c0b4e3abSDarrick J. Wong 	}
609c0b4e3abSDarrick J. Wong 	return 0;
610c0b4e3abSDarrick J. Wong }
611c0b4e3abSDarrick J. Wong 
612c0b4e3abSDarrick J. Wong static int temp_enabled(struct adt7462_data *data, int which)
613c0b4e3abSDarrick J. Wong {
614c0b4e3abSDarrick J. Wong 	switch (which) {
615c0b4e3abSDarrick J. Wong 	case 0:
616c0b4e3abSDarrick J. Wong 	case 2:
617c0b4e3abSDarrick J. Wong 		return 1;
618c0b4e3abSDarrick J. Wong 	case 1:
619c0b4e3abSDarrick J. Wong 		if (data->pin_cfg[0] & ADT7462_DIODE1_INPUT)
620c0b4e3abSDarrick J. Wong 			return 1;
621c0b4e3abSDarrick J. Wong 		break;
622c0b4e3abSDarrick J. Wong 	case 3:
623c0b4e3abSDarrick J. Wong 		if (data->pin_cfg[0] & ADT7462_DIODE3_INPUT)
624c0b4e3abSDarrick J. Wong 			return 1;
625c0b4e3abSDarrick J. Wong 		break;
626c0b4e3abSDarrick J. Wong 	}
627c0b4e3abSDarrick J. Wong 	return 0;
628c0b4e3abSDarrick J. Wong }
629c0b4e3abSDarrick J. Wong 
630c0b4e3abSDarrick J. Wong static const char *temp_label(struct adt7462_data *data, int which)
631c0b4e3abSDarrick J. Wong {
632c0b4e3abSDarrick J. Wong 	switch (which) {
633c0b4e3abSDarrick J. Wong 	case 0:
634c0b4e3abSDarrick J. Wong 		return "local";
635c0b4e3abSDarrick J. Wong 	case 1:
636c0b4e3abSDarrick J. Wong 		if (data->pin_cfg[0] & ADT7462_DIODE1_INPUT)
637c0b4e3abSDarrick J. Wong 			return "remote1";
638c0b4e3abSDarrick J. Wong 		break;
639c0b4e3abSDarrick J. Wong 	case 2:
640c0b4e3abSDarrick J. Wong 		return "remote2";
641c0b4e3abSDarrick J. Wong 	case 3:
642c0b4e3abSDarrick J. Wong 		if (data->pin_cfg[0] & ADT7462_DIODE3_INPUT)
643c0b4e3abSDarrick J. Wong 			return "remote3";
644c0b4e3abSDarrick J. Wong 		break;
645c0b4e3abSDarrick J. Wong 	}
646c0b4e3abSDarrick J. Wong 	return "N/A";
647c0b4e3abSDarrick J. Wong }
648c0b4e3abSDarrick J. Wong 
649c0b4e3abSDarrick J. Wong /* Map Trange register values to mC */
650c0b4e3abSDarrick J. Wong #define NUM_TRANGE_VALUES	16
651c0b4e3abSDarrick J. Wong static const int trange_values[NUM_TRANGE_VALUES] = {
652c0b4e3abSDarrick J. Wong 	2000,
653c0b4e3abSDarrick J. Wong 	2500,
654c0b4e3abSDarrick J. Wong 	3300,
655c0b4e3abSDarrick J. Wong 	4000,
656c0b4e3abSDarrick J. Wong 	5000,
657c0b4e3abSDarrick J. Wong 	6700,
658c0b4e3abSDarrick J. Wong 	8000,
659c0b4e3abSDarrick J. Wong 	10000,
660c0b4e3abSDarrick J. Wong 	13300,
661c0b4e3abSDarrick J. Wong 	16000,
662c0b4e3abSDarrick J. Wong 	20000,
663c0b4e3abSDarrick J. Wong 	26700,
664c0b4e3abSDarrick J. Wong 	32000,
665c0b4e3abSDarrick J. Wong 	40000,
666c0b4e3abSDarrick J. Wong 	53300,
667c0b4e3abSDarrick J. Wong 	80000
668c0b4e3abSDarrick J. Wong };
669c0b4e3abSDarrick J. Wong 
670c0b4e3abSDarrick J. Wong static int find_trange_value(int trange)
671c0b4e3abSDarrick J. Wong {
672c0b4e3abSDarrick J. Wong 	int i;
673c0b4e3abSDarrick J. Wong 
674c0b4e3abSDarrick J. Wong 	for (i = 0; i < NUM_TRANGE_VALUES; i++)
675c0b4e3abSDarrick J. Wong 		if (trange_values[i] == trange)
676c0b4e3abSDarrick J. Wong 			return i;
677c0b4e3abSDarrick J. Wong 
678bb34c0daSGuenter Roeck 	return -EINVAL;
679c0b4e3abSDarrick J. Wong }
680c0b4e3abSDarrick J. Wong 
681c0b4e3abSDarrick J. Wong static struct adt7462_data *adt7462_update_device(struct device *dev)
682c0b4e3abSDarrick J. Wong {
683573bfe67SAxel Lin 	struct adt7462_data *data = dev_get_drvdata(dev);
684573bfe67SAxel Lin 	struct i2c_client *client = data->client;
685c0b4e3abSDarrick J. Wong 	unsigned long local_jiffies = jiffies;
686c0b4e3abSDarrick J. Wong 	int i;
687c0b4e3abSDarrick J. Wong 
688c0b4e3abSDarrick J. Wong 	mutex_lock(&data->lock);
689c0b4e3abSDarrick J. Wong 	if (time_before(local_jiffies, data->sensors_last_updated +
690c0b4e3abSDarrick J. Wong 		SENSOR_REFRESH_INTERVAL)
691c0b4e3abSDarrick J. Wong 		&& data->sensors_valid)
692c0b4e3abSDarrick J. Wong 		goto no_sensor_update;
693c0b4e3abSDarrick J. Wong 
694c0b4e3abSDarrick J. Wong 	for (i = 0; i < ADT7462_TEMP_COUNT; i++) {
695c0b4e3abSDarrick J. Wong 		/*
696c0b4e3abSDarrick J. Wong 		 * Reading the fractional register locks the integral
697c0b4e3abSDarrick J. Wong 		 * register until both have been read.
698c0b4e3abSDarrick J. Wong 		 */
699c0b4e3abSDarrick J. Wong 		data->temp_frac[i] = i2c_smbus_read_byte_data(client,
700c0b4e3abSDarrick J. Wong 						ADT7462_TEMP_REG(i));
701c0b4e3abSDarrick J. Wong 		data->temp[i] = i2c_smbus_read_byte_data(client,
702c0b4e3abSDarrick J. Wong 						ADT7462_TEMP_REG(i) + 1);
703c0b4e3abSDarrick J. Wong 	}
704c0b4e3abSDarrick J. Wong 
705c0b4e3abSDarrick J. Wong 	for (i = 0; i < ADT7462_FAN_COUNT; i++)
706c0b4e3abSDarrick J. Wong 		data->fan[i] = adt7462_read_word_data(client,
707c0b4e3abSDarrick J. Wong 						ADT7462_REG_FAN(i));
708c0b4e3abSDarrick J. Wong 
709c0b4e3abSDarrick J. Wong 	data->fan_enabled = i2c_smbus_read_byte_data(client,
710c0b4e3abSDarrick J. Wong 					ADT7462_REG_FAN_ENABLE);
711c0b4e3abSDarrick J. Wong 
712c0b4e3abSDarrick J. Wong 	for (i = 0; i < ADT7462_PWM_COUNT; i++)
713c0b4e3abSDarrick J. Wong 		data->pwm[i] = i2c_smbus_read_byte_data(client,
714c0b4e3abSDarrick J. Wong 						ADT7462_REG_PWM(i));
715c0b4e3abSDarrick J. Wong 
716c0b4e3abSDarrick J. Wong 	for (i = 0; i < ADT7462_PIN_CFG_REG_COUNT; i++)
717c0b4e3abSDarrick J. Wong 		data->pin_cfg[i] = i2c_smbus_read_byte_data(client,
718c0b4e3abSDarrick J. Wong 				ADT7462_REG_PIN_CFG(i));
719c0b4e3abSDarrick J. Wong 
720c0b4e3abSDarrick J. Wong 	for (i = 0; i < ADT7462_VOLT_COUNT; i++) {
721c0b4e3abSDarrick J. Wong 		int reg = ADT7462_REG_VOLT(data, i);
722c0b4e3abSDarrick J. Wong 		if (!reg)
723c0b4e3abSDarrick J. Wong 			data->voltages[i] = 0;
724c0b4e3abSDarrick J. Wong 		else
725c0b4e3abSDarrick J. Wong 			data->voltages[i] = i2c_smbus_read_byte_data(client,
726c0b4e3abSDarrick J. Wong 								     reg);
727c0b4e3abSDarrick J. Wong 	}
728c0b4e3abSDarrick J. Wong 
729c0b4e3abSDarrick J. Wong 	data->alarms[0] = i2c_smbus_read_byte_data(client, ADT7462_REG_ALARM1);
730c0b4e3abSDarrick J. Wong 	data->alarms[1] = i2c_smbus_read_byte_data(client, ADT7462_REG_ALARM2);
731c0b4e3abSDarrick J. Wong 	data->alarms[2] = i2c_smbus_read_byte_data(client, ADT7462_REG_ALARM3);
732c0b4e3abSDarrick J. Wong 	data->alarms[3] = i2c_smbus_read_byte_data(client, ADT7462_REG_ALARM4);
733c0b4e3abSDarrick J. Wong 
734c0b4e3abSDarrick J. Wong 	data->sensors_last_updated = local_jiffies;
735c0b4e3abSDarrick J. Wong 	data->sensors_valid = 1;
736c0b4e3abSDarrick J. Wong 
737c0b4e3abSDarrick J. Wong no_sensor_update:
738c0b4e3abSDarrick J. Wong 	if (time_before(local_jiffies, data->limits_last_updated +
739c0b4e3abSDarrick J. Wong 		LIMIT_REFRESH_INTERVAL)
740c0b4e3abSDarrick J. Wong 		&& data->limits_valid)
741c0b4e3abSDarrick J. Wong 		goto out;
742c0b4e3abSDarrick J. Wong 
743c0b4e3abSDarrick J. Wong 	for (i = 0; i < ADT7462_TEMP_COUNT; i++) {
744c0b4e3abSDarrick J. Wong 		data->temp_min[i] = i2c_smbus_read_byte_data(client,
745c0b4e3abSDarrick J. Wong 						ADT7462_TEMP_MIN_REG(i));
746c0b4e3abSDarrick J. Wong 		data->temp_max[i] = i2c_smbus_read_byte_data(client,
747c0b4e3abSDarrick J. Wong 						ADT7462_TEMP_MAX_REG(i));
748c0b4e3abSDarrick J. Wong 	}
749c0b4e3abSDarrick J. Wong 
750c0b4e3abSDarrick J. Wong 	for (i = 0; i < ADT7462_FAN_COUNT; i++)
751c0b4e3abSDarrick J. Wong 		data->fan_min[i] = i2c_smbus_read_byte_data(client,
752c0b4e3abSDarrick J. Wong 						ADT7462_REG_FAN_MIN(i));
753c0b4e3abSDarrick J. Wong 
754c0b4e3abSDarrick J. Wong 	for (i = 0; i < ADT7462_VOLT_COUNT; i++) {
755c0b4e3abSDarrick J. Wong 		int reg = ADT7462_REG_VOLT_MAX(data, i);
756c0b4e3abSDarrick J. Wong 		data->volt_max[i] =
757c0b4e3abSDarrick J. Wong 			(reg ? i2c_smbus_read_byte_data(client, reg) : 0);
758c0b4e3abSDarrick J. Wong 
759c0b4e3abSDarrick J. Wong 		reg = ADT7462_REG_VOLT_MIN(data, i);
760c0b4e3abSDarrick J. Wong 		data->volt_min[i] =
761c0b4e3abSDarrick J. Wong 			(reg ? i2c_smbus_read_byte_data(client, reg) : 0);
762c0b4e3abSDarrick J. Wong 	}
763c0b4e3abSDarrick J. Wong 
764c0b4e3abSDarrick J. Wong 	for (i = 0; i < ADT7462_PWM_COUNT; i++) {
765c0b4e3abSDarrick J. Wong 		data->pwm_min[i] = i2c_smbus_read_byte_data(client,
766c0b4e3abSDarrick J. Wong 						ADT7462_REG_PWM_MIN(i));
767c0b4e3abSDarrick J. Wong 		data->pwm_tmin[i] = i2c_smbus_read_byte_data(client,
768c0b4e3abSDarrick J. Wong 						ADT7462_REG_PWM_TMIN(i));
769c0b4e3abSDarrick J. Wong 		data->pwm_trange[i] = i2c_smbus_read_byte_data(client,
770c0b4e3abSDarrick J. Wong 						ADT7462_REG_PWM_TRANGE(i));
771c0b4e3abSDarrick J. Wong 		data->pwm_cfg[i] = i2c_smbus_read_byte_data(client,
772c0b4e3abSDarrick J. Wong 						ADT7462_REG_PWM_CFG(i));
773c0b4e3abSDarrick J. Wong 	}
774c0b4e3abSDarrick J. Wong 
775c0b4e3abSDarrick J. Wong 	data->pwm_max = i2c_smbus_read_byte_data(client, ADT7462_REG_PWM_MAX);
776c0b4e3abSDarrick J. Wong 
777c0b4e3abSDarrick J. Wong 	data->cfg2 = i2c_smbus_read_byte_data(client, ADT7462_REG_CFG2);
778c0b4e3abSDarrick J. Wong 
779c0b4e3abSDarrick J. Wong 	data->limits_last_updated = local_jiffies;
780c0b4e3abSDarrick J. Wong 	data->limits_valid = 1;
781c0b4e3abSDarrick J. Wong 
782c0b4e3abSDarrick J. Wong out:
783c0b4e3abSDarrick J. Wong 	mutex_unlock(&data->lock);
784c0b4e3abSDarrick J. Wong 	return data;
785c0b4e3abSDarrick J. Wong }
786c0b4e3abSDarrick J. Wong 
787c0b4e3abSDarrick J. Wong static ssize_t show_temp_min(struct device *dev,
788c0b4e3abSDarrick J. Wong 			     struct device_attribute *devattr,
789c0b4e3abSDarrick J. Wong 			     char *buf)
790c0b4e3abSDarrick J. Wong {
791c0b4e3abSDarrick J. Wong 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
792c0b4e3abSDarrick J. Wong 	struct adt7462_data *data = adt7462_update_device(dev);
793c0b4e3abSDarrick J. Wong 
794c0b4e3abSDarrick J. Wong 	if (!temp_enabled(data, attr->index))
795c0b4e3abSDarrick J. Wong 		return sprintf(buf, "0\n");
796c0b4e3abSDarrick J. Wong 
797c0b4e3abSDarrick J. Wong 	return sprintf(buf, "%d\n", 1000 * (data->temp_min[attr->index] - 64));
798c0b4e3abSDarrick J. Wong }
799c0b4e3abSDarrick J. Wong 
800c0b4e3abSDarrick J. Wong static ssize_t set_temp_min(struct device *dev,
801c0b4e3abSDarrick J. Wong 			    struct device_attribute *devattr,
802c0b4e3abSDarrick J. Wong 			    const char *buf,
803c0b4e3abSDarrick J. Wong 			    size_t count)
804c0b4e3abSDarrick J. Wong {
805c0b4e3abSDarrick J. Wong 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
806573bfe67SAxel Lin 	struct adt7462_data *data = dev_get_drvdata(dev);
807573bfe67SAxel Lin 	struct i2c_client *client = data->client;
808c0b4e3abSDarrick J. Wong 	long temp;
809c0b4e3abSDarrick J. Wong 
810179c4fdbSFrans Meulenbroeks 	if (kstrtol(buf, 10, &temp) || !temp_enabled(data, attr->index))
811c0b4e3abSDarrick J. Wong 		return -EINVAL;
812c0b4e3abSDarrick J. Wong 
813*b94793b4SGuenter Roeck 	temp = clamp_val(temp, -64000, 191000);
8148f8c1fb0SDarrick J. Wong 	temp = DIV_ROUND_CLOSEST(temp, 1000) + 64;
815c0b4e3abSDarrick J. Wong 
816c0b4e3abSDarrick J. Wong 	mutex_lock(&data->lock);
817c0b4e3abSDarrick J. Wong 	data->temp_min[attr->index] = temp;
818c0b4e3abSDarrick J. Wong 	i2c_smbus_write_byte_data(client, ADT7462_TEMP_MIN_REG(attr->index),
819c0b4e3abSDarrick J. Wong 				  temp);
820c0b4e3abSDarrick J. Wong 	mutex_unlock(&data->lock);
821c0b4e3abSDarrick J. Wong 
822c0b4e3abSDarrick J. Wong 	return count;
823c0b4e3abSDarrick J. Wong }
824c0b4e3abSDarrick J. Wong 
825c0b4e3abSDarrick J. Wong static ssize_t show_temp_max(struct device *dev,
826c0b4e3abSDarrick J. Wong 			     struct device_attribute *devattr,
827c0b4e3abSDarrick J. Wong 			     char *buf)
828c0b4e3abSDarrick J. Wong {
829c0b4e3abSDarrick J. Wong 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
830c0b4e3abSDarrick J. Wong 	struct adt7462_data *data = adt7462_update_device(dev);
831c0b4e3abSDarrick J. Wong 
832c0b4e3abSDarrick J. Wong 	if (!temp_enabled(data, attr->index))
833c0b4e3abSDarrick J. Wong 		return sprintf(buf, "0\n");
834c0b4e3abSDarrick J. Wong 
835c0b4e3abSDarrick J. Wong 	return sprintf(buf, "%d\n", 1000 * (data->temp_max[attr->index] - 64));
836c0b4e3abSDarrick J. Wong }
837c0b4e3abSDarrick J. Wong 
838c0b4e3abSDarrick J. Wong static ssize_t set_temp_max(struct device *dev,
839c0b4e3abSDarrick J. Wong 			    struct device_attribute *devattr,
840c0b4e3abSDarrick J. Wong 			    const char *buf,
841c0b4e3abSDarrick J. Wong 			    size_t count)
842c0b4e3abSDarrick J. Wong {
843c0b4e3abSDarrick J. Wong 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
844573bfe67SAxel Lin 	struct adt7462_data *data = dev_get_drvdata(dev);
845573bfe67SAxel Lin 	struct i2c_client *client = data->client;
846c0b4e3abSDarrick J. Wong 	long temp;
847c0b4e3abSDarrick J. Wong 
848179c4fdbSFrans Meulenbroeks 	if (kstrtol(buf, 10, &temp) || !temp_enabled(data, attr->index))
849c0b4e3abSDarrick J. Wong 		return -EINVAL;
850c0b4e3abSDarrick J. Wong 
851*b94793b4SGuenter Roeck 	temp = clamp_val(temp, -64000, 191000);
8528f8c1fb0SDarrick J. Wong 	temp = DIV_ROUND_CLOSEST(temp, 1000) + 64;
853c0b4e3abSDarrick J. Wong 
854c0b4e3abSDarrick J. Wong 	mutex_lock(&data->lock);
855c0b4e3abSDarrick J. Wong 	data->temp_max[attr->index] = temp;
856c0b4e3abSDarrick J. Wong 	i2c_smbus_write_byte_data(client, ADT7462_TEMP_MAX_REG(attr->index),
857c0b4e3abSDarrick J. Wong 				  temp);
858c0b4e3abSDarrick J. Wong 	mutex_unlock(&data->lock);
859c0b4e3abSDarrick J. Wong 
860c0b4e3abSDarrick J. Wong 	return count;
861c0b4e3abSDarrick J. Wong }
862c0b4e3abSDarrick J. Wong 
863c0b4e3abSDarrick J. Wong static ssize_t show_temp(struct device *dev, struct device_attribute *devattr,
864c0b4e3abSDarrick J. Wong 			 char *buf)
865c0b4e3abSDarrick J. Wong {
866c0b4e3abSDarrick J. Wong 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
867c0b4e3abSDarrick J. Wong 	struct adt7462_data *data = adt7462_update_device(dev);
868c0b4e3abSDarrick J. Wong 	u8 frac = data->temp_frac[attr->index] >> TEMP_FRAC_OFFSET;
869c0b4e3abSDarrick J. Wong 
870c0b4e3abSDarrick J. Wong 	if (!temp_enabled(data, attr->index))
871c0b4e3abSDarrick J. Wong 		return sprintf(buf, "0\n");
872c0b4e3abSDarrick J. Wong 
873c0b4e3abSDarrick J. Wong 	return sprintf(buf, "%d\n", 1000 * (data->temp[attr->index] - 64) +
874c0b4e3abSDarrick J. Wong 				     250 * frac);
875c0b4e3abSDarrick J. Wong }
876c0b4e3abSDarrick J. Wong 
877c0b4e3abSDarrick J. Wong static ssize_t show_temp_label(struct device *dev,
878c0b4e3abSDarrick J. Wong 			       struct device_attribute *devattr,
879c0b4e3abSDarrick J. Wong 			       char *buf)
880c0b4e3abSDarrick J. Wong {
881c0b4e3abSDarrick J. Wong 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
882c0b4e3abSDarrick J. Wong 	struct adt7462_data *data = adt7462_update_device(dev);
883c0b4e3abSDarrick J. Wong 
884c0b4e3abSDarrick J. Wong 	return sprintf(buf, "%s\n", temp_label(data, attr->index));
885c0b4e3abSDarrick J. Wong }
886c0b4e3abSDarrick J. Wong 
887c0b4e3abSDarrick J. Wong static ssize_t show_volt_max(struct device *dev,
888c0b4e3abSDarrick J. Wong 			     struct device_attribute *devattr,
889c0b4e3abSDarrick J. Wong 			     char *buf)
890c0b4e3abSDarrick J. Wong {
891c0b4e3abSDarrick J. Wong 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
892c0b4e3abSDarrick J. Wong 	struct adt7462_data *data = adt7462_update_device(dev);
893c0b4e3abSDarrick J. Wong 	int x = voltage_multiplier(data, attr->index);
894c0b4e3abSDarrick J. Wong 
895c0b4e3abSDarrick J. Wong 	x *= data->volt_max[attr->index];
896c0b4e3abSDarrick J. Wong 	x /= 1000; /* convert from uV to mV */
897c0b4e3abSDarrick J. Wong 
898c0b4e3abSDarrick J. Wong 	return sprintf(buf, "%d\n", x);
899c0b4e3abSDarrick J. Wong }
900c0b4e3abSDarrick J. Wong 
901c0b4e3abSDarrick J. Wong static ssize_t set_volt_max(struct device *dev,
902c0b4e3abSDarrick J. Wong 			    struct device_attribute *devattr,
903c0b4e3abSDarrick J. Wong 			    const char *buf,
904c0b4e3abSDarrick J. Wong 			    size_t count)
905c0b4e3abSDarrick J. Wong {
906c0b4e3abSDarrick J. Wong 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
907573bfe67SAxel Lin 	struct adt7462_data *data = dev_get_drvdata(dev);
908573bfe67SAxel Lin 	struct i2c_client *client = data->client;
909c0b4e3abSDarrick J. Wong 	int x = voltage_multiplier(data, attr->index);
910c0b4e3abSDarrick J. Wong 	long temp;
911c0b4e3abSDarrick J. Wong 
912179c4fdbSFrans Meulenbroeks 	if (kstrtol(buf, 10, &temp) || !x)
913c0b4e3abSDarrick J. Wong 		return -EINVAL;
914c0b4e3abSDarrick J. Wong 
915*b94793b4SGuenter Roeck 	temp = clamp_val(temp, 0, 255 * x / 1000);
916c0b4e3abSDarrick J. Wong 	temp *= 1000; /* convert mV to uV */
9178f8c1fb0SDarrick J. Wong 	temp = DIV_ROUND_CLOSEST(temp, x);
918c0b4e3abSDarrick J. Wong 
919c0b4e3abSDarrick J. Wong 	mutex_lock(&data->lock);
920c0b4e3abSDarrick J. Wong 	data->volt_max[attr->index] = temp;
921c0b4e3abSDarrick J. Wong 	i2c_smbus_write_byte_data(client,
922c0b4e3abSDarrick J. Wong 				  ADT7462_REG_VOLT_MAX(data, attr->index),
923c0b4e3abSDarrick J. Wong 				  temp);
924c0b4e3abSDarrick J. Wong 	mutex_unlock(&data->lock);
925c0b4e3abSDarrick J. Wong 
926c0b4e3abSDarrick J. Wong 	return count;
927c0b4e3abSDarrick J. Wong }
928c0b4e3abSDarrick J. Wong 
929c0b4e3abSDarrick J. Wong static ssize_t show_volt_min(struct device *dev,
930c0b4e3abSDarrick J. Wong 			     struct device_attribute *devattr,
931c0b4e3abSDarrick J. Wong 			     char *buf)
932c0b4e3abSDarrick J. Wong {
933c0b4e3abSDarrick J. Wong 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
934c0b4e3abSDarrick J. Wong 	struct adt7462_data *data = adt7462_update_device(dev);
935c0b4e3abSDarrick J. Wong 	int x = voltage_multiplier(data, attr->index);
936c0b4e3abSDarrick J. Wong 
937c0b4e3abSDarrick J. Wong 	x *= data->volt_min[attr->index];
938c0b4e3abSDarrick J. Wong 	x /= 1000; /* convert from uV to mV */
939c0b4e3abSDarrick J. Wong 
940c0b4e3abSDarrick J. Wong 	return sprintf(buf, "%d\n", x);
941c0b4e3abSDarrick J. Wong }
942c0b4e3abSDarrick J. Wong 
943c0b4e3abSDarrick J. Wong static ssize_t set_volt_min(struct device *dev,
944c0b4e3abSDarrick J. Wong 			    struct device_attribute *devattr,
945c0b4e3abSDarrick J. Wong 			    const char *buf,
946c0b4e3abSDarrick J. Wong 			    size_t count)
947c0b4e3abSDarrick J. Wong {
948c0b4e3abSDarrick J. Wong 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
949573bfe67SAxel Lin 	struct adt7462_data *data = dev_get_drvdata(dev);
950573bfe67SAxel Lin 	struct i2c_client *client = data->client;
951c0b4e3abSDarrick J. Wong 	int x = voltage_multiplier(data, attr->index);
952c0b4e3abSDarrick J. Wong 	long temp;
953c0b4e3abSDarrick J. Wong 
954179c4fdbSFrans Meulenbroeks 	if (kstrtol(buf, 10, &temp) || !x)
955c0b4e3abSDarrick J. Wong 		return -EINVAL;
956c0b4e3abSDarrick J. Wong 
957*b94793b4SGuenter Roeck 	temp = clamp_val(temp, 0, 255 * x / 1000);
958c0b4e3abSDarrick J. Wong 	temp *= 1000; /* convert mV to uV */
9598f8c1fb0SDarrick J. Wong 	temp = DIV_ROUND_CLOSEST(temp, x);
960c0b4e3abSDarrick J. Wong 
961c0b4e3abSDarrick J. Wong 	mutex_lock(&data->lock);
962c0b4e3abSDarrick J. Wong 	data->volt_min[attr->index] = temp;
963c0b4e3abSDarrick J. Wong 	i2c_smbus_write_byte_data(client,
964c0b4e3abSDarrick J. Wong 				  ADT7462_REG_VOLT_MIN(data, attr->index),
965c0b4e3abSDarrick J. Wong 				  temp);
966c0b4e3abSDarrick J. Wong 	mutex_unlock(&data->lock);
967c0b4e3abSDarrick J. Wong 
968c0b4e3abSDarrick J. Wong 	return count;
969c0b4e3abSDarrick J. Wong }
970c0b4e3abSDarrick J. Wong 
971c0b4e3abSDarrick J. Wong static ssize_t show_voltage(struct device *dev,
972c0b4e3abSDarrick J. Wong 			    struct device_attribute *devattr,
973c0b4e3abSDarrick J. Wong 			    char *buf)
974c0b4e3abSDarrick J. Wong {
975c0b4e3abSDarrick J. Wong 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
976c0b4e3abSDarrick J. Wong 	struct adt7462_data *data = adt7462_update_device(dev);
977c0b4e3abSDarrick J. Wong 	int x = voltage_multiplier(data, attr->index);
978c0b4e3abSDarrick J. Wong 
979c0b4e3abSDarrick J. Wong 	x *= data->voltages[attr->index];
980c0b4e3abSDarrick J. Wong 	x /= 1000; /* convert from uV to mV */
981c0b4e3abSDarrick J. Wong 
982c0b4e3abSDarrick J. Wong 	return sprintf(buf, "%d\n", x);
983c0b4e3abSDarrick J. Wong }
984c0b4e3abSDarrick J. Wong 
985c0b4e3abSDarrick J. Wong static ssize_t show_voltage_label(struct device *dev,
986c0b4e3abSDarrick J. Wong 				  struct device_attribute *devattr,
987c0b4e3abSDarrick J. Wong 				  char *buf)
988c0b4e3abSDarrick J. Wong {
989c0b4e3abSDarrick J. Wong 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
990c0b4e3abSDarrick J. Wong 	struct adt7462_data *data = adt7462_update_device(dev);
991c0b4e3abSDarrick J. Wong 
992c0b4e3abSDarrick J. Wong 	return sprintf(buf, "%s\n", voltage_label(data, attr->index));
993c0b4e3abSDarrick J. Wong }
994c0b4e3abSDarrick J. Wong 
995c0b4e3abSDarrick J. Wong static ssize_t show_alarm(struct device *dev,
996c0b4e3abSDarrick J. Wong 			  struct device_attribute *devattr,
997c0b4e3abSDarrick J. Wong 			  char *buf)
998c0b4e3abSDarrick J. Wong {
999c0b4e3abSDarrick J. Wong 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
1000c0b4e3abSDarrick J. Wong 	struct adt7462_data *data = adt7462_update_device(dev);
1001c0b4e3abSDarrick J. Wong 	int reg = attr->index >> ADT7462_ALARM_REG_SHIFT;
1002c0b4e3abSDarrick J. Wong 	int mask = attr->index & ADT7462_ALARM_FLAG_MASK;
1003c0b4e3abSDarrick J. Wong 
1004c0b4e3abSDarrick J. Wong 	if (data->alarms[reg] & mask)
1005c0b4e3abSDarrick J. Wong 		return sprintf(buf, "1\n");
1006c0b4e3abSDarrick J. Wong 	else
1007c0b4e3abSDarrick J. Wong 		return sprintf(buf, "0\n");
1008c0b4e3abSDarrick J. Wong }
1009c0b4e3abSDarrick J. Wong 
1010c0b4e3abSDarrick J. Wong static int fan_enabled(struct adt7462_data *data, int fan)
1011c0b4e3abSDarrick J. Wong {
1012c0b4e3abSDarrick J. Wong 	return data->fan_enabled & (1 << fan);
1013c0b4e3abSDarrick J. Wong }
1014c0b4e3abSDarrick J. Wong 
1015c0b4e3abSDarrick J. Wong static ssize_t show_fan_min(struct device *dev,
1016c0b4e3abSDarrick J. Wong 			    struct device_attribute *devattr,
1017c0b4e3abSDarrick J. Wong 			    char *buf)
1018c0b4e3abSDarrick J. Wong {
1019c0b4e3abSDarrick J. Wong 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
1020c0b4e3abSDarrick J. Wong 	struct adt7462_data *data = adt7462_update_device(dev);
1021c0b4e3abSDarrick J. Wong 	u16 temp;
1022c0b4e3abSDarrick J. Wong 
1023c0b4e3abSDarrick J. Wong 	/* Only the MSB of the min fan period is stored... */
1024c0b4e3abSDarrick J. Wong 	temp = data->fan_min[attr->index];
1025c0b4e3abSDarrick J. Wong 	temp <<= 8;
1026c0b4e3abSDarrick J. Wong 
1027c0b4e3abSDarrick J. Wong 	if (!fan_enabled(data, attr->index) ||
1028c0b4e3abSDarrick J. Wong 	    !FAN_DATA_VALID(temp))
1029c0b4e3abSDarrick J. Wong 		return sprintf(buf, "0\n");
1030c0b4e3abSDarrick J. Wong 
1031c0b4e3abSDarrick J. Wong 	return sprintf(buf, "%d\n", FAN_PERIOD_TO_RPM(temp));
1032c0b4e3abSDarrick J. Wong }
1033c0b4e3abSDarrick J. Wong 
1034c0b4e3abSDarrick J. Wong static ssize_t set_fan_min(struct device *dev,
1035c0b4e3abSDarrick J. Wong 			   struct device_attribute *devattr,
1036c0b4e3abSDarrick J. Wong 			   const char *buf, size_t count)
1037c0b4e3abSDarrick J. Wong {
1038c0b4e3abSDarrick J. Wong 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
1039573bfe67SAxel Lin 	struct adt7462_data *data = dev_get_drvdata(dev);
1040573bfe67SAxel Lin 	struct i2c_client *client = data->client;
1041c0b4e3abSDarrick J. Wong 	long temp;
1042c0b4e3abSDarrick J. Wong 
1043179c4fdbSFrans Meulenbroeks 	if (kstrtol(buf, 10, &temp) || !temp ||
1044c0b4e3abSDarrick J. Wong 	    !fan_enabled(data, attr->index))
1045c0b4e3abSDarrick J. Wong 		return -EINVAL;
1046c0b4e3abSDarrick J. Wong 
1047c0b4e3abSDarrick J. Wong 	temp = FAN_RPM_TO_PERIOD(temp);
1048c0b4e3abSDarrick J. Wong 	temp >>= 8;
10492a844c14SGuenter Roeck 	temp = clamp_val(temp, 1, 255);
1050c0b4e3abSDarrick J. Wong 
1051c0b4e3abSDarrick J. Wong 	mutex_lock(&data->lock);
1052c0b4e3abSDarrick J. Wong 	data->fan_min[attr->index] = temp;
1053c0b4e3abSDarrick J. Wong 	i2c_smbus_write_byte_data(client, ADT7462_REG_FAN_MIN(attr->index),
1054c0b4e3abSDarrick J. Wong 				  temp);
1055c0b4e3abSDarrick J. Wong 	mutex_unlock(&data->lock);
1056c0b4e3abSDarrick J. Wong 
1057c0b4e3abSDarrick J. Wong 	return count;
1058c0b4e3abSDarrick J. Wong }
1059c0b4e3abSDarrick J. Wong 
1060c0b4e3abSDarrick J. Wong static ssize_t show_fan(struct device *dev, struct device_attribute *devattr,
1061c0b4e3abSDarrick J. Wong 			char *buf)
1062c0b4e3abSDarrick J. Wong {
1063c0b4e3abSDarrick J. Wong 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
1064c0b4e3abSDarrick J. Wong 	struct adt7462_data *data = adt7462_update_device(dev);
1065c0b4e3abSDarrick J. Wong 
1066c0b4e3abSDarrick J. Wong 	if (!fan_enabled(data, attr->index) ||
1067c0b4e3abSDarrick J. Wong 	    !FAN_DATA_VALID(data->fan[attr->index]))
1068c0b4e3abSDarrick J. Wong 		return sprintf(buf, "0\n");
1069c0b4e3abSDarrick J. Wong 
1070c0b4e3abSDarrick J. Wong 	return sprintf(buf, "%d\n",
1071c0b4e3abSDarrick J. Wong 		       FAN_PERIOD_TO_RPM(data->fan[attr->index]));
1072c0b4e3abSDarrick J. Wong }
1073c0b4e3abSDarrick J. Wong 
1074c0b4e3abSDarrick J. Wong static ssize_t show_force_pwm_max(struct device *dev,
1075c0b4e3abSDarrick J. Wong 				  struct device_attribute *devattr,
1076c0b4e3abSDarrick J. Wong 				  char *buf)
1077c0b4e3abSDarrick J. Wong {
1078c0b4e3abSDarrick J. Wong 	struct adt7462_data *data = adt7462_update_device(dev);
1079c0b4e3abSDarrick J. Wong 	return sprintf(buf, "%d\n", (data->cfg2 & ADT7462_FSPD_MASK ? 1 : 0));
1080c0b4e3abSDarrick J. Wong }
1081c0b4e3abSDarrick J. Wong 
1082c0b4e3abSDarrick J. Wong static ssize_t set_force_pwm_max(struct device *dev,
1083c0b4e3abSDarrick J. Wong 				 struct device_attribute *devattr,
1084c0b4e3abSDarrick J. Wong 				 const char *buf,
1085c0b4e3abSDarrick J. Wong 				 size_t count)
1086c0b4e3abSDarrick J. Wong {
1087573bfe67SAxel Lin 	struct adt7462_data *data = dev_get_drvdata(dev);
1088573bfe67SAxel Lin 	struct i2c_client *client = data->client;
1089c0b4e3abSDarrick J. Wong 	long temp;
1090c0b4e3abSDarrick J. Wong 	u8 reg;
1091c0b4e3abSDarrick J. Wong 
1092179c4fdbSFrans Meulenbroeks 	if (kstrtol(buf, 10, &temp))
1093c0b4e3abSDarrick J. Wong 		return -EINVAL;
1094c0b4e3abSDarrick J. Wong 
1095c0b4e3abSDarrick J. Wong 	mutex_lock(&data->lock);
1096c0b4e3abSDarrick J. Wong 	reg = i2c_smbus_read_byte_data(client, ADT7462_REG_CFG2);
1097c0b4e3abSDarrick J. Wong 	if (temp)
1098c0b4e3abSDarrick J. Wong 		reg |= ADT7462_FSPD_MASK;
1099c0b4e3abSDarrick J. Wong 	else
1100c0b4e3abSDarrick J. Wong 		reg &= ~ADT7462_FSPD_MASK;
1101c0b4e3abSDarrick J. Wong 	data->cfg2 = reg;
1102c0b4e3abSDarrick J. Wong 	i2c_smbus_write_byte_data(client, ADT7462_REG_CFG2, reg);
1103c0b4e3abSDarrick J. Wong 	mutex_unlock(&data->lock);
1104c0b4e3abSDarrick J. Wong 
1105c0b4e3abSDarrick J. Wong 	return count;
1106c0b4e3abSDarrick J. Wong }
1107c0b4e3abSDarrick J. Wong 
1108c0b4e3abSDarrick J. Wong static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr,
1109c0b4e3abSDarrick J. Wong 			char *buf)
1110c0b4e3abSDarrick J. Wong {
1111c0b4e3abSDarrick J. Wong 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
1112c0b4e3abSDarrick J. Wong 	struct adt7462_data *data = adt7462_update_device(dev);
1113c0b4e3abSDarrick J. Wong 	return sprintf(buf, "%d\n", data->pwm[attr->index]);
1114c0b4e3abSDarrick J. Wong }
1115c0b4e3abSDarrick J. Wong 
1116c0b4e3abSDarrick J. Wong static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr,
1117c0b4e3abSDarrick J. Wong 			const char *buf, size_t count)
1118c0b4e3abSDarrick J. Wong {
1119c0b4e3abSDarrick J. Wong 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
1120573bfe67SAxel Lin 	struct adt7462_data *data = dev_get_drvdata(dev);
1121573bfe67SAxel Lin 	struct i2c_client *client = data->client;
1122c0b4e3abSDarrick J. Wong 	long temp;
1123c0b4e3abSDarrick J. Wong 
1124179c4fdbSFrans Meulenbroeks 	if (kstrtol(buf, 10, &temp))
1125c0b4e3abSDarrick J. Wong 		return -EINVAL;
1126c0b4e3abSDarrick J. Wong 
11272a844c14SGuenter Roeck 	temp = clamp_val(temp, 0, 255);
1128c0b4e3abSDarrick J. Wong 
1129c0b4e3abSDarrick J. Wong 	mutex_lock(&data->lock);
1130c0b4e3abSDarrick J. Wong 	data->pwm[attr->index] = temp;
1131c0b4e3abSDarrick J. Wong 	i2c_smbus_write_byte_data(client, ADT7462_REG_PWM(attr->index), temp);
1132c0b4e3abSDarrick J. Wong 	mutex_unlock(&data->lock);
1133c0b4e3abSDarrick J. Wong 
1134c0b4e3abSDarrick J. Wong 	return count;
1135c0b4e3abSDarrick J. Wong }
1136c0b4e3abSDarrick J. Wong 
1137c0b4e3abSDarrick J. Wong static ssize_t show_pwm_max(struct device *dev,
1138c0b4e3abSDarrick J. Wong 			    struct device_attribute *devattr,
1139c0b4e3abSDarrick J. Wong 			    char *buf)
1140c0b4e3abSDarrick J. Wong {
1141c0b4e3abSDarrick J. Wong 	struct adt7462_data *data = adt7462_update_device(dev);
1142c0b4e3abSDarrick J. Wong 	return sprintf(buf, "%d\n", data->pwm_max);
1143c0b4e3abSDarrick J. Wong }
1144c0b4e3abSDarrick J. Wong 
1145c0b4e3abSDarrick J. Wong static ssize_t set_pwm_max(struct device *dev,
1146c0b4e3abSDarrick J. Wong 			   struct device_attribute *devattr,
1147c0b4e3abSDarrick J. Wong 			   const char *buf,
1148c0b4e3abSDarrick J. Wong 			   size_t count)
1149c0b4e3abSDarrick J. Wong {
1150573bfe67SAxel Lin 	struct adt7462_data *data = dev_get_drvdata(dev);
1151573bfe67SAxel Lin 	struct i2c_client *client = data->client;
1152c0b4e3abSDarrick J. Wong 	long temp;
1153c0b4e3abSDarrick J. Wong 
1154179c4fdbSFrans Meulenbroeks 	if (kstrtol(buf, 10, &temp))
1155c0b4e3abSDarrick J. Wong 		return -EINVAL;
1156c0b4e3abSDarrick J. Wong 
11572a844c14SGuenter Roeck 	temp = clamp_val(temp, 0, 255);
1158c0b4e3abSDarrick J. Wong 
1159c0b4e3abSDarrick J. Wong 	mutex_lock(&data->lock);
1160c0b4e3abSDarrick J. Wong 	data->pwm_max = temp;
1161c0b4e3abSDarrick J. Wong 	i2c_smbus_write_byte_data(client, ADT7462_REG_PWM_MAX, temp);
1162c0b4e3abSDarrick J. Wong 	mutex_unlock(&data->lock);
1163c0b4e3abSDarrick J. Wong 
1164c0b4e3abSDarrick J. Wong 	return count;
1165c0b4e3abSDarrick J. Wong }
1166c0b4e3abSDarrick J. Wong 
1167c0b4e3abSDarrick J. Wong static ssize_t show_pwm_min(struct device *dev,
1168c0b4e3abSDarrick J. Wong 			    struct device_attribute *devattr,
1169c0b4e3abSDarrick J. Wong 			    char *buf)
1170c0b4e3abSDarrick J. Wong {
1171c0b4e3abSDarrick J. Wong 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
1172c0b4e3abSDarrick J. Wong 	struct adt7462_data *data = adt7462_update_device(dev);
1173c0b4e3abSDarrick J. Wong 	return sprintf(buf, "%d\n", data->pwm_min[attr->index]);
1174c0b4e3abSDarrick J. Wong }
1175c0b4e3abSDarrick J. Wong 
1176c0b4e3abSDarrick J. Wong static ssize_t set_pwm_min(struct device *dev,
1177c0b4e3abSDarrick J. Wong 			   struct device_attribute *devattr,
1178c0b4e3abSDarrick J. Wong 			   const char *buf,
1179c0b4e3abSDarrick J. Wong 			   size_t count)
1180c0b4e3abSDarrick J. Wong {
1181c0b4e3abSDarrick J. Wong 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
1182573bfe67SAxel Lin 	struct adt7462_data *data = dev_get_drvdata(dev);
1183573bfe67SAxel Lin 	struct i2c_client *client = data->client;
1184c0b4e3abSDarrick J. Wong 	long temp;
1185c0b4e3abSDarrick J. Wong 
1186179c4fdbSFrans Meulenbroeks 	if (kstrtol(buf, 10, &temp))
1187c0b4e3abSDarrick J. Wong 		return -EINVAL;
1188c0b4e3abSDarrick J. Wong 
11892a844c14SGuenter Roeck 	temp = clamp_val(temp, 0, 255);
1190c0b4e3abSDarrick J. Wong 
1191c0b4e3abSDarrick J. Wong 	mutex_lock(&data->lock);
1192c0b4e3abSDarrick J. Wong 	data->pwm_min[attr->index] = temp;
1193c0b4e3abSDarrick J. Wong 	i2c_smbus_write_byte_data(client, ADT7462_REG_PWM_MIN(attr->index),
1194c0b4e3abSDarrick J. Wong 				  temp);
1195c0b4e3abSDarrick J. Wong 	mutex_unlock(&data->lock);
1196c0b4e3abSDarrick J. Wong 
1197c0b4e3abSDarrick J. Wong 	return count;
1198c0b4e3abSDarrick J. Wong }
1199c0b4e3abSDarrick J. Wong 
1200c0b4e3abSDarrick J. Wong static ssize_t show_pwm_hyst(struct device *dev,
1201c0b4e3abSDarrick J. Wong 			     struct device_attribute *devattr,
1202c0b4e3abSDarrick J. Wong 			     char *buf)
1203c0b4e3abSDarrick J. Wong {
1204c0b4e3abSDarrick J. Wong 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
1205c0b4e3abSDarrick J. Wong 	struct adt7462_data *data = adt7462_update_device(dev);
1206c0b4e3abSDarrick J. Wong 	return sprintf(buf, "%d\n", 1000 *
1207c0b4e3abSDarrick J. Wong 		      (data->pwm_trange[attr->index] & ADT7462_PWM_HYST_MASK));
1208c0b4e3abSDarrick J. Wong }
1209c0b4e3abSDarrick J. Wong 
1210c0b4e3abSDarrick J. Wong static ssize_t set_pwm_hyst(struct device *dev,
1211c0b4e3abSDarrick J. Wong 			    struct device_attribute *devattr,
1212c0b4e3abSDarrick J. Wong 			    const char *buf,
1213c0b4e3abSDarrick J. Wong 			    size_t count)
1214c0b4e3abSDarrick J. Wong {
1215c0b4e3abSDarrick J. Wong 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
1216573bfe67SAxel Lin 	struct adt7462_data *data = dev_get_drvdata(dev);
1217573bfe67SAxel Lin 	struct i2c_client *client = data->client;
1218c0b4e3abSDarrick J. Wong 	long temp;
1219c0b4e3abSDarrick J. Wong 
1220179c4fdbSFrans Meulenbroeks 	if (kstrtol(buf, 10, &temp))
1221c0b4e3abSDarrick J. Wong 		return -EINVAL;
1222c0b4e3abSDarrick J. Wong 
1223*b94793b4SGuenter Roeck 	temp = clamp_val(temp, 0, 15000);
12248f8c1fb0SDarrick J. Wong 	temp = DIV_ROUND_CLOSEST(temp, 1000);
1225c0b4e3abSDarrick J. Wong 
1226c0b4e3abSDarrick J. Wong 	/* package things up */
1227c0b4e3abSDarrick J. Wong 	temp &= ADT7462_PWM_HYST_MASK;
1228c0b4e3abSDarrick J. Wong 	temp |= data->pwm_trange[attr->index] & ADT7462_PWM_RANGE_MASK;
1229c0b4e3abSDarrick J. Wong 
1230c0b4e3abSDarrick J. Wong 	mutex_lock(&data->lock);
1231c0b4e3abSDarrick J. Wong 	data->pwm_trange[attr->index] = temp;
1232c0b4e3abSDarrick J. Wong 	i2c_smbus_write_byte_data(client, ADT7462_REG_PWM_TRANGE(attr->index),
1233c0b4e3abSDarrick J. Wong 				  temp);
1234c0b4e3abSDarrick J. Wong 	mutex_unlock(&data->lock);
1235c0b4e3abSDarrick J. Wong 
1236c0b4e3abSDarrick J. Wong 	return count;
1237c0b4e3abSDarrick J. Wong }
1238c0b4e3abSDarrick J. Wong 
1239c0b4e3abSDarrick J. Wong static ssize_t show_pwm_tmax(struct device *dev,
1240c0b4e3abSDarrick J. Wong 			     struct device_attribute *devattr,
1241c0b4e3abSDarrick J. Wong 			     char *buf)
1242c0b4e3abSDarrick J. Wong {
1243c0b4e3abSDarrick J. Wong 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
1244c0b4e3abSDarrick J. Wong 	struct adt7462_data *data = adt7462_update_device(dev);
1245c0b4e3abSDarrick J. Wong 
1246c0b4e3abSDarrick J. Wong 	/* tmax = tmin + trange */
1247c0b4e3abSDarrick J. Wong 	int trange = trange_values[data->pwm_trange[attr->index] >>
1248c0b4e3abSDarrick J. Wong 				   ADT7462_PWM_RANGE_SHIFT];
1249c0b4e3abSDarrick J. Wong 	int tmin = (data->pwm_tmin[attr->index] - 64) * 1000;
1250c0b4e3abSDarrick J. Wong 
1251c0b4e3abSDarrick J. Wong 	return sprintf(buf, "%d\n", tmin + trange);
1252c0b4e3abSDarrick J. Wong }
1253c0b4e3abSDarrick J. Wong 
1254c0b4e3abSDarrick J. Wong static ssize_t set_pwm_tmax(struct device *dev,
1255c0b4e3abSDarrick J. Wong 			    struct device_attribute *devattr,
1256c0b4e3abSDarrick J. Wong 			    const char *buf,
1257c0b4e3abSDarrick J. Wong 			    size_t count)
1258c0b4e3abSDarrick J. Wong {
1259c0b4e3abSDarrick J. Wong 	int temp;
1260c0b4e3abSDarrick J. Wong 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
1261573bfe67SAxel Lin 	struct adt7462_data *data = dev_get_drvdata(dev);
1262573bfe67SAxel Lin 	struct i2c_client *client = data->client;
1263c0b4e3abSDarrick J. Wong 	int tmin, trange_value;
1264c0b4e3abSDarrick J. Wong 	long trange;
1265c0b4e3abSDarrick J. Wong 
1266179c4fdbSFrans Meulenbroeks 	if (kstrtol(buf, 10, &trange))
1267c0b4e3abSDarrick J. Wong 		return -EINVAL;
1268c0b4e3abSDarrick J. Wong 
1269c0b4e3abSDarrick J. Wong 	/* trange = tmax - tmin */
1270c0b4e3abSDarrick J. Wong 	tmin = (data->pwm_tmin[attr->index] - 64) * 1000;
1271c0b4e3abSDarrick J. Wong 	trange_value = find_trange_value(trange - tmin);
1272c0b4e3abSDarrick J. Wong 	if (trange_value < 0)
1273bb34c0daSGuenter Roeck 		return trange_value;
1274c0b4e3abSDarrick J. Wong 
1275c0b4e3abSDarrick J. Wong 	temp = trange_value << ADT7462_PWM_RANGE_SHIFT;
1276c0b4e3abSDarrick J. Wong 	temp |= data->pwm_trange[attr->index] & ADT7462_PWM_HYST_MASK;
1277c0b4e3abSDarrick J. Wong 
1278c0b4e3abSDarrick J. Wong 	mutex_lock(&data->lock);
1279c0b4e3abSDarrick J. Wong 	data->pwm_trange[attr->index] = temp;
1280c0b4e3abSDarrick J. Wong 	i2c_smbus_write_byte_data(client, ADT7462_REG_PWM_TRANGE(attr->index),
1281c0b4e3abSDarrick J. Wong 				  temp);
1282c0b4e3abSDarrick J. Wong 	mutex_unlock(&data->lock);
1283c0b4e3abSDarrick J. Wong 
1284c0b4e3abSDarrick J. Wong 	return count;
1285c0b4e3abSDarrick J. Wong }
1286c0b4e3abSDarrick J. Wong 
1287c0b4e3abSDarrick J. Wong static ssize_t show_pwm_tmin(struct device *dev,
1288c0b4e3abSDarrick J. Wong 			     struct device_attribute *devattr,
1289c0b4e3abSDarrick J. Wong 			     char *buf)
1290c0b4e3abSDarrick J. Wong {
1291c0b4e3abSDarrick J. Wong 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
1292c0b4e3abSDarrick J. Wong 	struct adt7462_data *data = adt7462_update_device(dev);
1293c0b4e3abSDarrick J. Wong 	return sprintf(buf, "%d\n", 1000 * (data->pwm_tmin[attr->index] - 64));
1294c0b4e3abSDarrick J. Wong }
1295c0b4e3abSDarrick J. Wong 
1296c0b4e3abSDarrick J. Wong static ssize_t set_pwm_tmin(struct device *dev,
1297c0b4e3abSDarrick J. Wong 			    struct device_attribute *devattr,
1298c0b4e3abSDarrick J. Wong 			    const char *buf,
1299c0b4e3abSDarrick J. Wong 			    size_t count)
1300c0b4e3abSDarrick J. Wong {
1301c0b4e3abSDarrick J. Wong 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
1302573bfe67SAxel Lin 	struct adt7462_data *data = dev_get_drvdata(dev);
1303573bfe67SAxel Lin 	struct i2c_client *client = data->client;
1304c0b4e3abSDarrick J. Wong 	long temp;
1305c0b4e3abSDarrick J. Wong 
1306179c4fdbSFrans Meulenbroeks 	if (kstrtol(buf, 10, &temp))
1307c0b4e3abSDarrick J. Wong 		return -EINVAL;
1308c0b4e3abSDarrick J. Wong 
1309*b94793b4SGuenter Roeck 	temp = clamp_val(temp, -64000, 191000);
13108f8c1fb0SDarrick J. Wong 	temp = DIV_ROUND_CLOSEST(temp, 1000) + 64;
1311c0b4e3abSDarrick J. Wong 
1312c0b4e3abSDarrick J. Wong 	mutex_lock(&data->lock);
1313c0b4e3abSDarrick J. Wong 	data->pwm_tmin[attr->index] = temp;
1314c0b4e3abSDarrick J. Wong 	i2c_smbus_write_byte_data(client, ADT7462_REG_PWM_TMIN(attr->index),
1315c0b4e3abSDarrick J. Wong 				  temp);
1316c0b4e3abSDarrick J. Wong 	mutex_unlock(&data->lock);
1317c0b4e3abSDarrick J. Wong 
1318c0b4e3abSDarrick J. Wong 	return count;
1319c0b4e3abSDarrick J. Wong }
1320c0b4e3abSDarrick J. Wong 
1321c0b4e3abSDarrick J. Wong static ssize_t show_pwm_auto(struct device *dev,
1322c0b4e3abSDarrick J. Wong 			     struct device_attribute *devattr,
1323c0b4e3abSDarrick J. Wong 			     char *buf)
1324c0b4e3abSDarrick J. Wong {
1325c0b4e3abSDarrick J. Wong 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
1326c0b4e3abSDarrick J. Wong 	struct adt7462_data *data = adt7462_update_device(dev);
1327c0b4e3abSDarrick J. Wong 	int cfg = data->pwm_cfg[attr->index] >> ADT7462_PWM_CHANNEL_SHIFT;
1328c0b4e3abSDarrick J. Wong 
1329c0b4e3abSDarrick J. Wong 	switch (cfg) {
1330c0b4e3abSDarrick J. Wong 	case 4: /* off */
1331c0b4e3abSDarrick J. Wong 		return sprintf(buf, "0\n");
1332c0b4e3abSDarrick J. Wong 	case 7: /* manual */
1333c0b4e3abSDarrick J. Wong 		return sprintf(buf, "1\n");
1334c0b4e3abSDarrick J. Wong 	default: /* automatic */
1335c0b4e3abSDarrick J. Wong 		return sprintf(buf, "2\n");
1336c0b4e3abSDarrick J. Wong 	}
1337c0b4e3abSDarrick J. Wong }
1338c0b4e3abSDarrick J. Wong 
1339c0b4e3abSDarrick J. Wong static void set_pwm_channel(struct i2c_client *client,
1340c0b4e3abSDarrick J. Wong 			    struct adt7462_data *data,
1341c0b4e3abSDarrick J. Wong 			    int which,
1342c0b4e3abSDarrick J. Wong 			    int value)
1343c0b4e3abSDarrick J. Wong {
1344c0b4e3abSDarrick J. Wong 	int temp = data->pwm_cfg[which] & ~ADT7462_PWM_CHANNEL_MASK;
1345c0b4e3abSDarrick J. Wong 	temp |= value << ADT7462_PWM_CHANNEL_SHIFT;
1346c0b4e3abSDarrick J. Wong 
1347c0b4e3abSDarrick J. Wong 	mutex_lock(&data->lock);
1348c0b4e3abSDarrick J. Wong 	data->pwm_cfg[which] = temp;
1349c0b4e3abSDarrick J. Wong 	i2c_smbus_write_byte_data(client, ADT7462_REG_PWM_CFG(which), temp);
1350c0b4e3abSDarrick J. Wong 	mutex_unlock(&data->lock);
1351c0b4e3abSDarrick J. Wong }
1352c0b4e3abSDarrick J. Wong 
1353c0b4e3abSDarrick J. Wong static ssize_t set_pwm_auto(struct device *dev,
1354c0b4e3abSDarrick J. Wong 			    struct device_attribute *devattr,
1355c0b4e3abSDarrick J. Wong 			    const char *buf,
1356c0b4e3abSDarrick J. Wong 			    size_t count)
1357c0b4e3abSDarrick J. Wong {
1358c0b4e3abSDarrick J. Wong 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
1359573bfe67SAxel Lin 	struct adt7462_data *data = dev_get_drvdata(dev);
1360573bfe67SAxel Lin 	struct i2c_client *client = data->client;
1361c0b4e3abSDarrick J. Wong 	long temp;
1362c0b4e3abSDarrick J. Wong 
1363179c4fdbSFrans Meulenbroeks 	if (kstrtol(buf, 10, &temp))
1364c0b4e3abSDarrick J. Wong 		return -EINVAL;
1365c0b4e3abSDarrick J. Wong 
1366c0b4e3abSDarrick J. Wong 	switch (temp) {
1367c0b4e3abSDarrick J. Wong 	case 0: /* off */
1368c0b4e3abSDarrick J. Wong 		set_pwm_channel(client, data, attr->index, 4);
1369c0b4e3abSDarrick J. Wong 		return count;
1370c0b4e3abSDarrick J. Wong 	case 1: /* manual */
1371c0b4e3abSDarrick J. Wong 		set_pwm_channel(client, data, attr->index, 7);
1372c0b4e3abSDarrick J. Wong 		return count;
1373c0b4e3abSDarrick J. Wong 	default:
1374c0b4e3abSDarrick J. Wong 		return -EINVAL;
1375c0b4e3abSDarrick J. Wong 	}
1376c0b4e3abSDarrick J. Wong }
1377c0b4e3abSDarrick J. Wong 
1378c0b4e3abSDarrick J. Wong static ssize_t show_pwm_auto_temp(struct device *dev,
1379c0b4e3abSDarrick J. Wong 				  struct device_attribute *devattr,
1380c0b4e3abSDarrick J. Wong 				  char *buf)
1381c0b4e3abSDarrick J. Wong {
1382c0b4e3abSDarrick J. Wong 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
1383c0b4e3abSDarrick J. Wong 	struct adt7462_data *data = adt7462_update_device(dev);
1384c0b4e3abSDarrick J. Wong 	int channel = data->pwm_cfg[attr->index] >> ADT7462_PWM_CHANNEL_SHIFT;
1385c0b4e3abSDarrick J. Wong 
1386c0b4e3abSDarrick J. Wong 	switch (channel) {
1387c0b4e3abSDarrick J. Wong 	case 0: /* temp[1234] only */
1388c0b4e3abSDarrick J. Wong 	case 1:
1389c0b4e3abSDarrick J. Wong 	case 2:
1390c0b4e3abSDarrick J. Wong 	case 3:
1391c0b4e3abSDarrick J. Wong 		return sprintf(buf, "%d\n", (1 << channel));
1392c0b4e3abSDarrick J. Wong 	case 5: /* temp1 & temp4  */
1393c0b4e3abSDarrick J. Wong 		return sprintf(buf, "9\n");
1394c0b4e3abSDarrick J. Wong 	case 6:
1395c0b4e3abSDarrick J. Wong 		return sprintf(buf, "15\n");
1396c0b4e3abSDarrick J. Wong 	default:
1397c0b4e3abSDarrick J. Wong 		return sprintf(buf, "0\n");
1398c0b4e3abSDarrick J. Wong 	}
1399c0b4e3abSDarrick J. Wong }
1400c0b4e3abSDarrick J. Wong 
1401c0b4e3abSDarrick J. Wong static int cvt_auto_temp(int input)
1402c0b4e3abSDarrick J. Wong {
1403c0b4e3abSDarrick J. Wong 	if (input == 0xF)
1404c0b4e3abSDarrick J. Wong 		return 6;
1405c0b4e3abSDarrick J. Wong 	if (input == 0x9)
1406c0b4e3abSDarrick J. Wong 		return 5;
1407c0b4e3abSDarrick J. Wong 	if (input < 1 || !is_power_of_2(input))
1408c0b4e3abSDarrick J. Wong 		return -EINVAL;
1409c0b4e3abSDarrick J. Wong 	return ilog2(input);
1410c0b4e3abSDarrick J. Wong }
1411c0b4e3abSDarrick J. Wong 
1412c0b4e3abSDarrick J. Wong static ssize_t set_pwm_auto_temp(struct device *dev,
1413c0b4e3abSDarrick J. Wong 				 struct device_attribute *devattr,
1414c0b4e3abSDarrick J. Wong 				 const char *buf,
1415c0b4e3abSDarrick J. Wong 				 size_t count)
1416c0b4e3abSDarrick J. Wong {
1417c0b4e3abSDarrick J. Wong 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
1418573bfe67SAxel Lin 	struct adt7462_data *data = dev_get_drvdata(dev);
1419573bfe67SAxel Lin 	struct i2c_client *client = data->client;
1420c0b4e3abSDarrick J. Wong 	long temp;
1421c0b4e3abSDarrick J. Wong 
1422179c4fdbSFrans Meulenbroeks 	if (kstrtol(buf, 10, &temp))
1423c0b4e3abSDarrick J. Wong 		return -EINVAL;
1424c0b4e3abSDarrick J. Wong 
1425c0b4e3abSDarrick J. Wong 	temp = cvt_auto_temp(temp);
1426c0b4e3abSDarrick J. Wong 	if (temp < 0)
1427c0b4e3abSDarrick J. Wong 		return temp;
1428c0b4e3abSDarrick J. Wong 
1429c0b4e3abSDarrick J. Wong 	set_pwm_channel(client, data, attr->index, temp);
1430c0b4e3abSDarrick J. Wong 
1431c0b4e3abSDarrick J. Wong 	return count;
1432c0b4e3abSDarrick J. Wong }
1433c0b4e3abSDarrick J. Wong 
1434c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max,
1435c0b4e3abSDarrick J. Wong 		    set_temp_max, 0);
1436c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp_max,
1437c0b4e3abSDarrick J. Wong 		    set_temp_max, 1);
1438c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp3_max, S_IWUSR | S_IRUGO, show_temp_max,
1439c0b4e3abSDarrick J. Wong 		    set_temp_max, 2);
1440c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp4_max, S_IWUSR | S_IRUGO, show_temp_max,
1441c0b4e3abSDarrick J. Wong 		    set_temp_max, 3);
1442c0b4e3abSDarrick J. Wong 
1443c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp_min,
1444c0b4e3abSDarrick J. Wong 		    set_temp_min, 0);
1445c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp_min,
1446c0b4e3abSDarrick J. Wong 		    set_temp_min, 1);
1447c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp3_min, S_IWUSR | S_IRUGO, show_temp_min,
1448c0b4e3abSDarrick J. Wong 		    set_temp_min, 2);
1449c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp4_min, S_IWUSR | S_IRUGO, show_temp_min,
1450c0b4e3abSDarrick J. Wong 		    set_temp_min, 3);
1451c0b4e3abSDarrick J. Wong 
1452c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0);
1453c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1);
1454c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 2);
1455c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_temp, NULL, 3);
1456c0b4e3abSDarrick J. Wong 
1457c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, show_temp_label, NULL, 0);
1458c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp2_label, S_IRUGO, show_temp_label, NULL, 1);
1459c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp3_label, S_IRUGO, show_temp_label, NULL, 2);
1460c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp4_label, S_IRUGO, show_temp_label, NULL, 3);
1461c0b4e3abSDarrick J. Wong 
1462c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL,
1463c0b4e3abSDarrick J. Wong 			  ADT7462_ALARM1 | ADT7462_LT_ALARM);
1464c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL,
1465c0b4e3abSDarrick J. Wong 			  ADT7462_ALARM1 | ADT7462_R1T_ALARM);
1466c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL,
1467c0b4e3abSDarrick J. Wong 			  ADT7462_ALARM1 | ADT7462_R2T_ALARM);
1468c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp4_alarm, S_IRUGO, show_alarm, NULL,
1469c0b4e3abSDarrick J. Wong 			  ADT7462_ALARM1 | ADT7462_R3T_ALARM);
1470c0b4e3abSDarrick J. Wong 
1471c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in1_max, S_IWUSR | S_IRUGO, show_volt_max,
1472c0b4e3abSDarrick J. Wong 		    set_volt_max, 0);
1473c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in2_max, S_IWUSR | S_IRUGO, show_volt_max,
1474c0b4e3abSDarrick J. Wong 		    set_volt_max, 1);
1475c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in3_max, S_IWUSR | S_IRUGO, show_volt_max,
1476c0b4e3abSDarrick J. Wong 		    set_volt_max, 2);
1477c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in4_max, S_IWUSR | S_IRUGO, show_volt_max,
1478c0b4e3abSDarrick J. Wong 		    set_volt_max, 3);
1479c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in5_max, S_IWUSR | S_IRUGO, show_volt_max,
1480c0b4e3abSDarrick J. Wong 		    set_volt_max, 4);
1481c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in6_max, S_IWUSR | S_IRUGO, show_volt_max,
1482c0b4e3abSDarrick J. Wong 		    set_volt_max, 5);
1483c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in7_max, S_IWUSR | S_IRUGO, show_volt_max,
1484c0b4e3abSDarrick J. Wong 		    set_volt_max, 6);
1485c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in8_max, S_IWUSR | S_IRUGO, show_volt_max,
1486c0b4e3abSDarrick J. Wong 		    set_volt_max, 7);
1487c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in9_max, S_IWUSR | S_IRUGO, show_volt_max,
1488c0b4e3abSDarrick J. Wong 		    set_volt_max, 8);
1489c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in10_max, S_IWUSR | S_IRUGO, show_volt_max,
1490c0b4e3abSDarrick J. Wong 		    set_volt_max, 9);
1491c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in11_max, S_IWUSR | S_IRUGO, show_volt_max,
1492c0b4e3abSDarrick J. Wong 		    set_volt_max, 10);
1493c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in12_max, S_IWUSR | S_IRUGO, show_volt_max,
1494c0b4e3abSDarrick J. Wong 		    set_volt_max, 11);
1495c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in13_max, S_IWUSR | S_IRUGO, show_volt_max,
1496c0b4e3abSDarrick J. Wong 		    set_volt_max, 12);
1497c0b4e3abSDarrick J. Wong 
1498c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in1_min, S_IWUSR | S_IRUGO, show_volt_min,
1499c0b4e3abSDarrick J. Wong 		    set_volt_min, 0);
1500c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in2_min, S_IWUSR | S_IRUGO, show_volt_min,
1501c0b4e3abSDarrick J. Wong 		    set_volt_min, 1);
1502c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in3_min, S_IWUSR | S_IRUGO, show_volt_min,
1503c0b4e3abSDarrick J. Wong 		    set_volt_min, 2);
1504c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in4_min, S_IWUSR | S_IRUGO, show_volt_min,
1505c0b4e3abSDarrick J. Wong 		    set_volt_min, 3);
1506c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in5_min, S_IWUSR | S_IRUGO, show_volt_min,
1507c0b4e3abSDarrick J. Wong 		    set_volt_min, 4);
1508c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in6_min, S_IWUSR | S_IRUGO, show_volt_min,
1509c0b4e3abSDarrick J. Wong 		    set_volt_min, 5);
1510c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in7_min, S_IWUSR | S_IRUGO, show_volt_min,
1511c0b4e3abSDarrick J. Wong 		    set_volt_min, 6);
1512c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in8_min, S_IWUSR | S_IRUGO, show_volt_min,
1513c0b4e3abSDarrick J. Wong 		    set_volt_min, 7);
1514c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in9_min, S_IWUSR | S_IRUGO, show_volt_min,
1515c0b4e3abSDarrick J. Wong 		    set_volt_min, 8);
1516c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in10_min, S_IWUSR | S_IRUGO, show_volt_min,
1517c0b4e3abSDarrick J. Wong 		    set_volt_min, 9);
1518c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in11_min, S_IWUSR | S_IRUGO, show_volt_min,
1519c0b4e3abSDarrick J. Wong 		    set_volt_min, 10);
1520c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in12_min, S_IWUSR | S_IRUGO, show_volt_min,
1521c0b4e3abSDarrick J. Wong 		    set_volt_min, 11);
1522c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in13_min, S_IWUSR | S_IRUGO, show_volt_min,
1523c0b4e3abSDarrick J. Wong 		    set_volt_min, 12);
1524c0b4e3abSDarrick J. Wong 
1525c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_voltage, NULL, 0);
1526c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_voltage, NULL, 1);
1527c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_voltage, NULL, 2);
1528c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, show_voltage, NULL, 3);
1529c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, show_voltage, NULL, 4);
1530c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, show_voltage, NULL, 5);
1531c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, show_voltage, NULL, 6);
1532c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in8_input, S_IRUGO, show_voltage, NULL, 7);
1533c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in9_input, S_IRUGO, show_voltage, NULL, 8);
1534c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in10_input, S_IRUGO, show_voltage, NULL, 9);
1535c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in11_input, S_IRUGO, show_voltage, NULL, 10);
1536c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in12_input, S_IRUGO, show_voltage, NULL, 11);
1537c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in13_input, S_IRUGO, show_voltage, NULL, 12);
1538c0b4e3abSDarrick J. Wong 
1539c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in1_label, S_IRUGO, show_voltage_label, NULL, 0);
1540c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in2_label, S_IRUGO, show_voltage_label, NULL, 1);
1541c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in3_label, S_IRUGO, show_voltage_label, NULL, 2);
1542c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in4_label, S_IRUGO, show_voltage_label, NULL, 3);
1543c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in5_label, S_IRUGO, show_voltage_label, NULL, 4);
1544c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in6_label, S_IRUGO, show_voltage_label, NULL, 5);
1545c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in7_label, S_IRUGO, show_voltage_label, NULL, 6);
1546c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in8_label, S_IRUGO, show_voltage_label, NULL, 7);
1547c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in9_label, S_IRUGO, show_voltage_label, NULL, 8);
1548c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in10_label, S_IRUGO, show_voltage_label, NULL, 9);
1549c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in11_label, S_IRUGO, show_voltage_label, NULL, 10);
1550c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in12_label, S_IRUGO, show_voltage_label, NULL, 11);
1551c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in13_label, S_IRUGO, show_voltage_label, NULL, 12);
1552c0b4e3abSDarrick J. Wong 
1553c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL,
1554c0b4e3abSDarrick J. Wong 			  ADT7462_ALARM2 | ADT7462_V0_ALARM);
1555c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL,
1556c0b4e3abSDarrick J. Wong 			  ADT7462_ALARM2 | ADT7462_V7_ALARM);
1557c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL,
1558c0b4e3abSDarrick J. Wong 			  ADT7462_ALARM2 | ADT7462_V2_ALARM);
1559c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL,
1560c0b4e3abSDarrick J. Wong 			  ADT7462_ALARM2 | ADT7462_V6_ALARM);
1561c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL,
1562c0b4e3abSDarrick J. Wong 			  ADT7462_ALARM2 | ADT7462_V5_ALARM);
1563c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL,
1564c0b4e3abSDarrick J. Wong 			  ADT7462_ALARM2 | ADT7462_V4_ALARM);
1565c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in7_alarm, S_IRUGO, show_alarm, NULL,
1566c0b4e3abSDarrick J. Wong 			  ADT7462_ALARM2 | ADT7462_V3_ALARM);
1567c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in8_alarm, S_IRUGO, show_alarm, NULL,
1568c0b4e3abSDarrick J. Wong 			  ADT7462_ALARM2 | ADT7462_V1_ALARM);
1569c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in9_alarm, S_IRUGO, show_alarm, NULL,
1570c0b4e3abSDarrick J. Wong 			  ADT7462_ALARM3 | ADT7462_V10_ALARM);
1571c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in10_alarm, S_IRUGO, show_alarm, NULL,
1572c0b4e3abSDarrick J. Wong 			  ADT7462_ALARM3 | ADT7462_V9_ALARM);
1573c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in11_alarm, S_IRUGO, show_alarm, NULL,
1574c0b4e3abSDarrick J. Wong 			  ADT7462_ALARM3 | ADT7462_V8_ALARM);
1575c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in12_alarm, S_IRUGO, show_alarm, NULL,
1576c0b4e3abSDarrick J. Wong 			  ADT7462_ALARM3 | ADT7462_V11_ALARM);
1577c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(in13_alarm, S_IRUGO, show_alarm, NULL,
1578c0b4e3abSDarrick J. Wong 			  ADT7462_ALARM3 | ADT7462_V12_ALARM);
1579c0b4e3abSDarrick J. Wong 
1580c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan_min,
1581c0b4e3abSDarrick J. Wong 		    set_fan_min, 0);
1582c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(fan2_min, S_IWUSR | S_IRUGO, show_fan_min,
1583c0b4e3abSDarrick J. Wong 		    set_fan_min, 1);
1584c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(fan3_min, S_IWUSR | S_IRUGO, show_fan_min,
1585c0b4e3abSDarrick J. Wong 		    set_fan_min, 2);
1586c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(fan4_min, S_IWUSR | S_IRUGO, show_fan_min,
1587c0b4e3abSDarrick J. Wong 		    set_fan_min, 3);
1588c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(fan5_min, S_IWUSR | S_IRUGO, show_fan_min,
1589c0b4e3abSDarrick J. Wong 		    set_fan_min, 4);
1590c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(fan6_min, S_IWUSR | S_IRUGO, show_fan_min,
1591c0b4e3abSDarrick J. Wong 		    set_fan_min, 5);
1592c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(fan7_min, S_IWUSR | S_IRUGO, show_fan_min,
1593c0b4e3abSDarrick J. Wong 		    set_fan_min, 6);
1594c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(fan8_min, S_IWUSR | S_IRUGO, show_fan_min,
1595c0b4e3abSDarrick J. Wong 		    set_fan_min, 7);
1596c0b4e3abSDarrick J. Wong 
1597c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0);
1598c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1);
1599c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2);
1600c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 3);
1601c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(fan5_input, S_IRUGO, show_fan, NULL, 4);
1602c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(fan6_input, S_IRUGO, show_fan, NULL, 5);
1603c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(fan7_input, S_IRUGO, show_fan, NULL, 6);
1604c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(fan8_input, S_IRUGO, show_fan, NULL, 7);
1605c0b4e3abSDarrick J. Wong 
1606c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL,
1607c0b4e3abSDarrick J. Wong 			  ADT7462_ALARM4 | ADT7462_F0_ALARM);
1608c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL,
1609c0b4e3abSDarrick J. Wong 			  ADT7462_ALARM4 | ADT7462_F1_ALARM);
1610c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL,
1611c0b4e3abSDarrick J. Wong 			  ADT7462_ALARM4 | ADT7462_F2_ALARM);
1612c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(fan4_alarm, S_IRUGO, show_alarm, NULL,
1613c0b4e3abSDarrick J. Wong 			  ADT7462_ALARM4 | ADT7462_F3_ALARM);
1614c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(fan5_alarm, S_IRUGO, show_alarm, NULL,
1615c0b4e3abSDarrick J. Wong 			  ADT7462_ALARM4 | ADT7462_F4_ALARM);
1616c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(fan6_alarm, S_IRUGO, show_alarm, NULL,
1617c0b4e3abSDarrick J. Wong 			  ADT7462_ALARM4 | ADT7462_F5_ALARM);
1618c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(fan7_alarm, S_IRUGO, show_alarm, NULL,
1619c0b4e3abSDarrick J. Wong 			  ADT7462_ALARM4 | ADT7462_F6_ALARM);
1620c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(fan8_alarm, S_IRUGO, show_alarm, NULL,
1621c0b4e3abSDarrick J. Wong 			  ADT7462_ALARM4 | ADT7462_F7_ALARM);
1622c0b4e3abSDarrick J. Wong 
1623c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(force_pwm_max, S_IWUSR | S_IRUGO,
1624c0b4e3abSDarrick J. Wong 		    show_force_pwm_max, set_force_pwm_max, 0);
1625c0b4e3abSDarrick J. Wong 
1626c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 0);
1627c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 1);
1628c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(pwm3, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 2);
1629c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(pwm4, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 3);
1630c0b4e3abSDarrick J. Wong 
1631c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(pwm1_auto_point1_pwm, S_IWUSR | S_IRUGO,
1632c0b4e3abSDarrick J. Wong 		    show_pwm_min, set_pwm_min, 0);
1633c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(pwm2_auto_point1_pwm, S_IWUSR | S_IRUGO,
1634c0b4e3abSDarrick J. Wong 		    show_pwm_min, set_pwm_min, 1);
1635c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(pwm3_auto_point1_pwm, S_IWUSR | S_IRUGO,
1636c0b4e3abSDarrick J. Wong 		    show_pwm_min, set_pwm_min, 2);
1637c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(pwm4_auto_point1_pwm, S_IWUSR | S_IRUGO,
1638c0b4e3abSDarrick J. Wong 		    show_pwm_min, set_pwm_min, 3);
1639c0b4e3abSDarrick J. Wong 
1640c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(pwm1_auto_point2_pwm, S_IWUSR | S_IRUGO,
1641c0b4e3abSDarrick J. Wong 		    show_pwm_max, set_pwm_max, 0);
1642c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(pwm2_auto_point2_pwm, S_IWUSR | S_IRUGO,
1643c0b4e3abSDarrick J. Wong 		    show_pwm_max, set_pwm_max, 1);
1644c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(pwm3_auto_point2_pwm, S_IWUSR | S_IRUGO,
1645c0b4e3abSDarrick J. Wong 		    show_pwm_max, set_pwm_max, 2);
1646c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(pwm4_auto_point2_pwm, S_IWUSR | S_IRUGO,
1647c0b4e3abSDarrick J. Wong 		    show_pwm_max, set_pwm_max, 3);
1648c0b4e3abSDarrick J. Wong 
1649c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp1_auto_point1_hyst, S_IWUSR | S_IRUGO,
1650c0b4e3abSDarrick J. Wong 		    show_pwm_hyst, set_pwm_hyst, 0);
1651c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp2_auto_point1_hyst, S_IWUSR | S_IRUGO,
1652c0b4e3abSDarrick J. Wong 		    show_pwm_hyst, set_pwm_hyst, 1);
1653c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp3_auto_point1_hyst, S_IWUSR | S_IRUGO,
1654c0b4e3abSDarrick J. Wong 		    show_pwm_hyst, set_pwm_hyst, 2);
1655c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp4_auto_point1_hyst, S_IWUSR | S_IRUGO,
1656c0b4e3abSDarrick J. Wong 		    show_pwm_hyst, set_pwm_hyst, 3);
1657c0b4e3abSDarrick J. Wong 
1658c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp1_auto_point2_hyst, S_IWUSR | S_IRUGO,
1659c0b4e3abSDarrick J. Wong 		    show_pwm_hyst, set_pwm_hyst, 0);
1660c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp2_auto_point2_hyst, S_IWUSR | S_IRUGO,
1661c0b4e3abSDarrick J. Wong 		    show_pwm_hyst, set_pwm_hyst, 1);
1662c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp3_auto_point2_hyst, S_IWUSR | S_IRUGO,
1663c0b4e3abSDarrick J. Wong 		    show_pwm_hyst, set_pwm_hyst, 2);
1664c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp4_auto_point2_hyst, S_IWUSR | S_IRUGO,
1665c0b4e3abSDarrick J. Wong 		    show_pwm_hyst, set_pwm_hyst, 3);
1666c0b4e3abSDarrick J. Wong 
1667c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp, S_IWUSR | S_IRUGO,
1668c0b4e3abSDarrick J. Wong 		    show_pwm_tmin, set_pwm_tmin, 0);
1669c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp2_auto_point1_temp, S_IWUSR | S_IRUGO,
1670c0b4e3abSDarrick J. Wong 		    show_pwm_tmin, set_pwm_tmin, 1);
1671c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp3_auto_point1_temp, S_IWUSR | S_IRUGO,
1672c0b4e3abSDarrick J. Wong 		    show_pwm_tmin, set_pwm_tmin, 2);
1673c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp4_auto_point1_temp, S_IWUSR | S_IRUGO,
1674c0b4e3abSDarrick J. Wong 		    show_pwm_tmin, set_pwm_tmin, 3);
1675c0b4e3abSDarrick J. Wong 
1676c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp1_auto_point2_temp, S_IWUSR | S_IRUGO,
1677c0b4e3abSDarrick J. Wong 		    show_pwm_tmax, set_pwm_tmax, 0);
1678c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp2_auto_point2_temp, S_IWUSR | S_IRUGO,
1679c0b4e3abSDarrick J. Wong 		    show_pwm_tmax, set_pwm_tmax, 1);
1680c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp3_auto_point2_temp, S_IWUSR | S_IRUGO,
1681c0b4e3abSDarrick J. Wong 		    show_pwm_tmax, set_pwm_tmax, 2);
1682c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(temp4_auto_point2_temp, S_IWUSR | S_IRUGO,
1683c0b4e3abSDarrick J. Wong 		    show_pwm_tmax, set_pwm_tmax, 3);
1684c0b4e3abSDarrick J. Wong 
1685c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, show_pwm_auto,
1686c0b4e3abSDarrick J. Wong 		    set_pwm_auto, 0);
1687c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(pwm2_enable, S_IWUSR | S_IRUGO, show_pwm_auto,
1688c0b4e3abSDarrick J. Wong 		    set_pwm_auto, 1);
1689c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(pwm3_enable, S_IWUSR | S_IRUGO, show_pwm_auto,
1690c0b4e3abSDarrick J. Wong 		    set_pwm_auto, 2);
1691c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(pwm4_enable, S_IWUSR | S_IRUGO, show_pwm_auto,
1692c0b4e3abSDarrick J. Wong 		    set_pwm_auto, 3);
1693c0b4e3abSDarrick J. Wong 
1694c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(pwm1_auto_channels_temp, S_IWUSR | S_IRUGO,
1695c0b4e3abSDarrick J. Wong 		    show_pwm_auto_temp, set_pwm_auto_temp, 0);
1696c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(pwm2_auto_channels_temp, S_IWUSR | S_IRUGO,
1697c0b4e3abSDarrick J. Wong 		    show_pwm_auto_temp, set_pwm_auto_temp, 1);
1698c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(pwm3_auto_channels_temp, S_IWUSR | S_IRUGO,
1699c0b4e3abSDarrick J. Wong 		    show_pwm_auto_temp, set_pwm_auto_temp, 2);
1700c0b4e3abSDarrick J. Wong static SENSOR_DEVICE_ATTR(pwm4_auto_channels_temp, S_IWUSR | S_IRUGO,
1701c0b4e3abSDarrick J. Wong 		    show_pwm_auto_temp, set_pwm_auto_temp, 3);
1702c0b4e3abSDarrick J. Wong 
1703573bfe67SAxel Lin static struct attribute *adt7462_attrs[] = {
1704c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_temp1_max.dev_attr.attr,
1705c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_temp2_max.dev_attr.attr,
1706c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_temp3_max.dev_attr.attr,
1707c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_temp4_max.dev_attr.attr,
1708c0b4e3abSDarrick J. Wong 
1709c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_temp1_min.dev_attr.attr,
1710c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_temp2_min.dev_attr.attr,
1711c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_temp3_min.dev_attr.attr,
1712c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_temp4_min.dev_attr.attr,
1713c0b4e3abSDarrick J. Wong 
1714c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_temp1_input.dev_attr.attr,
1715c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_temp2_input.dev_attr.attr,
1716c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_temp3_input.dev_attr.attr,
1717c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_temp4_input.dev_attr.attr,
1718c0b4e3abSDarrick J. Wong 
1719c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_temp1_label.dev_attr.attr,
1720c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_temp2_label.dev_attr.attr,
1721c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_temp3_label.dev_attr.attr,
1722c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_temp4_label.dev_attr.attr,
1723c0b4e3abSDarrick J. Wong 
1724c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_temp1_alarm.dev_attr.attr,
1725c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_temp2_alarm.dev_attr.attr,
1726c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_temp3_alarm.dev_attr.attr,
1727c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_temp4_alarm.dev_attr.attr,
1728c0b4e3abSDarrick J. Wong 
1729c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in1_max.dev_attr.attr,
1730c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in2_max.dev_attr.attr,
1731c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in3_max.dev_attr.attr,
1732c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in4_max.dev_attr.attr,
1733c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in5_max.dev_attr.attr,
1734c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in6_max.dev_attr.attr,
1735c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in7_max.dev_attr.attr,
1736c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in8_max.dev_attr.attr,
1737c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in9_max.dev_attr.attr,
1738c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in10_max.dev_attr.attr,
1739c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in11_max.dev_attr.attr,
1740c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in12_max.dev_attr.attr,
1741c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in13_max.dev_attr.attr,
1742c0b4e3abSDarrick J. Wong 
1743c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in1_min.dev_attr.attr,
1744c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in2_min.dev_attr.attr,
1745c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in3_min.dev_attr.attr,
1746c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in4_min.dev_attr.attr,
1747c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in5_min.dev_attr.attr,
1748c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in6_min.dev_attr.attr,
1749c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in7_min.dev_attr.attr,
1750c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in8_min.dev_attr.attr,
1751c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in9_min.dev_attr.attr,
1752c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in10_min.dev_attr.attr,
1753c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in11_min.dev_attr.attr,
1754c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in12_min.dev_attr.attr,
1755c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in13_min.dev_attr.attr,
1756c0b4e3abSDarrick J. Wong 
1757c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in1_input.dev_attr.attr,
1758c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in2_input.dev_attr.attr,
1759c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in3_input.dev_attr.attr,
1760c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in4_input.dev_attr.attr,
1761c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in5_input.dev_attr.attr,
1762c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in6_input.dev_attr.attr,
1763c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in7_input.dev_attr.attr,
1764c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in8_input.dev_attr.attr,
1765c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in9_input.dev_attr.attr,
1766c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in10_input.dev_attr.attr,
1767c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in11_input.dev_attr.attr,
1768c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in12_input.dev_attr.attr,
1769c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in13_input.dev_attr.attr,
1770c0b4e3abSDarrick J. Wong 
1771c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in1_label.dev_attr.attr,
1772c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in2_label.dev_attr.attr,
1773c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in3_label.dev_attr.attr,
1774c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in4_label.dev_attr.attr,
1775c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in5_label.dev_attr.attr,
1776c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in6_label.dev_attr.attr,
1777c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in7_label.dev_attr.attr,
1778c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in8_label.dev_attr.attr,
1779c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in9_label.dev_attr.attr,
1780c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in10_label.dev_attr.attr,
1781c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in11_label.dev_attr.attr,
1782c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in12_label.dev_attr.attr,
1783c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in13_label.dev_attr.attr,
1784c0b4e3abSDarrick J. Wong 
1785c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in1_alarm.dev_attr.attr,
1786c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in2_alarm.dev_attr.attr,
1787c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in3_alarm.dev_attr.attr,
1788c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in4_alarm.dev_attr.attr,
1789c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in5_alarm.dev_attr.attr,
1790c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in6_alarm.dev_attr.attr,
1791c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in7_alarm.dev_attr.attr,
1792c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in8_alarm.dev_attr.attr,
1793c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in9_alarm.dev_attr.attr,
1794c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in10_alarm.dev_attr.attr,
1795c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in11_alarm.dev_attr.attr,
1796c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in12_alarm.dev_attr.attr,
1797c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_in13_alarm.dev_attr.attr,
1798c0b4e3abSDarrick J. Wong 
1799c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_fan1_min.dev_attr.attr,
1800c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_fan2_min.dev_attr.attr,
1801c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_fan3_min.dev_attr.attr,
1802c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_fan4_min.dev_attr.attr,
1803c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_fan5_min.dev_attr.attr,
1804c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_fan6_min.dev_attr.attr,
1805c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_fan7_min.dev_attr.attr,
1806c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_fan8_min.dev_attr.attr,
1807c0b4e3abSDarrick J. Wong 
1808c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_fan1_input.dev_attr.attr,
1809c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_fan2_input.dev_attr.attr,
1810c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_fan3_input.dev_attr.attr,
1811c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_fan4_input.dev_attr.attr,
1812c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_fan5_input.dev_attr.attr,
1813c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_fan6_input.dev_attr.attr,
1814c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_fan7_input.dev_attr.attr,
1815c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_fan8_input.dev_attr.attr,
1816c0b4e3abSDarrick J. Wong 
1817c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_fan1_alarm.dev_attr.attr,
1818c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_fan2_alarm.dev_attr.attr,
1819c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_fan3_alarm.dev_attr.attr,
1820c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_fan4_alarm.dev_attr.attr,
1821c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_fan5_alarm.dev_attr.attr,
1822c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_fan6_alarm.dev_attr.attr,
1823c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_fan7_alarm.dev_attr.attr,
1824c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_fan8_alarm.dev_attr.attr,
1825c0b4e3abSDarrick J. Wong 
1826c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_force_pwm_max.dev_attr.attr,
1827c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_pwm1.dev_attr.attr,
1828c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_pwm2.dev_attr.attr,
1829c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_pwm3.dev_attr.attr,
1830c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_pwm4.dev_attr.attr,
1831c0b4e3abSDarrick J. Wong 
1832c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr,
1833c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_pwm2_auto_point1_pwm.dev_attr.attr,
1834c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_pwm3_auto_point1_pwm.dev_attr.attr,
1835c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_pwm4_auto_point1_pwm.dev_attr.attr,
1836c0b4e3abSDarrick J. Wong 
1837c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_pwm1_auto_point2_pwm.dev_attr.attr,
1838c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_pwm2_auto_point2_pwm.dev_attr.attr,
1839c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_pwm3_auto_point2_pwm.dev_attr.attr,
1840c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_pwm4_auto_point2_pwm.dev_attr.attr,
1841c0b4e3abSDarrick J. Wong 
1842c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_temp1_auto_point1_hyst.dev_attr.attr,
1843c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_temp2_auto_point1_hyst.dev_attr.attr,
1844c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_temp3_auto_point1_hyst.dev_attr.attr,
1845c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_temp4_auto_point1_hyst.dev_attr.attr,
1846c0b4e3abSDarrick J. Wong 
1847c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_temp1_auto_point2_hyst.dev_attr.attr,
1848c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_temp2_auto_point2_hyst.dev_attr.attr,
1849c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_temp3_auto_point2_hyst.dev_attr.attr,
1850c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_temp4_auto_point2_hyst.dev_attr.attr,
1851c0b4e3abSDarrick J. Wong 
1852c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_temp1_auto_point1_temp.dev_attr.attr,
1853c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_temp2_auto_point1_temp.dev_attr.attr,
1854c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_temp3_auto_point1_temp.dev_attr.attr,
1855c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_temp4_auto_point1_temp.dev_attr.attr,
1856c0b4e3abSDarrick J. Wong 
1857c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_temp1_auto_point2_temp.dev_attr.attr,
1858c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_temp2_auto_point2_temp.dev_attr.attr,
1859c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_temp3_auto_point2_temp.dev_attr.attr,
1860c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_temp4_auto_point2_temp.dev_attr.attr,
1861c0b4e3abSDarrick J. Wong 
1862c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_pwm1_enable.dev_attr.attr,
1863c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_pwm2_enable.dev_attr.attr,
1864c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_pwm3_enable.dev_attr.attr,
1865c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_pwm4_enable.dev_attr.attr,
1866c0b4e3abSDarrick J. Wong 
1867c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_pwm1_auto_channels_temp.dev_attr.attr,
1868c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_pwm2_auto_channels_temp.dev_attr.attr,
1869c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_pwm3_auto_channels_temp.dev_attr.attr,
1870c0b4e3abSDarrick J. Wong 	&sensor_dev_attr_pwm4_auto_channels_temp.dev_attr.attr,
1871c0b4e3abSDarrick J. Wong 	NULL
1872c0b4e3abSDarrick J. Wong };
1873c0b4e3abSDarrick J. Wong 
1874573bfe67SAxel Lin ATTRIBUTE_GROUPS(adt7462);
1875573bfe67SAxel Lin 
1876c0b4e3abSDarrick J. Wong /* Return 0 if detection is successful, -ENODEV otherwise */
1877310ec792SJean Delvare static int adt7462_detect(struct i2c_client *client,
1878c0b4e3abSDarrick J. Wong 			  struct i2c_board_info *info)
1879c0b4e3abSDarrick J. Wong {
1880c0b4e3abSDarrick J. Wong 	struct i2c_adapter *adapter = client->adapter;
188152df6440SJean Delvare 	int vendor, device, revision;
1882c0b4e3abSDarrick J. Wong 
1883c0b4e3abSDarrick J. Wong 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
1884c0b4e3abSDarrick J. Wong 		return -ENODEV;
1885c0b4e3abSDarrick J. Wong 
1886c0b4e3abSDarrick J. Wong 	vendor = i2c_smbus_read_byte_data(client, ADT7462_REG_VENDOR);
1887c0b4e3abSDarrick J. Wong 	if (vendor != ADT7462_VENDOR)
1888c0b4e3abSDarrick J. Wong 		return -ENODEV;
1889c0b4e3abSDarrick J. Wong 
1890c0b4e3abSDarrick J. Wong 	device = i2c_smbus_read_byte_data(client, ADT7462_REG_DEVICE);
1891c0b4e3abSDarrick J. Wong 	if (device != ADT7462_DEVICE)
1892c0b4e3abSDarrick J. Wong 		return -ENODEV;
1893c0b4e3abSDarrick J. Wong 
189452df6440SJean Delvare 	revision = i2c_smbus_read_byte_data(client, ADT7462_REG_REVISION);
1895c0b4e3abSDarrick J. Wong 	if (revision != ADT7462_REVISION)
1896c0b4e3abSDarrick J. Wong 		return -ENODEV;
1897c0b4e3abSDarrick J. Wong 
1898c0b4e3abSDarrick J. Wong 	strlcpy(info->type, "adt7462", I2C_NAME_SIZE);
1899c0b4e3abSDarrick J. Wong 
1900c0b4e3abSDarrick J. Wong 	return 0;
1901c0b4e3abSDarrick J. Wong }
1902c0b4e3abSDarrick J. Wong 
1903c0b4e3abSDarrick J. Wong static int adt7462_probe(struct i2c_client *client,
1904c0b4e3abSDarrick J. Wong 			 const struct i2c_device_id *id)
1905c0b4e3abSDarrick J. Wong {
1906573bfe67SAxel Lin 	struct device *dev = &client->dev;
1907c0b4e3abSDarrick J. Wong 	struct adt7462_data *data;
1908573bfe67SAxel Lin 	struct device *hwmon_dev;
1909c0b4e3abSDarrick J. Wong 
1910573bfe67SAxel Lin 	data = devm_kzalloc(dev, sizeof(struct adt7462_data), GFP_KERNEL);
191108808300SGuenter Roeck 	if (!data)
191208808300SGuenter Roeck 		return -ENOMEM;
1913c0b4e3abSDarrick J. Wong 
1914573bfe67SAxel Lin 	data->client = client;
1915c0b4e3abSDarrick J. Wong 	mutex_init(&data->lock);
1916c0b4e3abSDarrick J. Wong 
1917c0b4e3abSDarrick J. Wong 	dev_info(&client->dev, "%s chip found\n", client->name);
1918c0b4e3abSDarrick J. Wong 
1919573bfe67SAxel Lin 	hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
1920573bfe67SAxel Lin 							   data,
1921573bfe67SAxel Lin 							   adt7462_groups);
1922573bfe67SAxel Lin 	return PTR_ERR_OR_ZERO(hwmon_dev);
1923c0b4e3abSDarrick J. Wong }
1924c0b4e3abSDarrick J. Wong 
1925a2cc2428SAxel Lin static const struct i2c_device_id adt7462_id[] = {
1926a2cc2428SAxel Lin 	{ "adt7462", 0 },
1927a2cc2428SAxel Lin 	{ }
1928a2cc2428SAxel Lin };
1929a2cc2428SAxel Lin MODULE_DEVICE_TABLE(i2c, adt7462_id);
1930a2cc2428SAxel Lin 
1931a2cc2428SAxel Lin static struct i2c_driver adt7462_driver = {
1932a2cc2428SAxel Lin 	.class		= I2C_CLASS_HWMON,
1933a2cc2428SAxel Lin 	.driver = {
1934a2cc2428SAxel Lin 		.name	= "adt7462",
1935a2cc2428SAxel Lin 	},
1936a2cc2428SAxel Lin 	.probe		= adt7462_probe,
1937a2cc2428SAxel Lin 	.id_table	= adt7462_id,
1938a2cc2428SAxel Lin 	.detect		= adt7462_detect,
1939a2cc2428SAxel Lin 	.address_list	= normal_i2c,
1940a2cc2428SAxel Lin };
1941a2cc2428SAxel Lin 
1942f0967eeaSAxel Lin module_i2c_driver(adt7462_driver);
1943c0b4e3abSDarrick J. Wong 
19445407e051SDarrick J. Wong MODULE_AUTHOR("Darrick J. Wong <darrick.wong@oracle.com>");
1945c0b4e3abSDarrick J. Wong MODULE_DESCRIPTION("ADT7462 driver");
1946c0b4e3abSDarrick J. Wong MODULE_LICENSE("GPL");
1947