Loading drivers/i2c/busses/i2c-bfin-twi.c +114 −71 Original line number Diff line number Diff line Loading @@ -39,9 +39,10 @@ #define POLL_TIMEOUT (2 * HZ) /* SMBus mode*/ #define TWI_I2C_MODE_STANDARD 0x01 #define TWI_I2C_MODE_STANDARDSUB 0x02 #define TWI_I2C_MODE_COMBINED 0x04 #define TWI_I2C_MODE_STANDARD 1 #define TWI_I2C_MODE_STANDARDSUB 2 #define TWI_I2C_MODE_COMBINED 3 #define TWI_I2C_MODE_REPEAT 4 struct bfin_twi_iface { int irq; Loading @@ -58,6 +59,9 @@ struct bfin_twi_iface { struct timer_list timeout_timer; struct i2c_adapter adap; struct completion complete; struct i2c_msg *pmsg; int msg_num; int cur_msg; }; static struct bfin_twi_iface twi_iface; Loading @@ -76,12 +80,16 @@ static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface) /* start receive immediately after complete sending in * combine mode. */ else if (iface->cur_mode == TWI_I2C_MODE_COMBINED) { else if (iface->cur_mode == TWI_I2C_MODE_COMBINED) bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | MDIR | RSTART); } else if (iface->manual_stop) else if (iface->manual_stop) bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | STOP); else if (iface->cur_mode == TWI_I2C_MODE_REPEAT && iface->cur_msg+1 < iface->msg_num) bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | RSTART); SSYNC(); /* Clear status */ bfin_write_TWI_INT_STAT(XMTSERV); Loading @@ -108,6 +116,11 @@ static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface) bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | STOP); SSYNC(); } else if (iface->cur_mode == TWI_I2C_MODE_REPEAT && iface->cur_msg+1 < iface->msg_num) { bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | RSTART); SSYNC(); } /* Clear interrupt source */ bfin_write_TWI_INT_STAT(RCVSERV); Loading @@ -119,7 +132,7 @@ static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface) bfin_write_TWI_MASTER_STAT(0x3e); bfin_write_TWI_MASTER_CTL(0); SSYNC(); iface->result = -1; iface->result = -EIO; /* if both err and complete int stats are set, return proper * results. */ Loading Loading @@ -170,6 +183,42 @@ static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface) bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | MEN | MDIR); SSYNC(); } else if (iface->cur_mode == TWI_I2C_MODE_REPEAT && iface->cur_msg+1 < iface->msg_num) { iface->cur_msg++; iface->transPtr = iface->pmsg[iface->cur_msg].buf; iface->writeNum = iface->readNum = iface->pmsg[iface->cur_msg].len; /* Set Transmit device address */ bfin_write_TWI_MASTER_ADDR( iface->pmsg[iface->cur_msg].addr); if (iface->pmsg[iface->cur_msg].flags & I2C_M_RD) iface->read_write = I2C_SMBUS_READ; else { iface->read_write = I2C_SMBUS_WRITE; /* Transmit first data */ if (iface->writeNum > 0) { bfin_write_TWI_XMT_DATA8( *(iface->transPtr++)); iface->writeNum--; SSYNC(); } } if (iface->pmsg[iface->cur_msg].len <= 255) bfin_write_TWI_MASTER_CTL( iface->pmsg[iface->cur_msg].len << 6); else { bfin_write_TWI_MASTER_CTL(0xff << 6); iface->manual_stop = 1; } /* remove restart bit and enable master receive */ bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() & ~RSTART); bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | MEN | ((iface->read_write == I2C_SMBUS_READ) ? MDIR : 0)); SSYNC(); } else { iface->result = 1; bfin_write_TWI_INT_MASK(0); Loading Loading @@ -221,7 +270,6 @@ static int bfin_twi_master_xfer(struct i2c_adapter *adap, { struct bfin_twi_iface *iface = adap->algo_data; struct i2c_msg *pmsg; int i, ret; int rc = 0; if (!(bfin_read_TWI_CONTROL() & TWI_ENA)) Loading @@ -231,17 +279,17 @@ static int bfin_twi_master_xfer(struct i2c_adapter *adap, yield(); } ret = 0; for (i = 0; rc >= 0 && i < num; i++) { pmsg = &msgs[i]; iface->pmsg = msgs; iface->msg_num = num; iface->cur_msg = 0; pmsg = &msgs[0]; if (pmsg->flags & I2C_M_TEN) { dev_err(&(adap->dev), "i2c-bfin-twi: 10 bits addr " "not supported !\n"); rc = -EINVAL; break; dev_err(&adap->dev, "10 bits addr not supported!\n"); return -EINVAL; } iface->cur_mode = TWI_I2C_MODE_STANDARD; iface->cur_mode = TWI_I2C_MODE_REPEAT; iface->manual_stop = 0; iface->transPtr = pmsg->buf; iface->writeNum = iface->readNum = pmsg->len; Loading Loading @@ -274,18 +322,15 @@ static int bfin_twi_master_xfer(struct i2c_adapter *adap, bfin_write_TWI_INT_STAT(MERR | MCOMP | XMTSERV | RCVSERV); /* Interrupt mask . Enable XMT, RCV interrupt */ bfin_write_TWI_INT_MASK(MCOMP | MERR | ((iface->read_write == I2C_SMBUS_READ)? RCVSERV : XMTSERV)); bfin_write_TWI_INT_MASK(MCOMP | MERR | RCVSERV | XMTSERV); SSYNC(); if (pmsg->len > 0 && pmsg->len <= 255) if (pmsg->len <= 255) bfin_write_TWI_MASTER_CTL(pmsg->len << 6); else if (pmsg->len > 255) { else { bfin_write_TWI_MASTER_CTL(0xff << 6); iface->manual_stop = 1; } else break; } iface->timeout_timer.expires = jiffies + POLL_TIMEOUT; add_timer(&iface->timeout_timer); Loading @@ -299,13 +344,11 @@ static int bfin_twi_master_xfer(struct i2c_adapter *adap, wait_for_completion(&iface->complete); rc = iface->result; if (rc == 1) ret++; else if (rc == -1) break; } return ret; if (rc == 1) return num; else return rc; } /* Loading Loading
drivers/i2c/busses/i2c-bfin-twi.c +114 −71 Original line number Diff line number Diff line Loading @@ -39,9 +39,10 @@ #define POLL_TIMEOUT (2 * HZ) /* SMBus mode*/ #define TWI_I2C_MODE_STANDARD 0x01 #define TWI_I2C_MODE_STANDARDSUB 0x02 #define TWI_I2C_MODE_COMBINED 0x04 #define TWI_I2C_MODE_STANDARD 1 #define TWI_I2C_MODE_STANDARDSUB 2 #define TWI_I2C_MODE_COMBINED 3 #define TWI_I2C_MODE_REPEAT 4 struct bfin_twi_iface { int irq; Loading @@ -58,6 +59,9 @@ struct bfin_twi_iface { struct timer_list timeout_timer; struct i2c_adapter adap; struct completion complete; struct i2c_msg *pmsg; int msg_num; int cur_msg; }; static struct bfin_twi_iface twi_iface; Loading @@ -76,12 +80,16 @@ static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface) /* start receive immediately after complete sending in * combine mode. */ else if (iface->cur_mode == TWI_I2C_MODE_COMBINED) { else if (iface->cur_mode == TWI_I2C_MODE_COMBINED) bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | MDIR | RSTART); } else if (iface->manual_stop) else if (iface->manual_stop) bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | STOP); else if (iface->cur_mode == TWI_I2C_MODE_REPEAT && iface->cur_msg+1 < iface->msg_num) bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | RSTART); SSYNC(); /* Clear status */ bfin_write_TWI_INT_STAT(XMTSERV); Loading @@ -108,6 +116,11 @@ static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface) bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | STOP); SSYNC(); } else if (iface->cur_mode == TWI_I2C_MODE_REPEAT && iface->cur_msg+1 < iface->msg_num) { bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | RSTART); SSYNC(); } /* Clear interrupt source */ bfin_write_TWI_INT_STAT(RCVSERV); Loading @@ -119,7 +132,7 @@ static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface) bfin_write_TWI_MASTER_STAT(0x3e); bfin_write_TWI_MASTER_CTL(0); SSYNC(); iface->result = -1; iface->result = -EIO; /* if both err and complete int stats are set, return proper * results. */ Loading Loading @@ -170,6 +183,42 @@ static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface) bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | MEN | MDIR); SSYNC(); } else if (iface->cur_mode == TWI_I2C_MODE_REPEAT && iface->cur_msg+1 < iface->msg_num) { iface->cur_msg++; iface->transPtr = iface->pmsg[iface->cur_msg].buf; iface->writeNum = iface->readNum = iface->pmsg[iface->cur_msg].len; /* Set Transmit device address */ bfin_write_TWI_MASTER_ADDR( iface->pmsg[iface->cur_msg].addr); if (iface->pmsg[iface->cur_msg].flags & I2C_M_RD) iface->read_write = I2C_SMBUS_READ; else { iface->read_write = I2C_SMBUS_WRITE; /* Transmit first data */ if (iface->writeNum > 0) { bfin_write_TWI_XMT_DATA8( *(iface->transPtr++)); iface->writeNum--; SSYNC(); } } if (iface->pmsg[iface->cur_msg].len <= 255) bfin_write_TWI_MASTER_CTL( iface->pmsg[iface->cur_msg].len << 6); else { bfin_write_TWI_MASTER_CTL(0xff << 6); iface->manual_stop = 1; } /* remove restart bit and enable master receive */ bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() & ~RSTART); bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | MEN | ((iface->read_write == I2C_SMBUS_READ) ? MDIR : 0)); SSYNC(); } else { iface->result = 1; bfin_write_TWI_INT_MASK(0); Loading Loading @@ -221,7 +270,6 @@ static int bfin_twi_master_xfer(struct i2c_adapter *adap, { struct bfin_twi_iface *iface = adap->algo_data; struct i2c_msg *pmsg; int i, ret; int rc = 0; if (!(bfin_read_TWI_CONTROL() & TWI_ENA)) Loading @@ -231,17 +279,17 @@ static int bfin_twi_master_xfer(struct i2c_adapter *adap, yield(); } ret = 0; for (i = 0; rc >= 0 && i < num; i++) { pmsg = &msgs[i]; iface->pmsg = msgs; iface->msg_num = num; iface->cur_msg = 0; pmsg = &msgs[0]; if (pmsg->flags & I2C_M_TEN) { dev_err(&(adap->dev), "i2c-bfin-twi: 10 bits addr " "not supported !\n"); rc = -EINVAL; break; dev_err(&adap->dev, "10 bits addr not supported!\n"); return -EINVAL; } iface->cur_mode = TWI_I2C_MODE_STANDARD; iface->cur_mode = TWI_I2C_MODE_REPEAT; iface->manual_stop = 0; iface->transPtr = pmsg->buf; iface->writeNum = iface->readNum = pmsg->len; Loading Loading @@ -274,18 +322,15 @@ static int bfin_twi_master_xfer(struct i2c_adapter *adap, bfin_write_TWI_INT_STAT(MERR | MCOMP | XMTSERV | RCVSERV); /* Interrupt mask . Enable XMT, RCV interrupt */ bfin_write_TWI_INT_MASK(MCOMP | MERR | ((iface->read_write == I2C_SMBUS_READ)? RCVSERV : XMTSERV)); bfin_write_TWI_INT_MASK(MCOMP | MERR | RCVSERV | XMTSERV); SSYNC(); if (pmsg->len > 0 && pmsg->len <= 255) if (pmsg->len <= 255) bfin_write_TWI_MASTER_CTL(pmsg->len << 6); else if (pmsg->len > 255) { else { bfin_write_TWI_MASTER_CTL(0xff << 6); iface->manual_stop = 1; } else break; } iface->timeout_timer.expires = jiffies + POLL_TIMEOUT; add_timer(&iface->timeout_timer); Loading @@ -299,13 +344,11 @@ static int bfin_twi_master_xfer(struct i2c_adapter *adap, wait_for_completion(&iface->complete); rc = iface->result; if (rc == 1) ret++; else if (rc == -1) break; } return ret; if (rc == 1) return num; else return rc; } /* Loading