1 /* 2 * ov534-ov9xxx gspca driver 3 * 4 * Copyright (C) 2009-2011 Jean-Francois Moine http://moinejf.free.fr 5 * Copyright (C) 2008 Antonio Ospite <ospite@studenti.unina.it> 6 * Copyright (C) 2008 Jim Paris <jim@jtan.com> 7 * 8 * Based on a prototype written by Mark Ferrell <majortrips@gmail.com> 9 * USB protocol reverse engineered by Jim Paris <jim@jtan.com> 10 * https://jim.sh/svn/jim/devl/playstation/ps3/eye/test/ 11 * 12 * This program is free software; you can redistribute it and/or modify 13 * it under the terms of the GNU General Public License as published by 14 * the Free Software Foundation; either version 2 of the License, or 15 * any later version. 16 * 17 * This program is distributed in the hope that it will be useful, 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 * GNU General Public License for more details. 21 * 22 * You should have received a copy of the GNU General Public License 23 * along with this program; if not, write to the Free Software 24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 25 */ 26 27 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 28 29 #define MODULE_NAME "ov534_9" 30 31 #include "gspca.h" 32 33 #define OV534_REG_ADDRESS 0xf1 /* sensor address */ 34 #define OV534_REG_SUBADDR 0xf2 35 #define OV534_REG_WRITE 0xf3 36 #define OV534_REG_READ 0xf4 37 #define OV534_REG_OPERATION 0xf5 38 #define OV534_REG_STATUS 0xf6 39 40 #define OV534_OP_WRITE_3 0x37 41 #define OV534_OP_WRITE_2 0x33 42 #define OV534_OP_READ_2 0xf9 43 44 #define CTRL_TIMEOUT 500 45 46 MODULE_AUTHOR("Jean-Francois Moine <moinejf@free.fr>"); 47 MODULE_DESCRIPTION("GSPCA/OV534_9 USB Camera Driver"); 48 MODULE_LICENSE("GPL"); 49 50 /* specific webcam descriptor */ 51 struct sd { 52 struct gspca_dev gspca_dev; /* !! must be the first item */ 53 __u32 last_pts; 54 u8 last_fid; 55 56 u8 sensor; 57 }; 58 enum sensors { 59 SENSOR_OV965x, /* ov9657 */ 60 SENSOR_OV971x, /* ov9712 */ 61 SENSOR_OV562x, /* ov5621 */ 62 SENSOR_OV361x, /* ov3610 */ 63 NSENSORS 64 }; 65 66 static const struct v4l2_pix_format ov965x_mode[] = { 67 #define QVGA_MODE 0 68 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 69 .bytesperline = 320, 70 .sizeimage = 320 * 240 * 3 / 8 + 590, 71 .colorspace = V4L2_COLORSPACE_JPEG}, 72 #define VGA_MODE 1 73 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 74 .bytesperline = 640, 75 .sizeimage = 640 * 480 * 3 / 8 + 590, 76 .colorspace = V4L2_COLORSPACE_JPEG}, 77 #define SVGA_MODE 2 78 {800, 600, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 79 .bytesperline = 800, 80 .sizeimage = 800 * 600 * 3 / 8 + 590, 81 .colorspace = V4L2_COLORSPACE_JPEG}, 82 #define XGA_MODE 3 83 {1024, 768, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 84 .bytesperline = 1024, 85 .sizeimage = 1024 * 768 * 3 / 8 + 590, 86 .colorspace = V4L2_COLORSPACE_JPEG}, 87 #define SXGA_MODE 4 88 {1280, 1024, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 89 .bytesperline = 1280, 90 .sizeimage = 1280 * 1024 * 3 / 8 + 590, 91 .colorspace = V4L2_COLORSPACE_JPEG}, 92 }; 93 94 static const struct v4l2_pix_format ov971x_mode[] = { 95 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 96 .bytesperline = 640, 97 .sizeimage = 640 * 480, 98 .colorspace = V4L2_COLORSPACE_SRGB 99 } 100 }; 101 102 static const struct v4l2_pix_format ov562x_mode[] = { 103 {2592, 1680, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 104 .bytesperline = 2592, 105 .sizeimage = 2592 * 1680, 106 .colorspace = V4L2_COLORSPACE_SRGB 107 } 108 }; 109 110 enum ov361x { 111 ov361x_2048 = 0, 112 ov361x_1600, 113 ov361x_1024, 114 ov361x_640, 115 ov361x_320, 116 ov361x_160, 117 ov361x_last 118 }; 119 120 static const struct v4l2_pix_format ov361x_mode[] = { 121 {0x800, 0x600, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 122 .bytesperline = 0x800, 123 .sizeimage = 0x800 * 0x600, 124 .colorspace = V4L2_COLORSPACE_SRGB}, 125 {1600, 1200, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 126 .bytesperline = 1600, 127 .sizeimage = 1600 * 1200, 128 .colorspace = V4L2_COLORSPACE_SRGB}, 129 {1024, 768, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 130 .bytesperline = 768, 131 .sizeimage = 1024 * 768, 132 .colorspace = V4L2_COLORSPACE_SRGB}, 133 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 134 .bytesperline = 640, 135 .sizeimage = 640 * 480, 136 .colorspace = V4L2_COLORSPACE_SRGB}, 137 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 138 .bytesperline = 320, 139 .sizeimage = 320 * 240, 140 .colorspace = V4L2_COLORSPACE_SRGB}, 141 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 142 .bytesperline = 160, 143 .sizeimage = 160 * 120, 144 .colorspace = V4L2_COLORSPACE_SRGB} 145 }; 146 147 static const u8 ov361x_start_2048[][2] = { 148 {0x12, 0x80}, 149 {0x13, 0xcf}, 150 {0x14, 0x40}, 151 {0x15, 0x00}, 152 {0x01, 0x80}, 153 {0x02, 0x80}, 154 {0x04, 0x70}, 155 {0x0d, 0x40}, 156 {0x0f, 0x47}, 157 {0x11, 0x81}, 158 {0x32, 0x36}, 159 {0x33, 0x0c}, 160 {0x34, 0x00}, 161 {0x35, 0x90}, 162 {0x12, 0x00}, 163 {0x17, 0x10}, 164 {0x18, 0x90}, 165 {0x19, 0x00}, 166 {0x1a, 0xc0}, 167 }; 168 static const u8 ov361x_bridge_start_2048[][2] = { 169 {0xf1, 0x60}, 170 {0x88, 0x00}, 171 {0x89, 0x08}, 172 {0x8a, 0x00}, 173 {0x8b, 0x06}, 174 {0x8c, 0x01}, 175 {0x8d, 0x10}, 176 {0x1c, 0x00}, 177 {0x1d, 0x48}, 178 {0x1d, 0x00}, 179 {0x1d, 0xff}, 180 {0x1c, 0x0a}, 181 {0x1d, 0x2e}, 182 {0x1d, 0x1e}, 183 }; 184 185 static const u8 ov361x_start_1600[][2] = { 186 {0x12, 0x80}, 187 {0x13, 0xcf}, 188 {0x14, 0x40}, 189 {0x15, 0x00}, 190 {0x01, 0x80}, 191 {0x02, 0x80}, 192 {0x04, 0x70}, 193 {0x0d, 0x40}, 194 {0x0f, 0x47}, 195 {0x11, 0x81}, 196 {0x32, 0x36}, 197 {0x33, 0x0C}, 198 {0x34, 0x00}, 199 {0x35, 0x90}, 200 {0x12, 0x00}, 201 {0x17, 0x10}, 202 {0x18, 0x90}, 203 {0x19, 0x00}, 204 {0x1a, 0xc0}, 205 }; 206 static const u8 ov361x_bridge_start_1600[][2] = { 207 {0xf1, 0x60}, /* Hsize[7:0] */ 208 {0x88, 0x00}, /* Hsize[15:8] Write Only, can't read */ 209 {0x89, 0x08}, /* Vsize[7:0] */ 210 {0x8a, 0x00}, /* Vsize[15:8] Write Only, can't read */ 211 {0x8b, 0x06}, /* for Iso */ 212 {0x8c, 0x01}, /* RAW input */ 213 {0x8d, 0x10}, 214 {0x1c, 0x00}, /* RAW output, Iso transfer */ 215 {0x1d, 0x48}, 216 {0x1d, 0x00}, 217 {0x1d, 0xff}, 218 {0x1c, 0x0a}, /* turn off JPEG, Iso mode */ 219 {0x1d, 0x2e}, /* for Iso */ 220 {0x1d, 0x1e}, 221 }; 222 223 static const u8 ov361x_start_1024[][2] = { 224 {0x12, 0x80}, 225 {0x13, 0xcf}, 226 {0x14, 0x40}, 227 {0x15, 0x00}, 228 {0x01, 0x80}, 229 {0x02, 0x80}, 230 {0x04, 0x70}, 231 {0x0d, 0x40}, 232 {0x0f, 0x47}, 233 {0x11, 0x81}, 234 {0x32, 0x36}, 235 {0x33, 0x0C}, 236 {0x34, 0x00}, 237 {0x35, 0x90}, 238 {0x12, 0x40}, 239 {0x17, 0x1f}, 240 {0x18, 0x5f}, 241 {0x19, 0x00}, 242 {0x1a, 0x68}, 243 }; 244 static const u8 ov361x_bridge_start_1024[][2] = { 245 {0xf1, 0x60}, /* Hsize[7:0] */ 246 {0x88, 0x00}, /* Hsize[15:8] Write Only, can't read */ 247 {0x89, 0x04}, /* Vsize[7:0] */ 248 {0x8a, 0x00}, /* Vsize[15:8] Write Only, can't read */ 249 {0x8b, 0x03}, /* for Iso */ 250 {0x8c, 0x01}, /* RAW input */ 251 {0x8d, 0x10}, 252 {0x1c, 0x00}, /* RAW output, Iso transfer */ 253 {0x1d, 0x48}, 254 {0x1d, 0x00}, 255 {0x1d, 0xff}, 256 {0x1c, 0x0a}, /* turn off JPEG, Iso mode */ 257 {0x1d, 0x2e}, /* for Iso */ 258 {0x1d, 0x1e}, 259 }; 260 261 static const u8 ov361x_start_640[][2] = { 262 {0x12, 0x80}, 263 {0x13, 0xcf}, 264 {0x14, 0x40}, 265 {0x15, 0x00}, 266 {0x01, 0x80}, 267 {0x02, 0x80}, 268 {0x04, 0x70}, 269 {0x0d, 0x40}, 270 {0x0f, 0x47}, 271 {0x11, 0x81}, 272 {0x32, 0x36}, 273 {0x33, 0x0C}, 274 {0x34, 0x00}, 275 {0x35, 0x90}, 276 {0x12, 0x40}, 277 {0x17, 0x1f}, 278 {0x18, 0x5f}, 279 {0x19, 0x00}, 280 {0x1a, 0x68}, 281 }; 282 283 static const u8 ov361x_bridge_start_640[][2] = { 284 {0xf1, 0x60}, /* Hsize[7:0]*/ 285 {0x88, 0x00}, /* Hsize[15:8] Write Only, can't read */ 286 {0x89, 0x04}, /* Vsize[7:0] */ 287 {0x8a, 0x00}, /* Vsize[15:8] Write Only, can't read */ 288 {0x8b, 0x03}, /* for Iso */ 289 {0x8c, 0x01}, /* RAW input */ 290 {0x8d, 0x10}, 291 {0x1c, 0x00}, /* RAW output, Iso transfer */ 292 {0x1d, 0x48}, 293 {0x1d, 0x00}, 294 {0x1d, 0xff}, 295 {0x1c, 0x0a}, /* turn off JPEG, Iso mode */ 296 {0x1d, 0x2e}, /* for Iso */ 297 {0x1d, 0x1e}, 298 }; 299 300 static const u8 ov361x_start_320[][2] = { 301 {0x12, 0x80}, 302 {0x13, 0xcf}, 303 {0x14, 0x40}, 304 {0x15, 0x00}, 305 {0x01, 0x80}, 306 {0x02, 0x80}, 307 {0x04, 0x70}, 308 {0x0d, 0x40}, 309 {0x0f, 0x47}, 310 {0x11, 0x81}, 311 {0x32, 0x36}, 312 {0x33, 0x0C}, 313 {0x34, 0x00}, 314 {0x35, 0x90}, 315 {0x12, 0x40}, 316 {0x17, 0x1f}, 317 {0x18, 0x5f}, 318 {0x19, 0x00}, 319 {0x1a, 0x68}, 320 }; 321 322 static const u8 ov361x_bridge_start_320[][2] = { 323 {0xf1, 0x60}, /* Hsize[7:0] */ 324 {0x88, 0x00}, /* Hsize[15:8] Write Only, can't read */ 325 {0x89, 0x04}, /* Vsize[7:0] */ 326 {0x8a, 0x00}, /* Vsize[15:8] Write Only, can't read */ 327 {0x8b, 0x03}, /* for Iso */ 328 {0x8c, 0x01}, /* RAW input */ 329 {0x8d, 0x10}, 330 {0x1c, 0x00}, /* RAW output, Iso transfer; */ 331 {0x1d, 0x48}, 332 {0x1d, 0x00}, 333 {0x1d, 0xff}, 334 {0x1c, 0x0a}, /* turn off JPEG, Iso mode */ 335 {0x1d, 0x2e}, /* for Iso */ 336 {0x1d, 0x1e}, 337 }; 338 339 static const u8 ov361x_start_160[][2] = { 340 {0x12, 0x80}, 341 {0x13, 0xcf}, 342 {0x14, 0x40}, 343 {0x15, 0x00}, 344 {0x01, 0x80}, 345 {0x02, 0x80}, 346 {0x04, 0x70}, 347 {0x0d, 0x40}, 348 {0x0f, 0x47}, 349 {0x11, 0x81}, 350 {0x32, 0x36}, 351 {0x33, 0x0C}, 352 {0x34, 0x00}, 353 {0x35, 0x90}, 354 {0x12, 0x40}, 355 {0x17, 0x1f}, 356 {0x18, 0x5f}, 357 {0x19, 0x00}, 358 {0x1a, 0x68}, 359 }; 360 361 static const u8 ov361x_bridge_start_160[][2] = { 362 {0xf1, 0x60}, /* Hsize[7:0] */ 363 {0x88, 0x00}, /* Hsize[15:8] Write Only, can't read */ 364 {0x89, 0x04}, /* Vsize[7:0] */ 365 {0x8a, 0x00}, /* Vsize[15:8] Write Only, can't read */ 366 {0x8b, 0x03}, /* for Iso */ 367 {0x8c, 0x01}, /* RAW input */ 368 {0x8d, 0x10}, 369 {0x1c, 0x00}, /* RAW output, Iso transfer */ 370 {0x1d, 0x48}, 371 {0x1d, 0x00}, 372 {0x1d, 0xff}, 373 {0x1c, 0x0a}, /* turn off JPEG, Iso mode */ 374 {0x1d, 0x2e}, /* for Iso */ 375 {0x1d, 0x1e}, 376 }; 377 378 static const u8 bridge_init[][2] = { 379 {0x88, 0xf8}, 380 {0x89, 0xff}, 381 {0x76, 0x03}, 382 {0x92, 0x03}, 383 {0x95, 0x10}, 384 {0xe2, 0x00}, 385 {0xe7, 0x3e}, 386 {0x8d, 0x1c}, 387 {0x8e, 0x00}, 388 {0x8f, 0x00}, 389 {0x1f, 0x00}, 390 {0xc3, 0xf9}, 391 {0x89, 0xff}, 392 {0x88, 0xf8}, 393 {0x76, 0x03}, 394 {0x92, 0x01}, 395 {0x93, 0x18}, 396 {0x1c, 0x0a}, 397 {0x1d, 0x48}, 398 {0xc0, 0x50}, 399 {0xc1, 0x3c}, 400 {0x34, 0x05}, 401 {0xc2, 0x0c}, 402 {0xc3, 0xf9}, 403 {0x34, 0x05}, 404 {0xe7, 0x2e}, 405 {0x31, 0xf9}, 406 {0x35, 0x02}, 407 {0xd9, 0x10}, 408 {0x25, 0x42}, 409 {0x94, 0x11}, 410 }; 411 412 static const u8 ov965x_init[][2] = { 413 {0x12, 0x80}, /* com7 - SSCB reset */ 414 {0x00, 0x00}, /* gain */ 415 {0x01, 0x80}, /* blue */ 416 {0x02, 0x80}, /* red */ 417 {0x03, 0x1b}, /* vref */ 418 {0x04, 0x03}, /* com1 - exposure low bits */ 419 {0x0b, 0x57}, /* ver */ 420 {0x0e, 0x61}, /* com5 */ 421 {0x0f, 0x42}, /* com6 */ 422 {0x11, 0x00}, /* clkrc */ 423 {0x12, 0x02}, /* com7 - 15fps VGA YUYV */ 424 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ 425 {0x14, 0x28}, /* com9 */ 426 {0x16, 0x24}, /* reg16 */ 427 {0x17, 0x1d}, /* hstart*/ 428 {0x18, 0xbd}, /* hstop */ 429 {0x19, 0x01}, /* vstrt */ 430 {0x1a, 0x81}, /* vstop*/ 431 {0x1e, 0x04}, /* mvfp */ 432 {0x24, 0x3c}, /* aew */ 433 {0x25, 0x36}, /* aeb */ 434 {0x26, 0x71}, /* vpt */ 435 {0x27, 0x08}, /* bbias */ 436 {0x28, 0x08}, /* gbbias */ 437 {0x29, 0x15}, /* gr com */ 438 {0x2a, 0x00}, /* exhch */ 439 {0x2b, 0x00}, /* exhcl */ 440 {0x2c, 0x08}, /* rbias */ 441 {0x32, 0xff}, /* href */ 442 {0x33, 0x00}, /* chlf */ 443 {0x34, 0x3f}, /* aref1 */ 444 {0x35, 0x00}, /* aref2 */ 445 {0x36, 0xf8}, /* aref3 */ 446 {0x38, 0x72}, /* adc2 */ 447 {0x39, 0x57}, /* aref4 */ 448 {0x3a, 0x80}, /* tslb - yuyv */ 449 {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */ 450 {0x3d, 0x99}, /* com13 */ 451 {0x3f, 0xc1}, /* edge */ 452 {0x40, 0xc0}, /* com15 */ 453 {0x41, 0x40}, /* com16 */ 454 {0x42, 0xc0}, /* com17 */ 455 {0x43, 0x0a}, /* rsvd */ 456 {0x44, 0xf0}, 457 {0x45, 0x46}, 458 {0x46, 0x62}, 459 {0x47, 0x2a}, 460 {0x48, 0x3c}, 461 {0x4a, 0xfc}, 462 {0x4b, 0xfc}, 463 {0x4c, 0x7f}, 464 {0x4d, 0x7f}, 465 {0x4e, 0x7f}, 466 {0x4f, 0x98}, /* matrix */ 467 {0x50, 0x98}, 468 {0x51, 0x00}, 469 {0x52, 0x28}, 470 {0x53, 0x70}, 471 {0x54, 0x98}, 472 {0x58, 0x1a}, /* matrix coef sign */ 473 {0x59, 0x85}, /* AWB control */ 474 {0x5a, 0xa9}, 475 {0x5b, 0x64}, 476 {0x5c, 0x84}, 477 {0x5d, 0x53}, 478 {0x5e, 0x0e}, 479 {0x5f, 0xf0}, /* AWB blue limit */ 480 {0x60, 0xf0}, /* AWB red limit */ 481 {0x61, 0xf0}, /* AWB green limit */ 482 {0x62, 0x00}, /* lcc1 */ 483 {0x63, 0x00}, /* lcc2 */ 484 {0x64, 0x02}, /* lcc3 */ 485 {0x65, 0x16}, /* lcc4 */ 486 {0x66, 0x01}, /* lcc5 */ 487 {0x69, 0x02}, /* hv */ 488 {0x6b, 0x5a}, /* dbvl */ 489 {0x6c, 0x04}, 490 {0x6d, 0x55}, 491 {0x6e, 0x00}, 492 {0x6f, 0x9d}, 493 {0x70, 0x21}, /* dnsth */ 494 {0x71, 0x78}, 495 {0x72, 0x00}, /* poidx */ 496 {0x73, 0x01}, /* pckdv */ 497 {0x74, 0x3a}, /* xindx */ 498 {0x75, 0x35}, /* yindx */ 499 {0x76, 0x01}, 500 {0x77, 0x02}, 501 {0x7a, 0x12}, /* gamma curve */ 502 {0x7b, 0x08}, 503 {0x7c, 0x16}, 504 {0x7d, 0x30}, 505 {0x7e, 0x5e}, 506 {0x7f, 0x72}, 507 {0x80, 0x82}, 508 {0x81, 0x8e}, 509 {0x82, 0x9a}, 510 {0x83, 0xa4}, 511 {0x84, 0xac}, 512 {0x85, 0xb8}, 513 {0x86, 0xc3}, 514 {0x87, 0xd6}, 515 {0x88, 0xe6}, 516 {0x89, 0xf2}, 517 {0x8a, 0x03}, 518 {0x8c, 0x89}, /* com19 */ 519 {0x14, 0x28}, /* com9 */ 520 {0x90, 0x7d}, 521 {0x91, 0x7b}, 522 {0x9d, 0x03}, /* lcc6 */ 523 {0x9e, 0x04}, /* lcc7 */ 524 {0x9f, 0x7a}, 525 {0xa0, 0x79}, 526 {0xa1, 0x40}, /* aechm */ 527 {0xa4, 0x50}, /* com21 */ 528 {0xa5, 0x68}, /* com26 */ 529 {0xa6, 0x4a}, /* AWB green */ 530 {0xa8, 0xc1}, /* refa8 */ 531 {0xa9, 0xef}, /* refa9 */ 532 {0xaa, 0x92}, 533 {0xab, 0x04}, 534 {0xac, 0x80}, /* black level control */ 535 {0xad, 0x80}, 536 {0xae, 0x80}, 537 {0xaf, 0x80}, 538 {0xb2, 0xf2}, 539 {0xb3, 0x20}, 540 {0xb4, 0x20}, /* ctrlb4 */ 541 {0xb5, 0x00}, 542 {0xb6, 0xaf}, 543 {0xbb, 0xae}, 544 {0xbc, 0x7f}, /* ADC channel offsets */ 545 {0xdb, 0x7f}, 546 {0xbe, 0x7f}, 547 {0xbf, 0x7f}, 548 {0xc0, 0xe2}, 549 {0xc1, 0xc0}, 550 {0xc2, 0x01}, 551 {0xc3, 0x4e}, 552 {0xc6, 0x85}, 553 {0xc7, 0x80}, /* com24 */ 554 {0xc9, 0xe0}, 555 {0xca, 0xe8}, 556 {0xcb, 0xf0}, 557 {0xcc, 0xd8}, 558 {0xcd, 0xf1}, 559 {0x4f, 0x98}, /* matrix */ 560 {0x50, 0x98}, 561 {0x51, 0x00}, 562 {0x52, 0x28}, 563 {0x53, 0x70}, 564 {0x54, 0x98}, 565 {0x58, 0x1a}, 566 {0xff, 0x41}, /* read 41, write ff 00 */ 567 {0x41, 0x40}, /* com16 */ 568 569 {0xc5, 0x03}, /* 60 Hz banding filter */ 570 {0x6a, 0x02}, /* 50 Hz banding filter */ 571 572 {0x12, 0x62}, /* com7 - 30fps VGA YUV */ 573 {0x36, 0xfa}, /* aref3 */ 574 {0x69, 0x0a}, /* hv */ 575 {0x8c, 0x89}, /* com22 */ 576 {0x14, 0x28}, /* com9 */ 577 {0x3e, 0x0c}, 578 {0x41, 0x40}, /* com16 */ 579 {0x72, 0x00}, 580 {0x73, 0x00}, 581 {0x74, 0x3a}, 582 {0x75, 0x35}, 583 {0x76, 0x01}, 584 {0xc7, 0x80}, 585 {0x03, 0x12}, /* vref */ 586 {0x17, 0x16}, /* hstart */ 587 {0x18, 0x02}, /* hstop */ 588 {0x19, 0x01}, /* vstrt */ 589 {0x1a, 0x3d}, /* vstop */ 590 {0x32, 0xff}, /* href */ 591 {0xc0, 0xaa}, 592 }; 593 594 static const u8 bridge_init_2[][2] = { 595 {0x94, 0xaa}, 596 {0xf1, 0x60}, 597 {0xe5, 0x04}, 598 {0xc0, 0x50}, 599 {0xc1, 0x3c}, 600 {0x8c, 0x00}, 601 {0x8d, 0x1c}, 602 {0x34, 0x05}, 603 604 {0xc2, 0x0c}, 605 {0xc3, 0xf9}, 606 {0xda, 0x01}, 607 {0x50, 0x00}, 608 {0x51, 0xa0}, 609 {0x52, 0x3c}, 610 {0x53, 0x00}, 611 {0x54, 0x00}, 612 {0x55, 0x00}, 613 {0x57, 0x00}, 614 {0x5c, 0x00}, 615 {0x5a, 0xa0}, 616 {0x5b, 0x78}, 617 {0x35, 0x02}, 618 {0xd9, 0x10}, 619 {0x94, 0x11}, 620 }; 621 622 static const u8 ov965x_init_2[][2] = { 623 {0x3b, 0xc4}, 624 {0x1e, 0x04}, /* mvfp */ 625 {0x13, 0xe0}, /* com8 */ 626 {0x00, 0x00}, /* gain */ 627 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ 628 {0x11, 0x03}, /* clkrc */ 629 {0x6b, 0x5a}, /* dblv */ 630 {0x6a, 0x05}, 631 {0xc5, 0x07}, 632 {0xa2, 0x4b}, 633 {0xa3, 0x3e}, 634 {0x2d, 0x00}, 635 {0xff, 0x42}, /* read 42, write ff 00 */ 636 {0x42, 0xc0}, /* com17 */ 637 {0x2d, 0x00}, 638 {0xff, 0x42}, /* read 42, write ff 00 */ 639 {0x42, 0xc1}, /* com17 */ 640 /* sharpness */ 641 {0x3f, 0x01}, 642 {0xff, 0x42}, /* read 42, write ff 00 */ 643 {0x42, 0xc1}, /* com17 */ 644 /* saturation */ 645 {0x4f, 0x98}, /* matrix */ 646 {0x50, 0x98}, 647 {0x51, 0x00}, 648 {0x52, 0x28}, 649 {0x53, 0x70}, 650 {0x54, 0x98}, 651 {0x58, 0x1a}, 652 {0xff, 0x41}, /* read 41, write ff 00 */ 653 {0x41, 0x40}, /* com16 */ 654 /* contrast */ 655 {0x56, 0x40}, 656 /* brightness */ 657 {0x55, 0x8f}, 658 /* expo */ 659 {0x10, 0x25}, /* aech - exposure high bits */ 660 {0xff, 0x13}, /* read 13, write ff 00 */ 661 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ 662 }; 663 664 static const u8 ov971x_init[][2] = { 665 {0x12, 0x80}, 666 {0x09, 0x10}, 667 {0x1e, 0x07}, 668 {0x5f, 0x18}, 669 {0x69, 0x04}, 670 {0x65, 0x2a}, 671 {0x68, 0x0a}, 672 {0x39, 0x28}, 673 {0x4d, 0x90}, 674 {0xc1, 0x80}, 675 {0x0c, 0x30}, 676 {0x6d, 0x02}, 677 {0x96, 0xf1}, 678 {0xbc, 0x68}, 679 {0x12, 0x00}, 680 {0x3b, 0x00}, 681 {0x97, 0x80}, 682 {0x17, 0x25}, 683 {0x18, 0xa2}, 684 {0x19, 0x01}, 685 {0x1a, 0xca}, 686 {0x03, 0x0a}, 687 {0x32, 0x07}, 688 {0x98, 0x40}, /*{0x98, 0x00},*/ 689 {0x99, 0xA0}, /*{0x99, 0x00},*/ 690 {0x9a, 0x01}, /*{0x9a, 0x00},*/ 691 {0x57, 0x00}, 692 {0x58, 0x78}, /*{0x58, 0xc8},*/ 693 {0x59, 0x50}, /*{0x59, 0xa0},*/ 694 {0x4c, 0x13}, 695 {0x4b, 0x36}, 696 {0x3d, 0x3c}, 697 {0x3e, 0x03}, 698 {0xbd, 0x50}, /*{0xbd, 0xa0},*/ 699 {0xbe, 0x78}, /*{0xbe, 0xc8},*/ 700 {0x4e, 0x55}, 701 {0x4f, 0x55}, 702 {0x50, 0x55}, 703 {0x51, 0x55}, 704 {0x24, 0x55}, 705 {0x25, 0x40}, 706 {0x26, 0xa1}, 707 {0x5c, 0x59}, 708 {0x5d, 0x00}, 709 {0x11, 0x00}, 710 {0x2a, 0x98}, 711 {0x2b, 0x06}, 712 {0x2d, 0x00}, 713 {0x2e, 0x00}, 714 {0x13, 0xa5}, 715 {0x14, 0x40}, 716 {0x4a, 0x00}, 717 {0x49, 0xce}, 718 {0x22, 0x03}, 719 {0x09, 0x00} 720 }; 721 722 static const u8 ov965x_start_1_vga[][2] = { /* same for qvga */ 723 {0x12, 0x62}, /* com7 - 30fps VGA YUV */ 724 {0x36, 0xfa}, /* aref3 */ 725 {0x69, 0x0a}, /* hv */ 726 {0x8c, 0x89}, /* com22 */ 727 {0x14, 0x28}, /* com9 */ 728 {0x3e, 0x0c}, /* com14 */ 729 {0x41, 0x40}, /* com16 */ 730 {0x72, 0x00}, 731 {0x73, 0x00}, 732 {0x74, 0x3a}, 733 {0x75, 0x35}, 734 {0x76, 0x01}, 735 {0xc7, 0x80}, /* com24 */ 736 {0x03, 0x12}, /* vref */ 737 {0x17, 0x16}, /* hstart */ 738 {0x18, 0x02}, /* hstop */ 739 {0x19, 0x01}, /* vstrt */ 740 {0x1a, 0x3d}, /* vstop */ 741 {0x32, 0xff}, /* href */ 742 {0xc0, 0xaa}, 743 }; 744 745 static const u8 ov965x_start_1_svga[][2] = { 746 {0x12, 0x02}, /* com7 - YUYV - VGA 15 full resolution */ 747 {0x36, 0xf8}, /* aref3 */ 748 {0x69, 0x02}, /* hv */ 749 {0x8c, 0x0d}, /* com22 */ 750 {0x3e, 0x0c}, /* com14 */ 751 {0x41, 0x40}, /* com16 */ 752 {0x72, 0x00}, 753 {0x73, 0x01}, 754 {0x74, 0x3a}, 755 {0x75, 0x35}, 756 {0x76, 0x01}, 757 {0xc7, 0x80}, /* com24 */ 758 {0x03, 0x1b}, /* vref */ 759 {0x17, 0x1d}, /* hstart */ 760 {0x18, 0xbd}, /* hstop */ 761 {0x19, 0x01}, /* vstrt */ 762 {0x1a, 0x81}, /* vstop */ 763 {0x32, 0xff}, /* href */ 764 {0xc0, 0xe2}, 765 }; 766 767 static const u8 ov965x_start_1_xga[][2] = { 768 {0x12, 0x02}, /* com7 */ 769 {0x36, 0xf8}, /* aref3 */ 770 {0x69, 0x02}, /* hv */ 771 {0x8c, 0x89}, /* com22 */ 772 {0x14, 0x28}, /* com9 */ 773 {0x3e, 0x0c}, /* com14 */ 774 {0x41, 0x40}, /* com16 */ 775 {0x72, 0x00}, 776 {0x73, 0x01}, 777 {0x74, 0x3a}, 778 {0x75, 0x35}, 779 {0x76, 0x01}, 780 {0xc7, 0x80}, /* com24 */ 781 {0x03, 0x1b}, /* vref */ 782 {0x17, 0x1d}, /* hstart */ 783 {0x18, 0xbd}, /* hstop */ 784 {0x19, 0x01}, /* vstrt */ 785 {0x1a, 0x81}, /* vstop */ 786 {0x32, 0xff}, /* href */ 787 {0xc0, 0xe2}, 788 }; 789 790 static const u8 ov965x_start_1_sxga[][2] = { 791 {0x12, 0x02}, /* com7 */ 792 {0x36, 0xf8}, /* aref3 */ 793 {0x69, 0x02}, /* hv */ 794 {0x8c, 0x89}, /* com22 */ 795 {0x14, 0x28}, /* com9 */ 796 {0x3e, 0x0c}, /* com14 */ 797 {0x41, 0x40}, /* com16 */ 798 {0x72, 0x00}, 799 {0x73, 0x01}, 800 {0x74, 0x3a}, 801 {0x75, 0x35}, 802 {0x76, 0x01}, 803 {0xc7, 0x80}, /* com24 */ 804 {0x03, 0x1b}, /* vref */ 805 {0x17, 0x1d}, /* hstart */ 806 {0x18, 0x02}, /* hstop */ 807 {0x19, 0x01}, /* vstrt */ 808 {0x1a, 0x81}, /* vstop */ 809 {0x32, 0xff}, /* href */ 810 {0xc0, 0xe2}, 811 }; 812 813 static const u8 bridge_start_qvga[][2] = { 814 {0x94, 0xaa}, 815 {0xf1, 0x60}, 816 {0xe5, 0x04}, 817 {0xc0, 0x50}, 818 {0xc1, 0x3c}, 819 {0x8c, 0x00}, 820 {0x8d, 0x1c}, 821 {0x34, 0x05}, 822 823 {0xc2, 0x4c}, 824 {0xc3, 0xf9}, 825 {0xda, 0x00}, 826 {0x50, 0x00}, 827 {0x51, 0xa0}, 828 {0x52, 0x78}, 829 {0x53, 0x00}, 830 {0x54, 0x00}, 831 {0x55, 0x00}, 832 {0x57, 0x00}, 833 {0x5c, 0x00}, 834 {0x5a, 0x50}, 835 {0x5b, 0x3c}, 836 {0x35, 0x02}, 837 {0xd9, 0x10}, 838 {0x94, 0x11}, 839 }; 840 841 static const u8 bridge_start_vga[][2] = { 842 {0x94, 0xaa}, 843 {0xf1, 0x60}, 844 {0xe5, 0x04}, 845 {0xc0, 0x50}, 846 {0xc1, 0x3c}, 847 {0x8c, 0x00}, 848 {0x8d, 0x1c}, 849 {0x34, 0x05}, 850 {0xc2, 0x0c}, 851 {0xc3, 0xf9}, 852 {0xda, 0x01}, 853 {0x50, 0x00}, 854 {0x51, 0xa0}, 855 {0x52, 0x3c}, 856 {0x53, 0x00}, 857 {0x54, 0x00}, 858 {0x55, 0x00}, 859 {0x57, 0x00}, 860 {0x5c, 0x00}, 861 {0x5a, 0xa0}, 862 {0x5b, 0x78}, 863 {0x35, 0x02}, 864 {0xd9, 0x10}, 865 {0x94, 0x11}, 866 }; 867 868 static const u8 bridge_start_svga[][2] = { 869 {0x94, 0xaa}, 870 {0xf1, 0x60}, 871 {0xe5, 0x04}, 872 {0xc0, 0xa0}, 873 {0xc1, 0x80}, 874 {0x8c, 0x00}, 875 {0x8d, 0x1c}, 876 {0x34, 0x05}, 877 {0xc2, 0x4c}, 878 {0xc3, 0xf9}, 879 {0x50, 0x00}, 880 {0x51, 0x40}, 881 {0x52, 0x00}, 882 {0x53, 0x00}, 883 {0x54, 0x00}, 884 {0x55, 0x88}, 885 {0x57, 0x00}, 886 {0x5c, 0x00}, 887 {0x5a, 0xc8}, 888 {0x5b, 0x96}, 889 {0x35, 0x02}, 890 {0xd9, 0x10}, 891 {0xda, 0x00}, 892 {0x94, 0x11}, 893 }; 894 895 static const u8 bridge_start_xga[][2] = { 896 {0x94, 0xaa}, 897 {0xf1, 0x60}, 898 {0xe5, 0x04}, 899 {0xc0, 0xa0}, 900 {0xc1, 0x80}, 901 {0x8c, 0x00}, 902 {0x8d, 0x1c}, 903 {0x34, 0x05}, 904 {0xc2, 0x4c}, 905 {0xc3, 0xf9}, 906 {0x50, 0x00}, 907 {0x51, 0x40}, 908 {0x52, 0x00}, 909 {0x53, 0x00}, 910 {0x54, 0x00}, 911 {0x55, 0x88}, 912 {0x57, 0x00}, 913 {0x5c, 0x01}, 914 {0x5a, 0x00}, 915 {0x5b, 0xc0}, 916 {0x35, 0x02}, 917 {0xd9, 0x10}, 918 {0xda, 0x01}, 919 {0x94, 0x11}, 920 }; 921 922 static const u8 bridge_start_sxga[][2] = { 923 {0x94, 0xaa}, 924 {0xf1, 0x60}, 925 {0xe5, 0x04}, 926 {0xc0, 0xa0}, 927 {0xc1, 0x80}, 928 {0x8c, 0x00}, 929 {0x8d, 0x1c}, 930 {0x34, 0x05}, 931 {0xc2, 0x0c}, 932 {0xc3, 0xf9}, 933 {0xda, 0x00}, 934 {0x35, 0x02}, 935 {0xd9, 0x10}, 936 {0x94, 0x11}, 937 }; 938 939 static const u8 ov965x_start_2_qvga[][2] = { 940 {0x3b, 0xe4}, /* com11 - night mode 1/4 frame rate */ 941 {0x1e, 0x04}, /* mvfp */ 942 {0x13, 0xe0}, /* com8 */ 943 {0x00, 0x00}, 944 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ 945 {0x11, 0x01}, /* clkrc */ 946 {0x6b, 0x5a}, /* dblv */ 947 {0x6a, 0x02}, /* 50 Hz banding filter */ 948 {0xc5, 0x03}, /* 60 Hz banding filter */ 949 {0xa2, 0x96}, /* bd50 */ 950 {0xa3, 0x7d}, /* bd60 */ 951 952 {0xff, 0x13}, /* read 13, write ff 00 */ 953 {0x13, 0xe7}, 954 {0x3a, 0x80}, /* tslb - yuyv */ 955 }; 956 957 static const u8 ov965x_start_2_vga[][2] = { 958 {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */ 959 {0x1e, 0x04}, /* mvfp */ 960 {0x13, 0xe0}, /* com8 */ 961 {0x00, 0x00}, 962 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ 963 {0x11, 0x03}, /* clkrc */ 964 {0x6b, 0x5a}, /* dblv */ 965 {0x6a, 0x05}, /* 50 Hz banding filter */ 966 {0xc5, 0x07}, /* 60 Hz banding filter */ 967 {0xa2, 0x4b}, /* bd50 */ 968 {0xa3, 0x3e}, /* bd60 */ 969 970 {0x2d, 0x00}, /* advfl */ 971 }; 972 973 static const u8 ov965x_start_2_svga[][2] = { /* same for xga */ 974 {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */ 975 {0x1e, 0x04}, /* mvfp */ 976 {0x13, 0xe0}, /* com8 */ 977 {0x00, 0x00}, 978 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ 979 {0x11, 0x01}, /* clkrc */ 980 {0x6b, 0x5a}, /* dblv */ 981 {0x6a, 0x0c}, /* 50 Hz banding filter */ 982 {0xc5, 0x0f}, /* 60 Hz banding filter */ 983 {0xa2, 0x4e}, /* bd50 */ 984 {0xa3, 0x41}, /* bd60 */ 985 }; 986 987 static const u8 ov965x_start_2_sxga[][2] = { 988 {0x13, 0xe0}, /* com8 */ 989 {0x00, 0x00}, 990 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ 991 {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */ 992 {0x1e, 0x04}, /* mvfp */ 993 {0x11, 0x01}, /* clkrc */ 994 {0x6b, 0x5a}, /* dblv */ 995 {0x6a, 0x0c}, /* 50 Hz banding filter */ 996 {0xc5, 0x0f}, /* 60 Hz banding filter */ 997 {0xa2, 0x4e}, /* bd50 */ 998 {0xa3, 0x41}, /* bd60 */ 999 }; 1000 1001 static const u8 ov562x_init[][2] = { 1002 {0x88, 0x20}, 1003 {0x89, 0x0a}, 1004 {0x8a, 0x90}, 1005 {0x8b, 0x06}, 1006 {0x8c, 0x01}, 1007 {0x8d, 0x10}, 1008 {0x1c, 0x00}, 1009 {0x1d, 0x48}, 1010 {0x1d, 0x00}, 1011 {0x1d, 0xff}, 1012 {0x1c, 0x0a}, 1013 {0x1d, 0x2e}, 1014 {0x1d, 0x1e}, 1015 }; 1016 1017 static const u8 ov562x_init_2[][2] = { 1018 {0x12, 0x80}, 1019 {0x11, 0x41}, 1020 {0x13, 0x00}, 1021 {0x10, 0x1e}, 1022 {0x3b, 0x07}, 1023 {0x5b, 0x40}, 1024 {0x39, 0x07}, 1025 {0x53, 0x02}, 1026 {0x54, 0x60}, 1027 {0x04, 0x20}, 1028 {0x27, 0x04}, 1029 {0x3d, 0x40}, 1030 {0x36, 0x00}, 1031 {0xc5, 0x04}, 1032 {0x4e, 0x00}, 1033 {0x4f, 0x93}, 1034 {0x50, 0x7b}, 1035 {0xca, 0x0c}, 1036 {0xcb, 0x0f}, 1037 {0x39, 0x07}, 1038 {0x4a, 0x10}, 1039 {0x3e, 0x0a}, 1040 {0x3d, 0x00}, 1041 {0x0c, 0x38}, 1042 {0x38, 0x90}, 1043 {0x46, 0x30}, 1044 {0x4f, 0x93}, 1045 {0x50, 0x7b}, 1046 {0xab, 0x00}, 1047 {0xca, 0x0c}, 1048 {0xcb, 0x0f}, 1049 {0x37, 0x02}, 1050 {0x44, 0x48}, 1051 {0x8d, 0x44}, 1052 {0x2a, 0x00}, 1053 {0x2b, 0x00}, 1054 {0x32, 0x00}, 1055 {0x38, 0x90}, 1056 {0x53, 0x02}, 1057 {0x54, 0x60}, 1058 {0x12, 0x00}, 1059 {0x17, 0x12}, 1060 {0x18, 0xb4}, 1061 {0x19, 0x0c}, 1062 {0x1a, 0xf4}, 1063 {0x03, 0x4a}, 1064 {0x89, 0x20}, 1065 {0x83, 0x80}, 1066 {0xb7, 0x9d}, 1067 {0xb6, 0x11}, 1068 {0xb5, 0x55}, 1069 {0xb4, 0x00}, 1070 {0xa9, 0xf0}, 1071 {0xa8, 0x0a}, 1072 {0xb8, 0xf0}, 1073 {0xb9, 0xf0}, 1074 {0xba, 0xf0}, 1075 {0x81, 0x07}, 1076 {0x63, 0x44}, 1077 {0x13, 0xc7}, 1078 {0x14, 0x60}, 1079 {0x33, 0x75}, 1080 {0x2c, 0x00}, 1081 {0x09, 0x00}, 1082 {0x35, 0x30}, 1083 {0x27, 0x04}, 1084 {0x3c, 0x07}, 1085 {0x3a, 0x0a}, 1086 {0x3b, 0x07}, 1087 {0x01, 0x40}, 1088 {0x02, 0x40}, 1089 {0x16, 0x40}, 1090 {0x52, 0xb0}, 1091 {0x51, 0x83}, 1092 {0x21, 0xbb}, 1093 {0x22, 0x10}, 1094 {0x23, 0x03}, 1095 {0x35, 0x38}, 1096 {0x20, 0x90}, 1097 {0x28, 0x30}, 1098 {0x73, 0xe1}, 1099 {0x6c, 0x00}, 1100 {0x6d, 0x80}, 1101 {0x6e, 0x00}, 1102 {0x70, 0x04}, 1103 {0x71, 0x00}, 1104 {0x8d, 0x04}, 1105 {0x64, 0x00}, 1106 {0x65, 0x00}, 1107 {0x66, 0x00}, 1108 {0x67, 0x00}, 1109 {0x68, 0x00}, 1110 {0x69, 0x00}, 1111 {0x6a, 0x00}, 1112 {0x6b, 0x00}, 1113 {0x71, 0x94}, 1114 {0x74, 0x20}, 1115 {0x80, 0x09}, 1116 {0x85, 0xc0}, 1117 }; 1118 1119 static void reg_w_i(struct gspca_dev *gspca_dev, u16 reg, u8 val) 1120 { 1121 struct usb_device *udev = gspca_dev->dev; 1122 int ret; 1123 1124 if (gspca_dev->usb_err < 0) 1125 return; 1126 gspca_dev->usb_buf[0] = val; 1127 ret = usb_control_msg(udev, 1128 usb_sndctrlpipe(udev, 0), 1129 0x01, 1130 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 1131 0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT); 1132 if (ret < 0) { 1133 pr_err("reg_w failed %d\n", ret); 1134 gspca_dev->usb_err = ret; 1135 } 1136 } 1137 1138 static void reg_w(struct gspca_dev *gspca_dev, u16 reg, u8 val) 1139 { 1140 PDEBUG(D_USBO, "reg_w [%04x] = %02x", reg, val); 1141 reg_w_i(gspca_dev, reg, val); 1142 } 1143 1144 static u8 reg_r(struct gspca_dev *gspca_dev, u16 reg) 1145 { 1146 struct usb_device *udev = gspca_dev->dev; 1147 int ret; 1148 1149 if (gspca_dev->usb_err < 0) 1150 return 0; 1151 ret = usb_control_msg(udev, 1152 usb_rcvctrlpipe(udev, 0), 1153 0x01, 1154 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 1155 0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT); 1156 PDEBUG(D_USBI, "reg_r [%04x] -> %02x", reg, gspca_dev->usb_buf[0]); 1157 if (ret < 0) { 1158 pr_err("reg_r err %d\n", ret); 1159 gspca_dev->usb_err = ret; 1160 } 1161 return gspca_dev->usb_buf[0]; 1162 } 1163 1164 static int sccb_check_status(struct gspca_dev *gspca_dev) 1165 { 1166 u8 data; 1167 int i; 1168 1169 for (i = 0; i < 5; i++) { 1170 msleep(20); 1171 data = reg_r(gspca_dev, OV534_REG_STATUS); 1172 1173 switch (data) { 1174 case 0x00: 1175 return 1; 1176 case 0x04: 1177 return 0; 1178 case 0x03: 1179 break; 1180 default: 1181 PDEBUG(D_USBI|D_USBO, 1182 "sccb status 0x%02x, attempt %d/5", 1183 data, i + 1); 1184 } 1185 } 1186 return 0; 1187 } 1188 1189 static void sccb_write(struct gspca_dev *gspca_dev, u8 reg, u8 val) 1190 { 1191 PDEBUG(D_USBO, "sccb_write [%02x] = %02x", reg, val); 1192 reg_w_i(gspca_dev, OV534_REG_SUBADDR, reg); 1193 reg_w_i(gspca_dev, OV534_REG_WRITE, val); 1194 reg_w_i(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_3); 1195 1196 if (!sccb_check_status(gspca_dev)) 1197 pr_err("sccb_write failed\n"); 1198 } 1199 1200 static u8 sccb_read(struct gspca_dev *gspca_dev, u16 reg) 1201 { 1202 reg_w(gspca_dev, OV534_REG_SUBADDR, reg); 1203 reg_w(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_2); 1204 if (!sccb_check_status(gspca_dev)) 1205 pr_err("sccb_read failed 1\n"); 1206 1207 reg_w(gspca_dev, OV534_REG_OPERATION, OV534_OP_READ_2); 1208 if (!sccb_check_status(gspca_dev)) 1209 pr_err("sccb_read failed 2\n"); 1210 1211 return reg_r(gspca_dev, OV534_REG_READ); 1212 } 1213 1214 /* output a bridge sequence (reg - val) */ 1215 static void reg_w_array(struct gspca_dev *gspca_dev, 1216 const u8 (*data)[2], int len) 1217 { 1218 while (--len >= 0) { 1219 reg_w(gspca_dev, (*data)[0], (*data)[1]); 1220 data++; 1221 } 1222 } 1223 1224 /* output a sensor sequence (reg - val) */ 1225 static void sccb_w_array(struct gspca_dev *gspca_dev, 1226 const u8 (*data)[2], int len) 1227 { 1228 while (--len >= 0) { 1229 if ((*data)[0] != 0xff) { 1230 sccb_write(gspca_dev, (*data)[0], (*data)[1]); 1231 } else { 1232 sccb_read(gspca_dev, (*data)[1]); 1233 sccb_write(gspca_dev, 0xff, 0x00); 1234 } 1235 data++; 1236 } 1237 } 1238 1239 /* Two bits control LED: 0x21 bit 7 and 0x23 bit 7. 1240 * (direction and output)? */ 1241 static void set_led(struct gspca_dev *gspca_dev, int status) 1242 { 1243 u8 data; 1244 1245 PDEBUG(D_CONF, "led status: %d", status); 1246 1247 data = reg_r(gspca_dev, 0x21); 1248 data |= 0x80; 1249 reg_w(gspca_dev, 0x21, data); 1250 1251 data = reg_r(gspca_dev, 0x23); 1252 if (status) 1253 data |= 0x80; 1254 else 1255 data &= ~0x80; 1256 1257 reg_w(gspca_dev, 0x23, data); 1258 1259 if (!status) { 1260 data = reg_r(gspca_dev, 0x21); 1261 data &= ~0x80; 1262 reg_w(gspca_dev, 0x21, data); 1263 } 1264 } 1265 1266 static void setbrightness(struct gspca_dev *gspca_dev, s32 brightness) 1267 { 1268 struct sd *sd = (struct sd *) gspca_dev; 1269 u8 val; 1270 s8 sval; 1271 1272 if (sd->sensor == SENSOR_OV562x) { 1273 sval = brightness; 1274 val = 0x76; 1275 val += sval; 1276 sccb_write(gspca_dev, 0x24, val); 1277 val = 0x6a; 1278 val += sval; 1279 sccb_write(gspca_dev, 0x25, val); 1280 if (sval < -40) 1281 val = 0x71; 1282 else if (sval < 20) 1283 val = 0x94; 1284 else 1285 val = 0xe6; 1286 sccb_write(gspca_dev, 0x26, val); 1287 } else { 1288 val = brightness; 1289 if (val < 8) 1290 val = 15 - val; /* f .. 8 */ 1291 else 1292 val = val - 8; /* 0 .. 7 */ 1293 sccb_write(gspca_dev, 0x55, /* brtn - brightness adjustment */ 1294 0x0f | (val << 4)); 1295 } 1296 } 1297 1298 static void setcontrast(struct gspca_dev *gspca_dev, s32 val) 1299 { 1300 sccb_write(gspca_dev, 0x56, /* cnst1 - contrast 1 ctrl coeff */ 1301 val << 4); 1302 } 1303 1304 static void setautogain(struct gspca_dev *gspca_dev, s32 autogain) 1305 { 1306 u8 val; 1307 1308 /*fixme: should adjust agc/awb/aec by different controls */ 1309 val = sccb_read(gspca_dev, 0x13); /* com8 */ 1310 sccb_write(gspca_dev, 0xff, 0x00); 1311 if (autogain) 1312 val |= 0x05; /* agc & aec */ 1313 else 1314 val &= 0xfa; 1315 sccb_write(gspca_dev, 0x13, val); 1316 } 1317 1318 static void setexposure(struct gspca_dev *gspca_dev, s32 exposure) 1319 { 1320 static const u8 expo[4] = {0x00, 0x25, 0x38, 0x5e}; 1321 u8 val; 1322 1323 sccb_write(gspca_dev, 0x10, expo[exposure]); /* aec[9:2] */ 1324 1325 val = sccb_read(gspca_dev, 0x13); /* com8 */ 1326 sccb_write(gspca_dev, 0xff, 0x00); 1327 sccb_write(gspca_dev, 0x13, val); 1328 1329 val = sccb_read(gspca_dev, 0xa1); /* aech */ 1330 sccb_write(gspca_dev, 0xff, 0x00); 1331 sccb_write(gspca_dev, 0xa1, val & 0xe0); /* aec[15:10] = 0 */ 1332 } 1333 1334 static void setsharpness(struct gspca_dev *gspca_dev, s32 val) 1335 { 1336 if (val < 0) { /* auto */ 1337 val = sccb_read(gspca_dev, 0x42); /* com17 */ 1338 sccb_write(gspca_dev, 0xff, 0x00); 1339 sccb_write(gspca_dev, 0x42, val | 0x40); 1340 /* Edge enhancement strength auto adjust */ 1341 return; 1342 } 1343 if (val != 0) 1344 val = 1 << (val - 1); 1345 sccb_write(gspca_dev, 0x3f, /* edge - edge enhance. factor */ 1346 val); 1347 val = sccb_read(gspca_dev, 0x42); /* com17 */ 1348 sccb_write(gspca_dev, 0xff, 0x00); 1349 sccb_write(gspca_dev, 0x42, val & 0xbf); 1350 } 1351 1352 static void setsatur(struct gspca_dev *gspca_dev, s32 val) 1353 { 1354 u8 val1, val2, val3; 1355 static const u8 matrix[5][2] = { 1356 {0x14, 0x38}, 1357 {0x1e, 0x54}, 1358 {0x28, 0x70}, 1359 {0x32, 0x8c}, 1360 {0x48, 0x90} 1361 }; 1362 1363 val1 = matrix[val][0]; 1364 val2 = matrix[val][1]; 1365 val3 = val1 + val2; 1366 sccb_write(gspca_dev, 0x4f, val3); /* matrix coeff */ 1367 sccb_write(gspca_dev, 0x50, val3); 1368 sccb_write(gspca_dev, 0x51, 0x00); 1369 sccb_write(gspca_dev, 0x52, val1); 1370 sccb_write(gspca_dev, 0x53, val2); 1371 sccb_write(gspca_dev, 0x54, val3); 1372 sccb_write(gspca_dev, 0x58, 0x1a); /* mtxs - coeff signs */ 1373 1374 val1 = sccb_read(gspca_dev, 0x41); /* com16 */ 1375 sccb_write(gspca_dev, 0xff, 0x00); 1376 sccb_write(gspca_dev, 0x41, val1); 1377 } 1378 1379 static void setlightfreq(struct gspca_dev *gspca_dev, s32 freq) 1380 { 1381 u8 val; 1382 1383 val = sccb_read(gspca_dev, 0x13); /* com8 */ 1384 sccb_write(gspca_dev, 0xff, 0x00); 1385 if (freq == 0) { 1386 sccb_write(gspca_dev, 0x13, val & 0xdf); 1387 return; 1388 } 1389 sccb_write(gspca_dev, 0x13, val | 0x20); 1390 1391 val = sccb_read(gspca_dev, 0x42); /* com17 */ 1392 sccb_write(gspca_dev, 0xff, 0x00); 1393 if (freq == 1) 1394 val |= 0x01; 1395 else 1396 val &= 0xfe; 1397 sccb_write(gspca_dev, 0x42, val); 1398 } 1399 1400 /* this function is called at probe time */ 1401 static int sd_config(struct gspca_dev *gspca_dev, 1402 const struct usb_device_id *id) 1403 { 1404 return 0; 1405 } 1406 1407 /* this function is called at probe and resume time */ 1408 static int sd_init(struct gspca_dev *gspca_dev) 1409 { 1410 struct sd *sd = (struct sd *) gspca_dev; 1411 u16 sensor_id; 1412 1413 /* reset bridge */ 1414 reg_w(gspca_dev, 0xe7, 0x3a); 1415 reg_w(gspca_dev, 0xe0, 0x08); 1416 msleep(100); 1417 1418 /* initialize the sensor address */ 1419 reg_w(gspca_dev, OV534_REG_ADDRESS, 0x60); 1420 1421 /* reset sensor */ 1422 sccb_write(gspca_dev, 0x12, 0x80); 1423 msleep(10); 1424 1425 /* probe the sensor */ 1426 sccb_read(gspca_dev, 0x0a); 1427 sensor_id = sccb_read(gspca_dev, 0x0a) << 8; 1428 sccb_read(gspca_dev, 0x0b); 1429 sensor_id |= sccb_read(gspca_dev, 0x0b); 1430 PDEBUG(D_PROBE, "Sensor ID: %04x", sensor_id); 1431 1432 /* initialize */ 1433 if ((sensor_id & 0xfff0) == 0x9650) { 1434 sd->sensor = SENSOR_OV965x; 1435 1436 gspca_dev->cam.cam_mode = ov965x_mode; 1437 gspca_dev->cam.nmodes = ARRAY_SIZE(ov965x_mode); 1438 1439 reg_w_array(gspca_dev, bridge_init, 1440 ARRAY_SIZE(bridge_init)); 1441 sccb_w_array(gspca_dev, ov965x_init, 1442 ARRAY_SIZE(ov965x_init)); 1443 reg_w_array(gspca_dev, bridge_init_2, 1444 ARRAY_SIZE(bridge_init_2)); 1445 sccb_w_array(gspca_dev, ov965x_init_2, 1446 ARRAY_SIZE(ov965x_init_2)); 1447 reg_w(gspca_dev, 0xe0, 0x00); 1448 reg_w(gspca_dev, 0xe0, 0x01); 1449 set_led(gspca_dev, 0); 1450 reg_w(gspca_dev, 0xe0, 0x00); 1451 } else if ((sensor_id & 0xfff0) == 0x9710) { 1452 const char *p; 1453 int l; 1454 1455 sd->sensor = SENSOR_OV971x; 1456 1457 gspca_dev->cam.cam_mode = ov971x_mode; 1458 gspca_dev->cam.nmodes = ARRAY_SIZE(ov971x_mode); 1459 1460 gspca_dev->cam.bulk = 1; 1461 gspca_dev->cam.bulk_size = 16384; 1462 gspca_dev->cam.bulk_nurbs = 2; 1463 1464 sccb_w_array(gspca_dev, ov971x_init, 1465 ARRAY_SIZE(ov971x_init)); 1466 1467 /* set video format on bridge processor */ 1468 /* access bridge processor's video format registers at: 0x00 */ 1469 reg_w(gspca_dev, 0x1c, 0x00); 1470 /*set register: 0x00 is 'RAW8', 0x40 is 'YUV422' (YUYV?)*/ 1471 reg_w(gspca_dev, 0x1d, 0x00); 1472 1473 /* Will W. specific stuff 1474 * set VSYNC to 1475 * output (0x1f) if first webcam 1476 * input (0x17) if 2nd or 3rd webcam */ 1477 p = video_device_node_name(&gspca_dev->vdev); 1478 l = strlen(p) - 1; 1479 if (p[l] == '0') 1480 reg_w(gspca_dev, 0x56, 0x1f); 1481 else 1482 reg_w(gspca_dev, 0x56, 0x17); 1483 } else if ((sensor_id & 0xfff0) == 0x5620) { 1484 sd->sensor = SENSOR_OV562x; 1485 gspca_dev->cam.cam_mode = ov562x_mode; 1486 gspca_dev->cam.nmodes = ARRAY_SIZE(ov562x_mode); 1487 1488 reg_w_array(gspca_dev, ov562x_init, 1489 ARRAY_SIZE(ov562x_init)); 1490 sccb_w_array(gspca_dev, ov562x_init_2, 1491 ARRAY_SIZE(ov562x_init_2)); 1492 reg_w(gspca_dev, 0xe0, 0x00); 1493 } else if ((sensor_id & 0xfff0) == 0x3610) { 1494 sd->sensor = SENSOR_OV361x; 1495 gspca_dev->cam.cam_mode = ov361x_mode; 1496 gspca_dev->cam.nmodes = ARRAY_SIZE(ov361x_mode); 1497 reg_w(gspca_dev, 0xe7, 0x3a); 1498 reg_w(gspca_dev, 0xf1, 0x60); 1499 sccb_write(gspca_dev, 0x12, 0x80); 1500 } else { 1501 pr_err("Unknown sensor %04x", sensor_id); 1502 return -EINVAL; 1503 } 1504 1505 return gspca_dev->usb_err; 1506 } 1507 1508 static int sd_start_ov361x(struct gspca_dev *gspca_dev) 1509 { 1510 sccb_write(gspca_dev, 0x12, 0x80); 1511 msleep(20); 1512 switch (gspca_dev->curr_mode % (ov361x_last)) { 1513 case ov361x_2048: 1514 reg_w_array(gspca_dev, ov361x_bridge_start_2048, 1515 ARRAY_SIZE(ov361x_bridge_start_2048)); 1516 sccb_w_array(gspca_dev, ov361x_start_2048, 1517 ARRAY_SIZE(ov361x_start_2048)); 1518 break; 1519 case ov361x_1600: 1520 reg_w_array(gspca_dev, ov361x_bridge_start_1600, 1521 ARRAY_SIZE(ov361x_bridge_start_1600)); 1522 sccb_w_array(gspca_dev, ov361x_start_1600, 1523 ARRAY_SIZE(ov361x_start_1600)); 1524 break; 1525 case ov361x_1024: 1526 reg_w_array(gspca_dev, ov361x_bridge_start_1024, 1527 ARRAY_SIZE(ov361x_bridge_start_1024)); 1528 sccb_w_array(gspca_dev, ov361x_start_1024, 1529 ARRAY_SIZE(ov361x_start_1024)); 1530 break; 1531 case ov361x_640: 1532 reg_w_array(gspca_dev, ov361x_bridge_start_640, 1533 ARRAY_SIZE(ov361x_bridge_start_640)); 1534 sccb_w_array(gspca_dev, ov361x_start_640, 1535 ARRAY_SIZE(ov361x_start_640)); 1536 break; 1537 case ov361x_320: 1538 reg_w_array(gspca_dev, ov361x_bridge_start_320, 1539 ARRAY_SIZE(ov361x_bridge_start_320)); 1540 sccb_w_array(gspca_dev, ov361x_start_320, 1541 ARRAY_SIZE(ov361x_start_320)); 1542 break; 1543 case ov361x_160: 1544 reg_w_array(gspca_dev, ov361x_bridge_start_160, 1545 ARRAY_SIZE(ov361x_bridge_start_160)); 1546 sccb_w_array(gspca_dev, ov361x_start_160, 1547 ARRAY_SIZE(ov361x_start_160)); 1548 break; 1549 } 1550 reg_w(gspca_dev, 0xe0, 0x00); /* start transfer */ 1551 1552 return gspca_dev->usb_err; 1553 } 1554 1555 static int sd_start(struct gspca_dev *gspca_dev) 1556 { 1557 struct sd *sd = (struct sd *) gspca_dev; 1558 1559 if (sd->sensor == SENSOR_OV971x) 1560 return gspca_dev->usb_err; 1561 if (sd->sensor == SENSOR_OV562x) 1562 return gspca_dev->usb_err; 1563 if (sd->sensor == SENSOR_OV361x) 1564 return sd_start_ov361x(gspca_dev); 1565 1566 switch (gspca_dev->curr_mode) { 1567 case QVGA_MODE: /* 320x240 */ 1568 sccb_w_array(gspca_dev, ov965x_start_1_vga, 1569 ARRAY_SIZE(ov965x_start_1_vga)); 1570 reg_w_array(gspca_dev, bridge_start_qvga, 1571 ARRAY_SIZE(bridge_start_qvga)); 1572 sccb_w_array(gspca_dev, ov965x_start_2_qvga, 1573 ARRAY_SIZE(ov965x_start_2_qvga)); 1574 break; 1575 case VGA_MODE: /* 640x480 */ 1576 sccb_w_array(gspca_dev, ov965x_start_1_vga, 1577 ARRAY_SIZE(ov965x_start_1_vga)); 1578 reg_w_array(gspca_dev, bridge_start_vga, 1579 ARRAY_SIZE(bridge_start_vga)); 1580 sccb_w_array(gspca_dev, ov965x_start_2_vga, 1581 ARRAY_SIZE(ov965x_start_2_vga)); 1582 break; 1583 case SVGA_MODE: /* 800x600 */ 1584 sccb_w_array(gspca_dev, ov965x_start_1_svga, 1585 ARRAY_SIZE(ov965x_start_1_svga)); 1586 reg_w_array(gspca_dev, bridge_start_svga, 1587 ARRAY_SIZE(bridge_start_svga)); 1588 sccb_w_array(gspca_dev, ov965x_start_2_svga, 1589 ARRAY_SIZE(ov965x_start_2_svga)); 1590 break; 1591 case XGA_MODE: /* 1024x768 */ 1592 sccb_w_array(gspca_dev, ov965x_start_1_xga, 1593 ARRAY_SIZE(ov965x_start_1_xga)); 1594 reg_w_array(gspca_dev, bridge_start_xga, 1595 ARRAY_SIZE(bridge_start_xga)); 1596 sccb_w_array(gspca_dev, ov965x_start_2_svga, 1597 ARRAY_SIZE(ov965x_start_2_svga)); 1598 break; 1599 default: 1600 /* case SXGA_MODE: * 1280x1024 */ 1601 sccb_w_array(gspca_dev, ov965x_start_1_sxga, 1602 ARRAY_SIZE(ov965x_start_1_sxga)); 1603 reg_w_array(gspca_dev, bridge_start_sxga, 1604 ARRAY_SIZE(bridge_start_sxga)); 1605 sccb_w_array(gspca_dev, ov965x_start_2_sxga, 1606 ARRAY_SIZE(ov965x_start_2_sxga)); 1607 break; 1608 } 1609 1610 reg_w(gspca_dev, 0xe0, 0x00); 1611 reg_w(gspca_dev, 0xe0, 0x00); 1612 set_led(gspca_dev, 1); 1613 return gspca_dev->usb_err; 1614 } 1615 1616 static void sd_stopN(struct gspca_dev *gspca_dev) 1617 { 1618 if (((struct sd *)gspca_dev)->sensor == SENSOR_OV361x) { 1619 reg_w(gspca_dev, 0xe0, 0x01); /* stop transfer */ 1620 /* reg_w(gspca_dev, 0x31, 0x09); */ 1621 return; 1622 } 1623 reg_w(gspca_dev, 0xe0, 0x01); 1624 set_led(gspca_dev, 0); 1625 reg_w(gspca_dev, 0xe0, 0x00); 1626 } 1627 1628 /* Values for bmHeaderInfo (Video and Still Image Payload Headers, 2.4.3.3) */ 1629 #define UVC_STREAM_EOH (1 << 7) 1630 #define UVC_STREAM_ERR (1 << 6) 1631 #define UVC_STREAM_STI (1 << 5) 1632 #define UVC_STREAM_RES (1 << 4) 1633 #define UVC_STREAM_SCR (1 << 3) 1634 #define UVC_STREAM_PTS (1 << 2) 1635 #define UVC_STREAM_EOF (1 << 1) 1636 #define UVC_STREAM_FID (1 << 0) 1637 1638 static void sd_pkt_scan(struct gspca_dev *gspca_dev, 1639 u8 *data, int len) 1640 { 1641 struct sd *sd = (struct sd *) gspca_dev; 1642 __u32 this_pts; 1643 u8 this_fid; 1644 int remaining_len = len; 1645 int payload_len; 1646 1647 payload_len = gspca_dev->cam.bulk ? 2048 : 2040; 1648 do { 1649 len = min(remaining_len, payload_len); 1650 1651 /* Payloads are prefixed with a UVC-style header. We 1652 consider a frame to start when the FID toggles, or the PTS 1653 changes. A frame ends when EOF is set, and we've received 1654 the correct number of bytes. */ 1655 1656 /* Verify UVC header. Header length is always 12 */ 1657 if (data[0] != 12 || len < 12) { 1658 PDEBUG(D_PACK, "bad header"); 1659 goto discard; 1660 } 1661 1662 /* Check errors */ 1663 if (data[1] & UVC_STREAM_ERR) { 1664 PDEBUG(D_PACK, "payload error"); 1665 goto discard; 1666 } 1667 1668 /* Extract PTS and FID */ 1669 if (!(data[1] & UVC_STREAM_PTS)) { 1670 PDEBUG(D_PACK, "PTS not present"); 1671 goto discard; 1672 } 1673 this_pts = (data[5] << 24) | (data[4] << 16) 1674 | (data[3] << 8) | data[2]; 1675 this_fid = data[1] & UVC_STREAM_FID; 1676 1677 /* If PTS or FID has changed, start a new frame. */ 1678 if (this_pts != sd->last_pts || this_fid != sd->last_fid) { 1679 if (gspca_dev->last_packet_type == INTER_PACKET) 1680 gspca_frame_add(gspca_dev, LAST_PACKET, 1681 NULL, 0); 1682 sd->last_pts = this_pts; 1683 sd->last_fid = this_fid; 1684 gspca_frame_add(gspca_dev, FIRST_PACKET, 1685 data + 12, len - 12); 1686 /* If this packet is marked as EOF, end the frame */ 1687 } else if (data[1] & UVC_STREAM_EOF) { 1688 sd->last_pts = 0; 1689 gspca_frame_add(gspca_dev, LAST_PACKET, 1690 data + 12, len - 12); 1691 } else { 1692 1693 /* Add the data from this payload */ 1694 gspca_frame_add(gspca_dev, INTER_PACKET, 1695 data + 12, len - 12); 1696 } 1697 1698 /* Done this payload */ 1699 goto scan_next; 1700 1701 discard: 1702 /* Discard data until a new frame starts. */ 1703 gspca_dev->last_packet_type = DISCARD_PACKET; 1704 1705 scan_next: 1706 remaining_len -= len; 1707 data += len; 1708 } while (remaining_len > 0); 1709 } 1710 1711 static int sd_s_ctrl(struct v4l2_ctrl *ctrl) 1712 { 1713 struct gspca_dev *gspca_dev = 1714 container_of(ctrl->handler, struct gspca_dev, ctrl_handler); 1715 1716 gspca_dev->usb_err = 0; 1717 1718 if (!gspca_dev->streaming) 1719 return 0; 1720 1721 switch (ctrl->id) { 1722 case V4L2_CID_BRIGHTNESS: 1723 setbrightness(gspca_dev, ctrl->val); 1724 break; 1725 case V4L2_CID_CONTRAST: 1726 setcontrast(gspca_dev, ctrl->val); 1727 break; 1728 case V4L2_CID_SATURATION: 1729 setsatur(gspca_dev, ctrl->val); 1730 break; 1731 case V4L2_CID_POWER_LINE_FREQUENCY: 1732 setlightfreq(gspca_dev, ctrl->val); 1733 break; 1734 case V4L2_CID_SHARPNESS: 1735 setsharpness(gspca_dev, ctrl->val); 1736 break; 1737 case V4L2_CID_AUTOGAIN: 1738 if (ctrl->is_new) 1739 setautogain(gspca_dev, ctrl->val); 1740 if (!ctrl->val && gspca_dev->exposure->is_new) 1741 setexposure(gspca_dev, gspca_dev->exposure->val); 1742 break; 1743 } 1744 return gspca_dev->usb_err; 1745 } 1746 1747 static const struct v4l2_ctrl_ops sd_ctrl_ops = { 1748 .s_ctrl = sd_s_ctrl, 1749 }; 1750 1751 static int sd_init_controls(struct gspca_dev *gspca_dev) 1752 { 1753 struct sd *sd = (struct sd *)gspca_dev; 1754 struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; 1755 1756 if (sd->sensor == SENSOR_OV971x) 1757 return 0; 1758 if (sd->sensor == SENSOR_OV361x) 1759 return 0; 1760 gspca_dev->vdev.ctrl_handler = hdl; 1761 v4l2_ctrl_handler_init(hdl, 7); 1762 if (sd->sensor == SENSOR_OV562x) { 1763 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 1764 V4L2_CID_BRIGHTNESS, -90, 90, 1, 0); 1765 } else { 1766 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 1767 V4L2_CID_BRIGHTNESS, 0, 15, 1, 7); 1768 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 1769 V4L2_CID_CONTRAST, 0, 15, 1, 3); 1770 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 1771 V4L2_CID_SATURATION, 0, 4, 1, 2); 1772 /* -1 = auto */ 1773 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 1774 V4L2_CID_SHARPNESS, -1, 4, 1, -1); 1775 gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 1776 V4L2_CID_AUTOGAIN, 0, 1, 1, 1); 1777 gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 1778 V4L2_CID_EXPOSURE, 0, 3, 1, 0); 1779 v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops, 1780 V4L2_CID_POWER_LINE_FREQUENCY, 1781 V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0, 0); 1782 v4l2_ctrl_auto_cluster(3, &gspca_dev->autogain, 0, false); 1783 } 1784 1785 if (hdl->error) { 1786 pr_err("Could not initialize controls\n"); 1787 return hdl->error; 1788 } 1789 return 0; 1790 } 1791 1792 /* sub-driver description */ 1793 static const struct sd_desc sd_desc = { 1794 .name = MODULE_NAME, 1795 .config = sd_config, 1796 .init = sd_init, 1797 .init_controls = sd_init_controls, 1798 .start = sd_start, 1799 .stopN = sd_stopN, 1800 .pkt_scan = sd_pkt_scan, 1801 }; 1802 1803 /* -- module initialisation -- */ 1804 static const struct usb_device_id device_table[] = { 1805 {USB_DEVICE(0x05a9, 0x8065)}, 1806 {USB_DEVICE(0x06f8, 0x3003)}, 1807 {USB_DEVICE(0x05a9, 0x1550)}, 1808 {} 1809 }; 1810 1811 MODULE_DEVICE_TABLE(usb, device_table); 1812 1813 /* -- device connect -- */ 1814 static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id) 1815 { 1816 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), 1817 THIS_MODULE); 1818 } 1819 1820 static struct usb_driver sd_driver = { 1821 .name = MODULE_NAME, 1822 .id_table = device_table, 1823 .probe = sd_probe, 1824 .disconnect = gspca_disconnect, 1825 #ifdef CONFIG_PM 1826 .suspend = gspca_suspend, 1827 .resume = gspca_resume, 1828 .reset_resume = gspca_resume, 1829 #endif 1830 }; 1831 1832 module_usb_driver(sd_driver); 1833