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

Commit 31554ae5 authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab
Browse files

V4L/DVB (7931): cx18: allow for simultaneous digital and analog capture



The HVR-1600 can do both analog and digital capture at the same time.
Due to a driver bug -EBUSY would be returned when attempting to setup an
analog capture while a digital capture was already in progress.

Separate the two internally.

Signed-off-by: default avatarHans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@infradead.org>
parent be303e16
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -159,7 +159,7 @@ static int cx18_setup_vbi_fmt(struct cx18 *cx, enum v4l2_mpeg_stream_vbi_fmt fmt
{
	if (!(cx->v4l2_cap & V4L2_CAP_SLICED_VBI_CAPTURE))
		return -EINVAL;
	if (atomic_read(&cx->capturing) > 0)
	if (atomic_read(&cx->ana_capturing) > 0)
		return -EBUSY;

	/* First try to allocate sliced VBI buffers if needed. */
@@ -235,7 +235,7 @@ int cx18_control_ioctls(struct cx18 *cx, unsigned int cmd, void *arg)
		CX18_DEBUG_IOCTL("VIDIOC_S_EXT_CTRLS\n");
		if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
			struct cx2341x_mpeg_params p = cx->params;
			int err = cx2341x_ext_ctrls(&p, atomic_read(&cx->capturing), arg, cmd);
			int err = cx2341x_ext_ctrls(&p, atomic_read(&cx->ana_capturing), arg, cmd);

			if (err)
				return err;
@@ -295,7 +295,7 @@ int cx18_control_ioctls(struct cx18 *cx, unsigned int cmd, void *arg)
		CX18_DEBUG_IOCTL("VIDIOC_TRY_EXT_CTRLS\n");
		if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG)
			return cx2341x_ext_ctrls(&cx->params,
					atomic_read(&cx->capturing), arg, cmd);
					atomic_read(&cx->ana_capturing), arg, cmd);
		return -EINVAL;
	}

+1 −1
Original line number Diff line number Diff line
@@ -889,7 +889,7 @@ static void cx18_remove(struct pci_dev *pci_dev)

	/* Stop all captures */
	CX18_DEBUG_INFO("Stopping all streams\n");
	if (atomic_read(&cx->capturing) > 0)
	if (atomic_read(&cx->tot_capturing) > 0)
		cx18_stop_all_captures(cx);

	/* Interrupts */
