diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/hwmon/Kconfig | 4 | ||||
-rw-r--r-- | drivers/hwmon/w83627ehf.c | 106 |
2 files changed, 72 insertions, 38 deletions
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index b4eea0292c1a..0eb4170cc4af 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
@@ -827,7 +827,7 @@ config SENSORS_W83627HF | |||
827 | will be called w83627hf. | 827 | will be called w83627hf. |
828 | 828 | ||
829 | config SENSORS_W83627EHF | 829 | config SENSORS_W83627EHF |
830 | tristate "Winbond W83627EHF/DHG" | 830 | tristate "Winbond W83627EHF/EHG/DHG, W83667HG" |
831 | select HWMON_VID | 831 | select HWMON_VID |
832 | help | 832 | help |
833 | If you say yes here you get support for the hardware | 833 | If you say yes here you get support for the hardware |
@@ -838,6 +838,8 @@ config SENSORS_W83627EHF | |||
838 | chip suited for specific Intel processors that use PECI such as | 838 | chip suited for specific Intel processors that use PECI such as |
839 | the Core 2 Duo. | 839 | the Core 2 Duo. |
840 | 840 | ||
841 | This driver also supports the W83667HG chip. | ||
842 | |||
841 | This driver can also be built as a module. If so, the module | 843 | This driver can also be built as a module. If so, the module |
842 | will be called w83627ehf. | 844 | will be called w83627ehf. |
843 | 845 | ||
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c index 18432e34dc7a..20a9332959bb 100644 --- a/drivers/hwmon/w83627ehf.c +++ b/drivers/hwmon/w83627ehf.c | |||
@@ -36,6 +36,7 @@ | |||
36 | w83627ehf 10 5 4 3 0x8850 0x88 0x5ca3 | 36 | w83627ehf 10 5 4 3 0x8850 0x88 0x5ca3 |
37 | 0x8860 0xa1 | 37 | 0x8860 0xa1 |
38 | w83627dhg 9 5 4 3 0xa020 0xc1 0x5ca3 | 38 | w83627dhg 9 5 4 3 0xa020 0xc1 0x5ca3 |
39 | w83667hg 9 5 3 3 0xa510 0xc1 0x5ca3 | ||
39 | */ | 40 | */ |
40 | 41 | ||
41 | #include <linux/module.h> | 42 | #include <linux/module.h> |
@@ -52,12 +53,13 @@ | |||
52 | #include <asm/io.h> | 53 | #include <asm/io.h> |
53 | #include "lm75.h" | 54 | #include "lm75.h" |
54 | 55 | ||
55 | enum kinds { w83627ehf, w83627dhg }; | 56 | enum kinds { w83627ehf, w83627dhg, w83667hg }; |
56 | 57 | ||
57 | /* used to set data->name = w83627ehf_device_names[data->sio_kind] */ | 58 | /* used to set data->name = w83627ehf_device_names[data->sio_kind] */ |
58 | static const char * w83627ehf_device_names[] = { | 59 | static const char * w83627ehf_device_names[] = { |
59 | "w83627ehf", | 60 | "w83627ehf", |
60 | "w83627dhg", | 61 | "w83627dhg", |
62 | "w83667hg", | ||
61 | }; | 63 | }; |
62 | 64 | ||
63 | static unsigned short force_id; | 65 | static unsigned short force_id; |
@@ -71,6 +73,7 @@ MODULE_PARM_DESC(force_id, "Override the detected device ID"); | |||
71 | */ | 73 | */ |
72 | 74 | ||
73 | #define W83627EHF_LD_HWM 0x0b | 75 | #define W83627EHF_LD_HWM 0x0b |
76 | #define W83667HG_LD_VID 0x0d | ||
74 | 77 | ||
75 | #define SIO_REG_LDSEL 0x07 /* Logical device select */ | 78 | #define SIO_REG_LDSEL 0x07 /* Logical device select */ |
76 | #define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */ | 79 | #define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */ |
@@ -83,6 +86,7 @@ MODULE_PARM_DESC(force_id, "Override the detected device ID"); | |||
83 | #define SIO_W83627EHF_ID 0x8850 | 86 | #define SIO_W83627EHF_ID 0x8850 |
84 | #define SIO_W83627EHG_ID 0x8860 | 87 | #define SIO_W83627EHG_ID 0x8860 |
85 | #define SIO_W83627DHG_ID 0xa020 | 88 | #define SIO_W83627DHG_ID 0xa020 |
89 | #define SIO_W83667HG_ID 0xa510 | ||
86 | #define SIO_ID_MASK 0xFFF0 | 90 | #define SIO_ID_MASK 0xFFF0 |
87 | 91 | ||
88 | static inline void | 92 | static inline void |
@@ -289,6 +293,7 @@ struct w83627ehf_data { | |||
289 | u8 pwm_mode[4]; /* 0->DC variable voltage, 1->PWM variable duty cycle */ | 293 | u8 pwm_mode[4]; /* 0->DC variable voltage, 1->PWM variable duty cycle */ |
290 | u8 pwm_enable[4]; /* 1->manual | 294 | u8 pwm_enable[4]; /* 1->manual |
291 | 2->thermal cruise (also called SmartFan I) */ | 295 | 2->thermal cruise (also called SmartFan I) */ |
296 | u8 pwm_num; /* number of pwm */ | ||
292 | u8 pwm[4]; | 297 | u8 pwm[4]; |
293 | u8 target_temp[4]; | 298 | u8 target_temp[4]; |
294 | u8 tolerance[4]; | 299 | u8 tolerance[4]; |
@@ -1192,7 +1197,7 @@ static void w83627ehf_device_remove_files(struct device *dev) | |||
1192 | device_remove_file(dev, &sda_fan_div[i].dev_attr); | 1197 | device_remove_file(dev, &sda_fan_div[i].dev_attr); |
1193 | device_remove_file(dev, &sda_fan_min[i].dev_attr); | 1198 | device_remove_file(dev, &sda_fan_min[i].dev_attr); |
1194 | } | 1199 | } |
1195 | for (i = 0; i < 4; i++) { | 1200 | for (i = 0; i < data->pwm_num; i++) { |
1196 | device_remove_file(dev, &sda_pwm[i].dev_attr); | 1201 | device_remove_file(dev, &sda_pwm[i].dev_attr); |
1197 | device_remove_file(dev, &sda_pwm_mode[i].dev_attr); | 1202 | device_remove_file(dev, &sda_pwm_mode[i].dev_attr); |
1198 | device_remove_file(dev, &sda_pwm_enable[i].dev_attr); | 1203 | device_remove_file(dev, &sda_pwm_enable[i].dev_attr); |
@@ -1272,8 +1277,10 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) | |||
1272 | data->name = w83627ehf_device_names[sio_data->kind]; | 1277 | data->name = w83627ehf_device_names[sio_data->kind]; |
1273 | platform_set_drvdata(pdev, data); | 1278 | platform_set_drvdata(pdev, data); |
1274 | 1279 | ||
1275 | /* 627EHG and 627EHF have 10 voltage inputs; DHG has 9 */ | 1280 | /* 627EHG and 627EHF have 10 voltage inputs; 627DHG and 667HG have 9 */ |
1276 | data->in_num = (sio_data->kind == w83627dhg) ? 9 : 10; | 1281 | data->in_num = (sio_data->kind == w83627ehf) ? 10 : 9; |
1282 | /* 667HG has 3 pwms */ | ||
1283 | data->pwm_num = (sio_data->kind == w83667hg) ? 3 : 4; | ||
1277 | 1284 | ||
1278 | /* Initialize the chip */ | 1285 | /* Initialize the chip */ |
1279 | w83627ehf_init_device(data); | 1286 | w83627ehf_init_device(data); |
@@ -1281,44 +1288,64 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) | |||
1281 | data->vrm = vid_which_vrm(); | 1288 | data->vrm = vid_which_vrm(); |
1282 | superio_enter(sio_data->sioreg); | 1289 | superio_enter(sio_data->sioreg); |
1283 | /* Read VID value */ | 1290 | /* Read VID value */ |
1284 | superio_select(sio_data->sioreg, W83627EHF_LD_HWM); | 1291 | if (sio_data->kind == w83667hg) { |
1285 | if (superio_inb(sio_data->sioreg, SIO_REG_VID_CTRL) & 0x80) { | 1292 | /* W83667HG has different pins for VID input and output, so |
1286 | /* Set VID input sensibility if needed. In theory the BIOS | 1293 | we can get the VID input values directly at logical device D |
1287 | should have set it, but in practice it's not always the | 1294 | 0xe3. */ |
1288 | case. We only do it for the W83627EHF/EHG because the | 1295 | superio_select(sio_data->sioreg, W83667HG_LD_VID); |
1289 | W83627DHG is more complex in this respect. */ | 1296 | data->vid = superio_inb(sio_data->sioreg, 0xe3); |
1290 | if (sio_data->kind == w83627ehf) { | ||
1291 | en_vrm10 = superio_inb(sio_data->sioreg, | ||
1292 | SIO_REG_EN_VRM10); | ||
1293 | if ((en_vrm10 & 0x08) && data->vrm == 90) { | ||
1294 | dev_warn(dev, "Setting VID input voltage to " | ||
1295 | "TTL\n"); | ||
1296 | superio_outb(sio_data->sioreg, SIO_REG_EN_VRM10, | ||
1297 | en_vrm10 & ~0x08); | ||
1298 | } else if (!(en_vrm10 & 0x08) && data->vrm == 100) { | ||
1299 | dev_warn(dev, "Setting VID input voltage to " | ||
1300 | "VRM10\n"); | ||
1301 | superio_outb(sio_data->sioreg, SIO_REG_EN_VRM10, | ||
1302 | en_vrm10 | 0x08); | ||
1303 | } | ||
1304 | } | ||
1305 | |||
1306 | data->vid = superio_inb(sio_data->sioreg, SIO_REG_VID_DATA); | ||
1307 | if (sio_data->kind == w83627ehf) /* 6 VID pins only */ | ||
1308 | data->vid &= 0x3f; | ||
1309 | |||
1310 | err = device_create_file(dev, &dev_attr_cpu0_vid); | 1297 | err = device_create_file(dev, &dev_attr_cpu0_vid); |
1311 | if (err) | 1298 | if (err) |
1312 | goto exit_release; | 1299 | goto exit_release; |
1313 | } else { | 1300 | } else { |
1314 | dev_info(dev, "VID pins in output mode, CPU VID not " | 1301 | superio_select(sio_data->sioreg, W83627EHF_LD_HWM); |
1315 | "available\n"); | 1302 | if (superio_inb(sio_data->sioreg, SIO_REG_VID_CTRL) & 0x80) { |
1303 | /* Set VID input sensibility if needed. In theory the | ||
1304 | BIOS should have set it, but in practice it's not | ||
1305 | always the case. We only do it for the W83627EHF/EHG | ||
1306 | because the W83627DHG is more complex in this | ||
1307 | respect. */ | ||
1308 | if (sio_data->kind == w83627ehf) { | ||
1309 | en_vrm10 = superio_inb(sio_data->sioreg, | ||
1310 | SIO_REG_EN_VRM10); | ||
1311 | if ((en_vrm10 & 0x08) && data->vrm == 90) { | ||
1312 | dev_warn(dev, "Setting VID input " | ||
1313 | "voltage to TTL\n"); | ||
1314 | superio_outb(sio_data->sioreg, | ||
1315 | SIO_REG_EN_VRM10, | ||
1316 | en_vrm10 & ~0x08); | ||
1317 | } else if (!(en_vrm10 & 0x08) | ||
1318 | && data->vrm == 100) { | ||
1319 | dev_warn(dev, "Setting VID input " | ||
1320 | "voltage to VRM10\n"); | ||
1321 | superio_outb(sio_data->sioreg, | ||
1322 | SIO_REG_EN_VRM10, | ||
1323 | en_vrm10 | 0x08); | ||
1324 | } | ||
1325 | } | ||
1326 | |||
1327 | data->vid = superio_inb(sio_data->sioreg, | ||
1328 | SIO_REG_VID_DATA); | ||
1329 | if (sio_data->kind == w83627ehf) /* 6 VID pins only */ | ||
1330 | data->vid &= 0x3f; | ||
1331 | |||
1332 | err = device_create_file(dev, &dev_attr_cpu0_vid); | ||
1333 | if (err) | ||
1334 | goto exit_release; | ||
1335 | } else { | ||
1336 | dev_info(dev, "VID pins in output mode, CPU VID not " | ||
1337 | "available\n"); | ||
1338 | } | ||
1316 | } | 1339 | } |
1317 | 1340 | ||
1318 | /* fan4 and fan5 share some pins with the GPIO and serial flash */ | 1341 | /* fan4 and fan5 share some pins with the GPIO and serial flash */ |
1319 | 1342 | if (sio_data->kind == w83667hg) { | |
1320 | fan5pin = !(superio_inb(sio_data->sioreg, 0x24) & 0x2); | 1343 | fan5pin = superio_inb(sio_data->sioreg, 0x27) & 0x20; |
1321 | fan4pin = !(superio_inb(sio_data->sioreg, 0x29) & 0x6); | 1344 | fan4pin = superio_inb(sio_data->sioreg, 0x27) & 0x40; |
1345 | } else { | ||
1346 | fan5pin = !(superio_inb(sio_data->sioreg, 0x24) & 0x02); | ||
1347 | fan4pin = !(superio_inb(sio_data->sioreg, 0x29) & 0x06); | ||
1348 | } | ||
1322 | superio_exit(sio_data->sioreg); | 1349 | superio_exit(sio_data->sioreg); |
1323 | 1350 | ||
1324 | /* It looks like fan4 and fan5 pins can be alternatively used | 1351 | /* It looks like fan4 and fan5 pins can be alternatively used |
@@ -1344,7 +1371,7 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) | |||
1344 | goto exit_remove; | 1371 | goto exit_remove; |
1345 | 1372 | ||
1346 | /* if fan4 is enabled create the sf3 files for it */ | 1373 | /* if fan4 is enabled create the sf3 files for it */ |
1347 | if (data->has_fan & (1 << 3)) | 1374 | if ((data->has_fan & (1 << 3)) && data->pwm_num >= 4) |
1348 | for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++) { | 1375 | for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++) { |
1349 | if ((err = device_create_file(dev, | 1376 | if ((err = device_create_file(dev, |
1350 | &sda_sf3_arrays_fan4[i].dev_attr))) | 1377 | &sda_sf3_arrays_fan4[i].dev_attr))) |
@@ -1372,7 +1399,7 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) | |||
1372 | || (err = device_create_file(dev, | 1399 | || (err = device_create_file(dev, |
1373 | &sda_fan_min[i].dev_attr))) | 1400 | &sda_fan_min[i].dev_attr))) |
1374 | goto exit_remove; | 1401 | goto exit_remove; |
1375 | if (i < 4 && /* w83627ehf only has 4 pwm */ | 1402 | if (i < data->pwm_num && |
1376 | ((err = device_create_file(dev, | 1403 | ((err = device_create_file(dev, |
1377 | &sda_pwm[i].dev_attr)) | 1404 | &sda_pwm[i].dev_attr)) |
1378 | || (err = device_create_file(dev, | 1405 | || (err = device_create_file(dev, |
@@ -1442,6 +1469,7 @@ static int __init w83627ehf_find(int sioaddr, unsigned short *addr, | |||
1442 | static const char __initdata sio_name_W83627EHF[] = "W83627EHF"; | 1469 | static const char __initdata sio_name_W83627EHF[] = "W83627EHF"; |
1443 | static const char __initdata sio_name_W83627EHG[] = "W83627EHG"; | 1470 | static const char __initdata sio_name_W83627EHG[] = "W83627EHG"; |
1444 | static const char __initdata sio_name_W83627DHG[] = "W83627DHG"; | 1471 | static const char __initdata sio_name_W83627DHG[] = "W83627DHG"; |
1472 | static const char __initdata sio_name_W83667HG[] = "W83667HG"; | ||
1445 | 1473 | ||
1446 | u16 val; | 1474 | u16 val; |
1447 | const char *sio_name; | 1475 | const char *sio_name; |
@@ -1466,6 +1494,10 @@ static int __init w83627ehf_find(int sioaddr, unsigned short *addr, | |||
1466 | sio_data->kind = w83627dhg; | 1494 | sio_data->kind = w83627dhg; |
1467 | sio_name = sio_name_W83627DHG; | 1495 | sio_name = sio_name_W83627DHG; |
1468 | break; | 1496 | break; |
1497 | case SIO_W83667HG_ID: | ||
1498 | sio_data->kind = w83667hg; | ||
1499 | sio_name = sio_name_W83667HG; | ||
1500 | break; | ||
1469 | default: | 1501 | default: |
1470 | if (val != 0xffff) | 1502 | if (val != 0xffff) |
1471 | pr_debug(DRVNAME ": unsupported chip ID: 0x%04x\n", | 1503 | pr_debug(DRVNAME ": unsupported chip ID: 0x%04x\n", |