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