diff options
Diffstat (limited to 'drivers/hwmon/lm85.c')
| -rw-r--r-- | drivers/hwmon/lm85.c | 52 |
1 files changed, 46 insertions, 6 deletions
diff --git a/drivers/hwmon/lm85.c b/drivers/hwmon/lm85.c index 3ff0285396fa..cfc1ee90f5a3 100644 --- a/drivers/hwmon/lm85.c +++ b/drivers/hwmon/lm85.c | |||
| @@ -39,7 +39,8 @@ | |||
| 39 | static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; | 39 | static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; |
| 40 | 40 | ||
| 41 | /* Insmod parameters */ | 41 | /* Insmod parameters */ |
| 42 | I2C_CLIENT_INSMOD_6(lm85b, lm85c, adm1027, adt7463, emc6d100, emc6d102); | 42 | I2C_CLIENT_INSMOD_7(lm85b, lm85c, adm1027, adt7463, adt7468, emc6d100, |
| 43 | emc6d102); | ||
| 43 | 44 | ||
| 44 | /* The LM85 registers */ | 45 | /* The LM85 registers */ |
| 45 | 46 | ||
| @@ -59,6 +60,12 @@ I2C_CLIENT_INSMOD_6(lm85b, lm85c, adm1027, adt7463, emc6d100, emc6d102); | |||
| 59 | 60 | ||
| 60 | #define LM85_REG_COMPANY 0x3e | 61 | #define LM85_REG_COMPANY 0x3e |
| 61 | #define LM85_REG_VERSTEP 0x3f | 62 | #define LM85_REG_VERSTEP 0x3f |
| 63 | |||
| 64 | #define ADT7468_REG_CFG5 0x7c | ||
| 65 | #define ADT7468_OFF64 0x01 | ||
| 66 | #define IS_ADT7468_OFF64(data) \ | ||
| 67 | ((data)->type == adt7468 && !((data)->cfg5 & ADT7468_OFF64)) | ||
| 68 | |||
| 62 | /* These are the recognized values for the above regs */ | 69 | /* These are the recognized values for the above regs */ |
| 63 | #define LM85_COMPANY_NATIONAL 0x01 | 70 | #define LM85_COMPANY_NATIONAL 0x01 |
| 64 | #define LM85_COMPANY_ANALOG_DEV 0x41 | 71 | #define LM85_COMPANY_ANALOG_DEV 0x41 |
| @@ -70,6 +77,8 @@ I2C_CLIENT_INSMOD_6(lm85b, lm85c, adm1027, adt7463, emc6d100, emc6d102); | |||
| 70 | #define LM85_VERSTEP_ADM1027 0x60 | 77 | #define LM85_VERSTEP_ADM1027 0x60 |
| 71 | #define LM85_VERSTEP_ADT7463 0x62 | 78 | #define LM85_VERSTEP_ADT7463 0x62 |
| 72 | #define LM85_VERSTEP_ADT7463C 0x6A | 79 | #define LM85_VERSTEP_ADT7463C 0x6A |
| 80 | #define LM85_VERSTEP_ADT7468_1 0x71 | ||
| 81 | #define LM85_VERSTEP_ADT7468_2 0x72 | ||
| 73 | #define LM85_VERSTEP_EMC6D100_A0 0x60 | 82 | #define LM85_VERSTEP_EMC6D100_A0 0x60 |
| 74 | #define LM85_VERSTEP_EMC6D100_A1 0x61 | 83 | #define LM85_VERSTEP_EMC6D100_A1 0x61 |
| 75 | #define LM85_VERSTEP_EMC6D102 0x65 | 84 | #define LM85_VERSTEP_EMC6D102 0x65 |
| @@ -306,6 +315,7 @@ struct lm85_data { | |||
| 306 | u8 vid; /* Register value */ | 315 | u8 vid; /* Register value */ |
| 307 | u8 vrm; /* VRM version */ | 316 | u8 vrm; /* VRM version */ |
| 308 | u32 alarms; /* Register encoding, combined */ | 317 | u32 alarms; /* Register encoding, combined */ |
| 318 | u8 cfg5; /* Config Register 5 on ADT7468 */ | ||
| 309 | struct lm85_autofan autofan[3]; | 319 | struct lm85_autofan autofan[3]; |
| 310 | struct lm85_zone zone[3]; | 320 | struct lm85_zone zone[3]; |
| 311 | }; | 321 | }; |
| @@ -685,6 +695,9 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr, | |||
| 685 | struct lm85_data *data = i2c_get_clientdata(client); | 695 | struct lm85_data *data = i2c_get_clientdata(client); |
| 686 | long val = simple_strtol(buf, NULL, 10); | 696 | long val = simple_strtol(buf, NULL, 10); |
| 687 | 697 | ||
| 698 | if (IS_ADT7468_OFF64(data)) | ||
| 699 | val += 64; | ||
| 700 | |||
| 688 | mutex_lock(&data->update_lock); | 701 | mutex_lock(&data->update_lock); |
| 689 | data->temp_min[nr] = TEMP_TO_REG(val); | 702 | data->temp_min[nr] = TEMP_TO_REG(val); |
| 690 | lm85_write_value(client, LM85_REG_TEMP_MIN(nr), data->temp_min[nr]); | 703 | lm85_write_value(client, LM85_REG_TEMP_MIN(nr), data->temp_min[nr]); |
| @@ -708,6 +721,9 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr, | |||
| 708 | struct lm85_data *data = i2c_get_clientdata(client); | 721 | struct lm85_data *data = i2c_get_clientdata(client); |
| 709 | long val = simple_strtol(buf, NULL, 10); | 722 | long val = simple_strtol(buf, NULL, 10); |
| 710 | 723 | ||
| 724 | if (IS_ADT7468_OFF64(data)) | ||
| 725 | val += 64; | ||
| 726 | |||
| 711 | mutex_lock(&data->update_lock); | 727 | mutex_lock(&data->update_lock); |
| 712 | data->temp_max[nr] = TEMP_TO_REG(val); | 728 | data->temp_max[nr] = TEMP_TO_REG(val); |
| 713 | lm85_write_value(client, LM85_REG_TEMP_MAX(nr), data->temp_max[nr]); | 729 | lm85_write_value(client, LM85_REG_TEMP_MAX(nr), data->temp_max[nr]); |
| @@ -1163,6 +1179,10 @@ static int lm85_detect(struct i2c_client *client, int kind, | |||
| 1163 | case LM85_VERSTEP_ADT7463C: | 1179 | case LM85_VERSTEP_ADT7463C: |
| 1164 | kind = adt7463; | 1180 | kind = adt7463; |
| 1165 | break; | 1181 | break; |
| 1182 | case LM85_VERSTEP_ADT7468_1: | ||
| 1183 | case LM85_VERSTEP_ADT7468_2: | ||
| 1184 | kind = adt7468; | ||
| 1185 | break; | ||
| 1166 | } | 1186 | } |
| 1167 | } else if (company == LM85_COMPANY_SMSC) { | 1187 | } else if (company == LM85_COMPANY_SMSC) { |
| 1168 | switch (verstep) { | 1188 | switch (verstep) { |
| @@ -1195,6 +1215,9 @@ static int lm85_detect(struct i2c_client *client, int kind, | |||
| 1195 | case adt7463: | 1215 | case adt7463: |
| 1196 | type_name = "adt7463"; | 1216 | type_name = "adt7463"; |
| 1197 | break; | 1217 | break; |
| 1218 | case adt7468: | ||
| 1219 | type_name = "adt7468"; | ||
| 1220 | break; | ||
| 1198 | case emc6d100: | 1221 | case emc6d100: |
| 1199 | type_name = "emc6d100"; | 1222 | type_name = "emc6d100"; |
| 1200 | break; | 1223 | break; |
| @@ -1246,10 +1269,11 @@ static int lm85_probe(struct i2c_client *client, | |||
| 1246 | if (err) | 1269 | if (err) |
| 1247 | goto err_kfree; | 1270 | goto err_kfree; |
| 1248 | 1271 | ||
| 1249 | /* The ADT7463 has an optional VRM 10 mode where pin 21 is used | 1272 | /* The ADT7463/68 have an optional VRM 10 mode where pin 21 is used |
| 1250 | as a sixth digital VID input rather than an analog input. */ | 1273 | as a sixth digital VID input rather than an analog input. */ |
| 1251 | data->vid = lm85_read_value(client, LM85_REG_VID); | 1274 | data->vid = lm85_read_value(client, LM85_REG_VID); |
| 1252 | if (!(data->type == adt7463 && (data->vid & 0x80))) | 1275 | if (!((data->type == adt7463 || data->type == adt7468) && |
| 1276 | (data->vid & 0x80))) | ||
| 1253 | if ((err = sysfs_create_group(&client->dev.kobj, | 1277 | if ((err = sysfs_create_group(&client->dev.kobj, |
| 1254 | &lm85_group_in4))) | 1278 | &lm85_group_in4))) |
| 1255 | goto err_remove_files; | 1279 | goto err_remove_files; |
| @@ -1357,7 +1381,8 @@ static struct lm85_data *lm85_update_device(struct device *dev) | |||
| 1357 | * There are 2 additional resolution bits per channel and we | 1381 | * There are 2 additional resolution bits per channel and we |
| 1358 | * have room for 4, so we shift them to the left. | 1382 | * have room for 4, so we shift them to the left. |
| 1359 | */ | 1383 | */ |
| 1360 | if (data->type == adm1027 || data->type == adt7463) { | 1384 | if (data->type == adm1027 || data->type == adt7463 || |
| 1385 | data->type == adt7468) { | ||
| 1361 | int ext1 = lm85_read_value(client, | 1386 | int ext1 = lm85_read_value(client, |
| 1362 | ADM1027_REG_EXTEND_ADC1); | 1387 | ADM1027_REG_EXTEND_ADC1); |
| 1363 | int ext2 = lm85_read_value(client, | 1388 | int ext2 = lm85_read_value(client, |
| @@ -1382,16 +1407,23 @@ static struct lm85_data *lm85_update_device(struct device *dev) | |||
| 1382 | lm85_read_value(client, LM85_REG_FAN(i)); | 1407 | lm85_read_value(client, LM85_REG_FAN(i)); |
| 1383 | } | 1408 | } |
| 1384 | 1409 | ||
| 1385 | if (!(data->type == adt7463 && (data->vid & 0x80))) { | 1410 | if (!((data->type == adt7463 || data->type == adt7468) && |
| 1411 | (data->vid & 0x80))) { | ||
| 1386 | data->in[4] = lm85_read_value(client, | 1412 | data->in[4] = lm85_read_value(client, |
| 1387 | LM85_REG_IN(4)); | 1413 | LM85_REG_IN(4)); |
| 1388 | } | 1414 | } |
| 1389 | 1415 | ||
| 1416 | if (data->type == adt7468) | ||
| 1417 | data->cfg5 = lm85_read_value(client, ADT7468_REG_CFG5); | ||
| 1418 | |||
| 1390 | for (i = 0; i <= 2; ++i) { | 1419 | for (i = 0; i <= 2; ++i) { |
| 1391 | data->temp[i] = | 1420 | data->temp[i] = |
| 1392 | lm85_read_value(client, LM85_REG_TEMP(i)); | 1421 | lm85_read_value(client, LM85_REG_TEMP(i)); |
| 1393 | data->pwm[i] = | 1422 | data->pwm[i] = |
| 1394 | lm85_read_value(client, LM85_REG_PWM(i)); | 1423 | lm85_read_value(client, LM85_REG_PWM(i)); |
| 1424 | |||
| 1425 | if (IS_ADT7468_OFF64(data)) | ||
| 1426 | data->temp[i] -= 64; | ||
| 1395 | } | 1427 | } |
| 1396 | 1428 | ||
| 1397 | data->alarms = lm85_read_value(client, LM85_REG_ALARM1); | 1429 | data->alarms = lm85_read_value(client, LM85_REG_ALARM1); |
| @@ -1446,7 +1478,8 @@ static struct lm85_data *lm85_update_device(struct device *dev) | |||
| 1446 | lm85_read_value(client, LM85_REG_FAN_MIN(i)); | 1478 | lm85_read_value(client, LM85_REG_FAN_MIN(i)); |
| 1447 | } | 1479 | } |
| 1448 | 1480 | ||
| 1449 | if (!(data->type == adt7463 && (data->vid & 0x80))) { | 1481 | if (!((data->type == adt7463 || data->type == adt7468) && |
| 1482 | (data->vid & 0x80))) { | ||
| 1450 | data->in_min[4] = lm85_read_value(client, | 1483 | data->in_min[4] = lm85_read_value(client, |
| 1451 | LM85_REG_IN_MIN(4)); | 1484 | LM85_REG_IN_MIN(4)); |
| 1452 | data->in_max[4] = lm85_read_value(client, | 1485 | data->in_max[4] = lm85_read_value(client, |
| @@ -1481,6 +1514,13 @@ static struct lm85_data *lm85_update_device(struct device *dev) | |||
| 1481 | lm85_read_value(client, LM85_REG_AFAN_LIMIT(i)); | 1514 | lm85_read_value(client, LM85_REG_AFAN_LIMIT(i)); |
| 1482 | data->zone[i].critical = | 1515 | data->zone[i].critical = |
| 1483 | lm85_read_value(client, LM85_REG_AFAN_CRITICAL(i)); | 1516 | lm85_read_value(client, LM85_REG_AFAN_CRITICAL(i)); |
| 1517 | |||
| 1518 | if (IS_ADT7468_OFF64(data)) { | ||
| 1519 | data->temp_min[i] -= 64; | ||
| 1520 | data->temp_max[i] -= 64; | ||
| 1521 | data->zone[i].limit -= 64; | ||
| 1522 | data->zone[i].critical -= 64; | ||
| 1523 | } | ||
| 1484 | } | 1524 | } |
| 1485 | 1525 | ||
| 1486 | i = lm85_read_value(client, LM85_REG_AFAN_SPIKE1); | 1526 | i = lm85_read_value(client, LM85_REG_AFAN_SPIKE1); |
