]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blame - drivers/media/pci/cx18/cx18-fileops.c
UBUNTU: Ubuntu-5.15.0-39.42
[mirror_ubuntu-jammy-kernel.git] / drivers / media / pci / cx18 / cx18-fileops.c
CommitLineData
c942fddf 1// SPDX-License-Identifier: GPL-2.0-or-later
1c1e45d1
HV
2/*
3 * cx18 file operation functions
4 *
5 * Derived from ivtv-fileops.c
6 *
7 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
6afdeaf8 8 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net>
1c1e45d1
HV
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"
eaa80c44 23#include <media/v4l2-event.h>
1c1e45d1
HV
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
79f3e960 27 associated VBI and IDX streams are also automatically claimed.
1c1e45d1
HV
28 Possible error returns: -EBUSY if someone else has claimed
29 the stream or 0 on success. */
8ef22f79 30int cx18_claim_stream(struct cx18_open_id *id, int type)
1c1e45d1
HV
31{
32 struct cx18 *cx = id->cx;
33 struct cx18_stream *s = &cx->streams[type];
79f3e960
AW
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) {
6beb1388 38 CX18_WARN("MPEG Index stream cannot be claimed directly, but something tried.\n");
79f3e960
AW
39 return -EINVAL;
40 }
1c1e45d1
HV
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
79f3e960
AW
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))
1c1e45d1 77 return 0;
1c1e45d1 78
79f3e960 79 set_bit(CX18_F_S_CLAIMED, &s_assoc->s_flags);
1c1e45d1
HV
80
81 /* mark that it is used internally */
79f3e960 82 set_bit(CX18_F_S_INTERNAL_USE, &s_assoc->s_flags);
1c1e45d1
HV
83 return 0;
84}
8ef22f79 85EXPORT_SYMBOL(cx18_claim_stream);
1c1e45d1
HV
86
87/* This function releases a previously claimed stream. It will take into
88 account associated VBI streams. */
8ef22f79 89void cx18_release_stream(struct cx18_stream *s)
1c1e45d1
HV
90{
91 struct cx18 *cx = s->cx;
79f3e960 92 struct cx18_stream *s_assoc;
1c1e45d1
HV
93
94 s->id = -1;
79f3e960
AW
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
1c1e45d1
HV
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
79f3e960
AW
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)
1c1e45d1
HV
122 return;
123
79f3e960
AW
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);
1c1e45d1 129 }
79f3e960
AW
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 }
1c1e45d1 142 }
1c1e45d1 143}
8ef22f79 144EXPORT_SYMBOL(cx18_release_stream);
1c1e45d1
HV
145
146static void cx18_dualwatch(struct cx18 *cx)
147{
148 struct v4l2_tuner vt;
0d82fe80 149 u32 new_stereo_mode;
0d82fe80 150 const u32 dual = 0x0200;
1c1e45d1 151
a75b9be1 152 new_stereo_mode = v4l2_ctrl_g_ctrl(cx->cxhdl.audio_mode);
1c1e45d1 153 memset(&vt, 0, sizeof(vt));
ff2a2001 154 cx18_call_all(cx, tuner, g_tuner, &vt);
1c1e45d1
HV
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
a75b9be1
HV
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");
1c1e45d1
HV
166}
167
168
52fcb3ec
AW
169static struct cx18_mdl *cx18_get_mdl(struct cx18_stream *s, int non_block,
170 int *err)
1c1e45d1
HV
171{
172 struct cx18 *cx = s->cx;
173 struct cx18_stream *s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
52fcb3ec 174 struct cx18_mdl *mdl;
1c1e45d1
HV
175 DEFINE_WAIT(wait);
176
177 *err = 0;
178 while (1) {
179 if (s->type == CX18_ENC_STREAM_TYPE_MPG) {
9bff2d61 180 /* Process pending program updates and VBI data */
1c1e45d1
HV
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)) {
52fcb3ec
AW
187 while ((mdl = cx18_dequeue(s_vbi,
188 &s_vbi->q_full))) {
1c1e45d1 189 /* byteswap and process VBI data */
52fcb3ec 190 cx18_process_vbi_data(cx, mdl,
af009cf6 191 s_vbi->type);
52fcb3ec 192 cx18_stream_put_mdl_fw(s_vbi, mdl);
1c1e45d1
HV
193 }
194 }
52fcb3ec
AW
195 mdl = &cx->vbi.sliced_mpeg_mdl;
196 if (mdl->readpos != mdl->bytesused)
197 return mdl;
1c1e45d1
HV
198 }
199
1c1e45d1 200 /* do we have new data? */
52fcb3ec
AW
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;
1c1e45d1
HV
206 if (s->type == CX18_ENC_STREAM_TYPE_MPG)
207 /* byteswap MPG data */
52fcb3ec 208 cx18_mdl_swap(mdl);
1c1e45d1
HV
209 else {
210 /* byteswap and process VBI data */
52fcb3ec 211 cx18_process_vbi_data(cx, mdl, s->type);
1c1e45d1 212 }
52fcb3ec 213 return mdl;
1c1e45d1
HV
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 */
c37b11bf 232 if (!atomic_read(&s->q_full.depth))
1c1e45d1
HV
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
52fcb3ec 244static void cx18_setup_sliced_vbi_mdl(struct cx18 *cx)
1c1e45d1 245{
52fcb3ec
AW
246 struct cx18_mdl *mdl = &cx->vbi.sliced_mpeg_mdl;
247 struct cx18_buffer *buf = &cx->vbi.sliced_mpeg_buf;
1c1e45d1
HV
248 int idx = cx->vbi.inserted_frame % CX18_VBI_FRAMES;
249
52fcb3ec
AW
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;
1c1e45d1
HV
257}
258
259static size_t cx18_copy_buf_to_user(struct cx18_stream *s,
52fcb3ec 260 struct cx18_buffer *buf, char __user *ubuf, size_t ucount, bool *stop)
1c1e45d1
HV
261{
262 struct cx18 *cx = s->cx;
263 size_t len = buf->bytesused - buf->readpos;
264
52fcb3ec 265 *stop = false;
1c1e45d1
HV
266 if (len > ucount)
267 len = ucount;
268 if (cx->vbi.insert_mpeg && s->type == CX18_ENC_STREAM_TYPE_MPG &&
dd073434 269 !cx18_raw_vbi(cx) && buf != &cx->vbi.sliced_mpeg_buf) {
302df970
AW
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.
0c629252
AW
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.
302df970 281 */
302df970
AW
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 */
1c1e45d1
HV
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) {
302df970 296 /* Scan for a 0 to find a potential MPEG-2 start code */
1c1e45d1
HV
297 q = memchr(p, 0, start + len - p);
298 if (q == NULL)
299 break;
300 p = q + 1;
302df970
AW
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 */
1c1e45d1
HV
306 if ((char *)q + 15 >= buf->buf + buf->bytesused ||
307 q[1] != 0 || q[2] != 1 || q[3] != ch)
308 continue;
302df970
AW
309
310 /* If expecting the primary video PES */
1c1e45d1 311 if (!cx->search_pack_header) {
302df970 312 /* Continue if it couldn't be a PES packet */
1c1e45d1
HV
313 if ((q[6] & 0xc0) != 0x80)
314 continue;
302df970
AW
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*/
1c1e45d1 322 cx->search_pack_header = 1;
302df970 323 p = q + 9; /* Skip this video PES hdr */
1c1e45d1
HV
324 }
325 continue;
326 }
302df970
AW
327
328 /* We may have found a Program Pack start code */
329
330 /* Get the count of stuffing bytes & verify them */
1c1e45d1
HV
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;
302df970
AW
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 */
1c1e45d1
HV
340 q[15 + stuffing] == 0 &&
341 q[16 + stuffing] == 1) {
302df970
AW
342 /* We declare we actually found a Program Pack*/
343 cx->search_pack_header = 0; /* expect vid PES */
1c1e45d1 344 len = (char *)q - start;
52fcb3ec
AW
345 cx18_setup_sliced_vbi_mdl(cx);
346 *stop = true;
1c1e45d1
HV
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
52fcb3ec
AW
363static 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 */
16790554 397 tot_written >= ucount || /* Reader request satisfied */
52fcb3ec
AW
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
1c1e45d1
HV
405static 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
31554ae5 412 if (atomic_read(&cx->ana_capturing) == 0 && s->id == -1) {
1c1e45d1
HV
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 */
dd073434 422 if (s->type == CX18_ENC_STREAM_TYPE_VBI && !cx18_raw_vbi(cx))
1c1e45d1
HV
423 single_frame = 1;
424
425 for (;;) {
52fcb3ec 426 struct cx18_mdl *mdl;
1c1e45d1
HV
427 int rc;
428
52fcb3ec 429 mdl = cx18_get_mdl(s, non_block, &rc);
1c1e45d1 430 /* if there is no data available... */
52fcb3ec 431 if (mdl == NULL) {
1c1e45d1
HV
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
52fcb3ec 445 rc = cx18_copy_mdl_to_user(s, mdl, ubuf + tot_written,
1c1e45d1
HV
446 tot_count - tot_written);
447
52fcb3ec
AW
448 if (mdl != &cx->vbi.sliced_mpeg_mdl) {
449 if (mdl->readpos == mdl->bytesused)
450 cx18_stream_put_mdl_fw(s, mdl);
66c2a6b0 451 else
52fcb3ec
AW
452 cx18_push(s, mdl, &s->q_full);
453 } else if (mdl->readpos == mdl->bytesused) {
1c1e45d1
HV
454 int idx = cx->vbi.inserted_frame % CX18_VBI_FRAMES;
455
456 cx->vbi.sliced_mpeg_size[idx] = 0;
457 cx->vbi.inserted_frame++;
52fcb3ec 458 cx->vbi_data_inserted += mdl->bytesused;
1c1e45d1
HV
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
470static 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)
7afb0df5 478 *pos += rc;
1c1e45d1
HV
479 return rc;
480}
481
482int 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;
79f3e960 487 struct cx18_stream *s_idx;
1c1e45d1
HV
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
79f3e960 506 /* Start associated VBI or IDX stream capture if required */
1c1e45d1 507 s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
79f3e960
AW
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");
1c1e45d1 532 }
1c1e45d1
HV
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
79f3e960 545start_failed:
1c1e45d1
HV
546 CX18_DEBUG_WARN("Failed to start capturing for stream %s\n", s->name);
547
79f3e960
AW
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 }
1c1e45d1
HV
565 }
566 clear_bit(CX18_F_S_STREAMING, &s->s_flags);
79f3e960 567 cx18_release_stream(s); /* Also releases associated streams */
1c1e45d1
HV
568 return -EIO;
569}
570
571ssize_t cx18_v4l2_read(struct file *filp, char __user *buf, size_t count,
572 loff_t *pos)
573{
0b5f265a 574 struct cx18_open_id *id = file2id(filp);
1c1e45d1
HV
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;
b7101de3 586
1bf5842f 587 if ((s->vb_type == V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
b7101de3 588 (id->type == CX18_ENC_STREAM_TYPE_YUV)) {
1bf5842f 589 return videobuf_read_stream(&s->vbuf_q, buf, count, pos, 0,
b7101de3
ST
590 filp->f_flags & O_NONBLOCK);
591 }
592
1c1e45d1
HV
593 return cx18_read_pos(s, buf, count, pos, filp->f_flags & O_NONBLOCK);
594}
595
c23e0cb8 596__poll_t cx18_v4l2_enc_poll(struct file *filp, poll_table *wait)
1c1e45d1 597{
01699437 598 __poll_t req_events = poll_requested_events(wait);
0b5f265a 599 struct cx18_open_id *id = file2id(filp);
1c1e45d1
HV
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);
c23e0cb8 603 __poll_t res = 0;
1c1e45d1
HV
604
605 /* Start a capture if there is none */
eaa80c44 606 if (!eof && !test_bit(CX18_F_S_STREAMING, &s->s_flags) &&
a9a08845 607 (req_events & (EPOLLIN | EPOLLRDNORM))) {
1c1e45d1
HV
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);
a9a08845 616 return EPOLLERR;
1c1e45d1
HV
617 }
618 CX18_DEBUG_FILE("Encoder poll started capture\n");
619 }
620
1bf5842f 621 if ((s->vb_type == V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
b7101de3 622 (id->type == CX18_ENC_STREAM_TYPE_YUV)) {
c23e0cb8 623 __poll_t videobuf_poll = videobuf_poll_stream(filp, &s->vbuf_q, wait);
eaa80c44
HV
624
625 if (v4l2_event_pending(&id->fh))
a9a08845
LT
626 res |= EPOLLPRI;
627 if (eof && videobuf_poll == EPOLLERR)
628 return res | EPOLLHUP;
eaa80c44 629 return res | videobuf_poll;
b7101de3
ST
630 }
631
1c1e45d1
HV
632 /* add stream's waitq to the poll list */
633 CX18_DEBUG_HI_FILE("Encoder poll\n");
eaa80c44 634 if (v4l2_event_pending(&id->fh))
a9a08845 635 res |= EPOLLPRI;
eaa80c44
HV
636 else
637 poll_wait(filp, &s->waitq, wait);
1c1e45d1 638
c37b11bf 639 if (atomic_read(&s->q_full.depth))
a9a08845 640 return res | EPOLLIN | EPOLLRDNORM;
1c1e45d1 641 if (eof)
a9a08845 642 return res | EPOLLHUP;
eaa80c44 643 return res;
1c1e45d1
HV
644}
645
b7101de3
ST
646int 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
1bf5842f 653 if ((s->vb_type == V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
b7101de3
ST
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 }
1bf5842f 669 CX18_DEBUG_FILE("Encoder mmap started capture\n");
b7101de3
ST
670 }
671
1bf5842f 672 return videobuf_mmap_mapper(&s->vbuf_q, vma);
b7101de3
ST
673 }
674
675 return -EINVAL;
676}
677
162e6376 678void cx18_vb_timeout(struct timer_list *t)
b7101de3 679{
162e6376 680 struct cx18_stream *s = from_timer(s, t, vb_timeout);
b7101de3
ST
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
1c1e45d1
HV
698void 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];
79f3e960
AW
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];
1c1e45d1
HV
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)) {
1c1e45d1 711 CX18_DEBUG_INFO("close stopping capture\n");
79f3e960
AW
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)) {
6beb1388 716 CX18_DEBUG_INFO("close stopping embedded VBI capture\n");
79f3e960
AW
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 }
1c1e45d1
HV
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
bec43661 738int cx18_v4l2_close(struct file *filp)
1c1e45d1 739{
0b5f265a
HV
740 struct v4l2_fh *fh = filp->private_data;
741 struct cx18_open_id *id = fh2id(fh);
1c1e45d1
HV
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
1c1e45d1 747 mutex_lock(&cx->serialize_lock);
4d68e700
HV
748 /* Stop radio */
749 if (id->type == CX18_ENC_STREAM_TYPE_RAD &&
750 v4l2_fh_is_singular_file(filp)) {
1c1e45d1
HV
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 */
8774bed9 756 cx18_call_all(cx, video, s_std, cx->std);
1c1e45d1
HV
757 /* Select correct audio input (i.e. TV tuner or Line in) */
758 cx18_audio_set_io(cx);
31554ae5 759 if (atomic_read(&cx->ana_capturing) > 0) {
1c1e45d1
HV
760 /* Undo video mute */
761 cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2, s->handle,
a75b9be1
HV
762 (v4l2_ctrl_g_ctrl(cx->cxhdl.video_mute) |
763 (v4l2_ctrl_g_ctrl(cx->cxhdl.video_mute_yuv) << 8)));
1c1e45d1
HV
764 }
765 /* Done! Unmute and continue. */
766 cx18_unmute(cx);
1c1e45d1 767 }
4d68e700
HV
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);
1c1e45d1
HV
775 kfree(id);
776 mutex_unlock(&cx->serialize_lock);
777 return 0;
778}
779
780static 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 */
0b5f265a 788 item = kzalloc(sizeof(struct cx18_open_id), GFP_KERNEL);
1c1e45d1
HV
789 if (NULL == item) {
790 CX18_DEBUG_WARN("nomem on v4l2 open\n");
791 return -ENOMEM;
792 }
08569d64 793 v4l2_fh_init(&item->fh, &s->video_dev);
0b5f265a 794
1c1e45d1
HV
795 item->cx = cx;
796 item->type = s->type;
1c1e45d1
HV
797
798 item->open_id = cx->open_id++;
0b5f265a 799 filp->private_data = &item->fh;
4d68e700 800 v4l2_fh_add(&item->fh);
1c1e45d1 801
4d68e700
HV
802 if (item->type == CX18_ENC_STREAM_TYPE_RAD &&
803 v4l2_fh_is_singular_file(filp)) {
1c1e45d1 804 if (!test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) {
31554ae5 805 if (atomic_read(&cx->ana_capturing) > 0) {
1c1e45d1
HV
806 /* switching to radio while capture is
807 in progress is not polite */
4d68e700 808 v4l2_fh_del(&item->fh);
0b5f265a 809 v4l2_fh_exit(&item->fh);
1c1e45d1
HV
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 */
ff2a2001 820 cx18_call_all(cx, tuner, s_radio);
1c1e45d1
HV
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
bec43661 829int cx18_v4l2_open(struct file *filp)
1c1e45d1 830{
5811cf99
AW
831 int res;
832 struct video_device *video_dev = video_devdata(filp);
833 struct cx18_stream *s = video_get_drvdata(video_dev);
32a60955 834 struct cx18 *cx = s->cx;
1c1e45d1
HV
835
836 mutex_lock(&cx->serialize_lock);
837 if (cx18_init_on_first_open(cx)) {
50462eb0
LP
838 CX18_ERR("Failed to initialize on %s\n",
839 video_device_node_name(video_dev));
1c1e45d1
HV
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
848void cx18_mute(struct cx18 *cx)
849{
d3c5e707
AW
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 }
1c1e45d1
HV
858 CX18_DEBUG_INFO("Mute\n");
859}
860
861void cx18_unmute(struct cx18 *cx)
862{
d3c5e707 863 u32 h;
31554ae5 864 if (atomic_read(&cx->ana_capturing)) {
d3c5e707
AW
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");
1c1e45d1
HV
872 }
873 CX18_DEBUG_INFO("Unmute\n");
874}