diff options
-rw-r--r-- | Documentation/i2c/chips/w83781d | 16 | ||||
-rw-r--r-- | drivers/i2c/chips/w83781d.c | 72 |
2 files changed, 24 insertions, 64 deletions
diff --git a/Documentation/i2c/chips/w83781d b/Documentation/i2c/chips/w83781d index 6d0e16f0a50a..e5459333ba68 100644 --- a/Documentation/i2c/chips/w83781d +++ b/Documentation/i2c/chips/w83781d | |||
@@ -18,14 +18,6 @@ Supported chips: | |||
18 | Prefix: 'w83627hf' | 18 | Prefix: 'w83627hf' |
19 | Addresses scanned: I2C 0x20 - 0x2f, ISA 0x290 (8 I/O ports) | 19 | Addresses scanned: I2C 0x20 - 0x2f, ISA 0x290 (8 I/O ports) |
20 | Datasheet: http://www.winbond.com/PDF/sheet/w83627hf.pdf | 20 | Datasheet: http://www.winbond.com/PDF/sheet/w83627hf.pdf |
21 | * Winbond W83627THF | ||
22 | Prefix: 'w83627thf' | ||
23 | Addresses scanned: ISA address 0x290 (8 I/O ports) | ||
24 | Datasheet: http://www.winbond.com/PDF/sheet/w83627thf.pdf | ||
25 | * Winbond W83697HF | ||
26 | Prefix: 'w83697hf' | ||
27 | Addresses scanned: ISA 0x290 (8 I/O ports) | ||
28 | Datasheet: http://www.winbond-usa.com/products/winbond_products/pdfs/PCIC/w83697hf.pdf | ||
29 | * Asus AS99127F | 21 | * Asus AS99127F |
30 | Prefix: 'as99127f' | 22 | Prefix: 'as99127f' |
31 | Addresses scanned: I2C 0x28 - 0x2f | 23 | Addresses scanned: I2C 0x28 - 0x2f |
@@ -53,9 +45,9 @@ force_subclients=bus,caddr,saddr,saddr | |||
53 | Description | 45 | Description |
54 | ----------- | 46 | ----------- |
55 | 47 | ||
56 | This driver implements support for the Winbond W83627HF, W83627THF, W83781D, | 48 | This driver implements support for the Winbond W83781D, W83782D, W83783S, |
57 | W83782D, W83783S, W83697HF chips, and the Asus AS99127F chips. We will refer | 49 | W83627HF chips, and the Asus AS99127F chips. We will refer to them |
58 | to them collectively as W8378* chips. | 50 | collectively as W8378* chips. |
59 | 51 | ||
60 | There is quite some difference between these chips, but they are similar | 52 | There is quite some difference between these chips, but they are similar |
61 | enough that it was sensible to put them together in one driver. | 53 | enough that it was sensible to put them together in one driver. |
@@ -67,10 +59,8 @@ as99127f 7 3 0 3 0x31 0x12c3 yes no | |||
67 | as99127f rev.2 (type_name = as99127f) 0x31 0x5ca3 yes no | 59 | as99127f rev.2 (type_name = as99127f) 0x31 0x5ca3 yes no |
68 | w83781d 7 3 0 3 0x10-1 0x5ca3 yes yes | 60 | w83781d 7 3 0 3 0x10-1 0x5ca3 yes yes |
69 | w83627hf 9 3 2 3 0x21 0x5ca3 yes yes(LPC) | 61 | w83627hf 9 3 2 3 0x21 0x5ca3 yes yes(LPC) |
70 | w83627thf 9 3 2 3 0x90 0x5ca3 no yes(LPC) | ||
71 | w83782d 9 3 2-4 3 0x30 0x5ca3 yes yes | 62 | w83782d 9 3 2-4 3 0x30 0x5ca3 yes yes |
72 | w83783s 5-6 3 2 1-2 0x40 0x5ca3 yes no | 63 | w83783s 5-6 3 2 1-2 0x40 0x5ca3 yes no |
73 | w83697hf 8 2 2 2 0x60 0x5ca3 no yes(LPC) | ||
74 | 64 | ||
75 | Detection of these chips can sometimes be foiled because they can be in | 65 | Detection of these chips can sometimes be foiled because they can be in |
76 | an internal state that allows no clean access. If you know the address | 66 | an internal state that allows no clean access. If you know the address |
diff --git a/drivers/i2c/chips/w83781d.c b/drivers/i2c/chips/w83781d.c index 4a5b06ba57d3..0bb131ce09eb 100644 --- a/drivers/i2c/chips/w83781d.c +++ b/drivers/i2c/chips/w83781d.c | |||
@@ -28,10 +28,8 @@ | |||
28 | as99127f rev.2 (type_name = as99127f) 0x31 0x5ca3 yes no | 28 | as99127f rev.2 (type_name = as99127f) 0x31 0x5ca3 yes no |
29 | w83781d 7 3 0 3 0x10-1 0x5ca3 yes yes | 29 | w83781d 7 3 0 3 0x10-1 0x5ca3 yes yes |
30 | w83627hf 9 3 2 3 0x21 0x5ca3 yes yes(LPC) | 30 | w83627hf 9 3 2 3 0x21 0x5ca3 yes yes(LPC) |
31 | w83627thf 9 3 2 3 0x90 0x5ca3 no yes(LPC) | ||
32 | w83782d 9 3 2-4 3 0x30 0x5ca3 yes yes | 31 | w83782d 9 3 2-4 3 0x30 0x5ca3 yes yes |
33 | w83783s 5-6 3 2 1-2 0x40 0x5ca3 yes no | 32 | w83783s 5-6 3 2 1-2 0x40 0x5ca3 yes no |
34 | w83697hf 8 2 2 2 0x60 0x5ca3 no yes(LPC) | ||
35 | 33 | ||
36 | */ | 34 | */ |
37 | 35 | ||
@@ -52,7 +50,7 @@ static unsigned short normal_i2c[] = { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, | |||
52 | static unsigned int normal_isa[] = { 0x0290, I2C_CLIENT_ISA_END }; | 50 | static unsigned int normal_isa[] = { 0x0290, I2C_CLIENT_ISA_END }; |
53 | 51 | ||
54 | /* Insmod parameters */ | 52 | /* Insmod parameters */ |
55 | SENSORS_INSMOD_6(w83781d, w83782d, w83783s, w83627hf, as99127f, w83697hf); | 53 | SENSORS_INSMOD_5(w83781d, w83782d, w83783s, w83627hf, as99127f); |
56 | I2C_CLIENT_MODULE_PARM(force_subclients, "List of subclient addresses: " | 54 | I2C_CLIENT_MODULE_PARM(force_subclients, "List of subclient addresses: " |
57 | "{bus, clientaddr, subclientaddr1, subclientaddr2}"); | 55 | "{bus, clientaddr, subclientaddr1, subclientaddr2}"); |
58 | 56 | ||
@@ -998,13 +996,6 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) | |||
998 | err = -EINVAL; | 996 | err = -EINVAL; |
999 | goto ERROR0; | 997 | goto ERROR0; |
1000 | } | 998 | } |
1001 | if (!is_isa && kind == w83697hf) { | ||
1002 | dev_err(&adapter->dev, | ||
1003 | "Cannot force ISA-only chip for I2C address 0x%02x.\n", | ||
1004 | address); | ||
1005 | err = -EINVAL; | ||
1006 | goto ERROR0; | ||
1007 | } | ||
1008 | 999 | ||
1009 | if (is_isa) | 1000 | if (is_isa) |
1010 | if (!request_region(address, W83781D_EXTENT, | 1001 | if (!request_region(address, W83781D_EXTENT, |
@@ -1137,12 +1128,10 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) | |||
1137 | else if (val1 == 0x40 && vendid == winbond && !is_isa | 1128 | else if (val1 == 0x40 && vendid == winbond && !is_isa |
1138 | && address == 0x2d) | 1129 | && address == 0x2d) |
1139 | kind = w83783s; | 1130 | kind = w83783s; |
1140 | else if ((val1 == 0x21 || val1 == 0x90) && vendid == winbond) | 1131 | else if (val1 == 0x21 && vendid == winbond) |
1141 | kind = w83627hf; | 1132 | kind = w83627hf; |
1142 | else if (val1 == 0x31 && !is_isa && address >= 0x28) | 1133 | else if (val1 == 0x31 && !is_isa && address >= 0x28) |
1143 | kind = as99127f; | 1134 | kind = as99127f; |
1144 | else if (val1 == 0x60 && vendid == winbond && is_isa) | ||
1145 | kind = w83697hf; | ||
1146 | else { | 1135 | else { |
1147 | if (kind == 0) | 1136 | if (kind == 0) |
1148 | dev_warn(&new_client->dev, "Ignoring 'force' " | 1137 | dev_warn(&new_client->dev, "Ignoring 'force' " |
@@ -1161,14 +1150,9 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) | |||
1161 | } else if (kind == w83783s) { | 1150 | } else if (kind == w83783s) { |
1162 | client_name = "w83783s"; | 1151 | client_name = "w83783s"; |
1163 | } else if (kind == w83627hf) { | 1152 | } else if (kind == w83627hf) { |
1164 | if (val1 == 0x90) | 1153 | client_name = "w83627hf"; |
1165 | client_name = "w83627thf"; | ||
1166 | else | ||
1167 | client_name = "w83627hf"; | ||
1168 | } else if (kind == as99127f) { | 1154 | } else if (kind == as99127f) { |
1169 | client_name = "as99127f"; | 1155 | client_name = "as99127f"; |
1170 | } else if (kind == w83697hf) { | ||
1171 | client_name = "w83697hf"; | ||
1172 | } | 1156 | } |
1173 | 1157 | ||
1174 | /* Fill in the remaining client fields and put into the global list */ | 1158 | /* Fill in the remaining client fields and put into the global list */ |
@@ -1206,7 +1190,7 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) | |||
1206 | 1190 | ||
1207 | /* Register sysfs hooks */ | 1191 | /* Register sysfs hooks */ |
1208 | device_create_file_in(new_client, 0); | 1192 | device_create_file_in(new_client, 0); |
1209 | if (kind != w83783s && kind != w83697hf) | 1193 | if (kind != w83783s) |
1210 | device_create_file_in(new_client, 1); | 1194 | device_create_file_in(new_client, 1); |
1211 | device_create_file_in(new_client, 2); | 1195 | device_create_file_in(new_client, 2); |
1212 | device_create_file_in(new_client, 3); | 1196 | device_create_file_in(new_client, 3); |
@@ -1220,24 +1204,19 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) | |||
1220 | 1204 | ||
1221 | device_create_file_fan(new_client, 1); | 1205 | device_create_file_fan(new_client, 1); |
1222 | device_create_file_fan(new_client, 2); | 1206 | device_create_file_fan(new_client, 2); |
1223 | if (kind != w83697hf) | 1207 | device_create_file_fan(new_client, 3); |
1224 | device_create_file_fan(new_client, 3); | ||
1225 | 1208 | ||
1226 | device_create_file_temp(new_client, 1); | 1209 | device_create_file_temp(new_client, 1); |
1227 | device_create_file_temp(new_client, 2); | 1210 | device_create_file_temp(new_client, 2); |
1228 | if (kind != w83783s && kind != w83697hf) | 1211 | if (kind != w83783s) |
1229 | device_create_file_temp(new_client, 3); | 1212 | device_create_file_temp(new_client, 3); |
1230 | 1213 | ||
1231 | if (kind != w83697hf) | 1214 | device_create_file_vid(new_client); |
1232 | device_create_file_vid(new_client); | 1215 | device_create_file_vrm(new_client); |
1233 | |||
1234 | if (kind != w83697hf) | ||
1235 | device_create_file_vrm(new_client); | ||
1236 | 1216 | ||
1237 | device_create_file_fan_div(new_client, 1); | 1217 | device_create_file_fan_div(new_client, 1); |
1238 | device_create_file_fan_div(new_client, 2); | 1218 | device_create_file_fan_div(new_client, 2); |
1239 | if (kind != w83697hf) | 1219 | device_create_file_fan_div(new_client, 3); |
1240 | device_create_file_fan_div(new_client, 3); | ||
1241 | 1220 | ||
1242 | device_create_file_alarms(new_client); | 1221 | device_create_file_alarms(new_client); |
1243 | 1222 | ||
@@ -1256,7 +1235,7 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) | |||
1256 | if (kind != as99127f && kind != w83781d) { | 1235 | if (kind != as99127f && kind != w83781d) { |
1257 | device_create_file_sensor(new_client, 1); | 1236 | device_create_file_sensor(new_client, 1); |
1258 | device_create_file_sensor(new_client, 2); | 1237 | device_create_file_sensor(new_client, 2); |
1259 | if (kind != w83783s && kind != w83697hf) | 1238 | if (kind != w83783s) |
1260 | device_create_file_sensor(new_client, 3); | 1239 | device_create_file_sensor(new_client, 3); |
1261 | } | 1240 | } |
1262 | 1241 | ||
@@ -1479,7 +1458,7 @@ w83781d_init_client(struct i2c_client *client) | |||
1479 | else | 1458 | else |
1480 | data->sens[i - 1] = 2; | 1459 | data->sens[i - 1] = 2; |
1481 | } | 1460 | } |
1482 | if ((type == w83783s || type == w83697hf) && (i == 2)) | 1461 | if (type == w83783s && i == 2) |
1483 | break; | 1462 | break; |
1484 | } | 1463 | } |
1485 | } | 1464 | } |
@@ -1495,7 +1474,7 @@ w83781d_init_client(struct i2c_client *client) | |||
1495 | } | 1474 | } |
1496 | 1475 | ||
1497 | /* Enable temp3 */ | 1476 | /* Enable temp3 */ |
1498 | if (type != w83783s && type != w83697hf) { | 1477 | if (type != w83783s) { |
1499 | tmp = w83781d_read_value(client, | 1478 | tmp = w83781d_read_value(client, |
1500 | W83781D_REG_TEMP3_CONFIG); | 1479 | W83781D_REG_TEMP3_CONFIG); |
1501 | if (tmp & 0x01) { | 1480 | if (tmp & 0x01) { |
@@ -1536,8 +1515,7 @@ static struct w83781d_data *w83781d_update_device(struct device *dev) | |||
1536 | dev_dbg(dev, "Starting device update\n"); | 1515 | dev_dbg(dev, "Starting device update\n"); |
1537 | 1516 | ||
1538 | for (i = 0; i <= 8; i++) { | 1517 | for (i = 0; i <= 8; i++) { |
1539 | if ((data->type == w83783s || data->type == w83697hf) | 1518 | if (data->type == w83783s && i == 1) |
1540 | && (i == 1)) | ||
1541 | continue; /* 783S has no in1 */ | 1519 | continue; /* 783S has no in1 */ |
1542 | data->in[i] = | 1520 | data->in[i] = |
1543 | w83781d_read_value(client, W83781D_REG_IN(i)); | 1521 | w83781d_read_value(client, W83781D_REG_IN(i)); |
@@ -1545,7 +1523,7 @@ static struct w83781d_data *w83781d_update_device(struct device *dev) | |||
1545 | w83781d_read_value(client, W83781D_REG_IN_MIN(i)); | 1523 | w83781d_read_value(client, W83781D_REG_IN_MIN(i)); |
1546 | data->in_max[i] = | 1524 | data->in_max[i] = |
1547 | w83781d_read_value(client, W83781D_REG_IN_MAX(i)); | 1525 | w83781d_read_value(client, W83781D_REG_IN_MAX(i)); |
1548 | if ((data->type != w83782d) && (data->type != w83697hf) | 1526 | if ((data->type != w83782d) |
1549 | && (data->type != w83627hf) && (i == 6)) | 1527 | && (data->type != w83627hf) && (i == 6)) |
1550 | break; | 1528 | break; |
1551 | } | 1529 | } |
@@ -1581,7 +1559,7 @@ static struct w83781d_data *w83781d_update_device(struct device *dev) | |||
1581 | w83781d_read_value(client, W83781D_REG_TEMP_OVER(2)); | 1559 | w83781d_read_value(client, W83781D_REG_TEMP_OVER(2)); |
1582 | data->temp_max_hyst_add[0] = | 1560 | data->temp_max_hyst_add[0] = |
1583 | w83781d_read_value(client, W83781D_REG_TEMP_HYST(2)); | 1561 | w83781d_read_value(client, W83781D_REG_TEMP_HYST(2)); |
1584 | if (data->type != w83783s && data->type != w83697hf) { | 1562 | if (data->type != w83783s) { |
1585 | data->temp_add[1] = | 1563 | data->temp_add[1] = |
1586 | w83781d_read_value(client, W83781D_REG_TEMP(3)); | 1564 | w83781d_read_value(client, W83781D_REG_TEMP(3)); |
1587 | data->temp_max_add[1] = | 1565 | data->temp_max_add[1] = |
@@ -1592,26 +1570,18 @@ static struct w83781d_data *w83781d_update_device(struct device *dev) | |||
1592 | W83781D_REG_TEMP_HYST(3)); | 1570 | W83781D_REG_TEMP_HYST(3)); |
1593 | } | 1571 | } |
1594 | i = w83781d_read_value(client, W83781D_REG_VID_FANDIV); | 1572 | i = w83781d_read_value(client, W83781D_REG_VID_FANDIV); |
1595 | if (data->type != w83697hf) { | 1573 | data->vid = i & 0x0f; |
1596 | data->vid = i & 0x0f; | 1574 | data->vid |= (w83781d_read_value(client, |
1597 | data->vid |= | 1575 | W83781D_REG_CHIPID) & 0x01) << 4; |
1598 | (w83781d_read_value(client, W83781D_REG_CHIPID) & | ||
1599 | 0x01) | ||
1600 | << 4; | ||
1601 | } | ||
1602 | data->fan_div[0] = (i >> 4) & 0x03; | 1576 | data->fan_div[0] = (i >> 4) & 0x03; |
1603 | data->fan_div[1] = (i >> 6) & 0x03; | 1577 | data->fan_div[1] = (i >> 6) & 0x03; |
1604 | if (data->type != w83697hf) { | 1578 | data->fan_div[2] = (w83781d_read_value(client, |
1605 | data->fan_div[2] = (w83781d_read_value(client, | 1579 | W83781D_REG_PIN) >> 6) & 0x03; |
1606 | W83781D_REG_PIN) | ||
1607 | >> 6) & 0x03; | ||
1608 | } | ||
1609 | if ((data->type != w83781d) && (data->type != as99127f)) { | 1580 | if ((data->type != w83781d) && (data->type != as99127f)) { |
1610 | i = w83781d_read_value(client, W83781D_REG_VBAT); | 1581 | i = w83781d_read_value(client, W83781D_REG_VBAT); |
1611 | data->fan_div[0] |= (i >> 3) & 0x04; | 1582 | data->fan_div[0] |= (i >> 3) & 0x04; |
1612 | data->fan_div[1] |= (i >> 4) & 0x04; | 1583 | data->fan_div[1] |= (i >> 4) & 0x04; |
1613 | if (data->type != w83697hf) | 1584 | data->fan_div[2] |= (i >> 5) & 0x04; |
1614 | data->fan_div[2] |= (i >> 5) & 0x04; | ||
1615 | } | 1585 | } |
1616 | data->alarms = | 1586 | data->alarms = |
1617 | w83781d_read_value(client, | 1587 | w83781d_read_value(client, |