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