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