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