summaryrefslogtreecommitdiff
path: root/linux/drivers/media/video
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@infradead.org>2007-09-12 15:20:14 -0300
committerMauro Carvalho Chehab <mchehab@infradead.org>2007-09-12 15:20:14 -0300
commit501a54f0edea703168f8fb7d5e27e915087906e6 (patch)
treebbbe1072fcfd0aaa02d66c9b91a0cab076a37b69 /linux/drivers/media/video
parent995f38acadb5dae1fb1b2769714d5e45aeb9db5c (diff)
parentd97a5c24bb8f480281d7bedce89525dab393b142 (diff)
downloadmediapointer-dvb-s2-501a54f0edea703168f8fb7d5e27e915087906e6.tar.gz
mediapointer-dvb-s2-501a54f0edea703168f8fb7d5e27e915087906e6.tar.bz2
merge: http://linuxtv.org/hg/~mcisely/pvrusb2
From: Mauro Carvalho Chehab <mchehab@infradead.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'linux/drivers/media/video')
-rw-r--r--linux/drivers/media/video/cx23885/cx23885-cards.c59
-rw-r--r--linux/drivers/media/video/cx23885/cx23885-core.c363
-rw-r--r--linux/drivers/media/video/cx23885/cx23885-dvb.c50
-rw-r--r--linux/drivers/media/video/cx23885/cx23885-i2c.c6
-rw-r--r--linux/drivers/media/video/cx23885/cx23885-reg.h27
-rw-r--r--linux/drivers/media/video/cx23885/cx23885.h23
-rw-r--r--linux/drivers/media/video/cx88/cx88-alsa.c8
-rw-r--r--linux/drivers/media/video/ir-kbd-i2c.c3
-rw-r--r--linux/drivers/media/video/saa7134/saa7134-cards.c10
-rw-r--r--linux/drivers/media/video/tuner-core.c3
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)