diff options
author | David Hubbard <david.c.hubbard@gmail.com> | 2007-06-24 05:16:15 -0400 |
---|---|---|
committer | Mark M. Hoffman <mhoffman@lightlink.com> | 2007-07-19 14:22:17 -0400 |
commit | 1ea6dd3840e5a22924d78299fee018c82e425d80 (patch) | |
tree | b3b8df56e520717caa6f79e8be1276ba8f4e4957 /drivers/hwmon | |
parent | 658291fc38715c8723372a869c22b700ec41c972 (diff) |
hwmon/w83627ehf: Convert to a platform driver
Remove i2c-isa from the w83627ehf driver, and use a platform driver
instead.
Signed-off-by: David Hubbard <david.c.hubbard@gmail.com>
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Signed-off-by: Mark M. Hoffman <mhoffman@lightlink.com>
Diffstat (limited to 'drivers/hwmon')
-rw-r--r-- | drivers/hwmon/Kconfig | 2 | ||||
-rw-r--r-- | drivers/hwmon/w83627ehf.c | 508 |
2 files changed, 286 insertions, 224 deletions
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index cedd4b7227de..fe7962bada13 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
@@ -618,8 +618,6 @@ config SENSORS_W83627HF | |||
618 | 618 | ||
619 | config SENSORS_W83627EHF | 619 | config SENSORS_W83627EHF |
620 | tristate "Winbond W83627EHF/DHG" | 620 | tristate "Winbond W83627EHF/DHG" |
621 | depends on I2C && EXPERIMENTAL | ||
622 | select I2C_ISA | ||
623 | help | 621 | help |
624 | If you say yes here you get support for the hardware | 622 | If you say yes here you get support for the hardware |
625 | monitoring functionality of the Winbond W83627EHF Super-I/O chip. | 623 | monitoring functionality of the Winbond W83627EHF Super-I/O chip. |
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c index f4d850c71585..2157c3424de1 100644 --- a/drivers/hwmon/w83627ehf.c +++ b/drivers/hwmon/w83627ehf.c | |||
@@ -41,8 +41,8 @@ | |||
41 | #include <linux/module.h> | 41 | #include <linux/module.h> |
42 | #include <linux/init.h> | 42 | #include <linux/init.h> |
43 | #include <linux/slab.h> | 43 | #include <linux/slab.h> |
44 | #include <linux/i2c.h> | 44 | #include <linux/jiffies.h> |
45 | #include <linux/i2c-isa.h> | 45 | #include <linux/platform_device.h> |
46 | #include <linux/hwmon.h> | 46 | #include <linux/hwmon.h> |
47 | #include <linux/hwmon-sysfs.h> | 47 | #include <linux/hwmon-sysfs.h> |
48 | #include <linux/err.h> | 48 | #include <linux/err.h> |
@@ -50,25 +50,19 @@ | |||
50 | #include <asm/io.h> | 50 | #include <asm/io.h> |
51 | #include "lm75.h" | 51 | #include "lm75.h" |
52 | 52 | ||
53 | /* The actual ISA address is read from Super-I/O configuration space */ | 53 | enum kinds { w83627ehf, w83627dhg }; |
54 | static unsigned short address; | ||
55 | 54 | ||
56 | /* | 55 | /* used to set data->name = w83627ehf_device_names[data->sio_kind] */ |
57 | * Super-I/O constants and functions | 56 | static const char * w83627ehf_device_names[] = { |
58 | */ | 57 | "w83627ehf", |
58 | "w83627dhg", | ||
59 | }; | ||
60 | |||
61 | #define DRVNAME "w83627ehf" | ||
59 | 62 | ||
60 | /* | 63 | /* |
61 | * The three following globals are initialized in w83627ehf_find(), before | 64 | * Super-I/O constants and functions |
62 | * the i2c-isa device is created. Otherwise, they could be stored in | ||
63 | * w83627ehf_data. This is ugly, but necessary, and when the driver is next | ||
64 | * updated to become a platform driver, the globals will disappear. | ||
65 | */ | 65 | */ |
66 | static int REG; /* The register to read/write */ | ||
67 | static int VAL; /* The value to read/write */ | ||
68 | /* The w83627ehf/ehg have 10 voltage inputs, but the w83627dhg has 9. This | ||
69 | * value is also used in w83627ehf_detect() to export a device name in sysfs | ||
70 | * (e.g. w83627ehf or w83627dhg) */ | ||
71 | static int w83627ehf_num_in; | ||
72 | 66 | ||
73 | #define W83627EHF_LD_HWM 0x0b | 67 | #define W83627EHF_LD_HWM 0x0b |
74 | 68 | ||
@@ -83,38 +77,38 @@ static int w83627ehf_num_in; | |||
83 | #define SIO_ID_MASK 0xFFF0 | 77 | #define SIO_ID_MASK 0xFFF0 |
84 | 78 | ||
85 | static inline void | 79 | static inline void |
86 | superio_outb(int reg, int val) | 80 | superio_outb(int ioreg, int reg, int val) |
87 | { | 81 | { |
88 | outb(reg, REG); | 82 | outb(reg, ioreg); |
89 | outb(val, VAL); | 83 | outb(val, ioreg + 1); |
90 | } | 84 | } |
91 | 85 | ||
92 | static inline int | 86 | static inline int |
93 | superio_inb(int reg) | 87 | superio_inb(int ioreg, int reg) |
94 | { | 88 | { |
95 | outb(reg, REG); | 89 | outb(reg, ioreg); |
96 | return inb(VAL); | 90 | return inb(ioreg + 1); |
97 | } | 91 | } |
98 | 92 | ||
99 | static inline void | 93 | static inline void |
100 | superio_select(int ld) | 94 | superio_select(int ioreg, int ld) |
101 | { | 95 | { |
102 | outb(SIO_REG_LDSEL, REG); | 96 | outb(SIO_REG_LDSEL, ioreg); |
103 | outb(ld, VAL); | 97 | outb(ld, ioreg + 1); |
104 | } | 98 | } |
105 | 99 | ||
106 | static inline void | 100 | static inline void |
107 | superio_enter(void) | 101 | superio_enter(int ioreg) |
108 | { | 102 | { |
109 | outb(0x87, REG); | 103 | outb(0x87, ioreg); |
110 | outb(0x87, REG); | 104 | outb(0x87, ioreg); |
111 | } | 105 | } |
112 | 106 | ||
113 | static inline void | 107 | static inline void |
114 | superio_exit(void) | 108 | superio_exit(int ioreg) |
115 | { | 109 | { |
116 | outb(0x02, REG); | 110 | outb(0x02, ioreg); |
117 | outb(0x02, VAL); | 111 | outb(0x02, ioreg + 1); |
118 | } | 112 | } |
119 | 113 | ||
120 | /* | 114 | /* |
@@ -124,8 +118,8 @@ superio_exit(void) | |||
124 | #define IOREGION_ALIGNMENT ~7 | 118 | #define IOREGION_ALIGNMENT ~7 |
125 | #define IOREGION_OFFSET 5 | 119 | #define IOREGION_OFFSET 5 |
126 | #define IOREGION_LENGTH 2 | 120 | #define IOREGION_LENGTH 2 |
127 | #define ADDR_REG_OFFSET 5 | 121 | #define ADDR_REG_OFFSET 0 |
128 | #define DATA_REG_OFFSET 6 | 122 | #define DATA_REG_OFFSET 1 |
129 | 123 | ||
130 | #define W83627EHF_REG_BANK 0x4E | 124 | #define W83627EHF_REG_BANK 0x4E |
131 | #define W83627EHF_REG_CONFIG 0x40 | 125 | #define W83627EHF_REG_CONFIG 0x40 |
@@ -255,7 +249,9 @@ static inline u8 in_to_reg(u32 val, u8 nr) | |||
255 | */ | 249 | */ |
256 | 250 | ||
257 | struct w83627ehf_data { | 251 | struct w83627ehf_data { |
258 | struct i2c_client client; | 252 | int addr; /* IO base of hw monitor block */ |
253 | const char *name; | ||
254 | |||
259 | struct class_device *class_dev; | 255 | struct class_device *class_dev; |
260 | struct mutex lock; | 256 | struct mutex lock; |
261 | 257 | ||
@@ -264,6 +260,7 @@ struct w83627ehf_data { | |||
264 | unsigned long last_updated; /* In jiffies */ | 260 | unsigned long last_updated; /* In jiffies */ |
265 | 261 | ||
266 | /* Register values */ | 262 | /* Register values */ |
263 | u8 in_num; /* number of in inputs we have */ | ||
267 | u8 in[10]; /* Register value */ | 264 | u8 in[10]; /* Register value */ |
268 | u8 in_max[10]; /* Register value */ | 265 | u8 in_max[10]; /* Register value */ |
269 | u8 in_min[10]; /* Register value */ | 266 | u8 in_min[10]; /* Register value */ |
@@ -290,6 +287,11 @@ struct w83627ehf_data { | |||
290 | u8 fan_stop_time[4]; | 287 | u8 fan_stop_time[4]; |
291 | }; | 288 | }; |
292 | 289 | ||
290 | struct w83627ehf_sio_data { | ||
291 | int sioreg; | ||
292 | enum kinds kind; | ||
293 | }; | ||
294 | |||
293 | static inline int is_word_sized(u16 reg) | 295 | static inline int is_word_sized(u16 reg) |
294 | { | 296 | { |
295 | return (((reg & 0xff00) == 0x100 | 297 | return (((reg & 0xff00) == 0x100 |
@@ -303,121 +305,117 @@ static inline int is_word_sized(u16 reg) | |||
303 | nothing for registers which live in bank 0. For others, they respectively | 305 | nothing for registers which live in bank 0. For others, they respectively |
304 | set the bank register to the correct value (before the register is | 306 | set the bank register to the correct value (before the register is |
305 | accessed), and back to 0 (afterwards). */ | 307 | accessed), and back to 0 (afterwards). */ |
306 | static inline void w83627ehf_set_bank(struct i2c_client *client, u16 reg) | 308 | static inline void w83627ehf_set_bank(struct w83627ehf_data *data, u16 reg) |
307 | { | 309 | { |
308 | if (reg & 0xff00) { | 310 | if (reg & 0xff00) { |
309 | outb_p(W83627EHF_REG_BANK, client->addr + ADDR_REG_OFFSET); | 311 | outb_p(W83627EHF_REG_BANK, data->addr + ADDR_REG_OFFSET); |
310 | outb_p(reg >> 8, client->addr + DATA_REG_OFFSET); | 312 | outb_p(reg >> 8, data->addr + DATA_REG_OFFSET); |
311 | } | 313 | } |
312 | } | 314 | } |
313 | 315 | ||
314 | static inline void w83627ehf_reset_bank(struct i2c_client *client, u16 reg) | 316 | static inline void w83627ehf_reset_bank(struct w83627ehf_data *data, u16 reg) |
315 | { | 317 | { |
316 | if (reg & 0xff00) { | 318 | if (reg & 0xff00) { |
317 | outb_p(W83627EHF_REG_BANK, client->addr + ADDR_REG_OFFSET); | 319 | outb_p(W83627EHF_REG_BANK, data->addr + ADDR_REG_OFFSET); |
318 | outb_p(0, client->addr + DATA_REG_OFFSET); | 320 | outb_p(0, data->addr + DATA_REG_OFFSET); |
319 | } | 321 | } |
320 | } | 322 | } |
321 | 323 | ||
322 | static u16 w83627ehf_read_value(struct i2c_client *client, u16 reg) | 324 | static u16 w83627ehf_read_value(struct w83627ehf_data *data, u16 reg) |
323 | { | 325 | { |
324 | struct w83627ehf_data *data = i2c_get_clientdata(client); | ||
325 | int res, word_sized = is_word_sized(reg); | 326 | int res, word_sized = is_word_sized(reg); |
326 | 327 | ||
327 | mutex_lock(&data->lock); | 328 | mutex_lock(&data->lock); |
328 | 329 | ||
329 | w83627ehf_set_bank(client, reg); | 330 | w83627ehf_set_bank(data, reg); |
330 | outb_p(reg & 0xff, client->addr + ADDR_REG_OFFSET); | 331 | outb_p(reg & 0xff, data->addr + ADDR_REG_OFFSET); |
331 | res = inb_p(client->addr + DATA_REG_OFFSET); | 332 | res = inb_p(data->addr + DATA_REG_OFFSET); |
332 | if (word_sized) { | 333 | if (word_sized) { |
333 | outb_p((reg & 0xff) + 1, | 334 | outb_p((reg & 0xff) + 1, |
334 | client->addr + ADDR_REG_OFFSET); | 335 | data->addr + ADDR_REG_OFFSET); |
335 | res = (res << 8) + inb_p(client->addr + DATA_REG_OFFSET); | 336 | res = (res << 8) + inb_p(data->addr + DATA_REG_OFFSET); |
336 | } | 337 | } |
337 | w83627ehf_reset_bank(client, reg); | 338 | w83627ehf_reset_bank(data, reg); |
338 | 339 | ||
339 | mutex_unlock(&data->lock); | 340 | mutex_unlock(&data->lock); |
340 | 341 | ||
341 | return res; | 342 | return res; |
342 | } | 343 | } |
343 | 344 | ||
344 | static int w83627ehf_write_value(struct i2c_client *client, u16 reg, u16 value) | 345 | static int w83627ehf_write_value(struct w83627ehf_data *data, u16 reg, u16 value) |
345 | { | 346 | { |
346 | struct w83627ehf_data *data = i2c_get_clientdata(client); | ||
347 | int word_sized = is_word_sized(reg); | 347 | int word_sized = is_word_sized(reg); |
348 | 348 | ||
349 | mutex_lock(&data->lock); | 349 | mutex_lock(&data->lock); |
350 | 350 | ||
351 | w83627ehf_set_bank(client, reg); | 351 | w83627ehf_set_bank(data, reg); |
352 | outb_p(reg & 0xff, client->addr + ADDR_REG_OFFSET); | 352 | outb_p(reg & 0xff, data->addr + ADDR_REG_OFFSET); |
353 | if (word_sized) { | 353 | if (word_sized) { |
354 | outb_p(value >> 8, client->addr + DATA_REG_OFFSET); | 354 | outb_p(value >> 8, data->addr + DATA_REG_OFFSET); |
355 | outb_p((reg & 0xff) + 1, | 355 | outb_p((reg & 0xff) + 1, |
356 | client->addr + ADDR_REG_OFFSET); | 356 | data->addr + ADDR_REG_OFFSET); |
357 | } | 357 | } |
358 | outb_p(value & 0xff, client->addr + DATA_REG_OFFSET); | 358 | outb_p(value & 0xff, data->addr + DATA_REG_OFFSET); |
359 | w83627ehf_reset_bank(client, reg); | 359 | w83627ehf_reset_bank(data, reg); |
360 | 360 | ||
361 | mutex_unlock(&data->lock); | 361 | mutex_unlock(&data->lock); |
362 | return 0; | 362 | return 0; |
363 | } | 363 | } |
364 | 364 | ||
365 | /* This function assumes that the caller holds data->update_lock */ | 365 | /* This function assumes that the caller holds data->update_lock */ |
366 | static void w83627ehf_write_fan_div(struct i2c_client *client, int nr) | 366 | static void w83627ehf_write_fan_div(struct w83627ehf_data *data, int nr) |
367 | { | 367 | { |
368 | struct w83627ehf_data *data = i2c_get_clientdata(client); | ||
369 | u8 reg; | 368 | u8 reg; |
370 | 369 | ||
371 | switch (nr) { | 370 | switch (nr) { |
372 | case 0: | 371 | case 0: |
373 | reg = (w83627ehf_read_value(client, W83627EHF_REG_FANDIV1) & 0xcf) | 372 | reg = (w83627ehf_read_value(data, W83627EHF_REG_FANDIV1) & 0xcf) |
374 | | ((data->fan_div[0] & 0x03) << 4); | 373 | | ((data->fan_div[0] & 0x03) << 4); |
375 | /* fan5 input control bit is write only, compute the value */ | 374 | /* fan5 input control bit is write only, compute the value */ |
376 | reg |= (data->has_fan & (1 << 4)) ? 1 : 0; | 375 | reg |= (data->has_fan & (1 << 4)) ? 1 : 0; |
377 | w83627ehf_write_value(client, W83627EHF_REG_FANDIV1, reg); | 376 | w83627ehf_write_value(data, W83627EHF_REG_FANDIV1, reg); |
378 | reg = (w83627ehf_read_value(client, W83627EHF_REG_VBAT) & 0xdf) | 377 | reg = (w83627ehf_read_value(data, W83627EHF_REG_VBAT) & 0xdf) |
379 | | ((data->fan_div[0] & 0x04) << 3); | 378 | | ((data->fan_div[0] & 0x04) << 3); |
380 | w83627ehf_write_value(client, W83627EHF_REG_VBAT, reg); | 379 | w83627ehf_write_value(data, W83627EHF_REG_VBAT, reg); |
381 | break; | 380 | break; |
382 | case 1: | 381 | case 1: |
383 | reg = (w83627ehf_read_value(client, W83627EHF_REG_FANDIV1) & 0x3f) | 382 | reg = (w83627ehf_read_value(data, W83627EHF_REG_FANDIV1) & 0x3f) |
384 | | ((data->fan_div[1] & 0x03) << 6); | 383 | | ((data->fan_div[1] & 0x03) << 6); |
385 | /* fan5 input control bit is write only, compute the value */ | 384 | /* fan5 input control bit is write only, compute the value */ |
386 | reg |= (data->has_fan & (1 << 4)) ? 1 : 0; | 385 | reg |= (data->has_fan & (1 << 4)) ? 1 : 0; |
387 | w83627ehf_write_value(client, W83627EHF_REG_FANDIV1, reg); | 386 | w83627ehf_write_value(data, W83627EHF_REG_FANDIV1, reg); |
388 | reg = (w83627ehf_read_value(client, W83627EHF_REG_VBAT) & 0xbf) | 387 | reg = (w83627ehf_read_value(data, W83627EHF_REG_VBAT) & 0xbf) |
389 | | ((data->fan_div[1] & 0x04) << 4); | 388 | | ((data->fan_div[1] & 0x04) << 4); |
390 | w83627ehf_write_value(client, W83627EHF_REG_VBAT, reg); | 389 | w83627ehf_write_value(data, W83627EHF_REG_VBAT, reg); |
391 | break; | 390 | break; |
392 | case 2: | 391 | case 2: |
393 | reg = (w83627ehf_read_value(client, W83627EHF_REG_FANDIV2) & 0x3f) | 392 | reg = (w83627ehf_read_value(data, W83627EHF_REG_FANDIV2) & 0x3f) |
394 | | ((data->fan_div[2] & 0x03) << 6); | 393 | | ((data->fan_div[2] & 0x03) << 6); |
395 | w83627ehf_write_value(client, W83627EHF_REG_FANDIV2, reg); | 394 | w83627ehf_write_value(data, W83627EHF_REG_FANDIV2, reg); |
396 | reg = (w83627ehf_read_value(client, W83627EHF_REG_VBAT) & 0x7f) | 395 | reg = (w83627ehf_read_value(data, W83627EHF_REG_VBAT) & 0x7f) |
397 | | ((data->fan_div[2] & 0x04) << 5); | 396 | | ((data->fan_div[2] & 0x04) << 5); |
398 | w83627ehf_write_value(client, W83627EHF_REG_VBAT, reg); | 397 | w83627ehf_write_value(data, W83627EHF_REG_VBAT, reg); |
399 | break; | 398 | break; |
400 | case 3: | 399 | case 3: |
401 | reg = (w83627ehf_read_value(client, W83627EHF_REG_DIODE) & 0xfc) | 400 | reg = (w83627ehf_read_value(data, W83627EHF_REG_DIODE) & 0xfc) |
402 | | (data->fan_div[3] & 0x03); | 401 | | (data->fan_div[3] & 0x03); |
403 | w83627ehf_write_value(client, W83627EHF_REG_DIODE, reg); | 402 | w83627ehf_write_value(data, W83627EHF_REG_DIODE, reg); |
404 | reg = (w83627ehf_read_value(client, W83627EHF_REG_SMI_OVT) & 0x7f) | 403 | reg = (w83627ehf_read_value(data, W83627EHF_REG_SMI_OVT) & 0x7f) |
405 | | ((data->fan_div[3] & 0x04) << 5); | 404 | | ((data->fan_div[3] & 0x04) << 5); |
406 | w83627ehf_write_value(client, W83627EHF_REG_SMI_OVT, reg); | 405 | w83627ehf_write_value(data, W83627EHF_REG_SMI_OVT, reg); |
407 | break; | 406 | break; |
408 | case 4: | 407 | case 4: |
409 | reg = (w83627ehf_read_value(client, W83627EHF_REG_DIODE) & 0x73) | 408 | reg = (w83627ehf_read_value(data, W83627EHF_REG_DIODE) & 0x73) |
410 | | ((data->fan_div[4] & 0x03) << 2) | 409 | | ((data->fan_div[4] & 0x03) << 2) |
411 | | ((data->fan_div[4] & 0x04) << 5); | 410 | | ((data->fan_div[4] & 0x04) << 5); |
412 | w83627ehf_write_value(client, W83627EHF_REG_DIODE, reg); | 411 | w83627ehf_write_value(data, W83627EHF_REG_DIODE, reg); |
413 | break; | 412 | break; |
414 | } | 413 | } |
415 | } | 414 | } |
416 | 415 | ||
417 | static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) | 416 | static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) |
418 | { | 417 | { |
419 | struct i2c_client *client = to_i2c_client(dev); | 418 | struct w83627ehf_data *data = dev_get_drvdata(dev); |
420 | struct w83627ehf_data *data = i2c_get_clientdata(client); | ||
421 | int pwmcfg = 0, tolerance = 0; /* shut up the compiler */ | 419 | int pwmcfg = 0, tolerance = 0; /* shut up the compiler */ |
422 | int i; | 420 | int i; |
423 | 421 | ||
@@ -426,33 +424,33 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) | |||
426 | if (time_after(jiffies, data->last_updated + HZ) | 424 | if (time_after(jiffies, data->last_updated + HZ) |
427 | || !data->valid) { | 425 | || !data->valid) { |
428 | /* Fan clock dividers */ | 426 | /* Fan clock dividers */ |
429 | i = w83627ehf_read_value(client, W83627EHF_REG_FANDIV1); | 427 | i = w83627ehf_read_value(data, W83627EHF_REG_FANDIV1); |
430 | data->fan_div[0] = (i >> 4) & 0x03; | 428 | data->fan_div[0] = (i >> 4) & 0x03; |
431 | data->fan_div[1] = (i >> 6) & 0x03; | 429 | data->fan_div[1] = (i >> 6) & 0x03; |
432 | i = w83627ehf_read_value(client, W83627EHF_REG_FANDIV2); | 430 | i = w83627ehf_read_value(data, W83627EHF_REG_FANDIV2); |
433 | data->fan_div[2] = (i >> 6) & 0x03; | 431 | data->fan_div[2] = (i >> 6) & 0x03; |
434 | i = w83627ehf_read_value(client, W83627EHF_REG_VBAT); | 432 | i = w83627ehf_read_value(data, W83627EHF_REG_VBAT); |
435 | data->fan_div[0] |= (i >> 3) & 0x04; | 433 | data->fan_div[0] |= (i >> 3) & 0x04; |
436 | data->fan_div[1] |= (i >> 4) & 0x04; | 434 | data->fan_div[1] |= (i >> 4) & 0x04; |
437 | data->fan_div[2] |= (i >> 5) & 0x04; | 435 | data->fan_div[2] |= (i >> 5) & 0x04; |
438 | if (data->has_fan & ((1 << 3) | (1 << 4))) { | 436 | if (data->has_fan & ((1 << 3) | (1 << 4))) { |
439 | i = w83627ehf_read_value(client, W83627EHF_REG_DIODE); | 437 | i = w83627ehf_read_value(data, W83627EHF_REG_DIODE); |
440 | data->fan_div[3] = i & 0x03; | 438 | data->fan_div[3] = i & 0x03; |
441 | data->fan_div[4] = ((i >> 2) & 0x03) | 439 | data->fan_div[4] = ((i >> 2) & 0x03) |
442 | | ((i >> 5) & 0x04); | 440 | | ((i >> 5) & 0x04); |
443 | } | 441 | } |
444 | if (data->has_fan & (1 << 3)) { | 442 | if (data->has_fan & (1 << 3)) { |
445 | i = w83627ehf_read_value(client, W83627EHF_REG_SMI_OVT); | 443 | i = w83627ehf_read_value(data, W83627EHF_REG_SMI_OVT); |
446 | data->fan_div[3] |= (i >> 5) & 0x04; | 444 | data->fan_div[3] |= (i >> 5) & 0x04; |
447 | } | 445 | } |
448 | 446 | ||
449 | /* Measured voltages and limits */ | 447 | /* Measured voltages and limits */ |
450 | for (i = 0; i < w83627ehf_num_in; i++) { | 448 | for (i = 0; i < data->in_num; i++) { |
451 | data->in[i] = w83627ehf_read_value(client, | 449 | data->in[i] = w83627ehf_read_value(data, |
452 | W83627EHF_REG_IN(i)); | 450 | W83627EHF_REG_IN(i)); |
453 | data->in_min[i] = w83627ehf_read_value(client, | 451 | data->in_min[i] = w83627ehf_read_value(data, |
454 | W83627EHF_REG_IN_MIN(i)); | 452 | W83627EHF_REG_IN_MIN(i)); |
455 | data->in_max[i] = w83627ehf_read_value(client, | 453 | data->in_max[i] = w83627ehf_read_value(data, |
456 | W83627EHF_REG_IN_MAX(i)); | 454 | W83627EHF_REG_IN_MAX(i)); |
457 | } | 455 | } |
458 | 456 | ||
@@ -461,9 +459,9 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) | |||
461 | if (!(data->has_fan & (1 << i))) | 459 | if (!(data->has_fan & (1 << i))) |
462 | continue; | 460 | continue; |
463 | 461 | ||
464 | data->fan[i] = w83627ehf_read_value(client, | 462 | data->fan[i] = w83627ehf_read_value(data, |
465 | W83627EHF_REG_FAN[i]); | 463 | W83627EHF_REG_FAN[i]); |
466 | data->fan_min[i] = w83627ehf_read_value(client, | 464 | data->fan_min[i] = w83627ehf_read_value(data, |
467 | W83627EHF_REG_FAN_MIN[i]); | 465 | W83627EHF_REG_FAN_MIN[i]); |
468 | 466 | ||
469 | /* If we failed to measure the fan speed and clock | 467 | /* If we failed to measure the fan speed and clock |
@@ -471,16 +469,16 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) | |||
471 | time */ | 469 | time */ |
472 | if (data->fan[i] == 0xff | 470 | if (data->fan[i] == 0xff |
473 | && data->fan_div[i] < 0x07) { | 471 | && data->fan_div[i] < 0x07) { |
474 | dev_dbg(&client->dev, "Increasing fan%d " | 472 | dev_dbg(dev, "Increasing fan%d " |
475 | "clock divider from %u to %u\n", | 473 | "clock divider from %u to %u\n", |
476 | i + 1, div_from_reg(data->fan_div[i]), | 474 | i + 1, div_from_reg(data->fan_div[i]), |
477 | div_from_reg(data->fan_div[i] + 1)); | 475 | div_from_reg(data->fan_div[i] + 1)); |
478 | data->fan_div[i]++; | 476 | data->fan_div[i]++; |
479 | w83627ehf_write_fan_div(client, i); | 477 | w83627ehf_write_fan_div(data, i); |
480 | /* Preserve min limit if possible */ | 478 | /* Preserve min limit if possible */ |
481 | if (data->fan_min[i] >= 2 | 479 | if (data->fan_min[i] >= 2 |
482 | && data->fan_min[i] != 255) | 480 | && data->fan_min[i] != 255) |
483 | w83627ehf_write_value(client, | 481 | w83627ehf_write_value(data, |
484 | W83627EHF_REG_FAN_MIN[i], | 482 | W83627EHF_REG_FAN_MIN[i], |
485 | (data->fan_min[i] /= 2)); | 483 | (data->fan_min[i] /= 2)); |
486 | } | 484 | } |
@@ -489,9 +487,9 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) | |||
489 | for (i = 0; i < 4; i++) { | 487 | for (i = 0; i < 4; i++) { |
490 | /* pwmcfg, tolarance mapped for i=0, i=1 to same reg */ | 488 | /* pwmcfg, tolarance mapped for i=0, i=1 to same reg */ |
491 | if (i != 1) { | 489 | if (i != 1) { |
492 | pwmcfg = w83627ehf_read_value(client, | 490 | pwmcfg = w83627ehf_read_value(data, |
493 | W83627EHF_REG_PWM_ENABLE[i]); | 491 | W83627EHF_REG_PWM_ENABLE[i]); |
494 | tolerance = w83627ehf_read_value(client, | 492 | tolerance = w83627ehf_read_value(data, |
495 | W83627EHF_REG_TOLERANCE[i]); | 493 | W83627EHF_REG_TOLERANCE[i]); |
496 | } | 494 | } |
497 | data->pwm_mode[i] = | 495 | data->pwm_mode[i] = |
@@ -500,14 +498,14 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) | |||
500 | data->pwm_enable[i] = | 498 | data->pwm_enable[i] = |
501 | ((pwmcfg >> W83627EHF_PWM_ENABLE_SHIFT[i]) | 499 | ((pwmcfg >> W83627EHF_PWM_ENABLE_SHIFT[i]) |
502 | & 3) + 1; | 500 | & 3) + 1; |
503 | data->pwm[i] = w83627ehf_read_value(client, | 501 | data->pwm[i] = w83627ehf_read_value(data, |
504 | W83627EHF_REG_PWM[i]); | 502 | W83627EHF_REG_PWM[i]); |
505 | data->fan_min_output[i] = w83627ehf_read_value(client, | 503 | data->fan_min_output[i] = w83627ehf_read_value(data, |
506 | W83627EHF_REG_FAN_MIN_OUTPUT[i]); | 504 | W83627EHF_REG_FAN_MIN_OUTPUT[i]); |
507 | data->fan_stop_time[i] = w83627ehf_read_value(client, | 505 | data->fan_stop_time[i] = w83627ehf_read_value(data, |
508 | W83627EHF_REG_FAN_STOP_TIME[i]); | 506 | W83627EHF_REG_FAN_STOP_TIME[i]); |
509 | data->target_temp[i] = | 507 | data->target_temp[i] = |
510 | w83627ehf_read_value(client, | 508 | w83627ehf_read_value(data, |
511 | W83627EHF_REG_TARGET[i]) & | 509 | W83627EHF_REG_TARGET[i]) & |
512 | (data->pwm_mode[i] == 1 ? 0x7f : 0xff); | 510 | (data->pwm_mode[i] == 1 ? 0x7f : 0xff); |
513 | data->tolerance[i] = (tolerance >> (i == 1 ? 4 : 0)) | 511 | data->tolerance[i] = (tolerance >> (i == 1 ? 4 : 0)) |
@@ -515,26 +513,26 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) | |||
515 | } | 513 | } |
516 | 514 | ||
517 | /* Measured temperatures and limits */ | 515 | /* Measured temperatures and limits */ |
518 | data->temp1 = w83627ehf_read_value(client, | 516 | data->temp1 = w83627ehf_read_value(data, |
519 | W83627EHF_REG_TEMP1); | 517 | W83627EHF_REG_TEMP1); |
520 | data->temp1_max = w83627ehf_read_value(client, | 518 | data->temp1_max = w83627ehf_read_value(data, |
521 | W83627EHF_REG_TEMP1_OVER); | 519 | W83627EHF_REG_TEMP1_OVER); |
522 | data->temp1_max_hyst = w83627ehf_read_value(client, | 520 | data->temp1_max_hyst = w83627ehf_read_value(data, |
523 | W83627EHF_REG_TEMP1_HYST); | 521 | W83627EHF_REG_TEMP1_HYST); |
524 | for (i = 0; i < 2; i++) { | 522 | for (i = 0; i < 2; i++) { |
525 | data->temp[i] = w83627ehf_read_value(client, | 523 | data->temp[i] = w83627ehf_read_value(data, |
526 | W83627EHF_REG_TEMP[i]); | 524 | W83627EHF_REG_TEMP[i]); |
527 | data->temp_max[i] = w83627ehf_read_value(client, | 525 | data->temp_max[i] = w83627ehf_read_value(data, |
528 | W83627EHF_REG_TEMP_OVER[i]); | 526 | W83627EHF_REG_TEMP_OVER[i]); |
529 | data->temp_max_hyst[i] = w83627ehf_read_value(client, | 527 | data->temp_max_hyst[i] = w83627ehf_read_value(data, |
530 | W83627EHF_REG_TEMP_HYST[i]); | 528 | W83627EHF_REG_TEMP_HYST[i]); |
531 | } | 529 | } |
532 | 530 | ||
533 | data->alarms = w83627ehf_read_value(client, | 531 | data->alarms = w83627ehf_read_value(data, |
534 | W83627EHF_REG_ALARM1) | | 532 | W83627EHF_REG_ALARM1) | |
535 | (w83627ehf_read_value(client, | 533 | (w83627ehf_read_value(data, |
536 | W83627EHF_REG_ALARM2) << 8) | | 534 | W83627EHF_REG_ALARM2) << 8) | |
537 | (w83627ehf_read_value(client, | 535 | (w83627ehf_read_value(data, |
538 | W83627EHF_REG_ALARM3) << 16); | 536 | W83627EHF_REG_ALARM3) << 16); |
539 | 537 | ||
540 | data->last_updated = jiffies; | 538 | data->last_updated = jiffies; |
@@ -567,15 +565,14 @@ static ssize_t \ | |||
567 | store_in_##reg (struct device *dev, struct device_attribute *attr, \ | 565 | store_in_##reg (struct device *dev, struct device_attribute *attr, \ |
568 | const char *buf, size_t count) \ | 566 | const char *buf, size_t count) \ |
569 | { \ | 567 | { \ |
570 | struct i2c_client *client = to_i2c_client(dev); \ | 568 | struct w83627ehf_data *data = dev_get_drvdata(dev); \ |
571 | struct w83627ehf_data *data = i2c_get_clientdata(client); \ | ||
572 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ | 569 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ |
573 | int nr = sensor_attr->index; \ | 570 | int nr = sensor_attr->index; \ |
574 | u32 val = simple_strtoul(buf, NULL, 10); \ | 571 | u32 val = simple_strtoul(buf, NULL, 10); \ |
575 | \ | 572 | \ |
576 | mutex_lock(&data->update_lock); \ | 573 | mutex_lock(&data->update_lock); \ |
577 | data->in_##reg[nr] = in_to_reg(val, nr); \ | 574 | data->in_##reg[nr] = in_to_reg(val, nr); \ |
578 | w83627ehf_write_value(client, W83627EHF_REG_IN_##REG(nr), \ | 575 | w83627ehf_write_value(data, W83627EHF_REG_IN_##REG(nr), \ |
579 | data->in_##reg[nr]); \ | 576 | data->in_##reg[nr]); \ |
580 | mutex_unlock(&data->update_lock); \ | 577 | mutex_unlock(&data->update_lock); \ |
581 | return count; \ | 578 | return count; \ |
@@ -673,8 +670,7 @@ static ssize_t | |||
673 | store_fan_min(struct device *dev, struct device_attribute *attr, | 670 | store_fan_min(struct device *dev, struct device_attribute *attr, |
674 | const char *buf, size_t count) | 671 | const char *buf, size_t count) |
675 | { | 672 | { |
676 | struct i2c_client *client = to_i2c_client(dev); | 673 | struct w83627ehf_data *data = dev_get_drvdata(dev); |
677 | struct w83627ehf_data *data = i2c_get_clientdata(client); | ||
678 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 674 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
679 | int nr = sensor_attr->index; | 675 | int nr = sensor_attr->index; |
680 | unsigned int val = simple_strtoul(buf, NULL, 10); | 676 | unsigned int val = simple_strtoul(buf, NULL, 10); |
@@ -730,9 +726,9 @@ store_fan_min(struct device *dev, struct device_attribute *attr, | |||
730 | nr + 1, div_from_reg(data->fan_div[nr]), | 726 | nr + 1, div_from_reg(data->fan_div[nr]), |
731 | div_from_reg(new_div)); | 727 | div_from_reg(new_div)); |
732 | data->fan_div[nr] = new_div; | 728 | data->fan_div[nr] = new_div; |
733 | w83627ehf_write_fan_div(client, nr); | 729 | w83627ehf_write_fan_div(data, nr); |
734 | } | 730 | } |
735 | w83627ehf_write_value(client, W83627EHF_REG_FAN_MIN[nr], | 731 | w83627ehf_write_value(data, W83627EHF_REG_FAN_MIN[nr], |
736 | data->fan_min[nr]); | 732 | data->fan_min[nr]); |
737 | mutex_unlock(&data->update_lock); | 733 | mutex_unlock(&data->update_lock); |
738 | 734 | ||
@@ -793,13 +789,12 @@ static ssize_t \ | |||
793 | store_temp1_##reg(struct device *dev, struct device_attribute *attr, \ | 789 | store_temp1_##reg(struct device *dev, struct device_attribute *attr, \ |
794 | const char *buf, size_t count) \ | 790 | const char *buf, size_t count) \ |
795 | { \ | 791 | { \ |
796 | struct i2c_client *client = to_i2c_client(dev); \ | 792 | struct w83627ehf_data *data = dev_get_drvdata(dev); \ |
797 | struct w83627ehf_data *data = i2c_get_clientdata(client); \ | ||
798 | u32 val = simple_strtoul(buf, NULL, 10); \ | 793 | u32 val = simple_strtoul(buf, NULL, 10); \ |
799 | \ | 794 | \ |
800 | mutex_lock(&data->update_lock); \ | 795 | mutex_lock(&data->update_lock); \ |
801 | data->temp1_##reg = temp1_to_reg(val, -128000, 127000); \ | 796 | data->temp1_##reg = temp1_to_reg(val, -128000, 127000); \ |
802 | w83627ehf_write_value(client, W83627EHF_REG_TEMP1_##REG, \ | 797 | w83627ehf_write_value(data, W83627EHF_REG_TEMP1_##REG, \ |
803 | data->temp1_##reg); \ | 798 | data->temp1_##reg); \ |
804 | mutex_unlock(&data->update_lock); \ | 799 | mutex_unlock(&data->update_lock); \ |
805 | return count; \ | 800 | return count; \ |
@@ -827,15 +822,14 @@ static ssize_t \ | |||
827 | store_##reg(struct device *dev, struct device_attribute *attr, \ | 822 | store_##reg(struct device *dev, struct device_attribute *attr, \ |
828 | const char *buf, size_t count) \ | 823 | const char *buf, size_t count) \ |
829 | { \ | 824 | { \ |
830 | struct i2c_client *client = to_i2c_client(dev); \ | 825 | struct w83627ehf_data *data = dev_get_drvdata(dev); \ |
831 | struct w83627ehf_data *data = i2c_get_clientdata(client); \ | ||
832 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ | 826 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ |
833 | int nr = sensor_attr->index; \ | 827 | int nr = sensor_attr->index; \ |
834 | u32 val = simple_strtoul(buf, NULL, 10); \ | 828 | u32 val = simple_strtoul(buf, NULL, 10); \ |
835 | \ | 829 | \ |
836 | mutex_lock(&data->update_lock); \ | 830 | mutex_lock(&data->update_lock); \ |
837 | data->reg[nr] = LM75_TEMP_TO_REG(val); \ | 831 | data->reg[nr] = LM75_TEMP_TO_REG(val); \ |
838 | w83627ehf_write_value(client, W83627EHF_REG_TEMP_##REG[nr], \ | 832 | w83627ehf_write_value(data, W83627EHF_REG_TEMP_##REG[nr], \ |
839 | data->reg[nr]); \ | 833 | data->reg[nr]); \ |
840 | mutex_unlock(&data->update_lock); \ | 834 | mutex_unlock(&data->update_lock); \ |
841 | return count; \ | 835 | return count; \ |
@@ -882,8 +876,7 @@ static ssize_t | |||
882 | store_pwm_mode(struct device *dev, struct device_attribute *attr, | 876 | store_pwm_mode(struct device *dev, struct device_attribute *attr, |
883 | const char *buf, size_t count) | 877 | const char *buf, size_t count) |
884 | { | 878 | { |
885 | struct i2c_client *client = to_i2c_client(dev); | 879 | struct w83627ehf_data *data = dev_get_drvdata(dev); |
886 | struct w83627ehf_data *data = i2c_get_clientdata(client); | ||
887 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 880 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
888 | int nr = sensor_attr->index; | 881 | int nr = sensor_attr->index; |
889 | u32 val = simple_strtoul(buf, NULL, 10); | 882 | u32 val = simple_strtoul(buf, NULL, 10); |
@@ -892,12 +885,12 @@ store_pwm_mode(struct device *dev, struct device_attribute *attr, | |||
892 | if (val > 1) | 885 | if (val > 1) |
893 | return -EINVAL; | 886 | return -EINVAL; |
894 | mutex_lock(&data->update_lock); | 887 | mutex_lock(&data->update_lock); |
895 | reg = w83627ehf_read_value(client, W83627EHF_REG_PWM_ENABLE[nr]); | 888 | reg = w83627ehf_read_value(data, W83627EHF_REG_PWM_ENABLE[nr]); |
896 | data->pwm_mode[nr] = val; | 889 | data->pwm_mode[nr] = val; |
897 | reg &= ~(1 << W83627EHF_PWM_MODE_SHIFT[nr]); | 890 | reg &= ~(1 << W83627EHF_PWM_MODE_SHIFT[nr]); |
898 | if (!val) | 891 | if (!val) |
899 | reg |= 1 << W83627EHF_PWM_MODE_SHIFT[nr]; | 892 | reg |= 1 << W83627EHF_PWM_MODE_SHIFT[nr]; |
900 | w83627ehf_write_value(client, W83627EHF_REG_PWM_ENABLE[nr], reg); | 893 | w83627ehf_write_value(data, W83627EHF_REG_PWM_ENABLE[nr], reg); |
901 | mutex_unlock(&data->update_lock); | 894 | mutex_unlock(&data->update_lock); |
902 | return count; | 895 | return count; |
903 | } | 896 | } |
@@ -906,15 +899,14 @@ static ssize_t | |||
906 | store_pwm(struct device *dev, struct device_attribute *attr, | 899 | store_pwm(struct device *dev, struct device_attribute *attr, |
907 | const char *buf, size_t count) | 900 | const char *buf, size_t count) |
908 | { | 901 | { |
909 | struct i2c_client *client = to_i2c_client(dev); | 902 | struct w83627ehf_data *data = dev_get_drvdata(dev); |
910 | struct w83627ehf_data *data = i2c_get_clientdata(client); | ||
911 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 903 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
912 | int nr = sensor_attr->index; | 904 | int nr = sensor_attr->index; |
913 | u32 val = SENSORS_LIMIT(simple_strtoul(buf, NULL, 10), 0, 255); | 905 | u32 val = SENSORS_LIMIT(simple_strtoul(buf, NULL, 10), 0, 255); |
914 | 906 | ||
915 | mutex_lock(&data->update_lock); | 907 | mutex_lock(&data->update_lock); |
916 | data->pwm[nr] = val; | 908 | data->pwm[nr] = val; |
917 | w83627ehf_write_value(client, W83627EHF_REG_PWM[nr], val); | 909 | w83627ehf_write_value(data, W83627EHF_REG_PWM[nr], val); |
918 | mutex_unlock(&data->update_lock); | 910 | mutex_unlock(&data->update_lock); |
919 | return count; | 911 | return count; |
920 | } | 912 | } |
@@ -923,8 +915,7 @@ static ssize_t | |||
923 | store_pwm_enable(struct device *dev, struct device_attribute *attr, | 915 | store_pwm_enable(struct device *dev, struct device_attribute *attr, |
924 | const char *buf, size_t count) | 916 | const char *buf, size_t count) |
925 | { | 917 | { |
926 | struct i2c_client *client = to_i2c_client(dev); | 918 | struct w83627ehf_data *data = dev_get_drvdata(dev); |
927 | struct w83627ehf_data *data = i2c_get_clientdata(client); | ||
928 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 919 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
929 | int nr = sensor_attr->index; | 920 | int nr = sensor_attr->index; |
930 | u32 val = simple_strtoul(buf, NULL, 10); | 921 | u32 val = simple_strtoul(buf, NULL, 10); |
@@ -933,11 +924,11 @@ store_pwm_enable(struct device *dev, struct device_attribute *attr, | |||
933 | if (!val || (val > 2)) /* only modes 1 and 2 are supported */ | 924 | if (!val || (val > 2)) /* only modes 1 and 2 are supported */ |
934 | return -EINVAL; | 925 | return -EINVAL; |
935 | mutex_lock(&data->update_lock); | 926 | mutex_lock(&data->update_lock); |
936 | reg = w83627ehf_read_value(client, W83627EHF_REG_PWM_ENABLE[nr]); | 927 | reg = w83627ehf_read_value(data, W83627EHF_REG_PWM_ENABLE[nr]); |
937 | data->pwm_enable[nr] = val; | 928 | data->pwm_enable[nr] = val; |
938 | reg &= ~(0x03 << W83627EHF_PWM_ENABLE_SHIFT[nr]); | 929 | reg &= ~(0x03 << W83627EHF_PWM_ENABLE_SHIFT[nr]); |
939 | reg |= (val - 1) << W83627EHF_PWM_ENABLE_SHIFT[nr]; | 930 | reg |= (val - 1) << W83627EHF_PWM_ENABLE_SHIFT[nr]; |
940 | w83627ehf_write_value(client, W83627EHF_REG_PWM_ENABLE[nr], reg); | 931 | w83627ehf_write_value(data, W83627EHF_REG_PWM_ENABLE[nr], reg); |
941 | mutex_unlock(&data->update_lock); | 932 | mutex_unlock(&data->update_lock); |
942 | return count; | 933 | return count; |
943 | } | 934 | } |
@@ -960,15 +951,14 @@ static ssize_t | |||
960 | store_target_temp(struct device *dev, struct device_attribute *attr, | 951 | store_target_temp(struct device *dev, struct device_attribute *attr, |
961 | const char *buf, size_t count) | 952 | const char *buf, size_t count) |
962 | { | 953 | { |
963 | struct i2c_client *client = to_i2c_client(dev); | 954 | struct w83627ehf_data *data = dev_get_drvdata(dev); |
964 | struct w83627ehf_data *data = i2c_get_clientdata(client); | ||
965 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 955 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
966 | int nr = sensor_attr->index; | 956 | int nr = sensor_attr->index; |
967 | u8 val = temp1_to_reg(simple_strtoul(buf, NULL, 10), 0, 127000); | 957 | u8 val = temp1_to_reg(simple_strtoul(buf, NULL, 10), 0, 127000); |
968 | 958 | ||
969 | mutex_lock(&data->update_lock); | 959 | mutex_lock(&data->update_lock); |
970 | data->target_temp[nr] = val; | 960 | data->target_temp[nr] = val; |
971 | w83627ehf_write_value(client, W83627EHF_REG_TARGET[nr], val); | 961 | w83627ehf_write_value(data, W83627EHF_REG_TARGET[nr], val); |
972 | mutex_unlock(&data->update_lock); | 962 | mutex_unlock(&data->update_lock); |
973 | return count; | 963 | return count; |
974 | } | 964 | } |
@@ -977,8 +967,7 @@ static ssize_t | |||
977 | store_tolerance(struct device *dev, struct device_attribute *attr, | 967 | store_tolerance(struct device *dev, struct device_attribute *attr, |
978 | const char *buf, size_t count) | 968 | const char *buf, size_t count) |
979 | { | 969 | { |
980 | struct i2c_client *client = to_i2c_client(dev); | 970 | struct w83627ehf_data *data = dev_get_drvdata(dev); |
981 | struct w83627ehf_data *data = i2c_get_clientdata(client); | ||
982 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 971 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
983 | int nr = sensor_attr->index; | 972 | int nr = sensor_attr->index; |
984 | u16 reg; | 973 | u16 reg; |
@@ -986,13 +975,13 @@ store_tolerance(struct device *dev, struct device_attribute *attr, | |||
986 | u8 val = temp1_to_reg(simple_strtoul(buf, NULL, 10), 0, 15000); | 975 | u8 val = temp1_to_reg(simple_strtoul(buf, NULL, 10), 0, 15000); |
987 | 976 | ||
988 | mutex_lock(&data->update_lock); | 977 | mutex_lock(&data->update_lock); |
989 | reg = w83627ehf_read_value(client, W83627EHF_REG_TOLERANCE[nr]); | 978 | reg = w83627ehf_read_value(data, W83627EHF_REG_TOLERANCE[nr]); |
990 | data->tolerance[nr] = val; | 979 | data->tolerance[nr] = val; |
991 | if (nr == 1) | 980 | if (nr == 1) |
992 | reg = (reg & 0x0f) | (val << 4); | 981 | reg = (reg & 0x0f) | (val << 4); |
993 | else | 982 | else |
994 | reg = (reg & 0xf0) | val; | 983 | reg = (reg & 0xf0) | val; |
995 | w83627ehf_write_value(client, W83627EHF_REG_TOLERANCE[nr], reg); | 984 | w83627ehf_write_value(data, W83627EHF_REG_TOLERANCE[nr], reg); |
996 | mutex_unlock(&data->update_lock); | 985 | mutex_unlock(&data->update_lock); |
997 | return count; | 986 | return count; |
998 | } | 987 | } |
@@ -1063,14 +1052,13 @@ static ssize_t \ | |||
1063 | store_##reg(struct device *dev, struct device_attribute *attr, \ | 1052 | store_##reg(struct device *dev, struct device_attribute *attr, \ |
1064 | const char *buf, size_t count) \ | 1053 | const char *buf, size_t count) \ |
1065 | {\ | 1054 | {\ |
1066 | struct i2c_client *client = to_i2c_client(dev); \ | 1055 | struct w83627ehf_data *data = dev_get_drvdata(dev); \ |
1067 | struct w83627ehf_data *data = i2c_get_clientdata(client); \ | ||
1068 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ | 1056 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ |
1069 | int nr = sensor_attr->index; \ | 1057 | int nr = sensor_attr->index; \ |
1070 | u32 val = SENSORS_LIMIT(simple_strtoul(buf, NULL, 10), 1, 255); \ | 1058 | u32 val = SENSORS_LIMIT(simple_strtoul(buf, NULL, 10), 1, 255); \ |
1071 | mutex_lock(&data->update_lock); \ | 1059 | mutex_lock(&data->update_lock); \ |
1072 | data->reg[nr] = val; \ | 1060 | data->reg[nr] = val; \ |
1073 | w83627ehf_write_value(client, W83627EHF_REG_##REG[nr], val); \ | 1061 | w83627ehf_write_value(data, W83627EHF_REG_##REG[nr], val); \ |
1074 | mutex_unlock(&data->update_lock); \ | 1062 | mutex_unlock(&data->update_lock); \ |
1075 | return count; \ | 1063 | return count; \ |
1076 | } | 1064 | } |
@@ -1092,21 +1080,28 @@ static ssize_t \ | |||
1092 | store_##reg(struct device *dev, struct device_attribute *attr, \ | 1080 | store_##reg(struct device *dev, struct device_attribute *attr, \ |
1093 | const char *buf, size_t count) \ | 1081 | const char *buf, size_t count) \ |
1094 | { \ | 1082 | { \ |
1095 | struct i2c_client *client = to_i2c_client(dev); \ | 1083 | struct w83627ehf_data *data = dev_get_drvdata(dev); \ |
1096 | struct w83627ehf_data *data = i2c_get_clientdata(client); \ | ||
1097 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ | 1084 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ |
1098 | int nr = sensor_attr->index; \ | 1085 | int nr = sensor_attr->index; \ |
1099 | u8 val = step_time_to_reg(simple_strtoul(buf, NULL, 10), \ | 1086 | u8 val = step_time_to_reg(simple_strtoul(buf, NULL, 10), \ |
1100 | data->pwm_mode[nr]); \ | 1087 | data->pwm_mode[nr]); \ |
1101 | mutex_lock(&data->update_lock); \ | 1088 | mutex_lock(&data->update_lock); \ |
1102 | data->reg[nr] = val; \ | 1089 | data->reg[nr] = val; \ |
1103 | w83627ehf_write_value(client, W83627EHF_REG_##REG[nr], val); \ | 1090 | w83627ehf_write_value(data, W83627EHF_REG_##REG[nr], val); \ |
1104 | mutex_unlock(&data->update_lock); \ | 1091 | mutex_unlock(&data->update_lock); \ |
1105 | return count; \ | 1092 | return count; \ |
1106 | } \ | 1093 | } \ |
1107 | 1094 | ||
1108 | fan_time_functions(fan_stop_time, FAN_STOP_TIME) | 1095 | fan_time_functions(fan_stop_time, FAN_STOP_TIME) |
1109 | 1096 | ||
1097 | static ssize_t show_name(struct device *dev, struct device_attribute *attr, | ||
1098 | char *buf) | ||
1099 | { | ||
1100 | struct w83627ehf_data *data = dev_get_drvdata(dev); | ||
1101 | |||
1102 | return sprintf(buf, "%s\n", data->name); | ||
1103 | } | ||
1104 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); | ||
1110 | 1105 | ||
1111 | static struct sensor_device_attribute sda_sf3_arrays_fan4[] = { | 1106 | static struct sensor_device_attribute sda_sf3_arrays_fan4[] = { |
1112 | SENSOR_ATTR(pwm4_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time, | 1107 | SENSOR_ATTR(pwm4_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time, |
@@ -1131,7 +1126,7 @@ static struct sensor_device_attribute sda_sf3_arrays[] = { | |||
1131 | }; | 1126 | }; |
1132 | 1127 | ||
1133 | /* | 1128 | /* |
1134 | * Driver and client management | 1129 | * Driver and device management |
1135 | */ | 1130 | */ |
1136 | 1131 | ||
1137 | static void w83627ehf_device_remove_files(struct device *dev) | 1132 | static void w83627ehf_device_remove_files(struct device *dev) |
@@ -1139,12 +1134,13 @@ static void w83627ehf_device_remove_files(struct device *dev) | |||
1139 | /* some entries in the following arrays may not have been used in | 1134 | /* some entries in the following arrays may not have been used in |
1140 | * device_create_file(), but device_remove_file() will ignore them */ | 1135 | * device_create_file(), but device_remove_file() will ignore them */ |
1141 | int i; | 1136 | int i; |
1137 | struct w83627ehf_data *data = dev_get_drvdata(dev); | ||
1142 | 1138 | ||
1143 | for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays); i++) | 1139 | for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays); i++) |
1144 | device_remove_file(dev, &sda_sf3_arrays[i].dev_attr); | 1140 | device_remove_file(dev, &sda_sf3_arrays[i].dev_attr); |
1145 | for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++) | 1141 | for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++) |
1146 | device_remove_file(dev, &sda_sf3_arrays_fan4[i].dev_attr); | 1142 | device_remove_file(dev, &sda_sf3_arrays_fan4[i].dev_attr); |
1147 | for (i = 0; i < w83627ehf_num_in; i++) { | 1143 | for (i = 0; i < data->in_num; i++) { |
1148 | device_remove_file(dev, &sda_in_input[i].dev_attr); | 1144 | device_remove_file(dev, &sda_in_input[i].dev_attr); |
1149 | device_remove_file(dev, &sda_in_alarm[i].dev_attr); | 1145 | device_remove_file(dev, &sda_in_alarm[i].dev_attr); |
1150 | device_remove_file(dev, &sda_in_min[i].dev_attr); | 1146 | device_remove_file(dev, &sda_in_min[i].dev_attr); |
@@ -1165,43 +1161,48 @@ static void w83627ehf_device_remove_files(struct device *dev) | |||
1165 | } | 1161 | } |
1166 | for (i = 0; i < ARRAY_SIZE(sda_temp); i++) | 1162 | for (i = 0; i < ARRAY_SIZE(sda_temp); i++) |
1167 | device_remove_file(dev, &sda_temp[i].dev_attr); | 1163 | device_remove_file(dev, &sda_temp[i].dev_attr); |
1168 | } | ||
1169 | 1164 | ||
1170 | static struct i2c_driver w83627ehf_driver; | 1165 | device_remove_file(dev, &dev_attr_name); |
1166 | } | ||
1171 | 1167 | ||
1172 | static void w83627ehf_init_client(struct i2c_client *client) | 1168 | /* Get the monitoring functions started */ |
1169 | static inline void __devinit w83627ehf_init_device(struct w83627ehf_data *data) | ||
1173 | { | 1170 | { |
1174 | int i; | 1171 | int i; |
1175 | u8 tmp; | 1172 | u8 tmp; |
1176 | 1173 | ||
1177 | /* Start monitoring is needed */ | 1174 | /* Start monitoring is needed */ |
1178 | tmp = w83627ehf_read_value(client, W83627EHF_REG_CONFIG); | 1175 | tmp = w83627ehf_read_value(data, W83627EHF_REG_CONFIG); |
1179 | if (!(tmp & 0x01)) | 1176 | if (!(tmp & 0x01)) |
1180 | w83627ehf_write_value(client, W83627EHF_REG_CONFIG, | 1177 | w83627ehf_write_value(data, W83627EHF_REG_CONFIG, |
1181 | tmp | 0x01); | 1178 | tmp | 0x01); |
1182 | 1179 | ||
1183 | /* Enable temp2 and temp3 if needed */ | 1180 | /* Enable temp2 and temp3 if needed */ |
1184 | for (i = 0; i < 2; i++) { | 1181 | for (i = 0; i < 2; i++) { |
1185 | tmp = w83627ehf_read_value(client, | 1182 | tmp = w83627ehf_read_value(data, |
1186 | W83627EHF_REG_TEMP_CONFIG[i]); | 1183 | W83627EHF_REG_TEMP_CONFIG[i]); |
1187 | if (tmp & 0x01) | 1184 | if (tmp & 0x01) |
1188 | w83627ehf_write_value(client, | 1185 | w83627ehf_write_value(data, |
1189 | W83627EHF_REG_TEMP_CONFIG[i], | 1186 | W83627EHF_REG_TEMP_CONFIG[i], |
1190 | tmp & 0xfe); | 1187 | tmp & 0xfe); |
1191 | } | 1188 | } |
1192 | } | 1189 | } |
1193 | 1190 | ||
1194 | static int w83627ehf_detect(struct i2c_adapter *adapter) | 1191 | static int __devinit w83627ehf_probe(struct platform_device *pdev) |
1195 | { | 1192 | { |
1196 | struct i2c_client *client; | 1193 | struct device *dev = &pdev->dev; |
1194 | struct w83627ehf_sio_data *sio_data = dev->platform_data; | ||
1197 | struct w83627ehf_data *data; | 1195 | struct w83627ehf_data *data; |
1198 | struct device *dev; | 1196 | struct resource *res; |
1199 | u8 fan4pin, fan5pin; | 1197 | u8 fan4pin, fan5pin; |
1200 | int i, err = 0; | 1198 | int i, err = 0; |
1201 | 1199 | ||
1202 | if (!request_region(address + IOREGION_OFFSET, IOREGION_LENGTH, | 1200 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
1203 | w83627ehf_driver.driver.name)) { | 1201 | if (!request_region(res->start, IOREGION_LENGTH, DRVNAME)) { |
1204 | err = -EBUSY; | 1202 | err = -EBUSY; |
1203 | dev_err(dev, "Failed to request region 0x%lx-0x%lx\n", | ||
1204 | (unsigned long)res->start, | ||
1205 | (unsigned long)res->start + IOREGION_LENGTH - 1); | ||
1205 | goto exit; | 1206 | goto exit; |
1206 | } | 1207 | } |
1207 | 1208 | ||
@@ -1210,41 +1211,29 @@ static int w83627ehf_detect(struct i2c_adapter *adapter) | |||
1210 | goto exit_release; | 1211 | goto exit_release; |
1211 | } | 1212 | } |
1212 | 1213 | ||
1213 | client = &data->client; | 1214 | data->addr = res->start; |
1214 | i2c_set_clientdata(client, data); | ||
1215 | client->addr = address; | ||
1216 | mutex_init(&data->lock); | 1215 | mutex_init(&data->lock); |
1217 | client->adapter = adapter; | ||
1218 | client->driver = &w83627ehf_driver; | ||
1219 | client->flags = 0; | ||
1220 | dev = &client->dev; | ||
1221 | |||
1222 | if (w83627ehf_num_in == 9) | ||
1223 | strlcpy(client->name, "w83627dhg", I2C_NAME_SIZE); | ||
1224 | else /* just say ehf. 627EHG is 627EHF in lead-free packaging. */ | ||
1225 | strlcpy(client->name, "w83627ehf", I2C_NAME_SIZE); | ||
1226 | |||
1227 | data->valid = 0; | ||
1228 | mutex_init(&data->update_lock); | 1216 | mutex_init(&data->update_lock); |
1217 | data->name = w83627ehf_device_names[sio_data->kind]; | ||
1218 | platform_set_drvdata(pdev, data); | ||
1229 | 1219 | ||
1230 | /* Tell the i2c layer a new client has arrived */ | 1220 | /* 627EHG and 627EHF have 10 voltage inputs; DHG has 9 */ |
1231 | if ((err = i2c_attach_client(client))) | 1221 | data->in_num = (sio_data->kind == w83627dhg) ? 9 : 10; |
1232 | goto exit_free; | ||
1233 | 1222 | ||
1234 | /* Initialize the chip */ | 1223 | /* Initialize the chip */ |
1235 | w83627ehf_init_client(client); | 1224 | w83627ehf_init_device(data); |
1236 | 1225 | ||
1237 | /* A few vars need to be filled upon startup */ | 1226 | /* A few vars need to be filled upon startup */ |
1238 | for (i = 0; i < 5; i++) | 1227 | for (i = 0; i < 5; i++) |
1239 | data->fan_min[i] = w83627ehf_read_value(client, | 1228 | data->fan_min[i] = w83627ehf_read_value(data, |
1240 | W83627EHF_REG_FAN_MIN[i]); | 1229 | W83627EHF_REG_FAN_MIN[i]); |
1241 | 1230 | ||
1242 | /* fan4 and fan5 share some pins with the GPIO and serial flash */ | 1231 | /* fan4 and fan5 share some pins with the GPIO and serial flash */ |
1243 | 1232 | ||
1244 | superio_enter(); | 1233 | superio_enter(sio_data->sioreg); |
1245 | fan5pin = superio_inb(0x24) & 0x2; | 1234 | fan5pin = superio_inb(sio_data->sioreg, 0x24) & 0x2; |
1246 | fan4pin = superio_inb(0x29) & 0x6; | 1235 | fan4pin = superio_inb(sio_data->sioreg, 0x29) & 0x6; |
1247 | superio_exit(); | 1236 | superio_exit(sio_data->sioreg); |
1248 | 1237 | ||
1249 | /* It looks like fan4 and fan5 pins can be alternatively used | 1238 | /* It looks like fan4 and fan5 pins can be alternatively used |
1250 | as fan on/off switches, but fan5 control is write only :/ | 1239 | as fan on/off switches, but fan5 control is write only :/ |
@@ -1253,7 +1242,7 @@ static int w83627ehf_detect(struct i2c_adapter *adapter) | |||
1253 | is not the default. */ | 1242 | is not the default. */ |
1254 | 1243 | ||
1255 | data->has_fan = 0x07; /* fan1, fan2 and fan3 */ | 1244 | data->has_fan = 0x07; /* fan1, fan2 and fan3 */ |
1256 | i = w83627ehf_read_value(client, W83627EHF_REG_FANDIV1); | 1245 | i = w83627ehf_read_value(data, W83627EHF_REG_FANDIV1); |
1257 | if ((i & (1 << 2)) && (!fan4pin)) | 1246 | if ((i & (1 << 2)) && (!fan4pin)) |
1258 | data->has_fan |= (1 << 3); | 1247 | data->has_fan |= (1 << 3); |
1259 | if (!(i & (1 << 1)) && (!fan5pin)) | 1248 | if (!(i & (1 << 1)) && (!fan5pin)) |
@@ -1273,7 +1262,7 @@ static int w83627ehf_detect(struct i2c_adapter *adapter) | |||
1273 | goto exit_remove; | 1262 | goto exit_remove; |
1274 | } | 1263 | } |
1275 | 1264 | ||
1276 | for (i = 0; i < w83627ehf_num_in; i++) | 1265 | for (i = 0; i < data->in_num; i++) |
1277 | if ((err = device_create_file(dev, &sda_in_input[i].dev_attr)) | 1266 | if ((err = device_create_file(dev, &sda_in_input[i].dev_attr)) |
1278 | || (err = device_create_file(dev, | 1267 | || (err = device_create_file(dev, |
1279 | &sda_in_alarm[i].dev_attr)) | 1268 | &sda_in_alarm[i].dev_attr)) |
@@ -1313,6 +1302,10 @@ static int w83627ehf_detect(struct i2c_adapter *adapter) | |||
1313 | if ((err = device_create_file(dev, &sda_temp[i].dev_attr))) | 1302 | if ((err = device_create_file(dev, &sda_temp[i].dev_attr))) |
1314 | goto exit_remove; | 1303 | goto exit_remove; |
1315 | 1304 | ||
1305 | err = device_create_file(dev, &dev_attr_name); | ||
1306 | if (err) | ||
1307 | goto exit_remove; | ||
1308 | |||
1316 | data->class_dev = hwmon_device_register(dev); | 1309 | data->class_dev = hwmon_device_register(dev); |
1317 | if (IS_ERR(data->class_dev)) { | 1310 | if (IS_ERR(data->class_dev)) { |
1318 | err = PTR_ERR(data->class_dev); | 1311 | err = PTR_ERR(data->class_dev); |
@@ -1323,95 +1316,166 @@ static int w83627ehf_detect(struct i2c_adapter *adapter) | |||
1323 | 1316 | ||
1324 | exit_remove: | 1317 | exit_remove: |
1325 | w83627ehf_device_remove_files(dev); | 1318 | w83627ehf_device_remove_files(dev); |
1326 | i2c_detach_client(client); | ||
1327 | exit_free: | ||
1328 | kfree(data); | 1319 | kfree(data); |
1320 | platform_set_drvdata(pdev, NULL); | ||
1329 | exit_release: | 1321 | exit_release: |
1330 | release_region(address + IOREGION_OFFSET, IOREGION_LENGTH); | 1322 | release_region(res->start, IOREGION_LENGTH); |
1331 | exit: | 1323 | exit: |
1332 | return err; | 1324 | return err; |
1333 | } | 1325 | } |
1334 | 1326 | ||
1335 | static int w83627ehf_detach_client(struct i2c_client *client) | 1327 | static int __devexit w83627ehf_remove(struct platform_device *pdev) |
1336 | { | 1328 | { |
1337 | struct w83627ehf_data *data = i2c_get_clientdata(client); | 1329 | struct w83627ehf_data *data = platform_get_drvdata(pdev); |
1338 | int err; | ||
1339 | 1330 | ||
1340 | hwmon_device_unregister(data->class_dev); | 1331 | hwmon_device_unregister(data->class_dev); |
1341 | w83627ehf_device_remove_files(&client->dev); | 1332 | w83627ehf_device_remove_files(&pdev->dev); |
1342 | 1333 | release_region(data->addr, IOREGION_LENGTH); | |
1343 | if ((err = i2c_detach_client(client))) | 1334 | platform_set_drvdata(pdev, NULL); |
1344 | return err; | ||
1345 | release_region(client->addr + IOREGION_OFFSET, IOREGION_LENGTH); | ||
1346 | kfree(data); | 1335 | kfree(data); |
1347 | 1336 | ||
1348 | return 0; | 1337 | return 0; |
1349 | } | 1338 | } |
1350 | 1339 | ||
1351 | static struct i2c_driver w83627ehf_driver = { | 1340 | static struct platform_driver w83627ehf_driver = { |
1352 | .driver = { | 1341 | .driver = { |
1353 | .owner = THIS_MODULE, | 1342 | .owner = THIS_MODULE, |
1354 | .name = "w83627ehf", | 1343 | .name = DRVNAME, |
1355 | }, | 1344 | }, |
1356 | .attach_adapter = w83627ehf_detect, | 1345 | .probe = w83627ehf_probe, |
1357 | .detach_client = w83627ehf_detach_client, | 1346 | .remove = __devexit_p(w83627ehf_remove), |
1358 | }; | 1347 | }; |
1359 | 1348 | ||
1360 | static int __init w83627ehf_find(int sioaddr, unsigned short *addr) | 1349 | /* w83627ehf_find() looks for a '627 in the Super-I/O config space */ |
1350 | static int __init w83627ehf_find(int sioaddr, unsigned short *addr, | ||
1351 | struct w83627ehf_sio_data *sio_data) | ||
1361 | { | 1352 | { |
1353 | static const char __initdata sio_name_W83627EHF[] = "W83627EHF"; | ||
1354 | static const char __initdata sio_name_W83627EHG[] = "W83627EHG"; | ||
1355 | static const char __initdata sio_name_W83627DHG[] = "W83627DHG"; | ||
1356 | |||
1362 | u16 val; | 1357 | u16 val; |
1358 | const char *sio_name; | ||
1363 | 1359 | ||
1364 | REG = sioaddr; | 1360 | superio_enter(sioaddr); |
1365 | VAL = sioaddr + 1; | ||
1366 | superio_enter(); | ||
1367 | 1361 | ||
1368 | val = (superio_inb(SIO_REG_DEVID) << 8) | 1362 | val = (superio_inb(sioaddr, SIO_REG_DEVID) << 8) |
1369 | | superio_inb(SIO_REG_DEVID + 1); | 1363 | | superio_inb(sioaddr, SIO_REG_DEVID + 1); |
1370 | switch (val & SIO_ID_MASK) { | 1364 | switch (val & SIO_ID_MASK) { |
1371 | case SIO_W83627DHG_ID: | ||
1372 | w83627ehf_num_in = 9; | ||
1373 | break; | ||
1374 | case SIO_W83627EHF_ID: | 1365 | case SIO_W83627EHF_ID: |
1366 | sio_data->kind = w83627ehf; | ||
1367 | sio_name = sio_name_W83627EHF; | ||
1368 | break; | ||
1375 | case SIO_W83627EHG_ID: | 1369 | case SIO_W83627EHG_ID: |
1376 | w83627ehf_num_in = 10; | 1370 | sio_data->kind = w83627ehf; |
1371 | sio_name = sio_name_W83627EHG; | ||
1372 | break; | ||
1373 | case SIO_W83627DHG_ID: | ||
1374 | sio_data->kind = w83627dhg; | ||
1375 | sio_name = sio_name_W83627DHG; | ||
1377 | break; | 1376 | break; |
1378 | default: | 1377 | default: |
1379 | printk(KERN_WARNING "w83627ehf: unsupported chip ID: 0x%04x\n", | 1378 | pr_info(DRVNAME ": unsupported chip ID: 0x%04x\n", |
1380 | val); | 1379 | val); |
1381 | superio_exit(); | 1380 | superio_exit(sioaddr); |
1382 | return -ENODEV; | 1381 | return -ENODEV; |
1383 | } | 1382 | } |
1384 | 1383 | ||
1385 | superio_select(W83627EHF_LD_HWM); | 1384 | /* We have a known chip, find the HWM I/O address */ |
1386 | val = (superio_inb(SIO_REG_ADDR) << 8) | 1385 | superio_select(sioaddr, W83627EHF_LD_HWM); |
1387 | | superio_inb(SIO_REG_ADDR + 1); | 1386 | val = (superio_inb(sioaddr, SIO_REG_ADDR) << 8) |
1387 | | superio_inb(sioaddr, SIO_REG_ADDR + 1); | ||
1388 | *addr = val & IOREGION_ALIGNMENT; | 1388 | *addr = val & IOREGION_ALIGNMENT; |
1389 | if (*addr == 0) { | 1389 | if (*addr == 0) { |
1390 | superio_exit(); | 1390 | superio_exit(sioaddr); |
1391 | return -ENODEV; | 1391 | return -ENODEV; |
1392 | } | 1392 | } |
1393 | 1393 | ||
1394 | /* Activate logical device if needed */ | 1394 | /* Activate logical device if needed */ |
1395 | val = superio_inb(SIO_REG_ENABLE); | 1395 | val = superio_inb(sioaddr, SIO_REG_ENABLE); |
1396 | if (!(val & 0x01)) | 1396 | if (!(val & 0x01)) |
1397 | superio_outb(SIO_REG_ENABLE, val | 0x01); | 1397 | superio_outb(sioaddr, SIO_REG_ENABLE, val | 0x01); |
1398 | |||
1399 | superio_exit(sioaddr); | ||
1400 | pr_info(DRVNAME ": Found %s chip at %#x\n", sio_name, *addr); | ||
1401 | sio_data->sioreg = sioaddr; | ||
1398 | 1402 | ||
1399 | superio_exit(); | ||
1400 | return 0; | 1403 | return 0; |
1401 | } | 1404 | } |
1402 | 1405 | ||
1406 | /* when Super-I/O functions move to a separate file, the Super-I/O | ||
1407 | * bus will manage the lifetime of the device and this module will only keep | ||
1408 | * track of the w83627ehf driver. But since we platform_device_alloc(), we | ||
1409 | * must keep track of the device */ | ||
1410 | static struct platform_device *pdev; | ||
1411 | |||
1403 | static int __init sensors_w83627ehf_init(void) | 1412 | static int __init sensors_w83627ehf_init(void) |
1404 | { | 1413 | { |
1405 | if (w83627ehf_find(0x2e, &address) | 1414 | int err; |
1406 | && w83627ehf_find(0x4e, &address)) | 1415 | unsigned short address; |
1416 | struct resource res; | ||
1417 | struct w83627ehf_sio_data sio_data; | ||
1418 | |||
1419 | /* initialize sio_data->kind and sio_data->sioreg. | ||
1420 | * | ||
1421 | * when Super-I/O functions move to a separate file, the Super-I/O | ||
1422 | * driver will probe 0x2e and 0x4e and auto-detect the presence of a | ||
1423 | * w83627ehf hardware monitor, and call probe() */ | ||
1424 | if (w83627ehf_find(0x2e, &address, &sio_data) && | ||
1425 | w83627ehf_find(0x4e, &address, &sio_data)) | ||
1407 | return -ENODEV; | 1426 | return -ENODEV; |
1408 | 1427 | ||
1409 | return i2c_isa_add_driver(&w83627ehf_driver); | 1428 | err = platform_driver_register(&w83627ehf_driver); |
1429 | if (err) | ||
1430 | goto exit; | ||
1431 | |||
1432 | if (!(pdev = platform_device_alloc(DRVNAME, address))) { | ||
1433 | err = -ENOMEM; | ||
1434 | printk(KERN_ERR DRVNAME ": Device allocation failed\n"); | ||
1435 | goto exit_unregister; | ||
1436 | } | ||
1437 | |||
1438 | err = platform_device_add_data(pdev, &sio_data, | ||
1439 | sizeof(struct w83627ehf_sio_data)); | ||
1440 | if (err) { | ||
1441 | printk(KERN_ERR DRVNAME ": Platform data allocation failed\n"); | ||
1442 | goto exit_device_put; | ||
1443 | } | ||
1444 | |||
1445 | memset(&res, 0, sizeof(res)); | ||
1446 | res.name = DRVNAME; | ||
1447 | res.start = address + IOREGION_OFFSET; | ||
1448 | res.end = address + IOREGION_OFFSET + IOREGION_LENGTH - 1; | ||
1449 | res.flags = IORESOURCE_IO; | ||
1450 | err = platform_device_add_resources(pdev, &res, 1); | ||
1451 | if (err) { | ||
1452 | printk(KERN_ERR DRVNAME ": Device resource addition failed " | ||
1453 | "(%d)\n", err); | ||
1454 | goto exit_device_put; | ||
1455 | } | ||
1456 | |||
1457 | /* platform_device_add calls probe() */ | ||
1458 | err = platform_device_add(pdev); | ||
1459 | if (err) { | ||
1460 | printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n", | ||
1461 | err); | ||
1462 | goto exit_device_put; | ||
1463 | } | ||
1464 | |||
1465 | return 0; | ||
1466 | |||
1467 | exit_device_put: | ||
1468 | platform_device_put(pdev); | ||
1469 | exit_unregister: | ||
1470 | platform_driver_unregister(&w83627ehf_driver); | ||
1471 | exit: | ||
1472 | return err; | ||
1410 | } | 1473 | } |
1411 | 1474 | ||
1412 | static void __exit sensors_w83627ehf_exit(void) | 1475 | static void __exit sensors_w83627ehf_exit(void) |
1413 | { | 1476 | { |
1414 | i2c_isa_del_driver(&w83627ehf_driver); | 1477 | platform_device_unregister(pdev); |
1478 | platform_driver_unregister(&w83627ehf_driver); | ||
1415 | } | 1479 | } |
1416 | 1480 | ||
1417 | MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>"); | 1481 | MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>"); |