File Index
Files and directories
Sign in
FILE

go7007-usb.c

File preview with syntax highlighting.

linux-6.19.14/drivers/media/usb/go7007/go7007-usb.c C
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright (C) 2005-2006 Micronas USA Inc.
   4 */
   5
   6#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
   7
   8#include <linux/module.h>
   9#include <linux/kernel.h>
  10#include <linux/wait.h>
  11#include <linux/list.h>
  12#include <linux/slab.h>
  13#include <linux/time.h>
  14#include <linux/mm.h>
  15#include <linux/usb.h>
  16#include <linux/i2c.h>
  17#include <asm/byteorder.h>
  18#include <media/i2c/saa7115.h>
  19#include <media/tuner.h>
  20#include <media/i2c/uda1342.h>
  21
  22#include "go7007-priv.h"
  23
  24static unsigned int assume_endura;
  25module_param(assume_endura, int, 0644);
  26MODULE_PARM_DESC(assume_endura,
  27			"when probing fails, hardware is a Pelco Endura");
  28
  29/* #define GO7007_I2C_DEBUG */ /* for debugging the EZ-USB I2C adapter */
  30
  31#define	HPI_STATUS_ADDR	0xFFF4
  32#define	INT_PARAM_ADDR	0xFFF6
  33#define	INT_INDEX_ADDR	0xFFF8
  34
  35/*
  36 * Pipes on EZ-USB interface:
  37 *	0 snd - Control
  38 *	0 rcv - Control
  39 *	2 snd - Download firmware (control)
  40 *	4 rcv - Read Interrupt (interrupt)
  41 *	6 rcv - Read Video (bulk)
  42 *	8 rcv - Read Audio (bulk)
  43 */
  44
  45#define GO7007_USB_EZUSB		(1<<0)
  46#define GO7007_USB_EZUSB_I2C		(1<<1)
  47
  48struct go7007_usb_board {
  49	unsigned int flags;
  50	struct go7007_board_info main_info;
  51};
  52
  53struct go7007_usb {
  54	const struct go7007_usb_board *board;
  55	struct mutex i2c_lock;
  56	struct usb_device *usbdev;
  57	struct urb *video_urbs[8];
  58	struct urb *audio_urbs[8];
  59	struct urb *intr_urb;
  60};
  61
  62/*********************** Product specification data ***********************/
  63
  64static const struct go7007_usb_board board_matrix_ii = {
  65	.flags		= GO7007_USB_EZUSB,
  66	.main_info	= {
  67		.flags		 = GO7007_BOARD_HAS_AUDIO |
  68					GO7007_BOARD_USE_ONBOARD_I2C,
  69		.audio_flags	 = GO7007_AUDIO_I2S_MODE_1 |
  70					GO7007_AUDIO_WORD_16,
  71		.audio_rate	 = 48000,
  72		.audio_bclk_div	 = 8,
  73		.audio_main_div	 = 2,
  74		.hpi_buffer_cap  = 7,
  75		.sensor_flags	 = GO7007_SENSOR_656 |
  76					GO7007_SENSOR_VALID_ENABLE |
  77					GO7007_SENSOR_TV |
  78					GO7007_SENSOR_SAA7115 |
  79					GO7007_SENSOR_VBI |
  80					GO7007_SENSOR_SCALING,
  81		.num_i2c_devs	 = 1,
  82		.i2c_devs	 = {
  83			{
  84				.type	= "saa7115",
  85				.addr	= 0x20,
  86				.is_video = 1,
  87			},
  88		},
  89		.num_inputs	 = 2,
  90		.inputs		 = {
  91			{
  92				.video_input	= 0,
  93				.name		= "Composite",
  94			},
  95			{
  96				.video_input	= 9,
  97				.name		= "S-Video",
  98			},
  99		},
 100		.video_config	= SAA7115_IDQ_IS_DEFAULT,
 101	},
 102};
 103
 104static const struct go7007_usb_board board_matrix_reload = {
 105	.flags		= GO7007_USB_EZUSB,
 106	.main_info	= {
 107		.flags		 = GO7007_BOARD_HAS_AUDIO |
 108					GO7007_BOARD_USE_ONBOARD_I2C,
 109		.audio_flags	 = GO7007_AUDIO_I2S_MODE_1 |
 110					GO7007_AUDIO_I2S_MASTER |
 111					GO7007_AUDIO_WORD_16,
 112		.audio_rate	 = 48000,
 113		.audio_bclk_div	 = 8,
 114		.audio_main_div	 = 2,
 115		.hpi_buffer_cap  = 7,
 116		.sensor_flags	 = GO7007_SENSOR_656 |
 117					GO7007_SENSOR_TV,
 118		.num_i2c_devs	 = 1,
 119		.i2c_devs	 = {
 120			{
 121				.type	= "saa7113",
 122				.addr	= 0x25,
 123				.is_video = 1,
 124			},
 125		},
 126		.num_inputs	 = 2,
 127		.inputs		 = {
 128			{
 129				.video_input	= 0,
 130				.name		= "Composite",
 131			},
 132			{
 133				.video_input	= 9,
 134				.name		= "S-Video",
 135			},
 136		},
 137		.video_config	= SAA7115_IDQ_IS_DEFAULT,
 138	},
 139};
 140
 141static const struct go7007_usb_board board_star_trek = {
 142	.flags		= GO7007_USB_EZUSB | GO7007_USB_EZUSB_I2C,
 143	.main_info	= {
 144		.flags		 = GO7007_BOARD_HAS_AUDIO, /* |
 145					GO7007_BOARD_HAS_TUNER, */
 146		.sensor_flags	 = GO7007_SENSOR_656 |
 147					GO7007_SENSOR_VALID_ENABLE |
 148					GO7007_SENSOR_TV |
 149					GO7007_SENSOR_SAA7115 |
 150					GO7007_SENSOR_VBI |
 151					GO7007_SENSOR_SCALING,
 152		.audio_flags	 = GO7007_AUDIO_I2S_MODE_1 |
 153					GO7007_AUDIO_WORD_16,
 154		.audio_bclk_div	 = 8,
 155		.audio_main_div	 = 2,
 156		.hpi_buffer_cap  = 7,
 157		.num_i2c_devs	 = 1,
 158		.i2c_devs	 = {
 159			{
 160				.type	= "saa7115",
 161				.addr	= 0x20,
 162				.is_video = 1,
 163			},
 164		},
 165		.num_inputs	 = 2,
 166		.inputs		 = {
 167		/*	{
 168		 *		.video_input	= 3,
 169		 *		.audio_index	= AUDIO_TUNER,
 170		 *		.name		= "Tuner",
 171		 *	},
 172		 */
 173			{
 174				.video_input	= 1,
 175			/*	.audio_index	= AUDIO_EXTERN, */
 176				.name		= "Composite",
 177			},
 178			{
 179				.video_input	= 8,
 180			/*	.audio_index	= AUDIO_EXTERN, */
 181				.name		= "S-Video",
 182			},
 183		},
 184		.video_config	= SAA7115_IDQ_IS_DEFAULT,
 185	},
 186};
 187
 188static const struct go7007_usb_board board_px_tv402u = {
 189	.flags		= GO7007_USB_EZUSB | GO7007_USB_EZUSB_I2C,
 190	.main_info	= {
 191		.flags		 = GO7007_BOARD_HAS_AUDIO |
 192					GO7007_BOARD_HAS_TUNER,
 193		.sensor_flags	 = GO7007_SENSOR_656 |
 194					GO7007_SENSOR_VALID_ENABLE |
 195					GO7007_SENSOR_TV |
 196					GO7007_SENSOR_SAA7115 |
 197					GO7007_SENSOR_VBI |
 198					GO7007_SENSOR_SCALING,
 199		.audio_flags	 = GO7007_AUDIO_I2S_MODE_1 |
 200					GO7007_AUDIO_WORD_16,
 201		.audio_bclk_div	 = 8,
 202		.audio_main_div	 = 2,
 203		.hpi_buffer_cap  = 7,
 204		.num_i2c_devs	 = 5,
 205		.i2c_devs	 = {
 206			{
 207				.type	= "saa7115",
 208				.addr	= 0x20,
 209				.is_video = 1,
 210			},
 211			{
 212				.type	= "uda1342",
 213				.addr	= 0x1a,
 214				.is_audio = 1,
 215			},
 216			{
 217				.type	= "tuner",
 218				.addr	= 0x60,
 219			},
 220			{
 221				.type	= "tuner",
 222				.addr	= 0x43,
 223			},
 224			{
 225				.type	= "sony-btf-mpx",
 226				.addr	= 0x44,
 227			},
 228		},
 229		.num_inputs	 = 3,
 230		.inputs		 = {
 231			{
 232				.video_input	= 3,
 233				.audio_index	= 0,
 234				.name		= "Tuner",
 235			},
 236			{
 237				.video_input	= 1,
 238				.audio_index	= 1,
 239				.name		= "Composite",
 240			},
 241			{
 242				.video_input	= 8,
 243				.audio_index	= 1,
 244				.name		= "S-Video",
 245			},
 246		},
 247		.video_config	= SAA7115_IDQ_IS_DEFAULT,
 248		.num_aud_inputs	 = 2,
 249		.aud_inputs	 = {
 250			{
 251				.audio_input	= UDA1342_IN2,
 252				.name		= "Tuner",
 253			},
 254			{
 255				.audio_input	= UDA1342_IN1,
 256				.name		= "Line In",
 257			},
 258		},
 259	},
 260};
 261
 262static const struct go7007_usb_board board_xmen = {
 263	.flags		= 0,
 264	.main_info	= {
 265		.flags		  = GO7007_BOARD_USE_ONBOARD_I2C,
 266		.hpi_buffer_cap   = 0,
 267		.sensor_flags	  = GO7007_SENSOR_VREF_POLAR,
 268		.sensor_width	  = 320,
 269		.sensor_height	  = 240,
 270		.sensor_framerate = 30030,
 271		.audio_flags	  = GO7007_AUDIO_ONE_CHANNEL |
 272					GO7007_AUDIO_I2S_MODE_3 |
 273					GO7007_AUDIO_WORD_14 |
 274					GO7007_AUDIO_I2S_MASTER |
 275					GO7007_AUDIO_BCLK_POLAR |
 276					GO7007_AUDIO_OKI_MODE,
 277		.audio_rate	  = 8000,
 278		.audio_bclk_div	  = 48,
 279		.audio_main_div	  = 1,
 280		.num_i2c_devs	  = 1,
 281		.i2c_devs	  = {
 282			{
 283				.type	= "ov7640",
 284				.addr	= 0x21,
 285			},
 286		},
 287		.num_inputs	  = 1,
 288		.inputs		  = {
 289			{
 290				.name		= "Camera",
 291			},
 292		},
 293	},
 294};
 295
 296static const struct go7007_usb_board board_matrix_revolution = {
 297	.flags		= GO7007_USB_EZUSB,
 298	.main_info	= {
 299		.flags		 = GO7007_BOARD_HAS_AUDIO |
 300					GO7007_BOARD_USE_ONBOARD_I2C,
 301		.audio_flags	 = GO7007_AUDIO_I2S_MODE_1 |
 302					GO7007_AUDIO_I2S_MASTER |
 303					GO7007_AUDIO_WORD_16,
 304		.audio_rate	 = 48000,
 305		.audio_bclk_div	 = 8,
 306		.audio_main_div	 = 2,
 307		.hpi_buffer_cap  = 7,
 308		.sensor_flags	 = GO7007_SENSOR_656 |
 309					GO7007_SENSOR_TV |
 310					GO7007_SENSOR_VBI,
 311		.num_i2c_devs	 = 1,
 312		.i2c_devs	 = {
 313			{
 314				.type	= "tw9903",
 315				.is_video = 1,
 316				.addr	= 0x44,
 317			},
 318		},
 319		.num_inputs	 = 2,
 320		.inputs		 = {
 321			{
 322				.video_input	= 2,
 323				.name		= "Composite",
 324			},
 325			{
 326				.video_input	= 8,
 327				.name		= "S-Video",
 328			},
 329		},
 330	},
 331};
 332
 333#if 0
 334static const struct go7007_usb_board board_lifeview_lr192 = {
 335	.flags		= GO7007_USB_EZUSB,
 336	.main_info	= {
 337		.flags		 = GO7007_BOARD_HAS_AUDIO |
 338					GO7007_BOARD_USE_ONBOARD_I2C,
 339		.audio_flags	 = GO7007_AUDIO_I2S_MODE_1 |
 340					GO7007_AUDIO_WORD_16,
 341		.audio_rate	 = 48000,
 342		.audio_bclk_div	 = 8,
 343		.audio_main_div	 = 2,
 344		.hpi_buffer_cap  = 7,
 345		.sensor_flags	 = GO7007_SENSOR_656 |
 346					GO7007_SENSOR_VALID_ENABLE |
 347					GO7007_SENSOR_TV |
 348					GO7007_SENSOR_VBI |
 349					GO7007_SENSOR_SCALING,
 350		.num_i2c_devs	 = 0,
 351		.num_inputs	 = 1,
 352		.inputs		 = {
 353			{
 354				.video_input	= 0,
 355				.name		= "Composite",
 356			},
 357		},
 358	},
 359};
 360#endif
 361
 362static const struct go7007_usb_board board_endura = {
 363	.flags		= 0,
 364	.main_info	= {
 365		.flags		 = 0,
 366		.audio_flags	 = GO7007_AUDIO_I2S_MODE_1 |
 367					GO7007_AUDIO_I2S_MASTER |
 368					GO7007_AUDIO_WORD_16,
 369		.audio_rate	 = 8000,
 370		.audio_bclk_div	 = 48,
 371		.audio_main_div	 = 8,
 372		.hpi_buffer_cap  = 0,
 373		.sensor_flags	 = GO7007_SENSOR_656 |
 374					GO7007_SENSOR_TV,
 375		.sensor_h_offset = 8,
 376		.num_i2c_devs	 = 0,
 377		.num_inputs	 = 1,
 378		.inputs		 = {
 379			{
 380				.name		= "Camera",
 381			},
 382		},
 383	},
 384};
 385
 386static const struct go7007_usb_board board_adlink_mpg24 = {
 387	.flags		= 0,
 388	.main_info	= {
 389		.flags		 = GO7007_BOARD_USE_ONBOARD_I2C,
 390		.audio_flags	 = GO7007_AUDIO_I2S_MODE_1 |
 391					GO7007_AUDIO_I2S_MASTER |
 392					GO7007_AUDIO_WORD_16,
 393		.audio_rate	 = 48000,
 394		.audio_bclk_div	 = 8,
 395		.audio_main_div	 = 2,
 396		.hpi_buffer_cap  = 0,
 397		.sensor_flags	 = GO7007_SENSOR_656 |
 398					GO7007_SENSOR_TV |
 399					GO7007_SENSOR_VBI,
 400		.num_i2c_devs	 = 1,
 401		.i2c_devs	 = {
 402			{
 403				.type	= "tw2804",
 404				.addr	= 0x00, /* yes, really */
 405				.flags  = I2C_CLIENT_TEN,
 406				.is_video = 1,
 407			},
 408		},
 409		.num_inputs	 = 1,
 410		.inputs		 = {
 411			{
 412				.name		= "Composite",
 413			},
 414		},
 415	},
 416};
 417
 418static const struct go7007_usb_board board_sensoray_2250 = {
 419	.flags		= GO7007_USB_EZUSB | GO7007_USB_EZUSB_I2C,
 420	.main_info	= {
 421		.audio_flags	 = GO7007_AUDIO_I2S_MODE_1 |
 422					GO7007_AUDIO_I2S_MASTER |
 423					GO7007_AUDIO_WORD_16,
 424		.flags		 = GO7007_BOARD_HAS_AUDIO,
 425		.audio_rate	 = 48000,
 426		.audio_bclk_div	 = 8,
 427		.audio_main_div	 = 2,
 428		.hpi_buffer_cap  = 7,
 429		.sensor_flags	 = GO7007_SENSOR_656 |
 430					GO7007_SENSOR_TV,
 431		.num_i2c_devs	 = 1,
 432		.i2c_devs	 = {
 433			{
 434				.type	= "s2250",
 435				.addr	= 0x43,
 436				.is_video = 1,
 437				.is_audio = 1,
 438			},
 439		},
 440		.num_inputs	 = 2,
 441		.inputs		 = {
 442			{
 443				.video_input	= 0,
 444				.name		= "Composite",
 445			},
 446			{
 447				.video_input	= 1,
 448				.name		= "S-Video",
 449			},
 450		},
 451		.num_aud_inputs	 = 3,
 452		.aud_inputs	 = {
 453			{
 454				.audio_input	= 0,
 455				.name		= "Line In",
 456			},
 457			{
 458				.audio_input	= 1,
 459				.name		= "Mic",
 460			},
 461			{
 462				.audio_input	= 2,
 463				.name		= "Mic Boost",
 464			},
 465		},
 466	},
 467};
 468
 469static const struct go7007_usb_board board_ads_usbav_709 = {
 470	.flags		= GO7007_USB_EZUSB,
 471	.main_info	= {
 472		.flags		 = GO7007_BOARD_HAS_AUDIO |
 473					GO7007_BOARD_USE_ONBOARD_I2C,
 474		.audio_flags	 = GO7007_AUDIO_I2S_MODE_1 |
 475					GO7007_AUDIO_I2S_MASTER |
 476					GO7007_AUDIO_WORD_16,
 477		.audio_rate	 = 48000,
 478		.audio_bclk_div	 = 8,
 479		.audio_main_div	 = 2,
 480		.hpi_buffer_cap  = 7,
 481		.sensor_flags	 = GO7007_SENSOR_656 |
 482					GO7007_SENSOR_TV |
 483					GO7007_SENSOR_VBI,
 484		.num_i2c_devs	 = 1,
 485		.i2c_devs	 = {
 486			{
 487				.type	= "tw9906",
 488				.is_video = 1,
 489				.addr	= 0x44,
 490			},
 491		},
 492		.num_inputs	 = 2,
 493		.inputs		 = {
 494			{
 495				.video_input	= 0,
 496				.name		= "Composite",
 497			},
 498			{
 499				.video_input	= 10,
 500				.name		= "S-Video",
 501			},
 502		},
 503	},
 504};
 505
 506static const struct usb_device_id go7007_usb_id_table[] = {
 507	{
 508		.match_flags	= USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION |
 509					USB_DEVICE_ID_MATCH_INT_INFO,
 510		.idVendor	= 0x0eb1,  /* Vendor ID of WIS Technologies */
 511		.idProduct	= 0x7007,  /* Product ID of GO7007SB chip */
 512		.bcdDevice_lo	= 0x200,   /* Revision number of XMen */
 513		.bcdDevice_hi	= 0x200,
 514		.bInterfaceClass	= 255,
 515		.bInterfaceSubClass	= 0,
 516		.bInterfaceProtocol	= 255,
 517		.driver_info	= (kernel_ulong_t)GO7007_BOARDID_XMEN,
 518	},
 519	{
 520		.match_flags	= USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
 521		.idVendor	= 0x0eb1,  /* Vendor ID of WIS Technologies */
 522		.idProduct	= 0x7007,  /* Product ID of GO7007SB chip */
 523		.bcdDevice_lo	= 0x202,   /* Revision number of Matrix II */
 524		.bcdDevice_hi	= 0x202,
 525		.driver_info	= (kernel_ulong_t)GO7007_BOARDID_MATRIX_II,
 526	},
 527	{
 528		.match_flags	= USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
 529		.idVendor	= 0x0eb1,  /* Vendor ID of WIS Technologies */
 530		.idProduct	= 0x7007,  /* Product ID of GO7007SB chip */
 531		.bcdDevice_lo	= 0x204,   /* Revision number of Matrix */
 532		.bcdDevice_hi	= 0x204,   /*     Reloaded */
 533		.driver_info	= (kernel_ulong_t)GO7007_BOARDID_MATRIX_RELOAD,
 534	},
 535	{
 536		.match_flags	= USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION |
 537					USB_DEVICE_ID_MATCH_INT_INFO,
 538		.idVendor	= 0x0eb1,  /* Vendor ID of WIS Technologies */
 539		.idProduct	= 0x7007,  /* Product ID of GO7007SB chip */
 540		.bcdDevice_lo	= 0x205,   /* Revision number of XMen-II */
 541		.bcdDevice_hi	= 0x205,
 542		.bInterfaceClass	= 255,
 543		.bInterfaceSubClass	= 0,
 544		.bInterfaceProtocol	= 255,
 545		.driver_info	= (kernel_ulong_t)GO7007_BOARDID_XMEN_II,
 546	},
 547	{
 548		.match_flags	= USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
 549		.idVendor	= 0x0eb1,  /* Vendor ID of WIS Technologies */
 550		.idProduct	= 0x7007,  /* Product ID of GO7007SB chip */
 551		.bcdDevice_lo	= 0x208,   /* Revision number of Star Trek */
 552		.bcdDevice_hi	= 0x208,
 553		.driver_info	= (kernel_ulong_t)GO7007_BOARDID_STAR_TREK,
 554	},
 555	{
 556		.match_flags	= USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION |
 557					USB_DEVICE_ID_MATCH_INT_INFO,
 558		.idVendor	= 0x0eb1,  /* Vendor ID of WIS Technologies */
 559		.idProduct	= 0x7007,  /* Product ID of GO7007SB chip */
 560		.bcdDevice_lo	= 0x209,   /* Revision number of XMen-III */
 561		.bcdDevice_hi	= 0x209,
 562		.bInterfaceClass	= 255,
 563		.bInterfaceSubClass	= 0,
 564		.bInterfaceProtocol	= 255,
 565		.driver_info	= (kernel_ulong_t)GO7007_BOARDID_XMEN_III,
 566	},
 567	{
 568		.match_flags	= USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
 569		.idVendor	= 0x0eb1,  /* Vendor ID of WIS Technologies */
 570		.idProduct	= 0x7007,  /* Product ID of GO7007SB chip */
 571		.bcdDevice_lo	= 0x210,   /* Revision number of Matrix */
 572		.bcdDevice_hi	= 0x210,   /*     Revolution */
 573		.driver_info	= (kernel_ulong_t)GO7007_BOARDID_MATRIX_REV,
 574	},
 575	{
 576		.match_flags	= USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
 577		.idVendor	= 0x093b,  /* Vendor ID of Plextor */
 578		.idProduct	= 0xa102,  /* Product ID of M402U */
 579		.bcdDevice_lo	= 0x1,	   /* revision number of Blueberry */
 580		.bcdDevice_hi	= 0x1,
 581		.driver_info	= (kernel_ulong_t)GO7007_BOARDID_PX_M402U,
 582	},
 583	{
 584		.match_flags	= USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
 585		.idVendor	= 0x093b,  /* Vendor ID of Plextor */
 586		.idProduct	= 0xa104,  /* Product ID of TV402U */
 587		.bcdDevice_lo	= 0x1,
 588		.bcdDevice_hi	= 0x1,
 589		.driver_info	= (kernel_ulong_t)GO7007_BOARDID_PX_TV402U,
 590	},
 591	{
 592		.match_flags	= USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
 593		.idVendor	= 0x10fd,  /* Vendor ID of Anubis Electronics */
 594		.idProduct	= 0xde00,  /* Product ID of Lifeview LR192 */
 595		.bcdDevice_lo	= 0x1,
 596		.bcdDevice_hi	= 0x1,
 597		.driver_info	= (kernel_ulong_t)GO7007_BOARDID_LIFEVIEW_LR192,
 598	},
 599	{
 600		.match_flags	= USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
 601		.idVendor	= 0x1943,  /* Vendor ID Sensoray */
 602		.idProduct	= 0x2250,  /* Product ID of 2250/2251 */
 603		.bcdDevice_lo	= 0x1,
 604		.bcdDevice_hi	= 0x1,
 605		.driver_info	= (kernel_ulong_t)GO7007_BOARDID_SENSORAY_2250,
 606	},
 607	{
 608		.match_flags	= USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
 609		.idVendor	= 0x06e1,  /* Vendor ID of ADS Technologies */
 610		.idProduct	= 0x0709,  /* Product ID of DVD Xpress DX2 */
 611		.bcdDevice_lo	= 0x204,
 612		.bcdDevice_hi	= 0x204,
 613		.driver_info	= (kernel_ulong_t)GO7007_BOARDID_ADS_USBAV_709,
 614	},
 615	{ }					/* Terminating entry */
 616};
 617
 618MODULE_DEVICE_TABLE(usb, go7007_usb_id_table);
 619
 620/********************* Driver for EZ-USB HPI interface *********************/
 621
 622static int go7007_usb_vendor_request(struct go7007 *go, int request,
 623		int value, int index, void *transfer_buffer, int length, int in)
 624{
 625	struct go7007_usb *usb = go->hpi_context;
 626	int timeout = 5000;
 627
 628	if (in) {
 629		return usb_control_msg(usb->usbdev,
 630				usb_rcvctrlpipe(usb->usbdev, 0), request,
 631				USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
 632				value, index, transfer_buffer, length, timeout);
 633	} else {
 634		return usb_control_msg(usb->usbdev,
 635				usb_sndctrlpipe(usb->usbdev, 0), request,
 636				USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 637				value, index, transfer_buffer, length, timeout);
 638	}
 639}
 640
 641static int go7007_usb_interface_reset(struct go7007 *go)
 642{
 643	struct go7007_usb *usb = go->hpi_context;
 644	u16 intr_val, intr_data;
 645
 646	if (go->status == STATUS_SHUTDOWN)
 647		return -1;
 648	/* Reset encoder */
 649	if (go7007_write_interrupt(go, 0x0001, 0x0001) < 0)
 650		return -1;
 651	msleep(100);
 652
 653	if (usb->board->flags & GO7007_USB_EZUSB) {
 654		/* Reset buffer in EZ-USB */
 655		pr_debug("resetting EZ-USB buffers\n");
 656		if (go7007_usb_vendor_request(go, 0x10, 0, 0, NULL, 0, 0) < 0 ||
 657		    go7007_usb_vendor_request(go, 0x10, 0, 0, NULL, 0, 0) < 0)
 658			return -1;
 659
 660		/* Reset encoder again */
 661		if (go7007_write_interrupt(go, 0x0001, 0x0001) < 0)
 662			return -1;
 663		msleep(100);
 664	}
 665
 666	/* Wait for an interrupt to indicate successful hardware reset */
 667	if (go7007_read_interrupt(go, &intr_val, &intr_data) < 0 ||
 668			(intr_val & ~0x1) != 0x55aa) {
 669		dev_err(go->dev, "unable to reset the USB interface\n");
 670		return -1;
 671	}
 672	return 0;
 673}
 674
 675static int go7007_usb_ezusb_write_interrupt(struct go7007 *go,
 676						int addr, int data)
 677{
 678	struct go7007_usb *usb = go->hpi_context;
 679	int i, r;
 680	u16 status_reg = 0;
 681	int timeout = 500;
 682
 683	pr_debug("WriteInterrupt: %04x %04x\n", addr, data);
 684
 685	for (i = 0; i < 100; ++i) {
 686		r = usb_control_msg(usb->usbdev,
 687				usb_rcvctrlpipe(usb->usbdev, 0), 0x14,
 688				USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
 689				0, HPI_STATUS_ADDR, go->usb_buf,
 690				sizeof(status_reg), timeout);
 691		if (r < 0)
 692			break;
 693		status_reg = le16_to_cpu(*((__le16 *)go->usb_buf));
 694		if (!(status_reg & 0x0010))
 695			break;
 696		msleep(10);
 697	}
 698	if (r < 0)
 699		goto write_int_error;
 700	if (i == 100) {
 701		dev_err(go->dev, "device is hung, status reg = 0x%04x\n", status_reg);
 702		return -1;
 703	}
 704	r = usb_control_msg(usb->usbdev, usb_sndctrlpipe(usb->usbdev, 0), 0x12,
 705			USB_TYPE_VENDOR | USB_RECIP_DEVICE, data,
 706			INT_PARAM_ADDR, NULL, 0, timeout);
 707	if (r < 0)
 708		goto write_int_error;
 709	r = usb_control_msg(usb->usbdev, usb_sndctrlpipe(usb->usbdev, 0),
 710			0x12, USB_TYPE_VENDOR | USB_RECIP_DEVICE, addr,
 711			INT_INDEX_ADDR, NULL, 0, timeout);
 712	if (r < 0)
 713		goto write_int_error;
 714	return 0;
 715
 716write_int_error:
 717	dev_err(go->dev, "error in WriteInterrupt: %d\n", r);
 718	return r;
 719}
 720
 721static int go7007_usb_onboard_write_interrupt(struct go7007 *go,
 722						int addr, int data)
 723{
 724	struct go7007_usb *usb = go->hpi_context;
 725	int r;
 726	int timeout = 500;
 727
 728	pr_debug("WriteInterrupt: %04x %04x\n", addr, data);
 729
 730	go->usb_buf[0] = data & 0xff;
 731	go->usb_buf[1] = data >> 8;
 732	go->usb_buf[2] = addr & 0xff;
 733	go->usb_buf[3] = addr >> 8;
 734	go->usb_buf[4] = go->usb_buf[5] = go->usb_buf[6] = go->usb_buf[7] = 0;
 735	r = usb_control_msg(usb->usbdev, usb_sndctrlpipe(usb->usbdev, 2), 0x00,
 736			USB_TYPE_VENDOR | USB_RECIP_ENDPOINT, 0x55aa,
 737			0xf0f0, go->usb_buf, 8, timeout);
 738	if (r < 0) {
 739		dev_err(go->dev, "error in WriteInterrupt: %d\n", r);
 740		return r;
 741	}
 742	return 0;
 743}
 744
 745static void go7007_usb_readinterrupt_complete(struct urb *urb)
 746{
 747	struct go7007 *go = (struct go7007 *)urb->context;
 748	__le16 *regs = (__le16 *)urb->transfer_buffer;
 749	int status = urb->status;
 750
 751	if (status) {
 752		if (status != -ESHUTDOWN &&
 753				go->status != STATUS_SHUTDOWN) {
 754			dev_err(go->dev, "error in read interrupt: %d\n", urb->status);
 755		} else {
 756			wake_up(&go->interrupt_waitq);
 757			return;
 758		}
 759	} else if (urb->actual_length != urb->transfer_buffer_length) {
 760		dev_err(go->dev, "short read in interrupt pipe!\n");
 761	} else {
 762		go->interrupt_available = 1;
 763		go->interrupt_data = __le16_to_cpu(regs[0]);
 764		go->interrupt_value = __le16_to_cpu(regs[1]);
 765		pr_debug("ReadInterrupt: %04x %04x\n",
 766				go->interrupt_value, go->interrupt_data);
 767	}
 768
 769	wake_up(&go->interrupt_waitq);
 770}
 771
 772static int go7007_usb_read_interrupt(struct go7007 *go)
 773{
 774	struct go7007_usb *usb = go->hpi_context;
 775	int r;
 776
 777	r = usb_submit_urb(usb->intr_urb, GFP_KERNEL);
 778	if (r < 0) {
 779		dev_err(go->dev, "unable to submit interrupt urb: %d\n", r);
 780		return r;
 781	}
 782	return 0;
 783}
 784
 785static void go7007_usb_read_video_pipe_complete(struct urb *urb)
 786{
 787	struct go7007 *go = (struct go7007 *)urb->context;
 788	int r, status = urb->status;
 789
 790	if (!vb2_is_streaming(&go->vidq)) {
 791		wake_up_interruptible(&go->frame_waitq);
 792		return;
 793	}
 794	if (status) {
 795		dev_err(go->dev, "error in video pipe: %d\n", status);
 796		return;
 797	}
 798	if (urb->actual_length != urb->transfer_buffer_length) {
 799		dev_err(go->dev, "short read in video pipe!\n");
 800		return;
 801	}
 802	go7007_parse_video_stream(go, urb->transfer_buffer, urb->actual_length);
 803	r = usb_submit_urb(urb, GFP_ATOMIC);
 804	if (r < 0)
 805		dev_err(go->dev, "error in video pipe: %d\n", r);
 806}
 807
 808static void go7007_usb_read_audio_pipe_complete(struct urb *urb)
 809{
 810	struct go7007 *go = (struct go7007 *)urb->context;
 811	int r, status = urb->status;
 812
 813	if (!vb2_is_streaming(&go->vidq))
 814		return;
 815	if (status) {
 816		dev_err(go->dev, "error in audio pipe: %d\n",
 817			status);
 818		return;
 819	}
 820	if (urb->actual_length != urb->transfer_buffer_length) {
 821		dev_err(go->dev, "short read in audio pipe!\n");
 822		return;
 823	}
 824	if (go->audio_deliver != NULL)
 825		go->audio_deliver(go, urb->transfer_buffer, urb->actual_length);
 826	r = usb_submit_urb(urb, GFP_ATOMIC);
 827	if (r < 0)
 828		dev_err(go->dev, "error in audio pipe: %d\n", r);
 829}
 830
 831static int go7007_usb_stream_start(struct go7007 *go)
 832{
 833	struct go7007_usb *usb = go->hpi_context;
 834	int i, r;
 835
 836	for (i = 0; i < 8; ++i) {
 837		r = usb_submit_urb(usb->video_urbs[i], GFP_KERNEL);
 838		if (r < 0) {
 839			dev_err(go->dev, "error submitting video urb %d: %d\n", i, r);
 840			goto video_submit_failed;
 841		}
 842	}
 843	if (!go->audio_enabled)
 844		return 0;
 845
 846	for (i = 0; i < 8; ++i) {
 847		r = usb_submit_urb(usb->audio_urbs[i], GFP_KERNEL);
 848		if (r < 0) {
 849			dev_err(go->dev, "error submitting audio urb %d: %d\n", i, r);
 850			goto audio_submit_failed;
 851		}
 852	}
 853	return 0;
 854
 855audio_submit_failed:
 856	for (i = 0; i < 7; ++i)
 857		usb_kill_urb(usb->audio_urbs[i]);
 858video_submit_failed:
 859	for (i = 0; i < 8; ++i)
 860		usb_kill_urb(usb->video_urbs[i]);
 861	return -1;
 862}
 863
 864static int go7007_usb_stream_stop(struct go7007 *go)
 865{
 866	struct go7007_usb *usb = go->hpi_context;
 867	int i;
 868
 869	if (go->status == STATUS_SHUTDOWN)
 870		return 0;
 871	for (i = 0; i < 8; ++i)
 872		usb_kill_urb(usb->video_urbs[i]);
 873	if (go->audio_enabled)
 874		for (i = 0; i < 8; ++i)
 875			usb_kill_urb(usb->audio_urbs[i]);
 876	return 0;
 877}
 878
 879static int go7007_usb_send_firmware(struct go7007 *go, u8 *data, int len)
 880{
 881	struct go7007_usb *usb = go->hpi_context;
 882	int transferred, pipe;
 883	int timeout = 500;
 884
 885	pr_debug("DownloadBuffer sending %d bytes\n", len);
 886
 887	if (usb->board->flags & GO7007_USB_EZUSB)
 888		pipe = usb_sndbulkpipe(usb->usbdev, 2);
 889	else
 890		pipe = usb_sndbulkpipe(usb->usbdev, 3);
 891
 892	return usb_bulk_msg(usb->usbdev, pipe, data, len,
 893					&transferred, timeout);
 894}
 895
 896static void go7007_usb_release(struct go7007 *go)
 897{
 898	struct go7007_usb *usb = go->hpi_context;
 899	struct urb *vurb, *aurb;
 900	int i;
 901
 902	if (usb->intr_urb) {
 903		usb_kill_urb(usb->intr_urb);
 904		kfree(usb->intr_urb->transfer_buffer);
 905		usb_free_urb(usb->intr_urb);
 906	}
 907
 908	/* Free USB-related structs */
 909	for (i = 0; i < 8; ++i) {
 910		vurb = usb->video_urbs[i];
 911		if (vurb) {
 912			usb_kill_urb(vurb);
 913			kfree(vurb->transfer_buffer);
 914			usb_free_urb(vurb);
 915		}
 916		aurb = usb->audio_urbs[i];
 917		if (aurb) {
 918			usb_kill_urb(aurb);
 919			kfree(aurb->transfer_buffer);
 920			usb_free_urb(aurb);
 921		}
 922	}
 923
 924	kfree(go->hpi_context);
 925}
 926
 927static const struct go7007_hpi_ops go7007_usb_ezusb_hpi_ops = {
 928	.interface_reset	= go7007_usb_interface_reset,
 929	.write_interrupt	= go7007_usb_ezusb_write_interrupt,
 930	.read_interrupt		= go7007_usb_read_interrupt,
 931	.stream_start		= go7007_usb_stream_start,
 932	.stream_stop		= go7007_usb_stream_stop,
 933	.send_firmware		= go7007_usb_send_firmware,
 934	.release		= go7007_usb_release,
 935};
 936
 937static const struct go7007_hpi_ops go7007_usb_onboard_hpi_ops = {
 938	.interface_reset	= go7007_usb_interface_reset,
 939	.write_interrupt	= go7007_usb_onboard_write_interrupt,
 940	.read_interrupt		= go7007_usb_read_interrupt,
 941	.stream_start		= go7007_usb_stream_start,
 942	.stream_stop		= go7007_usb_stream_stop,
 943	.send_firmware		= go7007_usb_send_firmware,
 944	.release		= go7007_usb_release,
 945};
 946
 947/********************* Driver for EZ-USB I2C adapter *********************/
 948
 949static int go7007_usb_i2c_master_xfer(struct i2c_adapter *adapter,
 950					struct i2c_msg msgs[], int num)
 951{
 952	struct go7007 *go = i2c_get_adapdata(adapter);
 953	struct go7007_usb *usb = go->hpi_context;
 954	u8 *buf = go->usb_buf;
 955	int buf_len, i;
 956	int ret = -EIO;
 957
 958	if (go->status == STATUS_SHUTDOWN)
 959		return -ENODEV;
 960
 961	mutex_lock(&usb->i2c_lock);
 962
 963	for (i = 0; i < num; ++i) {
 964		/* The hardware command is "write some bytes then read some
 965		 * bytes", so we try to coalesce a write followed by a read
 966		 * into a single USB transaction */
 967		if (i + 1 < num && msgs[i].addr == msgs[i + 1].addr &&
 968				!(msgs[i].flags & I2C_M_RD) &&
 969				(msgs[i + 1].flags & I2C_M_RD)) {
 970#ifdef GO7007_I2C_DEBUG
 971			pr_debug("i2c write/read %d/%d bytes on %02x\n",
 972				msgs[i].len, msgs[i + 1].len, msgs[i].addr);
 973#endif
 974			buf[0] = 0x01;
 975			buf[1] = msgs[i].len + 1;
 976			buf[2] = msgs[i].addr << 1;
 977			memcpy(&buf[3], msgs[i].buf, msgs[i].len);
 978			buf_len = msgs[i].len + 3;
 979			buf[buf_len++] = msgs[++i].len;
 980		} else if (msgs[i].flags & I2C_M_RD) {
 981#ifdef GO7007_I2C_DEBUG
 982			pr_debug("i2c read %d bytes on %02x\n",
 983					msgs[i].len, msgs[i].addr);
 984#endif
 985			buf[0] = 0x01;
 986			buf[1] = 1;
 987			buf[2] = msgs[i].addr << 1;
 988			buf[3] = msgs[i].len;
 989			buf_len = 4;
 990		} else {
 991#ifdef GO7007_I2C_DEBUG
 992			pr_debug("i2c write %d bytes on %02x\n",
 993					msgs[i].len, msgs[i].addr);
 994#endif
 995			buf[0] = 0x00;
 996			buf[1] = msgs[i].len + 1;
 997			buf[2] = msgs[i].addr << 1;
 998			memcpy(&buf[3], msgs[i].buf, msgs[i].len);
 999			buf_len = msgs[i].len + 3;
1000			buf[buf_len++] = 0;
1001		}
1002		if (go7007_usb_vendor_request(go, 0x24, 0, 0,
1003						buf, buf_len, 0) < 0)
1004			goto i2c_done;
1005		if (msgs[i].flags & I2C_M_RD) {
1006			memset(buf, 0, msgs[i].len + 1);
1007			if (go7007_usb_vendor_request(go, 0x25, 0, 0, buf,
1008						msgs[i].len + 1, 1) < 0)
1009				goto i2c_done;
1010			memcpy(msgs[i].buf, buf + 1, msgs[i].len);
1011		}
1012	}
1013	ret = num;
1014
1015i2c_done:
1016	mutex_unlock(&usb->i2c_lock);
1017	return ret;
1018}
1019
1020static u32 go7007_usb_functionality(struct i2c_adapter *adapter)
1021{
1022	/* No errors are reported by the hardware, so we don't bother
1023	 * supporting quick writes to avoid confusing probing */
1024	return (I2C_FUNC_SMBUS_EMUL) & ~I2C_FUNC_SMBUS_QUICK;
1025}
1026
1027static const struct i2c_algorithm go7007_usb_algo = {
1028	.master_xfer	= go7007_usb_i2c_master_xfer,
1029	.functionality	= go7007_usb_functionality,
1030};
1031
1032static struct i2c_adapter go7007_usb_adap_templ = {
1033	.owner			= THIS_MODULE,
1034	.name			= "WIS GO7007SB EZ-USB",
1035	.algo			= &go7007_usb_algo,
1036};
1037
1038/********************* USB add/remove functions *********************/
1039
1040static int go7007_usb_probe(struct usb_interface *intf,
1041		const struct usb_device_id *id)
1042{
1043	struct go7007 *go;
1044	struct go7007_usb *usb;
1045	const struct go7007_usb_board *board;
1046	struct usb_device *usbdev = interface_to_usbdev(intf);
1047	struct usb_host_endpoint *ep;
1048	unsigned num_i2c_devs;
1049	char *name;
1050	int video_pipe, i, v_urb_len;
1051
1052	pr_debug("probing new GO7007 USB board\n");
1053
1054	switch (id->driver_info) {
1055	case GO7007_BOARDID_MATRIX_II:
1056		name = "WIS Matrix II or compatible";
1057		board = &board_matrix_ii;
1058		break;
1059	case GO7007_BOARDID_MATRIX_RELOAD:
1060		name = "WIS Matrix Reloaded or compatible";
1061		board = &board_matrix_reload;
1062		break;
1063	case GO7007_BOARDID_MATRIX_REV:
1064		name = "WIS Matrix Revolution or compatible";
1065		board = &board_matrix_revolution;
1066		break;
1067	case GO7007_BOARDID_STAR_TREK:
1068		name = "WIS Star Trek or compatible";
1069		board = &board_star_trek;
1070		break;
1071	case GO7007_BOARDID_XMEN:
1072		name = "WIS XMen or compatible";
1073		board = &board_xmen;
1074		break;
1075	case GO7007_BOARDID_XMEN_II:
1076		name = "WIS XMen II or compatible";
1077		board = &board_xmen;
1078		break;
1079	case GO7007_BOARDID_XMEN_III:
1080		name = "WIS XMen III or compatible";
1081		board = &board_xmen;
1082		break;
1083	case GO7007_BOARDID_PX_M402U:
1084		name = "Plextor PX-M402U";
1085		board = &board_matrix_ii;
1086		break;
1087	case GO7007_BOARDID_PX_TV402U:
1088		name = "Plextor PX-TV402U (unknown tuner)";
1089		board = &board_px_tv402u;
1090		break;
1091	case GO7007_BOARDID_LIFEVIEW_LR192:
1092		dev_err(&intf->dev, "The Lifeview TV Walker Ultra is not supported. Sorry!\n");
1093		return -ENODEV;
1094#if 0
1095		name = "Lifeview TV Walker Ultra";
1096		board = &board_lifeview_lr192;
1097#endif
1098		break;
1099	case GO7007_BOARDID_SENSORAY_2250:
1100		dev_info(&intf->dev, "Sensoray 2250 found\n");
1101		name = "Sensoray 2250/2251";
1102		board = &board_sensoray_2250;
1103		break;
1104	case GO7007_BOARDID_ADS_USBAV_709:
1105		name = "ADS Tech DVD Xpress DX2";
1106		board = &board_ads_usbav_709;
1107		break;
1108	default:
1109		dev_err(&intf->dev, "unknown board ID %d!\n",
1110				(unsigned int)id->driver_info);
1111		return -ENODEV;
1112	}
1113
1114	go = go7007_alloc(&board->main_info, &intf->dev);
1115	if (go == NULL)
1116		return -ENOMEM;
1117
1118	usb = kzalloc(sizeof(struct go7007_usb), GFP_KERNEL);
1119	if (usb == NULL) {
1120		kfree(go);
1121		return -ENOMEM;
1122	}
1123
1124	usb->board = board;
1125	usb->usbdev = usbdev;
1126	usb_make_path(usbdev, go->bus_info, sizeof(go->bus_info));
1127	go->board_id = id->driver_info;
1128	strscpy(go->name, name, sizeof(go->name));
1129	if (board->flags & GO7007_USB_EZUSB)
1130		go->hpi_ops = &go7007_usb_ezusb_hpi_ops;
1131	else
1132		go->hpi_ops = &go7007_usb_onboard_hpi_ops;
1133	go->hpi_context = usb;
1134
1135	ep = usb->usbdev->ep_in[4];
1136	if (!ep)
1137		goto allocfail;
1138
1139	/* Allocate the URB and buffer for receiving incoming interrupts */
1140	usb->intr_urb = usb_alloc_urb(0, GFP_KERNEL);
1141	if (usb->intr_urb == NULL)
1142		goto allocfail;
1143	usb->intr_urb->transfer_buffer = kmalloc_array(2, sizeof(u16),
1144						       GFP_KERNEL);
1145	if (usb->intr_urb->transfer_buffer == NULL)
1146		goto allocfail;
1147
1148	if (usb_endpoint_type(&ep->desc) == USB_ENDPOINT_XFER_BULK)
1149		usb_fill_bulk_urb(usb->intr_urb, usb->usbdev,
1150			usb_rcvbulkpipe(usb->usbdev, 4),
1151			usb->intr_urb->transfer_buffer, 2*sizeof(u16),
1152			go7007_usb_readinterrupt_complete, go);
1153	else
1154		usb_fill_int_urb(usb->intr_urb, usb->usbdev,
1155			usb_rcvintpipe(usb->usbdev, 4),
1156			usb->intr_urb->transfer_buffer, 2*sizeof(u16),
1157			go7007_usb_readinterrupt_complete, go, 8);
1158	usb_set_intfdata(intf, &go->v4l2_dev);
1159
1160	/* Boot the GO7007 */
1161	if (go7007_boot_encoder(go, go->board_info->flags &
1162					GO7007_BOARD_USE_ONBOARD_I2C) < 0)
1163		goto allocfail;
1164
1165	/* Register the EZ-USB I2C adapter, if we're using it */
1166	if (board->flags & GO7007_USB_EZUSB_I2C) {
1167		memcpy(&go->i2c_adapter, &go7007_usb_adap_templ,
1168				sizeof(go7007_usb_adap_templ));
1169		mutex_init(&usb->i2c_lock);
1170		go->i2c_adapter.dev.parent = go->dev;
1171		i2c_set_adapdata(&go->i2c_adapter, go);
1172		if (i2c_add_adapter(&go->i2c_adapter) < 0) {
1173			dev_err(go->dev, "error: i2c_add_adapter failed\n");
1174			goto allocfail;
1175		}
1176		go->i2c_adapter_online = 1;
1177	}
1178
1179	/* Pelco and Adlink reused the XMen and XMen-III vendor and product
1180	 * IDs for their own incompatible designs.  We can detect XMen boards
1181	 * by probing the sensor, but there is no way to probe the sensors on
1182	 * the Pelco and Adlink designs so we default to the Adlink.  If it
1183	 * is actually a Pelco, the user must set the assume_endura module
1184	 * parameter. */
1185	if ((go->board_id == GO7007_BOARDID_XMEN ||
1186				go->board_id == GO7007_BOARDID_XMEN_III) &&
1187			go->i2c_adapter_online) {
1188		union i2c_smbus_data data;
1189
1190		/* Check to see if register 0x0A is 0x76 */
1191		i2c_smbus_xfer(&go->i2c_adapter, 0x21, I2C_CLIENT_SCCB,
1192			I2C_SMBUS_READ, 0x0A, I2C_SMBUS_BYTE_DATA, &data);
1193		if (data.byte != 0x76) {
1194			if (assume_endura) {
1195				go->board_id = GO7007_BOARDID_ENDURA;
1196				usb->board = board = &board_endura;
1197				go->board_info = &board->main_info;
1198				strscpy(go->name, "Pelco Endura",
1199					sizeof(go->name));
1200			} else {
1201				u16 channel;
1202
1203				/* read channel number from GPIO[1:0] */
1204				if (go7007_read_addr(go, 0x3c81, &channel))
1205					goto allocfail;
1206
1207				channel &= 0x3;
1208				go->board_id = GO7007_BOARDID_ADLINK_MPG24;
1209				usb->board = board = &board_adlink_mpg24;
1210				go->board_info = &board->main_info;
1211				go->channel_number = channel;
1212				snprintf(go->name, sizeof(go->name),
1213					"Adlink PCI-MPG24, channel #%d",
1214					channel);
1215			}
1216			go7007_update_board(go);
1217		}
1218	}
1219
1220	num_i2c_devs = go->board_info->num_i2c_devs;
1221
1222	/* Probe the tuner model on the TV402U */
1223	if (go->board_id == GO7007_BOARDID_PX_TV402U) {
1224		/* Board strapping indicates tuner model */
1225		if (go7007_usb_vendor_request(go, 0x41, 0, 0, go->usb_buf, 3,
1226					1) < 0) {
1227			dev_err(go->dev, "GPIO read failed!\n");
1228			goto allocfail;
1229		}
1230		switch (go->usb_buf[0] >> 6) {
1231		case 1:
1232			go->tuner_type = TUNER_SONY_BTF_PG472Z;
1233			go->std = V4L2_STD_PAL;
1234			strscpy(go->name, "Plextor PX-TV402U-EU",
1235				sizeof(go->name));
1236			break;
1237		case 2:
1238			go->tuner_type = TUNER_SONY_BTF_PK467Z;
1239			go->std = V4L2_STD_NTSC_M_JP;
1240			num_i2c_devs -= 2;
1241			strscpy(go->name, "Plextor PX-TV402U-JP",
1242				sizeof(go->name));
1243			break;
1244		case 3:
1245			go->tuner_type = TUNER_SONY_BTF_PB463Z;
1246			num_i2c_devs -= 2;
1247			strscpy(go->name, "Plextor PX-TV402U-NA",
1248				sizeof(go->name));
1249			break;
1250		default:
1251			pr_debug("unable to detect tuner type!\n");
1252			break;
1253		}
1254		/* Configure tuner mode selection inputs connected
1255		 * to the EZ-USB GPIO output pins */
1256		if (go7007_usb_vendor_request(go, 0x40, 0x7f02, 0,
1257					NULL, 0, 0) < 0) {
1258			dev_err(go->dev, "GPIO write failed!\n");
1259			goto allocfail;
1260		}
1261	}
1262
1263	/* Print a nasty message if the user attempts to use a USB2.0 device in
1264	 * a USB1.1 port.  There will be silent corruption of the stream. */
1265	if ((board->flags & GO7007_USB_EZUSB) &&
1266			usbdev->speed != USB_SPEED_HIGH)
1267		dev_err(go->dev, "*** WARNING ***  This device must be connected to a USB 2.0 port! Attempting to capture video through a USB 1.1 port will result in stream corruption, even at low bitrates!\n");
1268
1269	/* Allocate the URBs and buffers for receiving the video stream */
1270	if (board->flags & GO7007_USB_EZUSB) {
1271		if (!usb->usbdev->ep_in[6])
1272			goto allocfail;
1273		v_urb_len = 1024;
1274		video_pipe = usb_rcvbulkpipe(usb->usbdev, 6);
1275	} else {
1276		if (!usb->usbdev->ep_in[1])
1277			goto allocfail;
1278		v_urb_len = 512;
1279		video_pipe = usb_rcvbulkpipe(usb->usbdev, 1);
1280	}
1281	for (i = 0; i < 8; ++i) {
1282		usb->video_urbs[i] = usb_alloc_urb(0, GFP_KERNEL);
1283		if (usb->video_urbs[i] == NULL)
1284			goto allocfail;
1285		usb->video_urbs[i]->transfer_buffer =
1286						kmalloc(v_urb_len, GFP_KERNEL);
1287		if (usb->video_urbs[i]->transfer_buffer == NULL)
1288			goto allocfail;
1289		usb_fill_bulk_urb(usb->video_urbs[i], usb->usbdev, video_pipe,
1290				usb->video_urbs[i]->transfer_buffer, v_urb_len,
1291				go7007_usb_read_video_pipe_complete, go);
1292	}
1293
1294	/* Allocate the URBs and buffers for receiving the audio stream */
1295	if ((board->flags & GO7007_USB_EZUSB) &&
1296	    (board->main_info.flags & GO7007_BOARD_HAS_AUDIO)) {
1297		if (!usb->usbdev->ep_in[8])
1298			goto allocfail;
1299		for (i = 0; i < 8; ++i) {
1300			usb->audio_urbs[i] = usb_alloc_urb(0, GFP_KERNEL);
1301			if (usb->audio_urbs[i] == NULL)
1302				goto allocfail;
1303			usb->audio_urbs[i]->transfer_buffer = kmalloc(4096,
1304								GFP_KERNEL);
1305			if (usb->audio_urbs[i]->transfer_buffer == NULL)
1306				goto allocfail;
1307			usb_fill_bulk_urb(usb->audio_urbs[i], usb->usbdev,
1308				usb_rcvbulkpipe(usb->usbdev, 8),
1309				usb->audio_urbs[i]->transfer_buffer, 4096,
1310				go7007_usb_read_audio_pipe_complete, go);
1311		}
1312	}
1313
1314	/* Do any final GO7007 initialization, then register the
1315	 * V4L2 and ALSA interfaces */
1316	if (go7007_register_encoder(go, num_i2c_devs) < 0)
1317		goto allocfail;
1318
1319	go->status = STATUS_ONLINE;
1320	return 0;
1321
1322allocfail:
1323	go7007_usb_release(go);
1324	kfree(go);
1325	return -ENOMEM;
1326}
1327
1328static void go7007_usb_disconnect(struct usb_interface *intf)
1329{
1330	struct go7007 *go = to_go7007(usb_get_intfdata(intf));
1331
1332	mutex_lock(&go->queue_lock);
1333	mutex_lock(&go->serialize_lock);
1334
1335	if (go->audio_enabled)
1336		go7007_snd_remove(go);
1337
1338	go->status = STATUS_SHUTDOWN;
1339	v4l2_device_disconnect(&go->v4l2_dev);
1340	video_unregister_device(&go->vdev);
1341	mutex_unlock(&go->serialize_lock);
1342	mutex_unlock(&go->queue_lock);
1343
1344	v4l2_device_put(&go->v4l2_dev);
1345}
1346
1347static struct usb_driver go7007_usb_driver = {
1348	.name		= "go7007",
1349	.probe		= go7007_usb_probe,
1350	.disconnect	= go7007_usb_disconnect,
1351	.id_table	= go7007_usb_id_table,
1352};
1353
1354module_usb_driver(go7007_usb_driver);
1355MODULE_DESCRIPTION("WIS GO7007 USB support");
1356MODULE_LICENSE("GPL v2");
~/ Read-only file preview.