+2 −1
Original line number Diff line number Diff line
@@ -380,7 +380,8 @@ struct cx18 {
	int stream_buf_size[CX18_MAX_STREAMS]; /* Stream buffer size */
	struct cx18_stream streams[CX18_MAX_STREAMS]; 	/* Stream data */
	unsigned long i_flags;  /* global cx18 flags */
	atomic_t capturing;	/* count number of active capture streams */
	atomic_t ana_capturing;	/* count number of active analog capture streams */
	atomic_t tot_capturing;	/* total count number of active capture streams */
	spinlock_t lock;        /* lock access to this struct */
	int search_pack_header;

+5 −5
Original line number Diff line number Diff line
@@ -318,7 +318,7 @@ static ssize_t cx18_read(struct cx18_stream *s, char __user *ubuf,
	size_t tot_written = 0;
	int single_frame = 0;

	if (atomic_read(&cx->capturing) == 0 && s->id == -1) {
	if (atomic_read(&cx->ana_capturing) == 0 && s->id == -1) {
		/* shouldn't happen */
		CX18_DEBUG_WARN("Stream %s not initialized before read\n",
				s->name);
@@ -581,7 +581,7 @@ int cx18_v4l2_close(struct inode *inode, struct file *filp)
		cx18_call_i2c_clients(cx, VIDIOC_S_STD, &cx->std);
		/* Select correct audio input (i.e. TV tuner or Line in) */
		cx18_audio_set_io(cx);
		if (atomic_read(&cx->capturing) > 0) {
		if (atomic_read(&cx->ana_capturing) > 0) {
			/* Undo video mute */
			cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2, s->handle,
				cx->params.video_mute |
@@ -627,7 +627,7 @@ static int cx18_serialized_open(struct cx18_stream *s, struct file *filp)
		}

		if (!test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) {
			if (atomic_read(&cx->capturing) > 0) {
			if (atomic_read(&cx->ana_capturing) > 0) {
				/* switching to radio while capture is
				   in progress is not polite */
				cx18_release_stream(s);
@@ -694,7 +694,7 @@ int cx18_v4l2_open(struct inode *inode, struct file *filp)

void cx18_mute(struct cx18 *cx)
{
	if (atomic_read(&cx->capturing))
	if (atomic_read(&cx->ana_capturing))
		cx18_vapi(cx, CX18_CPU_SET_AUDIO_MUTE, 2,
				cx18_find_handle(cx), 1);
	CX18_DEBUG_INFO("Mute\n");
@@ -702,7 +702,7 @@ void cx18_mute(struct cx18 *cx)

void cx18_unmute(struct cx18 *cx)
{
	if (atomic_read(&cx->capturing)) {
	if (atomic_read(&cx->ana_capturing)) {
		cx18_msleep_timeout(100, 0);
		cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 2,
				cx18_find_handle(cx), 12);
+6 −6
Original line number Diff line number Diff line
@@ -247,7 +247,7 @@ static int cx18_try_or_set_fmt(struct cx18 *cx, int streamtype,

		if (!set_fmt || (cx->params.width == w && cx->params.height == h))
			return 0;
		if (atomic_read(&cx->capturing) > 0)
		if (atomic_read(&cx->ana_capturing) > 0)
			return -EBUSY;

		cx->params.width = w;
@@ -264,7 +264,7 @@ static int cx18_try_or_set_fmt(struct cx18 *cx, int streamtype,
	if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
		if (set_fmt && streamtype == CX18_ENC_STREAM_TYPE_VBI &&
		    cx->vbi.sliced_in->service_set &&
		    atomic_read(&cx->capturing) > 0)
		    atomic_read(&cx->ana_capturing) > 0)
			return -EBUSY;
		if (set_fmt) {
			cx->vbi.sliced_in->service_set = 0;
@@ -293,7 +293,7 @@ static int cx18_try_or_set_fmt(struct cx18 *cx, int streamtype,
		return 0;
	if (set == 0)
		return -EINVAL;
	if (atomic_read(&cx->capturing) > 0 && cx->vbi.sliced_in->service_set == 0)
	if (atomic_read(&cx->ana_capturing) > 0 && cx->vbi.sliced_in->service_set == 0)
		return -EBUSY;
	cx18_av_cmd(cx, VIDIOC_S_FMT, fmt);
	memcpy(cx->vbi.sliced_in, vbifmt, sizeof(*cx->vbi.sliced_in));
@@ -581,7 +581,7 @@ int cx18_v4l2_ioctls(struct cx18 *cx, struct file *filp, unsigned cmd, void *arg
			break;

		if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) ||
		    atomic_read(&cx->capturing) > 0) {
		    atomic_read(&cx->ana_capturing) > 0) {
			/* Switching standard would turn off the radio or mess
			   with already running streams, prevent that by
			   returning EBUSY. */
@@ -677,7 +677,7 @@ int cx18_v4l2_ioctls(struct cx18 *cx, struct file *filp, unsigned cmd, void *arg
			enc->flags = 0;
			if (try)
				return 0;
			if (!atomic_read(&cx->capturing))
			if (!atomic_read(&cx->ana_capturing))
				return -EPERM;
			if (test_and_set_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags))
				return 0;
@@ -689,7 +689,7 @@ int cx18_v4l2_ioctls(struct cx18 *cx, struct file *filp, unsigned cmd, void *arg
			enc->flags = 0;
			if (try)
				return 0;
			if (!atomic_read(&cx->capturing))
			if (!atomic_read(&cx->ana_capturing))
				return -EPERM;
			if (!test_and_clear_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags))
				return 0;
Loading