Show
Ignore:
Timestamp:
06/12/02 04:53:33 (11 years ago)
Author:
mds
Message:

ich4 software pec support. Still cleanups to be done but enough for ARP.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • lm-sensors/trunk/kernel/busses/i2c-i801.c

    r1387 r1391  
    4949#include "version.h" 
    5050 
     51#define DEBUG 1 
    5152#ifdef MODULE_LICENSE 
    5253MODULE_LICENSE("GPL"); 
     54#endif 
     55 
     56#ifdef I2C_FUNC_SMBUS_BLOCK_DATA_PEC 
     57#define HAVE_PEC 
    5358#endif 
    5459 
     
    8085#define SMBHSTDAT1 (6 + i801_smba) 
    8186#define SMBBLKDAT (7 + i801_smba) 
     87#define SMBPEC    (8 + i801_smba)       /* ICH4 only */ 
     88#define SMBAUXSTS (12 + i801_smba)      /* ICH4 only */ 
     89#define SMBAUXCTL (13 + i801_smba)      /* ICH4 only */ 
    8290 
    8391/* PCI Address Constants */ 
     
    92100 
    93101/* Other settings */ 
    94 #define MAX_TIMEOUT 500 
    95 #define  ENABLE_INT9 0 
     102#define MAX_TIMEOUT 100 
     103#define ENABLE_INT9 0   /* set to 0x01 to enable - untested */ 
    96104 
    97105/* I801 command constants */ 
     
    104112#define I801_BLOCK_LAST     0x34 
    105113#define I801_I2C_BLOCK_LAST 0x38        /* unimplemented */ 
     114#define I801_START          0x40 
     115#define I801_PEC_EN         0x80        /* ICH4 only */ 
    106116 
    107117/* insmod parameters */ 
     
    170180static unsigned short i801_smba = 0; 
    171181static struct pci_dev *I801_dev = NULL; 
    172  
     182static int isich4 = 0; 
    173183 
    174184/* Detect whether a I801 can be found, and initialize it, where necessary. 
     
    208218                goto END; 
    209219        } 
     220        isich4 = *num == PCI_DEVICE_ID_INTEL_82801DB_SMBUS; 
    210221 
    211222/* Determine the address of the SMBus areas */ 
     
    218229        } 
    219230 
    220         if (check_region(i801_smba, 8)) { 
     231        if (check_region(i801_smba, (isich4 ? 16 : 8))) { 
    221232                printk 
    222233                    (KERN_ERR "i2c-i801.o: I801_smb region 0x%x already in use!\n", 
     
    238249        } else if ((temp & 1) == 0) { 
    239250                if (force) { 
    240 /* This should never need to be done, but has been noted that 
    241    many Dell machines have the SMBus interface on the PIIX4 
    242    disabled!? NOTE: This assumes I/O space and other allocations WERE 
     251/* NOTE: This assumes I/O space and other allocations WERE 
    243252   done by the Bios!  Don't complain if your hardware does weird  
    244253   things after enabling this. :') Check for Bios updates before 
     
    259268        /* note: we assumed that the BIOS picked SMBus or I2C Bus timing 
    260269           appropriately (bit 2 in SMBHSTCFG) */ 
    261         /* Everything is happy, let's grab the memory and set things up. */ 
    262         request_region(i801_smba, 8, "i801-smbus"); 
     270        request_region(i801_smba, (isich4 ? 16 : 8), "i801-smbus"); 
    263271 
    264272#ifdef DEBUG 
     
    280288 
    281289 
    282 /* Internally used pause function */ 
    283290void i801_do_pause(unsigned int amount) 
    284291{ 
     
    287294} 
    288295 
    289 /* Another internally used function */ 
    290296int i801_transaction(void) 
    291297{ 
     
    309315#endif 
    310316                outb_p(temp, SMBHSTSTS); 
    311                 if ((temp = inb_p(SMBHSTSTS)) != 0x00) { 
     317                if ((temp = (0x1f & inb_p(SMBHSTSTS))) != 0x00) { 
    312318#ifdef DEBUG 
    313319                        printk(KERN_DEBUG "i2c-i801.o: Failed! (%02x)\n", temp); 
     
    321327        } 
    322328 
    323         /* start the transaction by setting bit 6 */ 
    324         outb_p(inb(SMBHSTCNT) | 0x040, SMBHSTCNT); 
     329        outb_p(inb(SMBHSTCNT) | I801_START, SMBHSTCNT); 
    325330 
    326331        /* We will always wait for a fraction of a second! */ 
     
    381386/* All-inclusive block transaction function */ 
    382387int i801_block_transaction(union i2c_smbus_data *data, char read_write,  
    383                            int i2c_enable) 
     388                           int command) 
    384389{ 
    385390        int i, len; 
     
    387392        int temp; 
    388393        int result = 0; 
    389         int timeout = 0; 
     394        int timeout; 
    390395        unsigned char hostc, errmask; 
    391396 
    392         if (i2c_enable) { 
     397        if (command == I2C_SMBUS_I2C_BLOCK_DATA) { 
    393398                if (read_write == I2C_SMBUS_WRITE) { 
    394399                        /* set I2C_EN bit in configuration register */ 
     
    420425                else 
    421426                        smbcmd = I801_BLOCK_DATA; 
    422  
    423                 outb_p((smbcmd & 0x3C) + (ENABLE_INT9 & 1), SMBHSTCNT); 
     427#ifdef HAVE_PEC 
     428                if(isich4 && command == I2C_SMBUS_BLOCK_DATA_PEC) 
     429                        smbcmd |= I801_PEC_EN; 
     430#endif 
     431                outb_p(smbcmd | ENABLE_INT9, SMBHSTCNT); 
    424432 
    425433#ifdef DEBUG 
     
    462470                } 
    463471 
    464                 /* start the transaction by setting bit 6 */ 
    465                 if (i==1) outb_p(inb(SMBHSTCNT) | 0x040, SMBHSTCNT); 
     472                if (i == 1) { 
     473#ifdef HAVE_PEC 
     474                        if(isich4 && command == I2C_SMBUS_BLOCK_DATA_PEC) { 
     475                                if(read_write == I2C_SMBUS_WRITE) 
     476                                        outb_p(data->block[len + 1], SMBPEC); 
     477                        } 
     478#endif 
     479                        outb_p(inb(SMBHSTCNT) | I801_START, SMBHSTCNT); 
     480                } 
    466481 
    467482                /* We will always wait for a fraction of a second! */ 
     483                timeout = 0; 
    468484                do { 
    469485                        temp = inb_p(SMBHSTSTS); 
    470486                        i801_do_pause(1); 
    471487                } 
    472                     while ( 
    473                            (((i >= len) && (temp & 0x01)) 
    474                             || ((i < len) && !(temp & 0x80))) 
     488                    while ((!(temp & 0x80)) 
    475489                           && (timeout++ < MAX_TIMEOUT)); 
    476490 
     
    491505                } else if (temp & 0x08) { 
    492506                        result = -1; 
    493                         printk 
    494                             (KERN_ERR "i2c-i801.o: Bus collision! SMBus may be locked until next hard" 
    495                              " reset. (sorry!)\n"); 
    496                         /* Clock stops and slave is stuck in mid-transmission */ 
     507                        printk(KERN_ERR "i2c-i801.o: Bus collision!\n"); 
    497508                } else if (temp & 0x04) { 
    498509                        result = -1; 
     
    517528                        outb_p(data->block[i+1], SMBBLKDAT); 
    518529                if ((temp & 0x9e) != 0x00) 
    519                         outb_p(temp, SMBHSTSTS);  /* signals SMBBLKDAT ready */ 
    520  
    521                 temp = inb_p(SMBHSTSTS); 
     530                        outb_p(temp, SMBHSTSTS);  /* signals SMBBLKDAT ready */ 
     531 
     532#ifdef DEBUG 
    522533                if ((temp = (0x1e & inb_p(SMBHSTSTS))) != 0x00) { 
    523 #ifdef DEBUG 
    524534                        printk 
    525                             (KERN_DEBUG "i2c-i801.o: Failed reset at end of transaction (%02x)\n", 
     535                            (KERN_DEBUG "i2c-i801.o: Bad status (%02x) at end of transaction\n", 
    526536                             temp); 
    527 #endif 
    528                 } 
    529 #ifdef DEBUG 
     537                } 
    530538                printk 
    531539                    (KERN_DEBUG "i2c-i801.o: Block (post %d): CNT=%02x, CMD=%02x, ADD=%02x, " 
     
    535543#endif 
    536544 
    537                 if (result < 0) { 
     545                if (result < 0) 
    538546                        goto END; 
    539                 } 
    540         } 
     547        } 
     548#ifdef HAVE_PEC 
     549        if(isich4 && command == I2C_SMBUS_BLOCK_DATA_PEC) { 
     550                timeout = 0; 
     551                do { 
     552                        temp = inb_p(SMBHSTSTS); 
     553                        i801_do_pause(1); 
     554                } 
     555                    while ((!(temp & 0x80)) 
     556                           && (timeout++ < MAX_TIMEOUT)); 
     557 
     558                /* If the SMBus is still busy, we give up */ 
     559                if (timeout >= MAX_TIMEOUT) { 
     560#ifdef DEBUG 
     561                        printk(KERN_DEBUG "i2c-i801.o: PEC Timeout!\n"); 
     562#endif 
     563                } 
     564                if(read_write == I2C_SMBUS_READ) { 
     565                        data->block[len + 1] = inb_p(SMBPEC); 
     566                } 
     567                outb_p(temp, SMBHSTSTS);  
     568                printk("i2c-i801.o: sts = 0x%02x len = %d PEC = 0x%02x\n", temp, len, data->block[len + 1]); 
     569        } 
     570#endif 
    541571        result = 0; 
    542572END: 
    543         if (i2c_enable) { 
     573        if (command == I2C_SMBUS_I2C_BLOCK_DATA) { 
    544574                /* restore saved configuration register value */ 
    545575                pci_write_config_byte(I801_dev, SMBHSTCFG, hostc); 
     
    548578} 
    549579 
    550 /* Return -1 on error. See smbus.h for more information */ 
     580/* Return -1 on error. */ 
    551581s32 i801_access(struct i2c_adapter * adap, u16 addr, unsigned short flags, 
    552582                char read_write, u8 command, int size, 
     
    555585 
    556586        switch (size) { 
    557         case I2C_SMBUS_PROC_CALL: 
    558                 printk(KERN_ERR "i2c-i801.o: I2C_SMBUS_PROC_CALL not supported!\n"); 
    559                 return -1; 
    560587        case I2C_SMBUS_QUICK: 
    561588                outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), 
     
    590617        case I2C_SMBUS_BLOCK_DATA: 
    591618        case I2C_SMBUS_I2C_BLOCK_DATA: 
     619#ifdef HAVE_PEC 
     620        case I2C_SMBUS_BLOCK_DATA_PEC: 
     621#endif 
    592622                outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), 
    593623                       SMBHSTADD); 
    594624                outb_p(command, SMBHSTCMD); 
    595                 /* Block transactions are very different from piix4 block 
    596                    and from the other i801 transactions. Handle in the 
    597                    i801_block_transaction() routine. */ 
    598                 return i801_block_transaction(data, read_write,  
    599                                               size==I2C_SMBUS_I2C_BLOCK_DATA); 
     625                return i801_block_transaction(data, read_write, size); 
     626        case I2C_SMBUS_PROC_CALL: 
     627        default: 
     628                printk(KERN_ERR "i2c-i801.o: Unsupported transaction %d\n", size); 
     629                return -1; 
    600630        } 
    601631 
    602632        /* 'size' is really the transaction type */ 
    603         outb_p((size & 0x3C) + (ENABLE_INT9 & 1), SMBHSTCNT); 
     633        outb_p(size | ENABLE_INT9, SMBHSTCNT); 
    604634 
    605635        if (i801_transaction()) /* Error in transaction */ 
     
    686716        } 
    687717        if (i801_initialized >= 1) { 
    688                 release_region(i801_smba, 8); 
     718                release_region(i801_smba, (isich4 ? 16 : 8)); 
    689719                i801_initialized--; 
    690720        }