cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

solo6x10-core.c (17501B)


      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);