Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b19581a9 authored by Shuah Khan's avatar Shuah Khan Committed by Mauro Carvalho Chehab
Browse files

[media] media: au0828 video change to use v4l_enable_media_source()



Change au0828 to check if tuner is free or not before changing tuner
configuration.

vidioc_g_tuner(), and au0828_v4l2_close() now call v4l-core interface
v4l_enable_media_source() before changing tuner configuration.

Remove au0828_enable_analog_tuner() as it is no longer needed because
v4l2-core implements common interfaces to check for media source
availability.

In addition, queue_setup() no longer needs the tuner availability check
since v4l2-core does it.

Signed-off-by: default avatarShuah Khan <shuahkh@osg.samsung.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@osg.samsung.com>
parent 68ff5767
Loading
Loading
Loading
Loading
+39 −63
Original line number Diff line number Diff line
@@ -796,64 +796,6 @@ int au0828_v4l2_device_register(struct usb_interface *interface,
	return 0;
}

static int au0828_enable_analog_tuner(struct au0828_dev *dev)
{
#ifdef CONFIG_MEDIA_CONTROLLER
	struct media_device *mdev = dev->media_dev;
	struct media_entity *source;
	struct media_link *link, *found_link = NULL;
	int ret, active_links = 0;

	if (!mdev || !dev->decoder)
		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.
	 */
	list_for_each_entry(link, &dev->decoder->links, list) {
		if (link->sink->entity == dev->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;
	list_for_each_entry(link, &source->links, list) {
		struct media_entity *sink;
		int flags = 0;

		sink = link->sink->entity;

		if (sink == dev->decoder)
			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[])
@@ -865,9 +807,6 @@ static int queue_setup(struct vb2_queue *vq,
		return sizes[0] < size ? -EINVAL : 0;
	*nplanes = 1;
	sizes[0] = size;

	au0828_enable_analog_tuner(dev);

	return 0;
}

@@ -1235,8 +1174,39 @@ static int au0828_v4l2_close(struct file *filp)
		goto end;

	if (dev->users == 1) {
		/* Save some power by putting tuner to sleep */
		v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_power, 0);
		/*
		 * Avoid putting tuner in sleep if DVB or ALSA are
		 * streaming.
		 *
		 * On most USB devices  like au0828 the tuner can
		 * be safely put in sleep stare here if ALSA isn't
		 * streaming. Exceptions are some very old USB tuner
		 * models such as em28xx-based WinTV USB2 which have
		 * a separate audio output jack. The devices that have
		 * a separate audio output jack have analog tuners,
		 * like Philips FM1236. Those devices are always on,
		 * so the s_power callback are silently ignored.
		 * So, the current logic here does the following:
		 * Disable (put tuner to sleep) when
		 * - ALSA and DVB aren't not streaming;
		 * - the last V4L2 file handler is closed.
		 *
		 * FIXME:
		 *
		 * Additionally, this logic could be improved to
		 * disable the media source if the above conditions
		 * are met and if the device:
		 * - doesn't have a separate audio out plug (or
		 * - doesn't use a silicon tuner like xc2028/3028/4000/5000).
		 *
		 * Once this additional logic is in place, a callback
		 * is needed to enable the media source and power on
		 * the tuner, for radio to work.
		*/
		ret = v4l_enable_media_source(vdev);
		if (ret == 0)
			v4l2_device_call_all(&dev->v4l2_dev, 0, core,
					     s_power, 0);
		dev->std_set_in_tuner_core = 0;

		/* When close the device, set the usb intf0 into alt0 to free
@@ -1636,10 +1606,16 @@ static int vidioc_s_audio(struct file *file, void *priv, const struct v4l2_audio
static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
{
	struct au0828_dev *dev = video_drvdata(file);
	struct video_device *vfd = video_devdata(file);
	int ret;

	if (t->index != 0)
		return -EINVAL;

	ret = v4l_enable_media_source(vfd);
	if (ret)
		return ret;

	dprintk(1, "%s called std_set %d dev_state %d\n", __func__,
		dev->std_set_in_tuner_core, dev->dev_state);