blob: 1ba072630361959678ef87def072a43755464345 [file] [log] [blame]
R.Marek@sh.cvut.cz5563e272005-07-27 11:43:47 +00001/*
2 w83792d.c - Part of lm_sensors, Linux kernel modules for hardware
3 monitoring
4 Copyright (C) 2004, 2005 Winbond Electronics Corp.
5 Chunhao Huang <DZShen@Winbond.com.tw>,
6 Rudolf Marek <r.marek@sh.cvut.cz>
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21
22 Note:
23 1. This driver is only for 2.6 kernel, 2.4 kernel need a different driver.
24 2. This driver is only for Winbond W83792D C version device, there
25 are also some motherboards with B version W83792D device. The
26 calculation method to in6-in7(measured value, limits) is a little
27 different between C and B version. C or B version can be identified
28 by CR[0x49h].
29*/
30
31/*
32 Supports following chips:
33
34 Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA
35 w83792d 9 7 7 3 0x7a 0x5ca3 yes no
36*/
37
38#include <linux/config.h>
39#include <linux/module.h>
40#include <linux/init.h>
41#include <linux/slab.h>
42#include <linux/i2c.h>
R.Marek@sh.cvut.czce785ab2005-07-27 11:50:18 +000043#include <linux/hwmon.h>
R.Marek@sh.cvut.cz5563e272005-07-27 11:43:47 +000044#include <linux/hwmon-sysfs.h>
R.Marek@sh.cvut.czce785ab2005-07-27 11:50:18 +000045#include <linux/err.h>
R.Marek@sh.cvut.cz5563e272005-07-27 11:43:47 +000046
47/* Addresses to scan */
48static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f, I2C_CLIENT_END };
49
50/* Insmod parameters */
Jean Delvaref4b50262005-07-31 21:49:03 +020051I2C_CLIENT_INSMOD_1(w83792d);
R.Marek@sh.cvut.cz5563e272005-07-27 11:43:47 +000052I2C_CLIENT_MODULE_PARM(force_subclients, "List of subclient addresses: "
53 "{bus, clientaddr, subclientaddr1, subclientaddr2}");
54
55static int init;
56module_param(init, bool, 0);
57MODULE_PARM_DESC(init, "Set to one to force chip initialization");
58
59/* The W83792D registers */
60static const u8 W83792D_REG_IN[9] = {
61 0x20, /* Vcore A in DataSheet */
62 0x21, /* Vcore B in DataSheet */
63 0x22, /* VIN0 in DataSheet */
64 0x23, /* VIN1 in DataSheet */
65 0x24, /* VIN2 in DataSheet */
66 0x25, /* VIN3 in DataSheet */
67 0x26, /* 5VCC in DataSheet */
68 0xB0, /* 5VSB in DataSheet */
69 0xB1 /* VBAT in DataSheet */
70};
71#define W83792D_REG_LOW_BITS1 0x3E /* Low Bits I in DataSheet */
72#define W83792D_REG_LOW_BITS2 0x3F /* Low Bits II in DataSheet */
73static const u8 W83792D_REG_IN_MAX[9] = {
74 0x2B, /* Vcore A High Limit in DataSheet */
75 0x2D, /* Vcore B High Limit in DataSheet */
76 0x2F, /* VIN0 High Limit in DataSheet */
77 0x31, /* VIN1 High Limit in DataSheet */
78 0x33, /* VIN2 High Limit in DataSheet */
79 0x35, /* VIN3 High Limit in DataSheet */
80 0x37, /* 5VCC High Limit in DataSheet */
81 0xB4, /* 5VSB High Limit in DataSheet */
82 0xB6 /* VBAT High Limit in DataSheet */
83};
84static const u8 W83792D_REG_IN_MIN[9] = {
85 0x2C, /* Vcore A Low Limit in DataSheet */
86 0x2E, /* Vcore B Low Limit in DataSheet */
87 0x30, /* VIN0 Low Limit in DataSheet */
88 0x32, /* VIN1 Low Limit in DataSheet */
89 0x34, /* VIN2 Low Limit in DataSheet */
90 0x36, /* VIN3 Low Limit in DataSheet */
91 0x38, /* 5VCC Low Limit in DataSheet */
92 0xB5, /* 5VSB Low Limit in DataSheet */
93 0xB7 /* VBAT Low Limit in DataSheet */
94};
95static const u8 W83792D_REG_FAN[7] = {
96 0x28, /* FAN 1 Count in DataSheet */
97 0x29, /* FAN 2 Count in DataSheet */
98 0x2A, /* FAN 3 Count in DataSheet */
99 0xB8, /* FAN 4 Count in DataSheet */
100 0xB9, /* FAN 5 Count in DataSheet */
101 0xBA, /* FAN 6 Count in DataSheet */
102 0xBE /* FAN 7 Count in DataSheet */
103};
104static const u8 W83792D_REG_FAN_MIN[7] = {
105 0x3B, /* FAN 1 Count Low Limit in DataSheet */
106 0x3C, /* FAN 2 Count Low Limit in DataSheet */
107 0x3D, /* FAN 3 Count Low Limit in DataSheet */
108 0xBB, /* FAN 4 Count Low Limit in DataSheet */
109 0xBC, /* FAN 5 Count Low Limit in DataSheet */
110 0xBD, /* FAN 6 Count Low Limit in DataSheet */
111 0xBF /* FAN 7 Count Low Limit in DataSheet */
112};
113#define W83792D_REG_FAN_CFG 0x84 /* FAN Configuration in DataSheet */
114static const u8 W83792D_REG_FAN_DIV[4] = {
115 0x47, /* contains FAN2 and FAN1 Divisor */
116 0x5B, /* contains FAN4 and FAN3 Divisor */
117 0x5C, /* contains FAN6 and FAN5 Divisor */
118 0x9E /* contains FAN7 Divisor. */
119};
120static const u8 W83792D_REG_PWM[7] = {
121 0x81, /* FAN 1 Duty Cycle, be used to control */
122 0x83, /* FAN 2 Duty Cycle, be used to control */
123 0x94, /* FAN 3 Duty Cycle, be used to control */
124 0xA3, /* FAN 4 Duty Cycle, be used to control */
125 0xA4, /* FAN 5 Duty Cycle, be used to control */
126 0xA5, /* FAN 6 Duty Cycle, be used to control */
127 0xA6 /* FAN 7 Duty Cycle, be used to control */
128};
129#define W83792D_REG_BANK 0x4E
130#define W83792D_REG_TEMP2_CONFIG 0xC2
131#define W83792D_REG_TEMP3_CONFIG 0xCA
132
133static const u8 W83792D_REG_TEMP1[3] = {
134 0x27, /* TEMP 1 in DataSheet */
135 0x39, /* TEMP 1 Over in DataSheet */
136 0x3A, /* TEMP 1 Hyst in DataSheet */
137};
138
139static const u8 W83792D_REG_TEMP_ADD[2][6] = {
140 { 0xC0, /* TEMP 2 in DataSheet */
141 0xC1, /* TEMP 2(0.5 deg) in DataSheet */
142 0xC5, /* TEMP 2 Over High part in DataSheet */
143 0xC6, /* TEMP 2 Over Low part in DataSheet */
144 0xC3, /* TEMP 2 Thyst High part in DataSheet */
145 0xC4 }, /* TEMP 2 Thyst Low part in DataSheet */
146 { 0xC8, /* TEMP 3 in DataSheet */
147 0xC9, /* TEMP 3(0.5 deg) in DataSheet */
148 0xCD, /* TEMP 3 Over High part in DataSheet */
149 0xCE, /* TEMP 3 Over Low part in DataSheet */
150 0xCB, /* TEMP 3 Thyst High part in DataSheet */
151 0xCC } /* TEMP 3 Thyst Low part in DataSheet */
152};
153
154static const u8 W83792D_REG_THERMAL[3] = {
155 0x85, /* SmartFanI: Fan1 target value */
156 0x86, /* SmartFanI: Fan2 target value */
157 0x96 /* SmartFanI: Fan3 target value */
158};
159
160static const u8 W83792D_REG_TOLERANCE[3] = {
161 0x87, /* (bit3-0)SmartFan Fan1 tolerance */
162 0x87, /* (bit7-4)SmartFan Fan2 tolerance */
163 0x97 /* (bit3-0)SmartFan Fan3 tolerance */
164};
165
166static const u8 W83792D_REG_POINTS[3][4] = {
167 { 0x85, /* SmartFanII: Fan1 temp point 1 */
168 0xE3, /* SmartFanII: Fan1 temp point 2 */
169 0xE4, /* SmartFanII: Fan1 temp point 3 */
170 0xE5 }, /* SmartFanII: Fan1 temp point 4 */
171 { 0x86, /* SmartFanII: Fan2 temp point 1 */
172 0xE6, /* SmartFanII: Fan2 temp point 2 */
173 0xE7, /* SmartFanII: Fan2 temp point 3 */
174 0xE8 }, /* SmartFanII: Fan2 temp point 4 */
175 { 0x96, /* SmartFanII: Fan3 temp point 1 */
176 0xE9, /* SmartFanII: Fan3 temp point 2 */
177 0xEA, /* SmartFanII: Fan3 temp point 3 */
178 0xEB } /* SmartFanII: Fan3 temp point 4 */
179};
180
181static const u8 W83792D_REG_LEVELS[3][4] = {
182 { 0x88, /* (bit3-0) SmartFanII: Fan1 Non-Stop */
183 0x88, /* (bit7-4) SmartFanII: Fan1 Level 1 */
184 0xE0, /* (bit7-4) SmartFanII: Fan1 Level 2 */
185 0xE0 }, /* (bit3-0) SmartFanII: Fan1 Level 3 */
186 { 0x89, /* (bit3-0) SmartFanII: Fan2 Non-Stop */
187 0x89, /* (bit7-4) SmartFanII: Fan2 Level 1 */
188 0xE1, /* (bit7-4) SmartFanII: Fan2 Level 2 */
189 0xE1 }, /* (bit3-0) SmartFanII: Fan2 Level 3 */
190 { 0x98, /* (bit3-0) SmartFanII: Fan3 Non-Stop */
191 0x98, /* (bit7-4) SmartFanII: Fan3 Level 1 */
192 0xE2, /* (bit7-4) SmartFanII: Fan3 Level 2 */
193 0xE2 } /* (bit3-0) SmartFanII: Fan3 Level 3 */
194};
195
Jean Delvare96320512005-11-29 22:27:14 +0100196#define W83792D_REG_GPIO_EN 0x1A
R.Marek@sh.cvut.cz5563e272005-07-27 11:43:47 +0000197#define W83792D_REG_CONFIG 0x40
198#define W83792D_REG_VID_FANDIV 0x47
199#define W83792D_REG_CHIPID 0x49
200#define W83792D_REG_WCHIPID 0x58
201#define W83792D_REG_CHIPMAN 0x4F
202#define W83792D_REG_PIN 0x4B
203#define W83792D_REG_I2C_SUBADDR 0x4A
204
205#define W83792D_REG_ALARM1 0xA9 /* realtime status register1 */
206#define W83792D_REG_ALARM2 0xAA /* realtime status register2 */
207#define W83792D_REG_ALARM3 0xAB /* realtime status register3 */
208#define W83792D_REG_CHASSIS 0x42 /* Bit 5: Case Open status bit */
209#define W83792D_REG_CHASSIS_CLR 0x44 /* Bit 7: Case Open CLR_CHS/Reset bit */
210
211/* control in0/in1 's limit modifiability */
212#define W83792D_REG_VID_IN_B 0x17
213
214#define W83792D_REG_VBAT 0x5D
215#define W83792D_REG_I2C_ADDR 0x48
216
217/* Conversions. Rounding and limit checking is only done on the TO_REG
218 variants. Note that you should be a bit careful with which arguments
219 these macros are called: arguments may be evaluated more than once.
220 Fixing this is just not worth it. */
221#define IN_FROM_REG(nr,val) (((nr)<=1)?(val*2): \
222 ((((nr)==6)||((nr)==7))?(val*6):(val*4)))
223#define IN_TO_REG(nr,val) (((nr)<=1)?(val/2): \
224 ((((nr)==6)||((nr)==7))?(val/6):(val/4)))
225
226static inline u8
227FAN_TO_REG(long rpm, int div)
228{
229 if (rpm == 0)
230 return 255;
231 rpm = SENSORS_LIMIT(rpm, 1, 1000000);
232 return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 254);
233}
234
235#define FAN_FROM_REG(val,div) ((val) == 0 ? -1 : \
236 ((val) == 255 ? 0 : \
237 1350000 / ((val) * (div))))
238
239/* for temp1 */
240#define TEMP1_TO_REG(val) (SENSORS_LIMIT(((val) < 0 ? (val)+0x100*1000 \
241 : (val)) / 1000, 0, 0xff))
242#define TEMP1_FROM_REG(val) (((val) & 0x80 ? (val)-0x100 : (val)) * 1000)
243/* for temp2 and temp3, because they need addtional resolution */
244#define TEMP_ADD_FROM_REG(val1, val2) \
245 ((((val1) & 0x80 ? (val1)-0x100 \
246 : (val1)) * 1000) + ((val2 & 0x80) ? 500 : 0))
247#define TEMP_ADD_TO_REG_HIGH(val) \
248 (SENSORS_LIMIT(((val) < 0 ? (val)+0x100*1000 \
249 : (val)) / 1000, 0, 0xff))
250#define TEMP_ADD_TO_REG_LOW(val) ((val%1000) ? 0x80 : 0x00)
251
252#define PWM_FROM_REG(val) (val)
253#define PWM_TO_REG(val) (SENSORS_LIMIT((val),0,255))
254#define DIV_FROM_REG(val) (1 << (val))
255
256static inline u8
257DIV_TO_REG(long val)
258{
259 int i;
260 val = SENSORS_LIMIT(val, 1, 128) >> 1;
Jean Delvare96320512005-11-29 22:27:14 +0100261 for (i = 0; i < 7; i++) {
R.Marek@sh.cvut.cz5563e272005-07-27 11:43:47 +0000262 if (val == 0)
263 break;
264 val >>= 1;
265 }
266 return ((u8) i);
267}
268
269struct w83792d_data {
270 struct i2c_client client;
R.Marek@sh.cvut.czce785ab2005-07-27 11:50:18 +0000271 struct class_device *class_dev;
R.Marek@sh.cvut.cz5563e272005-07-27 11:43:47 +0000272 struct semaphore lock;
273 enum chips type;
274
275 struct semaphore update_lock;
276 char valid; /* !=0 if following fields are valid */
277 unsigned long last_updated; /* In jiffies */
278
279 /* array of 2 pointers to subclients */
280 struct i2c_client *lm75[2];
281
282 u8 in[9]; /* Register value */
283 u8 in_max[9]; /* Register value */
284 u8 in_min[9]; /* Register value */
285 u8 low_bits[2]; /* Additional resolution to voltage in0-6 */
286 u8 fan[7]; /* Register value */
287 u8 fan_min[7]; /* Register value */
288 u8 temp1[3]; /* current, over, thyst */
289 u8 temp_add[2][6]; /* Register value */
290 u8 fan_div[7]; /* Register encoding, shifted right */
291 u8 pwm[7]; /* We only consider the first 3 set of pwm,
292 although 792 chip has 7 set of pwm. */
293 u8 pwmenable[3];
294 u8 pwm_mode[7]; /* indicates PWM or DC mode: 1->PWM; 0->DC */
295 u32 alarms; /* realtime status register encoding,combined */
296 u8 chassis; /* Chassis status */
297 u8 chassis_clear; /* CLR_CHS, clear chassis intrusion detection */
298 u8 thermal_cruise[3]; /* Smart FanI: Fan1,2,3 target value */
299 u8 tolerance[3]; /* Fan1,2,3 tolerance(Smart Fan I/II) */
300 u8 sf2_points[3][4]; /* Smart FanII: Fan1,2,3 temperature points */
301 u8 sf2_levels[3][4]; /* Smart FanII: Fan1,2,3 duty cycle levels */
302};
303
304static int w83792d_attach_adapter(struct i2c_adapter *adapter);
305static int w83792d_detect(struct i2c_adapter *adapter, int address, int kind);
306static int w83792d_detach_client(struct i2c_client *client);
307
308static int w83792d_read_value(struct i2c_client *client, u8 register);
309static int w83792d_write_value(struct i2c_client *client, u8 register,
310 u8 value);
311static struct w83792d_data *w83792d_update_device(struct device *dev);
312
313#ifdef DEBUG
314static void w83792d_print_debug(struct w83792d_data *data, struct device *dev);
315#endif
316
317static void w83792d_init_client(struct i2c_client *client);
318
319static struct i2c_driver w83792d_driver = {
320 .owner = THIS_MODULE,
321 .name = "w83792d",
322 .flags = I2C_DF_NOTIFY,
323 .attach_adapter = w83792d_attach_adapter,
324 .detach_client = w83792d_detach_client,
325};
326
327static long in_count_from_reg(int nr, struct w83792d_data *data)
328{
329 u16 vol_count = data->in[nr];
330 u16 low_bits = 0;
331 vol_count = (vol_count << 2);
332 switch (nr)
333 {
334 case 0: /* vin0 */
335 low_bits = (data->low_bits[0]) & 0x03;
336 break;
337 case 1: /* vin1 */
338 low_bits = ((data->low_bits[0]) & 0x0c) >> 2;
339 break;
340 case 2: /* vin2 */
341 low_bits = ((data->low_bits[0]) & 0x30) >> 4;
342 break;
343 case 3: /* vin3 */
344 low_bits = ((data->low_bits[0]) & 0xc0) >> 6;
345 break;
346 case 4: /* vin4 */
347 low_bits = (data->low_bits[1]) & 0x03;
348 break;
349 case 5: /* vin5 */
350 low_bits = ((data->low_bits[1]) & 0x0c) >> 2;
351 break;
352 case 6: /* vin6 */
353 low_bits = ((data->low_bits[1]) & 0x30) >> 4;
354 default:
355 break;
356 }
357 vol_count = vol_count | low_bits;
358 return vol_count;
359}
360
361/* following are the sysfs callback functions */
362static ssize_t show_in(struct device *dev, struct device_attribute *attr,
363 char *buf)
364{
365 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
366 int nr = sensor_attr->index;
367 struct w83792d_data *data = w83792d_update_device(dev);
368 return sprintf(buf,"%ld\n", IN_FROM_REG(nr,(in_count_from_reg(nr, data))));
369}
370
371#define show_in_reg(reg) \
372static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \
373 char *buf) \
374{ \
375 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \
376 int nr = sensor_attr->index; \
377 struct w83792d_data *data = w83792d_update_device(dev); \
378 return sprintf(buf,"%ld\n", (long)(IN_FROM_REG(nr, (data->reg[nr])*4))); \
379}
380
381show_in_reg(in_min);
382show_in_reg(in_max);
383
384#define store_in_reg(REG, reg) \
385static ssize_t store_in_##reg (struct device *dev, \
386 struct device_attribute *attr, \
387 const char *buf, size_t count) \
388{ \
389 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \
390 int nr = sensor_attr->index; \
391 struct i2c_client *client = to_i2c_client(dev); \
392 struct w83792d_data *data = i2c_get_clientdata(client); \
393 u32 val; \
394 \
395 val = simple_strtoul(buf, NULL, 10); \
396 data->in_##reg[nr] = SENSORS_LIMIT(IN_TO_REG(nr, val)/4, 0, 255); \
397 w83792d_write_value(client, W83792D_REG_IN_##REG[nr], data->in_##reg[nr]); \
398 \
399 return count; \
400}
401store_in_reg(MIN, min);
402store_in_reg(MAX, max);
403
404#define sysfs_in_reg(offset) \
405static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in, \
406 NULL, offset); \
407static SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \
408 show_in_min, store_in_min, offset); \
409static SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \
410 show_in_max, store_in_max, offset);
411
412sysfs_in_reg(0);
413sysfs_in_reg(1);
414sysfs_in_reg(2);
415sysfs_in_reg(3);
416sysfs_in_reg(4);
417sysfs_in_reg(5);
418sysfs_in_reg(6);
419sysfs_in_reg(7);
420sysfs_in_reg(8);
421
422#define device_create_file_in(client, offset) \
423do { \
424device_create_file(&client->dev, &sensor_dev_attr_in##offset##_input.dev_attr); \
425device_create_file(&client->dev, &sensor_dev_attr_in##offset##_max.dev_attr); \
426device_create_file(&client->dev, &sensor_dev_attr_in##offset##_min.dev_attr); \
427} while (0)
428
429#define show_fan_reg(reg) \
430static ssize_t show_##reg (struct device *dev, struct device_attribute *attr, \
431 char *buf) \
432{ \
433 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \
434 int nr = sensor_attr->index - 1; \
435 struct w83792d_data *data = w83792d_update_device(dev); \
436 return sprintf(buf,"%d\n", \
437 FAN_FROM_REG(data->reg[nr], DIV_FROM_REG(data->fan_div[nr]))); \
438}
439
440show_fan_reg(fan);
441show_fan_reg(fan_min);
442
443static ssize_t
444store_fan_min(struct device *dev, struct device_attribute *attr,
445 const char *buf, size_t count)
446{
447 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
448 int nr = sensor_attr->index - 1;
449 struct i2c_client *client = to_i2c_client(dev);
450 struct w83792d_data *data = i2c_get_clientdata(client);
451 u32 val;
452
453 val = simple_strtoul(buf, NULL, 10);
454 data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
455 w83792d_write_value(client, W83792D_REG_FAN_MIN[nr],
456 data->fan_min[nr]);
457
458 return count;
459}
460
461static ssize_t
462show_fan_div(struct device *dev, struct device_attribute *attr,
463 char *buf)
464{
465 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
466 int nr = sensor_attr->index;
467 struct w83792d_data *data = w83792d_update_device(dev);
468 return sprintf(buf, "%u\n", DIV_FROM_REG(data->fan_div[nr - 1]));
469}
470
471/* Note: we save and restore the fan minimum here, because its value is
472 determined in part by the fan divisor. This follows the principle of
473 least suprise; the user doesn't expect the fan minimum to change just
474 because the divisor changed. */
475static ssize_t
476store_fan_div(struct device *dev, struct device_attribute *attr,
477 const char *buf, size_t count)
478{
479 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
480 int nr = sensor_attr->index - 1;
481 struct i2c_client *client = to_i2c_client(dev);
482 struct w83792d_data *data = i2c_get_clientdata(client);
483 unsigned long min;
484 /*u8 reg;*/
485 u8 fan_div_reg = 0;
486 u8 tmp_fan_div;
487
488 /* Save fan_min */
489 min = FAN_FROM_REG(data->fan_min[nr],
490 DIV_FROM_REG(data->fan_div[nr]));
491
492 data->fan_div[nr] = DIV_TO_REG(simple_strtoul(buf, NULL, 10));
493
494 fan_div_reg = w83792d_read_value(client, W83792D_REG_FAN_DIV[nr >> 1]);
495 fan_div_reg &= (nr & 0x01) ? 0x8f : 0xf8;
496 tmp_fan_div = (nr & 0x01) ? (((data->fan_div[nr]) << 4) & 0x70)
497 : ((data->fan_div[nr]) & 0x07);
498 w83792d_write_value(client, W83792D_REG_FAN_DIV[nr >> 1],
499 fan_div_reg | tmp_fan_div);
500
501 /* Restore fan_min */
502 data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
503 w83792d_write_value(client, W83792D_REG_FAN_MIN[nr], data->fan_min[nr]);
504
505 return count;
506}
507
508#define sysfs_fan(offset) \
509static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan, NULL, \
510 offset); \
511static SENSOR_DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \
512 show_fan_div, store_fan_div, offset); \
513static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
514 show_fan_min, store_fan_min, offset);
515
516sysfs_fan(1);
517sysfs_fan(2);
518sysfs_fan(3);
519sysfs_fan(4);
520sysfs_fan(5);
521sysfs_fan(6);
522sysfs_fan(7);
523
524#define device_create_file_fan(client, offset) \
525do { \
526device_create_file(&client->dev, &sensor_dev_attr_fan##offset##_input.dev_attr); \
527device_create_file(&client->dev, &sensor_dev_attr_fan##offset##_div.dev_attr); \
528device_create_file(&client->dev, &sensor_dev_attr_fan##offset##_min.dev_attr); \
529} while (0)
530
531
532/* read/write the temperature1, includes measured value and limits */
533
534static ssize_t show_temp1(struct device *dev, struct device_attribute *attr,
535 char *buf)
536{
537 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
538 int nr = sensor_attr->index;
539 struct w83792d_data *data = w83792d_update_device(dev);
540 return sprintf(buf, "%d\n", TEMP1_FROM_REG(data->temp1[nr]));
541}
542
543static ssize_t store_temp1(struct device *dev, struct device_attribute *attr,
544 const char *buf, size_t count)
545{
546 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
547 int nr = sensor_attr->index;
548 struct i2c_client *client = to_i2c_client(dev);
549 struct w83792d_data *data = i2c_get_clientdata(client);
550 s32 val;
551
552 val = simple_strtol(buf, NULL, 10);
553
554 data->temp1[nr] = TEMP1_TO_REG(val);
555 w83792d_write_value(client, W83792D_REG_TEMP1[nr],
556 data->temp1[nr]);
557
558 return count;
559}
560
561
562static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp1, NULL, 0);
563static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR, show_temp1,
564 store_temp1, 1);
565static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR, show_temp1,
566 store_temp1, 2);
567
568#define device_create_file_temp1(client) \
569do { \
570device_create_file(&client->dev, &sensor_dev_attr_temp1_input.dev_attr); \
571device_create_file(&client->dev, &sensor_dev_attr_temp1_max.dev_attr); \
572device_create_file(&client->dev, &sensor_dev_attr_temp1_max_hyst.dev_attr); \
573} while (0)
574
575
576/* read/write the temperature2-3, includes measured value and limits */
577
578static ssize_t show_temp23(struct device *dev, struct device_attribute *attr,
579 char *buf)
580{
581 struct sensor_device_attribute_2 *sensor_attr = to_sensor_dev_attr_2(attr);
582 int nr = sensor_attr->nr;
583 int index = sensor_attr->index;
584 struct w83792d_data *data = w83792d_update_device(dev);
585 return sprintf(buf,"%ld\n",
586 (long)TEMP_ADD_FROM_REG(data->temp_add[nr][index],
587 data->temp_add[nr][index+1]));
588}
589
590static ssize_t store_temp23(struct device *dev, struct device_attribute *attr,
591 const char *buf, size_t count)
592{
593 struct sensor_device_attribute_2 *sensor_attr = to_sensor_dev_attr_2(attr);
594 int nr = sensor_attr->nr;
595 int index = sensor_attr->index;
596 struct i2c_client *client = to_i2c_client(dev);
597 struct w83792d_data *data = i2c_get_clientdata(client);
598 s32 val;
599
600 val = simple_strtol(buf, NULL, 10);
601
602 data->temp_add[nr][index] = TEMP_ADD_TO_REG_HIGH(val);
603 data->temp_add[nr][index+1] = TEMP_ADD_TO_REG_LOW(val);
604 w83792d_write_value(client, W83792D_REG_TEMP_ADD[nr][index],
605 data->temp_add[nr][index]);
606 w83792d_write_value(client, W83792D_REG_TEMP_ADD[nr][index+1],
607 data->temp_add[nr][index+1]);
608
609 return count;
610}
611
612#define sysfs_temp23(name,idx) \
613static SENSOR_DEVICE_ATTR_2(name##_input, S_IRUGO, show_temp23, NULL, \
614 idx, 0); \
615static SENSOR_DEVICE_ATTR_2(name##_max, S_IRUGO | S_IWUSR, \
616 show_temp23, store_temp23, idx, 2); \
617static SENSOR_DEVICE_ATTR_2(name##_max_hyst, S_IRUGO | S_IWUSR, \
618 show_temp23, store_temp23, idx, 4);
619
620sysfs_temp23(temp2,0)
621sysfs_temp23(temp3,1)
622
623#define device_create_file_temp_add(client, offset) \
624do { \
625device_create_file(&client->dev, &sensor_dev_attr_temp##offset##_input.dev_attr); \
626device_create_file(&client->dev, &sensor_dev_attr_temp##offset##_max.dev_attr); \
627device_create_file(&client->dev, \
628&sensor_dev_attr_temp##offset##_max_hyst.dev_attr); \
629} while (0)
630
631
632/* get reatime status of all sensors items: voltage, temp, fan */
633static ssize_t
634show_alarms_reg(struct device *dev, struct device_attribute *attr, char *buf)
635{
636 struct w83792d_data *data = w83792d_update_device(dev);
637 return sprintf(buf, "%d\n", data->alarms);
638}
639
640static
641DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL);
642#define device_create_file_alarms(client) \
643device_create_file(&client->dev, &dev_attr_alarms);
644
645
646
647static ssize_t
648show_pwm(struct device *dev, struct device_attribute *attr,
649 char *buf)
650{
651 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
652 int nr = sensor_attr->index;
653 struct w83792d_data *data = w83792d_update_device(dev);
654 return sprintf(buf, "%ld\n", (long) PWM_FROM_REG(data->pwm[nr-1]));
655}
656
657static ssize_t
658show_pwmenable(struct device *dev, struct device_attribute *attr,
659 char *buf)
660{
661 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
662 int nr = sensor_attr->index - 1;
663 struct w83792d_data *data = w83792d_update_device(dev);
664 long pwm_enable_tmp = 1;
665
666 switch (data->pwmenable[nr]) {
667 case 0:
668 pwm_enable_tmp = 1; /* manual mode */
669 break;
670 case 1:
671 pwm_enable_tmp = 3; /*thermal cruise/Smart Fan I */
672 break;
673 case 2:
674 pwm_enable_tmp = 2; /* Smart Fan II */
675 break;
676 }
677
678 return sprintf(buf, "%ld\n", pwm_enable_tmp);
679}
680
681static ssize_t
682store_pwm(struct device *dev, struct device_attribute *attr,
683 const char *buf, size_t count)
684{
685 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
686 int nr = sensor_attr->index - 1;
687 struct i2c_client *client = to_i2c_client(dev);
688 struct w83792d_data *data = i2c_get_clientdata(client);
689 u32 val;
690
691 val = simple_strtoul(buf, NULL, 10);
692 data->pwm[nr] = PWM_TO_REG(val);
693 w83792d_write_value(client, W83792D_REG_PWM[nr], data->pwm[nr]);
694
695 return count;
696}
697
698static ssize_t
699store_pwmenable(struct device *dev, struct device_attribute *attr,
700 const char *buf, size_t count)
701{
702 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
703 int nr = sensor_attr->index - 1;
704 struct i2c_client *client = to_i2c_client(dev);
705 struct w83792d_data *data = i2c_get_clientdata(client);
706 u32 val;
707 u8 fan_cfg_tmp, cfg1_tmp, cfg2_tmp, cfg3_tmp, cfg4_tmp;
708
709 val = simple_strtoul(buf, NULL, 10);
710 switch (val) {
711 case 1:
712 data->pwmenable[nr] = 0; /* manual mode */
713 break;
714 case 2:
715 data->pwmenable[nr] = 2; /* Smart Fan II */
716 break;
717 case 3:
718 data->pwmenable[nr] = 1; /* thermal cruise/Smart Fan I */
719 break;
720 default:
721 return -EINVAL;
722 }
723 cfg1_tmp = data->pwmenable[0];
724 cfg2_tmp = (data->pwmenable[1]) << 2;
725 cfg3_tmp = (data->pwmenable[2]) << 4;
726 cfg4_tmp = w83792d_read_value(client,W83792D_REG_FAN_CFG) & 0xc0;
727 fan_cfg_tmp = ((cfg4_tmp | cfg3_tmp) | cfg2_tmp) | cfg1_tmp;
728 w83792d_write_value(client, W83792D_REG_FAN_CFG, fan_cfg_tmp);
729
730 return count;
731}
732
733#define sysfs_pwm(offset) \
734static SENSOR_DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \
735 show_pwm, store_pwm, offset); \
736static SENSOR_DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR, \
737 show_pwmenable, store_pwmenable, offset); \
738
739sysfs_pwm(1);
740sysfs_pwm(2);
741sysfs_pwm(3);
742
743
744#define device_create_file_pwm(client, offset) \
745do { \
746device_create_file(&client->dev, &sensor_dev_attr_pwm##offset.dev_attr); \
747} while (0)
748
749#define device_create_file_pwmenable(client, offset) \
750do { \
751device_create_file(&client->dev, &sensor_dev_attr_pwm##offset##_enable.dev_attr); \
752} while (0)
753
754
755static ssize_t
756show_pwm_mode(struct device *dev, struct device_attribute *attr,
757 char *buf)
758{
759 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
760 int nr = sensor_attr->index;
761 struct w83792d_data *data = w83792d_update_device(dev);
762 return sprintf(buf, "%d\n", data->pwm_mode[nr-1]);
763}
764
765static ssize_t
766store_pwm_mode(struct device *dev, struct device_attribute *attr,
767 const char *buf, size_t count)
768{
769 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
770 int nr = sensor_attr->index - 1;
771 struct i2c_client *client = to_i2c_client(dev);
772 struct w83792d_data *data = i2c_get_clientdata(client);
773 u32 val;
774 u8 pwm_mode_mask = 0;
775
776 val = simple_strtoul(buf, NULL, 10);
777 data->pwm_mode[nr] = SENSORS_LIMIT(val, 0, 1);
778 pwm_mode_mask = w83792d_read_value(client,
779 W83792D_REG_PWM[nr]) & 0x7f;
780 w83792d_write_value(client, W83792D_REG_PWM[nr],
781 ((data->pwm_mode[nr]) << 7) | pwm_mode_mask);
782
783 return count;
784}
785
786#define sysfs_pwm_mode(offset) \
787static SENSOR_DEVICE_ATTR(pwm##offset##_mode, S_IRUGO | S_IWUSR, \
788 show_pwm_mode, store_pwm_mode, offset);
789
790sysfs_pwm_mode(1);
791sysfs_pwm_mode(2);
792sysfs_pwm_mode(3);
793
794#define device_create_file_pwm_mode(client, offset) \
795do { \
796device_create_file(&client->dev, &sensor_dev_attr_pwm##offset##_mode.dev_attr); \
797} while (0)
798
799
800static ssize_t
801show_regs_chassis(struct device *dev, struct device_attribute *attr,
802 char *buf)
803{
804 struct w83792d_data *data = w83792d_update_device(dev);
805 return sprintf(buf, "%d\n", data->chassis);
806}
807
808static DEVICE_ATTR(chassis, S_IRUGO, show_regs_chassis, NULL);
809
810#define device_create_file_chassis(client) \
811do { \
812device_create_file(&client->dev, &dev_attr_chassis); \
813} while (0)
814
815
816static ssize_t
817show_chassis_clear(struct device *dev, struct device_attribute *attr, char *buf)
818{
819 struct w83792d_data *data = w83792d_update_device(dev);
820 return sprintf(buf, "%d\n", data->chassis_clear);
821}
822
823static ssize_t
824store_chassis_clear(struct device *dev, struct device_attribute *attr,
825 const char *buf, size_t count)
826{
827 struct i2c_client *client = to_i2c_client(dev);
828 struct w83792d_data *data = i2c_get_clientdata(client);
829 u32 val;
830 u8 temp1 = 0, temp2 = 0;
831
832 val = simple_strtoul(buf, NULL, 10);
833
834 data->chassis_clear = SENSORS_LIMIT(val, 0 ,1);
835 temp1 = ((data->chassis_clear) << 7) & 0x80;
836 temp2 = w83792d_read_value(client,
837 W83792D_REG_CHASSIS_CLR) & 0x7f;
838 w83792d_write_value(client, W83792D_REG_CHASSIS_CLR, temp1 | temp2);
839
840 return count;
841}
842
843static DEVICE_ATTR(chassis_clear, S_IRUGO | S_IWUSR,
844 show_chassis_clear, store_chassis_clear);
845
846#define device_create_file_chassis_clear(client) \
847do { \
848device_create_file(&client->dev, &dev_attr_chassis_clear); \
849} while (0)
850
851
852
853/* For Smart Fan I / Thermal Cruise */
854static ssize_t
855show_thermal_cruise(struct device *dev, struct device_attribute *attr,
856 char *buf)
857{
858 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
859 int nr = sensor_attr->index;
860 struct w83792d_data *data = w83792d_update_device(dev);
861 return sprintf(buf, "%ld\n", (long)data->thermal_cruise[nr-1]);
862}
863
864static ssize_t
865store_thermal_cruise(struct device *dev, struct device_attribute *attr,
866 const char *buf, size_t count)
867{
868 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
869 int nr = sensor_attr->index - 1;
870 struct i2c_client *client = to_i2c_client(dev);
871 struct w83792d_data *data = i2c_get_clientdata(client);
872 u32 val;
873 u8 target_tmp=0, target_mask=0;
874
875 val = simple_strtoul(buf, NULL, 10);
876 target_tmp = val;
877 target_tmp = target_tmp & 0x7f;
878 target_mask = w83792d_read_value(client, W83792D_REG_THERMAL[nr]) & 0x80;
879 data->thermal_cruise[nr] = SENSORS_LIMIT(target_tmp, 0, 255);
880 w83792d_write_value(client, W83792D_REG_THERMAL[nr],
881 (data->thermal_cruise[nr]) | target_mask);
882
883 return count;
884}
885
886#define sysfs_thermal_cruise(offset) \
887static SENSOR_DEVICE_ATTR(thermal_cruise##offset, S_IRUGO | S_IWUSR, \
888 show_thermal_cruise, store_thermal_cruise, offset);
889
890sysfs_thermal_cruise(1);
891sysfs_thermal_cruise(2);
892sysfs_thermal_cruise(3);
893
894#define device_create_file_thermal_cruise(client, offset) \
895do { \
896device_create_file(&client->dev, \
897&sensor_dev_attr_thermal_cruise##offset.dev_attr); \
898} while (0)
899
900
901/* For Smart Fan I/Thermal Cruise and Smart Fan II */
902static ssize_t
903show_tolerance(struct device *dev, struct device_attribute *attr,
904 char *buf)
905{
906 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
907 int nr = sensor_attr->index;
908 struct w83792d_data *data = w83792d_update_device(dev);
909 return sprintf(buf, "%ld\n", (long)data->tolerance[nr-1]);
910}
911
912static ssize_t
913store_tolerance(struct device *dev, struct device_attribute *attr,
914 const char *buf, size_t count)
915{
916 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
917 int nr = sensor_attr->index - 1;
918 struct i2c_client *client = to_i2c_client(dev);
919 struct w83792d_data *data = i2c_get_clientdata(client);
920 u32 val;
921 u8 tol_tmp, tol_mask;
922
923 val = simple_strtoul(buf, NULL, 10);
924 tol_mask = w83792d_read_value(client,
925 W83792D_REG_TOLERANCE[nr]) & ((nr == 1) ? 0x0f : 0xf0);
926 tol_tmp = SENSORS_LIMIT(val, 0, 15);
927 tol_tmp &= 0x0f;
928 data->tolerance[nr] = tol_tmp;
929 if (nr == 1) {
930 tol_tmp <<= 4;
931 }
932 w83792d_write_value(client, W83792D_REG_TOLERANCE[nr],
933 tol_mask | tol_tmp);
934
935 return count;
936}
937
938#define sysfs_tolerance(offset) \
939static SENSOR_DEVICE_ATTR(tolerance##offset, S_IRUGO | S_IWUSR, \
940 show_tolerance, store_tolerance, offset);
941
942sysfs_tolerance(1);
943sysfs_tolerance(2);
944sysfs_tolerance(3);
945
946#define device_create_file_tolerance(client, offset) \
947do { \
948device_create_file(&client->dev, &sensor_dev_attr_tolerance##offset.dev_attr); \
949} while (0)
950
951
952/* For Smart Fan II */
953static ssize_t
954show_sf2_point(struct device *dev, struct device_attribute *attr,
955 char *buf)
956{
957 struct sensor_device_attribute_2 *sensor_attr = to_sensor_dev_attr_2(attr);
958 int nr = sensor_attr->nr;
959 int index = sensor_attr->index;
960 struct w83792d_data *data = w83792d_update_device(dev);
961 return sprintf(buf, "%ld\n", (long)data->sf2_points[index-1][nr-1]);
962}
963
964static ssize_t
965store_sf2_point(struct device *dev, struct device_attribute *attr,
966 const char *buf, size_t count)
967{
968 struct sensor_device_attribute_2 *sensor_attr = to_sensor_dev_attr_2(attr);
969 int nr = sensor_attr->nr - 1;
970 int index = sensor_attr->index - 1;
971 struct i2c_client *client = to_i2c_client(dev);
972 struct w83792d_data *data = i2c_get_clientdata(client);
973 u32 val;
974 u8 mask_tmp = 0;
975
976 val = simple_strtoul(buf, NULL, 10);
977 data->sf2_points[index][nr] = SENSORS_LIMIT(val, 0, 127);
978 mask_tmp = w83792d_read_value(client,
979 W83792D_REG_POINTS[index][nr]) & 0x80;
980 w83792d_write_value(client, W83792D_REG_POINTS[index][nr],
981 mask_tmp|data->sf2_points[index][nr]);
982
983 return count;
984}
985
986#define sysfs_sf2_point(offset, index) \
987static SENSOR_DEVICE_ATTR_2(sf2_point##offset##_fan##index, S_IRUGO | S_IWUSR, \
988 show_sf2_point, store_sf2_point, offset, index);
989
990sysfs_sf2_point(1, 1); /* Fan1 */
991sysfs_sf2_point(2, 1); /* Fan1 */
992sysfs_sf2_point(3, 1); /* Fan1 */
993sysfs_sf2_point(4, 1); /* Fan1 */
994sysfs_sf2_point(1, 2); /* Fan2 */
995sysfs_sf2_point(2, 2); /* Fan2 */
996sysfs_sf2_point(3, 2); /* Fan2 */
997sysfs_sf2_point(4, 2); /* Fan2 */
998sysfs_sf2_point(1, 3); /* Fan3 */
999sysfs_sf2_point(2, 3); /* Fan3 */
1000sysfs_sf2_point(3, 3); /* Fan3 */
1001sysfs_sf2_point(4, 3); /* Fan3 */
1002
1003#define device_create_file_sf2_point(client, offset, index) \
1004do { \
1005device_create_file(&client->dev, \
1006&sensor_dev_attr_sf2_point##offset##_fan##index.dev_attr); \
1007} while (0)
1008
1009
1010static ssize_t
1011show_sf2_level(struct device *dev, struct device_attribute *attr,
1012 char *buf)
1013{
1014 struct sensor_device_attribute_2 *sensor_attr = to_sensor_dev_attr_2(attr);
1015 int nr = sensor_attr->nr;
1016 int index = sensor_attr->index;
1017 struct w83792d_data *data = w83792d_update_device(dev);
1018 return sprintf(buf, "%d\n",
1019 (((data->sf2_levels[index-1][nr]) * 100) / 15));
1020}
1021
1022static ssize_t
1023store_sf2_level(struct device *dev, struct device_attribute *attr,
1024 const char *buf, size_t count)
1025{
1026 struct sensor_device_attribute_2 *sensor_attr = to_sensor_dev_attr_2(attr);
1027 int nr = sensor_attr->nr;
1028 int index = sensor_attr->index - 1;
1029 struct i2c_client *client = to_i2c_client(dev);
1030 struct w83792d_data *data = i2c_get_clientdata(client);
1031 u32 val;
1032 u8 mask_tmp=0, level_tmp=0;
1033
1034 val = simple_strtoul(buf, NULL, 10);
1035 data->sf2_levels[index][nr] = SENSORS_LIMIT((val * 15) / 100, 0, 15);
1036 mask_tmp = w83792d_read_value(client, W83792D_REG_LEVELS[index][nr])
1037 & ((nr==3) ? 0xf0 : 0x0f);
1038 if (nr==3) {
1039 level_tmp = data->sf2_levels[index][nr];
1040 } else {
1041 level_tmp = data->sf2_levels[index][nr] << 4;
1042 }
1043 w83792d_write_value(client, W83792D_REG_LEVELS[index][nr], level_tmp | mask_tmp);
1044
1045 return count;
1046}
1047
1048#define sysfs_sf2_level(offset, index) \
1049static SENSOR_DEVICE_ATTR_2(sf2_level##offset##_fan##index, S_IRUGO | S_IWUSR, \
1050 show_sf2_level, store_sf2_level, offset, index);
1051
1052sysfs_sf2_level(1, 1); /* Fan1 */
1053sysfs_sf2_level(2, 1); /* Fan1 */
1054sysfs_sf2_level(3, 1); /* Fan1 */
1055sysfs_sf2_level(1, 2); /* Fan2 */
1056sysfs_sf2_level(2, 2); /* Fan2 */
1057sysfs_sf2_level(3, 2); /* Fan2 */
1058sysfs_sf2_level(1, 3); /* Fan3 */
1059sysfs_sf2_level(2, 3); /* Fan3 */
1060sysfs_sf2_level(3, 3); /* Fan3 */
1061
1062#define device_create_file_sf2_level(client, offset, index) \
1063do { \
1064device_create_file(&client->dev, \
1065&sensor_dev_attr_sf2_level##offset##_fan##index.dev_attr); \
1066} while (0)
1067
1068
1069/* This function is called when:
1070 * w83792d_driver is inserted (when this module is loaded), for each
1071 available adapter
1072 * when a new adapter is inserted (and w83792d_driver is still present) */
1073static int
1074w83792d_attach_adapter(struct i2c_adapter *adapter)
1075{
1076 if (!(adapter->class & I2C_CLASS_HWMON))
1077 return 0;
Jean Delvare2ed2dc32005-07-31 21:42:02 +02001078 return i2c_probe(adapter, &addr_data, w83792d_detect);
R.Marek@sh.cvut.cz5563e272005-07-27 11:43:47 +00001079}
1080
1081
1082static int
1083w83792d_create_subclient(struct i2c_adapter *adapter,
1084 struct i2c_client *new_client, int addr,
1085 struct i2c_client **sub_cli)
1086{
1087 int err;
1088 struct i2c_client *sub_client;
1089
Deepak Saxenaba9c2e82005-10-17 23:08:32 +02001090 (*sub_cli) = sub_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
R.Marek@sh.cvut.cz5563e272005-07-27 11:43:47 +00001091 if (!(sub_client)) {
1092 return -ENOMEM;
1093 }
R.Marek@sh.cvut.cz5563e272005-07-27 11:43:47 +00001094 sub_client->addr = 0x48 + addr;
1095 i2c_set_clientdata(sub_client, NULL);
1096 sub_client->adapter = adapter;
1097 sub_client->driver = &w83792d_driver;
1098 sub_client->flags = 0;
1099 strlcpy(sub_client->name, "w83792d subclient", I2C_NAME_SIZE);
1100 if ((err = i2c_attach_client(sub_client))) {
1101 dev_err(&new_client->dev, "subclient registration "
1102 "at address 0x%x failed\n", sub_client->addr);
1103 kfree(sub_client);
1104 return err;
1105 }
1106 return 0;
1107}
1108
1109
1110static int
1111w83792d_detect_subclients(struct i2c_adapter *adapter, int address, int kind,
1112 struct i2c_client *new_client)
1113{
1114 int i, id, err;
1115 u8 val;
1116 struct w83792d_data *data = i2c_get_clientdata(new_client);
1117
1118 id = i2c_adapter_id(adapter);
1119 if (force_subclients[0] == id && force_subclients[1] == address) {
1120 for (i = 2; i <= 3; i++) {
1121 if (force_subclients[i] < 0x48 ||
1122 force_subclients[i] > 0x4f) {
1123 dev_err(&new_client->dev, "invalid subclient "
1124 "address %d; must be 0x48-0x4f\n",
1125 force_subclients[i]);
1126 err = -ENODEV;
1127 goto ERROR_SC_0;
1128 }
1129 }
1130 w83792d_write_value(new_client, W83792D_REG_I2C_SUBADDR,
1131 (force_subclients[2] & 0x07) |
1132 ((force_subclients[3] & 0x07) << 4));
1133 }
1134
1135 val = w83792d_read_value(new_client, W83792D_REG_I2C_SUBADDR);
1136 if (!(val & 0x08)) {
1137 err = w83792d_create_subclient(adapter, new_client, val & 0x7,
1138 &data->lm75[0]);
1139 if (err < 0)
1140 goto ERROR_SC_0;
1141 }
1142 if (!(val & 0x80)) {
1143 if ((data->lm75[0] != NULL) &&
1144 ((val & 0x7) == ((val >> 4) & 0x7))) {
1145 dev_err(&new_client->dev, "duplicate addresses 0x%x, "
1146 "use force_subclient\n", data->lm75[0]->addr);
1147 err = -ENODEV;
1148 goto ERROR_SC_1;
1149 }
1150 err = w83792d_create_subclient(adapter, new_client,
1151 (val >> 4) & 0x7, &data->lm75[1]);
1152 if (err < 0)
1153 goto ERROR_SC_1;
1154 }
1155
1156 return 0;
1157
1158/* Undo inits in case of errors */
1159
1160ERROR_SC_1:
1161 if (data->lm75[0] != NULL) {
1162 i2c_detach_client(data->lm75[0]);
1163 kfree(data->lm75[0]);
1164 }
1165ERROR_SC_0:
1166 return err;
1167}
1168
1169
1170static int
1171w83792d_detect(struct i2c_adapter *adapter, int address, int kind)
1172{
1173 int i = 0, val1 = 0, val2;
1174 struct i2c_client *new_client;
1175 struct w83792d_data *data;
1176 int err = 0;
1177 const char *client_name = "";
1178
1179 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
1180 goto ERROR0;
1181 }
1182
1183 /* OK. For now, we presume we have a valid client. We now create the
1184 client structure, even though we cannot fill it completely yet.
1185 But it allows us to access w83792d_{read,write}_value. */
1186
Deepak Saxenaba9c2e82005-10-17 23:08:32 +02001187 if (!(data = kzalloc(sizeof(struct w83792d_data), GFP_KERNEL))) {
R.Marek@sh.cvut.cz5563e272005-07-27 11:43:47 +00001188 err = -ENOMEM;
1189 goto ERROR0;
1190 }
R.Marek@sh.cvut.cz5563e272005-07-27 11:43:47 +00001191
1192 new_client = &data->client;
1193 i2c_set_clientdata(new_client, data);
1194 new_client->addr = address;
1195 init_MUTEX(&data->lock);
1196 new_client->adapter = adapter;
1197 new_client->driver = &w83792d_driver;
1198 new_client->flags = 0;
1199
1200 /* Now, we do the remaining detection. */
1201
1202 /* The w83792d may be stuck in some other bank than bank 0. This may
1203 make reading other information impossible. Specify a force=... or
1204 force_*=... parameter, and the Winbond will be reset to the right
1205 bank. */
1206 if (kind < 0) {
1207 if (w83792d_read_value(new_client, W83792D_REG_CONFIG) & 0x80) {
1208 dev_warn(&new_client->dev, "Detection failed at step "
1209 "3\n");
1210 goto ERROR1;
1211 }
1212 val1 = w83792d_read_value(new_client, W83792D_REG_BANK);
1213 val2 = w83792d_read_value(new_client, W83792D_REG_CHIPMAN);
1214 /* Check for Winbond ID if in bank 0 */
1215 if (!(val1 & 0x07)) { /* is Bank0 */
1216 if (((!(val1 & 0x80)) && (val2 != 0xa3)) ||
1217 ((val1 & 0x80) && (val2 != 0x5c))) {
1218 goto ERROR1;
1219 }
1220 }
1221 /* If Winbond chip, address of chip and W83792D_REG_I2C_ADDR
1222 should match */
1223 if (w83792d_read_value(new_client,
1224 W83792D_REG_I2C_ADDR) != address) {
1225 dev_warn(&new_client->dev, "Detection failed "
1226 "at step 5\n");
1227 goto ERROR1;
1228 }
1229 }
1230
1231 /* We have either had a force parameter, or we have already detected the
1232 Winbond. Put it now into bank 0 and Vendor ID High Byte */
1233 w83792d_write_value(new_client,
1234 W83792D_REG_BANK,
1235 (w83792d_read_value(new_client,
1236 W83792D_REG_BANK) & 0x78) | 0x80);
1237
1238 /* Determine the chip type. */
1239 if (kind <= 0) {
1240 /* get vendor ID */
1241 val2 = w83792d_read_value(new_client, W83792D_REG_CHIPMAN);
1242 if (val2 != 0x5c) { /* the vendor is NOT Winbond */
1243 goto ERROR1;
1244 }
1245 val1 = w83792d_read_value(new_client, W83792D_REG_WCHIPID);
1246 if (val1 == 0x7a && address >= 0x2c) {
1247 kind = w83792d;
1248 } else {
1249 if (kind == 0)
1250 dev_warn(&new_client->dev,
1251 "w83792d: Ignoring 'force' parameter for"
1252 " unknown chip at adapter %d, address"
1253 " 0x%02x\n", i2c_adapter_id(adapter),
1254 address);
1255 goto ERROR1;
1256 }
1257 }
1258
1259 if (kind == w83792d) {
1260 client_name = "w83792d";
1261 } else {
1262 dev_err(&new_client->dev, "w83792d: Internal error: unknown"
1263 " kind (%d)?!?", kind);
1264 goto ERROR1;
1265 }
1266
1267 /* Fill in the remaining client fields and put into the global list */
1268 strlcpy(new_client->name, client_name, I2C_NAME_SIZE);
1269 data->type = kind;
1270
1271 data->valid = 0;
1272 init_MUTEX(&data->update_lock);
1273
1274 /* Tell the I2C layer a new client has arrived */
1275 if ((err = i2c_attach_client(new_client)))
1276 goto ERROR1;
1277
1278 if ((err = w83792d_detect_subclients(adapter, address,
1279 kind, new_client)))
1280 goto ERROR2;
1281
1282 /* Initialize the chip */
1283 w83792d_init_client(new_client);
1284
1285 /* A few vars need to be filled upon startup */
Jean Delvare96320512005-11-29 22:27:14 +01001286 for (i = 0; i < 7; i++) {
1287 data->fan_min[i] = w83792d_read_value(new_client,
R.Marek@sh.cvut.cz5563e272005-07-27 11:43:47 +00001288 W83792D_REG_FAN_MIN[i]);
1289 }
1290
1291 /* Register sysfs hooks */
R.Marek@sh.cvut.czce785ab2005-07-27 11:50:18 +00001292 data->class_dev = hwmon_device_register(&new_client->dev);
1293 if (IS_ERR(data->class_dev)) {
1294 err = PTR_ERR(data->class_dev);
1295 goto ERROR3;
1296 }
R.Marek@sh.cvut.cz5563e272005-07-27 11:43:47 +00001297 device_create_file_in(new_client, 0);
1298 device_create_file_in(new_client, 1);
1299 device_create_file_in(new_client, 2);
1300 device_create_file_in(new_client, 3);
1301 device_create_file_in(new_client, 4);
1302 device_create_file_in(new_client, 5);
1303 device_create_file_in(new_client, 6);
1304 device_create_file_in(new_client, 7);
1305 device_create_file_in(new_client, 8);
1306
1307 device_create_file_fan(new_client, 1);
1308 device_create_file_fan(new_client, 2);
1309 device_create_file_fan(new_client, 3);
Jean Delvare96320512005-11-29 22:27:14 +01001310
1311 /* Read GPIO enable register to check if pins for fan 4,5 are used as
1312 GPIO */
1313 val1 = w83792d_read_value(new_client, W83792D_REG_GPIO_EN);
1314 if (!(val1 & 0x40))
1315 device_create_file_fan(new_client, 4);
1316 if (!(val1 & 0x20))
1317 device_create_file_fan(new_client, 5);
1318
1319 val1 = w83792d_read_value(new_client, W83792D_REG_PIN);
1320 if (val1 & 0x40)
1321 device_create_file_fan(new_client, 6);
1322 if (val1 & 0x04)
1323 device_create_file_fan(new_client, 7);
R.Marek@sh.cvut.cz5563e272005-07-27 11:43:47 +00001324
1325 device_create_file_temp1(new_client); /* Temp1 */
1326 device_create_file_temp_add(new_client, 2); /* Temp2 */
1327 device_create_file_temp_add(new_client, 3); /* Temp3 */
1328
1329 device_create_file_alarms(new_client);
1330
1331 device_create_file_pwm(new_client, 1);
1332 device_create_file_pwm(new_client, 2);
1333 device_create_file_pwm(new_client, 3);
1334
1335 device_create_file_pwmenable(new_client, 1);
1336 device_create_file_pwmenable(new_client, 2);
1337 device_create_file_pwmenable(new_client, 3);
1338
1339 device_create_file_pwm_mode(new_client, 1);
1340 device_create_file_pwm_mode(new_client, 2);
1341 device_create_file_pwm_mode(new_client, 3);
1342
1343 device_create_file_chassis(new_client);
1344 device_create_file_chassis_clear(new_client);
1345
1346 device_create_file_thermal_cruise(new_client, 1);
1347 device_create_file_thermal_cruise(new_client, 2);
1348 device_create_file_thermal_cruise(new_client, 3);
1349
1350 device_create_file_tolerance(new_client, 1);
1351 device_create_file_tolerance(new_client, 2);
1352 device_create_file_tolerance(new_client, 3);
1353
1354 device_create_file_sf2_point(new_client, 1, 1); /* Fan1 */
1355 device_create_file_sf2_point(new_client, 2, 1); /* Fan1 */
1356 device_create_file_sf2_point(new_client, 3, 1); /* Fan1 */
1357 device_create_file_sf2_point(new_client, 4, 1); /* Fan1 */
1358 device_create_file_sf2_point(new_client, 1, 2); /* Fan2 */
1359 device_create_file_sf2_point(new_client, 2, 2); /* Fan2 */
1360 device_create_file_sf2_point(new_client, 3, 2); /* Fan2 */
1361 device_create_file_sf2_point(new_client, 4, 2); /* Fan2 */
1362 device_create_file_sf2_point(new_client, 1, 3); /* Fan3 */
1363 device_create_file_sf2_point(new_client, 2, 3); /* Fan3 */
1364 device_create_file_sf2_point(new_client, 3, 3); /* Fan3 */
1365 device_create_file_sf2_point(new_client, 4, 3); /* Fan3 */
1366
1367 device_create_file_sf2_level(new_client, 1, 1); /* Fan1 */
1368 device_create_file_sf2_level(new_client, 2, 1); /* Fan1 */
1369 device_create_file_sf2_level(new_client, 3, 1); /* Fan1 */
1370 device_create_file_sf2_level(new_client, 1, 2); /* Fan2 */
1371 device_create_file_sf2_level(new_client, 2, 2); /* Fan2 */
1372 device_create_file_sf2_level(new_client, 3, 2); /* Fan2 */
1373 device_create_file_sf2_level(new_client, 1, 3); /* Fan3 */
1374 device_create_file_sf2_level(new_client, 2, 3); /* Fan3 */
1375 device_create_file_sf2_level(new_client, 3, 3); /* Fan3 */
1376
1377 return 0;
1378
R.Marek@sh.cvut.czce785ab2005-07-27 11:50:18 +00001379ERROR3:
1380 if (data->lm75[0] != NULL) {
1381 i2c_detach_client(data->lm75[0]);
1382 kfree(data->lm75[0]);
1383 }
1384 if (data->lm75[1] != NULL) {
1385 i2c_detach_client(data->lm75[1]);
1386 kfree(data->lm75[1]);
1387 }
R.Marek@sh.cvut.cz5563e272005-07-27 11:43:47 +00001388ERROR2:
1389 i2c_detach_client(new_client);
1390ERROR1:
1391 kfree(data);
1392ERROR0:
1393 return err;
1394}
1395
1396static int
1397w83792d_detach_client(struct i2c_client *client)
1398{
R.Marek@sh.cvut.czce785ab2005-07-27 11:50:18 +00001399 struct w83792d_data *data = i2c_get_clientdata(client);
R.Marek@sh.cvut.cz5563e272005-07-27 11:43:47 +00001400 int err;
1401
R.Marek@sh.cvut.czce785ab2005-07-27 11:50:18 +00001402 /* main client */
1403 if (data)
1404 hwmon_device_unregister(data->class_dev);
1405
Jean Delvare7bef5592005-07-27 22:14:49 +02001406 if ((err = i2c_detach_client(client)))
R.Marek@sh.cvut.cz5563e272005-07-27 11:43:47 +00001407 return err;
R.Marek@sh.cvut.cz5563e272005-07-27 11:43:47 +00001408
R.Marek@sh.cvut.czce785ab2005-07-27 11:50:18 +00001409 /* main client */
1410 if (data)
1411 kfree(data);
1412 /* subclient */
1413 else
R.Marek@sh.cvut.cz5563e272005-07-27 11:43:47 +00001414 kfree(client);
R.Marek@sh.cvut.cz5563e272005-07-27 11:43:47 +00001415
1416 return 0;
1417}
1418
1419/* The SMBus locks itself, usually, but nothing may access the Winbond between
1420 bank switches. ISA access must always be locked explicitly!
1421 We ignore the W83792D BUSY flag at this moment - it could lead to deadlocks,
1422 would slow down the W83792D access and should not be necessary.
1423 There are some ugly typecasts here, but the good news is - they should
1424 nowhere else be necessary! */
1425static int
1426w83792d_read_value(struct i2c_client *client, u8 reg)
1427{
1428 int res=0;
1429 res = i2c_smbus_read_byte_data(client, reg);
1430
1431 return res;
1432}
1433
1434static int
1435w83792d_write_value(struct i2c_client *client, u8 reg, u8 value)
1436{
1437 i2c_smbus_write_byte_data(client, reg, value);
1438 return 0;
1439}
1440
R.Marek@sh.cvut.cz5563e272005-07-27 11:43:47 +00001441static void
1442w83792d_init_client(struct i2c_client *client)
1443{
1444 u8 temp2_cfg, temp3_cfg, vid_in_b;
1445
1446 if (init) {
1447 w83792d_write_value(client, W83792D_REG_CONFIG, 0x80);
1448 }
1449 /* Clear the bit6 of W83792D_REG_VID_IN_B(set it into 0):
1450 W83792D_REG_VID_IN_B bit6 = 0: the high/low limit of
1451 vin0/vin1 can be modified by user;
1452 W83792D_REG_VID_IN_B bit6 = 1: the high/low limit of
1453 vin0/vin1 auto-updated, can NOT be modified by user. */
1454 vid_in_b = w83792d_read_value(client, W83792D_REG_VID_IN_B);
1455 w83792d_write_value(client, W83792D_REG_VID_IN_B,
1456 vid_in_b & 0xbf);
1457
1458 temp2_cfg = w83792d_read_value(client, W83792D_REG_TEMP2_CONFIG);
1459 temp3_cfg = w83792d_read_value(client, W83792D_REG_TEMP3_CONFIG);
1460 w83792d_write_value(client, W83792D_REG_TEMP2_CONFIG,
1461 temp2_cfg & 0xe6);
1462 w83792d_write_value(client, W83792D_REG_TEMP3_CONFIG,
1463 temp3_cfg & 0xe6);
1464
1465 /* Start monitoring */
1466 w83792d_write_value(client, W83792D_REG_CONFIG,
1467 (w83792d_read_value(client,
1468 W83792D_REG_CONFIG) & 0xf7)
1469 | 0x01);
1470}
1471
1472static struct w83792d_data *w83792d_update_device(struct device *dev)
1473{
1474 struct i2c_client *client = to_i2c_client(dev);
1475 struct w83792d_data *data = i2c_get_clientdata(client);
1476 int i, j;
1477 u8 reg_array_tmp[4], pwm_array_tmp[7], reg_tmp;
1478
1479 down(&data->update_lock);
1480
1481 if (time_after
1482 (jiffies - data->last_updated, (unsigned long) (HZ * 3))
1483 || time_before(jiffies, data->last_updated) || !data->valid) {
1484 dev_dbg(dev, "Starting device update\n");
1485
1486 /* Update the voltages measured value and limits */
1487 for (i = 0; i < 9; i++) {
1488 data->in[i] = w83792d_read_value(client,
1489 W83792D_REG_IN[i]);
1490 data->in_max[i] = w83792d_read_value(client,
1491 W83792D_REG_IN_MAX[i]);
1492 data->in_min[i] = w83792d_read_value(client,
1493 W83792D_REG_IN_MIN[i]);
1494 }
1495 data->low_bits[0] = w83792d_read_value(client,
1496 W83792D_REG_LOW_BITS1);
1497 data->low_bits[1] = w83792d_read_value(client,
1498 W83792D_REG_LOW_BITS2);
1499 for (i = 0; i < 7; i++) {
1500 /* Update the Fan measured value and limits */
1501 data->fan[i] = w83792d_read_value(client,
1502 W83792D_REG_FAN[i]);
1503 data->fan_min[i] = w83792d_read_value(client,
1504 W83792D_REG_FAN_MIN[i]);
1505 /* Update the PWM/DC Value and PWM/DC flag */
1506 pwm_array_tmp[i] = w83792d_read_value(client,
1507 W83792D_REG_PWM[i]);
1508 data->pwm[i] = pwm_array_tmp[i] & 0x0f;
1509 data->pwm_mode[i] = (pwm_array_tmp[i] >> 7) & 0x01;
1510 }
1511
1512 reg_tmp = w83792d_read_value(client, W83792D_REG_FAN_CFG);
1513 data->pwmenable[0] = reg_tmp & 0x03;
1514 data->pwmenable[1] = (reg_tmp>>2) & 0x03;
1515 data->pwmenable[2] = (reg_tmp>>4) & 0x03;
1516
1517 for (i = 0; i < 3; i++) {
1518 data->temp1[i] = w83792d_read_value(client,
1519 W83792D_REG_TEMP1[i]);
1520 }
1521 for (i = 0; i < 2; i++) {
1522 for (j = 0; j < 6; j++) {
1523 data->temp_add[i][j] = w83792d_read_value(
1524 client,W83792D_REG_TEMP_ADD[i][j]);
1525 }
1526 }
1527
1528 /* Update the Fan Divisor */
1529 for (i = 0; i < 4; i++) {
1530 reg_array_tmp[i] = w83792d_read_value(client,
1531 W83792D_REG_FAN_DIV[i]);
1532 }
1533 data->fan_div[0] = reg_array_tmp[0] & 0x07;
1534 data->fan_div[1] = (reg_array_tmp[0] >> 4) & 0x07;
1535 data->fan_div[2] = reg_array_tmp[1] & 0x07;
1536 data->fan_div[3] = (reg_array_tmp[1] >> 4) & 0x07;
1537 data->fan_div[4] = reg_array_tmp[2] & 0x07;
1538 data->fan_div[5] = (reg_array_tmp[2] >> 4) & 0x07;
1539 data->fan_div[6] = reg_array_tmp[3] & 0x07;
1540
1541 /* Update the realtime status */
1542 data->alarms = w83792d_read_value(client, W83792D_REG_ALARM1) +
1543 (w83792d_read_value(client, W83792D_REG_ALARM2) << 8) +
1544 (w83792d_read_value(client, W83792D_REG_ALARM3) << 16);
1545
1546 /* Update CaseOpen status and it's CLR_CHS. */
1547 data->chassis = (w83792d_read_value(client,
1548 W83792D_REG_CHASSIS) >> 5) & 0x01;
1549 data->chassis_clear = (w83792d_read_value(client,
1550 W83792D_REG_CHASSIS_CLR) >> 7) & 0x01;
1551
1552 /* Update Thermal Cruise/Smart Fan I target value */
1553 for (i = 0; i < 3; i++) {
1554 data->thermal_cruise[i] =
1555 w83792d_read_value(client,
1556 W83792D_REG_THERMAL[i]) & 0x7f;
1557 }
1558
1559 /* Update Smart Fan I/II tolerance */
1560 reg_tmp = w83792d_read_value(client, W83792D_REG_TOLERANCE[0]);
1561 data->tolerance[0] = reg_tmp & 0x0f;
1562 data->tolerance[1] = (reg_tmp >> 4) & 0x0f;
1563 data->tolerance[2] = w83792d_read_value(client,
1564 W83792D_REG_TOLERANCE[2]) & 0x0f;
1565
1566 /* Update Smart Fan II temperature points */
1567 for (i = 0; i < 3; i++) {
1568 for (j = 0; j < 4; j++) {
1569 data->sf2_points[i][j] = w83792d_read_value(
1570 client,W83792D_REG_POINTS[i][j]) & 0x7f;
1571 }
1572 }
1573
1574 /* Update Smart Fan II duty cycle levels */
1575 for (i = 0; i < 3; i++) {
1576 reg_tmp = w83792d_read_value(client,
1577 W83792D_REG_LEVELS[i][0]);
1578 data->sf2_levels[i][0] = reg_tmp & 0x0f;
1579 data->sf2_levels[i][1] = (reg_tmp >> 4) & 0x0f;
1580 reg_tmp = w83792d_read_value(client,
1581 W83792D_REG_LEVELS[i][2]);
1582 data->sf2_levels[i][2] = (reg_tmp >> 4) & 0x0f;
1583 data->sf2_levels[i][3] = reg_tmp & 0x0f;
1584 }
1585
1586 data->last_updated = jiffies;
1587 data->valid = 1;
1588 }
1589
1590 up(&data->update_lock);
1591
1592#ifdef DEBUG
1593 w83792d_print_debug(data, dev);
1594#endif
1595
1596 return data;
1597}
1598
1599#ifdef DEBUG
1600static void w83792d_print_debug(struct w83792d_data *data, struct device *dev)
1601{
1602 int i=0, j=0;
1603 dev_dbg(dev, "==========The following is the debug message...========\n");
1604 dev_dbg(dev, "9 set of Voltages: =====>\n");
1605 for (i=0; i<9; i++) {
1606 dev_dbg(dev, "vin[%d] is: 0x%x\n", i, data->in[i]);
1607 dev_dbg(dev, "vin[%d] max is: 0x%x\n", i, data->in_max[i]);
1608 dev_dbg(dev, "vin[%d] min is: 0x%x\n", i, data->in_min[i]);
1609 }
1610 dev_dbg(dev, "Low Bit1 is: 0x%x\n", data->low_bits[0]);
1611 dev_dbg(dev, "Low Bit2 is: 0x%x\n", data->low_bits[1]);
1612 dev_dbg(dev, "7 set of Fan Counts and Duty Cycles: =====>\n");
1613 for (i=0; i<7; i++) {
1614 dev_dbg(dev, "fan[%d] is: 0x%x\n", i, data->fan[i]);
1615 dev_dbg(dev, "fan[%d] min is: 0x%x\n", i, data->fan_min[i]);
1616 dev_dbg(dev, "pwm[%d] is: 0x%x\n", i, data->pwm[i]);
1617 dev_dbg(dev, "pwm_mode[%d] is: 0x%x\n", i, data->pwm_mode[i]);
1618 }
1619 dev_dbg(dev, "3 set of Temperatures: =====>\n");
1620 for (i=0; i<3; i++) {
1621 dev_dbg(dev, "temp1[%d] is: 0x%x\n", i, data->temp1[i]);
1622 }
1623
1624 for (i=0; i<2; i++) {
1625 for (j=0; j<6; j++) {
1626 dev_dbg(dev, "temp_add[%d][%d] is: 0x%x\n", i, j,
1627 data->temp_add[i][j]);
1628 }
1629 }
1630
1631 for (i=0; i<7; i++) {
1632 dev_dbg(dev, "fan_div[%d] is: 0x%x\n", i, data->fan_div[i]);
1633 }
1634 dev_dbg(dev, "==========End of the debug message...==================\n");
1635 dev_dbg(dev, "\n");
1636}
1637#endif
1638
1639static int __init
1640sensors_w83792d_init(void)
1641{
1642 return i2c_add_driver(&w83792d_driver);
1643}
1644
1645static void __exit
1646sensors_w83792d_exit(void)
1647{
1648 i2c_del_driver(&w83792d_driver);
1649}
1650
1651MODULE_AUTHOR("Chunhao Huang @ Winbond <DZShen@Winbond.com.tw>");
1652MODULE_DESCRIPTION("W83792AD/D driver for linux-2.6");
1653MODULE_LICENSE("GPL");
1654
1655module_init(sensors_w83792d_init);
1656module_exit(sensors_w83792d_exit);
1657