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. */
cx18_claim_stream(struct cx18_open_id * id,int type)44 int 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 }
100 EXPORT_SYMBOL(cx18_claim_stream);
101
102 /* This function releases a previously claimed stream. It will take into
103 account associated VBI streams. */
cx18_release_stream(struct cx18_stream * s)104 void 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 }
159 EXPORT_SYMBOL(cx18_release_stream);
160
cx18_dualwatch(struct cx18 * cx)161 static 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
cx18_get_mdl(struct cx18_stream * s,int non_block,int * err)184 static 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
cx18_setup_sliced_vbi_mdl(struct cx18 * cx)259 static 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
cx18_copy_buf_to_user(struct cx18_stream * s,struct cx18_buffer * buf,char __user * ubuf,size_t ucount,bool * stop)274 static 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
cx18_copy_mdl_to_user(struct cx18_stream * s,struct cx18_mdl * mdl,char __user * ubuf,size_t ucount)378 static 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
cx18_read(struct cx18_stream * s,char __user * ubuf,size_t tot_count,int non_block)420 static 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
cx18_read_pos(struct cx18_stream * s,char __user * ubuf,size_t count,loff_t * pos,int non_block)485 static 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
cx18_start_capture(struct cx18_open_id * id)497 int 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
560 start_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
cx18_v4l2_read(struct file * filp,char __user * buf,size_t count,loff_t * pos)586 ssize_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
cx18_v4l2_enc_poll(struct file * filp,poll_table * wait)611 unsigned 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
cx18_v4l2_mmap(struct file * file,struct vm_area_struct * vma)661 int 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
cx18_vb_timeout(unsigned long data)693 void 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
cx18_stop_capture(struct cx18_open_id * id,int gop_end)713 void 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
cx18_v4l2_close(struct file * filp)754 int 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
cx18_serialized_open(struct cx18_stream * s,struct file * filp)796 static 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
cx18_v4l2_open(struct file * filp)845 int 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
cx18_mute(struct cx18 * cx)864 void 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
cx18_unmute(struct cx18 * cx)877 void 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