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        f->fmt.pix.priv = 0;
 580
 581        return 0;
 582}
 583
 584static int cx25821_vidioc_try_fmt_vid_cap(struct file *file, void *priv,
 585                                   struct v4l2_format *f)
 586{
 587        struct cx25821_channel *chan = video_drvdata(file);
 588        struct cx25821_dev *dev = chan->dev;
 589        const struct cx25821_fmt *fmt;
 590        enum v4l2_field field = f->fmt.pix.field;
 591        unsigned int maxh;
 592        unsigned w;
 593
 594        fmt = cx25821_format_by_fourcc(f->fmt.pix.pixelformat);
 595        if (NULL == fmt)
 596                return -EINVAL;
 597        maxh = (dev->tvnorm & V4L2_STD_625_50) ? 576 : 480;
 598
 599        w = f->fmt.pix.width;
 600        if (field != V4L2_FIELD_BOTTOM)
 601                field = V4L2_FIELD_TOP;
 602        if (w < 352) {
 603                w = 176;
 604                f->fmt.pix.height = maxh / 4;
 605        } else if (w < 720) {
 606                w = 352;
 607                f->fmt.pix.height = maxh / 2;
 608        } else {
 609                w = 720;
 610                f->fmt.pix.height = maxh;
 611                field = V4L2_FIELD_INTERLACED;
 612        }
 613        f->fmt.pix.field = field;
 614        f->fmt.pix.width = w;
 615        f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
 616        f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
 617        f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
 618        f->fmt.pix.priv = 0;
 619
 620        return 0;
 621}
 622
 623static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
 624                                struct v4l2_format *f)
 625{
 626        struct cx25821_channel *chan = video_drvdata(file);
 627        struct cx25821_dev *dev = chan->dev;
 628        int pix_format = PIXEL_FRMT_422;
 629        int err;
 630
 631        err = cx25821_vidioc_try_fmt_vid_cap(file, priv, f);
 632
 633        if (0 != err)
 634                return err;
 635
 636        chan->fmt = cx25821_format_by_fourcc(f->fmt.pix.pixelformat);
 637        chan->vidq.field = f->fmt.pix.field;
 638        chan->width = f->fmt.pix.width;
 639        chan->height = f->fmt.pix.height;
 640
 641        if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
 642                pix_format = PIXEL_FRMT_411;
 643        else
 644                pix_format = PIXEL_FRMT_422;
 645
 646        cx25821_set_pixel_format(dev, SRAM_CH00, pix_format);
 647
 648        /* check if cif resolution */
 649        if (chan->width == 320 || chan->width == 352)
 650                chan->use_cif_resolution = 1;
 651        else
 652                chan->use_cif_resolution = 0;
 653
 654        chan->cif_width = chan->width;
 655        medusa_set_resolution(dev, chan->width, SRAM_CH00);
 656        return 0;
 657}
 658
 659static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
 660{
 661        struct cx25821_channel *chan = video_drvdata(file);
 662
 663        if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 664                return -EINVAL;
 665
 666        if (chan->streaming_fh && chan->streaming_fh != priv)
 667                return -EBUSY;
 668        chan->streaming_fh = priv;
 669
 670        return videobuf_streamon(&chan->vidq);
 671}
 672
 673static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
 674{
 675        struct cx25821_channel *chan = video_drvdata(file);
 676
 677        if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 678                return -EINVAL;
 679
 680        if (chan->streaming_fh && chan->streaming_fh != priv)
 681                return -EBUSY;
 682        if (chan->streaming_fh == NULL)
 683                return 0;
 684
 685        chan->streaming_fh = NULL;
 686        return videobuf_streamoff(&chan->vidq);
 687}
 688
 689static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
 690{
 691        int ret_val = 0;
 692        struct cx25821_channel *chan = video_drvdata(file);
 693
 694        ret_val = videobuf_dqbuf(&chan->vidq, p, file->f_flags & O_NONBLOCK);
 695        p->sequence = chan->dma_vidq.count;
 696
 697        return ret_val;
 698}
 699
 700static int vidioc_log_status(struct file *file, void *priv)
 701{
 702        struct cx25821_channel *chan = video_drvdata(file);
 703        struct cx25821_dev *dev = chan->dev;
 704        const struct sram_channel *sram_ch = chan->sram_channels;
 705        u32 tmp = 0;
 706
 707        tmp = cx_read(sram_ch->dma_ctl);
 708        pr_info("Video input 0 is %s\n",
 709                (tmp & 0x11) ? "streaming" : "stopped");
 710        return 0;
 711}
 712
 713
 714static int cx25821_vidioc_querycap(struct file *file, void *priv,
 715                            struct v4l2_capability *cap)
 716{
 717        struct cx25821_channel *chan = video_drvdata(file);
 718        struct cx25821_dev *dev = chan->dev;
 719        const u32 cap_input = V4L2_CAP_VIDEO_CAPTURE |
 720                        V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
 721        const u32 cap_output = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_READWRITE;
 722
 723        strcpy(cap->driver, "cx25821");
 724        strlcpy(cap->card, cx25821_boards[dev->board].name, sizeof(cap->card));
 725        sprintf(cap->bus_info, "PCIe:%s", pci_name(dev->pci));
 726        if (chan->id >= VID_CHANNEL_NUM)
 727                cap->device_caps = cap_output;
 728        else
 729                cap->device_caps = cap_input;
 730        cap->capabilities = cap_input | cap_output | V4L2_CAP_DEVICE_CAPS;
 731        return 0;
 732}
 733
 734static int cx25821_vidioc_reqbufs(struct file *file, void *priv,
 735                           struct v4l2_requestbuffers *p)
 736{
 737        struct cx25821_channel *chan = video_drvdata(file);
 738
 739        return videobuf_reqbufs(&chan->vidq, p);
 740}
 741
 742static int cx25821_vidioc_querybuf(struct file *file, void *priv,
 743                            struct v4l2_buffer *p)
 744{
 745        struct cx25821_channel *chan = video_drvdata(file);
 746
 747        return videobuf_querybuf(&chan->vidq, p);
 748}
 749
 750static int cx25821_vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
 751{
 752        struct cx25821_channel *chan = video_drvdata(file);
 753
 754        return videobuf_qbuf(&chan->vidq, p);
 755}
 756
 757static int cx25821_vidioc_g_std(struct file *file, void *priv, v4l2_std_id *tvnorms)
 758{
 759        struct cx25821_channel *chan = video_drvdata(file);
 760
 761        *tvnorms = chan->dev->tvnorm;
 762        return 0;
 763}
 764
 765static int cx25821_vidioc_s_std(struct file *file, void *priv,
 766                                v4l2_std_id tvnorms)
 767{
 768        struct cx25821_channel *chan = video_drvdata(file);
 769        struct cx25821_dev *dev = chan->dev;
 770
 771        if (dev->tvnorm == tvnorms)
 772                return 0;
 773
 774        dev->tvnorm = tvnorms;
 775        chan->width = 720;
 776        chan->height = (dev->tvnorm & V4L2_STD_625_50) ? 576 : 480;
 777
 778        medusa_set_videostandard(dev);
 779
 780        return 0;
 781}
 782
 783static int cx25821_vidioc_enum_input(struct file *file, void *priv,
 784                              struct v4l2_input *i)
 785{
 786        if (i->index)
 787                return -EINVAL;
 788
 789        i->type = V4L2_INPUT_TYPE_CAMERA;
 790        i->std = CX25821_NORMS;
 791        strcpy(i->name, "Composite");
 792        return 0;
 793}
 794
 795static int cx25821_vidioc_g_input(struct file *file, void *priv, unsigned int *i)
 796{
 797        *i = 0;
 798        return 0;
 799}
 800
 801static int cx25821_vidioc_s_input(struct file *file, void *priv, unsigned int i)
 802{
 803        return i ? -EINVAL : 0;
 804}
 805
 806static int cx25821_s_ctrl(struct v4l2_ctrl *ctrl)
 807{
 808        struct cx25821_channel *chan =
 809                container_of(ctrl->handler, struct cx25821_channel, hdl);
 810        struct cx25821_dev *dev = chan->dev;
 811
 812        switch (ctrl->id) {
 813        case V4L2_CID_BRIGHTNESS:
 814                medusa_set_brightness(dev, ctrl->val, chan->id);
 815                break;
 816        case V4L2_CID_HUE:
 817                medusa_set_hue(dev, ctrl->val, chan->id);
 818                break;
 819        case V4L2_CID_CONTRAST:
 820                medusa_set_contrast(dev, ctrl->val, chan->id);
 821                break;
 822        case V4L2_CID_SATURATION:
 823                medusa_set_saturation(dev, ctrl->val, chan->id);
 824                break;
 825        default:
 826                return -EINVAL;
 827        }
 828        return 0;
 829}
 830
 831static int cx25821_vidioc_enum_output(struct file *file, void *priv,
 832                              struct v4l2_output *o)
 833{
 834        if (o->index)
 835                return -EINVAL;
 836
 837        o->type = V4L2_INPUT_TYPE_CAMERA;
 838        o->std = CX25821_NORMS;
 839        strcpy(o->name, "Composite");
 840        return 0;
 841}
 842
 843static int cx25821_vidioc_g_output(struct file *file, void *priv, unsigned int *o)
 844{
 845        *o = 0;
 846        return 0;
 847}
 848
 849static int cx25821_vidioc_s_output(struct file *file, void *priv, unsigned int o)
 850{
 851        return o ? -EINVAL : 0;
 852}
 853
 854static int cx25821_vidioc_try_fmt_vid_out(struct file *file, void *priv,
 855                                   struct v4l2_format *f)
 856{
 857        struct cx25821_channel *chan = video_drvdata(file);
 858        struct cx25821_dev *dev = chan->dev;
 859        const struct cx25821_fmt *fmt;
 860
 861        fmt = cx25821_format_by_fourcc(f->fmt.pix.pixelformat);
 862        if (NULL == fmt)
 863                return -EINVAL;
 864        f->fmt.pix.width = 720;
 865        f->fmt.pix.height = (dev->tvnorm & V4L2_STD_625_50) ? 576 : 480;
 866        f->fmt.pix.field = V4L2_FIELD_INTERLACED;
 867        f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
 868        f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
 869        f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
 870        f->fmt.pix.priv = 0;
 871        return 0;
 872}
 873
 874static int vidioc_s_fmt_vid_out(struct file *file, void *priv,
 875                                struct v4l2_format *f)
 876{
 877        struct cx25821_channel *chan = video_drvdata(file);
 878        int err;
 879
 880        err = cx25821_vidioc_try_fmt_vid_out(file, priv, f);
 881
 882        if (0 != err)
 883                return err;
 884
 885        chan->fmt = cx25821_format_by_fourcc(f->fmt.pix.pixelformat);
 886        chan->vidq.field = f->fmt.pix.field;
 887        chan->width = f->fmt.pix.width;
 888        chan->height = f->fmt.pix.height;
 889        if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
 890                chan->pixel_formats = PIXEL_FRMT_411;
 891        else
 892                chan->pixel_formats = PIXEL_FRMT_422;
 893        return 0;
 894}
 895
 896static ssize_t video_write(struct file *file, const char __user *data, size_t count,
 897                         loff_t *ppos)
 898{
 899        struct cx25821_channel *chan = video_drvdata(file);
 900        struct cx25821_dev *dev = chan->dev;
 901        struct v4l2_fh *fh = file->private_data;
 902        int err = 0;
 903
 904        if (mutex_lock_interruptible(&dev->lock))
 905                return -ERESTARTSYS;
 906        if (chan->streaming_fh && chan->streaming_fh != fh) {
 907                err = -EBUSY;
 908                goto unlock;
 909        }
 910        if (!chan->streaming_fh) {
 911                err = cx25821_vidupstream_init(chan, chan->pixel_formats);
 912                if (err)
 913                        goto unlock;
 914                chan->streaming_fh = fh;
 915        }
 916
 917        err = cx25821_write_frame(chan, data, count);
 918        count -= err;
 919        *ppos += err;
 920
 921unlock:
 922        mutex_unlock(&dev->lock);
 923        return err;
 924}
 925
 926static int video_out_release(struct file *file)
 927{
 928        struct cx25821_channel *chan = video_drvdata(file);
 929        struct cx25821_dev *dev = chan->dev;
 930        struct v4l2_fh *fh = file->private_data;
 931
 932        mutex_lock(&dev->lock);
 933        if (chan->streaming_fh == fh) {
 934                cx25821_stop_upstream_video(chan);
 935                chan->streaming_fh = NULL;
 936        }
 937        mutex_unlock(&dev->lock);
 938
 939        return v4l2_fh_release(file);
 940}
 941
 942static const struct v4l2_ctrl_ops cx25821_ctrl_ops = {
 943        .s_ctrl = cx25821_s_ctrl,
 944};
 945
 946static const struct v4l2_file_operations video_fops = {
 947        .owner = THIS_MODULE,
 948        .open = v4l2_fh_open,
 949        .release = video_release,
 950        .read = video_read,
 951        .poll = video_poll,
 952        .mmap = cx25821_video_mmap,
 953        .unlocked_ioctl = video_ioctl2,
 954};
 955
 956static const struct v4l2_ioctl_ops video_ioctl_ops = {
 957        .vidioc_querycap = cx25821_vidioc_querycap,
 958        .vidioc_enum_fmt_vid_cap = cx25821_vidioc_enum_fmt_vid_cap,
 959        .vidioc_g_fmt_vid_cap = cx25821_vidioc_g_fmt_vid_cap,
 960        .vidioc_try_fmt_vid_cap = cx25821_vidioc_try_fmt_vid_cap,
 961        .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
 962        .vidioc_reqbufs = cx25821_vidioc_reqbufs,
 963        .vidioc_querybuf = cx25821_vidioc_querybuf,
 964        .vidioc_qbuf = cx25821_vidioc_qbuf,
 965        .vidioc_dqbuf = vidioc_dqbuf,
 966        .vidioc_g_std = cx25821_vidioc_g_std,
 967        .vidioc_s_std = cx25821_vidioc_s_std,
 968        .vidioc_enum_input = cx25821_vidioc_enum_input,
 969        .vidioc_g_input = cx25821_vidioc_g_input,
 970        .vidioc_s_input = cx25821_vidioc_s_input,
 971        .vidioc_streamon = vidioc_streamon,
 972        .vidioc_streamoff = vidioc_streamoff,
 973        .vidioc_log_status = vidioc_log_status,
 974        .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
 975        .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
 976};
 977
 978static const struct video_device cx25821_video_device = {
 979        .name = "cx25821-video",
 980        .fops = &video_fops,
 981        .release = video_device_release_empty,
 982        .minor = -1,
 983        .ioctl_ops = &video_ioctl_ops,
 984        .tvnorms = CX25821_NORMS,
 985};
 986
 987static const struct v4l2_file_operations video_out_fops = {
 988        .owner = THIS_MODULE,
 989        .open = v4l2_fh_open,
 990        .write = video_write,
 991        .release = video_out_release,
 992        .unlocked_ioctl = video_ioctl2,
 993};
 994
 995static const struct v4l2_ioctl_ops video_out_ioctl_ops = {
 996        .vidioc_querycap = cx25821_vidioc_querycap,
 997        .vidioc_enum_fmt_vid_out = cx25821_vidioc_enum_fmt_vid_cap,
 998        .vidioc_g_fmt_vid_out = cx25821_vidioc_g_fmt_vid_cap,
 999        .vidioc_try_fmt_vid_out = cx25821_vidioc_try_fmt_vid_out,
1000        .vidioc_s_fmt_vid_out = vidioc_s_fmt_vid_out,
1001        .vidioc_g_std = cx25821_vidioc_g_std,
1002        .vidioc_s_std = cx25821_vidioc_s_std,
1003        .vidioc_enum_output = cx25821_vidioc_enum_output,
1004        .vidioc_g_output = cx25821_vidioc_g_output,
1005        .vidioc_s_output = cx25821_vidioc_s_output,
1006        .vidioc_log_status = vidioc_log_status,
1007};
1008
1009static const struct video_device cx25821_video_out_device = {
1010        .name = "cx25821-video",
1011        .fops = &video_out_fops,
1012        .release = video_device_release_empty,
1013        .minor = -1,
1014        .ioctl_ops = &video_out_ioctl_ops,
1015        .tvnorms = CX25821_NORMS,
1016};
1017
1018void cx25821_video_unregister(struct cx25821_dev *dev, int chan_num)
1019{
1020        cx_clear(PCI_INT_MSK, 1);
1021
1022        if (video_is_registered(&dev->channels[chan_num].vdev)) {
1023                video_unregister_device(&dev->channels[chan_num].vdev);
1024                v4l2_ctrl_handler_free(&dev->channels[chan_num].hdl);
1025
1026                btcx_riscmem_free(dev->pci,
1027                                &dev->channels[chan_num].dma_vidq.stopper);
1028        }
1029}
1030
1031int cx25821_video_register(struct cx25821_dev *dev)
1032{
1033        int err;
1034        int i;
1035
1036        /* initial device configuration */
1037        dev->tvnorm = V4L2_STD_NTSC_M;
1038
1039        spin_lock_init(&dev->slock);
1040
1041        for (i = 0; i < MAX_VID_CHANNEL_NUM - 1; ++i) {
1042                struct cx25821_channel *chan = &dev->channels[i];
1043                struct video_device *vdev = &chan->vdev;
1044                struct v4l2_ctrl_handler *hdl = &chan->hdl;
1045                bool is_output = i > SRAM_CH08;
1046
1047                if (i == SRAM_CH08) /* audio channel */
1048                        continue;
1049
1050                if (!is_output) {
1051                        v4l2_ctrl_handler_init(hdl, 4);
1052                        v4l2_ctrl_new_std(hdl, &cx25821_ctrl_ops,
1053                                        V4L2_CID_BRIGHTNESS, 0, 10000, 1, 6200);
1054                        v4l2_ctrl_new_std(hdl, &cx25821_ctrl_ops,
1055                                        V4L2_CID_CONTRAST, 0, 10000, 1, 5000);
1056                        v4l2_ctrl_new_std(hdl, &cx25821_ctrl_ops,
1057                                        V4L2_CID_SATURATION, 0, 10000, 1, 5000);
1058                        v4l2_ctrl_new_std(hdl, &cx25821_ctrl_ops,
1059                                        V4L2_CID_HUE, 0, 10000, 1, 5000);
1060                        if (hdl->error) {
1061                                err = hdl->error;
1062                                goto fail_unreg;
1063                        }
1064                        err = v4l2_ctrl_handler_setup(hdl);
1065                        if (err)
1066                                goto fail_unreg;
1067                } else {
1068                        chan->out = &dev->vid_out_data[i - SRAM_CH09];
1069                        chan->out->chan = chan;
1070                }
1071
1072                cx25821_risc_stopper(dev->pci, &chan->dma_vidq.stopper,
1073                        chan->sram_channels->dma_ctl, 0x11, 0);
1074
1075                chan->sram_channels = &cx25821_sram_channels[i];
1076                chan->width = 720;
1077                if (dev->tvnorm & V4L2_STD_625_50)
1078                        chan->height = 576;
1079                else
1080                        chan->height = 480;
1081
1082                if (chan->pixel_formats == PIXEL_FRMT_411)
1083                        chan->fmt = cx25821_format_by_fourcc(V4L2_PIX_FMT_Y41P);
1084                else
1085                        chan->fmt = cx25821_format_by_fourcc(V4L2_PIX_FMT_YUYV);
1086
1087                cx_write(chan->sram_channels->int_stat, 0xffffffff);
1088
1089                INIT_LIST_HEAD(&chan->dma_vidq.active);
1090                INIT_LIST_HEAD(&chan->dma_vidq.queued);
1091
1092                chan->timeout_data.dev = dev;
1093                chan->timeout_data.channel = &cx25821_sram_channels[i];
1094                chan->dma_vidq.timeout.function = cx25821_vid_timeout;
1095                chan->dma_vidq.timeout.data = (unsigned long)&chan->timeout_data;
1096                init_timer(&chan->dma_vidq.timeout);
1097
1098                if (!is_output)
1099                        videobuf_queue_sg_init(&chan->vidq, &cx25821_video_qops, &dev->pci->dev,
1100                                &dev->slock, V4L2_BUF_TYPE_VIDEO_CAPTURE,
1101                                V4L2_FIELD_INTERLACED, sizeof(struct cx25821_buffer),
1102                                chan, &dev->lock);
1103
1104                /* register v4l devices */
1105                *vdev = is_output ? cx25821_video_out_device : cx25821_video_device;
1106                vdev->v4l2_dev = &dev->v4l2_dev;
1107                if (!is_output)
1108                        vdev->ctrl_handler = hdl;
1109                else
1110                        vdev->vfl_dir = VFL_DIR_TX;
1111                vdev->lock = &dev->lock;
1112                set_bit(V4L2_FL_USE_FH_PRIO, &vdev->flags);
1113                snprintf(vdev->name, sizeof(vdev->name), "%s #%d", dev->name, i);
1114                video_set_drvdata(vdev, chan);
1115
1116                err = video_register_device(vdev, VFL_TYPE_GRABBER,
1117                                            video_nr[dev->nr]);
1118
1119                if (err < 0)
1120                        goto fail_unreg;
1121        }
1122
1123        /* set PCI interrupt */
1124        cx_set(PCI_INT_MSK, 0xff);
1125
1126        return 0;
1127
1128fail_unreg:
1129        while (i >= 0)
1130                cx25821_video_unregister(dev, i--);
1131        return err;
1132}
1133