linux/drivers/media/video/gspca/sonixb.c
<<
>>
Prefs
   1/*
   2 *              sonix sn9c102 (bayer) library
   3 *
   4 * Copyright (C) 2009-2011 Jean-François Moine <http://moinejf.free.fr>
   5 * Copyright (C) 2003 2004 Michel Xhaard mxhaard@magic.fr
   6 * Add Pas106 Stefano Mozzi (C) 2004
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License as published by
  10 * the Free Software Foundation; either version 2 of the License, or
  11 * any later version.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16 * GNU General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License
  19 * along with this program; if not, write to the Free Software
  20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  21 */
  22
  23/* Some documentation on known sonixb registers:
  24
  25Reg     Use
  26sn9c101 / sn9c102:
  270x10    high nibble red gain low nibble blue gain
  280x11    low nibble green gain
  29sn9c103:
  300x05    red gain 0-127
  310x06    blue gain 0-127
  320x07    green gain 0-127
  33all:
  340x08-0x0f i2c / 3wire registers
  350x12    hstart
  360x13    vstart
  370x15    hsize (hsize = register-value * 16)
  380x16    vsize (vsize = register-value * 16)
  390x17    bit 0 toggle compression quality (according to sn9c102 driver)
  400x18    bit 7 enables compression, bit 4-5 set image down scaling:
  41        00 scale 1, 01 scale 1/2, 10, scale 1/4
  420x19    high-nibble is sensor clock divider, changes exposure on sensors which
  43        use a clock generated by the bridge. Some sensors have their own clock.
  440x1c    auto_exposure area (for avg_lum) startx (startx = register-value * 32)
  450x1d    auto_exposure area (for avg_lum) starty (starty = register-value * 32)
  460x1e    auto_exposure area (for avg_lum) stopx (hsize = (0x1e - 0x1c) * 32)
  470x1f    auto_exposure area (for avg_lum) stopy (vsize = (0x1f - 0x1d) * 32)
  48*/
  49
  50#define MODULE_NAME "sonixb"
  51
  52#include <linux/input.h>
  53#include "gspca.h"
  54
  55MODULE_AUTHOR("Jean-François Moine <http://moinejf.free.fr>");
  56MODULE_DESCRIPTION("GSPCA/SN9C102 USB Camera Driver");
  57MODULE_LICENSE("GPL");
  58
  59/* controls */
  60enum e_ctrl {
  61        BRIGHTNESS,
  62        GAIN,
  63        EXPOSURE,
  64        AUTOGAIN,
  65        FREQ,
  66        NCTRLS          /* number of controls */
  67};
  68
  69/* specific webcam descriptor */
  70struct sd {
  71        struct gspca_dev gspca_dev;     /* !! must be the first item */
  72
  73        struct gspca_ctrl ctrls[NCTRLS];
  74
  75        atomic_t avg_lum;
  76        int prev_avg_lum;
  77        int exp_too_low_cnt;
  78        int exp_too_high_cnt;
  79        int header_read;
  80        u8 header[12]; /* Header without sof marker */
  81
  82        unsigned char autogain_ignore_frames;
  83        unsigned char frames_to_drop;
  84
  85        __u8 bridge;                    /* Type of bridge */
  86#define BRIDGE_101 0
  87#define BRIDGE_102 0 /* We make no difference between 101 and 102 */
  88#define BRIDGE_103 1
  89
  90        __u8 sensor;                    /* Type of image sensor chip */
  91#define SENSOR_HV7131D 0
  92#define SENSOR_HV7131R 1
  93#define SENSOR_OV6650 2
  94#define SENSOR_OV7630 3
  95#define SENSOR_PAS106 4
  96#define SENSOR_PAS202 5
  97#define SENSOR_TAS5110C 6
  98#define SENSOR_TAS5110D 7
  99#define SENSOR_TAS5130CXX 8
 100        __u8 reg11;
 101};
 102
 103typedef const __u8 sensor_init_t[8];
 104
 105struct sensor_data {
 106        const __u8 *bridge_init;
 107        sensor_init_t *sensor_init;
 108        int sensor_init_size;
 109        int flags;
 110        unsigned ctrl_dis;
 111        __u8 sensor_addr;
 112};
 113
 114/* sensor_data flags */
 115#define F_GAIN 0x01             /* has gain */
 116#define F_SIF  0x02             /* sif or vga */
 117#define F_COARSE_EXPO 0x04      /* exposure control is coarse */
 118
 119/* priv field of struct v4l2_pix_format flags (do not use low nibble!) */
 120#define MODE_RAW 0x10           /* raw bayer mode */
 121#define MODE_REDUCED_SIF 0x20   /* vga mode (320x240 / 160x120) on sif cam */
 122
 123/* ctrl_dis helper macros */
 124#define NO_EXPO ((1 << EXPOSURE) | (1 << AUTOGAIN))
 125#define NO_FREQ (1 << FREQ)
 126#define NO_BRIGHTNESS (1 << BRIGHTNESS)
 127
 128#define COMP 0xc7               /* 0x87 //0x07 */
 129#define COMP1 0xc9              /* 0x89 //0x09 */
 130
 131#define MCK_INIT 0x63
 132#define MCK_INIT1 0x20          /*fixme: Bayer - 0x50 for JPEG ??*/
 133
 134#define SYS_CLK 0x04
 135
 136#define SENS(bridge, sensor, _flags, _ctrl_dis, _sensor_addr) \
 137{ \
 138        .bridge_init = bridge, \
 139        .sensor_init = sensor, \
 140        .sensor_init_size = sizeof(sensor), \
 141        .flags = _flags, .ctrl_dis = _ctrl_dis, .sensor_addr = _sensor_addr \
 142}
 143
 144/* We calculate the autogain at the end of the transfer of a frame, at this
 145   moment a frame with the old settings is being captured and transmitted. So
 146   if we adjust the gain or exposure we must ignore atleast the next frame for
 147   the new settings to come into effect before doing any other adjustments. */
 148#define AUTOGAIN_IGNORE_FRAMES 1
 149
 150/* V4L2 controls supported by the driver */
 151static void setbrightness(struct gspca_dev *gspca_dev);
 152static void setgain(struct gspca_dev *gspca_dev);
 153static void setexposure(struct gspca_dev *gspca_dev);
 154static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
 155static void setfreq(struct gspca_dev *gspca_dev);
 156
 157static const struct ctrl sd_ctrls[NCTRLS] = {
 158[BRIGHTNESS] = {
 159            {
 160                .id      = V4L2_CID_BRIGHTNESS,
 161                .type    = V4L2_CTRL_TYPE_INTEGER,
 162                .name    = "Brightness",
 163                .minimum = 0,
 164                .maximum = 255,
 165                .step    = 1,
 166                .default_value = 127,
 167            },
 168            .set_control = setbrightness
 169        },
 170[GAIN] = {
 171            {
 172                .id      = V4L2_CID_GAIN,
 173                .type    = V4L2_CTRL_TYPE_INTEGER,
 174                .name    = "Gain",
 175                .minimum = 0,
 176                .maximum = 255,
 177                .step    = 1,
 178#define GAIN_KNEE 230
 179                .default_value = 127,
 180            },
 181            .set_control = setgain
 182        },
 183[EXPOSURE] = {
 184                {
 185                        .id = V4L2_CID_EXPOSURE,
 186                        .type = V4L2_CTRL_TYPE_INTEGER,
 187                        .name = "Exposure",
 188                        .minimum = 0,
 189                        .maximum = 1023,
 190                        .step = 1,
 191                        .default_value = 66,
 192                                /*  33 ms / 30 fps (except on PASXXX) */
 193#define EXPOSURE_KNEE 200       /* 100 ms / 10 fps (except on PASXXX) */
 194                        .flags = 0,
 195                },
 196                .set_control = setexposure
 197        },
 198/* for coarse exposure */
 199#define COARSE_EXPOSURE_MIN 2
 200#define COARSE_EXPOSURE_MAX 15
 201#define COARSE_EXPOSURE_DEF  2 /* 30 fps */
 202[AUTOGAIN] = {
 203                {
 204                        .id = V4L2_CID_AUTOGAIN,
 205                        .type = V4L2_CTRL_TYPE_BOOLEAN,
 206                        .name = "Automatic Gain (and Exposure)",
 207                        .minimum = 0,
 208                        .maximum = 1,
 209                        .step = 1,
 210#define AUTOGAIN_DEF 1
 211                        .default_value = AUTOGAIN_DEF,
 212                        .flags = V4L2_CTRL_FLAG_UPDATE
 213                },
 214                .set = sd_setautogain,
 215        },
 216[FREQ] = {
 217                {
 218                        .id      = V4L2_CID_POWER_LINE_FREQUENCY,
 219                        .type    = V4L2_CTRL_TYPE_MENU,
 220                        .name    = "Light frequency filter",
 221                        .minimum = 0,
 222                        .maximum = 2,   /* 0: 0, 1: 50Hz, 2:60Hz */
 223                        .step    = 1,
 224#define FREQ_DEF 0
 225                        .default_value = FREQ_DEF,
 226                },
 227                .set_control = setfreq
 228        },
 229};
 230
 231static const struct v4l2_pix_format vga_mode[] = {
 232        {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
 233                .bytesperline = 160,
 234                .sizeimage = 160 * 120,
 235                .colorspace = V4L2_COLORSPACE_SRGB,
 236                .priv = 2 | MODE_RAW},
 237        {160, 120, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
 238                .bytesperline = 160,
 239                .sizeimage = 160 * 120 * 5 / 4,
 240                .colorspace = V4L2_COLORSPACE_SRGB,
 241                .priv = 2},
 242        {320, 240, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
 243                .bytesperline = 320,
 244                .sizeimage = 320 * 240 * 5 / 4,
 245                .colorspace = V4L2_COLORSPACE_SRGB,
 246                .priv = 1},
 247        {640, 480, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
 248                .bytesperline = 640,
 249                .sizeimage = 640 * 480 * 5 / 4,
 250                .colorspace = V4L2_COLORSPACE_SRGB,
 251                .priv = 0},
 252};
 253static const struct v4l2_pix_format sif_mode[] = {
 254        {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
 255                .bytesperline = 160,
 256                .sizeimage = 160 * 120,
 257                .colorspace = V4L2_COLORSPACE_SRGB,
 258                .priv = 1 | MODE_RAW | MODE_REDUCED_SIF},
 259        {160, 120, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
 260                .bytesperline = 160,
 261                .sizeimage = 160 * 120 * 5 / 4,
 262                .colorspace = V4L2_COLORSPACE_SRGB,
 263                .priv = 1 | MODE_REDUCED_SIF},
 264        {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
 265                .bytesperline = 176,
 266                .sizeimage = 176 * 144,
 267                .colorspace = V4L2_COLORSPACE_SRGB,
 268                .priv = 1 | MODE_RAW},
 269        {176, 144, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
 270                .bytesperline = 176,
 271                .sizeimage = 176 * 144 * 5 / 4,
 272                .colorspace = V4L2_COLORSPACE_SRGB,
 273                .priv = 1},
 274        {320, 240, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
 275                .bytesperline = 320,
 276                .sizeimage = 320 * 240 * 5 / 4,
 277                .colorspace = V4L2_COLORSPACE_SRGB,
 278                .priv = 0 | MODE_REDUCED_SIF},
 279        {352, 288, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
 280                .bytesperline = 352,
 281                .sizeimage = 352 * 288 * 5 / 4,
 282                .colorspace = V4L2_COLORSPACE_SRGB,
 283                .priv = 0},
 284};
 285
 286static const __u8 initHv7131d[] = {
 287        0x04, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00,
 288        0x00, 0x00,
 289        0x00, 0x00, 0x00, 0x02, 0x02, 0x00,
 290        0x28, 0x1e, 0x60, 0x8e, 0x42,
 291};
 292static const __u8 hv7131d_sensor_init[][8] = {
 293        {0xa0, 0x11, 0x01, 0x04, 0x00, 0x00, 0x00, 0x17},
 294        {0xa0, 0x11, 0x02, 0x00, 0x00, 0x00, 0x00, 0x17},
 295        {0xa0, 0x11, 0x28, 0x00, 0x00, 0x00, 0x00, 0x17},
 296        {0xa0, 0x11, 0x30, 0x30, 0x00, 0x00, 0x00, 0x17}, /* reset level */
 297        {0xa0, 0x11, 0x34, 0x02, 0x00, 0x00, 0x00, 0x17}, /* pixel bias volt */
 298};
 299
 300static const __u8 initHv7131r[] = {
 301        0x46, 0x77, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00,
 302        0x00, 0x00,
 303        0x00, 0x00, 0x00, 0x02, 0x01, 0x00,
 304        0x28, 0x1e, 0x60, 0x8a, 0x20,
 305};
 306static const __u8 hv7131r_sensor_init[][8] = {
 307        {0xc0, 0x11, 0x31, 0x38, 0x2a, 0x2e, 0x00, 0x10},
 308        {0xa0, 0x11, 0x01, 0x08, 0x2a, 0x2e, 0x00, 0x10},
 309        {0xb0, 0x11, 0x20, 0x00, 0xd0, 0x2e, 0x00, 0x10},
 310        {0xc0, 0x11, 0x25, 0x03, 0x0e, 0x28, 0x00, 0x16},
 311        {0xa0, 0x11, 0x30, 0x10, 0x0e, 0x28, 0x00, 0x15},
 312};
 313static const __u8 initOv6650[] = {
 314        0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
 315        0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 316        0x00, 0x01, 0x01, 0x0a, 0x16, 0x12, 0x68, 0x8b,
 317        0x10,
 318};
 319static const __u8 ov6650_sensor_init[][8] = {
 320        /* Bright, contrast, etc are set through SCBB interface.
 321         * AVCAP on win2 do not send any data on this controls. */
 322        /* Anyway, some registers appears to alter bright and constrat */
 323
 324        /* Reset sensor */
 325        {0xa0, 0x60, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},
 326        /* Set clock register 0x11 low nibble is clock divider */
 327        {0xd0, 0x60, 0x11, 0xc0, 0x1b, 0x18, 0xc1, 0x10},
 328        /* Next some unknown stuff */
 329        {0xb0, 0x60, 0x15, 0x00, 0x02, 0x18, 0xc1, 0x10},
 330/*      {0xa0, 0x60, 0x1b, 0x01, 0x02, 0x18, 0xc1, 0x10},
 331                 * THIS SET GREEN SCREEN
 332                 * (pixels could be innverted in decode kind of "brg",
 333                 * but blue wont be there. Avoid this data ... */
 334        {0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10}, /* format out? */
 335        {0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10},
 336        {0xa0, 0x60, 0x30, 0x3d, 0x0a, 0xd8, 0xa4, 0x10},
 337        /* Enable rgb brightness control */
 338        {0xa0, 0x60, 0x61, 0x08, 0x00, 0x00, 0x00, 0x10},
 339        /* HDG: Note windows uses the line below, which sets both register 0x60
 340           and 0x61 I believe these registers of the ov6650 are identical as
 341           those of the ov7630, because if this is true the windows settings
 342           add a bit additional red gain and a lot additional blue gain, which
 343           matches my findings that the windows settings make blue much too
 344           blue and red a little too red.
 345        {0xb0, 0x60, 0x60, 0x66, 0x68, 0xd8, 0xa4, 0x10}, */
 346        /* Some more unknown stuff */
 347        {0xa0, 0x60, 0x68, 0x04, 0x68, 0xd8, 0xa4, 0x10},
 348        {0xd0, 0x60, 0x17, 0x24, 0xd6, 0x04, 0x94, 0x10}, /* Clipreg */
 349};
 350
 351static const __u8 initOv7630[] = {
 352        0x04, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* r01 .. r08 */
 353        0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* r09 .. r10 */
 354        0x00, 0x01, 0x01, 0x0a,                         /* r11 .. r14 */
 355        0x28, 0x1e,                     /* H & V sizes     r15 .. r16 */
 356        0x68, 0x8f, MCK_INIT1,                          /* r17 .. r19 */
 357};
 358static const __u8 ov7630_sensor_init[][8] = {
 359        {0xa0, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},
 360        {0xb0, 0x21, 0x01, 0x77, 0x3a, 0x00, 0x00, 0x10},
 361/*      {0xd0, 0x21, 0x12, 0x7c, 0x01, 0x80, 0x34, 0x10},          jfm */
 362        {0xd0, 0x21, 0x12, 0x5c, 0x00, 0x80, 0x34, 0x10},       /* jfm */
 363        {0xa0, 0x21, 0x1b, 0x04, 0x00, 0x80, 0x34, 0x10},
 364        {0xa0, 0x21, 0x20, 0x44, 0x00, 0x80, 0x34, 0x10},
 365        {0xa0, 0x21, 0x23, 0xee, 0x00, 0x80, 0x34, 0x10},
 366        {0xd0, 0x21, 0x26, 0xa0, 0x9a, 0xa0, 0x30, 0x10},
 367        {0xb0, 0x21, 0x2a, 0x80, 0x00, 0xa0, 0x30, 0x10},
 368        {0xb0, 0x21, 0x2f, 0x3d, 0x24, 0xa0, 0x30, 0x10},
 369        {0xa0, 0x21, 0x32, 0x86, 0x24, 0xa0, 0x30, 0x10},
 370        {0xb0, 0x21, 0x60, 0xa9, 0x4a, 0xa0, 0x30, 0x10},
 371/*      {0xb0, 0x21, 0x60, 0xa9, 0x42, 0xa0, 0x30, 0x10},        * jfm */
 372        {0xa0, 0x21, 0x65, 0x00, 0x42, 0xa0, 0x30, 0x10},
 373        {0xa0, 0x21, 0x69, 0x38, 0x42, 0xa0, 0x30, 0x10},
 374        {0xc0, 0x21, 0x6f, 0x88, 0x0b, 0x00, 0x30, 0x10},
 375        {0xc0, 0x21, 0x74, 0x21, 0x8e, 0x00, 0x30, 0x10},
 376        {0xa0, 0x21, 0x7d, 0xf7, 0x8e, 0x00, 0x30, 0x10},
 377        {0xd0, 0x21, 0x17, 0x1c, 0xbd, 0x06, 0xf6, 0x10},
 378};
 379
 380static const __u8 initPas106[] = {
 381        0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x00, 0x00,
 382        0x00, 0x00,
 383        0x00, 0x00, 0x00, 0x04, 0x01, 0x00,
 384        0x16, 0x12, 0x24, COMP1, MCK_INIT1,
 385};
 386/* compression 0x86 mckinit1 0x2b */
 387
 388/* "Known" PAS106B registers:
 389  0x02 clock divider
 390  0x03 Variable framerate bits 4-11
 391  0x04 Var framerate bits 0-3, one must leave the 4 msb's at 0 !!
 392       The variable framerate control must never be set lower then 300,
 393       which sets the framerate at 90 / reg02, otherwise vsync is lost.
 394  0x05 Shutter Time Line Offset, this can be used as an exposure control:
 395       0 = use full frame time, 255 = no exposure at all
 396       Note this may never be larger then "var-framerate control" / 2 - 2.
 397       When var-framerate control is < 514, no exposure is reached at the max
 398       allowed value for the framerate control value, rather then at 255.
 399  0x06 Shutter Time Pixel Offset, like reg05 this influences exposure, but
 400       only a very little bit, leave at 0xcd
 401  0x07 offset sign bit (bit0 1 > negative offset)
 402  0x08 offset
 403  0x09 Blue Gain
 404  0x0a Green1 Gain
 405  0x0b Green2 Gain
 406  0x0c Red Gain
 407  0x0e Global gain
 408  0x13 Write 1 to commit settings to sensor
 409*/
 410
 411static const __u8 pas106_sensor_init[][8] = {
 412        /* Pixel Clock Divider 6 */
 413        { 0xa1, 0x40, 0x02, 0x04, 0x00, 0x00, 0x00, 0x14 },
 414        /* Frame Time MSB (also seen as 0x12) */
 415        { 0xa1, 0x40, 0x03, 0x13, 0x00, 0x00, 0x00, 0x14 },
 416        /* Frame Time LSB (also seen as 0x05) */
 417        { 0xa1, 0x40, 0x04, 0x06, 0x00, 0x00, 0x00, 0x14 },
 418        /* Shutter Time Line Offset (also seen as 0x6d) */
 419        { 0xa1, 0x40, 0x05, 0x65, 0x00, 0x00, 0x00, 0x14 },
 420        /* Shutter Time Pixel Offset (also seen as 0xb1) */
 421        { 0xa1, 0x40, 0x06, 0xcd, 0x00, 0x00, 0x00, 0x14 },
 422        /* Black Level Subtract Sign (also seen 0x00) */
 423        { 0xa1, 0x40, 0x07, 0xc1, 0x00, 0x00, 0x00, 0x14 },
 424        /* Black Level Subtract Level (also seen 0x01) */
 425        { 0xa1, 0x40, 0x08, 0x06, 0x00, 0x00, 0x00, 0x14 },
 426        { 0xa1, 0x40, 0x08, 0x06, 0x00, 0x00, 0x00, 0x14 },
 427        /* Color Gain B Pixel 5 a */
 428        { 0xa1, 0x40, 0x09, 0x05, 0x00, 0x00, 0x00, 0x14 },
 429        /* Color Gain G1 Pixel 1 5 */
 430        { 0xa1, 0x40, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x14 },
 431        /* Color Gain G2 Pixel 1 0 5 */
 432        { 0xa1, 0x40, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x14 },
 433        /* Color Gain R Pixel 3 1 */
 434        { 0xa1, 0x40, 0x0c, 0x05, 0x00, 0x00, 0x00, 0x14 },
 435        /* Color GainH  Pixel */
 436        { 0xa1, 0x40, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x14 },
 437        /* Global Gain */
 438        { 0xa1, 0x40, 0x0e, 0x0e, 0x00, 0x00, 0x00, 0x14 },
 439        /* Contrast */
 440        { 0xa1, 0x40, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x14 },
 441        /* H&V synchro polarity */
 442        { 0xa1, 0x40, 0x10, 0x06, 0x00, 0x00, 0x00, 0x14 },
 443        /* ?default */
 444        { 0xa1, 0x40, 0x11, 0x06, 0x00, 0x00, 0x00, 0x14 },
 445        /* DAC scale */
 446        { 0xa1, 0x40, 0x12, 0x06, 0x00, 0x00, 0x00, 0x14 },
 447        /* ?default */
 448        { 0xa1, 0x40, 0x14, 0x02, 0x00, 0x00, 0x00, 0x14 },
 449        /* Validate Settings */
 450        { 0xa1, 0x40, 0x13, 0x01, 0x00, 0x00, 0x00, 0x14 },
 451};
 452
 453static const __u8 initPas202[] = {
 454        0x44, 0x44, 0x21, 0x30, 0x00, 0x00, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00,
 455        0x00, 0x00,
 456        0x00, 0x00, 0x00, 0x06, 0x03, 0x0a,
 457        0x28, 0x1e, 0x20, 0x89, 0x20,
 458};
 459
 460/* "Known" PAS202BCB registers:
 461  0x02 clock divider
 462  0x04 Variable framerate bits 6-11 (*)
 463  0x05 Var framerate  bits 0-5, one must leave the 2 msb's at 0 !!
 464  0x07 Blue Gain
 465  0x08 Green Gain
 466  0x09 Red Gain
 467  0x0b offset sign bit (bit0 1 > negative offset)
 468  0x0c offset
 469  0x0e Unknown image is slightly brighter when bit 0 is 0, if reg0f is 0 too,
 470       leave at 1 otherwise we get a jump in our exposure control
 471  0x0f Exposure 0-255, 0 = use full frame time, 255 = no exposure at all
 472  0x10 Master gain 0 - 31
 473  0x11 write 1 to apply changes
 474  (*) The variable framerate control must never be set lower then 500
 475      which sets the framerate at 30 / reg02, otherwise vsync is lost.
 476*/
 477static const __u8 pas202_sensor_init[][8] = {
 478        /* Set the clock divider to 4 -> 30 / 4 = 7.5 fps, we would like
 479           to set it lower, but for some reason the bridge starts missing
 480           vsync's then */
 481        {0xa0, 0x40, 0x02, 0x04, 0x00, 0x00, 0x00, 0x10},
 482        {0xd0, 0x40, 0x04, 0x07, 0x34, 0x00, 0x09, 0x10},
 483        {0xd0, 0x40, 0x08, 0x01, 0x00, 0x00, 0x01, 0x10},
 484        {0xd0, 0x40, 0x0c, 0x00, 0x0c, 0x01, 0x32, 0x10},
 485        {0xd0, 0x40, 0x10, 0x00, 0x01, 0x00, 0x63, 0x10},
 486        {0xa0, 0x40, 0x15, 0x70, 0x01, 0x00, 0x63, 0x10},
 487        {0xa0, 0x40, 0x18, 0x00, 0x01, 0x00, 0x63, 0x10},
 488        {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10},
 489        {0xa0, 0x40, 0x03, 0x56, 0x01, 0x00, 0x63, 0x10},
 490        {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10},
 491};
 492
 493static const __u8 initTas5110c[] = {
 494        0x44, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
 495        0x00, 0x00,
 496        0x00, 0x00, 0x00, 0x45, 0x09, 0x0a,
 497        0x16, 0x12, 0x60, 0x86, 0x2b,
 498};
 499/* Same as above, except a different hstart */
 500static const __u8 initTas5110d[] = {
 501        0x44, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
 502        0x00, 0x00,
 503        0x00, 0x00, 0x00, 0x41, 0x09, 0x0a,
 504        0x16, 0x12, 0x60, 0x86, 0x2b,
 505};
 506/* tas5110c is 3 wire, tas5110d is 2 wire (regular i2c) */
 507static const __u8 tas5110c_sensor_init[][8] = {
 508        {0x30, 0x11, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10},
 509        {0x30, 0x11, 0x02, 0x20, 0xa9, 0x00, 0x00, 0x10},
 510};
 511/* Known TAS5110D registers
 512 * reg02: gain, bit order reversed!! 0 == max gain, 255 == min gain
 513 * reg03: bit3: vflip, bit4: ~hflip, bit7: ~gainboost (~ == inverted)
 514 *        Note: writing reg03 seems to only work when written together with 02
 515 */
 516static const __u8 tas5110d_sensor_init[][8] = {
 517        {0xa0, 0x61, 0x9a, 0xca, 0x00, 0x00, 0x00, 0x17}, /* reset */
 518};
 519
 520static const __u8 initTas5130[] = {
 521        0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
 522        0x00, 0x00,
 523        0x00, 0x00, 0x00, 0x68, 0x0c, 0x0a,
 524        0x28, 0x1e, 0x60, COMP, MCK_INIT,
 525};
 526static const __u8 tas5130_sensor_init[][8] = {
 527/*      {0x30, 0x11, 0x00, 0x40, 0x47, 0x00, 0x00, 0x10},
 528                                        * shutter 0x47 short exposure? */
 529        {0x30, 0x11, 0x00, 0x40, 0x01, 0x00, 0x00, 0x10},
 530                                        /* shutter 0x01 long exposure */
 531        {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10},
 532};
 533
 534static const struct sensor_data sensor_data[] = {
 535SENS(initHv7131d, hv7131d_sensor_init, F_GAIN, NO_BRIGHTNESS|NO_FREQ, 0),
 536SENS(initHv7131r, hv7131r_sensor_init, 0, NO_BRIGHTNESS|NO_EXPO|NO_FREQ, 0),
 537SENS(initOv6650, ov6650_sensor_init, F_GAIN|F_SIF, 0, 0x60),
 538SENS(initOv7630, ov7630_sensor_init, F_GAIN, 0, 0x21),
 539SENS(initPas106, pas106_sensor_init, F_GAIN|F_SIF, NO_FREQ, 0),
 540SENS(initPas202, pas202_sensor_init, F_GAIN, NO_FREQ, 0),
 541SENS(initTas5110c, tas5110c_sensor_init, F_GAIN|F_SIF|F_COARSE_EXPO,
 542        NO_BRIGHTNESS|NO_FREQ, 0),
 543SENS(initTas5110d, tas5110d_sensor_init, F_GAIN|F_SIF|F_COARSE_EXPO,
 544        NO_BRIGHTNESS|NO_FREQ, 0),
 545SENS(initTas5130, tas5130_sensor_init, F_GAIN,
 546        NO_BRIGHTNESS|NO_EXPO|NO_FREQ, 0),
 547};
 548
 549/* get one byte in gspca_dev->usb_buf */
 550static void reg_r(struct gspca_dev *gspca_dev,
 551                  __u16 value)
 552{
 553        usb_control_msg(gspca_dev->dev,
 554                        usb_rcvctrlpipe(gspca_dev->dev, 0),
 555                        0,                      /* request */
 556                        USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
 557                        value,
 558                        0,                      /* index */
 559                        gspca_dev->usb_buf, 1,
 560                        500);
 561}
 562
 563static void reg_w(struct gspca_dev *gspca_dev,
 564                  __u16 value,
 565                  const __u8 *buffer,
 566                  int len)
 567{
 568#ifdef GSPCA_DEBUG
 569        if (len > USB_BUF_SZ) {
 570                PDEBUG(D_ERR|D_PACK, "reg_w: buffer overflow");
 571                return;
 572        }
 573#endif
 574        memcpy(gspca_dev->usb_buf, buffer, len);
 575        usb_control_msg(gspca_dev->dev,
 576                        usb_sndctrlpipe(gspca_dev->dev, 0),
 577                        0x08,                   /* request */
 578                        USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
 579                        value,
 580                        0,                      /* index */
 581                        gspca_dev->usb_buf, len,
 582                        500);
 583}
 584
 585static int i2c_w(struct gspca_dev *gspca_dev, const __u8 *buffer)
 586{
 587        int retry = 60;
 588
 589        /* is i2c ready */
 590        reg_w(gspca_dev, 0x08, buffer, 8);
 591        while (retry--) {
 592                msleep(10);
 593                reg_r(gspca_dev, 0x08);
 594                if (gspca_dev->usb_buf[0] & 0x04) {
 595                        if (gspca_dev->usb_buf[0] & 0x08)
 596                                return -1;
 597                        return 0;
 598                }
 599        }
 600        return -1;
 601}
 602
 603static void i2c_w_vector(struct gspca_dev *gspca_dev,
 604                        const __u8 buffer[][8], int len)
 605{
 606        for (;;) {
 607                reg_w(gspca_dev, 0x08, *buffer, 8);
 608                len -= 8;
 609                if (len <= 0)
 610                        break;
 611                buffer++;
 612        }
 613}
 614
 615static void setbrightness(struct gspca_dev *gspca_dev)
 616{
 617        struct sd *sd = (struct sd *) gspca_dev;
 618
 619        switch (sd->sensor) {
 620        case  SENSOR_OV6650:
 621        case  SENSOR_OV7630: {
 622                __u8 i2cOV[] =
 623                        {0xa0, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10};
 624
 625                /* change reg 0x06 */
 626                i2cOV[1] = sensor_data[sd->sensor].sensor_addr;
 627                i2cOV[3] = sd->ctrls[BRIGHTNESS].val;
 628                if (i2c_w(gspca_dev, i2cOV) < 0)
 629                        goto err;
 630                break;
 631            }
 632        case SENSOR_PAS106:
 633        case SENSOR_PAS202: {
 634                __u8 i2cpbright[] =
 635                        {0xb0, 0x40, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x16};
 636                __u8 i2cpdoit[] =
 637                        {0xa0, 0x40, 0x11, 0x01, 0x00, 0x00, 0x00, 0x16};
 638
 639                /* PAS106 uses reg 7 and 8 instead of b and c */
 640                if (sd->sensor == SENSOR_PAS106) {
 641                        i2cpbright[2] = 7;
 642                        i2cpdoit[2] = 0x13;
 643                }
 644
 645                if (sd->ctrls[BRIGHTNESS].val < 127) {
 646                        /* change reg 0x0b, signreg */
 647                        i2cpbright[3] = 0x01;
 648                        /* set reg 0x0c, offset */
 649                        i2cpbright[4] = 127 - sd->ctrls[BRIGHTNESS].val;
 650                } else
 651                        i2cpbright[4] = sd->ctrls[BRIGHTNESS].val - 127;
 652
 653                if (i2c_w(gspca_dev, i2cpbright) < 0)
 654                        goto err;
 655                if (i2c_w(gspca_dev, i2cpdoit) < 0)
 656                        goto err;
 657                break;
 658            }
 659        }
 660        return;
 661err:
 662        PDEBUG(D_ERR, "i2c error brightness");
 663}
 664
 665static void setsensorgain(struct gspca_dev *gspca_dev)
 666{
 667        struct sd *sd = (struct sd *) gspca_dev;
 668        u8 gain = sd->ctrls[GAIN].val;
 669
 670        switch (sd->sensor) {
 671        case SENSOR_HV7131D: {
 672                __u8 i2c[] =
 673                        {0xc0, 0x11, 0x31, 0x00, 0x00, 0x00, 0x00, 0x17};
 674
 675                i2c[3] = 0x3f - (gain / 4);
 676                i2c[4] = 0x3f - (gain / 4);
 677                i2c[5] = 0x3f - (gain / 4);
 678
 679                if (i2c_w(gspca_dev, i2c) < 0)
 680                        goto err;
 681                break;
 682            }
 683        case SENSOR_TAS5110C:
 684        case SENSOR_TAS5130CXX: {
 685                __u8 i2c[] =
 686                        {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10};
 687
 688                i2c[4] = 255 - gain;
 689                if (i2c_w(gspca_dev, i2c) < 0)
 690                        goto err;
 691                break;
 692            }
 693        case SENSOR_TAS5110D: {
 694                __u8 i2c[] = {
 695                        0xb0, 0x61, 0x02, 0x00, 0x10, 0x00, 0x00, 0x17 };
 696                gain = 255 - gain;
 697                /* The bits in the register are the wrong way around!! */
 698                i2c[3] |= (gain & 0x80) >> 7;
 699                i2c[3] |= (gain & 0x40) >> 5;
 700                i2c[3] |= (gain & 0x20) >> 3;
 701                i2c[3] |= (gain & 0x10) >> 1;
 702                i2c[3] |= (gain & 0x08) << 1;
 703                i2c[3] |= (gain & 0x04) << 3;
 704                i2c[3] |= (gain & 0x02) << 5;
 705                i2c[3] |= (gain & 0x01) << 7;
 706                if (i2c_w(gspca_dev, i2c) < 0)
 707                        goto err;
 708                break;
 709            }
 710
 711        case SENSOR_OV6650:
 712                gain >>= 1;
 713                /* fall thru */
 714        case SENSOR_OV7630: {
 715                __u8 i2c[] = {0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
 716
 717                i2c[1] = sensor_data[sd->sensor].sensor_addr;
 718                i2c[3] = gain >> 2;
 719                if (i2c_w(gspca_dev, i2c) < 0)
 720                        goto err;
 721                break;
 722            }
 723        case SENSOR_PAS106:
 724        case SENSOR_PAS202: {
 725                __u8 i2cpgain[] =
 726                        {0xa0, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x15};
 727                __u8 i2cpcolorgain[] =
 728                        {0xc0, 0x40, 0x07, 0x00, 0x00, 0x00, 0x00, 0x15};
 729                __u8 i2cpdoit[] =
 730                        {0xa0, 0x40, 0x11, 0x01, 0x00, 0x00, 0x00, 0x16};
 731
 732                /* PAS106 uses different regs (and has split green gains) */
 733                if (sd->sensor == SENSOR_PAS106) {
 734                        i2cpgain[2] = 0x0e;
 735                        i2cpcolorgain[0] = 0xd0;
 736                        i2cpcolorgain[2] = 0x09;
 737                        i2cpdoit[2] = 0x13;
 738                }
 739
 740                i2cpgain[3] = gain >> 3;
 741                i2cpcolorgain[3] = gain >> 4;
 742                i2cpcolorgain[4] = gain >> 4;
 743                i2cpcolorgain[5] = gain >> 4;
 744                i2cpcolorgain[6] = gain >> 4;
 745
 746                if (i2c_w(gspca_dev, i2cpgain) < 0)
 747                        goto err;
 748                if (i2c_w(gspca_dev, i2cpcolorgain) < 0)
 749                        goto err;
 750                if (i2c_w(gspca_dev, i2cpdoit) < 0)
 751                        goto err;
 752                break;
 753            }
 754        }
 755        return;
 756err:
 757        PDEBUG(D_ERR, "i2c error gain");
 758}
 759
 760static void setgain(struct gspca_dev *gspca_dev)
 761{
 762        struct sd *sd = (struct sd *) gspca_dev;
 763        __u8 gain;
 764        __u8 buf[3] = { 0, 0, 0 };
 765
 766        if (sensor_data[sd->sensor].flags & F_GAIN) {
 767                /* Use the sensor gain to do the actual gain */
 768                setsensorgain(gspca_dev);
 769                return;
 770        }
 771
 772        if (sd->bridge == BRIDGE_103) {
 773                gain = sd->ctrls[GAIN].val >> 1;
 774                buf[0] = gain; /* Red */
 775                buf[1] = gain; /* Green */
 776                buf[2] = gain; /* Blue */
 777                reg_w(gspca_dev, 0x05, buf, 3);
 778        } else {
 779                gain = sd->ctrls[GAIN].val >> 4;
 780                buf[0] = gain << 4 | gain; /* Red and blue */
 781                buf[1] = gain; /* Green */
 782                reg_w(gspca_dev, 0x10, buf, 2);
 783        }
 784}
 785
 786static void setexposure(struct gspca_dev *gspca_dev)
 787{
 788        struct sd *sd = (struct sd *) gspca_dev;
 789
 790        switch (sd->sensor) {
 791        case SENSOR_HV7131D: {
 792                /* Note the datasheet wrongly says line mode exposure uses reg
 793                   0x26 and 0x27, testing has shown 0x25 + 0x26 */
 794                __u8 i2c[] = {0xc0, 0x11, 0x25, 0x00, 0x00, 0x00, 0x00, 0x17};
 795                /* The HV7131D's exposure goes from 0 - 65535, we scale our
 796                   exposure of 0-1023 to 0-6138. There are 2 reasons for this:
 797                   1) This puts our exposure knee of 200 at approx the point
 798                      where the framerate starts dropping
 799                   2) At 6138 the framerate has already dropped to 2 fps,
 800                      going any lower makes little sense */
 801                u16 reg = sd->ctrls[EXPOSURE].val * 6;
 802
 803                i2c[3] = reg >> 8;
 804                i2c[4] = reg & 0xff;
 805                if (i2c_w(gspca_dev, i2c) != 0)
 806                        goto err;
 807                break;
 808            }
 809        case SENSOR_TAS5110C:
 810        case SENSOR_TAS5110D: {
 811                /* register 19's high nibble contains the sn9c10x clock divider
 812                   The high nibble configures the no fps according to the
 813                   formula: 60 / high_nibble. With a maximum of 30 fps */
 814                u8 reg = sd->ctrls[EXPOSURE].val;
 815
 816                reg = (reg << 4) | 0x0b;
 817                reg_w(gspca_dev, 0x19, &reg, 1);
 818                break;
 819            }
 820        case SENSOR_OV6650:
 821        case SENSOR_OV7630: {
 822                /* The ov6650 / ov7630 have 2 registers which both influence
 823                   exposure, register 11, whose low nibble sets the nr off fps
 824                   according to: fps = 30 / (low_nibble + 1)
 825
 826                   The fps configures the maximum exposure setting, but it is
 827                   possible to use less exposure then what the fps maximum
 828                   allows by setting register 10. register 10 configures the
 829                   actual exposure as quotient of the full exposure, with 0
 830                   being no exposure at all (not very useful) and reg10_max
 831                   being max exposure possible at that framerate.
 832
 833                   The code maps our 0 - 510 ms exposure ctrl to these 2
 834                   registers, trying to keep fps as high as possible.
 835                */
 836                __u8 i2c[] = {0xb0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10};
 837                int reg10, reg11, reg10_max;
 838
 839                /* ov6645 datasheet says reg10_max is 9a, but that uses
 840                   tline * 2 * reg10 as formula for calculating texpo, the
 841                   ov6650 probably uses the same formula as the 7730 which uses
 842                   tline * 4 * reg10, which explains why the reg10max we've
 843                   found experimentally for the ov6650 is exactly half that of
 844                   the ov6645. The ov7630 datasheet says the max is 0x41. */
 845                if (sd->sensor == SENSOR_OV6650) {
 846                        reg10_max = 0x4d;
 847                        i2c[4] = 0xc0; /* OV6650 needs non default vsync pol */
 848                } else
 849                        reg10_max = 0x41;
 850
 851                reg11 = (15 * sd->ctrls[EXPOSURE].val + 999) / 1000;
 852                if (reg11 < 1)
 853                        reg11 = 1;
 854                else if (reg11 > 16)
 855                        reg11 = 16;
 856
 857                /* In 640x480, if the reg11 has less than 4, the image is
 858                   unstable (the bridge goes into a higher compression mode
 859                   which we have not reverse engineered yet). */
 860                if (gspca_dev->width == 640 && reg11 < 4)
 861                        reg11 = 4;
 862
 863                /* frame exposure time in ms = 1000 * reg11 / 30    ->
 864                reg10 = (sd->ctrls[EXPOSURE].val / 2) * reg10_max
 865                                / (1000 * reg11 / 30) */
 866                reg10 = (sd->ctrls[EXPOSURE].val * 15 * reg10_max)
 867                                / (1000 * reg11);
 868
 869                /* Don't allow this to get below 10 when using autogain, the
 870                   steps become very large (relatively) when below 10 causing
 871                   the image to oscilate from much too dark, to much too bright
 872                   and back again. */
 873                if (sd->ctrls[AUTOGAIN].val && reg10 < 10)
 874                        reg10 = 10;
 875                else if (reg10 > reg10_max)
 876                        reg10 = reg10_max;
 877
 878                /* Write reg 10 and reg11 low nibble */
 879                i2c[1] = sensor_data[sd->sensor].sensor_addr;
 880                i2c[3] = reg10;
 881                i2c[4] |= reg11 - 1;
 882
 883                /* If register 11 didn't change, don't change it */
 884                if (sd->reg11 == reg11)
 885                        i2c[0] = 0xa0;
 886
 887                if (i2c_w(gspca_dev, i2c) == 0)
 888                        sd->reg11 = reg11;
 889                else
 890                        goto err;
 891                break;
 892            }
 893        case SENSOR_PAS202: {
 894                __u8 i2cpframerate[] =
 895                        {0xb0, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x16};
 896                __u8 i2cpexpo[] =
 897                        {0xa0, 0x40, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x16};
 898                const __u8 i2cpdoit[] =
 899                        {0xa0, 0x40, 0x11, 0x01, 0x00, 0x00, 0x00, 0x16};
 900                int framerate_ctrl;
 901
 902                /* The exposure knee for the autogain algorithm is 200
 903                   (100 ms / 10 fps on other sensors), for values below this
 904                   use the control for setting the partial frame expose time,
 905                   above that use variable framerate. This way we run at max
 906                   framerate (640x480@7.5 fps, 320x240@10fps) until the knee
 907                   is reached. Using the variable framerate control above 200
 908                   is better then playing around with both clockdiv + partial
 909                   frame exposure times (like we are doing with the ov chips),
 910                   as that sometimes leads to jumps in the exposure control,
 911                   which are bad for auto exposure. */
 912                if (sd->ctrls[EXPOSURE].val < 200) {
 913                        i2cpexpo[3] = 255 - (sd->ctrls[EXPOSURE].val * 255)
 914                                                / 200;
 915                        framerate_ctrl = 500;
 916                } else {
 917                        /* The PAS202's exposure control goes from 0 - 4095,
 918                           but anything below 500 causes vsync issues, so scale
 919                           our 200-1023 to 500-4095 */
 920                        framerate_ctrl = (sd->ctrls[EXPOSURE].val - 200)
 921                                                        * 1000 / 229 +  500;
 922                }
 923
 924                i2cpframerate[3] = framerate_ctrl >> 6;
 925                i2cpframerate[4] = framerate_ctrl & 0x3f;
 926                if (i2c_w(gspca_dev, i2cpframerate) < 0)
 927                        goto err;
 928                if (i2c_w(gspca_dev, i2cpexpo) < 0)
 929                        goto err;
 930                if (i2c_w(gspca_dev, i2cpdoit) < 0)
 931                        goto err;
 932                break;
 933            }
 934        case SENSOR_PAS106: {
 935                __u8 i2cpframerate[] =
 936                        {0xb1, 0x40, 0x03, 0x00, 0x00, 0x00, 0x00, 0x14};
 937                __u8 i2cpexpo[] =
 938                        {0xa1, 0x40, 0x05, 0x00, 0x00, 0x00, 0x00, 0x14};
 939                const __u8 i2cpdoit[] =
 940                        {0xa1, 0x40, 0x13, 0x01, 0x00, 0x00, 0x00, 0x14};
 941                int framerate_ctrl;
 942
 943                /* For values below 150 use partial frame exposure, above
 944                   that use framerate ctrl */
 945                if (sd->ctrls[EXPOSURE].val < 150) {
 946                        i2cpexpo[3] = 150 - sd->ctrls[EXPOSURE].val;
 947                        framerate_ctrl = 300;
 948                } else {
 949                        /* The PAS106's exposure control goes from 0 - 4095,
 950                           but anything below 300 causes vsync issues, so scale
 951                           our 150-1023 to 300-4095 */
 952                        framerate_ctrl = (sd->ctrls[EXPOSURE].val - 150)
 953                                                * 1000 / 230 + 300;
 954                }
 955
 956                i2cpframerate[3] = framerate_ctrl >> 4;
 957                i2cpframerate[4] = framerate_ctrl & 0x0f;
 958                if (i2c_w(gspca_dev, i2cpframerate) < 0)
 959                        goto err;
 960                if (i2c_w(gspca_dev, i2cpexpo) < 0)
 961                        goto err;
 962                if (i2c_w(gspca_dev, i2cpdoit) < 0)
 963                        goto err;
 964                break;
 965            }
 966        }
 967        return;
 968err:
 969        PDEBUG(D_ERR, "i2c error exposure");
 970}
 971
 972static void setfreq(struct gspca_dev *gspca_dev)
 973{
 974        struct sd *sd = (struct sd *) gspca_dev;
 975
 976        switch (sd->sensor) {
 977        case SENSOR_OV6650:
 978        case SENSOR_OV7630: {
 979                /* Framerate adjust register for artificial light 50 hz flicker
 980                   compensation, for the ov6650 this is identical to ov6630
 981                   0x2b register, see ov6630 datasheet.
 982                   0x4f / 0x8a -> (30 fps -> 25 fps), 0x00 -> no adjustment */
 983                __u8 i2c[] = {0xa0, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10};
 984                switch (sd->ctrls[FREQ].val) {
 985                default:
 986/*              case 0:                  * no filter*/
 987/*              case 2:                  * 60 hz */
 988                        i2c[3] = 0;
 989                        break;
 990                case 1:                 /* 50 hz */
 991                        i2c[3] = (sd->sensor == SENSOR_OV6650)
 992                                        ? 0x4f : 0x8a;
 993                        break;
 994                }
 995                i2c[1] = sensor_data[sd->sensor].sensor_addr;
 996                if (i2c_w(gspca_dev, i2c) < 0)
 997                        PDEBUG(D_ERR, "i2c error setfreq");
 998                break;
 999            }
1000        }
1001}
1002
1003#include "autogain_functions.h"
1004
1005static void do_autogain(struct gspca_dev *gspca_dev)
1006{
1007        int deadzone, desired_avg_lum, result;
1008        struct sd *sd = (struct sd *) gspca_dev;
1009        int avg_lum = atomic_read(&sd->avg_lum);
1010
1011        if ((gspca_dev->ctrl_dis & (1 << AUTOGAIN)) ||
1012            avg_lum == -1 || !sd->ctrls[AUTOGAIN].val)
1013                return;
1014
1015        if (sd->autogain_ignore_frames > 0) {
1016                sd->autogain_ignore_frames--;
1017                return;
1018        }
1019
1020        /* SIF / VGA sensors have a different autoexposure area and thus
1021           different avg_lum values for the same picture brightness */
1022        if (sensor_data[sd->sensor].flags & F_SIF) {
1023                deadzone = 500;
1024                /* SIF sensors tend to overexpose, so keep this small */
1025                desired_avg_lum = 5000;
1026        } else {
1027                deadzone = 1500;
1028                desired_avg_lum = 13000;
1029        }
1030
1031        if (sensor_data[sd->sensor].flags & F_COARSE_EXPO)
1032                result = coarse_grained_expo_autogain(gspca_dev, avg_lum,
1033                                sd->ctrls[BRIGHTNESS].val
1034                                                * desired_avg_lum / 127,
1035                                deadzone);
1036        else
1037                result = auto_gain_n_exposure(gspca_dev, avg_lum,
1038                                sd->ctrls[BRIGHTNESS].val
1039                                                * desired_avg_lum / 127,
1040                                deadzone, GAIN_KNEE, EXPOSURE_KNEE);
1041
1042        if (result) {
1043                PDEBUG(D_FRAM, "autogain: gain changed: gain: %d expo: %d",
1044                        (int) sd->ctrls[GAIN].val,
1045                        (int) sd->ctrls[EXPOSURE].val);
1046                sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
1047        }
1048}
1049
1050/* this function is called at probe time */
1051static int sd_config(struct gspca_dev *gspca_dev,
1052                        const struct usb_device_id *id)
1053{
1054        struct sd *sd = (struct sd *) gspca_dev;
1055        struct cam *cam;
1056
1057        reg_r(gspca_dev, 0x00);
1058        if (gspca_dev->usb_buf[0] != 0x10)
1059                return -ENODEV;
1060
1061        /* copy the webcam info from the device id */
1062        sd->sensor = id->driver_info >> 8;
1063        sd->bridge = id->driver_info & 0xff;
1064
1065        gspca_dev->ctrl_dis = sensor_data[sd->sensor].ctrl_dis;
1066#if AUTOGAIN_DEF
1067        if (!(gspca_dev->ctrl_dis & (1 << AUTOGAIN)))
1068                gspca_dev->ctrl_inac = (1 << GAIN) | (1 << EXPOSURE);
1069#endif
1070
1071        cam = &gspca_dev->cam;
1072        cam->ctrls = sd->ctrls;
1073        if (!(sensor_data[sd->sensor].flags & F_SIF)) {
1074                cam->cam_mode = vga_mode;
1075                cam->nmodes = ARRAY_SIZE(vga_mode);
1076        } else {
1077                cam->cam_mode = sif_mode;
1078                cam->nmodes = ARRAY_SIZE(sif_mode);
1079        }
1080        cam->npkt = 36;                 /* 36 packets per ISOC message */
1081
1082        if (sensor_data[sd->sensor].flags & F_COARSE_EXPO) {
1083                sd->ctrls[EXPOSURE].min = COARSE_EXPOSURE_MIN;
1084                sd->ctrls[EXPOSURE].max = COARSE_EXPOSURE_MAX;
1085                sd->ctrls[EXPOSURE].def = COARSE_EXPOSURE_DEF;
1086        }
1087
1088        return 0;
1089}
1090
1091/* this function is called at probe and resume time */
1092static int sd_init(struct gspca_dev *gspca_dev)
1093{
1094        const __u8 stop = 0x09; /* Disable stream turn of LED */
1095
1096        reg_w(gspca_dev, 0x01, &stop, 1);
1097
1098        return 0;
1099}
1100
1101/* -- start the camera -- */
1102static int sd_start(struct gspca_dev *gspca_dev)
1103{
1104        struct sd *sd = (struct sd *) gspca_dev;
1105        struct cam *cam = &gspca_dev->cam;
1106        int i, mode;
1107        __u8 regs[0x31];
1108
1109        mode = cam->cam_mode[gspca_dev->curr_mode].priv & 0x07;
1110        /* Copy registers 0x01 - 0x19 from the template */
1111        memcpy(&regs[0x01], sensor_data[sd->sensor].bridge_init, 0x19);
1112        /* Set the mode */
1113        regs[0x18] |= mode << 4;
1114
1115        /* Set bridge gain to 1.0 */
1116        if (sd->bridge == BRIDGE_103) {
1117                regs[0x05] = 0x20; /* Red */
1118                regs[0x06] = 0x20; /* Green */
1119                regs[0x07] = 0x20; /* Blue */
1120        } else {
1121                regs[0x10] = 0x00; /* Red and blue */
1122                regs[0x11] = 0x00; /* Green */
1123        }
1124
1125        /* Setup pixel numbers and auto exposure window */
1126        if (sensor_data[sd->sensor].flags & F_SIF) {
1127                regs[0x1a] = 0x14; /* HO_SIZE 640, makes no sense */
1128                regs[0x1b] = 0x0a; /* VO_SIZE 320, makes no sense */
1129                regs[0x1c] = 0x02; /* AE H-start 64 */
1130                regs[0x1d] = 0x02; /* AE V-start 64 */
1131                regs[0x1e] = 0x09; /* AE H-end 288 */
1132                regs[0x1f] = 0x07; /* AE V-end 224 */
1133        } else {
1134                regs[0x1a] = 0x1d; /* HO_SIZE 960, makes no sense */
1135                regs[0x1b] = 0x10; /* VO_SIZE 512, makes no sense */
1136                regs[0x1c] = 0x05; /* AE H-start 160 */
1137                regs[0x1d] = 0x03; /* AE V-start 96 */
1138                regs[0x1e] = 0x0f; /* AE H-end 480 */
1139                regs[0x1f] = 0x0c; /* AE V-end 384 */
1140        }
1141
1142        /* Setup the gamma table (only used with the sn9c103 bridge) */
1143        for (i = 0; i < 16; i++)
1144                regs[0x20 + i] = i * 16;
1145        regs[0x20 + i] = 255;
1146
1147        /* Special cases where some regs depend on mode or bridge */
1148        switch (sd->sensor) {
1149        case SENSOR_TAS5130CXX:
1150                /* FIXME / TESTME
1151                   probably not mode specific at all most likely the upper
1152                   nibble of 0x19 is exposure (clock divider) just as with
1153                   the tas5110, we need someone to test this. */
1154                regs[0x19] = mode ? 0x23 : 0x43;
1155                break;
1156        case SENSOR_OV7630:
1157                /* FIXME / TESTME for some reason with the 101/102 bridge the
1158                   clock is set to 12 Mhz (reg1 == 0x04), rather then 24.
1159                   Also the hstart needs to go from 1 to 2 when using a 103,
1160                   which is likely related. This does not seem right. */
1161                if (sd->bridge == BRIDGE_103) {
1162                        regs[0x01] = 0x44; /* Select 24 Mhz clock */
1163                        regs[0x12] = 0x02; /* Set hstart to 2 */
1164                }
1165        }
1166        /* Disable compression when the raw bayer format has been selected */
1167        if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW)
1168                regs[0x18] &= ~0x80;
1169
1170        /* Vga mode emulation on SIF sensor? */
1171        if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_REDUCED_SIF) {
1172                regs[0x12] += 16;       /* hstart adjust */
1173                regs[0x13] += 24;       /* vstart adjust */
1174                regs[0x15]  = 320 / 16; /* hsize */
1175                regs[0x16]  = 240 / 16; /* vsize */
1176        }
1177
1178        /* reg 0x01 bit 2 video transfert on */
1179        reg_w(gspca_dev, 0x01, &regs[0x01], 1);
1180        /* reg 0x17 SensorClk enable inv Clk 0x60 */
1181        reg_w(gspca_dev, 0x17, &regs[0x17], 1);
1182        /* Set the registers from the template */
1183        reg_w(gspca_dev, 0x01, &regs[0x01],
1184              (sd->bridge == BRIDGE_103) ? 0x30 : 0x1f);
1185
1186        /* Init the sensor */
1187        i2c_w_vector(gspca_dev, sensor_data[sd->sensor].sensor_init,
1188                        sensor_data[sd->sensor].sensor_init_size);
1189
1190        /* Mode / bridge specific sensor setup */
1191        switch (sd->sensor) {
1192        case SENSOR_PAS202: {
1193                const __u8 i2cpclockdiv[] =
1194                        {0xa0, 0x40, 0x02, 0x03, 0x00, 0x00, 0x00, 0x10};
1195                /* clockdiv from 4 to 3 (7.5 -> 10 fps) when in low res mode */
1196                if (mode)
1197                        i2c_w(gspca_dev, i2cpclockdiv);
1198                break;
1199            }
1200        case SENSOR_OV7630:
1201                /* FIXME / TESTME We should be able to handle this identical
1202                   for the 101/102 and the 103 case */
1203                if (sd->bridge == BRIDGE_103) {
1204                        const __u8 i2c[] = { 0xa0, 0x21, 0x13,
1205                                             0x80, 0x00, 0x00, 0x00, 0x10 };
1206                        i2c_w(gspca_dev, i2c);
1207                }
1208                break;
1209        }
1210        /* H_size V_size 0x28, 0x1e -> 640x480. 0x16, 0x12 -> 352x288 */
1211        reg_w(gspca_dev, 0x15, &regs[0x15], 2);
1212        /* compression register */
1213        reg_w(gspca_dev, 0x18, &regs[0x18], 1);
1214        /* H_start */
1215        reg_w(gspca_dev, 0x12, &regs[0x12], 1);
1216        /* V_START */
1217        reg_w(gspca_dev, 0x13, &regs[0x13], 1);
1218        /* reset 0x17 SensorClk enable inv Clk 0x60 */
1219                                /*fixme: ov7630 [17]=68 8f (+20 if 102)*/
1220        reg_w(gspca_dev, 0x17, &regs[0x17], 1);
1221        /*MCKSIZE ->3 */        /*fixme: not ov7630*/
1222        reg_w(gspca_dev, 0x19, &regs[0x19], 1);
1223        /* AE_STRX AE_STRY AE_ENDX AE_ENDY */
1224        reg_w(gspca_dev, 0x1c, &regs[0x1c], 4);
1225        /* Enable video transfert */
1226        reg_w(gspca_dev, 0x01, &regs[0x01], 1);
1227        /* Compression */
1228        reg_w(gspca_dev, 0x18, &regs[0x18], 2);
1229        msleep(20);
1230
1231        sd->reg11 = -1;
1232
1233        setgain(gspca_dev);
1234        setbrightness(gspca_dev);
1235        setexposure(gspca_dev);
1236        setfreq(gspca_dev);
1237
1238        sd->frames_to_drop = 0;
1239        sd->autogain_ignore_frames = 0;
1240        sd->exp_too_high_cnt = 0;
1241        sd->exp_too_low_cnt = 0;
1242        atomic_set(&sd->avg_lum, -1);
1243        return 0;
1244}
1245
1246static void sd_stopN(struct gspca_dev *gspca_dev)
1247{
1248        sd_init(gspca_dev);
1249}
1250
1251static u8* find_sof(struct gspca_dev *gspca_dev, u8 *data, int len)
1252{
1253        struct sd *sd = (struct sd *) gspca_dev;
1254        int i, header_size = (sd->bridge == BRIDGE_103) ? 18 : 12;
1255
1256        /* frames start with:
1257         *      ff ff 00 c4 c4 96       synchro
1258         *      00              (unknown)
1259         *      xx              (frame sequence / size / compression)
1260         *      (xx)            (idem - extra byte for sn9c103)
1261         *      ll mm           brightness sum inside auto exposure
1262         *      ll mm           brightness sum outside auto exposure
1263         *      (xx xx xx xx xx)        audio values for snc103
1264         */
1265        for (i = 0; i < len; i++) {
1266                switch (sd->header_read) {
1267                case 0:
1268                        if (data[i] == 0xff)
1269                                sd->header_read++;
1270                        break;
1271                case 1:
1272                        if (data[i] == 0xff)
1273                                sd->header_read++;
1274                        else
1275                                sd->header_read = 0;
1276                        break;
1277                case 2:
1278                        if (data[i] == 0x00)
1279                                sd->header_read++;
1280                        else if (data[i] != 0xff)
1281                                sd->header_read = 0;
1282                        break;
1283                case 3:
1284                        if (data[i] == 0xc4)
1285                                sd->header_read++;
1286                        else if (data[i] == 0xff)
1287                                sd->header_read = 1;
1288                        else
1289                                sd->header_read = 0;
1290                        break;
1291                case 4:
1292                        if (data[i] == 0xc4)
1293                                sd->header_read++;
1294                        else if (data[i] == 0xff)
1295                                sd->header_read = 1;
1296                        else
1297                                sd->header_read = 0;
1298                        break;
1299                case 5:
1300                        if (data[i] == 0x96)
1301                                sd->header_read++;
1302                        else if (data[i] == 0xff)
1303                                sd->header_read = 1;
1304                        else
1305                                sd->header_read = 0;
1306                        break;
1307                default:
1308                        sd->header[sd->header_read - 6] = data[i];
1309                        sd->header_read++;
1310                        if (sd->header_read == header_size) {
1311                                sd->header_read = 0;
1312                                return data + i + 1;
1313                        }
1314                }
1315        }
1316        return NULL;
1317}
1318
1319static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1320                        u8 *data,                       /* isoc packet */
1321                        int len)                        /* iso packet length */
1322{
1323        int fr_h_sz = 0, lum_offset = 0, len_after_sof = 0;
1324        struct sd *sd = (struct sd *) gspca_dev;
1325        struct cam *cam = &gspca_dev->cam;
1326        u8 *sof;
1327
1328        sof = find_sof(gspca_dev, data, len);
1329        if (sof) {
1330                if (sd->bridge == BRIDGE_103) {
1331                        fr_h_sz = 18;
1332                        lum_offset = 3;
1333                } else {
1334                        fr_h_sz = 12;
1335                        lum_offset = 2;
1336                }
1337
1338                len_after_sof = len - (sof - data);
1339                len = (sof - data) - fr_h_sz;
1340                if (len < 0)
1341                        len = 0;
1342        }
1343
1344        if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW) {
1345                /* In raw mode we sometimes get some garbage after the frame
1346                   ignore this */
1347                int used;
1348                int size = cam->cam_mode[gspca_dev->curr_mode].sizeimage;
1349
1350                used = gspca_dev->image_len;
1351                if (used + len > size)
1352                        len = size - used;
1353        }
1354
1355        gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
1356
1357        if (sof) {
1358                int  lum = sd->header[lum_offset] +
1359                          (sd->header[lum_offset + 1] << 8);
1360
1361                /* When exposure changes midway a frame we
1362                   get a lum of 0 in this case drop 2 frames
1363                   as the frames directly after an exposure
1364                   change have an unstable image. Sometimes lum
1365                   *really* is 0 (cam used in low light with
1366                   low exposure setting), so do not drop frames
1367                   if the previous lum was 0 too. */
1368                if (lum == 0 && sd->prev_avg_lum != 0) {
1369                        lum = -1;
1370                        sd->frames_to_drop = 2;
1371                        sd->prev_avg_lum = 0;
1372                } else
1373                        sd->prev_avg_lum = lum;
1374                atomic_set(&sd->avg_lum, lum);
1375
1376                if (sd->frames_to_drop)
1377                        sd->frames_to_drop--;
1378                else
1379                        gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
1380
1381                gspca_frame_add(gspca_dev, FIRST_PACKET, sof, len_after_sof);
1382        }
1383}
1384
1385static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1386{
1387        struct sd *sd = (struct sd *) gspca_dev;
1388
1389        sd->ctrls[AUTOGAIN].val = val;
1390        sd->exp_too_high_cnt = 0;
1391        sd->exp_too_low_cnt = 0;
1392
1393        /* when switching to autogain set defaults to make sure
1394           we are on a valid point of the autogain gain /
1395           exposure knee graph, and give this change time to
1396           take effect before doing autogain. */
1397        if (sd->ctrls[AUTOGAIN].val
1398         && !(sensor_data[sd->sensor].flags & F_COARSE_EXPO)) {
1399                sd->ctrls[EXPOSURE].val = sd->ctrls[EXPOSURE].def;
1400                sd->ctrls[GAIN].val = sd->ctrls[GAIN].def;
1401                if (gspca_dev->streaming) {
1402                        sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
1403                        setexposure(gspca_dev);
1404                        setgain(gspca_dev);
1405                }
1406        }
1407
1408        if (sd->ctrls[AUTOGAIN].val)
1409                gspca_dev->ctrl_inac = (1 << GAIN) | (1 << EXPOSURE);
1410        else
1411                gspca_dev->ctrl_inac = 0;
1412
1413        return 0;
1414}
1415
1416static int sd_querymenu(struct gspca_dev *gspca_dev,
1417                        struct v4l2_querymenu *menu)
1418{
1419        switch (menu->id) {
1420        case V4L2_CID_POWER_LINE_FREQUENCY:
1421                switch (menu->index) {
1422                case 0:         /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
1423                        strcpy((char *) menu->name, "NoFliker");
1424                        return 0;
1425                case 1:         /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
1426                        strcpy((char *) menu->name, "50 Hz");
1427                        return 0;
1428                case 2:         /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
1429                        strcpy((char *) menu->name, "60 Hz");
1430                        return 0;
1431                }
1432                break;
1433        }
1434        return -EINVAL;
1435}
1436
1437#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
1438static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
1439                        u8 *data,               /* interrupt packet data */
1440                        int len)                /* interrupt packet length */
1441{
1442        int ret = -EINVAL;
1443
1444        if (len == 1 && data[0] == 1) {
1445                input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
1446                input_sync(gspca_dev->input_dev);
1447                input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
1448                input_sync(gspca_dev->input_dev);
1449                ret = 0;
1450        }
1451
1452        return ret;
1453}
1454#endif
1455
1456/* sub-driver description */
1457static const struct sd_desc sd_desc = {
1458        .name = MODULE_NAME,
1459        .ctrls = sd_ctrls,
1460        .nctrls = ARRAY_SIZE(sd_ctrls),
1461        .config = sd_config,
1462        .init = sd_init,
1463        .start = sd_start,
1464        .stopN = sd_stopN,
1465        .pkt_scan = sd_pkt_scan,
1466        .querymenu = sd_querymenu,
1467        .dq_callback = do_autogain,
1468#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
1469        .int_pkt_scan = sd_int_pkt_scan,
1470#endif
1471};
1472
1473/* -- module initialisation -- */
1474#define SB(sensor, bridge) \
1475        .driver_info = (SENSOR_ ## sensor << 8) | BRIDGE_ ## bridge
1476
1477
1478static const struct usb_device_id device_table[] = {
1479        {USB_DEVICE(0x0c45, 0x6001), SB(TAS5110C, 102)}, /* TAS5110C1B */
1480        {USB_DEVICE(0x0c45, 0x6005), SB(TAS5110C, 101)}, /* TAS5110C1B */
1481        {USB_DEVICE(0x0c45, 0x6007), SB(TAS5110D, 101)}, /* TAS5110D */
1482        {USB_DEVICE(0x0c45, 0x6009), SB(PAS106, 101)},
1483        {USB_DEVICE(0x0c45, 0x600d), SB(PAS106, 101)},
1484        {USB_DEVICE(0x0c45, 0x6011), SB(OV6650, 101)},
1485        {USB_DEVICE(0x0c45, 0x6019), SB(OV7630, 101)},
1486#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1487        {USB_DEVICE(0x0c45, 0x6024), SB(TAS5130CXX, 102)},
1488        {USB_DEVICE(0x0c45, 0x6025), SB(TAS5130CXX, 102)},
1489#endif
1490        {USB_DEVICE(0x0c45, 0x6028), SB(PAS202, 102)},
1491        {USB_DEVICE(0x0c45, 0x6029), SB(PAS106, 102)},
1492        {USB_DEVICE(0x0c45, 0x602a), SB(HV7131D, 102)},
1493        /* {USB_DEVICE(0x0c45, 0x602b), SB(MI0343, 102)}, */
1494        {USB_DEVICE(0x0c45, 0x602c), SB(OV7630, 102)},
1495        {USB_DEVICE(0x0c45, 0x602d), SB(HV7131R, 102)},
1496        {USB_DEVICE(0x0c45, 0x602e), SB(OV7630, 102)},
1497        /* {USB_DEVICE(0x0c45, 0x6030), SB(MI03XX, 102)}, */ /* MI0343 MI0360 MI0330 */
1498        /* {USB_DEVICE(0x0c45, 0x6082), SB(MI03XX, 103)}, */ /* MI0343 MI0360 */
1499        {USB_DEVICE(0x0c45, 0x6083), SB(HV7131D, 103)},
1500        {USB_DEVICE(0x0c45, 0x608c), SB(HV7131R, 103)},
1501        /* {USB_DEVICE(0x0c45, 0x608e), SB(CISVF10, 103)}, */
1502        {USB_DEVICE(0x0c45, 0x608f), SB(OV7630, 103)},
1503        {USB_DEVICE(0x0c45, 0x60a8), SB(PAS106, 103)},
1504        {USB_DEVICE(0x0c45, 0x60aa), SB(TAS5130CXX, 103)},
1505        {USB_DEVICE(0x0c45, 0x60af), SB(PAS202, 103)},
1506        {USB_DEVICE(0x0c45, 0x60b0), SB(OV7630, 103)},
1507        {}
1508};
1509MODULE_DEVICE_TABLE(usb, device_table);
1510
1511/* -- device connect -- */
1512static int sd_probe(struct usb_interface *intf,
1513                        const struct usb_device_id *id)
1514{
1515        return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1516                                THIS_MODULE);
1517}
1518
1519static struct usb_driver sd_driver = {
1520        .name = MODULE_NAME,
1521        .id_table = device_table,
1522        .probe = sd_probe,
1523        .disconnect = gspca_disconnect,
1524#ifdef CONFIG_PM
1525        .suspend = gspca_suspend,
1526        .resume = gspca_resume,
1527#endif
1528};
1529
1530/* -- module insert / remove -- */
1531static int __init sd_mod_init(void)
1532{
1533        return usb_register(&sd_driver);
1534}
1535static void __exit sd_mod_exit(void)
1536{
1537        usb_deregister(&sd_driver);
1538}
1539
1540module_init(sd_mod_init);
1541module_exit(sd_mod_exit);
1542