linux/drivers/media/video/gspca/ov534.c
<<
>>
Prefs
   1/*
   2 * ov534 gspca driver
   3 * Copyright (C) 2008 Antonio Ospite <ospite@studenti.unina.it>
   4 * Copyright (C) 2008 Jim Paris <jim@jtan.com>
   5 * Copyright (C) 2009 Jean-Francois Moine http://moinejf.free.fr
   6 *
   7 * Based on a prototype written by Mark Ferrell <majortrips@gmail.com>
   8 * USB protocol reverse engineered by Jim Paris <jim@jtan.com>
   9 * https://jim.sh/svn/jim/devl/playstation/ps3/eye/test/
  10 *
  11 * This program is free software; you can redistribute it and/or modify
  12 * it under the terms of the GNU General Public License as published by
  13 * the Free Software Foundation; either version 2 of the License, or
  14 * any later version.
  15 *
  16 * This program is distributed in the hope that it will be useful,
  17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19 * GNU General Public License for more details.
  20 *
  21 * You should have received a copy of the GNU General Public License
  22 * along with this program; if not, write to the Free Software
  23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  24 */
  25
  26#define MODULE_NAME "ov534"
  27
  28#include "gspca.h"
  29
  30#define OV534_REG_ADDRESS       0xf1    /* sensor address */
  31#define OV534_REG_SUBADDR       0xf2
  32#define OV534_REG_WRITE         0xf3
  33#define OV534_REG_READ          0xf4
  34#define OV534_REG_OPERATION     0xf5
  35#define OV534_REG_STATUS        0xf6
  36
  37#define OV534_OP_WRITE_3        0x37
  38#define OV534_OP_WRITE_2        0x33
  39#define OV534_OP_READ_2         0xf9
  40
  41#define CTRL_TIMEOUT 500
  42
  43MODULE_AUTHOR("Antonio Ospite <ospite@studenti.unina.it>");
  44MODULE_DESCRIPTION("GSPCA/OV534 USB Camera Driver");
  45MODULE_LICENSE("GPL");
  46
  47/* specific webcam descriptor */
  48struct sd {
  49        struct gspca_dev gspca_dev;     /* !! must be the first item */
  50        __u32 last_pts;
  51        u16 last_fid;
  52        u8 frame_rate;
  53
  54        u8 sensor;
  55#define SENSOR_OV772X 0
  56#define SENSOR_OV965X 1
  57};
  58
  59/* V4L2 controls supported by the driver */
  60static struct ctrl sd_ctrls[] = {
  61};
  62
  63static const struct v4l2_pix_format vga_yuyv_mode[] = {
  64        {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
  65         .bytesperline = 640 * 2,
  66         .sizeimage = 640 * 480 * 2,
  67         .colorspace = V4L2_COLORSPACE_SRGB,
  68         .priv = 0},
  69};
  70
  71static const struct v4l2_pix_format vga_jpeg_mode[] = {
  72        {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
  73         .bytesperline = 320,
  74         .sizeimage = 320 * 240 * 3 / 8 + 590,
  75         .colorspace = V4L2_COLORSPACE_JPEG,
  76         .priv = 1},
  77        {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
  78         .bytesperline = 640,
  79         .sizeimage = 640 * 480 * 3 / 8 + 590,
  80         .colorspace = V4L2_COLORSPACE_JPEG,
  81         .priv = 0},
  82};
  83
  84static const u8 bridge_init_ov722x[][2] = {
  85        { 0xc2, 0x0c },
  86        { 0x88, 0xf8 },
  87        { 0xc3, 0x69 },
  88        { 0x89, 0xff },
  89        { 0x76, 0x03 },
  90        { 0x92, 0x01 },
  91        { 0x93, 0x18 },
  92        { 0x94, 0x10 },
  93        { 0x95, 0x10 },
  94        { 0xe2, 0x00 },
  95        { 0xe7, 0x3e },
  96
  97        { 0x96, 0x00 },
  98
  99        { 0x97, 0x20 },
 100        { 0x97, 0x20 },
 101        { 0x97, 0x20 },
 102        { 0x97, 0x0a },
 103        { 0x97, 0x3f },
 104        { 0x97, 0x4a },
 105        { 0x97, 0x20 },
 106        { 0x97, 0x15 },
 107        { 0x97, 0x0b },
 108
 109        { 0x8e, 0x40 },
 110        { 0x1f, 0x81 },
 111        { 0x34, 0x05 },
 112        { 0xe3, 0x04 },
 113        { 0x88, 0x00 },
 114        { 0x89, 0x00 },
 115        { 0x76, 0x00 },
 116        { 0xe7, 0x2e },
 117        { 0x31, 0xf9 },
 118        { 0x25, 0x42 },
 119        { 0x21, 0xf0 },
 120
 121        { 0x1c, 0x00 },
 122        { 0x1d, 0x40 },
 123        { 0x1d, 0x02 }, /* payload size 0x0200 * 4 = 2048 bytes */
 124        { 0x1d, 0x00 }, /* payload size */
 125        { 0x1d, 0x02 }, /* frame size 0x025800 * 4 = 614400 */
 126        { 0x1d, 0x58 }, /* frame size */
 127        { 0x1d, 0x00 }, /* frame size */
 128
 129        { 0x1c, 0x0a },
 130        { 0x1d, 0x08 }, /* turn on UVC header */
 131        { 0x1d, 0x0e }, /* .. */
 132
 133        { 0x8d, 0x1c },
 134        { 0x8e, 0x80 },
 135        { 0xe5, 0x04 },
 136
 137        { 0xc0, 0x50 },
 138        { 0xc1, 0x3c },
 139        { 0xc2, 0x0c },
 140};
 141
 142static const u8 sensor_init_ov722x[][2] = {
 143        { 0x12, 0x80 },
 144        { 0x11, 0x01 },
 145
 146        { 0x3d, 0x03 },
 147        { 0x17, 0x26 },
 148        { 0x18, 0xa0 },
 149        { 0x19, 0x07 },
 150        { 0x1a, 0xf0 },
 151        { 0x32, 0x00 },
 152        { 0x29, 0xa0 },
 153        { 0x2c, 0xf0 },
 154        { 0x65, 0x20 },
 155        { 0x11, 0x01 },
 156        { 0x42, 0x7f },
 157        { 0x63, 0xe0 },
 158        { 0x64, 0xff },
 159        { 0x66, 0x00 },
 160        { 0x13, 0xf0 },
 161        { 0x0d, 0x41 },
 162        { 0x0f, 0xc5 },
 163        { 0x14, 0x11 },
 164
 165        { 0x22, 0x7f },
 166        { 0x23, 0x03 },
 167        { 0x24, 0x40 },
 168        { 0x25, 0x30 },
 169        { 0x26, 0xa1 },
 170        { 0x2a, 0x00 },
 171        { 0x2b, 0x00 },
 172        { 0x6b, 0xaa },
 173        { 0x13, 0xff },
 174
 175        { 0x90, 0x05 },
 176        { 0x91, 0x01 },
 177        { 0x92, 0x03 },
 178        { 0x93, 0x00 },
 179        { 0x94, 0x60 },
 180        { 0x95, 0x3c },
 181        { 0x96, 0x24 },
 182        { 0x97, 0x1e },
 183        { 0x98, 0x62 },
 184        { 0x99, 0x80 },
 185        { 0x9a, 0x1e },
 186        { 0x9b, 0x08 },
 187        { 0x9c, 0x20 },
 188        { 0x9e, 0x81 },
 189
 190        { 0xa6, 0x04 },
 191        { 0x7e, 0x0c },
 192        { 0x7f, 0x16 },
 193        { 0x80, 0x2a },
 194        { 0x81, 0x4e },
 195        { 0x82, 0x61 },
 196        { 0x83, 0x6f },
 197        { 0x84, 0x7b },
 198        { 0x85, 0x86 },
 199        { 0x86, 0x8e },
 200        { 0x87, 0x97 },
 201        { 0x88, 0xa4 },
 202        { 0x89, 0xaf },
 203        { 0x8a, 0xc5 },
 204        { 0x8b, 0xd7 },
 205        { 0x8c, 0xe8 },
 206        { 0x8d, 0x20 },
 207
 208        { 0x0c, 0x90 },
 209
 210        { 0x2b, 0x00 },
 211        { 0x22, 0x7f },
 212        { 0x23, 0x03 },
 213        { 0x11, 0x01 },
 214        { 0x0c, 0xd0 },
 215        { 0x64, 0xff },
 216        { 0x0d, 0x41 },
 217
 218        { 0x14, 0x41 },
 219        { 0x0e, 0xcd },
 220        { 0xac, 0xbf },
 221        { 0x8e, 0x00 },
 222        { 0x0c, 0xd0 }
 223};
 224
 225static const u8 bridge_init_ov965x[][2] = {
 226        {0x88, 0xf8},
 227        {0x89, 0xff},
 228        {0x76, 0x03},
 229        {0x92, 0x03},
 230        {0x95, 0x10},
 231        {0xe2, 0x00},
 232        {0xe7, 0x3e},
 233        {0x8d, 0x1c},
 234        {0x8e, 0x00},
 235        {0x8f, 0x00},
 236        {0x1f, 0x00},
 237        {0xc3, 0xf9},
 238        {0x89, 0xff},
 239        {0x88, 0xf8},
 240        {0x76, 0x03},
 241        {0x92, 0x01},
 242        {0x93, 0x18},
 243        {0x1c, 0x0a},
 244        {0x1d, 0x48},
 245        {0xc0, 0x50},
 246        {0xc1, 0x3c},
 247        {0x34, 0x05},
 248        {0xc2, 0x0c},
 249        {0xc3, 0xf9},
 250        {0x34, 0x05},
 251        {0xe7, 0x2e},
 252        {0x31, 0xf9},
 253        {0x35, 0x02},
 254        {0xd9, 0x10},
 255        {0x25, 0x42},
 256        {0x94, 0x11},
 257};
 258
 259static const u8 sensor_init_ov965x[][2] = {
 260        {0x12, 0x80},   /* com7 - SSCB reset */
 261        {0x00, 0x00},   /* gain */
 262        {0x01, 0x80},   /* blue */
 263        {0x02, 0x80},   /* red */
 264        {0x03, 0x1b},   /* vref */
 265        {0x04, 0x03},   /* com1 - exposure low bits */
 266        {0x0b, 0x57},   /* ver */
 267        {0x0e, 0x61},   /* com5 */
 268        {0x0f, 0x42},   /* com6 */
 269        {0x11, 0x00},   /* clkrc */
 270        {0x12, 0x02},   /* com7 - 15fps VGA YUYV */
 271        {0x13, 0xe7},   /* com8 - everything (AGC, AWB and AEC) */
 272        {0x14, 0x28},   /* com9 */
 273        {0x16, 0x24},   /* reg16 */
 274        {0x17, 0x1d},   /* hstart*/
 275        {0x18, 0xbd},   /* hstop */
 276        {0x19, 0x01},   /* vstrt */
 277        {0x1a, 0x81},   /* vstop*/
 278        {0x1e, 0x04},   /* mvfp */
 279        {0x24, 0x3c},   /* aew */
 280        {0x25, 0x36},   /* aeb */
 281        {0x26, 0x71},   /* vpt */
 282        {0x27, 0x08},   /* bbias */
 283        {0x28, 0x08},   /* gbbias */
 284        {0x29, 0x15},   /* gr com */
 285        {0x2a, 0x00},   /* exhch */
 286        {0x2b, 0x00},   /* exhcl */
 287        {0x2c, 0x08},   /* rbias */
 288        {0x32, 0xff},   /* href */
 289        {0x33, 0x00},   /* chlf */
 290        {0x34, 0x3f},   /* aref1 */
 291        {0x35, 0x00},   /* aref2 */
 292        {0x36, 0xf8},   /* aref3 */
 293        {0x38, 0x72},   /* adc2 */
 294        {0x39, 0x57},   /* aref4 */
 295        {0x3a, 0x80},   /* tslb - yuyv */
 296        {0x3b, 0xc4},   /* com11 - night mode 1/4 frame rate */
 297        {0x3d, 0x99},   /* com13 */
 298        {0x3f, 0xc1},   /* edge */
 299        {0x40, 0xc0},   /* com15 */
 300        {0x41, 0x40},   /* com16 */
 301        {0x42, 0xc0},   /* com17 */
 302        {0x43, 0x0a},   /* rsvd */
 303        {0x44, 0xf0},
 304        {0x45, 0x46},
 305        {0x46, 0x62},
 306        {0x47, 0x2a},
 307        {0x48, 0x3c},
 308        {0x4a, 0xfc},
 309        {0x4b, 0xfc},
 310        {0x4c, 0x7f},
 311        {0x4d, 0x7f},
 312        {0x4e, 0x7f},
 313        {0x4f, 0x98},   /* matrix */
 314        {0x50, 0x98},
 315        {0x51, 0x00},
 316        {0x52, 0x28},
 317        {0x53, 0x70},
 318        {0x54, 0x98},
 319        {0x58, 0x1a},   /* matrix coef sign */
 320        {0x59, 0x85},   /* AWB control */
 321        {0x5a, 0xa9},
 322        {0x5b, 0x64},
 323        {0x5c, 0x84},
 324        {0x5d, 0x53},
 325        {0x5e, 0x0e},
 326        {0x5f, 0xf0},   /* AWB blue limit */
 327        {0x60, 0xf0},   /* AWB red limit */
 328        {0x61, 0xf0},   /* AWB green limit */
 329        {0x62, 0x00},   /* lcc1 */
 330        {0x63, 0x00},   /* lcc2 */
 331        {0x64, 0x02},   /* lcc3 */
 332        {0x65, 0x16},   /* lcc4 */
 333        {0x66, 0x01},   /* lcc5 */
 334        {0x69, 0x02},   /* hv */
 335        {0x6b, 0x5a},   /* dbvl */
 336        {0x6c, 0x04},
 337        {0x6d, 0x55},
 338        {0x6e, 0x00},
 339        {0x6f, 0x9d},
 340        {0x70, 0x21},   /* dnsth */
 341        {0x71, 0x78},
 342        {0x72, 0x00},   /* poidx */
 343        {0x73, 0x01},   /* pckdv */
 344        {0x74, 0x3a},   /* xindx */
 345        {0x75, 0x35},   /* yindx */
 346        {0x76, 0x01},
 347        {0x77, 0x02},
 348        {0x7a, 0x12},   /* gamma curve */
 349        {0x7b, 0x08},
 350        {0x7c, 0x16},
 351        {0x7d, 0x30},
 352        {0x7e, 0x5e},
 353        {0x7f, 0x72},
 354        {0x80, 0x82},
 355        {0x81, 0x8e},
 356        {0x82, 0x9a},
 357        {0x83, 0xa4},
 358        {0x84, 0xac},
 359        {0x85, 0xb8},
 360        {0x86, 0xc3},
 361        {0x87, 0xd6},
 362        {0x88, 0xe6},
 363        {0x89, 0xf2},
 364        {0x8a, 0x03},
 365        {0x8c, 0x89},   /* com19 */
 366        {0x14, 0x28},   /* com9 */
 367        {0x90, 0x7d},
 368        {0x91, 0x7b},
 369        {0x9d, 0x03},   /* lcc6 */
 370        {0x9e, 0x04},   /* lcc7 */
 371        {0x9f, 0x7a},
 372        {0xa0, 0x79},
 373        {0xa1, 0x40},   /* aechm */
 374        {0xa4, 0x50},   /* com21 */
 375        {0xa5, 0x68},   /* com26 */
 376        {0xa6, 0x4a},   /* AWB green */
 377        {0xa8, 0xc1},   /* refa8 */
 378        {0xa9, 0xef},   /* refa9 */
 379        {0xaa, 0x92},
 380        {0xab, 0x04},
 381        {0xac, 0x80},   /* black level control */
 382        {0xad, 0x80},
 383        {0xae, 0x80},
 384        {0xaf, 0x80},
 385        {0xb2, 0xf2},
 386        {0xb3, 0x20},
 387        {0xb4, 0x20},   /* ctrlb4 */
 388        {0xb5, 0x00},
 389        {0xb6, 0xaf},
 390        {0xbb, 0xae},
 391        {0xbc, 0x7f},   /* ADC channel offsets */
 392        {0xdb, 0x7f},
 393        {0xbe, 0x7f},
 394        {0xbf, 0x7f},
 395        {0xc0, 0xe2},
 396        {0xc1, 0xc0},
 397        {0xc2, 0x01},
 398        {0xc3, 0x4e},
 399        {0xc6, 0x85},
 400        {0xc7, 0x80},   /* com24 */
 401        {0xc9, 0xe0},
 402        {0xca, 0xe8},
 403        {0xcb, 0xf0},
 404        {0xcc, 0xd8},
 405        {0xcd, 0xf1},
 406        {0x4f, 0x98},
 407        {0x50, 0x98},
 408        {0x51, 0x00},
 409        {0x52, 0x28},
 410        {0x53, 0x70},
 411        {0x54, 0x98},
 412        {0x58, 0x1a},
 413        {0xff, 0x41},   /* read 41, write ff 00 */
 414        {0x41, 0x40},   /* com16 */
 415        {0xc5, 0x03},   /* 60 Hz banding filter */
 416        {0x6a, 0x02},   /* 50 Hz banding filter */
 417
 418        {0x12, 0x62},   /* com7 - 30fps VGA YUV */
 419        {0x36, 0xfa},   /* aref3 */
 420        {0x69, 0x0a},   /* hv */
 421        {0x8c, 0x89},   /* com22 */
 422        {0x14, 0x28},   /* com9 */
 423        {0x3e, 0x0c},
 424        {0x41, 0x40},   /* com16 */
 425        {0x72, 0x00},
 426        {0x73, 0x00},
 427        {0x74, 0x3a},
 428        {0x75, 0x35},
 429        {0x76, 0x01},
 430        {0xc7, 0x80},
 431        {0x03, 0x12},   /* vref */
 432        {0x17, 0x16},   /* hstart */
 433        {0x18, 0x02},   /* hstop */
 434        {0x19, 0x01},   /* vstrt */
 435        {0x1a, 0x3d},   /* vstop */
 436        {0x32, 0xff},   /* href */
 437        {0xc0, 0xaa},
 438};
 439
 440static const u8 bridge_init_ov965x_2[][2] = {
 441        {0x94, 0xaa},
 442        {0xf1, 0x60},
 443        {0xe5, 0x04},
 444        {0xc0, 0x50},
 445        {0xc1, 0x3c},
 446        {0x8c, 0x00},
 447        {0x8d, 0x1c},
 448        {0x34, 0x05},
 449
 450        {0xc2, 0x0c},
 451        {0xc3, 0xf9},
 452        {0xda, 0x01},
 453        {0x50, 0x00},
 454        {0x51, 0xa0},
 455        {0x52, 0x3c},
 456        {0x53, 0x00},
 457        {0x54, 0x00},
 458        {0x55, 0x00},   /* brightness */
 459        {0x57, 0x00},   /* contrast 2 */
 460        {0x5c, 0x00},
 461        {0x5a, 0xa0},
 462        {0x5b, 0x78},
 463        {0x35, 0x02},
 464        {0xd9, 0x10},
 465        {0x94, 0x11},
 466};
 467
 468static const u8 sensor_init_ov965x_2[][2] = {
 469        {0x3b, 0xc4},
 470        {0x1e, 0x04},   /* mvfp */
 471        {0x13, 0xe0},   /* com8 */
 472        {0x00, 0x00},   /* gain */
 473        {0x13, 0xe7},   /* com8 - everything (AGC, AWB and AEC) */
 474        {0x11, 0x03},   /* clkrc */
 475        {0x6b, 0x5a},   /* dblv */
 476        {0x6a, 0x05},
 477        {0xc5, 0x07},
 478        {0xa2, 0x4b},
 479        {0xa3, 0x3e},
 480        {0x2d, 0x00},
 481        {0xff, 0x42},   /* read 42, write ff 00 */
 482        {0x42, 0xc0},
 483        {0x2d, 0x00},
 484        {0xff, 0x42},   /* read 42, write ff 00 */
 485        {0x42, 0xc1},
 486        {0x3f, 0x01},
 487        {0xff, 0x42},   /* read 42, write ff 00 */
 488        {0x42, 0xc1},
 489        {0x4f, 0x98},
 490        {0x50, 0x98},
 491        {0x51, 0x00},
 492        {0x52, 0x28},
 493        {0x53, 0x70},
 494        {0x54, 0x98},
 495        {0x58, 0x1a},
 496        {0xff, 0x41},   /* read 41, write ff 00 */
 497        {0x41, 0x40},   /* com16 */
 498        {0x56, 0x40},
 499        {0x55, 0x8f},
 500        {0x10, 0x25},   /* aech - exposure high bits */
 501        {0xff, 0x13},   /* read 13, write ff 00 */
 502        {0x13, 0xe7},   /* com8 - everything (AGC, AWB and AEC) */
 503};
 504
 505static const u8 sensor_start_ov965x[][2] = {
 506        {0x12, 0x62},   /* com7 - 30fps VGA YUV */
 507        {0x36, 0xfa},   /* aref3 */
 508        {0x69, 0x0a},   /* hv */
 509        {0x8c, 0x89},   /* com22 */
 510        {0x14, 0x28},   /* com9 */
 511        {0x3e, 0x0c},   /* com14 */
 512        {0x41, 0x40},   /* com16 */
 513        {0x72, 0x00},
 514        {0x73, 0x00},
 515        {0x74, 0x3a},
 516        {0x75, 0x35},
 517        {0x76, 0x01},
 518        {0xc7, 0x80},   /* com24 */
 519        {0x03, 0x12},   /* vref */
 520        {0x17, 0x16},   /* hstart */
 521        {0x18, 0x02},   /* hstop */
 522        {0x19, 0x01},   /* vstrt */
 523        {0x1a, 0x3d},   /* vstop */
 524        {0x32, 0xff},   /* href */
 525        {0xc0, 0xaa},
 526        {}
 527};
 528
 529static const u8 bridge_start_ov965x[][2] = {
 530        {0x94, 0xaa},
 531        {0xf1, 0x60},
 532        {0xe5, 0x04},
 533        {0xc0, 0x50},
 534        {0xc1, 0x3c},
 535        {0x8c, 0x00},
 536        {0x8d, 0x1c},
 537        {0x34, 0x05},
 538        {}
 539};
 540
 541static const u8 bridge_start_ov965x_vga[][2] = {
 542        {0xc2, 0x0c},
 543        {0xc3, 0xf9},
 544        {0xda, 0x01},
 545        {0x50, 0x00},
 546        {0x51, 0xa0},
 547        {0x52, 0x3c},
 548        {0x53, 0x00},
 549        {0x54, 0x00},
 550        {0x55, 0x00},
 551        {0x57, 0x00},
 552        {0x5c, 0x00},
 553        {0x5a, 0xa0},
 554        {0x5b, 0x78},
 555        {0x35, 0x02},
 556        {0xd9, 0x10},
 557        {0x94, 0x11},
 558        {}
 559};
 560
 561static const u8 bridge_start_ov965x_cif[][2] = {
 562        {0xc2, 0x4c},
 563        {0xc3, 0xf9},
 564        {0xda, 0x00},
 565        {0x50, 0x00},
 566        {0x51, 0xa0},
 567        {0x52, 0x78},
 568        {0x53, 0x00},
 569        {0x54, 0x00},
 570        {0x55, 0x00},
 571        {0x57, 0x00},
 572        {0x5c, 0x00},
 573        {0x5a, 0x50},
 574        {0x5b, 0x3c},
 575        {0x35, 0x02},
 576        {0xd9, 0x10},
 577        {0x94, 0x11},
 578        {}
 579};
 580
 581static const u8 sensor_start_ov965x_vga[][2] = {
 582        {0x3b, 0xc4},   /* com11 - night mode 1/4 frame rate */
 583        {0x1e, 0x04},   /* mvfp */
 584        {0x13, 0xe0},   /* com8 */
 585        {0x00, 0x00},
 586        {0x13, 0xe7},   /* com8 - everything (AGC, AWB and AEC) */
 587        {0x11, 0x03},   /* clkrc */
 588        {0x6b, 0x5a},   /* dblv */
 589        {0x6a, 0x05},   /* 50 Hz banding filter */
 590        {0xc5, 0x07},   /* 60 Hz banding filter */
 591        {0xa2, 0x4b},   /* bd50 */
 592        {0xa3, 0x3e},   /* bd60 */
 593
 594        {0x2d, 0x00},   /* advfl */
 595        {}
 596};
 597
 598static const u8 sensor_start_ov965x_cif[][2] = {
 599        {0x3b, 0xe4},   /* com11 - night mode 1/4 frame rate */
 600        {0x1e, 0x04},   /* mvfp */
 601        {0x13, 0xe0},   /* com8 */
 602        {0x00, 0x00},
 603        {0x13, 0xe7},   /* com8 - everything (AGC, AWB and AEC) */
 604        {0x11, 0x01},   /* clkrc */
 605        {0x6b, 0x5a},   /* dblv */
 606        {0x6a, 0x02},   /* 50 Hz banding filter */
 607        {0xc5, 0x03},   /* 60 Hz banding filter */
 608        {0xa2, 0x96},   /* bd50 */
 609        {0xa3, 0x7d},   /* bd60 */
 610
 611        {0xff, 0x13},   /* read 13, write ff 00 */
 612        {0x13, 0xe7},
 613        {0x3a, 0x80},   /* tslb - yuyv */
 614        {}
 615};
 616
 617static const u8 sensor_start_ov965x_2[][2] = {
 618        {0xff, 0x42},   /* read 42, write ff 00 */
 619        {0x42, 0xc1},   /* com17 - 50 Hz filter */
 620        {}
 621};
 622
 623
 624static void ov534_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val)
 625{
 626        struct usb_device *udev = gspca_dev->dev;
 627        int ret;
 628
 629        PDEBUG(D_USBO, "reg=0x%04x, val=0%02x", reg, val);
 630        gspca_dev->usb_buf[0] = val;
 631        ret = usb_control_msg(udev,
 632                              usb_sndctrlpipe(udev, 0),
 633                              0x01,
 634                              USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 635                              0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT);
 636        if (ret < 0)
 637                PDEBUG(D_ERR, "write failed");
 638}
 639
 640static u8 ov534_reg_read(struct gspca_dev *gspca_dev, u16 reg)
 641{
 642        struct usb_device *udev = gspca_dev->dev;
 643        int ret;
 644
 645        ret = usb_control_msg(udev,
 646                              usb_rcvctrlpipe(udev, 0),
 647                              0x01,
 648                              USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 649                              0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT);
 650        PDEBUG(D_USBI, "reg=0x%04x, data=0x%02x", reg, gspca_dev->usb_buf[0]);
 651        if (ret < 0)
 652                PDEBUG(D_ERR, "read failed");
 653        return gspca_dev->usb_buf[0];
 654}
 655
 656/* Two bits control LED: 0x21 bit 7 and 0x23 bit 7.
 657 * (direction and output)? */
 658static void ov534_set_led(struct gspca_dev *gspca_dev, int status)
 659{
 660        u8 data;
 661
 662        PDEBUG(D_CONF, "led status: %d", status);
 663
 664        data = ov534_reg_read(gspca_dev, 0x21);
 665        data |= 0x80;
 666        ov534_reg_write(gspca_dev, 0x21, data);
 667
 668        data = ov534_reg_read(gspca_dev, 0x23);
 669        if (status)
 670                data |= 0x80;
 671        else
 672                data &= ~0x80;
 673
 674        ov534_reg_write(gspca_dev, 0x23, data);
 675
 676        if (!status) {
 677                data = ov534_reg_read(gspca_dev, 0x21);
 678                data &= ~0x80;
 679                ov534_reg_write(gspca_dev, 0x21, data);
 680        }
 681}
 682
 683static int sccb_check_status(struct gspca_dev *gspca_dev)
 684{
 685        u8 data;
 686        int i;
 687
 688        for (i = 0; i < 5; i++) {
 689                data = ov534_reg_read(gspca_dev, OV534_REG_STATUS);
 690
 691                switch (data) {
 692                case 0x00:
 693                        return 1;
 694                case 0x04:
 695                        return 0;
 696                case 0x03:
 697                        break;
 698                default:
 699                        PDEBUG(D_ERR, "sccb status 0x%02x, attempt %d/5",
 700                               data, i + 1);
 701                }
 702        }
 703        return 0;
 704}
 705
 706static void sccb_reg_write(struct gspca_dev *gspca_dev, u8 reg, u8 val)
 707{
 708        PDEBUG(D_USBO, "reg: 0x%02x, val: 0x%02x", reg, val);
 709        ov534_reg_write(gspca_dev, OV534_REG_SUBADDR, reg);
 710        ov534_reg_write(gspca_dev, OV534_REG_WRITE, val);
 711        ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_3);
 712
 713        if (!sccb_check_status(gspca_dev))
 714                PDEBUG(D_ERR, "sccb_reg_write failed");
 715}
 716
 717static u8 sccb_reg_read(struct gspca_dev *gspca_dev, u16 reg)
 718{
 719        ov534_reg_write(gspca_dev, OV534_REG_SUBADDR, reg);
 720        ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_2);
 721        if (!sccb_check_status(gspca_dev))
 722                PDEBUG(D_ERR, "sccb_reg_read failed 1");
 723
 724        ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_READ_2);
 725        if (!sccb_check_status(gspca_dev))
 726                PDEBUG(D_ERR, "sccb_reg_read failed 2");
 727
 728        return ov534_reg_read(gspca_dev, OV534_REG_READ);
 729}
 730
 731/* output a bridge sequence (reg - val) */
 732static void reg_w_array(struct gspca_dev *gspca_dev,
 733                        const u8 (*data)[2], int len)
 734{
 735        while (--len >= 0) {
 736                ov534_reg_write(gspca_dev, (*data)[0], (*data)[1]);
 737                data++;
 738        }
 739}
 740
 741/* output a sensor sequence (reg - val) */
 742static void sccb_w_array(struct gspca_dev *gspca_dev,
 743                        const u8 (*data)[2], int len)
 744{
 745        while (--len >= 0) {
 746                if ((*data)[0] != 0xff) {
 747                        sccb_reg_write(gspca_dev, (*data)[0], (*data)[1]);
 748                } else {
 749                        sccb_reg_read(gspca_dev, (*data)[1]);
 750                        sccb_reg_write(gspca_dev, 0xff, 0x00);
 751                }
 752                data++;
 753        }
 754}
 755
 756/* set framerate */
 757static void ov534_set_frame_rate(struct gspca_dev *gspca_dev)
 758{
 759        struct sd *sd = (struct sd *) gspca_dev;
 760        int fr = sd->frame_rate;
 761
 762        switch (fr) {
 763        case 50:
 764                sccb_reg_write(gspca_dev, 0x11, 0x01);
 765                sccb_reg_write(gspca_dev, 0x0d, 0x41);
 766                ov534_reg_write(gspca_dev, 0xe5, 0x02);
 767                break;
 768        case 40:
 769                sccb_reg_write(gspca_dev, 0x11, 0x02);
 770                sccb_reg_write(gspca_dev, 0x0d, 0xc1);
 771                ov534_reg_write(gspca_dev, 0xe5, 0x04);
 772                break;
 773/*      case 30: */
 774        default:
 775                fr = 30;
 776                sccb_reg_write(gspca_dev, 0x11, 0x04);
 777                sccb_reg_write(gspca_dev, 0x0d, 0x81);
 778                ov534_reg_write(gspca_dev, 0xe5, 0x02);
 779                break;
 780        case 15:
 781                sccb_reg_write(gspca_dev, 0x11, 0x03);
 782                sccb_reg_write(gspca_dev, 0x0d, 0x41);
 783                ov534_reg_write(gspca_dev, 0xe5, 0x04);
 784                break;
 785        }
 786
 787        sd->frame_rate = fr;
 788        PDEBUG(D_PROBE, "frame_rate: %d", fr);
 789}
 790
 791/* this function is called at probe time */
 792static int sd_config(struct gspca_dev *gspca_dev,
 793                     const struct usb_device_id *id)
 794{
 795        struct sd *sd = (struct sd *) gspca_dev;
 796        struct cam *cam;
 797
 798        sd->sensor = id->driver_info;
 799
 800        cam = &gspca_dev->cam;
 801
 802        if (sd->sensor == SENSOR_OV772X) {
 803                cam->cam_mode = vga_yuyv_mode;
 804                cam->nmodes = ARRAY_SIZE(vga_yuyv_mode);
 805
 806                cam->bulk = 1;
 807                cam->bulk_size = 16384;
 808                cam->bulk_nurbs = 2;
 809        } else {                /* ov965x */
 810                cam->cam_mode = vga_jpeg_mode;
 811                cam->nmodes = ARRAY_SIZE(vga_jpeg_mode);
 812        }
 813
 814        return 0;
 815}
 816
 817/* this function is called at probe and resume time */
 818static int sd_init(struct gspca_dev *gspca_dev)
 819{
 820        struct sd *sd = (struct sd *) gspca_dev;
 821        u16 sensor_id;
 822        static const u8 sensor_addr[2] = {
 823                0x42,                   /* 0 SENSOR_OV772X */
 824                0x60,                   /* 1 SENSOR_OV965X */
 825        };
 826
 827        /* reset bridge */
 828        ov534_reg_write(gspca_dev, 0xe7, 0x3a);
 829        ov534_reg_write(gspca_dev, 0xe0, 0x08);
 830        msleep(100);
 831
 832        /* initialize the sensor address */
 833        ov534_reg_write(gspca_dev, OV534_REG_ADDRESS,
 834                                sensor_addr[sd->sensor]);
 835
 836        /* reset sensor */
 837        sccb_reg_write(gspca_dev, 0x12, 0x80);
 838        msleep(10);
 839
 840        /* probe the sensor */
 841        sccb_reg_read(gspca_dev, 0x0a);
 842        sensor_id = sccb_reg_read(gspca_dev, 0x0a) << 8;
 843        sccb_reg_read(gspca_dev, 0x0b);
 844        sensor_id |= sccb_reg_read(gspca_dev, 0x0b);
 845        PDEBUG(D_PROBE, "Sensor ID: %04x", sensor_id);
 846
 847        /* initialize */
 848        switch (sd->sensor) {
 849        case SENSOR_OV772X:
 850                reg_w_array(gspca_dev, bridge_init_ov722x,
 851                                ARRAY_SIZE(bridge_init_ov722x));
 852                ov534_set_led(gspca_dev, 1);
 853                sccb_w_array(gspca_dev, sensor_init_ov722x,
 854                                ARRAY_SIZE(sensor_init_ov722x));
 855                ov534_reg_write(gspca_dev, 0xe0, 0x09);
 856                ov534_set_led(gspca_dev, 0);
 857                ov534_set_frame_rate(gspca_dev);
 858                break;
 859        default:
 860/*      case SENSOR_OV965X: */
 861                reg_w_array(gspca_dev, bridge_init_ov965x,
 862                                ARRAY_SIZE(bridge_init_ov965x));
 863                sccb_w_array(gspca_dev, sensor_init_ov965x,
 864                                ARRAY_SIZE(sensor_init_ov965x));
 865                reg_w_array(gspca_dev, bridge_init_ov965x_2,
 866                                ARRAY_SIZE(bridge_init_ov965x_2));
 867                sccb_w_array(gspca_dev, sensor_init_ov965x_2,
 868                                ARRAY_SIZE(sensor_init_ov965x_2));
 869                ov534_reg_write(gspca_dev, 0xe0, 0x00);
 870                ov534_reg_write(gspca_dev, 0xe0, 0x01);
 871                ov534_set_led(gspca_dev, 0);
 872                ov534_reg_write(gspca_dev, 0xe0, 0x00);
 873        }
 874
 875        return 0;
 876}
 877
 878static int sd_start(struct gspca_dev *gspca_dev)
 879{
 880        struct sd *sd = (struct sd *) gspca_dev;
 881        int mode;
 882
 883        switch (sd->sensor) {
 884        case SENSOR_OV772X:
 885                ov534_set_led(gspca_dev, 1);
 886                ov534_reg_write(gspca_dev, 0xe0, 0x00);
 887                break;
 888        default:
 889/*      case SENSOR_OV965X: */
 890
 891                sccb_w_array(gspca_dev, sensor_start_ov965x,
 892                                ARRAY_SIZE(sensor_start_ov965x));
 893                reg_w_array(gspca_dev, bridge_start_ov965x,
 894                                ARRAY_SIZE(bridge_start_ov965x));
 895                mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
 896                if (mode != 0) {        /* 320x240 */
 897                        reg_w_array(gspca_dev, bridge_start_ov965x_cif,
 898                                        ARRAY_SIZE(bridge_start_ov965x_cif));
 899                        sccb_w_array(gspca_dev, sensor_start_ov965x_cif,
 900                                        ARRAY_SIZE(sensor_start_ov965x_cif));
 901                } else {                /* 640x480 */
 902                        reg_w_array(gspca_dev, bridge_start_ov965x_vga,
 903                                        ARRAY_SIZE(bridge_start_ov965x_vga));
 904                        sccb_w_array(gspca_dev, sensor_start_ov965x_vga,
 905                                        ARRAY_SIZE(sensor_start_ov965x_vga));
 906                }
 907                sccb_w_array(gspca_dev, sensor_start_ov965x_2,
 908                                ARRAY_SIZE(sensor_start_ov965x_2));
 909                ov534_reg_write(gspca_dev, 0xe0, 0x00);
 910                ov534_reg_write(gspca_dev, 0xe0, 0x00);
 911                ov534_set_led(gspca_dev, 1);
 912        }
 913        return 0;
 914}
 915
 916static void sd_stopN(struct gspca_dev *gspca_dev)
 917{
 918        struct sd *sd = (struct sd *) gspca_dev;
 919
 920        switch (sd->sensor) {
 921        case SENSOR_OV772X:
 922                ov534_reg_write(gspca_dev, 0xe0, 0x09);
 923                ov534_set_led(gspca_dev, 0);
 924                break;
 925        default:
 926/*      case SENSOR_OV965X: */
 927                ov534_reg_write(gspca_dev, 0xe0, 0x01);
 928                ov534_set_led(gspca_dev, 0);
 929                ov534_reg_write(gspca_dev, 0xe0, 0x00);
 930                break;
 931        }
 932}
 933
 934/* Values for bmHeaderInfo (Video and Still Image Payload Headers, 2.4.3.3) */
 935#define UVC_STREAM_EOH  (1 << 7)
 936#define UVC_STREAM_ERR  (1 << 6)
 937#define UVC_STREAM_STI  (1 << 5)
 938#define UVC_STREAM_RES  (1 << 4)
 939#define UVC_STREAM_SCR  (1 << 3)
 940#define UVC_STREAM_PTS  (1 << 2)
 941#define UVC_STREAM_EOF  (1 << 1)
 942#define UVC_STREAM_FID  (1 << 0)
 943
 944static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame,
 945                        __u8 *data, int len)
 946{
 947        struct sd *sd = (struct sd *) gspca_dev;
 948        __u32 this_pts;
 949        u16 this_fid;
 950        int remaining_len = len;
 951        int payload_len;
 952
 953        payload_len = gspca_dev->cam.bulk ? 2048 : 2040;
 954        do {
 955                len = min(remaining_len, payload_len);
 956
 957                /* Payloads are prefixed with a UVC-style header.  We
 958                   consider a frame to start when the FID toggles, or the PTS
 959                   changes.  A frame ends when EOF is set, and we've received
 960                   the correct number of bytes. */
 961
 962                /* Verify UVC header.  Header length is always 12 */
 963                if (data[0] != 12 || len < 12) {
 964                        PDEBUG(D_PACK, "bad header");
 965                        goto discard;
 966                }
 967
 968                /* Check errors */
 969                if (data[1] & UVC_STREAM_ERR) {
 970                        PDEBUG(D_PACK, "payload error");
 971                        goto discard;
 972                }
 973
 974                /* Extract PTS and FID */
 975                if (!(data[1] & UVC_STREAM_PTS)) {
 976                        PDEBUG(D_PACK, "PTS not present");
 977                        goto discard;
 978                }
 979                this_pts = (data[5] << 24) | (data[4] << 16)
 980                                                | (data[3] << 8) | data[2];
 981                this_fid = (data[1] & UVC_STREAM_FID) ? 1 : 0;
 982
 983                /* If PTS or FID has changed, start a new frame. */
 984                if (this_pts != sd->last_pts || this_fid != sd->last_fid) {
 985                        if (gspca_dev->last_packet_type == INTER_PACKET)
 986                                frame = gspca_frame_add(gspca_dev,
 987                                                        LAST_PACKET, frame,
 988                                                        NULL, 0);
 989                        sd->last_pts = this_pts;
 990                        sd->last_fid = this_fid;
 991                        gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
 992                                        data + 12, len - 12);
 993                /* If this packet is marked as EOF, end the frame */
 994                } else if (data[1] & UVC_STREAM_EOF) {
 995                        sd->last_pts = 0;
 996                        frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
 997                                                data + 12, len - 12);
 998                } else {
 999
1000                        /* Add the data from this payload */
1001                        gspca_frame_add(gspca_dev, INTER_PACKET, frame,
1002                                                data + 12, len - 12);
1003                }
1004
1005
1006                /* Done this payload */
1007                goto scan_next;
1008
1009discard:
1010                /* Discard data until a new frame starts. */
1011                gspca_frame_add(gspca_dev, DISCARD_PACKET, frame, NULL, 0);
1012
1013scan_next:
1014                remaining_len -= len;
1015                data += len;
1016        } while (remaining_len > 0);
1017}
1018
1019/* get stream parameters (framerate) */
1020static int sd_get_streamparm(struct gspca_dev *gspca_dev,
1021                             struct v4l2_streamparm *parm)
1022{
1023        struct v4l2_captureparm *cp = &parm->parm.capture;
1024        struct v4l2_fract *tpf = &cp->timeperframe;
1025        struct sd *sd = (struct sd *) gspca_dev;
1026
1027        if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1028                return -EINVAL;
1029
1030        cp->capability |= V4L2_CAP_TIMEPERFRAME;
1031        tpf->numerator = 1;
1032        tpf->denominator = sd->frame_rate;
1033
1034        return 0;
1035}
1036
1037/* set stream parameters (framerate) */
1038static int sd_set_streamparm(struct gspca_dev *gspca_dev,
1039                             struct v4l2_streamparm *parm)
1040{
1041        struct v4l2_captureparm *cp = &parm->parm.capture;
1042        struct v4l2_fract *tpf = &cp->timeperframe;
1043        struct sd *sd = (struct sd *) gspca_dev;
1044
1045        if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1046                return -EINVAL;
1047
1048        /* Set requested framerate */
1049        sd->frame_rate = tpf->denominator / tpf->numerator;
1050        ov534_set_frame_rate(gspca_dev);
1051
1052        /* Return the actual framerate */
1053        tpf->numerator = 1;
1054        tpf->denominator = sd->frame_rate;
1055
1056        return 0;
1057}
1058
1059/* sub-driver description */
1060static const struct sd_desc sd_desc = {
1061        .name     = MODULE_NAME,
1062        .ctrls    = sd_ctrls,
1063        .nctrls   = ARRAY_SIZE(sd_ctrls),
1064        .config   = sd_config,
1065        .init     = sd_init,
1066        .start    = sd_start,
1067        .stopN    = sd_stopN,
1068        .pkt_scan = sd_pkt_scan,
1069        .get_streamparm = sd_get_streamparm,
1070        .set_streamparm = sd_set_streamparm,
1071};
1072
1073/* -- module initialisation -- */
1074static const __devinitdata struct usb_device_id device_table[] = {
1075        {USB_DEVICE(0x06f8, 0x3003), .driver_info = SENSOR_OV965X},
1076        {USB_DEVICE(0x1415, 0x2000), .driver_info = SENSOR_OV772X},
1077        {}
1078};
1079
1080MODULE_DEVICE_TABLE(usb, device_table);
1081
1082/* -- device connect -- */
1083static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id)
1084{
1085        return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1086                               THIS_MODULE);
1087}
1088
1089static struct usb_driver sd_driver = {
1090        .name       = MODULE_NAME,
1091        .id_table   = device_table,
1092        .probe      = sd_probe,
1093        .disconnect = gspca_disconnect,
1094#ifdef CONFIG_PM
1095        .suspend    = gspca_suspend,
1096        .resume     = gspca_resume,
1097#endif
1098};
1099
1100/* -- module insert / remove -- */
1101static int __init sd_mod_init(void)
1102{
1103        int ret;
1104        ret = usb_register(&sd_driver);
1105        if (ret < 0)
1106                return ret;
1107        PDEBUG(D_PROBE, "registered");
1108        return 0;
1109}
1110
1111static void __exit sd_mod_exit(void)
1112{
1113        usb_deregister(&sd_driver);
1114        PDEBUG(D_PROBE, "deregistered");
1115}
1116
1117module_init(sd_mod_init);
1118module_exit(sd_mod_exit);
1119
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.