aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-07-25 17:10:34 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-07-25 17:10:34 -0400
commit750e06992d49666a7589aac555eb3bb68e4dbb88 (patch)
tree7ee3d85adf256491dae89e5b049bb28ef1a1680c /drivers/hwmon
parentd3ec4844d449cf7af9e749f73ba2052fb7b72fc2 (diff)
parent156e2d1adc03e17f18f98d297f7757fc6d93a589 (diff)
Merge branch 'hwmon-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jdelvare/staging
* 'hwmon-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jdelvare/staging: hwmon: (lm78) Become the maintainer hwmon: (lm78) Make ISA interface depend on CONFIG_ISA hwmon: (lm78) Avoid forward declarations hwmon: (sht15) Correct a comment mistake hwmon: (max1111) Avoid extra memory allocations hwmon: (it87) Add chassis intrusion detection support hwmon: (via-cputemp) Add VID reporting support hwmon-vid: Add support for VIA family 6 model D CPU hwmon: New driver sch5636 hwmon: (sch5627) Factor out some code shared with sch5636 driver
Diffstat (limited to 'drivers/hwmon')
-rw-r--r--drivers/hwmon/Kconfig21
-rw-r--r--drivers/hwmon/Makefile2
-rw-r--r--drivers/hwmon/hwmon-vid.c42
-rw-r--r--drivers/hwmon/it87.c29
-rw-r--r--drivers/hwmon/lm78.c305
-rw-r--r--drivers/hwmon/max1111.c27
-rw-r--r--drivers/hwmon/sch5627.c334
-rw-r--r--drivers/hwmon/sch5636.c539
-rw-r--r--drivers/hwmon/sch56xx-common.c340
-rw-r--r--drivers/hwmon/sch56xx-common.h24
-rw-r--r--drivers/hwmon/sht15.c2
-rw-r--r--drivers/hwmon/via-cputemp.c44
12 files changed, 1243 insertions, 466 deletions
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 5f888f7e7dcb..0598cd22edf2 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -1041,8 +1041,13 @@ config SENSORS_SMSC47B397
1041 This driver can also be built as a module. If so, the module 1041 This driver can also be built as a module. If so, the module
1042 will be called smsc47b397. 1042 will be called smsc47b397.
1043 1043
1044config SENSORS_SCH56XX_COMMON
1045 tristate
1046 default n
1047
1044config SENSORS_SCH5627 1048config SENSORS_SCH5627
1045 tristate "SMSC SCH5627" 1049 tristate "SMSC SCH5627"
1050 select SENSORS_SCH56XX_COMMON
1046 help 1051 help
1047 If you say yes here you get support for the hardware monitoring 1052 If you say yes here you get support for the hardware monitoring
1048 features of the SMSC SCH5627 Super-I/O chip. 1053 features of the SMSC SCH5627 Super-I/O chip.
@@ -1050,6 +1055,21 @@ config SENSORS_SCH5627
1050 This driver can also be built as a module. If so, the module 1055 This driver can also be built as a module. If so, the module
1051 will be called sch5627. 1056 will be called sch5627.
1052 1057
1058config SENSORS_SCH5636
1059 tristate "SMSC SCH5636"
1060 select SENSORS_SCH56XX_COMMON
1061 help
1062 SMSC SCH5636 Super I/O chips include an embedded microcontroller for
1063 hardware monitoring solutions, allowing motherboard manufacturers to
1064 create their own custom hwmon solution based upon the SCH5636.
1065
1066 Currently this driver only supports the Fujitsu Theseus SCH5636 based
1067 hwmon solution. Say yes here if you want support for the Fujitsu
1068 Theseus' hardware monitoring features.
1069
1070 This driver can also be built as a module. If so, the module
1071 will be called sch5636.
1072
1053config SENSORS_ADS1015 1073config SENSORS_ADS1015
1054 tristate "Texas Instruments ADS1015" 1074 tristate "Texas Instruments ADS1015"
1055 depends on I2C 1075 depends on I2C
@@ -1142,6 +1162,7 @@ config SENSORS_TWL4030_MADC
1142config SENSORS_VIA_CPUTEMP 1162config SENSORS_VIA_CPUTEMP
1143 tristate "VIA CPU temperature sensor" 1163 tristate "VIA CPU temperature sensor"
1144 depends on X86 1164 depends on X86
1165 select HWMON_VID
1145 help 1166 help
1146 If you say yes here you get support for the temperature 1167 If you say yes here you get support for the temperature
1147 sensor inside your CPU. Supported are all known variants of 1168 sensor inside your CPU. Supported are all known variants of
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 28061cfa0cdb..d7995a1d0784 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -95,7 +95,9 @@ obj-$(CONFIG_SENSORS_PC87360) += pc87360.o
95obj-$(CONFIG_SENSORS_PC87427) += pc87427.o 95obj-$(CONFIG_SENSORS_PC87427) += pc87427.o
96obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o 96obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o
97obj-$(CONFIG_SENSORS_S3C) += s3c-hwmon.o 97obj-$(CONFIG_SENSORS_S3C) += s3c-hwmon.o
98obj-$(CONFIG_SENSORS_SCH56XX_COMMON)+= sch56xx-common.o
98obj-$(CONFIG_SENSORS_SCH5627) += sch5627.o 99obj-$(CONFIG_SENSORS_SCH5627) += sch5627.o
100obj-$(CONFIG_SENSORS_SCH5636) += sch5636.o
99obj-$(CONFIG_SENSORS_SHT15) += sht15.o 101obj-$(CONFIG_SENSORS_SHT15) += sht15.o
100obj-$(CONFIG_SENSORS_SHT21) += sht21.o 102obj-$(CONFIG_SENSORS_SHT21) += sht21.o
101obj-$(CONFIG_SENSORS_SIS5595) += sis5595.o 103obj-$(CONFIG_SENSORS_SIS5595) += sis5595.o
diff --git a/drivers/hwmon/hwmon-vid.c b/drivers/hwmon/hwmon-vid.c
index c8195a077da3..932da8a5aaf4 100644
--- a/drivers/hwmon/hwmon-vid.c
+++ b/drivers/hwmon/hwmon-vid.c
@@ -140,7 +140,11 @@ int vid_from_reg(int val, u8 vrm)
140 return(val & 0x10 ? 975 - (val & 0xF) * 25 : 140 return(val & 0x10 ? 975 - (val & 0xF) * 25 :
141 1750 - val * 50); 141 1750 - val * 50);
142 case 13: 142 case 13:
143 case 131:
143 val &= 0x3f; 144 val &= 0x3f;
145 /* Exception for Eden ULV 500 MHz */
146 if (vrm == 131 && val == 0x3f)
147 val++;
144 return(1708 - val * 16); 148 return(1708 - val * 16);
145 case 14: /* Intel Core */ 149 case 14: /* Intel Core */
146 /* compute in uV, round to mV */ 150 /* compute in uV, round to mV */
@@ -205,11 +209,45 @@ static struct vrm_model vrm_models[] = {
205 {X86_VENDOR_CENTAUR, 0x6, 0x9, 0x7, 85}, /* Nehemiah */ 209 {X86_VENDOR_CENTAUR, 0x6, 0x9, 0x7, 85}, /* Nehemiah */
206 {X86_VENDOR_CENTAUR, 0x6, 0x9, ANY, 17}, /* C3-M, Eden-N */ 210 {X86_VENDOR_CENTAUR, 0x6, 0x9, ANY, 17}, /* C3-M, Eden-N */
207 {X86_VENDOR_CENTAUR, 0x6, 0xA, 0x7, 0}, /* No information */ 211 {X86_VENDOR_CENTAUR, 0x6, 0xA, 0x7, 0}, /* No information */
208 {X86_VENDOR_CENTAUR, 0x6, 0xA, ANY, 13}, /* C7, Esther */ 212 {X86_VENDOR_CENTAUR, 0x6, 0xA, ANY, 13}, /* C7-M, C7, Eden (Esther) */
213 {X86_VENDOR_CENTAUR, 0x6, 0xD, ANY, 134}, /* C7-D, C7-M, C7, Eden (Esther) */
209 214
210 {X86_VENDOR_UNKNOWN, ANY, ANY, ANY, 0} /* stop here */ 215 {X86_VENDOR_UNKNOWN, ANY, ANY, ANY, 0} /* stop here */
211}; 216};
212 217
218/*
219 * Special case for VIA model D: there are two different possible
220 * VID tables, so we have to figure out first, which one must be
221 * used. This resolves temporary drm value 134 to 14 (Intel Core
222 * 7-bit VID), 13 (Pentium M 6-bit VID) or 131 (Pentium M 6-bit VID
223 * + quirk for Eden ULV 500 MHz).
224 * Note: something similar might be needed for model A, I'm not sure.
225 */
226static u8 get_via_model_d_vrm(void)
227{
228 unsigned int vid, brand, dummy;
229 static const char *brands[4] = {
230 "C7-M", "C7", "Eden", "C7-D"
231 };
232
233 rdmsr(0x198, dummy, vid);
234 vid &= 0xff;
235
236 rdmsr(0x1154, brand, dummy);
237 brand = ((brand >> 4) ^ (brand >> 2)) & 0x03;
238
239 if (vid > 0x3f) {
240 pr_info("Using %d-bit VID table for VIA %s CPU\n",
241 7, brands[brand]);
242 return 14;
243 } else {
244 pr_info("Using %d-bit VID table for VIA %s CPU\n",
245 6, brands[brand]);
246 /* Enable quirk for Eden */
247 return brand == 2 ? 131 : 13;
248 }
249}
250
213static u8 find_vrm(u8 eff_family, u8 eff_model, u8 eff_stepping, u8 vendor) 251static u8 find_vrm(u8 eff_family, u8 eff_model, u8 eff_stepping, u8 vendor)
214{ 252{
215 int i = 0; 253 int i = 0;
@@ -247,6 +285,8 @@ u8 vid_which_vrm(void)
247 eff_model += ((eax & 0x000F0000)>>16)<<4; 285 eff_model += ((eax & 0x000F0000)>>16)<<4;
248 } 286 }
249 vrm_ret = find_vrm(eff_family, eff_model, eff_stepping, c->x86_vendor); 287 vrm_ret = find_vrm(eff_family, eff_model, eff_stepping, c->x86_vendor);
288 if (vrm_ret == 134)
289 vrm_ret = get_via_model_d_vrm();
250 if (vrm_ret == 0) 290 if (vrm_ret == 0)
251 pr_info("Unknown VRM version of your x86 CPU\n"); 291 pr_info("Unknown VRM version of your x86 CPU\n");
252 return vrm_ret; 292 return vrm_ret;
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 5f5247750430..d912649fac50 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -1172,6 +1172,32 @@ static ssize_t show_alarm(struct device *dev, struct device_attribute *attr,
1172 struct it87_data *data = it87_update_device(dev); 1172 struct it87_data *data = it87_update_device(dev);
1173 return sprintf(buf, "%u\n", (data->alarms >> bitnr) & 1); 1173 return sprintf(buf, "%u\n", (data->alarms >> bitnr) & 1);
1174} 1174}
1175
1176static ssize_t clear_intrusion(struct device *dev, struct device_attribute
1177 *attr, const char *buf, size_t count)
1178{
1179 struct it87_data *data = dev_get_drvdata(dev);
1180 long val;
1181 int config;
1182
1183 if (strict_strtol(buf, 10, &val) < 0 || val != 0)
1184 return -EINVAL;
1185
1186 mutex_lock(&data->update_lock);
1187 config = it87_read_value(data, IT87_REG_CONFIG);
1188 if (config < 0) {
1189 count = config;
1190 } else {
1191 config |= 1 << 5;
1192 it87_write_value(data, IT87_REG_CONFIG, config);
1193 /* Invalidate cache to force re-read */
1194 data->valid = 0;
1195 }
1196 mutex_unlock(&data->update_lock);
1197
1198 return count;
1199}
1200
1175static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 8); 1201static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 8);
1176static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 9); 1202static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 9);
1177static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 10); 1203static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 10);
@@ -1188,6 +1214,8 @@ static SENSOR_DEVICE_ATTR(fan5_alarm, S_IRUGO, show_alarm, NULL, 6);
1188static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 16); 1214static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 16);
1189static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 17); 1215static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 17);
1190static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 18); 1216static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 18);
1217static SENSOR_DEVICE_ATTR(intrusion0_alarm, S_IRUGO | S_IWUSR,
1218 show_alarm, clear_intrusion, 4);
1191 1219
1192static ssize_t show_beep(struct device *dev, struct device_attribute *attr, 1220static ssize_t show_beep(struct device *dev, struct device_attribute *attr,
1193 char *buf) 1221 char *buf)
@@ -1350,6 +1378,7 @@ static struct attribute *it87_attributes[] = {
1350 &sensor_dev_attr_temp3_alarm.dev_attr.attr, 1378 &sensor_dev_attr_temp3_alarm.dev_attr.attr,
1351 1379
1352 &dev_attr_alarms.attr, 1380 &dev_attr_alarms.attr,
1381 &sensor_dev_attr_intrusion0_alarm.dev_attr.attr,
1353 &dev_attr_name.attr, 1382 &dev_attr_name.attr,
1354 NULL 1383 NULL
1355}; 1384};
diff --git a/drivers/hwmon/lm78.c b/drivers/hwmon/lm78.c
index 4cb24eafe318..6df0b4681710 100644
--- a/drivers/hwmon/lm78.c
+++ b/drivers/hwmon/lm78.c
@@ -2,7 +2,7 @@
2 lm78.c - Part of lm_sensors, Linux kernel modules for hardware 2 lm78.c - Part of lm_sensors, Linux kernel modules for hardware
3 monitoring 3 monitoring
4 Copyright (c) 1998, 1999 Frodo Looijaard <frodol@dds.nl> 4 Copyright (c) 1998, 1999 Frodo Looijaard <frodol@dds.nl>
5 Copyright (c) 2007 Jean Delvare <khali@linux-fr.org> 5 Copyright (c) 2007, 2011 Jean Delvare <khali@linux-fr.org>
6 6
7 This program is free software; you can redistribute it and/or modify 7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by 8 it under the terms of the GNU General Public License as published by
@@ -26,23 +26,21 @@
26#include <linux/slab.h> 26#include <linux/slab.h>
27#include <linux/jiffies.h> 27#include <linux/jiffies.h>
28#include <linux/i2c.h> 28#include <linux/i2c.h>
29#include <linux/platform_device.h>
30#include <linux/ioport.h>
31#include <linux/hwmon.h> 29#include <linux/hwmon.h>
32#include <linux/hwmon-vid.h> 30#include <linux/hwmon-vid.h>
33#include <linux/hwmon-sysfs.h> 31#include <linux/hwmon-sysfs.h>
34#include <linux/err.h> 32#include <linux/err.h>
35#include <linux/mutex.h> 33#include <linux/mutex.h>
36#include <linux/io.h>
37 34
38/* ISA device, if found */ 35#ifdef CONFIG_ISA
39static struct platform_device *pdev; 36#include <linux/platform_device.h>
37#include <linux/ioport.h>
38#include <linux/io.h>
39#endif
40 40
41/* Addresses to scan */ 41/* Addresses to scan */
42static const unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 42static const unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d,
43 0x2e, 0x2f, I2C_CLIENT_END }; 43 0x2e, 0x2f, I2C_CLIENT_END };
44static unsigned short isa_address = 0x290;
45
46enum chips { lm78, lm79 }; 44enum chips { lm78, lm79 };
47 45
48/* Many LM78 constants specified below */ 46/* Many LM78 constants specified below */
@@ -143,50 +141,12 @@ struct lm78_data {
143}; 141};
144 142
145 143
146static int lm78_i2c_detect(struct i2c_client *client,
147 struct i2c_board_info *info);
148static int lm78_i2c_probe(struct i2c_client *client,
149 const struct i2c_device_id *id);
150static int lm78_i2c_remove(struct i2c_client *client);
151
152static int __devinit lm78_isa_probe(struct platform_device *pdev);
153static int __devexit lm78_isa_remove(struct platform_device *pdev);
154
155static int lm78_read_value(struct lm78_data *data, u8 reg); 144static int lm78_read_value(struct lm78_data *data, u8 reg);
156static int lm78_write_value(struct lm78_data *data, u8 reg, u8 value); 145static int lm78_write_value(struct lm78_data *data, u8 reg, u8 value);
157static struct lm78_data *lm78_update_device(struct device *dev); 146static struct lm78_data *lm78_update_device(struct device *dev);
158static void lm78_init_device(struct lm78_data *data); 147static void lm78_init_device(struct lm78_data *data);
159 148
160 149
161static const struct i2c_device_id lm78_i2c_id[] = {
162 { "lm78", lm78 },
163 { "lm79", lm79 },
164 { }
165};
166MODULE_DEVICE_TABLE(i2c, lm78_i2c_id);
167
168static struct i2c_driver lm78_driver = {
169 .class = I2C_CLASS_HWMON,
170 .driver = {
171 .name = "lm78",
172 },
173 .probe = lm78_i2c_probe,
174 .remove = lm78_i2c_remove,
175 .id_table = lm78_i2c_id,
176 .detect = lm78_i2c_detect,
177 .address_list = normal_i2c,
178};
179
180static struct platform_driver lm78_isa_driver = {
181 .driver = {
182 .owner = THIS_MODULE,
183 .name = "lm78",
184 },
185 .probe = lm78_isa_probe,
186 .remove = __devexit_p(lm78_isa_remove),
187};
188
189
190/* 7 Voltages */ 150/* 7 Voltages */
191static ssize_t show_in(struct device *dev, struct device_attribute *da, 151static ssize_t show_in(struct device *dev, struct device_attribute *da,
192 char *buf) 152 char *buf)
@@ -514,6 +474,16 @@ static const struct attribute_group lm78_group = {
514 .attrs = lm78_attributes, 474 .attrs = lm78_attributes,
515}; 475};
516 476
477/*
478 * ISA related code
479 */
480#ifdef CONFIG_ISA
481
482/* ISA device, if found */
483static struct platform_device *pdev;
484
485static unsigned short isa_address = 0x290;
486
517/* I2C devices get this name attribute automatically, but for ISA devices 487/* I2C devices get this name attribute automatically, but for ISA devices
518 we must create it by ourselves. */ 488 we must create it by ourselves. */
519static ssize_t show_name(struct device *dev, struct device_attribute 489static ssize_t show_name(struct device *dev, struct device_attribute
@@ -525,6 +495,11 @@ static ssize_t show_name(struct device *dev, struct device_attribute
525} 495}
526static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); 496static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
527 497
498static struct lm78_data *lm78_data_if_isa(void)
499{
500 return pdev ? platform_get_drvdata(pdev) : NULL;
501}
502
528/* Returns 1 if the I2C chip appears to be an alias of the ISA chip */ 503/* Returns 1 if the I2C chip appears to be an alias of the ISA chip */
529static int lm78_alias_detect(struct i2c_client *client, u8 chipid) 504static int lm78_alias_detect(struct i2c_client *client, u8 chipid)
530{ 505{
@@ -558,12 +533,24 @@ static int lm78_alias_detect(struct i2c_client *client, u8 chipid)
558 533
559 return 1; 534 return 1;
560} 535}
536#else /* !CONFIG_ISA */
537
538static int lm78_alias_detect(struct i2c_client *client, u8 chipid)
539{
540 return 0;
541}
542
543static struct lm78_data *lm78_data_if_isa(void)
544{
545 return NULL;
546}
547#endif /* CONFIG_ISA */
561 548
562static int lm78_i2c_detect(struct i2c_client *client, 549static int lm78_i2c_detect(struct i2c_client *client,
563 struct i2c_board_info *info) 550 struct i2c_board_info *info)
564{ 551{
565 int i; 552 int i;
566 struct lm78_data *isa = pdev ? platform_get_drvdata(pdev) : NULL; 553 struct lm78_data *isa = lm78_data_if_isa();
567 const char *client_name; 554 const char *client_name;
568 struct i2c_adapter *adapter = client->adapter; 555 struct i2c_adapter *adapter = client->adapter;
569 int address = client->addr; 556 int address = client->addr;
@@ -663,76 +650,24 @@ static int lm78_i2c_remove(struct i2c_client *client)
663 return 0; 650 return 0;
664} 651}
665 652
666static int __devinit lm78_isa_probe(struct platform_device *pdev) 653static const struct i2c_device_id lm78_i2c_id[] = {
667{ 654 { "lm78", lm78 },
668 int err; 655 { "lm79", lm79 },
669 struct lm78_data *data; 656 { }
670 struct resource *res; 657};
671 658MODULE_DEVICE_TABLE(i2c, lm78_i2c_id);
672 /* Reserve the ISA region */
673 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
674 if (!request_region(res->start + LM78_ADDR_REG_OFFSET, 2, "lm78")) {
675 err = -EBUSY;
676 goto exit;
677 }
678
679 if (!(data = kzalloc(sizeof(struct lm78_data), GFP_KERNEL))) {
680 err = -ENOMEM;
681 goto exit_release_region;
682 }
683 mutex_init(&data->lock);
684 data->isa_addr = res->start;
685 platform_set_drvdata(pdev, data);
686
687 if (lm78_read_value(data, LM78_REG_CHIPID) & 0x80) {
688 data->type = lm79;
689 data->name = "lm79";
690 } else {
691 data->type = lm78;
692 data->name = "lm78";
693 }
694
695 /* Initialize the LM78 chip */
696 lm78_init_device(data);
697
698 /* Register sysfs hooks */
699 if ((err = sysfs_create_group(&pdev->dev.kobj, &lm78_group))
700 || (err = device_create_file(&pdev->dev, &dev_attr_name)))
701 goto exit_remove_files;
702
703 data->hwmon_dev = hwmon_device_register(&pdev->dev);
704 if (IS_ERR(data->hwmon_dev)) {
705 err = PTR_ERR(data->hwmon_dev);
706 goto exit_remove_files;
707 }
708
709 return 0;
710
711 exit_remove_files:
712 sysfs_remove_group(&pdev->dev.kobj, &lm78_group);
713 device_remove_file(&pdev->dev, &dev_attr_name);
714 kfree(data);
715 exit_release_region:
716 release_region(res->start + LM78_ADDR_REG_OFFSET, 2);
717 exit:
718 return err;
719}
720
721static int __devexit lm78_isa_remove(struct platform_device *pdev)
722{
723 struct lm78_data *data = platform_get_drvdata(pdev);
724 struct resource *res;
725
726 hwmon_device_unregister(data->hwmon_dev);
727 sysfs_remove_group(&pdev->dev.kobj, &lm78_group);
728 device_remove_file(&pdev->dev, &dev_attr_name);
729 kfree(data);
730
731 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
732 release_region(res->start + LM78_ADDR_REG_OFFSET, 2);
733 659
734 return 0; 660static struct i2c_driver lm78_driver = {
735} 661 .class = I2C_CLASS_HWMON,
662 .driver = {
663 .name = "lm78",
664 },
665 .probe = lm78_i2c_probe,
666 .remove = lm78_i2c_remove,
667 .id_table = lm78_i2c_id,
668 .detect = lm78_i2c_detect,
669 .address_list = normal_i2c,
670};
736 671
737/* The SMBus locks itself, but ISA access must be locked explicitly! 672/* The SMBus locks itself, but ISA access must be locked explicitly!
738 We don't want to lock the whole ISA bus, so we lock each client 673 We don't want to lock the whole ISA bus, so we lock each client
@@ -743,6 +678,7 @@ static int lm78_read_value(struct lm78_data *data, u8 reg)
743{ 678{
744 struct i2c_client *client = data->client; 679 struct i2c_client *client = data->client;
745 680
681#ifdef CONFIG_ISA
746 if (!client) { /* ISA device */ 682 if (!client) { /* ISA device */
747 int res; 683 int res;
748 mutex_lock(&data->lock); 684 mutex_lock(&data->lock);
@@ -751,6 +687,7 @@ static int lm78_read_value(struct lm78_data *data, u8 reg)
751 mutex_unlock(&data->lock); 687 mutex_unlock(&data->lock);
752 return res; 688 return res;
753 } else 689 } else
690#endif
754 return i2c_smbus_read_byte_data(client, reg); 691 return i2c_smbus_read_byte_data(client, reg);
755} 692}
756 693
@@ -765,6 +702,7 @@ static int lm78_write_value(struct lm78_data *data, u8 reg, u8 value)
765{ 702{
766 struct i2c_client *client = data->client; 703 struct i2c_client *client = data->client;
767 704
705#ifdef CONFIG_ISA
768 if (!client) { /* ISA device */ 706 if (!client) { /* ISA device */
769 mutex_lock(&data->lock); 707 mutex_lock(&data->lock);
770 outb_p(reg, data->isa_addr + LM78_ADDR_REG_OFFSET); 708 outb_p(reg, data->isa_addr + LM78_ADDR_REG_OFFSET);
@@ -772,6 +710,7 @@ static int lm78_write_value(struct lm78_data *data, u8 reg, u8 value)
772 mutex_unlock(&data->lock); 710 mutex_unlock(&data->lock);
773 return 0; 711 return 0;
774 } else 712 } else
713#endif
775 return i2c_smbus_write_byte_data(client, reg, value); 714 return i2c_smbus_write_byte_data(client, reg, value);
776} 715}
777 716
@@ -849,6 +788,88 @@ static struct lm78_data *lm78_update_device(struct device *dev)
849 return data; 788 return data;
850} 789}
851 790
791#ifdef CONFIG_ISA
792static int __devinit lm78_isa_probe(struct platform_device *pdev)
793{
794 int err;
795 struct lm78_data *data;
796 struct resource *res;
797
798 /* Reserve the ISA region */
799 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
800 if (!request_region(res->start + LM78_ADDR_REG_OFFSET, 2, "lm78")) {
801 err = -EBUSY;
802 goto exit;
803 }
804
805 data = kzalloc(sizeof(struct lm78_data), GFP_KERNEL);
806 if (!data) {
807 err = -ENOMEM;
808 goto exit_release_region;
809 }
810 mutex_init(&data->lock);
811 data->isa_addr = res->start;
812 platform_set_drvdata(pdev, data);
813
814 if (lm78_read_value(data, LM78_REG_CHIPID) & 0x80) {
815 data->type = lm79;
816 data->name = "lm79";
817 } else {
818 data->type = lm78;
819 data->name = "lm78";
820 }
821
822 /* Initialize the LM78 chip */
823 lm78_init_device(data);
824
825 /* Register sysfs hooks */
826 if ((err = sysfs_create_group(&pdev->dev.kobj, &lm78_group))
827 || (err = device_create_file(&pdev->dev, &dev_attr_name)))
828 goto exit_remove_files;
829
830 data->hwmon_dev = hwmon_device_register(&pdev->dev);
831 if (IS_ERR(data->hwmon_dev)) {
832 err = PTR_ERR(data->hwmon_dev);
833 goto exit_remove_files;
834 }
835
836 return 0;
837
838 exit_remove_files:
839 sysfs_remove_group(&pdev->dev.kobj, &lm78_group);
840 device_remove_file(&pdev->dev, &dev_attr_name);
841 kfree(data);
842 exit_release_region:
843 release_region(res->start + LM78_ADDR_REG_OFFSET, 2);
844 exit:
845 return err;
846}
847
848static int __devexit lm78_isa_remove(struct platform_device *pdev)
849{
850 struct lm78_data *data = platform_get_drvdata(pdev);
851 struct resource *res;
852
853 hwmon_device_unregister(data->hwmon_dev);
854 sysfs_remove_group(&pdev->dev.kobj, &lm78_group);
855 device_remove_file(&pdev->dev, &dev_attr_name);
856 kfree(data);
857
858 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
859 release_region(res->start + LM78_ADDR_REG_OFFSET, 2);
860
861 return 0;
862}
863
864static struct platform_driver lm78_isa_driver = {
865 .driver = {
866 .owner = THIS_MODULE,
867 .name = "lm78",
868 },
869 .probe = lm78_isa_probe,
870 .remove = __devexit_p(lm78_isa_remove),
871};
872
852/* return 1 if a supported chip is found, 0 otherwise */ 873/* return 1 if a supported chip is found, 0 otherwise */
853static int __init lm78_isa_found(unsigned short address) 874static int __init lm78_isa_found(unsigned short address)
854{ 875{
@@ -969,12 +990,10 @@ static int __init lm78_isa_device_add(unsigned short address)
969 return err; 990 return err;
970} 991}
971 992
972static int __init sm_lm78_init(void) 993static int __init lm78_isa_register(void)
973{ 994{
974 int res; 995 int res;
975 996
976 /* We register the ISA device first, so that we can skip the
977 * registration of an I2C interface to the same device. */
978 if (lm78_isa_found(isa_address)) { 997 if (lm78_isa_found(isa_address)) {
979 res = platform_driver_register(&lm78_isa_driver); 998 res = platform_driver_register(&lm78_isa_driver);
980 if (res) 999 if (res)
@@ -986,32 +1005,62 @@ static int __init sm_lm78_init(void)
986 goto exit_unreg_isa_driver; 1005 goto exit_unreg_isa_driver;
987 } 1006 }
988 1007
989 res = i2c_add_driver(&lm78_driver);
990 if (res)
991 goto exit_unreg_isa_device;
992
993 return 0; 1008 return 0;
994 1009
995 exit_unreg_isa_device:
996 platform_device_unregister(pdev);
997 exit_unreg_isa_driver: 1010 exit_unreg_isa_driver:
998 platform_driver_unregister(&lm78_isa_driver); 1011 platform_driver_unregister(&lm78_isa_driver);
999 exit: 1012 exit:
1000 return res; 1013 return res;
1001} 1014}
1002 1015
1003static void __exit sm_lm78_exit(void) 1016static void lm78_isa_unregister(void)
1004{ 1017{
1005 if (pdev) { 1018 if (pdev) {
1006 platform_device_unregister(pdev); 1019 platform_device_unregister(pdev);
1007 platform_driver_unregister(&lm78_isa_driver); 1020 platform_driver_unregister(&lm78_isa_driver);
1008 } 1021 }
1009 i2c_del_driver(&lm78_driver);
1010} 1022}
1023#else /* !CONFIG_ISA */
1011 1024
1025static int __init lm78_isa_register(void)
1026{
1027 return 0;
1028}
1029
1030static void lm78_isa_unregister(void)
1031{
1032}
1033#endif /* CONFIG_ISA */
1012 1034
1035static int __init sm_lm78_init(void)
1036{
1037 int res;
1038
1039 /* We register the ISA device first, so that we can skip the
1040 * registration of an I2C interface to the same device. */
1041 res = lm78_isa_register();
1042 if (res)
1043 goto exit;
1044
1045 res = i2c_add_driver(&lm78_driver);
1046 if (res)
1047 goto exit_unreg_isa_device;
1048
1049 return 0;
1050
1051 exit_unreg_isa_device:
1052 lm78_isa_unregister();
1053 exit:
1054 return res;
1055}
1056
1057static void __exit sm_lm78_exit(void)
1058{
1059 lm78_isa_unregister();
1060 i2c_del_driver(&lm78_driver);
1061}
1013 1062
1014MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>"); 1063MODULE_AUTHOR("Frodo Looijaard, Jean Delvare <khali@linux-fr.org>");
1015MODULE_DESCRIPTION("LM78/LM79 driver"); 1064MODULE_DESCRIPTION("LM78/LM79 driver");
1016MODULE_LICENSE("GPL"); 1065MODULE_LICENSE("GPL");
1017 1066
diff --git a/drivers/hwmon/max1111.c b/drivers/hwmon/max1111.c
index 14335bbc9bdc..c97b78ef9116 100644
--- a/drivers/hwmon/max1111.c
+++ b/drivers/hwmon/max1111.c
@@ -38,8 +38,8 @@ struct max1111_data {
38 struct device *hwmon_dev; 38 struct device *hwmon_dev;
39 struct spi_message msg; 39 struct spi_message msg;
40 struct spi_transfer xfer[2]; 40 struct spi_transfer xfer[2];
41 uint8_t *tx_buf; 41 uint8_t tx_buf[MAX1111_TX_BUF_SIZE];
42 uint8_t *rx_buf; 42 uint8_t rx_buf[MAX1111_RX_BUF_SIZE];
43 struct mutex drvdata_lock; 43 struct mutex drvdata_lock;
44 /* protect msg, xfer and buffers from multiple access */ 44 /* protect msg, xfer and buffers from multiple access */
45}; 45};
@@ -131,33 +131,23 @@ static const struct attribute_group max1111_attr_group = {
131 .attrs = max1111_attributes, 131 .attrs = max1111_attributes,
132}; 132};
133 133
134static int setup_transfer(struct max1111_data *data) 134static int __devinit setup_transfer(struct max1111_data *data)
135{ 135{
136 struct spi_message *m; 136 struct spi_message *m;
137 struct spi_transfer *x; 137 struct spi_transfer *x;
138 138
139 data->tx_buf = kmalloc(MAX1111_TX_BUF_SIZE, GFP_KERNEL);
140 if (!data->tx_buf)
141 return -ENOMEM;
142
143 data->rx_buf = kmalloc(MAX1111_RX_BUF_SIZE, GFP_KERNEL);
144 if (!data->rx_buf) {
145 kfree(data->tx_buf);
146 return -ENOMEM;
147 }
148
149 m = &data->msg; 139 m = &data->msg;
150 x = &data->xfer[0]; 140 x = &data->xfer[0];
151 141
152 spi_message_init(m); 142 spi_message_init(m);
153 143
154 x->tx_buf = &data->tx_buf[0]; 144 x->tx_buf = &data->tx_buf[0];
155 x->len = 1; 145 x->len = MAX1111_TX_BUF_SIZE;
156 spi_message_add_tail(x, m); 146 spi_message_add_tail(x, m);
157 147
158 x++; 148 x++;
159 x->rx_buf = &data->rx_buf[0]; 149 x->rx_buf = &data->rx_buf[0];
160 x->len = 2; 150 x->len = MAX1111_RX_BUF_SIZE;
161 spi_message_add_tail(x, m); 151 spi_message_add_tail(x, m);
162 152
163 return 0; 153 return 0;
@@ -192,7 +182,7 @@ static int __devinit max1111_probe(struct spi_device *spi)
192 err = sysfs_create_group(&spi->dev.kobj, &max1111_attr_group); 182 err = sysfs_create_group(&spi->dev.kobj, &max1111_attr_group);
193 if (err) { 183 if (err) {
194 dev_err(&spi->dev, "failed to create attribute group\n"); 184 dev_err(&spi->dev, "failed to create attribute group\n");
195 goto err_free_all; 185 goto err_free_data;
196 } 186 }
197 187
198 data->hwmon_dev = hwmon_device_register(&spi->dev); 188 data->hwmon_dev = hwmon_device_register(&spi->dev);
@@ -209,9 +199,6 @@ static int __devinit max1111_probe(struct spi_device *spi)
209 199
210err_remove: 200err_remove:
211 sysfs_remove_group(&spi->dev.kobj, &max1111_attr_group); 201 sysfs_remove_group(&spi->dev.kobj, &max1111_attr_group);
212err_free_all:
213 kfree(data->rx_buf);
214 kfree(data->tx_buf);
215err_free_data: 202err_free_data:
216 kfree(data); 203 kfree(data);
217 return err; 204 return err;
@@ -224,8 +211,6 @@ static int __devexit max1111_remove(struct spi_device *spi)
224 hwmon_device_unregister(data->hwmon_dev); 211 hwmon_device_unregister(data->hwmon_dev);
225 sysfs_remove_group(&spi->dev.kobj, &max1111_attr_group); 212 sysfs_remove_group(&spi->dev.kobj, &max1111_attr_group);
226 mutex_destroy(&data->drvdata_lock); 213 mutex_destroy(&data->drvdata_lock);
227 kfree(data->rx_buf);
228 kfree(data->tx_buf);
229 kfree(data); 214 kfree(data);
230 return 0; 215 return 0;
231} 216}
diff --git a/drivers/hwmon/sch5627.c b/drivers/hwmon/sch5627.c
index 3494a4cce414..e3b5c6039c25 100644
--- a/drivers/hwmon/sch5627.c
+++ b/drivers/hwmon/sch5627.c
@@ -28,33 +28,15 @@
28#include <linux/hwmon-sysfs.h> 28#include <linux/hwmon-sysfs.h>
29#include <linux/err.h> 29#include <linux/err.h>
30#include <linux/mutex.h> 30#include <linux/mutex.h>
31#include <linux/io.h> 31#include "sch56xx-common.h"
32#include <linux/acpi.h>
33#include <linux/delay.h>
34 32
35#define DRVNAME "sch5627" 33#define DRVNAME "sch5627"
36#define DEVNAME DRVNAME /* We only support one model */ 34#define DEVNAME DRVNAME /* We only support one model */
37 35
38#define SIO_SCH5627_EM_LD 0x0C /* Embedded Microcontroller LD */
39#define SIO_UNLOCK_KEY 0x55 /* Key to enable Super-I/O */
40#define SIO_LOCK_KEY 0xAA /* Key to disable Super-I/O */
41
42#define SIO_REG_LDSEL 0x07 /* Logical device select */
43#define SIO_REG_DEVID 0x20 /* Device ID */
44#define SIO_REG_ENABLE 0x30 /* Logical device enable */
45#define SIO_REG_ADDR 0x66 /* Logical device address (2 bytes) */
46
47#define SIO_SCH5627_ID 0xC6 /* Chipset ID */
48
49#define REGION_LENGTH 9
50
51#define SCH5627_HWMON_ID 0xa5 36#define SCH5627_HWMON_ID 0xa5
52#define SCH5627_COMPANY_ID 0x5c 37#define SCH5627_COMPANY_ID 0x5c
53#define SCH5627_PRIMARY_ID 0xa0 38#define SCH5627_PRIMARY_ID 0xa0
54 39
55#define SCH5627_CMD_READ 0x02
56#define SCH5627_CMD_WRITE 0x03
57
58#define SCH5627_REG_BUILD_CODE 0x39 40#define SCH5627_REG_BUILD_CODE 0x39
59#define SCH5627_REG_BUILD_ID 0x3a 41#define SCH5627_REG_BUILD_ID 0x3a
60#define SCH5627_REG_HWMON_ID 0x3c 42#define SCH5627_REG_HWMON_ID 0x3c
@@ -111,182 +93,6 @@ struct sch5627_data {
111 u16 in[SCH5627_NO_IN]; 93 u16 in[SCH5627_NO_IN];
112}; 94};
113 95
114static struct platform_device *sch5627_pdev;
115
116/* Super I/O functions */
117static inline int superio_inb(int base, int reg)
118{
119 outb(reg, base);
120 return inb(base + 1);
121}
122
123static inline int superio_enter(int base)
124{
125 /* Don't step on other drivers' I/O space by accident */
126 if (!request_muxed_region(base, 2, DRVNAME)) {
127 pr_err("I/O address 0x%04x already in use\n", base);
128 return -EBUSY;
129 }
130
131 outb(SIO_UNLOCK_KEY, base);
132
133 return 0;
134}
135
136static inline void superio_select(int base, int ld)
137{
138 outb(SIO_REG_LDSEL, base);
139 outb(ld, base + 1);
140}
141
142static inline void superio_exit(int base)
143{
144 outb(SIO_LOCK_KEY, base);
145 release_region(base, 2);
146}
147
148static int sch5627_send_cmd(struct sch5627_data *data, u8 cmd, u16 reg, u8 v)
149{
150 u8 val;
151 int i;
152 /*
153 * According to SMSC for the commands we use the maximum time for
154 * the EM to respond is 15 ms, but testing shows in practice it
155 * responds within 15-32 reads, so we first busy poll, and if
156 * that fails sleep a bit and try again until we are way past
157 * the 15 ms maximum response time.
158 */
159 const int max_busy_polls = 64;
160 const int max_lazy_polls = 32;
161
162 /* (Optional) Write-Clear the EC to Host Mailbox Register */
163 val = inb(data->addr + 1);
164 outb(val, data->addr + 1);
165
166 /* Set Mailbox Address Pointer to first location in Region 1 */
167 outb(0x00, data->addr + 2);
168 outb(0x80, data->addr + 3);
169
170 /* Write Request Packet Header */
171 outb(cmd, data->addr + 4); /* VREG Access Type read:0x02 write:0x03 */
172 outb(0x01, data->addr + 5); /* # of Entries: 1 Byte (8-bit) */
173 outb(0x04, data->addr + 2); /* Mailbox AP to first data entry loc. */
174
175 /* Write Value field */
176 if (cmd == SCH5627_CMD_WRITE)
177 outb(v, data->addr + 4);
178
179 /* Write Address field */
180 outb(reg & 0xff, data->addr + 6);
181 outb(reg >> 8, data->addr + 7);
182
183 /* Execute the Random Access Command */
184 outb(0x01, data->addr); /* Write 01h to the Host-to-EC register */
185
186 /* EM Interface Polling "Algorithm" */
187 for (i = 0; i < max_busy_polls + max_lazy_polls; i++) {
188 if (i >= max_busy_polls)
189 msleep(1);
190 /* Read Interrupt source Register */
191 val = inb(data->addr + 8);
192 /* Write Clear the interrupt source bits */
193 if (val)
194 outb(val, data->addr + 8);
195 /* Command Completed ? */
196 if (val & 0x01)
197 break;
198 }
199 if (i == max_busy_polls + max_lazy_polls) {
200 pr_err("Max retries exceeded reading virtual "
201 "register 0x%04hx (%d)\n", reg, 1);
202 return -EIO;
203 }
204
205 /*
206 * According to SMSC we may need to retry this, but sofar I've always
207 * seen this succeed in 1 try.
208 */
209 for (i = 0; i < max_busy_polls; i++) {
210 /* Read EC-to-Host Register */
211 val = inb(data->addr + 1);
212 /* Command Completed ? */
213 if (val == 0x01)
214 break;
215
216 if (i == 0)
217 pr_warn("EC reports: 0x%02x reading virtual register "
218 "0x%04hx\n", (unsigned int)val, reg);
219 }
220 if (i == max_busy_polls) {
221 pr_err("Max retries exceeded reading virtual "
222 "register 0x%04hx (%d)\n", reg, 2);
223 return -EIO;
224 }
225
226 /*
227 * According to the SMSC app note we should now do:
228 *
229 * Set Mailbox Address Pointer to first location in Region 1 *
230 * outb(0x00, data->addr + 2);
231 * outb(0x80, data->addr + 3);
232 *
233 * But if we do that things don't work, so let's not.
234 */
235
236 /* Read Value field */
237 if (cmd == SCH5627_CMD_READ)
238 return inb(data->addr + 4);
239
240 return 0;
241}
242
243static int sch5627_read_virtual_reg(struct sch5627_data *data, u16 reg)
244{
245 return sch5627_send_cmd(data, SCH5627_CMD_READ, reg, 0);
246}
247
248static int sch5627_write_virtual_reg(struct sch5627_data *data,
249 u16 reg, u8 val)
250{
251 return sch5627_send_cmd(data, SCH5627_CMD_WRITE, reg, val);
252}
253
254static int sch5627_read_virtual_reg16(struct sch5627_data *data, u16 reg)
255{
256 int lsb, msb;
257
258 /* Read LSB first, this will cause the matching MSB to be latched */
259 lsb = sch5627_read_virtual_reg(data, reg);
260 if (lsb < 0)
261 return lsb;
262
263 msb = sch5627_read_virtual_reg(data, reg + 1);
264 if (msb < 0)
265 return msb;
266
267 return lsb | (msb << 8);
268}
269
270static int sch5627_read_virtual_reg12(struct sch5627_data *data, u16 msb_reg,
271 u16 lsn_reg, int high_nibble)
272{
273 int msb, lsn;
274
275 /* Read MSB first, this will cause the matching LSN to be latched */
276 msb = sch5627_read_virtual_reg(data, msb_reg);
277 if (msb < 0)
278 return msb;
279
280 lsn = sch5627_read_virtual_reg(data, lsn_reg);
281 if (lsn < 0)
282 return lsn;
283
284 if (high_nibble)
285 return (msb << 4) | (lsn >> 4);
286 else
287 return (msb << 4) | (lsn & 0x0f);
288}
289
290static struct sch5627_data *sch5627_update_device(struct device *dev) 96static struct sch5627_data *sch5627_update_device(struct device *dev)
291{ 97{
292 struct sch5627_data *data = dev_get_drvdata(dev); 98 struct sch5627_data *data = dev_get_drvdata(dev);
@@ -297,7 +103,7 @@ static struct sch5627_data *sch5627_update_device(struct device *dev)
297 103
298 /* Trigger a Vbat voltage measurement every 5 minutes */ 104 /* Trigger a Vbat voltage measurement every 5 minutes */
299 if (time_after(jiffies, data->last_battery + 300 * HZ)) { 105 if (time_after(jiffies, data->last_battery + 300 * HZ)) {
300 sch5627_write_virtual_reg(data, SCH5627_REG_CTRL, 106 sch56xx_write_virtual_reg(data->addr, SCH5627_REG_CTRL,
301 data->control | 0x10); 107 data->control | 0x10);
302 data->last_battery = jiffies; 108 data->last_battery = jiffies;
303 } 109 }
@@ -305,7 +111,7 @@ static struct sch5627_data *sch5627_update_device(struct device *dev)
305 /* Cache the values for 1 second */ 111 /* Cache the values for 1 second */
306 if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { 112 if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
307 for (i = 0; i < SCH5627_NO_TEMPS; i++) { 113 for (i = 0; i < SCH5627_NO_TEMPS; i++) {
308 val = sch5627_read_virtual_reg12(data, 114 val = sch56xx_read_virtual_reg12(data->addr,
309 SCH5627_REG_TEMP_MSB[i], 115 SCH5627_REG_TEMP_MSB[i],
310 SCH5627_REG_TEMP_LSN[i], 116 SCH5627_REG_TEMP_LSN[i],
311 SCH5627_REG_TEMP_HIGH_NIBBLE[i]); 117 SCH5627_REG_TEMP_HIGH_NIBBLE[i]);
@@ -317,7 +123,7 @@ static struct sch5627_data *sch5627_update_device(struct device *dev)
317 } 123 }
318 124
319 for (i = 0; i < SCH5627_NO_FANS; i++) { 125 for (i = 0; i < SCH5627_NO_FANS; i++) {
320 val = sch5627_read_virtual_reg16(data, 126 val = sch56xx_read_virtual_reg16(data->addr,
321 SCH5627_REG_FAN[i]); 127 SCH5627_REG_FAN[i]);
322 if (unlikely(val < 0)) { 128 if (unlikely(val < 0)) {
323 ret = ERR_PTR(val); 129 ret = ERR_PTR(val);
@@ -327,7 +133,7 @@ static struct sch5627_data *sch5627_update_device(struct device *dev)
327 } 133 }
328 134
329 for (i = 0; i < SCH5627_NO_IN; i++) { 135 for (i = 0; i < SCH5627_NO_IN; i++) {
330 val = sch5627_read_virtual_reg12(data, 136 val = sch56xx_read_virtual_reg12(data->addr,
331 SCH5627_REG_IN_MSB[i], 137 SCH5627_REG_IN_MSB[i],
332 SCH5627_REG_IN_LSN[i], 138 SCH5627_REG_IN_LSN[i],
333 SCH5627_REG_IN_HIGH_NIBBLE[i]); 139 SCH5627_REG_IN_HIGH_NIBBLE[i]);
@@ -355,18 +161,21 @@ static int __devinit sch5627_read_limits(struct sch5627_data *data)
355 * Note what SMSC calls ABS, is what lm_sensors calls max 161 * Note what SMSC calls ABS, is what lm_sensors calls max
356 * (aka high), and HIGH is what lm_sensors calls crit. 162 * (aka high), and HIGH is what lm_sensors calls crit.
357 */ 163 */
358 val = sch5627_read_virtual_reg(data, SCH5627_REG_TEMP_ABS[i]); 164 val = sch56xx_read_virtual_reg(data->addr,
165 SCH5627_REG_TEMP_ABS[i]);
359 if (val < 0) 166 if (val < 0)
360 return val; 167 return val;
361 data->temp_max[i] = val; 168 data->temp_max[i] = val;
362 169
363 val = sch5627_read_virtual_reg(data, SCH5627_REG_TEMP_HIGH[i]); 170 val = sch56xx_read_virtual_reg(data->addr,
171 SCH5627_REG_TEMP_HIGH[i]);
364 if (val < 0) 172 if (val < 0)
365 return val; 173 return val;
366 data->temp_crit[i] = val; 174 data->temp_crit[i] = val;
367 } 175 }
368 for (i = 0; i < SCH5627_NO_FANS; i++) { 176 for (i = 0; i < SCH5627_NO_FANS; i++) {
369 val = sch5627_read_virtual_reg16(data, SCH5627_REG_FAN_MIN[i]); 177 val = sch56xx_read_virtual_reg16(data->addr,
178 SCH5627_REG_FAN_MIN[i]);
370 if (val < 0) 179 if (val < 0)
371 return val; 180 return val;
372 data->fan_min[i] = val; 181 data->fan_min[i] = val;
@@ -667,7 +476,7 @@ static int __devinit sch5627_probe(struct platform_device *pdev)
667 mutex_init(&data->update_lock); 476 mutex_init(&data->update_lock);
668 platform_set_drvdata(pdev, data); 477 platform_set_drvdata(pdev, data);
669 478
670 val = sch5627_read_virtual_reg(data, SCH5627_REG_HWMON_ID); 479 val = sch56xx_read_virtual_reg(data->addr, SCH5627_REG_HWMON_ID);
671 if (val < 0) { 480 if (val < 0) {
672 err = val; 481 err = val;
673 goto error; 482 goto error;
@@ -679,7 +488,7 @@ static int __devinit sch5627_probe(struct platform_device *pdev)
679 goto error; 488 goto error;
680 } 489 }
681 490
682 val = sch5627_read_virtual_reg(data, SCH5627_REG_COMPANY_ID); 491 val = sch56xx_read_virtual_reg(data->addr, SCH5627_REG_COMPANY_ID);
683 if (val < 0) { 492 if (val < 0) {
684 err = val; 493 err = val;
685 goto error; 494 goto error;
@@ -691,7 +500,7 @@ static int __devinit sch5627_probe(struct platform_device *pdev)
691 goto error; 500 goto error;
692 } 501 }
693 502
694 val = sch5627_read_virtual_reg(data, SCH5627_REG_PRIMARY_ID); 503 val = sch56xx_read_virtual_reg(data->addr, SCH5627_REG_PRIMARY_ID);
695 if (val < 0) { 504 if (val < 0) {
696 err = val; 505 err = val;
697 goto error; 506 goto error;
@@ -703,25 +512,28 @@ static int __devinit sch5627_probe(struct platform_device *pdev)
703 goto error; 512 goto error;
704 } 513 }
705 514
706 build_code = sch5627_read_virtual_reg(data, SCH5627_REG_BUILD_CODE); 515 build_code = sch56xx_read_virtual_reg(data->addr,
516 SCH5627_REG_BUILD_CODE);
707 if (build_code < 0) { 517 if (build_code < 0) {
708 err = build_code; 518 err = build_code;
709 goto error; 519 goto error;
710 } 520 }
711 521
712 build_id = sch5627_read_virtual_reg16(data, SCH5627_REG_BUILD_ID); 522 build_id = sch56xx_read_virtual_reg16(data->addr,
523 SCH5627_REG_BUILD_ID);
713 if (build_id < 0) { 524 if (build_id < 0) {
714 err = build_id; 525 err = build_id;
715 goto error; 526 goto error;
716 } 527 }
717 528
718 hwmon_rev = sch5627_read_virtual_reg(data, SCH5627_REG_HWMON_REV); 529 hwmon_rev = sch56xx_read_virtual_reg(data->addr,
530 SCH5627_REG_HWMON_REV);
719 if (hwmon_rev < 0) { 531 if (hwmon_rev < 0) {
720 err = hwmon_rev; 532 err = hwmon_rev;
721 goto error; 533 goto error;
722 } 534 }
723 535
724 val = sch5627_read_virtual_reg(data, SCH5627_REG_CTRL); 536 val = sch56xx_read_virtual_reg(data->addr, SCH5627_REG_CTRL);
725 if (val < 0) { 537 if (val < 0) {
726 err = val; 538 err = val;
727 goto error; 539 goto error;
@@ -734,7 +546,7 @@ static int __devinit sch5627_probe(struct platform_device *pdev)
734 } 546 }
735 /* Trigger a Vbat voltage measurement, so that we get a valid reading 547 /* Trigger a Vbat voltage measurement, so that we get a valid reading
736 the first time we read Vbat */ 548 the first time we read Vbat */
737 sch5627_write_virtual_reg(data, SCH5627_REG_CTRL, 549 sch56xx_write_virtual_reg(data->addr, SCH5627_REG_CTRL,
738 data->control | 0x10); 550 data->control | 0x10);
739 data->last_battery = jiffies; 551 data->last_battery = jiffies;
740 552
@@ -746,6 +558,7 @@ static int __devinit sch5627_probe(struct platform_device *pdev)
746 if (err) 558 if (err)
747 goto error; 559 goto error;
748 560
561 pr_info("found %s chip at %#hx\n", DEVNAME, data->addr);
749 pr_info("firmware build: code 0x%02X, id 0x%04X, hwmon: rev 0x%02X\n", 562 pr_info("firmware build: code 0x%02X, id 0x%04X, hwmon: rev 0x%02X\n",
750 build_code, build_id, hwmon_rev); 563 build_code, build_id, hwmon_rev);
751 564
@@ -768,85 +581,6 @@ error:
768 return err; 581 return err;
769} 582}
770 583
771static int __init sch5627_find(int sioaddr, unsigned short *address)
772{
773 u8 devid;
774 int err = superio_enter(sioaddr);
775 if (err)
776 return err;
777
778 devid = superio_inb(sioaddr, SIO_REG_DEVID);
779 if (devid != SIO_SCH5627_ID) {
780 pr_debug("Unsupported device id: 0x%02x\n",
781 (unsigned int)devid);
782 err = -ENODEV;
783 goto exit;
784 }
785
786 superio_select(sioaddr, SIO_SCH5627_EM_LD);
787
788 if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) {
789 pr_warn("Device not activated\n");
790 err = -ENODEV;
791 goto exit;
792 }
793
794 /*
795 * Warning the order of the low / high byte is the other way around
796 * as on most other superio devices!!
797 */
798 *address = superio_inb(sioaddr, SIO_REG_ADDR) |
799 superio_inb(sioaddr, SIO_REG_ADDR + 1) << 8;
800 if (*address == 0) {
801 pr_warn("Base address not set\n");
802 err = -ENODEV;
803 goto exit;
804 }
805
806 pr_info("Found %s chip at %#hx\n", DEVNAME, *address);
807exit:
808 superio_exit(sioaddr);
809 return err;
810}
811
812static int __init sch5627_device_add(unsigned short address)
813{
814 struct resource res = {
815 .start = address,
816 .end = address + REGION_LENGTH - 1,
817 .flags = IORESOURCE_IO,
818 };
819 int err;
820
821 sch5627_pdev = platform_device_alloc(DRVNAME, address);
822 if (!sch5627_pdev)
823 return -ENOMEM;
824
825 res.name = sch5627_pdev->name;
826 err = acpi_check_resource_conflict(&res);
827 if (err)
828 goto exit_device_put;
829
830 err = platform_device_add_resources(sch5627_pdev, &res, 1);
831 if (err) {
832 pr_err("Device resource addition failed\n");
833 goto exit_device_put;
834 }
835
836 err = platform_device_add(sch5627_pdev);
837 if (err) {
838 pr_err("Device addition failed\n");
839 goto exit_device_put;
840 }
841
842 return 0;
843
844exit_device_put:
845 platform_device_put(sch5627_pdev);
846
847 return err;
848}
849
850static struct platform_driver sch5627_driver = { 584static struct platform_driver sch5627_driver = {
851 .driver = { 585 .driver = {
852 .owner = THIS_MODULE, 586 .owner = THIS_MODULE,
@@ -858,31 +592,11 @@ static struct platform_driver sch5627_driver = {
858 592
859static int __init sch5627_init(void) 593static int __init sch5627_init(void)
860{ 594{
861 int err = -ENODEV; 595 return platform_driver_register(&sch5627_driver);
862 unsigned short address;
863
864 if (sch5627_find(0x4e, &address) && sch5627_find(0x2e, &address))
865 goto exit;
866
867 err = platform_driver_register(&sch5627_driver);
868 if (err)
869 goto exit;
870
871 err = sch5627_device_add(address);
872 if (err)
873 goto exit_driver;
874
875 return 0;
876
877exit_driver:
878 platform_driver_unregister(&sch5627_driver);
879exit:
880 return err;
881} 596}
882 597
883static void __exit sch5627_exit(void) 598static void __exit sch5627_exit(void)
884{ 599{
885 platform_device_unregister(sch5627_pdev);
886 platform_driver_unregister(&sch5627_driver); 600 platform_driver_unregister(&sch5627_driver);
887} 601}
888 602
diff --git a/drivers/hwmon/sch5636.c b/drivers/hwmon/sch5636.c
new file mode 100644
index 000000000000..244407aa79fc
--- /dev/null
+++ b/drivers/hwmon/sch5636.c
@@ -0,0 +1,539 @@
1/***************************************************************************
2 * Copyright (C) 2011 Hans de Goede <hdegoede@redhat.com> *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
18 ***************************************************************************/
19
20#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
21
22#include <linux/module.h>
23#include <linux/init.h>
24#include <linux/slab.h>
25#include <linux/jiffies.h>
26#include <linux/platform_device.h>
27#include <linux/hwmon.h>
28#include <linux/hwmon-sysfs.h>
29#include <linux/err.h>
30#include <linux/mutex.h>
31#include "sch56xx-common.h"
32
33#define DRVNAME "sch5636"
34#define DEVNAME "theseus" /* We only support one model for now */
35
36#define SCH5636_REG_FUJITSU_ID 0x780
37#define SCH5636_REG_FUJITSU_REV 0x783
38
39#define SCH5636_NO_INS 5
40#define SCH5636_NO_TEMPS 16
41#define SCH5636_NO_FANS 8
42
43static const u16 SCH5636_REG_IN_VAL[SCH5636_NO_INS] = {
44 0x22, 0x23, 0x24, 0x25, 0x189 };
45static const u16 SCH5636_REG_IN_FACTORS[SCH5636_NO_INS] = {
46 4400, 1500, 4000, 4400, 16000 };
47static const char * const SCH5636_IN_LABELS[SCH5636_NO_INS] = {
48 "3.3V", "VREF", "VBAT", "3.3AUX", "12V" };
49
50static const u16 SCH5636_REG_TEMP_VAL[SCH5636_NO_TEMPS] = {
51 0x2B, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x180, 0x181,
52 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C };
53#define SCH5636_REG_TEMP_CTRL(i) (0x790 + (i))
54#define SCH5636_TEMP_WORKING 0x01
55#define SCH5636_TEMP_ALARM 0x02
56#define SCH5636_TEMP_DEACTIVATED 0x80
57
58static const u16 SCH5636_REG_FAN_VAL[SCH5636_NO_FANS] = {
59 0x2C, 0x2E, 0x30, 0x32, 0x62, 0x64, 0x66, 0x68 };
60#define SCH5636_REG_FAN_CTRL(i) (0x880 + (i))
61/* FAULT in datasheet, but acts as an alarm */
62#define SCH5636_FAN_ALARM 0x04
63#define SCH5636_FAN_NOT_PRESENT 0x08
64#define SCH5636_FAN_DEACTIVATED 0x80
65
66
67struct sch5636_data {
68 unsigned short addr;
69 struct device *hwmon_dev;
70
71 struct mutex update_lock;
72 char valid; /* !=0 if following fields are valid */
73 unsigned long last_updated; /* In jiffies */
74 u8 in[SCH5636_NO_INS];
75 u8 temp_val[SCH5636_NO_TEMPS];
76 u8 temp_ctrl[SCH5636_NO_TEMPS];
77 u16 fan_val[SCH5636_NO_FANS];
78 u8 fan_ctrl[SCH5636_NO_FANS];
79};
80
81static struct sch5636_data *sch5636_update_device(struct device *dev)
82{
83 struct sch5636_data *data = dev_get_drvdata(dev);
84 struct sch5636_data *ret = data;
85 int i, val;
86
87 mutex_lock(&data->update_lock);
88
89 /* Cache the values for 1 second */
90 if (data->valid && !time_after(jiffies, data->last_updated + HZ))
91 goto abort;
92
93 for (i = 0; i < SCH5636_NO_INS; i++) {
94 val = sch56xx_read_virtual_reg(data->addr,
95 SCH5636_REG_IN_VAL[i]);
96 if (unlikely(val < 0)) {
97 ret = ERR_PTR(val);
98 goto abort;
99 }
100 data->in[i] = val;
101 }
102
103 for (i = 0; i < SCH5636_NO_TEMPS; i++) {
104 if (data->temp_ctrl[i] & SCH5636_TEMP_DEACTIVATED)
105 continue;
106
107 val = sch56xx_read_virtual_reg(data->addr,
108 SCH5636_REG_TEMP_VAL[i]);
109 if (unlikely(val < 0)) {
110 ret = ERR_PTR(val);
111 goto abort;
112 }
113 data->temp_val[i] = val;
114
115 val = sch56xx_read_virtual_reg(data->addr,
116 SCH5636_REG_TEMP_CTRL(i));
117 if (unlikely(val < 0)) {
118 ret = ERR_PTR(val);
119 goto abort;
120 }
121 data->temp_ctrl[i] = val;
122 /* Alarms need to be explicitly write-cleared */
123 if (val & SCH5636_TEMP_ALARM) {
124 sch56xx_write_virtual_reg(data->addr,
125 SCH5636_REG_TEMP_CTRL(i), val);
126 }
127 }
128
129 for (i = 0; i < SCH5636_NO_FANS; i++) {
130 if (data->fan_ctrl[i] & SCH5636_FAN_DEACTIVATED)
131 continue;
132
133 val = sch56xx_read_virtual_reg16(data->addr,
134 SCH5636_REG_FAN_VAL[i]);
135 if (unlikely(val < 0)) {
136 ret = ERR_PTR(val);
137 goto abort;
138 }
139 data->fan_val[i] = val;
140
141 val = sch56xx_read_virtual_reg(data->addr,
142 SCH5636_REG_FAN_CTRL(i));
143 if (unlikely(val < 0)) {
144 ret = ERR_PTR(val);
145 goto abort;
146 }
147 data->fan_ctrl[i] = val;
148 /* Alarms need to be explicitly write-cleared */
149 if (val & SCH5636_FAN_ALARM) {
150 sch56xx_write_virtual_reg(data->addr,
151 SCH5636_REG_FAN_CTRL(i), val);
152 }
153 }
154
155 data->last_updated = jiffies;
156 data->valid = 1;
157abort:
158 mutex_unlock(&data->update_lock);
159 return ret;
160}
161
162static int reg_to_rpm(u16 reg)
163{
164 if (reg == 0)
165 return -EIO;
166 if (reg == 0xffff)
167 return 0;
168
169 return 5400540 / reg;
170}
171
172static ssize_t show_name(struct device *dev, struct device_attribute *devattr,
173 char *buf)
174{
175 return snprintf(buf, PAGE_SIZE, "%s\n", DEVNAME);
176}
177
178static ssize_t show_in_value(struct device *dev, struct device_attribute
179 *devattr, char *buf)
180{
181 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
182 struct sch5636_data *data = sch5636_update_device(dev);
183 int val;
184
185 if (IS_ERR(data))
186 return PTR_ERR(data);
187
188 val = DIV_ROUND_CLOSEST(
189 data->in[attr->index] * SCH5636_REG_IN_FACTORS[attr->index],
190 255);
191 return snprintf(buf, PAGE_SIZE, "%d\n", val);
192}
193
194static ssize_t show_in_label(struct device *dev, struct device_attribute
195 *devattr, char *buf)
196{
197 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
198
199 return snprintf(buf, PAGE_SIZE, "%s\n",
200 SCH5636_IN_LABELS[attr->index]);
201}
202
203static ssize_t show_temp_value(struct device *dev, struct device_attribute
204 *devattr, char *buf)
205{
206 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
207 struct sch5636_data *data = sch5636_update_device(dev);
208 int val;
209
210 if (IS_ERR(data))
211 return PTR_ERR(data);
212
213 val = (data->temp_val[attr->index] - 64) * 1000;
214 return snprintf(buf, PAGE_SIZE, "%d\n", val);
215}
216
217static ssize_t show_temp_fault(struct device *dev, struct device_attribute
218 *devattr, char *buf)
219{
220 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
221 struct sch5636_data *data = sch5636_update_device(dev);
222 int val;
223
224 if (IS_ERR(data))
225 return PTR_ERR(data);
226
227 val = (data->temp_ctrl[attr->index] & SCH5636_TEMP_WORKING) ? 0 : 1;
228 return snprintf(buf, PAGE_SIZE, "%d\n", val);
229}
230
231static ssize_t show_temp_alarm(struct device *dev, struct device_attribute
232 *devattr, char *buf)
233{
234 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
235 struct sch5636_data *data = sch5636_update_device(dev);
236 int val;
237
238 if (IS_ERR(data))
239 return PTR_ERR(data);
240
241 val = (data->temp_ctrl[attr->index] & SCH5636_TEMP_ALARM) ? 1 : 0;
242 return snprintf(buf, PAGE_SIZE, "%d\n", val);
243}
244
245static ssize_t show_fan_value(struct device *dev, struct device_attribute
246 *devattr, char *buf)
247{
248 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
249 struct sch5636_data *data = sch5636_update_device(dev);
250 int val;
251
252 if (IS_ERR(data))
253 return PTR_ERR(data);
254
255 val = reg_to_rpm(data->fan_val[attr->index]);
256 if (val < 0)
257 return val;
258
259 return snprintf(buf, PAGE_SIZE, "%d\n", val);
260}
261
262static ssize_t show_fan_fault(struct device *dev, struct device_attribute
263 *devattr, char *buf)
264{
265 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
266 struct sch5636_data *data = sch5636_update_device(dev);
267 int val;
268
269 if (IS_ERR(data))
270 return PTR_ERR(data);
271
272 val = (data->fan_ctrl[attr->index] & SCH5636_FAN_NOT_PRESENT) ? 1 : 0;
273 return snprintf(buf, PAGE_SIZE, "%d\n", val);
274}
275
276static ssize_t show_fan_alarm(struct device *dev, struct device_attribute
277 *devattr, char *buf)
278{
279 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
280 struct sch5636_data *data = sch5636_update_device(dev);
281 int val;
282
283 if (IS_ERR(data))
284 return PTR_ERR(data);
285
286 val = (data->fan_ctrl[attr->index] & SCH5636_FAN_ALARM) ? 1 : 0;
287 return snprintf(buf, PAGE_SIZE, "%d\n", val);
288}
289
290static struct sensor_device_attribute sch5636_attr[] = {
291 SENSOR_ATTR(name, 0444, show_name, NULL, 0),
292 SENSOR_ATTR(in0_input, 0444, show_in_value, NULL, 0),
293 SENSOR_ATTR(in0_label, 0444, show_in_label, NULL, 0),
294 SENSOR_ATTR(in1_input, 0444, show_in_value, NULL, 1),
295 SENSOR_ATTR(in1_label, 0444, show_in_label, NULL, 1),
296 SENSOR_ATTR(in2_input, 0444, show_in_value, NULL, 2),
297 SENSOR_ATTR(in2_label, 0444, show_in_label, NULL, 2),
298 SENSOR_ATTR(in3_input, 0444, show_in_value, NULL, 3),
299 SENSOR_ATTR(in3_label, 0444, show_in_label, NULL, 3),
300 SENSOR_ATTR(in4_input, 0444, show_in_value, NULL, 4),
301 SENSOR_ATTR(in4_label, 0444, show_in_label, NULL, 4),
302};
303
304static struct sensor_device_attribute sch5636_temp_attr[] = {
305 SENSOR_ATTR(temp1_input, 0444, show_temp_value, NULL, 0),
306 SENSOR_ATTR(temp1_fault, 0444, show_temp_fault, NULL, 0),
307 SENSOR_ATTR(temp1_alarm, 0444, show_temp_alarm, NULL, 0),
308 SENSOR_ATTR(temp2_input, 0444, show_temp_value, NULL, 1),
309 SENSOR_ATTR(temp2_fault, 0444, show_temp_fault, NULL, 1),
310 SENSOR_ATTR(temp2_alarm, 0444, show_temp_alarm, NULL, 1),
311 SENSOR_ATTR(temp3_input, 0444, show_temp_value, NULL, 2),
312 SENSOR_ATTR(temp3_fault, 0444, show_temp_fault, NULL, 2),
313 SENSOR_ATTR(temp3_alarm, 0444, show_temp_alarm, NULL, 2),
314 SENSOR_ATTR(temp4_input, 0444, show_temp_value, NULL, 3),
315 SENSOR_ATTR(temp4_fault, 0444, show_temp_fault, NULL, 3),
316 SENSOR_ATTR(temp4_alarm, 0444, show_temp_alarm, NULL, 3),
317 SENSOR_ATTR(temp5_input, 0444, show_temp_value, NULL, 4),
318 SENSOR_ATTR(temp5_fault, 0444, show_temp_fault, NULL, 4),
319 SENSOR_ATTR(temp5_alarm, 0444, show_temp_alarm, NULL, 4),
320 SENSOR_ATTR(temp6_input, 0444, show_temp_value, NULL, 5),
321 SENSOR_ATTR(temp6_fault, 0444, show_temp_fault, NULL, 5),
322 SENSOR_ATTR(temp6_alarm, 0444, show_temp_alarm, NULL, 5),
323 SENSOR_ATTR(temp7_input, 0444, show_temp_value, NULL, 6),
324 SENSOR_ATTR(temp7_fault, 0444, show_temp_fault, NULL, 6),
325 SENSOR_ATTR(temp7_alarm, 0444, show_temp_alarm, NULL, 6),
326 SENSOR_ATTR(temp8_input, 0444, show_temp_value, NULL, 7),
327 SENSOR_ATTR(temp8_fault, 0444, show_temp_fault, NULL, 7),
328 SENSOR_ATTR(temp8_alarm, 0444, show_temp_alarm, NULL, 7),
329 SENSOR_ATTR(temp9_input, 0444, show_temp_value, NULL, 8),
330 SENSOR_ATTR(temp9_fault, 0444, show_temp_fault, NULL, 8),
331 SENSOR_ATTR(temp9_alarm, 0444, show_temp_alarm, NULL, 8),
332 SENSOR_ATTR(temp10_input, 0444, show_temp_value, NULL, 9),
333 SENSOR_ATTR(temp10_fault, 0444, show_temp_fault, NULL, 9),
334 SENSOR_ATTR(temp10_alarm, 0444, show_temp_alarm, NULL, 9),
335 SENSOR_ATTR(temp11_input, 0444, show_temp_value, NULL, 10),
336 SENSOR_ATTR(temp11_fault, 0444, show_temp_fault, NULL, 10),
337 SENSOR_ATTR(temp11_alarm, 0444, show_temp_alarm, NULL, 10),
338 SENSOR_ATTR(temp12_input, 0444, show_temp_value, NULL, 11),
339 SENSOR_ATTR(temp12_fault, 0444, show_temp_fault, NULL, 11),
340 SENSOR_ATTR(temp12_alarm, 0444, show_temp_alarm, NULL, 11),
341 SENSOR_ATTR(temp13_input, 0444, show_temp_value, NULL, 12),
342 SENSOR_ATTR(temp13_fault, 0444, show_temp_fault, NULL, 12),
343 SENSOR_ATTR(temp13_alarm, 0444, show_temp_alarm, NULL, 12),
344 SENSOR_ATTR(temp14_input, 0444, show_temp_value, NULL, 13),
345 SENSOR_ATTR(temp14_fault, 0444, show_temp_fault, NULL, 13),
346 SENSOR_ATTR(temp14_alarm, 0444, show_temp_alarm, NULL, 13),
347 SENSOR_ATTR(temp15_input, 0444, show_temp_value, NULL, 14),
348 SENSOR_ATTR(temp15_fault, 0444, show_temp_fault, NULL, 14),
349 SENSOR_ATTR(temp15_alarm, 0444, show_temp_alarm, NULL, 14),
350 SENSOR_ATTR(temp16_input, 0444, show_temp_value, NULL, 15),
351 SENSOR_ATTR(temp16_fault, 0444, show_temp_fault, NULL, 15),
352 SENSOR_ATTR(temp16_alarm, 0444, show_temp_alarm, NULL, 15),
353};
354
355static struct sensor_device_attribute sch5636_fan_attr[] = {
356 SENSOR_ATTR(fan1_input, 0444, show_fan_value, NULL, 0),
357 SENSOR_ATTR(fan1_fault, 0444, show_fan_fault, NULL, 0),
358 SENSOR_ATTR(fan1_alarm, 0444, show_fan_alarm, NULL, 0),
359 SENSOR_ATTR(fan2_input, 0444, show_fan_value, NULL, 1),
360 SENSOR_ATTR(fan2_fault, 0444, show_fan_fault, NULL, 1),
361 SENSOR_ATTR(fan2_alarm, 0444, show_fan_alarm, NULL, 1),
362 SENSOR_ATTR(fan3_input, 0444, show_fan_value, NULL, 2),
363 SENSOR_ATTR(fan3_fault, 0444, show_fan_fault, NULL, 2),
364 SENSOR_ATTR(fan3_alarm, 0444, show_fan_alarm, NULL, 2),
365 SENSOR_ATTR(fan4_input, 0444, show_fan_value, NULL, 3),
366 SENSOR_ATTR(fan4_fault, 0444, show_fan_fault, NULL, 3),
367 SENSOR_ATTR(fan4_alarm, 0444, show_fan_alarm, NULL, 3),
368 SENSOR_ATTR(fan5_input, 0444, show_fan_value, NULL, 4),
369 SENSOR_ATTR(fan5_fault, 0444, show_fan_fault, NULL, 4),
370 SENSOR_ATTR(fan5_alarm, 0444, show_fan_alarm, NULL, 4),
371 SENSOR_ATTR(fan6_input, 0444, show_fan_value, NULL, 5),
372 SENSOR_ATTR(fan6_fault, 0444, show_fan_fault, NULL, 5),
373 SENSOR_ATTR(fan6_alarm, 0444, show_fan_alarm, NULL, 5),
374 SENSOR_ATTR(fan7_input, 0444, show_fan_value, NULL, 6),
375 SENSOR_ATTR(fan7_fault, 0444, show_fan_fault, NULL, 6),
376 SENSOR_ATTR(fan7_alarm, 0444, show_fan_alarm, NULL, 6),
377 SENSOR_ATTR(fan8_input, 0444, show_fan_value, NULL, 7),
378 SENSOR_ATTR(fan8_fault, 0444, show_fan_fault, NULL, 7),
379 SENSOR_ATTR(fan8_alarm, 0444, show_fan_alarm, NULL, 7),
380};
381
382static int sch5636_remove(struct platform_device *pdev)
383{
384 struct sch5636_data *data = platform_get_drvdata(pdev);
385 int i;
386
387 if (data->hwmon_dev)
388 hwmon_device_unregister(data->hwmon_dev);
389
390 for (i = 0; i < ARRAY_SIZE(sch5636_attr); i++)
391 device_remove_file(&pdev->dev, &sch5636_attr[i].dev_attr);
392
393 for (i = 0; i < SCH5636_NO_TEMPS * 3; i++)
394 device_remove_file(&pdev->dev,
395 &sch5636_temp_attr[i].dev_attr);
396
397 for (i = 0; i < SCH5636_NO_FANS * 3; i++)
398 device_remove_file(&pdev->dev,
399 &sch5636_fan_attr[i].dev_attr);
400
401 platform_set_drvdata(pdev, NULL);
402 kfree(data);
403
404 return 0;
405}
406
407static int __devinit sch5636_probe(struct platform_device *pdev)
408{
409 struct sch5636_data *data;
410 int i, err, val, revision[2];
411 char id[4];
412
413 data = kzalloc(sizeof(struct sch5636_data), GFP_KERNEL);
414 if (!data)
415 return -ENOMEM;
416
417 data->addr = platform_get_resource(pdev, IORESOURCE_IO, 0)->start;
418 mutex_init(&data->update_lock);
419 platform_set_drvdata(pdev, data);
420
421 for (i = 0; i < 3; i++) {
422 val = sch56xx_read_virtual_reg(data->addr,
423 SCH5636_REG_FUJITSU_ID + i);
424 if (val < 0) {
425 pr_err("Could not read Fujitsu id byte at %#x\n",
426 SCH5636_REG_FUJITSU_ID + i);
427 err = val;
428 goto error;
429 }
430 id[i] = val;
431 }
432 id[i] = '\0';
433
434 if (strcmp(id, "THS")) {
435 pr_err("Unknown Fujitsu id: %02x%02x%02x\n",
436 id[0], id[1], id[2]);
437 err = -ENODEV;
438 goto error;
439 }
440
441 for (i = 0; i < 2; i++) {
442 val = sch56xx_read_virtual_reg(data->addr,
443 SCH5636_REG_FUJITSU_REV + i);
444 if (val < 0) {
445 err = val;
446 goto error;
447 }
448 revision[i] = val;
449 }
450 pr_info("Found %s chip at %#hx, revison: %d.%02d\n", DEVNAME,
451 data->addr, revision[0], revision[1]);
452
453 /* Read all temp + fan ctrl registers to determine which are active */
454 for (i = 0; i < SCH5636_NO_TEMPS; i++) {
455 val = sch56xx_read_virtual_reg(data->addr,
456 SCH5636_REG_TEMP_CTRL(i));
457 if (unlikely(val < 0)) {
458 err = val;
459 goto error;
460 }
461 data->temp_ctrl[i] = val;
462 }
463
464 for (i = 0; i < SCH5636_NO_FANS; i++) {
465 val = sch56xx_read_virtual_reg(data->addr,
466 SCH5636_REG_FAN_CTRL(i));
467 if (unlikely(val < 0)) {
468 err = val;
469 goto error;
470 }
471 data->fan_ctrl[i] = val;
472 }
473
474 for (i = 0; i < ARRAY_SIZE(sch5636_attr); i++) {
475 err = device_create_file(&pdev->dev,
476 &sch5636_attr[i].dev_attr);
477 if (err)
478 goto error;
479 }
480
481 for (i = 0; i < (SCH5636_NO_TEMPS * 3); i++) {
482 if (data->temp_ctrl[i/3] & SCH5636_TEMP_DEACTIVATED)
483 continue;
484
485 err = device_create_file(&pdev->dev,
486 &sch5636_temp_attr[i].dev_attr);
487 if (err)
488 goto error;
489 }
490
491 for (i = 0; i < (SCH5636_NO_FANS * 3); i++) {
492 if (data->fan_ctrl[i/3] & SCH5636_FAN_DEACTIVATED)
493 continue;
494
495 err = device_create_file(&pdev->dev,
496 &sch5636_fan_attr[i].dev_attr);
497 if (err)
498 goto error;
499 }
500
501 data->hwmon_dev = hwmon_device_register(&pdev->dev);
502 if (IS_ERR(data->hwmon_dev)) {
503 err = PTR_ERR(data->hwmon_dev);
504 data->hwmon_dev = NULL;
505 goto error;
506 }
507
508 return 0;
509
510error:
511 sch5636_remove(pdev);
512 return err;
513}
514
515static struct platform_driver sch5636_driver = {
516 .driver = {
517 .owner = THIS_MODULE,
518 .name = DRVNAME,
519 },
520 .probe = sch5636_probe,
521 .remove = sch5636_remove,
522};
523
524static int __init sch5636_init(void)
525{
526 return platform_driver_register(&sch5636_driver);
527}
528
529static void __exit sch5636_exit(void)
530{
531 platform_driver_unregister(&sch5636_driver);
532}
533
534MODULE_DESCRIPTION("SMSC SCH5636 Hardware Monitoring Driver");
535MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
536MODULE_LICENSE("GPL");
537
538module_init(sch5636_init);
539module_exit(sch5636_exit);
diff --git a/drivers/hwmon/sch56xx-common.c b/drivers/hwmon/sch56xx-common.c
new file mode 100644
index 000000000000..fac32ee0b10e
--- /dev/null
+++ b/drivers/hwmon/sch56xx-common.c
@@ -0,0 +1,340 @@
1/***************************************************************************
2 * Copyright (C) 2010-2011 Hans de Goede <hdegoede@redhat.com> *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
18 ***************************************************************************/
19
20#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
21
22#include <linux/module.h>
23#include <linux/init.h>
24#include <linux/platform_device.h>
25#include <linux/err.h>
26#include <linux/io.h>
27#include <linux/acpi.h>
28#include <linux/delay.h>
29#include "sch56xx-common.h"
30
31#define SIO_SCH56XX_LD_EM 0x0C /* Embedded uController Logical Dev */
32#define SIO_UNLOCK_KEY 0x55 /* Key to enable Super-I/O */
33#define SIO_LOCK_KEY 0xAA /* Key to disable Super-I/O */
34
35#define SIO_REG_LDSEL 0x07 /* Logical device select */
36#define SIO_REG_DEVID 0x20 /* Device ID */
37#define SIO_REG_ENABLE 0x30 /* Logical device enable */
38#define SIO_REG_ADDR 0x66 /* Logical device address (2 bytes) */
39
40#define SIO_SCH5627_ID 0xC6 /* Chipset ID */
41#define SIO_SCH5636_ID 0xC7 /* Chipset ID */
42
43#define REGION_LENGTH 9
44
45#define SCH56XX_CMD_READ 0x02
46#define SCH56XX_CMD_WRITE 0x03
47
48static struct platform_device *sch56xx_pdev;
49
50/* Super I/O functions */
51static inline int superio_inb(int base, int reg)
52{
53 outb(reg, base);
54 return inb(base + 1);
55}
56
57static inline int superio_enter(int base)
58{
59 /* Don't step on other drivers' I/O space by accident */
60 if (!request_muxed_region(base, 2, "sch56xx")) {
61 pr_err("I/O address 0x%04x already in use\n", base);
62 return -EBUSY;
63 }
64
65 outb(SIO_UNLOCK_KEY, base);
66
67 return 0;
68}
69
70static inline void superio_select(int base, int ld)
71{
72 outb(SIO_REG_LDSEL, base);
73 outb(ld, base + 1);
74}
75
76static inline void superio_exit(int base)
77{
78 outb(SIO_LOCK_KEY, base);
79 release_region(base, 2);
80}
81
82static int sch56xx_send_cmd(u16 addr, u8 cmd, u16 reg, u8 v)
83{
84 u8 val;
85 int i;
86 /*
87 * According to SMSC for the commands we use the maximum time for
88 * the EM to respond is 15 ms, but testing shows in practice it
89 * responds within 15-32 reads, so we first busy poll, and if
90 * that fails sleep a bit and try again until we are way past
91 * the 15 ms maximum response time.
92 */
93 const int max_busy_polls = 64;
94 const int max_lazy_polls = 32;
95
96 /* (Optional) Write-Clear the EC to Host Mailbox Register */
97 val = inb(addr + 1);
98 outb(val, addr + 1);
99
100 /* Set Mailbox Address Pointer to first location in Region 1 */
101 outb(0x00, addr + 2);
102 outb(0x80, addr + 3);
103
104 /* Write Request Packet Header */
105 outb(cmd, addr + 4); /* VREG Access Type read:0x02 write:0x03 */
106 outb(0x01, addr + 5); /* # of Entries: 1 Byte (8-bit) */
107 outb(0x04, addr + 2); /* Mailbox AP to first data entry loc. */
108
109 /* Write Value field */
110 if (cmd == SCH56XX_CMD_WRITE)
111 outb(v, addr + 4);
112
113 /* Write Address field */
114 outb(reg & 0xff, addr + 6);
115 outb(reg >> 8, addr + 7);
116
117 /* Execute the Random Access Command */
118 outb(0x01, addr); /* Write 01h to the Host-to-EC register */
119
120 /* EM Interface Polling "Algorithm" */
121 for (i = 0; i < max_busy_polls + max_lazy_polls; i++) {
122 if (i >= max_busy_polls)
123 msleep(1);
124 /* Read Interrupt source Register */
125 val = inb(addr + 8);
126 /* Write Clear the interrupt source bits */
127 if (val)
128 outb(val, addr + 8);
129 /* Command Completed ? */
130 if (val & 0x01)
131 break;
132 }
133 if (i == max_busy_polls + max_lazy_polls) {
134 pr_err("Max retries exceeded reading virtual "
135 "register 0x%04hx (%d)\n", reg, 1);
136 return -EIO;
137 }
138
139 /*
140 * According to SMSC we may need to retry this, but sofar I've always
141 * seen this succeed in 1 try.
142 */
143 for (i = 0; i < max_busy_polls; i++) {
144 /* Read EC-to-Host Register */
145 val = inb(addr + 1);
146 /* Command Completed ? */
147 if (val == 0x01)
148 break;
149
150 if (i == 0)
151 pr_warn("EC reports: 0x%02x reading virtual register "
152 "0x%04hx\n", (unsigned int)val, reg);
153 }
154 if (i == max_busy_polls) {
155 pr_err("Max retries exceeded reading virtual "
156 "register 0x%04hx (%d)\n", reg, 2);
157 return -EIO;
158 }
159
160 /*
161 * According to the SMSC app note we should now do:
162 *
163 * Set Mailbox Address Pointer to first location in Region 1 *
164 * outb(0x00, addr + 2);
165 * outb(0x80, addr + 3);
166 *
167 * But if we do that things don't work, so let's not.
168 */
169
170 /* Read Value field */
171 if (cmd == SCH56XX_CMD_READ)
172 return inb(addr + 4);
173
174 return 0;
175}
176
177int sch56xx_read_virtual_reg(u16 addr, u16 reg)
178{
179 return sch56xx_send_cmd(addr, SCH56XX_CMD_READ, reg, 0);
180}
181EXPORT_SYMBOL(sch56xx_read_virtual_reg);
182
183int sch56xx_write_virtual_reg(u16 addr, u16 reg, u8 val)
184{
185 return sch56xx_send_cmd(addr, SCH56XX_CMD_WRITE, reg, val);
186}
187EXPORT_SYMBOL(sch56xx_write_virtual_reg);
188
189int sch56xx_read_virtual_reg16(u16 addr, u16 reg)
190{
191 int lsb, msb;
192
193 /* Read LSB first, this will cause the matching MSB to be latched */
194 lsb = sch56xx_read_virtual_reg(addr, reg);
195 if (lsb < 0)
196 return lsb;
197
198 msb = sch56xx_read_virtual_reg(addr, reg + 1);
199 if (msb < 0)
200 return msb;
201
202 return lsb | (msb << 8);
203}
204EXPORT_SYMBOL(sch56xx_read_virtual_reg16);
205
206int sch56xx_read_virtual_reg12(u16 addr, u16 msb_reg, u16 lsn_reg,
207 int high_nibble)
208{
209 int msb, lsn;
210
211 /* Read MSB first, this will cause the matching LSN to be latched */
212 msb = sch56xx_read_virtual_reg(addr, msb_reg);
213 if (msb < 0)
214 return msb;
215
216 lsn = sch56xx_read_virtual_reg(addr, lsn_reg);
217 if (lsn < 0)
218 return lsn;
219
220 if (high_nibble)
221 return (msb << 4) | (lsn >> 4);
222 else
223 return (msb << 4) | (lsn & 0x0f);
224}
225EXPORT_SYMBOL(sch56xx_read_virtual_reg12);
226
227static int __init sch56xx_find(int sioaddr, unsigned short *address,
228 const char **name)
229{
230 u8 devid;
231 int err;
232
233 err = superio_enter(sioaddr);
234 if (err)
235 return err;
236
237 devid = superio_inb(sioaddr, SIO_REG_DEVID);
238 switch (devid) {
239 case SIO_SCH5627_ID:
240 *name = "sch5627";
241 break;
242 case SIO_SCH5636_ID:
243 *name = "sch5636";
244 break;
245 default:
246 pr_debug("Unsupported device id: 0x%02x\n",
247 (unsigned int)devid);
248 err = -ENODEV;
249 goto exit;
250 }
251
252 superio_select(sioaddr, SIO_SCH56XX_LD_EM);
253
254 if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) {
255 pr_warn("Device not activated\n");
256 err = -ENODEV;
257 goto exit;
258 }
259
260 /*
261 * Warning the order of the low / high byte is the other way around
262 * as on most other superio devices!!
263 */
264 *address = superio_inb(sioaddr, SIO_REG_ADDR) |
265 superio_inb(sioaddr, SIO_REG_ADDR + 1) << 8;
266 if (*address == 0) {
267 pr_warn("Base address not set\n");
268 err = -ENODEV;
269 goto exit;
270 }
271
272exit:
273 superio_exit(sioaddr);
274 return err;
275}
276
277static int __init sch56xx_device_add(unsigned short address, const char *name)
278{
279 struct resource res = {
280 .start = address,
281 .end = address + REGION_LENGTH - 1,
282 .flags = IORESOURCE_IO,
283 };
284 int err;
285
286 sch56xx_pdev = platform_device_alloc(name, address);
287 if (!sch56xx_pdev)
288 return -ENOMEM;
289
290 res.name = sch56xx_pdev->name;
291 err = acpi_check_resource_conflict(&res);
292 if (err)
293 goto exit_device_put;
294
295 err = platform_device_add_resources(sch56xx_pdev, &res, 1);
296 if (err) {
297 pr_err("Device resource addition failed\n");
298 goto exit_device_put;
299 }
300
301 err = platform_device_add(sch56xx_pdev);
302 if (err) {
303 pr_err("Device addition failed\n");
304 goto exit_device_put;
305 }
306
307 return 0;
308
309exit_device_put:
310 platform_device_put(sch56xx_pdev);
311
312 return err;
313}
314
315static int __init sch56xx_init(void)
316{
317 int err;
318 unsigned short address;
319 const char *name;
320
321 err = sch56xx_find(0x4e, &address, &name);
322 if (err)
323 err = sch56xx_find(0x2e, &address, &name);
324 if (err)
325 return err;
326
327 return sch56xx_device_add(address, name);
328}
329
330static void __exit sch56xx_exit(void)
331{
332 platform_device_unregister(sch56xx_pdev);
333}
334
335MODULE_DESCRIPTION("SMSC SCH56xx Hardware Monitoring Common Code");
336MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
337MODULE_LICENSE("GPL");
338
339module_init(sch56xx_init);
340module_exit(sch56xx_exit);
diff --git a/drivers/hwmon/sch56xx-common.h b/drivers/hwmon/sch56xx-common.h
new file mode 100644
index 000000000000..d5eaf3b9ebf5
--- /dev/null
+++ b/drivers/hwmon/sch56xx-common.h
@@ -0,0 +1,24 @@
1/***************************************************************************
2 * Copyright (C) 2010-2011 Hans de Goede <hdegoede@redhat.com> *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
18 ***************************************************************************/
19
20int sch56xx_read_virtual_reg(u16 addr, u16 reg);
21int sch56xx_write_virtual_reg(u16 addr, u16 reg, u8 val);
22int sch56xx_read_virtual_reg16(u16 addr, u16 reg);
23int sch56xx_read_virtual_reg12(u16 addr, u16 msb_reg, u16 lsn_reg,
24 int high_nibble);
diff --git a/drivers/hwmon/sht15.c b/drivers/hwmon/sht15.c
index cf4330b352ef..7d231cf5d2ce 100644
--- a/drivers/hwmon/sht15.c
+++ b/drivers/hwmon/sht15.c
@@ -671,7 +671,7 @@ static ssize_t sht15_show_status(struct device *dev,
671 * @buf: sysfs buffer to read the new heater state from. 671 * @buf: sysfs buffer to read the new heater state from.
672 * @count: length of the data. 672 * @count: length of the data.
673 * 673 *
674 * Will be called on read access to heater_enable sysfs attribute. 674 * Will be called on write access to heater_enable sysfs attribute.
675 * Returns number of bytes actually decoded, negative errno on error. 675 * Returns number of bytes actually decoded, negative errno on error.
676 */ 676 */
677static ssize_t sht15_store_heater(struct device *dev, 677static ssize_t sht15_store_heater(struct device *dev,
diff --git a/drivers/hwmon/via-cputemp.c b/drivers/hwmon/via-cputemp.c
index 0d18de424c66..8eac67d769fa 100644
--- a/drivers/hwmon/via-cputemp.c
+++ b/drivers/hwmon/via-cputemp.c
@@ -27,6 +27,7 @@
27#include <linux/init.h> 27#include <linux/init.h>
28#include <linux/slab.h> 28#include <linux/slab.h>
29#include <linux/hwmon.h> 29#include <linux/hwmon.h>
30#include <linux/hwmon-vid.h>
30#include <linux/sysfs.h> 31#include <linux/sysfs.h>
31#include <linux/hwmon-sysfs.h> 32#include <linux/hwmon-sysfs.h>
32#include <linux/err.h> 33#include <linux/err.h>
@@ -48,8 +49,10 @@ enum { SHOW_TEMP, SHOW_LABEL, SHOW_NAME };
48struct via_cputemp_data { 49struct via_cputemp_data {
49 struct device *hwmon_dev; 50 struct device *hwmon_dev;
50 const char *name; 51 const char *name;
52 u8 vrm;
51 u32 id; 53 u32 id;
52 u32 msr; 54 u32 msr_temp;
55 u32 msr_vid;
53}; 56};
54 57
55/* 58/*
@@ -77,13 +80,27 @@ static ssize_t show_temp(struct device *dev,
77 u32 eax, edx; 80 u32 eax, edx;
78 int err; 81 int err;
79 82
80 err = rdmsr_safe_on_cpu(data->id, data->msr, &eax, &edx); 83 err = rdmsr_safe_on_cpu(data->id, data->msr_temp, &eax, &edx);
81 if (err) 84 if (err)
82 return -EAGAIN; 85 return -EAGAIN;
83 86
84 return sprintf(buf, "%lu\n", ((unsigned long)eax & 0xffffff) * 1000); 87 return sprintf(buf, "%lu\n", ((unsigned long)eax & 0xffffff) * 1000);
85} 88}
86 89
90static ssize_t show_cpu_vid(struct device *dev,
91 struct device_attribute *devattr, char *buf)
92{
93 struct via_cputemp_data *data = dev_get_drvdata(dev);
94 u32 eax, edx;
95 int err;
96
97 err = rdmsr_safe_on_cpu(data->id, data->msr_vid, &eax, &edx);
98 if (err)
99 return -EAGAIN;
100
101 return sprintf(buf, "%d\n", vid_from_reg(~edx & 0x7f, data->vrm));
102}
103
87static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 104static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL,
88 SHOW_TEMP); 105 SHOW_TEMP);
89static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, show_name, NULL, SHOW_LABEL); 106static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, show_name, NULL, SHOW_LABEL);
@@ -100,6 +117,9 @@ static const struct attribute_group via_cputemp_group = {
100 .attrs = via_cputemp_attributes, 117 .attrs = via_cputemp_attributes,
101}; 118};
102 119
120/* Optional attributes */
121static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_cpu_vid, NULL);
122
103static int __devinit via_cputemp_probe(struct platform_device *pdev) 123static int __devinit via_cputemp_probe(struct platform_device *pdev)
104{ 124{
105 struct via_cputemp_data *data; 125 struct via_cputemp_data *data;
@@ -122,11 +142,12 @@ static int __devinit via_cputemp_probe(struct platform_device *pdev)
122 /* C7 A */ 142 /* C7 A */
123 case 0xD: 143 case 0xD:
124 /* C7 D */ 144 /* C7 D */
125 data->msr = 0x1169; 145 data->msr_temp = 0x1169;
146 data->msr_vid = 0x198;
126 break; 147 break;
127 case 0xF: 148 case 0xF:
128 /* Nano */ 149 /* Nano */
129 data->msr = 0x1423; 150 data->msr_temp = 0x1423;
130 break; 151 break;
131 default: 152 default:
132 err = -ENODEV; 153 err = -ENODEV;
@@ -134,7 +155,7 @@ static int __devinit via_cputemp_probe(struct platform_device *pdev)
134 } 155 }
135 156
136 /* test if we can access the TEMPERATURE MSR */ 157 /* test if we can access the TEMPERATURE MSR */
137 err = rdmsr_safe_on_cpu(data->id, data->msr, &eax, &edx); 158 err = rdmsr_safe_on_cpu(data->id, data->msr_temp, &eax, &edx);
138 if (err) { 159 if (err) {
139 dev_err(&pdev->dev, 160 dev_err(&pdev->dev,
140 "Unable to access TEMPERATURE MSR, giving up\n"); 161 "Unable to access TEMPERATURE MSR, giving up\n");
@@ -147,6 +168,15 @@ static int __devinit via_cputemp_probe(struct platform_device *pdev)
147 if (err) 168 if (err)
148 goto exit_free; 169 goto exit_free;
149 170
171 if (data->msr_vid)
172 data->vrm = vid_which_vrm();
173
174 if (data->vrm) {
175 err = device_create_file(&pdev->dev, &dev_attr_cpu0_vid);
176 if (err)
177 goto exit_remove;
178 }
179
150 data->hwmon_dev = hwmon_device_register(&pdev->dev); 180 data->hwmon_dev = hwmon_device_register(&pdev->dev);
151 if (IS_ERR(data->hwmon_dev)) { 181 if (IS_ERR(data->hwmon_dev)) {
152 err = PTR_ERR(data->hwmon_dev); 182 err = PTR_ERR(data->hwmon_dev);
@@ -158,6 +188,8 @@ static int __devinit via_cputemp_probe(struct platform_device *pdev)
158 return 0; 188 return 0;
159 189
160exit_remove: 190exit_remove:
191 if (data->vrm)
192 device_remove_file(&pdev->dev, &dev_attr_cpu0_vid);
161 sysfs_remove_group(&pdev->dev.kobj, &via_cputemp_group); 193 sysfs_remove_group(&pdev->dev.kobj, &via_cputemp_group);
162exit_free: 194exit_free:
163 platform_set_drvdata(pdev, NULL); 195 platform_set_drvdata(pdev, NULL);
@@ -171,6 +203,8 @@ static int __devexit via_cputemp_remove(struct platform_device *pdev)
171 struct via_cputemp_data *data = platform_get_drvdata(pdev); 203 struct via_cputemp_data *data = platform_get_drvdata(pdev);
172 204
173 hwmon_device_unregister(data->hwmon_dev); 205 hwmon_device_unregister(data->hwmon_dev);
206 if (data->vrm)
207 device_remove_file(&pdev->dev, &dev_attr_cpu0_vid);
174 sysfs_remove_group(&pdev->dev.kobj, &via_cputemp_group); 208 sysfs_remove_group(&pdev->dev.kobj, &via_cputemp_group);
175 platform_set_drvdata(pdev, NULL); 209 platform_set_drvdata(pdev, NULL);
176 kfree(data); 210 kfree(data);