aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb-core
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@osg.samsung.com>2015-12-30 07:11:53 -0500
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>2016-01-11 09:19:26 -0500
commita0cce2a05756c9308f59c0303afe2c199e0789b0 (patch)
tree82e3d25ec429789607564063fcf461de3a937bd2 /drivers/media/dvb-core
parentb01cc9ce7c13e0463575332dfa3171727f706afb (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.c57
-rw-r--r--drivers/media/dvb-core/dvbdev.h7
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);