linux/drivers/staging/cx25821/cx25821-video.c
<<
>>
Prefs
   1/*
   2 *  Driver for the Conexant CX25821 PCIe bridge
   3 *
   4 *  Copyright (C) 2009 Conexant Systems Inc.
   5 *  Authors  <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
   6 *  Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
   7 *
   8 *  This program is free software; you can redistribute it and/or modify
   9 *  it under the terms of the GNU General Public License as published by
  10 *  the Free Software Foundation; either version 2 of the License, or
  11 *  (at your option) any later version.
  12 *
  13 *  This program is distributed in the hope that it will be useful,
  14 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 *
  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., 675 Mass Ave, Cambridge, MA 02139, USA.
  22 */
  23
  24#include "cx25821-video.h"
  25
  26MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards");
  27MODULE_AUTHOR("Steven Toth <stoth@linuxtv.org>");
  28MODULE_LICENSE("GPL");
  29
  30static unsigned int video_nr[] = {[0 ... (CX25821_MAXBOARDS - 1)] = UNSET };
  31static unsigned int radio_nr[] = {[0 ... (CX25821_MAXBOARDS - 1)] = UNSET };
  32
  33module_param_array(video_nr, int, NULL, 0444);
  34module_param_array(radio_nr, int, NULL, 0444);
  35
  36MODULE_PARM_DESC(video_nr, "video device numbers");
  37MODULE_PARM_DESC(radio_nr, "radio device numbers");
  38
  39static unsigned int video_debug = VIDEO_DEBUG;
  40module_param(video_debug, int, 0644);
  41MODULE_PARM_DESC(video_debug, "enable debug messages [video]");
  42
  43static unsigned int irq_debug;
  44module_param(irq_debug, int, 0644);
  45MODULE_PARM_DESC(irq_debug, "enable debug messages [IRQ handler]");
  46
  47unsigned int vid_limit = 16;
  48module_param(vid_limit, int, 0644);
  49MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes");
  50
  51static void init_controls(struct cx25821_dev *dev, int chan_num);
  52
  53#define FORMAT_FLAGS_PACKED       0x01
  54
  55struct cx25821_fmt formats[] = {
  56        {
  57         .name = "8 bpp, gray",
  58         .fourcc = V4L2_PIX_FMT_GREY,
  59         .depth = 8,
  60         .flags = FORMAT_FLAGS_PACKED,
  61         }, {
  62             .name = "4:1:1, packed, Y41P",
  63             .fourcc = V4L2_PIX_FMT_Y41P,
  64             .depth = 12,
  65             .flags = FORMAT_FLAGS_PACKED,
  66             }, {
  67                 .name = "4:2:2, packed, YUYV",
  68                 .fourcc = V4L2_PIX_FMT_YUYV,
  69                 .depth = 16,
  70                 .flags = FORMAT_FLAGS_PACKED,
  71                 }, {
  72                     .name = "4:2:2, packed, UYVY",
  73                     .fourcc = V4L2_PIX_FMT_UYVY,
  74                     .depth = 16,
  75                     .flags = FORMAT_FLAGS_PACKED,
  76                     }, {
  77                         .name = "4:2:0, YUV",
  78                         .fourcc = V4L2_PIX_FMT_YUV420,
  79                         .depth = 12,
  80                         .flags = FORMAT_FLAGS_PACKED,
  81                         },
  82};
  83
  84int get_format_size(void)
  85{
  86        return ARRAY_SIZE(formats);
  87}
  88
  89struct cx25821_fmt *format_by_fourcc(unsigned int fourcc)
  90{
  91        unsigned int i;
  92
  93        if (fourcc == V4L2_PIX_FMT_Y41P || fourcc == V4L2_PIX_FMT_YUV411P) {
  94                return formats + 1;
  95        }
  96
  97        for (i = 0; i < ARRAY_SIZE(formats); i++)
  98                if (formats[i].fourcc == fourcc)
  99                        return formats + i;
 100
 101        printk(KERN_ERR "%s(0x%08x) NOT FOUND\n", __func__, fourcc);
 102        return NULL;
 103}
 104
 105void dump_video_queue(struct cx25821_dev *dev, struct cx25821_dmaqueue *q)
 106{
 107        struct cx25821_buffer *buf;
 108        struct list_head *item;
 109        dprintk(1, "%s()\n", __func__);
 110
 111        if (!list_empty(&q->active)) {
 112                list_for_each(item, &q->active)
 113                    buf = list_entry(item, struct cx25821_buffer, vb.queue);
 114        }
 115
 116        if (!list_empty(&q->queued)) {
 117                list_for_each(item, &q->queued)
 118                    buf = list_entry(item, struct cx25821_buffer, vb.queue);
 119        }
 120
 121}
 122
 123void cx25821_video_wakeup(struct cx25821_dev *dev, struct cx25821_dmaqueue *q,
 124                          u32 count)
 125{
 126        struct cx25821_buffer *buf;
 127        int bc;
 128
 129        for (bc = 0;; bc++) {
 130                if (list_empty(&q->active)) {
 131                        dprintk(1, "bc=%d (=0: active empty)\n", bc);
 132                        break;
 133                }
 134
 135                buf =
 136                    list_entry(q->active.next, struct cx25821_buffer, vb.queue);
 137
 138                /* count comes from the hw and it is 16bit wide --
 139                 * this trick handles wrap-arounds correctly for
 140                 * up to 32767 buffers in flight... */
 141                if ((s16) (count - buf->count) < 0) {
 142                        break;
 143                }
 144
 145                do_gettimeofday(&buf->vb.ts);
 146                buf->vb.state = VIDEOBUF_DONE;
 147                list_del(&buf->vb.queue);
 148                wake_up(&buf->vb.done);
 149        }
 150
 151        if (list_empty(&q->active))
 152                del_timer(&q->timeout);
 153        else
 154                mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
 155        if (bc != 1)
 156                printk(KERN_ERR "%s: %d buffers handled (should be 1)\n",
 157                       __func__, bc);
 158}
 159
 160#ifdef TUNER_FLAG
 161int cx25821_set_tvnorm(struct cx25821_dev *dev, v4l2_std_id norm)
 162{
 163        dprintk(1, "%s(norm = 0x%08x) name: [%s]\n", __func__,
 164                (unsigned int)norm, v4l2_norm_to_name(norm));
 165
 166        dev->tvnorm = norm;
 167
 168        /* Tell the internal A/V decoder */
 169        cx25821_call_all(dev, core, s_std, norm);
 170
 171        return 0;
 172}
 173#endif
 174
 175struct video_device *cx25821_vdev_init(struct cx25821_dev *dev,
 176                                       struct pci_dev *pci,
 177                                       struct video_device *template,
 178                                       char *type)
 179{
 180        struct video_device *vfd;
 181        dprintk(1, "%s()\n", __func__);
 182
 183        vfd = video_device_alloc();
 184        if (NULL == vfd)
 185                return NULL;
 186        *vfd = *template;
 187        vfd->minor = -1;
 188        vfd->v4l2_dev = &dev->v4l2_dev;
 189        vfd->release = video_device_release;
 190        snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name, type,
 191                 cx25821_boards[dev->board].name);
 192        return vfd;
 193}
 194
 195/*
 196static int cx25821_ctrl_query(struct v4l2_queryctrl *qctrl)
 197{
 198    int i;
 199
 200    if (qctrl->id < V4L2_CID_BASE || qctrl->id >= V4L2_CID_LASTP1)
 201        return -EINVAL;
 202    for (i = 0; i < CX25821_CTLS; i++)
 203        if (cx25821_ctls[i].v.id == qctrl->id)
 204            break;
 205    if (i == CX25821_CTLS) {
 206        *qctrl = no_ctl;
 207        return 0;
 208    }
 209    *qctrl = cx25821_ctls[i].v;
 210    return 0;
 211}
 212*/
 213
 214// resource management
 215int res_get(struct cx25821_dev *dev, struct cx25821_fh *fh, unsigned int bit)
 216{
 217        dprintk(1, "%s()\n", __func__);
 218        if (fh->resources & bit)
 219                /* have it already allocated */
 220                return 1;
 221
 222        /* is it free? */
 223        mutex_lock(&dev->lock);
 224        if (dev->resources & bit) {
 225                /* no, someone else uses it */
 226                mutex_unlock(&dev->lock);
 227                return 0;
 228        }
 229        /* it's free, grab it */
 230        fh->resources |= bit;
 231        dev->resources |= bit;
 232        dprintk(1, "res: get %d\n", bit);
 233        mutex_unlock(&dev->lock);
 234        return 1;
 235}
 236
 237int res_check(struct cx25821_fh *fh, unsigned int bit)
 238{
 239        return fh->resources & bit;
 240}
 241
 242int res_locked(struct cx25821_dev *dev, unsigned int bit)
 243{
 244        return dev->resources & bit;
 245}
 246
 247void res_free(struct cx25821_dev *dev, struct cx25821_fh *fh, unsigned int bits)
 248{
 249        BUG_ON((fh->resources & bits) != bits);
 250        dprintk(1, "%s()\n", __func__);
 251
 252        mutex_lock(&dev->lock);
 253        fh->resources &= ~bits;
 254        dev->resources &= ~bits;
 255        dprintk(1, "res: put %d\n", bits);
 256        mutex_unlock(&dev->lock);
 257}
 258
 259int cx25821_video_mux(struct cx25821_dev *dev, unsigned int input)
 260{
 261        struct v4l2_routing route;
 262        memset(&route, 0, sizeof(route));
 263
 264        dprintk(1, "%s() video_mux: %d [vmux=%d, gpio=0x%x,0x%x,0x%x,0x%x]\n",
 265                __func__, input, INPUT(input)->vmux, INPUT(input)->gpio0,
 266                INPUT(input)->gpio1, INPUT(input)->gpio2, INPUT(input)->gpio3);
 267        dev->input = input;
 268
 269        route.input = INPUT(input)->vmux;
 270
 271        /* Tell the internal A/V decoder */
 272        cx25821_call_all(dev, video, s_routing, INPUT(input)->vmux, 0, 0);
 273
 274        return 0;
 275}
 276
 277int cx25821_start_video_dma(struct cx25821_dev *dev,
 278                            struct cx25821_dmaqueue *q,
 279                            struct cx25821_buffer *buf,
 280                            struct sram_channel *channel)
 281{
 282        int tmp = 0;
 283
 284        /* setup fifo + format */
 285        cx25821_sram_channel_setup(dev, channel, buf->bpl, buf->risc.dma);
 286
 287        /* reset counter */
 288        cx_write(channel->gpcnt_ctl, 3);
 289        q->count = 1;
 290
 291        /* enable irq */
 292        cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) | (1 << channel->i));
 293        cx_set(channel->int_msk, 0x11);
 294
 295        /* start dma */
 296        cx_write(channel->dma_ctl, 0x11);       /* FIFO and RISC enable */
 297
 298        /* make sure upstream setting if any is reversed */
 299        tmp = cx_read(VID_CH_MODE_SEL);
 300        cx_write(VID_CH_MODE_SEL, tmp & 0xFFFFFE00);
 301
 302        return 0;
 303}
 304
 305int cx25821_restart_video_queue(struct cx25821_dev *dev,
 306                                struct cx25821_dmaqueue *q,
 307                                struct sram_channel *channel)
 308{
 309        struct cx25821_buffer *buf, *prev;
 310        struct list_head *item;
 311
 312        if (!list_empty(&q->active)) {
 313                buf =
 314                    list_entry(q->active.next, struct cx25821_buffer, vb.queue);
 315
 316                cx25821_start_video_dma(dev, q, buf, channel);
 317
 318                list_for_each(item, &q->active) {
 319                        buf = list_entry(item, struct cx25821_buffer, vb.queue);
 320                        buf->count = q->count++;
 321                }
 322
 323                mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
 324                return 0;
 325        }
 326
 327        prev = NULL;
 328        for (;;) {
 329                if (list_empty(&q->queued))
 330                        return 0;
 331
 332                buf =
 333                    list_entry(q->queued.next, struct cx25821_buffer, vb.queue);
 334
 335                if (NULL == prev) {
 336                        list_move_tail(&buf->vb.queue, &q->active);
 337                        cx25821_start_video_dma(dev, q, buf, channel);
 338                        buf->vb.state = VIDEOBUF_ACTIVE;
 339                        buf->count = q->count++;
 340                        mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
 341                } else if (prev->vb.width == buf->vb.width &&
 342                           prev->vb.height == buf->vb.height &&
 343                           prev->fmt == buf->fmt) {
 344                        list_move_tail(&buf->vb.queue, &q->active);
 345                        buf->vb.state = VIDEOBUF_ACTIVE;
 346                        buf->count = q->count++;
 347                        prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
 348                        prev->risc.jmp[2] = cpu_to_le32(0);     /* Bits 63 - 32 */
 349                } else {
 350                        return 0;
 351                }
 352                prev = buf;
 353        }
 354}
 355
 356void cx25821_vid_timeout(unsigned long data)
 357{
 358        struct cx25821_data *timeout_data = (struct cx25821_data *)data;
 359        struct cx25821_dev *dev = timeout_data->dev;
 360        struct sram_channel *channel = timeout_data->channel;
 361        struct cx25821_dmaqueue *q = &dev->vidq[channel->i];
 362        struct cx25821_buffer *buf;
 363        unsigned long flags;
 364
 365        //cx25821_sram_channel_dump(dev, channel);
 366        cx_clear(channel->dma_ctl, 0x11);
 367
 368        spin_lock_irqsave(&dev->slock, flags);
 369        while (!list_empty(&q->active)) {
 370                buf =
 371                    list_entry(q->active.next, struct cx25821_buffer, vb.queue);
 372                list_del(&buf->vb.queue);
 373
 374                buf->vb.state = VIDEOBUF_ERROR;
 375                wake_up(&buf->vb.done);
 376        }
 377
 378        cx25821_restart_video_queue(dev, q, channel);
 379        spin_unlock_irqrestore(&dev->slock, flags);
 380}
 381
 382int cx25821_video_irq(struct cx25821_dev *dev, int chan_num, u32 status)
 383{
 384        u32 count = 0;
 385        int handled = 0;
 386        u32 mask;
 387        struct sram_channel *channel = &dev->sram_channels[chan_num];
 388
 389        mask = cx_read(channel->int_msk);
 390        if (0 == (status & mask))
 391                return handled;
 392
 393        cx_write(channel->int_stat, status);
 394
 395        /* risc op code error */
 396        if (status & (1 << 16)) {
 397                printk(KERN_WARNING "%s, %s: video risc op code error\n",
 398                       dev->name, channel->name);
 399                cx_clear(channel->dma_ctl, 0x11);
 400                cx25821_sram_channel_dump(dev, channel);
 401        }
 402
 403        /* risc1 y */
 404        if (status & FLD_VID_DST_RISC1) {
 405                spin_lock(&dev->slock);
 406                count = cx_read(channel->gpcnt);
 407                cx25821_video_wakeup(dev, &dev->vidq[channel->i], count);
 408                spin_unlock(&dev->slock);
 409                handled++;
 410        }
 411
 412        /* risc2 y */
 413        if (status & 0x10) {
 414                dprintk(2, "stopper video\n");
 415                spin_lock(&dev->slock);
 416                cx25821_restart_video_queue(dev, &dev->vidq[channel->i],
 417                                            channel);
 418                spin_unlock(&dev->slock);
 419                handled++;
 420        }
 421        return handled;
 422}
 423
 424void cx25821_videoioctl_unregister(struct cx25821_dev *dev)
 425{
 426        if (dev->ioctl_dev) {
 427                if (dev->ioctl_dev->minor != -1)
 428                        video_unregister_device(dev->ioctl_dev);
 429                else
 430                        video_device_release(dev->ioctl_dev);
 431
 432                dev->ioctl_dev = NULL;
 433        }
 434}
 435
 436void cx25821_video_unregister(struct cx25821_dev *dev, int chan_num)
 437{
 438        cx_clear(PCI_INT_MSK, 1);
 439
 440        if (dev->video_dev[chan_num]) {
 441                if (-1 != dev->video_dev[chan_num]->minor)
 442                        video_unregister_device(dev->video_dev[chan_num]);
 443                else
 444                        video_device_release(dev->video_dev[chan_num]);
 445
 446                dev->video_dev[chan_num] = NULL;
 447
 448                btcx_riscmem_free(dev->pci, &dev->vidq[chan_num].stopper);
 449
 450                printk(KERN_WARNING "device %d released!\n", chan_num);
 451        }
 452
 453}
 454
 455int cx25821_video_register(struct cx25821_dev *dev, int chan_num,
 456                           struct video_device *video_template)
 457{
 458        int err;
 459
 460        spin_lock_init(&dev->slock);
 461
 462        //printk(KERN_WARNING "Channel %d\n", chan_num);
 463
 464#ifdef TUNER_FLAG
 465        dev->tvnorm = video_template->current_norm;
 466#endif
 467
 468        /* init video dma queues */
 469        dev->timeout_data[chan_num].dev = dev;
 470        dev->timeout_data[chan_num].channel = &dev->sram_channels[chan_num];
 471        INIT_LIST_HEAD(&dev->vidq[chan_num].active);
 472        INIT_LIST_HEAD(&dev->vidq[chan_num].queued);
 473        dev->vidq[chan_num].timeout.function = cx25821_vid_timeout;
 474        dev->vidq[chan_num].timeout.data =
 475            (unsigned long)&dev->timeout_data[chan_num];
 476        init_timer(&dev->vidq[chan_num].timeout);
 477        cx25821_risc_stopper(dev->pci, &dev->vidq[chan_num].stopper,
 478                             dev->sram_channels[chan_num].dma_ctl, 0x11, 0);
 479
 480        /* register v4l devices */
 481        dev->video_dev[chan_num] =
 482            cx25821_vdev_init(dev, dev->pci, video_template, "video");
 483        err =
 484            video_register_device(dev->video_dev[chan_num], VFL_TYPE_GRABBER,
 485                                  video_nr[dev->nr]);
 486
 487        if (err < 0) {
 488                goto fail_unreg;
 489        }
 490        //set PCI interrupt
 491        cx_set(PCI_INT_MSK, 0xff);
 492
 493        /* initial device configuration */
 494        mutex_lock(&dev->lock);
 495#ifdef TUNER_FLAG
 496        cx25821_set_tvnorm(dev, dev->tvnorm);
 497#endif
 498        mutex_unlock(&dev->lock);
 499
 500        init_controls(dev, chan_num);
 501
 502        return 0;
 503
 504      fail_unreg:
 505        cx25821_video_unregister(dev, chan_num);
 506        return err;
 507}
 508
 509int buffer_setup(struct videobuf_queue *q, unsigned int *count,
 510                 unsigned int *size)
 511{
 512        struct cx25821_fh *fh = q->priv_data;
 513
 514        *size = fh->fmt->depth * fh->width * fh->height >> 3;
 515
 516        if (0 == *count)
 517                *count = 32;
 518
 519        while (*size * *count > vid_limit * 1024 * 1024)
 520                (*count)--;
 521
 522        return 0;
 523}
 524
 525int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
 526                   enum v4l2_field field)
 527{
 528        struct cx25821_fh *fh = q->priv_data;
 529        struct cx25821_dev *dev = fh->dev;
 530        struct cx25821_buffer *buf =
 531            container_of(vb, struct cx25821_buffer, vb);
 532        int rc, init_buffer = 0;
 533        u32 line0_offset, line1_offset;
 534        struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb);
 535        int bpl_local = LINE_SIZE_D1;
 536        int channel_opened = 0;
 537
 538        BUG_ON(NULL == fh->fmt);
 539        if (fh->width < 48 || fh->width > 720 ||
 540            fh->height < 32 || fh->height > 576)
 541                return -EINVAL;
 542
 543        buf->vb.size = (fh->width * fh->height * fh->fmt->depth) >> 3;
 544
 545        if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
 546                return -EINVAL;
 547
 548        if (buf->fmt != fh->fmt ||
 549            buf->vb.width != fh->width ||
 550            buf->vb.height != fh->height || buf->vb.field != field) {
 551                buf->fmt = fh->fmt;
 552                buf->vb.width = fh->width;
 553                buf->vb.height = fh->height;
 554                buf->vb.field = field;
 555                init_buffer = 1;
 556        }
 557
 558        if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
 559                init_buffer = 1;
 560                rc = videobuf_iolock(q, &buf->vb, NULL);
 561                if (0 != rc) {
 562                        printk(KERN_DEBUG "videobuf_iolock failed!\n");
 563                        goto fail;
 564                }
 565        }
 566
 567        dprintk(1, "init_buffer=%d\n", init_buffer);
 568
 569        if (init_buffer) {
 570
 571                channel_opened = dev->channel_opened;
 572                channel_opened = (channel_opened < 0
 573                                  || channel_opened > 7) ? 7 : channel_opened;
 574
 575                if (dev->pixel_formats[channel_opened] == PIXEL_FRMT_411)
 576                        buf->bpl = (buf->fmt->depth * buf->vb.width) >> 3;
 577                else
 578                        buf->bpl = (buf->fmt->depth >> 3) * (buf->vb.width);
 579
 580                if (dev->pixel_formats[channel_opened] == PIXEL_FRMT_411) {
 581                        bpl_local = buf->bpl;
 582                } else {
 583                        bpl_local = buf->bpl;   //Default
 584
 585                        if (channel_opened >= 0 && channel_opened <= 7) {
 586                                if (dev->use_cif_resolution[channel_opened]) {
 587                                        if (dev->tvnorm & V4L2_STD_PAL_BG
 588                                            || dev->tvnorm & V4L2_STD_PAL_DK)
 589                                                bpl_local = 352 << 1;
 590                                        else
 591                                                bpl_local =
 592                                                    dev->
 593                                                    cif_width[channel_opened] <<
 594                                                    1;
 595                                }
 596                        }
 597                }
 598
 599                switch (buf->vb.field) {
 600                case V4L2_FIELD_TOP:
 601                        cx25821_risc_buffer(dev->pci, &buf->risc,
 602                                            dma->sglist, 0, UNSET,
 603                                            buf->bpl, 0, buf->vb.height);
 604                        break;
 605                case V4L2_FIELD_BOTTOM:
 606                        cx25821_risc_buffer(dev->pci, &buf->risc,
 607                                            dma->sglist, UNSET, 0,
 608                                            buf->bpl, 0, buf->vb.height);
 609                        break;
 610                case V4L2_FIELD_INTERLACED:
 611                        /* All other formats are top field first */
 612                        line0_offset = 0;
 613                        line1_offset = buf->bpl;
 614                        dprintk(1, "top field first\n");
 615
 616                        cx25821_risc_buffer(dev->pci, &buf->risc,
 617                                            dma->sglist, line0_offset,
 618                                            bpl_local, bpl_local, bpl_local,
 619                                            buf->vb.height >> 1);
 620                        break;
 621                case V4L2_FIELD_SEQ_TB:
 622                        cx25821_risc_buffer(dev->pci, &buf->risc,
 623                                            dma->sglist,
 624                                            0, buf->bpl * (buf->vb.height >> 1),
 625                                            buf->bpl, 0, buf->vb.height >> 1);
 626                        break;
 627                case V4L2_FIELD_SEQ_BT:
 628                        cx25821_risc_buffer(dev->pci, &buf->risc,
 629                                            dma->sglist,
 630                                            buf->bpl * (buf->vb.height >> 1), 0,
 631                                            buf->bpl, 0, buf->vb.height >> 1);
 632                        break;
 633                default:
 634                        BUG();
 635                }
 636        }
 637
 638        dprintk(2, "[%p/%d] buffer_prep - %dx%d %dbpp \"%s\" - dma=0x%08lx\n",
 639                buf, buf->vb.i, fh->width, fh->height, fh->fmt->depth,
 640                fh->fmt->name, (unsigned long)buf->risc.dma);
 641
 642        buf->vb.state = VIDEOBUF_PREPARED;
 643
 644        return 0;
 645
 646      fail:
 647        cx25821_free_buffer(q, buf);
 648        return rc;
 649}
 650
 651void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
 652{
 653        struct cx25821_buffer *buf =
 654            container_of(vb, struct cx25821_buffer, vb);
 655
 656        cx25821_free_buffer(q, buf);
 657}
 658
 659struct videobuf_queue *get_queue(struct cx25821_fh *fh)
 660{
 661        switch (fh->type) {
 662        case V4L2_BUF_TYPE_VIDEO_CAPTURE:
 663                return &fh->vidq;
 664        default:
 665                BUG();
 666                return NULL;
 667        }
 668}
 669
 670int get_resource(struct cx25821_fh *fh, int resource)
 671{
 672        switch (fh->type) {
 673        case V4L2_BUF_TYPE_VIDEO_CAPTURE:
 674                return resource;
 675        default:
 676                BUG();
 677                return 0;
 678        }
 679}
 680
 681int video_mmap(struct file *file, struct vm_area_struct *vma)
 682{
 683        struct cx25821_fh *fh = file->private_data;
 684
 685        return videobuf_mmap_mapper(get_queue(fh), vma);
 686}
 687
 688/* VIDEO IOCTLS                                                       */
 689int vidioc_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f)
 690{
 691        struct cx25821_fh *fh = priv;
 692
 693        f->fmt.pix.width = fh->width;
 694        f->fmt.pix.height = fh->height;
 695        f->fmt.pix.field = fh->vidq.field;
 696        f->fmt.pix.pixelformat = fh->fmt->fourcc;
 697        f->fmt.pix.bytesperline = (f->fmt.pix.width * fh->fmt->depth) >> 3;
 698        f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
 699
 700        return 0;
 701}
 702
 703int vidioc_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f)
 704{
 705        struct cx25821_fmt *fmt;
 706        enum v4l2_field field;
 707        unsigned int maxw, maxh;
 708
 709        fmt = format_by_fourcc(f->fmt.pix.pixelformat);
 710        if (NULL == fmt)
 711                return -EINVAL;
 712
 713        field = f->fmt.pix.field;
 714        maxw = 720;
 715        maxh = 576;
 716
 717        if (V4L2_FIELD_ANY == field) {
 718                field = (f->fmt.pix.height > maxh / 2)
 719                    ? V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP;
 720        }
 721
 722        switch (field) {
 723        case V4L2_FIELD_TOP:
 724        case V4L2_FIELD_BOTTOM:
 725                maxh = maxh / 2;
 726                break;
 727        case V4L2_FIELD_INTERLACED:
 728                break;
 729        default:
 730                return -EINVAL;
 731        }
 732
 733        f->fmt.pix.field = field;
 734        if (f->fmt.pix.height < 32)
 735                f->fmt.pix.height = 32;
 736        if (f->fmt.pix.height > maxh)
 737                f->fmt.pix.height = maxh;
 738        if (f->fmt.pix.width < 48)
 739                f->fmt.pix.width = 48;
 740        if (f->fmt.pix.width > maxw)
 741                f->fmt.pix.width = maxw;
 742        f->fmt.pix.width &= ~0x03;
 743        f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
 744        f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
 745
 746        return 0;
 747}
 748
 749int vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap)
 750{
 751        struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
 752
 753        strcpy(cap->driver, "cx25821");
 754        strlcpy(cap->card, cx25821_boards[dev->board].name, sizeof(cap->card));
 755        sprintf(cap->bus_info, "PCIe:%s", pci_name(dev->pci));
 756        cap->version = CX25821_VERSION_CODE;
 757        cap->capabilities =
 758            V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
 759        if (UNSET != dev->tuner_type)
 760                cap->capabilities |= V4L2_CAP_TUNER;
 761        return 0;
 762}
 763
 764int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
 765                            struct v4l2_fmtdesc *f)
 766{
 767        if (unlikely(f->index >= ARRAY_SIZE(formats)))
 768                return -EINVAL;
 769
 770        strlcpy(f->description, formats[f->index].name, sizeof(f->description));
 771        f->pixelformat = formats[f->index].fourcc;
 772
 773        return 0;
 774}
 775
 776#ifdef CONFIG_VIDEO_V4L1_COMPAT
 777int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
 778{
 779        struct cx25821_fh *fh = priv;
 780        struct videobuf_queue *q;
 781        struct v4l2_requestbuffers req;
 782        unsigned int i;
 783        int err;
 784
 785        q = get_queue(fh);
 786        memset(&req, 0, sizeof(req));
 787        req.type = q->type;
 788        req.count = 8;
 789        req.memory = V4L2_MEMORY_MMAP;
 790        err = videobuf_reqbufs(q, &req);
 791        if (err < 0)
 792                return err;
 793
 794        mbuf->frames = req.count;
 795        mbuf->size = 0;
 796        for (i = 0; i < mbuf->frames; i++) {
 797                mbuf->offsets[i] = q->bufs[i]->boff;
 798                mbuf->size += q->bufs[i]->bsize;
 799        }
 800        return 0;
 801}
 802#endif
 803
 804int vidioc_reqbufs(struct file *file, void *priv, struct v4l2_requestbuffers *p)
 805{
 806        struct cx25821_fh *fh = priv;
 807        return videobuf_reqbufs(get_queue(fh), p);
 808}
 809
 810int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p)
 811{
 812        struct cx25821_fh *fh = priv;
 813        return videobuf_querybuf(get_queue(fh), p);
 814}
 815
 816int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
 817{
 818        struct cx25821_fh *fh = priv;
 819        return videobuf_qbuf(get_queue(fh), p);
 820}
 821
 822int vidioc_g_priority(struct file *file, void *f, enum v4l2_priority *p)
 823{
 824        struct cx25821_dev *dev = ((struct cx25821_fh *)f)->dev;
 825
 826        *p = v4l2_prio_max(&dev->prio);
 827
 828        return 0;
 829}
 830
 831int vidioc_s_priority(struct file *file, void *f, enum v4l2_priority prio)
 832{
 833        struct cx25821_fh *fh = f;
 834        struct cx25821_dev *dev = ((struct cx25821_fh *)f)->dev;
 835
 836        return v4l2_prio_change(&dev->prio, &fh->prio, prio);
 837}
 838
 839#ifdef TUNER_FLAG
 840int vidioc_s_std(struct file *file, void *priv, v4l2_std_id * tvnorms)
 841{
 842        struct cx25821_fh *fh = priv;
 843        struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
 844        int err;
 845
 846        dprintk(1, "%s()\n", __func__);
 847
 848        if (fh) {
 849                err = v4l2_prio_check(&dev->prio, &fh->prio);
 850                if (0 != err)
 851                        return err;
 852        }
 853
 854        if (dev->tvnorm == *tvnorms) {
 855                return 0;
 856        }
 857
 858        mutex_lock(&dev->lock);
 859        cx25821_set_tvnorm(dev, *tvnorms);
 860        mutex_unlock(&dev->lock);
 861
 862        medusa_set_videostandard(dev);
 863
 864        return 0;
 865}
 866#endif
 867
 868int cx25821_enum_input(struct cx25821_dev *dev, struct v4l2_input *i)
 869{
 870        static const char *iname[] = {
 871                [CX25821_VMUX_COMPOSITE] = "Composite",
 872                [CX25821_VMUX_SVIDEO] = "S-Video",
 873                [CX25821_VMUX_DEBUG] = "for debug only",
 874        };
 875        unsigned int n;
 876        dprintk(1, "%s()\n", __func__);
 877
 878        n = i->index;
 879        if (n > 2)
 880                return -EINVAL;
 881
 882        if (0 == INPUT(n)->type)
 883                return -EINVAL;
 884
 885        memset(i, 0, sizeof(*i));
 886        i->index = n;
 887        i->type = V4L2_INPUT_TYPE_CAMERA;
 888        strcpy(i->name, iname[INPUT(n)->type]);
 889
 890        i->std = CX25821_NORMS;
 891        return 0;
 892}
 893
 894int vidioc_enum_input(struct file *file, void *priv, struct v4l2_input *i)
 895{
 896        struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
 897        dprintk(1, "%s()\n", __func__);
 898        return cx25821_enum_input(dev, i);
 899}
 900
 901int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
 902{
 903        struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
 904
 905        *i = dev->input;
 906        dprintk(1, "%s() returns %d\n", __func__, *i);
 907        return 0;
 908}
 909
 910int vidioc_s_input(struct file *file, void *priv, unsigned int i)
 911{
 912        struct cx25821_fh *fh = priv;
 913        struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
 914        int err;
 915
 916        dprintk(1, "%s(%d)\n", __func__, i);
 917
 918        if (fh) {
 919                err = v4l2_prio_check(&dev->prio, &fh->prio);
 920                if (0 != err)
 921                        return err;
 922        }
 923
 924        if (i > 2) {
 925                dprintk(1, "%s() -EINVAL\n", __func__);
 926                return -EINVAL;
 927        }
 928
 929        mutex_lock(&dev->lock);
 930        cx25821_video_mux(dev, i);
 931        mutex_unlock(&dev->lock);
 932        return 0;
 933}
 934
 935#ifdef TUNER_FLAG
 936int vidioc_g_frequency(struct file *file, void *priv, struct v4l2_frequency *f)
 937{
 938        struct cx25821_fh *fh = priv;
 939        struct cx25821_dev *dev = fh->dev;
 940
 941        f->frequency = dev->freq;
 942
 943        cx25821_call_all(dev, tuner, g_frequency, f);
 944
 945        return 0;
 946}
 947
 948int cx25821_set_freq(struct cx25821_dev *dev, struct v4l2_frequency *f)
 949{
 950        mutex_lock(&dev->lock);
 951        dev->freq = f->frequency;
 952
 953        cx25821_call_all(dev, tuner, s_frequency, f);
 954
 955        /* When changing channels it is required to reset TVAUDIO */
 956        msleep(10);
 957
 958        mutex_unlock(&dev->lock);
 959
 960        return 0;
 961}
 962
 963int vidioc_s_frequency(struct file *file, void *priv, struct v4l2_frequency *f)
 964{
 965        struct cx25821_fh *fh = priv;
 966        struct cx25821_dev *dev = fh->dev;
 967        int err;
 968
 969        if (fh) {
 970                err = v4l2_prio_check(&dev->prio, &fh->prio);
 971                if (0 != err)
 972                        return err;
 973        }
 974
 975        return cx25821_set_freq(dev, f);
 976}
 977#endif
 978
 979#ifdef CONFIG_VIDEO_ADV_DEBUG
 980int vidioc_g_register(struct file *file, void *fh,
 981                      struct v4l2_dbg_register *reg)
 982{
 983        struct cx25821_dev *dev = ((struct cx25821_fh *)fh)->dev;
 984
 985        if (!v4l2_chip_match_host(&reg->match))
 986                return -EINVAL;
 987
 988        cx25821_call_all(dev, core, g_register, reg);
 989
 990        return 0;
 991}
 992
 993int vidioc_s_register(struct file *file, void *fh,
 994                      struct v4l2_dbg_register *reg)
 995{
 996        struct cx25821_dev *dev = ((struct cx25821_fh *)fh)->dev;
 997
 998        if (!v4l2_chip_match_host(&reg->match))
 999                return -EINVAL;
1000
1001        cx25821_call_all(dev, core, s_register, reg);
1002
1003        return 0;
1004}
1005
1006#endif
1007
1008#ifdef TUNER_FLAG
1009int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
1010{
1011        struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
1012
1013        if (unlikely(UNSET == dev->tuner_type))
1014                return -EINVAL;
1015        if (0 != t->index)
1016                return -EINVAL;
1017
1018        strcpy(t->name, "Television");
1019        t->type = V4L2_TUNER_ANALOG_TV;
1020        t->capability = V4L2_TUNER_CAP_NORM;
1021        t->rangehigh = 0xffffffffUL;
1022
1023        t->signal = 0xffff;     /* LOCKED */
1024        return 0;
1025}
1026
1027int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
1028{
1029        struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
1030        struct cx25821_fh *fh = priv;
1031        int err;
1032
1033        if (fh) {
1034                err = v4l2_prio_check(&dev->prio, &fh->prio);
1035                if (0 != err)
1036                        return err;
1037        }
1038
1039        dprintk(1, "%s()\n", __func__);
1040        if (UNSET == dev->tuner_type)
1041                return -EINVAL;
1042        if (0 != t->index)
1043                return -EINVAL;
1044
1045        return 0;
1046}
1047
1048#endif
1049// ******************************************************************************************
1050static const struct v4l2_queryctrl no_ctl = {
1051        .name = "42",
1052        .flags = V4L2_CTRL_FLAG_DISABLED,
1053};
1054
1055static struct v4l2_queryctrl cx25821_ctls[] = {
1056        /* --- video --- */
1057        {
1058         .id = V4L2_CID_BRIGHTNESS,
1059         .name = "Brightness",
1060         .minimum = 0,
1061         .maximum = 10000,
1062         .step = 1,
1063         .default_value = 6200,
1064         .type = V4L2_CTRL_TYPE_INTEGER,
1065         }, {
1066             .id = V4L2_CID_CONTRAST,
1067             .name = "Contrast",
1068             .minimum = 0,
1069             .maximum = 10000,
1070             .step = 1,
1071             .default_value = 5000,
1072             .type = V4L2_CTRL_TYPE_INTEGER,
1073             }, {
1074                 .id = V4L2_CID_SATURATION,
1075                 .name = "Saturation",
1076                 .minimum = 0,
1077                 .maximum = 10000,
1078                 .step = 1,
1079                 .default_value = 5000,
1080                 .type = V4L2_CTRL_TYPE_INTEGER,
1081                 }, {
1082                     .id = V4L2_CID_HUE,
1083                     .name = "Hue",
1084                     .minimum = 0,
1085                     .maximum = 10000,
1086                     .step = 1,
1087                     .default_value = 5000,
1088                     .type = V4L2_CTRL_TYPE_INTEGER,
1089                     }
1090};
1091static const int CX25821_CTLS = ARRAY_SIZE(cx25821_ctls);
1092
1093static int cx25821_ctrl_query(struct v4l2_queryctrl *qctrl)
1094{
1095        int i;
1096
1097        if (qctrl->id < V4L2_CID_BASE || qctrl->id >= V4L2_CID_LASTP1)
1098                return -EINVAL;
1099        for (i = 0; i < CX25821_CTLS; i++)
1100                if (cx25821_ctls[i].id == qctrl->id)
1101                        break;
1102        if (i == CX25821_CTLS) {
1103                *qctrl = no_ctl;
1104                return 0;
1105        }
1106        *qctrl = cx25821_ctls[i];
1107        return 0;
1108}
1109
1110int vidioc_queryctrl(struct file *file, void *priv,
1111                     struct v4l2_queryctrl *qctrl)
1112{
1113        return cx25821_ctrl_query(qctrl);
1114}
1115
1116/* ------------------------------------------------------------------ */
1117/* VIDEO CTRL IOCTLS                                                  */
1118
1119static const struct v4l2_queryctrl *ctrl_by_id(unsigned int id)
1120{
1121        unsigned int i;
1122
1123        for (i = 0; i < CX25821_CTLS; i++)
1124                if (cx25821_ctls[i].id == id)
1125                        return cx25821_ctls + i;
1126        return NULL;
1127}
1128
1129int vidioc_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctl)
1130{
1131        struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
1132
1133        const struct v4l2_queryctrl *ctrl;
1134
1135        ctrl = ctrl_by_id(ctl->id);
1136
1137        if (NULL == ctrl)
1138                return -EINVAL;
1139        switch (ctl->id) {
1140        case V4L2_CID_BRIGHTNESS:
1141                ctl->value = dev->ctl_bright;
1142                break;
1143        case V4L2_CID_HUE:
1144                ctl->value = dev->ctl_hue;
1145                break;
1146        case V4L2_CID_CONTRAST:
1147                ctl->value = dev->ctl_contrast;
1148                break;
1149        case V4L2_CID_SATURATION:
1150                ctl->value = dev->ctl_saturation;
1151                break;
1152        }
1153        return 0;
1154}
1155
1156int cx25821_set_control(struct cx25821_dev *dev,
1157                        struct v4l2_control *ctl, int chan_num)
1158{
1159        int err;
1160        const struct v4l2_queryctrl *ctrl;
1161
1162        err = -EINVAL;
1163
1164        ctrl = ctrl_by_id(ctl->id);
1165
1166        if (NULL == ctrl)
1167                return err;
1168
1169        switch (ctrl->type) {
1170        case V4L2_CTRL_TYPE_BOOLEAN:
1171        case V4L2_CTRL_TYPE_MENU:
1172        case V4L2_CTRL_TYPE_INTEGER:
1173                if (ctl->value < ctrl->minimum)
1174                        ctl->value = ctrl->minimum;
1175                if (ctl->value > ctrl->maximum)
1176                        ctl->value = ctrl->maximum;
1177                break;
1178        default:
1179                /* nothing */ ;
1180        };
1181
1182        switch (ctl->id) {
1183        case V4L2_CID_BRIGHTNESS:
1184                dev->ctl_bright = ctl->value;
1185                medusa_set_brightness(dev, ctl->value, chan_num);
1186                break;
1187        case V4L2_CID_HUE:
1188                dev->ctl_hue = ctl->value;
1189                medusa_set_hue(dev, ctl->value, chan_num);
1190                break;
1191        case V4L2_CID_CONTRAST:
1192                dev->ctl_contrast = ctl->value;
1193                medusa_set_contrast(dev, ctl->value, chan_num);
1194                break;
1195        case V4L2_CID_SATURATION:
1196                dev->ctl_saturation = ctl->value;
1197                medusa_set_saturation(dev, ctl->value, chan_num);
1198                break;
1199        }
1200
1201        err = 0;
1202
1203        return err;
1204}
1205
1206static void init_controls(struct cx25821_dev *dev, int chan_num)
1207{
1208        struct v4l2_control ctrl;
1209        int i;
1210        for (i = 0; i < CX25821_CTLS; i++) {
1211                ctrl.id = cx25821_ctls[i].id;
1212                ctrl.value = cx25821_ctls[i].default_value;
1213
1214                cx25821_set_control(dev, &ctrl, chan_num);
1215        }
1216}
1217
1218int vidioc_cropcap(struct file *file, void *priv, struct v4l2_cropcap *cropcap)
1219{
1220        struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
1221
1222        if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1223                return -EINVAL;
1224        cropcap->bounds.top = cropcap->bounds.left = 0;
1225        cropcap->bounds.width = 720;
1226        cropcap->bounds.height = dev->tvnorm == V4L2_STD_PAL_BG ? 576 : 480;
1227        cropcap->pixelaspect.numerator =
1228            dev->tvnorm == V4L2_STD_PAL_BG ? 59 : 10;
1229        cropcap->pixelaspect.denominator =
1230            dev->tvnorm == V4L2_STD_PAL_BG ? 54 : 11;
1231        cropcap->defrect = cropcap->bounds;
1232        return 0;
1233}
1234
1235int vidioc_s_crop(struct file *file, void *priv, struct v4l2_crop *crop)
1236{
1237        struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
1238        struct cx25821_fh *fh = priv;
1239        int err;
1240
1241        if (fh) {
1242                err = v4l2_prio_check(&dev->prio, &fh->prio);
1243                if (0 != err)
1244                        return err;
1245        }
1246        // vidioc_s_crop not supported
1247        return -EINVAL;
1248}
1249
1250int vidioc_g_crop(struct file *file, void *priv, struct v4l2_crop *crop)
1251{
1252        // vidioc_g_crop not supported
1253        return -EINVAL;
1254}
1255
1256int vidioc_querystd(struct file *file, void *priv, v4l2_std_id * norm)
1257{
1258        // medusa does not support video standard sensing of current input
1259        *norm = CX25821_NORMS;
1260
1261        return 0;
1262}
1263
1264int is_valid_width(u32 width, v4l2_std_id tvnorm)
1265{
1266        if (tvnorm == V4L2_STD_PAL_BG) {
1267                if (width == 352 || width == 720)
1268                        return 1;
1269                else
1270                        return 0;
1271        }
1272
1273        if (tvnorm == V4L2_STD_NTSC_M) {
1274                if (width == 320 || width == 352 || width == 720)
1275                        return 1;
1276                else
1277                        return 0;
1278        }
1279        return 0;
1280}
1281
1282int is_valid_height(u32 height, v4l2_std_id tvnorm)
1283{
1284        if (tvnorm == V4L2_STD_PAL_BG) {
1285                if (height == 576 || height == 288)
1286                        return 1;
1287                else
1288                        return 0;
1289        }
1290
1291        if (tvnorm == V4L2_STD_NTSC_M) {
1292                if (height == 480 || height == 240)
1293                        return 1;
1294                else
1295                        return 0;
1296        }
1297
1298        return 0;
1299}
1300