[media] dvbdev: Add RF connector if needed
Several pure digital TV devices have a frontend with the tuner integrated on it. Add the RF connector when dvb_create_media_graph() is called on such devices. Tested with siano and dvb_usb_mxl111sf drivers. Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
This commit is contained in:
parent
0820eb5c55
commit
0230d60e46
@ -1184,7 +1184,7 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev,
|
|||||||
if (smsdvb_debugfs_create(client) < 0)
|
if (smsdvb_debugfs_create(client) < 0)
|
||||||
pr_info("failed to create debugfs node\n");
|
pr_info("failed to create debugfs node\n");
|
||||||
|
|
||||||
rc = dvb_create_media_graph(&client->adapter);
|
rc = dvb_create_media_graph(&client->adapter, true);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
pr_err("dvb_create_media_graph failed %d\n", rc);
|
pr_err("dvb_create_media_graph failed %d\n", rc);
|
||||||
goto client_error;
|
goto client_error;
|
||||||
|
@ -213,6 +213,13 @@ static void dvb_media_device_free(struct dvb_device *dvbdev)
|
|||||||
media_devnode_remove(dvbdev->intf_devnode);
|
media_devnode_remove(dvbdev->intf_devnode);
|
||||||
dvbdev->intf_devnode = NULL;
|
dvbdev->intf_devnode = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dvbdev->adapter->conn) {
|
||||||
|
media_device_unregister_entity(dvbdev->adapter->conn);
|
||||||
|
dvbdev->adapter->conn = NULL;
|
||||||
|
kfree(dvbdev->adapter->conn_pads);
|
||||||
|
dvbdev->adapter->conn_pads = NULL;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -559,16 +566,18 @@ static int dvb_create_io_intf_links(struct dvb_adapter *adap,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dvb_create_media_graph(struct dvb_adapter *adap)
|
int dvb_create_media_graph(struct dvb_adapter *adap,
|
||||||
|
bool create_rf_connector)
|
||||||
{
|
{
|
||||||
struct media_device *mdev = adap->mdev;
|
struct media_device *mdev = adap->mdev;
|
||||||
struct media_entity *entity, *tuner = NULL, *demod = NULL;
|
struct media_entity *entity, *tuner = NULL, *demod = NULL, *conn;
|
||||||
struct media_entity *demux = NULL, *ca = NULL;
|
struct media_entity *demux = NULL, *ca = NULL;
|
||||||
struct media_link *link;
|
struct media_link *link;
|
||||||
struct media_interface *intf;
|
struct media_interface *intf;
|
||||||
unsigned demux_pad = 0;
|
unsigned demux_pad = 0;
|
||||||
unsigned dvr_pad = 0;
|
unsigned dvr_pad = 0;
|
||||||
int ret;
|
int ret;
|
||||||
|
static const char *connector_name = "Television";
|
||||||
|
|
||||||
if (!mdev)
|
if (!mdev)
|
||||||
return 0;
|
return 0;
|
||||||
@ -590,6 +599,42 @@ int dvb_create_media_graph(struct dvb_adapter *adap)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (create_rf_connector) {
|
||||||
|
conn = kzalloc(sizeof(*conn), GFP_KERNEL);
|
||||||
|
if (!conn)
|
||||||
|
return -ENOMEM;
|
||||||
|
adap->conn = conn;
|
||||||
|
|
||||||
|
adap->conn_pads = kcalloc(1, sizeof(*adap->conn_pads),
|
||||||
|
GFP_KERNEL);
|
||||||
|
if (!adap->conn_pads)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
conn->flags = MEDIA_ENT_FL_CONNECTOR;
|
||||||
|
conn->function = MEDIA_ENT_F_CONN_RF;
|
||||||
|
conn->name = connector_name;
|
||||||
|
adap->conn_pads->flags = MEDIA_PAD_FL_SOURCE;
|
||||||
|
|
||||||
|
ret = media_entity_pads_init(conn, 1, adap->conn_pads);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret = media_device_register_entity(mdev, conn);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (!tuner)
|
||||||
|
ret = media_create_pad_link(conn, 0,
|
||||||
|
demod, 0,
|
||||||
|
MEDIA_LNK_FL_ENABLED);
|
||||||
|
else
|
||||||
|
ret = media_create_pad_link(conn, 0,
|
||||||
|
tuner, TUNER_PAD_RF_INPUT,
|
||||||
|
MEDIA_LNK_FL_ENABLED);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
if (tuner && demod) {
|
if (tuner && demod) {
|
||||||
ret = media_create_pad_link(tuner, TUNER_PAD_IF_OUTPUT,
|
ret = media_create_pad_link(tuner, TUNER_PAD_IF_OUTPUT,
|
||||||
demod, 0, MEDIA_LNK_FL_ENABLED);
|
demod, 0, MEDIA_LNK_FL_ENABLED);
|
||||||
|
@ -75,6 +75,9 @@ struct dvb_frontend;
|
|||||||
* used.
|
* used.
|
||||||
* @mdev: pointer to struct media_device, used when the media
|
* @mdev: pointer to struct media_device, used when the media
|
||||||
* controller is used.
|
* controller is used.
|
||||||
|
* @conn: RF connector. Used only if the device has no separate
|
||||||
|
* tuner.
|
||||||
|
* @conn_pads: pointer to struct media_pad associated with @conn;
|
||||||
*/
|
*/
|
||||||
struct dvb_adapter {
|
struct dvb_adapter {
|
||||||
int num;
|
int num;
|
||||||
@ -94,6 +97,8 @@ struct dvb_adapter {
|
|||||||
|
|
||||||
#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
|
#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
|
||||||
struct media_device *mdev;
|
struct media_device *mdev;
|
||||||
|
struct media_entity *conn;
|
||||||
|
struct media_pad *conn_pads;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -214,7 +219,16 @@ int dvb_register_device(struct dvb_adapter *adap,
|
|||||||
void dvb_unregister_device(struct dvb_device *dvbdev);
|
void dvb_unregister_device(struct dvb_device *dvbdev);
|
||||||
|
|
||||||
#ifdef CONFIG_MEDIA_CONTROLLER_DVB
|
#ifdef CONFIG_MEDIA_CONTROLLER_DVB
|
||||||
__must_check int dvb_create_media_graph(struct dvb_adapter *adap);
|
/**
|
||||||
|
* dvb_create_media_graph - Creates media graph for the Digital TV part of the
|
||||||
|
* device.
|
||||||
|
*
|
||||||
|
* @adap: pointer to struct dvb_adapter
|
||||||
|
* @create_rf_connector: if true, it creates the RF connector too
|
||||||
|
*/
|
||||||
|
__must_check int dvb_create_media_graph(struct dvb_adapter *adap,
|
||||||
|
bool create_rf_connector);
|
||||||
|
|
||||||
static inline void dvb_register_media_controller(struct dvb_adapter *adap,
|
static inline void dvb_register_media_controller(struct dvb_adapter *adap,
|
||||||
struct media_device *mdev)
|
struct media_device *mdev)
|
||||||
{
|
{
|
||||||
@ -222,7 +236,9 @@ static inline void dvb_register_media_controller(struct dvb_adapter *adap,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
static inline int dvb_create_media_graph(struct dvb_adapter *adap)
|
static inline
|
||||||
|
int dvb_create_media_graph(struct dvb_adapter *adap,
|
||||||
|
bool create_rf_connector)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
@ -486,7 +486,7 @@ static int dvb_register(struct au0828_dev *dev)
|
|||||||
dvb->start_count = 0;
|
dvb->start_count = 0;
|
||||||
dvb->stop_count = 0;
|
dvb->stop_count = 0;
|
||||||
|
|
||||||
result = dvb_create_media_graph(&dvb->adapter);
|
result = dvb_create_media_graph(&dvb->adapter, false);
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
goto fail_create_graph;
|
goto fail_create_graph;
|
||||||
|
|
||||||
|
@ -551,7 +551,7 @@ static int register_dvb(struct cx231xx_dvb *dvb,
|
|||||||
|
|
||||||
/* register network adapter */
|
/* register network adapter */
|
||||||
dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx);
|
dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx);
|
||||||
result = dvb_create_media_graph(&dvb->adapter);
|
result = dvb_create_media_graph(&dvb->adapter, false);
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
goto fail_create_graph;
|
goto fail_create_graph;
|
||||||
|
|
||||||
|
@ -706,7 +706,7 @@ static int dvb_usbv2_adapter_frontend_init(struct dvb_usb_adapter *adap)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = dvb_create_media_graph(&adap->dvb_adap);
|
ret = dvb_create_media_graph(&adap->dvb_adap, true);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto err_dvb_unregister_frontend;
|
goto err_dvb_unregister_frontend;
|
||||||
|
|
||||||
|
@ -330,7 +330,7 @@ int dvb_usb_adapter_frontend_init(struct dvb_usb_adapter *adap)
|
|||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ret = dvb_create_media_graph(&adap->dvb_adap);
|
ret = dvb_create_media_graph(&adap->dvb_adap, true);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user