diff options
| author | David Hubbard <david.c.hubbard@gmail.com> | 2007-02-14 15:15:04 -0500 |
|---|---|---|
| committer | Jean Delvare <khali@arrakis.delvare> | 2007-02-14 15:15:04 -0500 |
| commit | 657c93b10fac97467cdf1d0424a209ce2e81991a (patch) | |
| tree | ac356cfed78ed89fe5116c031b67c21be2ac4f17 | |
| parent | 37f54ee546e415829ef14ca29d85fae26a439b9b (diff) | |
hwmon/w83627ehf: Add support for the W83627DHG chip
Signed-off-by: David Hubbard <david.c.hubbard@gmail.com>
Signed-off-by: Jean Delvare <khali@linux-fr.org>
| -rw-r--r-- | Documentation/hwmon/w83627ehf | 54 | ||||
| -rw-r--r-- | drivers/hwmon/w83627ehf.c | 54 |
2 files changed, 90 insertions, 18 deletions
diff --git a/Documentation/hwmon/w83627ehf b/Documentation/hwmon/w83627ehf index 8a15a7408753..030fac6cec7a 100644 --- a/Documentation/hwmon/w83627ehf +++ b/Documentation/hwmon/w83627ehf | |||
| @@ -2,26 +2,29 @@ Kernel driver w83627ehf | |||
| 2 | ======================= | 2 | ======================= |
| 3 | 3 | ||
| 4 | Supported chips: | 4 | Supported chips: |
| 5 | * Winbond W83627EHF/EHG (ISA access ONLY) | 5 | * Winbond W83627EHF/EHG/DHG (ISA access ONLY) |
| 6 | Prefix: 'w83627ehf' | 6 | Prefix: 'w83627ehf' |
| 7 | Addresses scanned: ISA address retrieved from Super I/O registers | 7 | Addresses scanned: ISA address retrieved from Super I/O registers |
| 8 | Datasheet: http://www.winbond-usa.com/products/winbond_products/pdfs/PCIC/W83627EHF_%20W83627EHGb.pdf | 8 | Datasheet: |
| 9 | http://www.winbond-usa.com/products/winbond_products/pdfs/PCIC/W83627EHF_%20W83627EHGb.pdf | ||
| 10 | DHG datasheet confidential. | ||
| 9 | 11 | ||
| 10 | Authors: | 12 | Authors: |
| 11 | Jean Delvare <khali@linux-fr.org> | 13 | Jean Delvare <khali@linux-fr.org> |
| 12 | Yuan Mu (Winbond) | 14 | Yuan Mu (Winbond) |
| 13 | Rudolf Marek <r.marek@assembler.cz> | 15 | Rudolf Marek <r.marek@assembler.cz> |
| 16 | David Hubbard <david.c.hubbard@gmail.com> | ||
| 14 | 17 | ||
| 15 | Description | 18 | Description |
| 16 | ----------- | 19 | ----------- |
| 17 | 20 | ||
| 18 | This driver implements support for the Winbond W83627EHF and W83627EHG | 21 | This driver implements support for the Winbond W83627EHF, W83627EHG, and |
| 19 | super I/O chips. We will refer to them collectively as Winbond chips. | 22 | W83627DHG super I/O chips. We will refer to them collectively as Winbond chips. |
| 20 | 23 | ||
| 21 | The chips implement three temperature sensors, five fan rotation | 24 | The chips implement three temperature sensors, five fan rotation |
| 22 | speed sensors, ten analog voltage sensors, alarms with beep warnings (control | 25 | speed sensors, ten analog voltage sensors (only nine for the 627DHG), alarms |
| 23 | unimplemented), and some automatic fan regulation strategies (plus manual | 26 | with beep warnings (control unimplemented), and some automatic fan regulation |
| 24 | fan control mode). | 27 | strategies (plus manual fan control mode). |
| 25 | 28 | ||
| 26 | Temperatures are measured in degrees Celsius and measurement resolution is 1 | 29 | Temperatures are measured in degrees Celsius and measurement resolution is 1 |
| 27 | degC for temp1 and 0.5 degC for temp2 and temp3. An alarm is triggered when | 30 | 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) | |||
| 55 | /sys files | 58 | /sys files |
| 56 | ---------- | 59 | ---------- |
| 57 | 60 | ||
| 61 | name - this is a standard hwmon device entry. For the W83627EHF and W83627EHG, | ||
| 62 | it is set to "w83627ehf" and for the W83627DHG it is set to "w83627dhg" | ||
| 63 | |||
| 58 | pwm[1-4] - this file stores PWM duty cycle or DC value (fan speed) in range: | 64 | pwm[1-4] - this file stores PWM duty cycle or DC value (fan speed) in range: |
| 59 | 0 (stop) to 255 (full) | 65 | 0 (stop) to 255 (full) |
| 60 | 66 | ||
| @@ -83,3 +89,37 @@ pwm[1-4]_stop_time - how many milliseconds [ms] must elapse to switch | |||
| 83 | 89 | ||
| 84 | Note: last two functions are influenced by other control bits, not yet exported | 90 | Note: last two functions are influenced by other control bits, not yet exported |
| 85 | by the driver, so a change might not have any effect. | 91 | by the driver, so a change might not have any effect. |
| 92 | |||
| 93 | Implementation Details | ||
| 94 | ---------------------- | ||
| 95 | |||
| 96 | Future driver development should bear in mind that the following registers have | ||
| 97 | different functions on the 627EHF and the 627DHG. Some registers also have | ||
| 98 | different power-on default values, but BIOS should already be loading | ||
| 99 | appropriate defaults. Note that bank selection must be performed as is currently | ||
| 100 | done in the driver for all register addresses. | ||
| 101 | |||
| 102 | 0x49: only on DHG, selects temperature source for AUX fan, CPU fan0 | ||
| 103 | 0x4a: not completely documented for the EHF and the DHG documentation assigns | ||
| 104 | different behavior to bits 7 and 6, including extending the temperature | ||
| 105 | input selection to SmartFan I, not just SmartFan III. Testing on the EHF | ||
| 106 | will reveal whether they are compatible or not. | ||
| 107 | |||
| 108 | 0x58: Chip ID: 0xa1=EHF 0xc1=DHG | ||
| 109 | 0x5e: only on DHG, has bits to enable "current mode" temperature detection and | ||
| 110 | critical temperature protection | ||
| 111 | 0x45b: only on EHF, bit 3, vin4 alarm (EHF supports 10 inputs, only 9 on DHG) | ||
| 112 | 0x552: only on EHF, vin4 | ||
| 113 | 0x558: only on EHF, vin4 high limit | ||
| 114 | 0x559: only on EHF, vin4 low limit | ||
| 115 | 0x6b: only on DHG, SYS fan critical temperature | ||
| 116 | 0x6c: only on DHG, CPU fan0 critical temperature | ||
| 117 | 0x6d: only on DHG, AUX fan critical temperature | ||
| 118 | 0x6e: only on DHG, CPU fan1 critical temperature | ||
| 119 | |||
| 120 | 0x50-0x55 and 0x650-0x657 are marked "Test Register" for the EHF, but "Reserved | ||
| 121 | Register" for the DHG | ||
| 122 | |||
| 123 | The DHG also supports PECI, where the DHG queries Intel CPU temperatures, and | ||
| 124 | the ICH8 southbridge gets that data via PECI from the DHG, so that the | ||
| 125 | 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 212a1558c63b..da5828f2dfc2 100644 --- a/drivers/hwmon/w83627ehf.c +++ b/drivers/hwmon/w83627ehf.c | |||
| @@ -32,8 +32,10 @@ | |||
| 32 | 32 | ||
| 33 | Supports the following chips: | 33 | Supports the following chips: |
| 34 | 34 | ||
| 35 | Chip #vin #fan #pwm #temp chip_id man_id | 35 | Chip #vin #fan #pwm #temp chip IDs man ID |
| 36 | w83627ehf 10 5 4 3 0x88,0xa1 0x5ca3 | 36 | w83627ehf 10 5 4 3 0x8850 0x88 0x5ca3 |
| 37 | 0x8860 0xa1 | ||
| 38 | w83627dhg 9 5 4 3 0xa020 0xc1 0x5ca3 | ||
| 37 | */ | 39 | */ |
| 38 | 40 | ||
| 39 | #include <linux/module.h> | 41 | #include <linux/module.h> |
| @@ -55,8 +57,18 @@ static unsigned short address; | |||
| 55 | * Super-I/O constants and functions | 57 | * Super-I/O constants and functions |
| 56 | */ | 58 | */ |
| 57 | 59 | ||
| 60 | /* | ||
| 61 | * The three following globals are initialized in w83627ehf_find(), before | ||
| 62 | * the i2c-isa device is created. Otherwise, they could be stored in | ||
| 63 | * w83627ehf_data. This is ugly, but necessary, and when the driver is next | ||
| 64 | * updated to become a platform driver, the globals will disappear. | ||
| 65 | */ | ||
| 58 | static int REG; /* The register to read/write */ | 66 | static int REG; /* The register to read/write */ |
| 59 | static int VAL; /* The value to read/write */ | 67 | static int VAL; /* The value to read/write */ |
| 68 | /* The w83627ehf/ehg have 10 voltage inputs, but the w83627dhg has 9. This | ||
| 69 | * value is also used in w83627ehf_detect() to export a device name in sysfs | ||
| 70 | * (e.g. w83627ehf or w83627dhg) */ | ||
| 71 | static int w83627ehf_num_in; | ||
| 60 | 72 | ||
| 61 | #define W83627EHF_LD_HWM 0x0b | 73 | #define W83627EHF_LD_HWM 0x0b |
| 62 | 74 | ||
| @@ -65,8 +77,10 @@ static int VAL; /* The value to read/write */ | |||
| 65 | #define SIO_REG_ENABLE 0x30 /* Logical device enable */ | 77 | #define SIO_REG_ENABLE 0x30 /* Logical device enable */ |
| 66 | #define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */ | 78 | #define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */ |
| 67 | 79 | ||
| 68 | #define SIO_W83627EHF_ID 0x8840 | 80 | #define SIO_W83627EHF_ID 0x8850 |
| 69 | #define SIO_ID_MASK 0xFFC0 | 81 | #define SIO_W83627EHG_ID 0x8860 |
| 82 | #define SIO_W83627DHG_ID 0xa020 | ||
| 83 | #define SIO_ID_MASK 0xFFF0 | ||
| 70 | 84 | ||
| 71 | static inline void | 85 | static inline void |
| 72 | superio_outb(int reg, int val) | 86 | superio_outb(int reg, int val) |
| @@ -115,8 +129,12 @@ superio_exit(void) | |||
| 115 | 129 | ||
| 116 | #define W83627EHF_REG_BANK 0x4E | 130 | #define W83627EHF_REG_BANK 0x4E |
| 117 | #define W83627EHF_REG_CONFIG 0x40 | 131 | #define W83627EHF_REG_CONFIG 0x40 |
| 118 | #define W83627EHF_REG_CHIP_ID 0x49 | 132 | |
| 119 | #define W83627EHF_REG_MAN_ID 0x4F | 133 | /* Not currently used: |
| 134 | * REG_MAN_ID has the value 0x5ca3 for all supported chips. | ||
| 135 | * REG_CHIP_ID == 0x88/0xa1/0xc1 depending on chip model. | ||
| 136 | * REG_MAN_ID is at port 0x4f | ||
| 137 | * REG_CHIP_ID is at port 0x58 */ | ||
| 120 | 138 | ||
| 121 | static const u16 W83627EHF_REG_FAN[] = { 0x28, 0x29, 0x2a, 0x3f, 0x553 }; | 139 | static const u16 W83627EHF_REG_FAN[] = { 0x28, 0x29, 0x2a, 0x3f, 0x553 }; |
| 122 | static const u16 W83627EHF_REG_FAN_MIN[] = { 0x3b, 0x3c, 0x3d, 0x3e, 0x55c }; | 140 | 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) | |||
| 429 | } | 447 | } |
| 430 | 448 | ||
| 431 | /* Measured voltages and limits */ | 449 | /* Measured voltages and limits */ |
| 432 | for (i = 0; i < 10; i++) { | 450 | for (i = 0; i < w83627ehf_num_in; i++) { |
| 433 | data->in[i] = w83627ehf_read_value(client, | 451 | data->in[i] = w83627ehf_read_value(client, |
| 434 | W83627EHF_REG_IN(i)); | 452 | W83627EHF_REG_IN(i)); |
| 435 | data->in_min[i] = w83627ehf_read_value(client, | 453 | data->in_min[i] = w83627ehf_read_value(client, |
| @@ -1121,7 +1139,7 @@ static void w83627ehf_device_remove_files(struct device *dev) | |||
| 1121 | device_remove_file(dev, &sda_sf3_arrays[i].dev_attr); | 1139 | device_remove_file(dev, &sda_sf3_arrays[i].dev_attr); |
| 1122 | for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++) | 1140 | for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++) |
| 1123 | device_remove_file(dev, &sda_sf3_arrays_fan4[i].dev_attr); | 1141 | device_remove_file(dev, &sda_sf3_arrays_fan4[i].dev_attr); |
| 1124 | for (i = 0; i < 10; i++) { | 1142 | for (i = 0; i < w83627ehf_num_in; i++) { |
| 1125 | device_remove_file(dev, &sda_in_input[i].dev_attr); | 1143 | device_remove_file(dev, &sda_in_input[i].dev_attr); |
| 1126 | device_remove_file(dev, &sda_in_alarm[i].dev_attr); | 1144 | device_remove_file(dev, &sda_in_alarm[i].dev_attr); |
| 1127 | device_remove_file(dev, &sda_in_min[i].dev_attr); | 1145 | device_remove_file(dev, &sda_in_min[i].dev_attr); |
| @@ -1196,7 +1214,11 @@ static int w83627ehf_detect(struct i2c_adapter *adapter) | |||
| 1196 | client->flags = 0; | 1214 | client->flags = 0; |
| 1197 | dev = &client->dev; | 1215 | dev = &client->dev; |
| 1198 | 1216 | ||
| 1199 | strlcpy(client->name, "w83627ehf", I2C_NAME_SIZE); | 1217 | if (w83627ehf_num_in == 9) |
| 1218 | strlcpy(client->name, "w83627dhg", I2C_NAME_SIZE); | ||
| 1219 | else /* just say ehf. 627EHG is 627EHF in lead-free packaging. */ | ||
| 1220 | strlcpy(client->name, "w83627ehf", I2C_NAME_SIZE); | ||
| 1221 | |||
| 1200 | data->valid = 0; | 1222 | data->valid = 0; |
| 1201 | mutex_init(&data->update_lock); | 1223 | mutex_init(&data->update_lock); |
| 1202 | 1224 | ||
| @@ -1246,7 +1268,7 @@ static int w83627ehf_detect(struct i2c_adapter *adapter) | |||
| 1246 | goto exit_remove; | 1268 | goto exit_remove; |
| 1247 | } | 1269 | } |
| 1248 | 1270 | ||
| 1249 | for (i = 0; i < 10; i++) | 1271 | for (i = 0; i < w83627ehf_num_in; i++) |
| 1250 | if ((err = device_create_file(dev, &sda_in_input[i].dev_attr)) | 1272 | if ((err = device_create_file(dev, &sda_in_input[i].dev_attr)) |
| 1251 | || (err = device_create_file(dev, | 1273 | || (err = device_create_file(dev, |
| 1252 | &sda_in_alarm[i].dev_attr)) | 1274 | &sda_in_alarm[i].dev_attr)) |
| @@ -1340,7 +1362,17 @@ static int __init w83627ehf_find(int sioaddr, unsigned short *addr) | |||
| 1340 | 1362 | ||
| 1341 | val = (superio_inb(SIO_REG_DEVID) << 8) | 1363 | val = (superio_inb(SIO_REG_DEVID) << 8) |
| 1342 | | superio_inb(SIO_REG_DEVID + 1); | 1364 | | superio_inb(SIO_REG_DEVID + 1); |
| 1343 | if ((val & SIO_ID_MASK) != SIO_W83627EHF_ID) { | 1365 | switch (val & SIO_ID_MASK) { |
| 1366 | case SIO_W83627DHG_ID: | ||
| 1367 | w83627ehf_num_in = 9; | ||
| 1368 | break; | ||
| 1369 | case SIO_W83627EHF_ID: | ||
| 1370 | case SIO_W83627EHG_ID: | ||
| 1371 | w83627ehf_num_in = 10; | ||
| 1372 | break; | ||
| 1373 | default: | ||
| 1374 | printk(KERN_WARNING "w83627ehf: unsupported chip ID: 0x%04x\n", | ||
| 1375 | val); | ||
| 1344 | superio_exit(); | 1376 | superio_exit(); |
| 1345 | return -ENODEV; | 1377 | return -ENODEV; |
| 1346 | } | 1378 | } |
