aboutsummaryrefslogtreecommitdiff
path: root/hw/i2c
diff options
context:
space:
mode:
authorStefan Hajnoczi <stefanha@redhat.com>2016-11-07 14:02:15 +0000
committerStefan Hajnoczi <stefanha@redhat.com>2016-11-07 14:02:15 +0000
commit207faf24c58859f5240f66bf6decc33b87a1776e (patch)
tree077b7005139b02e99476986b1af66242b12a5b7d /hw/i2c
parent0ea3eb65e84c5d4665dbeee3e3e5ed56b43f7648 (diff)
parent9706e0162d2405218fd7376ffdf13baed8569a4b (diff)
downloadqemu-207faf24c58859f5240f66bf6decc33b87a1776e.zip
qemu-207faf24c58859f5240f66bf6decc33b87a1776e.tar.gz
qemu-207faf24c58859f5240f66bf6decc33b87a1776e.tar.bz2
Merge remote-tracking branch 'pm215/tags/pull-target-arm-20161107' into staging
target-arm queue: * bitbang_i2c: Handle NACKs from devices * Fix corruption of CPSR when SCTLR.EE is set * nvic: set pending status for not active interrupts * char: cadence: check baud rate generator and divider values # gpg: Signature made Mon 07 Nov 2016 10:43:07 AM GMT # gpg: using RSA key 0x3C2525ED14360CDE # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" # gpg: aka "Peter Maydell <pmaydell@gmail.com>" # gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" # Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE * pm215/tags/pull-target-arm-20161107: hw/i2c/bitbang_i2c: Handle NACKs from devices Fix corruption of CPSR when SCTLR.EE is set nvic: set pending status for not active interrupts char: cadence: check baud rate generator and divider values Message-id: 1478515653-6361-1-git-send-email-peter.maydell@linaro.org Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Diffstat (limited to 'hw/i2c')
-rw-r--r--hw/i2c/bitbang_i2c.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/hw/i2c/bitbang_i2c.c b/hw/i2c/bitbang_i2c.c
index d3a2989..8be88ee 100644
--- a/hw/i2c/bitbang_i2c.c
+++ b/hw/i2c/bitbang_i2c.c
@@ -130,14 +130,25 @@ int bitbang_i2c_set(bitbang_i2c_interface *i2c, int line, int level)
return bitbang_i2c_ret(i2c, 1);
case WAITING_FOR_ACK:
+ {
+ int ret;
+
if (i2c->current_addr < 0) {
i2c->current_addr = i2c->buffer;
DPRINTF("Address 0x%02x\n", i2c->current_addr);
- i2c_start_transfer(i2c->bus, i2c->current_addr >> 1,
- i2c->current_addr & 1);
+ ret = i2c_start_transfer(i2c->bus, i2c->current_addr >> 1,
+ i2c->current_addr & 1);
} else {
DPRINTF("Sent 0x%02x\n", i2c->buffer);
- i2c_send(i2c->bus, i2c->buffer);
+ ret = i2c_send(i2c->bus, i2c->buffer);
+ }
+ if (ret) {
+ /* NACK (either addressing a nonexistent device, or the
+ * device we were sending to decided to NACK us).
+ */
+ DPRINTF("Got NACK\n");
+ bitbang_i2c_enter_stop(i2c);
+ return bitbang_i2c_ret(i2c, 1);
}
if (i2c->current_addr & 1) {
i2c->state = RECEIVING_BIT7;
@@ -145,7 +156,7 @@ int bitbang_i2c_set(bitbang_i2c_interface *i2c, int line, int level)
i2c->state = SENDING_BIT7;
}
return bitbang_i2c_ret(i2c, 0);
-
+ }
case RECEIVING_BIT7:
i2c->buffer = i2c_recv(i2c->bus);
DPRINTF("RX byte 0x%02x\n", i2c->buffer);