From 6cb59e915d04f71c62a0ee8fab34de274aa3fe2a Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sun, 6 Jan 2008 15:25:52 +0100 Subject: hwmon: (lm92) Add individual alarm files The new libsensors needs these individual alarm files. Signed-off-by: Jean Delvare Acked-by: Juerg Haefliger Signed-off-by: Mark M. Hoffman --- drivers/hwmon/lm92.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hwmon/lm92.c b/drivers/hwmon/lm92.c index af5c77d568fe..a2b804115ce5 100644 --- a/drivers/hwmon/lm92.c +++ b/drivers/hwmon/lm92.c @@ -45,6 +45,7 @@ #include #include #include +#include #include #include @@ -209,6 +210,14 @@ static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, ch return sprintf(buf, "%d\n", ALARMS_FROM_REG(data->temp1_input)); } +static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int bitnr = to_sensor_dev_attr(attr)->index; + struct lm92_data *data = lm92_update_device(dev); + return sprintf(buf, "%d\n", (data->temp1_input >> bitnr) & 1); +} + static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp1_input, NULL); static DEVICE_ATTR(temp1_crit, S_IWUSR | S_IRUGO, show_temp1_crit, set_temp1_crit); @@ -221,6 +230,9 @@ static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp1_max, set_temp1_max); static DEVICE_ATTR(temp1_max_hyst, S_IRUGO, show_temp1_max_hyst, NULL); static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); +static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 2); +static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, show_alarm, NULL, 0); +static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 1); /* @@ -297,7 +309,9 @@ static struct attribute *lm92_attributes[] = { &dev_attr_temp1_max.attr, &dev_attr_temp1_max_hyst.attr, &dev_attr_alarms.attr, - + &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, + &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, + &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, NULL }; -- cgit v1.2.2 From 71062ffcd5173b8291ee80e84711b619b34a64eb Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sun, 6 Jan 2008 15:27:59 +0100 Subject: hwmon: (max1619) Add individual alarm and fault files The new libsensors needs these individual alarm and fault files. Signed-off-by: Jean Delvare Acked-by: Juerg Haefliger Signed-off-by: Mark M. Hoffman --- drivers/hwmon/max1619.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'drivers') diff --git a/drivers/hwmon/max1619.c b/drivers/hwmon/max1619.c index 38a44c3d6cee..342803417973 100644 --- a/drivers/hwmon/max1619.c +++ b/drivers/hwmon/max1619.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -161,6 +162,14 @@ static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, ch return sprintf(buf, "%d\n", data->alarms); } +static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int bitnr = to_sensor_dev_attr(attr)->index; + struct max1619_data *data = max1619_update_device(dev); + return sprintf(buf, "%d\n", (data->alarms >> bitnr) & 1); +} + static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_input1, NULL); static DEVICE_ATTR(temp2_input, S_IRUGO, show_temp_input2, NULL); static DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp_low2, @@ -172,6 +181,10 @@ static DEVICE_ATTR(temp2_crit, S_IWUSR | S_IRUGO, show_temp_crit2, static DEVICE_ATTR(temp2_crit_hyst, S_IWUSR | S_IRUGO, show_temp_hyst2, set_temp_hyst2); static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); +static SENSOR_DEVICE_ATTR(temp2_crit_alarm, S_IRUGO, show_alarm, NULL, 1); +static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_alarm, NULL, 2); +static SENSOR_DEVICE_ATTR(temp2_min_alarm, S_IRUGO, show_alarm, NULL, 3); +static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_alarm, NULL, 4); static struct attribute *max1619_attributes[] = { &dev_attr_temp1_input.attr, @@ -182,6 +195,10 @@ static struct attribute *max1619_attributes[] = { &dev_attr_temp2_crit_hyst.attr, &dev_attr_alarms.attr, + &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr, + &sensor_dev_attr_temp2_fault.dev_attr.attr, + &sensor_dev_attr_temp2_min_alarm.dev_attr.attr, + &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, NULL }; -- cgit v1.2.2 From 1f08af7ea95e0f4ec632664b9f21a687426df658 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sun, 6 Jan 2008 15:36:13 +0100 Subject: hwmon: (smsc47m1) Add individual alarm files The new libsensors needs these individual alarm files. Signed-off-by: Jean Delvare Acked-by: Juerg Haefliger Signed-off-by: Mark M. Hoffman --- drivers/hwmon/smsc47m1.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c index 0d7f0c4d06bb..d1b498548736 100644 --- a/drivers/hwmon/smsc47m1.c +++ b/drivers/hwmon/smsc47m1.c @@ -198,6 +198,14 @@ static ssize_t get_fan_div(struct device *dev, struct device_attribute return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[attr->index])); } +static ssize_t get_fan_alarm(struct device *dev, struct device_attribute + *devattr, char *buf) +{ + int bitnr = to_sensor_dev_attr(devattr)->index; + struct smsc47m1_data *data = smsc47m1_update_device(dev, 0); + return sprintf(buf, "%u\n", (data->alarms >> bitnr) & 1); +} + static ssize_t get_pwm(struct device *dev, struct device_attribute *devattr, char *buf) { @@ -347,6 +355,8 @@ static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ get_fan_min, set_fan_min, offset - 1); \ static SENSOR_DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \ get_fan_div, set_fan_div, offset - 1); \ +static SENSOR_DEVICE_ATTR(fan##offset##_alarm, S_IRUGO, get_fan_alarm, \ + NULL, offset - 1); \ static SENSOR_DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \ get_pwm, set_pwm, offset - 1); \ static SENSOR_DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR, \ @@ -374,12 +384,15 @@ static struct attribute *smsc47m1_attributes[] = { &sensor_dev_attr_fan1_input.dev_attr.attr, &sensor_dev_attr_fan1_min.dev_attr.attr, &sensor_dev_attr_fan1_div.dev_attr.attr, + &sensor_dev_attr_fan1_alarm.dev_attr.attr, &sensor_dev_attr_fan2_input.dev_attr.attr, &sensor_dev_attr_fan2_min.dev_attr.attr, &sensor_dev_attr_fan2_div.dev_attr.attr, + &sensor_dev_attr_fan2_alarm.dev_attr.attr, &sensor_dev_attr_fan3_input.dev_attr.attr, &sensor_dev_attr_fan3_min.dev_attr.attr, &sensor_dev_attr_fan3_div.dev_attr.attr, + &sensor_dev_attr_fan3_alarm.dev_attr.attr, &sensor_dev_attr_pwm1.dev_attr.attr, &sensor_dev_attr_pwm1_enable.dev_attr.attr, @@ -533,7 +546,9 @@ static int __devinit smsc47m1_probe(struct platform_device *pdev) || (err = device_create_file(dev, &sensor_dev_attr_fan1_min.dev_attr)) || (err = device_create_file(dev, - &sensor_dev_attr_fan1_div.dev_attr))) + &sensor_dev_attr_fan1_div.dev_attr)) + || (err = device_create_file(dev, + &sensor_dev_attr_fan1_alarm.dev_attr))) goto error_remove_files; } else dev_dbg(dev, "Fan 1 not enabled by hardware, skipping\n"); @@ -544,7 +559,9 @@ static int __devinit smsc47m1_probe(struct platform_device *pdev) || (err = device_create_file(dev, &sensor_dev_attr_fan2_min.dev_attr)) || (err = device_create_file(dev, - &sensor_dev_attr_fan2_div.dev_attr))) + &sensor_dev_attr_fan2_div.dev_attr)) + || (err = device_create_file(dev, + &sensor_dev_attr_fan2_alarm.dev_attr))) goto error_remove_files; } else dev_dbg(dev, "Fan 2 not enabled by hardware, skipping\n"); @@ -555,7 +572,9 @@ static int __devinit smsc47m1_probe(struct platform_device *pdev) || (err = device_create_file(dev, &sensor_dev_attr_fan3_min.dev_attr)) || (err = device_create_file(dev, - &sensor_dev_attr_fan3_div.dev_attr))) + &sensor_dev_attr_fan3_div.dev_attr)) + || (err = device_create_file(dev, + &sensor_dev_attr_fan3_alarm.dev_attr))) goto error_remove_files; } else if (data->type == smsc47m2) dev_dbg(dev, "Fan 3 not enabled by hardware, skipping\n"); -- cgit v1.2.2 From 13ff05e9f87101407445f79c7402aca087ddbd02 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sun, 6 Jan 2008 15:42:04 +0100 Subject: hwmon: (via686a) Add individual alarm files The new libsensors needs these individual alarm files. Signed-off-by: Jean Delvare Acked-by: Juerg Haefliger Signed-off-by: Mark M. Hoffman --- drivers/hwmon/via686a.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'drivers') diff --git a/drivers/hwmon/via686a.c b/drivers/hwmon/via686a.c index 2635bba1e3fc..f1ee5e731968 100644 --- a/drivers/hwmon/via686a.c +++ b/drivers/hwmon/via686a.c @@ -533,6 +533,24 @@ static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, ch } static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); +static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int bitnr = to_sensor_dev_attr(attr)->index; + struct via686a_data *data = via686a_update_device(dev); + return sprintf(buf, "%u\n", (data->alarms >> bitnr) & 1); +} +static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0); +static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1); +static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2); +static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 3); +static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 8); +static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4); +static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 11); +static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 15); +static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 6); +static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 7); + static ssize_t show_name(struct device *dev, struct device_attribute *devattr, char *buf) { @@ -557,6 +575,11 @@ static struct attribute *via686a_attributes[] = { &sensor_dev_attr_in2_max.dev_attr.attr, &sensor_dev_attr_in3_max.dev_attr.attr, &sensor_dev_attr_in4_max.dev_attr.attr, + &sensor_dev_attr_in0_alarm.dev_attr.attr, + &sensor_dev_attr_in1_alarm.dev_attr.attr, + &sensor_dev_attr_in2_alarm.dev_attr.attr, + &sensor_dev_attr_in3_alarm.dev_attr.attr, + &sensor_dev_attr_in4_alarm.dev_attr.attr, &sensor_dev_attr_temp1_input.dev_attr.attr, &sensor_dev_attr_temp2_input.dev_attr.attr, @@ -567,6 +590,9 @@ static struct attribute *via686a_attributes[] = { &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, &sensor_dev_attr_temp2_max_hyst.dev_attr.attr, &sensor_dev_attr_temp3_max_hyst.dev_attr.attr, + &sensor_dev_attr_temp1_alarm.dev_attr.attr, + &sensor_dev_attr_temp2_alarm.dev_attr.attr, + &sensor_dev_attr_temp3_alarm.dev_attr.attr, &sensor_dev_attr_fan1_input.dev_attr.attr, &sensor_dev_attr_fan2_input.dev_attr.attr, @@ -574,6 +600,8 @@ static struct attribute *via686a_attributes[] = { &sensor_dev_attr_fan2_min.dev_attr.attr, &sensor_dev_attr_fan1_div.dev_attr.attr, &sensor_dev_attr_fan2_div.dev_attr.attr, + &sensor_dev_attr_fan1_alarm.dev_attr.attr, + &sensor_dev_attr_fan2_alarm.dev_attr.attr, &dev_attr_alarms.attr, &dev_attr_name.attr, -- cgit v1.2.2 From 2d1374cad5a97d7c08a2c0e4282fb674b588b421 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sun, 6 Jan 2008 15:46:02 +0100 Subject: hwmon: (vt8231) Add individual alarm files The new libsensors needs these individual alarm files. Signed-off-by: Jean Delvare CC: Roger Lucas Acked-by: Juerg Haefliger Signed-off-by: Mark M. Hoffman --- drivers/hwmon/vt8231.c | 40 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/vt8231.c b/drivers/hwmon/vt8231.c index f87661775fe0..ed4b89857673 100644 --- a/drivers/hwmon/vt8231.c +++ b/drivers/hwmon/vt8231.c @@ -541,6 +541,28 @@ static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, } static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); +static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int bitnr = to_sensor_dev_attr(attr)->index; + struct vt8231_data *data = vt8231_update_device(dev); + return sprintf(buf, "%u\n", (data->alarms >> bitnr) & 1); +} +static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4); +static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 11); +static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 0); +static SENSOR_DEVICE_ATTR(temp4_alarm, S_IRUGO, show_alarm, NULL, 1); +static SENSOR_DEVICE_ATTR(temp5_alarm, S_IRUGO, show_alarm, NULL, 3); +static SENSOR_DEVICE_ATTR(temp6_alarm, S_IRUGO, show_alarm, NULL, 8); +static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 11); +static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 0); +static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 1); +static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 3); +static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 8); +static SENSOR_DEVICE_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 2); +static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 6); +static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 7); + static ssize_t show_name(struct device *dev, struct device_attribute *devattr, char *buf) { @@ -549,36 +571,42 @@ static ssize_t show_name(struct device *dev, struct device_attribute } static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); -static struct attribute *vt8231_attributes_temps[6][4] = { +static struct attribute *vt8231_attributes_temps[6][5] = { { &dev_attr_temp1_input.attr, &dev_attr_temp1_max_hyst.attr, &dev_attr_temp1_max.attr, + &sensor_dev_attr_temp1_alarm.dev_attr.attr, NULL }, { &sensor_dev_attr_temp2_input.dev_attr.attr, &sensor_dev_attr_temp2_max_hyst.dev_attr.attr, &sensor_dev_attr_temp2_max.dev_attr.attr, + &sensor_dev_attr_temp2_alarm.dev_attr.attr, NULL }, { &sensor_dev_attr_temp3_input.dev_attr.attr, &sensor_dev_attr_temp3_max_hyst.dev_attr.attr, &sensor_dev_attr_temp3_max.dev_attr.attr, + &sensor_dev_attr_temp3_alarm.dev_attr.attr, NULL }, { &sensor_dev_attr_temp4_input.dev_attr.attr, &sensor_dev_attr_temp4_max_hyst.dev_attr.attr, &sensor_dev_attr_temp4_max.dev_attr.attr, + &sensor_dev_attr_temp4_alarm.dev_attr.attr, NULL }, { &sensor_dev_attr_temp5_input.dev_attr.attr, &sensor_dev_attr_temp5_max_hyst.dev_attr.attr, &sensor_dev_attr_temp5_max.dev_attr.attr, + &sensor_dev_attr_temp5_alarm.dev_attr.attr, NULL }, { &sensor_dev_attr_temp6_input.dev_attr.attr, &sensor_dev_attr_temp6_max_hyst.dev_attr.attr, &sensor_dev_attr_temp6_max.dev_attr.attr, + &sensor_dev_attr_temp6_alarm.dev_attr.attr, NULL } }; @@ -592,36 +620,42 @@ static const struct attribute_group vt8231_group_temps[6] = { { .attrs = vt8231_attributes_temps[5] }, }; -static struct attribute *vt8231_attributes_volts[6][4] = { +static struct attribute *vt8231_attributes_volts[6][5] = { { &sensor_dev_attr_in0_input.dev_attr.attr, &sensor_dev_attr_in0_min.dev_attr.attr, &sensor_dev_attr_in0_max.dev_attr.attr, + &sensor_dev_attr_in0_alarm.dev_attr.attr, NULL }, { &sensor_dev_attr_in1_input.dev_attr.attr, &sensor_dev_attr_in1_min.dev_attr.attr, &sensor_dev_attr_in1_max.dev_attr.attr, + &sensor_dev_attr_in1_alarm.dev_attr.attr, NULL }, { &sensor_dev_attr_in2_input.dev_attr.attr, &sensor_dev_attr_in2_min.dev_attr.attr, &sensor_dev_attr_in2_max.dev_attr.attr, + &sensor_dev_attr_in2_alarm.dev_attr.attr, NULL }, { &sensor_dev_attr_in3_input.dev_attr.attr, &sensor_dev_attr_in3_min.dev_attr.attr, &sensor_dev_attr_in3_max.dev_attr.attr, + &sensor_dev_attr_in3_alarm.dev_attr.attr, NULL }, { &sensor_dev_attr_in4_input.dev_attr.attr, &sensor_dev_attr_in4_min.dev_attr.attr, &sensor_dev_attr_in4_max.dev_attr.attr, + &sensor_dev_attr_in4_alarm.dev_attr.attr, NULL }, { &dev_attr_in5_input.attr, &dev_attr_in5_min.attr, &dev_attr_in5_max.attr, + &sensor_dev_attr_in5_alarm.dev_attr.attr, NULL } }; @@ -642,6 +676,8 @@ static struct attribute *vt8231_attributes[] = { &sensor_dev_attr_fan2_min.dev_attr.attr, &sensor_dev_attr_fan1_div.dev_attr.attr, &sensor_dev_attr_fan2_div.dev_attr.attr, + &sensor_dev_attr_fan1_alarm.dev_attr.attr, + &sensor_dev_attr_fan2_alarm.dev_attr.attr, &dev_attr_alarms.attr, &dev_attr_name.attr, NULL -- cgit v1.2.2 From af865765a9ee3e3510f0fe82a4f1308d2820b7f6 Mon Sep 17 00:00:00 2001 From: Roger Lucas Date: Wed, 13 Feb 2008 07:52:06 -0500 Subject: hwmon: (vt8231) Update maintainer email address Signed-off-by: Roger Lucas (modified MAINTAINERS entry also - MMH) Signed-off-by: Mark M. Hoffman --- drivers/hwmon/vt8231.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/vt8231.c b/drivers/hwmon/vt8231.c index ed4b89857673..5bc57275cae8 100644 --- a/drivers/hwmon/vt8231.c +++ b/drivers/hwmon/vt8231.c @@ -2,7 +2,7 @@ vt8231.c - Part of lm_sensors, Linux kernel modules for hardware monitoring - Copyright (c) 2005 Roger Lucas + Copyright (c) 2005 Roger Lucas Copyright (c) 2002 Mark D. Studebaker Aaron M. Marsh @@ -999,7 +999,7 @@ static void __exit sm_vt8231_exit(void) } } -MODULE_AUTHOR("Roger Lucas "); +MODULE_AUTHOR("Roger Lucas "); MODULE_DESCRIPTION("VT8231 sensors"); MODULE_LICENSE("GPL"); -- cgit v1.2.2 From 1d5f2c16c6125ae6da1435ac5a190ae08429902a Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sun, 10 Feb 2008 19:01:15 +0100 Subject: hwmon: (adm1026) Properly terminate sysfs groups The missing NULL at the end of two sysfs file groups causes a kernel crash when calling sysfs_create_group(). Signed-off-by: Jean Delvare Signed-off-by: Mark M. Hoffman --- drivers/hwmon/adm1026.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/hwmon/adm1026.c b/drivers/hwmon/adm1026.c index 8002f68240c4..b3e6b06caf61 100644 --- a/drivers/hwmon/adm1026.c +++ b/drivers/hwmon/adm1026.c @@ -1624,6 +1624,7 @@ static struct attribute *adm1026_attributes_temp3[] = { &dev_attr_temp3_crit_enable.attr, &dev_attr_temp3_auto_point1_pwm.attr, &dev_attr_temp3_auto_point2_pwm.attr, + NULL }; static const struct attribute_group adm1026_group_temp3 = { @@ -1639,6 +1640,7 @@ static struct attribute *adm1026_attributes_in8_9[] = { &sensor_dev_attr_in9_max.dev_attr.attr, &sensor_dev_attr_in9_min.dev_attr.attr, &sensor_dev_attr_in9_alarm.dev_attr.attr, + NULL }; static const struct attribute_group adm1026_group_in8_9 = { -- cgit v1.2.2 From 6369a2887a1b35fde91573adc650528e3efea8e9 Mon Sep 17 00:00:00 2001 From: Rudolf Marek Date: Fri, 18 Jan 2008 00:42:54 +0100 Subject: hwmon: (coretemp) Add maximum cooling temperature readout Following patch will add reporting of maximum temperature, at which all fans should spin full speed. It may be non-physical temperature on Desktop/Server CPUs. Signed-off-by: Rudolf Marek Acked-by: Jean Delvare Signed-off-by: Mark M. Hoffman --- drivers/hwmon/coretemp.c | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index 3ee60d26e3a2..52914e95e9dc 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c @@ -38,7 +38,8 @@ #define DRVNAME "coretemp" -typedef enum { SHOW_TEMP, SHOW_TJMAX, SHOW_LABEL, SHOW_NAME } SHOW; +typedef enum { SHOW_TEMP, SHOW_TJMAX, SHOW_TTARGET, SHOW_LABEL, + SHOW_NAME } SHOW; /* * Functions declaration @@ -55,6 +56,7 @@ struct coretemp_data { unsigned long last_updated; /* in jiffies */ int temp; int tjmax; + int ttarget; u8 alarm; }; @@ -93,9 +95,10 @@ static ssize_t show_temp(struct device *dev, if (attr->index == SHOW_TEMP) err = data->valid ? sprintf(buf, "%d\n", data->temp) : -EAGAIN; - else + else if (attr->index == SHOW_TJMAX) err = sprintf(buf, "%d\n", data->tjmax); - + else + err = sprintf(buf, "%d\n", data->ttarget); return err; } @@ -103,6 +106,8 @@ static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, SHOW_TEMP); static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, show_temp, NULL, SHOW_TJMAX); +static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO, show_temp, NULL, + SHOW_TTARGET); static DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL); static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, show_name, NULL, SHOW_LABEL); static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, SHOW_NAME); @@ -223,8 +228,26 @@ static int __devinit coretemp_probe(struct platform_device *pdev) platform_set_drvdata(pdev, data); + /* read the still undocumented IA32_TEMPERATURE_TARGET it exists + on older CPUs but not in this register */ + + if (c->x86_model > 0xe) { + err = rdmsr_safe_on_cpu(data->id, 0x1a2, &eax, &edx); + if (err) { + dev_warn(&pdev->dev, "Unable to read" + " IA32_TEMPERATURE_TARGET MSR\n"); + } else { + data->ttarget = data->tjmax - + (((eax >> 8) & 0xff) * 1000); + err = device_create_file(&pdev->dev, + &sensor_dev_attr_temp1_max.dev_attr); + if (err) + goto exit_free; + } + } + if ((err = sysfs_create_group(&pdev->dev.kobj, &coretemp_group))) - goto exit_free; + goto exit_dev; data->hwmon_dev = hwmon_device_register(&pdev->dev); if (IS_ERR(data->hwmon_dev)) { @@ -238,6 +261,8 @@ static int __devinit coretemp_probe(struct platform_device *pdev) exit_class: sysfs_remove_group(&pdev->dev.kobj, &coretemp_group); +exit_dev: + device_remove_file(&pdev->dev, &sensor_dev_attr_temp1_max.dev_attr); exit_free: kfree(data); exit: @@ -250,6 +275,7 @@ static int __devexit coretemp_remove(struct platform_device *pdev) hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&pdev->dev.kobj, &coretemp_group); + device_remove_file(&pdev->dev, &sensor_dev_attr_temp1_max.dev_attr); platform_set_drvdata(pdev, NULL); kfree(data); return 0; -- cgit v1.2.2 From ba7c1927aa69c4dfe1ecf646f03b306e49dc8e37 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sun, 17 Feb 2008 13:22:51 +0100 Subject: hwmon: (coretemp) fix section mismatch warning Fix following warning: WARNING: vmlinux.o(.text+0xebfd04): Section mismatch in reference from the function coretemp_cpu_callback() to the function .cpuinit.text:coretemp_device_add() coretemp_cpu_callback() are only used inside a HOTPLUG_CPU block so annotate it __cpuinit. The notifier referencing the function are annotated __refdata to silence warning from the exit function. The unregister function do not use the embedded pointer but clears the variable so the annotation is OK. Signed-off-by: Sam Ravnborg Signed-off-by: Mark M. Hoffman --- drivers/hwmon/coretemp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index 52914e95e9dc..cbd047eac5b4 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c @@ -356,7 +356,7 @@ static void coretemp_device_remove(unsigned int cpu) mutex_unlock(&pdev_list_mutex); } -static int coretemp_cpu_callback(struct notifier_block *nfb, +static int __cpuinit coretemp_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { unsigned int cpu = (unsigned long) hcpu; @@ -373,7 +373,7 @@ static int coretemp_cpu_callback(struct notifier_block *nfb, return NOTIFY_OK; } -static struct notifier_block coretemp_cpu_notifier = { +static struct notifier_block coretemp_cpu_notifier __refdata = { .notifier_call = coretemp_cpu_callback, }; #endif /* !CONFIG_HOTPLUG_CPU */ -- cgit v1.2.2 From 5910a9b2b1ff6205b39e5e03fdfd0ddb2a78386a Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Sun, 17 Feb 2008 15:39:24 +0100 Subject: hwmon: (thmc50) Storage class should be before const qualifier The C99 specification states in section 6.11.5: The placement of a storage-class specifier other than at the beginning of the declaration specifiers in a declaration is an obsolescent feature. Signed-off-by: Tobias Klauser Signed-off-by: Mark M. Hoffman --- drivers/hwmon/thmc50.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/thmc50.c b/drivers/hwmon/thmc50.c index 04dd7699b3ac..a42a03c24367 100644 --- a/drivers/hwmon/thmc50.c +++ b/drivers/hwmon/thmc50.c @@ -52,9 +52,9 @@ I2C_CLIENT_MODULE_PARM(adm1022_temp3, "List of adapter,address pairs " */ #define THMC50_REG_INTR 0x41 -const static u8 THMC50_REG_TEMP[] = { 0x27, 0x26, 0x20 }; -const static u8 THMC50_REG_TEMP_MIN[] = { 0x3A, 0x38, 0x2C }; -const static u8 THMC50_REG_TEMP_MAX[] = { 0x39, 0x37, 0x2B }; +static const u8 THMC50_REG_TEMP[] = { 0x27, 0x26, 0x20 }; +static const u8 THMC50_REG_TEMP_MIN[] = { 0x3A, 0x38, 0x2C }; +static const u8 THMC50_REG_TEMP_MAX[] = { 0x39, 0x37, 0x2B }; #define THMC50_REG_CONF_nFANOFF 0x20 -- cgit v1.2.2 From cd19ba1391f93bc3741d298667c074d2d3fcc9fd Mon Sep 17 00:00:00 2001 From: Riki Oktarianto Date: Mon, 4 Feb 2008 23:41:58 -0800 Subject: hwmon: (applesmc) sensors set for MacBook2 On my mid-2007 MacBook2, reading Ts0P sensor always failed with this message: applesmc: wait status failed: 5 != 50. So I assume that there's no such Ts0p sensor in this model (please confirm, anyone). If there's the case, then we need a new set of sensors defined for MacBook2. Signed-off-by: Riki Oktarianto Cc: Nicolas Boichat Signed-off-by: Andrew Morton Signed-off-by: Mark M. Hoffman --- drivers/hwmon/applesmc.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c index 0c94770b7f83..aacc0c4b809c 100644 --- a/drivers/hwmon/applesmc.c +++ b/drivers/hwmon/applesmc.c @@ -84,12 +84,15 @@ static const char* temperature_sensors_sets[][36] = { /* Set 0: Macbook Pro */ { "TA0P", "TB0T", "TC0D", "TC0P", "TG0H", "TG0P", "TG0T", "Th0H", "Th1H", "Tm0P", "Ts0P", "Ts1P", NULL }, -/* Set 1: Macbook set */ +/* Set 1: Macbook2 set */ + { "TB0T", "TC0D", "TC0P", "TM0P", "TN0P", "TN1P", "TTF0", "Th0H", + "Th0S", "Th1H", NULL }, +/* Set 2: Macbook set */ { "TB0T", "TC0D", "TC0P", "TM0P", "TN0P", "TN1P", "Th0H", "Th0S", "Th1H", "Ts0P", NULL }, -/* Set 2: Macmini set */ +/* Set 3: Macmini set */ { "TC0D", "TC0P", NULL }, -/* Set 3: Mac Pro (2 x Quad-Core) */ +/* Set 4: Mac Pro (2 x Quad-Core) */ { "TA0P", "TCAG", "TCAH", "TCBG", "TCBH", "TC0C", "TC0D", "TC0P", "TC1C", "TC1D", "TC2C", "TC2D", "TC3C", "TC3D", "THTG", "TH0P", "TH1P", "TH2P", "TH3P", "TMAP", "TMAS", "TMBS", "TM0P", "TM0S", @@ -1212,12 +1215,14 @@ static void applesmc_release_accelerometer(void) static __initdata struct dmi_match_data applesmc_dmi_data[] = { /* MacBook Pro: accelerometer, backlight and temperature set 0 */ { .accelerometer = 1, .light = 1, .temperature_set = 0 }, -/* MacBook: accelerometer and temperature set 1 */ +/* MacBook2: accelerometer and temperature set 1 */ { .accelerometer = 1, .light = 0, .temperature_set = 1 }, -/* MacMini: temperature set 2 */ - { .accelerometer = 0, .light = 0, .temperature_set = 2 }, -/* MacPro: temperature set 3 */ +/* MacBook: accelerometer and temperature set 2 */ + { .accelerometer = 1, .light = 0, .temperature_set = 2 }, +/* MacMini: temperature set 3 */ { .accelerometer = 0, .light = 0, .temperature_set = 3 }, +/* MacPro: temperature set 4 */ + { .accelerometer = 0, .light = 0, .temperature_set = 4 }, }; /* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1". @@ -1229,16 +1234,20 @@ static __initdata struct dmi_system_id applesmc_whitelist[] = { (void*)&applesmc_dmi_data[0]}, { applesmc_dmi_match, "Apple MacBook", { DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), - DMI_MATCH(DMI_PRODUCT_NAME,"MacBook") }, + DMI_MATCH(DMI_PRODUCT_NAME,"MacBook2") }, (void*)&applesmc_dmi_data[1]}, + { applesmc_dmi_match, "Apple MacBook", { + DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), + DMI_MATCH(DMI_PRODUCT_NAME,"MacBook") }, + (void*)&applesmc_dmi_data[2]}, { applesmc_dmi_match, "Apple Macmini", { DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), DMI_MATCH(DMI_PRODUCT_NAME,"Macmini") }, - (void*)&applesmc_dmi_data[2]}, + (void*)&applesmc_dmi_data[3]}, { applesmc_dmi_match, "Apple MacPro2", { DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), DMI_MATCH(DMI_PRODUCT_NAME,"MacPro2") }, - (void*)&applesmc_dmi_data[3]}, + (void*)&applesmc_dmi_data[4]}, { .ident = NULL } }; -- cgit v1.2.2 From 118a88718886a6cb7fb2cf7fb77ef2eea30c73a1 Mon Sep 17 00:00:00 2001 From: Rudolf Marek Date: Sun, 17 Feb 2008 22:59:39 +0100 Subject: hwmon: (coretemp) Add TjMax detection for mobile CPUs Following patch will finally solve the detection of Intel Mobile CPUs which share same CPUID with Desktop/Server CPUs. We need this information to test some bit so we know if TjMax is 100C or 85C. Intel claims this works for mobiles only, respect that and set for desktops the TjMax to 100C. Intel provided some table on their wiki based on my chat with them at: http://softwarecommunity.intel.com/isn/Community/en-US/forums/30247249/ShowThread.aspx#30247249 Signed-off-by: Rudolf Marek Signed-off-by: Mark M. Hoffman --- drivers/hwmon/coretemp.c | 83 +++++++++++++++++++++++++++++------------------- 1 file changed, 51 insertions(+), 32 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index cbd047eac5b4..1f34ad84c557 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c @@ -152,6 +152,56 @@ static struct coretemp_data *coretemp_update_device(struct device *dev) return data; } +static int __devinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *dev) +{ + /* The 100C is default for both mobile and non mobile CPUs */ + + int tjmax = 100000; + int ismobile = 1; + int err; + u32 eax, edx; + + /* Early chips have no MSR for TjMax */ + + if ((c->x86_model == 0xf) && (c->x86_mask < 4)) { + ismobile = 0; + } + + if ((c->x86_model > 0xe) && (ismobile)) { + + /* Now we can detect the mobile CPU using Intel provided table + http://softwarecommunity.intel.com/Wiki/Mobility/720.htm + For Core2 cores, check MSR 0x17, bit 28 1 = Mobile CPU + */ + + err = rdmsr_safe_on_cpu(id, 0x17, &eax, &edx); + if (err) { + dev_warn(dev, + "Unable to access MSR 0x17, assuming desktop" + " CPU\n"); + ismobile = 0; + } else if (!(eax & 0x10000000)) { + ismobile = 0; + } + } + + if (ismobile) { + + err = rdmsr_safe_on_cpu(id, 0xee, &eax, &edx); + if (err) { + dev_warn(dev, + "Unable to access MSR 0xEE, for Tjmax, left" + " at default"); + } else if (eax & 0x40000000) { + tjmax = 85000; + } + } else { + dev_warn(dev, "Using relative temperature scale!\n"); + } + + return tjmax; +} + static int __devinit coretemp_probe(struct platform_device *pdev) { struct coretemp_data *data; @@ -168,8 +218,6 @@ static int __devinit coretemp_probe(struct platform_device *pdev) data->id = pdev->id; data->name = "coretemp"; mutex_init(&data->update_lock); - /* Tjmax default is 100 degrees C */ - data->tjmax = 100000; /* test if we can access the THERM_STATUS MSR */ err = rdmsr_safe_on_cpu(data->id, MSR_IA32_THERM_STATUS, &eax, &edx); @@ -196,36 +244,7 @@ static int __devinit coretemp_probe(struct platform_device *pdev) } } - /* Some processors have Tjmax 85 following magic should detect it - Intel won't disclose the information without signed NDA, but - individuals cannot sign it. Catch(ed) 22. - */ - - if (((c->x86_model == 0xf) && (c->x86_mask > 3)) || - (c->x86_model == 0xe)) { - err = rdmsr_safe_on_cpu(data->id, 0xee, &eax, &edx); - if (err) { - dev_warn(&pdev->dev, - "Unable to access MSR 0xEE, Tjmax left at %d " - "degrees C\n", data->tjmax/1000); - } else if (eax & 0x40000000) { - data->tjmax = 85000; - } - } - - /* Intel says that above should not work for desktop Core2 processors, - but it seems to work. There is no other way how get the absolute - readings. Warn the user about this. First check if are desktop, - bit 50 of MSR_IA32_PLATFORM_ID should be 0. - */ - - rdmsr_safe_on_cpu(data->id, MSR_IA32_PLATFORM_ID, &eax, &edx); - - if ((c->x86_model == 0xf) && (!(edx & 0x00040000))) { - dev_warn(&pdev->dev, "Using undocumented features, absolute " - "temperature might be wrong!\n"); - } - + data->tjmax = adjust_tjmax(c, data->id, &pdev->dev); platform_set_drvdata(pdev, data); /* read the still undocumented IA32_TEMPERATURE_TARGET it exists -- cgit v1.2.2 From ae770152c801f10a91e5e86597a39b5f9ccf2d0d Mon Sep 17 00:00:00 2001 From: Rudolf Marek Date: Fri, 18 Jan 2008 00:50:04 +0100 Subject: hwmon: (coretemp) Add Penryn CPU to coretemp This patch adds support for family 0x17, which has Penryn Core. It should also cover the 8 cores Xeons. Can someone test please? I think it should work. Signed-off-by: Rudolf Marek Acked-by: Jean Delvare Signed-off-by: Mark M. Hoffman --- drivers/hwmon/coretemp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index 1f34ad84c557..70239acecc8e 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c @@ -413,10 +413,10 @@ static int __init coretemp_init(void) for_each_online_cpu(i) { struct cpuinfo_x86 *c = &cpu_data(i); - /* check if family 6, models e, f, 16 */ + /* check if family 6, models 0xe, 0xf, 0x16, 0x17 */ if ((c->cpuid_level < 0) || (c->x86 != 0x6) || !((c->x86_model == 0xe) || (c->x86_model == 0xf) || - (c->x86_model == 0x16))) { + (c->x86_model == 0x16) || (c->x86_model == 0x17))) { /* supported CPU not found, but report the unknown family 6 CPU */ -- cgit v1.2.2 From 57df46d6d9ccd6ced95f169020f79ae637423087 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Mon, 18 Feb 2008 13:33:23 -0800 Subject: hwmon: New driver for Analog Devices ADT7473 sensor chip This driver reports voltage, temperature and fan sensor readings on an ADT7473 chip. Signed-off-by: Darrick J. Wong Signed-off-by: Mark M. Hoffman --- drivers/hwmon/Kconfig | 10 + drivers/hwmon/Makefile | 1 + drivers/hwmon/adt7473.c | 1157 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1168 insertions(+) create mode 100644 drivers/hwmon/adt7473.c (limited to 'drivers') diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 410ffe4e9d80..368879ff5d8c 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -143,6 +143,16 @@ config SENSORS_ADT7470 This driver can also be built as a module. If so, the module will be called adt7470. +config SENSORS_ADT7473 + tristate "Analog Devices ADT7473" + depends on I2C && EXPERIMENTAL + help + If you say yes here you get support for the Analog Devices + ADT7473 temperature monitoring chips. + + This driver can also be built as a module. If so, the module + will be called adt7473. + config SENSORS_K8TEMP tristate "AMD Athlon64/FX or Opteron temperature sensor" depends on X86 && PCI && EXPERIMENTAL diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 824161337f1c..3bdb05a5cbd7 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile @@ -24,6 +24,7 @@ obj-$(CONFIG_SENSORS_ADM1031) += adm1031.o obj-$(CONFIG_SENSORS_ADM9240) += adm9240.o obj-$(CONFIG_SENSORS_ADS7828) += ads7828.o obj-$(CONFIG_SENSORS_ADT7470) += adt7470.o +obj-$(CONFIG_SENSORS_ADT7473) += adt7473.o obj-$(CONFIG_SENSORS_APPLESMC) += applesmc.o obj-$(CONFIG_SENSORS_AMS) += ams/ obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o diff --git a/drivers/hwmon/adt7473.c b/drivers/hwmon/adt7473.c new file mode 100644 index 000000000000..a3daeefff472 --- /dev/null +++ b/drivers/hwmon/adt7473.c @@ -0,0 +1,1157 @@ +/* + * A hwmon driver for the Analog Devices ADT7473 + * Copyright (C) 2007 IBM + * + * Author: Darrick J. Wong + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Addresses to scan */ +static unsigned short normal_i2c[] = { 0x2C, 0x2D, 0x2E, I2C_CLIENT_END }; + +/* Insmod parameters */ +I2C_CLIENT_INSMOD_1(adt7473); + +/* ADT7473 registers */ +#define ADT7473_REG_BASE_ADDR 0x20 + +#define ADT7473_REG_VOLT_BASE_ADDR 0x21 +#define ADT7473_REG_VOLT_MAX_ADDR 0x22 +#define ADT7473_REG_VOLT_MIN_BASE_ADDR 0x46 +#define ADT7473_REG_VOLT_MIN_MAX_ADDR 0x49 + +#define ADT7473_REG_TEMP_BASE_ADDR 0x25 +#define ADT7473_REG_TEMP_MAX_ADDR 0x27 +#define ADT7473_REG_TEMP_LIMITS_BASE_ADDR 0x4E +#define ADT7473_REG_TEMP_LIMITS_MAX_ADDR 0x53 +#define ADT7473_REG_TEMP_TMIN_BASE_ADDR 0x67 +#define ADT7473_REG_TEMP_TMIN_MAX_ADDR 0x69 +#define ADT7473_REG_TEMP_TMAX_BASE_ADDR 0x6A +#define ADT7473_REG_TEMP_TMAX_MAX_ADDR 0x6C + +#define ADT7473_REG_FAN_BASE_ADDR 0x28 +#define ADT7473_REG_FAN_MAX_ADDR 0x2F +#define ADT7473_REG_FAN_MIN_BASE_ADDR 0x54 +#define ADT7473_REG_FAN_MIN_MAX_ADDR 0x5B + +#define ADT7473_REG_PWM_BASE_ADDR 0x30 +#define ADT7473_REG_PWM_MAX_ADDR 0x32 +#define ADT7473_REG_PWM_MIN_BASE_ADDR 0x64 +#define ADT7473_REG_PWM_MIN_MAX_ADDR 0x66 +#define ADT7473_REG_PWM_MAX_BASE_ADDR 0x38 +#define ADT7473_REG_PWM_MAX_MAX_ADDR 0x3A +#define ADT7473_REG_PWM_BHVR_BASE_ADDR 0x5C +#define ADT7473_REG_PWM_BHVR_MAX_ADDR 0x5E +#define ADT7473_PWM_BHVR_MASK 0xE0 +#define ADT7473_PWM_BHVR_SHIFT 5 + +#define ADT7473_REG_CFG1 0x40 +#define ADT7473_CFG1_START 0x01 +#define ADT7473_CFG1_READY 0x04 +#define ADT7473_REG_CFG2 0x73 +#define ADT7473_REG_CFG3 0x78 +#define ADT7473_REG_CFG4 0x7D +#define ADT7473_CFG4_MAX_DUTY_AT_OVT 0x08 +#define ADT7473_REG_CFG5 0x7C +#define ADT7473_CFG5_TEMP_TWOS 0x01 +#define ADT7473_CFG5_TEMP_OFFSET 0x02 + +#define ADT7473_REG_DEVICE 0x3D +#define ADT7473_VENDOR 0x41 +#define ADT7473_REG_VENDOR 0x3E +#define ADT7473_DEVICE 0x73 +#define ADT7473_REG_REVISION 0x3F +#define ADT7473_REV_68 0x68 +#define ADT7473_REV_69 0x69 + +#define ADT7473_REG_ALARM1 0x41 +#define ADT7473_VCCP_ALARM 0x02 +#define ADT7473_VCC_ALARM 0x04 +#define ADT7473_R1T_ALARM 0x10 +#define ADT7473_LT_ALARM 0x20 +#define ADT7473_R2T_ALARM 0x40 +#define ADT7473_OOL 0x80 +#define ADT7473_REG_ALARM2 0x42 +#define ADT7473_OVT_ALARM 0x02 +#define ADT7473_FAN1_ALARM 0x04 +#define ADT7473_FAN2_ALARM 0x08 +#define ADT7473_FAN3_ALARM 0x10 +#define ADT7473_FAN4_ALARM 0x20 +#define ADT7473_R1T_SHORT 0x40 +#define ADT7473_R2T_SHORT 0x80 +#define ADT7473_REG_MAX_ADDR 0x80 + +#define ALARM2(x) ((x) << 8) + +#define ADT7473_VOLT_COUNT 2 +#define ADT7473_REG_VOLT(x) (ADT7473_REG_VOLT_BASE_ADDR + (x)) +#define ADT7473_REG_VOLT_MIN(x) (ADT7473_REG_VOLT_MIN_BASE_ADDR + ((x) * 2)) +#define ADT7473_REG_VOLT_MAX(x) (ADT7473_REG_VOLT_MIN_BASE_ADDR + \ + ((x) * 2) + 1) + +#define ADT7473_TEMP_COUNT 3 +#define ADT7473_REG_TEMP(x) (ADT7473_REG_TEMP_BASE_ADDR + (x)) +#define ADT7473_REG_TEMP_MIN(x) (ADT7473_REG_TEMP_LIMITS_BASE_ADDR + ((x) * 2)) +#define ADT7473_REG_TEMP_MAX(x) (ADT7473_REG_TEMP_LIMITS_BASE_ADDR + \ + ((x) * 2) + 1) +#define ADT7473_REG_TEMP_TMIN(x) (ADT7473_REG_TEMP_TMIN_BASE_ADDR + (x)) +#define ADT7473_REG_TEMP_TMAX(x) (ADT7473_REG_TEMP_TMAX_BASE_ADDR + (x)) + +#define ADT7473_FAN_COUNT 4 +#define ADT7473_REG_FAN(x) (ADT7473_REG_FAN_BASE_ADDR + ((x) * 2)) +#define ADT7473_REG_FAN_MIN(x) (ADT7473_REG_FAN_MIN_BASE_ADDR + ((x) * 2)) + +#define ADT7473_PWM_COUNT 3 +#define ADT7473_REG_PWM(x) (ADT7473_REG_PWM_BASE_ADDR + (x)) +#define ADT7473_REG_PWM_MAX(x) (ADT7473_REG_PWM_MAX_BASE_ADDR + (x)) +#define ADT7473_REG_PWM_MIN(x) (ADT7473_REG_PWM_MIN_BASE_ADDR + (x)) +#define ADT7473_REG_PWM_BHVR(x) (ADT7473_REG_PWM_BHVR_BASE_ADDR + (x)) + +/* How often do we reread sensors values? (In jiffies) */ +#define SENSOR_REFRESH_INTERVAL (2 * HZ) + +/* How often do we reread sensor limit values? (In jiffies) */ +#define LIMIT_REFRESH_INTERVAL (60 * HZ) + +/* datasheet says to divide this number by the fan reading to get fan rpm */ +#define FAN_PERIOD_TO_RPM(x) ((90000 * 60) / (x)) +#define FAN_RPM_TO_PERIOD FAN_PERIOD_TO_RPM +#define FAN_PERIOD_INVALID 65535 +#define FAN_DATA_VALID(x) ((x) && (x) != FAN_PERIOD_INVALID) + +struct adt7473_data { + struct i2c_client client; + struct device *hwmon_dev; + struct attribute_group attrs; + struct mutex lock; + char sensors_valid; + char limits_valid; + unsigned long sensors_last_updated; /* In jiffies */ + unsigned long limits_last_updated; /* In jiffies */ + + u8 volt[ADT7473_VOLT_COUNT]; + s8 volt_min[ADT7473_VOLT_COUNT]; + s8 volt_max[ADT7473_VOLT_COUNT]; + + s8 temp[ADT7473_TEMP_COUNT]; + s8 temp_min[ADT7473_TEMP_COUNT]; + s8 temp_max[ADT7473_TEMP_COUNT]; + s8 temp_tmin[ADT7473_TEMP_COUNT]; + /* This is called the !THERM limit in the datasheet */ + s8 temp_tmax[ADT7473_TEMP_COUNT]; + + u16 fan[ADT7473_FAN_COUNT]; + u16 fan_min[ADT7473_FAN_COUNT]; + + u8 pwm[ADT7473_PWM_COUNT]; + u8 pwm_max[ADT7473_PWM_COUNT]; + u8 pwm_min[ADT7473_PWM_COUNT]; + u8 pwm_behavior[ADT7473_PWM_COUNT]; + + u8 temp_twos_complement; + u8 temp_offset; + + u16 alarm; + u8 max_duty_at_overheat; +}; + +static int adt7473_attach_adapter(struct i2c_adapter *adapter); +static int adt7473_detect(struct i2c_adapter *adapter, int address, int kind); +static int adt7473_detach_client(struct i2c_client *client); + +static struct i2c_driver adt7473_driver = { + .driver = { + .name = "adt7473", + }, + .attach_adapter = adt7473_attach_adapter, + .detach_client = adt7473_detach_client, +}; + +/* + * 16-bit registers on the ADT7473 are low-byte first. The data sheet says + * that the low byte must be read before the high byte. + */ +static inline int adt7473_read_word_data(struct i2c_client *client, u8 reg) +{ + u16 foo; + foo = i2c_smbus_read_byte_data(client, reg); + foo |= ((u16)i2c_smbus_read_byte_data(client, reg + 1) << 8); + return foo; +} + +static inline int adt7473_write_word_data(struct i2c_client *client, u8 reg, + u16 value) +{ + return i2c_smbus_write_byte_data(client, reg, value & 0xFF) + && i2c_smbus_write_byte_data(client, reg + 1, value >> 8); +} + +static void adt7473_init_client(struct i2c_client *client) +{ + int reg = i2c_smbus_read_byte_data(client, ADT7473_REG_CFG1); + + if (!(reg & ADT7473_CFG1_READY)) { + dev_err(&client->dev, "Chip not ready.\n"); + } else { + /* start monitoring */ + i2c_smbus_write_byte_data(client, ADT7473_REG_CFG1, + reg | ADT7473_CFG1_START); + } +} + +static struct adt7473_data *adt7473_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct adt7473_data *data = i2c_get_clientdata(client); + unsigned long local_jiffies = jiffies; + u8 cfg; + int i; + + mutex_lock(&data->lock); + if (time_before(local_jiffies, data->sensors_last_updated + + SENSOR_REFRESH_INTERVAL) + && data->sensors_valid) + goto no_sensor_update; + + for (i = 0; i < ADT7473_VOLT_COUNT; i++) + data->volt[i] = i2c_smbus_read_byte_data(client, + ADT7473_REG_VOLT(i)); + + /* Determine temperature encoding */ + cfg = i2c_smbus_read_byte_data(client, ADT7473_REG_CFG5); + data->temp_twos_complement = (cfg & ADT7473_CFG5_TEMP_TWOS); + + /* + * What does this do? it implies a variable temperature sensor + * offset, but the datasheet doesn't say anything about this bit + * and other parts of the datasheet imply that "offset64" mode + * means that you shift temp values by -64 if the above bit was set. + */ + data->temp_offset = (cfg & ADT7473_CFG5_TEMP_OFFSET); + + for (i = 0; i < ADT7473_TEMP_COUNT; i++) + data->temp[i] = i2c_smbus_read_byte_data(client, + ADT7473_REG_TEMP(i)); + + for (i = 0; i < ADT7473_FAN_COUNT; i++) + data->fan[i] = adt7473_read_word_data(client, + ADT7473_REG_FAN(i)); + + for (i = 0; i < ADT7473_PWM_COUNT; i++) + data->pwm[i] = i2c_smbus_read_byte_data(client, + ADT7473_REG_PWM(i)); + + data->alarm = i2c_smbus_read_byte_data(client, ADT7473_REG_ALARM1); + if (data->alarm & ADT7473_OOL) + data->alarm |= ALARM2(i2c_smbus_read_byte_data(client, + ADT7473_REG_ALARM2)); + + data->sensors_last_updated = local_jiffies; + data->sensors_valid = 1; + +no_sensor_update: + if (time_before(local_jiffies, data->limits_last_updated + + LIMIT_REFRESH_INTERVAL) + && data->limits_valid) + goto out; + + for (i = 0; i < ADT7473_VOLT_COUNT; i++) { + data->volt_min[i] = i2c_smbus_read_byte_data(client, + ADT7473_REG_VOLT_MIN(i)); + data->volt_max[i] = i2c_smbus_read_byte_data(client, + ADT7473_REG_VOLT_MAX(i)); + } + + for (i = 0; i < ADT7473_TEMP_COUNT; i++) { + data->temp_min[i] = i2c_smbus_read_byte_data(client, + ADT7473_REG_TEMP_MIN(i)); + data->temp_max[i] = i2c_smbus_read_byte_data(client, + ADT7473_REG_TEMP_MAX(i)); + data->temp_tmin[i] = i2c_smbus_read_byte_data(client, + ADT7473_REG_TEMP_TMIN(i)); + data->temp_tmax[i] = i2c_smbus_read_byte_data(client, + ADT7473_REG_TEMP_TMAX(i)); + } + + for (i = 0; i < ADT7473_FAN_COUNT; i++) + data->fan_min[i] = adt7473_read_word_data(client, + ADT7473_REG_FAN_MIN(i)); + + for (i = 0; i < ADT7473_PWM_COUNT; i++) { + data->pwm_max[i] = i2c_smbus_read_byte_data(client, + ADT7473_REG_PWM_MAX(i)); + data->pwm_min[i] = i2c_smbus_read_byte_data(client, + ADT7473_REG_PWM_MIN(i)); + data->pwm_behavior[i] = i2c_smbus_read_byte_data(client, + ADT7473_REG_PWM_BHVR(i)); + } + + data->limits_last_updated = local_jiffies; + data->limits_valid = 1; + +out: + mutex_unlock(&data->lock); + return data; +} + +/* + * On this chip, voltages are given as a count of steps between a minimum + * and maximum voltage, not a direct voltage. + */ +static const int volt_convert_table[][2] = { + {2997, 3}, + {4395, 4}, +}; + +static int decode_volt(int volt_index, u8 raw) +{ + int cmax = volt_convert_table[volt_index][0]; + int cmin = volt_convert_table[volt_index][1]; + return ((raw * (cmax - cmin)) / 255) + cmin; +} + +static u8 encode_volt(int volt_index, int cooked) +{ + int cmax = volt_convert_table[volt_index][0]; + int cmin = volt_convert_table[volt_index][1]; + u8 x; + + if (cooked > cmax) + cooked = cmax; + else if (cooked < cmin) + cooked = cmin; + + x = ((cooked - cmin) * 255) / (cmax - cmin); + + return x; +} + +static ssize_t show_volt_min(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct adt7473_data *data = adt7473_update_device(dev); + return sprintf(buf, "%d\n", + decode_volt(attr->index, data->volt_min[attr->index])); +} + +static ssize_t set_volt_min(struct device *dev, + struct device_attribute *devattr, + const char *buf, + size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct adt7473_data *data = i2c_get_clientdata(client); + int volt = encode_volt(attr->index, simple_strtol(buf, NULL, 10)); + + mutex_lock(&data->lock); + data->volt_min[attr->index] = volt; + i2c_smbus_write_byte_data(client, ADT7473_REG_VOLT_MIN(attr->index), + volt); + mutex_unlock(&data->lock); + + return count; +} + +static ssize_t show_volt_max(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct adt7473_data *data = adt7473_update_device(dev); + return sprintf(buf, "%d\n", + decode_volt(attr->index, data->volt_max[attr->index])); +} + +static ssize_t set_volt_max(struct device *dev, + struct device_attribute *devattr, + const char *buf, + size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct adt7473_data *data = i2c_get_clientdata(client); + int volt = encode_volt(attr->index, simple_strtol(buf, NULL, 10)); + + mutex_lock(&data->lock); + data->volt_max[attr->index] = volt; + i2c_smbus_write_byte_data(client, ADT7473_REG_VOLT_MAX(attr->index), + volt); + mutex_unlock(&data->lock); + + return count; +} + +static ssize_t show_volt(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct adt7473_data *data = adt7473_update_device(dev); + + return sprintf(buf, "%d\n", + decode_volt(attr->index, data->volt[attr->index])); +} + +/* + * This chip can report temperature data either as a two's complement + * number in the range -128 to 127, or as an unsigned number that must + * be offset by 64. + */ +static int decode_temp(struct adt7473_data *data, u8 raw) +{ + if (data->temp_twos_complement) + return (s8)raw; + return raw - 64; +} + +static u8 encode_temp(struct adt7473_data *data, int cooked) +{ + if (data->temp_twos_complement) + return (cooked & 0xFF); + return cooked + 64; +} + +static ssize_t show_temp_min(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct adt7473_data *data = adt7473_update_device(dev); + return sprintf(buf, "%d\n", + 1000 * decode_temp(data, data->temp_min[attr->index])); +} + +static ssize_t set_temp_min(struct device *dev, + struct device_attribute *devattr, + const char *buf, + size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct adt7473_data *data = i2c_get_clientdata(client); + int temp = simple_strtol(buf, NULL, 10) / 1000; + temp = encode_temp(data, temp); + + mutex_lock(&data->lock); + data->temp_min[attr->index] = temp; + i2c_smbus_write_byte_data(client, ADT7473_REG_TEMP_MIN(attr->index), + temp); + mutex_unlock(&data->lock); + + return count; +} + +static ssize_t show_temp_max(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct adt7473_data *data = adt7473_update_device(dev); + return sprintf(buf, "%d\n", + 1000 * decode_temp(data, data->temp_max[attr->index])); +} + +static ssize_t set_temp_max(struct device *dev, + struct device_attribute *devattr, + const char *buf, + size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct adt7473_data *data = i2c_get_clientdata(client); + int temp = simple_strtol(buf, NULL, 10) / 1000; + temp = encode_temp(data, temp); + + mutex_lock(&data->lock); + data->temp_max[attr->index] = temp; + i2c_smbus_write_byte_data(client, ADT7473_REG_TEMP_MAX(attr->index), + temp); + mutex_unlock(&data->lock); + + return count; +} + +static ssize_t show_temp(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct adt7473_data *data = adt7473_update_device(dev); + return sprintf(buf, "%d\n", + 1000 * decode_temp(data, data->temp[attr->index])); +} + +static ssize_t show_fan_min(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct adt7473_data *data = adt7473_update_device(dev); + + if (FAN_DATA_VALID(data->fan_min[attr->index])) + return sprintf(buf, "%d\n", + FAN_PERIOD_TO_RPM(data->fan_min[attr->index])); + else + return sprintf(buf, "0\n"); +} + +static ssize_t set_fan_min(struct device *dev, + struct device_attribute *devattr, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct adt7473_data *data = i2c_get_clientdata(client); + int temp = simple_strtol(buf, NULL, 10); + + if (!temp) + return -EINVAL; + temp = FAN_RPM_TO_PERIOD(temp); + + mutex_lock(&data->lock); + data->fan_min[attr->index] = temp; + adt7473_write_word_data(client, ADT7473_REG_FAN_MIN(attr->index), temp); + mutex_unlock(&data->lock); + + return count; +} + +static ssize_t show_fan(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct adt7473_data *data = adt7473_update_device(dev); + + if (FAN_DATA_VALID(data->fan[attr->index])) + return sprintf(buf, "%d\n", + FAN_PERIOD_TO_RPM(data->fan[attr->index])); + else + return sprintf(buf, "0\n"); +} + +static ssize_t show_max_duty_at_crit(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct adt7473_data *data = adt7473_update_device(dev); + return sprintf(buf, "%d\n", data->max_duty_at_overheat); +} + +static ssize_t set_max_duty_at_crit(struct device *dev, + struct device_attribute *devattr, + const char *buf, + size_t count) +{ + u8 reg; + struct i2c_client *client = to_i2c_client(dev); + struct adt7473_data *data = i2c_get_clientdata(client); + int temp = simple_strtol(buf, NULL, 10); + temp = temp && 0xFF; + + mutex_lock(&data->lock); + data->max_duty_at_overheat = temp; + reg = i2c_smbus_read_byte_data(client, ADT7473_REG_CFG4); + if (temp) + reg |= ADT7473_CFG4_MAX_DUTY_AT_OVT; + else + reg &= ~ADT7473_CFG4_MAX_DUTY_AT_OVT; + i2c_smbus_write_byte_data(client, ADT7473_REG_CFG4, reg); + mutex_unlock(&data->lock); + + return count; +} + +static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct adt7473_data *data = adt7473_update_device(dev); + return sprintf(buf, "%d\n", data->pwm[attr->index]); +} + +static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct adt7473_data *data = i2c_get_clientdata(client); + int temp = simple_strtol(buf, NULL, 10); + + mutex_lock(&data->lock); + data->pwm[attr->index] = temp; + i2c_smbus_write_byte_data(client, ADT7473_REG_PWM(attr->index), temp); + mutex_unlock(&data->lock); + + return count; +} + +static ssize_t show_pwm_max(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct adt7473_data *data = adt7473_update_device(dev); + return sprintf(buf, "%d\n", data->pwm_max[attr->index]); +} + +static ssize_t set_pwm_max(struct device *dev, + struct device_attribute *devattr, + const char *buf, + size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct adt7473_data *data = i2c_get_clientdata(client); + int temp = simple_strtol(buf, NULL, 10); + + mutex_lock(&data->lock); + data->pwm_max[attr->index] = temp; + i2c_smbus_write_byte_data(client, ADT7473_REG_PWM_MAX(attr->index), + temp); + mutex_unlock(&data->lock); + + return count; +} + +static ssize_t show_pwm_min(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct adt7473_data *data = adt7473_update_device(dev); + return sprintf(buf, "%d\n", data->pwm_min[attr->index]); +} + +static ssize_t set_pwm_min(struct device *dev, + struct device_attribute *devattr, + const char *buf, + size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct adt7473_data *data = i2c_get_clientdata(client); + int temp = simple_strtol(buf, NULL, 10); + + mutex_lock(&data->lock); + data->pwm_min[attr->index] = temp; + i2c_smbus_write_byte_data(client, ADT7473_REG_PWM_MIN(attr->index), + temp); + mutex_unlock(&data->lock); + + return count; +} + +static ssize_t show_temp_tmax(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct adt7473_data *data = adt7473_update_device(dev); + return sprintf(buf, "%d\n", + 1000 * decode_temp(data, data->temp_tmax[attr->index])); +} + +static ssize_t set_temp_tmax(struct device *dev, + struct device_attribute *devattr, + const char *buf, + size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct adt7473_data *data = i2c_get_clientdata(client); + int temp = simple_strtol(buf, NULL, 10) / 1000; + temp = encode_temp(data, temp); + + mutex_lock(&data->lock); + data->temp_tmax[attr->index] = temp; + i2c_smbus_write_byte_data(client, ADT7473_REG_TEMP_TMAX(attr->index), + temp); + mutex_unlock(&data->lock); + + return count; +} + +static ssize_t show_temp_tmin(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct adt7473_data *data = adt7473_update_device(dev); + return sprintf(buf, "%d\n", + 1000 * decode_temp(data, data->temp_tmin[attr->index])); +} + +static ssize_t set_temp_tmin(struct device *dev, + struct device_attribute *devattr, + const char *buf, + size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct adt7473_data *data = i2c_get_clientdata(client); + int temp = simple_strtol(buf, NULL, 10) / 1000; + temp = encode_temp(data, temp); + + mutex_lock(&data->lock); + data->temp_tmin[attr->index] = temp; + i2c_smbus_write_byte_data(client, ADT7473_REG_TEMP_TMIN(attr->index), + temp); + mutex_unlock(&data->lock); + + return count; +} + +static ssize_t show_pwm_enable(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct adt7473_data *data = adt7473_update_device(dev); + + switch (data->pwm_behavior[attr->index] >> ADT7473_PWM_BHVR_SHIFT) { + case 3: + return sprintf(buf, "0\n"); + case 7: + return sprintf(buf, "1\n"); + default: + return sprintf(buf, "2\n"); + } +} + +static ssize_t set_pwm_enable(struct device *dev, + struct device_attribute *devattr, + const char *buf, + size_t count) +{ + u8 reg; + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct adt7473_data *data = i2c_get_clientdata(client); + int temp = simple_strtol(buf, NULL, 10); + + switch (temp) { + case 0: + temp = 3; + break; + case 1: + temp = 7; + break; + case 2: + /* Enter automatic mode with fans off */ + temp = 4; + break; + default: + return -EINVAL; + } + + mutex_lock(&data->lock); + reg = i2c_smbus_read_byte_data(client, + ADT7473_REG_PWM_BHVR(attr->index)); + reg = (temp << ADT7473_PWM_BHVR_SHIFT) | + (reg & ~ADT7473_PWM_BHVR_MASK); + i2c_smbus_write_byte_data(client, ADT7473_REG_PWM_BHVR(attr->index), + reg); + data->pwm_behavior[attr->index] = reg; + mutex_unlock(&data->lock); + + return count; +} + +static ssize_t show_pwm_auto_temp(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct adt7473_data *data = adt7473_update_device(dev); + int bhvr = data->pwm_behavior[attr->index] >> ADT7473_PWM_BHVR_SHIFT; + + switch (bhvr) { + case 3: + case 4: + case 7: + return sprintf(buf, "0\n"); + case 0: + case 1: + case 5: + case 6: + return sprintf(buf, "%d\n", bhvr + 1); + case 2: + return sprintf(buf, "4\n"); + } + /* shouldn't ever get here */ + BUG(); +} + +static ssize_t set_pwm_auto_temp(struct device *dev, + struct device_attribute *devattr, + const char *buf, + size_t count) +{ + u8 reg; + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct i2c_client *client = to_i2c_client(dev); + struct adt7473_data *data = i2c_get_clientdata(client); + int temp = simple_strtol(buf, NULL, 10); + + switch (temp) { + case 1: + case 2: + case 6: + case 7: + temp--; + break; + case 0: + temp = 4; + break; + default: + return -EINVAL; + } + + mutex_lock(&data->lock); + reg = i2c_smbus_read_byte_data(client, + ADT7473_REG_PWM_BHVR(attr->index)); + reg = (temp << ADT7473_PWM_BHVR_SHIFT) | + (reg & ~ADT7473_PWM_BHVR_MASK); + i2c_smbus_write_byte_data(client, ADT7473_REG_PWM_BHVR(attr->index), + reg); + data->pwm_behavior[attr->index] = reg; + mutex_unlock(&data->lock); + + return count; +} + +static ssize_t show_alarm(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct adt7473_data *data = adt7473_update_device(dev); + + if (data->alarm & attr->index) + return sprintf(buf, "1\n"); + else + return sprintf(buf, "0\n"); +} + + +static SENSOR_DEVICE_ATTR(in1_max, S_IWUSR | S_IRUGO, show_volt_max, + set_volt_max, 0); +static SENSOR_DEVICE_ATTR(in2_max, S_IWUSR | S_IRUGO, show_volt_max, + set_volt_max, 1); + +static SENSOR_DEVICE_ATTR(in1_min, S_IWUSR | S_IRUGO, show_volt_min, + set_volt_min, 0); +static SENSOR_DEVICE_ATTR(in2_min, S_IWUSR | S_IRUGO, show_volt_min, + set_volt_min, 1); + +static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_volt, NULL, 0); +static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_volt, NULL, 1); + +static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, + ADT7473_VCCP_ALARM); +static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, + ADT7473_VCC_ALARM); + +static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max, + set_temp_max, 0); +static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp_max, + set_temp_max, 1); +static SENSOR_DEVICE_ATTR(temp3_max, S_IWUSR | S_IRUGO, show_temp_max, + set_temp_max, 2); + +static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp_min, + set_temp_min, 0); +static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp_min, + set_temp_min, 1); +static SENSOR_DEVICE_ATTR(temp3_min, S_IWUSR | S_IRUGO, show_temp_min, + set_temp_min, 2); + +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); +static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1); +static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 2); + +static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, + ADT7473_R1T_ALARM | ALARM2(ADT7473_R1T_SHORT)); +static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, + ADT7473_LT_ALARM); +static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, + ADT7473_R2T_ALARM | ALARM2(ADT7473_R2T_SHORT)); + +static SENSOR_DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan_min, + set_fan_min, 0); +static SENSOR_DEVICE_ATTR(fan2_min, S_IWUSR | S_IRUGO, show_fan_min, + set_fan_min, 1); +static SENSOR_DEVICE_ATTR(fan3_min, S_IWUSR | S_IRUGO, show_fan_min, + set_fan_min, 2); +static SENSOR_DEVICE_ATTR(fan4_min, S_IWUSR | S_IRUGO, show_fan_min, + set_fan_min, 3); + +static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0); +static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1); +static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2); +static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 3); + +static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, + ALARM2(ADT7473_FAN1_ALARM)); +static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, + ALARM2(ADT7473_FAN2_ALARM)); +static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, + ALARM2(ADT7473_FAN3_ALARM)); +static SENSOR_DEVICE_ATTR(fan4_alarm, S_IRUGO, show_alarm, NULL, + ALARM2(ADT7473_FAN4_ALARM)); + +static SENSOR_DEVICE_ATTR(pwm_use_point2_pwm_at_crit, S_IWUSR | S_IRUGO, + show_max_duty_at_crit, set_max_duty_at_crit, 0); + +static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 0); +static SENSOR_DEVICE_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 1); +static SENSOR_DEVICE_ATTR(pwm3, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 2); + +static SENSOR_DEVICE_ATTR(pwm1_auto_point1_pwm, S_IWUSR | S_IRUGO, + show_pwm_min, set_pwm_min, 0); +static SENSOR_DEVICE_ATTR(pwm2_auto_point1_pwm, S_IWUSR | S_IRUGO, + show_pwm_min, set_pwm_min, 1); +static SENSOR_DEVICE_ATTR(pwm3_auto_point1_pwm, S_IWUSR | S_IRUGO, + show_pwm_min, set_pwm_min, 2); + +static SENSOR_DEVICE_ATTR(pwm1_auto_point2_pwm, S_IWUSR | S_IRUGO, + show_pwm_max, set_pwm_max, 0); +static SENSOR_DEVICE_ATTR(pwm2_auto_point2_pwm, S_IWUSR | S_IRUGO, + show_pwm_max, set_pwm_max, 1); +static SENSOR_DEVICE_ATTR(pwm3_auto_point2_pwm, S_IWUSR | S_IRUGO, + show_pwm_max, set_pwm_max, 2); + +static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp, S_IWUSR | S_IRUGO, + show_temp_tmin, set_temp_tmin, 0); +static SENSOR_DEVICE_ATTR(temp2_auto_point1_temp, S_IWUSR | S_IRUGO, + show_temp_tmin, set_temp_tmin, 1); +static SENSOR_DEVICE_ATTR(temp3_auto_point1_temp, S_IWUSR | S_IRUGO, + show_temp_tmin, set_temp_tmin, 2); + +static SENSOR_DEVICE_ATTR(temp1_auto_point2_temp, S_IWUSR | S_IRUGO, + show_temp_tmax, set_temp_tmax, 0); +static SENSOR_DEVICE_ATTR(temp2_auto_point2_temp, S_IWUSR | S_IRUGO, + show_temp_tmax, set_temp_tmax, 1); +static SENSOR_DEVICE_ATTR(temp3_auto_point2_temp, S_IWUSR | S_IRUGO, + show_temp_tmax, set_temp_tmax, 2); + +static SENSOR_DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, show_pwm_enable, + set_pwm_enable, 0); +static SENSOR_DEVICE_ATTR(pwm2_enable, S_IWUSR | S_IRUGO, show_pwm_enable, + set_pwm_enable, 1); +static SENSOR_DEVICE_ATTR(pwm3_enable, S_IWUSR | S_IRUGO, show_pwm_enable, + set_pwm_enable, 2); + +static SENSOR_DEVICE_ATTR(pwm1_auto_channels_temp, S_IWUSR | S_IRUGO, + show_pwm_auto_temp, set_pwm_auto_temp, 0); +static SENSOR_DEVICE_ATTR(pwm2_auto_channels_temp, S_IWUSR | S_IRUGO, + show_pwm_auto_temp, set_pwm_auto_temp, 1); +static SENSOR_DEVICE_ATTR(pwm3_auto_channels_temp, S_IWUSR | S_IRUGO, + show_pwm_auto_temp, set_pwm_auto_temp, 2); + +static struct attribute *adt7473_attr[] = +{ + &sensor_dev_attr_in1_max.dev_attr.attr, + &sensor_dev_attr_in2_max.dev_attr.attr, + &sensor_dev_attr_in1_min.dev_attr.attr, + &sensor_dev_attr_in2_min.dev_attr.attr, + &sensor_dev_attr_in1_input.dev_attr.attr, + &sensor_dev_attr_in2_input.dev_attr.attr, + &sensor_dev_attr_in1_alarm.dev_attr.attr, + &sensor_dev_attr_in2_alarm.dev_attr.attr, + + &sensor_dev_attr_temp1_max.dev_attr.attr, + &sensor_dev_attr_temp2_max.dev_attr.attr, + &sensor_dev_attr_temp3_max.dev_attr.attr, + &sensor_dev_attr_temp1_min.dev_attr.attr, + &sensor_dev_attr_temp2_min.dev_attr.attr, + &sensor_dev_attr_temp3_min.dev_attr.attr, + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_temp2_input.dev_attr.attr, + &sensor_dev_attr_temp3_input.dev_attr.attr, + &sensor_dev_attr_temp1_alarm.dev_attr.attr, + &sensor_dev_attr_temp2_alarm.dev_attr.attr, + &sensor_dev_attr_temp3_alarm.dev_attr.attr, + &sensor_dev_attr_temp1_auto_point1_temp.dev_attr.attr, + &sensor_dev_attr_temp2_auto_point1_temp.dev_attr.attr, + &sensor_dev_attr_temp3_auto_point1_temp.dev_attr.attr, + &sensor_dev_attr_temp1_auto_point2_temp.dev_attr.attr, + &sensor_dev_attr_temp2_auto_point2_temp.dev_attr.attr, + &sensor_dev_attr_temp3_auto_point2_temp.dev_attr.attr, + + &sensor_dev_attr_fan1_min.dev_attr.attr, + &sensor_dev_attr_fan2_min.dev_attr.attr, + &sensor_dev_attr_fan3_min.dev_attr.attr, + &sensor_dev_attr_fan4_min.dev_attr.attr, + &sensor_dev_attr_fan1_input.dev_attr.attr, + &sensor_dev_attr_fan2_input.dev_attr.attr, + &sensor_dev_attr_fan3_input.dev_attr.attr, + &sensor_dev_attr_fan4_input.dev_attr.attr, + &sensor_dev_attr_fan1_alarm.dev_attr.attr, + &sensor_dev_attr_fan2_alarm.dev_attr.attr, + &sensor_dev_attr_fan3_alarm.dev_attr.attr, + &sensor_dev_attr_fan4_alarm.dev_attr.attr, + + &sensor_dev_attr_pwm_use_point2_pwm_at_crit.dev_attr.attr, + + &sensor_dev_attr_pwm1.dev_attr.attr, + &sensor_dev_attr_pwm2.dev_attr.attr, + &sensor_dev_attr_pwm3.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr, + &sensor_dev_attr_pwm2_auto_point1_pwm.dev_attr.attr, + &sensor_dev_attr_pwm3_auto_point1_pwm.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point2_pwm.dev_attr.attr, + &sensor_dev_attr_pwm2_auto_point2_pwm.dev_attr.attr, + &sensor_dev_attr_pwm3_auto_point2_pwm.dev_attr.attr, + + &sensor_dev_attr_pwm1_enable.dev_attr.attr, + &sensor_dev_attr_pwm2_enable.dev_attr.attr, + &sensor_dev_attr_pwm3_enable.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_channels_temp.dev_attr.attr, + &sensor_dev_attr_pwm2_auto_channels_temp.dev_attr.attr, + &sensor_dev_attr_pwm3_auto_channels_temp.dev_attr.attr, + + NULL +}; + +static int adt7473_attach_adapter(struct i2c_adapter *adapter) +{ + if (!(adapter->class & I2C_CLASS_HWMON)) + return 0; + return i2c_probe(adapter, &addr_data, adt7473_detect); +} + +static int adt7473_detect(struct i2c_adapter *adapter, int address, int kind) +{ + struct i2c_client *client; + struct adt7473_data *data; + int err = 0; + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) + goto exit; + + data = kzalloc(sizeof(struct adt7473_data), GFP_KERNEL); + if (!data) { + err = -ENOMEM; + goto exit; + } + + client = &data->client; + client->addr = address; + client->adapter = adapter; + client->driver = &adt7473_driver; + + i2c_set_clientdata(client, data); + + mutex_init(&data->lock); + + if (kind <= 0) { + int vendor, device, revision; + + vendor = i2c_smbus_read_byte_data(client, ADT7473_REG_VENDOR); + if (vendor != ADT7473_VENDOR) { + err = -ENODEV; + goto exit_free; + } + + device = i2c_smbus_read_byte_data(client, ADT7473_REG_DEVICE); + if (device != ADT7473_DEVICE) { + err = -ENODEV; + goto exit_free; + } + + revision = i2c_smbus_read_byte_data(client, + ADT7473_REG_REVISION); + if (revision != ADT7473_REV_68 && revision != ADT7473_REV_69) { + err = -ENODEV; + goto exit_free; + } + } else + dev_dbg(&adapter->dev, "detection forced\n"); + + strlcpy(client->name, "adt7473", I2C_NAME_SIZE); + + err = i2c_attach_client(client); + if (err) + goto exit_free; + + dev_info(&client->dev, "%s chip found\n", client->name); + + /* Initialize the ADT7473 chip */ + adt7473_init_client(client); + + /* Register sysfs hooks */ + data->attrs.attrs = adt7473_attr; + err = sysfs_create_group(&client->dev.kobj, &data->attrs); + if (err) + goto exit_detach; + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + err = PTR_ERR(data->hwmon_dev); + goto exit_remove; + } + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &data->attrs); +exit_detach: + i2c_detach_client(client); +exit_free: + kfree(data); +exit: + return err; +} + +static int adt7473_detach_client(struct i2c_client *client) +{ + struct adt7473_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &data->attrs); + i2c_detach_client(client); + kfree(data); + return 0; +} + +static int __init adt7473_init(void) +{ + return i2c_add_driver(&adt7473_driver); +} + +static void __exit adt7473_exit(void) +{ + i2c_del_driver(&adt7473_driver); +} + +MODULE_AUTHOR("Darrick J. Wong "); +MODULE_DESCRIPTION("ADT7473 driver"); +MODULE_LICENSE("GPL"); + +module_init(adt7473_init); +module_exit(adt7473_exit); -- cgit v1.2.2 From 25e9c86d5a6d82ea45eb680fc66bf73ac5e50dff Mon Sep 17 00:00:00 2001 From: "Mark M. Hoffman" Date: Sun, 17 Feb 2008 22:28:03 -0500 Subject: hwmon: normal_i2c arrays should be const Signed-off-by: Mark M. Hoffman --- drivers/hwmon/ad7418.c | 2 +- drivers/hwmon/adm1021.c | 6 ++---- drivers/hwmon/adm1025.c | 2 +- drivers/hwmon/adm1026.c | 2 +- drivers/hwmon/adm1029.c | 6 ++---- drivers/hwmon/adm1031.c | 2 +- drivers/hwmon/adm9240.c | 2 +- drivers/hwmon/ads7828.c | 2 +- drivers/hwmon/adt7470.c | 2 +- drivers/hwmon/adt7473.c | 2 +- drivers/hwmon/asb100.c | 2 +- drivers/hwmon/atxp1.c | 2 +- drivers/hwmon/dme1737.c | 2 +- drivers/hwmon/ds1621.c | 2 +- drivers/hwmon/f75375s.c | 2 +- drivers/hwmon/fscher.c | 2 +- drivers/hwmon/fschmd.c | 2 +- drivers/hwmon/fscpos.c | 2 +- drivers/hwmon/gl518sm.c | 2 +- drivers/hwmon/gl520sm.c | 2 +- drivers/hwmon/lm63.c | 2 +- drivers/hwmon/lm75.c | 2 +- drivers/hwmon/lm77.c | 3 ++- drivers/hwmon/lm78.c | 4 ++-- drivers/hwmon/lm80.c | 4 ++-- drivers/hwmon/lm83.c | 6 ++---- drivers/hwmon/lm85.c | 2 +- drivers/hwmon/lm87.c | 2 +- drivers/hwmon/lm90.c | 6 ++---- drivers/hwmon/lm92.c | 4 ++-- drivers/hwmon/lm93.c | 2 +- drivers/hwmon/max1619.c | 6 ++---- drivers/hwmon/max6650.c | 3 ++- drivers/hwmon/smsc47m192.c | 2 +- drivers/hwmon/thmc50.c | 2 +- drivers/hwmon/w83781d.c | 4 ++-- drivers/hwmon/w83791d.c | 3 ++- drivers/hwmon/w83792d.c | 3 ++- drivers/hwmon/w83793.c | 3 ++- drivers/hwmon/w83l785ts.c | 2 +- drivers/hwmon/w83l786ng.c | 2 +- 41 files changed, 55 insertions(+), 60 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/ad7418.c b/drivers/hwmon/ad7418.c index fcd7fe78f3f9..466b9ee92797 100644 --- a/drivers/hwmon/ad7418.c +++ b/drivers/hwmon/ad7418.c @@ -26,7 +26,7 @@ #define DRV_VERSION "0.3" /* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x28, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x28, I2C_CLIENT_END }; /* Insmod parameters */ I2C_CLIENT_INSMOD_3(ad7416, ad7417, ad7418); diff --git a/drivers/hwmon/adm1021.c b/drivers/hwmon/adm1021.c index b96be772e498..ecbf69484bf5 100644 --- a/drivers/hwmon/adm1021.c +++ b/drivers/hwmon/adm1021.c @@ -31,10 +31,8 @@ /* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x18, 0x19, 0x1a, - 0x29, 0x2a, 0x2b, - 0x4c, 0x4d, 0x4e, - I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { + 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, 0x4c, 0x4d, 0x4e, I2C_CLIENT_END }; /* Insmod parameters */ I2C_CLIENT_INSMOD_8(adm1021, adm1023, max1617, max1617a, thmc10, lm84, gl523sm, diff --git a/drivers/hwmon/adm1025.c b/drivers/hwmon/adm1025.c index e96c3725203d..1d76de7d75c7 100644 --- a/drivers/hwmon/adm1025.c +++ b/drivers/hwmon/adm1025.c @@ -62,7 +62,7 @@ * NE1619 has two possible addresses: 0x2c and 0x2d. */ -static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; /* * Insmod parameters diff --git a/drivers/hwmon/adm1026.c b/drivers/hwmon/adm1026.c index b3e6b06caf61..904c6ce9d83f 100644 --- a/drivers/hwmon/adm1026.c +++ b/drivers/hwmon/adm1026.c @@ -35,7 +35,7 @@ #include /* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; /* Insmod parameters */ I2C_CLIENT_INSMOD_1(adm1026); diff --git a/drivers/hwmon/adm1029.c b/drivers/hwmon/adm1029.c index 0bc897dffa27..2c6608d453c2 100644 --- a/drivers/hwmon/adm1029.c +++ b/drivers/hwmon/adm1029.c @@ -39,10 +39,8 @@ * Addresses to scan */ -static unsigned short normal_i2c[] = { - 0x28, 0x29, 0x2a, - 0x2b, 0x2c, 0x2d, - 0x2e, 0x2f, I2C_CLIENT_END +static const unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, I2C_CLIENT_END }; /* diff --git a/drivers/hwmon/adm1031.c b/drivers/hwmon/adm1031.c index 5aaad3636c98..2bffcab7dc9f 100644 --- a/drivers/hwmon/adm1031.c +++ b/drivers/hwmon/adm1031.c @@ -61,7 +61,7 @@ #define ADM1031_CONF2_TEMP_ENABLE(chan) (0x10 << (chan)) /* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; /* Insmod parameters */ I2C_CLIENT_INSMOD_2(adm1030, adm1031); diff --git a/drivers/hwmon/adm9240.c b/drivers/hwmon/adm9240.c index 7671d2bf7800..149ef25252e7 100644 --- a/drivers/hwmon/adm9240.c +++ b/drivers/hwmon/adm9240.c @@ -52,7 +52,7 @@ #include /* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f, +static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f, I2C_CLIENT_END }; /* Insmod parameters */ diff --git a/drivers/hwmon/ads7828.c b/drivers/hwmon/ads7828.c index 6b8a73ef404c..ed71a8bc70dc 100644 --- a/drivers/hwmon/ads7828.c +++ b/drivers/hwmon/ads7828.c @@ -44,7 +44,7 @@ #define ADS7828_INT_VREF_MV 2500 /* Internal vref is 2.5V, 2500mV */ /* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, +static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, I2C_CLIENT_END }; /* Insmod parameters */ diff --git a/drivers/hwmon/adt7470.c b/drivers/hwmon/adt7470.c index 747693ab2ff1..6b5325f33a2c 100644 --- a/drivers/hwmon/adt7470.c +++ b/drivers/hwmon/adt7470.c @@ -30,7 +30,7 @@ #include /* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x2C, 0x2E, 0x2F, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x2C, 0x2E, 0x2F, I2C_CLIENT_END }; /* Insmod parameters */ I2C_CLIENT_INSMOD_1(adt7470); diff --git a/drivers/hwmon/adt7473.c b/drivers/hwmon/adt7473.c index a3daeefff472..9587869bdba0 100644 --- a/drivers/hwmon/adt7473.c +++ b/drivers/hwmon/adt7473.c @@ -30,7 +30,7 @@ #include /* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x2C, 0x2D, 0x2E, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x2C, 0x2D, 0x2E, I2C_CLIENT_END }; /* Insmod parameters */ I2C_CLIENT_INSMOD_1(adt7473); diff --git a/drivers/hwmon/asb100.c b/drivers/hwmon/asb100.c index 950cea8d1d65..84712a22acea 100644 --- a/drivers/hwmon/asb100.c +++ b/drivers/hwmon/asb100.c @@ -49,7 +49,7 @@ #include "lm75.h" /* I2C addresses to scan */ -static unsigned short normal_i2c[] = { 0x2d, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x2d, I2C_CLIENT_END }; /* Insmod parameters */ I2C_CLIENT_INSMOD_1(asb100); diff --git a/drivers/hwmon/atxp1.c b/drivers/hwmon/atxp1.c index cce3350e539e..01c17e387f03 100644 --- a/drivers/hwmon/atxp1.c +++ b/drivers/hwmon/atxp1.c @@ -42,7 +42,7 @@ MODULE_AUTHOR("Sebastian Witt "); #define ATXP1_VIDMASK 0x1f #define ATXP1_GPIO1MASK 0x0f -static unsigned short normal_i2c[] = { 0x37, 0x4e, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x37, 0x4e, I2C_CLIENT_END }; I2C_CLIENT_INSMOD_1(atxp1); diff --git a/drivers/hwmon/dme1737.c b/drivers/hwmon/dme1737.c index ddddd9f34c19..7673f65877e1 100644 --- a/drivers/hwmon/dme1737.c +++ b/drivers/hwmon/dme1737.c @@ -49,7 +49,7 @@ module_param(force_id, ushort, 0); MODULE_PARM_DESC(force_id, "Override the detected device ID"); /* Addresses to scan */ -static unsigned short normal_i2c[] = {0x2c, 0x2d, 0x2e, I2C_CLIENT_END}; +static const unsigned short normal_i2c[] = {0x2c, 0x2d, 0x2e, I2C_CLIENT_END}; /* Insmod parameters */ I2C_CLIENT_INSMOD_1(dme1737); diff --git a/drivers/hwmon/ds1621.c b/drivers/hwmon/ds1621.c index 3f5163de13c1..5f300ffed657 100644 --- a/drivers/hwmon/ds1621.c +++ b/drivers/hwmon/ds1621.c @@ -34,7 +34,7 @@ #include "lm75.h" /* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c, +static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, I2C_CLIENT_END }; /* Insmod parameters */ diff --git a/drivers/hwmon/f75375s.c b/drivers/hwmon/f75375s.c index 6892f76fc18a..1464338e4e11 100644 --- a/drivers/hwmon/f75375s.c +++ b/drivers/hwmon/f75375s.c @@ -37,7 +37,7 @@ #include /* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x2d, 0x2e, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x2d, 0x2e, I2C_CLIENT_END }; /* Insmod parameters */ I2C_CLIENT_INSMOD_2(f75373, f75375); diff --git a/drivers/hwmon/fscher.c b/drivers/hwmon/fscher.c index 721c70177b17..ed26b66e0831 100644 --- a/drivers/hwmon/fscher.c +++ b/drivers/hwmon/fscher.c @@ -40,7 +40,7 @@ * Addresses to scan */ -static unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END }; /* * Insmod parameters diff --git a/drivers/hwmon/fschmd.c b/drivers/hwmon/fschmd.c index b7c9eef0f928..bd89d270a5ed 100644 --- a/drivers/hwmon/fschmd.c +++ b/drivers/hwmon/fschmd.c @@ -44,7 +44,7 @@ #include /* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END }; /* Insmod parameters */ I2C_CLIENT_INSMOD_5(fscpos, fscher, fscscy, fschrc, fschmd); diff --git a/drivers/hwmon/fscpos.c b/drivers/hwmon/fscpos.c index 2f1075323a1e..00f48484e54b 100644 --- a/drivers/hwmon/fscpos.c +++ b/drivers/hwmon/fscpos.c @@ -43,7 +43,7 @@ /* * Addresses to scan */ -static unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END }; /* * Insmod parameters diff --git a/drivers/hwmon/gl518sm.c b/drivers/hwmon/gl518sm.c index 3b1ac48fce23..33e9e8a8d1ce 100644 --- a/drivers/hwmon/gl518sm.c +++ b/drivers/hwmon/gl518sm.c @@ -44,7 +44,7 @@ #include /* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END }; /* Insmod parameters */ I2C_CLIENT_INSMOD_2(gl518sm_r00, gl518sm_r80); diff --git a/drivers/hwmon/gl520sm.c b/drivers/hwmon/gl520sm.c index 03ecdc334764..8984ef141627 100644 --- a/drivers/hwmon/gl520sm.c +++ b/drivers/hwmon/gl520sm.c @@ -39,7 +39,7 @@ module_param(extra_sensor_type, ushort, 0); MODULE_PARM_DESC(extra_sensor_type, "Type of extra sensor (0=autodetect, 1=temperature, 2=voltage)"); /* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END }; /* Insmod parameters */ I2C_CLIENT_INSMOD_1(gl520sm); diff --git a/drivers/hwmon/lm63.c b/drivers/hwmon/lm63.c index 650b07d5b902..116287008083 100644 --- a/drivers/hwmon/lm63.c +++ b/drivers/hwmon/lm63.c @@ -53,7 +53,7 @@ * Address is fully defined internally and cannot be changed. */ -static unsigned short normal_i2c[] = { 0x4c, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x4c, I2C_CLIENT_END }; /* * Insmod parameters diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c index e5c35a355a57..115f4090b98e 100644 --- a/drivers/hwmon/lm75.c +++ b/drivers/hwmon/lm75.c @@ -31,7 +31,7 @@ /* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c, +static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, I2C_CLIENT_END }; /* Insmod parameters */ diff --git a/drivers/hwmon/lm77.c b/drivers/hwmon/lm77.c index 459b70ad6bee..36d5a8c3ad8c 100644 --- a/drivers/hwmon/lm77.c +++ b/drivers/hwmon/lm77.c @@ -36,7 +36,8 @@ #include /* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, + I2C_CLIENT_END }; /* Insmod parameters */ I2C_CLIENT_INSMOD_1(lm77); diff --git a/drivers/hwmon/lm78.c b/drivers/hwmon/lm78.c index 0a9eb1f6f4e4..ed7859f0e16a 100644 --- a/drivers/hwmon/lm78.c +++ b/drivers/hwmon/lm78.c @@ -37,8 +37,8 @@ static struct platform_device *pdev; /* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, - 0x2e, 0x2f, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, I2C_CLIENT_END }; static unsigned short isa_address = 0x290; /* Insmod parameters */ diff --git a/drivers/hwmon/lm80.c b/drivers/hwmon/lm80.c index a2ca055f3922..26c91c9d4769 100644 --- a/drivers/hwmon/lm80.c +++ b/drivers/hwmon/lm80.c @@ -32,8 +32,8 @@ #include /* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, - 0x2d, 0x2e, 0x2f, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, I2C_CLIENT_END }; /* Insmod parameters */ I2C_CLIENT_INSMOD_1(lm80); diff --git a/drivers/hwmon/lm83.c b/drivers/hwmon/lm83.c index 6e8903a6e902..6a8642fa25fb 100644 --- a/drivers/hwmon/lm83.c +++ b/drivers/hwmon/lm83.c @@ -48,10 +48,8 @@ * addresses. */ -static unsigned short normal_i2c[] = { 0x18, 0x19, 0x1a, - 0x29, 0x2a, 0x2b, - 0x4c, 0x4d, 0x4e, - I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { + 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, 0x4c, 0x4d, 0x4e, I2C_CLIENT_END }; /* * Insmod parameters diff --git a/drivers/hwmon/lm85.c b/drivers/hwmon/lm85.c index 4bb0f291a6b8..182fe6a5605f 100644 --- a/drivers/hwmon/lm85.c +++ b/drivers/hwmon/lm85.c @@ -35,7 +35,7 @@ #include /* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; /* Insmod parameters */ I2C_CLIENT_INSMOD_6(lm85b, lm85c, adm1027, adt7463, emc6d100, emc6d102); diff --git a/drivers/hwmon/lm87.c b/drivers/hwmon/lm87.c index 8ee07c5c97a1..e1c183f0aae0 100644 --- a/drivers/hwmon/lm87.c +++ b/drivers/hwmon/lm87.c @@ -73,7 +73,7 @@ * LM87 has three possible addresses: 0x2c, 0x2d and 0x2e. */ -static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; /* * Insmod parameters diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c index f7ec95bedbf6..d1a3da3dd8e0 100644 --- a/drivers/hwmon/lm90.c +++ b/drivers/hwmon/lm90.c @@ -101,10 +101,8 @@ * 0x4c, 0x4d or 0x4e. */ -static unsigned short normal_i2c[] = { 0x18, 0x19, 0x1a, - 0x29, 0x2a, 0x2b, - 0x4c, 0x4d, 0x4e, - I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { + 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, 0x4c, 0x4d, 0x4e, I2C_CLIENT_END }; /* * Insmod parameters diff --git a/drivers/hwmon/lm92.c b/drivers/hwmon/lm92.c index a2b804115ce5..c31942e08246 100644 --- a/drivers/hwmon/lm92.c +++ b/drivers/hwmon/lm92.c @@ -51,8 +51,8 @@ /* The LM92 and MAX6635 have 2 two-state pins for address selection, resulting in 4 possible addresses. */ -static unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, - I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, + I2C_CLIENT_END }; /* Insmod parameters */ I2C_CLIENT_INSMOD_1(lm92); diff --git a/drivers/hwmon/lm93.c b/drivers/hwmon/lm93.c index ea61946a4bf7..5e678f5c883d 100644 --- a/drivers/hwmon/lm93.c +++ b/drivers/hwmon/lm93.c @@ -142,7 +142,7 @@ I2C_FUNC_SMBUS_WORD_DATA) /* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; /* Insmod parameters */ I2C_CLIENT_INSMOD_1(lm93); diff --git a/drivers/hwmon/max1619.c b/drivers/hwmon/max1619.c index 342803417973..7e7267a04544 100644 --- a/drivers/hwmon/max1619.c +++ b/drivers/hwmon/max1619.c @@ -37,10 +37,8 @@ #include #include -static unsigned short normal_i2c[] = { 0x18, 0x19, 0x1a, - 0x29, 0x2a, 0x2b, - 0x4c, 0x4d, 0x4e, - I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { + 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, 0x4c, 0x4d, 0x4e, I2C_CLIENT_END }; /* * Insmod parameters diff --git a/drivers/hwmon/max6650.c b/drivers/hwmon/max6650.c index 755570c1f4eb..52d528b76cc3 100644 --- a/drivers/hwmon/max6650.c +++ b/drivers/hwmon/max6650.c @@ -44,7 +44,8 @@ * Addresses to scan. There are four disjoint possibilities, by pin config. */ -static unsigned short normal_i2c[] = {0x1b, 0x1f, 0x48, 0x4b, I2C_CLIENT_END}; +static const unsigned short normal_i2c[] = {0x1b, 0x1f, 0x48, 0x4b, + I2C_CLIENT_END}; /* * Insmod parameters diff --git a/drivers/hwmon/smsc47m192.c b/drivers/hwmon/smsc47m192.c index 8b0c188e60f6..3c9db6598ba7 100644 --- a/drivers/hwmon/smsc47m192.c +++ b/drivers/hwmon/smsc47m192.c @@ -34,7 +34,7 @@ #include /* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END }; /* Insmod parameters */ I2C_CLIENT_INSMOD_1(smsc47m192); diff --git a/drivers/hwmon/thmc50.c b/drivers/hwmon/thmc50.c index a42a03c24367..76a3859c3fbe 100644 --- a/drivers/hwmon/thmc50.c +++ b/drivers/hwmon/thmc50.c @@ -32,7 +32,7 @@ MODULE_LICENSE("GPL"); /* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; /* Insmod parameters */ I2C_CLIENT_INSMOD_2(thmc50, adm1022); diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c index 7421f6ea53e1..5c85670e2d16 100644 --- a/drivers/hwmon/w83781d.c +++ b/drivers/hwmon/w83781d.c @@ -53,8 +53,8 @@ static struct platform_device *pdev; /* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, - 0x2e, 0x2f, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, I2C_CLIENT_END }; static unsigned short isa_address = 0x290; /* Insmod parameters */ diff --git a/drivers/hwmon/w83791d.c b/drivers/hwmon/w83791d.c index 85bd21ee3298..85077c4c8039 100644 --- a/drivers/hwmon/w83791d.c +++ b/drivers/hwmon/w83791d.c @@ -47,7 +47,8 @@ #define NUMBER_OF_TEMPIN 3 /* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f, + I2C_CLIENT_END }; /* Insmod parameters */ I2C_CLIENT_INSMOD_1(w83791d); diff --git a/drivers/hwmon/w83792d.c b/drivers/hwmon/w83792d.c index 007449d3e16e..299629d47ed6 100644 --- a/drivers/hwmon/w83792d.c +++ b/drivers/hwmon/w83792d.c @@ -46,7 +46,8 @@ #include /* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f, + I2C_CLIENT_END }; /* Insmod parameters */ I2C_CLIENT_INSMOD_1(w83792d); diff --git a/drivers/hwmon/w83793.c b/drivers/hwmon/w83793.c index 3ba1d6b33473..ee35af93b574 100644 --- a/drivers/hwmon/w83793.c +++ b/drivers/hwmon/w83793.c @@ -37,7 +37,8 @@ #include /* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f, + I2C_CLIENT_END }; /* Insmod parameters */ I2C_CLIENT_INSMOD_1(w83793); diff --git a/drivers/hwmon/w83l785ts.c b/drivers/hwmon/w83l785ts.c index 1d6259d29e74..77f2d482888b 100644 --- a/drivers/hwmon/w83l785ts.c +++ b/drivers/hwmon/w83l785ts.c @@ -49,7 +49,7 @@ * Address is fully defined internally and cannot be changed. */ -static unsigned short normal_i2c[] = { 0x2e, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x2e, I2C_CLIENT_END }; /* * Insmod parameters diff --git a/drivers/hwmon/w83l786ng.c b/drivers/hwmon/w83l786ng.c index 1dbee4fa23ad..41e22ddb568a 100644 --- a/drivers/hwmon/w83l786ng.c +++ b/drivers/hwmon/w83l786ng.c @@ -35,7 +35,7 @@ #include /* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x2e, 0x2f, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x2e, 0x2f, I2C_CLIENT_END }; /* Insmod parameters */ I2C_CLIENT_INSMOD_1(w83l786ng); -- cgit v1.2.2