From ddca933bd554b4f81f27776f3cb9daa67cf241b1 Mon Sep 17 00:00:00 2001 From: Gong Jun Date: Thu, 18 Jan 2007 22:14:23 +0100 Subject: hwmon/w83793: Remove the description of AMDSI and update the voltage formula Fix the driver to match the information in datasheet 1.0. AMD SI interface is marked as reserved, computing formula for 5VDD and 5VSB is updated. Signed-off-by: Gong Jun Signed-off-by: Rudolf Marek Signed-off-by: Jean Delvare --- drivers/hwmon/w83793.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'drivers/hwmon/w83793.c') diff --git a/drivers/hwmon/w83793.c b/drivers/hwmon/w83793.c index c12ac5abc2bb..99e603a6a667 100644 --- a/drivers/hwmon/w83793.c +++ b/drivers/hwmon/w83793.c @@ -117,6 +117,7 @@ static const u16 W83793_REG_IN[][3] = { /* Low Bits of Vcore A/B Vtt Read/High/Low */ static const u16 W83793_REG_IN_LOW_BITS[] = { 0x1b, 0x68, 0x69 }; static u8 scale_in[] = { 2, 2, 2, 16, 16, 16, 8, 24, 24, 16 }; +static u8 scale_in_add[] = { 0, 0, 0, 0, 0, 0, 0, 150, 150, 0 }; #define W83793_REG_FAN(index) (0x23 + 2 * (index)) /* High byte */ #define W83793_REG_FAN_MIN(index) (0x90 + 2 * (index)) /* High byte */ @@ -500,7 +501,7 @@ store_temp(struct device *dev, struct device_attribute *attr, each has 4 mode:(2 bits) 0: Stop monitor 1: Use internal temp sensor(default) - 2: Use sensor in AMD CPU and get result by AMDSI + 2: Reserved 3: Use sensor in Intel CPU and get result by PECI TR1-TR2 @@ -509,8 +510,8 @@ store_temp(struct device *dev, struct device_attribute *attr, 1: To enable temp sensors monitor */ -/* 0 disable, 5 AMDSI, 6 PECI */ -static u8 TO_TEMP_MODE[] = { 0, 0, 5, 6 }; +/* 0 disable, 6 PECI */ +static u8 TO_TEMP_MODE[] = { 0, 0, 0, 6 }; static ssize_t show_temp_mode(struct device *dev, struct device_attribute *attr, char *buf) @@ -550,7 +551,7 @@ store_temp_mode(struct device *dev, struct device_attribute *attr, u8 val = simple_strtoul(buf, NULL, 10); /* transform the sysfs interface values into table above */ - if ((val == 5 || val == 6) && (index < 4)) { + if ((val == 6) && (index < 4)) { val -= 3; } else if ((val == 3 && index < 4) || (val == 4 && index >= 4) @@ -839,7 +840,9 @@ show_in(struct device *dev, struct device_attribute *attr, char *buf) val <<= 2; val += (data->in_low_bits[nr] >> (index * 2)) & 0x3; } - return sprintf(buf, "%d\n", val * scale_in[index]); + /* voltage inputs 5VDD and 5VSB needs 150mV offset */ + val = val * scale_in[index] + scale_in_add[index]; + return sprintf(buf, "%d\n", val); } static ssize_t @@ -859,6 +862,10 @@ store_in(struct device *dev, struct device_attribute *attr, scale_in[index] / 2) / scale_in[index]; mutex_lock(&data->update_lock); if (index > 2) { + /* fix the limit values of 5VDD and 5VSB to ALARM mechanism */ + if (1 == nr || 2 == nr) { + val -= scale_in_add[index] / scale_in[index]; + } val = SENSORS_LIMIT(val, 0, 255); } else { val = SENSORS_LIMIT(val, 0, 0x3FF); -- cgit v1.2.2 From 46bed4dfe5f95f1fc8f68ead592a7e295bbbe01e Mon Sep 17 00:00:00 2001 From: Gong Jun Date: Thu, 18 Jan 2007 22:14:24 +0100 Subject: hwmon/w83793: Ignore disabled temperature channels Ignore the temperature readings when its channel is disabled, ignore AMDSI readings. Signed-off-by: Gong Jun Signed-off-by: Rudolf Marek Signed-off-by: Jean Delvare --- drivers/hwmon/w83793.c | 63 ++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 54 insertions(+), 9 deletions(-) (limited to 'drivers/hwmon/w83793.c') diff --git a/drivers/hwmon/w83793.c b/drivers/hwmon/w83793.c index 99e603a6a667..c2b7834ecaa9 100644 --- a/drivers/hwmon/w83793.c +++ b/drivers/hwmon/w83793.c @@ -204,6 +204,7 @@ struct w83793_data { u8 temp_fan_map[6]; /* Temp controls which pwm fan, bit field */ u8 has_pwm; + u8 has_temp; u8 pwm_enable; /* Register value, each Temp has 1 bit */ u8 pwm_uptime; /* Register value */ u8 pwm_downtime; /* Register value */ @@ -554,8 +555,7 @@ store_temp_mode(struct device *dev, struct device_attribute *attr, if ((val == 6) && (index < 4)) { val -= 3; } else if ((val == 3 && index < 4) - || (val == 4 && index >= 4) - || val == 0) { + || (val == 4 && index >= 4)) { /* transform diode or thermistor into internal enable */ val = !!val; } else { @@ -986,12 +986,6 @@ static struct sensor_device_attribute_2 w83793_sensor_attr_2[] = { SENSOR_ATTR_IN(7), SENSOR_ATTR_IN(8), SENSOR_ATTR_IN(9), - SENSOR_ATTR_TEMP(1), - SENSOR_ATTR_TEMP(2), - SENSOR_ATTR_TEMP(3), - SENSOR_ATTR_TEMP(4), - SENSOR_ATTR_TEMP(5), - SENSOR_ATTR_TEMP(6), SENSOR_ATTR_FAN(1), SENSOR_ATTR_FAN(2), SENSOR_ATTR_FAN(3), @@ -1002,6 +996,15 @@ static struct sensor_device_attribute_2 w83793_sensor_attr_2[] = { SENSOR_ATTR_PWM(3), }; +static struct sensor_device_attribute_2 w83793_temp[] = { + SENSOR_ATTR_TEMP(1), + SENSOR_ATTR_TEMP(2), + SENSOR_ATTR_TEMP(3), + SENSOR_ATTR_TEMP(4), + SENSOR_ATTR_TEMP(5), + SENSOR_ATTR_TEMP(6), +}; + /* Fan6-Fan12 */ static struct sensor_device_attribute_2 w83793_left_fan[] = { SENSOR_ATTR_FAN(6), @@ -1082,6 +1085,9 @@ static int w83793_detach_client(struct i2c_client *client) for (i = 0; i < ARRAY_SIZE(w83793_left_pwm); i++) device_remove_file(dev, &w83793_left_pwm[i].dev_attr); + + for (i = 0; i < ARRAY_SIZE(w83793_temp); i++) + device_remove_file(dev, &w83793_temp[i].dev_attr); } if ((err = i2c_detach_client(client))) @@ -1194,6 +1200,7 @@ static int w83793_detect(struct i2c_adapter *adapter, int address, int kind) struct w83793_data *data; int files_fan = ARRAY_SIZE(w83793_left_fan) / 7; int files_pwm = ARRAY_SIZE(w83793_left_pwm) / 5; + int files_temp = ARRAY_SIZE(w83793_temp) / 6; int err = 0; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { @@ -1320,6 +1327,23 @@ static int w83793_detect(struct i2c_adapter *adapter, int address, int kind) data->has_pwm |= 0x80; } + /* check the temp1-6 mode, ignore former AMDSI selected inputs */ + tmp = w83793_read_value(client,W83793_REG_TEMP_MODE[0]); + if (tmp & 0x01) + data->has_temp |= 0x01; + if (tmp & 0x04) + data->has_temp |= 0x02; + if (tmp & 0x10) + data->has_temp |= 0x04; + if (tmp & 0x40) + data->has_temp |= 0x08; + + tmp = w83793_read_value(client,W83793_REG_TEMP_MODE[1]); + if (tmp & 0x01) + data->has_temp |= 0x10; + if (tmp & 0x02) + data->has_temp |= 0x20; + /* Register sysfs hooks */ for (i = 0; i < ARRAY_SIZE(w83793_sensor_attr_2); i++) { err = device_create_file(dev, @@ -1335,6 +1359,19 @@ static int w83793_detect(struct i2c_adapter *adapter, int address, int kind) } + for (i = 0; i < 6; i++) { + int j; + if (!(data->has_temp & (1 << i))) + continue; + for (j = 0; j < files_temp; j++) { + err = device_create_file(dev, + &w83793_temp[(i) * files_temp + + j].dev_attr); + if (err) + goto exit_remove; + } + } + for (i = 5; i < 12; i++) { int j; if (!(data->has_fan & (1 << i))) @@ -1384,6 +1421,9 @@ exit_remove: for (i = 0; i < ARRAY_SIZE(w83793_left_pwm); i++) device_remove_file(dev, &w83793_left_pwm[i].dev_attr); + for (i = 0; i < ARRAY_SIZE(w83793_temp); i++) + device_remove_file(dev, &w83793_temp[i].dev_attr); + if (data->lm75[0] != NULL) { i2c_detach_client(data->lm75[0]); kfree(data->lm75[0]); @@ -1435,6 +1475,8 @@ static void w83793_update_nonvolatile(struct device *dev) } for (i = 0; i < ARRAY_SIZE(data->temp_fan_map); i++) { + if (!(data->has_temp & (1 << i))) + continue; data->temp_fan_map[i] = w83793_read_value(client, W83793_REG_TEMP_FAN_MAP(i)); for (j = 1; j < 5; j++) { @@ -1517,9 +1559,12 @@ static struct w83793_data *w83793_update_device(struct device *dev) w83793_read_value(client, W83793_REG_FAN(i) + 1); } - for (i = 0; i < ARRAY_SIZE(data->temp); i++) + for (i = 0; i < ARRAY_SIZE(data->temp); i++) { + if (!(data->has_temp & (1 << i))) + continue; data->temp[i][TEMP_READ] = w83793_read_value(client, W83793_REG_TEMP[i][TEMP_READ]); + } data->temp_low_bits = w83793_read_value(client, W83793_REG_TEMP_LOW_BITS); -- cgit v1.2.2 From c92943152884e3777439ad40a40126f2e51b8ea8 Mon Sep 17 00:00:00 2001 From: Rudolf Marek Date: Thu, 18 Jan 2007 22:14:24 +0100 Subject: hwmon/w83793: Fix the fan input detection Catch the cases when alternative pins are used to route the fan9-12 input. Signed-off-by: Rudolf Marek Signed-off-by: Gong Jun Signed-off-by: Jean Delvare --- drivers/hwmon/w83793.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'drivers/hwmon/w83793.c') diff --git a/drivers/hwmon/w83793.c b/drivers/hwmon/w83793.c index c2b7834ecaa9..7cadef8cd87d 100644 --- a/drivers/hwmon/w83793.c +++ b/drivers/hwmon/w83793.c @@ -1327,6 +1327,20 @@ static int w83793_detect(struct i2c_adapter *adapter, int address, int kind) data->has_pwm |= 0x80; } + tmp = w83793_read_value(client, W83793_REG_FANIN_SEL); + if ((tmp & 0x01) && (val & 0x08)) { /* fan 9, second location */ + data->has_fan |= 0x100; + } + if ((tmp & 0x02) && (val & 0x10)) { /* fan 10, second location */ + data->has_fan |= 0x200; + } + if ((tmp & 0x04) && (val & 0x20)) { /* fan 11, second location */ + data->has_fan |= 0x400; + } + if ((tmp & 0x08) && (val & 0x40)) { /* fan 12, second location */ + data->has_fan |= 0x800; + } + /* check the temp1-6 mode, ignore former AMDSI selected inputs */ tmp = w83793_read_value(client,W83793_REG_TEMP_MODE[0]); if (tmp & 0x01) -- cgit v1.2.2 From c70a8c345fd770ecb2ff334bdf88b63edaffb77d Mon Sep 17 00:00:00 2001 From: Gong Jun Date: Thu, 18 Jan 2007 22:14:24 +0100 Subject: hwmon/w83793: Hide invalid VID readings Ignore the VID readings when the motherboard has not designed the function. Signed-off-by: Gong Jun Signed-off-by: Rudolf Marek Signed-off-by: Jean Delvare --- drivers/hwmon/w83793.c | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) (limited to 'drivers/hwmon/w83793.c') diff --git a/drivers/hwmon/w83793.c b/drivers/hwmon/w83793.c index 7cadef8cd87d..253ffaf1568a 100644 --- a/drivers/hwmon/w83793.c +++ b/drivers/hwmon/w83793.c @@ -205,6 +205,7 @@ struct w83793_data { u8 has_pwm; u8 has_temp; + u8 has_vid; u8 pwm_enable; /* Register value, each Temp has 1 bit */ u8 pwm_uptime; /* Register value */ u8 pwm_downtime; /* Register value */ @@ -1025,9 +1026,12 @@ static struct sensor_device_attribute_2 w83793_left_pwm[] = { SENSOR_ATTR_PWM(8), }; -static struct sensor_device_attribute_2 sda_single_files[] = { +static struct sensor_device_attribute_2 w83793_vid[] = { SENSOR_ATTR_2(cpu0_vid, S_IRUGO, show_vid, NULL, NOT_USED, 0), SENSOR_ATTR_2(cpu1_vid, S_IRUGO, show_vid, NULL, NOT_USED, 1), +}; + +static struct sensor_device_attribute_2 sda_single_files[] = { SENSOR_ATTR_2(vrm, S_IWUSR | S_IRUGO, show_vrm, store_vrm, NOT_USED, NOT_USED), SENSOR_ATTR_2(chassis, S_IWUSR | S_IRUGO, show_alarm_beep, @@ -1080,6 +1084,9 @@ static int w83793_detach_client(struct i2c_client *client) for (i = 0; i < ARRAY_SIZE(sda_single_files); i++) device_remove_file(dev, &sda_single_files[i].dev_attr); + for (i = 0; i < ARRAY_SIZE(w83793_vid); i++) + device_remove_file(dev, &w83793_vid[i].dev_attr); + for (i = 0; i < ARRAY_SIZE(w83793_left_fan); i++) device_remove_file(dev, &w83793_left_fan[i].dev_attr); @@ -1358,6 +1365,13 @@ static int w83793_detect(struct i2c_adapter *adapter, int address, int kind) if (tmp & 0x02) data->has_temp |= 0x20; + /* Detect the VID usage and ignore unused input */ + tmp = w83793_read_value(client, W83793_REG_MFC); + if (!(tmp & 0x29)) + data->has_vid |= 0x1; /* has VIDA */ + if (tmp & 0x80) + data->has_vid |= 0x2; /* has VIDB */ + /* Register sysfs hooks */ for (i = 0; i < ARRAY_SIZE(w83793_sensor_attr_2); i++) { err = device_create_file(dev, @@ -1366,6 +1380,14 @@ static int w83793_detect(struct i2c_adapter *adapter, int address, int kind) goto exit_remove; } + for (i = 0; i < ARRAY_SIZE(w83793_vid); i++) { + if (!(data->has_vid & (1 << i))) + continue; + err = device_create_file(dev, &w83793_vid[i].dev_attr); + if (err) + goto exit_remove; + } + for (i = 0; i < ARRAY_SIZE(sda_single_files); i++) { err = device_create_file(dev, &sda_single_files[i].dev_attr); if (err) @@ -1429,6 +1451,9 @@ exit_remove: for (i = 0; i < ARRAY_SIZE(sda_single_files); i++) device_remove_file(dev, &sda_single_files[i].dev_attr); + for (i = 0; i < ARRAY_SIZE(w83793_vid); i++) + device_remove_file(dev, &w83793_vid[i].dev_attr); + for (i = 0; i < ARRAY_SIZE(w83793_left_fan); i++) device_remove_file(dev, &w83793_left_fan[i].dev_attr); @@ -1593,8 +1618,10 @@ static struct w83793_data *w83793_update_device(struct device *dev) for (i = 0; i < ARRAY_SIZE(data->alarms); i++) data->alarms[i] = w83793_read_value(client, W83793_REG_ALARM(i)); - data->vid[0] = w83793_read_value(client, W83793_REG_VID_INA); - data->vid[1] = w83793_read_value(client, W83793_REG_VID_INB); + if (data->has_vid & 0x01) + data->vid[0] = w83793_read_value(client, W83793_REG_VID_INA); + if (data->has_vid & 0x02) + data->vid[1] = w83793_read_value(client, W83793_REG_VID_INB); w83793_update_nonvolatile(dev); data->last_updated = jiffies; data->valid = 1; -- cgit v1.2.2