diff options
| author | Mauro Carvalho Chehab <mchehab@osg.samsung.com> | 2015-12-30 07:11:53 -0500 |
|---|---|---|
| committer | Mauro Carvalho Chehab <mchehab@osg.samsung.com> | 2016-01-11 09:19:26 -0500 |
| commit | a0cce2a05756c9308f59c0303afe2c199e0789b0 (patch) | |
| tree | 82e3d25ec429789607564063fcf461de3a937bd2 /drivers/media/dvb-core | |
| parent | b01cc9ce7c13e0463575332dfa3171727f706afb (diff) | |
[media] dvbdev: create links on devices with multiple frontends
Devices like mxl111sf-based WinTV Aero-m have multiple
frontends, all linked on the same demod. Currently, the
dvb_create_graph() function is not smart enough to create
multiple links. Fix it.
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Diffstat (limited to 'drivers/media/dvb-core')
| -rw-r--r-- | drivers/media/dvb-core/dvbdev.c | 57 | ||||
| -rw-r--r-- | drivers/media/dvb-core/dvbdev.h | 7 |
2 files changed, 51 insertions, 13 deletions
diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index 28e340583ede..560450a0b32a 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c | |||
| @@ -576,6 +576,7 @@ int dvb_create_media_graph(struct dvb_adapter *adap, | |||
| 576 | struct media_interface *intf; | 576 | struct media_interface *intf; |
| 577 | unsigned demux_pad = 0; | 577 | unsigned demux_pad = 0; |
| 578 | unsigned dvr_pad = 0; | 578 | unsigned dvr_pad = 0; |
| 579 | unsigned ntuner = 0, ndemod = 0; | ||
| 579 | int ret; | 580 | int ret; |
| 580 | static const char *connector_name = "Television"; | 581 | static const char *connector_name = "Television"; |
| 581 | 582 | ||
| @@ -586,9 +587,11 @@ int dvb_create_media_graph(struct dvb_adapter *adap, | |||
| 586 | switch (entity->function) { | 587 | switch (entity->function) { |
| 587 | case MEDIA_ENT_F_TUNER: | 588 | case MEDIA_ENT_F_TUNER: |
| 588 | tuner = entity; | 589 | tuner = entity; |
| 590 | ntuner++; | ||
| 589 | break; | 591 | break; |
| 590 | case MEDIA_ENT_F_DTV_DEMOD: | 592 | case MEDIA_ENT_F_DTV_DEMOD: |
| 591 | demod = entity; | 593 | demod = entity; |
| 594 | ndemod++; | ||
| 592 | break; | 595 | break; |
| 593 | case MEDIA_ENT_F_TS_DEMUX: | 596 | case MEDIA_ENT_F_TS_DEMUX: |
| 594 | demux = entity; | 597 | demux = entity; |
| @@ -599,6 +602,18 @@ int dvb_create_media_graph(struct dvb_adapter *adap, | |||
| 599 | } | 602 | } |
| 600 | } | 603 | } |
| 601 | 604 | ||
| 605 | /* | ||
| 606 | * Prepare to signalize to media_create_pad_links() that multiple | ||
| 607 | * entities of the same type exists and a 1:n or n:1 links need to be | ||
| 608 | * created. | ||
| 609 | * NOTE: if both tuner and demod have multiple instances, it is up | ||
| 610 | * to the caller driver to create such links. | ||
| 611 | */ | ||
| 612 | if (ntuner > 1) | ||
| 613 | tuner = NULL; | ||
| 614 | if (ndemod > 1) | ||
| 615 | demod = NULL; | ||
| 616 | |||
| 602 | if (create_rf_connector) { | 617 | if (create_rf_connector) { |
| 603 | conn = kzalloc(sizeof(*conn), GFP_KERNEL); | 618 | conn = kzalloc(sizeof(*conn), GFP_KERNEL); |
| 604 | if (!conn) | 619 | if (!conn) |
| @@ -623,28 +638,44 @@ int dvb_create_media_graph(struct dvb_adapter *adap, | |||
| 623 | if (ret) | 638 | if (ret) |
| 624 | return ret; | 639 | return ret; |
| 625 | 640 | ||
| 626 | if (!tuner) | 641 | if (!ntuner) |
| 627 | ret = media_create_pad_link(conn, 0, | 642 | ret = media_create_pad_links(mdev, |
| 628 | demod, 0, | 643 | MEDIA_ENT_F_CONN_RF, |
| 629 | MEDIA_LNK_FL_ENABLED); | 644 | conn, 0, |
| 645 | MEDIA_ENT_F_DTV_DEMOD, | ||
| 646 | demod, 0, | ||
| 647 | MEDIA_LNK_FL_ENABLED, | ||
| 648 | false); | ||
| 630 | else | 649 | else |
| 631 | ret = media_create_pad_link(conn, 0, | 650 | ret = media_create_pad_links(mdev, |
| 632 | tuner, TUNER_PAD_RF_INPUT, | 651 | MEDIA_ENT_F_CONN_RF, |
| 633 | MEDIA_LNK_FL_ENABLED); | 652 | conn, 0, |
| 653 | MEDIA_ENT_F_TUNER, | ||
| 654 | tuner, TUNER_PAD_RF_INPUT, | ||
| 655 | MEDIA_LNK_FL_ENABLED, | ||
| 656 | false); | ||
| 634 | if (ret) | 657 | if (ret) |
| 635 | return ret; | 658 | return ret; |
| 636 | } | 659 | } |
| 637 | 660 | ||
| 638 | if (tuner && demod) { | 661 | if (ntuner && ndemod) { |
| 639 | ret = media_create_pad_link(tuner, TUNER_PAD_IF_OUTPUT, | 662 | ret = media_create_pad_links(mdev, |
| 640 | demod, 0, MEDIA_LNK_FL_ENABLED); | 663 | MEDIA_ENT_F_TUNER, |
| 664 | tuner, TUNER_PAD_IF_OUTPUT, | ||
| 665 | MEDIA_ENT_F_DTV_DEMOD, | ||
| 666 | demod, 0, MEDIA_LNK_FL_ENABLED, | ||
| 667 | false); | ||
| 641 | if (ret) | 668 | if (ret) |
| 642 | return ret; | 669 | return ret; |
| 643 | } | 670 | } |
| 644 | 671 | ||
| 645 | if (demod && demux) { | 672 | if (ndemod && demux) { |
| 646 | ret = media_create_pad_link(demod, 1, demux, | 673 | ret = media_create_pad_links(mdev, |
| 647 | 0, MEDIA_LNK_FL_ENABLED); | 674 | MEDIA_ENT_F_DTV_DEMOD, |
| 675 | demod, 1, | ||
| 676 | MEDIA_ENT_F_TS_DEMUX, | ||
| 677 | demux, 0, MEDIA_LNK_FL_ENABLED, | ||
| 678 | false); | ||
| 648 | if (ret) | 679 | if (ret) |
| 649 | return -ENOMEM; | 680 | return -ENOMEM; |
| 650 | } | 681 | } |
diff --git a/drivers/media/dvb-core/dvbdev.h b/drivers/media/dvb-core/dvbdev.h index b622d6a3b95e..d7c67baa885e 100644 --- a/drivers/media/dvb-core/dvbdev.h +++ b/drivers/media/dvb-core/dvbdev.h | |||
| @@ -225,6 +225,13 @@ void dvb_unregister_device(struct dvb_device *dvbdev); | |||
| 225 | * | 225 | * |
| 226 | * @adap: pointer to struct dvb_adapter | 226 | * @adap: pointer to struct dvb_adapter |
| 227 | * @create_rf_connector: if true, it creates the RF connector too | 227 | * @create_rf_connector: if true, it creates the RF connector too |
| 228 | * | ||
| 229 | * This function checks all DVB-related functions at the media controller | ||
| 230 | * entities and creates the needed links for the media graph. It is | ||
| 231 | * capable of working with multiple tuners or multiple frontends, but it | ||
| 232 | * won't create links if the device has multiple tuners and multiple frontends | ||
| 233 | * or if the device has multiple muxes. In such case, the caller driver should | ||
| 234 | * manually create the remaining links. | ||
| 228 | */ | 235 | */ |
| 229 | __must_check int dvb_create_media_graph(struct dvb_adapter *adap, | 236 | __must_check int dvb_create_media_graph(struct dvb_adapter *adap, |
| 230 | bool create_rf_connector); | 237 | bool create_rf_connector); |
