1
2
3
4
5
6
7
8
9
10#include "qemu/osdep.h"
11#include "hw/i2c/i2c.h"
12#include "hw/fdt_generic_util.h"
13
14typedef struct I2CNode I2CNode;
15
16struct I2CNode {
17 I2CSlave *elt;
18 QLIST_ENTRY(I2CNode) next;
19};
20
21#define I2C_BROADCAST 0x00
22
23static Property i2c_props[] = {
24 DEFINE_PROP_UINT8("address", struct I2CSlave, address, 0),
25 DEFINE_PROP_UINT8("address-range", struct I2CSlave, address_range, 1),
26 DEFINE_PROP_END_OF_LIST(),
27};
28
29#define TYPE_I2C_BUS "i2c-bus"
30#define I2C_BUS(obj) OBJECT_CHECK(I2CBus, (obj), TYPE_I2C_BUS)
31
32static const TypeInfo i2c_bus_info = {
33 .name = TYPE_I2C_BUS,
34 .parent = TYPE_BUS,
35 .instance_size = sizeof(I2CBus),
36};
37
38static void i2c_bus_pre_save(void *opaque)
39{
40 I2CBus *bus = opaque;
41
42 bus->saved_address = -1;
43 if (!QLIST_EMPTY(&bus->current_devs)) {
44 if (!bus->broadcast) {
45 bus->saved_address = QLIST_FIRST(&bus->current_devs)->elt->address;
46 } else {
47 bus->saved_address = I2C_BROADCAST;
48 }
49 }
50}
51
52static const VMStateDescription vmstate_i2c_bus = {
53 .name = "i2c_bus",
54 .version_id = 1,
55 .minimum_version_id = 1,
56 .pre_save = i2c_bus_pre_save,
57 .fields = (VMStateField[]) {
58 VMSTATE_UINT8(saved_address, I2CBus),
59 VMSTATE_END_OF_LIST()
60 }
61};
62
63
64I2CBus *i2c_init_bus(DeviceState *parent, const char *name)
65{
66 I2CBus *bus;
67
68 bus = I2C_BUS(qbus_create(TYPE_I2C_BUS, parent, name));
69 QLIST_INIT(&bus->current_devs);
70 vmstate_register(NULL, -1, &vmstate_i2c_bus, bus);
71 return bus;
72}
73
74void i2c_set_slave_address(I2CSlave *dev, uint8_t address)
75{
76 dev->address = address;
77}
78
79
80int i2c_bus_busy(I2CBus *bus)
81{
82 return !QLIST_EMPTY(&bus->current_devs);
83}
84
85
86
87
88
89
90
91
92int i2c_start_transfer(I2CBus *bus, uint8_t address, int recv)
93{
94 BusChild *kid;
95 I2CSlaveClass *sc;
96 I2CNode *node;
97
98 if (address == I2C_BROADCAST) {
99
100
101
102
103 bus->broadcast = true;
104 }
105
106
107
108
109
110
111
112
113
114 if (QLIST_EMPTY(&bus->current_devs)) {
115 QTAILQ_FOREACH(kid, &bus->qbus.children, sibling) {
116 DeviceState *qdev = kid->child;
117 I2CSlave *candidate = I2C_SLAVE(qdev);
118 if ((candidate->address <= address &&
119 address < candidate->address + candidate->address_range) ||
120 (bus->broadcast)) {
121 node = g_malloc(sizeof(struct I2CNode));
122 node->elt = candidate;
123 QLIST_INSERT_HEAD(&bus->current_devs, node, next);
124 if (!bus->broadcast) {
125 break;
126 }
127 }
128 }
129 }
130
131 if (QLIST_EMPTY(&bus->current_devs)) {
132 return 1;
133 }
134
135 QLIST_FOREACH(node, &bus->current_devs, next) {
136 sc = I2C_SLAVE_GET_CLASS(node->elt);
137
138
139 if (sc->event) {
140 sc->event(node->elt, recv ? I2C_START_RECV : I2C_START_SEND);
141 }
142 if (sc->decode_address) {
143 if (sc->decode_address(node->elt, address)) {
144 return 1;
145 }
146 }
147 }
148 return 0;
149}
150
151void i2c_end_transfer(I2CBus *bus)
152{
153 I2CSlaveClass *sc;
154 I2CNode *node, *next;
155
156 if (QLIST_EMPTY(&bus->current_devs)) {
157 return;
158 }
159
160 QLIST_FOREACH_SAFE(node, &bus->current_devs, next, next) {
161 sc = I2C_SLAVE_GET_CLASS(node->elt);
162 if (sc->event) {
163 sc->event(node->elt, I2C_FINISH);
164 }
165 QLIST_REMOVE(node, next);
166 g_free(node);
167 }
168 bus->broadcast = false;
169}
170
171int i2c_send_recv(I2CBus *bus, uint8_t *data, bool send)
172{
173 I2CSlaveClass *sc;
174 I2CNode *node;
175 int ret = 0;
176
177 if (send) {
178 QLIST_FOREACH(node, &bus->current_devs, next) {
179 sc = I2C_SLAVE_GET_CLASS(node->elt);
180 if (sc->send) {
181 ret = ret || sc->send(node->elt, *data);
182 } else {
183 ret = -1;
184 }
185 }
186 return ret ? -1 : 0;
187 } else {
188 if ((QLIST_EMPTY(&bus->current_devs)) || (bus->broadcast)) {
189 return -1;
190 }
191
192 sc = I2C_SLAVE_GET_CLASS(QLIST_FIRST(&bus->current_devs)->elt);
193 if (sc->recv) {
194 ret = sc->recv(QLIST_FIRST(&bus->current_devs)->elt);
195 if (ret < 0) {
196 return ret;
197 } else {
198 *data = ret;
199 return 0;
200 }
201 }
202 return -1;
203 }
204}
205
206int i2c_send(I2CBus *bus, uint8_t data)
207{
208 return i2c_send_recv(bus, &data, true);
209}
210
211int i2c_recv(I2CBus *bus)
212{
213 uint8_t data;
214 int ret = i2c_send_recv(bus, &data, false);
215
216 return ret < 0 ? ret : data;
217}
218
219void i2c_nack(I2CBus *bus)
220{
221 I2CSlaveClass *sc;
222 I2CNode *node;
223
224 if (QLIST_EMPTY(&bus->current_devs)) {
225 return;
226 }
227
228 QLIST_FOREACH(node, &bus->current_devs, next) {
229 sc = I2C_SLAVE_GET_CLASS(node->elt);
230 if (sc->event) {
231 sc->event(node->elt, I2C_NACK);
232 }
233 }
234}
235
236static int i2c_slave_post_load(void *opaque, int version_id)
237{
238 I2CSlave *dev = opaque;
239 I2CBus *bus;
240 I2CNode *node;
241
242 bus = I2C_BUS(qdev_get_parent_bus(DEVICE(dev)));
243 if ((bus->saved_address == dev->address) ||
244 (bus->saved_address == I2C_BROADCAST)) {
245 node = g_malloc(sizeof(struct I2CNode));
246 node->elt = dev;
247 QLIST_INSERT_HEAD(&bus->current_devs, node, next);
248 }
249 return 0;
250}
251
252const VMStateDescription vmstate_i2c_slave = {
253 .name = "I2CSlave",
254 .version_id = 1,
255 .minimum_version_id = 1,
256 .post_load = i2c_slave_post_load,
257 .fields = (VMStateField[]) {
258 VMSTATE_UINT8(address, I2CSlave),
259 VMSTATE_UINT8(address_range, I2CSlave),
260 VMSTATE_BOOL(broadcast, I2CBus),
261 VMSTATE_END_OF_LIST()
262 }
263};
264
265static int i2c_slave_qdev_init(DeviceState *dev)
266{
267 I2CSlave *s = I2C_SLAVE(dev);
268 I2CSlaveClass *sc = I2C_SLAVE_GET_CLASS(s);
269
270 return sc->init(s);
271}
272
273DeviceState *i2c_create_slave(I2CBus *bus, const char *name, uint8_t addr)
274{
275 DeviceState *dev;
276
277 dev = qdev_create(&bus->qbus, name);
278 qdev_prop_set_uint8(dev, "address", addr);
279 qdev_init_nofail(dev);
280 return dev;
281}
282
283static bool i2c_slave_parse_reg(FDTGenericMMap *obj, FDTGenericRegPropInfo reg,
284 Error **errp)
285{
286 DeviceState *parent;
287 I2CSlave *slave;
288
289 slave = I2C_SLAVE(obj);
290
291 slave->address = reg.a[0];
292 parent = (DeviceState *)object_dynamic_cast(reg.parents[0], TYPE_DEVICE);
293
294 if (!parent) {
295 return false;
296 }
297
298 if (!parent->realized) {
299 return true;
300 }
301
302 qdev_set_parent_bus(DEVICE(obj), qdev_get_child_bus(parent, "i2c"));
303
304 return false;
305}
306
307static void i2c_slave_class_init(ObjectClass *klass, void *data)
308{
309 DeviceClass *k = DEVICE_CLASS(klass);
310 FDTGenericMMapClass *fmc = FDT_GENERIC_MMAP_CLASS(klass);
311 k->init = i2c_slave_qdev_init;
312 set_bit(DEVICE_CATEGORY_MISC, k->categories);
313 k->bus_type = TYPE_I2C_BUS;
314 k->props = i2c_props;
315 fmc->parse_reg = i2c_slave_parse_reg;
316}
317
318static const TypeInfo i2c_slave_type_info = {
319 .name = TYPE_I2C_SLAVE,
320 .parent = TYPE_DEVICE,
321 .instance_size = sizeof(I2CSlave),
322 .abstract = true,
323 .class_size = sizeof(I2CSlaveClass),
324 .class_init = i2c_slave_class_init,
325 .interfaces = (InterfaceInfo []) {
326 { TYPE_FDT_GENERIC_MMAP },
327 },
328};
329
330static void i2c_slave_register_types(void)
331{
332 type_register_static(&i2c_bus_info);
333 type_register_static(&i2c_slave_type_info);
334}
335
336type_init(i2c_slave_register_types)
337