diff options
author | Ralph Metzler <rjkm@metzlerbros.de> | 2011-01-10 04:36:15 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-03-21 19:31:45 -0400 |
commit | 0f0b270f905bbb0c8e75988ceaf10ff9a401e712 (patch) | |
tree | 03fd199d1cc923a1182b51f6b737cadbd2f4f5fb /drivers/media/dvb/ngene/ngene-core.c | |
parent | 8a484719c790772bc51c87c56323611752361bef (diff) |
[media] ngene: CXD2099AR Common Interface driver
Driver for the Common Interface Controller CXD2099AR.
Supports the CI of the cineS2 DVB-S2.
For now, data is passed through '/dev/dvb/adapterX/sec0':
- Encrypted data must be written to 'sec0'.
- Decrypted data can be read from 'sec0'.
- Setup the CAM using device 'ca0'.
Signed-off-by: Ralph Metzler <rjkm@metzlerbros.de>
Signed-off-by: Oliver Endriss <o.endriss@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/dvb/ngene/ngene-core.c')
-rw-r--r-- | drivers/media/dvb/ngene/ngene-core.c | 110 |
1 files changed, 84 insertions, 26 deletions
diff --git a/drivers/media/dvb/ngene/ngene-core.c b/drivers/media/dvb/ngene/ngene-core.c index 831b7586e88f..deaf72aab058 100644 --- a/drivers/media/dvb/ngene/ngene-core.c +++ b/drivers/media/dvb/ngene/ngene-core.c | |||
@@ -45,7 +45,6 @@ static int one_adapter = 1; | |||
45 | module_param(one_adapter, int, 0444); | 45 | module_param(one_adapter, int, 0444); |
46 | MODULE_PARM_DESC(one_adapter, "Use only one adapter."); | 46 | MODULE_PARM_DESC(one_adapter, "Use only one adapter."); |
47 | 47 | ||
48 | |||
49 | static int debug; | 48 | static int debug; |
50 | module_param(debug, int, 0444); | 49 | module_param(debug, int, 0444); |
51 | MODULE_PARM_DESC(debug, "Print debugging information."); | 50 | MODULE_PARM_DESC(debug, "Print debugging information."); |
@@ -476,7 +475,7 @@ static u8 SPDIFConfiguration[10] = { | |||
476 | 475 | ||
477 | static u8 TS_I2SConfiguration[4] = { 0x3E, 0x18, 0x00, 0x00 }; | 476 | static u8 TS_I2SConfiguration[4] = { 0x3E, 0x18, 0x00, 0x00 }; |
478 | 477 | ||
479 | static u8 TS_I2SOutConfiguration[4] = { 0x80, 0x20, 0x00, 0x00 }; | 478 | static u8 TS_I2SOutConfiguration[4] = { 0x80, 0x04, 0x00, 0x00 }; |
480 | 479 | ||
481 | static u8 ITUDecoderSetup[4][16] = { | 480 | static u8 ITUDecoderSetup[4][16] = { |
482 | {0x1c, 0x13, 0x01, 0x68, 0x3d, 0x90, 0x14, 0x20, /* SDTV */ | 481 | {0x1c, 0x13, 0x01, 0x68, 0x3d, 0x90, 0x14, 0x20, /* SDTV */ |
@@ -749,13 +748,11 @@ void set_transfer(struct ngene_channel *chan, int state) | |||
749 | if (chan->mode & NGENE_IO_TSOUT) { | 748 | if (chan->mode & NGENE_IO_TSOUT) { |
750 | chan->pBufferExchange = tsout_exchange; | 749 | chan->pBufferExchange = tsout_exchange; |
751 | /* 0x66666666 = 50MHz *2^33 /250MHz */ | 750 | /* 0x66666666 = 50MHz *2^33 /250MHz */ |
752 | chan->AudioDTOValue = 0x66666666; | 751 | chan->AudioDTOValue = 0x80000000; |
753 | /* set_dto(chan, 38810700+1000); */ | 752 | chan->AudioDTOUpdated = 1; |
754 | /* set_dto(chan, 19392658); */ | ||
755 | } | 753 | } |
756 | if (chan->mode & NGENE_IO_TSIN) | 754 | if (chan->mode & NGENE_IO_TSIN) |
757 | chan->pBufferExchange = tsin_exchange; | 755 | chan->pBufferExchange = tsin_exchange; |
758 | /* ngwritel(0, 0x9310); */ | ||
759 | spin_unlock_irq(&chan->state_lock); | 756 | spin_unlock_irq(&chan->state_lock); |
760 | } else | 757 | } else |
761 | ;/* printk(KERN_INFO DEVICE_NAME ": lock=%08x\n", | 758 | ;/* printk(KERN_INFO DEVICE_NAME ": lock=%08x\n", |
@@ -1168,6 +1165,7 @@ static void ngene_release_buffers(struct ngene *dev) | |||
1168 | iounmap(dev->iomem); | 1165 | iounmap(dev->iomem); |
1169 | free_common_buffers(dev); | 1166 | free_common_buffers(dev); |
1170 | vfree(dev->tsout_buf); | 1167 | vfree(dev->tsout_buf); |
1168 | vfree(dev->tsin_buf); | ||
1171 | vfree(dev->ain_buf); | 1169 | vfree(dev->ain_buf); |
1172 | vfree(dev->vin_buf); | 1170 | vfree(dev->vin_buf); |
1173 | vfree(dev); | 1171 | vfree(dev); |
@@ -1184,6 +1182,13 @@ static int ngene_get_buffers(struct ngene *dev) | |||
1184 | dvb_ringbuffer_init(&dev->tsout_rbuf, | 1182 | dvb_ringbuffer_init(&dev->tsout_rbuf, |
1185 | dev->tsout_buf, TSOUT_BUF_SIZE); | 1183 | dev->tsout_buf, TSOUT_BUF_SIZE); |
1186 | } | 1184 | } |
1185 | if (dev->card_info->io_type[2]&NGENE_IO_TSIN) { | ||
1186 | dev->tsin_buf = vmalloc(TSIN_BUF_SIZE); | ||
1187 | if (!dev->tsin_buf) | ||
1188 | return -ENOMEM; | ||
1189 | dvb_ringbuffer_init(&dev->tsin_rbuf, | ||
1190 | dev->tsin_buf, TSIN_BUF_SIZE); | ||
1191 | } | ||
1187 | if (dev->card_info->io_type[2] & NGENE_IO_AIN) { | 1192 | if (dev->card_info->io_type[2] & NGENE_IO_AIN) { |
1188 | dev->ain_buf = vmalloc(AIN_BUF_SIZE); | 1193 | dev->ain_buf = vmalloc(AIN_BUF_SIZE); |
1189 | if (!dev->ain_buf) | 1194 | if (!dev->ain_buf) |
@@ -1307,6 +1312,35 @@ static void ngene_stop(struct ngene *dev) | |||
1307 | #endif | 1312 | #endif |
1308 | } | 1313 | } |
1309 | 1314 | ||
1315 | static int ngene_buffer_config(struct ngene *dev) | ||
1316 | { | ||
1317 | int stat; | ||
1318 | |||
1319 | if (dev->card_info->fw_version >= 17) { | ||
1320 | u8 tsin12_config[6] = { 0x60, 0x60, 0x00, 0x00, 0x00, 0x00 }; | ||
1321 | u8 tsin1234_config[6] = { 0x30, 0x30, 0x00, 0x30, 0x30, 0x00 }; | ||
1322 | u8 tsio1235_config[6] = { 0x30, 0x30, 0x00, 0x28, 0x00, 0x38 }; | ||
1323 | u8 *bconf = tsin12_config; | ||
1324 | |||
1325 | if (dev->card_info->io_type[2]&NGENE_IO_TSIN && | ||
1326 | dev->card_info->io_type[3]&NGENE_IO_TSIN) { | ||
1327 | bconf = tsin1234_config; | ||
1328 | if (dev->card_info->io_type[4]&NGENE_IO_TSOUT && | ||
1329 | dev->ci.en) | ||
1330 | bconf = tsio1235_config; | ||
1331 | } | ||
1332 | stat = ngene_command_config_free_buf(dev, bconf); | ||
1333 | } else { | ||
1334 | int bconf = BUFFER_CONFIG_4422; | ||
1335 | |||
1336 | if (dev->card_info->io_type[3] == NGENE_IO_TSIN) | ||
1337 | bconf = BUFFER_CONFIG_3333; | ||
1338 | stat = ngene_command_config_buf(dev, bconf); | ||
1339 | } | ||
1340 | return stat; | ||
1341 | } | ||
1342 | |||
1343 | |||
1310 | static int ngene_start(struct ngene *dev) | 1344 | static int ngene_start(struct ngene *dev) |
1311 | { | 1345 | { |
1312 | int stat; | 1346 | int stat; |
@@ -1371,23 +1405,6 @@ static int ngene_start(struct ngene *dev) | |||
1371 | if (stat < 0) | 1405 | if (stat < 0) |
1372 | goto fail; | 1406 | goto fail; |
1373 | 1407 | ||
1374 | if (dev->card_info->fw_version >= 17) { | ||
1375 | u8 tsin4_config[6] = { | ||
1376 | 3072 / 64, 3072 / 64, 0, 3072 / 64, 3072 / 64, 0}; | ||
1377 | u8 default_config[6] = { | ||
1378 | 4096 / 64, 4096 / 64, 0, 2048 / 64, 2048 / 64, 0}; | ||
1379 | u8 *bconf = default_config; | ||
1380 | |||
1381 | if (dev->card_info->io_type[3] == NGENE_IO_TSIN) | ||
1382 | bconf = tsin4_config; | ||
1383 | dprintk(KERN_DEBUG DEVICE_NAME ": FW 17+ buffer config\n"); | ||
1384 | stat = ngene_command_config_free_buf(dev, bconf); | ||
1385 | } else { | ||
1386 | int bconf = BUFFER_CONFIG_4422; | ||
1387 | if (dev->card_info->io_type[3] == NGENE_IO_TSIN) | ||
1388 | bconf = BUFFER_CONFIG_3333; | ||
1389 | stat = ngene_command_config_buf(dev, bconf); | ||
1390 | } | ||
1391 | if (!stat) | 1408 | if (!stat) |
1392 | return stat; | 1409 | return stat; |
1393 | 1410 | ||
@@ -1403,9 +1420,6 @@ fail2: | |||
1403 | return stat; | 1420 | return stat; |
1404 | } | 1421 | } |
1405 | 1422 | ||
1406 | |||
1407 | |||
1408 | |||
1409 | /****************************************************************************/ | 1423 | /****************************************************************************/ |
1410 | /****************************************************************************/ | 1424 | /****************************************************************************/ |
1411 | /****************************************************************************/ | 1425 | /****************************************************************************/ |
@@ -1422,7 +1436,12 @@ static void release_channel(struct ngene_channel *chan) | |||
1422 | 1436 | ||
1423 | tasklet_kill(&chan->demux_tasklet); | 1437 | tasklet_kill(&chan->demux_tasklet); |
1424 | 1438 | ||
1439 | if (chan->number >= 2 && chan->number <= 3 && dev->ci.en) | ||
1440 | return; | ||
1441 | |||
1425 | if (io & (NGENE_IO_TSIN | NGENE_IO_TSOUT)) { | 1442 | if (io & (NGENE_IO_TSIN | NGENE_IO_TSOUT)) { |
1443 | if (chan->ci_dev) | ||
1444 | dvb_unregister_device(chan->ci_dev); | ||
1426 | if (chan->fe) { | 1445 | if (chan->fe) { |
1427 | dvb_unregister_frontend(chan->fe); | 1446 | dvb_unregister_frontend(chan->fe); |
1428 | dvb_frontend_detach(chan->fe); | 1447 | dvb_frontend_detach(chan->fe); |
@@ -1458,6 +1477,9 @@ static int init_channel(struct ngene_channel *chan) | |||
1458 | if (io & (NGENE_IO_TSIN | NGENE_IO_TSOUT)) { | 1477 | if (io & (NGENE_IO_TSIN | NGENE_IO_TSOUT)) { |
1459 | if (nr >= STREAM_AUDIOIN1) | 1478 | if (nr >= STREAM_AUDIOIN1) |
1460 | chan->DataFormatFlags = DF_SWAP32; | 1479 | chan->DataFormatFlags = DF_SWAP32; |
1480 | |||
1481 | if (nr >= 2 && nr <= 3 && dev->ci.en) | ||
1482 | return 0; | ||
1461 | if (nr == 0 || !one_adapter || dev->first_adapter == NULL) { | 1483 | if (nr == 0 || !one_adapter || dev->first_adapter == NULL) { |
1462 | adapter = &dev->adapter[nr]; | 1484 | adapter = &dev->adapter[nr]; |
1463 | ret = dvb_register_adapter(adapter, "nGene", | 1485 | ret = dvb_register_adapter(adapter, "nGene", |
@@ -1478,6 +1500,15 @@ static int init_channel(struct ngene_channel *chan) | |||
1478 | ret = my_dvb_dmxdev_ts_card_init(&chan->dmxdev, &chan->demux, | 1500 | ret = my_dvb_dmxdev_ts_card_init(&chan->dmxdev, &chan->demux, |
1479 | &chan->hw_frontend, | 1501 | &chan->hw_frontend, |
1480 | &chan->mem_frontend, adapter); | 1502 | &chan->mem_frontend, adapter); |
1503 | if (dev->ci.en && (io&NGENE_IO_TSOUT)) { | ||
1504 | dvb_ca_en50221_init(adapter, dev->ci.en, 0, 1); | ||
1505 | set_transfer(chan, 1); | ||
1506 | set_transfer(&chan->dev->channel[2], 1); | ||
1507 | |||
1508 | dvb_register_device(adapter, &chan->ci_dev, | ||
1509 | &ngene_dvbdev_ci, (void *) chan, | ||
1510 | DVB_DEVICE_SEC); | ||
1511 | } | ||
1481 | } | 1512 | } |
1482 | 1513 | ||
1483 | if (io & NGENE_IO_TSIN) { | 1514 | if (io & NGENE_IO_TSIN) { |
@@ -1525,6 +1556,24 @@ static int init_channels(struct ngene *dev) | |||
1525 | return 0; | 1556 | return 0; |
1526 | } | 1557 | } |
1527 | 1558 | ||
1559 | static void cxd_attach(struct ngene *dev) | ||
1560 | { | ||
1561 | struct ngene_ci *ci = &dev->ci; | ||
1562 | |||
1563 | ci->en = cxd2099_attach(0x40, dev, &dev->channel[0].i2c_adapter); | ||
1564 | ci->dev = dev; | ||
1565 | return; | ||
1566 | } | ||
1567 | |||
1568 | static void cxd_detach(struct ngene *dev) | ||
1569 | { | ||
1570 | struct ngene_ci *ci = &dev->ci; | ||
1571 | |||
1572 | dvb_ca_en50221_release(ci->en); | ||
1573 | kfree(ci->en); | ||
1574 | ci->en = 0; | ||
1575 | } | ||
1576 | |||
1528 | /****************************************************************************/ | 1577 | /****************************************************************************/ |
1529 | /* device probe/remove calls ************************************************/ | 1578 | /* device probe/remove calls ************************************************/ |
1530 | /****************************************************************************/ | 1579 | /****************************************************************************/ |
@@ -1537,6 +1586,8 @@ void __devexit ngene_remove(struct pci_dev *pdev) | |||
1537 | tasklet_kill(&dev->event_tasklet); | 1586 | tasklet_kill(&dev->event_tasklet); |
1538 | for (i = MAX_STREAM - 1; i >= 0; i--) | 1587 | for (i = MAX_STREAM - 1; i >= 0; i--) |
1539 | release_channel(&dev->channel[i]); | 1588 | release_channel(&dev->channel[i]); |
1589 | if (dev->ci.en) | ||
1590 | cxd_detach(dev); | ||
1540 | ngene_stop(dev); | 1591 | ngene_stop(dev); |
1541 | ngene_release_buffers(dev); | 1592 | ngene_release_buffers(dev); |
1542 | pci_set_drvdata(pdev, NULL); | 1593 | pci_set_drvdata(pdev, NULL); |
@@ -1572,6 +1623,13 @@ int __devinit ngene_probe(struct pci_dev *pci_dev, | |||
1572 | if (stat < 0) | 1623 | if (stat < 0) |
1573 | goto fail1; | 1624 | goto fail1; |
1574 | 1625 | ||
1626 | cxd_attach(dev); | ||
1627 | |||
1628 | stat = ngene_buffer_config(dev); | ||
1629 | if (stat < 0) | ||
1630 | goto fail1; | ||
1631 | |||
1632 | |||
1575 | dev->i2c_current_bus = -1; | 1633 | dev->i2c_current_bus = -1; |
1576 | 1634 | ||
1577 | /* Register DVB adapters and devices for both channels */ | 1635 | /* Register DVB adapters and devices for both channels */ |