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