/*
 *  cx18 file operation functions
 *
 *  Derived from ivtv-fileops.c
 *
 *  Copyright (C) 2007  Hans Verkuil <hverkuil@xs4all.nl>
 *  Copyright (C) 2008  Andy Walls <awalls@md.metrocast.net>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
 *  02111-1307  USA
 */

#include "cx18-driver.h"
#include "cx18-fileops.h"
#include "cx18-i2c.h"
#include "cx18-queue.h"
#include "cx18-vbi.h"
#include "cx18-audio.h"
#include "cx18-mailbox.h"
#include "cx18-scb.h"
#include "cx18-streams.h"
#include "cx18-controls.h"
#include "cx18-ioctl.h"
#include "cx18-cards.h"

/* This function tries to claim the stream for a specific file descriptor.
   If no one else is using this stream then the stream is claimed and
   associated VBI and IDX streams are also automatically claimed.
   Possible error returns: -EBUSY if someone else has claimed
   the stream or 0 on success. */
int cx18_claim_stream(struct cx18_open_id *id, int type)
{
	struct cx18 *cx = id->cx;
	struct cx18_stream *s = &cx->streams[type];
	struct cx18_stream *s_assoc;

	/* Nothing should ever try to directly claim the IDX stream */
	if (type == CX18_ENC_STREAM_TYPE_IDX) {
		CX18_WARN("MPEG Index stream cannot be claimed "
			  "directly, but something tried.\n");
		return -EINVAL;
	}

	if (test_and_set_bit(CX18_F_S_CLAIMED, &s->s_flags)) {
		/* someone already claimed this stream */
		if (s->id == id->open_id) {
			/* yes, this file descriptor did. So that's OK. */
			return 0;
		}
		if (s->id == -1 && type == CX18_ENC_STREAM_TYPE_VBI) {
			/* VBI is handled already internally, now also assign
			   the file descriptor to this stream for external
			   reading of the stream. */
			s->id = id->open_id;
			CX18_DEBUG_INFO("Start Read VBI\n");
			return 0;
		}
		/* someone else is using this stream already */
		CX18_DEBUG_INFO("Stream %d is busy\n", type);
		return -EBUSY;
	}
	s->id = id->open_id;

	/*
	 * CX18_ENC_STREAM_TYPE_MPG needs to claim:
	 * CX18_ENC_STREAM_TYPE_VBI, if VBI insertion is on for sliced VBI, or
	 * CX18_ENC_STREAM_TYPE_IDX, if VBI insertion is off for sliced VBI
	 * (We don't yet fix up MPEG Index entries for our inserted packets).
	 *
	 * For all other streams we're done.
	 */
	if (type != CX18_ENC_STREAM_TYPE_MPG)
		return 0;

	s_assoc = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
	if (cx->vbi.insert_mpeg && !cx18_raw_vbi(cx))
		s_assoc = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
	else if (!cx18_stream_enabled(s_assoc))
		return 0;

	set_bit(CX18_F_S_CLAIMED, &s_assoc->s_flags);

	/* mark that it is used internally */
	set_bit(CX18_F_S_INTERNAL_USE, &s_assoc->s_flags);
	return 0;
}
EXPORT_SYMBOL(cx18_claim_stream);

/* This function releases a previously claimed stream. It will take into
   account associated VBI streams. */
