Changeset 856

Show
Ignore:
Timestamp:
08/12/00 18:33:25 (13 years ago)
Author:
mds
Message:

(mds) smbus block write fixes, i2c block write support from Rickard Westman.

Location:
lm-sensors/trunk
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • lm-sensors/trunk/CHANGES

    r853 r856  
    16162.5.3 (2000????) 
    1717  Module i2c-i801: support Intel 82801BA (815E chipset) 
     18  Module i2c-i801: add i2c block support, fix smbus block bugs 
     19                   (requires i2c 2.5.3 package) 
    1820  Programs i2cdetect, i2cdump: Improve error reporting 
    1921  Program sensors: new switch -u (--unknown) 
  • lm-sensors/trunk/kernel/busses/i2c-i801.c

    r849 r856  
    6666#define SMBREV    0x008 
    6767 
     68/* Host configuration bits for SMBHSTCFG */ 
     69#define SMBHSTCFG_HST_EN      1 
     70#define SMBHSTCFG_SMB_SMI_EN  2 
     71#define SMBHSTCFG_I2C_EN      4 
     72 
    6873/* Other settings */ 
    6974#define MAX_TIMEOUT 500 
     
    104109static int i801_transaction(void); 
    105110static int i801_block_transaction(union i2c_smbus_data *data, 
    106                                   char read_write); 
     111                                  char read_write, int i2c_enable); 
    107112static void i801_inc(struct i2c_adapter *adapter); 
    108113static void i801_dec(struct i2c_adapter *adapter); 
     
    118123        /* id */ I2C_ALGO_SMBUS, 
    119124        /* master_xfer */ NULL, 
    120         /* smbus_access */ i801_access, 
     125        /* smbus_xfer */ i801_access, 
    121126        /* slave_send */ NULL, 
    122127        /* slave_rcv */ NULL, 
     
    138143static int __initdata i801_initialized; 
    139144static unsigned short i801_smba = 0; 
     145static struct pci_dev *I801_dev = NULL; 
    140146 
    141147 
     
    148154        int error_return = 0; 
    149155        unsigned char temp; 
    150  
    151         struct pci_dev *I801_dev; 
    152156 
    153157        /* First check whether we can access PCI at all */ 
     
    359363 
    360364/* All-inclusive block transaction function */ 
    361 int i801_block_transaction(union i2c_smbus_data *data, char read_write) 
     365int i801_block_transaction(union i2c_smbus_data *data, char read_write,  
     366                           int i2c_enable) 
    362367{ 
    363368        int i, len; 
     
    366371        int result = 0; 
    367372        int timeout = 0; 
     373        unsigned char hostc, errmask; 
     374 
     375        if (i2c_enable) { 
     376                if (read_write == I2C_SMBUS_WRITE) { 
     377                        /* set I2C_EN bit in configuration register */ 
     378                        pci_read_config_byte(I801_dev, SMBHSTCFG, &hostc); 
     379                        pci_write_config_byte(I801_dev, SMBHSTCFG,  
     380                                              hostc | SMBHSTCFG_I2C_EN); 
     381                } else { 
     382                        printk("i2c-i801.o: " 
     383                               "I2C_SMBUS_I2C_BLOCK_READ not supported!\n"); 
     384                        return -1; 
     385                } 
     386        } 
    368387 
    369388        if (read_write == I2C_SMBUS_WRITE) { 
     
    384403                else 
    385404                        smbcmd = I801_BLOCK_DATA; 
    386                 if (read_write == I2C_SMBUS_WRITE) 
    387                         outb_p(data->block[i], SMBBLKDAT); 
     405 
    388406                outb_p((smbcmd & 0x3C) + (ENABLE_INT9 & 1), SMBHSTCNT); 
    389407 
     
    391409                printk 
    392410                    ("i2c-i801.o: Transaction (pre): CNT=%02x, CMD=%02x, ADD=%02x, " 
    393                      "DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT), 
     411                     "DAT0=%02x, BLKDAT=%02x\n", inb_p(SMBHSTCNT), 
    394412                     inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), 
    395                      inb_p(SMBHSTDAT1)); 
     413                     inb_p(SMBBLKDAT)); 
    396414#endif 
    397415 
    398416                /* Make sure the SMBus host is ready to start transmitting */ 
    399                 /* 0x1f = Failed, Bus_Err, Dev_Err, Intr, Host_Busy */ 
    400                 /* 0x9e = Byte_Done, Failed, Bus_Err, Dev_Err, Intr */ 
    401417                temp = inb_p(SMBHSTSTS); 
    402                 if (((i == 1) && ((temp & 0x1f) != 0x00)) || 
    403                     ((i != 1) && ((temp & 0x9e) != 0x00))) { 
     418                if (i == 1) { 
     419                    /* Erronenous conditions before transaction:  
     420                     * Byte_Done, Failed, Bus_Err, Dev_Err, Intr, Host_Busy */ 
     421                    errmask=0x9f;  
     422                } else { 
     423                    /* Erronenous conditions during transaction:  
     424                     * Failed, Bus_Err, Dev_Err, Intr */ 
     425                    errmask=0x1e;  
     426                } 
     427                if (temp & errmask) { 
    404428#ifdef DEBUG 
    405429                        printk 
     
    408432#endif 
    409433                        outb_p(temp, SMBHSTSTS); 
    410                         if (((temp = inb_p(SMBHSTSTS)) & 0x9f) != 0x00) { 
     434                        if (((temp = inb_p(SMBHSTSTS)) & errmask) != 0x00) { 
    411435                                printk 
    412436                                    ("i2c-i801.o: Reset failed! (%02x)\n", 
    413437                                     temp); 
    414                                 return -1; 
     438                                result = -1; 
     439                                goto END; 
    415440                        } 
    416                         if (i != 1) 
    417                                 return -1;      /* if die in middle of block transaction, fail */ 
     441                        if (i != 1) { 
     442                                result = -1;  /* if die in middle of block transaction, fail */ 
     443                                goto END; 
     444                        } 
    418445                } 
    419446 
    420447                /* start the transaction by setting bit 6 */ 
    421                 outb_p(inb(SMBHSTCNT) | 0x040, SMBHSTCNT); 
     448                if (i==1) outb_p(inb(SMBHSTCNT) | 0x040, SMBHSTCNT); 
    422449 
    423450                /* We will always wait for a fraction of a second! */ 
    424451                do { 
     452                        temp = inb_p(SMBHSTSTS); 
    425453                        i801_do_pause(1); 
    426                         temp = inb_p(SMBHSTSTS); 
    427454                } 
    428455                    while ( 
    429456                           (((i >= len) && (temp & 0x01)) 
    430                             || ((i < len) && (temp & 0x80))) 
     457                            || ((i < len) && !(temp & 0x80))) 
    431458                           && (timeout++ < MAX_TIMEOUT)); 
    432459 
     
    456483                        printk("i2c-i801.o: Error: no response!\n"); 
    457484#endif 
    458                 } else if (temp & 0x80) { 
    459                         result = -1; 
    460 #ifdef DEBUG 
    461                         printk 
    462                             ("i2c-i801.o: Error: Failed in middle of block!\n"); 
    463 #endif 
    464                 } 
    465  
    466                 if ((temp & 0x9f) != 0x00) 
    467                         outb_p(temp, SMBHSTSTS); 
    468  
    469                 if ((temp = (0x9f & inb_p(SMBHSTSTS))) != 0x00) { 
    470 #ifdef DEBUG 
    471                         printk 
    472                             ("i2c-i801.o: Failed reset at end of transaction (%02x)\n", 
    473                              temp); 
    474 #endif 
    475                 } 
    476 #ifdef DEBUG 
    477                 printk 
    478                     ("i2c-i801.o: Transaction (post): CNT=%02x, CMD=%02x, ADD=%02x, " 
    479                      "DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT), 
    480                      inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), 
    481                      inb_p(SMBHSTDAT1)); 
    482 #endif 
     485                } 
    483486 
    484487                if (i == 1 && read_write == I2C_SMBUS_READ) { 
     
    490493                        data->block[0] = len; 
    491494                } 
     495 
     496                /* Retrieve/store value in SMBBLKDAT */ 
    492497                if (read_write == I2C_SMBUS_READ) 
    493498                        data->block[i] = inb_p(SMBBLKDAT); 
    494  
    495                 if (result < 0) 
    496                         return (result); 
    497         } 
    498         return (0); 
     499                if (read_write == I2C_SMBUS_WRITE && i+1 <= len) 
     500                        outb_p(data->block[i+1], SMBBLKDAT); 
     501                if ((temp & 0x9e) != 0x00) 
     502                        outb_p(temp, SMBHSTSTS);  /* signals SMBBLKDAT ready */ 
     503 
     504                temp = inb_p(SMBHSTSTS); 
     505                if ((temp = (0x1e & inb_p(SMBHSTSTS))) != 0x00) { 
     506#ifdef DEBUG 
     507                        printk 
     508                            ("i2c-i801.o: Failed reset at end of transaction (%02x)\n", 
     509                             temp); 
     510#endif 
     511                } 
     512#ifdef DEBUG 
     513                printk 
     514                    ("i2c-i801.o: Transaction (post): CNT=%02x, CMD=%02x, ADD=%02x, " 
     515                     "DAT0=%02x, BLKDAT=%02x\n", inb_p(SMBHSTCNT), 
     516                     inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), 
     517                     inb_p(SMBBLKDAT)); 
     518#endif 
     519 
     520                if (result < 0) { 
     521                        goto END; 
     522                } 
     523        } 
     524        result = 0; 
     525END: 
     526        if (i2c_enable) { 
     527                /* restore saved configuration register value */ 
     528                pci_write_config_byte(I801_dev, SMBHSTCFG, hostc); 
     529        } 
     530        return result; 
    499531} 
    500532 
     
    540572                break; 
    541573        case I2C_SMBUS_BLOCK_DATA: 
     574        case I2C_SMBUS_I2C_BLOCK_DATA: 
    542575                outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), 
    543576                       SMBHSTADD); 
     
    546579                   and from the other i801 transactions. Handle in the 
    547580                   i801_block_transaction() routine. */ 
    548                 return (i801_block_transaction(data, read_write)); 
     581                return i801_block_transaction(data, read_write,  
     582                                              size==I2C_SMBUS_I2C_BLOCK_DATA); 
    549583        } 
    550584 
     
    587621        return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | 
    588622            I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | 
    589             I2C_FUNC_SMBUS_BLOCK_DATA; 
     623            I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_SMBUS_WRITE_I2C_BLOCK; 
    590624} 
    591625