summaryrefslogtreecommitdiff
path: root/drivers/media/dvb-core/dvbdev.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@osg.samsung.com>2015-12-29 11:52:23 -0200
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>2016-01-11 12:19:25 -0200
commit0230d60e4661d9ced6fb0b9a30f182ebdafbba7a (patch)
tree7d9d8e71ba103473fe276b1c49040bfb72230f44 /drivers/media/dvb-core/dvbdev.c
parent0820eb5c5510b0a5c25a17c8be5e40156ace4991 (diff)
[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>
Diffstat (limited to 'drivers/media/dvb-core/dvbdev.c')
-rw-r--r--drivers/media/dvb-core/dvbdev.c49
1 files changed, 47 insertions, 2 deletions
diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c
index 860dd7d06b60..28e340583ede 100644
--- a/drivers/media/dvb-core/dvbdev.c
+++ b/drivers/media/dvb-core/dvbdev.c
@@ -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);