1 /* 2 * Copyright (C) 2010-2013 Bluecherry, LLC <http://www.bluecherrydvr.com> 3 * 4 * Original author: 5 * Ben Collins <bcollins@ubuntu.com> 6 * 7 * Additional work by: 8 * John Brooks <john.brooks@bluecherry.net> 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; either version 2 of the License, or 13 * (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 */ 20 21 #include <linux/kernel.h> 22 #include <linux/module.h> 23 #include <linux/pci.h> 24 #include <linux/interrupt.h> 25 #include <linux/videodev2.h> 26 #include <linux/delay.h> 27 #include <linux/sysfs.h> 28 #include <linux/ktime.h> 29 #include <linux/slab.h> 30 31 #include "solo6x10.h" 32 #include "solo6x10-tw28.h" 33 34 MODULE_DESCRIPTION("Softlogic 6x10 MPEG4/H.264/G.723 CODEC V4L2/ALSA Driver"); 35 MODULE_AUTHOR("Bluecherry <maintainers@bluecherrydvr.com>"); 36 MODULE_VERSION(SOLO6X10_VERSION); 37 MODULE_LICENSE("GPL"); 38 39 static unsigned video_nr = -1; 40 module_param(video_nr, uint, 0644); 41 MODULE_PARM_DESC(video_nr, "videoX start number, -1 is autodetect (default)"); 42 43 static int full_eeprom; /* default is only top 64B */ 44 module_param(full_eeprom, uint, 0644); 45 MODULE_PARM_DESC(full_eeprom, "Allow access to full 128B EEPROM (dangerous)"); 46 47 48 static void solo_set_time(struct solo_dev *solo_dev) 49 { 50 struct timespec64 ts; 51 52 ktime_get_ts64(&ts); 53 54 /* no overflow because we use monotonic timestamps */ 55 solo_reg_write(solo_dev, SOLO_TIMER_SEC, (u32)ts.tv_sec); 56 solo_reg_write(solo_dev, SOLO_TIMER_USEC, (u32)ts.tv_nsec / NSEC_PER_USEC); 57 } 58 59 static void solo_timer_sync(struct solo_dev *solo_dev) 60 { 61 u32 sec, usec; 62 struct timespec64 ts; 63 long diff; 64 65 if (solo_dev->type != SOLO_DEV_6110) 66 return; 67 68 if (++solo_dev->time_sync < 60) 69 return; 70 71 solo_dev->time_sync = 0; 72 73 sec = solo_reg_read(solo_dev, SOLO_TIMER_SEC); 74 usec = solo_reg_read(solo_dev, SOLO_TIMER_USEC); 75 76 ktime_get_ts64(&ts); 77 78 diff = (s32)ts.tv_sec - (s32)sec; 79 diff = (diff * 1000000) 80 + ((s32)(ts.tv_nsec / NSEC_PER_USEC) - (s32)usec); 81 82 if (diff > 1000 || diff < -1000) { 83 solo_set_time(solo_dev); 84 } else if (diff) { 85 long usec_lsb = solo_dev->usec_lsb; 86 87 usec_lsb -= diff / 4; 88 if (usec_lsb < 0) 89 usec_lsb = 0; 90 else if (usec_lsb > 255) 91 usec_lsb = 255; 92 93 solo_dev->usec_lsb = usec_lsb; 94 solo_reg_write(solo_dev, SOLO_TIMER_USEC_LSB, 95 solo_dev->usec_lsb); 96 } 97 } 98 99 static irqreturn_t solo_isr(int irq, void *data) 100 { 101 struct solo_dev *solo_dev = data; 102 u32 status; 103 int i; 104 105 status = solo_reg_read(solo_dev, SOLO_IRQ_STAT); 106 if (!status) 107 return IRQ_NONE; 108 109 /* Acknowledge all interrupts immediately */ 110 solo_reg_write(solo_dev, SOLO_IRQ_STAT, status); 111 112 if (status & SOLO_IRQ_PCI_ERR) 113 solo_p2m_error_isr(solo_dev); 114 115 for (i = 0; i < SOLO_NR_P2M; i++) 116 if (status & SOLO_IRQ_P2M(i)) 117 solo_p2m_isr(solo_dev, i); 118 119 if (status & SOLO_IRQ_IIC) 120 solo_i2c_isr(solo_dev); 121 122 if (status & SOLO_IRQ_VIDEO_IN) { 123 solo_video_in_isr(solo_dev); 124 solo_timer_sync(solo_dev); 125 } 126 127 if (status & SOLO_IRQ_ENCODER) 128 solo_enc_v4l2_isr(solo_dev); 129 130 if (status & SOLO_IRQ_G723) 131 solo_g723_isr(solo_dev); 132 133 return IRQ_HANDLED; 134 } 135 136 static void free_solo_dev(struct solo_dev *solo_dev) 137 { 138 struct pci_dev *pdev = solo_dev->pdev; 139 140 if (solo_dev->dev.parent) 141 device_unregister(&solo_dev->dev); 142 143 if (solo_dev->reg_base) { 144 /* Bring down the sub-devices first */ 145 solo_g723_exit(solo_dev); 146 solo_enc_v4l2_exit(solo_dev); 147 solo_enc_exit(solo_dev); 148 solo_v4l2_exit(solo_dev); 149 solo_disp_exit(solo_dev); 150 solo_gpio_exit(solo_dev); 151 solo_p2m_exit(solo_dev); 152 solo_i2c_exit(solo_dev); 153 154 /* Now cleanup the PCI device */ 155 solo_irq_off(solo_dev, ~0); 156 free_irq(pdev->irq, solo_dev); 157 pci_iounmap(pdev, solo_dev->reg_base); 158 } 159 160 pci_release_regions(pdev); 161 pci_disable_device(pdev); 162 v4l2_device_unregister(&solo_dev->v4l2_dev); 163 pci_set_drvdata(pdev, NULL); 164 165 kfree(solo_dev); 166 } 167 168 static ssize_t eeprom_store(struct device *dev, struct device_attribute *attr, 169 const char *buf, size_t count) 170 { 171 struct solo_dev *solo_dev = 172 container_of(dev, struct solo_dev, dev); 173 u16 *p = (u16 *)buf; 174 int i; 175 176 if (count & 0x1) 177 dev_warn(dev, "EEPROM Write not aligned (truncating)\n"); 178 179 if (!full_eeprom && count > 64) { 180 dev_warn(dev, "EEPROM Write truncated to 64 bytes\n"); 181 count = 64; 182 } else if (full_eeprom && count > 128) { 183 dev_warn(dev, "EEPROM Write truncated to 128 bytes\n"); 184 count = 128; 185 } 186 187 solo_eeprom_ewen(solo_dev, 1); 188 189 for (i = full_eeprom ? 0 : 32; i < min((int)(full_eeprom ? 64 : 32), 190 (int)(count / 2)); i++) 191 solo_eeprom_write(solo_dev, i, cpu_to_be16(p[i])); 192 193 solo_eeprom_ewen(solo_dev, 0); 194 195 return count; 196 } 197 198 static ssize_t eeprom_show(struct device *dev, struct device_attribute *attr, 199 char *buf) 200 { 201 struct solo_dev *solo_dev = 202 container_of(dev, struct solo_dev, dev); 203 u16 *p = (u16 *)buf; 204 int count = (full_eeprom ? 128 : 64); 205 int i; 206 207 for (i = (full_eeprom ? 0 : 32); i < (count / 2); i++) 208 p[i] = be16_to_cpu(solo_eeprom_read(solo_dev, i)); 209 210 return count; 211 } 212 213 static ssize_t p2m_timeouts_show(struct device *dev, 214 struct device_attribute *attr, 215 char *buf) 216 { 217 struct solo_dev *solo_dev = 218 container_of(dev, struct solo_dev, dev); 219 220 return sprintf(buf, "%d\n", solo_dev->p2m_timeouts); 221 } 222 223 static ssize_t sdram_size_show(struct device *dev, 224 struct device_attribute *attr, 225 char *buf) 226 { 227 struct solo_dev *solo_dev = 228 container_of(dev, struct solo_dev, dev); 229 230 return sprintf(buf, "%dMegs\n", solo_dev->sdram_size >> 20); 231 } 232 233 static ssize_t tw28xx_show(struct device *dev, 234 struct device_attribute *attr, 235 char *buf) 236 { 237 struct solo_dev *solo_dev = 238 container_of(dev, struct solo_dev, dev); 239 240 return sprintf(buf, "tw2815[%d] tw2864[%d] tw2865[%d]\n", 241 hweight32(solo_dev->tw2815), 242 hweight32(solo_dev->tw2864), 243 hweight32(solo_dev->tw2865)); 244 } 245 246 static ssize_t input_map_show(struct device *dev, 247 struct device_attribute *attr, 248 char *buf) 249 { 250 struct solo_dev *solo_dev = 251 container_of(dev, struct solo_dev, dev); 252 unsigned int val; 253 char *out = buf; 254 255 val = solo_reg_read(solo_dev, SOLO_VI_CH_SWITCH_0); 256 out += sprintf(out, "Channel 0 => Input %d\n", val & 0x1f); 257 out += sprintf(out, "Channel 1 => Input %d\n", (val >> 5) & 0x1f); 258 out += sprintf(out, "Channel 2 => Input %d\n", (val >> 10) & 0x1f); 259 out += sprintf(out, "Channel 3 => Input %d\n", (val >> 15) & 0x1f); 260 out += sprintf(out, "Channel 4 => Input %d\n", (val >> 20) & 0x1f); 261 out += sprintf(out, "Channel 5 => Input %d\n", (val >> 25) & 0x1f); 262 263 val = solo_reg_read(solo_dev, SOLO_VI_CH_SWITCH_1); 264 out += sprintf(out, "Channel 6 => Input %d\n", val & 0x1f); 265 out += sprintf(out, "Channel 7 => Input %d\n", (val >> 5) & 0x1f); 266 out += sprintf(out, "Channel 8 => Input %d\n", (val >> 10) & 0x1f); 267 out += sprintf(out, "Channel 9 => Input %d\n", (val >> 15) & 0x1f); 268 out += sprintf(out, "Channel 10 => Input %d\n", (val >> 20) & 0x1f); 269 out += sprintf(out, "Channel 11 => Input %d\n", (val >> 25) & 0x1f); 270 271 val = solo_reg_read(solo_dev, SOLO_VI_CH_SWITCH_2); 272 out += sprintf(out, "Channel 12 => Input %d\n", val & 0x1f); 273 out += sprintf(out, "Channel 13 => Input %d\n", (val >> 5) & 0x1f); 274 out += sprintf(out, "Channel 14 => Input %d\n", (val >> 10) & 0x1f); 275 out += sprintf(out, "Channel 15 => Input %d\n", (val >> 15) & 0x1f); 276 out += sprintf(out, "Spot Output => Input %d\n", (val >> 20) & 0x1f); 277 278 return out - buf; 279 } 280 281 static ssize_t p2m_timeout_store(struct device *dev, 282 struct device_attribute *attr, 283 const char *buf, size_t count) 284 { 285 struct solo_dev *solo_dev = 286 container_of(dev, struct solo_dev, dev); 287 unsigned long ms; 288 int ret = kstrtoul(buf, 10, &ms); 289 290 if (ret < 0 || ms > 200) 291 return -EINVAL; 292 solo_dev->p2m_jiffies = msecs_to_jiffies(ms); 293 294 return count; 295 } 296 297 static ssize_t p2m_timeout_show(struct device *dev, 298 struct device_attribute *attr, 299 char *buf) 300 { 301 struct solo_dev *solo_dev = 302 container_of(dev, struct solo_dev, dev); 303 304 return sprintf(buf, "%ums\n", jiffies_to_msecs(solo_dev->p2m_jiffies)); 305 } 306 307 static ssize_t intervals_show(struct device *dev, 308 struct device_attribute *attr, 309 char *buf) 310 { 311 struct solo_dev *solo_dev = 312 container_of(dev, struct solo_dev, dev); 313 char *out = buf; 314 int fps = solo_dev->fps; 315 int i; 316 317 for (i = 0; i < solo_dev->nr_chans; i++) { 318 out += sprintf(out, "Channel %d: %d/%d (0x%08x)\n", 319 i, solo_dev->v4l2_enc[i]->interval, fps, 320 solo_reg_read(solo_dev, SOLO_CAP_CH_INTV(i))); 321 } 322 323 return out - buf; 324 } 325 326 static ssize_t sdram_offsets_show(struct device *dev, 327 struct device_attribute *attr, 328 char *buf) 329 { 330 struct solo_dev *solo_dev = 331 container_of(dev, struct solo_dev, dev); 332 char *out = buf; 333 334 out += sprintf(out, "DISP: 0x%08x @ 0x%08x\n", 335 SOLO_DISP_EXT_ADDR, 336 SOLO_DISP_EXT_SIZE); 337 338 out += sprintf(out, "EOSD: 0x%08x @ 0x%08x (0x%08x * %d)\n", 339 SOLO_EOSD_EXT_ADDR, 340 SOLO_EOSD_EXT_AREA(solo_dev), 341 SOLO_EOSD_EXT_SIZE(solo_dev), 342 SOLO_EOSD_EXT_AREA(solo_dev) / 343 SOLO_EOSD_EXT_SIZE(solo_dev)); 344 345 out += sprintf(out, "MOTI: 0x%08x @ 0x%08x\n", 346 SOLO_MOTION_EXT_ADDR(solo_dev), 347 SOLO_MOTION_EXT_SIZE); 348 349 out += sprintf(out, "G723: 0x%08x @ 0x%08x\n", 350 SOLO_G723_EXT_ADDR(solo_dev), 351 SOLO_G723_EXT_SIZE); 352 353 out += sprintf(out, "CAPT: 0x%08x @ 0x%08x (0x%08x * %d)\n", 354 SOLO_CAP_EXT_ADDR(solo_dev), 355 SOLO_CAP_EXT_SIZE(solo_dev), 356 SOLO_CAP_PAGE_SIZE, 357 SOLO_CAP_EXT_SIZE(solo_dev) / SOLO_CAP_PAGE_SIZE); 358 359 out += sprintf(out, "EREF: 0x%08x @ 0x%08x (0x%08x * %d)\n", 360 SOLO_EREF_EXT_ADDR(solo_dev), 361 SOLO_EREF_EXT_AREA(solo_dev), 362 SOLO_EREF_EXT_SIZE, 363 SOLO_EREF_EXT_AREA(solo_dev) / SOLO_EREF_EXT_SIZE); 364 365 out += sprintf(out, "MPEG: 0x%08x @ 0x%08x\n", 366 SOLO_MP4E_EXT_ADDR(solo_dev), 367 SOLO_MP4E_EXT_SIZE(solo_dev)); 368 369 out += sprintf(out, "JPEG: 0x%08x @ 0x%08x\n", 370 SOLO_JPEG_EXT_ADDR(solo_dev), 371 SOLO_JPEG_EXT_SIZE(solo_dev)); 372 373 return out - buf; 374 } 375 376 static ssize_t sdram_show(struct file *file, struct kobject *kobj, 377 struct bin_attribute *a, char *buf, 378 loff_t off, size_t count) 379 { 380 struct device *dev = container_of(kobj, struct device, kobj); 381 struct solo_dev *solo_dev = 382 container_of(dev, struct solo_dev, dev); 383 const int size = solo_dev->sdram_size; 384 385 if (off >= size) 386 return 0; 387 388 if (off + count > size) 389 count = size - off; 390 391 if (solo_p2m_dma(solo_dev, 0, buf, off, count, 0, 0)) 392 return -EIO; 393 394 return count; 395 } 396 397 static const struct device_attribute solo_dev_attrs[] = { 398 __ATTR(eeprom, 0640, eeprom_show, eeprom_store), 399 __ATTR(p2m_timeout, 0644, p2m_timeout_show, p2m_timeout_store), 400 __ATTR_RO(p2m_timeouts), 401 __ATTR_RO(sdram_size), 402 __ATTR_RO(tw28xx), 403 __ATTR_RO(input_map), 404 __ATTR_RO(intervals), 405 __ATTR_RO(sdram_offsets), 406 }; 407 408 static void solo_device_release(struct device *dev) 409 { 410 /* Do nothing */ 411 } 412 413 static int solo_sysfs_init(struct solo_dev *solo_dev) 414 { 415 struct bin_attribute *sdram_attr = &solo_dev->sdram_attr; 416 struct device *dev = &solo_dev->dev; 417 const char *driver; 418 int i; 419 420 if (solo_dev->type == SOLO_DEV_6110) 421 driver = "solo6110"; 422 else 423 driver = "solo6010"; 424 425 dev->release = solo_device_release; 426 dev->parent = &solo_dev->pdev->dev; 427 set_dev_node(dev, dev_to_node(&solo_dev->pdev->dev)); 428 dev_set_name(dev, "%s-%d-%d", driver, solo_dev->vfd->num, 429 solo_dev->nr_chans); 430 431 if (device_register(dev)) { 432 dev->parent = NULL; 433 return -ENOMEM; 434 } 435 436 for (i = 0; i < ARRAY_SIZE(solo_dev_attrs); i++) { 437 if (device_create_file(dev, &solo_dev_attrs[i])) { 438 device_unregister(dev); 439 return -ENOMEM; 440 } 441 } 442 443 sysfs_attr_init(&sdram_attr->attr); 444 sdram_attr->attr.name = "sdram"; 445 sdram_attr->attr.mode = 0440; 446 sdram_attr->read = sdram_show; 447 sdram_attr->size = solo_dev->sdram_size; 448 449 if (device_create_bin_file(dev, sdram_attr)) { 450 device_unregister(dev); 451 return -ENOMEM; 452 } 453 454 return 0; 455 } 456 457 static int solo_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) 458 { 459 struct solo_dev *solo_dev; 460 int ret; 461 u8 chip_id; 462 463 solo_dev = kzalloc(sizeof(*solo_dev), GFP_KERNEL); 464 if (solo_dev == NULL) 465 return -ENOMEM; 466 467 if (id->driver_data == SOLO_DEV_6010) 468 dev_info(&pdev->dev, "Probing Softlogic 6010\n"); 469 else 470 dev_info(&pdev->dev, "Probing Softlogic 6110\n"); 471 472 solo_dev->type = id->driver_data; 473 solo_dev->pdev = pdev; 474 ret = v4l2_device_register(&pdev->dev, &solo_dev->v4l2_dev); 475 if (ret) 476 goto fail_probe; 477 478 /* Only for during init */ 479 solo_dev->p2m_jiffies = msecs_to_jiffies(100); 480 481 ret = pci_enable_device(pdev); 482 if (ret) 483 goto fail_probe; 484 485 pci_set_master(pdev); 486 487 /* RETRY/TRDY Timeout disabled */ 488 pci_write_config_byte(pdev, 0x40, 0x00); 489 pci_write_config_byte(pdev, 0x41, 0x00); 490 491 ret = pci_request_regions(pdev, SOLO6X10_NAME); 492 if (ret) 493 goto fail_probe; 494 495 solo_dev->reg_base = pci_ioremap_bar(pdev, 0); 496 if (solo_dev->reg_base == NULL) { 497 ret = -ENOMEM; 498 goto fail_probe; 499 } 500 501 chip_id = solo_reg_read(solo_dev, SOLO_CHIP_OPTION) & 502 SOLO_CHIP_ID_MASK; 503 switch (chip_id) { 504 case 7: 505 solo_dev->nr_chans = 16; 506 solo_dev->nr_ext = 5; 507 break; 508 case 6: 509 solo_dev->nr_chans = 8; 510 solo_dev->nr_ext = 2; 511 break; 512 default: 513 dev_warn(&pdev->dev, "Invalid chip_id 0x%02x, assuming 4 ch\n", 514 chip_id); 515 /* fall through */ 516 case 5: 517 solo_dev->nr_chans = 4; 518 solo_dev->nr_ext = 1; 519 } 520 521 /* Disable all interrupts to start */ 522 solo_irq_off(solo_dev, ~0); 523 524 /* Initial global settings */ 525 if (solo_dev->type == SOLO_DEV_6010) { 526 solo_dev->clock_mhz = 108; 527 solo_dev->sys_config = SOLO_SYS_CFG_SDRAM64BIT 528 | SOLO_SYS_CFG_INPUTDIV(25) 529 | SOLO_SYS_CFG_FEEDBACKDIV(solo_dev->clock_mhz * 2 - 2) 530 | SOLO_SYS_CFG_OUTDIV(3); 531 solo_reg_write(solo_dev, SOLO_SYS_CFG, solo_dev->sys_config); 532 } else { 533 u32 divq, divf; 534 535 solo_dev->clock_mhz = 135; 536 537 if (solo_dev->clock_mhz < 125) { 538 divq = 3; 539 divf = (solo_dev->clock_mhz * 4) / 3 - 1; 540 } else { 541 divq = 2; 542 divf = (solo_dev->clock_mhz * 2) / 3 - 1; 543 } 544 545 solo_reg_write(solo_dev, SOLO_PLL_CONFIG, 546 (1 << 20) | /* PLL_RANGE */ 547 (8 << 15) | /* PLL_DIVR */ 548 (divq << 12) | 549 (divf << 4) | 550 (1 << 1) /* PLL_FSEN */); 551 552 solo_dev->sys_config = SOLO_SYS_CFG_SDRAM64BIT; 553 } 554 555 solo_reg_write(solo_dev, SOLO_SYS_CFG, solo_dev->sys_config); 556 solo_reg_write(solo_dev, SOLO_TIMER_CLOCK_NUM, 557 solo_dev->clock_mhz - 1); 558 559 /* PLL locking time of 1ms */ 560 mdelay(1); 561 562 ret = request_irq(pdev->irq, solo_isr, IRQF_SHARED, SOLO6X10_NAME, 563 solo_dev); 564 if (ret) 565 goto fail_probe; 566 567 /* Handle this from the start */ 568 solo_irq_on(solo_dev, SOLO_IRQ_PCI_ERR); 569 570 ret = solo_i2c_init(solo_dev); 571 if (ret) 572 goto fail_probe; 573 574 /* Setup the DMA engine */ 575 solo_reg_write(solo_dev, SOLO_DMA_CTRL, 576 SOLO_DMA_CTRL_REFRESH_CYCLE(1) | 577 SOLO_DMA_CTRL_SDRAM_SIZE(2) | 578 SOLO_DMA_CTRL_SDRAM_CLK_INVERT | 579 SOLO_DMA_CTRL_READ_CLK_SELECT | 580 SOLO_DMA_CTRL_LATENCY(1)); 581 582 /* Undocumented crap */ 583 solo_reg_write(solo_dev, SOLO_DMA_CTRL1, 584 solo_dev->type == SOLO_DEV_6010 ? 0x100 : 0x300); 585 586 if (solo_dev->type != SOLO_DEV_6010) { 587 solo_dev->usec_lsb = 0x3f; 588 solo_set_time(solo_dev); 589 } 590 591 /* Disable watchdog */ 592 solo_reg_write(solo_dev, SOLO_WATCHDOG, 0); 593 594 /* Initialize sub components */ 595 596 ret = solo_p2m_init(solo_dev); 597 if (ret) 598 goto fail_probe; 599 600 ret = solo_disp_init(solo_dev); 601 if (ret) 602 goto fail_probe; 603 604 ret = solo_gpio_init(solo_dev); 605 if (ret) 606 goto fail_probe; 607 608 ret = solo_tw28_init(solo_dev); 609 if (ret) 610 goto fail_probe; 611 612 ret = solo_v4l2_init(solo_dev, video_nr); 613 if (ret) 614 goto fail_probe; 615 616 ret = solo_enc_init(solo_dev); 617 if (ret) 618 goto fail_probe; 619 620 ret = solo_enc_v4l2_init(solo_dev, video_nr); 621 if (ret) 622 goto fail_probe; 623 624 ret = solo_g723_init(solo_dev); 625 if (ret) 626 goto fail_probe; 627 628 ret = solo_sysfs_init(solo_dev); 629 if (ret) 630 goto fail_probe; 631 632 /* Now that init is over, set this lower */ 633 solo_dev->p2m_jiffies = msecs_to_jiffies(20); 634 635 return 0; 636 637 fail_probe: 638 free_solo_dev(solo_dev); 639 return ret; 640 } 641 642 static void solo_pci_remove(struct pci_dev *pdev) 643 { 644 struct v4l2_device *v4l2_dev = pci_get_drvdata(pdev); 645 struct solo_dev *solo_dev = container_of(v4l2_dev, struct solo_dev, v4l2_dev); 646 647 free_solo_dev(solo_dev); 648 } 649 650 static const struct pci_device_id solo_id_table[] = { 651 /* 6010 based cards */ 652 { PCI_DEVICE(PCI_VENDOR_ID_SOFTLOGIC, PCI_DEVICE_ID_SOLO6010), 653 .driver_data = SOLO_DEV_6010 }, 654 { PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_NEUSOLO_4), 655 .driver_data = SOLO_DEV_6010 }, 656 { PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_NEUSOLO_9), 657 .driver_data = SOLO_DEV_6010 }, 658 { PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_NEUSOLO_16), 659 .driver_data = SOLO_DEV_6010 }, 660 { PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_BC_SOLO_4), 661 .driver_data = SOLO_DEV_6010 }, 662 { PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_BC_SOLO_9), 663 .driver_data = SOLO_DEV_6010 }, 664 { PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_BC_SOLO_16), 665 .driver_data = SOLO_DEV_6010 }, 666 /* 6110 based cards */ 667 { PCI_DEVICE(PCI_VENDOR_ID_SOFTLOGIC, PCI_DEVICE_ID_SOLO6110), 668 .driver_data = SOLO_DEV_6110 }, 669 { PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_BC_6110_4), 670 .driver_data = SOLO_DEV_6110 }, 671 { PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_BC_6110_8), 672 .driver_data = SOLO_DEV_6110 }, 673 { PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_BC_6110_16), 674 .driver_data = SOLO_DEV_6110 }, 675 {0,} 676 }; 677 678 MODULE_DEVICE_TABLE(pci, solo_id_table); 679 680 static struct pci_driver solo_pci_driver = { 681 .name = SOLO6X10_NAME, 682 .id_table = solo_id_table, 683 .probe = solo_pci_probe, 684 .remove = solo_pci_remove, 685 }; 686 687 module_pci_driver(solo_pci_driver); 688