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