linux/drivers/media/pci/cx18/cx18-fileops.c
<<
>>
Prefs
   1/*
   2 *  cx18 file operation functions
   3 *
   4 *  Derived from ivtv-fileops.c
   5 *
   6 *  Copyright (C) 2007  Hans Verkuil <hverkuil@xs4all.nl>
   7 *  Copyright (C) 2008  Andy Walls <awalls@md.metrocast.net>
   8 *
   9 *  This program is free software; you can redistribute it and/or modify
  10 *  it under the terms of the GNU General Public License as published by
  11 *  the Free Software Foundation; either version 2 of the License, or
  12 *  (at your option) any later version.
  13 *
  14 *  This program is distributed in the hope that it will be useful,
  15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17 *  GNU General Public License for more details.
  18 *
  19 *  You should have received a copy of the GNU General Public License
  20 *  along with this program; if not, write to the Free Software
  21 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  22 *  02111-1307  USA
  23 */
  24
  25#include "cx18-driver.h"
  26#include "cx18-fileops.h"
  27#include "cx18-i2c.h"
  28#include "cx18-queue.h"
  29#include "cx18-vbi.h"
  30#include "cx18-audio.h"
  31#include "cx18-mailbox.h"
  32#include "cx18-scb.h"
  33#include "cx18-streams.h"
  34#include "cx18-controls.h"
  35#include "cx18-ioctl.h"
  36#include "cx18-cards.h"
  37#include <media/v4l2-event.h>
  38
  39/* This function tries to claim the stream for a specific file descriptor.
  40   If no one else is using this stream then the stream is claimed and
  41   associated VBI and IDX streams are also automatically claimed.
  42   Possible error returns: -EBUSY if someone else has claimed
  43   the stream or 0 on success. */
  44int cx18_claim_stream(struct cx18_open_id *id, int type)
  45{
  46        struct cx18 *cx = id->cx;
  47        struct cx18_stream *s = &cx->streams[type];
  48        struct cx18_stream *s_assoc;
  49
  50        /* Nothing should ever try to directly claim the IDX stream */
  51        if (type == CX18_ENC_STREAM_TYPE_IDX) {
  52                CX18_WARN("MPEG Index stream cannot be claimed "
  53                          "directly, but something tried.\n");
  54                return -EINVAL;
  55        }
  56
  57        if (test_and_set_bit(CX18_F_S_CLAIMED, &s->s_flags)) {
  58                /* someone already claimed this stream */
  59                if (s->id == id->open_id) {
  60                        /* yes, this file descriptor did. So that's OK. */
  61                        return 0;
  62                }
  63                if (s->id == -1 && type == CX18_ENC_STREAM_TYPE_VBI) {
  64                        /* VBI is handled already internally, now also assign
  65                           the file descriptor to this stream for external
  66                           reading of the stream. */
  67                        s->id = id->open_id;
  68                        CX18_DEBUG_INFO("Start Read VBI\n");
  69                        return 0;
  70                }
  71                /* someone else is using this stream already */
  72                CX18_DEBUG_INFO("Stream %d is busy\n", type);
  73                return -EBUSY;
  74        }
  75        s->id = id->open_id;
  76
  77        /*
  78         * CX18_ENC_STREAM_TYPE_MPG needs to claim:
  79         * CX18_ENC_STREAM_TYPE_VBI, if VBI insertion is on for sliced VBI, or
  80         * CX18_ENC_STREAM_TYPE_IDX, if VBI insertion is off for sliced VBI
  81         * (We don't yet fix up MPEG Index entries for our inserted packets).
  82         *
  83         * For all other streams we're done.
  84         */
  85        if (type != CX18_ENC_STREAM_TYPE_MPG)
  86                return 0;
  87
  88        s_assoc = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
  89        if (cx->vbi.insert_mpeg && !cx18_raw_vbi(cx))
  90                s_assoc = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
  91        else if (!cx18_stream_enabled(s_assoc))
  92                return 0;
  93
  94        set_bit(CX18_F_S_CLAIMED, &s_assoc->s_flags);
  95
  96        /* mark that it is used internally */
  97        set_bit(CX18_F_S_INTERNAL_USE, &s_assoc->s_flags);
  98        return 0;
  99}
 100EXPORT_SYMBOL(cx18_claim_stream);
 101
 102/* This function releases a previously claimed stream. It will take into
 103   account associated VBI streams. */
 104void cx18_release_stream(struct cx18_stream *s)
 105{
 106        struct cx18 *cx = s->cx;
 107        struct cx18_stream *s_assoc;
 108
 109        s->id = -1;
 110        if (s->type == CX18_ENC_STREAM_TYPE_IDX) {
 111                /*
 112                 * The IDX stream is only used internally, and can
 113                 * only be indirectly unclaimed by unclaiming the MPG stream.
 114                 */
 115                return;
 116        }
 117
 118        if (s->type == CX18_ENC_STREAM_TYPE_VBI &&
 119                test_bit(CX18_F_S_INTERNAL_USE, &s->s_flags)) {
 120                /* this stream is still in use internally */
 121                return;
 122        }
 123        if (!test_and_clear_bit(CX18_F_S_CLAIMED, &s->s_flags)) {
 124                CX18_DEBUG_WARN("Release stream %s not in use!\n", s->name);
 125                return;
 126        }
 127
 128        cx18_flush_queues(s);
 129
 130        /*
 131         * CX18_ENC_STREAM_TYPE_MPG needs to release the
 132         * CX18_ENC_STREAM_TYPE_VBI and/or CX18_ENC_STREAM_TYPE_IDX streams.
 133         *
 134         * For all other streams we're done.
 135         */
 136        if (s->type != CX18_ENC_STREAM_TYPE_MPG)
 137                return;
 138
 139        /* Unclaim the associated MPEG Index stream */
 140        s_assoc = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
 141        if (test_and_clear_bit(CX18_F_S_INTERNAL_USE, &s_assoc->s_flags)) {
 142                clear_bit(CX18_F_S_CLAIMED, &s_assoc->s_flags);
 143                cx18_flush_queues(s_assoc);
 144        }
 145
 146        /* Unclaim the associated VBI stream */
 147        s_assoc = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
 148        if (test_and_clear_bit(CX18_F_S_INTERNAL_USE, &s_assoc->s_flags)) {
 149                if (s_assoc->id == -1) {
 150                        /*
 151                         * The VBI stream is not still claimed by a file
 152                         * descriptor, so completely unclaim it.
 153                         */
 154                        clear_bit(CX18_F_S_CLAIMED, &s_assoc->s_flags);
 155                        cx18_flush_queues(s_assoc);
 156                }
 157        }
 158}
 159EXPORT_SYMBOL(cx18_release_stream);
 160
 161static void cx18_dualwatch(struct cx18 *cx)
 162{
 163        struct v4l2_tuner vt;
 164        u32 new_stereo_mode;
 165        const u32 dual = 0x0200;
 166
 167        new_stereo_mode = v4l2_ctrl_g_ctrl(cx->cxhdl.audio_mode);
 168        memset(&vt, 0, sizeof(vt));
 169        cx18_call_all(cx, tuner, g_tuner, &vt);
 170        if (vt.audmode == V4L2_TUNER_MODE_LANG1_LANG2 &&
 171                        (vt.rxsubchans & V4L2_TUNER_SUB_LANG2))
 172                new_stereo_mode = dual;
 173
 174        if (new_stereo_mode == cx->dualwatch_stereo_mode)
 175                return;
 176
 177        CX18_DEBUG_INFO("dualwatch: change stereo flag from 0x%x to 0x%x.\n",
 178                           cx->dualwatch_stereo_mode, new_stereo_mode);
 179        if (v4l2_ctrl_s_ctrl(cx->cxhdl.audio_mode, new_stereo_mode))
 180                CX18_DEBUG_INFO("dualwatch: changing stereo flag failed\n");
 181}
 182
 183
 184static struct cx18_mdl *cx18_get_mdl(struct cx18_stream *s, int non_block,
 185                                     int *err)
 186{
 187        struct cx18 *cx = s->cx;
 188        struct cx18_stream *s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
 189        struct cx18_mdl *mdl;
 190        DEFINE_WAIT(wait);
 191
 192        *err = 0;
 193        while (1) {
 194                if (s->type == CX18_ENC_STREAM_TYPE_MPG) {
 195                        /* Process pending program updates and VBI data */
 196                        if (time_after(jiffies, cx->dualwatch_jiffies + msecs_to_jiffies(1000))) {
 197                                cx->dualwatch_jiffies = jiffies;
 198                                cx18_dualwatch(cx);
 199                        }
 200                        if (test_bit(CX18_F_S_INTERNAL_USE, &s_vbi->s_flags) &&
 201                            !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) {
 202                                while ((mdl = cx18_dequeue(s_vbi,
 203                                                           &s_vbi->q_full))) {
 204                                        /* byteswap and process VBI data */
 205                                        cx18_process_vbi_data(cx, mdl,
 206                                                              s_vbi->type);
 207                                        cx18_stream_put_mdl_fw(s_vbi, mdl);
 208                                }
 209                        }
 210                        mdl = &cx->vbi.sliced_mpeg_mdl;
 211                        if (mdl->readpos != mdl->bytesused)
 212                                return mdl;
 213                }
 214
 215                /* do we have new data? */
 216                mdl = cx18_dequeue(s, &s->q_full);
 217                if (mdl) {
 218                        if (!test_and_clear_bit(CX18_F_M_NEED_SWAP,
 219                                                &mdl->m_flags))
 220                                return mdl;
 221                        if (s->type == CX18_ENC_STREAM_TYPE_MPG)
 222                                /* byteswap MPG data */
 223                                cx18_mdl_swap(mdl);
 224                        else {
 225                                /* byteswap and process VBI data */
 226                                cx18_process_vbi_data(cx, mdl, s->type);
 227                        }
 228                        return mdl;
 229                }
 230
 231                /* return if end of stream */
 232                if (!test_bit(CX18_F_S_STREAMING, &s->s_flags)) {
 233                        CX18_DEBUG_INFO("EOS %s\n", s->name);
 234                        return NULL;
 235                }
 236
 237                /* return if file was opened with O_NONBLOCK */
 238                if (non_block) {
 239                        *err = -EAGAIN;
 240                        return NULL;
 241                }
 242
 243                /* wait for more data to arrive */
 244                prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE);
 245                /* New buffers might have become available before we were added
 246                   to the waitqueue */
 247                if (!atomic_read(&s->q_full.depth))
 248                        schedule();
 249                finish_wait(&s->waitq, &wait);
 250                if (signal_pending(current)) {
 251                        /* return if a signal was received */
 252                        CX18_DEBUG_INFO("User stopped %s\n", s->name);
 253                        *err = -EINTR;
 254                        return NULL;
 255                }
 256        }
 257}
 258
 259static void cx18_setup_sliced_vbi_mdl(struct cx18 *cx)
 260{
 261        struct cx18_mdl *mdl = &cx->vbi.sliced_mpeg_mdl;
 262        struct cx18_buffer *buf = &cx->vbi.sliced_mpeg_buf;
 263        int idx = cx->vbi.inserted_frame % CX18_VBI_FRAMES;
 264
 265        buf->buf = cx->vbi.sliced_mpeg_data[idx];
 266        buf->bytesused = cx->vbi.sliced_mpeg_size[idx];
 267        buf->readpos = 0;
 268
 269        mdl->curr_buf = NULL;
 270        mdl->bytesused = cx->vbi.sliced_mpeg_size[idx];
 271        mdl->readpos = 0;
 272}
 273
 274static size_t cx18_copy_buf_to_user(struct cx18_stream *s,
 275        struct cx18_buffer *buf, char __user *ubuf, size_t ucount, bool *stop)
 276{
 277        struct cx18 *cx = s->cx;
 278        size_t len = buf->bytesused - buf->readpos;
 279
 280        *stop = false;
 281        if (len > ucount)
 282                len = ucount;
 283        if (cx->vbi.insert_mpeg && s->type == CX18_ENC_STREAM_TYPE_MPG &&
 284            !cx18_raw_vbi(cx) && buf != &cx->vbi.sliced_mpeg_buf) {
 285                /*
 286                 * Try to find a good splice point in the PS, just before
 287                 * an MPEG-2 Program Pack start code, and provide only
 288                 * up to that point to the user, so it's easy to insert VBI data
 289                 * the next time around.
 290                 *
 291                 * This will not work for an MPEG-2 TS and has only been
 292                 * verified by analysis to work for an MPEG-2 PS.  Helen Buus
 293                 * pointed out this works for the CX23416 MPEG-2 DVD compatible
 294                 * stream, and research indicates both the MPEG 2 SVCD and DVD
 295                 * stream types use an MPEG-2 PS container.
 296                 */
 297                /*
 298                 * An MPEG-2 Program Stream (PS) is a series of
 299                 * MPEG-2 Program Packs terminated by an
 300                 * MPEG Program End Code after the last Program Pack.
 301                 * A Program Pack may hold a PS System Header packet and any
 302                 * number of Program Elementary Stream (PES) Packets
 303                 */
 304                const char *start = buf->buf + buf->readpos;
 305                const char *p = start + 1;
 306                const u8 *q;
 307                u8 ch = cx->search_pack_header ? 0xba : 0xe0;
 308                int stuffing, i;
 309
 310                while (start + len > p) {
 311                        /* Scan for a 0 to find a potential MPEG-2 start code */
 312                        q = memchr(p, 0, start + len - p);
 313                        if (q == NULL)
 314                                break;
 315                        p = q + 1;
 316                        /*
 317                         * Keep looking if not a
 318                         * MPEG-2 Pack header start code:  0x00 0x00 0x01 0xba
 319                         * or MPEG-2 video PES start code: 0x00 0x00 0x01 0xe0
 320                         */
 321                        if ((char *)q + 15 >= buf->buf + buf->bytesused ||
 322                            q[1] != 0 || q[2] != 1 || q[3] != ch)
 323                                continue;
 324
 325                        /* If expecting the primary video PES */
 326                        if (!cx->search_pack_header) {
 327                                /* Continue if it couldn't be a PES packet */
 328                                if ((q[6] & 0xc0) != 0x80)
 329                                        continue;
 330                                /* Check if a PTS or PTS & DTS follow */
 331                                if (((q[7] & 0xc0) == 0x80 &&  /* PTS only */
 332                                     (q[9] & 0xf0) == 0x20) || /* PTS only */
 333                                    ((q[7] & 0xc0) == 0xc0 &&  /* PTS & DTS */
 334                                     (q[9] & 0xf0) == 0x30)) { /* DTS follows */
 335                                        /* Assume we found the video PES hdr */
 336                                        ch = 0xba; /* next want a Program Pack*/
 337                                        cx->search_pack_header = 1;
 338                                        p = q + 9; /* Skip this video PES hdr */
 339                                }
 340                                continue;
 341                        }
 342
 343                        /* We may have found a Program Pack start code */
 344
 345                        /* Get the count of stuffing bytes & verify them */
 346                        stuffing = q[13] & 7;
 347                        /* all stuffing bytes must be 0xff */
 348                        for (i = 0; i < stuffing; i++)
 349                                if (q[14 + i] != 0xff)
 350                                        break;
 351                        if (i == stuffing && /* right number of stuffing bytes*/
 352                            (q[4] & 0xc4) == 0x44 && /* marker check */
 353                            (q[12] & 3) == 3 &&  /* marker check */
 354                            q[14 + stuffing] == 0 && /* PES Pack or Sys Hdr */
 355                            q[15 + stuffing] == 0 &&
 356                            q[16 + stuffing] == 1) {
 357                                /* We declare we actually found a Program Pack*/
 358                                cx->search_pack_header = 0; /* expect vid PES */
 359                                len = (char *)q - start;
 360                                cx18_setup_sliced_vbi_mdl(cx);
 361                                *stop = true;
 362                                break;
 363                        }
 364                }
 365        }
 366        if (copy_to_user(ubuf, (u8 *)buf->buf + buf->readpos, len)) {
 367                CX18_DEBUG_WARN("copy %zd bytes to user failed for %s\n",
 368                                len, s->name);
 369                return -EFAULT;
 370        }
 371        buf->readpos += len;
 372        if (s->type == CX18_ENC_STREAM_TYPE_MPG &&
 373            buf != &cx->vbi.sliced_mpeg_buf)
 374                cx->mpg_data_received += len;
 375        return len;
 376}
 377
 378static size_t cx18_copy_mdl_to_user(struct cx18_stream *s,
 379                struct cx18_mdl *mdl, char __user *ubuf, size_t ucount)
 380{
 381        size_t tot_written = 0;
 382        int rc;
 383        bool stop = false;
 384
 385        if (mdl->curr_buf == NULL)
 386                mdl->curr_buf = list_first_entry(&mdl->buf_list,
 387                                                 struct cx18_buffer, list);
 388
 389        if (list_entry_is_past_end(mdl->curr_buf, &mdl->buf_list, list)) {
 390                /*
 391                 * For some reason we've exhausted the buffers, but the MDL
 392                 * object still said some data was unread.
 393                 * Fix that and bail out.
 394                 */
 395                mdl->readpos = mdl->bytesused;
 396                return 0;
 397        }
 398
 399        list_for_each_entry_from(mdl->curr_buf, &mdl->buf_list, list) {
 400
 401                if (mdl->curr_buf->readpos >= mdl->curr_buf->bytesused)
 402                        continue;
 403
 404                rc = cx18_copy_buf_to_user(s, mdl->curr_buf, ubuf + tot_written,
 405                                           ucount - tot_written, &stop);
 406                if (rc < 0)
 407                        return rc;
 408                mdl->readpos += rc;
 409                tot_written += rc;
 410
 411                if (stop ||     /* Forced stopping point for VBI insertion */
 412                    tot_written >= ucount ||    /* Reader request statisfied */
 413                    mdl->curr_buf->readpos < mdl->curr_buf->bytesused ||
 414                    mdl->readpos >= mdl->bytesused) /* MDL buffers drained */
 415                        break;
 416        }
 417        return tot_written;
 418}
 419
 420static ssize_t cx18_read(struct cx18_stream *s, char __user *ubuf,
 421                size_t tot_count, int non_block)
 422{
 423        struct cx18 *cx = s->cx;
 424        size_t tot_written = 0;
 425        int single_frame = 0;
 426
 427        if (atomic_read(&cx->ana_capturing) == 0 && s->id == -1) {
 428                /* shouldn't happen */
 429                CX18_DEBUG_WARN("Stream %s not initialized before read\n",
 430                                s->name);
 431                return -EIO;
 432        }
 433
 434        /* Each VBI buffer is one frame, the v4l2 API says that for VBI the
 435           frames should arrive one-by-one, so make sure we never output more
 436           than one VBI frame at a time */
 437        if (s->type == CX18_ENC_STREAM_TYPE_VBI && !cx18_raw_vbi(cx))
 438                single_frame = 1;
 439
 440        for (;;) {
 441                struct cx18_mdl *mdl;
 442                int rc;
 443
 444                mdl = cx18_get_mdl(s, non_block, &rc);
 445                /* if there is no data available... */
 446                if (mdl == NULL) {
 447                        /* if we got data, then return that regardless */
 448                        if (tot_written)
 449                                break;
 450                        /* EOS condition */
 451                        if (rc == 0) {
 452                                clear_bit(CX18_F_S_STREAMOFF, &s->s_flags);
 453                                clear_bit(CX18_F_S_APPL_IO, &s->s_flags);
 454                                cx18_release_stream(s);
 455                        }
 456                        /* set errno */
 457                        return rc;
 458                }
 459
 460                rc = cx18_copy_mdl_to_user(s, mdl, ubuf + tot_written,
 461                                tot_count - tot_written);
 462
 463                if (mdl != &cx->vbi.sliced_mpeg_mdl) {
 464                        if (mdl->readpos == mdl->bytesused)
 465                                cx18_stream_put_mdl_fw(s, mdl);
 466                        else
 467                                cx18_push(s, mdl, &s->q_full);
 468                } else if (mdl->readpos == mdl->bytesused) {
 469                        int idx = cx->vbi.inserted_frame % CX18_VBI_FRAMES;
 470
 471                        cx->vbi.sliced_mpeg_size[idx] = 0;
 472                        cx->vbi.inserted_frame++;
 473                        cx->vbi_data_inserted += mdl->bytesused;
 474                }
 475                if (rc < 0)
 476                        return rc;
 477                tot_written += rc;
 478
 479                if (tot_written == tot_count || single_frame)
 480                        break;
 481        }
 482        return tot_written;
 483}
 484
 485static ssize_t cx18_read_pos(struct cx18_stream *s, char __user *ubuf,
 486                size_t count, loff_t *pos, int non_block)
 487{
 488        ssize_t rc = count ? cx18_read(s, ubuf, count, non_block) : 0;
 489        struct cx18 *cx = s->cx;
 490
 491        CX18_DEBUG_HI_FILE("read %zd from %s, got %zd\n", count, s->name, rc);
 492        if (rc > 0)
 493                pos += rc;
 494        return rc;
 495}
 496
 497int cx18_start_capture(struct cx18_open_id *id)
 498{
 499        struct cx18 *cx = id->cx;
 500        struct cx18_stream *s = &cx->streams[id->type];
 501        struct cx18_stream *s_vbi;
 502        struct cx18_stream *s_idx;
 503
 504        if (s->type == CX18_ENC_STREAM_TYPE_RAD) {
 505                /* you cannot read from these stream types. */
 506                return -EPERM;
 507        }
 508
 509        /* Try to claim this stream. */
 510        if (cx18_claim_stream(id, s->type))
 511                return -EBUSY;
 512
 513        /* If capture is already in progress, then we also have to
 514           do nothing extra. */
 515        if (test_bit(CX18_F_S_STREAMOFF, &s->s_flags) ||
 516            test_and_set_bit(CX18_F_S_STREAMING, &s->s_flags)) {
 517                set_bit(CX18_F_S_APPL_IO, &s->s_flags);
 518                return 0;
 519        }
 520
 521        /* Start associated VBI or IDX stream capture if required */
 522        s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
 523        s_idx = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
 524        if (s->type == CX18_ENC_STREAM_TYPE_MPG) {
 525                /*
 526                 * The VBI and IDX streams should have been claimed
 527                 * automatically, if for internal use, when the MPG stream was
 528                 * claimed.  We only need to start these streams capturing.
 529                 */
 530                if (test_bit(CX18_F_S_INTERNAL_USE, &s_idx->s_flags) &&
 531                    !test_and_set_bit(CX18_F_S_STREAMING, &s_idx->s_flags)) {
 532                        if (cx18_start_v4l2_encode_stream(s_idx)) {
 533                                CX18_DEBUG_WARN("IDX capture start failed\n");
 534                                clear_bit(CX18_F_S_STREAMING, &s_idx->s_flags);
 535                                goto start_failed;
 536                        }
 537                        CX18_DEBUG_INFO("IDX capture started\n");
 538                }
 539                if (test_bit(CX18_F_S_INTERNAL_USE, &s_vbi->s_flags) &&
 540                    !test_and_set_bit(CX18_F_S_STREAMING, &s_vbi->s_flags)) {
 541                        if (cx18_start_v4l2_encode_stream(s_vbi)) {
 542                                CX18_DEBUG_WARN("VBI capture start failed\n");
 543                                clear_bit(CX18_F_S_STREAMING, &s_vbi->s_flags);
 544                                goto start_failed;
 545                        }
 546                        CX18_DEBUG_INFO("VBI insertion started\n");
 547                }
 548        }
 549
 550        /* Tell the card to start capturing */
 551        if (!cx18_start_v4l2_encode_stream(s)) {
 552                /* We're done */
 553                set_bit(CX18_F_S_APPL_IO, &s->s_flags);
 554                /* Resume a possibly paused encoder */
 555                if (test_and_clear_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags))
 556                        cx18_vapi(cx, CX18_CPU_CAPTURE_PAUSE, 1, s->handle);
 557                return 0;
 558        }
 559
 560start_failed:
 561        CX18_DEBUG_WARN("Failed to start capturing for stream %s\n", s->name);
 562
 563        /*
 564         * The associated VBI and IDX streams for internal use are released
 565         * automatically when the MPG stream is released.  We only need to stop
 566         * the associated stream.
 567         */
 568        if (s->type == CX18_ENC_STREAM_TYPE_MPG) {
 569                /* Stop the IDX stream which is always for internal use */
 570                if (test_bit(CX18_F_S_STREAMING, &s_idx->s_flags)) {
 571                        cx18_stop_v4l2_encode_stream(s_idx, 0);
 572                        clear_bit(CX18_F_S_STREAMING, &s_idx->s_flags);
 573                }
 574                /* Stop the VBI stream, if only running for internal use */
 575                if (test_bit(CX18_F_S_STREAMING, &s_vbi->s_flags) &&
 576                    !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) {
 577                        cx18_stop_v4l2_encode_stream(s_vbi, 0);
 578                        clear_bit(CX18_F_S_STREAMING, &s_vbi->s_flags);
 579                }
 580        }
 581        clear_bit(CX18_F_S_STREAMING, &s->s_flags);
 582        cx18_release_stream(s); /* Also releases associated streams */
 583        return -EIO;
 584}
 585
 586ssize_t cx18_v4l2_read(struct file *filp, char __user *buf, size_t count,
 587                loff_t *pos)
 588{
 589        struct cx18_open_id *id = file2id(filp);
 590        struct cx18 *cx = id->cx;
 591        struct cx18_stream *s = &cx->streams[id->type];
 592        int rc;
 593
 594        CX18_DEBUG_HI_FILE("read %zd bytes from %s\n", count, s->name);
 595
 596        mutex_lock(&cx->serialize_lock);
 597        rc = cx18_start_capture(id);
 598        mutex_unlock(&cx->serialize_lock);
 599        if (rc)
 600                return rc;
 601
 602        if ((s->vb_type == V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
 603                (id->type == CX18_ENC_STREAM_TYPE_YUV)) {
 604                return videobuf_read_stream(&s->vbuf_q, buf, count, pos, 0,
 605                        filp->f_flags & O_NONBLOCK);
 606        }
 607
 608        return cx18_read_pos(s, buf, count, pos, filp->f_flags & O_NONBLOCK);
 609}
 610
 611unsigned int cx18_v4l2_enc_poll(struct file *filp, poll_table *wait)
 612{
 613        unsigned long req_events = poll_requested_events(wait);
 614        struct cx18_open_id *id = file2id(filp);
 615        struct cx18 *cx = id->cx;
 616        struct cx18_stream *s = &cx->streams[id->type];
 617        int eof = test_bit(CX18_F_S_STREAMOFF, &s->s_flags);
 618        unsigned res = 0;
 619
 620        /* Start a capture if there is none */
 621        if (!eof && !test_bit(CX18_F_S_STREAMING, &s->s_flags) &&
 622                        (req_events & (POLLIN | POLLRDNORM))) {
 623                int rc;
 624
 625                mutex_lock(&cx->serialize_lock);
 626                rc = cx18_start_capture(id);
 627                mutex_unlock(&cx->serialize_lock);
 628                if (rc) {
 629                        CX18_DEBUG_INFO("Could not start capture for %s (%d)\n",
 630                                        s->name, rc);
 631                        return POLLERR;
 632                }
 633                CX18_DEBUG_FILE("Encoder poll started capture\n");
 634        }
 635
 636        if ((s->vb_type == V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
 637                (id->type == CX18_ENC_STREAM_TYPE_YUV)) {
 638                int videobuf_poll = videobuf_poll_stream(filp, &s->vbuf_q, wait);
 639
 640                if (v4l2_event_pending(&id->fh))
 641                        res |= POLLPRI;
 642                if (eof && videobuf_poll == POLLERR)
 643                        return res | POLLHUP;
 644                return res | videobuf_poll;
 645        }
 646
 647        /* add stream's waitq to the poll list */
 648        CX18_DEBUG_HI_FILE("Encoder poll\n");
 649        if (v4l2_event_pending(&id->fh))
 650                res |= POLLPRI;
 651        else
 652                poll_wait(filp, &s->waitq, wait);
 653
 654        if (atomic_read(&s->q_full.depth))
 655                return res | POLLIN | POLLRDNORM;
 656        if (eof)
 657                return res | POLLHUP;
 658        return res;
 659}
 660
 661int cx18_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
 662{
 663        struct cx18_open_id *id = file->private_data;
 664        struct cx18 *cx = id->cx;
 665        struct cx18_stream *s = &cx->streams[id->type];
 666        int eof = test_bit(CX18_F_S_STREAMOFF, &s->s_flags);
 667
 668        if ((s->vb_type == V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
 669                (id->type == CX18_ENC_STREAM_TYPE_YUV)) {
 670
 671                /* Start a capture if there is none */
 672                if (!eof && !test_bit(CX18_F_S_STREAMING, &s->s_flags)) {
 673                        int rc;
 674
 675                        mutex_lock(&cx->serialize_lock);
 676                        rc = cx18_start_capture(id);
 677                        mutex_unlock(&cx->serialize_lock);
 678                        if (rc) {
 679                                CX18_DEBUG_INFO(
 680                                        "Could not start capture for %s (%d)\n",
 681                                        s->name, rc);
 682                                return -EINVAL;
 683                        }
 684                        CX18_DEBUG_FILE("Encoder mmap started capture\n");
 685                }
 686
 687                return videobuf_mmap_mapper(&s->vbuf_q, vma);
 688        }
 689
 690        return -EINVAL;
 691}
 692
 693void cx18_vb_timeout(unsigned long data)
 694{
 695        struct cx18_stream *s = (struct cx18_stream *)data;
 696        struct cx18_videobuf_buffer *buf;
 697        unsigned long flags;
 698
 699        /* Return all of the buffers in error state, so the vbi/vid inode
 700         * can return from blocking.
 701         */
 702        spin_lock_irqsave(&s->vb_lock, flags);
 703        while (!list_empty(&s->vb_capture)) {
 704                buf = list_entry(s->vb_capture.next,
 705                        struct cx18_videobuf_buffer, vb.queue);
 706                list_del(&buf->vb.queue);
 707                buf->vb.state = VIDEOBUF_ERROR;
 708                wake_up(&buf->vb.done);
 709        }
 710        spin_unlock_irqrestore(&s->vb_lock, flags);
 711}
 712
 713void cx18_stop_capture(struct cx18_open_id *id, int gop_end)
 714{
 715        struct cx18 *cx = id->cx;
 716        struct cx18_stream *s = &cx->streams[id->type];
 717        struct cx18_stream *s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
 718        struct cx18_stream *s_idx = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
 719
 720        CX18_DEBUG_IOCTL("close() of %s\n", s->name);
 721
 722        /* 'Unclaim' this stream */
 723
 724        /* Stop capturing */
 725        if (test_bit(CX18_F_S_STREAMING, &s->s_flags)) {
 726                CX18_DEBUG_INFO("close stopping capture\n");
 727                if (id->type == CX18_ENC_STREAM_TYPE_MPG) {
 728                        /* Stop internal use associated VBI and IDX streams */
 729                        if (test_bit(CX18_F_S_STREAMING, &s_vbi->s_flags) &&
 730                            !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) {
 731                                CX18_DEBUG_INFO("close stopping embedded VBI "
 732                                                "capture\n");
 733                                cx18_stop_v4l2_encode_stream(s_vbi, 0);
 734                        }
 735                        if (test_bit(CX18_F_S_STREAMING, &s_idx->s_flags)) {
 736                                CX18_DEBUG_INFO("close stopping IDX capture\n");
 737                                cx18_stop_v4l2_encode_stream(s_idx, 0);
 738                        }
 739                }
 740                if (id->type == CX18_ENC_STREAM_TYPE_VBI &&
 741                    test_bit(CX18_F_S_INTERNAL_USE, &s->s_flags))
 742                        /* Also used internally, don't stop capturing */
 743                        s->id = -1;
 744                else
 745                        cx18_stop_v4l2_encode_stream(s, gop_end);
 746        }
 747        if (!gop_end) {
 748                clear_bit(CX18_F_S_APPL_IO, &s->s_flags);
 749                clear_bit(CX18_F_S_STREAMOFF, &s->s_flags);
 750                cx18_release_stream(s);
 751        }
 752}
 753
 754int cx18_v4l2_close(struct file *filp)
 755{
 756        struct v4l2_fh *fh = filp->private_data;
 757        struct cx18_open_id *id = fh2id(fh);
 758        struct cx18 *cx = id->cx;
 759        struct cx18_stream *s = &cx->streams[id->type];
 760
 761        CX18_DEBUG_IOCTL("close() of %s\n", s->name);
 762
 763        mutex_lock(&cx->serialize_lock);
 764        /* Stop radio */
 765        if (id->type == CX18_ENC_STREAM_TYPE_RAD &&
 766                        v4l2_fh_is_singular_file(filp)) {
 767                /* Closing radio device, return to TV mode */
 768                cx18_mute(cx);
 769                /* Mark that the radio is no longer in use */
 770                clear_bit(CX18_F_I_RADIO_USER, &cx->i_flags);
 771                /* Switch tuner to TV */
 772                cx18_call_all(cx, video, s_std, cx->std);
 773                /* Select correct audio input (i.e. TV tuner or Line in) */
 774                cx18_audio_set_io(cx);
 775                if (atomic_read(&cx->ana_capturing) > 0) {
 776                        /* Undo video mute */
 777                        cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2, s->handle,
 778                            (v4l2_ctrl_g_ctrl(cx->cxhdl.video_mute) |
 779                            (v4l2_ctrl_g_ctrl(cx->cxhdl.video_mute_yuv) << 8)));
 780                }
 781                /* Done! Unmute and continue. */
 782                cx18_unmute(cx);
 783        }
 784
 785        v4l2_fh_del(fh);
 786        v4l2_fh_exit(fh);
 787
 788        /* 'Unclaim' this stream */
 789        if (s->id == id->open_id)
 790                cx18_stop_capture(id, 0);
 791        kfree(id);
 792        mutex_unlock(&cx->serialize_lock);
 793        return 0;
 794}
 795
 796static int cx18_serialized_open(struct cx18_stream *s, struct file *filp)
 797{
 798        struct cx18 *cx = s->cx;
 799        struct cx18_open_id *item;
 800
 801        CX18_DEBUG_FILE("open %s\n", s->name);
 802
 803        /* Allocate memory */
 804        item = kzalloc(sizeof(struct cx18_open_id), GFP_KERNEL);
 805        if (NULL == item) {
 806                CX18_DEBUG_WARN("nomem on v4l2 open\n");
 807                return -ENOMEM;
 808        }
 809        v4l2_fh_init(&item->fh, &s->video_dev);
 810
 811        item->cx = cx;
 812        item->type = s->type;
 813
 814        item->open_id = cx->open_id++;
 815        filp->private_data = &item->fh;
 816        v4l2_fh_add(&item->fh);
 817
 818        if (item->type == CX18_ENC_STREAM_TYPE_RAD &&
 819                        v4l2_fh_is_singular_file(filp)) {
 820                if (!test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) {
 821                        if (atomic_read(&cx->ana_capturing) > 0) {
 822                                /* switching to radio while capture is
 823                                   in progress is not polite */
 824                                v4l2_fh_del(&item->fh);
 825                                v4l2_fh_exit(&item->fh);
 826                                kfree(item);
 827                                return -EBUSY;
 828                        }
 829                }
 830
 831                /* Mark that the radio is being used. */
 832                set_bit(CX18_F_I_RADIO_USER, &cx->i_flags);
 833                /* We have the radio */
 834                cx18_mute(cx);
 835                /* Switch tuner to radio */
 836                cx18_call_all(cx, tuner, s_radio);
 837                /* Select the correct audio input (i.e. radio tuner) */
 838                cx18_audio_set_io(cx);
 839                /* Done! Unmute and continue. */
 840                cx18_unmute(cx);
 841        }
 842        return 0;
 843}
 844
 845int cx18_v4l2_open(struct file *filp)
 846{
 847        int res;
 848        struct video_device *video_dev = video_devdata(filp);
 849        struct cx18_stream *s = video_get_drvdata(video_dev);
 850        struct cx18 *cx = s->cx;
 851
 852        mutex_lock(&cx->serialize_lock);
 853        if (cx18_init_on_first_open(cx)) {
 854                CX18_ERR("Failed to initialize on %s\n",
 855                         video_device_node_name(video_dev));
 856                mutex_unlock(&cx->serialize_lock);
 857                return -ENXIO;
 858        }
 859        res = cx18_serialized_open(s, filp);
 860        mutex_unlock(&cx->serialize_lock);
 861        return res;
 862}
 863
 864void cx18_mute(struct cx18 *cx)
 865{
 866        u32 h;
 867        if (atomic_read(&cx->ana_capturing)) {
 868                h = cx18_find_handle(cx);
 869                if (h != CX18_INVALID_TASK_HANDLE)
 870                        cx18_vapi(cx, CX18_CPU_SET_AUDIO_MUTE, 2, h, 1);
 871                else
 872                        CX18_ERR("Can't find valid task handle for mute\n");
 873        }
 874        CX18_DEBUG_INFO("Mute\n");
 875}
 876
 877void cx18_unmute(struct cx18 *cx)
 878{
 879        u32 h;
 880        if (atomic_read(&cx->ana_capturing)) {
 881                h = cx18_find_handle(cx);
 882                if (h != CX18_INVALID_TASK_HANDLE) {
 883                        cx18_msleep_timeout(100, 0);
 884                        cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 2, h, 12);
 885                        cx18_vapi(cx, CX18_CPU_SET_AUDIO_MUTE, 2, h, 0);
 886                } else
 887                        CX18_ERR("Can't find valid task handle for unmute\n");
 888        }
 889        CX18_DEBUG_INFO("Unmute\n");
 890}
 891