Commit a0cce2a0 authored by Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab

[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: default avatarMauro Carvalho Chehab <mchehab@osg.samsung.com>
parent b01cc9ce
...@@ -576,6 +576,7 @@ int dvb_create_media_graph(struct dvb_adapter *adap, ...@@ -576,6 +576,7 @@ int dvb_create_media_graph(struct dvb_adapter *adap,
struct media_interface *intf; struct media_interface *intf;
unsigned demux_pad = 0; unsigned demux_pad = 0;
unsigned dvr_pad = 0; unsigned dvr_pad = 0;
unsigned ntuner = 0, ndemod = 0;
int ret; int ret;
static const char *connector_name = "Television"; static const char *connector_name = "Television";
...@@ -586,9 +587,11 @@ int dvb_create_media_graph(struct dvb_adapter *adap, ...@@ -586,9 +587,11 @@ int dvb_create_media_graph(struct dvb_adapter *adap,
switch (entity->function) { switch (entity->function) {
case MEDIA_ENT_F_TUNER: case MEDIA_ENT_F_TUNER:
tuner = entity; tuner = entity;
ntuner++;
break; break;
case MEDIA_ENT_F_DTV_DEMOD: case MEDIA_ENT_F_DTV_DEMOD:
demod = entity; demod = entity;
ndemod++;
break; break;
case MEDIA_ENT_F_TS_DEMUX: case MEDIA_ENT_F_TS_DEMUX:
demux = entity; demux = entity;
...@@ -599,6 +602,18 @@ int dvb_create_media_graph(struct dvb_adapter *adap, ...@@ -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) { if (create_rf_connector) {
conn = kzalloc(sizeof(*conn), GFP_KERNEL); conn = kzalloc(sizeof(*conn), GFP_KERNEL);
if (!conn) if (!conn)
...@@ -623,28 +638,44 @@ int dvb_create_media_graph(struct dvb_adapter *adap, ...@@ -623,28 +638,44 @@ int dvb_create_media_graph(struct dvb_adapter *adap,
if (ret) if (ret)
return ret; return ret;
if (!tuner) if (!ntuner)
ret = media_create_pad_link(conn, 0, ret = media_create_pad_links(mdev,
demod, 0, MEDIA_ENT_F_CONN_RF,
MEDIA_LNK_FL_ENABLED); conn, 0,
MEDIA_ENT_F_DTV_DEMOD,
demod, 0,
MEDIA_LNK_FL_ENABLED,
false);
else else
ret = media_create_pad_link(conn, 0, ret = media_create_pad_links(mdev,
tuner, TUNER_PAD_RF_INPUT, MEDIA_ENT_F_CONN_RF,
MEDIA_LNK_FL_ENABLED); conn, 0,
MEDIA_ENT_F_TUNER,
tuner, TUNER_PAD_RF_INPUT,
MEDIA_LNK_FL_ENABLED,
false);
if (ret) if (ret)
return ret; return ret;
} }
if (tuner && demod) { if (ntuner && ndemod) {
ret = media_create_pad_link(tuner, TUNER_PAD_IF_OUTPUT, ret = media_create_pad_links(mdev,
demod, 0, MEDIA_LNK_FL_ENABLED); MEDIA_ENT_F_TUNER,
tuner, TUNER_PAD_IF_OUTPUT,
MEDIA_ENT_F_DTV_DEMOD,
demod, 0, MEDIA_LNK_FL_ENABLED,
false);
if (ret) if (ret)
return ret; return ret;
} }
if (demod && demux) { if (ndemod && demux) {
ret = media_create_pad_link(demod, 1, demux, ret = media_create_pad_links(mdev,
0, MEDIA_LNK_FL_ENABLED); MEDIA_ENT_F_DTV_DEMOD,
demod, 1,
MEDIA_ENT_F_TS_DEMUX,
demux, 0, MEDIA_LNK_FL_ENABLED,
false);
if (ret) if (ret)
return -ENOMEM; return -ENOMEM;
} }
......
...@@ -225,6 +225,13 @@ void dvb_unregister_device(struct dvb_device *dvbdev); ...@@ -225,6 +225,13 @@ void dvb_unregister_device(struct dvb_device *dvbdev);
* *
* @adap: pointer to struct dvb_adapter * @adap: pointer to struct dvb_adapter
* @create_rf_connector: if true, it creates the RF connector too * @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, __must_check int dvb_create_media_graph(struct dvb_adapter *adap,
bool create_rf_connector); bool create_rf_connector);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment