linux/drivers/media/pci/tw68/tw68-video.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 *  tw68 functions to handle video data
   4 *
   5 *  Much of this code is derived from the cx88 and sa7134 drivers, which
   6 *  were in turn derived from the bt87x driver.  The original work was by
   7 *  Gerd Knorr; more recently the code was enhanced by Mauro Carvalho Chehab,
   8 *  Hans Verkuil, Andy Walls and many others.  Their work is gratefully
   9 *  acknowledged.  Full credit goes to them - any problems within this code
  10 *  are mine.
  11 *
  12 *  Copyright (C) 2009  William M. Brack
  13 *
  14 *  Refactored and updated to the latest v4l core frameworks:
  15 *
  16 *  Copyright (C) 2014 Hans Verkuil <hverkuil@xs4all.nl>
  17 */
  18
  19#include <linux/module.h>
  20#include <media/v4l2-common.h>
  21#include <media/v4l2-event.h>
  22#include <media/videobuf2-dma-sg.h>
  23
  24#include "tw68.h"
  25#include "tw68-reg.h"
  26
  27/* ------------------------------------------------------------------ */
  28/* data structs for video                                             */
  29/*
  30 * FIXME -
  31 * Note that the saa7134 has formats, e.g. YUV420, which are classified
  32 * as "planar".  These affect overlay mode, and are flagged with a field
  33 * ".planar" in the format.  Do we need to implement this in this driver?
  34 */
  35static const struct tw68_format formats[] = {
  36        {
  37                .fourcc         = V4L2_PIX_FMT_RGB555,
  38                .depth          = 16,
  39                .twformat       = ColorFormatRGB15,
  40        }, {
  41                .fourcc         = V4L2_PIX_FMT_RGB555X,
  42                .depth          = 16,
  43                .twformat       = ColorFormatRGB15 | ColorFormatBSWAP,
  44        }, {
  45                .fourcc         = V4L2_PIX_FMT_RGB565,
  46                .depth          = 16,
  47                .twformat       = ColorFormatRGB16,
  48        }, {
  49                .fourcc         = V4L2_PIX_FMT_RGB565X,
  50                .depth          = 16,
  51                .twformat       = ColorFormatRGB16 | ColorFormatBSWAP,
  52        }, {
  53                .fourcc         = V4L2_PIX_FMT_BGR24,
  54                .depth          = 24,
  55                .twformat       = ColorFormatRGB24,
  56        }, {
  57                .fourcc         = V4L2_PIX_FMT_RGB24,
  58                .depth          = 24,
  59                .twformat       = ColorFormatRGB24 | ColorFormatBSWAP,
  60        }, {
  61                .fourcc         = V4L2_PIX_FMT_BGR32,
  62                .depth          = 32,
  63                .twformat       = ColorFormatRGB32,
  64        }, {
  65                .fourcc         = V4L2_PIX_FMT_RGB32,
  66                .depth          = 32,
  67                .twformat       = ColorFormatRGB32 | ColorFormatBSWAP |
  68                                  ColorFormatWSWAP,
  69        }, {
  70                .fourcc         = V4L2_PIX_FMT_YUYV,
  71                .depth          = 16,
  72                .twformat       = ColorFormatYUY2,
  73        }, {
  74                .fourcc         = V4L2_PIX_FMT_UYVY,
  75                .depth          = 16,
  76                .twformat       = ColorFormatYUY2 | ColorFormatBSWAP,
  77        }
  78};
  79#define FORMATS ARRAY_SIZE(formats)
  80
  81#define NORM_625_50                     \
  82                .h_delay        = 3,    \
  83                .h_delay0       = 133,  \
  84                .h_start        = 0,    \
  85                .h_stop         = 719,  \
  86                .v_delay        = 24,   \
  87                .vbi_v_start_0  = 7,    \
  88                .vbi_v_stop_0   = 22,   \
  89                .video_v_start  = 24,   \
  90                .video_v_stop   = 311,  \
  91                .vbi_v_start_1  = 319
  92
  93#define NORM_525_60                     \
  94                .h_delay        = 8,    \
  95                .h_delay0       = 138,  \
  96                .h_start        = 0,    \
  97                .h_stop         = 719,  \
  98                .v_delay        = 22,   \
  99                .vbi_v_start_0  = 10,   \
 100                .vbi_v_stop_0   = 21,   \
 101                .video_v_start  = 22,   \
 102                .video_v_stop   = 262,  \
 103                .vbi_v_start_1  = 273
 104
 105/*
 106 * The following table is searched by tw68_s_std, first for a specific
 107 * match, then for an entry which contains the desired id.  The table
 108 * entries should therefore be ordered in ascending order of specificity.
 109 */
 110static const struct tw68_tvnorm tvnorms[] = {
 111        {
 112                .name           = "PAL", /* autodetect */
 113                .id             = V4L2_STD_PAL,
 114                NORM_625_50,
 115
 116                .sync_control   = 0x18,
 117                .luma_control   = 0x40,
 118                .chroma_ctrl1   = 0x81,
 119                .chroma_gain    = 0x2a,
 120                .chroma_ctrl2   = 0x06,
 121                .vgate_misc     = 0x1c,
 122                .format         = VideoFormatPALBDGHI,
 123        }, {
 124                .name           = "NTSC",
 125                .id             = V4L2_STD_NTSC,
 126                NORM_525_60,
 127
 128                .sync_control   = 0x59,
 129                .luma_control   = 0x40,
 130                .chroma_ctrl1   = 0x89,
 131                .chroma_gain    = 0x2a,
 132                .chroma_ctrl2   = 0x0e,
 133                .vgate_misc     = 0x18,
 134                .format         = VideoFormatNTSC,
 135        }, {
 136                .name           = "SECAM",
 137                .id             = V4L2_STD_SECAM,
 138                NORM_625_50,
 139
 140                .sync_control   = 0x18,
 141                .luma_control   = 0x1b,
 142                .chroma_ctrl1   = 0xd1,
 143                .chroma_gain    = 0x80,
 144                .chroma_ctrl2   = 0x00,
 145                .vgate_misc     = 0x1c,
 146                .format         = VideoFormatSECAM,
 147        }, {
 148                .name           = "PAL-M",
 149                .id             = V4L2_STD_PAL_M,
 150                NORM_525_60,
 151
 152                .sync_control   = 0x59,
 153                .luma_control   = 0x40,
 154                .chroma_ctrl1   = 0xb9,
 155                .chroma_gain    = 0x2a,
 156                .chroma_ctrl2   = 0x0e,
 157                .vgate_misc     = 0x18,
 158                .format         = VideoFormatPALM,
 159        }, {
 160                .name           = "PAL-Nc",
 161                .id             = V4L2_STD_PAL_Nc,
 162                NORM_625_50,
 163
 164                .sync_control   = 0x18,
 165                .luma_control   = 0x40,
 166                .chroma_ctrl1   = 0xa1,
 167                .chroma_gain    = 0x2a,
 168                .chroma_ctrl2   = 0x06,
 169                .vgate_misc     = 0x1c,
 170                .format         = VideoFormatPALNC,
 171        }, {
 172                .name           = "PAL-60",
 173                .id             = V4L2_STD_PAL_60,
 174                .h_delay        = 186,
 175                .h_start        = 0,
 176                .h_stop         = 719,
 177                .v_delay        = 26,
 178                .video_v_start  = 23,
 179                .video_v_stop   = 262,
 180                .vbi_v_start_0  = 10,
 181                .vbi_v_stop_0   = 21,
 182                .vbi_v_start_1  = 273,
 183
 184                .sync_control   = 0x18,
 185                .luma_control   = 0x40,
 186                .chroma_ctrl1   = 0x81,
 187                .chroma_gain    = 0x2a,
 188                .chroma_ctrl2   = 0x06,
 189                .vgate_misc     = 0x1c,
 190                .format         = VideoFormatPAL60,
 191        }
 192};
 193#define TVNORMS ARRAY_SIZE(tvnorms)
 194
 195static const struct tw68_format *format_by_fourcc(unsigned int fourcc)
 196{
 197        unsigned int i;
 198
 199        for (i = 0; i < FORMATS; i++)
 200                if (formats[i].fourcc == fourcc)
 201                        return formats+i;
 202        return NULL;
 203}
 204
 205
 206/* ------------------------------------------------------------------ */
 207/*
 208 * Note that the cropping rectangles are described in terms of a single
 209 * frame, i.e. line positions are only 1/2 the interlaced equivalent
 210 */
 211static void set_tvnorm(struct tw68_dev *dev, const struct tw68_tvnorm *norm)
 212{
 213        if (norm != dev->tvnorm) {
 214                dev->width = 720;
 215                dev->height = (norm->id & V4L2_STD_525_60) ? 480 : 576;
 216                dev->tvnorm = norm;
 217                tw68_set_tvnorm_hw(dev);
 218        }
 219}
 220
 221/*
 222 * tw68_set_scale
 223 *
 224 * Scaling and Cropping for video decoding
 225 *
 226 * We are working with 3 values for horizontal and vertical - scale,
 227 * delay and active.
 228 *
 229 * HACTIVE represent the actual number of pixels in the "usable" image,
 230 * before scaling.  HDELAY represents the number of pixels skipped
 231 * between the start of the horizontal sync and the start of the image.
 232 * HSCALE is calculated using the formula
 233 *      HSCALE = (HACTIVE / (#pixels desired)) * 256
 234 *
 235 * The vertical registers are similar, except based upon the total number
 236 * of lines in the image, and the first line of the image (i.e. ignoring
 237 * vertical sync and VBI).
 238 *
 239 * Note that the number of bytes reaching the FIFO (and hence needing
 240 * to be processed by the DMAP program) is completely dependent upon
 241 * these values, especially HSCALE.
 242 *
 243 * Parameters:
 244 *      @dev            pointer to the device structure, needed for
 245 *                      getting current norm (as well as debug print)
 246 *      @width          actual image width (from user buffer)
 247 *      @height         actual image height
 248 *      @field          indicates Top, Bottom or Interlaced
 249 */
 250static int tw68_set_scale(struct tw68_dev *dev, unsigned int width,
 251                          unsigned int height, enum v4l2_field field)
 252{
 253        const struct tw68_tvnorm *norm = dev->tvnorm;
 254        /* set individually for debugging clarity */
 255        int hactive, hdelay, hscale;
 256        int vactive, vdelay, vscale;
 257        int comb;
 258
 259        if (V4L2_FIELD_HAS_BOTH(field)) /* if field is interlaced */
 260                height /= 2;            /* we must set for 1-frame */
 261
 262        pr_debug("%s: width=%d, height=%d, both=%d\n"
 263                 "  tvnorm h_delay=%d, h_start=%d, h_stop=%d, v_delay=%d, v_start=%d, v_stop=%d\n",
 264                __func__, width, height, V4L2_FIELD_HAS_BOTH(field),
 265                norm->h_delay, norm->h_start, norm->h_stop,
 266                norm->v_delay, norm->video_v_start,
 267                norm->video_v_stop);
 268
 269        switch (dev->vdecoder) {
 270        case TW6800:
 271                hdelay = norm->h_delay0;
 272                break;
 273        default:
 274                hdelay = norm->h_delay;
 275                break;
 276        }
 277
 278        hdelay += norm->h_start;
 279        hactive = norm->h_stop - norm->h_start + 1;
 280
 281        hscale = (hactive * 256) / (width);
 282
 283        vdelay = norm->v_delay;
 284        vactive = ((norm->id & V4L2_STD_525_60) ? 524 : 624) / 2 - norm->video_v_start;
 285        vscale = (vactive * 256) / height;
 286
 287        pr_debug("%s: %dx%d [%s%s,%s]\n", __func__,
 288                width, height,
 289                V4L2_FIELD_HAS_TOP(field)    ? "T" : "",
 290                V4L2_FIELD_HAS_BOTTOM(field) ? "B" : "",
 291                v4l2_norm_to_name(dev->tvnorm->id));
 292        pr_debug("%s: hactive=%d, hdelay=%d, hscale=%d; vactive=%d, vdelay=%d, vscale=%d\n",
 293                 __func__,
 294                hactive, hdelay, hscale, vactive, vdelay, vscale);
 295
 296        comb =  ((vdelay & 0x300)  >> 2) |
 297                ((vactive & 0x300) >> 4) |
 298                ((hdelay & 0x300)  >> 6) |
 299                ((hactive & 0x300) >> 8);
 300        pr_debug("%s: setting CROP_HI=%02x, VDELAY_LO=%02x, VACTIVE_LO=%02x, HDELAY_LO=%02x, HACTIVE_LO=%02x\n",
 301                __func__, comb, vdelay, vactive, hdelay, hactive);
 302        tw_writeb(TW68_CROP_HI, comb);
 303        tw_writeb(TW68_VDELAY_LO, vdelay & 0xff);
 304        tw_writeb(TW68_VACTIVE_LO, vactive & 0xff);
 305        tw_writeb(TW68_HDELAY_LO, hdelay & 0xff);
 306        tw_writeb(TW68_HACTIVE_LO, hactive & 0xff);
 307
 308        comb = ((vscale & 0xf00) >> 4) | ((hscale & 0xf00) >> 8);
 309        pr_debug("%s: setting SCALE_HI=%02x, VSCALE_LO=%02x, HSCALE_LO=%02x\n",
 310                 __func__, comb, vscale, hscale);
 311        tw_writeb(TW68_SCALE_HI, comb);
 312        tw_writeb(TW68_VSCALE_LO, vscale);
 313        tw_writeb(TW68_HSCALE_LO, hscale);
 314
 315        return 0;
 316}
 317
 318/* ------------------------------------------------------------------ */
 319
 320int tw68_video_start_dma(struct tw68_dev *dev, struct tw68_buf *buf)
 321{
 322        /* Set cropping and scaling */
 323        tw68_set_scale(dev, dev->width, dev->height, dev->field);
 324        /*
 325         *  Set start address for RISC program.  Note that if the DMAP
 326         *  processor is currently running, it must be stopped before
 327         *  a new address can be set.
 328         */
 329        tw_clearl(TW68_DMAC, TW68_DMAP_EN);
 330        tw_writel(TW68_DMAP_SA, buf->dma);
 331        /* Clear any pending interrupts */
 332        tw_writel(TW68_INTSTAT, dev->board_virqmask);
 333        /* Enable the risc engine and the fifo */
 334        tw_andorl(TW68_DMAC, 0xff, dev->fmt->twformat |
 335                ColorFormatGamma | TW68_DMAP_EN | TW68_FIFO_EN);
 336        dev->pci_irqmask |= dev->board_virqmask;
 337        tw_setl(TW68_INTMASK, dev->pci_irqmask);
 338        return 0;
 339}
 340
 341/* ------------------------------------------------------------------ */
 342
 343/* calc max # of buffers from size (must not exceed the 4MB virtual
 344 * address space per DMA channel) */
 345static int tw68_buffer_count(unsigned int size, unsigned int count)
 346{
 347        unsigned int maxcount;
 348
 349        maxcount = (4 * 1024 * 1024) / roundup(size, PAGE_SIZE);
 350        if (count > maxcount)
 351                count = maxcount;
 352        return count;
 353}
 354
 355/* ------------------------------------------------------------- */
 356/* vb2 queue operations                                          */
 357
 358static int tw68_queue_setup(struct vb2_queue *q,
 359                           unsigned int *num_buffers, unsigned int *num_planes,
 360                           unsigned int sizes[], struct device *alloc_devs[])
 361{
 362        struct tw68_dev *dev = vb2_get_drv_priv(q);
 363        unsigned tot_bufs = q->num_buffers + *num_buffers;
 364        unsigned size = (dev->fmt->depth * dev->width * dev->height) >> 3;
 365
 366        if (tot_bufs < 2)
 367                tot_bufs = 2;
 368        tot_bufs = tw68_buffer_count(size, tot_bufs);
 369        *num_buffers = tot_bufs - q->num_buffers;
 370        /*
 371         * We allow create_bufs, but only if the sizeimage is >= as the
 372         * current sizeimage. The tw68_buffer_count calculation becomes quite
 373         * difficult otherwise.
 374         */
 375        if (*num_planes)
 376                return sizes[0] < size ? -EINVAL : 0;
 377        *num_planes = 1;
 378        sizes[0] = size;
 379
 380        return 0;
 381}
 382
 383/*
 384 * The risc program for each buffers works as follows: it starts with a simple
 385 * 'JUMP to addr + 8', which is effectively a NOP. Then the program to DMA the
 386 * buffer follows and at the end we have a JUMP back to the start + 8 (skipping
 387 * the initial JUMP).
 388 *
 389 * This is the program of the first buffer to be queued if the active list is
 390 * empty and it just keeps DMAing this buffer without generating any interrupts.
 391 *
 392 * If a new buffer is added then the initial JUMP in the program generates an
 393 * interrupt as well which signals that the previous buffer has been DMAed
 394 * successfully and that it can be returned to userspace.
 395 *
 396 * It also sets the final jump of the previous buffer to the start of the new
 397 * buffer, thus chaining the new buffer into the DMA chain. This is a single
 398 * atomic u32 write, so there is no race condition.
 399 *
 400 * The end-result of all this that you only get an interrupt when a buffer
 401 * is ready, so the control flow is very easy.
 402 */
 403static void tw68_buf_queue(struct vb2_buffer *vb)
 404{
 405        struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
 406        struct vb2_queue *vq = vb->vb2_queue;
 407        struct tw68_dev *dev = vb2_get_drv_priv(vq);
 408        struct tw68_buf *buf = container_of(vbuf, struct tw68_buf, vb);
 409        struct tw68_buf *prev;
 410        unsigned long flags;
 411
 412        spin_lock_irqsave(&dev->slock, flags);
 413
 414        /* append a 'JUMP to start of buffer' to the buffer risc program */
 415        buf->jmp[0] = cpu_to_le32(RISC_JUMP);
 416        buf->jmp[1] = cpu_to_le32(buf->dma + 8);
 417
 418        if (!list_empty(&dev->active)) {
 419                prev = list_entry(dev->active.prev, struct tw68_buf, list);
 420                buf->cpu[0] |= cpu_to_le32(RISC_INT_BIT);
 421                prev->jmp[1] = cpu_to_le32(buf->dma);
 422        }
 423        list_add_tail(&buf->list, &dev->active);
 424        spin_unlock_irqrestore(&dev->slock, flags);
 425}
 426
 427/*
 428 * buffer_prepare
 429 *
 430 * Set the ancillary information into the buffer structure.  This
 431 * includes generating the necessary risc program if it hasn't already
 432 * been done for the current buffer format.
 433 * The structure fh contains the details of the format requested by the
 434 * user - type, width, height and #fields.  This is compared with the
 435 * last format set for the current buffer.  If they differ, the risc
 436 * code (which controls the filling of the buffer) is (re-)generated.
 437 */
 438static int tw68_buf_prepare(struct vb2_buffer *vb)
 439{
 440        struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
 441        struct vb2_queue *vq = vb->vb2_queue;
 442        struct tw68_dev *dev = vb2_get_drv_priv(vq);
 443        struct tw68_buf *buf = container_of(vbuf, struct tw68_buf, vb);
 444        struct sg_table *dma = vb2_dma_sg_plane_desc(vb, 0);
 445        unsigned size, bpl;
 446
 447        size = (dev->width * dev->height * dev->fmt->depth) >> 3;
 448        if (vb2_plane_size(vb, 0) < size)
 449                return -EINVAL;
 450        vb2_set_plane_payload(vb, 0, size);
 451
 452        bpl = (dev->width * dev->fmt->depth) >> 3;
 453        switch (dev->field) {
 454        case V4L2_FIELD_TOP:
 455                tw68_risc_buffer(dev->pci, buf, dma->sgl,
 456                                 0, UNSET, bpl, 0, dev->height);
 457                break;
 458        case V4L2_FIELD_BOTTOM:
 459                tw68_risc_buffer(dev->pci, buf, dma->sgl,
 460                                 UNSET, 0, bpl, 0, dev->height);
 461                break;
 462        case V4L2_FIELD_SEQ_TB:
 463                tw68_risc_buffer(dev->pci, buf, dma->sgl,
 464                                 0, bpl * (dev->height >> 1),
 465                                 bpl, 0, dev->height >> 1);
 466                break;
 467        case V4L2_FIELD_SEQ_BT:
 468                tw68_risc_buffer(dev->pci, buf, dma->sgl,
 469                                 bpl * (dev->height >> 1), 0,
 470                                 bpl, 0, dev->height >> 1);
 471                break;
 472        case V4L2_FIELD_INTERLACED:
 473        default:
 474                tw68_risc_buffer(dev->pci, buf, dma->sgl,
 475                                 0, bpl, bpl, bpl, dev->height >> 1);
 476                break;
 477        }
 478        return 0;
 479}
 480
 481static void tw68_buf_finish(struct vb2_buffer *vb)
 482{
 483        struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
 484        struct vb2_queue *vq = vb->vb2_queue;
 485        struct tw68_dev *dev = vb2_get_drv_priv(vq);
 486        struct tw68_buf *buf = container_of(vbuf, struct tw68_buf, vb);
 487
 488        pci_free_consistent(dev->pci, buf->size, buf->cpu, buf->dma);
 489}
 490
 491static int tw68_start_streaming(struct vb2_queue *q, unsigned int count)
 492{
 493        struct tw68_dev *dev = vb2_get_drv_priv(q);
 494        struct tw68_buf *buf =
 495                container_of(dev->active.next, struct tw68_buf, list);
 496
 497        dev->seqnr = 0;
 498        tw68_video_start_dma(dev, buf);
 499        return 0;
 500}
 501
 502static void tw68_stop_streaming(struct vb2_queue *q)
 503{
 504        struct tw68_dev *dev = vb2_get_drv_priv(q);
 505
 506        /* Stop risc & fifo */
 507        tw_clearl(TW68_DMAC, TW68_DMAP_EN | TW68_FIFO_EN);
 508        while (!list_empty(&dev->active)) {
 509                struct tw68_buf *buf =
 510                        container_of(dev->active.next, struct tw68_buf, list);
 511
 512                list_del(&buf->list);
 513                vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
 514        }
 515}
 516
 517static const struct vb2_ops tw68_video_qops = {
 518        .queue_setup    = tw68_queue_setup,
 519        .buf_queue      = tw68_buf_queue,
 520        .buf_prepare    = tw68_buf_prepare,
 521        .buf_finish     = tw68_buf_finish,
 522        .start_streaming = tw68_start_streaming,
 523        .stop_streaming = tw68_stop_streaming,
 524        .wait_prepare   = vb2_ops_wait_prepare,
 525        .wait_finish    = vb2_ops_wait_finish,
 526};
 527
 528/* ------------------------------------------------------------------ */
 529
 530static int tw68_s_ctrl(struct v4l2_ctrl *ctrl)
 531{
 532        struct tw68_dev *dev =
 533                container_of(ctrl->handler, struct tw68_dev, hdl);
 534
 535        switch (ctrl->id) {
 536        case V4L2_CID_BRIGHTNESS:
 537                tw_writeb(TW68_BRIGHT, ctrl->val);
 538                break;
 539        case V4L2_CID_HUE:
 540                tw_writeb(TW68_HUE, ctrl->val);
 541                break;
 542        case V4L2_CID_CONTRAST:
 543                tw_writeb(TW68_CONTRAST, ctrl->val);
 544                break;
 545        case V4L2_CID_SATURATION:
 546                tw_writeb(TW68_SAT_U, ctrl->val);
 547                tw_writeb(TW68_SAT_V, ctrl->val);
 548                break;
 549        case V4L2_CID_COLOR_KILLER:
 550                if (ctrl->val)
 551                        tw_andorb(TW68_MISC2, 0xe0, 0xe0);
 552                else
 553                        tw_andorb(TW68_MISC2, 0xe0, 0x00);
 554                break;
 555        case V4L2_CID_CHROMA_AGC:
 556                if (ctrl->val)
 557                        tw_andorb(TW68_LOOP, 0x30, 0x20);
 558                else
 559                        tw_andorb(TW68_LOOP, 0x30, 0x00);
 560                break;
 561        }
 562        return 0;
 563}
 564
 565/* ------------------------------------------------------------------ */
 566
 567/*
 568 * Note that this routine returns what is stored in the fh structure, and
 569 * does not interrogate any of the device registers.
 570 */
 571static int tw68_g_fmt_vid_cap(struct file *file, void *priv,
 572                                struct v4l2_format *f)
 573{
 574        struct tw68_dev *dev = video_drvdata(file);
 575
 576        f->fmt.pix.width        = dev->width;
 577        f->fmt.pix.height       = dev->height;
 578        f->fmt.pix.field        = dev->field;
 579        f->fmt.pix.pixelformat  = dev->fmt->fourcc;
 580        f->fmt.pix.bytesperline =
 581                (f->fmt.pix.width * (dev->fmt->depth)) >> 3;
 582        f->fmt.pix.sizeimage =
 583                f->fmt.pix.height * f->fmt.pix.bytesperline;
 584        f->fmt.pix.colorspace   = V4L2_COLORSPACE_SMPTE170M;
 585        return 0;
 586}
 587
 588static int tw68_try_fmt_vid_cap(struct file *file, void *priv,
 589                                                struct v4l2_format *f)
 590{
 591        struct tw68_dev *dev = video_drvdata(file);
 592        const struct tw68_format *fmt;
 593        enum v4l2_field field;
 594        unsigned int maxh;
 595
 596        fmt = format_by_fourcc(f->fmt.pix.pixelformat);
 597        if (NULL == fmt)
 598                return -EINVAL;
 599
 600        field = f->fmt.pix.field;
 601        maxh  = (dev->tvnorm->id & V4L2_STD_525_60) ? 480 : 576;
 602
 603        switch (field) {
 604        case V4L2_FIELD_TOP:
 605        case V4L2_FIELD_BOTTOM:
 606                break;
 607        case V4L2_FIELD_INTERLACED:
 608        case V4L2_FIELD_SEQ_BT:
 609        case V4L2_FIELD_SEQ_TB:
 610                maxh = maxh * 2;
 611                break;
 612        default:
 613                field = (f->fmt.pix.height > maxh / 2)
 614                        ? V4L2_FIELD_INTERLACED
 615                        : V4L2_FIELD_BOTTOM;
 616                break;
 617        }
 618
 619        f->fmt.pix.field = field;
 620        if (f->fmt.pix.width  < 48)
 621                f->fmt.pix.width  = 48;
 622        if (f->fmt.pix.height < 32)
 623                f->fmt.pix.height = 32;
 624        if (f->fmt.pix.width > 720)
 625                f->fmt.pix.width = 720;
 626        if (f->fmt.pix.height > maxh)
 627                f->fmt.pix.height = maxh;
 628        f->fmt.pix.width &= ~0x03;
 629        f->fmt.pix.bytesperline =
 630                (f->fmt.pix.width * (fmt->depth)) >> 3;
 631        f->fmt.pix.sizeimage =
 632                f->fmt.pix.height * f->fmt.pix.bytesperline;
 633        f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
 634        return 0;
 635}
 636
 637/*
 638 * Note that tw68_s_fmt_vid_cap sets the information into the fh structure,
 639 * and it will be used for all future new buffers.  However, there could be
 640 * some number of buffers on the "active" chain which will be filled before
 641 * the change takes place.
 642 */
 643static int tw68_s_fmt_vid_cap(struct file *file, void *priv,
 644                                        struct v4l2_format *f)
 645{
 646        struct tw68_dev *dev = video_drvdata(file);
 647        int err;
 648
 649        err = tw68_try_fmt_vid_cap(file, priv, f);
 650        if (0 != err)
 651                return err;
 652
 653        dev->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
 654        dev->width = f->fmt.pix.width;
 655        dev->height = f->fmt.pix.height;
 656        dev->field = f->fmt.pix.field;
 657        return 0;
 658}
 659
 660static int tw68_enum_input(struct file *file, void *priv,
 661                                        struct v4l2_input *i)
 662{
 663        struct tw68_dev *dev = video_drvdata(file);
 664        unsigned int n;
 665
 666        n = i->index;
 667        if (n >= TW68_INPUT_MAX)
 668                return -EINVAL;
 669        i->index = n;
 670        i->type = V4L2_INPUT_TYPE_CAMERA;
 671        snprintf(i->name, sizeof(i->name), "Composite %d", n);
 672
 673        /* If the query is for the current input, get live data */
 674        if (n == dev->input) {
 675                int v1 = tw_readb(TW68_STATUS1);
 676                int v2 = tw_readb(TW68_MVSN);
 677
 678                if (0 != (v1 & (1 << 7)))
 679                        i->status |= V4L2_IN_ST_NO_SYNC;
 680                if (0 != (v1 & (1 << 6)))
 681                        i->status |= V4L2_IN_ST_NO_H_LOCK;
 682                if (0 != (v1 & (1 << 2)))
 683                        i->status |= V4L2_IN_ST_NO_SIGNAL;
 684                if (0 != (v1 & 1 << 1))
 685                        i->status |= V4L2_IN_ST_NO_COLOR;
 686                if (0 != (v2 & (1 << 2)))
 687                        i->status |= V4L2_IN_ST_MACROVISION;
 688        }
 689        i->std = video_devdata(file)->tvnorms;
 690        return 0;
 691}
 692
 693static int tw68_g_input(struct file *file, void *priv, unsigned int *i)
 694{
 695        struct tw68_dev *dev = video_drvdata(file);
 696
 697        *i = dev->input;
 698        return 0;
 699}
 700
 701static int tw68_s_input(struct file *file, void *priv, unsigned int i)
 702{
 703        struct tw68_dev *dev = video_drvdata(file);
 704
 705        if (i >= TW68_INPUT_MAX)
 706                return -EINVAL;
 707        dev->input = i;
 708        tw_andorb(TW68_INFORM, 0x03 << 2, dev->input << 2);
 709        return 0;
 710}
 711
 712static int tw68_querycap(struct file *file, void  *priv,
 713                                        struct v4l2_capability *cap)
 714{
 715        struct tw68_dev *dev = video_drvdata(file);
 716
 717        strscpy(cap->driver, "tw68", sizeof(cap->driver));
 718        strscpy(cap->card, "Techwell Capture Card",
 719                sizeof(cap->card));
 720        sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci));
 721        return 0;
 722}
 723
 724static int tw68_s_std(struct file *file, void *priv, v4l2_std_id id)
 725{
 726        struct tw68_dev *dev = video_drvdata(file);
 727        unsigned int i;
 728
 729        if (vb2_is_busy(&dev->vidq))
 730                return -EBUSY;
 731
 732        /* Look for match on complete norm id (may have mult bits) */
 733        for (i = 0; i < TVNORMS; i++) {
 734                if (id == tvnorms[i].id)
 735                        break;
 736        }
 737
 738        /* If no exact match, look for norm which contains this one */
 739        if (i == TVNORMS) {
 740                for (i = 0; i < TVNORMS; i++)
 741                        if (id & tvnorms[i].id)
 742                                break;
 743        }
 744        /* If still not matched, give up */
 745        if (i == TVNORMS)
 746                return -EINVAL;
 747
 748        set_tvnorm(dev, &tvnorms[i]);   /* do the actual setting */
 749        return 0;
 750}
 751
 752static int tw68_g_std(struct file *file, void *priv, v4l2_std_id *id)
 753{
 754        struct tw68_dev *dev = video_drvdata(file);
 755
 756        *id = dev->tvnorm->id;
 757        return 0;
 758}
 759
 760static int tw68_enum_fmt_vid_cap(struct file *file, void  *priv,
 761                                        struct v4l2_fmtdesc *f)
 762{
 763        if (f->index >= FORMATS)
 764                return -EINVAL;
 765
 766        f->pixelformat = formats[f->index].fourcc;
 767
 768        return 0;
 769}
 770
 771/*
 772 * Used strictly for internal development and debugging, this routine
 773 * prints out the current register contents for the tw68xx device.
 774 */
 775static void tw68_dump_regs(struct tw68_dev *dev)
 776{
 777        unsigned char line[80];
 778        int i, j, k;
 779        unsigned char *cptr;
 780
 781        pr_info("Full dump of TW68 registers:\n");
 782        /* First we do the PCI regs, 8 4-byte regs per line */
 783        for (i = 0; i < 0x100; i += 32) {
 784                cptr = line;
 785                cptr += sprintf(cptr, "%03x  ", i);
 786                /* j steps through the next 4 words */
 787                for (j = i; j < i + 16; j += 4)
 788                        cptr += sprintf(cptr, "%08x ", tw_readl(j));
 789                *cptr++ = ' ';
 790                for (; j < i + 32; j += 4)
 791                        cptr += sprintf(cptr, "%08x ", tw_readl(j));
 792                *cptr++ = '\n';
 793                *cptr = 0;
 794                pr_info("%s", line);
 795        }
 796        /* Next the control regs, which are single-byte, address mod 4 */
 797        while (i < 0x400) {
 798                cptr = line;
 799                cptr += sprintf(cptr, "%03x ", i);
 800                /* Print out 4 groups of 4 bytes */
 801                for (j = 0; j < 4; j++) {
 802                        for (k = 0; k < 4; k++) {
 803                                cptr += sprintf(cptr, "%02x ",
 804                                        tw_readb(i));
 805                                i += 4;
 806                        }
 807                        *cptr++ = ' ';
 808                }
 809                *cptr++ = '\n';
 810                *cptr = 0;
 811                pr_info("%s", line);
 812        }
 813}
 814
 815static int vidioc_log_status(struct file *file, void *priv)
 816{
 817        struct tw68_dev *dev = video_drvdata(file);
 818
 819        tw68_dump_regs(dev);
 820        return v4l2_ctrl_log_status(file, priv);
 821}
 822
 823#ifdef CONFIG_VIDEO_ADV_DEBUG
 824static int vidioc_g_register(struct file *file, void *priv,
 825                              struct v4l2_dbg_register *reg)
 826{
 827        struct tw68_dev *dev = video_drvdata(file);
 828
 829        if (reg->size == 1)
 830                reg->val = tw_readb(reg->reg);
 831        else
 832                reg->val = tw_readl(reg->reg);
 833        return 0;
 834}
 835
 836static int vidioc_s_register(struct file *file, void *priv,
 837                                const struct v4l2_dbg_register *reg)
 838{
 839        struct tw68_dev *dev = video_drvdata(file);
 840
 841        if (reg->size == 1)
 842                tw_writeb(reg->reg, reg->val);
 843        else
 844                tw_writel(reg->reg & 0xffff, reg->val);
 845        return 0;
 846}
 847#endif
 848
 849static const struct v4l2_ctrl_ops tw68_ctrl_ops = {
 850        .s_ctrl = tw68_s_ctrl,
 851};
 852
 853static const struct v4l2_file_operations video_fops = {
 854        .owner                  = THIS_MODULE,
 855        .open                   = v4l2_fh_open,
 856        .release                = vb2_fop_release,
 857        .read                   = vb2_fop_read,
 858        .poll                   = vb2_fop_poll,
 859        .mmap                   = vb2_fop_mmap,
 860        .unlocked_ioctl         = video_ioctl2,
 861};
 862
 863static const struct v4l2_ioctl_ops video_ioctl_ops = {
 864        .vidioc_querycap                = tw68_querycap,
 865        .vidioc_enum_fmt_vid_cap        = tw68_enum_fmt_vid_cap,
 866        .vidioc_reqbufs                 = vb2_ioctl_reqbufs,
 867        .vidioc_create_bufs             = vb2_ioctl_create_bufs,
 868        .vidioc_querybuf                = vb2_ioctl_querybuf,
 869        .vidioc_qbuf                    = vb2_ioctl_qbuf,
 870        .vidioc_dqbuf                   = vb2_ioctl_dqbuf,
 871        .vidioc_s_std                   = tw68_s_std,
 872        .vidioc_g_std                   = tw68_g_std,
 873        .vidioc_enum_input              = tw68_enum_input,
 874        .vidioc_g_input                 = tw68_g_input,
 875        .vidioc_s_input                 = tw68_s_input,
 876        .vidioc_streamon                = vb2_ioctl_streamon,
 877        .vidioc_streamoff               = vb2_ioctl_streamoff,
 878        .vidioc_g_fmt_vid_cap           = tw68_g_fmt_vid_cap,
 879        .vidioc_try_fmt_vid_cap         = tw68_try_fmt_vid_cap,
 880        .vidioc_s_fmt_vid_cap           = tw68_s_fmt_vid_cap,
 881        .vidioc_log_status              = vidioc_log_status,
 882        .vidioc_subscribe_event         = v4l2_ctrl_subscribe_event,
 883        .vidioc_unsubscribe_event       = v4l2_event_unsubscribe,
 884#ifdef CONFIG_VIDEO_ADV_DEBUG
 885        .vidioc_g_register              = vidioc_g_register,
 886        .vidioc_s_register              = vidioc_s_register,
 887#endif
 888};
 889
 890static const struct video_device tw68_video_template = {
 891        .name                   = "tw68_video",
 892        .fops                   = &video_fops,
 893        .ioctl_ops              = &video_ioctl_ops,
 894        .release                = video_device_release_empty,
 895        .tvnorms                = TW68_NORMS,
 896        .device_caps            = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
 897                                  V4L2_CAP_STREAMING,
 898};
 899
 900/* ------------------------------------------------------------------ */
 901/* exported stuff                                                     */
 902void tw68_set_tvnorm_hw(struct tw68_dev *dev)
 903{
 904        tw_andorb(TW68_SDT, 0x07, dev->tvnorm->format);
 905}
 906
 907int tw68_video_init1(struct tw68_dev *dev)
 908{
 909        struct v4l2_ctrl_handler *hdl = &dev->hdl;
 910
 911        v4l2_ctrl_handler_init(hdl, 6);
 912        v4l2_ctrl_new_std(hdl, &tw68_ctrl_ops,
 913                        V4L2_CID_BRIGHTNESS, -128, 127, 1, 20);
 914        v4l2_ctrl_new_std(hdl, &tw68_ctrl_ops,
 915                        V4L2_CID_CONTRAST, 0, 255, 1, 100);
 916        v4l2_ctrl_new_std(hdl, &tw68_ctrl_ops,
 917                        V4L2_CID_SATURATION, 0, 255, 1, 128);
 918        /* NTSC only */
 919        v4l2_ctrl_new_std(hdl, &tw68_ctrl_ops,
 920                        V4L2_CID_HUE, -128, 127, 1, 0);
 921        v4l2_ctrl_new_std(hdl, &tw68_ctrl_ops,
 922                        V4L2_CID_COLOR_KILLER, 0, 1, 1, 0);
 923        v4l2_ctrl_new_std(hdl, &tw68_ctrl_ops,
 924                        V4L2_CID_CHROMA_AGC, 0, 1, 1, 1);
 925        if (hdl->error) {
 926                v4l2_ctrl_handler_free(hdl);
 927                return hdl->error;
 928        }
 929        dev->v4l2_dev.ctrl_handler = hdl;
 930        v4l2_ctrl_handler_setup(hdl);
 931        return 0;
 932}
 933
 934int tw68_video_init2(struct tw68_dev *dev, int video_nr)
 935{
 936        int ret;
 937
 938        set_tvnorm(dev, &tvnorms[0]);
 939
 940        dev->fmt      = format_by_fourcc(V4L2_PIX_FMT_BGR24);
 941        dev->width    = 720;
 942        dev->height   = 576;
 943        dev->field    = V4L2_FIELD_INTERLACED;
 944
 945        INIT_LIST_HEAD(&dev->active);
 946        dev->vidq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 947        dev->vidq.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
 948        dev->vidq.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ | VB2_DMABUF;
 949        dev->vidq.ops = &tw68_video_qops;
 950        dev->vidq.mem_ops = &vb2_dma_sg_memops;
 951        dev->vidq.drv_priv = dev;
 952        dev->vidq.gfp_flags = __GFP_DMA32 | __GFP_KSWAPD_RECLAIM;
 953        dev->vidq.buf_struct_size = sizeof(struct tw68_buf);
 954        dev->vidq.lock = &dev->lock;
 955        dev->vidq.min_buffers_needed = 2;
 956        dev->vidq.dev = &dev->pci->dev;
 957        ret = vb2_queue_init(&dev->vidq);
 958        if (ret)
 959                return ret;
 960        dev->vdev = tw68_video_template;
 961        dev->vdev.v4l2_dev = &dev->v4l2_dev;
 962        dev->vdev.lock = &dev->lock;
 963        dev->vdev.queue = &dev->vidq;
 964        video_set_drvdata(&dev->vdev, dev);
 965        return video_register_device(&dev->vdev, VFL_TYPE_GRABBER, video_nr);
 966}
 967
 968/*
 969 * tw68_irq_video_done
 970 */
 971void tw68_irq_video_done(struct tw68_dev *dev, unsigned long status)
 972{
 973        __u32 reg;
 974
 975        /* reset interrupts handled by this routine */
 976        tw_writel(TW68_INTSTAT, status);
 977        /*
 978         * Check most likely first
 979         *
 980         * DMAPI shows we have reached the end of the risc code
 981         * for the current buffer.
 982         */
 983        if (status & TW68_DMAPI) {
 984                struct tw68_buf *buf;
 985
 986                spin_lock(&dev->slock);
 987                buf = list_entry(dev->active.next, struct tw68_buf, list);
 988                list_del(&buf->list);
 989                spin_unlock(&dev->slock);
 990                buf->vb.vb2_buf.timestamp = ktime_get_ns();
 991                buf->vb.field = dev->field;
 992                buf->vb.sequence = dev->seqnr++;
 993                vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
 994                status &= ~(TW68_DMAPI);
 995                if (0 == status)
 996                        return;
 997        }
 998        if (status & (TW68_VLOCK | TW68_HLOCK))
 999                dev_dbg(&dev->pci->dev, "Lost sync\n");
1000        if (status & TW68_PABORT)
1001                dev_err(&dev->pci->dev, "PABORT interrupt\n");
1002        if (status & TW68_DMAPERR)
1003                dev_err(&dev->pci->dev, "DMAPERR interrupt\n");
1004        /*
1005         * On TW6800, FDMIS is apparently generated if video input is switched
1006         * during operation.  Therefore, it is not enabled for that chip.
1007         */
1008        if (status & TW68_FDMIS)
1009                dev_dbg(&dev->pci->dev, "FDMIS interrupt\n");
1010        if (status & TW68_FFOF) {
1011                /* probably a logic error */
1012                reg = tw_readl(TW68_DMAC) & TW68_FIFO_EN;
1013                tw_clearl(TW68_DMAC, TW68_FIFO_EN);
1014                dev_dbg(&dev->pci->dev, "FFOF interrupt\n");
1015                tw_setl(TW68_DMAC, reg);
1016        }
1017        if (status & TW68_FFERR)
1018                dev_dbg(&dev->pci->dev, "FFERR interrupt\n");
1019}
1020