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