Skip to content

Commit

Permalink
[media] dvbdev: create links on devices with multiple frontends
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Mauro Carvalho Chehab committed Jan 11, 2016
1 parent b01cc9c commit a0cce2a
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 13 deletions.
57 changes: 44 additions & 13 deletions drivers/media/dvb-core/dvbdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand All @@ -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;
Expand All @@ -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)
Expand All @@ -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;
}
Expand Down
7 changes: 7 additions & 0 deletions drivers/media/dvb-core/dvbdev.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit a0cce2a

Please sign in to comment.