]> bbs.cooldavid.org Git - net-next-2.6.git/blob - 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
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@radix.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
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
40    associated VBI and IDX streams are also automatically claimed.
41    Possible error returns: -EBUSY if someone else has claimed
42    the stream or 0 on success. */
43 static int cx18_claim_stream(struct cx18_open_id *id, int type)
44 {
45         struct cx18 *cx = id->cx;
46         struct cx18_stream *s = &cx->streams[type];
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         }
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
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))
91                 return 0;
92
93         set_bit(CX18_F_S_CLAIMED, &s_assoc->s_flags);
94
95         /* mark that it is used internally */
96         set_bit(CX18_F_S_INTERNAL_USE, &s_assoc->s_flags);
97         return 0;
98 }
99
100 /* This function releases a previously claimed stream. It will take into
101    account associated VBI streams. */
102 static void cx18_release_stream(struct cx18_stream *s)
103 {
104         struct cx18 *cx = s->cx;
105         struct cx18_stream *s_assoc;
106
107         s->id = -1;
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
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
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)
135                 return;
136
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);
142         }
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                 }
155         }
156 }
157
158 static void cx18_dualwatch(struct cx18 *cx)
159 {
160         struct v4l2_tuner vt;
161         u32 new_bitmap;
162         u32 new_stereo_mode;
163         const u32 stereo_mask = 0x0300;
164         const u32 dual = 0x0200;
165         u32 h;
166
167         new_stereo_mode = cx->params.audio_properties & stereo_mask;
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         new_bitmap = new_stereo_mode
178                         | (cx->params.audio_properties & ~stereo_mask);
179
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);
183
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) {
192                 cx->dualwatch_stereo_mode = new_stereo_mode;
193                 return;
194         }
195         CX18_DEBUG_INFO("dualwatch: changing stereo flag failed\n");
196 }
197
198
199 static struct cx18_mdl *cx18_get_mdl(struct cx18_stream *s, int non_block,
200                                      int *err)
201 {
202         struct cx18 *cx = s->cx;
203         struct cx18_stream *s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
204         struct cx18_mdl *mdl;
205         DEFINE_WAIT(wait);
206
207         *err = 0;
208         while (1) {
209                 if (s->type == CX18_ENC_STREAM_TYPE_MPG) {
210                         /* Process pending program updates and VBI data */
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)) {
217                                 while ((mdl = cx18_dequeue(s_vbi,
218                                                            &s_vbi->q_full))) {
219                                         /* byteswap and process VBI data */
220                                         cx18_process_vbi_data(cx, mdl,
221                                                               s_vbi->type);
222                                         cx18_stream_put_mdl_fw(s_vbi, mdl);
223                                 }
224                         }
225                         mdl = &cx->vbi.sliced_mpeg_mdl;
226                         if (mdl->readpos != mdl->bytesused)
227                                 return mdl;
228                 }
229
230                 /* do we have new data? */
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;
236                         if (s->type == CX18_ENC_STREAM_TYPE_MPG)
237                                 /* byteswap MPG data */
238                                 cx18_mdl_swap(mdl);
239                         else {
240                                 /* byteswap and process VBI data */
241                                 cx18_process_vbi_data(cx, mdl, s->type);
242                         }
243                         return mdl;
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 */
262                 if (!atomic_read(&s->q_full.depth))
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
274 static void cx18_setup_sliced_vbi_mdl(struct cx18 *cx)
275 {
276         struct cx18_mdl *mdl = &cx->vbi.sliced_mpeg_mdl;
277         struct cx18_buffer *buf = &cx->vbi.sliced_mpeg_buf;
278         int idx = cx->vbi.inserted_frame % CX18_VBI_FRAMES;
279
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;
287 }
288
289 static size_t cx18_copy_buf_to_user(struct cx18_stream *s,
290         struct cx18_buffer *buf, char __user *ubuf, size_t ucount, bool *stop)
291 {
292         struct cx18 *cx = s->cx;
293         size_t len = buf->bytesused - buf->readpos;
294
295         *stop = false;
296         if (len > ucount)
297                 len = ucount;
298         if (cx->vbi.insert_mpeg && s->type == CX18_ENC_STREAM_TYPE_MPG &&
299             !cx18_raw_vbi(cx) && buf != &cx->vbi.sliced_mpeg_buf) {
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.
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.
311                  */
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                  */
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) {
326                         /* Scan for a 0 to find a potential MPEG-2 start code */
327                         q = memchr(p, 0, start + len - p);
328                         if (q == NULL)
329                                 break;
330                         p = q + 1;
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                          */
336                         if ((char *)q + 15 >= buf->buf + buf->bytesused ||
337                             q[1] != 0 || q[2] != 1 || q[3] != ch)
338                                 continue;
339
340                         /* If expecting the primary video PES */
341                         if (!cx->search_pack_header) {
342                                 /* Continue if it couldn't be a PES packet */
343                                 if ((q[6] & 0xc0) != 0x80)
344                                         continue;
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*/
352                                         cx->search_pack_header = 1;
353                                         p = q + 9; /* Skip this video PES hdr */
354                                 }
355                                 continue;
356                         }
357
358                         /* We may have found a Program Pack start code */
359
360                         /* Get the count of stuffing bytes & verify them */
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;
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 */
370                             q[15 + stuffing] == 0 &&
371                             q[16 + stuffing] == 1) {
372                                 /* We declare we actually found a Program Pack*/
373                                 cx->search_pack_header = 0; /* expect vid PES */
374                                 len = (char *)q - start;
375                                 cx18_setup_sliced_vbi_mdl(cx);
376                                 *stop = true;
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
393 static 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
435 static 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
442         if (atomic_read(&cx->ana_capturing) == 0 && s->id == -1) {
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 */
452         if (s->type == CX18_ENC_STREAM_TYPE_VBI && !cx18_raw_vbi(cx))
453                 single_frame = 1;
454
455         for (;;) {
456                 struct cx18_mdl *mdl;
457                 int rc;
458
459                 mdl = cx18_get_mdl(s, non_block, &rc);
460                 /* if there is no data available... */
461                 if (mdl == NULL) {
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
475                 rc = cx18_copy_mdl_to_user(s, mdl, ubuf + tot_written,
476                                 tot_count - tot_written);
477
478                 if (mdl != &cx->vbi.sliced_mpeg_mdl) {
479                         if (mdl->readpos == mdl->bytesused)
480                                 cx18_stream_put_mdl_fw(s, mdl);
481                         else
482                                 cx18_push(s, mdl, &s->q_full);
483                 } else if (mdl->readpos == mdl->bytesused) {
484                         int idx = cx->vbi.inserted_frame % CX18_VBI_FRAMES;
485
486                         cx->vbi.sliced_mpeg_size[idx] = 0;
487                         cx->vbi.inserted_frame++;
488                         cx->vbi_data_inserted += mdl->bytesused;
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
500 static 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
512 int 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;
517         struct cx18_stream *s_idx;
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
536         /* Start associated VBI or IDX stream capture if required */
537         s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
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");
562                 }
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
575 start_failed:
576         CX18_DEBUG_WARN("Failed to start capturing for stream %s\n", s->name);
577
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                 }
595         }
596         clear_bit(CX18_F_S_STREAMING, &s->s_flags);
597         cx18_release_stream(s); /* Also releases associated streams */
598         return -EIO;
599 }
600
601 ssize_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
619 unsigned 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
645         if (atomic_read(&s->q_full.depth))
646                 return POLLIN | POLLRDNORM;
647         if (eof)
648                 return POLLHUP;
649         return 0;
650 }
651
652 void 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];
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];
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)) {
665                 CX18_DEBUG_INFO("close stopping capture\n");
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                         }
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
693 int cx18_v4l2_close(struct file *filp)
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 */
719                 cx18_call_all(cx, core, s_std, cx->std);
720                 /* Select correct audio input (i.e. TV tuner or Line in) */
721                 cx18_audio_set_io(cx);
722                 if (atomic_read(&cx->ana_capturing) > 0) {
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
739 static 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)) {
768                         if (atomic_read(&cx->ana_capturing) > 0) {
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 */
782                 cx18_call_all(cx, tuner, s_radio);
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
791 int cx18_v4l2_open(struct file *filp)
792 {
793         int res;
794         struct video_device *video_dev = video_devdata(filp);
795         struct cx18_stream *s = video_get_drvdata(video_dev);
796         struct cx18 *cx = s->cx;
797
798         mutex_lock(&cx->serialize_lock);
799         if (cx18_init_on_first_open(cx)) {
800                 CX18_ERR("Failed to initialize on %s\n",
801                          video_device_node_name(video_dev));
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
810 void cx18_mute(struct cx18 *cx)
811 {
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         }
820         CX18_DEBUG_INFO("Mute\n");
821 }
822
823 void cx18_unmute(struct cx18 *cx)
824 {
825         u32 h;
826         if (atomic_read(&cx->ana_capturing)) {
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");
834         }
835         CX18_DEBUG_INFO("Unmute\n");
836 }