qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: "Cédric Le Goater" <clg@kaod.org>
To: qemu-arm@nongnu.org, qemu-devel@nongnu.org
Cc: "Peter Maydell" <peter.maydell@linaro.org>,
	"Joe Komlodi" <komlodi@google.com>,
	"Troy Lee" <troy_lee@aspeedtech.com>,
	"Jamin Lin" <jamin_lin@aspeedtech.com>,
	"Steven Lee" <steven_lee@aspeedtech.com>,
	"Klaus Jensen" <k.jensen@samsung.com>,
	"Peter Delevoryas" <pdel@fb.com>,
	"Corey Minyard" <cminyard@mvista.com>,
	"Jonathan Cameron" <Jonathan.Cameron@huawei.com>,
	"Damien Hedde" <damien.hedde@greensocs.com>,
	"Andrew Jeffery" <andrew@aj.id.au>,
	"Joel Stanley" <joel@jms.id.au>, "Cleber Rosa" <crosa@redhat.com>,
	"Philippe Mathieu-Daudé" <f4bug@amsat.org>,
	"Wainer dos Santos Moschetta" <wainersm@redhat.com>,
	"Beraldo Leal" <bleal@redhat.com>,
	"Cédric Le Goater" <clg@kaod.org>
Subject: [PATCH 20/21] hw/misc: add a toy i2c echo device [DO NOT PULL]
Date: Mon,  6 Jun 2022 17:07:31 +0200	[thread overview]
Message-ID: <20220606150732.2282041-21-clg@kaod.org> (raw)
In-Reply-To: <20220606150732.2282041-1-clg@kaod.org>

From: Klaus Jensen <k.jensen@samsung.com>

Add an example I2C device to demonstrate how a slave may master the bus
and send data asynchronously to another slave.

The device will echo whatever it is sent to the device identified by the
first byte received.

Signed-off-by: Klaus Jensen <k.jensen@samsung.com>
Message-Id: <20220601210831.67259-7-its@irrelevant.dk>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/misc/i2c-echo.c  | 162 ++++++++++++++++++++++++++++++++++++++++++++
 hw/misc/meson.build |   2 +
 2 files changed, 164 insertions(+)
 create mode 100644 hw/misc/i2c-echo.c

