i2c-omap: always send stop after nack
Subsystems (4)
PATCH 1/1 i2c-omap: always send stop after nack
Hi Vikram,
On a OMAP4460, i2c-bus-3:
A driver (lm75) is causing many 'timeout waiting for bus ready' errors. SDA remains high (as it should), but SCL remains low after a NACK. The bus becomes _unusable for other clients_.
While probing, "lm75" writes a command, followed by a read + stop, but the write command is NACK'd. The chip does accept other writes/reads, it just refuses to ack invalid commands.
Can you tell me if the patch below would make any sense? Or is it the responsibility of the client to reset the i2c_smbus?
In case of M_IGNORE_NAK there is no problem, a STOP will follow after the last command.
Thanks, Hein
--- drivers/i2c/busses/i2c-omap.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-)
drivers/i2c/busses/i2c-omap.c +3 -5
@@ -615,11 +615,9 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,if (dev->cmd_err &OMAP_I2C_STAT_NACK ) {if (msg->flags &I2C_M_IGNORE_NAK )return 0 ; -if (stop) { - w =omap_i2c_read_reg (dev,OMAP_I2C_CON_REG ); - w |=OMAP_I2C_CON_STP ; -omap_i2c_write_reg (dev,OMAP_I2C_CON_REG , w); - } + w =omap_i2c_read_reg (dev,OMAP_I2C_CON_REG ); + w |=OMAP_I2C_CON_STP ; +omap_i2c_write_reg (dev,OMAP_I2C_CON_REG , w);return -EREMOTEIO ; }return -EIO ;
Signature · 1 line
1.7.9.5
Hi,
Quoted 8 lines · Hein Tibosch
Hi Vikram,
On a OMAP4460, i2c-bus-3:
A driver (lm75) is causing many 'timeout waiting for bus ready' errors. SDA remains high (as it should), but SCL remains low after a NACK. The bus becomes
_unusablefor otherclients_.
Quoted 6 lines
While probing, "lm75" writes a command, followed by a read + stop, but the write command is NACK'd. The chip does accept other writes/reads, it just refuses to ack invalid commands.
Can you tell me if the patch below would make any sense? Or is it the responsibility of the client to reset the
i2c_smbus?
patch below breaks repeated start.
Signature · 1 line
balbi
Quoted 11 lines · Felipe Balbi
Hi,
Quoted 8 lines · Hein Tibosch
Hi Vikram,
On a OMAP4460, i2c-bus-3:
A driver (lm75) is causing many 'timeout waiting for bus ready' errors. SDA remains high (as it should), but SCL remains low after a NACK. The bus becomes
_unusablefor otherclients_.
Quoted 7 lines
Quoted 6 lines
While probing, "lm75" writes a command, followed by a read + stop, but the write command is NACK'd. The chip does accept other writes/reads, it just refuses to ack invalid commands.
Can you tell me if the patch below would make any sense? Or is it the responsibility of the client to reset the
i2c_smbus?patch below breaks repeated start.
Hi,
No, after the NACK, no more commands are being processed, including a repeated start. omap_i2c_xfer() returns -EREMOTEIO without ever freeing the bus.
The bus is left in an impossible state with SCL constantly low and all next commands (to different chips) will therefore get a -ETIMEDOUT
With this patch, the bus will become idle again and new commands can be processed normally
Hein
Hi,
Quoted 25 lines · Hein Tibosch
Quoted 11 lines · Felipe Balbi
Hi,
Quoted 8 lines · Hein Tibosch
Hi Vikram,
On a OMAP4460, i2c-bus-3:
A driver (lm75) is causing many 'timeout waiting for bus ready' errors. SDA remains high (as it should), but SCL remains low after a NACK. The bus becomes
_unusablefor otherclients_.Quoted 7 lines
Quoted 6 lines
While probing, "lm75" writes a command, followed by a read + stop, but the write command is NACK'd. The chip does accept other writes/reads, it just refuses to ack invalid commands.
Can you tell me if the patch below would make any sense? Or is it the responsibility of the client to reset the
i2c_smbus?patch below breaks repeated start.
Hi,
No, after the NACK, no more commands are being processed, including a repeated start.
omap_i2c_xfer()returns-EREMOTEIOwithout ever freeing the bus.
Quoted 6 lines
The bus is left in an impossible state with SCL constantly low and all next commands (to different chips) will therefore get a
-ETIMEDOUTWith this patch, the bus will become idle again and new commands can be processed normally
but you mentioned that if you have IGNORE_NAK set, everything is fine, since lm75 will get a return value of 0 and things will work just fine, right ?
Also, you also said that the chip 'refuses to ack invalid commands', why are you sending invalid commands to start with ? This could be a bug in i2c-omap.c, sure, but let's try to figure out why IGNORE_NAK helps and why is lm75 driver sending invalid commands.
Signature · 1 line
balbi
Hi Hein, Felipe
Quoted 22 lines · Felipe Balbi
Hi,
Quoted 19 lines · Hein Tibosch
Quoted 18 lines · Felipe Balbi
Hi,
Quoted 8 lines · Hein Tibosch
Hi Vikram,
On a OMAP4460, i2c-bus-3:
A driver (lm75) is causing many 'timeout waiting for bus ready' errors. SDA remains high (as it should), but SCL remains low after a NACK. The bus becomes
_unusablefor otherclients_.Quoted 6 lines
While probing, "lm75" writes a command, followed by a read + stop, but the write command is NACK'd. The chip does accept other writes/reads, it just refuses to ack invalid commands.
Can you tell me if the patch below would make any sense? Or is it the responsibility of the client to reset the
i2c_smbus?patch below breaks repeated start.
Felipe, I'd very appreciate if you'd be able to provide the use case which will fail with such solution?
Quoted 6 lines
Quoted 6 lines
Hi,
No, after the NACK, no more commands are being processed, including a repeated start.
omap_i2c_xfer()returns-EREMOTEIOwithout ever freeing the bus.
Quoted 6 lines
Quoted 6 lines
The bus is left in an impossible state with SCL constantly low and all next commands (to different chips) will therefore get a
-ETIMEDOUTWith this patch, the bus will become idle again and new commands can be processed normally
I think, this is valid fix, but it was done here already:)
http://patchwork.ozlabs.org/patch/249790/
"i2c: omap: query STP always when NACK is received"
And nacked in the same way :(
But! I've back-ported my patch on TI Android product kernel 3.4, did sanity test and I didn't see any issues with my patch :))
Quoted 10 lines
but you mentioned that if you have
IGNORE_NAKset, everything is fine, since lm75 will get a return value of 0 and things will work just fine, right ?Also, you also said that the chip 'refuses to ack invalid commands', why are you sending invalid commands to start with ? This could be a bug in
i2c-omap.c, sure, but let's try to figure out whyIGNORE_NAKhelps and why is lm75 driver sending invalid commands.
The problem is, that lm75 device is SmBus compatible and its driver has .detect() function implemented. During detection it tries to scan some registers which might be not present in current device - in my case it's tmp105.
For example to read regA in tmp105 following is done:
1) do write in "Index" register (val RegA index) (I2C 1st message)
2) do read (I2C 2d message)
the message 1 is Nacked by device in case if register index is wrong, but i2c-omap don't send NACK (or STP). As result, bus stack in Bus Busy state.
For SMBus devices the specification states (http://smbus.org/specs/)
"4.2.Acknowledge (ACK) and not acknowledge (NACK)":
- "The slave device detects an invalid command or invalid data. In this case the slave device must not acknowledge the received byte. The master upon detection of this condition must generate a STOP condition and retry the transaction"
Regards,
-grygorii
Hi,
Quoted 10 lines · Grygorii Strashko
Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
On a OMAP4460, i2c-bus-3:
A driver (lm75) is causing many 'timeout waiting for bus ready' errors. SDA remains high (as it should), but SCL remains low after a NACK. The bus becomes
_unusablefor otherclients_.While probing, "lm75" writes a command, followed by a read + stop, but the write command is NACK'd. The chip does accept other writes/reads, it just refuses to ack invalid commands.
Quoted 5 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 2 lines
Can you tell me if the patch below would make any sense? Or is it the responsibility of the client to reset the
i2c_smbus?patch below breaks repeated start.
Felipe, I'd very appreciate if you'd be able to provide the use case which will fail with such solution?
can't you see how this would fail ?
assume omap_i2c_xfer() is called with its last argument (num) being greater than one and you get the NAK before the last transfer.
Will you not be breaking a possible repeated start for the following transfer ?
Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
No, after the NACK, no more commands are being processed, including a repeated start.
omap_i2c_xfer()returns-EREMOTEIOwithout ever freeing the bus.The bus is left in an impossible state with SCL constantly low and all next commands (to different chips) will therefore get a
-ETIMEDOUTWith this patch, the bus will become idle again and new commands can be processed normally
Quoted 7 lines
I think, this is valid fix, but it was done here already:)
http://patchwork.ozlabs.org/patch/249790/
"i2c: omap: query STP always when NACK is received"And nacked in the same way :(
But! I've back-ported my patch on TI Android product kernel 3.4, did sanity test and I didn't see any issues with my patch :))
that's because you don't care about repeated start, but that's a valid bus signal which needs to be supported.
Quoted 15 lines
Quoted 9 lines
but you mentioned that if you have
IGNORE_NAKset, everything is fine, since lm75 will get a return value of 0 and things will work just fine, right ?Also, you also said that the chip 'refuses to ack invalid commands', why are you sending invalid commands to start with ? This could be a bug in
i2c-omap.c, sure, but let's try to figure out whyIGNORE_NAKhelps and why is lm75 driver sending invalid commands.The problem is, that lm75 device is SmBus compatible and its driver has .detect() function implemented. During detection it tries to scan some registers which might be not present in current device - in my case it's tmp105.
Quoted 6 lines
For example to read regA in tmp105 following is done:
1) do write in "Index" register (val RegA index) (I2C 1st message)
2) do read (I2C 2d message)
the message 1 is Nacked by device in case if register index is wrong, but i2c-omap don't send NACK (or STP). As result, bus stack in Bus Busy state.
wait a minute, it's not i2c-omap which needs to send NAK, it's LM75, and it does the NAK. The handling for NAK in the i2c framework is to return -EREMOTEIO as we do. If our last message got a NAK, we send STOP because there will be no other transfers following this one, namely, the for loop in omap_i2c_xfer() will be finished.
Quoted 6 lines
For SMBus devices the specification states (http://smbus.org/specs/)
"4.2.Acknowledge (ACK) and not acknowledge (NACK)":
- "The slave device detects an invalid command or invalid data. In this case the slave device must not acknowledge the received byte. The master upon detection of this condition must generate a STOP condition and retry the transaction"
hmm, but that's something that the OMAP I2C controller doesn't support and is emulated by the i2c framework, right ?
If you look into the I2C specification, the one the OMAP controller is compliant to, you'll see e.g. in Figure 13 that a repeated start is a valid condition after a NAK.
Also it states that:
"This is indicated by the slave generating the not-acknowledge on the first byte to follow. The slave leaves the data line HIGH and the master generates a STOP or a repeated START condition."
Because the OMAP I2C controller is compliant to the I2C specification, not the SMBus specification, we must follow through with the loop and let the next message try to send a repeated start.
What you need here is a way to discriminate between SMBus message and normal I2C message, that way you could have something like:
drivers/i2c/busses/i2c-omap.c +1 -1
@@ -618,7 +618,7 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,if (dev->cmd_err &OMAP_I2C_STAT_NACK ) {if (msg->flags &I2C_M_IGNORE_NAK )return 0 ; -if (stop) { +if (stop || is_smbus) { w =omap_i2c_read_reg (dev,OMAP_I2C_CON_REG ); w |=OMAP_I2C_CON_STP ;omap_i2c_write_reg (dev,OMAP_I2C_CON_REG , w);
and, btw, this also means that I2C_M_IGNORE_NAK is invalid during SMBus transfers, so you might want to patch the framework to prevent that case altogether.
Signature · 1 line
balbi
Hi Felipe,
Quoted 15 lines · Felipe Balbi
Hi,
Quoted 12 lines · Grygorii Strashko
Quoted 12 lines
Quoted 12 lines
Quoted 12 lines
Quoted 12 lines
On a OMAP4460, i2c-bus-3:
A driver (lm75) is causing many 'timeout waiting for bus ready' errors. SDA remains high (as it should), but SCL remains low after a NACK. The bus becomes
_unusablefor otherclients_.While probing, "lm75" writes a command, followed by a read + stop, but the write command is NACK'd. The chip does accept other writes/reads, it just refuses to ack invalid commands.
Can you tell me if the patch below would make any sense? Or is it the responsibility of the client to reset the
i2c_smbus?
Quoted 8 lines
Quoted 3 lines
Quoted 1 line
Quoted 1 line
Quoted 1 line
patch below breaks repeated start.
Felipe, I'd very appreciate if you'd be able to provide the use case which will fail with such solution?
can't you see how this would fail ?
assume
omap_i2c_xfer()is called with its last argument (num) being greater than one and you get the NAK before the last transfer.
That's our case - NACK from slave before last transfer
Quoted 3 lines
Will you not be breaking a possible repeated start for the following transfer ?
Sorry, but in this case omap_i2c_xfer() will be aborted and there would be no transfers until next call to omap_i2c_xfer(). Which, in turn, may address another device!?
Quoted 45 lines
Quoted 11 lines
Quoted 11 lines
Quoted 11 lines
No, after the NACK, no more commands are being processed, including a repeated start.
omap_i2c_xfer()returns-EREMOTEIOwithout ever freeing the bus.The bus is left in an impossible state with SCL constantly low and all next commands (to different chips) will therefore get a
-ETIMEDOUTWith this patch, the bus will become idle again and new commands can be processed normally
Quoted 7 lines
I think, this is valid fix, but it was done here already:)
http://patchwork.ozlabs.org/patch/249790/
"i2c: omap: query STP always when NACK is received"And nacked in the same way :(
But! I've back-ported my patch on TI Android product kernel 3.4, did sanity test and I didn't see any issues with my patch :))that's because you don't care about repeated start, but that's a valid bus signal which needs to be supported.
Quoted 15 lines
Quoted 9 lines
but you mentioned that if you have
IGNORE_NAKset, everything is fine, since lm75 will get a return value of 0 and things will work just fine, right ?Also, you also said that the chip 'refuses to ack invalid commands', why are you sending invalid commands to start with ? This could be a bug in
i2c-omap.c, sure, but let's try to figure out whyIGNORE_NAKhelps and why is lm75 driver sending invalid commands.The problem is, that lm75 device is SmBus compatible and its driver has .detect() function implemented. During detection it tries to scan some registers which might be not present in current device - in my case it's tmp105.
Quoted 6 lines
For example to read regA in tmp105 following is done:
1) do write in "Index" register (val RegA index) (I2C 1st message)
2) do read (I2C 2d message)
the message 1 is Nacked by device in case if register index is wrong, but i2c-omap don't send NACK (or STP). As result, bus stack in Bus Busy state.
Quoted 5 lines
wait a minute, it's not i2c-omap which needs to send NAK, it's LM75, and it does the NAK. The handling for NAK in the i2c framework is to return
-EREMOTEIOas we do. If our last message got a NAK, we send STOP because there will be no other transfers following this one, namely, the for loop inomap_i2c_xfer()will be finished.
Sorry, wrong descr, my bad - slave sends NACK (lm75), master (OMAP i2)
should send STP.
But, you *can* send STT if you wish to continue with next
message to the *same* device - which is not true for OMAP i2c, because OMAP I2C driver always interrupts transfer with error -EREMOTEIO!! And, again:), next call of omap_i2c_xfer() may be *not* to the same
slave I2C device.
Quoted 21 lines
Quoted 7 lines
For SMBus devices the specification states (http://smbus.org/specs/)
"4.2.Acknowledge (ACK) and not acknowledge (NACK)":
- "The slave device detects an invalid command or invalid data. In this case the slave device must not acknowledge the received byte. The master upon detection of this condition must generate a STOP condition and retry the transaction"hmm, but that's something that the OMAP I2C controller doesn't support and is emulated by the i2c framework, right ?
If you look into the I2C specification, the one the OMAP controller is compliant to, you'll see e.g. in Figure 13 that a repeated start is a valid condition after a NAK.
Also it states that:
"This is indicated by the slave generating the not-acknowledge on the first byte to follow. The slave leaves the data line HIGH and the master generates a STOP or a repeated START condition."
Quoted 6 lines
Because the OMAP I2C controller is compliant to the I2C specification, not the SMBus specification, we must follow through with the loop and let the next message try to send a repeated start.
What you need here is a way to discriminate between SMBus message and normal I2C message, that way you could have something like:
I don't think that is right (my explanation above) - the same can happen even with pure I2C device.
Quoted 15 lines
drivers/i2c/busses/i2c-omap.c +1
-1@@ -618,7 +618,7 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,if (dev->cmd_err &OMAP_I2C_STAT_NACK ) {if (msg->flags &I2C_M_IGNORE_NAK )return 0 ; -if (stop) { +if (stop || is_smbus) { w =omap_i2c_read_reg (dev,OMAP_I2C_CON_REG ); w |=OMAP_I2C_CON_STP ;omap_i2c_write_reg (dev,OMAP_I2C_CON_REG , w);
Quoted 4 lines
and, btw, this also means that
I2C_M_IGNORE_NAKis invalid during SMBus transfers, so you might want to patch the framework to prevent that case altogether.
Regards,
-grygorii
Hi,
(when replying, can you add some blank lines around your reply and the previous mail, it's quite difficult to find your replies with so many quote marks (>) around)
Quoted 18 lines · Grygorii Strashko
Hi Felipe,
Quoted 16 lines · Felipe Balbi
Hi,
Quoted 13 lines · Grygorii Strashko
Quoted 13 lines
Quoted 13 lines
Quoted 13 lines
Quoted 6 lines
On a OMAP4460, i2c-bus-3:
A driver (lm75) is causing many 'timeout waiting for bus ready' errors. SDA remains high (as it should), but SCL remains low after a NACK. The bus becomes
_unusablefor otherclients_.Quoted 6 lines
While probing, "lm75" writes a command, followed by a read + stop, but the write command is NACK'd. The chip does accept other writes/reads, it just refuses to ack invalid commands.
Can you tell me if the patch below would make any sense? Or is it the responsibility of the client to reset the
i2c_smbus?patch below breaks repeated start.
Quoted 8 lines
Quoted 7 lines
Quoted 2 lines
Felipe, I'd very appreciate if you'd be able to provide the use case which will fail with such solution?
can't you see how this would fail ?
assume
omap_i2c_xfer()is called with its last argument (num) being greater than one and you get the NAK before the last transfer.That's our case - NACK from slave before last transfer
with one difference, your device requires a STP condition because it's SMBus, right ? Not all devices act like that :-)
But now I noticed, because of your reply, something I have been overlooking for quite some time. As you said below, in case of NAK we break out of the loop and don't even try the following messages.
Which means your original patch starts to make a lot more sense. I wonder is this is really what we should be doing though - breaking out of the loop, I mean.
It'd be cool to get an answer from I2C maintainers if we're doing the right thing here.
Signature · 1 line
balbi
Hi Grygorii, Filipe,
Quoted 8 lines · Felipe Balbi
Quoted 7 lines · Grygorii Strashko
Hi Felipe,
Quoted 5 lines · Felipe Balbi
Hi,
Quoted 2 lines · Grygorii Strashko
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
On a OMAP4460, i2c-bus-3:
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
A driver (lm75) is causing many 'timeout waiting for bus ready' errors. SDA remains high (as it should), but SCL remains low after a NACK. The bus becomes
_unusablefor otherclients_.While probing, "lm75" writes a command, followed by a read + stop, but the write command is NACK'd. The chip does accept other writes/reads, it just refuses to ack invalid commands.
In case the NACK may not be ignored, I believe it is correct to break out of the loop and send a stop for 2 reasons:
1. all chips, including the target chip, will know that the current transaction is finished
2. to set CLK high again, which prevents numerous timeouts on subsequent transactions
As a test I've set 'I2C_M_IGNORE_NAK' for all .detect messages sent by the lm75 driver.
Now the chip (tmp105) will provide read data as expected after the _repeated start_, even though it NACK'd the preceding WR command.
And also the detection trick does work now, addresses 4,5,6,7 return the same read data as was returned from the last valid address 2.
Felipe:
Quoted 3 lines
Which means your original patch starts to make a lot more sense. I wonder is this is really what we should be doing though - breaking out of the loop, I mean.
So yes, we have to break the loop as the caller is not interested in processing any further commands.
In i2c/algos/i2c-algo-bit.c, bit_xfer() works exactly the same way:
break the loop (unless IGNORE_NAK) and call unconditionally i2c_stop().
It looks like TI's i2c-davinci will have the same problem as i2c-omap, and will need the same change.
Grygorii, if you submit the patch, please add my
cause you were earlier to notice and fix this problem.
Hein
Hi,
Quoted 3 lines
Quoted 3 lines
Which means your original patch starts to make a lot more sense. I wonder is this is really what we should be doing though - breaking out of the loop, I mean.
Yup, that is fine. I applied the old patch with Acks from Hein and Felipe to -next. Thanks!
Quoted 2 lines
It looks like TI's i2c-davinci will have the same problem as i2c-omap, and will need the same change.
Somebody up for this?
Quoted 6 lines · Wolfram Sang
Hi,
Quoted 3 lines
Quoted 3 lines
Which means your original patch starts to make a lot more sense. I wonder is this is really what we should be doing though - breaking out of the loop, I mean.
Quoted 7 lines
Yup, that is fine. I applied the old patch with Acks from Hein and Felipe to -next. Thanks!
Quoted 2 lines
It looks like TI's i2c-davinci will have the same problem as i2c-omap, and will need the same change.
Somebody up for this?
I would suggest deleting i2c-davinci and making sure it can use i2c-omap. It's the same IP anyway. Just an older version which was used back in OMAP1 times.
Signature · 1 line
balbi
Quoted 10 lines · Felipe Balbi
Quoted 9 lines · Wolfram Sang
Hi,
Quoted 3 lines
Quoted 3 lines
Which means your original patch starts to make a lot more sense. I wonder is this is really what we should be doing though - breaking out of the loop, I mean.
Yup, that is fine. I applied the old patch with Acks from Hein and Felipe to -next. Thanks!
Quoted 8 lines
Quoted 4 lines
Quoted 2 lines
It looks like TI's i2c-davinci will have the same problem as i2c-omap, and will need the same change.
Somebody up for this?
I would suggest deleting i2c-davinci and making sure it can use i2c-omap. It's the same IP anyway. Just an older version which was used back in OMAP1 times.
Yay, I'd love such a patch...
Quoted 8 lines · Wolfram Sang
Hi,
Quoted 3 lines
Quoted 3 lines
Which means your original patch starts to make a lot more sense. I wonder is this is really what we should be doing though - breaking out of the loop, I mean.
Yup, that is fine. I applied the old patch with Acks from Hein and Felipe to -next. Thanks!
Thanks.
Quoted 6 lines
Quoted 3 lines
It looks like TI's i2c-davinci will have the same problem as i2c-omap, and will need the same change.
Somebody up for this?
Regards,
-grygorii