void cx18_release_stream(struct cx18_stream *s)
{
	struct cx18 *cx = s->cx;
	struct cx18_stream *s_assoc;

	s->id = -1;
	if (s->type == CX18_ENC_STREAM_TYPE_IDX) {
		/*
		 * The IDX stream is only used internally, and can
		 * only be indirectly unclaimed by unclaiming the MPG stream.
		 */
		return;
	}

	if (s->type == CX18_ENC_STREAM_TYPE_VBI &&
		test_bit(CX18_F_S_INTERNAL_USE, &s->s_flags)) {
		/* this stream is still in use internally */
		return;
	}
	if (!test_and_clear_bit(CX18_F_S_CLAIMED, &s->s_flags)) {
		CX18_DEBUG_WARN("Release stream %s not in use!\n", s->name);
		return;
	}

	cx18_flush_queues(s);

	/*
	 * CX18_ENC_STREAM_TYPE_MPG needs to release the
	 * CX18_ENC_STREAM_TYPE_VBI and/or CX18_ENC_STREAM_TYPE_IDX streams.
	 *
	 * For all other streams we're done.
	 */
	if (s->type != CX18_ENC_STREAM_TYPE_MPG)
		return;

	/* Unclaim the associated MPEG Index stream */
	s_assoc = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
	if (test_and_clear_bit(CX18_F_S_INTERNAL_USE, &s_assoc->s_flags)) {
		clear_bit(CX18_F_S_CLAIMED, &s_assoc->s_flags);
		cx18_flush_queues(s_assoc);
	}

	/* Unclaim the associated VBI stream */
	s_assoc = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
	if (test_and_clear_bit(CX18_F_S_INTERNAL_USE, &s_assoc->s_flags)) {
		if (s_assoc->id == -1) {
			/*
			 * The VBI stream is not still claimed by a file
			 * descriptor, so completely unclaim it.
			 */
			clear_bit(CX18_F_S_CLAIMED, &s_assoc->s_flags);
			cx18_flush_queues(s_assoc);
		}
	}
}
EXPORT_SYMBOL(cx18_release_stream);

static void cx18_dualwatch(struct cx18 *cx)
{
	struct v4l2_tuner vt;
	u32 new_stereo_mode;
	const u32 dual = 0x0200;

	new_stereo_mode = v4l2_ctrl_g_ctrl(cx->cxhdl.audio_mode);
	memset(&vt, 0, sizeof(vt));
	cx18_call_all(cx, tuner, g_tuner, &vt);
	if (vt.audmode == V4L2_TUNER_MODE_LANG1_LANG2 &&
			(vt.rxsubchans & V4L2_TUNER_SUB_LANG2))
		new_stereo_mode = dual;

	if (new_stereo_mode == cx->dualwatch_stereo_mode)
		return;

	CX18_DEBUG_INFO("dualwatch: change stereo flag from 0x%x to 0x%x.\n",
			   cx->dualwatch_stereo_mode, new_stereo_mode);
	if (v4l2_ctrl_s_ctrl(cx->cxhdl.audio_mode, new_stereo_mode))
		CX18_DEBUG_INFO("dualwatch: changing stereo flag failed\n");
}


static struct cx18_mdl *cx18_get_mdl(struct cx18_stream *s, int non_block,
				     int *err)
{
	struct cx18 *cx = s->cx;
	struct cx18_stream *s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
	struct cx18_mdl *mdl;
	DEFINE_WAIT(wait);

	*err = 0;
	while (1) {
		if (s->type == CX18_ENC_STREAM_TYPE_MPG) {
			/* Process pending program updates and VBI data */
			if (time_after(jiffies, cx->dualwatch_jiffies + msecs_to_jiffies(1000))) {
				cx->dualwatch_jiffies = jiffies;
				cx18_dualwatch(cx);
			}
			if (test_bit(CX18_F_S_INTERNAL_USE, &s_vbi->s_flags) &&
			    !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) {
				while ((mdl = cx18_dequeue(s_vbi,
							   &s_vbi->q_full))) {
					/* byteswap and process VBI data */
					cx18_process_vbi_data(cx, mdl,
							      s_vbi->type);
					cx18_stream_put_mdl_fw(s_vbi, mdl);
				}
			}
			mdl = &cx->vbi.sliced_mpeg_mdl;
			if (mdl->readpos != mdl->bytesused)
				return mdl;
		}

		/* do we have new data? */
		mdl = cx18_dequeue(s, &s->q_full);
		if (mdl) {
			if (!test_and_clear_bit(CX18_F_M_NEED_SWAP,
						&mdl->m_flags))
				return mdl;
			if (s->type == CX18_ENC_STREAM_TYPE_MPG)
				/* byteswap MPG data */
				cx18_mdl_swap(mdl);
			else {
				/* byteswap and process VBI data */
				cx18_process_vbi_data(cx, mdl, s->type);
			}
			return mdl;
		}

		/* return if end of stream */
		if (!test_bit(CX18_F_S_STREAMING, &s->s_flags)) {
			CX18_DEBUG_INFO("EOS %s\n", s->name);
			return NULL;
		}

		/* return if file was opened with O_NONBLOCK */
		if (non_block) {
			*err = -EAGAIN;
			return NULL;
		}

		/* wait for more data to arrive */
		prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE);
		/* New buffers might have become available before we were added
		   to the waitqueue */
		if (!atomic_read(&s->q_full.depth))
			schedule();
		finish_wait(&s->waitq, &wait);
		if (signal_pending(current)) {
			/* return if a signal was received */
			CX18_DEBUG_INFO("User stopped %s\n", s->name);
			*err = -EINTR;
			return NULL;
		}
	}
}

static void cx18_setup_sliced_vbi_mdl(struct cx18 *cx)
{
	struct cx18_mdl *mdl = &cx->vbi.sliced_mpeg_mdl;
	struct cx18_buffer *buf = &cx->vbi.sliced_mpeg_buf;
	int idx = cx->vbi.inserted_frame % CX18_VBI_FRAMES;

	buf->buf = cx->vbi.sliced_mpeg_data[idx];
	buf->bytesused = cx->vbi.sliced_mpeg_size[idx];
	buf->readpos = 0;

	mdl->curr_buf = NULL;
	mdl->bytesused = cx->vbi.sliced_mpeg_size[idx];
	mdl->readpos = 0;
}

static size_t cx18_copy_buf_to_user(struct cx18_stream *s,
	struct cx18_buffer *buf, char __user *ubuf, size_t ucount, bool *stop)
{
	struct cx18 *cx = s->cx;
	size_t len = buf->bytesused - buf->readpos;

	*stop = false;
	if (len > ucount)
		len = ucount;
	if (cx->vbi.insert_mpeg && s->type == CX18_ENC_STREAM_TYPE_MPG &&
	    !cx18_raw_vbi(cx) && buf != &cx->vbi.sliced_mpeg_buf) {
		/*
		 * Try to find a good splice point in the PS, just before
		 * an MPEG-2 Program Pack start code, and provide only
		 * up to that point to the user, so it's easy to insert VBI data
		 * the next time around.
		 *
		 * This will not work for an MPEG-2 TS and has only been
		 * verified by analysis to work for an MPEG-2 PS.  Helen Buus
		 * pointed out this works for the CX23416 MPEG-2 DVD compatible
		 * stream, and research indicates both the MPEG 2 SVCD and DVD
		 * stream types use an MPEG-2 PS container.
		 */
		/*
		 * An MPEG-2 Program Stream (PS) is a series of
		 * MPEG-2 Program Packs terminated by an
		 * MPEG Program End Code after the last Program Pack.
		 * A Program Pack may hold a PS System Header packet and any
		 * number of Program Elementary Stream (PES) Packets
		 */
		const char *start = buf->buf + buf->readpos;
		const char *p = start + 1;
		const u8 *q;
		u8 ch = cx->search_pack_header ? 0xba : 0xe0;
		int stuffing, i;

		while (start + len > p) {
			/* Scan for a 0 to find a potential MPEG-2 start code */
			q = memchr(p, 0, start + len - p);
			if (q == NULL)
				break;
			p = q + 1;
			/*
			 * Keep looking if not a
			 * MPEG-2 Pack header start code:  0x00 0x00 0x01 0xba
			 * or MPEG-2 video PES start code: 0x00 0x00 0x01 0xe0
			 */
			if ((char *)q + 15 >= buf->buf + buf->bytesused ||
			    q[1] != 0 || q[2] != 1 || q[3] != ch)
				continue;

			/* If expecting the primary video PES */
			if (!cx->search_pack_header) {
				/* Continue if it couldn't be a PES packet */
				if ((q[6] & 0xc0) != 0x80)
					continue;
				/* Check if a PTS or PTS & DTS follow */
				if (((q[7] & 0xc0) == 0x80 &&  /* PTS only */
				     (q[9] & 0xf0) == 0x20) || /* PTS only */
				    ((q[7] & 0xc0) == 0xc0 &&  /* PTS & DTS */
				     (q[9] & 0xf0) == 0x30)) { /* DTS follows */
					/* Assume we found the video PES hdr */
					ch = 0xba; /* next want a Program Pack*/
					cx->search_pack_header = 1;
					p = q + 9; /* Skip this video PES hdr */
				}
				continue;
			}

			/* We may have found a Program Pack start code */

			/* Get the count of stuffing bytes & verify them */
			stuffing = q[13] & 7;
			/* all stuffing bytes must be 0xff */
			for (i = 0; i < stuffing; i++)
				if (q[14 + i] != 0xff)
					break;
			if (i == stuffing && /* right number of stuffing bytes*/
			    (q[4] & 0xc4) == 0x44 && /* marker check */
			    (q[12] & 3) == 3 &&  /* marker check */
			    q[14 + stuffing] == 0 && /* PES Pack or Sys Hdr */
			    q[15 + stuffing] == 0 &&
			    q[16 + stuffing] == 1) {
				/* We declare we actually found a Program Pack*/
				cx->search_pack_header = 0; /* expect vid PES */
				len = (char *)q - start;
				cx18_setup_sliced_vbi_mdl(cx);
				*stop = true;
				break;
			}
		}
	}
	if (copy_to_user(ubuf, (u8 *)buf->buf + buf->readpos, len)) {
		CX18_DEBUG_WARN("copy %zd bytes to user failed for %s\n",
				len, s->name);
		return -EFAULT;
	}
	buf->readpos += len;
	if (s->type == CX18_ENC_STREAM_TYPE_MPG &&
	    buf != &cx->vbi.sliced_mpeg_buf)
		cx->mpg_data_received += len;
	return len;
}

static size_t cx18_copy_mdl_to_user(struct cx18_stream *s,
		struct cx18_mdl *mdl, char __user *ubuf, size_t ucount)
{
	size_t tot_written = 0;
	int rc;
	bool stop = false;

	if (mdl->curr_buf == NULL)
		mdl->curr_buf = list_first_entry(&mdl->buf_list,
						 struct cx18_buffer, list);

	if (list_entry_is_past_end(mdl->curr_buf, &mdl->buf_list, list)) {
		/*
		 * For some reason we've exhausted the buffers, but the MDL
		 * object still said some data was unread.
		 * Fix that and bail out.
		 */
		mdl->readpos = mdl->bytesused;
		return 0;
	}

	list_for_each_entry_from(mdl->curr_buf, &mdl->buf_list, list) {

		if (mdl->curr_buf->readpos >= mdl->curr_buf->bytesused)
			continue;

		rc = cx18_copy_buf_to_user(s, mdl->curr_buf, ubuf + tot_written,
					   ucount - tot_written, &stop);
		if (rc < 0)
			return rc;
		mdl->readpos += rc;
		tot_written += rc;

		if (stop ||	/* Forced stopping point for VBI insertion */
		    tot_written >= ucount ||	/* Reader request statisfied */
		    mdl->curr_buf->readpos < mdl->curr_buf->bytesused ||
		    mdl->readpos >= mdl->bytesused) /* MDL buffers drained */
			break;
	}
	return tot_written;
}

