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