static s32 ali1563_access(struct i2c_adapter * a, u16 addr, unsigned short flags, char rw, u8 cmd, int size, union i2c_smbus_data * data) { int error = 0; int timeout; u32 reg; for (timeout = ALI1563_MAX_TIMEOUT; timeout; timeout--) { if (!(reg = inb_p(SMB_HST_STS) & HST_STS_BUSY)) break; } if (!timeout) dev_warn(&a->dev,"SMBus not idle. HST_STS = %02x\n",reg); outb_p(0xff,SMB_HST_STS); /* Map the size to what the chip understands */ switch (size) { case I2C_SMBUS_QUICK: size = HST_CNTL2_QUICK; break; case I2C_SMBUS_BYTE: size = HST_CNTL2_BYTE; break; case I2C_SMBUS_BYTE_DATA: size = HST_CNTL2_BYTE_DATA; break; case I2C_SMBUS_WORD_DATA: size = HST_CNTL2_WORD_DATA; break; case I2C_SMBUS_BLOCK_DATA: size = HST_CNTL2_BLOCK; break; default: dev_warn(&a->dev, "Unsupported transaction %d\n", size); error = -EOPNOTSUPP; goto Done; } outb_p(((addr & 0x7f) << 1) | (rw & 0x01), SMB_HST_ADD); outb_p((inb_p(SMB_HST_CNTL2) & ~HST_CNTL2_SIZEMASK) | (size << 3), SMB_HST_CNTL2); /* Write the command register */ switch(size) { case HST_CNTL2_BYTE: if (rw== I2C_SMBUS_WRITE) /* Beware it uses DAT0 register and not CMD! */ outb_p(cmd, SMB_HST_DAT0); break; case HST_CNTL2_BYTE_DATA: outb_p(cmd, SMB_HST_CMD); if (rw == I2C_SMBUS_WRITE) outb_p(data->byte, SMB_HST_DAT0); break; case HST_CNTL2_WORD_DATA: outb_p(cmd, SMB_HST_CMD); if (rw == I2C_SMBUS_WRITE) { outb_p(data->word & 0xff, SMB_HST_DAT0); outb_p((data->word & 0xff00) >> 8, SMB_HST_DAT1); } break; case HST_CNTL2_BLOCK: outb_p(cmd, SMB_HST_CMD); error = ali1563_block(a,data,rw); goto Done; }
static s32 ali1563_access(struct i2c_adapter * a, u16 addr, unsigned short flags, char rw, u8 cmd, int size, union i2c_smbus_data * data) { int error = 0; int timeout; u32 reg; for (timeout = ALI1563_MAX_TIMEOUT; timeout; timeout--) { if (!(reg = inb_p(SMB_HST_STS) & HST_STS_BUSY)) break; } if (!timeout) printk(KERN_WARNING "ali1563: SMBus not idle. HST_STS = %02x\n",reg); outb_p(0xff,SMB_HST_STS); /* Map the size to what the chip understands */ switch (size) { case I2C_SMBUS_PROC_CALL: printk(KERN_ERR "ali1563: I2C_SMBUS_PROC_CALL not supported!\n"); error = -EINVAL; break; case I2C_SMBUS_QUICK: size = HST_CNTL2_QUICK; break; case I2C_SMBUS_BYTE: size = HST_CNTL2_BYTE; break; case I2C_SMBUS_BYTE_DATA: size = HST_CNTL2_BYTE_DATA; break; case I2C_SMBUS_WORD_DATA: size = HST_CNTL2_WORD_DATA; break; case I2C_SMBUS_BLOCK_DATA: size = HST_CNTL2_BLOCK; break; } outb_p(((addr & 0x7f) << 1) | (rw & 0x01), SMB_HST_ADD); outb_p( (inb_p(SMB_HST_CNTL2)&~HST_CNTL2_SIZEMASK) | (size << 3), SMB_HST_CNTL2); /* Write the command register */ switch(size) { case HST_CNTL2_BYTE: if (rw== I2C_SMBUS_WRITE) /* outb_p(cmd, SMB_HST_CMD); */ outb_p(cmd, SMB_HST_DAT0); /* modify by Rudolf */ break; case HST_CNTL2_BYTE_DATA: outb_p(cmd, SMB_HST_CMD); if (rw == I2C_SMBUS_WRITE) outb_p(data->byte, SMB_HST_DAT0); break; case HST_CNTL2_WORD_DATA: outb_p(cmd, SMB_HST_CMD); if (rw == I2C_SMBUS_WRITE) { outb_p(data->word & 0xff, SMB_HST_DAT0); outb_p((data->word & 0xff00) >> 8, SMB_HST_DAT1); } break; case HST_CNTL2_BLOCK: outb_p(cmd, SMB_HST_CMD); error = ali1563_block(a,data,rw); goto Done; }