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