blob: 9018445ac1bfd9687817b030de77d1a4440a7fca [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 = {
Laurent Riffardcdaf7932005-11-26 20:37:41 +0100320 .driver = {
321 .owner = THIS_MODULE,
322 .name = "w83792d",
323 },
R.Marek@sh.cvut.cz5563e272005-07-27 11:43:47 +0000324 .attach_adapter = w83792d_attach_adapter,
325 .detach_client = w83792d_detach_client,
326};
327
328static long in_count_from_reg(int nr, struct w83792d_data *data)
329{
330 u16 vol_count = data->in[nr];
331 u16 low_bits = 0;
332 vol_count = (vol_count << 2);
333 switch (nr)
334 {
335 case 0: /* vin0 */
336 low_bits = (data->low_bits[0]) & 0x03;
337 break;
338 case 1: /* vin1 */
339 low_bits = ((data->low_bits[0]) & 0x0c) >> 2;
340 break;
341 case 2: /* vin2 */
342 low_bits = ((data->low_bits[0]) & 0x30) >> 4;
343 break;
344 case 3: /* vin3 */
345 low_bits = ((data->low_bits[0]) & 0xc0) >> 6;
346 break;
347 case 4: /* vin4 */
348 low_bits = (data->low_bits[1]) & 0x03;
349 break;
350 case 5: /* vin5 */
351 low_bits = ((data->low_bits[1]) & 0x0c) >> 2;
352 break;
353 case 6: /* vin6 */
354 low_bits = ((data->low_bits[1]) & 0x30) >> 4;
355 default:
356 break;
357 }
358 vol_count = vol_count | low_bits;
359 return vol_count;
360}
361
362/* following are the sysfs callback functions */
363static ssize_t show_in(struct device *dev, struct device_attribute *attr,
364 char *buf)
365{
366 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
367 int nr = sensor_attr->index;
368 struct w83792d_data *data = w83792d_update_device(dev);
369 return sprintf(buf,"%ld\n", IN_FROM_REG(nr,(in_count_from_reg(nr, data))));
370}
371
372#define show_in_reg(reg) \
373static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \
374 char *buf) \
375{ \
376 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \
377 int nr = sensor_attr->index; \
378 struct w83792d_data *data = w83792d_update_device(dev); \
379 return sprintf(buf,"%ld\n", (long)(IN_FROM_REG(nr, (data->reg[nr])*4))); \
380}
381
382show_in_reg(in_min);
383show_in_reg(in_max);
384
385#define store_in_reg(REG, reg) \
386static ssize_t store_in_##reg (struct device *dev, \
387 struct device_attribute *attr, \
388 const char *buf, size_t count) \
389{ \
390 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \
391 int nr = sensor_attr->index; \
392 struct i2c_client *client = to_i2c_client(dev); \
393 struct w83792d_data *data = i2c_get_clientdata(client); \
394 u32 val; \
395 \
396 val = simple_strtoul(buf, NULL, 10); \
397 data->in_##reg[nr] = SENSORS_LIMIT(IN_TO_REG(nr, val)/4, 0, 255); \
398 w83792d_write_value(client, W83792D_REG_IN_##REG[nr], data->in_##reg[nr]); \
399 \
400 return count; \
401}
402store_in_reg(MIN, min);
403store_in_reg(MAX, max);
404
405#define sysfs_in_reg(offset) \
406static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in, \
407 NULL, offset); \
408static SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \
409 show_in_min, store_in_min, offset); \
410static SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \
411 show_in_max, store_in_max, offset);
412
413sysfs_in_reg(0);
414sysfs_in_reg(1);
415sysfs_in_reg(2);
416sysfs_in_reg(3);
417sysfs_in_reg(4);
418sysfs_in_reg(5);
419sysfs_in_reg(6);
420sysfs_in_reg(7);
421sysfs_in_reg(8);
422
423#define device_create_file_in(client, offset) \
424do { \
425device_create_file(&client->dev, &sensor_dev_attr_in##offset##_input.dev_attr); \
426device_create_file(&client->dev, &sensor_dev_attr_in##offset##_max.dev_attr); \
427device_create_file(&client->dev, &sensor_dev_attr_in##offset##_min.dev_attr); \
428} while (0)
429
430#define show_fan_reg(reg) \
431static ssize_t show_##reg (struct device *dev, struct device_attribute *attr, \
432 char *buf) \
433{ \
434 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \
435 int nr = sensor_attr->index - 1; \
436 struct w83792d_data *data = w83792d_update_device(dev); \
437 return sprintf(buf,"%d\n", \
438 FAN_FROM_REG(data->reg[nr], DIV_FROM_REG(data->fan_div[nr]))); \
439}
440
441show_fan_reg(fan);
442show_fan_reg(fan_min);
443
444static ssize_t
445store_fan_min(struct device *dev, struct device_attribute *attr,
446 const char *buf, size_t count)
447{
448 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
449 int nr = sensor_attr->index - 1;
450 struct i2c_client *client = to_i2c_client(dev);
451 struct w83792d_data *data = i2c_get_clientdata(client);
452 u32 val;
453
454 val = simple_strtoul(buf, NULL, 10);
455 data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
456 w83792d_write_value(client, W83792D_REG_FAN_MIN[nr],
457 data->fan_min[nr]);
458
459 return count;
460}
461
462static ssize_t
463show_fan_div(struct device *dev, struct device_attribute *attr,
464 char *buf)
465{
466 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
467 int nr = sensor_attr->index;
468 struct w83792d_data *data = w83792d_update_device(dev);
469 return sprintf(buf, "%u\n", DIV_FROM_REG(data->fan_div[nr - 1]));
470}
471
472/* Note: we save and restore the fan minimum here, because its value is
473 determined in part by the fan divisor. This follows the principle of
474 least suprise; the user doesn't expect the fan minimum to change just
475 because the divisor changed. */
476static ssize_t
477store_fan_div(struct device *dev, struct device_attribute *attr,
478 const char *buf, size_t count)
479{
480 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
481 int nr = sensor_attr->index - 1;
482 struct i2c_client *client = to_i2c_client(dev);
483 struct w83792d_data *data = i2c_get_clientdata(client);
484 unsigned long min;
485 /*u8 reg;*/
486 u8 fan_div_reg = 0;
487 u8 tmp_fan_div;
488
489 /* Save fan_min */
490 min = FAN_FROM_REG(data->fan_min[nr],
491 DIV_FROM_REG(data->fan_div[nr]));
492
493 data->fan_div[nr] = DIV_TO_REG(simple_strtoul(buf, NULL, 10));
494
495 fan_div_reg = w83792d_read_value(client, W83792D_REG_FAN_DIV[nr >> 1]);
496 fan_div_reg &= (nr & 0x01) ? 0x8f : 0xf8;
497 tmp_fan_div = (nr & 0x01) ? (((data->fan_div[nr]) << 4) & 0x70)
498 : ((data->fan_div[nr]) & 0x07);
499 w83792d_write_value(client, W83792D_REG_FAN_DIV[nr >> 1],
500 fan_div_reg | tmp_fan_div);
501
502 /* Restore fan_min */
503 data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
504 w83792d_write_value(client, W83792D_REG_FAN_MIN[nr], data->fan_min[nr]);
505
506 return count;
507}
508
509#define sysfs_fan(offset) \
510static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan, NULL, \
511 offset); \
512static SENSOR_DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \
513 show_fan_div, store_fan_div, offset); \
514static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
515 show_fan_min, store_fan_min, offset);
516
517sysfs_fan(1);
518sysfs_fan(2);
519sysfs_fan(3);
520sysfs_fan(4);
521sysfs_fan(5);
522sysfs_fan(6);
523sysfs_fan(7);
524
525#define device_create_file_fan(client, offset) \
526do { \
527device_create_file(&client->dev, &sensor_dev_attr_fan##offset##_input.dev_attr); \
528device_create_file(&client->dev, &sensor_dev_attr_fan##offset##_div.dev_attr); \
529device_create_file(&client->dev, &sensor_dev_attr_fan##offset##_min.dev_attr); \
530} while (0)
531
532
533/* read/write the temperature1, includes measured value and limits */
534
535static ssize_t show_temp1(struct device *dev, struct device_attribute *attr,
536 char *buf)
537{
538 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
539 int nr = sensor_attr->index;
540 struct w83792d_data *data = w83792d_update_device(dev);
541 return sprintf(buf, "%d\n", TEMP1_FROM_REG(data->temp1[nr]));
542}
543
544static ssize_t store_temp1(struct device *dev, struct device_attribute *attr,
545 const char *buf, size_t count)
546{
547 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
548 int nr = sensor_attr->index;
549 struct i2c_client *client = to_i2c_client(dev);
550 struct w83792d_data *data = i2c_get_clientdata(client);
551 s32 val;
552
553 val = simple_strtol(buf, NULL, 10);
554
555 data->temp1[nr] = TEMP1_TO_REG(val);
556 w83792d_write_value(client, W83792D_REG_TEMP1[nr],
557 data->temp1[nr]);
558
559 return count;
560}
561
562
563static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp1, NULL, 0);
564static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR, show_temp1,
565 store_temp1, 1);
566static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR, show_temp1,
567 store_temp1, 2);
568
569#define device_create_file_temp1(client) \
570do { \
571device_create_file(&client->dev, &sensor_dev_attr_temp1_input.dev_attr); \
572device_create_file(&client->dev, &sensor_dev_attr_temp1_max.dev_attr); \
573device_create_file(&client->dev, &sensor_dev_attr_temp1_max_hyst.dev_attr); \
574} while (0)
575
576
577/* read/write the temperature2-3, includes measured value and limits */
578
579static ssize_t show_temp23(struct device *dev, struct device_attribute *attr,
580 char *buf)
581{
582 struct sensor_device_attribute_2 *sensor_attr = to_sensor_dev_attr_2(attr);
583 int nr = sensor_attr->nr;
584 int index = sensor_attr->index;
585 struct w83792d_data *data = w83792d_update_device(dev);
586 return sprintf(buf,"%ld\n",
587 (long)TEMP_ADD_FROM_REG(data->temp_add[nr][index],
588 data->temp_add[nr][index+1]));
589}
590
591static ssize_t store_temp23(struct device *dev, struct device_attribute *attr,
592 const char *buf, size_t count)
593{
594 struct sensor_device_attribute_2 *sensor_attr = to_sensor_dev_attr_2(attr);
595 int nr = sensor_attr->nr;
596 int index = sensor_attr->index;
597 struct i2c_client *client = to_i2c_client(dev);
598 struct w83792d_data *data = i2c_get_clientdata(client);
599 s32 val;
600
601 val = simple_strtol(buf, NULL, 10);
602
603 data->temp_add[nr][index] = TEMP_ADD_TO_REG_HIGH(val);
604 data->temp_add[nr][index+1] = TEMP_ADD_TO_REG_LOW(val);
605 w83792d_write_value(client, W83792D_REG_TEMP_ADD[nr][index],
606 data->temp_add[nr][index]);
607 w83792d_write_value(client, W83792D_REG_TEMP_ADD[nr][index+1],
608 data->temp_add[nr][index+1]);
609
610 return count;
611}
612
613#define sysfs_temp23(name,idx) \
614static SENSOR_DEVICE_ATTR_2(name##_input, S_IRUGO, show_temp23, NULL, \
615 idx, 0); \
616static SENSOR_DEVICE_ATTR_2(name##_max, S_IRUGO | S_IWUSR, \
617 show_temp23, store_temp23, idx, 2); \
618static SENSOR_DEVICE_ATTR_2(name##_max_hyst, S_IRUGO | S_IWUSR, \
619 show_temp23, store_temp23, idx, 4);
620
621sysfs_temp23(temp2,0)
622sysfs_temp23(temp3,1)
623
624#define device_create_file_temp_add(client, offset) \
625do { \
626device_create_file(&client->dev, &sensor_dev_attr_temp##offset##_input.dev_attr); \
627device_create_file(&client->dev, &sensor_dev_attr_temp##offset##_max.dev_attr); \
628device_create_file(&client->dev, \
629&sensor_dev_attr_temp##offset##_max_hyst.dev_attr); \
630} while (0)
631
632
633/* get reatime status of all sensors items: voltage, temp, fan */
634static ssize_t
635show_alarms_reg(struct device *dev, struct device_attribute *attr, char *buf)
636{
637 struct w83792d_data *data = w83792d_update_device(dev);
638 return sprintf(buf, "%d\n", data->alarms);
639}
640
641static
642DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL);
643#define device_create_file_alarms(client) \
644device_create_file(&client->dev, &dev_attr_alarms);
645
646
647
648static ssize_t
649show_pwm(struct device *dev, struct device_attribute *attr,
650 char *buf)
651{
652 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
653 int nr = sensor_attr->index;
654 struct w83792d_data *data = w83792d_update_device(dev);
655 return sprintf(buf, "%ld\n", (long) PWM_FROM_REG(data->pwm[nr-1]));
656}
657
658static ssize_t
659show_pwmenable(struct device *dev, struct device_attribute *attr,
660 char *buf)
661{
662 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
663 int nr = sensor_attr->index - 1;
664 struct w83792d_data *data = w83792d_update_device(dev);
665 long pwm_enable_tmp = 1;
666
667 switch (data->pwmenable[nr]) {
668 case 0:
669 pwm_enable_tmp = 1; /* manual mode */
670 break;
671 case 1:
672 pwm_enable_tmp = 3; /*thermal cruise/Smart Fan I */
673 break;
674 case 2:
675 pwm_enable_tmp = 2; /* Smart Fan II */
676 break;
677 }
678
679 return sprintf(buf, "%ld\n", pwm_enable_tmp);
680}
681
682static ssize_t
683store_pwm(struct device *dev, struct device_attribute *attr,
684 const char *buf, size_t count)
685{
686 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
687 int nr = sensor_attr->index - 1;
688 struct i2c_client *client = to_i2c_client(dev);
689 struct w83792d_data *data = i2c_get_clientdata(client);
690 u32 val;
691
692 val = simple_strtoul(buf, NULL, 10);
693 data->pwm[nr] = PWM_TO_REG(val);
694 w83792d_write_value(client, W83792D_REG_PWM[nr], data->pwm[nr]);
695
696 return count;
697}
698
699static ssize_t
700store_pwmenable(struct device *dev, struct device_attribute *attr,
701 const char *buf, size_t count)
702{
703 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
704 int nr = sensor_attr->index - 1;
705 struct i2c_client *client = to_i2c_client(dev);
706 struct w83792d_data *data = i2c_get_clientdata(client);
707 u32 val;
708 u8 fan_cfg_tmp, cfg1_tmp, cfg2_tmp, cfg3_tmp, cfg4_tmp;
709
710 val = simple_strtoul(buf, NULL, 10);
711 switch (val) {
712 case 1:
713 data->pwmenable[nr] = 0; /* manual mode */
714 break;
715 case 2:
716 data->pwmenable[nr] = 2; /* Smart Fan II */
717 break;
718 case 3:
719 data->pwmenable[nr] = 1; /* thermal cruise/Smart Fan I */
720 break;
721 default:
722 return -EINVAL;
723 }
724 cfg1_tmp = data->pwmenable[0];
725 cfg2_tmp = (data->pwmenable[1]) << 2;
726 cfg3_tmp = (data->pwmenable[2]) << 4;
727 cfg4_tmp = w83792d_read_value(client,W83792D_REG_FAN_CFG) & 0xc0;
728 fan_cfg_tmp = ((cfg4_tmp | cfg3_tmp) | cfg2_tmp) | cfg1_tmp;
729 w83792d_write_value(client, W83792D_REG_FAN_CFG, fan_cfg_tmp);
730
731 return count;
732}
733
734#define sysfs_pwm(offset) \
735static SENSOR_DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \
736 show_pwm, store_pwm, offset); \
737static SENSOR_DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR, \
738 show_pwmenable, store_pwmenable, offset); \
739
740sysfs_pwm(1);
741sysfs_pwm(2);
742sysfs_pwm(3);
743
744
745#define device_create_file_pwm(client, offset) \
746do { \
747device_create_file(&client->dev, &sensor_dev_attr_pwm##offset.dev_attr); \
748} while (0)
749
750#define device_create_file_pwmenable(client, offset) \
751do { \
752device_create_file(&client->dev, &sensor_dev_attr_pwm##offset##_enable.dev_attr); \
753} while (0)
754
755
756static ssize_t
757show_pwm_mode(struct device *dev, struct device_attribute *attr,
758 char *buf)
759{
760 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
761 int nr = sensor_attr->index;
762 struct w83792d_data *data = w83792d_update_device(dev);
763 return sprintf(buf, "%d\n", data->pwm_mode[nr-1]);
764}
765
766static ssize_t
767store_pwm_mode(struct device *dev, struct device_attribute *attr,
768 const char *buf, size_t count)
769{
770 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
771 int nr = sensor_attr->index - 1;
772 struct i2c_client *client = to_i2c_client(dev);
773 struct w83792d_data *data = i2c_get_clientdata(client);
774 u32 val;
775 u8 pwm_mode_mask = 0;
776
777 val = simple_strtoul(buf, NULL, 10);
778 data->pwm_mode[nr] = SENSORS_LIMIT(val, 0, 1);
779 pwm_mode_mask = w83792d_read_value(client,
780 W83792D_REG_PWM[nr]) & 0x7f;
781 w83792d_write_value(client, W83792D_REG_PWM[nr],
782 ((data->pwm_mode[nr]) << 7) | pwm_mode_mask);
783
784 return count;
785}
786
787#define sysfs_pwm_mode(offset) \
788static SENSOR_DEVICE_ATTR(pwm##offset##_mode, S_IRUGO | S_IWUSR, \
789 show_pwm_mode, store_pwm_mode, offset);
790
791sysfs_pwm_mode(1);
792sysfs_pwm_mode(2);
793sysfs_pwm_mode(3);
794
795#define device_create_file_pwm_mode(client, offset) \
796do { \
797device_create_file(&client->dev, &sensor_dev_attr_pwm##offset##_mode.dev_attr); \
798} while (0)
799
800
801static ssize_t
802show_regs_chassis(struct device *dev, struct device_attribute *attr,
803 char *buf)
804{
805 struct w83792d_data *data = w83792d_update_device(dev);
806 return sprintf(buf, "%d\n", data->chassis);
807}
808
809static DEVICE_ATTR(chassis, S_IRUGO, show_regs_chassis, NULL);
810
811#define device_create_file_chassis(client) \
812do { \
813device_create_file(&client->dev, &dev_attr_chassis); \
814} while (0)
815
816
817static ssize_t
818show_chassis_clear(struct device *dev, struct device_attribute *attr, char *buf)
819{
820 struct w83792d_data *data = w83792d_update_device(dev);
821 return sprintf(buf, "%d\n", data->chassis_clear);
822}
823
824static ssize_t
825store_chassis_clear(struct device *dev, struct device_attribute *attr,
826 const char *buf, size_t count)
827{
828 struct i2c_client *client = to_i2c_client(dev);
829 struct w83792d_data *data = i2c_get_clientdata(client);
830 u32 val;
831 u8 temp1 = 0, temp2 = 0;
832
833 val = simple_strtoul(buf, NULL, 10);
834
835 data->chassis_clear = SENSORS_LIMIT(val, 0 ,1);
836 temp1 = ((data->chassis_clear) << 7) & 0x80;
837 temp2 = w83792d_read_value(client,
838 W83792D_REG_CHASSIS_CLR) & 0x7f;
839 w83792d_write_value(client, W83792D_REG_CHASSIS_CLR, temp1 | temp2);
840
841 return count;
842}
843
844static DEVICE_ATTR(chassis_clear, S_IRUGO | S_IWUSR,
845 show_chassis_clear, store_chassis_clear);
846
847#define device_create_file_chassis_clear(client) \
848do { \
849device_create_file(&client->dev, &dev_attr_chassis_clear); \
850} while (0)
851
852
853
854/* For Smart Fan I / Thermal Cruise */
855static ssize_t
856show_thermal_cruise(struct device *dev, struct device_attribute *attr,
857 char *buf)
858{
859 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
860 int nr = sensor_attr->index;
861 struct w83792d_data *data = w83792d_update_device(dev);
862 return sprintf(buf, "%ld\n", (long)data->thermal_cruise[nr-1]);
863}
864
865static ssize_t
866store_thermal_cruise(struct device *dev, struct device_attribute *attr,
867 const char *buf, size_t count)
868{
869 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
870 int nr = sensor_attr->index - 1;
871 struct i2c_client *client = to_i2c_client(dev);
872 struct w83792d_data *data = i2c_get_clientdata(client);
873 u32 val;
874 u8 target_tmp=0, target_mask=0;
875
876 val = simple_strtoul(buf, NULL, 10);
877 target_tmp = val;
878 target_tmp = target_tmp & 0x7f;
879 target_mask = w83792d_read_value(client, W83792D_REG_THERMAL[nr]) & 0x80;
880 data->thermal_cruise[nr] = SENSORS_LIMIT(target_tmp, 0, 255);
881 w83792d_write_value(client, W83792D_REG_THERMAL[nr],
882 (data->thermal_cruise[nr]) | target_mask);
883
884 return count;
885}
886
887#define sysfs_thermal_cruise(offset) \
888static SENSOR_DEVICE_ATTR(thermal_cruise##offset, S_IRUGO | S_IWUSR, \
889 show_thermal_cruise, store_thermal_cruise, offset);
890
891sysfs_thermal_cruise(1);
892sysfs_thermal_cruise(2);
893sysfs_thermal_cruise(3);
894
895#define device_create_file_thermal_cruise(client, offset) \
896do { \
897device_create_file(&client->dev, \
898&sensor_dev_attr_thermal_cruise##offset.dev_attr); \
899} while (0)
900
901
902/* For Smart Fan I/Thermal Cruise and Smart Fan II */
903static ssize_t
904show_tolerance(struct device *dev, struct device_attribute *attr,
905 char *buf)
906{
907 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
908 int nr = sensor_attr->index;
909 struct w83792d_data *data = w83792d_update_device(dev);
910 return sprintf(buf, "%ld\n", (long)data->tolerance[nr-1]);
911}
912
913static ssize_t
914store_tolerance(struct device *dev, struct device_attribute *attr,
915 const char *buf, size_t count)
916{
917 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
918 int nr = sensor_attr->index - 1;
919 struct i2c_client *client = to_i2c_client(dev);
920 struct w83792d_data *data = i2c_get_clientdata(client);
921 u32 val;
922 u8 tol_tmp, tol_mask;
923
924 val = simple_strtoul(buf, NULL, 10);
925 tol_mask = w83792d_read_value(client,
926 W83792D_REG_TOLERANCE[nr]) & ((nr == 1) ? 0x0f : 0xf0);
927 tol_tmp = SENSORS_LIMIT(val, 0, 15);
928 tol_tmp &= 0x0f;
929 data->tolerance[nr] = tol_tmp;
930 if (nr == 1) {
931 tol_tmp <<= 4;
932 }
933 w83792d_write_value(client, W83792D_REG_TOLERANCE[nr],
934 tol_mask | tol_tmp);
935
936 return count;
937}
938
939#define sysfs_tolerance(offset) \
940static SENSOR_DEVICE_ATTR(tolerance##offset, S_IRUGO | S_IWUSR, \
941 show_tolerance, store_tolerance, offset);
942
943sysfs_tolerance(1);
944sysfs_tolerance(2);
945sysfs_tolerance(3);
946
947#define device_create_file_tolerance(client, offset) \
948do { \
949device_create_file(&client->dev, &sensor_dev_attr_tolerance##offset.dev_attr); \
950} while (0)
951
952
953/* For Smart Fan II */
954static ssize_t
955show_sf2_point(struct device *dev, struct device_attribute *attr,
956 char *buf)
957{
958 struct sensor_device_attribute_2 *sensor_attr = to_sensor_dev_attr_2(attr);
959 int nr = sensor_attr->nr;
960 int index = sensor_attr->index;
961 struct w83792d_data *data = w83792d_update_device(dev);
962 return sprintf(buf, "%ld\n", (long)data->sf2_points[index-1][nr-1]);
963}
964
965static ssize_t
966store_sf2_point(struct device *dev, struct device_attribute *attr,
967 const char *buf, size_t count)
968{
969 struct sensor_device_attribute_2 *sensor_attr = to_sensor_dev_attr_2(attr);
970 int nr = sensor_attr->nr - 1;
971 int index = sensor_attr->index - 1;
972 struct i2c_client *client = to_i2c_client(dev);
973 struct w83792d_data *data = i2c_get_clientdata(client);
974 u32 val;
975 u8 mask_tmp = 0;
976
977 val = simple_strtoul(buf, NULL, 10);
978 data->sf2_points[index][nr] = SENSORS_LIMIT(val, 0, 127);
979 mask_tmp = w83792d_read_value(client,
980 W83792D_REG_POINTS[index][nr]) & 0x80;
981 w83792d_write_value(client, W83792D_REG_POINTS[index][nr],
982 mask_tmp|data->sf2_points[index][nr]);
983
984 return count;
985}
986
987#define sysfs_sf2_point(offset, index) \
988static SENSOR_DEVICE_ATTR_2(sf2_point##offset##_fan##index, S_IRUGO | S_IWUSR, \
989 show_sf2_point, store_sf2_point, offset, index);
990
991sysfs_sf2_point(1, 1); /* Fan1 */
992sysfs_sf2_point(2, 1); /* Fan1 */
993sysfs_sf2_point(3, 1); /* Fan1 */
994sysfs_sf2_point(4, 1); /* Fan1 */
995sysfs_sf2_point(1, 2); /* Fan2 */
996sysfs_sf2_point(2, 2); /* Fan2 */
997sysfs_sf2_point(3, 2); /* Fan2 */
998sysfs_sf2_point(4, 2); /* Fan2 */
999sysfs_sf2_point(1, 3); /* Fan3 */
1000sysfs_sf2_point(2, 3); /* Fan3 */
1001sysfs_sf2_point(3, 3); /* Fan3 */
1002sysfs_sf2_point(4, 3); /* Fan3 */
1003
1004#define device_create_file_sf2_point(client, offset, index) \
1005do { \
1006device_create_file(&client->dev, \
1007&sensor_dev_attr_sf2_point##offset##_fan##index.dev_attr); \
1008} while (0)
1009
1010
1011static ssize_t
1012show_sf2_level(struct device *dev, struct device_attribute *attr,
1013 char *buf)
1014{
1015 struct sensor_device_attribute_2 *sensor_attr = to_sensor_dev_attr_2(attr);
1016 int nr = sensor_attr->nr;
1017 int index = sensor_attr->index;
1018 struct w83792d_data *data = w83792d_update_device(dev);
1019 return sprintf(buf, "%d\n",
1020 (((data->sf2_levels[index-1][nr]) * 100) / 15));
1021}
1022
1023static ssize_t
1024store_sf2_level(struct device *dev, struct device_attribute *attr,
1025 const char *buf, size_t count)
1026{
1027 struct sensor_device_attribute_2 *sensor_attr = to_sensor_dev_attr_2(attr);
1028 int nr = sensor_attr->nr;
1029 int index = sensor_attr->index - 1;
1030 struct i2c_client *client = to_i2c_client(dev);
1031 struct w83792d_data *data = i2c_get_clientdata(client);
1032 u32 val;
1033 u8 mask_tmp=0, level_tmp=0;
1034
1035 val = simple_strtoul(buf, NULL, 10);
1036 data->sf2_levels[index][nr] = SENSORS_LIMIT((val * 15) / 100, 0, 15);
1037 mask_tmp = w83792d_read_value(client, W83792D_REG_LEVELS[index][nr])
1038 & ((nr==3) ? 0xf0 : 0x0f);
1039 if (nr==3) {
1040 level_tmp = data->sf2_levels[index][nr];
1041 } else {
1042 level_tmp = data->sf2_levels[index][nr] << 4;
1043 }
1044 w83792d_write_value(client, W83792D_REG_LEVELS[index][nr], level_tmp | mask_tmp);
1045
1046 return count;
1047}
1048
1049#define sysfs_sf2_level(offset, index) \
1050static SENSOR_DEVICE_ATTR_2(sf2_level##offset##_fan##index, S_IRUGO | S_IWUSR, \
1051 show_sf2_level, store_sf2_level, offset, index);
1052
1053sysfs_sf2_level(1, 1); /* Fan1 */
1054sysfs_sf2_level(2, 1); /* Fan1 */
1055sysfs_sf2_level(3, 1); /* Fan1 */
1056sysfs_sf2_level(1, 2); /* Fan2 */
1057sysfs_sf2_level(2, 2); /* Fan2 */
1058sysfs_sf2_level(3, 2); /* Fan2 */
1059sysfs_sf2_level(1, 3); /* Fan3 */
1060sysfs_sf2_level(2, 3); /* Fan3 */
1061sysfs_sf2_level(3, 3); /* Fan3 */
1062
1063#define device_create_file_sf2_level(client, offset, index) \
1064do { \
1065device_create_file(&client->dev, \
1066&sensor_dev_attr_sf2_level##offset##_fan##index.dev_attr); \
1067} while (0)
1068
1069
1070/* This function is called when:
1071 * w83792d_driver is inserted (when this module is loaded), for each
1072 available adapter
1073 * when a new adapter is inserted (and w83792d_driver is still present) */
1074static int
1075w83792d_attach_adapter(struct i2c_adapter *adapter)
1076{
1077 if (!(adapter->class & I2C_CLASS_HWMON))
1078 return 0;
Jean Delvare2ed2dc32005-07-31 21:42:02 +02001079 return i2c_probe(adapter, &addr_data, w83792d_detect);
R.Marek@sh.cvut.cz5563e272005-07-27 11:43:47 +00001080}
1081
1082
1083static int
1084w83792d_create_subclient(struct i2c_adapter *adapter,
1085 struct i2c_client *new_client, int addr,
1086 struct i2c_client **sub_cli)
1087{
1088 int err;
1089 struct i2c_client *sub_client;
1090
Deepak Saxenaba9c2e82005-10-17 23:08:32 +02001091 (*sub_cli) = sub_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
R.Marek@sh.cvut.cz5563e272005-07-27 11:43:47 +00001092 if (!(sub_client)) {
1093 return -ENOMEM;
1094 }
R.Marek@sh.cvut.cz5563e272005-07-27 11:43:47 +00001095 sub_client->addr = 0x48 + addr;
1096 i2c_set_clientdata(sub_client, NULL);
1097 sub_client->adapter = adapter;
1098 sub_client->driver = &w83792d_driver;
1099 sub_client->flags = 0;
1100 strlcpy(sub_client->name, "w83792d subclient", I2C_NAME_SIZE);
1101 if ((err = i2c_attach_client(sub_client))) {
1102 dev_err(&new_client->dev, "subclient registration "
1103 "at address 0x%x failed\n", sub_client->addr);
1104 kfree(sub_client);
1105 return err;
1106 }
1107 return 0;
1108}
1109
1110
1111static int
1112w83792d_detect_subclients(struct i2c_adapter *adapter, int address, int kind,
1113 struct i2c_client *new_client)
1114{
1115 int i, id, err;
1116 u8 val;
1117 struct w83792d_data *data = i2c_get_clientdata(new_client);
1118
1119 id = i2c_adapter_id(adapter);
1120 if (force_subclients[0] == id && force_subclients[1] == address) {
1121 for (i = 2; i <= 3; i++) {
1122 if (force_subclients[i] < 0x48 ||
1123 force_subclients[i] > 0x4f) {
1124 dev_err(&new_client->dev, "invalid subclient "
1125 "address %d; must be 0x48-0x4f\n",
1126 force_subclients[i]);
1127 err = -ENODEV;
1128 goto ERROR_SC_0;
1129 }
1130 }
1131 w83792d_write_value(new_client, W83792D_REG_I2C_SUBADDR,
1132 (force_subclients[2] & 0x07) |
1133 ((force_subclients[3] & 0x07) << 4));
1134 }
1135
1136 val = w83792d_read_value(new_client, W83792D_REG_I2C_SUBADDR);
1137 if (!(val & 0x08)) {
1138 err = w83792d_create_subclient(adapter, new_client, val & 0x7,
1139 &data->lm75[0]);
1140 if (err < 0)
1141 goto ERROR_SC_0;
1142 }
1143 if (!(val & 0x80)) {
1144 if ((data->lm75[0] != NULL) &&
1145 ((val & 0x7) == ((val >> 4) & 0x7))) {
1146 dev_err(&new_client->dev, "duplicate addresses 0x%x, "
1147 "use force_subclient\n", data->lm75[0]->addr);
1148 err = -ENODEV;
1149 goto ERROR_SC_1;
1150 }
1151 err = w83792d_create_subclient(adapter, new_client,
1152 (val >> 4) & 0x7, &data->lm75[1]);
1153 if (err < 0)
1154 goto ERROR_SC_1;
1155 }
1156
1157 return 0;
1158
1159/* Undo inits in case of errors */
1160
1161ERROR_SC_1:
1162 if (data->lm75[0] != NULL) {
1163 i2c_detach_client(data->lm75[0]);
1164 kfree(data->lm75[0]);
1165 }
1166ERROR_SC_0:
1167 return err;
1168}
1169
1170
1171static int
1172w83792d_detect(struct i2c_adapter *adapter, int address, int kind)
1173{
1174 int i = 0, val1 = 0, val2;
1175 struct i2c_client *new_client;
1176 struct w83792d_data *data;
1177 int err = 0;
1178 const char *client_name = "";
1179
1180 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
1181 goto ERROR0;
1182 }
1183
1184 /* OK. For now, we presume we have a valid client. We now create the
1185 client structure, even though we cannot fill it completely yet.
1186 But it allows us to access w83792d_{read,write}_value. */
1187
Deepak Saxenaba9c2e82005-10-17 23:08:32 +02001188 if (!(data = kzalloc(sizeof(struct w83792d_data), GFP_KERNEL))) {
R.Marek@sh.cvut.cz5563e272005-07-27 11:43:47 +00001189 err = -ENOMEM;
1190 goto ERROR0;
1191 }
R.Marek@sh.cvut.cz5563e272005-07-27 11:43:47 +00001192
1193 new_client = &data->client;
1194 i2c_set_clientdata(new_client, data);
1195 new_client->addr = address;
1196 init_MUTEX(&data->lock);
1197 new_client->adapter = adapter;
1198 new_client->driver = &w83792d_driver;
1199 new_client->flags = 0;
1200
1201 /* Now, we do the remaining detection. */
1202
1203 /* The w83792d may be stuck in some other bank than bank 0. This may
1204 make reading other information impossible. Specify a force=... or
1205 force_*=... parameter, and the Winbond will be reset to the right
1206 bank. */
1207 if (kind < 0) {
1208 if (w83792d_read_value(new_client, W83792D_REG_CONFIG) & 0x80) {
1209 dev_warn(&new_client->dev, "Detection failed at step "
1210 "3\n");
1211 goto ERROR1;
1212 }
1213 val1 = w83792d_read_value(new_client, W83792D_REG_BANK);
1214 val2 = w83792d_read_value(new_client, W83792D_REG_CHIPMAN);
1215 /* Check for Winbond ID if in bank 0 */
1216 if (!(val1 & 0x07)) { /* is Bank0 */
1217 if (((!(val1 & 0x80)) && (val2 != 0xa3)) ||
1218 ((val1 & 0x80) && (val2 != 0x5c))) {
1219 goto ERROR1;
1220 }
1221 }
1222 /* If Winbond chip, address of chip and W83792D_REG_I2C_ADDR
1223 should match */
1224 if (w83792d_read_value(new_client,
1225 W83792D_REG_I2C_ADDR) != address) {
1226 dev_warn(&new_client->dev, "Detection failed "
1227 "at step 5\n");
1228 goto ERROR1;
1229 }
1230 }
1231
1232 /* We have either had a force parameter, or we have already detected the
1233 Winbond. Put it now into bank 0 and Vendor ID High Byte */
1234 w83792d_write_value(new_client,
1235 W83792D_REG_BANK,
1236 (w83792d_read_value(new_client,
1237 W83792D_REG_BANK) & 0x78) | 0x80);
1238
1239 /* Determine the chip type. */
1240 if (kind <= 0) {
1241 /* get vendor ID */
1242 val2 = w83792d_read_value(new_client, W83792D_REG_CHIPMAN);
1243 if (val2 != 0x5c) { /* the vendor is NOT Winbond */
1244 goto ERROR1;
1245 }
1246 val1 = w83792d_read_value(new_client, W83792D_REG_WCHIPID);
1247 if (val1 == 0x7a && address >= 0x2c) {
1248 kind = w83792d;
1249 } else {
1250 if (kind == 0)
1251 dev_warn(&new_client->dev,
1252 "w83792d: Ignoring 'force' parameter for"
1253 " unknown chip at adapter %d, address"
1254 " 0x%02x\n", i2c_adapter_id(adapter),
1255 address);
1256 goto ERROR1;
1257 }
1258 }
1259
1260 if (kind == w83792d) {
1261 client_name = "w83792d";
1262 } else {
1263 dev_err(&new_client->dev, "w83792d: Internal error: unknown"
1264 " kind (%d)?!?", kind);
1265 goto ERROR1;
1266 }
1267
1268 /* Fill in the remaining client fields and put into the global list */
1269 strlcpy(new_client->name, client_name, I2C_NAME_SIZE);
1270 data->type = kind;
1271
1272 data->valid = 0;
1273 init_MUTEX(&data->update_lock);
1274
1275 /* Tell the I2C layer a new client has arrived */
1276 if ((err = i2c_attach_client(new_client)))
1277 goto ERROR1;
1278
1279 if ((err = w83792d_detect_subclients(adapter, address,
1280 kind, new_client)))
1281 goto ERROR2;
1282
1283 /* Initialize the chip */
1284 w83792d_init_client(new_client);
1285
1286 /* A few vars need to be filled upon startup */
Jean Delvare96320512005-11-29 22:27:14 +01001287 for (i = 0; i < 7; i++) {
1288 data->fan_min[i] = w83792d_read_value(new_client,
R.Marek@sh.cvut.cz5563e272005-07-27 11:43:47 +00001289 W83792D_REG_FAN_MIN[i]);
1290 }
1291
1292 /* Register sysfs hooks */
R.Marek@sh.cvut.czce785ab2005-07-27 11:50:18 +00001293 data->class_dev = hwmon_device_register(&new_client->dev);
1294 if (IS_ERR(data->class_dev)) {
1295 err = PTR_ERR(data->class_dev);
1296 goto ERROR3;
1297 }
R.Marek@sh.cvut.cz5563e272005-07-27 11:43:47 +00001298 device_create_file_in(new_client, 0);
1299 device_create_file_in(new_client, 1);
1300 device_create_file_in(new_client, 2);
1301 device_create_file_in(new_client, 3);
1302 device_create_file_in(new_client, 4);
1303 device_create_file_in(new_client, 5);
1304 device_create_file_in(new_client, 6);
1305 device_create_file_in(new_client, 7);
1306 device_create_file_in(new_client, 8);
1307
1308 device_create_file_fan(new_client, 1);
1309 device_create_file_fan(new_client, 2);
1310 device_create_file_fan(new_client, 3);
Jean Delvare96320512005-11-29 22:27:14 +01001311
1312 /* Read GPIO enable register to check if pins for fan 4,5 are used as
1313 GPIO */
1314 val1 = w83792d_read_value(new_client, W83792D_REG_GPIO_EN);
1315 if (!(val1 & 0x40))
1316 device_create_file_fan(new_client, 4);
1317 if (!(val1 & 0x20))
1318 device_create_file_fan(new_client, 5);
1319
1320 val1 = w83792d_read_value(new_client, W83792D_REG_PIN);
1321 if (val1 & 0x40)
1322 device_create_file_fan(new_client, 6);
1323 if (val1 & 0x04)
1324 device_create_file_fan(new_client, 7);
R.Marek@sh.cvut.cz5563e272005-07-27 11:43:47 +00001325
1326 device_create_file_temp1(new_client); /* Temp1 */
1327 device_create_file_temp_add(new_client, 2); /* Temp2 */
1328 device_create_file_temp_add(new_client, 3); /* Temp3 */
1329
1330 device_create_file_alarms(new_client);
1331
1332 device_create_file_pwm(new_client, 1);
1333 device_create_file_pwm(new_client, 2);
1334 device_create_file_pwm(new_client, 3);
1335
1336 device_create_file_pwmenable(new_client, 1);
1337 device_create_file_pwmenable(new_client, 2);
1338 device_create_file_pwmenable(new_client, 3);
1339
1340 device_create_file_pwm_mode(new_client, 1);
1341 device_create_file_pwm_mode(new_client, 2);
1342 device_create_file_pwm_mode(new_client, 3);
1343
1344 device_create_file_chassis(new_client);
1345 device_create_file_chassis_clear(new_client);
1346
1347 device_create_file_thermal_cruise(new_client, 1);
1348 device_create_file_thermal_cruise(new_client, 2);
1349 device_create_file_thermal_cruise(new_client, 3);
1350
1351 device_create_file_tolerance(new_client, 1);
1352 device_create_file_tolerance(new_client, 2);
1353 device_create_file_tolerance(new_client, 3);
1354
1355 device_create_file_sf2_point(new_client, 1, 1); /* Fan1 */
1356 device_create_file_sf2_point(new_client, 2, 1); /* Fan1 */
1357 device_create_file_sf2_point(new_client, 3, 1); /* Fan1 */
1358 device_create_file_sf2_point(new_client, 4, 1); /* Fan1 */
1359 device_create_file_sf2_point(new_client, 1, 2); /* Fan2 */
1360 device_create_file_sf2_point(new_client, 2, 2); /* Fan2 */
1361 device_create_file_sf2_point(new_client, 3, 2); /* Fan2 */
1362 device_create_file_sf2_point(new_client, 4, 2); /* Fan2 */
1363 device_create_file_sf2_point(new_client, 1, 3); /* Fan3 */
1364 device_create_file_sf2_point(new_client, 2, 3); /* Fan3 */
1365 device_create_file_sf2_point(new_client, 3, 3); /* Fan3 */
1366 device_create_file_sf2_point(new_client, 4, 3); /* Fan3 */
1367
1368 device_create_file_sf2_level(new_client, 1, 1); /* Fan1 */
1369 device_create_file_sf2_level(new_client, 2, 1); /* Fan1 */
1370 device_create_file_sf2_level(new_client, 3, 1); /* Fan1 */
1371 device_create_file_sf2_level(new_client, 1, 2); /* Fan2 */
1372 device_create_file_sf2_level(new_client, 2, 2); /* Fan2 */
1373 device_create_file_sf2_level(new_client, 3, 2); /* Fan2 */
1374 device_create_file_sf2_level(new_client, 1, 3); /* Fan3 */
1375 device_create_file_sf2_level(new_client, 2, 3); /* Fan3 */
1376 device_create_file_sf2_level(new_client, 3, 3); /* Fan3 */
1377
1378 return 0;
1379
R.Marek@sh.cvut.czce785ab2005-07-27 11:50:18 +00001380ERROR3:
1381 if (data->lm75[0] != NULL) {
1382 i2c_detach_client(data->lm75[0]);
1383 kfree(data->lm75[0]);
1384 }
1385 if (data->lm75[1] != NULL) {
1386 i2c_detach_client(data->lm75[1]);
1387 kfree(data->lm75[1]);
1388 }
R.Marek@sh.cvut.cz5563e272005-07-27 11:43:47 +00001389ERROR2:
1390 i2c_detach_client(new_client);
1391ERROR1:
1392 kfree(data);
1393ERROR0:
1394 return err;
1395}
1396
1397static int
1398w83792d_detach_client(struct i2c_client *client)
1399{
R.Marek@sh.cvut.czce785ab2005-07-27 11:50:18 +00001400 struct w83792d_data *data = i2c_get_clientdata(client);
R.Marek@sh.cvut.cz5563e272005-07-27 11:43:47 +00001401 int err;
1402
R.Marek@sh.cvut.czce785ab2005-07-27 11:50:18 +00001403 /* main client */
1404 if (data)
1405 hwmon_device_unregister(data->class_dev);
1406
Jean Delvare7bef5592005-07-27 22:14:49 +02001407 if ((err = i2c_detach_client(client)))
R.Marek@sh.cvut.cz5563e272005-07-27 11:43:47 +00001408 return err;
R.Marek@sh.cvut.cz5563e272005-07-27 11:43:47 +00001409
R.Marek@sh.cvut.czce785ab2005-07-27 11:50:18 +00001410 /* main client */
1411 if (data)
1412 kfree(data);
1413 /* subclient */
1414 else
R.Marek@sh.cvut.cz5563e272005-07-27 11:43:47 +00001415 kfree(client);
R.Marek@sh.cvut.cz5563e272005-07-27 11:43:47 +00001416
1417 return 0;
1418}
1419
1420/* The SMBus locks itself, usually, but nothing may access the Winbond between
1421 bank switches. ISA access must always be locked explicitly!
1422 We ignore the W83792D BUSY flag at this moment - it could lead to deadlocks,
1423 would slow down the W83792D access and should not be necessary.
1424 There are some ugly typecasts here, but the good news is - they should
1425 nowhere else be necessary! */
1426static int
1427w83792d_read_value(struct i2c_client *client, u8 reg)
1428{
1429 int res=0;
1430 res = i2c_smbus_read_byte_data(client, reg);
1431
1432 return res;
1433}
1434
1435static int
1436w83792d_write_value(struct i2c_client *client, u8 reg, u8 value)
1437{
1438 i2c_smbus_write_byte_data(client, reg, value);
1439 return 0;
1440}
1441
R.Marek@sh.cvut.cz5563e272005-07-27 11:43:47 +00001442static void
1443w83792d_init_client(struct i2c_client *client)
1444{
1445 u8 temp2_cfg, temp3_cfg, vid_in_b;
1446
1447 if (init) {
1448 w83792d_write_value(client, W83792D_REG_CONFIG, 0x80);
1449 }
1450 /* Clear the bit6 of W83792D_REG_VID_IN_B(set it into 0):
1451 W83792D_REG_VID_IN_B bit6 = 0: the high/low limit of
1452 vin0/vin1 can be modified by user;
1453 W83792D_REG_VID_IN_B bit6 = 1: the high/low limit of
1454 vin0/vin1 auto-updated, can NOT be modified by user. */
1455 vid_in_b = w83792d_read_value(client, W83792D_REG_VID_IN_B);
1456 w83792d_write_value(client, W83792D_REG_VID_IN_B,
1457 vid_in_b & 0xbf);
1458
1459 temp2_cfg = w83792d_read_value(client, W83792D_REG_TEMP2_CONFIG);
1460 temp3_cfg = w83792d_read_value(client, W83792D_REG_TEMP3_CONFIG);
1461 w83792d_write_value(client, W83792D_REG_TEMP2_CONFIG,
1462 temp2_cfg & 0xe6);
1463 w83792d_write_value(client, W83792D_REG_TEMP3_CONFIG,
1464 temp3_cfg & 0xe6);
1465
1466 /* Start monitoring */
1467 w83792d_write_value(client, W83792D_REG_CONFIG,
1468 (w83792d_read_value(client,
1469 W83792D_REG_CONFIG) & 0xf7)
1470 | 0x01);
1471}
1472
1473static struct w83792d_data *w83792d_update_device(struct device *dev)
1474{
1475 struct i2c_client *client = to_i2c_client(dev);
1476 struct w83792d_data *data = i2c_get_clientdata(client);
1477 int i, j;
1478 u8 reg_array_tmp[4], pwm_array_tmp[7], reg_tmp;
1479
1480 down(&data->update_lock);
1481
1482 if (time_after
1483 (jiffies - data->last_updated, (unsigned long) (HZ * 3))
1484 || time_before(jiffies, data->last_updated) || !data->valid) {
1485 dev_dbg(dev, "Starting device update\n");
1486
1487 /* Update the voltages measured value and limits */
1488 for (i = 0; i < 9; i++) {
1489 data->in[i] = w83792d_read_value(client,
1490 W83792D_REG_IN[i]);
1491 data->in_max[i] = w83792d_read_value(client,
1492 W83792D_REG_IN_MAX[i]);
1493 data->in_min[i] = w83792d_read_value(client,
1494 W83792D_REG_IN_MIN[i]);
1495 }
1496 data->low_bits[0] = w83792d_read_value(client,
1497 W83792D_REG_LOW_BITS1);
1498 data->low_bits[1] = w83792d_read_value(client,
1499 W83792D_REG_LOW_BITS2);
1500 for (i = 0; i < 7; i++) {
1501 /* Update the Fan measured value and limits */
1502 data->fan[i] = w83792d_read_value(client,
1503 W83792D_REG_FAN[i]);
1504 data->fan_min[i] = w83792d_read_value(client,
1505 W83792D_REG_FAN_MIN[i]);
1506 /* Update the PWM/DC Value and PWM/DC flag */
1507 pwm_array_tmp[i] = w83792d_read_value(client,
1508 W83792D_REG_PWM[i]);
1509 data->pwm[i] = pwm_array_tmp[i] & 0x0f;
1510 data->pwm_mode[i] = (pwm_array_tmp[i] >> 7) & 0x01;
1511 }
1512
1513 reg_tmp = w83792d_read_value(client, W83792D_REG_FAN_CFG);
1514 data->pwmenable[0] = reg_tmp & 0x03;
1515 data->pwmenable[1] = (reg_tmp>>2) & 0x03;
1516 data->pwmenable[2] = (reg_tmp>>4) & 0x03;
1517
1518 for (i = 0; i < 3; i++) {
1519 data->temp1[i] = w83792d_read_value(client,
1520 W83792D_REG_TEMP1[i]);
1521 }
1522 for (i = 0; i < 2; i++) {
1523 for (j = 0; j < 6; j++) {
1524 data->temp_add[i][j] = w83792d_read_value(
1525 client,W83792D_REG_TEMP_ADD[i][j]);
1526 }
1527 }
1528
1529 /* Update the Fan Divisor */
1530 for (i = 0; i < 4; i++) {
1531 reg_array_tmp[i] = w83792d_read_value(client,
1532 W83792D_REG_FAN_DIV[i]);
1533 }
1534 data->fan_div[0] = reg_array_tmp[0] & 0x07;
1535 data->fan_div[1] = (reg_array_tmp[0] >> 4) & 0x07;
1536 data->fan_div[2] = reg_array_tmp[1] & 0x07;
1537 data->fan_div[3] = (reg_array_tmp[1] >> 4) & 0x07;
1538 data->fan_div[4] = reg_array_tmp[2] & 0x07;
1539 data->fan_div[5] = (reg_array_tmp[2] >> 4) & 0x07;
1540 data->fan_div[6] = reg_array_tmp[3] & 0x07;
1541
1542 /* Update the realtime status */
1543 data->alarms = w83792d_read_value(client, W83792D_REG_ALARM1) +
1544 (w83792d_read_value(client, W83792D_REG_ALARM2) << 8) +
1545 (w83792d_read_value(client, W83792D_REG_ALARM3) << 16);
1546
1547 /* Update CaseOpen status and it's CLR_CHS. */
1548 data->chassis = (w83792d_read_value(client,
1549 W83792D_REG_CHASSIS) >> 5) & 0x01;
1550 data->chassis_clear = (w83792d_read_value(client,
1551 W83792D_REG_CHASSIS_CLR) >> 7) & 0x01;
1552
1553 /* Update Thermal Cruise/Smart Fan I target value */
1554 for (i = 0; i < 3; i++) {
1555 data->thermal_cruise[i] =
1556 w83792d_read_value(client,
1557 W83792D_REG_THERMAL[i]) & 0x7f;
1558 }
1559
1560 /* Update Smart Fan I/II tolerance */
1561 reg_tmp = w83792d_read_value(client, W83792D_REG_TOLERANCE[0]);
1562 data->tolerance[0] = reg_tmp & 0x0f;
1563 data->tolerance[1] = (reg_tmp >> 4) & 0x0f;
1564 data->tolerance[2] = w83792d_read_value(client,
1565 W83792D_REG_TOLERANCE[2]) & 0x0f;
1566
1567 /* Update Smart Fan II temperature points */
1568 for (i = 0; i < 3; i++) {
1569 for (j = 0; j < 4; j++) {
1570 data->sf2_points[i][j] = w83792d_read_value(
1571 client,W83792D_REG_POINTS[i][j]) & 0x7f;
1572 }
1573 }
1574
1575 /* Update Smart Fan II duty cycle levels */
1576 for (i = 0; i < 3; i++) {
1577 reg_tmp = w83792d_read_value(client,
1578 W83792D_REG_LEVELS[i][0]);
1579 data->sf2_levels[i][0] = reg_tmp & 0x0f;
1580 data->sf2_levels[i][1] = (reg_tmp >> 4) & 0x0f;
1581 reg_tmp = w83792d_read_value(client,
1582 W83792D_REG_LEVELS[i][2]);
1583 data->sf2_levels[i][2] = (reg_tmp >> 4) & 0x0f;
1584 data->sf2_levels[i][3] = reg_tmp & 0x0f;
1585 }
1586
1587 data->last_updated = jiffies;
1588 data->valid = 1;
1589 }
1590
1591 up(&data->update_lock);
1592
1593#ifdef DEBUG
1594 w83792d_print_debug(data, dev);
1595#endif
1596
1597 return data;
1598}
1599
1600#ifdef DEBUG
1601static void w83792d_print_debug(struct w83792d_data *data, struct device *dev)
1602{
1603 int i=0, j=0;
1604 dev_dbg(dev, "==========The following is the debug message...========\n");
1605 dev_dbg(dev, "9 set of Voltages: =====>\n");
1606 for (i=0; i<9; i++) {
1607 dev_dbg(dev, "vin[%d] is: 0x%x\n", i, data->in[i]);
1608 dev_dbg(dev, "vin[%d] max is: 0x%x\n", i, data->in_max[i]);
1609 dev_dbg(dev, "vin[%d] min is: 0x%x\n", i, data->in_min[i]);
1610 }
1611 dev_dbg(dev, "Low Bit1 is: 0x%x\n", data->low_bits[0]);
1612 dev_dbg(dev, "Low Bit2 is: 0x%x\n", data->low_bits[1]);
1613 dev_dbg(dev, "7 set of Fan Counts and Duty Cycles: =====>\n");
1614 for (i=0; i<7; i++) {
1615 dev_dbg(dev, "fan[%d] is: 0x%x\n", i, data->fan[i]);
1616 dev_dbg(dev, "fan[%d] min is: 0x%x\n", i, data->fan_min[i]);
1617 dev_dbg(dev, "pwm[%d] is: 0x%x\n", i, data->pwm[i]);
1618 dev_dbg(dev, "pwm_mode[%d] is: 0x%x\n", i, data->pwm_mode[i]);
1619 }
1620 dev_dbg(dev, "3 set of Temperatures: =====>\n");
1621 for (i=0; i<3; i++) {
1622 dev_dbg(dev, "temp1[%d] is: 0x%x\n", i, data->temp1[i]);
1623 }
1624
1625 for (i=0; i<2; i++) {
1626 for (j=0; j<6; j++) {
1627 dev_dbg(dev, "temp_add[%d][%d] is: 0x%x\n", i, j,
1628 data->temp_add[i][j]);
1629 }
1630 }
1631
1632 for (i=0; i<7; i++) {
1633 dev_dbg(dev, "fan_div[%d] is: 0x%x\n", i, data->fan_div[i]);
1634 }
1635 dev_dbg(dev, "==========End of the debug message...==================\n");
1636 dev_dbg(dev, "\n");
1637}
1638#endif
1639
1640static int __init
1641sensors_w83792d_init(void)
1642{
1643 return i2c_add_driver(&w83792d_driver);
1644}
1645
1646static void __exit
1647sensors_w83792d_exit(void)
1648{
1649 i2c_del_driver(&w83792d_driver);
1650}
1651
1652MODULE_AUTHOR("Chunhao Huang @ Winbond <DZShen@Winbond.com.tw>");
1653MODULE_DESCRIPTION("W83792AD/D driver for linux-2.6");
1654MODULE_LICENSE("GPL");
1655
1656module_init(sensors_w83792d_init);
1657module_exit(sensors_w83792d_exit);
1658