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