aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Toth <stoth@hauppauge.com>2008-01-10 01:40:49 -0500
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-01-25 16:04:49 -0500
commit7b8880140ff6aec6a5bec7929b03ce0b96a7c79a (patch)
treeb2646197762030abaa1110be0d2a9474bce20c3e
parentc771261330c90b7c77f686a1aa0fb4f756e07b5f (diff)
V4L/DVB (7007): cx23885: Add basic video support for the HVR1800
This enabled basic preview NTSC and PAL support for the HVR1800. Signed-off-by: Steven Toth <stoth@hauppauge.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
-rw-r--r--drivers/media/video/cx23885/Makefile2
-rw-r--r--drivers/media/video/cx23885/cx23885-cards.c27
-rw-r--r--drivers/media/video/cx23885/cx23885-core.c185
-rw-r--r--drivers/media/video/cx23885/cx23885-i2c.c31
-rw-r--r--drivers/media/video/cx23885/cx23885-reg.h12
-rw-r--r--drivers/media/video/cx23885/cx23885.h151
6 files changed, 366 insertions, 42 deletions
diff --git a/drivers/media/video/cx23885/Makefile b/drivers/media/video/cx23885/Makefile
index 665067022d2a..32c90be50602 100644
--- a/drivers/media/video/cx23885/Makefile
+++ b/drivers/media/video/cx23885/Makefile
@@ -1,4 +1,4 @@
1cx23885-objs := cx23885-cards.o cx23885-core.o cx23885-i2c.o cx23885-dvb.o 1cx23885-objs := cx23885-cards.o cx23885-video.o cx23885-vbi.o cx23885-core.o cx23885-i2c.o cx23885-dvb.o
2 2
3obj-$(CONFIG_VIDEO_CX23885) += cx23885.o 3obj-$(CONFIG_VIDEO_CX23885) += cx23885.o
4 4
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c
index a4bac43cf9f5..c2d5a4d7228b 100644
--- a/drivers/media/video/cx23885/cx23885-cards.c
+++ b/drivers/media/video/cx23885/cx23885-cards.c
@@ -23,6 +23,7 @@
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/pci.h> 24#include <linux/pci.h>
25#include <linux/delay.h> 25#include <linux/delay.h>
26#include <media/cx25840.h>
26 27
27#include "cx23885.h" 28#include "cx23885.h"
28 29
@@ -71,23 +72,29 @@ struct cx23885_board cx23885_boards[] = {
71 }, 72 },
72 [CX23885_BOARD_HAUPPAUGE_HVR1800] = { 73 [CX23885_BOARD_HAUPPAUGE_HVR1800] = {
73 .name = "Hauppauge WinTV-HVR1800", 74 .name = "Hauppauge WinTV-HVR1800",
75 .porta = CX23885_ANALOG_VIDEO,
74 .portc = CX23885_MPEG_DVB, 76 .portc = CX23885_MPEG_DVB,
77 .tuner_type = TUNER_PHILIPS_TDA8290,
78 .tuner_addr = 0x42, /* 0x84 >> 1 */
75 .input = {{ 79 .input = {{
76 .type = CX23885_VMUX_TELEVISION, 80 .type = CX23885_VMUX_TELEVISION,
77 .vmux = 0, 81 .vmux = CX25840_VIN7_CH3 |
78 .gpio0 = 0xff00, 82 CX25840_VIN5_CH2 |
79 },{ 83 CX25840_VIN2_CH1,
80 .type = CX23885_VMUX_DEBUG, 84 .gpio0 = 0,
81 .vmux = 0,
82 .gpio0 = 0xff01,
83 },{ 85 },{
84 .type = CX23885_VMUX_COMPOSITE1, 86 .type = CX23885_VMUX_COMPOSITE1,
85 .vmux = 1, 87 .vmux = CX25840_VIN7_CH3 |
86 .gpio0 = 0xff02, 88 CX25840_VIN4_CH2 |
89 CX25840_VIN6_CH1,
90 .gpio0 = 0,
87 },{ 91 },{
88 .type = CX23885_VMUX_SVIDEO, 92 .type = CX23885_VMUX_SVIDEO,
89 .vmux = 2, 93 .vmux = CX25840_VIN7_CH3 |
90 .gpio0 = 0xff02, 94 CX25840_VIN4_CH2 |
95 CX25840_VIN8_CH1 |
96 CX25840_SVIDEO_ON,
97 .gpio0 = 0,
91 }}, 98 }},
92 }, 99 },
93 [CX23885_BOARD_HAUPPAUGE_HVR1250] = { 100 [CX23885_BOARD_HAUPPAUGE_HVR1250] = {
diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c
index 8616a26895d8..e1b06d79e9b1 100644
--- a/drivers/media/video/cx23885/cx23885-core.c
+++ b/drivers/media/video/cx23885/cx23885-core.c
@@ -50,7 +50,7 @@ MODULE_PARM_DESC(card,"card type");
50static unsigned int cx23885_devcount; 50static unsigned int cx23885_devcount;
51 51
52static DEFINE_MUTEX(devlist); 52static DEFINE_MUTEX(devlist);
53static LIST_HEAD(cx23885_devlist); 53LIST_HEAD(cx23885_devlist);
54 54
55#define NO_SYNC_LINE (-1U) 55#define NO_SYNC_LINE (-1U)
56 56
@@ -356,7 +356,7 @@ static int cx23885_risc_decode(u32 risc)
356 return incr[risc >> 28] ? incr[risc >> 28] : 1; 356 return incr[risc >> 28] ? incr[risc >> 28] : 1;
357} 357}
358 358
359static void cx23885_wakeup(struct cx23885_tsport *port, 359void cx23885_wakeup(struct cx23885_tsport *port,
360 struct cx23885_dmaqueue *q, u32 count) 360 struct cx23885_dmaqueue *q, u32 count)
361{ 361{
362 struct cx23885_dev *dev = port->dev; 362 struct cx23885_dev *dev = port->dev;
@@ -392,7 +392,7 @@ static void cx23885_wakeup(struct cx23885_tsport *port,
392 __FUNCTION__, bc); 392 __FUNCTION__, bc);
393} 393}
394 394
395static int cx23885_sram_channel_setup(struct cx23885_dev *dev, 395int cx23885_sram_channel_setup(struct cx23885_dev *dev,
396 struct sram_channel *ch, 396 struct sram_channel *ch,
397 unsigned int bpl, u32 risc) 397 unsigned int bpl, u32 risc)
398{ 398{
@@ -465,7 +465,7 @@ static int cx23885_sram_channel_setup(struct cx23885_dev *dev,
465 return 0; 465 return 0;
466} 466}
467 467
468static void cx23885_sram_channel_dump(struct cx23885_dev *dev, 468void cx23885_sram_channel_dump(struct cx23885_dev *dev,
469 struct sram_channel *ch) 469 struct sram_channel *ch)
470{ 470{
471 static char *name[] = { 471 static char *name[] = {
@@ -592,15 +592,18 @@ static void cx23885_reset(struct cx23885_dev *dev)
592 592
593 mdelay(100); 593 mdelay(100);
594 594
595 cx23885_sram_channel_setup(dev, &dev->sram_channels[ SRAM_CH01 ], 188*4, 0); 595 cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH01],
596 cx23885_sram_channel_setup(dev, &dev->sram_channels[ SRAM_CH02 ], 128, 0); 596 720*4, 0);
597 cx23885_sram_channel_setup(dev, &dev->sram_channels[ SRAM_CH03 ], 188*4, 0); 597 cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH02], 128, 0);
598 cx23885_sram_channel_setup(dev, &dev->sram_channels[ SRAM_CH04 ], 128, 0); 598 cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH03],
599 cx23885_sram_channel_setup(dev, &dev->sram_channels[ SRAM_CH05 ], 128, 0); 599 188*4, 0);
600 cx23885_sram_channel_setup(dev, &dev->sram_channels[ SRAM_CH06 ], 188*4, 0); 600 cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH04], 128, 0);
601 cx23885_sram_channel_setup(dev, &dev->sram_channels[ SRAM_CH07 ], 128, 0); 601 cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH05], 128, 0);
602 cx23885_sram_channel_setup(dev, &dev->sram_channels[ SRAM_CH08 ], 128, 0); 602 cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH06],
603 cx23885_sram_channel_setup(dev, &dev->sram_channels[ SRAM_CH09 ], 128, 0); 603 188*4, 0);
604 cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH07], 128, 0);
605 cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH08], 128, 0);
606 cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH09], 128, 0);
604 607
605 cx23885_gpio_setup(dev); 608 cx23885_gpio_setup(dev);
606} 609}
@@ -634,7 +637,7 @@ static int get_resources(struct cx23885_dev *dev)
634} 637}
635 638
636static void cx23885_timeout(unsigned long data); 639static void cx23885_timeout(unsigned long data);
637static int cx23885_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc, 640int cx23885_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
638 u32 reg, u32 mask, u32 value); 641 u32 reg, u32 mask, u32 value);
639 642
640static int cx23885_init_tsport(struct cx23885_dev *dev, struct cx23885_tsport *port, int portno) 643static int cx23885_init_tsport(struct cx23885_dev *dev, struct cx23885_tsport *port, int portno)
@@ -854,6 +857,17 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
854 857
855 cx23885_pci_quirks(dev); 858 cx23885_pci_quirks(dev);
856 859
860 /* Assume some sensible defaults */
861 dev->tuner_type = cx23885_boards[dev->board].tuner_type;
862 dev->tuner_addr = cx23885_boards[dev->board].tuner_addr;
863 dev->radio_type = cx23885_boards[dev->board].radio_type;
864 dev->radio_addr = cx23885_boards[dev->board].radio_addr;
865
866 dprintk(1, "%s() tuner_type = 0x%x tuner_addr = 0x%x\n",
867 __FUNCTION__, dev->tuner_type, dev->tuner_addr);
868 dprintk(1, "%s() radio_type = 0x%x radio_addr = 0x%x\n",
869 __FUNCTION__, dev->radio_type, dev->radio_addr);
870
857 /* init hardware */ 871 /* init hardware */
858 cx23885_reset(dev); 872 cx23885_reset(dev);
859 873
@@ -864,14 +878,21 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
864 cx23885_card_setup(dev); 878 cx23885_card_setup(dev);
865 cx23885_ir_init(dev); 879 cx23885_ir_init(dev);
866 880
867 if(cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) { 881 if (cx23885_boards[dev->board].porta == CX23885_ANALOG_VIDEO) {
882 if (cx23885_video_register(dev) < 0) {
883 printk(KERN_ERR "%s() Failed to register analog "
884 "video adapters on VID_A\n", __FUNCTION__);
885 }
886 }
887
888 if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) {
868 if (cx23885_dvb_register(&dev->ts1) < 0) { 889 if (cx23885_dvb_register(&dev->ts1) < 0) {
869 printk(KERN_ERR "%s() Failed to register dvb adapters on VID_B\n", 890 printk(KERN_ERR "%s() Failed to register dvb adapters on VID_B\n",
870 __FUNCTION__); 891 __FUNCTION__);
871 } 892 }
872 } 893 }
873 894
874 if(cx23885_boards[dev->board].portc == CX23885_MPEG_DVB) { 895 if (cx23885_boards[dev->board].portc == CX23885_MPEG_DVB) {
875 if (cx23885_dvb_register(&dev->ts2) < 0) { 896 if (cx23885_dvb_register(&dev->ts2) < 0) {
876 printk(KERN_ERR "%s() Failed to register dvb adapters on VID_C\n", 897 printk(KERN_ERR "%s() Failed to register dvb adapters on VID_C\n",
877 __FUNCTION__); 898 __FUNCTION__);
@@ -891,6 +912,9 @@ static void cx23885_dev_unregister(struct cx23885_dev *dev)
891 if (!atomic_dec_and_test(&dev->refcount)) 912 if (!atomic_dec_and_test(&dev->refcount))
892 return; 913 return;
893 914
915 if (cx23885_boards[dev->board].porta == CX23885_ANALOG_VIDEO)
916 cx23885_video_unregister(dev);
917
894 if(cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) 918 if(cx23885_boards[dev->board].portb == CX23885_MPEG_DVB)
895 cx23885_dvb_unregister(&dev->ts1); 919 cx23885_dvb_unregister(&dev->ts1);
896 920
@@ -958,6 +982,45 @@ static u32* cx23885_risc_field(u32 *rp, struct scatterlist *sglist,
958 return rp; 982 return rp;
959} 983}
960 984
985int cx23885_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
986 struct scatterlist *sglist, unsigned int top_offset,
987 unsigned int bottom_offset, unsigned int bpl,
988 unsigned int padding, unsigned int lines)
989{
990 u32 instructions, fields;
991 u32 *rp;
992 int rc;
993
994 fields = 0;
995 if (UNSET != top_offset)
996 fields++;
997 if (UNSET != bottom_offset)
998 fields++;
999
1000 /* estimate risc mem: worst case is one write per page border +
1001 one write per scan line + syncs + jump (all 2 dwords). Padding
1002 can cause next bpl to start close to a page border. First DMA
1003 region may be smaller than PAGE_SIZE */
1004 /* write and jump need and extra dword */
1005 instructions = fields * (1 + ((bpl + padding) * lines) / PAGE_SIZE + lines);
1006 instructions += 2;
1007 if ((rc = btcx_riscmem_alloc(pci,risc,instructions*12)) < 0)
1008 return rc;
1009
1010 /* write risc instructions */
1011 rp = risc->cpu;
1012 if (UNSET != top_offset)
1013 rp = cx23885_risc_field(rp, sglist, top_offset, 0,
1014 bpl, padding, lines);
1015 if (UNSET != bottom_offset)
1016 rp = cx23885_risc_field(rp, sglist, bottom_offset, 0x200,
1017 bpl, padding, lines);
1018
1019 /* save pointer to jmp instruction address */
1020 risc->jmp = rp;
1021 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof (*risc->cpu) > risc->size);
1022 return 0;
1023}
961 1024
962static int cx23885_risc_databuffer(struct pci_dev *pci, 1025static int cx23885_risc_databuffer(struct pci_dev *pci,
963 struct btcx_riscmem *risc, 1026 struct btcx_riscmem *risc,
@@ -990,7 +1053,7 @@ static int cx23885_risc_databuffer(struct pci_dev *pci,
990 return 0; 1053 return 0;
991} 1054}
992 1055
993static int cx23885_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc, 1056int cx23885_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
994 u32 reg, u32 mask, u32 value) 1057 u32 reg, u32 mask, u32 value)
995{ 1058{
996 u32 *rp; 1059 u32 *rp;
@@ -1023,6 +1086,57 @@ void cx23885_free_buffer(struct videobuf_queue *q, struct cx23885_buffer *buf)
1023 buf->vb.state = VIDEOBUF_NEEDS_INIT; 1086 buf->vb.state = VIDEOBUF_NEEDS_INIT;
1024} 1087}
1025 1088
1089static void cx23885_tsport_reg_dump(struct cx23885_tsport *port)
1090{
1091 struct cx23885_dev *dev = port->dev;
1092
1093 dprintk(1, "%s() Register Dump\n", __FUNCTION__);
1094 dprintk(1, "%s() DEV_CNTRL2 0x%08X\n", __FUNCTION__,
1095 cx_read(DEV_CNTRL2));
1096 dprintk(1, "%s() PCI_INT_MSK 0x%08X\n", __FUNCTION__,
1097 cx_read(PCI_INT_MSK));
1098 dprintk(1, "%s() AUD_INT_INT_MSK 0x%08X\n", __FUNCTION__,
1099 cx_read(AUDIO_INT_INT_MSK));
1100 dprintk(1, "%s() AUD_INT_DMA_CTL 0x%08X\n", __FUNCTION__,
1101 cx_read(AUD_INT_DMA_CTL));
1102 dprintk(1, "%s() AUD_EXT_INT_MSK 0x%08X\n", __FUNCTION__,
1103 cx_read(AUDIO_EXT_INT_MSK));
1104 dprintk(1, "%s() AUD_EXT_DMA_CTL 0x%08X\n", __FUNCTION__,
1105 cx_read(AUD_EXT_DMA_CTL));
1106 dprintk(1, "%s() PAD_CTRL 0x%08X\n", __FUNCTION__,
1107 cx_read(PAD_CTRL));
1108 dprintk(1, "%s() ALT_PIN_OUT_SEL 0x%08X\n", __FUNCTION__,
1109 cx_read(ALT_PIN_OUT_SEL));
1110 dprintk(1, "%s() GPIO2 0x%08X\n", __FUNCTION__,
1111 cx_read(GPIO2));
1112 dprintk(1, "%s() gpcnt(0x%08X) 0x%08X\n", __FUNCTION__,
1113 port->reg_gpcnt, cx_read(port->reg_gpcnt));
1114 dprintk(1, "%s() gpcnt_ctl(0x%08X) 0x%08x\n", __FUNCTION__,
1115 port->reg_gpcnt_ctl, cx_read(port->reg_gpcnt_ctl));
1116 dprintk(1, "%s() dma_ctl(0x%08X) 0x%08x\n", __FUNCTION__,
1117 port->reg_dma_ctl, cx_read(port->reg_dma_ctl));
1118 dprintk(1, "%s() src_sel(0x%08X) 0x%08x\n", __FUNCTION__,
1119 port->reg_src_sel, cx_read(port->reg_src_sel));
1120 dprintk(1, "%s() lngth(0x%08X) 0x%08x\n", __FUNCTION__,
1121 port->reg_lngth, cx_read(port->reg_lngth));
1122 dprintk(1, "%s() hw_sop_ctrl(0x%08X) 0x%08x\n", __FUNCTION__,
1123 port->reg_hw_sop_ctrl, cx_read(port->reg_hw_sop_ctrl));
1124 dprintk(1, "%s() gen_ctrl(0x%08X) 0x%08x\n", __FUNCTION__,
1125 port->reg_gen_ctrl, cx_read(port->reg_gen_ctrl));
1126 dprintk(1, "%s() bd_pkt_status(0x%08X) 0x%08x\n", __FUNCTION__,
1127 port->reg_bd_pkt_status, cx_read(port->reg_bd_pkt_status));
1128 dprintk(1, "%s() sop_status(0x%08X) 0x%08x\n", __FUNCTION__,
1129 port->reg_sop_status, cx_read(port->reg_sop_status));
1130 dprintk(1, "%s() fifo_ovfl_stat(0x%08X) 0x%08x\n", __FUNCTION__,
1131 port->reg_fifo_ovfl_stat, cx_read(port->reg_fifo_ovfl_stat));
1132 dprintk(1, "%s() vld_misc(0x%08X) 0x%08x\n", __FUNCTION__,
1133 port->reg_vld_misc, cx_read(port->reg_vld_misc));
1134 dprintk(1, "%s() ts_clk_en(0x%08X) 0x%08x\n", __FUNCTION__,
1135 port->reg_ts_clk_en, cx_read(port->reg_ts_clk_en));
1136 dprintk(1, "%s() ts_int_msk(0x%08X) 0x%08x\n", __FUNCTION__,
1137 port->reg_ts_int_msk, cx_read(port->reg_ts_int_msk));
1138}
1139
1026static int cx23885_start_dma(struct cx23885_tsport *port, 1140static int cx23885_start_dma(struct cx23885_tsport *port,
1027 struct cx23885_dmaqueue *q, 1141 struct cx23885_dmaqueue *q,
1028 struct cx23885_buffer *buf) 1142 struct cx23885_buffer *buf)
@@ -1085,6 +1199,9 @@ static int cx23885_start_dma(struct cx23885_tsport *port,
1085 1199
1086 cx_set(DEV_CNTRL2, (1<<5)); /* Enable RISC controller */ 1200 cx_set(DEV_CNTRL2, (1<<5)); /* Enable RISC controller */
1087 1201
1202 if (debug > 4)
1203 cx23885_tsport_reg_dump(port);
1204
1088 return 0; 1205 return 0;
1089} 1206}
1090 1207
@@ -1100,7 +1217,7 @@ static int cx23885_stop_dma(struct cx23885_tsport *port)
1100 return 0; 1217 return 0;
1101} 1218}
1102 1219
1103static int cx23885_restart_queue(struct cx23885_tsport *port, 1220int cx23885_restart_queue(struct cx23885_tsport *port,
1104 struct cx23885_dmaqueue *q) 1221 struct cx23885_dmaqueue *q)
1105{ 1222{
1106 struct cx23885_dev *dev = port->dev; 1223 struct cx23885_dev *dev = port->dev;
@@ -1324,12 +1441,15 @@ static irqreturn_t cx23885_irq(int irq, void *dev_id)
1324 struct cx23885_tsport *ts1 = &dev->ts1; 1441 struct cx23885_tsport *ts1 = &dev->ts1;
1325 struct cx23885_tsport *ts2 = &dev->ts2; 1442 struct cx23885_tsport *ts2 = &dev->ts2;
1326 u32 pci_status, pci_mask; 1443 u32 pci_status, pci_mask;
1444 u32 vida_status, vida_mask;
1327 u32 ts1_status, ts1_mask; 1445 u32 ts1_status, ts1_mask;
1328 u32 ts2_status, ts2_mask; 1446 u32 ts2_status, ts2_mask;
1329 int ts1_count = 0, ts2_count = 0, handled = 0; 1447 int vida_count = 0, ts1_count = 0, ts2_count = 0, handled = 0;
1330 1448
1331 pci_status = cx_read(PCI_INT_STAT); 1449 pci_status = cx_read(PCI_INT_STAT);
1332 pci_mask = cx_read(PCI_INT_MSK); 1450 pci_mask = cx_read(PCI_INT_MSK);
1451 vida_status = cx_read(VID_A_INT_STAT);
1452 vida_mask = cx_read(VID_A_INT_MSK);
1333 ts1_status = cx_read(VID_B_INT_STAT); 1453 ts1_status = cx_read(VID_B_INT_STAT);
1334 ts1_mask = cx_read(VID_B_INT_MSK); 1454 ts1_mask = cx_read(VID_B_INT_MSK);
1335 ts2_status = cx_read(VID_C_INT_STAT); 1455 ts2_status = cx_read(VID_C_INT_STAT);
@@ -1338,11 +1458,17 @@ static irqreturn_t cx23885_irq(int irq, void *dev_id)
1338 if ( (pci_status == 0) && (ts2_status == 0) && (ts1_status == 0) ) 1458 if ( (pci_status == 0) && (ts2_status == 0) && (ts1_status == 0) )
1339 goto out; 1459 goto out;
1340 1460
1461 vida_count = cx_read(VID_A_GPCNT);
1341 ts1_count = cx_read(ts1->reg_gpcnt); 1462 ts1_count = cx_read(ts1->reg_gpcnt);
1342 ts2_count = cx_read(ts2->reg_gpcnt); 1463 ts2_count = cx_read(ts2->reg_gpcnt);
1343 dprintk(7, "pci_status: 0x%08x pci_mask: 0x%08x\n", pci_status, pci_mask ); 1464 dprintk(7, "pci_status: 0x%08x pci_mask: 0x%08x\n",
1344 dprintk(7, "ts1_status: 0x%08x ts1_mask: 0x%08x count: 0x%x\n", ts1_status, ts1_mask, ts1_count ); 1465 pci_status, pci_mask);
1345 dprintk(7, "ts2_status: 0x%08x ts2_mask: 0x%08x count: 0x%x\n", ts2_status, ts2_mask, ts2_count ); 1466 dprintk(7, "vida_status: 0x%08x vida_mask: 0x%08x count: 0x%x\n",
1467 vida_status, vida_mask, vida_count);
1468 dprintk(7, "ts1_status: 0x%08x ts1_mask: 0x%08x count: 0x%x\n",
1469 ts1_status, ts1_mask, ts1_count);
1470 dprintk(7, "ts2_status: 0x%08x ts2_mask: 0x%08x count: 0x%x\n",
1471 ts2_status, ts2_mask, ts2_count);
1346 1472
1347 if ( (pci_status & PCI_MSK_RISC_RD) || 1473 if ( (pci_status & PCI_MSK_RISC_RD) ||
1348 (pci_status & PCI_MSK_RISC_WR) || 1474 (pci_status & PCI_MSK_RISC_WR) ||
@@ -1379,11 +1505,18 @@ static irqreturn_t cx23885_irq(int irq, void *dev_id)
1379 1505
1380 } 1506 }
1381 1507
1382 if (ts1_status) 1508 if (ts1_status) {
1383 handled += cx23885_irq_ts(ts1, ts1_status); 1509 if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB)
1510 handled += cx23885_irq_ts(ts1, ts1_status);
1511 }
1512
1513 if (ts2_status) {
1514 if (cx23885_boards[dev->board].portc == CX23885_MPEG_DVB)
1515 handled += cx23885_irq_ts(ts2, ts2_status);
1516 }
1384 1517
1385 if (ts2_status) 1518 if (vida_status)
1386 handled += cx23885_irq_ts(ts2, ts2_status); 1519 handled += cx23885_video_irq(dev, vida_status);
1387 1520
1388 if (handled) 1521 if (handled)
1389 cx_write(PCI_INT_STAT, pci_status); 1522 cx_write(PCI_INT_STAT, pci_status);
diff --git a/drivers/media/video/cx23885/cx23885-i2c.c b/drivers/media/video/cx23885/cx23885-i2c.c
index b2ffbf04ef2c..fbc4a57a236b 100644
--- a/drivers/media/video/cx23885/cx23885-i2c.c
+++ b/drivers/media/video/cx23885/cx23885-i2c.c
@@ -270,7 +270,9 @@ static int i2c_xfer(struct i2c_adapter *i2c_adap,
270 270
271static int attach_inform(struct i2c_client *client) 271static int attach_inform(struct i2c_client *client)
272{ 272{
273 struct cx23885_dev *dev = i2c_get_adapdata(client->adapter); 273 struct cx23885_i2c *bus = i2c_get_adapdata(client->adapter);
274 struct cx23885_dev *dev = bus->dev;
275 struct tuner_setup tun_setup;
274 276
275 dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n", 277 dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n",
276 client->driver->driver.name, client->addr, client->name); 278 client->driver->driver.name, client->addr, client->name);
@@ -278,6 +280,31 @@ static int attach_inform(struct i2c_client *client)
278 if (!client->driver->command) 280 if (!client->driver->command)
279 return 0; 281 return 0;
280 282
283 if (dev->tuner_type != UNSET) {
284
285 dprintk(1, "%s (tuner) i2c attach [addr=0x%x,client=%s]\n",
286 client->driver->driver.name, client->addr,
287 client->name);
288
289 if ((dev->tuner_addr == ADDR_UNSET) ||
290 (dev->tuner_addr == client->addr)) {
291
292 dprintk(1, "%s (tuner || addr UNSET)\n",
293 client->driver->driver.name);
294
295 dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n",
296 client->driver->driver.name,
297 client->addr, client->name);
298
299 tun_setup.mode_mask = T_ANALOG_TV;
300 tun_setup.type = dev->tuner_type;
301 tun_setup.addr = dev->tuner_addr;
302
303 client->driver->command(client, TUNER_SET_TYPE_ADDR,
304 &tun_setup);
305 }
306 }
307
281 return 0; 308 return 0;
282} 309}
283 310
@@ -316,6 +343,7 @@ static struct i2c_adapter cx23885_i2c_adap_template = {
316 .owner = THIS_MODULE, 343 .owner = THIS_MODULE,
317 .id = I2C_HW_B_CX23885, 344 .id = I2C_HW_B_CX23885,
318 .algo = &cx23885_i2c_algo_template, 345 .algo = &cx23885_i2c_algo_template,
346 .class = I2C_CLASS_TV_ANALOG,
319 .client_register = attach_inform, 347 .client_register = attach_inform,
320 .client_unregister = detach_inform, 348 .client_unregister = detach_inform,
321}; 349};
@@ -371,6 +399,7 @@ int cx23885_i2c_register(struct cx23885_i2c *bus)
371 399
372 bus->i2c_algo.data = bus; 400 bus->i2c_algo.data = bus;
373 bus->i2c_adap.algo_data = bus; 401 bus->i2c_adap.algo_data = bus;
402 i2c_set_adapdata(&bus->i2c_adap, bus);
374 i2c_add_adapter(&bus->i2c_adap); 403 i2c_add_adapter(&bus->i2c_adap);
375 404
376 bus->i2c_client.adapter = &bus->i2c_adap; 405 bus->i2c_client.adapter = &bus->i2c_adap;
diff --git a/drivers/media/video/cx23885/cx23885-reg.h b/drivers/media/video/cx23885/cx23885-reg.h
index 38abf49b63a1..bdd11bc513ad 100644
--- a/drivers/media/video/cx23885/cx23885-reg.h
+++ b/drivers/media/video/cx23885/cx23885-reg.h
@@ -233,6 +233,17 @@ Channel manager Data Structure entry = 20 DWORD
233#define VID_A_INT_SSTAT 0x0004002C 233#define VID_A_INT_SSTAT 0x0004002C
234 234
235#define VID_B_INT_MSK 0x00040030 235#define VID_B_INT_MSK 0x00040030
236#define VID_B_MSK_BAD_PKT (1 << 20)
237#define VID_B_MSK_VBI_OPC_ERR (1 << 17)
238#define VID_B_MSK_OPC_ERR (1 << 16)
239#define VID_B_MSK_VBI_SYNC (1 << 13)
240#define VID_B_MSK_SYNC (1 << 12)
241#define VID_B_MSK_VBI_OF (1 << 9)
242#define VID_B_MSK_OF (1 << 8)
243#define VID_B_MSK_VBI_RISCI2 (1 << 5)
244#define VID_B_MSK_RISCI2 (1 << 4)
245#define VID_B_MSK_VBI_RISCI1 (1 << 1)
246#define VID_B_MSK_RISCI1 1
236#define VID_B_INT_STAT 0x00040034 247#define VID_B_INT_STAT 0x00040034
237#define VID_B_INT_MSTAT 0x00040038 248#define VID_B_INT_MSTAT 0x00040038
238#define VID_B_INT_SSTAT 0x0004003C 249#define VID_B_INT_SSTAT 0x0004003C
@@ -336,6 +347,7 @@ Channel manager Data Structure entry = 20 DWORD
336/* GPIO (417 Microsoftcontroller) Output Enable, Low Active */ 347/* GPIO (417 Microsoftcontroller) Output Enable, Low Active */
337#define MC417_OEN 0x00110024 348#define MC417_OEN 0x00110024
338#define MC417_CTL 0x00110028 349#define MC417_CTL 0x00110028
350#define ALT_PIN_OUT_SEL 0x0011002C
339#define CLK_DELAY 0x00110048 351#define CLK_DELAY 0x00110048
340#define PAD_CTRL 0x0011004C 352#define PAD_CTRL 0x0011004C
341 353
diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h
index b957242dcd5e..390f9335bdc9 100644
--- a/drivers/media/video/cx23885/cx23885.h
+++ b/drivers/media/video/cx23885/cx23885.h
@@ -44,6 +44,10 @@
44 44
45/* Max number of inputs by card */ 45/* Max number of inputs by card */
46#define MAX_CX23885_INPUT 8 46#define MAX_CX23885_INPUT 8
47#define INPUT(nr) (&cx23885_boards[dev->board].input[nr])
48#define RESOURCE_OVERLAY 1
49#define RESOURCE_VIDEO 2
50#define RESOURCE_VBI 4
47 51
48#define BUFFER_TIMEOUT (HZ) /* 0.5 seconds */ 52#define BUFFER_TIMEOUT (HZ) /* 0.5 seconds */
49 53
@@ -56,6 +60,60 @@
56#define CX23885_BOARD_HAUPPAUGE_HVR1500Q 5 60#define CX23885_BOARD_HAUPPAUGE_HVR1500Q 5
57#define CX23885_BOARD_HAUPPAUGE_HVR1500 6 61#define CX23885_BOARD_HAUPPAUGE_HVR1500 6
58 62
63/* Currently unsupported by the driver: PAL/H, NTSC/Kr, SECAM B/G/H/LC */
64#define CX23885_NORMS (\
65 V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_JP | V4L2_STD_NTSC_443 | \
66 V4L2_STD_PAL_BG | V4L2_STD_PAL_DK | V4L2_STD_PAL_I | \
67 V4L2_STD_PAL_M | V4L2_STD_PAL_N | V4L2_STD_PAL_Nc | \
68 V4L2_STD_PAL_60 | V4L2_STD_SECAM_L | V4L2_STD_SECAM_DK)
69
70struct cx23885_fmt {
71 char *name;
72 u32 fourcc; /* v4l2 format id */
73 int depth;
74 int flags;
75 u32 cxformat;
76};
77
78struct cx23885_ctrl {
79 struct v4l2_queryctrl v;
80 u32 off;
81 u32 reg;
82 u32 mask;
83 u32 shift;
84};
85
86struct cx23885_tvnorm {
87 char *name;
88 v4l2_std_id id;
89 u32 cxiformat;
90 u32 cxoformat;
91};
92
93struct cx23885_fh {
94 struct cx23885_dev *dev;
95 enum v4l2_buf_type type;
96 int radio;
97 u32 resources;
98
99 /* video overlay */
100 struct v4l2_window win;
101 struct v4l2_clip *clips;
102 unsigned int nclips;
103
104 /* video capture */
105 struct cx23885_fmt *fmt;
106 unsigned int width, height;
107
108 /* vbi capture */
109 struct videobuf_queue vidq;
110 struct videobuf_queue vbiq;
111
112 /* MPEG Encoder specifics ONLY */
113 struct videobuf_queue mpegq;
114 atomic_t v4l_reading;
115};
116
59enum cx23885_itype { 117enum cx23885_itype {
60 CX23885_VMUX_COMPOSITE1 = 1, 118 CX23885_VMUX_COMPOSITE1 = 1,
61 CX23885_VMUX_COMPOSITE2, 119 CX23885_VMUX_COMPOSITE2,
@@ -94,12 +152,17 @@ struct cx23885_input {
94 152
95typedef enum { 153typedef enum {
96 CX23885_MPEG_UNDEFINED = 0, 154 CX23885_MPEG_UNDEFINED = 0,
97 CX23885_MPEG_DVB 155 CX23885_MPEG_DVB,
156 CX23885_ANALOG_VIDEO,
98} port_t; 157} port_t;
99 158
100struct cx23885_board { 159struct cx23885_board {
101 char *name; 160 char *name;
102 port_t portb, portc; 161 port_t porta, portb, portc;
162 unsigned int tuner_type;
163 unsigned int radio_type;
164 unsigned char tuner_addr;
165 unsigned char radio_addr;
103 166
104 /* Vendors can and do run the PCIe bridge at different 167 /* Vendors can and do run the PCIe bridge at different
105 * clock rates, driven physically by crystals on the PCBs. 168 * clock rates, driven physically by crystals on the PCBs.
@@ -228,8 +291,31 @@ struct cx23885_dev {
228 CX23885_BRIDGE_885 = 885, 291 CX23885_BRIDGE_885 = 885,
229 CX23885_BRIDGE_887 = 887, 292 CX23885_BRIDGE_887 = 887,
230 } bridge; 293 } bridge;
294
295 /* Analog video */
296 u32 resources;
297 unsigned int input;
298 u32 tvaudio;
299 v4l2_std_id tvnorm;
300 unsigned int tuner_type;
301 unsigned char tuner_addr;
302 unsigned int radio_type;
303 unsigned char radio_addr;
304 unsigned int has_radio;
305
306 /* V4l */
307 u32 freq;
308 struct video_device *video_dev;
309 struct video_device *vbi_dev;
310 struct video_device *radio_dev;
311
312 struct cx23885_dmaqueue vidq;
313 struct cx23885_dmaqueue vbiq;
314 spinlock_t slock;
231}; 315};
232 316
317extern struct list_head cx23885_devlist;
318
233#define SRAM_CH01 0 /* Video A */ 319#define SRAM_CH01 0 /* Video A */
234#define SRAM_CH02 1 /* VBI A */ 320#define SRAM_CH02 1 /* VBI A */
235#define SRAM_CH03 2 /* Video B */ 321#define SRAM_CH03 2 /* Video B */
@@ -273,8 +359,34 @@ struct sram_channel {
273#define cx_clear(reg,bit) cx_andor((reg),(bit),0) 359#define cx_clear(reg,bit) cx_andor((reg),(bit),0)
274 360
275/* ----------------------------------------------------------- */ 361/* ----------------------------------------------------------- */
276/* cx23885-cards.c */ 362/* cx23885-core.c */
363
364extern int cx23885_sram_channel_setup(struct cx23885_dev *dev,
365 struct sram_channel *ch,
366 unsigned int bpl, u32 risc);
367
368extern void cx23885_sram_channel_dump(struct cx23885_dev *dev,
369 struct sram_channel *ch);
277 370
371extern int cx23885_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
372 u32 reg, u32 mask, u32 value);
373
374extern int cx23885_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
375 struct scatterlist *sglist,
376 unsigned int top_offset, unsigned int bottom_offset,
377 unsigned int bpl, unsigned int padding, unsigned int lines);
378
379void cx23885_cancel_buffers(struct cx23885_tsport *port);
380
381extern int cx23885_restart_queue(struct cx23885_tsport *port,
382 struct cx23885_dmaqueue *q);
383
384extern void cx23885_wakeup(struct cx23885_tsport *port,
385 struct cx23885_dmaqueue *q, u32 count);
386
387
388/* ----------------------------------------------------------- */
389/* cx23885-cards.c */
278extern struct cx23885_board cx23885_boards[]; 390extern struct cx23885_board cx23885_boards[];
279extern const unsigned int cx23885_bcount; 391extern const unsigned int cx23885_bcount;
280 392
@@ -294,19 +406,50 @@ extern int cx23885_buf_prepare(struct videobuf_queue *q,
294 struct cx23885_tsport *port, 406 struct cx23885_tsport *port,
295 struct cx23885_buffer *buf, 407 struct cx23885_buffer *buf,
296 enum v4l2_field field); 408 enum v4l2_field field);
297
298extern void cx23885_buf_queue(struct cx23885_tsport *port, 409extern void cx23885_buf_queue(struct cx23885_tsport *port,
299 struct cx23885_buffer *buf); 410 struct cx23885_buffer *buf);
300extern void cx23885_free_buffer(struct videobuf_queue *q, 411extern void cx23885_free_buffer(struct videobuf_queue *q,
301 struct cx23885_buffer *buf); 412 struct cx23885_buffer *buf);
302 413
303/* ----------------------------------------------------------- */ 414/* ----------------------------------------------------------- */
415/* cx23885-video.c */
416/* Video */
417extern int cx23885_video_register(struct cx23885_dev *dev);
418extern void cx23885_video_unregister(struct cx23885_dev *dev);
419extern int cx23885_video_irq(struct cx23885_dev *dev, u32 status);
420
421/* ----------------------------------------------------------- */
422/* cx23885-vbi.c */
423extern int cx23885_vbi_fmt(struct file *file, void *priv,
424 struct v4l2_format *f);
425extern void cx23885_vbi_timeout(unsigned long data);
426extern struct videobuf_queue_ops cx23885_vbi_qops;
427
304/* cx23885-i2c.c */ 428/* cx23885-i2c.c */
305extern int cx23885_i2c_register(struct cx23885_i2c *bus); 429extern int cx23885_i2c_register(struct cx23885_i2c *bus);
306extern int cx23885_i2c_unregister(struct cx23885_i2c *bus); 430extern int cx23885_i2c_unregister(struct cx23885_i2c *bus);
307extern void cx23885_call_i2c_clients(struct cx23885_i2c *bus, unsigned int cmd, 431extern void cx23885_call_i2c_clients(struct cx23885_i2c *bus, unsigned int cmd,
308 void *arg); 432 void *arg);
309 433
434/* ----------------------------------------------------------- */
435/* tv norms */
436
437static inline unsigned int norm_maxw(v4l2_std_id norm)
438{
439 return (norm & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 720 : 768;
440}
441
442static inline unsigned int norm_maxh(v4l2_std_id norm)
443{
444 return (norm & V4L2_STD_625_50) ? 576 : 480;
445}
446
447static inline unsigned int norm_swidth(v4l2_std_id norm)
448{
449 return (norm & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 754 : 922;
450}
451
452
310/* 453/*
311 * Local variables: 454 * Local variables:
312 * c-basic-offset: 8 455 * c-basic-offset: 8