diff --git a/hw/misc/i2c-echo.c b/hw/misc/i2c-echo.c
new file mode 100644
index 000000000000..27992eff8c5b
--- /dev/null
+++ b/hw/misc/i2c-echo.c
@@ -0,0 +1,162 @@
+#include "qemu/osdep.h"
+#include "qemu/timer.h"
+#include "qemu/main-loop.h"
+#include "block/aio.h"
+#include "hw/i2c/i2c.h"
+
+#define TYPE_I2C_ECHO "i2c-echo"
+OBJECT_DECLARE_SIMPLE_TYPE(I2CEchoState, I2C_ECHO)
+
+enum i2c_echo_state {
+    I2C_ECHO_STATE_IDLE,
+    I2C_ECHO_STATE_REQUEST_MASTER,
+    I2C_ECHO_STATE_START_SEND,
+    I2C_ECHO_STATE_ACK,
+};
+
+typedef struct I2CEchoState {
+    I2CSlave parent_obj;
+
+    I2CBus *bus;
+
+    enum i2c_echo_state state;
+    QEMUBH *bh;
+
+    unsigned int pos;
+    uint8_t data[3];
+} I2CEchoState;
+
+static void i2c_echo_bh(void *opaque)
+{
+    I2CEchoState *state = opaque;
+
+    switch (state->state) {
+    case I2C_ECHO_STATE_IDLE:
+        return;
+
+    case I2C_ECHO_STATE_REQUEST_MASTER:
+        i2c_bus_master(state->bus, state->bh);
+        state->state = I2C_ECHO_STATE_START_SEND;
+        return;
+
+    case I2C_ECHO_STATE_START_SEND:
+        if (i2c_start_send_async(state->bus, state->data[0])) {
+            goto release_bus;
+        }
+
+        state->pos++;
+        state->state = I2C_ECHO_STATE_ACK;
+        return;
+
+    case I2C_ECHO_STATE_ACK:
+        if (state->pos > 2) {
+            break;
+        }
+
+        if (i2c_send_async(state->bus, state->data[state->pos++])) {
+            break;
+        }
+
+        return;
+    }
+
+
+    i2c_end_transfer(state->bus);
+release_bus:
+    i2c_bus_release(state->bus);
+
+    state->state = I2C_ECHO_STATE_IDLE;
+}
+
+static int i2c_echo_event(I2CSlave *s, enum i2c_event event)
+{
+    I2CEchoState *state = I2C_ECHO(s);
+
+    switch (event) {
+    case I2C_START_RECV:
+        state->pos = 0;
+
+        break;
+
+    case I2C_START_SEND:
+        state->pos = 0;
+
+        break;
+
+    case I2C_FINISH:
+        state->pos = 0;
+        state->state = I2C_ECHO_STATE_REQUEST_MASTER;
+        qemu_bh_schedule(state->bh);
+
+        break;
+
+    case I2C_NACK:
+        break;
+
+    default:
+        return -1;
+    }
+
+    return 0;
+}
+
+static uint8_t i2c_echo_recv(I2CSlave *s)
+{
+    I2CEchoState *state = I2C_ECHO(s);
+
+    if (state->pos > 2) {
+        return 0xff;
+    }
+
+    return state->data[state->pos++];
+}
+
+static int i2c_echo_send(I2CSlave *s, uint8_t data)
+{
+    I2CEchoState *state = I2C_ECHO(s);
+
+    if (state->pos > 2) {
+        return -1;
+    }
+
+    state->data[state->pos++] = data;
+
+    return 0;
+}
+
+static void i2c_echo_realize(DeviceState *dev, Error **errp)
+{
+    I2CEchoState *state = I2C_ECHO(dev);
+    BusState *bus = qdev_get_parent_bus(dev);
+
+    state->bus = I2C_BUS(bus);
+    state->bh = qemu_bh_new(i2c_echo_bh, state);
+
+    return;
+}
+
+static void i2c_echo_class_init(ObjectClass *oc, void *data)
+{
+    I2CSlaveClass *sc = I2C_SLAVE_CLASS(oc);
+    DeviceClass *dc = DEVICE_CLASS(oc);
+
+    dc->realize = i2c_echo_realize;
+
+    sc->event = i2c_echo_event;
+    sc->recv = i2c_echo_recv;
+    sc->send = i2c_echo_send;
+}
+
+static const TypeInfo i2c_echo = {
+    .name = TYPE_I2C_ECHO,
+    .parent = TYPE_I2C_SLAVE,
+    .instance_size = sizeof(I2CEchoState),
+    .class_init = i2c_echo_class_init,
+};
+
+static void register_types(void)
+{
+    type_register_static(&i2c_echo);
+}
+
+type_init(register_types);
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
index 132b7b7344bb..8c366f94da42 100644
--- a/hw/misc/meson.build
+++ b/hw/misc/meson.build
@@ -123,6 +123,8 @@ softmmu_ss.add(when: 'CONFIG_NRF51_SOC', if_true: files('nrf51_rng.c'))
 
 softmmu_ss.add(when: 'CONFIG_GRLIB', if_true: files('grlib_ahb_apb_pnp.c'))
 
+softmmu_ss.add(when: 'CONFIG_I2C', if_true: files('i2c-echo.c'))
+
 specific_ss.add(when: 'CONFIG_AVR_POWER', if_true: files('avr_power.c'))
 
 specific_ss.add(when: 'CONFIG_IMX', if_true: files('imx6_src.c'))
