[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[RFC PATCH 2/4] hw/i2c: add async send
From: |
Klaus Jensen |
Subject: |
[RFC PATCH 2/4] hw/i2c: add async send |
Date: |
Thu, 31 Mar 2022 18:57:35 +0200 |
From: Klaus Jensen <k.jensen@samsung.com>
Add an asynchronous version of of i2c_send that requires an explicit
acknowledgement on the bus.
Signed-off-by: Klaus Jensen <k.jensen@samsung.com>
---
hw/i2c/core.c | 23 +++++++++++++++++++++++
include/hw/i2c/i2c.h | 5 +++++
2 files changed, 28 insertions(+)
diff --git a/hw/i2c/core.c b/hw/i2c/core.c
index 145dce60782a..344d764d7eaa 100644
--- a/hw/i2c/core.c
+++ b/hw/i2c/core.c
@@ -261,6 +261,20 @@ int i2c_send(I2CBus *bus, uint8_t data)
return ret ? -1 : 0;
}
+int i2c_send_async(I2CBus *bus, uint8_t data)
+{
+ I2CNode *node = QLIST_FIRST(&bus->current_devs);
+ I2CSlave *slave = node->elt;
+ I2CSlaveClass *sc = I2C_SLAVE_GET_CLASS(slave);
+
+ if (sc->send_async) {
+ sc->send_async(slave, data);
+ return 0;
+ }
+
+ return -1;
+}
+
uint8_t i2c_recv(I2CBus *bus)
{
uint8_t data = 0xff;
@@ -297,6 +311,15 @@ void i2c_nack(I2CBus *bus)
}
}
+void i2c_ack(I2CBus *bus)
+{
+ if (!bus->bh) {
+ return;
+ }
+
+ qemu_bh_schedule(bus->bh);
+}
+
static int i2c_slave_post_load(void *opaque, int version_id)
{
I2CSlave *dev = opaque;
diff --git a/include/hw/i2c/i2c.h b/include/hw/i2c/i2c.h
index be8bb8b78a60..ae58e4151585 100644
--- a/include/hw/i2c/i2c.h
+++ b/include/hw/i2c/i2c.h
@@ -28,6 +28,9 @@ struct I2CSlaveClass {
/* Master to slave. Returns non-zero for a NAK, 0 for success. */
int (*send)(I2CSlave *s, uint8_t data);
+ /* Master to slave. */
+ void (*send_async)(I2CSlave *s, uint8_t data);
+
/*
* Slave to master. This cannot fail, the device should always
* return something here.
@@ -129,9 +132,11 @@ int i2c_start_send(I2CBus *bus, uint8_t address);
void i2c_end_transfer(I2CBus *bus);
void i2c_nack(I2CBus *bus);
+void i2c_ack(I2CBus *bus);
void i2c_bus_master(I2CBus *bus, QEMUBH *bh);
void i2c_bus_release(I2CBus *bus);
int i2c_send(I2CBus *bus, uint8_t data);
+int i2c_send_async(I2CBus *bus, uint8_t data);
uint8_t i2c_recv(I2CBus *bus);
bool i2c_scan_bus(I2CBus *bus, uint8_t address, bool broadcast,
I2CNodeList *current_devs);
--
2.35.1