aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorR.Marek@sh.cvut.cz <R.Marek@sh.cvut.cz>2005-07-27 07:43:47 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2005-09-05 12:14:13 -0400
commit5563e27d3a42667734e81c1cb8ad72bff76321f6 (patch)
treec04676ff2cd3730efeb1a5b3dda2d9df9b1c1279
parent570aefc361d3315ec6749f573009286106b0b2d8 (diff)
[PATCH] I2C: W83792D driver 1/3
I would like to announce support for W83792D chip. This driver was developed by Winbond Electronics Corp. I added sysfs attributes callbacks infrastructure plus various code fixes and codingstyle cleanups. I would like to thank Winbond for supporting free software. This patch is against 2.6.13rc3 plus hwmon-class and hwmon-split. Separate patch for documantation and hwmon class register will follow. Signed-off-by: Rudolf Marek <r.marek@sh.cvut.cz> Signed-off-by: Chunhao Huang <DZShen@Winbond.com.tw> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/hwmon/Kconfig10
-rw-r--r--drivers/hwmon/Makefile1
-rw-r--r--drivers/hwmon/w83792d.c1633
-rw-r--r--include/linux/hwmon-sysfs.h15
4 files changed, 1659 insertions, 0 deletions
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 29583e1f7a20..6483ff696b5a 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -377,6 +377,16 @@ config SENSORS_W83781D
377 This driver can also be built as a module. If so, the module 377 This driver can also be built as a module. If so, the module
378 will be called w83781d. 378 will be called w83781d.
379 379
380config SENSORS_W83792D
381 tristate "Winbond W83792D"
382 depends on HWMON && I2C && EXPERIMENTAL
383 select I2C_SENSOR
384 help
385 If you say yes here you get support for the Winbond W83792D chip.
386
387 This driver can also be built as a module. If so, the module
388 will be called w83792d.
389
380config SENSORS_W83L785TS 390config SENSORS_W83L785TS
381 tristate "Winbond W83L785TS-S" 391 tristate "Winbond W83L785TS-S"
382 depends on HWMON && I2C && EXPERIMENTAL 392 depends on HWMON && I2C && EXPERIMENTAL
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index bd1bd59eb149..187b89d47f83 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_HWMON) += hwmon.o
7# asb100, then w83781d go first, as they can override other drivers' addresses. 7# asb100, then w83781d go first, as they can override other drivers' addresses.
8obj-$(CONFIG_SENSORS_ASB100) += asb100.o 8obj-$(CONFIG_SENSORS_ASB100) += asb100.o
9obj-$(CONFIG_SENSORS_W83627HF) += w83627hf.o 9obj-$(CONFIG_SENSORS_W83627HF) += w83627hf.o
10obj-$(CONFIG_SENSORS_W83792D) += w83792d.o
10obj-$(CONFIG_SENSORS_W83781D) += w83781d.o 11obj-$(CONFIG_SENSORS_W83781D) += w83781d.o
11 12
12obj-$(CONFIG_SENSORS_ADM1021) += adm1021.o 13obj-$(CONFIG_SENSORS_ADM1021) += adm1021.o
diff --git a/drivers/hwmon/w83792d.c b/drivers/hwmon/w83792d.c
new file mode 100644
index 000000000000..fa43b6fd1212
--- /dev/null
+++ b/drivers/hwmon/w83792d.c
@@ -0,0 +1,1633 @@
1/*
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>
43#include <linux/i2c-sensor.h>
44#include <linux/i2c-vid.h>
45#include <linux/hwmon-sysfs.h>
46
47/* Addresses to scan */
48static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f, I2C_CLIENT_END };
49
50/* Insmod parameters */
51SENSORS_INSMOD_1(w83792d);
52I2C_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
196#define W83792D_REG_CONFIG 0x40
197#define W83792D_REG_VID_FANDIV 0x47
198#define W83792D_REG_CHIPID 0x49
199#define W83792D_REG_WCHIPID 0x58
200#define W83792D_REG_CHIPMAN 0x4F
201#define W83792D_REG_PIN 0x4B
202#define W83792D_REG_I2C_SUBADDR 0x4A
203
204#define W83792D_REG_ALARM1 0xA9 /* realtime status register1 */
205#define W83792D_REG_ALARM2 0xAA /* realtime status register2 */
206#define W83792D_REG_ALARM3 0xAB /* realtime status register3 */
207#define W83792D_REG_CHASSIS 0x42 /* Bit 5: Case Open status bit */
208#define W83792D_REG_CHASSIS_CLR 0x44 /* Bit 7: Case Open CLR_CHS/Reset bit */
209
210/* control in0/in1 's limit modifiability */
211#define W83792D_REG_VID_IN_B 0x17
212
213#define W83792D_REG_VBAT 0x5D
214#define W83792D_REG_I2C_ADDR 0x48
215
216/* Conversions. Rounding and limit checking is only done on the TO_REG
217 variants. Note that you should be a bit careful with which arguments
218 these macros are called: arguments may be evaluated more than once.
219 Fixing this is just not worth it. */
220#define IN_FROM_REG(nr,val) (((nr)<=1)?(val*2): \
221 ((((nr)==6)||((nr)==7))?(val*6):(val*4)))
222#define IN_TO_REG(nr,val) (((nr)<=1)?(val/2): \
223 ((((nr)==6)||((nr)==7))?(val/6):(val/4)))
224
225static inline u8
226FAN_TO_REG(long rpm, int div)
227{
228 if (rpm == 0)
229 return 255;
230 rpm = SENSORS_LIMIT(rpm, 1, 1000000);
231 return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 254);
232}
233
234#define FAN_FROM_REG(val,div) ((val) == 0 ? -1 : \
235 ((val) == 255 ? 0 : \
236 1350000 / ((val) * (div))))
237
238/* for temp1 */
239#define TEMP1_TO_REG(val) (SENSORS_LIMIT(((val) < 0 ? (val)+0x100*1000 \
240 : (val)) / 1000, 0, 0xff))
241#define TEMP1_FROM_REG(val) (((val) & 0x80 ? (val)-0x100 : (val)) * 1000)
242/* for temp2 and temp3, because they need addtional resolution */
243#define TEMP_ADD_FROM_REG(val1, val2) \
244 ((((val1) & 0x80 ? (val1)-0x100 \
245 : (val1)) * 1000) + ((val2 & 0x80) ? 500 : 0))
246#define TEMP_ADD_TO_REG_HIGH(val) \
247 (SENSORS_LIMIT(((val) < 0 ? (val)+0x100*1000 \
248 : (val)) / 1000, 0, 0xff))
249#define TEMP_ADD_TO_REG_LOW(val) ((val%1000) ? 0x80 : 0x00)
250
251#define PWM_FROM_REG(val) (val)
252#define PWM_TO_REG(val) (SENSORS_LIMIT((val),0,255))
253#define DIV_FROM_REG(val) (1 << (val))
254
255static inline u8
256DIV_TO_REG(long val)
257{
258 int i;
259 val = SENSORS_LIMIT(val, 1, 128) >> 1;
260 for (i = 0; i < 6; i++) {
261 if (val == 0)
262 break;
263 val >>= 1;
264 }
265 return ((u8) i);
266}
267
268struct w83792d_data {
269 struct i2c_client client;
270 struct semaphore lock;
271 enum chips type;
272
273 struct semaphore update_lock;
274 char valid; /* !=0 if following fields are valid */
275 unsigned long last_updated; /* In jiffies */
276
277 /* array of 2 pointers to subclients */
278 struct i2c_client *lm75[2];
279
280 u8 in[9]; /* Register value */
281 u8 in_max[9]; /* Register value */
282 u8 in_min[9]; /* Register value */
283 u8 low_bits[2]; /* Additional resolution to voltage in0-6 */
284 u8 fan[7]; /* Register value */
285 u8 fan_min[7]; /* Register value */
286 u8 temp1[3]; /* current, over, thyst */
287 u8 temp_add[2][6]; /* Register value */
288 u8 fan_div[7]; /* Register encoding, shifted right */
289 u8 pwm[7]; /* We only consider the first 3 set of pwm,
290 although 792 chip has 7 set of pwm. */
291 u8 pwmenable[3];
292 u8 pwm_mode[7]; /* indicates PWM or DC mode: 1->PWM; 0->DC */
293 u32 alarms; /* realtime status register encoding,combined */
294 u8 chassis; /* Chassis status */
295 u8 chassis_clear; /* CLR_CHS, clear chassis intrusion detection */
296 u8 thermal_cruise[3]; /* Smart FanI: Fan1,2,3 target value */
297 u8 tolerance[3]; /* Fan1,2,3 tolerance(Smart Fan I/II) */
298 u8 sf2_points[3][4]; /* Smart FanII: Fan1,2,3 temperature points */
299 u8 sf2_levels[3][4]; /* Smart FanII: Fan1,2,3 duty cycle levels */
300};
301
302static int w83792d_attach_adapter(struct i2c_adapter *adapter);
303static int w83792d_detect(struct i2c_adapter *adapter, int address, int kind);
304static int w83792d_detach_client(struct i2c_client *client);
305
306static int w83792d_read_value(struct i2c_client *client, u8 register);
307static int w83792d_write_value(struct i2c_client *client, u8 register,
308 u8 value);
309static struct w83792d_data *w83792d_update_device(struct device *dev);
310
311#ifdef DEBUG
312static void w83792d_print_debug(struct w83792d_data *data, struct device *dev);
313#endif
314
315static void w83792d_init_client(struct i2c_client *client);
316
317static struct i2c_driver w83792d_driver = {
318 .owner = THIS_MODULE,
319 .name = "w83792d",
320 .flags = I2C_DF_NOTIFY,
321 .attach_adapter = w83792d_attach_adapter,
322 .detach_client = w83792d_detach_client,
323};
324
325static long in_count_from_reg(int nr, struct w83792d_data *data)
326{
327 u16 vol_count = data->in[nr];
328 u16 low_bits = 0;
329 vol_count = (vol_count << 2);
330 switch (nr)
331 {
332 case 0: /* vin0 */
333 low_bits = (data->low_bits[0]) & 0x03;
334 break;
335 case 1: /* vin1 */
336 low_bits = ((data->low_bits[0]) & 0x0c) >> 2;
337 break;
338 case 2: /* vin2 */
339 low_bits = ((data->low_bits[0]) & 0x30) >> 4;
340 break;
341 case 3: /* vin3 */
342 low_bits = ((data->low_bits[0]) & 0xc0) >> 6;
343 break;
344 case 4: /* vin4 */
345 low_bits = (data->low_bits[1]) & 0x03;
346 break;
347 case 5: /* vin5 */
348 low_bits = ((data->low_bits[1]) & 0x0c) >> 2;
349 break;
350 case 6: /* vin6 */
351 low_bits = ((data->low_bits[1]) & 0x30) >> 4;
352 default:
353 break;
354 }
355 vol_count = vol_count | low_bits;
356 return vol_count;
357}
358
359/* following are the sysfs callback functions */
360static ssize_t show_in(struct device *dev, struct device_attribute *attr,
361 char *buf)
362{
363 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
364 int nr = sensor_attr->index;
365 struct w83792d_data *data = w83792d_update_device(dev);
366 return sprintf(buf,"%ld\n", IN_FROM_REG(nr,(in_count_from_reg(nr, data))));
367}
368
369#define show_in_reg(reg) \
370static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \
371 char *buf) \
372{ \
373 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \
374 int nr = sensor_attr->index; \
375 struct w83792d_data *data = w83792d_update_device(dev); \
376 return sprintf(buf,"%ld\n", (long)(IN_FROM_REG(nr, (data->reg[nr])*4))); \
377}
378
379show_in_reg(in_min);
380show_in_reg(in_max);
381
382#define store_in_reg(REG, reg) \
383static ssize_t store_in_##reg (struct device *dev, \
384 struct device_attribute *attr, \
385 const char *buf, size_t count) \
386{ \
387 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \
388 int nr = sensor_attr->index; \
389 struct i2c_client *client = to_i2c_client(dev); \
390 struct w83792d_data *data = i2c_get_clientdata(client); \
391 u32 val; \
392 \
393 val = simple_strtoul(buf, NULL, 10); \
394 data->in_##reg[nr] = SENSORS_LIMIT(IN_TO_REG(nr, val)/4, 0, 255); \
395 w83792d_write_value(client, W83792D_REG_IN_##REG[nr], data->in_##reg[nr]); \
396 \
397 return count; \
398}
399store_in_reg(MIN, min);
400store_in_reg(MAX, max);
401
402#define sysfs_in_reg(offset) \
403static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in, \
404 NULL, offset); \
405static SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \
406 show_in_min, store_in_min, offset); \
407static SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \
408 show_in_max, store_in_max, offset);
409
410sysfs_in_reg(0);
411sysfs_in_reg(1);
412sysfs_in_reg(2);
413sysfs_in_reg(3);
414sysfs_in_reg(4);
415sysfs_in_reg(5);
416sysfs_in_reg(6);
417sysfs_in_reg(7);
418sysfs_in_reg(8);
419
420#define device_create_file_in(client, offset) \
421do { \
422device_create_file(&client->dev, &sensor_dev_attr_in##offset##_input.dev_attr); \
423device_create_file(&client->dev, &sensor_dev_attr_in##offset##_max.dev_attr); \
424device_create_file(&client->dev, &sensor_dev_attr_in##offset##_min.dev_attr); \
425} while (0)
426
427#define show_fan_reg(reg) \
428static ssize_t show_##reg (struct device *dev, struct device_attribute *attr, \
429 char *buf) \
430{ \
431 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \
432 int nr = sensor_attr->index - 1; \
433 struct w83792d_data *data = w83792d_update_device(dev); \
434 return sprintf(buf,"%d\n", \
435 FAN_FROM_REG(data->reg[nr], DIV_FROM_REG(data->fan_div[nr]))); \
436}
437
438show_fan_reg(fan);
439show_fan_reg(fan_min);
440
441static ssize_t
442store_fan_min(struct device *dev, struct device_attribute *attr,
443 const char *buf, size_t count)
444{
445 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
446 int nr = sensor_attr->index - 1;
447 struct i2c_client *client = to_i2c_client(dev);
448 struct w83792d_data *data = i2c_get_clientdata(client);
449 u32 val;
450
451 val = simple_strtoul(buf, NULL, 10);
452 data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
453 w83792d_write_value(client, W83792D_REG_FAN_MIN[nr],
454 data->fan_min[nr]);
455
456 return count;
457}
458
459static ssize_t
460show_fan_div(struct device *dev, struct device_attribute *attr,
461 char *buf)
462{
463 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
464 int nr = sensor_attr->index;
465 struct w83792d_data *data = w83792d_update_device(dev);
466 return sprintf(buf, "%u\n", DIV_FROM_REG(data->fan_div[nr - 1]));
467}
468
469/* Note: we save and restore the fan minimum here, because its value is
470 determined in part by the fan divisor. This follows the principle of
471 least suprise; the user doesn't expect the fan minimum to change just
472 because the divisor changed. */
473static ssize_t
474store_fan_div(struct device *dev, struct device_attribute *attr,
475 const char *buf, size_t count)
476{
477 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
478 int nr = sensor_attr->index - 1;
479 struct i2c_client *client = to_i2c_client(dev);
480 struct w83792d_data *data = i2c_get_clientdata(client);
481 unsigned long min;
482 /*u8 reg;*/
483 u8 fan_div_reg = 0;
484 u8 tmp_fan_div;
485
486 /* Save fan_min */
487 min = FAN_FROM_REG(data->fan_min[nr],
488 DIV_FROM_REG(data->fan_div[nr]));
489
490 data->fan_div[nr] = DIV_TO_REG(simple_strtoul(buf, NULL, 10));
491
492 fan_div_reg = w83792d_read_value(client, W83792D_REG_FAN_DIV[nr >> 1]);
493 fan_div_reg &= (nr & 0x01) ? 0x8f : 0xf8;
494 tmp_fan_div = (nr & 0x01) ? (((data->fan_div[nr]) << 4) & 0x70)
495 : ((data->fan_div[nr]) & 0x07);
496 w83792d_write_value(client, W83792D_REG_FAN_DIV[nr >> 1],
497 fan_div_reg | tmp_fan_div);
498
499 /* Restore fan_min */
500 data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
501 w83792d_write_value(client, W83792D_REG_FAN_MIN[nr], data->fan_min[nr]);
502
503 return count;
504}
505
506#define sysfs_fan(offset) \
507static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan, NULL, \
508 offset); \
509static SENSOR_DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \
510 show_fan_div, store_fan_div, offset); \
511static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
512 show_fan_min, store_fan_min, offset);
513
514sysfs_fan(1);
515sysfs_fan(2);
516sysfs_fan(3);
517sysfs_fan(4);
518sysfs_fan(5);
519sysfs_fan(6);
520sysfs_fan(7);
521
522#define device_create_file_fan(client, offset) \
523do { \
524device_create_file(&client->dev, &sensor_dev_attr_fan##offset##_input.dev_attr); \
525device_create_file(&client->dev, &sensor_dev_attr_fan##offset##_div.dev_attr); \
526device_create_file(&client->dev, &sensor_dev_attr_fan##offset##_min.dev_attr); \
527} while (0)
528
529
530/* read/write the temperature1, includes measured value and limits */
531
532static ssize_t show_temp1(struct device *dev, struct device_attribute *attr,
533 char *buf)
534{
535 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
536 int nr = sensor_attr->index;
537 struct w83792d_data *data = w83792d_update_device(dev);
538 return sprintf(buf, "%d\n", TEMP1_FROM_REG(data->temp1[nr]));
539}
540
541static ssize_t store_temp1(struct device *dev, struct device_attribute *attr,
542 const char *buf, size_t count)
543{
544 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
545 int nr = sensor_attr->index;
546 struct i2c_client *client = to_i2c_client(dev);
547 struct w83792d_data *data = i2c_get_clientdata(client);
548 s32 val;
549
550 val = simple_strtol(buf, NULL, 10);
551
552 data->temp1[nr] = TEMP1_TO_REG(val);
553 w83792d_write_value(client, W83792D_REG_TEMP1[nr],
554 data->temp1[nr]);
555
556 return count;
557}
558
559
560static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp1, NULL, 0);
561static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR, show_temp1,
562 store_temp1, 1);
563static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR, show_temp1,
564 store_temp1, 2);
565
566#define device_create_file_temp1(client) \
567do { \
568device_create_file(&client->dev, &sensor_dev_attr_temp1_input.dev_attr); \
569device_create_file(&client->dev, &sensor_dev_attr_temp1_max.dev_attr); \
570device_create_file(&client->dev, &sensor_dev_attr_temp1_max_hyst.dev_attr); \
571} while (0)
572
573
574/* read/write the temperature2-3, includes measured value and limits */
575
576static ssize_t show_temp23(struct device *dev, struct device_attribute *attr,
577 char *buf)
578{
579 struct sensor_device_attribute_2 *sensor_attr = to_sensor_dev_attr_2(attr);
580 int nr = sensor_attr->nr;
581 int index = sensor_attr->index;
582 struct w83792d_data *data = w83792d_update_device(dev);
583 return sprintf(buf,"%ld\n",
584 (long)TEMP_ADD_FROM_REG(data->temp_add[nr][index],
585 data->temp_add[nr][index+1]));
586}
587
588static ssize_t store_temp23(struct device *dev, struct device_attribute *attr,
589 const char *buf, size_t count)
590{
591 struct sensor_device_attribute_2 *sensor_attr = to_sensor_dev_attr_2(attr);
592 int nr = sensor_attr->nr;
593 int index = sensor_attr->index;
594 struct i2c_client *client = to_i2c_client(dev);
595 struct w83792d_data *data = i2c_get_clientdata(client);
596 s32 val;
597
598 val = simple_strtol(buf, NULL, 10);
599
600 data->temp_add[nr][index] = TEMP_ADD_TO_REG_HIGH(val);
601 data->temp_add[nr][index+1] = TEMP_ADD_TO_REG_LOW(val);
602 w83792d_write_value(client, W83792D_REG_TEMP_ADD[nr][index],
603 data->temp_add[nr][index]);
604 w83792d_write_value(client, W83792D_REG_TEMP_ADD[nr][index+1],
605 data->temp_add[nr][index+1]);
606
607 return count;
608}
609
610#define sysfs_temp23(name,idx) \
611static SENSOR_DEVICE_ATTR_2(name##_input, S_IRUGO, show_temp23, NULL, \
612 idx, 0); \
613static SENSOR_DEVICE_ATTR_2(name##_max, S_IRUGO | S_IWUSR, \
614 show_temp23, store_temp23, idx, 2); \
615static SENSOR_DEVICE_ATTR_2(name##_max_hyst, S_IRUGO | S_IWUSR, \
616 show_temp23, store_temp23, idx, 4);
617
618sysfs_temp23(temp2,0)
619sysfs_temp23(temp3,1)
620
621#define device_create_file_temp_add(client, offset) \
622do { \
623device_create_file(&client->dev, &sensor_dev_attr_temp##offset##_input.dev_attr); \
624device_create_file(&client->dev, &sensor_dev_attr_temp##offset##_max.dev_attr); \
625device_create_file(&client->dev, \
626&sensor_dev_attr_temp##offset##_max_hyst.dev_attr); \
627} while (0)
628
629
630/* get reatime status of all sensors items: voltage, temp, fan */
631static ssize_t
632show_alarms_reg(struct device *dev, struct device_attribute *attr, char *buf)
633{
634 struct w83792d_data *data = w83792d_update_device(dev);
635 return sprintf(buf, "%d\n", data->alarms);
636}
637
638static
639DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL);
640#define device_create_file_alarms(client) \
641device_create_file(&client->dev, &dev_attr_alarms);
642
643
644
645static ssize_t
646show_pwm(struct device *dev, struct device_attribute *attr,
647 char *buf)
648{
649 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
650 int nr = sensor_attr->index;
651 struct w83792d_data *data = w83792d_update_device(dev);
652 return sprintf(buf, "%ld\n", (long) PWM_FROM_REG(data->pwm[nr-1]));
653}
654
655static ssize_t
656show_pwmenable(struct device *dev, struct device_attribute *attr,
657 char *buf)
658{
659 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
660 int nr = sensor_attr->index - 1;
661 struct w83792d_data *data = w83792d_update_device(dev);
662 long pwm_enable_tmp = 1;
663
664 switch (data->pwmenable[nr]) {
665 case 0:
666 pwm_enable_tmp = 1; /* manual mode */
667 break;
668 case 1:
669 pwm_enable_tmp = 3; /*thermal cruise/Smart Fan I */
670 break;
671 case 2:
672 pwm_enable_tmp = 2; /* Smart Fan II */
673 break;
674 }
675
676 return sprintf(buf, "%ld\n", pwm_enable_tmp);
677}
678
679static ssize_t
680store_pwm(struct device *dev, struct device_attribute *attr,
681 const char *buf, size_t count)
682{
683 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
684 int nr = sensor_attr->index - 1;
685 struct i2c_client *client = to_i2c_client(dev);
686 struct w83792d_data *data = i2c_get_clientdata(client);
687 u32 val;
688
689 val = simple_strtoul(buf, NULL, 10);
690 data->pwm[nr] = PWM_TO_REG(val);
691 w83792d_write_value(client, W83792D_REG_PWM[nr], data->pwm[nr]);
692
693 return count;
694}
695
696static ssize_t
697store_pwmenable(struct device *dev, struct device_attribute *attr,
698 const char *buf, size_t count)
699{
700 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
701 int nr = sensor_attr->index - 1;
702 struct i2c_client *client = to_i2c_client(dev);
703 struct w83792d_data *data = i2c_get_clientdata(client);
704 u32 val;
705 u8 fan_cfg_tmp, cfg1_tmp, cfg2_tmp, cfg3_tmp, cfg4_tmp;
706
707 val = simple_strtoul(buf, NULL, 10);
708 switch (val) {
709 case 1:
710 data->pwmenable[nr] = 0; /* manual mode */
711 break;
712 case 2:
713 data->pwmenable[nr] = 2; /* Smart Fan II */
714 break;
715 case 3:
716 data->pwmenable[nr] = 1; /* thermal cruise/Smart Fan I */
717 break;
718 default:
719 return -EINVAL;
720 }
721 cfg1_tmp = data->pwmenable[0];
722 cfg2_tmp = (data->pwmenable[1]) << 2;
723 cfg3_tmp = (data->pwmenable[2]) << 4;
724 cfg4_tmp = w83792d_read_value(client,W83792D_REG_FAN_CFG) & 0xc0;
725 fan_cfg_tmp = ((cfg4_tmp | cfg3_tmp) | cfg2_tmp) | cfg1_tmp;
726 w83792d_write_value(client, W83792D_REG_FAN_CFG, fan_cfg_tmp);
727
728 return count;
729}
730
731#define sysfs_pwm(offset) \
732static SENSOR_DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \
733 show_pwm, store_pwm, offset); \
734static SENSOR_DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR, \
735 show_pwmenable, store_pwmenable, offset); \
736
737sysfs_pwm(1);
738sysfs_pwm(2);
739sysfs_pwm(3);
740
741
742#define device_create_file_pwm(client, offset) \
743do { \
744device_create_file(&client->dev, &sensor_dev_attr_pwm##offset.dev_attr); \
745} while (0)
746
747#define device_create_file_pwmenable(client, offset) \
748do { \
749device_create_file(&client->dev, &sensor_dev_attr_pwm##offset##_enable.dev_attr); \
750} while (0)
751
752
753static ssize_t
754show_pwm_mode(struct device *dev, struct device_attribute *attr,
755 char *buf)
756{
757 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
758 int nr = sensor_attr->index;
759 struct w83792d_data *data = w83792d_update_device(dev);
760 return sprintf(buf, "%d\n", data->pwm_mode[nr-1]);
761}
762
763static ssize_t
764store_pwm_mode(struct device *dev, struct device_attribute *attr,
765 const char *buf, size_t count)
766{
767 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
768 int nr = sensor_attr->index - 1;
769 struct i2c_client *client = to_i2c_client(dev);
770 struct w83792d_data *data = i2c_get_clientdata(client);
771 u32 val;
772 u8 pwm_mode_mask = 0;
773
774 val = simple_strtoul(buf, NULL, 10);
775 data->pwm_mode[nr] = SENSORS_LIMIT(val, 0, 1);
776 pwm_mode_mask = w83792d_read_value(client,
777 W83792D_REG_PWM[nr]) & 0x7f;
778 w83792d_write_value(client, W83792D_REG_PWM[nr],
779 ((data->pwm_mode[nr]) << 7) | pwm_mode_mask);
780
781 return count;
782}
783
784#define sysfs_pwm_mode(offset) \
785static SENSOR_DEVICE_ATTR(pwm##offset##_mode, S_IRUGO | S_IWUSR, \
786 show_pwm_mode, store_pwm_mode, offset);
787
788sysfs_pwm_mode(1);
789sysfs_pwm_mode(2);
790sysfs_pwm_mode(3);
791
792#define device_create_file_pwm_mode(client, offset) \
793do { \
794device_create_file(&client->dev, &sensor_dev_attr_pwm##offset##_mode.dev_attr); \
795} while (0)
796
797
798static ssize_t
799show_regs_chassis(struct device *dev, struct device_attribute *attr,
800 char *buf)
801{
802 struct w83792d_data *data = w83792d_update_device(dev);
803 return sprintf(buf, "%d\n", data->chassis);
804}
805
806static DEVICE_ATTR(chassis, S_IRUGO, show_regs_chassis, NULL);
807
808#define device_create_file_chassis(client) \
809do { \
810device_create_file(&client->dev, &dev_attr_chassis); \
811} while (0)
812
813
814static ssize_t
815show_chassis_clear(struct device *dev, struct device_attribute *attr, char *buf)
816{
817 struct w83792d_data *data = w83792d_update_device(dev);
818 return sprintf(buf, "%d\n", data->chassis_clear);
819}
820
821static ssize_t
822store_chassis_clear(struct device *dev, struct device_attribute *attr,
823 const char *buf, size_t count)
824{
825 struct i2c_client *client = to_i2c_client(dev);
826 struct w83792d_data *data = i2c_get_clientdata(client);
827 u32 val;
828 u8 temp1 = 0, temp2 = 0;
829
830 val = simple_strtoul(buf, NULL, 10);
831
832 data->chassis_clear = SENSORS_LIMIT(val, 0 ,1);
833 temp1 = ((data->chassis_clear) << 7) & 0x80;
834 temp2 = w83792d_read_value(client,
835 W83792D_REG_CHASSIS_CLR) & 0x7f;
836 w83792d_write_value(client, W83792D_REG_CHASSIS_CLR, temp1 | temp2);
837
838 return count;
839}
840
841static DEVICE_ATTR(chassis_clear, S_IRUGO | S_IWUSR,
842 show_chassis_clear, store_chassis_clear);
843
844#define device_create_file_chassis_clear(client) \
845do { \
846device_create_file(&client->dev, &dev_attr_chassis_clear); \
847} while (0)
848
849
850
851/* For Smart Fan I / Thermal Cruise */
852static ssize_t
853show_thermal_cruise(struct device *dev, struct device_attribute *attr,
854 char *buf)
855{
856 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
857 int nr = sensor_attr->index;
858 struct w83792d_data *data = w83792d_update_device(dev);
859 return sprintf(buf, "%ld\n", (long)data->thermal_cruise[nr-1]);
860}
861
862static ssize_t
863store_thermal_cruise(struct device *dev, struct device_attribute *attr,
864 const char *buf, size_t count)
865{
866 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
867 int nr = sensor_attr->index - 1;
868 struct i2c_client *client = to_i2c_client(dev);
869 struct w83792d_data *data = i2c_get_clientdata(client);
870 u32 val;
871 u8 target_tmp=0, target_mask=0;
872
873 val = simple_strtoul(buf, NULL, 10);
874 target_tmp = val;
875 target_tmp = target_tmp & 0x7f;
876 target_mask = w83792d_read_value(client, W83792D_REG_THERMAL[nr]) & 0x80;
877 data->thermal_cruise[nr] = SENSORS_LIMIT(target_tmp, 0, 255);
878 w83792d_write_value(client, W83792D_REG_THERMAL[nr],
879 (data->thermal_cruise[nr]) | target_mask);
880
881 return count;
882}
883
884#define sysfs_thermal_cruise(offset) \
885static SENSOR_DEVICE_ATTR(thermal_cruise##offset, S_IRUGO | S_IWUSR, \
886 show_thermal_cruise, store_thermal_cruise, offset);
887
888sysfs_thermal_cruise(1);
889sysfs_thermal_cruise(2);
890sysfs_thermal_cruise(3);
891
892#define device_create_file_thermal_cruise(client, offset) \
893do { \
894device_create_file(&client->dev, \
895&sensor_dev_attr_thermal_cruise##offset.dev_attr); \
896} while (0)
897
898
899/* For Smart Fan I/Thermal Cruise and Smart Fan II */
900static ssize_t
901show_tolerance(struct device *dev, struct device_attribute *attr,
902 char *buf)
903{
904 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
905 int nr = sensor_attr->index;
906 struct w83792d_data *data = w83792d_update_device(dev);
907 return sprintf(buf, "%ld\n", (long)data->tolerance[nr-1]);
908}
909
910static ssize_t
911store_tolerance(struct device *dev, struct device_attribute *attr,
912 const char *buf, size_t count)
913{
914 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
915 int nr = sensor_attr->index - 1;
916 struct i2c_client *client = to_i2c_client(dev);
917 struct w83792d_data *data = i2c_get_clientdata(client);
918 u32 val;
919 u8 tol_tmp, tol_mask;
920
921 val = simple_strtoul(buf, NULL, 10);
922 tol_mask = w83792d_read_value(client,
923 W83792D_REG_TOLERANCE[nr]) & ((nr == 1) ? 0x0f : 0xf0);
924 tol_tmp = SENSORS_LIMIT(val, 0, 15);
925 tol_tmp &= 0x0f;
926 data->tolerance[nr] = tol_tmp;
927 if (nr == 1) {
928 tol_tmp <<= 4;
929 }
930 w83792d_write_value(client, W83792D_REG_TOLERANCE[nr],
931 tol_mask | tol_tmp);
932
933 return count;
934}
935
936#define sysfs_tolerance(offset) \
937static SENSOR_DEVICE_ATTR(tolerance##offset, S_IRUGO | S_IWUSR, \
938 show_tolerance, store_tolerance, offset);
939
940sysfs_tolerance(1);
941sysfs_tolerance(2);
942sysfs_tolerance(3);
943
944#define device_create_file_tolerance(client, offset) \
945do { \
946device_create_file(&client->dev, &sensor_dev_attr_tolerance##offset.dev_attr); \
947} while (0)
948
949
950/* For Smart Fan II */
951static ssize_t
952show_sf2_point(struct device *dev, struct device_attribute *attr,
953 char *buf)
954{
955 struct sensor_device_attribute_2 *sensor_attr = to_sensor_dev_attr_2(attr);
956 int nr = sensor_attr->nr;
957 int index = sensor_attr->index;
958 struct w83792d_data *data = w83792d_update_device(dev);
959 return sprintf(buf, "%ld\n", (long)data->sf2_points[index-1][nr-1]);
960}
961
962static ssize_t
963store_sf2_point(struct device *dev, struct device_attribute *attr,
964 const char *buf, size_t count)
965{
966 struct sensor_device_attribute_2 *sensor_attr = to_sensor_dev_attr_2(attr);
967 int nr = sensor_attr->nr - 1;
968 int index = sensor_attr->index - 1;
969 struct i2c_client *client = to_i2c_client(dev);
970 struct w83792d_data *data = i2c_get_clientdata(client);
971 u32 val;
972 u8 mask_tmp = 0;
973
974 val = simple_strtoul(buf, NULL, 10);
975 data->sf2_points[index][nr] = SENSORS_LIMIT(val, 0, 127);
976 mask_tmp = w83792d_read_value(client,
977 W83792D_REG_POINTS[index][nr]) & 0x80;
978 w83792d_write_value(client, W83792D_REG_POINTS[index][nr],
979 mask_tmp|data->sf2_points[index][nr]);
980
981 return count;
982}
983
984#define sysfs_sf2_point(offset, index) \
985static SENSOR_DEVICE_ATTR_2(sf2_point##offset##_fan##index, S_IRUGO | S_IWUSR, \
986 show_sf2_point, store_sf2_point, offset, index);
987
988sysfs_sf2_point(1, 1); /* Fan1 */
989sysfs_sf2_point(2, 1); /* Fan1 */
990sysfs_sf2_point(3, 1); /* Fan1 */
991sysfs_sf2_point(4, 1); /* Fan1 */
992sysfs_sf2_point(1, 2); /* Fan2 */
993sysfs_sf2_point(2, 2); /* Fan2 */
994sysfs_sf2_point(3, 2); /* Fan2 */
995sysfs_sf2_point(4, 2); /* Fan2 */
996sysfs_sf2_point(1, 3); /* Fan3 */
997sysfs_sf2_point(2, 3); /* Fan3 */
998sysfs_sf2_point(3, 3); /* Fan3 */
999sysfs_sf2_point(4, 3); /* Fan3 */
1000
1001#define device_create_file_sf2_point(client, offset, index) \
1002do { \
1003device_create_file(&client->dev, \
1004&sensor_dev_attr_sf2_point##offset##_fan##index.dev_attr); \
1005} while (0)
1006
1007
1008static ssize_t
1009show_sf2_level(struct device *dev, struct device_attribute *attr,
1010 char *buf)
1011{
1012 struct sensor_device_attribute_2 *sensor_attr = to_sensor_dev_attr_2(attr);
1013 int nr = sensor_attr->nr;
1014 int index = sensor_attr->index;
1015 struct w83792d_data *data = w83792d_update_device(dev);
1016 return sprintf(buf, "%d\n",
1017 (((data->sf2_levels[index-1][nr]) * 100) / 15));
1018}
1019
1020static ssize_t
1021store_sf2_level(struct device *dev, struct device_attribute *attr,
1022 const char *buf, size_t count)
1023{
1024 struct sensor_device_attribute_2 *sensor_attr = to_sensor_dev_attr_2(attr);
1025 int nr = sensor_attr->nr;
1026 int index = sensor_attr->index - 1;
1027 struct i2c_client *client = to_i2c_client(dev);
1028 struct w83792d_data *data = i2c_get_clientdata(client);
1029 u32 val;
1030 u8 mask_tmp=0, level_tmp=0;
1031
1032 val = simple_strtoul(buf, NULL, 10);
1033 data->sf2_levels[index][nr] = SENSORS_LIMIT((val * 15) / 100, 0, 15);
1034 mask_tmp = w83792d_read_value(client, W83792D_REG_LEVELS[index][nr])
1035 & ((nr==3) ? 0xf0 : 0x0f);
1036 if (nr==3) {
1037 level_tmp = data->sf2_levels[index][nr];
1038 } else {
1039 level_tmp = data->sf2_levels[index][nr] << 4;
1040 }
1041 w83792d_write_value(client, W83792D_REG_LEVELS[index][nr], level_tmp | mask_tmp);
1042
1043 return count;
1044}
1045
1046#define sysfs_sf2_level(offset, index) \
1047static SENSOR_DEVICE_ATTR_2(sf2_level##offset##_fan##index, S_IRUGO | S_IWUSR, \
1048 show_sf2_level, store_sf2_level, offset, index);
1049
1050sysfs_sf2_level(1, 1); /* Fan1 */
1051sysfs_sf2_level(2, 1); /* Fan1 */
1052sysfs_sf2_level(3, 1); /* Fan1 */
1053sysfs_sf2_level(1, 2); /* Fan2 */
1054sysfs_sf2_level(2, 2); /* Fan2 */
1055sysfs_sf2_level(3, 2); /* Fan2 */
1056sysfs_sf2_level(1, 3); /* Fan3 */
1057sysfs_sf2_level(2, 3); /* Fan3 */
1058sysfs_sf2_level(3, 3); /* Fan3 */
1059
1060#define device_create_file_sf2_level(client, offset, index) \
1061do { \
1062device_create_file(&client->dev, \
1063&sensor_dev_attr_sf2_level##offset##_fan##index.dev_attr); \
1064} while (0)
1065
1066
1067/* This function is called when:
1068 * w83792d_driver is inserted (when this module is loaded), for each
1069 available adapter
1070 * when a new adapter is inserted (and w83792d_driver is still present) */
1071static int
1072w83792d_attach_adapter(struct i2c_adapter *adapter)
1073{
1074 if (!(adapter->class & I2C_CLASS_HWMON))
1075 return 0;
1076 return i2c_detect(adapter, &addr_data, w83792d_detect);
1077}
1078
1079
1080static int
1081w83792d_create_subclient(struct i2c_adapter *adapter,
1082 struct i2c_client *new_client, int addr,
1083 struct i2c_client **sub_cli)
1084{
1085 int err;
1086 struct i2c_client *sub_client;
1087
1088 (*sub_cli) = sub_client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
1089 if (!(sub_client)) {
1090 return -ENOMEM;
1091 }
1092 memset(sub_client, 0x00, sizeof(struct i2c_client));
1093 sub_client->addr = 0x48 + addr;
1094 i2c_set_clientdata(sub_client, NULL);
1095 sub_client->adapter = adapter;
1096 sub_client->driver = &w83792d_driver;
1097 sub_client->flags = 0;
1098 strlcpy(sub_client->name, "w83792d subclient", I2C_NAME_SIZE);
1099 if ((err = i2c_attach_client(sub_client))) {
1100 dev_err(&new_client->dev, "subclient registration "
1101 "at address 0x%x failed\n", sub_client->addr);
1102 kfree(sub_client);
1103 return err;
1104 }
1105 return 0;
1106}
1107
1108
1109static int
1110w83792d_detect_subclients(struct i2c_adapter *adapter, int address, int kind,
1111 struct i2c_client *new_client)
1112{
1113 int i, id, err;
1114 u8 val;
1115 struct w83792d_data *data = i2c_get_clientdata(new_client);
1116
1117 id = i2c_adapter_id(adapter);
1118 if (force_subclients[0] == id && force_subclients[1] == address) {
1119 for (i = 2; i <= 3; i++) {
1120 if (force_subclients[i] < 0x48 ||
1121 force_subclients[i] > 0x4f) {
1122 dev_err(&new_client->dev, "invalid subclient "
1123 "address %d; must be 0x48-0x4f\n",
1124 force_subclients[i]);
1125 err = -ENODEV;
1126 goto ERROR_SC_0;
1127 }
1128 }
1129 w83792d_write_value(new_client, W83792D_REG_I2C_SUBADDR,
1130 (force_subclients[2] & 0x07) |
1131 ((force_subclients[3] & 0x07) << 4));
1132 }
1133
1134 val = w83792d_read_value(new_client, W83792D_REG_I2C_SUBADDR);
1135 if (!(val & 0x08)) {
1136 err = w83792d_create_subclient(adapter, new_client, val & 0x7,
1137 &data->lm75[0]);
1138 if (err < 0)
1139 goto ERROR_SC_0;
1140 }
1141 if (!(val & 0x80)) {
1142 if ((data->lm75[0] != NULL) &&
1143 ((val & 0x7) == ((val >> 4) & 0x7))) {
1144 dev_err(&new_client->dev, "duplicate addresses 0x%x, "
1145 "use force_subclient\n", data->lm75[0]->addr);
1146 err = -ENODEV;
1147 goto ERROR_SC_1;
1148 }
1149 err = w83792d_create_subclient(adapter, new_client,
1150 (val >> 4) & 0x7, &data->lm75[1]);
1151 if (err < 0)
1152 goto ERROR_SC_1;
1153 }
1154
1155 return 0;
1156
1157/* Undo inits in case of errors */
1158
1159ERROR_SC_1:
1160 if (data->lm75[0] != NULL) {
1161 i2c_detach_client(data->lm75[0]);
1162 kfree(data->lm75[0]);
1163 }
1164ERROR_SC_0:
1165 return err;
1166}
1167
1168
1169static int
1170w83792d_detect(struct i2c_adapter *adapter, int address, int kind)
1171{
1172 int i = 0, val1 = 0, val2;
1173 struct i2c_client *new_client;
1174 struct w83792d_data *data;
1175 int err = 0;
1176 const char *client_name = "";
1177
1178 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
1179 goto ERROR0;
1180 }
1181
1182 /* OK. For now, we presume we have a valid client. We now create the
1183 client structure, even though we cannot fill it completely yet.
1184 But it allows us to access w83792d_{read,write}_value. */
1185
1186 if (!(data = kmalloc(sizeof(struct w83792d_data), GFP_KERNEL))) {
1187 err = -ENOMEM;
1188 goto ERROR0;
1189 }
1190 memset(data, 0, sizeof(struct w83792d_data));
1191
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 */
1286 for (i = 1; i <= 7; i++) {
1287 data->fan_min[i - 1] = w83792d_read_value(new_client,
1288 W83792D_REG_FAN_MIN[i]);
1289 }
1290
1291 /* Register sysfs hooks */
1292 device_create_file_in(new_client, 0);
1293 device_create_file_in(new_client, 1);
1294 device_create_file_in(new_client, 2);
1295 device_create_file_in(new_client, 3);
1296 device_create_file_in(new_client, 4);
1297 device_create_file_in(new_client, 5);
1298 device_create_file_in(new_client, 6);
1299 device_create_file_in(new_client, 7);
1300 device_create_file_in(new_client, 8);
1301
1302 device_create_file_fan(new_client, 1);
1303 device_create_file_fan(new_client, 2);
1304 device_create_file_fan(new_client, 3);
1305 device_create_file_fan(new_client, 4);
1306 device_create_file_fan(new_client, 5);
1307 device_create_file_fan(new_client, 6);
1308 device_create_file_fan(new_client, 7);
1309
1310 device_create_file_temp1(new_client); /* Temp1 */
1311 device_create_file_temp_add(new_client, 2); /* Temp2 */
1312 device_create_file_temp_add(new_client, 3); /* Temp3 */
1313
1314 device_create_file_alarms(new_client);
1315
1316 device_create_file_pwm(new_client, 1);
1317 device_create_file_pwm(new_client, 2);
1318 device_create_file_pwm(new_client, 3);
1319
1320 device_create_file_pwmenable(new_client, 1);
1321 device_create_file_pwmenable(new_client, 2);
1322 device_create_file_pwmenable(new_client, 3);
1323
1324 device_create_file_pwm_mode(new_client, 1);
1325 device_create_file_pwm_mode(new_client, 2);
1326 device_create_file_pwm_mode(new_client, 3);
1327
1328 device_create_file_chassis(new_client);
1329 device_create_file_chassis_clear(new_client);
1330
1331 device_create_file_thermal_cruise(new_client, 1);
1332 device_create_file_thermal_cruise(new_client, 2);
1333 device_create_file_thermal_cruise(new_client, 3);
1334
1335 device_create_file_tolerance(new_client, 1);
1336 device_create_file_tolerance(new_client, 2);
1337 device_create_file_tolerance(new_client, 3);
1338
1339 device_create_file_sf2_point(new_client, 1, 1); /* Fan1 */
1340 device_create_file_sf2_point(new_client, 2, 1); /* Fan1 */
1341 device_create_file_sf2_point(new_client, 3, 1); /* Fan1 */
1342 device_create_file_sf2_point(new_client, 4, 1); /* Fan1 */
1343 device_create_file_sf2_point(new_client, 1, 2); /* Fan2 */
1344 device_create_file_sf2_point(new_client, 2, 2); /* Fan2 */
1345 device_create_file_sf2_point(new_client, 3, 2); /* Fan2 */
1346 device_create_file_sf2_point(new_client, 4, 2); /* Fan2 */
1347 device_create_file_sf2_point(new_client, 1, 3); /* Fan3 */
1348 device_create_file_sf2_point(new_client, 2, 3); /* Fan3 */
1349 device_create_file_sf2_point(new_client, 3, 3); /* Fan3 */
1350 device_create_file_sf2_point(new_client, 4, 3); /* Fan3 */
1351
1352 device_create_file_sf2_level(new_client, 1, 1); /* Fan1 */
1353 device_create_file_sf2_level(new_client, 2, 1); /* Fan1 */
1354 device_create_file_sf2_level(new_client, 3, 1); /* Fan1 */
1355 device_create_file_sf2_level(new_client, 1, 2); /* Fan2 */
1356 device_create_file_sf2_level(new_client, 2, 2); /* Fan2 */
1357 device_create_file_sf2_level(new_client, 3, 2); /* Fan2 */
1358 device_create_file_sf2_level(new_client, 1, 3); /* Fan3 */
1359 device_create_file_sf2_level(new_client, 2, 3); /* Fan3 */
1360 device_create_file_sf2_level(new_client, 3, 3); /* Fan3 */
1361
1362 return 0;
1363
1364ERROR2:
1365 i2c_detach_client(new_client);
1366ERROR1:
1367 kfree(data);
1368ERROR0:
1369 return err;
1370}
1371
1372static int
1373w83792d_detach_client(struct i2c_client *client)
1374{
1375 int err;
1376
1377 if ((err = i2c_detach_client(client))) {
1378 dev_err(&client->dev,
1379 "Client deregistration failed, client not detached.\n");
1380 return err;
1381 }
1382
1383 if (i2c_get_clientdata(client)==NULL) {
1384 /* subclients */
1385 kfree(client);
1386 } else {
1387 /* main client */
1388 kfree(i2c_get_clientdata(client));
1389 }
1390
1391 return 0;
1392}
1393
1394/* The SMBus locks itself, usually, but nothing may access the Winbond between
1395 bank switches. ISA access must always be locked explicitly!
1396 We ignore the W83792D BUSY flag at this moment - it could lead to deadlocks,
1397 would slow down the W83792D access and should not be necessary.
1398 There are some ugly typecasts here, but the good news is - they should
1399 nowhere else be necessary! */
1400static int
1401w83792d_read_value(struct i2c_client *client, u8 reg)
1402{
1403 int res=0;
1404 res = i2c_smbus_read_byte_data(client, reg);
1405
1406 return res;
1407}
1408
1409static int
1410w83792d_write_value(struct i2c_client *client, u8 reg, u8 value)
1411{
1412 i2c_smbus_write_byte_data(client, reg, value);
1413 return 0;
1414}
1415
1416/* Called when we have found a new W83792D. It should set limits, etc. */
1417static void
1418w83792d_init_client(struct i2c_client *client)
1419{
1420 u8 temp2_cfg, temp3_cfg, vid_in_b;
1421
1422 if (init) {
1423 w83792d_write_value(client, W83792D_REG_CONFIG, 0x80);
1424 }
1425 /* Clear the bit6 of W83792D_REG_VID_IN_B(set it into 0):
1426 W83792D_REG_VID_IN_B bit6 = 0: the high/low limit of
1427 vin0/vin1 can be modified by user;
1428 W83792D_REG_VID_IN_B bit6 = 1: the high/low limit of
1429 vin0/vin1 auto-updated, can NOT be modified by user. */
1430 vid_in_b = w83792d_read_value(client, W83792D_REG_VID_IN_B);
1431 w83792d_write_value(client, W83792D_REG_VID_IN_B,
1432 vid_in_b & 0xbf);
1433
1434 temp2_cfg = w83792d_read_value(client, W83792D_REG_TEMP2_CONFIG);
1435 temp3_cfg = w83792d_read_value(client, W83792D_REG_TEMP3_CONFIG);
1436 w83792d_write_value(client, W83792D_REG_TEMP2_CONFIG,
1437 temp2_cfg & 0xe6);
1438 w83792d_write_value(client, W83792D_REG_TEMP3_CONFIG,
1439 temp3_cfg & 0xe6);
1440
1441 /* Start monitoring */
1442 w83792d_write_value(client, W83792D_REG_CONFIG,
1443 (w83792d_read_value(client,
1444 W83792D_REG_CONFIG) & 0xf7)
1445 | 0x01);
1446}
1447
1448static struct w83792d_data *w83792d_update_device(struct device *dev)
1449{
1450 struct i2c_client *client = to_i2c_client(dev);
1451 struct w83792d_data *data = i2c_get_clientdata(client);
1452 int i, j;
1453 u8 reg_array_tmp[4], pwm_array_tmp[7], reg_tmp;
1454
1455 down(&data->update_lock);
1456
1457 if (time_after
1458 (jiffies - data->last_updated, (unsigned long) (HZ * 3))
1459 || time_before(jiffies, data->last_updated) || !data->valid) {
1460 dev_dbg(dev, "Starting device update\n");
1461
1462 /* Update the voltages measured value and limits */
1463 for (i = 0; i < 9; i++) {
1464 data->in[i] = w83792d_read_value(client,
1465 W83792D_REG_IN[i]);
1466 data->in_max[i] = w83792d_read_value(client,
1467 W83792D_REG_IN_MAX[i]);
1468 data->in_min[i] = w83792d_read_value(client,
1469 W83792D_REG_IN_MIN[i]);
1470 }
1471 data->low_bits[0] = w83792d_read_value(client,
1472 W83792D_REG_LOW_BITS1);
1473 data->low_bits[1] = w83792d_read_value(client,
1474 W83792D_REG_LOW_BITS2);
1475 for (i = 0; i < 7; i++) {
1476 /* Update the Fan measured value and limits */
1477 data->fan[i] = w83792d_read_value(client,
1478 W83792D_REG_FAN[i]);
1479 data->fan_min[i] = w83792d_read_value(client,
1480 W83792D_REG_FAN_MIN[i]);
1481 /* Update the PWM/DC Value and PWM/DC flag */
1482 pwm_array_tmp[i] = w83792d_read_value(client,
1483 W83792D_REG_PWM[i]);
1484 data->pwm[i] = pwm_array_tmp[i] & 0x0f;
1485 data->pwm_mode[i] = (pwm_array_tmp[i] >> 7) & 0x01;
1486 }
1487
1488 reg_tmp = w83792d_read_value(client, W83792D_REG_FAN_CFG);
1489 data->pwmenable[0] = reg_tmp & 0x03;
1490 data->pwmenable[1] = (reg_tmp>>2) & 0x03;
1491 data->pwmenable[2] = (reg_tmp>>4) & 0x03;
1492
1493 for (i = 0; i < 3; i++) {
1494 data->temp1[i] = w83792d_read_value(client,
1495 W83792D_REG_TEMP1[i]);
1496 }
1497 for (i = 0; i < 2; i++) {
1498 for (j = 0; j < 6; j++) {
1499 data->temp_add[i][j] = w83792d_read_value(
1500 client,W83792D_REG_TEMP_ADD[i][j]);
1501 }
1502 }
1503
1504 /* Update the Fan Divisor */
1505 for (i = 0; i < 4; i++) {
1506 reg_array_tmp[i] = w83792d_read_value(client,
1507 W83792D_REG_FAN_DIV[i]);
1508 }
1509 data->fan_div[0] = reg_array_tmp[0] & 0x07;
1510 data->fan_div[1] = (reg_array_tmp[0] >> 4) & 0x07;
1511 data->fan_div[2] = reg_array_tmp[1] & 0x07;
1512 data->fan_div[3] = (reg_array_tmp[1] >> 4) & 0x07;
1513 data->fan_div[4] = reg_array_tmp[2] & 0x07;
1514 data->fan_div[5] = (reg_array_tmp[2] >> 4) & 0x07;
1515 data->fan_div[6] = reg_array_tmp[3] & 0x07;
1516
1517 /* Update the realtime status */
1518 data->alarms = w83792d_read_value(client, W83792D_REG_ALARM1) +
1519 (w83792d_read_value(client, W83792D_REG_ALARM2) << 8) +
1520 (w83792d_read_value(client, W83792D_REG_ALARM3) << 16);
1521
1522 /* Update CaseOpen status and it's CLR_CHS. */
1523 data->chassis = (w83792d_read_value(client,
1524 W83792D_REG_CHASSIS) >> 5) & 0x01;
1525 data->chassis_clear = (w83792d_read_value(client,
1526 W83792D_REG_CHASSIS_CLR) >> 7) & 0x01;
1527
1528 /* Update Thermal Cruise/Smart Fan I target value */
1529 for (i = 0; i < 3; i++) {
1530 data->thermal_cruise[i] =
1531 w83792d_read_value(client,
1532 W83792D_REG_THERMAL[i]) & 0x7f;
1533 }
1534
1535 /* Update Smart Fan I/II tolerance */
1536 reg_tmp = w83792d_read_value(client, W83792D_REG_TOLERANCE[0]);
1537 data->tolerance[0] = reg_tmp & 0x0f;
1538 data->tolerance[1] = (reg_tmp >> 4) & 0x0f;
1539 data->tolerance[2] = w83792d_read_value(client,
1540 W83792D_REG_TOLERANCE[2]) & 0x0f;
1541
1542 /* Update Smart Fan II temperature points */
1543 for (i = 0; i < 3; i++) {
1544 for (j = 0; j < 4; j++) {
1545 data->sf2_points[i][j] = w83792d_read_value(
1546 client,W83792D_REG_POINTS[i][j]) & 0x7f;
1547 }
1548 }
1549
1550 /* Update Smart Fan II duty cycle levels */
1551 for (i = 0; i < 3; i++) {
1552 reg_tmp = w83792d_read_value(client,
1553 W83792D_REG_LEVELS[i][0]);
1554 data->sf2_levels[i][0] = reg_tmp & 0x0f;
1555 data->sf2_levels[i][1] = (reg_tmp >> 4) & 0x0f;
1556 reg_tmp = w83792d_read_value(client,
1557 W83792D_REG_LEVELS[i][2]);
1558 data->sf2_levels[i][2] = (reg_tmp >> 4) & 0x0f;
1559 data->sf2_levels[i][3] = reg_tmp & 0x0f;
1560 }
1561
1562 data->last_updated = jiffies;
1563 data->valid = 1;
1564 }
1565
1566 up(&data->update_lock);
1567
1568#ifdef DEBUG
1569 w83792d_print_debug(data, dev);
1570#endif
1571
1572 return data;
1573}
1574
1575#ifdef DEBUG
1576static void w83792d_print_debug(struct w83792d_data *data, struct device *dev)
1577{
1578 int i=0, j=0;
1579 dev_dbg(dev, "==========The following is the debug message...========\n");
1580 dev_dbg(dev, "9 set of Voltages: =====>\n");
1581 for (i=0; i<9; i++) {
1582 dev_dbg(dev, "vin[%d] is: 0x%x\n", i, data->in[i]);
1583 dev_dbg(dev, "vin[%d] max is: 0x%x\n", i, data->in_max[i]);
1584 dev_dbg(dev, "vin[%d] min is: 0x%x\n", i, data->in_min[i]);
1585 }
1586 dev_dbg(dev, "Low Bit1 is: 0x%x\n", data->low_bits[0]);
1587 dev_dbg(dev, "Low Bit2 is: 0x%x\n", data->low_bits[1]);
1588 dev_dbg(dev, "7 set of Fan Counts and Duty Cycles: =====>\n");
1589 for (i=0; i<7; i++) {
1590 dev_dbg(dev, "fan[%d] is: 0x%x\n", i, data->fan[i]);
1591 dev_dbg(dev, "fan[%d] min is: 0x%x\n", i, data->fan_min[i]);
1592 dev_dbg(dev, "pwm[%d] is: 0x%x\n", i, data->pwm[i]);
1593 dev_dbg(dev, "pwm_mode[%d] is: 0x%x\n", i, data->pwm_mode[i]);
1594 }
1595 dev_dbg(dev, "3 set of Temperatures: =====>\n");
1596 for (i=0; i<3; i++) {
1597 dev_dbg(dev, "temp1[%d] is: 0x%x\n", i, data->temp1[i]);
1598 }
1599
1600 for (i=0; i<2; i++) {
1601 for (j=0; j<6; j++) {
1602 dev_dbg(dev, "temp_add[%d][%d] is: 0x%x\n", i, j,
1603 data->temp_add[i][j]);
1604 }
1605 }
1606
1607 for (i=0; i<7; i++) {
1608 dev_dbg(dev, "fan_div[%d] is: 0x%x\n", i, data->fan_div[i]);
1609 }
1610 dev_dbg(dev, "==========End of the debug message...==================\n");
1611 dev_dbg(dev, "\n");
1612}
1613#endif
1614
1615static int __init
1616sensors_w83792d_init(void)
1617{
1618 return i2c_add_driver(&w83792d_driver);
1619}
1620
1621static void __exit
1622sensors_w83792d_exit(void)
1623{
1624 i2c_del_driver(&w83792d_driver);
1625}
1626
1627MODULE_AUTHOR("Chunhao Huang @ Winbond <DZShen@Winbond.com.tw>");
1628MODULE_DESCRIPTION("W83792AD/D driver for linux-2.6");
1629MODULE_LICENSE("GPL");
1630
1631module_init(sensors_w83792d_init);
1632module_exit(sensors_w83792d_exit);
1633
diff --git a/include/linux/hwmon-sysfs.h b/include/linux/hwmon-sysfs.h
index 1b5018a965f5..7eb4004b3601 100644
--- a/include/linux/hwmon-sysfs.h
+++ b/include/linux/hwmon-sysfs.h
@@ -33,4 +33,19 @@ struct sensor_device_attribute sensor_dev_attr_##_name = { \
33 .index = _index, \ 33 .index = _index, \
34} 34}
35 35
36struct sensor_device_attribute_2 {
37 struct device_attribute dev_attr;
38 u8 index;
39 u8 nr;
40};
41#define to_sensor_dev_attr_2(_dev_attr) \
42 container_of(_dev_attr, struct sensor_device_attribute_2, dev_attr)
43
44#define SENSOR_DEVICE_ATTR_2(_name,_mode,_show,_store,_nr,_index) \
45struct sensor_device_attribute_2 sensor_dev_attr_##_name = { \
46 .dev_attr = __ATTR(_name,_mode,_show,_store), \
47 .index = _index, \
48 .nr = _nr, \
49}
50
36#endif /* _LINUX_HWMON_SYSFS_H */ 51#endif /* _LINUX_HWMON_SYSFS_H */