linux/drivers/media/video/gspca/sonixb.c
<<
>>
Prefs
   1/*
   2 *              sonix sn9c102 (bayer) library
   3 *              Copyright (C) 2003 2004 Michel Xhaard mxhaard@magic.fr
   4 * Add Pas106 Stefano Mozzi (C) 2004
   5 *
   6 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
   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
  260x10    high nibble red gain low nibble blue gain
  270x11    low nibble green gain
  280x12    hstart
  290x13    vstart
  300x15    hsize (hsize = register-value * 16)
  310x16    vsize (vsize = register-value * 16)
  320x17    bit 0 toggle compression quality (according to sn9c102 driver)
  330x18    bit 7 enables compression, bit 4-5 set image down scaling:
  34        00 scale 1, 01 scale 1/2, 10, scale 1/4
  350x19    high-nibble is sensor clock divider, changes exposure on sensors which
  36        use a clock generated by the bridge. Some sensors have their own clock.
  370x1c    auto_exposure area (for avg_lum) startx (startx = register-value * 32)
  380x1d    auto_exposure area (for avg_lum) starty (starty = register-value * 32)
  390x1e    auto_exposure area (for avg_lum) stopx (hsize = (0x1e - 0x1c) * 32)
  400x1f    auto_exposure area (for avg_lum) stopy (vsize = (0x1f - 0x1d) * 32)
  41*/
  42
  43#define MODULE_NAME "sonixb"
  44
  45#include "gspca.h"
  46
  47MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
  48MODULE_DESCRIPTION("GSPCA/SN9C102 USB Camera Driver");
  49MODULE_LICENSE("GPL");
  50
  51/* specific webcam descriptor */
  52struct sd {
  53        struct gspca_dev gspca_dev;     /* !! must be the first item */
  54        atomic_t avg_lum;
  55        int prev_avg_lum;
  56
  57        unsigned char gain;
  58        unsigned char exposure;
  59        unsigned char brightness;
  60        unsigned char autogain;
  61        unsigned char autogain_ignore_frames;
  62        unsigned char frames_to_drop;
  63        unsigned char freq;             /* light freq filter setting */
  64
  65        __u8 bridge;                    /* Type of bridge */
  66#define BRIDGE_101 0
  67#define BRIDGE_102 0 /* We make no difference between 101 and 102 */
  68#define BRIDGE_103 1
  69
  70        __u8 sensor;                    /* Type of image sensor chip */
  71#define SENSOR_HV7131R 0
  72#define SENSOR_OV6650 1
  73#define SENSOR_OV7630 2
  74#define SENSOR_PAS106 3
  75#define SENSOR_PAS202 4
  76#define SENSOR_TAS5110 5
  77#define SENSOR_TAS5130CXX 6
  78        __u8 reg11;
  79};
  80
  81typedef const __u8 sensor_init_t[8];
  82
  83struct sensor_data {
  84        const __u8 *bridge_init[2];
  85        int bridge_init_size[2];
  86        sensor_init_t *sensor_init;
  87        int sensor_init_size;
  88        sensor_init_t *sensor_bridge_init[2];
  89        int sensor_bridge_init_size[2];
  90        int flags;
  91        unsigned ctrl_dis;
  92        __u8 sensor_addr;
  93};
  94
  95/* sensor_data flags */
  96#define F_GAIN 0x01             /* has gain */
  97#define F_SIF  0x02             /* sif or vga */
  98
  99/* priv field of struct v4l2_pix_format flags (do not use low nibble!) */
 100#define MODE_RAW 0x10           /* raw bayer mode */
 101#define MODE_REDUCED_SIF 0x20   /* vga mode (320x240 / 160x120) on sif cam */
 102
 103/* ctrl_dis helper macros */
 104#define NO_EXPO ((1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX))
 105#define NO_FREQ (1 << FREQ_IDX)
 106#define NO_BRIGHTNESS (1 << BRIGHTNESS_IDX)
 107
 108#define COMP2 0x8f
 109#define COMP 0xc7               /* 0x87 //0x07 */
 110#define COMP1 0xc9              /* 0x89 //0x09 */
 111
 112#define MCK_INIT 0x63
 113#define MCK_INIT1 0x20          /*fixme: Bayer - 0x50 for JPEG ??*/
 114
 115#define SYS_CLK 0x04
 116
 117#define SENS(bridge_1, bridge_3, sensor, sensor_1, \
 118        sensor_3, _flags, _ctrl_dis, _sensor_addr) \
 119{ \
 120        .bridge_init = { bridge_1, bridge_3 }, \
 121        .bridge_init_size = { sizeof(bridge_1), sizeof(bridge_3) }, \
 122        .sensor_init = sensor, \
 123        .sensor_init_size = sizeof(sensor), \
 124        .sensor_bridge_init = { sensor_1, sensor_3,}, \
 125        .sensor_bridge_init_size = { sizeof(sensor_1), sizeof(sensor_3)}, \
 126        .flags = _flags, .ctrl_dis = _ctrl_dis, .sensor_addr = _sensor_addr \
 127}
 128
 129/* We calculate the autogain at the end of the transfer of a frame, at this
 130   moment a frame with the old settings is being transmitted, and a frame is
 131   being captured with the old settings. So if we adjust the autogain we must
 132   ignore atleast the 2 next frames for the new settings to come into effect
 133   before doing any other adjustments */
 134#define AUTOGAIN_IGNORE_FRAMES 3
 135
 136/* V4L2 controls supported by the driver */
 137static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
 138static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
 139static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
 140static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
 141static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
 142static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
 143static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
 144static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
 145static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
 146static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
 147
 148static struct ctrl sd_ctrls[] = {
 149#define BRIGHTNESS_IDX 0
 150        {
 151            {
 152                .id      = V4L2_CID_BRIGHTNESS,
 153                .type    = V4L2_CTRL_TYPE_INTEGER,
 154                .name    = "Brightness",
 155                .minimum = 0,
 156                .maximum = 255,
 157                .step    = 1,
 158#define BRIGHTNESS_DEF 127
 159                .default_value = BRIGHTNESS_DEF,
 160            },
 161            .set = sd_setbrightness,
 162            .get = sd_getbrightness,
 163        },
 164#define GAIN_IDX 1
 165        {
 166            {
 167                .id      = V4L2_CID_GAIN,
 168                .type    = V4L2_CTRL_TYPE_INTEGER,
 169                .name    = "Gain",
 170                .minimum = 0,
 171                .maximum = 255,
 172                .step    = 1,
 173#define GAIN_DEF 127
 174#define GAIN_KNEE 200
 175                .default_value = GAIN_DEF,
 176            },
 177            .set = sd_setgain,
 178            .get = sd_getgain,
 179        },
 180#define EXPOSURE_IDX 2
 181        {
 182                {
 183                        .id = V4L2_CID_EXPOSURE,
 184                        .type = V4L2_CTRL_TYPE_INTEGER,
 185                        .name = "Exposure",
 186#define EXPOSURE_DEF  16 /*  32 ms / 30 fps */
 187#define EXPOSURE_KNEE 50 /* 100 ms / 10 fps */
 188                        .minimum = 0,
 189                        .maximum = 255,
 190                        .step = 1,
 191                        .default_value = EXPOSURE_DEF,
 192                        .flags = 0,
 193                },
 194                .set = sd_setexposure,
 195                .get = sd_getexposure,
 196        },
 197#define AUTOGAIN_IDX 3
 198        {
 199                {
 200                        .id = V4L2_CID_AUTOGAIN,
 201                        .type = V4L2_CTRL_TYPE_BOOLEAN,
 202                        .name = "Automatic Gain (and Exposure)",
 203                        .minimum = 0,
 204                        .maximum = 1,
 205                        .step = 1,
 206#define AUTOGAIN_DEF 1
 207                        .default_value = AUTOGAIN_DEF,
 208                        .flags = 0,
 209                },
 210                .set = sd_setautogain,
 211                .get = sd_getautogain,
 212        },
 213#define FREQ_IDX 4
 214        {
 215                {
 216                        .id      = V4L2_CID_POWER_LINE_FREQUENCY,
 217                        .type    = V4L2_CTRL_TYPE_MENU,
 218                        .name    = "Light frequency filter",
 219                        .minimum = 0,
 220                        .maximum = 2,   /* 0: 0, 1: 50Hz, 2:60Hz */
 221                        .step    = 1,
 222#define FREQ_DEF 1
 223                        .default_value = FREQ_DEF,
 224                },
 225                .set = sd_setfreq,
 226                .get = sd_getfreq,
 227        },
 228};
 229
 230static const struct v4l2_pix_format vga_mode[] = {
 231        {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
 232                .bytesperline = 160,
 233                .sizeimage = 160 * 120,
 234                .colorspace = V4L2_COLORSPACE_SRGB,
 235                .priv = 2 | MODE_RAW},
 236        {160, 120, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
 237                .bytesperline = 160,
 238                .sizeimage = 160 * 120 * 5 / 4,
 239                .colorspace = V4L2_COLORSPACE_SRGB,
 240                .priv = 2},
 241        {320, 240, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
 242                .bytesperline = 320,
 243                .sizeimage = 320 * 240 * 5 / 4,
 244                .colorspace = V4L2_COLORSPACE_SRGB,
 245                .priv = 1},
 246        {640, 480, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
 247                .bytesperline = 640,
 248                .sizeimage = 640 * 480 * 5 / 4,
 249                .colorspace = V4L2_COLORSPACE_SRGB,
 250                .priv = 0},
 251};
 252static const struct v4l2_pix_format sif_mode[] = {
 253        {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
 254                .bytesperline = 160,
 255                .sizeimage = 160 * 120,
 256                .colorspace = V4L2_COLORSPACE_SRGB,
 257                .priv = 1 | MODE_RAW | MODE_REDUCED_SIF},
 258        {160, 120, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
 259                .bytesperline = 160,
 260                .sizeimage = 160 * 120 * 5 / 4,
 261                .colorspace = V4L2_COLORSPACE_SRGB,
 262                .priv = 1 | MODE_REDUCED_SIF},
 263        {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
 264                .bytesperline = 176,
 265                .sizeimage = 176 * 144,
 266                .colorspace = V4L2_COLORSPACE_SRGB,
 267                .priv = 1 | MODE_RAW},
 268        {176, 144, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
 269                .bytesperline = 176,
 270                .sizeimage = 176 * 144 * 5 / 4,
 271                .colorspace = V4L2_COLORSPACE_SRGB,
 272                .priv = 1},
 273        {320, 240, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
 274                .bytesperline = 320,
 275                .sizeimage = 320 * 240 * 5 / 4,
 276                .colorspace = V4L2_COLORSPACE_SRGB,
 277                .priv = 0 | MODE_REDUCED_SIF},
 278        {352, 288, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
 279                .bytesperline = 352,
 280                .sizeimage = 352 * 288 * 5 / 4,
 281                .colorspace = V4L2_COLORSPACE_SRGB,
 282                .priv = 0},
 283};
 284
 285static const __u8 initHv7131[] = {
 286        0x46, 0x77, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00,
 287        0x00, 0x00,
 288        0x00, 0x00, 0x00, 0x02, 0x01, 0x00,
 289        0x28, 0x1e, 0x60, 0x8a, 0x20,
 290        0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c
 291};
 292static const __u8 hv7131_sensor_init[][8] = {
 293        {0xc0, 0x11, 0x31, 0x38, 0x2a, 0x2e, 0x00, 0x10},
 294        {0xa0, 0x11, 0x01, 0x08, 0x2a, 0x2e, 0x00, 0x10},
 295        {0xb0, 0x11, 0x20, 0x00, 0xd0, 0x2e, 0x00, 0x10},
 296        {0xc0, 0x11, 0x25, 0x03, 0x0e, 0x28, 0x00, 0x16},
 297        {0xa0, 0x11, 0x30, 0x10, 0x0e, 0x28, 0x00, 0x15},
 298};
 299static const __u8 initOv6650[] = {
 300        0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
 301        0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 302        0x00, 0x01, 0x01, 0x0a, 0x16, 0x12, 0x68, 0x8b,
 303        0x10, 0x1d, 0x10, 0x02, 0x02, 0x09, 0x07
 304};
 305static const __u8 ov6650_sensor_init[][8] =
 306{
 307        /* Bright, contrast, etc are set througth SCBB interface.
 308         * AVCAP on win2 do not send any data on this   controls. */
 309        /* Anyway, some registers appears to alter bright and constrat */
 310
 311        /* Reset sensor */
 312        {0xa0, 0x60, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},
 313        /* Set clock register 0x11 low nibble is clock divider */
 314        {0xd0, 0x60, 0x11, 0xc0, 0x1b, 0x18, 0xc1, 0x10},
 315        /* Next some unknown stuff */
 316        {0xb0, 0x60, 0x15, 0x00, 0x02, 0x18, 0xc1, 0x10},
 317/*      {0xa0, 0x60, 0x1b, 0x01, 0x02, 0x18, 0xc1, 0x10},
 318                 * THIS SET GREEN SCREEN
 319                 * (pixels could be innverted in decode kind of "brg",
 320                 * but blue wont be there. Avoid this data ... */
 321        {0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10}, /* format out? */
 322        {0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10},
 323        {0xa0, 0x60, 0x30, 0x3d, 0x0A, 0xd8, 0xa4, 0x10},
 324        /* Enable rgb brightness control */
 325        {0xa0, 0x60, 0x61, 0x08, 0x00, 0x00, 0x00, 0x10},
 326        /* HDG: Note windows uses the line below, which sets both register 0x60
 327           and 0x61 I believe these registers of the ov6650 are identical as
 328           those of the ov7630, because if this is true the windows settings
 329           add a bit additional red gain and a lot additional blue gain, which
 330           matches my findings that the windows settings make blue much too
 331           blue and red a little too red.
 332        {0xb0, 0x60, 0x60, 0x66, 0x68, 0xd8, 0xa4, 0x10}, */
 333        /* Some more unknown stuff */
 334        {0xa0, 0x60, 0x68, 0x04, 0x68, 0xd8, 0xa4, 0x10},
 335        {0xd0, 0x60, 0x17, 0x24, 0xd6, 0x04, 0x94, 0x10}, /* Clipreg */
 336};
 337
 338static const __u8 initOv7630[] = {
 339        0x04, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* r01 .. r08 */
 340        0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* r09 .. r10 */
 341        0x00, 0x01, 0x01, 0x0a,                         /* r11 .. r14 */
 342        0x28, 0x1e,                     /* H & V sizes     r15 .. r16 */
 343        0x68, COMP2, MCK_INIT1,                         /* r17 .. r19 */
 344        0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c              /* r1a .. r1f */
 345};
 346static const __u8 initOv7630_3[] = {
 347        0x44, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0x80, /* r01 .. r08 */
 348        0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, /* r09 .. r10 */
 349        0x00, 0x02, 0x01, 0x0a,                         /* r11 .. r14 */
 350        0x28, 0x1e,                     /* H & V sizes     r15 .. r16 */
 351        0x68, 0x8f, MCK_INIT1,                          /* r17 .. r19 */
 352        0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c, 0x00,       /* r1a .. r20 */
 353        0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, /* r21 .. r28 */
 354        0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0, 0xff  /* r29 .. r30 */
 355};
 356static const __u8 ov7630_sensor_init[][8] = {
 357        {0xa0, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},
 358        {0xb0, 0x21, 0x01, 0x77, 0x3a, 0x00, 0x00, 0x10},
 359/*      {0xd0, 0x21, 0x12, 0x7c, 0x01, 0x80, 0x34, 0x10},          jfm */
 360        {0xd0, 0x21, 0x12, 0x1c, 0x00, 0x80, 0x34, 0x10},       /* jfm */
 361        {0xa0, 0x21, 0x1b, 0x04, 0x00, 0x80, 0x34, 0x10},
 362        {0xa0, 0x21, 0x20, 0x44, 0x00, 0x80, 0x34, 0x10},
 363        {0xa0, 0x21, 0x23, 0xee, 0x00, 0x80, 0x34, 0x10},
 364        {0xd0, 0x21, 0x26, 0xa0, 0x9a, 0xa0, 0x30, 0x10},
 365        {0xb0, 0x21, 0x2a, 0x80, 0x00, 0xa0, 0x30, 0x10},
 366        {0xb0, 0x21, 0x2f, 0x3d, 0x24, 0xa0, 0x30, 0x10},
 367        {0xa0, 0x21, 0x32, 0x86, 0x24, 0xa0, 0x30, 0x10},
 368        {0xb0, 0x21, 0x60, 0xa9, 0x4a, 0xa0, 0x30, 0x10},
 369/*      {0xb0, 0x21, 0x60, 0xa9, 0x42, 0xa0, 0x30, 0x10},        * jfm */
 370        {0xa0, 0x21, 0x65, 0x00, 0x42, 0xa0, 0x30, 0x10},
 371        {0xa0, 0x21, 0x69, 0x38, 0x42, 0xa0, 0x30, 0x10},
 372        {0xc0, 0x21, 0x6f, 0x88, 0x0b, 0x00, 0x30, 0x10},
 373        {0xc0, 0x21, 0x74, 0x21, 0x8e, 0x00, 0x30, 0x10},
 374        {0xa0, 0x21, 0x7d, 0xf7, 0x8e, 0x00, 0x30, 0x10},
 375        {0xd0, 0x21, 0x17, 0x1c, 0xbd, 0x06, 0xf6, 0x10},
 376};
 377
 378static const __u8 ov7630_sensor_init_3[][8] = {
 379        {0xa0, 0x21, 0x13, 0x80, 0x00,  0x00, 0x00, 0x10},
 380};
 381
 382static const __u8 initPas106[] = {
 383        0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x00, 0x00,
 384        0x00, 0x00,
 385        0x00, 0x00, 0x00, 0x04, 0x01, 0x00,
 386        0x16, 0x12, 0x24, COMP1, MCK_INIT1,
 387        0x18, 0x10, 0x02, 0x02, 0x09, 0x07
 388};
 389/* compression 0x86 mckinit1 0x2b */
 390static const __u8 pas106_sensor_init[][8] = {
 391        /* Pixel Clock Divider 6 */
 392        { 0xa1, 0x40, 0x02, 0x04, 0x00, 0x00, 0x00, 0x14 },
 393        /* Frame Time MSB (also seen as 0x12) */
 394        { 0xa1, 0x40, 0x03, 0x13, 0x00, 0x00, 0x00, 0x14 },
 395        /* Frame Time LSB (also seen as 0x05) */
 396        { 0xa1, 0x40, 0x04, 0x06, 0x00, 0x00, 0x00, 0x14 },
 397        /* Shutter Time Line Offset (also seen as 0x6d) */
 398        { 0xa1, 0x40, 0x05, 0x65, 0x00, 0x00, 0x00, 0x14 },
 399        /* Shutter Time Pixel Offset (also seen as 0xb1) */
 400        { 0xa1, 0x40, 0x06, 0xcd, 0x00, 0x00, 0x00, 0x14 },
 401        /* Black Level Subtract Sign (also seen 0x00) */
 402        { 0xa1, 0x40, 0x07, 0xc1, 0x00, 0x00, 0x00, 0x14 },
 403        /* Black Level Subtract Level (also seen 0x01) */
 404        { 0xa1, 0x40, 0x08, 0x06, 0x00, 0x00, 0x00, 0x14 },
 405        { 0xa1, 0x40, 0x08, 0x06, 0x00, 0x00, 0x00, 0x14 },
 406        /* Color Gain B Pixel 5 a */
 407        { 0xa1, 0x40, 0x09, 0x05, 0x00, 0x00, 0x00, 0x14 },
 408        /* Color Gain G1 Pixel 1 5 */
 409        { 0xa1, 0x40, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x14 },
 410        /* Color Gain G2 Pixel 1 0 5 */
 411        { 0xa1, 0x40, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x14 },
 412        /* Color Gain R Pixel 3 1 */
 413        { 0xa1, 0x40, 0x0c, 0x05, 0x00, 0x00, 0x00, 0x14 },
 414        /* Color GainH  Pixel */
 415        { 0xa1, 0x40, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x14 },
 416        /* Global Gain */
 417        { 0xa1, 0x40, 0x0e, 0x0e, 0x00, 0x00, 0x00, 0x14 },
 418        /* Contrast */
 419        { 0xa1, 0x40, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x14 },
 420        /* H&V synchro polarity */
 421        { 0xa1, 0x40, 0x10, 0x06, 0x00, 0x00, 0x00, 0x14 },
 422        /* ?default */
 423        { 0xa1, 0x40, 0x11, 0x06, 0x00, 0x00, 0x00, 0x14 },
 424        /* DAC scale */
 425        { 0xa1, 0x40, 0x12, 0x06, 0x00, 0x00, 0x00, 0x14 },
 426        /* ?default */
 427        { 0xa1, 0x40, 0x14, 0x02, 0x00, 0x00, 0x00, 0x14 },
 428        /* Validate Settings */
 429        { 0xa1, 0x40, 0x13, 0x01, 0x00, 0x00, 0x00, 0x14 },
 430};
 431
 432static const __u8 initPas202[] = {
 433        0x44, 0x44, 0x21, 0x30, 0x00, 0x00, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00,
 434        0x00, 0x00,
 435        0x00, 0x00, 0x00, 0x06, 0x03, 0x0a,
 436        0x28, 0x1e, 0x28, 0x89, 0x20,
 437        0x00, 0x00, 0x02, 0x03, 0x0f, 0x0c
 438};
 439static const __u8 pas202_sensor_init[][8] = {
 440        {0xa0, 0x40, 0x02, 0x03, 0x00, 0x00, 0x00, 0x10},
 441        {0xd0, 0x40, 0x04, 0x07, 0x34, 0x00, 0x09, 0x10},
 442        {0xd0, 0x40, 0x08, 0x01, 0x00, 0x00, 0x01, 0x10},
 443        {0xd0, 0x40, 0x0C, 0x00, 0x0C, 0x00, 0x32, 0x10},
 444        {0xd0, 0x40, 0x10, 0x00, 0x01, 0x00, 0x63, 0x10},
 445        {0xa0, 0x40, 0x15, 0x70, 0x01, 0x00, 0x63, 0x10},
 446        {0xa0, 0x40, 0x18, 0x00, 0x01, 0x00, 0x63, 0x10},
 447        {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10},
 448        {0xa0, 0x40, 0x03, 0x56, 0x01, 0x00, 0x63, 0x10},
 449        {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10},
 450        {0xb0, 0x40, 0x04, 0x07, 0x2a, 0x00, 0x63, 0x10},
 451        {0xb0, 0x40, 0x0e, 0x00, 0x3d, 0x00, 0x63, 0x10},
 452
 453        {0xa0, 0x40, 0x11, 0x01, 0x3d, 0x00, 0x63, 0x16},
 454        {0xa0, 0x40, 0x10, 0x08, 0x3d, 0x00, 0x63, 0x15},
 455        {0xa0, 0x40, 0x02, 0x04, 0x3d, 0x00, 0x63, 0x16},
 456        {0xa0, 0x40, 0x11, 0x01, 0x3d, 0x00, 0x63, 0x16},
 457        {0xb0, 0x40, 0x0e, 0x00, 0x31, 0x00, 0x63, 0x16},
 458        {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16},
 459        {0xa0, 0x40, 0x10, 0x0e, 0x31, 0x00, 0x63, 0x15},
 460        {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16},
 461};
 462
 463static const __u8 initTas5110[] = {
 464        0x44, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
 465        0x00, 0x00,
 466        0x00, 0x01, 0x00, 0x45, 0x09, 0x0a,
 467        0x16, 0x12, 0x60, 0x86, 0x2b,
 468        0x14, 0x0a, 0x02, 0x02, 0x09, 0x07
 469};
 470static const __u8 tas5110_sensor_init[][8] = {
 471        {0x30, 0x11, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10},
 472        {0x30, 0x11, 0x02, 0x20, 0xa9, 0x00, 0x00, 0x10},
 473        {0xa0, 0x61, 0x9a, 0xca, 0x00, 0x00, 0x00, 0x17},
 474};
 475
 476static const __u8 initTas5130[] = {
 477        0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
 478        0x00, 0x00,
 479        0x00, 0x01, 0x00, 0x68, 0x0c, 0x0a,
 480        0x28, 0x1e, 0x60, COMP, MCK_INIT,
 481        0x18, 0x10, 0x04, 0x03, 0x11, 0x0c
 482};
 483static const __u8 tas5130_sensor_init[][8] = {
 484/*      {0x30, 0x11, 0x00, 0x40, 0x47, 0x00, 0x00, 0x10},
 485                                        * shutter 0x47 short exposure? */
 486        {0x30, 0x11, 0x00, 0x40, 0x01, 0x00, 0x00, 0x10},
 487                                        /* shutter 0x01 long exposure */
 488        {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10},
 489};
 490
 491static struct sensor_data sensor_data[] = {
 492SENS(initHv7131, NULL, hv7131_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ, 0),
 493SENS(initOv6650, NULL, ov6650_sensor_init, NULL, NULL, F_GAIN|F_SIF, 0, 0x60),
 494SENS(initOv7630, initOv7630_3, ov7630_sensor_init, NULL, ov7630_sensor_init_3,
 495        F_GAIN, 0, 0x21),
 496SENS(initPas106, NULL, pas106_sensor_init, NULL, NULL, F_SIF, NO_EXPO|NO_FREQ,
 497        0),
 498SENS(initPas202, initPas202, pas202_sensor_init, NULL, NULL, 0,
 499        NO_EXPO|NO_FREQ, 0),
 500SENS(initTas5110, NULL, tas5110_sensor_init, NULL, NULL, F_GAIN|F_SIF,
 501        NO_BRIGHTNESS|NO_FREQ, 0),
 502SENS(initTas5130, NULL, tas5130_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ,
 503        0),
 504};
 505
 506/* get one byte in gspca_dev->usb_buf */
 507static void reg_r(struct gspca_dev *gspca_dev,
 508                  __u16 value)
 509{
 510        usb_control_msg(gspca_dev->dev,
 511                        usb_rcvctrlpipe(gspca_dev->dev, 0),
 512                        0,                      /* request */
 513                        USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
 514                        value,
 515                        0,                      /* index */
 516                        gspca_dev->usb_buf, 1,
 517                        500);
 518}
 519
 520static void reg_w(struct gspca_dev *gspca_dev,
 521                  __u16 value,
 522                  const __u8 *buffer,
 523                  int len)
 524{
 525#ifdef GSPCA_DEBUG
 526        if (len > USB_BUF_SZ) {
 527                PDEBUG(D_ERR|D_PACK, "reg_w: buffer overflow");
 528                return;
 529        }
 530#endif
 531        memcpy(gspca_dev->usb_buf, buffer, len);
 532        usb_control_msg(gspca_dev->dev,
 533                        usb_sndctrlpipe(gspca_dev->dev, 0),
 534                        0x08,                   /* request */
 535                        USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
 536                        value,
 537                        0,                      /* index */
 538                        gspca_dev->usb_buf, len,
 539                        500);
 540}
 541
 542static int i2c_w(struct gspca_dev *gspca_dev, const __u8 *buffer)
 543{
 544        int retry = 60;
 545
 546        /* is i2c ready */
 547        reg_w(gspca_dev, 0x08, buffer, 8);
 548        while (retry--) {
 549                msleep(10);
 550                reg_r(gspca_dev, 0x08);
 551                if (gspca_dev->usb_buf[0] & 0x04) {
 552                        if (gspca_dev->usb_buf[0] & 0x08)
 553                                return -1;
 554                        return 0;
 555                }
 556        }
 557        return -1;
 558}
 559
 560static void i2c_w_vector(struct gspca_dev *gspca_dev,
 561                        const __u8 buffer[][8], int len)
 562{
 563        for (;;) {
 564                reg_w(gspca_dev, 0x08, *buffer, 8);
 565                len -= 8;
 566                if (len <= 0)
 567                        break;
 568                buffer++;
 569        }
 570}
 571
 572static void setbrightness(struct gspca_dev *gspca_dev)
 573{
 574        struct sd *sd = (struct sd *) gspca_dev;
 575        __u8 value;
 576
 577        switch (sd->sensor) {
 578        case  SENSOR_OV6650:
 579        case  SENSOR_OV7630: {
 580                __u8 i2cOV[] =
 581                        {0xa0, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10};
 582
 583                /* change reg 0x06 */
 584                i2cOV[1] = sensor_data[sd->sensor].sensor_addr;
 585                i2cOV[3] = sd->brightness;
 586                if (i2c_w(gspca_dev, i2cOV) < 0)
 587                        goto err;
 588                break;
 589            }
 590        case SENSOR_PAS106: {
 591                __u8 i2c1[] =
 592                        {0xa1, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14};
 593
 594                i2c1[3] = sd->brightness >> 3;
 595                i2c1[2] = 0x0e;
 596                if (i2c_w(gspca_dev, i2c1) < 0)
 597                        goto err;
 598                i2c1[3] = 0x01;
 599                i2c1[2] = 0x13;
 600                if (i2c_w(gspca_dev, i2c1) < 0)
 601                        goto err;
 602                break;
 603            }
 604        case SENSOR_PAS202: {
 605                /* __u8 i2cpexpo1[] =
 606                        {0xb0, 0x40, 0x04, 0x07, 0x2a, 0x00, 0x63, 0x16}; */
 607                __u8 i2cpexpo[] =
 608                        {0xb0, 0x40, 0x0e, 0x01, 0xab, 0x00, 0x63, 0x16};
 609                __u8 i2cp202[] =
 610                        {0xa0, 0x40, 0x10, 0x0e, 0x31, 0x00, 0x63, 0x15};
 611                static __u8 i2cpdoit[] =
 612                        {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16};
 613
 614                /* change reg 0x10 */
 615                i2cpexpo[4] = 0xff - sd->brightness;
 616/*              if(i2c_w(gspca_dev,i2cpexpo1) < 0)
 617                        goto err; */
 618/*              if(i2c_w(gspca_dev,i2cpdoit) < 0)
 619                        goto err; */
 620                if (i2c_w(gspca_dev, i2cpexpo) < 0)
 621                        goto err;
 622                if (i2c_w(gspca_dev, i2cpdoit) < 0)
 623                        goto err;
 624                i2cp202[3] = sd->brightness >> 3;
 625                if (i2c_w(gspca_dev, i2cp202) < 0)
 626                        goto err;
 627                if (i2c_w(gspca_dev, i2cpdoit) < 0)
 628                        goto err;
 629                break;
 630            }
 631        case SENSOR_TAS5130CXX: {
 632                __u8 i2c[] =
 633                        {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10};
 634
 635                value = 0xff - sd->brightness;
 636                i2c[4] = value;
 637                PDEBUG(D_CONF, "brightness %d : %d", value, i2c[4]);
 638                if (i2c_w(gspca_dev, i2c) < 0)
 639                        goto err;
 640                break;
 641            }
 642        }
 643        return;
 644err:
 645        PDEBUG(D_ERR, "i2c error brightness");
 646}
 647
 648static void setsensorgain(struct gspca_dev *gspca_dev)
 649{
 650        struct sd *sd = (struct sd *) gspca_dev;
 651        unsigned char gain = sd->gain;
 652
 653        switch (sd->sensor) {
 654
 655        case SENSOR_TAS5110: {
 656                __u8 i2c[] =
 657                        {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10};
 658
 659                i2c[4] = 255 - gain;
 660                if (i2c_w(gspca_dev, i2c) < 0)
 661                        goto err;
 662                break;
 663            }
 664
 665        case SENSOR_OV6650:
 666                gain >>= 1;
 667                /* fall thru */
 668        case SENSOR_OV7630: {
 669                __u8 i2c[] = {0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
 670
 671                i2c[1] = sensor_data[sd->sensor].sensor_addr;
 672                i2c[3] = gain >> 2;
 673                if (i2c_w(gspca_dev, i2c) < 0)
 674                        goto err;
 675                break;
 676            }
 677        }
 678        return;
 679err:
 680        PDEBUG(D_ERR, "i2c error gain");
 681}
 682
 683static void setgain(struct gspca_dev *gspca_dev)
 684{
 685        struct sd *sd = (struct sd *) gspca_dev;
 686        __u8 gain;
 687        __u8 rgb_value;
 688
 689        gain = sd->gain >> 4;
 690
 691        /* red and blue gain */
 692        rgb_value = gain << 4 | gain;
 693        reg_w(gspca_dev, 0x10, &rgb_value, 1);
 694        /* green gain */
 695        rgb_value = gain;
 696        reg_w(gspca_dev, 0x11, &rgb_value, 1);
 697
 698        if (sensor_data[sd->sensor].flags & F_GAIN)
 699                setsensorgain(gspca_dev);
 700}
 701
 702static void setexposure(struct gspca_dev *gspca_dev)
 703{
 704        struct sd *sd = (struct sd *) gspca_dev;
 705
 706        switch (sd->sensor) {
 707        case SENSOR_TAS5110: {
 708                __u8 reg;
 709
 710                /* register 19's high nibble contains the sn9c10x clock divider
 711                   The high nibble configures the no fps according to the
 712                   formula: 60 / high_nibble. With a maximum of 30 fps */
 713                reg = 120 * sd->exposure / 1000;
 714                if (reg < 2)
 715                        reg = 2;
 716                else if (reg > 15)
 717                        reg = 15;
 718                reg = (reg << 4) | 0x0b;
 719                reg_w(gspca_dev, 0x19, &reg, 1);
 720                break;
 721            }
 722        case SENSOR_OV6650:
 723        case SENSOR_OV7630: {
 724                /* The ov6650 / ov7630 have 2 registers which both influence
 725                   exposure, register 11, whose low nibble sets the nr off fps
 726                   according to: fps = 30 / (low_nibble + 1)
 727
 728                   The fps configures the maximum exposure setting, but it is
 729                   possible to use less exposure then what the fps maximum
 730                   allows by setting register 10. register 10 configures the
 731                   actual exposure as quotient of the full exposure, with 0
 732                   being no exposure at all (not very usefull) and reg10_max
 733                   being max exposure possible at that framerate.
 734
 735                   The code maps our 0 - 510 ms exposure ctrl to these 2
 736                   registers, trying to keep fps as high as possible.
 737                */
 738                __u8 i2c[] = {0xb0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10};
 739                int reg10, reg11, reg10_max;
 740
 741                /* ov6645 datasheet says reg10_max is 9a, but that uses
 742                   tline * 2 * reg10 as formula for calculating texpo, the
 743                   ov6650 probably uses the same formula as the 7730 which uses
 744                   tline * 4 * reg10, which explains why the reg10max we've
 745                   found experimentally for the ov6650 is exactly half that of
 746                   the ov6645. The ov7630 datasheet says the max is 0x41. */
 747                if (sd->sensor == SENSOR_OV6650) {
 748                        reg10_max = 0x4d;
 749                        i2c[4] = 0xc0; /* OV6650 needs non default vsync pol */
 750                } else
 751                        reg10_max = 0x41;
 752
 753                reg11 = (60 * sd->exposure + 999) / 1000;
 754                if (reg11 < 1)
 755                        reg11 = 1;
 756                else if (reg11 > 16)
 757                        reg11 = 16;
 758
 759                /* In 640x480, if the reg11 has less than 3, the image is
 760                   unstable (not enough bandwidth). */
 761                if (gspca_dev->width == 640 && reg11 < 3)
 762                        reg11 = 3;
 763
 764                /* frame exposure time in ms = 1000 * reg11 / 30    ->
 765                reg10 = sd->exposure * 2 * reg10_max / (1000 * reg11 / 30) */
 766                reg10 = (sd->exposure * 60 * reg10_max) / (1000 * reg11);
 767
 768                /* Don't allow this to get below 10 when using autogain, the
 769                   steps become very large (relatively) when below 10 causing
 770                   the image to oscilate from much too dark, to much too bright
 771                   and back again. */
 772                if (sd->autogain && reg10 < 10)
 773                        reg10 = 10;
 774                else if (reg10 > reg10_max)
 775                        reg10 = reg10_max;
 776
 777                /* Write reg 10 and reg11 low nibble */
 778                i2c[1] = sensor_data[sd->sensor].sensor_addr;
 779                i2c[3] = reg10;
 780                i2c[4] |= reg11 - 1;
 781
 782                /* If register 11 didn't change, don't change it */
 783                if (sd->reg11 == reg11 )
 784                        i2c[0] = 0xa0;
 785
 786                if (i2c_w(gspca_dev, i2c) == 0)
 787                        sd->reg11 = reg11;
 788                else
 789                        PDEBUG(D_ERR, "i2c error exposure");
 790                break;
 791            }
 792        }
 793}
 794
 795static void setfreq(struct gspca_dev *gspca_dev)
 796{
 797        struct sd *sd = (struct sd *) gspca_dev;
 798
 799        switch (sd->sensor) {
 800        case SENSOR_OV6650:
 801        case SENSOR_OV7630: {
 802                /* Framerate adjust register for artificial light 50 hz flicker
 803                   compensation, for the ov6650 this is identical to ov6630
 804                   0x2b register, see ov6630 datasheet.
 805                   0x4f / 0x8a -> (30 fps -> 25 fps), 0x00 -> no adjustment */
 806                __u8 i2c[] = {0xa0, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10};
 807                switch (sd->freq) {
 808                default:
 809/*              case 0:                  * no filter*/
 810/*              case 2:                  * 60 hz */
 811                        i2c[3] = 0;
 812                        break;
 813                case 1:                 /* 50 hz */
 814                        i2c[3] = (sd->sensor == SENSOR_OV6650)
 815                                        ? 0x4f : 0x8a;
 816                        break;
 817                }
 818                i2c[1] = sensor_data[sd->sensor].sensor_addr;
 819                if (i2c_w(gspca_dev, i2c) < 0)
 820                        PDEBUG(D_ERR, "i2c error setfreq");
 821                break;
 822            }
 823        }
 824}
 825
 826static void do_autogain(struct gspca_dev *gspca_dev)
 827{
 828        int deadzone, desired_avg_lum;
 829        struct sd *sd = (struct sd *) gspca_dev;
 830        int avg_lum = atomic_read(&sd->avg_lum);
 831
 832        if (avg_lum == -1)
 833                return;
 834
 835        /* SIF / VGA sensors have a different autoexposure area and thus
 836           different avg_lum values for the same picture brightness */
 837        if (sensor_data[sd->sensor].flags & F_SIF) {
 838                deadzone = 1000;
 839                desired_avg_lum = 7000;
 840        } else {
 841                deadzone = 3000;
 842                desired_avg_lum = 23000;
 843        }
 844
 845        if (sd->autogain_ignore_frames > 0)
 846                sd->autogain_ignore_frames--;
 847        else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum,
 848                        sd->brightness * desired_avg_lum / 127,
 849                        deadzone, GAIN_KNEE, EXPOSURE_KNEE)) {
 850                PDEBUG(D_FRAM, "autogain: gain changed: gain: %d expo: %d",
 851                        (int)sd->gain, (int)sd->exposure);
 852                sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
 853        }
 854}
 855
 856/* this function is called at probe time */
 857static int sd_config(struct gspca_dev *gspca_dev,
 858                        const struct usb_device_id *id)
 859{
 860        struct sd *sd = (struct sd *) gspca_dev;
 861        struct cam *cam;
 862
 863        reg_r(gspca_dev, 0x00);
 864        if (gspca_dev->usb_buf[0] != 0x10)
 865                return -ENODEV;
 866
 867        /* copy the webcam info from the device id */
 868        sd->sensor = id->driver_info >> 8;
 869        sd->bridge = id->driver_info & 0xff;
 870        gspca_dev->ctrl_dis = sensor_data[sd->sensor].ctrl_dis;
 871
 872        cam = &gspca_dev->cam;
 873        if (!(sensor_data[sd->sensor].flags & F_SIF)) {
 874                cam->cam_mode = vga_mode;
 875                cam->nmodes = ARRAY_SIZE(vga_mode);
 876        } else {
 877                cam->cam_mode = sif_mode;
 878                cam->nmodes = ARRAY_SIZE(sif_mode);
 879        }
 880        cam->npkt = 36;                 /* 36 packets per ISOC message */
 881
 882        sd->brightness = BRIGHTNESS_DEF;
 883        sd->gain = GAIN_DEF;
 884        sd->exposure = EXPOSURE_DEF;
 885        if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
 886                sd->autogain = 0; /* Disable do_autogain callback */
 887        else
 888                sd->autogain = AUTOGAIN_DEF;
 889        sd->freq = FREQ_DEF;
 890
 891        return 0;
 892}
 893
 894/* this function is called at probe and resume time */
 895static int sd_init(struct gspca_dev *gspca_dev)
 896{
 897        const __u8 stop = 0x09; /* Disable stream turn of LED */
 898
 899        reg_w(gspca_dev, 0x01, &stop, 1);
 900
 901        return 0;
 902}
 903
 904/* -- start the camera -- */
 905static int sd_start(struct gspca_dev *gspca_dev)
 906{
 907        struct sd *sd = (struct sd *) gspca_dev;
 908        struct cam *cam = &gspca_dev->cam;
 909        int mode, l;
 910        const __u8 *sn9c10x;
 911        __u8 reg12_19[8];
 912
 913        mode = cam->cam_mode[gspca_dev->curr_mode].priv & 0x07;
 914        sn9c10x = sensor_data[sd->sensor].bridge_init[sd->bridge];
 915        l = sensor_data[sd->sensor].bridge_init_size[sd->bridge];
 916        memcpy(reg12_19, &sn9c10x[0x12 - 1], 8);
 917        reg12_19[6] = sn9c10x[0x18 - 1] | (mode << 4);
 918        /* Special cases where reg 17 and or 19 value depends on mode */
 919        switch (sd->sensor) {
 920        case SENSOR_PAS202:
 921                reg12_19[5] = mode ? 0x24 : 0x20;
 922                break;
 923        case SENSOR_TAS5130CXX:
 924                /* probably not mode specific at all most likely the upper
 925                   nibble of 0x19 is exposure (clock divider) just as with
 926                   the tas5110, we need someone to test this. */
 927                reg12_19[7] = mode ? 0x23 : 0x43;
 928                break;
 929        }
 930        /* Disable compression when the raw bayer format has been selected */
 931        if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW)
 932                reg12_19[6] &= ~0x80;
 933
 934        /* Vga mode emulation on SIF sensor? */
 935        if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_REDUCED_SIF) {
 936                reg12_19[0] += 16; /* 0x12: hstart adjust */
 937                reg12_19[1] += 24; /* 0x13: vstart adjust */
 938                reg12_19[3] = 320 / 16; /* 0x15: hsize */
 939                reg12_19[4] = 240 / 16; /* 0x16: vsize */
 940        }
 941
 942        /* reg 0x01 bit 2 video transfert on */
 943        reg_w(gspca_dev, 0x01, &sn9c10x[0x01 - 1], 1);
 944        /* reg 0x17 SensorClk enable inv Clk 0x60 */
 945        reg_w(gspca_dev, 0x17, &sn9c10x[0x17 - 1], 1);
 946        /* Set the registers from the template */
 947        reg_w(gspca_dev, 0x01, sn9c10x, l);
 948
 949        /* Init the sensor */
 950        i2c_w_vector(gspca_dev, sensor_data[sd->sensor].sensor_init,
 951                        sensor_data[sd->sensor].sensor_init_size);
 952        if (sensor_data[sd->sensor].sensor_bridge_init[sd->bridge])
 953                i2c_w_vector(gspca_dev,
 954                        sensor_data[sd->sensor].sensor_bridge_init[sd->bridge],
 955                        sensor_data[sd->sensor].sensor_bridge_init_size[
 956                                sd->bridge]);
 957
 958        /* H_size V_size 0x28, 0x1e -> 640x480. 0x16, 0x12 -> 352x288 */
 959        reg_w(gspca_dev, 0x15, &reg12_19[3], 2);
 960        /* compression register */
 961        reg_w(gspca_dev, 0x18, &reg12_19[6], 1);
 962        /* H_start */
 963        reg_w(gspca_dev, 0x12, &reg12_19[0], 1);
 964        /* V_START */
 965        reg_w(gspca_dev, 0x13, &reg12_19[1], 1);
 966        /* reset 0x17 SensorClk enable inv Clk 0x60 */
 967                                /*fixme: ov7630 [17]=68 8f (+20 if 102)*/
 968        reg_w(gspca_dev, 0x17, &reg12_19[5], 1);
 969        /*MCKSIZE ->3 */        /*fixme: not ov7630*/
 970        reg_w(gspca_dev, 0x19, &reg12_19[7], 1);
 971        /* AE_STRX AE_STRY AE_ENDX AE_ENDY */
 972        reg_w(gspca_dev, 0x1c, &sn9c10x[0x1c - 1], 4);
 973        /* Enable video transfert */
 974        reg_w(gspca_dev, 0x01, &sn9c10x[0], 1);
 975        /* Compression */
 976        reg_w(gspca_dev, 0x18, &reg12_19[6], 2);
 977        msleep(20);
 978
 979        sd->reg11 = -1;
 980
 981        setgain(gspca_dev);
 982        setbrightness(gspca_dev);
 983        setexposure(gspca_dev);
 984        setfreq(gspca_dev);
 985
 986        sd->frames_to_drop = 0;
 987        sd->autogain_ignore_frames = 0;
 988        atomic_set(&sd->avg_lum, -1);
 989        return 0;
 990}
 991
 992static void sd_stopN(struct gspca_dev *gspca_dev)
 993{
 994        sd_init(gspca_dev);
 995}
 996
 997static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 998                        struct gspca_frame *frame,      /* target */
 999                        unsigned char *data,            /* isoc packet */
