diff options
Diffstat (limited to 'linux/drivers/media/video')
-rw-r--r-- | linux/drivers/media/video/cx23885/cx23885-cards.c | 59 | ||||
-rw-r--r-- | linux/drivers/media/video/cx23885/cx23885-core.c | 363 | ||||
-rw-r--r-- | linux/drivers/media/video/cx23885/cx23885-dvb.c | 50 | ||||
-rw-r--r-- | linux/drivers/media/video/cx23885/cx23885-i2c.c | 6 | ||||
-rw-r--r-- | linux/drivers/media/video/cx23885/cx23885-reg.h | 27 | ||||
-rw-r--r-- | linux/drivers/media/video/cx23885/cx23885.h | 23 | ||||
-rw-r--r-- | linux/drivers/media/video/cx88/cx88-alsa.c | 8 | ||||
-rw-r--r-- | linux/drivers/media/video/ir-kbd-i2c.c | 3 | ||||
-rw-r--r-- | linux/drivers/media/video/saa7134/saa7134-cards.c | 10 | ||||
-rw-r--r-- | linux/drivers/media/video/tuner-core.c | 3 |
10 files changed, 365 insertions, 187 deletions
diff --git a/linux/drivers/media/video/cx23885/cx23885-cards.c b/linux/drivers/media/video/cx23885/cx23885-cards.c index e35d221da..3ea417146 100644 --- a/linux/drivers/media/video/cx23885/cx23885-cards.c +++ b/linux/drivers/media/video/cx23885/cx23885-cards.c @@ -110,6 +110,10 @@ struct cx23885_board cx23885_boards[] = { .gpio0 = 0xff02, }}, }, + [CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP] = { + .name = "DViCO FusionHDTV5 Express", + .portb = CX23885_MPEG_DVB, + }, }; const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); @@ -137,6 +141,10 @@ struct cx23885_subid cx23885_subids[] = { .subvendor = 0x0070, .subdevice = 0x7911, .card = CX23885_BOARD_HAUPPAUGE_HVR1250, + },{ + .subvendor = 0x18ac, + .subdevice = 0xd500, + .card = CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP, }, }; const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); @@ -190,8 +198,43 @@ static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data) dev->name, tv.model); } +void cx23885_gpio_setup(struct cx23885_dev *dev) +{ + switch(dev->board) { + case CX23885_BOARD_HAUPPAUGE_HVR1250: + /* GPIO-0 cx24227 demodulator reset */ + cx_set(GP0_IO, 0x00010001); /* Bring the part out of reset */ + break; + case CX23885_BOARD_HAUPPAUGE_HVR1800: + /* GPIO-0 656_CLK */ + /* GPIO-1 656_D0 */ + /* GPIO-2 8295A Reset */ + /* GPIO-3-10 cx23417 data0-7 */ + /* GPIO-11-14 cx23417 addr0-3 */ + /* GPIO-15-18 cx23417 READY, CS, RD, WR */ + /* GPIO-19 IR_RX */ + // FIXME: Analog requires the tuner is brought out of reset + break; + } +} + +int cx23885_ir_init(struct cx23885_dev *dev) +{ + switch (dev->board) { + case CX23885_BOARD_HAUPPAUGE_HVR1250: + case CX23885_BOARD_HAUPPAUGE_HVR1800: + /* FIXME: Implement me */ + break; + } + + return 0; +} + void cx23885_card_setup(struct cx23885_dev *dev) { + struct cx23885_tsport *ts1 = &dev->ts1; + struct cx23885_tsport *ts2 = &dev->ts2; + static u8 eeprom[256]; if (dev->i2c_bus[0].i2c_rc == 0) { @@ -208,6 +251,22 @@ void cx23885_card_setup(struct cx23885_dev *dev) hauppauge_eeprom(dev, eeprom+0x80); break; } + + switch (dev->board) { + case CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP: + ts1->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ + ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ + ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; + break; + case CX23885_BOARD_HAUPPAUGE_HVR1250: + case CX23885_BOARD_HAUPPAUGE_HVR1800: + case CX23885_BOARD_HAUPPAUGE_HVR1800lp: + default: + ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ + ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ + ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; + } + } /* ------------------------------------------------------------------ */ diff --git a/linux/drivers/media/video/cx23885/cx23885-core.c b/linux/drivers/media/video/cx23885/cx23885-core.c index c32d836b6..03f66e267 100644 --- a/linux/drivers/media/video/cx23885/cx23885-core.c +++ b/linux/drivers/media/video/cx23885/cx23885-core.c @@ -101,12 +101,12 @@ struct sram_channel cx23885_sram_channels[] = { .cnt2_reg = DMA2_CNT2, }, [SRAM_CH03] = { - .name = "ch3", - .cmds_start = 0x0, - .ctrl_start = 0x0, - .cdt = 0x0, - .fifo_start = 0x0, - .fifo_size = 0x0, + .name = "TS1 B", + .cmds_start = 0x100A0, + .ctrl_start = 0x10780, + .cdt = 0x10400, + .fifo_start = 0x5000, + .fifo_size = 0x1000, .ptr1_reg = DMA3_PTR1, .ptr2_reg = DMA3_PTR2, .cnt1_reg = DMA3_CNT1, @@ -597,7 +597,7 @@ void cx23885_reset(struct cx23885_dev *dev) cx23885_sram_channel_setup(dev, &dev->sram_channels[ SRAM_CH01 ], 188*4, 0); cx23885_sram_channel_setup(dev, &dev->sram_channels[ SRAM_CH02 ], 128, 0); - cx23885_sram_channel_setup(dev, &dev->sram_channels[ SRAM_CH03 ], 128, 0); + cx23885_sram_channel_setup(dev, &dev->sram_channels[ SRAM_CH03 ], 188*4, 0); cx23885_sram_channel_setup(dev, &dev->sram_channels[ SRAM_CH04 ], 128, 0); cx23885_sram_channel_setup(dev, &dev->sram_channels[ SRAM_CH05 ], 128, 0); cx23885_sram_channel_setup(dev, &dev->sram_channels[ SRAM_CH06 ], 188*4, 0); @@ -605,24 +605,7 @@ void cx23885_reset(struct cx23885_dev *dev) cx23885_sram_channel_setup(dev, &dev->sram_channels[ SRAM_CH08 ], 128, 0); cx23885_sram_channel_setup(dev, &dev->sram_channels[ SRAM_CH09 ], 128, 0); - switch(dev->board) { - case CX23885_BOARD_HAUPPAUGE_HVR1250: - /* GPIO-0 cx24227 demodulator reset */ - dprintk( 1, "%s() Configuring HVR1250 GPIO's\n", __FUNCTION__); - cx_set(GP0_IO, 0x00010001); /* Bring the part out of reset */ - break; - case CX23885_BOARD_HAUPPAUGE_HVR1800: - /* GPIO-0 656_CLK */ - /* GPIO-1 656_D0 */ - /* GPIO-2 8295A Reset */ - /* GPIO-3-10 cx23417 data0-7 */ - /* GPIO-11-14 cx23417 addr0-3 */ - /* GPIO-15-18 cx23417 READY, CS, RD, WR */ - /* GPIO-19 IR_RX */ - dprintk( 1, "%s() Configuring HVR1800 GPIO's\n", __FUNCTION__); - // FIXME: Analog requires the tuner is brought out of reset - break; - } + cx23885_gpio_setup(dev); } @@ -657,17 +640,68 @@ static void cx23885_timeout(unsigned long data); int cx23885_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc, u32 reg, u32 mask, u32 value); -static int cx23885_ir_init(struct cx23885_dev *dev) +static int cx23885_init_tsport(struct cx23885_dev *dev, struct cx23885_tsport *port, int portno) { - dprintk(1, "%s()\n", __FUNCTION__); - - switch (dev->board) { - case CX23885_BOARD_HAUPPAUGE_HVR1250: - case CX23885_BOARD_HAUPPAUGE_HVR1800: - dprintk(1, "%s() FIXME - Implement IR support\n", __FUNCTION__); + dprintk(1, "%s(portno=%d)\n", __FUNCTION__, portno); + + /* Transport bus init dma queue - Common settings */ + port->dma_ctl_val = 0x11; /* Enable RISC controller and Fifo */ + port->ts_int_msk_val = 0x1111; /* TS port bits for RISC */ + + spin_lock_init(&port->slock); + port->dev = dev; + port->nr = portno; + + INIT_LIST_HEAD(&port->mpegq.active); + INIT_LIST_HEAD(&port->mpegq.queued); + port->mpegq.timeout.function = cx23885_timeout; + port->mpegq.timeout.data = (unsigned long)port; + init_timer(&port->mpegq.timeout); + + switch(portno) { + case 1: + port->reg_gpcnt = VID_B_GPCNT; + port->reg_gpcnt_ctl = VID_B_GPCNT_CTL; + port->reg_dma_ctl = VID_B_DMA_CTL; + port->reg_lngth = VID_B_LNGTH; + port->reg_hw_sop_ctrl = VID_B_HW_SOP_CTL; + port->reg_gen_ctrl = VID_B_GEN_CTL; + port->reg_bd_pkt_status = VID_B_BD_PKT_STATUS; + port->reg_sop_status = VID_B_SOP_STATUS; + port->reg_fifo_ovfl_stat = VID_B_FIFO_OVFL_STAT; + port->reg_vld_misc = VID_B_VLD_MISC; + port->reg_ts_clk_en = VID_B_TS_CLK_EN; + port->reg_src_sel = VID_B_SRC_SEL; + port->reg_ts_int_msk = VID_B_INT_MSK; + port->reg_ts_int_stat = VID_B_INT_STAT; + port->sram_chno = SRAM_CH03; /* VID_B */ + port->pci_irqmask = 0x02; /* VID_B bit1 */ break; + case 2: + port->reg_gpcnt = VID_C_GPCNT; + port->reg_gpcnt_ctl = VID_C_GPCNT_CTL; + port->reg_dma_ctl = VID_C_DMA_CTL; + port->reg_lngth = VID_C_LNGTH; + port->reg_hw_sop_ctrl = VID_C_HW_SOP_CTL; + port->reg_gen_ctrl = VID_C_GEN_CTL; + port->reg_bd_pkt_status = VID_C_BD_PKT_STATUS; + port->reg_sop_status = VID_C_SOP_STATUS; + port->reg_fifo_ovfl_stat = VID_C_FIFO_OVFL_STAT; + port->reg_vld_misc = VID_C_VLD_MISC; + port->reg_ts_clk_en = VID_C_TS_CLK_EN; + port->reg_src_sel = 0; + port->reg_ts_int_msk = VID_C_INT_MSK; + port->reg_ts_int_stat = VID_C_INT_STAT; + port->sram_chno = SRAM_CH06; /* VID_C */ + port->pci_irqmask = 0x04; /* VID_C bit2 */ + break; + default: + BUG(); } + cx23885_risc_stopper(dev->pci, &port->mpegq.stopper, + port->reg_dma_ctl, port->dma_ctl_val, 0x00); + return 0; } @@ -680,6 +714,39 @@ static int cx23885_dev_setup(struct cx23885_dev *dev) atomic_inc(&dev->refcount); dev->nr = cx23885_devcount++; + sprintf(dev->name, "cx23885[%d]", dev->nr); + + mutex_lock(&devlist); + list_add_tail(&dev->devlist, &cx23885_devlist); + mutex_unlock(&devlist); + + /* Configure the internal memory */ + if(dev->pci->device == 0x8880) { + dev->bridge = CX23885_BRIDGE_887; + dev->sram_channels = cx23887_sram_channels; + } else + if(dev->pci->device == 0x8852) { + dev->bridge = CX23885_BRIDGE_885; + dev->sram_channels = cx23885_sram_channels; + } else + BUG(); + + dprintk(1, "%s() Memory configured for PCIe bridge type %d\n", + __FUNCTION__, dev->bridge); + + /* board config */ + dev->board = UNSET; + if (card[dev->nr] < cx23885_bcount) + dev->board = card[dev->nr]; + for (i = 0; UNSET == dev->board && i < cx23885_idcount; i++) + if (dev->pci->subsystem_vendor == cx23885_subids[i].subvendor && + dev->pci->subsystem_device == cx23885_subids[i].subdevice) + dev->board = cx23885_subids[i].card; + if (UNSET == dev->board) { + dev->board = CX23885_BOARD_UNKNOWN; + cx23885_card_list(dev); + } + dev->pci_bus = dev->pci->bus->number; dev->pci_slot = PCI_SLOT(dev->pci->devfn); dev->pci_irqmask = 0x001f00; @@ -714,41 +781,11 @@ static int cx23885_dev_setup(struct cx23885_dev *dev) dev->i2c_bus[2].reg_wdata = I2C3_WDATA; dev->i2c_bus[2].i2c_period = (0x07 << 24); /* 1.95MHz */ - /* Transport bus init dma queue */ - spin_lock_init(&dev->ts2.slock); - dev->ts2.dev = dev; - dev->ts2.nr = 2; - dev->ts2.sram_chno = SRAM_CH06; - INIT_LIST_HEAD(&dev->ts2.mpegq.active); - INIT_LIST_HEAD(&dev->ts2.mpegq.queued); - dev->ts2.mpegq.timeout.function = cx23885_timeout; - dev->ts2.mpegq.timeout.data = (unsigned long)&dev->ts2; - init_timer(&dev->ts2.mpegq.timeout); - - dev->ts2.reg_gpcnt = VID_C_GPCNT; - dev->ts2.reg_gpcnt_ctl = VID_C_GPCNT_CTL; - dev->ts2.reg_dma_ctl = VID_C_DMA_CTL; - dev->ts2.reg_lngth = VID_C_LNGTH; - dev->ts2.reg_hw_sop_ctrl = VID_C_HW_SOP_CTL; - dev->ts2.reg_gen_ctrl = VID_C_GEN_CTL; - dev->ts2.reg_bd_pkt_status = VID_C_BD_PKT_STATUS; - dev->ts2.reg_sop_status = VID_C_SOP_STATUS; - dev->ts2.reg_fifo_ovfl_stat = VID_C_FIFO_OVFL_STAT; - dev->ts2.reg_vld_misc = VID_C_VLD_MISC; - dev->ts2.reg_ts_clk_en = VID_C_TS_CLK_EN; - dev->ts2.reg_ts_int_msk = VID_C_INT_MSK; - - // FIXME: Make this board specific - dev->ts2.pci_irqmask = 0x04; /* TS Port 2 bit */ - dev->ts2.dma_ctl_val = 0x11; /* Enable RISC controller and Fifo */ - dev->ts2.ts_int_msk_val = 0x1111; /* TS port bits for RISC */ - dev->ts2.gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ - dev->ts2.ts_clk_en_val = 0x1; /* Enable TS_CLK */ - - cx23885_risc_stopper(dev->pci, &dev->ts2.mpegq.stopper, - dev->ts2.reg_dma_ctl, dev->ts2.dma_ctl_val, 0x00); + if(cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) + cx23885_init_tsport(dev, &dev->ts1, 1); - sprintf(dev->name, "cx23885[%d]", dev->nr); + if(cx23885_boards[dev->board].portc == CX23885_MPEG_DVB) + cx23885_init_tsport(dev, &dev->ts2, 2); if (get_resources(dev) < 0) { printk(KERN_ERR "CORE %s No more PCIe resources for " @@ -760,46 +797,18 @@ static int cx23885_dev_setup(struct cx23885_dev *dev) goto fail_free; } - mutex_lock(&devlist); - list_add_tail(&dev->devlist, &cx23885_devlist); - mutex_unlock(&devlist); - /* PCIe stuff */ dev->lmmio = ioremap(pci_resource_start(dev->pci,0), pci_resource_len(dev->pci,0)); dev->bmmio = (u8 __iomem *)dev->lmmio; - /* board config */ - dev->board = UNSET; - if (card[dev->nr] < cx23885_bcount) - dev->board = card[dev->nr]; - for (i = 0; UNSET == dev->board && i < cx23885_idcount; i++) - if (dev->pci->subsystem_vendor == cx23885_subids[i].subvendor && - dev->pci->subsystem_device == cx23885_subids[i].subdevice) - dev->board = cx23885_subids[i].card; - if (UNSET == dev->board) { - dev->board = CX23885_BOARD_UNKNOWN; - cx23885_card_list(dev); - } printk(KERN_INFO "CORE %s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n", dev->name, dev->pci->subsystem_vendor, dev->pci->subsystem_device, cx23885_boards[dev->board].name, dev->board, card[dev->nr] == dev->board ? "insmod option" : "autodetected"); - /* Configure the internal memory */ - if(dev->pci->device == 0x8880) { - dev->bridge = CX23885_BRIDGE_887; - dev->sram_channels = cx23887_sram_channels; - } else - if(dev->pci->device == 0x8852) { - dev->bridge = CX23885_BRIDGE_885; - dev->sram_channels = cx23885_sram_channels; - } - dprintk(1, "%s() Memory configured for PCIe bridge type %d\n", - __FUNCTION__, dev->bridge); - cx23885_pci_quirks(dev); /* init hardware */ @@ -809,13 +818,21 @@ static int cx23885_dev_setup(struct cx23885_dev *dev) cx23885_i2c_register(&dev->i2c_bus[1]); cx23885_i2c_register(&dev->i2c_bus[2]); cx23885_call_i2c_clients (&dev->i2c_bus[0], TUNER_SET_STANDBY, NULL); - cx23885_card_setup(dev); cx23885_ir_init(dev); - if (cx23885_dvb_register(&dev->ts2) < 0) { - printk(KERN_ERR "%s() Failed to register dvb adapters\n", - __FUNCTION__); + if(cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) { + if (cx23885_dvb_register(&dev->ts1) < 0) { + printk(KERN_ERR "%s() Failed to register dvb adapters on VID_B\n", + __FUNCTION__); + } + } + + if(cx23885_boards[dev->board].portc == CX23885_MPEG_DVB) { + if (cx23885_dvb_register(&dev->ts2) < 0) { + printk(KERN_ERR "%s() Failed to register dvb adapters on VID_C\n", + __FUNCTION__); + } } return 0; @@ -833,7 +850,12 @@ void cx23885_dev_unregister(struct cx23885_dev *dev) if (!atomic_dec_and_test(&dev->refcount)) return; - cx23885_dvb_unregister(&dev->ts2); + if(cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) + cx23885_dvb_unregister(&dev->ts1); + + if(cx23885_boards[dev->board].portc == CX23885_MPEG_DVB) + cx23885_dvb_unregister(&dev->ts2); + cx23885_i2c_unregister(&dev->i2c_bus[2]); cx23885_i2c_unregister(&dev->i2c_bus[1]); cx23885_i2c_unregister(&dev->i2c_bus[0]); @@ -1016,32 +1038,28 @@ static int cx23885_start_dma(struct cx23885_tsport *port, /* write TS length to chip */ cx_write(port->reg_lngth, buf->vb.width); - if (!(cx23885_boards[dev->board].portc & CX23885_MPEG_DVB)) { - printk( "%s() Failed. Unsupported value in .portc (0x%08x)\n", - __FUNCTION__, cx23885_boards[dev->board].portc ); + if ( (!(cx23885_boards[dev->board].portb & CX23885_MPEG_DVB)) && + (!(cx23885_boards[dev->board].portc & CX23885_MPEG_DVB)) ) { + printk( "%s() Failed. Unsupported value in .portb/c (0x%08x)/(0x%08x)\n", + __FUNCTION__, + cx23885_boards[dev->board].portb, + cx23885_boards[dev->board].portc ); return -EINVAL; } udelay(100); + /* If the port supports SRC SELECT, configure it */ + if(port->reg_src_sel) + cx_write(port->reg_src_sel, port->src_sel_val); + cx_write(port->reg_hw_sop_ctrl, 0x47 << 16 | 188 << 4); cx_write(port->reg_ts_clk_en, port->ts_clk_en_val); - - switch (dev->board) { - case CX23885_BOARD_HAUPPAUGE_HVR1250: - case CX23885_BOARD_HAUPPAUGE_HVR1800lp: - case CX23885_BOARD_HAUPPAUGE_HVR1800: - cx_write(port->reg_vld_misc, 0x00); - dprintk(1, "%s() Configuring HVR1800/lp/1500 board\n", - __FUNCTION__); - break; - default: - printk(KERN_ERR "%s() error, default case", __FUNCTION__ ); - } - + cx_write(port->reg_vld_misc, 0x00); cx_write(port->reg_gen_ctrl, port->gen_ctrl_val); udelay(100); + // NOTE: this is 2 (reserved) for portb, does it matter? /* reset counter to zero */ cx_write(port->reg_gpcnt_ctl, 3); q->count = 1; @@ -1056,7 +1074,7 @@ static int cx23885_start_dma(struct cx23885_tsport *port, cx_set(PCI_INT_MSK, dev->pci_irqmask | port->pci_irqmask); break; default: - printk(KERN_ERR "%s() error, default case", __FUNCTION__ ); + BUG(); } cx_set(DEV_CNTRL2, (1<<5)); /* Enable RISC controller */ @@ -1256,6 +1274,57 @@ static void cx23885_timeout(unsigned long data) do_cancel_buffers(port, "timeout", 1); } +static int cx23885_irq_ts(struct cx23885_tsport *port, u32 status) +{ + struct cx23885_dev *dev = port->dev; + int handled = 0; + u32 count; + + if ( (status & VID_BC_MSK_OPC_ERR) || + (status & VID_BC_MSK_BAD_PKT) || + (status & VID_BC_MSK_SYNC) || + (status & VID_BC_MSK_OF)) + { + if (status & VID_BC_MSK_OPC_ERR) + dprintk(7, " (VID_BC_MSK_OPC_ERR 0x%08x)\n", VID_BC_MSK_OPC_ERR); + if (status & VID_BC_MSK_BAD_PKT) + dprintk(7, " (VID_BC_MSK_BAD_PKT 0x%08x)\n", VID_BC_MSK_BAD_PKT); + if (status & VID_BC_MSK_SYNC) + dprintk(7, " (VID_BC_MSK_SYNC 0x%08x)\n", VID_BC_MSK_SYNC); + if (status & VID_BC_MSK_OF) + dprintk(7, " (VID_BC_MSK_OF 0x%08x)\n", VID_BC_MSK_OF); + + printk(KERN_ERR "%s: mpeg risc op code error\n", dev->name); + + cx_clear(port->reg_dma_ctl, port->dma_ctl_val); + cx23885_sram_channel_dump(dev, &dev->sram_channels[ port->sram_chno ]); + + } else if (status & VID_BC_MSK_RISCI1) { + + dprintk(7, " (RISCI1 0x%08x)\n", VID_BC_MSK_RISCI1); + + spin_lock(&port->slock); + count = cx_read(port->reg_gpcnt); + cx23885_wakeup(port, &port->mpegq, count); + spin_unlock(&port->slock); + + } else if (status & VID_BC_MSK_RISCI2) { + + dprintk(7, " (RISCI2 0x%08x)\n", VID_BC_MSK_RISCI2); + + spin_lock(&port->slock); + cx23885_restart_queue(port, &port->mpegq); + spin_unlock(&port->slock); + + } + if (status) { + cx_write(port->reg_ts_int_stat, status); + handled = 1; + } + + return handled; +} + #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) static irqreturn_t cx23885_irq(int irq, void *dev_id, struct pt_regs *regs) #else @@ -1263,23 +1332,28 @@ static irqreturn_t cx23885_irq(int irq, void *dev_id) #endif { struct cx23885_dev *dev = dev_id; - struct cx23885_tsport *port = &dev->ts2; + struct cx23885_tsport *ts1 = &dev->ts1; + struct cx23885_tsport *ts2 = &dev->ts2; u32 pci_status, pci_mask; + u32 ts1_status, ts1_mask; u32 ts2_status, ts2_mask; - int count = 0, handled = 0; + int ts1_count = 0, ts2_count = 0, handled = 0; pci_status = cx_read(PCI_INT_STAT); pci_mask = cx_read(PCI_INT_MSK); - + ts1_status = cx_read(VID_B_INT_STAT); + ts1_mask = cx_read(VID_B_INT_MSK); ts2_status = cx_read(VID_C_INT_STAT); ts2_mask = cx_read(VID_C_INT_MSK); - if ( (pci_status == 0) && (ts2_status == 0) ) + if ( (pci_status == 0) && (ts2_status == 0) && (ts1_status == 0) ) goto out; - count = cx_read(port->reg_gpcnt); + ts1_count = cx_read(ts1->reg_gpcnt); + ts2_count = cx_read(ts2->reg_gpcnt); dprintk(7, "pci_status: 0x%08x pci_mask: 0x%08x\n", pci_status, pci_mask ); - dprintk(7, "ts2_status: 0x%08x ts2_mask: 0x%08x count: 0x%x\n", ts2_status, ts2_mask, count ); + dprintk(7, "ts1_status: 0x%08x ts1_mask: 0x%08x count: 0x%x\n", ts1_status, ts1_mask, ts1_count ); + dprintk(7, "ts2_status: 0x%08x ts2_mask: 0x%08x count: 0x%x\n", ts2_status, ts2_mask, ts2_count ); if ( (pci_status & PCI_MSK_RISC_RD) || (pci_status & PCI_MSK_RISC_WR) || @@ -1316,47 +1390,14 @@ static irqreturn_t cx23885_irq(int irq, void *dev_id) } - if ( (ts2_status & VID_C_MSK_OPC_ERR) || - (ts2_status & VID_C_MSK_BAD_PKT) || - (ts2_status & VID_C_MSK_SYNC) || - (ts2_status & VID_C_MSK_OF)) - { - if (ts2_status & VID_C_MSK_OPC_ERR) - dprintk(7, " (VID_C_MSK_OPC_ERR 0x%08x)\n", VID_C_MSK_OPC_ERR); - if (ts2_status & VID_C_MSK_BAD_PKT) - dprintk(7, " (VID_C_MSK_BAD_PKT 0x%08x)\n", VID_C_MSK_BAD_PKT); - if (ts2_status & VID_C_MSK_SYNC) - dprintk(7, " (VID_C_MSK_SYNC 0x%08x)\n", VID_C_MSK_SYNC); - if (ts2_status & VID_C_MSK_OF) - dprintk(7, " (VID_C_MSK_OF 0x%08x)\n", VID_C_MSK_OF); - - printk(KERN_ERR "%s: mpeg risc op code error\n", dev->name); - - cx_clear(port->reg_dma_ctl, port->dma_ctl_val); - cx23885_sram_channel_dump(dev, &dev->sram_channels[ port->sram_chno ]); - - } else if (ts2_status & VID_C_MSK_RISCI1) { - - dprintk(7, " (RISCI1 0x%08x)\n", VID_C_MSK_RISCI1); + if (ts1_status) + handled += cx23885_irq_ts(ts1, ts1_status); - spin_lock(&port->slock); - count = cx_read(port->reg_gpcnt); - cx23885_wakeup(port, &port->mpegq, count); - spin_unlock(&port->slock); - - } else if (ts2_status & VID_C_MSK_RISCI2) { - - dprintk(7, " (RISCI2 0x%08x)\n", VID_C_MSK_RISCI2); - - spin_lock(&port->slock); - cx23885_restart_queue(port, &port->mpegq); - spin_unlock(&port->slock); - - } + if (ts2_status) + handled += cx23885_irq_ts(ts2, ts2_status); - cx_write(VID_C_INT_STAT, ts2_status); - cx_write(PCI_INT_STAT, pci_status); - handled = 1; + if (handled) + cx_write(PCI_INT_STAT, pci_status); out: return IRQ_RETVAL(handled); } diff --git a/linux/drivers/media/video/cx23885/cx23885-dvb.c b/linux/drivers/media/video/cx23885/cx23885-dvb.c index f06d31c1f..49c35f3fc 100644 --- a/linux/drivers/media/video/cx23885/cx23885-dvb.c +++ b/linux/drivers/media/video/cx23885/cx23885-dvb.c @@ -33,6 +33,8 @@ #include "s5h1409.h" #include "mt2131.h" +#include "lgdt330x.h" +#include "dvb-pll.h" static unsigned int debug = 0; @@ -83,6 +85,15 @@ static struct videobuf_queue_ops dvb_qops = { static struct s5h1409_config hauppauge_generic_config = { .demod_address = 0x32 >> 1, .output_mode = S5H1409_SERIAL_OUTPUT, + .gpio = S5H1409_GPIO_ON, + .if_freq = 44000, + .inversion = S5H1409_INVERSION_OFF, + .status_mode = S5H1409_DEMODLOCKING +}; + +static struct s5h1409_config hauppauge_hvr1800lp_config = { + .demod_address = 0x32 >> 1, + .output_mode = S5H1409_SERIAL_OUTPUT, .gpio = S5H1409_GPIO_OFF, .if_freq = 44000, .inversion = S5H1409_INVERSION_OFF, @@ -93,9 +104,16 @@ static struct mt2131_config hauppauge_generic_tunerconfig = { 0x61 }; +static struct lgdt330x_config fusionhdtv_5_express = { + .demod_address = 0x0e, + .demod_chip = LGDT3303, + .serial_mpeg = 0x40, +}; + static int dvb_register(struct cx23885_tsport *port) { struct cx23885_dev *dev = port->dev; + struct cx23885_i2c *i2c_bus = NULL; /* init struct videobuf_dvb */ port->dvb.name = dev->name; @@ -104,16 +122,37 @@ static int dvb_register(struct cx23885_tsport *port) switch (dev->board) { case CX23885_BOARD_HAUPPAUGE_HVR1250: case CX23885_BOARD_HAUPPAUGE_HVR1800: - case CX23885_BOARD_HAUPPAUGE_HVR1800lp: + i2c_bus = &dev->i2c_bus[0]; port->dvb.frontend = dvb_attach(s5h1409_attach, &hauppauge_generic_config, - &dev->i2c_bus[0].i2c_adap); + &i2c_bus->i2c_adap); if (port->dvb.frontend != NULL) { dvb_attach(mt2131_attach, port->dvb.frontend, - &dev->i2c_bus[0].i2c_adap, + &i2c_bus->i2c_adap, &hauppauge_generic_tunerconfig, 0); } break; + case CX23885_BOARD_HAUPPAUGE_HVR1800lp: + i2c_bus = &dev->i2c_bus[0]; + port->dvb.frontend = dvb_attach(s5h1409_attach, + &hauppauge_hvr1800lp_config, + &i2c_bus->i2c_adap); + if (port->dvb.frontend != NULL) { + dvb_attach(mt2131_attach, port->dvb.frontend, + &i2c_bus->i2c_adap, + &hauppauge_generic_tunerconfig, 0); + } + break; + case CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP: + i2c_bus = &dev->i2c_bus[0]; + port->dvb.frontend = dvb_attach(lgdt330x_attach, + &fusionhdtv_5_express, + &i2c_bus->i2c_adap); + if (port->dvb.frontend != NULL) { + dvb_attach(dvb_pll_attach, port->dvb.frontend, 0x61, + &i2c_bus->i2c_adap, DVB_PLL_LG_TDVS_H06XF); + } + break; default: printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n", dev->name); @@ -125,7 +164,7 @@ static int dvb_register(struct cx23885_tsport *port) } /* Put the analog decoder in standby to keep it quiet */ - cx23885_call_i2c_clients (&dev->i2c_bus[0], TUNER_SET_STANDBY, NULL); + cx23885_call_i2c_clients(i2c_bus, TUNER_SET_STANDBY, NULL); /* register everything */ return videobuf_dvb_register(&port->dvb, THIS_MODULE, port, @@ -145,8 +184,6 @@ int cx23885_dvb_register(struct cx23885_tsport *port) dev->pci_slot); err = -ENODEV; - if (!(cx23885_boards[dev->board].portc & CX23885_MPEG_DVB)) - goto fail_core; /* dvb stuff */ printk("%s: cx23885 based dvb card\n", dev->name); @@ -157,7 +194,6 @@ int cx23885_dvb_register(struct cx23885_tsport *port) if (err != 0) printk("%s() dvb_register failed err = %d\n", __FUNCTION__, err); - fail_core: return err; } diff --git a/linux/drivers/media/video/cx23885/cx23885-i2c.c b/linux/drivers/media/video/cx23885/cx23885-i2c.c index 22594396b..a177711ea 100644 --- a/linux/drivers/media/video/cx23885/cx23885-i2c.c +++ b/linux/drivers/media/video/cx23885/cx23885-i2c.c @@ -308,12 +308,14 @@ static struct i2c_client cx23885_i2c_client_template = { }; static char *i2c_devs[128] = { + [ 0x1c >> 1 ] = "lgdt3303", + [ 0x86 >> 1 ] = "tda9887", [ 0x32 >> 1 ] = "cx24227", [ 0x88 >> 1 ] = "cx25837", [ 0x84 >> 1 ] = "tda8295", [ 0xa0 >> 1 ] = "eeprom", - [ 0xc0 >> 1 ] = "mt2131/tda8275", - [ 0xc2 >> 1 ] = "mt2131/tda8275", + [ 0xc0 >> 1 ] = "tuner/mt2131/tda8275", + [ 0xc2 >> 1 ] = "tuner/mt2131/tda8275", }; static void do_i2c_scan(char *name, struct i2c_client *c) diff --git a/linux/drivers/media/video/cx23885/cx23885-reg.h b/linux/drivers/media/video/cx23885/cx23885-reg.h index 63ab0fb26..162169f90 100644 --- a/linux/drivers/media/video/cx23885/cx23885-reg.h +++ b/linux/drivers/media/video/cx23885/cx23885-reg.h @@ -237,13 +237,12 @@ Channel manager Data Structure entry = 20 DWORD #define VID_B_INT_MSTAT 0x00040038 #define VID_B_INT_SSTAT 0x0004003C -#define VID_C_MSK_BAD_PKT (1 << 20) -#define VID_C_MSK_OPC_ERR (1 << 16) -#define VID_C_MSK_SYNC (1 << 12) -#define VID_C_MSK_OF (1 << 8) -#define VID_C_MSK_RISCI2 (1 << 4) -#define VID_C_MSK_RISCI1 1 -#define VID_C_INT_MSK 0x00040040 +#define VID_B_MSK_BAD_PKT (1 << 20) +#define VID_B_MSK_OPC_ERR (1 << 16) +#define VID_B_MSK_SYNC (1 << 12) +#define VID_B_MSK_OF (1 << 8) +#define VID_B_MSK_RISCI2 (1 << 4) +#define VID_B_MSK_RISCI1 1 #define VID_C_MSK_BAD_PKT (1 << 20) #define VID_C_MSK_OPC_ERR (1 << 16) @@ -251,6 +250,16 @@ Channel manager Data Structure entry = 20 DWORD #define VID_C_MSK_OF (1 << 8) #define VID_C_MSK_RISCI2 (1 << 4) #define VID_C_MSK_RISCI1 1 + +/* A superset for testing purposes */ +#define VID_BC_MSK_BAD_PKT (1 << 20) +#define VID_BC_MSK_OPC_ERR (1 << 16) +#define VID_BC_MSK_SYNC (1 << 12) +#define VID_BC_MSK_OF (1 << 8) +#define VID_BC_MSK_RISCI2 (1 << 4) +#define VID_BC_MSK_RISCI1 1 + +#define VID_C_INT_MSK 0x00040040 #define VID_C_INT_STAT 0x00040044 #define VID_C_INT_MSTAT 0x00040048 #define VID_C_INT_SSTAT 0x0004004C @@ -344,8 +353,8 @@ Channel manager Data Structure entry = 20 DWORD #define VBI_B_DMA 0x00130108 #define VID_B_GPCNT 0x00130120 #define VBI_B_GPCNT 0x00130124 -#define VID_B_GPCNT_CTL 0x00130130 -#define VBI_B_GPCNT_CTL 0x00130134 +#define VID_B_GPCNT_CTL 0x00130134 +#define VBI_B_GPCNT_CTL 0x00130138 #define VID_B_DMA_CTL 0x00130140 #define VID_B_SRC_SEL 0x00130144 #define VID_B_LNGTH 0x00130150 diff --git a/linux/drivers/media/video/cx23885/cx23885.h b/linux/drivers/media/video/cx23885/cx23885.h index 66cc04cfa..a0b353096 100644 --- a/linux/drivers/media/video/cx23885/cx23885.h +++ b/linux/drivers/media/video/cx23885/cx23885.h @@ -57,6 +57,7 @@ #define CX23885_BOARD_HAUPPAUGE_HVR1800lp 1 #define CX23885_BOARD_HAUPPAUGE_HVR1800 2 #define CX23885_BOARD_HAUPPAUGE_HVR1250 3 +#define CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP 4 enum cx23885_itype { CX23885_VMUX_COMPOSITE1 = 1, @@ -71,6 +72,11 @@ enum cx23885_itype { CX23885_RADIO, }; +enum cx23885_src_sel_type { + CX23885_SRC_SEL_EXT_656_VIDEO = 0, + CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO +}; + /* buffer for one video frame */ struct cx23885_buffer { /* common v4l buffer stuff -- must be first */ @@ -89,12 +95,14 @@ struct cx23885_input { u32 gpio0, gpio1, gpio2, gpio3; }; +typedef enum { + CX23885_MPEG_UNDEFINED = 0, + CX23885_MPEG_DVB +} port_t; + struct cx23885_board { char *name; - enum { - CX23885_MPEG_UNDEFINED = 0, - CX23885_MPEG_DVB - } portc; + port_t portb, portc; struct cx23885_input input[MAX_CX23885_INPUT]; }; @@ -163,6 +171,8 @@ struct cx23885_tsport { u32 reg_vld_misc; u32 reg_ts_clk_en; u32 reg_ts_int_msk; + u32 reg_ts_int_stat; + u32 reg_src_sel; /* Default register vals */ int pci_irqmask; @@ -170,6 +180,7 @@ struct cx23885_tsport { u32 ts_int_msk_val; u32 gen_ctrl_val; u32 ts_clk_en_val; + u32 src_sel_val; }; struct cx23885_dev { @@ -198,7 +209,7 @@ struct cx23885_dev { unsigned int board; char name[32]; - struct cx23885_tsport ts2; + struct cx23885_tsport ts1, ts2; /* sram configuration */ struct sram_channel *sram_channels; @@ -266,6 +277,8 @@ extern struct cx23885_subid cx23885_subids[]; extern const unsigned int cx23885_idcount; extern void cx23885_card_list(struct cx23885_dev *dev); +extern int cx23885_ir_init(struct cx23885_dev *dev); +extern void cx23885_gpio_setup(struct cx23885_dev *dev); extern void cx23885_card_setup(struct cx23885_dev *dev); extern void cx23885_card_setup_pre_i2c(struct cx23885_dev *dev); diff --git a/linux/drivers/media/video/cx88/cx88-alsa.c b/linux/drivers/media/video/cx88/cx88-alsa.c index dab6fbc06..f441193eb 100644 --- a/linux/drivers/media/video/cx88/cx88-alsa.c +++ b/linux/drivers/media/video/cx88/cx88-alsa.c @@ -39,7 +39,9 @@ #include <sound/pcm_params.h> #include <sound/control.h> #include <sound/initval.h> +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19) #include <sound/tlv.h> +#endif #include "compat.h" #include "cx88.h" @@ -659,17 +661,23 @@ static int snd_cx88_volume_put(struct snd_kcontrol *kcontrol, return changed; } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19) static const DECLARE_TLV_DB_SCALE(snd_cx88_db_scale, -6300, 100, 0); +#endif static struct snd_kcontrol_new snd_cx88_volume = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19) .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, +#endif .name = "Playback Volume", .info = snd_cx88_volume_info, .get = snd_cx88_volume_get, .put = snd_cx88_volume_put, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19) .tlv.p = snd_cx88_db_scale, +#endif }; static int snd_cx88_switch_get(struct snd_kcontrol *kcontrol, diff --git a/linux/drivers/media/video/ir-kbd-i2c.c b/linux/drivers/media/video/ir-kbd-i2c.c index 62df86c58..ed402a94d 100644 --- a/linux/drivers/media/video/ir-kbd-i2c.c +++ b/linux/drivers/media/video/ir-kbd-i2c.c @@ -528,6 +528,7 @@ static int ir_probe(struct i2c_adapter *adap) static const int probe_saa7134[] = { 0x7a, 0x47, 0x71, -1 }; static const int probe_em28XX[] = { 0x30, 0x47, -1 }; static const int probe_cx88[] = { 0x18, 0x6b, 0x71, -1 }; + static const int probe_cx23885[] = { 0x6b, -1 }; const int *probe = NULL; struct i2c_client c; unsigned char buf; @@ -548,6 +549,8 @@ static int ir_probe(struct i2c_adapter *adap) break; case I2C_HW_B_CX2388x: probe = probe_cx88; + case I2C_HW_B_CX23885: + probe = probe_cx23885; break; } if (NULL == probe) diff --git a/linux/drivers/media/video/saa7134/saa7134-cards.c b/linux/drivers/media/video/saa7134/saa7134-cards.c index 88434225e..5812bfc0d 100644 --- a/linux/drivers/media/video/saa7134/saa7134-cards.c +++ b/linux/drivers/media/video/saa7134/saa7134-cards.c @@ -2771,6 +2771,7 @@ struct saa7134_board saa7134_boards[] = { .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, .mpeg = SAA7134_MPEG_DVB, + .gpiomask = 1 << 21, .inputs = {{ .name = name_tv, .vmux = 1, @@ -2781,13 +2782,18 @@ struct saa7134_board saa7134_boards[] = { .vmux = 3, .amux = LINE1, },{ - .name = name_svideo, + .name = name_comp2, .vmux = 0, .amux = LINE1, + },{ + .name = name_svideo, + .vmux = 8, + .amux = LINE1, }}, .radio = { .name = name_radio, - .amux = LINE1, + .amux = TV, + .gpio = 0x0200000, }, }, [SAA7134_BOARD_KWORLD_DVBT_210] = { diff --git a/linux/drivers/media/video/tuner-core.c b/linux/drivers/media/video/tuner-core.c index d4d3fcf8e..8ce6f46a2 100644 --- a/linux/drivers/media/video/tuner-core.c +++ b/linux/drivers/media/video/tuner-core.c @@ -714,7 +714,8 @@ static int tuner_probe(struct i2c_adapter *adap) * FusionHDTV5 RT Gold has an ir receiver at 0x6b * and an RTC at 0x6f which can get corrupted if probed. */ - if (adap->id == I2C_HW_B_CX2388x) { + if ((adap->id == I2C_HW_B_CX2388x) || + (adap->id == I2C_HW_B_CX23885)) { unsigned int i = 0; while (i < I2C_CLIENT_MAX_OPTS && ignore[i] != I2C_CLIENT_END) |