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/i2c/imx_i2c.h"
23#include "hw/i2c/i2c.h"
24#include "qemu/log.h"
25#include "qemu/module.h"
26
27#ifndef DEBUG_IMX_I2C
28#define DEBUG_IMX_I2C 0
29#endif
30
31#define DPRINTF(fmt, args...) \
32 do { \
33 if (DEBUG_IMX_I2C) { \
34 fprintf(stderr, "[%s]%s: " fmt , TYPE_IMX_I2C, \
35 __func__, ##args); \
36 } \
37 } while (0)
38
39static const char *imx_i2c_get_regname(unsigned offset)
40{
41 switch (offset) {
42 case IADR_ADDR:
43 return "IADR";
44 case IFDR_ADDR:
45 return "IFDR";
46 case I2CR_ADDR:
47 return "I2CR";
48 case I2SR_ADDR:
49 return "I2SR";
50 case I2DR_ADDR:
51 return "I2DR";
52 default:
53 return "[?]";
54 }
55}
56
57static inline bool imx_i2c_is_enabled(IMXI2CState *s)
58{
59 return s->i2cr & I2CR_IEN;
60}
61
62static inline bool imx_i2c_interrupt_is_enabled(IMXI2CState *s)
63{
64 return s->i2cr & I2CR_IIEN;
65}
66
67static inline bool imx_i2c_is_master(IMXI2CState *s)
68{
69 return s->i2cr & I2CR_MSTA;
70}
71
72static void imx_i2c_reset(DeviceState *dev)
73{
74 IMXI2CState *s = IMX_I2C(dev);
75
76 if (s->address != ADDR_RESET) {
77 i2c_end_transfer(s->bus);
78 }
79
80 s->address = ADDR_RESET;
81 s->iadr = IADR_RESET;
82 s->ifdr = IFDR_RESET;
83 s->i2cr = I2CR_RESET;
84 s->i2sr = I2SR_RESET;
85 s->i2dr_read = I2DR_RESET;
86 s->i2dr_write = I2DR_RESET;
87}
88
89static inline void imx_i2c_raise_interrupt(IMXI2CState *s)
90{
91
92
93
94
95 if (imx_i2c_is_enabled(s) && imx_i2c_interrupt_is_enabled(s)) {
96 s->i2sr |= I2SR_IIF;
97 qemu_irq_raise(s->irq);
98 }
99}
100
101static uint64_t imx_i2c_read(void *opaque, hwaddr offset,
102 unsigned size)
103{
104 uint16_t value;
105 IMXI2CState *s = IMX_I2C(opaque);
106
107 switch (offset) {
108 case IADR_ADDR:
109 value = s->iadr;
110 break;
111 case IFDR_ADDR:
112 value = s->ifdr;
113 break;
114 case I2CR_ADDR:
115 value = s->i2cr;
116 break;
117 case I2SR_ADDR:
118 value = s->i2sr;
119 break;
120 case I2DR_ADDR:
121 value = s->i2dr_read;
122
123 if (imx_i2c_is_master(s)) {
124 uint8_t ret = 0xff;
125
126 if (s->address == ADDR_RESET) {
127
128 qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Trying to read "
129 "without specifying the slave address\n",
130 TYPE_IMX_I2C, __func__);
131 } else if (s->i2cr & I2CR_MTX) {
132 qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Trying to read "
133 "but MTX is set\n", TYPE_IMX_I2C, __func__);
134 } else {
135
136 ret = i2c_recv(s->bus);
137 imx_i2c_raise_interrupt(s);
138 }
139
140 s->i2dr_read = ret;
141 } else {
142 qemu_log_mask(LOG_UNIMP, "[%s]%s: slave mode not implemented\n",
143 TYPE_IMX_I2C, __func__);
144 }
145 break;
146 default:
147 qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad address at offset 0x%"
148 HWADDR_PRIx "\n", TYPE_IMX_I2C, __func__, offset);
149 value = 0;
150 break;
151 }
152
153 DPRINTF("read %s [0x%" HWADDR_PRIx "] -> 0x%02x\n",
154 imx_i2c_get_regname(offset), offset, value);
155
156 return (uint64_t)value;
157}
158
159static void imx_i2c_write(void *opaque, hwaddr offset,
160 uint64_t value, unsigned size)
161{
162 IMXI2CState *s = IMX_I2C(opaque);
163
164 DPRINTF("write %s [0x%" HWADDR_PRIx "] <- 0x%02x\n",
165 imx_i2c_get_regname(offset), offset, (int)value);
166
167 value &= 0xff;
168
169 switch (offset) {
170 case IADR_ADDR:
171 s->iadr = value & IADR_MASK;
172
173 break;
174 case IFDR_ADDR:
175 s->ifdr = value & IFDR_MASK;
176 break;
177 case I2CR_ADDR:
178 if (imx_i2c_is_enabled(s) && ((value & I2CR_IEN) == 0)) {
179
180 uint16_t iadr = s->iadr;
181 imx_i2c_reset(DEVICE(s));
182 s->iadr = iadr;
183 } else {
184 s->i2cr = value & I2CR_MASK;
185
186 if (imx_i2c_is_master(s)) {
187
188 s->i2sr |= I2SR_IBB;
189 } else {
190
191 s->i2sr &= ~I2SR_IBB;
192
193
194
195
196
197 if (s->address != ADDR_RESET) {
198 i2c_end_transfer(s->bus);
199 s->address = ADDR_RESET;
200 }
201 }
202
203 if (s->i2cr & I2CR_RSTA) {
204
205 if (s->address != ADDR_RESET) {
206 i2c_end_transfer(s->bus);
207 s->address = ADDR_RESET;
208 s->i2cr &= ~I2CR_RSTA;
209 }
210 }
211 }
212 break;
213 case I2SR_ADDR:
214
215
216
217
218 if ((s->i2sr & I2SR_IIF) && !(value & I2SR_IIF)) {
219 s->i2sr &= ~I2SR_IIF;
220 qemu_irq_lower(s->irq);
221 }
222
223
224
225
226 if ((s->i2sr & I2SR_IAL) && !(value & I2SR_IAL)) {
227 s->i2sr &= ~I2SR_IAL;
228 }
229
230 break;
231 case I2DR_ADDR:
232
233 if (!imx_i2c_is_enabled(s)) {
234 break;
235 }
236
237 s->i2dr_write = value & I2DR_MASK;
238
239 if (imx_i2c_is_master(s)) {
240
241 if (s->address == ADDR_RESET) {
242 if (i2c_start_transfer(s->bus, extract32(s->i2dr_write, 1, 7),
243 extract32(s->i2dr_write, 0, 1))) {
244
245 s->i2sr |= I2SR_RXAK;
246 } else {
247 s->address = s->i2dr_write;
248 s->i2sr &= ~I2SR_RXAK;
249 imx_i2c_raise_interrupt(s);
250 }
251 } else {
252 if (i2c_send(s->bus, s->i2dr_write)) {
253
254 s->i2sr |= I2SR_RXAK;
255 s->address = ADDR_RESET;
256 i2c_end_transfer(s->bus);
257 } else {
258 s->i2sr &= ~I2SR_RXAK;
259 imx_i2c_raise_interrupt(s);
260 }
261 }
262 } else {
263 qemu_log_mask(LOG_UNIMP, "[%s]%s: slave mode not implemented\n",
264 TYPE_IMX_I2C, __func__);
265 }
266 break;
267 default:
268 qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad address at offset 0x%"
269 HWADDR_PRIx "\n", TYPE_IMX_I2C, __func__, offset);
270 break;
271 }
272}
273
274static const MemoryRegionOps imx_i2c_ops = {
275 .read = imx_i2c_read,
276 .write = imx_i2c_write,
277 .valid.min_access_size = 1,
278 .valid.max_access_size = 2,
279 .endianness = DEVICE_NATIVE_ENDIAN,
280};
281
282static const VMStateDescription imx_i2c_vmstate = {
283 .name = TYPE_IMX_I2C,
284 .version_id = 1,
285 .minimum_version_id = 1,
286 .fields = (VMStateField[]) {
287 VMSTATE_UINT16(address, IMXI2CState),
288 VMSTATE_UINT16(iadr, IMXI2CState),
289 VMSTATE_UINT16(ifdr, IMXI2CState),
290 VMSTATE_UINT16(i2cr, IMXI2CState),
291 VMSTATE_UINT16(i2sr, IMXI2CState),
292 VMSTATE_UINT16(i2dr_read, IMXI2CState),
293 VMSTATE_UINT16(i2dr_write, IMXI2CState),
294 VMSTATE_END_OF_LIST()
295 }
296};
297
298static void imx_i2c_realize(DeviceState *dev, Error **errp)
299{
300 IMXI2CState *s = IMX_I2C(dev);
301
302 memory_region_init_io(&s->iomem, OBJECT(s), &imx_i2c_ops, s, TYPE_IMX_I2C,
303 IMX_I2C_MEM_SIZE);
304 sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
305 sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq);
306 s->bus = i2c_init_bus(DEVICE(dev), NULL);
307}
308
309static void imx_i2c_class_init(ObjectClass *klass, void *data)
310{
311 DeviceClass *dc = DEVICE_CLASS(klass);
312
313 dc->vmsd = &imx_i2c_vmstate;
314 dc->reset = imx_i2c_reset;
315 dc->realize = imx_i2c_realize;
316 dc->desc = "i.MX I2C Controller";
317}
318
319static const TypeInfo imx_i2c_type_info = {
320 .name = TYPE_IMX_I2C,
321 .parent = TYPE_SYS_BUS_DEVICE,
322 .instance_size = sizeof(IMXI2CState),
323 .class_init = imx_i2c_class_init,
324};
325
326static void imx_i2c_register_types(void)
327{
328 type_register_static(&imx_i2c_type_info);
329}
330
331type_init(imx_i2c_register_types)
332