aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/nct6775.c
diff options
context:
space:
mode:
authorGuenter Roeck <linux@roeck-us.net>2012-12-04 06:13:34 -0500
committerGuenter Roeck <linux@roeck-us.net>2013-04-08 00:16:38 -0400
commita6bd587842772cd3e63a689c7ff4d64cf25284a3 (patch)
tree484cc1e651d30adfd71debbce075eb303fd2c127 /drivers/hwmon/nct6775.c
parent9de2e2e84e7d52e4c2a9e1a1e21ab6ac686233c0 (diff)
hwmon: (nct6775) Add case open detection
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Diffstat (limited to 'drivers/hwmon/nct6775.c')
-rw-r--r--drivers/hwmon/nct6775.c67
1 files changed, 67 insertions, 0 deletions
diff --git a/drivers/hwmon/nct6775.c b/drivers/hwmon/nct6775.c
index f75cd8231534..435691febe9b 100644
--- a/drivers/hwmon/nct6775.c
+++ b/drivers/hwmon/nct6775.c
@@ -76,6 +76,7 @@ MODULE_PARM_DESC(force_id, "Override the detected device ID");
76 * Super-I/O constants and functions 76 * Super-I/O constants and functions
77 */ 77 */
78 78
79#define NCT6775_LD_ACPI 0x0a
79#define NCT6775_LD_HWM 0x0b 80#define NCT6775_LD_HWM 0x0b
80#define NCT6775_LD_VID 0x0d 81#define NCT6775_LD_VID 0x0d
81 82
@@ -186,6 +187,11 @@ static const s8 NCT6775_ALARM_BITS[] = {
186 4, 5, 13, -1, -1, -1, /* temp1..temp6 */ 187 4, 5, 13, -1, -1, -1, /* temp1..temp6 */
187 12, -1 }; /* intrusion0, intrusion1 */ 188 12, -1 }; /* intrusion0, intrusion1 */
188 189
190#define INTRUSION_ALARM_BASE 30
191
192static const u8 NCT6775_REG_CR_CASEOPEN_CLR[] = { 0xe6, 0xee };
193static const u8 NCT6775_CR_CASEOPEN_CLR_MASK[] = { 0x20, 0x01 };
194
189/* NCT6776 specific data */ 195/* NCT6776 specific data */
190 196
191static const s8 NCT6776_ALARM_BITS[] = { 197static const s8 NCT6776_ALARM_BITS[] = {
@@ -694,6 +700,56 @@ show_vid(struct device *dev, struct device_attribute *attr, char *buf)
694 700
695static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL); 701static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL);
696 702
703/* Case open detection */
704
705static ssize_t
706clear_caseopen(struct device *dev, struct device_attribute *attr,
707 const char *buf, size_t count)
708{
709 struct nct6775_data *data = dev_get_drvdata(dev);
710 struct nct6775_sio_data *sio_data = dev->platform_data;
711 int nr = to_sensor_dev_attr(attr)->index - INTRUSION_ALARM_BASE;
712 unsigned long val;
713 u8 reg;
714 int ret;
715
716 if (kstrtoul(buf, 10, &val) || val != 0)
717 return -EINVAL;
718
719 mutex_lock(&data->update_lock);
720
721 /*
722 * Use CR registers to clear caseopen status.
723 * The CR registers are the same for all chips, and not all chips
724 * support clearing the caseopen status through "regular" registers.
725 */
726 ret = superio_enter(sio_data->sioreg);
727 if (ret) {
728 count = ret;
729 goto error;
730 }
731
732 superio_select(sio_data->sioreg, NCT6775_LD_ACPI);
733 reg = superio_inb(sio_data->sioreg, NCT6775_REG_CR_CASEOPEN_CLR[nr]);
734 reg |= NCT6775_CR_CASEOPEN_CLR_MASK[nr];
735 superio_outb(sio_data->sioreg, NCT6775_REG_CR_CASEOPEN_CLR[nr], reg);
736 reg &= ~NCT6775_CR_CASEOPEN_CLR_MASK[nr];
737 superio_outb(sio_data->sioreg, NCT6775_REG_CR_CASEOPEN_CLR[nr], reg);
738 superio_exit(sio_data->sioreg);
739
740 data->valid = false; /* Force cache refresh */
741error:
742 mutex_unlock(&data->update_lock);
743 return count;
744}
745
746static struct sensor_device_attribute sda_caseopen[] = {
747 SENSOR_ATTR(intrusion0_alarm, S_IWUSR | S_IRUGO, show_alarm,
748 clear_caseopen, INTRUSION_ALARM_BASE),
749 SENSOR_ATTR(intrusion1_alarm, S_IWUSR | S_IRUGO, show_alarm,
750 clear_caseopen, INTRUSION_ALARM_BASE + 1),
751};
752
697/* 753/*
698 * Driver and device management 754 * Driver and device management
699 */ 755 */
@@ -710,6 +766,9 @@ static void nct6775_device_remove_files(struct device *dev)
710 for (i = 0; i < data->in_num; i++) 766 for (i = 0; i < data->in_num; i++)
711 sysfs_remove_group(&dev->kobj, &nct6775_group_in[i]); 767 sysfs_remove_group(&dev->kobj, &nct6775_group_in[i]);
712 768
769 device_remove_file(dev, &sda_caseopen[0].dev_attr);
770 device_remove_file(dev, &sda_caseopen[1].dev_attr);
771
713 device_remove_file(dev, &dev_attr_name); 772 device_remove_file(dev, &dev_attr_name);
714 device_remove_file(dev, &dev_attr_cpu0_vid); 773 device_remove_file(dev, &dev_attr_cpu0_vid);
715} 774}
@@ -828,6 +887,14 @@ static int nct6775_probe(struct platform_device *pdev)
828 goto exit_remove; 887 goto exit_remove;
829 } 888 }
830 889
890 for (i = 0; i < ARRAY_SIZE(sda_caseopen); i++) {
891 if (data->ALARM_BITS[INTRUSION_ALARM_BASE + i] < 0)
892 continue;
893 err = device_create_file(dev, &sda_caseopen[i].dev_attr);
894 if (err)
895 goto exit_remove;
896 }
897
831 err = device_create_file(dev, &dev_attr_name); 898 err = device_create_file(dev, &dev_attr_name);
832 if (err) 899 if (err)
833 goto exit_remove; 900 goto exit_remove;