1/*
2 *  cx18 file operation functions
3 *
4 *  Derived from ivtv-fileops.c
5 *
6 *  Copyright (C) 2007  Hans Verkuil <hverkuil@xs4all.nl>
7 *  Copyright (C) 2008  Andy Walls <awalls@md.metrocast.net>
8 *
9 *  This program is free software; you can redistribute it and/or modify
10 *  it under the terms of the GNU General Public License as published by
11 *  the Free Software Foundation; either version 2 of the License, or
12 *  (at your option) any later version.
13 *
14 *  This program is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU General Public License for more details.
18 *
19 *  You should have received a copy of the GNU General Public License
20 *  along with this program; if not, write to the Free Software
21 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
22 *  02111-1307  USA
23 */
24
25#include "cx18-driver.h"
26#include "cx18-fileops.h"
27#include "cx18-i2c.h"
28#include "cx18-queue.h"
29#include "cx18-vbi.h"
30#include "cx18-audio.h"
31#include "cx18-mailbox.h"
32#include "cx18-scb.h"
33#include "cx18-streams.h"
34#include "cx18-controls.h"
35#include "cx18-ioctl.h"
36#include "cx18-cards.h"
37#include <media/v4l2-event.h>
38
39/* This function tries to claim the stream for a specific file descriptor.
40   If no one else is using this stream then the stream is claimed and
41   associated VBI and IDX streams are also automatically claimed.
42   Possible error returns: -EBUSY if someone else has claimed
43   the stream or 0 on success. */
44int cx18_claim_stream(struct cx18_open_id *id, int type)
45{
46	struct cx18 *cx = id->cx;
47	struct cx18_stream *s = &cx->streams[type];
48	struct cx18_stream *s_assoc;
49
50	/* Nothing should ever try to directly claim the IDX stream */
51	if (type == CX18_ENC_STREAM_TYPE_IDX) {
52		CX18_WARN("MPEG Index stream cannot be claimed "
53			  "directly, but something tried.\n");
54		return -EINVAL;
55	}
56
57	if (test_and_set_bit(CX18_F_S_CLAIMED, &s->s_flags)) {
58		/* someone already claimed this stream */
59		if (s->id == id->open_id) {
60			/* yes, this file descriptor did. So that's OK. */
61			return 0;
62		}
63		if (s->id == -1 && type == CX18_ENC_STREAM_TYPE_VBI) {
64			/* VBI is handled already internally, now also assign
65			   the file descriptor to this stream for external
66			   reading of the stream. */
67			s->id = id->open_id;
68			CX18_DEBUG_INFO("Start Read VBI\n");
69			return 0;
70		}
71		/* someone else is using this stream already */
72		CX18_DEBUG_INFO("Stream %d is busy\n", type);
73		return -EBUSY;
74	}
75	s->id = id->open_id;
76
77	/*
78	 * CX18_ENC_STREAM_TYPE_MPG needs to claim:
79	 * CX18_ENC_STREAM_TYPE_VBI, if VBI insertion is on for sliced VBI, or
80	 * CX18_ENC_STREAM_TYPE_IDX, if VBI insertion is off for sliced VBI
81	 * (We don't yet fix up MPEG Index entries for our inserted packets).
82	 *
83	 * For all other streams we're done.
84	 */
85	if (type != CX18_ENC_STREAM_TYPE_MPG)
86		return 0;
87
88	s_assoc = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
89	if (cx->vbi.insert_mpeg && !cx18_raw_vbi(cx))
90		s_assoc = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
91	else if (!cx18_stream_enabled(s_assoc))
92		return 0;
93
94	set_bit(CX18_F_S_CLAIMED, &s_assoc->s_flags);
95
96	/* mark that it is used internally */
97	set_bit(CX18_F_S_INTERNAL_USE, &s_assoc->s_flags);
98	return 0;
99}
100EXPORT_SYMBOL(cx18_claim_stream);
101
102/* This function releases a previously claimed stream. It will take into
103   account associated VBI streams. */
104void cx18_release_stream(struct cx18_stream *s)
105{
106	struct cx18 *cx = s->cx;
107	struct cx18_stream *s_assoc;
108
109	s->id = -1;
110	if (s->type == CX18_ENC_STREAM_TYPE_IDX) {
111		/*
112		 * The IDX stream is only used internally, and can
113		 * only be indirectly unclaimed by unclaiming the MPG stream.
114		 */
115		return;
116	}
117
118	if (s->type == CX18_ENC_STREAM_TYPE_VBI &&
119		test_bit(CX18_F_S_INTERNAL_USE, &s->s_flags)) {
120		/* this stream is still in use internally */
121		return;
122	}
123	if (!test_and_clear_bit(CX18_F_S_CLAIMED, &s->s_flags)) {
124		CX18_DEBUG_WARN("Release stream %s not in use!\n", s->name);
125		return;
126	}
127
128	cx18_flush_queues(s);
129
130	/*
131	 * CX18_ENC_STREAM_TYPE_MPG needs to release the
132	 * CX18_ENC_STREAM_TYPE_VBI and/or CX18_ENC_STREAM_TYPE_IDX streams.
133	 *
134	 * For all other streams we're done.
135	 */
136	if (s->type != CX18_ENC_STREAM_TYPE_MPG)
137		return;
138
139	/* Unclaim the associated MPEG Index stream */
140	s_assoc = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
141	if (test_and_clear_bit(CX18_F_S_INTERNAL_USE, &s_assoc->s_flags)) {
142		clear_bit(CX18_F_S_CLAIMED, &s_assoc->s_flags);
143		cx18_flush_queues(s_assoc);
144	}
145
146	/* Unclaim the associated VBI stream */
147	s_assoc = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
148	if (test_and_clear_bit(CX18_F_S_INTERNAL_USE, &s_assoc->s_flags)) {
149		if (s_assoc->id == -1) {
150			/*
151			 * The VBI stream is not still claimed by a file
152			 * descriptor, so completely unclaim it.
153			 */
154			clear_bit(CX18_F_S_CLAIMED, &s_assoc->s_flags);
155			cx18_flush_queues(s_assoc);
156		}
157	}
158}
159EXPORT_SYMBOL(cx18_release_stream);
160
161static void cx18_dualwatch(struct cx18 *cx)
162{
163	struct v4l2_tuner vt;
164	u32 new_stereo_mode;
165	const u32 dual = 0x0200;
166
167	new_stereo_mode = v4l2_ctrl_g_ctrl(cx->cxhdl.audio_mode);
168	memset(&vt, 0, sizeof(vt));
169	cx18_call_all(cx, tuner, g_tuner, &vt);
170	if (vt.audmode == V4L2_TUNER_MODE_LANG1_LANG2 &&
171			(vt.rxsubchans & V4L2_TUNER_SUB_LANG2))
172		new_stereo_mode = dual;
173
174	if (new_stereo_mode == cx->dualwatch_stereo_mode)
175		return;
176
177	CX18_DEBUG_INFO("dualwatch: change stereo flag from 0x%x to 0x%x.\n",
178			   cx->dualwatch_stereo_mode, new_stereo_mode);
179	if (v4l2_ctrl_s_ctrl(cx->cxhdl.audio_mode, new_stereo_mode))
180		CX18_DEBUG_INFO("dualwatch: changing stereo flag failed\n");
181}
182
183
184static struct cx18_mdl *cx18_get_mdl(struct cx18_stream *s, int non_block,
185				     int *err)
186{
187	struct cx18 *cx = s->cx;
188	struct cx18_stream *s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
189	struct cx18_mdl *mdl;
190	DEFINE_WAIT(wait);
191
192	*err = 0;
193	while (1) {
194		if (s->type == CX18_ENC_STREAM_TYPE_MPG) {
195			/* Process pending program updates and VBI data */
196			if (time_after(jiffies, cx->dualwatch_jiffies + msecs_to_jiffies(1000))) {
197				cx->dualwatch_jiffies = jiffies;
198				cx18_dualwatch(cx);
199			}
200			if (test_bit(CX18_F_S_INTERNAL_USE, &s_vbi->s_flags) &&
201			    !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) {
202				while ((mdl = cx18_dequeue(s_vbi,
203							   &s_vbi->q_full))) {
204					/* byteswap and process VBI data */
205					cx18_process_vbi_data(cx, mdl,
206							      s_vbi->type);
207					cx18_stream_put_mdl_fw(s_vbi, mdl);
208				}
209			}
210			mdl = &cx->vbi.sliced_mpeg_mdl;
211			if (mdl->readpos != mdl->bytesused)
212				return mdl;
213		}
214
215		/* do we have new data? */
216		mdl = cx18_dequeue(s, &s->q_full);
217		if (mdl) {
218			if (!test_and_clear_bit(CX18_F_M_NEED_SWAP,
219						&mdl->m_flags))
220				return mdl;
221			if (s->type == CX18_ENC_STREAM_TYPE_MPG)
222				/* byteswap MPG data */
223				cx18_mdl_swap(mdl);
224			else {
225				/* byteswap and process VBI data */
226				cx18_process_vbi_data(cx, mdl, s->type);
227			}
228			return mdl;
229		}
230
231		/* return if end of stream */
232		if (!test_bit(CX18_F_S_STREAMING, &s->s_flags)) {
233			CX18_DEBUG_INFO("EOS %s\n", s->name);
234			return NULL;
235		}
236
237		/* return if file was opened with O_NONBLOCK */
238		if (non_block) {
239			*err = -EAGAIN;
240			return NULL;
241		}
242
243		/* wait for more data to arrive */
244		prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE);
245		/* New buffers might have become available before we were added
246		   to the waitqueue */
247		if (!atomic_read(&s->q_full.depth))
248			schedule();
249		finish_wait(&s->waitq, &wait);
250		if (signal_pending(current)) {
251			/* return if a signal was received */
252			CX18_DEBUG_INFO("User stopped %s\n", s->name);
253			*err = -EINTR;
254			return NULL;
255		}
256	}
257}
258
259static void cx18_setup_sliced_vbi_mdl(struct cx18 *cx)
260{
261	struct cx18_mdl *mdl = &cx->vbi.sliced_mpeg_mdl;
262	struct cx18_buffer *buf = &cx->vbi.sliced_mpeg_buf;
263	int idx = cx->vbi.inserted_frame % CX18_VBI_FRAMES;
264
265	buf->buf = cx->vbi.sliced_mpeg_data[idx];
266	buf->bytesused = cx->vbi.sliced_mpeg_size[idx];
267	buf->readpos = 0;
268
269	mdl->curr_buf = NULL;
270	mdl->bytesused = cx->vbi.sliced_mpeg_size[idx];
271	mdl->readpos = 0;
272}
273
274static size_t cx18_copy_buf_to_user(struct cx18_stream *s,
275	struct cx18_buffer *buf, char __user *ubuf, size_t ucount, bool *stop)
276{
277	struct cx18 *cx = s->cx;
278	size_t len = buf->bytesused - buf->readpos;
279
280	*stop = false;
281	if (len > ucount)
282		len = ucount;
283	if (cx->vbi.insert_mpeg && s->type == CX18_ENC_STREAM_TYPE_MPG &&
284	    !cx18_raw_vbi(cx) && buf != &cx->vbi.sliced_mpeg_buf) {
285		/*
286		 * Try to find a good splice point in the PS, just before
287		 * an MPEG-2 Program Pack start code, and provide only
288		 * up to that point to the user, so it's easy to insert VBI data
289		 * the next time around.
290		 *
291		 * This will not work for an MPEG-2 TS and has only been
292		 * verified by analysis to work for an MPEG-2 PS.  Helen Buus
293		 * pointed out this works for the CX23416 MPEG-2 DVD compatible
294		 * stream, and research indicates both the MPEG 2 SVCD and DVD
295		 * stream types use an MPEG-2 PS container.
296		 */
297		/*
298		 * An MPEG-2 Program Stream (PS) is a series of
299		 * MPEG-2 Program Packs terminated by an
300		 * MPEG Program End Code after the last Program Pack.
301		 * A Program Pack may hold a PS System Header packet and any
302		 * number of Program Elementary Stream (PES) Packets
303		 */
304		const char *start = buf->buf + buf->readpos;
305		const char *p = start + 1;
306		const u8 *q;
307		u8 ch = cx->search_pack_header ? 0xba : 0xe0;
308		int stuffing, i;
309
310		while (start + len > p) {
311			/* Scan for a 0 to find a potential MPEG-2 start code */
312			q = memchr(p, 0, start + len - p);
313			if (q == NULL)
314				break;
315			p = q + 1;
316			/*
317			 * Keep looking if not a
318			 * MPEG-2 Pack header start code:  0x00 0x00 0x01 0xba
319			 * or MPEG-2 video PES start code: 0x00 0x00 0x01 0xe0
320			 */
321			if ((char *)q + 15 >= buf->buf + buf->bytesused ||
322			    q[1] != 0 || q[2] != 1 || q[3] != ch)
323				continue;
324
325			/* If expecting the primary video PES */
326			if (!cx->search_pack_header) {
327				/* Continue if it couldn't be a PES packet */
328				if ((q[6] & 0xc0) != 0x80)
329					continue;
330				/* Check if a PTS or PTS & DTS follow */
331				if (((q[7] & 0xc0) == 0x80 &&  /* PTS only */
332				     (q[9] & 0xf0) == 0x20) || /* PTS only */
333				    ((q[7] & 0xc0) == 0xc0 &&  /* PTS & DTS */
334				     (q[9] & 0xf0) == 0x30)) { /* DTS follows */
335					/* Assume we found the video PES hdr */
336					ch = 0xba; /* next want a Program Pack*/
337					cx->search_pack_header = 1;
338					p = q + 9; /* Skip this video PES hdr */
339				}
340				continue;
341			}
342
343			/* We may have found a Program Pack start code */
344
345			/* Get the count of stuffing bytes & verify them */
346			stuffing = q[13] & 7;
347			/* all stuffing bytes must be 0xff */
348			for (i = 0; i < stuffing; i++)
349				if (q[14 + i] != 0xff)
350					break;
351			if (i == stuffing && /* right number of stuffing bytes*/
352			    (q[4] & 0xc4) == 0x44 && /* marker check */
353			    (q[12] & 3) == 3 &&  /* marker check */
354			    q[14 + stuffing] == 0 && /* PES Pack or Sys Hdr */
355			    q[15 + stuffing] == 0 &&
356			    q[16 + stuffing] == 1) {
357				/* We declare we actually found a Program Pack*/
358				cx->search_pack_header = 0; /* expect vid PES */
359				len = (char *)q - start;
360				cx18_setup_sliced_vbi_mdl(cx);
361				*stop = true;
362				break;
363			}
364		}
365	}
366	if (copy_to_user(ubuf, (u8 *)buf->buf + buf->readpos, len)) {
367		CX18_DEBUG_WARN("copy %zd bytes to user failed for %s\n",
368				len, s->name);
369		return -EFAULT;
370	}
371	buf->readpos += len;
372	if (s->type == CX18_ENC_STREAM_TYPE_MPG &&
373	    buf != &cx->vbi.sliced_mpeg_buf)
374		cx->mpg_data_received += len;
375	return len;
376}
377
378static size_t cx18_copy_mdl_to_user(struct cx18_stream *s,
379		struct cx18_mdl *mdl, char __user *ubuf, size_t ucount)
380{
381	size_t tot_written = 0;
382	int rc;
383	bool stop = false;
384
385	if (mdl->curr_buf == NULL)
386		mdl->curr_buf = list_first_entry(&mdl->buf_list,
387						 struct cx18_buffer, list);
388
389	if (list_entry_is_past_end(mdl->curr_buf, &mdl->buf_list, list)) {
390		/*
391		 * For some reason we've exhausted the buffers, but the MDL
392		 * object still said some data was unread.
393		 * Fix that and bail out.
394		 */
395		mdl->readpos = mdl->bytesused;
396		return 0;
397	}
398
399	list_for_each_entry_from(mdl->curr_buf, &mdl->buf_list, list) {
400
401		if (mdl->curr_buf->readpos >= mdl->curr_buf->bytesused)
402			continue;
403
404		rc = cx18_copy_buf_to_user(s, mdl->curr_buf, ubuf + tot_written,
405					   ucount - tot_written, &stop);
406		if (rc < 0)
407			return rc;
408		mdl->readpos += rc;
409		tot_written += rc;
410
411		if (stop ||	/* Forced stopping point for VBI insertion */
412		    tot_written >= ucount ||	/* Reader request statisfied */
413		    mdl->curr_buf->readpos < mdl->curr_buf->bytesused ||
414		    mdl->readpos >= mdl->bytesused) /* MDL buffers drained */
415			break;
416	}
417	return tot_written;
418}
419
420static ssize_t cx18_read(struct cx18_stream *s, char __user *ubuf,
421		size_t tot_count, int non_block)
422{
423	struct cx18 *cx = s->cx;
424	size_t tot_written = 0;
425	int single_frame = 0;
426
427	if (atomic_read(&cx->ana_capturing) == 0 && s->id == -1) {
428		/* shouldn't happen */
429		CX18_DEBUG_WARN("Stream %s not initialized before read\n",
430				s->name);
431		return -EIO;
432	}
433
434	/* Each VBI buffer is one frame, the v4l2 API says that for VBI the
435	   frames should arrive one-by-one, so make sure we never output more
436	   than one VBI frame at a time */
437	if (s->type == CX18_ENC_STREAM_TYPE_VBI && !cx18_raw_vbi(cx))
438		single_frame = 1;
439
440	for (;;) {
441		struct cx18_mdl *mdl;
442		int rc;
443
444		mdl = cx18_get_mdl(s, non_block, &rc);
445		/* if there is no data available... */
446		if (mdl == NULL) {
447			/* if we got data, then return that regardless */
448			if (tot_written)
449				break;
450			/* EOS condition */
451			if (rc == 0) {
452				clear_bit(CX18_F_S_STREAMOFF, &s->s_flags);
453				clear_bit(CX18_F_S_APPL_IO, &s->s_flags);
454				cx18_release_stream(s);
455			}
456			/* set errno */
457			return rc;
458		}
459
460		rc = cx18_copy_mdl_to_user(s, mdl, ubuf + tot_written,
461				tot_count - tot_written);
462
463		if (mdl != &cx->vbi.sliced_mpeg_mdl) {
464			if (mdl->readpos == mdl->bytesused)
465				cx18_stream_put_mdl_fw(s, mdl);
466			else
467				cx18_push(s, mdl, &s->q_full);
468		} else if (mdl->readpos == mdl->bytesused) {
469			int idx = cx->vbi.inserted_frame % CX18_VBI_FRAMES;
470
471			cx->vbi.sliced_mpeg_size[idx] = 0;
472			cx->vbi.inserted_frame++;
473			cx->vbi_data_inserted += mdl->bytesused;
474		}
475		if (rc < 0)
476			return rc;
477		tot_written += rc;
478
479		if (tot_written == tot_count || single_frame)
480			break;
481	}
482	return tot_written;
483}
484
485static ssize_t cx18_read_pos(struct cx18_stream *s, char __user *ubuf,
486		size_t count, loff_t *pos, int non_block)
487{
488	ssize_t rc = count ? cx18_read(s, ubuf, count, non_block) : 0;
489	struct cx18 *cx = s->cx;
490
491	CX18_DEBUG_HI_FILE("read %zd from %s, got %zd\n", count, s->name, rc);
492	if (rc > 0)
493		pos += rc;
494	return rc;
495}
496
497int cx18_start_capture(struct cx18_open_id *id)
498{
499	struct cx18 *cx = id->cx;
500	struct cx18_stream *s = &cx->streams[id->type];
501	struct cx18_stream *s_vbi;
502	struct cx18_stream *s_idx;
503
504	if (s->type == CX18_ENC_STREAM_TYPE_RAD) {
505		/* you cannot read from these stream types. */
506		return -EPERM;
507	}
508
509	/* Try to claim this stream. */
510	if (cx18_claim_stream(id, s->type))
511		return -EBUSY;
512
513	/* If capture is already in progress, then we also have to
514	   do nothing extra. */
515	if (test_bit(CX18_F_S_STREAMOFF, &s->s_flags) ||
516	    test_and_set_bit(CX18_F_S_STREAMING, &s->s_flags)) {
517		set_bit(CX18_F_S_APPL_IO, &s->s_flags);
518		return 0;
519	}
520
521	/* Start associated VBI or IDX stream capture if required */
522	s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
523	s_idx = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
524	if (s->type == CX18_ENC_STREAM_TYPE_MPG) {
525		/*
526		 * The VBI and IDX streams should have been claimed
527		 * automatically, if for internal use, when the MPG stream was
528		 * claimed.  We only need to start these streams capturing.
529		 */
530		if (test_bit(CX18_F_S_INTERNAL_USE, &s_idx->s_flags) &&
531		    !test_and_set_bit(CX18_F_S_STREAMING, &s_idx->s_flags)) {
532			if (cx18_start_v4l2_encode_stream(s_idx)) {
533				CX18_DEBUG_WARN("IDX capture start failed\n");
534				clear_bit(CX18_F_S_STREAMING, &s_idx->s_flags);
535				goto start_failed;
536			}
537			CX18_DEBUG_INFO("IDX capture started\n");
538		}
539		if (test_bit(CX18_F_S_INTERNAL_USE, &s_vbi->s_flags) &&
540		    !test_and_set_bit(CX18_F_S_STREAMING, &s_vbi->s_flags)) {
541			if (cx18_start_v4l2_encode_stream(s_vbi)) {
542				CX18_DEBUG_WARN("VBI capture start failed\n");
543				clear_bit(CX18_F_S_STREAMING, &s_vbi->s_flags);
544				goto start_failed;
545			}
546			CX18_DEBUG_INFO("VBI insertion started\n");
547		}
548	}
549
550	/* Tell the card to start capturing */
551	if (!cx18_start_v4l2_encode_stream(s)) {
552		/* We're done */
553		set_bit(CX18_F_S_APPL_IO, &s->s_flags);
554		/* Resume a possibly paused encoder */
555		if (test_and_clear_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags))
556			cx18_vapi(cx, CX18_CPU_CAPTURE_PAUSE, 1, s->handle);
557		return 0;
558	}
559
560start_failed:
561	CX18_DEBUG_WARN("Failed to start capturing for stream %s\n", s->name);
562
563	/*
564	 * The associated VBI and IDX streams for internal use are released
565	 * automatically when the MPG stream is released.  We only need to stop
566	 * the associated stream.
567	 */
568	if (s->type == CX18_ENC_STREAM_TYPE_MPG) {
569		/* Stop the IDX stream which is always for internal use */
570		if (test_bit(CX18_F_S_STREAMING, &s_idx->s_flags)) {
571			cx18_stop_v4l2_encode_stream(s_idx, 0);
572			clear_bit(CX18_F_S_STREAMING, &s_idx->s_flags);
573		}
574		/* Stop the VBI stream, if only running for internal use */
575		if (test_bit(CX18_F_S_STREAMING, &s_vbi->s_flags) &&
576		    !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) {
577			cx18_stop_v4l2_encode_stream(s_vbi, 0);
578			clear_bit(CX18_F_S_STREAMING, &s_vbi->s_flags);
579		}
580	}
581	clear_bit(CX18_F_S_STREAMING, &s->s_flags);
582	cx18_release_stream(s); /* Also releases associated streams */
583	return -EIO;
584}
585
586ssize_t cx18_v4l2_read(struct file *filp, char __user *buf, size_t count,
587		loff_t *pos)
588{
589	struct cx18_open_id *id = file2id(filp);
590	struct cx18 *cx = id->cx;
591	struct cx18_stream *s = &cx->streams[id->type];
592	int rc;
593
594	CX18_DEBUG_HI_FILE("read %zd bytes from %s\n", count, s->name);
595
596	mutex_lock(&cx->serialize_lock);
597	rc = cx18_start_capture(id);
598	mutex_unlock(&cx->serialize_lock);
599	if (rc)
600		return rc;
601
602	if ((s->vb_type == V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
603		(id->type == CX18_ENC_STREAM_TYPE_YUV)) {
604		return videobuf_read_stream(&s->vbuf_q, buf, count, pos, 0,
605			filp->f_flags & O_NONBLOCK);
606	}
607
608	return cx18_read_pos(s, buf, count, pos, filp->f_flags & O_NONBLOCK);
609}
610
611unsigned int cx18_v4l2_enc_poll(struct file *filp, poll_table *wait)
612{
613	unsigned long req_events = poll_requested_events(wait);
614	struct cx18_open_id *id = file2id(filp);
615	struct cx18 *cx = id->cx;
616	struct cx18_stream *s = &cx->streams[id->type];
617	int eof = test_bit(CX18_F_S_STREAMOFF, &s->s_flags);
618	unsigned res = 0;
619
620	/* Start a capture if there is none */
621	if (!eof && !test_bit(CX18_F_S_STREAMING, &s->s_flags) &&
622			(req_events & (POLLIN | POLLRDNORM))) {
623		int rc;
624
625		mutex_lock(&cx->serialize_lock);
626		rc = cx18_start_capture(id);
627		mutex_unlock(&cx->serialize_lock);
628		if (rc) {
629			CX18_DEBUG_INFO("Could not start capture for %s (%d)\n",
630					s->name, rc);
631			return POLLERR;
632		}
633		CX18_DEBUG_FILE("Encoder poll started capture\n");
634	}
635
636	if ((s->vb_type == V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
637		(id->type == CX18_ENC_STREAM_TYPE_YUV)) {
638		int videobuf_poll = videobuf_poll_stream(filp, &s->vbuf_q, wait);
639
640		if (v4l2_event_pending(&id->fh))
641			res |= POLLPRI;
642                if (eof && videobuf_poll == POLLERR)
643			return res | POLLHUP;
644		return res | videobuf_poll;
645	}
646
647	/* add stream's waitq to the poll list */
648	CX18_DEBUG_HI_FILE("Encoder poll\n");
649	if (v4l2_event_pending(&id->fh))
650		res |= POLLPRI;
651	else
652		poll_wait(filp, &s->waitq, wait);
653
654	if (atomic_read(&s->q_full.depth))
655		return res | POLLIN | POLLRDNORM;
656	if (eof)
657		return res | POLLHUP;
658	return res;
659}
660
661int cx18_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
662{
663	struct cx18_open_id *id = file->private_data;
664	struct cx18 *cx = id->cx;
665	struct cx18_stream *s = &cx->streams[id->type];
666	int eof = test_bit(CX18_F_S_STREAMOFF, &s->s_flags);
667
668	if ((s->vb_type == V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
669		(id->type == CX18_ENC_STREAM_TYPE_YUV)) {
670
671		/* Start a capture if there is none */
672		if (!eof && !test_bit(CX18_F_S_STREAMING, &s->s_flags)) {
673			int rc;
674
675			mutex_lock(&cx->serialize_lock);
676			rc = cx18_start_capture(id);
677			mutex_unlock(&cx->serialize_lock);
678			if (rc) {
679				CX18_DEBUG_INFO(
680					"Could not start capture for %s (%d)\n",
681					s->name, rc);
682				return -EINVAL;
683			}
684			CX18_DEBUG_FILE("Encoder mmap started capture\n");
685		}
686
687		return videobuf_mmap_mapper(&s->vbuf_q, vma);
688	}
689
690	return -EINVAL;
691}
692
693void cx18_vb_timeout(unsigned long data)
694{
695	struct cx18_stream *s = (struct cx18_stream *)data;
696	struct cx18_videobuf_buffer *buf;
697	unsigned long flags;
698
699	/* Return all of the buffers in error state, so the vbi/vid inode
700	 * can return from blocking.
701	 */
702	spin_lock_irqsave(&s->vb_lock, flags);
703	while (!list_empty(&s->vb_capture)) {
704		buf = list_entry(s->vb_capture.next,
705			struct cx18_videobuf_buffer, vb.queue);
706		list_del(&buf->vb.queue);
707		buf->vb.state = VIDEOBUF_ERROR;
708		wake_up(&buf->vb.done);
709	}
710	spin_unlock_irqrestore(&s->vb_lock, flags);
711}
712
713void cx18_stop_capture(struct cx18_open_id *id, int gop_end)
714{
715	struct cx18 *cx = id->cx;
716	struct cx18_stream *s = &cx->streams[id->type];
717	struct cx18_stream *s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
718	struct cx18_stream *s_idx = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
719
720	CX18_DEBUG_IOCTL("close() of %s\n", s->name);
721
722	/* 'Unclaim' this stream */
723
724	/* Stop capturing */
725	if (test_bit(CX18_F_S_STREAMING, &s->s_flags)) {
726		CX18_DEBUG_INFO("close stopping capture\n");
727		if (id->type == CX18_ENC_STREAM_TYPE_MPG) {
728			/* Stop internal use associated VBI and IDX streams */
729			if (test_bit(CX18_F_S_STREAMING, &s_vbi->s_flags) &&
730			    !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) {
731				CX18_DEBUG_INFO("close stopping embedded VBI "
732						"capture\n");
733				cx18_stop_v4l2_encode_stream(s_vbi, 0);
734			}
735			if (test_bit(CX18_F_S_STREAMING, &s_idx->s_flags)) {
736				CX18_DEBUG_INFO("close stopping IDX capture\n");
737				cx18_stop_v4l2_encode_stream(s_idx, 0);
738			}
739		}
740		if (id->type == CX18_ENC_STREAM_TYPE_VBI &&
741		    test_bit(CX18_F_S_INTERNAL_USE, &s->s_flags))
742			/* Also used internally, don't stop capturing */
743			s->id = -1;
744		else
745			cx18_stop_v4l2_encode_stream(s, gop_end);
746	}
747	if (!gop_end) {
748		clear_bit(CX18_F_S_APPL_IO, &s->s_flags);
749		clear_bit(CX18_F_S_STREAMOFF, &s->s_flags);
750		cx18_release_stream(s);
751	}
752}
753
754int cx18_v4l2_close(struct file *filp)
755{
756	struct v4l2_fh *fh = filp->private_data;
757	struct cx18_open_id *id = fh2id(fh);
758	struct cx18 *cx = id->cx;
759	struct cx18_stream *s = &cx->streams[id->type];
760
761	CX18_DEBUG_IOCTL("close() of %s\n", s->name);
762
763	mutex_lock(&cx->serialize_lock);
764	/* Stop radio */
765	if (id->type == CX18_ENC_STREAM_TYPE_RAD &&
766			v4l2_fh_is_singular_file(filp)) {
767		/* Closing radio device, return to TV mode */
768		cx18_mute(cx);
769		/* Mark that the radio is no longer in use */
770		clear_bit(CX18_F_I_RADIO_USER, &cx->i_flags);
771		/* Switch tuner to TV */
772		cx18_call_all(cx, video, s_std, cx->std);
773		/* Select correct audio input (i.e. TV tuner or Line in) */
774		cx18_audio_set_io(cx);
775		if (atomic_read(&cx->ana_capturing) > 0) {
776			/* Undo video mute */
777			cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2, s->handle,
778			    (v4l2_ctrl_g_ctrl(cx->cxhdl.video_mute) |
779			    (v4l2_ctrl_g_ctrl(cx->cxhdl.video_mute_yuv) << 8)));
780		}
781		/* Done! Unmute and continue. */
782		cx18_unmute(cx);
783	}
784
785	v4l2_fh_del(fh);
786	v4l2_fh_exit(fh);
787
788	/* 'Unclaim' this stream */
789	if (s->id == id->open_id)
790		cx18_stop_capture(id, 0);
791	kfree(id);
792	mutex_unlock(&cx->serialize_lock);
793	return 0;
794}
795
796static int cx18_serialized_open(struct cx18_stream *s, struct file *filp)
797{
798	struct cx18 *cx = s->cx;
799	struct cx18_open_id *item;
800
801	CX18_DEBUG_FILE("open %s\n", s->name);
802
803	/* Allocate memory */
804	item = kzalloc(sizeof(struct cx18_open_id), GFP_KERNEL);
805	if (NULL == item) {
806		CX18_DEBUG_WARN("nomem on v4l2 open\n");
807		return -ENOMEM;
808	}
809	v4l2_fh_init(&item->fh, &s->video_dev);
810
811	item->cx = cx;
812	item->type = s->type;
813
814	item->open_id = cx->open_id++;
815	filp->private_data = &item->fh;
816	v4l2_fh_add(&item->fh);
817
818	if (item->type == CX18_ENC_STREAM_TYPE_RAD &&
819			v4l2_fh_is_singular_file(filp)) {
820		if (!test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) {
821			if (atomic_read(&cx->ana_capturing) > 0) {
822				/* switching to radio while capture is
823				   in progress is not polite */
824				v4l2_fh_del(&item->fh);
825				v4l2_fh_exit(&item->fh);
826				kfree(item);
827				return -EBUSY;
828			}
829		}
830
831		/* Mark that the radio is being used. */
832		set_bit(CX18_F_I_RADIO_USER, &cx->i_flags);
833		/* We have the radio */
834		cx18_mute(cx);
835		/* Switch tuner to radio */
836		cx18_call_all(cx, tuner, s_radio);
837		/* Select the correct audio input (i.e. radio tuner) */
838		cx18_audio_set_io(cx);
839		/* Done! Unmute and continue. */
840		cx18_unmute(cx);
841	}
842	return 0;
843}
844
845int cx18_v4l2_open(struct file *filp)
846{
847	int res;
848	struct video_device *video_dev = video_devdata(filp);
849	struct cx18_stream *s = video_get_drvdata(video_dev);
850	struct cx18 *cx = s->cx;
851
852	mutex_lock(&cx->serialize_lock);
853	if (cx18_init_on_first_open(cx)) {
854		CX18_ERR("Failed to initialize on %s\n",
855			 video_device_node_name(video_dev));
856		mutex_unlock(&cx->serialize_lock);
857		return -ENXIO;
858	}
859	res = cx18_serialized_open(s, filp);
860	mutex_unlock(&cx->serialize_lock);
861	return res;
862}
863
864void cx18_mute(struct cx18 *cx)
865{
866	u32 h;
867	if (atomic_read(&cx->ana_capturing)) {
868		h = cx18_find_handle(cx);
869		if (h != CX18_INVALID_TASK_HANDLE)
870			cx18_vapi(cx, CX18_CPU_SET_AUDIO_MUTE, 2, h, 1);
871		else
872			CX18_ERR("Can't find valid task handle for mute\n");
873	}
874	CX18_DEBUG_INFO("Mute\n");
875}
876
877void cx18_unmute(struct cx18 *cx)
878{
879	u32 h;
880	if (atomic_read(&cx->ana_capturing)) {
881		h = cx18_find_handle(cx);
882		if (h != CX18_INVALID_TASK_HANDLE) {
883			cx18_msleep_timeout(100, 0);
884			cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 2, h, 12);
885			cx18_vapi(cx, CX18_CPU_SET_AUDIO_MUTE, 2, h, 0);
886		} else
887			CX18_ERR("Can't find valid task handle for unmute\n");
888	}
889	CX18_DEBUG_INFO("Unmute\n");
890}
891