linux/drivers/media/usb/gspca/spca508.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * SPCA508 chip based cameras subdriver
   4 *
   5 * Copyright (C) 2009 Jean-Francois Moine <http://moinejf.free.fr>
   6 */
   7
   8#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
   9
  10#define MODULE_NAME "spca508"
  11
  12#include "gspca.h"
  13
  14MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
  15MODULE_DESCRIPTION("GSPCA/SPCA508 USB Camera Driver");
  16MODULE_LICENSE("GPL");
  17
  18/* specific webcam descriptor */
  19struct sd {
  20        struct gspca_dev gspca_dev;             /* !! must be the first item */
  21
  22        u8 subtype;
  23#define CreativeVista 0
  24#define HamaUSBSightcam 1
  25#define HamaUSBSightcam2 2
  26#define IntelEasyPCCamera 3
  27#define MicroInnovationIC200 4
  28#define ViewQuestVQ110 5
  29};
  30
  31static const struct v4l2_pix_format sif_mode[] = {
  32        {160, 120, V4L2_PIX_FMT_SPCA508, V4L2_FIELD_NONE,
  33                .bytesperline = 160,
  34                .sizeimage = 160 * 120 * 3 / 2,
  35                .colorspace = V4L2_COLORSPACE_SRGB,
  36                .priv = 3},
  37        {176, 144, V4L2_PIX_FMT_SPCA508, V4L2_FIELD_NONE,
  38                .bytesperline = 176,
  39                .sizeimage = 176 * 144 * 3 / 2,
  40                .colorspace = V4L2_COLORSPACE_SRGB,
  41                .priv = 2},
  42        {320, 240, V4L2_PIX_FMT_SPCA508, V4L2_FIELD_NONE,
  43                .bytesperline = 320,
  44                .sizeimage = 320 * 240 * 3 / 2,
  45                .colorspace = V4L2_COLORSPACE_SRGB,
  46                .priv = 1},
  47        {352, 288, V4L2_PIX_FMT_SPCA508, V4L2_FIELD_NONE,
  48                .bytesperline = 352,
  49                .sizeimage = 352 * 288 * 3 / 2,
  50                .colorspace = V4L2_COLORSPACE_SRGB,
  51                .priv = 0},
  52};
  53
  54/* Frame packet header offsets for the spca508 */
  55#define SPCA508_OFFSET_DATA 37
  56
  57/*
  58 * Initialization data: this is the first set-up data written to the
  59 * device (before the open data).
  60 */
  61static const u16 spca508_init_data[][2] = {
  62        {0x0000, 0x870b},
  63
  64        {0x0020, 0x8112},       /* Video drop enable, ISO streaming disable */
  65        {0x0003, 0x8111},       /* Reset compression & memory */
  66        {0x0000, 0x8110},       /* Disable all outputs */
  67        /* READ {0x0000, 0x8114} -> 0000: 00  */
  68        {0x0000, 0x8114},       /* SW GPIO data */
  69        {0x0008, 0x8110},       /* Enable charge pump output */
  70        {0x0002, 0x8116},       /* 200 kHz pump clock */
  71        /* UNKNOWN DIRECTION (URB_FUNCTION_SELECT_INTERFACE:) */
  72        {0x0003, 0x8111},       /* Reset compression & memory */
  73        {0x0000, 0x8111},       /* Normal mode (not reset) */
  74        {0x0098, 0x8110},
  75                /* Enable charge pump output, sync.serial,external 2x clock */
  76        {0x000d, 0x8114},       /* SW GPIO data */
  77        {0x0002, 0x8116},       /* 200 kHz pump clock */
  78        {0x0020, 0x8112},       /* Video drop enable, ISO streaming disable */
  79/* --------------------------------------- */
  80        {0x000f, 0x8402},       /* memory bank */
  81        {0x0000, 0x8403},       /* ... address */
  82/* --------------------------------------- */
  83/* 0x88__ is Synchronous Serial Interface. */
  84/* TBD: This table could be expressed more compactly */
  85/* using spca508_write_i2c_vector(). */
  86/* TBD: Should see if the values in spca50x_i2c_data */
  87/* would work with the VQ110 instead of the values */
  88/* below. */
  89        {0x00c0, 0x8804},       /* SSI slave addr */
  90        {0x0008, 0x8802},       /* 375 Khz SSI clock */
  91        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
  92        /* READ { 0x0001, 0x8802 } -> 0000: 08  */
  93        {0x0008, 0x8802},       /* 375 Khz SSI clock */
  94        {0x0012, 0x8801},       /* SSI reg addr */
  95        {0x0080, 0x8800},       /* SSI data to write */
  96        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
  97        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
  98        /* READ { 0x0001, 0x8802 } -> 0000: 08  */
  99        {0x0008, 0x8802},       /* 375 Khz SSI clock */
 100        {0x0012, 0x8801},       /* SSI reg addr */
 101        {0x0000, 0x8800},       /* SSI data to write */
 102        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 103        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 104        /* READ { 0x0001, 0x8802 } -> 0000: 08  */
 105        {0x0008, 0x8802},       /* 375 Khz SSI clock */
 106        {0x0011, 0x8801},       /* SSI reg addr */
 107        {0x0040, 0x8800},       /* SSI data to write */
 108        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 109        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 110        /* READ { 0x0001, 0x8802 } -> 0000: 08  */
 111        {0x0008, 0x8802},
 112        {0x0013, 0x8801},
 113        {0x0000, 0x8800},
 114        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 115        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 116        /* READ { 0x0001, 0x8802 } -> 0000: 08  */
 117        {0x0008, 0x8802},
 118        {0x0014, 0x8801},
 119        {0x0000, 0x8800},
 120        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 121        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 122        /* READ { 0x0001, 0x8802 } -> 0000: 08  */
 123        {0x0008, 0x8802},
 124        {0x0015, 0x8801},
 125        {0x0001, 0x8800},
 126        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 127        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 128        /* READ { 0x0001, 0x8802 } -> 0000: 08  */
 129        {0x0008, 0x8802},
 130        {0x0016, 0x8801},
 131        {0x0003, 0x8800},
 132        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 133        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 134        /* READ { 0x0001, 0x8802 } -> 0000: 08  */
 135        {0x0008, 0x8802},
 136        {0x0017, 0x8801},
 137        {0x0036, 0x8800},
 138        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 139        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 140        /* READ { 0x0001, 0x8802 } -> 0000: 08  */
 141        {0x0008, 0x8802},
 142        {0x0018, 0x8801},
 143        {0x00ec, 0x8800},
 144        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 145        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 146        /* READ { 0x0001, 0x8802 } -> 0000: 08  */
 147        {0x0008, 0x8802},
 148        {0x001a, 0x8801},
 149        {0x0094, 0x8800},
 150        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 151        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 152        /* READ { 0x0001, 0x8802 } -> 0000: 08  */
 153        {0x0008, 0x8802},
 154        {0x001b, 0x8801},
 155        {0x0000, 0x8800},
 156        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 157        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 158        /* READ { 0x0001, 0x8802 } -> 0000: 08  */
 159        {0x0008, 0x8802},
 160        {0x0027, 0x8801},
 161        {0x00a2, 0x8800},
 162        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 163        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 164        /* READ { 0x0001, 0x8802 } -> 0000: 08  */
 165        {0x0008, 0x8802},
 166        {0x0028, 0x8801},
 167        {0x0040, 0x8800},
 168        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 169        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 170        /* READ { 0x0001, 0x8802 } -> 0000: 08  */
 171        {0x0008, 0x8802},
 172        {0x002a, 0x8801},
 173        {0x0084, 0x8800},
 174        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 175        /* READ { 0x0001, 0x8803 } -> 0000: 00 */
 176        /* READ { 0x0001, 0x8802 } -> 0000: 08  */
 177        {0x0008, 0x8802},
 178        {0x002b, 0x8801},
 179        {0x00a8, 0x8800},
 180        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 181        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 182        /* READ { 0x0001, 0x8802 } -> 0000: 08  */
 183        {0x0008, 0x8802},
 184        {0x002c, 0x8801},
 185        {0x00fe, 0x8800},
 186        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 187        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 188        /* READ { 0x0001, 0x8802 } -> 0000: 08  */
 189        {0x0008, 0x8802},
 190        {0x002d, 0x8801},
 191        {0x0003, 0x8800},
 192        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 193        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 194        /* READ { 0x0001, 0x8802 } -> 0000: 08  */
 195        {0x0008, 0x8802},
 196        {0x0038, 0x8801},
 197        {0x0083, 0x8800},
 198        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 199        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 200        /* READ { 0x0001, 0x8802 } -> 0000: 08  */
 201        {0x0008, 0x8802},
 202        {0x0033, 0x8801},
 203        {0x0081, 0x8800},
 204        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 205        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 206        /* READ { 0x0001, 0x8802 } -> 0000: 08  */
 207        {0x0008, 0x8802},
 208        {0x0034, 0x8801},
 209        {0x004a, 0x8800},
 210        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 211        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 212        /* READ { 0x0001, 0x8802 } -> 0000: 08  */
 213        {0x0008, 0x8802},
 214        {0x0039, 0x8801},
 215        {0x0000, 0x8800},
 216        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 217        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 218        /* READ { 0x0001, 0x8802 } -> 0000: 08  */
 219        {0x0008, 0x8802},
 220        {0x0010, 0x8801},
 221        {0x00a8, 0x8800},
 222        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 223        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 224        /* READ { 0x0001, 0x8802 } -> 0000: 08  */
 225        {0x0008, 0x8802},
 226        {0x0006, 0x8801},
 227        {0x0058, 0x8800},
 228        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 229        /* READ { 0x0001, 0x8803 } -> 0000: 00 */
 230        /* READ { 0x0001, 0x8802 } -> 0000: 08  */
 231        {0x0008, 0x8802},
 232        {0x0000, 0x8801},
 233        {0x0004, 0x8800},
 234        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 235        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 236        /* READ { 0x0001, 0x8802 } -> 0000: 08  */
 237        {0x0008, 0x8802},
 238        {0x0040, 0x8801},
 239        {0x0080, 0x8800},
 240        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 241        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 242        /* READ { 0x0001, 0x8802 } -> 0000: 08  */
 243        {0x0008, 0x8802},
 244        {0x0041, 0x8801},
 245        {0x000c, 0x8800},
 246        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 247        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 248        /* READ { 0x0001, 0x8802 } -> 0000: 08  */
 249        {0x0008, 0x8802},
 250        {0x0042, 0x8801},
 251        {0x000c, 0x8800},
 252        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 253        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 254        /* READ { 0x0001, 0x8802 } -> 0000: 08  */
 255        {0x0008, 0x8802},
 256        {0x0043, 0x8801},
 257        {0x0028, 0x8800},
 258        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 259        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 260        /* READ { 0x0001, 0x8802 } -> 0000: 08  */
 261        {0x0008, 0x8802},
 262        {0x0044, 0x8801},
 263        {0x0080, 0x8800},
 264        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 265        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 266        /* READ { 0x0001, 0x8802 } -> 0000: 08  */
 267        {0x0008, 0x8802},
 268        {0x0045, 0x8801},
 269        {0x0020, 0x8800},
 270        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 271        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 272        /* READ { 0x0001, 0x8802 } -> 0000: 08  */
 273        {0x0008, 0x8802},
 274        {0x0046, 0x8801},
 275        {0x0020, 0x8800},
 276        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 277        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 278        /* READ { 0x0001, 0x8802 } -> 0000: 08  */
 279        {0x0008, 0x8802},
 280        {0x0047, 0x8801},
 281        {0x0080, 0x8800},
 282        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 283        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 284        /* READ { 0x0001, 0x8802 } -> 0000: 08  */
 285        {0x0008, 0x8802},
 286        {0x0048, 0x8801},
 287        {0x004c, 0x8800},
 288        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 289        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 290        /* READ { 0x0001, 0x8802 } -> 0000: 08  */
 291        {0x0008, 0x8802},
 292        {0x0049, 0x8801},
 293        {0x0084, 0x8800},
 294        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 295        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 296        /* READ { 0x0001, 0x8802 } -> 0000: 08  */
 297        {0x0008, 0x8802},
 298        {0x004a, 0x8801},
 299        {0x0084, 0x8800},
 300        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 301        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 302        /* READ { 0x0001, 0x8802 } -> 0000: 08  */
 303        {0x0008, 0x8802},
 304        {0x004b, 0x8801},
 305        {0x0084, 0x8800},
 306        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 307        /* --------------------------------------- */
 308        {0x0012, 0x8700},       /* Clock speed 48Mhz/(2+2)/2= 6 Mhz */
 309        {0x0000, 0x8701},       /* CKx1 clock delay adj */
 310        {0x0000, 0x8701},       /* CKx1 clock delay adj */
 311        {0x0001, 0x870c},       /* CKOx2 output */
 312        /* --------------------------------------- */
 313        {0x0080, 0x8600},       /* Line memory read counter (L) */
 314        {0x0001, 0x8606},       /* reserved */
 315        {0x0064, 0x8607},       /* Line memory read counter (H) 0x6480=25,728 */
 316        {0x002a, 0x8601},       /* CDSP sharp interpolation mode,
 317         *                      line sel for color sep, edge enhance enab */
 318        {0x0000, 0x8602},       /* optical black level for user settng = 0 */
 319        {0x0080, 0x8600},       /* Line memory read counter (L) */
 320        {0x000a, 0x8603},       /* optical black level calc mode:
 321                                 * auto; optical black offset = 10 */
 322        {0x00df, 0x865b},       /* Horiz offset for valid pixels (L)=0xdf */
 323        {0x0012, 0x865c},       /* Vert offset for valid lines (L)=0x12 */
 324
 325/* The following two lines seem to be the "wrong" resolution. */
 326/* But perhaps these indicate the actual size of the sensor */
 327/* rather than the size of the current video mode. */
 328        {0x0058, 0x865d},       /* Horiz valid pixels (*4) (L) = 352 */
 329        {0x0048, 0x865e},       /* Vert valid lines (*4) (L) = 288 */
 330
 331        {0x0015, 0x8608},       /* A11 Coef ... */
 332        {0x0030, 0x8609},
 333        {0x00fb, 0x860a},
 334        {0x003e, 0x860b},
 335        {0x00ce, 0x860c},
 336        {0x00f4, 0x860d},
 337        {0x00eb, 0x860e},
 338        {0x00dc, 0x860f},
 339        {0x0039, 0x8610},
 340        {0x0001, 0x8611},       /* R offset for white balance ... */
 341        {0x0000, 0x8612},
 342        {0x0001, 0x8613},
 343        {0x0000, 0x8614},
 344        {0x005b, 0x8651},       /* R gain for white balance ... */
 345        {0x0040, 0x8652},
 346        {0x0060, 0x8653},
 347        {0x0040, 0x8654},
 348        {0x0000, 0x8655},
 349        {0x0001, 0x863f},       /* Fixed gamma correction enable, USB control,
 350                                 * lum filter disable, lum noise clip disable */
 351        {0x00a1, 0x8656},       /* Window1 size 256x256, Windows2 size 64x64,
 352                                 * gamma look-up disable,
 353                                 * new edge enhancement enable */
 354        {0x0018, 0x8657},       /* Edge gain high thresh */
 355        {0x0020, 0x8658},       /* Edge gain low thresh */
 356        {0x000a, 0x8659},       /* Edge bandwidth high threshold */
 357        {0x0005, 0x865a},       /* Edge bandwidth low threshold */
 358        /* -------------------------------- */
 359        {0x0030, 0x8112},       /* Video drop enable, ISO streaming enable */
 360        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 361        /* READ { 0x0001, 0x8802 } -> 0000: 08  */
 362        {0xa908, 0x8802},
 363        {0x0034, 0x8801},       /* SSI reg addr */
 364        {0x00ca, 0x8800},
 365        /* SSI data to write */
 366        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 367        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 368        /* READ { 0x0001, 0x8802 } -> 0000: 08  */
 369        {0x1f08, 0x8802},
 370        {0x0006, 0x8801},
 371        {0x0080, 0x8800},
 372        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 373
 374/* ----- Read back coefs we wrote earlier. */
 375        /* READ { 0x0000, 0x8608 } -> 0000: 15  */
 376        /* READ { 0x0000, 0x8609 } -> 0000: 30  */
 377        /* READ { 0x0000, 0x860a } -> 0000: fb  */
 378        /* READ { 0x0000, 0x860b } -> 0000: 3e  */
 379        /* READ { 0x0000, 0x860c } -> 0000: ce  */
 380        /* READ { 0x0000, 0x860d } -> 0000: f4  */
 381        /* READ { 0x0000, 0x860e } -> 0000: eb  */
 382        /* READ { 0x0000, 0x860f } -> 0000: dc  */
 383        /* READ { 0x0000, 0x8610 } -> 0000: 39  */
 384        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 385        /* READ { 0x0001, 0x8802 } -> 0000: 08  */
 386        {0xb008, 0x8802},
 387        {0x0006, 0x8801},
 388        {0x007d, 0x8800},
 389        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 390
 391
 392        /* This chunk is seemingly redundant with */
 393        /* earlier commands (A11 Coef...), but if I disable it, */
 394        /* the image appears too dark.  Maybe there was some kind of */
 395        /* reset since the earlier commands, so this is necessary again. */
 396        {0x0015, 0x8608},
 397        {0x0030, 0x8609},
 398        {0xfffb, 0x860a},
 399        {0x003e, 0x860b},
 400        {0xffce, 0x860c},
 401        {0xfff4, 0x860d},
 402        {0xffeb, 0x860e},
 403        {0xffdc, 0x860f},
 404        {0x0039, 0x8610},
 405        {0x0018, 0x8657},
 406
 407        {0x0000, 0x8508},       /* Disable compression. */
 408        /* Previous line was:
 409        {0x0021, 0x8508},        * Enable compression. */
 410        {0x0032, 0x850b},       /* compression stuff */
 411        {0x0003, 0x8509},       /* compression stuff */
 412        {0x0011, 0x850a},       /* compression stuff */
 413        {0x0021, 0x850d},       /* compression stuff */
 414        {0x0010, 0x850c},       /* compression stuff */
 415        {0x0003, 0x8500},       /* *** Video mode: 160x120 */
 416        {0x0001, 0x8501},       /* Hardware-dominated snap control */
 417        {0x0061, 0x8656},       /* Window1 size 128x128, Windows2 size 128x128,
 418                                 * gamma look-up disable,
 419                                 * new edge enhancement enable */
 420        {0x0018, 0x8617},       /* Window1 start X (*2) */
 421        {0x0008, 0x8618},       /* Window1 start Y (*2) */
 422        {0x0061, 0x8656},       /* Window1 size 128x128, Windows2 size 128x128,
 423                                 * gamma look-up disable,
 424                                 * new edge enhancement enable */
 425        {0x0058, 0x8619},       /* Window2 start X (*2) */
 426        {0x0008, 0x861a},       /* Window2 start Y (*2) */
 427        {0x00ff, 0x8615},       /* High lum thresh for white balance */
 428        {0x0000, 0x8616},       /* Low lum thresh for white balance */
 429        {0x0012, 0x8700},       /* Clock speed 48Mhz/(2+2)/2= 6 Mhz */
 430        {0x0012, 0x8700},       /* Clock speed 48Mhz/(2+2)/2= 6 Mhz */
 431        /* READ { 0x0000, 0x8656 } -> 0000: 61  */
 432        {0x0028, 0x8802},    /* 375 Khz SSI clock, SSI r/w sync with VSYNC */
 433        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 434        /* READ { 0x0001, 0x8802 } -> 0000: 28  */
 435        {0x1f28, 0x8802},    /* 375 Khz SSI clock, SSI r/w sync with VSYNC */
 436        {0x0010, 0x8801},       /* SSI reg addr */
 437        {0x003e, 0x8800},       /* SSI data to write */
 438        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 439        {0x0028, 0x8802},
 440        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 441        /* READ { 0x0001, 0x8802 } -> 0000: 28  */
 442        {0x1f28, 0x8802},
 443        {0x0000, 0x8801},
 444        {0x001f, 0x8800},
 445        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 446        {0x0001, 0x8602},    /* optical black level for user settning = 1 */
 447
 448        /* Original: */
 449        {0x0023, 0x8700},       /* Clock speed 48Mhz/(3+2)/4= 2.4 Mhz */
 450        {0x000f, 0x8602},    /* optical black level for user settning = 15 */
 451
 452        {0x0028, 0x8802},
 453        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 454        /* READ { 0x0001, 0x8802 } -> 0000: 28  */
 455        {0x1f28, 0x8802},
 456        {0x0010, 0x8801},
 457        {0x007b, 0x8800},
 458        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
 459        {0x002f, 0x8651},       /* R gain for white balance ... */
 460        {0x0080, 0x8653},
 461        /* READ { 0x0000, 0x8655 } -> 0000: 00  */
 462        {0x0000, 0x8655},
 463
 464        {0x0030, 0x8112},       /* Video drop enable, ISO streaming enable */
 465        {0x0020, 0x8112},       /* Video drop enable, ISO streaming disable */
 466        /* UNKNOWN DIRECTION (URB_FUNCTION_SELECT_INTERFACE: (ALT=0) ) */
 467        {}
 468};
 469
 470/*
 471 * Initialization data for Intel EasyPC Camera CS110
 472 */
 473static const u16 spca508cs110_init_data[][2] = {
 474        {0x0000, 0x870b},       /* Reset CTL3 */
 475        {0x0003, 0x8111},       /* Soft Reset compression, memory, TG & CDSP */
 476        {0x0000, 0x8111},       /* Normal operation on reset */
 477        {0x0090, 0x8110},
 478                 /* External Clock 2x & Synchronous Serial Interface Output */
 479        {0x0020, 0x8112},       /* Video Drop packet enable */
 480        {0x0000, 0x8114},       /* Software GPIO output data */
 481        {0x0001, 0x8114},
 482        {0x0001, 0x8114},
 483        {0x0001, 0x8114},
 484        {0x0003, 0x8114},
 485
 486        /* Initial sequence Synchronous Serial Interface */
 487        {0x000f, 0x8402},       /* Memory bank Address */
 488        {0x0000, 0x8403},       /* Memory bank Address */
 489        {0x00ba, 0x8804},       /* SSI Slave address */
 490        {0x0010, 0x8802},       /* 93.75kHz SSI Clock Two DataByte */
 491        {0x0010, 0x8802},       /* 93.75kHz SSI Clock two DataByte */
 492
 493        {0x0001, 0x8801},
 494        {0x000a, 0x8805},       /* a - NWG: Dunno what this is about */
 495        {0x0000, 0x8800},
 496        {0x0010, 0x8802},
 497
 498        {0x0002, 0x8801},
 499        {0x0000, 0x8805},
 500        {0x0000, 0x8800},
 501        {0x0010, 0x8802},
 502
 503        {0x0003, 0x8801},
 504        {0x0027, 0x8805},
 505        {0x0001, 0x8800},
 506        {0x0010, 0x8802},
 507
 508        {0x0004, 0x8801},
 509        {0x0065, 0x8805},
 510        {0x0001, 0x8800},
 511        {0x0010, 0x8802},
 512
 513        {0x0005, 0x8801},
 514        {0x0003, 0x8805},
 515        {0x0000, 0x8800},
 516        {0x0010, 0x8802},
 517
 518        {0x0006, 0x8801},
 519        {0x001c, 0x8805},
 520        {0x0000, 0x8800},
 521        {0x0010, 0x8802},
 522
 523        {0x0007, 0x8801},
 524        {0x002a, 0x8805},
 525        {0x0000, 0x8800},
 526        {0x0010, 0x8802},
 527
 528        {0x0002, 0x8704},       /* External input CKIx1 */
 529        {0x0001, 0x8606},    /* 1 Line memory Read Counter (H) Result: (d)410 */
 530        {0x009a, 0x8600},       /* Line memory Read Counter (L) */
 531        {0x0001, 0x865b},       /* 1 Horizontal Offset for Valid Pixel(L) */
 532        {0x0003, 0x865c},       /* 3 Vertical Offset for Valid Lines(L) */
 533        {0x0058, 0x865d},       /* 58 Horizontal Valid Pixel Window(L) */
 534
 535        {0x0006, 0x8660},       /* Nibble data + input order */
 536
 537        {0x000a, 0x8602},       /* Optical black level set to 0x0a */
 538        {0x0000, 0x8603},       /* Optical black level Offset */
 539
 540/*      {0x0000, 0x8611},        * 0 R  Offset for white Balance */
 541/*      {0x0000, 0x8612},        * 1 Gr Offset for white Balance */
 542/*      {0x0000, 0x8613},        * 1f B  Offset for white Balance */
 543/*      {0x0000, 0x8614},        * f0 Gb Offset for white Balance */
 544
 545        {0x0040, 0x8651},   /* 2b BLUE gain for white balance  good at all 60 */
 546        {0x0030, 0x8652},       /* 41 Gr Gain for white Balance (L) */
 547        {0x0035, 0x8653},       /* 26 RED gain for white balance */
 548        {0x0035, 0x8654},       /* 40Gb Gain for white Balance (L) */
 549        {0x0041, 0x863f},
 550              /* Fixed Gamma correction enabled (makes colours look better) */
 551
 552        {0x0000, 0x8655},
 553                /* High bits for white balance*****brightness control*** */
 554        {}
 555};
 556
 557static const u16 spca508_sightcam_init_data[][2] = {
 558/* This line seems to setup the frame/canvas */
 559        {0x000f, 0x8402},
 560
 561/* These 6 lines are needed to startup the webcam */
 562        {0x0090, 0x8110},
 563        {0x0001, 0x8114},
 564        {0x0001, 0x8114},
 565        {0x0001, 0x8114},
 566        {0x0003, 0x8114},
 567        {0x0080, 0x8804},
 568
 569/* This part seems to make the pictures darker? (autobrightness?) */
 570        {0x0001, 0x8801},
 571        {0x0004, 0x8800},
 572        {0x0003, 0x8801},
 573        {0x00e0, 0x8800},
 574        {0x0004, 0x8801},
 575        {0x00b4, 0x8800},
 576        {0x0005, 0x8801},
 577        {0x0000, 0x8800},
 578
 579        {0x0006, 0x8801},
 580        {0x00e0, 0x8800},
 581        {0x0007, 0x8801},
 582        {0x000c, 0x8800},
 583
 584/* This section is just needed, it probably
 585 * does something like the previous section,
 586 * but the cam won't start if it's not included.
 587 */
 588        {0x0014, 0x8801},
 589        {0x0008, 0x8800},
 590        {0x0015, 0x8801},
 591        {0x0067, 0x8800},
 592        {0x0016, 0x8801},
 593        {0x0000, 0x8800},
 594        {0x0017, 0x8801},
 595        {0x0020, 0x8800},
 596        {0x0018, 0x8801},
 597        {0x0044, 0x8800},
 598
 599/* Makes the picture darker - and the
 600 * cam won't start if not included
 601 */
 602        {0x001e, 0x8801},
 603        {0x00ea, 0x8800},
 604        {0x001f, 0x8801},
 605        {0x0001, 0x8800},
 606        {0x0003, 0x8801},
 607        {0x00e0, 0x8800},
 608
 609/* seems to place the colors ontop of each other #1 */
 610        {0x0006, 0x8704},
 611        {0x0001, 0x870c},
 612        {0x0016, 0x8600},
 613        {0x0002, 0x8606},
 614
 615/* if not included the pictures becomes _very_ dark */
 616        {0x0064, 0x8607},
 617        {0x003a, 0x8601},
 618        {0x0000, 0x8602},
 619
 620/* seems to place the colors ontop of each other #2 */
 621        {0x0016, 0x8600},
 622        {0x0018, 0x8617},
 623        {0x0008, 0x8618},
 624        {0x00a1, 0x8656},
 625
 626/* webcam won't start if not included */
 627        {0x0007, 0x865b},
 628        {0x0001, 0x865c},
 629        {0x0058, 0x865d},
 630        {0x0048, 0x865e},
 631
 632/* adjusts the colors */
 633        {0x0049, 0x8651},
 634        {0x0040, 0x8652},
 635        {0x004c, 0x8653},
 636        {0x0040, 0x8654},
 637        {}
 638};
 639
 640static const u16 spca508_sightcam2_init_data[][2] = {
 641        {0x0020, 0x8112},
 642
 643        {0x000f, 0x8402},
 644        {0x0000, 0x8403},
 645
 646        {0x0008, 0x8201},
 647        {0x0008, 0x8200},
 648        {0x0001, 0x8200},
 649        {0x0009, 0x8201},
 650        {0x0008, 0x8200},
 651        {0x0001, 0x8200},
 652        {0x000a, 0x8201},
 653        {0x0008, 0x8200},
 654        {0x0001, 0x8200},
 655        {0x000b, 0x8201},
 656        {0x0008, 0x8200},
 657        {0x0001, 0x8200},
 658        {0x000c, 0x8201},
 659        {0x0008, 0x8200},
 660        {0x0001, 0x8200},
 661        {0x000d, 0x8201},
 662        {0x0008, 0x8200},
 663        {0x0001, 0x8200},
 664        {0x000e, 0x8201},
 665        {0x0008, 0x8200},
 666        {0x0001, 0x8200},
 667        {0x0007, 0x8201},
 668        {0x0008, 0x8200},
 669        {0x0001, 0x8200},
 670        {0x000f, 0x8201},
 671        {0x0008, 0x8200},
 672        {0x0001, 0x8200},
 673
 674        {0x0018, 0x8660},
 675        {0x0010, 0x8201},
 676
 677        {0x0008, 0x8200},
 678        {0x0001, 0x8200},
 679        {0x0011, 0x8201},
 680        {0x0008, 0x8200},
 681        {0x0001, 0x8200},
 682
 683        {0x0000, 0x86b0},
 684        {0x0034, 0x86b1},
 685        {0x0000, 0x86b2},
 686        {0x0049, 0x86b3},
 687        {0x0000, 0x86b4},
 688        {0x0000, 0x86b4},
 689
 690        {0x0012, 0x8201},
 691        {0x0008, 0x8200},
 692        {0x0001, 0x8200},
 693        {0x0013, 0x8201},
 694        {0x0008, 0x8200},
 695        {0x0001, 0x8200},
 696
 697        {0x0001, 0x86b0},
 698        {0x00aa, 0x86b1},
 699        {0x0000, 0x86b2},
 700        {0x00e4, 0x86b3},
 701        {0x0000, 0x86b4},
 702        {0x0000, 0x86b4},
 703
 704        {0x0018, 0x8660},
 705
 706        {0x0090, 0x8110},
 707        {0x0001, 0x8114},
 708        {0x0001, 0x8114},
 709        {0x0001, 0x8114},
 710        {0x0003, 0x8114},
 711
 712        {0x0080, 0x8804},
 713        {0x0003, 0x8801},
 714        {0x0012, 0x8800},
 715        {0x0004, 0x8801},
 716        {0x0005, 0x8800},
 717        {0x0005, 0x8801},
 718        {0x0000, 0x8800},
 719        {0x0006, 0x8801},
 720        {0x0000, 0x8800},
 721        {0x0007, 0x8801},
 722        {0x0000, 0x8800},
 723        {0x0008, 0x8801},
 724        {0x0005, 0x8800},
 725        {0x000a, 0x8700},
 726        {0x000e, 0x8801},
 727        {0x0004, 0x8800},
 728        {0x0005, 0x8801},
 729        {0x0047, 0x8800},
 730        {0x0006, 0x8801},
 731        {0x0000, 0x8800},
 732        {0x0007, 0x8801},
 733        {0x00c0, 0x8800},
 734        {0x0008, 0x8801},
 735        {0x0003, 0x8800},
 736        {0x0013, 0x8801},
 737        {0x0001, 0x8800},
 738        {0x0009, 0x8801},
 739        {0x0000, 0x8800},
 740        {0x000a, 0x8801},
 741        {0x0000, 0x8800},
 742        {0x000b, 0x8801},
 743        {0x0000, 0x8800},
 744        {0x000c, 0x8801},
 745        {0x0000, 0x8800},
 746        {0x000e, 0x8801},
 747        {0x0004, 0x8800},
 748        {0x000f, 0x8801},
 749        {0x0000, 0x8800},
 750        {0x0010, 0x8801},
 751        {0x0006, 0x8800},
 752        {0x0011, 0x8801},
 753        {0x0006, 0x8800},
 754        {0x0012, 0x8801},
 755        {0x0000, 0x8800},
 756        {0x0013, 0x8801},
 757        {0x0001, 0x8800},
 758
 759        {0x000a, 0x8700},
 760        {0x0000, 0x8702},
 761        {0x0000, 0x8703},
 762        {0x00c2, 0x8704},
 763        {0x0001, 0x870c},
 764
 765        {0x0044, 0x8600},
 766        {0x0002, 0x8606},
 767        {0x0064, 0x8607},
 768        {0x003a, 0x8601},
 769        {0x0008, 0x8602},
 770        {0x0044, 0x8600},
 771        {0x0018, 0x8617},
 772        {0x0008, 0x8618},
 773        {0x00a1, 0x8656},
 774        {0x0004, 0x865b},
 775        {0x0002, 0x865c},
 776        {0x0058, 0x865d},
 777        {0x0048, 0x865e},
 778        {0x0012, 0x8608},
 779        {0x002c, 0x8609},
 780        {0x0002, 0x860a},
 781        {0x002c, 0x860b},
 782        {0x00db, 0x860c},
 783        {0x00f9, 0x860d},
 784        {0x00f1, 0x860e},
 785        {0x00e3, 0x860f},
 786        {0x002c, 0x8610},
 787        {0x006c, 0x8651},
 788        {0x0041, 0x8652},
 789        {0x0059, 0x8653},
 790        {0x0040, 0x8654},
 791        {0x00fa, 0x8611},
 792        {0x00ff, 0x8612},
 793        {0x00f8, 0x8613},
 794        {0x0000, 0x8614},
 795        {0x0001, 0x863f},
 796        {0x0000, 0x8640},
 797        {0x0026, 0x8641},
 798        {0x0045, 0x8642},
 799        {0x0060, 0x8643},
 800        {0x0075, 0x8644},
 801        {0x0088, 0x8645},
 802        {0x009b, 0x8646},
 803        {0x00b0, 0x8647},
 804        {0x00c5, 0x8648},
 805        {0x00d2, 0x8649},
 806        {0x00dc, 0x864a},
 807        {0x00e5, 0x864b},
 808        {0x00eb, 0x864c},
 809        {0x00f0, 0x864d},
 810        {0x00f6, 0x864e},
 811        {0x00fa, 0x864f},
 812        {0x00ff, 0x8650},
 813        {0x0060, 0x8657},
 814        {0x0010, 0x8658},
 815        {0x0018, 0x8659},
 816        {0x0005, 0x865a},
 817        {0x0018, 0x8660},
 818        {0x0003, 0x8509},
 819        {0x0011, 0x850a},
 820        {0x0032, 0x850b},
 821        {0x0010, 0x850c},
 822        {0x0021, 0x850d},
 823        {0x0001, 0x8500},
 824        {0x0000, 0x8508},
 825        {0x0012, 0x8608},
 826        {0x002c, 0x8609},
 827        {0x0002, 0x860a},
 828        {0x0039, 0x860b},
 829        {0x00d0, 0x860c},
 830        {0x00f7, 0x860d},
 831        {0x00ed, 0x860e},
 832        {0x00db, 0x860f},
 833        {0x0039, 0x8610},
 834        {0x0012, 0x8657},
 835        {0x000c, 0x8619},
 836        {0x0004, 0x861a},
 837        {0x00a1, 0x8656},
 838        {0x00c8, 0x8615},
 839        {0x0032, 0x8616},
 840
 841        {0x0030, 0x8112},
 842        {0x0020, 0x8112},
 843        {0x0020, 0x8112},
 844        {0x000f, 0x8402},
 845        {0x0000, 0x8403},
 846
 847        {0x0090, 0x8110},
 848        {0x0001, 0x8114},
 849        {0x0001, 0x8114},
 850        {0x0001, 0x8114},
 851        {0x0003, 0x8114},
 852        {0x0080, 0x8804},
 853
 854        {0x0003, 0x8801},
 855        {0x0012, 0x8800},
 856        {0x0004, 0x8801},
 857        {0x0005, 0x8800},
 858        {0x0005, 0x8801},
 859        {0x0047, 0x8800},
 860        {0x0006, 0x8801},
 861        {0x0000, 0x8800},
 862        {0x0007, 0x8801},
 863        {0x00c0, 0x8800},
 864        {0x0008, 0x8801},
 865        {0x0003, 0x8800},
 866        {0x000a, 0x8700},
 867        {0x000e, 0x8801},
 868        {0x0004, 0x8800},
 869        {0x0005, 0x8801},
 870        {0x0047, 0x8800},
 871        {0x0006, 0x8801},
 872        {0x0000, 0x8800},
 873        {0x0007, 0x8801},
 874        {0x00c0, 0x8800},
 875        {0x0008, 0x8801},
 876        {0x0003, 0x8800},
 877        {0x0013, 0x8801},
 878        {0x0001, 0x8800},
 879        {0x0009, 0x8801},
 880        {0x0000, 0x8800},
 881        {0x000a, 0x8801},
 882        {0x0000, 0x8800},
 883        {0x000b, 0x8801},
 884        {0x0000, 0x8800},
 885        {0x000c, 0x8801},
 886        {0x0000, 0x8800},
 887        {0x000e, 0x8801},
 888        {0x0004, 0x8800},
 889        {0x000f, 0x8801},
 890        {0x0000, 0x8800},
 891        {0x0010, 0x8801},
 892        {0x0006, 0x8800},
 893        {0x0011, 0x8801},
 894        {0x0006, 0x8800},
 895        {0x0012, 0x8801},
 896        {0x0000, 0x8800},
 897        {0x0013, 0x8801},
 898        {0x0001, 0x8800},
 899        {0x000a, 0x8700},
 900        {0x0000, 0x8702},
 901        {0x0000, 0x8703},
 902        {0x00c2, 0x8704},
 903        {0x0001, 0x870c},
 904        {0x0044, 0x8600},
 905        {0x0002, 0x8606},
 906        {0x0064, 0x8607},
 907        {0x003a, 0x8601},
 908        {0x0008, 0x8602},
 909        {0x0044, 0x8600},
 910        {0x0018, 0x8617},
 911        {0x0008, 0x8618},
 912        {0x00a1, 0x8656},
 913        {0x0004, 0x865b},
 914        {0x0002, 0x865c},
 915        {0x0058, 0x865d},
 916        {0x0048, 0x865e},
 917        {0x0012, 0x8608},
 918        {0x002c, 0x8609},
 919        {0x0002, 0x860a},
 920        {0x002c, 0x860b},
 921        {0x00db, 0x860c},
 922        {0x00f9, 0x860d},
 923        {0x00f1, 0x860e},
 924        {0x00e3, 0x860f},
 925        {0x002c, 0x8610},
 926        {0x006c, 0x8651},
 927        {0x0041, 0x8652},
 928        {0x0059, 0x8653},
 929        {0x0040, 0x8654},
 930        {0x00fa, 0x8611},
 931        {0x00ff, 0x8612},
 932        {0x00f8, 0x8613},
 933        {0x0000, 0x8614},
 934        {0x0001, 0x863f},
 935        {0x0000, 0x8640},
 936        {0x0026, 0x8641},
 937        {0x0045, 0x8642},
 938        {0x0060, 0x8643},
 939        {0x0075, 0x8644},
 940        {0x0088, 0x8645},
 941        {0x009b, 0x8646},
 942        {0x00b0, 0x8647},
 943        {0x00c5, 0x8648},
 944        {0x00d2, 0x8649},
 945        {0x00dc, 0x864a},
 946        {0x00e5, 0x864b},
 947        {0x00eb, 0x864c},
 948        {0x00f0, 0x864d},
 949        {0x00f6, 0x864e},
 950        {0x00fa, 0x864f},
 951        {0x00ff, 0x8650},
 952        {0x0060, 0x8657},
 953        {0x0010, 0x8658},
 954        {0x0018, 0x8659},
 955        {0x0005, 0x865a},
 956        {0x0018, 0x8660},
 957        {0x0003, 0x8509},
 958        {0x0011, 0x850a},
 959        {0x0032, 0x850b},
 960        {0x0010, 0x850c},
 961        {0x0021, 0x850d},
 962        {0x0001, 0x8500},
 963        {0x0000, 0x8508},
 964
 965        {0x0012, 0x8608},
 966        {0x002c, 0x8609},
 967        {0x0002, 0x860a},
 968        {0x0039, 0x860b},
 969        {0x00d0, 0x860c},
 970        {0x00f7, 0x860d},
 971        {0x00ed, 0x860e},
 972        {0x00db, 0x860f},
 973        {0x0039, 0x8610},
 974        {0x0012, 0x8657},
 975        {0x0064, 0x8619},
 976
 977/* This line starts it all, it is not needed here */
 978/* since it has been build into the driver */
 979/* jfm: don't start now */
 980/*      {0x0030, 0x8112}, */
 981        {}
 982};
 983
 984/*
 985 * Initialization data for Creative Webcam Vista
 986 */
 987static const u16 spca508_vista_init_data[][2] = {
 988        {0x0008, 0x8200},       /* Clear register */
 989        {0x0000, 0x870b},       /* Reset CTL3 */
 990        {0x0020, 0x8112},       /* Video Drop packet enable */
 991        {0x0003, 0x8111},       /* Soft Reset compression, memory, TG & CDSP */
 992        {0x0000, 0x8110},       /* Disable everything */
 993        {0x0000, 0x8114},       /* Software GPIO output data */
 994        {0x0000, 0x8114},
 995
 996        {0x0003, 0x8111},
 997        {0x0000, 0x8111},
 998        {0x0090, 0x8110},    /* Enable: SSI output, External 2X clock output */
 999        {0x0020, 0x8112},
1000        {0x0000, 0x8114},
1001        {0x0001, 0x8114},
1002        {0x0001, 0x8114},
1003        {0x0001, 0x8114},
1004        {0x0003, 0x8114},
1005
1006        {0x000f, 0x8402},       /* Memory bank Address */
1007        {0x0000, 0x8403},       /* Memory bank Address */
1008        {0x00ba, 0x8804},       /* SSI Slave address */
1009        {0x0010, 0x8802},       /* 93.75kHz SSI Clock Two DataByte */
1010
1011        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
1012        /* READ { 0x0001, 0x8802 } -> 0000: 10  */
1013        {0x0010, 0x8802},       /* Will write 2 bytes (DATA1+DATA2) */
1014        {0x0020, 0x8801},       /* Register address for SSI read/write */
1015        {0x0044, 0x8805},       /* DATA2 */
1016        {0x0004, 0x8800},       /* DATA1 -> write triggered */
1017        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
1018
1019        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
1020        /* READ { 0x0001, 0x8802 } -> 0000: 10  */
1021        {0x0010, 0x8802},
1022        {0x0009, 0x8801},
1023        {0x0042, 0x8805},
1024        {0x0001, 0x8800},
1025        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
1026
1027        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
1028        /* READ { 0x0001, 0x8802 } -> 0000: 10  */
1029        {0x0010, 0x8802},
1030        {0x003c, 0x8801},
1031        {0x0001, 0x8805},
1032        {0x0000, 0x8800},
1033        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
1034
1035        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
1036        /* READ { 0x0001, 0x8802 } -> 0000: 10  */
1037        {0x0010, 0x8802},
1038        {0x0001, 0x8801},
1039        {0x000a, 0x8805},
1040        {0x0000, 0x8800},
1041        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
1042
1043        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
1044        /* READ { 0x0001, 0x8802 } -> 0000: 10  */
1045        {0x0010, 0x8802},
1046        {0x0002, 0x8801},
1047        {0x0000, 0x8805},
1048        {0x0000, 0x8800},
1049        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
1050
1051        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
1052        /* READ { 0x0001, 0x8802 } -> 0000: 10  */
1053        {0x0010, 0x8802},
1054        {0x0003, 0x8801},
1055        {0x0027, 0x8805},
1056        {0x0001, 0x8800},
1057        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
1058
1059        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
1060        /* READ { 0x0001, 0x8802 } -> 0000: 10  */
1061        {0x0010, 0x8802},
1062        {0x0004, 0x8801},
1063        {0x0065, 0x8805},
1064        {0x0001, 0x8800},
1065        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
1066
1067        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
1068        /* READ { 0x0001, 0x8802 } -> 0000: 10  */
1069        {0x0010, 0x8802},
1070        {0x0005, 0x8801},
1071        {0x0003, 0x8805},
1072        {0x0000, 0x8800},
1073        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
1074
1075        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
1076        /* READ { 0x0001, 0x8802 } -> 0000: 10  */
1077        {0x0010, 0x8802},
1078        {0x0006, 0x8801},
1079        {0x001c, 0x8805},
1080        {0x0000, 0x8800},
1081        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
1082
1083        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
1084        /* READ { 0x0001, 0x8802 } -> 0000: 10  */
1085        {0x0010, 0x8802},
1086        {0x0007, 0x8801},
1087        {0x002a, 0x8805},
1088        {0x0000, 0x8800},
1089        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
1090
1091        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
1092        /* READ { 0x0001, 0x8802 } -> 0000: 10  */
1093        {0x0010, 0x8802},
1094        {0x000e, 0x8801},
1095        {0x0000, 0x8805},
1096        {0x0000, 0x8800},
1097        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
1098
1099        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
1100        /* READ { 0x0001, 0x8802 } -> 0000: 10  */
1101        {0x0010, 0x8802},
1102        {0x0028, 0x8801},
1103        {0x002e, 0x8805},
1104        {0x0000, 0x8800},
1105        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
1106
1107        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
1108        /* READ { 0x0001, 0x8802 } -> 0000: 10  */
1109        {0x0010, 0x8802},
1110        {0x0039, 0x8801},
1111        {0x0013, 0x8805},
1112        {0x0000, 0x8800},
1113        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
1114
1115        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
1116        /* READ { 0x0001, 0x8802 } -> 0000: 10  */
1117        {0x0010, 0x8802},
1118        {0x003b, 0x8801},
1119        {0x000c, 0x8805},
1120        {0x0000, 0x8800},
1121        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
1122
1123        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
1124        /* READ { 0x0001, 0x8802 } -> 0000: 10  */
1125        {0x0010, 0x8802},
1126        {0x0035, 0x8801},
1127        {0x0028, 0x8805},
1128        {0x0000, 0x8800},
1129        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
1130
1131        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
1132        /* READ { 0x0001, 0x8802 } -> 0000: 10  */
1133        {0x0010, 0x8802},
1134        {0x0009, 0x8801},
1135        {0x0042, 0x8805},
1136        {0x0001, 0x8800},
1137        /* READ { 0x0001, 0x8803 } -> 0000: 00  */
1138
1139        {0x0050, 0x8703},
1140        {0x0002, 0x8704},       /* External input CKIx1 */
1141        {0x0001, 0x870c},       /* Select CKOx2 output */
1142        {0x009a, 0x8600},       /* Line memory Read Counter (L) */
1143        {0x0001, 0x8606},    /* 1 Line memory Read Counter (H) Result: (d)410 */
1144        {0x0023, 0x8601},
1145        {0x0010, 0x8602},
1146        {0x000a, 0x8603},
1147        {0x009a, 0x8600},
1148        {0x0001, 0x865b},       /* 1 Horizontal Offset for Valid Pixel(L) */
1149        {0x0003, 0x865c},       /* Vertical offset for valid lines (L) */
1150        {0x0058, 0x865d},       /* Horizontal valid pixels window (L) */
1151        {0x0048, 0x865e},       /* Vertical valid lines window (L) */
1152        {0x0000, 0x865f},
1153
1154        {0x0006, 0x8660},
1155                    /* Enable nibble data input, select nibble input order */
1156
1157        {0x0013, 0x8608},       /* A11 Coeficients for color correction */
1158        {0x0028, 0x8609},
1159                    /* Note: these values are confirmed at the end of array */
1160        {0x0005, 0x860a},       /* ... */
1161        {0x0025, 0x860b},
1162        {0x00e1, 0x860c},
1163        {0x00fa, 0x860d},
1164        {0x00f4, 0x860e},
1165        {0x00e8, 0x860f},
1166        {0x0025, 0x8610},       /* A33 Coef. */
1167        {0x00fc, 0x8611},       /* White balance offset: R */
1168        {0x0001, 0x8612},       /* White balance offset: Gr */
1169        {0x00fe, 0x8613},       /* White balance offset: B */
1170        {0x0000, 0x8614},       /* White balance offset: Gb */
1171
1172        {0x0064, 0x8651},       /* R gain for white balance (L) */
1173        {0x0040, 0x8652},       /* Gr gain for white balance (L) */
1174        {0x0066, 0x8653},       /* B gain for white balance (L) */
1175        {0x0040, 0x8654},       /* Gb gain for white balance (L) */
1176        {0x0001, 0x863f},       /* Enable fixed gamma correction */
1177
1178        {0x00a1, 0x8656},       /* Size - Window1: 256x256, Window2: 128x128,
1179                                 * UV division: UV no change,
1180                                 * Enable New edge enhancement */
1181        {0x0018, 0x8657},       /* Edge gain high threshold */
1182        {0x0020, 0x8658},       /* Edge gain low threshold */
1183        {0x000a, 0x8659},       /* Edge bandwidth high threshold */
1184        {0x0005, 0x865a},       /* Edge bandwidth low threshold */
1185        {0x0064, 0x8607},       /* UV filter enable */
1186
1187        {0x0016, 0x8660},
1188        {0x0000, 0x86b0},       /* Bad pixels compensation address */
1189        {0x00dc, 0x86b1},       /* X coord for bad pixels compensation (L) */
1190        {0x0000, 0x86b2},
1191        {0x0009, 0x86b3},       /* Y coord for bad pixels compensation (L) */
1192        {0x0000, 0x86b4},
1193
1194        {0x0001, 0x86b0},
1195        {0x00f5, 0x86b1},
1196        {0x0000, 0x86b2},
1197        {0x00c6, 0x86b3},
1198        {0x0000, 0x86b4},
1199
1200        {0x0002, 0x86b0},
1201        {0x001c, 0x86b1},
1202        {0x0001, 0x86b2},
1203        {0x00d7, 0x86b3},
1204        {0x0000, 0x86b4},
1205
1206        {0x0003, 0x86b0},
1207        {0x001c, 0x86b1},
1208        {0x0001, 0x86b2},
1209        {0x00d8, 0x86b3},
1210        {0x0000, 0x86b4},
1211
1212        {0x0004, 0x86b0},
1213        {0x001d, 0x86b1},
1214        {0x0001, 0x86b2},
1215        {0x00d8, 0x86b3},
1216        {0x0000, 0x86b4},
1217        {0x001e, 0x8660},
1218
1219        /* READ { 0x0000, 0x8608 } -> 0000: 13  */
1220        /* READ { 0x0000, 0x8609 } -> 0000: 28  */
1221        /* READ { 0x0000, 0x8610 } -> 0000: 05  */
1222        /* READ { 0x0000, 0x8611 } -> 0000: 25  */
1223        /* READ { 0x0000, 0x8612 } -> 0000: e1  */
1224        /* READ { 0x0000, 0x8613 } -> 0000: fa  */
1225        /* READ { 0x0000, 0x8614 } -> 0000: f4  */
1226        /* READ { 0x0000, 0x8615 } -> 0000: e8  */
1227        /* READ { 0x0000, 0x8616 } -> 0000: 25  */
1228        {}
1229};
1230
1231static int reg_write(struct gspca_dev *gspca_dev, u16 index, u16 value)
1232{
1233        int ret;
1234        struct usb_device *dev = gspca_dev->dev;
1235
1236        ret = usb_control_msg(dev,
1237                        usb_sndctrlpipe(dev, 0),
1238                        0,              /* request */
1239                        USB_TYPE_VENDOR | USB_RECIP_DEVICE,
1240                        value, index, NULL, 0, 500);
1241        gspca_dbg(gspca_dev, D_USBO, "reg write i:0x%04x = 0x%02x\n",
1242                  index, value);
1243        if (ret < 0)
1244                pr_err("reg write: error %d\n", ret);
1245        return ret;
1246}
1247
1248/* read 1 byte */
1249/* returns: negative is error, pos or zero is data */
1250static int reg_read(struct gspca_dev *gspca_dev,
1251                        u16 index)      /* wIndex */
1252{
1253        int ret;
1254
1255        ret = usb_control_msg(gspca_dev->dev,
1256                        usb_rcvctrlpipe(gspca_dev->dev, 0),
1257                        0,                      /* register */
1258                        USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
1259                        0,              /* value */
1260                        index,
1261                        gspca_dev->usb_buf, 1,
1262                        500);                   /* timeout */
1263        gspca_dbg(gspca_dev, D_USBI, "reg read i:%04x --> %02x\n",
1264                  index, gspca_dev->usb_buf[0]);
1265        if (ret < 0) {
1266                pr_err("reg_read err %d\n", ret);
1267                return ret;
1268        }
1269        return gspca_dev->usb_buf[0];
1270}
1271
1272/* send 1 or 2 bytes to the sensor via the Synchronous Serial Interface */
1273static int ssi_w(struct gspca_dev *gspca_dev,
1274                u16 reg, u16 val)
1275{
1276        int ret, retry;
1277
1278        ret = reg_write(gspca_dev, 0x8802, reg >> 8);
1279        if (ret < 0)
1280                goto out;
1281        ret = reg_write(gspca_dev, 0x8801, reg & 0x00ff);
1282        if (ret < 0)
1283                goto out;
1284        if ((reg & 0xff00) == 0x1000) {         /* if 2 bytes */
1285                ret = reg_write(gspca_dev, 0x8805, val & 0x00ff);
1286                if (ret < 0)
1287                        goto out;
1288                val >>= 8;
1289        }
1290        ret = reg_write(gspca_dev, 0x8800, val);
1291        if (ret < 0)
1292                goto out;
1293
1294        /* poll until not busy */
1295        retry = 10;
1296        for (;;) {
1297                ret = reg_read(gspca_dev, 0x8803);
1298                if (ret < 0)
1299                        break;
1300                if (gspca_dev->usb_buf[0] == 0)
1301                        break;
1302                if (--retry <= 0) {
1303                        gspca_err(gspca_dev, "ssi_w busy %02x\n",
1304                                  gspca_dev->usb_buf[0]);
1305                        ret = -1;
1306                        break;
1307                }
1308                msleep(8);
1309        }
1310
1311out:
1312        return ret;
1313}
1314
1315static int write_vector(struct gspca_dev *gspca_dev,
1316                        const u16 (*data)[2])
1317{
1318        int ret = 0;
1319
1320        while ((*data)[1] != 0) {
1321                if ((*data)[1] & 0x8000) {
1322                        if ((*data)[1] == 0xdd00)       /* delay */
1323                                msleep((*data)[0]);
1324                        else
1325                                ret = reg_write(gspca_dev, (*data)[1],
1326                                                                (*data)[0]);
1327                } else {
1328                        ret = ssi_w(gspca_dev, (*data)[1], (*data)[0]);
1329                }
1330                if (ret < 0)
1331                        break;
1332                data++;
1333        }
1334        return ret;
1335}
1336
1337/* this function is called at probe time */
1338static int sd_config(struct gspca_dev *gspca_dev,
1339                        const struct usb_device_id *id)
1340{
1341        struct sd *sd = (struct sd *) gspca_dev;
1342        struct cam *cam;
1343        const u16 (*init_data)[2];
1344        static const u16 (*(init_data_tb[]))[2] = {
1345                spca508_vista_init_data,        /* CreativeVista 0 */
1346                spca508_sightcam_init_data,     /* HamaUSBSightcam 1 */
1347                spca508_sightcam2_init_data,    /* HamaUSBSightcam2 2 */
1348                spca508cs110_init_data,         /* IntelEasyPCCamera 3 */
1349                spca508cs110_init_data,         /* MicroInnovationIC200 4 */
1350                spca508_init_data,              /* ViewQuestVQ110 5 */
1351        };
1352        int data1, data2;
1353
1354        /* Read from global register the USB product and vendor IDs, just to
1355         * prove that we can communicate with the device.  This works, which
1356         * confirms at we are communicating properly and that the device
1357         * is a 508. */
1358        data1 = reg_read(gspca_dev, 0x8104);
1359        data2 = reg_read(gspca_dev, 0x8105);
1360        gspca_dbg(gspca_dev, D_PROBE, "Webcam Vendor ID: 0x%02x%02x\n",
1361                  data2, data1);
1362
1363        data1 = reg_read(gspca_dev, 0x8106);
1364        data2 = reg_read(gspca_dev, 0x8107);
1365        gspca_dbg(gspca_dev, D_PROBE, "Webcam Product ID: 0x%02x%02x\n",
1366                  data2, data1);
1367
1368        data1 = reg_read(gspca_dev, 0x8621);
1369        gspca_dbg(gspca_dev, D_PROBE, "Window 1 average luminance: %d\n",
1370                  data1);
1371
1372        cam = &gspca_dev->cam;
1373        cam->cam_mode = sif_mode;
1374        cam->nmodes = ARRAY_SIZE(sif_mode);
1375
1376        sd->subtype = id->driver_info;
1377
1378        init_data = init_data_tb[sd->subtype];
1379        return write_vector(gspca_dev, init_data);
1380}
1381
1382/* this function is called at probe and resume time */
1383static int sd_init(struct gspca_dev *gspca_dev)
1384{
1385        return 0;
1386}
1387
1388static int sd_start(struct gspca_dev *gspca_dev)
1389{
1390        int mode;
1391
1392        mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
1393        reg_write(gspca_dev, 0x8500, mode);
1394        switch (mode) {
1395        case 0:
1396        case 1:
1397                reg_write(gspca_dev, 0x8700, 0x28); /* clock */
1398                break;
1399        default:
1400/*      case 2: */
1401/*      case 3: */
1402                reg_write(gspca_dev, 0x8700, 0x23); /* clock */
1403                break;
1404        }
1405        reg_write(gspca_dev, 0x8112, 0x10 | 0x20);
1406        return 0;
1407}
1408
1409static void sd_stopN(struct gspca_dev *gspca_dev)
1410{
1411        /* Video ISO disable, Video Drop Packet enable: */
1412        reg_write(gspca_dev, 0x8112, 0x20);
1413}
1414
1415static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1416                        u8 *data,                       /* isoc packet */
1417                        int len)                        /* iso packet length */
1418{
1419        switch (data[0]) {
1420        case 0:                         /* start of frame */
1421                gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
1422                data += SPCA508_OFFSET_DATA;
1423                len -= SPCA508_OFFSET_DATA;
1424                gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
1425                break;
1426        case 0xff:                      /* drop */
1427                break;
1428        default:
1429                data += 1;
1430                len -= 1;
1431                gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
1432                break;
1433        }
1434}
1435
1436static void setbrightness(struct gspca_dev *gspca_dev, s32 brightness)
1437{
1438        /* MX seem contrast */
1439        reg_write(gspca_dev, 0x8651, brightness);
1440        reg_write(gspca_dev, 0x8652, brightness);
1441        reg_write(gspca_dev, 0x8653, brightness);
1442        reg_write(gspca_dev, 0x8654, brightness);
1443}
1444
1445static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
1446{
1447        struct gspca_dev *gspca_dev =
1448                container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
1449
1450        gspca_dev->usb_err = 0;
1451
1452        if (!gspca_dev->streaming)
1453                return 0;
1454
1455        switch (ctrl->id) {
1456        case V4L2_CID_BRIGHTNESS:
1457                setbrightness(gspca_dev, ctrl->val);
1458                break;
1459        }
1460        return gspca_dev->usb_err;
1461}
1462
1463static const struct v4l2_ctrl_ops sd_ctrl_ops = {
1464        .s_ctrl = sd_s_ctrl,
1465};
1466
1467static int sd_init_controls(struct gspca_dev *gspca_dev)
1468{
1469        struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
1470
1471        gspca_dev->vdev.ctrl_handler = hdl;
1472        v4l2_ctrl_handler_init(hdl, 5);
1473        v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1474                        V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
1475
1476        if (hdl->error) {
1477                pr_err("Could not initialize controls\n");
1478                return hdl->error;
1479        }
1480        return 0;
1481}
1482
1483/* sub-driver description */
1484static const struct sd_desc sd_desc = {
1485        .name = MODULE_NAME,
1486        .config = sd_config,
1487        .init = sd_init,
1488        .init_controls = sd_init_controls,
1489        .start = sd_start,
1490        .stopN = sd_stopN,
1491        .pkt_scan = sd_pkt_scan,
1492};
1493
1494/* -- module initialisation -- */
1495static const struct usb_device_id device_table[] = {
1496        {USB_DEVICE(0x0130, 0x0130), .driver_info = HamaUSBSightcam},
1497        {USB_DEVICE(0x041e, 0x4018), .driver_info = CreativeVista},
1498        {USB_DEVICE(0x0733, 0x0110), .driver_info = ViewQuestVQ110},
1499        {USB_DEVICE(0x0af9, 0x0010), .driver_info = HamaUSBSightcam},
1500        {USB_DEVICE(0x0af9, 0x0011), .driver_info = HamaUSBSightcam2},
1501        {USB_DEVICE(0x8086, 0x0110), .driver_info = IntelEasyPCCamera},
1502        {}
1503};
1504MODULE_DEVICE_TABLE(usb, device_table);
1505
1506/* -- device connect -- */
1507static int sd_probe(struct usb_interface *intf,
1508                        const struct usb_device_id *id)
1509{
1510        return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1511                                THIS_MODULE);
1512}
1513
1514static struct usb_driver sd_driver = {
1515        .name = MODULE_NAME,
1516        .id_table = device_table,
1517        .probe = sd_probe,
1518        .disconnect = gspca_disconnect,
1519#ifdef CONFIG_PM
1520        .suspend = gspca_suspend,
1521        .resume = gspca_resume,
1522        .reset_resume = gspca_resume,
1523#endif
1524};
1525
1526module_usb_driver(sd_driver);
1527