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