linux/drivers/media/usb/gspca/sn9c20x.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 *      Sonix sn9c201 sn9c202 library
   4 *
   5 * Copyright (C) 2012 Jean-Francois Moine <http://moinejf.free.fr>
   6 *      Copyright (C) 2008-2009 microdia project <microdia@googlegroups.com>
   7 *      Copyright (C) 2009 Brian Johnson <brijohn@gmail.com>
   8 */
   9
  10#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  11
  12#include <linux/input.h>
  13
  14#include "gspca.h"
  15#include "jpeg.h"
  16
  17#include <linux/dmi.h>
  18
  19MODULE_AUTHOR("Brian Johnson <brijohn@gmail.com>, microdia project <microdia@googlegroups.com>");
  20MODULE_DESCRIPTION("GSPCA/SN9C20X USB Camera Driver");
  21MODULE_LICENSE("GPL");
  22
  23/*
  24 * Pixel format private data
  25 */
  26#define SCALE_MASK      0x0f
  27#define SCALE_160x120   0
  28#define SCALE_320x240   1
  29#define SCALE_640x480   2
  30#define SCALE_1280x1024 3
  31#define MODE_RAW        0x10
  32#define MODE_JPEG       0x20
  33#define MODE_SXGA       0x80
  34
  35#define SENSOR_OV9650   0
  36#define SENSOR_OV9655   1
  37#define SENSOR_SOI968   2
  38#define SENSOR_OV7660   3
  39#define SENSOR_OV7670   4
  40#define SENSOR_MT9V011  5
  41#define SENSOR_MT9V111  6
  42#define SENSOR_MT9V112  7
  43#define SENSOR_MT9M001  8
  44#define SENSOR_MT9M111  9
  45#define SENSOR_MT9M112  10
  46#define SENSOR_HV7131R  11
  47#define SENSOR_MT9VPRB  12
  48
  49/* camera flags */
  50#define HAS_NO_BUTTON   0x1
  51#define LED_REVERSE     0x2 /* some cameras unset gpio to turn on leds */
  52#define FLIP_DETECT     0x4
  53
  54/* specific webcam descriptor */
  55struct sd {
  56        struct gspca_dev gspca_dev;
  57
  58        struct { /* color control cluster */
  59                struct v4l2_ctrl *brightness;
  60                struct v4l2_ctrl *contrast;
  61                struct v4l2_ctrl *saturation;
  62                struct v4l2_ctrl *hue;
  63        };
  64        struct { /* blue/red balance control cluster */
  65                struct v4l2_ctrl *blue;
  66                struct v4l2_ctrl *red;
  67        };
  68        struct { /* h/vflip control cluster */
  69                struct v4l2_ctrl *hflip;
  70                struct v4l2_ctrl *vflip;
  71        };
  72        struct v4l2_ctrl *gamma;
  73        struct { /* autogain and exposure or gain control cluster */
  74                struct v4l2_ctrl *autogain;
  75                struct v4l2_ctrl *exposure;
  76                struct v4l2_ctrl *gain;
  77        };
  78        struct v4l2_ctrl *jpegqual;
  79
  80        struct work_struct work;
  81
  82        u32 pktsz;                      /* (used by pkt_scan) */
  83        u16 npkt;
  84        s8 nchg;
  85        u8 fmt;                         /* (used for JPEG QTAB update */
  86
  87#define MIN_AVG_LUM 80
  88#define MAX_AVG_LUM 130
  89        atomic_t avg_lum;
  90        u8 old_step;
  91        u8 older_step;
  92        u8 exposure_step;
  93
  94        u8 i2c_addr;
  95        u8 i2c_intf;
  96        u8 sensor;
  97        u8 hstart;
  98        u8 vstart;
  99
 100        u8 jpeg_hdr[JPEG_HDR_SZ];
 101
 102        u8 flags;
 103};
 104
 105static void qual_upd(struct work_struct *work);
 106
 107struct i2c_reg_u8 {
 108        u8 reg;
 109        u8 val;
 110};
 111
 112struct i2c_reg_u16 {
 113        u8 reg;
 114        u16 val;
 115};
 116
 117static const struct dmi_system_id flip_dmi_table[] = {
 118        {
 119                .ident = "MSI MS-1034",
 120                .matches = {
 121                        DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT'L CO.,LTD."),
 122                        DMI_MATCH(DMI_PRODUCT_NAME, "MS-1034"),
 123                        DMI_MATCH(DMI_PRODUCT_VERSION, "0341")
 124                }
 125        },
 126        {
 127                .ident = "MSI MS-1632",
 128                .matches = {
 129                        DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
 130                        DMI_MATCH(DMI_BOARD_NAME, "MS-1632")
 131                }
 132        },
 133        {
 134                .ident = "MSI MS-1633X",
 135                .matches = {
 136                        DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
 137                        DMI_MATCH(DMI_BOARD_NAME, "MS-1633X")
 138                }
 139        },
 140        {
 141                .ident = "MSI MS-1635X",
 142                .matches = {
 143                        DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
 144                        DMI_MATCH(DMI_BOARD_NAME, "MS-1635X")
 145                }
 146        },
 147        {
 148                .ident = "ASUSTeK W7J",
 149                .matches = {
 150                        DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc."),
 151                        DMI_MATCH(DMI_BOARD_NAME, "W7J       ")
 152                }
 153        },
 154        {}
 155};
 156
 157static const struct v4l2_pix_format vga_mode[] = {
 158        {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
 159                .bytesperline = 160,
 160                .sizeimage = 160 * 120 * 4 / 8 + 590,
 161                .colorspace = V4L2_COLORSPACE_JPEG,
 162                .priv = SCALE_160x120 | MODE_JPEG},
 163        {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
 164                .bytesperline = 160,
 165                .sizeimage = 160 * 120,
 166                .colorspace = V4L2_COLORSPACE_SRGB,
 167                .priv = SCALE_160x120 | MODE_RAW},
 168        {160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
 169                .bytesperline = 160,
 170                .sizeimage = 240 * 120,
 171                .colorspace = V4L2_COLORSPACE_SRGB,
 172                .priv = SCALE_160x120},
 173        {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
 174                .bytesperline = 320,
 175                .sizeimage = 320 * 240 * 4 / 8 + 590,
 176                .colorspace = V4L2_COLORSPACE_JPEG,
 177                .priv = SCALE_320x240 | MODE_JPEG},
 178        {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
 179                .bytesperline = 320,
 180                .sizeimage = 320 * 240 ,
 181                .colorspace = V4L2_COLORSPACE_SRGB,
 182                .priv = SCALE_320x240 | MODE_RAW},
 183        {320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
 184                .bytesperline = 320,
 185                .sizeimage = 480 * 240 ,
 186                .colorspace = V4L2_COLORSPACE_SRGB,
 187                .priv = SCALE_320x240},
 188        {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
 189                .bytesperline = 640,
 190                .sizeimage = 640 * 480 * 4 / 8 + 590,
 191                .colorspace = V4L2_COLORSPACE_JPEG,
 192                .priv = SCALE_640x480 | MODE_JPEG},
 193        {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
 194                .bytesperline = 640,
 195                .sizeimage = 640 * 480,
 196                .colorspace = V4L2_COLORSPACE_SRGB,
 197                .priv = SCALE_640x480 | MODE_RAW},
 198        {640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
 199                .bytesperline = 640,
 200                .sizeimage = 960 * 480,
 201                .colorspace = V4L2_COLORSPACE_SRGB,
 202                .priv = SCALE_640x480},
 203};
 204
 205static const struct v4l2_pix_format sxga_mode[] = {
 206        {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
 207                .bytesperline = 160,
 208                .sizeimage = 160 * 120 * 4 / 8 + 590,
 209                .colorspace = V4L2_COLORSPACE_JPEG,
 210                .priv = SCALE_160x120 | MODE_JPEG},
 211        {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
 212                .bytesperline = 160,
 213                .sizeimage = 160 * 120,
 214                .colorspace = V4L2_COLORSPACE_SRGB,
 215                .priv = SCALE_160x120 | MODE_RAW},
 216        {160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
 217                .bytesperline = 160,
 218                .sizeimage = 240 * 120,
 219                .colorspace = V4L2_COLORSPACE_SRGB,
 220                .priv = SCALE_160x120},
 221        {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
 222                .bytesperline = 320,
 223                .sizeimage = 320 * 240 * 4 / 8 + 590,
 224                .colorspace = V4L2_COLORSPACE_JPEG,
 225                .priv = SCALE_320x240 | MODE_JPEG},
 226        {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
 227                .bytesperline = 320,
 228                .sizeimage = 320 * 240 ,
 229                .colorspace = V4L2_COLORSPACE_SRGB,
 230                .priv = SCALE_320x240 | MODE_RAW},
 231        {320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
 232                .bytesperline = 320,
 233                .sizeimage = 480 * 240 ,
 234                .colorspace = V4L2_COLORSPACE_SRGB,
 235                .priv = SCALE_320x240},
 236        {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
 237                .bytesperline = 640,
 238                .sizeimage = 640 * 480 * 4 / 8 + 590,
 239                .colorspace = V4L2_COLORSPACE_JPEG,
 240                .priv = SCALE_640x480 | MODE_JPEG},
 241        {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
 242                .bytesperline = 640,
 243                .sizeimage = 640 * 480,
 244                .colorspace = V4L2_COLORSPACE_SRGB,
 245                .priv = SCALE_640x480 | MODE_RAW},
 246        {640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
 247                .bytesperline = 640,
 248                .sizeimage = 960 * 480,
 249                .colorspace = V4L2_COLORSPACE_SRGB,
 250                .priv = SCALE_640x480},
 251        {1280, 1024, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
 252                .bytesperline = 1280,
 253                .sizeimage = 1280 * 1024,
 254                .colorspace = V4L2_COLORSPACE_SRGB,
 255                .priv = SCALE_1280x1024 | MODE_RAW | MODE_SXGA},
 256};
 257
 258static const struct v4l2_pix_format mono_mode[] = {
 259        {160, 120, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
 260                .bytesperline = 160,
 261                .sizeimage = 160 * 120,
 262                .colorspace = V4L2_COLORSPACE_SRGB,
 263                .priv = SCALE_160x120 | MODE_RAW},
 264        {320, 240, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
 265                .bytesperline = 320,
 266                .sizeimage = 320 * 240 ,
 267                .colorspace = V4L2_COLORSPACE_SRGB,
 268                .priv = SCALE_320x240 | MODE_RAW},
 269        {640, 480, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
 270                .bytesperline = 640,
 271                .sizeimage = 640 * 480,
 272                .colorspace = V4L2_COLORSPACE_SRGB,
 273                .priv = SCALE_640x480 | MODE_RAW},
 274        {1280, 1024, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
 275                .bytesperline = 1280,
 276                .sizeimage = 1280 * 1024,
 277                .colorspace = V4L2_COLORSPACE_SRGB,
 278                .priv = SCALE_1280x1024 | MODE_RAW | MODE_SXGA},
 279};
 280
 281static const s16 hsv_red_x[] = {
 282        41,  44,  46,  48,  50,  52,  54,  56,
 283        58,  60,  62,  64,  66,  68,  70,  72,
 284        74,  76,  78,  80,  81,  83,  85,  87,
 285        88,  90,  92,  93,  95,  97,  98, 100,
 286        101, 102, 104, 105, 107, 108, 109, 110,
 287        112, 113, 114, 115, 116, 117, 118, 119,
 288        120, 121, 122, 123, 123, 124, 125, 125,
 289        126, 127, 127, 128, 128, 129, 129, 129,
 290        130, 130, 130, 130, 131, 131, 131, 131,
 291        131, 131, 131, 131, 130, 130, 130, 130,
 292        129, 129, 129, 128, 128, 127, 127, 126,
 293        125, 125, 124, 123, 122, 122, 121, 120,
 294        119, 118, 117, 116, 115, 114, 112, 111,
 295        110, 109, 107, 106, 105, 103, 102, 101,
 296        99,  98,  96,  94,  93,  91,  90,  88,
 297        86,  84,  83,  81,  79,  77,  75,  74,
 298        72,  70,  68,  66,  64,  62,  60,  58,
 299        56,  54,  52,  49,  47,  45,  43,  41,
 300        39,  36,  34,  32,  30,  28,  25,  23,
 301        21,  19,  16,  14,  12,   9,   7,   5,
 302        3,   0,  -1,  -3,  -6,  -8, -10, -12,
 303        -15, -17, -19, -22, -24, -26, -28, -30,
 304        -33, -35, -37, -39, -41, -44, -46, -48,
 305        -50, -52, -54, -56, -58, -60, -62, -64,
 306        -66, -68, -70, -72, -74, -76, -78, -80,
 307        -81, -83, -85, -87, -88, -90, -92, -93,
 308        -95, -97, -98, -100, -101, -102, -104, -105,
 309        -107, -108, -109, -110, -112, -113, -114, -115,
 310        -116, -117, -118, -119, -120, -121, -122, -123,
 311        -123, -124, -125, -125, -126, -127, -127, -128,
 312        -128, -128, -128, -128, -128, -128, -128, -128,
 313        -128, -128, -128, -128, -128, -128, -128, -128,
 314        -128, -128, -128, -128, -128, -128, -128, -128,
 315        -128, -127, -127, -126, -125, -125, -124, -123,
 316        -122, -122, -121, -120, -119, -118, -117, -116,
 317        -115, -114, -112, -111, -110, -109, -107, -106,
 318        -105, -103, -102, -101, -99, -98, -96, -94,
 319        -93, -91, -90, -88, -86, -84, -83, -81,
 320        -79, -77, -75, -74, -72, -70, -68, -66,
 321        -64, -62, -60, -58, -56, -54, -52, -49,
 322        -47, -45, -43, -41, -39, -36, -34, -32,
 323        -30, -28, -25, -23, -21, -19, -16, -14,
 324        -12,  -9,  -7,  -5,  -3,   0,   1,   3,
 325        6,   8,  10,  12,  15,  17,  19,  22,
 326        24,  26,  28,  30,  33,  35,  37,  39, 41
 327};
 328
 329static const s16 hsv_red_y[] = {
 330        82,  80,  78,  76,  74,  73,  71,  69,
 331        67,  65,  63,  61,  58,  56,  54,  52,
 332        50,  48,  46,  44,  41,  39,  37,  35,
 333        32,  30,  28,  26,  23,  21,  19,  16,
 334        14,  12,  10,   7,   5,   3,   0,  -1,
 335        -3,  -6,  -8, -10, -13, -15, -17, -19,
 336        -22, -24, -26, -29, -31, -33, -35, -38,
 337        -40, -42, -44, -46, -48, -51, -53, -55,
 338        -57, -59, -61, -63, -65, -67, -69, -71,
 339        -73, -75, -77, -79, -81, -82, -84, -86,
 340        -88, -89, -91, -93, -94, -96, -98, -99,
 341        -101, -102, -104, -105, -106, -108, -109, -110,
 342        -112, -113, -114, -115, -116, -117, -119, -120,
 343        -120, -121, -122, -123, -124, -125, -126, -126,
 344        -127, -128, -128, -128, -128, -128, -128, -128,
 345        -128, -128, -128, -128, -128, -128, -128, -128,
 346        -128, -128, -128, -128, -128, -128, -128, -128,
 347        -128, -128, -128, -128, -128, -128, -128, -128,
 348        -127, -127, -126, -125, -125, -124, -123, -122,
 349        -121, -120, -119, -118, -117, -116, -115, -114,
 350        -113, -111, -110, -109, -107, -106, -105, -103,
 351        -102, -100, -99, -97, -96, -94, -92, -91,
 352        -89, -87, -85, -84, -82, -80, -78, -76,
 353        -74, -73, -71, -69, -67, -65, -63, -61,
 354        -58, -56, -54, -52, -50, -48, -46, -44,
 355        -41, -39, -37, -35, -32, -30, -28, -26,
 356        -23, -21, -19, -16, -14, -12, -10,  -7,
 357        -5,  -3,   0,   1,   3,   6,   8,  10,
 358        13,  15,  17,  19,  22,  24,  26,  29,
 359        31,  33,  35,  38,  40,  42,  44,  46,
 360        48,  51,  53,  55,  57,  59,  61,  63,
 361        65,  67,  69,  71,  73,  75,  77,  79,
 362        81,  82,  84,  86,  88,  89,  91,  93,
 363        94,  96,  98,  99, 101, 102, 104, 105,
 364        106, 108, 109, 110, 112, 113, 114, 115,
 365        116, 117, 119, 120, 120, 121, 122, 123,
 366        124, 125, 126, 126, 127, 128, 128, 129,
 367        129, 130, 130, 131, 131, 131, 131, 132,
 368        132, 132, 132, 132, 132, 132, 132, 132,
 369        132, 132, 132, 131, 131, 131, 130, 130,
 370        130, 129, 129, 128, 127, 127, 126, 125,
 371        125, 124, 123, 122, 121, 120, 119, 118,
 372        117, 116, 115, 114, 113, 111, 110, 109,
 373        107, 106, 105, 103, 102, 100,  99,  97,
 374        96, 94, 92, 91, 89, 87, 85, 84, 82
 375};
 376
 377static const s16 hsv_green_x[] = {
 378        -124, -124, -125, -125, -125, -125, -125, -125,
 379        -125, -126, -126, -125, -125, -125, -125, -125,
 380        -125, -124, -124, -124, -123, -123, -122, -122,
 381        -121, -121, -120, -120, -119, -118, -117, -117,
 382        -116, -115, -114, -113, -112, -111, -110, -109,
 383        -108, -107, -105, -104, -103, -102, -100, -99,
 384        -98, -96, -95, -93, -92, -91, -89, -87,
 385        -86, -84, -83, -81, -79, -77, -76, -74,
 386        -72, -70, -69, -67, -65, -63, -61, -59,
 387        -57, -55, -53, -51, -49, -47, -45, -43,
 388        -41, -39, -37, -35, -33, -30, -28, -26,
 389        -24, -22, -20, -18, -15, -13, -11,  -9,
 390        -7,  -4,  -2,   0,   1,   3,   6,   8,
 391        10,  12,  14,  17,  19,  21,  23,  25,
 392        27,  29,  32,  34,  36,  38,  40,  42,
 393        44,  46,  48,  50,  52,  54,  56,  58,
 394        60,  62,  64,  66,  68,  70,  71,  73,
 395        75,  77,  78,  80,  82,  83,  85,  87,
 396        88,  90,  91,  93,  94,  96,  97,  98,
 397        100, 101, 102, 104, 105, 106, 107, 108,
 398        109, 111, 112, 113, 113, 114, 115, 116,
 399        117, 118, 118, 119, 120, 120, 121, 122,
 400        122, 123, 123, 124, 124, 124, 125, 125,
 401        125, 125, 125, 125, 125, 126, 126, 125,
 402        125, 125, 125, 125, 125, 124, 124, 124,
 403        123, 123, 122, 122, 121, 121, 120, 120,
 404        119, 118, 117, 117, 116, 115, 114, 113,
 405        112, 111, 110, 109, 108, 107, 105, 104,
 406        103, 102, 100,  99,  98,  96,  95,  93,
 407        92,  91,  89,  87,  86,  84,  83,  81,
 408        79,  77,  76,  74,  72,  70,  69,  67,
 409        65,  63,  61,  59,  57,  55,  53,  51,
 410        49,  47,  45,  43,  41,  39,  37,  35,
 411        33,  30,  28,  26,  24,  22,  20,  18,
 412        15,  13,  11,   9,   7,   4,   2,   0,
 413        -1,  -3,  -6,  -8, -10, -12, -14, -17,
 414        -19, -21, -23, -25, -27, -29, -32, -34,
 415        -36, -38, -40, -42, -44, -46, -48, -50,
 416        -52, -54, -56, -58, -60, -62, -64, -66,
 417        -68, -70, -71, -73, -75, -77, -78, -80,
 418        -82, -83, -85, -87, -88, -90, -91, -93,
 419        -94, -96, -97, -98, -100, -101, -102, -104,
 420        -105, -106, -107, -108, -109, -111, -112, -113,
 421        -113, -114, -115, -116, -117, -118, -118, -119,
 422        -120, -120, -121, -122, -122, -123, -123, -124, -124
 423};
 424
 425static const s16 hsv_green_y[] = {
 426        -100, -99, -98, -97, -95, -94, -93, -91,
 427        -90, -89, -87, -86, -84, -83, -81, -80,
 428        -78, -76, -75, -73, -71, -70, -68, -66,
 429        -64, -63, -61, -59, -57, -55, -53, -51,
 430        -49, -48, -46, -44, -42, -40, -38, -36,
 431        -34, -32, -30, -27, -25, -23, -21, -19,
 432        -17, -15, -13, -11,  -9,  -7,  -4,  -2,
 433        0,   1,   3,   5,   7,   9,  11,  14,
 434        16,  18,  20,  22,  24,  26,  28,  30,
 435        32,  34,  36,  38,  40,  42,  44,  46,
 436        48,  50,  52,  54,  56,  58,  59,  61,
 437        63,  65,  67,  68,  70,  72,  74,  75,
 438        77,  78,  80,  82,  83,  85,  86,  88,
 439        89,  90,  92,  93,  95,  96,  97,  98,
 440        100, 101, 102, 103, 104, 105, 106, 107,
 441        108, 109, 110, 111, 112, 112, 113, 114,
 442        115, 115, 116, 116, 117, 117, 118, 118,
 443        119, 119, 119, 120, 120, 120, 120, 120,
 444        121, 121, 121, 121, 121, 121, 120, 120,
 445        120, 120, 120, 119, 119, 119, 118, 118,
 446        117, 117, 116, 116, 115, 114, 114, 113,
 447        112, 111, 111, 110, 109, 108, 107, 106,
 448        105, 104, 103, 102, 100,  99,  98,  97,
 449        95,  94,  93,  91,  90,  89,  87,  86,
 450        84,  83,  81,  80,  78,  76,  75,  73,
 451        71,  70,  68,  66,  64,  63,  61,  59,
 452        57,  55,  53,  51,  49,  48,  46,  44,
 453        42,  40,  38,  36,  34,  32,  30,  27,
 454        25,  23,  21,  19,  17,  15,  13,  11,
 455        9,   7,   4,   2,   0,  -1,  -3,  -5,
 456        -7,  -9, -11, -14, -16, -18, -20, -22,
 457        -24, -26, -28, -30, -32, -34, -36, -38,
 458        -40, -42, -44, -46, -48, -50, -52, -54,
 459        -56, -58, -59, -61, -63, -65, -67, -68,
 460        -70, -72, -74, -75, -77, -78, -80, -82,
 461        -83, -85, -86, -88, -89, -90, -92, -93,
 462        -95, -96, -97, -98, -100, -101, -102, -103,
 463        -104, -105, -106, -107, -108, -109, -110, -111,
 464        -112, -112, -113, -114, -115, -115, -116, -116,
 465        -117, -117, -118, -118, -119, -119, -119, -120,
 466        -120, -120, -120, -120, -121, -121, -121, -121,
 467        -121, -121, -120, -120, -120, -120, -120, -119,
 468        -119, -119, -118, -118, -117, -117, -116, -116,
 469        -115, -114, -114, -113, -112, -111, -111, -110,
 470        -109, -108, -107, -106, -105, -104, -103, -102, -100
 471};
 472
 473static const s16 hsv_blue_x[] = {
 474        112, 113, 114, 114, 115, 116, 117, 117,
 475        118, 118, 119, 119, 120, 120, 120, 121,
 476        121, 121, 122, 122, 122, 122, 122, 122,
 477        122, 122, 122, 122, 122, 122, 121, 121,
 478        121, 120, 120, 120, 119, 119, 118, 118,
 479        117, 116, 116, 115, 114, 113, 113, 112,
 480        111, 110, 109, 108, 107, 106, 105, 104,
 481        103, 102, 100,  99,  98,  97,  95,  94,
 482        93,  91,  90,  88,  87,  85,  84,  82,
 483        80,  79,  77,  76,  74,  72,  70,  69,
 484        67,  65,  63,  61,  60,  58,  56,  54,
 485        52,  50,  48,  46,  44,  42,  40,  38,
 486        36,  34,  32,  30,  28,  26,  24,  22,
 487        19,  17,  15,  13,  11,   9,   7,   5,
 488        2,   0,  -1,  -3,  -5,  -7,  -9, -12,
 489        -14, -16, -18, -20, -22, -24, -26, -28,
 490        -31, -33, -35, -37, -39, -41, -43, -45,
 491        -47, -49, -51, -53, -54, -56, -58, -60,
 492        -62, -64, -66, -67, -69, -71, -73, -74,
 493        -76, -78, -79, -81, -83, -84, -86, -87,
 494        -89, -90, -92, -93, -94, -96, -97, -98,
 495        -99, -101, -102, -103, -104, -105, -106, -107,
 496        -108, -109, -110, -111, -112, -113, -114, -114,
 497        -115, -116, -117, -117, -118, -118, -119, -119,
 498        -120, -120, -120, -121, -121, -121, -122, -122,
 499        -122, -122, -122, -122, -122, -122, -122, -122,
 500        -122, -122, -121, -121, -121, -120, -120, -120,
 501        -119, -119, -118, -118, -117, -116, -116, -115,
 502        -114, -113, -113, -112, -111, -110, -109, -108,
 503        -107, -106, -105, -104, -103, -102, -100, -99,
 504        -98, -97, -95, -94, -93, -91, -90, -88,
 505        -87, -85, -84, -82, -80, -79, -77, -76,
 506        -74, -72, -70, -69, -67, -65, -63, -61,
 507        -60, -58, -56, -54, -52, -50, -48, -46,
 508        -44, -42, -40, -38, -36, -34, -32, -30,
 509        -28, -26, -24, -22, -19, -17, -15, -13,
 510        -11,  -9,  -7,  -5,  -2,   0,   1,   3,
 511        5,   7,   9,  12,  14,  16,  18,  20,
 512        22,  24,  26,  28,  31,  33,  35,  37,
 513        39,  41,  43,  45,  47,  49,  51,  53,
 514        54,  56,  58,  60,  62,  64,  66,  67,
 515        69,  71,  73,  74,  76,  78,  79,  81,
 516        83,  84,  86,  87,  89,  90,  92,  93,
 517        94,  96,  97,  98,  99, 101, 102, 103,
 518        104, 105, 106, 107, 108, 109, 110, 111, 112
 519};
 520
 521static const s16 hsv_blue_y[] = {
 522        -11, -13, -15, -17, -19, -21, -23, -25,
 523        -27, -29, -31, -33, -35, -37, -39, -41,
 524        -43, -45, -46, -48, -50, -52, -54, -55,
 525        -57, -59, -61, -62, -64, -66, -67, -69,
 526        -71, -72, -74, -75, -77, -78, -80, -81,
 527        -83, -84, -86, -87, -88, -90, -91, -92,
 528        -93, -95, -96, -97, -98, -99, -100, -101,
 529        -102, -103, -104, -105, -106, -106, -107, -108,
 530        -109, -109, -110, -111, -111, -112, -112, -113,
 531        -113, -114, -114, -114, -115, -115, -115, -115,
 532        -116, -116, -116, -116, -116, -116, -116, -116,
 533        -116, -115, -115, -115, -115, -114, -114, -114,
 534        -113, -113, -112, -112, -111, -111, -110, -110,
 535        -109, -108, -108, -107, -106, -105, -104, -103,
 536        -102, -101, -100, -99, -98, -97, -96, -95,
 537        -94, -93, -91, -90, -89, -88, -86, -85,
 538        -84, -82, -81, -79, -78, -76, -75, -73,
 539        -71, -70, -68, -67, -65, -63, -62, -60,
 540        -58, -56, -55, -53, -51, -49, -47, -45,
 541        -44, -42, -40, -38, -36, -34, -32, -30,
 542        -28, -26, -24, -22, -20, -18, -16, -14,
 543        -12, -10,  -8,  -6,  -4,  -2,   0,   1,
 544        3,   5,   7,   9,  11,  13,  15,  17,
 545        19,  21,  23,  25,  27,  29,  31,  33,
 546        35,  37,  39,  41,  43,  45,  46,  48,
 547        50,  52,  54,  55,  57,  59,  61,  62,
 548        64,  66,  67,  69,  71,  72,  74,  75,
 549        77,  78,  80,  81,  83,  84,  86,  87,
 550        88,  90,  91,  92,  93,  95,  96,  97,
 551        98,  99, 100, 101, 102, 103, 104, 105,
 552        106, 106, 107, 108, 109, 109, 110, 111,
 553        111, 112, 112, 113, 113, 114, 114, 114,
 554        115, 115, 115, 115, 116, 116, 116, 116,
 555        116, 116, 116, 116, 116, 115, 115, 115,
 556        115, 114, 114, 114, 113, 113, 112, 112,
 557        111, 111, 110, 110, 109, 108, 108, 107,
 558        106, 105, 104, 103, 102, 101, 100,  99,
 559        98,  97,  96,  95,  94,  93,  91,  90,
 560        89,  88,  86,  85,  84,  82,  81,  79,
 561        78,  76,  75,  73,  71,  70,  68,  67,
 562        65,  63,  62,  60,  58,  56,  55,  53,
 563        51,  49,  47,  45,  44,  42,  40,  38,
 564        36,  34,  32,  30,  28,  26,  24,  22,
 565        20,  18,  16,  14,  12,  10,   8,   6,
 566        4,   2,   0,  -1,  -3,  -5,  -7,  -9, -11
 567};
 568
 569static const u16 bridge_init[][2] = {
 570        {0x1000, 0x78}, {0x1001, 0x40}, {0x1002, 0x1c},
 571        {0x1020, 0x80}, {0x1061, 0x01}, {0x1067, 0x40},
 572        {0x1068, 0x30}, {0x1069, 0x20}, {0x106a, 0x10},
 573        {0x106b, 0x08}, {0x1188, 0x87}, {0x11a1, 0x00},
 574        {0x11a2, 0x00}, {0x11a3, 0x6a}, {0x11a4, 0x50},
 575        {0x11ab, 0x00}, {0x11ac, 0x00}, {0x11ad, 0x50},
 576        {0x11ae, 0x3c}, {0x118a, 0x04}, {0x0395, 0x04},
 577        {0x11b8, 0x3a}, {0x118b, 0x0e}, {0x10f7, 0x05},
 578        {0x10f8, 0x14}, {0x10fa, 0xff}, {0x10f9, 0x00},
 579        {0x11ba, 0x0a}, {0x11a5, 0x2d}, {0x11a6, 0x2d},
 580        {0x11a7, 0x3a}, {0x11a8, 0x05}, {0x11a9, 0x04},
 581        {0x11aa, 0x3f}, {0x11af, 0x28}, {0x11b0, 0xd8},
 582        {0x11b1, 0x14}, {0x11b2, 0xec}, {0x11b3, 0x32},
 583        {0x11b4, 0xdd}, {0x11b5, 0x32}, {0x11b6, 0xdd},
 584        {0x10e0, 0x2c}, {0x11bc, 0x40}, {0x11bd, 0x01},
 585        {0x11be, 0xf0}, {0x11bf, 0x00}, {0x118c, 0x1f},
 586        {0x118d, 0x1f}, {0x118e, 0x1f}, {0x118f, 0x1f},
 587        {0x1180, 0x01}, {0x1181, 0x00}, {0x1182, 0x01},
 588        {0x1183, 0x00}, {0x1184, 0x50}, {0x1185, 0x80},
 589        {0x1007, 0x00}
 590};
 591
 592/* Gain = (bit[3:0] / 16 + 1) * (bit[4] + 1) * (bit[5] + 1) * (bit[6] + 1) */
 593static const u8 ov_gain[] = {
 594        0x00 /* 1x */, 0x04 /* 1.25x */, 0x08 /* 1.5x */, 0x0c /* 1.75x */,
 595        0x10 /* 2x */, 0x12 /* 2.25x */, 0x14 /* 2.5x */, 0x16 /* 2.75x */,
 596        0x18 /* 3x */, 0x1a /* 3.25x */, 0x1c /* 3.5x */, 0x1e /* 3.75x */,
 597        0x30 /* 4x */, 0x31 /* 4.25x */, 0x32 /* 4.5x */, 0x33 /* 4.75x */,
 598        0x34 /* 5x */, 0x35 /* 5.25x */, 0x36 /* 5.5x */, 0x37 /* 5.75x */,
 599        0x38 /* 6x */, 0x39 /* 6.25x */, 0x3a /* 6.5x */, 0x3b /* 6.75x */,
 600        0x3c /* 7x */, 0x3d /* 7.25x */, 0x3e /* 7.5x */, 0x3f /* 7.75x */,
 601        0x70 /* 8x */
 602};
 603
 604/* Gain = (bit[8] + 1) * (bit[7] + 1) * (bit[6:0] * 0.03125) */
 605static const u16 micron1_gain[] = {
 606        /* 1x   1.25x   1.5x    1.75x */
 607        0x0020, 0x0028, 0x0030, 0x0038,
 608        /* 2x   2.25x   2.5x    2.75x */
 609        0x00a0, 0x00a4, 0x00a8, 0x00ac,
 610        /* 3x   3.25x   3.5x    3.75x */
 611        0x00b0, 0x00b4, 0x00b8, 0x00bc,
 612        /* 4x   4.25x   4.5x    4.75x */
 613        0x00c0, 0x00c4, 0x00c8, 0x00cc,
 614        /* 5x   5.25x   5.5x    5.75x */
 615        0x00d0, 0x00d4, 0x00d8, 0x00dc,
 616        /* 6x   6.25x   6.5x    6.75x */
 617        0x00e0, 0x00e4, 0x00e8, 0x00ec,
 618        /* 7x   7.25x   7.5x    7.75x */
 619        0x00f0, 0x00f4, 0x00f8, 0x00fc,
 620        /* 8x */
 621        0x01c0
 622};
 623
 624/* mt9m001 sensor uses a different gain formula then other micron sensors */
 625/* Gain = (bit[6] + 1) * (bit[5-0] * 0.125) */
 626static const u16 micron2_gain[] = {
 627        /* 1x   1.25x   1.5x    1.75x */
 628        0x0008, 0x000a, 0x000c, 0x000e,
 629        /* 2x   2.25x   2.5x    2.75x */
 630        0x0010, 0x0012, 0x0014, 0x0016,
 631        /* 3x   3.25x   3.5x    3.75x */
 632        0x0018, 0x001a, 0x001c, 0x001e,
 633        /* 4x   4.25x   4.5x    4.75x */
 634        0x0020, 0x0051, 0x0052, 0x0053,
 635        /* 5x   5.25x   5.5x    5.75x */
 636        0x0054, 0x0055, 0x0056, 0x0057,
 637        /* 6x   6.25x   6.5x    6.75x */
 638        0x0058, 0x0059, 0x005a, 0x005b,
 639        /* 7x   7.25x   7.5x    7.75x */
 640        0x005c, 0x005d, 0x005e, 0x005f,
 641        /* 8x */
 642        0x0060
 643};
 644
 645/* Gain = .5 + bit[7:0] / 16 */
 646static const u8 hv7131r_gain[] = {
 647        0x08 /* 1x */, 0x0c /* 1.25x */, 0x10 /* 1.5x */, 0x14 /* 1.75x */,
 648        0x18 /* 2x */, 0x1c /* 2.25x */, 0x20 /* 2.5x */, 0x24 /* 2.75x */,
 649        0x28 /* 3x */, 0x2c /* 3.25x */, 0x30 /* 3.5x */, 0x34 /* 3.75x */,
 650        0x38 /* 4x */, 0x3c /* 4.25x */, 0x40 /* 4.5x */, 0x44 /* 4.75x */,
 651        0x48 /* 5x */, 0x4c /* 5.25x */, 0x50 /* 5.5x */, 0x54 /* 5.75x */,
 652        0x58 /* 6x */, 0x5c /* 6.25x */, 0x60 /* 6.5x */, 0x64 /* 6.75x */,
 653        0x68 /* 7x */, 0x6c /* 7.25x */, 0x70 /* 7.5x */, 0x74 /* 7.75x */,
 654        0x78 /* 8x */
 655};
 656
 657static const struct i2c_reg_u8 soi968_init[] = {
 658        {0x0c, 0x00}, {0x0f, 0x1f},
 659        {0x11, 0x80}, {0x38, 0x52}, {0x1e, 0x00},
 660        {0x33, 0x08}, {0x35, 0x8c}, {0x36, 0x0c},
 661        {0x37, 0x04}, {0x45, 0x04}, {0x47, 0xff},
 662        {0x3e, 0x00}, {0x3f, 0x00}, {0x3b, 0x20},
 663        {0x3a, 0x96}, {0x3d, 0x0a}, {0x14, 0x8e},
 664        {0x13, 0x8b}, {0x12, 0x40}, {0x17, 0x13},
 665        {0x18, 0x63}, {0x19, 0x01}, {0x1a, 0x79},
 666        {0x32, 0x24}, {0x03, 0x00}, {0x11, 0x40},
 667        {0x2a, 0x10}, {0x2b, 0xe0}, {0x10, 0x32},
 668        {0x00, 0x00}, {0x01, 0x80}, {0x02, 0x80},
 669};
 670
 671static const struct i2c_reg_u8 ov7660_init[] = {
 672        {0x0e, 0x80}, {0x0d, 0x08}, {0x0f, 0xc3},
 673        {0x04, 0xc3}, {0x10, 0x40}, {0x11, 0x40},
 674        {0x12, 0x05}, {0x13, 0xba}, {0x14, 0x2a},
 675        /* HDG Set hstart and hstop, datasheet default 0x11, 0x61, using
 676           0x10, 0x61 and sd->hstart, vstart = 3, fixes ugly colored borders */
 677        {0x17, 0x10}, {0x18, 0x61},
 678        {0x37, 0x0f}, {0x38, 0x02}, {0x39, 0x43},
 679        {0x3a, 0x00}, {0x69, 0x90}, {0x2d, 0x00},
 680        {0x2e, 0x00}, {0x01, 0x78}, {0x02, 0x50},
 681};
 682
 683static const struct i2c_reg_u8 ov7670_init[] = {
 684        {0x11, 0x80}, {0x3a, 0x04}, {0x12, 0x01},
 685        {0x32, 0xb6}, {0x03, 0x0a}, {0x0c, 0x00}, {0x3e, 0x00},
 686        {0x70, 0x3a}, {0x71, 0x35}, {0x72, 0x11}, {0x73, 0xf0},
 687        {0xa2, 0x02}, {0x13, 0xe0}, {0x00, 0x00}, {0x10, 0x00},
 688        {0x0d, 0x40}, {0x14, 0x28}, {0xa5, 0x05}, {0xab, 0x07},
 689        {0x24, 0x95}, {0x25, 0x33}, {0x26, 0xe3}, {0x9f, 0x75},
 690        {0xa0, 0x65}, {0xa1, 0x0b}, {0xa6, 0xd8}, {0xa7, 0xd8},
 691        {0xa8, 0xf0}, {0xa9, 0x90}, {0xaa, 0x94}, {0x13, 0xe5},
 692        {0x0e, 0x61}, {0x0f, 0x4b}, {0x16, 0x02}, {0x1e, 0x27},
 693        {0x21, 0x02}, {0x22, 0x91}, {0x29, 0x07}, {0x33, 0x0b},
 694        {0x35, 0x0b}, {0x37, 0x1d}, {0x38, 0x71}, {0x39, 0x2a},
 695        {0x3c, 0x78}, {0x4d, 0x40}, {0x4e, 0x20}, {0x69, 0x00},
 696        {0x74, 0x19}, {0x8d, 0x4f}, {0x8e, 0x00}, {0x8f, 0x00},
 697        {0x90, 0x00}, {0x91, 0x00}, {0x96, 0x00}, {0x9a, 0x80},
 698        {0xb0, 0x84}, {0xb1, 0x0c}, {0xb2, 0x0e}, {0xb3, 0x82},
 699        {0xb8, 0x0a}, {0x43, 0x0a}, {0x44, 0xf0}, {0x45, 0x20},
 700        {0x46, 0x7d}, {0x47, 0x29}, {0x48, 0x4a}, {0x59, 0x8c},
 701        {0x5a, 0xa5}, {0x5b, 0xde}, {0x5c, 0x96}, {0x5d, 0x66},
 702        {0x5e, 0x10}, {0x6c, 0x0a}, {0x6d, 0x55}, {0x6e, 0x11},
 703        {0x6f, 0x9e}, {0x6a, 0x40}, {0x01, 0x40}, {0x02, 0x40},
 704        {0x13, 0xe7}, {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x02},
 705        {0x52, 0x1d}, {0x53, 0x56}, {0x54, 0x73}, {0x55, 0x0a},
 706        {0x56, 0x55}, {0x57, 0x80}, {0x58, 0x9e}, {0x41, 0x08},
 707        {0x3f, 0x02}, {0x75, 0x03}, {0x76, 0x63}, {0x4c, 0x04},
 708        {0x77, 0x06}, {0x3d, 0x02}, {0x4b, 0x09}, {0xc9, 0x30},
 709        {0x41, 0x08}, {0x56, 0x48}, {0x34, 0x11}, {0xa4, 0x88},
 710        {0x96, 0x00}, {0x97, 0x30}, {0x98, 0x20}, {0x99, 0x30},
 711        {0x9a, 0x84}, {0x9b, 0x29}, {0x9c, 0x03}, {0x9d, 0x99},
 712        {0x9e, 0x7f}, {0x78, 0x04}, {0x79, 0x01}, {0xc8, 0xf0},
 713        {0x79, 0x0f}, {0xc8, 0x00}, {0x79, 0x10}, {0xc8, 0x7e},
 714        {0x79, 0x0a}, {0xc8, 0x80}, {0x79, 0x0b}, {0xc8, 0x01},
 715        {0x79, 0x0c}, {0xc8, 0x0f}, {0x79, 0x0d}, {0xc8, 0x20},
 716        {0x79, 0x09}, {0xc8, 0x80}, {0x79, 0x02}, {0xc8, 0xc0},
 717        {0x79, 0x03}, {0xc8, 0x40}, {0x79, 0x05}, {0xc8, 0x30},
 718        {0x79, 0x26}, {0x62, 0x20}, {0x63, 0x00}, {0x64, 0x06},
 719        {0x65, 0x00}, {0x66, 0x05}, {0x94, 0x05}, {0x95, 0x0a},
 720        {0x17, 0x13}, {0x18, 0x01}, {0x19, 0x02}, {0x1a, 0x7a},
 721        {0x46, 0x59}, {0x47, 0x30}, {0x58, 0x9a}, {0x59, 0x84},
 722        {0x5a, 0x91}, {0x5b, 0x57}, {0x5c, 0x75}, {0x5d, 0x6d},
 723        {0x5e, 0x13}, {0x64, 0x07}, {0x94, 0x07}, {0x95, 0x0d},
 724        {0xa6, 0xdf}, {0xa7, 0xdf}, {0x48, 0x4d}, {0x51, 0x00},
 725        {0x6b, 0x0a}, {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00},
 726        {0x92, 0x00}, {0x93, 0x00}, {0x55, 0x0a}, {0x56, 0x60},
 727        {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d},
 728        {0x53, 0x56}, {0x54, 0x73}, {0x58, 0x9a}, {0x4f, 0x6e},
 729        {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d}, {0x53, 0x56},
 730        {0x54, 0x73}, {0x58, 0x9a}, {0x3f, 0x01}, {0x7b, 0x03},
 731        {0x7c, 0x09}, {0x7d, 0x16}, {0x7e, 0x38}, {0x7f, 0x47},
 732        {0x80, 0x53}, {0x81, 0x5e}, {0x82, 0x6a}, {0x83, 0x74},
 733        {0x84, 0x80}, {0x85, 0x8c}, {0x86, 0x9b}, {0x87, 0xb2},
 734        {0x88, 0xcc}, {0x89, 0xe5}, {0x7a, 0x24}, {0x3b, 0x00},
 735        {0x9f, 0x76}, {0xa0, 0x65}, {0x13, 0xe2}, {0x6b, 0x0a},
 736        {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00}, {0x92, 0x00},
 737        {0x93, 0x00},
 738};
 739
 740static const struct i2c_reg_u8 ov9650_init[] = {
 741        {0x00, 0x00}, {0x01, 0x78},
 742        {0x02, 0x78}, {0x03, 0x36}, {0x04, 0x03},
 743        {0x05, 0x00}, {0x06, 0x00}, {0x08, 0x00},
 744        {0x09, 0x01}, {0x0c, 0x00}, {0x0d, 0x00},
 745        {0x0e, 0xa0}, {0x0f, 0x52}, {0x10, 0x7c},
 746        {0x11, 0x80}, {0x12, 0x45}, {0x13, 0xc2},
 747        {0x14, 0x2e}, {0x15, 0x00}, {0x16, 0x07},
 748        {0x17, 0x24}, {0x18, 0xc5}, {0x19, 0x00},
 749        {0x1a, 0x3c}, {0x1b, 0x00}, {0x1e, 0x04},
 750        {0x1f, 0x00}, {0x24, 0x78}, {0x25, 0x68},
 751        {0x26, 0xd4}, {0x27, 0x80}, {0x28, 0x80},
 752        {0x29, 0x30}, {0x2a, 0x00}, {0x2b, 0x00},
 753        {0x2c, 0x80}, {0x2d, 0x00}, {0x2e, 0x00},
 754        {0x2f, 0x00}, {0x30, 0x08}, {0x31, 0x30},
 755        {0x32, 0x84}, {0x33, 0xe2}, {0x34, 0xbf},
 756        {0x35, 0x81}, {0x36, 0xf9}, {0x37, 0x00},
 757        {0x38, 0x93}, {0x39, 0x50}, {0x3a, 0x01},
 758        {0x3b, 0x01}, {0x3c, 0x73}, {0x3d, 0x19},
 759        {0x3e, 0x0b}, {0x3f, 0x80}, {0x40, 0xc1},
 760        {0x41, 0x00}, {0x42, 0x08}, {0x67, 0x80},
 761        {0x68, 0x80}, {0x69, 0x40}, {0x6a, 0x00},
 762        {0x6b, 0x0a}, {0x8b, 0x06}, {0x8c, 0x20},
 763        {0x8d, 0x00}, {0x8e, 0x00}, {0x8f, 0xdf},
 764        {0x92, 0x00}, {0x93, 0x00}, {0x94, 0x88},
 765        {0x95, 0x88}, {0x96, 0x04}, {0xa1, 0x00},
 766        {0xa5, 0x80}, {0xa8, 0x80}, {0xa9, 0xb8},
 767        {0xaa, 0x92}, {0xab, 0x0a},
 768};
 769
 770static const struct i2c_reg_u8 ov9655_init[] = {
 771        {0x0e, 0x61}, {0x11, 0x80}, {0x13, 0xba},
 772        {0x14, 0x2e}, {0x16, 0x24}, {0x1e, 0x04}, {0x27, 0x08},
 773        {0x28, 0x08}, {0x29, 0x15}, {0x2c, 0x08}, {0x34, 0x3d},
 774        {0x35, 0x00}, {0x38, 0x12}, {0x0f, 0x42}, {0x39, 0x57},
 775        {0x3a, 0x00}, {0x3b, 0xcc}, {0x3c, 0x0c}, {0x3d, 0x19},
 776        {0x3e, 0x0c}, {0x3f, 0x01}, {0x41, 0x40}, {0x42, 0x80},
 777        {0x45, 0x46}, {0x46, 0x62}, {0x47, 0x2a}, {0x48, 0x3c},
 778        {0x4a, 0xf0}, {0x4b, 0xdc}, {0x4c, 0xdc}, {0x4d, 0xdc},
 779        {0x4e, 0xdc}, {0x6c, 0x04}, {0x6f, 0x9e}, {0x70, 0x05},
 780        {0x71, 0x78}, {0x77, 0x02}, {0x8a, 0x23}, {0x90, 0x7e},
 781        {0x91, 0x7c}, {0x9f, 0x6e}, {0xa0, 0x6e}, {0xa5, 0x68},
 782        {0xa6, 0x60}, {0xa8, 0xc1}, {0xa9, 0xfa}, {0xaa, 0x92},
 783        {0xab, 0x04}, {0xac, 0x80}, {0xad, 0x80}, {0xae, 0x80},
 784        {0xaf, 0x80}, {0xb2, 0xf2}, {0xb3, 0x20}, {0xb5, 0x00},
 785        {0xb6, 0xaf}, {0xbb, 0xae}, {0xbc, 0x44}, {0xbd, 0x44},
 786        {0xbe, 0x3b}, {0xbf, 0x3a}, {0xc1, 0xc8}, {0xc2, 0x01},
 787        {0xc4, 0x00}, {0xc6, 0x85}, {0xc7, 0x81}, {0xc9, 0xe0},
 788        {0xca, 0xe8}, {0xcc, 0xd8}, {0xcd, 0x93}, {0x2d, 0x00},
 789        {0x2e, 0x00}, {0x01, 0x80}, {0x02, 0x80}, {0x12, 0x61},
 790        {0x36, 0xfa}, {0x8c, 0x8d}, {0xc0, 0xaa}, {0x69, 0x0a},
 791        {0x03, 0x09}, {0x17, 0x16}, {0x18, 0x6e}, {0x19, 0x01},
 792        {0x1a, 0x3e}, {0x32, 0x09}, {0x2a, 0x10}, {0x2b, 0x0a},
 793        {0x92, 0x00}, {0x93, 0x00}, {0xa1, 0x00}, {0x10, 0x7c},
 794        {0x04, 0x03}, {0x00, 0x13},
 795};
 796
 797static const struct i2c_reg_u16 mt9v112_init[] = {
 798        {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0020},
 799        {0x34, 0xc019}, {0x0a, 0x0011}, {0x0b, 0x000b},
 800        {0x20, 0x0703}, {0x35, 0x2022}, {0xf0, 0x0001},
 801        {0x05, 0x0000}, {0x06, 0x340c}, {0x3b, 0x042a},
 802        {0x3c, 0x0400}, {0xf0, 0x0002}, {0x2e, 0x0c58},
 803        {0x5b, 0x0001}, {0xc8, 0x9f0b}, {0xf0, 0x0001},
 804        {0x9b, 0x5300}, {0xf0, 0x0000}, {0x2b, 0x0020},
 805        {0x2c, 0x002a}, {0x2d, 0x0032}, {0x2e, 0x0020},
 806        {0x09, 0x01dc}, {0x01, 0x000c}, {0x02, 0x0020},
 807        {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
 808        {0x05, 0x0098}, {0x20, 0x0703}, {0x09, 0x01f2},
 809        {0x2b, 0x00a0}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
 810        {0x2e, 0x00a0}, {0x01, 0x000c}, {0x02, 0x0020},
 811        {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
 812        {0x05, 0x0098}, {0x09, 0x01c1}, {0x2b, 0x00ae},
 813        {0x2c, 0x00ae}, {0x2d, 0x00ae}, {0x2e, 0x00ae},
 814};
 815
 816static const struct i2c_reg_u16 mt9v111_init[] = {
 817        {0x01, 0x0004}, {0x0d, 0x0001}, {0x0d, 0x0000},
 818        {0x01, 0x0001}, {0x05, 0x0004}, {0x2d, 0xe0a0},
 819        {0x2e, 0x0c64}, {0x2f, 0x0064}, {0x06, 0x600e},
 820        {0x08, 0x0480}, {0x01, 0x0004}, {0x02, 0x0016},
 821        {0x03, 0x01e7}, {0x04, 0x0287}, {0x05, 0x0004},
 822        {0x06, 0x002d}, {0x07, 0x3002}, {0x08, 0x0008},
 823        {0x0e, 0x0008}, {0x20, 0x0000}
 824};
 825
 826static const struct i2c_reg_u16 mt9v011_init[] = {
 827        {0x07, 0x0002}, {0x0d, 0x0001}, {0x0d, 0x0000},
 828        {0x01, 0x0008}, {0x02, 0x0016}, {0x03, 0x01e1},
 829        {0x04, 0x0281}, {0x05, 0x0083}, {0x06, 0x0006},
 830        {0x0d, 0x0002}, {0x0a, 0x0000}, {0x0b, 0x0000},
 831        {0x0c, 0x0000}, {0x0d, 0x0000}, {0x0e, 0x0000},
 832        {0x0f, 0x0000}, {0x10, 0x0000}, {0x11, 0x0000},
 833        {0x12, 0x0000}, {0x13, 0x0000}, {0x14, 0x0000},
 834        {0x15, 0x0000}, {0x16, 0x0000}, {0x17, 0x0000},
 835        {0x18, 0x0000}, {0x19, 0x0000}, {0x1a, 0x0000},
 836        {0x1b, 0x0000}, {0x1c, 0x0000}, {0x1d, 0x0000},
 837        {0x32, 0x0000}, {0x20, 0x1101}, {0x21, 0x0000},
 838        {0x22, 0x0000}, {0x23, 0x0000}, {0x24, 0x0000},
 839        {0x25, 0x0000}, {0x26, 0x0000}, {0x27, 0x0024},
 840        {0x2f, 0xf7b0}, {0x30, 0x0005}, {0x31, 0x0000},
 841        {0x32, 0x0000}, {0x33, 0x0000}, {0x34, 0x0100},
 842        {0x3d, 0x068f}, {0x40, 0x01e0}, {0x41, 0x00d1},
 843        {0x44, 0x0082}, {0x5a, 0x0000}, {0x5b, 0x0000},
 844        {0x5c, 0x0000}, {0x5d, 0x0000}, {0x5e, 0x0000},
 845        {0x5f, 0xa31d}, {0x62, 0x0611}, {0x0a, 0x0000},
 846        {0x06, 0x0029}, {0x05, 0x0009}, {0x20, 0x1101},
 847        {0x20, 0x1101}, {0x09, 0x0064}, {0x07, 0x0003},
 848        {0x2b, 0x0033}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
 849        {0x2e, 0x0033}, {0x07, 0x0002}, {0x06, 0x0000},
 850        {0x06, 0x0029}, {0x05, 0x0009},
 851};
 852
 853static const struct i2c_reg_u16 mt9m001_init[] = {
 854        {0x0d, 0x0001},
 855        {0x0d, 0x0000},
 856        {0x04, 0x0500},         /* hres = 1280 */
 857        {0x03, 0x0400},         /* vres = 1024 */
 858        {0x20, 0x1100},
 859        {0x06, 0x0010},
 860        {0x2b, 0x0024},
 861        {0x2e, 0x0024},
 862        {0x35, 0x0024},
 863        {0x2d, 0x0020},
 864        {0x2c, 0x0020},
 865        {0x09, 0x0ad4},
 866        {0x35, 0x0057},
 867};
 868
 869static const struct i2c_reg_u16 mt9m111_init[] = {
 870        {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
 871        {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
 872        {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
 873        {0xf0, 0x0000},
 874};
 875
 876static const struct i2c_reg_u16 mt9m112_init[] = {
 877        {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
 878        {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
 879        {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
 880        {0xf0, 0x0000},
 881};
 882
 883static const struct i2c_reg_u8 hv7131r_init[] = {
 884        {0x02, 0x08}, {0x02, 0x00}, {0x01, 0x08},
 885        {0x02, 0x00}, {0x20, 0x00}, {0x21, 0xd0},
 886        {0x22, 0x00}, {0x23, 0x09}, {0x01, 0x08},
 887        {0x01, 0x08}, {0x01, 0x08}, {0x25, 0x07},
 888        {0x26, 0xc3}, {0x27, 0x50}, {0x30, 0x62},
 889        {0x31, 0x10}, {0x32, 0x06}, {0x33, 0x10},
 890        {0x20, 0x00}, {0x21, 0xd0}, {0x22, 0x00},
 891        {0x23, 0x09}, {0x01, 0x08},
 892};
 893
 894static void reg_r(struct gspca_dev *gspca_dev, u16 reg, u16 length)
 895{
 896        struct usb_device *dev = gspca_dev->dev;
 897        int result;
 898
 899        if (gspca_dev->usb_err < 0)
 900                return;
 901        result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
 902                        0x00,
 903                        USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
 904                        reg,
 905                        0x00,
 906                        gspca_dev->usb_buf,
 907                        length,
 908                        500);
 909        if (unlikely(result < 0 || result != length)) {
 910                pr_err("Read register %02x failed %d\n", reg, result);
 911                gspca_dev->usb_err = result;
 912        }
 913}
 914
 915static void reg_w(struct gspca_dev *gspca_dev, u16 reg,
 916                 const u8 *buffer, int length)
 917{
 918        struct usb_device *dev = gspca_dev->dev;
 919        int result;
 920
 921        if (gspca_dev->usb_err < 0)
 922                return;
 923        memcpy(gspca_dev->usb_buf, buffer, length);
 924        result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
 925                        0x08,
 926                        USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
 927                        reg,
 928                        0x00,
 929                        gspca_dev->usb_buf,
 930                        length,
 931                        500);
 932        if (unlikely(result < 0 || result != length)) {
 933                pr_err("Write register %02x failed %d\n", reg, result);
 934                gspca_dev->usb_err = result;
 935        }
 936}
 937
 938static void reg_w1(struct gspca_dev *gspca_dev, u16 reg, const u8 value)
 939{
 940        reg_w(gspca_dev, reg, &value, 1);
 941}
 942
 943static void i2c_w(struct gspca_dev *gspca_dev, const u8 *buffer)
 944{
 945        int i;
 946
 947        reg_w(gspca_dev, 0x10c0, buffer, 8);
 948        for (i = 0; i < 5; i++) {
 949                reg_r(gspca_dev, 0x10c0, 1);
 950                if (gspca_dev->usb_err < 0)
 951                        return;
 952                if (gspca_dev->usb_buf[0] & 0x04) {
 953                        if (gspca_dev->usb_buf[0] & 0x08) {
 954                                pr_err("i2c_w error\n");
 955                                gspca_dev->usb_err = -EIO;
 956                        }
 957                        return;
 958                }
 959                msleep(10);
 960        }
 961        pr_err("i2c_w reg %02x no response\n", buffer[2]);
 962/*      gspca_dev->usb_err = -EIO;      fixme: may occur */
 963}
 964
 965static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
 966{
 967        struct sd *sd = (struct sd *) gspca_dev;
 968        u8 row[8];
 969
 970        /*
 971         * from the point of view of the bridge, the length
 972         * includes the address
 973         */
 974        row[0] = sd->i2c_intf | (2 << 4);
 975        row[1] = sd->i2c_addr;
 976        row[2] = reg;
 977        row[3] = val;
 978        row[4] = 0x00;
 979        row[5] = 0x00;
 980        row[6] = 0x00;
 981        row[7] = 0x10;
 982
 983        i2c_w(gspca_dev, row);
 984}
 985
 986static void i2c_w1_buf(struct gspca_dev *gspca_dev,
 987                        const struct i2c_reg_u8 *buf, int sz)
 988{
 989        while (--sz >= 0) {
 990                i2c_w1(gspca_dev, buf->reg, buf->val);
 991                buf++;
 992        }
 993}
 994
 995static void i2c_w2(struct gspca_dev *gspca_dev, u8 reg, u16 val)
 996{
 997        struct sd *sd = (struct sd *) gspca_dev;
 998        u8 row[8];
 999
1000        /*
1001         * from the point of view of the bridge, the length
1002         * includes the address
1003         */
1004        row[0] = sd->i2c_intf | (3 << 4);
1005        row[1] = sd->i2c_addr;
1006        row[2] = reg;
1007        row[3] = val >> 8;
1008        row[4] = val;
1009        row[5] = 0x00;
1010        row[6] = 0x00;
1011        row[7] = 0x10;
1012
1013        i2c_w(gspca_dev, row);
1014}
1015
1016static void i2c_w2_buf(struct gspca_dev *gspca_dev,
1017                        const struct i2c_reg_u16 *buf, int sz)
1018{
1019        while (--sz >= 0) {
1020                i2c_w2(gspca_dev, buf->reg, buf->val);
1021                buf++;
1022        }
1023}
1024
1025static void i2c_r1(struct gspca_dev *gspca_dev, u8 reg, u8 *val)
1026{
1027        struct sd *sd = (struct sd *) gspca_dev;
1028        u8 row[8];
1029
1030        row[0] = sd->i2c_intf | (1 << 4);
1031        row[1] = sd->i2c_addr;
1032        row[2] = reg;
1033        row[3] = 0;
1034        row[4] = 0;
1035        row[5] = 0;
1036        row[6] = 0;
1037        row[7] = 0x10;
1038        i2c_w(gspca_dev, row);
1039        row[0] = sd->i2c_intf | (1 << 4) | 0x02;
1040        row[2] = 0;
1041        i2c_w(gspca_dev, row);
1042        reg_r(gspca_dev, 0x10c2, 5);
1043        *val = gspca_dev->usb_buf[4];
1044}
1045
1046static void i2c_r2(struct gspca_dev *gspca_dev, u8 reg, u16 *val)
1047{
1048        struct sd *sd = (struct sd *) gspca_dev;
1049        u8 row[8];
1050
1051        row[0] = sd->i2c_intf | (1 << 4);
1052        row[1] = sd->i2c_addr;
1053        row[2] = reg;
1054        row[3] = 0;
1055        row[4] = 0;
1056        row[5] = 0;
1057        row[6] = 0;
1058        row[7] = 0x10;
1059        i2c_w(gspca_dev, row);
1060        row[0] = sd->i2c_intf | (2 << 4) | 0x02;
1061        row[2] = 0;
1062        i2c_w(gspca_dev, row);
1063        reg_r(gspca_dev, 0x10c2, 5);
1064        *val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1065}
1066
1067static void ov9650_init_sensor(struct gspca_dev *gspca_dev)
1068{
1069        u16 id;
1070        struct sd *sd = (struct sd *) gspca_dev;
1071
1072        i2c_r2(gspca_dev, 0x1c, &id);
1073        if (gspca_dev->usb_err < 0)
1074                return;
1075
1076        if (id != 0x7fa2) {
1077                pr_err("sensor id for ov9650 doesn't match (0x%04x)\n", id);
1078                gspca_dev->usb_err = -ENODEV;
1079                return;
1080        }
1081
1082        i2c_w1(gspca_dev, 0x12, 0x80);          /* sensor reset */
1083        msleep(200);
1084        i2c_w1_buf(gspca_dev, ov9650_init, ARRAY_SIZE(ov9650_init));
1085        if (gspca_dev->usb_err < 0)
1086                pr_err("OV9650 sensor initialization failed\n");
1087        sd->hstart = 1;
1088        sd->vstart = 7;
1089}
1090
1091static void ov9655_init_sensor(struct gspca_dev *gspca_dev)
1092{
1093        struct sd *sd = (struct sd *) gspca_dev;
1094
1095        i2c_w1(gspca_dev, 0x12, 0x80);          /* sensor reset */
1096        msleep(200);
1097        i2c_w1_buf(gspca_dev, ov9655_init, ARRAY_SIZE(ov9655_init));
1098        if (gspca_dev->usb_err < 0)
1099                pr_err("OV9655 sensor initialization failed\n");
1100
1101        sd->hstart = 1;
1102        sd->vstart = 2;
1103}
1104
1105static void soi968_init_sensor(struct gspca_dev *gspca_dev)
1106{
1107        struct sd *sd = (struct sd *) gspca_dev;
1108
1109        i2c_w1(gspca_dev, 0x12, 0x80);          /* sensor reset */
1110        msleep(200);
1111        i2c_w1_buf(gspca_dev, soi968_init, ARRAY_SIZE(soi968_init));
1112        if (gspca_dev->usb_err < 0)
1113                pr_err("SOI968 sensor initialization failed\n");
1114
1115        sd->hstart = 60;
1116        sd->vstart = 11;
1117}
1118
1119static void ov7660_init_sensor(struct gspca_dev *gspca_dev)
1120{
1121        struct sd *sd = (struct sd *) gspca_dev;
1122
1123        i2c_w1(gspca_dev, 0x12, 0x80);          /* sensor reset */
1124        msleep(200);
1125        i2c_w1_buf(gspca_dev, ov7660_init, ARRAY_SIZE(ov7660_init));
1126        if (gspca_dev->usb_err < 0)
1127                pr_err("OV7660 sensor initialization failed\n");
1128        sd->hstart = 3;
1129        sd->vstart = 3;
1130}
1131
1132static void ov7670_init_sensor(struct gspca_dev *gspca_dev)
1133{
1134        struct sd *sd = (struct sd *) gspca_dev;
1135
1136        i2c_w1(gspca_dev, 0x12, 0x80);          /* sensor reset */
1137        msleep(200);
1138        i2c_w1_buf(gspca_dev, ov7670_init, ARRAY_SIZE(ov7670_init));
1139        if (gspca_dev->usb_err < 0)
1140                pr_err("OV7670 sensor initialization failed\n");
1141
1142        sd->hstart = 0;
1143        sd->vstart = 1;
1144}
1145
1146static void mt9v_init_sensor(struct gspca_dev *gspca_dev)
1147{
1148        struct sd *sd = (struct sd *) gspca_dev;
1149        u16 value;
1150
1151        sd->i2c_addr = 0x5d;
1152        i2c_r2(gspca_dev, 0xff, &value);
1153        if (gspca_dev->usb_err >= 0
1154         && value == 0x8243) {
1155                i2c_w2_buf(gspca_dev, mt9v011_init, ARRAY_SIZE(mt9v011_init));
1156                if (gspca_dev->usb_err < 0) {
1157                        pr_err("MT9V011 sensor initialization failed\n");
1158                        return;
1159                }
1160                sd->hstart = 2;
1161                sd->vstart = 2;
1162                sd->sensor = SENSOR_MT9V011;
1163                pr_info("MT9V011 sensor detected\n");
1164                return;
1165        }
1166
1167        gspca_dev->usb_err = 0;
1168        sd->i2c_addr = 0x5c;
1169        i2c_w2(gspca_dev, 0x01, 0x0004);
1170        i2c_r2(gspca_dev, 0xff, &value);
1171        if (gspca_dev->usb_err >= 0
1172         && value == 0x823a) {
1173                i2c_w2_buf(gspca_dev, mt9v111_init, ARRAY_SIZE(mt9v111_init));
1174                if (gspca_dev->usb_err < 0) {
1175                        pr_err("MT9V111 sensor initialization failed\n");
1176                        return;
1177                }
1178                sd->hstart = 2;
1179                sd->vstart = 2;
1180                sd->sensor = SENSOR_MT9V111;
1181                pr_info("MT9V111 sensor detected\n");
1182                return;
1183        }
1184
1185        gspca_dev->usb_err = 0;
1186        sd->i2c_addr = 0x5d;
1187        i2c_w2(gspca_dev, 0xf0, 0x0000);
1188        if (gspca_dev->usb_err < 0) {
1189                gspca_dev->usb_err = 0;
1190                sd->i2c_addr = 0x48;
1191                i2c_w2(gspca_dev, 0xf0, 0x0000);
1192        }
1193        i2c_r2(gspca_dev, 0x00, &value);
1194        if (gspca_dev->usb_err >= 0
1195         && value == 0x1229) {
1196                i2c_w2_buf(gspca_dev, mt9v112_init, ARRAY_SIZE(mt9v112_init));
1197                if (gspca_dev->usb_err < 0) {
1198                        pr_err("MT9V112 sensor initialization failed\n");
1199                        return;
1200                }
1201                sd->hstart = 6;
1202                sd->vstart = 2;
1203                sd->sensor = SENSOR_MT9V112;
1204                pr_info("MT9V112 sensor detected\n");
1205                return;
1206        }
1207
1208        gspca_dev->usb_err = -ENODEV;
1209}
1210
1211static void mt9m112_init_sensor(struct gspca_dev *gspca_dev)
1212{
1213        struct sd *sd = (struct sd *) gspca_dev;
1214
1215        i2c_w2_buf(gspca_dev, mt9m112_init, ARRAY_SIZE(mt9m112_init));
1216        if (gspca_dev->usb_err < 0)
1217                pr_err("MT9M112 sensor initialization failed\n");
1218
1219        sd->hstart = 0;
1220        sd->vstart = 2;
1221}
1222
1223static void mt9m111_init_sensor(struct gspca_dev *gspca_dev)
1224{
1225        struct sd *sd = (struct sd *) gspca_dev;
1226
1227        i2c_w2_buf(gspca_dev, mt9m111_init, ARRAY_SIZE(mt9m111_init));
1228        if (gspca_dev->usb_err < 0)
1229                pr_err("MT9M111 sensor initialization failed\n");
1230
1231        sd->hstart = 0;
1232        sd->vstart = 2;
1233}
1234
1235static void mt9m001_init_sensor(struct gspca_dev *gspca_dev)
1236{
1237        struct sd *sd = (struct sd *) gspca_dev;
1238        u16 id;
1239
1240        i2c_r2(gspca_dev, 0x00, &id);
1241        if (gspca_dev->usb_err < 0)
1242                return;
1243
1244        /* must be 0x8411 or 0x8421 for colour sensor and 8431 for bw */
1245        switch (id) {
1246        case 0x8411:
1247        case 0x8421:
1248                pr_info("MT9M001 color sensor detected\n");
1249                break;
1250        case 0x8431:
1251                pr_info("MT9M001 mono sensor detected\n");
1252                break;
1253        default:
1254                pr_err("No MT9M001 chip detected, ID = %x\n\n", id);
1255                gspca_dev->usb_err = -ENODEV;
1256                return;
1257        }
1258
1259        i2c_w2_buf(gspca_dev, mt9m001_init, ARRAY_SIZE(mt9m001_init));
1260        if (gspca_dev->usb_err < 0)
1261                pr_err("MT9M001 sensor initialization failed\n");
1262
1263        sd->hstart = 1;
1264        sd->vstart = 1;
1265}
1266
1267static void hv7131r_init_sensor(struct gspca_dev *gspca_dev)
1268{
1269        struct sd *sd = (struct sd *) gspca_dev;
1270
1271        i2c_w1_buf(gspca_dev, hv7131r_init, ARRAY_SIZE(hv7131r_init));
1272        if (gspca_dev->usb_err < 0)
1273                pr_err("HV7131R Sensor initialization failed\n");
1274
1275        sd->hstart = 0;
1276        sd->vstart = 1;
1277}
1278
1279static void set_cmatrix(struct gspca_dev *gspca_dev,
1280                s32 brightness, s32 contrast, s32 satur, s32 hue)
1281{
1282        s32 hue_coord, hue_index = 180 + hue;
1283        u8 cmatrix[21];
1284
1285        memset(cmatrix, 0, sizeof(cmatrix));
1286        cmatrix[2] = (contrast * 0x25 / 0x100) + 0x26;
1287        cmatrix[0] = 0x13 + (cmatrix[2] - 0x26) * 0x13 / 0x25;
1288        cmatrix[4] = 0x07 + (cmatrix[2] - 0x26) * 0x07 / 0x25;
1289        cmatrix[18] = brightness - 0x80;
1290
1291        hue_coord = (hsv_red_x[hue_index] * satur) >> 8;
1292        cmatrix[6] = hue_coord;
1293        cmatrix[7] = (hue_coord >> 8) & 0x0f;
1294
1295        hue_coord = (hsv_red_y[hue_index] * satur) >> 8;
1296        cmatrix[8] = hue_coord;
1297        cmatrix[9] = (hue_coord >> 8) & 0x0f;
1298
1299        hue_coord = (hsv_green_x[hue_index] * satur) >> 8;
1300        cmatrix[10] = hue_coord;
1301        cmatrix[11] = (hue_coord >> 8) & 0x0f;
1302
1303        hue_coord = (hsv_green_y[hue_index] * satur) >> 8;
1304        cmatrix[12] = hue_coord;
1305        cmatrix[13] = (hue_coord >> 8) & 0x0f;
1306
1307        hue_coord = (hsv_blue_x[hue_index] * satur) >> 8;
1308        cmatrix[14] = hue_coord;
1309        cmatrix[15] = (hue_coord >> 8) & 0x0f;
1310
1311        hue_coord = (hsv_blue_y[hue_index] * satur) >> 8;
1312        cmatrix[16] = hue_coord;
1313        cmatrix[17] = (hue_coord >> 8) & 0x0f;
1314
1315        reg_w(gspca_dev, 0x10e1, cmatrix, 21);
1316}
1317
1318static void set_gamma(struct gspca_dev *gspca_dev, s32 val)
1319{
1320        u8 gamma[17];
1321        u8 gval = val * 0xb8 / 0x100;
1322
1323        gamma[0] = 0x0a;
1324        gamma[1] = 0x13 + (gval * (0xcb - 0x13) / 0xb8);
1325        gamma[2] = 0x25 + (gval * (0xee - 0x25) / 0xb8);
1326        gamma[3] = 0x37 + (gval * (0xfa - 0x37) / 0xb8);
1327        gamma[4] = 0x45 + (gval * (0xfc - 0x45) / 0xb8);
1328        gamma[5] = 0x55 + (gval * (0xfb - 0x55) / 0xb8);
1329        gamma[6] = 0x65 + (gval * (0xfc - 0x65) / 0xb8);
1330        gamma[7] = 0x74 + (gval * (0xfd - 0x74) / 0xb8);
1331        gamma[8] = 0x83 + (gval * (0xfe - 0x83) / 0xb8);
1332        gamma[9] = 0x92 + (gval * (0xfc - 0x92) / 0xb8);
1333        gamma[10] = 0xa1 + (gval * (0xfc - 0xa1) / 0xb8);
1334        gamma[11] = 0xb0 + (gval * (0xfc - 0xb0) / 0xb8);
1335        gamma[12] = 0xbf + (gval * (0xfb - 0xbf) / 0xb8);
1336        gamma[13] = 0xce + (gval * (0xfb - 0xce) / 0xb8);
1337        gamma[14] = 0xdf + (gval * (0xfd - 0xdf) / 0xb8);
1338        gamma[15] = 0xea + (gval * (0xf9 - 0xea) / 0xb8);
1339        gamma[16] = 0xf5;
1340
1341        reg_w(gspca_dev, 0x1190, gamma, 17);
1342}
1343
1344static void set_redblue(struct gspca_dev *gspca_dev, s32 blue, s32 red)
1345{
1346        reg_w1(gspca_dev, 0x118c, red);
1347        reg_w1(gspca_dev, 0x118f, blue);
1348}
1349
1350static void set_hvflip(struct gspca_dev *gspca_dev, s32 hflip, s32 vflip)
1351{
1352        u8 value, tslb;
1353        u16 value2;
1354        struct sd *sd = (struct sd *) gspca_dev;
1355
1356        if ((sd->flags & FLIP_DETECT) && dmi_check_system(flip_dmi_table)) {
1357                hflip = !hflip;
1358                vflip = !vflip;
1359        }
1360
1361        switch (sd->sensor) {
1362        case SENSOR_OV7660:
1363                value = 0x01;
1364                if (hflip)
1365                        value |= 0x20;
1366                if (vflip) {
1367                        value |= 0x10;
1368                        sd->vstart = 2;
1369                } else {
1370                        sd->vstart = 3;
1371                }
1372                reg_w1(gspca_dev, 0x1182, sd->vstart);
1373                i2c_w1(gspca_dev, 0x1e, value);
1374                break;
1375        case SENSOR_OV9650:
1376                i2c_r1(gspca_dev, 0x1e, &value);
1377                value &= ~0x30;
1378                tslb = 0x01;
1379                if (hflip)
1380                        value |= 0x20;
1381                if (vflip) {
1382                        value |= 0x10;
1383                        tslb = 0x49;
1384                }
1385                i2c_w1(gspca_dev, 0x1e, value);
1386                i2c_w1(gspca_dev, 0x3a, tslb);
1387                break;
1388        case SENSOR_MT9V111:
1389        case SENSOR_MT9V011:
1390                i2c_r2(gspca_dev, 0x20, &value2);
1391                value2 &= ~0xc0a0;
1392                if (hflip)
1393                        value2 |= 0x8080;
1394                if (vflip)
1395                        value2 |= 0x4020;
1396                i2c_w2(gspca_dev, 0x20, value2);
1397                break;
1398        case SENSOR_MT9M112:
1399        case SENSOR_MT9M111:
1400        case SENSOR_MT9V112:
1401                i2c_r2(gspca_dev, 0x20, &value2);
1402                value2 &= ~0x0003;
1403                if (hflip)
1404                        value2 |= 0x0002;
1405                if (vflip)
1406                        value2 |= 0x0001;
1407                i2c_w2(gspca_dev, 0x20, value2);
1408                break;
1409        case SENSOR_HV7131R:
1410                i2c_r1(gspca_dev, 0x01, &value);
1411                value &= ~0x03;
1412                if (vflip)
1413                        value |= 0x01;
1414                if (hflip)
1415                        value |= 0x02;
1416                i2c_w1(gspca_dev, 0x01, value);
1417                break;
1418        }
1419}
1420
1421static void set_exposure(struct gspca_dev *gspca_dev, s32 expo)
1422{
1423        struct sd *sd = (struct sd *) gspca_dev;
1424        u8 exp[8] = {sd->i2c_intf, sd->i2c_addr,
1425                                0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
1426        int expo2;
1427
1428        if (gspca_dev->streaming)
1429                exp[7] = 0x1e;
1430
1431        switch (sd->sensor) {
1432        case SENSOR_OV7660:
1433        case SENSOR_OV7670:
1434        case SENSOR_OV9655:
1435        case SENSOR_OV9650:
1436                if (expo > 547)
1437                        expo2 = 547;
1438                else
1439                        expo2 = expo;
1440                exp[0] |= (2 << 4);
1441                exp[2] = 0x10;                  /* AECH */
1442                exp[3] = expo2 >> 2;
1443                exp[7] = 0x10;
1444                i2c_w(gspca_dev, exp);
1445                exp[2] = 0x04;                  /* COM1 */
1446                exp[3] = expo2 & 0x0003;
1447                exp[7] = 0x10;
1448                i2c_w(gspca_dev, exp);
1449                expo -= expo2;
1450                exp[7] = 0x1e;
1451                exp[0] |= (3 << 4);
1452                exp[2] = 0x2d;                  /* ADVFL & ADVFH */
1453                exp[3] = expo;
1454                exp[4] = expo >> 8;
1455                break;
1456        case SENSOR_MT9M001:
1457        case SENSOR_MT9V112:
1458        case SENSOR_MT9V011:
1459                exp[0] |= (3 << 4);
1460                exp[2] = 0x09;
1461                exp[3] = expo >> 8;
1462                exp[4] = expo;
1463                break;
1464        case SENSOR_HV7131R:
1465                exp[0] |= (4 << 4);
1466                exp[2] = 0x25;
1467                exp[3] = expo >> 5;
1468                exp[4] = expo << 3;
1469                exp[5] = 0;
1470                break;
1471        default:
1472                return;
1473        }
1474        i2c_w(gspca_dev, exp);
1475}
1476
1477static void set_gain(struct gspca_dev *gspca_dev, s32 g)
1478{
1479        struct sd *sd = (struct sd *) gspca_dev;
1480        u8 gain[8] = {sd->i2c_intf, sd->i2c_addr,
1481                                0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
1482
1483        if (gspca_dev->streaming)
1484                gain[7] = 0x15;         /* or 1d ? */
1485
1486        switch (sd->sensor) {
1487        case SENSOR_OV7660:
1488        case SENSOR_OV7670:
1489        case SENSOR_SOI968:
1490        case SENSOR_OV9655:
1491        case SENSOR_OV9650:
1492                gain[0] |= (2 << 4);
1493                gain[3] = ov_gain[g];
1494                break;
1495        case SENSOR_MT9V011:
1496                gain[0] |= (3 << 4);
1497                gain[2] = 0x35;
1498                gain[3] = micron1_gain[g] >> 8;
1499                gain[4] = micron1_gain[g];
1500                break;
1501        case SENSOR_MT9V112:
1502                gain[0] |= (3 << 4);
1503                gain[2] = 0x2f;
1504                gain[3] = micron1_gain[g] >> 8;
1505                gain[4] = micron1_gain[g];
1506                break;
1507        case SENSOR_MT9M001:
1508                gain[0] |= (3 << 4);
1509                gain[2] = 0x2f;
1510                gain[3] = micron2_gain[g] >> 8;
1511                gain[4] = micron2_gain[g];
1512                break;
1513        case SENSOR_HV7131R:
1514                gain[0] |= (2 << 4);
1515                gain[2] = 0x30;
1516                gain[3] = hv7131r_gain[g];
1517                break;
1518        default:
1519                return;
1520        }
1521        i2c_w(gspca_dev, gain);
1522}
1523
1524static void set_quality(struct gspca_dev *gspca_dev, s32 val)
1525{
1526        struct sd *sd = (struct sd *) gspca_dev;
1527
1528        jpeg_set_qual(sd->jpeg_hdr, val);
1529        reg_w1(gspca_dev, 0x1061, 0x01);        /* stop transfer */
1530        reg_w1(gspca_dev, 0x10e0, sd->fmt | 0x20); /* write QTAB */
1531        reg_w(gspca_dev, 0x1100, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64);
1532        reg_w(gspca_dev, 0x1140, &sd->jpeg_hdr[JPEG_QT1_OFFSET], 64);
1533        reg_w1(gspca_dev, 0x1061, 0x03);        /* restart transfer */
1534        reg_w1(gspca_dev, 0x10e0, sd->fmt);
1535        sd->fmt ^= 0x0c;                        /* invert QTAB use + write */
1536        reg_w1(gspca_dev, 0x10e0, sd->fmt);
1537}
1538
1539#ifdef CONFIG_VIDEO_ADV_DEBUG
1540static int sd_dbg_g_register(struct gspca_dev *gspca_dev,
1541                        struct v4l2_dbg_register *reg)
1542{
1543        struct sd *sd = (struct sd *) gspca_dev;
1544
1545        reg->size = 1;
1546        switch (reg->match.addr) {
1547        case 0:
1548                if (reg->reg < 0x1000 || reg->reg > 0x11ff)
1549                        return -EINVAL;
1550                reg_r(gspca_dev, reg->reg, 1);
1551                reg->val = gspca_dev->usb_buf[0];
1552                return gspca_dev->usb_err;
1553        case 1:
1554                if (sd->sensor >= SENSOR_MT9V011 &&
1555                    sd->sensor <= SENSOR_MT9M112) {
1556                        i2c_r2(gspca_dev, reg->reg, (u16 *) &reg->val);
1557                        reg->size = 2;
1558                } else {
1559                        i2c_r1(gspca_dev, reg->reg, (u8 *) &reg->val);
1560                }
1561                return gspca_dev->usb_err;
1562        }
1563        return -EINVAL;
1564}
1565
1566static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
1567                        const struct v4l2_dbg_register *reg)
1568{
1569        struct sd *sd = (struct sd *) gspca_dev;
1570
1571        switch (reg->match.addr) {
1572        case 0:
1573                if (reg->reg < 0x1000 || reg->reg > 0x11ff)
1574                        return -EINVAL;
1575                reg_w1(gspca_dev, reg->reg, reg->val);
1576                return gspca_dev->usb_err;
1577        case 1:
1578                if (sd->sensor >= SENSOR_MT9V011 &&
1579                    sd->sensor <= SENSOR_MT9M112) {
1580                        i2c_w2(gspca_dev, reg->reg, reg->val);
1581                } else {
1582                        i2c_w1(gspca_dev, reg->reg, reg->val);
1583                }
1584                return gspca_dev->usb_err;
1585        }
1586        return -EINVAL;
1587}
1588
1589static int sd_chip_info(struct gspca_dev *gspca_dev,
1590                        struct v4l2_dbg_chip_info *chip)
1591{
1592        if (chip->match.addr > 1)
1593                return -EINVAL;
1594        if (chip->match.addr == 1)
1595                strscpy(chip->name, "sensor", sizeof(chip->name));
1596        return 0;
1597}
1598#endif
1599
1600static int sd_config(struct gspca_dev *gspca_dev,
1601                        const struct usb_device_id *id)
1602{
1603        struct sd *sd = (struct sd *) gspca_dev;
1604        struct cam *cam;
1605
1606        cam = &gspca_dev->cam;
1607        cam->needs_full_bandwidth = 1;
1608
1609        sd->sensor = id->driver_info >> 8;
1610        sd->i2c_addr = id->driver_info;
1611        sd->flags = id->driver_info >> 16;
1612        sd->i2c_intf = 0x80;                    /* i2c 100 Kb/s */
1613
1614        switch (sd->sensor) {
1615        case SENSOR_MT9M112:
1616        case SENSOR_MT9M111:
1617        case SENSOR_OV9650:
1618        case SENSOR_SOI968:
1619                cam->cam_mode = sxga_mode;
1620                cam->nmodes = ARRAY_SIZE(sxga_mode);
1621                break;
1622        case SENSOR_MT9M001:
1623                cam->cam_mode = mono_mode;
1624                cam->nmodes = ARRAY_SIZE(mono_mode);
1625                break;
1626        case SENSOR_HV7131R:
1627                sd->i2c_intf = 0x81;                    /* i2c 400 Kb/s */
1628                /* fall through */
1629        default:
1630                cam->cam_mode = vga_mode;
1631                cam->nmodes = ARRAY_SIZE(vga_mode);
1632                break;
1633        }
1634
1635        sd->old_step = 0;
1636        sd->older_step = 0;
1637        sd->exposure_step = 16;
1638
1639        INIT_WORK(&sd->work, qual_upd);
1640
1641        return 0;
1642}
1643
1644static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
1645{
1646        struct gspca_dev *gspca_dev =
1647                container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
1648        struct sd *sd = (struct sd *)gspca_dev;
1649
1650        gspca_dev->usb_err = 0;
1651
1652        if (!gspca_dev->streaming)
1653                return 0;
1654
1655        switch (ctrl->id) {
1656        /* color control cluster */
1657        case V4L2_CID_BRIGHTNESS:
1658                set_cmatrix(gspca_dev, sd->brightness->val,
1659                        sd->contrast->val, sd->saturation->val, sd->hue->val);
1660                break;
1661        case V4L2_CID_GAMMA:
1662                set_gamma(gspca_dev, ctrl->val);
1663                break;
1664        /* blue/red balance cluster */
1665        case V4L2_CID_BLUE_BALANCE:
1666                set_redblue(gspca_dev, sd->blue->val, sd->red->val);
1667                break;
1668        /* h/vflip cluster */
1669        case V4L2_CID_HFLIP:
1670                set_hvflip(gspca_dev, sd->hflip->val, sd->vflip->val);
1671                break;
1672        /* standalone exposure control */
1673        case V4L2_CID_EXPOSURE:
1674                set_exposure(gspca_dev, ctrl->val);
1675                break;
1676        /* standalone gain control */
1677        case V4L2_CID_GAIN:
1678                set_gain(gspca_dev, ctrl->val);
1679                break;
1680        /* autogain + exposure or gain control cluster */
1681        case V4L2_CID_AUTOGAIN:
1682                if (sd->sensor == SENSOR_SOI968)
1683                        set_gain(gspca_dev, sd->gain->val);
1684                else
1685                        set_exposure(gspca_dev, sd->exposure->val);
1686                break;
1687        case V4L2_CID_JPEG_COMPRESSION_QUALITY:
1688                set_quality(gspca_dev, ctrl->val);
1689                break;
1690        }
1691        return gspca_dev->usb_err;
1692}
1693
1694static const struct v4l2_ctrl_ops sd_ctrl_ops = {
1695        .s_ctrl = sd_s_ctrl,
1696};
1697
1698static int sd_init_controls(struct gspca_dev *gspca_dev)
1699{
1700        struct sd *sd = (struct sd *) gspca_dev;
1701        struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
1702
1703        gspca_dev->vdev.ctrl_handler = hdl;
1704        v4l2_ctrl_handler_init(hdl, 13);
1705
1706        sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1707                        V4L2_CID_BRIGHTNESS, 0, 255, 1, 127);
1708        sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1709                        V4L2_CID_CONTRAST, 0, 255, 1, 127);
1710        sd->saturation = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1711                        V4L2_CID_SATURATION, 0, 255, 1, 127);
1712        sd->hue = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1713                        V4L2_CID_HUE, -180, 180, 1, 0);
1714
1715        sd->gamma = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1716                        V4L2_CID_GAMMA, 0, 255, 1, 0x10);
1717
1718        sd->blue = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1719                        V4L2_CID_BLUE_BALANCE, 0, 127, 1, 0x28);
1720        sd->red = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1721                        V4L2_CID_RED_BALANCE, 0, 127, 1, 0x28);
1722
1723        if (sd->sensor != SENSOR_OV9655 && sd->sensor != SENSOR_SOI968 &&
1724            sd->sensor != SENSOR_OV7670 && sd->sensor != SENSOR_MT9M001 &&
1725            sd->sensor != SENSOR_MT9VPRB) {
1726                sd->hflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1727                        V4L2_CID_HFLIP, 0, 1, 1, 0);
1728                sd->vflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1729                        V4L2_CID_VFLIP, 0, 1, 1, 0);
1730        }
1731
1732        if (sd->sensor != SENSOR_SOI968 && sd->sensor != SENSOR_MT9VPRB &&
1733            sd->sensor != SENSOR_MT9M112 && sd->sensor != SENSOR_MT9M111 &&
1734            sd->sensor != SENSOR_MT9V111)
1735                sd->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1736                        V4L2_CID_EXPOSURE, 0, 0x1780, 1, 0x33);
1737
1738        if (sd->sensor != SENSOR_MT9VPRB && sd->sensor != SENSOR_MT9M112 &&
1739            sd->sensor != SENSOR_MT9M111 && sd->sensor != SENSOR_MT9V111) {
1740                sd->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1741                        V4L2_CID_GAIN, 0, 28, 1, 0);
1742                sd->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1743                        V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
1744        }
1745
1746        sd->jpegqual = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1747                        V4L2_CID_JPEG_COMPRESSION_QUALITY, 50, 90, 1, 80);
1748        if (hdl->error) {
1749                pr_err("Could not initialize controls\n");
1750                return hdl->error;
1751        }
1752
1753        v4l2_ctrl_cluster(4, &sd->brightness);
1754        v4l2_ctrl_cluster(2, &sd->blue);
1755        if (sd->hflip)
1756                v4l2_ctrl_cluster(2, &sd->hflip);
1757        if (sd->autogain) {
1758                if (sd->sensor == SENSOR_SOI968)
1759                        /* this sensor doesn't have the exposure control and
1760                           autogain is clustered with gain instead. This works
1761                           because sd->exposure == NULL. */
1762                        v4l2_ctrl_auto_cluster(3, &sd->autogain, 0, false);
1763                else
1764                        /* Otherwise autogain is clustered with exposure. */
1765                        v4l2_ctrl_auto_cluster(2, &sd->autogain, 0, false);
1766        }
1767        return 0;
1768}
1769
1770static int sd_init(struct gspca_dev *gspca_dev)
1771{
1772        struct sd *sd = (struct sd *) gspca_dev;
1773        int i;
1774        u8 value;
1775        u8 i2c_init[9] = {
1776                0x80, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03
1777        };
1778
1779        for (i = 0; i < ARRAY_SIZE(bridge_init); i++) {
1780                value = bridge_init[i][1];
1781                reg_w(gspca_dev, bridge_init[i][0], &value, 1);
1782                if (gspca_dev->usb_err < 0) {
1783                        pr_err("Device initialization failed\n");
1784                        return gspca_dev->usb_err;
1785                }
1786        }
1787
1788        if (sd->flags & LED_REVERSE)
1789                reg_w1(gspca_dev, 0x1006, 0x00);
1790        else
1791                reg_w1(gspca_dev, 0x1006, 0x20);
1792
1793        reg_w(gspca_dev, 0x10c0, i2c_init, 9);
1794        if (gspca_dev->usb_err < 0) {
1795                pr_err("Device initialization failed\n");
1796                return gspca_dev->usb_err;
1797        }
1798
1799        switch (sd->sensor) {
1800        case SENSOR_OV9650:
1801                ov9650_init_sensor(gspca_dev);
1802                if (gspca_dev->usb_err < 0)
1803                        break;
1804                pr_info("OV9650 sensor detected\n");
1805                break;
1806        case SENSOR_OV9655:
1807                ov9655_init_sensor(gspca_dev);
1808                if (gspca_dev->usb_err < 0)
1809                        break;
1810                pr_info("OV9655 sensor detected\n");
1811                break;
1812        case SENSOR_SOI968:
1813                soi968_init_sensor(gspca_dev);
1814                if (gspca_dev->usb_err < 0)
1815                        break;
1816                pr_info("SOI968 sensor detected\n");
1817                break;
1818        case SENSOR_OV7660:
1819                ov7660_init_sensor(gspca_dev);
1820                if (gspca_dev->usb_err < 0)
1821                        break;
1822                pr_info("OV7660 sensor detected\n");
1823                break;
1824        case SENSOR_OV7670:
1825                ov7670_init_sensor(gspca_dev);
1826                if (gspca_dev->usb_err < 0)
1827                        break;
1828                pr_info("OV7670 sensor detected\n");
1829                break;
1830        case SENSOR_MT9VPRB:
1831                mt9v_init_sensor(gspca_dev);
1832                if (gspca_dev->usb_err < 0)
1833                        break;
1834                pr_info("MT9VPRB sensor detected\n");
1835                break;
1836        case SENSOR_MT9M111:
1837                mt9m111_init_sensor(gspca_dev);
1838                if (gspca_dev->usb_err < 0)
1839                        break;
1840                pr_info("MT9M111 sensor detected\n");
1841                break;
1842        case SENSOR_MT9M112:
1843                mt9m112_init_sensor(gspca_dev);
1844                if (gspca_dev->usb_err < 0)
1845                        break;
1846                pr_info("MT9M112 sensor detected\n");
1847                break;
1848        case SENSOR_MT9M001:
1849                mt9m001_init_sensor(gspca_dev);
1850                if (gspca_dev->usb_err < 0)
1851                        break;
1852                break;
1853        case SENSOR_HV7131R:
1854                hv7131r_init_sensor(gspca_dev);
1855                if (gspca_dev->usb_err < 0)
1856                        break;
1857                pr_info("HV7131R sensor detected\n");
1858                break;
1859        default:
1860                pr_err("Unsupported sensor\n");
1861                gspca_dev->usb_err = -ENODEV;
1862        }
1863        return gspca_dev->usb_err;
1864}
1865
1866static void configure_sensor_output(struct gspca_dev *gspca_dev, int mode)
1867{
1868        struct sd *sd = (struct sd *) gspca_dev;
1869        u8 value;
1870
1871        switch (sd->sensor) {
1872        case SENSOR_SOI968:
1873                if (mode & MODE_SXGA) {
1874                        i2c_w1(gspca_dev, 0x17, 0x1d);
1875                        i2c_w1(gspca_dev, 0x18, 0xbd);
1876                        i2c_w1(gspca_dev, 0x19, 0x01);
1877                        i2c_w1(gspca_dev, 0x1a, 0x81);
1878                        i2c_w1(gspca_dev, 0x12, 0x00);
1879                        sd->hstart = 140;
1880                        sd->vstart = 19;
1881                } else {
1882                        i2c_w1(gspca_dev, 0x17, 0x13);
1883                        i2c_w1(gspca_dev, 0x18, 0x63);
1884                        i2c_w1(gspca_dev, 0x19, 0x01);
1885                        i2c_w1(gspca_dev, 0x1a, 0x79);
1886                        i2c_w1(gspca_dev, 0x12, 0x40);
1887                        sd->hstart = 60;
1888                        sd->vstart = 11;
1889                }
1890                break;
1891        case SENSOR_OV9650:
1892                if (mode & MODE_SXGA) {
1893                        i2c_w1(gspca_dev, 0x17, 0x1b);
1894                        i2c_w1(gspca_dev, 0x18, 0xbc);
1895                        i2c_w1(gspca_dev, 0x19, 0x01);
1896                        i2c_w1(gspca_dev, 0x1a, 0x82);
1897                        i2c_r1(gspca_dev, 0x12, &value);
1898                        i2c_w1(gspca_dev, 0x12, value & 0x07);
1899                } else {
1900                        i2c_w1(gspca_dev, 0x17, 0x24);
1901                        i2c_w1(gspca_dev, 0x18, 0xc5);
1902                        i2c_w1(gspca_dev, 0x19, 0x00);
1903                        i2c_w1(gspca_dev, 0x1a, 0x3c);
1904                        i2c_r1(gspca_dev, 0x12, &value);
1905                        i2c_w1(gspca_dev, 0x12, (value & 0x7) | 0x40);
1906                }
1907                break;
1908        case SENSOR_MT9M112:
1909        case SENSOR_MT9M111:
1910                if (mode & MODE_SXGA) {
1911                        i2c_w2(gspca_dev, 0xf0, 0x0002);
1912                        i2c_w2(gspca_dev, 0xc8, 0x970b);
1913                        i2c_w2(gspca_dev, 0xf0, 0x0000);
1914                } else {
1915                        i2c_w2(gspca_dev, 0xf0, 0x0002);
1916                        i2c_w2(gspca_dev, 0xc8, 0x8000);
1917                        i2c_w2(gspca_dev, 0xf0, 0x0000);
1918                }
1919                break;
1920        }
1921}
1922
1923static int sd_isoc_init(struct gspca_dev *gspca_dev)
1924{
1925        struct usb_interface *intf;
1926        u32 flags = gspca_dev->cam.cam_mode[(int)gspca_dev->curr_mode].priv;
1927
1928        /*
1929         * When using the SN9C20X_I420 fmt the sn9c20x needs more bandwidth
1930         * than our regular bandwidth calculations reserve, so we force the
1931         * use of a specific altsetting when using the SN9C20X_I420 fmt.
1932         */
1933        if (!(flags & (MODE_RAW | MODE_JPEG))) {
1934                intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface);
1935
1936                if (intf->num_altsetting != 9) {
1937                        pr_warn("sn9c20x camera with unknown number of alt settings (%d), please report!\n",
1938                                intf->num_altsetting);
1939                        gspca_dev->alt = intf->num_altsetting;
1940                        return 0;
1941                }
1942
1943                switch (gspca_dev->pixfmt.width) {
1944                case 160: /* 160x120 */
1945                        gspca_dev->alt = 2;
1946                        break;
1947                case 320: /* 320x240 */
1948                        gspca_dev->alt = 6;
1949                        break;
1950                default:  /* >= 640x480 */
1951                        gspca_dev->alt = 9;
1952                        break;
1953                }
1954        }
1955
1956        return 0;
1957}
1958
1959#define HW_WIN(mode, hstart, vstart) \
1960((const u8 []){hstart, 0, vstart, 0, \
1961(mode & MODE_SXGA ? 1280 >> 4 : 640 >> 4), \
1962(mode & MODE_SXGA ? 1024 >> 3 : 480 >> 3)})
1963
1964#define CLR_WIN(width, height) \
1965((const u8 [])\
1966{0, width >> 2, 0, height >> 1,\
1967((width >> 10) & 0x01) | ((height >> 8) & 0x6)})
1968
1969static int sd_start(struct gspca_dev *gspca_dev)
1970{
1971        struct sd *sd = (struct sd *) gspca_dev;
1972        int mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
1973        int width = gspca_dev->pixfmt.width;
1974        int height = gspca_dev->pixfmt.height;
1975        u8 fmt, scale = 0;
1976
1977        jpeg_define(sd->jpeg_hdr, height, width,
1978                        0x21);
1979        jpeg_set_qual(sd->jpeg_hdr, v4l2_ctrl_g_ctrl(sd->jpegqual));
1980
1981        if (mode & MODE_RAW)
1982                fmt = 0x2d;
1983        else if (mode & MODE_JPEG)
1984                fmt = 0x24;
1985        else
1986                fmt = 0x2f;     /* YUV 420 */
1987        sd->fmt = fmt;
1988
1989        switch (mode & SCALE_MASK) {
1990        case SCALE_1280x1024:
1991                scale = 0xc0;
1992                pr_info("Set 1280x1024\n");
1993                break;
1994        case SCALE_640x480:
1995                scale = 0x80;
1996                pr_info("Set 640x480\n");
1997                break;
1998        case SCALE_320x240:
1999                scale = 0x90;
2000                pr_info("Set 320x240\n");
2001                break;
2002        case SCALE_160x120:
2003                scale = 0xa0;
2004                pr_info("Set 160x120\n");
2005                break;
2006        }
2007
2008        configure_sensor_output(gspca_dev, mode);
2009        reg_w(gspca_dev, 0x1100, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64);
2010        reg_w(gspca_dev, 0x1140, &sd->jpeg_hdr[JPEG_QT1_OFFSET], 64);
2011        reg_w(gspca_dev, 0x10fb, CLR_WIN(width, height), 5);
2012        reg_w(gspca_dev, 0x1180, HW_WIN(mode, sd->hstart, sd->vstart), 6);
2013        reg_w1(gspca_dev, 0x1189, scale);
2014        reg_w1(gspca_dev, 0x10e0, fmt);
2015
2016        set_cmatrix(gspca_dev, v4l2_ctrl_g_ctrl(sd->brightness),
2017                        v4l2_ctrl_g_ctrl(sd->contrast),
2018                        v4l2_ctrl_g_ctrl(sd->saturation),
2019                        v4l2_ctrl_g_ctrl(sd->hue));
2020        set_gamma(gspca_dev, v4l2_ctrl_g_ctrl(sd->gamma));
2021        set_redblue(gspca_dev, v4l2_ctrl_g_ctrl(sd->blue),
2022                        v4l2_ctrl_g_ctrl(sd->red));
2023        if (sd->gain)
2024                set_gain(gspca_dev, v4l2_ctrl_g_ctrl(sd->gain));
2025        if (sd->exposure)
2026                set_exposure(gspca_dev, v4l2_ctrl_g_ctrl(sd->exposure));
2027        if (sd->hflip)
2028                set_hvflip(gspca_dev, v4l2_ctrl_g_ctrl(sd->hflip),
2029                                v4l2_ctrl_g_ctrl(sd->vflip));
2030
2031        reg_w1(gspca_dev, 0x1007, 0x20);
2032        reg_w1(gspca_dev, 0x1061, 0x03);
2033
2034        /* if JPEG, prepare the compression quality update */
2035        if (mode & MODE_JPEG) {
2036                sd->pktsz = sd->npkt = 0;
2037                sd->nchg = 0;
2038        }
2039
2040        return gspca_dev->usb_err;
2041}
2042
2043static void sd_stopN(struct gspca_dev *gspca_dev)
2044{
2045        reg_w1(gspca_dev, 0x1007, 0x00);
2046        reg_w1(gspca_dev, 0x1061, 0x01);
2047}
2048
2049/* called on streamoff with alt==0 and on disconnect */
2050/* the usb_lock is held at entry - restore on exit */
2051static void sd_stop0(struct gspca_dev *gspca_dev)
2052{
2053        struct sd *sd = (struct sd *) gspca_dev;
2054
2055        mutex_unlock(&gspca_dev->usb_lock);
2056        flush_work(&sd->work);
2057        mutex_lock(&gspca_dev->usb_lock);
2058}
2059
2060static void do_autoexposure(struct gspca_dev *gspca_dev, u16 avg_lum)
2061{
2062        struct sd *sd = (struct sd *) gspca_dev;
2063        s32 cur_exp = v4l2_ctrl_g_ctrl(sd->exposure);
2064        s32 max = sd->exposure->maximum - sd->exposure_step;
2065        s32 min = sd->exposure->minimum + sd->exposure_step;
2066        s16 new_exp;
2067
2068        /*
2069         * some hardcoded values are present
2070         * like those for maximal/minimal exposure
2071         * and exposure steps
2072         */
2073        if (avg_lum < MIN_AVG_LUM) {
2074                if (cur_exp > max)
2075                        return;
2076
2077                new_exp = cur_exp + sd->exposure_step;
2078                if (new_exp > max)
2079                        new_exp = max;
2080                if (new_exp < min)
2081                        new_exp = min;
2082                v4l2_ctrl_s_ctrl(sd->exposure, new_exp);
2083
2084                sd->older_step = sd->old_step;
2085                sd->old_step = 1;
2086
2087                if (sd->old_step ^ sd->older_step)
2088                        sd->exposure_step /= 2;
2089                else
2090                        sd->exposure_step += 2;
2091        }
2092        if (avg_lum > MAX_AVG_LUM) {
2093                if (cur_exp < min)
2094                        return;
2095                new_exp = cur_exp - sd->exposure_step;
2096                if (new_exp > max)
2097                        new_exp = max;
2098                if (new_exp < min)
2099                        new_exp = min;
2100                v4l2_ctrl_s_ctrl(sd->exposure, new_exp);
2101                sd->older_step = sd->old_step;
2102                sd->old_step = 0;
2103
2104                if (sd->old_step ^ sd->older_step)
2105                        sd->exposure_step /= 2;
2106                else
2107                        sd->exposure_step += 2;
2108        }
2109}
2110
2111static void do_autogain(struct gspca_dev *gspca_dev, u16 avg_lum)
2112{
2113        struct sd *sd = (struct sd *) gspca_dev;
2114        s32 cur_gain = v4l2_ctrl_g_ctrl(sd->gain);
2115
2116        if (avg_lum < MIN_AVG_LUM && cur_gain < sd->gain->maximum)
2117                v4l2_ctrl_s_ctrl(sd->gain, cur_gain + 1);
2118        if (avg_lum > MAX_AVG_LUM && cur_gain > sd->gain->minimum)
2119                v4l2_ctrl_s_ctrl(sd->gain, cur_gain - 1);
2120}
2121
2122static void sd_dqcallback(struct gspca_dev *gspca_dev)
2123{
2124        struct sd *sd = (struct sd *) gspca_dev;
2125        int avg_lum;
2126
2127        if (sd->autogain == NULL || !v4l2_ctrl_g_ctrl(sd->autogain))
2128                return;
2129
2130        avg_lum = atomic_read(&sd->avg_lum);
2131        if (sd->sensor == SENSOR_SOI968)
2132                do_autogain(gspca_dev, avg_lum);
2133        else
2134                do_autoexposure(gspca_dev, avg_lum);
2135}
2136
2137/* JPEG quality update */
2138/* This function is executed from a work queue. */
2139static void qual_upd(struct work_struct *work)
2140{
2141        struct sd *sd = container_of(work, struct sd, work);
2142        struct gspca_dev *gspca_dev = &sd->gspca_dev;
2143        s32 qual = v4l2_ctrl_g_ctrl(sd->jpegqual);
2144
2145        /* To protect gspca_dev->usb_buf and gspca_dev->usb_err */
2146        mutex_lock(&gspca_dev->usb_lock);
2147        gspca_dbg(gspca_dev, D_STREAM, "qual_upd %d%%\n", qual);
2148        gspca_dev->usb_err = 0;
2149        set_quality(gspca_dev, qual);
2150        mutex_unlock(&gspca_dev->usb_lock);
2151}
2152
2153#if IS_ENABLED(CONFIG_INPUT)
2154static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
2155                        u8 *data,               /* interrupt packet */
2156                        int len)                /* interrupt packet length */
2157{
2158        struct sd *sd = (struct sd *) gspca_dev;
2159
2160        if (!(sd->flags & HAS_NO_BUTTON) && len == 1) {
2161                input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
2162                input_sync(gspca_dev->input_dev);
2163                input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
2164                input_sync(gspca_dev->input_dev);
2165                return 0;
2166        }
2167        return -EINVAL;
2168}
2169#endif
2170
2171/* check the JPEG compression */
2172static void transfer_check(struct gspca_dev *gspca_dev,
2173                        u8 *data)
2174{
2175        struct sd *sd = (struct sd *) gspca_dev;
2176        int new_qual, r;
2177
2178        new_qual = 0;
2179
2180        /* if USB error, discard the frame and decrease the quality */
2181        if (data[6] & 0x08) {                           /* USB FIFO full */
2182                gspca_dev->last_packet_type = DISCARD_PACKET;
2183                new_qual = -5;
2184        } else {
2185
2186                /* else, compute the filling rate and a new JPEG quality */
2187                r = (sd->pktsz * 100) /
2188                        (sd->npkt *
2189                                gspca_dev->urb[0]->iso_frame_desc[0].length);
2190                if (r >= 85)
2191                        new_qual = -3;
2192                else if (r < 75)
2193                        new_qual = 2;
2194        }
2195        if (new_qual != 0) {
2196                sd->nchg += new_qual;
2197                if (sd->nchg < -6 || sd->nchg >= 12) {
2198                        /* Note: we are in interrupt context, so we can't
2199                           use v4l2_ctrl_g/s_ctrl here. Access the value
2200                           directly instead. */
2201                        s32 curqual = sd->jpegqual->cur.val;
2202                        sd->nchg = 0;
2203                        new_qual += curqual;
2204                        if (new_qual < sd->jpegqual->minimum)
2205                                new_qual = sd->jpegqual->minimum;
2206                        else if (new_qual > sd->jpegqual->maximum)
2207                                new_qual = sd->jpegqual->maximum;
2208                        if (new_qual != curqual) {
2209                                sd->jpegqual->cur.val = new_qual;
2210                                schedule_work(&sd->work);
2211                        }
2212                }
2213        } else {
2214                sd->nchg = 0;
2215        }
2216        sd->pktsz = sd->npkt = 0;
2217}
2218
2219static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2220                        u8 *data,                       /* isoc packet */
2221                        int len)                        /* iso packet length */
2222{
2223        struct sd *sd = (struct sd *) gspca_dev;
2224        int avg_lum, is_jpeg;
2225        static const u8 frame_header[] = {
2226                0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96
2227        };
2228
2229        is_jpeg = (sd->fmt & 0x03) == 0;
2230        if (len >= 64 && memcmp(data, frame_header, 6) == 0) {
2231                avg_lum = ((data[35] >> 2) & 3) |
2232                           (data[20] << 2) |
2233                           (data[19] << 10);
2234                avg_lum += ((data[35] >> 4) & 3) |
2235                            (data[22] << 2) |
2236                            (data[21] << 10);
2237                avg_lum += ((data[35] >> 6) & 3) |
2238                            (data[24] << 2) |
2239                            (data[23] << 10);
2240                avg_lum += (data[36] & 3) |
2241                           (data[26] << 2) |
2242                           (data[25] << 10);
2243                avg_lum += ((data[36] >> 2) & 3) |
2244                            (data[28] << 2) |
2245                            (data[27] << 10);
2246                avg_lum += ((data[36] >> 4) & 3) |
2247                            (data[30] << 2) |
2248                            (data[29] << 10);
2249                avg_lum += ((data[36] >> 6) & 3) |
2250                            (data[32] << 2) |
2251                            (data[31] << 10);
2252                avg_lum += ((data[44] >> 4) & 3) |
2253                            (data[34] << 2) |
2254                            (data[33] << 10);
2255                avg_lum >>= 9;
2256                atomic_set(&sd->avg_lum, avg_lum);
2257
2258                if (is_jpeg)
2259                        transfer_check(gspca_dev, data);
2260
2261                gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
2262                len -= 64;
2263                if (len == 0)
2264                        return;
2265                data += 64;
2266        }
2267        if (gspca_dev->last_packet_type == LAST_PACKET) {
2268                if (is_jpeg) {
2269                        gspca_frame_add(gspca_dev, FIRST_PACKET,
2270                                sd->jpeg_hdr, JPEG_HDR_SZ);
2271                        gspca_frame_add(gspca_dev, INTER_PACKET,
2272                                data, len);
2273                } else {
2274                        gspca_frame_add(gspca_dev, FIRST_PACKET,
2275                                data, len);
2276                }
2277        } else {
2278                /* if JPEG, count the packets and their size */
2279                if (is_jpeg) {
2280                        sd->npkt++;
2281                        sd->pktsz += len;
2282                }
2283                gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
2284        }
2285}
2286
2287/* sub-driver description */
2288static const struct sd_desc sd_desc = {
2289        .name = KBUILD_MODNAME,
2290        .config = sd_config,
2291        .init = sd_init,
2292        .init_controls = sd_init_controls,
2293        .isoc_init = sd_isoc_init,
2294        .start = sd_start,
2295        .stopN = sd_stopN,
2296        .stop0 = sd_stop0,
2297        .pkt_scan = sd_pkt_scan,
2298#if IS_ENABLED(CONFIG_INPUT)
2299        .int_pkt_scan = sd_int_pkt_scan,
2300#endif
2301        .dq_callback = sd_dqcallback,
2302#ifdef CONFIG_VIDEO_ADV_DEBUG
2303        .set_register = sd_dbg_s_register,
2304        .get_register = sd_dbg_g_register,
2305        .get_chip_info = sd_chip_info,
2306#endif
2307};
2308
2309#define SN9C20X(sensor, i2c_addr, flags) \
2310        .driver_info =  ((flags & 0xff) << 16) \
2311                        | (SENSOR_ ## sensor << 8) \
2312                        | (i2c_addr)
2313
2314static const struct usb_device_id device_table[] = {
2315        {USB_DEVICE(0x0c45, 0x6240), SN9C20X(MT9M001, 0x5d, 0)},
2316        {USB_DEVICE(0x0c45, 0x6242), SN9C20X(MT9M111, 0x5d, 0)},
2317        {USB_DEVICE(0x0c45, 0x6248), SN9C20X(OV9655, 0x30, 0)},
2318        {USB_DEVICE(0x0c45, 0x624c), SN9C20X(MT9M112, 0x5d, 0)},
2319        {USB_DEVICE(0x0c45, 0x624e), SN9C20X(SOI968, 0x30, LED_REVERSE)},
2320        {USB_DEVICE(0x0c45, 0x624f), SN9C20X(OV9650, 0x30,
2321                                             (FLIP_DETECT | HAS_NO_BUTTON))},
2322        {USB_DEVICE(0x0c45, 0x6251), SN9C20X(OV9650, 0x30, 0)},
2323        {USB_DEVICE(0x0c45, 0x6253), SN9C20X(OV9650, 0x30, 0)},
2324        {USB_DEVICE(0x0c45, 0x6260), SN9C20X(OV7670, 0x21, 0)},
2325        {USB_DEVICE(0x0c45, 0x6270), SN9C20X(MT9VPRB, 0x00, 0)},
2326        {USB_DEVICE(0x0c45, 0x627b), SN9C20X(OV7660, 0x21, FLIP_DETECT)},
2327        {USB_DEVICE(0x0c45, 0x627c), SN9C20X(HV7131R, 0x11, 0)},
2328        {USB_DEVICE(0x0c45, 0x627f), SN9C20X(OV9650, 0x30, 0)},
2329        {USB_DEVICE(0x0c45, 0x6280), SN9C20X(MT9M001, 0x5d, 0)},
2330        {USB_DEVICE(0x0c45, 0x6282), SN9C20X(MT9M111, 0x5d, 0)},
2331        {USB_DEVICE(0x0c45, 0x6288), SN9C20X(OV9655, 0x30, 0)},
2332        {USB_DEVICE(0x0c45, 0x628c), SN9C20X(MT9M112, 0x5d, 0)},
2333        {USB_DEVICE(0x0c45, 0x628e), SN9C20X(SOI968, 0x30, 0)},
2334        {USB_DEVICE(0x0c45, 0x628f), SN9C20X(OV9650, 0x30, 0)},
2335        {USB_DEVICE(0x0c45, 0x62a0), SN9C20X(OV7670, 0x21, 0)},
2336        {USB_DEVICE(0x0c45, 0x62b0), SN9C20X(MT9VPRB, 0x00, 0)},
2337        {USB_DEVICE(0x0c45, 0x62b3), SN9C20X(OV9655, 0x30, LED_REVERSE)},
2338        {USB_DEVICE(0x0c45, 0x62bb), SN9C20X(OV7660, 0x21, LED_REVERSE)},
2339        {USB_DEVICE(0x0c45, 0x62bc), SN9C20X(HV7131R, 0x11, 0)},
2340        {USB_DEVICE(0x045e, 0x00f4), SN9C20X(OV9650, 0x30, 0)},
2341        {USB_DEVICE(0x145f, 0x013d), SN9C20X(OV7660, 0x21, 0)},
2342        {USB_DEVICE(0x0458, 0x7029), SN9C20X(HV7131R, 0x11, 0)},
2343        {USB_DEVICE(0x0458, 0x7045), SN9C20X(MT9M112, 0x5d, LED_REVERSE)},
2344        {USB_DEVICE(0x0458, 0x704a), SN9C20X(MT9M112, 0x5d, 0)},
2345        {USB_DEVICE(0x0458, 0x704c), SN9C20X(MT9M112, 0x5d, 0)},
2346        {USB_DEVICE(0xa168, 0x0610), SN9C20X(HV7131R, 0x11, 0)},
2347        {USB_DEVICE(0xa168, 0x0611), SN9C20X(HV7131R, 0x11, 0)},
2348        {USB_DEVICE(0xa168, 0x0613), SN9C20X(HV7131R, 0x11, 0)},
2349        {USB_DEVICE(0xa168, 0x0618), SN9C20X(HV7131R, 0x11, 0)},
2350        {USB_DEVICE(0xa168, 0x0614), SN9C20X(MT9M111, 0x5d, 0)},
2351        {USB_DEVICE(0xa168, 0x0615), SN9C20X(MT9M111, 0x5d, 0)},
2352        {USB_DEVICE(0xa168, 0x0617), SN9C20X(MT9M111, 0x5d, 0)},
2353        {}
2354};
2355MODULE_DEVICE_TABLE(usb, device_table);
2356
2357/* -- device connect -- */
2358static int sd_probe(struct usb_interface *intf,
2359                    const struct usb_device_id *id)
2360{
2361        return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
2362                                THIS_MODULE);
2363}
2364
2365static struct usb_driver sd_driver = {
2366        .name = KBUILD_MODNAME,
2367        .id_table = device_table,
2368        .probe = sd_probe,
2369        .disconnect = gspca_disconnect,
2370#ifdef CONFIG_PM
2371        .suspend = gspca_suspend,
2372        .resume = gspca_resume,
2373        .reset_resume = gspca_resume,
2374#endif
2375};
2376
2377module_usb_driver(sd_driver);
2378