static ssize_t cx18_read(struct cx18_stream *s, char __user *ubuf,
		size_t tot_count, int non_block)
{
	struct cx18 *cx = s->cx;
	size_t tot_written = 0;
	int single_frame = 0;

	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);
		return -EIO;
	}

	/* Each VBI buffer is one frame, the v4l2 API says that for VBI the
	   frames should arrive one-by-one, so make sure we never output more
	   than one VBI frame at a time */
	if (s->type == CX18_ENC_STREAM_TYPE_VBI && !cx18_raw_vbi(cx))
		single_frame = 1;

	for (;;) {
		struct cx18_mdl *mdl;
		int rc;

		mdl = cx18_get_mdl(s, non_block, &rc);
		/* if there is no data available... */
		if (mdl == NULL) {
			/* if we got data, then return that regardless */
			if (tot_written)
				break;
			/* EOS condition */
			if (rc == 0) {
				clear_bit(CX18_F_S_STREAMOFF, &s->s_flags);
				clear_bit(CX18_F_S_APPL_IO, &s->s_flags);
				cx18_release_stream(s);
			}
			/* set errno */
			return rc;
		}

		rc = cx18_copy_mdl_to_user(s, mdl, ubuf + tot_written,
				tot_count - tot_written);

		if (mdl != &cx->vbi.sliced_mpeg_mdl) {
			if (mdl->readpos == mdl->bytesused)
				cx18_stream_put_mdl_fw(s, mdl);
			else
				cx18_push(s, mdl, &s->q_full);
		} else if (mdl->readpos == mdl->bytesused) {
			int idx = cx->vbi.inserted_frame % CX18_VBI_FRAMES;

			cx->vbi.sliced_mpeg_size[idx] = 0;
			cx->vbi.inserted_frame++;
			cx->vbi_data_inserted += mdl->bytesused;
		}
		if (rc < 0)
			return rc;
		tot_written += rc;

		if (tot_written == tot_count || single_frame)
			break;
	}
	return tot_written;
}

static ssize_t cx18_read_pos(struct cx18_stream *s, char __user *ubuf,
		size_t count, loff_t *pos, int non_block)
{
	ssize_t rc = count ? cx18_read(s, ubuf, count, non_block) : 0;
	struct cx18 *cx = s->cx;

	CX18_DEBUG_HI_FILE("read %zd from %s, got %zd\n", count, s->name, rc);
	if (rc > 0)
		pos += rc;
	return rc;
}

int cx18_start_capture(struct cx18_open_id *id)
{
	struct cx18 *cx = id->cx;
	struct cx18_stream *s = &cx->streams[id->type];
	struct cx18_stream *s_vbi;
	struct cx18_stream *s_idx;

	if (s->type == CX18_ENC_STREAM_TYPE_RAD) {
		/* you cannot read from these stream types. */
		return -EPERM;
	}

	/* Try to claim this stream. */
	if (cx18_claim_stream(id, s->type))
		return -EBUSY;

	/* If capture is already in progress, then we also have to
	   do nothing extra. */
	if (test_bit(CX18_F_S_STREAMOFF, &s->s_flags) ||
	    test_and_set_bit(CX18_F_S_STREAMING, &s->s_flags)) {
		set_bit(CX18_F_S_APPL_IO, &s->s_flags);
		return 0;
	}

	/* Start associated VBI or IDX stream capture if required */
	s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
	s_idx = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
	if (s->type == CX18_ENC_STREAM_TYPE_MPG) {
		/*
		 * The VBI and IDX streams should have been claimed
		 * automatically, if for internal use, when the MPG stream was
		 * claimed.  We only need to start these streams capturing.
		 */
		if (test_bit(CX18_F_S_INTERNAL_USE, &s_idx->s_flags) &&
		    !test_and_set_bit(CX18_F_S_STREAMING, &s_idx->s_flags)) {
			if (cx18_start_v4l2_encode_stream(s_idx)) {
				CX18_DEBUG_WARN("IDX capture start failed\n");
				clear_bit(CX18_F_S_STREAMING, &s_idx->s_flags);
				goto start_failed;
			}
			CX18_DEBUG_INFO("IDX capture started\n");
		}
		if (test_bit(CX18_F_S_INTERNAL_USE, &s_vbi->s_flags) &&
		    !test_and_set_bit(CX18_F_S_STREAMING, &s_vbi->s_flags)) {
			if (cx18_start_v4l2_encode_stream(s_vbi)) {
				CX18_DEBUG_WARN("VBI capture start failed\n");
				clear_bit(CX18_F_S_STREAMING, &s_vbi->s_flags);
				goto start_failed;
			}
			CX18_DEBUG_INFO("VBI insertion started\n");
		}
	}

	/* Tell the card to start capturing */
	if (!cx18_start_v4l2_encode_stream(s)) {
		/* We're done */
		set_bit(CX18_F_S_APPL_IO, &s->s_flags);
		/* Resume a possibly paused encoder */
		if (test_and_clear_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags))
			cx18_vapi(cx, CX18_CPU_CAPTURE_PAUSE, 1, s->handle);
		return 0;
	}

