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