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