diff options
author | Rafael Lourenço de Lima Chehab <chehabrafael@gmail.com> | 2015-06-09 04:20:46 +0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@osg.samsung.com> | 2016-01-11 17:18:39 +0300 |
commit | bed6919665072b1e5bad31a013d53798394e097c (patch) | |
tree | baed884274ac819b315d5ffe7042a57ada05bfbd /drivers/media/usb/au0828/au0828-video.c | |
parent | e576d60bb21e7add884f052ff0e5c28ebf7b7461 (diff) | |
download | linux-bed6919665072b1e5bad31a013d53798394e097c.tar.xz |
[media] au0828: Add support for media controller
Add support for analog and dvb tv using media controller.
Signed-off-by: Rafael Lourenço de Lima Chehab <chehabrafael@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Diffstat (limited to 'drivers/media/usb/au0828/au0828-video.c')
-rw-r--r-- | drivers/media/usb/au0828/au0828-video.c | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c index 0a725a161dd6..7aa7d509885b 100644 --- a/drivers/media/usb/au0828/au0828-video.c +++ b/drivers/media/usb/au0828/au0828-video.c @@ -638,6 +638,75 @@ static inline int au0828_isoc_copy(struct au0828_dev *dev, struct urb *urb) return rc; } +static int au0828_enable_analog_tuner(struct au0828_dev *dev) +{ +#ifdef CONFIG_MEDIA_CONTROLLER + struct media_device *mdev = dev->media_dev; + struct media_entity *entity, *decoder = NULL, *source; + struct media_link *link, *found_link = NULL; + int i, ret, active_links = 0; + + if (!mdev) + return 0; + + /* + * This will find the tuner that is connected into the decoder. + * Technically, this is not 100% correct, as the device may be + * using an analog input instead of the tuner. However, as we can't + * do DVB streaming while the DMA engine is being used for V4L2, + * this should be enough for the actual needs. + */ + media_device_for_each_entity(entity, mdev) { + if (entity->type == MEDIA_ENT_T_V4L2_SUBDEV_DECODER) { + decoder = entity; + break; + } + } + if (!decoder) + return 0; + + for (i = 0; i < decoder->num_links; i++) { + link = &decoder->links[i]; + if (link->sink->entity == decoder) { + found_link = link; + if (link->flags & MEDIA_LNK_FL_ENABLED) + active_links++; + break; + } + } + + if (active_links == 1 || !found_link) + return 0; + + source = found_link->source->entity; + for (i = 0; i < source->num_links; i++) { + struct media_entity *sink; + int flags = 0; + + link = &source->links[i]; + sink = link->sink->entity; + + if (sink == entity) + flags = MEDIA_LNK_FL_ENABLED; + + ret = media_entity_setup_link(link, flags); + if (ret) { + pr_err( + "Couldn't change link %s->%s to %s. Error %d\n", + source->name, sink->name, + flags ? "enabled" : "disabled", + ret); + return ret; + } else + au0828_isocdbg( + "link %s->%s was %s\n", + source->name, sink->name, + flags ? "ENABLED" : "disabled"); + } +#endif + return 0; +} + static int queue_setup(struct vb2_queue *vq, unsigned int *nbuffers, unsigned int *nplanes, unsigned int sizes[], void *alloc_ctxs[]) @@ -650,6 +719,8 @@ static int queue_setup(struct vb2_queue *vq, *nplanes = 1; sizes[0] = size; + au0828_enable_analog_tuner(dev); + return 0; } @@ -1823,6 +1894,18 @@ int au0828_analog_register(struct au0828_dev *dev, dev->vbi_dev.queue->lock = &dev->vb_vbi_queue_lock; strcpy(dev->vbi_dev.name, "au0828a vbi"); +#if defined(CONFIG_MEDIA_CONTROLLER) + dev->video_pad.flags = MEDIA_PAD_FL_SINK; + ret = media_entity_init(&dev->vdev.entity, 1, &dev->video_pad, 0); + if (ret < 0) + pr_err("failed to initialize video media entity!\n"); + + dev->vbi_pad.flags = MEDIA_PAD_FL_SINK; + ret = media_entity_init(&dev->vbi_dev.entity, 1, &dev->vbi_pad, 0); + if (ret < 0) + pr_err("failed to initialize vbi media entity!\n"); +#endif + /* initialize videobuf2 stuff */ retval = au0828_vb2_setup(dev); if (retval != 0) { |