1 /*
2 * i.MX I2C Bus Serial Interface Emulation
3 *
4 * Copyright (C) 2013 Jean-Christophe Dubois. <jcd@tribudubois.net>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, see <http://www.gnu.org/licenses/>.
18 *
19 */
20
21 #include "qemu/osdep.h"
22 #include "hw/i2c/imx_i2c.h"
23 #include "hw/irq.h"
24 #include "migration/vmstate.h"
25 #include "hw/i2c/i2c.h"
26 #include "qemu/log.h"
27 #include "qemu/module.h"
28 #include "trace.h"
29
imx_i2c_get_regname(unsigned offset)30 static const char *imx_i2c_get_regname(unsigned offset)
31 {
32 switch (offset) {
33 case IADR_ADDR:
34 return "IADR";
35 case IFDR_ADDR:
36 return "IFDR";
37 case I2CR_ADDR:
38 return "I2CR";
39 case I2SR_ADDR:
40 return "I2SR";
41 case I2DR_ADDR:
42 return "I2DR";
43 default:
44 return "[?]";
45 }
46 }
47
imx_i2c_is_enabled(IMXI2CState * s)48 static inline bool imx_i2c_is_enabled(IMXI2CState *s)
49 {
50 return s->i2cr & I2CR_IEN;
51 }
52
imx_i2c_interrupt_is_enabled(IMXI2CState * s)53 static inline bool imx_i2c_interrupt_is_enabled(IMXI2CState *s)
54 {
55 return s->i2cr & I2CR_IIEN;
56 }
57
imx_i2c_is_master(IMXI2CState * s)58 static inline bool imx_i2c_is_master(IMXI2CState *s)
59 {
60 return s->i2cr & I2CR_MSTA;
61 }
62
imx_i2c_reset(DeviceState * dev)63 static void imx_i2c_reset(DeviceState *dev)
64 {
65 IMXI2CState *s = IMX_I2C(dev);
66
67 if (s->address != ADDR_RESET) {
68 i2c_end_transfer(s->bus);
69 }
70
71 s->address = ADDR_RESET;
72 s->iadr = IADR_RESET;
73 s->ifdr = IFDR_RESET;
74 s->i2cr = I2CR_RESET;
75 s->i2sr = I2SR_RESET;
76 s->i2dr_read = I2DR_RESET;
77 s->i2dr_write = I2DR_RESET;
78 }
79
imx_i2c_raise_interrupt(IMXI2CState * s)80 static inline void imx_i2c_raise_interrupt(IMXI2CState *s)
81 {
82 if (imx_i2c_is_enabled(s)) {
83 s->i2sr |= I2SR_IIF;
84
85 if (imx_i2c_interrupt_is_enabled(s)) {
86 qemu_irq_raise(s->irq);
87 }
88 }
89 }
90
imx_i2c_read(void * opaque,hwaddr offset,unsigned size)91 static uint64_t imx_i2c_read(void *opaque, hwaddr offset,
92 unsigned size)
93 {
94 uint16_t value;
95 IMXI2CState *s = IMX_I2C(opaque);
96
97 switch (offset) {
98 case IADR_ADDR:
99 value = s->iadr;
100 break;
101 case IFDR_ADDR:
102 value = s->ifdr;
103 break;
104 case I2CR_ADDR:
105 value = s->i2cr;
106 break;
107 case I2SR_ADDR:
108 value = s->i2sr;
109 break;
110 case I2DR_ADDR:
111 value = s->i2dr_read;
112
113 if (imx_i2c_is_master(s)) {
114 uint8_t ret = 0xff;
115
116 if (s->address == ADDR_RESET) {
117 /* something is wrong as the address is not set */
118 qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Trying to read "
119 "without specifying the slave address\n",
120 TYPE_IMX_I2C, __func__);
121 } else if (s->i2cr & I2CR_MTX) {
122 qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Trying to read "
123 "but MTX is set\n", TYPE_IMX_I2C, __func__);
124 } else {
125 /* get the next byte */
126 ret = i2c_recv(s->bus);
127 imx_i2c_raise_interrupt(s);
128 }
129
130 s->i2dr_read = ret;
131 } else {
132 qemu_log_mask(LOG_UNIMP, "[%s]%s: slave mode not implemented\n",
133 TYPE_IMX_I2C, __func__);
134 }
135 break;
136 default:
137 qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad address at offset 0x%"
138 HWADDR_PRIx "\n", TYPE_IMX_I2C, __func__, offset);
139 value = 0;
140 break;
141 }
142
143 trace_imx_i2c_read(DEVICE(s)->canonical_path, imx_i2c_get_regname(offset),
144 offset, value);
145
146 return (uint64_t)value;
147 }
148
imx_i2c_write(void * opaque,hwaddr offset,uint64_t value,unsigned size)149 static void imx_i2c_write(void *opaque, hwaddr offset,
150 uint64_t value, unsigned size)
151 {
152 IMXI2CState *s = IMX_I2C(opaque);
153
154 trace_imx_i2c_read(DEVICE(s)->canonical_path, imx_i2c_get_regname(offset),
155 offset, value);
156
157 value &= 0xff;
158
159 switch (offset) {
160 case IADR_ADDR:
161 s->iadr = value & IADR_MASK;
162 /* i2c_slave_set_address(s->bus, (uint8_t)s->iadr); */
163 break;
164 case IFDR_ADDR:
165 s->ifdr = value & IFDR_MASK;
166 break;
167 case I2CR_ADDR:
168 if (imx_i2c_is_enabled(s) && ((value & I2CR_IEN) == 0)) {
169 /* This is a soft reset. IADR is preserved during soft resets */
170 uint16_t iadr = s->iadr;
171 imx_i2c_reset(DEVICE(s));
172 s->iadr = iadr;
173 } else { /* normal write */
174 s->i2cr = value & I2CR_MASK;
175
176 if (imx_i2c_is_master(s)) {
177 /* set the bus to busy */
178 s->i2sr |= I2SR_IBB;
179 } else { /* slave mode */
180 /* bus is not busy anymore */
181 s->i2sr &= ~I2SR_IBB;
182
183 /*
184 * if we unset the master mode then it ends the ongoing
185 * transfer if any
186 */
187 if (s->address != ADDR_RESET) {
188 i2c_end_transfer(s->bus);
189 s->address = ADDR_RESET;
190 }
191 }
192
193 if (s->i2cr & I2CR_RSTA) { /* Restart */
194 /* if this is a restart then it ends the ongoing transfer */
195 if (s->address != ADDR_RESET) {
196 i2c_end_transfer(s->bus);
197 s->address = ADDR_RESET;
198 s->i2cr &= ~I2CR_RSTA;
199 }
200 }
201 }
202 break;
203 case I2SR_ADDR:
204 /*
205 * if the user writes 0 to IIF then lower the interrupt and
206 * reset the bit
207 */
208 if ((s->i2sr & I2SR_IIF) && !(value & I2SR_IIF)) {
209 s->i2sr &= ~I2SR_IIF;
210 qemu_irq_lower(s->irq);
211 }
212
213 /*
214 * if the user writes 0 to IAL, reset the bit
215 */
216 if ((s->i2sr & I2SR_IAL) && !(value & I2SR_IAL)) {
217 s->i2sr &= ~I2SR_IAL;
218 }
219
220 break;
221 case I2DR_ADDR:
222 /* if the device is not enabled, nothing to do */
223 if (!imx_i2c_is_enabled(s)) {
224 break;
225 }
226
227 s->i2dr_write = value & I2DR_MASK;
228
229 if (imx_i2c_is_master(s)) {
230 /* If this is the first write cycle then it is the slave addr */
231 if (s->address == ADDR_RESET) {
232 if (i2c_start_transfer(s->bus, extract32(s->i2dr_write, 1, 7),
233 extract32(s->i2dr_write, 0, 1))) {
234 /* if non zero is returned, the address is not valid */
235 s->i2sr |= I2SR_RXAK;
236 } else {
237 s->address = s->i2dr_write;
238 s->i2sr &= ~I2SR_RXAK;
239 imx_i2c_raise_interrupt(s);
240 }
241 } else { /* This is a normal data write */
242 if (i2c_send(s->bus, s->i2dr_write)) {
243 /* if the target return non zero then end the transfer */
244 s->i2sr |= I2SR_RXAK;
245 s->address = ADDR_RESET;
246 i2c_end_transfer(s->bus);
247 } else {
248 s->i2sr &= ~I2SR_RXAK;
249 imx_i2c_raise_interrupt(s);
250 }
251 }
252 } else {
253 qemu_log_mask(LOG_UNIMP, "[%s]%s: slave mode not implemented\n",
254 TYPE_IMX_I2C, __func__);
255 }
256 break;
257 default:
258 qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad address at offset 0x%"
259 HWADDR_PRIx "\n", TYPE_IMX_I2C, __func__, offset);
260 break;
261 }
262 }
263
264 static const MemoryRegionOps imx_i2c_ops = {
265 .read = imx_i2c_read,
266 .write = imx_i2c_write,
267 .valid.min_access_size = 1,
268 .valid.max_access_size = 2,
269 .endianness = DEVICE_NATIVE_ENDIAN,
270 };
271
272 static const VMStateDescription imx_i2c_vmstate = {
273 .name = TYPE_IMX_I2C,
274 .version_id = 1,
275 .minimum_version_id = 1,
276 .fields = (const VMStateField[]) {
277 VMSTATE_UINT16(address, IMXI2CState),
278 VMSTATE_UINT16(iadr, IMXI2CState),
279 VMSTATE_UINT16(ifdr, IMXI2CState),
280 VMSTATE_UINT16(i2cr, IMXI2CState),
281 VMSTATE_UINT16(i2sr, IMXI2CState),
282 VMSTATE_UINT16(i2dr_read, IMXI2CState),
283 VMSTATE_UINT16(i2dr_write, IMXI2CState),
284 VMSTATE_END_OF_LIST()
285 }
286 };
287
imx_i2c_realize(DeviceState * dev,Error ** errp)288 static void imx_i2c_realize(DeviceState *dev, Error **errp)
289 {
290 IMXI2CState *s = IMX_I2C(dev);
291
292 memory_region_init_io(&s->iomem, OBJECT(s), &imx_i2c_ops, s, TYPE_IMX_I2C,
293 IMX_I2C_MEM_SIZE);
294 sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
295 sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq);
296 s->bus = i2c_init_bus(dev, NULL);
297 }
298
imx_i2c_class_init(ObjectClass * klass,const void * data)299 static void imx_i2c_class_init(ObjectClass *klass, const void *data)
300 {
301 DeviceClass *dc = DEVICE_CLASS(klass);
302
303 dc->vmsd = &imx_i2c_vmstate;
304 device_class_set_legacy_reset(dc, imx_i2c_reset);
305 dc->realize = imx_i2c_realize;
306 dc->desc = "i.MX I2C Controller";
307 }
308
309 static const TypeInfo imx_i2c_type_info = {
310 .name = TYPE_IMX_I2C,
311 .parent = TYPE_SYS_BUS_DEVICE,
312 .instance_size = sizeof(IMXI2CState),
313 .class_init = imx_i2c_class_init,
314 };
315
imx_i2c_register_types(void)316 static void imx_i2c_register_types(void)
317 {
318 type_register_static(&imx_i2c_type_info);
319 }
320
321 type_init(imx_i2c_register_types)
322