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_twTW2804",
 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_board",
 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
 447static struct usb_device_id go7007_usb_id_table[] = {
 448        {
 449                .match_flags    = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION |
 450                                        USB_DEVICE_ID_MATCH_INT_INFO,
 451                .idVendor       = 0x0eb1,  /* Vendor ID of WIS Technologies */
 452                .idProduct      = 0x7007,  /* Product ID of GO7007SB chip */
 453                .bcdDevice_lo   = 0x200,   /* Revision number of XMen */
 454                .bcdDevice_hi   = 0x200,
 455                .bInterfaceClass        = 255,
 456                .bInterfaceSubClass     = 0,
 457                .bInterfaceProtocol     = 255,
 458                .driver_info    = (kernel_ulong_t)GO7007_BOARDID_XMEN,
 459        },
 460        {
 461                .match_flags    = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
 462                .idVendor       = 0x0eb1,  /* Vendor ID of WIS Technologies */
 463                .idProduct      = 0x7007,  /* Product ID of GO7007SB chip */
 464                .bcdDevice_lo   = 0x202,   /* Revision number of Matrix II */
 465                .bcdDevice_hi   = 0x202,
 466                .driver_info    = (kernel_ulong_t)GO7007_BOARDID_MATRIX_II,
 467        },
 468        {
 469                .match_flags    = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
 470                .idVendor       = 0x0eb1,  /* Vendor ID of WIS Technologies */
 471                .idProduct      = 0x7007,  /* Product ID of GO7007SB chip */
 472                .bcdDevice_lo   = 0x204,   /* Revision number of Matrix */
 473                .bcdDevice_hi   = 0x204,   /*     Reloaded */
 474                .driver_info    = (kernel_ulong_t)GO7007_BOARDID_MATRIX_RELOAD,
 475        },
 476        {
 477                .match_flags    = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION |
 478                                        USB_DEVICE_ID_MATCH_INT_INFO,
 479                .idVendor       = 0x0eb1,  /* Vendor ID of WIS Technologies */
 480                .idProduct      = 0x7007,  /* Product ID of GO7007SB chip */
 481                .bcdDevice_lo   = 0x205,   /* Revision number of XMen-II */
 482                .bcdDevice_hi   = 0x205,
 483                .bInterfaceClass        = 255,
 484                .bInterfaceSubClass     = 0,
 485                .bInterfaceProtocol     = 255,
 486                .driver_info    = (kernel_ulong_t)GO7007_BOARDID_XMEN_II,
 487        },
 488        {
 489                .match_flags    = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
 490                .idVendor       = 0x0eb1,  /* Vendor ID of WIS Technologies */
 491                .idProduct      = 0x7007,  /* Product ID of GO7007SB chip */
 492                .bcdDevice_lo   = 0x208,   /* Revision number of Star Trek */
 493                .bcdDevice_hi   = 0x208,
 494                .driver_info    = (kernel_ulong_t)GO7007_BOARDID_STAR_TREK,
 495        },
 496        {
 497                .match_flags    = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION |
 498                                        USB_DEVICE_ID_MATCH_INT_INFO,
 499                .idVendor       = 0x0eb1,  /* Vendor ID of WIS Technologies */
 500                .idProduct      = 0x7007,  /* Product ID of GO7007SB chip */
 501                .bcdDevice_lo   = 0x209,   /* Revision number of XMen-III */
 502                .bcdDevice_hi   = 0x209,
 503                .bInterfaceClass        = 255,
 504                .bInterfaceSubClass     = 0,
 505                .bInterfaceProtocol     = 255,
 506                .driver_info    = (kernel_ulong_t)GO7007_BOARDID_XMEN_III,
 507        },
 508        {
 509                .match_flags    = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
 510                .idVendor       = 0x0eb1,  /* Vendor ID of WIS Technologies */
 511                .idProduct      = 0x7007,  /* Product ID of GO7007SB chip */
 512                .bcdDevice_lo   = 0x210,   /* Revision number of Matrix */
 513                .bcdDevice_hi   = 0x210,   /*     Revolution */
 514                .driver_info    = (kernel_ulong_t)GO7007_BOARDID_MATRIX_REV,
 515        },
 516        {
 517                .match_flags    = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
 518                .idVendor       = 0x093b,  /* Vendor ID of Plextor */
 519                .idProduct      = 0xa102,  /* Product ID of M402U */
 520                .bcdDevice_lo   = 0x1,     /* revision number of Blueberry */
 521                .bcdDevice_hi   = 0x1,
 522                .driver_info    = (kernel_ulong_t)GO7007_BOARDID_PX_M402U,
 523        },
 524        {
 525                .match_flags    = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
 526                .idVendor       = 0x093b,  /* Vendor ID of Plextor */
 527                .idProduct      = 0xa104,  /* Product ID of TV402U */
 528                .bcdDevice_lo   = 0x1,
 529                .bcdDevice_hi   = 0x1,
 530                .driver_info    = (kernel_ulong_t)GO7007_BOARDID_PX_TV402U_ANY,
 531        },
 532        {
 533                .match_flags    = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
 534                .idVendor       = 0x10fd,  /* Vendor ID of Anubis Electronics */
 535                .idProduct      = 0xde00,  /* Product ID of Lifeview LR192 */
 536                .bcdDevice_lo   = 0x1,
 537                .bcdDevice_hi   = 0x1,
 538                .driver_info    = (kernel_ulong_t)GO7007_BOARDID_LIFEVIEW_LR192,
 539        },
 540        {
 541                .match_flags    = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
 542                .idVendor       = 0x1943,  /* Vendor ID Sensoray */
 543                .idProduct      = 0x2250,  /* Product ID of 2250/2251 */
 544                .bcdDevice_lo   = 0x1,
 545                .bcdDevice_hi   = 0x1,
 546                .driver_info    = (kernel_ulong_t)GO7007_BOARDID_SENSORAY_2250,
 547        },
 548        { }                                     /* Terminating entry */
 549};
 550
 551MODULE_DEVICE_TABLE(usb, go7007_usb_id_table);
 552
 553/********************* Driver for EZ-USB HPI interface *********************/
 554
 555static int go7007_usb_vendor_request(struct go7007 *go, int request,
 556                int value, int index, void *transfer_buffer, int length, int in)
 557{
 558        struct go7007_usb *usb = go->hpi_context;
 559        int timeout = 5000;
 560
 561        if (in) {
 562                return usb_control_msg(usb->usbdev,
 563                                usb_rcvctrlpipe(usb->usbdev, 0), request,
 564                                USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
 565                                value, index, transfer_buffer, length, timeout);
 566        } else {
 567                return usb_control_msg(usb->usbdev,
 568                                usb_sndctrlpipe(usb->usbdev, 0), request,
 569                                USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 570                                value, index, transfer_buffer, length, timeout);
 571        }
 572}
 573
 574static int go7007_usb_interface_reset(struct go7007 *go)
 575{
 576        struct go7007_usb *usb = go->hpi_context;
 577        u16 intr_val, intr_data;
 578
 579        /* Reset encoder */
 580        if (go7007_write_interrupt(go, 0x0001, 0x0001) < 0)
 581                return -1;
 582        msleep(100);
 583
 584        if (usb->board->flags & GO7007_USB_EZUSB) {
 585                /* Reset buffer in EZ-USB */
 586#ifdef GO7007_USB_DEBUG
 587                printk(KERN_DEBUG "go7007-usb: resetting EZ-USB buffers\n");
 588#endif
 589                if (go7007_usb_vendor_request(go, 0x10, 0, 0, NULL, 0, 0) < 0 ||
 590                    go7007_usb_vendor_request(go, 0x10, 0, 0, NULL, 0, 0) < 0)
 591                        return -1;
 592
 593                /* Reset encoder again */
 594                if (go7007_write_interrupt(go, 0x0001, 0x0001) < 0)
 595                        return -1;
 596                msleep(100);
 597        }
 598
 599        /* Wait for an interrupt to indicate successful hardware reset */
 600        if (go7007_read_interrupt(go, &intr_val, &intr_data) < 0 ||
 601                        (intr_val & ~0x1) != 0x55aa) {
 602                printk(KERN_ERR
 603                        "go7007-usb: unable to reset the USB interface\n");
 604                return -1;
 605        }
 606        return 0;
 607}
 608
 609static int go7007_usb_ezusb_write_interrupt(struct go7007 *go,
 610                                                int addr, int data)
 611{
 612        struct go7007_usb *usb = go->hpi_context;
 613        int i, r;
 614        u16 status_reg;
 615        int timeout = 500;
 616
 617#ifdef GO7007_USB_DEBUG
 618        printk(KERN_DEBUG
 619                "go7007-usb: WriteInterrupt: %04x %04x\n", addr, data);
 620#endif
 621
 622        for (i = 0; i < 100; ++i) {
 623                r = usb_control_msg(usb->usbdev,
 624                                usb_rcvctrlpipe(usb->usbdev, 0), 0x14,
 625                                USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
 626                                0, HPI_STATUS_ADDR, &status_reg,
 627                                sizeof(status_reg), timeout);
 628                if (r < 0)
 629                        goto write_int_error;
 630                __le16_to_cpus(&status_reg);
 631                if (!(status_reg & 0x0010))
 632                        break;
 633                msleep(10);
 634        }
 635        if (i == 100) {
 636                printk(KERN_ERR
 637                        "go7007-usb: device is hung, status reg = 0x%04x\n",
 638                        status_reg);
 639                return -1;
 640        }
 641        r = usb_control_msg(usb->usbdev, usb_sndctrlpipe(usb->usbdev, 0), 0x12,
 642                        USB_TYPE_VENDOR | USB_RECIP_DEVICE, data,
 643                        INT_PARAM_ADDR, NULL, 0, timeout);
 644        if (r < 0)
 645                goto write_int_error;
 646        r = usb_control_msg(usb->usbdev, usb_sndctrlpipe(usb->usbdev, 0),
 647                        0x12, USB_TYPE_VENDOR | USB_RECIP_DEVICE, addr,
 648                        INT_INDEX_ADDR, NULL, 0, timeout);
 649        if (r < 0)
 650                goto write_int_error;
 651        return 0;
 652
 653write_int_error:
 654        printk(KERN_ERR "go7007-usb: error in WriteInterrupt: %d\n", r);
 655        return r;
 656}
 657
 658static int go7007_usb_onboard_write_interrupt(struct go7007 *go,
 659                                                int addr, int data)
 660{
 661        struct go7007_usb *usb = go->hpi_context;
 662        u8 *tbuf;
 663        int r;
 664        int timeout = 500;
 665
 666#ifdef GO7007_USB_DEBUG
 667        printk(KERN_DEBUG
 668                "go7007-usb: WriteInterrupt: %04x %04x\n", addr, data);
 669#endif
 670
 671        tbuf = kmalloc(8, GFP_KERNEL);
 672        if (tbuf == NULL)
 673                return -ENOMEM;
 674        memset(tbuf, 0, 8);
 675        tbuf[0] = data & 0xff;
 676        tbuf[1] = data >> 8;
 677        tbuf[2] = addr & 0xff;
 678        tbuf[3] = addr >> 8;
 679        r = usb_control_msg(usb->usbdev, usb_sndctrlpipe(usb->usbdev, 2), 0x00,
 680                        USB_TYPE_VENDOR | USB_RECIP_ENDPOINT, 0x55aa,
 681                        0xf0f0, tbuf, 8, timeout);
 682        kfree(tbuf);
 683        if (r < 0) {
 684                printk(KERN_ERR "go7007-usb: error in WriteInterrupt: %d\n", r);
 685                return r;
 686        }
 687        return 0;
 688}
 689
 690static void go7007_usb_readinterrupt_complete(struct urb *urb)
 691{
 692        struct go7007 *go = (struct go7007 *)urb->context;
 693        u16 *regs = (u16 *)urb->transfer_buffer;
 694        int status = urb->status;
 695
 696        if (status) {
 697                if (status != -ESHUTDOWN &&
 698                                go->status != STATUS_SHUTDOWN) {
 699                        printk(KERN_ERR
 700                                "go7007-usb: error in read interrupt: %d\n",
 701                                urb->status);
 702                } else {
 703                        wake_up(&go->interrupt_waitq);
 704                        return;
 705                }
 706        } else if (urb->actual_length != urb->transfer_buffer_length) {
 707                printk(KERN_ERR "go7007-usb: short read in interrupt pipe!\n");
 708        } else {
 709                go->interrupt_available = 1;
 710                go->interrupt_data = __le16_to_cpu(regs[0]);
 711                go->interrupt_value = __le16_to_cpu(regs[1]);
 712#ifdef GO7007_USB_DEBUG
 713                printk(KERN_DEBUG "go7007-usb: ReadInterrupt: %04x %04x\n",
 714                                go->interrupt_value, go->interrupt_data);
 715#endif
 716        }
 717
 718        wake_up(&go->interrupt_waitq);
 719}
 720
 721static int go7007_usb_read_interrupt(struct go7007 *go)
 722{
 723        struct go7007_usb *usb = go->hpi_context;
 724        int r;
 725
 726        r = usb_submit_urb(usb->intr_urb, GFP_KERNEL);
 727        if (r < 0) {
 728                printk(KERN_ERR
 729                        "go7007-usb: unable to submit interrupt urb: %d\n", r);
 730                return r;
 731        }
 732        return 0;
 733}
 734
 735static void go7007_usb_read_video_pipe_complete(struct urb *urb)
 736{
 737        struct go7007 *go = (struct go7007 *)urb->context;
 738        int r, status = urb->status;
 739
 740        if (!go->streaming) {
 741                wake_up_interruptible(&go->frame_waitq);
 742                return;
 743        }
 744        if (status) {
 745                printk(KERN_ERR "go7007-usb: error in video pipe: %d\n",
 746                        status);
 747                return;
 748        }
 749        if (urb->actual_length != urb->transfer_buffer_length) {
 750                printk(KERN_ERR "go7007-usb: short read in video pipe!\n");
 751                return;
 752        }
 753        go7007_parse_video_stream(go, urb->transfer_buffer, urb->actual_length);
 754        r = usb_submit_urb(urb, GFP_ATOMIC);
 755        if (r < 0)
 756                printk(KERN_ERR "go7007-usb: error in video pipe: %d\n", r);
 757}
 758
 759static void go7007_usb_read_audio_pipe_complete(struct urb *urb)
 760{
 761        struct go7007 *go = (struct go7007 *)urb->context;
 762        int r, status = urb->status;
 763
 764        if (!go->streaming)
 765                return;
 766        if (status) {
 767                printk(KERN_ERR "go7007-usb: error in audio pipe: %d\n",
 768                        status);
 769                return;
 770        }
 771        if (urb->actual_length != urb->transfer_buffer_length) {
 772                printk(KERN_ERR "go7007-usb: short read in audio pipe!\n");
 773                return;
 774        }
 775        if (go->audio_deliver != NULL)
 776                go->audio_deliver(go, urb->transfer_buffer, urb->actual_length);
 777        r = usb_submit_urb(urb, GFP_ATOMIC);
 778        if (r < 0)
 779                printk(KERN_ERR "go7007-usb: error in audio pipe: %d\n", r);
 780}
 781
 782static int go7007_usb_stream_start(struct go7007 *go)
 783{
 784        struct go7007_usb *usb = go->hpi_context;
 785        int i, r;
 786
 787        for (i = 0; i < 8; ++i) {
 788                r = usb_submit_urb(usb->video_urbs[i], GFP_KERNEL);
 789                if (r < 0) {
 790                        printk(KERN_ERR "go7007-usb: error submitting video "
 791                                        "urb %d: %d\n", i, r);
 792                        goto video_submit_failed;
 793                }
 794        }
 795        if (!go->audio_enabled)
 796                return 0;
 797
 798        for (i = 0; i < 8; ++i) {
 799                r = usb_submit_urb(usb->audio_urbs[i], GFP_KERNEL);
 800                if (r < 0) {
 801                        printk(KERN_ERR "go7007-usb: error submitting audio "
 802                                        "urb %d: %d\n", i, r);
 803                        goto audio_submit_failed;
 804                }
 805        }
 806        return 0;
 807
 808audio_submit_failed:
 809        for (i = 0; i < 7; ++i)
 810                usb_kill_urb(usb->audio_urbs[i]);
 811video_submit_failed:
 812        for (i = 0; i < 8; ++i)
 813                usb_kill_urb(usb->video_urbs[i]);
 814        return -1;
 815}
 816
 817static int go7007_usb_stream_stop(struct go7007 *go)
 818{
 819        struct go7007_usb *usb = go->hpi_context;
 820        int i;
 821
 822        if (go->status == STATUS_SHUTDOWN)
 823                return 0;
 824        for (i = 0; i < 8; ++i)
 825                usb_kill_urb(usb->video_urbs[i]);
 826        if (go->audio_enabled)
 827                for (i = 0; i < 8; ++i)
 828                        usb_kill_urb(usb->audio_urbs[i]);
 829        return 0;
 830}
 831
 832static int go7007_usb_send_firmware(struct go7007 *go, u8 *data, int len)
 833{
 834        struct go7007_usb *usb = go->hpi_context;
 835        int transferred, pipe;
 836        int timeout = 500;
 837
 838#ifdef GO7007_USB_DEBUG
 839        printk(KERN_DEBUG "go7007-usb: DownloadBuffer sending %d bytes\n", len);
 840#endif
 841
 842        if (usb->board->flags & GO7007_USB_EZUSB)
 843                pipe = usb_sndbulkpipe(usb->usbdev, 2);
 844        else
 845                pipe = usb_sndbulkpipe(usb->usbdev, 3);
 846
 847        return usb_bulk_msg(usb->usbdev, pipe, data, len,
 848                                        &transferred, timeout);
 849}
 850
 851static struct go7007_hpi_ops go7007_usb_ezusb_hpi_ops = {
 852        .interface_reset        = go7007_usb_interface_reset,
 853        .write_interrupt        = go7007_usb_ezusb_write_interrupt,
 854        .read_interrupt         = go7007_usb_read_interrupt,
 855        .stream_start           = go7007_usb_stream_start,
 856        .stream_stop            = go7007_usb_stream_stop,
 857        .send_firmware          = go7007_usb_send_firmware,
 858};
 859
 860static struct go7007_hpi_ops go7007_usb_onboard_hpi_ops = {
 861        .interface_reset        = go7007_usb_interface_reset,
 862        .write_interrupt        = go7007_usb_onboard_write_interrupt,
 863        .read_interrupt         = go7007_usb_read_interrupt,
 864        .stream_start           = go7007_usb_stream_start,
 865        .stream_stop            = go7007_usb_stream_stop,
 866        .send_firmware          = go7007_usb_send_firmware,
 867};
 868
 869/********************* Driver for EZ-USB I2C adapter *********************/
 870
 871static int go7007_usb_i2c_master_xfer(struct i2c_adapter *adapter,
 872                                        struct i2c_msg msgs[], int num)
 873{
 874        struct go7007 *go = i2c_get_adapdata(adapter);
 875        struct go7007_usb *usb = go->hpi_context;
 876        u8 buf[16];
 877        int buf_len, i;
 878        int ret = -1;
 879
 880        if (go->status == STATUS_SHUTDOWN)
 881                return -1;
 882
 883        mutex_lock(&usb->i2c_lock);
 884
 885        for (i = 0; i < num; ++i) {
 886                /* The hardware command is "write some bytes then read some
 887                 * bytes", so we try to coalesce a write followed by a read
 888                 * into a single USB transaction */
 889                if (i + 1 < num && msgs[i].addr == msgs[i + 1].addr &&
 890                                !(msgs[i].flags & I2C_M_RD) &&
 891                                (msgs[i + 1].flags & I2C_M_RD)) {
 892#ifdef GO7007_I2C_DEBUG
 893                        printk(KERN_DEBUG "go7007-usb: i2c write/read %d/%d "
 894                                        "bytes on %02x\n", msgs[i].len,
 895                                        msgs[i + 1].len, msgs[i].addr);
 896#endif
 897                        buf[0] = 0x01;
 898                        buf[1] = msgs[i].len + 1;
 899                        buf[2] = msgs[i].addr << 1;
 900                        memcpy(&buf[3], msgs[i].buf, msgs[i].len);
 901                        buf_len = msgs[i].len + 3;
 902                        buf[buf_len++] = msgs[++i].len;
 903                } else if (msgs[i].flags & I2C_M_RD) {
 904#ifdef GO7007_I2C_DEBUG
 905                        printk(KERN_DEBUG "go7007-usb: i2c read %d "
 906                                        "bytes on %02x\n", msgs[i].len,
 907                                        msgs[i].addr);
 908#endif
 909                        buf[0] = 0x01;
 910                        buf[1] = 1;
 911                        buf[2] = msgs[i].addr << 1;
 912                        buf[3] = msgs[i].len;
 913                        buf_len = 4;
 914                } else {
 915#ifdef GO7007_I2C_DEBUG
 916                        printk(KERN_DEBUG "go7007-usb: i2c write %d "
 917                                        "bytes on %02x\n", msgs[i].len,
 918                                        msgs[i].addr);
 919#endif
 920                        buf[0] = 0x00;
 921                        buf[1] = msgs[i].len + 1;
 922                        buf[2] = msgs[i].addr << 1;
 923                        memcpy(&buf[3], msgs[i].buf, msgs[i].len);
 924                        buf_len = msgs[i].len + 3;
 925                        buf[buf_len++] = 0;
 926                }
 927                if (go7007_usb_vendor_request(go, 0x24, 0, 0,
 928                                                buf, buf_len, 0) < 0)
 929                        goto i2c_done;
 930                if (msgs[i].flags & I2C_M_RD) {
 931                        memset(buf, 0, sizeof(buf));
 932                        if (go7007_usb_vendor_request(go, 0x25, 0, 0, buf,
 933                                                msgs[i].len + 1, 1) < 0)
 934                                goto i2c_done;
 935                        memcpy(msgs[i].buf, buf + 1, msgs[i].len);
 936                }
 937        }
 938        ret = 0;
 939
 940i2c_done:
 941        mutex_unlock(&usb->i2c_lock);
 942        return ret;
 943}
 944
 945static u32 go7007_usb_functionality(struct i2c_adapter *adapter)
 946{
 947        /* No errors are reported by the hardware, so we don't bother
 948         * supporting quick writes to avoid confusing probing */
 949        return (I2C_FUNC_SMBUS_EMUL) & ~I2C_FUNC_SMBUS_QUICK;
 950}
 951
 952static struct i2c_algorithm go7007_usb_algo = {
 953        .master_xfer    = go7007_usb_i2c_master_xfer,
 954        .functionality  = go7007_usb_functionality,
 955};
 956
 957static struct i2c_adapter go7007_usb_adap_templ = {
 958        .owner                  = THIS_MODULE,
 959        .name                   = "WIS GO7007SB EZ-USB",
 960        .algo                   = &go7007_usb_algo,
 961};
 962
 963/********************* USB add/remove functions *********************/
 964
 965static int go7007_usb_probe(struct usb_interface *intf,
 966                const struct usb_device_id *id)
 967{
 968        struct go7007 *go;
 969        struct go7007_usb *usb;
 970        struct go7007_usb_board *board;
 971        struct usb_device *usbdev = interface_to_usbdev(intf);
 972        char *name;
 973        int video_pipe, i, v_urb_len;
 974
 975        printk(KERN_DEBUG "go7007-usb: probing new GO7007 USB board\n");
 976
 977        switch (id->driver_info) {
 978        case GO7007_BOARDID_MATRIX_II:
 979                name = "WIS Matrix II or compatible";
 980                board = &board_matrix_ii;
 981                break;
 982        case GO7007_BOARDID_MATRIX_RELOAD:
 983                name = "WIS Matrix Reloaded or compatible";
 984                board = &board_matrix_reload;
 985                break;
 986        case GO7007_BOARDID_MATRIX_REV:
 987                name = "WIS Matrix Revolution or compatible";
 988                board = &board_matrix_revolution;
 989                break;
 990        case GO7007_BOARDID_STAR_TREK:
 991                name = "WIS Star Trek or compatible";
 992                board = &board_star_trek;
 993                break;
 994        case GO7007_BOARDID_XMEN:
 995                name = "WIS XMen or compatible";
 996                board = &board_xmen;
 997                break;
 998        case GO7007_BOARDID_XMEN_II:
 999                name = "WIS XMen II or compatible";
1000                board = &board_xmen;
1001                break;
1002        case GO7007_BOARDID_XMEN_III:
1003                name = "WIS XMen III or compatible";
1004                board = &board_xmen;
1005                break;
1006        case GO7007_BOARDID_PX_M402U:
1007                name = "Plextor PX-M402U";
1008                board = &board_matrix_ii;
1009                break;
1010        case GO7007_BOARDID_PX_TV402U_ANY:
1011                name = "Plextor PX-TV402U (unknown tuner)";
1012                board = &board_px_tv402u;
1013                break;
1014        case GO7007_BOARDID_LIFEVIEW_LR192:
1015                printk(KERN_ERR "go7007-usb: The Lifeview TV Walker Ultra "
1016                                "is not supported.  Sorry!\n");
1017                return 0;
1018                name = "Lifeview TV Walker Ultra";
1019                board = &board_lifeview_lr192;
1020                break;
1021        case GO7007_BOARDID_SENSORAY_2250:
1022                printk(KERN_INFO "Sensoray 2250 found\n");
1023                name = "Sensoray 2250/2251";
1024                board = &board_sensoray_2250;
1025                break;
1026        default:
1027                printk(KERN_ERR "go7007-usb: unknown board ID %d!\n",
1028                                (unsigned int)id->driver_info);
1029                return 0;
1030        }
1031
1032        usb = kzalloc(sizeof(struct go7007_usb), GFP_KERNEL);
1033        if (usb == NULL)
1034                return -ENOMEM;
1035
1036        /* Allocate the URB and buffer for receiving incoming interrupts */
1037        usb->intr_urb = usb_alloc_urb(0, GFP_KERNEL);
1038        if (usb->intr_urb == NULL)
1039                goto allocfail;
1040        usb->intr_urb->transfer_buffer = kmalloc(2*sizeof(u16), GFP_KERNEL);
1041        if (usb->intr_urb->transfer_buffer == NULL)
1042                goto allocfail;
1043
1044        go = go7007_alloc(&board->main_info, &intf->dev);
1045        if (go == NULL)
1046                goto allocfail;
1047        usb->board = board;
1048        usb->usbdev = usbdev;
1049        go->board_id = id->driver_info;
1050        strncpy(go->name, name, sizeof(go->name));
1051        if (board->flags & GO7007_USB_EZUSB)
1052                go->hpi_ops = &go7007_usb_ezusb_hpi_ops;
1053        else
1054                go->hpi_ops = &go7007_usb_onboard_hpi_ops;
1055        go->hpi_context = usb;
1056        usb_fill_int_urb(usb->intr_urb, usb->usbdev,
1057                        usb_rcvintpipe(usb->usbdev, 4),
1058                        usb->intr_urb->transfer_buffer, 2*sizeof(u16),
1059                        go7007_usb_readinterrupt_complete, go, 8);
1060        usb_set_intfdata(intf, go);
1061
1062        /* Boot the GO7007 */
1063        if (go7007_boot_encoder(go, go->board_info->flags &
1064                                        GO7007_BOARD_USE_ONBOARD_I2C) < 0)
1065                goto initfail;
1066
1067        /* Register the EZ-USB I2C adapter, if we're using it */
1068        if (board->flags & GO7007_USB_EZUSB_I2C) {
1069                memcpy(&go->i2c_adapter, &go7007_usb_adap_templ,
1070                                sizeof(go7007_usb_adap_templ));
1071                mutex_init(&usb->i2c_lock);
1072                go->i2c_adapter.dev.parent = go->dev;
1073                i2c_set_adapdata(&go->i2c_adapter, go);
1074                if (i2c_add_adapter(&go->i2c_adapter) < 0) {
1075                        printk(KERN_ERR
1076                                "go7007-usb: error: i2c_add_adapter failed\n");
1077                        goto initfail;
1078                }
1079                go->i2c_adapter_online = 1;
1080        }
1081
1082        /* Pelco and Adlink reused the XMen and XMen-III vendor and product
1083         * IDs for their own incompatible designs.  We can detect XMen boards
1084         * by probing the sensor, but there is no way to probe the sensors on
1085         * the Pelco and Adlink designs so we default to the Adlink.  If it
1086         * is actually a Pelco, the user must set the assume_endura module
1087         * parameter. */
1088        if ((go->board_id == GO7007_BOARDID_XMEN ||
1089                                go->board_id == GO7007_BOARDID_XMEN_III) &&
1090                        go->i2c_adapter_online) {
1091                union i2c_smbus_data data;
1092
1093                /* Check to see if register 0x0A is 0x76 */
1094                i2c_smbus_xfer(&go->i2c_adapter, 0x21, I2C_CLIENT_SCCB,
1095                        I2C_SMBUS_READ, 0x0A, I2C_SMBUS_BYTE_DATA, &data);
1096                if (data.byte != 0x76) {
1097                        if (assume_endura) {
1098                                go->board_id = GO7007_BOARDID_ENDURA;
1099                                usb->board = board = &board_endura;
1100                                go->board_info = &board->main_info;
1101                                strncpy(go->name, "Pelco Endura",
1102                                        sizeof(go->name));
1103                        } else {
1104                                u16 channel;
1105
1106                                /* set GPIO5 to be an output, currently low */
1107                                go7007_write_addr(go, 0x3c82, 0x0000);
1108                                go7007_write_addr(go, 0x3c80, 0x00df);
1109                                /* read channel number from GPIO[1:0] */
1110                                go7007_read_addr(go, 0x3c81, &channel);
1111                                channel &= 0x3;
1112                                go->board_id = GO7007_BOARDID_ADLINK_MPG24;
1113                                usb->board = board = &board_adlink_mpg24;
1114                                go->board_info = &board->main_info;
1115                                go->channel_number = channel;
1116                                snprintf(go->name, sizeof(go->name),
1117                                        "Adlink PCI-MPG24, channel #%d",
1118                                        channel);
1119                        }
1120                }
1121        }
1122
1123        /* Probe the tuner model on the TV402U */
1124        if (go->board_id == GO7007_BOARDID_PX_TV402U_ANY) {
1125                u8 data[3];
1126
1127                /* Board strapping indicates tuner model */
1128                if (go7007_usb_vendor_request(go, 0x41, 0, 0, data, 3, 1) < 0) {
1129                        printk(KERN_ERR "go7007-usb: GPIO read failed!\n");
1130                        goto initfail;
1131                }
1132                switch (data[0] >> 6) {
1133                case 1:
1134                        go->board_id = GO7007_BOARDID_PX_TV402U_EU;
1135                        go->tuner_type = TUNER_SONY_BTF_PG472Z;
1136                        strncpy(go->name, "Plextor PX-TV402U-EU",
1137                                        sizeof(go->name));
1138                        break;
1139                case 2:
1140                        go->board_id = GO7007_BOARDID_PX_TV402U_JP;
1141                        go->tuner_type = TUNER_SONY_BTF_PK467Z;
1142                        strncpy(go->name, "Plextor PX-TV402U-JP",
1143                                        sizeof(go->name));
1144                        break;
1145                case 3:
1146                        go->board_id = GO7007_BOARDID_PX_TV402U_NA;
1147                        go->tuner_type = TUNER_SONY_BTF_PB463Z;
1148                        strncpy(go->name, "Plextor PX-TV402U-NA",
1149                                        sizeof(go->name));
1150                        break;
1151                default:
1152                        printk(KERN_DEBUG "go7007-usb: unable to detect "
1153                                                "tuner type!\n");
1154                        break;
1155                }
1156                /* Configure tuner mode selection inputs connected
1157                 * to the EZ-USB GPIO output pins */
1158                if (go7007_usb_vendor_request(go, 0x40, 0x7f02, 0,
1159                                        NULL, 0, 0) < 0) {
1160                        printk(KERN_ERR "go7007-usb: GPIO write failed!\n");
1161                        goto initfail;
1162                }
1163        }
1164
1165        /* Print a nasty message if the user attempts to use a USB2.0 device in
1166         * a USB1.1 port.  There will be silent corruption of the stream. */
1167        if ((board->flags & GO7007_USB_EZUSB) &&
1168                        usbdev->speed != USB_SPEED_HIGH)
1169                printk(KERN_ERR "go7007-usb: *** WARNING ***  This device "
1170                                "must be connected to a USB 2.0 port!  "
1171                                "Attempting to capture video through a USB 1.1 "
1172                                "port will result in stream corruption, even "
1173                                "at low bitrates!\n");
1174
1175        /* Do any final GO7007 initialization, then register the
1176         * V4L2 and ALSA interfaces */
1177        if (go7007_register_encoder(go) < 0)
1178                goto initfail;
1179
1180        /* Allocate the URBs and buffers for receiving the video stream */
1181        if (board->flags & GO7007_USB_EZUSB) {
1182                v_urb_len = 1024;
1183                video_pipe = usb_rcvbulkpipe(usb->usbdev, 6);
1184        } else {
1185                v_urb_len = 512;
1186                video_pipe = usb_rcvbulkpipe(usb->usbdev, 1);
1187        }
1188        for (i = 0; i < 8; ++i) {
1189                usb->video_urbs[i] = usb_alloc_urb(0, GFP_KERNEL);
1190                if (usb->video_urbs[i] == NULL)
1191                        goto initfail;
1192                usb->video_urbs[i]->transfer_buffer =
1193                                                kmalloc(v_urb_len, GFP_KERNEL);
1194                if (usb->video_urbs[i]->transfer_buffer == NULL)
1195                        goto initfail;
1196                usb_fill_bulk_urb(usb->video_urbs[i], usb->usbdev, video_pipe,
1197                                usb->video_urbs[i]->transfer_buffer, v_urb_len,
1198                                go7007_usb_read_video_pipe_complete, go);
1199        }
1200
1201        /* Allocate the URBs and buffers for receiving the audio stream */
1202        if ((board->flags & GO7007_USB_EZUSB) && go->audio_enabled)
1203                for (i = 0; i < 8; ++i) {
1204                        usb->audio_urbs[i] = usb_alloc_urb(0, GFP_KERNEL);
1205                        if (usb->audio_urbs[i] == NULL)
1206                                goto initfail;
1207                        usb->audio_urbs[i]->transfer_buffer = kmalloc(4096,
1208                                                                GFP_KERNEL);
1209                        if (usb->audio_urbs[i]->transfer_buffer == NULL)
1210                                goto initfail;
1211                        usb_fill_bulk_urb(usb->audio_urbs[i], usb->usbdev,
1212                                usb_rcvbulkpipe(usb->usbdev, 8),
1213                                usb->audio_urbs[i]->transfer_buffer, 4096,
1214                                go7007_usb_read_audio_pipe_complete, go);
1215                }
1216
1217
1218        go->status = STATUS_ONLINE;
1219        return 0;
1220
1221initfail:
1222        go->status = STATUS_SHUTDOWN;
1223        return 0;
1224
1225allocfail:
1226        if (usb->intr_urb) {
1227                kfree(usb->intr_urb->transfer_buffer);
1228                usb_free_urb(usb->intr_urb);
1229        }
1230        kfree(usb);
1231        return -ENOMEM;
1232}
1233
1234static void go7007_usb_disconnect(struct usb_interface *intf)
1235{
1236        struct go7007 *go = usb_get_intfdata(intf);
1237        struct go7007_usb *usb = go->hpi_context;
1238        struct urb *vurb, *aurb;
1239        int i;
1240
1241        go->status = STATUS_SHUTDOWN;
1242        usb_kill_urb(usb->intr_urb);
1243
1244        /* Free USB-related structs */
1245        for (i = 0; i < 8; ++i) {
1246                vurb = usb->video_urbs[i];
1247                if (vurb) {
1248                        usb_kill_urb(vurb);
1249                        if (vurb->transfer_buffer)
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                        if (aurb->transfer_buffer)
1257                                kfree(aurb->transfer_buffer);
1258                        usb_free_urb(aurb);
1259                }
1260        }
1261        kfree(usb->intr_urb->transfer_buffer);
1262        usb_free_urb(usb->intr_urb);
1263
1264        kfree(go->hpi_context);
1265
1266        go7007_remove(go);
1267}
1268
1269static struct usb_driver go7007_usb_driver = {
1270        .name           = "go7007",
1271        .probe          = go7007_usb_probe,
1272        .disconnect     = go7007_usb_disconnect,
1273        .id_table       = go7007_usb_id_table,
1274};
1275
1276static int __init go7007_usb_init(void)
1277{
1278        return usb_register(&go7007_usb_driver);
1279}
1280
1281static void __exit go7007_usb_cleanup(void)
1282{
1283        usb_deregister(&go7007_usb_driver);
1284}
1285
1286module_init(go7007_usb_init);
1287module_exit(go7007_usb_cleanup);
1288
1289MODULE_LICENSE("GPL v2");
1290