From c07d28cae856c91c33afe4e21c92335302cccdf7 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Sat, 8 Sep 2007 18:08:17 -0400 Subject: cx23885: GPIO fix for non HVR1800lp boards. From: Steven Toth The HVR1250 and HVR1800 boards need the s5h1409 demod GPIO enabled. Signed-off-by: Steven Toth --- linux/drivers/media/video/cx23885/cx23885-dvb.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'linux/drivers/media/video/cx23885') diff --git a/linux/drivers/media/video/cx23885/cx23885-dvb.c b/linux/drivers/media/video/cx23885/cx23885-dvb.c index f06d31c1f..7411acdef 100644 --- a/linux/drivers/media/video/cx23885/cx23885-dvb.c +++ b/linux/drivers/media/video/cx23885/cx23885-dvb.c @@ -81,6 +81,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, @@ -104,7 +113,6 @@ 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: port->dvb.frontend = dvb_attach(s5h1409_attach, &hauppauge_generic_config, &dev->i2c_bus[0].i2c_adap); @@ -114,6 +122,16 @@ static int dvb_register(struct cx23885_tsport *port) &hauppauge_generic_tunerconfig, 0); } break; + case CX23885_BOARD_HAUPPAUGE_HVR1800lp: + port->dvb.frontend = dvb_attach(s5h1409_attach, + &hauppauge_hvr1800lp_config, + &dev->i2c_bus[0].i2c_adap); + if (port->dvb.frontend != NULL) { + dvb_attach(mt2131_attach, port->dvb.frontend, + &dev->i2c_bus[0].i2c_adap, + &hauppauge_generic_tunerconfig, 0); + } + break; default: printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n", dev->name); -- cgit v1.2.3 From 4cb6954cc185565789a9aed7975a62ca6cda5ab2 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Thu, 6 Sep 2007 14:50:31 -0400 Subject: Removed a redundant switch() From: Steven Toth The switch() statement is no longer required. Signed-off-by: Steven Toth --- linux/drivers/media/video/cx23885/cx23885-core.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'linux/drivers/media/video/cx23885') diff --git a/linux/drivers/media/video/cx23885/cx23885-core.c b/linux/drivers/media/video/cx23885/cx23885-core.c index c32d836b6..7dd6dfd01 100644 --- a/linux/drivers/media/video/cx23885/cx23885-core.c +++ b/linux/drivers/media/video/cx23885/cx23885-core.c @@ -1026,18 +1026,7 @@ static int cx23885_start_dma(struct cx23885_tsport *port, 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); -- cgit v1.2.3 From 40003635ce2746dc471ee224c86bd5df01bf9d18 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Thu, 6 Sep 2007 15:07:49 -0400 Subject: Ensure start_dma() is capable of starting dma on port VIDB. From: Steven Toth start_dma() would fail to start dma if a device used VIDB (portb). Signed-off-by: Steven Toth --- linux/drivers/media/video/cx23885/cx23885-core.c | 9 ++++++--- linux/drivers/media/video/cx23885/cx23885.h | 10 ++++++---- 2 files changed, 12 insertions(+), 7 deletions(-) (limited to 'linux/drivers/media/video/cx23885') diff --git a/linux/drivers/media/video/cx23885/cx23885-core.c b/linux/drivers/media/video/cx23885/cx23885-core.c index 7dd6dfd01..362d7e1e4 100644 --- a/linux/drivers/media/video/cx23885/cx23885-core.c +++ b/linux/drivers/media/video/cx23885/cx23885-core.c @@ -1016,9 +1016,12 @@ 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; } diff --git a/linux/drivers/media/video/cx23885/cx23885.h b/linux/drivers/media/video/cx23885/cx23885.h index 66cc04cfa..d718e40fe 100644 --- a/linux/drivers/media/video/cx23885/cx23885.h +++ b/linux/drivers/media/video/cx23885/cx23885.h @@ -89,12 +89,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]; }; -- cgit v1.2.3 From de851e2d30e40d613624444bf9df807d075b175d Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 8 Sep 2007 10:25:37 -0400 Subject: cx23885: define Video B Interrupt Status register bit values From: Michael Krufky - define missing register bit values for VID_B - corrected VID/VBI_B_GPCNT_CTL register addresses Signed-off-by: Michael Krufky --- linux/drivers/media/video/cx23885/cx23885-reg.h | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media/video/cx23885') diff --git a/linux/drivers/media/video/cx23885/cx23885-reg.h b/linux/drivers/media/video/cx23885/cx23885-reg.h index 63ab0fb26..3f1afbeea 100644 --- a/linux/drivers/media/video/cx23885/cx23885-reg.h +++ b/linux/drivers/media/video/cx23885/cx23885-reg.h @@ -237,6 +237,13 @@ Channel manager Data Structure entry = 20 DWORD #define VID_B_INT_MSTAT 0x00040038 #define VID_B_INT_SSTAT 0x0004003C +#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) #define VID_C_MSK_SYNC (1 << 12) @@ -344,8 +351,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 -- cgit v1.2.3 From 473b042b6ad7544981a79dda2187bb1088edf3de Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Sat, 8 Sep 2007 13:21:03 -0400 Subject: Changes to support interrupts on VIDB From: Steven Toth Changes to support interrupts on VIDB Signed-off-by: Steven Toth --- linux/drivers/media/video/cx23885/cx23885-core.c | 59 ++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 5 deletions(-) (limited to 'linux/drivers/media/video/cx23885') diff --git a/linux/drivers/media/video/cx23885/cx23885-core.c b/linux/drivers/media/video/cx23885/cx23885-core.c index 362d7e1e4..4b275bdc8 100644 --- a/linux/drivers/media/video/cx23885/cx23885-core.c +++ b/linux/drivers/media/video/cx23885/cx23885-core.c @@ -1257,20 +1257,23 @@ static irqreturn_t cx23885_irq(int irq, void *dev_id) struct cx23885_dev *dev = dev_id; struct cx23885_tsport *port = &dev->ts2; u32 pci_status, pci_mask; + u32 ts1_status, ts1_mask; u32 ts2_status, ts2_mask; int 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); dprintk(7, "pci_status: 0x%08x pci_mask: 0x%08x\n", pci_status, pci_mask ); + dprintk(7, "ts1_status: 0x%08x ts1_mask: 0x%08x count: 0x%x\n", ts1_status, ts1_mask, count ); dprintk(7, "ts2_status: 0x%08x ts2_mask: 0x%08x count: 0x%x\n", ts2_status, ts2_mask, count ); if ( (pci_status & PCI_MSK_RISC_RD) || @@ -1308,6 +1311,48 @@ static irqreturn_t cx23885_irq(int irq, void *dev_id) } + if ( (ts1_status & VID_B_MSK_OPC_ERR) || + (ts1_status & VID_B_MSK_BAD_PKT) || + (ts1_status & VID_B_MSK_SYNC) || + (ts1_status & VID_B_MSK_OF)) + { + if (ts1_status & VID_B_MSK_OPC_ERR) + dprintk(7, " (VID_B_MSK_OPC_ERR 0x%08x)\n", VID_B_MSK_OPC_ERR); + if (ts1_status & VID_B_MSK_BAD_PKT) + dprintk(7, " (VID_B_MSK_BAD_PKT 0x%08x)\n", VID_B_MSK_BAD_PKT); + if (ts1_status & VID_B_MSK_SYNC) + dprintk(7, " (VID_B_MSK_SYNC 0x%08x)\n", VID_B_MSK_SYNC); + if (ts1_status & VID_B_MSK_OF) + dprintk(7, " (VID_B_MSK_OF 0x%08x)\n", VID_B_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 (ts1_status & VID_B_MSK_RISCI1) { + + dprintk(7, " (RISCI1 0x%08x)\n", VID_B_MSK_RISCI1); + + spin_lock(&port->slock); + count = cx_read(port->reg_gpcnt); + cx23885_wakeup(port, &port->mpegq, count); + spin_unlock(&port->slock); + + } else if (ts1_status & VID_B_MSK_RISCI2) { + + dprintk(7, " (RISCI2 0x%08x)\n", VID_B_MSK_RISCI2); + + spin_lock(&port->slock); + cx23885_restart_queue(port, &port->mpegq); + spin_unlock(&port->slock); + + } + if (ts1_status) { + cx_write(VID_B_INT_STAT, ts1_status); + handled = 1; + } + if ( (ts2_status & VID_C_MSK_OPC_ERR) || (ts2_status & VID_C_MSK_BAD_PKT) || (ts2_status & VID_C_MSK_SYNC) || @@ -1346,9 +1391,13 @@ static irqreturn_t cx23885_irq(int irq, void *dev_id) } - cx_write(VID_C_INT_STAT, ts2_status); - cx_write(PCI_INT_STAT, pci_status); - handled = 1; + if (ts2_status) { + cx_write(VID_C_INT_STAT, ts2_status); + handled = 1; + } + + if (handled) + cx_write(PCI_INT_STAT, pci_status); out: return IRQ_RETVAL(handled); } -- cgit v1.2.3 From 0f81ffde8b48544ab4eb875c1810c99af374ce43 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Sat, 8 Sep 2007 14:07:02 -0400 Subject: Changes to support MPEG TS on VIDB From: Steven Toth Changes to support MPEG TS on VIDB Signed-off-by: Steven Toth --- linux/drivers/media/video/cx23885/cx23885-core.c | 170 ++++++++++++++--------- linux/drivers/media/video/cx23885/cx23885.h | 7 + 2 files changed, 114 insertions(+), 63 deletions(-) (limited to 'linux/drivers/media/video/cx23885') diff --git a/linux/drivers/media/video/cx23885/cx23885-core.c b/linux/drivers/media/video/cx23885/cx23885-core.c index 4b275bdc8..1227965c5 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); @@ -680,6 +680,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; @@ -718,38 +751,13 @@ static int cx23885_dev_setup(struct cx23885_dev *dev) 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); - - sprintf(dev->name, "cx23885[%d]", dev->nr); - if (get_resources(dev) < 0) { printk(KERN_ERR "CORE %s No more PCIe resources for " "subsystem: %04x:%04x\n", @@ -760,46 +768,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 */ @@ -813,6 +793,66 @@ static int cx23885_dev_setup(struct cx23885_dev *dev) cx23885_card_setup(dev); cx23885_ir_init(dev); + switch (dev->board) { +#if 0 + case CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP: + dev->ts2.reg_gpcnt = VID_B_GPCNT; + dev->ts2.reg_gpcnt_ctl = VID_B_GPCNT_CTL; + dev->ts2.reg_dma_ctl = VID_B_DMA_CTL; + dev->ts2.reg_lngth = VID_B_LNGTH; + dev->ts2.reg_hw_sop_ctrl = VID_B_HW_SOP_CTL; + dev->ts2.reg_gen_ctrl = VID_B_GEN_CTL; + dev->ts2.reg_bd_pkt_status = VID_B_BD_PKT_STATUS; + dev->ts2.reg_sop_status = VID_B_SOP_STATUS; + dev->ts2.reg_fifo_ovfl_stat = VID_B_FIFO_OVFL_STAT; + dev->ts2.reg_vld_misc = VID_B_VLD_MISC; + dev->ts2.reg_ts_clk_en = VID_B_TS_CLK_EN; + dev->ts2.reg_ts_int_msk = VID_B_INT_MSK; + dev->ts2.reg_src_sel = VID_B_SRC_SEL; + + // FIXME: Make this board specific + dev->ts2.pci_irqmask = 0x02; /* 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 */ + dev->ts2.src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; + + // Drive this from cards.c (portb/c) and move it outside of this switch + dev->ts2.sram_chno = SRAM_CH03; + break; +#endif + default: + 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; + dev->ts2.reg_src_sel = 0; + + // 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 */ + dev->ts2.src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; + + // Drive this from cards.c (portb/c) and move it outside of this switch + dev->ts2.sram_chno = SRAM_CH06; + } + + cx23885_risc_stopper(dev->pci, &dev->ts2.mpegq.stopper, + dev->ts2.reg_dma_ctl, dev->ts2.dma_ctl_val, 0x00); + + // FIXME: This should only be called if ts2 is being used, driven by cards.c if (cx23885_dvb_register(&dev->ts2) < 0) { printk(KERN_ERR "%s() Failed to register dvb adapters\n", __FUNCTION__); @@ -1027,13 +1067,17 @@ static int cx23885_start_dma(struct cx23885_tsport *port, 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); 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; @@ -1048,7 +1092,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 */ diff --git a/linux/drivers/media/video/cx23885/cx23885.h b/linux/drivers/media/video/cx23885/cx23885.h index d718e40fe..7355f6fd2 100644 --- a/linux/drivers/media/video/cx23885/cx23885.h +++ b/linux/drivers/media/video/cx23885/cx23885.h @@ -71,6 +71,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 */ @@ -165,6 +170,7 @@ struct cx23885_tsport { u32 reg_vld_misc; u32 reg_ts_clk_en; u32 reg_ts_int_msk; + u32 reg_src_sel; /* Default register vals */ int pci_irqmask; @@ -172,6 +178,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 { -- cgit v1.2.3 From d1c13402d0c6dedd352fd44b20a24c4e9cbab543 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 8 Sep 2007 14:17:13 -0400 Subject: cx23885: add support for DViCO FusionHDTV 5 Express From: Michael Krufky This patch adds digital ATSC / QAM support for the DViCO FusionHDTV5 Express. Remote control is supported by ir-kbd-i2c, RTC is supported by rtc-isl1208. Signed-off-by: Michael Krufky --- linux/drivers/media/video/cx23885/cx23885-cards.c | 8 ++++++++ linux/drivers/media/video/cx23885/cx23885-core.c | 2 -- linux/drivers/media/video/cx23885/cx23885-dvb.c | 18 ++++++++++++++++++ linux/drivers/media/video/cx23885/cx23885-i2c.c | 6 ++++-- linux/drivers/media/video/cx23885/cx23885.h | 1 + 5 files changed, 31 insertions(+), 4 deletions(-) (limited to 'linux/drivers/media/video/cx23885') diff --git a/linux/drivers/media/video/cx23885/cx23885-cards.c b/linux/drivers/media/video/cx23885/cx23885-cards.c index e35d221da..3dda33879 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", + .portc = 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); diff --git a/linux/drivers/media/video/cx23885/cx23885-core.c b/linux/drivers/media/video/cx23885/cx23885-core.c index 1227965c5..c4503354c 100644 --- a/linux/drivers/media/video/cx23885/cx23885-core.c +++ b/linux/drivers/media/video/cx23885/cx23885-core.c @@ -794,7 +794,6 @@ static int cx23885_dev_setup(struct cx23885_dev *dev) cx23885_ir_init(dev); switch (dev->board) { -#if 0 case CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP: dev->ts2.reg_gpcnt = VID_B_GPCNT; dev->ts2.reg_gpcnt_ctl = VID_B_GPCNT_CTL; @@ -821,7 +820,6 @@ static int cx23885_dev_setup(struct cx23885_dev *dev) // Drive this from cards.c (portb/c) and move it outside of this switch dev->ts2.sram_chno = SRAM_CH03; break; -#endif default: dev->ts2.reg_gpcnt = VID_C_GPCNT; dev->ts2.reg_gpcnt_ctl = VID_C_GPCNT_CTL; diff --git a/linux/drivers/media/video/cx23885/cx23885-dvb.c b/linux/drivers/media/video/cx23885/cx23885-dvb.c index 7411acdef..73040fbde 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; @@ -102,6 +104,12 @@ 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; @@ -132,6 +140,16 @@ static int dvb_register(struct cx23885_tsport *port) &hauppauge_generic_tunerconfig, 0); } break; + case CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP: + port->dvb.frontend = dvb_attach(lgdt330x_attach, + &fusionhdtv_5_express, + &dev->i2c_bus[0].i2c_adap); + if (port->dvb.frontend != NULL) { + dvb_attach(dvb_pll_attach, port->dvb.frontend, + 0x61, &dev->i2c_bus[0].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); 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.h b/linux/drivers/media/video/cx23885/cx23885.h index 7355f6fd2..b94e21bbe 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, -- cgit v1.2.3 From 614fdf5da1f2462682bb2d498aaa4a2a3a2253cb Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Sat, 8 Sep 2007 20:31:56 -0400 Subject: cx23885: Changes to allow demodulators on each transport bus. From: Steven Toth cx23885: Changes to allow demodulators on each transport bus. Signed-off-by: Steven Toth --- linux/drivers/media/video/cx23885/cx23885-cards.c | 53 +++- linux/drivers/media/video/cx23885/cx23885-core.c | 324 ++++++++++------------ linux/drivers/media/video/cx23885/cx23885-dvb.c | 4 +- linux/drivers/media/video/cx23885/cx23885-reg.h | 16 +- linux/drivers/media/video/cx23885/cx23885.h | 5 +- 5 files changed, 207 insertions(+), 195 deletions(-) (limited to 'linux/drivers/media/video/cx23885') diff --git a/linux/drivers/media/video/cx23885/cx23885-cards.c b/linux/drivers/media/video/cx23885/cx23885-cards.c index 3dda33879..3ea417146 100644 --- a/linux/drivers/media/video/cx23885/cx23885-cards.c +++ b/linux/drivers/media/video/cx23885/cx23885-cards.c @@ -112,7 +112,7 @@ struct cx23885_board cx23885_boards[] = { }, [CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP] = { .name = "DViCO FusionHDTV5 Express", - .portc = CX23885_MPEG_DVB, + .portb = CX23885_MPEG_DVB, }, }; const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); @@ -198,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) { @@ -216,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 c4503354c..03f66e267 100644 --- a/linux/drivers/media/video/cx23885/cx23885-core.c +++ b/linux/drivers/media/video/cx23885/cx23885-core.c @@ -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; } @@ -747,16 +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; + if(cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) + cx23885_init_tsport(dev, &dev->ts1, 1); - 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); + 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 " @@ -789,71 +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); - switch (dev->board) { - case CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP: - dev->ts2.reg_gpcnt = VID_B_GPCNT; - dev->ts2.reg_gpcnt_ctl = VID_B_GPCNT_CTL; - dev->ts2.reg_dma_ctl = VID_B_DMA_CTL; - dev->ts2.reg_lngth = VID_B_LNGTH; - dev->ts2.reg_hw_sop_ctrl = VID_B_HW_SOP_CTL; - dev->ts2.reg_gen_ctrl = VID_B_GEN_CTL; - dev->ts2.reg_bd_pkt_status = VID_B_BD_PKT_STATUS; - dev->ts2.reg_sop_status = VID_B_SOP_STATUS; - dev->ts2.reg_fifo_ovfl_stat = VID_B_FIFO_OVFL_STAT; - dev->ts2.reg_vld_misc = VID_B_VLD_MISC; - dev->ts2.reg_ts_clk_en = VID_B_TS_CLK_EN; - dev->ts2.reg_ts_int_msk = VID_B_INT_MSK; - dev->ts2.reg_src_sel = VID_B_SRC_SEL; - - // FIXME: Make this board specific - dev->ts2.pci_irqmask = 0x02; /* 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 */ - dev->ts2.src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; - - // Drive this from cards.c (portb/c) and move it outside of this switch - dev->ts2.sram_chno = SRAM_CH03; - break; - default: - 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; - dev->ts2.reg_src_sel = 0; - - // 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 */ - dev->ts2.src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; - - // Drive this from cards.c (portb/c) and move it outside of this switch - dev->ts2.sram_chno = SRAM_CH06; + 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__); + } } - cx23885_risc_stopper(dev->pci, &dev->ts2.mpegq.stopper, - dev->ts2.reg_dma_ctl, dev->ts2.dma_ctl_val, 0x00); - - // FIXME: This should only be called if ts2 is being used, driven by cards.c - if (cx23885_dvb_register(&dev->ts2) < 0) { - printk(KERN_ERR "%s() Failed to register dvb adapters\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; @@ -871,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]); @@ -1290,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 @@ -1297,11 +1332,12 @@ 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); @@ -1313,10 +1349,11 @@ static irqreturn_t cx23885_irq(int irq, void *dev_id) 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, "ts1_status: 0x%08x ts1_mask: 0x%08x count: 0x%x\n", ts1_status, ts1_mask, count ); - 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) || @@ -1353,90 +1390,11 @@ static irqreturn_t cx23885_irq(int irq, void *dev_id) } - if ( (ts1_status & VID_B_MSK_OPC_ERR) || - (ts1_status & VID_B_MSK_BAD_PKT) || - (ts1_status & VID_B_MSK_SYNC) || - (ts1_status & VID_B_MSK_OF)) - { - if (ts1_status & VID_B_MSK_OPC_ERR) - dprintk(7, " (VID_B_MSK_OPC_ERR 0x%08x)\n", VID_B_MSK_OPC_ERR); - if (ts1_status & VID_B_MSK_BAD_PKT) - dprintk(7, " (VID_B_MSK_BAD_PKT 0x%08x)\n", VID_B_MSK_BAD_PKT); - if (ts1_status & VID_B_MSK_SYNC) - dprintk(7, " (VID_B_MSK_SYNC 0x%08x)\n", VID_B_MSK_SYNC); - if (ts1_status & VID_B_MSK_OF) - dprintk(7, " (VID_B_MSK_OF 0x%08x)\n", VID_B_MSK_OF); + if (ts1_status) + handled += cx23885_irq_ts(ts1, ts1_status); - 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 (ts1_status & VID_B_MSK_RISCI1) { - - dprintk(7, " (RISCI1 0x%08x)\n", VID_B_MSK_RISCI1); - - spin_lock(&port->slock); - count = cx_read(port->reg_gpcnt); - cx23885_wakeup(port, &port->mpegq, count); - spin_unlock(&port->slock); - - } else if (ts1_status & VID_B_MSK_RISCI2) { - - dprintk(7, " (RISCI2 0x%08x)\n", VID_B_MSK_RISCI2); - - spin_lock(&port->slock); - cx23885_restart_queue(port, &port->mpegq); - spin_unlock(&port->slock); - - } - if (ts1_status) { - cx_write(VID_B_INT_STAT, ts1_status); - handled = 1; - } - - 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); - - 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) { - cx_write(VID_C_INT_STAT, ts2_status); - handled = 1; - } + if (ts2_status) + handled += cx23885_irq_ts(ts2, ts2_status); if (handled) cx_write(PCI_INT_STAT, pci_status); diff --git a/linux/drivers/media/video/cx23885/cx23885-dvb.c b/linux/drivers/media/video/cx23885/cx23885-dvb.c index 73040fbde..ad65600e9 100644 --- a/linux/drivers/media/video/cx23885/cx23885-dvb.c +++ b/linux/drivers/media/video/cx23885/cx23885-dvb.c @@ -161,6 +161,7 @@ static int dvb_register(struct cx23885_tsport *port) } /* Put the analog decoder in standby to keep it quiet */ + /* Assumption here: analog decoder is only on i2c bus 0 */ cx23885_call_i2c_clients (&dev->i2c_bus[0], TUNER_SET_STANDBY, NULL); /* register everything */ @@ -181,8 +182,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); @@ -193,7 +192,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-reg.h b/linux/drivers/media/video/cx23885/cx23885-reg.h index 3f1afbeea..162169f90 100644 --- a/linux/drivers/media/video/cx23885/cx23885-reg.h +++ b/linux/drivers/media/video/cx23885/cx23885-reg.h @@ -250,14 +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 -#define VID_C_INT_MSK 0x00040040 -#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 +/* 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 diff --git a/linux/drivers/media/video/cx23885/cx23885.h b/linux/drivers/media/video/cx23885/cx23885.h index b94e21bbe..a0b353096 100644 --- a/linux/drivers/media/video/cx23885/cx23885.h +++ b/linux/drivers/media/video/cx23885/cx23885.h @@ -171,6 +171,7 @@ 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 */ @@ -208,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; @@ -276,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); -- cgit v1.2.3 From f1574b2149f0763188a2c566a05ed973db7141c3 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 9 Sep 2007 02:55:34 -0400 Subject: cx23885: use a pointer to the required i2c bus in dvb_register function From: Michael Krufky Store a pointer to the required i2c_bus so that we do not put the wrong analog demod into standby. Signed-off-by: Michael Krufky --- linux/drivers/media/video/cx23885/cx23885-dvb.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'linux/drivers/media/video/cx23885') diff --git a/linux/drivers/media/video/cx23885/cx23885-dvb.c b/linux/drivers/media/video/cx23885/cx23885-dvb.c index ad65600e9..49c35f3fc 100644 --- a/linux/drivers/media/video/cx23885/cx23885-dvb.c +++ b/linux/drivers/media/video/cx23885/cx23885-dvb.c @@ -113,6 +113,7 @@ static struct lgdt330x_config fusionhdtv_5_express = { 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; @@ -121,33 +122,35 @@ static int dvb_register(struct cx23885_tsport *port) switch (dev->board) { case CX23885_BOARD_HAUPPAUGE_HVR1250: case CX23885_BOARD_HAUPPAUGE_HVR1800: + 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, - &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_DVICO_FUSIONHDTV_5_EXP: + i2c_bus = &dev->i2c_bus[0]; port->dvb.frontend = dvb_attach(lgdt330x_attach, &fusionhdtv_5_express, - &dev->i2c_bus[0].i2c_adap); + &i2c_bus->i2c_adap); if (port->dvb.frontend != NULL) { - dvb_attach(dvb_pll_attach, port->dvb.frontend, - 0x61, &dev->i2c_bus[0].i2c_adap, - DVB_PLL_LG_TDVS_H06XF); + dvb_attach(dvb_pll_attach, port->dvb.frontend, 0x61, + &i2c_bus->i2c_adap, DVB_PLL_LG_TDVS_H06XF); } break; default: @@ -161,8 +164,7 @@ static int dvb_register(struct cx23885_tsport *port) } /* Put the analog decoder in standby to keep it quiet */ - /* Assumption here: analog decoder is only on i2c bus 0 */ - 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, -- cgit v1.2.3