brintos

brintos / linux-shallow public Read only

0
0
Text · 34.5 KiB · 334cdde Raw
1357 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (C) 2005-2006 Micronas USA Inc.4 */5 6#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt7 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	0xFFF432#define	INT_PARAM_ADDR	0xFFF633#define	INT_INDEX_ADDR	0xFFF834 35/*36 * Pipes on EZ-USB interface:37 *	0 snd - Control38 *	0 rcv - Control39 *	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 0334static 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#endif361 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	else890		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 some965		 * bytes", so we try to coalesce a write followed by a read966		 * 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_DEBUG971			pr_debug("i2c write/read %d/%d bytes on %02x\n",972				msgs[i].len, msgs[i + 1].len, msgs[i].addr);973#endif974			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_DEBUG982			pr_debug("i2c read %d bytes on %02x\n",983					msgs[i].len, msgs[i].addr);984#endif985			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_DEBUG992			pr_debug("i2c write %d bytes on %02x\n",993					msgs[i].len, msgs[i].addr);994#endif995			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 bother1023	 * 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 01095		name = "Lifeview TV Walker Ultra";1096		board = &board_lifeview_lr192;1097#endif1098		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	else1132		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	else1154		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 product1180	 * IDs for their own incompatible designs.  We can detect XMen boards1181	 * by probing the sensor, but there is no way to probe the sensors on1182	 * the Pelco and Adlink designs so we default to the Adlink.  If it1183	 * is actually a Pelco, the user must set the assume_endura module1184	 * 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 connected1255		 * 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 in1264	 * 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 the1315	 * 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");1357