usbvision-core.c 72.9 KB
Newer Older
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 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/timer.h>
29
#include <linux/gfp.h>
30 31 32 33 34 35 36 37 38 39
#include <linux/mm.h>
#include <linux/highmem.h>
#include <linux/vmalloc.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/spinlock.h>
#include <asm/io.h>
#include <linux/videodev2.h>
#include <linux/i2c.h>

40 41
#include <media/saa7115.h>
#include <media/v4l2-common.h>
42 43
#include <media/tuner.h>

44
#include <linux/workqueue.h>
45 46 47

#include "usbvision.h"

48
static unsigned int core_debug;
49 50
module_param(core_debug,int,0644);
MODULE_PARM_DESC(core_debug,"enable debug messages [core]");
51

52
static unsigned int force_testpattern;
53 54 55
module_param(force_testpattern,int,0644);
MODULE_PARM_DESC(force_testpattern,"enable test pattern display [core]");

56 57 58
static int adjust_compression = 1;	/* Set the compression to be adaptive */
module_param(adjust_compression, int, 0444);
MODULE_PARM_DESC(adjust_compression, " Set the ADPCM compression for the device.  Default: 1 (On)");
59

60 61
/* To help people with Black and White output with using s-video input.
 * Some cables and input device are wired differently. */
62 63 64
static int switch_svideo_input;
module_param(switch_svideo_input, int, 0444);
MODULE_PARM_DESC(switch_svideo_input, " Set the S-Video input.  Some cables and input device are wired differently. Default: 0 (Off)");
65

66 67 68
static unsigned int adjust_x_offset = -1;
module_param(adjust_x_offset, int, 0644);
MODULE_PARM_DESC(adjust_x_offset, "adjust X offset display [core]");
69

70 71 72
static unsigned int adjust_y_offset = -1;
module_param(adjust_y_offset, int, 0644);
MODULE_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 80
	#define PDEBUG(level, fmt, args...) { \
		if (core_debug & (level)) \
81 82
			printk(KERN_INFO KBUILD_MODNAME ":[%s:%d] " fmt, \
				__func__, __LINE__ , ## args); \
83
	}
84 85 86 87
#else
	#define PDEBUG(level, fmt, args...) do {} while(0)
#endif

88 89 90 91 92
#define DBG_HEADER	1<<0
#define DBG_IRQ		1<<1
#define DBG_ISOC	1<<2
#define DBG_PARSE	1<<3
#define DBG_SCRATCH	1<<4
93
#define DBG_FUNC	1<<5
94 95 96 97 98 99

static const int max_imgwidth = MAX_FRAME_WIDTH;
static const int max_imgheight = MAX_FRAME_HEIGHT;
static const int min_imgwidth = MIN_FRAME_WIDTH;
static const int min_imgheight = MIN_FRAME_HEIGHT;

100
/* The value of 'scratch_buf_size' affects quality of the picture
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
 * in many ways. Shorter buffers may cause loss of data when client
 * is too slow. Larger buffers are memory-consuming and take longer
 * to work with. This setting can be adjusted, but the default value
 * should be OK for most desktop users.
 */
#define DEFAULT_SCRATCH_BUF_SIZE	(0x20000)		// 128kB memory scratch buffer
static const int scratch_buf_size = DEFAULT_SCRATCH_BUF_SIZE;

// Function prototypes
static int usbvision_request_intra (struct usb_usbvision *usbvision);
static int usbvision_unrequest_intra (struct usb_usbvision *usbvision);
static int usbvision_adjust_compression (struct usb_usbvision *usbvision);
static int usbvision_measure_bandwidth (struct usb_usbvision *usbvision);

/*******************************/
/* Memory management functions */
/*******************************/

/*
 * Here we want the physical address of the memory.
 * This is used when initializing the contents of the area.
 */

124
static void *usbvision_rvmalloc(unsigned long size)
125 126 127 128 129 130 131 132 133 134
{
	void *mem;
	unsigned long adr;

	size = PAGE_ALIGN(size);
	mem = vmalloc_32(size);
	if (!mem)
		return NULL;

	memset(mem, 0, size); /* Clear the ram out, no junk to the user */
135 136 137 138 139 140 141 142
	adr = (unsigned long) mem;
	while (size > 0) {
		SetPageReserved(vmalloc_to_page((void *)adr));
		adr += PAGE_SIZE;
		size -= PAGE_SIZE;
	}

	return mem;
143 144
}

145
static void usbvision_rvfree(void *mem, unsigned long size)
146
{
147 148 149 150
	unsigned long adr;

	if (!mem)
		return;
151

152
	size = PAGE_ALIGN(size);
153

154 155 156 157 158 159
	adr = (unsigned long) mem;
	while ((long) size > 0) {
		ClearPageReserved(vmalloc_to_page((void *)adr));
		adr += PAGE_SIZE;
		size -= PAGE_SIZE;
	}
160

161 162
	vfree(mem);
}
163 164 165 166 167


#if ENABLE_HEXDUMP
static void usbvision_hexdump(const unsigned char *data, int len)
{
168 169 170 171 172 173 174 175 176 177 178 179
	char tmp[80];
	int i, k;

	for (i = k = 0; len > 0; i++, len--) {
		if (i > 0 && (i % 16 == 0)) {
			printk("%s\n", tmp);
			k = 0;
		}
		k += sprintf(&tmp[k], "%02x ", data[i]);
	}
	if (k > 0)
		printk("%s\n", tmp);
180 181 182
}
#endif

183 184 185
/********************************
 * scratch ring buffer handling
 ********************************/
186
static int scratch_len(struct usb_usbvision *usbvision)    /*This returns the amount of data actually in the buffer */
187 188 189 190 191 192 193 194 195 196 197 198
{
	int len = usbvision->scratch_write_ptr - usbvision->scratch_read_ptr;
	if (len < 0) {
		len += scratch_buf_size;
	}
	PDEBUG(DBG_SCRATCH, "scratch_len() = %d\n", len);

	return len;
}


/* This returns the free space left in the buffer */
199
static int scratch_free(struct usb_usbvision *usbvision)
200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215
{
	int free = usbvision->scratch_read_ptr - usbvision->scratch_write_ptr;
	if (free <= 0) {
		free += scratch_buf_size;
	}
	if (free) {
		free -= 1;							/* at least one byte in the buffer must */
										/* left blank, otherwise there is no chance to differ between full and empty */
	}
	PDEBUG(DBG_SCRATCH, "return %d\n", free);

	return free;
}


/* This puts data into the buffer */
216 217
static int scratch_put(struct usb_usbvision *usbvision, unsigned char *data,
		       int len)
218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242
{
	int len_part;

	if (usbvision->scratch_write_ptr + len < scratch_buf_size) {
		memcpy(usbvision->scratch + usbvision->scratch_write_ptr, data, len);
		usbvision->scratch_write_ptr += len;
	}
	else {
		len_part = scratch_buf_size - usbvision->scratch_write_ptr;
		memcpy(usbvision->scratch + usbvision->scratch_write_ptr, data, len_part);
		if (len == len_part) {
			usbvision->scratch_write_ptr = 0;			/* just set write_ptr to zero */
		}
		else {
			memcpy(usbvision->scratch, data + len_part, len - len_part);
			usbvision->scratch_write_ptr = len - len_part;
		}
	}

	PDEBUG(DBG_SCRATCH, "len=%d, new write_ptr=%d\n", len, usbvision->scratch_write_ptr);

	return len;
}

/* This marks the write_ptr as position of new frame header */
243
static void scratch_mark_header(struct usb_usbvision *usbvision)
244 245 246 247 248 249 250 251 252 253
{
	PDEBUG(DBG_SCRATCH, "header at write_ptr=%d\n", usbvision->scratch_headermarker_write_ptr);

	usbvision->scratch_headermarker[usbvision->scratch_headermarker_write_ptr] =
				usbvision->scratch_write_ptr;
	usbvision->scratch_headermarker_write_ptr += 1;
	usbvision->scratch_headermarker_write_ptr %= USBVISION_NUM_HEADERMARKER;
}

/* This gets data from the buffer at the given "ptr" position */
254 255
static int scratch_get_extra(struct usb_usbvision *usbvision,
			     unsigned char *data, int *ptr, int len)
256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280
{
	int len_part;
	if (*ptr + len < scratch_buf_size) {
		memcpy(data, usbvision->scratch + *ptr, len);
		*ptr += len;
	}
	else {
		len_part = scratch_buf_size - *ptr;
		memcpy(data, usbvision->scratch + *ptr, len_part);
		if (len == len_part) {
			*ptr = 0;							/* just set the y_ptr to zero */
		}
		else {
			memcpy(data + len_part, usbvision->scratch, len - len_part);
			*ptr = len - len_part;
		}
	}

	PDEBUG(DBG_SCRATCH, "len=%d, new ptr=%d\n", len, *ptr);

	return len;
}


/* This sets the scratch extra read pointer */
281 282
static void scratch_set_extra_ptr(struct usb_usbvision *usbvision, int *ptr,
				  int len)
283 284 285 286 287 288 289 290
{
	*ptr = (usbvision->scratch_read_ptr + len)%scratch_buf_size;

	PDEBUG(DBG_SCRATCH, "ptr=%d\n", *ptr);
}


/*This increments the scratch extra read pointer */
291
static void scratch_inc_extra_ptr(int *ptr, int len)
292 293 294 295 296 297 298 299
{
	*ptr = (*ptr + len) % scratch_buf_size;

	PDEBUG(DBG_SCRATCH, "ptr=%d\n", *ptr);
}


/* This gets data from the buffer */
300 301
static int scratch_get(struct usb_usbvision *usbvision, unsigned char *data,
		       int len)
302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326
{
	int len_part;
	if (usbvision->scratch_read_ptr + len < scratch_buf_size) {
		memcpy(data, usbvision->scratch + usbvision->scratch_read_ptr, len);
		usbvision->scratch_read_ptr += len;
	}
	else {
		len_part = scratch_buf_size - usbvision->scratch_read_ptr;
		memcpy(data, usbvision->scratch + usbvision->scratch_read_ptr, len_part);
		if (len == len_part) {
			usbvision->scratch_read_ptr = 0;				/* just set the read_ptr to zero */
		}
		else {
			memcpy(data + len_part, usbvision->scratch, len - len_part);
			usbvision->scratch_read_ptr = len - len_part;
		}
	}

	PDEBUG(DBG_SCRATCH, "len=%d, new read_ptr=%d\n", len, usbvision->scratch_read_ptr);

	return len;
}


/* This sets read pointer to next header and returns it */
327 328
static int scratch_get_header(struct usb_usbvision *usbvision,
			      struct usbvision_frame_header *header)
329
{
330
	int err_code = 0;
331 332 333 334 335 336 337 338 339 340 341 342

	PDEBUG(DBG_SCRATCH, "from read_ptr=%d", usbvision->scratch_headermarker_read_ptr);

	while (usbvision->scratch_headermarker_write_ptr -
		usbvision->scratch_headermarker_read_ptr != 0) {
		usbvision->scratch_read_ptr =
			usbvision->scratch_headermarker[usbvision->scratch_headermarker_read_ptr];
		usbvision->scratch_headermarker_read_ptr += 1;
		usbvision->scratch_headermarker_read_ptr %= USBVISION_NUM_HEADERMARKER;
		scratch_get(usbvision, (unsigned char *)header, USBVISION_HEADER_LENGTH);
		if ((header->magic_1 == USBVISION_MAGIC_1)
			 && (header->magic_2 == USBVISION_MAGIC_2)
343 344 345 346
			 && (header->header_length == USBVISION_HEADER_LENGTH)) {
			err_code = USBVISION_HEADER_LENGTH;
			header->frame_width  = header->frame_width_lo  + (header->frame_width_hi << 8);
			header->frame_height = header->frame_height_lo + (header->frame_height_hi << 8);
347 348 349 350
			break;
		}
	}

351
	return err_code;
352 353 354 355
}


/*This removes len bytes of old data from the buffer */
356
static void scratch_rm_old(struct usb_usbvision *usbvision, int len)
357 358 359 360 361 362 363 364 365
{

	usbvision->scratch_read_ptr += len;
	usbvision->scratch_read_ptr %= scratch_buf_size;
	PDEBUG(DBG_SCRATCH, "read_ptr is now %d\n", usbvision->scratch_read_ptr);
}


/*This resets the buffer - kills all data in it too */
366
static void scratch_reset(struct usb_usbvision *usbvision)
367 368 369 370 371 372 373
{
	PDEBUG(DBG_SCRATCH, "\n");

	usbvision->scratch_read_ptr = 0;
	usbvision->scratch_write_ptr = 0;
	usbvision->scratch_headermarker_read_ptr = 0;
	usbvision->scratch_headermarker_write_ptr = 0;
374
	usbvision->isocstate = isoc_state_no_frame;
375 376
}

377
int usbvision_scratch_alloc(struct usb_usbvision *usbvision)
378
{
379
	usbvision->scratch = vmalloc_32(scratch_buf_size);
380 381
	scratch_reset(usbvision);
	if(usbvision->scratch == NULL) {
382 383 384
		dev_err(&usbvision->dev->dev,
			"%s: unable to allocate %d bytes for scratch\n",
				__func__, scratch_buf_size);
385
		return -ENOMEM;
386
	}
387
	return 0;
388 389
}

