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