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