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