2 * Example I2C device using asynchronous I2C send.
4 * Copyright (C) 2023 Samsung Electronics Co., Ltd. All Rights Reserved.
6 * This work is licensed under the terms of the GNU GPL, version 2. See
7 * the COPYING file in the top-level directory.
11 #include "qemu/osdep.h"
12 #include "qemu/timer.h"
13 #include "qemu/main-loop.h"
14 #include "block/aio.h"
15 #include "hw/i2c/i2c.h"
17 #define TYPE_I2C_ECHO "i2c-echo"
18 OBJECT_DECLARE_SIMPLE_TYPE(I2CEchoState
, I2C_ECHO
)
22 I2C_ECHO_STATE_START_SEND
,
26 typedef struct I2CEchoState
{
31 enum i2c_echo_state state
;
38 static void i2c_echo_bh(void *opaque
)
40 I2CEchoState
*state
= opaque
;
42 switch (state
->state
) {
43 case I2C_ECHO_STATE_IDLE
:
46 case I2C_ECHO_STATE_START_SEND
:
47 if (i2c_start_send_async(state
->bus
, state
->data
[0])) {
52 state
->state
= I2C_ECHO_STATE_ACK
;
55 case I2C_ECHO_STATE_ACK
:
60 if (i2c_send_async(state
->bus
, state
->data
[state
->pos
++])) {
68 i2c_end_transfer(state
->bus
);
70 i2c_bus_release(state
->bus
);
72 state
->state
= I2C_ECHO_STATE_IDLE
;
75 static int i2c_echo_event(I2CSlave
*s
, enum i2c_event event
)
77 I2CEchoState
*state
= I2C_ECHO(s
);
92 state
->state
= I2C_ECHO_STATE_START_SEND
;
93 i2c_bus_master(state
->bus
, state
->bh
);
107 static uint8_t i2c_echo_recv(I2CSlave
*s
)
109 I2CEchoState
*state
= I2C_ECHO(s
);
111 if (state
->pos
> 2) {
115 return state
->data
[state
->pos
++];
118 static int i2c_echo_send(I2CSlave
*s
, uint8_t data
)
120 I2CEchoState
*state
= I2C_ECHO(s
);
122 if (state
->pos
> 2) {
126 state
->data
[state
->pos
++] = data
;
131 static void i2c_echo_realize(DeviceState
*dev
, Error
**errp
)
133 I2CEchoState
*state
= I2C_ECHO(dev
);
134 BusState
*bus
= qdev_get_parent_bus(dev
);
136 state
->bus
= I2C_BUS(bus
);
137 state
->bh
= qemu_bh_new(i2c_echo_bh
, state
);
142 static void i2c_echo_class_init(ObjectClass
*oc
, void *data
)
144 I2CSlaveClass
*sc
= I2C_SLAVE_CLASS(oc
);
145 DeviceClass
*dc
= DEVICE_CLASS(oc
);
147 dc
->realize
= i2c_echo_realize
;
149 sc
->event
= i2c_echo_event
;
150 sc
->recv
= i2c_echo_recv
;
151 sc
->send
= i2c_echo_send
;
154 static const TypeInfo i2c_echo
= {
155 .name
= TYPE_I2C_ECHO
,
156 .parent
= TYPE_I2C_SLAVE
,
157 .instance_size
= sizeof(I2CEchoState
),
158 .class_init
= i2c_echo_class_init
,
161 static void register_types(void)
163 type_register_static(&i2c_echo
);
166 type_init(register_types
);