Show
Ignore:
Timestamp:
08/26/99 02:39:34 (14 years ago)
Author:
mds
Message:

(mds) Added block read/write support. Much different than piix4.

Files:
1 modified

Legend:

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

    r528 r537  
    2323    This driver supports the Intel 82801AA and 82801AB 
    2424    I/O Controller Hubs (ICH). They are similar to the PIIX4 and are part 
    25     of Intel's '810' chipset. See the doc/busses directory for details. 
     25    of Intel's '810' chipset. See the doc/busses/i2c-i801 file for details. 
    2626*/       
    2727 
     
    6868#define  ENABLE_INT9 0 
    6969 
    70 /* I801 constants */ 
    71 #define I801_QUICK      0x00 
    72 #define I801_BYTE       0x04 
    73 #define I801_BYTE_DATA  0x08 
    74 #define I801_WORD_DATA  0x0C 
    75 #define I801_BLOCK_DATA 0x14 
     70/* I801 command constants */ 
     71#define I801_QUICK          0x00 
     72#define I801_BYTE           0x04 
     73#define I801_BYTE_DATA      0x08 
     74#define I801_WORD_DATA      0x0C 
     75#define I801_BLOCK_DATA     0x14 
     76#define I801_I2C_BLOCK_DATA 0x18        /* unimplemented */ 
     77#define I801_BLOCK_LAST     0x34 
     78#define I801_I2C_BLOCK_LAST 0x38        /* unimplemented */ 
    7679 
    7780/* insmod parameters */ 
     
    9699static void i801_do_pause( unsigned int amount ); 
    97100static int i801_transaction(void); 
     101static int i801_block_transaction(union i2c_smbus_data *data, char read_write); 
    98102static void i801_inc(struct i2c_adapter *adapter); 
    99103static void i801_dec(struct i2c_adapter *adapter); 
     
    195199    force = 0; 
    196200  } else { 
    197  
    198201    pci_read_config_word_united(I801_dev, I801_bus ,I801_devfn, 
    199202                                SMBBA,&i801_smba); 
     
    304307  outb_p(inb(SMBHSTCNT) | 0x040, SMBHSTCNT);  
    305308 
    306   /* We will always wait for a fraction of a second! (See PIIX4 docs errata) */ 
     309  /* We will always wait for a fraction of a second! */ 
    307310  do { 
    308311    i801_do_pause(1); 
     
    356359} 
    357360 
     361/* All-inclusive block transaction function */ 
     362int i801_block_transaction(union i2c_smbus_data *data, char read_write) 
     363{ 
     364  int i, len; 
     365  int smbcmd; 
     366  int temp; 
     367  int result=0; 
     368  int timeout=0; 
     369 
     370  if (read_write == I2C_SMBUS_WRITE) { 
     371    len = data->block[0]; 
     372    if (len < 1)  
     373      len = 1; 
     374    if (len > 32) 
     375      len = 32; 
     376    outb_p(len,SMBHSTDAT0); 
     377    outb_p(data->block[1],SMBBLKDAT); 
     378  } else { 
     379    len = 32;   /* max for reads */ 
     380  } 
     381 
     382  for(i = 1; i <= len; i++) 
     383  { 
     384    if(i == len  &&  read_write == I2C_SMBUS_READ) 
     385      smbcmd = I801_BLOCK_LAST; 
     386    else 
     387      smbcmd = I801_BLOCK_DATA; 
     388    if (read_write == I2C_SMBUS_WRITE) 
     389      outb_p(data->block[i],SMBBLKDAT); 
     390    outb_p((smbcmd & 0x3C) + (ENABLE_INT9 & 1), SMBHSTCNT); 
     391 
     392#ifdef DEBUG 
     393    printk("i2c-i801.o: Transaction (pre): CNT=%02x, CMD=%02x, ADD=%02x, " 
     394           "DAT0=%02x, DAT1=%02x\n", 
     395           inb_p(SMBHSTCNT),inb_p(SMBHSTCMD),inb_p(SMBHSTADD),inb_p(SMBHSTDAT0), 
     396           inb_p(SMBHSTDAT1)); 
     397#endif 
     398 
     399  /* Make sure the SMBus host is ready to start transmitting */ 
     400  /* 0x1f = Failed, Bus_Err, Dev_Err, Intr, Host_Busy */ 
     401  /* 0x9e = Byte_Done, Failed, Bus_Err, Dev_Err, Intr */ 
     402    temp = inb_p(SMBHSTSTS); 
     403    if (((i == 1)  &&  ((temp & 0x1f) != 0x00)) || 
     404        ((i != 1)  &&  ((temp & 0x9e) != 0x00))) 
     405    { 
     406#ifdef DEBUG 
     407      printk("i2c-i801.o: SMBus busy (%02x). Resetting... \n",temp); 
     408#endif 
     409      outb_p(temp, SMBHSTSTS); 
     410      if (((temp = inb_p(SMBHSTSTS)) & 0x9f) != 0x00) 
     411      { 
     412        printk("i2c-i801.o: Reset failed! (%02x)\n",temp); 
     413        return -1; 
     414      } 
     415      if(i != 1) 
     416        return -1;   /* if die in middle of block transaction, fail */ 
     417    } 
     418 
     419    /* start the transaction by setting bit 6 */ 
     420    outb_p(inb(SMBHSTCNT) | 0x040, SMBHSTCNT);  
     421 
     422    /* We will always wait for a fraction of a second! */ 
     423    do { 
     424      i801_do_pause(1); 
     425      temp=inb_p(SMBHSTSTS); 
     426    } while ((((i >= len) && (temp & 0x01)) || ((i < len) && (temp & 0x80))) 
     427             && (timeout++ < MAX_TIMEOUT)); 
     428 
     429    /* If the SMBus is still busy, we give up */ 
     430    if (timeout >= MAX_TIMEOUT) { 
     431      result = -1; 
     432#ifdef DEBUG 
     433      printk("i2c-i801.o: SMBus Timeout!\n");  
     434#endif 
     435    } 
     436 
     437    if (temp & 0x10) { 
     438      result = -1; 
     439#ifdef DEBUG 
     440      printk("i2c-i801.o: Error: Failed bus transaction\n"); 
     441#endif 
     442    } else if (temp & 0x08) { 
     443      result = -1; 
     444      printk("i2c-i801.o: Bus collision! SMBus may be locked until next hard" 
     445             " reset. (sorry!)\n"); 
     446      /* Clock stops and slave is stuck in mid-transmission */ 
     447    } else if (temp & 0x04) { 
     448      result = -1; 
     449#ifdef DEBUG 
     450      printk("i2c-i801.o: Error: no response!\n"); 
     451#endif 
     452    } else if (temp & 0x80) { 
     453      result = -1; 
     454#ifdef DEBUG 
     455      printk("i2c-i801.o: Error: Failed in middle of block!\n"); 
     456#endif 
     457    } 
     458 
     459    if ((temp & 0x9f) != 0x00) 
     460      outb_p(temp, SMBHSTSTS); 
     461 
     462    if ((temp = (0x9f & inb_p(SMBHSTSTS))) != 0x00) { 
     463#ifdef DEBUG 
     464      printk("i2c-i801.o: Failed reset at end of transaction (%02x)\n",temp); 
     465#endif 
     466    } 
     467#ifdef DEBUG 
     468    printk("i2c-i801.o: Transaction (post): CNT=%02x, CMD=%02x, ADD=%02x, " 
     469           "DAT0=%02x, DAT1=%02x\n", 
     470           inb_p(SMBHSTCNT),inb_p(SMBHSTCMD),inb_p(SMBHSTADD),inb_p(SMBHSTDAT0), 
     471           inb_p(SMBHSTDAT1)); 
     472#endif 
     473 
     474    if (i == 1  &&  read_write == I2C_SMBUS_READ) { 
     475        len = inb_p(SMBHSTDAT0); 
     476      if (len < 1)  
     477        len = 1; 
     478      if (len > 32) 
     479        len = 32; 
     480      data->block[0] = len; 
     481    } 
     482    if (read_write == I2C_SMBUS_READ) 
     483      data->block[i] = inb_p(SMBBLKDAT); 
     484 
     485    if(result < 0) 
     486      return(result); 
     487  } 
     488  return(0); 
     489} 
     490 
    358491/* Return -1 on error. See smbus.h for more information */ 
    359492s32 i801_access(struct i2c_adapter *adap, u8 addr, char read_write, 
    360493                 u8 command, int size, union i2c_smbus_data * data) 
    361494{ 
    362   int i,len; 
    363495 
    364496  switch(size) { 
     
    395527      outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMBHSTADD); 
    396528      outb_p(command, SMBHSTCMD); 
    397       if (read_write == I2C_SMBUS_WRITE) { 
    398         len = data->block[0]; 
    399         if (len < 0)  
    400           len = 0; 
    401         if (len > 32) 
    402           len = 32; 
    403         outb_p(len,SMBHSTDAT0); 
    404         i = inb_p(SMBHSTCNT); /* Reset SMBBLKDAT */ 
    405         for (i = 1; i <= len; i ++) 
    406           outb_p(data->block[i],SMBBLKDAT); 
    407       } 
    408       size = I801_BLOCK_DATA; 
    409       break; 
    410   } 
    411  
    412   outb_p((size & 0x1C) + (ENABLE_INT9 & 1), SMBHSTCNT); 
     529      /* Block transactions are very different from piix4 block 
     530         and from the other i801 transactions. Handle in the 
     531         i801_block_transaction() routine. */ 
     532      return(i801_block_transaction(data, read_write)); 
     533  } 
     534 
     535  /* 'size' is really the transaction type */ 
     536  outb_p((size & 0x3C) + (ENABLE_INT9 & 1), SMBHSTCNT); 
    413537 
    414538  if (i801_transaction()) /* Error in transaction */  
     
    420544 
    421545  switch(size) { 
    422     case I801_BYTE: /* Where is the result put? I assume here it is in 
    423                         SMBHSTDAT0 but it might just as well be in the 
    424                         SMBHSTCMD. No clue in the docs */ 
    425   
     546    case I801_BYTE: /* Result put in SMBHSTDAT0 */ 
    426547      data->byte = inb_p(SMBHSTDAT0); 
    427548      break; 
     
    432553      data->word = inb_p(SMBHSTDAT0) + (inb_p(SMBHSTDAT1) << 8); 
    433554      break; 
    434     case I801_BLOCK_DATA: 
    435       data->block[0] = inb_p(SMBHSTDAT0); 
    436       i = inb_p(SMBHSTCNT); /* Reset SMBBLKDAT */ 
    437       for (i = 1; i <= data->block[0]; i++) 
    438         data->block[i] = inb_p(SMBBLKDAT); 
    439       break; 
    440555  } 
    441556  return 0; 
     
    449564void i801_dec(struct i2c_adapter *adapter) 
    450565{ 
    451  
    452566        MOD_DEC_USE_COUNT; 
    453567}