1 /* 2 * TI OMAP on-chip I2C controller. Only "new I2C" mode supported. 3 * 4 * Copyright (C) 2007 Andrzej Zaborowski <balrog@zabor.org> 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License as 8 * published by the Free Software Foundation; either version 2 of 9 * the License, or (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License 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 #include "qemu/osdep.h" 20 #include "hw/hw.h" 21 #include "hw/i2c/i2c.h" 22 #include "hw/arm/omap.h" 23 #include "hw/sysbus.h" 24 #include "qemu/error-report.h" 25 26 #define TYPE_OMAP_I2C "omap_i2c" 27 #define OMAP_I2C(obj) OBJECT_CHECK(OMAPI2CState, (obj), TYPE_OMAP_I2C) 28 29 typedef struct OMAPI2CState { 30 SysBusDevice parent_obj; 31 32 MemoryRegion iomem; 33 qemu_irq irq; 34 qemu_irq drq[2]; 35 I2CBus *bus; 36 37 uint8_t revision; 38 void *iclk; 39 void *fclk; 40 41 uint8_t mask; 42 uint16_t stat; 43 uint16_t dma; 44 uint16_t count; 45 int count_cur; 46 uint32_t fifo; 47 int rxlen; 48 int txlen; 49 uint16_t control; 50 uint16_t addr[2]; 51 uint8_t divider; 52 uint8_t times[2]; 53 uint16_t test; 54 } OMAPI2CState; 55 56 #define OMAP2_INTR_REV 0x34 57 #define OMAP2_GC_REV 0x34 58 59 static void omap_i2c_interrupts_update(OMAPI2CState *s) 60 { 61 qemu_set_irq(s->irq, s->stat & s->mask); 62 if ((s->dma >> 15) & 1) /* RDMA_EN */ 63 qemu_set_irq(s->drq[0], (s->stat >> 3) & 1); /* RRDY */ 64 if ((s->dma >> 7) & 1) /* XDMA_EN */ 65 qemu_set_irq(s->drq[1], (s->stat >> 4) & 1); /* XRDY */ 66 } 67 68 static void omap_i2c_fifo_run(OMAPI2CState *s) 69 { 70 int ack = 1; 71 72 if (!i2c_bus_busy(s->bus)) 73 return; 74 75 if ((s->control >> 2) & 1) { /* RM */ 76 if ((s->control >> 1) & 1) { /* STP */ 77 i2c_end_transfer(s->bus); 78 s->control &= ~(1 << 1); /* STP */ 79 s->count_cur = s->count; 80 s->txlen = 0; 81 } else if ((s->control >> 9) & 1) { /* TRX */ 82 while (ack && s->txlen) 83 ack = (i2c_send(s->bus, 84 (s->fifo >> ((-- s->txlen) << 3)) & 85 0xff) >= 0); 86 s->stat |= 1 << 4; /* XRDY */ 87 } else { 88 while (s->rxlen < 4) 89 s->fifo |= i2c_recv(s->bus) << ((s->rxlen ++) << 3); 90 s->stat |= 1 << 3; /* RRDY */ 91 } 92 } else { 93 if ((s->control >> 9) & 1) { /* TRX */ 94 while (ack && s->count_cur && s->txlen) { 95 ack = (i2c_send(s->bus, 96 (s->fifo >> ((-- s->txlen) << 3)) & 97 0xff) >= 0); 98 s->count_cur --; 99 } 100 if (ack && s->count_cur) 101 s->stat |= 1 << 4; /* XRDY */ 102 else 103 s->stat &= ~(1 << 4); /* XRDY */ 104 if (!s->count_cur) { 105 s->stat |= 1 << 2; /* ARDY */ 106 s->control &= ~(1 << 10); /* MST */ 107 } 108 } else { 109 while (s->count_cur && s->rxlen < 4) { 110 s->fifo |= i2c_recv(s->bus) << ((s->rxlen ++) << 3); 111 s->count_cur --; 112 } 113 if (s->rxlen) 114 s->stat |= 1 << 3; /* RRDY */ 115 else 116 s->stat &= ~(1 << 3); /* RRDY */ 117 } 118 if (!s->count_cur) { 119 if ((s->control >> 1) & 1) { /* STP */ 120 i2c_end_transfer(s->bus); 121 s->control &= ~(1 << 1); /* STP */ 122 s->count_cur = s->count; 123 s->txlen = 0; 124 } else { 125 s->stat |= 1 << 2; /* ARDY */ 126 s->control &= ~(1 << 10); /* MST */ 127 } 128 } 129 } 130 131 s->stat |= (!ack) << 1; /* NACK */ 132 if (!ack) 133 s->control &= ~(1 << 1); /* STP */ 134 } 135 136 static void omap_i2c_reset(DeviceState *dev) 137 { 138 OMAPI2CState *s = OMAP_I2C(dev); 139 140 s->mask = 0; 141 s->stat = 0; 142 s->dma = 0; 143 s->count = 0; 144 s->count_cur = 0; 145 s->fifo = 0; 146 s->rxlen = 0; 147 s->txlen = 0; 148 s->control = 0; 149 s->addr[0] = 0; 150 s->addr[1] = 0; 151 s->divider = 0; 152 s->times[0] = 0; 153 s->times[1] = 0; 154 s->test = 0; 155 } 156 157 static uint32_t omap_i2c_read(void *opaque, hwaddr addr) 158 { 159 OMAPI2CState *s = opaque; 160 int offset = addr & OMAP_MPUI_REG_MASK; 161 uint16_t ret; 162 163 switch (offset) { 164 case 0x00: /* I2C_REV */ 165 return s->revision; /* REV */ 166 167 case 0x04: /* I2C_IE */ 168 return s->mask; 169 170 case 0x08: /* I2C_STAT */ 171 return s->stat | (i2c_bus_busy(s->bus) << 12); 172 173 case 0x0c: /* I2C_IV */ 174 if (s->revision >= OMAP2_INTR_REV) 175 break; 176 ret = ctz32(s->stat & s->mask); 177 if (ret != 32) { 178 s->stat ^= 1 << ret; 179 ret++; 180 } else { 181 ret = 0; 182 } 183 omap_i2c_interrupts_update(s); 184 return ret; 185 186 case 0x10: /* I2C_SYSS */ 187 return (s->control >> 15) & 1; /* I2C_EN */ 188 189 case 0x14: /* I2C_BUF */ 190 return s->dma; 191 192 case 0x18: /* I2C_CNT */ 193 return s->count_cur; /* DCOUNT */ 194 195 case 0x1c: /* I2C_DATA */ 196 ret = 0; 197 if (s->control & (1 << 14)) { /* BE */ 198 ret |= ((s->fifo >> 0) & 0xff) << 8; 199 ret |= ((s->fifo >> 8) & 0xff) << 0; 200 } else { 201 ret |= ((s->fifo >> 8) & 0xff) << 8; 202 ret |= ((s->fifo >> 0) & 0xff) << 0; 203 } 204 if (s->rxlen == 1) { 205 s->stat |= 1 << 15; /* SBD */ 206 s->rxlen = 0; 207 } else if (s->rxlen > 1) { 208 if (s->rxlen > 2) 209 s->fifo >>= 16; 210 s->rxlen -= 2; 211 } else { 212 /* XXX: remote access (qualifier) error - what's that? */ 213 } 214 if (!s->rxlen) { 215 s->stat &= ~(1 << 3); /* RRDY */ 216 if (((s->control >> 10) & 1) && /* MST */ 217 ((~s->control >> 9) & 1)) { /* TRX */ 218 s->stat |= 1 << 2; /* ARDY */ 219 s->control &= ~(1 << 10); /* MST */ 220 } 221 } 222 s->stat &= ~(1 << 11); /* ROVR */ 223 omap_i2c_fifo_run(s); 224 omap_i2c_interrupts_update(s); 225 return ret; 226 227 case 0x20: /* I2C_SYSC */ 228 return 0; 229 230 case 0x24: /* I2C_CON */ 231 return s->control; 232 233 case 0x28: /* I2C_OA */ 234 return s->addr[0]; 235 236 case 0x2c: /* I2C_SA */ 237 return s->addr[1]; 238 239 case 0x30: /* I2C_PSC */ 240 return s->divider; 241 242 case 0x34: /* I2C_SCLL */ 243 return s->times[0]; 244 245 case 0x38: /* I2C_SCLH */ 246 return s->times[1]; 247 248 case 0x3c: /* I2C_SYSTEST */ 249 if (s->test & (1 << 15)) { /* ST_EN */ 250 s->test ^= 0xa; 251 return s->test; 252 } else 253 return s->test & ~0x300f; 254 } 255 256 OMAP_BAD_REG(addr); 257 return 0; 258 } 259 260 static void omap_i2c_write(void *opaque, hwaddr addr, 261 uint32_t value) 262 { 263 OMAPI2CState *s = opaque; 264 int offset = addr & OMAP_MPUI_REG_MASK; 265 int nack; 266 267 switch (offset) { 268 case 0x00: /* I2C_REV */ 269 case 0x0c: /* I2C_IV */ 270 case 0x10: /* I2C_SYSS */ 271 OMAP_RO_REG(addr); 272 return; 273 274 case 0x04: /* I2C_IE */ 275 s->mask = value & (s->revision < OMAP2_GC_REV ? 0x1f : 0x3f); 276 break; 277 278 case 0x08: /* I2C_STAT */ 279 if (s->revision < OMAP2_INTR_REV) { 280 OMAP_RO_REG(addr); 281 return; 282 } 283 284 /* RRDY and XRDY are reset by hardware. (in all versions???) */ 285 s->stat &= ~(value & 0x27); 286 omap_i2c_interrupts_update(s); 287 break; 288 289 case 0x14: /* I2C_BUF */ 290 s->dma = value & 0x8080; 291 if (value & (1 << 15)) /* RDMA_EN */ 292 s->mask &= ~(1 << 3); /* RRDY_IE */ 293 if (value & (1 << 7)) /* XDMA_EN */ 294 s->mask &= ~(1 << 4); /* XRDY_IE */ 295 break; 296 297 case 0x18: /* I2C_CNT */ 298 s->count = value; /* DCOUNT */ 299 break; 300 301 case 0x1c: /* I2C_DATA */ 302 if (s->txlen > 2) { 303 /* XXX: remote access (qualifier) error - what's that? */ 304 break; 305 } 306 s->fifo <<= 16; 307 s->txlen += 2; 308 if (s->control & (1 << 14)) { /* BE */ 309 s->fifo |= ((value >> 8) & 0xff) << 8; 310 s->fifo |= ((value >> 0) & 0xff) << 0; 311 } else { 312 s->fifo |= ((value >> 0) & 0xff) << 8; 313 s->fifo |= ((value >> 8) & 0xff) << 0; 314 } 315 s->stat &= ~(1 << 10); /* XUDF */ 316 if (s->txlen > 2) 317 s->stat &= ~(1 << 4); /* XRDY */ 318 omap_i2c_fifo_run(s); 319 omap_i2c_interrupts_update(s); 320 break; 321 322 case 0x20: /* I2C_SYSC */ 323 if (s->revision < OMAP2_INTR_REV) { 324 OMAP_BAD_REG(addr); 325 return; 326 } 327 328 if (value & 2) { 329 omap_i2c_reset(DEVICE(s)); 330 } 331 break; 332 333 case 0x24: /* I2C_CON */ 334 s->control = value & 0xcf87; 335 if (~value & (1 << 15)) { /* I2C_EN */ 336 if (s->revision < OMAP2_INTR_REV) { 337 omap_i2c_reset(DEVICE(s)); 338 } 339 break; 340 } 341 if ((value & (1 << 15)) && !(value & (1 << 10))) { /* MST */ 342 fprintf(stderr, "%s: I^2C slave mode not supported\n", 343 __FUNCTION__); 344 break; 345 } 346 if ((value & (1 << 15)) && value & (1 << 8)) { /* XA */ 347 fprintf(stderr, "%s: 10-bit addressing mode not supported\n", 348 __FUNCTION__); 349 break; 350 } 351 if ((value & (1 << 15)) && value & (1 << 0)) { /* STT */ 352 nack = !!i2c_start_transfer(s->bus, s->addr[1], /* SA */ 353 (~value >> 9) & 1); /* TRX */ 354 s->stat |= nack << 1; /* NACK */ 355 s->control &= ~(1 << 0); /* STT */ 356 s->fifo = 0; 357 if (nack) 358 s->control &= ~(1 << 1); /* STP */ 359 else { 360 s->count_cur = s->count; 361 omap_i2c_fifo_run(s); 362 } 363 omap_i2c_interrupts_update(s); 364 } 365 break; 366 367 case 0x28: /* I2C_OA */ 368 s->addr[0] = value & 0x3ff; 369 break; 370 371 case 0x2c: /* I2C_SA */ 372 s->addr[1] = value & 0x3ff; 373 break; 374 375 case 0x30: /* I2C_PSC */ 376 s->divider = value; 377 break; 378 379 case 0x34: /* I2C_SCLL */ 380 s->times[0] = value; 381 break; 382 383 case 0x38: /* I2C_SCLH */ 384 s->times[1] = value; 385 break; 386 387 case 0x3c: /* I2C_SYSTEST */ 388 s->test = value & 0xf80f; 389 if (value & (1 << 11)) /* SBB */ 390 if (s->revision >= OMAP2_INTR_REV) { 391 s->stat |= 0x3f; 392 omap_i2c_interrupts_update(s); 393 } 394 if (value & (1 << 15)) /* ST_EN */ 395 fprintf(stderr, "%s: System Test not supported\n", __FUNCTION__); 396 break; 397 398 default: 399 OMAP_BAD_REG(addr); 400 return; 401 } 402 } 403 404 static void omap_i2c_writeb(void *opaque, hwaddr addr, 405 uint32_t value) 406 { 407 OMAPI2CState *s = opaque; 408 int offset = addr & OMAP_MPUI_REG_MASK; 409 410 switch (offset) { 411 case 0x1c: /* I2C_DATA */ 412 if (s->txlen > 2) { 413 /* XXX: remote access (qualifier) error - what's that? */ 414 break; 415 } 416 s->fifo <<= 8; 417 s->txlen += 1; 418 s->fifo |= value & 0xff; 419 s->stat &= ~(1 << 10); /* XUDF */ 420 if (s->txlen > 2) 421 s->stat &= ~(1 << 4); /* XRDY */ 422 omap_i2c_fifo_run(s); 423 omap_i2c_interrupts_update(s); 424 break; 425 426 default: 427 OMAP_BAD_REG(addr); 428 return; 429 } 430 } 431 432 static const MemoryRegionOps omap_i2c_ops = { 433 .old_mmio = { 434 .read = { 435 omap_badwidth_read16, 436 omap_i2c_read, 437 omap_badwidth_read16, 438 }, 439 .write = { 440 omap_i2c_writeb, /* Only the last fifo write can be 8 bit. */ 441 omap_i2c_write, 442 omap_badwidth_write16, 443 }, 444 }, 445 .endianness = DEVICE_NATIVE_ENDIAN, 446 }; 447 448 static int omap_i2c_init(SysBusDevice *sbd) 449 { 450 DeviceState *dev = DEVICE(sbd); 451 OMAPI2CState *s = OMAP_I2C(dev); 452 453 if (!s->fclk) { 454 error_report("omap_i2c: fclk not connected"); 455 return -1; 456 } 457 if (s->revision >= OMAP2_INTR_REV && !s->iclk) { 458 /* Note that OMAP1 doesn't have a separate interface clock */ 459 error_report("omap_i2c: iclk not connected"); 460 return -1; 461 } 462 463 sysbus_init_irq(sbd, &s->irq); 464 sysbus_init_irq(sbd, &s->drq[0]); 465 sysbus_init_irq(sbd, &s->drq[1]); 466 memory_region_init_io(&s->iomem, OBJECT(s), &omap_i2c_ops, s, "omap.i2c", 467 (s->revision < OMAP2_INTR_REV) ? 0x800 : 0x1000); 468 sysbus_init_mmio(sbd, &s->iomem); 469 s->bus = i2c_init_bus(dev, NULL); 470 return 0; 471 } 472 473 static Property omap_i2c_properties[] = { 474 DEFINE_PROP_UINT8("revision", OMAPI2CState, revision, 0), 475 DEFINE_PROP_PTR("iclk", OMAPI2CState, iclk), 476 DEFINE_PROP_PTR("fclk", OMAPI2CState, fclk), 477 DEFINE_PROP_END_OF_LIST(), 478 }; 479 480 static void omap_i2c_class_init(ObjectClass *klass, void *data) 481 { 482 DeviceClass *dc = DEVICE_CLASS(klass); 483 SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); 484 k->init = omap_i2c_init; 485 dc->props = omap_i2c_properties; 486 dc->reset = omap_i2c_reset; 487 /* Reason: pointer properties "iclk", "fclk" */ 488 dc->cannot_instantiate_with_device_add_yet = true; 489 } 490 491 static const TypeInfo omap_i2c_info = { 492 .name = TYPE_OMAP_I2C, 493 .parent = TYPE_SYS_BUS_DEVICE, 494 .instance_size = sizeof(OMAPI2CState), 495 .class_init = omap_i2c_class_init, 496 }; 497 498 static void omap_i2c_register_types(void) 499 { 500 type_register_static(&omap_i2c_info); 501 } 502 503 I2CBus *omap_i2c_bus(DeviceState *omap_i2c) 504 { 505 OMAPI2CState *s = OMAP_I2C(omap_i2c); 506 return s->bus; 507 } 508 509 type_init(omap_i2c_register_types) 510