root/drivers/media/pci/cx18/cx18-fileops.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. cx18_claim_stream
  2. cx18_release_stream
  3. cx18_dualwatch
  4. cx18_get_mdl
  5. cx18_setup_sliced_vbi_mdl
  6. cx18_copy_buf_to_user
  7. cx18_copy_mdl_to_user
  8. cx18_read
  9. cx18_read_pos
  10. cx18_start_capture
  11. cx18_v4l2_read
  12. cx18_v4l2_enc_poll
  13. cx18_v4l2_mmap
  14. cx18_vb_timeout
  15. cx18_stop_capture
  16. cx18_v4l2_close
  17. cx18_serialized_open
  18. cx18_v4l2_open
  19. cx18_mute
  20. cx18_unmute

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  *  cx18 file operation functions
   4  *
   5  *  Derived from ivtv-fileops.c
   6  *
   7  *  Copyright (C) 2007  Hans Verkuil <hverkuil@xs4all.nl>
   8  *  Copyright (C) 2008  Andy Walls <awalls@md.metrocast.net>
   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 /* This function tries to claim the stream for a specific file descriptor.
  26    If no one else is using this stream then the stream is claimed and
  27    associated VBI and IDX streams are also automatically claimed.
  28    Possible error returns: -EBUSY if someone else has claimed
  29    the stream or 0 on success. */
  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         /* Nothing should ever try to directly claim the IDX stream */
  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                 /* someone already claimed this stream */
  44                 if (s->id == id->open_id) {
  45                         /* yes, this file descriptor did. So that's OK. */
  46                         return 0;
  47                 }
  48                 if (s->id == -1 && type == CX18_ENC_STREAM_TYPE_VBI) {
  49                         /* VBI is handled already internally, now also assign
  50                            the file descriptor to this stream for external
  51                            reading of the stream. */
  52                         s->id = id->open_id;
  53                         CX18_DEBUG_INFO("Start Read VBI\n");
  54                         return 0;
  55                 }
  56                 /* someone else is using this stream already */
  57                 CX18_DEBUG_INFO("Stream %d is busy\n", type);
  58                 return -EBUSY;
  59         }
  60         s->id = id->open_id;
  61 
  62         /*
  63          * CX18_ENC_STREAM_TYPE_MPG needs to claim:
  64          * CX18_ENC_STREAM_TYPE_VBI, if VBI insertion is on for sliced VBI, or
  65          * CX18_ENC_STREAM_TYPE_IDX, if VBI insertion is off for sliced VBI
  66          * (We don't yet fix up MPEG Index entries for our inserted packets).
  67          *
  68          * For all other streams we're done.
  69          */
  70         if (type != CX18_ENC_STREAM_TYPE_MPG)
  71                 return 0;
  72 
  73         s_assoc = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
  74         if (cx->vbi.insert_mpeg && !cx18_raw_vbi(cx))
  75                 s_assoc = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
  76         else if (!cx18_stream_enabled(s_assoc))
  77                 return 0;
  78 
  79         set_bit(CX18_F_S_CLAIMED, &s_assoc->s_flags);
  80 
  81         /* mark that it is used internally */
  82         set_bit(CX18_F_S_INTERNAL_USE, &s_assoc->s_flags);
  83         return 0;
  84 }
  85 EXPORT_SYMBOL(cx18_claim_stream);
  86 
  87 /* This function releases a previously claimed stream. It will take into
  88    account associated VBI streams. */
  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                  * The IDX stream is only used internally, and can
  98                  * only be indirectly unclaimed by unclaiming the MPG stream.
  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                 /* this stream is still in use internally */
 106                 return;
 107         }
 108         if (!test_and_clear_bit(CX18_F_S_CLAIMED, &s->s_flags)) {
 109                 CX18_DEBUG_WARN("Release stream %s not in use!\n", s->name);
 110                 return;
 111         }
 112 
 113         cx18_flush_queues(s);
 114 
 115         /*
 116          * CX18_ENC_STREAM_TYPE_MPG needs to release the
 117          * CX18_ENC_STREAM_TYPE_VBI and/or CX18_ENC_STREAM_TYPE_IDX streams.
 118          *
 119          * For all other streams we're done.
 120          */
 121         if (s->type != CX18_ENC_STREAM_TYPE_MPG)
 122                 return;
 123 
 124         /* Unclaim the associated MPEG Index stream */
 125         s_assoc = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
 126         if (test_and_clear_bit(CX18_F_S_INTERNAL_USE, &s_assoc->s_flags)) {
 127                 clear_bit(CX18_F_S_CLAIMED, &s_assoc->s_flags);
 128                 cx18_flush_queues(s_assoc);
 129         }
 130 
 131         /* Unclaim the associated VBI stream */
 132         s_assoc = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
 133         if (test_and_clear_bit(CX18_F_S_INTERNAL_USE, &s_assoc->s_flags)) {
 134                 if (s_assoc->id == -1) {
 135                         /*
 136                          * The VBI stream is not still claimed by a file
 137                          * descriptor, so completely unclaim it.
 138                          */
 139                         clear_bit(CX18_F_S_CLAIMED, &s_assoc->s_flags);
 140                         cx18_flush_queues(s_assoc);
 141                 }
 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                         /* Process pending program updates and VBI data */
 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                                         /* byteswap and process VBI data */
 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                 /* do we have new data? */
 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                                 /* byteswap MPG data */
 208                                 cx18_mdl_swap(mdl);
 209                         else {
 210                                 /* byteswap and process VBI data */
 211                                 cx18_process_vbi_data(cx, mdl, s->type);
 212                         }
 213                         return mdl;
 214                 }
 215 
 216                 /* return if end of stream */
 217                 if (!test_bit(CX18_F_S_STREAMING, &s->s_flags)) {
 218                         CX18_DEBUG_INFO("EOS %s\n", s->name);
 219                         return NULL;
 220                 }
 221 
 222                 /* return if file was opened with O_NONBLOCK */
 223                 if (non_block) {
 224                         *err = -EAGAIN;
 225                         return NULL;
 226                 }
 227 
 228                 /* wait for more data to arrive */
 229                 prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE);
 230                 /* New buffers might have become available before we were added
 231                    to the waitqueue */
 232                 if (!atomic_read(&s->q_full.depth))
 233                         schedule();
 234                 finish_wait(&s->waitq, &wait);
 235                 if (signal_pending(current)) {
 236                         /* return if a signal was received */
 237                         CX18_DEBUG_INFO("User stopped %s\n", s->name);
 238                         *err = -EINTR;
 239                         return NULL;
 240                 }
 241         }
 242 }
 243 
 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                  * Try to find a good splice point in the PS, just before
 272                  * an MPEG-2 Program Pack start code, and provide only
 273                  * up to that point to the user, so it's easy to insert VBI data
 274                  * the next time around.
 275                  *
 276                  * This will not work for an MPEG-2 TS and has only been
 277                  * verified by analysis to work for an MPEG-2 PS.  Helen Buus
 278                  * pointed out this works for the CX23416 MPEG-2 DVD compatible
 279                  * stream, and research indicates both the MPEG 2 SVCD and DVD
 280                  * stream types use an MPEG-2 PS container.
 281                  */
 282                 /*
 283                  * An MPEG-2 Program Stream (PS) is a series of
 284                  * MPEG-2 Program Packs terminated by an
 285                  * MPEG Program End Code after the last Program Pack.
 286                  * A Program Pack may hold a PS System Header packet and any
 287                  * number of Program Elementary Stream (PES) Packets
 288                  */
 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                         /* Scan for a 0 to find a potential MPEG-2 start code */
 297                         q = memchr(p, 0, start + len - p);
 298                         if (q == NULL)
 299                                 break;
 300                         p = q + 1;
 301                         /*
 302                          * Keep looking if not a
 303                          * MPEG-2 Pack header start code:  0x00 0x00 0x01 0xba
 304                          * or MPEG-2 video PES start code: 0x00 0x00 0x01 0xe0
 305                          */
 306                         if ((char *)q + 15 >= buf->buf + buf->bytesused ||
 307                             q[1] != 0 || q[2] != 1 || q[3] != ch)
 308                                 continue;
 309 
 310                         /* If expecting the primary video PES */
 311                         if (!cx->search_pack_header) {
 312                                 /* Continue if it couldn't be a PES packet */
 313                                 if ((q[6] & 0xc0) != 0x80)
 314                                         continue;
 315                                 /* Check if a PTS or PTS & DTS follow */
 316                                 if (((q[7] & 0xc0) == 0x80 &&  /* PTS only */
 317                                      (q[9] & 0xf0) == 0x20) || /* PTS only */
 318                                     ((q[7] & 0xc0) == 0xc0 &&  /* PTS & DTS */
 319                                      (q[9] & 0xf0) == 0x30)) { /* DTS follows */
 320                                         /* Assume we found the video PES hdr */
 321                                         ch = 0xba; /* next want a Program Pack*/
 322                                         cx->search_pack_header = 1;
 323                                         p = q + 9; /* Skip this video PES hdr */
 324                                 }
 325                                 continue;
 326                         }
 327 
 328                         /* We may have found a Program Pack start code */
 329 
 330                         /* Get the count of stuffing bytes & verify them */
 331                         stuffing = q[13] & 7;
 332                         /* all stuffing bytes must be 0xff */
 333                         for (i = 0; i < stuffing; i++)
 334                                 if (q[14 + i] != 0xff)
 335                                         break;
 336                         if (i == stuffing && /* right number of stuffing bytes*/
 337                             (q[4] & 0xc4) == 0x44 && /* marker check */
 338                             (q[12] & 3) == 3 &&  /* marker check */
 339                             q[14 + stuffing] == 0 && /* PES Pack or Sys Hdr */
 340                             q[15 + stuffing] == 0 &&
 341                             q[16 + stuffing] == 1) {
 342                                 /* We declare we actually found a Program Pack*/
 343                                 cx->search_pack_header = 0; /* expect vid PES */
 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                  * For some reason we've exhausted the buffers, but the MDL
 377                  * object still said some data was unread.
 378                  * Fix that and bail out.
 379                  */
 380                 mdl->readpos = mdl->bytesused;
 381                 return 0;
 382         }
 383 
 384         list_for_each_entry_from(mdl->curr_buf, &mdl->buf_list, list) {
 385 
 386                 if (mdl->curr_buf->readpos >= mdl->curr_buf->bytesused)
 387                         continue;
 388 
 389                 rc = cx18_copy_buf_to_user(s, mdl->curr_buf, ubuf + tot_written,
 390                                            ucount - tot_written, &stop);
 391                 if (rc < 0)
 392                         return rc;
 393                 mdl->readpos += rc;
 394                 tot_written += rc;
 395 
 396                 if (stop ||     /* Forced stopping point for VBI insertion */
 397                     tot_written >= ucount ||    /* Reader request satisfied */
 398                     mdl->curr_buf->readpos < mdl->curr_buf->bytesused ||
 399                     mdl->readpos >= mdl->bytesused) /* MDL buffers drained */
 400                         break;
 401         }
 402         return tot_written;
 403 }
 404 
 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                 /* shouldn't happen */
 414                 CX18_DEBUG_WARN("Stream %s not initialized before read\n",
 415                                 s->name);
 416                 return -EIO;
 417         }
 418 
 419         /* Each VBI buffer is one frame, the v4l2 API says that for VBI the
 420            frames should arrive one-by-one, so make sure we never output more
 421            than one VBI frame at a time */
 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                 /* if there is no data available... */
 431                 if (mdl == NULL) {
 432                         /* if we got data, then return that regardless */
 433                         if (tot_written)
 434                                 break;
 435                         /* EOS condition */
 436                         if (rc == 0) {
 437                                 clear_bit(CX18_F_S_STREAMOFF, &s->s_flags);
 438                                 clear_bit(CX18_F_S_APPL_IO, &s->s_flags);
 439                                 cx18_release_stream(s);
 440                         }
 441                         /* set errno */
 442                         return rc;
 443                 }
 444 
 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                 /* you cannot read from these stream types. */
 491                 return -EPERM;
 492         }
 493 
 494         /* Try to claim this stream. */
 495         if (cx18_claim_stream(id, s->type))
 496                 return -EBUSY;
 497 
 498         /* If capture is already in progress, then we also have to
 499            do nothing extra. */
 500         if (test_bit(CX18_F_S_STREAMOFF, &s->s_flags) ||
 501             test_and_set_bit(CX18_F_S_STREAMING, &s->s_flags)) {
 502                 set_bit(CX18_F_S_APPL_IO, &s->s_flags);
 503                 return 0;
 504         }
 505 
 506         /* Start associated VBI or IDX stream capture if required */
 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                  * The VBI and IDX streams should have been claimed
 512                  * automatically, if for internal use, when the MPG stream was
 513                  * claimed.  We only need to start these streams capturing.
 514                  */
 515                 if (test_bit(CX18_F_S_INTERNAL_USE, &s_idx->s_flags) &&
 516                     !test_and_set_bit(CX18_F_S_STREAMING, &s_idx->s_flags)) {
 517                         if (cx18_start_v4l2_encode_stream(s_idx)) {
 518                                 CX18_DEBUG_WARN("IDX capture start failed\n");
 519                                 clear_bit(CX18_F_S_STREAMING, &s_idx->s_flags);
 520                                 goto start_failed;
 521                         }
 522                         CX18_DEBUG_INFO("IDX capture started\n");
 523                 }
 524                 if (test_bit(CX18_F_S_INTERNAL_USE, &s_vbi->s_flags) &&
 525                     !test_and_set_bit(CX18_F_S_STREAMING, &s_vbi->s_flags)) {
 526                         if (cx18_start_v4l2_encode_stream(s_vbi)) {
 527                                 CX18_DEBUG_WARN("VBI capture start failed\n");
 528                                 clear_bit(CX18_F_S_STREAMING, &s_vbi->s_flags);
 529                                 goto start_failed;
 530                         }
 531                         CX18_DEBUG_INFO("VBI insertion started\n");
 532                 }
 533         }
 534 
 535         /* Tell the card to start capturing */
 536         if (!cx18_start_v4l2_encode_stream(s)) {
 537                 /* We're done */
 538                 set_bit(CX18_F_S_APPL_IO, &s->s_flags);
 539                 /* Resume a possibly paused encoder */
 540                 if (test_and_clear_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags))
 541                         cx18_vapi(cx, CX18_CPU_CAPTURE_PAUSE, 1, s->handle);
 542                 return 0;
 543         }
 544 
 545 start_failed:
 546         CX18_DEBUG_WARN("Failed to start capturing for stream %s\n", s->name);
 547 
 548         /*
 549          * The associated VBI and IDX streams for internal use are released
 550          * automatically when the MPG stream is released.  We only need to stop
 551          * the associated stream.
 552          */
 553         if (s->type == CX18_ENC_STREAM_TYPE_MPG) {
 554                 /* Stop the IDX stream which is always for internal use */
 555                 if (test_bit(CX18_F_S_STREAMING, &s_idx->s_flags)) {
 556                         cx18_stop_v4l2_encode_stream(s_idx, 0);
 557                         clear_bit(CX18_F_S_STREAMING, &s_idx->s_flags);
 558                 }
 559                 /* Stop the VBI stream, if only running for internal use */
 560                 if (test_bit(CX18_F_S_STREAMING, &s_vbi->s_flags) &&
 561                     !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) {
 562                         cx18_stop_v4l2_encode_stream(s_vbi, 0);
 563                         clear_bit(CX18_F_S_STREAMING, &s_vbi->s_flags);
 564                 }
 565         }
 566         clear_bit(CX18_F_S_STREAMING, &s->s_flags);
 567         cx18_release_stream(s); /* Also releases associated streams */
 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         /* Start a capture if there is none */
 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         /* add stream's waitq to the poll list */
 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                 /* Start a capture if there is none */
 657                 if (!eof && !test_bit(CX18_F_S_STREAMING, &s->s_flags)) {
 658                         int rc;
 659 
 660                         mutex_lock(&cx->serialize_lock);
 661                         rc = cx18_start_capture(id);
 662                         mutex_unlock(&cx->serialize_lock);
 663                         if (rc) {
 664                                 CX18_DEBUG_INFO(
 665                                         "Could not start capture for %s (%d)\n",
 666                                         s->name, rc);
 667                                 return -EINVAL;
 668                         }
 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         /* Return all of the buffers in error state, so the vbi/vid inode
 685          * can return from blocking.
 686          */
 687         spin_lock_irqsave(&s->vb_lock, flags);
 688         while (!list_empty(&s->vb_capture)) {
 689                 buf = list_entry(s->vb_capture.next,
 690                         struct cx18_videobuf_buffer, vb.queue);
 691                 list_del(&buf->vb.queue);
 692                 buf->vb.state = VIDEOBUF_ERROR;
 693                 wake_up(&buf->vb.done);
 694         }
 695         spin_unlock_irqrestore(&s->vb_lock, flags);
 696 }
 697 
 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         /* 'Unclaim' this stream */
 708 
 709         /* Stop capturing */
 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                         /* Stop internal use associated VBI and IDX streams */
 714                         if (test_bit(CX18_F_S_STREAMING, &s_vbi->s_flags) &&
 715                             !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) {
 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                         /* Also used internally, don't stop capturing */
 727                         s->id = -1;
 728                 else
 729                         cx18_stop_v4l2_encode_stream(s, gop_end);
 730         }
 731         if (!gop_end) {
 732                 clear_bit(CX18_F_S_APPL_IO, &s->s_flags);
 733                 clear_bit(CX18_F_S_STREAMOFF, &s->s_flags);
 734                 cx18_release_stream(s);
 735         }
 736 }
 737 
 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         /* Stop radio */
 749         if (id->type == CX18_ENC_STREAM_TYPE_RAD &&
 750                         v4l2_fh_is_singular_file(filp)) {
 751                 /* Closing radio device, return to TV mode */
 752                 cx18_mute(cx);
 753                 /* Mark that the radio is no longer in use */
 754                 clear_bit(CX18_F_I_RADIO_USER, &cx->i_flags);
 755                 /* Switch tuner to TV */
 756                 cx18_call_all(cx, video, s_std, cx->std);
 757                 /* Select correct audio input (i.e. TV tuner or Line in) */
 758                 cx18_audio_set_io(cx);
 759                 if (atomic_read(&cx->ana_capturing) > 0) {
 760                         /* Undo video mute */
 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                 /* Done! Unmute and continue. */
 766                 cx18_unmute(cx);
 767         }
 768 
 769         v4l2_fh_del(fh);
 770         v4l2_fh_exit(fh);
 771 
 772         /* 'Unclaim' this stream */
 773         if (s->id == id->open_id)
 774                 cx18_stop_capture(id, 0);
 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         /* Allocate memory */
 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                                 /* switching to radio while capture is
 807                                    in progress is not polite */
 808                                 v4l2_fh_del(&item->fh);
 809                                 v4l2_fh_exit(&item->fh);
 810                                 kfree(item);
 811                                 return -EBUSY;
 812                         }
 813                 }
 814 
 815                 /* Mark that the radio is being used. */
 816                 set_bit(CX18_F_I_RADIO_USER, &cx->i_flags);
 817                 /* We have the radio */
 818                 cx18_mute(cx);
 819                 /* Switch tuner to radio */
 820                 cx18_call_all(cx, tuner, s_radio);
 821                 /* Select the correct audio input (i.e. radio tuner) */
 822                 cx18_audio_set_io(cx);
 823                 /* Done! Unmute and continue. */
 824                 cx18_unmute(cx);
 825         }
 826         return 0;
 827 }
 828 
 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 }

/* [<][>][^][v][top][bottom][index][help] */