aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon')
-rw-r--r--drivers/hwmon/it87.c122
1 files changed, 122 insertions, 0 deletions
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 7a349e066fdc..d70c6ec31725 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -128,6 +128,7 @@ superio_exit(void)
128#define IT87_SIO_GPIO5_REG 0x29 128#define IT87_SIO_GPIO5_REG 0x29
129#define IT87_SIO_PINX2_REG 0x2c /* Pin selection */ 129#define IT87_SIO_PINX2_REG 0x2c /* Pin selection */
130#define IT87_SIO_VID_REG 0xfc /* VID value */ 130#define IT87_SIO_VID_REG 0xfc /* VID value */
131#define IT87_SIO_BEEP_PIN_REG 0xf6 /* Beep pin mapping */
131 132
132/* Update battery voltage after every reading if true */ 133/* Update battery voltage after every reading if true */
133static int update_vbat; 134static int update_vbat;
@@ -187,6 +188,7 @@ static const u8 IT87_REG_FANX_MIN[] = { 0x1b, 0x1c, 0x1d, 0x85, 0x87 };
187 188
188#define IT87_REG_VIN_ENABLE 0x50 189#define IT87_REG_VIN_ENABLE 0x50
189#define IT87_REG_TEMP_ENABLE 0x51 190#define IT87_REG_TEMP_ENABLE 0x51
191#define IT87_REG_BEEP_ENABLE 0x5c
190 192
191#define IT87_REG_CHIPID 0x58 193#define IT87_REG_CHIPID 0x58
192 194
@@ -246,6 +248,7 @@ struct it87_sio_data {
246 /* Values read from Super-I/O config space */ 248 /* Values read from Super-I/O config space */
247 u8 revision; 249 u8 revision;
248 u8 vid_value; 250 u8 vid_value;
251 u8 beep_pin;
249 /* Features skipped based on config or DMI */ 252 /* Features skipped based on config or DMI */
250 u8 skip_vid; 253 u8 skip_vid;
251 u8 skip_fan; 254 u8 skip_fan;
@@ -279,6 +282,7 @@ struct it87_data {
279 u8 vid; /* Register encoding, combined */ 282 u8 vid; /* Register encoding, combined */
280 u8 vrm; 283 u8 vrm;
281 u32 alarms; /* Register encoding, combined */ 284 u32 alarms; /* Register encoding, combined */
285 u8 beeps; /* Register encoding */
282 u8 fan_main_ctrl; /* Register value */ 286 u8 fan_main_ctrl; /* Register value */
283 u8 fan_ctl; /* Register value */ 287 u8 fan_ctl; /* Register value */
284 288
@@ -919,6 +923,55 @@ static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 16);
919static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 17); 923static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 17);
920static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 18); 924static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 18);
921 925
926static ssize_t show_beep(struct device *dev, struct device_attribute *attr,
927 char *buf)
928{
929 int bitnr = to_sensor_dev_attr(attr)->index;
930 struct it87_data *data = it87_update_device(dev);
931 return sprintf(buf, "%u\n", (data->beeps >> bitnr) & 1);
932}
933static ssize_t set_beep(struct device *dev, struct device_attribute *attr,
934 const char *buf, size_t count)
935{
936 int bitnr = to_sensor_dev_attr(attr)->index;
937 struct it87_data *data = dev_get_drvdata(dev);
938 long val;
939
940 if (strict_strtol(buf, 10, &val) < 0
941 || (val != 0 && val != 1))
942 return -EINVAL;
943
944 mutex_lock(&data->update_lock);
945 data->beeps = it87_read_value(data, IT87_REG_BEEP_ENABLE);
946 if (val)
947 data->beeps |= (1 << bitnr);
948 else
949 data->beeps &= ~(1 << bitnr);
950 it87_write_value(data, IT87_REG_BEEP_ENABLE, data->beeps);
951 mutex_unlock(&data->update_lock);
952 return count;
953}
954
955static SENSOR_DEVICE_ATTR(in0_beep, S_IRUGO | S_IWUSR,
956 show_beep, set_beep, 1);
957static SENSOR_DEVICE_ATTR(in1_beep, S_IRUGO, show_beep, NULL, 1);
958static SENSOR_DEVICE_ATTR(in2_beep, S_IRUGO, show_beep, NULL, 1);
959static SENSOR_DEVICE_ATTR(in3_beep, S_IRUGO, show_beep, NULL, 1);
960static SENSOR_DEVICE_ATTR(in4_beep, S_IRUGO, show_beep, NULL, 1);
961static SENSOR_DEVICE_ATTR(in5_beep, S_IRUGO, show_beep, NULL, 1);
962static SENSOR_DEVICE_ATTR(in6_beep, S_IRUGO, show_beep, NULL, 1);
963static SENSOR_DEVICE_ATTR(in7_beep, S_IRUGO, show_beep, NULL, 1);
964/* fanX_beep writability is set later */
965static SENSOR_DEVICE_ATTR(fan1_beep, S_IRUGO, show_beep, set_beep, 0);
966static SENSOR_DEVICE_ATTR(fan2_beep, S_IRUGO, show_beep, set_beep, 0);
967static SENSOR_DEVICE_ATTR(fan3_beep, S_IRUGO, show_beep, set_beep, 0);
968static SENSOR_DEVICE_ATTR(fan4_beep, S_IRUGO, show_beep, set_beep, 0);
969static SENSOR_DEVICE_ATTR(fan5_beep, S_IRUGO, show_beep, set_beep, 0);
970static SENSOR_DEVICE_ATTR(temp1_beep, S_IRUGO | S_IWUSR,
971 show_beep, set_beep, 2);
972static SENSOR_DEVICE_ATTR(temp2_beep, S_IRUGO, show_beep, NULL, 2);
973static SENSOR_DEVICE_ATTR(temp3_beep, S_IRUGO, show_beep, NULL, 2);
974
922static ssize_t 975static ssize_t
923show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf) 976show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf)
924{ 977{
@@ -1014,6 +1067,26 @@ static const struct attribute_group it87_group = {
1014 .attrs = it87_attributes, 1067 .attrs = it87_attributes,
1015}; 1068};
1016 1069
1070static struct attribute *it87_attributes_beep[] = {
1071 &sensor_dev_attr_in0_beep.dev_attr.attr,
1072 &sensor_dev_attr_in1_beep.dev_attr.attr,
1073 &sensor_dev_attr_in2_beep.dev_attr.attr,
1074 &sensor_dev_attr_in3_beep.dev_attr.attr,
1075 &sensor_dev_attr_in4_beep.dev_attr.attr,
1076 &sensor_dev_attr_in5_beep.dev_attr.attr,
1077 &sensor_dev_attr_in6_beep.dev_attr.attr,
1078 &sensor_dev_attr_in7_beep.dev_attr.attr,
1079
1080 &sensor_dev_attr_temp1_beep.dev_attr.attr,
1081 &sensor_dev_attr_temp2_beep.dev_attr.attr,
1082 &sensor_dev_attr_temp3_beep.dev_attr.attr,
1083 NULL
1084};
1085
1086static const struct attribute_group it87_group_beep = {
1087 .attrs = it87_attributes_beep,
1088};
1089
1017static struct attribute *it87_attributes_fan16[5][3+1] = { { 1090static struct attribute *it87_attributes_fan16[5][3+1] = { {
1018 &sensor_dev_attr_fan1_input16.dev_attr.attr, 1091 &sensor_dev_attr_fan1_input16.dev_attr.attr,
1019 &sensor_dev_attr_fan1_min16.dev_attr.attr, 1092 &sensor_dev_attr_fan1_min16.dev_attr.attr,
@@ -1107,6 +1180,14 @@ static const struct attribute_group it87_group_pwm[3] = {
1107 { .attrs = it87_attributes_pwm[2] }, 1180 { .attrs = it87_attributes_pwm[2] },
1108}; 1181};
1109 1182
1183static struct attribute *it87_attributes_fan_beep[] = {
1184 &sensor_dev_attr_fan1_beep.dev_attr.attr,
1185 &sensor_dev_attr_fan2_beep.dev_attr.attr,
1186 &sensor_dev_attr_fan3_beep.dev_attr.attr,
1187 &sensor_dev_attr_fan4_beep.dev_attr.attr,
1188 &sensor_dev_attr_fan5_beep.dev_attr.attr,
1189};
1190
1110static struct attribute *it87_attributes_vid[] = { 1191static struct attribute *it87_attributes_vid[] = {
1111 &dev_attr_vrm.attr, 1192 &dev_attr_vrm.attr,
1112 &dev_attr_cpu0_vid.attr, 1193 &dev_attr_cpu0_vid.attr,
@@ -1174,6 +1255,10 @@ static int __init it87_find(unsigned short *address,
1174 if (sio_data->type == it87) { 1255 if (sio_data->type == it87) {
1175 /* The IT8705F doesn't have VID pins at all */ 1256 /* The IT8705F doesn't have VID pins at all */
1176 sio_data->skip_vid = 1; 1257 sio_data->skip_vid = 1;
1258
1259 /* The IT8705F has a different LD number for GPIO */
1260 superio_select(5);
1261 sio_data->beep_pin = superio_inb(IT87_SIO_BEEP_PIN_REG) & 0x3f;
1177 } else { 1262 } else {
1178 int reg; 1263 int reg;
1179 1264
@@ -1207,7 +1292,11 @@ static int __init it87_find(unsigned short *address,
1207 pr_info("it87: in3 is VCC (+5V)\n"); 1292 pr_info("it87: in3 is VCC (+5V)\n");
1208 if (reg & (1 << 1)) 1293 if (reg & (1 << 1))
1209 pr_info("it87: in7 is VCCH (+5V Stand-By)\n"); 1294 pr_info("it87: in7 is VCCH (+5V Stand-By)\n");
1295
1296 sio_data->beep_pin = superio_inb(IT87_SIO_BEEP_PIN_REG) & 0x3f;
1210 } 1297 }
1298 if (sio_data->beep_pin)
1299 pr_info("it87: Beeping is supported\n");
1211 1300
1212 /* Disable specific features based on DMI strings */ 1301 /* Disable specific features based on DMI strings */
1213 board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR); 1302 board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR);
@@ -1240,10 +1329,15 @@ static void it87_remove_files(struct device *dev)
1240 int i; 1329 int i;
1241 1330
1242 sysfs_remove_group(&dev->kobj, &it87_group); 1331 sysfs_remove_group(&dev->kobj, &it87_group);
1332 if (sio_data->beep_pin)
1333 sysfs_remove_group(&dev->kobj, &it87_group_beep);
1243 for (i = 0; i < 5; i++) { 1334 for (i = 0; i < 5; i++) {
1244 if (!(data->has_fan & (1 << i))) 1335 if (!(data->has_fan & (1 << i)))
1245 continue; 1336 continue;
1246 sysfs_remove_group(&dev->kobj, &fan_group[i]); 1337 sysfs_remove_group(&dev->kobj, &fan_group[i]);
1338 if (sio_data->beep_pin)
1339 sysfs_remove_file(&dev->kobj,
1340 it87_attributes_fan_beep[i]);
1247 } 1341 }
1248 for (i = 0; i < 3; i++) { 1342 for (i = 0; i < 3; i++) {
1249 if (sio_data->skip_pwm & (1 << 0)) 1343 if (sio_data->skip_pwm & (1 << 0))
@@ -1263,6 +1357,7 @@ static int __devinit it87_probe(struct platform_device *pdev)
1263 const struct attribute_group *fan_group; 1357 const struct attribute_group *fan_group;
1264 int err = 0, i; 1358 int err = 0, i;
1265 int enable_pwm_interface; 1359 int enable_pwm_interface;
1360 int fan_beep_need_rw;
1266 static const char *names[] = { 1361 static const char *names[] = {
1267 "it87", 1362 "it87",
1268 "it8712", 1363 "it8712",
@@ -1311,14 +1406,40 @@ static int __devinit it87_probe(struct platform_device *pdev)
1311 if ((err = sysfs_create_group(&dev->kobj, &it87_group))) 1406 if ((err = sysfs_create_group(&dev->kobj, &it87_group)))
1312 goto ERROR2; 1407 goto ERROR2;
1313 1408
1409 if (sio_data->beep_pin) {
1410 err = sysfs_create_group(&dev->kobj, &it87_group_beep);
1411 if (err)
1412 goto ERROR4;
1413 }
1414
1314 /* Do not create fan files for disabled fans */ 1415 /* Do not create fan files for disabled fans */
1315 fan_group = it87_get_fan_group(data); 1416 fan_group = it87_get_fan_group(data);
1417 fan_beep_need_rw = 1;
1316 for (i = 0; i < 5; i++) { 1418 for (i = 0; i < 5; i++) {
1317 if (!(data->has_fan & (1 << i))) 1419 if (!(data->has_fan & (1 << i)))
1318 continue; 1420 continue;
1319 err = sysfs_create_group(&dev->kobj, &fan_group[i]); 1421 err = sysfs_create_group(&dev->kobj, &fan_group[i]);
1320 if (err) 1422 if (err)
1321 goto ERROR4; 1423 goto ERROR4;
1424
1425 if (sio_data->beep_pin) {
1426 err = sysfs_create_file(&dev->kobj,
1427 it87_attributes_fan_beep[i]);
1428 if (err)
1429 goto ERROR4;
1430 if (!fan_beep_need_rw)
1431 continue;
1432
1433 /* As we have a single beep enable bit for all fans,
1434 * only the first enabled fan has a writable attribute
1435 * for it. */
1436 if (sysfs_chmod_file(&dev->kobj,
1437 it87_attributes_fan_beep[i],
1438 S_IRUGO | S_IWUSR))
1439 dev_dbg(dev, "chmod +w fan%d_beep failed\n",
1440 i + 1);
1441 fan_beep_need_rw = 0;
1442 }
1322 } 1443 }
1323 1444
1324 if (enable_pwm_interface) { 1445 if (enable_pwm_interface) {
@@ -1608,6 +1729,7 @@ static struct it87_data *it87_update_device(struct device *dev)
1608 it87_read_value(data, IT87_REG_ALARM1) | 1729 it87_read_value(data, IT87_REG_ALARM1) |
1609 (it87_read_value(data, IT87_REG_ALARM2) << 8) | 1730 (it87_read_value(data, IT87_REG_ALARM2) << 8) |
1610 (it87_read_value(data, IT87_REG_ALARM3) << 16); 1731 (it87_read_value(data, IT87_REG_ALARM3) << 16);
1732 data->beeps = it87_read_value(data, IT87_REG_BEEP_ENABLE);
1611 1733
1612 data->fan_main_ctrl = it87_read_value(data, 1734 data->fan_main_ctrl = it87_read_value(data,
1613 IT87_REG_FAN_MAIN_CTRL); 1735 IT87_REG_FAN_MAIN_CTRL);