aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/busses/i2c-i801.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c/busses/i2c-i801.c')
-rw-r--r--drivers/i2c/busses/i2c-i801.c61
1 files changed, 18 insertions, 43 deletions
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index 709beab76609..4f63195069da 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -52,10 +52,6 @@
52#include <linux/i2c.h> 52#include <linux/i2c.h>
53#include <asm/io.h> 53#include <asm/io.h>
54 54
55#ifdef I2C_FUNC_SMBUS_BLOCK_DATA_PEC
56#define HAVE_PEC
57#endif
58
59/* I801 SMBus address offsets */ 55/* I801 SMBus address offsets */
60#define SMBHSTSTS (0 + i801_smba) 56#define SMBHSTSTS (0 + i801_smba)
61#define SMBHSTCNT (2 + i801_smba) 57#define SMBHSTCNT (2 + i801_smba)
@@ -106,10 +102,11 @@ MODULE_PARM_DESC(force_addr,
106 "EXTREMELY DANGEROUS!"); 102 "EXTREMELY DANGEROUS!");
107 103
108static int i801_transaction(void); 104static int i801_transaction(void);
109static int i801_block_transaction(union i2c_smbus_data *data, 105static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
110 char read_write, int command); 106 int command, int hwpec);
111 107
112static unsigned short i801_smba; 108static unsigned short i801_smba;
109static struct pci_driver i801_driver;
113static struct pci_dev *I801_dev; 110static struct pci_dev *I801_dev;
114static int isich4; 111static int isich4;
115 112
@@ -143,7 +140,7 @@ static int i801_setup(struct pci_dev *dev)
143 } 140 }
144 } 141 }
145 142
146 if (!request_region(i801_smba, (isich4 ? 16 : 8), "i801-smbus")) { 143 if (!request_region(i801_smba, (isich4 ? 16 : 8), i801_driver.name)) {
147 dev_err(&dev->dev, "I801_smb region 0x%x already in use!\n", 144 dev_err(&dev->dev, "I801_smb region 0x%x already in use!\n",
148 i801_smba); 145 i801_smba);
149 error_return = -EBUSY; 146 error_return = -EBUSY;
@@ -252,7 +249,7 @@ static int i801_transaction(void)
252 249
253/* All-inclusive block transaction function */ 250/* All-inclusive block transaction function */
254static int i801_block_transaction(union i2c_smbus_data *data, char read_write, 251static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
255 int command) 252 int command, int hwpec)
256{ 253{
257 int i, len; 254 int i, len;
258 int smbcmd; 255 int smbcmd;
@@ -391,8 +388,7 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
391 goto END; 388 goto END;
392 } 389 }
393 390
394#ifdef HAVE_PEC 391 if (hwpec) {
395 if(isich4 && command == I2C_SMBUS_BLOCK_DATA_PEC) {
396 /* wait for INTR bit as advised by Intel */ 392 /* wait for INTR bit as advised by Intel */
397 timeout = 0; 393 timeout = 0;
398 do { 394 do {
@@ -406,7 +402,6 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
406 } 402 }
407 outb_p(temp, SMBHSTSTS); 403 outb_p(temp, SMBHSTSTS);
408 } 404 }
409#endif
410 result = 0; 405 result = 0;
411END: 406END:
412 if (command == I2C_SMBUS_I2C_BLOCK_DATA) { 407 if (command == I2C_SMBUS_I2C_BLOCK_DATA) {
@@ -421,14 +416,13 @@ static s32 i801_access(struct i2c_adapter * adap, u16 addr,
421 unsigned short flags, char read_write, u8 command, 416 unsigned short flags, char read_write, u8 command,
422 int size, union i2c_smbus_data * data) 417 int size, union i2c_smbus_data * data)
423{ 418{
424 int hwpec = 0; 419 int hwpec;
425 int block = 0; 420 int block = 0;
426 int ret, xact = 0; 421 int ret, xact = 0;
427 422
428#ifdef HAVE_PEC 423 hwpec = isich4 && (flags & I2C_CLIENT_PEC)
429 if(isich4) 424 && size != I2C_SMBUS_QUICK
430 hwpec = (flags & I2C_CLIENT_PEC) != 0; 425 && size != I2C_SMBUS_I2C_BLOCK_DATA;
431#endif
432 426
433 switch (size) { 427 switch (size) {
434 case I2C_SMBUS_QUICK: 428 case I2C_SMBUS_QUICK:
@@ -463,11 +457,6 @@ static s32 i801_access(struct i2c_adapter * adap, u16 addr,
463 break; 457 break;
464 case I2C_SMBUS_BLOCK_DATA: 458 case I2C_SMBUS_BLOCK_DATA:
465 case I2C_SMBUS_I2C_BLOCK_DATA: 459 case I2C_SMBUS_I2C_BLOCK_DATA:
466#ifdef HAVE_PEC
467 case I2C_SMBUS_BLOCK_DATA_PEC:
468 if(hwpec && size == I2C_SMBUS_BLOCK_DATA)
469 size = I2C_SMBUS_BLOCK_DATA_PEC;
470#endif
471 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), 460 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
472 SMBHSTADD); 461 SMBHSTADD);
473 outb_p(command, SMBHSTCMD); 462 outb_p(command, SMBHSTCMD);
@@ -479,27 +468,18 @@ static s32 i801_access(struct i2c_adapter * adap, u16 addr,
479 return -1; 468 return -1;
480 } 469 }
481 470
482#ifdef HAVE_PEC 471 if (hwpec)
483 if(isich4 && hwpec) { 472 outb_p(1, SMBAUXCTL); /* enable hardware PEC */
484 if(size != I2C_SMBUS_QUICK && 473
485 size != I2C_SMBUS_I2C_BLOCK_DATA)
486 outb_p(1, SMBAUXCTL); /* enable HW PEC */
487 }
488#endif
489 if(block) 474 if(block)
490 ret = i801_block_transaction(data, read_write, size); 475 ret = i801_block_transaction(data, read_write, size, hwpec);
491 else { 476 else {
492 outb_p(xact | ENABLE_INT9, SMBHSTCNT); 477 outb_p(xact | ENABLE_INT9, SMBHSTCNT);
493 ret = i801_transaction(); 478 ret = i801_transaction();
494 } 479 }
495 480
496#ifdef HAVE_PEC 481 if (hwpec)
497 if(isich4 && hwpec) { 482 outb_p(0, SMBAUXCTL); /* disable hardware PEC */
498 if(size != I2C_SMBUS_QUICK &&
499 size != I2C_SMBUS_I2C_BLOCK_DATA)
500 outb_p(0, SMBAUXCTL);
501 }
502#endif
503 483
504 if(block) 484 if(block)
505 return ret; 485 return ret;
@@ -526,12 +506,7 @@ static u32 i801_func(struct i2c_adapter *adapter)
526 return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | 506 return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
527 I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | 507 I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
528 I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_SMBUS_WRITE_I2C_BLOCK 508 I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_SMBUS_WRITE_I2C_BLOCK
529#ifdef HAVE_PEC 509 | (isich4 ? I2C_FUNC_SMBUS_HWPEC_CALC : 0);
530 | (isich4 ? I2C_FUNC_SMBUS_BLOCK_DATA_PEC |
531 I2C_FUNC_SMBUS_HWPEC_CALC
532 : 0)
533#endif
534 ;
535} 510}
536 511
537static struct i2c_algorithm smbus_algorithm = { 512static struct i2c_algorithm smbus_algorithm = {
@@ -543,7 +518,6 @@ static struct i2c_adapter i801_adapter = {
543 .owner = THIS_MODULE, 518 .owner = THIS_MODULE,
544 .class = I2C_CLASS_HWMON, 519 .class = I2C_CLASS_HWMON,
545 .algo = &smbus_algorithm, 520 .algo = &smbus_algorithm,
546 .name = "unset",
547}; 521};
548 522
549static struct pci_device_id i801_ids[] = { 523static struct pci_device_id i801_ids[] = {
@@ -586,6 +560,7 @@ static void __devexit i801_remove(struct pci_dev *dev)
586} 560}
587 561
588static struct pci_driver i801_driver = { 562static struct pci_driver i801_driver = {
563 .owner = THIS_MODULE,
589 .name = "i801_smbus", 564 .name = "i801_smbus",
590 .id_table = i801_ids, 565 .id_table = i801_ids,
591 .probe = i801_probe, 566 .probe = i801_probe,