mirror of
https://github.com/fail0verflow/switch-linux.git
synced 2025-05-04 02:34:21 -04:00
hwmon: (w83627ehf) Add support for the W83627UHG
This is essentially a stripped down version of the W83627DHG. Noticeable difference is that it is still powered with +5V, as older models, even though the ADC resolution is 8 mV as newer models have. Thanks to Ulf Bruman (Saab Group) for doing all the testing. Signed-off-by: Jean Delvare <khali@linux-fr.org> Acked-by: Guenter Roeck <guenter.roeck@ericsson.com>
This commit is contained in:
parent
6ba71de5f8
commit
eff7687d47
3 changed files with 139 additions and 40 deletions
|
@ -14,6 +14,10 @@ Supported chips:
|
||||||
Prefix: 'w83627dhg'
|
Prefix: 'w83627dhg'
|
||||||
Addresses scanned: ISA address retrieved from Super I/O registers
|
Addresses scanned: ISA address retrieved from Super I/O registers
|
||||||
Datasheet: not available
|
Datasheet: not available
|
||||||
|
* Winbond W83627UHG
|
||||||
|
Prefix: 'w83627uhg'
|
||||||
|
Addresses scanned: ISA address retrieved from Super I/O registers
|
||||||
|
Datasheet: available from www.nuvoton.com
|
||||||
* Winbond W83667HG
|
* Winbond W83667HG
|
||||||
Prefix: 'w83667hg'
|
Prefix: 'w83667hg'
|
||||||
Addresses scanned: ISA address retrieved from Super I/O registers
|
Addresses scanned: ISA address retrieved from Super I/O registers
|
||||||
|
@ -42,14 +46,13 @@ Description
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
This driver implements support for the Winbond W83627EHF, W83627EHG,
|
This driver implements support for the Winbond W83627EHF, W83627EHG,
|
||||||
W83627DHG, W83627DHG-P, W83667HG, W83667HG-B, W83667HG-I (NCT6775F),
|
W83627DHG, W83627DHG-P, W83627UHG, W83667HG, W83667HG-B, W83667HG-I
|
||||||
and NCT6776F super I/O chips. We will refer to them collectively as
|
(NCT6775F), and NCT6776F super I/O chips. We will refer to them collectively
|
||||||
Winbond chips.
|
as Winbond chips.
|
||||||
|
|
||||||
The chips implement three temperature sensors (up to four for 667HG-B, and nine
|
The chips implement 2 to 4 temperature sensors (9 for NCT6775F and NCT6776F),
|
||||||
for NCT6775F and NCT6776F), five fan rotation speed sensors, ten analog voltage
|
2 to 5 fan rotation speed sensors, 8 to 10 analog voltage sensors, one VID
|
||||||
sensors (only nine for the 627DHG), one VID (6 pins for the 627EHF/EHG, 8 pins
|
(except for 627UHG), alarms with beep warnings (control unimplemented),
|
||||||
for the 627DHG and 667HG), alarms with beep warnings (control unimplemented),
|
|
||||||
and some automatic fan regulation strategies (plus manual fan control mode).
|
and some automatic fan regulation strategies (plus manual fan control mode).
|
||||||
|
|
||||||
The temperature sensor sources on W82677HG-B, NCT6775F, and NCT6776F are
|
The temperature sensor sources on W82677HG-B, NCT6775F, and NCT6776F are
|
||||||
|
@ -86,17 +89,16 @@ follows:
|
||||||
|
|
||||||
temp1 -> pwm1
|
temp1 -> pwm1
|
||||||
temp2 -> pwm2
|
temp2 -> pwm2
|
||||||
temp3 -> pwm3
|
temp3 -> pwm3 (not on 627UHG)
|
||||||
prog -> pwm4 (not on 667HG and 667HG-B; the programmable setting is not
|
prog -> pwm4 (not on 667HG and 667HG-B; the programmable setting is not
|
||||||
supported by the driver)
|
supported by the driver)
|
||||||
|
|
||||||
/sys files
|
/sys files
|
||||||
----------
|
----------
|
||||||
|
|
||||||
name - this is a standard hwmon device entry. For the W83627EHF and W83627EHG,
|
name - this is a standard hwmon device entry, it contains the name of
|
||||||
it is set to "w83627ehf", for the W83627DHG it is set to "w83627dhg",
|
the device (see the prefix in the list of supported devices at
|
||||||
for the W83667HG and W83667HG-B it is set to "w83667hg", for NCT6775F it
|
the top of this file)
|
||||||
is set to "nct6775", and for NCT6776F it is set to "nct6776".
|
|
||||||
|
|
||||||
pwm[1-4] - this file stores PWM duty cycle or DC value (fan speed) in range:
|
pwm[1-4] - this file stores PWM duty cycle or DC value (fan speed) in range:
|
||||||
0 (stop) to 255 (full)
|
0 (stop) to 255 (full)
|
||||||
|
|
|
@ -1282,7 +1282,7 @@ config SENSORS_W83627HF
|
||||||
will be called w83627hf.
|
will be called w83627hf.
|
||||||
|
|
||||||
config SENSORS_W83627EHF
|
config SENSORS_W83627EHF
|
||||||
tristate "Winbond W83627EHF/EHG/DHG, W83667HG, NCT6775F, NCT6776F"
|
tristate "Winbond W83627EHF/EHG/DHG/UHG, W83667HG, NCT6775F, NCT6776F"
|
||||||
depends on !PPC
|
depends on !PPC
|
||||||
select HWMON_VID
|
select HWMON_VID
|
||||||
help
|
help
|
||||||
|
@ -1292,7 +1292,8 @@ config SENSORS_W83627EHF
|
||||||
This driver also supports the W83627EHG, which is the lead-free
|
This driver also supports the W83627EHG, which is the lead-free
|
||||||
version of the W83627EHF, and the W83627DHG, which is a similar
|
version of the W83627EHF, and the W83627DHG, which is a similar
|
||||||
chip suited for specific Intel processors that use PECI such as
|
chip suited for specific Intel processors that use PECI such as
|
||||||
the Core 2 Duo.
|
the Core 2 Duo. And also the W83627UHG, which is a stripped down
|
||||||
|
version of the W83627DHG (as far as hardware monitoring goes.)
|
||||||
|
|
||||||
This driver also supports Nuvoton W83667HG, W83667HG-B, NCT6775F
|
This driver also supports Nuvoton W83667HG, W83667HG-B, NCT6775F
|
||||||
(also known as W83667HG-I), and NCT6776F.
|
(also known as W83667HG-I), and NCT6776F.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
w83627ehf - Driver for the hardware monitoring functionality of
|
w83627ehf - Driver for the hardware monitoring functionality of
|
||||||
the Winbond W83627EHF Super-I/O chip
|
the Winbond W83627EHF Super-I/O chip
|
||||||
Copyright (C) 2005 Jean Delvare <khali@linux-fr.org>
|
Copyright (C) 2005-2011 Jean Delvare <khali@linux-fr.org>
|
||||||
Copyright (C) 2006 Yuan Mu (Winbond),
|
Copyright (C) 2006 Yuan Mu (Winbond),
|
||||||
Rudolf Marek <r.marek@assembler.cz>
|
Rudolf Marek <r.marek@assembler.cz>
|
||||||
David Hubbard <david.c.hubbard@gmail.com>
|
David Hubbard <david.c.hubbard@gmail.com>
|
||||||
|
@ -39,6 +39,7 @@
|
||||||
0x8860 0xa1
|
0x8860 0xa1
|
||||||
w83627dhg 9 5 4 3 0xa020 0xc1 0x5ca3
|
w83627dhg 9 5 4 3 0xa020 0xc1 0x5ca3
|
||||||
w83627dhg-p 9 5 4 3 0xb070 0xc1 0x5ca3
|
w83627dhg-p 9 5 4 3 0xb070 0xc1 0x5ca3
|
||||||
|
w83627uhg 8 2 2 2 0xa230 0xc1 0x5ca3
|
||||||
w83667hg 9 5 3 3 0xa510 0xc1 0x5ca3
|
w83667hg 9 5 3 3 0xa510 0xc1 0x5ca3
|
||||||
w83667hg-b 9 5 3 4 0xb350 0xc1 0x5ca3
|
w83667hg-b 9 5 3 4 0xb350 0xc1 0x5ca3
|
||||||
nct6775f 9 4 3 9 0xb470 0xc1 0x5ca3
|
nct6775f 9 4 3 9 0xb470 0xc1 0x5ca3
|
||||||
|
@ -61,14 +62,17 @@
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include "lm75.h"
|
#include "lm75.h"
|
||||||
|
|
||||||
enum kinds { w83627ehf, w83627dhg, w83627dhg_p, w83667hg, w83667hg_b, nct6775,
|
enum kinds {
|
||||||
nct6776 };
|
w83627ehf, w83627dhg, w83627dhg_p, w83627uhg,
|
||||||
|
w83667hg, w83667hg_b, nct6775, nct6776,
|
||||||
|
};
|
||||||
|
|
||||||
/* used to set data->name = w83627ehf_device_names[data->sio_kind] */
|
/* used to set data->name = w83627ehf_device_names[data->sio_kind] */
|
||||||
static const char * const w83627ehf_device_names[] = {
|
static const char * const w83627ehf_device_names[] = {
|
||||||
"w83627ehf",
|
"w83627ehf",
|
||||||
"w83627dhg",
|
"w83627dhg",
|
||||||
"w83627dhg",
|
"w83627dhg",
|
||||||
|
"w83627uhg",
|
||||||
"w83667hg",
|
"w83667hg",
|
||||||
"w83667hg",
|
"w83667hg",
|
||||||
"nct6775",
|
"nct6775",
|
||||||
|
@ -104,6 +108,7 @@ MODULE_PARM_DESC(fan_debounce, "Enable debouncing for fan RPM signal");
|
||||||
#define SIO_W83627EHG_ID 0x8860
|
#define SIO_W83627EHG_ID 0x8860
|
||||||
#define SIO_W83627DHG_ID 0xa020
|
#define SIO_W83627DHG_ID 0xa020
|
||||||
#define SIO_W83627DHG_P_ID 0xb070
|
#define SIO_W83627DHG_P_ID 0xb070
|
||||||
|
#define SIO_W83627UHG_ID 0xa230
|
||||||
#define SIO_W83667HG_ID 0xa510
|
#define SIO_W83667HG_ID 0xa510
|
||||||
#define SIO_W83667HG_B_ID 0xb350
|
#define SIO_W83667HG_B_ID 0xb350
|
||||||
#define SIO_NCT6775_ID 0xb470
|
#define SIO_NCT6775_ID 0xb470
|
||||||
|
@ -388,18 +393,23 @@ div_from_reg(u8 reg)
|
||||||
return 1 << reg;
|
return 1 << reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Some of analog inputs have internal scaling (2x), 8mV is ADC LSB */
|
/* Some of the voltage inputs have internal scaling, the tables below
|
||||||
|
* contain 8 (the ADC LSB in mV) * scaling factor * 100 */
|
||||||
|
static const u16 scale_in_common[10] = {
|
||||||
|
800, 800, 1600, 1600, 800, 800, 800, 1600, 1600, 800
|
||||||
|
};
|
||||||
|
static const u16 scale_in_w83627uhg[9] = {
|
||||||
|
800, 800, 3328, 3424, 800, 800, 0, 3328, 3400
|
||||||
|
};
|
||||||
|
|
||||||
static u8 scale_in[10] = { 8, 8, 16, 16, 8, 8, 8, 16, 16, 8 };
|
static inline long in_from_reg(u8 reg, u8 nr, const u16 *scale_in)
|
||||||
|
|
||||||
static inline long in_from_reg(u8 reg, u8 nr)
|
|
||||||
{
|
{
|
||||||
return reg * scale_in[nr];
|
return DIV_ROUND_CLOSEST(reg * scale_in[nr], 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline u8 in_to_reg(u32 val, u8 nr)
|
static inline u8 in_to_reg(u32 val, u8 nr, const u16 *scale_in)
|
||||||
{
|
{
|
||||||
return SENSORS_LIMIT(((val + (scale_in[nr] / 2)) / scale_in[nr]), 0,
|
return SENSORS_LIMIT(DIV_ROUND_CLOSEST(val * 100, scale_in[nr]), 0,
|
||||||
255);
|
255);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -430,6 +440,7 @@ struct w83627ehf_data {
|
||||||
const u16 *REG_FAN_STOP_TIME;
|
const u16 *REG_FAN_STOP_TIME;
|
||||||
const u16 *REG_FAN_MAX_OUTPUT;
|
const u16 *REG_FAN_MAX_OUTPUT;
|
||||||
const u16 *REG_FAN_STEP_OUTPUT;
|
const u16 *REG_FAN_STEP_OUTPUT;
|
||||||
|
const u16 *scale_in;
|
||||||
|
|
||||||
unsigned int (*fan_from_reg)(u16 reg, unsigned int divreg);
|
unsigned int (*fan_from_reg)(u16 reg, unsigned int divreg);
|
||||||
unsigned int (*fan_from_reg_min)(u16 reg, unsigned int divreg);
|
unsigned int (*fan_from_reg_min)(u16 reg, unsigned int divreg);
|
||||||
|
@ -481,7 +492,8 @@ struct w83627ehf_data {
|
||||||
u8 vrm;
|
u8 vrm;
|
||||||
|
|
||||||
u16 have_temp;
|
u16 have_temp;
|
||||||
u8 in6_skip;
|
u8 in6_skip:1;
|
||||||
|
u8 temp3_val_only:1;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct w83627ehf_sio_data {
|
struct w83627ehf_sio_data {
|
||||||
|
@ -907,7 +919,8 @@ show_##reg(struct device *dev, struct device_attribute *attr, \
|
||||||
struct sensor_device_attribute *sensor_attr = \
|
struct sensor_device_attribute *sensor_attr = \
|
||||||
to_sensor_dev_attr(attr); \
|
to_sensor_dev_attr(attr); \
|
||||||
int nr = sensor_attr->index; \
|
int nr = sensor_attr->index; \
|
||||||
return sprintf(buf, "%ld\n", in_from_reg(data->reg[nr], nr)); \
|
return sprintf(buf, "%ld\n", in_from_reg(data->reg[nr], nr, \
|
||||||
|
data->scale_in)); \
|
||||||
}
|
}
|
||||||
show_in_reg(in)
|
show_in_reg(in)
|
||||||
show_in_reg(in_min)
|
show_in_reg(in_min)
|
||||||
|
@ -928,7 +941,7 @@ store_in_##reg(struct device *dev, struct device_attribute *attr, \
|
||||||
if (err < 0) \
|
if (err < 0) \
|
||||||
return err; \
|
return err; \
|
||||||
mutex_lock(&data->update_lock); \
|
mutex_lock(&data->update_lock); \
|
||||||
data->in_##reg[nr] = in_to_reg(val, nr); \
|
data->in_##reg[nr] = in_to_reg(val, nr, data->scale_in); \
|
||||||
w83627ehf_write_value(data, W83627EHF_REG_IN_##REG(nr), \
|
w83627ehf_write_value(data, W83627EHF_REG_IN_##REG(nr), \
|
||||||
data->in_##reg[nr]); \
|
data->in_##reg[nr]); \
|
||||||
mutex_unlock(&data->update_lock); \
|
mutex_unlock(&data->update_lock); \
|
||||||
|
@ -1617,25 +1630,28 @@ static struct sensor_device_attribute sda_sf3_arrays_fan4[] = {
|
||||||
store_fan_step_output, 3),
|
store_fan_step_output, 3),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct sensor_device_attribute sda_sf3_arrays_fan3[] = {
|
||||||
|
SENSOR_ATTR(pwm3_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time,
|
||||||
|
store_fan_stop_time, 2),
|
||||||
|
SENSOR_ATTR(pwm3_start_output, S_IWUSR | S_IRUGO, show_fan_start_output,
|
||||||
|
store_fan_start_output, 2),
|
||||||
|
SENSOR_ATTR(pwm3_stop_output, S_IWUSR | S_IRUGO, show_fan_stop_output,
|
||||||
|
store_fan_stop_output, 2),
|
||||||
|
};
|
||||||
|
|
||||||
static struct sensor_device_attribute sda_sf3_arrays[] = {
|
static struct sensor_device_attribute sda_sf3_arrays[] = {
|
||||||
SENSOR_ATTR(pwm1_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time,
|
SENSOR_ATTR(pwm1_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time,
|
||||||
store_fan_stop_time, 0),
|
store_fan_stop_time, 0),
|
||||||
SENSOR_ATTR(pwm2_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time,
|
SENSOR_ATTR(pwm2_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time,
|
||||||
store_fan_stop_time, 1),
|
store_fan_stop_time, 1),
|
||||||
SENSOR_ATTR(pwm3_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time,
|
|
||||||
store_fan_stop_time, 2),
|
|
||||||
SENSOR_ATTR(pwm1_start_output, S_IWUSR | S_IRUGO, show_fan_start_output,
|
SENSOR_ATTR(pwm1_start_output, S_IWUSR | S_IRUGO, show_fan_start_output,
|
||||||
store_fan_start_output, 0),
|
store_fan_start_output, 0),
|
||||||
SENSOR_ATTR(pwm2_start_output, S_IWUSR | S_IRUGO, show_fan_start_output,
|
SENSOR_ATTR(pwm2_start_output, S_IWUSR | S_IRUGO, show_fan_start_output,
|
||||||
store_fan_start_output, 1),
|
store_fan_start_output, 1),
|
||||||
SENSOR_ATTR(pwm3_start_output, S_IWUSR | S_IRUGO, show_fan_start_output,
|
|
||||||
store_fan_start_output, 2),
|
|
||||||
SENSOR_ATTR(pwm1_stop_output, S_IWUSR | S_IRUGO, show_fan_stop_output,
|
SENSOR_ATTR(pwm1_stop_output, S_IWUSR | S_IRUGO, show_fan_stop_output,
|
||||||
store_fan_stop_output, 0),
|
store_fan_stop_output, 0),
|
||||||
SENSOR_ATTR(pwm2_stop_output, S_IWUSR | S_IRUGO, show_fan_stop_output,
|
SENSOR_ATTR(pwm2_stop_output, S_IWUSR | S_IRUGO, show_fan_stop_output,
|
||||||
store_fan_stop_output, 1),
|
store_fan_stop_output, 1),
|
||||||
SENSOR_ATTR(pwm3_stop_output, S_IWUSR | S_IRUGO, show_fan_stop_output,
|
|
||||||
store_fan_stop_output, 2),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1728,6 +1744,8 @@ static void w83627ehf_device_remove_files(struct device *dev)
|
||||||
data->REG_FAN_STEP_OUTPUT[attr->index] != 0xff)
|
data->REG_FAN_STEP_OUTPUT[attr->index] != 0xff)
|
||||||
device_remove_file(dev, &attr->dev_attr);
|
device_remove_file(dev, &attr->dev_attr);
|
||||||
}
|
}
|
||||||
|
for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan3); i++)
|
||||||
|
device_remove_file(dev, &sda_sf3_arrays_fan3[i].dev_attr);
|
||||||
for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++)
|
for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++)
|
||||||
device_remove_file(dev, &sda_sf3_arrays_fan4[i].dev_attr);
|
device_remove_file(dev, &sda_sf3_arrays_fan4[i].dev_attr);
|
||||||
for (i = 0; i < data->in_num; i++) {
|
for (i = 0; i < data->in_num; i++) {
|
||||||
|
@ -1756,6 +1774,8 @@ static void w83627ehf_device_remove_files(struct device *dev)
|
||||||
continue;
|
continue;
|
||||||
device_remove_file(dev, &sda_temp_input[i].dev_attr);
|
device_remove_file(dev, &sda_temp_input[i].dev_attr);
|
||||||
device_remove_file(dev, &sda_temp_label[i].dev_attr);
|
device_remove_file(dev, &sda_temp_label[i].dev_attr);
|
||||||
|
if (i == 2 && data->temp3_val_only)
|
||||||
|
continue;
|
||||||
device_remove_file(dev, &sda_temp_max[i].dev_attr);
|
device_remove_file(dev, &sda_temp_max[i].dev_attr);
|
||||||
device_remove_file(dev, &sda_temp_max_hyst[i].dev_attr);
|
device_remove_file(dev, &sda_temp_max_hyst[i].dev_attr);
|
||||||
if (i > 2)
|
if (i > 2)
|
||||||
|
@ -1808,6 +1828,9 @@ static inline void __devinit w83627ehf_init_device(struct w83627ehf_data *data,
|
||||||
case w83627ehf:
|
case w83627ehf:
|
||||||
diode = w83627ehf_read_value(data, W83627EHF_REG_DIODE);
|
diode = w83627ehf_read_value(data, W83627EHF_REG_DIODE);
|
||||||
break;
|
break;
|
||||||
|
case w83627uhg:
|
||||||
|
diode = 0x00;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
diode = 0x70;
|
diode = 0x70;
|
||||||
}
|
}
|
||||||
|
@ -1871,6 +1894,13 @@ w83627ehf_check_fan_inputs(const struct w83627ehf_sio_data *sio_data,
|
||||||
{
|
{
|
||||||
int fan3pin, fan4pin, fan4min, fan5pin, regval;
|
int fan3pin, fan4pin, fan4min, fan5pin, regval;
|
||||||
|
|
||||||
|
/* The W83627UHG is simple, only two fan inputs, no config */
|
||||||
|
if (sio_data->kind == w83627uhg) {
|
||||||
|
data->has_fan = 0x03; /* fan1 and fan2 */
|
||||||
|
data->has_fan_min = 0x03;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
superio_enter(sio_data->sioreg);
|
superio_enter(sio_data->sioreg);
|
||||||
|
|
||||||
/* fan4 and fan5 share some pins with the GPIO and serial flash */
|
/* fan4 and fan5 share some pins with the GPIO and serial flash */
|
||||||
|
@ -1962,11 +1992,21 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
/* 627EHG and 627EHF have 10 voltage inputs; 627DHG and 667HG have 9 */
|
/* 627EHG and 627EHF have 10 voltage inputs; 627DHG and 667HG have 9 */
|
||||||
data->in_num = (sio_data->kind == w83627ehf) ? 10 : 9;
|
data->in_num = (sio_data->kind == w83627ehf) ? 10 : 9;
|
||||||
/* 667HG, NCT6775F, and NCT6776F have 3 pwms */
|
/* 667HG, NCT6775F, and NCT6776F have 3 pwms, and 627UHG has only 2 */
|
||||||
data->pwm_num = (sio_data->kind == w83667hg
|
switch (sio_data->kind) {
|
||||||
|| sio_data->kind == w83667hg_b
|
default:
|
||||||
|| sio_data->kind == nct6775
|
data->pwm_num = 4;
|
||||||
|| sio_data->kind == nct6776) ? 3 : 4;
|
break;
|
||||||
|
case w83667hg:
|
||||||
|
case w83667hg_b:
|
||||||
|
case nct6775:
|
||||||
|
case nct6776:
|
||||||
|
data->pwm_num = 3;
|
||||||
|
break;
|
||||||
|
case w83627uhg:
|
||||||
|
data->pwm_num = 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* Default to 3 temperature inputs, code below will adjust as needed */
|
/* Default to 3 temperature inputs, code below will adjust as needed */
|
||||||
data->have_temp = 0x07;
|
data->have_temp = 0x07;
|
||||||
|
@ -2084,6 +2124,42 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
|
||||||
|| (data->temp_src[3] == 2 && (data->have_temp & (1 << 3))))
|
|| (data->temp_src[3] == 2 && (data->have_temp & (1 << 3))))
|
||||||
data->in6_skip = 1;
|
data->in6_skip = 1;
|
||||||
|
|
||||||
|
data->temp_label = w83667hg_b_temp_label;
|
||||||
|
} else if (sio_data->kind == w83627uhg) {
|
||||||
|
u8 reg;
|
||||||
|
|
||||||
|
w83627ehf_set_temp_reg_ehf(data, 3);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Temperature sources for temp1 and temp2 are selected with
|
||||||
|
* bank 0, registers 0x49 and 0x4a.
|
||||||
|
*/
|
||||||
|
data->temp_src[0] = 0; /* SYSTIN */
|
||||||
|
reg = w83627ehf_read_value(data, 0x49) & 0x07;
|
||||||
|
/* Adjust to have the same mapping as other source registers */
|
||||||
|
if (reg == 0)
|
||||||
|
data->temp_src[1]++;
|
||||||
|
else if (reg >= 2 && reg <= 5)
|
||||||
|
data->temp_src[1] += 2;
|
||||||
|
else /* should never happen */
|
||||||
|
data->have_temp &= ~(1 << 1);
|
||||||
|
reg = w83627ehf_read_value(data, 0x4a);
|
||||||
|
data->temp_src[2] = reg >> 5;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Skip temp3 if source is invalid or the same as temp1
|
||||||
|
* or temp2.
|
||||||
|
*/
|
||||||
|
if (data->temp_src[2] == 2 || data->temp_src[2] == 3 ||
|
||||||
|
data->temp_src[2] == data->temp_src[0] ||
|
||||||
|
((data->have_temp & (1 << 1)) &&
|
||||||
|
data->temp_src[2] == data->temp_src[1]))
|
||||||
|
data->have_temp &= ~(1 << 2);
|
||||||
|
else
|
||||||
|
data->temp3_val_only = 1; /* No limit regs */
|
||||||
|
|
||||||
|
data->in6_skip = 1; /* No VIN3 */
|
||||||
|
|
||||||
data->temp_label = w83667hg_b_temp_label;
|
data->temp_label = w83667hg_b_temp_label;
|
||||||
} else {
|
} else {
|
||||||
w83627ehf_set_temp_reg_ehf(data, 3);
|
w83627ehf_set_temp_reg_ehf(data, 3);
|
||||||
|
@ -2162,6 +2238,12 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
|
||||||
W83627EHF_REG_FAN_STEP_OUTPUT_COMMON;
|
W83627EHF_REG_FAN_STEP_OUTPUT_COMMON;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Setup input voltage scaling factors */
|
||||||
|
if (sio_data->kind == w83627uhg)
|
||||||
|
data->scale_in = scale_in_w83627uhg;
|
||||||
|
else
|
||||||
|
data->scale_in = scale_in_common;
|
||||||
|
|
||||||
/* Initialize the chip */
|
/* Initialize the chip */
|
||||||
w83627ehf_init_device(data, sio_data->kind);
|
w83627ehf_init_device(data, sio_data->kind);
|
||||||
|
|
||||||
|
@ -2178,7 +2260,7 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
|
||||||
err = device_create_file(dev, &dev_attr_cpu0_vid);
|
err = device_create_file(dev, &dev_attr_cpu0_vid);
|
||||||
if (err)
|
if (err)
|
||||||
goto exit_release;
|
goto exit_release;
|
||||||
} else {
|
} else if (sio_data->kind != w83627uhg) {
|
||||||
superio_select(sio_data->sioreg, W83627EHF_LD_HWM);
|
superio_select(sio_data->sioreg, W83627EHF_LD_HWM);
|
||||||
if (superio_inb(sio_data->sioreg, SIO_REG_VID_CTRL) & 0x80) {
|
if (superio_inb(sio_data->sioreg, SIO_REG_VID_CTRL) & 0x80) {
|
||||||
/* Set VID input sensibility if needed. In theory the
|
/* Set VID input sensibility if needed. In theory the
|
||||||
|
@ -2268,7 +2350,14 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
|
||||||
goto exit_remove;
|
goto exit_remove;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* if fan4 is enabled create the sf3 files for it */
|
/* if fan3 and fan4 are enabled create the sf3 files for them */
|
||||||
|
if ((data->has_fan & (1 << 2)) && data->pwm_num >= 3)
|
||||||
|
for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan3); i++) {
|
||||||
|
err = device_create_file(dev,
|
||||||
|
&sda_sf3_arrays_fan3[i].dev_attr);
|
||||||
|
if (err)
|
||||||
|
goto exit_remove;
|
||||||
|
}
|
||||||
if ((data->has_fan & (1 << 3)) && data->pwm_num >= 4)
|
if ((data->has_fan & (1 << 3)) && data->pwm_num >= 4)
|
||||||
for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++) {
|
for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++) {
|
||||||
err = device_create_file(dev,
|
err = device_create_file(dev,
|
||||||
|
@ -2336,6 +2425,8 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
|
||||||
if (err)
|
if (err)
|
||||||
goto exit_remove;
|
goto exit_remove;
|
||||||
}
|
}
|
||||||
|
if (i == 2 && data->temp3_val_only)
|
||||||
|
continue;
|
||||||
if (data->reg_temp_over[i]) {
|
if (data->reg_temp_over[i]) {
|
||||||
err = device_create_file(dev,
|
err = device_create_file(dev,
|
||||||
&sda_temp_max[i].dev_attr);
|
&sda_temp_max[i].dev_attr);
|
||||||
|
@ -2419,6 +2510,7 @@ static int __init w83627ehf_find(int sioaddr, unsigned short *addr,
|
||||||
static const char __initdata sio_name_W83627EHG[] = "W83627EHG";
|
static const char __initdata sio_name_W83627EHG[] = "W83627EHG";
|
||||||
static const char __initdata sio_name_W83627DHG[] = "W83627DHG";
|
static const char __initdata sio_name_W83627DHG[] = "W83627DHG";
|
||||||
static const char __initdata sio_name_W83627DHG_P[] = "W83627DHG-P";
|
static const char __initdata sio_name_W83627DHG_P[] = "W83627DHG-P";
|
||||||
|
static const char __initdata sio_name_W83627UHG[] = "W83627UHG";
|
||||||
static const char __initdata sio_name_W83667HG[] = "W83667HG";
|
static const char __initdata sio_name_W83667HG[] = "W83667HG";
|
||||||
static const char __initdata sio_name_W83667HG_B[] = "W83667HG-B";
|
static const char __initdata sio_name_W83667HG_B[] = "W83667HG-B";
|
||||||
static const char __initdata sio_name_NCT6775[] = "NCT6775F";
|
static const char __initdata sio_name_NCT6775[] = "NCT6775F";
|
||||||
|
@ -2451,6 +2543,10 @@ static int __init w83627ehf_find(int sioaddr, unsigned short *addr,
|
||||||
sio_data->kind = w83627dhg_p;
|
sio_data->kind = w83627dhg_p;
|
||||||
sio_name = sio_name_W83627DHG_P;
|
sio_name = sio_name_W83627DHG_P;
|
||||||
break;
|
break;
|
||||||
|
case SIO_W83627UHG_ID:
|
||||||
|
sio_data->kind = w83627uhg;
|
||||||
|
sio_name = sio_name_W83627UHG;
|
||||||
|
break;
|
||||||
case SIO_W83667HG_ID:
|
case SIO_W83667HG_ID:
|
||||||
sio_data->kind = w83667hg;
|
sio_data->kind = w83667hg;
|
||||||
sio_name = sio_name_W83667HG;
|
sio_name = sio_name_W83667HG;
|
||||||
|
|
Loading…
Add table
Reference in a new issue