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