diff options
Diffstat (limited to 'drivers/i2c/busses/i2c-bfin-twi.c')
-rw-r--r-- | drivers/i2c/busses/i2c-bfin-twi.c | 25 |
1 files changed, 14 insertions, 11 deletions
diff --git a/drivers/i2c/busses/i2c-bfin-twi.c b/drivers/i2c/busses/i2c-bfin-twi.c index 71be486a224d..2288e1bcf016 100644 --- a/drivers/i2c/busses/i2c-bfin-twi.c +++ b/drivers/i2c/busses/i2c-bfin-twi.c | |||
@@ -99,7 +99,7 @@ static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface, | |||
99 | */ | 99 | */ |
100 | else if (iface->cur_mode == TWI_I2C_MODE_COMBINED) | 100 | else if (iface->cur_mode == TWI_I2C_MODE_COMBINED) |
101 | write_MASTER_CTL(iface, | 101 | write_MASTER_CTL(iface, |
102 | read_MASTER_CTL(iface) | MDIR | RSTART); | 102 | read_MASTER_CTL(iface) | MDIR); |
103 | else if (iface->manual_stop) | 103 | else if (iface->manual_stop) |
104 | write_MASTER_CTL(iface, | 104 | write_MASTER_CTL(iface, |
105 | read_MASTER_CTL(iface) | STOP); | 105 | read_MASTER_CTL(iface) | STOP); |
@@ -107,10 +107,10 @@ static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface, | |||
107 | iface->cur_msg + 1 < iface->msg_num) { | 107 | iface->cur_msg + 1 < iface->msg_num) { |
108 | if (iface->pmsg[iface->cur_msg + 1].flags & I2C_M_RD) | 108 | if (iface->pmsg[iface->cur_msg + 1].flags & I2C_M_RD) |
109 | write_MASTER_CTL(iface, | 109 | write_MASTER_CTL(iface, |
110 | read_MASTER_CTL(iface) | RSTART | MDIR); | 110 | read_MASTER_CTL(iface) | MDIR); |
111 | else | 111 | else |
112 | write_MASTER_CTL(iface, | 112 | write_MASTER_CTL(iface, |
113 | (read_MASTER_CTL(iface) | RSTART) & ~MDIR); | 113 | read_MASTER_CTL(iface) & ~MDIR); |
114 | } | 114 | } |
115 | } | 115 | } |
116 | if (twi_int_status & RCVSERV) { | 116 | if (twi_int_status & RCVSERV) { |
@@ -144,10 +144,10 @@ static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface, | |||
144 | iface->cur_msg + 1 < iface->msg_num) { | 144 | iface->cur_msg + 1 < iface->msg_num) { |
145 | if (iface->pmsg[iface->cur_msg + 1].flags & I2C_M_RD) | 145 | if (iface->pmsg[iface->cur_msg + 1].flags & I2C_M_RD) |
146 | write_MASTER_CTL(iface, | 146 | write_MASTER_CTL(iface, |
147 | read_MASTER_CTL(iface) | RSTART | MDIR); | 147 | read_MASTER_CTL(iface) | MDIR); |
148 | else | 148 | else |
149 | write_MASTER_CTL(iface, | 149 | write_MASTER_CTL(iface, |
150 | (read_MASTER_CTL(iface) | RSTART) & ~MDIR); | 150 | read_MASTER_CTL(iface) & ~MDIR); |
151 | } | 151 | } |
152 | } | 152 | } |
153 | } | 153 | } |
@@ -230,7 +230,7 @@ static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface, | |||
230 | write_MASTER_CTL(iface, | 230 | write_MASTER_CTL(iface, |
231 | read_MASTER_CTL(iface) & ~RSTART); | 231 | read_MASTER_CTL(iface) & ~RSTART); |
232 | } else if (iface->cur_mode == TWI_I2C_MODE_REPEAT && | 232 | } else if (iface->cur_mode == TWI_I2C_MODE_REPEAT && |
233 | iface->cur_msg+1 < iface->msg_num) { | 233 | iface->cur_msg + 1 < iface->msg_num) { |
234 | iface->cur_msg++; | 234 | iface->cur_msg++; |
235 | iface->transPtr = iface->pmsg[iface->cur_msg].buf; | 235 | iface->transPtr = iface->pmsg[iface->cur_msg].buf; |
236 | iface->writeNum = iface->readNum = | 236 | iface->writeNum = iface->readNum = |
@@ -262,9 +262,10 @@ static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface, | |||
262 | (0xff << 6))); | 262 | (0xff << 6))); |
263 | iface->manual_stop = 1; | 263 | iface->manual_stop = 1; |
264 | } | 264 | } |
265 | /* remove restart bit and enable master receive */ | 265 | /* remove restart bit before last message */ |
266 | write_MASTER_CTL(iface, | 266 | if (iface->cur_msg + 1 == iface->msg_num) |
267 | read_MASTER_CTL(iface) & ~RSTART); | 267 | write_MASTER_CTL(iface, |
268 | read_MASTER_CTL(iface) & ~RSTART); | ||
268 | } else { | 269 | } else { |
269 | iface->result = 1; | 270 | iface->result = 1; |
270 | write_INT_MASK(iface, 0); | 271 | write_INT_MASK(iface, 0); |
@@ -321,7 +322,8 @@ static int bfin_twi_do_master_xfer(struct i2c_adapter *adap, | |||
321 | return -EINVAL; | 322 | return -EINVAL; |
322 | } | 323 | } |
323 | 324 | ||
324 | iface->cur_mode = TWI_I2C_MODE_REPEAT; | 325 | if (iface->msg_num > 1) |
326 | iface->cur_mode = TWI_I2C_MODE_REPEAT; | ||
325 | iface->manual_stop = 0; | 327 | iface->manual_stop = 0; |
326 | iface->transPtr = pmsg->buf; | 328 | iface->transPtr = pmsg->buf; |
327 | iface->writeNum = iface->readNum = pmsg->len; | 329 | iface->writeNum = iface->readNum = pmsg->len; |
@@ -366,6 +368,7 @@ static int bfin_twi_do_master_xfer(struct i2c_adapter *adap, | |||
366 | 368 | ||
367 | /* Master enable */ | 369 | /* Master enable */ |
368 | write_MASTER_CTL(iface, read_MASTER_CTL(iface) | MEN | | 370 | write_MASTER_CTL(iface, read_MASTER_CTL(iface) | MEN | |
371 | (iface->msg_num > 1 ? RSTART : 0) | | ||
369 | ((iface->read_write == I2C_SMBUS_READ) ? MDIR : 0) | | 372 | ((iface->read_write == I2C_SMBUS_READ) ? MDIR : 0) | |
370 | ((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ > 100) ? FAST : 0)); | 373 | ((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ > 100) ? FAST : 0)); |
371 | SSYNC(); | 374 | SSYNC(); |
@@ -530,7 +533,7 @@ int bfin_twi_do_smbus_xfer(struct i2c_adapter *adap, u16 addr, | |||
530 | else | 533 | else |
531 | write_MASTER_CTL(iface, 0x1 << 6); | 534 | write_MASTER_CTL(iface, 0x1 << 6); |
532 | /* Master enable */ | 535 | /* Master enable */ |
533 | write_MASTER_CTL(iface, read_MASTER_CTL(iface) | MEN | | 536 | write_MASTER_CTL(iface, read_MASTER_CTL(iface) | MEN | RSTART | |
534 | ((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ>100) ? FAST : 0)); | 537 | ((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ>100) ? FAST : 0)); |
535 | break; | 538 | break; |
536 | default: | 539 | default: |