1000                        int len)                        /* iso packet length */
1001{
1002        int i;
1003        struct sd *sd = (struct sd *) gspca_dev;
1004        struct cam *cam = &gspca_dev->cam;
1005
1006        /* frames start with:
1007         *      ff ff 00 c4 c4 96       synchro
1008         *      00              (unknown)
1009         *      xx              (frame sequence / size / compression)
1010         *      (xx)            (idem - extra byte for sn9c103)
1011         *      ll mm           brightness sum inside auto exposure
1012         *      ll mm           brightness sum outside auto exposure
1013         *      (xx xx xx xx xx)        audio values for snc103
1014         */
1015        if (len > 6 && len < 24) {
1016                for (i = 0; i < len - 6; i++) {
1017                        if (data[0 + i] == 0xff
1018                            && data[1 + i] == 0xff
1019                            && data[2 + i] == 0x00
1020                            && data[3 + i] == 0xc4
1021                            && data[4 + i] == 0xc4
1022                            && data[5 + i] == 0x96) {   /* start of frame */
1023                                int lum = -1;
1024                                int pkt_type = LAST_PACKET;
1025                                int fr_h_sz = (sd->bridge == BRIDGE_103) ?
1026                                        18 : 12;
1027
1028                                if (len - i < fr_h_sz) {
1029                                        PDEBUG(D_STREAM, "packet too short to"
1030                                                " get avg brightness");
1031                                } else if (sd->bridge == BRIDGE_103) {
1032                                        lum = data[i + 9] +
1033                                                (data[i + 10] << 8);
1034                                } else {
1035                                        lum = data[i + 8] + (data[i + 9] << 8);
1036                                }
1037                                /* When exposure changes midway a frame we
1038                                   get a lum of 0 in this case drop 2 frames
1039                                   as the frames directly after an exposure
1040                                   change have an unstable image. Sometimes lum
1041                                   *really* is 0 (cam used in low light with
1042                                   low exposure setting), so do not drop frames
1043                                   if the previous lum was 0 too. */
1044                                if (lum == 0 && sd->prev_avg_lum != 0) {
1045                                        lum = -1;
1046                                        sd->frames_to_drop = 2;
1047                                        sd->prev_avg_lum = 0;
1048                                } else
1049                                        sd->prev_avg_lum = lum;
1050                                atomic_set(&sd->avg_lum, lum);
1051
1052                                if (sd->frames_to_drop) {
1053                                        sd->frames_to_drop--;
1054                                        pkt_type = DISCARD_PACKET;
1055                                }
1056
1057                                frame = gspca_frame_add(gspca_dev, pkt_type,
1058                                                        frame, data, 0);
1059                                data += i + fr_h_sz;
1060                                len -= i + fr_h_sz;
1061                                gspca_frame_add(gspca_dev, FIRST_PACKET,
1062                                                frame, data, len);
1063                                return;
1064                        }
1065                }
1066        }
1067
1068        if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW) {
1069                /* In raw mode we sometimes get some garbage after the frame
1070                   ignore this */
1071                int used = frame->data_end - frame->data;
1072                int size = cam->cam_mode[gspca_dev->curr_mode].sizeimage;
1073
1074                if (used + len > size)
1075                        len = size - used;
1076        }
1077
1078        gspca_frame_add(gspca_dev, INTER_PACKET,
1079                        frame, data, len);
1080}
1081
1082static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1083{
1084        struct sd *sd = (struct sd *) gspca_dev;
1085
1086        sd->brightness = val;
1087        if (gspca_dev->streaming)
1088                setbrightness(gspca_dev);
1089        return 0;
1090}
1091
1092static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1093{
1094        struct sd *sd = (struct sd *) gspca_dev;
1095
1096        *val = sd->brightness;
1097        return 0;
1098}
1099
1100static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
1101{
1102        struct sd *sd = (struct sd *) gspca_dev;
1103
1104        sd->gain = val;
1105        if (gspca_dev->streaming)
1106                setgain(gspca_dev);
1107        return 0;
1108}
1109
1110static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
1111{
1112        struct sd *sd = (struct sd *) gspca_dev;
1113
1114        *val = sd->gain;
1115        return 0;
1116}
1117
1118static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
1119{
1120        struct sd *sd = (struct sd *) gspca_dev;
1121
1122        sd->exposure = val;
1123        if (gspca_dev->streaming)
1124                setexposure(gspca_dev);
1125        return 0;
1126}
1127
1128static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
1129{
1130        struct sd *sd = (struct sd *) gspca_dev;
1131
1132        *val = sd->exposure;
1133        return 0;
1134}
1135
1136static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1137{
1138        struct sd *sd = (struct sd *) gspca_dev;
1139
1140        sd->autogain = val;
1141        /* when switching to autogain set defaults to make sure
1142           we are on a valid point of the autogain gain /
1143           exposure knee graph, and give this change time to
1144           take effect before doing autogain. */
1145        if (sd->autogain) {
1146                sd->exposure = EXPOSURE_DEF;
1147                sd->gain = GAIN_DEF;
1148                if (gspca_dev->streaming) {
1149                        sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
1150                        setexposure(gspca_dev);
1151                        setgain(gspca_dev);
1152                }
1153        }
1154
1155        return 0;
1156}
1157
1158static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1159{
1160        struct sd *sd = (struct sd *) gspca_dev;
1161
1162        *val = sd->autogain;
1163        return 0;
1164}
1165
1166static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
1167{
1168        struct sd *sd = (struct sd *) gspca_dev;
1169
1170        sd->freq = val;
1171        if (gspca_dev->streaming)
1172                setfreq(gspca_dev);
1173        return 0;
1174}
1175
1176static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
1177{
1178        struct sd *sd = (struct sd *) gspca_dev;
1179
1180        *val = sd->freq;
1181        return 0;
1182}
1183
1184static int sd_querymenu(struct gspca_dev *gspca_dev,
1185                        struct v4l2_querymenu *menu)
1186{
1187        switch (menu->id) {
1188        case V4L2_CID_POWER_LINE_FREQUENCY:
1189                switch (menu->index) {
1190                case 0:         /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
1191                        strcpy((char *) menu->name, "NoFliker");
1192                        return 0;
1193                case 1:         /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
1194                        strcpy((char *) menu->name, "50 Hz");
1195                        return 0;
1196                case 2:         /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
1197                        strcpy((char *) menu->name, "60 Hz");
1198                        return 0;
1199                }
1200                break;
1201        }
1202        return -EINVAL;
1203}
1204
1205/* sub-driver description */
1206static const struct sd_desc sd_desc = {
1207        .name = MODULE_NAME,
1208        .ctrls = sd_ctrls,
1209        .nctrls = ARRAY_SIZE(sd_ctrls),
1210        .config = sd_config,
1211        .init = sd_init,
1212        .start = sd_start,
1213        .stopN = sd_stopN,
1214        .pkt_scan = sd_pkt_scan,
1215        .querymenu = sd_querymenu,
1216        .dq_callback = do_autogain,
1217};
1218
1219/* -- module initialisation -- */
1220#define SB(sensor, bridge) \
1221        .driver_info = (SENSOR_ ## sensor << 8) | BRIDGE_ ## bridge
1222
1223
1224static __devinitdata struct usb_device_id device_table[] = {
1225        {USB_DEVICE(0x0c45, 0x6001), SB(TAS5110, 102)}, /* TAS5110C1B */
1226        {USB_DEVICE(0x0c45, 0x6005), SB(TAS5110, 101)}, /* TAS5110C1B */
1227#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1228        {USB_DEVICE(0x0c45, 0x6007), SB(TAS5110, 101)}, /* TAS5110D */
1229        {USB_DEVICE(0x0c45, 0x6009), SB(PAS106, 101)},
1230        {USB_DEVICE(0x0c45, 0x600d), SB(PAS106, 101)},
1231#endif
1232        {USB_DEVICE(0x0c45, 0x6011), SB(OV6650, 101)},
1233#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1234        {USB_DEVICE(0x0c45, 0x6019), SB(OV7630, 101)},
1235        {USB_DEVICE(0x0c45, 0x6024), SB(TAS5130CXX, 102)},
1236        {USB_DEVICE(0x0c45, 0x6025), SB(TAS5130CXX, 102)},
1237        {USB_DEVICE(0x0c45, 0x6028), SB(PAS202, 102)},
1238        {USB_DEVICE(0x0c45, 0x6029), SB(PAS106, 102)},
1239#endif
1240        {USB_DEVICE(0x0c45, 0x602c), SB(OV7630, 102)},
1241        {USB_DEVICE(0x0c45, 0x602d), SB(HV7131R, 102)},
1242#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1243        {USB_DEVICE(0x0c45, 0x602e), SB(OV7630, 102)},
1244#endif
1245        {USB_DEVICE(0x0c45, 0x608f), SB(OV7630, 103)},
1246#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1247        {USB_DEVICE(0x0c45, 0x60af), SB(PAS202, 103)},
1248#endif
1249        {USB_DEVICE(0x0c45, 0x60b0), SB(OV7630, 103)},
1250        {}
1251};
1252MODULE_DEVICE_TABLE(usb, device_table);
1253
1254/* -- device connect -- */
1255static int sd_probe(struct usb_interface *intf,
1256                        const struct usb_device_id *id)
1257{
1258        return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1259                                THIS_MODULE);
1260}
1261
1262static struct usb_driver sd_driver = {
1263        .name = MODULE_NAME,
1264        .id_table = device_table,
1265        .probe = sd_probe,
1266        .disconnect = gspca_disconnect,
1267#ifdef CONFIG_PM
1268        .suspend = gspca_suspend,
1269        .resume = gspca_resume,
1270#endif
1271};
1272
1273/* -- module insert / remove -- */
1274static int __init sd_mod_init(void)
1275{
1276        int ret;
1277        ret = usb_register(&sd_driver);
1278        if (ret < 0)
1279                return ret;
1280        PDEBUG(D_PROBE, "registered");
1281        return 0;
1282}
1283static void __exit sd_mod_exit(void)
1284{
1285        usb_deregister(&sd_driver);
1286        PDEBUG(D_PROBE, "deregistered");
1287}
1288
1289module_init(sd_mod_init);
1290module_exit(sd_mod_exit);
1291
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.