linux/drivers/media/video/vino.c
<<
>>
Prefs
   1/*
   2 * Driver for the VINO (Video In No Out) system found in SGI Indys.
   3 *
   4 * This file is subject to the terms and conditions of the GNU General Public
   5 * License version 2 as published by the Free Software Foundation.
   6 *
   7 * Copyright (C) 2004,2005 Mikael Nousiainen <tmnousia@cc.hut.fi>
   8 *
   9 * Based on the previous version of the driver for 2.4 kernels by:
  10 * Copyright (C) 2003 Ladislav Michl <ladis@linux-mips.org>
  11 *
  12 * v4l2_device/v4l2_subdev conversion by:
  13 * Copyright (C) 2009 Hans Verkuil <hverkuil@xs4all.nl>
  14 *
  15 * Note: this conversion is untested! Please contact the linux-media
  16 * mailinglist if you can test this, together with the test results.
  17 */
  18
  19/*
  20 * TODO:
  21 * - remove "mark pages reserved-hacks" from memory allocation code
  22 *   and implement fault()
  23 * - check decimation, calculating and reporting image size when
  24 *   using decimation
  25 * - implement read(), user mode buffers and overlay (?)
  26 */
  27
  28#include <linux/init.h>
  29#include <linux/module.h>
  30#include <linux/delay.h>
  31#include <linux/dma-mapping.h>
  32#include <linux/errno.h>
  33#include <linux/fs.h>
  34#include <linux/interrupt.h>
  35#include <linux/kernel.h>
  36#include <linux/slab.h>
  37#include <linux/mm.h>
  38#include <linux/time.h>
  39#include <linux/version.h>
  40#include <linux/kmod.h>
  41
  42#include <linux/i2c.h>
  43
  44#include <linux/videodev2.h>
  45#include <media/v4l2-device.h>
  46#include <media/v4l2-ioctl.h>
  47#include <linux/mutex.h>
  48
  49#include <asm/paccess.h>
  50#include <asm/io.h>
  51#include <asm/sgi/ip22.h>
  52#include <asm/sgi/mc.h>
  53
  54#include "vino.h"
  55#include "saa7191.h"
  56#include "indycam.h"
  57
  58/* Uncomment the following line to get lots and lots of (mostly useless)
  59 * debug info.
  60 * Note that the debug output also slows down the driver significantly */
  61// #define VINO_DEBUG
  62// #define VINO_DEBUG_INT
  63
  64#define VINO_MODULE_VERSION "0.0.6"
  65#define VINO_VERSION_CODE KERNEL_VERSION(0, 0, 6)
  66
  67MODULE_DESCRIPTION("SGI VINO Video4Linux2 driver");
  68MODULE_VERSION(VINO_MODULE_VERSION);
  69MODULE_AUTHOR("Mikael Nousiainen <tmnousia@cc.hut.fi>");
  70MODULE_LICENSE("GPL");
  71
  72#ifdef VINO_DEBUG
  73#define dprintk(x...) printk("VINO: " x);
  74#else
  75#define dprintk(x...)
  76#endif
  77
  78#define VINO_NO_CHANNEL                 0
  79#define VINO_CHANNEL_A                  1
  80#define VINO_CHANNEL_B                  2
  81
  82#define VINO_PAL_WIDTH                  768
  83#define VINO_PAL_HEIGHT                 576
  84#define VINO_NTSC_WIDTH                 640
  85#define VINO_NTSC_HEIGHT                480
  86
  87#define VINO_MIN_WIDTH                  32
  88#define VINO_MIN_HEIGHT                 32
  89
  90#define VINO_CLIPPING_START_ODD_D1      1
  91#define VINO_CLIPPING_START_ODD_PAL     15
  92#define VINO_CLIPPING_START_ODD_NTSC    12
  93
  94#define VINO_CLIPPING_START_EVEN_D1     2
  95#define VINO_CLIPPING_START_EVEN_PAL    15
  96#define VINO_CLIPPING_START_EVEN_NTSC   12
  97
  98#define VINO_INPUT_CHANNEL_COUNT        3
  99
 100/* the number is the index for vino_inputs */
 101#define VINO_INPUT_NONE                 -1
 102#define VINO_INPUT_COMPOSITE            0
 103#define VINO_INPUT_SVIDEO               1
 104#define VINO_INPUT_D1                   2
 105
 106#define VINO_PAGE_RATIO                 (PAGE_SIZE / VINO_PAGE_SIZE)
 107
 108#define VINO_FIFO_THRESHOLD_DEFAULT     16
 109
 110#define VINO_FRAMEBUFFER_SIZE           ((VINO_PAL_WIDTH \
 111                                          * VINO_PAL_HEIGHT * 4 \
 112                                          + 3 * PAGE_SIZE) & ~(PAGE_SIZE - 1))
 113
 114#define VINO_FRAMEBUFFER_COUNT_MAX      8
 115
 116#define VINO_FRAMEBUFFER_UNUSED         0
 117#define VINO_FRAMEBUFFER_IN_USE         1
 118#define VINO_FRAMEBUFFER_READY          2
 119
 120#define VINO_QUEUE_ERROR                -1
 121#define VINO_QUEUE_MAGIC                0x20050125
 122
 123#define VINO_MEMORY_NONE                0
 124#define VINO_MEMORY_MMAP                1
 125#define VINO_MEMORY_USERPTR             2
 126
 127#define VINO_DUMMY_DESC_COUNT           4
 128#define VINO_DESC_FETCH_DELAY           5       /* microseconds */
 129
 130#define VINO_MAX_FRAME_SKIP_COUNT       128
 131
 132/* the number is the index for vino_data_formats */
 133#define VINO_DATA_FMT_NONE              -1
 134#define VINO_DATA_FMT_GREY              0
 135#define VINO_DATA_FMT_RGB332            1
 136#define VINO_DATA_FMT_RGB32             2
 137#define VINO_DATA_FMT_YUV               3
 138
 139#define VINO_DATA_FMT_COUNT             4
 140
 141/* the number is the index for vino_data_norms */
 142#define VINO_DATA_NORM_NONE             -1
 143#define VINO_DATA_NORM_NTSC             0
 144#define VINO_DATA_NORM_PAL              1
 145#define VINO_DATA_NORM_SECAM            2
 146#define VINO_DATA_NORM_D1               3
 147
 148#define VINO_DATA_NORM_COUNT            4
 149
 150/* I2C controller flags */
 151#define SGI_I2C_FORCE_IDLE              (0 << 0)
 152#define SGI_I2C_NOT_IDLE                (1 << 0)
 153#define SGI_I2C_WRITE                   (0 << 1)
 154#define SGI_I2C_READ                    (1 << 1)
 155#define SGI_I2C_RELEASE_BUS             (0 << 2)
 156#define SGI_I2C_HOLD_BUS                (1 << 2)
 157#define SGI_I2C_XFER_DONE               (0 << 4)
 158#define SGI_I2C_XFER_BUSY               (1 << 4)
 159#define SGI_I2C_ACK                     (0 << 5)
 160#define SGI_I2C_NACK                    (1 << 5)
 161#define SGI_I2C_BUS_OK                  (0 << 7)
 162#define SGI_I2C_BUS_ERR                 (1 << 7)
 163
 164/* Internal data structure definitions */
 165
 166struct vino_input {
 167        char *name;
 168        v4l2_std_id std;
 169};
 170
 171struct vino_clipping {
 172        unsigned int left, right, top, bottom;
 173};
 174
 175struct vino_data_format {
 176        /* the description */
 177        char *description;
 178        /* bytes per pixel */
 179        unsigned int bpp;
 180        /* V4L2 fourcc code */
 181        __u32 pixelformat;
 182        /* V4L2 colorspace (duh!) */
 183        enum v4l2_colorspace colorspace;
 184};
 185
 186struct vino_data_norm {
 187        char *description;
 188        unsigned int width, height;
 189        struct vino_clipping odd;
 190        struct vino_clipping even;
 191
 192        v4l2_std_id std;
 193        unsigned int fps_min, fps_max;
 194        __u32 framelines;
 195};
 196
 197struct vino_descriptor_table {
 198        /* the number of PAGE_SIZE sized pages in the buffer */
 199        unsigned int page_count;
 200        /* virtual (kmalloc'd) pointers to the actual data
 201         * (in PAGE_SIZE chunks, used with mmap streaming) */
 202        unsigned long *virtual;
 203
 204        /* cpu address for the VINO descriptor table
 205         * (contains DMA addresses, VINO_PAGE_SIZE chunks) */
 206        unsigned long *dma_cpu;
 207        /* dma address for the VINO descriptor table
 208         * (contains DMA addresses, VINO_PAGE_SIZE chunks) */
 209        dma_addr_t dma;
 210};
 211
 212struct vino_framebuffer {
 213        /* identifier nubmer */
 214        unsigned int id;
 215        /* the length of the whole buffer */
 216        unsigned int size;
 217        /* the length of actual data in buffer */
 218        unsigned int data_size;
 219        /* the data format */
 220        unsigned int data_format;
 221        /* the state of buffer data */
 222        unsigned int state;
 223        /* is the buffer mapped in user space? */
 224        unsigned int map_count;
 225        /* memory offset for mmap() */
 226        unsigned int offset;
 227        /* frame counter */
 228        unsigned int frame_counter;
 229        /* timestamp (written when image capture finishes) */
 230        struct timeval timestamp;
 231
 232        struct vino_descriptor_table desc_table;
 233
 234        spinlock_t state_lock;
 235};
 236
 237struct vino_framebuffer_fifo {
 238        unsigned int length;
 239
 240        unsigned int used;
 241        unsigned int head;
 242        unsigned int tail;
 243
 244        unsigned int data[VINO_FRAMEBUFFER_COUNT_MAX];
 245};
 246
 247struct vino_framebuffer_queue {
 248        unsigned int magic;
 249
 250        /* VINO_MEMORY_NONE, VINO_MEMORY_MMAP or VINO_MEMORY_USERPTR */
 251        unsigned int type;
 252        unsigned int length;
 253
 254        /* data field of in and out contain index numbers for buffer */
 255        struct vino_framebuffer_fifo in;
 256        struct vino_framebuffer_fifo out;
 257
 258        struct vino_framebuffer *buffer[VINO_FRAMEBUFFER_COUNT_MAX];
 259
 260        spinlock_t queue_lock;
 261        struct mutex queue_mutex;
 262        wait_queue_head_t frame_wait_queue;
 263};
 264
 265struct vino_interrupt_data {
 266        struct timeval timestamp;
 267        unsigned int frame_counter;
 268        unsigned int skip_count;
 269        unsigned int skip;
 270};
 271
 272struct vino_channel_settings {
 273        unsigned int channel;
 274
 275        int input;
 276        unsigned int data_format;
 277        unsigned int data_norm;
 278        struct vino_clipping clipping;
 279        unsigned int decimation;
 280        unsigned int line_size;
 281        unsigned int alpha;
 282        unsigned int fps;
 283        unsigned int framert_reg;
 284
 285        unsigned int fifo_threshold;
 286
 287        struct vino_framebuffer_queue fb_queue;
 288
 289        /* number of the current field */
 290        unsigned int field;
 291
 292        /* read in progress */
 293        int reading;
 294        /* streaming is active */
 295        int streaming;
 296        /* the driver is currently processing the queue */
 297        int capturing;
 298
 299        struct mutex mutex;
 300        spinlock_t capture_lock;
 301
 302        unsigned int users;
 303
 304        struct vino_interrupt_data int_data;
 305
 306        /* V4L support */
 307        struct video_device *vdev;
 308};
 309
 310struct vino_settings {
 311        struct v4l2_device v4l2_dev;
 312        struct vino_channel_settings a;
 313        struct vino_channel_settings b;
 314
 315        /* the channel which owns this client:
 316         * VINO_NO_CHANNEL, VINO_CHANNEL_A or VINO_CHANNEL_B */
 317        unsigned int decoder_owner;
 318        struct v4l2_subdev *decoder;
 319        unsigned int camera_owner;
 320        struct v4l2_subdev *camera;
 321
 322        /* a lock for vino register access */
 323        spinlock_t vino_lock;
 324        /* a lock for channel input changes */
 325        spinlock_t input_lock;
 326
 327        unsigned long dummy_page;
 328        struct vino_descriptor_table dummy_desc_table;
 329};
 330
 331/* Module parameters */
 332
 333/*
 334 * Using vino_pixel_conversion the ABGR32-format pixels supplied
 335 * by the VINO chip can be converted to more common formats
 336 * like RGBA32 (or probably RGB24 in the future). This way we
 337 * can give out data that can be specified correctly with
 338 * the V4L2-definitions.
 339 *
 340 * The pixel format is specified as RGBA32 when no conversion
 341 * is used.
 342 *
 343 * Note that this only affects the 32-bit bit depth.
 344 *
 345 * Use non-zero value to enable conversion.
 346 */
 347static int vino_pixel_conversion;
 348
 349module_param_named(pixelconv, vino_pixel_conversion, int, 0);
 350
 351MODULE_PARM_DESC(pixelconv,
 352                 "enable pixel conversion (non-zero value enables)");
 353
 354/* Internal data structures */
 355
 356static struct sgi_vino *vino;
 357
 358static struct vino_settings *vino_drvdata;
 359
 360#define camera_call(o, f, args...) \
 361        v4l2_subdev_call(vino_drvdata->camera, o, f, ##args)
 362#define decoder_call(o, f, args...) \
 363        v4l2_subdev_call(vino_drvdata->decoder, o, f, ##args)
 364
 365static const char *vino_driver_name = "vino";
 366static const char *vino_driver_description = "SGI VINO";
 367static const char *vino_bus_name = "GIO64 bus";
 368static const char *vino_vdev_name_a = "SGI VINO Channel A";
 369static const char *vino_vdev_name_b = "SGI VINO Channel B";
 370
 371static void vino_capture_tasklet(unsigned long channel);
 372
 373DECLARE_TASKLET(vino_tasklet_a, vino_capture_tasklet, VINO_CHANNEL_A);
 374DECLARE_TASKLET(vino_tasklet_b, vino_capture_tasklet, VINO_CHANNEL_B);
 375
 376static const struct vino_input vino_inputs[] = {
 377        {
 378                .name           = "Composite",
 379                .std            = V4L2_STD_NTSC | V4L2_STD_PAL
 380                | V4L2_STD_SECAM,
 381        }, {
 382                .name           = "S-Video",
 383                .std            = V4L2_STD_NTSC | V4L2_STD_PAL
 384                | V4L2_STD_SECAM,
 385        }, {
 386                .name           = "D1/IndyCam",
 387                .std            = V4L2_STD_NTSC,
 388        }
 389};
 390
 391static const struct vino_data_format vino_data_formats[] = {
 392        {
 393                .description    = "8-bit greyscale",
 394                .bpp            = 1,
 395                .pixelformat    = V4L2_PIX_FMT_GREY,
 396                .colorspace     = V4L2_COLORSPACE_SMPTE170M,
 397        }, {
 398                .description    = "8-bit dithered RGB 3-3-2",
 399                .bpp            = 1,
 400                .pixelformat    = V4L2_PIX_FMT_RGB332,
 401                .colorspace     = V4L2_COLORSPACE_SRGB,
 402        }, {
 403                .description    = "32-bit RGB",
 404                .bpp            = 4,
 405                .pixelformat    = V4L2_PIX_FMT_RGB32,
 406                .colorspace     = V4L2_COLORSPACE_SRGB,
 407        }, {
 408                .description    = "YUV 4:2:2",
 409                .bpp            = 2,
 410                .pixelformat    = V4L2_PIX_FMT_YUYV, // XXX: swapped?
 411                .colorspace     = V4L2_COLORSPACE_SMPTE170M,
 412        }
 413};
 414
 415static const struct vino_data_norm vino_data_norms[] = {
 416        {
 417                .description    = "NTSC",
 418                .std            = V4L2_STD_NTSC,
 419                .fps_min        = 6,
 420                .fps_max        = 30,
 421                .framelines     = 525,
 422                .width          = VINO_NTSC_WIDTH,
 423                .height         = VINO_NTSC_HEIGHT,
 424                .odd            = {
 425                        .top    = VINO_CLIPPING_START_ODD_NTSC,
 426                        .left   = 0,
 427                        .bottom = VINO_CLIPPING_START_ODD_NTSC
 428                        + VINO_NTSC_HEIGHT / 2 - 1,
 429                        .right  = VINO_NTSC_WIDTH,
 430                },
 431                .even           = {
 432                        .top    = VINO_CLIPPING_START_EVEN_NTSC,
 433                        .left   = 0,
 434                        .bottom = VINO_CLIPPING_START_EVEN_NTSC
 435                        + VINO_NTSC_HEIGHT / 2 - 1,
 436                        .right  = VINO_NTSC_WIDTH,
 437                },
 438        }, {
 439                .description    = "PAL",
 440                .std            = V4L2_STD_PAL,
 441                .fps_min        = 5,
 442                .fps_max        = 25,
 443                .framelines     = 625,
 444                .width          = VINO_PAL_WIDTH,
 445                .height         = VINO_PAL_HEIGHT,
 446                .odd            = {
 447                        .top    = VINO_CLIPPING_START_ODD_PAL,
 448                        .left   = 0,
 449                        .bottom = VINO_CLIPPING_START_ODD_PAL
 450                        + VINO_PAL_HEIGHT / 2 - 1,
 451                        .right  = VINO_PAL_WIDTH,
 452                },
 453                .even           = {
 454                        .top    = VINO_CLIPPING_START_EVEN_PAL,
 455                        .left   = 0,
 456                        .bottom = VINO_CLIPPING_START_EVEN_PAL
 457                        + VINO_PAL_HEIGHT / 2 - 1,
 458                        .right  = VINO_PAL_WIDTH,
 459                },
 460        }, {
 461                .description    = "SECAM",
 462                .std            = V4L2_STD_SECAM,
 463                .fps_min        = 5,
 464                .fps_max        = 25,
 465                .framelines     = 625,
 466                .width          = VINO_PAL_WIDTH,
 467                .height         = VINO_PAL_HEIGHT,
 468                .odd            = {
 469                        .top    = VINO_CLIPPING_START_ODD_PAL,
 470                        .left   = 0,
 471                        .bottom = VINO_CLIPPING_START_ODD_PAL
 472                        + VINO_PAL_HEIGHT / 2 - 1,
 473                        .right  = VINO_PAL_WIDTH,
 474                },
 475                .even           = {
 476                        .top    = VINO_CLIPPING_START_EVEN_PAL,
 477                        .left   = 0,
 478                        .bottom = VINO_CLIPPING_START_EVEN_PAL
 479                        + VINO_PAL_HEIGHT / 2 - 1,
 480                        .right  = VINO_PAL_WIDTH,
 481                },
 482        }, {
 483                .description    = "NTSC/D1",
 484                .std            = V4L2_STD_NTSC,
 485                .fps_min        = 6,
 486                .fps_max        = 30,
 487                .framelines     = 525,
 488                .width          = VINO_NTSC_WIDTH,
 489                .height         = VINO_NTSC_HEIGHT,
 490                .odd            = {
 491                        .top    = VINO_CLIPPING_START_ODD_D1,
 492                        .left   = 0,
 493                        .bottom = VINO_CLIPPING_START_ODD_D1
 494                        + VINO_NTSC_HEIGHT / 2 - 1,
 495                        .right  = VINO_NTSC_WIDTH,
 496                },
 497                .even           = {
 498                        .top    = VINO_CLIPPING_START_EVEN_D1,
 499                        .left   = 0,
 500                        .bottom = VINO_CLIPPING_START_EVEN_D1
 501                        + VINO_NTSC_HEIGHT / 2 - 1,
 502                        .right  = VINO_NTSC_WIDTH,
 503                },
 504        }
 505};
 506
 507#define VINO_INDYCAM_V4L2_CONTROL_COUNT         9
 508
 509struct v4l2_queryctrl vino_indycam_v4l2_controls[] = {
 510        {
 511                .id = V4L2_CID_AUTOGAIN,
 512                .type = V4L2_CTRL_TYPE_BOOLEAN,
 513                .name = "Automatic Gain Control",
 514                .minimum = 0,
 515                .maximum = 1,
 516                .step = 1,
 517                .default_value = INDYCAM_AGC_DEFAULT,
 518        }, {
 519                .id = V4L2_CID_AUTO_WHITE_BALANCE,
 520                .type = V4L2_CTRL_TYPE_BOOLEAN,
 521                .name = "Automatic White Balance",
 522                .minimum = 0,
 523                .maximum = 1,
 524                .step = 1,
 525                .default_value = INDYCAM_AWB_DEFAULT,
 526        }, {
 527                .id = V4L2_CID_GAIN,
 528                .type = V4L2_CTRL_TYPE_INTEGER,
 529                .name = "Gain",
 530                .minimum = INDYCAM_GAIN_MIN,
 531                .maximum = INDYCAM_GAIN_MAX,
 532                .step = 1,
 533                .default_value = INDYCAM_GAIN_DEFAULT,
 534        }, {
 535                .id = INDYCAM_CONTROL_RED_SATURATION,
 536                .type = V4L2_CTRL_TYPE_INTEGER,
 537                .name = "Red Saturation",
 538                .minimum = INDYCAM_RED_SATURATION_MIN,
 539                .maximum = INDYCAM_RED_SATURATION_MAX,
 540                .step = 1,
 541                .default_value = INDYCAM_RED_SATURATION_DEFAULT,
 542        }, {
 543                .id = INDYCAM_CONTROL_BLUE_SATURATION,
 544                .type = V4L2_CTRL_TYPE_INTEGER,
 545                .name = "Blue Saturation",
 546                .minimum = INDYCAM_BLUE_SATURATION_MIN,
 547                .maximum = INDYCAM_BLUE_SATURATION_MAX,
 548                .step = 1,
 549                .default_value = INDYCAM_BLUE_SATURATION_DEFAULT,
 550        }, {
 551                .id = V4L2_CID_RED_BALANCE,
 552                .type = V4L2_CTRL_TYPE_INTEGER,
 553                .name = "Red Balance",
 554                .minimum = INDYCAM_RED_BALANCE_MIN,
 555                .maximum = INDYCAM_RED_BALANCE_MAX,
 556                .step = 1,
 557                .default_value = INDYCAM_RED_BALANCE_DEFAULT,
 558        }, {
 559                .id = V4L2_CID_BLUE_BALANCE,
 560                .type = V4L2_CTRL_TYPE_INTEGER,
 561                .name = "Blue Balance",
 562                .minimum = INDYCAM_BLUE_BALANCE_MIN,
 563                .maximum = INDYCAM_BLUE_BALANCE_MAX,
 564                .step = 1,
 565                .default_value = INDYCAM_BLUE_BALANCE_DEFAULT,
 566        }, {
 567                .id = V4L2_CID_EXPOSURE,
 568                .type = V4L2_CTRL_TYPE_INTEGER,
 569                .name = "Shutter Control",
 570                .minimum = INDYCAM_SHUTTER_MIN,
 571                .maximum = INDYCAM_SHUTTER_MAX,
 572                .step = 1,
 573                .default_value = INDYCAM_SHUTTER_DEFAULT,
 574        }, {
 575                .id = V4L2_CID_GAMMA,
 576                .type = V4L2_CTRL_TYPE_INTEGER,
 577                .name = "Gamma",
 578                .minimum = INDYCAM_GAMMA_MIN,
 579                .maximum = INDYCAM_GAMMA_MAX,
 580                .step = 1,
 581                .default_value = INDYCAM_GAMMA_DEFAULT,
 582        }
 583};
 584
 585#define VINO_SAA7191_V4L2_CONTROL_COUNT         9
 586
 587struct v4l2_queryctrl vino_saa7191_v4l2_controls[] = {
 588        {
 589                .id = V4L2_CID_HUE,
 590                .type = V4L2_CTRL_TYPE_INTEGER,
 591                .name = "Hue",
 592                .minimum = SAA7191_HUE_MIN,
 593                .maximum = SAA7191_HUE_MAX,
 594                .step = 1,
 595                .default_value = SAA7191_HUE_DEFAULT,
 596        }, {
 597                .id = SAA7191_CONTROL_BANDPASS,
 598                .type = V4L2_CTRL_TYPE_INTEGER,
 599                .name = "Luminance Bandpass",
 600                .minimum = SAA7191_BANDPASS_MIN,
 601                .maximum = SAA7191_BANDPASS_MAX,
 602                .step = 1,
 603                .default_value = SAA7191_BANDPASS_DEFAULT,
 604        }, {
 605                .id = SAA7191_CONTROL_BANDPASS_WEIGHT,
 606                .type = V4L2_CTRL_TYPE_INTEGER,
 607                .name = "Luminance Bandpass Weight",
 608                .minimum = SAA7191_BANDPASS_WEIGHT_MIN,
 609                .maximum = SAA7191_BANDPASS_WEIGHT_MAX,
 610                .step = 1,
 611                .default_value = SAA7191_BANDPASS_WEIGHT_DEFAULT,
 612        }, {
 613                .id = SAA7191_CONTROL_CORING,
 614                .type = V4L2_CTRL_TYPE_INTEGER,
 615                .name = "HF Luminance Coring",
 616                .minimum = SAA7191_CORING_MIN,
 617                .maximum = SAA7191_CORING_MAX,
 618                .step = 1,
 619                .default_value = SAA7191_CORING_DEFAULT,
 620        }, {
 621                .id = SAA7191_CONTROL_FORCE_COLOUR,
 622                .type = V4L2_CTRL_TYPE_BOOLEAN,
 623                .name = "Force Colour",
 624                .minimum = SAA7191_FORCE_COLOUR_MIN,
 625                .maximum = SAA7191_FORCE_COLOUR_MAX,
 626                .step = 1,
 627                .default_value = SAA7191_FORCE_COLOUR_DEFAULT,
 628        }, {
 629                .id = SAA7191_CONTROL_CHROMA_GAIN,
 630                .type = V4L2_CTRL_TYPE_INTEGER,
 631                .name = "Chrominance Gain Control",
 632                .minimum = SAA7191_CHROMA_GAIN_MIN,
 633                .maximum = SAA7191_CHROMA_GAIN_MAX,
 634                .step = 1,
 635                .default_value = SAA7191_CHROMA_GAIN_DEFAULT,
 636        }, {
 637                .id = SAA7191_CONTROL_VTRC,
 638                .type = V4L2_CTRL_TYPE_BOOLEAN,
 639                .name = "VTR Time Constant",
 640                .minimum = SAA7191_VTRC_MIN,
 641                .maximum = SAA7191_VTRC_MAX,
 642                .step = 1,
 643                .default_value = SAA7191_VTRC_DEFAULT,
 644        }, {
 645                .id = SAA7191_CONTROL_LUMA_DELAY,
 646                .type = V4L2_CTRL_TYPE_INTEGER,
 647                .name = "Luminance Delay Compensation",
 648                .minimum = SAA7191_LUMA_DELAY_MIN,
 649                .maximum = SAA7191_LUMA_DELAY_MAX,
 650                .step = 1,
 651                .default_value = SAA7191_LUMA_DELAY_DEFAULT,
 652        }, {
 653                .id = SAA7191_CONTROL_VNR,
 654                .type = V4L2_CTRL_TYPE_INTEGER,
 655                .name = "Vertical Noise Reduction",
 656                .minimum = SAA7191_VNR_MIN,
 657                .maximum = SAA7191_VNR_MAX,
 658                .step = 1,
 659                .default_value = SAA7191_VNR_DEFAULT,
 660        }
 661};
 662
 663/* VINO framebuffer/DMA descriptor management */
 664
 665static void vino_free_buffer_with_count(struct vino_framebuffer *fb,
 666                                               unsigned int count)
 667{
 668        unsigned int i;
 669
 670        dprintk("vino_free_buffer_with_count(): count = %d\n", count);
 671
 672        for (i = 0; i < count; i++) {
 673                ClearPageReserved(virt_to_page((void *)fb->desc_table.virtual[i]));
 674                dma_unmap_single(NULL,
 675                                 fb->desc_table.dma_cpu[VINO_PAGE_RATIO * i],
 676                                 PAGE_SIZE, DMA_FROM_DEVICE);
 677                free_page(fb->desc_table.virtual[i]);
 678        }
 679
 680        dma_free_coherent(NULL,
 681                          VINO_PAGE_RATIO * (fb->desc_table.page_count + 4) *
 682                          sizeof(dma_addr_t), (void *)fb->desc_table.dma_cpu,
 683                          fb->desc_table.dma);
 684        kfree(fb->desc_table.virtual);
 685
 686        memset(fb, 0, sizeof(struct vino_framebuffer));
 687}
 688
 689static void vino_free_buffer(struct vino_framebuffer *fb)
 690{
 691        vino_free_buffer_with_count(fb, fb->desc_table.page_count);
 692}
 693
 694static int vino_allocate_buffer(struct vino_framebuffer *fb,
 695                                unsigned int size)
 696{
 697        unsigned int count, i, j;
 698        int ret = 0;
 699
 700        dprintk("vino_allocate_buffer():\n");
 701
 702        if (size < 1)
 703                return -EINVAL;
 704
 705        memset(fb, 0, sizeof(struct vino_framebuffer));
 706
 707        count = ((size / PAGE_SIZE) + 4) & ~3;
 708
 709        dprintk("vino_allocate_buffer(): size = %d, count = %d\n",
 710                size, count);
 711
 712        /* allocate memory for table with virtual (page) addresses */
 713        fb->desc_table.virtual = (unsigned long *)
 714                kmalloc(count * sizeof(unsigned long), GFP_KERNEL);
 715        if (!fb->desc_table.virtual)
 716                return -ENOMEM;
 717
 718        /* allocate memory for table with dma addresses
 719         * (has space for four extra descriptors) */
 720        fb->desc_table.dma_cpu =
 721                dma_alloc_coherent(NULL, VINO_PAGE_RATIO * (count + 4) *
 722                                   sizeof(dma_addr_t), &fb->desc_table.dma,
 723                                   GFP_KERNEL | GFP_DMA);
 724        if (!fb->desc_table.dma_cpu) {
 725                ret = -ENOMEM;
 726                goto out_free_virtual;
 727        }
 728
 729        /* allocate pages for the buffer and acquire the according
 730         * dma addresses */
 731        for (i = 0; i < count; i++) {
 732                dma_addr_t dma_data_addr;
 733
 734                fb->desc_table.virtual[i] =
 735                        get_zeroed_page(GFP_KERNEL | GFP_DMA);
 736                if (!fb->desc_table.virtual[i]) {
 737                        ret = -ENOBUFS;
 738                        break;
 739                }
 740
 741                dma_data_addr =
 742                        dma_map_single(NULL,
 743                                       (void *)fb->desc_table.virtual[i],
 744                                       PAGE_SIZE, DMA_FROM_DEVICE);
 745
 746                for (j = 0; j < VINO_PAGE_RATIO; j++) {
 747                        fb->desc_table.dma_cpu[VINO_PAGE_RATIO * i + j] =
 748                                dma_data_addr + VINO_PAGE_SIZE * j;
 749                }
 750
 751                SetPageReserved(virt_to_page((void *)fb->desc_table.virtual[i]));
 752        }
 753
 754        /* page_count needs to be set anyway, because the descriptor table has
 755         * been allocated according to this number */
 756        fb->desc_table.page_count = count;
 757
 758        if (ret) {
 759                /* the descriptor with index i doesn't contain
 760                 * a valid address yet */
 761                vino_free_buffer_with_count(fb, i);
 762                return ret;
 763        }
 764
 765        //fb->size = size;
 766        fb->size = count * PAGE_SIZE;
 767        fb->data_format = VINO_DATA_FMT_NONE;
 768
 769        /* set the dma stop-bit for the last (count+1)th descriptor */
 770        fb->desc_table.dma_cpu[VINO_PAGE_RATIO * count] = VINO_DESC_STOP;
 771        return 0;
 772
 773 out_free_virtual:
 774        kfree(fb->desc_table.virtual);
 775        return ret;
 776}
 777
 778#if 0
 779/* user buffers not fully implemented yet */
 780static int vino_prepare_user_buffer(struct vino_framebuffer *fb,
 781                                     void *user,
 782                                     unsigned int size)
 783{
 784        unsigned int count, i, j;
 785        int ret = 0;
 786
 787        dprintk("vino_prepare_user_buffer():\n");
 788
 789        if (size < 1)
 790                return -EINVAL;
 791
 792        memset(fb, 0, sizeof(struct vino_framebuffer));
 793
 794        count = ((size / PAGE_SIZE)) & ~3;
 795
 796        dprintk("vino_prepare_user_buffer(): size = %d, count = %d\n",
 797                size, count);
 798
 799        /* allocate memory for table with virtual (page) addresses */
 800        fb->desc_table.virtual = (unsigned long *)
 801                kmalloc(count * sizeof(unsigned long), GFP_KERNEL);
 802        if (!fb->desc_table.virtual)
 803                return -ENOMEM;
 804
 805        /* allocate memory for table with dma addresses
 806         * (has space for four extra descriptors) */
 807        fb->desc_table.dma_cpu =
 808                dma_alloc_coherent(NULL, VINO_PAGE_RATIO * (count + 4) *
 809                                   sizeof(dma_addr_t), &fb->desc_table.dma,
 810                                   GFP_KERNEL | GFP_DMA);
 811        if (!fb->desc_table.dma_cpu) {
 812                ret = -ENOMEM;
 813                goto out_free_virtual;
 814        }
 815
 816        /* allocate pages for the buffer and acquire the according
 817         * dma addresses */
 818        for (i = 0; i < count; i++) {
 819                dma_addr_t dma_data_addr;
 820
 821                fb->desc_table.virtual[i] =
 822                        get_zeroed_page(GFP_KERNEL | GFP_DMA);
 823                if (!fb->desc_table.virtual[i]) {
 824                        ret = -ENOBUFS;
 825                        break;
 826                }
 827
 828                dma_data_addr =
 829                        dma_map_single(NULL,
 830                                       (void *)fb->desc_table.virtual[i],
 831                                       PAGE_SIZE, DMA_FROM_DEVICE);
 832
 833                for (j = 0; j < VINO_PAGE_RATIO; j++) {
 834                        fb->desc_table.dma_cpu[VINO_PAGE_RATIO * i + j] =
 835                                dma_data_addr + VINO_PAGE_SIZE * j;
 836                }
 837
 838                SetPageReserved(virt_to_page((void *)fb->desc_table.virtual[i]));
 839        }
 840
 841        /* page_count needs to be set anyway, because the descriptor table has
 842         * been allocated according to this number */
 843        fb->desc_table.page_count = count;
 844
 845        if (ret) {
 846                /* the descriptor with index i doesn't contain
 847                 * a valid address yet */
 848                vino_free_buffer_with_count(fb, i);
 849                return ret;
 850        }
 851
 852        //fb->size = size;
 853        fb->size = count * PAGE_SIZE;
 854
 855        /* set the dma stop-bit for the last (count+1)th descriptor */
 856        fb->desc_table.dma_cpu[VINO_PAGE_RATIO * count] = VINO_DESC_STOP;
 857        return 0;
 858
 859 out_free_virtual:
 860        kfree(fb->desc_table.virtual);
 861        return ret;
 862}
 863#endif
 864
 865static void vino_sync_buffer(struct vino_framebuffer *fb)
 866{
 867        int i;
 868
 869        dprintk("vino_sync_buffer():\n");
 870
 871        for (i = 0; i < fb->desc_table.page_count; i++)
 872                dma_sync_single_for_cpu(NULL,
 873                                        fb->desc_table.dma_cpu[VINO_PAGE_RATIO * i],
 874                                        PAGE_SIZE, DMA_FROM_DEVICE);
 875}
 876
 877/* Framebuffer fifo functions (need to be locked externally) */
 878
 879static inline void vino_fifo_init(struct vino_framebuffer_fifo *f,
 880                           unsigned int length)
 881{
 882        f->length = 0;
 883        f->used = 0;
 884        f->head = 0;
 885        f->tail = 0;
 886
 887        if (length > VINO_FRAMEBUFFER_COUNT_MAX)
 888                length = VINO_FRAMEBUFFER_COUNT_MAX;
 889
 890        f->length = length;
 891}
 892
 893/* returns true/false */
 894static inline int vino_fifo_has_id(struct vino_framebuffer_fifo *f,
 895                                   unsigned int id)
 896{
 897        unsigned int i;
 898
 899        for (i = f->head; i == (f->tail - 1); i = (i + 1) % f->length) {
 900                if (f->data[i] == id)
 901                        return 1;
 902        }
 903
 904        return 0;
 905}
 906
 907#if 0
 908/* returns true/false */
 909static inline int vino_fifo_full(struct vino_framebuffer_fifo *f)
 910{
 911        return (f->used == f->length);
 912}
 913#endif
 914
 915static inline unsigned int vino_fifo_get_used(struct vino_framebuffer_fifo *f)
 916{
 917        return f->used;
 918}
 919
 920static int vino_fifo_enqueue(struct vino_framebuffer_fifo *f, unsigned int id)
 921{
 922        if (id >= f->length) {
 923                return VINO_QUEUE_ERROR;
 924        }
 925
 926        if (vino_fifo_has_id(f, id)) {
 927                return VINO_QUEUE_ERROR;
 928        }
 929
 930        if (f->used < f->length) {
 931                f->data[f->tail] = id;
 932                f->tail = (f->tail + 1) % f->length;
 933                f->used++;
 934        } else {
 935                return VINO_QUEUE_ERROR;
 936        }
 937
 938        return 0;
 939}
 940
 941static int vino_fifo_peek(struct vino_framebuffer_fifo *f, unsigned int *id)
 942{
 943        if (f->used > 0) {
 944                *id = f->data[f->head];
 945        } else {
 946                return VINO_QUEUE_ERROR;
 947        }
 948
 949        return 0;
 950}
 951
 952static int vino_fifo_dequeue(struct vino_framebuffer_fifo *f, unsigned int *id)
 953{
 954        if (f->used > 0) {
 955                *id = f->data[f->head];
 956                f->head = (f->head + 1) % f->length;
 957                f->used--;
 958        } else {
 959                return VINO_QUEUE_ERROR;
 960        }
 961
 962        return 0;
 963}
 964
 965/* Framebuffer queue functions */
 966
 967/* execute with queue_lock locked */
 968static void vino_queue_free_with_count(struct vino_framebuffer_queue *q,
 969                                       unsigned int length)
 970{
 971        unsigned int i;
 972
 973        q->length = 0;
 974        memset(&q->in, 0, sizeof(struct vino_framebuffer_fifo));
 975        memset(&q->out, 0, sizeof(struct vino_framebuffer_fifo));
 976        for (i = 0; i < length; i++) {
 977                dprintk("vino_queue_free_with_count(): freeing buffer %d\n",
 978                        i);
 979                vino_free_buffer(q->buffer[i]);
 980                kfree(q->buffer[i]);
 981        }
 982
 983        q->type = VINO_MEMORY_NONE;
 984        q->magic = 0;
 985}
 986
 987static void vino_queue_free(struct vino_framebuffer_queue *q)
 988{
 989        dprintk("vino_queue_free():\n");
 990
 991        if (q->magic != VINO_QUEUE_MAGIC)
 992                return;
 993        if (q->type != VINO_MEMORY_MMAP)
 994                return;
 995
 996        mutex_lock(&q->queue_mutex);
 997
 998        vino_queue_free_with_count(q, q->length);
 999
1000        mutex_unlock(&q->queue_mutex);
1001}
1002
1003static int vino_queue_init(struct vino_framebuffer_queue *q,
1004                           unsigned int *length)
1005{
1006        unsigned int i;
1007        int ret = 0;
1008
1009        dprintk("vino_queue_init(): length = %d\n", *length);
1010
1011        if (q->magic == VINO_QUEUE_MAGIC) {
1012                dprintk("vino_queue_init(): queue already initialized!\n");
1013                return -EINVAL;
1014        }
1015
1016        if (q->type != VINO_MEMORY_NONE) {
1017                dprintk("vino_queue_init(): queue already initialized!\n");
1018                return -EINVAL;
1019        }
1020
1021        if (*length < 1)
1022                return -EINVAL;
1023
1024        mutex_lock(&q->queue_mutex);
1025
1026        if (*length > VINO_FRAMEBUFFER_COUNT_MAX)
1027                *length = VINO_FRAMEBUFFER_COUNT_MAX;
1028
1029        q->length = 0;
1030
1031        for (i = 0; i < *length; i++) {
1032                dprintk("vino_queue_init(): allocating buffer %d\n", i);
1033                q->buffer[i] = kmalloc(sizeof(struct vino_framebuffer),
1034                                       GFP_KERNEL);
1035                if (!q->buffer[i]) {
1036                        dprintk("vino_queue_init(): kmalloc() failed\n");
1037                        ret = -ENOMEM;
1038                        break;
1039                }
1040
1041                ret = vino_allocate_buffer(q->buffer[i],
1042                                           VINO_FRAMEBUFFER_SIZE);
1043                if (ret) {
1044                        kfree(q->buffer[i]);
1045                        dprintk("vino_queue_init(): "
1046                                "vino_allocate_buffer() failed\n");
1047                        break;
1048                }
1049
1050                q->buffer[i]->id = i;
1051                if (i > 0) {
1052                        q->buffer[i]->offset = q->buffer[i - 1]->offset +
1053                                q->buffer[i - 1]->size;
1054                } else {
1055                        q->buffer[i]->offset = 0;
1056                }
1057
1058                spin_lock_init(&q->buffer[i]->state_lock);
1059
1060                dprintk("vino_queue_init(): buffer = %d, offset = %d, "
1061                        "size = %d\n", i, q->buffer[i]->offset,
1062                        q->buffer[i]->size);
1063        }
1064
1065        if (ret) {
1066                vino_queue_free_with_count(q, i);
1067                *length = 0;
1068        } else {
1069                q->length = *length;
1070                vino_fifo_init(&q->in, q->length);
1071                vino_fifo_init(&q->out, q->length);
1072                q->type = VINO_MEMORY_MMAP;
1073                q->magic = VINO_QUEUE_MAGIC;
1074        }
1075
1076        mutex_unlock(&q->queue_mutex);
1077
1078        return ret;
1079}
1080
1081static struct vino_framebuffer *vino_queue_add(struct
1082                                               vino_framebuffer_queue *q,
1083                                               unsigned int id)
1084{
1085        struct vino_framebuffer *ret = NULL;
1086        unsigned int total;
1087        unsigned long flags;
1088
1089        dprintk("vino_queue_add(): id = %d\n", id);
1090
1091        if (q->magic != VINO_QUEUE_MAGIC) {
1092                return ret;
1093        }
1094
1095        spin_lock_irqsave(&q->queue_lock, flags);
1096
1097        if (q->length == 0)
1098                goto out;
1099
1100        if (id >= q->length)
1101                goto out;
1102
1103        /* not needed?: if (vino_fifo_full(&q->out)) {
1104                goto out;
1105                }*/
1106        /* check that outgoing queue isn't already full
1107         * (or that it won't become full) */
1108        total = vino_fifo_get_used(&q->in) +
1109                vino_fifo_get_used(&q->out);
1110        if (total >= q->length)
1111                goto out;
1112
1113        if (vino_fifo_enqueue(&q->in, id))
1114                goto out;
1115
1116        ret = q->buffer[id];
1117
1118out:
1119        spin_unlock_irqrestore(&q->queue_lock, flags);
1120
1121        return ret;
1122}
1123
1124static struct vino_framebuffer *vino_queue_transfer(struct
1125                                                    vino_framebuffer_queue *q)
1126{
1127        struct vino_framebuffer *ret = NULL;
1128        struct vino_framebuffer *fb;
1129        int id;
1130        unsigned long flags;
1131
1132        dprintk("vino_queue_transfer():\n");
1133
1134        if (q->magic != VINO_QUEUE_MAGIC) {
1135                return ret;
1136        }
1137
1138        spin_lock_irqsave(&q->queue_lock, flags);
1139
1140        if (q->length == 0)
1141                goto out;
1142
1143        // now this actually removes an entry from the incoming queue
1144        if (vino_fifo_dequeue(&q->in, &id)) {
1145                goto out;
1146        }
1147
1148        dprintk("vino_queue_transfer(): id = %d\n", id);
1149        fb = q->buffer[id];
1150
1151        // we have already checked that the outgoing queue is not full, but...
1152        if (vino_fifo_enqueue(&q->out, id)) {
1153                printk(KERN_ERR "vino_queue_transfer(): "
1154                       "outgoing queue is full, this shouldn't happen!\n");
1155                goto out;
1156        }
1157
1158        ret = fb;
1159out:
1160        spin_unlock_irqrestore(&q->queue_lock, flags);
1161
1162        return ret;
1163}
1164
1165/* returns true/false */
1166static int vino_queue_incoming_contains(struct vino_framebuffer_queue *q,
1167                                        unsigned int id)
1168{
1169        int ret = 0;
1170        unsigned long flags;
1171
1172        if (q->magic != VINO_QUEUE_MAGIC) {
1173                return ret;
1174        }
1175
1176        spin_lock_irqsave(&q->queue_lock, flags);
1177
1178        if (q->length == 0)
1179                goto out;
1180
1181        ret = vino_fifo_has_id(&q->in, id);
1182
1183out:
1184        spin_unlock_irqrestore(&q->queue_lock, flags);
1185
1186        return ret;
1187}
1188
1189/* returns true/false */
1190static int vino_queue_outgoing_contains(struct vino_framebuffer_queue *q,
1191                                        unsigned int id)
1192{
1193        int ret = 0;
1194        unsigned long flags;
1195
1196        if (q->magic != VINO_QUEUE_MAGIC) {
1197                return ret;
1198        }
1199
1200        spin_lock_irqsave(&q->queue_lock, flags);
1201
1202        if (q->length == 0)
1203                goto out;
1204
1205        ret = vino_fifo_has_id(&q->out, id);
1206
1207out:
1208        spin_unlock_irqrestore(&q->queue_lock, flags);
1209
1210        return ret;
1211}
1212
1213static int vino_queue_get_incoming(struct vino_framebuffer_queue *q,
1214                                   unsigned int *used)
1215{
1216        int ret = 0;
1217        unsigned long flags;
1218
1219        if (q->magic != VINO_QUEUE_MAGIC) {
1220                return VINO_QUEUE_ERROR;
1221        }
1222
1223        spin_lock_irqsave(&q->queue_lock, flags);
1224
1225        if (q->length == 0) {
1226                ret = VINO_QUEUE_ERROR;
1227                goto out;
1228        }
1229
1230        *used = vino_fifo_get_used(&q->in);
1231
1232out:
1233        spin_unlock_irqrestore(&q->queue_lock, flags);
1234
1235        return ret;
1236}
1237
1238static int vino_queue_get_outgoing(struct vino_framebuffer_queue *q,
1239                                   unsigned int *used)
1240{
1241        int ret = 0;
1242        unsigned long flags;
1243
1244        if (q->magic != VINO_QUEUE_MAGIC) {
1245                return VINO_QUEUE_ERROR;
1246        }
1247
1248        spin_lock_irqsave(&q->queue_lock, flags);
1249
1250        if (q->length == 0) {
1251                ret = VINO_QUEUE_ERROR;
1252                goto out;
1253        }
1254
1255        *used = vino_fifo_get_used(&q->out);
1256
1257out:
1258        spin_unlock_irqrestore(&q->queue_lock, flags);
1259
1260        return ret;
1261}
1262
1263#if 0
1264static int vino_queue_get_total(struct vino_framebuffer_queue *q,
1265                                unsigned int *total)
1266{
1267        int ret = 0;
1268        unsigned long flags;
1269
1270        if (q->magic != VINO_QUEUE_MAGIC) {
1271                return VINO_QUEUE_ERROR;
1272        }
1273
1274        spin_lock_irqsave(&q->queue_lock, flags);
1275
1276        if (q->length == 0) {
1277                ret = VINO_QUEUE_ERROR;
1278                goto out;
1279        }
1280
1281        *total = vino_fifo_get_used(&q->in) +
1282                vino_fifo_get_used(&q->out);
1283
1284out:
1285        spin_unlock_irqrestore(&q->queue_lock, flags);
1286
1287        return ret;
1288}
1289#endif
1290
1291static struct vino_framebuffer *vino_queue_peek(struct
1292                                                vino_framebuffer_queue *q,
1293                                                unsigned int *id)
1294{
1295        struct vino_framebuffer *ret = NULL;
1296        unsigned long flags;
1297
1298        if (q->magic != VINO_QUEUE_MAGIC) {
1299                return ret;
1300        }
1301
1302        spin_lock_irqsave(&q->queue_lock, flags);
1303
1304        if (q->length == 0)
1305                goto out;
1306
1307        if (vino_fifo_peek(&q->in, id)) {
1308                goto out;
1309        }
1310
1311        ret = q->buffer[*id];
1312out:
1313        spin_unlock_irqrestore(&q->queue_lock, flags);
1314
1315        return ret;
1316}
1317
1318static struct vino_framebuffer *vino_queue_remove(struct
1319                                                  vino_framebuffer_queue *q,
1320                                                  unsigned int *id)
1321{
1322        struct vino_framebuffer *ret = NULL;
1323        unsigned long flags;
1324        dprintk("vino_queue_remove():\n");
1325
1326        if (q->magic != VINO_QUEUE_MAGIC) {
1327                return ret;
1328        }
1329
1330        spin_lock_irqsave(&q->queue_lock, flags);
1331
1332        if (q->length == 0)
1333                goto out;
1334
1335        if (vino_fifo_dequeue(&q->out, id)) {
1336                goto out;
1337        }
1338
1339        dprintk("vino_queue_remove(): id = %d\n", *id);
1340        ret = q->buffer[*id];
1341out:
1342        spin_unlock_irqrestore(&q->queue_lock, flags);
1343
1344        return ret;
1345}
1346
1347static struct
1348vino_framebuffer *vino_queue_get_buffer(struct vino_framebuffer_queue *q,
1349                                        unsigned int id)
1350{
1351        struct vino_framebuffer *ret = NULL;
1352        unsigned long flags;
1353
1354        if (q->magic != VINO_QUEUE_MAGIC) {
1355                return ret;
1356        }
1357
1358        spin_lock_irqsave(&q->queue_lock, flags);
1359
1360        if (q->length == 0)
1361                goto out;
1362
1363        if (id >= q->length)
1364                goto out;
1365
1366        ret = q->buffer[id];
1367 out:
1368        spin_unlock_irqrestore(&q->queue_lock, flags);
1369
1370        return ret;
1371}
1372
1373static unsigned int vino_queue_get_length(struct vino_framebuffer_queue *q)
1374{
1375        unsigned int length = 0;
1376        unsigned long flags;
1377
1378        if (q->magic != VINO_QUEUE_MAGIC) {
1379                return length;
1380        }
1381
1382        spin_lock_irqsave(&q->queue_lock, flags);
1383        length = q->length;
1384        spin_unlock_irqrestore(&q->queue_lock, flags);
1385
1386        return length;
1387}
1388
1389static int vino_queue_has_mapped_buffers(struct vino_framebuffer_queue *q)
1390{
1391        unsigned int i;
1392        int ret = 0;
1393        unsigned long flags;
1394
1395        if (q->magic != VINO_QUEUE_MAGIC) {
1396                return ret;
1397        }
1398
1399        spin_lock_irqsave(&q->queue_lock, flags);
1400        for (i = 0; i < q->length; i++) {
1401                if (q->buffer[i]->map_count > 0) {
1402                        ret = 1;
1403                        break;
1404                }
1405        }
1406        spin_unlock_irqrestore(&q->queue_lock, flags);
1407
1408        return ret;
1409}
1410
1411/* VINO functions */
1412
1413/* execute with input_lock locked */
1414static void vino_update_line_size(struct vino_channel_settings *vcs)
1415{
1416        unsigned int w = vcs->clipping.right - vcs->clipping.left;
1417        unsigned int d = vcs->decimation;
1418        unsigned int bpp = vino_data_formats[vcs->data_format].bpp;
1419        unsigned int lsize;
1420
1421        dprintk("update_line_size(): before: w = %d, d = %d, "
1422                "line_size = %d\n", w, d, vcs->line_size);
1423
1424        /* line size must be multiple of 8 bytes */
1425        lsize = (bpp * (w / d)) & ~7;
1426        w = (lsize / bpp) * d;
1427
1428        vcs->clipping.right = vcs->clipping.left + w;
1429        vcs->line_size = lsize;
1430
1431        dprintk("update_line_size(): after: w = %d, d = %d, "
1432                "line_size = %d\n", w, d, vcs->line_size);
1433}
1434
1435/* execute with input_lock locked */
1436static void vino_set_clipping(struct vino_channel_settings *vcs,
1437                              unsigned int x, unsigned int y,
1438                              unsigned int w, unsigned int h)
1439{
1440        unsigned int maxwidth, maxheight;
1441        unsigned int d;
1442
1443        maxwidth = vino_data_norms[vcs->data_norm].width;
1444        maxheight = vino_data_norms[vcs->data_norm].height;
1445        d = vcs->decimation;
1446
1447        y &= ~1;        /* odd/even fields */
1448
1449        if (x > maxwidth) {
1450                x = 0;
1451        }
1452        if (y > maxheight) {
1453                y = 0;
1454        }
1455
1456        if (((w / d) < VINO_MIN_WIDTH)
1457            || ((h / d) < VINO_MIN_HEIGHT)) {
1458                w = VINO_MIN_WIDTH * d;
1459                h = VINO_MIN_HEIGHT * d;
1460        }
1461
1462        if ((x + w) > maxwidth) {
1463                w = maxwidth - x;
1464                if ((w / d) < VINO_MIN_WIDTH)
1465                        x = maxwidth - VINO_MIN_WIDTH * d;
1466        }
1467        if ((y + h) > maxheight) {
1468                h = maxheight - y;
1469                if ((h / d) < VINO_MIN_HEIGHT)
1470                        y = maxheight - VINO_MIN_HEIGHT * d;
1471        }
1472
1473        vcs->clipping.left = x;
1474        vcs->clipping.top = y;
1475        vcs->clipping.right = x + w;
1476        vcs->clipping.bottom = y + h;
1477
1478        vino_update_line_size(vcs);
1479
1480        dprintk("clipping %d, %d, %d, %d / %d - %d\n",
1481                vcs->clipping.left, vcs->clipping.top, vcs->clipping.right,
1482                vcs->clipping.bottom, vcs->decimation, vcs->line_size);
1483}
1484
1485/* execute with input_lock locked */
1486static inline void vino_set_default_clipping(struct vino_channel_settings *vcs)
1487{
1488        vino_set_clipping(vcs, 0, 0, vino_data_norms[vcs->data_norm].width,
1489                          vino_data_norms[vcs->data_norm].height);
1490}
1491
1492/* execute with input_lock locked */
1493static void vino_set_scaling(struct vino_channel_settings *vcs,
1494                             unsigned int w, unsigned int h)
1495{
1496        unsigned int x, y, curw, curh, d;
1497
1498        x = vcs->clipping.left;
1499        y = vcs->clipping.top;
1500        curw = vcs->clipping.right - vcs->clipping.left;
1501        curh = vcs->clipping.bottom - vcs->clipping.top;
1502
1503        d = max(curw / w, curh / h);
1504
1505        dprintk("scaling w: %d, h: %d, curw: %d, curh: %d, d: %d\n",
1506                w, h, curw, curh, d);
1507
1508        if (d < 1) {
1509                d = 1;
1510        } else if (d > 8) {
1511                d = 8;
1512        }
1513
1514        vcs->decimation = d;
1515        vino_set_clipping(vcs, x, y, w * d, h * d);
1516
1517        dprintk("scaling %d, %d, %d, %d / %d - %d\n", vcs->clipping.left,
1518                vcs->clipping.top, vcs->clipping.right, vcs->clipping.bottom,
1519                vcs->decimation, vcs->line_size);
1520}
1521
1522/* execute with input_lock locked */
1523static inline void vino_set_default_scaling(struct vino_channel_settings *vcs)
1524{
1525        vino_set_scaling(vcs, vcs->clipping.right - vcs->clipping.left,
1526                         vcs->clipping.bottom - vcs->clipping.top);
1527}
1528
1529/* execute with input_lock locked */
1530static void vino_set_framerate(struct vino_channel_settings *vcs,
1531                               unsigned int fps)
1532{
1533        unsigned int mask;
1534
1535        switch (vcs->data_norm) {
1536        case VINO_DATA_NORM_NTSC:
1537        case VINO_DATA_NORM_D1:
1538                fps = (unsigned int)(fps / 6) * 6; // FIXME: round!
1539
1540                if (fps < vino_data_norms[vcs->data_norm].fps_min)
1541                        fps = vino_data_norms[vcs->data_norm].fps_min;
1542                if (fps > vino_data_norms[vcs->data_norm].fps_max)
1543                        fps = vino_data_norms[vcs->data_norm].fps_max;
1544
1545                switch (fps) {
1546                case 6:
1547                        mask = 0x003;
1548                        break;
1549                case 12:
1550                        mask = 0x0c3;
1551                        break;
1552                case 18:
1553                        mask = 0x333;
1554                        break;
1555                case 24:
1556                        mask = 0x3ff;
1557                        break;
1558                case 30:
1559                        mask = 0xfff;
1560                        break;
1561                default:
1562                        mask = VINO_FRAMERT_FULL;
1563                }
1564                vcs->framert_reg = VINO_FRAMERT_RT(mask);
1565                break;
1566        case VINO_DATA_NORM_PAL:
1567        case VINO_DATA_NORM_SECAM:
1568                fps = (unsigned int)(fps / 5) * 5; // FIXME: round!
1569
1570                if (fps < vino_data_norms[vcs->data_norm].fps_min)
1571                        fps = vino_data_norms[vcs->data_norm].fps_min;
1572                if (fps > vino_data_norms[vcs->data_norm].fps_max)
1573                        fps = vino_data_norms[vcs->data_norm].fps_max;
1574
1575                switch (fps) {
1576                case 5:
1577                        mask = 0x003;
1578                        break;
1579                case 10:
1580                        mask = 0x0c3;
1581                        break;
1582                case 15:
1583                        mask = 0x333;
1584                        break;
1585                case 20:
1586                        mask = 0x0ff;
1587                        break;
1588                case 25:
1589                        mask = 0x3ff;
1590                        break;
1591                default:
1592                        mask = VINO_FRAMERT_FULL;
1593                }
1594                vcs->framert_reg = VINO_FRAMERT_RT(mask) | VINO_FRAMERT_PAL;
1595                break;
1596        }
1597
1598        vcs->fps = fps;
1599}
1600
1601/* execute with input_lock locked */
1602static inline void vino_set_default_framerate(struct
1603                                              vino_channel_settings *vcs)
1604{
1605        vino_set_framerate(vcs, vino_data_norms[vcs->data_norm].fps_max);
1606}
1607
1608/* VINO I2C bus functions */
1609
1610struct i2c_algo_sgi_data {
1611        void *data;     /* private data for lowlevel routines */
1612        unsigned (*getctrl)(void *data);
1613        void (*setctrl)(void *data, unsigned val);
1614        unsigned (*rdata)(void *data);
1615        void (*wdata)(void *data, unsigned val);
1616
1617        int xfer_timeout;
1618        int ack_timeout;
1619};
1620
1621static int wait_xfer_done(struct i2c_algo_sgi_data *adap)
1622{
1623        int i;
1624
1625        for (i = 0; i < adap->xfer_timeout; i++) {
1626                if ((adap->getctrl(adap->data) & SGI_I2C_XFER_BUSY) == 0)
1627                        return 0;
1628                udelay(1);
1629        }
1630
1631        return -ETIMEDOUT;
1632}
1633
1634static int wait_ack(struct i2c_algo_sgi_data *adap)
1635{
1636        int i;
1637
1638        if (wait_xfer_done(adap))
1639                return -ETIMEDOUT;
1640        for (i = 0; i < adap->ack_timeout; i++) {
1641                if ((adap->getctrl(adap->data) & SGI_I2C_NACK) == 0)
1642                        return 0;
1643                udelay(1);
1644        }
1645
1646        return -ETIMEDOUT;
1647}
1648
1649static int force_idle(struct i2c_algo_sgi_data *adap)
1650{
1651        int i;
1652
1653        adap->setctrl(adap->data, SGI_I2C_FORCE_IDLE);
1654        for (i = 0; i < adap->xfer_timeout; i++) {
1655                if ((adap->getctrl(adap->data) & SGI_I2C_NOT_IDLE) == 0)
1656                        goto out;
1657                udelay(1);
1658        }
1659        return -ETIMEDOUT;
1660out:
1661        if (adap->getctrl(adap->data) & SGI_I2C_BUS_ERR)
1662                return -EIO;
1663        return 0;
1664}
1665
1666static int do_address(struct i2c_algo_sgi_data *adap, unsigned int addr,
1667                      int rd)
1668{
1669        if (rd)
1670                adap->setctrl(adap->data, SGI_I2C_NOT_IDLE);
1671        /* Check if bus is idle, eventually force it to do so */
1672        if (adap->getctrl(adap->data) & SGI_I2C_NOT_IDLE)
1673                if (force_idle(adap))
1674                        return -EIO;
1675        /* Write out the i2c chip address and specify operation */
1676        adap->setctrl(adap->data,
1677                      SGI_I2C_HOLD_BUS | SGI_I2C_WRITE | SGI_I2C_NOT_IDLE);
1678        if (rd)
1679                addr |= 1;
1680        adap->wdata(adap->data, addr);
1681        if (wait_ack(adap))
1682                return -EIO;
1683        return 0;
1684}
1685
1686static int i2c_read(struct i2c_algo_sgi_data *adap, unsigned char *buf,
1687                    unsigned int len)
1688{
1689        int i;
1690
1691        adap->setctrl(adap->data,
1692                      SGI_I2C_HOLD_BUS | SGI_I2C_READ | SGI_I2C_NOT_IDLE);
1693        for (i = 0; i < len; i++) {
1694                if (wait_xfer_done(adap))
1695                        return -EIO;
1696                buf[i] = adap->rdata(adap->data);
1697        }
1698        adap->setctrl(adap->data, SGI_I2C_RELEASE_BUS | SGI_I2C_FORCE_IDLE);
1699
1700        return 0;
1701
1702}
1703
1704static int i2c_write(struct i2c_algo_sgi_data *adap, unsigned char *buf,
1705                     unsigned int len)
1706{
1707        int i;
1708
1709        /* We are already in write state */
1710        for (i = 0; i < len; i++) {
1711                adap->wdata(adap->data, buf[i]);
1712                if (wait_ack(adap))
1713                        return -EIO;
1714        }
1715        return 0;
1716}
1717
1718static int sgi_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs,
1719                    int num)
1720{
1721        struct i2c_algo_sgi_data *adap = i2c_adap->algo_data;
1722        struct i2c_msg *p;
1723        int i, err = 0;
1724
1725        for (i = 0; !err && i < num; i++) {
1726                p = &msgs[i];
1727                err = do_address(adap, p->addr, p->flags & I2C_M_RD);
1728                if (err || !p->len)
1729                        continue;
1730                if (p->flags & I2C_M_RD)
1731                        err = i2c_read(adap, p->buf, p->len);
1732                else
1733                        err = i2c_write(adap, p->buf, p->len);
1734        }
1735
1736        return (err < 0) ? err : i;
1737}
1738
1739static u32 sgi_func(struct i2c_adapter *adap)
1740{
1741        return I2C_FUNC_SMBUS_EMUL;
1742}
1743
1744static const struct i2c_algorithm sgi_algo = {
1745        .master_xfer    = sgi_xfer,
1746        .functionality  = sgi_func,
1747};
1748
1749static unsigned i2c_vino_getctrl(void *data)
1750{
1751        return vino->i2c_control;
1752}
1753
1754static void i2c_vino_setctrl(void *data, unsigned val)
1755{
1756        vino->i2c_control = val;
1757}
1758
1759static unsigned i2c_vino_rdata(void *data)
1760{
1761        return vino->i2c_data;
1762}
1763
1764static void i2c_vino_wdata(void *data, unsigned val)
1765{
1766        vino->i2c_data = val;
1767}
1768
1769static struct i2c_algo_sgi_data i2c_sgi_vino_data = {
1770        .getctrl = &i2c_vino_getctrl,
1771        .setctrl = &i2c_vino_setctrl,
1772        .rdata   = &i2c_vino_rdata,
1773        .wdata   = &i2c_vino_wdata,
1774        .xfer_timeout = 200,
1775        .ack_timeout  = 1000,
1776};
1777
1778static struct i2c_adapter vino_i2c_adapter = {
1779        .name                   = "VINO I2C bus",
1780        .algo                   = &sgi_algo,
1781        .algo_data              = &i2c_sgi_vino_data,
1782        .owner                  = THIS_MODULE,
1783};
1784
1785/*
1786 * Prepare VINO for DMA transfer...
1787 * (execute only with vino_lock and input_lock locked)
1788 */
1789static int vino_dma_setup(struct vino_channel_settings *vcs,
1790                          struct vino_framebuffer *fb)
1791{
1792        u32 ctrl, intr;
1793        struct sgi_vino_channel *ch;
1794        const struct vino_data_norm *norm;
1795
1796        dprintk("vino_dma_setup():\n");
1797
1798        vcs->field = 0;
1799        fb->frame_counter = 0;
1800
1801        ch = (vcs->channel == VINO_CHANNEL_A) ? &vino->a : &vino->b;
1802        norm = &vino_data_norms[vcs->data_norm];
1803
1804        ch->page_index = 0;
1805        ch->line_count = 0;
1806
1807        /* VINO line size register is set 8 bytes less than actual */
1808        ch->line_size = vcs->line_size - 8;
1809
1810        /* let VINO know where to transfer data */
1811        ch->start_desc_tbl = fb->desc_table.dma;
1812        ch->next_4_desc = fb->desc_table.dma;
1813
1814        /* give vino time to fetch the first four descriptors, 5 usec
1815         * should be more than enough time */
1816        udelay(VINO_DESC_FETCH_DELAY);
1817
1818        dprintk("vino_dma_setup(): start desc = %08x, next 4 desc = %08x\n",
1819                ch->start_desc_tbl, ch->next_4_desc);
1820
1821        /* set the alpha register */
1822        ch->alpha = vcs->alpha;
1823
1824        /* set clipping registers */
1825        ch->clip_start = VINO_CLIP_ODD(norm->odd.top + vcs->clipping.top / 2) |
1826                VINO_CLIP_EVEN(norm->even.top +
1827                               vcs->clipping.top / 2) |
1828                VINO_CLIP_X(vcs->clipping.left);
1829        ch->clip_end = VINO_CLIP_ODD(norm->odd.top +
1830                                     vcs->clipping.bottom / 2 - 1) |
1831                VINO_CLIP_EVEN(norm->even.top +
1832                               vcs->clipping.bottom / 2 - 1) |
1833                VINO_CLIP_X(vcs->clipping.right);
1834
1835        /* set the size of actual content in the buffer (DECIMATION !) */
1836        fb->data_size = ((vcs->clipping.right - vcs->clipping.left) /
1837                         vcs->decimation) *
1838                ((vcs->clipping.bottom - vcs->clipping.top) /
1839                 vcs->decimation) *
1840                vino_data_formats[vcs->data_format].bpp;
1841
1842        ch->frame_rate = vcs->framert_reg;
1843
1844        ctrl = vino->control;
1845        intr = vino->intr_status;
1846
1847        if (vcs->channel == VINO_CHANNEL_A) {
1848                /* All interrupt conditions for this channel was cleared
1849                 * so clear the interrupt status register and enable
1850                 * interrupts */
1851                intr &= ~VINO_INTSTAT_A;
1852                ctrl |= VINO_CTRL_A_INT;
1853
1854                /* enable synchronization */
1855                ctrl |= VINO_CTRL_A_SYNC_ENBL;
1856
1857                /* enable frame assembly */
1858                ctrl |= VINO_CTRL_A_INTERLEAVE_ENBL;
1859
1860                /* set decimation used */
1861                if (vcs->decimation < 2)
1862                        ctrl &= ~VINO_CTRL_A_DEC_ENBL;
1863                else {
1864                        ctrl |= VINO_CTRL_A_DEC_ENBL;
1865                        ctrl &= ~VINO_CTRL_A_DEC_SCALE_MASK;
1866                        ctrl |= (vcs->decimation - 1) <<
1867                                VINO_CTRL_A_DEC_SCALE_SHIFT;
1868                }
1869
1870                /* select input interface */
1871                if (vcs->input == VINO_INPUT_D1)
1872                        ctrl |= VINO_CTRL_A_SELECT;
1873                else
1874                        ctrl &= ~VINO_CTRL_A_SELECT;
1875
1876                /* palette */
1877                ctrl &= ~(VINO_CTRL_A_LUMA_ONLY | VINO_CTRL_A_RGB |
1878                          VINO_CTRL_A_DITHER);
1879        } else {
1880                intr &= ~VINO_INTSTAT_B;
1881                ctrl |= VINO_CTRL_B_INT;
1882
1883                ctrl |= VINO_CTRL_B_SYNC_ENBL;
1884                ctrl |= VINO_CTRL_B_INTERLEAVE_ENBL;
1885
1886                if (vcs->decimation < 2)
1887                        ctrl &= ~VINO_CTRL_B_DEC_ENBL;
1888                else {
1889                        ctrl |= VINO_CTRL_B_DEC_ENBL;
1890                        ctrl &= ~VINO_CTRL_B_DEC_SCALE_MASK;
1891                        ctrl |= (vcs->decimation - 1) <<
1892                                VINO_CTRL_B_DEC_SCALE_SHIFT;
1893
1894                }
1895                if (vcs->input == VINO_INPUT_D1)
1896                        ctrl |= VINO_CTRL_B_SELECT;
1897                else
1898                        ctrl &= ~VINO_CTRL_B_SELECT;
1899
1900                ctrl &= ~(VINO_CTRL_B_LUMA_ONLY | VINO_CTRL_B_RGB |
1901                          VINO_CTRL_B_DITHER);
1902        }
1903
1904        /* set palette */
1905        fb->data_format = vcs->data_format;
1906
1907        switch (vcs->data_format) {
1908                case VINO_DATA_FMT_GREY:
1909                        ctrl |= (vcs->channel == VINO_CHANNEL_A) ?
1910                                VINO_CTRL_A_LUMA_ONLY : VINO_CTRL_B_LUMA_ONLY;
1911                        break;
1912                case VINO_DATA_FMT_RGB32:
1913                        ctrl |= (vcs->channel == VINO_CHANNEL_A) ?
1914                                VINO_CTRL_A_RGB : VINO_CTRL_B_RGB;
1915                        break;
1916                case VINO_DATA_FMT_YUV:
1917                        /* nothing needs to be done */
1918                        break;
1919                case VINO_DATA_FMT_RGB332:
1920                        ctrl |= (vcs->channel == VINO_CHANNEL_A) ?
1921                                VINO_CTRL_A_RGB | VINO_CTRL_A_DITHER :
1922                                VINO_CTRL_B_RGB | VINO_CTRL_B_DITHER;
1923                        break;
1924        }
1925
1926        vino->intr_status = intr;
1927        vino->control = ctrl;
1928
1929        return 0;
1930}
1931
1932/* (execute only with vino_lock locked) */
1933static inline void vino_dma_start(struct vino_channel_settings *vcs)
1934{
1935        u32 ctrl = vino->control;
1936
1937        dprintk("vino_dma_start():\n");
1938        ctrl |= (vcs->channel == VINO_CHANNEL_A) ?
1939                VINO_CTRL_A_DMA_ENBL : VINO_CTRL_B_DMA_ENBL;
1940        vino->control = ctrl;
1941}
1942
1943/* (execute only with vino_lock locked) */
1944static inline void vino_dma_stop(struct vino_channel_settings *vcs)
1945{
1946        u32 ctrl = vino->control;
1947
1948        ctrl &= (vcs->channel == VINO_CHANNEL_A) ?
1949                ~VINO_CTRL_A_DMA_ENBL : ~VINO_CTRL_B_DMA_ENBL;
1950        ctrl &= (vcs->channel == VINO_CHANNEL_A) ?
1951                ~VINO_CTRL_A_INT : ~VINO_CTRL_B_INT;
1952        vino->control = ctrl;
1953        dprintk("vino_dma_stop():\n");
1954}
1955
1956/*
1957 * Load dummy page to descriptor registers. This prevents generating of
1958 * spurious interrupts. (execute only with vino_lock locked)
1959 */
1960static void vino_clear_interrupt(struct vino_channel_settings *vcs)
1961{
1962        struct sgi_vino_channel *ch;
1963
1964        ch = (vcs->channel == VINO_CHANNEL_A) ? &vino->a : &vino->b;
1965
1966        ch->page_index = 0;
1967        ch->line_count = 0;
1968
1969        ch->start_desc_tbl = vino_drvdata->dummy_desc_table.dma;
1970        ch->next_4_desc = vino_drvdata->dummy_desc_table.dma;
1971
1972        udelay(VINO_DESC_FETCH_DELAY);
1973        dprintk("channel %c clear interrupt condition\n",
1974               (vcs->channel == VINO_CHANNEL_A) ? 'A':'B');
1975}
1976
1977static int vino_capture(struct vino_channel_settings *vcs,
1978                        struct vino_framebuffer *fb)
1979{
1980        int err = 0;
1981        unsigned long flags, flags2;
1982
1983        spin_lock_irqsave(&fb->state_lock, flags);
1984
1985        if (fb->state == VINO_FRAMEBUFFER_IN_USE)
1986                err = -EBUSY;
1987        fb->state = VINO_FRAMEBUFFER_IN_USE;
1988
1989        spin_unlock_irqrestore(&fb->state_lock, flags);
1990
1991        if (err)
1992                return err;
1993
1994        spin_lock_irqsave(&vino_drvdata->vino_lock, flags);
1995        spin_lock_irqsave(&vino_drvdata->input_lock, flags2);
1996
1997        vino_dma_setup(vcs, fb);
1998        vino_dma_start(vcs);
1999
2000        spin_unlock_irqrestore(&vino_drvdata->input_lock, flags2);
2001        spin_unlock_irqrestore(&vino_drvdata->vino_lock, flags);
2002
2003        return err;
2004}
2005
2006static
2007struct vino_framebuffer *vino_capture_enqueue(struct
2008                                              vino_channel_settings *vcs,
2009                                              unsigned int index)
2010{
2011        struct vino_framebuffer *fb;
2012        unsigned long flags;
2013
2014        dprintk("vino_capture_enqueue():\n");
2015
2016        spin_lock_irqsave(&vcs->capture_lock, flags);
2017
2018        fb = vino_queue_add(&vcs->fb_queue, index);
2019        if (fb == NULL) {
2020                dprintk("vino_capture_enqueue(): vino_queue_add() failed, "
2021                        "queue full?\n");
2022                goto out;
2023        }
2024out:
2025        spin_unlock_irqrestore(&vcs->capture_lock, flags);
2026
2027        return fb;
2028}
2029
2030static int vino_capture_next(struct vino_channel_settings *vcs, int start)
2031{
2032        struct vino_framebuffer *fb;
2033        unsigned int incoming, id;
2034        int err = 0;
2035        unsigned long flags;
2036
2037        dprintk("vino_capture_next():\n");
2038
2039        spin_lock_irqsave(&vcs->capture_lock, flags);
2040
2041        if (start) {
2042                /* start capture only if capture isn't in progress already */
2043                if (vcs->capturing) {
2044                        spin_unlock_irqrestore(&vcs->capture_lock, flags);
2045                        return 0;
2046                }
2047
2048        } else {
2049                /* capture next frame:
2050                 * stop capture if capturing is not set */
2051                if (!vcs->capturing) {
2052                        spin_unlock_irqrestore(&vcs->capture_lock, flags);
2053                        return 0;
2054                }
2055        }
2056
2057        err = vino_queue_get_incoming(&vcs->fb_queue, &incoming);
2058        if (err) {
2059                dprintk("vino_capture_next(): vino_queue_get_incoming() "
2060                        "failed\n");
2061                err = -EINVAL;
2062                goto out;
2063        }
2064        if (incoming == 0) {
2065                dprintk("vino_capture_next(): no buffers available\n");
2066                goto out;
2067        }
2068
2069        fb = vino_queue_peek(&vcs->fb_queue, &id);
2070        if (fb == NULL) {
2071                dprintk("vino_capture_next(): vino_queue_peek() failed\n");
2072                err = -EINVAL;
2073                goto out;
2074        }
2075
2076        if (start) {
2077                vcs->capturing = 1;
2078        }
2079
2080        spin_unlock_irqrestore(&vcs->capture_lock, flags);
2081
2082        err = vino_capture(vcs, fb);
2083
2084        return err;
2085
2086out:
2087        vcs->capturing = 0;
2088        spin_unlock_irqrestore(&vcs->capture_lock, flags);
2089
2090        return err;
2091}
2092
2093static inline int vino_is_capturing(struct vino_channel_settings *vcs)
2094{
2095        int ret;
2096        unsigned long flags;
2097
2098        spin_lock_irqsave(&vcs->capture_lock, flags);
2099
2100        ret = vcs->capturing;
2101
2102        spin_unlock_irqrestore(&vcs->capture_lock, flags);
2103
2104        return ret;
2105}
2106
2107/* waits until a frame is captured */
2108static int vino_wait_for_frame(struct vino_channel_settings *vcs)
2109{
2110        wait_queue_t wait;
2111        int err = 0;
2112
2113        dprintk("vino_wait_for_frame():\n");
2114
2115        init_waitqueue_entry(&wait, current);
2116        /* add ourselves into wait queue */
2117        add_wait_queue(&vcs->fb_queue.frame_wait_queue, &wait);
2118
2119        /* to ensure that schedule_timeout will return immediately
2120         * if VINO interrupt was triggered meanwhile */
2121        schedule_timeout_interruptible(msecs_to_jiffies(100));
2122
2123        if (signal_pending(current))
2124                err = -EINTR;
2125
2126        remove_wait_queue(&vcs->fb_queue.frame_wait_queue, &wait);
2127
2128        dprintk("vino_wait_for_frame(): waiting for frame %s\n",
2129                err ? "failed" : "ok");
2130
2131        return err;
2132}
2133
2134/* the function assumes that PAGE_SIZE % 4 == 0 */
2135static void vino_convert_to_rgba(struct vino_framebuffer *fb) {
2136        unsigned char *pageptr;
2137        unsigned int page, i;
2138        unsigned char a;
2139
2140        for (page = 0; page < fb->desc_table.page_count; page++) {
2141                pageptr = (unsigned char *)fb->desc_table.virtual[page];
2142
2143                for (i = 0; i < PAGE_SIZE; i += 4) {
2144                        a = pageptr[0];
2145                        pageptr[0] = pageptr[3];
2146                        pageptr[1] = pageptr[2];
2147                        pageptr[2] = pageptr[1];
2148                        pageptr[3] = a;
2149                        pageptr += 4;
2150                }
2151        }
2152}
2153
2154/* checks if the buffer is in correct state and syncs data */
2155static int vino_check_buffer(struct vino_channel_settings *vcs,
2156                             struct vino_framebuffer *fb)
2157{
2158        int err = 0;
2159        unsigned long flags;
2160
2161        dprintk("vino_check_buffer():\n");
2162
2163        spin_lock_irqsave(&fb->state_lock, flags);
2164        switch (fb->state) {
2165        case VINO_FRAMEBUFFER_IN_USE:
2166                err = -EIO;
2167                break;
2168        case VINO_FRAMEBUFFER_READY:
2169                vino_sync_buffer(fb);
2170                fb->state = VINO_FRAMEBUFFER_UNUSED;
2171                break;
2172        default:
2173                err = -EINVAL;
2174        }
2175        spin_unlock_irqrestore(&fb->state_lock, flags);
2176
2177        if (!err) {
2178                if (vino_pixel_conversion
2179                    && (fb->data_format == VINO_DATA_FMT_RGB32)) {
2180                        vino_convert_to_rgba(fb);
2181                }
2182        } else if (err && (err != -EINVAL)) {
2183                dprintk("vino_check_buffer(): buffer not ready\n");
2184
2185                spin_lock_irqsave(&vino_drvdata->vino_lock, flags);
2186                vino_dma_stop(vcs);
2187                vino_clear_interrupt(vcs);
2188                spin_unlock_irqrestore(&vino_drvdata->vino_lock, flags);
2189        }
2190
2191        return err;
2192}
2193
2194/* forcefully terminates capture */
2195static void vino_capture_stop(struct vino_channel_settings *vcs)
2196{
2197        unsigned int incoming = 0, outgoing = 0, id;
2198        unsigned long flags, flags2;
2199
2200        dprintk("vino_capture_stop():\n");
2201
2202        spin_lock_irqsave(&vcs->capture_lock, flags);
2203
2204        /* unset capturing to stop queue processing */
2205        vcs->capturing = 0;
2206
2207        spin_lock_irqsave(&vino_drvdata->vino_lock, flags2);
2208
2209        vino_dma_stop(vcs);
2210        vino_clear_interrupt(vcs);
2211
2212        spin_unlock_irqrestore(&vino_drvdata->vino_lock, flags2);
2213
2214        /* remove all items from the queue */
2215        if (vino_queue_get_incoming(&vcs->fb_queue, &incoming)) {
2216                dprintk("vino_capture_stop(): "
2217                        "vino_queue_get_incoming() failed\n");
2218                goto out;
2219        }
2220        while (incoming > 0) {
2221                vino_queue_transfer(&vcs->fb_queue);
2222
2223                if (vino_queue_get_incoming(&vcs->fb_queue, &incoming)) {
2224                        dprintk("vino_capture_stop(): "
2225                                "vino_queue_get_incoming() failed\n");
2226                        goto out;
2227                }
2228        }
2229
2230        if (vino_queue_get_outgoing(&vcs->fb_queue, &outgoing)) {
2231                dprintk("vino_capture_stop(): "
2232                        "vino_queue_get_outgoing() failed\n");
2233                goto out;
2234        }
2235        while (outgoing > 0) {
2236                vino_queue_remove(&vcs->fb_queue, &id);
2237
2238                if (vino_queue_get_outgoing(&vcs->fb_queue, &outgoing)) {
2239                        dprintk("vino_capture_stop(): "
2240                                "vino_queue_get_outgoing() failed\n");
2241                        goto out;
2242                }
2243        }
2244
2245out:
2246        spin_unlock_irqrestore(&vcs->capture_lock, flags);
2247}
2248
2249#if 0
2250static int vino_capture_failed(struct vino_channel_settings *vcs)
2251{
2252        struct vino_framebuffer *fb;
2253        unsigned long flags;
2254        unsigned int i;
2255        int ret;
2256
2257        dprintk("vino_capture_failed():\n");
2258
2259        spin_lock_irqsave(&vino_drvdata->vino_lock, flags);
2260
2261        vino_dma_stop(vcs);
2262        vino_clear_interrupt(vcs);
2263
2264        spin_unlock_irqrestore(&vino_drvdata->vino_lock, flags);
2265
2266        ret = vino_queue_get_incoming(&vcs->fb_queue, &i);
2267        if (ret == VINO_QUEUE_ERROR) {
2268                dprintk("vino_queue_get_incoming() failed\n");
2269                return -EINVAL;
2270        }
2271        if (i == 0) {
2272                /* no buffers to process */
2273                return 0;
2274        }
2275
2276        fb = vino_queue_peek(&vcs->fb_queue, &i);
2277        if (fb == NULL) {
2278                dprintk("vino_queue_peek() failed\n");
2279                return -EINVAL;
2280        }
2281
2282        spin_lock_irqsave(&fb->state_lock, flags);
2283        if (fb->state == VINO_FRAMEBUFFER_IN_USE) {
2284                fb->state = VINO_FRAMEBUFFER_UNUSED;
2285                vino_queue_transfer(&vcs->fb_queue);
2286                vino_queue_remove(&vcs->fb_queue, &i);
2287                /* we should actually discard the newest frame,
2288                 * but who cares ... */
2289        }
2290        spin_unlock_irqrestore(&fb->state_lock, flags);
2291
2292        return 0;
2293}
2294#endif
2295
2296static void vino_skip_frame(struct vino_channel_settings *vcs)
2297{
2298        struct vino_framebuffer *fb;
2299        unsigned long flags;
2300        unsigned int id;
2301
2302        spin_lock_irqsave(&vcs->capture_lock, flags);
2303        fb = vino_queue_peek(&vcs->fb_queue, &id);
2304        if (!fb) {
2305                spin_unlock_irqrestore(&vcs->capture_lock, flags);
2306                dprintk("vino_skip_frame(): vino_queue_peek() failed!\n");
2307                return;
2308        }
2309        spin_unlock_irqrestore(&vcs->capture_lock, flags);
2310
2311        spin_lock_irqsave(&fb->state_lock, flags);
2312        fb->state = VINO_FRAMEBUFFER_UNUSED;
2313        spin_unlock_irqrestore(&fb->state_lock, flags);
2314
2315        vino_capture_next(vcs, 0);
2316}
2317
2318static void vino_frame_done(struct vino_channel_settings *vcs)
2319{
2320        struct vino_framebuffer *fb;
2321        unsigned long flags;
2322
2323        spin_lock_irqsave(&vcs->capture_lock, flags);
2324        fb = vino_queue_transfer(&vcs->fb_queue);
2325        if (!fb) {
2326                spin_unlock_irqrestore(&vcs->capture_lock, flags);
2327                dprintk("vino_frame_done(): vino_queue_transfer() failed!\n");
2328                return;
2329        }
2330        spin_unlock_irqrestore(&vcs->capture_lock, flags);
2331
2332        fb->frame_counter = vcs->int_data.frame_counter;
2333        memcpy(&fb->timestamp, &vcs->int_data.timestamp,
2334               sizeof(struct timeval));
2335
2336        spin_lock_irqsave(&fb->state_lock, flags);
2337        if (fb->state == VINO_FRAMEBUFFER_IN_USE)
2338                fb->state = VINO_FRAMEBUFFER_READY;
2339        spin_unlock_irqrestore(&fb->state_lock, flags);
2340
2341        wake_up(&vcs->fb_queue.frame_wait_queue);
2342
2343        vino_capture_next(vcs, 0);
2344}
2345
2346static void vino_capture_tasklet(unsigned long channel) {
2347        struct vino_channel_settings *vcs;
2348
2349        vcs = (channel == VINO_CHANNEL_A)
2350                ? &vino_drvdata->a : &vino_drvdata->b;
2351
2352        if (vcs->int_data.skip)
2353                vcs->int_data.skip_count++;
2354
2355        if (vcs->int_data.skip && (vcs->int_data.skip_count
2356                                   <= VINO_MAX_FRAME_SKIP_COUNT)) {
2357                vino_skip_frame(vcs);
2358        } else {
2359                vcs->int_data.skip_count = 0;
2360                vino_frame_done(vcs);
2361        }
2362}
2363
2364static irqreturn_t vino_interrupt(int irq, void *dev_id)
2365{
2366        u32 ctrl, intr;
2367        unsigned int fc_a, fc_b;
2368        int handled_a = 0, skip_a = 0, done_a = 0;
2369        int handled_b = 0, skip_b = 0, done_b = 0;
2370
2371#ifdef VINO_DEBUG_INT
2372        int loop = 0;
2373        unsigned int line_count = vino->a.line_count,
2374                page_index = vino->a.page_index,
2375                field_counter = vino->a.field_counter,
2376                start_desc_tbl = vino->a.start_desc_tbl,
2377                next_4_desc = vino->a.next_4_desc;
2378        unsigned int line_count_2,
2379                page_index_2,
2380                field_counter_2,
2381                start_desc_tbl_2,
2382                next_4_desc_2;
2383#endif
2384
2385        spin_lock(&vino_drvdata->vino_lock);
2386
2387        while ((intr = vino->intr_status)) {
2388                fc_a = vino->a.field_counter >> 1;
2389                fc_b = vino->b.field_counter >> 1;
2390
2391                /* handle error-interrupts in some special way ?
2392                 * --> skips frames */
2393                if (intr & VINO_INTSTAT_A) {
2394                        if (intr & VINO_INTSTAT_A_EOF) {
2395                                vino_drvdata->a.field++;
2396                                if (vino_drvdata->a.field > 1) {
2397                                        vino_dma_stop(&vino_drvdata->a);
2398                                        vino_clear_interrupt(&vino_drvdata->a);
2399                                        vino_drvdata->a.field = 0;
2400                                        done_a = 1;
2401                                } else {
2402                                        if (vino->a.page_index
2403                                            != vino_drvdata->a.line_size) {
2404                                                vino->a.line_count = 0;
2405                                                vino->a.page_index =
2406                                                        vino_drvdata->
2407                                                        a.line_size;
2408                                                vino->a.next_4_desc =
2409                                                        vino->a.start_desc_tbl;
2410                                        }
2411                                }
2412                                dprintk("channel A end-of-field "
2413                                        "interrupt: %04x\n", intr);
2414                        } else {
2415                                vino_dma_stop(&vino_drvdata->a);
2416                                vino_clear_interrupt(&vino_drvdata->a);
2417                                vino_drvdata->a.field = 0;
2418                                skip_a = 1;
2419                                dprintk("channel A error interrupt: %04x\n",
2420                                        intr);
2421                        }
2422
2423#ifdef VINO_DEBUG_INT
2424                        line_count_2 = vino->a.line_count;
2425                        page_index_2 = vino->a.page_index;
2426                        field_counter_2 = vino->a.field_counter;
2427                        start_desc_tbl_2 = vino->a.start_desc_tbl;
2428                        next_4_desc_2 = vino->a.next_4_desc;
2429
2430                        printk("intr = %04x, loop = %d, field = %d\n",
2431                               intr, loop, vino_drvdata->a.field);
2432                        printk("1- line count = %04d, page index = %04d, "
2433                               "start = %08x, next = %08x\n"
2434                               "   fieldc = %d, framec = %d\n",
2435                               line_count, page_index, start_desc_tbl,
2436                               next_4_desc, field_counter, fc_a);
2437                        printk("12-line count = %04d, page index = %04d, "
2438                               "   start = %08x, next = %08x\n",
2439                               line_count_2, page_index_2, start_desc_tbl_2,
2440                               next_4_desc_2);
2441
2442                        if (done_a)
2443                                printk("\n");
2444#endif
2445                }
2446
2447                if (intr & VINO_INTSTAT_B) {
2448                        if (intr & VINO_INTSTAT_B_EOF) {
2449                                vino_drvdata->b.field++;
2450                                if (vino_drvdata->b.field > 1) {
2451                                        vino_dma_stop(&vino_drvdata->b);
2452                                        vino_clear_interrupt(&vino_drvdata->b);
2453                                        vino_drvdata->b.field = 0;
2454                                        done_b = 1;
2455                                }
2456                                dprintk("channel B end-of-field "
2457                                        "interrupt: %04x\n", intr);
2458                        } else {
2459                                vino_dma_stop(&vino_drvdata->b);
2460                                vino_clear_interrupt(&vino_drvdata->b);
2461                                vino_drvdata->b.field = 0;
2462                                skip_b = 1;
2463                                dprintk("channel B error interrupt: %04x\n",
2464                                        intr);
2465                        }
2466                }
2467
2468                /* Always remember to clear interrupt status.
2469                 * Disable VINO interrupts while we do this. */
2470                ctrl = vino->control;
2471                vino->control = ctrl & ~(VINO_CTRL_A_INT | VINO_CTRL_B_INT);
2472                vino->intr_status = ~intr;
2473                vino->control = ctrl;
2474
2475                spin_unlock(&vino_drvdata->vino_lock);
2476
2477                if ((!handled_a) && (done_a || skip_a)) {
2478                        if (!skip_a) {
2479                                do_gettimeofday(&vino_drvdata->
2480                                                a.int_data.timestamp);
2481                                vino_drvdata->a.int_data.frame_counter = fc_a;
2482                        }
2483                        vino_drvdata->a.int_data.skip = skip_a;
2484
2485                        dprintk("channel A %s, interrupt: %d\n",
2486                                skip_a ? "skipping frame" : "frame done",
2487                                intr);
2488                        tasklet_hi_schedule(&vino_tasklet_a);
2489                        handled_a = 1;
2490                }
2491
2492                if ((!handled_b) && (done_b || skip_b)) {
2493                        if (!skip_b) {
2494                                do_gettimeofday(&vino_drvdata->
2495                                                b.int_data.timestamp);
2496                                vino_drvdata->b.int_data.frame_counter = fc_b;
2497                        }
2498                        vino_drvdata->b.int_data.skip = skip_b;
2499
2500                        dprintk("channel B %s, interrupt: %d\n",
2501                                skip_b ? "skipping frame" : "frame done",
2502                                intr);
2503                        tasklet_hi_schedule(&vino_tasklet_b);
2504                        handled_b = 1;
2505                }
2506
2507#ifdef VINO_DEBUG_INT
2508                loop++;
2509#endif
2510                spin_lock(&vino_drvdata->vino_lock);
2511        }
2512
2513        spin_unlock(&vino_drvdata->vino_lock);
2514
2515        return IRQ_HANDLED;
2516}
2517
2518/* VINO video input management */
2519
2520static int vino_get_saa7191_input(int input)
2521{
2522        switch (input) {
2523        case VINO_INPUT_COMPOSITE:
2524                return SAA7191_INPUT_COMPOSITE;
2525        case VINO_INPUT_SVIDEO:
2526                return SAA7191_INPUT_SVIDEO;
2527        default:
2528                printk(KERN_ERR "VINO: vino_get_saa7191_input(): "
2529                       "invalid input!\n");
2530                return -1;
2531        }
2532}
2533
2534/* execute with input_lock locked */
2535static int vino_is_input_owner(struct vino_channel_settings *vcs)
2536{
2537        switch(vcs->input) {
2538        case VINO_INPUT_COMPOSITE:
2539        case VINO_INPUT_SVIDEO:
2540                return vino_drvdata->decoder_owner == vcs->channel;
2541        case VINO_INPUT_D1:
2542                return vino_drvdata->camera_owner == vcs->channel;
2543        default:
2544                return 0;
2545        }
2546}
2547
2548static int vino_acquire_input(struct vino_channel_settings *vcs)
2549{
2550        unsigned long flags;
2551        int ret = 0;
2552
2553        dprintk("vino_acquire_input():\n");
2554
2555        spin_lock_irqsave(&vino_drvdata->input_lock, flags);
2556
2557        /* First try D1 and then SAA7191 */
2558        if (vino_drvdata->camera
2559            && (vino_drvdata->camera_owner == VINO_NO_CHANNEL)) {
2560                vino_drvdata->camera_owner = vcs->channel;
2561                vcs->input = VINO_INPUT_D1;
2562                vcs->data_norm = VINO_DATA_NORM_D1;
2563        } else if (vino_drvdata->decoder
2564                   && (vino_drvdata->decoder_owner == VINO_NO_CHANNEL)) {
2565                int input;
2566                int data_norm;
2567                v4l2_std_id norm;
2568
2569                input = VINO_INPUT_COMPOSITE;
2570
2571                ret = decoder_call(video, s_routing,
2572                                vino_get_saa7191_input(input), 0, 0);
2573                if (ret) {
2574                        ret = -EINVAL;
2575                        goto out;
2576                }
2577
2578                spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
2579
2580                /* Don't hold spinlocks while auto-detecting norm
2581                 * as it may take a while... */
2582
2583                ret = decoder_call(video, querystd, &norm);
2584                if (!ret) {
2585                        for (data_norm = 0; data_norm < 3; data_norm++) {
2586                                if (vino_data_norms[data_norm].std & norm)
2587                                        break;
2588                        }
2589                        if (data_norm == 3)
2590                                data_norm = VINO_DATA_NORM_PAL;
2591                        ret = decoder_call(core, s_std, norm);
2592                }
2593
2594                spin_lock_irqsave(&vino_drvdata->input_lock, flags);
2595
2596                if (ret) {
2597                        ret = -EINVAL;
2598                        goto out;
2599                }
2600
2601                vino_drvdata->decoder_owner = vcs->channel;
2602
2603                vcs->input = input;
2604                vcs->data_norm = data_norm;
2605        } else {
2606                vcs->input = (vcs->channel == VINO_CHANNEL_A) ?
2607                        vino_drvdata->b.input : vino_drvdata->a.input;
2608                vcs->data_norm = (vcs->channel == VINO_CHANNEL_A) ?
2609                        vino_drvdata->b.data_norm : vino_drvdata->a.data_norm;
2610        }
2611
2612        if (vcs->input == VINO_INPUT_NONE) {
2613                ret = -ENODEV;
2614                goto out;
2615        }
2616
2617        vino_set_default_clipping(vcs);
2618        vino_set_default_scaling(vcs);
2619        vino_set_default_framerate(vcs);
2620
2621        dprintk("vino_acquire_input(): %s\n", vino_inputs[vcs->input].name);
2622
2623out:
2624        spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
2625
2626        return ret;
2627}
2628
2629static int vino_set_input(struct vino_channel_settings *vcs, int input)
2630{
2631        struct vino_channel_settings *vcs2 = (vcs->channel == VINO_CHANNEL_A) ?
2632                &vino_drvdata->b : &vino_drvdata->a;
2633        unsigned long flags;
2634        int ret = 0;
2635
2636        dprintk("vino_set_input():\n");
2637
2638        spin_lock_irqsave(&vino_drvdata->input_lock, flags);
2639
2640        if (vcs->input == input)
2641                goto out;
2642
2643        switch (input) {
2644        case VINO_INPUT_COMPOSITE:
2645        case VINO_INPUT_SVIDEO:
2646                if (!vino_drvdata->decoder) {
2647                        ret = -EINVAL;
2648                        goto out;
2649                }
2650
2651                if (vino_drvdata->decoder_owner == VINO_NO_CHANNEL) {
2652                        vino_drvdata->decoder_owner = vcs->channel;
2653                }
2654
2655                if (vino_drvdata->decoder_owner == vcs->channel) {
2656                        int data_norm;
2657                        v4l2_std_id norm;
2658
2659                        ret = decoder_call(video, s_routing,
2660                                        vino_get_saa7191_input(input), 0, 0);
2661                        if (ret) {
2662                                vino_drvdata->decoder_owner = VINO_NO_CHANNEL;
2663                                ret = -EINVAL;
2664                                goto out;
2665                        }
2666
2667                        spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
2668
2669                        /* Don't hold spinlocks while auto-detecting norm
2670                         * as it may take a while... */
2671
2672                        ret = decoder_call(video, querystd, &norm);
2673                        if (!ret) {
2674                                for (data_norm = 0; data_norm < 3; data_norm++) {
2675                                        if (vino_data_norms[data_norm].std & norm)
2676                                                break;
2677                                }
2678                                if (data_norm == 3)
2679                                        data_norm = VINO_DATA_NORM_PAL;
2680                                ret = decoder_call(core, s_std, norm);
2681                        }
2682
2683                        spin_lock_irqsave(&vino_drvdata->input_lock, flags);
2684
2685                        if (ret) {
2686                                vino_drvdata->decoder_owner = VINO_NO_CHANNEL;
2687                                ret = -EINVAL;
2688                                goto out;
2689                        }
2690
2691                        vcs->input = input;
2692                        vcs->data_norm = data_norm;
2693                } else {
2694                        if (input != vcs2->input) {
2695                                ret = -EBUSY;
2696                                goto out;
2697                        }
2698
2699                        vcs->input = input;
2700                        vcs->data_norm = vcs2->data_norm;
2701                }
2702
2703                if (vino_drvdata->camera_owner == vcs->channel) {
2704                        /* Transfer the ownership or release the input */
2705                        if (vcs2->input == VINO_INPUT_D1) {
2706                                vino_drvdata->camera_owner = vcs2->channel;
2707                        } else {
2708                                vino_drvdata->camera_owner = VINO_NO_CHANNEL;
2709                        }
2710                }
2711                break;
2712        case VINO_INPUT_D1:
2713                if (!vino_drvdata->camera) {
2714                        ret = -EINVAL;
2715                        goto out;
2716                }
2717
2718                if (vino_drvdata->camera_owner == VINO_NO_CHANNEL)
2719                        vino_drvdata->camera_owner = vcs->channel;
2720
2721                if (vino_drvdata->decoder_owner == vcs->channel) {
2722                        /* Transfer the ownership or release the input */
2723                        if ((vcs2->input == VINO_INPUT_COMPOSITE) ||
2724                                 (vcs2->input == VINO_INPUT_SVIDEO)) {
2725                                vino_drvdata->decoder_owner = vcs2->channel;
2726                        } else {
2727                                vino_drvdata->decoder_owner = VINO_NO_CHANNEL;
2728                        }
2729                }
2730
2731                vcs->input = input;
2732                vcs->data_norm = VINO_DATA_NORM_D1;
2733                break;
2734        default:
2735                ret = -EINVAL;
2736                goto out;
2737        }
2738
2739        vino_set_default_clipping(vcs);
2740        vino_set_default_scaling(vcs);
2741        vino_set_default_framerate(vcs);
2742
2743        dprintk("vino_set_input(): %s\n", vino_inputs[vcs->input].name);
2744
2745out:
2746        spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
2747
2748        return ret;
2749}
2750
2751static void vino_release_input(struct vino_channel_settings *vcs)
2752{
2753        struct vino_channel_settings *vcs2 = (vcs->channel == VINO_CHANNEL_A) ?
2754                &vino_drvdata->b : &vino_drvdata->a;
2755        unsigned long flags;
2756
2757        dprintk("vino_release_input():\n");
2758
2759        spin_lock_irqsave(&vino_drvdata->input_lock, flags);
2760
2761        /* Release ownership of the channel
2762         * and if the other channel takes input from
2763         * the same source, transfer the ownership */
2764        if (vino_drvdata->camera_owner == vcs->channel) {
2765                if (vcs2->input == VINO_INPUT_D1) {
2766                        vino_drvdata->camera_owner = vcs2->channel;
2767                } else {
2768                        vino_drvdata->camera_owner = VINO_NO_CHANNEL;
2769                }
2770        } else if (vino_drvdata->decoder_owner == vcs->channel) {
2771                if ((vcs2->input == VINO_INPUT_COMPOSITE) ||
2772                         (vcs2->input == VINO_INPUT_SVIDEO)) {
2773                        vino_drvdata->decoder_owner = vcs2->channel;
2774                } else {
2775                        vino_drvdata->decoder_owner = VINO_NO_CHANNEL;
2776                }
2777        }
2778        vcs->input = VINO_INPUT_NONE;
2779
2780        spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
2781}
2782
2783/* execute with input_lock locked */
2784static int vino_set_data_norm(struct vino_channel_settings *vcs,
2785                              unsigned int data_norm,
2786                              unsigned long *flags)
2787{
2788        int err = 0;
2789
2790        if (data_norm == vcs->data_norm)
2791                return 0;
2792
2793        switch (vcs->input) {
2794        case VINO_INPUT_D1:
2795                /* only one "norm" supported */
2796                if (data_norm != VINO_DATA_NORM_D1)
2797                        return -EINVAL;
2798                break;
2799        case VINO_INPUT_COMPOSITE:
2800        case VINO_INPUT_SVIDEO: {
2801                v4l2_std_id norm;
2802
2803                if ((data_norm != VINO_DATA_NORM_PAL)
2804                    && (data_norm != VINO_DATA_NORM_NTSC)
2805                    && (data_norm != VINO_DATA_NORM_SECAM))
2806                        return -EINVAL;
2807
2808                spin_unlock_irqrestore(&vino_drvdata->input_lock, *flags);
2809
2810                /* Don't hold spinlocks while setting norm
2811                 * as it may take a while... */
2812
2813                norm = vino_data_norms[data_norm].std;
2814                err = decoder_call(core, s_std, norm);
2815
2816                spin_lock_irqsave(&vino_drvdata->input_lock, *flags);
2817
2818                if (err)
2819                        goto out;
2820
2821                vcs->data_norm = data_norm;
2822
2823                vino_set_default_clipping(vcs);
2824                vino_set_default_scaling(vcs);
2825                vino_set_default_framerate(vcs);
2826                break;
2827        }
2828        default:
2829                return -EINVAL;
2830        }
2831
2832out:
2833        return err;
2834}
2835
2836/* V4L2 helper functions */
2837
2838static int vino_find_data_format(__u32 pixelformat)
2839{
2840        int i;
2841
2842        for (i = 0; i < VINO_DATA_FMT_COUNT; i++) {
2843                if (vino_data_formats[i].pixelformat == pixelformat)
2844                        return i;
2845        }
2846
2847        return VINO_DATA_FMT_NONE;
2848}
2849
2850static int vino_int_enum_input(struct vino_channel_settings *vcs, __u32 index)
2851{
2852        int input = VINO_INPUT_NONE;
2853        unsigned long flags;
2854
2855        spin_lock_irqsave(&vino_drvdata->input_lock, flags);
2856        if (vino_drvdata->decoder && vino_drvdata->camera) {
2857                switch (index) {
2858                case 0:
2859                        input = VINO_INPUT_COMPOSITE;
2860                        break;
2861                case 1:
2862                        input = VINO_INPUT_SVIDEO;
2863                        break;
2864                case 2:
2865                        input = VINO_INPUT_D1;
2866                        break;
2867                }
2868        } else if (vino_drvdata->decoder) {
2869                switch (index) {
2870                case 0:
2871                        input = VINO_INPUT_COMPOSITE;
2872                        break;
2873                case 1:
2874                        input = VINO_INPUT_SVIDEO;
2875                        break;
2876                }
2877        } else if (vino_drvdata->camera) {
2878                switch (index) {
2879                case 0:
2880                        input = VINO_INPUT_D1;
2881                        break;
2882                }
2883        }
2884        spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
2885
2886        return input;
2887}
2888
2889/* execute with input_lock locked */
2890static __u32 vino_find_input_index(struct vino_channel_settings *vcs)
2891{
2892        __u32 index = 0;
2893        // FIXME: detect when no inputs available
2894
2895        if (vino_drvdata->decoder && vino_drvdata->camera) {
2896                switch (vcs->input) {
2897                case VINO_INPUT_COMPOSITE:
2898                        index = 0;
2899                        break;
2900                case VINO_INPUT_SVIDEO:
2901                        index = 1;
2902                        break;
2903                case VINO_INPUT_D1:
2904                        index = 2;
2905                        break;
2906                }
2907        } else if (vino_drvdata->decoder) {
2908                switch (vcs->input) {
2909                case VINO_INPUT_COMPOSITE:
2910                        index = 0;
2911                        break;
2912                case VINO_INPUT_SVIDEO:
2913                        index = 1;
2914                        break;
2915                }
2916        } else if (vino_drvdata->camera) {
2917                switch (vcs->input) {
2918                case VINO_INPUT_D1:
2919                        index = 0;
2920                        break;
2921                }
2922        }
2923
2924        return index;
2925}
2926
2927/* V4L2 ioctls */
2928
2929static int vino_querycap(struct file *file, void *__fh,
2930                struct v4l2_capability *cap)
2931{
2932        memset(cap, 0, sizeof(struct v4l2_capability));
2933
2934        strcpy(cap->driver, vino_driver_name);
2935        strcpy(cap->card, vino_driver_description);
2936        strcpy(cap->bus_info, vino_bus_name);
2937        cap->version = VINO_VERSION_CODE;
2938        cap->capabilities =
2939                V4L2_CAP_VIDEO_CAPTURE |
2940                V4L2_CAP_STREAMING;
2941        // V4L2_CAP_OVERLAY, V4L2_CAP_READWRITE
2942        return 0;
2943}
2944
2945static int vino_enum_input(struct file *file, void *__fh,
2946                               struct v4l2_input *i)
2947{
2948        struct vino_channel_settings *vcs = video_drvdata(file);
2949        __u32 index = i->index;
2950        int input;
2951        dprintk("requested index = %d\n", index);
2952
2953        input = vino_int_enum_input(vcs, index);
2954        if (input == VINO_INPUT_NONE)
2955                return -EINVAL;
2956
2957        i->type = V4L2_INPUT_TYPE_CAMERA;
2958        i->std = vino_inputs[input].std;
2959        strcpy(i->name, vino_inputs[input].name);
2960
2961        if (input == VINO_INPUT_COMPOSITE || input == VINO_INPUT_SVIDEO)
2962                decoder_call(video, g_input_status, &i->status);
2963        return 0;
2964}
2965
2966static int vino_g_input(struct file *file, void *__fh,
2967                             unsigned int *i)
2968{
2969        struct vino_channel_settings *vcs = video_drvdata(file);
2970        __u32 index;
2971        int input;
2972        unsigned long flags;
2973
2974        spin_lock_irqsave(&vino_drvdata->input_lock, flags);
2975        input = vcs->input;
2976        index = vino_find_input_index(vcs);
2977        spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
2978
2979        dprintk("input = %d\n", input);
2980
2981        if (input == VINO_INPUT_NONE) {
2982                return -EINVAL;
2983        }
2984
2985        *i = index;
2986
2987        return 0;
2988}
2989
2990static int vino_s_input(struct file *file, void *__fh,
2991                             unsigned int i)
2992{
2993        struct vino_channel_settings *vcs = video_drvdata(file);
2994        int input;
2995        dprintk("requested input = %d\n", i);
2996
2997        input = vino_int_enum_input(vcs, i);
2998        if (input == VINO_INPUT_NONE)
2999                return -EINVAL;
3000
3001        return vino_set_input(vcs, input);
3002}
3003
3004static int vino_querystd(struct file *file, void *__fh,
3005                              v4l2_std_id *std)
3006{
3007        struct vino_channel_settings *vcs = video_drvdata(file);
3008        unsigned long flags;
3009        int err = 0;
3010
3011        spin_lock_irqsave(&vino_drvdata->input_lock, flags);
3012
3013        switch (vcs->input) {
3014        case VINO_INPUT_D1:
3015                *std = vino_inputs[vcs->input].std;
3016                break;
3017        case VINO_INPUT_COMPOSITE:
3018        case VINO_INPUT_SVIDEO: {
3019                decoder_call(video, querystd, std);
3020                break;
3021        }
3022        default:
3023                err = -EINVAL;
3024        }
3025
3026        spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3027
3028        return err;
3029}
3030
3031static int vino_g_std(struct file *file, void *__fh,
3032                           v4l2_std_id *std)
3033{
3034        struct vino_channel_settings *vcs = video_drvdata(file);
3035        unsigned long flags;
3036
3037        spin_lock_irqsave(&vino_drvdata->input_lock, flags);
3038
3039        *std = vino_data_norms[vcs->data_norm].std;
3040        dprintk("current standard = %d\n", vcs->data_norm);
3041
3042        spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3043
3044        return 0;
3045}
3046
3047static int vino_s_std(struct file *file, void *__fh,
3048                           v4l2_std_id *std)
3049{
3050        struct vino_channel_settings *vcs = video_drvdata(file);
3051        unsigned long flags;
3052        int ret = 0;
3053
3054        spin_lock_irqsave(&vino_drvdata->input_lock, flags);
3055
3056        if (!vino_is_input_owner(vcs)) {
3057                ret = -EBUSY;
3058                goto out;
3059        }
3060
3061        /* check if the standard is valid for the current input */
3062        if ((*std) & vino_inputs[vcs->input].std) {
3063                dprintk("standard accepted\n");
3064
3065                /* change the video norm for SAA7191
3066                 * and accept NTSC for D1 (do nothing) */
3067
3068                if (vcs->input == VINO_INPUT_D1)
3069                        goto out;
3070
3071                if ((*std) & V4L2_STD_PAL) {
3072                        ret = vino_set_data_norm(vcs, VINO_DATA_NORM_PAL,
3073                                                 &flags);
3074                } else if ((*std) & V4L2_STD_NTSC) {
3075                        ret = vino_set_data_norm(vcs, VINO_DATA_NORM_NTSC,
3076                                                 &flags);
3077                } else if ((*std) & V4L2_STD_SECAM) {
3078                        ret = vino_set_data_norm(vcs, VINO_DATA_NORM_SECAM,
3079                                                 &flags);
3080                } else {
3081                        ret = -EINVAL;
3082                }
3083
3084                if (ret) {
3085                        ret = -EINVAL;
3086                }
3087        } else {
3088                ret = -EINVAL;
3089        }
3090
3091out:
3092        spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3093
3094        return ret;
3095}
3096
3097static int vino_enum_fmt_vid_cap(struct file *file, void *__fh,
3098                              struct v4l2_fmtdesc *fd)
3099{
3100        dprintk("format index = %d\n", fd->index);
3101
3102        if (fd->index >= VINO_DATA_FMT_COUNT)
3103                return -EINVAL;
3104        dprintk("format name = %s\n", vino_data_formats[fd->index].description);
3105
3106        fd->pixelformat = vino_data_formats[fd->index].pixelformat;
3107        strcpy(fd->description, vino_data_formats[fd->index].description);
3108        return 0;
3109}
3110
3111static int vino_try_fmt_vid_cap(struct file *file, void *__fh,
3112                             struct v4l2_format *f)
3113{
3114        struct vino_channel_settings *vcs = video_drvdata(file);
3115        struct vino_channel_settings tempvcs;
3116        unsigned long flags;
3117        struct v4l2_pix_format *pf = &f->fmt.pix;
3118
3119        dprintk("requested: w = %d, h = %d\n",
3120                        pf->width, pf->height);
3121
3122        spin_lock_irqsave(&vino_drvdata->input_lock, flags);
3123        memcpy(&tempvcs, vcs, sizeof(struct vino_channel_settings));
3124        spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3125
3126        tempvcs.data_format = vino_find_data_format(pf->pixelformat);
3127        if (tempvcs.data_format == VINO_DATA_FMT_NONE) {
3128                tempvcs.data_format = VINO_DATA_FMT_GREY;
3129                pf->pixelformat =
3130                        vino_data_formats[tempvcs.data_format].
3131                        pixelformat;
3132        }
3133
3134        /* data format must be set before clipping/scaling */
3135        vino_set_scaling(&tempvcs, pf->width, pf->height);
3136
3137        dprintk("data format = %s\n",
3138                        vino_data_formats[tempvcs.data_format].description);
3139
3140        pf->width = (tempvcs.clipping.right - tempvcs.clipping.left) /
3141                tempvcs.decimation;
3142        pf->height = (tempvcs.clipping.bottom - tempvcs.clipping.top) /
3143                tempvcs.decimation;
3144
3145        pf->field = V4L2_FIELD_INTERLACED;
3146        pf->bytesperline = tempvcs.line_size;
3147        pf->sizeimage = tempvcs.line_size *
3148                (tempvcs.clipping.bottom - tempvcs.clipping.top) /
3149                tempvcs.decimation;
3150        pf->colorspace =
3151                vino_data_formats[tempvcs.data_format].colorspace;
3152
3153        pf->priv = 0;
3154        return 0;
3155}
3156
3157static int vino_g_fmt_vid_cap(struct file *file, void *__fh,
3158                           struct v4l2_format *f)
3159{
3160        struct vino_channel_settings *vcs = video_drvdata(file);
3161        unsigned long flags;
3162        struct v4l2_pix_format *pf = &f->fmt.pix;
3163
3164        spin_lock_irqsave(&vino_drvdata->input_lock, flags);
3165
3166        pf->width = (vcs->clipping.right - vcs->clipping.left) /
3167                vcs->decimation;
3168        pf->height = (vcs->clipping.bottom - vcs->clipping.top) /
3169                vcs->decimation;
3170        pf->pixelformat =
3171                vino_data_formats[vcs->data_format].pixelformat;
3172
3173        pf->field = V4L2_FIELD_INTERLACED;
3174        pf->bytesperline = vcs->line_size;
3175        pf->sizeimage = vcs->line_size *
3176                (vcs->clipping.bottom - vcs->clipping.top) /
3177                vcs->decimation;
3178        pf->colorspace =
3179                vino_data_formats[vcs->data_format].colorspace;
3180
3181        pf->priv = 0;
3182
3183        spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3184        return 0;
3185}
3186
3187static int vino_s_fmt_vid_cap(struct file *file, void *__fh,
3188                           struct v4l2_format *f)
3189{
3190        struct vino_channel_settings *vcs = video_drvdata(file);
3191        int data_format;
3192        unsigned long flags;
3193        struct v4l2_pix_format *pf = &f->fmt.pix;
3194
3195        spin_lock_irqsave(&vino_drvdata->input_lock, flags);
3196
3197        data_format = vino_find_data_format(pf->pixelformat);
3198
3199        if (data_format == VINO_DATA_FMT_NONE) {
3200                vcs->data_format = VINO_DATA_FMT_GREY;
3201                pf->pixelformat =
3202                        vino_data_formats[vcs->data_format].
3203                        pixelformat;
3204        } else {
3205                vcs->data_format = data_format;
3206        }
3207
3208        /* data format must be set before clipping/scaling */
3209        vino_set_scaling(vcs, pf->width, pf->height);
3210
3211        dprintk("data format = %s\n",
3212               vino_data_formats[vcs->data_format].description);
3213
3214        pf->width = vcs->clipping.right - vcs->clipping.left;
3215        pf->height = vcs->clipping.bottom - vcs->clipping.top;
3216
3217        pf->field = V4L2_FIELD_INTERLACED;
3218        pf->bytesperline = vcs->line_size;
3219        pf->sizeimage = vcs->line_size *
3220                (vcs->clipping.bottom - vcs->clipping.top) /
3221                vcs->decimation;
3222        pf->colorspace =
3223                vino_data_formats[vcs->data_format].colorspace;
3224
3225        pf->priv = 0;
3226
3227        spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3228        return 0;
3229}
3230
3231static int vino_cropcap(struct file *file, void *__fh,
3232                             struct v4l2_cropcap *ccap)
3233{
3234        struct vino_channel_settings *vcs = video_drvdata(file);
3235        const struct vino_data_norm *norm;
3236        unsigned long flags;
3237
3238        switch (ccap->type) {
3239        case V4L2_BUF_TYPE_VIDEO_CAPTURE:
3240                spin_lock_irqsave(&vino_drvdata->input_lock, flags);
3241
3242                norm = &vino_data_norms[vcs->data_norm];
3243
3244                spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3245
3246                ccap->bounds.left = 0;
3247                ccap->bounds.top = 0;
3248                ccap->bounds.width = norm->width;
3249                ccap->bounds.height = norm->height;
3250                memcpy(&ccap->defrect, &ccap->bounds,
3251                       sizeof(struct v4l2_rect));
3252
3253                ccap->pixelaspect.numerator = 1;
3254                ccap->pixelaspect.denominator = 1;
3255                break;
3256        case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3257        default:
3258                return -EINVAL;
3259        }
3260
3261        return 0;
3262}
3263
3264static int vino_g_crop(struct file *file, void *__fh,
3265                            struct v4l2_crop *c)
3266{
3267        struct vino_channel_settings *vcs = video_drvdata(file);
3268        unsigned long flags;
3269
3270        switch (c->type) {
3271        case V4L2_BUF_TYPE_VIDEO_CAPTURE:
3272                spin_lock_irqsave(&vino_drvdata->input_lock, flags);
3273
3274                c->c.left = vcs->clipping.left;
3275                c->c.top = vcs->clipping.top;
3276                c->c.width = vcs->clipping.right - vcs->clipping.left;
3277                c->c.height = vcs->clipping.bottom - vcs->clipping.top;
3278
3279                spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3280                break;
3281        case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3282        default:
3283                return -EINVAL;
3284        }
3285
3286        return 0;
3287}
3288
3289static int vino_s_crop(struct file *file, void *__fh,
3290                            struct v4l2_crop *c)
3291{
3292        struct vino_channel_settings *vcs = video_drvdata(file);
3293        unsigned long flags;
3294
3295        switch (c->type) {
3296        case V4L2_BUF_TYPE_VIDEO_CAPTURE:
3297                spin_lock_irqsave(&vino_drvdata->input_lock, flags);
3298
3299                vino_set_clipping(vcs, c->c.left, c->c.top,
3300                                  c->c.width, c->c.height);
3301
3302                spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3303                break;
3304        case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3305        default:
3306                return -EINVAL;
3307        }
3308
3309        return 0;
3310}
3311
3312static int vino_g_parm(struct file *file, void *__fh,
3313                            struct v4l2_streamparm *sp)
3314{
3315        struct vino_channel_settings *vcs = video_drvdata(file);
3316        unsigned long flags;
3317        struct v4l2_captureparm *cp = &sp->parm.capture;
3318
3319        cp->capability = V4L2_CAP_TIMEPERFRAME;
3320        cp->timeperframe.numerator = 1;
3321
3322        spin_lock_irqsave(&vino_drvdata->input_lock, flags);
3323
3324        cp->timeperframe.denominator = vcs->fps;
3325
3326        spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3327
3328        /* TODO: cp->readbuffers = xxx; */
3329
3330        return 0;
3331}
3332
3333static int vino_s_parm(struct file *file, void *__fh,
3334                            struct v4l2_streamparm *sp)
3335{
3336        struct vino_channel_settings *vcs = video_drvdata(file);
3337        unsigned long flags;
3338        struct v4l2_captureparm *cp = &sp->parm.capture;
3339
3340        spin_lock_irqsave(&vino_drvdata->input_lock, flags);
3341
3342        if ((cp->timeperframe.numerator == 0) ||
3343            (cp->timeperframe.denominator == 0)) {
3344                /* reset framerate */
3345                vino_set_default_framerate(vcs);
3346        } else {
3347                vino_set_framerate(vcs, cp->timeperframe.denominator /
3348                                   cp->timeperframe.numerator);
3349        }
3350
3351        spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3352
3353        return 0;
3354}
3355
3356static int vino_reqbufs(struct file *file, void *__fh,
3357                             struct v4l2_requestbuffers *rb)
3358{
3359        struct vino_channel_settings *vcs = video_drvdata(file);
3360
3361        if (vcs->reading)
3362                return -EBUSY;
3363
3364        /* TODO: check queue type */
3365        if (rb->memory != V4L2_MEMORY_MMAP) {
3366                dprintk("type not mmap\n");
3367                return -EINVAL;
3368        }
3369
3370        dprintk("count = %d\n", rb->count);
3371        if (rb->count > 0) {
3372                if (vino_is_capturing(vcs)) {
3373                        dprintk("busy, capturing\n");
3374                        return -EBUSY;
3375                }
3376
3377                if (vino_queue_has_mapped_buffers(&vcs->fb_queue)) {
3378                        dprintk("busy, buffers still mapped\n");
3379                        return -EBUSY;
3380                } else {
3381                        vcs->streaming = 0;
3382                        vino_queue_free(&vcs->fb_queue);
3383                        vino_queue_init(&vcs->fb_queue, &rb->count);
3384                }
3385        } else {
3386                vcs->streaming = 0;
3387                vino_capture_stop(vcs);
3388                vino_queue_free(&vcs->fb_queue);
3389        }
3390
3391        return 0;
3392}
3393
3394static void vino_v4l2_get_buffer_status(struct vino_channel_settings *vcs,
3395                                        struct vino_framebuffer *fb,
3396                                        struct v4l2_buffer *b)
3397{
3398        if (vino_queue_outgoing_contains(&vcs->fb_queue,
3399                                         fb->id)) {
3400                b->flags &= ~V4L2_BUF_FLAG_QUEUED;
3401                b->flags |= V4L2_BUF_FLAG_DONE;
3402        } else if (vino_queue_incoming_contains(&vcs->fb_queue,
3403                                       fb->id)) {
3404                b->flags &= ~V4L2_BUF_FLAG_DONE;
3405                b->flags |= V4L2_BUF_FLAG_QUEUED;
3406        } else {
3407                b->flags &= ~(V4L2_BUF_FLAG_DONE |
3408                              V4L2_BUF_FLAG_QUEUED);
3409        }
3410
3411        b->flags &= ~(V4L2_BUF_FLAG_TIMECODE);
3412
3413        if (fb->map_count > 0)
3414                b->flags |= V4L2_BUF_FLAG_MAPPED;
3415
3416        b->index = fb->id;
3417        b->memory = (vcs->fb_queue.type == VINO_MEMORY_MMAP) ?
3418                V4L2_MEMORY_MMAP : V4L2_MEMORY_USERPTR;
3419        b->m.offset = fb->offset;
3420        b->bytesused = fb->data_size;
3421        b->length = fb->size;
3422        b->field = V4L2_FIELD_INTERLACED;
3423        b->sequence = fb->frame_counter;
3424        memcpy(&b->timestamp, &fb->timestamp,
3425               sizeof(struct timeval));
3426        // b->input ?
3427
3428        dprintk("buffer %d: length = %d, bytesused = %d, offset = %d\n",
3429                fb->id, fb->size, fb->data_size, fb->offset);
3430}
3431
3432static int vino_querybuf(struct file *file, void *__fh,
3433                              struct v4l2_buffer *b)
3434{
3435        struct vino_channel_settings *vcs = video_drvdata(file);
3436        struct vino_framebuffer *fb;
3437
3438        if (vcs->reading)
3439                return -EBUSY;
3440
3441        /* TODO: check queue type */
3442        if (b->index >= vino_queue_get_length(&vcs->fb_queue)) {
3443                dprintk("invalid index = %d\n",
3444                       b->index);
3445                return -EINVAL;
3446        }
3447
3448        fb = vino_queue_get_buffer(&vcs->fb_queue,
3449                                   b->index);
3450        if (fb == NULL) {
3451                dprintk("vino_queue_get_buffer() failed");
3452                return -EINVAL;
3453        }
3454
3455        vino_v4l2_get_buffer_status(vcs, fb, b);
3456
3457        return 0;
3458}
3459
3460static int vino_qbuf(struct file *file, void *__fh,
3461                          struct v4l2_buffer *b)
3462{
3463        struct vino_channel_settings *vcs = video_drvdata(file);
3464        struct vino_framebuffer *fb;
3465        int ret;
3466
3467        if (vcs->reading)
3468                return -EBUSY;
3469
3470        /* TODO: check queue type */
3471        if (b->memory != V4L2_MEMORY_MMAP) {
3472                dprintk("type not mmap\n");
3473                return -EINVAL;
3474        }
3475
3476        fb = vino_capture_enqueue(vcs, b->index);
3477        if (fb == NULL)
3478                return -EINVAL;
3479
3480        vino_v4l2_get_buffer_status(vcs, fb, b);
3481
3482        if (vcs->streaming) {
3483                ret = vino_capture_next(vcs, 1);
3484                if (ret)
3485                        return ret;
3486        }
3487
3488        return 0;
3489}
3490
3491static int vino_dqbuf(struct file *file, void *__fh,
3492                           struct v4l2_buffer *b)
3493{
3494        struct vino_channel_settings *vcs = video_drvdata(file);
3495        unsigned int nonblocking = file->f_flags & O_NONBLOCK;
3496        struct vino_framebuffer *fb;
3497        unsigned int incoming, outgoing;
3498        int err;
3499
3500        if (vcs->reading)
3501                return -EBUSY;
3502
3503        /* TODO: check queue type */
3504
3505        err = vino_queue_get_incoming(&vcs->fb_queue, &incoming);
3506        if (err) {
3507                dprintk("vino_queue_get_incoming() failed\n");
3508                return -EINVAL;
3509        }
3510        err = vino_queue_get_outgoing(&vcs->fb_queue, &outgoing);
3511        if (err) {
3512                dprintk("vino_queue_get_outgoing() failed\n");
3513                return -EINVAL;
3514        }
3515
3516        dprintk("incoming = %d, outgoing = %d\n", incoming, outgoing);
3517
3518        if (outgoing == 0) {
3519                if (incoming == 0) {
3520                        dprintk("no incoming or outgoing buffers\n");
3521                        return -EINVAL;
3522                }
3523                if (nonblocking) {
3524                        dprintk("non-blocking I/O was selected and "
3525                                "there are no buffers to dequeue\n");
3526                        return -EAGAIN;
3527                }
3528
3529                err = vino_wait_for_frame(vcs);
3530                if (err) {
3531                        err = vino_wait_for_frame(vcs);
3532                        if (err) {
3533                                /* interrupted or no frames captured because of
3534                                 * frame skipping */
3535                                /* vino_capture_failed(vcs); */
3536                                return -EIO;
3537                        }
3538                }
3539        }
3540
3541        fb = vino_queue_remove(&vcs->fb_queue, &b->index);
3542        if (fb == NULL) {
3543                dprintk("vino_queue_remove() failed\n");
3544                return -EINVAL;
3545        }
3546
3547        err = vino_check_buffer(vcs, fb);
3548
3549        vino_v4l2_get_buffer_status(vcs, fb, b);
3550
3551        if (err)
3552                return -EIO;
3553
3554        return 0;
3555}
3556
3557static int vino_streamon(struct file *file, void *__fh,
3558                enum v4l2_buf_type i)
3559{
3560        struct vino_channel_settings *vcs = video_drvdata(file);
3561        unsigned int incoming;
3562        int ret;
3563        if (vcs->reading)
3564                return -EBUSY;
3565
3566        if (vcs->streaming)
3567                return 0;
3568
3569        // TODO: check queue type
3570
3571        if (vino_queue_get_length(&vcs->fb_queue) < 1) {
3572                dprintk("no buffers allocated\n");
3573                return -EINVAL;
3574        }
3575
3576        ret = vino_queue_get_incoming(&vcs->fb_queue, &incoming);
3577        if (ret) {
3578                dprintk("vino_queue_get_incoming() failed\n");
3579                return -EINVAL;
3580        }
3581
3582        vcs->streaming = 1;
3583
3584        if (incoming > 0) {
3585                ret = vino_capture_next(vcs, 1);
3586                if (ret) {
3587                        vcs->streaming = 0;
3588
3589                        dprintk("couldn't start capture\n");
3590                        return -EINVAL;
3591                }
3592        }
3593
3594        return 0;
3595}
3596
3597static int vino_streamoff(struct file *file, void *__fh,
3598                enum v4l2_buf_type i)
3599{
3600        struct vino_channel_settings *vcs = video_drvdata(file);
3601        if (vcs->reading)
3602                return -EBUSY;
3603
3604        if (!vcs->streaming)
3605                return 0;
3606
3607        vcs->streaming = 0;
3608        vino_capture_stop(vcs);
3609
3610        return 0;
3611}
3612
3613static int vino_queryctrl(struct file *file, void *__fh,
3614                               struct v4l2_queryctrl *queryctrl)
3615{
3616        struct vino_channel_settings *vcs = video_drvdata(file);
3617        unsigned long flags;
3618        int i;
3619        int err = 0;
3620
3621        spin_lock_irqsave(&vino_drvdata->input_lock, flags);
3622
3623        switch (vcs->input) {
3624        case VINO_INPUT_D1:
3625                for (i = 0; i < VINO_INDYCAM_V4L2_CONTROL_COUNT; i++) {
3626                        if (vino_indycam_v4l2_controls[i].id ==
3627                            queryctrl->id) {
3628                                memcpy(queryctrl,
3629                                       &vino_indycam_v4l2_controls[i],
3630                                       sizeof(struct v4l2_queryctrl));
3631                                queryctrl->reserved[0] = 0;
3632                                goto found;
3633                        }
3634                }
3635
3636                err =  -EINVAL;
3637                break;
3638        case VINO_INPUT_COMPOSITE:
3639        case VINO_INPUT_SVIDEO:
3640                for (i = 0; i < VINO_SAA7191_V4L2_CONTROL_COUNT; i++) {
3641                        if (vino_saa7191_v4l2_controls[i].id ==
3642                            queryctrl->id) {
3643                                memcpy(queryctrl,
3644                                       &vino_saa7191_v4l2_controls[i],
3645                                       sizeof(struct v4l2_queryctrl));
3646                                queryctrl->reserved[0] = 0;
3647                                goto found;
3648                        }
3649                }
3650
3651                err =  -EINVAL;
3652                break;
3653        default:
3654                err =  -EINVAL;
3655        }
3656
3657 found:
3658        spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3659
3660        return err;
3661}
3662
3663static int vino_g_ctrl(struct file *file, void *__fh,
3664                            struct v4l2_control *control)
3665{
3666        struct vino_channel_settings *vcs = video_drvdata(file);
3667        unsigned long flags;
3668        int i;
3669        int err = 0;
3670
3671        spin_lock_irqsave(&vino_drvdata->input_lock, flags);
3672
3673        switch (vcs->input) {
3674        case VINO_INPUT_D1: {
3675                err = -EINVAL;
3676                for (i = 0; i < VINO_INDYCAM_V4L2_CONTROL_COUNT; i++) {
3677                        if (vino_indycam_v4l2_controls[i].id == control->id) {
3678                                err = 0;
3679                                break;
3680                        }
3681                }
3682
3683                if (err)
3684                        goto out;
3685
3686                err = camera_call(core, g_ctrl, control);
3687                if (err)
3688                        err = -EINVAL;
3689                break;
3690        }
3691        case VINO_INPUT_COMPOSITE:
3692        case VINO_INPUT_SVIDEO: {
3693                err = -EINVAL;
3694                for (i = 0; i < VINO_SAA7191_V4L2_CONTROL_COUNT; i++) {
3695                        if (vino_saa7191_v4l2_controls[i].id == control->id) {
3696                                err = 0;
3697                                break;
3698                        }
3699                }
3700
3701                if (err)
3702                        goto out;
3703
3704                err = decoder_call(core, g_ctrl, control);
3705                if (err)
3706                        err = -EINVAL;
3707                break;
3708        }
3709        default:
3710                err =  -EINVAL;
3711        }
3712
3713out:
3714        spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3715
3716        return err;
3717}
3718
3719static int vino_s_ctrl(struct file *file, void *__fh,
3720                            struct v4l2_control *control)
3721{
3722        struct vino_channel_settings *vcs = video_drvdata(file);
3723        unsigned long flags;
3724        int i;
3725        int err = 0;
3726
3727        spin_lock_irqsave(&vino_drvdata->input_lock, flags);
3728
3729        if (!vino_is_input_owner(vcs)) {
3730                err = -EBUSY;
3731                goto out;
3732        }
3733
3734        switch (vcs->input) {
3735        case VINO_INPUT_D1: {
3736                err = -EINVAL;
3737                for (i = 0; i < VINO_INDYCAM_V4L2_CONTROL_COUNT; i++) {
3738                        if (vino_indycam_v4l2_controls[i].id == control->id) {
3739                                err = 0;
3740                                break;
3741                        }
3742                }
3743                if (err)
3744                        goto out;
3745                if (control->value < vino_indycam_v4l2_controls[i].minimum ||
3746                    control->value > vino_indycam_v4l2_controls[i].maximum) {
3747                        err = -ERANGE;
3748                        goto out;
3749                }
3750                err = camera_call(core, s_ctrl, control);
3751                if (err)
3752                        err = -EINVAL;
3753                break;
3754        }
3755        case VINO_INPUT_COMPOSITE:
3756        case VINO_INPUT_SVIDEO: {
3757                err = -EINVAL;
3758                for (i = 0; i < VINO_SAA7191_V4L2_CONTROL_COUNT; i++) {
3759                        if (vino_saa7191_v4l2_controls[i].id == control->id) {
3760                                err = 0;
3761                                break;
3762                        }
3763                }
3764                if (err)
3765                        goto out;
3766                if (control->value < vino_saa7191_v4l2_controls[i].minimum ||
3767                    control->value > vino_saa7191_v4l2_controls[i].maximum) {
3768                        err = -ERANGE;
3769                        goto out;
3770                }
3771
3772                err = decoder_call(core, s_ctrl, control);
3773                if (err)
3774                        err = -EINVAL;
3775                break;
3776        }
3777        default:
3778                err =  -EINVAL;
3779        }
3780
3781out:
3782        spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3783
3784        return err;
3785}
3786
3787/* File operations */
3788
3789static int vino_open(struct file *file)
3790{
3791        struct vino_channel_settings *vcs = video_drvdata(file);
3792        int ret = 0;
3793        dprintk("open(): channel = %c\n",
3794               (vcs->channel == VINO_CHANNEL_A) ? 'A' : 'B');
3795
3796        mutex_lock(&vcs->mutex);
3797
3798        if (vcs->users) {
3799                dprintk("open(): driver busy\n");
3800                ret = -EBUSY;
3801                goto out;
3802        }
3803
3804        ret = vino_acquire_input(vcs);
3805        if (ret) {
3806                dprintk("open(): vino_acquire_input() failed\n");
3807                goto out;
3808        }
3809
3810        vcs->users++;
3811
3812 out:
3813        mutex_unlock(&vcs->mutex);
3814
3815        dprintk("open(): %s!\n", ret ? "failed" : "complete");
3816
3817        return ret;
3818}
3819
3820static int vino_close(struct file *file)
3821{
3822        struct vino_channel_settings *vcs = video_drvdata(file);
3823        dprintk("close():\n");
3824
3825        mutex_lock(&vcs->mutex);
3826
3827        vcs->users--;
3828
3829        if (!vcs->users) {
3830                vino_release_input(vcs);
3831
3832                /* stop DMA and free buffers */
3833                vino_capture_stop(vcs);
3834                vino_queue_free(&vcs->fb_queue);
3835        }
3836
3837        mutex_unlock(&vcs->mutex);
3838
3839        return 0;
3840}
3841
3842static void vino_vm_open(struct vm_area_struct *vma)
3843{
3844        struct vino_framebuffer *fb = vma->vm_private_data;
3845
3846        fb->map_count++;
3847        dprintk("vino_vm_open(): count = %d\n", fb->map_count);
3848}
3849
3850static void vino_vm_close(struct vm_area_struct *vma)
3851{
3852        struct vino_framebuffer *fb = vma->vm_private_data;
3853
3854        fb->map_count--;
3855        dprintk("vino_vm_close(): count = %d\n", fb->map_count);
3856}
3857
3858static const struct vm_operations_struct vino_vm_ops = {
3859        .open   = vino_vm_open,
3860        .close  = vino_vm_close,
3861};
3862
3863static int vino_mmap(struct file *file, struct vm_area_struct *vma)
3864{
3865        struct vino_channel_settings *vcs = video_drvdata(file);
3866
3867        unsigned long start = vma->vm_start;
3868        unsigned long size = vma->vm_end - vma->vm_start;
3869        unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
3870
3871        struct vino_framebuffer *fb = NULL;
3872        unsigned int i, length;
3873        int ret = 0;
3874
3875        dprintk("mmap():\n");
3876
3877        // TODO: reject mmap if already mapped
3878
3879        if (mutex_lock_interruptible(&vcs->mutex))
3880                return -EINTR;
3881
3882        if (vcs->reading) {
3883                ret = -EBUSY;
3884                goto out;
3885        }
3886
3887        // TODO: check queue type
3888
3889        if (!(vma->vm_flags & VM_WRITE)) {
3890                dprintk("mmap(): app bug: PROT_WRITE please\n");
3891                ret = -EINVAL;
3892                goto out;
3893        }
3894        if (!(vma->vm_flags & VM_SHARED)) {
3895                dprintk("mmap(): app bug: MAP_SHARED please\n");
3896                ret = -EINVAL;
3897                goto out;
3898        }
3899
3900        /* find the correct buffer using offset */
3901        length = vino_queue_get_length(&vcs->fb_queue);
3902        if (length == 0) {
3903                dprintk("mmap(): queue not initialized\n");
3904                ret = -EINVAL;
3905                goto out;
3906        }
3907
3908        for (i = 0; i < length; i++) {
3909                fb = vino_queue_get_buffer(&vcs->fb_queue, i);
3910                if (fb == NULL) {
3911                        dprintk("mmap(): vino_queue_get_buffer() failed\n");
3912                        ret = -EINVAL;
3913                        goto out;
3914                }
3915
3916                if (fb->offset == offset)
3917                        goto found;
3918        }
3919
3920        dprintk("mmap(): invalid offset = %lu\n", offset);
3921        ret = -EINVAL;
3922        goto out;
3923
3924found:
3925        dprintk("mmap(): buffer = %d\n", i);
3926
3927        if (size > (fb->desc_table.page_count * PAGE_SIZE)) {
3928                dprintk("mmap(): failed: size = %lu > %lu\n",
3929                        size, fb->desc_table.page_count * PAGE_SIZE);
3930                ret = -EINVAL;
3931                goto out;
3932        }
3933
3934        for (i = 0; i < fb->desc_table.page_count; i++) {
3935                unsigned long pfn =
3936                        virt_to_phys((void *)fb->desc_table.virtual[i]) >>
3937                        PAGE_SHIFT;
3938
3939                if (size < PAGE_SIZE)
3940                        break;
3941
3942                // protection was: PAGE_READONLY
3943                if (remap_pfn_range(vma, start, pfn, PAGE_SIZE,
3944                                    vma->vm_page_prot)) {
3945                        dprintk("mmap(): remap_pfn_range() failed\n");
3946                        ret = -EAGAIN;
3947                        goto out;
3948                }
3949
3950                start += PAGE_SIZE;
3951                size -= PAGE_SIZE;
3952        }
3953
3954        fb->map_count = 1;
3955
3956        vma->vm_flags |= VM_DONTEXPAND | VM_RESERVED;
3957        vma->vm_flags &= ~VM_IO;
3958        vma->vm_private_data = fb;
3959        vma->vm_file = file;
3960        vma->vm_ops = &vino_vm_ops;
3961
3962out:
3963        mutex_unlock(&vcs->mutex);
3964
3965        return ret;
3966}
3967
3968static unsigned int vino_poll(struct file *file, poll_table *pt)
3969{
3970        struct vino_channel_settings *vcs = video_drvdata(file);
3971        unsigned int outgoing;
3972        unsigned int ret = 0;
3973
3974        // lock mutex (?)
3975        // TODO: this has to be corrected for different read modes
3976
3977        dprintk("poll():\n");
3978
3979        if (vino_queue_get_outgoing(&vcs->fb_queue, &outgoing)) {
3980                dprintk("poll(): vino_queue_get_outgoing() failed\n");
3981                ret = POLLERR;
3982                goto error;
3983        }
3984        if (outgoing > 0)
3985                goto over;
3986
3987        poll_wait(file, &vcs->fb_queue.frame_wait_queue, pt);
3988
3989        if (vino_queue_get_outgoing(&vcs->fb_queue, &outgoing)) {
3990                dprintk("poll(): vino_queue_get_outgoing() failed\n");
3991                ret = POLLERR;
3992                goto error;
3993        }
3994
3995over:
3996        dprintk("poll(): data %savailable\n",
3997                (outgoing > 0) ? "" : "not ");
3998
3999        if (outgoing > 0)
4000                ret = POLLIN | POLLRDNORM;
4001
4002error:
4003        return ret;
4004}
4005
4006static long vino_ioctl(struct file *file,
4007                      unsigned int cmd, unsigned long arg)
4008{
4009        struct vino_channel_settings *vcs = video_drvdata(file);
4010        long ret;
4011
4012        if (mutex_lock_interruptible(&vcs->mutex))
4013                return -EINTR;
4014
4015        ret = video_ioctl2(file, cmd, arg);
4016
4017        mutex_unlock(&vcs->mutex);
4018
4019        return ret;
4020}
4021
4022/* Initialization and cleanup */
4023
4024/* __initdata */
4025static int vino_init_stage;
4026
4027const struct v4l2_ioctl_ops vino_ioctl_ops = {
4028        .vidioc_enum_fmt_vid_cap     = vino_enum_fmt_vid_cap,
4029        .vidioc_g_fmt_vid_cap        = vino_g_fmt_vid_cap,
4030        .vidioc_s_fmt_vid_cap        = vino_s_fmt_vid_cap,
4031        .vidioc_try_fmt_vid_cap      = vino_try_fmt_vid_cap,
4032        .vidioc_querycap             = vino_querycap,
4033        .vidioc_enum_input           = vino_enum_input,
4034        .vidioc_g_input              = vino_g_input,
4035        .vidioc_s_input              = vino_s_input,
4036        .vidioc_g_std                = vino_g_std,
4037        .vidioc_s_std                = vino_s_std,
4038        .vidioc_querystd             = vino_querystd,
4039        .vidioc_cropcap              = vino_cropcap,
4040        .vidioc_s_crop               = vino_s_crop,
4041        .vidioc_g_crop               = vino_g_crop,
4042        .vidioc_s_parm               = vino_s_parm,
4043        .vidioc_g_parm               = vino_g_parm,
4044        .vidioc_reqbufs              = vino_reqbufs,
4045        .vidioc_querybuf             = vino_querybuf,
4046        .vidioc_qbuf                 = vino_qbuf,
4047        .vidioc_dqbuf                = vino_dqbuf,
4048        .vidioc_streamon             = vino_streamon,
4049        .vidioc_streamoff            = vino_streamoff,
4050        .vidioc_queryctrl            = vino_queryctrl,
4051        .vidioc_g_ctrl               = vino_g_ctrl,
4052        .vidioc_s_ctrl               = vino_s_ctrl,
4053};
4054
4055static const struct v4l2_file_operations vino_fops = {
4056        .owner          = THIS_MODULE,
4057        .open           = vino_open,
4058        .release        = vino_close,
4059        .unlocked_ioctl = vino_ioctl,
4060        .mmap           = vino_mmap,
4061        .poll           = vino_poll,
4062};
4063
4064static struct video_device vdev_template = {
4065        .name           = "NOT SET",
4066        .fops           = &vino_fops,
4067        .ioctl_ops      = &vino_ioctl_ops,
4068        .tvnorms        = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM,
4069};
4070
4071static void vino_module_cleanup(int stage)
4072{
4073        switch(stage) {
4074        case 11:
4075                video_unregister_device(vino_drvdata->b.vdev);
4076                vino_drvdata->b.vdev = NULL;
4077        case 10:
4078                video_unregister_device(vino_drvdata->a.vdev);
4079                vino_drvdata->a.vdev = NULL;
4080        case 9:
4081                i2c_del_adapter(&vino_i2c_adapter);
4082        case 8:
4083                free_irq(SGI_VINO_IRQ, NULL);
4084        case 7:
4085                if (vino_drvdata->b.vdev) {
4086                        video_device_release(vino_drvdata->b.vdev);
4087                        vino_drvdata->b.vdev = NULL;
4088                }
4089        case 6:
4090                if (vino_drvdata->a.vdev) {
4091                        video_device_release(vino_drvdata->a.vdev);
4092                        vino_drvdata->a.vdev = NULL;
4093                }
4094        case 5:
4095                /* all entries in dma_cpu dummy table have the same address */
4096                dma_unmap_single(NULL,
4097                                 vino_drvdata->dummy_desc_table.dma_cpu[0],
4098                                 PAGE_SIZE, DMA_FROM_DEVICE);
4099                dma_free_coherent(NULL, VINO_DUMMY_DESC_COUNT
4100                                  * sizeof(dma_addr_t),
4101                                  (void *)vino_drvdata->
4102                                  dummy_desc_table.dma_cpu,
4103                                  vino_drvdata->dummy_desc_table.dma);
4104        case 4:
4105                free_page(vino_drvdata->dummy_page);
4106        case 3:
4107                v4l2_device_unregister(&vino_drvdata->v4l2_dev);
4108        case 2:
4109                kfree(vino_drvdata);
4110        case 1:
4111                iounmap(vino);
4112        case 0:
4113                break;
4114        default:
4115                dprintk("vino_module_cleanup(): invalid cleanup stage = %d\n",
4116                        stage);
4117        }
4118}
4119
4120static int vino_probe(void)
4121{
4122        unsigned long rev_id;
4123
4124        if (ip22_is_fullhouse()) {
4125                printk(KERN_ERR "VINO doesn't exist in IP22 Fullhouse\n");
4126                return -ENODEV;
4127        }
4128
4129        if (!(sgimc->systemid & SGIMC_SYSID_EPRESENT)) {
4130                printk(KERN_ERR "VINO is not found (EISA BUS not present)\n");
4131                return -ENODEV;
4132        }
4133
4134        vino = (struct sgi_vino *)ioremap(VINO_BASE, sizeof(struct sgi_vino));
4135        if (!vino) {
4136                printk(KERN_ERR "VINO: ioremap() failed\n");
4137                return -EIO;
4138        }
4139        vino_init_stage++;
4140
4141        if (get_dbe(rev_id, &(vino->rev_id))) {
4142                printk(KERN_ERR "Failed to read VINO revision register\n");
4143                vino_module_cleanup(vino_init_stage);
4144                return -ENODEV;
4145        }
4146
4147        if (VINO_ID_VALUE(rev_id) != VINO_CHIP_ID) {
4148                printk(KERN_ERR "Unknown VINO chip ID (Rev/ID: 0x%02lx)\n",
4149                       rev_id);
4150                vino_module_cleanup(vino_init_stage);
4151                return -ENODEV;
4152        }
4153
4154        printk(KERN_INFO "VINO revision %ld found\n", VINO_REV_NUM(rev_id));
4155
4156        return 0;
4157}
4158
4159static int vino_init(void)
4160{
4161        dma_addr_t dma_dummy_address;
4162        int err;
4163        int i;
4164
4165        vino_drvdata = kzalloc(sizeof(struct vino_settings), GFP_KERNEL);
4166        if (!vino_drvdata) {
4167                vino_module_cleanup(vino_init_stage);
4168                return -ENOMEM;
4169        }
4170        vino_init_stage++;
4171        strlcpy(vino_drvdata->v4l2_dev.name, "vino",
4172                        sizeof(vino_drvdata->v4l2_dev.name));
4173        err = v4l2_device_register(NULL, &vino_drvdata->v4l2_dev);
4174        if (err)
4175                return err;
4176        vino_init_stage++;
4177
4178        /* create a dummy dma descriptor */
4179        vino_drvdata->dummy_page = get_zeroed_page(GFP_KERNEL | GFP_DMA);
4180        if (!vino_drvdata->dummy_page) {
4181                vino_module_cleanup(vino_init_stage);
4182                return -ENOMEM;
4183        }
4184        vino_init_stage++;
4185
4186        // TODO: use page_count in dummy_desc_table
4187
4188        vino_drvdata->dummy_desc_table.dma_cpu =
4189                dma_alloc_coherent(NULL,
4190                VINO_DUMMY_DESC_COUNT * sizeof(dma_addr_t),
4191                &vino_drvdata->dummy_desc_table.dma,
4192                GFP_KERNEL | GFP_DMA);
4193        if (!vino_drvdata->dummy_desc_table.dma_cpu) {
4194                vino_module_cleanup(vino_init_stage);
4195                return -ENOMEM;
4196        }
4197        vino_init_stage++;
4198
4199        dma_dummy_address = dma_map_single(NULL,
4200                                           (void *)vino_drvdata->dummy_page,
4201                                        PAGE_SIZE, DMA_FROM_DEVICE);
4202        for (i = 0; i < VINO_DUMMY_DESC_COUNT; i++) {
4203                vino_drvdata->dummy_desc_table.dma_cpu[i] = dma_dummy_address;
4204        }
4205
4206        /* initialize VINO */
4207
4208        vino->control = 0;
4209        vino->a.next_4_desc = vino_drvdata->dummy_desc_table.dma;
4210        vino->b.next_4_desc = vino_drvdata->dummy_desc_table.dma;
4211        udelay(VINO_DESC_FETCH_DELAY);
4212
4213        vino->intr_status = 0;
4214
4215        vino->a.fifo_thres = VINO_FIFO_THRESHOLD_DEFAULT;
4216        vino->b.fifo_thres = VINO_FIFO_THRESHOLD_DEFAULT;
4217
4218        return 0;
4219}
4220
4221static int vino_init_channel_settings(struct vino_channel_settings *vcs,
4222                                 unsigned int channel, const char *name)
4223{
4224        vcs->channel = channel;
4225        vcs->input = VINO_INPUT_NONE;
4226        vcs->alpha = 0;
4227        vcs->users = 0;
4228        vcs->data_format = VINO_DATA_FMT_GREY;
4229        vcs->data_norm = VINO_DATA_NORM_NTSC;
4230        vcs->decimation = 1;
4231        vino_set_default_clipping(vcs);
4232        vino_set_default_framerate(vcs);
4233
4234        vcs->capturing = 0;
4235
4236        mutex_init(&vcs->mutex);
4237        spin_lock_init(&vcs->capture_lock);
4238
4239        mutex_init(&vcs->fb_queue.queue_mutex);
4240        spin_lock_init(&vcs->fb_queue.queue_lock);
4241        init_waitqueue_head(&vcs->fb_queue.frame_wait_queue);
4242
4243        vcs->vdev = video_device_alloc();
4244        if (!vcs->vdev) {
4245                vino_module_cleanup(vino_init_stage);
4246                return -ENOMEM;
4247        }
4248        vino_init_stage++;
4249
4250        memcpy(vcs->vdev, &vdev_template,
4251               sizeof(struct video_device));
4252        strcpy(vcs->vdev->name, name);
4253        vcs->vdev->release = video_device_release;
4254        vcs->vdev->v4l2_dev = &vino_drvdata->v4l2_dev;
4255
4256        video_set_drvdata(vcs->vdev, vcs);
4257
4258        return 0;
4259}
4260
4261static int __init vino_module_init(void)
4262{
4263        int ret;
4264
4265        printk(KERN_INFO "SGI VINO driver version %s\n",
4266               VINO_MODULE_VERSION);
4267
4268        ret = vino_probe();
4269        if (ret)
4270                return ret;
4271
4272        ret = vino_init();
4273        if (ret)
4274                return ret;
4275
4276        /* initialize data structures */
4277
4278        spin_lock_init(&vino_drvdata->vino_lock);
4279        spin_lock_init(&vino_drvdata->input_lock);
4280
4281        ret = vino_init_channel_settings(&vino_drvdata->a, VINO_CHANNEL_A,
4282                                    vino_vdev_name_a);
4283        if (ret)
4284                return ret;
4285
4286        ret = vino_init_channel_settings(&vino_drvdata->b, VINO_CHANNEL_B,
4287                                    vino_vdev_name_b);
4288        if (ret)
4289                return ret;
4290
4291        /* initialize hardware and register V4L devices */
4292
4293        ret = request_irq(SGI_VINO_IRQ, vino_interrupt, 0,
4294                vino_driver_description, NULL);
4295        if (ret) {
4296                printk(KERN_ERR "VINO: requesting IRQ %02d failed\n",
4297                       SGI_VINO_IRQ);
4298                vino_module_cleanup(vino_init_stage);
4299                return -EAGAIN;
4300        }
4301        vino_init_stage++;
4302
4303        ret = i2c_add_adapter(&vino_i2c_adapter);
4304        if (ret) {
4305                printk(KERN_ERR "VINO I2C bus registration failed\n");
4306                vino_module_cleanup(vino_init_stage);
4307                return ret;
4308        }
4309        i2c_set_adapdata(&vino_i2c_adapter, &vino_drvdata->v4l2_dev);
4310        vino_init_stage++;
4311
4312        ret = video_register_device(vino_drvdata->a.vdev,
4313                                    VFL_TYPE_GRABBER, -1);
4314        if (ret < 0) {
4315                printk(KERN_ERR "VINO channel A Video4Linux-device "
4316                       "registration failed\n");
4317                vino_module_cleanup(vino_init_stage);
4318                return -EINVAL;
4319        }
4320        vino_init_stage++;
4321
4322        ret = video_register_device(vino_drvdata->b.vdev,
4323                                    VFL_TYPE_GRABBER, -1);
4324        if (ret < 0) {
4325                printk(KERN_ERR "VINO channel B Video4Linux-device "
4326                       "registration failed\n");
4327                vino_module_cleanup(vino_init_stage);
4328                return -EINVAL;
4329        }
4330        vino_init_stage++;
4331
4332        vino_drvdata->decoder =
4333                v4l2_i2c_new_subdev(&vino_drvdata->v4l2_dev, &vino_i2c_adapter,
4334                               "saa7191", 0, I2C_ADDRS(0x45));
4335        vino_drvdata->camera =
4336                v4l2_i2c_new_subdev(&vino_drvdata->v4l2_dev, &vino_i2c_adapter,
4337                               "indycam", 0, I2C_ADDRS(0x2b));
4338
4339        dprintk("init complete!\n");
4340
4341        return 0;
4342}
4343
4344static void __exit vino_module_exit(void)
4345{
4346        dprintk("exiting, stage = %d ...\n", vino_init_stage);
4347        vino_module_cleanup(vino_init_stage);
4348        dprintk("cleanup complete, exit!\n");
4349}
4350
4351module_init(vino_module_init);
4352module_exit(vino_module_exit);
4353