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