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