aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx23885/cx23885-core.c
diff options
context:
space:
mode:
authorSteven Toth <stoth@hauppauge.com>2008-01-13 21:42:44 -0500
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-04-24 13:09:50 -0400
commitb1b81f1db73f00e595585b16aa31293a791964c0 (patch)
tree3e348070d6c08cf421729f36005e91b50c89ab98 /drivers/media/video/cx23885/cx23885-core.c
parente57b1c80065f7922e3ba464f54254c7ce983a3a4 (diff)
V4L/DVB (7725): cx23885: Add generic cx23417 hardware encoder support
cx23885: Add generic cx23417 hardware encoder support. Signed-off-by: Steven Toth <stoth@hauppauge.com> Signed-off-by: Michael Krufky <mkrufky@linuxtv.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/cx23885/cx23885-core.c')
-rw-r--r--drivers/media/video/cx23885/cx23885-core.c163
1 files changed, 133 insertions, 30 deletions
diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c
index b23d60801ed0..7f7446a76465 100644
--- a/drivers/media/video/cx23885/cx23885-core.c
+++ b/drivers/media/video/cx23885/cx23885-core.c
@@ -190,25 +190,25 @@ static struct sram_channel cx23887_sram_channels[] = {
190static int cx23885_risc_decode(u32 risc) 190static int cx23885_risc_decode(u32 risc)
191{ 191{
192 static char *instr[16] = { 192 static char *instr[16] = {
193 [ RISC_SYNC >> 28 ] = "sync", 193 [RISC_SYNC >> 28] = "sync",
194 [ RISC_WRITE >> 28 ] = "write", 194 [RISC_WRITE >> 28] = "write",
195 [ RISC_WRITEC >> 28 ] = "writec", 195 [RISC_WRITEC >> 28] = "writec",
196 [ RISC_READ >> 28 ] = "read", 196 [RISC_READ >> 28] = "read",
197 [ RISC_READC >> 28 ] = "readc", 197 [RISC_READC >> 28] = "readc",
198 [ RISC_JUMP >> 28 ] = "jump", 198 [RISC_JUMP >> 28] = "jump",
199 [ RISC_SKIP >> 28 ] = "skip", 199 [RISC_SKIP >> 28] = "skip",
200 [ RISC_WRITERM >> 28 ] = "writerm", 200 [RISC_WRITERM >> 28] = "writerm",
201 [ RISC_WRITECM >> 28 ] = "writecm", 201 [RISC_WRITECM >> 28] = "writecm",
202 [ RISC_WRITECR >> 28 ] = "writecr", 202 [RISC_WRITECR >> 28] = "writecr",
203 }; 203 };
204 static int incr[16] = { 204 static int incr[16] = {
205 [ RISC_WRITE >> 28 ] = 3, 205 [RISC_WRITE >> 28] = 3,
206 [ RISC_JUMP >> 28 ] = 3, 206 [RISC_JUMP >> 28] = 3,
207 [ RISC_SKIP >> 28 ] = 1, 207 [RISC_SKIP >> 28] = 1,
208 [ RISC_SYNC >> 28 ] = 1, 208 [RISC_SYNC >> 28] = 1,
209 [ RISC_WRITERM >> 28 ] = 3, 209 [RISC_WRITERM >> 28] = 3,
210 [ RISC_WRITECM >> 28 ] = 3, 210 [RISC_WRITECM >> 28] = 3,
211 [ RISC_WRITECR >> 28 ] = 4, 211 [RISC_WRITECR >> 28] = 4,
212 }; 212 };
213 static char *bits[] = { 213 static char *bits[] = {
214 "12", "13", "14", "resync", 214 "12", "13", "14", "resync",
@@ -518,6 +518,8 @@ static int cx23885_init_tsport(struct cx23885_dev *dev, struct cx23885_tsport *p
518 /* Transport bus init dma queue - Common settings */ 518 /* Transport bus init dma queue - Common settings */
519 port->dma_ctl_val = 0x11; /* Enable RISC controller and Fifo */ 519 port->dma_ctl_val = 0x11; /* Enable RISC controller and Fifo */
520 port->ts_int_msk_val = 0x1111; /* TS port bits for RISC */ 520 port->ts_int_msk_val = 0x1111; /* TS port bits for RISC */
521 port->vld_misc_val = 0x0;
522 port->hw_sop_ctrl_val = (0x47 << 16 | 188 << 4);
521 523
522 spin_lock_init(&port->slock); 524 spin_lock_init(&port->slock);
523 port->dev = dev; 525 port->dev = dev;
@@ -544,7 +546,7 @@ static int cx23885_init_tsport(struct cx23885_dev *dev, struct cx23885_tsport *p
544 port->reg_ts_clk_en = VID_B_TS_CLK_EN; 546 port->reg_ts_clk_en = VID_B_TS_CLK_EN;
545 port->reg_src_sel = VID_B_SRC_SEL; 547 port->reg_src_sel = VID_B_SRC_SEL;
546 port->reg_ts_int_msk = VID_B_INT_MSK; 548 port->reg_ts_int_msk = VID_B_INT_MSK;
547 port->reg_ts_int_stat = VID_B_INT_STAT; 549 port->reg_ts_int_stat = VID_B_INT_STAT;
548 port->sram_chno = SRAM_CH03; /* VID_B */ 550 port->sram_chno = SRAM_CH03; /* VID_B */
549 port->pci_irqmask = 0x02; /* VID_B bit1 */ 551 port->pci_irqmask = 0x02; /* VID_B bit1 */
550 break; 552 break;
@@ -697,10 +699,12 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
697 dev->i2c_bus[2].reg_wdata = I2C3_WDATA; 699 dev->i2c_bus[2].reg_wdata = I2C3_WDATA;
698 dev->i2c_bus[2].i2c_period = (0x07 << 24); /* 1.95MHz */ 700 dev->i2c_bus[2].i2c_period = (0x07 << 24); /* 1.95MHz */
699 701
700 if(cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) 702 if ((cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) ||
703 (cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER))
701 cx23885_init_tsport(dev, &dev->ts1, 1); 704 cx23885_init_tsport(dev, &dev->ts1, 1);
702 705
703 if(cx23885_boards[dev->board].portc == CX23885_MPEG_DVB) 706 if ((cx23885_boards[dev->board].portc == CX23885_MPEG_DVB) ||
707 (cx23885_boards[dev->board].portc == CX23885_MPEG_ENCODER))
704 cx23885_init_tsport(dev, &dev->ts2, 2); 708 cx23885_init_tsport(dev, &dev->ts2, 2);
705 709
706 if (get_resources(dev) < 0) { 710 if (get_resources(dev) < 0) {
@@ -760,11 +764,26 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
760 printk(KERN_ERR "%s() Failed to register dvb adapters on VID_B\n", 764 printk(KERN_ERR "%s() Failed to register dvb adapters on VID_B\n",
761 __func__); 765 __func__);
762 } 766 }
767 } else
768 if (cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER) {
769 if (cx23885_417_register(dev) < 0) {
770 printk(KERN_ERR
771 "%s() Failed to register 417 on VID_B\n",
772 __func__);
773 }
763 } 774 }
764 775
765 if (cx23885_boards[dev->board].portc == CX23885_MPEG_DVB) { 776 if (cx23885_boards[dev->board].portc == CX23885_MPEG_DVB) {
766 if (cx23885_dvb_register(&dev->ts2) < 0) { 777 if (cx23885_dvb_register(&dev->ts2) < 0) {
767 printk(KERN_ERR "%s() Failed to register dvb adapters on VID_C\n", 778 printk(KERN_ERR
779 "%s() Failed to register dvb on VID_C\n",
780 __func__);
781 }
782 } else
783 if (cx23885_boards[dev->board].portc == CX23885_MPEG_ENCODER) {
784 if (cx23885_417_register(dev) < 0) {
785 printk(KERN_ERR
786 "%s() Failed to register 417 on VID_C\n",
768 __func__); 787 __func__);
769 } 788 }
770 } 789 }
@@ -785,12 +804,18 @@ static void cx23885_dev_unregister(struct cx23885_dev *dev)
785 if (cx23885_boards[dev->board].porta == CX23885_ANALOG_VIDEO) 804 if (cx23885_boards[dev->board].porta == CX23885_ANALOG_VIDEO)
786 cx23885_video_unregister(dev); 805 cx23885_video_unregister(dev);
787 806
788 if(cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) 807 if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB)
789 cx23885_dvb_unregister(&dev->ts1); 808 cx23885_dvb_unregister(&dev->ts1);
790 809
791 if(cx23885_boards[dev->board].portc == CX23885_MPEG_DVB) 810 if (cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER)
811 cx23885_417_unregister(dev);
812
813 if (cx23885_boards[dev->board].portc == CX23885_MPEG_DVB)
792 cx23885_dvb_unregister(&dev->ts2); 814 cx23885_dvb_unregister(&dev->ts2);
793 815
816 if (cx23885_boards[dev->board].portc == CX23885_MPEG_ENCODER)
817 cx23885_417_unregister(dev);
818
794 cx23885_i2c_unregister(&dev->i2c_bus[2]); 819 cx23885_i2c_unregister(&dev->i2c_bus[2]);
795 cx23885_i2c_unregister(&dev->i2c_bus[1]); 820 cx23885_i2c_unregister(&dev->i2c_bus[1]);
796 cx23885_i2c_unregister(&dev->i2c_bus[0]); 821 cx23885_i2c_unregister(&dev->i2c_bus[0]);
@@ -1043,9 +1068,9 @@ static int cx23885_start_dma(struct cx23885_tsport *port,
1043 if(port->reg_src_sel) 1068 if(port->reg_src_sel)
1044 cx_write(port->reg_src_sel, port->src_sel_val); 1069 cx_write(port->reg_src_sel, port->src_sel_val);
1045 1070
1046 cx_write(port->reg_hw_sop_ctrl, 0x47 << 16 | 188 << 4); 1071 cx_write(port->reg_hw_sop_ctrl, port->hw_sop_ctrl_val);
1047 cx_write(port->reg_ts_clk_en, port->ts_clk_en_val); 1072 cx_write(port->reg_ts_clk_en, port->ts_clk_en_val);
1048 cx_write(port->reg_vld_misc, 0x00); 1073 cx_write(port->reg_vld_misc, port->vld_misc_val);
1049 cx_write(port->reg_gen_ctrl, port->gen_ctrl_val); 1074 cx_write(port->reg_gen_ctrl, port->gen_ctrl_val);
1050 udelay(100); 1075 udelay(100);
1051 1076
@@ -1239,6 +1264,16 @@ static void do_cancel_buffers(struct cx23885_tsport *port, char *reason,
1239 spin_unlock_irqrestore(&port->slock, flags); 1264 spin_unlock_irqrestore(&port->slock, flags);
1240} 1265}
1241 1266
1267void cx23885_cancel_buffers(struct cx23885_tsport *port)
1268{
1269 struct cx23885_dev *dev = port->dev;
1270 struct cx23885_dmaqueue *q = &port->mpegq;
1271
1272 dprintk(1, "%s()\n", __FUNCTION__);
1273 del_timer_sync(&q->timeout);
1274 cx23885_stop_dma(port);
1275 do_cancel_buffers(port, "cancel", 0);
1276}
1242 1277
1243static void cx23885_timeout(unsigned long data) 1278static void cx23885_timeout(unsigned long data)
1244{ 1279{
@@ -1254,16 +1289,77 @@ static void cx23885_timeout(unsigned long data)
1254 do_cancel_buffers(port, "timeout", 1); 1289 do_cancel_buffers(port, "timeout", 1);
1255} 1290}
1256 1291
1292int cx23885_irq_417(struct cx23885_dev *dev, u32 status)
1293{
1294 /* FIXME: port1 assumption here. */
1295 struct cx23885_tsport *port = &dev->ts1;
1296 int count = 0;
1297 int handled = 0;
1298
1299 if (status == 0)
1300 return handled;
1301
1302 count = cx_read(port->reg_gpcnt);
1303 dprintk(7, "status: 0x%08x mask: 0x%08x count: 0x%x\n",
1304 status, cx_read(port->reg_ts_int_msk), count);
1305
1306 if ((status & VID_B_MSK_BAD_PKT) ||
1307 (status & VID_B_MSK_OPC_ERR) ||
1308 (status & VID_B_MSK_VBI_OPC_ERR) ||
1309 (status & VID_B_MSK_SYNC) ||
1310 (status & VID_B_MSK_VBI_SYNC) ||
1311 (status & VID_B_MSK_OF) ||
1312 (status & VID_B_MSK_VBI_OF)) {
1313 printk(KERN_ERR "%s: V4L mpeg risc op code error, status "
1314 "= 0x%x\n", dev->name, status);
1315 if (status & VID_B_MSK_BAD_PKT)
1316 dprintk(1, " VID_B_MSK_BAD_PKT\n");
1317 if (status & VID_B_MSK_OPC_ERR)
1318 dprintk(1, " VID_B_MSK_OPC_ERR\n");
1319 if (status & VID_B_MSK_VBI_OPC_ERR)
1320 dprintk(1, " VID_B_MSK_VBI_OPC_ERR\n");
1321 if (status & VID_B_MSK_SYNC)
1322 dprintk(1, " VID_B_MSK_SYNC\n");
1323 if (status & VID_B_MSK_VBI_SYNC)
1324 dprintk(1, " VID_B_MSK_VBI_SYNC\n");
1325 if (status & VID_B_MSK_OF)
1326 dprintk(1, " VID_B_MSK_OF\n");
1327 if (status & VID_B_MSK_VBI_OF)
1328 dprintk(1, " VID_B_MSK_VBI_OF\n");
1329
1330 cx_clear(port->reg_dma_ctl, port->dma_ctl_val);
1331 cx23885_sram_channel_dump(dev,
1332 &dev->sram_channels[port->sram_chno]);
1333 cx23885_417_check_encoder(dev);
1334 } else if (status & VID_B_MSK_RISCI1) {
1335 dprintk(7, " VID_B_MSK_RISCI1\n");
1336 spin_lock(&port->slock);
1337 cx23885_wakeup(port, &port->mpegq, count);
1338 spin_unlock(&port->slock);
1339 } else if (status & VID_B_MSK_RISCI2) {
1340 dprintk(7, " VID_B_MSK_RISCI2\n");
1341 spin_lock(&port->slock);
1342 cx23885_restart_queue(port, &port->mpegq);
1343 spin_unlock(&port->slock);
1344 }
1345 if (status) {
1346 cx_write(port->reg_ts_int_stat, status);
1347 handled = 1;
1348 }
1349
1350 return handled;
1351}
1352
1257static int cx23885_irq_ts(struct cx23885_tsport *port, u32 status) 1353static int cx23885_irq_ts(struct cx23885_tsport *port, u32 status)
1258{ 1354{
1259 struct cx23885_dev *dev = port->dev; 1355 struct cx23885_dev *dev = port->dev;
1260 int handled = 0; 1356 int handled = 0;
1261 u32 count; 1357 u32 count;
1262 1358
1263 if ( (status & VID_BC_MSK_OPC_ERR) || 1359 if ((status & VID_BC_MSK_OPC_ERR) ||
1264 (status & VID_BC_MSK_BAD_PKT) || 1360 (status & VID_BC_MSK_BAD_PKT) ||
1265 (status & VID_BC_MSK_SYNC) || 1361 (status & VID_BC_MSK_SYNC) ||
1266 (status & VID_BC_MSK_OF)) 1362 (status & VID_BC_MSK_OF))
1267 { 1363 {
1268 if (status & VID_BC_MSK_OPC_ERR) 1364 if (status & VID_BC_MSK_OPC_ERR)
1269 dprintk(7, " (VID_BC_MSK_OPC_ERR 0x%08x)\n", VID_BC_MSK_OPC_ERR); 1365 dprintk(7, " (VID_BC_MSK_OPC_ERR 0x%08x)\n", VID_BC_MSK_OPC_ERR);
@@ -1277,7 +1373,8 @@ static int cx23885_irq_ts(struct cx23885_tsport *port, u32 status)
1277 printk(KERN_ERR "%s: mpeg risc op code error\n", dev->name); 1373 printk(KERN_ERR "%s: mpeg risc op code error\n", dev->name);
1278 1374
1279 cx_clear(port->reg_dma_ctl, port->dma_ctl_val); 1375 cx_clear(port->reg_dma_ctl, port->dma_ctl_val);
1280 cx23885_sram_channel_dump(dev, &dev->sram_channels[ port->sram_chno ]); 1376 cx23885_sram_channel_dump(dev,
1377 &dev->sram_channels[port->sram_chno]);
1281 1378
1282 } else if (status & VID_BC_MSK_RISCI1) { 1379 } else if (status & VID_BC_MSK_RISCI1) {
1283 1380
@@ -1378,11 +1475,17 @@ static irqreturn_t cx23885_irq(int irq, void *dev_id)
1378 if (ts1_status) { 1475 if (ts1_status) {
1379 if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) 1476 if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB)
1380 handled += cx23885_irq_ts(ts1, ts1_status); 1477 handled += cx23885_irq_ts(ts1, ts1_status);
1478 else
1479 if (cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER)
1480 handled += cx23885_irq_417(dev, ts1_status);
1381 } 1481 }
1382 1482
1383 if (ts2_status) { 1483 if (ts2_status) {
1384 if (cx23885_boards[dev->board].portc == CX23885_MPEG_DVB) 1484 if (cx23885_boards[dev->board].portc == CX23885_MPEG_DVB)
1385 handled += cx23885_irq_ts(ts2, ts2_status); 1485 handled += cx23885_irq_ts(ts2, ts2_status);
1486 else
1487 if (cx23885_boards[dev->board].portc == CX23885_MPEG_ENCODER)
1488 handled += cx23885_irq_417(dev, ts2_status);
1386 } 1489 }
1387 1490
1388 if (vida_status) 1491 if (vida_status)