This source file includes following definitions.
- cx18_claim_stream
- cx18_release_stream
- cx18_dualwatch
- cx18_get_mdl
- cx18_setup_sliced_vbi_mdl
- cx18_copy_buf_to_user
- cx18_copy_mdl_to_user
- cx18_read
- cx18_read_pos
- cx18_start_capture
- cx18_v4l2_read
- cx18_v4l2_enc_poll
- cx18_v4l2_mmap
- cx18_vb_timeout
- cx18_stop_capture
- cx18_v4l2_close
- cx18_serialized_open
- cx18_v4l2_open
- cx18_mute
- cx18_unmute
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 #include "cx18-driver.h"
  12 #include "cx18-fileops.h"
  13 #include "cx18-i2c.h"
  14 #include "cx18-queue.h"
  15 #include "cx18-vbi.h"
  16 #include "cx18-audio.h"
  17 #include "cx18-mailbox.h"
  18 #include "cx18-scb.h"
  19 #include "cx18-streams.h"
  20 #include "cx18-controls.h"
  21 #include "cx18-ioctl.h"
  22 #include "cx18-cards.h"
  23 #include <media/v4l2-event.h>
  24 
  25 
  26 
  27 
  28 
  29 
  30 int cx18_claim_stream(struct cx18_open_id *id, int type)
  31 {
  32         struct cx18 *cx = id->cx;
  33         struct cx18_stream *s = &cx->streams[type];
  34         struct cx18_stream *s_assoc;
  35 
  36         
  37         if (type == CX18_ENC_STREAM_TYPE_IDX) {
  38                 CX18_WARN("MPEG Index stream cannot be claimed directly, but something tried.\n");
  39                 return -EINVAL;
  40         }
  41 
  42         if (test_and_set_bit(CX18_F_S_CLAIMED, &s->s_flags)) {
  43                 
  44                 if (s->id == id->open_id) {
  45                         
  46                         return 0;
  47                 }
  48                 if (s->id == -1 && type == CX18_ENC_STREAM_TYPE_VBI) {
  49                         
  50 
  51 
  52                         s->id = id->open_id;
  53                         CX18_DEBUG_INFO("Start Read VBI\n");
  54                         return 0;
  55                 }
  56                 
  57                 CX18_DEBUG_INFO("Stream %d is busy\n", type);
  58                 return -EBUSY;
  59         }
  60         s->id = id->open_id;
  61 
  62         
  63 
  64 
  65 
  66 
  67 
  68 
  69 
  70         if (type != CX18_ENC_STREAM_TYPE_MPG)
  71                 return 0;
  72 
  73         s_assoc = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
  74         if (cx->vbi.insert_mpeg && !cx18_raw_vbi(cx))
  75                 s_assoc = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
  76         else if (!cx18_stream_enabled(s_assoc))
  77                 return 0;
  78 
  79         set_bit(CX18_F_S_CLAIMED, &s_assoc->s_flags);
  80 
  81         
  82         set_bit(CX18_F_S_INTERNAL_USE, &s_assoc->s_flags);
  83         return 0;
  84 }
  85 EXPORT_SYMBOL(cx18_claim_stream);
  86 
  87 
  88 
  89 void cx18_release_stream(struct cx18_stream *s)
  90 {
  91         struct cx18 *cx = s->cx;
  92         struct cx18_stream *s_assoc;
  93 
  94         s->id = -1;
  95         if (s->type == CX18_ENC_STREAM_TYPE_IDX) {
  96                 
  97 
  98 
  99 
 100                 return;
 101         }
 102 
 103         if (s->type == CX18_ENC_STREAM_TYPE_VBI &&
 104                 test_bit(CX18_F_S_INTERNAL_USE, &s->s_flags)) {
 105                 
 106                 return;
 107         }
 108         if (!test_and_clear_bit(CX18_F_S_CLAIMED, &s->s_flags)) {
 109                 CX18_DEBUG_WARN("Release stream %s not in use!\n", s->name);
 110                 return;
 111         }
 112 
 113         cx18_flush_queues(s);
 114 
 115         
 116 
 117 
 118 
 119 
 120 
 121         if (s->type != CX18_ENC_STREAM_TYPE_MPG)
 122                 return;
 123 
 124         
 125         s_assoc = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
 126         if (test_and_clear_bit(CX18_F_S_INTERNAL_USE, &s_assoc->s_flags)) {
 127                 clear_bit(CX18_F_S_CLAIMED, &s_assoc->s_flags);
 128                 cx18_flush_queues(s_assoc);
 129         }
 130 
 131         
 132         s_assoc = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
 133         if (test_and_clear_bit(CX18_F_S_INTERNAL_USE, &s_assoc->s_flags)) {
 134                 if (s_assoc->id == -1) {
 135                         
 136 
 137 
 138 
 139                         clear_bit(CX18_F_S_CLAIMED, &s_assoc->s_flags);
 140                         cx18_flush_queues(s_assoc);
 141                 }
 142         }
 143 }
 144 EXPORT_SYMBOL(cx18_release_stream);
 145 
 146 static void cx18_dualwatch(struct cx18 *cx)
 147 {
 148         struct v4l2_tuner vt;
 149         u32 new_stereo_mode;
 150         const u32 dual = 0x0200;
 151 
 152         new_stereo_mode = v4l2_ctrl_g_ctrl(cx->cxhdl.audio_mode);
 153         memset(&vt, 0, sizeof(vt));
 154         cx18_call_all(cx, tuner, g_tuner, &vt);
 155         if (vt.audmode == V4L2_TUNER_MODE_LANG1_LANG2 &&
 156                         (vt.rxsubchans & V4L2_TUNER_SUB_LANG2))
 157                 new_stereo_mode = dual;
 158 
 159         if (new_stereo_mode == cx->dualwatch_stereo_mode)
 160                 return;
 161 
 162         CX18_DEBUG_INFO("dualwatch: change stereo flag from 0x%x to 0x%x.\n",
 163                            cx->dualwatch_stereo_mode, new_stereo_mode);
 164         if (v4l2_ctrl_s_ctrl(cx->cxhdl.audio_mode, new_stereo_mode))
 165                 CX18_DEBUG_INFO("dualwatch: changing stereo flag failed\n");
 166 }
 167 
 168 
 169 static struct cx18_mdl *cx18_get_mdl(struct cx18_stream *s, int non_block,
 170                                      int *err)
 171 {
 172         struct cx18 *cx = s->cx;
 173         struct cx18_stream *s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
 174         struct cx18_mdl *mdl;
 175         DEFINE_WAIT(wait);
 176 
 177         *err = 0;
 178         while (1) {
 179                 if (s->type == CX18_ENC_STREAM_TYPE_MPG) {
 180                         
 181                         if (time_after(jiffies, cx->dualwatch_jiffies + msecs_to_jiffies(1000))) {
 182                                 cx->dualwatch_jiffies = jiffies;
 183                                 cx18_dualwatch(cx);
 184                         }
 185                         if (test_bit(CX18_F_S_INTERNAL_USE, &s_vbi->s_flags) &&
 186                             !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) {
 187                                 while ((mdl = cx18_dequeue(s_vbi,
 188                                                            &s_vbi->q_full))) {
 189                                         
 190                                         cx18_process_vbi_data(cx, mdl,
 191                                                               s_vbi->type);
 192                                         cx18_stream_put_mdl_fw(s_vbi, mdl);
 193                                 }
 194                         }
 195                         mdl = &cx->vbi.sliced_mpeg_mdl;
 196                         if (mdl->readpos != mdl->bytesused)
 197                                 return mdl;
 198                 }
 199 
 200                 
 201                 mdl = cx18_dequeue(s, &s->q_full);
 202                 if (mdl) {
 203                         if (!test_and_clear_bit(CX18_F_M_NEED_SWAP,
 204                                                 &mdl->m_flags))
 205                                 return mdl;
 206                         if (s->type == CX18_ENC_STREAM_TYPE_MPG)
 207                                 
 208                                 cx18_mdl_swap(mdl);
 209                         else {
 210                                 
 211                                 cx18_process_vbi_data(cx, mdl, s->type);
 212                         }
 213                         return mdl;
 214                 }
 215 
 216                 
 217                 if (!test_bit(CX18_F_S_STREAMING, &s->s_flags)) {
 218                         CX18_DEBUG_INFO("EOS %s\n", s->name);
 219                         return NULL;
 220                 }
 221 
 222                 
 223                 if (non_block) {
 224                         *err = -EAGAIN;
 225                         return NULL;
 226                 }
 227 
 228                 
 229                 prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE);
 230                 
 231 
 232                 if (!atomic_read(&s->q_full.depth))
 233                         schedule();
 234                 finish_wait(&s->waitq, &wait);
 235                 if (signal_pending(current)) {
 236                         
 237                         CX18_DEBUG_INFO("User stopped %s\n", s->name);
 238                         *err = -EINTR;
 239                         return NULL;
 240                 }
 241         }
 242 }
 243 
 244 static void cx18_setup_sliced_vbi_mdl(struct cx18 *cx)
 245 {
 246         struct cx18_mdl *mdl = &cx->vbi.sliced_mpeg_mdl;
 247         struct cx18_buffer *buf = &cx->vbi.sliced_mpeg_buf;
 248         int idx = cx->vbi.inserted_frame % CX18_VBI_FRAMES;
 249 
 250         buf->buf = cx->vbi.sliced_mpeg_data[idx];
 251         buf->bytesused = cx->vbi.sliced_mpeg_size[idx];
 252         buf->readpos = 0;
 253 
 254         mdl->curr_buf = NULL;
 255         mdl->bytesused = cx->vbi.sliced_mpeg_size[idx];
 256         mdl->readpos = 0;
 257 }
 258 
 259 static size_t cx18_copy_buf_to_user(struct cx18_stream *s,
 260         struct cx18_buffer *buf, char __user *ubuf, size_t ucount, bool *stop)
 261 {
 262         struct cx18 *cx = s->cx;
 263         size_t len = buf->bytesused - buf->readpos;
 264 
 265         *stop = false;
 266         if (len > ucount)
 267                 len = ucount;
 268         if (cx->vbi.insert_mpeg && s->type == CX18_ENC_STREAM_TYPE_MPG &&
 269             !cx18_raw_vbi(cx) && buf != &cx->vbi.sliced_mpeg_buf) {
 270                 
 271 
 272 
 273 
 274 
 275 
 276 
 277 
 278 
 279 
 280 
 281 
 282                 
 283 
 284 
 285 
 286 
 287 
 288 
 289                 const char *start = buf->buf + buf->readpos;
 290                 const char *p = start + 1;
 291                 const u8 *q;
 292                 u8 ch = cx->search_pack_header ? 0xba : 0xe0;
 293                 int stuffing, i;
 294 
 295                 while (start + len > p) {
 296                         
 297                         q = memchr(p, 0, start + len - p);
 298                         if (q == NULL)
 299                                 break;
 300                         p = q + 1;
 301                         
 302 
 303 
 304 
 305 
 306                         if ((char *)q + 15 >= buf->buf + buf->bytesused ||
 307                             q[1] != 0 || q[2] != 1 || q[3] != ch)
 308                                 continue;
 309 
 310                         
 311                         if (!cx->search_pack_header) {
 312                                 
 313                                 if ((q[6] & 0xc0) != 0x80)
 314                                         continue;
 315                                 
 316                                 if (((q[7] & 0xc0) == 0x80 &&  
 317                                      (q[9] & 0xf0) == 0x20) || 
 318                                     ((q[7] & 0xc0) == 0xc0 &&  
 319                                      (q[9] & 0xf0) == 0x30)) { 
 320                                         
 321                                         ch = 0xba; 
 322                                         cx->search_pack_header = 1;
 323                                         p = q + 9; 
 324                                 }
 325                                 continue;
 326                         }
 327 
 328                         
 329 
 330                         
 331                         stuffing = q[13] & 7;
 332                         
 333                         for (i = 0; i < stuffing; i++)
 334                                 if (q[14 + i] != 0xff)
 335                                         break;
 336                         if (i == stuffing && 
 337                             (q[4] & 0xc4) == 0x44 && 
 338                             (q[12] & 3) == 3 &&  
 339                             q[14 + stuffing] == 0 && 
 340                             q[15 + stuffing] == 0 &&
 341                             q[16 + stuffing] == 1) {
 342                                 
 343                                 cx->search_pack_header = 0; 
 344                                 len = (char *)q - start;
 345                                 cx18_setup_sliced_vbi_mdl(cx);
 346                                 *stop = true;
 347                                 break;
 348                         }
 349                 }
 350         }
 351         if (copy_to_user(ubuf, (u8 *)buf->buf + buf->readpos, len)) {
 352                 CX18_DEBUG_WARN("copy %zd bytes to user failed for %s\n",
 353                                 len, s->name);
 354                 return -EFAULT;
 355         }
 356         buf->readpos += len;
 357         if (s->type == CX18_ENC_STREAM_TYPE_MPG &&
 358             buf != &cx->vbi.sliced_mpeg_buf)
 359                 cx->mpg_data_received += len;
 360         return len;
 361 }
 362 
 363 static size_t cx18_copy_mdl_to_user(struct cx18_stream *s,
 364                 struct cx18_mdl *mdl, char __user *ubuf, size_t ucount)
 365 {
 366         size_t tot_written = 0;
 367         int rc;
 368         bool stop = false;
 369 
 370         if (mdl->curr_buf == NULL)
 371                 mdl->curr_buf = list_first_entry(&mdl->buf_list,
 372                                                  struct cx18_buffer, list);
 373 
 374         if (list_entry_is_past_end(mdl->curr_buf, &mdl->buf_list, list)) {
 375                 
 376 
 377 
 378 
 379 
 380                 mdl->readpos = mdl->bytesused;
 381                 return 0;
 382         }
 383 
 384         list_for_each_entry_from(mdl->curr_buf, &mdl->buf_list, list) {
 385 
 386                 if (mdl->curr_buf->readpos >= mdl->curr_buf->bytesused)
 387                         continue;
 388 
 389                 rc = cx18_copy_buf_to_user(s, mdl->curr_buf, ubuf + tot_written,
 390                                            ucount - tot_written, &stop);
 391                 if (rc < 0)
 392                         return rc;
 393                 mdl->readpos += rc;
 394                 tot_written += rc;
 395 
 396                 if (stop ||     
 397                     tot_written >= ucount ||    
 398                     mdl->curr_buf->readpos < mdl->curr_buf->bytesused ||
 399                     mdl->readpos >= mdl->bytesused) 
 400                         break;
 401         }
 402         return tot_written;
 403 }
 404 
 405 static ssize_t cx18_read(struct cx18_stream *s, char __user *ubuf,
 406                 size_t tot_count, int non_block)
 407 {
 408         struct cx18 *cx = s->cx;
 409         size_t tot_written = 0;
 410         int single_frame = 0;
 411 
 412         if (atomic_read(&cx->ana_capturing) == 0 && s->id == -1) {
 413                 
 414                 CX18_DEBUG_WARN("Stream %s not initialized before read\n",
 415                                 s->name);
 416                 return -EIO;
 417         }
 418 
 419         
 420 
 421 
 422         if (s->type == CX18_ENC_STREAM_TYPE_VBI && !cx18_raw_vbi(cx))
 423                 single_frame = 1;
 424 
 425         for (;;) {
 426                 struct cx18_mdl *mdl;
 427                 int rc;
 428 
 429                 mdl = cx18_get_mdl(s, non_block, &rc);
 430                 
 431                 if (mdl == NULL) {
 432                         
 433                         if (tot_written)
 434                                 break;
 435                         
 436                         if (rc == 0) {
 437                                 clear_bit(CX18_F_S_STREAMOFF, &s->s_flags);
 438                                 clear_bit(CX18_F_S_APPL_IO, &s->s_flags);
 439                                 cx18_release_stream(s);
 440                         }
 441                         
 442                         return rc;
 443                 }
 444 
 445                 rc = cx18_copy_mdl_to_user(s, mdl, ubuf + tot_written,
 446                                 tot_count - tot_written);
 447 
 448                 if (mdl != &cx->vbi.sliced_mpeg_mdl) {
 449                         if (mdl->readpos == mdl->bytesused)
 450                                 cx18_stream_put_mdl_fw(s, mdl);
 451                         else
 452                                 cx18_push(s, mdl, &s->q_full);
 453                 } else if (mdl->readpos == mdl->bytesused) {
 454                         int idx = cx->vbi.inserted_frame % CX18_VBI_FRAMES;
 455 
 456                         cx->vbi.sliced_mpeg_size[idx] = 0;
 457                         cx->vbi.inserted_frame++;
 458                         cx->vbi_data_inserted += mdl->bytesused;
 459                 }
 460                 if (rc < 0)
 461                         return rc;
 462                 tot_written += rc;
 463 
 464                 if (tot_written == tot_count || single_frame)
 465                         break;
 466         }
 467         return tot_written;
 468 }
 469 
 470 static ssize_t cx18_read_pos(struct cx18_stream *s, char __user *ubuf,
 471                 size_t count, loff_t *pos, int non_block)
 472 {
 473         ssize_t rc = count ? cx18_read(s, ubuf, count, non_block) : 0;
 474         struct cx18 *cx = s->cx;
 475 
 476         CX18_DEBUG_HI_FILE("read %zd from %s, got %zd\n", count, s->name, rc);
 477         if (rc > 0)
 478                 *pos += rc;
 479         return rc;
 480 }
 481 
 482 int cx18_start_capture(struct cx18_open_id *id)
 483 {
 484         struct cx18 *cx = id->cx;
 485         struct cx18_stream *s = &cx->streams[id->type];
 486         struct cx18_stream *s_vbi;
 487         struct cx18_stream *s_idx;
 488 
 489         if (s->type == CX18_ENC_STREAM_TYPE_RAD) {
 490                 
 491                 return -EPERM;
 492         }
 493 
 494         
 495         if (cx18_claim_stream(id, s->type))
 496                 return -EBUSY;
 497 
 498         
 499 
 500         if (test_bit(CX18_F_S_STREAMOFF, &s->s_flags) ||
 501             test_and_set_bit(CX18_F_S_STREAMING, &s->s_flags)) {
 502                 set_bit(CX18_F_S_APPL_IO, &s->s_flags);
 503                 return 0;
 504         }
 505 
 506         
 507         s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
 508         s_idx = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
 509         if (s->type == CX18_ENC_STREAM_TYPE_MPG) {
 510                 
 511 
 512 
 513 
 514 
 515                 if (test_bit(CX18_F_S_INTERNAL_USE, &s_idx->s_flags) &&
 516                     !test_and_set_bit(CX18_F_S_STREAMING, &s_idx->s_flags)) {
 517                         if (cx18_start_v4l2_encode_stream(s_idx)) {
 518                                 CX18_DEBUG_WARN("IDX capture start failed\n");
 519                                 clear_bit(CX18_F_S_STREAMING, &s_idx->s_flags);
 520                                 goto start_failed;
 521                         }
 522                         CX18_DEBUG_INFO("IDX capture started\n");
 523                 }
 524                 if (test_bit(CX18_F_S_INTERNAL_USE, &s_vbi->s_flags) &&
 525                     !test_and_set_bit(CX18_F_S_STREAMING, &s_vbi->s_flags)) {
 526                         if (cx18_start_v4l2_encode_stream(s_vbi)) {
 527                                 CX18_DEBUG_WARN("VBI capture start failed\n");
 528                                 clear_bit(CX18_F_S_STREAMING, &s_vbi->s_flags);
 529                                 goto start_failed;
 530                         }
 531                         CX18_DEBUG_INFO("VBI insertion started\n");
 532                 }
 533         }
 534 
 535         
 536         if (!cx18_start_v4l2_encode_stream(s)) {
 537                 
 538                 set_bit(CX18_F_S_APPL_IO, &s->s_flags);
 539                 
 540                 if (test_and_clear_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags))
 541                         cx18_vapi(cx, CX18_CPU_CAPTURE_PAUSE, 1, s->handle);
 542                 return 0;
 543         }
 544 
 545 start_failed:
 546         CX18_DEBUG_WARN("Failed to start capturing for stream %s\n", s->name);
 547 
 548         
 549 
 550 
 551 
 552 
 553         if (s->type == CX18_ENC_STREAM_TYPE_MPG) {
 554                 
 555                 if (test_bit(CX18_F_S_STREAMING, &s_idx->s_flags)) {
 556                         cx18_stop_v4l2_encode_stream(s_idx, 0);
 557                         clear_bit(CX18_F_S_STREAMING, &s_idx->s_flags);
 558                 }
 559                 
 560                 if (test_bit(CX18_F_S_STREAMING, &s_vbi->s_flags) &&
 561                     !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) {
 562                         cx18_stop_v4l2_encode_stream(s_vbi, 0);
 563                         clear_bit(CX18_F_S_STREAMING, &s_vbi->s_flags);
 564                 }
 565         }
 566         clear_bit(CX18_F_S_STREAMING, &s->s_flags);
 567         cx18_release_stream(s); 
 568         return -EIO;
 569 }
 570 
 571 ssize_t cx18_v4l2_read(struct file *filp, char __user *buf, size_t count,
 572                 loff_t *pos)
 573 {
 574         struct cx18_open_id *id = file2id(filp);
 575         struct cx18 *cx = id->cx;
 576         struct cx18_stream *s = &cx->streams[id->type];
 577         int rc;
 578 
 579         CX18_DEBUG_HI_FILE("read %zd bytes from %s\n", count, s->name);
 580 
 581         mutex_lock(&cx->serialize_lock);
 582         rc = cx18_start_capture(id);
 583         mutex_unlock(&cx->serialize_lock);
 584         if (rc)
 585                 return rc;
 586 
 587         if ((s->vb_type == V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
 588                 (id->type == CX18_ENC_STREAM_TYPE_YUV)) {
 589                 return videobuf_read_stream(&s->vbuf_q, buf, count, pos, 0,
 590                         filp->f_flags & O_NONBLOCK);
 591         }
 592 
 593         return cx18_read_pos(s, buf, count, pos, filp->f_flags & O_NONBLOCK);
 594 }
 595 
 596 __poll_t cx18_v4l2_enc_poll(struct file *filp, poll_table *wait)
 597 {
 598         __poll_t req_events = poll_requested_events(wait);
 599         struct cx18_open_id *id = file2id(filp);
 600         struct cx18 *cx = id->cx;
 601         struct cx18_stream *s = &cx->streams[id->type];
 602         int eof = test_bit(CX18_F_S_STREAMOFF, &s->s_flags);
 603         __poll_t res = 0;
 604 
 605         
 606         if (!eof && !test_bit(CX18_F_S_STREAMING, &s->s_flags) &&
 607                         (req_events & (EPOLLIN | EPOLLRDNORM))) {
 608                 int rc;
 609 
 610                 mutex_lock(&cx->serialize_lock);
 611                 rc = cx18_start_capture(id);
 612                 mutex_unlock(&cx->serialize_lock);
 613                 if (rc) {
 614                         CX18_DEBUG_INFO("Could not start capture for %s (%d)\n",
 615                                         s->name, rc);
 616                         return EPOLLERR;
 617                 }
 618                 CX18_DEBUG_FILE("Encoder poll started capture\n");
 619         }
 620 
 621         if ((s->vb_type == V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
 622                 (id->type == CX18_ENC_STREAM_TYPE_YUV)) {
 623                 __poll_t videobuf_poll = videobuf_poll_stream(filp, &s->vbuf_q, wait);
 624 
 625                 if (v4l2_event_pending(&id->fh))
 626                         res |= EPOLLPRI;
 627                 if (eof && videobuf_poll == EPOLLERR)
 628                         return res | EPOLLHUP;
 629                 return res | videobuf_poll;
 630         }
 631 
 632         
 633         CX18_DEBUG_HI_FILE("Encoder poll\n");
 634         if (v4l2_event_pending(&id->fh))
 635                 res |= EPOLLPRI;
 636         else
 637                 poll_wait(filp, &s->waitq, wait);
 638 
 639         if (atomic_read(&s->q_full.depth))
 640                 return res | EPOLLIN | EPOLLRDNORM;
 641         if (eof)
 642                 return res | EPOLLHUP;
 643         return res;
 644 }
 645 
 646 int cx18_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
 647 {
 648         struct cx18_open_id *id = file->private_data;
 649         struct cx18 *cx = id->cx;
 650         struct cx18_stream *s = &cx->streams[id->type];
 651         int eof = test_bit(CX18_F_S_STREAMOFF, &s->s_flags);
 652 
 653         if ((s->vb_type == V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
 654                 (id->type == CX18_ENC_STREAM_TYPE_YUV)) {
 655 
 656                 
 657                 if (!eof && !test_bit(CX18_F_S_STREAMING, &s->s_flags)) {
 658                         int rc;
 659 
 660                         mutex_lock(&cx->serialize_lock);
 661                         rc = cx18_start_capture(id);
 662                         mutex_unlock(&cx->serialize_lock);
 663                         if (rc) {
 664                                 CX18_DEBUG_INFO(
 665                                         "Could not start capture for %s (%d)\n",
 666                                         s->name, rc);
 667                                 return -EINVAL;
 668                         }
 669                         CX18_DEBUG_FILE("Encoder mmap started capture\n");
 670                 }
 671 
 672                 return videobuf_mmap_mapper(&s->vbuf_q, vma);
 673         }
 674 
 675         return -EINVAL;
 676 }
 677 
 678 void cx18_vb_timeout(struct timer_list *t)
 679 {
 680         struct cx18_stream *s = from_timer(s, t, vb_timeout);
 681         struct cx18_videobuf_buffer *buf;
 682         unsigned long flags;
 683 
 684         
 685 
 686 
 687         spin_lock_irqsave(&s->vb_lock, flags);
 688         while (!list_empty(&s->vb_capture)) {
 689                 buf = list_entry(s->vb_capture.next,
 690                         struct cx18_videobuf_buffer, vb.queue);
 691                 list_del(&buf->vb.queue);
 692                 buf->vb.state = VIDEOBUF_ERROR;
 693                 wake_up(&buf->vb.done);
 694         }
 695         spin_unlock_irqrestore(&s->vb_lock, flags);
 696 }
 697 
 698 void cx18_stop_capture(struct cx18_open_id *id, int gop_end)
 699 {
 700         struct cx18 *cx = id->cx;
 701         struct cx18_stream *s = &cx->streams[id->type];
 702         struct cx18_stream *s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
 703         struct cx18_stream *s_idx = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
 704 
 705         CX18_DEBUG_IOCTL("close() of %s\n", s->name);
 706 
 707         
 708 
 709         
 710         if (test_bit(CX18_F_S_STREAMING, &s->s_flags)) {
 711                 CX18_DEBUG_INFO("close stopping capture\n");
 712                 if (id->type == CX18_ENC_STREAM_TYPE_MPG) {
 713                         
 714                         if (test_bit(CX18_F_S_STREAMING, &s_vbi->s_flags) &&
 715                             !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) {
 716                                 CX18_DEBUG_INFO("close stopping embedded VBI capture\n");
 717                                 cx18_stop_v4l2_encode_stream(s_vbi, 0);
 718                         }
 719                         if (test_bit(CX18_F_S_STREAMING, &s_idx->s_flags)) {
 720                                 CX18_DEBUG_INFO("close stopping IDX capture\n");
 721                                 cx18_stop_v4l2_encode_stream(s_idx, 0);
 722                         }
 723                 }
 724                 if (id->type == CX18_ENC_STREAM_TYPE_VBI &&
 725                     test_bit(CX18_F_S_INTERNAL_USE, &s->s_flags))
 726                         
 727                         s->id = -1;
 728                 else
 729                         cx18_stop_v4l2_encode_stream(s, gop_end);
 730         }
 731         if (!gop_end) {
 732                 clear_bit(CX18_F_S_APPL_IO, &s->s_flags);
 733                 clear_bit(CX18_F_S_STREAMOFF, &s->s_flags);
 734                 cx18_release_stream(s);
 735         }
 736 }
 737 
 738 int cx18_v4l2_close(struct file *filp)
 739 {
 740         struct v4l2_fh *fh = filp->private_data;
 741         struct cx18_open_id *id = fh2id(fh);
 742         struct cx18 *cx = id->cx;
 743         struct cx18_stream *s = &cx->streams[id->type];
 744 
 745         CX18_DEBUG_IOCTL("close() of %s\n", s->name);
 746 
 747         mutex_lock(&cx->serialize_lock);
 748         
 749         if (id->type == CX18_ENC_STREAM_TYPE_RAD &&
 750                         v4l2_fh_is_singular_file(filp)) {
 751                 
 752                 cx18_mute(cx);
 753                 
 754                 clear_bit(CX18_F_I_RADIO_USER, &cx->i_flags);
 755                 
 756                 cx18_call_all(cx, video, s_std, cx->std);
 757                 
 758                 cx18_audio_set_io(cx);
 759                 if (atomic_read(&cx->ana_capturing) > 0) {
 760                         
 761                         cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2, s->handle,
 762                             (v4l2_ctrl_g_ctrl(cx->cxhdl.video_mute) |
 763                             (v4l2_ctrl_g_ctrl(cx->cxhdl.video_mute_yuv) << 8)));
 764                 }
 765                 
 766                 cx18_unmute(cx);
 767         }
 768 
 769         v4l2_fh_del(fh);
 770         v4l2_fh_exit(fh);
 771 
 772         
 773         if (s->id == id->open_id)
 774                 cx18_stop_capture(id, 0);
 775         kfree(id);
 776         mutex_unlock(&cx->serialize_lock);
 777         return 0;
 778 }
 779 
 780 static int cx18_serialized_open(struct cx18_stream *s, struct file *filp)
 781 {
 782         struct cx18 *cx = s->cx;
 783         struct cx18_open_id *item;
 784 
 785         CX18_DEBUG_FILE("open %s\n", s->name);
 786 
 787         
 788         item = kzalloc(sizeof(struct cx18_open_id), GFP_KERNEL);
 789         if (NULL == item) {
 790                 CX18_DEBUG_WARN("nomem on v4l2 open\n");
 791                 return -ENOMEM;
 792         }
 793         v4l2_fh_init(&item->fh, &s->video_dev);
 794 
 795         item->cx = cx;
 796         item->type = s->type;
 797 
 798         item->open_id = cx->open_id++;
 799         filp->private_data = &item->fh;
 800         v4l2_fh_add(&item->fh);
 801 
 802         if (item->type == CX18_ENC_STREAM_TYPE_RAD &&
 803                         v4l2_fh_is_singular_file(filp)) {
 804                 if (!test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) {
 805                         if (atomic_read(&cx->ana_capturing) > 0) {
 806                                 
 807 
 808                                 v4l2_fh_del(&item->fh);
 809                                 v4l2_fh_exit(&item->fh);
 810                                 kfree(item);
 811                                 return -EBUSY;
 812                         }
 813                 }
 814 
 815                 
 816                 set_bit(CX18_F_I_RADIO_USER, &cx->i_flags);
 817                 
 818                 cx18_mute(cx);
 819                 
 820                 cx18_call_all(cx, tuner, s_radio);
 821                 
 822                 cx18_audio_set_io(cx);
 823                 
 824                 cx18_unmute(cx);
 825         }
 826         return 0;
 827 }
 828 
 829 int cx18_v4l2_open(struct file *filp)
 830 {
 831         int res;
 832         struct video_device *video_dev = video_devdata(filp);
 833         struct cx18_stream *s = video_get_drvdata(video_dev);
 834         struct cx18 *cx = s->cx;
 835 
 836         mutex_lock(&cx->serialize_lock);
 837         if (cx18_init_on_first_open(cx)) {
 838                 CX18_ERR("Failed to initialize on %s\n",
 839                          video_device_node_name(video_dev));
 840                 mutex_unlock(&cx->serialize_lock);
 841                 return -ENXIO;
 842         }
 843         res = cx18_serialized_open(s, filp);
 844         mutex_unlock(&cx->serialize_lock);
 845         return res;
 846 }
 847 
 848 void cx18_mute(struct cx18 *cx)
 849 {
 850         u32 h;
 851         if (atomic_read(&cx->ana_capturing)) {
 852                 h = cx18_find_handle(cx);
 853                 if (h != CX18_INVALID_TASK_HANDLE)
 854                         cx18_vapi(cx, CX18_CPU_SET_AUDIO_MUTE, 2, h, 1);
 855                 else
 856                         CX18_ERR("Can't find valid task handle for mute\n");
 857         }
 858         CX18_DEBUG_INFO("Mute\n");
 859 }
 860 
 861 void cx18_unmute(struct cx18 *cx)
 862 {
 863         u32 h;
 864         if (atomic_read(&cx->ana_capturing)) {
 865                 h = cx18_find_handle(cx);
 866                 if (h != CX18_INVALID_TASK_HANDLE) {
 867                         cx18_msleep_timeout(100, 0);
 868                         cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 2, h, 12);
 869                         cx18_vapi(cx, CX18_CPU_SET_AUDIO_MUTE, 2, h, 0);
 870                 } else
 871                         CX18_ERR("Can't find valid task handle for unmute\n");
 872         }
 873         CX18_DEBUG_INFO("Unmute\n");
 874 }