root/drivers/media/usb/gspca/spca508.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. reg_write
  2. reg_read
  3. ssi_w
  4. write_vector
  5. sd_config
  6. sd_init
  7. sd_start
  8. sd_stopN
  9. sd_pkt_scan
  10. setbrightness
  11. sd_s_ctrl
  12. sd_init_controls
  13. sd_probe

   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 
  14 MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
  15 MODULE_DESCRIPTION("GSPCA/SPCA508 USB Camera Driver");
  16 MODULE_LICENSE("GPL");
  17 
  18 /* specific webcam descriptor */
  19 struct 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 
  31 static 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  */
  61 static 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  */
 473 static 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 
 557 static 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 
 640 static 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  */
 987 static 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 
1231 static 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 */
1250 static 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 */
1273 static 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 
1311 out:
1312         return ret;
1313 }
1314 
1315 static 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 */
1338 static 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 */
1383 static int sd_init(struct gspca_dev *gspca_dev)
1384 {
1385         return 0;
1386 }
1387 
1388 static 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 
1409 static 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 
1415 static 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 
1436 static 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 
1445 static 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 
1463 static const struct v4l2_ctrl_ops sd_ctrl_ops = {
1464         .s_ctrl = sd_s_ctrl,
1465 };
1466 
1467 static 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 */
1484 static 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 -- */
1495 static 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 };
1504 MODULE_DEVICE_TABLE(usb, device_table);
1505 
1506 /* -- device connect -- */
1507 static 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 
1514 static 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 
1526 module_usb_driver(sd_driver);

/* [<][>][^][v][top][bottom][index][help] */