diff options
author | Gerd Knorr <devnull@localhost> | 2004-07-29 21:35:48 +0000 |
---|---|---|
committer | Gerd Knorr <devnull@localhost> | 2004-07-29 21:35:48 +0000 |
commit | 38ea67b839abf0e8f150106314bc4dff33312e18 (patch) | |
tree | dbb14a85e437ad4c2eeec5876f24953c0494aaa6 /linux/drivers/media/video/cx88/cx88-video.c | |
parent | cd05362dcbcd4554765bd6d811981202533df047 (diff) | |
download | mediapointer-dvb-s2-38ea67b839abf0e8f150106314bc4dff33312e18.tar.gz mediapointer-dvb-s2-38ea67b839abf0e8f150106314bc4dff33312e18.tar.bz2 |
- cx88: big code reorganization.
- cx88: started merging blackbird patches, not working yet.
Diffstat (limited to 'linux/drivers/media/video/cx88/cx88-video.c')
-rw-r--r-- | linux/drivers/media/video/cx88/cx88-video.c | 299 |
1 files changed, 122 insertions, 177 deletions
diff --git a/linux/drivers/media/video/cx88/cx88-video.c b/linux/drivers/media/video/cx88/cx88-video.c index 910ef7c82..79ccb4989 100644 --- a/linux/drivers/media/video/cx88/cx88-video.c +++ b/linux/drivers/media/video/cx88/cx88-video.c @@ -1,4 +1,6 @@ /* + * $Id: cx88-video.c,v 1.29 2004/07/29 21:35:48 kraxel Exp $ + * * device driver for Conexant 2388x based TV cards * video4linux video interface * @@ -50,10 +52,6 @@ static unsigned int radio_nr[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET }; MODULE_PARM(radio_nr,"1-" __stringify(CX88_MAXBOARDS) "i"); MODULE_PARM_DESC(radio_nr,"radio device numbers"); -static unsigned int latency = UNSET; -MODULE_PARM(latency,"i"); -MODULE_PARM_DESC(latency,"pci latency timer"); - static unsigned int video_debug = 0; MODULE_PARM(video_debug,"i"); MODULE_PARM_DESC(video_debug,"enable debug messages [video]"); @@ -66,25 +64,16 @@ static unsigned int vid_limit = 16; MODULE_PARM(vid_limit,"i"); MODULE_PARM_DESC(vid_limit,"capture memory limit in megabytes"); -static unsigned int tuner[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET }; -MODULE_PARM(tuner,"1-" __stringify(CX88_MAXBOARDS) "i"); -MODULE_PARM_DESC(tuner,"tuner type"); - -static unsigned int card[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET }; -MODULE_PARM(card,"1-" __stringify(CX88_MAXBOARDS) "i"); -MODULE_PARM_DESC(card,"card type"); - static unsigned int nicam = 0; MODULE_PARM(nicam,"i"); MODULE_PARM_DESC(nicam,"tv audio is nicam"); #define dprintk(level,fmt, arg...) if (video_debug >= level) \ - printk(KERN_DEBUG "%s: " fmt, dev->name , ## arg) + printk(KERN_DEBUG "%s/0: " fmt, dev->core->name , ## arg) /* ------------------------------------------------------------------ */ -static struct list_head cx8800_devlist; -static unsigned int cx8800_devcount; +static LIST_HEAD(cx8800_devlist); /* ------------------------------------------------------------------- */ /* static data */ @@ -448,6 +437,7 @@ static const u32 xtal = 28636363; static int set_pll(struct cx8800_dev *dev, int prescale, u32 ofreq) { static u32 pre[] = { 0, 0, 0, 3, 2, 1 }; + struct cx88_core *core = dev->core; u64 pll; u32 reg; int i; @@ -461,7 +451,7 @@ static int set_pll(struct cx8800_dev *dev, int prescale, u32 ofreq) do_div(pll,xtal); reg = (pll & 0x3ffffff) | (pre[prescale] << 26); if (((reg >> 20) & 0x3f) < 14) { - printk("%s: pll out of range\n",dev->name); + printk("%s/0: pll out of range\n",core->name); return -1; } @@ -485,6 +475,8 @@ static int set_pll(struct cx8800_dev *dev, int prescale, u32 ofreq) static int set_tvaudio(struct cx8800_dev *dev) { + struct cx88_core *core = dev->core; + if (CX88_VMUX_TELEVISION != INPUT(dev->input)->type) return 0; @@ -511,8 +503,8 @@ static int set_tvaudio(struct cx8800_dev *dev) dev->tvaudio = WW_EIAJ; } else { - printk("%s: tvaudio support needs work for this tv norm [%s], sorry\n", - dev->name, dev->tvnorm->name); + printk("%s/0: tvaudio support needs work for this tv norm [%s], sorry\n", + core->name, dev->tvnorm->name); dev->tvaudio = 0; return 0; } @@ -529,6 +521,7 @@ static int set_tvaudio(struct cx8800_dev *dev) static int set_tvnorm(struct cx8800_dev *dev, struct cx8800_tvnorm *norm) { + struct cx88_core *core = dev->core; u32 fsc8; u32 adc_clock; u32 vdec_clock; @@ -608,7 +601,7 @@ static int set_tvnorm(struct cx8800_dev *dev, struct cx8800_tvnorm *norm) // tell i2c chips #ifdef V4L2_I2C_CLIENTS - cx8800_call_i2c_clients(dev,VIDIOC_S_STD,&norm->id); + cx88_call_i2c_clients(dev->core,VIDIOC_S_STD,&norm->id); #else { struct video_channel c; @@ -619,7 +612,7 @@ static int set_tvnorm(struct cx8800_dev *dev, struct cx8800_tvnorm *norm) c.norm = VIDEO_MODE_NTSC; if (norm->id & V4L2_STD_SECAM) c.norm = VIDEO_MODE_SECAM; - cx8800_call_i2c_clients(dev,VIDIOCSCHAN,&c); + cx88_call_i2c_clients(dev->core,VIDIOCSCHAN,&c); } #endif @@ -630,6 +623,7 @@ static int set_tvnorm(struct cx8800_dev *dev, struct cx8800_tvnorm *norm) static int set_scale(struct cx8800_dev *dev, unsigned int width, unsigned int height, enum v4l2_field field) { + struct cx88_core *core = dev->core; unsigned int swidth = norm_swidth(dev->tvnorm); unsigned int sheight = norm_maxh(dev->tvnorm); u32 value; @@ -696,6 +690,8 @@ static int set_scale(struct cx8800_dev *dev, unsigned int width, unsigned int he static int video_mux(struct cx8800_dev *dev, unsigned int input) { + struct cx88_core *core = dev->core; + dprintk(1,"video_mux: %d [vmux=%d,gpio=0x%x,0x%x,0x%x,0x%x]\n", input, INPUT(input)->vmux, INPUT(input)->gpio0,INPUT(input)->gpio1, @@ -730,8 +726,10 @@ static int start_video_dma(struct cx8800_dev *dev, struct cx88_dmaqueue *q, struct cx88_buffer *buf) { + struct cx88_core *core = dev->core; + /* setup fifo + format */ - cx88_sram_channel_setup(dev, &cx88_sram_channels[SRAM_CH21], + cx88_sram_channel_setup(dev->core, &cx88_sram_channels[SRAM_CH21], buf->bpl, buf->risc.dma); set_scale(dev, buf->vb.width, buf->vb.height, buf->vb.field); cx_write(MO_COLOR_CTRL, buf->fmt->cxformat | ColorFormatGamma); @@ -1282,15 +1280,17 @@ static int video_open(struct inode *inode, struct file *file) init_MUTEX(&fh->vbiq.lock); if (fh->radio) { + struct cx88_core *core = dev->core; + int board = core->board; dprintk(1,"video_open: setting radio device\n"); - cx_write(MO_GP0_IO, cx88_boards[dev->board].radio.gpio0); - cx_write(MO_GP1_IO, cx88_boards[dev->board].radio.gpio1); - cx_write(MO_GP2_IO, cx88_boards[dev->board].radio.gpio2); - cx_write(MO_GP3_IO, cx88_boards[dev->board].radio.gpio3); + cx_write(MO_GP0_IO, cx88_boards[board].radio.gpio0); + cx_write(MO_GP1_IO, cx88_boards[board].radio.gpio1); + cx_write(MO_GP2_IO, cx88_boards[board].radio.gpio2); + cx_write(MO_GP3_IO, cx88_boards[board].radio.gpio3); dev->tvaudio = WW_FM; cx88_set_tvaudio(dev); cx88_set_stereo(dev,V4L2_TUNER_MODE_STEREO); - cx8800_call_i2c_clients(dev,AUDC_SET_RADIO,NULL); + cx88_call_i2c_clients(dev->core,AUDC_SET_RADIO,NULL); } return 0; @@ -1375,6 +1375,7 @@ video_mmap(struct file *file, struct vm_area_struct * vma) static int get_control(struct cx8800_dev *dev, struct v4l2_control *ctl) { + struct cx88_core *core = dev->core; struct cx88_ctrl *c = NULL; u32 value; int i; @@ -1402,6 +1403,7 @@ static int get_control(struct cx8800_dev *dev, struct v4l2_control *ctl) static int set_control(struct cx8800_dev *dev, struct v4l2_control *ctl) { + struct cx88_core *core = dev->core; struct cx88_ctrl *c = NULL; u32 v_sat_value; u32 value; @@ -1579,15 +1581,16 @@ static int cx8800_s_fmt(struct cx8800_dev *dev, struct cx8800_fh *fh, static int video_do_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg) { - struct cx8800_fh *fh = file->private_data; - struct cx8800_dev *dev = fh->dev; + struct cx8800_fh *fh = file->private_data; + struct cx8800_dev *dev = fh->dev; + struct cx88_core *core = dev->core; #if 0 unsigned long flags; #endif int err; if (video_debug > 1) - cx88_print_ioctl(dev->name,cmd); + cx88_print_ioctl(core->name,cmd); switch (cmd) { case VIDIOC_QUERYCAP: { @@ -1595,7 +1598,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file, memset(cap,0,sizeof(*cap)); strcpy(cap->driver, "cx8800"); - strlcpy(cap->card, cx88_boards[dev->board].name, + strlcpy(cap->card, cx88_boards[core->board].name, sizeof(cap->card)); sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci)); cap->version = CX88_VERSION_CODE; @@ -1608,7 +1611,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file, V4L2_CAP_VIDEO_OVERLAY | #endif 0; - if (UNSET != dev->tuner_type) + if (UNSET != core->tuner_type) cap->capabilities |= V4L2_CAP_TUNER; return 0; @@ -1774,7 +1777,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file, struct v4l2_tuner *t = arg; u32 reg; - if (UNSET == dev->tuner_type) + if (UNSET == core->tuner_type) return -EINVAL; if (0 != t->index) return -EINVAL; @@ -1794,7 +1797,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file, { struct v4l2_tuner *t = arg; - if (UNSET == dev->tuner_type) + if (UNSET == core->tuner_type) return -EINVAL; if (0 != t->index) return -EINVAL; @@ -1805,7 +1808,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file, { struct v4l2_frequency *f = arg; - if (UNSET == dev->tuner_type) + if (UNSET == core->tuner_type) return -EINVAL; if (f->tuner != 0) return -EINVAL; @@ -1818,7 +1821,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file, { struct v4l2_frequency *f = arg; - if (UNSET == dev->tuner_type) + if (UNSET == core->tuner_type) return -EINVAL; if (f->tuner != 0) return -EINVAL; @@ -1829,9 +1832,9 @@ static int video_do_ioctl(struct inode *inode, struct file *file, down(&dev->lock); dev->freq = f->frequency; #ifdef V4L2_I2C_CLIENTS - cx8800_call_i2c_clients(dev,VIDIOC_S_FREQUENCY,f); + cx88_call_i2c_clients(dev->core,VIDIOC_S_FREQUENCY,f); #else - cx8800_call_i2c_clients(dev,VIDIOCSFREQ,&dev->freq); + cx88_call_i2c_clients(dev->core,VIDIOCSFREQ,&dev->freq); #endif up(&dev->lock); return 0; @@ -1911,11 +1914,12 @@ static int video_ioctl(struct inode *inode, struct file *file, static int radio_do_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg) { - struct cx8800_fh *fh = file->private_data; - struct cx8800_dev *dev = fh->dev; + struct cx8800_fh *fh = file->private_data; + struct cx8800_dev *dev = fh->dev; + struct cx88_core *core = dev->core; if (video_debug > 1) - cx88_print_ioctl(dev->name,cmd); + cx88_print_ioctl(core->name,cmd); switch (cmd) { case VIDIOC_QUERYCAP: @@ -1924,7 +1928,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file, memset(cap,0,sizeof(*cap)); strcpy(cap->driver, "cx8800"); - strlcpy(cap->card, cx88_boards[dev->board].name, + strlcpy(cap->card, cx88_boards[core->board].name, sizeof(cap->card)); sprintf(cap->bus_info,"PCI:%s", pci_name(dev->pci)); cap->version = CX88_VERSION_CODE; @@ -1944,7 +1948,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file, t->rangehigh = (int)(108*16); #ifdef V4L2_I2C_CLIENTS - cx8800_call_i2c_clients(dev,VIDIOC_G_TUNER,t); + cx88_call_i2c_clients(dev->core,VIDIOC_G_TUNER,t); #else { struct video_tuner vt; @@ -2034,12 +2038,12 @@ static int radio_ioctl(struct inode *inode, struct file *file, static void cx8800_vid_timeout(unsigned long data) { struct cx8800_dev *dev = (struct cx8800_dev*)data; + struct cx88_core *core = dev->core; struct cx88_dmaqueue *q = &dev->vidq; struct cx88_buffer *buf; unsigned long flags; - cx88_sram_channel_dump(dev, &cx88_sram_channels[SRAM_CH21]); - //cx88_risc_disasm(dev,&dev->vidq.stopper); + cx88_sram_channel_dump(dev->core, &cx88_sram_channels[SRAM_CH21]); cx_clear(MO_VID_DMACNTRL, 0x11); cx_clear(VID_CAPTURE_CONTROL, 0x06); @@ -2050,7 +2054,7 @@ static void cx8800_vid_timeout(unsigned long data) list_del(&buf->vb.queue); buf->vb.state = STATE_ERROR; wake_up(&buf->vb.done); - printk("%s: [%p/%d] timeout - dma=0x%08lx\n", dev->name, + printk("%s/0: [%p/%d] timeout - dma=0x%08lx\n", core->name, buf, buf->vb.i, (unsigned long)buf->risc.dma); } restart_video_queue(dev,q); @@ -2085,6 +2089,7 @@ static void cx8800_wakeup(struct cx8800_dev *dev, static void cx8800_vid_irq(struct cx8800_dev *dev) { + struct cx88_core *core = dev->core; u32 status, mask, count; status = cx_read(MO_VID_INTSTAT); @@ -2093,15 +2098,15 @@ static void cx8800_vid_irq(struct cx8800_dev *dev) return; cx_write(MO_VID_INTSTAT, status); if (irq_debug || (status & mask & ~0xff)) - cx88_print_irqbits(dev->name, "irq vid", + cx88_print_irqbits(core->name, "irq vid", cx88_vid_irqs, status, mask); /* risc op code error */ if (status & (1 << 16)) { - printk(KERN_WARNING "%s: video risc op code error\n",dev->name); + printk(KERN_WARNING "%s/0: video risc op code error\n",core->name); cx_clear(MO_VID_DMACNTRL, 0x11); cx_clear(VID_CAPTURE_CONTROL, 0x06); - cx88_sram_channel_dump(dev, &cx88_sram_channels[SRAM_CH21]); + cx88_sram_channel_dump(dev->core, &cx88_sram_channels[SRAM_CH21]); } /* risc1 y */ @@ -2140,6 +2145,7 @@ static void cx8800_vid_irq(struct cx8800_dev *dev) static irqreturn_t cx8800_irq(int irq, void *dev_id, struct pt_regs *regs) { struct cx8800_dev *dev = dev_id; + struct cx88_core *core = dev->core; u32 status, mask; int loop, handled = 0; @@ -2151,15 +2157,15 @@ static irqreturn_t cx8800_irq(int irq, void *dev_id, struct pt_regs *regs) handled = 1; cx_write(MO_PCI_INTSTAT, status); if (irq_debug || (status & mask & ~0x1f)) - cx88_print_irqbits(dev->name, "irq pci", + cx88_print_irqbits(core->name, "irq pci", cx88_pci_irqs, status, mask); if (status & 1) cx8800_vid_irq(dev); }; if (10 == loop) { - printk(KERN_WARNING "%s: irq loop -- clearing mask\n", - dev->name); + printk(KERN_WARNING "%s/0: irq loop -- clearing mask\n", + core->name); cx_write(MO_PCI_INTMSK,0); } @@ -2222,6 +2228,8 @@ struct video_device cx8800_radio_template = static void cx8800_shutdown(struct cx8800_dev *dev) { + struct cx88_core *core = dev->core; + /* disable RISC controller + IRQs */ cx_write(MO_DEV_CNTRL2, 0); @@ -2246,6 +2254,8 @@ static void cx8800_shutdown(struct cx8800_dev *dev) static int cx8800_reset(struct cx8800_dev *dev) { + struct cx88_core *core = dev->core; + dprintk(1,"cx8800_reset\n"); cx8800_shutdown(dev); @@ -2260,12 +2270,13 @@ static int cx8800_reset(struct cx8800_dev *dev) schedule_timeout(HZ/10); /* init sram */ - cx88_sram_channel_setup(dev, &cx88_sram_channels[SRAM_CH21], 720*4, 0); - cx88_sram_channel_setup(dev, &cx88_sram_channels[SRAM_CH22], 128, 0); - cx88_sram_channel_setup(dev, &cx88_sram_channels[SRAM_CH23], 128, 0); - cx88_sram_channel_setup(dev, &cx88_sram_channels[SRAM_CH24], 128, 0); - cx88_sram_channel_setup(dev, &cx88_sram_channels[SRAM_CH25], 128, 0); - cx88_sram_channel_setup(dev, &cx88_sram_channels[SRAM_CH26], 128, 0); + cx88_sram_channel_setup(dev->core, &cx88_sram_channels[SRAM_CH21], 720*4, 0); + cx88_sram_channel_setup(dev->core, &cx88_sram_channels[SRAM_CH22], 128, 0); + cx88_sram_channel_setup(dev->core, &cx88_sram_channels[SRAM_CH23], 128, 0); + cx88_sram_channel_setup(dev->core, &cx88_sram_channels[SRAM_CH24], 128, 0); + cx88_sram_channel_setup(dev->core, &cx88_sram_channels[SRAM_CH25], 128, 0); + cx88_sram_channel_setup(dev->core, &cx88_sram_channels[SRAM_CH26], 128, 0); + // cx88_sram_channel_setup(dev->core, &cx88_sram_channels[SRAM_CH28], 512, 0); /* misc init ... */ cx_write(MO_INPUT_FORMAT, ((1 << 13) | // agc enable @@ -2293,26 +2304,6 @@ static int cx8800_reset(struct cx8800_dev *dev) return 0; } -static struct video_device *vdev_init(struct cx8800_dev *dev, - struct video_device *template, - char *type) -{ - struct video_device *vfd; - - vfd = video_device_alloc(); - if (NULL == vfd) - return NULL; - *vfd = *template; - vfd->minor = -1; -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) - vfd->dev = &dev->pci->dev; - vfd->release = video_device_release; -#endif - snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", - dev->name, type, cx88_boards[dev->board].name); - return vfd; -} - static void cx8800_unregister_video(struct cx8800_dev *dev) { if (dev->radio_dev) { @@ -2342,7 +2333,7 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, const struct pci_device_id *pci_id) { struct cx8800_dev *dev; - unsigned int i; + struct cx88_core *core; int err; dev = kmalloc(sizeof(*dev),GFP_KERNEL); @@ -2354,68 +2345,29 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, dev->pci = pci_dev; if (pci_enable_device(pci_dev)) { err = -EIO; - goto fail1; + goto fail_free; } - sprintf(dev->name,"cx%x[%d]",pci_dev->device,cx8800_devcount); - - /* pci quirks */ - cx88_pci_quirks(dev->name, dev->pci, &latency); - if (UNSET != latency) { - printk(KERN_INFO "%s: setting pci latency timer to %d\n", - dev->name,latency); - pci_write_config_byte(pci_dev, PCI_LATENCY_TIMER, latency); + core = cx88_core_get(dev->pci); + if (NULL == core) { + err = -EINVAL; + goto fail_free; } + dev->core = core; /* print pci info */ pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev); pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat); - printk(KERN_INFO "%s: found at %s, rev: %d, irq: %d, " - "latency: %d, mmio: 0x%lx\n", dev->name, + printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, " + "latency: %d, mmio: 0x%lx\n", core->name, pci_name(pci_dev), dev->pci_rev, pci_dev->irq, dev->pci_lat,pci_resource_start(pci_dev,0)); pci_set_master(pci_dev); if (!pci_dma_supported(pci_dev,0xffffffff)) { - printk("%s: Oops: no 32bit PCI DMA ???\n",dev->name); + printk("%s/0: Oops: no 32bit PCI DMA ???\n",core->name); err = -EIO; - goto fail1; - } - - /* board config */ - dev->board = UNSET; - if (card[cx8800_devcount] < cx88_bcount) - dev->board = card[cx8800_devcount]; - for (i = 0; UNSET == dev->board && i < cx88_idcount; i++) - if (pci_dev->subsystem_vendor == cx88_subids[i].subvendor && - pci_dev->subsystem_device == cx88_subids[i].subdevice) - dev->board = cx88_subids[i].card; - if (UNSET == dev->board) { - dev->board = CX88_BOARD_UNKNOWN; - cx88_card_list(dev); - } - printk(KERN_INFO "%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n", - dev->name,pci_dev->subsystem_vendor, - pci_dev->subsystem_device,cx88_boards[dev->board].name, - dev->board, card[cx8800_devcount] == dev->board ? - "insmod option" : "autodetected"); - - dev->tuner_type = tuner[cx8800_devcount]; - if (UNSET == dev->tuner_type) - dev->tuner_type = cx88_boards[dev->board].tuner_type; - dev->tda9887_conf = cx88_boards[dev->board].tda9887_conf; - - /* get mmio */ - if (!request_mem_region(pci_resource_start(pci_dev,0), - pci_resource_len(pci_dev,0), - dev->name)) { - err = -EBUSY; - printk(KERN_ERR "%s: can't get MMIO memory @ 0x%lx\n", - dev->name,pci_resource_start(pci_dev,0)); - goto fail1; - } - dev->lmmio = ioremap(pci_resource_start(pci_dev,0), - pci_resource_len(pci_dev,0)); - dev->bmmio = (u8*)dev->lmmio; + goto fail_core; + } /* initialize driver struct */ init_MUTEX(&dev->lock); @@ -2445,67 +2397,67 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, /* get irq */ err = request_irq(pci_dev->irq, cx8800_irq, - SA_SHIRQ | SA_INTERRUPT, dev->name, dev); + SA_SHIRQ | SA_INTERRUPT, core->name, dev); if (err < 0) { printk(KERN_ERR "%s: can't get IRQ %d\n", - dev->name,pci_dev->irq); - goto fail2; + core->name,pci_dev->irq); + goto fail_core; } /* register i2c bus + load i2c helpers */ - cx8800_i2c_init(dev); - cx88_card_setup(dev); + cx88_card_setup(dev->core); /* load and configure helper modules */ - if (TUNER_ABSENT != dev->tuner_type) + if (TUNER_ABSENT != core->tuner_type) request_module("tuner"); - if (dev->tda9887_conf) + if (core->tda9887_conf) request_module("tda9887"); - if (dev->tuner_type != UNSET) - cx8800_call_i2c_clients(dev,TUNER_SET_TYPE,&dev->tuner_type); - if (dev->tda9887_conf) - cx8800_call_i2c_clients(dev,TDA9887_SET_CONFIG,&dev->tda9887_conf); + if (core->tuner_type != UNSET) + cx88_call_i2c_clients(dev->core,TUNER_SET_TYPE,&core->tuner_type); + if (core->tda9887_conf) + cx88_call_i2c_clients(dev->core,TDA9887_SET_CONFIG,&core->tda9887_conf); /* register v4l devices */ - dev->video_dev = vdev_init(dev,&cx8800_video_template,"video"); + dev->video_dev = cx88_vdev_init(core,dev->pci, + &cx8800_video_template,"video"); err = video_register_device(dev->video_dev,VFL_TYPE_GRABBER, - video_nr[cx8800_devcount]); + video_nr[core->nr]); if (err < 0) { printk(KERN_INFO "%s: can't register video device\n", - dev->name); - goto fail3; + core->name); + goto fail_unreg; } - printk(KERN_INFO "%s: registered device video%d [v4l2]\n", - dev->name,dev->video_dev->minor & 0x1f); + printk(KERN_INFO "%s/0: registered device video%d [v4l2]\n", + core->name,dev->video_dev->minor & 0x1f); - dev->vbi_dev = vdev_init(dev,&cx8800_vbi_template,"vbi"); + dev->vbi_dev = cx88_vdev_init(core,dev->pci,&cx8800_vbi_template,"vbi"); err = video_register_device(dev->vbi_dev,VFL_TYPE_VBI, - vbi_nr[cx8800_devcount]); + vbi_nr[core->nr]); if (err < 0) { - printk(KERN_INFO "%s: can't register vbi device\n", - dev->name); - goto fail3; + printk(KERN_INFO "%s/0: can't register vbi device\n", + core->name); + goto fail_unreg; } - printk(KERN_INFO "%s: registered device vbi%d\n", - dev->name,dev->vbi_dev->minor & 0x1f); + printk(KERN_INFO "%s/0: registered device vbi%d\n", + core->name,dev->vbi_dev->minor & 0x1f); - if (dev->has_radio) { - dev->radio_dev = vdev_init(dev,&cx8800_radio_template,"radio"); + if (core->has_radio) { + dev->radio_dev = cx88_vdev_init(core,dev->pci, + &cx8800_radio_template,"radio"); err = video_register_device(dev->radio_dev,VFL_TYPE_RADIO, - radio_nr[cx8800_devcount]); + radio_nr[core->nr]); if (err < 0) { - printk(KERN_INFO "%s: can't register radio device\n", - dev->name); - goto fail3; + printk(KERN_INFO "%s/0: can't register radio device\n", + core->name); + goto fail_unreg; } - printk(KERN_INFO "%s: registered device radio%d\n", - dev->name,dev->radio_dev->minor & 0x1f); + printk(KERN_INFO "%s/0: registered device radio%d\n", + core->name,dev->radio_dev->minor & 0x1f); } /* everything worked */ list_add_tail(&dev->devlist,&cx8800_devlist); pci_set_drvdata(pci_dev,dev); - cx8800_devcount++; /* initial device configuration */ down(&dev->lock); @@ -2519,15 +2471,12 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, dev->tpid = kernel_thread(cx88_audio_thread, dev, 0); return 0; - fail3: +fail_unreg: cx8800_unregister_video(dev); - if (0 == dev->i2c_rc) - i2c_bit_del_bus(&dev->i2c_adap); free_irq(pci_dev->irq, dev); - fail2: - release_mem_region(pci_resource_start(pci_dev,0), - pci_resource_len(pci_dev,0)); - fail1: +fail_core: + cx88_core_put(core,dev->pci); +fail_free: kfree(dev); return err; } @@ -2545,28 +2494,24 @@ static void __devexit cx8800_finidev(struct pci_dev *pci_dev) pci_disable_device(pci_dev); /* unregister stuff */ - if (0 == dev->i2c_rc) - i2c_bit_del_bus(&dev->i2c_adap); free_irq(pci_dev->irq, dev); - release_mem_region(pci_resource_start(pci_dev,0), - pci_resource_len(pci_dev,0)); - cx8800_unregister_video(dev); pci_set_drvdata(pci_dev, NULL); /* free memory */ btcx_riscmem_free(dev->pci,&dev->vidq.stopper); list_del(&dev->devlist); - cx8800_devcount--; + cx88_core_put(dev->core,dev->pci); kfree(dev); } static int cx8800_suspend(struct pci_dev *pci_dev, u32 state) { struct cx8800_dev *dev = pci_get_drvdata(pci_dev); + struct cx88_core *core = dev->core; - printk("%s: suspend %d\n", dev->name, state); + printk("%s: suspend %d\n", core->name, state); cx8800_shutdown(dev); del_timer(&dev->vidq.timeout); @@ -2582,8 +2527,9 @@ static int cx8800_suspend(struct pci_dev *pci_dev, u32 state) static int cx8800_resume(struct pci_dev *pci_dev) { struct cx8800_dev *dev = pci_get_drvdata(pci_dev); + struct cx88_core *core = dev->core; - printk("%s: resume\n", dev->name); + printk("%s: resume\n", core->name); if (dev->state.disabled) { pci_enable_device(pci_dev); @@ -2629,7 +2575,6 @@ static struct pci_driver cx8800_pci_driver = { static int cx8800_init(void) { - INIT_LIST_HEAD(&cx8800_devlist); printk(KERN_INFO "cx2388x v4l2 driver version %d.%d.%d loaded\n", (CX88_VERSION_CODE >> 16) & 0xff, (CX88_VERSION_CODE >> 8) & 0xff, |