linux/drivers/media/pci/cx18/cx18-fileops.c
<<
>>
Prefs
   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. */
  30int 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}
  85EXPORT_SYMBOL(cx18_claim_stream);
  86
  87/* This function releases a previously claimed stream. It will take into
  88   account associated VBI streams. */
  89void 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}
 144EXPORT_SYMBOL(cx18_release_stream);
 145
 146static 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
 169static 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
 244static 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
 259static 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
 363static 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
 405static 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
 470static 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
 482int 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
 545start_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
 571ssize_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
 646int 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
 678void 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
 698void 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
 738int 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
 780static 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
 829int 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
 848void 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
 861void 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}
 875