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 | } |