aboutsummaryrefslogtreecommitdiff
path: root/hw/i2c/smbus.c
diff options
context:
space:
mode:
authorCorey Minyard <cminyard@mvista.com>2017-01-09 11:40:20 +0000
committerPeter Maydell <peter.maydell@linaro.org>2017-01-09 11:40:20 +0000
commitd307c28ca9dba7a0677035c9244198b05164c873 (patch)
treeee942307fac668f7a2d531bf6b86e6db025cdfd0 /hw/i2c/smbus.c
parentffe22bf51065dd33022cf91f77a821d1f11c250d (diff)
downloadqemu-d307c28ca9dba7a0677035c9244198b05164c873.zip
qemu-d307c28ca9dba7a0677035c9244198b05164c873.tar.gz
qemu-d307c28ca9dba7a0677035c9244198b05164c873.tar.bz2
i2c: Allow I2C devices to NAK start events
Add a return value to the event handler. Some I2C devices will NAK if they have no data, so allow them to do this. This required the following changes: Go through all the event handlers and change them to return int and return 0. Modify i2c_start_transfer to terminate the transaction on a NAK. Modify smbus handing to not assert if a NAK occurs on a second operation, and terminate the transaction and return -1 instead. Add some information on semantics to I2CSlaveClass. Signed-off-by: Corey Minyard <cminyard@mvista.com> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/i2c/smbus.c')
-rw-r--r--hw/i2c/smbus.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/hw/i2c/smbus.c b/hw/i2c/smbus.c
index 5b4dd3e..2d1b79a 100644
--- a/hw/i2c/smbus.c
+++ b/hw/i2c/smbus.c
@@ -67,7 +67,7 @@ static void smbus_do_write(SMBusDevice *dev)
}
}
-static void smbus_i2c_event(I2CSlave *s, enum i2c_event event)
+static int smbus_i2c_event(I2CSlave *s, enum i2c_event event)
{
SMBusDevice *dev = SMBUS_DEVICE(s);
@@ -148,6 +148,8 @@ static void smbus_i2c_event(I2CSlave *s, enum i2c_event event)
break;
}
}
+
+ return 0;
}
static int smbus_i2c_recv(I2CSlave *s)
@@ -249,7 +251,8 @@ int smbus_read_byte(I2CBus *bus, uint8_t addr, uint8_t command)
}
i2c_send(bus, command);
if (i2c_start_transfer(bus, addr, 1)) {
- assert(0);
+ i2c_end_transfer(bus);
+ return -1;
}
data = i2c_recv(bus);
i2c_nack(bus);
@@ -276,7 +279,8 @@ int smbus_read_word(I2CBus *bus, uint8_t addr, uint8_t command)
}
i2c_send(bus, command);
if (i2c_start_transfer(bus, addr, 1)) {
- assert(0);
+ i2c_end_transfer(bus);
+ return -1;
}
data = i2c_recv(bus);
data |= i2c_recv(bus) << 8;
@@ -307,7 +311,8 @@ int smbus_read_block(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t *data)
}
i2c_send(bus, command);
if (i2c_start_transfer(bus, addr, 1)) {
- assert(0);
+ i2c_end_transfer(bus);
+ return -1;
}
len = i2c_recv(bus);
if (len > 32) {