linux/drivers/media/video/usbvision/usbvision-core.c
<<
>>
Prefs
   1/*
   2 * usbvision-core.c - driver for NT100x USB video capture devices
   3 *
   4 *
   5 * Copyright (c) 1999-2005 Joerg Heckenbach <joerg@heckenbach-aw.de>
   6 *                         Dwaine Garden <dwainegarden@rogers.com>
   7 *
   8 * This module is part of usbvision driver project.
   9 * Updates to driver completed by Dwaine P. Garden
  10 *
  11 * This program is free software; you can redistribute it and/or modify
  12 * it under the terms of the GNU General Public License as published by
  13 * the Free Software Foundation; either version 2 of the License, or
  14 * (at your option) any later version.
  15 *
  16 * This program is distributed in the hope that it will be useful,
  17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19 * GNU General Public License for more details.
  20 *
  21 * You should have received a copy of the GNU General Public License
  22 * along with this program; if not, write to the Free Software
  23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  24 */
  25
  26#include <linux/kernel.h>
  27#include <linux/list.h>
  28#include <linux/timer.h>
  29#include <linux/gfp.h>
  30#include <linux/mm.h>
  31#include <linux/highmem.h>
  32#include <linux/vmalloc.h>
  33#include <linux/module.h>
  34#include <linux/init.h>
  35#include <linux/spinlock.h>
  36#include <asm/io.h>
  37#include <linux/videodev2.h>
  38#include <linux/i2c.h>
  39
  40#include <media/saa7115.h>
  41#include <media/v4l2-common.h>
  42#include <media/tuner.h>
  43
  44#include <linux/workqueue.h>
  45
  46#include "usbvision.h"
  47
  48static unsigned int core_debug;
  49module_param(core_debug,int,0644);
  50MODULE_PARM_DESC(core_debug,"enable debug messages [core]");
  51
  52static unsigned int force_testpattern;
  53module_param(force_testpattern,int,0644);
  54MODULE_PARM_DESC(force_testpattern,"enable test pattern display [core]");
  55
  56static int adjustCompression = 1;       /* Set the compression to be adaptive */
  57module_param(adjustCompression, int, 0444);
  58MODULE_PARM_DESC(adjustCompression, " Set the ADPCM compression for the device.  Default: 1 (On)");
  59
  60/* To help people with Black and White output with using s-video input.
  61 * Some cables and input device are wired differently. */
  62static int SwitchSVideoInput;
  63module_param(SwitchSVideoInput, int, 0444);
  64MODULE_PARM_DESC(SwitchSVideoInput, " Set the S-Video input.  Some cables and input device are wired differently. Default: 0 (Off)");
  65
  66static unsigned int adjust_X_Offset = -1;
  67module_param(adjust_X_Offset, int, 0644);
  68MODULE_PARM_DESC(adjust_X_Offset, "adjust X offset display [core]");
  69
  70static unsigned int adjust_Y_Offset = -1;
  71module_param(adjust_Y_Offset, int, 0644);
  72MODULE_PARM_DESC(adjust_Y_Offset, "adjust Y offset display [core]");
  73
  74
  75#define ENABLE_HEXDUMP  0       /* Enable if you need it */
  76
  77
  78#ifdef USBVISION_DEBUG
  79        #define PDEBUG(level, fmt, args...) { \
  80                if (core_debug & (level)) \
  81                        printk(KERN_INFO KBUILD_MODNAME ":[%s:%d] " fmt, \
  82                                __func__, __LINE__ , ## args); \
  83        }
  84#else
  85        #define PDEBUG(level, fmt, args...) do {} while(0)
  86#endif
  87
  88#define DBG_HEADER      1<<0
  89#define DBG_IRQ         1<<1
  90#define DBG_ISOC        1<<2
  91#define DBG_PARSE       1<<3
  92#define DBG_SCRATCH     1<<4
  93#define DBG_FUNC        1<<5
  94
  95static const int max_imgwidth = MAX_FRAME_WIDTH;
  96static const int max_imgheight = MAX_FRAME_HEIGHT;
  97static const int min_imgwidth = MIN_FRAME_WIDTH;
  98static const int min_imgheight = MIN_FRAME_HEIGHT;
  99
 100/* The value of 'scratch_buf_size' affects quality of the picture
 101 * in many ways. Shorter buffers may cause loss of data when client
 102 * is too slow. Larger buffers are memory-consuming and take longer
 103 * to work with. This setting can be adjusted, but the default value
 104 * should be OK for most desktop users.
 105 */
 106#define DEFAULT_SCRATCH_BUF_SIZE        (0x20000)               // 128kB memory scratch buffer
 107static const int scratch_buf_size = DEFAULT_SCRATCH_BUF_SIZE;
 108
 109// Function prototypes
 110static int usbvision_request_intra (struct usb_usbvision *usbvision);
 111static int usbvision_unrequest_intra (struct usb_usbvision *usbvision);
 112static int usbvision_adjust_compression (struct usb_usbvision *usbvision);
 113static int usbvision_measure_bandwidth (struct usb_usbvision *usbvision);
 114
 115/*******************************/
 116/* Memory management functions */
 117/*******************************/
 118
 119/*
 120 * Here we want the physical address of the memory.
 121 * This is used when initializing the contents of the area.
 122 */
 123
 124static void *usbvision_rvmalloc(unsigned long size)
 125{
 126        void *mem;
 127        unsigned long adr;
 128
 129        size = PAGE_ALIGN(size);
 130        mem = vmalloc_32(size);
 131        if (!mem)
 132                return NULL;
 133
 134        memset(mem, 0, size); /* Clear the ram out, no junk to the user */
 135        adr = (unsigned long) mem;
 136        while (size > 0) {
 137                SetPageReserved(vmalloc_to_page((void *)adr));
 138                adr += PAGE_SIZE;
 139                size -= PAGE_SIZE;
 140        }
 141
 142        return mem;
 143}
 144
 145static void usbvision_rvfree(void *mem, unsigned long size)
 146{
 147        unsigned long adr;
 148
 149        if (!mem)
 150                return;
 151
 152        size = PAGE_ALIGN(size);
 153
 154        adr = (unsigned long) mem;
 155        while ((long) size > 0) {
 156                ClearPageReserved(vmalloc_to_page((void *)adr));
 157                adr += PAGE_SIZE;
 158                size -= PAGE_SIZE;
 159        }
 160
 161        vfree(mem);
 162}
 163
 164
 165#if ENABLE_HEXDUMP
 166static void usbvision_hexdump(const unsigned char *data, int len)
 167{
 168        char tmp[80];
 169        int i, k;
 170
 171        for (i = k = 0; len > 0; i++, len--) {
 172                if (i > 0 && (i % 16 == 0)) {
 173                        printk("%s\n", tmp);
 174                        k = 0;
 175                }
 176                k += sprintf(&tmp[k], "%02x ", data[i]);
 177        }
 178        if (k > 0)
 179                printk("%s\n", tmp);
 180}
 181#endif
 182
 183/********************************
 184 * scratch ring buffer handling
 185 ********************************/
 186static int scratch_len(struct usb_usbvision *usbvision)    /*This returns the amount of data actually in the buffer */
 187{
 188        int len = usbvision->scratch_write_ptr - usbvision->scratch_read_ptr;
 189        if (len < 0) {
 190                len += scratch_buf_size;
 191        }
 192        PDEBUG(DBG_SCRATCH, "scratch_len() = %d\n", len);
 193
 194        return len;
 195}
 196
 197
 198/* This returns the free space left in the buffer */
 199static int scratch_free(struct usb_usbvision *usbvision)
 200{
 201        int free = usbvision->scratch_read_ptr - usbvision->scratch_write_ptr;
 202        if (free <= 0) {
 203                free += scratch_buf_size;
 204        }
 205        if (free) {
 206                free -= 1;                                                      /* at least one byte in the buffer must */
 207                                                                                /* left blank, otherwise there is no chance to differ between full and empty */
 208        }
 209        PDEBUG(DBG_SCRATCH, "return %d\n", free);
 210
 211        return free;
 212}
 213
 214
 215/* This puts data into the buffer */
 216static int scratch_put(struct usb_usbvision *usbvision, unsigned char *data,
 217                       int len)
 218{
 219        int len_part;
 220
 221        if (usbvision->scratch_write_ptr + len < scratch_buf_size) {
 222                memcpy(usbvision->scratch + usbvision->scratch_write_ptr, data, len);
 223                usbvision->scratch_write_ptr += len;
 224        }
 225        else {
 226                len_part = scratch_buf_size - usbvision->scratch_write_ptr;
 227                memcpy(usbvision->scratch + usbvision->scratch_write_ptr, data, len_part);
 228                if (len == len_part) {
 229                        usbvision->scratch_write_ptr = 0;                       /* just set write_ptr to zero */
 230                }
 231                else {
 232                        memcpy(usbvision->scratch, data + len_part, len - len_part);
 233                        usbvision->scratch_write_ptr = len - len_part;
 234                }
 235        }
 236
 237        PDEBUG(DBG_SCRATCH, "len=%d, new write_ptr=%d\n", len, usbvision->scratch_write_ptr);
 238
 239        return len;
 240}
 241
 242/* This marks the write_ptr as position of new frame header */
 243static void scratch_mark_header(struct usb_usbvision *usbvision)
 244{
 245        PDEBUG(DBG_SCRATCH, "header at write_ptr=%d\n", usbvision->scratch_headermarker_write_ptr);
 246
 247        usbvision->scratch_headermarker[usbvision->scratch_headermarker_write_ptr] =
 248                                usbvision->scratch_write_ptr;
 249        usbvision->scratch_headermarker_write_ptr += 1;
 250        usbvision->scratch_headermarker_write_ptr %= USBVISION_NUM_HEADERMARKER;
 251}
 252
 253/* This gets data from the buffer at the given "ptr" position */
 254static int scratch_get_extra(struct usb_usbvision *usbvision,
 255                             unsigned char *data, int *ptr, int len)
 256{
 257        int len_part;
 258        if (*ptr + len < scratch_buf_size) {
 259                memcpy(data, usbvision->scratch + *ptr, len);
 260                *ptr += len;
 261        }
 262        else {
 263                len_part = scratch_buf_size - *ptr;
 264                memcpy(data, usbvision->scratch + *ptr, len_part);
 265                if (len == len_part) {
 266                        *ptr = 0;                                                       /* just set the y_ptr to zero */
 267                }
 268                else {
 269                        memcpy(data + len_part, usbvision->scratch, len - len_part);
 270                        *ptr = len - len_part;
 271                }
 272        }
 273
 274        PDEBUG(DBG_SCRATCH, "len=%d, new ptr=%d\n", len, *ptr);
 275
 276        return len;
 277}
 278
 279
 280/* This sets the scratch extra read pointer */
 281static void scratch_set_extra_ptr(struct usb_usbvision *usbvision, int *ptr,
 282                                  int len)
 283{
 284        *ptr = (usbvision->scratch_read_ptr + len)%scratch_buf_size;
 285
 286        PDEBUG(DBG_SCRATCH, "ptr=%d\n", *ptr);
 287}
 288
 289
 290/*This increments the scratch extra read pointer */
 291static void scratch_inc_extra_ptr(int *ptr, int len)
 292{
 293        *ptr = (*ptr + len) % scratch_buf_size;
 294
 295        PDEBUG(DBG_SCRATCH, "ptr=%d\n", *ptr);
 296}
 297
 298
 299/* This gets data from the buffer */
 300static int scratch_get(struct usb_usbvision *usbvision, unsigned char *data,
 301                       int len)
 302{
 303        int len_part;
 304        if (usbvision->scratch_read_ptr + len < scratch_buf_size) {
 305                memcpy(data, usbvision->scratch + usbvision->scratch_read_ptr, len);
 306                usbvision->scratch_read_ptr += len;
 307        }
 308        else {
 309                len_part = scratch_buf_size - usbvision->scratch_read_ptr;
 310                memcpy(data, usbvision->scratch + usbvision->scratch_read_ptr, len_part);
 311                if (len == len_part) {
 312                        usbvision->scratch_read_ptr = 0;                                /* just set the read_ptr to zero */
 313                }
 314                else {
 315                        memcpy(data + len_part, usbvision->scratch, len - len_part);
 316                        usbvision->scratch_read_ptr = len - len_part;
 317                }
 318        }
 319
 320        PDEBUG(DBG_SCRATCH, "len=%d, new read_ptr=%d\n", len, usbvision->scratch_read_ptr);
 321
 322        return len;
 323}
 324
 325
 326/* This sets read pointer to next header and returns it */
 327static int scratch_get_header(struct usb_usbvision *usbvision,
 328                              struct usbvision_frame_header *header)
 329{
 330        int errCode = 0;
 331
 332        PDEBUG(DBG_SCRATCH, "from read_ptr=%d", usbvision->scratch_headermarker_read_ptr);
 333
 334        while (usbvision->scratch_headermarker_write_ptr -
 335                usbvision->scratch_headermarker_read_ptr != 0) {
 336                usbvision->scratch_read_ptr =
 337                        usbvision->scratch_headermarker[usbvision->scratch_headermarker_read_ptr];
 338                usbvision->scratch_headermarker_read_ptr += 1;
 339                usbvision->scratch_headermarker_read_ptr %= USBVISION_NUM_HEADERMARKER;
 340                scratch_get(usbvision, (unsigned char *)header, USBVISION_HEADER_LENGTH);
 341                if ((header->magic_1 == USBVISION_MAGIC_1)
 342                         && (header->magic_2 == USBVISION_MAGIC_2)
 343                         && (header->headerLength == USBVISION_HEADER_LENGTH)) {
 344                        errCode = USBVISION_HEADER_LENGTH;
 345                        header->frameWidth  = header->frameWidthLo  + (header->frameWidthHi << 8);
 346                        header->frameHeight = header->frameHeightLo + (header->frameHeightHi << 8);
 347                        break;
 348                }
 349        }
 350
 351        return errCode;
 352}
 353
 354
 355/*This removes len bytes of old data from the buffer */
 356static void scratch_rm_old(struct usb_usbvision *usbvision, int len)
 357{
 358
 359        usbvision->scratch_read_ptr += len;
 360        usbvision->scratch_read_ptr %= scratch_buf_size;
 361        PDEBUG(DBG_SCRATCH, "read_ptr is now %d\n", usbvision->scratch_read_ptr);
 362}
 363
 364
 365/*This resets the buffer - kills all data in it too */
 366static void scratch_reset(struct usb_usbvision *usbvision)
 367{
 368        PDEBUG(DBG_SCRATCH, "\n");
 369
 370        usbvision->scratch_read_ptr = 0;
 371        usbvision->scratch_write_ptr = 0;
 372        usbvision->scratch_headermarker_read_ptr = 0;
 373        usbvision->scratch_headermarker_write_ptr = 0;
 374        usbvision->isocstate = IsocState_NoFrame;
 375}
 376
 377int usbvision_scratch_alloc(struct usb_usbvision *usbvision)
 378{
 379        usbvision->scratch = vmalloc_32(scratch_buf_size);
 380        scratch_reset(usbvision);
 381        if(usbvision->scratch == NULL) {
 382                dev_err(&usbvision->dev->dev,
 383                        "%s: unable to allocate %d bytes for scratch\n",
 384                                __func__, scratch_buf_size);
 385                return -ENOMEM;
 386        }
 387        return 0;
 388}
 389
 390void usbvision_scratch_free(struct usb_usbvision *usbvision)
 391{
 392        vfree(usbvision->scratch);
 393        usbvision->scratch = NULL;
 394
 395}
 396
 397/*
 398 * usbvision_testpattern()
 399 *
 400 * Procedure forms a test pattern (yellow grid on blue background).
 401 *
 402 * Parameters:
 403 * fullframe:   if TRUE then entire frame is filled, otherwise the procedure
 404 *              continues from the current scanline.
 405 * pmode        0: fill the frame with solid blue color (like on VCR or TV)
 406 *              1: Draw a colored grid
 407 *
 408 */
 409static void usbvision_testpattern(struct usb_usbvision *usbvision,
 410                                  int fullframe, int pmode)
 411{
 412        static const char proc[] = "usbvision_testpattern";
 413        struct usbvision_frame *frame;
 414        unsigned char *f;
 415        int num_cell = 0;
 416        int scan_length = 0;
 417        static int num_pass;
 418
 419        if (usbvision == NULL) {
 420                printk(KERN_ERR "%s: usbvision == NULL\n", proc);
 421                return;
 422        }
 423        if (usbvision->curFrame == NULL) {
 424                printk(KERN_ERR "%s: usbvision->curFrame is NULL.\n", proc);
 425                return;
 426        }
 427
 428        /* Grab the current frame */
 429        frame = usbvision->curFrame;
 430
 431        /* Optionally start at the beginning */
 432        if (fullframe) {
 433                frame->curline = 0;
 434                frame->scanlength = 0;
 435        }
 436
 437        /* Form every scan line */
 438        for (; frame->curline < frame->frmheight; frame->curline++) {
 439                int i;
 440
 441                f = frame->data + (usbvision->curwidth * 3 * frame->curline);
 442                for (i = 0; i < usbvision->curwidth; i++) {
 443                        unsigned char cb = 0x80;
 444                        unsigned char cg = 0;
 445                        unsigned char cr = 0;
 446
 447                        if (pmode == 1) {
 448                                if (frame->curline % 32 == 0)
 449                                        cb = 0, cg = cr = 0xFF;
 450                                else if (i % 32 == 0) {
 451                                        if (frame->curline % 32 == 1)
 452                                                num_cell++;
 453                                        cb = 0, cg = cr = 0xFF;
 454                                } else {
 455                                        cb =
 456                                            ((num_cell * 7) +
 457                                             num_pass) & 0xFF;
 458                                        cg =
 459                                            ((num_cell * 5) +
 460                                             num_pass * 2) & 0xFF;
 461                                        cr =
 462                                            ((num_cell * 3) +
 463                                             num_pass * 3) & 0xFF;
 464                                }
 465                        } else {
 466                                /* Just the blue screen */
 467                        }
 468
 469                        *f++ = cb;
 470                        *f++ = cg;
 471                        *f++ = cr;
 472                        scan_length += 3;
 473                }
 474        }
 475
 476        frame->grabstate = FrameState_Done;
 477        frame->scanlength += scan_length;
 478        ++num_pass;
 479
 480}
 481
 482/*
 483 * usbvision_decompress_alloc()
 484 *
 485 * allocates intermediate buffer for decompression
 486 */
 487int usbvision_decompress_alloc(struct usb_usbvision *usbvision)
 488{
 489        int IFB_size = MAX_FRAME_WIDTH * MAX_FRAME_HEIGHT * 3 / 2;
 490        usbvision->IntraFrameBuffer = vmalloc_32(IFB_size);
 491        if (usbvision->IntraFrameBuffer == NULL) {
 492                dev_err(&usbvision->dev->dev,
 493                        "%s: unable to allocate %d for compr. frame buffer\n",
 494                                __func__, IFB_size);
 495                return -ENOMEM;
 496        }
 497        return 0;
 498}
 499
 500/*
 501 * usbvision_decompress_free()
 502 *
 503 * frees intermediate buffer for decompression
 504 */
 505void usbvision_decompress_free(struct usb_usbvision *usbvision)
 506{
 507        vfree(usbvision->IntraFrameBuffer);
 508        usbvision->IntraFrameBuffer = NULL;
 509
 510}
 511
 512/************************************************************
 513 * Here comes the data parsing stuff that is run as interrupt
 514 ************************************************************/
 515/*
 516 * usbvision_find_header()
 517 *
 518 * Locate one of supported header markers in the scratch buffer.
 519 */
 520static enum ParseState usbvision_find_header(struct usb_usbvision *usbvision)
 521{
 522        struct usbvision_frame *frame;
 523        int foundHeader = 0;
 524
 525        frame = usbvision->curFrame;
 526
 527        while (scratch_get_header(usbvision, &frame->isocHeader) == USBVISION_HEADER_LENGTH) {
 528                // found header in scratch
 529                PDEBUG(DBG_HEADER, "found header: 0x%02x%02x %d %d %d %d %#x 0x%02x %u %u",
 530                                frame->isocHeader.magic_2,
 531                                frame->isocHeader.magic_1,
 532                                frame->isocHeader.headerLength,
 533                                frame->isocHeader.frameNum,
 534                                frame->isocHeader.framePhase,
 535                                frame->isocHeader.frameLatency,
 536                                frame->isocHeader.dataFormat,
 537                                frame->isocHeader.formatParam,
 538                                frame->isocHeader.frameWidth,
 539                                frame->isocHeader.frameHeight);
 540
 541                if (usbvision->requestIntra) {
 542                        if (frame->isocHeader.formatParam & 0x80) {
 543                                foundHeader = 1;
 544                                usbvision->lastIsocFrameNum = -1; // do not check for lost frames this time
 545                                usbvision_unrequest_intra(usbvision);
 546                                break;
 547                        }
 548                }
 549                else {
 550                        foundHeader = 1;
 551                        break;
 552                }
 553        }
 554
 555        if (foundHeader) {
 556                frame->frmwidth = frame->isocHeader.frameWidth * usbvision->stretch_width;
 557                frame->frmheight = frame->isocHeader.frameHeight * usbvision->stretch_height;
 558                frame->v4l2_linesize = (frame->frmwidth * frame->v4l2_format.depth)>> 3;
 559        }
 560        else { // no header found
 561                PDEBUG(DBG_HEADER, "skipping scratch data, no header");
 562                scratch_reset(usbvision);
 563                return ParseState_EndParse;
 564        }
 565
 566        // found header
 567        if (frame->isocHeader.dataFormat==ISOC_MODE_COMPRESS) {
 568                //check isocHeader.frameNum for lost frames
 569                if (usbvision->lastIsocFrameNum >= 0) {
 570                        if (((usbvision->lastIsocFrameNum + 1) % 32) != frame->isocHeader.frameNum) {
 571                                // unexpected frame drop: need to request new intra frame
 572                                PDEBUG(DBG_HEADER, "Lost frame before %d on USB", frame->isocHeader.frameNum);
 573                                usbvision_request_intra(usbvision);
 574                                return ParseState_NextFrame;
 575                        }
 576                }
 577                usbvision->lastIsocFrameNum = frame->isocHeader.frameNum;
 578        }
 579        usbvision->header_count++;
 580        frame->scanstate = ScanState_Lines;
 581        frame->curline = 0;
 582
 583        if (force_testpattern) {
 584                usbvision_testpattern(usbvision, 1, 1);
 585                return ParseState_NextFrame;
 586        }
 587        return ParseState_Continue;
 588}
 589
 590static enum ParseState usbvision_parse_lines_422(struct usb_usbvision *usbvision,
 591                                           long *pcopylen)
 592{
 593        volatile struct usbvision_frame *frame;
 594        unsigned char *f;
 595        int len;
 596        int i;
 597        unsigned char yuyv[4]={180, 128, 10, 128}; // YUV components
 598        unsigned char rv, gv, bv;       // RGB components
 599        int clipmask_index, bytes_per_pixel;
 600        int stretch_bytes, clipmask_add;
 601
 602        frame  = usbvision->curFrame;
 603        f = frame->data + (frame->v4l2_linesize * frame->curline);
 604
 605        /* Make sure there's enough data for the entire line */
 606        len = (frame->isocHeader.frameWidth * 2)+5;
 607        if (scratch_len(usbvision) < len) {
 608                PDEBUG(DBG_PARSE, "out of data in line %d, need %u.\n", frame->curline, len);
 609                return ParseState_Out;
 610        }
 611
 612        if ((frame->curline + 1) >= frame->frmheight) {
 613                return ParseState_NextFrame;
 614        }
 615
 616        bytes_per_pixel = frame->v4l2_format.bytes_per_pixel;
 617        stretch_bytes = (usbvision->stretch_width - 1) * bytes_per_pixel;
 618        clipmask_index = frame->curline * MAX_FRAME_WIDTH;
 619        clipmask_add = usbvision->stretch_width;
 620
 621        for (i = 0; i < frame->frmwidth; i+=(2 * usbvision->stretch_width)) {
 622
 623                scratch_get(usbvision, &yuyv[0], 4);
 624
 625                if (frame->v4l2_format.format == V4L2_PIX_FMT_YUYV) {
 626                        *f++ = yuyv[0]; // Y
 627                        *f++ = yuyv[3]; // U
 628                }
 629                else {
 630
 631                        YUV_TO_RGB_BY_THE_BOOK(yuyv[0], yuyv[1], yuyv[3], rv, gv, bv);
 632                        switch (frame->v4l2_format.format) {
 633                        case V4L2_PIX_FMT_RGB565:
 634                                *f++ = (0x1F & rv) |
 635                                        (0xE0 & (gv << 5));
 636                                *f++ = (0x07 & (gv >> 3)) |
 637                                        (0xF8 &  bv);
 638                                break;
 639                        case V4L2_PIX_FMT_RGB24:
 640                                *f++ = rv;
 641                                *f++ = gv;
 642                                *f++ = bv;
 643                                break;
 644                        case V4L2_PIX_FMT_RGB32:
 645                                *f++ = rv;
 646                                *f++ = gv;
 647                                *f++ = bv;
 648                                f++;
 649                                break;
 650                        case V4L2_PIX_FMT_RGB555:
 651                                *f++ = (0x1F & rv) |
 652                                        (0xE0 & (gv << 5));
 653                                *f++ = (0x03 & (gv >> 3)) |
 654                                        (0x7C & (bv << 2));
 655                                break;
 656                        }
 657                }
 658                clipmask_index += clipmask_add;
 659                f += stretch_bytes;
 660
 661                if (frame->v4l2_format.format == V4L2_PIX_FMT_YUYV) {
 662                        *f++ = yuyv[2]; // Y
 663                        *f++ = yuyv[1]; // V
 664                }
 665                else {
 666
 667                        YUV_TO_RGB_BY_THE_BOOK(yuyv[2], yuyv[1], yuyv[3], rv, gv, bv);
 668                        switch (frame->v4l2_format.format) {
 669                        case V4L2_PIX_FMT_RGB565:
 670                                *f++ = (0x1F & rv) |
 671                                        (0xE0 & (gv << 5));
 672                                *f++ = (0x07 & (gv >> 3)) |
 673                                        (0xF8 &  bv);
 674                                break;
 675                        case V4L2_PIX_FMT_RGB24:
 676                                *f++ = rv;
 677                                *f++ = gv;
 678                                *f++ = bv;
 679                                break;
 680                        case V4L2_PIX_FMT_RGB32:
 681                                *f++ = rv;
 682                                *f++ = gv;
 683                                *f++ = bv;
 684                                f++;
 685                                break;
 686                        case V4L2_PIX_FMT_RGB555:
 687                                *f++ = (0x1F & rv) |
 688                                        (0xE0 & (gv << 5));
 689                                *f++ = (0x03 & (gv >> 3)) |
 690                                        (0x7C & (bv << 2));
 691                                break;
 692                        }
 693                }
 694                clipmask_index += clipmask_add;
 695                f += stretch_bytes;
 696        }
 697
 698        frame->curline += usbvision->stretch_height;
 699        *pcopylen += frame->v4l2_linesize * usbvision->stretch_height;
 700
 701        if (frame->curline >= frame->frmheight) {
 702                return ParseState_NextFrame;
 703        }
 704        else {
 705                return ParseState_Continue;
 706        }
 707}
 708
 709/* The decompression routine  */
 710static int usbvision_decompress(struct usb_usbvision *usbvision,unsigned char *Compressed,
 711                                                                unsigned char *Decompressed, int *StartPos,
 712                                                                int *BlockTypeStartPos, int Len)
 713{
 714        int RestPixel, Idx, MaxPos, Pos, ExtraPos, BlockLen, BlockTypePos, BlockTypeLen;
 715        unsigned char BlockByte, BlockCode, BlockType, BlockTypeByte, Integrator;
 716
 717        Integrator = 0;
 718        Pos = *StartPos;
 719        BlockTypePos = *BlockTypeStartPos;
 720        MaxPos = 396; //Pos + Len;
 721        ExtraPos = Pos;
 722        BlockLen = 0;
 723        BlockByte = 0;
 724        BlockCode = 0;
 725        BlockType = 0;
 726        BlockTypeByte = 0;
 727        BlockTypeLen = 0;
 728        RestPixel = Len;
 729
 730        for (Idx = 0; Idx < Len; Idx++) {
 731
 732                if (BlockLen == 0) {
 733                        if (BlockTypeLen==0) {
 734                                BlockTypeByte = Compressed[BlockTypePos];
 735                                BlockTypePos++;
 736                                BlockTypeLen = 4;
 737                        }
 738                        BlockType = (BlockTypeByte & 0xC0) >> 6;
 739
 740                        //statistic:
 741                        usbvision->ComprBlockTypes[BlockType]++;
 742
 743                        Pos = ExtraPos;
 744                        if (BlockType == 0) {
 745                                if(RestPixel >= 24) {
 746                                        Idx += 23;
 747                                        RestPixel -= 24;
 748                                        Integrator = Decompressed[Idx];
 749                                } else {
 750                                        Idx += RestPixel - 1;
 751                                        RestPixel = 0;
 752                                }
 753                        } else {
 754                                BlockCode = Compressed[Pos];
 755                                Pos++;
 756                                if (RestPixel >= 24) {
 757                                        BlockLen  = 24;
 758                                } else {
 759                                        BlockLen = RestPixel;
 760                                }
 761                                RestPixel -= BlockLen;
 762                                ExtraPos = Pos + (BlockLen / 4);
 763                        }
 764                        BlockTypeByte <<= 2;
 765                        BlockTypeLen -= 1;
 766                }
 767                if (BlockLen > 0) {
 768                        if ((BlockLen%4) == 0) {
 769                                BlockByte = Compressed[Pos];
 770                                Pos++;
 771                        }
 772                        if (BlockType == 1) { //inter Block
 773                                Integrator = Decompressed[Idx];
 774                        }
 775                        switch (BlockByte & 0xC0) {
 776                                case 0x03<<6:
 777                                        Integrator += Compressed[ExtraPos];
 778                                        ExtraPos++;
 779                                        break;
 780                                case 0x02<<6:
 781                                        Integrator += BlockCode;
 782                                        break;
 783                                case 0x00:
 784                                        Integrator -= BlockCode;
 785                                        break;
 786                        }
 787                        Decompressed[Idx] = Integrator;
 788                        BlockByte <<= 2;
 789                        BlockLen -= 1;
 790                }
 791        }
 792        *StartPos = ExtraPos;
 793        *BlockTypeStartPos = BlockTypePos;
 794        return Idx;
 795}
 796
 797
 798/*
 799 * usbvision_parse_compress()
 800 *
 801 * Parse compressed frame from the scratch buffer, put
 802 * decoded RGB value into the current frame buffer and add the written
 803 * number of bytes (RGB) to the *pcopylen.
 804 *
 805 */
 806static enum ParseState usbvision_parse_compress(struct usb_usbvision *usbvision,
 807                                           long *pcopylen)
 808{
 809#define USBVISION_STRIP_MAGIC           0x5A
 810#define USBVISION_STRIP_LEN_MAX         400
 811#define USBVISION_STRIP_HEADER_LEN      3
 812
 813        struct usbvision_frame *frame;
 814        unsigned char *f,*u = NULL ,*v = NULL;
 815        unsigned char StripData[USBVISION_STRIP_LEN_MAX];
 816        unsigned char StripHeader[USBVISION_STRIP_HEADER_LEN];
 817        int Idx, IdxEnd, StripLen, StripPtr, StartBlockPos, BlockPos, BlockTypePos;
 818        int clipmask_index, bytes_per_pixel, rc;
 819        int imageSize;
 820        unsigned char rv, gv, bv;
 821        static unsigned char *Y, *U, *V;
 822
 823        frame  = usbvision->curFrame;
 824        imageSize = frame->frmwidth * frame->frmheight;
 825        if ( (frame->v4l2_format.format == V4L2_PIX_FMT_YUV422P) ||
 826             (frame->v4l2_format.format == V4L2_PIX_FMT_YVU420) ) {       // this is a planar format
 827                //... v4l2_linesize not used here.
 828                f = frame->data + (frame->width * frame->curline);
 829        } else
 830                f = frame->data + (frame->v4l2_linesize * frame->curline);
 831
 832        if (frame->v4l2_format.format == V4L2_PIX_FMT_YUYV){ //initialise u and v pointers
 833                // get base of u and b planes add halfoffset
 834
 835                u = frame->data
 836                        + imageSize
 837                        + (frame->frmwidth >>1) * frame->curline ;
 838                v = u + (imageSize >>1 );
 839
 840        } else if (frame->v4l2_format.format == V4L2_PIX_FMT_YVU420){
 841
 842                v = frame->data + imageSize + ((frame->curline* (frame->width))>>2) ;
 843                u = v + (imageSize >>2) ;
 844        }
 845
 846        if (frame->curline == 0) {
 847                usbvision_adjust_compression(usbvision);
 848        }
 849
 850        if (scratch_len(usbvision) < USBVISION_STRIP_HEADER_LEN) {
 851                return ParseState_Out;
 852        }
 853
 854        //get strip header without changing the scratch_read_ptr
 855        scratch_set_extra_ptr(usbvision, &StripPtr, 0);
 856        scratch_get_extra(usbvision, &StripHeader[0], &StripPtr,
 857                                USBVISION_STRIP_HEADER_LEN);
 858
 859        if (StripHeader[0] != USBVISION_STRIP_MAGIC) {
 860                // wrong strip magic
 861                usbvision->stripMagicErrors++;
 862                return ParseState_NextFrame;
 863        }
 864
 865        if (frame->curline != (int)StripHeader[2]) {
 866                //line number missmatch error
 867                usbvision->stripLineNumberErrors++;
 868        }
 869
 870        StripLen = 2 * (unsigned int)StripHeader[1];
 871        if (StripLen > USBVISION_STRIP_LEN_MAX) {
 872                // strip overrun
 873                // I think this never happens
 874                usbvision_request_intra(usbvision);
 875        }
 876
 877        if (scratch_len(usbvision) < StripLen) {
 878                //there is not enough data for the strip
 879                return ParseState_Out;
 880        }
 881
 882        if (usbvision->IntraFrameBuffer) {
 883                Y = usbvision->IntraFrameBuffer + frame->frmwidth * frame->curline;
 884                U = usbvision->IntraFrameBuffer + imageSize + (frame->frmwidth / 2) * (frame->curline / 2);
 885                V = usbvision->IntraFrameBuffer + imageSize / 4 * 5 + (frame->frmwidth / 2) * (frame->curline / 2);
 886        }
 887        else {
 888                return ParseState_NextFrame;
 889        }
 890
 891        bytes_per_pixel = frame->v4l2_format.bytes_per_pixel;
 892        clipmask_index = frame->curline * MAX_FRAME_WIDTH;
 893
 894        scratch_get(usbvision, StripData, StripLen);
 895
 896        IdxEnd = frame->frmwidth;
 897        BlockTypePos = USBVISION_STRIP_HEADER_LEN;
 898        StartBlockPos = BlockTypePos + (IdxEnd - 1) / 96 + (IdxEnd / 2 - 1) / 96 + 2;
 899        BlockPos = StartBlockPos;
 900
 901        usbvision->BlockPos = BlockPos;
 902
 903        if ((rc = usbvision_decompress(usbvision, StripData, Y, &BlockPos, &BlockTypePos, IdxEnd)) != IdxEnd) {
 904                //return ParseState_Continue;
 905        }
 906        if (StripLen > usbvision->maxStripLen) {
 907                usbvision->maxStripLen = StripLen;
 908        }
 909
 910        if (frame->curline%2) {
 911                if ((rc = usbvision_decompress(usbvision, StripData, V, &BlockPos, &BlockTypePos, IdxEnd/2)) != IdxEnd/2) {
 912                //return ParseState_Continue;
 913                }
 914        }
 915        else {
 916                if ((rc = usbvision_decompress(usbvision, StripData, U, &BlockPos, &BlockTypePos, IdxEnd/2)) != IdxEnd/2) {
 917                        //return ParseState_Continue;
 918                }
 919        }
 920
 921        if (BlockPos > usbvision->comprBlockPos) {
 922                usbvision->comprBlockPos = BlockPos;
 923        }
 924        if (BlockPos > StripLen) {
 925                usbvision->stripLenErrors++;
 926        }
 927
 928        for (Idx = 0; Idx < IdxEnd; Idx++) {
 929                if(frame->v4l2_format.format == V4L2_PIX_FMT_YUYV) {
 930                        *f++ = Y[Idx];
 931                        *f++ = Idx & 0x01 ? U[Idx/2] : V[Idx/2];
 932                }
 933                else if(frame->v4l2_format.format == V4L2_PIX_FMT_YUV422P) {
 934                        *f++ = Y[Idx];
 935                        if ( Idx & 0x01)
 936                                *u++ = U[Idx>>1] ;
 937                        else
 938                                *v++ = V[Idx>>1];
 939                }
 940                else if (frame->v4l2_format.format == V4L2_PIX_FMT_YVU420) {
 941                        *f++ = Y [Idx];
 942                        if ( !((  Idx & 0x01  ) | (  frame->curline & 0x01  )) ){
 943
 944/*                               only need do this for 1 in 4 pixels */
 945/*                               intraframe buffer is YUV420 format */
 946
 947                                *u++ = U[Idx >>1];
 948                                *v++ = V[Idx >>1];
 949                        }
 950
 951                }
 952                else {
 953                        YUV_TO_RGB_BY_THE_BOOK(Y[Idx], U[Idx/2], V[Idx/2], rv, gv, bv);
 954                        switch (frame->v4l2_format.format) {
 955                                case V4L2_PIX_FMT_GREY:
 956                                        *f++ = Y[Idx];
 957                                        break;
 958                                case V4L2_PIX_FMT_RGB555:
 959                                        *f++ = (0x1F & rv) |
 960                                                (0xE0 & (gv << 5));
 961                                        *f++ = (0x03 & (gv >> 3)) |
 962                                                (0x7C & (bv << 2));
 963                                        break;
 964                                case V4L2_PIX_FMT_RGB565:
 965                                        *f++ = (0x1F & rv) |
 966                                                (0xE0 & (gv << 5));
 967                                        *f++ = (0x07 & (gv >> 3)) |
 968                                                (0xF8 &  bv);
 969                                        break;
 970                                case V4L2_PIX_FMT_RGB24:
 971                                        *f++ = rv;
 972                                        *f++ = gv;
 973                                        *f++ = bv;
 974                                        break;
 975                                case V4L2_PIX_FMT_RGB32:
 976                                        *f++ = rv;
 977                                        *f++ = gv;
 978                                        *f++ = bv;
 979                                        f++;
 980                                        break;
 981                        }
 982                }
 983                clipmask_index++;
 984        }
 985        /* Deal with non-integer no. of bytes for YUV420P */
 986        if (frame->v4l2_format.format != V4L2_PIX_FMT_YVU420 )
 987                *pcopylen += frame->v4l2_linesize;
 988        else
 989                *pcopylen += frame->curline & 0x01 ? frame->v4l2_linesize : frame->v4l2_linesize << 1;
 990
 991        frame->curline += 1;
 992
 993        if (frame->curline >= frame->frmheight) {
 994                return ParseState_NextFrame;
 995        }
 996        else {
 997                return ParseState_Continue;
 998        }
 999
1000}
1001
1002
1003/*
1004 * usbvision_parse_lines_420()
1005 *
1006 * Parse two lines from the scratch buffer, put
1007 * decoded RGB value into the current frame buffer and add the written
1008 * number of bytes (RGB) to the *pcopylen.
1009 *
1010 */
1011static enum ParseState usbvision_parse_lines_420(struct usb_usbvision *usbvision,
1012                                           long *pcopylen)
1013{
1014        struct usbvision_frame *frame;
1015        unsigned char *f_even = NULL, *f_odd = NULL;
1016        unsigned int pixel_per_line, block;
1017        int pixel, block_split;
1018        int y_ptr, u_ptr, v_ptr, y_odd_offset;
1019        const int   y_block_size = 128;
1020        const int  uv_block_size = 64;
1021        const int sub_block_size = 32;
1022        const int y_step[] = { 0, 0, 0, 2 },  y_step_size = 4;
1023        const int uv_step[]= { 0, 0, 0, 4 }, uv_step_size = 4;
1024        unsigned char y[2], u, v;       /* YUV components */
1025        int y_, u_, v_, vb, uvg, ur;
1026        int r_, g_, b_;                 /* RGB components */
1027        unsigned char g;
1028        int clipmask_even_index, clipmask_odd_index, bytes_per_pixel;
1029        int clipmask_add, stretch_bytes;
1030
1031        frame  = usbvision->curFrame;
1032        f_even = frame->data + (frame->v4l2_linesize * frame->curline);
1033        f_odd  = f_even + frame->v4l2_linesize * usbvision->stretch_height;
1034
1035        /* Make sure there's enough data for the entire line */
1036        /* In this mode usbvision transfer 3 bytes for every 2 pixels */
1037        /* I need two lines to decode the color */
1038        bytes_per_pixel = frame->v4l2_format.bytes_per_pixel;
1039        stretch_bytes = (usbvision->stretch_width - 1) * bytes_per_pixel;
1040        clipmask_even_index = frame->curline * MAX_FRAME_WIDTH;
1041        clipmask_odd_index  = clipmask_even_index + MAX_FRAME_WIDTH;
1042        clipmask_add = usbvision->stretch_width;
1043        pixel_per_line = frame->isocHeader.frameWidth;
1044
1045        if (scratch_len(usbvision) < (int)pixel_per_line * 3) {
1046                //printk(KERN_DEBUG "out of data, need %d\n", len);
1047                return ParseState_Out;
1048        }
1049
1050        if ((frame->curline + 1) >= frame->frmheight) {
1051                return ParseState_NextFrame;
1052        }
1053
1054        block_split = (pixel_per_line%y_block_size) ? 1 : 0;    //are some blocks splitted into different lines?
1055
1056        y_odd_offset = (pixel_per_line / y_block_size) * (y_block_size + uv_block_size)
1057                        + block_split * uv_block_size;
1058
1059        scratch_set_extra_ptr(usbvision, &y_ptr, y_odd_offset);
1060        scratch_set_extra_ptr(usbvision, &u_ptr, y_block_size);
1061        scratch_set_extra_ptr(usbvision, &v_ptr, y_odd_offset
1062                        + (4 - block_split) * sub_block_size);
1063
1064        for (block = 0; block < (pixel_per_line / sub_block_size);
1065             block++) {
1066
1067
1068                for (pixel = 0; pixel < sub_block_size; pixel +=2) {
1069                        scratch_get(usbvision, &y[0], 2);
1070                        scratch_get_extra(usbvision, &u, &u_ptr, 1);
1071                        scratch_get_extra(usbvision, &v, &v_ptr, 1);
1072
1073                        //I don't use the YUV_TO_RGB macro for better performance
1074                        v_ = v - 128;
1075                        u_ = u - 128;
1076                        vb =              132252 * v_;
1077                        uvg= -53281 * u_ - 25625 * v_;
1078                        ur = 104595 * u_;
1079
1080                        if(frame->v4l2_format.format == V4L2_PIX_FMT_YUYV) {
1081                                *f_even++ = y[0];
1082                                *f_even++ = v;
1083                        }
1084                        else {
1085                                y_ = 76284 * (y[0] - 16);
1086
1087                                b_ = (y_ + vb) >> 16;
1088                                g_ = (y_ + uvg)>> 16;
1089                                r_ = (y_ + ur) >> 16;
1090
1091                                switch (frame->v4l2_format.format) {
1092                                case V4L2_PIX_FMT_RGB565:
1093                                        g = LIMIT_RGB(g_);
1094                                        *f_even++ =
1095                                                (0x1F & LIMIT_RGB(r_)) |
1096                                                (0xE0 & (g << 5));
1097                                        *f_even++ =
1098                                                (0x07 & (g >> 3)) |
1099                                                (0xF8 &  LIMIT_RGB(b_));
1100                                        break;
1101                                case V4L2_PIX_FMT_RGB24:
1102                                        *f_even++ = LIMIT_RGB(r_);
1103                                        *f_even++ = LIMIT_RGB(g_);
1104                                        *f_even++ = LIMIT_RGB(b_);
1105                                        break;
1106                                case V4L2_PIX_FMT_RGB32:
1107                                        *f_even++ = LIMIT_RGB(r_);
1108                                        *f_even++ = LIMIT_RGB(g_);
1109                                        *f_even++ = LIMIT_RGB(b_);
1110                                        f_even++;
1111                                        break;
1112                                case V4L2_PIX_FMT_RGB555:
1113                                        g = LIMIT_RGB(g_);
1114                                        *f_even++ = (0x1F & LIMIT_RGB(r_)) |
1115                                                (0xE0 & (g << 5));
1116                                        *f_even++ = (0x03 & (g >> 3)) |
1117                                                (0x7C & (LIMIT_RGB(b_) << 2));
1118                                        break;
1119                                }
1120                        }
1121                        clipmask_even_index += clipmask_add;
1122                        f_even += stretch_bytes;
1123
1124                        if(frame->v4l2_format.format == V4L2_PIX_FMT_YUYV) {
1125                                *f_even++ = y[1];
1126                                *f_even++ = u;
1127                        }
1128                        else {
1129                                y_ = 76284 * (y[1] - 16);
1130
1131                                b_ = (y_ + vb) >> 16;
1132                                g_ = (y_ + uvg)>> 16;
1133                                r_ = (y_ + ur) >> 16;
1134
1135                                switch (frame->v4l2_format.format) {
1136                                case V4L2_PIX_FMT_RGB565:
1137                                        g = LIMIT_RGB(g_);
1138                                        *f_even++ =
1139                                                (0x1F & LIMIT_RGB(r_)) |
1140                                                (0xE0 & (g << 5));
1141                                        *f_even++ =
1142                                                (0x07 & (g >> 3)) |
1143                                                (0xF8 &  LIMIT_RGB(b_));
1144                                        break;
1145                                case V4L2_PIX_FMT_RGB24:
1146                                        *f_even++ = LIMIT_RGB(r_);
1147                                        *f_even++ = LIMIT_RGB(g_);
1148                                        *f_even++ = LIMIT_RGB(b_);
1149                                        break;
1150                                case V4L2_PIX_FMT_RGB32:
1151                                        *f_even++ = LIMIT_RGB(r_);
1152                                        *f_even++ = LIMIT_RGB(g_);
1153                                        *f_even++ = LIMIT_RGB(b_);
1154                                        f_even++;
1155                                        break;
1156                                case V4L2_PIX_FMT_RGB555:
1157                                        g = LIMIT_RGB(g_);
1158                                        *f_even++ = (0x1F & LIMIT_RGB(r_)) |
1159                                                (0xE0 & (g << 5));
1160                                        *f_even++ = (0x03 & (g >> 3)) |
1161                                                (0x7C & (LIMIT_RGB(b_) << 2));
1162                                        break;
1163                                }
1164                        }
1165                        clipmask_even_index += clipmask_add;
1166                        f_even += stretch_bytes;
1167
1168                        scratch_get_extra(usbvision, &y[0], &y_ptr, 2);
1169
1170                        if(frame->v4l2_format.format == V4L2_PIX_FMT_YUYV) {
1171                                *f_odd++ = y[0];
1172                                *f_odd++ = v;
1173                        }
1174                        else {
1175                                y_ = 76284 * (y[0] - 16);
1176
1177                                b_ = (y_ + vb) >> 16;
1178                                g_ = (y_ + uvg)>> 16;
1179                                r_ = (y_ + ur) >> 16;
1180
1181                                switch (frame->v4l2_format.format) {
1182                                case V4L2_PIX_FMT_RGB565:
1183                                        g = LIMIT_RGB(g_);
1184                                        *f_odd++ =
1185                                                (0x1F & LIMIT_RGB(r_)) |
1186                                                (0xE0 & (g << 5));
1187                                        *f_odd++ =
1188                                                (0x07 & (g >> 3)) |
1189                                                (0xF8 &  LIMIT_RGB(b_));
1190                                        break;
1191                                case V4L2_PIX_FMT_RGB24:
1192                                        *f_odd++ = LIMIT_RGB(r_);
1193                                        *f_odd++ = LIMIT_RGB(g_);
1194                                        *f_odd++ = LIMIT_RGB(b_);
1195                                        break;
1196                                case V4L2_PIX_FMT_RGB32:
1197                                        *f_odd++ = LIMIT_RGB(r_);
1198                                        *f_odd++ = LIMIT_RGB(g_);
1199                                        *f_odd++ = LIMIT_RGB(b_);
1200                                        f_odd++;
1201                                        break;
1202                                case V4L2_PIX_FMT_RGB555:
1203                                        g = LIMIT_RGB(g_);
1204                                        *f_odd++ = (0x1F & LIMIT_RGB(r_)) |
1205                                                (0xE0 & (g << 5));
1206                                        *f_odd++ = (0x03 & (g >> 3)) |
1207                                                (0x7C & (LIMIT_RGB(b_) << 2));
1208                                        break;
1209                                }
1210                        }
1211                        clipmask_odd_index += clipmask_add;
1212                        f_odd += stretch_bytes;
1213
1214                        if(frame->v4l2_format.format == V4L2_PIX_FMT_YUYV) {
1215                                *f_odd++ = y[1];
1216                                *f_odd++ = u;
1217                        }
1218                        else {
1219                                y_ = 76284 * (y[1] - 16);
1220
1221                                b_ = (y_ + vb) >> 16;
1222                                g_ = (y_ + uvg)>> 16;
1223                                r_ = (y_ + ur) >> 16;
1224
1225                                switch (frame->v4l2_format.format) {
1226                                case V4L2_PIX_FMT_RGB565:
1227                                        g = LIMIT_RGB(g_);
1228                                        *f_odd++ =
1229                                                (0x1F & LIMIT_RGB(r_)) |
1230                                                (0xE0 & (g << 5));
1231                                        *f_odd++ =
1232                                                (0x07 & (g >> 3)) |
1233                                                (0xF8 &  LIMIT_RGB(b_));
1234                                        break;
1235                                case V4L2_PIX_FMT_RGB24:
1236                                        *f_odd++ = LIMIT_RGB(r_);
1237                                        *f_odd++ = LIMIT_RGB(g_);
1238                                        *f_odd++ = LIMIT_RGB(b_);
1239                                        break;
1240                                case V4L2_PIX_FMT_RGB32:
1241                                        *f_odd++ = LIMIT_RGB(r_);
1242                                        *f_odd++ = LIMIT_RGB(g_);
1243                                        *f_odd++ = LIMIT_RGB(b_);
1244                                        f_odd++;
1245                                        break;
1246                                case V4L2_PIX_FMT_RGB555:
1247                                        g = LIMIT_RGB(g_);
1248                                        *f_odd++ = (0x1F & LIMIT_RGB(r_)) |
1249                                                (0xE0 & (g << 5));
1250                                        *f_odd++ = (0x03 & (g >> 3)) |
1251                                                (0x7C & (LIMIT_RGB(b_) << 2));
1252                                        break;
1253                                }
1254                        }
1255                        clipmask_odd_index += clipmask_add;
1256                        f_odd += stretch_bytes;
1257                }
1258
1259                scratch_rm_old(usbvision,y_step[block % y_step_size] * sub_block_size);
1260                scratch_inc_extra_ptr(&y_ptr, y_step[(block + 2 * block_split) % y_step_size]
1261                                * sub_block_size);
1262                scratch_inc_extra_ptr(&u_ptr, uv_step[block % uv_step_size]
1263                                * sub_block_size);
1264                scratch_inc_extra_ptr(&v_ptr, uv_step[(block + 2 * block_split) % uv_step_size]
1265                                * sub_block_size);
1266        }
1267
1268        scratch_rm_old(usbvision, pixel_per_line * 3 / 2
1269                        + block_split * sub_block_size);
1270
1271        frame->curline += 2 * usbvision->stretch_height;
1272        *pcopylen += frame->v4l2_linesize * 2 * usbvision->stretch_height;
1273
1274        if (frame->curline >= frame->frmheight)
1275                return ParseState_NextFrame;
1276        else
1277                return ParseState_Continue;
1278}
1279
1280/*
1281 * usbvision_parse_data()
1282 *
1283 * Generic routine to parse the scratch buffer. It employs either
1284 * usbvision_find_header() or usbvision_parse_lines() to do most
1285 * of work.
1286 *
1287 */
1288static void usbvision_parse_data(struct usb_usbvision *usbvision)
1289{
1290        struct usbvision_frame *frame;
1291        enum ParseState newstate;
1292        long copylen = 0;
1293        unsigned long lock_flags;
1294
1295        frame = usbvision->curFrame;
1296
1297        PDEBUG(DBG_PARSE, "parsing len=%d\n", scratch_len(usbvision));
1298
1299        while (1) {
1300
1301                newstate = ParseState_Out;
1302                if (scratch_len(usbvision)) {
1303                        if (frame->scanstate == ScanState_Scanning) {
1304                                newstate = usbvision_find_header(usbvision);
1305                        }
1306                        else if (frame->scanstate == ScanState_Lines) {
1307                                if (usbvision->isocMode == ISOC_MODE_YUV420) {
1308                                        newstate = usbvision_parse_lines_420(usbvision, &copylen);
1309                                }
1310                                else if (usbvision->isocMode == ISOC_MODE_YUV422) {
1311                                        newstate = usbvision_parse_lines_422(usbvision, &copylen);
1312                                }
1313                                else if (usbvision->isocMode == ISOC_MODE_COMPRESS) {
1314                                        newstate = usbvision_parse_compress(usbvision, &copylen);
1315                                }
1316
1317                        }
1318                }
1319                if (newstate == ParseState_Continue) {
1320                        continue;
1321                }
1322                else if ((newstate == ParseState_NextFrame) || (newstate == ParseState_Out)) {
1323                        break;
1324                }
1325                else {
1326                        return; /* ParseState_EndParse */
1327                }
1328        }
1329
1330        if (newstate == ParseState_NextFrame) {
1331                frame->grabstate = FrameState_Done;
1332                do_gettimeofday(&(frame->timestamp));
1333                frame->sequence = usbvision->frame_num;
1334
1335                spin_lock_irqsave(&usbvision->queue_lock, lock_flags);
1336                list_move_tail(&(frame->frame), &usbvision->outqueue);
1337                usbvision->curFrame = NULL;
1338                spin_unlock_irqrestore(&usbvision->queue_lock, lock_flags);
1339
1340                usbvision->frame_num++;
1341
1342                /* This will cause the process to request another frame. */
1343                if (waitqueue_active(&usbvision->wait_frame)) {
1344                        PDEBUG(DBG_PARSE, "Wake up !");
1345                        wake_up_interruptible(&usbvision->wait_frame);
1346                }
1347        }
1348        else
1349                frame->grabstate = FrameState_Grabbing;
1350
1351
1352        /* Update the frame's uncompressed length. */
1353        frame->scanlength += copylen;
1354}
1355
1356
1357/*
1358 * Make all of the blocks of data contiguous
1359 */
1360static int usbvision_compress_isochronous(struct usb_usbvision *usbvision,
1361                                          struct urb *urb)
1362{
1363        unsigned char *packet_data;
1364        int i, totlen = 0;
1365
1366        for (i = 0; i < urb->number_of_packets; i++) {
1367                int packet_len = urb->iso_frame_desc[i].actual_length;
1368                int packet_stat = urb->iso_frame_desc[i].status;
1369
1370                packet_data = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
1371
1372                /* Detect and ignore errored packets */
1373                if (packet_stat) {      // packet_stat != 0 ?????????????
1374                        PDEBUG(DBG_ISOC, "data error: [%d] len=%d, status=%X", i, packet_len, packet_stat);
1375                        usbvision->isocErrCount++;
1376                        continue;
1377                }
1378
1379                /* Detect and ignore empty packets */
1380                if (packet_len < 0) {
1381                        PDEBUG(DBG_ISOC, "error packet [%d]", i);
1382                        usbvision->isocSkipCount++;
1383                        continue;
1384                }
1385                else if (packet_len == 0) {     /* Frame end ????? */
1386                        PDEBUG(DBG_ISOC, "null packet [%d]", i);
1387                        usbvision->isocstate=IsocState_NoFrame;
1388                        usbvision->isocSkipCount++;
1389                        continue;
1390                }
1391                else if (packet_len > usbvision->isocPacketSize) {
1392                        PDEBUG(DBG_ISOC, "packet[%d] > isocPacketSize", i);
1393                        usbvision->isocSkipCount++;
1394                        continue;
1395                }
1396
1397                PDEBUG(DBG_ISOC, "packet ok [%d] len=%d", i, packet_len);
1398
1399                if (usbvision->isocstate==IsocState_NoFrame) { //new frame begins
1400                        usbvision->isocstate=IsocState_InFrame;
1401                        scratch_mark_header(usbvision);
1402                        usbvision_measure_bandwidth(usbvision);
1403                        PDEBUG(DBG_ISOC, "packet with header");
1404                }
1405
1406                /*
1407                 * If usbvision continues to feed us with data but there is no
1408                 * consumption (if, for example, V4L client fell asleep) we
1409                 * may overflow the buffer. We have to move old data over to
1410                 * free room for new data. This is bad for old data. If we
1411                 * just drop new data then it's bad for new data... choose
1412                 * your favorite evil here.
1413                 */
1414                if (scratch_free(usbvision) < packet_len) {
1415
1416                        usbvision->scratch_ovf_count++;
1417                        PDEBUG(DBG_ISOC, "scratch buf overflow! scr_len: %d, n: %d",
1418                               scratch_len(usbvision), packet_len);
1419                        scratch_rm_old(usbvision, packet_len - scratch_free(usbvision));
1420                }
1421
1422                /* Now we know that there is enough room in scratch buffer */
1423                scratch_put(usbvision, packet_data, packet_len);
1424                totlen += packet_len;
1425                usbvision->isocDataCount += packet_len;
1426                usbvision->isocPacketCount++;
1427        }
1428#if ENABLE_HEXDUMP
1429        if (totlen > 0) {
1430                static int foo;
1431                if (foo < 1) {
1432                        printk(KERN_DEBUG "+%d.\n", usbvision->scratchlen);
1433                        usbvision_hexdump(data0, (totlen > 64) ? 64 : totlen);
1434                        ++foo;
1435                }
1436        }
1437#endif
1438 return totlen;
1439}
1440
1441static void usbvision_isocIrq(struct urb *urb)
1442{
1443        int errCode = 0;
1444        int len;
1445        struct usb_usbvision *usbvision = urb->context;
1446        int i;
1447        unsigned long startTime = jiffies;
1448        struct usbvision_frame **f;
1449
1450        /* We don't want to do anything if we are about to be removed! */
1451        if (!USBVISION_IS_OPERATIONAL(usbvision))
1452                return;
1453
1454        /* any urb with wrong status is ignored without acknowledgement */
1455        if (urb->status == -ENOENT) {
1456                return;
1457        }
1458
1459        f = &usbvision->curFrame;
1460
1461        /* Manage streaming interruption */
1462        if (usbvision->streaming == Stream_Interrupt) {
1463                usbvision->streaming = Stream_Idle;
1464                if ((*f)) {
1465                        (*f)->grabstate = FrameState_Ready;
1466                        (*f)->scanstate = ScanState_Scanning;
1467                }
1468                PDEBUG(DBG_IRQ, "stream interrupted");
1469                wake_up_interruptible(&usbvision->wait_stream);
1470        }
1471
1472        /* Copy the data received into our scratch buffer */
1473        len = usbvision_compress_isochronous(usbvision, urb);
1474
1475        usbvision->isocUrbCount++;
1476        usbvision->urb_length = len;
1477
1478        if (usbvision->streaming == Stream_On) {
1479
1480                /* If we collected enough data let's parse! */
1481                if ((scratch_len(usbvision) > USBVISION_HEADER_LENGTH) &&
1482                    (!list_empty(&(usbvision->inqueue))) ) {
1483                        if (!(*f)) {
1484                                (*f) = list_entry(usbvision->inqueue.next,
1485                                                  struct usbvision_frame,
1486                                                  frame);
1487                        }
1488                        usbvision_parse_data(usbvision);
1489                }
1490                else {
1491                        /*If we don't have a frame
1492                          we're current working on, complain */
1493                        PDEBUG(DBG_IRQ,
1494                               "received data, but no one needs it");
1495                        scratch_reset(usbvision);
1496                }
1497        }
1498        else {
1499                PDEBUG(DBG_IRQ, "received data, but no one needs it");
1500                scratch_reset(usbvision);
1501        }
1502
1503        usbvision->timeInIrq += jiffies - startTime;
1504
1505        for (i = 0; i < USBVISION_URB_FRAMES; i++) {
1506                urb->iso_frame_desc[i].status = 0;
1507                urb->iso_frame_desc[i].actual_length = 0;
1508        }
1509
1510        urb->status = 0;
1511        urb->dev = usbvision->dev;
1512        errCode = usb_submit_urb (urb, GFP_ATOMIC);
1513
1514        if(errCode) {
1515                dev_err(&usbvision->dev->dev,
1516                        "%s: usb_submit_urb failed: error %d\n",
1517                                __func__, errCode);
1518        }
1519
1520        return;
1521}
1522
1523/*************************************/
1524/* Low level usbvision access functions */
1525/*************************************/
1526
1527/*
1528 * usbvision_read_reg()
1529 *
1530 * return  < 0 -> Error
1531 *        >= 0 -> Data
1532 */
1533
1534int usbvision_read_reg(struct usb_usbvision *usbvision, unsigned char reg)
1535{
1536        int errCode = 0;
1537        unsigned char buffer[1];
1538
1539        if (!USBVISION_IS_OPERATIONAL(usbvision))
1540                return -1;
1541
1542        errCode = usb_control_msg(usbvision->dev, usb_rcvctrlpipe(usbvision->dev, 1),
1543                                USBVISION_OP_CODE,
1544                                USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT,
1545                                0, (__u16) reg, buffer, 1, HZ);
1546
1547        if (errCode < 0) {
1548                dev_err(&usbvision->dev->dev,
1549                        "%s: failed: error %d\n", __func__, errCode);
1550                return errCode;
1551        }
1552        return buffer[0];
1553}
1554
1555/*
1556 * usbvision_write_reg()
1557 *
1558 * return 1 -> Reg written
1559 *        0 -> usbvision is not yet ready
1560 *       -1 -> Something went wrong
1561 */
1562
1563int usbvision_write_reg(struct usb_usbvision *usbvision, unsigned char reg,
1564                            unsigned char value)
1565{
1566        int errCode = 0;
1567
1568        if (!USBVISION_IS_OPERATIONAL(usbvision))
1569                return 0;
1570
1571        errCode = usb_control_msg(usbvision->dev, usb_sndctrlpipe(usbvision->dev, 1),
1572                                USBVISION_OP_CODE,
1573                                USB_DIR_OUT | USB_TYPE_VENDOR |
1574                                USB_RECIP_ENDPOINT, 0, (__u16) reg, &value, 1, HZ);
1575
1576        if (errCode < 0) {
1577                dev_err(&usbvision->dev->dev,
1578                        "%s: failed: error %d\n", __func__, errCode);
1579        }
1580        return errCode;
1581}
1582
1583
1584static void usbvision_ctrlUrb_complete(struct urb *urb)
1585{
1586        struct usb_usbvision *usbvision = (struct usb_usbvision *)urb->context;
1587
1588        PDEBUG(DBG_IRQ, "");
1589        usbvision->ctrlUrbBusy = 0;
1590        if (waitqueue_active(&usbvision->ctrlUrb_wq)) {
1591                wake_up_interruptible(&usbvision->ctrlUrb_wq);
1592        }
1593}
1594
1595
1596static int usbvision_write_reg_irq(struct usb_usbvision *usbvision,int address,
1597                                                                        unsigned char *data, int len)
1598{
1599        int errCode = 0;
1600
1601        PDEBUG(DBG_IRQ, "");
1602        if (len > 8) {
1603                return -EFAULT;
1604        }
1605        if (usbvision->ctrlUrbBusy) {
1606                return -EBUSY;
1607        }
1608        usbvision->ctrlUrbBusy = 1;
1609
1610        usbvision->ctrlUrbSetup.bRequestType = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT;
1611        usbvision->ctrlUrbSetup.bRequest     = USBVISION_OP_CODE;
1612        usbvision->ctrlUrbSetup.wValue       = 0;
1613        usbvision->ctrlUrbSetup.wIndex       = cpu_to_le16(address);
1614        usbvision->ctrlUrbSetup.wLength      = cpu_to_le16(len);
1615        usb_fill_control_urb (usbvision->ctrlUrb, usbvision->dev,
1616                                                        usb_sndctrlpipe(usbvision->dev, 1),
1617                                                        (unsigned char *)&usbvision->ctrlUrbSetup,
1618                                                        (void *)usbvision->ctrlUrbBuffer, len,
1619                                                        usbvision_ctrlUrb_complete,
1620                                                        (void *)usbvision);
1621
1622        memcpy(usbvision->ctrlUrbBuffer, data, len);
1623
1624        errCode = usb_submit_urb(usbvision->ctrlUrb, GFP_ATOMIC);
1625        if (errCode < 0) {
1626                // error in usb_submit_urb()
1627                usbvision->ctrlUrbBusy = 0;
1628        }
1629        PDEBUG(DBG_IRQ, "submit %d byte: error %d", len, errCode);
1630        return errCode;
1631}
1632
1633
1634static int usbvision_init_compression(struct usb_usbvision *usbvision)
1635{
1636        int errCode = 0;
1637
1638        usbvision->lastIsocFrameNum = -1;
1639        usbvision->isocDataCount = 0;
1640        usbvision->isocPacketCount = 0;
1641        usbvision->isocSkipCount = 0;
1642        usbvision->comprLevel = 50;
1643        usbvision->lastComprLevel = -1;
1644        usbvision->isocUrbCount = 0;
1645        usbvision->requestIntra = 1;
1646        usbvision->isocMeasureBandwidthCount = 0;
1647
1648        return errCode;
1649}
1650
1651/* this function measures the used bandwidth since last call
1652 * return:    0 : no error
1653 * sets usedBandwidth to 1-100 : 1-100% of full bandwidth resp. to isocPacketSize
1654 */
1655static int usbvision_measure_bandwidth (struct usb_usbvision *usbvision)
1656{
1657        int errCode = 0;
1658
1659        if (usbvision->isocMeasureBandwidthCount < 2) { // this gives an average bandwidth of 3 frames
1660                usbvision->isocMeasureBandwidthCount++;
1661                return errCode;
1662        }
1663        if ((usbvision->isocPacketSize > 0) && (usbvision->isocPacketCount > 0)) {
1664                usbvision->usedBandwidth = usbvision->isocDataCount /
1665                                        (usbvision->isocPacketCount + usbvision->isocSkipCount) *
1666                                        100 / usbvision->isocPacketSize;
1667        }
1668        usbvision->isocMeasureBandwidthCount = 0;
1669        usbvision->isocDataCount = 0;
1670        usbvision->isocPacketCount = 0;
1671        usbvision->isocSkipCount = 0;
1672        return errCode;
1673}
1674
1675static int usbvision_adjust_compression (struct usb_usbvision *usbvision)
1676{
1677        int errCode = 0;
1678        unsigned char buffer[6];
1679
1680        PDEBUG(DBG_IRQ, "");
1681        if ((adjustCompression) && (usbvision->usedBandwidth > 0)) {
1682                usbvision->comprLevel += (usbvision->usedBandwidth - 90) / 2;
1683                RESTRICT_TO_RANGE(usbvision->comprLevel, 0, 100);
1684                if (usbvision->comprLevel != usbvision->lastComprLevel) {
1685                        int distorsion;
1686                        if (usbvision->bridgeType == BRIDGE_NT1004 || usbvision->bridgeType == BRIDGE_NT1005) {
1687                                buffer[0] = (unsigned char)(4 + 16 * usbvision->comprLevel / 100);      // PCM Threshold 1
1688                                buffer[1] = (unsigned char)(4 + 8 * usbvision->comprLevel / 100);       // PCM Threshold 2
1689                                distorsion = 7 + 248 * usbvision->comprLevel / 100;
1690                                buffer[2] = (unsigned char)(distorsion & 0xFF);                         // Average distorsion Threshold (inter)
1691                                buffer[3] = (unsigned char)(distorsion & 0xFF);                         // Average distorsion Threshold (intra)
1692                                distorsion = 1 + 42 * usbvision->comprLevel / 100;
1693                                buffer[4] = (unsigned char)(distorsion & 0xFF);                         // Maximum distorsion Threshold (inter)
1694                                buffer[5] = (unsigned char)(distorsion & 0xFF);                         // Maximum distorsion Threshold (intra)
1695                        }
1696                        else { //BRIDGE_NT1003
1697                                buffer[0] = (unsigned char)(4 + 16 * usbvision->comprLevel / 100);      // PCM threshold 1
1698                                buffer[1] = (unsigned char)(4 + 8 * usbvision->comprLevel / 100);       // PCM threshold 2
1699                                distorsion = 2 + 253 * usbvision->comprLevel / 100;
1700                                buffer[2] = (unsigned char)(distorsion & 0xFF);                         // distorsion threshold bit0-7
1701                                buffer[3] = 0;  //(unsigned char)((distorsion >> 8) & 0x0F);            // distorsion threshold bit 8-11
1702                                distorsion = 0 + 43 * usbvision->comprLevel / 100;
1703                                buffer[4] = (unsigned char)(distorsion & 0xFF);                         // maximum distorsion bit0-7
1704                                buffer[5] = 0; //(unsigned char)((distorsion >> 8) & 0x01);             // maximum distorsion bit 8
1705                        }
1706                        errCode = usbvision_write_reg_irq(usbvision, USBVISION_PCM_THR1, buffer, 6);
1707                        if (errCode == 0){
1708                                PDEBUG(DBG_IRQ, "new compr params %#02x %#02x %#02x %#02x %#02x %#02x", buffer[0],
1709                                                                buffer[1], buffer[2], buffer[3], buffer[4], buffer[5]);
1710                                usbvision->lastComprLevel = usbvision->comprLevel;
1711                        }
1712                }
1713        }
1714        return errCode;
1715}
1716
1717static int usbvision_request_intra (struct usb_usbvision *usbvision)
1718{
1719        int errCode = 0;
1720        unsigned char buffer[1];
1721
1722        PDEBUG(DBG_IRQ, "");
1723        usbvision->requestIntra = 1;
1724        buffer[0] = 1;
1725        usbvision_write_reg_irq(usbvision, USBVISION_FORCE_INTRA, buffer, 1);
1726        return errCode;
1727}
1728
1729static int usbvision_unrequest_intra (struct usb_usbvision *usbvision)
1730{
1731        int errCode = 0;
1732        unsigned char buffer[1];
1733
1734        PDEBUG(DBG_IRQ, "");
1735        usbvision->requestIntra = 0;
1736        buffer[0] = 0;
1737        usbvision_write_reg_irq(usbvision, USBVISION_FORCE_INTRA, buffer, 1);
1738        return errCode;
1739}
1740
1741/*******************************
1742 * usbvision utility functions
1743 *******************************/
1744
1745int usbvision_power_off(struct usb_usbvision *usbvision)
1746{
1747        int errCode = 0;
1748
1749        PDEBUG(DBG_FUNC, "");
1750
1751        errCode = usbvision_write_reg(usbvision, USBVISION_PWR_REG, USBVISION_SSPND_EN);
1752        if (errCode == 1) {
1753                usbvision->power = 0;
1754        }
1755        PDEBUG(DBG_FUNC, "%s: errCode %d", (errCode!=1)?"ERROR":"power is off", errCode);
1756        return errCode;
1757}
1758
1759/*
1760 * usbvision_set_video_format()
1761 *
1762 */
1763static int usbvision_set_video_format(struct usb_usbvision *usbvision, int format)
1764{
1765        static const char proc[] = "usbvision_set_video_format";
1766        int rc;
1767        unsigned char value[2];
1768
1769        if (!USBVISION_IS_OPERATIONAL(usbvision))
1770                return 0;
1771
1772        PDEBUG(DBG_FUNC, "isocMode %#02x", format);
1773
1774        if ((format != ISOC_MODE_YUV422)
1775            && (format != ISOC_MODE_YUV420)
1776            && (format != ISOC_MODE_COMPRESS)) {
1777                printk(KERN_ERR "usbvision: unknown video format %02x, using default YUV420",
1778                       format);
1779                format = ISOC_MODE_YUV420;
1780        }
1781        value[0] = 0x0A;  //TODO: See the effect of the filter
1782        value[1] = format; // Sets the VO_MODE register which follows FILT_CONT
1783        rc = usb_control_msg(usbvision->dev, usb_sndctrlpipe(usbvision->dev, 1),
1784                             USBVISION_OP_CODE,
1785                             USB_DIR_OUT | USB_TYPE_VENDOR |
1786                             USB_RECIP_ENDPOINT, 0,
1787                             (__u16) USBVISION_FILT_CONT, value, 2, HZ);
1788
1789        if (rc < 0) {
1790                printk(KERN_ERR "%s: ERROR=%d. USBVISION stopped - "
1791                       "reconnect or reload driver.\n", proc, rc);
1792        }
1793        usbvision->isocMode = format;
1794        return rc;
1795}
1796
1797/*
1798 * usbvision_set_output()
1799 *
1800 */
1801
1802int usbvision_set_output(struct usb_usbvision *usbvision, int width,
1803                         int height)
1804{
1805        int errCode = 0;
1806        int UsbWidth, UsbHeight;
1807        unsigned int frameRate=0, frameDrop=0;
1808        unsigned char value[4];
1809
1810        if (!USBVISION_IS_OPERATIONAL(usbvision)) {
1811                return 0;
1812        }
1813
1814        if (width > MAX_USB_WIDTH) {
1815                UsbWidth = width / 2;
1816                usbvision->stretch_width = 2;
1817        }
1818        else {
1819                UsbWidth = width;
1820                usbvision->stretch_width = 1;
1821        }
1822
1823        if (height > MAX_USB_HEIGHT) {
1824                UsbHeight = height / 2;
1825                usbvision->stretch_height = 2;
1826        }
1827        else {
1828                UsbHeight = height;
1829                usbvision->stretch_height = 1;
1830        }
1831
1832        RESTRICT_TO_RANGE(UsbWidth, MIN_FRAME_WIDTH, MAX_USB_WIDTH);
1833        UsbWidth &= ~(MIN_FRAME_WIDTH-1);
1834        RESTRICT_TO_RANGE(UsbHeight, MIN_FRAME_HEIGHT, MAX_USB_HEIGHT);
1835        UsbHeight &= ~(1);
1836
1837        PDEBUG(DBG_FUNC, "usb %dx%d; screen %dx%d; stretch %dx%d",
1838                                                UsbWidth, UsbHeight, width, height,
1839                                                usbvision->stretch_width, usbvision->stretch_height);
1840
1841        /* I'll not rewrite the same values */
1842        if ((UsbWidth != usbvision->curwidth) || (UsbHeight != usbvision->curheight)) {
1843                value[0] = UsbWidth & 0xff;             //LSB
1844                value[1] = (UsbWidth >> 8) & 0x03;      //MSB
1845                value[2] = UsbHeight & 0xff;            //LSB
1846                value[3] = (UsbHeight >> 8) & 0x03;     //MSB
1847
1848                errCode = usb_control_msg(usbvision->dev, usb_sndctrlpipe(usbvision->dev, 1),
1849                             USBVISION_OP_CODE,
1850                             USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT,
1851                                 0, (__u16) USBVISION_LXSIZE_O, value, 4, HZ);
1852
1853                if (errCode < 0) {
1854                        dev_err(&usbvision->dev->dev,
1855                                "%s failed: error %d\n", __func__, errCode);
1856                        return errCode;
1857                }
1858                usbvision->curwidth = usbvision->stretch_width * UsbWidth;
1859                usbvision->curheight = usbvision->stretch_height * UsbHeight;
1860        }
1861
1862        if (usbvision->isocMode == ISOC_MODE_YUV422) {
1863                frameRate = (usbvision->isocPacketSize * 1000) / (UsbWidth * UsbHeight * 2);
1864        }
1865        else if (usbvision->isocMode == ISOC_MODE_YUV420) {
1866                frameRate = (usbvision->isocPacketSize * 1000) / ((UsbWidth * UsbHeight * 12) / 8);
1867        }
1868        else {
1869                frameRate = FRAMERATE_MAX;
1870        }
1871
1872        if (usbvision->tvnormId & V4L2_STD_625_50) {
1873                frameDrop = frameRate * 32 / 25 - 1;
1874        }
1875        else if (usbvision->tvnormId & V4L2_STD_525_60) {
1876                frameDrop = frameRate * 32 / 30 - 1;
1877        }
1878
1879        RESTRICT_TO_RANGE(frameDrop, FRAMERATE_MIN, FRAMERATE_MAX);
1880
1881        PDEBUG(DBG_FUNC, "frameRate %d fps, frameDrop %d", frameRate, frameDrop);
1882
1883        frameDrop = FRAMERATE_MAX;      // We can allow the maximum here, because dropping is controlled
1884
1885        /* frameDrop = 7; => framePhase = 1, 5, 9, 13, 17, 21, 25, 0, 4, 8, ...
1886                => frameSkip = 4;
1887                => frameRate = (7 + 1) * 25 / 32 = 200 / 32 = 6.25;
1888
1889           frameDrop = 9; => framePhase = 1, 5, 8, 11, 14, 17, 21, 24, 27, 1, 4, 8, ...
1890            => frameSkip = 4, 3, 3, 3, 3, 4, 3, 3, 3, 3, 4, ...
1891                => frameRate = (9 + 1) * 25 / 32 = 250 / 32 = 7.8125;
1892        */
1893        errCode = usbvision_write_reg(usbvision, USBVISION_FRM_RATE, frameDrop);
1894        return errCode;
1895}
1896
1897
1898/*
1899 * usbvision_frames_alloc
1900 * allocate the required frames
1901 */
1902int usbvision_frames_alloc(struct usb_usbvision *usbvision, int number_of_frames)
1903{
1904        int i;
1905
1906        /*needs to be page aligned cause the buffers can be mapped individually! */
1907        usbvision->max_frame_size =  PAGE_ALIGN(usbvision->curwidth *
1908                                                usbvision->curheight *
1909                                                usbvision->palette.bytes_per_pixel);
1910
1911        /* Try to do my best to allocate the frames the user want in the remaining memory */
1912        usbvision->num_frames = number_of_frames;
1913        while (usbvision->num_frames > 0) {
1914                usbvision->fbuf_size = usbvision->num_frames * usbvision->max_frame_size;
1915                if((usbvision->fbuf = usbvision_rvmalloc(usbvision->fbuf_size))) {
1916                        break;
1917                }
1918                usbvision->num_frames--;
1919        }
1920
1921        spin_lock_init(&usbvision->queue_lock);
1922        init_waitqueue_head(&usbvision->wait_frame);
1923        init_waitqueue_head(&usbvision->wait_stream);
1924
1925        /* Allocate all buffers */
1926        for (i = 0; i < usbvision->num_frames; i++) {
1927                usbvision->frame[i].index = i;
1928                usbvision->frame[i].grabstate = FrameState_Unused;
1929                usbvision->frame[i].data = usbvision->fbuf +
1930                        i * usbvision->max_frame_size;
1931                /*
1932                 * Set default sizes for read operation.
1933                 */
1934                usbvision->stretch_width = 1;
1935                usbvision->stretch_height = 1;
1936                usbvision->frame[i].width = usbvision->curwidth;
1937                usbvision->frame[i].height = usbvision->curheight;
1938                usbvision->frame[i].bytes_read = 0;
1939        }
1940        PDEBUG(DBG_FUNC, "allocated %d frames (%d bytes per frame)",usbvision->num_frames,usbvision->max_frame_size);
1941        return usbvision->num_frames;
1942}
1943
1944/*
1945 * usbvision_frames_free
1946 * frees memory allocated for the frames
1947 */
1948void usbvision_frames_free(struct usb_usbvision *usbvision)
1949{
1950        /* Have to free all that memory */
1951        PDEBUG(DBG_FUNC, "free %d frames",usbvision->num_frames);
1952
1953        if (usbvision->fbuf != NULL) {
1954                usbvision_rvfree(usbvision->fbuf, usbvision->fbuf_size);
1955                usbvision->fbuf = NULL;
1956
1957                usbvision->num_frames = 0;
1958        }
1959}
1960/*
1961 * usbvision_empty_framequeues()
1962 * prepare queues for incoming and outgoing frames
1963 */
1964void usbvision_empty_framequeues(struct usb_usbvision *usbvision)
1965{
1966        u32 i;
1967
1968        INIT_LIST_HEAD(&(usbvision->inqueue));
1969        INIT_LIST_HEAD(&(usbvision->outqueue));
1970
1971        for (i = 0; i < USBVISION_NUMFRAMES; i++) {
1972                usbvision->frame[i].grabstate = FrameState_Unused;
1973                usbvision->frame[i].bytes_read = 0;
1974        }
1975}
1976
1977/*
1978 * usbvision_stream_interrupt()
1979 * stops streaming
1980 */
1981int usbvision_stream_interrupt(struct usb_usbvision *usbvision)
1982{
1983        int ret = 0;
1984
1985        /* stop reading from the device */
1986
1987        usbvision->streaming = Stream_Interrupt;
1988        ret = wait_event_timeout(usbvision->wait_stream,
1989                                 (usbvision->streaming == Stream_Idle),
1990                                 msecs_to_jiffies(USBVISION_NUMSBUF*USBVISION_URB_FRAMES));
1991        return ret;
1992}
1993
1994/*
1995 * usbvision_set_compress_params()
1996 *
1997 */
1998
1999static int usbvision_set_compress_params(struct usb_usbvision *usbvision)
2000{
2001        static const char proc[] = "usbvision_set_compresion_params: ";
2002        int rc;
2003        unsigned char value[6];
2004
2005        value[0] = 0x0F;    // Intra-Compression cycle
2006        value[1] = 0x01;    // Reg.45 one line per strip
2007        value[2] = 0x00;    // Reg.46 Force intra mode on all new frames
2008        value[3] = 0x00;    // Reg.47 FORCE_UP <- 0 normal operation (not force)
2009        value[4] = 0xA2;    // Reg.48 BUF_THR I'm not sure if this does something in not compressed mode.
2010        value[5] = 0x00;    // Reg.49 DVI_YUV This has nothing to do with compression
2011
2012        //catched values for NT1004
2013        // value[0] = 0xFF; // Never apply intra mode automatically
2014        // value[1] = 0xF1; // Use full frame height for virtual strip width; One line per strip
2015        // value[2] = 0x01; // Force intra mode on all new frames
2016        // value[3] = 0x00; // Strip size 400 Bytes; do not force up
2017        // value[4] = 0xA2; //
2018        if (!USBVISION_IS_OPERATIONAL(usbvision))
2019                return 0;
2020
2021        rc = usb_control_msg(usbvision->dev, usb_sndctrlpipe(usbvision->dev, 1),
2022                             USBVISION_OP_CODE,
2023                             USB_DIR_OUT | USB_TYPE_VENDOR |
2024                             USB_RECIP_ENDPOINT, 0,
2025                             (__u16) USBVISION_INTRA_CYC, value, 5, HZ);
2026
2027        if (rc < 0) {
2028                printk(KERN_ERR "%sERROR=%d. USBVISION stopped - "
2029                       "reconnect or reload driver.\n", proc, rc);
2030                return rc;
2031        }
2032
2033        if (usbvision->bridgeType == BRIDGE_NT1004) {
2034                value[0] =  20; // PCM Threshold 1
2035                value[1] =  12; // PCM Threshold 2
2036                value[2] = 255; // Distorsion Threshold inter
2037                value[3] = 255; // Distorsion Threshold intra
2038                value[4] =  43; // Max Distorsion inter
2039                value[5] =  43; // Max Distorsion intra
2040        }
2041        else {
2042                value[0] =  20; // PCM Threshold 1
2043                value[1] =  12; // PCM Threshold 2
2044                value[2] = 255; // Distorsion Threshold d7-d0
2045                value[3] =   0; // Distorsion Threshold d11-d8
2046                value[4] =  43; // Max Distorsion d7-d0
2047                value[5] =   0; // Max Distorsion d8
2048        }
2049
2050        if (!USBVISION_IS_OPERATIONAL(usbvision))
2051                return 0;
2052
2053        rc = usb_control_msg(usbvision->dev, usb_sndctrlpipe(usbvision->dev, 1),
2054                             USBVISION_OP_CODE,
2055                             USB_DIR_OUT | USB_TYPE_VENDOR |
2056                             USB_RECIP_ENDPOINT, 0,
2057                             (__u16) USBVISION_PCM_THR1, value, 6, HZ);
2058
2059        if (rc < 0) {
2060                printk(KERN_ERR "%sERROR=%d. USBVISION stopped - "
2061                       "reconnect or reload driver.\n", proc, rc);
2062                return rc;
2063        }
2064
2065
2066        return rc;
2067}
2068
2069
2070/*
2071 * usbvision_set_input()
2072 *
2073 * Set the input (saa711x, ...) size x y and other misc input params
2074 * I've no idea if this parameters are right
2075 *
2076 */
2077int usbvision_set_input(struct usb_usbvision *usbvision)
2078{
2079        static const char proc[] = "usbvision_set_input: ";
2080        int rc;
2081        unsigned char value[8];
2082        unsigned char dvi_yuv_value;
2083
2084        if (!USBVISION_IS_OPERATIONAL(usbvision))
2085                return 0;
2086
2087        /* Set input format expected from decoder*/
2088        if (usbvision_device_data[usbvision->DevModel].Vin_Reg1_override) {
2089                value[0] = usbvision_device_data[usbvision->DevModel].Vin_Reg1;
2090        } else if(usbvision_device_data[usbvision->DevModel].Codec == CODEC_SAA7113) {
2091                /* SAA7113 uses 8 bit output */
2092                value[0] = USBVISION_8_422_SYNC;
2093        } else {
2094                /* I'm sure only about d2-d0 [010] 16 bit 4:2:2 usin sync pulses
2095                 * as that is how saa7111 is configured */
2096                value[0] = USBVISION_16_422_SYNC;
2097                /* | USBVISION_VSNC_POL | USBVISION_VCLK_POL);*/
2098        }
2099
2100        rc = usbvision_write_reg(usbvision, USBVISION_VIN_REG1, value[0]);
2101        if (rc < 0) {
2102                printk(KERN_ERR "%sERROR=%d. USBVISION stopped - "
2103                       "reconnect or reload driver.\n", proc, rc);
2104                return rc;
2105        }
2106
2107
2108        if (usbvision->tvnormId & V4L2_STD_PAL) {
2109                value[0] = 0xC0;
2110                value[1] = 0x02;        //0x02C0 -> 704 Input video line length
2111                value[2] = 0x20;
2112                value[3] = 0x01;        //0x0120 -> 288 Input video n. of lines
2113                value[4] = 0x60;
2114                value[5] = 0x00;        //0x0060 -> 96 Input video h offset
2115                value[6] = 0x16;
2116                value[7] = 0x00;        //0x0016 -> 22 Input video v offset
2117        } else if (usbvision->tvnormId & V4L2_STD_SECAM) {
2118                value[0] = 0xC0;
2119                value[1] = 0x02;        //0x02C0 -> 704 Input video line length
2120                value[2] = 0x20;
2121                value[3] = 0x01;        //0x0120 -> 288 Input video n. of lines
2122                value[4] = 0x01;
2123                value[5] = 0x00;        //0x0001 -> 01 Input video h offset
2124                value[6] = 0x01;
2125                value[7] = 0x00;        //0x0001 -> 01 Input video v offset
2126        } else {        /* V4L2_STD_NTSC */
2127                value[0] = 0xD0;
2128                value[1] = 0x02;        //0x02D0 -> 720 Input video line length
2129                value[2] = 0xF0;
2130                value[3] = 0x00;        //0x00F0 -> 240 Input video number of lines
2131                value[4] = 0x50;
2132                value[5] = 0x00;        //0x0050 -> 80 Input video h offset
2133                value[6] = 0x10;
2134                value[7] = 0x00;        //0x0010 -> 16 Input video v offset
2135        }
2136
2137        if (usbvision_device_data[usbvision->DevModel].X_Offset >= 0) {
2138                value[4]=usbvision_device_data[usbvision->DevModel].X_Offset & 0xff;
2139                value[5]=(usbvision_device_data[usbvision->DevModel].X_Offset & 0x0300) >> 8;
2140        }
2141
2142        if (adjust_X_Offset != -1) {
2143                value[4] = adjust_X_Offset & 0xff;
2144                value[5] = (adjust_X_Offset & 0x0300) >> 8;
2145        }
2146
2147        if (usbvision_device_data[usbvision->DevModel].Y_Offset >= 0) {
2148                value[6]=usbvision_device_data[usbvision->DevModel].Y_Offset & 0xff;
2149                value[7]=(usbvision_device_data[usbvision->DevModel].Y_Offset & 0x0300) >> 8;
2150        }
2151
2152        if (adjust_Y_Offset != -1) {
2153                value[6] = adjust_Y_Offset & 0xff;
2154                value[7] = (adjust_Y_Offset & 0x0300) >> 8;
2155        }
2156
2157        rc = usb_control_msg(usbvision->dev, usb_sndctrlpipe(usbvision->dev, 1),
2158                             USBVISION_OP_CODE, /* USBVISION specific code */
2159                             USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT, 0,
2160                             (__u16) USBVISION_LXSIZE_I, value, 8, HZ);
2161        if (rc < 0) {
2162                printk(KERN_ERR "%sERROR=%d. USBVISION stopped - "
2163                       "reconnect or reload driver.\n", proc, rc);
2164                return rc;
2165        }
2166
2167
2168        dvi_yuv_value = 0x00;   /* U comes after V, Ya comes after U/V, Yb comes after Yb */
2169
2170        if(usbvision_device_data[usbvision->DevModel].Dvi_yuv_override){
2171                dvi_yuv_value = usbvision_device_data[usbvision->DevModel].Dvi_yuv;
2172        }
2173        else if(usbvision_device_data[usbvision->DevModel].Codec == CODEC_SAA7113) {
2174        /* This changes as the fine sync control changes. Further investigation necessary */
2175                dvi_yuv_value = 0x06;
2176        }
2177
2178        return (usbvision_write_reg(usbvision, USBVISION_DVI_YUV, dvi_yuv_value));
2179}
2180
2181
2182/*
2183 * usbvision_set_dram_settings()
2184 *
2185 * Set the buffer address needed by the usbvision dram to operate
2186 * This values has been taken with usbsnoop.
2187 *
2188 */
2189
2190static int usbvision_set_dram_settings(struct usb_usbvision *usbvision)
2191{
2192        int rc;
2193        unsigned char value[8];
2194
2195        if (usbvision->isocMode == ISOC_MODE_COMPRESS) {
2196                value[0] = 0x42;
2197                value[1] = 0x71;
2198                value[2] = 0xff;
2199                value[3] = 0x00;
2200                value[4] = 0x98;
2201                value[5] = 0xe0;
2202                value[6] = 0x71;
2203                value[7] = 0xff;
2204                // UR:  0x0E200-0x3FFFF = 204288 Words (1 Word = 2 Byte)
2205                // FDL: 0x00000-0x0E099 =  57498 Words
2206                // VDW: 0x0E3FF-0x3FFFF
2207        }
2208        else {
2209                value[0] = 0x42;
2210                value[1] = 0x00;
2211                value[2] = 0xff;
2212                value[3] = 0x00;
2213                value[4] = 0x00;
2214                value[5] = 0x00;
2215                value[6] = 0x00;
2216                value[7] = 0xff;
2217        }
2218        /* These are the values of the address of the video buffer,
2219         * they have to be loaded into the USBVISION_DRM_PRM1-8
2220         *
2221         * Start address of video output buffer for read:       drm_prm1-2 -> 0x00000
2222         * End address of video output buffer for read:         drm_prm1-3 -> 0x1ffff
2223         * Start address of video frame delay buffer:           drm_prm1-4 -> 0x20000
2224         *    Only used in compressed mode
2225         * End address of video frame delay buffer:             drm_prm1-5-6 -> 0x3ffff
2226         *    Only used in compressed mode
2227         * Start address of video output buffer for write:      drm_prm1-7 -> 0x00000
2228         * End address of video output buffer for write:        drm_prm1-8 -> 0x1ffff
2229         */
2230
2231        if (!USBVISION_IS_OPERATIONAL(usbvision))
2232                return 0;
2233
2234        rc = usb_control_msg(usbvision->dev, usb_sndctrlpipe(usbvision->dev, 1),
2235                             USBVISION_OP_CODE, /* USBVISION specific code */
2236                             USB_DIR_OUT | USB_TYPE_VENDOR |
2237                             USB_RECIP_ENDPOINT, 0,
2238                             (__u16) USBVISION_DRM_PRM1, value, 8, HZ);
2239
2240        if (rc < 0) {
2241                dev_err(&usbvision->dev->dev, "%sERROR=%d\n", __func__, rc);
2242                return rc;
2243        }
2244
2245        /* Restart the video buffer logic */
2246        if ((rc = usbvision_write_reg(usbvision, USBVISION_DRM_CONT, USBVISION_RES_UR |
2247                                   USBVISION_RES_FDL | USBVISION_RES_VDW)) < 0)
2248                return rc;
2249        rc = usbvision_write_reg(usbvision, USBVISION_DRM_CONT, 0x00);
2250
2251        return rc;
2252}
2253
2254/*
2255 * ()
2256 *
2257 * Power on the device, enables suspend-resume logic
2258 * &  reset the isoc End-Point
2259 *
2260 */
2261
2262int usbvision_power_on(struct usb_usbvision *usbvision)
2263{
2264        int errCode = 0;
2265
2266        PDEBUG(DBG_FUNC, "");
2267
2268        usbvision_write_reg(usbvision, USBVISION_PWR_REG, USBVISION_SSPND_EN);
2269        usbvision_write_reg(usbvision, USBVISION_PWR_REG,
2270                         USBVISION_SSPND_EN | USBVISION_RES2);
2271
2272        usbvision_write_reg(usbvision, USBVISION_PWR_REG,
2273                         USBVISION_SSPND_EN | USBVISION_PWR_VID);
2274        errCode = usbvision_write_reg(usbvision, USBVISION_PWR_REG,
2275                                                USBVISION_SSPND_EN | USBVISION_PWR_VID | USBVISION_RES2);
2276        if (errCode == 1) {
2277                usbvision->power = 1;
2278        }
2279        PDEBUG(DBG_FUNC, "%s: errCode %d", (errCode<0)?"ERROR":"power is on", errCode);
2280        return errCode;
2281}
2282
2283
2284/*
2285 * usbvision timer stuff
2286 */
2287
2288// to call usbvision_power_off from task queue
2289static void call_usbvision_power_off(struct work_struct *work)
2290{
2291        struct usb_usbvision *usbvision = container_of(work, struct usb_usbvision, powerOffWork);
2292
2293        PDEBUG(DBG_FUNC, "");
2294        if(mutex_lock_interruptible(&usbvision->lock)) {
2295                return;
2296        }
2297
2298
2299        if(usbvision->user == 0) {
2300                usbvision_i2c_unregister(usbvision);
2301
2302                usbvision_power_off(usbvision);
2303                usbvision->initialized = 0;
2304        }
2305        mutex_unlock(&usbvision->lock);
2306}
2307
2308static void usbvision_powerOffTimer(unsigned long data)
2309{
2310        struct usb_usbvision *usbvision = (void *) data;
2311
2312        PDEBUG(DBG_FUNC, "");
2313        del_timer(&usbvision->powerOffTimer);
2314        INIT_WORK(&usbvision->powerOffWork, call_usbvision_power_off);
2315        (void) schedule_work(&usbvision->powerOffWork);
2316}
2317
2318void usbvision_init_powerOffTimer(struct usb_usbvision *usbvision)
2319{
2320        init_timer(&usbvision->powerOffTimer);
2321        usbvision->powerOffTimer.data = (long) usbvision;
2322        usbvision->powerOffTimer.function = usbvision_powerOffTimer;
2323}
2324
2325void usbvision_set_powerOffTimer(struct usb_usbvision *usbvision)
2326{
2327        mod_timer(&usbvision->powerOffTimer, jiffies + USBVISION_POWEROFF_TIME);
2328}
2329
2330void usbvision_reset_powerOffTimer(struct usb_usbvision *usbvision)
2331{
2332        if (timer_pending(&usbvision->powerOffTimer)) {
2333                del_timer(&usbvision->powerOffTimer);
2334        }
2335}
2336
2337/*
2338 * usbvision_begin_streaming()
2339 * Sure you have to put bit 7 to 0, if not incoming frames are droped, but no
2340 * idea about the rest
2341 */
2342int usbvision_begin_streaming(struct usb_usbvision *usbvision)
2343{
2344        int errCode = 0;
2345
2346        if (usbvision->isocMode == ISOC_MODE_COMPRESS) {
2347                usbvision_init_compression(usbvision);
2348        }
2349        errCode = usbvision_write_reg(usbvision, USBVISION_VIN_REG2, USBVISION_NOHVALID |
2350                                                                                usbvision->Vin_Reg2_Preset);
2351        return errCode;
2352}
2353
2354/*
2355 * usbvision_restart_isoc()
2356 * Not sure yet if touching here PWR_REG make loose the config
2357 */
2358
2359int usbvision_restart_isoc(struct usb_usbvision *usbvision)
2360{
2361        int ret;
2362
2363        if (
2364            (ret =
2365             usbvision_write_reg(usbvision, USBVISION_PWR_REG,
2366                              USBVISION_SSPND_EN | USBVISION_PWR_VID)) < 0)
2367                return ret;
2368        if (
2369            (ret =
2370             usbvision_write_reg(usbvision, USBVISION_PWR_REG,
2371                              USBVISION_SSPND_EN | USBVISION_PWR_VID |
2372                              USBVISION_RES2)) < 0)
2373                return ret;
2374        if (
2375            (ret =
2376             usbvision_write_reg(usbvision, USBVISION_VIN_REG2,
2377                              USBVISION_KEEP_BLANK | USBVISION_NOHVALID |
2378                                  usbvision->Vin_Reg2_Preset)) < 0) return ret;
2379
2380        /* TODO: schedule timeout */
2381        while ((usbvision_read_reg(usbvision, USBVISION_STATUS_REG) & 0x01) != 1);
2382
2383        return 0;
2384}
2385
2386int usbvision_audio_off(struct usb_usbvision *usbvision)
2387{
2388        if (usbvision_write_reg(usbvision, USBVISION_IOPIN_REG, USBVISION_AUDIO_MUTE) < 0) {
2389                printk(KERN_ERR "usbvision_audio_off: can't wirte reg\n");
2390                return -1;
2391        }
2392        usbvision->AudioMute = 0;
2393        usbvision->AudioChannel = USBVISION_AUDIO_MUTE;
2394        return 0;
2395}
2396
2397int usbvision_set_audio(struct usb_usbvision *usbvision, int AudioChannel)
2398{
2399        if (!usbvision->AudioMute) {
2400                if (usbvision_write_reg(usbvision, USBVISION_IOPIN_REG, AudioChannel) < 0) {
2401                        printk(KERN_ERR "usbvision_set_audio: can't write iopin register for audio switching\n");
2402                        return -1;
2403                }
2404        }
2405        usbvision->AudioChannel = AudioChannel;
2406        return 0;
2407}
2408
2409int usbvision_setup(struct usb_usbvision *usbvision,int format)
2410{
2411        usbvision_set_video_format(usbvision, format);
2412        usbvision_set_dram_settings(usbvision);
2413        usbvision_set_compress_params(usbvision);
2414        usbvision_set_input(usbvision);
2415        usbvision_set_output(usbvision, MAX_USB_WIDTH, MAX_USB_HEIGHT);
2416        usbvision_restart_isoc(usbvision);
2417
2418        /* cosas del PCM */
2419        return USBVISION_IS_OPERATIONAL(usbvision);
2420}
2421
2422int usbvision_set_alternate(struct usb_usbvision *dev)
2423{
2424        int errCode, prev_alt = dev->ifaceAlt;
2425        int i;
2426
2427        dev->ifaceAlt=0;
2428        for(i=0;i< dev->num_alt; i++)
2429                if(dev->alt_max_pkt_size[i]>dev->alt_max_pkt_size[dev->ifaceAlt])
2430                        dev->ifaceAlt=i;
2431
2432        if (dev->ifaceAlt != prev_alt) {
2433                dev->isocPacketSize = dev->alt_max_pkt_size[dev->ifaceAlt];
2434                PDEBUG(DBG_FUNC,"setting alternate %d with wMaxPacketSize=%u", dev->ifaceAlt,dev->isocPacketSize);
2435                errCode = usb_set_interface(dev->dev, dev->iface, dev->ifaceAlt);
2436                if (errCode < 0) {
2437                        dev_err(&dev->dev->dev,
2438                                "cannot change alternate number to %d (error=%i)\n",
2439                                        dev->ifaceAlt, errCode);
2440                        return errCode;
2441                }
2442        }
2443
2444        PDEBUG(DBG_ISOC, "ISO Packet Length:%d", dev->isocPacketSize);
2445
2446        return 0;
2447}
2448
2449/*
2450 * usbvision_init_isoc()
2451 *
2452 */
2453int usbvision_init_isoc(struct usb_usbvision *usbvision)
2454{
2455        struct usb_device *dev = usbvision->dev;
2456        int bufIdx, errCode, regValue;
2457        int sb_size;
2458
2459        if (!USBVISION_IS_OPERATIONAL(usbvision))
2460                return -EFAULT;
2461
2462        usbvision->curFrame = NULL;
2463        scratch_reset(usbvision);
2464
2465        /* Alternate interface 1 is is the biggest frame size */
2466        errCode = usbvision_set_alternate(usbvision);
2467        if (errCode < 0) {
2468                usbvision->last_error = errCode;
2469                return -EBUSY;
2470        }
2471        sb_size = USBVISION_URB_FRAMES * usbvision->isocPacketSize;
2472
2473        regValue = (16 - usbvision_read_reg(usbvision,
2474                                            USBVISION_ALTER_REG)) & 0x0F;
2475
2476        usbvision->usb_bandwidth = regValue >> 1;
2477        PDEBUG(DBG_ISOC, "USB Bandwidth Usage: %dMbit/Sec",
2478               usbvision->usb_bandwidth);
2479
2480
2481
2482        /* We double buffer the Iso lists */
2483
2484        for (bufIdx = 0; bufIdx < USBVISION_NUMSBUF; bufIdx++) {
2485                int j, k;
2486                struct urb *urb;
2487
2488                urb = usb_alloc_urb(USBVISION_URB_FRAMES, GFP_KERNEL);
2489                if (urb == NULL) {
2490                        dev_err(&usbvision->dev->dev,
2491                                "%s: usb_alloc_urb() failed\n", __func__);
2492                        return -ENOMEM;
2493                }
2494                usbvision->sbuf[bufIdx].urb = urb;
2495                usbvision->sbuf[bufIdx].data =
2496                        usb_alloc_coherent(usbvision->dev,
2497                                           sb_size,
2498                                           GFP_KERNEL,
2499                                           &urb->transfer_dma);
2500                urb->dev = dev;
2501                urb->context = usbvision;
2502                urb->pipe = usb_rcvisocpipe(dev, usbvision->video_endp);
2503                urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
2504                urb->interval = 1;
2505                urb->transfer_buffer = usbvision->sbuf[bufIdx].data;
2506                urb->complete = usbvision_isocIrq;
2507                urb->number_of_packets = USBVISION_URB_FRAMES;
2508                urb->transfer_buffer_length =
2509                    usbvision->isocPacketSize * USBVISION_URB_FRAMES;
2510                for (j = k = 0; j < USBVISION_URB_FRAMES; j++,
2511                     k += usbvision->isocPacketSize) {
2512                        urb->iso_frame_desc[j].offset = k;
2513                        urb->iso_frame_desc[j].length =
2514                                usbvision->isocPacketSize;
2515                }
2516        }
2517
2518        /* Submit all URBs */
2519        for (bufIdx = 0; bufIdx < USBVISION_NUMSBUF; bufIdx++) {
2520                        errCode = usb_submit_urb(usbvision->sbuf[bufIdx].urb,
2521                                                 GFP_KERNEL);
2522                if (errCode) {
2523                        dev_err(&usbvision->dev->dev,
2524                                "%s: usb_submit_urb(%d) failed: error %d\n",
2525                                        __func__, bufIdx, errCode);
2526                }
2527        }
2528
2529        usbvision->streaming = Stream_Idle;
2530        PDEBUG(DBG_ISOC, "%s: streaming=1 usbvision->video_endp=$%02x",
2531               __func__,
2532               usbvision->video_endp);
2533        return 0;
2534}
2535
2536/*
2537 * usbvision_stop_isoc()
2538 *
2539 * This procedure stops streaming and deallocates URBs. Then it
2540 * activates zero-bandwidth alt. setting of the video interface.
2541 *
2542 */
2543void usbvision_stop_isoc(struct usb_usbvision *usbvision)
2544{
2545        int bufIdx, errCode, regValue;
2546        int sb_size = USBVISION_URB_FRAMES * usbvision->isocPacketSize;
2547
2548        if ((usbvision->streaming == Stream_Off) || (usbvision->dev == NULL))
2549                return;
2550
2551        /* Unschedule all of the iso td's */
2552        for (bufIdx = 0; bufIdx < USBVISION_NUMSBUF; bufIdx++) {
2553                usb_kill_urb(usbvision->sbuf[bufIdx].urb);
2554                if (usbvision->sbuf[bufIdx].data){
2555                        usb_free_coherent(usbvision->dev,
2556                                          sb_size,
2557                                          usbvision->sbuf[bufIdx].data,
2558                                          usbvision->sbuf[bufIdx].urb->transfer_dma);
2559                }
2560                usb_free_urb(usbvision->sbuf[bufIdx].urb);
2561                usbvision->sbuf[bufIdx].urb = NULL;
2562        }
2563
2564        PDEBUG(DBG_ISOC, "%s: streaming=Stream_Off\n", __func__);
2565        usbvision->streaming = Stream_Off;
2566
2567        if (!usbvision->remove_pending) {
2568
2569                /* Set packet size to 0 */
2570                usbvision->ifaceAlt=0;
2571                errCode = usb_set_interface(usbvision->dev, usbvision->iface,
2572                                            usbvision->ifaceAlt);
2573                if (errCode < 0) {
2574                        dev_err(&usbvision->dev->dev,
2575                                "%s: usb_set_interface() failed: error %d\n",
2576                                        __func__, errCode);
2577                        usbvision->last_error = errCode;
2578                }
2579                regValue = (16-usbvision_read_reg(usbvision, USBVISION_ALTER_REG)) & 0x0F;
2580                usbvision->isocPacketSize =
2581                        (regValue == 0) ? 0 : (regValue * 64) - 1;
2582                PDEBUG(DBG_ISOC, "ISO Packet Length:%d",
2583                       usbvision->isocPacketSize);
2584
2585                usbvision->usb_bandwidth = regValue >> 1;
2586                PDEBUG(DBG_ISOC, "USB Bandwidth Usage: %dMbit/Sec",
2587                       usbvision->usb_bandwidth);
2588        }
2589}
2590
2591int usbvision_muxsel(struct usb_usbvision *usbvision, int channel)
2592{
2593        /* inputs #0 and #3 are constant for every SAA711x. */
2594        /* inputs #1 and #2 are variable for SAA7111 and SAA7113 */
2595        int mode[4]= {SAA7115_COMPOSITE0, 0, 0, SAA7115_COMPOSITE3};
2596        int audio[]= {1, 0, 0, 0};
2597        //channel 0 is TV with audiochannel 1 (tuner mono)
2598        //channel 1 is Composite with audio channel 0 (line in)
2599        //channel 2 is S-Video with audio channel 0 (line in)
2600        //channel 3 is additional video inputs to the device with audio channel 0 (line in)
2601
2602        RESTRICT_TO_RANGE(channel, 0, usbvision->video_inputs);
2603        usbvision->ctl_input = channel;
2604
2605        // set the new channel
2606        // Regular USB TV Tuners -> channel: 0 = Television, 1 = Composite, 2 = S-Video
2607        // Four video input devices -> channel: 0 = Chan White, 1 = Chan Green, 2 = Chan Yellow, 3 = Chan Red
2608
2609        switch (usbvision_device_data[usbvision->DevModel].Codec) {
2610                case CODEC_SAA7113:
2611                        mode[1] = SAA7115_COMPOSITE2;
2612                        if (SwitchSVideoInput) {
2613                                /* To handle problems with S-Video Input for
2614                                 * some devices.  Use SwitchSVideoInput
2615                                 * parameter when loading the module.*/
2616                                mode[2] = SAA7115_COMPOSITE1;
2617                        }
2618                        else {
2619                                mode[2] = SAA7115_SVIDEO1;
2620                        }
2621                        break;
2622                case CODEC_SAA7111:
2623                default:
2624                        /* modes for saa7111 */
2625                        mode[1] = SAA7115_COMPOSITE1;
2626                        mode[2] = SAA7115_SVIDEO1;
2627                        break;
2628        }
2629        call_all(usbvision, video, s_routing, mode[channel], 0, 0);
2630        usbvision_set_audio(usbvision, audio[channel]);
2631        return 0;
2632}
2633
2634/*
2635 * Overrides for Emacs so that we follow Linus's tabbing style.
2636 * ---------------------------------------------------------------------------
2637 * Local variables:
2638 * c-basic-offset: 8
2639 * End:
2640 */
2641