diff options
-rw-r--r-- | Documentation/hwmon/lm85 | 12 | ||||
-rw-r--r-- | drivers/hwmon/lm85.c | 75 |
2 files changed, 62 insertions, 25 deletions
diff --git a/Documentation/hwmon/lm85 b/Documentation/hwmon/lm85 index 239258a63c81..7c49feaa79d2 100644 --- a/Documentation/hwmon/lm85 +++ b/Documentation/hwmon/lm85 | |||
@@ -26,6 +26,14 @@ Supported chips: | |||
26 | Prefix: 'emc6d102' | 26 | Prefix: 'emc6d102' |
27 | Addresses scanned: I2C 0x2c, 0x2d, 0x2e | 27 | Addresses scanned: I2C 0x2c, 0x2d, 0x2e |
28 | Datasheet: http://www.smsc.com/main/catalog/emc6d102.html | 28 | Datasheet: http://www.smsc.com/main/catalog/emc6d102.html |
29 | * SMSC EMC6D103 | ||
30 | Prefix: 'emc6d103' | ||
31 | Addresses scanned: I2C 0x2c, 0x2d, 0x2e | ||
32 | Datasheet: http://www.smsc.com/main/catalog/emc6d103.html | ||
33 | * SMSC EMC6D103S | ||
34 | Prefix: 'emc6d103s' | ||
35 | Addresses scanned: I2C 0x2c, 0x2d, 0x2e | ||
36 | Datasheet: http://www.smsc.com/main/catalog/emc6d103s.html | ||
29 | 37 | ||
30 | Authors: | 38 | Authors: |
31 | Philip Pokorny <ppokorny@penguincomputing.com>, | 39 | Philip Pokorny <ppokorny@penguincomputing.com>, |
@@ -122,9 +130,11 @@ to be register compatible. The EMC6D100 offers all the features of the | |||
122 | EMC6D101 plus additional voltage monitoring and system control features. | 130 | EMC6D101 plus additional voltage monitoring and system control features. |
123 | Unfortunately it is not possible to distinguish between the package | 131 | Unfortunately it is not possible to distinguish between the package |
124 | versions on register level so these additional voltage inputs may read | 132 | versions on register level so these additional voltage inputs may read |
125 | zero. The EMC6D102 features addtional ADC bits thus extending precision | 133 | zero. EMC6D102 and EMC6D103 feature additional ADC bits thus extending precision |
126 | of voltage and temperature channels. | 134 | of voltage and temperature channels. |
127 | 135 | ||
136 | SMSC EMC6D103S is similar to EMC6D103, but does not support pwm#_auto_pwm_minctl | ||
137 | and temp#_auto_temp_off. | ||
128 | 138 | ||
129 | Hardware Configurations | 139 | Hardware Configurations |
130 | ----------------------- | 140 | ----------------------- |
diff --git a/drivers/hwmon/lm85.c b/drivers/hwmon/lm85.c index fbb5189141bc..cf47e6e476ed 100644 --- a/drivers/hwmon/lm85.c +++ b/drivers/hwmon/lm85.c | |||
@@ -41,7 +41,7 @@ static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; | |||
41 | enum chips { | 41 | enum chips { |
42 | any_chip, lm85b, lm85c, | 42 | any_chip, lm85b, lm85c, |
43 | adm1027, adt7463, adt7468, | 43 | adm1027, adt7463, adt7468, |
44 | emc6d100, emc6d102, emc6d103 | 44 | emc6d100, emc6d102, emc6d103, emc6d103s |
45 | }; | 45 | }; |
46 | 46 | ||
47 | /* The LM85 registers */ | 47 | /* The LM85 registers */ |
@@ -350,6 +350,7 @@ static const struct i2c_device_id lm85_id[] = { | |||
350 | { "emc6d101", emc6d100 }, | 350 | { "emc6d101", emc6d100 }, |
351 | { "emc6d102", emc6d102 }, | 351 | { "emc6d102", emc6d102 }, |
352 | { "emc6d103", emc6d103 }, | 352 | { "emc6d103", emc6d103 }, |
353 | { "emc6d103s", emc6d103s }, | ||
353 | { } | 354 | { } |
354 | }; | 355 | }; |
355 | MODULE_DEVICE_TABLE(i2c, lm85_id); | 356 | MODULE_DEVICE_TABLE(i2c, lm85_id); |
@@ -1068,13 +1069,7 @@ static struct attribute *lm85_attributes[] = { | |||
1068 | &sensor_dev_attr_pwm1_auto_pwm_min.dev_attr.attr, | 1069 | &sensor_dev_attr_pwm1_auto_pwm_min.dev_attr.attr, |
1069 | &sensor_dev_attr_pwm2_auto_pwm_min.dev_attr.attr, | 1070 | &sensor_dev_attr_pwm2_auto_pwm_min.dev_attr.attr, |
1070 | &sensor_dev_attr_pwm3_auto_pwm_min.dev_attr.attr, | 1071 | &sensor_dev_attr_pwm3_auto_pwm_min.dev_attr.attr, |
1071 | &sensor_dev_attr_pwm1_auto_pwm_minctl.dev_attr.attr, | ||
1072 | &sensor_dev_attr_pwm2_auto_pwm_minctl.dev_attr.attr, | ||
1073 | &sensor_dev_attr_pwm3_auto_pwm_minctl.dev_attr.attr, | ||
1074 | 1072 | ||
1075 | &sensor_dev_attr_temp1_auto_temp_off.dev_attr.attr, | ||
1076 | &sensor_dev_attr_temp2_auto_temp_off.dev_attr.attr, | ||
1077 | &sensor_dev_attr_temp3_auto_temp_off.dev_attr.attr, | ||
1078 | &sensor_dev_attr_temp1_auto_temp_min.dev_attr.attr, | 1073 | &sensor_dev_attr_temp1_auto_temp_min.dev_attr.attr, |
1079 | &sensor_dev_attr_temp2_auto_temp_min.dev_attr.attr, | 1074 | &sensor_dev_attr_temp2_auto_temp_min.dev_attr.attr, |
1080 | &sensor_dev_attr_temp3_auto_temp_min.dev_attr.attr, | 1075 | &sensor_dev_attr_temp3_auto_temp_min.dev_attr.attr, |
@@ -1095,6 +1090,26 @@ static const struct attribute_group lm85_group = { | |||
1095 | .attrs = lm85_attributes, | 1090 | .attrs = lm85_attributes, |
1096 | }; | 1091 | }; |
1097 | 1092 | ||
1093 | static struct attribute *lm85_attributes_minctl[] = { | ||
1094 | &sensor_dev_attr_pwm1_auto_pwm_minctl.dev_attr.attr, | ||
1095 | &sensor_dev_attr_pwm2_auto_pwm_minctl.dev_attr.attr, | ||
1096 | &sensor_dev_attr_pwm3_auto_pwm_minctl.dev_attr.attr, | ||
1097 | }; | ||
1098 | |||
1099 | static const struct attribute_group lm85_group_minctl = { | ||
1100 | .attrs = lm85_attributes_minctl, | ||
1101 | }; | ||
1102 | |||
1103 | static struct attribute *lm85_attributes_temp_off[] = { | ||
1104 | &sensor_dev_attr_temp1_auto_temp_off.dev_attr.attr, | ||
1105 | &sensor_dev_attr_temp2_auto_temp_off.dev_attr.attr, | ||
1106 | &sensor_dev_attr_temp3_auto_temp_off.dev_attr.attr, | ||
1107 | }; | ||
1108 | |||
1109 | static const struct attribute_group lm85_group_temp_off = { | ||
1110 | .attrs = lm85_attributes_temp_off, | ||
1111 | }; | ||
1112 | |||
1098 | static struct attribute *lm85_attributes_in4[] = { | 1113 | static struct attribute *lm85_attributes_in4[] = { |
1099 | &sensor_dev_attr_in4_input.dev_attr.attr, | 1114 | &sensor_dev_attr_in4_input.dev_attr.attr, |
1100 | &sensor_dev_attr_in4_min.dev_attr.attr, | 1115 | &sensor_dev_attr_in4_min.dev_attr.attr, |
@@ -1242,16 +1257,9 @@ static int lm85_detect(struct i2c_client *client, struct i2c_board_info *info) | |||
1242 | case LM85_VERSTEP_EMC6D103_A1: | 1257 | case LM85_VERSTEP_EMC6D103_A1: |
1243 | type_name = "emc6d103"; | 1258 | type_name = "emc6d103"; |
1244 | break; | 1259 | break; |
1245 | /* | ||
1246 | * Registers apparently missing in EMC6D103S/EMC6D103:A2 | ||
1247 | * compared to EMC6D103:A0, EMC6D103:A1, and EMC6D102 | ||
1248 | * (according to the data sheets), but used unconditionally | ||
1249 | * in the driver: 62[5:7], 6D[0:7], and 6E[0:7]. | ||
1250 | * So skip EMC6D103S for now. | ||
1251 | case LM85_VERSTEP_EMC6D103S: | 1260 | case LM85_VERSTEP_EMC6D103S: |
1252 | type_name = "emc6d103s"; | 1261 | type_name = "emc6d103s"; |
1253 | break; | 1262 | break; |
1254 | */ | ||
1255 | } | 1263 | } |
1256 | } else { | 1264 | } else { |
1257 | dev_dbg(&adapter->dev, | 1265 | dev_dbg(&adapter->dev, |
@@ -1267,6 +1275,10 @@ static int lm85_detect(struct i2c_client *client, struct i2c_board_info *info) | |||
1267 | static void lm85_remove_files(struct i2c_client *client, struct lm85_data *data) | 1275 | static void lm85_remove_files(struct i2c_client *client, struct lm85_data *data) |
1268 | { | 1276 | { |
1269 | sysfs_remove_group(&client->dev.kobj, &lm85_group); | 1277 | sysfs_remove_group(&client->dev.kobj, &lm85_group); |
1278 | if (data->type != emc6d103s) { | ||
1279 | sysfs_remove_group(&client->dev.kobj, &lm85_group_minctl); | ||
1280 | sysfs_remove_group(&client->dev.kobj, &lm85_group_temp_off); | ||
1281 | } | ||
1270 | if (!data->has_vid5) | 1282 | if (!data->has_vid5) |
1271 | sysfs_remove_group(&client->dev.kobj, &lm85_group_in4); | 1283 | sysfs_remove_group(&client->dev.kobj, &lm85_group_in4); |
1272 | if (data->type == emc6d100) | 1284 | if (data->type == emc6d100) |
@@ -1295,6 +1307,7 @@ static int lm85_probe(struct i2c_client *client, | |||
1295 | case emc6d100: | 1307 | case emc6d100: |
1296 | case emc6d102: | 1308 | case emc6d102: |
1297 | case emc6d103: | 1309 | case emc6d103: |
1310 | case emc6d103s: | ||
1298 | data->freq_map = adm1027_freq_map; | 1311 | data->freq_map = adm1027_freq_map; |
1299 | break; | 1312 | break; |
1300 | default: | 1313 | default: |
@@ -1312,6 +1325,17 @@ static int lm85_probe(struct i2c_client *client, | |||
1312 | if (err) | 1325 | if (err) |
1313 | goto err_kfree; | 1326 | goto err_kfree; |
1314 | 1327 | ||
1328 | /* minctl and temp_off exist on all chips except emc6d103s */ | ||
1329 | if (data->type != emc6d103s) { | ||
1330 | err = sysfs_create_group(&client->dev.kobj, &lm85_group_minctl); | ||
1331 | if (err) | ||
1332 | goto err_kfree; | ||
1333 | err = sysfs_create_group(&client->dev.kobj, | ||
1334 | &lm85_group_temp_off); | ||
1335 | if (err) | ||
1336 | goto err_kfree; | ||
1337 | } | ||
1338 | |||
1315 | /* The ADT7463/68 have an optional VRM 10 mode where pin 21 is used | 1339 | /* The ADT7463/68 have an optional VRM 10 mode where pin 21 is used |
1316 | as a sixth digital VID input rather than an analog input. */ | 1340 | as a sixth digital VID input rather than an analog input. */ |
1317 | if (data->type == adt7463 || data->type == adt7468) { | 1341 | if (data->type == adt7463 || data->type == adt7468) { |
@@ -1475,7 +1499,8 @@ static struct lm85_data *lm85_update_device(struct device *dev) | |||
1475 | /* More alarm bits */ | 1499 | /* More alarm bits */ |
1476 | data->alarms |= lm85_read_value(client, | 1500 | data->alarms |= lm85_read_value(client, |
1477 | EMC6D100_REG_ALARM3) << 16; | 1501 | EMC6D100_REG_ALARM3) << 16; |
1478 | } else if (data->type == emc6d102 || data->type == emc6d103) { | 1502 | } else if (data->type == emc6d102 || data->type == emc6d103 || |
1503 | data->type == emc6d103s) { | ||
1479 | /* Have to read LSB bits after the MSB ones because | 1504 | /* Have to read LSB bits after the MSB ones because |
1480 | the reading of the MSB bits has frozen the | 1505 | the reading of the MSB bits has frozen the |
1481 | LSBs (backward from the ADM1027). | 1506 | LSBs (backward from the ADM1027). |
@@ -1560,17 +1585,19 @@ static struct lm85_data *lm85_update_device(struct device *dev) | |||
1560 | } | 1585 | } |
1561 | } | 1586 | } |
1562 | 1587 | ||
1563 | i = lm85_read_value(client, LM85_REG_AFAN_SPIKE1); | 1588 | if (data->type != emc6d103s) { |
1564 | data->autofan[0].min_off = (i & 0x20) != 0; | 1589 | i = lm85_read_value(client, LM85_REG_AFAN_SPIKE1); |
1565 | data->autofan[1].min_off = (i & 0x40) != 0; | 1590 | data->autofan[0].min_off = (i & 0x20) != 0; |
1566 | data->autofan[2].min_off = (i & 0x80) != 0; | 1591 | data->autofan[1].min_off = (i & 0x40) != 0; |
1592 | data->autofan[2].min_off = (i & 0x80) != 0; | ||
1567 | 1593 | ||
1568 | i = lm85_read_value(client, LM85_REG_AFAN_HYST1); | 1594 | i = lm85_read_value(client, LM85_REG_AFAN_HYST1); |
1569 | data->zone[0].hyst = i >> 4; | 1595 | data->zone[0].hyst = i >> 4; |
1570 | data->zone[1].hyst = i & 0x0f; | 1596 | data->zone[1].hyst = i & 0x0f; |
1571 | 1597 | ||
1572 | i = lm85_read_value(client, LM85_REG_AFAN_HYST2); | 1598 | i = lm85_read_value(client, LM85_REG_AFAN_HYST2); |
1573 | data->zone[2].hyst = i >> 4; | 1599 | data->zone[2].hyst = i >> 4; |
1600 | } | ||
1574 | 1601 | ||
1575 | data->last_config = jiffies; | 1602 | data->last_config = jiffies; |
1576 | } /* last_config */ | 1603 | } /* last_config */ |