From f8d0c19a93cea3a26a90f2462295e1e01a4cd250 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 14 Feb 2007 21:15:02 +0100 Subject: hwmon/it87: Add PWM base frequency control Let the user select the base PWM frequency when using the it87 hardware monitoring driver. Different frequencies can give better control on some fans. Also update the documentation to mention the PWM frequency control files, with misc cleanups to the PWM section. Signed-off-by: Jean Delvare --- Documentation/hwmon/it87 | 10 ++++++++++ Documentation/hwmon/sysfs-interface | 15 ++++++++++----- 2 files changed, 20 insertions(+), 5 deletions(-) (limited to 'Documentation') diff --git a/Documentation/hwmon/it87 b/Documentation/hwmon/it87 index 74a80992d23..c0528d6f9ac 100644 --- a/Documentation/hwmon/it87 +++ b/Documentation/hwmon/it87 @@ -135,6 +135,16 @@ Give 0 for unused sensor. Any other value is invalid. To configure this at startup, consult lm_sensors's /etc/sensors.conf. (2 = thermistor; 3 = thermal diode) + +Fan speed control +----------------- + The fan speed control features are limited to manual PWM mode. Automatic "Smart Guardian" mode control handling is not implemented. However if you want to go for "manual mode" just write 1 to pwmN_enable. + +If you are only able to control the fan speed with very small PWM values, +try lowering the PWM base frequency (pwm1_freq). Depending on the fan, +it may give you a somewhat greater control range. The same frequency is +used to drive all fan outputs, which is why pwm2_freq and pwm3_freq are +read-only. diff --git a/Documentation/hwmon/sysfs-interface b/Documentation/hwmon/sysfs-interface index efef3b962cd..d73d2e8c753 100644 --- a/Documentation/hwmon/sysfs-interface +++ b/Documentation/hwmon/sysfs-interface @@ -166,16 +166,21 @@ pwm[1-*] Pulse width modulation fan control. pwm[1-*]_enable Switch PWM on and off. - Not always present even if fan*_pwm is. + Not always present even if pwmN is. 0: turn off 1: turn on in manual mode 2+: turn on in automatic mode - Check individual chip documentation files for automatic mode details. + Check individual chip documentation files for automatic mode + details. RW -pwm[1-*]_mode - 0: DC mode - 1: PWM mode +pwm[1-*]_mode 0: DC mode (direct current) + 1: PWM mode (pulse-width modulation) + RW + +pwm[1-*]_freq Base PWM frequency in Hz. + Only possibly available when pwmN_mode is PWM, but not always + present even then. RW pwm[1-*]_auto_channels_temp -- cgit v1.2.3-70-g09d2 From 657c93b10fac97467cdf1d0424a209ce2e81991a Mon Sep 17 00:00:00 2001 From: David Hubbard Date: Wed, 14 Feb 2007 21:15:04 +0100 Subject: hwmon/w83627ehf: Add support for the W83627DHG chip Signed-off-by: David Hubbard Signed-off-by: Jean Delvare --- Documentation/hwmon/w83627ehf | 54 +++++++++++++++++++++++++++++++++++++------ drivers/hwmon/w83627ehf.c | 54 ++++++++++++++++++++++++++++++++++--------- 2 files changed, 90 insertions(+), 18 deletions(-) (limited to 'Documentation') diff --git a/Documentation/hwmon/w83627ehf b/Documentation/hwmon/w83627ehf index 8a15a740875..030fac6cec7 100644 --- a/Documentation/hwmon/w83627ehf +++ b/Documentation/hwmon/w83627ehf @@ -2,26 +2,29 @@ Kernel driver w83627ehf ======================= Supported chips: - * Winbond W83627EHF/EHG (ISA access ONLY) + * Winbond W83627EHF/EHG/DHG (ISA access ONLY) Prefix: 'w83627ehf' Addresses scanned: ISA address retrieved from Super I/O registers - Datasheet: http://www.winbond-usa.com/products/winbond_products/pdfs/PCIC/W83627EHF_%20W83627EHGb.pdf + Datasheet: + http://www.winbond-usa.com/products/winbond_products/pdfs/PCIC/W83627EHF_%20W83627EHGb.pdf + DHG datasheet confidential. Authors: Jean Delvare Yuan Mu (Winbond) Rudolf Marek + David Hubbard Description ----------- -This driver implements support for the Winbond W83627EHF and W83627EHG -super I/O chips. We will refer to them collectively as Winbond chips. +This driver implements support for the Winbond W83627EHF, W83627EHG, and +W83627DHG super I/O chips. We will refer to them collectively as Winbond chips. The chips implement three temperature sensors, five fan rotation -speed sensors, ten analog voltage sensors, alarms with beep warnings (control -unimplemented), and some automatic fan regulation strategies (plus manual -fan control mode). +speed sensors, ten analog voltage sensors (only nine for the 627DHG), alarms +with beep warnings (control unimplemented), and some automatic fan regulation +strategies (plus manual fan control mode). 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 @@ -55,6 +58,9 @@ prog -> pwm4 (the programmable setting is not supported by the driver) /sys files ---------- +name - this is a standard hwmon device entry. For the W83627EHF and W83627EHG, + it is set to "w83627ehf" and for the W83627DHG it is set to "w83627dhg" + pwm[1-4] - this file stores PWM duty cycle or DC value (fan speed) in range: 0 (stop) to 255 (full) @@ -83,3 +89,37 @@ pwm[1-4]_stop_time - how many milliseconds [ms] must elapse to switch Note: last two functions are influenced by other control bits, not yet exported by the driver, so a change might not have any effect. + +Implementation Details +---------------------- + +Future driver development should bear in mind that the following registers have +different functions on the 627EHF and the 627DHG. Some registers also have +different power-on default values, but BIOS should already be loading +appropriate defaults. Note that bank selection must be performed as is currently +done in the driver for all register addresses. + +0x49: only on DHG, selects temperature source for AUX fan, CPU fan0 +0x4a: not completely documented for the EHF and the DHG documentation assigns + different behavior to bits 7 and 6, including extending the temperature + input selection to SmartFan I, not just SmartFan III. Testing on the EHF + will reveal whether they are compatible or not. + +0x58: Chip ID: 0xa1=EHF 0xc1=DHG +0x5e: only on DHG, has bits to enable "current mode" temperature detection and + critical temperature protection +0x45b: only on EHF, bit 3, vin4 alarm (EHF supports 10 inputs, only 9 on DHG) +0x552: only on EHF, vin4 +0x558: only on EHF, vin4 high limit +0x559: only on EHF, vin4 low limit +0x6b: only on DHG, SYS fan critical temperature +0x6c: only on DHG, CPU fan0 critical temperature +0x6d: only on DHG, AUX fan critical temperature +0x6e: only on DHG, CPU fan1 critical temperature + +0x50-0x55 and 0x650-0x657 are marked "Test Register" for the EHF, but "Reserved + Register" for the DHG + +The DHG also supports PECI, where the DHG queries Intel CPU temperatures, and +the ICH8 southbridge gets that data via PECI from the DHG, so that the +southbridge drives the fans. And the DHG supports SST, a one-wire serial bus. diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c index 212a1558c63..da5828f2dfc 100644 --- a/drivers/hwmon/w83627ehf.c +++ b/drivers/hwmon/w83627ehf.c @@ -32,8 +32,10 @@ Supports the following chips: - Chip #vin #fan #pwm #temp chip_id man_id - w83627ehf 10 5 4 3 0x88,0xa1 0x5ca3 + Chip #vin #fan #pwm #temp chip IDs man ID + w83627ehf 10 5 4 3 0x8850 0x88 0x5ca3 + 0x8860 0xa1 + w83627dhg 9 5 4 3 0xa020 0xc1 0x5ca3 */ #include @@ -55,8 +57,18 @@ static unsigned short address; * Super-I/O constants and functions */ +/* + * The three following globals are initialized in w83627ehf_find(), before + * the i2c-isa device is created. Otherwise, they could be stored in + * w83627ehf_data. This is ugly, but necessary, and when the driver is next + * updated to become a platform driver, the globals will disappear. + */ static int REG; /* The register to read/write */ static int VAL; /* The value to read/write */ +/* The w83627ehf/ehg have 10 voltage inputs, but the w83627dhg has 9. This + * value is also used in w83627ehf_detect() to export a device name in sysfs + * (e.g. w83627ehf or w83627dhg) */ +static int w83627ehf_num_in; #define W83627EHF_LD_HWM 0x0b @@ -65,8 +77,10 @@ static int VAL; /* The value to read/write */ #define SIO_REG_ENABLE 0x30 /* Logical device enable */ #define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */ -#define SIO_W83627EHF_ID 0x8840 -#define SIO_ID_MASK 0xFFC0 +#define SIO_W83627EHF_ID 0x8850 +#define SIO_W83627EHG_ID 0x8860 +#define SIO_W83627DHG_ID 0xa020 +#define SIO_ID_MASK 0xFFF0 static inline void superio_outb(int reg, int val) @@ -115,8 +129,12 @@ superio_exit(void) #define W83627EHF_REG_BANK 0x4E #define W83627EHF_REG_CONFIG 0x40 -#define W83627EHF_REG_CHIP_ID 0x49 -#define W83627EHF_REG_MAN_ID 0x4F + +/* Not currently used: + * REG_MAN_ID has the value 0x5ca3 for all supported chips. + * REG_CHIP_ID == 0x88/0xa1/0xc1 depending on chip model. + * REG_MAN_ID is at port 0x4f + * REG_CHIP_ID is at port 0x58 */ static const u16 W83627EHF_REG_FAN[] = { 0x28, 0x29, 0x2a, 0x3f, 0x553 }; static const u16 W83627EHF_REG_FAN_MIN[] = { 0x3b, 0x3c, 0x3d, 0x3e, 0x55c }; @@ -429,7 +447,7 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) } /* Measured voltages and limits */ - for (i = 0; i < 10; i++) { + for (i = 0; i < w83627ehf_num_in; i++) { data->in[i] = w83627ehf_read_value(client, W83627EHF_REG_IN(i)); data->in_min[i] = w83627ehf_read_value(client, @@ -1121,7 +1139,7 @@ static void w83627ehf_device_remove_files(struct device *dev) device_remove_file(dev, &sda_sf3_arrays[i].dev_attr); for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++) device_remove_file(dev, &sda_sf3_arrays_fan4[i].dev_attr); - for (i = 0; i < 10; i++) { + for (i = 0; i < w83627ehf_num_in; i++) { device_remove_file(dev, &sda_in_input[i].dev_attr); device_remove_file(dev, &sda_in_alarm[i].dev_attr); device_remove_file(dev, &sda_in_min[i].dev_attr); @@ -1196,7 +1214,11 @@ static int w83627ehf_detect(struct i2c_adapter *adapter) client->flags = 0; dev = &client->dev; - strlcpy(client->name, "w83627ehf", I2C_NAME_SIZE); + if (w83627ehf_num_in == 9) + strlcpy(client->name, "w83627dhg", I2C_NAME_SIZE); + else /* just say ehf. 627EHG is 627EHF in lead-free packaging. */ + strlcpy(client->name, "w83627ehf", I2C_NAME_SIZE); + data->valid = 0; mutex_init(&data->update_lock); @@ -1246,7 +1268,7 @@ static int w83627ehf_detect(struct i2c_adapter *adapter) goto exit_remove; } - for (i = 0; i < 10; i++) + for (i = 0; i < w83627ehf_num_in; i++) if ((err = device_create_file(dev, &sda_in_input[i].dev_attr)) || (err = device_create_file(dev, &sda_in_alarm[i].dev_attr)) @@ -1340,7 +1362,17 @@ static int __init w83627ehf_find(int sioaddr, unsigned short *addr) val = (superio_inb(SIO_REG_DEVID) << 8) | superio_inb(SIO_REG_DEVID + 1); - if ((val & SIO_ID_MASK) != SIO_W83627EHF_ID) { + switch (val & SIO_ID_MASK) { + case SIO_W83627DHG_ID: + w83627ehf_num_in = 9; + break; + case SIO_W83627EHF_ID: + case SIO_W83627EHG_ID: + w83627ehf_num_in = 10; + break; + default: + printk(KERN_WARNING "w83627ehf: unsupported chip ID: 0x%04x\n", + val); superio_exit(); return -ENODEV; } -- cgit v1.2.3-70-g09d2