return -ENOMEM;
        }
        cx18_cards[cx18_cards_active] = cx;
-       cx->pci_dev = pci_dev;
        cx->num = cx18_cards_active++;
        snprintf(cx->name, sizeof(cx->name), "cx18-%d", cx->num);
        CX18_INFO("Initializing card #%d\n", cx->num);
 
        spin_unlock(&cx18_cards_lock);
 
+       cx->pci_dev = pci_dev;
+       retval = v4l2_device_register(&pci_dev->dev, &cx->v4l2_dev);
+       if (retval) {
+               CX18_ERR("Call to v4l2_device_register() failed\n");
+               goto err;
+       }
+       CX18_DEBUG_INFO("registered v4l2_device name: %s\n", cx->v4l2_dev.name);
+
        cx18_process_options(cx);
        if (cx->options.cardtype == -1) {
                retval = -ENODEV;
-               goto err;
+               goto unregister_v4l2;
        }
        if (cx18_init_struct1(cx)) {
                retval = -ENOMEM;
-               goto err;
+               goto unregister_v4l2;
        }
 
        CX18_DEBUG_INFO("base addr: 0x%08x\n", cx->base_addr);
        if (retval != 0)
                goto free_workqueue;
 
-       /* save cx in the pci struct for later use */
-       pci_set_drvdata(pci_dev, cx);
-
        /* map io memory */
        CX18_DEBUG_INFO("attempting ioremap at 0x%08x len 0x%08x\n",
                   cx->base_addr + CX18_MEM_OFFSET, CX18_MEM_SIZE);
        release_mem_region(cx->base_addr, CX18_MEM_SIZE);
 free_workqueue:
        destroy_workqueue(cx->work_queue);
+unregister_v4l2:
+       v4l2_device_unregister(&cx->v4l2_dev);
 err:
        if (retval == 0)
                retval = -ENODEV;
 
 static void cx18_remove(struct pci_dev *pci_dev)
 {
-       struct cx18 *cx = pci_get_drvdata(pci_dev);
+       struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
+       struct cx18 *cx = container_of(v4l2_dev, struct cx18, v4l2_dev);
 
        CX18_DEBUG_INFO("Removing Card #%d\n", cx->num);
 
 
        pci_disable_device(cx->pci_dev);
 
+       v4l2_device_unregister(v4l2_dev);
+
        CX18_INFO("Removed %s, card #%d\n", cx->card_name, cx->num);
 }
 
 
 #include <linux/dvb/audio.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
+#include <media/v4l2-device.h>
 #include <media/tuner.h>
 #include "cx18-mailbox.h"
 #include "cx18-av-core.h"
        int num;                /* board number, -1 during init! */
        char name[8];           /* board name for printk and interrupts (e.g. 'cx180') */
        struct pci_dev *pci_dev;
+       struct v4l2_device v4l2_dev;
+
        const struct cx18_card *card;   /* card information */
        const char *card_name;  /* full name of the card */
        const struct cx18_card_tuner_i2c *card_i2c; /* i2c addresses to probe for tuner */