aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon')
-rw-r--r--drivers/hwmon/Kconfig1
-rw-r--r--drivers/hwmon/w83627ehf.c50
2 files changed, 49 insertions, 2 deletions
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index fe7962bada13..dbdca6f10e46 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -618,6 +618,7 @@ config SENSORS_W83627HF
618 618
619config SENSORS_W83627EHF 619config SENSORS_W83627EHF
620 tristate "Winbond W83627EHF/DHG" 620 tristate "Winbond W83627EHF/DHG"
621 select HWMON_VID
621 help 622 help
622 If you say yes here you get support for the hardware 623 If you say yes here you get support for the hardware
623 monitoring functionality of the Winbond W83627EHF Super-I/O chip. 624 monitoring functionality of the Winbond W83627EHF Super-I/O chip.
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c
index 0c2d929cf573..a336793c1caf 100644
--- a/drivers/hwmon/w83627ehf.c
+++ b/drivers/hwmon/w83627ehf.c
@@ -45,6 +45,7 @@
45#include <linux/platform_device.h> 45#include <linux/platform_device.h>
46#include <linux/hwmon.h> 46#include <linux/hwmon.h>
47#include <linux/hwmon-sysfs.h> 47#include <linux/hwmon-sysfs.h>
48#include <linux/hwmon-vid.h>
48#include <linux/err.h> 49#include <linux/err.h>
49#include <linux/mutex.h> 50#include <linux/mutex.h>
50#include <asm/io.h> 51#include <asm/io.h>
@@ -68,8 +69,11 @@ static const char * w83627ehf_device_names[] = {
68 69
69#define SIO_REG_LDSEL 0x07 /* Logical device select */ 70#define SIO_REG_LDSEL 0x07 /* Logical device select */
70#define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */ 71#define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */
72#define SIO_REG_EN_VRM10 0x2C /* GPIO3, GPIO4 selection */
71#define SIO_REG_ENABLE 0x30 /* Logical device enable */ 73#define SIO_REG_ENABLE 0x30 /* Logical device enable */
72#define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */ 74#define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */
75#define SIO_REG_VID_CTRL 0xF0 /* VID control */
76#define SIO_REG_VID_DATA 0xF1 /* VID data */
73 77
74#define SIO_W83627EHF_ID 0x8850 78#define SIO_W83627EHF_ID 0x8850
75#define SIO_W83627EHG_ID 0x8860 79#define SIO_W83627EHG_ID 0x8860
@@ -285,6 +289,9 @@ struct w83627ehf_data {
285 289
286 u8 fan_min_output[4]; /* minimum fan speed */ 290 u8 fan_min_output[4]; /* minimum fan speed */
287 u8 fan_stop_time[4]; 291 u8 fan_stop_time[4];
292
293 u8 vid;
294 u8 vrm;
288}; 295};
289 296
290struct w83627ehf_sio_data { 297struct w83627ehf_sio_data {
@@ -1127,6 +1134,14 @@ static struct sensor_device_attribute sda_sf3_arrays[] = {
1127 store_fan_min_output, 2), 1134 store_fan_min_output, 2),
1128}; 1135};
1129 1136
1137static ssize_t
1138show_vid(struct device *dev, struct device_attribute *attr, char *buf)
1139{
1140 struct w83627ehf_data *data = dev_get_drvdata(dev);
1141 return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm));
1142}
1143static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL);
1144
1130/* 1145/*
1131 * Driver and device management 1146 * Driver and device management
1132 */ 1147 */
@@ -1165,6 +1180,8 @@ static void w83627ehf_device_remove_files(struct device *dev)
1165 device_remove_file(dev, &sda_temp[i].dev_attr); 1180 device_remove_file(dev, &sda_temp[i].dev_attr);
1166 1181
1167 device_remove_file(dev, &dev_attr_name); 1182 device_remove_file(dev, &dev_attr_name);
1183 if (data->vid != 0x3f)
1184 device_remove_file(dev, &dev_attr_cpu0_vid);
1168} 1185}
1169 1186
1170/* Get the monitoring functions started */ 1187/* Get the monitoring functions started */
@@ -1196,7 +1213,7 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
1196 struct w83627ehf_sio_data *sio_data = dev->platform_data; 1213 struct w83627ehf_sio_data *sio_data = dev->platform_data;
1197 struct w83627ehf_data *data; 1214 struct w83627ehf_data *data;
1198 struct resource *res; 1215 struct resource *res;
1199 u8 fan4pin, fan5pin; 1216 u8 fan4pin, fan5pin, en_vrm10;
1200 int i, err = 0; 1217 int i, err = 0;
1201 1218
1202 res = platform_get_resource(pdev, IORESOURCE_IO, 0); 1219 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
@@ -1230,9 +1247,32 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
1230 data->fan_min[i] = w83627ehf_read_value(data, 1247 data->fan_min[i] = w83627ehf_read_value(data,
1231 W83627EHF_REG_FAN_MIN[i]); 1248 W83627EHF_REG_FAN_MIN[i]);
1232 1249
1250 data->vrm = vid_which_vrm();
1251 superio_enter(sio_data->sioreg);
1252 /* Set VID input sensibility if needed. In theory the BIOS should
1253 have set it, but in practice it's not always the case. */
1254 en_vrm10 = superio_inb(sio_data->sioreg, SIO_REG_EN_VRM10);
1255 if ((en_vrm10 & 0x08) && data->vrm != 100) {
1256 dev_warn(dev, "Setting VID input voltage to TTL\n");
1257 superio_outb(sio_data->sioreg, SIO_REG_EN_VRM10,
1258 en_vrm10 & ~0x08);
1259 } else if (!(en_vrm10 & 0x08) && data->vrm == 100) {
1260 dev_warn(dev, "Setting VID input voltage to VRM10\n");
1261 superio_outb(sio_data->sioreg, SIO_REG_EN_VRM10,
1262 en_vrm10 | 0x08);
1263 }
1264 /* Read VID value */
1265 superio_select(sio_data->sioreg, W83627EHF_LD_HWM);
1266 if (superio_inb(sio_data->sioreg, SIO_REG_VID_CTRL) & 0x80)
1267 data->vid = superio_inb(sio_data->sioreg, SIO_REG_VID_DATA) & 0x3f;
1268 else {
1269 dev_info(dev, "VID pins in output mode, CPU VID not "
1270 "available\n");
1271 data->vid = 0x3f;
1272 }
1273
1233 /* fan4 and fan5 share some pins with the GPIO and serial flash */ 1274 /* fan4 and fan5 share some pins with the GPIO and serial flash */
1234 1275
1235 superio_enter(sio_data->sioreg);
1236 fan5pin = superio_inb(sio_data->sioreg, 0x24) & 0x2; 1276 fan5pin = superio_inb(sio_data->sioreg, 0x24) & 0x2;
1237 fan4pin = superio_inb(sio_data->sioreg, 0x29) & 0x6; 1277 fan4pin = superio_inb(sio_data->sioreg, 0x29) & 0x6;
1238 superio_exit(sio_data->sioreg); 1278 superio_exit(sio_data->sioreg);
@@ -1308,6 +1348,12 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
1308 if (err) 1348 if (err)
1309 goto exit_remove; 1349 goto exit_remove;
1310 1350
1351 if (data->vid != 0x3f) {
1352 err = device_create_file(dev, &dev_attr_cpu0_vid);
1353 if (err)
1354 goto exit_remove;
1355 }
1356
1311 data->class_dev = hwmon_device_register(dev); 1357 data->class_dev = hwmon_device_register(dev);
1312 if (IS_ERR(data->class_dev)) { 1358 if (IS_ERR(data->class_dev)) {
1313 err = PTR_ERR(data->class_dev); 1359 err = PTR_ERR(data->class_dev);