aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2006-01-18 17:22:12 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2006-03-23 17:21:52 -0500
commitc2db6ce14a743ac5f8973124272cf425c4f86b90 (patch)
treeae55d515d46acf40c52b0b62c2ee31ae6c3a0897 /drivers/hwmon
parentf08191849e42e67ab6ad556d9c2e8cbed1ddf303 (diff)
[PATCH] hwmon: Add support for the Winbond W83687THF
Add support for the Winbond W83687THF chip to the w83627hf hardware monitoring driver. This new chip is almost similar to the already supported W83627THF chip, except for VID and a few other minor changes. Signed-off-by: Jean Delvare <khali@linux-fr.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/hwmon')
-rw-r--r--drivers/hwmon/Kconfig7
-rw-r--r--drivers/hwmon/w83627hf.c72
2 files changed, 62 insertions, 17 deletions
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 7230d4e08196..99cdc612d2c6 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -406,13 +406,14 @@ config SENSORS_W83L785TS
406 will be called w83l785ts. 406 will be called w83l785ts.
407 407
408config SENSORS_W83627HF 408config SENSORS_W83627HF
409 tristate "Winbond W83627HF, W83627THF, W83637HF, W83697HF" 409 tristate "Winbond W83627HF, W83627THF, W83637HF, W83687THF, W83697HF"
410 depends on HWMON && I2C && EXPERIMENTAL 410 depends on HWMON && I2C
411 select I2C_ISA 411 select I2C_ISA
412 select HWMON_VID 412 select HWMON_VID
413 help 413 help
414 If you say yes here you get support for the Winbond W836X7 series 414 If you say yes here you get support for the Winbond W836X7 series
415 of sensor chips: the W83627HF, W83627THF, W83637HF, and the W83697HF 415 of sensor chips: the W83627HF, W83627THF, W83637HF, W83687THF and
416 W83697HF.
416 417
417 This driver can also be built as a module. If so, the module 418 This driver can also be built as a module. If so, the module
418 will be called w83627hf. 419 will be called w83627hf.
diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c
index 3d4888c178c9..992e34402705 100644
--- a/drivers/hwmon/w83627hf.c
+++ b/drivers/hwmon/w83627hf.c
@@ -28,6 +28,7 @@
28 w83627hf 9 3 2 3 0x20 0x5ca3 no yes(LPC) 28 w83627hf 9 3 2 3 0x20 0x5ca3 no yes(LPC)
29 w83627thf 7 3 3 3 0x90 0x5ca3 no yes(LPC) 29 w83627thf 7 3 3 3 0x90 0x5ca3 no yes(LPC)
30 w83637hf 7 3 3 3 0x80 0x5ca3 no yes(LPC) 30 w83637hf 7 3 3 3 0x80 0x5ca3 no yes(LPC)
31 w83687thf 7 3 3 3 0x90 0x5ca3 no yes(LPC)
31 w83697hf 8 2 2 2 0x60 0x5ca3 no yes(LPC) 32 w83697hf 8 2 2 2 0x60 0x5ca3 no yes(LPC)
32 33
33 For other winbond chips, and for i2c support in the above chips, 34 For other winbond chips, and for i2c support in the above chips,
@@ -63,7 +64,7 @@ MODULE_PARM_DESC(force_i2c,
63static unsigned short address; 64static unsigned short address;
64 65
65/* Insmod parameters */ 66/* Insmod parameters */
66enum chips { any_chip, w83627hf, w83627thf, w83697hf, w83637hf }; 67enum chips { any_chip, w83627hf, w83627thf, w83697hf, w83637hf, w83687thf };
67 68
68static int reset; 69static int reset;
69module_param(reset, bool, 0); 70module_param(reset, bool, 0);
@@ -101,6 +102,10 @@ static int VAL; /* The value to read/write */
101#define W83627THF_GPIO5_IOSR 0xf3 /* w83627thf only */ 102#define W83627THF_GPIO5_IOSR 0xf3 /* w83627thf only */
102#define W83627THF_GPIO5_DR 0xf4 /* w83627thf only */ 103#define W83627THF_GPIO5_DR 0xf4 /* w83627thf only */
103 104
105#define W83687THF_VID_EN 0x29 /* w83687thf only */
106#define W83687THF_VID_CFG 0xF0 /* w83687thf only */
107#define W83687THF_VID_DATA 0xF1 /* w83687thf only */
108
104static inline void 109static inline void
105superio_outb(int reg, int val) 110superio_outb(int reg, int val)
106{ 111{
@@ -139,6 +144,7 @@ superio_exit(void)
139#define W627THF_DEVID 0x82 144#define W627THF_DEVID 0x82
140#define W697_DEVID 0x60 145#define W697_DEVID 0x60
141#define W637_DEVID 0x70 146#define W637_DEVID 0x70
147#define W687THF_DEVID 0x85
142#define WINB_ACT_REG 0x30 148#define WINB_ACT_REG 0x30
143#define WINB_BASE_REG 0x60 149#define WINB_BASE_REG 0x60
144/* Constants specified below */ 150/* Constants specified below */
@@ -202,11 +208,11 @@ superio_exit(void)
202#define W83627HF_REG_PWM1 0x5A 208#define W83627HF_REG_PWM1 0x5A
203#define W83627HF_REG_PWM2 0x5B 209#define W83627HF_REG_PWM2 0x5B
204 210
205#define W83627THF_REG_PWM1 0x01 /* 697HF and 637HF too */ 211#define W83627THF_REG_PWM1 0x01 /* 697HF/637HF/687THF too */
206#define W83627THF_REG_PWM2 0x03 /* 697HF and 637HF too */ 212#define W83627THF_REG_PWM2 0x03 /* 697HF/637HF/687THF too */
207#define W83627THF_REG_PWM3 0x11 /* 637HF too */ 213#define W83627THF_REG_PWM3 0x11 /* 637HF/687THF too */
208 214
209#define W83627THF_REG_VRM_OVT_CFG 0x18 /* 637HF too */ 215#define W83627THF_REG_VRM_OVT_CFG 0x18 /* 637HF/687THF too */
210 216
211static const u8 regpwm_627hf[] = { W83627HF_REG_PWM1, W83627HF_REG_PWM2 }; 217static const u8 regpwm_627hf[] = { W83627HF_REG_PWM1, W83627HF_REG_PWM2 };
212static const u8 regpwm[] = { W83627THF_REG_PWM1, W83627THF_REG_PWM2, 218static const u8 regpwm[] = { W83627THF_REG_PWM1, W83627THF_REG_PWM2,
@@ -319,7 +325,7 @@ struct w83627hf_data {
319 Default = 3435. 325 Default = 3435.
320 Other Betas unimplemented */ 326 Other Betas unimplemented */
321 u8 vrm; 327 u8 vrm;
322 u8 vrm_ovt; /* Register value, 627thf & 637hf only */ 328 u8 vrm_ovt; /* Register value, 627THF/637HF/687THF only */
323}; 329};
324 330
325 331
@@ -414,7 +420,8 @@ static ssize_t show_in_0(struct w83627hf_data *data, char *buf, u8 reg)
414 long in0; 420 long in0;
415 421
416 if ((data->vrm_ovt & 0x01) && 422 if ((data->vrm_ovt & 0x01) &&
417 (w83627thf == data->type || w83637hf == data->type)) 423 (w83627thf == data->type || w83637hf == data->type
424 || w83687thf == data->type))
418 425
419 /* use VRM9 calculation */ 426 /* use VRM9 calculation */
420 in0 = (long)((reg * 488 + 70000 + 50) / 100); 427 in0 = (long)((reg * 488 + 70000 + 50) / 100);
@@ -455,7 +462,8 @@ static ssize_t store_regs_in_min0(struct device *dev, struct device_attribute *a
455 mutex_lock(&data->update_lock); 462 mutex_lock(&data->update_lock);
456 463
457 if ((data->vrm_ovt & 0x01) && 464 if ((data->vrm_ovt & 0x01) &&
458 (w83627thf == data->type || w83637hf == data->type)) 465 (w83627thf == data->type || w83637hf == data->type
466 || w83687thf == data->type))
459 467
460 /* use VRM9 calculation */ 468 /* use VRM9 calculation */
461 data->in_min[0] = 469 data->in_min[0] =
@@ -482,7 +490,8 @@ static ssize_t store_regs_in_max0(struct device *dev, struct device_attribute *a
482 mutex_lock(&data->update_lock); 490 mutex_lock(&data->update_lock);
483 491
484 if ((data->vrm_ovt & 0x01) && 492 if ((data->vrm_ovt & 0x01) &&
485 (w83627thf == data->type || w83637hf == data->type)) 493 (w83627thf == data->type || w83637hf == data->type
494 || w83687thf == data->type))
486 495
487 /* use VRM9 calculation */ 496 /* use VRM9 calculation */
488 data->in_max[0] = 497 data->in_max[0] =
@@ -981,7 +990,8 @@ static int __init w83627hf_find(int sioaddr, unsigned short *addr)
981 if(val != W627_DEVID && 990 if(val != W627_DEVID &&
982 val != W627THF_DEVID && 991 val != W627THF_DEVID &&
983 val != W697_DEVID && 992 val != W697_DEVID &&
984 val != W637_DEVID) { 993 val != W637_DEVID &&
994 val != W687THF_DEVID) {
985 superio_exit(); 995 superio_exit();
986 return -ENODEV; 996 return -ENODEV;
987 } 997 }
@@ -1035,6 +1045,8 @@ static int w83627hf_detect(struct i2c_adapter *adapter)
1035 kind = w83627thf; 1045 kind = w83627thf;
1036 else if(val == W637_DEVID) 1046 else if(val == W637_DEVID)
1037 kind = w83637hf; 1047 kind = w83637hf;
1048 else if (val == W687THF_DEVID)
1049 kind = w83687thf;
1038 else { 1050 else {
1039 dev_info(&adapter->dev, 1051 dev_info(&adapter->dev,
1040 "Unsupported chip (dev_id=0x%02X).\n", val); 1052 "Unsupported chip (dev_id=0x%02X).\n", val);
@@ -1072,6 +1084,8 @@ static int w83627hf_detect(struct i2c_adapter *adapter)
1072 client_name = "w83697hf"; 1084 client_name = "w83697hf";
1073 } else if (kind == w83637hf) { 1085 } else if (kind == w83637hf) {
1074 client_name = "w83637hf"; 1086 client_name = "w83637hf";
1087 } else if (kind == w83687thf) {
1088 client_name = "w83687thf";
1075 } 1089 }
1076 1090
1077 /* Fill in the remaining client fields and put into the global list */ 1091 /* Fill in the remaining client fields and put into the global list */
@@ -1107,7 +1121,7 @@ static int w83627hf_detect(struct i2c_adapter *adapter)
1107 device_create_file_in(new_client, 2); 1121 device_create_file_in(new_client, 2);
1108 device_create_file_in(new_client, 3); 1122 device_create_file_in(new_client, 3);
1109 device_create_file_in(new_client, 4); 1123 device_create_file_in(new_client, 4);
1110 if (kind != w83627thf && kind != w83637hf) { 1124 if (kind == w83627hf || kind == w83697hf) {
1111 device_create_file_in(new_client, 5); 1125 device_create_file_in(new_client, 5);
1112 device_create_file_in(new_client, 6); 1126 device_create_file_in(new_client, 6);
1113 } 1127 }
@@ -1140,7 +1154,7 @@ static int w83627hf_detect(struct i2c_adapter *adapter)
1140 1154
1141 device_create_file_pwm(new_client, 1); 1155 device_create_file_pwm(new_client, 1);
1142 device_create_file_pwm(new_client, 2); 1156 device_create_file_pwm(new_client, 2);
1143 if (kind == w83627thf || kind == w83637hf) 1157 if (kind == w83627thf || kind == w83637hf || kind == w83687thf)
1144 device_create_file_pwm(new_client, 3); 1158 device_create_file_pwm(new_client, 3);
1145 1159
1146 device_create_file_sensor(new_client, 1); 1160 device_create_file_sensor(new_client, 1);
@@ -1248,6 +1262,33 @@ exit:
1248 return res; 1262 return res;
1249} 1263}
1250 1264
1265static int w83687thf_read_vid(struct i2c_client *client)
1266{
1267 int res = 0xff;
1268
1269 superio_enter();
1270 superio_select(W83627HF_LD_HWM);
1271
1272 /* Make sure these GPIO pins are enabled */
1273 if (!(superio_inb(W83687THF_VID_EN) & (1 << 2))) {
1274 dev_dbg(&client->dev, "VID disabled, no VID function\n");
1275 goto exit;
1276 }
1277
1278 /* Make sure the pins are configured for input */
1279 if (!(superio_inb(W83687THF_VID_CFG) & (1 << 4))) {
1280 dev_dbg(&client->dev, "VID configured as output, "
1281 "no VID function\n");
1282 goto exit;
1283 }
1284
1285 res = superio_inb(W83687THF_VID_DATA) & 0x3f;
1286
1287exit:
1288 superio_exit();
1289 return res;
1290}
1291
1251static int w83627hf_write_value(struct i2c_client *client, u16 reg, u16 value) 1292static int w83627hf_write_value(struct i2c_client *client, u16 reg, u16 value)
1252{ 1293{
1253 struct w83627hf_data *data = i2c_get_clientdata(client); 1294 struct w83627hf_data *data = i2c_get_clientdata(client);
@@ -1325,10 +1366,13 @@ static void w83627hf_init_client(struct i2c_client *client)
1325 data->vid = (lo & 0x0f) | ((hi & 0x01) << 4); 1366 data->vid = (lo & 0x0f) | ((hi & 0x01) << 4);
1326 } else if (w83627thf == data->type) { 1367 } else if (w83627thf == data->type) {
1327 data->vid = w83627thf_read_gpio5(client); 1368 data->vid = w83627thf_read_gpio5(client);
1369 } else if (w83687thf == data->type) {
1370 data->vid = w83687thf_read_vid(client);
1328 } 1371 }
1329 1372
1330 /* Read VRM & OVT Config only once */ 1373 /* Read VRM & OVT Config only once */
1331 if (w83627thf == data->type || w83637hf == data->type) { 1374 if (w83627thf == data->type || w83637hf == data->type
1375 || w83687thf == data->type) {
1332 data->vrm_ovt = 1376 data->vrm_ovt =
1333 w83627hf_read_value(client, W83627THF_REG_VRM_OVT_CFG); 1377 w83627hf_read_value(client, W83627THF_REG_VRM_OVT_CFG);
1334 } 1378 }
@@ -1395,7 +1439,7 @@ static struct w83627hf_data *w83627hf_update_device(struct device *dev)
1395 for (i = 0; i <= 8; i++) { 1439 for (i = 0; i <= 8; i++) {
1396 /* skip missing sensors */ 1440 /* skip missing sensors */
1397 if (((data->type == w83697hf) && (i == 1)) || 1441 if (((data->type == w83697hf) && (i == 1)) ||
1398 ((data->type == w83627thf || data->type == w83637hf) 1442 ((data->type != w83627hf && data->type != w83697hf)
1399 && (i == 5 || i == 6))) 1443 && (i == 5 || i == 6)))
1400 continue; 1444 continue;
1401 data->in[i] = 1445 data->in[i] =