linux/drivers/media/pci/saa7164/saa7164-vbi.c
<<
>>
Prefs
   1/*
   2 *  Driver for the NXP SAA7164 PCIe bridge
   3 *
   4 *  Copyright (c) 2010-2015 Steven Toth <stoth@kernellabs.com>
   5 *
   6 *  This program is free software; you can redistribute it and/or modify
   7 *  it under the terms of the GNU General Public License as published by
   8 *  the Free Software Foundation; either version 2 of the License, or
   9 *  (at your option) any later version.
  10 *
  11 *  This program is distributed in the hope that it will be useful,
  12 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 *
  15 *  GNU General Public License for more details.
  16 *
  17 *  You should have received a copy of the GNU General Public License
  18 *  along with this program; if not, write to the Free Software
  19 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20 */
  21
  22#include "saa7164.h"
  23
  24/* Take the encoder configuration from the port struct and
  25 * flush it to the hardware.
  26 */
  27static void saa7164_vbi_configure(struct saa7164_port *port)
  28{
  29        struct saa7164_dev *dev = port->dev;
  30        dprintk(DBGLVL_VBI, "%s()\n", __func__);
  31
  32        port->vbi_params.width = port->enc_port->width;
  33        port->vbi_params.height = port->enc_port->height;
  34        port->vbi_params.is_50hz =
  35                (port->enc_port->encodernorm.id & V4L2_STD_625_50) != 0;
  36
  37        /* Set up the DIF (enable it) for analog mode by default */
  38        saa7164_api_initialize_dif(port);
  39        dprintk(DBGLVL_VBI, "%s() ends\n", __func__);
  40}
  41
  42static int saa7164_vbi_buffers_dealloc(struct saa7164_port *port)
  43{
  44        struct list_head *c, *n, *p, *q, *l, *v;
  45        struct saa7164_dev *dev = port->dev;
  46        struct saa7164_buffer *buf;
  47        struct saa7164_user_buffer *ubuf;
  48
  49        /* Remove any allocated buffers */
  50        mutex_lock(&port->dmaqueue_lock);
  51
  52        dprintk(DBGLVL_VBI, "%s(port=%d) dmaqueue\n", __func__, port->nr);
  53        list_for_each_safe(c, n, &port->dmaqueue.list) {
  54                buf = list_entry(c, struct saa7164_buffer, list);
  55                list_del(c);
  56                saa7164_buffer_dealloc(buf);
  57        }
  58
  59        dprintk(DBGLVL_VBI, "%s(port=%d) used\n", __func__, port->nr);
  60        list_for_each_safe(p, q, &port->list_buf_used.list) {
  61                ubuf = list_entry(p, struct saa7164_user_buffer, list);
  62                list_del(p);
  63                saa7164_buffer_dealloc_user(ubuf);
  64        }
  65
  66        dprintk(DBGLVL_VBI, "%s(port=%d) free\n", __func__, port->nr);
  67        list_for_each_safe(l, v, &port->list_buf_free.list) {
  68                ubuf = list_entry(l, struct saa7164_user_buffer, list);
  69                list_del(l);
  70                saa7164_buffer_dealloc_user(ubuf);
  71        }
  72
  73        mutex_unlock(&port->dmaqueue_lock);
  74        dprintk(DBGLVL_VBI, "%s(port=%d) done\n", __func__, port->nr);
  75
  76        return 0;
  77}
  78
  79/* Dynamic buffer switch at vbi start time */
  80static int saa7164_vbi_buffers_alloc(struct saa7164_port *port)
  81{
  82        struct saa7164_dev *dev = port->dev;
  83        struct saa7164_buffer *buf;
  84        struct saa7164_user_buffer *ubuf;
  85        struct tmHWStreamParameters *params = &port->hw_streamingparams;
  86        int result = -ENODEV, i;
  87        int len = 0;
  88
  89        dprintk(DBGLVL_VBI, "%s()\n", __func__);
  90
  91        /* TODO: NTSC SPECIFIC */
  92        /* Init and establish defaults */
  93        params->samplesperline = 1440;
  94        params->numberoflines = 12;
  95        params->numberoflines = 18;
  96        params->pitch = 1600;
  97        params->pitch = 1440;
  98        params->numpagetables = 2 +
  99                ((params->numberoflines * params->pitch) / PAGE_SIZE);
 100        params->bitspersample = 8;
 101        params->linethreshold = 0;
 102        params->pagetablelistvirt = NULL;
 103        params->pagetablelistphys = NULL;
 104        params->numpagetableentries = port->hwcfg.buffercount;
 105
 106        /* Allocate the PCI resources, buffers (hard) */
 107        for (i = 0; i < port->hwcfg.buffercount; i++) {
 108                buf = saa7164_buffer_alloc(port,
 109                        params->numberoflines *
 110                        params->pitch);
 111
 112                if (!buf) {
 113                        printk(KERN_ERR "%s() failed "
 114                               "(errno = %d), unable to allocate buffer\n",
 115                                __func__, result);
 116                        result = -ENOMEM;
 117                        goto failed;
 118                } else {
 119
 120                        mutex_lock(&port->dmaqueue_lock);
 121                        list_add_tail(&buf->list, &port->dmaqueue.list);
 122                        mutex_unlock(&port->dmaqueue_lock);
 123
 124                }
 125        }
 126
 127        /* Allocate some kernel buffers for copying
 128         * to userpsace.
 129         */
 130        len = params->numberoflines * params->pitch;
 131
 132        if (vbi_buffers < 16)
 133                vbi_buffers = 16;
 134        if (vbi_buffers > 512)
 135                vbi_buffers = 512;
 136
 137        for (i = 0; i < vbi_buffers; i++) {
 138
 139                ubuf = saa7164_buffer_alloc_user(dev, len);
 140                if (ubuf) {
 141                        mutex_lock(&port->dmaqueue_lock);
 142                        list_add_tail(&ubuf->list, &port->list_buf_free.list);
 143                        mutex_unlock(&port->dmaqueue_lock);
 144                }
 145
 146        }
 147
 148        result = 0;
 149
 150failed:
 151        return result;
 152}
 153
 154
 155static int saa7164_vbi_initialize(struct saa7164_port *port)
 156{
 157        saa7164_vbi_configure(port);
 158        return 0;
 159}
 160
 161/* -- V4L2 --------------------------------------------------------- */
 162static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id id)
 163{
 164        struct saa7164_vbi_fh *fh = file->private_data;
 165
 166        return saa7164_s_std(fh->port->enc_port, id);
 167}
 168
 169static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id)
 170{
 171        struct saa7164_encoder_fh *fh = file->private_data;
 172
 173        return saa7164_g_std(fh->port->enc_port, id);
 174}
 175
 176static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
 177{
 178        struct saa7164_vbi_fh *fh = file->private_data;
 179
 180        return saa7164_g_input(fh->port->enc_port, i);
 181}
 182
 183static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
 184{
 185        struct saa7164_vbi_fh *fh = file->private_data;
 186
 187        return saa7164_s_input(fh->port->enc_port, i);
 188}
 189
 190static int vidioc_g_frequency(struct file *file, void *priv,
 191        struct v4l2_frequency *f)
 192{
 193        struct saa7164_vbi_fh *fh = file->private_data;
 194
 195        return saa7164_g_frequency(fh->port->enc_port, f);
 196}
 197
 198static int vidioc_s_frequency(struct file *file, void *priv,
 199        const struct v4l2_frequency *f)
 200{
 201        struct saa7164_vbi_fh *fh = file->private_data;
 202        int ret = saa7164_s_frequency(fh->port->enc_port, f);
 203
 204        if (ret == 0)
 205                saa7164_vbi_initialize(fh->port);
 206        return ret;
 207}
 208
 209static int vidioc_querycap(struct file *file, void  *priv,
 210        struct v4l2_capability *cap)
 211{
 212        struct saa7164_vbi_fh *fh = file->private_data;
 213        struct saa7164_port *port = fh->port;
 214        struct saa7164_dev *dev = port->dev;
 215
 216        strcpy(cap->driver, dev->name);
 217        strlcpy(cap->card, saa7164_boards[dev->board].name,
 218                sizeof(cap->card));
 219        sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci));
 220
 221        cap->device_caps =
 222                V4L2_CAP_VBI_CAPTURE |
 223                V4L2_CAP_READWRITE |
 224                V4L2_CAP_TUNER;
 225
 226        cap->capabilities = cap->device_caps |
 227                V4L2_CAP_VIDEO_CAPTURE |
 228                V4L2_CAP_DEVICE_CAPS;
 229
 230        return 0;
 231}
 232
 233static int saa7164_vbi_stop_port(struct saa7164_port *port)
 234{
 235        struct saa7164_dev *dev = port->dev;
 236        int ret;
 237
 238        ret = saa7164_api_transition_port(port, SAA_DMASTATE_STOP);
 239        if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) {
 240                printk(KERN_ERR "%s() stop transition failed, ret = 0x%x\n",
 241                        __func__, ret);
 242                ret = -EIO;
 243        } else {
 244                dprintk(DBGLVL_VBI, "%s()    Stopped\n", __func__);
 245                ret = 0;
 246        }
 247
 248        return ret;
 249}
 250
 251static int saa7164_vbi_acquire_port(struct saa7164_port *port)
 252{
 253        struct saa7164_dev *dev = port->dev;
 254        int ret;
 255
 256        ret = saa7164_api_transition_port(port, SAA_DMASTATE_ACQUIRE);
 257        if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) {
 258                printk(KERN_ERR "%s() acquire transition failed, ret = 0x%x\n",
 259                        __func__, ret);
 260                ret = -EIO;
 261        } else {
 262                dprintk(DBGLVL_VBI, "%s() Acquired\n", __func__);
 263                ret = 0;
 264        }
 265
 266        return ret;
 267}
 268
 269static int saa7164_vbi_pause_port(struct saa7164_port *port)
 270{
 271        struct saa7164_dev *dev = port->dev;
 272        int ret;
 273
 274        ret = saa7164_api_transition_port(port, SAA_DMASTATE_PAUSE);
 275        if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) {
 276                printk(KERN_ERR "%s() pause transition failed, ret = 0x%x\n",
 277                        __func__, ret);
 278                ret = -EIO;
 279        } else {
 280                dprintk(DBGLVL_VBI, "%s()   Paused\n", __func__);
 281                ret = 0;
 282        }
 283
 284        return ret;
 285}
 286
 287/* Firmware is very windows centric, meaning you have to transition
 288 * the part through AVStream / KS Windows stages, forwards or backwards.
 289 * States are: stopped, acquired (h/w), paused, started.
 290 * We have to leave here will all of the soft buffers on the free list,
 291 * else the cfg_post() func won't have soft buffers to correctly configure.
 292 */
 293static int saa7164_vbi_stop_streaming(struct saa7164_port *port)
 294{
 295        struct saa7164_dev *dev = port->dev;
 296        struct saa7164_buffer *buf;
 297        struct saa7164_user_buffer *ubuf;
 298        struct list_head *c, *n;
 299        int ret;
 300
 301        dprintk(DBGLVL_VBI, "%s(port=%d)\n", __func__, port->nr);
 302
 303        ret = saa7164_vbi_pause_port(port);
 304        ret = saa7164_vbi_acquire_port(port);
 305        ret = saa7164_vbi_stop_port(port);
 306
 307        dprintk(DBGLVL_VBI, "%s(port=%d) Hardware stopped\n", __func__,
 308                port->nr);
 309
 310        /* Reset the state of any allocated buffer resources */
 311        mutex_lock(&port->dmaqueue_lock);
 312
 313        /* Reset the hard and soft buffer state */
 314        list_for_each_safe(c, n, &port->dmaqueue.list) {
 315                buf = list_entry(c, struct saa7164_buffer, list);
 316                buf->flags = SAA7164_BUFFER_FREE;
 317                buf->pos = 0;
 318        }
 319
 320        list_for_each_safe(c, n, &port->list_buf_used.list) {
 321                ubuf = list_entry(c, struct saa7164_user_buffer, list);
 322                ubuf->pos = 0;
 323                list_move_tail(&ubuf->list, &port->list_buf_free.list);
 324        }
 325
 326        mutex_unlock(&port->dmaqueue_lock);
 327
 328        /* Free any allocated resources */
 329        saa7164_vbi_buffers_dealloc(port);
 330
 331        dprintk(DBGLVL_VBI, "%s(port=%d) Released\n", __func__, port->nr);
 332
 333        return ret;
 334}
 335
 336static int saa7164_vbi_start_streaming(struct saa7164_port *port)
 337{
 338        struct saa7164_dev *dev = port->dev;
 339        int result, ret = 0;
 340
 341        dprintk(DBGLVL_VBI, "%s(port=%d)\n", __func__, port->nr);
 342
 343        port->done_first_interrupt = 0;
 344
 345        /* allocate all of the PCIe DMA buffer resources on the fly,
 346         * allowing switching between TS and PS payloads without
 347         * requiring a complete driver reload.
 348         */
 349        saa7164_vbi_buffers_alloc(port);
 350
 351        /* Configure the encoder with any cache values */
 352#if 0
 353        saa7164_api_set_encoder(port);
 354        saa7164_api_get_encoder(port);
 355#endif
 356
 357        /* Place the empty buffers on the hardware */
 358        saa7164_buffer_cfg_port(port);
 359
 360        /* Negotiate format */
 361        if (saa7164_api_set_vbi_format(port) != SAA_OK) {
 362                printk(KERN_ERR "%s() No supported VBI format\n", __func__);
 363                ret = -EIO;
 364                goto out;
 365        }
 366
 367        /* Acquire the hardware */
 368        result = saa7164_api_transition_port(port, SAA_DMASTATE_ACQUIRE);
 369        if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
 370                printk(KERN_ERR "%s() acquire transition failed, res = 0x%x\n",
 371                        __func__, result);
 372
 373                ret = -EIO;
 374                goto out;
 375        } else
 376                dprintk(DBGLVL_VBI, "%s()   Acquired\n", __func__);
 377
 378        /* Pause the hardware */
 379        result = saa7164_api_transition_port(port, SAA_DMASTATE_PAUSE);
 380        if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
 381                printk(KERN_ERR "%s() pause transition failed, res = 0x%x\n",
 382                                __func__, result);
 383
 384                /* Stop the hardware, regardless */
 385                result = saa7164_vbi_stop_port(port);
 386                if (result != SAA_OK) {
 387                        printk(KERN_ERR "%s() pause/forced stop transition "
 388                                "failed, res = 0x%x\n", __func__, result);
 389                }
 390
 391                ret = -EIO;
 392                goto out;
 393        } else
 394                dprintk(DBGLVL_VBI, "%s()   Paused\n", __func__);
 395
 396        /* Start the hardware */
 397        result = saa7164_api_transition_port(port, SAA_DMASTATE_RUN);
 398        if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
 399                printk(KERN_ERR "%s() run transition failed, result = 0x%x\n",
 400                                __func__, result);
 401
 402                /* Stop the hardware, regardless */
 403                result = saa7164_vbi_acquire_port(port);
 404                result = saa7164_vbi_stop_port(port);
 405                if (result != SAA_OK) {
 406                        printk(KERN_ERR "%s() run/forced stop transition "
 407                                "failed, res = 0x%x\n", __func__, result);
 408                }
 409
 410                ret = -EIO;
 411        } else
 412                dprintk(DBGLVL_VBI, "%s()   Running\n", __func__);
 413
 414out:
 415        return ret;
 416}
 417
 418static int saa7164_vbi_fmt(struct file *file, void *priv,
 419                           struct v4l2_format *f)
 420{
 421        /* ntsc */
 422        f->fmt.vbi.samples_per_line = 1440;
 423        f->fmt.vbi.sampling_rate = 27000000;
 424        f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
 425        f->fmt.vbi.offset = 0;
 426        f->fmt.vbi.flags = 0;
 427        f->fmt.vbi.start[0] = 10;
 428        f->fmt.vbi.count[0] = 18;
 429        f->fmt.vbi.start[1] = 263 + 10 + 1;
 430        f->fmt.vbi.count[1] = 18;
 431        memset(f->fmt.vbi.reserved, 0, sizeof(f->fmt.vbi.reserved));
 432        return 0;
 433}
 434
 435static int fops_open(struct file *file)
 436{
 437        struct saa7164_dev *dev;
 438        struct saa7164_port *port;
 439        struct saa7164_vbi_fh *fh;
 440
 441        port = (struct saa7164_port *)video_get_drvdata(video_devdata(file));
 442        if (!port)
 443                return -ENODEV;
 444
 445        dev = port->dev;
 446
 447        dprintk(DBGLVL_VBI, "%s()\n", __func__);
 448
 449        /* allocate + initialize per filehandle data */
 450        fh = kzalloc(sizeof(*fh), GFP_KERNEL);
 451        if (NULL == fh)
 452                return -ENOMEM;
 453
 454        fh->port = port;
 455        v4l2_fh_init(&fh->fh, video_devdata(file));
 456        v4l2_fh_add(&fh->fh);
 457        file->private_data = fh;
 458
 459        return 0;
 460}
 461
 462static int fops_release(struct file *file)
 463{
 464        struct saa7164_vbi_fh *fh = file->private_data;
 465        struct saa7164_port *port = fh->port;
 466        struct saa7164_dev *dev = port->dev;
 467
 468        dprintk(DBGLVL_VBI, "%s()\n", __func__);
 469
 470        /* Shut device down on last close */
 471        if (atomic_cmpxchg(&fh->v4l_reading, 1, 0) == 1) {
 472                if (atomic_dec_return(&port->v4l_reader_count) == 0) {
 473                        /* stop vbi capture then cancel buffers */
 474                        saa7164_vbi_stop_streaming(port);
 475                }
 476        }
 477
 478        v4l2_fh_del(&fh->fh);
 479        v4l2_fh_exit(&fh->fh);
 480        kfree(fh);
 481
 482        return 0;
 483}
 484
 485static struct
 486saa7164_user_buffer *saa7164_vbi_next_buf(struct saa7164_port *port)
 487{
 488        struct saa7164_user_buffer *ubuf = NULL;
 489        struct saa7164_dev *dev = port->dev;
 490        u32 crc;
 491
 492        mutex_lock(&port->dmaqueue_lock);
 493        if (!list_empty(&port->list_buf_used.list)) {
 494                ubuf = list_first_entry(&port->list_buf_used.list,
 495                        struct saa7164_user_buffer, list);
 496
 497                if (crc_checking) {
 498                        crc = crc32(0, ubuf->data, ubuf->actual_size);
 499                        if (crc != ubuf->crc) {
 500                                printk(KERN_ERR "%s() ubuf %p crc became invalid, was 0x%x became 0x%x\n",
 501                                        __func__,
 502                                        ubuf, ubuf->crc, crc);
 503                        }
 504                }
 505
 506        }
 507        mutex_unlock(&port->dmaqueue_lock);
 508
 509        dprintk(DBGLVL_VBI, "%s() returns %p\n", __func__, ubuf);
 510
 511        return ubuf;
 512}
 513
 514static ssize_t fops_read(struct file *file, char __user *buffer,
 515        size_t count, loff_t *pos)
 516{
 517        struct saa7164_vbi_fh *fh = file->private_data;
 518        struct saa7164_port *port = fh->port;
 519        struct saa7164_user_buffer *ubuf = NULL;
 520        struct saa7164_dev *dev = port->dev;
 521        int ret = 0;
 522        int rem, cnt;
 523        u8 *p;
 524
 525        port->last_read_msecs_diff = port->last_read_msecs;
 526        port->last_read_msecs = jiffies_to_msecs(jiffies);
 527        port->last_read_msecs_diff = port->last_read_msecs -
 528                port->last_read_msecs_diff;
 529
 530        saa7164_histogram_update(&port->read_interval,
 531                port->last_read_msecs_diff);
 532
 533        if (*pos) {
 534                printk(KERN_ERR "%s() ESPIPE\n", __func__);
 535                return -ESPIPE;
 536        }
 537
 538        if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) {
 539                if (atomic_inc_return(&port->v4l_reader_count) == 1) {
 540
 541                        if (saa7164_vbi_initialize(port) < 0) {
 542                                printk(KERN_ERR "%s() EINVAL\n", __func__);
 543                                return -EINVAL;
 544                        }
 545
 546                        saa7164_vbi_start_streaming(port);
 547                        msleep(200);
 548                }
 549        }
 550
 551        /* blocking wait for buffer */
 552        if ((file->f_flags & O_NONBLOCK) == 0) {
 553                if (wait_event_interruptible(port->wait_read,
 554                        saa7164_vbi_next_buf(port))) {
 555                                printk(KERN_ERR "%s() ERESTARTSYS\n", __func__);
 556                                return -ERESTARTSYS;
 557                }
 558        }
 559
 560        /* Pull the first buffer from the used list */
 561        ubuf = saa7164_vbi_next_buf(port);
 562
 563        while ((count > 0) && ubuf) {
 564
 565                /* set remaining bytes to copy */
 566                rem = ubuf->actual_size - ubuf->pos;
 567                cnt = rem > count ? count : rem;
 568
 569                p = ubuf->data + ubuf->pos;
 570
 571                dprintk(DBGLVL_VBI,
 572                        "%s() count=%d cnt=%d rem=%d buf=%p buf->pos=%d\n",
 573                        __func__, (int)count, cnt, rem, ubuf, ubuf->pos);
 574
 575                if (copy_to_user(buffer, p, cnt)) {
 576                        printk(KERN_ERR "%s() copy_to_user failed\n", __func__);
 577                        if (!ret) {
 578                                printk(KERN_ERR "%s() EFAULT\n", __func__);
 579                                ret = -EFAULT;
 580                        }
 581                        goto err;
 582                }
 583
 584                ubuf->pos += cnt;
 585                count -= cnt;
 586                buffer += cnt;
 587                ret += cnt;
 588
 589                if (ubuf->pos > ubuf->actual_size)
 590                        printk(KERN_ERR "read() pos > actual, huh?\n");
 591
 592                if (ubuf->pos == ubuf->actual_size) {
 593
 594                        /* finished with current buffer, take next buffer */
 595
 596                        /* Requeue the buffer on the free list */
 597                        ubuf->pos = 0;
 598
 599                        mutex_lock(&port->dmaqueue_lock);
 600                        list_move_tail(&ubuf->list, &port->list_buf_free.list);
 601                        mutex_unlock(&port->dmaqueue_lock);
 602
 603                        /* Dequeue next */
 604                        if ((file->f_flags & O_NONBLOCK) == 0) {
 605                                if (wait_event_interruptible(port->wait_read,
 606                                        saa7164_vbi_next_buf(port))) {
 607                                                break;
 608                                }
 609                        }
 610                        ubuf = saa7164_vbi_next_buf(port);
 611                }
 612        }
 613err:
 614        if (!ret && !ubuf) {
 615                printk(KERN_ERR "%s() EAGAIN\n", __func__);
 616                ret = -EAGAIN;
 617        }
 618
 619        return ret;
 620}
 621
 622static unsigned int fops_poll(struct file *file, poll_table *wait)
 623{
 624        struct saa7164_vbi_fh *fh = (struct saa7164_vbi_fh *)file->private_data;
 625        struct saa7164_port *port = fh->port;
 626        unsigned int mask = 0;
 627
 628        port->last_poll_msecs_diff = port->last_poll_msecs;
 629        port->last_poll_msecs = jiffies_to_msecs(jiffies);
 630        port->last_poll_msecs_diff = port->last_poll_msecs -
 631                port->last_poll_msecs_diff;
 632
 633        saa7164_histogram_update(&port->poll_interval,
 634                port->last_poll_msecs_diff);
 635
 636        if (!video_is_registered(port->v4l_device))
 637                return -EIO;
 638
 639        if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) {
 640                if (atomic_inc_return(&port->v4l_reader_count) == 1) {
 641                        if (saa7164_vbi_initialize(port) < 0)
 642                                return -EINVAL;
 643                        saa7164_vbi_start_streaming(port);
 644                        msleep(200);
 645                }
 646        }
 647
 648        /* blocking wait for buffer */
 649        if ((file->f_flags & O_NONBLOCK) == 0) {
 650                if (wait_event_interruptible(port->wait_read,
 651                        saa7164_vbi_next_buf(port))) {
 652                                return -ERESTARTSYS;
 653                }
 654        }
 655
 656        /* Pull the first buffer from the used list */
 657        if (!list_empty(&port->list_buf_used.list))
 658                mask |= POLLIN | POLLRDNORM;
 659
 660        return mask;
 661}
 662static const struct v4l2_file_operations vbi_fops = {
 663        .owner          = THIS_MODULE,
 664        .open           = fops_open,
 665        .release        = fops_release,
 666        .read           = fops_read,
 667        .poll           = fops_poll,
 668        .unlocked_ioctl = video_ioctl2,
 669};
 670
 671static const struct v4l2_ioctl_ops vbi_ioctl_ops = {
 672        .vidioc_s_std            = vidioc_s_std,
 673        .vidioc_g_std            = vidioc_g_std,
 674        .vidioc_enum_input       = saa7164_enum_input,
 675        .vidioc_g_input          = vidioc_g_input,
 676        .vidioc_s_input          = vidioc_s_input,
 677        .vidioc_g_tuner          = saa7164_g_tuner,
 678        .vidioc_s_tuner          = saa7164_s_tuner,
 679        .vidioc_g_frequency      = vidioc_g_frequency,
 680        .vidioc_s_frequency      = vidioc_s_frequency,
 681        .vidioc_querycap         = vidioc_querycap,
 682        .vidioc_g_fmt_vbi_cap    = saa7164_vbi_fmt,
 683        .vidioc_try_fmt_vbi_cap  = saa7164_vbi_fmt,
 684        .vidioc_s_fmt_vbi_cap    = saa7164_vbi_fmt,
 685};
 686
 687static struct video_device saa7164_vbi_template = {
 688        .name          = "saa7164",
 689        .fops          = &vbi_fops,
 690        .ioctl_ops     = &vbi_ioctl_ops,
 691        .minor         = -1,
 692        .tvnorms       = SAA7164_NORMS,
 693};
 694
 695static struct video_device *saa7164_vbi_alloc(
 696        struct saa7164_port *port,
 697        struct pci_dev *pci,
 698        struct video_device *template,
 699        char *type)
 700{
 701        struct video_device *vfd;
 702        struct saa7164_dev *dev = port->dev;
 703
 704        dprintk(DBGLVL_VBI, "%s()\n", __func__);
 705
 706        vfd = video_device_alloc();
 707        if (NULL == vfd)
 708                return NULL;
 709
 710        *vfd = *template;
 711        snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name,
 712                type, saa7164_boards[dev->board].name);
 713
 714        vfd->v4l2_dev  = &dev->v4l2_dev;
 715        vfd->release = video_device_release;
 716        return vfd;
 717}
 718
 719int saa7164_vbi_register(struct saa7164_port *port)
 720{
 721        struct saa7164_dev *dev = port->dev;
 722        int result = -ENODEV;
 723
 724        dprintk(DBGLVL_VBI, "%s()\n", __func__);
 725
 726        if (port->type != SAA7164_MPEG_VBI)
 727                BUG();
 728
 729        /* Sanity check that the PCI configuration space is active */
 730        if (port->hwcfg.BARLocation == 0) {
 731                printk(KERN_ERR "%s() failed "
 732                       "(errno = %d), NO PCI configuration\n",
 733                        __func__, result);
 734                result = -ENOMEM;
 735                goto failed;
 736        }
 737
 738        /* Establish VBI defaults here */
 739
 740        /* Allocate and register the video device node */
 741        port->v4l_device = saa7164_vbi_alloc(port,
 742                dev->pci, &saa7164_vbi_template, "vbi");
 743
 744        if (!port->v4l_device) {
 745                printk(KERN_INFO "%s: can't allocate vbi device\n",
 746                        dev->name);
 747                result = -ENOMEM;
 748                goto failed;
 749        }
 750
 751        port->enc_port = &dev->ports[port->nr - 2];
 752        video_set_drvdata(port->v4l_device, port);
 753        result = video_register_device(port->v4l_device,
 754                VFL_TYPE_VBI, -1);
 755        if (result < 0) {
 756                printk(KERN_INFO "%s: can't register vbi device\n",
 757                        dev->name);
 758                /* TODO: We're going to leak here if we don't dealloc
 759                 The buffers above. The unreg function can't deal wit it.
 760                */
 761                goto failed;
 762        }
 763
 764        printk(KERN_INFO "%s: registered device vbi%d [vbi]\n",
 765                dev->name, port->v4l_device->num);
 766
 767        /* Configure the hardware defaults */
 768
 769        result = 0;
 770failed:
 771        return result;
 772}
 773
 774void saa7164_vbi_unregister(struct saa7164_port *port)
 775{
 776        struct saa7164_dev *dev = port->dev;
 777
 778        dprintk(DBGLVL_VBI, "%s(port=%d)\n", __func__, port->nr);
 779
 780        if (port->type != SAA7164_MPEG_VBI)
 781                BUG();
 782
 783        if (port->v4l_device) {
 784                if (port->v4l_device->minor != -1)
 785                        video_unregister_device(port->v4l_device);
 786                else
 787                        video_device_release(port->v4l_device);
 788
 789                port->v4l_device = NULL;
 790        }
 791
 792}
 793