1 | /* |
2 | * Copyright (C) 2014 Freescale Semiconductor, Inc. All rights reserved. |
3 | * |
4 | * Author: Amit Tomar, <Amit.Tomar@freescale.com> |
5 | * |
6 | * Description: |
7 | * This file is derived from IMX I2C controller, |
8 | * by Jean-Christophe DUBOIS . |
9 | * |
10 | * Thanks to Scott Wood and Alexander Graf for their kind help on this. |
11 | * |
12 | * This program is free software; you can redistribute it and/or modify |
13 | * it under the terms of the GNU General Public License, version 2 or later, |
14 | * as published by the Free Software Foundation. |
15 | * |
16 | * You should have received a copy of the GNU Lesser General Public |
17 | * License along with this library; if not, see <http://www.gnu.org/licenses/>. |
18 | */ |
19 | |
20 | #include "qemu/osdep.h" |
21 | #include "hw/i2c/i2c.h" |
22 | #include "hw/irq.h" |
23 | #include "qemu/log.h" |
24 | #include "qemu/module.h" |
25 | #include "hw/sysbus.h" |
26 | #include "migration/vmstate.h" |
27 | |
28 | /* #define DEBUG_I2C */ |
29 | |
30 | #ifdef DEBUG_I2C |
31 | #define DPRINTF(fmt, ...) \ |
32 | do { fprintf(stderr, "mpc_i2c[%s]: " fmt, __func__, ## __VA_ARGS__); \ |
33 | } while (0) |
34 | #else |
35 | #define DPRINTF(fmt, ...) do {} while (0) |
36 | #endif |
37 | |
38 | #define TYPE_MPC_I2C "mpc-i2c" |
39 | #define MPC_I2C(obj) \ |
40 | OBJECT_CHECK(MPCI2CState, (obj), TYPE_MPC_I2C) |
41 | |
42 | #define MPC_I2C_ADR 0x00 |
43 | #define MPC_I2C_FDR 0x04 |
44 | #define MPC_I2C_CR 0x08 |
45 | #define MPC_I2C_SR 0x0c |
46 | #define MPC_I2C_DR 0x10 |
47 | #define MPC_I2C_DFSRR 0x14 |
48 | |
49 | #define CCR_MEN (1 << 7) |
50 | #define CCR_MIEN (1 << 6) |
51 | #define CCR_MSTA (1 << 5) |
52 | #define CCR_MTX (1 << 4) |
53 | #define CCR_TXAK (1 << 3) |
54 | #define CCR_RSTA (1 << 2) |
55 | #define CCR_BCST (1 << 0) |
56 | |
57 | #define CSR_MCF (1 << 7) |
58 | #define CSR_MAAS (1 << 6) |
59 | #define CSR_MBB (1 << 5) |
60 | #define CSR_MAL (1 << 4) |
61 | #define CSR_SRW (1 << 2) |
62 | #define CSR_MIF (1 << 1) |
63 | #define CSR_RXAK (1 << 0) |
64 | |
65 | #define CADR_MASK 0xFE |
66 | #define CFDR_MASK 0x3F |
67 | #define CCR_MASK 0xFC |
68 | #define CSR_MASK 0xED |
69 | #define CDR_MASK 0xFF |
70 | |
71 | #define CYCLE_RESET 0xFF |
72 | |
73 | typedef struct MPCI2CState { |
74 | SysBusDevice parent_obj; |
75 | |
76 | I2CBus *bus; |
77 | qemu_irq irq; |
78 | MemoryRegion iomem; |
79 | |
80 | uint8_t address; |
81 | uint8_t adr; |
82 | uint8_t fdr; |
83 | uint8_t cr; |
84 | uint8_t sr; |
85 | uint8_t dr; |
86 | uint8_t dfssr; |
87 | } MPCI2CState; |
88 | |
89 | static bool mpc_i2c_is_enabled(MPCI2CState *s) |
90 | { |
91 | return s->cr & CCR_MEN; |
92 | } |
93 | |
94 | static bool mpc_i2c_is_master(MPCI2CState *s) |
95 | { |
96 | return s->cr & CCR_MSTA; |
97 | } |
98 | |
99 | static bool mpc_i2c_direction_is_tx(MPCI2CState *s) |
100 | { |
101 | return s->cr & CCR_MTX; |
102 | } |
103 | |
104 | static bool mpc_i2c_irq_pending(MPCI2CState *s) |
105 | { |
106 | return s->sr & CSR_MIF; |
107 | } |
108 | |
109 | static bool mpc_i2c_irq_is_enabled(MPCI2CState *s) |
110 | { |
111 | return s->cr & CCR_MIEN; |
112 | } |
113 | |
114 | static void mpc_i2c_reset(DeviceState *dev) |
115 | { |
116 | MPCI2CState *i2c = MPC_I2C(dev); |
117 | |
118 | i2c->address = 0xFF; |
119 | i2c->adr = 0x00; |
120 | i2c->fdr = 0x00; |
121 | i2c->cr = 0x00; |
122 | i2c->sr = 0x81; |
123 | i2c->dr = 0x00; |
124 | } |
125 | |
126 | static void mpc_i2c_irq(MPCI2CState *s) |
127 | { |
128 | bool irq_active = false; |
129 | |
130 | if (mpc_i2c_is_enabled(s) && mpc_i2c_irq_is_enabled(s) |
131 | && mpc_i2c_irq_pending(s)) { |
132 | irq_active = true; |
133 | } |
134 | |
135 | if (irq_active) { |
136 | qemu_irq_raise(s->irq); |
137 | } else { |
138 | qemu_irq_lower(s->irq); |
139 | } |
140 | } |
141 | |
142 | static void mpc_i2c_soft_reset(MPCI2CState *s) |
143 | { |
144 | /* This is a soft reset. ADR is preserved during soft resets */ |
145 | uint8_t adr = s->adr; |
146 | mpc_i2c_reset(DEVICE(s)); |
147 | s->adr = adr; |
148 | } |
149 | |
150 | static void mpc_i2c_address_send(MPCI2CState *s) |
151 | { |
152 | /* if returns non zero slave address is not right */ |
153 | if (i2c_start_transfer(s->bus, s->dr >> 1, s->dr & (0x01))) { |
154 | s->sr |= CSR_RXAK; |
155 | } else { |
156 | s->address = s->dr; |
157 | s->sr &= ~CSR_RXAK; |
158 | s->sr |= CSR_MCF; /* Set after Byte Transfer is completed */ |
159 | s->sr |= CSR_MIF; /* Set after Byte Transfer is completed */ |
160 | mpc_i2c_irq(s); |
161 | } |
162 | } |
163 | |
164 | static void mpc_i2c_data_send(MPCI2CState *s) |
165 | { |
166 | if (i2c_send(s->bus, s->dr)) { |
167 | /* End of transfer */ |
168 | s->sr |= CSR_RXAK; |
169 | i2c_end_transfer(s->bus); |
170 | } else { |
171 | s->sr &= ~CSR_RXAK; |
172 | s->sr |= CSR_MCF; /* Set after Byte Transfer is completed */ |
173 | s->sr |= CSR_MIF; /* Set after Byte Transfer is completed */ |
174 | mpc_i2c_irq(s); |
175 | } |
176 | } |
177 | |
178 | static void mpc_i2c_data_recive(MPCI2CState *s) |
179 | { |
180 | int ret; |
181 | /* get the next byte */ |
182 | ret = i2c_recv(s->bus); |
183 | if (ret >= 0) { |
184 | s->sr |= CSR_MCF; /* Set after Byte Transfer is completed */ |
185 | s->sr |= CSR_MIF; /* Set after Byte Transfer is completed */ |
186 | mpc_i2c_irq(s); |
187 | } else { |
188 | DPRINTF("read failed for device" ); |
189 | ret = 0xff; |
190 | } |
191 | s->dr = ret; |
192 | } |
193 | |
194 | static uint64_t mpc_i2c_read(void *opaque, hwaddr addr, unsigned size) |
195 | { |
196 | MPCI2CState *s = opaque; |
197 | uint8_t value; |
198 | |
199 | switch (addr) { |
200 | case MPC_I2C_ADR: |
201 | value = s->adr; |
202 | break; |
203 | case MPC_I2C_FDR: |
204 | value = s->fdr; |
205 | break; |
206 | case MPC_I2C_CR: |
207 | value = s->cr; |
208 | break; |
209 | case MPC_I2C_SR: |
210 | value = s->sr; |
211 | break; |
212 | case MPC_I2C_DR: |
213 | value = s->dr; |
214 | if (mpc_i2c_is_master(s)) { /* master mode */ |
215 | if (mpc_i2c_direction_is_tx(s)) { |
216 | DPRINTF("MTX is set not in recv mode\n" ); |
217 | } else { |
218 | mpc_i2c_data_recive(s); |
219 | } |
220 | } |
221 | break; |
222 | default: |
223 | value = 0; |
224 | DPRINTF("ERROR: Bad read addr 0x%x\n" , (unsigned int)addr); |
225 | break; |
226 | } |
227 | |
228 | DPRINTF("%s: addr " TARGET_FMT_plx " %02" PRIx32 "\n" , __func__, |
229 | addr, value); |
230 | return (uint64_t)value; |
231 | } |
232 | |
233 | static void mpc_i2c_write(void *opaque, hwaddr addr, |
234 | uint64_t value, unsigned size) |
235 | { |
236 | MPCI2CState *s = opaque; |
237 | |
238 | DPRINTF("%s: addr " TARGET_FMT_plx " val %08" PRIx64 "\n" , __func__, |
239 | addr, value); |
240 | switch (addr) { |
241 | case MPC_I2C_ADR: |
242 | s->adr = value & CADR_MASK; |
243 | break; |
244 | case MPC_I2C_FDR: |
245 | s->fdr = value & CFDR_MASK; |
246 | break; |
247 | case MPC_I2C_CR: |
248 | if (mpc_i2c_is_enabled(s) && ((value & CCR_MEN) == 0)) { |
249 | mpc_i2c_soft_reset(s); |
250 | break; |
251 | } |
252 | /* normal write */ |
253 | s->cr = value & CCR_MASK; |
254 | if (mpc_i2c_is_master(s)) { /* master mode */ |
255 | /* set the bus to busy after master is set as per RM */ |
256 | s->sr |= CSR_MBB; |
257 | } else { |
258 | /* bus is not busy anymore */ |
259 | s->sr &= ~CSR_MBB; |
260 | /* Reset the address for fresh write/read cycle */ |
261 | if (s->address != CYCLE_RESET) { |
262 | i2c_end_transfer(s->bus); |
263 | s->address = CYCLE_RESET; |
264 | } |
265 | } |
266 | /* For restart end the onging transfer */ |
267 | if (s->cr & CCR_RSTA) { |
268 | if (s->address != CYCLE_RESET) { |
269 | s->address = CYCLE_RESET; |
270 | i2c_end_transfer(s->bus); |
271 | s->cr &= ~CCR_RSTA; |
272 | } |
273 | } |
274 | break; |
275 | case MPC_I2C_SR: |
276 | s->sr = value & CSR_MASK; |
277 | /* Lower the interrupt */ |
278 | if (!(s->sr & CSR_MIF) || !(s->sr & CSR_MAL)) { |
279 | mpc_i2c_irq(s); |
280 | } |
281 | break; |
282 | case MPC_I2C_DR: |
283 | /* if the device is not enabled, nothing to do */ |
284 | if (!mpc_i2c_is_enabled(s)) { |
285 | break; |
286 | } |
287 | s->dr = value & CDR_MASK; |
288 | if (mpc_i2c_is_master(s)) { /* master mode */ |
289 | if (s->address == CYCLE_RESET) { |
290 | mpc_i2c_address_send(s); |
291 | } else { |
292 | mpc_i2c_data_send(s); |
293 | } |
294 | } |
295 | break; |
296 | case MPC_I2C_DFSRR: |
297 | s->dfssr = value; |
298 | break; |
299 | default: |
300 | DPRINTF("ERROR: Bad write addr 0x%x\n" , (unsigned int)addr); |
301 | break; |
302 | } |
303 | } |
304 | |
305 | static const MemoryRegionOps i2c_ops = { |
306 | .read = mpc_i2c_read, |
307 | .write = mpc_i2c_write, |
308 | .valid.max_access_size = 1, |
309 | .endianness = DEVICE_NATIVE_ENDIAN, |
310 | }; |
311 | |
312 | static const VMStateDescription mpc_i2c_vmstate = { |
313 | .name = TYPE_MPC_I2C, |
314 | .version_id = 1, |
315 | .minimum_version_id = 1, |
316 | .fields = (VMStateField[]) { |
317 | VMSTATE_UINT8(address, MPCI2CState), |
318 | VMSTATE_UINT8(adr, MPCI2CState), |
319 | VMSTATE_UINT8(fdr, MPCI2CState), |
320 | VMSTATE_UINT8(cr, MPCI2CState), |
321 | VMSTATE_UINT8(sr, MPCI2CState), |
322 | VMSTATE_UINT8(dr, MPCI2CState), |
323 | VMSTATE_UINT8(dfssr, MPCI2CState), |
324 | VMSTATE_END_OF_LIST() |
325 | } |
326 | }; |
327 | |
328 | static void mpc_i2c_realize(DeviceState *dev, Error **errp) |
329 | { |
330 | MPCI2CState *i2c = MPC_I2C(dev); |
331 | sysbus_init_irq(SYS_BUS_DEVICE(dev), &i2c->irq); |
332 | memory_region_init_io(&i2c->iomem, OBJECT(i2c), &i2c_ops, i2c, |
333 | "mpc-i2c" , 0x14); |
334 | sysbus_init_mmio(SYS_BUS_DEVICE(dev), &i2c->iomem); |
335 | i2c->bus = i2c_init_bus(DEVICE(dev), "i2c" ); |
336 | } |
337 | |
338 | static void mpc_i2c_class_init(ObjectClass *klass, void *data) |
339 | { |
340 | DeviceClass *dc = DEVICE_CLASS(klass); |
341 | |
342 | dc->vmsd = &mpc_i2c_vmstate ; |
343 | dc->reset = mpc_i2c_reset; |
344 | dc->realize = mpc_i2c_realize; |
345 | dc->desc = "MPC I2C Controller" ; |
346 | } |
347 | |
348 | static const TypeInfo mpc_i2c_type_info = { |
349 | .name = TYPE_MPC_I2C, |
350 | .parent = TYPE_SYS_BUS_DEVICE, |
351 | .instance_size = sizeof(MPCI2CState), |
352 | .class_init = mpc_i2c_class_init, |
353 | }; |
354 | |
355 | static void mpc_i2c_register_types(void) |
356 | { |
357 | type_register_static(&mpc_i2c_type_info); |
358 | } |
359 | |
360 | type_init(mpc_i2c_register_types) |
361 | |