mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 22:21:40 +00:00
[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)
|
||||
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) {
|
||||
pr_err("dvb_create_media_graph failed %d\n", rc);
|
||||
goto client_error;
|
||||
|
@ -213,6 +213,13 @@ static void dvb_media_device_free(struct dvb_device *dvbdev)
|
||||
media_devnode_remove(dvbdev->intf_devnode);
|
||||
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
|
||||
}
|
||||
|
||||
@ -559,16 +566,18 @@ static int dvb_create_io_intf_links(struct dvb_adapter *adap,
|
||||
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_entity *entity, *tuner = NULL, *demod = NULL;
|
||||
struct media_entity *entity, *tuner = NULL, *demod = NULL, *conn;
|
||||
struct media_entity *demux = NULL, *ca = NULL;
|
||||
struct media_link *link;
|
||||
struct media_interface *intf;
|
||||
unsigned demux_pad = 0;
|
||||
unsigned dvr_pad = 0;
|
||||
int ret;
|
||||
static const char *connector_name = "Television";
|
||||
|
||||
if (!mdev)
|
||||
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) {
|
||||
ret = media_create_pad_link(tuner, TUNER_PAD_IF_OUTPUT,
|
||||
demod, 0, MEDIA_LNK_FL_ENABLED);
|
||||
|
@ -75,6 +75,9 @@ struct dvb_frontend;
|
||||
* used.
|
||||
* @mdev: pointer to struct media_device, used when the media
|
||||
* 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 {
|
||||
int num;
|
||||
@ -94,6 +97,8 @@ struct dvb_adapter {
|
||||
|
||||
#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
|
||||
struct media_device *mdev;
|
||||
struct media_entity *conn;
|
||||
struct media_pad *conn_pads;
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -214,7 +219,16 @@ int dvb_register_device(struct dvb_adapter *adap,
|
||||
void dvb_unregister_device(struct dvb_device *dvbdev);
|
||||
|
||||
#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,
|
||||
struct media_device *mdev)
|
||||
{
|
||||
@ -222,7 +236,9 @@ static inline void dvb_register_media_controller(struct dvb_adapter *adap,
|
||||
}
|
||||
|
||||
#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;
|
||||
};
|
||||
|
@ -486,7 +486,7 @@ static int dvb_register(struct au0828_dev *dev)
|
||||
dvb->start_count = 0;
|
||||
dvb->stop_count = 0;
|
||||
|
||||
result = dvb_create_media_graph(&dvb->adapter);
|
||||
result = dvb_create_media_graph(&dvb->adapter, false);
|
||||
if (result < 0)
|
||||
goto fail_create_graph;
|
||||
|
||||
|
@ -551,7 +551,7 @@ static int register_dvb(struct cx231xx_dvb *dvb,
|
||||
|
||||
/* register network adapter */
|
||||
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)
|
||||
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)
|
||||
goto err_dvb_unregister_frontend;
|
||||
|
||||
|
@ -330,7 +330,7 @@ int dvb_usb_adapter_frontend_init(struct dvb_usb_adapter *adap)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = dvb_create_media_graph(&adap->dvb_adap);
|
||||
ret = dvb_create_media_graph(&adap->dvb_adap, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user