linux/drivers/media/pci/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 *  Parts adapted/taken from Eduardo Moscoso Rubino
   8 *  Copyright (C) 2009 Eduardo Moscoso Rubino <moscoso@TopoLogica.com>
   9 *
  10 *
  11 *  This program is free software; you can redistribute it and/or modify
  12 *  it under the terms of the GNU General Public License as published by
  13 *  the Free Software Foundation; either version 2 of the License, or
  14 *  (at your option) any later version.
  15 *
  16 *  This program is distributed in the hope that it will be useful,
  17 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  18 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19 *
  20 *  GNU General Public License for more details.
  21 *
  22 *  You should have received a copy of the GNU General Public License
  23 *  along with this program; if not, write to the Free Software
  24 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  25 */
  26
  27#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  28
  29#include "cx25821-video.h"
  30
  31MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards");
  32MODULE_AUTHOR("Hiep Huynh <hiep.huynh@conexant.com>");
  33MODULE_LICENSE("GPL");
  34
  35static unsigned int video_nr[] = {[0 ... (CX25821_MAXBOARDS - 1)] = UNSET };
  36
  37module_param_array(video_nr, int, NULL, 0444);
  38
  39MODULE_PARM_DESC(video_nr, "video device numbers");
  40
  41static unsigned int video_debug = VIDEO_DEBUG;
  42module_param(video_debug, int, 0644);
  43MODULE_PARM_DESC(video_debug, "enable debug messages [video]");
  44
  45static unsigned int irq_debug;
  46module_param(irq_debug, int, 0644);
  47MODULE_PARM_DESC(irq_debug, "enable debug messages [IRQ handler]");
  48
  49static unsigned int vid_limit = 16;
  50module_param(vid_limit, int, 0644);
  51MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes");
  52
  53#define FORMAT_FLAGS_PACKED       0x01
  54
  55static const struct cx25821_fmt formats[] = {
  56        {
  57                .name = "4:1:1, packed, Y41P",
  58                .fourcc = V4L2_PIX_FMT_Y41P,
  59                .depth = 12,
  60                .flags = FORMAT_FLAGS_PACKED,
  61        }, {
  62                .name = "4:2:2, packed, YUYV",
  63                .fourcc = V4L2_PIX_FMT_YUYV,
  64                .depth = 16,
  65                .flags = FORMAT_FLAGS_PACKED,
  66        },
  67};
  68
  69static const struct cx25821_fmt *cx25821_format_by_fourcc(unsigned int fourcc)
  70{
  71        unsigned int i;
  72
  73        for (i = 0; i < ARRAY_SIZE(formats); i++)
  74                if (formats[i].fourcc == fourcc)
  75                        return formats + i;
  76        return NULL;
  77}
  78
  79void cx25821_video_wakeup(struct cx25821_dev *dev, struct cx25821_dmaqueue *q,
  80                          u32 count)
  81{
  82        struct cx25821_buffer *buf;
  83        int bc;
  84
  85        for (bc = 0;; bc++) {
  86                if (list_empty(&q->active)) {
  87                        dprintk(1, "bc=%d (=0: active empty)\n", bc);
  88                        break;
  89                }
  90
  91                buf = list_entry(q->active.next, struct cx25821_buffer,
  92                                vb.queue);
  93
  94                /* count comes from the hw and it is 16bit wide --
  95                 * this trick handles wrap-arounds correctly for
  96                 * up to 32767 buffers in flight... */
  97                if ((s16) (count - buf->count) < 0)
  98                        break;
  99
 100                v4l2_get_timestamp(&buf->vb.ts);
 101                buf->vb.state = VIDEOBUF_DONE;
 102                list_del(&buf->vb.queue);
 103                wake_up(&buf->vb.done);
 104        }
 105
 106        if (list_empty(&q->active))
 107                del_timer(&q->timeout);
 108        else
 109                mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
 110        if (bc != 1)
 111                pr_err("%s: %d buffers handled (should be 1)\n", __func__, bc);
 112}
 113
 114int cx25821_start_video_dma(struct cx25821_dev *dev,
 115                            struct cx25821_dmaqueue *q,
 116                            struct cx25821_buffer *buf,
 117                            const struct sram_channel *channel)
 118{
 119        int tmp = 0;
 120
 121        /* setup fifo + format */
 122        cx25821_sram_channel_setup(dev, channel, buf->bpl, buf->risc.dma);
 123
 124        /* reset counter */
 125        cx_write(channel->gpcnt_ctl, 3);
 126        q->count = 1;
 127
 128        /* enable irq */
 129        cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) | (1 << channel->i));
 130        cx_set(channel->int_msk, 0x11);
 131
 132        /* start dma */
 133        cx_write(channel->dma_ctl, 0x11);       /* FIFO and RISC enable */
 134
 135        /* make sure upstream setting if any is reversed */
 136        tmp = cx_read(VID_CH_MODE_SEL);
 137        cx_write(VID_CH_MODE_SEL, tmp & 0xFFFFFE00);
 138
 139        return 0;
 140}
 141
 142static int cx25821_restart_video_queue(struct cx25821_dev *dev,
 143                                       struct cx25821_dmaqueue *q,
 144                                       const struct sram_channel *channel)
 145{
 146        struct cx25821_buffer *buf, *prev;
 147        struct list_head *item;
 148
 149        if (!list_empty(&q->active)) {
 150                buf = list_entry(q->active.next, struct cx25821_buffer,
 151                                vb.queue);
 152
 153                cx25821_start_video_dma(dev, q, buf, channel);
 154
 155                list_for_each(item, &q->active) {
 156                        buf = list_entry(item, struct cx25821_buffer, vb.queue);
 157                        buf->count = q->count++;
 158                }
 159
 160                mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
 161                return 0;
 162        }
 163
 164        prev = NULL;
 165        for (;;) {
 166                if (list_empty(&q->queued))
 167                        return 0;
 168
 169                buf = list_entry(q->queued.next, struct cx25821_buffer,
 170                                vb.queue);
 171
 172                if (NULL == prev) {
 173                        list_move_tail(&buf->vb.queue, &q->active);
 174                        cx25821_start_video_dma(dev, q, buf, channel);
 175                        buf->vb.state = VIDEOBUF_ACTIVE;
 176                        buf->count = q->count++;
 177                        mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
 178                } else if (prev->vb.width == buf->vb.width &&
 179                           prev->vb.height == buf->vb.height &&
 180                           prev->fmt == buf->fmt) {
 181                        list_move_tail(&buf->vb.queue, &q->active);
 182                        buf->vb.state = VIDEOBUF_ACTIVE;
 183                        buf->count = q->count++;
 184                        prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
 185                        prev->risc.jmp[2] = cpu_to_le32(0); /* Bits 63 - 32 */
 186                } else {
 187                        return 0;
 188                }
 189                prev = buf;
 190        }
 191}
 192
 193static void cx25821_vid_timeout(unsigned long data)
 194{
 195        struct cx25821_data *timeout_data = (struct cx25821_data *)data;
 196        struct cx25821_dev *dev = timeout_data->dev;
 197        const struct sram_channel *channel = timeout_data->channel;
 198        struct cx25821_dmaqueue *q = &dev->channels[channel->i].dma_vidq;
 199        struct cx25821_buffer *buf;
 200        unsigned long flags;
 201
 202        /* cx25821_sram_channel_dump(dev, channel); */
 203        cx_clear(channel->dma_ctl, 0x11);
 204
 205        spin_lock_irqsave(&dev->slock, flags);
 206        while (!list_empty(&q->active)) {
 207                buf = list_entry(q->active.next, struct cx25821_buffer,
 208                                vb.queue);
 209                list_del(&buf->vb.queue);
 210
 211                buf->vb.state = VIDEOBUF_ERROR;
 212                wake_up(&buf->vb.done);
 213        }
 214
 215        cx25821_restart_video_queue(dev, q, channel);
 216        spin_unlock_irqrestore(&dev->slock, flags);
 217}
 218
 219int cx25821_video_irq(struct cx25821_dev *dev, int chan_num, u32 status)
 220{
 221        u32 count = 0;
 222        int handled = 0;
 223        u32 mask;
 224        const struct sram_channel *channel = dev->channels[chan_num].sram_channels;
 225
 226        mask = cx_read(channel->int_msk);
 227        if (0 == (status & mask))
 228                return handled;
 229
 230        cx_write(channel->int_stat, status);
 231
 232        /* risc op code error */
 233        if (status & (1 << 16)) {
 234                pr_warn("%s, %s: video risc op code error\n",
 235                        dev->name, channel->name);
 236                cx_clear(channel->dma_ctl, 0x11);
 237                cx25821_sram_channel_dump(dev, channel);
 238        }
 239
 240        /* risc1 y */
 241        if (status & FLD_VID_DST_RISC1) {
 242                spin_lock(&dev->slock);
 243                count = cx_read(channel->gpcnt);
 244                cx25821_video_wakeup(dev, &dev->channels[channel->i].dma_vidq,
 245                                count);
 246                spin_unlock(&dev->slock);
 247                handled++;
 248        }
 249
 250        /* risc2 y */
 251        if (status & 0x10) {
 252                dprintk(2, "stopper video\n");
 253                spin_lock(&dev->slock);
 254                cx25821_restart_video_queue(dev,
 255                                &dev->channels[channel->i].dma_vidq, channel);
 256                spin_unlock(&dev->slock);
 257                handled++;
 258        }
 259        return handled;
 260}
 261
 262static int cx25821_buffer_setup(struct videobuf_queue *q, unsigned int *count,
 263                 unsigned int *size)
 264{
 265        struct cx25821_channel *chan = q->priv_data;
 266
 267        *size = chan->fmt->depth * chan->width * chan->height >> 3;
 268
 269        if (0 == *count)
 270                *count = 32;
 271
 272        if (*size * *count > vid_limit * 1024 * 1024)
 273                *count = (vid_limit * 1024 * 1024) / *size;
 274
 275        return 0;
 276}
 277
 278static int cx25821_buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
 279                   enum v4l2_field field)
 280{
 281        struct cx25821_channel *chan = q->priv_data;
 282        struct cx25821_dev *dev = chan->dev;
 283        struct cx25821_buffer *buf =
 284                container_of(vb, struct cx25821_buffer, vb);
 285        int rc, init_buffer = 0;
 286        u32 line0_offset;
 287        struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb);
 288        int bpl_local = LINE_SIZE_D1;
 289
 290        BUG_ON(NULL == chan->fmt);
 291        if (chan->width < 48 || chan->width > 720 ||
 292            chan->height < 32 || chan->height > 576)
 293                return -EINVAL;
 294
 295        buf->vb.size = (chan->width * chan->height * chan->fmt->depth) >> 3;
 296
 297        if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
 298                return -EINVAL;
 299
 300        if (buf->fmt != chan->fmt ||
 301            buf->vb.width != chan->width ||
 302            buf->vb.height != chan->height || buf->vb.field != field) {
 303                buf->fmt = chan->fmt;
 304                buf->vb.width = chan->width;
 305                buf->vb.height = chan->height;
 306                buf->vb.field = field;
 307                init_buffer = 1;
 308        }
 309
 310        if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
 311                init_buffer = 1;
 312                rc = videobuf_iolock(q, &buf->vb, NULL);
 313                if (0 != rc) {
 314                        printk(KERN_DEBUG pr_fmt("videobuf_iolock failed!\n"));
 315                        goto fail;
 316                }
 317        }
 318
 319        dprintk(1, "init_buffer=%d\n", init_buffer);
 320
 321        if (init_buffer) {
 322                if (chan->pixel_formats == PIXEL_FRMT_411)
 323                        buf->bpl = (buf->fmt->depth * buf->vb.width) >> 3;
 324                else
 325                        buf->bpl = (buf->fmt->depth >> 3) * (buf->vb.width);
 326
 327                if (chan->pixel_formats == PIXEL_FRMT_411) {
 328                        bpl_local = buf->bpl;
 329                } else {
 330                        bpl_local = buf->bpl;   /* Default */
 331
 332                        if (chan->use_cif_resolution) {
 333                                if (dev->tvnorm & V4L2_STD_625_50)
 334                                        bpl_local = 352 << 1;
 335                                else
 336                                        bpl_local = chan->cif_width << 1;
 337                        }
 338                }
 339
 340                switch (buf->vb.field) {
 341                case V4L2_FIELD_TOP:
 342                        cx25821_risc_buffer(dev->pci, &buf->risc,
 343                                            dma->sglist, 0, UNSET,
 344                                            buf->bpl, 0, buf->vb.height);
 345                        break;
 346                case V4L2_FIELD_BOTTOM:
 347                        cx25821_risc_buffer(dev->pci, &buf->risc,
 348                                            dma->sglist, UNSET, 0,
 349                                            buf->bpl, 0, buf->vb.height);
 350                        break;
 351                case V4L2_FIELD_INTERLACED:
 352                        /* All other formats are top field first */
 353                        line0_offset = 0;
 354                        dprintk(1, "top field first\n");
 355
 356                        cx25821_risc_buffer(dev->pci, &buf->risc,
 357                                            dma->sglist, line0_offset,
 358                                            bpl_local, bpl_local, bpl_local,
 359                                            buf->vb.height >> 1);
 360                        break;
 361                case V4L2_FIELD_SEQ_TB:
 362                        cx25821_risc_buffer(dev->pci, &buf->risc,
 363                                            dma->sglist,
 364                                            0, buf->bpl * (buf->vb.height >> 1),
 365                                            buf->bpl, 0, buf->vb.height >> 1);
 366                        break;
 367                case V4L2_FIELD_SEQ_BT:
 368                        cx25821_risc_buffer(dev->pci, &buf->risc,
 369                                            dma->sglist,
 370                                            buf->bpl * (buf->vb.height >> 1), 0,
 371                                            buf->bpl, 0, buf->vb.height >> 1);
 372                        break;
 373                default:
 374                        BUG();
 375                }
 376        }
 377
 378        dprintk(2, "[%p/%d] buffer_prep - %dx%d %dbpp \"%s\" - dma=0x%08lx\n",
 379                buf, buf->vb.i, chan->width, chan->height, chan->fmt->depth,
 380                chan->fmt->name, (unsigned long)buf->risc.dma);
 381
 382        buf->vb.state = VIDEOBUF_PREPARED;
 383
 384        return 0;
 385
 386fail:
 387        cx25821_free_buffer(q, buf);
 388        return rc;
 389}
 390
 391static void cx25821_buffer_release(struct videobuf_queue *q,
 392                            struct videobuf_buffer *vb)
 393{
 394        struct cx25821_buffer *buf =
 395                container_of(vb, struct cx25821_buffer, vb);
 396
 397        cx25821_free_buffer(q, buf);
 398}
 399
 400static int cx25821_video_mmap(struct file *file, struct vm_area_struct *vma)
 401{
 402        struct cx25821_channel *chan = video_drvdata(file);
 403
 404        return videobuf_mmap_mapper(&chan->vidq, vma);
 405}
 406
 407
 408static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
 409{
 410        struct cx25821_buffer *buf =
 411                container_of(vb, struct cx25821_buffer, vb);
 412        struct cx25821_buffer *prev;
 413        struct cx25821_channel *chan = vq->priv_data;
 414        struct cx25821_dev *dev = chan->dev;
 415        struct cx25821_dmaqueue *q = &dev->channels[chan->id].dma_vidq;
 416
 417        /* add jump to stopper */
 418        buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
 419        buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
 420        buf->risc.jmp[2] = cpu_to_le32(0);      /* bits 63-32 */
 421
 422        dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
 423
 424        if (!list_empty(&q->queued)) {
 425                list_add_tail(&buf->vb.queue, &q->queued);
 426                buf->vb.state = VIDEOBUF_QUEUED;
 427                dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf,
 428                                buf->vb.i);
 429
 430        } else if (list_empty(&q->active)) {
 431                list_add_tail(&buf->vb.queue, &q->active);
 432                cx25821_start_video_dma(dev, q, buf, chan->sram_channels);
 433                buf->vb.state = VIDEOBUF_ACTIVE;
 434                buf->count = q->count++;
 435                mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
 436                dprintk(2, "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
 437                                buf, buf->vb.i, buf->count, q->count);
 438        } else {
 439                prev = list_entry(q->active.prev, struct cx25821_buffer,
 440                                vb.queue);
 441                if (prev->vb.width == buf->vb.width
 442                   && prev->vb.height == buf->vb.height
 443                   && prev->fmt == buf->fmt) {
 444                        list_add_tail(&buf->vb.queue, &q->active);
 445                        buf->vb.state = VIDEOBUF_ACTIVE;
 446                        buf->count = q->count++;
 447                        prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
 448
 449                        /* 64 bit bits 63-32 */
 450                        prev->risc.jmp[2] = cpu_to_le32(0);
 451                        dprintk(2, "[%p/%d] buffer_queue - append to active, buf->count=%d\n",
 452                                        buf, buf->vb.i, buf->count);
 453
 454                } else {
 455                        list_add_tail(&buf->vb.queue, &q->queued);
 456                        buf->vb.state = VIDEOBUF_QUEUED;
 457                        dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
 458                                        buf->vb.i);
 459                }
 460        }
 461
 462        if (list_empty(&q->active))
 463                dprintk(2, "active queue empty!\n");
 464}
 465
 466static struct videobuf_queue_ops cx25821_video_qops = {
 467        .buf_setup = cx25821_buffer_setup,
 468        .buf_prepare = cx25821_buffer_prepare,
 469        .buf_queue = buffer_queue,
 470        .buf_release = cx25821_buffer_release,
 471};
 472
 473static ssize_t video_read(struct file *file, char __user * data, size_t count,
 474                         loff_t *ppos)
 475{
 476        struct v4l2_fh *fh = file->private_data;
 477        struct cx25821_channel *chan = video_drvdata(file);
 478        struct cx25821_dev *dev = chan->dev;
 479        int err = 0;
 480
 481        if (mutex_lock_interruptible(&dev->lock))
 482                return -ERESTARTSYS;
 483        if (chan->streaming_fh && chan->streaming_fh != fh) {
 484                err = -EBUSY;
 485                goto unlock;
 486        }
 487        chan->streaming_fh = fh;
 488
 489        err = videobuf_read_one(&chan->vidq, data, count, ppos,
 490                                file->f_flags & O_NONBLOCK);
 491unlock:
 492        mutex_unlock(&dev->lock);
 493        return err;
 494}
 495
 496static unsigned int video_poll(struct file *file,
 497                              struct poll_table_struct *wait)
 498{
 499        struct cx25821_channel *chan = video_drvdata(file);
 500        unsigned long req_events = poll_requested_events(wait);
 501        unsigned int res = v4l2_ctrl_poll(file, wait);
 502
 503        if (req_events & (POLLIN | POLLRDNORM))
 504                res |= videobuf_poll_stream(file, &chan->vidq, wait);
 505        return res;
 506
 507        /* This doesn't belong in poll(). This can be done
 508         * much better with vb2. We keep this code here as a
 509         * reminder.
 510        if ((res & POLLIN) && buf->vb.state == VIDEOBUF_DONE) {
 511                struct cx25821_dev *dev = chan->dev;
 512
 513                if (dev && chan->use_cif_resolution) {
 514                        u8 cam_id = *((char *)buf->vb.baddr + 3);
 515                        memcpy((char *)buf->vb.baddr,
 516                                        (char *)buf->vb.baddr + (chan->width * 2),
 517                                        (chan->width * 2));
 518                        *((char *)buf->vb.baddr + 3) = cam_id;
 519                }
 520        }
 521         */
 522}
 523
 524static int video_release(struct file *file)
 525{
 526        struct cx25821_channel *chan = video_drvdata(file);
 527        struct v4l2_fh *fh = file->private_data;
 528        struct cx25821_dev *dev = chan->dev;
 529        const struct sram_channel *sram_ch =
 530                dev->channels[0].sram_channels;
 531
 532        mutex_lock(&dev->lock);
 533        /* stop the risc engine and fifo */
 534        cx_write(sram_ch->dma_ctl, 0); /* FIFO and RISC disable */
 535
 536        /* stop video capture */
 537        if (chan->streaming_fh == fh) {
 538                videobuf_queue_cancel(&chan->vidq);
 539                chan->streaming_fh = NULL;
 540        }
 541
 542        if (chan->vidq.read_buf) {
 543                cx25821_buffer_release(&chan->vidq, chan->vidq.read_buf);
 544                kfree(chan->vidq.read_buf);
 545        }
 546
 547        videobuf_mmap_free(&chan->vidq);
 548        mutex_unlock(&dev->lock);
 549
 550        return v4l2_fh_release(file);
 551}
 552
 553/* VIDEO IOCTLS */
 554
 555static int cx25821_vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
 556                            struct v4l2_fmtdesc *f)
 557{
 558        if (unlikely(f->index >= ARRAY_SIZE(formats)))
 559                return -EINVAL;
 560
 561        strlcpy(f->description, formats[f->index].name, sizeof(f->description));
 562        f->pixelformat = formats[f->index].fourcc;
 563
 564        return 0;
 565}
 566
 567static int cx25821_vidioc_g_fmt_vid_cap(struct file *file, void *priv,
 568                                 struct v4l2_format *f)
 569{
 570        struct cx25821_channel *chan = video_drvdata(file);
 571
 572        f->fmt.pix.width = chan->width;
 573        f->fmt.pix.height = chan->height;
 574        f->fmt.pix.field = chan->vidq.field;
 575        f->fmt.pix.pixelformat = chan->fmt->fourcc;
 576        f->fmt.pix.bytesperline = (chan->width * chan->fmt->depth) >> 3;
 577        f->fmt.pix.sizeimage = chan->height * f->fmt.pix.bytesperline;
 578        f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
 579
 580        return 0;
 581}
 582
 583static int cx25821_vidioc_try_fmt_vid_cap(struct file *file, void *priv,
 584                                   struct v4l2_format *f)
 585{
 586        struct cx25821_channel *chan = video_drvdata(file);
 587        struct cx25821_dev *dev = chan->dev;
 588        const struct cx25821_fmt *fmt;
 589        enum v4l2_field field = f->fmt.pix.field;
 590        unsigned int maxh;
 591        unsigned w;
 592
 593        fmt = cx25821_format_by_fourcc(f->fmt.pix.pixelformat);
 594        if (NULL == fmt)
 595                return -EINVAL;
 596        maxh = (dev->tvnorm & V4L2_STD_625_50) ? 576 : 480;
 597
 598        w = f->fmt.pix.width;
 599        if (field != V4L2_FIELD_BOTTOM)
 600                field = V4L2_FIELD_TOP;
 601        if (w < 352) {
 602                w = 176;
 603                f->fmt.pix.height = maxh / 4;
 604        } else if (w < 720) {
 605                w = 352;
 606                f->fmt.pix.height = maxh / 2;
 607        } else {
 608                w = 720;
 609                f->fmt.pix.height = maxh;
 610                field = V4L2_FIELD_INTERLACED;
 611        }
 612        f->fmt.pix.field = field;
 613        f->fmt.pix.width = w;
 614        f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
 615        f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
 616        f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
 617
 618        return 0;
 619}
 620
 621static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
 622                                struct v4l2_format *f)
 623{
 624        struct cx25821_channel *chan = video_drvdata(file);
 625        struct cx25821_dev *dev = chan->dev;
 626        int pix_format = PIXEL_FRMT_422;
 627        int err;
 628
 629        err = cx25821_vidioc_try_fmt_vid_cap(file, priv, f);
 630
 631        if (0 != err)
 632                return err;
 633
 634        chan->fmt = cx25821_format_by_fourcc(f->fmt.pix.pixelformat);
 635        chan->vidq.field = f->fmt.pix.field;
 636        chan->width = f->fmt.pix.width;
 637        chan->height = f->fmt.pix.height;
 638
 639        if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
 640                pix_format = PIXEL_FRMT_411;
 641        else
 642                pix_format = PIXEL_FRMT_422;
 643
 644        cx25821_set_pixel_format(dev, SRAM_CH00, pix_format);
 645
 646        /* check if cif resolution */
 647        if (chan->width == 320 || chan->width == 352)
 648                chan->use_cif_resolution = 1;
 649        else
 650                chan->use_cif_resolution = 0;
 651
 652        chan->cif_width = chan->width;
 653        medusa_set_resolution(dev, chan->width, SRAM_CH00);
 654        return 0;
 655}
 656
 657static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
 658{
 659        struct cx25821_channel *chan = video_drvdata(file);
 660
 661        if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 662                return -EINVAL;
 663
 664        if (chan->streaming_fh && chan->streaming_fh != priv)
 665                return -EBUSY;
 666        chan->streaming_fh = priv;
 667
 668        return videobuf_streamon(&chan->vidq);
 669}
 670
 671static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
 672{
 673        struct cx25821_channel *chan = video_drvdata(file);
 674
 675        if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 676                return -EINVAL;
 677
 678        if (chan->streaming_fh && chan->streaming_fh != priv)
 679                return -EBUSY;
 680        if (chan->streaming_fh == NULL)
 681                return 0;
 682
 683        chan->streaming_fh = NULL;
 684        return videobuf_streamoff(&chan->vidq);
 685}
 686
 687static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
 688{
 689        int ret_val = 0;
 690        struct cx25821_channel *chan = video_drvdata(file);
 691
 692        ret_val = videobuf_dqbuf(&chan->vidq, p, file->f_flags & O_NONBLOCK);
 693        p->sequence = chan->dma_vidq.count;
 694
 695        return ret_val;
 696}
 697
 698static int vidioc_log_status(struct file *file, void *priv)
 699{
 700        struct cx25821_channel *chan = video_drvdata(file);
 701        struct cx25821_dev *dev = chan->dev;
 702        const struct sram_channel *sram_ch = chan->sram_channels;
 703        u32 tmp = 0;
 704
 705        tmp = cx_read(sram_ch->dma_ctl);
 706        pr_info("Video input 0 is %s\n",
 707                (tmp & 0x11) ? "streaming" : "stopped");
 708        return 0;
 709}
 710
 711
 712static int cx25821_vidioc_querycap(struct file *file, void *priv,
 713                            struct v4l2_capability *cap)
 714{
 715        struct cx25821_channel *chan = video_drvdata(file);
 716        struct cx25821_dev *dev = chan->dev;
 717        const u32 cap_input = V4L2_CAP_VIDEO_CAPTURE |
 718                        V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
 719        const u32 cap_output = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_READWRITE;
 720
 721        strcpy(cap->driver, "cx25821");
 722        strlcpy(cap->card, cx25821_boards[dev->board].name, sizeof(cap->card));
 723        sprintf(cap->bus_info, "PCIe:%s", pci_name(dev->pci));
 724        if (chan->id >= VID_CHANNEL_NUM)
 725                cap->device_caps = cap_output;
 726        else
 727                cap->device_caps = cap_input;
 728        cap->capabilities = cap_input | cap_output | V4L2_CAP_DEVICE_CAPS;
 729        return 0;
 730}
 731
 732static int cx25821_vidioc_reqbufs(struct file *file, void *priv,
 733                           struct v4l2_requestbuffers *p)
 734{
 735        struct cx25821_channel *chan = video_drvdata(file);
 736
 737        return videobuf_reqbufs(&chan->vidq, p);
 738}
 739
 740static int cx25821_vidioc_querybuf(struct file *file, void *priv,
 741                            struct v4l2_buffer *p)
 742{
 743        struct cx25821_channel *chan = video_drvdata(file);
 744
 745        return videobuf_querybuf(&chan->vidq, p);
 746}
 747
 748static int cx25821_vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
 749{
 750        struct cx25821_channel *chan = video_drvdata(file);
 751
 752        return videobuf_qbuf(&chan->vidq, p);
 753}
 754
 755static int cx25821_vidioc_g_std(struct file *file, void *priv, v4l2_std_id *tvnorms)
 756{
 757        struct cx25821_channel *chan = video_drvdata(file);
 758
 759        *tvnorms = chan->dev->tvnorm;
 760        return 0;
 761}
 762
 763static int cx25821_vidioc_s_std(struct file *file, void *priv,
 764                                v4l2_std_id tvnorms)
 765{
 766        struct cx25821_channel *chan = video_drvdata(file);
 767        struct cx25821_dev *dev = chan->dev;
 768
 769        if (dev->tvnorm == tvnorms)
 770                return 0;
 771
 772        dev->tvnorm = tvnorms;
 773        chan->width = 720;
 774        chan->height = (dev->tvnorm & V4L2_STD_625_50) ? 576 : 480;
 775
 776        medusa_set_videostandard(dev);
 777
 778        return 0;
 779}
 780
 781static int cx25821_vidioc_enum_input(struct file *file, void *priv,
 782                              struct v4l2_input *i)
 783{
 784        if (i->index)
 785                return -EINVAL;
 786
 787        i->type = V4L2_INPUT_TYPE_CAMERA;
 788        i->std = CX25821_NORMS;
 789        strcpy(i->name, "Composite");
 790        return 0;
 791}
 792
 793static int cx25821_vidioc_g_input(struct file *file, void *priv, unsigned int *i)
 794{
 795        *i = 0;
 796        return 0;
 797}
 798
 799static int cx25821_vidioc_s_input(struct file *file, void *priv, unsigned int i)
 800{
 801        return i ? -EINVAL : 0;
 802}
 803
 804static int cx25821_s_ctrl(struct v4l2_ctrl *ctrl)
 805{
 806        struct cx25821_channel *chan =
 807                container_of(ctrl->handler, struct cx25821_channel, hdl);
 808        struct cx25821_dev *dev = chan->dev;
 809
 810        switch (ctrl->id) {
 811        case V4L2_CID_BRIGHTNESS:
 812                medusa_set_brightness(dev, ctrl->val, chan->id);
 813                break;
 814        case V4L2_CID_HUE:
 815                medusa_set_hue(dev, ctrl->val, chan->id);
 816                break;
 817        case V4L2_CID_CONTRAST:
 818                medusa_set_contrast(dev, ctrl->val, chan->id);
 819                break;
 820        case V4L2_CID_SATURATION:
 821                medusa_set_saturation(dev, ctrl->val, chan->id);
 822                break;
 823        default:
 824                return -EINVAL;
 825        }
 826        return 0;
 827}
 828
 829static int cx25821_vidioc_enum_output(struct file *file, void *priv,
 830                              struct v4l2_output *o)
 831{
 832        if (o->index)
 833                return -EINVAL;
 834
 835        o->type = V4L2_INPUT_TYPE_CAMERA;
 836        o->std = CX25821_NORMS;
 837        strcpy(o->name, "Composite");
 838        return 0;
 839}
 840
 841static int cx25821_vidioc_g_output(struct file *file, void *priv, unsigned int *o)
 842{
 843        *o = 0;
 844        return 0;
 845}
 846
 847static int cx25821_vidioc_s_output(struct file *file, void *priv, unsigned int o)
 848{
 849        return o ? -EINVAL : 0;
 850}
 851
 852static int cx25821_vidioc_try_fmt_vid_out(struct file *file, void *priv,
 853                                   struct v4l2_format *f)
 854{
 855        struct cx25821_channel *chan = video_drvdata(file);
 856        struct cx25821_dev *dev = chan->dev;
 857        const struct cx25821_fmt *fmt;
 858
 859        fmt = cx25821_format_by_fourcc(f->fmt.pix.pixelformat);
 860        if (NULL == fmt)
 861                return -EINVAL;
 862        f->fmt.pix.width = 720;
 863        f->fmt.pix.height = (dev->tvnorm & V4L2_STD_625_50) ? 576 : 480;
 864        f->fmt.pix.field = V4L2_FIELD_INTERLACED;
 865        f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
 866        f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
 867        f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
 868        return 0;
 869}
 870
 871static int vidioc_s_fmt_vid_out(struct file *file, void *priv,
 872                                struct v4l2_format *f)
 873{
 874        struct cx25821_channel *chan = video_drvdata(file);
 875        int err;
 876
 877        err = cx25821_vidioc_try_fmt_vid_out(file, priv, f);
 878
 879        if (0 != err)
 880                return err;
 881
 882        chan->fmt = cx25821_format_by_fourcc(f->fmt.pix.pixelformat);
 883        chan->vidq.field = f->fmt.pix.field;
 884        chan->width = f->fmt.pix.width;
 885        chan->height = f->fmt.pix.height;
 886        if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
 887                chan->pixel_formats = PIXEL_FRMT_411;
 888        else
 889                chan->pixel_formats = PIXEL_FRMT_422;
 890        return 0;
 891}
 892
 893static ssize_t video_write(struct file *file, const char __user *data, size_t count,
 894                         loff_t *ppos)
 895{
 896        struct cx25821_channel *chan = video_drvdata(file);
 897        struct cx25821_dev *dev = chan->dev;
 898        struct v4l2_fh *fh = file->private_data;
 899        int err = 0;
 900
 901        if (mutex_lock_interruptible(&dev->lock))
 902                return -ERESTARTSYS;
 903        if (chan->streaming_fh && chan->streaming_fh != fh) {
 904                err = -EBUSY;
 905                goto unlock;
 906        }
 907        if (!chan->streaming_fh) {
 908                err = cx25821_vidupstream_init(chan, chan->pixel_formats);
 909                if (err)
 910                        goto unlock;
 911                chan->streaming_fh = fh;
 912        }
 913
 914        err = cx25821_write_frame(chan, data, count);
 915        count -= err;
 916        *ppos += err;
 917
 918unlock:
 919        mutex_unlock(&dev->lock);
 920        return err;
 921}
 922
 923static int video_out_release(struct file *file)
 924{
 925        struct cx25821_channel *chan = video_drvdata(file);
 926        struct cx25821_dev *dev = chan->dev;
 927        struct v4l2_fh *fh = file->private_data;
 928
 929        mutex_lock(&dev->lock);
 930        if (chan->streaming_fh == fh) {
 931                cx25821_stop_upstream_video(chan);
 932                chan->streaming_fh = NULL;
 933        }
 934        mutex_unlock(&dev->lock);
 935
 936        return v4l2_fh_release(file);
 937}
 938
 939static const struct v4l2_ctrl_ops cx25821_ctrl_ops = {
 940        .s_ctrl = cx25821_s_ctrl,
 941};
 942
 943static const struct v4l2_file_operations video_fops = {
 944        .owner = THIS_MODULE,
 945        .open = v4l2_fh_open,
 946        .release = video_release,
 947        .read = video_read,
 948        .poll = video_poll,
 949        .mmap = cx25821_video_mmap,
 950        .unlocked_ioctl = video_ioctl2,
 951};
 952
 953static const struct v4l2_ioctl_ops video_ioctl_ops = {
 954        .vidioc_querycap = cx25821_vidioc_querycap,
 955        .vidioc_enum_fmt_vid_cap = cx25821_vidioc_enum_fmt_vid_cap,
 956        .vidioc_g_fmt_vid_cap = cx25821_vidioc_g_fmt_vid_cap,
 957        .vidioc_try_fmt_vid_cap = cx25821_vidioc_try_fmt_vid_cap,
 958        .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
 959        .vidioc_reqbufs = cx25821_vidioc_reqbufs,
 960        .vidioc_querybuf = cx25821_vidioc_querybuf,
 961        .vidioc_qbuf = cx25821_vidioc_qbuf,
 962        .vidioc_dqbuf = vidioc_dqbuf,
 963        .vidioc_g_std = cx25821_vidioc_g_std,
 964        .vidioc_s_std = cx25821_vidioc_s_std,
 965        .vidioc_enum_input = cx25821_vidioc_enum_input,
 966        .vidioc_g_input = cx25821_vidioc_g_input,
 967        .vidioc_s_input = cx25821_vidioc_s_input,
 968        .vidioc_streamon = vidioc_streamon,
 969        .vidioc_streamoff = vidioc_streamoff,
 970        .vidioc_log_status = vidioc_log_status,
 971        .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
 972        .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
 973};
 974
 975static const struct video_device cx25821_video_device = {
 976        .name = "cx25821-video",
 977        .fops = &video_fops,
 978        .release = video_device_release_empty,
 979        .minor = -1,
 980        .ioctl_ops = &video_ioctl_ops,
 981        .tvnorms = CX25821_NORMS,
 982};
 983
 984static const struct v4l2_file_operations video_out_fops = {
 985        .owner = THIS_MODULE,
 986        .open = v4l2_fh_open,
 987        .write = video_write,
 988        .release = video_out_release,
 989        .unlocked_ioctl = video_ioctl2,
 990};
 991
 992static const struct v4l2_ioctl_ops video_out_ioctl_ops = {
 993        .vidioc_querycap = cx25821_vidioc_querycap,
 994        .vidioc_enum_fmt_vid_out = cx25821_vidioc_enum_fmt_vid_cap,
 995        .vidioc_g_fmt_vid_out = cx25821_vidioc_g_fmt_vid_cap,
 996        .vidioc_try_fmt_vid_out = cx25821_vidioc_try_fmt_vid_out,
 997        .vidioc_s_fmt_vid_out = vidioc_s_fmt_vid_out,
 998        .vidioc_g_std = cx25821_vidioc_g_std,
 999        .vidioc_s_std = cx25821_vidioc_s_std,
1000        .vidioc_enum_output = cx25821_vidioc_enum_output,
1001        .vidioc_g_output = cx25821_vidioc_g_output,
1002        .vidioc_s_output = cx25821_vidioc_s_output,
1003        .vidioc_log_status = vidioc_log_status,
1004};
1005
1006static const struct video_device cx25821_video_out_device = {
1007        .name = "cx25821-video",
1008        .fops = &video_out_fops,
1009        .release = video_device_release_empty,
1010        .minor = -1,
1011        .ioctl_ops = &video_out_ioctl_ops,
1012        .tvnorms = CX25821_NORMS,
1013};
1014
1015void cx25821_video_unregister(struct cx25821_dev *dev, int chan_num)
1016{
1017        cx_clear(PCI_INT_MSK, 1);
1018
1019        if (video_is_registered(&dev->channels[chan_num].vdev)) {
1020                video_unregister_device(&dev->channels[chan_num].vdev);
1021                v4l2_ctrl_handler_free(&dev->channels[chan_num].hdl);
1022
1023                btcx_riscmem_free(dev->pci,
1024                                &dev->channels[chan_num].dma_vidq.stopper);
1025        }
1026}
1027
1028int cx25821_video_register(struct cx25821_dev *dev)
1029{
1030        int err;
1031        int i;
1032
1033        /* initial device configuration */
1034        dev->tvnorm = V4L2_STD_NTSC_M;
1035
1036        spin_lock_init(&dev->slock);
1037
1038        for (i = 0; i < MAX_VID_CHANNEL_NUM - 1; ++i) {
1039                struct cx25821_channel *chan = &dev->channels[i];
1040                struct video_device *vdev = &chan->vdev;
1041                struct v4l2_ctrl_handler *hdl = &chan->hdl;
1042                bool is_output = i > SRAM_CH08;
1043
1044                if (i == SRAM_CH08) /* audio channel */
1045                        continue;
1046
1047                if (!is_output) {
1048                        v4l2_ctrl_handler_init(hdl, 4);
1049                        v4l2_ctrl_new_std(hdl, &cx25821_ctrl_ops,
1050                                        V4L2_CID_BRIGHTNESS, 0, 10000, 1, 6200);
1051                        v4l2_ctrl_new_std(hdl, &cx25821_ctrl_ops,
1052                                        V4L2_CID_CONTRAST, 0, 10000, 1, 5000);
1053                        v4l2_ctrl_new_std(hdl, &cx25821_ctrl_ops,
1054                                        V4L2_CID_SATURATION, 0, 10000, 1, 5000);
1055                        v4l2_ctrl_new_std(hdl, &cx25821_ctrl_ops,
1056                                        V4L2_CID_HUE, 0, 10000, 1, 5000);
1057                        if (hdl->error) {
1058                                err = hdl->error;
1059                                goto fail_unreg;
1060                        }
1061                        err = v4l2_ctrl_handler_setup(hdl);
1062                        if (err)
1063                                goto fail_unreg;
1064                } else {
1065                        chan->out = &dev->vid_out_data[i - SRAM_CH09];
1066                        chan->out->chan = chan;
1067                }
1068
1069                cx25821_risc_stopper(dev->pci, &chan->dma_vidq.stopper,
1070                        chan->sram_channels->dma_ctl, 0x11, 0);
1071
1072                chan->sram_channels = &cx25821_sram_channels[i];
1073                chan->width = 720;
1074                if (dev->tvnorm & V4L2_STD_625_50)
1075                        chan->height = 576;
1076                else
1077                        chan->height = 480;
1078
1079                if (chan->pixel_formats == PIXEL_FRMT_411)
1080                        chan->fmt = cx25821_format_by_fourcc(V4L2_PIX_FMT_Y41P);
1081                else
1082                        chan->fmt = cx25821_format_by_fourcc(V4L2_PIX_FMT_YUYV);
1083
1084                cx_write(chan->sram_channels->int_stat, 0xffffffff);
1085
1086                INIT_LIST_HEAD(&chan->dma_vidq.active);
1087                INIT_LIST_HEAD(&chan->dma_vidq.queued);
1088
1089                chan->timeout_data.dev = dev;
1090                chan->timeout_data.channel = &cx25821_sram_channels[i];
1091                chan->dma_vidq.timeout.function = cx25821_vid_timeout;
1092                chan->dma_vidq.timeout.data = (unsigned long)&chan->timeout_data;
1093                init_timer(&chan->dma_vidq.timeout);
1094
1095                if (!is_output)
1096                        videobuf_queue_sg_init(&chan->vidq, &cx25821_video_qops, &dev->pci->dev,
1097                                &dev->slock, V4L2_BUF_TYPE_VIDEO_CAPTURE,
1098                                V4L2_FIELD_INTERLACED, sizeof(struct cx25821_buffer),
1099                                chan, &dev->lock);
1100
1101                /* register v4l devices */
1102                *vdev = is_output ? cx25821_video_out_device : cx25821_video_device;
1103                vdev->v4l2_dev = &dev->v4l2_dev;
1104                if (!is_output)
1105                        vdev->ctrl_handler = hdl;
1106                else
1107                        vdev->vfl_dir = VFL_DIR_TX;
1108                vdev->lock = &dev->lock;
1109                snprintf(vdev->name, sizeof(vdev->name), "%s #%d", dev->name, i);
1110                video_set_drvdata(vdev, chan);
1111
1112                err = video_register_device(vdev, VFL_TYPE_GRABBER,
1113                                            video_nr[dev->nr]);
1114
1115                if (err < 0)
1116                        goto fail_unreg;
1117        }
1118
1119        /* set PCI interrupt */
1120        cx_set(PCI_INT_MSK, 0xff);
1121
1122        return 0;
1123
1124fail_unreg:
1125        while (i >= 0)
1126                cx25821_video_unregister(dev, i--);
1127        return err;
1128}
1129