Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
420 | giacomo | 1 | /* |
2 | lm85.c - Part of lm_sensors, Linux kernel modules for hardware |
||
3 | monitoring |
||
4 | Copyright (c) 1998, 1999 Frodo Looijaard <frodol@dds.nl> |
||
5 | Copyright (c) 2002, 2003 Philip Pokorny <ppokorny@penguincomputing.com> |
||
6 | Copyright (c) 2003 Margit Schubert-While <margitsw@t-online.de> |
||
7 | |||
8 | Chip details at <http://www.national.com/ds/LM/LM85.pdf> |
||
9 | |||
10 | This program is free software; you can redistribute it and/or modify |
||
11 | it under the terms of the GNU General Public License as published by |
||
12 | the Free Software Foundation; either version 2 of the License, or |
||
13 | (at your option) any later version. |
||
14 | |||
15 | This program is distributed in the hope that it will be useful, |
||
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
18 | GNU General Public License for more details. |
||
19 | |||
20 | You should have received a copy of the GNU General Public License |
||
21 | along with this program; if not, write to the Free Software |
||
22 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
||
23 | */ |
||
24 | |||
25 | #include <linux/module.h> |
||
26 | #include <linux/init.h> |
||
27 | #include <linux/slab.h> |
||
28 | #include <linux/i2c.h> |
||
29 | #include <linux/i2c-sensor.h> |
||
30 | #include <linux/i2c-vid.h> |
||
31 | /* |
||
32 | #include <asm/io.h> |
||
33 | */ |
||
34 | |||
35 | #undef LM85EXTENDEDFUNC /* Extended functionality */ |
||
36 | |||
37 | /* Addresses to scan */ |
||
38 | static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; |
||
39 | static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; |
||
40 | static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END }; |
||
41 | static unsigned int normal_isa_range[] = { I2C_CLIENT_ISA_END }; |
||
42 | |||
43 | /* Insmod parameters */ |
||
44 | SENSORS_INSMOD_4(lm85b, lm85c, adm1027, adt7463); |
||
45 | |||
46 | /* Enable debug if true */ |
||
47 | static int lm85debug = 0; |
||
48 | |||
49 | /* The LM85 registers */ |
||
50 | |||
51 | #define LM85_REG_IN(nr) (0x20 + (nr)) |
||
52 | #define LM85_REG_IN_MIN(nr) (0x44 + (nr) * 2) |
||
53 | #define LM85_REG_IN_MAX(nr) (0x45 + (nr) * 2) |
||
54 | |||
55 | #define LM85_REG_TEMP(nr) (0x25 + (nr)) |
||
56 | #define LM85_REG_TEMP_MIN(nr) (0x4e + (nr) * 2) |
||
57 | #define LM85_REG_TEMP_MAX(nr) (0x4f + (nr) * 2) |
||
58 | |||
59 | /* Fan speeds are LSB, MSB (2 bytes) */ |
||
60 | #define LM85_REG_FAN(nr) (0x28 + (nr) *2) |
||
61 | #define LM85_REG_FAN_MIN(nr) (0x54 + (nr) *2) |
||
62 | |||
63 | #define LM85_REG_PWM(nr) (0x30 + (nr)) |
||
64 | |||
65 | #define ADT7463_REG_OPPOINT(nr) (0x33 + (nr)) |
||
66 | |||
67 | #define ADT7463_REG_TMIN_CTL1 0x36 |
||
68 | #define ADT7463_REG_TMIN_CTL2 0x37 |
||
69 | |||
70 | #define LM85_REG_DEVICE 0x3d |
||
71 | #define LM85_REG_COMPANY 0x3e |
||
72 | #define LM85_REG_VERSTEP 0x3f |
||
73 | /* These are the recognized values for the above regs */ |
||
74 | #define LM85_DEVICE_ADX 0x27 |
||
75 | #define LM85_COMPANY_NATIONAL 0x01 |
||
76 | #define LM85_COMPANY_ANALOG_DEV 0x41 |
||
77 | #define LM85_VERSTEP_GENERIC 0x60 |
||
78 | #define LM85_VERSTEP_LM85C 0x60 |
||
79 | #define LM85_VERSTEP_LM85B 0x62 |
||
80 | #define LM85_VERSTEP_ADM1027 0x60 |
||
81 | #define LM85_VERSTEP_ADT7463 0x62 |
||
82 | |||
83 | #define LM85_REG_CONFIG 0x40 |
||
84 | |||
85 | #define LM85_REG_ALARM1 0x41 |
||
86 | #define LM85_REG_ALARM2 0x42 |
||
87 | |||
88 | #define LM85_REG_VID 0x43 |
||
89 | |||
90 | /* Automated FAN control */ |
||
91 | #define LM85_REG_AFAN_CONFIG(nr) (0x5c + (nr)) |
||
92 | #define LM85_REG_AFAN_RANGE(nr) (0x5f + (nr)) |
||
93 | #define LM85_REG_AFAN_SPIKE1 0x62 |
||
94 | #define LM85_REG_AFAN_SPIKE2 0x63 |
||
95 | #define LM85_REG_AFAN_MINPWM(nr) (0x64 + (nr)) |
||
96 | #define LM85_REG_AFAN_LIMIT(nr) (0x67 + (nr)) |
||
97 | #define LM85_REG_AFAN_CRITICAL(nr) (0x6a + (nr)) |
||
98 | #define LM85_REG_AFAN_HYST1 0x6d |
||
99 | #define LM85_REG_AFAN_HYST2 0x6e |
||
100 | |||
101 | #define LM85_REG_TACH_MODE 0x74 |
||
102 | #define LM85_REG_SPINUP_CTL 0x75 |
||
103 | |||
104 | #define ADM1027_REG_TEMP_OFFSET(nr) (0x70 + (nr)) |
||
105 | #define ADM1027_REG_CONFIG2 0x73 |
||
106 | #define ADM1027_REG_INTMASK1 0x74 |
||
107 | #define ADM1027_REG_INTMASK2 0x75 |
||
108 | #define ADM1027_REG_EXTEND_ADC1 0x76 |
||
109 | #define ADM1027_REG_EXTEND_ADC2 0x77 |
||
110 | #define ADM1027_REG_CONFIG3 0x78 |
||
111 | #define ADM1027_REG_FAN_PPR 0x7b |
||
112 | |||
113 | #define ADT7463_REG_THERM 0x79 |
||
114 | #define ADT7463_REG_THERM_LIMIT 0x7A |
||
115 | |||
116 | #define LM85_ALARM_IN0 0x0001 |
||
117 | #define LM85_ALARM_IN1 0x0002 |
||
118 | #define LM85_ALARM_IN2 0x0004 |
||
119 | #define LM85_ALARM_IN3 0x0008 |
||
120 | #define LM85_ALARM_TEMP1 0x0010 |
||
121 | #define LM85_ALARM_TEMP2 0x0020 |
||
122 | #define LM85_ALARM_TEMP3 0x0040 |
||
123 | #define LM85_ALARM_ALARM2 0x0080 |
||
124 | #define LM85_ALARM_IN4 0x0100 |
||
125 | #define LM85_ALARM_RESERVED 0x0200 |
||
126 | #define LM85_ALARM_FAN1 0x0400 |
||
127 | #define LM85_ALARM_FAN2 0x0800 |
||
128 | #define LM85_ALARM_FAN3 0x1000 |
||
129 | #define LM85_ALARM_FAN4 0x2000 |
||
130 | #define LM85_ALARM_TEMP1_FAULT 0x4000 |
||
131 | #define LM85_ALARM_TEMP3_FAULT 0x8000 |
||
132 | |||
133 | |||
134 | /* Conversions. Rounding and limit checking is only done on the TO_REG |
||
135 | variants. Note that you should be a bit careful with which arguments |
||
136 | these macros are called: arguments may be evaluated more than once. |
||
137 | */ |
||
138 | |||
139 | /* IN are scaled 1.000 == 0xc0, mag = 3 */ |
||
140 | #define IN_TO_REG(val) (SENSORS_LIMIT((((val)*0xc0+500)/1000),0,255)) |
||
141 | #define INEXT_FROM_REG(val,ext) (((val)*1000 + (ext)*250 + 96)/0xc0) |
||
142 | #define IN_FROM_REG(val) (INEXT_FROM_REG(val,0)) |
||
143 | |||
144 | /* IN are scaled acording to built-in resistors */ |
||
145 | static int lm85_scaling[] = { /* .001 Volts */ |
||
146 | 2500, 2250, 3300, 5000, 12000 |
||
147 | }; |
||
148 | #define SCALE(val,from,to) (((val)*(to) + ((from)/2))/(from)) |
||
149 | #define INS_TO_REG(n,val) (SENSORS_LIMIT(SCALE(val,lm85_scaling[n],192),0,255)) |
||
150 | #define INSEXT_FROM_REG(n,val,ext) (SCALE((val)*4 + (ext),192*4,lm85_scaling[n])) |
||
151 | #define INS_FROM_REG(n,val) (INSEXT_FROM_REG(n,val,0)) |
||
152 | |||
153 | /* FAN speed is measured using 90kHz clock */ |
||
154 | #define FAN_TO_REG(val) (SENSORS_LIMIT( (val)<=0?0: 5400000/(val),0,65534)) |
||
155 | #define FAN_FROM_REG(val) ((val)==0?-1:(val)==0xffff?0:5400000/(val)) |
||
156 | |||
157 | /* Temperature is reported in .001 degC increments */ |
||
158 | #define TEMP_TO_REG(val) (SENSORS_LIMIT(((val)+500)/1000,-127,127)) |
||
159 | #define TEMPEXT_FROM_REG(val,ext) ((val)*1000 + (ext)*250) |
||
160 | #define TEMP_FROM_REG(val) (TEMPEXT_FROM_REG(val,0)) |
||
161 | #define EXTTEMP_TO_REG(val) (SENSORS_LIMIT((val)/250,-127,127)) |
||
162 | |||
163 | #define PWM_TO_REG(val) (SENSORS_LIMIT(val,0,255)) |
||
164 | #define PWM_FROM_REG(val) (val) |
||
165 | |||
166 | #define EXT_FROM_REG(val,sensor) (((val)>>(sensor * 2))&0x03) |
||
167 | |||
168 | #ifdef LM85EXTENDEDFUNC /* Extended functionality */ |
||
169 | |||
170 | /* ZONEs have the following parameters: |
||
171 | * Limit (low) temp, 1. degC |
||
172 | * Hysteresis (below limit), 1. degC (0-15) |
||
173 | * Range of speed control, .1 degC (2-80) |
||
174 | * Critical (high) temp, 1. degC |
||
175 | * |
||
176 | * FAN PWMs have the following parameters: |
||
177 | * Reference Zone, 1, 2, 3, etc. |
||
178 | * Spinup time, .05 sec |
||
179 | * PWM value at limit/low temp, 1 count |
||
180 | * PWM Frequency, 1. Hz |
||
181 | * PWM is Min or OFF below limit, flag |
||
182 | * Invert PWM output, flag |
||
183 | * |
||
184 | * Some chips filter the temp, others the fan. |
||
185 | * Filter constant (or disabled) .1 seconds |
||
186 | */ |
||
187 | |||
188 | /* These are the zone temperature range encodings */ |
||
189 | static int lm85_range_map[] = { /* .1 degC */ |
||
190 | 20, 25, 33, 40, 50, 66, |
||
191 | 80, 100, 133, 160, 200, 266, |
||
192 | 320, 400, 533, 800 |
||
193 | }; |
||
194 | static int RANGE_TO_REG( int range ) |
||
195 | { |
||
196 | int i; |
||
197 | |||
198 | if( range >= lm85_range_map[15] ) { return 15 ; } |
||
199 | for( i = 0 ; i < 15 ; ++i ) |
||
200 | if( range <= lm85_range_map[i] ) |
||
201 | break ; |
||
202 | return( i & 0x0f ); |
||
203 | } |
||
204 | #define RANGE_FROM_REG(val) (lm85_range_map[(val)&0x0f]) |
||
205 | |||
206 | /* These are the Acoustic Enhancement, or Temperature smoothing encodings |
||
207 | * NOTE: The enable/disable bit is INCLUDED in these encodings as the |
||
208 | * MSB (bit 3, value 8). If the enable bit is 0, the encoded value |
||
209 | * is ignored, or set to 0. |
||
210 | */ |
||
211 | static int lm85_smooth_map[] = { /* .1 sec */ |
||
212 | 350, 176, 118, 70, 44, 30, 16, 8 |
||
213 | /* 35.4 * 1/1, 1/2, 1/3, 1/5, 1/8, 1/12, 1/24, 1/48 */ |
||
214 | }; |
||
215 | static int SMOOTH_TO_REG( int smooth ) |
||
216 | { |
||
217 | int i; |
||
218 | |||
219 | if( smooth <= 0 ) { return 0 ; } /* Disabled */ |
||
220 | for( i = 0 ; i < 7 ; ++i ) |
||
221 | if( smooth >= lm85_smooth_map[i] ) |
||
222 | break ; |
||
223 | return( (i & 0x07) | 0x08 ); |
||
224 | } |
||
225 | #define SMOOTH_FROM_REG(val) ((val)&0x08?lm85_smooth_map[(val)&0x07]:0) |
||
226 | |||
227 | /* These are the fan spinup delay time encodings */ |
||
228 | static int lm85_spinup_map[] = { /* .1 sec */ |
||
229 | 0, 1, 2, 4, 7, 10, 20, 40 |
||
230 | }; |
||
231 | static int SPINUP_TO_REG( int spinup ) |
||
232 | { |
||
233 | int i; |
||
234 | |||
235 | if( spinup >= lm85_spinup_map[7] ) { return 7 ; } |
||
236 | for( i = 0 ; i < 7 ; ++i ) |
||
237 | if( spinup <= lm85_spinup_map[i] ) |
||
238 | break ; |
||
239 | return( i & 0x07 ); |
||
240 | } |
||
241 | #define SPINUP_FROM_REG(val) (lm85_spinup_map[(val)&0x07]) |
||
242 | |||
243 | /* These are the PWM frequency encodings */ |
||
244 | static int lm85_freq_map[] = { /* .1 Hz */ |
||
245 | 100, 150, 230, 300, 380, 470, 620, 980 |
||
246 | }; |
||
247 | static int FREQ_TO_REG( int freq ) |
||
248 | { |
||
249 | int i; |
||
250 | |||
251 | if( freq >= lm85_freq_map[7] ) { return 7 ; } |
||
252 | for( i = 0 ; i < 7 ; ++i ) |
||
253 | if( freq <= lm85_freq_map[i] ) |
||
254 | break ; |
||
255 | return( i & 0x07 ); |
||
256 | } |
||
257 | #define FREQ_FROM_REG(val) (lm85_freq_map[(val)&0x07]) |
||
258 | |||
259 | /* Since we can't use strings, I'm abusing these numbers |
||
260 | * to stand in for the following meanings: |
||
261 | * 1 -- PWM responds to Zone 1 |
||
262 | * 2 -- PWM responds to Zone 2 |
||
263 | * 3 -- PWM responds to Zone 3 |
||
264 | * 23 -- PWM responds to the higher temp of Zone 2 or 3 |
||
265 | * 123 -- PWM responds to highest of Zone 1, 2, or 3 |
||
266 | * 0 -- PWM is always at 0% (ie, off) |
||
267 | * -1 -- PWM is always at 100% |
||
268 | * -2 -- PWM responds to manual control |
||
269 | */ |
||
270 | |||
271 | #endif /* Extended functionality */ |
||
272 | |||
273 | static int lm85_zone_map[] = { 1, 2, 3, -1, 0, 23, 123, -2 }; |
||
274 | #define ZONE_FROM_REG(val) (lm85_zone_map[((val)>>5)&0x07]) |
||
275 | |||
276 | #ifdef LM85EXTENDEDFUNC /* Extended functionality */ |
||
277 | |||
278 | static int ZONE_TO_REG( int zone ) |
||
279 | { |
||
280 | int i; |
||
281 | |||
282 | for( i = 0 ; i <= 7 ; ++i ) |
||
283 | if( zone == lm85_zone_map[i] ) |
||
284 | break ; |
||
285 | if( i > 7 ) /* Not found. */ |
||
286 | i = 3; /* Always 100% */ |
||
287 | return( (i & 0x07)<<5 ); |
||
288 | } |
||
289 | |||
290 | #endif /* Extended functionality */ |
||
291 | |||
292 | #define HYST_TO_REG(val) (SENSORS_LIMIT((-(val)+5)/10,0,15)) |
||
293 | #define HYST_FROM_REG(val) (-(val)*10) |
||
294 | |||
295 | #define OFFSET_TO_REG(val) (SENSORS_LIMIT((val)/25,-127,127)) |
||
296 | #define OFFSET_FROM_REG(val) ((val)*25) |
||
297 | |||
298 | #define PPR_MASK(fan) (0x03<<(fan *2)) |
||
299 | #define PPR_TO_REG(val,fan) (SENSORS_LIMIT((val)-1,0,3)<<(fan *2)) |
||
300 | #define PPR_FROM_REG(val,fan) ((((val)>>(fan * 2))&0x03)+1) |
||
301 | |||
302 | /* i2c-vid.h defines vid_from_reg() */ |
||
303 | #define VID_FROM_REG(val,vrm) (vid_from_reg((val),(vrm))) |
||
304 | |||
305 | #define ALARMS_FROM_REG(val) (val) |
||
306 | |||
307 | /* Unlike some other drivers we DO NOT set initial limits. Use |
||
308 | * the config file to set limits. Some users have reported |
||
309 | * motherboards shutting down when we set limits in a previous |
||
310 | * version of the driver. |
||
311 | */ |
||
312 | |||
313 | /* Typically used with Pentium 4 systems v9.1 VRM spec */ |
||
314 | #define LM85_INIT_VRM 91 |
||
315 | |||
316 | /* Chip sampling rates |
||
317 | * |
||
318 | * Some sensors are not updated more frequently than once per second |
||
319 | * so it doesn't make sense to read them more often than that. |
||
320 | * We cache the results and return the saved data if the driver |
||
321 | * is called again before a second has elapsed. |
||
322 | * |
||
323 | * Also, there is significant configuration data for this chip |
||
324 | * given the automatic PWM fan control that is possible. There |
||
325 | * are about 47 bytes of config data to only 22 bytes of actual |
||
326 | * readings. So, we keep the config data up to date in the cache |
||
327 | * when it is written and only sample it once every 1 *minute* |
||
328 | */ |
||
329 | #define LM85_DATA_INTERVAL (HZ + HZ / 2) |
||
330 | #define LM85_CONFIG_INTERVAL (1 * 60 * HZ) |
||
331 | |||
332 | /* For each registered LM85, we need to keep some data in memory. That |
||
333 | data is pointed to by lm85_list[NR]->data. The structure itself is |
||
334 | dynamically allocated, at the same time when a new lm85 client is |
||
335 | allocated. */ |
||
336 | |||
337 | /* LM85 can automatically adjust fan speeds based on temperature |
||
338 | * This structure encapsulates an entire Zone config. There are |
||
339 | * three zones (one for each temperature input) on the lm85 |
||
340 | */ |
||
341 | struct lm85_zone { |
||
342 | s8 limit; /* Low temp limit */ |
||
343 | u8 hyst; /* Low limit hysteresis. (0-15) */ |
||
344 | u8 range; /* Temp range, encoded */ |
||
345 | s8 critical; /* "All fans ON" temp limit */ |
||
346 | }; |
||
347 | |||
348 | struct lm85_autofan { |
||
349 | u8 config; /* Register value */ |
||
350 | u8 freq; /* PWM frequency, encoded */ |
||
351 | u8 min_pwm; /* Minimum PWM value, encoded */ |
||
352 | u8 min_off; /* Min PWM or OFF below "limit", flag */ |
||
353 | }; |
||
354 | |||
355 | struct lm85_data { |
||
356 | struct semaphore lock; |
||
357 | enum chips type; |
||
358 | |||
359 | struct semaphore update_lock; |
||
360 | int valid; /* !=0 if following fields are valid */ |
||
361 | unsigned long last_reading; /* In jiffies */ |
||
362 | unsigned long last_config; /* In jiffies */ |
||
363 | |||
364 | u8 in[5]; /* Register value */ |
||
365 | u8 in_max[5]; /* Register value */ |
||
366 | u8 in_min[5]; /* Register value */ |
||
367 | s8 temp[3]; /* Register value */ |
||
368 | s8 temp_min[3]; /* Register value */ |
||
369 | s8 temp_max[3]; /* Register value */ |
||
370 | s8 temp_offset[3]; /* Register value */ |
||
371 | u16 fan[4]; /* Register value */ |
||
372 | u16 fan_min[4]; /* Register value */ |
||
373 | u8 pwm[3]; /* Register value */ |
||
374 | u8 spinup_ctl; /* Register encoding, combined */ |
||
375 | u8 tach_mode; /* Register encoding, combined */ |
||
376 | u16 extend_adc; /* Register value */ |
||
377 | u8 fan_ppr; /* Register value */ |
||
378 | u8 smooth[3]; /* Register encoding */ |
||
379 | u8 vid; /* Register value */ |
||
380 | u8 vrm; /* VRM version */ |
||
381 | u8 syncpwm3; /* Saved PWM3 for TACH 2,3,4 config */ |
||
382 | u8 oppoint[3]; /* Register value */ |
||
383 | u16 tmin_ctl; /* Register value */ |
||
384 | u32 therm_total; /* Cummulative therm count */ |
||
385 | u8 therm_limit; /* Register value */ |
||
386 | u16 alarms; /* Register encoding, combined */ |
||
387 | struct lm85_autofan autofan[3]; |
||
388 | struct lm85_zone zone[3]; |
||
389 | }; |
||
390 | |||
391 | static int lm85_attach_adapter(struct i2c_adapter *adapter); |
||
392 | static int lm85_detect(struct i2c_adapter *adapter, int address, |
||
393 | int kind); |
||
394 | static int lm85_detach_client(struct i2c_client *client); |
||
395 | |||
396 | static int lm85_read_value(struct i2c_client *client, u8 register); |
||
397 | static int lm85_write_value(struct i2c_client *client, u8 register, int value); |
||
398 | static void lm85_update_client(struct i2c_client *client); |
||
399 | static void lm85_init_client(struct i2c_client *client); |
||
400 | |||
401 | |||
402 | static struct i2c_driver lm85_driver = { |
||
403 | .owner = THIS_MODULE, |
||
404 | .name = "lm85", |
||
405 | .id = I2C_DRIVERID_LM85, |
||
406 | .flags = I2C_DF_NOTIFY, |
||
407 | .attach_adapter = lm85_attach_adapter, |
||
408 | .detach_client = lm85_detach_client, |
||
409 | }; |
||
410 | |||
411 | /* Unique ID assigned to each LM85 detected */ |
||
412 | static int lm85_id = 0; |
||
413 | |||
414 | |||
415 | /* 4 Fans */ |
||
416 | static ssize_t show_fan(struct device *dev, char *buf, int nr) |
||
417 | { |
||
418 | struct i2c_client *client = to_i2c_client(dev); |
||
419 | struct lm85_data *data = i2c_get_clientdata(client); |
||
420 | |||
421 | lm85_update_client(client); |
||
422 | return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan[nr]) ); |
||
423 | } |
||
424 | static ssize_t show_fan_min(struct device *dev, char *buf, int nr) |
||
425 | { |
||
426 | struct i2c_client *client = to_i2c_client(dev); |
||
427 | struct lm85_data *data = i2c_get_clientdata(client); |
||
428 | |||
429 | lm85_update_client(client); |
||
430 | return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan_min[nr]) ); |
||
431 | } |
||
432 | static ssize_t set_fan_min(struct device *dev, const char *buf, |
||
433 | size_t count, int nr) |
||
434 | { |
||
435 | struct i2c_client *client = to_i2c_client(dev); |
||
436 | struct lm85_data *data = i2c_get_clientdata(client); |
||
437 | int val; |
||
438 | |||
439 | down(&data->update_lock); |
||
440 | val = simple_strtol(buf, NULL, 10); |
||
441 | data->fan_min[nr] = FAN_TO_REG(val); |
||
442 | lm85_write_value(client, LM85_REG_FAN_MIN(nr), data->fan_min[nr]); |
||
443 | up(&data->update_lock); |
||
444 | return count; |
||
445 | } |
||
446 | |||
447 | #define show_fan_offset(offset) \ |
||
448 | static ssize_t show_fan_##offset (struct device *dev, char *buf) \ |
||
449 | { \ |
||
450 | return show_fan(dev, buf, 0x##offset - 1); \ |
||
451 | } \ |
||
452 | static ssize_t show_fan_##offset##_min (struct device *dev, char *buf) \ |
||
453 | { \ |
||
454 | return show_fan_min(dev, buf, 0x##offset - 1); \ |
||
455 | } \ |
||
456 | static ssize_t set_fan_##offset##_min (struct device *dev, \ |
||
457 | const char *buf, size_t count) \ |
||
458 | { \ |
||
459 | return set_fan_min(dev, buf, count, 0x##offset - 1); \ |
||
460 | } \ |
||
461 | static DEVICE_ATTR(fan_input##offset, S_IRUGO, show_fan_##offset, NULL) \ |
||
462 | static DEVICE_ATTR(fan_min##offset, S_IRUGO | S_IWUSR, \ |
||
463 | show_fan_##offset##_min, set_fan_##offset##_min) |
||
464 | |||
465 | show_fan_offset(1); |
||
466 | show_fan_offset(2); |
||
467 | show_fan_offset(3); |
||
468 | show_fan_offset(4); |
||
469 | |||
470 | /* vid, vrm, alarms */ |
||
471 | |||
472 | static ssize_t show_vid_reg(struct device *dev, char *buf) |
||
473 | { |
||
474 | struct i2c_client *client = to_i2c_client(dev); |
||
475 | struct lm85_data *data = i2c_get_clientdata(client); |
||
476 | |||
477 | lm85_update_client(client); |
||
478 | return sprintf(buf, "%ld\n", (long) vid_from_reg(data->vid, data->vrm)); |
||
479 | } |
||
480 | |||
481 | static DEVICE_ATTR(vid, S_IRUGO, show_vid_reg, NULL) |
||
482 | |||
483 | static ssize_t show_vrm_reg(struct device *dev, char *buf) |
||
484 | { |
||
485 | struct i2c_client *client = to_i2c_client(dev); |
||
486 | struct lm85_data *data = i2c_get_clientdata(client); |
||
487 | |||
488 | lm85_update_client(client); |
||
489 | return sprintf(buf, "%ld\n", (long) data->vrm); |
||
490 | } |
||
491 | |||
492 | static ssize_t store_vrm_reg(struct device *dev, const char *buf, size_t count) |
||
493 | { |
||
494 | struct i2c_client *client = to_i2c_client(dev); |
||
495 | struct lm85_data *data = i2c_get_clientdata(client); |
||
496 | u32 val; |
||
497 | |||
498 | val = simple_strtoul(buf, NULL, 10); |
||
499 | data->vrm = val; |
||
500 | return count; |
||
501 | } |
||
502 | |||
503 | static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg) |
||
504 | |||
505 | static ssize_t show_alarms_reg(struct device *dev, char *buf) |
||
506 | { |
||
507 | struct i2c_client *client = to_i2c_client(dev); |
||
508 | struct lm85_data *data = i2c_get_clientdata(client); |
||
509 | |||
510 | lm85_update_client(client); |
||
511 | return sprintf(buf, "%ld\n", (long) ALARMS_FROM_REG(data->alarms)); |
||
512 | } |
||
513 | |||
514 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL) |
||
515 | |||
516 | /* pwm */ |
||
517 | |||
518 | static ssize_t show_pwm(struct device *dev, char *buf, int nr) |
||
519 | { |
||
520 | struct i2c_client *client = to_i2c_client(dev); |
||
521 | struct lm85_data *data = i2c_get_clientdata(client); |
||
522 | |||
523 | lm85_update_client(client); |
||
524 | return sprintf(buf,"%d\n", PWM_FROM_REG(data->pwm[nr]) ); |
||
525 | } |
||
526 | static ssize_t set_pwm(struct device *dev, const char *buf, |
||
527 | size_t count, int nr) |
||
528 | { |
||
529 | struct i2c_client *client = to_i2c_client(dev); |
||
530 | struct lm85_data *data = i2c_get_clientdata(client); |
||
531 | int val; |
||
532 | |||
533 | down(&data->update_lock); |
||
534 | val = simple_strtol(buf, NULL, 10); |
||
535 | data->pwm[nr] = PWM_TO_REG(val); |
||
536 | lm85_write_value(client, LM85_REG_PWM(nr), data->pwm[nr]); |
||
537 | up(&data->update_lock); |
||
538 | return count; |
||
539 | } |
||
540 | static ssize_t show_pwm_enable(struct device *dev, char *buf, int nr) |
||
541 | { |
||
542 | struct i2c_client *client = to_i2c_client(dev); |
||
543 | struct lm85_data *data = i2c_get_clientdata(client); |
||
544 | int pwm_zone; |
||
545 | |||
546 | lm85_update_client(client); |
||
547 | pwm_zone = ZONE_FROM_REG(data->autofan[nr].config); |
||
548 | return sprintf(buf,"%d\n", (pwm_zone != 0 && pwm_zone != -1) ); |
||
549 | } |
||
550 | |||
551 | #define show_pwm_reg(offset) \ |
||
552 | static ssize_t show_pwm_##offset (struct device *dev, char *buf) \ |
||
553 | { \ |
||
554 | return show_pwm(dev, buf, 0x##offset - 1); \ |
||
555 | } \ |
||
556 | static ssize_t set_pwm_##offset (struct device *dev, \ |
||
557 | const char *buf, size_t count) \ |
||
558 | { \ |
||
559 | return set_pwm(dev, buf, count, 0x##offset - 1); \ |
||
560 | } \ |
||
561 | static ssize_t show_pwm_enable##offset (struct device *dev, char *buf) \ |
||
562 | { \ |
||
563 | return show_pwm_enable(dev, buf, 0x##offset - 1); \ |
||
564 | } \ |
||
565 | static DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \ |
||
566 | show_pwm_##offset, set_pwm_##offset) \ |
||
567 | static DEVICE_ATTR(pwm_enable##offset, S_IRUGO, show_pwm_enable##offset, NULL) |
||
568 | |||
569 | show_pwm_reg(1); |
||
570 | show_pwm_reg(2); |
||
571 | show_pwm_reg(3); |
||
572 | |||
573 | /* Voltages */ |
||
574 | |||
575 | static ssize_t show_in(struct device *dev, char *buf, int nr) |
||
576 | { |
||
577 | struct i2c_client *client = to_i2c_client(dev); |
||
578 | struct lm85_data *data = i2c_get_clientdata(client); |
||
579 | |||
580 | lm85_update_client(client); |
||
581 | return sprintf(buf,"%d\n", INS_FROM_REG(nr, data->in[nr]) ); |
||
582 | } |
||
583 | static ssize_t show_in_min(struct device *dev, char *buf, int nr) |
||
584 | { |
||
585 | struct i2c_client *client = to_i2c_client(dev); |
||
586 | struct lm85_data *data = i2c_get_clientdata(client); |
||
587 | |||
588 | lm85_update_client(client); |
||
589 | return sprintf(buf,"%d\n", INS_FROM_REG(nr, data->in_min[nr]) ); |
||
590 | } |
||
591 | static ssize_t set_in_min(struct device *dev, const char *buf, |
||
592 | size_t count, int nr) |
||
593 | { |
||
594 | struct i2c_client *client = to_i2c_client(dev); |
||
595 | struct lm85_data *data = i2c_get_clientdata(client); |
||
596 | int val; |
||
597 | |||
598 | down(&data->update_lock); |
||
599 | val = simple_strtol(buf, NULL, 10); |
||
600 | data->in_min[nr] = INS_TO_REG(nr, val); |
||
601 | lm85_write_value(client, LM85_REG_IN_MIN(nr), data->in_min[nr]); |
||
602 | up(&data->update_lock); |
||
603 | return count; |
||
604 | } |
||
605 | static ssize_t show_in_max(struct device *dev, char *buf, int nr) |
||
606 | { |
||
607 | struct i2c_client *client = to_i2c_client(dev); |
||
608 | struct lm85_data *data = i2c_get_clientdata(client); |
||
609 | |||
610 | lm85_update_client(client); |
||
611 | return sprintf(buf,"%d\n", INS_FROM_REG(nr, data->in_max[nr]) ); |
||
612 | } |
||
613 | static ssize_t set_in_max(struct device *dev, const char *buf, |
||
614 | size_t count, int nr) |
||
615 | { |
||
616 | struct i2c_client *client = to_i2c_client(dev); |
||
617 | struct lm85_data *data = i2c_get_clientdata(client); |
||
618 | int val; |
||
619 | |||
620 | down(&data->update_lock); |
||
621 | val = simple_strtol(buf, NULL, 10); |
||
622 | data->in_max[nr] = INS_TO_REG(nr, val); |
||
623 | lm85_write_value(client, LM85_REG_IN_MAX(nr), data->in_max[nr]); |
||
624 | up(&data->update_lock); |
||
625 | return count; |
||
626 | } |
||
627 | #define show_in_reg(offset) \ |
||
628 | static ssize_t show_in_##offset (struct device *dev, char *buf) \ |
||
629 | { \ |
||
630 | return show_in(dev, buf, 0x##offset); \ |
||
631 | } \ |
||
632 | static ssize_t show_in_##offset##_min (struct device *dev, char *buf) \ |
||
633 | { \ |
||
634 | return show_in_min(dev, buf, 0x##offset); \ |
||
635 | } \ |
||
636 | static ssize_t show_in_##offset##_max (struct device *dev, char *buf) \ |
||
637 | { \ |
||
638 | return show_in_max(dev, buf, 0x##offset); \ |
||
639 | } \ |
||
640 | static ssize_t set_in_##offset##_min (struct device *dev, \ |
||
641 | const char *buf, size_t count) \ |
||
642 | { \ |
||
643 | return set_in_min(dev, buf, count, 0x##offset); \ |
||
644 | } \ |
||
645 | static ssize_t set_in_##offset##_max (struct device *dev, \ |
||
646 | const char *buf, size_t count) \ |
||
647 | { \ |
||
648 | return set_in_max(dev, buf, count, 0x##offset); \ |
||
649 | } \ |
||
650 | static DEVICE_ATTR(in_input##offset, S_IRUGO, show_in_##offset, NULL) \ |
||
651 | static DEVICE_ATTR(in_min##offset, S_IRUGO | S_IWUSR, \ |
||
652 | show_in_##offset##_min, set_in_##offset##_min) \ |
||
653 | static DEVICE_ATTR(in_max##offset, S_IRUGO | S_IWUSR, \ |
||
654 | show_in_##offset##_max, set_in_##offset##_max) |
||
655 | |||
656 | show_in_reg(0); |
||
657 | show_in_reg(1); |
||
658 | show_in_reg(2); |
||
659 | show_in_reg(3); |
||
660 | show_in_reg(4); |
||
661 | |||
662 | /* Temps */ |
||
663 | |||
664 | static ssize_t show_temp(struct device *dev, char *buf, int nr) |
||
665 | { |
||
666 | struct i2c_client *client = to_i2c_client(dev); |
||
667 | struct lm85_data *data = i2c_get_clientdata(client); |
||
668 | |||
669 | lm85_update_client(client); |
||
670 | return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp[nr]) ); |
||
671 | } |
||
672 | static ssize_t show_temp_min(struct device *dev, char *buf, int nr) |
||
673 | { |
||
674 | struct i2c_client *client = to_i2c_client(dev); |
||
675 | struct lm85_data *data = i2c_get_clientdata(client); |
||
676 | |||
677 | lm85_update_client(client); |
||
678 | return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp_min[nr]) ); |
||
679 | } |
||
680 | static ssize_t set_temp_min(struct device *dev, const char *buf, |
||
681 | size_t count, int nr) |
||
682 | { |
||
683 | struct i2c_client *client = to_i2c_client(dev); |
||
684 | struct lm85_data *data = i2c_get_clientdata(client); |
||
685 | int val; |
||
686 | |||
687 | down(&data->update_lock); |
||
688 | val = simple_strtol(buf, NULL, 10); |
||
689 | data->temp_min[nr] = TEMP_TO_REG(val); |
||
690 | lm85_write_value(client, LM85_REG_TEMP_MIN(nr), data->temp_min[nr]); |
||
691 | up(&data->update_lock); |
||
692 | return count; |
||
693 | } |
||
694 | static ssize_t show_temp_max(struct device *dev, char *buf, int nr) |
||
695 | { |
||
696 | struct i2c_client *client = to_i2c_client(dev); |
||
697 | struct lm85_data *data = i2c_get_clientdata(client); |
||
698 | |||
699 | lm85_update_client(client); |
||
700 | return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp_max[nr]) ); |
||
701 | } |
||
702 | static ssize_t set_temp_max(struct device *dev, const char *buf, |
||
703 | size_t count, int nr) |
||
704 | { |
||
705 | struct i2c_client *client = to_i2c_client(dev); |
||
706 | struct lm85_data *data = i2c_get_clientdata(client); |
||
707 | int val; |
||
708 | |||
709 | down(&data->update_lock); |
||
710 | val = simple_strtol(buf, NULL, 10); |
||
711 | data->temp_max[nr] = TEMP_TO_REG(val); |
||
712 | lm85_write_value(client, LM85_REG_TEMP_MAX(nr), data->temp_max[nr]); |
||
713 | up(&data->update_lock); |
||
714 | return count; |
||
715 | } |
||
716 | #define show_temp_reg(offset) \ |
||
717 | static ssize_t show_temp_##offset (struct device *dev, char *buf) \ |
||
718 | { \ |
||
719 | return show_temp(dev, buf, 0x##offset - 1); \ |
||
720 | } \ |
||
721 | static ssize_t show_temp_##offset##_min (struct device *dev, char *buf) \ |
||
722 | { \ |
||
723 | return show_temp_min(dev, buf, 0x##offset - 1); \ |
||
724 | } \ |
||
725 | static ssize_t show_temp_##offset##_max (struct device *dev, char *buf) \ |
||
726 | { \ |
||
727 | return show_temp_max(dev, buf, 0x##offset - 1); \ |
||
728 | } \ |
||
729 | static ssize_t set_temp_##offset##_min (struct device *dev, \ |
||
730 | const char *buf, size_t count) \ |
||
731 | { \ |
||
732 | return set_temp_min(dev, buf, count, 0x##offset - 1); \ |
||
733 | } \ |
||
734 | static ssize_t set_temp_##offset##_max (struct device *dev, \ |
||
735 | const char *buf, size_t count) \ |
||
736 | { \ |
||
737 | return set_temp_max(dev, buf, count, 0x##offset - 1); \ |
||
738 | } \ |
||
739 | static DEVICE_ATTR(temp_input##offset, S_IRUGO, show_temp_##offset, NULL) \ |
||
740 | static DEVICE_ATTR(temp_min##offset, S_IRUGO | S_IWUSR, \ |
||
741 | show_temp_##offset##_min, set_temp_##offset##_min) \ |
||
742 | static DEVICE_ATTR(temp_max##offset, S_IRUGO | S_IWUSR, \ |
||
743 | show_temp_##offset##_max, set_temp_##offset##_max) |
||
744 | |||
745 | show_temp_reg(1); |
||
746 | show_temp_reg(2); |
||
747 | show_temp_reg(3); |
||
748 | |||
749 | |||
750 | int lm85_attach_adapter(struct i2c_adapter *adapter) |
||
751 | { |
||
752 | return i2c_detect(adapter, &addr_data, lm85_detect); |
||
753 | } |
||
754 | |||
755 | int lm85_detect(struct i2c_adapter *adapter, int address, |
||
756 | int kind) |
||
757 | { |
||
758 | int company, verstep ; |
||
759 | struct i2c_client *new_client = NULL; |
||
760 | struct lm85_data *data; |
||
761 | int err = 0; |
||
762 | const char *type_name = ""; |
||
763 | |||
764 | if (i2c_is_isa_adapter(adapter)) { |
||
765 | /* This chip has no ISA interface */ |
||
766 | goto ERROR0 ; |
||
767 | }; |
||
768 | |||
769 | if (!i2c_check_functionality(adapter, |
||
770 | I2C_FUNC_SMBUS_BYTE_DATA)) { |
||
771 | /* We need to be able to do byte I/O */ |
||
772 | goto ERROR0 ; |
||
773 | }; |
||
774 | |||
775 | /* OK. For now, we presume we have a valid client. We now create the |
||
776 | client structure, even though we cannot fill it completely yet. |
||
777 | But it allows us to access lm85_{read,write}_value. */ |
||
778 | |||
779 | if (!(new_client = kmalloc((sizeof(struct i2c_client)) + |
||
780 | sizeof(struct lm85_data), |
||
781 | GFP_KERNEL))) { |
||
782 | err = -ENOMEM; |
||
783 | goto ERROR0; |
||
784 | } |
||
785 | |||
786 | memset(new_client, 0, sizeof(struct i2c_client) + |
||
787 | sizeof(struct lm85_data)); |
||
788 | data = (struct lm85_data *) (new_client + 1); |
||
789 | i2c_set_clientdata(new_client, data); |
||
790 | new_client->addr = address; |
||
791 | new_client->adapter = adapter; |
||
792 | new_client->driver = &lm85_driver; |
||
793 | new_client->flags = 0; |
||
794 | |||
795 | /* Now, we do the remaining detection. */ |
||
796 | |||
797 | company = lm85_read_value(new_client, LM85_REG_COMPANY); |
||
798 | verstep = lm85_read_value(new_client, LM85_REG_VERSTEP); |
||
799 | |||
800 | if (lm85debug) { |
||
801 | printk("lm85: Detecting device at %d,0x%02x with" |
||
802 | " COMPANY: 0x%02x and VERSTEP: 0x%02x\n", |
||
803 | i2c_adapter_id(new_client->adapter), new_client->addr, |
||
804 | company, verstep); |
||
805 | } |
||
806 | |||
807 | /* If auto-detecting, Determine the chip type. */ |
||
808 | if (kind <= 0) { |
||
809 | if (lm85debug) { |
||
810 | printk("lm85: Autodetecting device at %d,0x%02x ...\n", |
||
811 | i2c_adapter_id(adapter), address ); |
||
812 | } |
||
813 | if( company == LM85_COMPANY_NATIONAL |
||
814 | && verstep == LM85_VERSTEP_LM85C ) { |
||
815 | kind = lm85c ; |
||
816 | } else if( company == LM85_COMPANY_NATIONAL |
||
817 | && verstep == LM85_VERSTEP_LM85B ) { |
||
818 | kind = lm85b ; |
||
819 | } else if( company == LM85_COMPANY_NATIONAL |
||
820 | && (verstep & 0xf0) == LM85_VERSTEP_GENERIC ) { |
||
821 | printk("lm85: Unrecgonized version/stepping 0x%02x" |
||
822 | " Defaulting to LM85.\n", verstep ); |
||
823 | kind = any_chip ; |
||
824 | } else if( company == LM85_COMPANY_ANALOG_DEV |
||
825 | && verstep == LM85_VERSTEP_ADM1027 ) { |
||
826 | kind = adm1027 ; |
||
827 | } else if( company == LM85_COMPANY_ANALOG_DEV |
||
828 | && verstep == LM85_VERSTEP_ADT7463 ) { |
||
829 | kind = adt7463 ; |
||
830 | } else if( company == LM85_COMPANY_ANALOG_DEV |
||
831 | && (verstep & 0xf0) == LM85_VERSTEP_GENERIC ) { |
||
832 | printk("lm85: Unrecgonized version/stepping 0x%02x" |
||
833 | " Defaulting to ADM1027.\n", verstep ); |
||
834 | kind = adm1027 ; |
||
835 | } else if( kind == 0 && (verstep & 0xf0) == 0x60) { |
||
836 | printk("lm85: Generic LM85 Version 6 detected\n"); |
||
837 | /* Leave kind as "any_chip" */ |
||
838 | } else { |
||
839 | if (lm85debug) { |
||
840 | printk("lm85: Autodetection failed\n"); |
||
841 | } |
||
842 | /* Not an LM85 ... */ |
||
843 | if( kind == 0 ) { /* User used force=x,y */ |
||
844 | printk("lm85: Generic LM85 Version 6 not" |
||
845 | " found at %d,0x%02x. Try force_lm85c.\n", |
||
846 | i2c_adapter_id(adapter), address ); |
||
847 | } |
||
848 | err = 0 ; |
||
849 | goto ERROR1; |
||
850 | } |
||
851 | } |
||
852 | |||
853 | /* Fill in the chip specific driver values */ |
||
854 | if ( kind == any_chip ) { |
||
855 | type_name = "lm85"; |
||
856 | } else if ( kind == lm85b ) { |
||
857 | type_name = "lm85b"; |
||
858 | } else if ( kind == lm85c ) { |
||
859 | type_name = "lm85c"; |
||
860 | } else if ( kind == adm1027 ) { |
||
861 | type_name = "adm1027"; |
||
862 | } else if ( kind == adt7463 ) { |
||
863 | type_name = "adt7463"; |
||
864 | } else { |
||
865 | dev_dbg(&adapter->dev, "Internal error, invalid kind (%d)!", kind); |
||
866 | err = -EFAULT ; |
||
867 | goto ERROR1; |
||
868 | } |
||
869 | strlcpy(new_client->name, type_name, I2C_NAME_SIZE); |
||
870 | |||
871 | /* Fill in the remaining client fields */ |
||
872 | new_client->id = lm85_id++; |
||
873 | data->type = kind; |
||
874 | data->valid = 0; |
||
875 | init_MUTEX(&data->update_lock); |
||
876 | |||
877 | if (lm85debug) { |
||
878 | printk("lm85: Assigning ID %d to %s at %d,0x%02x\n", |
||
879 | new_client->id, new_client->name, |
||
880 | i2c_adapter_id(new_client->adapter), |
||
881 | new_client->addr); |
||
882 | } |
||
883 | |||
884 | /* Tell the I2C layer a new client has arrived */ |
||
885 | if ((err = i2c_attach_client(new_client))) |
||
886 | goto ERROR1; |
||
887 | |||
888 | /* Set the VRM version */ |
||
889 | data->vrm = LM85_INIT_VRM ; |
||
890 | |||
891 | /* Initialize the LM85 chip */ |
||
892 | lm85_init_client(new_client); |
||
893 | |||
894 | /* Register sysfs hooks */ |
||
895 | device_create_file(&new_client->dev, &dev_attr_fan_input1); |
||
896 | device_create_file(&new_client->dev, &dev_attr_fan_input2); |
||
897 | device_create_file(&new_client->dev, &dev_attr_fan_input3); |
||
898 | device_create_file(&new_client->dev, &dev_attr_fan_input4); |
||
899 | device_create_file(&new_client->dev, &dev_attr_fan_min1); |
||
900 | device_create_file(&new_client->dev, &dev_attr_fan_min2); |
||
901 | device_create_file(&new_client->dev, &dev_attr_fan_min3); |
||
902 | device_create_file(&new_client->dev, &dev_attr_fan_min4); |
||
903 | device_create_file(&new_client->dev, &dev_attr_pwm1); |
||
904 | device_create_file(&new_client->dev, &dev_attr_pwm2); |
||
905 | device_create_file(&new_client->dev, &dev_attr_pwm3); |
||
906 | device_create_file(&new_client->dev, &dev_attr_pwm_enable1); |
||
907 | device_create_file(&new_client->dev, &dev_attr_pwm_enable2); |
||
908 | device_create_file(&new_client->dev, &dev_attr_pwm_enable3); |
||
909 | device_create_file(&new_client->dev, &dev_attr_in_input0); |
||
910 | device_create_file(&new_client->dev, &dev_attr_in_input1); |
||
911 | device_create_file(&new_client->dev, &dev_attr_in_input2); |
||
912 | device_create_file(&new_client->dev, &dev_attr_in_input3); |
||
913 | device_create_file(&new_client->dev, &dev_attr_in_input4); |
||
914 | device_create_file(&new_client->dev, &dev_attr_in_min0); |
||
915 | device_create_file(&new_client->dev, &dev_attr_in_min1); |
||
916 | device_create_file(&new_client->dev, &dev_attr_in_min2); |
||
917 | device_create_file(&new_client->dev, &dev_attr_in_min3); |
||
918 | device_create_file(&new_client->dev, &dev_attr_in_min4); |
||
919 | device_create_file(&new_client->dev, &dev_attr_in_max0); |
||
920 | device_create_file(&new_client->dev, &dev_attr_in_max1); |
||
921 | device_create_file(&new_client->dev, &dev_attr_in_max2); |
||
922 | device_create_file(&new_client->dev, &dev_attr_in_max3); |
||
923 | device_create_file(&new_client->dev, &dev_attr_in_max4); |
||
924 | device_create_file(&new_client->dev, &dev_attr_temp_input1); |
||
925 | device_create_file(&new_client->dev, &dev_attr_temp_input2); |
||
926 | device_create_file(&new_client->dev, &dev_attr_temp_input3); |
||
927 | device_create_file(&new_client->dev, &dev_attr_temp_min1); |
||
928 | device_create_file(&new_client->dev, &dev_attr_temp_min2); |
||
929 | device_create_file(&new_client->dev, &dev_attr_temp_min3); |
||
930 | device_create_file(&new_client->dev, &dev_attr_temp_max1); |
||
931 | device_create_file(&new_client->dev, &dev_attr_temp_max2); |
||
932 | device_create_file(&new_client->dev, &dev_attr_temp_max3); |
||
933 | device_create_file(&new_client->dev, &dev_attr_vrm); |
||
934 | device_create_file(&new_client->dev, &dev_attr_vid); |
||
935 | device_create_file(&new_client->dev, &dev_attr_alarms); |
||
936 | |||
937 | return 0; |
||
938 | |||
939 | /* Error out and cleanup code */ |
||
940 | ERROR1: |
||
941 | kfree(new_client); |
||
942 | ERROR0: |
||
943 | return err; |
||
944 | } |
||
945 | |||
946 | int lm85_detach_client(struct i2c_client *client) |
||
947 | { |
||
948 | i2c_detach_client(client); |
||
949 | kfree(client); |
||
950 | return 0; |
||
951 | } |
||
952 | |||
953 | |||
954 | int lm85_read_value(struct i2c_client *client, u8 reg) |
||
955 | { |
||
956 | int res; |
||
957 | |||
958 | /* What size location is it? */ |
||
959 | switch( reg ) { |
||
960 | case LM85_REG_FAN(0) : /* Read WORD data */ |
||
961 | case LM85_REG_FAN(1) : |
||
962 | case LM85_REG_FAN(2) : |
||
963 | case LM85_REG_FAN(3) : |
||
964 | case LM85_REG_FAN_MIN(0) : |
||
965 | case LM85_REG_FAN_MIN(1) : |
||
966 | case LM85_REG_FAN_MIN(2) : |
||
967 | case LM85_REG_FAN_MIN(3) : |
||
968 | case LM85_REG_ALARM1 : /* Read both bytes at once */ |
||
969 | case ADM1027_REG_EXTEND_ADC1 : /* Read two bytes at once */ |
||
970 | res = i2c_smbus_read_byte_data(client, reg) & 0xff ; |
||
971 | res |= i2c_smbus_read_byte_data(client, reg+1) << 8 ; |
||
972 | break ; |
||
973 | case ADT7463_REG_TMIN_CTL1 : /* Read WORD MSB, LSB */ |
||
974 | res = i2c_smbus_read_byte_data(client, reg) << 8 ; |
||
975 | res |= i2c_smbus_read_byte_data(client, reg+1) & 0xff ; |
||
976 | break ; |
||
977 | default: /* Read BYTE data */ |
||
978 | res = i2c_smbus_read_byte_data(client, reg); |
||
979 | break ; |
||
980 | } |
||
981 | |||
982 | return res ; |
||
983 | } |
||
984 | |||
985 | int lm85_write_value(struct i2c_client *client, u8 reg, int value) |
||
986 | { |
||
987 | int res ; |
||
988 | |||
989 | switch( reg ) { |
||
990 | case LM85_REG_FAN(0) : /* Write WORD data */ |
||
991 | case LM85_REG_FAN(1) : |
||
992 | case LM85_REG_FAN(2) : |
||
993 | case LM85_REG_FAN(3) : |
||
994 | case LM85_REG_FAN_MIN(0) : |
||
995 | case LM85_REG_FAN_MIN(1) : |
||
996 | case LM85_REG_FAN_MIN(2) : |
||
997 | case LM85_REG_FAN_MIN(3) : |
||
998 | /* NOTE: ALARM is read only, so not included here */ |
||
999 | res = i2c_smbus_write_byte_data(client, reg, value & 0xff) ; |
||
1000 | res |= i2c_smbus_write_byte_data(client, reg+1, (value>>8) & 0xff) ; |
||
1001 | break ; |
||
1002 | case ADT7463_REG_TMIN_CTL1 : /* Write WORD MSB, LSB */ |
||
1003 | res = i2c_smbus_write_byte_data(client, reg, (value>>8) & 0xff); |
||
1004 | res |= i2c_smbus_write_byte_data(client, reg+1, value & 0xff) ; |
||
1005 | break ; |
||
1006 | default: /* Write BYTE data */ |
||
1007 | res = i2c_smbus_write_byte_data(client, reg, value); |
||
1008 | break ; |
||
1009 | } |
||
1010 | |||
1011 | return res ; |
||
1012 | } |
||
1013 | |||
1014 | void lm85_init_client(struct i2c_client *client) |
||
1015 | { |
||
1016 | int value; |
||
1017 | struct lm85_data *data = i2c_get_clientdata(client); |
||
1018 | |||
1019 | if (lm85debug) { |
||
1020 | printk("lm85(%d): Initializing device\n", client->id); |
||
1021 | } |
||
1022 | |||
1023 | /* Warn if part was not "READY" */ |
||
1024 | value = lm85_read_value(client, LM85_REG_CONFIG); |
||
1025 | if (lm85debug) { |
||
1026 | printk("lm85(%d): LM85_REG_CONFIG is: 0x%02x\n", client->id, value ); |
||
1027 | } |
||
1028 | if( value & 0x02 ) { |
||
1029 | printk("lm85(%d): Client (%d,0x%02x) config is locked.\n", |
||
1030 | client->id, |
||
1031 | i2c_adapter_id(client->adapter), client->addr ); |
||
1032 | }; |
||
1033 | if( ! (value & 0x04) ) { |
||
1034 | printk("lm85(%d): Client (%d,0x%02x) is not ready.\n", |
||
1035 | client->id, |
||
1036 | i2c_adapter_id(client->adapter), client->addr ); |
||
1037 | }; |
||
1038 | if( value & 0x10 |
||
1039 | && ( data->type == adm1027 |
||
1040 | || data->type == adt7463 ) ) { |
||
1041 | printk("lm85(%d): Client (%d,0x%02x) VxI mode is set. " |
||
1042 | "Please report this to the lm85 maintainer.\n", |
||
1043 | client->id, |
||
1044 | i2c_adapter_id(client->adapter), client->addr ); |
||
1045 | }; |
||
1046 | |||
1047 | /* WE INTENTIONALLY make no changes to the limits, |
||
1048 | * offsets, pwms, fans and zones. If they were |
||
1049 | * configured, we don't want to mess with them. |
||
1050 | * If they weren't, the default is 100% PWM, no |
||
1051 | * control and will suffice until 'sensors -s' |
||
1052 | * can be run by the user. |
||
1053 | */ |
||
1054 | |||
1055 | /* Start monitoring */ |
||
1056 | value = lm85_read_value(client, LM85_REG_CONFIG); |
||
1057 | /* Try to clear LOCK, Set START, save everything else */ |
||
1058 | value = (value & ~ 0x02) | 0x01 ; |
||
1059 | if (lm85debug) { |
||
1060 | printk("lm85(%d): Setting CONFIG to: 0x%02x\n", client->id, value ); |
||
1061 | } |
||
1062 | lm85_write_value(client, LM85_REG_CONFIG, value); |
||
1063 | |||
1064 | } |
||
1065 | |||
1066 | void lm85_update_client(struct i2c_client *client) |
||
1067 | { |
||
1068 | struct lm85_data *data = i2c_get_clientdata(client); |
||
1069 | int i; |
||
1070 | |||
1071 | down(&data->update_lock); |
||
1072 | |||
1073 | if ( !data->valid || |
||
1074 | (jiffies - data->last_reading > LM85_DATA_INTERVAL ) ) { |
||
1075 | /* Things that change quickly */ |
||
1076 | |||
1077 | if (lm85debug) { |
||
1078 | printk("lm85(%d): Reading sensor values\n", client->id); |
||
1079 | } |
||
1080 | /* Have to read extended bits first to "freeze" the |
||
1081 | * more significant bits that are read later. |
||
1082 | */ |
||
1083 | if ( (data->type == adm1027) || (data->type == adt7463) ) { |
||
1084 | data->extend_adc = |
||
1085 | lm85_read_value(client, ADM1027_REG_EXTEND_ADC1); |
||
1086 | } |
||
1087 | |||
1088 | for (i = 0; i <= 4; ++i) { |
||
1089 | data->in[i] = |
||
1090 | lm85_read_value(client, LM85_REG_IN(i)); |
||
1091 | } |
||
1092 | |||
1093 | for (i = 0; i <= 3; ++i) { |
||
1094 | data->fan[i] = |
||
1095 | lm85_read_value(client, LM85_REG_FAN(i)); |
||
1096 | } |
||
1097 | |||
1098 | for (i = 0; i <= 2; ++i) { |
||
1099 | data->temp[i] = |
||
1100 | lm85_read_value(client, LM85_REG_TEMP(i)); |
||
1101 | } |
||
1102 | |||
1103 | for (i = 0; i <= 2; ++i) { |
||
1104 | data->pwm[i] = |
||
1105 | lm85_read_value(client, LM85_REG_PWM(i)); |
||
1106 | } |
||
1107 | |||
1108 | if ( data->type == adt7463 ) { |
||
1109 | if( data->therm_total < ULONG_MAX - 256 ) { |
||
1110 | data->therm_total += |
||
1111 | lm85_read_value(client, ADT7463_REG_THERM ); |
||
1112 | } |
||
1113 | } |
||
1114 | |||
1115 | data->alarms = lm85_read_value(client, LM85_REG_ALARM1); |
||
1116 | |||
1117 | data->last_reading = jiffies ; |
||
1118 | }; /* last_reading */ |
||
1119 | |||
1120 | if ( !data->valid || |
||
1121 | (jiffies - data->last_config > LM85_CONFIG_INTERVAL) ) { |
||
1122 | /* Things that don't change often */ |
||
1123 | |||
1124 | if (lm85debug) { |
||
1125 | printk("lm85(%d): Reading config values\n", client->id); |
||
1126 | } |
||
1127 | for (i = 0; i <= 4; ++i) { |
||
1128 | data->in_min[i] = |
||
1129 | lm85_read_value(client, LM85_REG_IN_MIN(i)); |
||
1130 | data->in_max[i] = |
||
1131 | lm85_read_value(client, LM85_REG_IN_MAX(i)); |
||
1132 | } |
||
1133 | |||
1134 | for (i = 0; i <= 3; ++i) { |
||
1135 | data->fan_min[i] = |
||
1136 | lm85_read_value(client, LM85_REG_FAN_MIN(i)); |
||
1137 | } |
||
1138 | |||
1139 | for (i = 0; i <= 2; ++i) { |
||
1140 | data->temp_min[i] = |
||
1141 | lm85_read_value(client, LM85_REG_TEMP_MIN(i)); |
||
1142 | data->temp_max[i] = |
||
1143 | lm85_read_value(client, LM85_REG_TEMP_MAX(i)); |
||
1144 | } |
||
1145 | |||
1146 | data->vid = lm85_read_value(client, LM85_REG_VID); |
||
1147 | |||
1148 | for (i = 0; i <= 2; ++i) { |
||
1149 | int val ; |
||
1150 | data->autofan[i].config = |
||
1151 | lm85_read_value(client, LM85_REG_AFAN_CONFIG(i)); |
||
1152 | val = lm85_read_value(client, LM85_REG_AFAN_RANGE(i)); |
||
1153 | data->autofan[i].freq = val & 0x07 ; |
||
1154 | data->zone[i].range = (val >> 4) & 0x0f ; |
||
1155 | data->autofan[i].min_pwm = |
||
1156 | lm85_read_value(client, LM85_REG_AFAN_MINPWM(i)); |
||
1157 | data->zone[i].limit = |
||
1158 | lm85_read_value(client, LM85_REG_AFAN_LIMIT(i)); |
||
1159 | data->zone[i].critical = |
||
1160 | lm85_read_value(client, LM85_REG_AFAN_CRITICAL(i)); |
||
1161 | } |
||
1162 | |||
1163 | i = lm85_read_value(client, LM85_REG_AFAN_SPIKE1); |
||
1164 | data->smooth[0] = i & 0x0f ; |
||
1165 | data->syncpwm3 = i & 0x10 ; /* Save PWM3 config */ |
||
1166 | data->autofan[0].min_off = (i & 0x20) != 0 ; |
||
1167 | data->autofan[1].min_off = (i & 0x40) != 0 ; |
||
1168 | data->autofan[2].min_off = (i & 0x80) != 0 ; |
||
1169 | i = lm85_read_value(client, LM85_REG_AFAN_SPIKE2); |
||
1170 | data->smooth[1] = (i>>4) & 0x0f ; |
||
1171 | data->smooth[2] = i & 0x0f ; |
||
1172 | |||
1173 | i = lm85_read_value(client, LM85_REG_AFAN_HYST1); |
||
1174 | data->zone[0].hyst = (i>>4) & 0x0f ; |
||
1175 | data->zone[1].hyst = i & 0x0f ; |
||
1176 | |||
1177 | i = lm85_read_value(client, LM85_REG_AFAN_HYST2); |
||
1178 | data->zone[2].hyst = (i>>4) & 0x0f ; |
||
1179 | |||
1180 | if ( (data->type == lm85b) || (data->type == lm85c) ) { |
||
1181 | data->tach_mode = lm85_read_value(client, |
||
1182 | LM85_REG_TACH_MODE ); |
||
1183 | data->spinup_ctl = lm85_read_value(client, |
||
1184 | LM85_REG_SPINUP_CTL ); |
||
1185 | } else if ( (data->type == adt7463) || (data->type == adm1027) ) { |
||
1186 | if ( data->type == adt7463 ) { |
||
1187 | for (i = 0; i <= 2; ++i) { |
||
1188 | data->oppoint[i] = lm85_read_value(client, |
||
1189 | ADT7463_REG_OPPOINT(i) ); |
||
1190 | } |
||
1191 | data->tmin_ctl = lm85_read_value(client, |
||
1192 | ADT7463_REG_TMIN_CTL1 ); |
||
1193 | data->therm_limit = lm85_read_value(client, |
||
1194 | ADT7463_REG_THERM_LIMIT ); |
||
1195 | } |
||
1196 | for (i = 0; i <= 2; ++i) { |
||
1197 | data->temp_offset[i] = lm85_read_value(client, |
||
1198 | ADM1027_REG_TEMP_OFFSET(i) ); |
||
1199 | } |
||
1200 | data->tach_mode = lm85_read_value(client, |
||
1201 | ADM1027_REG_CONFIG3 ); |
||
1202 | data->fan_ppr = lm85_read_value(client, |
||
1203 | ADM1027_REG_FAN_PPR ); |
||
1204 | } |
||
1205 | |||
1206 | data->last_config = jiffies; |
||
1207 | }; /* last_config */ |
||
1208 | |||
1209 | data->valid = 1; |
||
1210 | |||
1211 | up(&data->update_lock); |
||
1212 | } |
||
1213 | |||
1214 | |||
1215 | static int __init sm_lm85_init(void) |
||
1216 | { |
||
1217 | return i2c_add_driver(&lm85_driver); |
||
1218 | } |
||
1219 | |||
1220 | static void __exit sm_lm85_exit(void) |
||
1221 | { |
||
1222 | i2c_del_driver(&lm85_driver); |
||
1223 | } |
||
1224 | |||
1225 | /* Thanks to Richard Barrington for adding the LM85 to sensors-detect. |
||
1226 | * Thanks to Margit Schubert-While <margitsw@t-online.de> for help with |
||
1227 | * post 2.7.0 CVS changes |
||
1228 | */ |
||
1229 | MODULE_LICENSE("GPL"); |
||
1230 | MODULE_AUTHOR("Philip Pokorny <ppokorny@penguincomputing.com>, Margit Schubert-While <margitsw@t-online.de>"); |
||
1231 | MODULE_DESCRIPTION("LM85-B, LM85-C driver"); |
||
1232 | MODULE_PARM(lm85debug, "i"); |
||
1233 | MODULE_PARM_DESC(lm85debug, "Enable debugging statements"); |
||
1234 | |||
1235 | module_init(sm_lm85_init); |
||
1236 | module_exit(sm_lm85_exit); |