diff options
Diffstat (limited to 'drivers/hwmon')
-rw-r--r-- | drivers/hwmon/Kconfig | 1 | ||||
-rw-r--r-- | drivers/hwmon/w83627ehf.c | 50 |
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 | ||
619 | config SENSORS_W83627EHF | 619 | config 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 | ||
290 | struct w83627ehf_sio_data { | 297 | struct 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 | ||
1137 | static ssize_t | ||
1138 | show_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 | } | ||
1143 | static 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); |