diff options
Diffstat (limited to 'drivers/i2c/chips/w83781d.c')
-rw-r--r-- | drivers/i2c/chips/w83781d.c | 78 |
1 files changed, 23 insertions, 55 deletions
diff --git a/drivers/i2c/chips/w83781d.c b/drivers/i2c/chips/w83781d.c index c3926d2d8ac6..0bb131ce09eb 100644 --- a/drivers/i2c/chips/w83781d.c +++ b/drivers/i2c/chips/w83781d.c | |||
@@ -28,14 +28,11 @@ | |||
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 | ||
38 | #include <linux/config.h> | ||
39 | #include <linux/module.h> | 36 | #include <linux/module.h> |
40 | #include <linux/init.h> | 37 | #include <linux/init.h> |
41 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
@@ -53,7 +50,7 @@ static unsigned short normal_i2c[] = { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, | |||
53 | static unsigned int normal_isa[] = { 0x0290, I2C_CLIENT_ISA_END }; | 50 | static unsigned int normal_isa[] = { 0x0290, I2C_CLIENT_ISA_END }; |
54 | 51 | ||
55 | /* Insmod parameters */ | 52 | /* Insmod parameters */ |
56 | SENSORS_INSMOD_6(w83781d, w83782d, w83783s, w83627hf, as99127f, w83697hf); | 53 | SENSORS_INSMOD_5(w83781d, w83782d, w83783s, w83627hf, as99127f); |
57 | I2C_CLIENT_MODULE_PARM(force_subclients, "List of subclient addresses: " | 54 | I2C_CLIENT_MODULE_PARM(force_subclients, "List of subclient addresses: " |
58 | "{bus, clientaddr, subclientaddr1, subclientaddr2}"); | 55 | "{bus, clientaddr, subclientaddr1, subclientaddr2}"); |
59 | 56 | ||
@@ -173,7 +170,6 @@ FAN_TO_REG(long rpm, int div) | |||
173 | : (val)) / 1000, 0, 0xff)) | 170 | : (val)) / 1000, 0, 0xff)) |
174 | #define TEMP_FROM_REG(val) (((val) & 0x80 ? (val)-0x100 : (val)) * 1000) | 171 | #define TEMP_FROM_REG(val) (((val) & 0x80 ? (val)-0x100 : (val)) * 1000) |
175 | 172 | ||
176 | #define ALARMS_FROM_REG(val) (val) | ||
177 | #define PWM_FROM_REG(val) (val) | 173 | #define PWM_FROM_REG(val) (val) |
178 | #define PWM_TO_REG(val) (SENSORS_LIMIT((val),0,255)) | 174 | #define PWM_TO_REG(val) (SENSORS_LIMIT((val),0,255)) |
179 | #define BEEP_MASK_FROM_REG(val,type) ((type) == as99127f ? \ | 175 | #define BEEP_MASK_FROM_REG(val,type) ((type) == as99127f ? \ |
@@ -193,7 +189,7 @@ DIV_TO_REG(long val, enum chips type) | |||
193 | val = SENSORS_LIMIT(val, 1, | 189 | val = SENSORS_LIMIT(val, 1, |
194 | ((type == w83781d | 190 | ((type == w83781d |
195 | || type == as99127f) ? 8 : 128)) >> 1; | 191 | || type == as99127f) ? 8 : 128)) >> 1; |
196 | for (i = 0; i < 6; i++) { | 192 | for (i = 0; i < 7; i++) { |
197 | if (val == 0) | 193 | if (val == 0) |
198 | break; | 194 | break; |
199 | val >>= 1; | 195 | val >>= 1; |
@@ -524,7 +520,7 @@ static ssize_t | |||
524 | show_alarms_reg(struct device *dev, struct device_attribute *attr, char *buf) | 520 | show_alarms_reg(struct device *dev, struct device_attribute *attr, char *buf) |
525 | { | 521 | { |
526 | struct w83781d_data *data = w83781d_update_device(dev); | 522 | struct w83781d_data *data = w83781d_update_device(dev); |
527 | return sprintf(buf, "%ld\n", (long) ALARMS_FROM_REG(data->alarms)); | 523 | return sprintf(buf, "%u\n", data->alarms); |
528 | } | 524 | } |
529 | 525 | ||
530 | static | 526 | static |
@@ -1000,13 +996,6 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) | |||
1000 | err = -EINVAL; | 996 | err = -EINVAL; |
1001 | goto ERROR0; | 997 | goto ERROR0; |
1002 | } | 998 | } |
1003 | if (!is_isa && kind == w83697hf) { | ||
1004 | dev_err(&adapter->dev, | ||
1005 | "Cannot force ISA-only chip for I2C address 0x%02x.\n", | ||
1006 | address); | ||
1007 | err = -EINVAL; | ||
1008 | goto ERROR0; | ||
1009 | } | ||
1010 | 999 | ||
1011 | if (is_isa) | 1000 | if (is_isa) |
1012 | if (!request_region(address, W83781D_EXTENT, | 1001 | if (!request_region(address, W83781D_EXTENT, |
@@ -1139,12 +1128,10 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) | |||
1139 | else if (val1 == 0x40 && vendid == winbond && !is_isa | 1128 | else if (val1 == 0x40 && vendid == winbond && !is_isa |
1140 | && address == 0x2d) | 1129 | && address == 0x2d) |
1141 | kind = w83783s; | 1130 | kind = w83783s; |
1142 | else if ((val1 == 0x21 || val1 == 0x90) && vendid == winbond) | 1131 | else if (val1 == 0x21 && vendid == winbond) |
1143 | kind = w83627hf; | 1132 | kind = w83627hf; |
1144 | else if (val1 == 0x31 && !is_isa && address >= 0x28) | 1133 | else if (val1 == 0x31 && !is_isa && address >= 0x28) |
1145 | kind = as99127f; | 1134 | kind = as99127f; |
1146 | else if (val1 == 0x60 && vendid == winbond && is_isa) | ||
1147 | kind = w83697hf; | ||
1148 | else { | 1135 | else { |
1149 | if (kind == 0) | 1136 | if (kind == 0) |
1150 | dev_warn(&new_client->dev, "Ignoring 'force' " | 1137 | dev_warn(&new_client->dev, "Ignoring 'force' " |
@@ -1163,14 +1150,9 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) | |||
1163 | } else if (kind == w83783s) { | 1150 | } else if (kind == w83783s) { |
1164 | client_name = "w83783s"; | 1151 | client_name = "w83783s"; |
1165 | } else if (kind == w83627hf) { | 1152 | } else if (kind == w83627hf) { |
1166 | if (val1 == 0x90) | 1153 | client_name = "w83627hf"; |
1167 | client_name = "w83627thf"; | ||
1168 | else | ||
1169 | client_name = "w83627hf"; | ||
1170 | } else if (kind == as99127f) { | 1154 | } else if (kind == as99127f) { |
1171 | client_name = "as99127f"; | 1155 | client_name = "as99127f"; |
1172 | } else if (kind == w83697hf) { | ||
1173 | client_name = "w83697hf"; | ||
1174 | } | 1156 | } |
1175 | 1157 | ||
1176 | /* 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 */ |
@@ -1208,7 +1190,7 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) | |||
1208 | 1190 | ||
1209 | /* Register sysfs hooks */ | 1191 | /* Register sysfs hooks */ |
1210 | device_create_file_in(new_client, 0); | 1192 | device_create_file_in(new_client, 0); |
1211 | if (kind != w83783s && kind != w83697hf) | 1193 | if (kind != w83783s) |
1212 | device_create_file_in(new_client, 1); | 1194 | device_create_file_in(new_client, 1); |
1213 | device_create_file_in(new_client, 2); | 1195 | device_create_file_in(new_client, 2); |
1214 | device_create_file_in(new_client, 3); | 1196 | device_create_file_in(new_client, 3); |
@@ -1222,24 +1204,19 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) | |||
1222 | 1204 | ||
1223 | device_create_file_fan(new_client, 1); | 1205 | device_create_file_fan(new_client, 1); |
1224 | device_create_file_fan(new_client, 2); | 1206 | device_create_file_fan(new_client, 2); |
1225 | if (kind != w83697hf) | 1207 | device_create_file_fan(new_client, 3); |
1226 | device_create_file_fan(new_client, 3); | ||
1227 | 1208 | ||
1228 | device_create_file_temp(new_client, 1); | 1209 | device_create_file_temp(new_client, 1); |
1229 | device_create_file_temp(new_client, 2); | 1210 | device_create_file_temp(new_client, 2); |
1230 | if (kind != w83783s && kind != w83697hf) | 1211 | if (kind != w83783s) |
1231 | device_create_file_temp(new_client, 3); | 1212 | device_create_file_temp(new_client, 3); |
1232 | 1213 | ||
1233 | if (kind != w83697hf) | 1214 | device_create_file_vid(new_client); |
1234 | device_create_file_vid(new_client); | 1215 | device_create_file_vrm(new_client); |
1235 | |||
1236 | if (kind != w83697hf) | ||
1237 | device_create_file_vrm(new_client); | ||
1238 | 1216 | ||
1239 | device_create_file_fan_div(new_client, 1); | 1217 | device_create_file_fan_div(new_client, 1); |
1240 | device_create_file_fan_div(new_client, 2); | 1218 | device_create_file_fan_div(new_client, 2); |
1241 | if (kind != w83697hf) | 1219 | device_create_file_fan_div(new_client, 3); |
1242 | device_create_file_fan_div(new_client, 3); | ||
1243 | 1220 | ||
1244 | device_create_file_alarms(new_client); | 1221 | device_create_file_alarms(new_client); |
1245 | 1222 | ||
@@ -1258,7 +1235,7 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) | |||
1258 | if (kind != as99127f && kind != w83781d) { | 1235 | if (kind != as99127f && kind != w83781d) { |
1259 | device_create_file_sensor(new_client, 1); | 1236 | device_create_file_sensor(new_client, 1); |
1260 | device_create_file_sensor(new_client, 2); | 1237 | device_create_file_sensor(new_client, 2); |
1261 | if (kind != w83783s && kind != w83697hf) | 1238 | if (kind != w83783s) |
1262 | device_create_file_sensor(new_client, 3); | 1239 | device_create_file_sensor(new_client, 3); |
1263 | } | 1240 | } |
1264 | 1241 | ||
@@ -1481,7 +1458,7 @@ w83781d_init_client(struct i2c_client *client) | |||
1481 | else | 1458 | else |
1482 | data->sens[i - 1] = 2; | 1459 | data->sens[i - 1] = 2; |
1483 | } | 1460 | } |
1484 | if ((type == w83783s || type == w83697hf) && (i == 2)) | 1461 | if (type == w83783s && i == 2) |
1485 | break; | 1462 | break; |
1486 | } | 1463 | } |
1487 | } | 1464 | } |
@@ -1497,7 +1474,7 @@ w83781d_init_client(struct i2c_client *client) | |||
1497 | } | 1474 | } |
1498 | 1475 | ||
1499 | /* Enable temp3 */ | 1476 | /* Enable temp3 */ |
1500 | if (type != w83783s && type != w83697hf) { | 1477 | if (type != w83783s) { |
1501 | tmp = w83781d_read_value(client, | 1478 | tmp = w83781d_read_value(client, |
1502 | W83781D_REG_TEMP3_CONFIG); | 1479 | W83781D_REG_TEMP3_CONFIG); |
1503 | if (tmp & 0x01) { | 1480 | if (tmp & 0x01) { |
@@ -1538,8 +1515,7 @@ static struct w83781d_data *w83781d_update_device(struct device *dev) | |||
1538 | dev_dbg(dev, "Starting device update\n"); | 1515 | dev_dbg(dev, "Starting device update\n"); |
1539 | 1516 | ||
1540 | for (i = 0; i <= 8; i++) { | 1517 | for (i = 0; i <= 8; i++) { |
1541 | if ((data->type == w83783s || data->type == w83697hf) | 1518 | if (data->type == w83783s && i == 1) |
1542 | && (i == 1)) | ||
1543 | continue; /* 783S has no in1 */ | 1519 | continue; /* 783S has no in1 */ |
1544 | data->in[i] = | 1520 | data->in[i] = |
1545 | w83781d_read_value(client, W83781D_REG_IN(i)); | 1521 | w83781d_read_value(client, W83781D_REG_IN(i)); |
@@ -1547,7 +1523,7 @@ static struct w83781d_data *w83781d_update_device(struct device *dev) | |||
1547 | w83781d_read_value(client, W83781D_REG_IN_MIN(i)); | 1523 | w83781d_read_value(client, W83781D_REG_IN_MIN(i)); |
1548 | data->in_max[i] = | 1524 | data->in_max[i] = |
1549 | w83781d_read_value(client, W83781D_REG_IN_MAX(i)); | 1525 | w83781d_read_value(client, W83781D_REG_IN_MAX(i)); |
1550 | if ((data->type != w83782d) && (data->type != w83697hf) | 1526 | if ((data->type != w83782d) |
1551 | && (data->type != w83627hf) && (i == 6)) | 1527 | && (data->type != w83627hf) && (i == 6)) |
1552 | break; | 1528 | break; |
1553 | } | 1529 | } |
@@ -1583,7 +1559,7 @@ static struct w83781d_data *w83781d_update_device(struct device *dev) | |||
1583 | w83781d_read_value(client, W83781D_REG_TEMP_OVER(2)); | 1559 | w83781d_read_value(client, W83781D_REG_TEMP_OVER(2)); |
1584 | data->temp_max_hyst_add[0] = | 1560 | data->temp_max_hyst_add[0] = |
1585 | w83781d_read_value(client, W83781D_REG_TEMP_HYST(2)); | 1561 | w83781d_read_value(client, W83781D_REG_TEMP_HYST(2)); |
1586 | if (data->type != w83783s && data->type != w83697hf) { | 1562 | if (data->type != w83783s) { |
1587 | data->temp_add[1] = | 1563 | data->temp_add[1] = |
1588 | w83781d_read_value(client, W83781D_REG_TEMP(3)); | 1564 | w83781d_read_value(client, W83781D_REG_TEMP(3)); |
1589 | data->temp_max_add[1] = | 1565 | data->temp_max_add[1] = |
@@ -1594,26 +1570,18 @@ static struct w83781d_data *w83781d_update_device(struct device *dev) | |||
1594 | W83781D_REG_TEMP_HYST(3)); | 1570 | W83781D_REG_TEMP_HYST(3)); |
1595 | } | 1571 | } |
1596 | i = w83781d_read_value(client, W83781D_REG_VID_FANDIV); | 1572 | i = w83781d_read_value(client, W83781D_REG_VID_FANDIV); |
1597 | if (data->type != w83697hf) { | 1573 | data->vid = i & 0x0f; |
1598 | data->vid = i & 0x0f; | 1574 | data->vid |= (w83781d_read_value(client, |
1599 | data->vid |= | 1575 | W83781D_REG_CHIPID) & 0x01) << 4; |
1600 | (w83781d_read_value(client, W83781D_REG_CHIPID) & | ||
1601 | 0x01) | ||
1602 | << 4; | ||
1603 | } | ||
1604 | data->fan_div[0] = (i >> 4) & 0x03; | 1576 | data->fan_div[0] = (i >> 4) & 0x03; |
1605 | data->fan_div[1] = (i >> 6) & 0x03; | 1577 | data->fan_div[1] = (i >> 6) & 0x03; |
1606 | if (data->type != w83697hf) { | 1578 | data->fan_div[2] = (w83781d_read_value(client, |
1607 | data->fan_div[2] = (w83781d_read_value(client, | 1579 | W83781D_REG_PIN) >> 6) & 0x03; |
1608 | W83781D_REG_PIN) | ||
1609 | >> 6) & 0x03; | ||
1610 | } | ||
1611 | if ((data->type != w83781d) && (data->type != as99127f)) { | 1580 | if ((data->type != w83781d) && (data->type != as99127f)) { |
1612 | i = w83781d_read_value(client, W83781D_REG_VBAT); | 1581 | i = w83781d_read_value(client, W83781D_REG_VBAT); |
1613 | data->fan_div[0] |= (i >> 3) & 0x04; | 1582 | data->fan_div[0] |= (i >> 3) & 0x04; |
1614 | data->fan_div[1] |= (i >> 4) & 0x04; | 1583 | data->fan_div[1] |= (i >> 4) & 0x04; |
1615 | if (data->type != w83697hf) | 1584 | data->fan_div[2] |= (i >> 5) & 0x04; |
1616 | data->fan_div[2] |= (i >> 5) & 0x04; | ||
1617 | } | 1585 | } |
1618 | data->alarms = | 1586 | data->alarms = |
1619 | w83781d_read_value(client, | 1587 | w83781d_read_value(client, |