390
void usbvision_scratch_free(struct usb_usbvision *usbvision)
391
{
392 393 394
	vfree(usbvision->scratch);
	usbvision->scratch = NULL;

395 396 397 398 399 400 401 402 403
}

/*
 * usbvision_testpattern()
 *
 * Procedure forms a test pattern (yellow grid on blue background).
 *
 * Parameters:
 * 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
 *
 */
409 410
static void usbvision_testpattern(struct usb_usbvision *usbvision,
				  int fullframe, int pmode)
411 412 413 414 415 416
{
	static const char proc[] = "usbvision_testpattern";
	struct usbvision_frame *frame;
	unsigned char *f;
	int num_cell = 0;
	int scan_length = 0;
417
	static int num_pass;
418 419 420 421 422

	if (usbvision == NULL) {
		printk(KERN_ERR "%s: usbvision == NULL\n", proc);
		return;
	}
423 424
	if (usbvision->cur_frame == NULL) {
		printk(KERN_ERR "%s: usbvision->cur_frame is NULL.\n", proc);
425 426 427 428
		return;
	}

	/* Grab the current frame */
429
	frame = usbvision->cur_frame;
430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475

	/* Optionally start at the beginning */
	if (fullframe) {
		frame->curline = 0;
		frame->scanlength = 0;
	}

	/* Form every scan line */
	for (; frame->curline < frame->frmheight; frame->curline++) {
		int i;

		f = frame->data + (usbvision->curwidth * 3 * frame->curline);
		for (i = 0; i < usbvision->curwidth; i++) {
			unsigned char cb = 0x80;
			unsigned char cg = 0;
			unsigned char cr = 0;

			if (pmode == 1) {
				if (frame->curline % 32 == 0)
					cb = 0, cg = cr = 0xFF;
				else if (i % 32 == 0) {
					if (frame->curline % 32 == 1)
						num_cell++;
					cb = 0, cg = cr = 0xFF;
				} else {
					cb =
					    ((num_cell * 7) +
					     num_pass) & 0xFF;
					cg =
					    ((num_cell * 5) +
					     num_pass * 2) & 0xFF;
					cr =
					    ((num_cell * 3) +
					     num_pass * 3) & 0xFF;
				}
			} else {
				/* Just the blue screen */
			}

			*f++ = cb;
			*f++ = cg;
			*f++ = cr;
			scan_length += 3;
		}
	}

476
	frame->grabstate = frame_state_done;
477 478 479 480 481 482
	frame->scanlength += scan_length;
	++num_pass;

}

/*
483 484 485
 * usbvision_decompress_alloc()
 *
 * allocates intermediate buffer for decompression
486
 */
487 488 489
int usbvision_decompress_alloc(struct usb_usbvision *usbvision)
{
	int IFB_size = MAX_FRAME_WIDTH * MAX_FRAME_HEIGHT * 3 / 2;
490 491
	usbvision->intra_frame_buffer = vmalloc_32(IFB_size);
	if (usbvision->intra_frame_buffer == NULL) {
492 493 494
		dev_err(&usbvision->dev->dev,
			"%s: unable to allocate %d for compr. frame buffer\n",
				__func__, IFB_size);
495 496 497 498 499 500 501 502 503 504 505 506
		return -ENOMEM;
	}
	return 0;
}

/*
 * usbvision_decompress_free()
 *
 * frees intermediate buffer for decompression
 */
void usbvision_decompress_free(struct usb_usbvision *usbvision)
{
507 508
	vfree(usbvision->intra_frame_buffer);
	usbvision->intra_frame_buffer = NULL;
509

510 511 512 513 514
}

/************************************************************
 * Here comes the data parsing stuff that is run as interrupt
 ************************************************************/
515 516 517 518 519
/*
 * usbvision_find_header()
 *
 * Locate one of supported header markers in the scratch buffer.
 */
520
static enum parse_state usbvision_find_header(struct usb_usbvision *usbvision)
521 522
{
	struct usbvision_frame *frame;
523
	int found_header = 0;
524

525
	frame = usbvision->cur_frame;
526

527
	while (scratch_get_header(usbvision, &frame->isoc_header) == USBVISION_HEADER_LENGTH) {
528 529
		// found header in scratch
		PDEBUG(DBG_HEADER, "found header: 0x%02x%02x %d %d %d %d %#x 0x%02x %u %u",
530 531 532 533 534 535 536 537 538 539 540 541 542 543 544
				frame->isoc_header.magic_2,
				frame->isoc_header.magic_1,
				frame->isoc_header.header_length,
				frame->isoc_header.frame_num,
				frame->isoc_header.frame_phase,
				frame->isoc_header.frame_latency,
				frame->isoc_header.data_format,
				frame->isoc_header.format_param,
				frame->isoc_header.frame_width,
				frame->isoc_header.frame_height);

		if (usbvision->request_intra) {
			if (frame->isoc_header.format_param & 0x80) {
				found_header = 1;
				usbvision->last_isoc_frame_num = -1; // do not check for lost frames this time
545 546 547 548 549
				usbvision_unrequest_intra(usbvision);
				break;
			}
		}
		else {
550
			found_header = 1;
551 552 553 554
			break;
		}
	}

555 556 557
	if (found_header) {
		frame->frmwidth = frame->isoc_header.frame_width * usbvision->stretch_width;
		frame->frmheight = frame->isoc_header.frame_height * usbvision->stretch_height;
558 559 560 561 562
		frame->v4l2_linesize = (frame->frmwidth * frame->v4l2_format.depth)>> 3;
	}
	else { // no header found
		PDEBUG(DBG_HEADER, "skipping scratch data, no header");
		scratch_reset(usbvision);
563
		return parse_state_end_parse;
564 565 566
	}

	// found header
567 568 569 570
	if (frame->isoc_header.data_format==ISOC_MODE_COMPRESS) {
		//check isoc_header.frame_num for lost frames
		if (usbvision->last_isoc_frame_num >= 0) {
			if (((usbvision->last_isoc_frame_num + 1) % 32) != frame->isoc_header.frame_num) {
571
				// unexpected frame drop: need to request new intra frame
572
				PDEBUG(DBG_HEADER, "Lost frame before %d on USB", frame->isoc_header.frame_num);
573
				usbvision_request_intra(usbvision);
574
				return parse_state_next_frame;
575 576
			}
		}
577
		usbvision->last_isoc_frame_num = frame->isoc_header.frame_num;
578 579
	}
	usbvision->header_count++;
580
	frame->scanstate = scan_state_lines;
581 582
	frame->curline = 0;

583
	if (force_testpattern) {
584
		usbvision_testpattern(usbvision, 1, 1);
585
		return parse_state_next_frame;
586
	}
587
	return parse_state_continue;
588 589
}

590
static enum parse_state usbvision_parse_lines_422(struct usb_usbvision *usbvision,
591 592 593 594 595 596 597 598 599 600 601
					   long *pcopylen)
{
	volatile struct usbvision_frame *frame;
	unsigned char *f;
	int len;
	int i;
	unsigned char yuyv[4]={180, 128, 10, 128}; // YUV components
	unsigned char rv, gv, bv;	// RGB components
	int clipmask_index, bytes_per_pixel;
	int stretch_bytes, clipmask_add;

602
	frame  = usbvision->cur_frame;
603
	f = frame->data + (frame->v4l2_linesize * frame->curline);
604 605

	/* Make sure there's enough data for the entire line */
606
	len = (frame->isoc_header.frame_width * 2)+5;
607 608
	if (scratch_len(usbvision) < len) {
		PDEBUG(DBG_PARSE, "out of data in line %d, need %u.\n", frame->curline, len);
609
		return parse_state_out;
610 611 612
	}

	if ((frame->curline + 1) >= frame->frmheight) {
613
		return parse_state_next_frame;
614 615 616 617 618 619 620 621 622 623 624
	}

	bytes_per_pixel = frame->v4l2_format.bytes_per_pixel;
	stretch_bytes = (usbvision->stretch_width - 1) * bytes_per_pixel;
	clipmask_index = frame->curline * MAX_FRAME_WIDTH;
	clipmask_add = usbvision->stretch_width;

	for (i = 0; i < frame->frmwidth; i+=(2 * usbvision->stretch_width)) {

		scratch_get(usbvision, &yuyv[0], 4);

625
		if (frame->v4l2_format.format == V4L2_PIX_FMT_YUYV) {
626 627 628 629 630 631 632
			*f++ = yuyv[0]; // Y
			*f++ = yuyv[3]; // U
		}
		else {

			YUV_TO_RGB_BY_THE_BOOK(yuyv[0], yuyv[1], yuyv[3], rv, gv, bv);
			switch (frame->v4l2_format.format) {
633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655
			case V4L2_PIX_FMT_RGB565:
				*f++ = (0x1F & rv) |
					(0xE0 & (gv << 5));
				*f++ = (0x07 & (gv >> 3)) |
					(0xF8 &  bv);
				break;
			case V4L2_PIX_FMT_RGB24:
				*f++ = rv;
				*f++ = gv;
				*f++ = bv;
				break;
			case V4L2_PIX_FMT_RGB32:
				*f++ = rv;
				*f++ = gv;
				*f++ = bv;
				f++;
				break;
			case V4L2_PIX_FMT_RGB555:
				*f++ = (0x1F & rv) |
					(0xE0 & (gv << 5));
				*f++ = (0x03 & (gv >> 3)) |
					(0x7C & (bv << 2));
				break;
656 657 658 659 660
			}
		}
		clipmask_index += clipmask_add;
		f += stretch_bytes;

661
		if (frame->v4l2_format.format == V4L2_PIX_FMT_YUYV) {
662 663 664 665 666 667 668
			*f++ = yuyv[2]; // Y
			*f++ = yuyv[1]; // V
		}
		else {

			YUV_TO_RGB_BY_THE_BOOK(yuyv[2], yuyv[1], yuyv[3], rv, gv, bv);
			switch (frame->v4l2_format.format) {
669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691
			case V4L2_PIX_FMT_RGB565:
				*f++ = (0x1F & rv) |
					(0xE0 & (gv << 5));
				*f++ = (0x07 & (gv >> 3)) |
					(0xF8 &  bv);
				break;
			case V4L2_PIX_FMT_RGB24:
				*f++ = rv;
				*f++ = gv;
				*f++ = bv;
				break;
			case V4L2_PIX_FMT_RGB32:
				*f++ = rv;
				*f++ = gv;
				*f++ = bv;
				f++;
				break;
			case V4L2_PIX_FMT_RGB555:
				*f++ = (0x1F & rv) |
					(0xE0 & (gv << 5));
				*f++ = (0x03 & (gv >> 3)) |
					(0x7C & (bv << 2));
				break;
692 693 694 695 696 697 698 699 700 701
			}
		}
		clipmask_index += clipmask_add;
		f += stretch_bytes;
	}

	frame->curline += usbvision->stretch_height;
	*pcopylen += frame->v4l2_linesize * usbvision->stretch_height;

	if (frame->curline >= frame->frmheight) {
702
		return parse_state_next_frame;
703 704
	}
	else {
705
		return parse_state_continue;
706 707 708
	}
}

709
/* The decompression routine  */
710 711 712
static int usbvision_decompress(struct usb_usbvision *usbvision,unsigned char *compressed,
								unsigned char *decompressed, int *start_pos,
								int *block_typestart_pos, int len)
713
{
714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736
	int rest_pixel, idx, max_pos, pos, extra_pos, block_len, block_type_pos, block_type_len;
	unsigned char block_byte, block_code, block_type, block_type_byte, integrator;

	integrator = 0;
	pos = *start_pos;
	block_type_pos = *block_typestart_pos;
	max_pos = 396; //pos + len;
	extra_pos = pos;
	block_len = 0;
	block_byte = 0;
	block_code = 0;
	block_type = 0;
	block_type_byte = 0;
	block_type_len = 0;
	rest_pixel = len;

	for (idx = 0; idx < len; idx++) {

		if (block_len == 0) {
			if (block_type_len==0) {
				block_type_byte = compressed[block_type_pos];
				block_type_pos++;
				block_type_len = 4;
737
			}
738
			block_type = (block_type_byte & 0xC0) >> 6;
739 740

			//statistic:
741 742 743 744 745 746 747 748
			usbvision->compr_block_types[block_type]++;

			pos = extra_pos;
			if (block_type == 0) {
				if(rest_pixel >= 24) {
					idx += 23;
					rest_pixel -= 24;
					integrator = decompressed[idx];
749
				} else {
750 751
					idx += rest_pixel - 1;
					rest_pixel = 0;
752 753
				}
			} else {
754 755 756 757
				block_code = compressed[pos];
				pos++;
				if (rest_pixel >= 24) {
					block_len  = 24;
758
				} else {
759
					block_len = rest_pixel;
760
				}
761 762
				rest_pixel -= block_len;
				extra_pos = pos + (block_len / 4);
763
			}
764 765
			block_type_byte <<= 2;
			block_type_len -= 1;
766
		}
767 768 769 770
		if (block_len > 0) {
			if ((block_len%4) == 0) {
				block_byte = compressed[pos];
				pos++;
771
			}
772 773
			if (block_type == 1) { //inter Block
				integrator = decompressed[idx];
774
			}
775
			switch (block_byte & 0xC0) {
776
				case 0x03<<6:
777 778
					integrator += compressed[extra_pos];
					extra_pos++;
779 780
					break;
				case 0x02<<6:
781
					integrator += block_code;
782 783
					break;
				case 0x00:
784
					integrator -= block_code;
785 786
					break;
			}
787 788 789
			decompressed[idx] = integrator;
			block_byte <<= 2;
			block_len -= 1;
790 791
		}
	}
792 793 794
	*start_pos = extra_pos;
	*block_typestart_pos = block_type_pos;
	return idx;
795 796 797 798 799 800 801 802 803 804 805
}


