diff options
Diffstat (limited to 'drivers/hwmon/w83627ehf.c')
| -rw-r--r-- | drivers/hwmon/w83627ehf.c | 615 |
1 files changed, 380 insertions, 235 deletions
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c index 30a76404f0af..c51ae2e17758 100644 --- a/drivers/hwmon/w83627ehf.c +++ b/drivers/hwmon/w83627ehf.c | |||
| @@ -41,41 +41,39 @@ | |||
| 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/hwmon-vid.h> | ||
| 48 | #include <linux/err.h> | 49 | #include <linux/err.h> |
| 49 | #include <linux/mutex.h> | 50 | #include <linux/mutex.h> |
| 50 | #include <asm/io.h> | 51 | #include <asm/io.h> |
| 51 | #include "lm75.h" | 52 | #include "lm75.h" |
| 52 | 53 | ||
| 53 | /* The actual ISA address is read from Super-I/O configuration space */ | 54 | enum kinds { w83627ehf, w83627dhg }; |
| 54 | static unsigned short address; | ||
| 55 | 55 | ||
| 56 | /* | 56 | /* used to set data->name = w83627ehf_device_names[data->sio_kind] */ |
| 57 | * Super-I/O constants and functions | 57 | static const char * w83627ehf_device_names[] = { |
| 58 | */ | 58 | "w83627ehf", |
| 59 | "w83627dhg", | ||
| 60 | }; | ||
| 61 | |||
| 62 | #define DRVNAME "w83627ehf" | ||
| 59 | 63 | ||
| 60 | /* | 64 | /* |
| 61 | * The three following globals are initialized in w83627ehf_find(), before | 65 | * 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 | */ | 66 | */ |
| 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 | 67 | ||
| 73 | #define W83627EHF_LD_HWM 0x0b | 68 | #define W83627EHF_LD_HWM 0x0b |
| 74 | 69 | ||
| 75 | #define SIO_REG_LDSEL 0x07 /* Logical device select */ | 70 | #define SIO_REG_LDSEL 0x07 /* Logical device select */ |
| 76 | #define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */ | 71 | #define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */ |
| 72 | #define SIO_REG_EN_VRM10 0x2C /* GPIO3, GPIO4 selection */ | ||
| 77 | #define SIO_REG_ENABLE 0x30 /* Logical device enable */ | 73 | #define SIO_REG_ENABLE 0x30 /* Logical device enable */ |
| 78 | #define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */ | 74 | #define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */ |
| 75 | #define SIO_REG_VID_CTRL 0xF0 /* VID control */ | ||
| 76 | #define SIO_REG_VID_DATA 0xF1 /* VID data */ | ||
| 79 | 77 | ||
| 80 | #define SIO_W83627EHF_ID 0x8850 | 78 | #define SIO_W83627EHF_ID 0x8850 |
| 81 | #define SIO_W83627EHG_ID 0x8860 | 79 | #define SIO_W83627EHG_ID 0x8860 |
| @@ -83,38 +81,38 @@ static int w83627ehf_num_in; | |||
| 83 | #define SIO_ID_MASK 0xFFF0 | 81 | #define SIO_ID_MASK 0xFFF0 |
| 84 | 82 | ||
| 85 | static inline void | 83 | static inline void |
| 86 | superio_outb(int reg, int val) | 84 | superio_outb(int ioreg, int reg, int val) |
| 87 | { | 85 | { |
| 88 | outb(reg, REG); | 86 | outb(reg, ioreg); |
| 89 | outb(val, VAL); | 87 | outb(val, ioreg + 1); |
| 90 | } | 88 | } |
| 91 | 89 | ||
| 92 | static inline int | 90 | static inline int |
| 93 | superio_inb(int reg) | 91 | superio_inb(int ioreg, int reg) |
| 94 | { | 92 | { |
| 95 | outb(reg, REG); | 93 | outb(reg, ioreg); |
| 96 | return inb(VAL); | 94 | return inb(ioreg + 1); |
| 97 | } | 95 | } |
| 98 | 96 | ||
| 99 | static inline void | 97 | static inline void |
| 100 | superio_select(int ld) | 98 | superio_select(int ioreg, int ld) |
| 101 | { | 99 | { |
| 102 | outb(SIO_REG_LDSEL, REG); | 100 | outb(SIO_REG_LDSEL, ioreg); |
| 103 | outb(ld, VAL); | 101 | outb(ld, ioreg + 1); |
| 104 | } | 102 | } |
| 105 | 103 | ||
| 106 | static inline void | 104 | static inline void |
| 107 | superio_enter(void) | 105 | superio_enter(int ioreg) |
| 108 | { | 106 | { |
| 109 | outb(0x87, REG); | 107 | outb(0x87, ioreg); |
| 110 | outb(0x87, REG); | 108 | outb(0x87, ioreg); |
| 111 | } | 109 | } |
| 112 | 110 | ||
| 113 | static inline void | 111 | static inline void |
| 114 | superio_exit(void) | 112 | superio_exit(int ioreg) |
| 115 | { | 113 | { |
| 116 | outb(0x02, REG); | 114 | outb(0x02, ioreg); |
| 117 | outb(0x02, VAL); | 115 | outb(0x02, ioreg + 1); |
| 118 | } | 116 | } |
| 119 | 117 | ||
| 120 | /* | 118 | /* |
| @@ -124,8 +122,8 @@ superio_exit(void) | |||
| 124 | #define IOREGION_ALIGNMENT ~7 | 122 | #define IOREGION_ALIGNMENT ~7 |
| 125 | #define IOREGION_OFFSET 5 | 123 | #define IOREGION_OFFSET 5 |
| 126 | #define IOREGION_LENGTH 2 | 124 | #define IOREGION_LENGTH 2 |
| 127 | #define ADDR_REG_OFFSET 5 | 125 | #define ADDR_REG_OFFSET 0 |
| 128 | #define DATA_REG_OFFSET 6 | 126 | #define DATA_REG_OFFSET 1 |
| 129 | 127 | ||
| 130 | #define W83627EHF_REG_BANK 0x4E | 128 | #define W83627EHF_REG_BANK 0x4E |
| 131 | #define W83627EHF_REG_CONFIG 0x40 | 129 | #define W83627EHF_REG_CONFIG 0x40 |
| @@ -255,7 +253,9 @@ static inline u8 in_to_reg(u32 val, u8 nr) | |||
| 255 | */ | 253 | */ |
| 256 | 254 | ||
| 257 | struct w83627ehf_data { | 255 | struct w83627ehf_data { |
| 258 | struct i2c_client client; | 256 | int addr; /* IO base of hw monitor block */ |
| 257 | const char *name; | ||
| 258 | |||
| 259 | struct class_device *class_dev; | 259 | struct class_device *class_dev; |
| 260 | struct mutex lock; | 260 | struct mutex lock; |
| 261 | 261 | ||
| @@ -264,6 +264,7 @@ struct w83627ehf_data { | |||
| 264 | unsigned long last_updated; /* In jiffies */ | 264 | unsigned long last_updated; /* In jiffies */ |
| 265 | 265 | ||
| 266 | /* Register values */ | 266 | /* Register values */ |
| 267 | u8 in_num; /* number of in inputs we have */ | ||
| 267 | u8 in[10]; /* Register value */ | 268 | u8 in[10]; /* Register value */ |
| 268 | u8 in_max[10]; /* Register value */ | 269 | u8 in_max[10]; /* Register value */ |
| 269 | u8 in_min[10]; /* Register value */ | 270 | u8 in_min[10]; /* Register value */ |
| @@ -271,6 +272,7 @@ struct w83627ehf_data { | |||
| 271 | u8 fan_min[5]; | 272 | u8 fan_min[5]; |
| 272 | u8 fan_div[5]; | 273 | u8 fan_div[5]; |
| 273 | u8 has_fan; /* some fan inputs can be disabled */ | 274 | u8 has_fan; /* some fan inputs can be disabled */ |
| 275 | u8 temp_type[3]; | ||
| 274 | s8 temp1; | 276 | s8 temp1; |
| 275 | s8 temp1_max; | 277 | s8 temp1_max; |
| 276 | s8 temp1_max_hyst; | 278 | s8 temp1_max_hyst; |
| @@ -288,6 +290,14 @@ struct w83627ehf_data { | |||
| 288 | 290 | ||
| 289 | u8 fan_min_output[4]; /* minimum fan speed */ | 291 | u8 fan_min_output[4]; /* minimum fan speed */ |
| 290 | u8 fan_stop_time[4]; | 292 | u8 fan_stop_time[4]; |
| 293 | |||
| 294 | u8 vid; | ||
| 295 | u8 vrm; | ||
| 296 | }; | ||
| 297 | |||
| 298 | struct w83627ehf_sio_data { | ||
| 299 | int sioreg; | ||
| 300 | enum kinds kind; | ||
| 291 | }; | 301 | }; |
| 292 | 302 | ||
| 293 | static inline int is_word_sized(u16 reg) | 303 | static inline int is_word_sized(u16 reg) |
| @@ -303,156 +313,152 @@ static inline int is_word_sized(u16 reg) | |||
| 303 | nothing for registers which live in bank 0. For others, they respectively | 313 | 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 | 314 | set the bank register to the correct value (before the register is |
| 305 | accessed), and back to 0 (afterwards). */ | 315 | accessed), and back to 0 (afterwards). */ |
| 306 | static inline void w83627ehf_set_bank(struct i2c_client *client, u16 reg) | 316 | static inline void w83627ehf_set_bank(struct w83627ehf_data *data, u16 reg) |
| 307 | { | 317 | { |
| 308 | if (reg & 0xff00) { | 318 | if (reg & 0xff00) { |
| 309 | outb_p(W83627EHF_REG_BANK, client->addr + ADDR_REG_OFFSET); | 319 | outb_p(W83627EHF_REG_BANK, data->addr + ADDR_REG_OFFSET); |
| 310 | outb_p(reg >> 8, client->addr + DATA_REG_OFFSET); | 320 | outb_p(reg >> 8, data->addr + DATA_REG_OFFSET); |
| 311 | } | 321 | } |
| 312 | } | 322 | } |
| 313 | 323 | ||
| 314 | static inline void w83627ehf_reset_bank(struct i2c_client *client, u16 reg) | 324 | static inline void w83627ehf_reset_bank(struct w83627ehf_data *data, u16 reg) |
| 315 | { | 325 | { |
| 316 | if (reg & 0xff00) { | 326 | if (reg & 0xff00) { |
| 317 | outb_p(W83627EHF_REG_BANK, client->addr + ADDR_REG_OFFSET); | 327 | outb_p(W83627EHF_REG_BANK, data->addr + ADDR_REG_OFFSET); |
| 318 | outb_p(0, client->addr + DATA_REG_OFFSET); | 328 | outb_p(0, data->addr + DATA_REG_OFFSET); |
| 319 | } | 329 | } |
| 320 | } | 330 | } |
| 321 | 331 | ||
| 322 | static u16 w83627ehf_read_value(struct i2c_client *client, u16 reg) | 332 | static u16 w83627ehf_read_value(struct w83627ehf_data *data, u16 reg) |
| 323 | { | 333 | { |
| 324 | struct w83627ehf_data *data = i2c_get_clientdata(client); | ||
| 325 | int res, word_sized = is_word_sized(reg); | 334 | int res, word_sized = is_word_sized(reg); |
| 326 | 335 | ||
| 327 | mutex_lock(&data->lock); | 336 | mutex_lock(&data->lock); |
| 328 | 337 | ||
| 329 | w83627ehf_set_bank(client, reg); | 338 | w83627ehf_set_bank(data, reg); |
| 330 | outb_p(reg & 0xff, client->addr + ADDR_REG_OFFSET); | 339 | outb_p(reg & 0xff, data->addr + ADDR_REG_OFFSET); |
| 331 | res = inb_p(client->addr + DATA_REG_OFFSET); | 340 | res = inb_p(data->addr + DATA_REG_OFFSET); |
| 332 | if (word_sized) { | 341 | if (word_sized) { |
| 333 | outb_p((reg & 0xff) + 1, | 342 | outb_p((reg & 0xff) + 1, |
| 334 | client->addr + ADDR_REG_OFFSET); | 343 | data->addr + ADDR_REG_OFFSET); |
| 335 | res = (res << 8) + inb_p(client->addr + DATA_REG_OFFSET); | 344 | res = (res << 8) + inb_p(data->addr + DATA_REG_OFFSET); |
| 336 | } | 345 | } |
| 337 | w83627ehf_reset_bank(client, reg); | 346 | w83627ehf_reset_bank(data, reg); |
| 338 | 347 | ||
| 339 | mutex_unlock(&data->lock); | 348 | mutex_unlock(&data->lock); |
| 340 | 349 | ||
| 341 | return res; | 350 | return res; |
| 342 | } | 351 | } |
| 343 | 352 | ||
| 344 | static int w83627ehf_write_value(struct i2c_client *client, u16 reg, u16 value) | 353 | static int w83627ehf_write_value(struct w83627ehf_data *data, u16 reg, u16 value) |
| 345 | { | 354 | { |
| 346 | struct w83627ehf_data *data = i2c_get_clientdata(client); | ||
| 347 | int word_sized = is_word_sized(reg); | 355 | int word_sized = is_word_sized(reg); |
| 348 | 356 | ||
| 349 | mutex_lock(&data->lock); | 357 | mutex_lock(&data->lock); |
| 350 | 358 | ||
| 351 | w83627ehf_set_bank(client, reg); | 359 | w83627ehf_set_bank(data, reg); |
| 352 | outb_p(reg & 0xff, client->addr + ADDR_REG_OFFSET); | 360 | outb_p(reg & 0xff, data->addr + ADDR_REG_OFFSET); |
| 353 | if (word_sized) { | 361 | if (word_sized) { |
| 354 | outb_p(value >> 8, client->addr + DATA_REG_OFFSET); | 362 | outb_p(value >> 8, data->addr + DATA_REG_OFFSET); |
| 355 | outb_p((reg & 0xff) + 1, | 363 | outb_p((reg & 0xff) + 1, |
| 356 | client->addr + ADDR_REG_OFFSET); | 364 | data->addr + ADDR_REG_OFFSET); |
| 357 | } | 365 | } |
| 358 | outb_p(value & 0xff, client->addr + DATA_REG_OFFSET); | 366 | outb_p(value & 0xff, data->addr + DATA_REG_OFFSET); |
| 359 | w83627ehf_reset_bank(client, reg); | 367 | w83627ehf_reset_bank(data, reg); |
| 360 | 368 | ||
| 361 | mutex_unlock(&data->lock); | 369 | mutex_unlock(&data->lock); |
| 362 | return 0; | 370 | return 0; |
| 363 | } | 371 | } |
| 364 | 372 | ||
| 365 | /* This function assumes that the caller holds data->update_lock */ | 373 | /* This function assumes that the caller holds data->update_lock */ |
| 366 | static void w83627ehf_write_fan_div(struct i2c_client *client, int nr) | 374 | static void w83627ehf_write_fan_div(struct w83627ehf_data *data, int nr) |
| 367 | { | 375 | { |
| 368 | struct w83627ehf_data *data = i2c_get_clientdata(client); | ||
| 369 | u8 reg; | 376 | u8 reg; |
| 370 | 377 | ||
| 371 | switch (nr) { | 378 | switch (nr) { |
| 372 | case 0: | 379 | case 0: |
| 373 | reg = (w83627ehf_read_value(client, W83627EHF_REG_FANDIV1) & 0xcf) | 380 | reg = (w83627ehf_read_value(data, W83627EHF_REG_FANDIV1) & 0xcf) |
| 374 | | ((data->fan_div[0] & 0x03) << 4); | 381 | | ((data->fan_div[0] & 0x03) << 4); |
| 375 | /* fan5 input control bit is write only, compute the value */ | 382 | /* fan5 input control bit is write only, compute the value */ |
| 376 | reg |= (data->has_fan & (1 << 4)) ? 1 : 0; | 383 | reg |= (data->has_fan & (1 << 4)) ? 1 : 0; |
| 377 | w83627ehf_write_value(client, W83627EHF_REG_FANDIV1, reg); | 384 | w83627ehf_write_value(data, W83627EHF_REG_FANDIV1, reg); |
| 378 | reg = (w83627ehf_read_value(client, W83627EHF_REG_VBAT) & 0xdf) | 385 | reg = (w83627ehf_read_value(data, W83627EHF_REG_VBAT) & 0xdf) |
| 379 | | ((data->fan_div[0] & 0x04) << 3); | 386 | | ((data->fan_div[0] & 0x04) << 3); |
| 380 | w83627ehf_write_value(client, W83627EHF_REG_VBAT, reg); | 387 | w83627ehf_write_value(data, W83627EHF_REG_VBAT, reg); |
| 381 | break; | 388 | break; |
| 382 | case 1: | 389 | case 1: |
| 383 | reg = (w83627ehf_read_value(client, W83627EHF_REG_FANDIV1) & 0x3f) | 390 | reg = (w83627ehf_read_value(data, W83627EHF_REG_FANDIV1) & 0x3f) |
| 384 | | ((data->fan_div[1] & 0x03) << 6); | 391 | | ((data->fan_div[1] & 0x03) << 6); |
| 385 | /* fan5 input control bit is write only, compute the value */ | 392 | /* fan5 input control bit is write only, compute the value */ |
| 386 | reg |= (data->has_fan & (1 << 4)) ? 1 : 0; | 393 | reg |= (data->has_fan & (1 << 4)) ? 1 : 0; |
| 387 | w83627ehf_write_value(client, W83627EHF_REG_FANDIV1, reg); | 394 | w83627ehf_write_value(data, W83627EHF_REG_FANDIV1, reg); |
| 388 | reg = (w83627ehf_read_value(client, W83627EHF_REG_VBAT) & 0xbf) | 395 | reg = (w83627ehf_read_value(data, W83627EHF_REG_VBAT) & 0xbf) |
| 389 | | ((data->fan_div[1] & 0x04) << 4); | 396 | | ((data->fan_div[1] & 0x04) << 4); |
| 390 | w83627ehf_write_value(client, W83627EHF_REG_VBAT, reg); | 397 | w83627ehf_write_value(data, W83627EHF_REG_VBAT, reg); |
| 391 | break; | 398 | break; |
| 392 | case 2: | 399 | case 2: |
| 393 | reg = (w83627ehf_read_value(client, W83627EHF_REG_FANDIV2) & 0x3f) | 400 | reg = (w83627ehf_read_value(data, W83627EHF_REG_FANDIV2) & 0x3f) |
| 394 | | ((data->fan_div[2] & 0x03) << 6); | 401 | | ((data->fan_div[2] & 0x03) << 6); |
| 395 | w83627ehf_write_value(client, W83627EHF_REG_FANDIV2, reg); | 402 | w83627ehf_write_value(data, W83627EHF_REG_FANDIV2, reg); |
| 396 | reg = (w83627ehf_read_value(client, W83627EHF_REG_VBAT) & 0x7f) | 403 | reg = (w83627ehf_read_value(data, W83627EHF_REG_VBAT) & 0x7f) |
| 397 | | ((data->fan_div[2] & 0x04) << 5); | 404 | | ((data->fan_div[2] & 0x04) << 5); |
| 398 | w83627ehf_write_value(client, W83627EHF_REG_VBAT, reg); | 405 | w83627ehf_write_value(data, W83627EHF_REG_VBAT, reg); |
| 399 | break; | 406 | break; |
| 400 | case 3: | 407 | case 3: |
| 401 | reg = (w83627ehf_read_value(client, W83627EHF_REG_DIODE) & 0xfc) | 408 | reg = (w83627ehf_read_value(data, W83627EHF_REG_DIODE) & 0xfc) |
| 402 | | (data->fan_div[3] & 0x03); | 409 | | (data->fan_div[3] & 0x03); |
| 403 | w83627ehf_write_value(client, W83627EHF_REG_DIODE, reg); | 410 | w83627ehf_write_value(data, W83627EHF_REG_DIODE, reg); |
| 404 | reg = (w83627ehf_read_value(client, W83627EHF_REG_SMI_OVT) & 0x7f) | 411 | reg = (w83627ehf_read_value(data, W83627EHF_REG_SMI_OVT) & 0x7f) |
| 405 | | ((data->fan_div[3] & 0x04) << 5); | 412 | | ((data->fan_div[3] & 0x04) << 5); |
| 406 | w83627ehf_write_value(client, W83627EHF_REG_SMI_OVT, reg); | 413 | w83627ehf_write_value(data, W83627EHF_REG_SMI_OVT, reg); |
| 407 | break; | 414 | break; |
| 408 | case 4: | 415 | case 4: |
| 409 | reg = (w83627ehf_read_value(client, W83627EHF_REG_DIODE) & 0x73) | 416 | reg = (w83627ehf_read_value(data, W83627EHF_REG_DIODE) & 0x73) |
| 410 | | ((data->fan_div[4] & 0x03) << 2) | 417 | | ((data->fan_div[4] & 0x03) << 2) |
| 411 | | ((data->fan_div[4] & 0x04) << 5); | 418 | | ((data->fan_div[4] & 0x04) << 5); |
| 412 | w83627ehf_write_value(client, W83627EHF_REG_DIODE, reg); | 419 | w83627ehf_write_value(data, W83627EHF_REG_DIODE, reg); |
| 413 | break; | 420 | break; |
| 414 | } | 421 | } |
| 415 | } | 422 | } |
| 416 | 423 | ||
| 417 | static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) | 424 | static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) |
| 418 | { | 425 | { |
| 419 | struct i2c_client *client = to_i2c_client(dev); | 426 | 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 */ | 427 | int pwmcfg = 0, tolerance = 0; /* shut up the compiler */ |
| 422 | int i; | 428 | int i; |
| 423 | 429 | ||
| 424 | mutex_lock(&data->update_lock); | 430 | mutex_lock(&data->update_lock); |
| 425 | 431 | ||
| 426 | if (time_after(jiffies, data->last_updated + HZ) | 432 | if (time_after(jiffies, data->last_updated + HZ + HZ/2) |
| 427 | || !data->valid) { | 433 | || !data->valid) { |
| 428 | /* Fan clock dividers */ | 434 | /* Fan clock dividers */ |
| 429 | i = w83627ehf_read_value(client, W83627EHF_REG_FANDIV1); | 435 | i = w83627ehf_read_value(data, W83627EHF_REG_FANDIV1); |
| 430 | data->fan_div[0] = (i >> 4) & 0x03; | 436 | data->fan_div[0] = (i >> 4) & 0x03; |
| 431 | data->fan_div[1] = (i >> 6) & 0x03; | 437 | data->fan_div[1] = (i >> 6) & 0x03; |
| 432 | i = w83627ehf_read_value(client, W83627EHF_REG_FANDIV2); | 438 | i = w83627ehf_read_value(data, W83627EHF_REG_FANDIV2); |
| 433 | data->fan_div[2] = (i >> 6) & 0x03; | 439 | data->fan_div[2] = (i >> 6) & 0x03; |
| 434 | i = w83627ehf_read_value(client, W83627EHF_REG_VBAT); | 440 | i = w83627ehf_read_value(data, W83627EHF_REG_VBAT); |
| 435 | data->fan_div[0] |= (i >> 3) & 0x04; | 441 | data->fan_div[0] |= (i >> 3) & 0x04; |
| 436 | data->fan_div[1] |= (i >> 4) & 0x04; | 442 | data->fan_div[1] |= (i >> 4) & 0x04; |
| 437 | data->fan_div[2] |= (i >> 5) & 0x04; | 443 | data->fan_div[2] |= (i >> 5) & 0x04; |
| 438 | if (data->has_fan & ((1 << 3) | (1 << 4))) { | 444 | if (data->has_fan & ((1 << 3) | (1 << 4))) { |
| 439 | i = w83627ehf_read_value(client, W83627EHF_REG_DIODE); | 445 | i = w83627ehf_read_value(data, W83627EHF_REG_DIODE); |
| 440 | data->fan_div[3] = i & 0x03; | 446 | data->fan_div[3] = i & 0x03; |
| 441 | data->fan_div[4] = ((i >> 2) & 0x03) | 447 | data->fan_div[4] = ((i >> 2) & 0x03) |
| 442 | | ((i >> 5) & 0x04); | 448 | | ((i >> 5) & 0x04); |
| 443 | } | 449 | } |
| 444 | if (data->has_fan & (1 << 3)) { | 450 | if (data->has_fan & (1 << 3)) { |
| 445 | i = w83627ehf_read_value(client, W83627EHF_REG_SMI_OVT); | 451 | i = w83627ehf_read_value(data, W83627EHF_REG_SMI_OVT); |
| 446 | data->fan_div[3] |= (i >> 5) & 0x04; | 452 | data->fan_div[3] |= (i >> 5) & 0x04; |
| 447 | } | 453 | } |
| 448 | 454 | ||
| 449 | /* Measured voltages and limits */ | 455 | /* Measured voltages and limits */ |
| 450 | for (i = 0; i < w83627ehf_num_in; i++) { | 456 | for (i = 0; i < data->in_num; i++) { |
| 451 | data->in[i] = w83627ehf_read_value(client, | 457 | data->in[i] = w83627ehf_read_value(data, |
| 452 | W83627EHF_REG_IN(i)); | 458 | W83627EHF_REG_IN(i)); |
| 453 | data->in_min[i] = w83627ehf_read_value(client, | 459 | data->in_min[i] = w83627ehf_read_value(data, |
| 454 | W83627EHF_REG_IN_MIN(i)); | 460 | W83627EHF_REG_IN_MIN(i)); |
| 455 | data->in_max[i] = w83627ehf_read_value(client, | 461 | data->in_max[i] = w83627ehf_read_value(data, |
| 456 | W83627EHF_REG_IN_MAX(i)); | 462 | W83627EHF_REG_IN_MAX(i)); |
| 457 | } | 463 | } |
| 458 | 464 | ||
| @@ -461,9 +467,9 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) | |||
| 461 | if (!(data->has_fan & (1 << i))) | 467 | if (!(data->has_fan & (1 << i))) |
| 462 | continue; | 468 | continue; |
| 463 | 469 | ||
| 464 | data->fan[i] = w83627ehf_read_value(client, | 470 | data->fan[i] = w83627ehf_read_value(data, |
| 465 | W83627EHF_REG_FAN[i]); | 471 | W83627EHF_REG_FAN[i]); |
| 466 | data->fan_min[i] = w83627ehf_read_value(client, | 472 | data->fan_min[i] = w83627ehf_read_value(data, |
| 467 | W83627EHF_REG_FAN_MIN[i]); | 473 | W83627EHF_REG_FAN_MIN[i]); |
| 468 | 474 | ||
| 469 | /* If we failed to measure the fan speed and clock | 475 | /* If we failed to measure the fan speed and clock |
| @@ -471,16 +477,16 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) | |||
| 471 | time */ | 477 | time */ |
| 472 | if (data->fan[i] == 0xff | 478 | if (data->fan[i] == 0xff |
| 473 | && data->fan_div[i] < 0x07) { | 479 | && data->fan_div[i] < 0x07) { |
| 474 | dev_dbg(&client->dev, "Increasing fan%d " | 480 | dev_dbg(dev, "Increasing fan%d " |
| 475 | "clock divider from %u to %u\n", | 481 | "clock divider from %u to %u\n", |
| 476 | i + 1, div_from_reg(data->fan_div[i]), | 482 | i + 1, div_from_reg(data->fan_div[i]), |
| 477 | div_from_reg(data->fan_div[i] + 1)); | 483 | div_from_reg(data->fan_div[i] + 1)); |
| 478 | data->fan_div[i]++; | 484 | data->fan_div[i]++; |
| 479 | w83627ehf_write_fan_div(client, i); | 485 | w83627ehf_write_fan_div(data, i); |
| 480 | /* Preserve min limit if possible */ | 486 | /* Preserve min limit if possible */ |
| 481 | if (data->fan_min[i] >= 2 | 487 | if (data->fan_min[i] >= 2 |
| 482 | && data->fan_min[i] != 255) | 488 | && data->fan_min[i] != 255) |
| 483 | w83627ehf_write_value(client, | 489 | w83627ehf_write_value(data, |
| 484 | W83627EHF_REG_FAN_MIN[i], | 490 | W83627EHF_REG_FAN_MIN[i], |
| 485 | (data->fan_min[i] /= 2)); | 491 | (data->fan_min[i] /= 2)); |
| 486 | } | 492 | } |
| @@ -489,9 +495,9 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) | |||
| 489 | for (i = 0; i < 4; i++) { | 495 | for (i = 0; i < 4; i++) { |
| 490 | /* pwmcfg, tolarance mapped for i=0, i=1 to same reg */ | 496 | /* pwmcfg, tolarance mapped for i=0, i=1 to same reg */ |
| 491 | if (i != 1) { | 497 | if (i != 1) { |
| 492 | pwmcfg = w83627ehf_read_value(client, | 498 | pwmcfg = w83627ehf_read_value(data, |
| 493 | W83627EHF_REG_PWM_ENABLE[i]); | 499 | W83627EHF_REG_PWM_ENABLE[i]); |
| 494 | tolerance = w83627ehf_read_value(client, | 500 | tolerance = w83627ehf_read_value(data, |
| 495 | W83627EHF_REG_TOLERANCE[i]); | 501 | W83627EHF_REG_TOLERANCE[i]); |
| 496 | } | 502 | } |
| 497 | data->pwm_mode[i] = | 503 | data->pwm_mode[i] = |
| @@ -500,14 +506,14 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) | |||
| 500 | data->pwm_enable[i] = | 506 | data->pwm_enable[i] = |
| 501 | ((pwmcfg >> W83627EHF_PWM_ENABLE_SHIFT[i]) | 507 | ((pwmcfg >> W83627EHF_PWM_ENABLE_SHIFT[i]) |
| 502 | & 3) + 1; | 508 | & 3) + 1; |
| 503 | data->pwm[i] = w83627ehf_read_value(client, | 509 | data->pwm[i] = w83627ehf_read_value(data, |
| 504 | W83627EHF_REG_PWM[i]); | 510 | W83627EHF_REG_PWM[i]); |
| 505 | data->fan_min_output[i] = w83627ehf_read_value(client, | 511 | data->fan_min_output[i] = w83627ehf_read_value(data, |
| 506 | W83627EHF_REG_FAN_MIN_OUTPUT[i]); | 512 | W83627EHF_REG_FAN_MIN_OUTPUT[i]); |
| 507 | data->fan_stop_time[i] = w83627ehf_read_value(client, | 513 | data->fan_stop_time[i] = w83627ehf_read_value(data, |
| 508 | W83627EHF_REG_FAN_STOP_TIME[i]); | 514 | W83627EHF_REG_FAN_STOP_TIME[i]); |
| 509 | data->target_temp[i] = | 515 | data->target_temp[i] = |
| 510 | w83627ehf_read_value(client, | 516 | w83627ehf_read_value(data, |
| 511 | W83627EHF_REG_TARGET[i]) & | 517 | W83627EHF_REG_TARGET[i]) & |
| 512 | (data->pwm_mode[i] == 1 ? 0x7f : 0xff); | 518 | (data->pwm_mode[i] == 1 ? 0x7f : 0xff); |
| 513 | data->tolerance[i] = (tolerance >> (i == 1 ? 4 : 0)) | 519 | data->tolerance[i] = (tolerance >> (i == 1 ? 4 : 0)) |
| @@ -515,26 +521,26 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) | |||
| 515 | } | 521 | } |
| 516 | 522 | ||
| 517 | /* Measured temperatures and limits */ | 523 | /* Measured temperatures and limits */ |
| 518 | data->temp1 = w83627ehf_read_value(client, | 524 | data->temp1 = w83627ehf_read_value(data, |
| 519 | W83627EHF_REG_TEMP1); | 525 | W83627EHF_REG_TEMP1); |
| 520 | data->temp1_max = w83627ehf_read_value(client, | 526 | data->temp1_max = w83627ehf_read_value(data, |
| 521 | W83627EHF_REG_TEMP1_OVER); | 527 | W83627EHF_REG_TEMP1_OVER); |
| 522 | data->temp1_max_hyst = w83627ehf_read_value(client, | 528 | data->temp1_max_hyst = w83627ehf_read_value(data, |
| 523 | W83627EHF_REG_TEMP1_HYST); | 529 | W83627EHF_REG_TEMP1_HYST); |
| 524 | for (i = 0; i < 2; i++) { | 530 | for (i = 0; i < 2; i++) { |
| 525 | data->temp[i] = w83627ehf_read_value(client, | 531 | data->temp[i] = w83627ehf_read_value(data, |
| 526 | W83627EHF_REG_TEMP[i]); | 532 | W83627EHF_REG_TEMP[i]); |
| 527 | data->temp_max[i] = w83627ehf_read_value(client, | 533 | data->temp_max[i] = w83627ehf_read_value(data, |
| 528 | W83627EHF_REG_TEMP_OVER[i]); | 534 | W83627EHF_REG_TEMP_OVER[i]); |
| 529 | data->temp_max_hyst[i] = w83627ehf_read_value(client, | 535 | data->temp_max_hyst[i] = w83627ehf_read_value(data, |
| 530 | W83627EHF_REG_TEMP_HYST[i]); | 536 | W83627EHF_REG_TEMP_HYST[i]); |
| 531 | } | 537 | } |
| 532 | 538 | ||
| 533 | data->alarms = w83627ehf_read_value(client, | 539 | data->alarms = w83627ehf_read_value(data, |
| 534 | W83627EHF_REG_ALARM1) | | 540 | W83627EHF_REG_ALARM1) | |
| 535 | (w83627ehf_read_value(client, | 541 | (w83627ehf_read_value(data, |
| 536 | W83627EHF_REG_ALARM2) << 8) | | 542 | W83627EHF_REG_ALARM2) << 8) | |
| 537 | (w83627ehf_read_value(client, | 543 | (w83627ehf_read_value(data, |
| 538 | W83627EHF_REG_ALARM3) << 16); | 544 | W83627EHF_REG_ALARM3) << 16); |
| 539 | 545 | ||
| 540 | data->last_updated = jiffies; | 546 | data->last_updated = jiffies; |
| @@ -567,15 +573,14 @@ static ssize_t \ | |||
| 567 | store_in_##reg (struct device *dev, struct device_attribute *attr, \ | 573 | store_in_##reg (struct device *dev, struct device_attribute *attr, \ |
| 568 | const char *buf, size_t count) \ | 574 | const char *buf, size_t count) \ |
| 569 | { \ | 575 | { \ |
| 570 | struct i2c_client *client = to_i2c_client(dev); \ | 576 | 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); \ | 577 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ |
| 573 | int nr = sensor_attr->index; \ | 578 | int nr = sensor_attr->index; \ |
| 574 | u32 val = simple_strtoul(buf, NULL, 10); \ | 579 | u32 val = simple_strtoul(buf, NULL, 10); \ |
| 575 | \ | 580 | \ |
| 576 | mutex_lock(&data->update_lock); \ | 581 | mutex_lock(&data->update_lock); \ |
| 577 | data->in_##reg[nr] = in_to_reg(val, nr); \ | 582 | data->in_##reg[nr] = in_to_reg(val, nr); \ |
| 578 | w83627ehf_write_value(client, W83627EHF_REG_IN_##REG(nr), \ | 583 | w83627ehf_write_value(data, W83627EHF_REG_IN_##REG(nr), \ |
| 579 | data->in_##reg[nr]); \ | 584 | data->in_##reg[nr]); \ |
| 580 | mutex_unlock(&data->update_lock); \ | 585 | mutex_unlock(&data->update_lock); \ |
| 581 | return count; \ | 586 | return count; \ |
| @@ -673,8 +678,7 @@ static ssize_t | |||
| 673 | store_fan_min(struct device *dev, struct device_attribute *attr, | 678 | store_fan_min(struct device *dev, struct device_attribute *attr, |
| 674 | const char *buf, size_t count) | 679 | const char *buf, size_t count) |
| 675 | { | 680 | { |
| 676 | struct i2c_client *client = to_i2c_client(dev); | 681 | 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); | 682 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
| 679 | int nr = sensor_attr->index; | 683 | int nr = sensor_attr->index; |
| 680 | unsigned int val = simple_strtoul(buf, NULL, 10); | 684 | unsigned int val = simple_strtoul(buf, NULL, 10); |
| @@ -716,18 +720,25 @@ store_fan_min(struct device *dev, struct device_attribute *attr, | |||
| 716 | /* Write both the fan clock divider (if it changed) and the new | 720 | /* Write both the fan clock divider (if it changed) and the new |
| 717 | fan min (unconditionally) */ | 721 | fan min (unconditionally) */ |
| 718 | if (new_div != data->fan_div[nr]) { | 722 | if (new_div != data->fan_div[nr]) { |
| 719 | if (new_div > data->fan_div[nr]) | 723 | /* Preserve the fan speed reading */ |
| 720 | data->fan[nr] >>= (data->fan_div[nr] - new_div); | 724 | if (data->fan[nr] != 0xff) { |
| 721 | else | 725 | if (new_div > data->fan_div[nr]) |
| 722 | data->fan[nr] <<= (new_div - data->fan_div[nr]); | 726 | data->fan[nr] >>= new_div - data->fan_div[nr]; |
| 727 | else if (data->fan[nr] & 0x80) | ||
| 728 | data->fan[nr] = 0xff; | ||
| 729 | else | ||
| 730 | data->fan[nr] <<= data->fan_div[nr] - new_div; | ||
| 731 | } | ||
| 723 | 732 | ||
| 724 | dev_dbg(dev, "fan%u clock divider changed from %u to %u\n", | 733 | dev_dbg(dev, "fan%u clock divider changed from %u to %u\n", |
| 725 | nr + 1, div_from_reg(data->fan_div[nr]), | 734 | nr + 1, div_from_reg(data->fan_div[nr]), |
| 726 | div_from_reg(new_div)); | 735 | div_from_reg(new_div)); |
| 727 | data->fan_div[nr] = new_div; | 736 | data->fan_div[nr] = new_div; |
| 728 | w83627ehf_write_fan_div(client, nr); | 737 | w83627ehf_write_fan_div(data, nr); |
| 738 | /* Give the chip time to sample a new speed value */ | ||
| 739 | data->last_updated = jiffies; | ||
| 729 | } | 740 | } |
| 730 | w83627ehf_write_value(client, W83627EHF_REG_FAN_MIN[nr], | 741 | w83627ehf_write_value(data, W83627EHF_REG_FAN_MIN[nr], |
| 731 | data->fan_min[nr]); | 742 | data->fan_min[nr]); |
| 732 | mutex_unlock(&data->update_lock); | 743 | mutex_unlock(&data->update_lock); |
| 733 | 744 | ||
| @@ -788,13 +799,12 @@ static ssize_t \ | |||
| 788 | store_temp1_##reg(struct device *dev, struct device_attribute *attr, \ | 799 | store_temp1_##reg(struct device *dev, struct device_attribute *attr, \ |
| 789 | const char *buf, size_t count) \ | 800 | const char *buf, size_t count) \ |
| 790 | { \ | 801 | { \ |
| 791 | struct i2c_client *client = to_i2c_client(dev); \ | 802 | struct w83627ehf_data *data = dev_get_drvdata(dev); \ |
| 792 | struct w83627ehf_data *data = i2c_get_clientdata(client); \ | ||
| 793 | u32 val = simple_strtoul(buf, NULL, 10); \ | 803 | u32 val = simple_strtoul(buf, NULL, 10); \ |
| 794 | \ | 804 | \ |
| 795 | mutex_lock(&data->update_lock); \ | 805 | mutex_lock(&data->update_lock); \ |
| 796 | data->temp1_##reg = temp1_to_reg(val, -128000, 127000); \ | 806 | data->temp1_##reg = temp1_to_reg(val, -128000, 127000); \ |
| 797 | w83627ehf_write_value(client, W83627EHF_REG_TEMP1_##REG, \ | 807 | w83627ehf_write_value(data, W83627EHF_REG_TEMP1_##REG, \ |
| 798 | data->temp1_##reg); \ | 808 | data->temp1_##reg); \ |
| 799 | mutex_unlock(&data->update_lock); \ | 809 | mutex_unlock(&data->update_lock); \ |
| 800 | return count; \ | 810 | return count; \ |
| @@ -822,15 +832,14 @@ static ssize_t \ | |||
| 822 | store_##reg(struct device *dev, struct device_attribute *attr, \ | 832 | store_##reg(struct device *dev, struct device_attribute *attr, \ |
| 823 | const char *buf, size_t count) \ | 833 | const char *buf, size_t count) \ |
| 824 | { \ | 834 | { \ |
| 825 | struct i2c_client *client = to_i2c_client(dev); \ | 835 | struct w83627ehf_data *data = dev_get_drvdata(dev); \ |
| 826 | struct w83627ehf_data *data = i2c_get_clientdata(client); \ | ||
| 827 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ | 836 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ |
| 828 | int nr = sensor_attr->index; \ | 837 | int nr = sensor_attr->index; \ |
| 829 | u32 val = simple_strtoul(buf, NULL, 10); \ | 838 | u32 val = simple_strtoul(buf, NULL, 10); \ |
| 830 | \ | 839 | \ |
| 831 | mutex_lock(&data->update_lock); \ | 840 | mutex_lock(&data->update_lock); \ |
| 832 | data->reg[nr] = LM75_TEMP_TO_REG(val); \ | 841 | data->reg[nr] = LM75_TEMP_TO_REG(val); \ |
| 833 | w83627ehf_write_value(client, W83627EHF_REG_TEMP_##REG[nr], \ | 842 | w83627ehf_write_value(data, W83627EHF_REG_TEMP_##REG[nr], \ |
| 834 | data->reg[nr]); \ | 843 | data->reg[nr]); \ |
| 835 | mutex_unlock(&data->update_lock); \ | 844 | mutex_unlock(&data->update_lock); \ |
| 836 | return count; \ | 845 | return count; \ |
| @@ -838,6 +847,15 @@ store_##reg(struct device *dev, struct device_attribute *attr, \ | |||
| 838 | store_temp_reg(OVER, temp_max); | 847 | store_temp_reg(OVER, temp_max); |
| 839 | store_temp_reg(HYST, temp_max_hyst); | 848 | store_temp_reg(HYST, temp_max_hyst); |
| 840 | 849 | ||
| 850 | static ssize_t | ||
| 851 | show_temp_type(struct device *dev, struct device_attribute *attr, char *buf) | ||
| 852 | { | ||
| 853 | struct w83627ehf_data *data = w83627ehf_update_device(dev); | ||
| 854 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
| 855 | int nr = sensor_attr->index; | ||
| 856 | return sprintf(buf, "%d\n", (int)data->temp_type[nr]); | ||
| 857 | } | ||
| 858 | |||
| 841 | static struct sensor_device_attribute sda_temp[] = { | 859 | static struct sensor_device_attribute sda_temp[] = { |
| 842 | SENSOR_ATTR(temp1_input, S_IRUGO, show_temp1, NULL, 0), | 860 | SENSOR_ATTR(temp1_input, S_IRUGO, show_temp1, NULL, 0), |
| 843 | SENSOR_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 0), | 861 | SENSOR_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 0), |
| @@ -857,6 +875,9 @@ static struct sensor_device_attribute sda_temp[] = { | |||
| 857 | SENSOR_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4), | 875 | SENSOR_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4), |
| 858 | SENSOR_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 5), | 876 | SENSOR_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 5), |
| 859 | SENSOR_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 13), | 877 | SENSOR_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 13), |
| 878 | SENSOR_ATTR(temp1_type, S_IRUGO, show_temp_type, NULL, 0), | ||
| 879 | SENSOR_ATTR(temp2_type, S_IRUGO, show_temp_type, NULL, 1), | ||
| 880 | SENSOR_ATTR(temp3_type, S_IRUGO, show_temp_type, NULL, 2), | ||
| 860 | }; | 881 | }; |
| 861 | 882 | ||
| 862 | #define show_pwm_reg(reg) \ | 883 | #define show_pwm_reg(reg) \ |
| @@ -877,8 +898,7 @@ static ssize_t | |||
| 877 | store_pwm_mode(struct device *dev, struct device_attribute *attr, | 898 | store_pwm_mode(struct device *dev, struct device_attribute *attr, |
| 878 | const char *buf, size_t count) | 899 | const char *buf, size_t count) |
| 879 | { | 900 | { |
| 880 | struct i2c_client *client = to_i2c_client(dev); | 901 | struct w83627ehf_data *data = dev_get_drvdata(dev); |
| 881 | struct w83627ehf_data *data = i2c_get_clientdata(client); | ||
| 882 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 902 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
| 883 | int nr = sensor_attr->index; | 903 | int nr = sensor_attr->index; |
| 884 | u32 val = simple_strtoul(buf, NULL, 10); | 904 | u32 val = simple_strtoul(buf, NULL, 10); |
| @@ -887,12 +907,12 @@ store_pwm_mode(struct device *dev, struct device_attribute *attr, | |||
| 887 | if (val > 1) | 907 | if (val > 1) |
| 888 | return -EINVAL; | 908 | return -EINVAL; |
| 889 | mutex_lock(&data->update_lock); | 909 | mutex_lock(&data->update_lock); |
| 890 | reg = w83627ehf_read_value(client, W83627EHF_REG_PWM_ENABLE[nr]); | 910 | reg = w83627ehf_read_value(data, W83627EHF_REG_PWM_ENABLE[nr]); |
| 891 | data->pwm_mode[nr] = val; | 911 | data->pwm_mode[nr] = val; |
| 892 | reg &= ~(1 << W83627EHF_PWM_MODE_SHIFT[nr]); | 912 | reg &= ~(1 << W83627EHF_PWM_MODE_SHIFT[nr]); |
| 893 | if (!val) | 913 | if (!val) |
| 894 | reg |= 1 << W83627EHF_PWM_MODE_SHIFT[nr]; | 914 | reg |= 1 << W83627EHF_PWM_MODE_SHIFT[nr]; |
| 895 | w83627ehf_write_value(client, W83627EHF_REG_PWM_ENABLE[nr], reg); | 915 | w83627ehf_write_value(data, W83627EHF_REG_PWM_ENABLE[nr], reg); |
| 896 | mutex_unlock(&data->update_lock); | 916 | mutex_unlock(&data->update_lock); |
| 897 | return count; | 917 | return count; |
| 898 | } | 918 | } |
| @@ -901,15 +921,14 @@ static ssize_t | |||
| 901 | store_pwm(struct device *dev, struct device_attribute *attr, | 921 | store_pwm(struct device *dev, struct device_attribute *attr, |
| 902 | const char *buf, size_t count) | 922 | const char *buf, size_t count) |
| 903 | { | 923 | { |
| 904 | struct i2c_client *client = to_i2c_client(dev); | 924 | struct w83627ehf_data *data = dev_get_drvdata(dev); |
| 905 | struct w83627ehf_data *data = i2c_get_clientdata(client); | ||
| 906 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 925 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
| 907 | int nr = sensor_attr->index; | 926 | int nr = sensor_attr->index; |
| 908 | u32 val = SENSORS_LIMIT(simple_strtoul(buf, NULL, 10), 0, 255); | 927 | u32 val = SENSORS_LIMIT(simple_strtoul(buf, NULL, 10), 0, 255); |
| 909 | 928 | ||
| 910 | mutex_lock(&data->update_lock); | 929 | mutex_lock(&data->update_lock); |
| 911 | data->pwm[nr] = val; | 930 | data->pwm[nr] = val; |
| 912 | w83627ehf_write_value(client, W83627EHF_REG_PWM[nr], val); | 931 | w83627ehf_write_value(data, W83627EHF_REG_PWM[nr], val); |
| 913 | mutex_unlock(&data->update_lock); | 932 | mutex_unlock(&data->update_lock); |
| 914 | return count; | 933 | return count; |
| 915 | } | 934 | } |
| @@ -918,8 +937,7 @@ static ssize_t | |||
| 918 | store_pwm_enable(struct device *dev, struct device_attribute *attr, | 937 | store_pwm_enable(struct device *dev, struct device_attribute *attr, |
| 919 | const char *buf, size_t count) | 938 | const char *buf, size_t count) |
| 920 | { | 939 | { |
| 921 | struct i2c_client *client = to_i2c_client(dev); | 940 | struct w83627ehf_data *data = dev_get_drvdata(dev); |
| 922 | struct w83627ehf_data *data = i2c_get_clientdata(client); | ||
| 923 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 941 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
| 924 | int nr = sensor_attr->index; | 942 | int nr = sensor_attr->index; |
| 925 | u32 val = simple_strtoul(buf, NULL, 10); | 943 | u32 val = simple_strtoul(buf, NULL, 10); |
| @@ -928,11 +946,11 @@ store_pwm_enable(struct device *dev, struct device_attribute *attr, | |||
| 928 | if (!val || (val > 2)) /* only modes 1 and 2 are supported */ | 946 | if (!val || (val > 2)) /* only modes 1 and 2 are supported */ |
| 929 | return -EINVAL; | 947 | return -EINVAL; |
| 930 | mutex_lock(&data->update_lock); | 948 | mutex_lock(&data->update_lock); |
| 931 | reg = w83627ehf_read_value(client, W83627EHF_REG_PWM_ENABLE[nr]); | 949 | reg = w83627ehf_read_value(data, W83627EHF_REG_PWM_ENABLE[nr]); |
| 932 | data->pwm_enable[nr] = val; | 950 | data->pwm_enable[nr] = val; |
| 933 | reg &= ~(0x03 << W83627EHF_PWM_ENABLE_SHIFT[nr]); | 951 | reg &= ~(0x03 << W83627EHF_PWM_ENABLE_SHIFT[nr]); |
| 934 | reg |= (val - 1) << W83627EHF_PWM_ENABLE_SHIFT[nr]; | 952 | reg |= (val - 1) << W83627EHF_PWM_ENABLE_SHIFT[nr]; |
| 935 | w83627ehf_write_value(client, W83627EHF_REG_PWM_ENABLE[nr], reg); | 953 | w83627ehf_write_value(data, W83627EHF_REG_PWM_ENABLE[nr], reg); |
| 936 | mutex_unlock(&data->update_lock); | 954 | mutex_unlock(&data->update_lock); |
| 937 | return count; | 955 | return count; |
| 938 | } | 956 | } |
| @@ -955,15 +973,14 @@ static ssize_t | |||
| 955 | store_target_temp(struct device *dev, struct device_attribute *attr, | 973 | store_target_temp(struct device *dev, struct device_attribute *attr, |
| 956 | const char *buf, size_t count) | 974 | const char *buf, size_t count) |
| 957 | { | 975 | { |
| 958 | struct i2c_client *client = to_i2c_client(dev); | 976 | struct w83627ehf_data *data = dev_get_drvdata(dev); |
| 959 | struct w83627ehf_data *data = i2c_get_clientdata(client); | ||
| 960 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 977 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
| 961 | int nr = sensor_attr->index; | 978 | int nr = sensor_attr->index; |
| 962 | u8 val = temp1_to_reg(simple_strtoul(buf, NULL, 10), 0, 127000); | 979 | u8 val = temp1_to_reg(simple_strtoul(buf, NULL, 10), 0, 127000); |
| 963 | 980 | ||
| 964 | mutex_lock(&data->update_lock); | 981 | mutex_lock(&data->update_lock); |
| 965 | data->target_temp[nr] = val; | 982 | data->target_temp[nr] = val; |
| 966 | w83627ehf_write_value(client, W83627EHF_REG_TARGET[nr], val); | 983 | w83627ehf_write_value(data, W83627EHF_REG_TARGET[nr], val); |
| 967 | mutex_unlock(&data->update_lock); | 984 | mutex_unlock(&data->update_lock); |
| 968 | return count; | 985 | return count; |
| 969 | } | 986 | } |
| @@ -972,8 +989,7 @@ static ssize_t | |||
| 972 | store_tolerance(struct device *dev, struct device_attribute *attr, | 989 | store_tolerance(struct device *dev, struct device_attribute *attr, |
| 973 | const char *buf, size_t count) | 990 | const char *buf, size_t count) |
| 974 | { | 991 | { |
| 975 | struct i2c_client *client = to_i2c_client(dev); | 992 | struct w83627ehf_data *data = dev_get_drvdata(dev); |
| 976 | struct w83627ehf_data *data = i2c_get_clientdata(client); | ||
| 977 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 993 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
| 978 | int nr = sensor_attr->index; | 994 | int nr = sensor_attr->index; |
| 979 | u16 reg; | 995 | u16 reg; |
| @@ -981,13 +997,13 @@ store_tolerance(struct device *dev, struct device_attribute *attr, | |||
| 981 | u8 val = temp1_to_reg(simple_strtoul(buf, NULL, 10), 0, 15000); | 997 | u8 val = temp1_to_reg(simple_strtoul(buf, NULL, 10), 0, 15000); |
| 982 | 998 | ||
| 983 | mutex_lock(&data->update_lock); | 999 | mutex_lock(&data->update_lock); |
| 984 | reg = w83627ehf_read_value(client, W83627EHF_REG_TOLERANCE[nr]); | 1000 | reg = w83627ehf_read_value(data, W83627EHF_REG_TOLERANCE[nr]); |
| 985 | data->tolerance[nr] = val; | 1001 | data->tolerance[nr] = val; |
| 986 | if (nr == 1) | 1002 | if (nr == 1) |
| 987 | reg = (reg & 0x0f) | (val << 4); | 1003 | reg = (reg & 0x0f) | (val << 4); |
| 988 | else | 1004 | else |
| 989 | reg = (reg & 0xf0) | val; | 1005 | reg = (reg & 0xf0) | val; |
| 990 | w83627ehf_write_value(client, W83627EHF_REG_TOLERANCE[nr], reg); | 1006 | w83627ehf_write_value(data, W83627EHF_REG_TOLERANCE[nr], reg); |
| 991 | mutex_unlock(&data->update_lock); | 1007 | mutex_unlock(&data->update_lock); |
| 992 | return count; | 1008 | return count; |
| 993 | } | 1009 | } |
| @@ -1058,14 +1074,13 @@ static ssize_t \ | |||
| 1058 | store_##reg(struct device *dev, struct device_attribute *attr, \ | 1074 | store_##reg(struct device *dev, struct device_attribute *attr, \ |
| 1059 | const char *buf, size_t count) \ | 1075 | const char *buf, size_t count) \ |
| 1060 | {\ | 1076 | {\ |
| 1061 | struct i2c_client *client = to_i2c_client(dev); \ | 1077 | struct w83627ehf_data *data = dev_get_drvdata(dev); \ |
| 1062 | struct w83627ehf_data *data = i2c_get_clientdata(client); \ | ||
| 1063 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ | 1078 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ |
| 1064 | int nr = sensor_attr->index; \ | 1079 | int nr = sensor_attr->index; \ |
| 1065 | u32 val = SENSORS_LIMIT(simple_strtoul(buf, NULL, 10), 1, 255); \ | 1080 | u32 val = SENSORS_LIMIT(simple_strtoul(buf, NULL, 10), 1, 255); \ |
| 1066 | mutex_lock(&data->update_lock); \ | 1081 | mutex_lock(&data->update_lock); \ |
| 1067 | data->reg[nr] = val; \ | 1082 | data->reg[nr] = val; \ |
| 1068 | w83627ehf_write_value(client, W83627EHF_REG_##REG[nr], val); \ | 1083 | w83627ehf_write_value(data, W83627EHF_REG_##REG[nr], val); \ |
| 1069 | mutex_unlock(&data->update_lock); \ | 1084 | mutex_unlock(&data->update_lock); \ |
| 1070 | return count; \ | 1085 | return count; \ |
| 1071 | } | 1086 | } |
| @@ -1087,21 +1102,28 @@ static ssize_t \ | |||
| 1087 | store_##reg(struct device *dev, struct device_attribute *attr, \ | 1102 | store_##reg(struct device *dev, struct device_attribute *attr, \ |
| 1088 | const char *buf, size_t count) \ | 1103 | const char *buf, size_t count) \ |
| 1089 | { \ | 1104 | { \ |
| 1090 | struct i2c_client *client = to_i2c_client(dev); \ | 1105 | struct w83627ehf_data *data = dev_get_drvdata(dev); \ |
| 1091 | struct w83627ehf_data *data = i2c_get_clientdata(client); \ | ||
| 1092 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ | 1106 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ |
| 1093 | int nr = sensor_attr->index; \ | 1107 | int nr = sensor_attr->index; \ |
| 1094 | u8 val = step_time_to_reg(simple_strtoul(buf, NULL, 10), \ | 1108 | u8 val = step_time_to_reg(simple_strtoul(buf, NULL, 10), \ |
| 1095 | data->pwm_mode[nr]); \ | 1109 | data->pwm_mode[nr]); \ |
| 1096 | mutex_lock(&data->update_lock); \ | 1110 | mutex_lock(&data->update_lock); \ |
| 1097 | data->reg[nr] = val; \ | 1111 | data->reg[nr] = val; \ |
| 1098 | w83627ehf_write_value(client, W83627EHF_REG_##REG[nr], val); \ | 1112 | w83627ehf_write_value(data, W83627EHF_REG_##REG[nr], val); \ |
| 1099 | mutex_unlock(&data->update_lock); \ | 1113 | mutex_unlock(&data->update_lock); \ |
| 1100 | return count; \ | 1114 | return count; \ |
| 1101 | } \ | 1115 | } \ |
| 1102 | 1116 | ||
| 1103 | fan_time_functions(fan_stop_time, FAN_STOP_TIME) | 1117 | fan_time_functions(fan_stop_time, FAN_STOP_TIME) |
| 1104 | 1118 | ||
| 1119 | static ssize_t show_name(struct device *dev, struct device_attribute *attr, | ||
| 1120 | char *buf) | ||
| 1121 | { | ||
| 1122 | struct w83627ehf_data *data = dev_get_drvdata(dev); | ||
| 1123 | |||
| 1124 | return sprintf(buf, "%s\n", data->name); | ||
| 1125 | } | ||
| 1126 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); | ||
| 1105 | 1127 | ||
| 1106 | static struct sensor_device_attribute sda_sf3_arrays_fan4[] = { | 1128 | static struct sensor_device_attribute sda_sf3_arrays_fan4[] = { |
| 1107 | SENSOR_ATTR(pwm4_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time, | 1129 | SENSOR_ATTR(pwm4_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time, |
| @@ -1125,8 +1147,16 @@ static struct sensor_device_attribute sda_sf3_arrays[] = { | |||
| 1125 | store_fan_min_output, 2), | 1147 | store_fan_min_output, 2), |
| 1126 | }; | 1148 | }; |
| 1127 | 1149 | ||
| 1150 | static ssize_t | ||
| 1151 | show_vid(struct device *dev, struct device_attribute *attr, char *buf) | ||
| 1152 | { | ||
| 1153 | struct w83627ehf_data *data = dev_get_drvdata(dev); | ||
| 1154 | return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm)); | ||
| 1155 | } | ||
| 1156 | static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL); | ||
| 1157 | |||
| 1128 | /* | 1158 | /* |
| 1129 | * Driver and client management | 1159 | * Driver and device management |
| 1130 | */ | 1160 | */ |
| 1131 | 1161 | ||
| 1132 | static void w83627ehf_device_remove_files(struct device *dev) | 1162 | static void w83627ehf_device_remove_files(struct device *dev) |
| @@ -1134,12 +1164,13 @@ static void w83627ehf_device_remove_files(struct device *dev) | |||
| 1134 | /* some entries in the following arrays may not have been used in | 1164 | /* some entries in the following arrays may not have been used in |
| 1135 | * device_create_file(), but device_remove_file() will ignore them */ | 1165 | * device_create_file(), but device_remove_file() will ignore them */ |
| 1136 | int i; | 1166 | int i; |
| 1167 | struct w83627ehf_data *data = dev_get_drvdata(dev); | ||
| 1137 | 1168 | ||
| 1138 | for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays); i++) | 1169 | for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays); i++) |
| 1139 | device_remove_file(dev, &sda_sf3_arrays[i].dev_attr); | 1170 | device_remove_file(dev, &sda_sf3_arrays[i].dev_attr); |
| 1140 | for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++) | 1171 | for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++) |
| 1141 | device_remove_file(dev, &sda_sf3_arrays_fan4[i].dev_attr); | 1172 | device_remove_file(dev, &sda_sf3_arrays_fan4[i].dev_attr); |
| 1142 | for (i = 0; i < w83627ehf_num_in; i++) { | 1173 | for (i = 0; i < data->in_num; i++) { |
| 1143 | device_remove_file(dev, &sda_in_input[i].dev_attr); | 1174 | device_remove_file(dev, &sda_in_input[i].dev_attr); |
| 1144 | device_remove_file(dev, &sda_in_alarm[i].dev_attr); | 1175 | device_remove_file(dev, &sda_in_alarm[i].dev_attr); |
| 1145 | device_remove_file(dev, &sda_in_min[i].dev_attr); | 1176 | device_remove_file(dev, &sda_in_min[i].dev_attr); |
| @@ -1160,43 +1191,64 @@ static void w83627ehf_device_remove_files(struct device *dev) | |||
| 1160 | } | 1191 | } |
| 1161 | for (i = 0; i < ARRAY_SIZE(sda_temp); i++) | 1192 | for (i = 0; i < ARRAY_SIZE(sda_temp); i++) |
| 1162 | device_remove_file(dev, &sda_temp[i].dev_attr); | 1193 | device_remove_file(dev, &sda_temp[i].dev_attr); |
| 1163 | } | ||
| 1164 | 1194 | ||
| 1165 | static struct i2c_driver w83627ehf_driver; | 1195 | device_remove_file(dev, &dev_attr_name); |
| 1196 | if (data->vid != 0x3f) | ||
| 1197 | device_remove_file(dev, &dev_attr_cpu0_vid); | ||
| 1198 | } | ||
| 1166 | 1199 | ||
| 1167 | static void w83627ehf_init_client(struct i2c_client *client) | 1200 | /* Get the monitoring functions started */ |
| 1201 | static inline void __devinit w83627ehf_init_device(struct w83627ehf_data *data) | ||
| 1168 | { | 1202 | { |
| 1169 | int i; | 1203 | int i; |
| 1170 | u8 tmp; | 1204 | u8 tmp, diode; |
| 1171 | 1205 | ||
| 1172 | /* Start monitoring is needed */ | 1206 | /* Start monitoring is needed */ |
| 1173 | tmp = w83627ehf_read_value(client, W83627EHF_REG_CONFIG); | 1207 | tmp = w83627ehf_read_value(data, W83627EHF_REG_CONFIG); |
| 1174 | if (!(tmp & 0x01)) | 1208 | if (!(tmp & 0x01)) |
| 1175 | w83627ehf_write_value(client, W83627EHF_REG_CONFIG, | 1209 | w83627ehf_write_value(data, W83627EHF_REG_CONFIG, |
| 1176 | tmp | 0x01); | 1210 | tmp | 0x01); |
| 1177 | 1211 | ||
| 1178 | /* Enable temp2 and temp3 if needed */ | 1212 | /* Enable temp2 and temp3 if needed */ |
| 1179 | for (i = 0; i < 2; i++) { | 1213 | for (i = 0; i < 2; i++) { |
| 1180 | tmp = w83627ehf_read_value(client, | 1214 | tmp = w83627ehf_read_value(data, |
| 1181 | W83627EHF_REG_TEMP_CONFIG[i]); | 1215 | W83627EHF_REG_TEMP_CONFIG[i]); |
| 1182 | if (tmp & 0x01) | 1216 | if (tmp & 0x01) |
| 1183 | w83627ehf_write_value(client, | 1217 | w83627ehf_write_value(data, |
| 1184 | W83627EHF_REG_TEMP_CONFIG[i], | 1218 | W83627EHF_REG_TEMP_CONFIG[i], |
| 1185 | tmp & 0xfe); | 1219 | tmp & 0xfe); |
| 1186 | } | 1220 | } |
| 1221 | |||
| 1222 | /* Enable VBAT monitoring if needed */ | ||
| 1223 | tmp = w83627ehf_read_value(data, W83627EHF_REG_VBAT); | ||
| 1224 | if (!(tmp & 0x01)) | ||
| 1225 | w83627ehf_write_value(data, W83627EHF_REG_VBAT, tmp | 0x01); | ||
| 1226 | |||
| 1227 | /* Get thermal sensor types */ | ||
| 1228 | diode = w83627ehf_read_value(data, W83627EHF_REG_DIODE); | ||
| 1229 | for (i = 0; i < 3; i++) { | ||
| 1230 | if ((tmp & (0x02 << i))) | ||
| 1231 | data->temp_type[i] = (diode & (0x10 << i)) ? 1 : 2; | ||
| 1232 | else | ||
| 1233 | data->temp_type[i] = 4; /* thermistor */ | ||
| 1234 | } | ||
| 1187 | } | 1235 | } |
| 1188 | 1236 | ||
| 1189 | static int w83627ehf_detect(struct i2c_adapter *adapter) | 1237 | static int __devinit w83627ehf_probe(struct platform_device *pdev) |
| 1190 | { | 1238 | { |
| 1191 | struct i2c_client *client; | 1239 | struct device *dev = &pdev->dev; |
| 1240 | struct w83627ehf_sio_data *sio_data = dev->platform_data; | ||
| 1192 | struct w83627ehf_data *data; | 1241 | struct w83627ehf_data *data; |
| 1193 | struct device *dev; | 1242 | struct resource *res; |
| 1194 | u8 fan4pin, fan5pin; | 1243 | u8 fan4pin, fan5pin, en_vrm10; |
| 1195 | int i, err = 0; | 1244 | int i, err = 0; |
| 1196 | 1245 | ||
| 1197 | if (!request_region(address + IOREGION_OFFSET, IOREGION_LENGTH, | 1246 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
| 1198 | w83627ehf_driver.driver.name)) { | 1247 | if (!request_region(res->start, IOREGION_LENGTH, DRVNAME)) { |
| 1199 | err = -EBUSY; | 1248 | err = -EBUSY; |
| 1249 | dev_err(dev, "Failed to request region 0x%lx-0x%lx\n", | ||
| 1250 | (unsigned long)res->start, | ||
| 1251 | (unsigned long)res->start + IOREGION_LENGTH - 1); | ||
| 1200 | goto exit; | 1252 | goto exit; |
| 1201 | } | 1253 | } |
| 1202 | 1254 | ||
| @@ -1205,41 +1257,47 @@ static int w83627ehf_detect(struct i2c_adapter *adapter) | |||
| 1205 | goto exit_release; | 1257 | goto exit_release; |
| 1206 | } | 1258 | } |
| 1207 | 1259 | ||
| 1208 | client = &data->client; | 1260 | data->addr = res->start; |
| 1209 | i2c_set_clientdata(client, data); | ||
| 1210 | client->addr = address; | ||
| 1211 | mutex_init(&data->lock); | 1261 | mutex_init(&data->lock); |
| 1212 | client->adapter = adapter; | ||
| 1213 | client->driver = &w83627ehf_driver; | ||
| 1214 | client->flags = 0; | ||
| 1215 | dev = &client->dev; | ||
| 1216 | |||
| 1217 | if (w83627ehf_num_in == 9) | ||
| 1218 | strlcpy(client->name, "w83627dhg", I2C_NAME_SIZE); | ||
| 1219 | else /* just say ehf. 627EHG is 627EHF in lead-free packaging. */ | ||
| 1220 | strlcpy(client->name, "w83627ehf", I2C_NAME_SIZE); | ||
| 1221 | |||
| 1222 | data->valid = 0; | ||
| 1223 | mutex_init(&data->update_lock); | 1262 | mutex_init(&data->update_lock); |
| 1263 | data->name = w83627ehf_device_names[sio_data->kind]; | ||
| 1264 | platform_set_drvdata(pdev, data); | ||
| 1224 | 1265 | ||
| 1225 | /* Tell the i2c layer a new client has arrived */ | 1266 | /* 627EHG and 627EHF have 10 voltage inputs; DHG has 9 */ |
| 1226 | if ((err = i2c_attach_client(client))) | 1267 | data->in_num = (sio_data->kind == w83627dhg) ? 9 : 10; |
| 1227 | goto exit_free; | ||
| 1228 | 1268 | ||
| 1229 | /* Initialize the chip */ | 1269 | /* Initialize the chip */ |
| 1230 | w83627ehf_init_client(client); | 1270 | w83627ehf_init_device(data); |
| 1231 | 1271 | ||
| 1232 | /* A few vars need to be filled upon startup */ | 1272 | data->vrm = vid_which_vrm(); |
| 1233 | for (i = 0; i < 5; i++) | 1273 | superio_enter(sio_data->sioreg); |
| 1234 | data->fan_min[i] = w83627ehf_read_value(client, | 1274 | /* Set VID input sensibility if needed. In theory the BIOS should |
| 1235 | W83627EHF_REG_FAN_MIN[i]); | 1275 | have set it, but in practice it's not always the case. */ |
| 1276 | en_vrm10 = superio_inb(sio_data->sioreg, SIO_REG_EN_VRM10); | ||
| 1277 | if ((en_vrm10 & 0x08) && data->vrm != 100) { | ||
| 1278 | dev_warn(dev, "Setting VID input voltage to TTL\n"); | ||
| 1279 | superio_outb(sio_data->sioreg, SIO_REG_EN_VRM10, | ||
| 1280 | en_vrm10 & ~0x08); | ||
| 1281 | } else if (!(en_vrm10 & 0x08) && data->vrm == 100) { | ||
| 1282 | dev_warn(dev, "Setting VID input voltage to VRM10\n"); | ||
| 1283 | superio_outb(sio_data->sioreg, SIO_REG_EN_VRM10, | ||
| 1284 | en_vrm10 | 0x08); | ||
| 1285 | } | ||
| 1286 | /* Read VID value */ | ||
| 1287 | superio_select(sio_data->sioreg, W83627EHF_LD_HWM); | ||
| 1288 | if (superio_inb(sio_data->sioreg, SIO_REG_VID_CTRL) & 0x80) | ||
| 1289 | data->vid = superio_inb(sio_data->sioreg, SIO_REG_VID_DATA) & 0x3f; | ||
| 1290 | else { | ||
| 1291 | dev_info(dev, "VID pins in output mode, CPU VID not " | ||
| 1292 | "available\n"); | ||
| 1293 | data->vid = 0x3f; | ||
| 1294 | } | ||
| 1236 | 1295 | ||
| 1237 | /* fan4 and fan5 share some pins with the GPIO and serial flash */ | 1296 | /* fan4 and fan5 share some pins with the GPIO and serial flash */ |
| 1238 | 1297 | ||
| 1239 | superio_enter(); | 1298 | fan5pin = superio_inb(sio_data->sioreg, 0x24) & 0x2; |
| 1240 | fan5pin = superio_inb(0x24) & 0x2; | 1299 | fan4pin = superio_inb(sio_data->sioreg, 0x29) & 0x6; |
| 1241 | fan4pin = superio_inb(0x29) & 0x6; | 1300 | superio_exit(sio_data->sioreg); |
| 1242 | superio_exit(); | ||
| 1243 | 1301 | ||
| 1244 | /* It looks like fan4 and fan5 pins can be alternatively used | 1302 | /* It looks like fan4 and fan5 pins can be alternatively used |
| 1245 | as fan on/off switches, but fan5 control is write only :/ | 1303 | as fan on/off switches, but fan5 control is write only :/ |
| @@ -1248,7 +1306,7 @@ static int w83627ehf_detect(struct i2c_adapter *adapter) | |||
| 1248 | is not the default. */ | 1306 | is not the default. */ |
| 1249 | 1307 | ||
| 1250 | data->has_fan = 0x07; /* fan1, fan2 and fan3 */ | 1308 | data->has_fan = 0x07; /* fan1, fan2 and fan3 */ |
| 1251 | i = w83627ehf_read_value(client, W83627EHF_REG_FANDIV1); | 1309 | i = w83627ehf_read_value(data, W83627EHF_REG_FANDIV1); |
| 1252 | if ((i & (1 << 2)) && (!fan4pin)) | 1310 | if ((i & (1 << 2)) && (!fan4pin)) |
| 1253 | data->has_fan |= (1 << 3); | 1311 | data->has_fan |= (1 << 3); |
| 1254 | if (!(i & (1 << 1)) && (!fan5pin)) | 1312 | if (!(i & (1 << 1)) && (!fan5pin)) |
| @@ -1268,7 +1326,7 @@ static int w83627ehf_detect(struct i2c_adapter *adapter) | |||
| 1268 | goto exit_remove; | 1326 | goto exit_remove; |
| 1269 | } | 1327 | } |
| 1270 | 1328 | ||
| 1271 | for (i = 0; i < w83627ehf_num_in; i++) | 1329 | for (i = 0; i < data->in_num; i++) |
| 1272 | if ((err = device_create_file(dev, &sda_in_input[i].dev_attr)) | 1330 | if ((err = device_create_file(dev, &sda_in_input[i].dev_attr)) |
| 1273 | || (err = device_create_file(dev, | 1331 | || (err = device_create_file(dev, |
| 1274 | &sda_in_alarm[i].dev_attr)) | 1332 | &sda_in_alarm[i].dev_attr)) |
| @@ -1308,6 +1366,16 @@ static int w83627ehf_detect(struct i2c_adapter *adapter) | |||
| 1308 | if ((err = device_create_file(dev, &sda_temp[i].dev_attr))) | 1366 | if ((err = device_create_file(dev, &sda_temp[i].dev_attr))) |
| 1309 | goto exit_remove; | 1367 | goto exit_remove; |
| 1310 | 1368 | ||
| 1369 | err = device_create_file(dev, &dev_attr_name); | ||
| 1370 | if (err) | ||
| 1371 | goto exit_remove; | ||
| 1372 | |||
| 1373 | if (data->vid != 0x3f) { | ||
| 1374 | err = device_create_file(dev, &dev_attr_cpu0_vid); | ||
| 1375 | if (err) | ||
| 1376 | goto exit_remove; | ||
| 1377 | } | ||
| 1378 | |||
| 1311 | data->class_dev = hwmon_device_register(dev); | 1379 | data->class_dev = hwmon_device_register(dev); |
| 1312 | if (IS_ERR(data->class_dev)) { | 1380 | if (IS_ERR(data->class_dev)) { |
| 1313 | err = PTR_ERR(data->class_dev); | 1381 | err = PTR_ERR(data->class_dev); |
| @@ -1318,95 +1386,172 @@ static int w83627ehf_detect(struct i2c_adapter *adapter) | |||
| 1318 | 1386 | ||
| 1319 | exit_remove: | 1387 | exit_remove: |
| 1320 | w83627ehf_device_remove_files(dev); | 1388 | w83627ehf_device_remove_files(dev); |
| 1321 | i2c_detach_client(client); | ||
| 1322 | exit_free: | ||
| 1323 | kfree(data); | 1389 | kfree(data); |
| 1390 | platform_set_drvdata(pdev, NULL); | ||
| 1324 | exit_release: | 1391 | exit_release: |
| 1325 | release_region(address + IOREGION_OFFSET, IOREGION_LENGTH); | 1392 | release_region(res->start, IOREGION_LENGTH); |
| 1326 | exit: | 1393 | exit: |
| 1327 | return err; | 1394 | return err; |
| 1328 | } | 1395 | } |
| 1329 | 1396 | ||
| 1330 | static int w83627ehf_detach_client(struct i2c_client *client) | 1397 | static int __devexit w83627ehf_remove(struct platform_device *pdev) |
| 1331 | { | 1398 | { |
| 1332 | struct w83627ehf_data *data = i2c_get_clientdata(client); | 1399 | struct w83627ehf_data *data = platform_get_drvdata(pdev); |
| 1333 | int err; | ||
| 1334 | 1400 | ||
| 1335 | hwmon_device_unregister(data->class_dev); | 1401 | hwmon_device_unregister(data->class_dev); |
| 1336 | w83627ehf_device_remove_files(&client->dev); | 1402 | w83627ehf_device_remove_files(&pdev->dev); |
| 1337 | 1403 | release_region(data->addr, IOREGION_LENGTH); | |
| 1338 | if ((err = i2c_detach_client(client))) | 1404 | platform_set_drvdata(pdev, NULL); |
| 1339 | return err; | ||
| 1340 | release_region(client->addr + IOREGION_OFFSET, IOREGION_LENGTH); | ||
| 1341 | kfree(data); | 1405 | kfree(data); |
| 1342 | 1406 | ||
| 1343 | return 0; | 1407 | return 0; |
| 1344 | } | 1408 | } |
| 1345 | 1409 | ||
| 1346 | static struct i2c_driver w83627ehf_driver = { | 1410 | static struct platform_driver w83627ehf_driver = { |
| 1347 | .driver = { | 1411 | .driver = { |
| 1348 | .owner = THIS_MODULE, | 1412 | .owner = THIS_MODULE, |
| 1349 | .name = "w83627ehf", | 1413 | .name = DRVNAME, |
| 1350 | }, | 1414 | }, |
| 1351 | .attach_adapter = w83627ehf_detect, | 1415 | .probe = w83627ehf_probe, |
| 1352 | .detach_client = w83627ehf_detach_client, | 1416 | .remove = __devexit_p(w83627ehf_remove), |
| 1353 | }; | 1417 | }; |
| 1354 | 1418 | ||
| 1355 | static int __init w83627ehf_find(int sioaddr, unsigned short *addr) | 1419 | /* w83627ehf_find() looks for a '627 in the Super-I/O config space */ |
| 1420 | static int __init w83627ehf_find(int sioaddr, unsigned short *addr, | ||
| 1421 | struct w83627ehf_sio_data *sio_data) | ||
| 1356 | { | 1422 | { |
| 1423 | static const char __initdata sio_name_W83627EHF[] = "W83627EHF"; | ||
| 1424 | static const char __initdata sio_name_W83627EHG[] = "W83627EHG"; | ||
| 1425 | static const char __initdata sio_name_W83627DHG[] = "W83627DHG"; | ||
| 1426 | |||
| 1357 | u16 val; | 1427 | u16 val; |
| 1428 | const char *sio_name; | ||
| 1358 | 1429 | ||
| 1359 | REG = sioaddr; | 1430 | superio_enter(sioaddr); |
| 1360 | VAL = sioaddr + 1; | ||
| 1361 | superio_enter(); | ||
| 1362 | 1431 | ||
| 1363 | val = (superio_inb(SIO_REG_DEVID) << 8) | 1432 | val = (superio_inb(sioaddr, SIO_REG_DEVID) << 8) |
| 1364 | | superio_inb(SIO_REG_DEVID + 1); | 1433 | | superio_inb(sioaddr, SIO_REG_DEVID + 1); |
| 1365 | switch (val & SIO_ID_MASK) { | 1434 | switch (val & SIO_ID_MASK) { |
| 1366 | case SIO_W83627DHG_ID: | ||
| 1367 | w83627ehf_num_in = 9; | ||
| 1368 | break; | ||
| 1369 | case SIO_W83627EHF_ID: | 1435 | case SIO_W83627EHF_ID: |
| 1436 | sio_data->kind = w83627ehf; | ||
| 1437 | sio_name = sio_name_W83627EHF; | ||
| 1438 | break; | ||
| 1370 | case SIO_W83627EHG_ID: | 1439 | case SIO_W83627EHG_ID: |
| 1371 | w83627ehf_num_in = 10; | 1440 | sio_data->kind = w83627ehf; |
| 1441 | sio_name = sio_name_W83627EHG; | ||
| 1442 | break; | ||
| 1443 | case SIO_W83627DHG_ID: | ||
| 1444 | sio_data->kind = w83627dhg; | ||
| 1445 | sio_name = sio_name_W83627DHG; | ||
| 1372 | break; | 1446 | break; |
| 1373 | default: | 1447 | default: |
| 1374 | printk(KERN_WARNING "w83627ehf: unsupported chip ID: 0x%04x\n", | 1448 | if (val != 0xffff) |
| 1375 | val); | 1449 | pr_debug(DRVNAME ": unsupported chip ID: 0x%04x\n", |
| 1376 | superio_exit(); | 1450 | val); |
| 1451 | superio_exit(sioaddr); | ||
| 1377 | return -ENODEV; | 1452 | return -ENODEV; |
| 1378 | } | 1453 | } |
| 1379 | 1454 | ||
| 1380 | superio_select(W83627EHF_LD_HWM); | 1455 | /* We have a known chip, find the HWM I/O address */ |
| 1381 | val = (superio_inb(SIO_REG_ADDR) << 8) | 1456 | superio_select(sioaddr, W83627EHF_LD_HWM); |
| 1382 | | superio_inb(SIO_REG_ADDR + 1); | 1457 | val = (superio_inb(sioaddr, SIO_REG_ADDR) << 8) |
| 1458 | | superio_inb(sioaddr, SIO_REG_ADDR + 1); | ||
| 1383 | *addr = val & IOREGION_ALIGNMENT; | 1459 | *addr = val & IOREGION_ALIGNMENT; |
| 1384 | if (*addr == 0) { | 1460 | if (*addr == 0) { |
| 1385 | superio_exit(); | 1461 | printk(KERN_ERR DRVNAME ": Refusing to enable a Super-I/O " |
| 1462 | "device with a base I/O port 0.\n"); | ||
| 1463 | superio_exit(sioaddr); | ||
| 1386 | return -ENODEV; | 1464 | return -ENODEV; |
| 1387 | } | 1465 | } |
| 1388 | 1466 | ||
| 1389 | /* Activate logical device if needed */ | 1467 | /* Activate logical device if needed */ |
| 1390 | val = superio_inb(SIO_REG_ENABLE); | 1468 | val = superio_inb(sioaddr, SIO_REG_ENABLE); |
| 1391 | if (!(val & 0x01)) | 1469 | if (!(val & 0x01)) { |
| 1392 | superio_outb(SIO_REG_ENABLE, val | 0x01); | 1470 | printk(KERN_WARNING DRVNAME ": Forcibly enabling Super-I/O. " |
| 1471 | "Sensor is probably unusable.\n"); | ||
| 1472 | superio_outb(sioaddr, SIO_REG_ENABLE, val | 0x01); | ||
| 1473 | } | ||
| 1474 | |||
| 1475 | superio_exit(sioaddr); | ||
| 1476 | pr_info(DRVNAME ": Found %s chip at %#x\n", sio_name, *addr); | ||
| 1477 | sio_data->sioreg = sioaddr; | ||
| 1393 | 1478 | ||
| 1394 | superio_exit(); | ||
| 1395 | return 0; | 1479 | return 0; |
| 1396 | } | 1480 | } |
| 1397 | 1481 | ||
| 1482 | /* when Super-I/O functions move to a separate file, the Super-I/O | ||
| 1483 | * bus will manage the lifetime of the device and this module will only keep | ||
| 1484 | * track of the w83627ehf driver. But since we platform_device_alloc(), we | ||
| 1485 | * must keep track of the device */ | ||
| 1486 | static struct platform_device *pdev; | ||
| 1487 | |||
| 1398 | static int __init sensors_w83627ehf_init(void) | 1488 | static int __init sensors_w83627ehf_init(void) |
| 1399 | { | 1489 | { |
| 1400 | if (w83627ehf_find(0x2e, &address) | 1490 | int err; |
| 1401 | && w83627ehf_find(0x4e, &address)) | 1491 | unsigned short address; |
| 1492 | struct resource res; | ||
| 1493 | struct w83627ehf_sio_data sio_data; | ||
| 1494 | |||
| 1495 | /* initialize sio_data->kind and sio_data->sioreg. | ||
| 1496 | * | ||
| 1497 | * when Super-I/O functions move to a separate file, the Super-I/O | ||
| 1498 | * driver will probe 0x2e and 0x4e and auto-detect the presence of a | ||
| 1499 | * w83627ehf hardware monitor, and call probe() */ | ||
| 1500 | if (w83627ehf_find(0x2e, &address, &sio_data) && | ||
| 1501 | w83627ehf_find(0x4e, &address, &sio_data)) | ||
| 1402 | return -ENODEV; | 1502 | return -ENODEV; |
| 1403 | 1503 | ||
| 1404 | return i2c_isa_add_driver(&w83627ehf_driver); | 1504 | err = platform_driver_register(&w83627ehf_driver); |
| 1505 | if (err) | ||
| 1506 | goto exit; | ||
| 1507 | |||
| 1508 | if (!(pdev = platform_device_alloc(DRVNAME, address))) { | ||
| 1509 | err = -ENOMEM; | ||
| 1510 | printk(KERN_ERR DRVNAME ": Device allocation failed\n"); | ||
| 1511 | goto exit_unregister; | ||
| 1512 | } | ||
| 1513 | |||
| 1514 | err = platform_device_add_data(pdev, &sio_data, | ||
| 1515 | sizeof(struct w83627ehf_sio_data)); | ||
| 1516 | if (err) { | ||
| 1517 | printk(KERN_ERR DRVNAME ": Platform data allocation failed\n"); | ||
| 1518 | goto exit_device_put; | ||
| 1519 | } | ||
| 1520 | |||
| 1521 | memset(&res, 0, sizeof(res)); | ||
| 1522 | res.name = DRVNAME; | ||
| 1523 | res.start = address + IOREGION_OFFSET; | ||
| 1524 | res.end = address + IOREGION_OFFSET + IOREGION_LENGTH - 1; | ||
| 1525 | res.flags = IORESOURCE_IO; | ||
| 1526 | err = platform_device_add_resources(pdev, &res, 1); | ||
| 1527 | if (err) { | ||
| 1528 | printk(KERN_ERR DRVNAME ": Device resource addition failed " | ||
| 1529 | "(%d)\n", err); | ||
| 1530 | goto exit_device_put; | ||
| 1531 | } | ||
| 1532 | |||
| 1533 | /* platform_device_add calls probe() */ | ||
| 1534 | err = platform_device_add(pdev); | ||
| 1535 | if (err) { | ||
| 1536 | printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n", | ||
| 1537 | err); | ||
| 1538 | goto exit_device_put; | ||
| 1539 | } | ||
| 1540 | |||
| 1541 | return 0; | ||
| 1542 | |||
| 1543 | exit_device_put: | ||
| 1544 | platform_device_put(pdev); | ||
| 1545 | exit_unregister: | ||
| 1546 | platform_driver_unregister(&w83627ehf_driver); | ||
| 1547 | exit: | ||
| 1548 | return err; | ||
| 1405 | } | 1549 | } |
| 1406 | 1550 | ||
| 1407 | static void __exit sensors_w83627ehf_exit(void) | 1551 | static void __exit sensors_w83627ehf_exit(void) |
| 1408 | { | 1552 | { |
| 1409 | i2c_isa_del_driver(&w83627ehf_driver); | 1553 | platform_device_unregister(pdev); |
| 1554 | platform_driver_unregister(&w83627ehf_driver); | ||
| 1410 | } | 1555 | } |
| 1411 | 1556 | ||
| 1412 | MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>"); | 1557 | MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>"); |
