1:
2:
3:
4:
5:
6:
7:
8:
9:
10: #include "hw.h"
11: #include "i2c.h"
12:
13: struct i2c_bus
14: {
15: i2c_slave *current_dev;
16: i2c_slave *dev;
17: };
18:
19:
20: i2c_bus *i2c_init_bus(void)
21: {
22: i2c_bus *bus;
23:
24: bus = (i2c_bus *)qemu_mallocz(sizeof(i2c_bus));
25: return bus;
26: }
27:
28:
29: i2c_slave *i2c_slave_init(i2c_bus *bus, int address, int size)
30: {
31: i2c_slave *dev;
32:
33: if (size < sizeof(i2c_slave))
34: hw_error("I2C struct too small");
35:
36: dev = (i2c_slave *)qemu_mallocz(size);
37: dev->address = address;
38: dev->next = bus->dev;
39: bus->dev = dev;
40:
41: return dev;
42: }
43:
44: void i2c_set_slave_address(i2c_slave *dev, int address)
45: {
46: dev->address = address;
47: }
48:
49:
50: int i2c_bus_busy(i2c_bus *bus)
51: {
52: return bus->current_dev != NULL;
53: }
54:
55:
56:
57: int i2c_start_transfer(i2c_bus *bus, int address, int recv)
58: {
59: i2c_slave *dev;
60:
61: for (dev = bus->dev; dev; dev = dev->next) {
62: if (dev->address == address)
63: break;
64: }
65:
66: if (!dev)
67: return 1;
68:
69:
70:
71: bus->current_dev = dev;
72: dev->event(dev, recv ? I2C_START_RECV : I2C_START_SEND);
73: return 0;
74: }
75:
76: void i2c_end_transfer(i2c_bus *bus)
77: {
78: i2c_slave *dev = bus->current_dev;
79:
80: if (!dev)
81: return;
82:
83: dev->event(dev, I2C_FINISH);
84:
85: bus->current_dev = NULL;
86: }
87:
88: int i2c_send(i2c_bus *bus, uint8_t data)
89: {
90: i2c_slave *dev = bus->current_dev;
91:
92: if (!dev)
93: return -1;
94:
95: return dev->send(dev, data);
96: }
97:
98: int i2c_recv(i2c_bus *bus)
99: {
100: i2c_slave *dev = bus->current_dev;
101:
102: if (!dev)
103: return -1;
104:
105: return dev->recv(dev);
106: }
107:
108: void i2c_nack(i2c_bus *bus)
109: {
110: i2c_slave *dev = bus->current_dev;
111:
112: if (!dev)
113: return;
114:
115: dev->event(dev, I2C_NACK);
116: }
117:
118: void i2c_bus_save(QEMUFile *f, i2c_bus *bus)
119: {
120: qemu_put_byte(f, bus->current_dev ? bus->current_dev->address : 0x00);
121: }
122:
123: void i2c_bus_load(QEMUFile *f, i2c_bus *bus)
124: {
125: i2c_slave *dev;
126: uint8_t address = qemu_get_byte(f);
127:
128: if (address) {
129: for (dev = bus->dev; dev; dev = dev->next)
130: if (dev->address == address) {
131: bus->current_dev = dev;
132: return;
133: }
134:
135: fprintf(stderr, "%s: I2C slave with address %02x disappeared\n",
136: __FUNCTION__, address);
137: }
138: }
139:
140: void i2c_slave_save(QEMUFile *f, i2c_slave *dev)
141: {
142: qemu_put_byte(f, dev->address);
143: }
144:
145: void i2c_slave_load(QEMUFile *f, i2c_slave *dev)
146: {
147: dev->address = qemu_get_byte(f);
148: }