diff options
Diffstat (limited to 'drivers/media/video/cx23885/cx23885-core.c')
-rw-r--r-- | drivers/media/video/cx23885/cx23885-core.c | 48 |
1 files changed, 33 insertions, 15 deletions
diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c index ee41a88..d8dfa40 100644 --- a/drivers/media/video/cx23885/cx23885-core.c +++ b/drivers/media/video/cx23885/cx23885-core.c @@ -156,11 +156,12 @@ static struct sram_channel cx23885_sram_channels[] = { }, [SRAM_CH07] = { .name = "ch7", - .cmds_start = 0x0, - .ctrl_start = 0x0, - .cdt = 0x0, - .fifo_start = 0x0, - .fifo_size = 0x0, + .name = "TV Audio", + .cmds_start = 0x10190, + .ctrl_start = 0x10480, + .cdt = 0x10a00, + .fifo_start = 0x7000, + .fifo_size = 0x1000, .ptr1_reg = DMA6_PTR1, .ptr2_reg = DMA6_PTR2, .cnt1_reg = DMA6_CNT1, @@ -1082,10 +1083,10 @@ static void cx23885_dev_unregister(struct cx23885_dev *dev) static __le32 *cx23885_risc_field(__le32 *rp, struct scatterlist *sglist, unsigned int offset, u32 sync_line, unsigned int bpl, unsigned int padding, - unsigned int lines) + unsigned int lines, unsigned int lpi) { struct scatterlist *sg; - unsigned int line, todo; + unsigned int line, todo, sol; /* sync instruction */ if (sync_line != NO_SYNC_LINE) @@ -1098,16 +1099,22 @@ static __le32 *cx23885_risc_field(__le32 *rp, struct scatterlist *sglist, offset -= sg_dma_len(sg); sg++; } + + if (lpi && line > 0 && !(line % lpi)) + sol = RISC_SOL | RISC_IRQ1 | RISC_CNT_INC; + else + sol = RISC_SOL; + if (bpl <= sg_dma_len(sg)-offset) { /* fits into current chunk */ - *(rp++) = cpu_to_le32(RISC_WRITE|RISC_SOL|RISC_EOL|bpl); + *(rp++) = cpu_to_le32(RISC_WRITE|sol|RISC_EOL|bpl); *(rp++) = cpu_to_le32(sg_dma_address(sg)+offset); *(rp++) = cpu_to_le32(0); /* bits 63-32 */ offset += bpl; } else { /* scanline needs to be split */ todo = bpl; - *(rp++) = cpu_to_le32(RISC_WRITE|RISC_SOL| + *(rp++) = cpu_to_le32(RISC_WRITE|sol| (sg_dma_len(sg)-offset)); *(rp++) = cpu_to_le32(sg_dma_address(sg)+offset); *(rp++) = cpu_to_le32(0); /* bits 63-32 */ @@ -1164,10 +1171,10 @@ int cx23885_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc, rp = risc->cpu; if (UNSET != top_offset) rp = cx23885_risc_field(rp, sglist, top_offset, 0, - bpl, padding, lines); + bpl, padding, lines, 0); if (UNSET != bottom_offset) rp = cx23885_risc_field(rp, sglist, bottom_offset, 0x200, - bpl, padding, lines); + bpl, padding, lines, 0); /* save pointer to jmp instruction address */ risc->jmp = rp; @@ -1175,11 +1182,11 @@ int cx23885_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc, return 0; } -static int cx23885_risc_databuffer(struct pci_dev *pci, +int cx23885_risc_databuffer(struct pci_dev *pci, struct btcx_riscmem *risc, struct scatterlist *sglist, unsigned int bpl, - unsigned int lines) + unsigned int lines, unsigned int lpi) { u32 instructions; __le32 *rp; @@ -1199,7 +1206,8 @@ static int cx23885_risc_databuffer(struct pci_dev *pci, /* write risc instructions */ rp = risc->cpu; - rp = cx23885_risc_field(rp, sglist, 0, NO_SYNC_LINE, bpl, 0, lines); + rp = cx23885_risc_field(rp, sglist, 0, NO_SYNC_LINE, + bpl, 0, lines, lpi); /* save pointer to jmp instruction address */ risc->jmp = rp; @@ -1517,7 +1525,7 @@ int cx23885_buf_prepare(struct videobuf_queue *q, struct cx23885_tsport *port, goto fail; cx23885_risc_databuffer(dev->pci, &buf->risc, videobuf_to_dma(&buf->vb)->sglist, - buf->vb.width, buf->vb.height); + buf->vb.width, buf->vb.height, 0); } buf->vb.state = VIDEOBUF_PREPARED; return 0; @@ -1741,15 +1749,19 @@ static irqreturn_t cx23885_irq(int irq, void *dev_id) struct cx23885_tsport *ts2 = &dev->ts2; u32 pci_status, pci_mask; u32 vida_status, vida_mask; + u32 audint_status, audint_mask; u32 ts1_status, ts1_mask; u32 ts2_status, ts2_mask; int vida_count = 0, ts1_count = 0, ts2_count = 0, handled = 0; + int audint_count = 0; bool subdev_handled; pci_status = cx_read(PCI_INT_STAT); pci_mask = cx23885_irq_get_mask(dev); vida_status = cx_read(VID_A_INT_STAT); vida_mask = cx_read(VID_A_INT_MSK); + audint_status = cx_read(AUDIO_INT_INT_STAT); + audint_mask = cx_read(AUDIO_INT_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); @@ -1759,12 +1771,15 @@ static irqreturn_t cx23885_irq(int irq, void *dev_id) goto out; vida_count = cx_read(VID_A_GPCNT); + audint_count = cx_read(AUD_INT_A_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, "vida_status: 0x%08x vida_mask: 0x%08x count: 0x%x\n", vida_status, vida_mask, vida_count); + dprintk(7, "audint_status: 0x%08x audint_mask: 0x%08x count: 0x%x\n", + audint_status, audint_mask, audint_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", @@ -1861,6 +1876,9 @@ static irqreturn_t cx23885_irq(int irq, void *dev_id) if (vida_status) handled += cx23885_video_irq(dev, vida_status); + if (audint_status) + handled += cx23885_audio_irq(dev, audint_status, audint_mask); + if (pci_status & PCI_MSK_IR) { subdev_handled = false; v4l2_subdev_call(dev->sd_ir, core, interrupt_service_routine, |