aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/w83627ehf.c
diff options
context:
space:
mode:
authorGong Jun <JGong@nuvoton.com>2009-03-30 15:46:42 -0400
committerJean Delvare <khali@linux-fr.org>2009-03-30 15:46:42 -0400
commit237c8d2f54ff12bd4fea1a9d18a94ae5810271d3 (patch)
treef93114b8b4c24a59151353cdfb63dd52fa055f9b /drivers/hwmon/w83627ehf.c
parent1704b26ee3fd89c76724cbea238e951dc019faca (diff)
hwmon: (w83627ehf) Add support for W83667HG
Add initial support for the Nuvoton W83667HG chip to the w83627ehf driver. It has been tested on ASUS P5QL PRO by Gong Jun. At the moment there is still a usability issue which is that only in6 or temp3 can be present on the W83667HG, so the driver shouldn't expose both. This will be addressed later. Signed-off-by: Gong Jun <JGong@nuvoton.com> Acked-by: David Hubbard <david.c.hubbard@gmail.com> Signed-off-by: Jean Delvare <khali@linux-fr.org>
Diffstat (limited to 'drivers/hwmon/w83627ehf.c')
-rw-r--r--drivers/hwmon/w83627ehf.c106
1 files changed, 69 insertions, 37 deletions
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
55enum kinds { w83627ehf, w83627dhg }; 56enum 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] */
58static const char * w83627ehf_device_names[] = { 59static const char * w83627ehf_device_names[] = {
59 "w83627ehf", 60 "w83627ehf",
60 "w83627dhg", 61 "w83627dhg",
62 "w83667hg",
61}; 63};
62 64
63static unsigned short force_id; 65static 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
88static inline void 92static 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",