1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21#include "qemu/osdep.h"
22#include "hw/hw.h"
23#include "sysemu/blockdev.h"
24#include "hw/i2c/pca954x.h"
25#include "qemu/log.h"
26
27#ifndef PCA954X_DEBUG
28#define PCA954X_DEBUG 0
29#endif
30
31#define DB_PRINT(fmt, args...) do { \
32 if (PCA954X_DEBUG) { \
33 qemu_log("PCA954X: "fmt, ## args); \
34 } \
35} while (0);
36
37static pca954x_type known_devices[] = {
38
39 { .name = "pca9542", .lanes = 2, .mux = true },
40 { .name = "pca9544", .lanes = 4, .mux = true },
41 { .name = "pca9547", .lanes = 8, .mux = true },
42
43 { .name = "pca9543", .lanes = 2, .mux = false },
44 { .name = "pca9545", .lanes = 4, .mux = false },
45 { .name = "pca9546", .lanes = 4, .mux = false },
46 { .name = "pca9548", .lanes = 8, .mux = false },
47 { .name = "pca9549", .lanes = 8, .mux = false },
48};
49
50static void pca954x_reset(DeviceState *dev)
51{
52 PCA954XState *s = PCA954X(dev);
53 I2CSlave *i2cs = I2C_SLAVE(dev);
54
55
56
57
58 i2cs->address = 0;
59 i2cs->address_range = 0x80;
60
61 s->control_reg = 0;
62 s->active_lanes = 0;
63}
64
65static int pca954x_recv(I2CSlave *i2c)
66{
67 PCA954XState *s = PCA954X(i2c);
68 int i;
69 int ret = 0;
70
71 if (s->control_decoded) {
72 ret |= s->control_reg;
73 DB_PRINT("returning control register: %x\n", ret);
74 } else {
75 for (i = 0; i < s->lanes; ++i) {
76 if (s->active_lanes & (1 << i)) {
77 ret |= i2c_recv(s->busses[i]);
78 DB_PRINT("recieving from active bus %d:%x\n", i, ret);
79 }
80 }
81 }
82
83 return ret;
84}
85
86static void pca954x_decode_lane(PCA954XState *s)
87{
88 if (s->mux) {
89 s->active_lanes = (1 << (s->control_reg & (s->lanes - 1)));
90 } else {
91 s->active_lanes = s->control_reg;
92 }
93}
94
95static int pca954x_send(I2CSlave *i2c, uint8_t data)
96{
97 PCA954XState *s = PCA954X(i2c);
98 int i;
99 int ret = -1;
100
101 if (s->control_decoded) {
102 DB_PRINT("setting control register: %x\n", data);
103 s->control_reg = data;
104 pca954x_decode_lane(s);
105 ret = 0;
106 } else {
107 for (i = 0; i < s->lanes; ++i) {
108 if (s->active_lanes & (1 << i)) {
109 DB_PRINT("sending to active bus %d:%x\n", i, data);
110 ret &= i2c_send(s->busses[i], data);
111 }
112 }
113 }
114
115 return ret;
116}
117
118static int pca954x_event(I2CSlave *i2c, enum i2c_event event)
119{
120 PCA954XState *s = PCA954X(i2c);
121 int i;
122
123 s->event = event;
124 for (i = 0; i < s->lanes; ++i) {
125 if (s->active_lanes & (1 << i)) {
126 switch (event) {
127
128 case I2C_START_SEND:
129 case I2C_START_RECV:
130 break;
131
132 case I2C_FINISH:
133 if (!s->control_decoded) {
134 DB_PRINT("stopping active bus %d\n", i);
135 i2c_end_transfer(s->busses[i]);
136 }
137 break;
138 case I2C_NACK:
139 if (!s->control_decoded) {
140 DB_PRINT("nacking active bus %d\n", i);
141 i2c_nack(s->busses[i]);
142 }
143 break;
144 }
145 }
146 }
147
148 return 0;
149}
150
151static int pca954x_decode_address(I2CSlave *i2c, uint8_t address)
152{
153 PCA954XState *s = PCA954X(i2c);
154 int i;
155 uint8_t channel_status = 0;
156
157 s->control_decoded = address ==
158 (PCA954X_CONTROL_ADDR | (s->chip_enable & 0x7));
159
160 if (s->control_decoded) {
161 return 0;
162 }
163
164 for (i = 0; i < s->lanes; ++i) {
165 if (s->active_lanes & (1 << i)) {
166 DB_PRINT("starting active bus %d addr:%02x rnw:%d\n", i, address,
167 s->event == I2C_START_RECV);
168 channel_status |= (i2c_start_transfer(s->busses[i], address,
169 s->event == I2C_START_RECV)) << i;
170 }
171 }
172
173 if (s->active_lanes == channel_status) {
174 return 1;
175 }
176
177 return 0;
178}
179
180static void pca954x_init(Object *obj)
181{
182 PCA954XState *s = PCA954X(obj);
183 PCA954XClass *sc = PCA954X_GET_CLASS(obj);
184 int i;
185
186 if (sc->device) {
187 s->mux = sc->device->mux;
188 s->lanes = sc->device->lanes;
189 } else {
190
191 s->mux = false;
192 s->lanes = 8;
193 }
194 for (i = 0; i < s->lanes; ++i) {
195 char bus_name[16];
196
197 snprintf(bus_name, sizeof(bus_name), "i2c@%d", i);
198 s->busses[i] = i2c_init_bus(DEVICE(s), bus_name);
199 }
200}
201
202static void pca954x_realize(DeviceState *dev, Error **errp)
203{
204
205}
206
207static const VMStateDescription vmstate_PCA954X = {
208 .name = "pca954x",
209 .version_id = 1,
210 .fields = (VMStateField[]) {
211 VMSTATE_I2C_SLAVE(i2c, PCA954XState),
212 VMSTATE_UINT8(control_reg, PCA954XState),
213 VMSTATE_BOOL(control_decoded, PCA954XState),
214 VMSTATE_UINT8(active_lanes, PCA954XState),
215 VMSTATE_UINT8(lanes, PCA954XState),
216 VMSTATE_BOOL(mux, PCA954XState),
217 VMSTATE_END_OF_LIST()
218 }
219};
220
221static Property pca954x_properties[] = {
222
223
224
225 DEFINE_PROP_UINT8("chip-enable", PCA954XState, chip_enable, 0),
226 DEFINE_PROP_END_OF_LIST(),
227};
228
229static void pca954x_class_init(ObjectClass *klass, void *data)
230{
231 DeviceClass *dc = DEVICE_CLASS(klass);
232 I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
233 PCA954XClass *sc = PCA954X_CLASS(klass);
234
235 k->event = pca954x_event;
236 k->recv = pca954x_recv;
237 k->send = pca954x_send;
238 k->decode_address = pca954x_decode_address;
239
240 dc->realize = pca954x_realize;
241 dc->reset = pca954x_reset;
242 dc->vmsd = &vmstate_PCA954X;
243 dc->props = pca954x_properties;
244 sc->device = data;
245}
246
247static TypeInfo pca954x_info = {
248 .name = TYPE_PCA954X,
249 .parent = TYPE_I2C_SLAVE,
250 .instance_size = sizeof(PCA954XState),
251 .instance_init = pca954x_init,
252};
253
254static void pca954x_register_types(void)
255{
256 int i;
257
258 type_register_static(&pca954x_info);
259 for (i = 0; i < ARRAY_SIZE(known_devices); i++) {
260 TypeInfo t = {
261 .name = known_devices[i].name,
262 .parent = TYPE_PCA954X,
263 .class_init = pca954x_class_init,
264 .class_data = &known_devices[i]
265 };
266 type_register(&t);
267 }
268}
269
270type_init(pca954x_register_types)
271