Most of the control flow logic between send and recv (error checking etc) is the same. Factor this out into a common send_recv() API. This is then usable by clients, where the control logic for send and receive differs only by a boolean. E.g.
if (send) i2c_send(...): else i2c_recv(...); becomes: i2c_send_recv(... , send); Signed-off-by: Peter Crosthwaite <crosthwaite.pe...@gmail.com> --- hw/i2c/core.c | 34 +++++++++++++++++++--------------- include/hw/i2c/i2c.h | 1 + 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/hw/i2c/core.c b/hw/i2c/core.c index 5a64026..d4a8cbb 100644 --- a/hw/i2c/core.c +++ b/hw/i2c/core.c @@ -129,7 +129,7 @@ void i2c_end_transfer(I2CBus *bus) bus->current_dev = NULL; } -int i2c_send(I2CBus *bus, uint8_t data) +int i2c_send_recv(I2CBus *bus, uint8_t *data, bool send) { I2CSlave *dev = bus->current_dev; I2CSlaveClass *sc; @@ -139,28 +139,32 @@ int i2c_send(I2CBus *bus, uint8_t data) } sc = I2C_SLAVE_GET_CLASS(dev); - if (sc->send) { - return sc->send(dev, data); + if (send && sc->send) { + return sc->send(dev, *data); + } else if (!send && sc->recv) { + int ret = sc->recv(dev); + if (ret < 0) { + return ret; + } else { + *data = ret; + return 0; + } } return -1; } -int i2c_recv(I2CBus *bus) +int i2c_send(I2CBus *bus, uint8_t data) { - I2CSlave *dev = bus->current_dev; - I2CSlaveClass *sc; - - if (!dev) { - return -1; - } + return i2c_send_recv(bus, &data, true); +} - sc = I2C_SLAVE_GET_CLASS(dev); - if (sc->recv) { - return sc->recv(dev); - } +int i2c_recv(I2CBus *bus) +{ + uint8_t data; + int ret = i2c_send_recv(bus, &data, false); - return -1; + return ret < 0 ? ret : data; } void i2c_nack(I2CBus *bus) diff --git a/include/hw/i2c/i2c.h b/include/hw/i2c/i2c.h index 4986ebc..c4085aa 100644 --- a/include/hw/i2c/i2c.h +++ b/include/hw/i2c/i2c.h @@ -56,6 +56,7 @@ int i2c_bus_busy(I2CBus *bus); int i2c_start_transfer(I2CBus *bus, uint8_t address, int recv); void i2c_end_transfer(I2CBus *bus); void i2c_nack(I2CBus *bus); +int i2c_send_recv(I2CBus *bus, uint8_t *data, bool send); int i2c_send(I2CBus *bus, uint8_t data); int i2c_recv(I2CBus *bus); -- 1.9.1