cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

spca508.c (41019B)


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