Changeset 43

Show
Ignore:
Timestamp:
12/07/98 00:03:46 (15 years ago)
Author:
frodo
Message:

SMBus emulation on real I2C adapters finished

Not tested, as I do not own such an adapter...

Block reading not implemented, as it seems impossible to do with the
currently available I2C primitives.

Location:
lm-sensors/trunk
Files:
5 modified

Legend:

Unmodified
Added
Removed
  • lm-sensors/trunk/TODO

    r36 r43  
    11Many, many things. Most notably: 
    22 
     3* Support 10-bit addresses. At this moment, they are supported nowhere  
    34* Change the i2c modules to keep the namespace clean (EXPORT_SYMBOL does not 
    45  work for us; many static declarations need to be added; better ask Simon 
  • lm-sensors/trunk/kernel/i2c-proc.c

    r38 r43  
    6262    /* name */          "bus", 
    6363    /* mode */          S_IRUGO | S_IXUGO | S_IFDIR, 
    64     /* nlink */         1,     /* Corrected by proc_register[_dynamic] */ 
     64    /* nlink */         2,     /* Corrected by proc_register[_dynamic] */ 
    6565    /* uid */           0, 
    6666    /* gid */           0, 
  • lm-sensors/trunk/kernel/smbus.c

    r41 r43  
    9494   
    9595/* Simulate a SMBus command using the i2c protocol  
    96    No checking of paramters is done! 
    97    For SMBUS_QUICK: Use addr, read_write  
    98    For SMBUS_BYTE: Use addr, read_write, command  
    99    ....  */ 
     96   No checking of paramters is done!  */ 
    10097s32 smbus_access_i2c(struct i2c_adapter * adapter, u8 addr, char read_write, 
    10198                     u8 command, int size, union smbus_data * data) 
    10299{ 
    103   /* For now */ 
    104   return -1; 
    105  
    106   /* So we need to generate a series of msgs  
    107   struct i2c_msg msg[2]; 
    108   char msgbuf0[2]; 
    109   char msgbuf1[32]; 
    110   msg[0].addr = addr; 
    111   msg[0].flags = read_write; 
    112   msg[0].len = 0; 
    113   msg[0].buf = msgbuf0; 
    114   WHATEVER */ 
     100  /* So we need to generate a series of msgs. In the case of writing, we 
     101     need to use only one message; when reading, we need two. We initialize 
     102     most things with sane defaults, to keep the code below somewhat 
     103     simpler. */ 
     104  char msgbuf0[33] = { command };  
     105  char msgbuf1[33]; 
     106  int num = read_write == SMBUS_READ?2:1; 
     107  struct i2c_msg msg[2] = { { addr, 0, 1, msgbuf0 },  
     108                            { addr, I2C_M_RD, 0, msgbuf1 } 
     109                          }; 
     110  int i; 
     111 
     112  switch(size) { 
     113  case SMBUS_QUICK: 
     114    msg[0].len = 0; 
     115    num = 1; /* Special case: The read/write field is used as data */ 
     116    break; 
     117  case SMBUS_BYTE: 
     118    if (read_write == SMBUS_READ) 
     119      /* Special case: only a read! */ 
     120      msg[0].flags = I2C_M_RD; 
     121    break; 
     122  case SMBUS_BYTE_DATA: 
     123    if (read_write == SMBUS_READ) 
     124      msg[1].len = 1; 
     125    else { 
     126      msg[0].len = 2; 
     127      msgbuf0[1] = data->byte; 
     128    } 
     129    break; 
     130  case SMBUS_WORD_DATA: 
     131    if (read_write == SMBUS_READ) 
     132      msg[1].len = 2; 
     133    else { 
     134      msg[0].len=3; 
     135      msgbuf0[1] = data->word & 0xff; 
     136      msgbuf0[2] = (data->word >> 8) & 0xff; 
     137    } 
     138    break; 
     139  case SMBUS_PROC_CALL: 
     140    num = 2; /* Special case */ 
     141    msg[0].len = 3; 
     142    msg[1].len = 2; 
     143    msgbuf0[1] = data->word & 0xff; 
     144    msgbuf0[2] = (data->word >> 8) & 0xff; 
     145    break; 
     146  case SMBUS_BLOCK_DATA: 
     147    if (read_write == SMBUS_READ) { 
     148      printk("smbus.o: Block read not supported under I2C emulation!\n"); 
     149      return -1; 
     150    } else { 
     151      msg[1].len = data->block[0] + 1; 
     152      if (msg[1].len > 32) { 
     153        printk("smbus.o: smbus_access called with invalid block write " 
     154               "size (%d)\n",msg[1].len); 
     155        return -1; 
     156      } 
     157      for (i = 1; i <= msg[1].len; i++) 
     158        msgbuf0[i] = data->block[1]; 
     159    } 
     160    break; 
     161  default: 
     162    printk("smbus.o: smbus_access called with invalid size (%d)\n",size); 
     163    return -1; 
     164  } 
     165     
     166  if (i2c_transfer(adapter, msg, num) < 0) 
     167    return -1; 
     168 
     169  if(read_write == SMBUS_READ) 
     170    switch(size) { 
     171    case SMBUS_BYTE: 
     172      data->byte = msgbuf0[0]; 
     173      break; 
     174    case SMBUS_BYTE_DATA: 
     175      data->byte = msgbuf1[0]; 
     176      break; 
     177    case SMBUS_WORD_DATA:  
     178    case SMBUS_PROC_CALL: 
     179      data->word = msgbuf1[0] + (msgbuf1[1] << 8); 
     180      break; 
     181  } 
     182  return 0; 
    115183} 
    116184 
  • lm-sensors/trunk/src/i2c-proc.c

    r38 r43  
    6262    /* name */          "bus", 
    6363    /* mode */          S_IRUGO | S_IXUGO | S_IFDIR, 
    64     /* nlink */         1,     /* Corrected by proc_register[_dynamic] */ 
     64    /* nlink */         2,     /* Corrected by proc_register[_dynamic] */ 
    6565    /* uid */           0, 
    6666    /* gid */           0, 
  • lm-sensors/trunk/src/smbus.c

    r41 r43  
    9494   
    9595/* Simulate a SMBus command using the i2c protocol  
    96    No checking of paramters is done! 
    97    For SMBUS_QUICK: Use addr, read_write  
    98    For SMBUS_BYTE: Use addr, read_write, command  
    99    ....  */ 
     96   No checking of paramters is done!  */ 
    10097s32 smbus_access_i2c(struct i2c_adapter * adapter, u8 addr, char read_write, 
    10198                     u8 command, int size, union smbus_data * data) 
    10299{ 
    103   /* For now */ 
    104   return -1; 
    105  
    106   /* So we need to generate a series of msgs  
    107   struct i2c_msg msg[2]; 
    108   char msgbuf0[2]; 
    109   char msgbuf1[32]; 
    110   msg[0].addr = addr; 
    111   msg[0].flags = read_write; 
    112   msg[0].len = 0; 
    113   msg[0].buf = msgbuf0; 
    114   WHATEVER */ 
     100  /* So we need to generate a series of msgs. In the case of writing, we 
     101     need to use only one message; when reading, we need two. We initialize 
     102     most things with sane defaults, to keep the code below somewhat 
     103     simpler. */ 
     104  char msgbuf0[33] = { command };  
     105  char msgbuf1[33]; 
     106  int num = read_write == SMBUS_READ?2:1; 
     107  struct i2c_msg msg[2] = { { addr, 0, 1, msgbuf0 },  
     108                            { addr, I2C_M_RD, 0, msgbuf1 } 
     109                          }; 
     110  int i; 
     111 
     112  switch(size) { 
     113  case SMBUS_QUICK: 
     114    msg[0].len = 0; 
     115    num = 1; /* Special case: The read/write field is used as data */ 
     116    break; 
     117  case SMBUS_BYTE: 
     118    if (read_write == SMBUS_READ) 
     119      /* Special case: only a read! */ 
     120      msg[0].flags = I2C_M_RD; 
     121    break; 
     122  case SMBUS_BYTE_DATA: 
     123    if (read_write == SMBUS_READ) 
     124      msg[1].len = 1; 
     125    else { 
     126      msg[0].len = 2; 
     127      msgbuf0[1] = data->byte; 
     128    } 
     129    break; 
     130  case SMBUS_WORD_DATA: 
     131    if (read_write == SMBUS_READ) 
     132      msg[1].len = 2; 
     133    else { 
     134      msg[0].len=3; 
     135      msgbuf0[1] = data->word & 0xff; 
     136      msgbuf0[2] = (data->word >> 8) & 0xff; 
     137    } 
     138    break; 
     139  case SMBUS_PROC_CALL: 
     140    num = 2; /* Special case */ 
     141    msg[0].len = 3; 
     142    msg[1].len = 2; 
     143    msgbuf0[1] = data->word & 0xff; 
     144    msgbuf0[2] = (data->word >> 8) & 0xff; 
     145    break; 
     146  case SMBUS_BLOCK_DATA: 
     147    if (read_write == SMBUS_READ) { 
     148      printk("smbus.o: Block read not supported under I2C emulation!\n"); 
     149      return -1; 
     150    } else { 
     151      msg[1].len = data->block[0] + 1; 
     152      if (msg[1].len > 32) { 
     153        printk("smbus.o: smbus_access called with invalid block write " 
     154               "size (%d)\n",msg[1].len); 
     155        return -1; 
     156      } 
     157      for (i = 1; i <= msg[1].len; i++) 
     158        msgbuf0[i] = data->block[1]; 
     159    } 
     160    break; 
     161  default: 
     162    printk("smbus.o: smbus_access called with invalid size (%d)\n",size); 
     163    return -1; 
     164  } 
     165     
     166  if (i2c_transfer(adapter, msg, num) < 0) 
     167    return -1; 
     168 
     169  if(read_write == SMBUS_READ) 
     170    switch(size) { 
     171    case SMBUS_BYTE: 
     172      data->byte = msgbuf0[0]; 
     173      break; 
     174    case SMBUS_BYTE_DATA: 
     175      data->byte = msgbuf1[0]; 
     176      break; 
     177    case SMBUS_WORD_DATA:  
     178    case SMBUS_PROC_CALL: 
     179      data->word = msgbuf1[0] + (msgbuf1[1] << 8); 
     180      break; 
     181  } 
     182  return 0; 
    115183} 
    116184