1 /* 2 * QEMU TEWS TPCI200 IndustryPack carrier emulation 3 * 4 * Copyright (C) 2012 Igalia, S.L. 5 * Author: Alberto Garcia <berto@igalia.com> 6 * 7 * This code is licensed under the GNU GPL v2 or (at your option) any 8 * later version. 9 */ 10 11 #include "qemu/osdep.h" 12 #include "qemu/units.h" 13 #include "hw/ipack/ipack.h" 14 #include "hw/pci/pci.h" 15 #include "qemu/bitops.h" 16 17 /* #define DEBUG_TPCI */ 18 19 #ifdef DEBUG_TPCI 20 #define DPRINTF(fmt, ...) \ 21 do { fprintf(stderr, "TPCI200: " fmt, ## __VA_ARGS__); } while (0) 22 #else 23 #define DPRINTF(fmt, ...) do { } while (0) 24 #endif 25 26 #define N_MODULES 4 27 28 #define IP_ID_SPACE 2 29 #define IP_INT_SPACE 3 30 #define IP_IO_SPACE_ADDR_MASK 0x7F 31 #define IP_ID_SPACE_ADDR_MASK 0x3F 32 #define IP_INT_SPACE_ADDR_MASK 0x3F 33 34 #define STATUS_INT(IP, INTNO) BIT((IP) * 2 + (INTNO)) 35 #define STATUS_TIME(IP) BIT((IP) + 12) 36 #define STATUS_ERR_ANY 0xF00 37 38 #define CTRL_CLKRATE BIT(0) 39 #define CTRL_RECOVER BIT(1) 40 #define CTRL_TIME_INT BIT(2) 41 #define CTRL_ERR_INT BIT(3) 42 #define CTRL_INT_EDGE(INTNO) BIT(4 + (INTNO)) 43 #define CTRL_INT(INTNO) BIT(6 + (INTNO)) 44 45 #define REG_REV_ID 0x00 46 #define REG_IP_A_CTRL 0x02 47 #define REG_IP_B_CTRL 0x04 48 #define REG_IP_C_CTRL 0x06 49 #define REG_IP_D_CTRL 0x08 50 #define REG_RESET 0x0A 51 #define REG_STATUS 0x0C 52 #define IP_N_FROM_REG(REG) ((REG) / 2 - 1) 53 54 typedef struct { 55 PCIDevice dev; 56 IPackBus bus; 57 MemoryRegion mmio; 58 MemoryRegion io; 59 MemoryRegion las0; 60 MemoryRegion las1; 61 MemoryRegion las2; 62 MemoryRegion las3; 63 bool big_endian[3]; 64 uint8_t ctrl[N_MODULES]; 65 uint16_t status; 66 uint8_t int_set; 67 } TPCI200State; 68 69 #define TYPE_TPCI200 "tpci200" 70 71 #define TPCI200(obj) \ 72 OBJECT_CHECK(TPCI200State, (obj), TYPE_TPCI200) 73 74 static const uint8_t local_config_regs[] = { 75 0x00, 0xFF, 0xFF, 0x0F, 0x00, 0xFC, 0xFF, 0x0F, 0x00, 0x00, 0x00, 76 0x0E, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 77 0x00, 0x08, 0x01, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x01, 78 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x60, 0x41, 0xD4, 79 0xA2, 0x20, 0x41, 0x14, 0xA2, 0x20, 0x41, 0x14, 0xA2, 0x20, 0x01, 80 0x14, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x08, 0x01, 0x02, 81 0x00, 0x04, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x80, 0x02, 0x41, 82 0x00, 0x00, 0x00, 0x00, 0x40, 0x7A, 0x00, 0x52, 0x92, 0x24, 0x02 83 }; 84 85 static void adjust_addr(bool big_endian, hwaddr *addr, unsigned size) 86 { 87 /* During 8 bit access in big endian mode, 88 odd and even addresses are swapped */ 89 if (big_endian && size == 1) { 90 *addr ^= 1; 91 } 92 } 93 94 static uint64_t adjust_value(bool big_endian, uint64_t *val, unsigned size) 95 { 96 /* Local spaces only support 8/16 bit access, 97 * so there's no need to care for sizes > 2 */ 98 if (big_endian && size == 2) { 99 *val = bswap16(*val); 100 } 101 return *val; 102 } 103 104 static void tpci200_set_irq(void *opaque, int intno, int level) 105 { 106 IPackDevice *ip = opaque; 107 IPackBus *bus = IPACK_BUS(qdev_get_parent_bus(DEVICE(ip))); 108 PCIDevice *pcidev = PCI_DEVICE(BUS(bus)->parent); 109 TPCI200State *dev = TPCI200(pcidev); 110 unsigned ip_n = ip->slot; 111 uint16_t prev_status = dev->status; 112 113 assert(ip->slot >= 0 && ip->slot < N_MODULES); 114 115 /* The requested interrupt must be enabled in the IP CONTROL 116 * register */ 117 if (!(dev->ctrl[ip_n] & CTRL_INT(intno))) { 118 return; 119 } 120 121 /* Update the interrupt status in the IP STATUS register */ 122 if (level) { 123 dev->status |= STATUS_INT(ip_n, intno); 124 } else { 125 dev->status &= ~STATUS_INT(ip_n, intno); 126 } 127 128 /* Return if there are no changes */ 129 if (dev->status == prev_status) { 130 return; 131 } 132 133 DPRINTF("IP %u INT%u#: %u\n", ip_n, intno, level); 134 135 /* Check if the interrupt is edge sensitive */ 136 if (dev->ctrl[ip_n] & CTRL_INT_EDGE(intno)) { 137 if (level) { 138 pci_set_irq(&dev->dev, !dev->int_set); 139 pci_set_irq(&dev->dev, dev->int_set); 140 } 141 } else { 142 unsigned i, j; 143 uint16_t level_status = dev->status; 144 145 /* Check if there are any level sensitive interrupts set by 146 removing the ones that are edge sensitive from the status 147 register */ 148 for (i = 0; i < N_MODULES; i++) { 149 for (j = 0; j < 2; j++) { 150 if (dev->ctrl[i] & CTRL_INT_EDGE(j)) { 151 level_status &= ~STATUS_INT(i, j); 152 } 153 } 154 } 155 156 if (level_status && !dev->int_set) { 157 pci_irq_assert(&dev->dev); 158 dev->int_set = 1; 159 } else if (!level_status && dev->int_set) { 160 pci_irq_deassert(&dev->dev); 161 dev->int_set = 0; 162 } 163 } 164 } 165 166 static uint64_t tpci200_read_cfg(void *opaque, hwaddr addr, unsigned size) 167 { 168 TPCI200State *s = opaque; 169 uint8_t ret = 0; 170 if (addr < ARRAY_SIZE(local_config_regs)) { 171 ret = local_config_regs[addr]; 172 } 173 /* Endianness is stored in the first bit of these registers */ 174 if ((addr == 0x2b && s->big_endian[0]) || 175 (addr == 0x2f && s->big_endian[1]) || 176 (addr == 0x33 && s->big_endian[2])) { 177 ret |= 1; 178 } 179 DPRINTF("Read from LCR 0x%x: 0x%x\n", (unsigned) addr, (unsigned) ret); 180 return ret; 181 } 182 183 static void tpci200_write_cfg(void *opaque, hwaddr addr, uint64_t val, 184 unsigned size) 185 { 186 TPCI200State *s = opaque; 187 /* Endianness is stored in the first bit of these registers */ 188 if (addr == 0x2b || addr == 0x2f || addr == 0x33) { 189 unsigned las = (addr - 0x2b) / 4; 190 s->big_endian[las] = val & 1; 191 DPRINTF("LAS%u big endian mode: %u\n", las, (unsigned) val & 1); 192 } else { 193 DPRINTF("Write to LCR 0x%x: 0x%x\n", (unsigned) addr, (unsigned) val); 194 } 195 } 196 197 static uint64_t tpci200_read_las0(void *opaque, hwaddr addr, unsigned size) 198 { 199 TPCI200State *s = opaque; 200 uint64_t ret = 0; 201 202 switch (addr) { 203 204 case REG_REV_ID: 205 DPRINTF("Read REVISION ID\n"); /* Current value is 0x00 */ 206 break; 207 208 case REG_IP_A_CTRL: 209 case REG_IP_B_CTRL: 210 case REG_IP_C_CTRL: 211 case REG_IP_D_CTRL: 212 { 213 unsigned ip_n = IP_N_FROM_REG(addr); 214 ret = s->ctrl[ip_n]; 215 DPRINTF("Read IP %c CONTROL: 0x%x\n", 'A' + ip_n, (unsigned) ret); 216 } 217 break; 218 219 case REG_RESET: 220 DPRINTF("Read RESET\n"); /* Not implemented */ 221 break; 222 223 case REG_STATUS: 224 ret = s->status; 225 DPRINTF("Read STATUS: 0x%x\n", (unsigned) ret); 226 break; 227 228 /* Reserved */ 229 default: 230 DPRINTF("Unsupported read from LAS0 0x%x\n", (unsigned) addr); 231 break; 232 } 233 234 return adjust_value(s->big_endian[0], &ret, size); 235 } 236 237 static void tpci200_write_las0(void *opaque, hwaddr addr, uint64_t val, 238 unsigned size) 239 { 240 TPCI200State *s = opaque; 241 242 adjust_value(s->big_endian[0], &val, size); 243 244 switch (addr) { 245 246 case REG_REV_ID: 247 DPRINTF("Write Revision ID: 0x%x\n", (unsigned) val); /* No effect */ 248 break; 249 250 case REG_IP_A_CTRL: 251 case REG_IP_B_CTRL: 252 case REG_IP_C_CTRL: 253 case REG_IP_D_CTRL: 254 { 255 unsigned ip_n = IP_N_FROM_REG(addr); 256 s->ctrl[ip_n] = val; 257 DPRINTF("Write IP %c CONTROL: 0x%x\n", 'A' + ip_n, (unsigned) val); 258 } 259 break; 260 261 case REG_RESET: 262 DPRINTF("Write RESET: 0x%x\n", (unsigned) val); /* Not implemented */ 263 break; 264 265 case REG_STATUS: 266 { 267 unsigned i; 268 269 for (i = 0; i < N_MODULES; i++) { 270 IPackDevice *ip = ipack_device_find(&s->bus, i); 271 272 if (ip != NULL) { 273 if (val & STATUS_INT(i, 0)) { 274 DPRINTF("Clear IP %c INT0# status\n", 'A' + i); 275 qemu_irq_lower(ip->irq[0]); 276 } 277 if (val & STATUS_INT(i, 1)) { 278 DPRINTF("Clear IP %c INT1# status\n", 'A' + i); 279 qemu_irq_lower(ip->irq[1]); 280 } 281 } 282 283 if (val & STATUS_TIME(i)) { 284 DPRINTF("Clear IP %c timeout\n", 'A' + i); 285 s->status &= ~STATUS_TIME(i); 286 } 287 } 288 289 if (val & STATUS_ERR_ANY) { 290 DPRINTF("Unexpected write to STATUS register: 0x%x\n", 291 (unsigned) val); 292 } 293 } 294 break; 295 296 /* Reserved */ 297 default: 298 DPRINTF("Unsupported write to LAS0 0x%x: 0x%x\n", 299 (unsigned) addr, (unsigned) val); 300 break; 301 } 302 } 303 304 static uint64_t tpci200_read_las1(void *opaque, hwaddr addr, unsigned size) 305 { 306 TPCI200State *s = opaque; 307 IPackDevice *ip; 308 uint64_t ret = 0; 309 unsigned ip_n, space; 310 uint8_t offset; 311 312 adjust_addr(s->big_endian[1], &addr, size); 313 314 /* 315 * The address is divided into the IP module number (0-4), the IP 316 * address space (I/O, ID, INT) and the offset within that space. 317 */ 318 ip_n = addr >> 8; 319 space = (addr >> 6) & 3; 320 ip = ipack_device_find(&s->bus, ip_n); 321 322 if (ip == NULL) { 323 DPRINTF("Read LAS1: IP module %u not installed\n", ip_n); 324 } else { 325 IPackDeviceClass *k = IPACK_DEVICE_GET_CLASS(ip); 326 switch (space) { 327 328 case IP_ID_SPACE: 329 offset = addr & IP_ID_SPACE_ADDR_MASK; 330 if (k->id_read) { 331 ret = k->id_read(ip, offset); 332 } 333 break; 334 335 case IP_INT_SPACE: 336 offset = addr & IP_INT_SPACE_ADDR_MASK; 337 338 /* Read address 0 to ACK IP INT0# and address 2 to ACK IP INT1# */ 339 if (offset == 0 || offset == 2) { 340 unsigned intno = offset / 2; 341 bool int_set = s->status & STATUS_INT(ip_n, intno); 342 bool int_edge_sensitive = s->ctrl[ip_n] & CTRL_INT_EDGE(intno); 343 if (int_set && !int_edge_sensitive) { 344 qemu_irq_lower(ip->irq[intno]); 345 } 346 } 347 348 if (k->int_read) { 349 ret = k->int_read(ip, offset); 350 } 351 break; 352 353 default: 354 offset = addr & IP_IO_SPACE_ADDR_MASK; 355 if (k->io_read) { 356 ret = k->io_read(ip, offset); 357 } 358 break; 359 } 360 } 361 362 return adjust_value(s->big_endian[1], &ret, size); 363 } 364 365 static void tpci200_write_las1(void *opaque, hwaddr addr, uint64_t val, 366 unsigned size) 367 { 368 TPCI200State *s = opaque; 369 IPackDevice *ip; 370 unsigned ip_n, space; 371 uint8_t offset; 372 373 adjust_addr(s->big_endian[1], &addr, size); 374 adjust_value(s->big_endian[1], &val, size); 375 376 /* 377 * The address is divided into the IP module number, the IP 378 * address space (I/O, ID, INT) and the offset within that space. 379 */ 380 ip_n = addr >> 8; 381 space = (addr >> 6) & 3; 382 ip = ipack_device_find(&s->bus, ip_n); 383 384 if (ip == NULL) { 385 DPRINTF("Write LAS1: IP module %u not installed\n", ip_n); 386 } else { 387 IPackDeviceClass *k = IPACK_DEVICE_GET_CLASS(ip); 388 switch (space) { 389 390 case IP_ID_SPACE: 391 offset = addr & IP_ID_SPACE_ADDR_MASK; 392 if (k->id_write) { 393 k->id_write(ip, offset, val); 394 } 395 break; 396 397 case IP_INT_SPACE: 398 offset = addr & IP_INT_SPACE_ADDR_MASK; 399 if (k->int_write) { 400 k->int_write(ip, offset, val); 401 } 402 break; 403 404 default: 405 offset = addr & IP_IO_SPACE_ADDR_MASK; 406 if (k->io_write) { 407 k->io_write(ip, offset, val); 408 } 409 break; 410 } 411 } 412 } 413 414 static uint64_t tpci200_read_las2(void *opaque, hwaddr addr, unsigned size) 415 { 416 TPCI200State *s = opaque; 417 IPackDevice *ip; 418 uint64_t ret = 0; 419 unsigned ip_n; 420 uint32_t offset; 421 422 adjust_addr(s->big_endian[2], &addr, size); 423 424 /* 425 * The address is divided into the IP module number and the offset 426 * within the IP module MEM space. 427 */ 428 ip_n = addr >> 23; 429 offset = addr & 0x7fffff; 430 ip = ipack_device_find(&s->bus, ip_n); 431 432 if (ip == NULL) { 433 DPRINTF("Read LAS2: IP module %u not installed\n", ip_n); 434 } else { 435 IPackDeviceClass *k = IPACK_DEVICE_GET_CLASS(ip); 436 if (k->mem_read16) { 437 ret = k->mem_read16(ip, offset); 438 } 439 } 440 441 return adjust_value(s->big_endian[2], &ret, size); 442 } 443 444 static void tpci200_write_las2(void *opaque, hwaddr addr, uint64_t val, 445 unsigned size) 446 { 447 TPCI200State *s = opaque; 448 IPackDevice *ip; 449 unsigned ip_n; 450 uint32_t offset; 451 452 adjust_addr(s->big_endian[2], &addr, size); 453 adjust_value(s->big_endian[2], &val, size); 454 455 /* 456 * The address is divided into the IP module number and the offset 457 * within the IP module MEM space. 458 */ 459 ip_n = addr >> 23; 460 offset = addr & 0x7fffff; 461 ip = ipack_device_find(&s->bus, ip_n); 462 463 if (ip == NULL) { 464 DPRINTF("Write LAS2: IP module %u not installed\n", ip_n); 465 } else { 466 IPackDeviceClass *k = IPACK_DEVICE_GET_CLASS(ip); 467 if (k->mem_write16) { 468 k->mem_write16(ip, offset, val); 469 } 470 } 471 } 472 473 static uint64_t tpci200_read_las3(void *opaque, hwaddr addr, unsigned size) 474 { 475 TPCI200State *s = opaque; 476 IPackDevice *ip; 477 uint64_t ret = 0; 478 /* 479 * The address is divided into the IP module number and the offset 480 * within the IP module MEM space. 481 */ 482 unsigned ip_n = addr >> 22; 483 uint32_t offset = addr & 0x3fffff; 484 485 ip = ipack_device_find(&s->bus, ip_n); 486 487 if (ip == NULL) { 488 DPRINTF("Read LAS3: IP module %u not installed\n", ip_n); 489 } else { 490 IPackDeviceClass *k = IPACK_DEVICE_GET_CLASS(ip); 491 if (k->mem_read8) { 492 ret = k->mem_read8(ip, offset); 493 } 494 } 495 496 return ret; 497 } 498 499 static void tpci200_write_las3(void *opaque, hwaddr addr, uint64_t val, 500 unsigned size) 501 { 502 TPCI200State *s = opaque; 503 IPackDevice *ip; 504 /* 505 * The address is divided into the IP module number and the offset 506 * within the IP module MEM space. 507 */ 508 unsigned ip_n = addr >> 22; 509 uint32_t offset = addr & 0x3fffff; 510 511 ip = ipack_device_find(&s->bus, ip_n); 512 513 if (ip == NULL) { 514 DPRINTF("Write LAS3: IP module %u not installed\n", ip_n); 515 } else { 516 IPackDeviceClass *k = IPACK_DEVICE_GET_CLASS(ip); 517 if (k->mem_write8) { 518 k->mem_write8(ip, offset, val); 519 } 520 } 521 } 522 523 static const MemoryRegionOps tpci200_cfg_ops = { 524 .read = tpci200_read_cfg, 525 .write = tpci200_write_cfg, 526 .endianness = DEVICE_NATIVE_ENDIAN, 527 .valid = { 528 .min_access_size = 1, 529 .max_access_size = 4 530 }, 531 .impl = { 532 .min_access_size = 1, 533 .max_access_size = 1 534 } 535 }; 536 537 static const MemoryRegionOps tpci200_las0_ops = { 538 .read = tpci200_read_las0, 539 .write = tpci200_write_las0, 540 .endianness = DEVICE_NATIVE_ENDIAN, 541 .valid = { 542 .min_access_size = 2, 543 .max_access_size = 2 544 } 545 }; 546 547 static const MemoryRegionOps tpci200_las1_ops = { 548 .read = tpci200_read_las1, 549 .write = tpci200_write_las1, 550 .endianness = DEVICE_NATIVE_ENDIAN, 551 .valid = { 552 .min_access_size = 1, 553 .max_access_size = 2 554 } 555 }; 556 557 static const MemoryRegionOps tpci200_las2_ops = { 558 .read = tpci200_read_las2, 559 .write = tpci200_write_las2, 560 .endianness = DEVICE_NATIVE_ENDIAN, 561 .valid = { 562 .min_access_size = 1, 563 .max_access_size = 2 564 } 565 }; 566 567 static const MemoryRegionOps tpci200_las3_ops = { 568 .read = tpci200_read_las3, 569 .write = tpci200_write_las3, 570 .endianness = DEVICE_NATIVE_ENDIAN, 571 .valid = { 572 .min_access_size = 1, 573 .max_access_size = 1 574 } 575 }; 576 577 static void tpci200_realize(PCIDevice *pci_dev, Error **errp) 578 { 579 TPCI200State *s = TPCI200(pci_dev); 580 uint8_t *c = s->dev.config; 581 582 pci_set_word(c + PCI_COMMAND, 0x0003); 583 pci_set_word(c + PCI_STATUS, 0x0280); 584 585 pci_set_byte(c + PCI_INTERRUPT_PIN, 0x01); /* Interrupt pin A */ 586 587 pci_set_byte(c + PCI_CAPABILITY_LIST, 0x40); 588 pci_set_long(c + 0x40, 0x48014801); 589 pci_set_long(c + 0x48, 0x00024C06); 590 pci_set_long(c + 0x4C, 0x00000003); 591 592 memory_region_init_io(&s->mmio, OBJECT(s), &tpci200_cfg_ops, 593 s, "tpci200_mmio", 128); 594 memory_region_init_io(&s->io, OBJECT(s), &tpci200_cfg_ops, 595 s, "tpci200_io", 128); 596 memory_region_init_io(&s->las0, OBJECT(s), &tpci200_las0_ops, 597 s, "tpci200_las0", 256); 598 memory_region_init_io(&s->las1, OBJECT(s), &tpci200_las1_ops, 599 s, "tpci200_las1", 1024); 600 memory_region_init_io(&s->las2, OBJECT(s), &tpci200_las2_ops, 601 s, "tpci200_las2", 32 * MiB); 602 memory_region_init_io(&s->las3, OBJECT(s), &tpci200_las3_ops, 603 s, "tpci200_las3", 16 * MiB); 604 pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mmio); 605 pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &s->io); 606 pci_register_bar(&s->dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->las0); 607 pci_register_bar(&s->dev, 3, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->las1); 608 pci_register_bar(&s->dev, 4, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->las2); 609 pci_register_bar(&s->dev, 5, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->las3); 610 611 ipack_bus_new_inplace(&s->bus, sizeof(s->bus), DEVICE(pci_dev), NULL, 612 N_MODULES, tpci200_set_irq); 613 } 614 615 static const VMStateDescription vmstate_tpci200 = { 616 .name = "tpci200", 617 .version_id = 1, 618 .minimum_version_id = 1, 619 .fields = (VMStateField[]) { 620 VMSTATE_PCI_DEVICE(dev, TPCI200State), 621 VMSTATE_BOOL_ARRAY(big_endian, TPCI200State, 3), 622 VMSTATE_UINT8_ARRAY(ctrl, TPCI200State, N_MODULES), 623 VMSTATE_UINT16(status, TPCI200State), 624 VMSTATE_UINT8(int_set, TPCI200State), 625 VMSTATE_END_OF_LIST() 626 } 627 }; 628 629 static void tpci200_class_init(ObjectClass *klass, void *data) 630 { 631 DeviceClass *dc = DEVICE_CLASS(klass); 632 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); 633 634 k->realize = tpci200_realize; 635 k->vendor_id = PCI_VENDOR_ID_TEWS; 636 k->device_id = PCI_DEVICE_ID_TEWS_TPCI200; 637 k->class_id = PCI_CLASS_BRIDGE_OTHER; 638 k->subsystem_vendor_id = PCI_VENDOR_ID_TEWS; 639 k->subsystem_id = 0x300A; 640 set_bit(DEVICE_CATEGORY_INPUT, dc->categories); 641 dc->desc = "TEWS TPCI200 IndustryPack carrier"; 642 dc->vmsd = &vmstate_tpci200; 643 } 644 645 static const TypeInfo tpci200_info = { 646 .name = TYPE_TPCI200, 647 .parent = TYPE_PCI_DEVICE, 648 .instance_size = sizeof(TPCI200State), 649 .class_init = tpci200_class_init, 650 .interfaces = (InterfaceInfo[]) { 651 { INTERFACE_CONVENTIONAL_PCI_DEVICE }, 652 { }, 653 }, 654 }; 655 656 static void tpci200_register_types(void) 657 { 658 type_register_static(&tpci200_info); 659 } 660 661 type_init(tpci200_register_types) 662