diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/hwmon/w83627ehf.c | 54 |
1 files changed, 43 insertions, 11 deletions
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c index 212a1558c63b..da5828f2dfc2 100644 --- a/drivers/hwmon/w83627ehf.c +++ b/drivers/hwmon/w83627ehf.c | |||
@@ -32,8 +32,10 @@ | |||
32 | 32 | ||
33 | Supports the following chips: | 33 | Supports the following chips: |
34 | 34 | ||
35 | Chip #vin #fan #pwm #temp chip_id man_id | 35 | Chip #vin #fan #pwm #temp chip IDs man ID |
36 | w83627ehf 10 5 4 3 0x88,0xa1 0x5ca3 | 36 | w83627ehf 10 5 4 3 0x8850 0x88 0x5ca3 |
37 | 0x8860 0xa1 | ||
38 | w83627dhg 9 5 4 3 0xa020 0xc1 0x5ca3 | ||
37 | */ | 39 | */ |
38 | 40 | ||
39 | #include <linux/module.h> | 41 | #include <linux/module.h> |
@@ -55,8 +57,18 @@ static unsigned short address; | |||
55 | * Super-I/O constants and functions | 57 | * Super-I/O constants and functions |
56 | */ | 58 | */ |
57 | 59 | ||
60 | /* | ||
61 | * The three following globals are initialized in w83627ehf_find(), before | ||
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 | */ | ||
58 | static int REG; /* The register to read/write */ | 66 | static int REG; /* The register to read/write */ |
59 | static int VAL; /* The value 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; | ||
60 | 72 | ||
61 | #define W83627EHF_LD_HWM 0x0b | 73 | #define W83627EHF_LD_HWM 0x0b |
62 | 74 | ||
@@ -65,8 +77,10 @@ static int VAL; /* The value to read/write */ | |||
65 | #define SIO_REG_ENABLE 0x30 /* Logical device enable */ | 77 | #define SIO_REG_ENABLE 0x30 /* Logical device enable */ |
66 | #define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */ | 78 | #define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */ |
67 | 79 | ||
68 | #define SIO_W83627EHF_ID 0x8840 | 80 | #define SIO_W83627EHF_ID 0x8850 |
69 | #define SIO_ID_MASK 0xFFC0 | 81 | #define SIO_W83627EHG_ID 0x8860 |
82 | #define SIO_W83627DHG_ID 0xa020 | ||
83 | #define SIO_ID_MASK 0xFFF0 | ||
70 | 84 | ||
71 | static inline void | 85 | static inline void |
72 | superio_outb(int reg, int val) | 86 | superio_outb(int reg, int val) |
@@ -115,8 +129,12 @@ superio_exit(void) | |||
115 | 129 | ||
116 | #define W83627EHF_REG_BANK 0x4E | 130 | #define W83627EHF_REG_BANK 0x4E |
117 | #define W83627EHF_REG_CONFIG 0x40 | 131 | #define W83627EHF_REG_CONFIG 0x40 |
118 | #define W83627EHF_REG_CHIP_ID 0x49 | 132 | |
119 | #define W83627EHF_REG_MAN_ID 0x4F | 133 | /* Not currently used: |
134 | * REG_MAN_ID has the value 0x5ca3 for all supported chips. | ||
135 | * REG_CHIP_ID == 0x88/0xa1/0xc1 depending on chip model. | ||
136 | * REG_MAN_ID is at port 0x4f | ||
137 | * REG_CHIP_ID is at port 0x58 */ | ||
120 | 138 | ||
121 | static const u16 W83627EHF_REG_FAN[] = { 0x28, 0x29, 0x2a, 0x3f, 0x553 }; | 139 | static const u16 W83627EHF_REG_FAN[] = { 0x28, 0x29, 0x2a, 0x3f, 0x553 }; |
122 | static const u16 W83627EHF_REG_FAN_MIN[] = { 0x3b, 0x3c, 0x3d, 0x3e, 0x55c }; | 140 | static const u16 W83627EHF_REG_FAN_MIN[] = { 0x3b, 0x3c, 0x3d, 0x3e, 0x55c }; |
@@ -429,7 +447,7 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) | |||
429 | } | 447 | } |
430 | 448 | ||
431 | /* Measured voltages and limits */ | 449 | /* Measured voltages and limits */ |
432 | for (i = 0; i < 10; i++) { | 450 | for (i = 0; i < w83627ehf_num_in; i++) { |
433 | data->in[i] = w83627ehf_read_value(client, | 451 | data->in[i] = w83627ehf_read_value(client, |
434 | W83627EHF_REG_IN(i)); | 452 | W83627EHF_REG_IN(i)); |
435 | data->in_min[i] = w83627ehf_read_value(client, | 453 | data->in_min[i] = w83627ehf_read_value(client, |
@@ -1121,7 +1139,7 @@ static void w83627ehf_device_remove_files(struct device *dev) | |||
1121 | device_remove_file(dev, &sda_sf3_arrays[i].dev_attr); | 1139 | device_remove_file(dev, &sda_sf3_arrays[i].dev_attr); |
1122 | for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++) | 1140 | for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++) |
1123 | device_remove_file(dev, &sda_sf3_arrays_fan4[i].dev_attr); | 1141 | device_remove_file(dev, &sda_sf3_arrays_fan4[i].dev_attr); |
1124 | for (i = 0; i < 10; i++) { | 1142 | for (i = 0; i < w83627ehf_num_in; i++) { |
1125 | device_remove_file(dev, &sda_in_input[i].dev_attr); | 1143 | device_remove_file(dev, &sda_in_input[i].dev_attr); |
1126 | device_remove_file(dev, &sda_in_alarm[i].dev_attr); | 1144 | device_remove_file(dev, &sda_in_alarm[i].dev_attr); |
1127 | device_remove_file(dev, &sda_in_min[i].dev_attr); | 1145 | device_remove_file(dev, &sda_in_min[i].dev_attr); |
@@ -1196,7 +1214,11 @@ static int w83627ehf_detect(struct i2c_adapter *adapter) | |||
1196 | client->flags = 0; | 1214 | client->flags = 0; |
1197 | dev = &client->dev; | 1215 | dev = &client->dev; |
1198 | 1216 | ||
1199 | strlcpy(client->name, "w83627ehf", I2C_NAME_SIZE); | 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 | |||
1200 | data->valid = 0; | 1222 | data->valid = 0; |
1201 | mutex_init(&data->update_lock); | 1223 | mutex_init(&data->update_lock); |
1202 | 1224 | ||
@@ -1246,7 +1268,7 @@ static int w83627ehf_detect(struct i2c_adapter *adapter) | |||
1246 | goto exit_remove; | 1268 | goto exit_remove; |
1247 | } | 1269 | } |
1248 | 1270 | ||
1249 | for (i = 0; i < 10; i++) | 1271 | for (i = 0; i < w83627ehf_num_in; i++) |
1250 | if ((err = device_create_file(dev, &sda_in_input[i].dev_attr)) | 1272 | if ((err = device_create_file(dev, &sda_in_input[i].dev_attr)) |
1251 | || (err = device_create_file(dev, | 1273 | || (err = device_create_file(dev, |
1252 | &sda_in_alarm[i].dev_attr)) | 1274 | &sda_in_alarm[i].dev_attr)) |
@@ -1340,7 +1362,17 @@ static int __init w83627ehf_find(int sioaddr, unsigned short *addr) | |||
1340 | 1362 | ||
1341 | val = (superio_inb(SIO_REG_DEVID) << 8) | 1363 | val = (superio_inb(SIO_REG_DEVID) << 8) |
1342 | | superio_inb(SIO_REG_DEVID + 1); | 1364 | | superio_inb(SIO_REG_DEVID + 1); |
1343 | if ((val & SIO_ID_MASK) != SIO_W83627EHF_ID) { | 1365 | switch (val & SIO_ID_MASK) { |
1366 | case SIO_W83627DHG_ID: | ||
1367 | w83627ehf_num_in = 9; | ||
1368 | break; | ||
1369 | case SIO_W83627EHF_ID: | ||
1370 | case SIO_W83627EHG_ID: | ||
1371 | w83627ehf_num_in = 10; | ||
1372 | break; | ||
1373 | default: | ||
1374 | printk(KERN_WARNING "w83627ehf: unsupported chip ID: 0x%04x\n", | ||
1375 | val); | ||
1344 | superio_exit(); | 1376 | superio_exit(); |
1345 | return -ENODEV; | 1377 | return -ENODEV; |
1346 | } | 1378 | } |