1 |
62 |
marcus.erl |
/*
|
2 |
|
|
adm1026.c - Part of lm_sensors, Linux kernel modules for hardware
|
3 |
|
|
monitoring
|
4 |
|
|
Copyright (C) 2002, 2003 Philip Pokorny <ppokorny@penguincomputing.com>
|
5 |
|
|
Copyright (C) 2004 Justin Thiessen <jthiessen@penguincomputing.com>
|
6 |
|
|
|
7 |
|
|
Chip details at:
|
8 |
|
|
|
9 |
|
|
<http://www.analog.com/UploadedFiles/Data_Sheets/779263102ADM1026_a.pdf>
|
10 |
|
|
|
11 |
|
|
This program is free software; you can redistribute it and/or modify
|
12 |
|
|
it under the terms of the GNU General Public License as published by
|
13 |
|
|
the Free Software Foundation; either version 2 of the License, or
|
14 |
|
|
(at your option) any later version.
|
15 |
|
|
|
16 |
|
|
This program is distributed in the hope that it will be useful,
|
17 |
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
18 |
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
19 |
|
|
GNU General Public License for more details.
|
20 |
|
|
|
21 |
|
|
You should have received a copy of the GNU General Public License
|
22 |
|
|
along with this program; if not, write to the Free Software
|
23 |
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
24 |
|
|
*/
|
25 |
|
|
|
26 |
|
|
#include <linux/module.h>
|
27 |
|
|
#include <linux/init.h>
|
28 |
|
|
#include <linux/slab.h>
|
29 |
|
|
#include <linux/jiffies.h>
|
30 |
|
|
#include <linux/i2c.h>
|
31 |
|
|
#include <linux/hwmon.h>
|
32 |
|
|
#include <linux/hwmon-sysfs.h>
|
33 |
|
|
#include <linux/hwmon-vid.h>
|
34 |
|
|
#include <linux/err.h>
|
35 |
|
|
#include <linux/mutex.h>
|
36 |
|
|
|
37 |
|
|
/* Addresses to scan */
|
38 |
|
|
static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
|
39 |
|
|
|
40 |
|
|
/* Insmod parameters */
|
41 |
|
|
I2C_CLIENT_INSMOD_1(adm1026);
|
42 |
|
|
|
43 |
|
|
static int gpio_input[17] = { -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
44 |
|
|
-1, -1, -1, -1, -1, -1, -1, -1 };
|
45 |
|
|
static int gpio_output[17] = { -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
46 |
|
|
-1, -1, -1, -1, -1, -1, -1, -1 };
|
47 |
|
|
static int gpio_inverted[17] = { -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
48 |
|
|
-1, -1, -1, -1, -1, -1, -1, -1 };
|
49 |
|
|
static int gpio_normal[17] = { -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
50 |
|
|
-1, -1, -1, -1, -1, -1, -1, -1 };
|
51 |
|
|
static int gpio_fan[8] = { -1, -1, -1, -1, -1, -1, -1, -1 };
|
52 |
|
|
module_param_array(gpio_input,int,NULL,0);
|
53 |
|
|
MODULE_PARM_DESC(gpio_input,"List of GPIO pins (0-16) to program as inputs");
|
54 |
|
|
module_param_array(gpio_output,int,NULL,0);
|
55 |
|
|
MODULE_PARM_DESC(gpio_output,"List of GPIO pins (0-16) to program as "
|
56 |
|
|
"outputs");
|
57 |
|
|
module_param_array(gpio_inverted,int,NULL,0);
|
58 |
|
|
MODULE_PARM_DESC(gpio_inverted,"List of GPIO pins (0-16) to program as "
|
59 |
|
|
"inverted");
|
60 |
|
|
module_param_array(gpio_normal,int,NULL,0);
|
61 |
|
|
MODULE_PARM_DESC(gpio_normal,"List of GPIO pins (0-16) to program as "
|
62 |
|
|
"normal/non-inverted");
|
63 |
|
|
module_param_array(gpio_fan,int,NULL,0);
|
64 |
|
|
MODULE_PARM_DESC(gpio_fan,"List of GPIO pins (0-7) to program as fan tachs");
|
65 |
|
|
|
66 |
|
|
/* Many ADM1026 constants specified below */
|
67 |
|
|
|
68 |
|
|
/* The ADM1026 registers */
|
69 |
|
|
#define ADM1026_REG_CONFIG1 0x00
|
70 |
|
|
#define CFG1_MONITOR 0x01
|
71 |
|
|
#define CFG1_INT_ENABLE 0x02
|
72 |
|
|
#define CFG1_INT_CLEAR 0x04
|
73 |
|
|
#define CFG1_AIN8_9 0x08
|
74 |
|
|
#define CFG1_THERM_HOT 0x10
|
75 |
|
|
#define CFG1_DAC_AFC 0x20
|
76 |
|
|
#define CFG1_PWM_AFC 0x40
|
77 |
|
|
#define CFG1_RESET 0x80
|
78 |
|
|
#define ADM1026_REG_CONFIG2 0x01
|
79 |
|
|
/* CONFIG2 controls FAN0/GPIO0 through FAN7/GPIO7 */
|
80 |
|
|
#define ADM1026_REG_CONFIG3 0x07
|
81 |
|
|
#define CFG3_GPIO16_ENABLE 0x01
|
82 |
|
|
#define CFG3_CI_CLEAR 0x02
|
83 |
|
|
#define CFG3_VREF_250 0x04
|
84 |
|
|
#define CFG3_GPIO16_DIR 0x40
|
85 |
|
|
#define CFG3_GPIO16_POL 0x80
|
86 |
|
|
#define ADM1026_REG_E2CONFIG 0x13
|
87 |
|
|
#define E2CFG_READ 0x01
|
88 |
|
|
#define E2CFG_WRITE 0x02
|
89 |
|
|
#define E2CFG_ERASE 0x04
|
90 |
|
|
#define E2CFG_ROM 0x08
|
91 |
|
|
#define E2CFG_CLK_EXT 0x80
|
92 |
|
|
|
93 |
|
|
/* There are 10 general analog inputs and 7 dedicated inputs
|
94 |
|
|
* They are:
|
95 |
|
|
* 0 - 9 = AIN0 - AIN9
|
96 |
|
|
* 10 = Vbat
|
97 |
|
|
* 11 = 3.3V Standby
|
98 |
|
|
* 12 = 3.3V Main
|
99 |
|
|
* 13 = +5V
|
100 |
|
|
* 14 = Vccp (CPU core voltage)
|
101 |
|
|
* 15 = +12V
|
102 |
|
|
* 16 = -12V
|
103 |
|
|
*/
|
104 |
|
|
static u16 ADM1026_REG_IN[] = {
|
105 |
|
|
0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
|
106 |
|
|
0x36, 0x37, 0x27, 0x29, 0x26, 0x2a,
|
107 |
|
|
0x2b, 0x2c, 0x2d, 0x2e, 0x2f
|
108 |
|
|
};
|
109 |
|
|
static u16 ADM1026_REG_IN_MIN[] = {
|
110 |
|
|
0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d,
|
111 |
|
|
0x5e, 0x5f, 0x6d, 0x49, 0x6b, 0x4a,
|
112 |
|
|
0x4b, 0x4c, 0x4d, 0x4e, 0x4f
|
113 |
|
|
};
|
114 |
|
|
static u16 ADM1026_REG_IN_MAX[] = {
|
115 |
|
|
0x50, 0x51, 0x52, 0x53, 0x54, 0x55,
|
116 |
|
|
0x56, 0x57, 0x6c, 0x41, 0x6a, 0x42,
|
117 |
|
|
0x43, 0x44, 0x45, 0x46, 0x47
|
118 |
|
|
};
|
119 |
|
|
|
120 |
|
|
/* Temperatures are:
|
121 |
|
|
* 0 - Internal
|
122 |
|
|
* 1 - External 1
|
123 |
|
|
* 2 - External 2
|
124 |
|
|
*/
|
125 |
|
|
static u16 ADM1026_REG_TEMP[] = { 0x1f, 0x28, 0x29 };
|
126 |
|
|
static u16 ADM1026_REG_TEMP_MIN[] = { 0x69, 0x48, 0x49 };
|
127 |
|
|
static u16 ADM1026_REG_TEMP_MAX[] = { 0x68, 0x40, 0x41 };
|
128 |
|
|
static u16 ADM1026_REG_TEMP_TMIN[] = { 0x10, 0x11, 0x12 };
|
129 |
|
|
static u16 ADM1026_REG_TEMP_THERM[] = { 0x0d, 0x0e, 0x0f };
|
130 |
|
|
static u16 ADM1026_REG_TEMP_OFFSET[] = { 0x1e, 0x6e, 0x6f };
|
131 |
|
|
|
132 |
|
|
#define ADM1026_REG_FAN(nr) (0x38 + (nr))
|
133 |
|
|
#define ADM1026_REG_FAN_MIN(nr) (0x60 + (nr))
|
134 |
|
|
#define ADM1026_REG_FAN_DIV_0_3 0x02
|
135 |
|
|
#define ADM1026_REG_FAN_DIV_4_7 0x03
|
136 |
|
|
|
137 |
|
|
#define ADM1026_REG_DAC 0x04
|
138 |
|
|
#define ADM1026_REG_PWM 0x05
|
139 |
|
|
|
140 |
|
|
#define ADM1026_REG_GPIO_CFG_0_3 0x08
|
141 |
|
|
#define ADM1026_REG_GPIO_CFG_4_7 0x09
|
142 |
|
|
#define ADM1026_REG_GPIO_CFG_8_11 0x0a
|
143 |
|
|
#define ADM1026_REG_GPIO_CFG_12_15 0x0b
|
144 |
|
|
/* CFG_16 in REG_CFG3 */
|
145 |
|
|
#define ADM1026_REG_GPIO_STATUS_0_7 0x24
|
146 |
|
|
#define ADM1026_REG_GPIO_STATUS_8_15 0x25
|
147 |
|
|
/* STATUS_16 in REG_STATUS4 */
|
148 |
|
|
#define ADM1026_REG_GPIO_MASK_0_7 0x1c
|
149 |
|
|
#define ADM1026_REG_GPIO_MASK_8_15 0x1d
|
150 |
|
|
/* MASK_16 in REG_MASK4 */
|
151 |
|
|
|
152 |
|
|
#define ADM1026_REG_COMPANY 0x16
|
153 |
|
|
#define ADM1026_REG_VERSTEP 0x17
|
154 |
|
|
/* These are the recognized values for the above regs */
|
155 |
|
|
#define ADM1026_COMPANY_ANALOG_DEV 0x41
|
156 |
|
|
#define ADM1026_VERSTEP_GENERIC 0x40
|
157 |
|
|
#define ADM1026_VERSTEP_ADM1026 0x44
|
158 |
|
|
|
159 |
|
|
#define ADM1026_REG_MASK1 0x18
|
160 |
|
|
#define ADM1026_REG_MASK2 0x19
|
161 |
|
|
#define ADM1026_REG_MASK3 0x1a
|
162 |
|
|
#define ADM1026_REG_MASK4 0x1b
|
163 |
|
|
|
164 |
|
|
#define ADM1026_REG_STATUS1 0x20
|
165 |
|
|
#define ADM1026_REG_STATUS2 0x21
|
166 |
|
|
#define ADM1026_REG_STATUS3 0x22
|
167 |
|
|
#define ADM1026_REG_STATUS4 0x23
|
168 |
|
|
|
169 |
|
|
#define ADM1026_FAN_ACTIVATION_TEMP_HYST -6
|
170 |
|
|
#define ADM1026_FAN_CONTROL_TEMP_RANGE 20
|
171 |
|
|
#define ADM1026_PWM_MAX 255
|
172 |
|
|
|
173 |
|
|
/* Conversions. Rounding and limit checking is only done on the TO_REG
|
174 |
|
|
* variants. Note that you should be a bit careful with which arguments
|
175 |
|
|
* these macros are called: arguments may be evaluated more than once.
|
176 |
|
|
*/
|
177 |
|
|
|
178 |
|
|
/* IN are scaled acording to built-in resistors. These are the
|
179 |
|
|
* voltages corresponding to 3/4 of full scale (192 or 0xc0)
|
180 |
|
|
* NOTE: The -12V input needs an additional factor to account
|
181 |
|
|
* for the Vref pullup resistor.
|
182 |
|
|
* NEG12_OFFSET = SCALE * Vref / V-192 - Vref
|
183 |
|
|
* = 13875 * 2.50 / 1.875 - 2500
|
184 |
|
|
* = 16000
|
185 |
|
|
*
|
186 |
|
|
* The values in this table are based on Table II, page 15 of the
|
187 |
|
|
* datasheet.
|
188 |
|
|
*/
|
189 |
|
|
static int adm1026_scaling[] = { /* .001 Volts */
|
190 |
|
|
2250, 2250, 2250, 2250, 2250, 2250,
|
191 |
|
|
1875, 1875, 1875, 1875, 3000, 3330,
|
192 |
|
|
3330, 4995, 2250, 12000, 13875
|
193 |
|
|
};
|
194 |
|
|
#define NEG12_OFFSET 16000
|
195 |
|
|
#define SCALE(val,from,to) (((val)*(to) + ((from)/2))/(from))
|
196 |
|
|
#define INS_TO_REG(n,val) (SENSORS_LIMIT(SCALE(val,adm1026_scaling[n],192),\
|
197 |
|
|
0,255))
|
198 |
|
|
#define INS_FROM_REG(n,val) (SCALE(val,192,adm1026_scaling[n]))
|
199 |
|
|
|
200 |
|
|
/* FAN speed is measured using 22.5kHz clock and counts for 2 pulses
|
201 |
|
|
* and we assume a 2 pulse-per-rev fan tach signal
|
202 |
|
|
* 22500 kHz * 60 (sec/min) * 2 (pulse) / 2 (pulse/rev) == 1350000
|
203 |
|
|
*/
|
204 |
|
|
#define FAN_TO_REG(val,div) ((val)<=0 ? 0xff : SENSORS_LIMIT(1350000/((val)*\
|
205 |
|
|
(div)),1,254))
|
206 |
|
|
#define FAN_FROM_REG(val,div) ((val)==0?-1:(val)==0xff ? 0 : 1350000/((val)*\
|
207 |
|
|
(div)))
|
208 |
|
|
#define DIV_FROM_REG(val) (1<<(val))
|
209 |
|
|
#define DIV_TO_REG(val) ((val)>=8 ? 3 : (val)>=4 ? 2 : (val)>=2 ? 1 : 0)
|
210 |
|
|
|
211 |
|
|
/* Temperature is reported in 1 degC increments */
|
212 |
|
|
#define TEMP_TO_REG(val) (SENSORS_LIMIT(((val)+((val)<0 ? -500 : 500))/1000,\
|
213 |
|
|
-127,127))
|
214 |
|
|
#define TEMP_FROM_REG(val) ((val) * 1000)
|
215 |
|
|
#define OFFSET_TO_REG(val) (SENSORS_LIMIT(((val)+((val)<0 ? -500 : 500))/1000,\
|
216 |
|
|
-127,127))
|
217 |
|
|
#define OFFSET_FROM_REG(val) ((val) * 1000)
|
218 |
|
|
|
219 |
|
|
#define PWM_TO_REG(val) (SENSORS_LIMIT(val,0,255))
|
220 |
|
|
#define PWM_FROM_REG(val) (val)
|
221 |
|
|
|
222 |
|
|
#define PWM_MIN_TO_REG(val) ((val) & 0xf0)
|
223 |
|
|
#define PWM_MIN_FROM_REG(val) (((val) & 0xf0) + ((val) >> 4))
|
224 |
|
|
|
225 |
|
|
/* Analog output is a voltage, and scaled to millivolts. The datasheet
|
226 |
|
|
* indicates that the DAC could be used to drive the fans, but in our
|
227 |
|
|
* example board (Arima HDAMA) it isn't connected to the fans at all.
|
228 |
|
|
*/
|
229 |
|
|
#define DAC_TO_REG(val) (SENSORS_LIMIT(((((val)*255)+500)/2500),0,255))
|
230 |
|
|
#define DAC_FROM_REG(val) (((val)*2500)/255)
|
231 |
|
|
|
232 |
|
|
/* Typically used with systems using a v9.1 VRM spec ? */
|
233 |
|
|
#define ADM1026_INIT_VRM 91
|
234 |
|
|
|
235 |
|
|
/* Chip sampling rates
|
236 |
|
|
*
|
237 |
|
|
* Some sensors are not updated more frequently than once per second
|
238 |
|
|
* so it doesn't make sense to read them more often than that.
|
239 |
|
|
* We cache the results and return the saved data if the driver
|
240 |
|
|
* is called again before a second has elapsed.
|
241 |
|
|
*
|
242 |
|
|
* Also, there is significant configuration data for this chip
|
243 |
|
|
* So, we keep the config data up to date in the cache
|
244 |
|
|
* when it is written and only sample it once every 5 *minutes*
|
245 |
|
|
*/
|
246 |
|
|
#define ADM1026_DATA_INTERVAL (1 * HZ)
|
247 |
|
|
#define ADM1026_CONFIG_INTERVAL (5 * 60 * HZ)
|
248 |
|
|
|
249 |
|
|
/* We allow for multiple chips in a single system.
|
250 |
|
|
*
|
251 |
|
|
* For each registered ADM1026, we need to keep state information
|
252 |
|
|
* at client->data. The adm1026_data structure is dynamically
|
253 |
|
|
* allocated, when a new client structure is allocated. */
|
254 |
|
|
|
255 |
|
|
struct pwm_data {
|
256 |
|
|
u8 pwm;
|
257 |
|
|
u8 enable;
|
258 |
|
|
u8 auto_pwm_min;
|
259 |
|
|
};
|
260 |
|
|
|
261 |
|
|
struct adm1026_data {
|
262 |
|
|
struct i2c_client client;
|
263 |
|
|
struct device *hwmon_dev;
|
264 |
|
|
enum chips type;
|
265 |
|
|
|
266 |
|
|
struct mutex update_lock;
|
267 |
|
|
int valid; /* !=0 if following fields are valid */
|
268 |
|
|
unsigned long last_reading; /* In jiffies */
|
269 |
|
|
unsigned long last_config; /* In jiffies */
|
270 |
|
|
|
271 |
|
|
u8 in[17]; /* Register value */
|
272 |
|
|
u8 in_max[17]; /* Register value */
|
273 |
|
|
u8 in_min[17]; /* Register value */
|
274 |
|
|
s8 temp[3]; /* Register value */
|
275 |
|
|
s8 temp_min[3]; /* Register value */
|
276 |
|
|
s8 temp_max[3]; /* Register value */
|
277 |
|
|
s8 temp_tmin[3]; /* Register value */
|
278 |
|
|
s8 temp_crit[3]; /* Register value */
|
279 |
|
|
s8 temp_offset[3]; /* Register value */
|
280 |
|
|
u8 fan[8]; /* Register value */
|
281 |
|
|
u8 fan_min[8]; /* Register value */
|
282 |
|
|
u8 fan_div[8]; /* Decoded value */
|
283 |
|
|
struct pwm_data pwm1; /* Pwm control values */
|
284 |
|
|
int vid; /* Decoded value */
|
285 |
|
|
u8 vrm; /* VRM version */
|
286 |
|
|
u8 analog_out; /* Register value (DAC) */
|
287 |
|
|
long alarms; /* Register encoding, combined */
|
288 |
|
|
long alarm_mask; /* Register encoding, combined */
|
289 |
|
|
long gpio; /* Register encoding, combined */
|
290 |
|
|
long gpio_mask; /* Register encoding, combined */
|
291 |
|
|
u8 gpio_config[17]; /* Decoded value */
|
292 |
|
|
u8 config1; /* Register value */
|
293 |
|
|
u8 config2; /* Register value */
|
294 |
|
|
u8 config3; /* Register value */
|
295 |
|
|
};
|
296 |
|
|
|
297 |
|
|
static int adm1026_attach_adapter(struct i2c_adapter *adapter);
|
298 |
|
|
static int adm1026_detect(struct i2c_adapter *adapter, int address,
|
299 |
|
|
int kind);
|
300 |
|
|
static int adm1026_detach_client(struct i2c_client *client);
|
301 |
|
|
static int adm1026_read_value(struct i2c_client *client, u8 reg);
|
302 |
|
|
static int adm1026_write_value(struct i2c_client *client, u8 reg, int value);
|
303 |
|
|
static void adm1026_print_gpio(struct i2c_client *client);
|
304 |
|
|
static void adm1026_fixup_gpio(struct i2c_client *client);
|
305 |
|
|
static struct adm1026_data *adm1026_update_device(struct device *dev);
|
306 |
|
|
static void adm1026_init_client(struct i2c_client *client);
|
307 |
|
|
|
308 |
|
|
|
309 |
|
|
static struct i2c_driver adm1026_driver = {
|
310 |
|
|
.driver = {
|
311 |
|
|
.name = "adm1026",
|
312 |
|
|
},
|
313 |
|
|
.attach_adapter = adm1026_attach_adapter,
|
314 |
|
|
.detach_client = adm1026_detach_client,
|
315 |
|
|
};
|
316 |
|
|
|
317 |
|
|
static int adm1026_attach_adapter(struct i2c_adapter *adapter)
|
318 |
|
|
{
|
319 |
|
|
if (!(adapter->class & I2C_CLASS_HWMON)) {
|
320 |
|
|
return 0;
|
321 |
|
|
}
|
322 |
|
|
return i2c_probe(adapter, &addr_data, adm1026_detect);
|
323 |
|
|
}
|
324 |
|
|
|
325 |
|
|
static int adm1026_read_value(struct i2c_client *client, u8 reg)
|
326 |
|
|
{
|
327 |
|
|
int res;
|
328 |
|
|
|
329 |
|
|
if (reg < 0x80) {
|
330 |
|
|
/* "RAM" locations */
|
331 |
|
|
res = i2c_smbus_read_byte_data(client, reg) & 0xff;
|
332 |
|
|
} else {
|
333 |
|
|
/* EEPROM, do nothing */
|
334 |
|
|
res = 0;
|
335 |
|
|
}
|
336 |
|
|
return res;
|
337 |
|
|
}
|
338 |
|
|
|
339 |
|
|
static int adm1026_write_value(struct i2c_client *client, u8 reg, int value)
|
340 |
|
|
{
|
341 |
|
|
int res;
|
342 |
|
|
|
343 |
|
|
if (reg < 0x80) {
|
344 |
|
|
/* "RAM" locations */
|
345 |
|
|
res = i2c_smbus_write_byte_data(client, reg, value);
|
346 |
|
|
} else {
|
347 |
|
|
/* EEPROM, do nothing */
|
348 |
|
|
res = 0;
|
349 |
|
|
}
|
350 |
|
|
return res;
|
351 |
|
|
}
|
352 |
|
|
|
353 |
|
|
static void adm1026_init_client(struct i2c_client *client)
|
354 |
|
|
{
|
355 |
|
|
int value, i;
|
356 |
|
|
struct adm1026_data *data = i2c_get_clientdata(client);
|
357 |
|
|
|
358 |
|
|
dev_dbg(&client->dev, "Initializing device\n");
|
359 |
|
|
/* Read chip config */
|
360 |
|
|
data->config1 = adm1026_read_value(client, ADM1026_REG_CONFIG1);
|
361 |
|
|
data->config2 = adm1026_read_value(client, ADM1026_REG_CONFIG2);
|
362 |
|
|
data->config3 = adm1026_read_value(client, ADM1026_REG_CONFIG3);
|
363 |
|
|
|
364 |
|
|
/* Inform user of chip config */
|
365 |
|
|
dev_dbg(&client->dev, "ADM1026_REG_CONFIG1 is: 0x%02x\n",
|
366 |
|
|
data->config1);
|
367 |
|
|
if ((data->config1 & CFG1_MONITOR) == 0) {
|
368 |
|
|
dev_dbg(&client->dev, "Monitoring not currently "
|
369 |
|
|
"enabled.\n");
|
370 |
|
|
}
|
371 |
|
|
if (data->config1 & CFG1_INT_ENABLE) {
|
372 |
|
|
dev_dbg(&client->dev, "SMBALERT interrupts are "
|
373 |
|
|
"enabled.\n");
|
374 |
|
|
}
|
375 |
|
|
if (data->config1 & CFG1_AIN8_9) {
|
376 |
|
|
dev_dbg(&client->dev, "in8 and in9 enabled. "
|
377 |
|
|
"temp3 disabled.\n");
|
378 |
|
|
} else {
|
379 |
|
|
dev_dbg(&client->dev, "temp3 enabled. in8 and "
|
380 |
|
|
"in9 disabled.\n");
|
381 |
|
|
}
|
382 |
|
|
if (data->config1 & CFG1_THERM_HOT) {
|
383 |
|
|
dev_dbg(&client->dev, "Automatic THERM, PWM, "
|
384 |
|
|
"and temp limits enabled.\n");
|
385 |
|
|
}
|
386 |
|
|
|
387 |
|
|
value = data->config3;
|
388 |
|
|
if (data->config3 & CFG3_GPIO16_ENABLE) {
|
389 |
|
|
dev_dbg(&client->dev, "GPIO16 enabled. THERM "
|
390 |
|
|
"pin disabled.\n");
|
391 |
|
|
} else {
|
392 |
|
|
dev_dbg(&client->dev, "THERM pin enabled. "
|
393 |
|
|
"GPIO16 disabled.\n");
|
394 |
|
|
}
|
395 |
|
|
if (data->config3 & CFG3_VREF_250) {
|
396 |
|
|
dev_dbg(&client->dev, "Vref is 2.50 Volts.\n");
|
397 |
|
|
} else {
|
398 |
|
|
dev_dbg(&client->dev, "Vref is 1.82 Volts.\n");
|
399 |
|
|
}
|
400 |
|
|
/* Read and pick apart the existing GPIO configuration */
|
401 |
|
|
value = 0;
|
402 |
|
|
for (i = 0;i <= 15;++i) {
|
403 |
|
|
if ((i & 0x03) == 0) {
|
404 |
|
|
value = adm1026_read_value(client,
|
405 |
|
|
ADM1026_REG_GPIO_CFG_0_3 + i/4);
|
406 |
|
|
}
|
407 |
|
|
data->gpio_config[i] = value & 0x03;
|
408 |
|
|
value >>= 2;
|
409 |
|
|
}
|
410 |
|
|
data->gpio_config[16] = (data->config3 >> 6) & 0x03;
|
411 |
|
|
|
412 |
|
|
/* ... and then print it */
|
413 |
|
|
adm1026_print_gpio(client);
|
414 |
|
|
|
415 |
|
|
/* If the user asks us to reprogram the GPIO config, then
|
416 |
|
|
* do it now.
|
417 |
|
|
*/
|
418 |
|
|
if (gpio_input[0] != -1 || gpio_output[0] != -1
|
419 |
|
|
|| gpio_inverted[0] != -1 || gpio_normal[0] != -1
|
420 |
|
|
|| gpio_fan[0] != -1) {
|
421 |
|
|
adm1026_fixup_gpio(client);
|
422 |
|
|
}
|
423 |
|
|
|
424 |
|
|
/* WE INTENTIONALLY make no changes to the limits,
|
425 |
|
|
* offsets, pwms, fans and zones. If they were
|
426 |
|
|
* configured, we don't want to mess with them.
|
427 |
|
|
* If they weren't, the default is 100% PWM, no
|
428 |
|
|
* control and will suffice until 'sensors -s'
|
429 |
|
|
* can be run by the user. We DO set the default
|
430 |
|
|
* value for pwm1.auto_pwm_min to its maximum
|
431 |
|
|
* so that enabling automatic pwm fan control
|
432 |
|
|
* without first setting a value for pwm1.auto_pwm_min
|
433 |
|
|
* will not result in potentially dangerous fan speed decrease.
|
434 |
|
|
*/
|
435 |
|
|
data->pwm1.auto_pwm_min=255;
|
436 |
|
|
/* Start monitoring */
|
437 |
|
|
value = adm1026_read_value(client, ADM1026_REG_CONFIG1);
|
438 |
|
|
/* Set MONITOR, clear interrupt acknowledge and s/w reset */
|
439 |
|
|
value = (value | CFG1_MONITOR) & (~CFG1_INT_CLEAR & ~CFG1_RESET);
|
440 |
|
|
dev_dbg(&client->dev, "Setting CONFIG to: 0x%02x\n", value);
|
441 |
|
|
data->config1 = value;
|
442 |
|
|
adm1026_write_value(client, ADM1026_REG_CONFIG1, value);
|
443 |
|
|
|
444 |
|
|
/* initialize fan_div[] to hardware defaults */
|
445 |
|
|
value = adm1026_read_value(client, ADM1026_REG_FAN_DIV_0_3) |
|
446 |
|
|
(adm1026_read_value(client, ADM1026_REG_FAN_DIV_4_7) << 8);
|
447 |
|
|
for (i = 0;i <= 7;++i) {
|
448 |
|
|
data->fan_div[i] = DIV_FROM_REG(value & 0x03);
|
449 |
|
|
value >>= 2;
|
450 |
|
|
}
|
451 |
|
|
}
|
452 |
|
|
|
453 |
|
|
static void adm1026_print_gpio(struct i2c_client *client)
|
454 |
|
|
{
|
455 |
|
|
struct adm1026_data *data = i2c_get_clientdata(client);
|
456 |
|
|
int i;
|
457 |
|
|
|
458 |
|
|
dev_dbg(&client->dev, "GPIO config is:");
|
459 |
|
|
for (i = 0;i <= 7;++i) {
|
460 |
|
|
if (data->config2 & (1 << i)) {
|
461 |
|
|
dev_dbg(&client->dev, "\t%sGP%s%d\n",
|
462 |
|
|
data->gpio_config[i] & 0x02 ? "" : "!",
|
463 |
|
|
data->gpio_config[i] & 0x01 ? "OUT" : "IN",
|
464 |
|
|
i);
|
465 |
|
|
} else {
|
466 |
|
|
dev_dbg(&client->dev, "\tFAN%d\n", i);
|
467 |
|
|
}
|
468 |
|
|
}
|
469 |
|
|
for (i = 8;i <= 15;++i) {
|
470 |
|
|
dev_dbg(&client->dev, "\t%sGP%s%d\n",
|
471 |
|
|
data->gpio_config[i] & 0x02 ? "" : "!",
|
472 |
|
|
data->gpio_config[i] & 0x01 ? "OUT" : "IN",
|
473 |
|
|
i);
|
474 |
|
|
}
|
475 |
|
|
if (data->config3 & CFG3_GPIO16_ENABLE) {
|
476 |
|
|
dev_dbg(&client->dev, "\t%sGP%s16\n",
|
477 |
|
|
data->gpio_config[16] & 0x02 ? "" : "!",
|
478 |
|
|
data->gpio_config[16] & 0x01 ? "OUT" : "IN");
|
479 |
|
|
} else {
|
480 |
|
|
/* GPIO16 is THERM */
|
481 |
|
|
dev_dbg(&client->dev, "\tTHERM\n");
|
482 |
|
|
}
|
483 |
|
|
}
|
484 |
|
|
|
485 |
|
|
static void adm1026_fixup_gpio(struct i2c_client *client)
|
486 |
|
|
{
|
487 |
|
|
struct adm1026_data *data = i2c_get_clientdata(client);
|
488 |
|
|
int i;
|
489 |
|
|
int value;
|
490 |
|
|
|
491 |
|
|
/* Make the changes requested. */
|
492 |
|
|
/* We may need to unlock/stop monitoring or soft-reset the
|
493 |
|
|
* chip before we can make changes. This hasn't been
|
494 |
|
|
* tested much. FIXME
|
495 |
|
|
*/
|
496 |
|
|
|
497 |
|
|
/* Make outputs */
|
498 |
|
|
for (i = 0;i <= 16;++i) {
|
499 |
|
|
if (gpio_output[i] >= 0 && gpio_output[i] <= 16) {
|
500 |
|
|
data->gpio_config[gpio_output[i]] |= 0x01;
|
501 |
|
|
}
|
502 |
|
|
/* if GPIO0-7 is output, it isn't a FAN tach */
|
503 |
|
|
if (gpio_output[i] >= 0 && gpio_output[i] <= 7) {
|
504 |
|
|
data->config2 |= 1 << gpio_output[i];
|
505 |
|
|
}
|
506 |
|
|
}
|
507 |
|
|
|
508 |
|
|
/* Input overrides output */
|
509 |
|
|
for (i = 0;i <= 16;++i) {
|
510 |
|
|
if (gpio_input[i] >= 0 && gpio_input[i] <= 16) {
|
511 |
|
|
data->gpio_config[gpio_input[i]] &= ~ 0x01;
|
512 |
|
|
}
|
513 |
|
|
/* if GPIO0-7 is input, it isn't a FAN tach */
|
514 |
|
|
if (gpio_input[i] >= 0 && gpio_input[i] <= 7) {
|
515 |
|
|
data->config2 |= 1 << gpio_input[i];
|
516 |
|
|
}
|
517 |
|
|
}
|
518 |
|
|
|
519 |
|
|
/* Inverted */
|
520 |
|
|
for (i = 0;i <= 16;++i) {
|
521 |
|
|
if (gpio_inverted[i] >= 0 && gpio_inverted[i] <= 16) {
|
522 |
|
|
data->gpio_config[gpio_inverted[i]] &= ~ 0x02;
|
523 |
|
|
}
|
524 |
|
|
}
|
525 |
|
|
|
526 |
|
|
/* Normal overrides inverted */
|
527 |
|
|
for (i = 0;i <= 16;++i) {
|
528 |
|
|
if (gpio_normal[i] >= 0 && gpio_normal[i] <= 16) {
|
529 |
|
|
data->gpio_config[gpio_normal[i]] |= 0x02;
|
530 |
|
|
}
|
531 |
|
|
}
|
532 |
|
|
|
533 |
|
|
/* Fan overrides input and output */
|
534 |
|
|
for (i = 0;i <= 7;++i) {
|
535 |
|
|
if (gpio_fan[i] >= 0 && gpio_fan[i] <= 7) {
|
536 |
|
|
data->config2 &= ~(1 << gpio_fan[i]);
|
537 |
|
|
}
|
538 |
|
|
}
|
539 |
|
|
|
540 |
|
|
/* Write new configs to registers */
|
541 |
|
|
adm1026_write_value(client, ADM1026_REG_CONFIG2, data->config2);
|
542 |
|
|
data->config3 = (data->config3 & 0x3f)
|
543 |
|
|
| ((data->gpio_config[16] & 0x03) << 6);
|
544 |
|
|
adm1026_write_value(client, ADM1026_REG_CONFIG3, data->config3);
|
545 |
|
|
for (i = 15, value = 0;i >= 0;--i) {
|
546 |
|
|
value <<= 2;
|
547 |
|
|
value |= data->gpio_config[i] & 0x03;
|
548 |
|
|
if ((i & 0x03) == 0) {
|
549 |
|
|
adm1026_write_value(client,
|
550 |
|
|
ADM1026_REG_GPIO_CFG_0_3 + i/4,
|
551 |
|
|
value);
|
552 |
|
|
value = 0;
|
553 |
|
|
}
|
554 |
|
|
}
|
555 |
|
|
|
556 |
|
|
/* Print the new config */
|
557 |
|
|
adm1026_print_gpio(client);
|
558 |
|
|
}
|
559 |
|
|
|
560 |
|
|
|
561 |
|
|
static struct adm1026_data *adm1026_update_device(struct device *dev)
|
562 |
|
|
{
|
563 |
|
|
struct i2c_client *client = to_i2c_client(dev);
|
564 |
|
|
struct adm1026_data *data = i2c_get_clientdata(client);
|
565 |
|
|
int i;
|
566 |
|
|
long value, alarms, gpio;
|
567 |
|
|
|
568 |
|
|
mutex_lock(&data->update_lock);
|
569 |
|
|
if (!data->valid
|
570 |
|
|
|| time_after(jiffies, data->last_reading + ADM1026_DATA_INTERVAL)) {
|
571 |
|
|
/* Things that change quickly */
|
572 |
|
|
dev_dbg(&client->dev,"Reading sensor values\n");
|
573 |
|
|
for (i = 0;i <= 16;++i) {
|
574 |
|
|
data->in[i] =
|
575 |
|
|
adm1026_read_value(client, ADM1026_REG_IN[i]);
|
576 |
|
|
}
|
577 |
|
|
|
578 |
|
|
for (i = 0;i <= 7;++i) {
|
579 |
|
|
data->fan[i] =
|
580 |
|
|
adm1026_read_value(client, ADM1026_REG_FAN(i));
|
581 |
|
|
}
|
582 |
|
|
|
583 |
|
|
for (i = 0;i <= 2;++i) {
|
584 |
|
|
/* NOTE: temp[] is s8 and we assume 2's complement
|
585 |
|
|
* "conversion" in the assignment */
|
586 |
|
|
data->temp[i] =
|
587 |
|
|
adm1026_read_value(client, ADM1026_REG_TEMP[i]);
|
588 |
|
|
}
|
589 |
|
|
|
590 |
|
|
data->pwm1.pwm = adm1026_read_value(client,
|
591 |
|
|
ADM1026_REG_PWM);
|
592 |
|
|
data->analog_out = adm1026_read_value(client,
|
593 |
|
|
ADM1026_REG_DAC);
|
594 |
|
|
/* GPIO16 is MSbit of alarms, move it to gpio */
|
595 |
|
|
alarms = adm1026_read_value(client, ADM1026_REG_STATUS4);
|
596 |
|
|
gpio = alarms & 0x80 ? 0x0100 : 0; /* GPIO16 */
|
597 |
|
|
alarms &= 0x7f;
|
598 |
|
|
alarms <<= 8;
|
599 |
|
|
alarms |= adm1026_read_value(client, ADM1026_REG_STATUS3);
|
600 |
|
|
alarms <<= 8;
|
601 |
|
|
alarms |= adm1026_read_value(client, ADM1026_REG_STATUS2);
|
602 |
|
|
alarms <<= 8;
|
603 |
|
|
alarms |= adm1026_read_value(client, ADM1026_REG_STATUS1);
|
604 |
|
|
data->alarms = alarms;
|
605 |
|
|
|
606 |
|
|
/* Read the GPIO values */
|
607 |
|
|
gpio |= adm1026_read_value(client,
|
608 |
|
|
ADM1026_REG_GPIO_STATUS_8_15);
|
609 |
|
|
gpio <<= 8;
|
610 |
|
|
gpio |= adm1026_read_value(client,
|
611 |
|
|
ADM1026_REG_GPIO_STATUS_0_7);
|
612 |
|
|
data->gpio = gpio;
|
613 |
|
|
|
614 |
|
|
data->last_reading = jiffies;
|
615 |
|
|
}; /* last_reading */
|
616 |
|
|
|
617 |
|
|
if (!data->valid ||
|
618 |
|
|
time_after(jiffies, data->last_config + ADM1026_CONFIG_INTERVAL)) {
|
619 |
|
|
/* Things that don't change often */
|
620 |
|
|
dev_dbg(&client->dev, "Reading config values\n");
|
621 |
|
|
for (i = 0;i <= 16;++i) {
|
622 |
|
|
data->in_min[i] = adm1026_read_value(client,
|
623 |
|
|
ADM1026_REG_IN_MIN[i]);
|
624 |
|
|
data->in_max[i] = adm1026_read_value(client,
|
625 |
|
|
ADM1026_REG_IN_MAX[i]);
|
626 |
|
|
}
|
627 |
|
|
|
628 |
|
|
value = adm1026_read_value(client, ADM1026_REG_FAN_DIV_0_3)
|
629 |
|
|
| (adm1026_read_value(client, ADM1026_REG_FAN_DIV_4_7)
|
630 |
|
|
<< 8);
|
631 |
|
|
for (i = 0;i <= 7;++i) {
|
632 |
|
|
data->fan_min[i] = adm1026_read_value(client,
|
633 |
|
|
ADM1026_REG_FAN_MIN(i));
|
634 |
|
|
data->fan_div[i] = DIV_FROM_REG(value & 0x03);
|
635 |
|
|
value >>= 2;
|
636 |
|
|
}
|
637 |
|
|
|
638 |
|
|
for (i = 0; i <= 2; ++i) {
|
639 |
|
|
/* NOTE: temp_xxx[] are s8 and we assume 2's
|
640 |
|
|
* complement "conversion" in the assignment
|
641 |
|
|
*/
|
642 |
|
|
data->temp_min[i] = adm1026_read_value(client,
|
643 |
|
|
ADM1026_REG_TEMP_MIN[i]);
|
644 |
|
|
data->temp_max[i] = adm1026_read_value(client,
|
645 |
|
|
ADM1026_REG_TEMP_MAX[i]);
|
646 |
|
|
data->temp_tmin[i] = adm1026_read_value(client,
|
647 |
|
|
ADM1026_REG_TEMP_TMIN[i]);
|
648 |
|
|
data->temp_crit[i] = adm1026_read_value(client,
|
649 |
|
|
ADM1026_REG_TEMP_THERM[i]);
|
650 |
|
|
data->temp_offset[i] = adm1026_read_value(client,
|
651 |
|
|
ADM1026_REG_TEMP_OFFSET[i]);
|
652 |
|
|
}
|
653 |
|
|
|
654 |
|
|
/* Read the STATUS/alarm masks */
|
655 |
|
|
alarms = adm1026_read_value(client, ADM1026_REG_MASK4);
|
656 |
|
|
gpio = alarms & 0x80 ? 0x0100 : 0; /* GPIO16 */
|
657 |
|
|
alarms = (alarms & 0x7f) << 8;
|
658 |
|
|
alarms |= adm1026_read_value(client, ADM1026_REG_MASK3);
|
659 |
|
|
alarms <<= 8;
|
660 |
|
|
alarms |= adm1026_read_value(client, ADM1026_REG_MASK2);
|
661 |
|
|
alarms <<= 8;
|
662 |
|
|
alarms |= adm1026_read_value(client, ADM1026_REG_MASK1);
|
663 |
|
|
data->alarm_mask = alarms;
|
664 |
|
|
|
665 |
|
|
/* Read the GPIO values */
|
666 |
|
|
gpio |= adm1026_read_value(client,
|
667 |
|
|
ADM1026_REG_GPIO_MASK_8_15);
|
668 |
|
|
gpio <<= 8;
|
669 |
|
|
gpio |= adm1026_read_value(client, ADM1026_REG_GPIO_MASK_0_7);
|
670 |
|
|
data->gpio_mask = gpio;
|
671 |
|
|
|
672 |
|
|
/* Read various values from CONFIG1 */
|
673 |
|
|
data->config1 = adm1026_read_value(client,
|
674 |
|
|
ADM1026_REG_CONFIG1);
|
675 |
|
|
if (data->config1 & CFG1_PWM_AFC) {
|
676 |
|
|
data->pwm1.enable = 2;
|
677 |
|
|
data->pwm1.auto_pwm_min =
|
678 |
|
|
PWM_MIN_FROM_REG(data->pwm1.pwm);
|
679 |
|
|
}
|
680 |
|
|
/* Read the GPIO config */
|
681 |
|
|
data->config2 = adm1026_read_value(client,
|
682 |
|
|
ADM1026_REG_CONFIG2);
|
683 |
|
|
data->config3 = adm1026_read_value(client,
|
684 |
|
|
ADM1026_REG_CONFIG3);
|
685 |
|
|
data->gpio_config[16] = (data->config3 >> 6) & 0x03;
|
686 |
|
|
|
687 |
|
|
value = 0;
|
688 |
|
|
for (i = 0;i <= 15;++i) {
|
689 |
|
|
if ((i & 0x03) == 0) {
|
690 |
|
|
value = adm1026_read_value(client,
|
691 |
|
|
ADM1026_REG_GPIO_CFG_0_3 + i/4);
|
692 |
|
|
}
|
693 |
|
|
data->gpio_config[i] = value & 0x03;
|
694 |
|
|
value >>= 2;
|
695 |
|
|
}
|
696 |
|
|
|
697 |
|
|
data->last_config = jiffies;
|
698 |
|
|
}; /* last_config */
|
699 |
|
|
|
700 |
|
|
dev_dbg(&client->dev, "Setting VID from GPIO11-15.\n");
|
701 |
|
|
data->vid = (data->gpio >> 11) & 0x1f;
|
702 |
|
|
data->valid = 1;
|
703 |
|
|
mutex_unlock(&data->update_lock);
|
704 |
|
|
return data;
|
705 |
|
|
}
|
706 |
|
|
|
707 |
|
|
static ssize_t show_in(struct device *dev, struct device_attribute *attr,
|
708 |
|
|
char *buf)
|
709 |
|
|
{
|
710 |
|
|
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
|
711 |
|
|
int nr = sensor_attr->index;
|
712 |
|
|
struct adm1026_data *data = adm1026_update_device(dev);
|
713 |
|
|
return sprintf(buf,"%d\n", INS_FROM_REG(nr, data->in[nr]));
|
714 |
|
|
}
|
715 |
|
|
static ssize_t show_in_min(struct device *dev, struct device_attribute *attr,
|
716 |
|
|
char *buf)
|
717 |
|
|
{
|
718 |
|
|
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
|
719 |
|
|
int nr = sensor_attr->index;
|
720 |
|
|
struct adm1026_data *data = adm1026_update_device(dev);
|
721 |
|
|
return sprintf(buf,"%d\n", INS_FROM_REG(nr, data->in_min[nr]));
|
722 |
|
|
}
|
723 |
|
|
static ssize_t set_in_min(struct device *dev, struct device_attribute *attr,
|
724 |
|
|
const char *buf, size_t count)
|
725 |
|
|
{
|
726 |
|
|
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
|
727 |
|
|
int nr = sensor_attr->index;
|
728 |
|
|
struct i2c_client *client = to_i2c_client(dev);
|
729 |
|
|
struct adm1026_data *data = i2c_get_clientdata(client);
|
730 |
|
|
int val = simple_strtol(buf, NULL, 10);
|
731 |
|
|
|
732 |
|
|
mutex_lock(&data->update_lock);
|
733 |
|
|
data->in_min[nr] = INS_TO_REG(nr, val);
|
734 |
|
|
adm1026_write_value(client, ADM1026_REG_IN_MIN[nr], data->in_min[nr]);
|
735 |
|
|
mutex_unlock(&data->update_lock);
|
736 |
|
|
return count;
|
737 |
|
|
}
|
738 |
|
|
static ssize_t show_in_max(struct device *dev, struct device_attribute *attr,
|
739 |
|
|
char *buf)
|
740 |
|
|
{
|
741 |
|
|
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
|
742 |
|
|
int nr = sensor_attr->index;
|
743 |
|
|
struct adm1026_data *data = adm1026_update_device(dev);
|
744 |
|
|
return sprintf(buf,"%d\n", INS_FROM_REG(nr, data->in_max[nr]));
|
745 |
|
|
}
|
746 |
|
|
static ssize_t set_in_max(struct device *dev, struct device_attribute *attr,
|
747 |
|
|
const char *buf, size_t count)
|
748 |
|
|
{
|
749 |
|
|
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
|
750 |
|
|
int nr = sensor_attr->index;
|
751 |
|
|
struct i2c_client *client = to_i2c_client(dev);
|
752 |
|
|
struct adm1026_data *data = i2c_get_clientdata(client);
|
753 |
|
|
int val = simple_strtol(buf, NULL, 10);
|
754 |
|
|
|
755 |
|
|
mutex_lock(&data->update_lock);
|
756 |
|
|
data->in_max[nr] = INS_TO_REG(nr, val);
|
757 |
|
|
adm1026_write_value(client, ADM1026_REG_IN_MAX[nr], data->in_max[nr]);
|
758 |
|
|
mutex_unlock(&data->update_lock);
|
759 |
|
|
return count;
|
760 |
|
|
}
|
761 |
|
|
|
762 |
|
|
#define in_reg(offset) \
|
763 |
|
|
static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in, \
|
764 |
|
|
NULL, offset); \
|
765 |
|
|
static SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \
|
766 |
|
|
show_in_min, set_in_min, offset); \
|
767 |
|
|
static SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \
|
768 |
|
|
show_in_max, set_in_max, offset);
|
769 |
|
|
|
770 |
|
|
|
771 |
|
|
in_reg(0);
|
772 |
|
|
in_reg(1);
|
773 |
|
|
in_reg(2);
|
774 |
|
|
in_reg(3);
|
775 |
|
|
in_reg(4);
|
776 |
|
|
in_reg(5);
|
777 |
|
|
in_reg(6);
|
778 |
|
|
in_reg(7);
|
779 |
|
|
in_reg(8);
|
780 |
|
|
in_reg(9);
|
781 |
|
|
in_reg(10);
|
782 |
|
|
in_reg(11);
|
783 |
|
|
in_reg(12);
|
784 |
|
|
in_reg(13);
|
785 |
|
|
in_reg(14);
|
786 |
|
|
in_reg(15);
|
787 |
|
|
|
788 |
|
|
static ssize_t show_in16(struct device *dev, struct device_attribute *attr, char *buf)
|
789 |
|
|
{
|
790 |
|
|
struct adm1026_data *data = adm1026_update_device(dev);
|
791 |
|
|
return sprintf(buf,"%d\n", INS_FROM_REG(16, data->in[16]) -
|
792 |
|
|
NEG12_OFFSET);
|
793 |
|
|
}
|
794 |
|
|
static ssize_t show_in16_min(struct device *dev, struct device_attribute *attr, char *buf)
|
795 |
|
|
{
|
796 |
|
|
struct adm1026_data *data = adm1026_update_device(dev);
|
797 |
|
|
return sprintf(buf,"%d\n", INS_FROM_REG(16, data->in_min[16])
|
798 |
|
|
- NEG12_OFFSET);
|
799 |
|
|
}
|
800 |
|
|
static ssize_t set_in16_min(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
|
801 |
|
|
{
|
802 |
|
|
struct i2c_client *client = to_i2c_client(dev);
|
803 |
|
|
struct adm1026_data *data = i2c_get_clientdata(client);
|
804 |
|
|
int val = simple_strtol(buf, NULL, 10);
|
805 |
|
|
|
806 |
|
|
mutex_lock(&data->update_lock);
|
807 |
|
|
data->in_min[16] = INS_TO_REG(16, val + NEG12_OFFSET);
|
808 |
|
|
adm1026_write_value(client, ADM1026_REG_IN_MIN[16], data->in_min[16]);
|
809 |
|
|
mutex_unlock(&data->update_lock);
|
810 |
|
|
return count;
|
811 |
|
|
}
|
812 |
|
|
static ssize_t show_in16_max(struct device *dev, struct device_attribute *attr, char *buf)
|
813 |
|
|
{
|
814 |
|
|
struct adm1026_data *data = adm1026_update_device(dev);
|
815 |
|
|
return sprintf(buf,"%d\n", INS_FROM_REG(16, data->in_max[16])
|
816 |
|
|
- NEG12_OFFSET);
|
817 |
|
|
}
|
818 |
|
|
static ssize_t set_in16_max(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
|
819 |
|
|
{
|
820 |
|
|
struct i2c_client *client = to_i2c_client(dev);
|
821 |
|
|
struct adm1026_data *data = i2c_get_clientdata(client);
|
822 |
|
|
int val = simple_strtol(buf, NULL, 10);
|
823 |
|
|
|
824 |
|
|
mutex_lock(&data->update_lock);
|
825 |
|
|
data->in_max[16] = INS_TO_REG(16, val+NEG12_OFFSET);
|
826 |
|
|
adm1026_write_value(client, ADM1026_REG_IN_MAX[16], data->in_max[16]);
|
827 |
|
|
mutex_unlock(&data->update_lock);
|
828 |
|
|
return count;
|
829 |
|
|
}
|
830 |
|
|
|
831 |
|
|
static SENSOR_DEVICE_ATTR(in16_input, S_IRUGO, show_in16, NULL, 16);
|
832 |
|
|
static SENSOR_DEVICE_ATTR(in16_min, S_IRUGO | S_IWUSR, show_in16_min, set_in16_min, 16);
|
833 |
|
|
static SENSOR_DEVICE_ATTR(in16_max, S_IRUGO | S_IWUSR, show_in16_max, set_in16_max, 16);
|
834 |
|
|
|
835 |
|
|
|
836 |
|
|
|
837 |
|
|
|
838 |
|
|
/* Now add fan read/write functions */
|
839 |
|
|
|
840 |
|
|
static ssize_t show_fan(struct device *dev, struct device_attribute *attr,
|
841 |
|
|
char *buf)
|
842 |
|
|
{
|
843 |
|
|
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
|
844 |
|
|
int nr = sensor_attr->index;
|
845 |
|
|
struct adm1026_data *data = adm1026_update_device(dev);
|
846 |
|
|
return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan[nr],
|
847 |
|
|
data->fan_div[nr]));
|
848 |
|
|
}
|
849 |
|
|
static ssize_t show_fan_min(struct device *dev, struct device_attribute *attr,
|
850 |
|
|
char *buf)
|
851 |
|
|
{
|
852 |
|
|
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
|
853 |
|
|
int nr = sensor_attr->index;
|
854 |
|
|
struct adm1026_data *data = adm1026_update_device(dev);
|
855 |
|
|
return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan_min[nr],
|
856 |
|
|
data->fan_div[nr]));
|
857 |
|
|
}
|
858 |
|
|
static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
|
859 |
|
|
const char *buf, size_t count)
|
860 |
|
|
{
|
861 |
|
|
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
|
862 |
|
|
int nr = sensor_attr->index;
|
863 |
|
|
struct i2c_client *client = to_i2c_client(dev);
|
864 |
|
|
struct adm1026_data *data = i2c_get_clientdata(client);
|
865 |
|
|
int val = simple_strtol(buf, NULL, 10);
|
866 |
|
|
|
867 |
|
|
mutex_lock(&data->update_lock);
|
868 |
|
|
data->fan_min[nr] = FAN_TO_REG(val, data->fan_div[nr]);
|
869 |
|
|
adm1026_write_value(client, ADM1026_REG_FAN_MIN(nr),
|
870 |
|
|
data->fan_min[nr]);
|
871 |
|
|
mutex_unlock(&data->update_lock);
|
872 |
|
|
return count;
|
873 |
|
|
}
|
874 |
|
|
|
875 |
|
|
#define fan_offset(offset) \
|
876 |
|
|
static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan, NULL, \
|
877 |
|
|
offset - 1); \
|
878 |
|
|
static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
|
879 |
|
|
show_fan_min, set_fan_min, offset - 1);
|
880 |
|
|
|
881 |
|
|
fan_offset(1);
|
882 |
|
|
fan_offset(2);
|
883 |
|
|
fan_offset(3);
|
884 |
|
|
fan_offset(4);
|
885 |
|
|
fan_offset(5);
|
886 |
|
|
fan_offset(6);
|
887 |
|
|
fan_offset(7);
|
888 |
|
|
fan_offset(8);
|
889 |
|
|
|
890 |
|
|
/* Adjust fan_min to account for new fan divisor */
|
891 |
|
|
static void fixup_fan_min(struct device *dev, int fan, int old_div)
|
892 |
|
|
{
|
893 |
|
|
struct i2c_client *client = to_i2c_client(dev);
|
894 |
|
|
struct adm1026_data *data = i2c_get_clientdata(client);
|
895 |
|
|
int new_min;
|
896 |
|
|
int new_div = data->fan_div[fan];
|
897 |
|
|
|
898 |
|
|
/* 0 and 0xff are special. Don't adjust them */
|
899 |
|
|
if (data->fan_min[fan] == 0 || data->fan_min[fan] == 0xff) {
|
900 |
|
|
return;
|
901 |
|
|
}
|
902 |
|
|
|
903 |
|
|
new_min = data->fan_min[fan] * old_div / new_div;
|
904 |
|
|
new_min = SENSORS_LIMIT(new_min, 1, 254);
|
905 |
|
|
data->fan_min[fan] = new_min;
|
906 |
|
|
adm1026_write_value(client, ADM1026_REG_FAN_MIN(fan), new_min);
|
907 |
|
|
}
|
908 |
|
|
|
909 |
|
|
/* Now add fan_div read/write functions */
|
910 |
|
|
static ssize_t show_fan_div(struct device *dev, struct device_attribute *attr,
|
911 |
|
|
char *buf)
|
912 |
|
|
{
|
913 |
|
|
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
|
914 |
|
|
int nr = sensor_attr->index;
|
915 |
|
|
struct adm1026_data *data = adm1026_update_device(dev);
|
916 |
|
|
return sprintf(buf,"%d\n", data->fan_div[nr]);
|
917 |
|
|
}
|
918 |
|
|
static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
|
919 |
|
|
const char *buf, size_t count)
|
920 |
|
|
{
|
921 |
|
|
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
|
922 |
|
|
int nr = sensor_attr->index;
|
923 |
|
|
struct i2c_client *client = to_i2c_client(dev);
|
924 |
|
|
struct adm1026_data *data = i2c_get_clientdata(client);
|
925 |
|
|
int val,orig_div,new_div,shift;
|
926 |
|
|
|
927 |
|
|
val = simple_strtol(buf, NULL, 10);
|
928 |
|
|
new_div = DIV_TO_REG(val);
|
929 |
|
|
if (new_div == 0) {
|
930 |
|
|
return -EINVAL;
|
931 |
|
|
}
|
932 |
|
|
mutex_lock(&data->update_lock);
|
933 |
|
|
orig_div = data->fan_div[nr];
|
934 |
|
|
data->fan_div[nr] = DIV_FROM_REG(new_div);
|
935 |
|
|
|
936 |
|
|
if (nr < 4) { /* 0 <= nr < 4 */
|
937 |
|
|
shift = 2 * nr;
|
938 |
|
|
adm1026_write_value(client, ADM1026_REG_FAN_DIV_0_3,
|
939 |
|
|
((DIV_TO_REG(orig_div) & (~(0x03 << shift))) |
|
940 |
|
|
(new_div << shift)));
|
941 |
|
|
} else { /* 3 < nr < 8 */
|
942 |
|
|
shift = 2 * (nr - 4);
|
943 |
|
|
adm1026_write_value(client, ADM1026_REG_FAN_DIV_4_7,
|
944 |
|
|
((DIV_TO_REG(orig_div) & (~(0x03 << (2 * shift)))) |
|
945 |
|
|
(new_div << shift)));
|
946 |
|
|
}
|
947 |
|
|
|
948 |
|
|
if (data->fan_div[nr] != orig_div) {
|
949 |
|
|
fixup_fan_min(dev,nr,orig_div);
|
950 |
|
|
}
|
951 |
|
|
mutex_unlock(&data->update_lock);
|
952 |
|
|
return count;
|
953 |
|
|
}
|
954 |
|
|
|
955 |
|
|
#define fan_offset_div(offset) \
|
956 |
|
|
static SENSOR_DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \
|
957 |
|
|
show_fan_div, set_fan_div, offset - 1);
|
958 |
|
|
|
959 |
|
|
fan_offset_div(1);
|
960 |
|
|
fan_offset_div(2);
|
961 |
|
|
fan_offset_div(3);
|
962 |
|
|
fan_offset_div(4);
|
963 |
|
|
fan_offset_div(5);
|
964 |
|
|
fan_offset_div(6);
|
965 |
|
|
fan_offset_div(7);
|
966 |
|
|
fan_offset_div(8);
|
967 |
|
|
|
968 |
|
|
/* Temps */
|
969 |
|
|
static ssize_t show_temp(struct device *dev, struct device_attribute *attr,
|
970 |
|
|
char *buf)
|
971 |
|
|
{
|
972 |
|
|
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
|
973 |
|
|
int nr = sensor_attr->index;
|
974 |
|
|
struct adm1026_data *data = adm1026_update_device(dev);
|
975 |
|
|
return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp[nr]));
|
976 |
|
|
}
|
977 |
|
|
static ssize_t show_temp_min(struct device *dev, struct device_attribute *attr,
|
978 |
|
|
char *buf)
|
979 |
|
|
{
|
980 |
|
|
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
|
981 |
|
|
int nr = sensor_attr->index;
|
982 |
|
|
struct adm1026_data *data = adm1026_update_device(dev);
|
983 |
|
|
return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp_min[nr]));
|
984 |
|
|
}
|
985 |
|
|
static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr,
|
986 |
|
|
const char *buf, size_t count)
|
987 |
|
|
{
|
988 |
|
|
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
|
989 |
|
|
int nr = sensor_attr->index;
|
990 |
|
|
struct i2c_client *client = to_i2c_client(dev);
|
991 |
|
|
struct adm1026_data *data = i2c_get_clientdata(client);
|
992 |
|
|
int val = simple_strtol(buf, NULL, 10);
|
993 |
|
|
|
994 |
|
|
mutex_lock(&data->update_lock);
|
995 |
|
|
data->temp_min[nr] = TEMP_TO_REG(val);
|
996 |
|
|
adm1026_write_value(client, ADM1026_REG_TEMP_MIN[nr],
|
997 |
|
|
data->temp_min[nr]);
|
998 |
|
|
mutex_unlock(&data->update_lock);
|
999 |
|
|
return count;
|
1000 |
|
|
}
|
1001 |
|
|
static ssize_t show_temp_max(struct device *dev, struct device_attribute *attr,
|
1002 |
|
|
char *buf)
|
1003 |
|
|
{
|
1004 |
|
|
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
|
1005 |
|
|
int nr = sensor_attr->index;
|
1006 |
|
|
struct adm1026_data *data = adm1026_update_device(dev);
|
1007 |
|
|
return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp_max[nr]));
|
1008 |
|
|
}
|
1009 |
|
|
static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
|
1010 |
|
|
const char *buf, size_t count)
|
1011 |
|
|
{
|
1012 |
|
|
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
|
1013 |
|
|
int nr = sensor_attr->index;
|
1014 |
|
|
struct i2c_client *client = to_i2c_client(dev);
|
1015 |
|
|
struct adm1026_data *data = i2c_get_clientdata(client);
|
1016 |
|
|
int val = simple_strtol(buf, NULL, 10);
|
1017 |
|
|
|
1018 |
|
|
mutex_lock(&data->update_lock);
|
1019 |
|
|
data->temp_max[nr] = TEMP_TO_REG(val);
|
1020 |
|
|
adm1026_write_value(client, ADM1026_REG_TEMP_MAX[nr],
|
1021 |
|
|
data->temp_max[nr]);
|
1022 |
|
|
mutex_unlock(&data->update_lock);
|
1023 |
|
|
return count;
|
1024 |
|
|
}
|
1025 |
|
|
|
1026 |
|
|
#define temp_reg(offset) \
|
1027 |
|
|
static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp, \
|
1028 |
|
|
NULL, offset - 1); \
|
1029 |
|
|
static SENSOR_DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR, \
|
1030 |
|
|
show_temp_min, set_temp_min, offset - 1); \
|
1031 |
|
|
static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \
|
1032 |
|
|
show_temp_max, set_temp_max, offset - 1);
|
1033 |
|
|
|
1034 |
|
|
|
1035 |
|
|
temp_reg(1);
|
1036 |
|
|
temp_reg(2);
|
1037 |
|
|
temp_reg(3);
|
1038 |
|
|
|
1039 |
|
|
static ssize_t show_temp_offset(struct device *dev,
|
1040 |
|
|
struct device_attribute *attr, char *buf)
|
1041 |
|
|
{
|
1042 |
|
|
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
|
1043 |
|
|
int nr = sensor_attr->index;
|
1044 |
|
|
struct adm1026_data *data = adm1026_update_device(dev);
|
1045 |
|
|
return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp_offset[nr]));
|
1046 |
|
|
}
|
1047 |
|
|
static ssize_t set_temp_offset(struct device *dev,
|
1048 |
|
|
struct device_attribute *attr, const char *buf,
|
1049 |
|
|
size_t count)
|
1050 |
|
|
{
|
1051 |
|
|
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
|
1052 |
|
|
int nr = sensor_attr->index;
|
1053 |
|
|
struct i2c_client *client = to_i2c_client(dev);
|
1054 |
|
|
struct adm1026_data *data = i2c_get_clientdata(client);
|
1055 |
|
|
int val = simple_strtol(buf, NULL, 10);
|
1056 |
|
|
|
1057 |
|
|
mutex_lock(&data->update_lock);
|
1058 |
|
|
data->temp_offset[nr] = TEMP_TO_REG(val);
|
1059 |
|
|
adm1026_write_value(client, ADM1026_REG_TEMP_OFFSET[nr],
|
1060 |
|
|
data->temp_offset[nr]);
|
1061 |
|
|
mutex_unlock(&data->update_lock);
|
1062 |
|
|
return count;
|
1063 |
|
|
}
|
1064 |
|
|
|
1065 |
|
|
#define temp_offset_reg(offset) \
|
1066 |
|
|
static SENSOR_DEVICE_ATTR(temp##offset##_offset, S_IRUGO | S_IWUSR, \
|
1067 |
|
|
show_temp_offset, set_temp_offset, offset - 1);
|
1068 |
|
|
|
1069 |
|
|
temp_offset_reg(1);
|
1070 |
|
|
temp_offset_reg(2);
|
1071 |
|
|
temp_offset_reg(3);
|
1072 |
|
|
|
1073 |
|
|
static ssize_t show_temp_auto_point1_temp_hyst(struct device *dev,
|
1074 |
|
|
struct device_attribute *attr, char *buf)
|
1075 |
|
|
{
|
1076 |
|
|
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
|
1077 |
|
|
int nr = sensor_attr->index;
|
1078 |
|
|
struct adm1026_data *data = adm1026_update_device(dev);
|
1079 |
|
|
return sprintf(buf,"%d\n", TEMP_FROM_REG(
|
1080 |
|
|
ADM1026_FAN_ACTIVATION_TEMP_HYST + data->temp_tmin[nr]));
|
1081 |
|
|
}
|
1082 |
|
|
static ssize_t show_temp_auto_point2_temp(struct device *dev,
|
1083 |
|
|
struct device_attribute *attr, char *buf)
|
1084 |
|
|
{
|
1085 |
|
|
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
|
1086 |
|
|
int nr = sensor_attr->index;
|
1087 |
|
|
struct adm1026_data *data = adm1026_update_device(dev);
|
1088 |
|
|
return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp_tmin[nr] +
|
1089 |
|
|
ADM1026_FAN_CONTROL_TEMP_RANGE));
|
1090 |
|
|
}
|
1091 |
|
|
static ssize_t show_temp_auto_point1_temp(struct device *dev,
|
1092 |
|
|
struct device_attribute *attr, char *buf)
|
1093 |
|
|
{
|
1094 |
|
|
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
|
1095 |
|
|
int nr = sensor_attr->index;
|
1096 |
|
|
struct adm1026_data *data = adm1026_update_device(dev);
|
1097 |
|
|
return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp_tmin[nr]));
|
1098 |
|
|
}
|
1099 |
|
|
static ssize_t set_temp_auto_point1_temp(struct device *dev,
|
1100 |
|
|
struct device_attribute *attr, const char *buf, size_t count)
|
1101 |
|
|
{
|
1102 |
|
|
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
|
1103 |
|
|
int nr = sensor_attr->index;
|
1104 |
|
|
struct i2c_client *client = to_i2c_client(dev);
|
1105 |
|
|
struct adm1026_data *data = i2c_get_clientdata(client);
|
1106 |
|
|
int val = simple_strtol(buf, NULL, 10);
|
1107 |
|
|
|
1108 |
|
|
mutex_lock(&data->update_lock);
|
1109 |
|
|
data->temp_tmin[nr] = TEMP_TO_REG(val);
|
1110 |
|
|
adm1026_write_value(client, ADM1026_REG_TEMP_TMIN[nr],
|
1111 |
|
|
data->temp_tmin[nr]);
|
1112 |
|
|
mutex_unlock(&data->update_lock);
|
1113 |
|
|
return count;
|
1114 |
|
|
}
|
1115 |
|
|
|
1116 |
|
|
#define temp_auto_point(offset) \
|
1117 |
|
|
static SENSOR_DEVICE_ATTR(temp##offset##_auto_point1_temp, S_IRUGO | S_IWUSR, \
|
1118 |
|
|
show_temp_auto_point1_temp, set_temp_auto_point1_temp, \
|
1119 |
|
|
offset - 1); \
|
1120 |
|
|
static SENSOR_DEVICE_ATTR(temp##offset##_auto_point1_temp_hyst, S_IRUGO, \
|
1121 |
|
|
show_temp_auto_point1_temp_hyst, NULL, offset - 1); \
|
1122 |
|
|
static SENSOR_DEVICE_ATTR(temp##offset##_auto_point2_temp, S_IRUGO, \
|
1123 |
|
|
show_temp_auto_point2_temp, NULL, offset - 1);
|
1124 |
|
|
|
1125 |
|
|
temp_auto_point(1);
|
1126 |
|
|
temp_auto_point(2);
|
1127 |
|
|
temp_auto_point(3);
|
1128 |
|
|
|
1129 |
|
|
static ssize_t show_temp_crit_enable(struct device *dev,
|
1130 |
|
|
struct device_attribute *attr, char *buf)
|
1131 |
|
|
{
|
1132 |
|
|
struct adm1026_data *data = adm1026_update_device(dev);
|
1133 |
|
|
return sprintf(buf,"%d\n", (data->config1 & CFG1_THERM_HOT) >> 4);
|
1134 |
|
|
}
|
1135 |
|
|
static ssize_t set_temp_crit_enable(struct device *dev,
|
1136 |
|
|
struct device_attribute *attr, const char *buf, size_t count)
|
1137 |
|
|
{
|
1138 |
|
|
struct i2c_client *client = to_i2c_client(dev);
|
1139 |
|
|
struct adm1026_data *data = i2c_get_clientdata(client);
|
1140 |
|
|
int val = simple_strtol(buf, NULL, 10);
|
1141 |
|
|
|
1142 |
|
|
if ((val == 1) || (val==0)) {
|
1143 |
|
|
mutex_lock(&data->update_lock);
|
1144 |
|
|
data->config1 = (data->config1 & ~CFG1_THERM_HOT) | (val << 4);
|
1145 |
|
|
adm1026_write_value(client, ADM1026_REG_CONFIG1,
|
1146 |
|
|
data->config1);
|
1147 |
|
|
mutex_unlock(&data->update_lock);
|
1148 |
|
|
}
|
1149 |
|
|
return count;
|
1150 |
|
|
}
|
1151 |
|
|
|
1152 |
|
|
#define temp_crit_enable(offset) \
|
1153 |
|
|
static DEVICE_ATTR(temp##offset##_crit_enable, S_IRUGO | S_IWUSR, \
|
1154 |
|
|
show_temp_crit_enable, set_temp_crit_enable);
|
1155 |
|
|
|
1156 |
|
|
temp_crit_enable(1);
|
1157 |
|
|
temp_crit_enable(2);
|
1158 |
|
|
temp_crit_enable(3);
|
1159 |
|
|
|
1160 |
|
|
static ssize_t show_temp_crit(struct device *dev,
|
1161 |
|
|
struct device_attribute *attr, char *buf)
|
1162 |
|
|
{
|
1163 |
|
|
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
|
1164 |
|
|
int nr = sensor_attr->index;
|
1165 |
|
|
struct adm1026_data *data = adm1026_update_device(dev);
|
1166 |
|
|
return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp_crit[nr]));
|
1167 |
|
|
}
|
1168 |
|
|
static ssize_t set_temp_crit(struct device *dev, struct device_attribute *attr,
|
1169 |
|
|
const char *buf, size_t count)
|
1170 |
|
|
{
|
1171 |
|
|
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
|
1172 |
|
|
int nr = sensor_attr->index;
|
1173 |
|
|
struct i2c_client *client = to_i2c_client(dev);
|
1174 |
|
|
struct adm1026_data *data = i2c_get_clientdata(client);
|
1175 |
|
|
int val = simple_strtol(buf, NULL, 10);
|
1176 |
|
|
|
1177 |
|
|
mutex_lock(&data->update_lock);
|
1178 |
|
|
data->temp_crit[nr] = TEMP_TO_REG(val);
|
1179 |
|
|
adm1026_write_value(client, ADM1026_REG_TEMP_THERM[nr],
|
1180 |
|
|
data->temp_crit[nr]);
|
1181 |
|
|
mutex_unlock(&data->update_lock);
|
1182 |
|
|
return count;
|
1183 |
|
|
}
|
1184 |
|
|
|
1185 |
|
|
#define temp_crit_reg(offset) \
|
1186 |
|
|
static SENSOR_DEVICE_ATTR(temp##offset##_crit, S_IRUGO | S_IWUSR, \
|
1187 |
|
|
show_temp_crit, set_temp_crit, offset - 1);
|
1188 |
|
|
|
1189 |
|
|
temp_crit_reg(1);
|
1190 |
|
|
temp_crit_reg(2);
|
1191 |
|
|
temp_crit_reg(3);
|
1192 |
|
|
|
1193 |
|
|
static ssize_t show_analog_out_reg(struct device *dev, struct device_attribute *attr, char *buf)
|
1194 |
|
|
{
|
1195 |
|
|
struct adm1026_data *data = adm1026_update_device(dev);
|
1196 |
|
|
return sprintf(buf,"%d\n", DAC_FROM_REG(data->analog_out));
|
1197 |
|
|
}
|
1198 |
|
|
static ssize_t set_analog_out_reg(struct device *dev, struct device_attribute *attr, const char *buf,
|
1199 |
|
|
size_t count)
|
1200 |
|
|
{
|
1201 |
|
|
struct i2c_client *client = to_i2c_client(dev);
|
1202 |
|
|
struct adm1026_data *data = i2c_get_clientdata(client);
|
1203 |
|
|
int val = simple_strtol(buf, NULL, 10);
|
1204 |
|
|
|
1205 |
|
|
mutex_lock(&data->update_lock);
|
1206 |
|
|
data->analog_out = DAC_TO_REG(val);
|
1207 |
|
|
adm1026_write_value(client, ADM1026_REG_DAC, data->analog_out);
|
1208 |
|
|
mutex_unlock(&data->update_lock);
|
1209 |
|
|
return count;
|
1210 |
|
|
}
|
1211 |
|
|
|
1212 |
|
|
static DEVICE_ATTR(analog_out, S_IRUGO | S_IWUSR, show_analog_out_reg,
|
1213 |
|
|
set_analog_out_reg);
|
1214 |
|
|
|
1215 |
|
|
static ssize_t show_vid_reg(struct device *dev, struct device_attribute *attr, char *buf)
|
1216 |
|
|
{
|
1217 |
|
|
struct adm1026_data *data = adm1026_update_device(dev);
|
1218 |
|
|
return sprintf(buf,"%d\n", vid_from_reg(data->vid & 0x3f, data->vrm));
|
1219 |
|
|
}
|
1220 |
|
|
static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL);
|
1221 |
|
|
|
1222 |
|
|
static ssize_t show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf)
|
1223 |
|
|
{
|
1224 |
|
|
struct adm1026_data *data = dev_get_drvdata(dev);
|
1225 |
|
|
return sprintf(buf,"%d\n", data->vrm);
|
1226 |
|
|
}
|
1227 |
|
|
static ssize_t store_vrm_reg(struct device *dev, struct device_attribute *attr, const char *buf,
|
1228 |
|
|
size_t count)
|
1229 |
|
|
{
|
1230 |
|
|
struct i2c_client *client = to_i2c_client(dev);
|
1231 |
|
|
struct adm1026_data *data = i2c_get_clientdata(client);
|
1232 |
|
|
|
1233 |
|
|
data->vrm = simple_strtol(buf, NULL, 10);
|
1234 |
|
|
return count;
|
1235 |
|
|
}
|
1236 |
|
|
|
1237 |
|
|
static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg);
|
1238 |
|
|
|
1239 |
|
|
static ssize_t show_alarms_reg(struct device *dev, struct device_attribute *attr, char *buf)
|
1240 |
|
|
{
|
1241 |
|
|
struct adm1026_data *data = adm1026_update_device(dev);
|
1242 |
|
|
return sprintf(buf, "%ld\n", (long) (data->alarms));
|
1243 |
|
|
}
|
1244 |
|
|
|
1245 |
|
|
static DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL);
|
1246 |
|
|
|
1247 |
|
|
static ssize_t show_alarm_mask(struct device *dev, struct device_attribute *attr, char *buf)
|
1248 |
|
|
{
|
1249 |
|
|
struct adm1026_data *data = adm1026_update_device(dev);
|
1250 |
|
|
return sprintf(buf,"%ld\n", data->alarm_mask);
|
1251 |
|
|
}
|
1252 |
|
|
static ssize_t set_alarm_mask(struct device *dev, struct device_attribute *attr, const char *buf,
|
1253 |
|
|
size_t count)
|
1254 |
|
|
{
|
1255 |
|
|
struct i2c_client *client = to_i2c_client(dev);
|
1256 |
|
|
struct adm1026_data *data = i2c_get_clientdata(client);
|
1257 |
|
|
int val = simple_strtol(buf, NULL, 10);
|
1258 |
|
|
unsigned long mask;
|
1259 |
|
|
|
1260 |
|
|
mutex_lock(&data->update_lock);
|
1261 |
|
|
data->alarm_mask = val & 0x7fffffff;
|
1262 |
|
|
mask = data->alarm_mask
|
1263 |
|
|
| (data->gpio_mask & 0x10000 ? 0x80000000 : 0);
|
1264 |
|
|
adm1026_write_value(client, ADM1026_REG_MASK1,
|
1265 |
|
|
mask & 0xff);
|
1266 |
|
|
mask >>= 8;
|
1267 |
|
|
adm1026_write_value(client, ADM1026_REG_MASK2,
|
1268 |
|
|
mask & 0xff);
|
1269 |
|
|
mask >>= 8;
|
1270 |
|
|
adm1026_write_value(client, ADM1026_REG_MASK3,
|
1271 |
|
|
mask & 0xff);
|
1272 |
|
|
mask >>= 8;
|
1273 |
|
|
adm1026_write_value(client, ADM1026_REG_MASK4,
|
1274 |
|
|
mask & 0xff);
|
1275 |
|
|
mutex_unlock(&data->update_lock);
|
1276 |
|
|
return count;
|
1277 |
|
|
}
|
1278 |
|
|
|
1279 |
|
|
static DEVICE_ATTR(alarm_mask, S_IRUGO | S_IWUSR, show_alarm_mask,
|
1280 |
|
|
set_alarm_mask);
|
1281 |
|
|
|
1282 |
|
|
|
1283 |
|
|
static ssize_t show_gpio(struct device *dev, struct device_attribute *attr, char *buf)
|
1284 |
|
|
{
|
1285 |
|
|
struct adm1026_data *data = adm1026_update_device(dev);
|
1286 |
|
|
return sprintf(buf,"%ld\n", data->gpio);
|
1287 |
|
|
}
|
1288 |
|
|
static ssize_t set_gpio(struct device *dev, struct device_attribute *attr, const char *buf,
|
1289 |
|
|
size_t count)
|
1290 |
|
|
{
|
1291 |
|
|
struct i2c_client *client = to_i2c_client(dev);
|
1292 |
|
|
struct adm1026_data *data = i2c_get_clientdata(client);
|
1293 |
|
|
int val = simple_strtol(buf, NULL, 10);
|
1294 |
|
|
long gpio;
|
1295 |
|
|
|
1296 |
|
|
mutex_lock(&data->update_lock);
|
1297 |
|
|
data->gpio = val & 0x1ffff;
|
1298 |
|
|
gpio = data->gpio;
|
1299 |
|
|
adm1026_write_value(client, ADM1026_REG_GPIO_STATUS_0_7,gpio & 0xff);
|
1300 |
|
|
gpio >>= 8;
|
1301 |
|
|
adm1026_write_value(client, ADM1026_REG_GPIO_STATUS_8_15,gpio & 0xff);
|
1302 |
|
|
gpio = ((gpio >> 1) & 0x80) | (data->alarms >> 24 & 0x7f);
|
1303 |
|
|
adm1026_write_value(client, ADM1026_REG_STATUS4,gpio & 0xff);
|
1304 |
|
|
mutex_unlock(&data->update_lock);
|
1305 |
|
|
return count;
|
1306 |
|
|
}
|
1307 |
|
|
|
1308 |
|
|
static DEVICE_ATTR(gpio, S_IRUGO | S_IWUSR, show_gpio, set_gpio);
|
1309 |
|
|
|
1310 |
|
|
|
1311 |
|
|
static ssize_t show_gpio_mask(struct device *dev, struct device_attribute *attr, char *buf)
|
1312 |
|
|
{
|
1313 |
|
|
struct adm1026_data *data = adm1026_update_device(dev);
|
1314 |
|
|
return sprintf(buf,"%ld\n", data->gpio_mask);
|
1315 |
|
|
}
|
1316 |
|
|
static ssize_t set_gpio_mask(struct device *dev, struct device_attribute *attr, const char *buf,
|
1317 |
|
|
size_t count)
|
1318 |
|
|
{
|
1319 |
|
|
struct i2c_client *client = to_i2c_client(dev);
|
1320 |
|
|
struct adm1026_data *data = i2c_get_clientdata(client);
|
1321 |
|
|
int val = simple_strtol(buf, NULL, 10);
|
1322 |
|
|
long mask;
|
1323 |
|
|
|
1324 |
|
|
mutex_lock(&data->update_lock);
|
1325 |
|
|
data->gpio_mask = val & 0x1ffff;
|
1326 |
|
|
mask = data->gpio_mask;
|
1327 |
|
|
adm1026_write_value(client, ADM1026_REG_GPIO_MASK_0_7,mask & 0xff);
|
1328 |
|
|
mask >>= 8;
|
1329 |
|
|
adm1026_write_value(client, ADM1026_REG_GPIO_MASK_8_15,mask & 0xff);
|
1330 |
|
|
mask = ((mask >> 1) & 0x80) | (data->alarm_mask >> 24 & 0x7f);
|
1331 |
|
|
adm1026_write_value(client, ADM1026_REG_MASK1,mask & 0xff);
|
1332 |
|
|
mutex_unlock(&data->update_lock);
|
1333 |
|
|
return count;
|
1334 |
|
|
}
|
1335 |
|
|
|
1336 |
|
|
static DEVICE_ATTR(gpio_mask, S_IRUGO | S_IWUSR, show_gpio_mask, set_gpio_mask);
|
1337 |
|
|
|
1338 |
|
|
static ssize_t show_pwm_reg(struct device *dev, struct device_attribute *attr, char *buf)
|
1339 |
|
|
{
|
1340 |
|
|
struct adm1026_data *data = adm1026_update_device(dev);
|
1341 |
|
|
return sprintf(buf,"%d\n", PWM_FROM_REG(data->pwm1.pwm));
|
1342 |
|
|
}
|
1343 |
|
|
static ssize_t set_pwm_reg(struct device *dev, struct device_attribute *attr, const char *buf,
|
1344 |
|
|
size_t count)
|
1345 |
|
|
{
|
1346 |
|
|
struct i2c_client *client = to_i2c_client(dev);
|
1347 |
|
|
struct adm1026_data *data = i2c_get_clientdata(client);
|
1348 |
|
|
|
1349 |
|
|
if (data->pwm1.enable == 1) {
|
1350 |
|
|
int val = simple_strtol(buf, NULL, 10);
|
1351 |
|
|
|
1352 |
|
|
mutex_lock(&data->update_lock);
|
1353 |
|
|
data->pwm1.pwm = PWM_TO_REG(val);
|
1354 |
|
|
adm1026_write_value(client, ADM1026_REG_PWM, data->pwm1.pwm);
|
1355 |
|
|
mutex_unlock(&data->update_lock);
|
1356 |
|
|
}
|
1357 |
|
|
return count;
|
1358 |
|
|
}
|
1359 |
|
|
static ssize_t show_auto_pwm_min(struct device *dev, struct device_attribute *attr, char *buf)
|
1360 |
|
|
{
|
1361 |
|
|
struct adm1026_data *data = adm1026_update_device(dev);
|
1362 |
|
|
return sprintf(buf,"%d\n", data->pwm1.auto_pwm_min);
|
1363 |
|
|
}
|
1364 |
|
|
static ssize_t set_auto_pwm_min(struct device *dev, struct device_attribute *attr, const char *buf,
|
1365 |
|
|
size_t count)
|
1366 |
|
|
{
|
1367 |
|
|
struct i2c_client *client = to_i2c_client(dev);
|
1368 |
|
|
struct adm1026_data *data = i2c_get_clientdata(client);
|
1369 |
|
|
int val = simple_strtol(buf, NULL, 10);
|
1370 |
|
|
|
1371 |
|
|
mutex_lock(&data->update_lock);
|
1372 |
|
|
data->pwm1.auto_pwm_min = SENSORS_LIMIT(val,0,255);
|
1373 |
|
|
if (data->pwm1.enable == 2) { /* apply immediately */
|
1374 |
|
|
data->pwm1.pwm = PWM_TO_REG((data->pwm1.pwm & 0x0f) |
|
1375 |
|
|
PWM_MIN_TO_REG(data->pwm1.auto_pwm_min));
|
1376 |
|
|
adm1026_write_value(client, ADM1026_REG_PWM, data->pwm1.pwm);
|
1377 |
|
|
}
|
1378 |
|
|
mutex_unlock(&data->update_lock);
|
1379 |
|
|
return count;
|
1380 |
|
|
}
|
1381 |
|
|
static ssize_t show_auto_pwm_max(struct device *dev, struct device_attribute *attr, char *buf)
|
1382 |
|
|
{
|
1383 |
|
|
return sprintf(buf,"%d\n", ADM1026_PWM_MAX);
|
1384 |
|
|
}
|
1385 |
|
|
static ssize_t show_pwm_enable(struct device *dev, struct device_attribute *attr, char *buf)
|
1386 |
|
|
{
|
1387 |
|
|
struct adm1026_data *data = adm1026_update_device(dev);
|
1388 |
|
|
return sprintf(buf,"%d\n", data->pwm1.enable);
|
1389 |
|
|
}
|
1390 |
|
|
static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr, const char *buf,
|
1391 |
|
|
size_t count)
|
1392 |
|
|
{
|
1393 |
|
|
struct i2c_client *client = to_i2c_client(dev);
|
1394 |
|
|
struct adm1026_data *data = i2c_get_clientdata(client);
|
1395 |
|
|
int val = simple_strtol(buf, NULL, 10);
|
1396 |
|
|
int old_enable;
|
1397 |
|
|
|
1398 |
|
|
if ((val >= 0) && (val < 3)) {
|
1399 |
|
|
mutex_lock(&data->update_lock);
|
1400 |
|
|
old_enable = data->pwm1.enable;
|
1401 |
|
|
data->pwm1.enable = val;
|
1402 |
|
|
data->config1 = (data->config1 & ~CFG1_PWM_AFC)
|
1403 |
|
|
| ((val == 2) ? CFG1_PWM_AFC : 0);
|
1404 |
|
|
adm1026_write_value(client, ADM1026_REG_CONFIG1,
|
1405 |
|
|
data->config1);
|
1406 |
|
|
if (val == 2) { /* apply pwm1_auto_pwm_min to pwm1 */
|
1407 |
|
|
data->pwm1.pwm = PWM_TO_REG((data->pwm1.pwm & 0x0f) |
|
1408 |
|
|
PWM_MIN_TO_REG(data->pwm1.auto_pwm_min));
|
1409 |
|
|
adm1026_write_value(client, ADM1026_REG_PWM,
|
1410 |
|
|
data->pwm1.pwm);
|
1411 |
|
|
} else if (!((old_enable == 1) && (val == 1))) {
|
1412 |
|
|
/* set pwm to safe value */
|
1413 |
|
|
data->pwm1.pwm = 255;
|
1414 |
|
|
adm1026_write_value(client, ADM1026_REG_PWM,
|
1415 |
|
|
data->pwm1.pwm);
|
1416 |
|
|
}
|
1417 |
|
|
mutex_unlock(&data->update_lock);
|
1418 |
|
|
}
|
1419 |
|
|
return count;
|
1420 |
|
|
}
|
1421 |
|
|
|
1422 |
|
|
/* enable PWM fan control */
|
1423 |
|
|
static DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_pwm_reg, set_pwm_reg);
|
1424 |
|
|
static DEVICE_ATTR(pwm2, S_IRUGO | S_IWUSR, show_pwm_reg, set_pwm_reg);
|
1425 |
|
|
static DEVICE_ATTR(pwm3, S_IRUGO | S_IWUSR, show_pwm_reg, set_pwm_reg);
|
1426 |
|
|
static DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR, show_pwm_enable,
|
1427 |
|
|
set_pwm_enable);
|
1428 |
|
|
static DEVICE_ATTR(pwm2_enable, S_IRUGO | S_IWUSR, show_pwm_enable,
|
1429 |
|
|
set_pwm_enable);
|
1430 |
|
|
static DEVICE_ATTR(pwm3_enable, S_IRUGO | S_IWUSR, show_pwm_enable,
|
1431 |
|
|
set_pwm_enable);
|
1432 |
|
|
static DEVICE_ATTR(temp1_auto_point1_pwm, S_IRUGO | S_IWUSR,
|
1433 |
|
|
show_auto_pwm_min, set_auto_pwm_min);
|
1434 |
|
|
static DEVICE_ATTR(temp2_auto_point1_pwm, S_IRUGO | S_IWUSR,
|
1435 |
|
|
show_auto_pwm_min, set_auto_pwm_min);
|
1436 |
|
|
static DEVICE_ATTR(temp3_auto_point1_pwm, S_IRUGO | S_IWUSR,
|
1437 |
|
|
show_auto_pwm_min, set_auto_pwm_min);
|
1438 |
|
|
|
1439 |
|
|
static DEVICE_ATTR(temp1_auto_point2_pwm, S_IRUGO, show_auto_pwm_max, NULL);
|
1440 |
|
|
static DEVICE_ATTR(temp2_auto_point2_pwm, S_IRUGO, show_auto_pwm_max, NULL);
|
1441 |
|
|
static DEVICE_ATTR(temp3_auto_point2_pwm, S_IRUGO, show_auto_pwm_max, NULL);
|
1442 |
|
|
|
1443 |
|
|
static struct attribute *adm1026_attributes[] = {
|
1444 |
|
|
&sensor_dev_attr_in0_input.dev_attr.attr,
|
1445 |
|
|
&sensor_dev_attr_in0_max.dev_attr.attr,
|
1446 |
|
|
&sensor_dev_attr_in0_min.dev_attr.attr,
|
1447 |
|
|
&sensor_dev_attr_in1_input.dev_attr.attr,
|
1448 |
|
|
&sensor_dev_attr_in1_max.dev_attr.attr,
|
1449 |
|
|
&sensor_dev_attr_in1_min.dev_attr.attr,
|
1450 |
|
|
&sensor_dev_attr_in2_input.dev_attr.attr,
|
1451 |
|
|
&sensor_dev_attr_in2_max.dev_attr.attr,
|
1452 |
|
|
&sensor_dev_attr_in2_min.dev_attr.attr,
|
1453 |
|
|
&sensor_dev_attr_in3_input.dev_attr.attr,
|
1454 |
|
|
&sensor_dev_attr_in3_max.dev_attr.attr,
|
1455 |
|
|
&sensor_dev_attr_in3_min.dev_attr.attr,
|
1456 |
|
|
&sensor_dev_attr_in4_input.dev_attr.attr,
|
1457 |
|
|
&sensor_dev_attr_in4_max.dev_attr.attr,
|
1458 |
|
|
&sensor_dev_attr_in4_min.dev_attr.attr,
|
1459 |
|
|
&sensor_dev_attr_in5_input.dev_attr.attr,
|
1460 |
|
|
&sensor_dev_attr_in5_max.dev_attr.attr,
|
1461 |
|
|
&sensor_dev_attr_in5_min.dev_attr.attr,
|
1462 |
|
|
&sensor_dev_attr_in6_input.dev_attr.attr,
|
1463 |
|
|
&sensor_dev_attr_in6_max.dev_attr.attr,
|
1464 |
|
|
&sensor_dev_attr_in6_min.dev_attr.attr,
|
1465 |
|
|
&sensor_dev_attr_in7_input.dev_attr.attr,
|
1466 |
|
|
&sensor_dev_attr_in7_max.dev_attr.attr,
|
1467 |
|
|
&sensor_dev_attr_in7_min.dev_attr.attr,
|
1468 |
|
|
&sensor_dev_attr_in8_input.dev_attr.attr,
|
1469 |
|
|
&sensor_dev_attr_in8_max.dev_attr.attr,
|
1470 |
|
|
&sensor_dev_attr_in8_min.dev_attr.attr,
|
1471 |
|
|
&sensor_dev_attr_in9_input.dev_attr.attr,
|
1472 |
|
|
&sensor_dev_attr_in9_max.dev_attr.attr,
|
1473 |
|
|
&sensor_dev_attr_in9_min.dev_attr.attr,
|
1474 |
|
|
&sensor_dev_attr_in10_input.dev_attr.attr,
|
1475 |
|
|
&sensor_dev_attr_in10_max.dev_attr.attr,
|
1476 |
|
|
&sensor_dev_attr_in10_min.dev_attr.attr,
|
1477 |
|
|
&sensor_dev_attr_in11_input.dev_attr.attr,
|
1478 |
|
|
&sensor_dev_attr_in11_max.dev_attr.attr,
|
1479 |
|
|
&sensor_dev_attr_in11_min.dev_attr.attr,
|
1480 |
|
|
&sensor_dev_attr_in12_input.dev_attr.attr,
|
1481 |
|
|
&sensor_dev_attr_in12_max.dev_attr.attr,
|
1482 |
|
|
&sensor_dev_attr_in12_min.dev_attr.attr,
|
1483 |
|
|
&sensor_dev_attr_in13_input.dev_attr.attr,
|
1484 |
|
|
&sensor_dev_attr_in13_max.dev_attr.attr,
|
1485 |
|
|
&sensor_dev_attr_in13_min.dev_attr.attr,
|
1486 |
|
|
&sensor_dev_attr_in14_input.dev_attr.attr,
|
1487 |
|
|
&sensor_dev_attr_in14_max.dev_attr.attr,
|
1488 |
|
|
&sensor_dev_attr_in14_min.dev_attr.attr,
|
1489 |
|
|
&sensor_dev_attr_in15_input.dev_attr.attr,
|
1490 |
|
|
&sensor_dev_attr_in15_max.dev_attr.attr,
|
1491 |
|
|
&sensor_dev_attr_in15_min.dev_attr.attr,
|
1492 |
|
|
&sensor_dev_attr_in16_input.dev_attr.attr,
|
1493 |
|
|
&sensor_dev_attr_in16_max.dev_attr.attr,
|
1494 |
|
|
&sensor_dev_attr_in16_min.dev_attr.attr,
|
1495 |
|
|
&sensor_dev_attr_fan1_input.dev_attr.attr,
|
1496 |
|
|
&sensor_dev_attr_fan1_div.dev_attr.attr,
|
1497 |
|
|
&sensor_dev_attr_fan1_min.dev_attr.attr,
|
1498 |
|
|
&sensor_dev_attr_fan2_input.dev_attr.attr,
|
1499 |
|
|
&sensor_dev_attr_fan2_div.dev_attr.attr,
|
1500 |
|
|
&sensor_dev_attr_fan2_min.dev_attr.attr,
|
1501 |
|
|
&sensor_dev_attr_fan3_input.dev_attr.attr,
|
1502 |
|
|
&sensor_dev_attr_fan3_div.dev_attr.attr,
|
1503 |
|
|
&sensor_dev_attr_fan3_min.dev_attr.attr,
|
1504 |
|
|
&sensor_dev_attr_fan4_input.dev_attr.attr,
|
1505 |
|
|
&sensor_dev_attr_fan4_div.dev_attr.attr,
|
1506 |
|
|
&sensor_dev_attr_fan4_min.dev_attr.attr,
|
1507 |
|
|
&sensor_dev_attr_fan5_input.dev_attr.attr,
|
1508 |
|
|
&sensor_dev_attr_fan5_div.dev_attr.attr,
|
1509 |
|
|
&sensor_dev_attr_fan5_min.dev_attr.attr,
|
1510 |
|
|
&sensor_dev_attr_fan6_input.dev_attr.attr,
|
1511 |
|
|
&sensor_dev_attr_fan6_div.dev_attr.attr,
|
1512 |
|
|
&sensor_dev_attr_fan6_min.dev_attr.attr,
|
1513 |
|
|
&sensor_dev_attr_fan7_input.dev_attr.attr,
|
1514 |
|
|
&sensor_dev_attr_fan7_div.dev_attr.attr,
|
1515 |
|
|
&sensor_dev_attr_fan7_min.dev_attr.attr,
|
1516 |
|
|
&sensor_dev_attr_fan8_input.dev_attr.attr,
|
1517 |
|
|
&sensor_dev_attr_fan8_div.dev_attr.attr,
|
1518 |
|
|
&sensor_dev_attr_fan8_min.dev_attr.attr,
|
1519 |
|
|
&sensor_dev_attr_temp1_input.dev_attr.attr,
|
1520 |
|
|
&sensor_dev_attr_temp1_max.dev_attr.attr,
|
1521 |
|
|
&sensor_dev_attr_temp1_min.dev_attr.attr,
|
1522 |
|
|
&sensor_dev_attr_temp2_input.dev_attr.attr,
|
1523 |
|
|
&sensor_dev_attr_temp2_max.dev_attr.attr,
|
1524 |
|
|
&sensor_dev_attr_temp2_min.dev_attr.attr,
|
1525 |
|
|
&sensor_dev_attr_temp3_input.dev_attr.attr,
|
1526 |
|
|
&sensor_dev_attr_temp3_max.dev_attr.attr,
|
1527 |
|
|
&sensor_dev_attr_temp3_min.dev_attr.attr,
|
1528 |
|
|
&sensor_dev_attr_temp1_offset.dev_attr.attr,
|
1529 |
|
|
&sensor_dev_attr_temp2_offset.dev_attr.attr,
|
1530 |
|
|
&sensor_dev_attr_temp3_offset.dev_attr.attr,
|
1531 |
|
|
&sensor_dev_attr_temp1_auto_point1_temp.dev_attr.attr,
|
1532 |
|
|
&sensor_dev_attr_temp2_auto_point1_temp.dev_attr.attr,
|
1533 |
|
|
&sensor_dev_attr_temp3_auto_point1_temp.dev_attr.attr,
|
1534 |
|
|
&sensor_dev_attr_temp1_auto_point1_temp_hyst.dev_attr.attr,
|
1535 |
|
|
&sensor_dev_attr_temp2_auto_point1_temp_hyst.dev_attr.attr,
|
1536 |
|
|
&sensor_dev_attr_temp3_auto_point1_temp_hyst.dev_attr.attr,
|
1537 |
|
|
&sensor_dev_attr_temp1_auto_point2_temp.dev_attr.attr,
|
1538 |
|
|
&sensor_dev_attr_temp2_auto_point2_temp.dev_attr.attr,
|
1539 |
|
|
&sensor_dev_attr_temp3_auto_point2_temp.dev_attr.attr,
|
1540 |
|
|
&sensor_dev_attr_temp1_crit.dev_attr.attr,
|
1541 |
|
|
&sensor_dev_attr_temp2_crit.dev_attr.attr,
|
1542 |
|
|
&sensor_dev_attr_temp3_crit.dev_attr.attr,
|
1543 |
|
|
&dev_attr_temp1_crit_enable.attr,
|
1544 |
|
|
&dev_attr_temp2_crit_enable.attr,
|
1545 |
|
|
&dev_attr_temp3_crit_enable.attr,
|
1546 |
|
|
&dev_attr_cpu0_vid.attr,
|
1547 |
|
|
&dev_attr_vrm.attr,
|
1548 |
|
|
&dev_attr_alarms.attr,
|
1549 |
|
|
&dev_attr_alarm_mask.attr,
|
1550 |
|
|
&dev_attr_gpio.attr,
|
1551 |
|
|
&dev_attr_gpio_mask.attr,
|
1552 |
|
|
&dev_attr_pwm1.attr,
|
1553 |
|
|
&dev_attr_pwm2.attr,
|
1554 |
|
|
&dev_attr_pwm3.attr,
|
1555 |
|
|
&dev_attr_pwm1_enable.attr,
|
1556 |
|
|
&dev_attr_pwm2_enable.attr,
|
1557 |
|
|
&dev_attr_pwm3_enable.attr,
|
1558 |
|
|
&dev_attr_temp1_auto_point1_pwm.attr,
|
1559 |
|
|
&dev_attr_temp2_auto_point1_pwm.attr,
|
1560 |
|
|
&dev_attr_temp3_auto_point1_pwm.attr,
|
1561 |
|
|
&dev_attr_temp1_auto_point2_pwm.attr,
|
1562 |
|
|
&dev_attr_temp2_auto_point2_pwm.attr,
|
1563 |
|
|
&dev_attr_temp3_auto_point2_pwm.attr,
|
1564 |
|
|
&dev_attr_analog_out.attr,
|
1565 |
|
|
NULL
|
1566 |
|
|
};
|
1567 |
|
|
|
1568 |
|
|
static const struct attribute_group adm1026_group = {
|
1569 |
|
|
.attrs = adm1026_attributes,
|
1570 |
|
|
};
|
1571 |
|
|
|
1572 |
|
|
static int adm1026_detect(struct i2c_adapter *adapter, int address,
|
1573 |
|
|
int kind)
|
1574 |
|
|
{
|
1575 |
|
|
int company, verstep;
|
1576 |
|
|
struct i2c_client *new_client;
|
1577 |
|
|
struct adm1026_data *data;
|
1578 |
|
|
int err = 0;
|
1579 |
|
|
const char *type_name = "";
|
1580 |
|
|
|
1581 |
|
|
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
|
1582 |
|
|
/* We need to be able to do byte I/O */
|
1583 |
|
|
goto exit;
|
1584 |
|
|
};
|
1585 |
|
|
|
1586 |
|
|
/* OK. For now, we presume we have a valid client. We now create the
|
1587 |
|
|
client structure, even though we cannot fill it completely yet.
|
1588 |
|
|
But it allows us to access adm1026_{read,write}_value. */
|
1589 |
|
|
|
1590 |
|
|
if (!(data = kzalloc(sizeof(struct adm1026_data), GFP_KERNEL))) {
|
1591 |
|
|
err = -ENOMEM;
|
1592 |
|
|
goto exit;
|
1593 |
|
|
}
|
1594 |
|
|
|
1595 |
|
|
new_client = &data->client;
|
1596 |
|
|
i2c_set_clientdata(new_client, data);
|
1597 |
|
|
new_client->addr = address;
|
1598 |
|
|
new_client->adapter = adapter;
|
1599 |
|
|
new_client->driver = &adm1026_driver;
|
1600 |
|
|
new_client->flags = 0;
|
1601 |
|
|
|
1602 |
|
|
/* Now, we do the remaining detection. */
|
1603 |
|
|
|
1604 |
|
|
company = adm1026_read_value(new_client, ADM1026_REG_COMPANY);
|
1605 |
|
|
verstep = adm1026_read_value(new_client, ADM1026_REG_VERSTEP);
|
1606 |
|
|
|
1607 |
|
|
dev_dbg(&new_client->dev, "Detecting device at %d,0x%02x with"
|
1608 |
|
|
" COMPANY: 0x%02x and VERSTEP: 0x%02x\n",
|
1609 |
|
|
i2c_adapter_id(new_client->adapter), new_client->addr,
|
1610 |
|
|
company, verstep);
|
1611 |
|
|
|
1612 |
|
|
/* If auto-detecting, Determine the chip type. */
|
1613 |
|
|
if (kind <= 0) {
|
1614 |
|
|
dev_dbg(&new_client->dev, "Autodetecting device at %d,0x%02x "
|
1615 |
|
|
"...\n", i2c_adapter_id(adapter), address);
|
1616 |
|
|
if (company == ADM1026_COMPANY_ANALOG_DEV
|
1617 |
|
|
&& verstep == ADM1026_VERSTEP_ADM1026) {
|
1618 |
|
|
kind = adm1026;
|
1619 |
|
|
} else if (company == ADM1026_COMPANY_ANALOG_DEV
|
1620 |
|
|
&& (verstep & 0xf0) == ADM1026_VERSTEP_GENERIC) {
|
1621 |
|
|
dev_err(&adapter->dev, ": Unrecognized stepping "
|
1622 |
|
|
"0x%02x. Defaulting to ADM1026.\n", verstep);
|
1623 |
|
|
kind = adm1026;
|
1624 |
|
|
} else if ((verstep & 0xf0) == ADM1026_VERSTEP_GENERIC) {
|
1625 |
|
|
dev_err(&adapter->dev, ": Found version/stepping "
|
1626 |
|
|
"0x%02x. Assuming generic ADM1026.\n",
|
1627 |
|
|
verstep);
|
1628 |
|
|
kind = any_chip;
|
1629 |
|
|
} else {
|
1630 |
|
|
dev_dbg(&new_client->dev, ": Autodetection "
|
1631 |
|
|
"failed\n");
|
1632 |
|
|
/* Not an ADM1026 ... */
|
1633 |
|
|
if (kind == 0) { /* User used force=x,y */
|
1634 |
|
|
dev_err(&adapter->dev, "Generic ADM1026 not "
|
1635 |
|
|
"found at %d,0x%02x. Try "
|
1636 |
|
|
"force_adm1026.\n",
|
1637 |
|
|
i2c_adapter_id(adapter), address);
|
1638 |
|
|
}
|
1639 |
|
|
err = 0;
|
1640 |
|
|
goto exitfree;
|
1641 |
|
|
}
|
1642 |
|
|
}
|
1643 |
|
|
|
1644 |
|
|
/* Fill in the chip specific driver values */
|
1645 |
|
|
switch (kind) {
|
1646 |
|
|
case any_chip :
|
1647 |
|
|
type_name = "adm1026";
|
1648 |
|
|
break;
|
1649 |
|
|
case adm1026 :
|
1650 |
|
|
type_name = "adm1026";
|
1651 |
|
|
break;
|
1652 |
|
|
default :
|
1653 |
|
|
dev_err(&adapter->dev, ": Internal error, invalid "
|
1654 |
|
|
"kind (%d)!\n", kind);
|
1655 |
|
|
err = -EFAULT;
|
1656 |
|
|
goto exitfree;
|
1657 |
|
|
}
|
1658 |
|
|
strlcpy(new_client->name, type_name, I2C_NAME_SIZE);
|
1659 |
|
|
|
1660 |
|
|
/* Fill in the remaining client fields */
|
1661 |
|
|
data->type = kind;
|
1662 |
|
|
data->valid = 0;
|
1663 |
|
|
mutex_init(&data->update_lock);
|
1664 |
|
|
|
1665 |
|
|
/* Tell the I2C layer a new client has arrived */
|
1666 |
|
|
if ((err = i2c_attach_client(new_client)))
|
1667 |
|
|
goto exitfree;
|
1668 |
|
|
|
1669 |
|
|
/* Set the VRM version */
|
1670 |
|
|
data->vrm = vid_which_vrm();
|
1671 |
|
|
|
1672 |
|
|
/* Initialize the ADM1026 chip */
|
1673 |
|
|
adm1026_init_client(new_client);
|
1674 |
|
|
|
1675 |
|
|
/* Register sysfs hooks */
|
1676 |
|
|
if ((err = sysfs_create_group(&new_client->dev.kobj, &adm1026_group)))
|
1677 |
|
|
goto exitdetach;
|
1678 |
|
|
|
1679 |
|
|
data->hwmon_dev = hwmon_device_register(&new_client->dev);
|
1680 |
|
|
if (IS_ERR(data->hwmon_dev)) {
|
1681 |
|
|
err = PTR_ERR(data->hwmon_dev);
|
1682 |
|
|
goto exitremove;
|
1683 |
|
|
}
|
1684 |
|
|
|
1685 |
|
|
return 0;
|
1686 |
|
|
|
1687 |
|
|
/* Error out and cleanup code */
|
1688 |
|
|
exitremove:
|
1689 |
|
|
sysfs_remove_group(&new_client->dev.kobj, &adm1026_group);
|
1690 |
|
|
exitdetach:
|
1691 |
|
|
i2c_detach_client(new_client);
|
1692 |
|
|
exitfree:
|
1693 |
|
|
kfree(data);
|
1694 |
|
|
exit:
|
1695 |
|
|
return err;
|
1696 |
|
|
}
|
1697 |
|
|
|
1698 |
|
|
static int adm1026_detach_client(struct i2c_client *client)
|
1699 |
|
|
{
|
1700 |
|
|
struct adm1026_data *data = i2c_get_clientdata(client);
|
1701 |
|
|
hwmon_device_unregister(data->hwmon_dev);
|
1702 |
|
|
sysfs_remove_group(&client->dev.kobj, &adm1026_group);
|
1703 |
|
|
i2c_detach_client(client);
|
1704 |
|
|
kfree(data);
|
1705 |
|
|
return 0;
|
1706 |
|
|
}
|
1707 |
|
|
|
1708 |
|
|
static int __init sm_adm1026_init(void)
|
1709 |
|
|
{
|
1710 |
|
|
return i2c_add_driver(&adm1026_driver);
|
1711 |
|
|
}
|
1712 |
|
|
|
1713 |
|
|
static void __exit sm_adm1026_exit(void)
|
1714 |
|
|
{
|
1715 |
|
|
i2c_del_driver(&adm1026_driver);
|
1716 |
|
|
}
|
1717 |
|
|
|
1718 |
|
|
MODULE_LICENSE("GPL");
|
1719 |
|
|
MODULE_AUTHOR("Philip Pokorny <ppokorny@penguincomputing.com>, "
|
1720 |
|
|
"Justin Thiessen <jthiessen@penguincomputing.com>");
|
1721 |
|
|
MODULE_DESCRIPTION("ADM1026 driver");
|
1722 |
|
|
|
1723 |
|
|
module_init(sm_adm1026_init);
|
1724 |
|
|
module_exit(sm_adm1026_exit);
|