start_failed:
	CX18_DEBUG_WARN("Failed to start capturing for stream %s\n", s->name);

	/*
	 * The associated VBI and IDX streams for internal use are released
	 * automatically when the MPG stream is released.  We only need to stop
	 * the associated stream.
	 */
	if (s->type == CX18_ENC_STREAM_TYPE_MPG) {
		/* Stop the IDX stream which is always for internal use */
		if (test_bit(CX18_F_S_STREAMING, &s_idx->s_flags)) {
			cx18_stop_v4l2_encode_stream(s_idx, 0);
			clear_bit(CX18_F_S_STREAMING, &s_idx->s_flags);
		}
		/* Stop the VBI stream, if only running for internal use */
		if (test_bit(CX18_F_S_STREAMING, &s_vbi->s_flags) &&
		    !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) {
			cx18_stop_v4l2_encode_stream(s_vbi, 0);
			clear_bit(CX18_F_S_STREAMING, &s_vbi->s_flags);
		}
	}
	clear_bit(CX18_F_S_STREAMING, &s->s_flags);
	cx18_release_stream(s); /* Also releases associated streams */
	return -EIO;
}

ssize_t cx18_v4l2_read(struct file *filp, char __user *buf, size_t count,
		loff_t *pos)
{
	struct cx18_open_id *id = file2id(filp);
	struct cx18 *cx = id->cx;
	struct cx18_stream *s = &cx->streams[id->type];
	int rc;

	CX18_DEBUG_HI_FILE("read %zd bytes from %s\n", count, s->name);

	mutex_lock(&cx->serialize_lock);
	rc = cx18_start_capture(id);
	mutex_unlock(&cx->serialize_lock);
	if (rc)
		return rc;

	if ((s->vb_type == V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
		(id->type == CX18_ENC_STREAM_TYPE_YUV)) {
		return videobuf_read_stream(&s->vbuf_q, buf, count, pos, 0,
			filp->f_flags & O_NONBLOCK);
	}

	return cx18_read_pos(s, buf, count, pos, filp->f_flags & O_NONBLOCK);
}

unsigned int cx18_v4l2_enc_poll(struct file *filp, poll_table *wait)
{
	struct cx18_open_id *id = file2id(filp);
	struct cx18 *cx = id->cx;
	struct cx18_stream *s = &cx->streams[id->type];
	int eof = test_bit(CX18_F_S_STREAMOFF, &s->s_flags);

	/* Start a capture if there is none */
	if (!eof && !test_bit(CX18_F_S_STREAMING, &s->s_flags)) {
		int rc;

		mutex_lock(&cx->serialize_lock);
		rc = cx18_start_capture(id);
		mutex_unlock(&cx->serialize_lock);
		if (rc) {
			CX18_DEBUG_INFO("Could not start capture for %s (%d)\n",
					s->name, rc);
			return POLLERR;
		}
		CX18_DEBUG_FILE("Encoder poll started capture\n");
	}

	if ((s->vb_type == V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
		(id->type == CX18_ENC_STREAM_TYPE_YUV)) {
		int videobuf_poll = videobuf_poll_stream(filp, &s->vbuf_q, wait);
                if (eof && videobuf_poll == POLLERR)
                        return POLLHUP;
                else
                        return videobuf_poll;
	}

	/* add stream's waitq to the poll list */
	CX18_DEBUG_HI_FILE("Encoder poll\n");
	poll_wait(filp, &s->waitq, wait);

	if (atomic_read(&s->q_full.depth))
		return POLLIN | POLLRDNORM;
	if (eof)
		return POLLHUP;
	return 0;
}

int cx18_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
{
	struct cx18_open_id *id = file->private_data;
	struct cx18 *cx = id->cx;
	struct cx18_stream *s = &cx->streams[id->type];
	int eof = test_bit(CX18_F_S_STREAMOFF, &s->s_flags);

	if ((s->vb_type == V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
		(id->type == CX18_ENC_STREAM_TYPE_YUV)) {

		/* Start a capture if there is none */
		if (!eof && !test_bit(CX18_F_S_STREAMING, &s->s_flags)) {
			int rc;

			mutex_lock(&cx->serialize_lock);
			rc = cx18_start_capture(id);
			mutex_unlock(&cx->serialize_lock);
			if (rc) {
				CX18_DEBUG_INFO(
					"Could not start capture for %s (%d)\n",
					s->name, rc);
				return -EINVAL;
			}
			CX18_DEBUG_FILE("Encoder mmap started capture\n");
		}

		return videobuf_mmap_mapper(&s->vbuf_q, vma);
	}

	return -EINVAL;
}

void cx18_vb_timeout(unsigned long data)
{
	struct cx18_stream *s = (struct cx18_stream *)data;
	struct cx18_videobuf_buffer *buf;
	unsigned long flags;

	/* Return all of the buffers in error state, so the vbi/vid inode
	 * can return from blocking.
	 */
	spin_lock_irqsave(&s->vb_lock, flags);
	while (!list_empty(&s->vb_capture)) {
		buf = list_entry(s->vb_capture.next,
			struct cx18_videobuf_buffer, vb.queue);
		list_del(&buf->vb.queue);
		buf->vb.state = VIDEOBUF_ERROR;
		wake_up(&buf->vb.done);
	}
	spin_unlock_irqrestore(&s->vb_lock, flags);
}

void cx18_stop_capture(struct cx18_open_id *id, int gop_end)
{
	struct cx18 *cx = id->cx;
	struct cx18_stream *s = &cx->streams[id->type];
	struct cx18_stream *s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
	struct cx18_stream *s_idx = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];

	CX18_DEBUG_IOCTL("close() of %s\n", s->name);

	/* 'Unclaim' this stream */

	/* Stop capturing */
	if (test_bit(CX18_F_S_STREAMING, &s->s_flags)) {
		CX18_DEBUG_INFO("close stopping capture\n");
		if (id->type == CX18_ENC_STREAM_TYPE_MPG) {
			/* Stop internal use associated VBI and IDX streams */
			if (test_bit(CX18_F_S_STREAMING, &s_vbi->s_flags) &&
			    !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) {
				CX18_DEBUG_INFO("close stopping embedded VBI "
						"capture\n");
				cx18_stop_v4l2_encode_stream(s_vbi, 0);
			}
			if (test_bit(CX18_F_S_STREAMING, &s_idx->s_flags)) {
				CX18_DEBUG_INFO("close stopping IDX capture\n");
				cx18_stop_v4l2_encode_stream(s_idx, 0);
			}
		}
		if (id->type == CX18_ENC_STREAM_TYPE_VBI &&
		    test_bit(CX18_F_S_INTERNAL_USE, &s->s_flags))
			/* Also used internally, don't stop capturing */
			s->id = -1;
		else
			cx18_stop_v4l2_encode_stream(s, gop_end);
	}
	if (!gop_end) {
		clear_bit(CX18_F_S_APPL_IO, &s->s_flags);
		clear_bit(CX18_F_S_STREAMOFF, &s->s_flags);
		cx18_release_stream(s);
	}
}

int cx18_v4l2_close(struct file *filp)
{
	struct v4l2_fh *fh = filp->private_data;
	struct cx18_open_id *id = fh2id(fh);
	struct cx18 *cx = id->cx;
	struct cx18_stream *s = &cx->streams[id->type];

	CX18_DEBUG_IOCTL("close() of %s\n", s->name);

	mutex_lock(&cx->serialize_lock);
	/* Stop radio */
	if (id->type == CX18_ENC_STREAM_TYPE_RAD &&
			v4l2_fh_is_singular_file(filp)) {
		/* Closing radio device, return to TV mode */
		cx18_mute(cx);
		/* Mark that the radio is no longer in use */
		clear_bit(CX18_F_I_RADIO_USER, &cx->i_flags);
		/* Switch tuner to TV */
		cx18_call_all(cx, core, s_std, cx->std);
		/* Select correct audio input (i.e. TV tuner or Line in) */
		cx18_audio_set_io(cx);
		if (atomic_read(&cx->ana_capturing) > 0) {
			/* Undo video mute */
			cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2, s->handle,
			    (v4l2_ctrl_g_ctrl(cx->cxhdl.video_mute) |
			    (v4l2_ctrl_g_ctrl(cx->cxhdl.video_mute_yuv) << 8)));
		}
		/* Done! Unmute and continue. */
		cx18_unmute(cx);
	}

	v4l2_fh_del(fh);
	v4l2_fh_exit(fh);

	/* 'Unclaim' this stream */
	if (s->id == id->open_id)
		cx18_stop_capture(id, 0);
	kfree(id);
	mutex_unlock(&cx->serialize_lock);
	return 0;
}

static int cx18_serialized_open(struct cx18_stream *s, struct file *filp)
{
	struct cx18 *cx = s->cx;
	struct cx18_open_id *item;

	CX18_DEBUG_FILE("open %s\n", s->name);

	/* Allocate memory */
	item = kzalloc(sizeof(struct cx18_open_id), GFP_KERNEL);
	if (NULL == item) {
		CX18_DEBUG_WARN("nomem on v4l2 open\n");
		return -ENOMEM;
	}
	v4l2_fh_init(&item->fh, s->video_dev);

	item->cx = cx;
	item->type = s->type;

	item->open_id = cx->open_id++;
	filp->private_data = &item->fh;
	v4l2_fh_add(&item->fh);

	if (item->type == CX18_ENC_STREAM_TYPE_RAD &&
			v4l2_fh_is_singular_file(filp)) {
		if (!test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) {
			if (atomic_read(&cx->ana_capturing) > 0) {
				/* switching to radio while capture is
				   in progress is not polite */
				v4l2_fh_del(&item->fh);
				v4l2_fh_exit(&item->fh);
				kfree(item);
				return -EBUSY;
			}
		}

		/* Mark that the radio is being used. */
		set_bit(CX18_F_I_RADIO_USER, &cx->i_flags);
		/* We have the radio */
		cx18_mute(cx);
		/* Switch tuner to radio */
		cx18_call_all(cx, tuner, s_radio);
		/* Select the correct audio input (i.e. radio tuner) */
		cx18_audio_set_io(cx);
		/* Done! Unmute and continue. */
		cx18_unmute(cx);
	}
	return 0;
}

int cx18_v4l2_open(struct file *filp)
{
	int res;
	struct video_device *video_dev = video_devdata(filp);
	struct cx18_stream *s = video_get_drvdata(video_dev);
	struct cx18 *cx = s->cx;

	mutex_lock(&cx->serialize_lock);
	if (cx18_init_on_first_open(cx)) {
		CX18_ERR("Failed to initialize on %s\n",
			 video_device_node_name(video_dev));
		mutex_unlock(&cx->serialize_lock);
		return -ENXIO;
	}
	res = cx18_serialized_open(s, filp);
	mutex_unlock(&cx->serialize_lock);
	return res;
}

void cx18_mute(struct cx18 *cx)
{
	u32 h;
	if (atomic_read(&cx->ana_capturing)) {
		h = cx18_find_handle(cx);
		if (h != CX18_INVALID_TASK_HANDLE)
			cx18_vapi(cx, CX18_CPU_SET_AUDIO_MUTE, 2, h, 1);
		else
			CX18_ERR("Can't find valid task handle for mute\n");
	}
	CX18_DEBUG_INFO("Mute\n");
}

void cx18_unmute(struct cx18 *cx)
{
	u32 h;
	if (atomic_read(&cx->ana_capturing)) {
		h = cx18_find_handle(cx);
		if (h != CX18_INVALID_TASK_HANDLE) {
			cx18_msleep_timeout(100, 0);
			cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 2, h, 12);
			cx18_vapi(cx, CX18_CPU_SET_AUDIO_MUTE, 2, h, 0);
		} else
			CX18_ERR("Can't find valid task handle for unmute\n");
	}
	CX18_DEBUG_INFO("Unmute\n");
}