/*
 * usbvision_parse_compress()
 *
 * Parse compressed frame from the scratch buffer, put
 * decoded RGB value into the current frame buffer and add the written
 * number of bytes (RGB) to the *pcopylen.
 *
 */
806
static enum parse_state usbvision_parse_compress(struct usb_usbvision *usbvision,
807 808 809 810 811 812 813 814
					   long *pcopylen)
{
#define USBVISION_STRIP_MAGIC		0x5A
#define USBVISION_STRIP_LEN_MAX		400
#define USBVISION_STRIP_HEADER_LEN	3

	struct usbvision_frame *frame;
	unsigned char *f,*u = NULL ,*v = NULL;
815 816 817
	unsigned char strip_data[USBVISION_STRIP_LEN_MAX];
	unsigned char strip_header[USBVISION_STRIP_HEADER_LEN];
	int idx, idx_end, strip_len, strip_ptr, Startblock_pos, block_pos, block_type_pos;
818
	int clipmask_index, bytes_per_pixel, rc;
819
	int image_size;
820 821 822
	unsigned char rv, gv, bv;
	static unsigned char *Y, *U, *V;

823 824
	frame  = usbvision->cur_frame;
	image_size = frame->frmwidth * frame->frmheight;
825 826 827 828 829 830 831 832 833 834 835
	if ( (frame->v4l2_format.format == V4L2_PIX_FMT_YUV422P) ||
	     (frame->v4l2_format.format == V4L2_PIX_FMT_YVU420) ) {       // this is a planar format
		//... v4l2_linesize not used here.
		f = frame->data + (frame->width * frame->curline);
	} else
		f = frame->data + (frame->v4l2_linesize * frame->curline);

	if (frame->v4l2_format.format == V4L2_PIX_FMT_YUYV){ //initialise u and v pointers
		// get base of u and b planes add halfoffset

		u = frame->data
836
			+ image_size
837
			+ (frame->frmwidth >>1) * frame->curline ;
838
		v = u + (image_size >>1 );
839 840 841

	} else if (frame->v4l2_format.format == V4L2_PIX_FMT_YVU420){

842 843
		v = frame->data + image_size + ((frame->curline* (frame->width))>>2) ;
		u = v + (image_size >>2) ;
844 845 846 847 848 849 850
	}

	if (frame->curline == 0) {
		usbvision_adjust_compression(usbvision);
	}

	if (scratch_len(usbvision) < USBVISION_STRIP_HEADER_LEN) {
851
		return parse_state_out;
852 853 854
	}

	//get strip header without changing the scratch_read_ptr
855 856
	scratch_set_extra_ptr(usbvision, &strip_ptr, 0);
	scratch_get_extra(usbvision, &strip_header[0], &strip_ptr,
857 858
				USBVISION_STRIP_HEADER_LEN);

859
	if (strip_header[0] != USBVISION_STRIP_MAGIC) {
860
		// wrong strip magic
861 862
		usbvision->strip_magic_errors++;
		return parse_state_next_frame;
863 864
	}

865
	if (frame->curline != (int)strip_header[2]) {
866
		//line number missmatch error
867
		usbvision->strip_line_number_errors++;
868 869
	}

870 871
	strip_len = 2 * (unsigned int)strip_header[1];
	if (strip_len > USBVISION_STRIP_LEN_MAX) {
872 873 874 875 876
		// strip overrun
		// I think this never happens
		usbvision_request_intra(usbvision);
	}

877
	if (scratch_len(usbvision) < strip_len) {
878
		//there is not enough data for the strip
879
		return parse_state_out;
880 881
	}

882 883 884 885
	if (usbvision->intra_frame_buffer) {
		Y = usbvision->intra_frame_buffer + frame->frmwidth * frame->curline;
		U = usbvision->intra_frame_buffer + image_size + (frame->frmwidth / 2) * (frame->curline / 2);
		V = usbvision->intra_frame_buffer + image_size / 4 * 5 + (frame->frmwidth / 2) * (frame->curline / 2);
886 887
	}
	else {
888
		return parse_state_next_frame;
889 890
	}

891
	bytes_per_pixel = frame->v4l2_format.bytes_per_pixel;
892 893
	clipmask_index = frame->curline * MAX_FRAME_WIDTH;

894
	scratch_get(usbvision, strip_data, strip_len);
895

896 897 898 899
	idx_end = frame->frmwidth;
	block_type_pos = USBVISION_STRIP_HEADER_LEN;
	Startblock_pos = block_type_pos + (idx_end - 1) / 96 + (idx_end / 2 - 1) / 96 + 2;
	block_pos = Startblock_pos;
900

901
	usbvision->block_pos = block_pos;
902

903 904
	if ((rc = usbvision_decompress(usbvision, strip_data, Y, &block_pos, &block_type_pos, idx_end)) != idx_end) {
		//return parse_state_continue;
905
	}
906 907
	if (strip_len > usbvision->max_strip_len) {
		usbvision->max_strip_len = strip_len;
908 909 910
	}

	if (frame->curline%2) {
911 912
		if ((rc = usbvision_decompress(usbvision, strip_data, V, &block_pos, &block_type_pos, idx_end/2)) != idx_end/2) {
		//return parse_state_continue;
913 914 915
		}
	}
	else {
916 917
		if ((rc = usbvision_decompress(usbvision, strip_data, U, &block_pos, &block_type_pos, idx_end/2)) != idx_end/2) {
			//return parse_state_continue;
918 919 920
		}
	}

921 922
	if (block_pos > usbvision->comprblock_pos) {
		usbvision->comprblock_pos = block_pos;
923
	}
924 925
	if (block_pos > strip_len) {
		usbvision->strip_len_errors++;
926
	}
927

928
	for (idx = 0; idx < idx_end; idx++) {
929
		if(frame->v4l2_format.format == V4L2_PIX_FMT_YUYV) {
930 931
			*f++ = Y[idx];
			*f++ = idx & 0x01 ? U[idx/2] : V[idx/2];
932 933
		}
		else if(frame->v4l2_format.format == V4L2_PIX_FMT_YUV422P) {
934 935 936
			*f++ = Y[idx];
			if ( idx & 0x01)
				*u++ = U[idx>>1] ;
937
			else
938
				*v++ = V[idx>>1];
939 940
		}
		else if (frame->v4l2_format.format == V4L2_PIX_FMT_YVU420) {
941 942
			*f++ = Y [idx];
			if ( !((  idx & 0x01  ) | (  frame->curline & 0x01  )) ){
943

944 945 946
/* 				 only need do this for 1 in 4 pixels */
/* 				 intraframe buffer is YUV420 format */

947 948
				*u++ = U[idx >>1];
				*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 955
			switch (frame->v4l2_format.format) {
				case V4L2_PIX_FMT_GREY:
956
					*f++ = Y[idx];
957 958
					break;
				case V4L2_PIX_FMT_RGB555:
959 960 961 962
					*f++ = (0x1F & rv) |
						(0xE0 & (gv << 5));
					*f++ = (0x03 & (gv >> 3)) |
						(0x7C & (bv << 2));
963 964
					break;
				case V4L2_PIX_FMT_RGB565:
965 966 967 968
					*f++ = (0x1F & rv) |
						(0xE0 & (gv << 5));
					*f++ = (0x07 & (gv >> 3)) |
						(0xF8 &  bv);
969 970 971
					break;
				case V4L2_PIX_FMT_RGB24:
					*f++ = rv;
972 973
					*f++ = gv;
					*f++ = bv;
974 975 976
					break;
				case V4L2_PIX_FMT_RGB32:
					*f++ = rv;
977 978
					*f++ = gv;
					*f++ = bv;
979 980 981 982 983 984
					f++;
					break;
			}
		}
		clipmask_index++;
	}
985 986 987 988 989 990
	/* Deal with non-integer no. of bytes for YUV420P */
	if (frame->v4l2_format.format != V4L2_PIX_FMT_YVU420 )
		*pcopylen += frame->v4l2_linesize;
	else
		*pcopylen += frame->curline & 0x01 ? frame->v4l2_linesize : frame->v4l2_linesize << 1;

991 992 993
	frame->curline += 1;

	if (frame->curline >= frame->frmheight) {
994
		return parse_state_next_frame;
995 996
	}
	else {
997
		return parse_state_continue;
998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010
	}

}


/*
 * usbvision_parse_lines_420()
 *
 * Parse two lines from the scratch buffer, put
 * decoded RGB value into the current frame buffer and add the written
 * number of bytes (RGB) to the *pcopylen.
 *
 */
1011
static enum parse_state usbvision_parse_lines_420(struct usb_usbvision *usbvision,
1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030
					   long *pcopylen)
{
	struct usbvision_frame *frame;
	unsigned char *f_even = NULL, *f_odd = NULL;
	unsigned int pixel_per_line, block;
	int pixel, block_split;
	int y_ptr, u_ptr, v_ptr, y_odd_offset;
	const int   y_block_size = 128;
	const int  uv_block_size = 64;
	const int sub_block_size = 32;
	const int y_step[] = { 0, 0, 0, 2 },  y_step_size = 4;
	const int uv_step[]= { 0, 0, 0, 4 }, uv_step_size = 4;
	unsigned char y[2], u, v;	/* YUV components */
	int y_, u_, v_, vb, uvg, ur;
	int r_, g_, b_;			/* RGB components */
	unsigned char g;
	int clipmask_even_index, clipmask_odd_index, bytes_per_pixel;
	int clipmask_add, stretch_bytes;

1031
	frame  = usbvision->cur_frame;
1032 1033
	f_even = frame->data + (frame->v4l2_linesize * frame->curline);
	f_odd  = f_even + frame->v4l2_linesize * usbvision->stretch_height;
1034 1035 1036 1037

	/* Make sure there's enough data for the entire line */
	/* In this mode usbvision transfer 3 bytes for every 2 pixels */
	/* I need two lines to decode the color */
1038
	bytes_per_pixel = frame->v4l2_format.bytes_per_pixel;
1039 1040 1041 1042
	stretch_bytes = (usbvision->stretch_width - 1) * bytes_per_pixel;
	clipmask_even_index = frame->curline * MAX_FRAME_WIDTH;
	clipmask_odd_index  = clipmask_even_index + MAX_FRAME_WIDTH;
	clipmask_add = usbvision->stretch_width;
1043
	pixel_per_line = frame->isoc_header.frame_width;
1044 1045 1046

	if (scratch_len(usbvision) < (int)pixel_per_line * 3) {
		//printk(KERN_DEBUG "out of data, need %d\n", len);
1047
		return parse_state_out;
1048 1049 1050
	}

	if ((frame->curline + 1) >= frame->frmheight) {
1051
		return parse_state_next_frame;
1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079
	}

	block_split = (pixel_per_line%y_block_size) ? 1 : 0;	//are some blocks splitted into different lines?

	y_odd_offset = (pixel_per_line / y_block_size) * (y_block_size + uv_block_size)
			+ block_split * uv_block_size;

	scratch_set_extra_ptr(usbvision, &y_ptr, y_odd_offset);
	scratch_set_extra_ptr(usbvision, &u_ptr, y_block_size);
	scratch_set_extra_ptr(usbvision, &v_ptr, y_odd_offset
			+ (4 - block_split) * sub_block_size);

	for (block = 0; block < (pixel_per_line / sub_block_size);
	     block++) {


		for (pixel = 0; pixel < sub_block_size; pixel +=2) {
			scratch_get(usbvision, &y[0], 2);
			scratch_get_extra(usbvision, &u, &u_ptr, 1);
			scratch_get_extra(usbvision, &v, &v_ptr, 1);

			//I don't use the YUV_TO_RGB macro for better performance
			v_ = v - 128;
			u_ = u - 128;
			vb =              132252 * v_;
			uvg= -53281 * u_ - 25625 * v_;
			ur = 104595 * u_;

1080
			if(frame->v4l2_format.format == V4L2_PIX_FMT_YUYV) {
1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091
				*f_even++ = y[0];
				*f_even++ = v;
			}
			else {
				y_ = 76284 * (y[0] - 16);

				b_ = (y_ + vb) >> 16;
				g_ = (y_ + uvg)>> 16;
				r_ = (y_ + ur) >> 16;

				switch (frame->v4l2_format.format) {
1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118
				case V4L2_PIX_FMT_RGB565:
					g = LIMIT_RGB(g_);
					*f_even++ =
						(0x1F & LIMIT_RGB(r_)) |
						(0xE0 & (g << 5));
					*f_even++ =
						(0x07 & (g >> 3)) |
						(0xF8 &  LIMIT_RGB(b_));
					break;
				case V4L2_PIX_FMT_RGB24:
					*f_even++ = LIMIT_RGB(r_);
					*f_even++ = LIMIT_RGB(g_);
					*f_even++ = LIMIT_RGB(b_);
					break;
				case V4L2_PIX_FMT_RGB32:
					*f_even++ = LIMIT_RGB(r_);
					*f_even++ = LIMIT_RGB(g_);
					*f_even++ = LIMIT_RGB(b_);
					f_even++;
					break;
				case V4L2_PIX_FMT_RGB555:
					g = LIMIT_RGB(g_);
					*f_even++ = (0x1F & LIMIT_RGB(r_)) |
						(0xE0 & (g << 5));
					*f_even++ = (0x03 & (g >> 3)) |
						(0x7C & (LIMIT_RGB(b_) << 2));
					break;
1119 1120 1121 1122 1123
				}
			}
			clipmask_even_index += clipmask_add;
			f_even += stretch_bytes;

1124
			if(frame->v4l2_format.format == V4L2_PIX_FMT_YUYV) {
1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135
				*f_even++ = y[1];
				*f_even++ = u;
			}
			else {
				y_ = 76284 * (y[1] - 16);

				b_ = (y_ + vb) >> 16;
				g_ = (y_ + uvg)>> 16;
				r_ = (y_ + ur) >> 16;

				switch (frame->v4l2_format.format) {
1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162
				case V4L2_PIX_FMT_RGB565:
					g = LIMIT_RGB(g_);
					*f_even++ =
						(0x1F & LIMIT_RGB(r_)) |
						(0xE0 & (g << 5));
					*f_even++ =
						(0x07 & (g >> 3)) |
						(0xF8 &  LIMIT_RGB(b_));
					break;
				case V4L2_PIX_FMT_RGB24:
					*f_even++ = LIMIT_RGB(r_);
					*f_even++ = LIMIT_RGB(g_);
					*f_even++ = LIMIT_RGB(b_);
					break;
				case V4L2_PIX_FMT_RGB32:
					*f_even++ = LIMIT_RGB(r_);
					*f_even++ = LIMIT_RGB(g_);
					*f_even++ = LIMIT_RGB(b_);
					f_even++;
					break;
				case V4L2_PIX_FMT_RGB555:
					g = LIMIT_RGB(g_);
					*f_even++ = (0x1F & LIMIT_RGB(r_)) |
						(0xE0 & (g << 5));
					*f_even++ = (0x03 & (g >> 3)) |
						(0x7C & (LIMIT_RGB(b_) << 2));
					break;
1163 1164 1165 1166 1167 1168 1169
				}
			}
			clipmask_even_index += clipmask_add;
			f_even += stretch_bytes;

			scratch_get_extra(usbvision, &y[0], &y_ptr, 2);

1170
			if(frame->v4l2_format.format == V4L2_PIX_FMT_YUYV) {
1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181
				*f_odd++ = y[0];
				*f_odd++ = v;
			}
			else {
				y_ = 76284 * (y[0] - 16);

				b_ = (y_ + vb) >> 16;
				g_ = (y_ + uvg)>> 16;
				r_ = (y_ + ur) >> 16;

				switch (frame->v4l2_format.format) {
1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208
				case V4L2_PIX_FMT_RGB565:
					g = LIMIT_RGB(g_);
					*f_odd++ =
						(0x1F & LIMIT_RGB(r_)) |
						(0xE0 & (g << 5));
					*f_odd++ =
						(0x07 & (g >> 3)) |
						(0xF8 &  LIMIT_RGB(b_));
					break;
				case V4L2_PIX_FMT_RGB24:
					*f_odd++ = LIMIT_RGB(r_);
					*f_odd++ = LIMIT_RGB(g_);
					*f_odd++ = LIMIT_RGB(b_);
					break;
				case V4L2_PIX_FMT_RGB32:
					*f_odd++ = LIMIT_RGB(r_);
					*f_odd++ = LIMIT_RGB(g_);
					*f_odd++ = LIMIT_RGB(b_);
					f_odd++;
					break;
				case V4L2_PIX_FMT_RGB555:
					g = LIMIT_RGB(g_);
					*f_odd++ = (0x1F & LIMIT_RGB(r_)) |
						(0xE0 & (g << 5));
					*f_odd++ = (0x03 & (g >> 3)) |
						(0x7C & (LIMIT_RGB(b_) << 2));
					break;
1209 1210 1211 1212 1213
				}
			}
			clipmask_odd_index += clipmask_add;
			f_odd += stretch_bytes;

1214
			if(frame->v4l2_format.format == V4L2_PIX_FMT_YUYV) {
1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225
				*f_odd++ = y[1];
				*f_odd++ = u;
			}
			else {
				y_ = 76284 * (y[1] - 16);

				b_ = (y_ + vb) >> 16;
				g_ = (y_ + uvg)>> 16;
				r_ = (y_ + ur) >> 16;

				switch (frame->v4l2_format.format) {
1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252
				case V4L2_PIX_FMT_RGB565:
					g = LIMIT_RGB(g_);
					*f_odd++ =
						(0x1F & LIMIT_RGB(r_)) |
						(0xE0 & (g << 5));
					*f_odd++ =
						(0x07 & (g >> 3)) |
						(0xF8 &  LIMIT_RGB(b_));
					break;
				case V4L2_PIX_FMT_RGB24:
					*f_odd++ = LIMIT_RGB(r_);
					*f_odd++ = LIMIT_RGB(g_);
					*f_odd++ = LIMIT_RGB(b_);
					break;
				case V4L2_PIX_FMT_RGB32:
					*f_odd++ = LIMIT_RGB(r_);
					*f_odd++ = LIMIT_RGB(g_);
					*f_odd++ = LIMIT_RGB(b_);
					f_odd++;
					break;
				case V4L2_PIX_FMT_RGB555:
					g = LIMIT_RGB(g_);
					*f_odd++ = (0x1F & LIMIT_RGB(r_)) |
						(0xE0 & (g << 5));
					*f_odd++ = (0x03 & (g >> 3)) |
						(0x7C & (LIMIT_RGB(b_) << 2));
					break;
1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274
				}
			}
			clipmask_odd_index += clipmask_add;
			f_odd += stretch_bytes;
		}

		scratch_rm_old(usbvision,y_step[block % y_step_size] * sub_block_size);
		scratch_inc_extra_ptr(&y_ptr, y_step[(block + 2 * block_split) % y_step_size]
				* sub_block_size);
		scratch_inc_extra_ptr(&u_ptr, uv_step[block % uv_step_size]
				* sub_block_size);
		scratch_inc_extra_ptr(&v_ptr, uv_step[(block + 2 * block_split) % uv_step_size]
				* sub_block_size);
	}

	scratch_rm_old(usbvision, pixel_per_line * 3 / 2
			+ block_split * sub_block_size);

	frame->curline += 2 * usbvision->stretch_height;
	*pcopylen += frame->v4l2_linesize * 2 * usbvision->stretch_height;

	if (frame->curline >= frame->frmheight)
1275
		return parse_state_next_frame;
1276
	else
1277
		return parse_state_continue;
1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290
}

/*
 * usbvision_parse_data()
 *
 * Generic routine to parse the scratch buffer. It employs either
 * usbvision_find_header() or usbvision_parse_lines() to do most
 * of work.
 *
 */
static void usbvision_parse_data(struct usb_usbvision *usbvision)
{
	struct usbvision_frame *frame;
1291
	enum parse_state newstate;
1292
	long copylen = 0;
1293
	unsigned long lock_flags;
1294

1295
	frame = usbvision->cur_frame;
1296 1297 1298 1299 1300

	PDEBUG(DBG_PARSE, "parsing len=%d\n", scratch_len(usbvision));

	while (1) {

1301
		newstate = parse_state_out;
1302
		if (scratch_len(usbvision)) {
1303
			if (frame->scanstate == scan_state_scanning) {
1304 1305
				newstate = usbvision_find_header(usbvision);
			}
1306 1307
			else if (frame->scanstate == scan_state_lines) {
				if (usbvision->isoc_mode == ISOC_MODE_YUV420) {
1308 1309
					newstate = usbvision_parse_lines_420(usbvision, &copylen);
				}
1310
				else if (usbvision->isoc_mode == ISOC_MODE_YUV422) {
1311 1312
					newstate = usbvision_parse_lines_422(usbvision, &copylen);
				}
1313
				else if (usbvision->isoc_mode == ISOC_MODE_COMPRESS) {
1314 1315 1316 1317 1318
					newstate = usbvision_parse_compress(usbvision, &copylen);
				}

			}
		}
1319
		if (newstate == parse_state_continue) {
1320 1321
			continue;
		}
1322
		else if ((newstate == parse_state_next_frame) || (newstate == parse_state_out)) {
1323 1324 1325
			break;
		}
		else {
1326
			return;	/* parse_state_end_parse */
1327 1328 1329
		}
	}

1330 1331
	if (newstate == parse_state_next_frame) {
		frame->grabstate = frame_state_done;
1332 1333 1334
		do_gettimeofday(&(frame->timestamp));
		frame->sequence = usbvision->frame_num;

1335 1336
		spin_lock_irqsave(&usbvision->queue_lock, lock_flags);
		list_move_tail(&(frame->frame), &usbvision->outqueue);
1337
		usbvision->cur_frame = NULL;
1338 1339 1340
		spin_unlock_irqrestore(&usbvision->queue_lock, lock_flags);

		usbvision->frame_num++;
1341 1342

		/* This will cause the process to request another frame. */
1343 1344 1345
		if (waitqueue_active(&usbvision->wait_frame)) {
			PDEBUG(DBG_PARSE, "Wake up !");
			wake_up_interruptible(&usbvision->wait_frame);
1346 1347
		}
	}
1348
	else
1349
		frame->grabstate = frame_state_grabbing;
1350

1351 1352 1353 1354 1355 1356 1357 1358 1359 1360

	/* Update the frame's uncompressed length. */
	frame->scanlength += copylen;
}


/*
 * Make all of the blocks of data contiguous
 */
static int usbvision_compress_isochronous(struct usb_usbvision *usbvision,
1361
					  struct urb *urb)
1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374
{
	unsigned char *packet_data;
	int i, totlen = 0;

	for (i = 0; i < urb->number_of_packets; i++) {
		int packet_len = urb->iso_frame_desc[i].actual_length;
		int packet_stat = urb->iso_frame_desc[i].status;

		packet_data = urb->transfer_buffer + urb->iso_frame_desc[i].offset;

		/* Detect and ignore errored packets */
		if (packet_stat) {	// packet_stat != 0 ?????????????
			PDEBUG(DBG_ISOC, "data error: [%d] len=%d, status=%X", i, packet_len, packet_stat);
1375
			usbvision->isoc_err_count++;
1376 1377 1378 1379 1380 1381
			continue;
		}

		/* Detect and ignore empty packets */
		if (packet_len < 0) {
			PDEBUG(DBG_ISOC, "error packet [%d]", i);
1382
			usbvision->isoc_skip_count++;
1383 1384 1385 1386
			continue;
		}
		else if (packet_len == 0) {	/* Frame end ????? */
			PDEBUG(DBG_ISOC, "null packet [%d]", i);
1387 1388
			usbvision->isocstate=isoc_state_no_frame;
			usbvision->isoc_skip_count++;
1389 1390
			continue;
		}
1391 1392 1393
		else if (packet_len > usbvision->isoc_packet_size) {
			PDEBUG(DBG_ISOC, "packet[%d] > isoc_packet_size", i);
			usbvision->isoc_skip_count++;
1394 1395 1396 1397 1398
			continue;
		}

		PDEBUG(DBG_ISOC, "packet ok [%d] len=%d", i, packet_len);

1399 1400
		if (usbvision->isocstate==isoc_state_no_frame) { //new frame begins
			usbvision->isocstate=isoc_state_in_frame;
1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424
			scratch_mark_header(usbvision);
			usbvision_measure_bandwidth(usbvision);
			PDEBUG(DBG_ISOC, "packet with header");
		}

		/*
		 * If usbvision continues to feed us with data but there is no
		 * consumption (if, for example, V4L client fell asleep) we
		 * may overflow the buffer. We have to move old data over to
		 * free room for new data. This is bad for old data. If we
		 * just drop new data then it's bad for new data... choose
		 * your favorite evil here.
		 */
		if (scratch_free(usbvision) < packet_len) {

			usbvision->scratch_ovf_count++;
			PDEBUG(DBG_ISOC, "scratch buf overflow! scr_len: %d, n: %d",
			       scratch_len(usbvision), packet_len);
			scratch_rm_old(usbvision, packet_len - scratch_free(usbvision));
		}

		/* Now we know that there is enough room in scratch buffer */
		scratch_put(usbvision, packet_data, packet_len);
		totlen += packet_len;
1425 1426
		usbvision->isoc_data_count += packet_len;
		usbvision->isoc_packet_count++;
1427 1428 1429
	}
#if ENABLE_HEXDUMP
	if (totlen > 0) {
1430
		static int foo;
1431 1432 1433 1434 1435 1436 1437 1438 1439 1440
		if (foo < 1) {
			printk(KERN_DEBUG "+%d.\n", usbvision->scratchlen);
			usbvision_hexdump(data0, (totlen > 64) ? 64 : totlen);
			++foo;
		}
	}
#endif
 return totlen;
}

1441
static void usbvision_isoc_irq(struct urb *urb)
1442
{
1443
	int err_code = 0;
1444 1445 1446
	int len;
	struct usb_usbvision *usbvision = urb->context;
	int i;
1447
	unsigned long start_time = jiffies;
1448
	struct usbvision_frame **f;
1449

1450 1451 1452
	/* We don't want to do anything if we are about to be removed! */
	if (!USBVISION_IS_OPERATIONAL(usbvision))
		return;
1453

1454 1455 1456 1457 1458
	/* any urb with wrong status is ignored without acknowledgement */
	if (urb->status == -ENOENT) {
		return;
	}

1459
	f = &usbvision->cur_frame;
1460

1461
	/* Manage streaming interruption */
1462 1463
	if (usbvision->streaming == stream_interrupt) {
		usbvision->streaming = stream_idle;
1464
		if ((*f)) {
1465 1466
			(*f)->grabstate = frame_state_ready;
			(*f)->scanstate = scan_state_scanning;
1467 1468 1469 1470
		}
		PDEBUG(DBG_IRQ, "stream interrupted");
		wake_up_interruptible(&usbvision->wait_stream);
	}
1471

1472 1473
	/* Copy the data received into our scratch buffer */
	len = usbvision_compress_isochronous(usbvision, urb);
1474

1475
	usbvision->isoc_urb_count++;
1476
	usbvision->urb_length = len;
1477

1478
	if (usbvision->streaming == stream_on) {
1479 1480

		/* If we collected enough data let's parse! */
1481 1482 1483 1484 1485 1486
		if ((scratch_len(usbvision) > USBVISION_HEADER_LENGTH) &&
		    (!list_empty(&(usbvision->inqueue))) ) {
			if (!(*f)) {
				(*f) = list_entry(usbvision->inqueue.next,
						  struct usbvision_frame,
						  frame);
1487
			}
1488 1489 1490 1491 1492 1493 1494 1495
			usbvision_parse_data(usbvision);
		}
		else {
			/*If we don't have a frame
			  we're current working on, complain */
			PDEBUG(DBG_IRQ,
			       "received data, but no one needs it");
			scratch_reset(usbvision);
1496 1497
		}
	}
1498 1499 1500 1501
	else {
		PDEBUG(DBG_IRQ, "received data, but no one needs it");
		scratch_reset(usbvision);
	}
1502

1503
	usbvision->time_in_irq += jiffies - start_time;
1504 1505 1506 1507 1508 1509 1510 1511

	for (i = 0; i < USBVISION_URB_FRAMES; i++) {
		urb->iso_frame_desc[i].status = 0;
		urb->iso_frame_desc[i].actual_length = 0;
	}

	urb->status = 0;
	urb->dev = usbvision->dev;
1512
	err_code = usb_submit_urb (urb, GFP_ATOMIC);
1513

1514
	if(err_code) {
1515 1516
		dev_err(&usbvision->dev->dev,
			"%s: usb_submit_urb failed: error %d\n",
1517
				__func__, err_code);
1518
	}
1519

1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533
	return;
}

/*************************************/
/* Low level usbvision access functions */
/*************************************/

/*
 * usbvision_read_reg()
 *
 * return  < 0 -> Error
 *        >= 0 -> Data
 */

1534
int usbvision_read_reg(struct usb_usbvision *usbvision, unsigned char reg)
1535
{
1536
	int err_code = 0;
1537 1538 1539 1540 1541
	unsigned char buffer[1];

	if (!USBVISION_IS_OPERATIONAL(usbvision))
		return -1;

1542
	err_code = usb_control_msg(usbvision->dev, usb_rcvctrlpipe(usbvision->dev, 1),
1543 1544 1545 1546
				USBVISION_OP_CODE,
				USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT,
				0, (__u16) reg, buffer, 1, HZ);

1547
	if (err_code < 0) {
1548
		dev_err(&usbvision->dev->dev,
1549 1550
			"%s: failed: error %d\n", __func__, err_code);
		return err_code;
1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562
	}
	return buffer[0];
}

/*
 * usbvision_write_reg()
 *
 * return 1 -> Reg written
 *        0 -> usbvision is not yet ready
 *       -1 -> Something went wrong
 */

1563
int usbvision_write_reg(struct usb_usbvision *usbvision, unsigned char reg,
1564 1565
			    unsigned char value)
{
1566
	int err_code = 0;
1567 1568 1569 1570

	if (!USBVISION_IS_OPERATIONAL(usbvision))
		return 0;

1571
	err_code = usb_control_msg(usbvision->dev, usb_sndctrlpipe(usbvision->dev, 1),
1572 1573 1574 1575
				USBVISION_OP_CODE,
				USB_DIR_OUT | USB_TYPE_VENDOR |
				USB_RECIP_ENDPOINT, 0, (__u16) reg, &value, 1, HZ);

1576
	if (err_code < 0) {
1577
		dev_err(&usbvision->dev->dev,
1578
			"%s: failed: error %d\n", __func__, err_code);
1579
	}
1580
	return err_code;
1581 1582 1583
}


1584
static void usbvision_ctrl_urb_complete(struct urb *urb)
1585 1586 1587 1588
{
	struct usb_usbvision *usbvision = (struct usb_usbvision *)urb->context;

	PDEBUG(DBG_IRQ, "");
1589 1590 1591
	usbvision->ctrl_urb_busy = 0;
	if (waitqueue_active(&usbvision->ctrl_urb_wq)) {
		wake_up_interruptible(&usbvision->ctrl_urb_wq);
1592 1593 1594 1595 1596 1597 1598
	}
}


static int usbvision_write_reg_irq(struct usb_usbvision *usbvision,int address,
									unsigned char *data, int len)
{
1599
	int err_code = 0;
1600 1601 1602 1603 1604

	PDEBUG(DBG_IRQ, "");
	if (len > 8) {
		return -EFAULT;
	}
1605
	if (usbvision->ctrl_urb_busy) {
1606 1607
		return -EBUSY;
	}
1608
	usbvision->ctrl_urb_busy = 1;
1609

1610 1611 1612 1613 1614 1615
	usbvision->ctrl_urb_setup.bRequestType = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT;
	usbvision->ctrl_urb_setup.bRequest     = USBVISION_OP_CODE;
	usbvision->ctrl_urb_setup.wValue       = 0;
	usbvision->ctrl_urb_setup.wIndex       = cpu_to_le16(address);
	usbvision->ctrl_urb_setup.wLength      = cpu_to_le16(len);
	usb_fill_control_urb (usbvision->ctrl_urb, usbvision->dev,
1616
							usb_sndctrlpipe(usbvision->dev, 1),
1617 1618 1619
							(unsigned char *)&usbvision->ctrl_urb_setup,
							(void *)usbvision->ctrl_urb_buffer, len,
							usbvision_ctrl_urb_complete,
1620 1621
							(void *)usbvision);

1622
	memcpy(usbvision->ctrl_urb_buffer, data, len);
1623

1624 1625
	err_code = usb_submit_urb(usbvision->ctrl_urb, GFP_ATOMIC);
	if (err_code < 0) {
1626
		// error in usb_submit_urb()
1627
		usbvision->ctrl_urb_busy = 0;
1628
	}
1629 1630
	PDEBUG(DBG_IRQ, "submit %d byte: error %d", len, err_code);
	return err_code;
1631 1632 1633 1634 1635
}


static int usbvision_init_compression(struct usb_usbvision *usbvision)
{
1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648
	int err_code = 0;

	usbvision->last_isoc_frame_num = -1;
	usbvision->isoc_data_count = 0;
	usbvision->isoc_packet_count = 0;
	usbvision->isoc_skip_count = 0;
	usbvision->compr_level = 50;
	usbvision->last_compr_level = -1;
	usbvision->isoc_urb_count = 0;
	usbvision->request_intra = 1;
	usbvision->isoc_measure_bandwidth_count = 0;

	return err_code;
1649 1650 1651 1652
}

/* this function measures the used bandwidth since last call
 * return:    0 : no error
1653
 * sets used_bandwidth to 1-100 : 1-100% of full bandwidth resp. to isoc_packet_size
1654 1655 1656
 */
static int usbvision_measure_bandwidth (struct usb_usbvision *usbvision)
{
1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672
	int err_code = 0;

	if (usbvision->isoc_measure_bandwidth_count < 2) { // this gives an average bandwidth of 3 frames
		usbvision->isoc_measure_bandwidth_count++;
		return err_code;
	}
	if ((usbvision->isoc_packet_size > 0) && (usbvision->isoc_packet_count > 0)) {
		usbvision->used_bandwidth = usbvision->isoc_data_count /
					(usbvision->isoc_packet_count + usbvision->isoc_skip_count) *
					100 / usbvision->isoc_packet_size;
	}
	usbvision->isoc_measure_bandwidth_count = 0;
	usbvision->isoc_data_count = 0;
	usbvision->isoc_packet_count = 0;
	usbvision->isoc_skip_count = 0;
	return err_code;
1673 1674 1675 1676
}

static int usbvision_adjust_compression (struct usb_usbvision *usbvision)
{
1677
	int err_code = 0;
1678 1679 1680
	unsigned char buffer[6];

	PDEBUG(DBG_IRQ, "");
1681 1682 1683 1684
	if ((adjust_compression) && (usbvision->used_bandwidth > 0)) {
		usbvision->compr_level += (usbvision->used_bandwidth - 90) / 2;
		RESTRICT_TO_RANGE(usbvision->compr_level, 0, 100);
		if (usbvision->compr_level != usbvision->last_compr_level) {
1685
			int distorsion;
1686 1687 1688 1689
			if (usbvision->bridge_type == BRIDGE_NT1004 || usbvision->bridge_type == BRIDGE_NT1005) {
				buffer[0] = (unsigned char)(4 + 16 * usbvision->compr_level / 100);	// PCM Threshold 1
				buffer[1] = (unsigned char)(4 + 8 * usbvision->compr_level / 100);	// PCM Threshold 2
				distorsion = 7 + 248 * usbvision->compr_level / 100;
1690 1691
				buffer[2] = (unsigned char)(distorsion & 0xFF);				// Average distorsion Threshold (inter)
				buffer[3] = (unsigned char)(distorsion & 0xFF);				// Average distorsion Threshold (intra)
1692
				distorsion = 1 + 42 * usbvision->compr_level / 100;
1693 1694 1695 1696
				buffer[4] = (unsigned char)(distorsion & 0xFF);				// Maximum distorsion Threshold (inter)
				buffer[5] = (unsigned char)(distorsion & 0xFF);				// Maximum distorsion Threshold (intra)
			}
			else { //BRIDGE_NT1003
1697 1698 1699
				buffer[0] = (unsigned char)(4 + 16 * usbvision->compr_level / 100);	// PCM threshold 1
				buffer[1] = (unsigned char)(4 + 8 * usbvision->compr_level / 100);	// PCM threshold 2
				distorsion = 2 + 253 * usbvision->compr_level / 100;
1700 1701
				buffer[2] = (unsigned char)(distorsion & 0xFF);				// distorsion threshold bit0-7
				buffer[3] = 0; 	//(unsigned char)((distorsion >> 8) & 0x0F);		// distorsion threshold bit 8-11
1702
				distorsion = 0 + 43 * usbvision->compr_level / 100;
1703 1704 1705
				buffer[4] = (unsigned char)(distorsion & 0xFF);				// maximum distorsion bit0-7
				buffer[5] = 0; //(unsigned char)((distorsion >> 8) & 0x01);		// maximum distorsion bit 8
			}
1706 1707
			err_code = usbvision_write_reg_irq(usbvision, USBVISION_PCM_THR1, buffer, 6);
			if (err_code == 0){
1708 1709
				PDEBUG(DBG_IRQ, "new compr params %#02x %#02x %#02x %#02x %#02x %#02x", buffer[0],
								buffer[1], buffer[2], buffer[3], buffer[4], buffer[5]);
1710
				usbvision->last_compr_level = usbvision->compr_level;
1711 1712 1713
			}
		}
	}
1714
	return err_code;
1715 1716 1717 1718
}

static int usbvision_request_intra (struct usb_usbvision *usbvision)
{
1719
	int err_code = 0;
1720 1721 1722
	unsigned char buffer[1];

	PDEBUG(DBG_IRQ, "");
1723
	usbvision->request_intra = 1;
1724 1725
	buffer[0] = 1;
	usbvision_write_reg_irq(usbvision, USBVISION_FORCE_INTRA, buffer, 1);
1726
	return err_code;
1727 1728 1729 1730
}

static int usbvision_unrequest_intra (struct usb_usbvision *usbvision)
{
1731
	int err_code = 0;
1732 1733 1734
	unsigned char buffer[1];

	PDEBUG(DBG_IRQ, "");
1735
	usbvision->request_intra = 0;
1736 1737
	buffer[0] = 0;
	usbvision_write_reg_irq(usbvision, USBVISION_FORCE_INTRA, buffer, 1);
1738
	return err_code;
1739 1740
}

1741 1742 1743
/*******************************
 * usbvision utility functions
 *******************************/
1744

1745
int usbvision_power_off(struct usb_usbvision *usbvision)
1746
{
1747
	int err_code = 0;
1748 1749 1750

	PDEBUG(DBG_FUNC, "");

1751 1752
	err_code = usbvision_write_reg(usbvision, USBVISION_PWR_REG, USBVISION_SSPND_EN);
	if (err_code == 1) {
1753 1754
		usbvision->power = 0;
	}
1755 1756
	PDEBUG(DBG_FUNC, "%s: err_code %d", (err_code!=1)?"ERROR":"power is off", err_code);
	return err_code;
1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771
}

/*
 * usbvision_set_video_format()
 *
 */
static int usbvision_set_video_format(struct usb_usbvision *usbvision, int format)
{
	static const char proc[] = "usbvision_set_video_format";
	int rc;
	unsigned char value[2];

	if (!USBVISION_IS_OPERATIONAL(usbvision))
		return 0;

1772
	PDEBUG(DBG_FUNC, "isoc_mode %#02x", format);
1773 1774 1775 1776 1777 1778 1779 1780 1781

	if ((format != ISOC_MODE_YUV422)
	    && (format != ISOC_MODE_YUV420)
	    && (format != ISOC_MODE_COMPRESS)) {
		printk(KERN_ERR "usbvision: unknown video format %02x, using default YUV420",
		       format);
		format = ISOC_MODE_YUV420;
	}
	value[0] = 0x0A;  //TODO: See the effect of the filter
1782
	value[1] = format; // Sets the VO_MODE register which follows FILT_CONT
1783 1784 1785 1786 1787 1788 1789 1790 1791 1792
	rc = usb_control_msg(usbvision->dev, usb_sndctrlpipe(usbvision->dev, 1),
			     USBVISION_OP_CODE,
			     USB_DIR_OUT | USB_TYPE_VENDOR |
			     USB_RECIP_ENDPOINT, 0,
			     (__u16) USBVISION_FILT_CONT, value, 2, HZ);

	if (rc < 0) {
		printk(KERN_ERR "%s: ERROR=%d. USBVISION stopped - "
		       "reconnect or reload driver.\n", proc, rc);
	}
1793
	usbvision->isoc_mode = format;
1794 1795 1796 1797 1798 1799 1800 1801
	return rc;
}

/*
 * usbvision_set_output()
 *
 */

1802 1803
int usbvision_set_output(struct usb_usbvision *usbvision, int width,
			 int height)
1804
{
1805 1806 1807
	int err_code = 0;
	int usb_width, usb_height;
	unsigned int frame_rate=0, frame_drop=0;
1808 1809 1810 1811 1812 1813 1814
	unsigned char value[4];

	if (!USBVISION_IS_OPERATIONAL(usbvision)) {
		return 0;
	}

	if (width > MAX_USB_WIDTH) {
1815
		usb_width = width / 2;
1816 1817 1818
		usbvision->stretch_width = 2;
	}
	else {
1819
		usb_width = width;
1820 1821 1822 1823
		usbvision->stretch_width = 1;
	}

	if (height > MAX_USB_HEIGHT) {
1824
		usb_height = height / 2;
1825 1826 1827
		usbvision->stretch_height = 2;
	}
	else {
1828
		usb_height = height;
1829 1830 1831
		usbvision->stretch_height = 1;
	}

1832 1833 1834 1835
	RESTRICT_TO_RANGE(usb_width, MIN_FRAME_WIDTH, MAX_USB_WIDTH);
	usb_width &= ~(MIN_FRAME_WIDTH-1);
	RESTRICT_TO_RANGE(usb_height, MIN_FRAME_HEIGHT, MAX_USB_HEIGHT);
	usb_height &= ~(1);
1836 1837

	PDEBUG(DBG_FUNC, "usb %dx%d; screen %dx%d; stretch %dx%d",
1838
						usb_width, usb_height, width, height,
1839 1840 1841
						usbvision->stretch_width, usbvision->stretch_height);

	/* I'll not rewrite the same values */
1842 1843 1844 1845 1846
	if ((usb_width != usbvision->curwidth) || (usb_height != usbvision->curheight)) {
		value[0] = usb_width & 0xff;		//LSB
		value[1] = (usb_width >> 8) & 0x03;	//MSB
		value[2] = usb_height & 0xff;		//LSB
		value[3] = (usb_height >> 8) & 0x03;	//MSB
1847

1848
		err_code = usb_control_msg(usbvision->dev, usb_sndctrlpipe(usbvision->dev, 1),
1849 1850 1851 1852
			     USBVISION_OP_CODE,
			     USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT,
				 0, (__u16) USBVISION_LXSIZE_O, value, 4, HZ);

1853
		if (err_code < 0) {
1854
			dev_err(&usbvision->dev->dev,
1855 1856
				"%s failed: error %d\n", __func__, err_code);
			return err_code;
1857
		}
1858 1859
		usbvision->curwidth = usbvision->stretch_width * usb_width;
		usbvision->curheight = usbvision->stretch_height * usb_height;
1860 1861
	}

1862 1863
	if (usbvision->isoc_mode == ISOC_MODE_YUV422) {
		frame_rate = (usbvision->isoc_packet_size * 1000) / (usb_width * usb_height * 2);
1864
	}
1865 1866
	else if (usbvision->isoc_mode == ISOC_MODE_YUV420) {
		frame_rate = (usbvision->isoc_packet_size * 1000) / ((usb_width * usb_height * 12) / 8);
1867 1868
	}
	else {
1869
		frame_rate = FRAMERATE_MAX;
1870 1871
	}

1872 1873
	if (usbvision->tvnorm_id & V4L2_STD_625_50) {
		frame_drop = frame_rate * 32 / 25 - 1;
1874
	}
1875 1876
	else if (usbvision->tvnorm_id & V4L2_STD_525_60) {
		frame_drop = frame_rate * 32 / 30 - 1;
1877 1878
	}

1879
	RESTRICT_TO_RANGE(frame_drop, FRAMERATE_MIN, FRAMERATE_MAX);
1880

1881
	PDEBUG(DBG_FUNC, "frame_rate %d fps, frame_drop %d", frame_rate, frame_drop);
1882

1883
	frame_drop = FRAMERATE_MAX; 	// We can allow the maximum here, because dropping is controlled
1884

1885 1886 1887
	/* frame_drop = 7; => frame_phase = 1, 5, 9, 13, 17, 21, 25, 0, 4, 8, ...
		=> frame_skip = 4;
		=> frame_rate = (7 + 1) * 25 / 32 = 200 / 32 = 6.25;
1888

1889 1890 1891
	   frame_drop = 9; => frame_phase = 1, 5, 8, 11, 14, 17, 21, 24, 27, 1, 4, 8, ...
	    => frame_skip = 4, 3, 3, 3, 3, 4, 3, 3, 3, 3, 4, ...
		=> frame_rate = (9 + 1) * 25 / 32 = 250 / 32 = 7.8125;
1892
	*/
1893 1894
	err_code = usbvision_write_reg(usbvision, USBVISION_FRM_RATE, frame_drop);
	return err_code;
1895 1896 1897
}


1898 1899
/*
 * usbvision_frames_alloc
1900
 * allocate the required frames
1901
 */
1902
int usbvision_frames_alloc(struct usb_usbvision *usbvision, int number_of_frames)
1903 1904 1905
{
	int i;

1906 1907 1908 1909
	/*needs to be page aligned cause the buffers can be mapped individually! */
	usbvision->max_frame_size =  PAGE_ALIGN(usbvision->curwidth *
						usbvision->curheight *
						usbvision->palette.bytes_per_pixel);
1910

1911 1912 1913 1914 1915 1916 1917 1918
	/* Try to do my best to allocate the frames the user want in the remaining memory */
	usbvision->num_frames = number_of_frames;
	while (usbvision->num_frames > 0) {
		usbvision->fbuf_size = usbvision->num_frames * usbvision->max_frame_size;
		if((usbvision->fbuf = usbvision_rvmalloc(usbvision->fbuf_size))) {
			break;
		}
		usbvision->num_frames--;
1919
	}
1920

1921 1922 1923 1924 1925
	spin_lock_init(&usbvision->queue_lock);
	init_waitqueue_head(&usbvision->wait_frame);
	init_waitqueue_head(&usbvision->wait_stream);

	/* Allocate all buffers */
1926
	for (i = 0; i < usbvision->num_frames; i++) {
1927
		usbvision->frame[i].index = i;
1928
		usbvision->frame[i].grabstate = frame_state_unused;
1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939
		usbvision->frame[i].data = usbvision->fbuf +
			i * usbvision->max_frame_size;
		/*
		 * Set default sizes for read operation.
		 */
		usbvision->stretch_width = 1;
		usbvision->stretch_height = 1;
		usbvision->frame[i].width = usbvision->curwidth;
		usbvision->frame[i].height = usbvision->curheight;
		usbvision->frame[i].bytes_read = 0;
	}
1940 1941
	PDEBUG(DBG_FUNC, "allocated %d frames (%d bytes per frame)",usbvision->num_frames,usbvision->max_frame_size);
	return usbvision->num_frames;
1942 1943 1944 1945 1946 1947 1948 1949 1950
}

/*
 * usbvision_frames_free
 * frees memory allocated for the frames
 */
void usbvision_frames_free(struct usb_usbvision *usbvision)
{
	/* Have to free all that memory */
1951 1952
	PDEBUG(DBG_FUNC, "free %d frames",usbvision->num_frames);

1953 1954 1955
	if (usbvision->fbuf != NULL) {
		usbvision_rvfree(usbvision->fbuf, usbvision->fbuf_size);
		usbvision->fbuf = NULL;
1956 1957

		usbvision->num_frames = 0;
1958 1959
	}
}
1960 1961 1962 1963
/*
 * usbvision_empty_framequeues()
 * prepare queues for incoming and outgoing frames
 */
1964
void usbvision_empty_framequeues(struct usb_usbvision *usbvision)
1965 1966 1967 1968 1969 1970 1971
{
	u32 i;

	INIT_LIST_HEAD(&(usbvision->inqueue));
	INIT_LIST_HEAD(&(usbvision->outqueue));

	for (i = 0; i < USBVISION_NUMFRAMES; i++) {
1972
		usbvision->frame[i].grabstate = frame_state_unused;
1973 1974 1975 1976 1977 1978 1979 1980
		usbvision->frame[i].bytes_read = 0;
	}
}

/*
 * usbvision_stream_interrupt()
 * stops streaming
 */
1981
int usbvision_stream_interrupt(struct usb_usbvision *usbvision)
1982 1983 1984 1985 1986
{
	int ret = 0;

	/* stop reading from the device */

1987
	usbvision->streaming = stream_interrupt;
1988
	ret = wait_event_timeout(usbvision->wait_stream,
1989
				 (usbvision->streaming == stream_idle),
1990 1991 1992 1993
				 msecs_to_jiffies(USBVISION_NUMSBUF*USBVISION_URB_FRAMES));
	return ret;
}

1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009
/*
 * usbvision_set_compress_params()
 *
 */

static int usbvision_set_compress_params(struct usb_usbvision *usbvision)
{
	static const char proc[] = "usbvision_set_compresion_params: ";
	int rc;
	unsigned char value[6];

	value[0] = 0x0F;    // Intra-Compression cycle
	value[1] = 0x01;    // Reg.45 one line per strip
	value[2] = 0x00;    // Reg.46 Force intra mode on all new frames
	value[3] = 0x00;    // Reg.47 FORCE_UP <- 0 normal operation (not force)
	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 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032

	//catched values for NT1004
	// value[0] = 0xFF; // Never apply intra mode automatically
	// value[1] = 0xF1; // Use full frame height for virtual strip width; One line per strip
	// value[2] = 0x01; // Force intra mode on all new frames
	// value[3] = 0x00; // Strip size 400 Bytes; do not force up
	// value[4] = 0xA2; //
	if (!USBVISION_IS_OPERATIONAL(usbvision))
		return 0;

	rc = usb_control_msg(usbvision->dev, usb_sndctrlpipe(usbvision->dev, 1),
			     USBVISION_OP_CODE,
			     USB_DIR_OUT | USB_TYPE_VENDOR |
			     USB_RECIP_ENDPOINT, 0,
			     (__u16) USBVISION_INTRA_CYC, value, 5, HZ);

	if (rc < 0) {
		printk(KERN_ERR "%sERROR=%d. USBVISION stopped - "
		       "reconnect or reload driver.\n", proc, rc);
		return rc;
	}

2033
	if (usbvision->bridge_type == BRIDGE_NT1004) {
2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076
		value[0] =  20; // PCM Threshold 1
		value[1] =  12; // PCM Threshold 2
		value[2] = 255; // Distorsion Threshold inter
		value[3] = 255; // Distorsion Threshold intra
		value[4] =  43; // Max Distorsion inter
		value[5] =  43; // Max Distorsion intra
	}
	else {
		value[0] =  20; // PCM Threshold 1
		value[1] =  12; // PCM Threshold 2
		value[2] = 255; // Distorsion Threshold d7-d0
		value[3] =   0; // Distorsion Threshold d11-d8
		value[4] =  43; // Max Distorsion d7-d0
		value[5] =   0; // Max Distorsion d8
	}

	if (!USBVISION_IS_OPERATIONAL(usbvision))
		return 0;

	rc = usb_control_msg(usbvision->dev, usb_sndctrlpipe(usbvision->dev, 1),
			     USBVISION_OP_CODE,
			     USB_DIR_OUT | USB_TYPE_VENDOR |
			     USB_RECIP_ENDPOINT, 0,
			     (__u16) USBVISION_PCM_THR1, value, 6, HZ);

	if (rc < 0) {
		printk(KERN_ERR "%sERROR=%d. USBVISION stopped - "
		       "reconnect or reload driver.\n", proc, rc);
		return rc;
	}


	return rc;
}


/*
 * usbvision_set_input()
 *
 * Set the input (saa711x, ...) size x y and other misc input params
 * I've no idea if this parameters are right
 *
 */
2077
int usbvision_set_input(struct usb_usbvision *usbvision)
2078 2079 2080 2081 2082 2083 2084 2085 2086 2087
{
	static const char proc[] = "usbvision_set_input: ";
	int rc;
	unsigned char value[8];
	unsigned char dvi_yuv_value;

	if (!USBVISION_IS_OPERATIONAL(usbvision))
		return 0;

	/* Set input format expected from decoder*/
2088 2089 2090
	if (usbvision_device_data[usbvision->dev_model].vin_reg1_override) {
		value[0] = usbvision_device_data[usbvision->dev_model].vin_reg1;
	} else if(usbvision_device_data[usbvision->dev_model].codec == CODEC_SAA7113) {
2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107
		/* SAA7113 uses 8 bit output */
		value[0] = USBVISION_8_422_SYNC;
	} else {
		/* I'm sure only about d2-d0 [010] 16 bit 4:2:2 usin sync pulses
		 * as that is how saa7111 is configured */
		value[0] = USBVISION_16_422_SYNC;
		/* | USBVISION_VSNC_POL | USBVISION_VCLK_POL);*/
	}

	rc = usbvision_write_reg(usbvision, USBVISION_VIN_REG1, value[0]);
	if (rc < 0) {
		printk(KERN_ERR "%sERROR=%d. USBVISION stopped - "
		       "reconnect or reload driver.\n", proc, rc);
		return rc;
	}


2108
	if (usbvision->tvnorm_id & V4L2_STD_PAL) {
2109 2110 2111 2112 2113 2114 2115 2116
		value[0] = 0xC0;
		value[1] = 0x02;	//0x02C0 -> 704 Input video line length
		value[2] = 0x20;
		value[3] = 0x01;	//0x0120 -> 288 Input video n. of lines
		value[4] = 0x60;
		value[5] = 0x00;	//0x0060 -> 96 Input video h offset
		value[6] = 0x16;
		value[7] = 0x00;	//0x0016 -> 22 Input video v offset
2117
	} else if (usbvision->tvnorm_id & V4L2_STD_SECAM) {
2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136
		value[0] = 0xC0;
		value[1] = 0x02;	//0x02C0 -> 704 Input video line length
		value[2] = 0x20;
		value[3] = 0x01;	//0x0120 -> 288 Input video n. of lines
		value[4] = 0x01;
		value[5] = 0x00;	//0x0001 -> 01 Input video h offset
		value[6] = 0x01;
		value[7] = 0x00;	//0x0001 -> 01 Input video v offset
	} else {	/* V4L2_STD_NTSC */
		value[0] = 0xD0;
		value[1] = 0x02;	//0x02D0 -> 720 Input video line length
		value[2] = 0xF0;
		value[3] = 0x00;	//0x00F0 -> 240 Input video number of lines
		value[4] = 0x50;
		value[5] = 0x00;	//0x0050 -> 80 Input video h offset
		value[6] = 0x10;
		value[7] = 0x00;	//0x0010 -> 16 Input video v offset
	}

2137 2138 2139
	if (usbvision_device_data[usbvision->dev_model].x_offset >= 0) {
		value[4]=usbvision_device_data[usbvision->dev_model].x_offset & 0xff;
		value[5]=(usbvision_device_data[usbvision->dev_model].x_offset & 0x0300) >> 8;
2140 2141
	}

2142 2143 2144
	if (adjust_x_offset != -1) {
		value[4] = adjust_x_offset & 0xff;
		value[5] = (adjust_x_offset & 0x0300) >> 8;
2145 2146
	}

2147 2148 2149
	if (usbvision_device_data[usbvision->dev_model].y_offset >= 0) {
		value[6]=usbvision_device_data[usbvision->dev_model].y_offset & 0xff;
		value[7]=(usbvision_device_data[usbvision->dev_model].y_offset & 0x0300) >> 8;
2150 2151
	}

2152 2153 2154
	if (adjust_y_offset != -1) {
		value[6] = adjust_y_offset & 0xff;
		value[7] = (adjust_y_offset & 0x0300) >> 8;
2155 2156
	}

2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169
	rc = usb_control_msg(usbvision->dev, usb_sndctrlpipe(usbvision->dev, 1),
			     USBVISION_OP_CODE,	/* USBVISION specific code */
			     USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT, 0,
			     (__u16) USBVISION_LXSIZE_I, value, 8, HZ);
	if (rc < 0) {
		printk(KERN_ERR "%sERROR=%d. USBVISION stopped - "
		       "reconnect or reload driver.\n", proc, rc);
		return rc;
	}


	dvi_yuv_value = 0x00;	/* U comes after V, Ya comes after U/V, Yb comes after Yb */

2170 2171
	if(usbvision_device_data[usbvision->dev_model].dvi_yuv_override){
		dvi_yuv_value = usbvision_device_data[usbvision->dev_model].dvi_yuv;
2172
	}
2173
	else if(usbvision_device_data[usbvision->dev_model].codec == CODEC_SAA7113) {
2174
	/* This changes as the fine sync control changes. Further investigation necessary */
2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194
		dvi_yuv_value = 0x06;
	}

	return (usbvision_write_reg(usbvision, USBVISION_DVI_YUV, dvi_yuv_value));
}


/*
 * usbvision_set_dram_settings()
 *
 * Set the buffer address needed by the usbvision dram to operate
 * This values has been taken with usbsnoop.
 *
 */

static int usbvision_set_dram_settings(struct usb_usbvision *usbvision)
{
	int rc;
	unsigned char value[8];

2195
	if (usbvision->isoc_mode == ISOC_MODE_COMPRESS) {
2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240
		value[0] = 0x42;
		value[1] = 0x71;
		value[2] = 0xff;
		value[3] = 0x00;
		value[4] = 0x98;
		value[5] = 0xe0;
		value[6] = 0x71;
		value[7] = 0xff;
		// UR:  0x0E200-0x3FFFF = 204288 Words (1 Word = 2 Byte)
		// FDL: 0x00000-0x0E099 =  57498 Words
		// VDW: 0x0E3FF-0x3FFFF
	}
	else {
		value[0] = 0x42;
		value[1] = 0x00;
		value[2] = 0xff;
		value[3] = 0x00;
		value[4] = 0x00;
		value[5] = 0x00;
		value[6] = 0x00;
		value[7] = 0xff;
	}
	/* These are the values of the address of the video buffer,
	 * they have to be loaded into the USBVISION_DRM_PRM1-8
	 *
	 * Start address of video output buffer for read: 	drm_prm1-2 -> 0x00000
	 * End address of video output buffer for read: 	drm_prm1-3 -> 0x1ffff
	 * Start address of video frame delay buffer: 		drm_prm1-4 -> 0x20000
	 *    Only used in compressed mode
	 * End address of video frame delay buffer: 		drm_prm1-5-6 -> 0x3ffff
	 *    Only used in compressed mode
	 * Start address of video output buffer for write: 	drm_prm1-7 -> 0x00000
	 * End address of video output buffer for write: 	drm_prm1-8 -> 0x1ffff
	 */

	if (!USBVISION_IS_OPERATIONAL(usbvision))
		return 0;

	rc = usb_control_msg(usbvision->dev, usb_sndctrlpipe(usbvision->dev, 1),
			     USBVISION_OP_CODE,	/* USBVISION specific code */
			     USB_DIR_OUT | USB_TYPE_VENDOR |
			     USB_RECIP_ENDPOINT, 0,
			     (__u16) USBVISION_DRM_PRM1, value, 8, HZ);

	if (rc < 0) {
2241
		dev_err(&usbvision->dev->dev, "%sERROR=%d\n", __func__, rc);
2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261
		return rc;
	}

	/* Restart the video buffer logic */
	if ((rc = usbvision_write_reg(usbvision, USBVISION_DRM_CONT, USBVISION_RES_UR |
				   USBVISION_RES_FDL | USBVISION_RES_VDW)) < 0)
		return rc;
	rc = usbvision_write_reg(usbvision, USBVISION_DRM_CONT, 0x00);

	return rc;
}

/*
 * ()
 *
 * Power on the device, enables suspend-resume logic
 * &  reset the isoc End-Point
 *
 */

2262
int usbvision_power_on(struct usb_usbvision *usbvision)
2263
{
2264
	int err_code = 0;
2265 2266 2267 2268 2269 2270

	PDEBUG(DBG_FUNC, "");

	usbvision_write_reg(usbvision, USBVISION_PWR_REG, USBVISION_SSPND_EN);
	usbvision_write_reg(usbvision, USBVISION_PWR_REG,
			 USBVISION_SSPND_EN | USBVISION_RES2);
2271

2272 2273
	usbvision_write_reg(usbvision, USBVISION_PWR_REG,
			 USBVISION_SSPND_EN | USBVISION_PWR_VID);
2274
	err_code = usbvision_write_reg(usbvision, USBVISION_PWR_REG,
2275
						USBVISION_SSPND_EN | USBVISION_PWR_VID | USBVISION_RES2);
2276
	if (err_code == 1) {
2277 2278
		usbvision->power = 1;
	}
2279 2280
	PDEBUG(DBG_FUNC, "%s: err_code %d", (err_code<0)?"ERROR":"power is on", err_code);
	return err_code;
2281 2282 2283
}


2284 2285 2286 2287 2288
/*
 * usbvision timer stuff
 */

// to call usbvision_power_off from task queue
2289
static void call_usbvision_power_off(struct work_struct *work)
2290
{
2291
	struct usb_usbvision *usbvision = container_of(work, struct usb_usbvision, power_off_work);
2292 2293

	PDEBUG(DBG_FUNC, "");
2294
	if (mutex_lock_interruptible(&usbvision->v4l2_lock))
2295 2296
		return;

2297
	if(usbvision->user == 0) {
2298
		usbvision_i2c_unregister(usbvision);
2299

2300 2301 2302
		usbvision_power_off(usbvision);
		usbvision->initialized = 0;
	}
2303
	mutex_unlock(&usbvision->v4l2_lock);
2304 2305
}

2306
static void usbvision_power_off_timer(unsigned long data)
2307 2308 2309 2310
{
	struct usb_usbvision *usbvision = (void *) data;

	PDEBUG(DBG_FUNC, "");
2311 2312 2313
	del_timer(&usbvision->power_off_timer);
	INIT_WORK(&usbvision->power_off_work, call_usbvision_power_off);
	(void) schedule_work(&usbvision->power_off_work);
2314 2315
}

2316
void usbvision_init_power_off_timer(struct usb_usbvision *usbvision)
2317
{
2318 2319 2320
	init_timer(&usbvision->power_off_timer);
	usbvision->power_off_timer.data = (long) usbvision;
	usbvision->power_off_timer.function = usbvision_power_off_timer;
2321 2322
}

2323
void usbvision_set_power_off_timer(struct usb_usbvision *usbvision)
2324
{
2325
	mod_timer(&usbvision->power_off_timer, jiffies + USBVISION_POWEROFF_TIME);
2326 2327
}

2328
void usbvision_reset_power_off_timer(struct usb_usbvision *usbvision)
2329
{
2330 2331
	if (timer_pending(&usbvision->power_off_timer)) {
		del_timer(&usbvision->power_off_timer);
2332 2333
	}
}
2334 2335 2336 2337 2338 2339

/*
 * usbvision_begin_streaming()
 * Sure you have to put bit 7 to 0, if not incoming frames are droped, but no
 * idea about the rest
 */
2340
int usbvision_begin_streaming(struct usb_usbvision *usbvision)
2341
{
2342
	int err_code = 0;
2343

2344
	if (usbvision->isoc_mode == ISOC_MODE_COMPRESS) {
2345 2346
		usbvision_init_compression(usbvision);
	}
2347 2348 2349
	err_code = usbvision_write_reg(usbvision, USBVISION_VIN_REG2, USBVISION_NOHVALID |
										usbvision->vin_reg2_preset);
	return err_code;
2350 2351 2352 2353 2354 2355 2356
}

/*
 * usbvision_restart_isoc()
 * Not sure yet if touching here PWR_REG make loose the config
 */

2357
int usbvision_restart_isoc(struct usb_usbvision *usbvision)
2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375
{
	int ret;

	if (
	    (ret =
	     usbvision_write_reg(usbvision, USBVISION_PWR_REG,
			      USBVISION_SSPND_EN | USBVISION_PWR_VID)) < 0)
		return ret;
	if (
	    (ret =
	     usbvision_write_reg(usbvision, USBVISION_PWR_REG,
			      USBVISION_SSPND_EN | USBVISION_PWR_VID |
			      USBVISION_RES2)) < 0)
		return ret;
	if (
	    (ret =
	     usbvision_write_reg(usbvision, USBVISION_VIN_REG2,
			      USBVISION_KEEP_BLANK | USBVISION_NOHVALID |
2376
				  usbvision->vin_reg2_preset)) < 0) return ret;
2377 2378

	/* TODO: schedule timeout */
2379
	while ((usbvision_read_reg(usbvision, USBVISION_STATUS_REG) & 0x01) != 1);
2380 2381 2382 2383

	return 0;
}

2384
int usbvision_audio_off(struct usb_usbvision *usbvision)
2385 2386 2387 2388 2389
{
	if (usbvision_write_reg(usbvision, USBVISION_IOPIN_REG, USBVISION_AUDIO_MUTE) < 0) {
		printk(KERN_ERR "usbvision_audio_off: can't wirte reg\n");
		return -1;
	}
2390 2391
	usbvision->audio_mute = 0;
	usbvision->audio_channel = USBVISION_AUDIO_MUTE;
2392 2393 2394
	return 0;
}

2395
int usbvision_set_audio(struct usb_usbvision *usbvision, int audio_channel)
2396
{
2397 2398
	if (!usbvision->audio_mute) {
		if (usbvision_write_reg(usbvision, USBVISION_IOPIN_REG, audio_channel) < 0) {
2399 2400 2401 2402
			printk(KERN_ERR "usbvision_set_audio: can't write iopin register for audio switching\n");
			return -1;
		}
	}
2403
	usbvision->audio_channel = audio_channel;
2404 2405 2406
	return 0;
}

2407
int usbvision_setup(struct usb_usbvision *usbvision,int format)
2408
{
2409
	usbvision_set_video_format(usbvision, format);
2410 2411 2412 2413 2414
	usbvision_set_dram_settings(usbvision);
	usbvision_set_compress_params(usbvision);
	usbvision_set_input(usbvision);
	usbvision_set_output(usbvision, MAX_USB_WIDTH, MAX_USB_HEIGHT);
	usbvision_restart_isoc(usbvision);
2415

2416 2417 2418 2419
	/* cosas del PCM */
	return USBVISION_IS_OPERATIONAL(usbvision);
}

2420 2421
int usbvision_set_alternate(struct usb_usbvision *dev)
{
2422
	int err_code, prev_alt = dev->iface_alt;
2423 2424
	int i;

2425
	dev->iface_alt=0;
2426
	for(i=0;i< dev->num_alt; i++)
2427 2428 2429 2430 2431 2432 2433 2434
		if(dev->alt_max_pkt_size[i]>dev->alt_max_pkt_size[dev->iface_alt])
			dev->iface_alt=i;

	if (dev->iface_alt != prev_alt) {
		dev->isoc_packet_size = dev->alt_max_pkt_size[dev->iface_alt];
		PDEBUG(DBG_FUNC,"setting alternate %d with max_packet_size=%u", dev->iface_alt,dev->isoc_packet_size);
		err_code = usb_set_interface(dev->dev, dev->iface, dev->iface_alt);
		if (err_code < 0) {
2435 2436
			dev_err(&dev->dev->dev,
				"cannot change alternate number to %d (error=%i)\n",
2437 2438
					dev->iface_alt, err_code);
			return err_code;
2439 2440 2441
		}
	}

2442
	PDEBUG(DBG_ISOC, "ISO Packet Length:%d", dev->isoc_packet_size);
2443 2444 2445 2446

	return 0;
}

2447 2448 2449 2450 2451 2452 2453
/*
 * usbvision_init_isoc()
 *
 */
int usbvision_init_isoc(struct usb_usbvision *usbvision)
{
	struct usb_device *dev = usbvision->dev;
2454
	int buf_idx, err_code, reg_value;
2455
	int sb_size;
2456 2457 2458 2459

	if (!USBVISION_IS_OPERATIONAL(usbvision))
		return -EFAULT;

2460
	usbvision->cur_frame = NULL;
2461 2462 2463
	scratch_reset(usbvision);

	/* Alternate interface 1 is is the biggest frame size */
2464 2465 2466
	err_code = usbvision_set_alternate(usbvision);
	if (err_code < 0) {
		usbvision->last_error = err_code;
2467 2468
		return -EBUSY;
	}
2469
	sb_size = USBVISION_URB_FRAMES * usbvision->isoc_packet_size;
2470

2471
	reg_value = (16 - usbvision_read_reg(usbvision,
2472
					    USBVISION_ALTER_REG)) & 0x0F;
2473

2474
	usbvision->usb_bandwidth = reg_value >> 1;
2475 2476
	PDEBUG(DBG_ISOC, "USB Bandwidth Usage: %dMbit/Sec",
	       usbvision->usb_bandwidth);
2477 2478 2479 2480 2481



	/* We double buffer the Iso lists */

2482
	for (buf_idx = 0; buf_idx < USBVISION_NUMSBUF; buf_idx++) {
2483 2484 2485
		int j, k;
		struct urb *urb;

2486
		urb = usb_alloc_urb(USBVISION_URB_FRAMES, GFP_KERNEL);
2487
		if (urb == NULL) {
2488 2489
			dev_err(&usbvision->dev->dev,
				"%s: usb_alloc_urb() failed\n", __func__);
2490 2491
			return -ENOMEM;
		}
2492 2493
		usbvision->sbuf[buf_idx].urb = urb;
		usbvision->sbuf[buf_idx].data =
2494 2495 2496 2497
			usb_alloc_coherent(usbvision->dev,
					   sb_size,
					   GFP_KERNEL,
					   &urb->transfer_dma);
2498 2499 2500
		urb->dev = dev;
		urb->context = usbvision;
		urb->pipe = usb_rcvisocpipe(dev, usbvision->video_endp);
2501
		urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
2502
		urb->interval = 1;
2503 2504
		urb->transfer_buffer = usbvision->sbuf[buf_idx].data;
		urb->complete = usbvision_isoc_irq;
2505 2506
		urb->number_of_packets = USBVISION_URB_FRAMES;
		urb->transfer_buffer_length =
2507
		    usbvision->isoc_packet_size * USBVISION_URB_FRAMES;
2508
		for (j = k = 0; j < USBVISION_URB_FRAMES; j++,
2509
		     k += usbvision->isoc_packet_size) {
2510
			urb->iso_frame_desc[j].offset = k;
2511
			urb->iso_frame_desc[j].length =
2512
				usbvision->isoc_packet_size;
2513 2514 2515 2516
		}
	}

	/* Submit all URBs */
2517 2518
	for (buf_idx = 0; buf_idx < USBVISION_NUMSBUF; buf_idx++) {
			err_code = usb_submit_urb(usbvision->sbuf[buf_idx].urb,
2519
						 GFP_KERNEL);
2520
		if (err_code) {
2521 2522
			dev_err(&usbvision->dev->dev,
				"%s: usb_submit_urb(%d) failed: error %d\n",
2523
					__func__, buf_idx, err_code);
2524 2525 2526
		}
	}

2527
	usbvision->streaming = stream_idle;
2528
	PDEBUG(DBG_ISOC, "%s: streaming=1 usbvision->video_endp=$%02x",
2529
	       __func__,
2530
	       usbvision->video_endp);
2531 2532 2533 2534 2535 2536 2537 2538 2539 2540
	return 0;
}

/*
 * usbvision_stop_isoc()
 *
 * This procedure stops streaming and deallocates URBs. Then it
 * activates zero-bandwidth alt. setting of the video interface.
 *
 */
2541
void usbvision_stop_isoc(struct usb_usbvision *usbvision)
2542
{
2543 2544
	int buf_idx, err_code, reg_value;
	int sb_size = USBVISION_URB_FRAMES * usbvision->isoc_packet_size;
2545

2546
	if ((usbvision->streaming == stream_off) || (usbvision->dev == NULL))
2547 2548 2549
		return;

	/* Unschedule all of the iso td's */
2550 2551 2552
	for (buf_idx = 0; buf_idx < USBVISION_NUMSBUF; buf_idx++) {
		usb_kill_urb(usbvision->sbuf[buf_idx].urb);
		if (usbvision->sbuf[buf_idx].data){
2553 2554
			usb_free_coherent(usbvision->dev,
					  sb_size,
2555 2556
					  usbvision->sbuf[buf_idx].data,
					  usbvision->sbuf[buf_idx].urb->transfer_dma);
2557
		}
2558 2559
		usb_free_urb(usbvision->sbuf[buf_idx].urb);
		usbvision->sbuf[buf_idx].urb = NULL;
2560
	}
2561

2562 2563
	PDEBUG(DBG_ISOC, "%s: streaming=stream_off\n", __func__);
	usbvision->streaming = stream_off;
2564 2565 2566 2567

	if (!usbvision->remove_pending) {

		/* Set packet size to 0 */
2568 2569 2570 2571
		usbvision->iface_alt=0;
		err_code = usb_set_interface(usbvision->dev, usbvision->iface,
					    usbvision->iface_alt);
		if (err_code < 0) {
2572 2573
			dev_err(&usbvision->dev->dev,
				"%s: usb_set_interface() failed: error %d\n",
2574 2575
					__func__, err_code);
			usbvision->last_error = err_code;
2576
		}
2577 2578 2579
		reg_value = (16-usbvision_read_reg(usbvision, USBVISION_ALTER_REG)) & 0x0F;
		usbvision->isoc_packet_size =
			(reg_value == 0) ? 0 : (reg_value * 64) - 1;
2580
		PDEBUG(DBG_ISOC, "ISO Packet Length:%d",
2581
		       usbvision->isoc_packet_size);
2582

2583
		usbvision->usb_bandwidth = reg_value >> 1;
2584 2585
		PDEBUG(DBG_ISOC, "USB Bandwidth Usage: %dMbit/Sec",
		       usbvision->usb_bandwidth);
2586 2587 2588
	}
}

2589
int usbvision_muxsel(struct usb_usbvision *usbvision, int channel)
2590
{
2591 2592 2593
	/* inputs #0 and #3 are constant for every SAA711x. */
	/* inputs #1 and #2 are variable for SAA7111 and SAA7113 */
	int mode[4]= {SAA7115_COMPOSITE0, 0, 0, SAA7115_COMPOSITE3};
2594
	int audio[]= {1, 0, 0, 0};
2595 2596 2597 2598 2599 2600
	//channel 0 is TV with audiochannel 1 (tuner mono)
	//channel 1 is Composite with audio channel 0 (line in)
	//channel 2 is S-Video with audio channel 0 (line in)
	//channel 3 is additional video inputs to the device with audio channel 0 (line in)

	RESTRICT_TO_RANGE(channel, 0, usbvision->video_inputs);
2601
	usbvision->ctl_input = channel;
2602 2603 2604

	// set the new channel
	// Regular USB TV Tuners -> channel: 0 = Television, 1 = Composite, 2 = S-Video
2605
	// Four video input devices -> channel: 0 = Chan White, 1 = Chan Green, 2 = Chan Yellow, 3 = Chan Red
2606

2607
	switch (usbvision_device_data[usbvision->dev_model].codec) {
2608
		case CODEC_SAA7113:
2609
			mode[1] = SAA7115_COMPOSITE2;
2610
			if (switch_svideo_input) {
2611
				/* To handle problems with S-Video Input for
2612
				 * some devices.  Use switch_svideo_input
2613 2614
				 * parameter when loading the module.*/
				mode[2] = SAA7115_COMPOSITE1;
2615 2616
			}
			else {
2617
				mode[2] = SAA7115_SVIDEO1;
2618 2619 2620 2621
			}
			break;
		case CODEC_SAA7111:
		default:
2622 2623 2624 2625
			/* modes for saa7111 */
			mode[1] = SAA7115_COMPOSITE1;
			mode[2] = SAA7115_SVIDEO1;
			break;
2626
	}
2627
	call_all(usbvision, video, s_routing, mode[channel], 0, 0);
2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638
	usbvision_set_audio(usbvision, audio[channel]);
	return 0;
}

/*
 * Overrides for Emacs so that we follow Linus's tabbing style.
 * ---------------------------------------------------------------------------
 * Local variables:
 * c-basic-offset: 8
 * End:
 */