diff options
Diffstat (limited to 'drivers/hwmon/w83781d.c')
-rw-r--r-- | drivers/hwmon/w83781d.c | 1205 |
1 files changed, 665 insertions, 540 deletions
diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c index a47da3ec5472..f85b48fea1c4 100644 --- a/drivers/hwmon/w83781d.c +++ b/drivers/hwmon/w83781d.c | |||
@@ -2,8 +2,9 @@ | |||
2 | w83781d.c - Part of lm_sensors, Linux kernel modules for hardware | 2 | w83781d.c - Part of lm_sensors, Linux kernel modules for hardware |
3 | monitoring | 3 | monitoring |
4 | Copyright (c) 1998 - 2001 Frodo Looijaard <frodol@dds.nl>, | 4 | Copyright (c) 1998 - 2001 Frodo Looijaard <frodol@dds.nl>, |
5 | Philip Edelbrock <phil@netroedge.com>, | 5 | Philip Edelbrock <phil@netroedge.com>, |
6 | and Mark Studebaker <mdsxyz123@yahoo.com> | 6 | and Mark Studebaker <mdsxyz123@yahoo.com> |
7 | Copyright (c) 2007 Jean Delvare <khali@linux-fr.org> | ||
7 | 8 | ||
8 | This program is free software; you can redistribute it and/or modify | 9 | 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 | it under the terms of the GNU General Public License as published by |
@@ -38,15 +39,20 @@ | |||
38 | #include <linux/slab.h> | 39 | #include <linux/slab.h> |
39 | #include <linux/jiffies.h> | 40 | #include <linux/jiffies.h> |
40 | #include <linux/i2c.h> | 41 | #include <linux/i2c.h> |
41 | #include <linux/i2c-isa.h> | 42 | #include <linux/platform_device.h> |
43 | #include <linux/ioport.h> | ||
42 | #include <linux/hwmon.h> | 44 | #include <linux/hwmon.h> |
43 | #include <linux/hwmon-vid.h> | 45 | #include <linux/hwmon-vid.h> |
46 | #include <linux/hwmon-sysfs.h> | ||
44 | #include <linux/sysfs.h> | 47 | #include <linux/sysfs.h> |
45 | #include <linux/err.h> | 48 | #include <linux/err.h> |
46 | #include <linux/mutex.h> | 49 | #include <linux/mutex.h> |
47 | #include <asm/io.h> | 50 | #include <asm/io.h> |
48 | #include "lm75.h" | 51 | #include "lm75.h" |
49 | 52 | ||
53 | /* ISA device, if found */ | ||
54 | static struct platform_device *pdev; | ||
55 | |||
50 | /* Addresses to scan */ | 56 | /* Addresses to scan */ |
51 | static unsigned short normal_i2c[] = { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, | 57 | static unsigned short normal_i2c[] = { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, |
52 | 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, | 58 | 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, |
@@ -75,8 +81,8 @@ MODULE_PARM_DESC(init, "Set to zero to bypass chip initialization"); | |||
75 | #define W83781D_ADDR_REG_OFFSET 5 | 81 | #define W83781D_ADDR_REG_OFFSET 5 |
76 | #define W83781D_DATA_REG_OFFSET 6 | 82 | #define W83781D_DATA_REG_OFFSET 6 |
77 | 83 | ||
78 | /* The W83781D registers */ | 84 | /* The device registers */ |
79 | /* The W83782D registers for nr=7,8 are in bank 5 */ | 85 | /* in nr from 0 to 8 */ |
80 | #define W83781D_REG_IN_MAX(nr) ((nr < 7) ? (0x2b + (nr) * 2) : \ | 86 | #define W83781D_REG_IN_MAX(nr) ((nr < 7) ? (0x2b + (nr) * 2) : \ |
81 | (0x554 + (((nr) - 7) * 2))) | 87 | (0x554 + (((nr) - 7) * 2))) |
82 | #define W83781D_REG_IN_MIN(nr) ((nr < 7) ? (0x2c + (nr) * 2) : \ | 88 | #define W83781D_REG_IN_MIN(nr) ((nr < 7) ? (0x2c + (nr) * 2) : \ |
@@ -84,12 +90,14 @@ MODULE_PARM_DESC(init, "Set to zero to bypass chip initialization"); | |||
84 | #define W83781D_REG_IN(nr) ((nr < 7) ? (0x20 + (nr)) : \ | 90 | #define W83781D_REG_IN(nr) ((nr < 7) ? (0x20 + (nr)) : \ |
85 | (0x550 + (nr) - 7)) | 91 | (0x550 + (nr) - 7)) |
86 | 92 | ||
87 | #define W83781D_REG_FAN_MIN(nr) (0x3a + (nr)) | 93 | /* fan nr from 0 to 2 */ |
88 | #define W83781D_REG_FAN(nr) (0x27 + (nr)) | 94 | #define W83781D_REG_FAN_MIN(nr) (0x3b + (nr)) |
95 | #define W83781D_REG_FAN(nr) (0x28 + (nr)) | ||
89 | 96 | ||
90 | #define W83781D_REG_BANK 0x4E | 97 | #define W83781D_REG_BANK 0x4E |
91 | #define W83781D_REG_TEMP2_CONFIG 0x152 | 98 | #define W83781D_REG_TEMP2_CONFIG 0x152 |
92 | #define W83781D_REG_TEMP3_CONFIG 0x252 | 99 | #define W83781D_REG_TEMP3_CONFIG 0x252 |
100 | /* temp nr from 1 to 3 */ | ||
93 | #define W83781D_REG_TEMP(nr) ((nr == 3) ? (0x0250) : \ | 101 | #define W83781D_REG_TEMP(nr) ((nr == 3) ? (0x0250) : \ |
94 | ((nr == 2) ? (0x0150) : \ | 102 | ((nr == 2) ? (0x0150) : \ |
95 | (0x27))) | 103 | (0x27))) |
@@ -127,19 +135,9 @@ MODULE_PARM_DESC(init, "Set to zero to bypass chip initialization"); | |||
127 | #define W83781D_REG_VBAT 0x5D | 135 | #define W83781D_REG_VBAT 0x5D |
128 | 136 | ||
129 | /* PWM 782D (1-4) and 783S (1-2) only */ | 137 | /* PWM 782D (1-4) and 783S (1-2) only */ |
130 | #define W83781D_REG_PWM1 0x5B /* 782d and 783s/627hf datasheets disagree */ | 138 | static const u8 W83781D_REG_PWM[] = { 0x5B, 0x5A, 0x5E, 0x5F }; |
131 | /* on which is which; */ | ||
132 | #define W83781D_REG_PWM2 0x5A /* We follow the 782d convention here, */ | ||
133 | /* However 782d is probably wrong. */ | ||
134 | #define W83781D_REG_PWM3 0x5E | ||
135 | #define W83781D_REG_PWM4 0x5F | ||
136 | #define W83781D_REG_PWMCLK12 0x5C | 139 | #define W83781D_REG_PWMCLK12 0x5C |
137 | #define W83781D_REG_PWMCLK34 0x45C | 140 | #define W83781D_REG_PWMCLK34 0x45C |
138 | static const u8 regpwm[] = { W83781D_REG_PWM1, W83781D_REG_PWM2, | ||
139 | W83781D_REG_PWM3, W83781D_REG_PWM4 | ||
140 | }; | ||
141 | |||
142 | #define W83781D_REG_PWM(nr) (regpwm[(nr) - 1]) | ||
143 | 141 | ||
144 | #define W83781D_REG_I2C_ADDR 0x48 | 142 | #define W83781D_REG_I2C_ADDR 0x48 |
145 | #define W83781D_REG_I2C_SUBADDR 0x4A | 143 | #define W83781D_REG_I2C_SUBADDR 0x4A |
@@ -159,12 +157,9 @@ static const u8 BIT_SCFG2[] = { 0x10, 0x20, 0x40 }; | |||
159 | #define W83781D_REG_RT_IDX 0x50 | 157 | #define W83781D_REG_RT_IDX 0x50 |
160 | #define W83781D_REG_RT_VAL 0x51 | 158 | #define W83781D_REG_RT_VAL 0x51 |
161 | 159 | ||
162 | /* Conversions. Rounding and limit checking is only done on the TO_REG | 160 | /* Conversions */ |
163 | variants. Note that you should be a bit careful with which arguments | 161 | #define IN_TO_REG(val) SENSORS_LIMIT(((val) + 8) / 16, 0, 255) |
164 | these macros are called: arguments may be evaluated more than once. | 162 | #define IN_FROM_REG(val) ((val) * 16) |
165 | Fixing this is just not worth it. */ | ||
166 | #define IN_TO_REG(val) (SENSORS_LIMIT((((val) * 10 + 8)/16),0,255)) | ||
167 | #define IN_FROM_REG(val) (((val) * 16) / 10) | ||
168 | 163 | ||
169 | static inline u8 | 164 | static inline u8 |
170 | FAN_TO_REG(long rpm, int div) | 165 | FAN_TO_REG(long rpm, int div) |
@@ -175,24 +170,24 @@ FAN_TO_REG(long rpm, int div) | |||
175 | return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 254); | 170 | return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 254); |
176 | } | 171 | } |
177 | 172 | ||
178 | #define FAN_FROM_REG(val,div) ((val) == 0 ? -1 : \ | 173 | static inline long |
179 | ((val) == 255 ? 0 : \ | 174 | FAN_FROM_REG(u8 val, int div) |
180 | 1350000 / ((val) * (div)))) | 175 | { |
176 | if (val == 0) | ||
177 | return -1; | ||
178 | if (val == 255) | ||
179 | return 0; | ||
180 | return 1350000 / (val * div); | ||
181 | } | ||
181 | 182 | ||
182 | #define TEMP_TO_REG(val) (SENSORS_LIMIT(((val) < 0 ? (val)+0x100*1000 \ | 183 | #define TEMP_TO_REG(val) SENSORS_LIMIT((val) / 1000, -127, 128) |
183 | : (val)) / 1000, 0, 0xff)) | 184 | #define TEMP_FROM_REG(val) ((val) * 1000) |
184 | #define TEMP_FROM_REG(val) (((val) & 0x80 ? (val)-0x100 : (val)) * 1000) | ||
185 | 185 | ||
186 | #define PWM_FROM_REG(val) (val) | ||
187 | #define PWM_TO_REG(val) (SENSORS_LIMIT((val),0,255)) | ||
188 | #define BEEP_MASK_FROM_REG(val,type) ((type) == as99127f ? \ | 186 | #define BEEP_MASK_FROM_REG(val,type) ((type) == as99127f ? \ |
189 | (val) ^ 0x7fff : (val)) | 187 | (val) ^ 0x7fff : (val)) |
190 | #define BEEP_MASK_TO_REG(val,type) ((type) == as99127f ? \ | 188 | #define BEEP_MASK_TO_REG(val,type) ((type) == as99127f ? \ |
191 | (~(val)) & 0x7fff : (val) & 0xffffff) | 189 | (~(val)) & 0x7fff : (val) & 0xffffff) |
192 | 190 | ||
193 | #define BEEP_ENABLE_TO_REG(val) ((val) ? 1 : 0) | ||
194 | #define BEEP_ENABLE_FROM_REG(val) ((val) ? 1 : 0) | ||
195 | |||
196 | #define DIV_FROM_REG(val) (1 << (val)) | 191 | #define DIV_FROM_REG(val) (1 << (val)) |
197 | 192 | ||
198 | static inline u8 | 193 | static inline u8 |
@@ -207,7 +202,7 @@ DIV_TO_REG(long val, enum chips type) | |||
207 | break; | 202 | break; |
208 | val >>= 1; | 203 | val >>= 1; |
209 | } | 204 | } |
210 | return ((u8) i); | 205 | return i; |
211 | } | 206 | } |
212 | 207 | ||
213 | /* There are some complications in a module like this. First off, W83781D chips | 208 | /* There are some complications in a module like this. First off, W83781D chips |
@@ -221,8 +216,8 @@ DIV_TO_REG(long val, enum chips type) | |||
221 | a bit - except if there could be more than one SMBus. Groan. No solution | 216 | a bit - except if there could be more than one SMBus. Groan. No solution |
222 | for this yet. */ | 217 | for this yet. */ |
223 | 218 | ||
224 | /* For each registered chip, we need to keep some data in memory. | 219 | /* For ISA chips, we abuse the i2c_client addr and name fields. We also use |
225 | The structure is dynamically allocated. */ | 220 | the driver field to differentiate between I2C and ISA chips. */ |
226 | struct w83781d_data { | 221 | struct w83781d_data { |
227 | struct i2c_client client; | 222 | struct i2c_client client; |
228 | struct class_device *class_dev; | 223 | struct class_device *class_dev; |
@@ -241,9 +236,9 @@ struct w83781d_data { | |||
241 | u8 in_min[9]; /* Register value - 8 & 9 for 782D only */ | 236 | u8 in_min[9]; /* Register value - 8 & 9 for 782D only */ |
242 | u8 fan[3]; /* Register value */ | 237 | u8 fan[3]; /* Register value */ |
243 | u8 fan_min[3]; /* Register value */ | 238 | u8 fan_min[3]; /* Register value */ |
244 | u8 temp; | 239 | s8 temp; /* Register value */ |
245 | u8 temp_max; /* Register value */ | 240 | s8 temp_max; /* Register value */ |
246 | u8 temp_max_hyst; /* Register value */ | 241 | s8 temp_max_hyst; /* Register value */ |
247 | u16 temp_add[2]; /* Register value */ | 242 | u16 temp_add[2]; /* Register value */ |
248 | u16 temp_max_add[2]; /* Register value */ | 243 | u16 temp_max_add[2]; /* Register value */ |
249 | u16 temp_max_hyst_add[2]; /* Register value */ | 244 | u16 temp_max_hyst_add[2]; /* Register value */ |
@@ -253,7 +248,7 @@ struct w83781d_data { | |||
253 | u32 beep_mask; /* Register encoding, combined */ | 248 | u32 beep_mask; /* Register encoding, combined */ |
254 | u8 beep_enable; /* Boolean */ | 249 | u8 beep_enable; /* Boolean */ |
255 | u8 pwm[4]; /* Register value */ | 250 | u8 pwm[4]; /* Register value */ |
256 | u8 pwmenable[4]; /* Boolean */ | 251 | u8 pwm2_enable; /* Boolean */ |
257 | u16 sens[3]; /* 782D/783S only. | 252 | u16 sens[3]; /* 782D/783S only. |
258 | 1 = pentium diode; 2 = 3904 diode; | 253 | 1 = pentium diode; 2 = 3904 diode; |
259 | 3000-5000 = thermistor beta. | 254 | 3000-5000 = thermistor beta. |
@@ -263,14 +258,16 @@ struct w83781d_data { | |||
263 | }; | 258 | }; |
264 | 259 | ||
265 | static int w83781d_attach_adapter(struct i2c_adapter *adapter); | 260 | static int w83781d_attach_adapter(struct i2c_adapter *adapter); |
266 | static int w83781d_isa_attach_adapter(struct i2c_adapter *adapter); | ||
267 | static int w83781d_detect(struct i2c_adapter *adapter, int address, int kind); | 261 | static int w83781d_detect(struct i2c_adapter *adapter, int address, int kind); |
268 | static int w83781d_detach_client(struct i2c_client *client); | 262 | static int w83781d_detach_client(struct i2c_client *client); |
269 | 263 | ||
270 | static int w83781d_read_value(struct i2c_client *client, u16 reg); | 264 | static int __devinit w83781d_isa_probe(struct platform_device *pdev); |
271 | static int w83781d_write_value(struct i2c_client *client, u16 reg, u16 value); | 265 | static int __devexit w83781d_isa_remove(struct platform_device *pdev); |
266 | |||
267 | static int w83781d_read_value(struct w83781d_data *data, u16 reg); | ||
268 | static int w83781d_write_value(struct w83781d_data *data, u16 reg, u16 value); | ||
272 | static struct w83781d_data *w83781d_update_device(struct device *dev); | 269 | static struct w83781d_data *w83781d_update_device(struct device *dev); |
273 | static void w83781d_init_client(struct i2c_client *client); | 270 | static void w83781d_init_device(struct device *dev); |
274 | 271 | ||
275 | static struct i2c_driver w83781d_driver = { | 272 | static struct i2c_driver w83781d_driver = { |
276 | .driver = { | 273 | .driver = { |
@@ -281,39 +278,44 @@ static struct i2c_driver w83781d_driver = { | |||
281 | .detach_client = w83781d_detach_client, | 278 | .detach_client = w83781d_detach_client, |
282 | }; | 279 | }; |
283 | 280 | ||
284 | static struct i2c_driver w83781d_isa_driver = { | 281 | static struct platform_driver w83781d_isa_driver = { |
285 | .driver = { | 282 | .driver = { |
286 | .owner = THIS_MODULE, | 283 | .owner = THIS_MODULE, |
287 | .name = "w83781d-isa", | 284 | .name = "w83781d", |
288 | }, | 285 | }, |
289 | .attach_adapter = w83781d_isa_attach_adapter, | 286 | .probe = w83781d_isa_probe, |
290 | .detach_client = w83781d_detach_client, | 287 | .remove = w83781d_isa_remove, |
291 | }; | 288 | }; |
292 | 289 | ||
293 | 290 | ||
294 | /* following are the sysfs callback functions */ | 291 | /* following are the sysfs callback functions */ |
295 | #define show_in_reg(reg) \ | 292 | #define show_in_reg(reg) \ |
296 | static ssize_t show_##reg (struct device *dev, char *buf, int nr) \ | 293 | static ssize_t show_##reg (struct device *dev, struct device_attribute *da, \ |
294 | char *buf) \ | ||
297 | { \ | 295 | { \ |
296 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); \ | ||
298 | struct w83781d_data *data = w83781d_update_device(dev); \ | 297 | struct w83781d_data *data = w83781d_update_device(dev); \ |
299 | return sprintf(buf,"%ld\n", (long)IN_FROM_REG(data->reg[nr] * 10)); \ | 298 | return sprintf(buf, "%ld\n", \ |
299 | (long)IN_FROM_REG(data->reg[attr->index])); \ | ||
300 | } | 300 | } |
301 | show_in_reg(in); | 301 | show_in_reg(in); |
302 | show_in_reg(in_min); | 302 | show_in_reg(in_min); |
303 | show_in_reg(in_max); | 303 | show_in_reg(in_max); |
304 | 304 | ||
305 | #define store_in_reg(REG, reg) \ | 305 | #define store_in_reg(REG, reg) \ |
306 | static ssize_t store_in_##reg (struct device *dev, const char *buf, size_t count, int nr) \ | 306 | static ssize_t store_in_##reg (struct device *dev, struct device_attribute \ |
307 | *da, const char *buf, size_t count) \ | ||
307 | { \ | 308 | { \ |
308 | struct i2c_client *client = to_i2c_client(dev); \ | 309 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); \ |
309 | struct w83781d_data *data = i2c_get_clientdata(client); \ | 310 | struct w83781d_data *data = dev_get_drvdata(dev); \ |
311 | int nr = attr->index; \ | ||
310 | u32 val; \ | 312 | u32 val; \ |
311 | \ | 313 | \ |
312 | val = simple_strtoul(buf, NULL, 10) / 10; \ | 314 | val = simple_strtoul(buf, NULL, 10); \ |
313 | \ | 315 | \ |
314 | mutex_lock(&data->update_lock); \ | 316 | mutex_lock(&data->update_lock); \ |
315 | data->in_##reg[nr] = IN_TO_REG(val); \ | 317 | data->in_##reg[nr] = IN_TO_REG(val); \ |
316 | w83781d_write_value(client, W83781D_REG_IN_##REG(nr), data->in_##reg[nr]); \ | 318 | w83781d_write_value(data, W83781D_REG_IN_##REG(nr), data->in_##reg[nr]); \ |
317 | \ | 319 | \ |
318 | mutex_unlock(&data->update_lock); \ | 320 | mutex_unlock(&data->update_lock); \ |
319 | return count; \ | 321 | return count; \ |
@@ -321,29 +323,13 @@ static ssize_t store_in_##reg (struct device *dev, const char *buf, size_t count | |||
321 | store_in_reg(MIN, min); | 323 | store_in_reg(MIN, min); |
322 | store_in_reg(MAX, max); | 324 | store_in_reg(MAX, max); |
323 | 325 | ||
324 | #define sysfs_in_offset(offset) \ | ||
325 | static ssize_t \ | ||
326 | show_regs_in_##offset (struct device *dev, struct device_attribute *attr, char *buf) \ | ||
327 | { \ | ||
328 | return show_in(dev, buf, offset); \ | ||
329 | } \ | ||
330 | static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_regs_in_##offset, NULL); | ||
331 | |||
332 | #define sysfs_in_reg_offset(reg, offset) \ | ||
333 | static ssize_t show_regs_in_##reg##offset (struct device *dev, struct device_attribute *attr, char *buf) \ | ||
334 | { \ | ||
335 | return show_in_##reg (dev, buf, offset); \ | ||
336 | } \ | ||
337 | static ssize_t store_regs_in_##reg##offset (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \ | ||
338 | { \ | ||
339 | return store_in_##reg (dev, buf, count, offset); \ | ||
340 | } \ | ||
341 | static DEVICE_ATTR(in##offset##_##reg, S_IRUGO| S_IWUSR, show_regs_in_##reg##offset, store_regs_in_##reg##offset); | ||
342 | |||
343 | #define sysfs_in_offsets(offset) \ | 326 | #define sysfs_in_offsets(offset) \ |
344 | sysfs_in_offset(offset); \ | 327 | static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO, \ |
345 | sysfs_in_reg_offset(min, offset); \ | 328 | show_in, NULL, offset); \ |
346 | sysfs_in_reg_offset(max, offset); | 329 | static SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \ |
330 | show_in_min, store_in_min, offset); \ | ||
331 | static SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \ | ||
332 | show_in_max, store_in_max, offset) | ||
347 | 333 | ||
348 | sysfs_in_offsets(0); | 334 | sysfs_in_offsets(0); |
349 | sysfs_in_offsets(1); | 335 | sysfs_in_offsets(1); |
@@ -356,63 +342,56 @@ sysfs_in_offsets(7); | |||
356 | sysfs_in_offsets(8); | 342 | sysfs_in_offsets(8); |
357 | 343 | ||
358 | #define show_fan_reg(reg) \ | 344 | #define show_fan_reg(reg) \ |
359 | static ssize_t show_##reg (struct device *dev, char *buf, int nr) \ | 345 | static ssize_t show_##reg (struct device *dev, struct device_attribute *da, \ |
346 | char *buf) \ | ||
360 | { \ | 347 | { \ |
348 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); \ | ||
361 | struct w83781d_data *data = w83781d_update_device(dev); \ | 349 | struct w83781d_data *data = w83781d_update_device(dev); \ |
362 | return sprintf(buf,"%ld\n", \ | 350 | return sprintf(buf,"%ld\n", \ |
363 | FAN_FROM_REG(data->reg[nr-1], (long)DIV_FROM_REG(data->fan_div[nr-1]))); \ | 351 | FAN_FROM_REG(data->reg[attr->index], \ |
352 | DIV_FROM_REG(data->fan_div[attr->index]))); \ | ||
364 | } | 353 | } |
365 | show_fan_reg(fan); | 354 | show_fan_reg(fan); |
366 | show_fan_reg(fan_min); | 355 | show_fan_reg(fan_min); |
367 | 356 | ||
368 | static ssize_t | 357 | static ssize_t |
369 | store_fan_min(struct device *dev, const char *buf, size_t count, int nr) | 358 | store_fan_min(struct device *dev, struct device_attribute *da, |
359 | const char *buf, size_t count) | ||
370 | { | 360 | { |
371 | struct i2c_client *client = to_i2c_client(dev); | 361 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); |
372 | struct w83781d_data *data = i2c_get_clientdata(client); | 362 | struct w83781d_data *data = dev_get_drvdata(dev); |
363 | int nr = attr->index; | ||
373 | u32 val; | 364 | u32 val; |
374 | 365 | ||
375 | val = simple_strtoul(buf, NULL, 10); | 366 | val = simple_strtoul(buf, NULL, 10); |
376 | 367 | ||
377 | mutex_lock(&data->update_lock); | 368 | mutex_lock(&data->update_lock); |
378 | data->fan_min[nr - 1] = | 369 | data->fan_min[nr] = |
379 | FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr - 1])); | 370 | FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); |
380 | w83781d_write_value(client, W83781D_REG_FAN_MIN(nr), | 371 | w83781d_write_value(data, W83781D_REG_FAN_MIN(nr), |
381 | data->fan_min[nr - 1]); | 372 | data->fan_min[nr]); |
382 | 373 | ||
383 | mutex_unlock(&data->update_lock); | 374 | mutex_unlock(&data->update_lock); |
384 | return count; | 375 | return count; |
385 | } | 376 | } |
386 | 377 | ||
387 | #define sysfs_fan_offset(offset) \ | 378 | static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0); |
388 | static ssize_t show_regs_fan_##offset (struct device *dev, struct device_attribute *attr, char *buf) \ | 379 | static SENSOR_DEVICE_ATTR(fan1_min, S_IRUGO | S_IWUSR, |
389 | { \ | 380 | show_fan_min, store_fan_min, 0); |
390 | return show_fan(dev, buf, offset); \ | 381 | static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1); |
391 | } \ | 382 | static SENSOR_DEVICE_ATTR(fan2_min, S_IRUGO | S_IWUSR, |
392 | static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_regs_fan_##offset, NULL); | 383 | show_fan_min, store_fan_min, 1); |
393 | 384 | static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2); | |
394 | #define sysfs_fan_min_offset(offset) \ | 385 | static SENSOR_DEVICE_ATTR(fan3_min, S_IRUGO | S_IWUSR, |
395 | static ssize_t show_regs_fan_min##offset (struct device *dev, struct device_attribute *attr, char *buf) \ | 386 | show_fan_min, store_fan_min, 2); |
396 | { \ | ||
397 | return show_fan_min(dev, buf, offset); \ | ||
398 | } \ | ||
399 | static ssize_t store_regs_fan_min##offset (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \ | ||
400 | { \ | ||
401 | return store_fan_min(dev, buf, count, offset); \ | ||
402 | } \ | ||
403 | static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, show_regs_fan_min##offset, store_regs_fan_min##offset); | ||
404 | |||
405 | sysfs_fan_offset(1); | ||
406 | sysfs_fan_min_offset(1); | ||
407 | sysfs_fan_offset(2); | ||
408 | sysfs_fan_min_offset(2); | ||
409 | sysfs_fan_offset(3); | ||
410 | sysfs_fan_min_offset(3); | ||
411 | 387 | ||
412 | #define show_temp_reg(reg) \ | 388 | #define show_temp_reg(reg) \ |
413 | static ssize_t show_##reg (struct device *dev, char *buf, int nr) \ | 389 | static ssize_t show_##reg (struct device *dev, struct device_attribute *da, \ |
390 | char *buf) \ | ||
414 | { \ | 391 | { \ |
392 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); \ | ||
415 | struct w83781d_data *data = w83781d_update_device(dev); \ | 393 | struct w83781d_data *data = w83781d_update_device(dev); \ |
394 | int nr = attr->index; \ | ||
416 | if (nr >= 2) { /* TEMP2 and TEMP3 */ \ | 395 | if (nr >= 2) { /* TEMP2 and TEMP3 */ \ |
417 | return sprintf(buf,"%d\n", \ | 396 | return sprintf(buf,"%d\n", \ |
418 | LM75_TEMP_FROM_REG(data->reg##_add[nr-2])); \ | 397 | LM75_TEMP_FROM_REG(data->reg##_add[nr-2])); \ |
@@ -425,10 +404,12 @@ show_temp_reg(temp_max); | |||
425 | show_temp_reg(temp_max_hyst); | 404 | show_temp_reg(temp_max_hyst); |
426 | 405 | ||
427 | #define store_temp_reg(REG, reg) \ | 406 | #define store_temp_reg(REG, reg) \ |
428 | static ssize_t store_temp_##reg (struct device *dev, const char *buf, size_t count, int nr) \ | 407 | static ssize_t store_temp_##reg (struct device *dev, \ |
408 | struct device_attribute *da, const char *buf, size_t count) \ | ||
429 | { \ | 409 | { \ |
430 | struct i2c_client *client = to_i2c_client(dev); \ | 410 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); \ |
431 | struct w83781d_data *data = i2c_get_clientdata(client); \ | 411 | struct w83781d_data *data = dev_get_drvdata(dev); \ |
412 | int nr = attr->index; \ | ||
432 | s32 val; \ | 413 | s32 val; \ |
433 | \ | 414 | \ |
434 | val = simple_strtol(buf, NULL, 10); \ | 415 | val = simple_strtol(buf, NULL, 10); \ |
@@ -437,11 +418,11 @@ static ssize_t store_temp_##reg (struct device *dev, const char *buf, size_t cou | |||
437 | \ | 418 | \ |
438 | if (nr >= 2) { /* TEMP2 and TEMP3 */ \ | 419 | if (nr >= 2) { /* TEMP2 and TEMP3 */ \ |
439 | data->temp_##reg##_add[nr-2] = LM75_TEMP_TO_REG(val); \ | 420 | data->temp_##reg##_add[nr-2] = LM75_TEMP_TO_REG(val); \ |
440 | w83781d_write_value(client, W83781D_REG_TEMP_##REG(nr), \ | 421 | w83781d_write_value(data, W83781D_REG_TEMP_##REG(nr), \ |
441 | data->temp_##reg##_add[nr-2]); \ | 422 | data->temp_##reg##_add[nr-2]); \ |
442 | } else { /* TEMP1 */ \ | 423 | } else { /* TEMP1 */ \ |
443 | data->temp_##reg = TEMP_TO_REG(val); \ | 424 | data->temp_##reg = TEMP_TO_REG(val); \ |
444 | w83781d_write_value(client, W83781D_REG_TEMP_##REG(nr), \ | 425 | w83781d_write_value(data, W83781D_REG_TEMP_##REG(nr), \ |
445 | data->temp_##reg); \ | 426 | data->temp_##reg); \ |
446 | } \ | 427 | } \ |
447 | \ | 428 | \ |
@@ -451,29 +432,13 @@ static ssize_t store_temp_##reg (struct device *dev, const char *buf, size_t cou | |||
451 | store_temp_reg(OVER, max); | 432 | store_temp_reg(OVER, max); |
452 | store_temp_reg(HYST, max_hyst); | 433 | store_temp_reg(HYST, max_hyst); |
453 | 434 | ||
454 | #define sysfs_temp_offset(offset) \ | ||
455 | static ssize_t \ | ||
456 | show_regs_temp_##offset (struct device *dev, struct device_attribute *attr, char *buf) \ | ||
457 | { \ | ||
458 | return show_temp(dev, buf, offset); \ | ||
459 | } \ | ||
460 | static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_regs_temp_##offset, NULL); | ||
461 | |||
462 | #define sysfs_temp_reg_offset(reg, offset) \ | ||
463 | static ssize_t show_regs_temp_##reg##offset (struct device *dev, struct device_attribute *attr, char *buf) \ | ||
464 | { \ | ||
465 | return show_temp_##reg (dev, buf, offset); \ | ||
466 | } \ | ||
467 | static ssize_t store_regs_temp_##reg##offset (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \ | ||
468 | { \ | ||
469 | return store_temp_##reg (dev, buf, count, offset); \ | ||
470 | } \ | ||
471 | static DEVICE_ATTR(temp##offset##_##reg, S_IRUGO| S_IWUSR, show_regs_temp_##reg##offset, store_regs_temp_##reg##offset); | ||
472 | |||
473 | #define sysfs_temp_offsets(offset) \ | 435 | #define sysfs_temp_offsets(offset) \ |
474 | sysfs_temp_offset(offset); \ | 436 | static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, \ |
475 | sysfs_temp_reg_offset(max, offset); \ | 437 | show_temp, NULL, offset); \ |
476 | sysfs_temp_reg_offset(max_hyst, offset); | 438 | static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \ |
439 | show_temp_max, store_temp_max, offset); \ | ||
440 | static SENSOR_DEVICE_ATTR(temp##offset##_max_hyst, S_IRUGO | S_IWUSR, \ | ||
441 | show_temp_max_hyst, store_temp_max_hyst, offset); | ||
477 | 442 | ||
478 | sysfs_temp_offsets(1); | 443 | sysfs_temp_offsets(1); |
479 | sysfs_temp_offsets(2); | 444 | sysfs_temp_offsets(2); |
@@ -498,8 +463,7 @@ show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf) | |||
498 | static ssize_t | 463 | static ssize_t |
499 | store_vrm_reg(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | 464 | store_vrm_reg(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
500 | { | 465 | { |
501 | struct i2c_client *client = to_i2c_client(dev); | 466 | struct w83781d_data *data = dev_get_drvdata(dev); |
502 | struct w83781d_data *data = i2c_get_clientdata(client); | ||
503 | u32 val; | 467 | u32 val; |
504 | 468 | ||
505 | val = simple_strtoul(buf, NULL, 10); | 469 | val = simple_strtoul(buf, NULL, 10); |
@@ -528,68 +492,67 @@ static ssize_t show_beep_mask (struct device *dev, struct device_attribute *attr | |||
528 | static ssize_t show_beep_enable (struct device *dev, struct device_attribute *attr, char *buf) | 492 | static ssize_t show_beep_enable (struct device *dev, struct device_attribute *attr, char *buf) |
529 | { | 493 | { |
530 | struct w83781d_data *data = w83781d_update_device(dev); | 494 | struct w83781d_data *data = w83781d_update_device(dev); |
531 | return sprintf(buf, "%ld\n", | 495 | return sprintf(buf, "%ld\n", (long)data->beep_enable); |
532 | (long)BEEP_ENABLE_FROM_REG(data->beep_enable)); | ||
533 | } | 496 | } |
534 | 497 | ||
535 | #define BEEP_ENABLE 0 /* Store beep_enable */ | ||
536 | #define BEEP_MASK 1 /* Store beep_mask */ | ||
537 | |||
538 | static ssize_t | 498 | static ssize_t |
539 | store_beep_reg(struct device *dev, const char *buf, size_t count, | 499 | store_beep_mask(struct device *dev, struct device_attribute *attr, |
540 | int update_mask) | 500 | const char *buf, size_t count) |
541 | { | 501 | { |
542 | struct i2c_client *client = to_i2c_client(dev); | 502 | struct w83781d_data *data = dev_get_drvdata(dev); |
543 | struct w83781d_data *data = i2c_get_clientdata(client); | 503 | u32 val; |
544 | u32 val, val2; | ||
545 | 504 | ||
546 | val = simple_strtoul(buf, NULL, 10); | 505 | val = simple_strtoul(buf, NULL, 10); |
547 | 506 | ||
548 | mutex_lock(&data->update_lock); | 507 | mutex_lock(&data->update_lock); |
508 | data->beep_mask = BEEP_MASK_TO_REG(val, data->type); | ||
509 | w83781d_write_value(data, W83781D_REG_BEEP_INTS1, | ||
510 | data->beep_mask & 0xff); | ||
511 | w83781d_write_value(data, W83781D_REG_BEEP_INTS2, | ||
512 | ((data->beep_mask >> 8) & 0x7f) | ||
513 | | data->beep_enable << 7); | ||
514 | if (data->type != w83781d && data->type != as99127f) { | ||
515 | w83781d_write_value(data, W83781D_REG_BEEP_INTS3, | ||
516 | ((data->beep_mask) >> 16) & 0xff); | ||
517 | } | ||
518 | mutex_unlock(&data->update_lock); | ||
549 | 519 | ||
550 | if (update_mask == BEEP_MASK) { /* We are storing beep_mask */ | 520 | return count; |
551 | data->beep_mask = BEEP_MASK_TO_REG(val, data->type); | 521 | } |
552 | w83781d_write_value(client, W83781D_REG_BEEP_INTS1, | ||
553 | data->beep_mask & 0xff); | ||
554 | |||
555 | if ((data->type != w83781d) && (data->type != as99127f)) { | ||
556 | w83781d_write_value(client, W83781D_REG_BEEP_INTS3, | ||
557 | ((data->beep_mask) >> 16) & 0xff); | ||
558 | } | ||
559 | 522 | ||
560 | val2 = (data->beep_mask >> 8) & 0x7f; | 523 | static ssize_t |
561 | } else { /* We are storing beep_enable */ | 524 | store_beep_enable(struct device *dev, struct device_attribute *attr, |
562 | val2 = w83781d_read_value(client, W83781D_REG_BEEP_INTS2) & 0x7f; | 525 | const char *buf, size_t count) |
563 | data->beep_enable = BEEP_ENABLE_TO_REG(val); | 526 | { |
564 | } | 527 | struct w83781d_data *data = dev_get_drvdata(dev); |
528 | u32 val; | ||
565 | 529 | ||
566 | w83781d_write_value(client, W83781D_REG_BEEP_INTS2, | 530 | val = simple_strtoul(buf, NULL, 10); |
567 | val2 | data->beep_enable << 7); | 531 | if (val != 0 && val != 1) |
532 | return -EINVAL; | ||
568 | 533 | ||
534 | mutex_lock(&data->update_lock); | ||
535 | data->beep_enable = val; | ||
536 | val = w83781d_read_value(data, W83781D_REG_BEEP_INTS2) & 0x7f; | ||
537 | val |= data->beep_enable << 7; | ||
538 | w83781d_write_value(data, W83781D_REG_BEEP_INTS2, val); | ||
569 | mutex_unlock(&data->update_lock); | 539 | mutex_unlock(&data->update_lock); |
540 | |||
570 | return count; | 541 | return count; |
571 | } | 542 | } |
572 | 543 | ||
573 | #define sysfs_beep(REG, reg) \ | 544 | static DEVICE_ATTR(beep_mask, S_IRUGO | S_IWUSR, |
574 | static ssize_t show_regs_beep_##reg (struct device *dev, struct device_attribute *attr, char *buf) \ | 545 | show_beep_mask, store_beep_mask); |
575 | { \ | 546 | static DEVICE_ATTR(beep_enable, S_IRUGO | S_IWUSR, |
576 | return show_beep_##reg(dev, attr, buf); \ | 547 | show_beep_enable, store_beep_enable); |
577 | } \ | ||
578 | static ssize_t store_regs_beep_##reg (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \ | ||
579 | { \ | ||
580 | return store_beep_reg(dev, buf, count, BEEP_##REG); \ | ||
581 | } \ | ||
582 | static DEVICE_ATTR(beep_##reg, S_IRUGO | S_IWUSR, show_regs_beep_##reg, store_regs_beep_##reg); | ||
583 | |||
584 | sysfs_beep(ENABLE, enable); | ||
585 | sysfs_beep(MASK, mask); | ||
586 | 548 | ||
587 | static ssize_t | 549 | static ssize_t |
588 | show_fan_div_reg(struct device *dev, char *buf, int nr) | 550 | show_fan_div(struct device *dev, struct device_attribute *da, char *buf) |
589 | { | 551 | { |
552 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | ||
590 | struct w83781d_data *data = w83781d_update_device(dev); | 553 | struct w83781d_data *data = w83781d_update_device(dev); |
591 | return sprintf(buf, "%ld\n", | 554 | return sprintf(buf, "%ld\n", |
592 | (long) DIV_FROM_REG(data->fan_div[nr - 1])); | 555 | (long) DIV_FROM_REG(data->fan_div[attr->index])); |
593 | } | 556 | } |
594 | 557 | ||
595 | /* Note: we save and restore the fan minimum here, because its value is | 558 | /* Note: we save and restore the fan minimum here, because its value is |
@@ -597,11 +560,13 @@ show_fan_div_reg(struct device *dev, char *buf, int nr) | |||
597 | least surprise; the user doesn't expect the fan minimum to change just | 560 | least surprise; the user doesn't expect the fan minimum to change just |
598 | because the divisor changed. */ | 561 | because the divisor changed. */ |
599 | static ssize_t | 562 | static ssize_t |
600 | store_fan_div_reg(struct device *dev, const char *buf, size_t count, int nr) | 563 | store_fan_div(struct device *dev, struct device_attribute *da, |
564 | const char *buf, size_t count) | ||
601 | { | 565 | { |
602 | struct i2c_client *client = to_i2c_client(dev); | 566 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); |
603 | struct w83781d_data *data = i2c_get_clientdata(client); | 567 | struct w83781d_data *data = dev_get_drvdata(dev); |
604 | unsigned long min; | 568 | unsigned long min; |
569 | int nr = attr->index; | ||
605 | u8 reg; | 570 | u8 reg; |
606 | unsigned long val = simple_strtoul(buf, NULL, 10); | 571 | unsigned long val = simple_strtoul(buf, NULL, 10); |
607 | 572 | ||
@@ -613,77 +578,72 @@ store_fan_div_reg(struct device *dev, const char *buf, size_t count, int nr) | |||
613 | 578 | ||
614 | data->fan_div[nr] = DIV_TO_REG(val, data->type); | 579 | data->fan_div[nr] = DIV_TO_REG(val, data->type); |
615 | 580 | ||
616 | reg = (w83781d_read_value(client, nr==2 ? W83781D_REG_PIN : W83781D_REG_VID_FANDIV) | 581 | reg = (w83781d_read_value(data, nr==2 ? W83781D_REG_PIN : W83781D_REG_VID_FANDIV) |
617 | & (nr==0 ? 0xcf : 0x3f)) | 582 | & (nr==0 ? 0xcf : 0x3f)) |
618 | | ((data->fan_div[nr] & 0x03) << (nr==0 ? 4 : 6)); | 583 | | ((data->fan_div[nr] & 0x03) << (nr==0 ? 4 : 6)); |
619 | w83781d_write_value(client, nr==2 ? W83781D_REG_PIN : W83781D_REG_VID_FANDIV, reg); | 584 | w83781d_write_value(data, nr==2 ? W83781D_REG_PIN : W83781D_REG_VID_FANDIV, reg); |
620 | 585 | ||
621 | /* w83781d and as99127f don't have extended divisor bits */ | 586 | /* w83781d and as99127f don't have extended divisor bits */ |
622 | if (data->type != w83781d && data->type != as99127f) { | 587 | if (data->type != w83781d && data->type != as99127f) { |
623 | reg = (w83781d_read_value(client, W83781D_REG_VBAT) | 588 | reg = (w83781d_read_value(data, W83781D_REG_VBAT) |
624 | & ~(1 << (5 + nr))) | 589 | & ~(1 << (5 + nr))) |
625 | | ((data->fan_div[nr] & 0x04) << (3 + nr)); | 590 | | ((data->fan_div[nr] & 0x04) << (3 + nr)); |
626 | w83781d_write_value(client, W83781D_REG_VBAT, reg); | 591 | w83781d_write_value(data, W83781D_REG_VBAT, reg); |
627 | } | 592 | } |
628 | 593 | ||
629 | /* Restore fan_min */ | 594 | /* Restore fan_min */ |
630 | data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); | 595 | data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); |
631 | w83781d_write_value(client, W83781D_REG_FAN_MIN(nr+1), data->fan_min[nr]); | 596 | w83781d_write_value(data, W83781D_REG_FAN_MIN(nr), data->fan_min[nr]); |
632 | 597 | ||
633 | mutex_unlock(&data->update_lock); | 598 | mutex_unlock(&data->update_lock); |
634 | return count; | 599 | return count; |
635 | } | 600 | } |
636 | 601 | ||
637 | #define sysfs_fan_div(offset) \ | 602 | static SENSOR_DEVICE_ATTR(fan1_div, S_IRUGO | S_IWUSR, |
638 | static ssize_t show_regs_fan_div_##offset (struct device *dev, struct device_attribute *attr, char *buf) \ | 603 | show_fan_div, store_fan_div, 0); |
639 | { \ | 604 | static SENSOR_DEVICE_ATTR(fan2_div, S_IRUGO | S_IWUSR, |
640 | return show_fan_div_reg(dev, buf, offset); \ | 605 | show_fan_div, store_fan_div, 1); |
641 | } \ | 606 | static SENSOR_DEVICE_ATTR(fan3_div, S_IRUGO | S_IWUSR, |
642 | static ssize_t store_regs_fan_div_##offset (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \ | 607 | show_fan_div, store_fan_div, 2); |
643 | { \ | ||
644 | return store_fan_div_reg(dev, buf, count, offset - 1); \ | ||
645 | } \ | ||
646 | static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, show_regs_fan_div_##offset, store_regs_fan_div_##offset); | ||
647 | |||
648 | sysfs_fan_div(1); | ||
649 | sysfs_fan_div(2); | ||
650 | sysfs_fan_div(3); | ||
651 | 608 | ||
652 | static ssize_t | 609 | static ssize_t |
653 | show_pwm_reg(struct device *dev, char *buf, int nr) | 610 | show_pwm(struct device *dev, struct device_attribute *da, char *buf) |
654 | { | 611 | { |
612 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | ||
655 | struct w83781d_data *data = w83781d_update_device(dev); | 613 | struct w83781d_data *data = w83781d_update_device(dev); |
656 | return sprintf(buf, "%ld\n", (long) PWM_FROM_REG(data->pwm[nr - 1])); | 614 | return sprintf(buf, "%d\n", (int)data->pwm[attr->index]); |
657 | } | 615 | } |
658 | 616 | ||
659 | static ssize_t | 617 | static ssize_t |
660 | show_pwmenable_reg(struct device *dev, char *buf, int nr) | 618 | show_pwm2_enable(struct device *dev, struct device_attribute *da, char *buf) |
661 | { | 619 | { |
662 | struct w83781d_data *data = w83781d_update_device(dev); | 620 | struct w83781d_data *data = w83781d_update_device(dev); |
663 | return sprintf(buf, "%ld\n", (long) data->pwmenable[nr - 1]); | 621 | return sprintf(buf, "%d\n", (int)data->pwm2_enable); |
664 | } | 622 | } |
665 | 623 | ||
666 | static ssize_t | 624 | static ssize_t |
667 | store_pwm_reg(struct device *dev, const char *buf, size_t count, int nr) | 625 | store_pwm(struct device *dev, struct device_attribute *da, const char *buf, |
626 | size_t count) | ||
668 | { | 627 | { |
669 | struct i2c_client *client = to_i2c_client(dev); | 628 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); |
670 | struct w83781d_data *data = i2c_get_clientdata(client); | 629 | struct w83781d_data *data = dev_get_drvdata(dev); |
630 | int nr = attr->index; | ||
671 | u32 val; | 631 | u32 val; |
672 | 632 | ||
673 | val = simple_strtoul(buf, NULL, 10); | 633 | val = simple_strtoul(buf, NULL, 10); |
674 | 634 | ||
675 | mutex_lock(&data->update_lock); | 635 | mutex_lock(&data->update_lock); |
676 | data->pwm[nr - 1] = PWM_TO_REG(val); | 636 | data->pwm[nr] = SENSORS_LIMIT(val, 0, 255); |
677 | w83781d_write_value(client, W83781D_REG_PWM(nr), data->pwm[nr - 1]); | 637 | w83781d_write_value(data, W83781D_REG_PWM[nr], data->pwm[nr]); |
678 | mutex_unlock(&data->update_lock); | 638 | mutex_unlock(&data->update_lock); |
679 | return count; | 639 | return count; |
680 | } | 640 | } |
681 | 641 | ||
682 | static ssize_t | 642 | static ssize_t |
683 | store_pwmenable_reg(struct device *dev, const char *buf, size_t count, int nr) | 643 | store_pwm2_enable(struct device *dev, struct device_attribute *da, |
644 | const char *buf, size_t count) | ||
684 | { | 645 | { |
685 | struct i2c_client *client = to_i2c_client(dev); | 646 | struct w83781d_data *data = dev_get_drvdata(dev); |
686 | struct w83781d_data *data = i2c_get_clientdata(client); | ||
687 | u32 val, reg; | 647 | u32 val, reg; |
688 | 648 | ||
689 | val = simple_strtoul(buf, NULL, 10); | 649 | val = simple_strtoul(buf, NULL, 10); |
@@ -693,15 +653,15 @@ store_pwmenable_reg(struct device *dev, const char *buf, size_t count, int nr) | |||
693 | switch (val) { | 653 | switch (val) { |
694 | case 0: | 654 | case 0: |
695 | case 1: | 655 | case 1: |
696 | reg = w83781d_read_value(client, W83781D_REG_PWMCLK12); | 656 | reg = w83781d_read_value(data, W83781D_REG_PWMCLK12); |
697 | w83781d_write_value(client, W83781D_REG_PWMCLK12, | 657 | w83781d_write_value(data, W83781D_REG_PWMCLK12, |
698 | (reg & 0xf7) | (val << 3)); | 658 | (reg & 0xf7) | (val << 3)); |
699 | 659 | ||
700 | reg = w83781d_read_value(client, W83781D_REG_BEEP_CONFIG); | 660 | reg = w83781d_read_value(data, W83781D_REG_BEEP_CONFIG); |
701 | w83781d_write_value(client, W83781D_REG_BEEP_CONFIG, | 661 | w83781d_write_value(data, W83781D_REG_BEEP_CONFIG, |
702 | (reg & 0xef) | (!val << 4)); | 662 | (reg & 0xef) | (!val << 4)); |
703 | 663 | ||
704 | data->pwmenable[nr - 1] = val; | 664 | data->pwm2_enable = val; |
705 | break; | 665 | break; |
706 | 666 | ||
707 | default: | 667 | default: |
@@ -713,50 +673,29 @@ store_pwmenable_reg(struct device *dev, const char *buf, size_t count, int nr) | |||
713 | return count; | 673 | return count; |
714 | } | 674 | } |
715 | 675 | ||
716 | #define sysfs_pwm(offset) \ | 676 | static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_pwm, store_pwm, 0); |
717 | static ssize_t show_regs_pwm_##offset (struct device *dev, struct device_attribute *attr, char *buf) \ | 677 | static SENSOR_DEVICE_ATTR(pwm2, S_IRUGO | S_IWUSR, show_pwm, store_pwm, 1); |
718 | { \ | 678 | static SENSOR_DEVICE_ATTR(pwm3, S_IRUGO | S_IWUSR, show_pwm, store_pwm, 2); |
719 | return show_pwm_reg(dev, buf, offset); \ | 679 | static SENSOR_DEVICE_ATTR(pwm4, S_IRUGO | S_IWUSR, show_pwm, store_pwm, 3); |
720 | } \ | 680 | /* only PWM2 can be enabled/disabled */ |
721 | static ssize_t store_regs_pwm_##offset (struct device *dev, struct device_attribute *attr, \ | 681 | static DEVICE_ATTR(pwm2_enable, S_IRUGO | S_IWUSR, |
722 | const char *buf, size_t count) \ | 682 | show_pwm2_enable, store_pwm2_enable); |
723 | { \ | ||
724 | return store_pwm_reg(dev, buf, count, offset); \ | ||
725 | } \ | ||
726 | static DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \ | ||
727 | show_regs_pwm_##offset, store_regs_pwm_##offset); | ||
728 | |||
729 | #define sysfs_pwmenable(offset) \ | ||
730 | static ssize_t show_regs_pwmenable_##offset (struct device *dev, struct device_attribute *attr, char *buf) \ | ||
731 | { \ | ||
732 | return show_pwmenable_reg(dev, buf, offset); \ | ||
733 | } \ | ||
734 | static ssize_t store_regs_pwmenable_##offset (struct device *dev, struct device_attribute *attr, \ | ||
735 | const char *buf, size_t count) \ | ||
736 | { \ | ||
737 | return store_pwmenable_reg(dev, buf, count, offset); \ | ||
738 | } \ | ||
739 | static DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR, \ | ||
740 | show_regs_pwmenable_##offset, store_regs_pwmenable_##offset); | ||
741 | |||
742 | sysfs_pwm(1); | ||
743 | sysfs_pwm(2); | ||
744 | sysfs_pwmenable(2); /* only PWM2 can be enabled/disabled */ | ||
745 | sysfs_pwm(3); | ||
746 | sysfs_pwm(4); | ||
747 | 683 | ||
748 | static ssize_t | 684 | static ssize_t |
749 | show_sensor_reg(struct device *dev, char *buf, int nr) | 685 | show_sensor(struct device *dev, struct device_attribute *da, char *buf) |
750 | { | 686 | { |
687 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | ||
751 | struct w83781d_data *data = w83781d_update_device(dev); | 688 | struct w83781d_data *data = w83781d_update_device(dev); |
752 | return sprintf(buf, "%ld\n", (long) data->sens[nr - 1]); | 689 | return sprintf(buf, "%d\n", (int)data->sens[attr->index]); |
753 | } | 690 | } |
754 | 691 | ||
755 | static ssize_t | 692 | static ssize_t |
756 | store_sensor_reg(struct device *dev, const char *buf, size_t count, int nr) | 693 | store_sensor(struct device *dev, struct device_attribute *da, |
694 | const char *buf, size_t count) | ||
757 | { | 695 | { |
758 | struct i2c_client *client = to_i2c_client(dev); | 696 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); |
759 | struct w83781d_data *data = i2c_get_clientdata(client); | 697 | struct w83781d_data *data = dev_get_drvdata(dev); |
698 | int nr = attr->index; | ||
760 | u32 val, tmp; | 699 | u32 val, tmp; |
761 | 700 | ||
762 | val = simple_strtoul(buf, NULL, 10); | 701 | val = simple_strtoul(buf, NULL, 10); |
@@ -765,28 +704,28 @@ store_sensor_reg(struct device *dev, const char *buf, size_t count, int nr) | |||
765 | 704 | ||
766 | switch (val) { | 705 | switch (val) { |
767 | case 1: /* PII/Celeron diode */ | 706 | case 1: /* PII/Celeron diode */ |
768 | tmp = w83781d_read_value(client, W83781D_REG_SCFG1); | 707 | tmp = w83781d_read_value(data, W83781D_REG_SCFG1); |
769 | w83781d_write_value(client, W83781D_REG_SCFG1, | 708 | w83781d_write_value(data, W83781D_REG_SCFG1, |
770 | tmp | BIT_SCFG1[nr - 1]); | 709 | tmp | BIT_SCFG1[nr]); |
771 | tmp = w83781d_read_value(client, W83781D_REG_SCFG2); | 710 | tmp = w83781d_read_value(data, W83781D_REG_SCFG2); |
772 | w83781d_write_value(client, W83781D_REG_SCFG2, | 711 | w83781d_write_value(data, W83781D_REG_SCFG2, |
773 | tmp | BIT_SCFG2[nr - 1]); | 712 | tmp | BIT_SCFG2[nr]); |
774 | data->sens[nr - 1] = val; | 713 | data->sens[nr] = val; |
775 | break; | 714 | break; |
776 | case 2: /* 3904 */ | 715 | case 2: /* 3904 */ |
777 | tmp = w83781d_read_value(client, W83781D_REG_SCFG1); | 716 | tmp = w83781d_read_value(data, W83781D_REG_SCFG1); |
778 | w83781d_write_value(client, W83781D_REG_SCFG1, | 717 | w83781d_write_value(data, W83781D_REG_SCFG1, |
779 | tmp | BIT_SCFG1[nr - 1]); | 718 | tmp | BIT_SCFG1[nr]); |
780 | tmp = w83781d_read_value(client, W83781D_REG_SCFG2); | 719 | tmp = w83781d_read_value(data, W83781D_REG_SCFG2); |
781 | w83781d_write_value(client, W83781D_REG_SCFG2, | 720 | w83781d_write_value(data, W83781D_REG_SCFG2, |
782 | tmp & ~BIT_SCFG2[nr - 1]); | 721 | tmp & ~BIT_SCFG2[nr]); |
783 | data->sens[nr - 1] = val; | 722 | data->sens[nr] = val; |
784 | break; | 723 | break; |
785 | case W83781D_DEFAULT_BETA: /* thermistor */ | 724 | case W83781D_DEFAULT_BETA: /* thermistor */ |
786 | tmp = w83781d_read_value(client, W83781D_REG_SCFG1); | 725 | tmp = w83781d_read_value(data, W83781D_REG_SCFG1); |
787 | w83781d_write_value(client, W83781D_REG_SCFG1, | 726 | w83781d_write_value(data, W83781D_REG_SCFG1, |
788 | tmp & ~BIT_SCFG1[nr - 1]); | 727 | tmp & ~BIT_SCFG1[nr]); |
789 | data->sens[nr - 1] = val; | 728 | data->sens[nr] = val; |
790 | break; | 729 | break; |
791 | default: | 730 | default: |
792 | dev_err(dev, "Invalid sensor type %ld; must be 1, 2, or %d\n", | 731 | dev_err(dev, "Invalid sensor type %ld; must be 1, 2, or %d\n", |
@@ -798,20 +737,22 @@ store_sensor_reg(struct device *dev, const char *buf, size_t count, int nr) | |||
798 | return count; | 737 | return count; |
799 | } | 738 | } |
800 | 739 | ||
801 | #define sysfs_sensor(offset) \ | 740 | static SENSOR_DEVICE_ATTR(temp1_type, S_IRUGO | S_IWUSR, |
802 | static ssize_t show_regs_sensor_##offset (struct device *dev, struct device_attribute *attr, char *buf) \ | 741 | show_sensor, store_sensor, 0); |
803 | { \ | 742 | static SENSOR_DEVICE_ATTR(temp2_type, S_IRUGO | S_IWUSR, |
804 | return show_sensor_reg(dev, buf, offset); \ | 743 | show_sensor, store_sensor, 0); |
805 | } \ | 744 | static SENSOR_DEVICE_ATTR(temp3_type, S_IRUGO | S_IWUSR, |
806 | static ssize_t store_regs_sensor_##offset (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \ | 745 | show_sensor, store_sensor, 0); |
807 | { \ | ||
808 | return store_sensor_reg(dev, buf, count, offset); \ | ||
809 | } \ | ||
810 | static DEVICE_ATTR(temp##offset##_type, S_IRUGO | S_IWUSR, show_regs_sensor_##offset, store_regs_sensor_##offset); | ||
811 | 746 | ||
812 | sysfs_sensor(1); | 747 | /* I2C devices get this name attribute automatically, but for ISA devices |
813 | sysfs_sensor(2); | 748 | we must create it by ourselves. */ |
814 | sysfs_sensor(3); | 749 | static ssize_t |
750 | show_name(struct device *dev, struct device_attribute *devattr, char *buf) | ||
751 | { | ||
752 | struct w83781d_data *data = dev_get_drvdata(dev); | ||
753 | return sprintf(buf, "%s\n", data->client.name); | ||
754 | } | ||
755 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); | ||
815 | 756 | ||
816 | /* This function is called when: | 757 | /* This function is called when: |
817 | * w83781d_driver is inserted (when this module is loaded), for each | 758 | * w83781d_driver is inserted (when this module is loaded), for each |
@@ -825,12 +766,6 @@ w83781d_attach_adapter(struct i2c_adapter *adapter) | |||
825 | return i2c_probe(adapter, &addr_data, w83781d_detect); | 766 | return i2c_probe(adapter, &addr_data, w83781d_detect); |
826 | } | 767 | } |
827 | 768 | ||
828 | static int | ||
829 | w83781d_isa_attach_adapter(struct i2c_adapter *adapter) | ||
830 | { | ||
831 | return w83781d_detect(adapter, isa_address, -1); | ||
832 | } | ||
833 | |||
834 | /* Assumes that adapter is of I2C, not ISA variety. | 769 | /* Assumes that adapter is of I2C, not ISA variety. |
835 | * OTHERWISE DON'T CALL THIS | 770 | * OTHERWISE DON'T CALL THIS |
836 | */ | 771 | */ |
@@ -862,12 +797,12 @@ w83781d_detect_subclients(struct i2c_adapter *adapter, int address, int kind, | |||
862 | goto ERROR_SC_1; | 797 | goto ERROR_SC_1; |
863 | } | 798 | } |
864 | } | 799 | } |
865 | w83781d_write_value(new_client, W83781D_REG_I2C_SUBADDR, | 800 | w83781d_write_value(data, W83781D_REG_I2C_SUBADDR, |
866 | (force_subclients[2] & 0x07) | | 801 | (force_subclients[2] & 0x07) | |
867 | ((force_subclients[3] & 0x07) << 4)); | 802 | ((force_subclients[3] & 0x07) << 4)); |
868 | data->lm75[0]->addr = force_subclients[2]; | 803 | data->lm75[0]->addr = force_subclients[2]; |
869 | } else { | 804 | } else { |
870 | val1 = w83781d_read_value(new_client, W83781D_REG_I2C_SUBADDR); | 805 | val1 = w83781d_read_value(data, W83781D_REG_I2C_SUBADDR); |
871 | data->lm75[0]->addr = 0x48 + (val1 & 0x07); | 806 | data->lm75[0]->addr = 0x48 + (val1 & 0x07); |
872 | } | 807 | } |
873 | 808 | ||
@@ -937,20 +872,20 @@ ERROR_SC_0: | |||
937 | return err; | 872 | return err; |
938 | } | 873 | } |
939 | 874 | ||
940 | #define IN_UNIT_ATTRS(X) \ | 875 | #define IN_UNIT_ATTRS(X) \ |
941 | &dev_attr_in##X##_input.attr, \ | 876 | &sensor_dev_attr_in##X##_input.dev_attr.attr, \ |
942 | &dev_attr_in##X##_min.attr, \ | 877 | &sensor_dev_attr_in##X##_min.dev_attr.attr, \ |
943 | &dev_attr_in##X##_max.attr | 878 | &sensor_dev_attr_in##X##_max.dev_attr.attr |
944 | 879 | ||
945 | #define FAN_UNIT_ATTRS(X) \ | 880 | #define FAN_UNIT_ATTRS(X) \ |
946 | &dev_attr_fan##X##_input.attr, \ | 881 | &sensor_dev_attr_fan##X##_input.dev_attr.attr, \ |
947 | &dev_attr_fan##X##_min.attr, \ | 882 | &sensor_dev_attr_fan##X##_min.dev_attr.attr, \ |
948 | &dev_attr_fan##X##_div.attr | 883 | &sensor_dev_attr_fan##X##_div.dev_attr.attr |
949 | 884 | ||
950 | #define TEMP_UNIT_ATTRS(X) \ | 885 | #define TEMP_UNIT_ATTRS(X) \ |
951 | &dev_attr_temp##X##_input.attr, \ | 886 | &sensor_dev_attr_temp##X##_input.dev_attr.attr, \ |
952 | &dev_attr_temp##X##_max.attr, \ | 887 | &sensor_dev_attr_temp##X##_max.dev_attr.attr, \ |
953 | &dev_attr_temp##X##_max_hyst.attr | 888 | &sensor_dev_attr_temp##X##_max_hyst.dev_attr.attr |
954 | 889 | ||
955 | static struct attribute* w83781d_attributes[] = { | 890 | static struct attribute* w83781d_attributes[] = { |
956 | IN_UNIT_ATTRS(0), | 891 | IN_UNIT_ATTRS(0), |
@@ -980,91 +915,115 @@ static struct attribute *w83781d_attributes_opt[] = { | |||
980 | IN_UNIT_ATTRS(7), | 915 | IN_UNIT_ATTRS(7), |
981 | IN_UNIT_ATTRS(8), | 916 | IN_UNIT_ATTRS(8), |
982 | TEMP_UNIT_ATTRS(3), | 917 | TEMP_UNIT_ATTRS(3), |
983 | &dev_attr_pwm1.attr, | 918 | &sensor_dev_attr_pwm1.dev_attr.attr, |
984 | &dev_attr_pwm2.attr, | 919 | &sensor_dev_attr_pwm2.dev_attr.attr, |
920 | &sensor_dev_attr_pwm3.dev_attr.attr, | ||
921 | &sensor_dev_attr_pwm4.dev_attr.attr, | ||
985 | &dev_attr_pwm2_enable.attr, | 922 | &dev_attr_pwm2_enable.attr, |
986 | &dev_attr_pwm3.attr, | 923 | &sensor_dev_attr_temp1_type.dev_attr.attr, |
987 | &dev_attr_pwm4.attr, | 924 | &sensor_dev_attr_temp2_type.dev_attr.attr, |
988 | &dev_attr_temp1_type.attr, | 925 | &sensor_dev_attr_temp3_type.dev_attr.attr, |
989 | &dev_attr_temp2_type.attr, | ||
990 | &dev_attr_temp3_type.attr, | ||
991 | NULL | 926 | NULL |
992 | }; | 927 | }; |
993 | static const struct attribute_group w83781d_group_opt = { | 928 | static const struct attribute_group w83781d_group_opt = { |
994 | .attrs = w83781d_attributes_opt, | 929 | .attrs = w83781d_attributes_opt, |
995 | }; | 930 | }; |
996 | 931 | ||
932 | /* No clean up is done on error, it's up to the caller */ | ||
997 | static int | 933 | static int |
998 | w83781d_detect(struct i2c_adapter *adapter, int address, int kind) | 934 | w83781d_create_files(struct device *dev, int kind, int is_isa) |
999 | { | 935 | { |
1000 | int i = 0, val1 = 0, val2; | ||
1001 | struct i2c_client *client; | ||
1002 | struct device *dev; | ||
1003 | struct w83781d_data *data; | ||
1004 | int err; | 936 | int err; |
1005 | const char *client_name = ""; | ||
1006 | int is_isa = i2c_is_isa_adapter(adapter); | ||
1007 | enum vendor { winbond, asus } vendid; | ||
1008 | 937 | ||
1009 | if (!is_isa | 938 | if ((err = sysfs_create_group(&dev->kobj, &w83781d_group))) |
1010 | && !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { | 939 | return err; |
1011 | err = -EINVAL; | 940 | |
1012 | goto ERROR0; | 941 | if (kind != w83783s) { |
942 | if ((err = device_create_file(dev, | ||
943 | &sensor_dev_attr_in1_input.dev_attr)) | ||
944 | || (err = device_create_file(dev, | ||
945 | &sensor_dev_attr_in1_min.dev_attr)) | ||
946 | || (err = device_create_file(dev, | ||
947 | &sensor_dev_attr_in1_max.dev_attr))) | ||
948 | return err; | ||
949 | } | ||
950 | if (kind != as99127f && kind != w83781d && kind != w83783s) { | ||
951 | if ((err = device_create_file(dev, | ||
952 | &sensor_dev_attr_in7_input.dev_attr)) | ||
953 | || (err = device_create_file(dev, | ||
954 | &sensor_dev_attr_in7_min.dev_attr)) | ||
955 | || (err = device_create_file(dev, | ||
956 | &sensor_dev_attr_in7_max.dev_attr)) | ||
957 | || (err = device_create_file(dev, | ||
958 | &sensor_dev_attr_in8_input.dev_attr)) | ||
959 | || (err = device_create_file(dev, | ||
960 | &sensor_dev_attr_in8_min.dev_attr)) | ||
961 | || (err = device_create_file(dev, | ||
962 | &sensor_dev_attr_in8_max.dev_attr))) | ||
963 | return err; | ||
964 | } | ||
965 | if (kind != w83783s) { | ||
966 | if ((err = device_create_file(dev, | ||
967 | &sensor_dev_attr_temp3_input.dev_attr)) | ||
968 | || (err = device_create_file(dev, | ||
969 | &sensor_dev_attr_temp3_max.dev_attr)) | ||
970 | || (err = device_create_file(dev, | ||
971 | &sensor_dev_attr_temp3_max_hyst.dev_attr))) | ||
972 | return err; | ||
1013 | } | 973 | } |
1014 | 974 | ||
1015 | /* Prevent users from forcing a kind for a bus it isn't supposed | 975 | if (kind != w83781d && kind != as99127f) { |
1016 | to possibly be on */ | 976 | if ((err = device_create_file(dev, |
1017 | if (is_isa && (kind == as99127f || kind == w83783s)) { | 977 | &sensor_dev_attr_pwm1.dev_attr)) |
1018 | dev_err(&adapter->dev, | 978 | || (err = device_create_file(dev, |
1019 | "Cannot force I2C-only chip for ISA address 0x%02x.\n", | 979 | &sensor_dev_attr_pwm2.dev_attr)) |
1020 | address); | 980 | || (err = device_create_file(dev, &dev_attr_pwm2_enable))) |
1021 | err = -EINVAL; | 981 | return err; |
1022 | goto ERROR0; | ||
1023 | } | 982 | } |
1024 | 983 | if (kind == w83782d && !is_isa) { | |
1025 | if (is_isa) | 984 | if ((err = device_create_file(dev, |
1026 | if (!request_region(address, W83781D_EXTENT, | 985 | &sensor_dev_attr_pwm3.dev_attr)) |
1027 | w83781d_isa_driver.driver.name)) { | 986 | || (err = device_create_file(dev, |
1028 | dev_dbg(&adapter->dev, "Request of region " | 987 | &sensor_dev_attr_pwm4.dev_attr))) |
1029 | "0x%x-0x%x for w83781d failed\n", address, | 988 | return err; |
1030 | address + W83781D_EXTENT - 1); | 989 | } |
1031 | err = -EBUSY; | 990 | |
1032 | goto ERROR0; | 991 | if (kind != as99127f && kind != w83781d) { |
992 | if ((err = device_create_file(dev, | ||
993 | &sensor_dev_attr_temp1_type.dev_attr)) | ||
994 | || (err = device_create_file(dev, | ||
995 | &sensor_dev_attr_temp2_type.dev_attr))) | ||
996 | return err; | ||
997 | if (kind != w83783s) { | ||
998 | if ((err = device_create_file(dev, | ||
999 | &sensor_dev_attr_temp3_type.dev_attr))) | ||
1000 | return err; | ||
1033 | } | 1001 | } |
1002 | } | ||
1034 | 1003 | ||
1035 | /* Probe whether there is anything available on this address. Already | 1004 | if (is_isa) { |
1036 | done for SMBus clients */ | 1005 | err = device_create_file(&pdev->dev, &dev_attr_name); |
1037 | if (kind < 0) { | 1006 | if (err) |
1038 | if (is_isa) { | 1007 | return err; |
1008 | } | ||
1039 | 1009 | ||
1040 | #define REALLY_SLOW_IO | 1010 | return 0; |
1041 | /* We need the timeouts for at least some LM78-like | 1011 | } |
1042 | chips. But only if we read 'undefined' registers. */ | ||
1043 | i = inb_p(address + 1); | ||
1044 | if (inb_p(address + 2) != i | ||
1045 | || inb_p(address + 3) != i | ||
1046 | || inb_p(address + 7) != i) { | ||
1047 | dev_dbg(&adapter->dev, "Detection of w83781d " | ||
1048 | "chip failed at step 1\n"); | ||
1049 | err = -ENODEV; | ||
1050 | goto ERROR1; | ||
1051 | } | ||
1052 | #undef REALLY_SLOW_IO | ||
1053 | 1012 | ||
1054 | /* Let's just hope nothing breaks here */ | 1013 | static int |
1055 | i = inb_p(address + 5) & 0x7f; | 1014 | w83781d_detect(struct i2c_adapter *adapter, int address, int kind) |
1056 | outb_p(~i & 0x7f, address + 5); | 1015 | { |
1057 | val2 = inb_p(address + 5) & 0x7f; | 1016 | int val1 = 0, val2; |
1058 | if (val2 != (~i & 0x7f)) { | 1017 | struct i2c_client *client; |
1059 | outb_p(i, address + 5); | 1018 | struct device *dev; |
1060 | dev_dbg(&adapter->dev, "Detection of w83781d " | 1019 | struct w83781d_data *data; |
1061 | "chip failed at step 2 (0x%x != " | 1020 | int err; |
1062 | "0x%x at 0x%x)\n", val2, ~i & 0x7f, | 1021 | const char *client_name = ""; |
1063 | address + 5); | 1022 | enum vendor { winbond, asus } vendid; |
1064 | err = -ENODEV; | 1023 | |
1065 | goto ERROR1; | 1024 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { |
1066 | } | 1025 | err = -EINVAL; |
1067 | } | 1026 | goto ERROR1; |
1068 | } | 1027 | } |
1069 | 1028 | ||
1070 | /* OK. For now, we presume we have a valid client. We now create the | 1029 | /* OK. For now, we presume we have a valid client. We now create the |
@@ -1081,8 +1040,7 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) | |||
1081 | client->addr = address; | 1040 | client->addr = address; |
1082 | mutex_init(&data->lock); | 1041 | mutex_init(&data->lock); |
1083 | client->adapter = adapter; | 1042 | client->adapter = adapter; |
1084 | client->driver = is_isa ? &w83781d_isa_driver : &w83781d_driver; | 1043 | client->driver = &w83781d_driver; |
1085 | client->flags = 0; | ||
1086 | dev = &client->dev; | 1044 | dev = &client->dev; |
1087 | 1045 | ||
1088 | /* Now, we do the remaining detection. */ | 1046 | /* Now, we do the remaining detection. */ |
@@ -1092,14 +1050,14 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) | |||
1092 | force_*=... parameter, and the Winbond will be reset to the right | 1050 | force_*=... parameter, and the Winbond will be reset to the right |
1093 | bank. */ | 1051 | bank. */ |
1094 | if (kind < 0) { | 1052 | if (kind < 0) { |
1095 | if (w83781d_read_value(client, W83781D_REG_CONFIG) & 0x80) { | 1053 | if (w83781d_read_value(data, W83781D_REG_CONFIG) & 0x80) { |
1096 | dev_dbg(&adapter->dev, "Detection of w83781d chip " | 1054 | dev_dbg(&adapter->dev, "Detection of w83781d chip " |
1097 | "failed at step 3\n"); | 1055 | "failed at step 3\n"); |
1098 | err = -ENODEV; | 1056 | err = -ENODEV; |
1099 | goto ERROR2; | 1057 | goto ERROR2; |
1100 | } | 1058 | } |
1101 | val1 = w83781d_read_value(client, W83781D_REG_BANK); | 1059 | val1 = w83781d_read_value(data, W83781D_REG_BANK); |
1102 | val2 = w83781d_read_value(client, W83781D_REG_CHIPMAN); | 1060 | val2 = w83781d_read_value(data, W83781D_REG_CHIPMAN); |
1103 | /* Check for Winbond or Asus ID if in bank 0 */ | 1061 | /* Check for Winbond or Asus ID if in bank 0 */ |
1104 | if ((!(val1 & 0x07)) && | 1062 | if ((!(val1 & 0x07)) && |
1105 | (((!(val1 & 0x80)) && (val2 != 0xa3) && (val2 != 0xc3)) | 1063 | (((!(val1 & 0x80)) && (val2 != 0xa3) && (val2 != 0xc3)) |
@@ -1111,10 +1069,10 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) | |||
1111 | } | 1069 | } |
1112 | /* If Winbond SMBus, check address at 0x48. | 1070 | /* If Winbond SMBus, check address at 0x48. |
1113 | Asus doesn't support, except for as99127f rev.2 */ | 1071 | Asus doesn't support, except for as99127f rev.2 */ |
1114 | if ((!is_isa) && (((!(val1 & 0x80)) && (val2 == 0xa3)) || | 1072 | if ((!(val1 & 0x80) && (val2 == 0xa3)) || |
1115 | ((val1 & 0x80) && (val2 == 0x5c)))) { | 1073 | ((val1 & 0x80) && (val2 == 0x5c))) { |
1116 | if (w83781d_read_value | 1074 | if (w83781d_read_value |
1117 | (client, W83781D_REG_I2C_ADDR) != address) { | 1075 | (data, W83781D_REG_I2C_ADDR) != address) { |
1118 | dev_dbg(&adapter->dev, "Detection of w83781d " | 1076 | dev_dbg(&adapter->dev, "Detection of w83781d " |
1119 | "chip failed at step 5\n"); | 1077 | "chip failed at step 5\n"); |
1120 | err = -ENODEV; | 1078 | err = -ENODEV; |
@@ -1125,14 +1083,14 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) | |||
1125 | 1083 | ||
1126 | /* We have either had a force parameter, or we have already detected the | 1084 | /* We have either had a force parameter, or we have already detected the |
1127 | Winbond. Put it now into bank 0 and Vendor ID High Byte */ | 1085 | Winbond. Put it now into bank 0 and Vendor ID High Byte */ |
1128 | w83781d_write_value(client, W83781D_REG_BANK, | 1086 | w83781d_write_value(data, W83781D_REG_BANK, |
1129 | (w83781d_read_value(client, W83781D_REG_BANK) | 1087 | (w83781d_read_value(data, W83781D_REG_BANK) |
1130 | & 0x78) | 0x80); | 1088 | & 0x78) | 0x80); |
1131 | 1089 | ||
1132 | /* Determine the chip type. */ | 1090 | /* Determine the chip type. */ |
1133 | if (kind <= 0) { | 1091 | if (kind <= 0) { |
1134 | /* get vendor ID */ | 1092 | /* get vendor ID */ |
1135 | val2 = w83781d_read_value(client, W83781D_REG_CHIPMAN); | 1093 | val2 = w83781d_read_value(data, W83781D_REG_CHIPMAN); |
1136 | if (val2 == 0x5c) | 1094 | if (val2 == 0x5c) |
1137 | vendid = winbond; | 1095 | vendid = winbond; |
1138 | else if (val2 == 0x12) | 1096 | else if (val2 == 0x12) |
@@ -1144,17 +1102,16 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) | |||
1144 | goto ERROR2; | 1102 | goto ERROR2; |
1145 | } | 1103 | } |
1146 | 1104 | ||
1147 | val1 = w83781d_read_value(client, W83781D_REG_WCHIPID); | 1105 | val1 = w83781d_read_value(data, W83781D_REG_WCHIPID); |
1148 | if ((val1 == 0x10 || val1 == 0x11) && vendid == winbond) | 1106 | if ((val1 == 0x10 || val1 == 0x11) && vendid == winbond) |
1149 | kind = w83781d; | 1107 | kind = w83781d; |
1150 | else if (val1 == 0x30 && vendid == winbond) | 1108 | else if (val1 == 0x30 && vendid == winbond) |
1151 | kind = w83782d; | 1109 | kind = w83782d; |
1152 | else if (val1 == 0x40 && vendid == winbond && !is_isa | 1110 | else if (val1 == 0x40 && vendid == winbond && address == 0x2d) |
1153 | && address == 0x2d) | ||
1154 | kind = w83783s; | 1111 | kind = w83783s; |
1155 | else if (val1 == 0x21 && vendid == winbond) | 1112 | else if (val1 == 0x21 && vendid == winbond) |
1156 | kind = w83627hf; | 1113 | kind = w83627hf; |
1157 | else if (val1 == 0x31 && !is_isa && address >= 0x28) | 1114 | else if (val1 == 0x31 && address >= 0x28) |
1158 | kind = as99127f; | 1115 | kind = as99127f; |
1159 | else { | 1116 | else { |
1160 | if (kind == 0) | 1117 | if (kind == 0) |
@@ -1182,86 +1139,23 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) | |||
1182 | strlcpy(client->name, client_name, I2C_NAME_SIZE); | 1139 | strlcpy(client->name, client_name, I2C_NAME_SIZE); |
1183 | data->type = kind; | 1140 | data->type = kind; |
1184 | 1141 | ||
1185 | data->valid = 0; | ||
1186 | mutex_init(&data->update_lock); | ||
1187 | |||
1188 | /* Tell the I2C layer a new client has arrived */ | 1142 | /* Tell the I2C layer a new client has arrived */ |
1189 | if ((err = i2c_attach_client(client))) | 1143 | if ((err = i2c_attach_client(client))) |
1190 | goto ERROR2; | 1144 | goto ERROR2; |
1191 | 1145 | ||
1192 | /* attach secondary i2c lm75-like clients */ | 1146 | /* attach secondary i2c lm75-like clients */ |
1193 | if (!is_isa) { | 1147 | if ((err = w83781d_detect_subclients(adapter, address, |
1194 | if ((err = w83781d_detect_subclients(adapter, address, | 1148 | kind, client))) |
1195 | kind, client))) | 1149 | goto ERROR3; |
1196 | goto ERROR3; | ||
1197 | } else { | ||
1198 | data->lm75[0] = NULL; | ||
1199 | data->lm75[1] = NULL; | ||
1200 | } | ||
1201 | 1150 | ||
1202 | /* Initialize the chip */ | 1151 | /* Initialize the chip */ |
1203 | w83781d_init_client(client); | 1152 | w83781d_init_device(dev); |
1204 | |||
1205 | /* A few vars need to be filled upon startup */ | ||
1206 | for (i = 1; i <= 3; i++) { | ||
1207 | data->fan_min[i - 1] = w83781d_read_value(client, | ||
1208 | W83781D_REG_FAN_MIN(i)); | ||
1209 | } | ||
1210 | if (kind != w83781d && kind != as99127f) | ||
1211 | for (i = 0; i < 4; i++) | ||
1212 | data->pwmenable[i] = 1; | ||
1213 | 1153 | ||
1214 | /* Register sysfs hooks */ | 1154 | /* Register sysfs hooks */ |
1215 | if ((err = sysfs_create_group(&dev->kobj, &w83781d_group))) | 1155 | err = w83781d_create_files(dev, kind, 0); |
1156 | if (err) | ||
1216 | goto ERROR4; | 1157 | goto ERROR4; |
1217 | 1158 | ||
1218 | if (kind != w83783s) { | ||
1219 | if ((err = device_create_file(dev, &dev_attr_in1_input)) | ||
1220 | || (err = device_create_file(dev, &dev_attr_in1_min)) | ||
1221 | || (err = device_create_file(dev, &dev_attr_in1_max))) | ||
1222 | goto ERROR4; | ||
1223 | } | ||
1224 | if (kind != as99127f && kind != w83781d && kind != w83783s) { | ||
1225 | if ((err = device_create_file(dev, &dev_attr_in7_input)) | ||
1226 | || (err = device_create_file(dev, &dev_attr_in7_min)) | ||
1227 | || (err = device_create_file(dev, &dev_attr_in7_max)) | ||
1228 | || (err = device_create_file(dev, &dev_attr_in8_input)) | ||
1229 | || (err = device_create_file(dev, &dev_attr_in8_min)) | ||
1230 | || (err = device_create_file(dev, &dev_attr_in8_max))) | ||
1231 | goto ERROR4; | ||
1232 | } | ||
1233 | if (kind != w83783s) { | ||
1234 | if ((err = device_create_file(dev, &dev_attr_temp3_input)) | ||
1235 | || (err = device_create_file(dev, &dev_attr_temp3_max)) | ||
1236 | || (err = device_create_file(dev, | ||
1237 | &dev_attr_temp3_max_hyst))) | ||
1238 | goto ERROR4; | ||
1239 | } | ||
1240 | |||
1241 | if (kind != w83781d && kind != as99127f) { | ||
1242 | if ((err = device_create_file(dev, &dev_attr_pwm1)) | ||
1243 | || (err = device_create_file(dev, &dev_attr_pwm2)) | ||
1244 | || (err = device_create_file(dev, &dev_attr_pwm2_enable))) | ||
1245 | goto ERROR4; | ||
1246 | } | ||
1247 | if (kind == w83782d && !is_isa) { | ||
1248 | if ((err = device_create_file(dev, &dev_attr_pwm3)) | ||
1249 | || (err = device_create_file(dev, &dev_attr_pwm4))) | ||
1250 | goto ERROR4; | ||
1251 | } | ||
1252 | |||
1253 | if (kind != as99127f && kind != w83781d) { | ||
1254 | if ((err = device_create_file(dev, &dev_attr_temp1_type)) | ||
1255 | || (err = device_create_file(dev, | ||
1256 | &dev_attr_temp2_type))) | ||
1257 | goto ERROR4; | ||
1258 | if (kind != w83783s) { | ||
1259 | if ((err = device_create_file(dev, | ||
1260 | &dev_attr_temp3_type))) | ||
1261 | goto ERROR4; | ||
1262 | } | ||
1263 | } | ||
1264 | |||
1265 | data->class_dev = hwmon_device_register(dev); | 1159 | data->class_dev = hwmon_device_register(dev); |
1266 | if (IS_ERR(data->class_dev)) { | 1160 | if (IS_ERR(data->class_dev)) { |
1267 | err = PTR_ERR(data->class_dev); | 1161 | err = PTR_ERR(data->class_dev); |
@@ -1287,9 +1181,6 @@ ERROR3: | |||
1287 | ERROR2: | 1181 | ERROR2: |
1288 | kfree(data); | 1182 | kfree(data); |
1289 | ERROR1: | 1183 | ERROR1: |
1290 | if (is_isa) | ||
1291 | release_region(address, W83781D_EXTENT); | ||
1292 | ERROR0: | ||
1293 | return err; | 1184 | return err; |
1294 | } | 1185 | } |
1295 | 1186 | ||
@@ -1305,8 +1196,6 @@ w83781d_detach_client(struct i2c_client *client) | |||
1305 | sysfs_remove_group(&client->dev.kobj, &w83781d_group); | 1196 | sysfs_remove_group(&client->dev.kobj, &w83781d_group); |
1306 | sysfs_remove_group(&client->dev.kobj, &w83781d_group_opt); | 1197 | sysfs_remove_group(&client->dev.kobj, &w83781d_group_opt); |
1307 | } | 1198 | } |
1308 | if (i2c_is_isa_client(client)) | ||
1309 | release_region(client->addr, W83781D_EXTENT); | ||
1310 | 1199 | ||
1311 | if ((err = i2c_detach_client(client))) | 1200 | if ((err = i2c_detach_client(client))) |
1312 | return err; | 1201 | return err; |
@@ -1322,6 +1211,88 @@ w83781d_detach_client(struct i2c_client *client) | |||
1322 | return 0; | 1211 | return 0; |
1323 | } | 1212 | } |
1324 | 1213 | ||
1214 | static int __devinit | ||
1215 | w83781d_isa_probe(struct platform_device *pdev) | ||
1216 | { | ||
1217 | int err, reg; | ||
1218 | struct w83781d_data *data; | ||
1219 | struct resource *res; | ||
1220 | const char *name; | ||
1221 | |||
1222 | /* Reserve the ISA region */ | ||
1223 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); | ||
1224 | if (!request_region(res->start, W83781D_EXTENT, "w83781d")) { | ||
1225 | err = -EBUSY; | ||
1226 | goto exit; | ||
1227 | } | ||
1228 | |||
1229 | if (!(data = kzalloc(sizeof(struct w83781d_data), GFP_KERNEL))) { | ||
1230 | err = -ENOMEM; | ||
1231 | goto exit_release_region; | ||
1232 | } | ||
1233 | mutex_init(&data->lock); | ||
1234 | data->client.addr = res->start; | ||
1235 | i2c_set_clientdata(&data->client, data); | ||
1236 | platform_set_drvdata(pdev, data); | ||
1237 | |||
1238 | reg = w83781d_read_value(data, W83781D_REG_WCHIPID); | ||
1239 | switch (reg) { | ||
1240 | case 0x21: | ||
1241 | data->type = w83627hf; | ||
1242 | name = "w83627hf"; | ||
1243 | break; | ||
1244 | case 0x30: | ||
1245 | data->type = w83782d; | ||
1246 | name = "w83782d"; | ||
1247 | break; | ||
1248 | default: | ||
1249 | data->type = w83781d; | ||
1250 | name = "w83781d"; | ||
1251 | } | ||
1252 | strlcpy(data->client.name, name, I2C_NAME_SIZE); | ||
1253 | |||
1254 | /* Initialize the W83781D chip */ | ||
1255 | w83781d_init_device(&pdev->dev); | ||
1256 | |||
1257 | /* Register sysfs hooks */ | ||
1258 | err = w83781d_create_files(&pdev->dev, data->type, 1); | ||
1259 | if (err) | ||
1260 | goto exit_remove_files; | ||
1261 | |||
1262 | data->class_dev = hwmon_device_register(&pdev->dev); | ||
1263 | if (IS_ERR(data->class_dev)) { | ||
1264 | err = PTR_ERR(data->class_dev); | ||
1265 | goto exit_remove_files; | ||
1266 | } | ||
1267 | |||
1268 | return 0; | ||
1269 | |||
1270 | exit_remove_files: | ||
1271 | sysfs_remove_group(&pdev->dev.kobj, &w83781d_group); | ||
1272 | sysfs_remove_group(&pdev->dev.kobj, &w83781d_group_opt); | ||
1273 | device_remove_file(&pdev->dev, &dev_attr_name); | ||
1274 | kfree(data); | ||
1275 | exit_release_region: | ||
1276 | release_region(res->start, W83781D_EXTENT); | ||
1277 | exit: | ||
1278 | return err; | ||
1279 | } | ||
1280 | |||
1281 | static int __devexit | ||
1282 | w83781d_isa_remove(struct platform_device *pdev) | ||
1283 | { | ||
1284 | struct w83781d_data *data = platform_get_drvdata(pdev); | ||
1285 | |||
1286 | hwmon_device_unregister(data->class_dev); | ||
1287 | sysfs_remove_group(&pdev->dev.kobj, &w83781d_group); | ||
1288 | sysfs_remove_group(&pdev->dev.kobj, &w83781d_group_opt); | ||
1289 | device_remove_file(&pdev->dev, &dev_attr_name); | ||
1290 | release_region(data->client.addr, W83781D_EXTENT); | ||
1291 | kfree(data); | ||
1292 | |||
1293 | return 0; | ||
1294 | } | ||
1295 | |||
1325 | /* The SMBus locks itself, usually, but nothing may access the Winbond between | 1296 | /* The SMBus locks itself, usually, but nothing may access the Winbond between |
1326 | bank switches. ISA access must always be locked explicitly! | 1297 | bank switches. ISA access must always be locked explicitly! |
1327 | We ignore the W83781D BUSY flag at this moment - it could lead to deadlocks, | 1298 | We ignore the W83781D BUSY flag at this moment - it could lead to deadlocks, |
@@ -1329,14 +1300,14 @@ w83781d_detach_client(struct i2c_client *client) | |||
1329 | There are some ugly typecasts here, but the good news is - they should | 1300 | There are some ugly typecasts here, but the good news is - they should |
1330 | nowhere else be necessary! */ | 1301 | nowhere else be necessary! */ |
1331 | static int | 1302 | static int |
1332 | w83781d_read_value(struct i2c_client *client, u16 reg) | 1303 | w83781d_read_value(struct w83781d_data *data, u16 reg) |
1333 | { | 1304 | { |
1334 | struct w83781d_data *data = i2c_get_clientdata(client); | 1305 | struct i2c_client *client = &data->client; |
1335 | int res, word_sized, bank; | 1306 | int res, word_sized, bank; |
1336 | struct i2c_client *cl; | 1307 | struct i2c_client *cl; |
1337 | 1308 | ||
1338 | mutex_lock(&data->lock); | 1309 | mutex_lock(&data->lock); |
1339 | if (i2c_is_isa_client(client)) { | 1310 | if (!client->driver) { /* ISA device */ |
1340 | word_sized = (((reg & 0xff00) == 0x100) | 1311 | word_sized = (((reg & 0xff00) == 0x100) |
1341 | || ((reg & 0xff00) == 0x200)) | 1312 | || ((reg & 0xff00) == 0x200)) |
1342 | && (((reg & 0x00ff) == 0x50) | 1313 | && (((reg & 0x00ff) == 0x50) |
@@ -1398,14 +1369,14 @@ w83781d_read_value(struct i2c_client *client, u16 reg) | |||
1398 | } | 1369 | } |
1399 | 1370 | ||
1400 | static int | 1371 | static int |
1401 | w83781d_write_value(struct i2c_client *client, u16 reg, u16 value) | 1372 | w83781d_write_value(struct w83781d_data *data, u16 reg, u16 value) |
1402 | { | 1373 | { |
1403 | struct w83781d_data *data = i2c_get_clientdata(client); | 1374 | struct i2c_client *client = &data->client; |
1404 | int word_sized, bank; | 1375 | int word_sized, bank; |
1405 | struct i2c_client *cl; | 1376 | struct i2c_client *cl; |
1406 | 1377 | ||
1407 | mutex_lock(&data->lock); | 1378 | mutex_lock(&data->lock); |
1408 | if (i2c_is_isa_client(client)) { | 1379 | if (!client->driver) { /* ISA device */ |
1409 | word_sized = (((reg & 0xff00) == 0x100) | 1380 | word_sized = (((reg & 0xff00) == 0x100) |
1410 | || ((reg & 0xff00) == 0x200)) | 1381 | || ((reg & 0xff00) == 0x200)) |
1411 | && (((reg & 0x00ff) == 0x53) | 1382 | && (((reg & 0x00ff) == 0x53) |
@@ -1462,13 +1433,18 @@ w83781d_write_value(struct i2c_client *client, u16 reg, u16 value) | |||
1462 | } | 1433 | } |
1463 | 1434 | ||
1464 | static void | 1435 | static void |
1465 | w83781d_init_client(struct i2c_client *client) | 1436 | w83781d_init_device(struct device *dev) |
1466 | { | 1437 | { |
1467 | struct w83781d_data *data = i2c_get_clientdata(client); | 1438 | struct w83781d_data *data = dev_get_drvdata(dev); |
1468 | int i, p; | 1439 | int i, p; |
1469 | int type = data->type; | 1440 | int type = data->type; |
1470 | u8 tmp; | 1441 | u8 tmp; |
1471 | 1442 | ||
1443 | if (type == w83627hf) | ||
1444 | dev_info(dev, "The W83627HF chip is better supported by the " | ||
1445 | "w83627hf driver, support will be dropped from the " | ||
1446 | "w83781d driver soon\n"); | ||
1447 | |||
1472 | if (reset && type != as99127f) { /* this resets registers we don't have | 1448 | if (reset && type != as99127f) { /* this resets registers we don't have |
1473 | documentation for on the as99127f */ | 1449 | documentation for on the as99127f */ |
1474 | /* Resetting the chip has been the default for a long time, | 1450 | /* Resetting the chip has been the default for a long time, |
@@ -1477,42 +1453,42 @@ w83781d_init_client(struct i2c_client *client) | |||
1477 | It might even go away if nobody reports it as being useful, | 1453 | It might even go away if nobody reports it as being useful, |
1478 | as I see very little reason why this would be needed at | 1454 | as I see very little reason why this would be needed at |
1479 | all. */ | 1455 | all. */ |
1480 | dev_info(&client->dev, "If reset=1 solved a problem you were " | 1456 | dev_info(dev, "If reset=1 solved a problem you were " |
1481 | "having, please report!\n"); | 1457 | "having, please report!\n"); |
1482 | 1458 | ||
1483 | /* save these registers */ | 1459 | /* save these registers */ |
1484 | i = w83781d_read_value(client, W83781D_REG_BEEP_CONFIG); | 1460 | i = w83781d_read_value(data, W83781D_REG_BEEP_CONFIG); |
1485 | p = w83781d_read_value(client, W83781D_REG_PWMCLK12); | 1461 | p = w83781d_read_value(data, W83781D_REG_PWMCLK12); |
1486 | /* Reset all except Watchdog values and last conversion values | 1462 | /* Reset all except Watchdog values and last conversion values |
1487 | This sets fan-divs to 2, among others */ | 1463 | This sets fan-divs to 2, among others */ |
1488 | w83781d_write_value(client, W83781D_REG_CONFIG, 0x80); | 1464 | w83781d_write_value(data, W83781D_REG_CONFIG, 0x80); |
1489 | /* Restore the registers and disable power-on abnormal beep. | 1465 | /* Restore the registers and disable power-on abnormal beep. |
1490 | This saves FAN 1/2/3 input/output values set by BIOS. */ | 1466 | This saves FAN 1/2/3 input/output values set by BIOS. */ |
1491 | w83781d_write_value(client, W83781D_REG_BEEP_CONFIG, i | 0x80); | 1467 | w83781d_write_value(data, W83781D_REG_BEEP_CONFIG, i | 0x80); |
1492 | w83781d_write_value(client, W83781D_REG_PWMCLK12, p); | 1468 | w83781d_write_value(data, W83781D_REG_PWMCLK12, p); |
1493 | /* Disable master beep-enable (reset turns it on). | 1469 | /* Disable master beep-enable (reset turns it on). |
1494 | Individual beep_mask should be reset to off but for some reason | 1470 | Individual beep_mask should be reset to off but for some reason |
1495 | disabling this bit helps some people not get beeped */ | 1471 | disabling this bit helps some people not get beeped */ |
1496 | w83781d_write_value(client, W83781D_REG_BEEP_INTS2, 0); | 1472 | w83781d_write_value(data, W83781D_REG_BEEP_INTS2, 0); |
1497 | } | 1473 | } |
1498 | 1474 | ||
1499 | /* Disable power-on abnormal beep, as advised by the datasheet. | 1475 | /* Disable power-on abnormal beep, as advised by the datasheet. |
1500 | Already done if reset=1. */ | 1476 | Already done if reset=1. */ |
1501 | if (init && !reset && type != as99127f) { | 1477 | if (init && !reset && type != as99127f) { |
1502 | i = w83781d_read_value(client, W83781D_REG_BEEP_CONFIG); | 1478 | i = w83781d_read_value(data, W83781D_REG_BEEP_CONFIG); |
1503 | w83781d_write_value(client, W83781D_REG_BEEP_CONFIG, i | 0x80); | 1479 | w83781d_write_value(data, W83781D_REG_BEEP_CONFIG, i | 0x80); |
1504 | } | 1480 | } |
1505 | 1481 | ||
1506 | data->vrm = vid_which_vrm(); | 1482 | data->vrm = vid_which_vrm(); |
1507 | 1483 | ||
1508 | if ((type != w83781d) && (type != as99127f)) { | 1484 | if ((type != w83781d) && (type != as99127f)) { |
1509 | tmp = w83781d_read_value(client, W83781D_REG_SCFG1); | 1485 | tmp = w83781d_read_value(data, W83781D_REG_SCFG1); |
1510 | for (i = 1; i <= 3; i++) { | 1486 | for (i = 1; i <= 3; i++) { |
1511 | if (!(tmp & BIT_SCFG1[i - 1])) { | 1487 | if (!(tmp & BIT_SCFG1[i - 1])) { |
1512 | data->sens[i - 1] = W83781D_DEFAULT_BETA; | 1488 | data->sens[i - 1] = W83781D_DEFAULT_BETA; |
1513 | } else { | 1489 | } else { |
1514 | if (w83781d_read_value | 1490 | if (w83781d_read_value |
1515 | (client, | 1491 | (data, |
1516 | W83781D_REG_SCFG2) & BIT_SCFG2[i - 1]) | 1492 | W83781D_REG_SCFG2) & BIT_SCFG2[i - 1]) |
1517 | data->sens[i - 1] = 1; | 1493 | data->sens[i - 1] = 1; |
1518 | else | 1494 | else |
@@ -1525,38 +1501,46 @@ w83781d_init_client(struct i2c_client *client) | |||
1525 | 1501 | ||
1526 | if (init && type != as99127f) { | 1502 | if (init && type != as99127f) { |
1527 | /* Enable temp2 */ | 1503 | /* Enable temp2 */ |
1528 | tmp = w83781d_read_value(client, W83781D_REG_TEMP2_CONFIG); | 1504 | tmp = w83781d_read_value(data, W83781D_REG_TEMP2_CONFIG); |
1529 | if (tmp & 0x01) { | 1505 | if (tmp & 0x01) { |
1530 | dev_warn(&client->dev, "Enabling temp2, readings " | 1506 | dev_warn(dev, "Enabling temp2, readings " |
1531 | "might not make sense\n"); | 1507 | "might not make sense\n"); |
1532 | w83781d_write_value(client, W83781D_REG_TEMP2_CONFIG, | 1508 | w83781d_write_value(data, W83781D_REG_TEMP2_CONFIG, |
1533 | tmp & 0xfe); | 1509 | tmp & 0xfe); |
1534 | } | 1510 | } |
1535 | 1511 | ||
1536 | /* Enable temp3 */ | 1512 | /* Enable temp3 */ |
1537 | if (type != w83783s) { | 1513 | if (type != w83783s) { |
1538 | tmp = w83781d_read_value(client, | 1514 | tmp = w83781d_read_value(data, |
1539 | W83781D_REG_TEMP3_CONFIG); | 1515 | W83781D_REG_TEMP3_CONFIG); |
1540 | if (tmp & 0x01) { | 1516 | if (tmp & 0x01) { |
1541 | dev_warn(&client->dev, "Enabling temp3, " | 1517 | dev_warn(dev, "Enabling temp3, " |
1542 | "readings might not make sense\n"); | 1518 | "readings might not make sense\n"); |
1543 | w83781d_write_value(client, | 1519 | w83781d_write_value(data, |
1544 | W83781D_REG_TEMP3_CONFIG, tmp & 0xfe); | 1520 | W83781D_REG_TEMP3_CONFIG, tmp & 0xfe); |
1545 | } | 1521 | } |
1546 | } | 1522 | } |
1547 | } | 1523 | } |
1548 | 1524 | ||
1549 | /* Start monitoring */ | 1525 | /* Start monitoring */ |
1550 | w83781d_write_value(client, W83781D_REG_CONFIG, | 1526 | w83781d_write_value(data, W83781D_REG_CONFIG, |
1551 | (w83781d_read_value(client, | 1527 | (w83781d_read_value(data, |
1552 | W83781D_REG_CONFIG) & 0xf7) | 1528 | W83781D_REG_CONFIG) & 0xf7) |
1553 | | 0x01); | 1529 | | 0x01); |
1530 | |||
1531 | /* A few vars need to be filled upon startup */ | ||
1532 | for (i = 0; i < 3; i++) { | ||
1533 | data->fan_min[i] = w83781d_read_value(data, | ||
1534 | W83781D_REG_FAN_MIN(i)); | ||
1535 | } | ||
1536 | |||
1537 | mutex_init(&data->update_lock); | ||
1554 | } | 1538 | } |
1555 | 1539 | ||
1556 | static struct w83781d_data *w83781d_update_device(struct device *dev) | 1540 | static struct w83781d_data *w83781d_update_device(struct device *dev) |
1557 | { | 1541 | { |
1558 | struct i2c_client *client = to_i2c_client(dev); | 1542 | struct w83781d_data *data = dev_get_drvdata(dev); |
1559 | struct w83781d_data *data = i2c_get_clientdata(client); | 1543 | struct i2c_client *client = &data->client; |
1560 | int i; | 1544 | int i; |
1561 | 1545 | ||
1562 | mutex_lock(&data->update_lock); | 1546 | mutex_lock(&data->update_lock); |
@@ -1569,98 +1553,97 @@ static struct w83781d_data *w83781d_update_device(struct device *dev) | |||
1569 | if (data->type == w83783s && i == 1) | 1553 | if (data->type == w83783s && i == 1) |
1570 | continue; /* 783S has no in1 */ | 1554 | continue; /* 783S has no in1 */ |
1571 | data->in[i] = | 1555 | data->in[i] = |
1572 | w83781d_read_value(client, W83781D_REG_IN(i)); | 1556 | w83781d_read_value(data, W83781D_REG_IN(i)); |
1573 | data->in_min[i] = | 1557 | data->in_min[i] = |
1574 | w83781d_read_value(client, W83781D_REG_IN_MIN(i)); | 1558 | w83781d_read_value(data, W83781D_REG_IN_MIN(i)); |
1575 | data->in_max[i] = | 1559 | data->in_max[i] = |
1576 | w83781d_read_value(client, W83781D_REG_IN_MAX(i)); | 1560 | w83781d_read_value(data, W83781D_REG_IN_MAX(i)); |
1577 | if ((data->type != w83782d) | 1561 | if ((data->type != w83782d) |
1578 | && (data->type != w83627hf) && (i == 6)) | 1562 | && (data->type != w83627hf) && (i == 6)) |
1579 | break; | 1563 | break; |
1580 | } | 1564 | } |
1581 | for (i = 1; i <= 3; i++) { | 1565 | for (i = 0; i < 3; i++) { |
1582 | data->fan[i - 1] = | 1566 | data->fan[i] = |
1583 | w83781d_read_value(client, W83781D_REG_FAN(i)); | 1567 | w83781d_read_value(data, W83781D_REG_FAN(i)); |
1584 | data->fan_min[i - 1] = | 1568 | data->fan_min[i] = |
1585 | w83781d_read_value(client, W83781D_REG_FAN_MIN(i)); | 1569 | w83781d_read_value(data, W83781D_REG_FAN_MIN(i)); |
1586 | } | 1570 | } |
1587 | if (data->type != w83781d && data->type != as99127f) { | 1571 | if (data->type != w83781d && data->type != as99127f) { |
1588 | for (i = 1; i <= 4; i++) { | 1572 | for (i = 0; i < 4; i++) { |
1589 | data->pwm[i - 1] = | 1573 | data->pwm[i] = |
1590 | w83781d_read_value(client, | 1574 | w83781d_read_value(data, |
1591 | W83781D_REG_PWM(i)); | 1575 | W83781D_REG_PWM[i]); |
1592 | if ((data->type != w83782d | 1576 | if ((data->type != w83782d || !client->driver) |
1593 | || i2c_is_isa_client(client)) | 1577 | && i == 1) |
1594 | && i == 2) | ||
1595 | break; | 1578 | break; |
1596 | } | 1579 | } |
1597 | /* Only PWM2 can be disabled */ | 1580 | /* Only PWM2 can be disabled */ |
1598 | data->pwmenable[1] = (w83781d_read_value(client, | 1581 | data->pwm2_enable = (w83781d_read_value(data, |
1599 | W83781D_REG_PWMCLK12) & 0x08) >> 3; | 1582 | W83781D_REG_PWMCLK12) & 0x08) >> 3; |
1600 | } | 1583 | } |
1601 | 1584 | ||
1602 | data->temp = w83781d_read_value(client, W83781D_REG_TEMP(1)); | 1585 | data->temp = w83781d_read_value(data, W83781D_REG_TEMP(1)); |
1603 | data->temp_max = | 1586 | data->temp_max = |
1604 | w83781d_read_value(client, W83781D_REG_TEMP_OVER(1)); | 1587 | w83781d_read_value(data, W83781D_REG_TEMP_OVER(1)); |
1605 | data->temp_max_hyst = | 1588 | data->temp_max_hyst = |
1606 | w83781d_read_value(client, W83781D_REG_TEMP_HYST(1)); | 1589 | w83781d_read_value(data, W83781D_REG_TEMP_HYST(1)); |
1607 | data->temp_add[0] = | 1590 | data->temp_add[0] = |
1608 | w83781d_read_value(client, W83781D_REG_TEMP(2)); | 1591 | w83781d_read_value(data, W83781D_REG_TEMP(2)); |
1609 | data->temp_max_add[0] = | 1592 | data->temp_max_add[0] = |
1610 | w83781d_read_value(client, W83781D_REG_TEMP_OVER(2)); | 1593 | w83781d_read_value(data, W83781D_REG_TEMP_OVER(2)); |
1611 | data->temp_max_hyst_add[0] = | 1594 | data->temp_max_hyst_add[0] = |
1612 | w83781d_read_value(client, W83781D_REG_TEMP_HYST(2)); | 1595 | w83781d_read_value(data, W83781D_REG_TEMP_HYST(2)); |
1613 | if (data->type != w83783s) { | 1596 | if (data->type != w83783s) { |
1614 | data->temp_add[1] = | 1597 | data->temp_add[1] = |
1615 | w83781d_read_value(client, W83781D_REG_TEMP(3)); | 1598 | w83781d_read_value(data, W83781D_REG_TEMP(3)); |
1616 | data->temp_max_add[1] = | 1599 | data->temp_max_add[1] = |
1617 | w83781d_read_value(client, | 1600 | w83781d_read_value(data, |
1618 | W83781D_REG_TEMP_OVER(3)); | 1601 | W83781D_REG_TEMP_OVER(3)); |
1619 | data->temp_max_hyst_add[1] = | 1602 | data->temp_max_hyst_add[1] = |
1620 | w83781d_read_value(client, | 1603 | w83781d_read_value(data, |
1621 | W83781D_REG_TEMP_HYST(3)); | 1604 | W83781D_REG_TEMP_HYST(3)); |
1622 | } | 1605 | } |
1623 | i = w83781d_read_value(client, W83781D_REG_VID_FANDIV); | 1606 | i = w83781d_read_value(data, W83781D_REG_VID_FANDIV); |
1624 | data->vid = i & 0x0f; | 1607 | data->vid = i & 0x0f; |
1625 | data->vid |= (w83781d_read_value(client, | 1608 | data->vid |= (w83781d_read_value(data, |
1626 | W83781D_REG_CHIPID) & 0x01) << 4; | 1609 | W83781D_REG_CHIPID) & 0x01) << 4; |
1627 | data->fan_div[0] = (i >> 4) & 0x03; | 1610 | data->fan_div[0] = (i >> 4) & 0x03; |
1628 | data->fan_div[1] = (i >> 6) & 0x03; | 1611 | data->fan_div[1] = (i >> 6) & 0x03; |
1629 | data->fan_div[2] = (w83781d_read_value(client, | 1612 | data->fan_div[2] = (w83781d_read_value(data, |
1630 | W83781D_REG_PIN) >> 6) & 0x03; | 1613 | W83781D_REG_PIN) >> 6) & 0x03; |
1631 | if ((data->type != w83781d) && (data->type != as99127f)) { | 1614 | if ((data->type != w83781d) && (data->type != as99127f)) { |
1632 | i = w83781d_read_value(client, W83781D_REG_VBAT); | 1615 | i = w83781d_read_value(data, W83781D_REG_VBAT); |
1633 | data->fan_div[0] |= (i >> 3) & 0x04; | 1616 | data->fan_div[0] |= (i >> 3) & 0x04; |
1634 | data->fan_div[1] |= (i >> 4) & 0x04; | 1617 | data->fan_div[1] |= (i >> 4) & 0x04; |
1635 | data->fan_div[2] |= (i >> 5) & 0x04; | 1618 | data->fan_div[2] |= (i >> 5) & 0x04; |
1636 | } | 1619 | } |
1637 | if ((data->type == w83782d) || (data->type == w83627hf)) { | 1620 | if ((data->type == w83782d) || (data->type == w83627hf)) { |
1638 | data->alarms = w83781d_read_value(client, | 1621 | data->alarms = w83781d_read_value(data, |
1639 | W83782D_REG_ALARM1) | 1622 | W83782D_REG_ALARM1) |
1640 | | (w83781d_read_value(client, | 1623 | | (w83781d_read_value(data, |
1641 | W83782D_REG_ALARM2) << 8) | 1624 | W83782D_REG_ALARM2) << 8) |
1642 | | (w83781d_read_value(client, | 1625 | | (w83781d_read_value(data, |
1643 | W83782D_REG_ALARM3) << 16); | 1626 | W83782D_REG_ALARM3) << 16); |
1644 | } else if (data->type == w83783s) { | 1627 | } else if (data->type == w83783s) { |
1645 | data->alarms = w83781d_read_value(client, | 1628 | data->alarms = w83781d_read_value(data, |
1646 | W83782D_REG_ALARM1) | 1629 | W83782D_REG_ALARM1) |
1647 | | (w83781d_read_value(client, | 1630 | | (w83781d_read_value(data, |
1648 | W83782D_REG_ALARM2) << 8); | 1631 | W83782D_REG_ALARM2) << 8); |
1649 | } else { | 1632 | } else { |
1650 | /* No real-time status registers, fall back to | 1633 | /* No real-time status registers, fall back to |
1651 | interrupt status registers */ | 1634 | interrupt status registers */ |
1652 | data->alarms = w83781d_read_value(client, | 1635 | data->alarms = w83781d_read_value(data, |
1653 | W83781D_REG_ALARM1) | 1636 | W83781D_REG_ALARM1) |
1654 | | (w83781d_read_value(client, | 1637 | | (w83781d_read_value(data, |
1655 | W83781D_REG_ALARM2) << 8); | 1638 | W83781D_REG_ALARM2) << 8); |
1656 | } | 1639 | } |
1657 | i = w83781d_read_value(client, W83781D_REG_BEEP_INTS2); | 1640 | i = w83781d_read_value(data, W83781D_REG_BEEP_INTS2); |
1658 | data->beep_enable = i >> 7; | 1641 | data->beep_enable = i >> 7; |
1659 | data->beep_mask = ((i & 0x7f) << 8) + | 1642 | data->beep_mask = ((i & 0x7f) << 8) + |
1660 | w83781d_read_value(client, W83781D_REG_BEEP_INTS1); | 1643 | w83781d_read_value(data, W83781D_REG_BEEP_INTS1); |
1661 | if ((data->type != w83781d) && (data->type != as99127f)) { | 1644 | if ((data->type != w83781d) && (data->type != as99127f)) { |
1662 | data->beep_mask |= | 1645 | data->beep_mask |= |
1663 | w83781d_read_value(client, | 1646 | w83781d_read_value(data, |
1664 | W83781D_REG_BEEP_INTS3) << 16; | 1647 | W83781D_REG_BEEP_INTS3) << 16; |
1665 | } | 1648 | } |
1666 | data->last_updated = jiffies; | 1649 | data->last_updated = jiffies; |
@@ -1672,6 +1655,133 @@ static struct w83781d_data *w83781d_update_device(struct device *dev) | |||
1672 | return data; | 1655 | return data; |
1673 | } | 1656 | } |
1674 | 1657 | ||
1658 | /* return 1 if a supported chip is found, 0 otherwise */ | ||
1659 | static int __init | ||
1660 | w83781d_isa_found(unsigned short address) | ||
1661 | { | ||
1662 | int val, save, found = 0; | ||
1663 | |||
1664 | if (!request_region(address, W83781D_EXTENT, "w83781d")) | ||
1665 | return 0; | ||
1666 | |||
1667 | #define REALLY_SLOW_IO | ||
1668 | /* We need the timeouts for at least some W83781D-like | ||
1669 | chips. But only if we read 'undefined' registers. */ | ||
1670 | val = inb_p(address + 1); | ||
1671 | if (inb_p(address + 2) != val | ||
1672 | || inb_p(address + 3) != val | ||
1673 | || inb_p(address + 7) != val) { | ||
1674 | pr_debug("w83781d: Detection failed at step 1\n"); | ||
1675 | goto release; | ||
1676 | } | ||
1677 | #undef REALLY_SLOW_IO | ||
1678 | |||
1679 | /* We should be able to change the 7 LSB of the address port. The | ||
1680 | MSB (busy flag) should be clear initially, set after the write. */ | ||
1681 | save = inb_p(address + W83781D_ADDR_REG_OFFSET); | ||
1682 | if (save & 0x80) { | ||
1683 | pr_debug("w83781d: Detection failed at step 2\n"); | ||
1684 | goto release; | ||
1685 | } | ||
1686 | val = ~save & 0x7f; | ||
1687 | outb_p(val, address + W83781D_ADDR_REG_OFFSET); | ||
1688 | if (inb_p(address + W83781D_ADDR_REG_OFFSET) != (val | 0x80)) { | ||
1689 | outb_p(save, address + W83781D_ADDR_REG_OFFSET); | ||
1690 | pr_debug("w83781d: Detection failed at step 3\n"); | ||
1691 | goto release; | ||
1692 | } | ||
1693 | |||
1694 | /* We found a device, now see if it could be a W83781D */ | ||
1695 | outb_p(W83781D_REG_CONFIG, address + W83781D_ADDR_REG_OFFSET); | ||
1696 | val = inb_p(address + W83781D_DATA_REG_OFFSET); | ||
1697 | if (val & 0x80) { | ||
1698 | pr_debug("w83781d: Detection failed at step 4\n"); | ||
1699 | goto release; | ||
1700 | } | ||
1701 | outb_p(W83781D_REG_BANK, address + W83781D_ADDR_REG_OFFSET); | ||
1702 | save = inb_p(address + W83781D_DATA_REG_OFFSET); | ||
1703 | outb_p(W83781D_REG_CHIPMAN, address + W83781D_ADDR_REG_OFFSET); | ||
1704 | val = inb_p(address + W83781D_DATA_REG_OFFSET); | ||
1705 | if ((!(save & 0x80) && (val != 0xa3)) | ||
1706 | || ((save & 0x80) && (val != 0x5c))) { | ||
1707 | pr_debug("w83781d: Detection failed at step 5\n"); | ||
1708 | goto release; | ||
1709 | } | ||
1710 | outb_p(W83781D_REG_I2C_ADDR, address + W83781D_ADDR_REG_OFFSET); | ||
1711 | val = inb_p(address + W83781D_DATA_REG_OFFSET); | ||
1712 | if (val < 0x03 || val > 0x77) { /* Not a valid I2C address */ | ||
1713 | pr_debug("w83781d: Detection failed at step 6\n"); | ||
1714 | goto release; | ||
1715 | } | ||
1716 | |||
1717 | /* The busy flag should be clear again */ | ||
1718 | if (inb_p(address + W83781D_ADDR_REG_OFFSET) & 0x80) { | ||
1719 | pr_debug("w83781d: Detection failed at step 7\n"); | ||
1720 | goto release; | ||
1721 | } | ||
1722 | |||
1723 | /* Determine the chip type */ | ||
1724 | outb_p(W83781D_REG_BANK, address + W83781D_ADDR_REG_OFFSET); | ||
1725 | save = inb_p(address + W83781D_DATA_REG_OFFSET); | ||
1726 | outb_p(save & 0xf8, address + W83781D_DATA_REG_OFFSET); | ||
1727 | outb_p(W83781D_REG_WCHIPID, address + W83781D_ADDR_REG_OFFSET); | ||
1728 | val = inb_p(address + W83781D_DATA_REG_OFFSET); | ||
1729 | if ((val & 0xfe) == 0x10 /* W83781D */ | ||
1730 | || val == 0x30 /* W83782D */ | ||
1731 | || val == 0x21) /* W83627HF */ | ||
1732 | found = 1; | ||
1733 | |||
1734 | if (found) | ||
1735 | pr_info("w83781d: Found a %s chip at %#x\n", | ||
1736 | val == 0x21 ? "W83627HF" : | ||
1737 | val == 0x30 ? "W83782D" : "W83781D", (int)address); | ||
1738 | |||
1739 | release: | ||
1740 | release_region(address, W83781D_EXTENT); | ||
1741 | return found; | ||
1742 | } | ||
1743 | |||
1744 | static int __init | ||
1745 | w83781d_isa_device_add(unsigned short address) | ||
1746 | { | ||
1747 | struct resource res = { | ||
1748 | .start = address, | ||
1749 | .end = address + W83781D_EXTENT, | ||
1750 | .name = "w83781d", | ||
1751 | .flags = IORESOURCE_IO, | ||
1752 | }; | ||
1753 | int err; | ||
1754 | |||
1755 | pdev = platform_device_alloc("w83781d", address); | ||
1756 | if (!pdev) { | ||
1757 | err = -ENOMEM; | ||
1758 | printk(KERN_ERR "w83781d: Device allocation failed\n"); | ||
1759 | goto exit; | ||
1760 | } | ||
1761 | |||
1762 | err = platform_device_add_resources(pdev, &res, 1); | ||
1763 | if (err) { | ||
1764 | printk(KERN_ERR "w83781d: Device resource addition failed " | ||
1765 | "(%d)\n", err); | ||
1766 | goto exit_device_put; | ||
1767 | } | ||
1768 | |||
1769 | err = platform_device_add(pdev); | ||
1770 | if (err) { | ||
1771 | printk(KERN_ERR "w83781d: Device addition failed (%d)\n", | ||
1772 | err); | ||
1773 | goto exit_device_put; | ||
1774 | } | ||
1775 | |||
1776 | return 0; | ||
1777 | |||
1778 | exit_device_put: | ||
1779 | platform_device_put(pdev); | ||
1780 | exit: | ||
1781 | pdev = NULL; | ||
1782 | return err; | ||
1783 | } | ||
1784 | |||
1675 | static int __init | 1785 | static int __init |
1676 | sensors_w83781d_init(void) | 1786 | sensors_w83781d_init(void) |
1677 | { | 1787 | { |
@@ -1679,21 +1789,36 @@ sensors_w83781d_init(void) | |||
1679 | 1789 | ||
1680 | res = i2c_add_driver(&w83781d_driver); | 1790 | res = i2c_add_driver(&w83781d_driver); |
1681 | if (res) | 1791 | if (res) |
1682 | return res; | 1792 | goto exit; |
1793 | |||
1794 | if (w83781d_isa_found(isa_address)) { | ||
1795 | res = platform_driver_register(&w83781d_isa_driver); | ||
1796 | if (res) | ||
1797 | goto exit_unreg_i2c_driver; | ||
1683 | 1798 | ||
1684 | /* Don't exit if this one fails, we still want the I2C variants | 1799 | /* Sets global pdev as a side effect */ |
1685 | to work! */ | 1800 | res = w83781d_isa_device_add(isa_address); |
1686 | if (i2c_isa_add_driver(&w83781d_isa_driver)) | 1801 | if (res) |
1687 | isa_address = 0; | 1802 | goto exit_unreg_isa_driver; |
1803 | } | ||
1688 | 1804 | ||
1689 | return 0; | 1805 | return 0; |
1806 | |||
1807 | exit_unreg_isa_driver: | ||
1808 | platform_driver_unregister(&w83781d_isa_driver); | ||
1809 | exit_unreg_i2c_driver: | ||
1810 | i2c_del_driver(&w83781d_driver); | ||
1811 | exit: | ||
1812 | return res; | ||
1690 | } | 1813 | } |
1691 | 1814 | ||
1692 | static void __exit | 1815 | static void __exit |
1693 | sensors_w83781d_exit(void) | 1816 | sensors_w83781d_exit(void) |
1694 | { | 1817 | { |
1695 | if (isa_address) | 1818 | if (pdev) { |
1696 | i2c_isa_del_driver(&w83781d_isa_driver); | 1819 | platform_device_unregister(pdev); |
1820 | platform_driver_unregister(&w83781d_isa_driver); | ||
1821 | } | ||
1697 | i2c_del_driver(&w83781d_driver); | 1822 | i2c_del_driver(&w83781d_driver); |
1698 | } | 1823 | } |
1699 | 1824 | ||