Commit fc18d6c0 authored by Jean Delvare's avatar Jean Delvare Committed by Mark M. Hoffman

hwmon/w83627ehf: Add support for the VID inputs

The W83627EHF and similar chips have 6 VID input pins, add support
for them. The driver changes the input voltage level automatically
if the current setting is not correct for the detected CPU model.
Signed-off-by: default avatarJean Delvare <khali@linux-fr.org>
Signed-off-by: default avatarMark M. Hoffman <mhoffman@lightlink.com>
parent 6b3e4645
...@@ -22,9 +22,9 @@ This driver implements support for the Winbond W83627EHF, W83627EHG, and ...@@ -22,9 +22,9 @@ This driver implements support for the Winbond W83627EHF, W83627EHG, and
W83627DHG super I/O chips. We will refer to them collectively as Winbond chips. W83627DHG super I/O chips. We will refer to them collectively as Winbond chips.
The chips implement three temperature sensors, five fan rotation The chips implement three temperature sensors, five fan rotation
speed sensors, ten analog voltage sensors (only nine for the 627DHG), alarms speed sensors, ten analog voltage sensors (only nine for the 627DHG), one
with beep warnings (control unimplemented), and some automatic fan regulation VID (6 pins), alarms with beep warnings (control unimplemented), and
strategies (plus manual fan control mode). some automatic fan regulation strategies (plus manual fan control mode).
Temperatures are measured in degrees Celsius and measurement resolution is 1 Temperatures are measured in degrees Celsius and measurement resolution is 1
degC for temp1 and 0.5 degC for temp2 and temp3. An alarm is triggered when degC for temp1 and 0.5 degC for temp2 and temp3. An alarm is triggered when
......
...@@ -618,6 +618,7 @@ config SENSORS_W83627HF ...@@ -618,6 +618,7 @@ config SENSORS_W83627HF
config SENSORS_W83627EHF config SENSORS_W83627EHF
tristate "Winbond W83627EHF/DHG" tristate "Winbond W83627EHF/DHG"
select HWMON_VID
help help
If you say yes here you get support for the hardware If you say yes here you get support for the hardware
monitoring functionality of the Winbond W83627EHF Super-I/O chip. monitoring functionality of the Winbond W83627EHF Super-I/O chip.
......
...@@ -45,6 +45,7 @@ ...@@ -45,6 +45,7 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/hwmon.h> #include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h> #include <linux/hwmon-sysfs.h>
#include <linux/hwmon-vid.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <asm/io.h> #include <asm/io.h>
...@@ -68,8 +69,11 @@ static const char * w83627ehf_device_names[] = { ...@@ -68,8 +69,11 @@ static const char * w83627ehf_device_names[] = {
#define SIO_REG_LDSEL 0x07 /* Logical device select */ #define SIO_REG_LDSEL 0x07 /* Logical device select */
#define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */ #define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */
#define SIO_REG_EN_VRM10 0x2C /* GPIO3, GPIO4 selection */
#define SIO_REG_ENABLE 0x30 /* Logical device enable */ #define SIO_REG_ENABLE 0x30 /* Logical device enable */
#define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */ #define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */
#define SIO_REG_VID_CTRL 0xF0 /* VID control */
#define SIO_REG_VID_DATA 0xF1 /* VID data */
#define SIO_W83627EHF_ID 0x8850 #define SIO_W83627EHF_ID 0x8850
#define SIO_W83627EHG_ID 0x8860 #define SIO_W83627EHG_ID 0x8860
...@@ -285,6 +289,9 @@ struct w83627ehf_data { ...@@ -285,6 +289,9 @@ struct w83627ehf_data {
u8 fan_min_output[4]; /* minimum fan speed */ u8 fan_min_output[4]; /* minimum fan speed */
u8 fan_stop_time[4]; u8 fan_stop_time[4];
u8 vid;
u8 vrm;
}; };
struct w83627ehf_sio_data { struct w83627ehf_sio_data {
...@@ -1127,6 +1134,14 @@ static struct sensor_device_attribute sda_sf3_arrays[] = { ...@@ -1127,6 +1134,14 @@ static struct sensor_device_attribute sda_sf3_arrays[] = {
store_fan_min_output, 2), store_fan_min_output, 2),
}; };
static ssize_t
show_vid(struct device *dev, struct device_attribute *attr, char *buf)
{
struct w83627ehf_data *data = dev_get_drvdata(dev);
return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm));
}
static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL);
/* /*
* Driver and device management * Driver and device management
*/ */
...@@ -1165,6 +1180,8 @@ static void w83627ehf_device_remove_files(struct device *dev) ...@@ -1165,6 +1180,8 @@ static void w83627ehf_device_remove_files(struct device *dev)
device_remove_file(dev, &sda_temp[i].dev_attr); device_remove_file(dev, &sda_temp[i].dev_attr);
device_remove_file(dev, &dev_attr_name); device_remove_file(dev, &dev_attr_name);
if (data->vid != 0x3f)
device_remove_file(dev, &dev_attr_cpu0_vid);
} }
/* Get the monitoring functions started */ /* Get the monitoring functions started */
...@@ -1196,7 +1213,7 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) ...@@ -1196,7 +1213,7 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
struct w83627ehf_sio_data *sio_data = dev->platform_data; struct w83627ehf_sio_data *sio_data = dev->platform_data;
struct w83627ehf_data *data; struct w83627ehf_data *data;
struct resource *res; struct resource *res;
u8 fan4pin, fan5pin; u8 fan4pin, fan5pin, en_vrm10;
int i, err = 0; int i, err = 0;
res = platform_get_resource(pdev, IORESOURCE_IO, 0); res = platform_get_resource(pdev, IORESOURCE_IO, 0);
...@@ -1230,9 +1247,32 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) ...@@ -1230,9 +1247,32 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
data->fan_min[i] = w83627ehf_read_value(data, data->fan_min[i] = w83627ehf_read_value(data,
W83627EHF_REG_FAN_MIN[i]); W83627EHF_REG_FAN_MIN[i]);
data->vrm = vid_which_vrm();
superio_enter(sio_data->sioreg);
/* Set VID input sensibility if needed. In theory the BIOS should
have set it, but in practice it's not always the case. */
en_vrm10 = superio_inb(sio_data->sioreg, SIO_REG_EN_VRM10);
if ((en_vrm10 & 0x08) && data->vrm != 100) {
dev_warn(dev, "Setting VID input voltage to TTL\n");
superio_outb(sio_data->sioreg, SIO_REG_EN_VRM10,
en_vrm10 & ~0x08);
} else if (!(en_vrm10 & 0x08) && data->vrm == 100) {
dev_warn(dev, "Setting VID input voltage to VRM10\n");
superio_outb(sio_data->sioreg, SIO_REG_EN_VRM10,
en_vrm10 | 0x08);
}
/* Read VID value */
superio_select(sio_data->sioreg, W83627EHF_LD_HWM);
if (superio_inb(sio_data->sioreg, SIO_REG_VID_CTRL) & 0x80)
data->vid = superio_inb(sio_data->sioreg, SIO_REG_VID_DATA) & 0x3f;
else {
dev_info(dev, "VID pins in output mode, CPU VID not "
"available\n");
data->vid = 0x3f;
}
/* fan4 and fan5 share some pins with the GPIO and serial flash */ /* fan4 and fan5 share some pins with the GPIO and serial flash */
superio_enter(sio_data->sioreg);
fan5pin = superio_inb(sio_data->sioreg, 0x24) & 0x2; fan5pin = superio_inb(sio_data->sioreg, 0x24) & 0x2;
fan4pin = superio_inb(sio_data->sioreg, 0x29) & 0x6; fan4pin = superio_inb(sio_data->sioreg, 0x29) & 0x6;
superio_exit(sio_data->sioreg); superio_exit(sio_data->sioreg);
...@@ -1308,6 +1348,12 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) ...@@ -1308,6 +1348,12 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
if (err) if (err)
goto exit_remove; goto exit_remove;
if (data->vid != 0x3f) {
err = device_create_file(dev, &dev_attr_cpu0_vid);
if (err)
goto exit_remove;
}
data->class_dev = hwmon_device_register(dev); data->class_dev = hwmon_device_register(dev);
if (IS_ERR(data->class_dev)) { if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev); err = PTR_ERR(data->class_dev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment