aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2010-03-05 16:17:17 -0500
committerJean Delvare <khali@linux-fr.org>2010-03-05 16:17:17 -0500
commitd9b327c310030fa80abbbc9eaaca9f1a6228dbf3 (patch)
tree43e98a7e1080d9fb1d0586796c4f272dd5b2b530 /drivers/hwmon
parent6a8d7acfbef8ac6bf34421eae980f903cbe36874 (diff)
hwmon: (it87) Add support for beep on alarm
The IT87xxF chips support beeping on alarm, if properly wired and configured. There is one control bit for each input type (temperature, fan, voltage.) Let the user see and change them. Signed-off-by: Jean Delvare <khali@linux-fr.org>
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);