summaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@osg.samsung.com>2015-12-30 13:11:53 +0100
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>2016-01-11 15:19:26 +0100
commita0cce2a05756c9308f59c0303afe2c199e0789b0 (patch)
tree82e3d25ec429789607564063fcf461de3a937bd2 /drivers/media
parent[media] media-entitiy: add a function to create multiple links (diff)
downloadlinux-a0cce2a05756c9308f59c0303afe2c199e0789b0.tar.xz
linux-a0cce2a05756c9308f59c0303afe2c199e0789b0.zip
[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')
-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,
struct media_interface *intf;
unsigned demux_pad = 0;
unsigned dvr_pad = 0;
+ unsigned ntuner = 0, ndemod = 0;
int ret;
static const char *connector_name = "Television";
@@ -586,9 +587,11 @@ int dvb_create_media_graph(struct dvb_adapter *adap,
switch (entity->function) {
case MEDIA_ENT_F_TUNER:
tuner = entity;
+ ntuner++;
break;
case MEDIA_ENT_F_DTV_DEMOD:
demod = entity;
+ ndemod++;
break;
case MEDIA_ENT_F_TS_DEMUX:
demux = entity;
@@ -599,6 +602,18 @@ int dvb_create_media_graph(struct dvb_adapter *adap,
}
}
+ /*
+ * Prepare to signalize to media_create_pad_links() that multiple
+ * entities of the same type exists and a 1:n or n:1 links need to be
+ * created.
+ * NOTE: if both tuner and demod have multiple instances, it is up
+ * to the caller driver to create such links.
+ */
+ if (ntuner > 1)
+ tuner = NULL;
+ if (ndemod > 1)
+ demod = NULL;
+
if (create_rf_connector) {
conn = kzalloc(sizeof(*conn), GFP_KERNEL);
if (!conn)
@@ -623,28 +638,44 @@ int dvb_create_media_graph(struct dvb_adapter *adap,
if (ret)
return ret;
- if (!tuner)
- ret = media_create_pad_link(conn, 0,
- demod, 0,
- MEDIA_LNK_FL_ENABLED);
+ if (!ntuner)
+ ret = media_create_pad_links(mdev,
+ MEDIA_ENT_F_CONN_RF,
+ conn, 0,
+ MEDIA_ENT_F_DTV_DEMOD,
+ demod, 0,
+ MEDIA_LNK_FL_ENABLED,
+ false);
else
- ret = media_create_pad_link(conn, 0,
- tuner, TUNER_PAD_RF_INPUT,
- MEDIA_LNK_FL_ENABLED);
+ ret = media_create_pad_links(mdev,
+ MEDIA_ENT_F_CONN_RF,
+ conn, 0,
+ MEDIA_ENT_F_TUNER,
+ tuner, TUNER_PAD_RF_INPUT,
+ MEDIA_LNK_FL_ENABLED,
+ false);
if (ret)
return ret;
}
- if (tuner && demod) {
- ret = media_create_pad_link(tuner, TUNER_PAD_IF_OUTPUT,
- demod, 0, MEDIA_LNK_FL_ENABLED);
+ if (ntuner && ndemod) {
+ ret = media_create_pad_links(mdev,
+ MEDIA_ENT_F_TUNER,
+ tuner, TUNER_PAD_IF_OUTPUT,
+ MEDIA_ENT_F_DTV_DEMOD,
+ demod, 0, MEDIA_LNK_FL_ENABLED,
+ false);
if (ret)
return ret;
}
- if (demod && demux) {
- ret = media_create_pad_link(demod, 1, demux,
- 0, MEDIA_LNK_FL_ENABLED);
+ if (ndemod && demux) {
+ ret = media_create_pad_links(mdev,
+ MEDIA_ENT_F_DTV_DEMOD,
+ demod, 1,
+ MEDIA_ENT_F_TS_DEMUX,
+ demux, 0, MEDIA_LNK_FL_ENABLED,
+ false);
if (ret)
return -ENOMEM;
}
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);
*
* @adap: pointer to struct dvb_adapter
* @create_rf_connector: if true, it creates the RF connector too
+ *
+ * This function checks all DVB-related functions at the media controller
+ * entities and creates the needed links for the media graph. It is
+ * capable of working with multiple tuners or multiple frontends, but it
+ * won't create links if the device has multiple tuners and multiple frontends
+ * or if the device has multiple muxes. In such case, the caller driver should
+ * manually create the remaining links.
*/
__must_check int dvb_create_media_graph(struct dvb_adapter *adap,
bool create_rf_connector);