brintos

brintos / linux-shallow public Read only

0
0
Text · 40.1 KiB · 754ab1d Raw
1527 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * SPCA508 chip based cameras subdriver4 *5 * Copyright (C) 2009 Jean-Francois Moine <http://moinejf.free.fr>6 */7 8#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt9 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 024#define HamaUSBSightcam 125#define HamaUSBSightcam2 226#define IntelEasyPCCamera 327#define MicroInnovationIC200 428#define ViewQuestVQ110 529};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 3756 57/*58 * Initialization data: this is the first set-up data written to the59 * 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 CS110472 */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 probably585 * 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 the600 * cam won't start if not included601 */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 Vista986 */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			else1325				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 to1355	 * prove that we can communicate with the device.  This works, which1356	 * confirms at we are communicating properly and that the device1357	 * 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_PM1520	.suspend = gspca_suspend,1521	.resume = gspca_resume,1522	.reset_resume = gspca_resume,1523#endif1524};1525 1526module_usb_driver(sd_driver);1527