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