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