-- 
2.35.3



  parent reply	other threads:[~2022-06-06 16:02 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-06-06 15:07 [PATCH 00/21] aspeed: Extend ast2600 I2C model with new mode Cédric Le Goater
2022-06-06 15:07 ` [PATCH 01/21] hw/registerfields: Add shared fields macros Cédric Le Goater
2022-06-06 15:07 ` [PATCH 02/21] aspeed: i2c: Add ctrl_global_rsvd property Cédric Le Goater
2022-06-07  0:05   ` Joel Stanley
2022-06-07 17:32     ` Cédric Le Goater
2022-06-06 15:07 ` [PATCH 03/21] aspeed: i2c: Migrate to registerfields API Cédric Le Goater
2022-06-06 23:29   ` Joel Stanley
2022-06-06 15:07 ` [PATCH 04/21] aspeed: i2c: Use reg array instead of individual vars Cédric Le Goater
2022-06-06 23:49   ` Joel Stanley
2022-06-07  9:57     ` Cédric Le Goater
2022-06-07 10:50     ` Cédric Le Goater
2022-06-06 15:07 ` [PATCH 05/21] aspeed: i2c: Add new mode support Cédric Le Goater
2022-06-06 15:07 ` [PATCH 06/21] aspeed: i2c: Add PKT_DONE IRQ to trace Cédric Le Goater
2022-06-06 15:07 ` [PATCH 07/21] aspeed: i2c: Move regs and helpers to header file Cédric Le Goater
2022-06-06 15:07 ` [PATCH 08/21] test/avocado/machine_aspeed.py: Move OpenBMC tests Cédric Le Goater
2022-06-06 15:07 ` [PATCH 09/21] test/avocado/machine_aspeed.py: Add tests using buildroot images Cédric Le Goater
2022-06-06 15:07 ` [PATCH 10/21] test/avocado/machine_aspeed.py: Add I2C tests to ast2600-evb Cédric Le Goater
2022-06-06 15:07 ` [PATCH 11/21] test/avocado/machine_aspeed.py: Add an I2C RTC test Cédric Le Goater
2022-06-06 23:16   ` Joel Stanley
2022-06-07 10:17     ` Cédric Le Goater
2022-06-06 15:07 ` [PATCH 12/21] aspeed/i2c: Add ast1030 controller models Cédric Le Goater
2022-06-06 23:22   ` Joel Stanley
2022-06-06 15:07 ` [PATCH 13/21] aspeed: Add I2C buses to AST1030 model Cédric Le Goater
2022-06-06 23:18   ` Joel Stanley
2022-06-07 10:43     ` Cédric Le Goater
2022-06-06 15:07 ` [PATCH 14/21] hw/i2c/aspeed: rework raise interrupt trace event Cédric Le Goater
2022-06-06 15:07 ` [PATCH 15/21] hw/i2c/aspeed: add DEV_ADDR in old register mode Cédric Le Goater
2022-06-06 15:07 ` [PATCH 16/21] hw/i2c: support multiple masters Cédric Le Goater
2022-06-06 15:07 ` [PATCH 17/21] hw/i2c: add asynchronous send Cédric Le Goater
2022-06-06 15:07 ` [PATCH 18/21] hw/i2c/aspeed: add slave device in old register mode Cédric Le Goater
2022-06-06 15:07 ` [PATCH 19/21] aspeed/i2c: Enable SLAVE_ADDR_RX_MATCH always Cédric Le Goater
2022-06-06 15:07 ` Cédric Le Goater [this message]
2022-06-06 15:07 ` [PATCH 21/21] test/avocado/machine_aspeed.py: Add I2C slave tests Cédric Le Goater
2022-06-19 14:50 ` [PATCH 00/21] aspeed: Extend ast2600 I2C model with new mode Cédric Le Goater

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220606150732.2282041-21-clg@kaod.org \
    --to=clg@kaod.org \
    --cc=Jonathan.Cameron@huawei.com \
    --cc=andrew@aj.id.au \
    --cc=bleal@redhat.com \
    --cc=cminyard@mvista.com \
    --cc=crosa@redhat.com \
    --cc=damien.hedde@greensocs.com \
    --cc=f4bug@amsat.org \
    --cc=jamin_lin@aspeedtech.com \
    --cc=joel@jms.id.au \
    --cc=k.jensen@samsung.com \
    --cc=komlodi@google.com \
    --cc=pdel@fb.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-arm@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=steven_lee@aspeedtech.com \
    --cc=troy_lee@aspeedtech.com \
    --cc=wainersm@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).