11a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil/*
21a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil    file operation functions
31a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil    Copyright (C) 2003-2004  Kevin Thayer <nufan_wfk at yahoo.com>
41a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil    Copyright (C) 2004  Chris Kennedy <c@groovy.org>
51a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil    Copyright (C) 2005-2007  Hans Verkuil <hverkuil@xs4all.nl>
61a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
71a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil    This program is free software; you can redistribute it and/or modify
81a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil    it under the terms of the GNU General Public License as published by
91a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil    the Free Software Foundation; either version 2 of the License, or
101a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil    (at your option) any later version.
111a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
121a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil    This program is distributed in the hope that it will be useful,
131a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil    but WITHOUT ANY WARRANTY; without even the implied warranty of
141a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
151a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil    GNU General Public License for more details.
161a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
171a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil    You should have received a copy of the GNU General Public License
181a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil    along with this program; if not, write to the Free Software
191a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
201a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil */
211a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
221a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil#include "ivtv-driver.h"
231a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil#include "ivtv-fileops.h"
241a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil#include "ivtv-i2c.h"
251a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil#include "ivtv-queue.h"
261a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil#include "ivtv-udma.h"
271a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil#include "ivtv-irq.h"
281a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil#include "ivtv-vbi.h"
291a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil#include "ivtv-mailbox.h"
3033c0fcad2160bc211272295e862c6f708118d006Hans Verkuil#include "ivtv-routing.h"
311a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil#include "ivtv-streams.h"
321a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil#include "ivtv-yuv.h"
331a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil#include "ivtv-ioctl.h"
34f2100d82b858815848b661d57d7e166341c02e20Hans Verkuil#include "ivtv-cards.h"
35914610e8c508224a6fb9fb501ed4bda25b340ba6Ian Armstrong#include "ivtv-firmware.h"
36092501936fc128992456a086193746cf34642815Hans Verkuil#include <media/v4l2-event.h>
37f2100d82b858815848b661d57d7e166341c02e20Hans Verkuil#include <media/saa7115.h>
381a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
391a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil/* This function tries to claim the stream for a specific file descriptor.
401a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil   If no one else is using this stream then the stream is claimed and
411a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil   associated VBI streams are also automatically claimed.
421a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil   Possible error returns: -EBUSY if someone else has claimed
431a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil   the stream or 0 on success. */
4495f73c5b57990c97047c200b8746ab62a360c5bcAdrian Bunkstatic int ivtv_claim_stream(struct ivtv_open_id *id, int type)
451a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{
461a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	struct ivtv *itv = id->itv;
471a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	struct ivtv_stream *s = &itv->streams[type];
481a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	struct ivtv_stream *s_vbi;
491a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	int vbi_type;
501a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
511a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	if (test_and_set_bit(IVTV_F_S_CLAIMED, &s->s_flags)) {
521a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		/* someone already claimed this stream */
5361bb725ef5a646d3fc8a64e41b020a65542cdae1Hans Verkuil		if (s->fh == &id->fh) {
541a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			/* yes, this file descriptor did. So that's OK. */
551a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			return 0;
561a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		}
5761bb725ef5a646d3fc8a64e41b020a65542cdae1Hans Verkuil		if (s->fh == NULL && (type == IVTV_DEC_STREAM_TYPE_VBI ||
581a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil					 type == IVTV_ENC_STREAM_TYPE_VBI)) {
591a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			/* VBI is handled already internally, now also assign
601a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			   the file descriptor to this stream for external
611a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			   reading of the stream. */
6261bb725ef5a646d3fc8a64e41b020a65542cdae1Hans Verkuil			s->fh = &id->fh;
631a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			IVTV_DEBUG_INFO("Start Read VBI\n");
641a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			return 0;
651a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		}
661a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		/* someone else is using this stream already */
671a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		IVTV_DEBUG_INFO("Stream %d is busy\n", type);
681a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		return -EBUSY;
691a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	}
7061bb725ef5a646d3fc8a64e41b020a65542cdae1Hans Verkuil	s->fh = &id->fh;
711a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	if (type == IVTV_DEC_STREAM_TYPE_VBI) {
721a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		/* Enable reinsertion interrupt */
731a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		ivtv_clear_irq_mask(itv, IVTV_IRQ_DEC_VBI_RE_INSERT);
741a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	}
751a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
761a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	/* IVTV_DEC_STREAM_TYPE_MPG needs to claim IVTV_DEC_STREAM_TYPE_VBI,
771a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	   IVTV_ENC_STREAM_TYPE_MPG needs to claim IVTV_ENC_STREAM_TYPE_VBI
781a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	   (provided VBI insertion is on and sliced VBI is selected), for all
791a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	   other streams we're done */
801a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	if (type == IVTV_DEC_STREAM_TYPE_MPG) {
811a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		vbi_type = IVTV_DEC_STREAM_TYPE_VBI;
821a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	} else if (type == IVTV_ENC_STREAM_TYPE_MPG &&
83a8b864354e060dda1000e62d1fea7c1274581cafHans Verkuil		   itv->vbi.insert_mpeg && !ivtv_raw_vbi(itv)) {
841a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		vbi_type = IVTV_ENC_STREAM_TYPE_VBI;
851a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	} else {
861a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		return 0;
871a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	}
881a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	s_vbi = &itv->streams[vbi_type];
891a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
901a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	if (!test_and_set_bit(IVTV_F_S_CLAIMED, &s_vbi->s_flags)) {
911a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		/* Enable reinsertion interrupt */
921a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		if (vbi_type == IVTV_DEC_STREAM_TYPE_VBI)
931a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			ivtv_clear_irq_mask(itv, IVTV_IRQ_DEC_VBI_RE_INSERT);
941a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	}
951a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	/* mark that it is used internally */
961a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	set_bit(IVTV_F_S_INTERNAL_USE, &s_vbi->s_flags);
971a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	return 0;
981a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil}
991a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
1001a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil/* This function releases a previously claimed stream. It will take into
1011a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil   account associated VBI streams. */
1021a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilvoid ivtv_release_stream(struct ivtv_stream *s)
1031a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{
1041a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	struct ivtv *itv = s->itv;
1051a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	struct ivtv_stream *s_vbi;
1061a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
10761bb725ef5a646d3fc8a64e41b020a65542cdae1Hans Verkuil	s->fh = NULL;
1081a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	if ((s->type == IVTV_DEC_STREAM_TYPE_VBI || s->type == IVTV_ENC_STREAM_TYPE_VBI) &&
1091a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		test_bit(IVTV_F_S_INTERNAL_USE, &s->s_flags)) {
1101a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		/* this stream is still in use internally */
1111a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		return;
1121a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	}
1131a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	if (!test_and_clear_bit(IVTV_F_S_CLAIMED, &s->s_flags)) {
1141a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		IVTV_DEBUG_WARN("Release stream %s not in use!\n", s->name);
1151a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		return;
1161a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	}
1171a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
1181a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	ivtv_flush_queues(s);
1191a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
1201a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	/* disable reinsertion interrupt */
1211a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	if (s->type == IVTV_DEC_STREAM_TYPE_VBI)
1221a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		ivtv_set_irq_mask(itv, IVTV_IRQ_DEC_VBI_RE_INSERT);
1231a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
1241a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	/* IVTV_DEC_STREAM_TYPE_MPG needs to release IVTV_DEC_STREAM_TYPE_VBI,
1251a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	   IVTV_ENC_STREAM_TYPE_MPG needs to release IVTV_ENC_STREAM_TYPE_VBI,
1261a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	   for all other streams we're done */
1271a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	if (s->type == IVTV_DEC_STREAM_TYPE_MPG)
1281a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		s_vbi = &itv->streams[IVTV_DEC_STREAM_TYPE_VBI];
1291a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	else if (s->type == IVTV_ENC_STREAM_TYPE_MPG)
1301a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		s_vbi = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
1311a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	else
1321a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		return;
1331a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
1341a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	/* clear internal use flag */
1351a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	if (!test_and_clear_bit(IVTV_F_S_INTERNAL_USE, &s_vbi->s_flags)) {
1361a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		/* was already cleared */
1371a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		return;
1381a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	}
13961bb725ef5a646d3fc8a64e41b020a65542cdae1Hans Verkuil	if (s_vbi->fh) {
1401a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		/* VBI stream still claimed by a file descriptor */
1411a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		return;
1421a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	}
1431a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	/* disable reinsertion interrupt */
1441a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	if (s_vbi->type == IVTV_DEC_STREAM_TYPE_VBI)
1451a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		ivtv_set_irq_mask(itv, IVTV_IRQ_DEC_VBI_RE_INSERT);
1461a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	clear_bit(IVTV_F_S_CLAIMED, &s_vbi->s_flags);
1471a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	ivtv_flush_queues(s_vbi);
1481a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil}
1491a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
1501a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilstatic void ivtv_dualwatch(struct ivtv *itv)
1511a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{
1521a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	struct v4l2_tuner vt;
1530d82fe801d7c6d8cb8987e66b570f6decde9e235Andy Walls	u32 new_stereo_mode;
154f7b80e6919df812b4bed99a927325312a904111bHans Verkuil	const u32 dual = 0x02;
1551a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
156f7b80e6919df812b4bed99a927325312a904111bHans Verkuil	new_stereo_mode = v4l2_ctrl_g_ctrl(itv->cxhdl.audio_mode);
1571a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	memset(&vt, 0, sizeof(vt));
15867ec09fdf5e05d4670b617256c696348b5df080bHans Verkuil	ivtv_call_all(itv, tuner, g_tuner, &vt);
1591a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	if (vt.audmode == V4L2_TUNER_MODE_LANG1_LANG2 && (vt.rxsubchans & V4L2_TUNER_SUB_LANG2))
1601a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		new_stereo_mode = dual;
1611a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
1621a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	if (new_stereo_mode == itv->dualwatch_stereo_mode)
1631a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		return;
1641a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
165f7b80e6919df812b4bed99a927325312a904111bHans Verkuil	IVTV_DEBUG_INFO("dualwatch: change stereo flag from 0x%x to 0x%x.\n",
166f7b80e6919df812b4bed99a927325312a904111bHans Verkuil			   itv->dualwatch_stereo_mode, new_stereo_mode);
167f7b80e6919df812b4bed99a927325312a904111bHans Verkuil	if (v4l2_ctrl_s_ctrl(itv->cxhdl.audio_mode, new_stereo_mode))
168f7b80e6919df812b4bed99a927325312a904111bHans Verkuil		IVTV_DEBUG_INFO("dualwatch: changing stereo flag failed\n");
1691a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil}
1701a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
1711a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilstatic void ivtv_update_pgm_info(struct ivtv *itv)
1721a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{
1731a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	u32 wr_idx = (read_enc(itv->pgm_info_offset) - itv->pgm_info_offset - 4) / 24;
1741a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	int cnt;
1751a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	int i = 0;
1761a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
1771a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	if (wr_idx >= itv->pgm_info_num) {
1781a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		IVTV_DEBUG_WARN("Invalid PGM index %d (>= %d)\n", wr_idx, itv->pgm_info_num);
1791a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		return;
1801a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	}
1811a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	cnt = (wr_idx + itv->pgm_info_num - itv->pgm_info_write_idx) % itv->pgm_info_num;
1821a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	while (i < cnt) {
1831a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		int idx = (itv->pgm_info_write_idx + i) % itv->pgm_info_num;
1841a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		struct v4l2_enc_idx_entry *e = itv->pgm_info + idx;
1851a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		u32 addr = itv->pgm_info_offset + 4 + idx * 24;
1865614b02143171a99e0e6eb6c7d1d2f8750d2957fHans Verkuil		const int mapping[8] = { -1, V4L2_ENC_IDX_FRAME_I, V4L2_ENC_IDX_FRAME_P, -1,
1875614b02143171a99e0e6eb6c7d1d2f8750d2957fHans Verkuil			V4L2_ENC_IDX_FRAME_B, -1, -1, -1 };
1885614b02143171a99e0e6eb6c7d1d2f8750d2957fHans Verkuil					// 1=I, 2=P, 4=B
1891a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
1901a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		e->offset = read_enc(addr + 4) + ((u64)read_enc(addr + 8) << 32);
1911a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		if (e->offset > itv->mpg_data_received) {
1921a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			break;
1931a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		}
1941a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		e->offset += itv->vbi_data_inserted;
1951a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		e->length = read_enc(addr);
1961a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		e->pts = read_enc(addr + 16) + ((u64)(read_enc(addr + 20) & 1) << 32);
1975614b02143171a99e0e6eb6c7d1d2f8750d2957fHans Verkuil		e->flags = mapping[read_enc(addr + 12) & 7];
1981a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		i++;
1991a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	}
2001a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	itv->pgm_info_write_idx = (itv->pgm_info_write_idx + i) % itv->pgm_info_num;
2011a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil}
2021a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
2031a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilstatic struct ivtv_buffer *ivtv_get_buffer(struct ivtv_stream *s, int non_block, int *err)
2041a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{
2051a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	struct ivtv *itv = s->itv;
2061a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	struct ivtv_stream *s_vbi = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
2071a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	struct ivtv_buffer *buf;
2081a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	DEFINE_WAIT(wait);
2091a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
2101a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	*err = 0;
2111a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	while (1) {
2121a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		if (s->type == IVTV_ENC_STREAM_TYPE_MPG) {
2131a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			/* Process pending program info updates and pending VBI data */
2141a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			ivtv_update_pgm_info(itv);
2151a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
216168c626cb8f85df17585af99e14403904641c7acJulia Lawall			if (time_after(jiffies,
217168c626cb8f85df17585af99e14403904641c7acJulia Lawall				       itv->dualwatch_jiffies +
218168c626cb8f85df17585af99e14403904641c7acJulia Lawall				       msecs_to_jiffies(1000))) {
2191a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil				itv->dualwatch_jiffies = jiffies;
2201a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil				ivtv_dualwatch(itv);
2211a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			}
2221a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
2231a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			if (test_bit(IVTV_F_S_INTERNAL_USE, &s_vbi->s_flags) &&
2241a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			    !test_bit(IVTV_F_S_APPL_IO, &s_vbi->s_flags)) {
2251a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil				while ((buf = ivtv_dequeue(s_vbi, &s_vbi->q_full))) {
2261a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil					/* byteswap and process VBI data */
2271a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil					ivtv_process_vbi_data(itv, buf, s_vbi->dma_pts, s_vbi->type);
2281a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil					ivtv_enqueue(s_vbi, buf, &s_vbi->q_free);
2291a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil				}
2301a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			}
2311a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			buf = &itv->vbi.sliced_mpeg_buf;
2321a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			if (buf->readpos != buf->bytesused) {
2331a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil				return buf;
2341a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			}
2351a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		}
2361a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
2371a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		/* do we have leftover data? */
2381a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		buf = ivtv_dequeue(s, &s->q_io);
2391a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		if (buf)
2401a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			return buf;
2411a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
2421a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		/* do we have new data? */
2431a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		buf = ivtv_dequeue(s, &s->q_full);
2441a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		if (buf) {
245f4071b85ea0ca3bd06f63c330562b4cfdffa8473Hans Verkuil			if ((buf->b_flags & IVTV_F_B_NEED_BUF_SWAP) == 0)
2461a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil				return buf;
247f4071b85ea0ca3bd06f63c330562b4cfdffa8473Hans Verkuil			buf->b_flags &= ~IVTV_F_B_NEED_BUF_SWAP;
2481a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			if (s->type == IVTV_ENC_STREAM_TYPE_MPG)
2491a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil				/* byteswap MPG data */
2501a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil				ivtv_buf_swap(buf);
2511a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			else if (s->type != IVTV_DEC_STREAM_TYPE_VBI) {
2521a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil				/* byteswap and process VBI data */
2531a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil				ivtv_process_vbi_data(itv, buf, s->dma_pts, s->type);
2541a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			}
2551a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			return buf;
2561a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		}
2571a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
2581a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		/* return if end of stream */
2591a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		if (s->type != IVTV_DEC_STREAM_TYPE_VBI && !test_bit(IVTV_F_S_STREAMING, &s->s_flags)) {
2601a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			IVTV_DEBUG_INFO("EOS %s\n", s->name);
2611a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			return NULL;
2621a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		}
2631a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
264559e196a56a5d518181efc1d2fefe0892f4689b4Hans Verkuil		/* return if file was opened with O_NONBLOCK */
265559e196a56a5d518181efc1d2fefe0892f4689b4Hans Verkuil		if (non_block) {
266559e196a56a5d518181efc1d2fefe0892f4689b4Hans Verkuil			*err = -EAGAIN;
267559e196a56a5d518181efc1d2fefe0892f4689b4Hans Verkuil			return NULL;
268559e196a56a5d518181efc1d2fefe0892f4689b4Hans Verkuil		}
269559e196a56a5d518181efc1d2fefe0892f4689b4Hans Verkuil
2701a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		/* wait for more data to arrive */
271cdc037817cc15caf931cd3476970860d62f1985cHans Verkuil		mutex_unlock(&itv->serialize_lock);
2721a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE);
2731a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		/* New buffers might have become available before we were added to the waitqueue */
2741a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		if (!s->q_full.buffers)
2751a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			schedule();
2761a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		finish_wait(&s->waitq, &wait);
277cdc037817cc15caf931cd3476970860d62f1985cHans Verkuil		mutex_lock(&itv->serialize_lock);
2781a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		if (signal_pending(current)) {
2791a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			/* return if a signal was received */
2801a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			IVTV_DEBUG_INFO("User stopped %s\n", s->name);
2811a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			*err = -EINTR;
2821a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			return NULL;
2831a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		}
2841a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	}
2851a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil}
2861a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
2871a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilstatic void ivtv_setup_sliced_vbi_buf(struct ivtv *itv)
2881a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{
2891a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	int idx = itv->vbi.inserted_frame % IVTV_VBI_FRAMES;
2901a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
2911a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	itv->vbi.sliced_mpeg_buf.buf = itv->vbi.sliced_mpeg_data[idx];
2921a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	itv->vbi.sliced_mpeg_buf.bytesused = itv->vbi.sliced_mpeg_size[idx];
2931a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	itv->vbi.sliced_mpeg_buf.readpos = 0;
2941a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil}
2951a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
2961a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilstatic size_t ivtv_copy_buf_to_user(struct ivtv_stream *s, struct ivtv_buffer *buf,
2971a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		char __user *ubuf, size_t ucount)
2981a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{
2991a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	struct ivtv *itv = s->itv;
3001a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	size_t len = buf->bytesused - buf->readpos;
3011a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
3021a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	if (len > ucount) len = ucount;
3031a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	if (itv->vbi.insert_mpeg && s->type == IVTV_ENC_STREAM_TYPE_MPG &&
304a8b864354e060dda1000e62d1fea7c1274581cafHans Verkuil	    !ivtv_raw_vbi(itv) && buf != &itv->vbi.sliced_mpeg_buf) {
3051a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		const char *start = buf->buf + buf->readpos;
3061a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		const char *p = start + 1;
3071a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		const u8 *q;
3081a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		u8 ch = itv->search_pack_header ? 0xba : 0xe0;
3091a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		int stuffing, i;
3101a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
3111a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		while (start + len > p && (q = memchr(p, 0, start + len - p))) {
3121a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			p = q + 1;
3131a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			if ((char *)q + 15 >= buf->buf + buf->bytesused ||
3141a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			    q[1] != 0 || q[2] != 1 || q[3] != ch) {
3151a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil				continue;
3161a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			}
3171a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			if (!itv->search_pack_header) {
3181a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil				if ((q[6] & 0xc0) != 0x80)
3191a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil					continue;
3201a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil				if (((q[7] & 0xc0) == 0x80 && (q[9] & 0xf0) == 0x20) ||
3211a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil				    ((q[7] & 0xc0) == 0xc0 && (q[9] & 0xf0) == 0x30)) {
3221a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil					ch = 0xba;
3231a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil					itv->search_pack_header = 1;
3241a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil					p = q + 9;
3251a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil				}
3261a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil				continue;
3271a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			}
3281a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			stuffing = q[13] & 7;
3291a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			/* all stuffing bytes must be 0xff */
3301a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			for (i = 0; i < stuffing; i++)
3311a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil				if (q[14 + i] != 0xff)
3321a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil					break;
3331a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			if (i == stuffing && (q[4] & 0xc4) == 0x44 && (q[12] & 3) == 3 &&
3341a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil					q[14 + stuffing] == 0 && q[15 + stuffing] == 0 &&
3351a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil					q[16 + stuffing] == 1) {
3361a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil				itv->search_pack_header = 0;
3371a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil				len = (char *)q - start;
3381a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil				ivtv_setup_sliced_vbi_buf(itv);
3391a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil				break;
3401a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			}
3411a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		}
3421a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	}
3431a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	if (copy_to_user(ubuf, (u8 *)buf->buf + buf->readpos, len)) {
3441a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		IVTV_DEBUG_WARN("copy %zd bytes to user failed for %s\n", len, s->name);
3451a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		return -EFAULT;
3461a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	}
3471a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	/*IVTV_INFO("copied %lld %d %d %d %d %d vbi %d\n", itv->mpg_data_received, len, ucount,
3481a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			buf->readpos, buf->bytesused, buf->bytesused - buf->readpos - len,
3491a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			buf == &itv->vbi.sliced_mpeg_buf); */
3501a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	buf->readpos += len;
3511a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	if (s->type == IVTV_ENC_STREAM_TYPE_MPG && buf != &itv->vbi.sliced_mpeg_buf)
3521a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		itv->mpg_data_received += len;
3531a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	return len;
3541a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil}
3551a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
3561a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilstatic ssize_t ivtv_read(struct ivtv_stream *s, char __user *ubuf, size_t tot_count, int non_block)
3571a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{
3581a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	struct ivtv *itv = s->itv;
3591a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	size_t tot_written = 0;
3601a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	int single_frame = 0;
3611a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
36261bb725ef5a646d3fc8a64e41b020a65542cdae1Hans Verkuil	if (atomic_read(&itv->capturing) == 0 && s->fh == NULL) {
3631a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		/* shouldn't happen */
3641a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		IVTV_DEBUG_WARN("Stream %s not initialized before read\n", s->name);
3651a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		return -EIO;
3661a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	}
3671a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
3681a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	/* Each VBI buffer is one frame, the v4l2 API says that for VBI the frames should
3691a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	   arrive one-by-one, so make sure we never output more than one VBI frame at a time */
3701a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	if (s->type == IVTV_DEC_STREAM_TYPE_VBI ||
371a8b864354e060dda1000e62d1fea7c1274581cafHans Verkuil	    (s->type == IVTV_ENC_STREAM_TYPE_VBI && !ivtv_raw_vbi(itv)))
3721a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		single_frame = 1;
3731a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
3741a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	for (;;) {
3751a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		struct ivtv_buffer *buf;
3761a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		int rc;
3771a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
3781a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		buf = ivtv_get_buffer(s, non_block, &rc);
379559e196a56a5d518181efc1d2fefe0892f4689b4Hans Verkuil		/* if there is no data available... */
380559e196a56a5d518181efc1d2fefe0892f4689b4Hans Verkuil		if (buf == NULL) {
381559e196a56a5d518181efc1d2fefe0892f4689b4Hans Verkuil			/* if we got data, then return that regardless */
382559e196a56a5d518181efc1d2fefe0892f4689b4Hans Verkuil			if (tot_written)
383559e196a56a5d518181efc1d2fefe0892f4689b4Hans Verkuil				break;
384559e196a56a5d518181efc1d2fefe0892f4689b4Hans Verkuil			/* EOS condition */
385559e196a56a5d518181efc1d2fefe0892f4689b4Hans Verkuil			if (rc == 0) {
386559e196a56a5d518181efc1d2fefe0892f4689b4Hans Verkuil				clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags);
387559e196a56a5d518181efc1d2fefe0892f4689b4Hans Verkuil				clear_bit(IVTV_F_S_APPL_IO, &s->s_flags);
388559e196a56a5d518181efc1d2fefe0892f4689b4Hans Verkuil				ivtv_release_stream(s);
389559e196a56a5d518181efc1d2fefe0892f4689b4Hans Verkuil			}
390559e196a56a5d518181efc1d2fefe0892f4689b4Hans Verkuil			/* set errno */
3911a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			return rc;
392559e196a56a5d518181efc1d2fefe0892f4689b4Hans Verkuil		}
3931a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		rc = ivtv_copy_buf_to_user(s, buf, ubuf + tot_written, tot_count - tot_written);
3941a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		if (buf != &itv->vbi.sliced_mpeg_buf) {
3951a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			ivtv_enqueue(s, buf, (buf->readpos == buf->bytesused) ? &s->q_free : &s->q_io);
3961a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		}
3971a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		else if (buf->readpos == buf->bytesused) {
3981a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			int idx = itv->vbi.inserted_frame % IVTV_VBI_FRAMES;
3991a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			itv->vbi.sliced_mpeg_size[idx] = 0;
4001a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			itv->vbi.inserted_frame++;
4011a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			itv->vbi_data_inserted += buf->bytesused;
4021a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		}
4031a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		if (rc < 0)
4041a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			return rc;
4051a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		tot_written += rc;
4061a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
4071a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		if (tot_written == tot_count || single_frame)
4081a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			break;
4091a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	}
4101a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	return tot_written;
4111a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil}
4121a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
4131a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilstatic ssize_t ivtv_read_pos(struct ivtv_stream *s, char __user *ubuf, size_t count,
4141a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			loff_t *pos, int non_block)
4151a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{
4161a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	ssize_t rc = count ? ivtv_read(s, ubuf, count, non_block) : 0;
4171a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	struct ivtv *itv = s->itv;
4181a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
4191aa32c2ffd146dddd76babf842e998502f1b993aHans Verkuil	IVTV_DEBUG_HI_FILE("read %zd from %s, got %zd\n", count, s->name, rc);
4201a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	if (rc > 0)
4211a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		pos += rc;
4221a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	return rc;
4231a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil}
4241a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
4251a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilint ivtv_start_capture(struct ivtv_open_id *id)
4261a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{
4271a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	struct ivtv *itv = id->itv;
4281a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	struct ivtv_stream *s = &itv->streams[id->type];
4291a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	struct ivtv_stream *s_vbi;
4301a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
4311a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	if (s->type == IVTV_ENC_STREAM_TYPE_RAD ||
4321a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	    s->type == IVTV_DEC_STREAM_TYPE_MPG ||
4331a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	    s->type == IVTV_DEC_STREAM_TYPE_YUV ||
4341a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	    s->type == IVTV_DEC_STREAM_TYPE_VOUT) {
4351a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		/* you cannot read from these stream types. */
4361a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		return -EPERM;
4371a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	}
4381a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
4391a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	/* Try to claim this stream. */
4401a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	if (ivtv_claim_stream(id, s->type))
4411a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		return -EBUSY;
4421a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
4431a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	/* This stream does not need to start capturing */
4441a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	if (s->type == IVTV_DEC_STREAM_TYPE_VBI) {
4451a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		set_bit(IVTV_F_S_APPL_IO, &s->s_flags);
4461a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		return 0;
4471a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	}
4481a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
4491a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	/* If capture is already in progress, then we also have to
4501a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	   do nothing extra. */
4511a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	if (test_bit(IVTV_F_S_STREAMOFF, &s->s_flags) || test_and_set_bit(IVTV_F_S_STREAMING, &s->s_flags)) {
4521a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		set_bit(IVTV_F_S_APPL_IO, &s->s_flags);
4531a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		return 0;
4541a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	}
4551a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
4561a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	/* Start VBI capture if required */
4571a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	s_vbi = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
4581a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	if (s->type == IVTV_ENC_STREAM_TYPE_MPG &&
4591a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	    test_bit(IVTV_F_S_INTERNAL_USE, &s_vbi->s_flags) &&
4601a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	    !test_and_set_bit(IVTV_F_S_STREAMING, &s_vbi->s_flags)) {
4611a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		/* Note: the IVTV_ENC_STREAM_TYPE_VBI is claimed
4621a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		   automatically when the MPG stream is claimed.
4631a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		   We only need to start the VBI capturing. */
4641a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		if (ivtv_start_v4l2_encode_stream(s_vbi)) {
4651a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			IVTV_DEBUG_WARN("VBI capture start failed\n");
4661a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
4671a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			/* Failure, clean up and return an error */
4681a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			clear_bit(IVTV_F_S_STREAMING, &s_vbi->s_flags);
4691a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			clear_bit(IVTV_F_S_STREAMING, &s->s_flags);
4701a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			/* also releases the associated VBI stream */
4711a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			ivtv_release_stream(s);
4721a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			return -EIO;
4731a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		}
4741a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		IVTV_DEBUG_INFO("VBI insertion started\n");
4751a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	}
4761a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
4771a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	/* Tell the card to start capturing */
4781a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	if (!ivtv_start_v4l2_encode_stream(s)) {
4791a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		/* We're done */
4801a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		set_bit(IVTV_F_S_APPL_IO, &s->s_flags);
4811a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		/* Resume a possibly paused encoder */
4821a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		if (test_and_clear_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
4831a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 1);
4841a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		return 0;
4851a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	}
4861a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
4871a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	/* failure, clean up */
4881a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	IVTV_DEBUG_WARN("Failed to start capturing for stream %s\n", s->name);
4891a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
4901a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	/* Note: the IVTV_ENC_STREAM_TYPE_VBI is released
4911a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	   automatically when the MPG stream is released.
4921a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	   We only need to stop the VBI capturing. */
4931a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	if (s->type == IVTV_ENC_STREAM_TYPE_MPG &&
4941a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	    test_bit(IVTV_F_S_STREAMING, &s_vbi->s_flags)) {
4951a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		ivtv_stop_v4l2_encode_stream(s_vbi, 0);
4961a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		clear_bit(IVTV_F_S_STREAMING, &s_vbi->s_flags);
4971a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	}
4981a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	clear_bit(IVTV_F_S_STREAMING, &s->s_flags);
4991a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	ivtv_release_stream(s);
5001a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	return -EIO;
5011a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil}
5021a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
5031a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilssize_t ivtv_v4l2_read(struct file * filp, char __user *buf, size_t count, loff_t * pos)
5041a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{
505092501936fc128992456a086193746cf34642815Hans Verkuil	struct ivtv_open_id *id = fh2id(filp->private_data);
5061a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	struct ivtv *itv = id->itv;
5071a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	struct ivtv_stream *s = &itv->streams[id->type];
5081a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	int rc;
5091a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
5101aa32c2ffd146dddd76babf842e998502f1b993aHans Verkuil	IVTV_DEBUG_HI_FILE("read %zd bytes from %s\n", count, s->name);
5111a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
5121a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	rc = ivtv_start_capture(id);
5131a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	if (rc)
5141a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		return rc;
5151a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	return ivtv_read_pos(s, buf, count, pos, filp->f_flags & O_NONBLOCK);
5161a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil}
5171a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
5181a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilint ivtv_start_decoding(struct ivtv_open_id *id, int speed)
5191a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{
5201a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	struct ivtv *itv = id->itv;
5211a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	struct ivtv_stream *s = &itv->streams[id->type];
522914610e8c508224a6fb9fb501ed4bda25b340ba6Ian Armstrong	int rc;
5231a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
5241a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	if (atomic_read(&itv->decoding) == 0) {
5251a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		if (ivtv_claim_stream(id, s->type)) {
5261a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			/* someone else is using this stream already */
5271a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			IVTV_DEBUG_WARN("start decode, stream already claimed\n");
5281a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			return -EBUSY;
5291a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		}
530914610e8c508224a6fb9fb501ed4bda25b340ba6Ian Armstrong		rc = ivtv_start_v4l2_decode_stream(s, 0);
531215659d14f9dbc849ccda1655c94d710f8cc6384Ian Armstrong		if (rc < 0) {
532215659d14f9dbc849ccda1655c94d710f8cc6384Ian Armstrong			if (rc == -EAGAIN)
533215659d14f9dbc849ccda1655c94d710f8cc6384Ian Armstrong				rc = ivtv_start_v4l2_decode_stream(s, 0);
534215659d14f9dbc849ccda1655c94d710f8cc6384Ian Armstrong			if (rc < 0)
535215659d14f9dbc849ccda1655c94d710f8cc6384Ian Armstrong				return rc;
536215659d14f9dbc849ccda1655c94d710f8cc6384Ian Armstrong		}
5371a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	}
5381a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	if (s->type == IVTV_DEC_STREAM_TYPE_MPG)
5391a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		return ivtv_set_speed(itv, speed);
5401a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	return 0;
5411a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil}
5421a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
5431a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilssize_t ivtv_v4l2_write(struct file *filp, const char __user *user_buf, size_t count, loff_t *pos)
5441a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{
545092501936fc128992456a086193746cf34642815Hans Verkuil	struct ivtv_open_id *id = fh2id(filp->private_data);
5461a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	struct ivtv *itv = id->itv;
5471a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	struct ivtv_stream *s = &itv->streams[id->type];
548c240ad00af78228726e6301ad6ffc54d3adce2a0Ian Armstrong	struct yuv_playback_info *yi = &itv->yuv_info;
5491a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	struct ivtv_buffer *buf;
5501a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	struct ivtv_queue q;
5511a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	int bytes_written = 0;
5521a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	int mode;
5531a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	int rc;
5541a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	DEFINE_WAIT(wait);
5551a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
5561aa32c2ffd146dddd76babf842e998502f1b993aHans Verkuil	IVTV_DEBUG_HI_FILE("write %zd bytes to %s\n", count, s->name);
5571a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
5581a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	if (s->type != IVTV_DEC_STREAM_TYPE_MPG &&
5591a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	    s->type != IVTV_DEC_STREAM_TYPE_YUV &&
5601a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	    s->type != IVTV_DEC_STREAM_TYPE_VOUT)
5611a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		/* not decoder streams */
5621a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		return -EPERM;
5631a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
5641a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	/* Try to claim this stream */
5651a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	if (ivtv_claim_stream(id, s->type))
5661a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		return -EBUSY;
5671a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
5681a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	/* This stream does not need to start any decoding */
5691a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	if (s->type == IVTV_DEC_STREAM_TYPE_VOUT) {
5702f3a98931f51be6093df7c6cc2633bf238778b7dHans Verkuil		int elems = count / sizeof(struct v4l2_sliced_vbi_data);
5712f3a98931f51be6093df7c6cc2633bf238778b7dHans Verkuil
5721a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		set_bit(IVTV_F_S_APPL_IO, &s->s_flags);
573ddda424999817fbc17adf9013feb066903382edeAndy Walls		return ivtv_write_vbi_from_user(itv,
574b0c45686c8e8aecc7b0cd04d9b6af48d74418d53Andy Walls		   (const struct v4l2_sliced_vbi_data __user *)user_buf, elems);
5751a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	}
5761a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
5771a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	mode = s->type == IVTV_DEC_STREAM_TYPE_MPG ? OUT_MPG : OUT_YUV;
5781a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
5791a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	if (ivtv_set_output_mode(itv, mode) != mode) {
5801a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	    ivtv_release_stream(s);
5811a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	    return -EBUSY;
5821a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	}
5831a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	ivtv_queue_init(&q);
5841a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	set_bit(IVTV_F_S_APPL_IO, &s->s_flags);
5851a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
586464e9f3a0cabce9a7cf51f382f129d464483b0d0Ian Armstrong	/* Start decoder (returns 0 if already started) */
587464e9f3a0cabce9a7cf51f382f129d464483b0d0Ian Armstrong	rc = ivtv_start_decoding(id, itv->speed);
588464e9f3a0cabce9a7cf51f382f129d464483b0d0Ian Armstrong	if (rc) {
589464e9f3a0cabce9a7cf51f382f129d464483b0d0Ian Armstrong		IVTV_DEBUG_WARN("Failed start decode stream %s\n", s->name);
590464e9f3a0cabce9a7cf51f382f129d464483b0d0Ian Armstrong
591464e9f3a0cabce9a7cf51f382f129d464483b0d0Ian Armstrong		/* failure, clean up */
592464e9f3a0cabce9a7cf51f382f129d464483b0d0Ian Armstrong		clear_bit(IVTV_F_S_STREAMING, &s->s_flags);
593464e9f3a0cabce9a7cf51f382f129d464483b0d0Ian Armstrong		clear_bit(IVTV_F_S_APPL_IO, &s->s_flags);
594464e9f3a0cabce9a7cf51f382f129d464483b0d0Ian Armstrong		return rc;
595464e9f3a0cabce9a7cf51f382f129d464483b0d0Ian Armstrong	}
596464e9f3a0cabce9a7cf51f382f129d464483b0d0Ian Armstrong
5971a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilretry:
59877aded6ba51f01335840ce8e18b413067810b68eIan Armstrong	/* If possible, just DMA the entire frame - Check the data transfer size
59977aded6ba51f01335840ce8e18b413067810b68eIan Armstrong	since we may get here before the stream has been fully set-up */
60077aded6ba51f01335840ce8e18b413067810b68eIan Armstrong	if (mode == OUT_YUV && s->q_full.length == 0 && itv->dma_data_req_size) {
60177aded6ba51f01335840ce8e18b413067810b68eIan Armstrong		while (count >= itv->dma_data_req_size) {
6022e668962a54b64f3daffb8eef3ca538e25324d1aIan Armstrong			rc = ivtv_yuv_udma_stream_frame(itv, (void __user *)user_buf);
6032e668962a54b64f3daffb8eef3ca538e25324d1aIan Armstrong
6042e668962a54b64f3daffb8eef3ca538e25324d1aIan Armstrong			if (rc < 0)
6052e668962a54b64f3daffb8eef3ca538e25324d1aIan Armstrong				return rc;
6062e668962a54b64f3daffb8eef3ca538e25324d1aIan Armstrong
6072e668962a54b64f3daffb8eef3ca538e25324d1aIan Armstrong			bytes_written += itv->dma_data_req_size;
6082e668962a54b64f3daffb8eef3ca538e25324d1aIan Armstrong			user_buf += itv->dma_data_req_size;
6092e668962a54b64f3daffb8eef3ca538e25324d1aIan Armstrong			count -= itv->dma_data_req_size;
61077aded6ba51f01335840ce8e18b413067810b68eIan Armstrong		}
61177aded6ba51f01335840ce8e18b413067810b68eIan Armstrong		if (count == 0) {
61277aded6ba51f01335840ce8e18b413067810b68eIan Armstrong			IVTV_DEBUG_HI_FILE("Wrote %d bytes to %s (%d)\n", bytes_written, s->name, s->q_full.bytesused);
61377aded6ba51f01335840ce8e18b413067810b68eIan Armstrong			return bytes_written;
61477aded6ba51f01335840ce8e18b413067810b68eIan Armstrong		}
61577aded6ba51f01335840ce8e18b413067810b68eIan Armstrong	}
61677aded6ba51f01335840ce8e18b413067810b68eIan Armstrong
6171a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	for (;;) {
6181a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		/* Gather buffers */
6191a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		while (q.length - q.bytesused < count && (buf = ivtv_dequeue(s, &s->q_io)))
6201a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			ivtv_enqueue(s, buf, &q);
6211a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		while (q.length - q.bytesused < count && (buf = ivtv_dequeue(s, &s->q_free))) {
6221a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			ivtv_enqueue(s, buf, &q);
6231a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		}
6241a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		if (q.buffers)
6251a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			break;
6261a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		if (filp->f_flags & O_NONBLOCK)
6271a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			return -EAGAIN;
628cdc037817cc15caf931cd3476970860d62f1985cHans Verkuil		mutex_unlock(&itv->serialize_lock);
6291a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE);
6301a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		/* New buffers might have become free before we were added to the waitqueue */
6311a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		if (!s->q_free.buffers)
6321a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			schedule();
6331a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		finish_wait(&s->waitq, &wait);
634cdc037817cc15caf931cd3476970860d62f1985cHans Verkuil		mutex_lock(&itv->serialize_lock);
6351a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		if (signal_pending(current)) {
6361a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			IVTV_DEBUG_INFO("User stopped %s\n", s->name);
6371a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			return -EINTR;
6381a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		}
6391a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	}
6401a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
6411a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	/* copy user data into buffers */
6421a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	while ((buf = ivtv_dequeue(s, &q))) {
643c240ad00af78228726e6301ad6ffc54d3adce2a0Ian Armstrong		/* yuv is a pain. Don't copy more data than needed for a single
644c240ad00af78228726e6301ad6ffc54d3adce2a0Ian Armstrong		   frame, otherwise we lose sync with the incoming stream */
645c240ad00af78228726e6301ad6ffc54d3adce2a0Ian Armstrong		if (s->type == IVTV_DEC_STREAM_TYPE_YUV &&
646c240ad00af78228726e6301ad6ffc54d3adce2a0Ian Armstrong		    yi->stream_size + count > itv->dma_data_req_size)
647c240ad00af78228726e6301ad6ffc54d3adce2a0Ian Armstrong			rc  = ivtv_buf_copy_from_user(s, buf, user_buf,
648c240ad00af78228726e6301ad6ffc54d3adce2a0Ian Armstrong				itv->dma_data_req_size - yi->stream_size);
649c240ad00af78228726e6301ad6ffc54d3adce2a0Ian Armstrong		else
650c240ad00af78228726e6301ad6ffc54d3adce2a0Ian Armstrong			rc = ivtv_buf_copy_from_user(s, buf, user_buf, count);
6511a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
652c240ad00af78228726e6301ad6ffc54d3adce2a0Ian Armstrong		/* Make sure we really got all the user data */
6531a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		if (rc < 0) {
6541a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			ivtv_queue_move(s, &q, NULL, &s->q_free, 0);
6551a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			return rc;
6561a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		}
6571a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		user_buf += rc;
6581a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		count -= rc;
6591a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		bytes_written += rc;
6601a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
661c240ad00af78228726e6301ad6ffc54d3adce2a0Ian Armstrong		if (s->type == IVTV_DEC_STREAM_TYPE_YUV) {
662c240ad00af78228726e6301ad6ffc54d3adce2a0Ian Armstrong			yi->stream_size += rc;
663c240ad00af78228726e6301ad6ffc54d3adce2a0Ian Armstrong			/* If we have a complete yuv frame, break loop now */
664c240ad00af78228726e6301ad6ffc54d3adce2a0Ian Armstrong			if (yi->stream_size == itv->dma_data_req_size) {
665c240ad00af78228726e6301ad6ffc54d3adce2a0Ian Armstrong				ivtv_enqueue(s, buf, &s->q_full);
666c240ad00af78228726e6301ad6ffc54d3adce2a0Ian Armstrong				yi->stream_size = 0;
667c240ad00af78228726e6301ad6ffc54d3adce2a0Ian Armstrong				break;
668c240ad00af78228726e6301ad6ffc54d3adce2a0Ian Armstrong			}
669c240ad00af78228726e6301ad6ffc54d3adce2a0Ian Armstrong		}
670c240ad00af78228726e6301ad6ffc54d3adce2a0Ian Armstrong
6711a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		if (buf->bytesused != s->buf_size) {
6721a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			/* incomplete, leave in q_io for next time */
6731a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			ivtv_enqueue(s, buf, &s->q_io);
6741a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			break;
6751a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		}
6761a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		/* Byteswap MPEG buffer */
6771a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		if (s->type == IVTV_DEC_STREAM_TYPE_MPG)
6781a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			ivtv_buf_swap(buf);
6791a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		ivtv_enqueue(s, buf, &s->q_full);
6801a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	}
6811a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
6821a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	if (test_bit(IVTV_F_S_NEEDS_DATA, &s->s_flags)) {
6831a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		if (s->q_full.length >= itv->dma_data_req_size) {
6841a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			int got_sig;
6851a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
68677aded6ba51f01335840ce8e18b413067810b68eIan Armstrong			if (mode == OUT_YUV)
68777aded6ba51f01335840ce8e18b413067810b68eIan Armstrong				ivtv_yuv_setup_stream_frame(itv);
68877aded6ba51f01335840ce8e18b413067810b68eIan Armstrong
689cdc037817cc15caf931cd3476970860d62f1985cHans Verkuil			mutex_unlock(&itv->serialize_lock);
6901a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE);
6911a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			while (!(got_sig = signal_pending(current)) &&
6921a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil					test_bit(IVTV_F_S_DMA_PENDING, &s->s_flags)) {
6931a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil				schedule();
6941a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			}
6951a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			finish_wait(&itv->dma_waitq, &wait);
696cdc037817cc15caf931cd3476970860d62f1985cHans Verkuil			mutex_lock(&itv->serialize_lock);
6971a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			if (got_sig) {
6981a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil				IVTV_DEBUG_INFO("User interrupted %s\n", s->name);
6991a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil				return -EINTR;
7001a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			}
7011a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
7021a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			clear_bit(IVTV_F_S_NEEDS_DATA, &s->s_flags);
7031a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			ivtv_queue_move(s, &s->q_full, NULL, &s->q_predma, itv->dma_data_req_size);
7041a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			ivtv_dma_stream_dec_prepare(s, itv->dma_data_req_offset + IVTV_DECODER_OFFSET, 1);
7051a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		}
7061a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	}
7071a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	/* more user data is available, wait until buffers become free
7081a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	   to transfer the rest. */
7091a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	if (count && !(filp->f_flags & O_NONBLOCK))
7101a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		goto retry;
7111aa32c2ffd146dddd76babf842e998502f1b993aHans Verkuil	IVTV_DEBUG_HI_FILE("Wrote %d bytes to %s (%d)\n", bytes_written, s->name, s->q_full.bytesused);
7121a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	return bytes_written;
7131a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil}
7141a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
7151a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilunsigned int ivtv_v4l2_dec_poll(struct file *filp, poll_table *wait)
7161a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{
717092501936fc128992456a086193746cf34642815Hans Verkuil	struct ivtv_open_id *id = fh2id(filp->private_data);
7181a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	struct ivtv *itv = id->itv;
7191a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	struct ivtv_stream *s = &itv->streams[id->type];
7201a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	int res = 0;
7211a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
7221a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	/* add stream's waitq to the poll list */
7231aa32c2ffd146dddd76babf842e998502f1b993aHans Verkuil	IVTV_DEBUG_HI_FILE("Decoder poll\n");
7241a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
725092501936fc128992456a086193746cf34642815Hans Verkuil	/* If there are subscribed events, then only use the new event
726092501936fc128992456a086193746cf34642815Hans Verkuil	   API instead of the old video.h based API. */
727523f46d6aba9dcb0a2d0fc474ca884e93a7cf198Hans Verkuil	if (!list_empty(&id->fh.subscribed)) {
728523f46d6aba9dcb0a2d0fc474ca884e93a7cf198Hans Verkuil		poll_wait(filp, &id->fh.wait, wait);
729092501936fc128992456a086193746cf34642815Hans Verkuil		/* Turn off the old-style vsync events */
730092501936fc128992456a086193746cf34642815Hans Verkuil		clear_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags);
731092501936fc128992456a086193746cf34642815Hans Verkuil		if (v4l2_event_pending(&id->fh))
732092501936fc128992456a086193746cf34642815Hans Verkuil			res = POLLPRI;
733092501936fc128992456a086193746cf34642815Hans Verkuil	} else {
734092501936fc128992456a086193746cf34642815Hans Verkuil		/* This is the old-style API which is here only for backwards
735092501936fc128992456a086193746cf34642815Hans Verkuil		   compatibility. */
736092501936fc128992456a086193746cf34642815Hans Verkuil		poll_wait(filp, &s->waitq, wait);
737092501936fc128992456a086193746cf34642815Hans Verkuil		set_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags);
738092501936fc128992456a086193746cf34642815Hans Verkuil		if (test_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags) ||
739092501936fc128992456a086193746cf34642815Hans Verkuil		    test_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags))
740092501936fc128992456a086193746cf34642815Hans Verkuil			res = POLLPRI;
741092501936fc128992456a086193746cf34642815Hans Verkuil	}
7421a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
7431a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	/* Allow write if buffers are available for writing */
7441a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	if (s->q_free.buffers)
7451a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		res |= POLLOUT | POLLWRNORM;
7461a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	return res;
7471a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil}
7481a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
7491a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilunsigned int ivtv_v4l2_enc_poll(struct file *filp, poll_table * wait)
7501a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{
751092501936fc128992456a086193746cf34642815Hans Verkuil	struct ivtv_open_id *id = fh2id(filp->private_data);
7521a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	struct ivtv *itv = id->itv;
7531a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	struct ivtv_stream *s = &itv->streams[id->type];
7541a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	int eof = test_bit(IVTV_F_S_STREAMOFF, &s->s_flags);
7555138870d68ffbf6fcdf019af5b2ce78bc5a1f837Hans Verkuil	unsigned res = 0;
7561a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
7571a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	/* Start a capture if there is none */
7581a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	if (!eof && !test_bit(IVTV_F_S_STREAMING, &s->s_flags)) {
759baa4072d84e7a2e9954121c826d7bb8f1fb66b38Hans Verkuil		int rc;
7601a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
761baa4072d84e7a2e9954121c826d7bb8f1fb66b38Hans Verkuil		rc = ivtv_start_capture(id);
7621a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		if (rc) {
7631a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			IVTV_DEBUG_INFO("Could not start capture for %s (%d)\n",
7641a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil					s->name, rc);
7651a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			return POLLERR;
7661a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		}
7671aa32c2ffd146dddd76babf842e998502f1b993aHans Verkuil		IVTV_DEBUG_FILE("Encoder poll started capture\n");
7681a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	}
7691a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
7701a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	/* add stream's waitq to the poll list */
7711aa32c2ffd146dddd76babf842e998502f1b993aHans Verkuil	IVTV_DEBUG_HI_FILE("Encoder poll\n");
7721a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	poll_wait(filp, &s->waitq, wait);
7735138870d68ffbf6fcdf019af5b2ce78bc5a1f837Hans Verkuil	if (v4l2_event_pending(&id->fh))
7745138870d68ffbf6fcdf019af5b2ce78bc5a1f837Hans Verkuil		res |= POLLPRI;
7755138870d68ffbf6fcdf019af5b2ce78bc5a1f837Hans Verkuil	else
776523f46d6aba9dcb0a2d0fc474ca884e93a7cf198Hans Verkuil		poll_wait(filp, &id->fh.wait, wait);
7771a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
77816928be301b0881f7b7afcf95e0ee7dc3214de8dHans Verkuil	if (s->q_full.length || s->q_io.length)
7795138870d68ffbf6fcdf019af5b2ce78bc5a1f837Hans Verkuil		return res | POLLIN | POLLRDNORM;
78016928be301b0881f7b7afcf95e0ee7dc3214de8dHans Verkuil	if (eof)
7815138870d68ffbf6fcdf019af5b2ce78bc5a1f837Hans Verkuil		return res | POLLHUP;
7825138870d68ffbf6fcdf019af5b2ce78bc5a1f837Hans Verkuil	return res;
7831a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil}
7841a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
7851a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilvoid ivtv_stop_capture(struct ivtv_open_id *id, int gop_end)
7861a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{
7871a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	struct ivtv *itv = id->itv;
7881a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	struct ivtv_stream *s = &itv->streams[id->type];
7891a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
7901aa32c2ffd146dddd76babf842e998502f1b993aHans Verkuil	IVTV_DEBUG_FILE("close() of %s\n", s->name);
7911a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
7921a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	/* 'Unclaim' this stream */
7931a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
7941a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	/* Stop capturing */
7951a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	if (test_bit(IVTV_F_S_STREAMING, &s->s_flags)) {
7961a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		struct ivtv_stream *s_vbi = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
7971a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
7981a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		IVTV_DEBUG_INFO("close stopping capture\n");
7991a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		/* Special case: a running VBI capture for VBI insertion
8001a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		   in the mpeg stream. Need to stop that too. */
8011a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		if (id->type == IVTV_ENC_STREAM_TYPE_MPG &&
8021a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		    test_bit(IVTV_F_S_STREAMING, &s_vbi->s_flags) &&
8031a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		    !test_bit(IVTV_F_S_APPL_IO, &s_vbi->s_flags)) {
8041a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			IVTV_DEBUG_INFO("close stopping embedded VBI capture\n");
8051a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			ivtv_stop_v4l2_encode_stream(s_vbi, 0);
8061a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		}
8071a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		if ((id->type == IVTV_DEC_STREAM_TYPE_VBI ||
8081a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		     id->type == IVTV_ENC_STREAM_TYPE_VBI) &&
8091a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		    test_bit(IVTV_F_S_INTERNAL_USE, &s->s_flags)) {
8101a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			/* Also used internally, don't stop capturing */
81161bb725ef5a646d3fc8a64e41b020a65542cdae1Hans Verkuil			s->fh = NULL;
8121a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		}
8131a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		else {
8141a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			ivtv_stop_v4l2_encode_stream(s, gop_end);
8151a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		}
8161a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	}
817559e196a56a5d518181efc1d2fefe0892f4689b4Hans Verkuil	if (!gop_end) {
818559e196a56a5d518181efc1d2fefe0892f4689b4Hans Verkuil		clear_bit(IVTV_F_S_APPL_IO, &s->s_flags);
819559e196a56a5d518181efc1d2fefe0892f4689b4Hans Verkuil		clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags);
820559e196a56a5d518181efc1d2fefe0892f4689b4Hans Verkuil		ivtv_release_stream(s);
821559e196a56a5d518181efc1d2fefe0892f4689b4Hans Verkuil	}
8221a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil}
8231a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
82431ec13561060b748221f4e0404bcc5bf8078ccd0Hans Verkuilstatic void ivtv_stop_decoding(struct ivtv_open_id *id, int flags, u64 pts)
8251a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{
8261a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	struct ivtv *itv = id->itv;
8271a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	struct ivtv_stream *s = &itv->streams[id->type];
8281a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
8291aa32c2ffd146dddd76babf842e998502f1b993aHans Verkuil	IVTV_DEBUG_FILE("close() of %s\n", s->name);
8301a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
831666092c679f7d9eb9f5230087f960a487fda721cIan Armstrong	if (id->type == IVTV_DEC_STREAM_TYPE_YUV &&
832666092c679f7d9eb9f5230087f960a487fda721cIan Armstrong		test_bit(IVTV_F_I_DECODING_YUV, &itv->i_flags)) {
833666092c679f7d9eb9f5230087f960a487fda721cIan Armstrong		/* Restore registers we've changed & clean up any mess */
834666092c679f7d9eb9f5230087f960a487fda721cIan Armstrong		ivtv_yuv_close(itv);
835666092c679f7d9eb9f5230087f960a487fda721cIan Armstrong	}
836666092c679f7d9eb9f5230087f960a487fda721cIan Armstrong
8371a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	/* Stop decoding */
8381a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	if (test_bit(IVTV_F_S_STREAMING, &s->s_flags)) {
8391a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		IVTV_DEBUG_INFO("close stopping decode\n");
8401a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
8411a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		ivtv_stop_v4l2_decode_stream(s, flags, pts);
842ad8ff0f10b489562012e433acdac92498fe8bdc9Hans Verkuil		itv->output_mode = OUT_NONE;
8431a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	}
8441a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	clear_bit(IVTV_F_S_APPL_IO, &s->s_flags);
8451a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags);
846666092c679f7d9eb9f5230087f960a487fda721cIan Armstrong
847ad8ff0f10b489562012e433acdac92498fe8bdc9Hans Verkuil	if (itv->output_mode == OUT_UDMA_YUV && id->yuv_frames)
848cb50f548c0ee9b2aac39743fc4021a7188825a98Ian Armstrong		itv->output_mode = OUT_NONE;
8491a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
8501a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	itv->speed = 0;
851ac4251445d7302697814351f1d9f548f5aa49342Hans Verkuil	clear_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags);
8521a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	ivtv_release_stream(s);
8531a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil}
8541a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
855bec43661b1dc0075b7445223ba775674133b164dHans Verkuilint ivtv_v4l2_close(struct file *filp)
8561a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{
857092501936fc128992456a086193746cf34642815Hans Verkuil	struct v4l2_fh *fh = filp->private_data;
858092501936fc128992456a086193746cf34642815Hans Verkuil	struct ivtv_open_id *id = fh2id(fh);
8591a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	struct ivtv *itv = id->itv;
8601a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	struct ivtv_stream *s = &itv->streams[id->type];
8611a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
8621aa32c2ffd146dddd76babf842e998502f1b993aHans Verkuil	IVTV_DEBUG_FILE("close %s\n", s->name);
8631a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
8643f3edd7c97d0a5ae355aace36000576acbc2f2ccHans Verkuil	/* Stop radio */
8653f3edd7c97d0a5ae355aace36000576acbc2f2ccHans Verkuil	if (id->type == IVTV_ENC_STREAM_TYPE_RAD &&
8663f3edd7c97d0a5ae355aace36000576acbc2f2ccHans Verkuil			v4l2_fh_is_singular_file(filp)) {
8671a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		/* Closing radio device, return to TV mode */
8681a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		ivtv_mute(itv);
8691a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		/* Mark that the radio is no longer in use */
8701a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		clear_bit(IVTV_F_I_RADIO_USER, &itv->i_flags);
8711a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		/* Switch tuner to TV */
872f41737ece472cd803ffb24ac9f5d6fdd1d871341Hans Verkuil		ivtv_call_all(itv, core, s_std, itv->std);
8731a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		/* Select correct audio input (i.e. TV tuner or Line in) */
8741a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		ivtv_audio_set_io(itv);
8753ff4ad815c5824ab35375d72ea8fe14fb3230daaHans Verkuil		if (itv->hw_flags & IVTV_HW_SAA711X) {
8763ff4ad815c5824ab35375d72ea8fe14fb3230daaHans Verkuil			ivtv_call_hw(itv, IVTV_HW_SAA711X, video, s_crystal_freq,
8773ff4ad815c5824ab35375d72ea8fe14fb3230daaHans Verkuil					SAA7115_FREQ_32_11_MHZ, 0);
878f2100d82b858815848b661d57d7e166341c02e20Hans Verkuil		}
8792f7362ef9bc9c41436c7f44212a2dcf12dddffbfHans Verkuil		if (atomic_read(&itv->capturing) > 0) {
8802f7362ef9bc9c41436c7f44212a2dcf12dddffbfHans Verkuil			/* Undo video mute */
8812f7362ef9bc9c41436c7f44212a2dcf12dddffbfHans Verkuil			ivtv_vapi(itv, CX2341X_ENC_MUTE_VIDEO, 1,
8823f3edd7c97d0a5ae355aace36000576acbc2f2ccHans Verkuil					v4l2_ctrl_g_ctrl(itv->cxhdl.video_mute) |
8833f3edd7c97d0a5ae355aace36000576acbc2f2ccHans Verkuil					(v4l2_ctrl_g_ctrl(itv->cxhdl.video_mute_yuv) << 8));
8842f7362ef9bc9c41436c7f44212a2dcf12dddffbfHans Verkuil		}
8851a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		/* Done! Unmute and continue. */
8861a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		ivtv_unmute(itv);
8873f3edd7c97d0a5ae355aace36000576acbc2f2ccHans Verkuil	}
8883f3edd7c97d0a5ae355aace36000576acbc2f2ccHans Verkuil
8893f3edd7c97d0a5ae355aace36000576acbc2f2ccHans Verkuil	v4l2_fh_del(fh);
8903f3edd7c97d0a5ae355aace36000576acbc2f2ccHans Verkuil	v4l2_fh_exit(fh);
8913f3edd7c97d0a5ae355aace36000576acbc2f2ccHans Verkuil
8923f3edd7c97d0a5ae355aace36000576acbc2f2ccHans Verkuil	/* Easy case first: this stream was never claimed by us */
89361bb725ef5a646d3fc8a64e41b020a65542cdae1Hans Verkuil	if (s->fh != &id->fh) {
8943f3edd7c97d0a5ae355aace36000576acbc2f2ccHans Verkuil		kfree(id);
8953f3edd7c97d0a5ae355aace36000576acbc2f2ccHans Verkuil		return 0;
8963f3edd7c97d0a5ae355aace36000576acbc2f2ccHans Verkuil	}
8973f3edd7c97d0a5ae355aace36000576acbc2f2ccHans Verkuil
8983f3edd7c97d0a5ae355aace36000576acbc2f2ccHans Verkuil	/* 'Unclaim' this stream */
8993f3edd7c97d0a5ae355aace36000576acbc2f2ccHans Verkuil
9003f3edd7c97d0a5ae355aace36000576acbc2f2ccHans Verkuil	if (s->type >= IVTV_DEC_STREAM_TYPE_MPG) {
9015a338c38ced1569a2e67e3c163505cc95429d508Hans Verkuil		struct ivtv_stream *s_vout = &itv->streams[IVTV_DEC_STREAM_TYPE_VOUT];
9025a338c38ced1569a2e67e3c163505cc95429d508Hans Verkuil
903da8ec560e3b4e25d73c64a9e08f9f90ebfbfbf7cHans Verkuil		ivtv_stop_decoding(id, V4L2_DEC_CMD_STOP_TO_BLACK | V4L2_DEC_CMD_STOP_IMMEDIATELY, 0);
9045a338c38ced1569a2e67e3c163505cc95429d508Hans Verkuil
9055a338c38ced1569a2e67e3c163505cc95429d508Hans Verkuil		/* If all output streams are closed, and if the user doesn't have
9062f3a98931f51be6093df7c6cc2633bf238778b7dHans Verkuil		   IVTV_DEC_STREAM_TYPE_VOUT open, then disable CC on TV-out. */
9075a338c38ced1569a2e67e3c163505cc95429d508Hans Verkuil		if (itv->output_mode == OUT_NONE && !test_bit(IVTV_F_S_APPL_IO, &s_vout->s_flags)) {
9082f3a98931f51be6093df7c6cc2633bf238778b7dHans Verkuil			/* disable CC on TV-out */
9092f3a98931f51be6093df7c6cc2633bf238778b7dHans Verkuil			ivtv_disable_cc(itv);
9105a338c38ced1569a2e67e3c163505cc95429d508Hans Verkuil		}
9111a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	} else {
9121a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		ivtv_stop_capture(id, 0);
9131a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	}
9141a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	kfree(id);
9151a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	return 0;
9161a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil}
9171a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
918cdc037817cc15caf931cd3476970860d62f1985cHans Verkuilint ivtv_v4l2_open(struct file *filp)
9191a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{
920914610e8c508224a6fb9fb501ed4bda25b340ba6Ian Armstrong	struct video_device *vdev = video_devdata(filp);
921cdc037817cc15caf931cd3476970860d62f1985cHans Verkuil	struct ivtv_stream *s = video_get_drvdata(vdev);
922baa4072d84e7a2e9954121c826d7bb8f1fb66b38Hans Verkuil	struct ivtv *itv = s->itv;
9231a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	struct ivtv_open_id *item;
924092501936fc128992456a086193746cf34642815Hans Verkuil	int res = 0;
9251a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
9261aa32c2ffd146dddd76babf842e998502f1b993aHans Verkuil	IVTV_DEBUG_FILE("open %s\n", s->name);
927c976bc82339437e840f7dbf0b8c89c09d3fcd75eHans Verkuil
928cdc037817cc15caf931cd3476970860d62f1985cHans Verkuil	if (ivtv_init_on_first_open(itv)) {
929cdc037817cc15caf931cd3476970860d62f1985cHans Verkuil		IVTV_ERR("Failed to initialize on device %s\n",
930cdc037817cc15caf931cd3476970860d62f1985cHans Verkuil			 video_device_node_name(vdev));
931cdc037817cc15caf931cd3476970860d62f1985cHans Verkuil		return -ENXIO;
932cdc037817cc15caf931cd3476970860d62f1985cHans Verkuil	}
933cdc037817cc15caf931cd3476970860d62f1985cHans Verkuil
934914610e8c508224a6fb9fb501ed4bda25b340ba6Ian Armstrong#ifdef CONFIG_VIDEO_ADV_DEBUG
935215659d14f9dbc849ccda1655c94d710f8cc6384Ian Armstrong	/* Unless ivtv_fw_debug is set, error out if firmware dead. */
936914610e8c508224a6fb9fb501ed4bda25b340ba6Ian Armstrong	if (ivtv_fw_debug) {
937914610e8c508224a6fb9fb501ed4bda25b340ba6Ian Armstrong		IVTV_WARN("Opening %s with dead firmware lockout disabled\n",
938914610e8c508224a6fb9fb501ed4bda25b340ba6Ian Armstrong			  video_device_node_name(vdev));
939914610e8c508224a6fb9fb501ed4bda25b340ba6Ian Armstrong		IVTV_WARN("Selected firmware errors will be ignored\n");
940215659d14f9dbc849ccda1655c94d710f8cc6384Ian Armstrong	} else {
941914610e8c508224a6fb9fb501ed4bda25b340ba6Ian Armstrong#else
942215659d14f9dbc849ccda1655c94d710f8cc6384Ian Armstrong	if (1) {
943914610e8c508224a6fb9fb501ed4bda25b340ba6Ian Armstrong#endif
944215659d14f9dbc849ccda1655c94d710f8cc6384Ian Armstrong		res = ivtv_firmware_check(itv, "ivtv_serialized_open");
945215659d14f9dbc849ccda1655c94d710f8cc6384Ian Armstrong		if (res == -EAGAIN)
946215659d14f9dbc849ccda1655c94d710f8cc6384Ian Armstrong			res = ivtv_firmware_check(itv, "ivtv_serialized_open");
947215659d14f9dbc849ccda1655c94d710f8cc6384Ian Armstrong		if (res < 0)
948215659d14f9dbc849ccda1655c94d710f8cc6384Ian Armstrong			return -EIO;
949215659d14f9dbc849ccda1655c94d710f8cc6384Ian Armstrong	}
950914610e8c508224a6fb9fb501ed4bda25b340ba6Ian Armstrong
951baa4072d84e7a2e9954121c826d7bb8f1fb66b38Hans Verkuil	if (s->type == IVTV_DEC_STREAM_TYPE_MPG &&
9521a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		test_bit(IVTV_F_S_CLAIMED, &itv->streams[IVTV_DEC_STREAM_TYPE_YUV].s_flags))
9531a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		return -EBUSY;
9541a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
955baa4072d84e7a2e9954121c826d7bb8f1fb66b38Hans Verkuil	if (s->type == IVTV_DEC_STREAM_TYPE_YUV &&
9561a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		test_bit(IVTV_F_S_CLAIMED, &itv->streams[IVTV_DEC_STREAM_TYPE_MPG].s_flags))
9571a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		return -EBUSY;
9581a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
959baa4072d84e7a2e9954121c826d7bb8f1fb66b38Hans Verkuil	if (s->type == IVTV_DEC_STREAM_TYPE_YUV) {
9601a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		if (read_reg(0x82c) == 0) {
9611a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			IVTV_ERR("Tried to open YUV output device but need to send data to mpeg decoder before it can be used\n");
9621a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil			/* return -ENODEV; */
9631a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		}
9641a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		ivtv_udma_alloc(itv);
9651a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	}
9661a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
9671a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	/* Allocate memory */
968092501936fc128992456a086193746cf34642815Hans Verkuil	item = kzalloc(sizeof(struct ivtv_open_id), GFP_KERNEL);
9691a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	if (NULL == item) {
9701a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		IVTV_DEBUG_WARN("nomem on v4l2 open\n");
9711a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		return -ENOMEM;
9721a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	}
973092501936fc128992456a086193746cf34642815Hans Verkuil	v4l2_fh_init(&item->fh, s->vdev);
9741a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	item->itv = itv;
975baa4072d84e7a2e9954121c826d7bb8f1fb66b38Hans Verkuil	item->type = s->type;
9761a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
977092501936fc128992456a086193746cf34642815Hans Verkuil	filp->private_data = &item->fh;
9783f3edd7c97d0a5ae355aace36000576acbc2f2ccHans Verkuil	v4l2_fh_add(&item->fh);
9791a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
9803f3edd7c97d0a5ae355aace36000576acbc2f2ccHans Verkuil	if (item->type == IVTV_ENC_STREAM_TYPE_RAD &&
9813f3edd7c97d0a5ae355aace36000576acbc2f2ccHans Verkuil			v4l2_fh_is_singular_file(filp)) {
9823562c43be8cfd6e300508d7c33acebf3369eacd3Hans Verkuil		if (!test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) {
9833562c43be8cfd6e300508d7c33acebf3369eacd3Hans Verkuil			if (atomic_read(&itv->capturing) > 0) {
9843562c43be8cfd6e300508d7c33acebf3369eacd3Hans Verkuil				/* switching to radio while capture is
9853562c43be8cfd6e300508d7c33acebf3369eacd3Hans Verkuil				   in progress is not polite */
9863f3edd7c97d0a5ae355aace36000576acbc2f2ccHans Verkuil				v4l2_fh_del(&item->fh);
987092501936fc128992456a086193746cf34642815Hans Verkuil				v4l2_fh_exit(&item->fh);
9883562c43be8cfd6e300508d7c33acebf3369eacd3Hans Verkuil				kfree(item);
9893562c43be8cfd6e300508d7c33acebf3369eacd3Hans Verkuil				return -EBUSY;
9903562c43be8cfd6e300508d7c33acebf3369eacd3Hans Verkuil			}
9913562c43be8cfd6e300508d7c33acebf3369eacd3Hans Verkuil		}
9923562c43be8cfd6e300508d7c33acebf3369eacd3Hans Verkuil		/* Mark that the radio is being used. */
9933562c43be8cfd6e300508d7c33acebf3369eacd3Hans Verkuil		set_bit(IVTV_F_I_RADIO_USER, &itv->i_flags);
9941a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		/* We have the radio */
9951a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		ivtv_mute(itv);
9961a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		/* Switch tuner to radio */
99767ec09fdf5e05d4670b617256c696348b5df080bHans Verkuil		ivtv_call_all(itv, tuner, s_radio);
9981a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		/* Select the correct audio input (i.e. radio tuner) */
9991a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		ivtv_audio_set_io(itv);
100067ec09fdf5e05d4670b617256c696348b5df080bHans Verkuil		if (itv->hw_flags & IVTV_HW_SAA711X) {
10013ff4ad815c5824ab35375d72ea8fe14fb3230daaHans Verkuil			ivtv_call_hw(itv, IVTV_HW_SAA711X, video, s_crystal_freq,
10023ff4ad815c5824ab35375d72ea8fe14fb3230daaHans Verkuil				SAA7115_FREQ_32_11_MHZ, SAA7115_FREQ_FL_APLL);
1003f2100d82b858815848b661d57d7e166341c02e20Hans Verkuil		}
10041a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		/* Done! Unmute and continue. */
10051a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		ivtv_unmute(itv);
10061a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	}
10071a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
10081a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	/* YUV or MPG Decoding Mode? */
1009c240ad00af78228726e6301ad6ffc54d3adce2a0Ian Armstrong	if (s->type == IVTV_DEC_STREAM_TYPE_MPG) {
10101a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		clear_bit(IVTV_F_I_DEC_YUV, &itv->i_flags);
1011c240ad00af78228726e6301ad6ffc54d3adce2a0Ian Armstrong	} else if (s->type == IVTV_DEC_STREAM_TYPE_YUV) {
10121a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		set_bit(IVTV_F_I_DEC_YUV, &itv->i_flags);
1013c240ad00af78228726e6301ad6ffc54d3adce2a0Ian Armstrong		/* For yuv, we need to know the dma size before we start */
1014c240ad00af78228726e6301ad6ffc54d3adce2a0Ian Armstrong		itv->dma_data_req_size =
101577aded6ba51f01335840ce8e18b413067810b68eIan Armstrong				1080 * ((itv->yuv_info.v4l2_src_h + 31) & ~31);
1016c240ad00af78228726e6301ad6ffc54d3adce2a0Ian Armstrong		itv->yuv_info.stream_size = 0;
1017c240ad00af78228726e6301ad6ffc54d3adce2a0Ian Armstrong	}
1018baa4072d84e7a2e9954121c826d7bb8f1fb66b38Hans Verkuil	return 0;
1019baa4072d84e7a2e9954121c826d7bb8f1fb66b38Hans Verkuil}
1020baa4072d84e7a2e9954121c826d7bb8f1fb66b38Hans Verkuil
10211a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilvoid ivtv_mute(struct ivtv *itv)
10221a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{
10231a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	if (atomic_read(&itv->capturing))
10241a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		ivtv_vapi(itv, CX2341X_ENC_MUTE_AUDIO, 1, 1);
10251a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	IVTV_DEBUG_INFO("Mute\n");
10261a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil}
10271a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil
10281a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilvoid ivtv_unmute(struct ivtv *itv)
10291a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{
10301a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	if (atomic_read(&itv->capturing)) {
10313562c43be8cfd6e300508d7c33acebf3369eacd3Hans Verkuil		ivtv_msleep_timeout(100, 0);
10321a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		ivtv_vapi(itv, CX2341X_ENC_MISC, 1, 12);
10331a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil		ivtv_vapi(itv, CX2341X_ENC_MUTE_AUDIO, 1, 0);
10341a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	}
10351a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil	IVTV_DEBUG_INFO("Unmute\n");
10361a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil}
1037