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