diff options
| -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>"); |
