Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *  Sonix sn9c201 sn9c202 library
0004  *
0005  * Copyright (C) 2012 Jean-Francois Moine <http://moinejf.free.fr>
0006  *  Copyright (C) 2008-2009 microdia project <microdia@googlegroups.com>
0007  *  Copyright (C) 2009 Brian Johnson <brijohn@gmail.com>
0008  */
0009 
0010 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0011 
0012 #include <linux/input.h>
0013 
0014 #include "gspca.h"
0015 #include "jpeg.h"
0016 
0017 #include <linux/dmi.h>
0018 
0019 MODULE_AUTHOR("Brian Johnson <brijohn@gmail.com>, microdia project <microdia@googlegroups.com>");
0020 MODULE_DESCRIPTION("GSPCA/SN9C20X USB Camera Driver");
0021 MODULE_LICENSE("GPL");
0022 
0023 /*
0024  * Pixel format private data
0025  */
0026 #define SCALE_MASK  0x0f
0027 #define SCALE_160x120   0
0028 #define SCALE_320x240   1
0029 #define SCALE_640x480   2
0030 #define SCALE_1280x1024 3
0031 #define MODE_RAW    0x10
0032 #define MODE_JPEG   0x20
0033 #define MODE_SXGA   0x80
0034 
0035 #define SENSOR_OV9650   0
0036 #define SENSOR_OV9655   1
0037 #define SENSOR_SOI968   2
0038 #define SENSOR_OV7660   3
0039 #define SENSOR_OV7670   4
0040 #define SENSOR_MT9V011  5
0041 #define SENSOR_MT9V111  6
0042 #define SENSOR_MT9V112  7
0043 #define SENSOR_MT9M001  8
0044 #define SENSOR_MT9M111  9
0045 #define SENSOR_MT9M112  10
0046 #define SENSOR_HV7131R  11
0047 #define SENSOR_MT9VPRB  12
0048 
0049 /* camera flags */
0050 #define HAS_NO_BUTTON   0x1
0051 #define LED_REVERSE 0x2 /* some cameras unset gpio to turn on leds */
0052 #define FLIP_DETECT 0x4
0053 #define HAS_LED_TORCH   0x8
0054 
0055 /* specific webcam descriptor */
0056 struct sd {
0057     struct gspca_dev gspca_dev;
0058 
0059     struct { /* color control cluster */
0060         struct v4l2_ctrl *brightness;
0061         struct v4l2_ctrl *contrast;
0062         struct v4l2_ctrl *saturation;
0063         struct v4l2_ctrl *hue;
0064     };
0065     struct { /* blue/red balance control cluster */
0066         struct v4l2_ctrl *blue;
0067         struct v4l2_ctrl *red;
0068     };
0069     struct { /* h/vflip control cluster */
0070         struct v4l2_ctrl *hflip;
0071         struct v4l2_ctrl *vflip;
0072     };
0073     struct v4l2_ctrl *gamma;
0074     struct { /* autogain and exposure or gain control cluster */
0075         struct v4l2_ctrl *autogain;
0076         struct v4l2_ctrl *exposure;
0077         struct v4l2_ctrl *gain;
0078     };
0079     struct v4l2_ctrl *jpegqual;
0080 
0081     struct v4l2_ctrl *led_mode;
0082 
0083     struct work_struct work;
0084 
0085     u32 pktsz;          /* (used by pkt_scan) */
0086     u16 npkt;
0087     s8 nchg;
0088     u8 fmt;             /* (used for JPEG QTAB update */
0089 
0090 #define MIN_AVG_LUM 80
0091 #define MAX_AVG_LUM 130
0092     atomic_t avg_lum;
0093     u8 old_step;
0094     u8 older_step;
0095     u8 exposure_step;
0096 
0097     u8 i2c_addr;
0098     u8 i2c_intf;
0099     u8 sensor;
0100     u8 hstart;
0101     u8 vstart;
0102 
0103     u8 jpeg_hdr[JPEG_HDR_SZ];
0104 
0105     u8 flags;
0106 };
0107 
0108 static void qual_upd(struct work_struct *work);
0109 
0110 struct i2c_reg_u8 {
0111     u8 reg;
0112     u8 val;
0113 };
0114 
0115 struct i2c_reg_u16 {
0116     u8 reg;
0117     u16 val;
0118 };
0119 
0120 static const struct dmi_system_id flip_dmi_table[] = {
0121     {
0122         .ident = "MSI MS-1034",
0123         .matches = {
0124             DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT'L CO.,LTD."),
0125             DMI_MATCH(DMI_PRODUCT_NAME, "MS-1034"),
0126             DMI_MATCH(DMI_PRODUCT_VERSION, "0341")
0127         }
0128     },
0129     {
0130         .ident = "MSI MS-1039",
0131         .matches = {
0132             DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT'L CO.,LTD."),
0133             DMI_MATCH(DMI_PRODUCT_NAME, "MS-1039"),
0134         }
0135     },
0136     {
0137         .ident = "MSI MS-1632",
0138         .matches = {
0139             DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
0140             DMI_MATCH(DMI_BOARD_NAME, "MS-1632")
0141         }
0142     },
0143     {
0144         .ident = "MSI MS-1633X",
0145         .matches = {
0146             DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
0147             DMI_MATCH(DMI_BOARD_NAME, "MS-1633X")
0148         }
0149     },
0150     {
0151         .ident = "MSI MS-1635X",
0152         .matches = {
0153             DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
0154             DMI_MATCH(DMI_BOARD_NAME, "MS-1635X")
0155         }
0156     },
0157     {
0158         .ident = "ASUSTeK W7J",
0159         .matches = {
0160             DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc."),
0161             DMI_MATCH(DMI_BOARD_NAME, "W7J       ")
0162         }
0163     },
0164     {}
0165 };
0166 
0167 static const struct v4l2_pix_format vga_mode[] = {
0168     {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
0169         .bytesperline = 160,
0170         .sizeimage = 160 * 120 * 4 / 8 + 590,
0171         .colorspace = V4L2_COLORSPACE_JPEG,
0172         .priv = SCALE_160x120 | MODE_JPEG},
0173     {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
0174         .bytesperline = 160,
0175         .sizeimage = 160 * 120,
0176         .colorspace = V4L2_COLORSPACE_SRGB,
0177         .priv = SCALE_160x120 | MODE_RAW},
0178     {160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
0179         .bytesperline = 160,
0180         .sizeimage = 240 * 120,
0181         .colorspace = V4L2_COLORSPACE_SRGB,
0182         .priv = SCALE_160x120},
0183     {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
0184         .bytesperline = 320,
0185         .sizeimage = 320 * 240 * 4 / 8 + 590,
0186         .colorspace = V4L2_COLORSPACE_JPEG,
0187         .priv = SCALE_320x240 | MODE_JPEG},
0188     {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
0189         .bytesperline = 320,
0190         .sizeimage = 320 * 240 ,
0191         .colorspace = V4L2_COLORSPACE_SRGB,
0192         .priv = SCALE_320x240 | MODE_RAW},
0193     {320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
0194         .bytesperline = 320,
0195         .sizeimage = 480 * 240 ,
0196         .colorspace = V4L2_COLORSPACE_SRGB,
0197         .priv = SCALE_320x240},
0198     {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
0199         .bytesperline = 640,
0200         .sizeimage = 640 * 480 * 4 / 8 + 590,
0201         .colorspace = V4L2_COLORSPACE_JPEG,
0202         .priv = SCALE_640x480 | MODE_JPEG},
0203     {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
0204         .bytesperline = 640,
0205         .sizeimage = 640 * 480,
0206         .colorspace = V4L2_COLORSPACE_SRGB,
0207         .priv = SCALE_640x480 | MODE_RAW},
0208     {640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
0209         .bytesperline = 640,
0210         .sizeimage = 960 * 480,
0211         .colorspace = V4L2_COLORSPACE_SRGB,
0212         .priv = SCALE_640x480},
0213 };
0214 
0215 static const struct v4l2_pix_format sxga_mode[] = {
0216     {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
0217         .bytesperline = 160,
0218         .sizeimage = 160 * 120 * 4 / 8 + 590,
0219         .colorspace = V4L2_COLORSPACE_JPEG,
0220         .priv = SCALE_160x120 | MODE_JPEG},
0221     {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
0222         .bytesperline = 160,
0223         .sizeimage = 160 * 120,
0224         .colorspace = V4L2_COLORSPACE_SRGB,
0225         .priv = SCALE_160x120 | MODE_RAW},
0226     {160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
0227         .bytesperline = 160,
0228         .sizeimage = 240 * 120,
0229         .colorspace = V4L2_COLORSPACE_SRGB,
0230         .priv = SCALE_160x120},
0231     {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
0232         .bytesperline = 320,
0233         .sizeimage = 320 * 240 * 4 / 8 + 590,
0234         .colorspace = V4L2_COLORSPACE_JPEG,
0235         .priv = SCALE_320x240 | MODE_JPEG},
0236     {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
0237         .bytesperline = 320,
0238         .sizeimage = 320 * 240 ,
0239         .colorspace = V4L2_COLORSPACE_SRGB,
0240         .priv = SCALE_320x240 | MODE_RAW},
0241     {320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
0242         .bytesperline = 320,
0243         .sizeimage = 480 * 240 ,
0244         .colorspace = V4L2_COLORSPACE_SRGB,
0245         .priv = SCALE_320x240},
0246     {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
0247         .bytesperline = 640,
0248         .sizeimage = 640 * 480 * 4 / 8 + 590,
0249         .colorspace = V4L2_COLORSPACE_JPEG,
0250         .priv = SCALE_640x480 | MODE_JPEG},
0251     {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
0252         .bytesperline = 640,
0253         .sizeimage = 640 * 480,
0254         .colorspace = V4L2_COLORSPACE_SRGB,
0255         .priv = SCALE_640x480 | MODE_RAW},
0256     {640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
0257         .bytesperline = 640,
0258         .sizeimage = 960 * 480,
0259         .colorspace = V4L2_COLORSPACE_SRGB,
0260         .priv = SCALE_640x480},
0261     {1280, 1024, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
0262         .bytesperline = 1280,
0263         .sizeimage = 1280 * 1024,
0264         .colorspace = V4L2_COLORSPACE_SRGB,
0265         .priv = SCALE_1280x1024 | MODE_RAW | MODE_SXGA},
0266 };
0267 
0268 static const struct v4l2_pix_format mono_mode[] = {
0269     {160, 120, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
0270         .bytesperline = 160,
0271         .sizeimage = 160 * 120,
0272         .colorspace = V4L2_COLORSPACE_SRGB,
0273         .priv = SCALE_160x120 | MODE_RAW},
0274     {320, 240, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
0275         .bytesperline = 320,
0276         .sizeimage = 320 * 240 ,
0277         .colorspace = V4L2_COLORSPACE_SRGB,
0278         .priv = SCALE_320x240 | MODE_RAW},
0279     {640, 480, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
0280         .bytesperline = 640,
0281         .sizeimage = 640 * 480,
0282         .colorspace = V4L2_COLORSPACE_SRGB,
0283         .priv = SCALE_640x480 | MODE_RAW},
0284     {1280, 1024, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
0285         .bytesperline = 1280,
0286         .sizeimage = 1280 * 1024,
0287         .colorspace = V4L2_COLORSPACE_SRGB,
0288         .priv = SCALE_1280x1024 | MODE_RAW | MODE_SXGA},
0289 };
0290 
0291 static const s16 hsv_red_x[] = {
0292     41,  44,  46,  48,  50,  52,  54,  56,
0293     58,  60,  62,  64,  66,  68,  70,  72,
0294     74,  76,  78,  80,  81,  83,  85,  87,
0295     88,  90,  92,  93,  95,  97,  98, 100,
0296     101, 102, 104, 105, 107, 108, 109, 110,
0297     112, 113, 114, 115, 116, 117, 118, 119,
0298     120, 121, 122, 123, 123, 124, 125, 125,
0299     126, 127, 127, 128, 128, 129, 129, 129,
0300     130, 130, 130, 130, 131, 131, 131, 131,
0301     131, 131, 131, 131, 130, 130, 130, 130,
0302     129, 129, 129, 128, 128, 127, 127, 126,
0303     125, 125, 124, 123, 122, 122, 121, 120,
0304     119, 118, 117, 116, 115, 114, 112, 111,
0305     110, 109, 107, 106, 105, 103, 102, 101,
0306     99,  98,  96,  94,  93,  91,  90,  88,
0307     86,  84,  83,  81,  79,  77,  75,  74,
0308     72,  70,  68,  66,  64,  62,  60,  58,
0309     56,  54,  52,  49,  47,  45,  43,  41,
0310     39,  36,  34,  32,  30,  28,  25,  23,
0311     21,  19,  16,  14,  12,   9,   7,   5,
0312     3,   0,  -1,  -3,  -6,  -8, -10, -12,
0313     -15, -17, -19, -22, -24, -26, -28, -30,
0314     -33, -35, -37, -39, -41, -44, -46, -48,
0315     -50, -52, -54, -56, -58, -60, -62, -64,
0316     -66, -68, -70, -72, -74, -76, -78, -80,
0317     -81, -83, -85, -87, -88, -90, -92, -93,
0318     -95, -97, -98, -100, -101, -102, -104, -105,
0319     -107, -108, -109, -110, -112, -113, -114, -115,
0320     -116, -117, -118, -119, -120, -121, -122, -123,
0321     -123, -124, -125, -125, -126, -127, -127, -128,
0322     -128, -128, -128, -128, -128, -128, -128, -128,
0323     -128, -128, -128, -128, -128, -128, -128, -128,
0324     -128, -128, -128, -128, -128, -128, -128, -128,
0325     -128, -127, -127, -126, -125, -125, -124, -123,
0326     -122, -122, -121, -120, -119, -118, -117, -116,
0327     -115, -114, -112, -111, -110, -109, -107, -106,
0328     -105, -103, -102, -101, -99, -98, -96, -94,
0329     -93, -91, -90, -88, -86, -84, -83, -81,
0330     -79, -77, -75, -74, -72, -70, -68, -66,
0331     -64, -62, -60, -58, -56, -54, -52, -49,
0332     -47, -45, -43, -41, -39, -36, -34, -32,
0333     -30, -28, -25, -23, -21, -19, -16, -14,
0334     -12,  -9,  -7,  -5,  -3,   0,   1,   3,
0335     6,   8,  10,  12,  15,  17,  19,  22,
0336     24,  26,  28,  30,  33,  35,  37,  39, 41
0337 };
0338 
0339 static const s16 hsv_red_y[] = {
0340     82,  80,  78,  76,  74,  73,  71,  69,
0341     67,  65,  63,  61,  58,  56,  54,  52,
0342     50,  48,  46,  44,  41,  39,  37,  35,
0343     32,  30,  28,  26,  23,  21,  19,  16,
0344     14,  12,  10,   7,   5,   3,   0,  -1,
0345     -3,  -6,  -8, -10, -13, -15, -17, -19,
0346     -22, -24, -26, -29, -31, -33, -35, -38,
0347     -40, -42, -44, -46, -48, -51, -53, -55,
0348     -57, -59, -61, -63, -65, -67, -69, -71,
0349     -73, -75, -77, -79, -81, -82, -84, -86,
0350     -88, -89, -91, -93, -94, -96, -98, -99,
0351     -101, -102, -104, -105, -106, -108, -109, -110,
0352     -112, -113, -114, -115, -116, -117, -119, -120,
0353     -120, -121, -122, -123, -124, -125, -126, -126,
0354     -127, -128, -128, -128, -128, -128, -128, -128,
0355     -128, -128, -128, -128, -128, -128, -128, -128,
0356     -128, -128, -128, -128, -128, -128, -128, -128,
0357     -128, -128, -128, -128, -128, -128, -128, -128,
0358     -127, -127, -126, -125, -125, -124, -123, -122,
0359     -121, -120, -119, -118, -117, -116, -115, -114,
0360     -113, -111, -110, -109, -107, -106, -105, -103,
0361     -102, -100, -99, -97, -96, -94, -92, -91,
0362     -89, -87, -85, -84, -82, -80, -78, -76,
0363     -74, -73, -71, -69, -67, -65, -63, -61,
0364     -58, -56, -54, -52, -50, -48, -46, -44,
0365     -41, -39, -37, -35, -32, -30, -28, -26,
0366     -23, -21, -19, -16, -14, -12, -10,  -7,
0367     -5,  -3,   0,   1,   3,   6,   8,  10,
0368     13,  15,  17,  19,  22,  24,  26,  29,
0369     31,  33,  35,  38,  40,  42,  44,  46,
0370     48,  51,  53,  55,  57,  59,  61,  63,
0371     65,  67,  69,  71,  73,  75,  77,  79,
0372     81,  82,  84,  86,  88,  89,  91,  93,
0373     94,  96,  98,  99, 101, 102, 104, 105,
0374     106, 108, 109, 110, 112, 113, 114, 115,
0375     116, 117, 119, 120, 120, 121, 122, 123,
0376     124, 125, 126, 126, 127, 128, 128, 129,
0377     129, 130, 130, 131, 131, 131, 131, 132,
0378     132, 132, 132, 132, 132, 132, 132, 132,
0379     132, 132, 132, 131, 131, 131, 130, 130,
0380     130, 129, 129, 128, 127, 127, 126, 125,
0381     125, 124, 123, 122, 121, 120, 119, 118,
0382     117, 116, 115, 114, 113, 111, 110, 109,
0383     107, 106, 105, 103, 102, 100,  99,  97,
0384     96, 94, 92, 91, 89, 87, 85, 84, 82
0385 };
0386 
0387 static const s16 hsv_green_x[] = {
0388     -124, -124, -125, -125, -125, -125, -125, -125,
0389     -125, -126, -126, -125, -125, -125, -125, -125,
0390     -125, -124, -124, -124, -123, -123, -122, -122,
0391     -121, -121, -120, -120, -119, -118, -117, -117,
0392     -116, -115, -114, -113, -112, -111, -110, -109,
0393     -108, -107, -105, -104, -103, -102, -100, -99,
0394     -98, -96, -95, -93, -92, -91, -89, -87,
0395     -86, -84, -83, -81, -79, -77, -76, -74,
0396     -72, -70, -69, -67, -65, -63, -61, -59,
0397     -57, -55, -53, -51, -49, -47, -45, -43,
0398     -41, -39, -37, -35, -33, -30, -28, -26,
0399     -24, -22, -20, -18, -15, -13, -11,  -9,
0400     -7,  -4,  -2,   0,   1,   3,   6,   8,
0401     10,  12,  14,  17,  19,  21,  23,  25,
0402     27,  29,  32,  34,  36,  38,  40,  42,
0403     44,  46,  48,  50,  52,  54,  56,  58,
0404     60,  62,  64,  66,  68,  70,  71,  73,
0405     75,  77,  78,  80,  82,  83,  85,  87,
0406     88,  90,  91,  93,  94,  96,  97,  98,
0407     100, 101, 102, 104, 105, 106, 107, 108,
0408     109, 111, 112, 113, 113, 114, 115, 116,
0409     117, 118, 118, 119, 120, 120, 121, 122,
0410     122, 123, 123, 124, 124, 124, 125, 125,
0411     125, 125, 125, 125, 125, 126, 126, 125,
0412     125, 125, 125, 125, 125, 124, 124, 124,
0413     123, 123, 122, 122, 121, 121, 120, 120,
0414     119, 118, 117, 117, 116, 115, 114, 113,
0415     112, 111, 110, 109, 108, 107, 105, 104,
0416     103, 102, 100,  99,  98,  96,  95,  93,
0417     92,  91,  89,  87,  86,  84,  83,  81,
0418     79,  77,  76,  74,  72,  70,  69,  67,
0419     65,  63,  61,  59,  57,  55,  53,  51,
0420     49,  47,  45,  43,  41,  39,  37,  35,
0421     33,  30,  28,  26,  24,  22,  20,  18,
0422     15,  13,  11,   9,   7,   4,   2,   0,
0423     -1,  -3,  -6,  -8, -10, -12, -14, -17,
0424     -19, -21, -23, -25, -27, -29, -32, -34,
0425     -36, -38, -40, -42, -44, -46, -48, -50,
0426     -52, -54, -56, -58, -60, -62, -64, -66,
0427     -68, -70, -71, -73, -75, -77, -78, -80,
0428     -82, -83, -85, -87, -88, -90, -91, -93,
0429     -94, -96, -97, -98, -100, -101, -102, -104,
0430     -105, -106, -107, -108, -109, -111, -112, -113,
0431     -113, -114, -115, -116, -117, -118, -118, -119,
0432     -120, -120, -121, -122, -122, -123, -123, -124, -124
0433 };
0434 
0435 static const s16 hsv_green_y[] = {
0436     -100, -99, -98, -97, -95, -94, -93, -91,
0437     -90, -89, -87, -86, -84, -83, -81, -80,
0438     -78, -76, -75, -73, -71, -70, -68, -66,
0439     -64, -63, -61, -59, -57, -55, -53, -51,
0440     -49, -48, -46, -44, -42, -40, -38, -36,
0441     -34, -32, -30, -27, -25, -23, -21, -19,
0442     -17, -15, -13, -11,  -9,  -7,  -4,  -2,
0443     0,   1,   3,   5,   7,   9,  11,  14,
0444     16,  18,  20,  22,  24,  26,  28,  30,
0445     32,  34,  36,  38,  40,  42,  44,  46,
0446     48,  50,  52,  54,  56,  58,  59,  61,
0447     63,  65,  67,  68,  70,  72,  74,  75,
0448     77,  78,  80,  82,  83,  85,  86,  88,
0449     89,  90,  92,  93,  95,  96,  97,  98,
0450     100, 101, 102, 103, 104, 105, 106, 107,
0451     108, 109, 110, 111, 112, 112, 113, 114,
0452     115, 115, 116, 116, 117, 117, 118, 118,
0453     119, 119, 119, 120, 120, 120, 120, 120,
0454     121, 121, 121, 121, 121, 121, 120, 120,
0455     120, 120, 120, 119, 119, 119, 118, 118,
0456     117, 117, 116, 116, 115, 114, 114, 113,
0457     112, 111, 111, 110, 109, 108, 107, 106,
0458     105, 104, 103, 102, 100,  99,  98,  97,
0459     95,  94,  93,  91,  90,  89,  87,  86,
0460     84,  83,  81,  80,  78,  76,  75,  73,
0461     71,  70,  68,  66,  64,  63,  61,  59,
0462     57,  55,  53,  51,  49,  48,  46,  44,
0463     42,  40,  38,  36,  34,  32,  30,  27,
0464     25,  23,  21,  19,  17,  15,  13,  11,
0465     9,   7,   4,   2,   0,  -1,  -3,  -5,
0466     -7,  -9, -11, -14, -16, -18, -20, -22,
0467     -24, -26, -28, -30, -32, -34, -36, -38,
0468     -40, -42, -44, -46, -48, -50, -52, -54,
0469     -56, -58, -59, -61, -63, -65, -67, -68,
0470     -70, -72, -74, -75, -77, -78, -80, -82,
0471     -83, -85, -86, -88, -89, -90, -92, -93,
0472     -95, -96, -97, -98, -100, -101, -102, -103,
0473     -104, -105, -106, -107, -108, -109, -110, -111,
0474     -112, -112, -113, -114, -115, -115, -116, -116,
0475     -117, -117, -118, -118, -119, -119, -119, -120,
0476     -120, -120, -120, -120, -121, -121, -121, -121,
0477     -121, -121, -120, -120, -120, -120, -120, -119,
0478     -119, -119, -118, -118, -117, -117, -116, -116,
0479     -115, -114, -114, -113, -112, -111, -111, -110,
0480     -109, -108, -107, -106, -105, -104, -103, -102, -100
0481 };
0482 
0483 static const s16 hsv_blue_x[] = {
0484     112, 113, 114, 114, 115, 116, 117, 117,
0485     118, 118, 119, 119, 120, 120, 120, 121,
0486     121, 121, 122, 122, 122, 122, 122, 122,
0487     122, 122, 122, 122, 122, 122, 121, 121,
0488     121, 120, 120, 120, 119, 119, 118, 118,
0489     117, 116, 116, 115, 114, 113, 113, 112,
0490     111, 110, 109, 108, 107, 106, 105, 104,
0491     103, 102, 100,  99,  98,  97,  95,  94,
0492     93,  91,  90,  88,  87,  85,  84,  82,
0493     80,  79,  77,  76,  74,  72,  70,  69,
0494     67,  65,  63,  61,  60,  58,  56,  54,
0495     52,  50,  48,  46,  44,  42,  40,  38,
0496     36,  34,  32,  30,  28,  26,  24,  22,
0497     19,  17,  15,  13,  11,   9,   7,   5,
0498     2,   0,  -1,  -3,  -5,  -7,  -9, -12,
0499     -14, -16, -18, -20, -22, -24, -26, -28,
0500     -31, -33, -35, -37, -39, -41, -43, -45,
0501     -47, -49, -51, -53, -54, -56, -58, -60,
0502     -62, -64, -66, -67, -69, -71, -73, -74,
0503     -76, -78, -79, -81, -83, -84, -86, -87,
0504     -89, -90, -92, -93, -94, -96, -97, -98,
0505     -99, -101, -102, -103, -104, -105, -106, -107,
0506     -108, -109, -110, -111, -112, -113, -114, -114,
0507     -115, -116, -117, -117, -118, -118, -119, -119,
0508     -120, -120, -120, -121, -121, -121, -122, -122,
0509     -122, -122, -122, -122, -122, -122, -122, -122,
0510     -122, -122, -121, -121, -121, -120, -120, -120,
0511     -119, -119, -118, -118, -117, -116, -116, -115,
0512     -114, -113, -113, -112, -111, -110, -109, -108,
0513     -107, -106, -105, -104, -103, -102, -100, -99,
0514     -98, -97, -95, -94, -93, -91, -90, -88,
0515     -87, -85, -84, -82, -80, -79, -77, -76,
0516     -74, -72, -70, -69, -67, -65, -63, -61,
0517     -60, -58, -56, -54, -52, -50, -48, -46,
0518     -44, -42, -40, -38, -36, -34, -32, -30,
0519     -28, -26, -24, -22, -19, -17, -15, -13,
0520     -11,  -9,  -7,  -5,  -2,   0,   1,   3,
0521     5,   7,   9,  12,  14,  16,  18,  20,
0522     22,  24,  26,  28,  31,  33,  35,  37,
0523     39,  41,  43,  45,  47,  49,  51,  53,
0524     54,  56,  58,  60,  62,  64,  66,  67,
0525     69,  71,  73,  74,  76,  78,  79,  81,
0526     83,  84,  86,  87,  89,  90,  92,  93,
0527     94,  96,  97,  98,  99, 101, 102, 103,
0528     104, 105, 106, 107, 108, 109, 110, 111, 112
0529 };
0530 
0531 static const s16 hsv_blue_y[] = {
0532     -11, -13, -15, -17, -19, -21, -23, -25,
0533     -27, -29, -31, -33, -35, -37, -39, -41,
0534     -43, -45, -46, -48, -50, -52, -54, -55,
0535     -57, -59, -61, -62, -64, -66, -67, -69,
0536     -71, -72, -74, -75, -77, -78, -80, -81,
0537     -83, -84, -86, -87, -88, -90, -91, -92,
0538     -93, -95, -96, -97, -98, -99, -100, -101,
0539     -102, -103, -104, -105, -106, -106, -107, -108,
0540     -109, -109, -110, -111, -111, -112, -112, -113,
0541     -113, -114, -114, -114, -115, -115, -115, -115,
0542     -116, -116, -116, -116, -116, -116, -116, -116,
0543     -116, -115, -115, -115, -115, -114, -114, -114,
0544     -113, -113, -112, -112, -111, -111, -110, -110,
0545     -109, -108, -108, -107, -106, -105, -104, -103,
0546     -102, -101, -100, -99, -98, -97, -96, -95,
0547     -94, -93, -91, -90, -89, -88, -86, -85,
0548     -84, -82, -81, -79, -78, -76, -75, -73,
0549     -71, -70, -68, -67, -65, -63, -62, -60,
0550     -58, -56, -55, -53, -51, -49, -47, -45,
0551     -44, -42, -40, -38, -36, -34, -32, -30,
0552     -28, -26, -24, -22, -20, -18, -16, -14,
0553     -12, -10,  -8,  -6,  -4,  -2,   0,   1,
0554     3,   5,   7,   9,  11,  13,  15,  17,
0555     19,  21,  23,  25,  27,  29,  31,  33,
0556     35,  37,  39,  41,  43,  45,  46,  48,
0557     50,  52,  54,  55,  57,  59,  61,  62,
0558     64,  66,  67,  69,  71,  72,  74,  75,
0559     77,  78,  80,  81,  83,  84,  86,  87,
0560     88,  90,  91,  92,  93,  95,  96,  97,
0561     98,  99, 100, 101, 102, 103, 104, 105,
0562     106, 106, 107, 108, 109, 109, 110, 111,
0563     111, 112, 112, 113, 113, 114, 114, 114,
0564     115, 115, 115, 115, 116, 116, 116, 116,
0565     116, 116, 116, 116, 116, 115, 115, 115,
0566     115, 114, 114, 114, 113, 113, 112, 112,
0567     111, 111, 110, 110, 109, 108, 108, 107,
0568     106, 105, 104, 103, 102, 101, 100,  99,
0569     98,  97,  96,  95,  94,  93,  91,  90,
0570     89,  88,  86,  85,  84,  82,  81,  79,
0571     78,  76,  75,  73,  71,  70,  68,  67,
0572     65,  63,  62,  60,  58,  56,  55,  53,
0573     51,  49,  47,  45,  44,  42,  40,  38,
0574     36,  34,  32,  30,  28,  26,  24,  22,
0575     20,  18,  16,  14,  12,  10,   8,   6,
0576     4,   2,   0,  -1,  -3,  -5,  -7,  -9, -11
0577 };
0578 
0579 static const u16 bridge_init[][2] = {
0580     {0x1000, 0x78}, {0x1001, 0x40}, {0x1002, 0x1c},
0581     {0x1020, 0x80}, {0x1061, 0x01}, {0x1067, 0x40},
0582     {0x1068, 0x30}, {0x1069, 0x20}, {0x106a, 0x10},
0583     {0x106b, 0x08}, {0x1188, 0x87}, {0x11a1, 0x00},
0584     {0x11a2, 0x00}, {0x11a3, 0x6a}, {0x11a4, 0x50},
0585     {0x11ab, 0x00}, {0x11ac, 0x00}, {0x11ad, 0x50},
0586     {0x11ae, 0x3c}, {0x118a, 0x04}, {0x0395, 0x04},
0587     {0x11b8, 0x3a}, {0x118b, 0x0e}, {0x10f7, 0x05},
0588     {0x10f8, 0x14}, {0x10fa, 0xff}, {0x10f9, 0x00},
0589     {0x11ba, 0x0a}, {0x11a5, 0x2d}, {0x11a6, 0x2d},
0590     {0x11a7, 0x3a}, {0x11a8, 0x05}, {0x11a9, 0x04},
0591     {0x11aa, 0x3f}, {0x11af, 0x28}, {0x11b0, 0xd8},
0592     {0x11b1, 0x14}, {0x11b2, 0xec}, {0x11b3, 0x32},
0593     {0x11b4, 0xdd}, {0x11b5, 0x32}, {0x11b6, 0xdd},
0594     {0x10e0, 0x2c}, {0x11bc, 0x40}, {0x11bd, 0x01},
0595     {0x11be, 0xf0}, {0x11bf, 0x00}, {0x118c, 0x1f},
0596     {0x118d, 0x1f}, {0x118e, 0x1f}, {0x118f, 0x1f},
0597     {0x1180, 0x01}, {0x1181, 0x00}, {0x1182, 0x01},
0598     {0x1183, 0x00}, {0x1184, 0x50}, {0x1185, 0x80},
0599     {0x1007, 0x00}
0600 };
0601 
0602 /* Gain = (bit[3:0] / 16 + 1) * (bit[4] + 1) * (bit[5] + 1) * (bit[6] + 1) */
0603 static const u8 ov_gain[] = {
0604     0x00 /* 1x */, 0x04 /* 1.25x */, 0x08 /* 1.5x */, 0x0c /* 1.75x */,
0605     0x10 /* 2x */, 0x12 /* 2.25x */, 0x14 /* 2.5x */, 0x16 /* 2.75x */,
0606     0x18 /* 3x */, 0x1a /* 3.25x */, 0x1c /* 3.5x */, 0x1e /* 3.75x */,
0607     0x30 /* 4x */, 0x31 /* 4.25x */, 0x32 /* 4.5x */, 0x33 /* 4.75x */,
0608     0x34 /* 5x */, 0x35 /* 5.25x */, 0x36 /* 5.5x */, 0x37 /* 5.75x */,
0609     0x38 /* 6x */, 0x39 /* 6.25x */, 0x3a /* 6.5x */, 0x3b /* 6.75x */,
0610     0x3c /* 7x */, 0x3d /* 7.25x */, 0x3e /* 7.5x */, 0x3f /* 7.75x */,
0611     0x70 /* 8x */
0612 };
0613 
0614 /* Gain = (bit[8] + 1) * (bit[7] + 1) * (bit[6:0] * 0.03125) */
0615 static const u16 micron1_gain[] = {
0616     /* 1x   1.25x   1.5x    1.75x */
0617     0x0020, 0x0028, 0x0030, 0x0038,
0618     /* 2x   2.25x   2.5x    2.75x */
0619     0x00a0, 0x00a4, 0x00a8, 0x00ac,
0620     /* 3x   3.25x   3.5x    3.75x */
0621     0x00b0, 0x00b4, 0x00b8, 0x00bc,
0622     /* 4x   4.25x   4.5x    4.75x */
0623     0x00c0, 0x00c4, 0x00c8, 0x00cc,
0624     /* 5x   5.25x   5.5x    5.75x */
0625     0x00d0, 0x00d4, 0x00d8, 0x00dc,
0626     /* 6x   6.25x   6.5x    6.75x */
0627     0x00e0, 0x00e4, 0x00e8, 0x00ec,
0628     /* 7x   7.25x   7.5x    7.75x */
0629     0x00f0, 0x00f4, 0x00f8, 0x00fc,
0630     /* 8x */
0631     0x01c0
0632 };
0633 
0634 /* mt9m001 sensor uses a different gain formula then other micron sensors */
0635 /* Gain = (bit[6] + 1) * (bit[5-0] * 0.125) */
0636 static const u16 micron2_gain[] = {
0637     /* 1x   1.25x   1.5x    1.75x */
0638     0x0008, 0x000a, 0x000c, 0x000e,
0639     /* 2x   2.25x   2.5x    2.75x */
0640     0x0010, 0x0012, 0x0014, 0x0016,
0641     /* 3x   3.25x   3.5x    3.75x */
0642     0x0018, 0x001a, 0x001c, 0x001e,
0643     /* 4x   4.25x   4.5x    4.75x */
0644     0x0020, 0x0051, 0x0052, 0x0053,
0645     /* 5x   5.25x   5.5x    5.75x */
0646     0x0054, 0x0055, 0x0056, 0x0057,
0647     /* 6x   6.25x   6.5x    6.75x */
0648     0x0058, 0x0059, 0x005a, 0x005b,
0649     /* 7x   7.25x   7.5x    7.75x */
0650     0x005c, 0x005d, 0x005e, 0x005f,
0651     /* 8x */
0652     0x0060
0653 };
0654 
0655 /* Gain = .5 + bit[7:0] / 16 */
0656 static const u8 hv7131r_gain[] = {
0657     0x08 /* 1x */, 0x0c /* 1.25x */, 0x10 /* 1.5x */, 0x14 /* 1.75x */,
0658     0x18 /* 2x */, 0x1c /* 2.25x */, 0x20 /* 2.5x */, 0x24 /* 2.75x */,
0659     0x28 /* 3x */, 0x2c /* 3.25x */, 0x30 /* 3.5x */, 0x34 /* 3.75x */,
0660     0x38 /* 4x */, 0x3c /* 4.25x */, 0x40 /* 4.5x */, 0x44 /* 4.75x */,
0661     0x48 /* 5x */, 0x4c /* 5.25x */, 0x50 /* 5.5x */, 0x54 /* 5.75x */,
0662     0x58 /* 6x */, 0x5c /* 6.25x */, 0x60 /* 6.5x */, 0x64 /* 6.75x */,
0663     0x68 /* 7x */, 0x6c /* 7.25x */, 0x70 /* 7.5x */, 0x74 /* 7.75x */,
0664     0x78 /* 8x */
0665 };
0666 
0667 static const struct i2c_reg_u8 soi968_init[] = {
0668     {0x0c, 0x00}, {0x0f, 0x1f},
0669     {0x11, 0x80}, {0x38, 0x52}, {0x1e, 0x00},
0670     {0x33, 0x08}, {0x35, 0x8c}, {0x36, 0x0c},
0671     {0x37, 0x04}, {0x45, 0x04}, {0x47, 0xff},
0672     {0x3e, 0x00}, {0x3f, 0x00}, {0x3b, 0x20},
0673     {0x3a, 0x96}, {0x3d, 0x0a}, {0x14, 0x8e},
0674     {0x13, 0x8b}, {0x12, 0x40}, {0x17, 0x13},
0675     {0x18, 0x63}, {0x19, 0x01}, {0x1a, 0x79},
0676     {0x32, 0x24}, {0x03, 0x00}, {0x11, 0x40},
0677     {0x2a, 0x10}, {0x2b, 0xe0}, {0x10, 0x32},
0678     {0x00, 0x00}, {0x01, 0x80}, {0x02, 0x80},
0679 };
0680 
0681 static const struct i2c_reg_u8 ov7660_init[] = {
0682     {0x0e, 0x80}, {0x0d, 0x08}, {0x0f, 0xc3},
0683     {0x04, 0xc3}, {0x10, 0x40}, {0x11, 0x40},
0684     {0x12, 0x05}, {0x13, 0xba}, {0x14, 0x2a},
0685     /* HDG Set hstart and hstop, datasheet default 0x11, 0x61, using
0686        0x10, 0x61 and sd->hstart, vstart = 3, fixes ugly colored borders */
0687     {0x17, 0x10}, {0x18, 0x61},
0688     {0x37, 0x0f}, {0x38, 0x02}, {0x39, 0x43},
0689     {0x3a, 0x00}, {0x69, 0x90}, {0x2d, 0x00},
0690     {0x2e, 0x00}, {0x01, 0x78}, {0x02, 0x50},
0691 };
0692 
0693 static const struct i2c_reg_u8 ov7670_init[] = {
0694     {0x11, 0x80}, {0x3a, 0x04}, {0x12, 0x01},
0695     {0x32, 0xb6}, {0x03, 0x0a}, {0x0c, 0x00}, {0x3e, 0x00},
0696     {0x70, 0x3a}, {0x71, 0x35}, {0x72, 0x11}, {0x73, 0xf0},
0697     {0xa2, 0x02}, {0x13, 0xe0}, {0x00, 0x00}, {0x10, 0x00},
0698     {0x0d, 0x40}, {0x14, 0x28}, {0xa5, 0x05}, {0xab, 0x07},
0699     {0x24, 0x95}, {0x25, 0x33}, {0x26, 0xe3}, {0x9f, 0x75},
0700     {0xa0, 0x65}, {0xa1, 0x0b}, {0xa6, 0xd8}, {0xa7, 0xd8},
0701     {0xa8, 0xf0}, {0xa9, 0x90}, {0xaa, 0x94}, {0x13, 0xe5},
0702     {0x0e, 0x61}, {0x0f, 0x4b}, {0x16, 0x02}, {0x1e, 0x27},
0703     {0x21, 0x02}, {0x22, 0x91}, {0x29, 0x07}, {0x33, 0x0b},
0704     {0x35, 0x0b}, {0x37, 0x1d}, {0x38, 0x71}, {0x39, 0x2a},
0705     {0x3c, 0x78}, {0x4d, 0x40}, {0x4e, 0x20}, {0x69, 0x00},
0706     {0x74, 0x19}, {0x8d, 0x4f}, {0x8e, 0x00}, {0x8f, 0x00},
0707     {0x90, 0x00}, {0x91, 0x00}, {0x96, 0x00}, {0x9a, 0x80},
0708     {0xb0, 0x84}, {0xb1, 0x0c}, {0xb2, 0x0e}, {0xb3, 0x82},
0709     {0xb8, 0x0a}, {0x43, 0x0a}, {0x44, 0xf0}, {0x45, 0x20},
0710     {0x46, 0x7d}, {0x47, 0x29}, {0x48, 0x4a}, {0x59, 0x8c},
0711     {0x5a, 0xa5}, {0x5b, 0xde}, {0x5c, 0x96}, {0x5d, 0x66},
0712     {0x5e, 0x10}, {0x6c, 0x0a}, {0x6d, 0x55}, {0x6e, 0x11},
0713     {0x6f, 0x9e}, {0x6a, 0x40}, {0x01, 0x40}, {0x02, 0x40},
0714     {0x13, 0xe7}, {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x02},
0715     {0x52, 0x1d}, {0x53, 0x56}, {0x54, 0x73}, {0x55, 0x0a},
0716     {0x56, 0x55}, {0x57, 0x80}, {0x58, 0x9e}, {0x41, 0x08},
0717     {0x3f, 0x02}, {0x75, 0x03}, {0x76, 0x63}, {0x4c, 0x04},
0718     {0x77, 0x06}, {0x3d, 0x02}, {0x4b, 0x09}, {0xc9, 0x30},
0719     {0x41, 0x08}, {0x56, 0x48}, {0x34, 0x11}, {0xa4, 0x88},
0720     {0x96, 0x00}, {0x97, 0x30}, {0x98, 0x20}, {0x99, 0x30},
0721     {0x9a, 0x84}, {0x9b, 0x29}, {0x9c, 0x03}, {0x9d, 0x99},
0722     {0x9e, 0x7f}, {0x78, 0x04}, {0x79, 0x01}, {0xc8, 0xf0},
0723     {0x79, 0x0f}, {0xc8, 0x00}, {0x79, 0x10}, {0xc8, 0x7e},
0724     {0x79, 0x0a}, {0xc8, 0x80}, {0x79, 0x0b}, {0xc8, 0x01},
0725     {0x79, 0x0c}, {0xc8, 0x0f}, {0x79, 0x0d}, {0xc8, 0x20},
0726     {0x79, 0x09}, {0xc8, 0x80}, {0x79, 0x02}, {0xc8, 0xc0},
0727     {0x79, 0x03}, {0xc8, 0x40}, {0x79, 0x05}, {0xc8, 0x30},
0728     {0x79, 0x26}, {0x62, 0x20}, {0x63, 0x00}, {0x64, 0x06},
0729     {0x65, 0x00}, {0x66, 0x05}, {0x94, 0x05}, {0x95, 0x0a},
0730     {0x17, 0x13}, {0x18, 0x01}, {0x19, 0x02}, {0x1a, 0x7a},
0731     {0x46, 0x59}, {0x47, 0x30}, {0x58, 0x9a}, {0x59, 0x84},
0732     {0x5a, 0x91}, {0x5b, 0x57}, {0x5c, 0x75}, {0x5d, 0x6d},
0733     {0x5e, 0x13}, {0x64, 0x07}, {0x94, 0x07}, {0x95, 0x0d},
0734     {0xa6, 0xdf}, {0xa7, 0xdf}, {0x48, 0x4d}, {0x51, 0x00},
0735     {0x6b, 0x0a}, {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00},
0736     {0x92, 0x00}, {0x93, 0x00}, {0x55, 0x0a}, {0x56, 0x60},
0737     {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d},
0738     {0x53, 0x56}, {0x54, 0x73}, {0x58, 0x9a}, {0x4f, 0x6e},
0739     {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d}, {0x53, 0x56},
0740     {0x54, 0x73}, {0x58, 0x9a}, {0x3f, 0x01}, {0x7b, 0x03},
0741     {0x7c, 0x09}, {0x7d, 0x16}, {0x7e, 0x38}, {0x7f, 0x47},
0742     {0x80, 0x53}, {0x81, 0x5e}, {0x82, 0x6a}, {0x83, 0x74},
0743     {0x84, 0x80}, {0x85, 0x8c}, {0x86, 0x9b}, {0x87, 0xb2},
0744     {0x88, 0xcc}, {0x89, 0xe5}, {0x7a, 0x24}, {0x3b, 0x00},
0745     {0x9f, 0x76}, {0xa0, 0x65}, {0x13, 0xe2}, {0x6b, 0x0a},
0746     {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00}, {0x92, 0x00},
0747     {0x93, 0x00},
0748 };
0749 
0750 static const struct i2c_reg_u8 ov9650_init[] = {
0751     {0x00, 0x00}, {0x01, 0x78},
0752     {0x02, 0x78}, {0x03, 0x36}, {0x04, 0x03},
0753     {0x05, 0x00}, {0x06, 0x00}, {0x08, 0x00},
0754     {0x09, 0x01}, {0x0c, 0x00}, {0x0d, 0x00},
0755     {0x0e, 0xa0}, {0x0f, 0x52}, {0x10, 0x7c},
0756     {0x11, 0x80}, {0x12, 0x45}, {0x13, 0xc2},
0757     {0x14, 0x2e}, {0x15, 0x00}, {0x16, 0x07},
0758     {0x17, 0x24}, {0x18, 0xc5}, {0x19, 0x00},
0759     {0x1a, 0x3c}, {0x1b, 0x00}, {0x1e, 0x04},
0760     {0x1f, 0x00}, {0x24, 0x78}, {0x25, 0x68},
0761     {0x26, 0xd4}, {0x27, 0x80}, {0x28, 0x80},
0762     {0x29, 0x30}, {0x2a, 0x00}, {0x2b, 0x00},
0763     {0x2c, 0x80}, {0x2d, 0x00}, {0x2e, 0x00},
0764     {0x2f, 0x00}, {0x30, 0x08}, {0x31, 0x30},
0765     {0x32, 0x84}, {0x33, 0xe2}, {0x34, 0xbf},
0766     {0x35, 0x81}, {0x36, 0xf9}, {0x37, 0x00},
0767     {0x38, 0x93}, {0x39, 0x50}, {0x3a, 0x01},
0768     {0x3b, 0x01}, {0x3c, 0x73}, {0x3d, 0x19},
0769     {0x3e, 0x0b}, {0x3f, 0x80}, {0x40, 0xc1},
0770     {0x41, 0x00}, {0x42, 0x08}, {0x67, 0x80},
0771     {0x68, 0x80}, {0x69, 0x40}, {0x6a, 0x00},
0772     {0x6b, 0x0a}, {0x8b, 0x06}, {0x8c, 0x20},
0773     {0x8d, 0x00}, {0x8e, 0x00}, {0x8f, 0xdf},
0774     {0x92, 0x00}, {0x93, 0x00}, {0x94, 0x88},
0775     {0x95, 0x88}, {0x96, 0x04}, {0xa1, 0x00},
0776     {0xa5, 0x80}, {0xa8, 0x80}, {0xa9, 0xb8},
0777     {0xaa, 0x92}, {0xab, 0x0a},
0778 };
0779 
0780 static const struct i2c_reg_u8 ov9655_init[] = {
0781     {0x0e, 0x61}, {0x11, 0x80}, {0x13, 0xba},
0782     {0x14, 0x2e}, {0x16, 0x24}, {0x1e, 0x04}, {0x27, 0x08},
0783     {0x28, 0x08}, {0x29, 0x15}, {0x2c, 0x08}, {0x34, 0x3d},
0784     {0x35, 0x00}, {0x38, 0x12}, {0x0f, 0x42}, {0x39, 0x57},
0785     {0x3a, 0x00}, {0x3b, 0xcc}, {0x3c, 0x0c}, {0x3d, 0x19},
0786     {0x3e, 0x0c}, {0x3f, 0x01}, {0x41, 0x40}, {0x42, 0x80},
0787     {0x45, 0x46}, {0x46, 0x62}, {0x47, 0x2a}, {0x48, 0x3c},
0788     {0x4a, 0xf0}, {0x4b, 0xdc}, {0x4c, 0xdc}, {0x4d, 0xdc},
0789     {0x4e, 0xdc}, {0x6c, 0x04}, {0x6f, 0x9e}, {0x70, 0x05},
0790     {0x71, 0x78}, {0x77, 0x02}, {0x8a, 0x23}, {0x90, 0x7e},
0791     {0x91, 0x7c}, {0x9f, 0x6e}, {0xa0, 0x6e}, {0xa5, 0x68},
0792     {0xa6, 0x60}, {0xa8, 0xc1}, {0xa9, 0xfa}, {0xaa, 0x92},
0793     {0xab, 0x04}, {0xac, 0x80}, {0xad, 0x80}, {0xae, 0x80},
0794     {0xaf, 0x80}, {0xb2, 0xf2}, {0xb3, 0x20}, {0xb5, 0x00},
0795     {0xb6, 0xaf}, {0xbb, 0xae}, {0xbc, 0x44}, {0xbd, 0x44},
0796     {0xbe, 0x3b}, {0xbf, 0x3a}, {0xc1, 0xc8}, {0xc2, 0x01},
0797     {0xc4, 0x00}, {0xc6, 0x85}, {0xc7, 0x81}, {0xc9, 0xe0},
0798     {0xca, 0xe8}, {0xcc, 0xd8}, {0xcd, 0x93}, {0x2d, 0x00},
0799     {0x2e, 0x00}, {0x01, 0x80}, {0x02, 0x80}, {0x12, 0x61},
0800     {0x36, 0xfa}, {0x8c, 0x8d}, {0xc0, 0xaa}, {0x69, 0x0a},
0801     {0x03, 0x09}, {0x17, 0x16}, {0x18, 0x6e}, {0x19, 0x01},
0802     {0x1a, 0x3e}, {0x32, 0x09}, {0x2a, 0x10}, {0x2b, 0x0a},
0803     {0x92, 0x00}, {0x93, 0x00}, {0xa1, 0x00}, {0x10, 0x7c},
0804     {0x04, 0x03}, {0x00, 0x13},
0805 };
0806 
0807 static const struct i2c_reg_u16 mt9v112_init[] = {
0808     {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0020},
0809     {0x34, 0xc019}, {0x0a, 0x0011}, {0x0b, 0x000b},
0810     {0x20, 0x0703}, {0x35, 0x2022}, {0xf0, 0x0001},
0811     {0x05, 0x0000}, {0x06, 0x340c}, {0x3b, 0x042a},
0812     {0x3c, 0x0400}, {0xf0, 0x0002}, {0x2e, 0x0c58},
0813     {0x5b, 0x0001}, {0xc8, 0x9f0b}, {0xf0, 0x0001},
0814     {0x9b, 0x5300}, {0xf0, 0x0000}, {0x2b, 0x0020},
0815     {0x2c, 0x002a}, {0x2d, 0x0032}, {0x2e, 0x0020},
0816     {0x09, 0x01dc}, {0x01, 0x000c}, {0x02, 0x0020},
0817     {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
0818     {0x05, 0x0098}, {0x20, 0x0703}, {0x09, 0x01f2},
0819     {0x2b, 0x00a0}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
0820     {0x2e, 0x00a0}, {0x01, 0x000c}, {0x02, 0x0020},
0821     {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
0822     {0x05, 0x0098}, {0x09, 0x01c1}, {0x2b, 0x00ae},
0823     {0x2c, 0x00ae}, {0x2d, 0x00ae}, {0x2e, 0x00ae},
0824 };
0825 
0826 static const struct i2c_reg_u16 mt9v111_init[] = {
0827     {0x01, 0x0004}, {0x0d, 0x0001}, {0x0d, 0x0000},
0828     {0x01, 0x0001}, {0x05, 0x0004}, {0x2d, 0xe0a0},
0829     {0x2e, 0x0c64}, {0x2f, 0x0064}, {0x06, 0x600e},
0830     {0x08, 0x0480}, {0x01, 0x0004}, {0x02, 0x0016},
0831     {0x03, 0x01e7}, {0x04, 0x0287}, {0x05, 0x0004},
0832     {0x06, 0x002d}, {0x07, 0x3002}, {0x08, 0x0008},
0833     {0x0e, 0x0008}, {0x20, 0x0000}
0834 };
0835 
0836 static const struct i2c_reg_u16 mt9v011_init[] = {
0837     {0x07, 0x0002}, {0x0d, 0x0001}, {0x0d, 0x0000},
0838     {0x01, 0x0008}, {0x02, 0x0016}, {0x03, 0x01e1},
0839     {0x04, 0x0281}, {0x05, 0x0083}, {0x06, 0x0006},
0840     {0x0d, 0x0002}, {0x0a, 0x0000}, {0x0b, 0x0000},
0841     {0x0c, 0x0000}, {0x0d, 0x0000}, {0x0e, 0x0000},
0842     {0x0f, 0x0000}, {0x10, 0x0000}, {0x11, 0x0000},
0843     {0x12, 0x0000}, {0x13, 0x0000}, {0x14, 0x0000},
0844     {0x15, 0x0000}, {0x16, 0x0000}, {0x17, 0x0000},
0845     {0x18, 0x0000}, {0x19, 0x0000}, {0x1a, 0x0000},
0846     {0x1b, 0x0000}, {0x1c, 0x0000}, {0x1d, 0x0000},
0847     {0x32, 0x0000}, {0x20, 0x1101}, {0x21, 0x0000},
0848     {0x22, 0x0000}, {0x23, 0x0000}, {0x24, 0x0000},
0849     {0x25, 0x0000}, {0x26, 0x0000}, {0x27, 0x0024},
0850     {0x2f, 0xf7b0}, {0x30, 0x0005}, {0x31, 0x0000},
0851     {0x32, 0x0000}, {0x33, 0x0000}, {0x34, 0x0100},
0852     {0x3d, 0x068f}, {0x40, 0x01e0}, {0x41, 0x00d1},
0853     {0x44, 0x0082}, {0x5a, 0x0000}, {0x5b, 0x0000},
0854     {0x5c, 0x0000}, {0x5d, 0x0000}, {0x5e, 0x0000},
0855     {0x5f, 0xa31d}, {0x62, 0x0611}, {0x0a, 0x0000},
0856     {0x06, 0x0029}, {0x05, 0x0009}, {0x20, 0x1101},
0857     {0x20, 0x1101}, {0x09, 0x0064}, {0x07, 0x0003},
0858     {0x2b, 0x0033}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
0859     {0x2e, 0x0033}, {0x07, 0x0002}, {0x06, 0x0000},
0860     {0x06, 0x0029}, {0x05, 0x0009},
0861 };
0862 
0863 static const struct i2c_reg_u16 mt9m001_init[] = {
0864     {0x0d, 0x0001},
0865     {0x0d, 0x0000},
0866     {0x04, 0x0500},     /* hres = 1280 */
0867     {0x03, 0x0400},     /* vres = 1024 */
0868     {0x20, 0x1100},
0869     {0x06, 0x0010},
0870     {0x2b, 0x0024},
0871     {0x2e, 0x0024},
0872     {0x35, 0x0024},
0873     {0x2d, 0x0020},
0874     {0x2c, 0x0020},
0875     {0x09, 0x0ad4},
0876     {0x35, 0x0057},
0877 };
0878 
0879 static const struct i2c_reg_u16 mt9m111_init[] = {
0880     {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
0881     {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
0882     {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
0883     {0xf0, 0x0000},
0884 };
0885 
0886 static const struct i2c_reg_u16 mt9m112_init[] = {
0887     {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
0888     {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
0889     {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
0890     {0xf0, 0x0000},
0891 };
0892 
0893 static const struct i2c_reg_u8 hv7131r_init[] = {
0894     {0x02, 0x08}, {0x02, 0x00}, {0x01, 0x08},
0895     {0x02, 0x00}, {0x20, 0x00}, {0x21, 0xd0},
0896     {0x22, 0x00}, {0x23, 0x09}, {0x01, 0x08},
0897     {0x01, 0x08}, {0x01, 0x08}, {0x25, 0x07},
0898     {0x26, 0xc3}, {0x27, 0x50}, {0x30, 0x62},
0899     {0x31, 0x10}, {0x32, 0x06}, {0x33, 0x10},
0900     {0x20, 0x00}, {0x21, 0xd0}, {0x22, 0x00},
0901     {0x23, 0x09}, {0x01, 0x08},
0902 };
0903 
0904 static void reg_r(struct gspca_dev *gspca_dev, u16 reg, u16 length)
0905 {
0906     struct usb_device *dev = gspca_dev->dev;
0907     int result;
0908 
0909     if (gspca_dev->usb_err < 0)
0910         return;
0911     result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
0912             0x00,
0913             USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
0914             reg,
0915             0x00,
0916             gspca_dev->usb_buf,
0917             length,
0918             500);
0919     if (unlikely(result < 0 || result != length)) {
0920         pr_err("Read register %02x failed %d\n", reg, result);
0921         gspca_dev->usb_err = result;
0922         /*
0923          * Make sure the buffer is zeroed to avoid uninitialized
0924          * values.
0925          */
0926         memset(gspca_dev->usb_buf, 0, USB_BUF_SZ);
0927     }
0928 }
0929 
0930 static void reg_w(struct gspca_dev *gspca_dev, u16 reg,
0931          const u8 *buffer, int length)
0932 {
0933     struct usb_device *dev = gspca_dev->dev;
0934     int result;
0935 
0936     if (gspca_dev->usb_err < 0)
0937         return;
0938     memcpy(gspca_dev->usb_buf, buffer, length);
0939     result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
0940             0x08,
0941             USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
0942             reg,
0943             0x00,
0944             gspca_dev->usb_buf,
0945             length,
0946             500);
0947     if (unlikely(result < 0 || result != length)) {
0948         pr_err("Write register %02x failed %d\n", reg, result);
0949         gspca_dev->usb_err = result;
0950     }
0951 }
0952 
0953 static void reg_w1(struct gspca_dev *gspca_dev, u16 reg, const u8 value)
0954 {
0955     reg_w(gspca_dev, reg, &value, 1);
0956 }
0957 
0958 static void i2c_w(struct gspca_dev *gspca_dev, const u8 *buffer)
0959 {
0960     int i;
0961 
0962     reg_w(gspca_dev, 0x10c0, buffer, 8);
0963     for (i = 0; i < 5; i++) {
0964         reg_r(gspca_dev, 0x10c0, 1);
0965         if (gspca_dev->usb_err < 0)
0966             return;
0967         if (gspca_dev->usb_buf[0] & 0x04) {
0968             if (gspca_dev->usb_buf[0] & 0x08) {
0969                 pr_err("i2c_w error\n");
0970                 gspca_dev->usb_err = -EIO;
0971             }
0972             return;
0973         }
0974         msleep(10);
0975     }
0976     pr_err("i2c_w reg %02x no response\n", buffer[2]);
0977 /*  gspca_dev->usb_err = -EIO;  fixme: may occur */
0978 }
0979 
0980 static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
0981 {
0982     struct sd *sd = (struct sd *) gspca_dev;
0983     u8 row[8];
0984 
0985     /*
0986      * from the point of view of the bridge, the length
0987      * includes the address
0988      */
0989     row[0] = sd->i2c_intf | (2 << 4);
0990     row[1] = sd->i2c_addr;
0991     row[2] = reg;
0992     row[3] = val;
0993     row[4] = 0x00;
0994     row[5] = 0x00;
0995     row[6] = 0x00;
0996     row[7] = 0x10;
0997 
0998     i2c_w(gspca_dev, row);
0999 }
1000 
1001 static void i2c_w1_buf(struct gspca_dev *gspca_dev,
1002             const struct i2c_reg_u8 *buf, int sz)
1003 {
1004     while (--sz >= 0) {
1005         i2c_w1(gspca_dev, buf->reg, buf->val);
1006         buf++;
1007     }
1008 }
1009 
1010 static void i2c_w2(struct gspca_dev *gspca_dev, u8 reg, u16 val)
1011 {
1012     struct sd *sd = (struct sd *) gspca_dev;
1013     u8 row[8];
1014 
1015     /*
1016      * from the point of view of the bridge, the length
1017      * includes the address
1018      */
1019     row[0] = sd->i2c_intf | (3 << 4);
1020     row[1] = sd->i2c_addr;
1021     row[2] = reg;
1022     row[3] = val >> 8;
1023     row[4] = val;
1024     row[5] = 0x00;
1025     row[6] = 0x00;
1026     row[7] = 0x10;
1027 
1028     i2c_w(gspca_dev, row);
1029 }
1030 
1031 static void i2c_w2_buf(struct gspca_dev *gspca_dev,
1032             const struct i2c_reg_u16 *buf, int sz)
1033 {
1034     while (--sz >= 0) {
1035         i2c_w2(gspca_dev, buf->reg, buf->val);
1036         buf++;
1037     }
1038 }
1039 
1040 static void i2c_r1(struct gspca_dev *gspca_dev, u8 reg, u8 *val)
1041 {
1042     struct sd *sd = (struct sd *) gspca_dev;
1043     u8 row[8];
1044 
1045     row[0] = sd->i2c_intf | (1 << 4);
1046     row[1] = sd->i2c_addr;
1047     row[2] = reg;
1048     row[3] = 0;
1049     row[4] = 0;
1050     row[5] = 0;
1051     row[6] = 0;
1052     row[7] = 0x10;
1053     i2c_w(gspca_dev, row);
1054     row[0] = sd->i2c_intf | (1 << 4) | 0x02;
1055     row[2] = 0;
1056     i2c_w(gspca_dev, row);
1057     reg_r(gspca_dev, 0x10c2, 5);
1058     *val = gspca_dev->usb_buf[4];
1059 }
1060 
1061 static void i2c_r2(struct gspca_dev *gspca_dev, u8 reg, u16 *val)
1062 {
1063     struct sd *sd = (struct sd *) gspca_dev;
1064     u8 row[8];
1065 
1066     row[0] = sd->i2c_intf | (1 << 4);
1067     row[1] = sd->i2c_addr;
1068     row[2] = reg;
1069     row[3] = 0;
1070     row[4] = 0;
1071     row[5] = 0;
1072     row[6] = 0;
1073     row[7] = 0x10;
1074     i2c_w(gspca_dev, row);
1075     row[0] = sd->i2c_intf | (2 << 4) | 0x02;
1076     row[2] = 0;
1077     i2c_w(gspca_dev, row);
1078     reg_r(gspca_dev, 0x10c2, 5);
1079     *val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1080 }
1081 
1082 static void ov9650_init_sensor(struct gspca_dev *gspca_dev)
1083 {
1084     u16 id;
1085     struct sd *sd = (struct sd *) gspca_dev;
1086 
1087     i2c_r2(gspca_dev, 0x1c, &id);
1088     if (gspca_dev->usb_err < 0)
1089         return;
1090 
1091     if (id != 0x7fa2) {
1092         pr_err("sensor id for ov9650 doesn't match (0x%04x)\n", id);
1093         gspca_dev->usb_err = -ENODEV;
1094         return;
1095     }
1096 
1097     i2c_w1(gspca_dev, 0x12, 0x80);      /* sensor reset */
1098     msleep(200);
1099     i2c_w1_buf(gspca_dev, ov9650_init, ARRAY_SIZE(ov9650_init));
1100     if (gspca_dev->usb_err < 0)
1101         pr_err("OV9650 sensor initialization failed\n");
1102     sd->hstart = 1;
1103     sd->vstart = 7;
1104 }
1105 
1106 static void ov9655_init_sensor(struct gspca_dev *gspca_dev)
1107 {
1108     struct sd *sd = (struct sd *) gspca_dev;
1109 
1110     i2c_w1(gspca_dev, 0x12, 0x80);      /* sensor reset */
1111     msleep(200);
1112     i2c_w1_buf(gspca_dev, ov9655_init, ARRAY_SIZE(ov9655_init));
1113     if (gspca_dev->usb_err < 0)
1114         pr_err("OV9655 sensor initialization failed\n");
1115 
1116     sd->hstart = 1;
1117     sd->vstart = 2;
1118 }
1119 
1120 static void soi968_init_sensor(struct gspca_dev *gspca_dev)
1121 {
1122     struct sd *sd = (struct sd *) gspca_dev;
1123 
1124     i2c_w1(gspca_dev, 0x12, 0x80);      /* sensor reset */
1125     msleep(200);
1126     i2c_w1_buf(gspca_dev, soi968_init, ARRAY_SIZE(soi968_init));
1127     if (gspca_dev->usb_err < 0)
1128         pr_err("SOI968 sensor initialization failed\n");
1129 
1130     sd->hstart = 60;
1131     sd->vstart = 11;
1132 }
1133 
1134 static void ov7660_init_sensor(struct gspca_dev *gspca_dev)
1135 {
1136     struct sd *sd = (struct sd *) gspca_dev;
1137 
1138     i2c_w1(gspca_dev, 0x12, 0x80);      /* sensor reset */
1139     msleep(200);
1140     i2c_w1_buf(gspca_dev, ov7660_init, ARRAY_SIZE(ov7660_init));
1141     if (gspca_dev->usb_err < 0)
1142         pr_err("OV7660 sensor initialization failed\n");
1143     sd->hstart = 3;
1144     sd->vstart = 3;
1145 }
1146 
1147 static void ov7670_init_sensor(struct gspca_dev *gspca_dev)
1148 {
1149     struct sd *sd = (struct sd *) gspca_dev;
1150 
1151     i2c_w1(gspca_dev, 0x12, 0x80);      /* sensor reset */
1152     msleep(200);
1153     i2c_w1_buf(gspca_dev, ov7670_init, ARRAY_SIZE(ov7670_init));
1154     if (gspca_dev->usb_err < 0)
1155         pr_err("OV7670 sensor initialization failed\n");
1156 
1157     sd->hstart = 0;
1158     sd->vstart = 1;
1159 }
1160 
1161 static void mt9v_init_sensor(struct gspca_dev *gspca_dev)
1162 {
1163     struct sd *sd = (struct sd *) gspca_dev;
1164     u16 value;
1165 
1166     sd->i2c_addr = 0x5d;
1167     i2c_r2(gspca_dev, 0xff, &value);
1168     if (gspca_dev->usb_err >= 0
1169      && value == 0x8243) {
1170         i2c_w2_buf(gspca_dev, mt9v011_init, ARRAY_SIZE(mt9v011_init));
1171         if (gspca_dev->usb_err < 0) {
1172             pr_err("MT9V011 sensor initialization failed\n");
1173             return;
1174         }
1175         sd->hstart = 2;
1176         sd->vstart = 2;
1177         sd->sensor = SENSOR_MT9V011;
1178         pr_info("MT9V011 sensor detected\n");
1179         return;
1180     }
1181 
1182     gspca_dev->usb_err = 0;
1183     sd->i2c_addr = 0x5c;
1184     i2c_w2(gspca_dev, 0x01, 0x0004);
1185     i2c_r2(gspca_dev, 0xff, &value);
1186     if (gspca_dev->usb_err >= 0
1187      && value == 0x823a) {
1188         i2c_w2_buf(gspca_dev, mt9v111_init, ARRAY_SIZE(mt9v111_init));
1189         if (gspca_dev->usb_err < 0) {
1190             pr_err("MT9V111 sensor initialization failed\n");
1191             return;
1192         }
1193         sd->hstart = 2;
1194         sd->vstart = 2;
1195         sd->sensor = SENSOR_MT9V111;
1196         pr_info("MT9V111 sensor detected\n");
1197         return;
1198     }
1199 
1200     gspca_dev->usb_err = 0;
1201     sd->i2c_addr = 0x5d;
1202     i2c_w2(gspca_dev, 0xf0, 0x0000);
1203     if (gspca_dev->usb_err < 0) {
1204         gspca_dev->usb_err = 0;
1205         sd->i2c_addr = 0x48;
1206         i2c_w2(gspca_dev, 0xf0, 0x0000);
1207     }
1208     i2c_r2(gspca_dev, 0x00, &value);
1209     if (gspca_dev->usb_err >= 0
1210      && value == 0x1229) {
1211         i2c_w2_buf(gspca_dev, mt9v112_init, ARRAY_SIZE(mt9v112_init));
1212         if (gspca_dev->usb_err < 0) {
1213             pr_err("MT9V112 sensor initialization failed\n");
1214             return;
1215         }
1216         sd->hstart = 6;
1217         sd->vstart = 2;
1218         sd->sensor = SENSOR_MT9V112;
1219         pr_info("MT9V112 sensor detected\n");
1220         return;
1221     }
1222 
1223     gspca_dev->usb_err = -ENODEV;
1224 }
1225 
1226 static void mt9m112_init_sensor(struct gspca_dev *gspca_dev)
1227 {
1228     struct sd *sd = (struct sd *) gspca_dev;
1229 
1230     i2c_w2_buf(gspca_dev, mt9m112_init, ARRAY_SIZE(mt9m112_init));
1231     if (gspca_dev->usb_err < 0)
1232         pr_err("MT9M112 sensor initialization failed\n");
1233 
1234     sd->hstart = 0;
1235     sd->vstart = 2;
1236 }
1237 
1238 static void mt9m111_init_sensor(struct gspca_dev *gspca_dev)
1239 {
1240     struct sd *sd = (struct sd *) gspca_dev;
1241 
1242     i2c_w2_buf(gspca_dev, mt9m111_init, ARRAY_SIZE(mt9m111_init));
1243     if (gspca_dev->usb_err < 0)
1244         pr_err("MT9M111 sensor initialization failed\n");
1245 
1246     sd->hstart = 0;
1247     sd->vstart = 2;
1248 }
1249 
1250 static void mt9m001_init_sensor(struct gspca_dev *gspca_dev)
1251 {
1252     struct sd *sd = (struct sd *) gspca_dev;
1253     u16 id;
1254 
1255     i2c_r2(gspca_dev, 0x00, &id);
1256     if (gspca_dev->usb_err < 0)
1257         return;
1258 
1259     /* must be 0x8411 or 0x8421 for colour sensor and 8431 for bw */
1260     switch (id) {
1261     case 0x8411:
1262     case 0x8421:
1263         pr_info("MT9M001 color sensor detected\n");
1264         break;
1265     case 0x8431:
1266         pr_info("MT9M001 mono sensor detected\n");
1267         break;
1268     default:
1269         pr_err("No MT9M001 chip detected, ID = %x\n\n", id);
1270         gspca_dev->usb_err = -ENODEV;
1271         return;
1272     }
1273 
1274     i2c_w2_buf(gspca_dev, mt9m001_init, ARRAY_SIZE(mt9m001_init));
1275     if (gspca_dev->usb_err < 0)
1276         pr_err("MT9M001 sensor initialization failed\n");
1277 
1278     sd->hstart = 1;
1279     sd->vstart = 1;
1280 }
1281 
1282 static void hv7131r_init_sensor(struct gspca_dev *gspca_dev)
1283 {
1284     struct sd *sd = (struct sd *) gspca_dev;
1285 
1286     i2c_w1_buf(gspca_dev, hv7131r_init, ARRAY_SIZE(hv7131r_init));
1287     if (gspca_dev->usb_err < 0)
1288         pr_err("HV7131R Sensor initialization failed\n");
1289 
1290     sd->hstart = 0;
1291     sd->vstart = 1;
1292 }
1293 
1294 static void set_cmatrix(struct gspca_dev *gspca_dev,
1295         s32 brightness, s32 contrast, s32 satur, s32 hue)
1296 {
1297     s32 hue_coord, hue_index = 180 + hue;
1298     u8 cmatrix[21];
1299 
1300     memset(cmatrix, 0, sizeof(cmatrix));
1301     cmatrix[2] = (contrast * 0x25 / 0x100) + 0x26;
1302     cmatrix[0] = 0x13 + (cmatrix[2] - 0x26) * 0x13 / 0x25;
1303     cmatrix[4] = 0x07 + (cmatrix[2] - 0x26) * 0x07 / 0x25;
1304     cmatrix[18] = brightness - 0x80;
1305 
1306     hue_coord = (hsv_red_x[hue_index] * satur) >> 8;
1307     cmatrix[6] = hue_coord;
1308     cmatrix[7] = (hue_coord >> 8) & 0x0f;
1309 
1310     hue_coord = (hsv_red_y[hue_index] * satur) >> 8;
1311     cmatrix[8] = hue_coord;
1312     cmatrix[9] = (hue_coord >> 8) & 0x0f;
1313 
1314     hue_coord = (hsv_green_x[hue_index] * satur) >> 8;
1315     cmatrix[10] = hue_coord;
1316     cmatrix[11] = (hue_coord >> 8) & 0x0f;
1317 
1318     hue_coord = (hsv_green_y[hue_index] * satur) >> 8;
1319     cmatrix[12] = hue_coord;
1320     cmatrix[13] = (hue_coord >> 8) & 0x0f;
1321 
1322     hue_coord = (hsv_blue_x[hue_index] * satur) >> 8;
1323     cmatrix[14] = hue_coord;
1324     cmatrix[15] = (hue_coord >> 8) & 0x0f;
1325 
1326     hue_coord = (hsv_blue_y[hue_index] * satur) >> 8;
1327     cmatrix[16] = hue_coord;
1328     cmatrix[17] = (hue_coord >> 8) & 0x0f;
1329 
1330     reg_w(gspca_dev, 0x10e1, cmatrix, 21);
1331 }
1332 
1333 static void set_gamma(struct gspca_dev *gspca_dev, s32 val)
1334 {
1335     u8 gamma[17];
1336     u8 gval = val * 0xb8 / 0x100;
1337 
1338     gamma[0] = 0x0a;
1339     gamma[1] = 0x13 + (gval * (0xcb - 0x13) / 0xb8);
1340     gamma[2] = 0x25 + (gval * (0xee - 0x25) / 0xb8);
1341     gamma[3] = 0x37 + (gval * (0xfa - 0x37) / 0xb8);
1342     gamma[4] = 0x45 + (gval * (0xfc - 0x45) / 0xb8);
1343     gamma[5] = 0x55 + (gval * (0xfb - 0x55) / 0xb8);
1344     gamma[6] = 0x65 + (gval * (0xfc - 0x65) / 0xb8);
1345     gamma[7] = 0x74 + (gval * (0xfd - 0x74) / 0xb8);
1346     gamma[8] = 0x83 + (gval * (0xfe - 0x83) / 0xb8);
1347     gamma[9] = 0x92 + (gval * (0xfc - 0x92) / 0xb8);
1348     gamma[10] = 0xa1 + (gval * (0xfc - 0xa1) / 0xb8);
1349     gamma[11] = 0xb0 + (gval * (0xfc - 0xb0) / 0xb8);
1350     gamma[12] = 0xbf + (gval * (0xfb - 0xbf) / 0xb8);
1351     gamma[13] = 0xce + (gval * (0xfb - 0xce) / 0xb8);
1352     gamma[14] = 0xdf + (gval * (0xfd - 0xdf) / 0xb8);
1353     gamma[15] = 0xea + (gval * (0xf9 - 0xea) / 0xb8);
1354     gamma[16] = 0xf5;
1355 
1356     reg_w(gspca_dev, 0x1190, gamma, 17);
1357 }
1358 
1359 static void set_redblue(struct gspca_dev *gspca_dev, s32 blue, s32 red)
1360 {
1361     reg_w1(gspca_dev, 0x118c, red);
1362     reg_w1(gspca_dev, 0x118f, blue);
1363 }
1364 
1365 static void set_hvflip(struct gspca_dev *gspca_dev, s32 hflip, s32 vflip)
1366 {
1367     u8 value, tslb;
1368     u16 value2;
1369     struct sd *sd = (struct sd *) gspca_dev;
1370 
1371     if ((sd->flags & FLIP_DETECT) && dmi_check_system(flip_dmi_table)) {
1372         hflip = !hflip;
1373         vflip = !vflip;
1374     }
1375 
1376     switch (sd->sensor) {
1377     case SENSOR_OV7660:
1378         value = 0x01;
1379         if (hflip)
1380             value |= 0x20;
1381         if (vflip) {
1382             value |= 0x10;
1383             sd->vstart = 2;
1384         } else {
1385             sd->vstart = 3;
1386         }
1387         reg_w1(gspca_dev, 0x1182, sd->vstart);
1388         i2c_w1(gspca_dev, 0x1e, value);
1389         break;
1390     case SENSOR_OV9650:
1391         i2c_r1(gspca_dev, 0x1e, &value);
1392         value &= ~0x30;
1393         tslb = 0x01;
1394         if (hflip)
1395             value |= 0x20;
1396         if (vflip) {
1397             value |= 0x10;
1398             tslb = 0x49;
1399         }
1400         i2c_w1(gspca_dev, 0x1e, value);
1401         i2c_w1(gspca_dev, 0x3a, tslb);
1402         break;
1403     case SENSOR_MT9V111:
1404     case SENSOR_MT9V011:
1405         i2c_r2(gspca_dev, 0x20, &value2);
1406         value2 &= ~0xc0a0;
1407         if (hflip)
1408             value2 |= 0x8080;
1409         if (vflip)
1410             value2 |= 0x4020;
1411         i2c_w2(gspca_dev, 0x20, value2);
1412         break;
1413     case SENSOR_MT9M112:
1414     case SENSOR_MT9M111:
1415     case SENSOR_MT9V112:
1416         i2c_r2(gspca_dev, 0x20, &value2);
1417         value2 &= ~0x0003;
1418         if (hflip)
1419             value2 |= 0x0002;
1420         if (vflip)
1421             value2 |= 0x0001;
1422         i2c_w2(gspca_dev, 0x20, value2);
1423         break;
1424     case SENSOR_HV7131R:
1425         i2c_r1(gspca_dev, 0x01, &value);
1426         value &= ~0x03;
1427         if (vflip)
1428             value |= 0x01;
1429         if (hflip)
1430             value |= 0x02;
1431         i2c_w1(gspca_dev, 0x01, value);
1432         break;
1433     }
1434 }
1435 
1436 static void set_exposure(struct gspca_dev *gspca_dev, s32 expo)
1437 {
1438     struct sd *sd = (struct sd *) gspca_dev;
1439     u8 exp[8] = {sd->i2c_intf, sd->i2c_addr,
1440                 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
1441     int expo2;
1442 
1443     if (gspca_dev->streaming)
1444         exp[7] = 0x1e;
1445 
1446     switch (sd->sensor) {
1447     case SENSOR_OV7660:
1448     case SENSOR_OV7670:
1449     case SENSOR_OV9655:
1450     case SENSOR_OV9650:
1451         if (expo > 547)
1452             expo2 = 547;
1453         else
1454             expo2 = expo;
1455         exp[0] |= (2 << 4);
1456         exp[2] = 0x10;          /* AECH */
1457         exp[3] = expo2 >> 2;
1458         exp[7] = 0x10;
1459         i2c_w(gspca_dev, exp);
1460         exp[2] = 0x04;          /* COM1 */
1461         exp[3] = expo2 & 0x0003;
1462         exp[7] = 0x10;
1463         i2c_w(gspca_dev, exp);
1464         expo -= expo2;
1465         exp[7] = 0x1e;
1466         exp[0] |= (3 << 4);
1467         exp[2] = 0x2d;          /* ADVFL & ADVFH */
1468         exp[3] = expo;
1469         exp[4] = expo >> 8;
1470         break;
1471     case SENSOR_MT9M001:
1472     case SENSOR_MT9V112:
1473     case SENSOR_MT9V011:
1474         exp[0] |= (3 << 4);
1475         exp[2] = 0x09;
1476         exp[3] = expo >> 8;
1477         exp[4] = expo;
1478         break;
1479     case SENSOR_HV7131R:
1480         exp[0] |= (4 << 4);
1481         exp[2] = 0x25;
1482         exp[3] = expo >> 5;
1483         exp[4] = expo << 3;
1484         exp[5] = 0;
1485         break;
1486     default:
1487         return;
1488     }
1489     i2c_w(gspca_dev, exp);
1490 }
1491 
1492 static void set_gain(struct gspca_dev *gspca_dev, s32 g)
1493 {
1494     struct sd *sd = (struct sd *) gspca_dev;
1495     u8 gain[8] = {sd->i2c_intf, sd->i2c_addr,
1496                 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
1497 
1498     if (gspca_dev->streaming)
1499         gain[7] = 0x15;     /* or 1d ? */
1500 
1501     switch (sd->sensor) {
1502     case SENSOR_OV7660:
1503     case SENSOR_OV7670:
1504     case SENSOR_SOI968:
1505     case SENSOR_OV9655:
1506     case SENSOR_OV9650:
1507         gain[0] |= (2 << 4);
1508         gain[3] = ov_gain[g];
1509         break;
1510     case SENSOR_MT9V011:
1511         gain[0] |= (3 << 4);
1512         gain[2] = 0x35;
1513         gain[3] = micron1_gain[g] >> 8;
1514         gain[4] = micron1_gain[g];
1515         break;
1516     case SENSOR_MT9V112:
1517         gain[0] |= (3 << 4);
1518         gain[2] = 0x2f;
1519         gain[3] = micron1_gain[g] >> 8;
1520         gain[4] = micron1_gain[g];
1521         break;
1522     case SENSOR_MT9M001:
1523         gain[0] |= (3 << 4);
1524         gain[2] = 0x2f;
1525         gain[3] = micron2_gain[g] >> 8;
1526         gain[4] = micron2_gain[g];
1527         break;
1528     case SENSOR_HV7131R:
1529         gain[0] |= (2 << 4);
1530         gain[2] = 0x30;
1531         gain[3] = hv7131r_gain[g];
1532         break;
1533     default:
1534         return;
1535     }
1536     i2c_w(gspca_dev, gain);
1537 }
1538 
1539 static void set_led_mode(struct gspca_dev *gspca_dev, s32 val)
1540 {
1541     reg_w1(gspca_dev, 0x1007, 0x60);
1542     reg_w1(gspca_dev, 0x1006, val ? 0x40 : 0x00);
1543 }
1544 
1545 static void set_quality(struct gspca_dev *gspca_dev, s32 val)
1546 {
1547     struct sd *sd = (struct sd *) gspca_dev;
1548 
1549     jpeg_set_qual(sd->jpeg_hdr, val);
1550     reg_w1(gspca_dev, 0x1061, 0x01);    /* stop transfer */
1551     reg_w1(gspca_dev, 0x10e0, sd->fmt | 0x20); /* write QTAB */
1552     reg_w(gspca_dev, 0x1100, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64);
1553     reg_w(gspca_dev, 0x1140, &sd->jpeg_hdr[JPEG_QT1_OFFSET], 64);
1554     reg_w1(gspca_dev, 0x1061, 0x03);    /* restart transfer */
1555     reg_w1(gspca_dev, 0x10e0, sd->fmt);
1556     sd->fmt ^= 0x0c;            /* invert QTAB use + write */
1557     reg_w1(gspca_dev, 0x10e0, sd->fmt);
1558 }
1559 
1560 #ifdef CONFIG_VIDEO_ADV_DEBUG
1561 static int sd_dbg_g_register(struct gspca_dev *gspca_dev,
1562             struct v4l2_dbg_register *reg)
1563 {
1564     struct sd *sd = (struct sd *) gspca_dev;
1565 
1566     reg->size = 1;
1567     switch (reg->match.addr) {
1568     case 0:
1569         if (reg->reg < 0x1000 || reg->reg > 0x11ff)
1570             return -EINVAL;
1571         reg_r(gspca_dev, reg->reg, 1);
1572         reg->val = gspca_dev->usb_buf[0];
1573         return gspca_dev->usb_err;
1574     case 1:
1575         if (sd->sensor >= SENSOR_MT9V011 &&
1576             sd->sensor <= SENSOR_MT9M112) {
1577             i2c_r2(gspca_dev, reg->reg, (u16 *) &reg->val);
1578             reg->size = 2;
1579         } else {
1580             i2c_r1(gspca_dev, reg->reg, (u8 *) &reg->val);
1581         }
1582         return gspca_dev->usb_err;
1583     }
1584     return -EINVAL;
1585 }
1586 
1587 static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
1588             const struct v4l2_dbg_register *reg)
1589 {
1590     struct sd *sd = (struct sd *) gspca_dev;
1591 
1592     switch (reg->match.addr) {
1593     case 0:
1594         if (reg->reg < 0x1000 || reg->reg > 0x11ff)
1595             return -EINVAL;
1596         reg_w1(gspca_dev, reg->reg, reg->val);
1597         return gspca_dev->usb_err;
1598     case 1:
1599         if (sd->sensor >= SENSOR_MT9V011 &&
1600             sd->sensor <= SENSOR_MT9M112) {
1601             i2c_w2(gspca_dev, reg->reg, reg->val);
1602         } else {
1603             i2c_w1(gspca_dev, reg->reg, reg->val);
1604         }
1605         return gspca_dev->usb_err;
1606     }
1607     return -EINVAL;
1608 }
1609 
1610 static int sd_chip_info(struct gspca_dev *gspca_dev,
1611             struct v4l2_dbg_chip_info *chip)
1612 {
1613     if (chip->match.addr > 1)
1614         return -EINVAL;
1615     if (chip->match.addr == 1)
1616         strscpy(chip->name, "sensor", sizeof(chip->name));
1617     return 0;
1618 }
1619 #endif
1620 
1621 static int sd_config(struct gspca_dev *gspca_dev,
1622             const struct usb_device_id *id)
1623 {
1624     struct sd *sd = (struct sd *) gspca_dev;
1625     struct cam *cam;
1626 
1627     cam = &gspca_dev->cam;
1628     cam->needs_full_bandwidth = 1;
1629 
1630     sd->sensor = id->driver_info >> 8;
1631     sd->i2c_addr = id->driver_info;
1632     sd->flags = id->driver_info >> 16;
1633     sd->i2c_intf = 0x80;            /* i2c 100 Kb/s */
1634 
1635     switch (sd->sensor) {
1636     case SENSOR_MT9M112:
1637     case SENSOR_MT9M111:
1638     case SENSOR_OV9650:
1639     case SENSOR_SOI968:
1640         cam->cam_mode = sxga_mode;
1641         cam->nmodes = ARRAY_SIZE(sxga_mode);
1642         break;
1643     case SENSOR_MT9M001:
1644         cam->cam_mode = mono_mode;
1645         cam->nmodes = ARRAY_SIZE(mono_mode);
1646         break;
1647     case SENSOR_HV7131R:
1648         sd->i2c_intf = 0x81;            /* i2c 400 Kb/s */
1649         fallthrough;
1650     default:
1651         cam->cam_mode = vga_mode;
1652         cam->nmodes = ARRAY_SIZE(vga_mode);
1653         break;
1654     }
1655 
1656     sd->old_step = 0;
1657     sd->older_step = 0;
1658     sd->exposure_step = 16;
1659 
1660     INIT_WORK(&sd->work, qual_upd);
1661 
1662     return 0;
1663 }
1664 
1665 static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
1666 {
1667     struct gspca_dev *gspca_dev =
1668         container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
1669     struct sd *sd = (struct sd *)gspca_dev;
1670 
1671     gspca_dev->usb_err = 0;
1672 
1673     if (!gspca_dev->streaming)
1674         return 0;
1675 
1676     switch (ctrl->id) {
1677     /* color control cluster */
1678     case V4L2_CID_BRIGHTNESS:
1679         set_cmatrix(gspca_dev, sd->brightness->val,
1680             sd->contrast->val, sd->saturation->val, sd->hue->val);
1681         break;
1682     case V4L2_CID_GAMMA:
1683         set_gamma(gspca_dev, ctrl->val);
1684         break;
1685     /* blue/red balance cluster */
1686     case V4L2_CID_BLUE_BALANCE:
1687         set_redblue(gspca_dev, sd->blue->val, sd->red->val);
1688         break;
1689     /* h/vflip cluster */
1690     case V4L2_CID_HFLIP:
1691         set_hvflip(gspca_dev, sd->hflip->val, sd->vflip->val);
1692         break;
1693     /* standalone exposure control */
1694     case V4L2_CID_EXPOSURE:
1695         set_exposure(gspca_dev, ctrl->val);
1696         break;
1697     /* standalone gain control */
1698     case V4L2_CID_GAIN:
1699         set_gain(gspca_dev, ctrl->val);
1700         break;
1701     /* autogain + exposure or gain control cluster */
1702     case V4L2_CID_AUTOGAIN:
1703         if (sd->sensor == SENSOR_SOI968)
1704             set_gain(gspca_dev, sd->gain->val);
1705         else
1706             set_exposure(gspca_dev, sd->exposure->val);
1707         break;
1708     case V4L2_CID_JPEG_COMPRESSION_QUALITY:
1709         set_quality(gspca_dev, ctrl->val);
1710         break;
1711     case V4L2_CID_FLASH_LED_MODE:
1712         set_led_mode(gspca_dev, ctrl->val);
1713         break;
1714     }
1715     return gspca_dev->usb_err;
1716 }
1717 
1718 static const struct v4l2_ctrl_ops sd_ctrl_ops = {
1719     .s_ctrl = sd_s_ctrl,
1720 };
1721 
1722 static int sd_init_controls(struct gspca_dev *gspca_dev)
1723 {
1724     struct sd *sd = (struct sd *) gspca_dev;
1725     struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
1726 
1727     gspca_dev->vdev.ctrl_handler = hdl;
1728     v4l2_ctrl_handler_init(hdl, 13);
1729 
1730     sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1731             V4L2_CID_BRIGHTNESS, 0, 255, 1, 127);
1732     sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1733             V4L2_CID_CONTRAST, 0, 255, 1, 127);
1734     sd->saturation = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1735             V4L2_CID_SATURATION, 0, 255, 1, 127);
1736     sd->hue = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1737             V4L2_CID_HUE, -180, 180, 1, 0);
1738 
1739     sd->gamma = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1740             V4L2_CID_GAMMA, 0, 255, 1, 0x10);
1741 
1742     sd->blue = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1743             V4L2_CID_BLUE_BALANCE, 0, 127, 1, 0x28);
1744     sd->red = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1745             V4L2_CID_RED_BALANCE, 0, 127, 1, 0x28);
1746 
1747     if (sd->sensor != SENSOR_OV9655 && sd->sensor != SENSOR_SOI968 &&
1748         sd->sensor != SENSOR_OV7670 && sd->sensor != SENSOR_MT9M001 &&
1749         sd->sensor != SENSOR_MT9VPRB) {
1750         sd->hflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1751             V4L2_CID_HFLIP, 0, 1, 1, 0);
1752         sd->vflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1753             V4L2_CID_VFLIP, 0, 1, 1, 0);
1754     }
1755 
1756     if (sd->sensor != SENSOR_SOI968 && sd->sensor != SENSOR_MT9VPRB &&
1757         sd->sensor != SENSOR_MT9M112 && sd->sensor != SENSOR_MT9M111 &&
1758         sd->sensor != SENSOR_MT9V111)
1759         sd->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1760             V4L2_CID_EXPOSURE, 0, 0x1780, 1, 0x33);
1761 
1762     if (sd->sensor != SENSOR_MT9VPRB && sd->sensor != SENSOR_MT9M112 &&
1763         sd->sensor != SENSOR_MT9M111 && sd->sensor != SENSOR_MT9V111) {
1764         sd->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1765             V4L2_CID_GAIN, 0, 28, 1, 0);
1766         sd->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1767             V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
1768     }
1769 
1770     sd->jpegqual = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1771             V4L2_CID_JPEG_COMPRESSION_QUALITY, 50, 90, 1, 80);
1772 
1773     if (sd->flags & HAS_LED_TORCH)
1774         sd->led_mode = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops,
1775                 V4L2_CID_FLASH_LED_MODE, V4L2_FLASH_LED_MODE_TORCH,
1776                 ~0x5, V4L2_FLASH_LED_MODE_NONE);
1777 
1778     if (hdl->error) {
1779         pr_err("Could not initialize controls\n");
1780         return hdl->error;
1781     }
1782 
1783     v4l2_ctrl_cluster(4, &sd->brightness);
1784     v4l2_ctrl_cluster(2, &sd->blue);
1785     if (sd->hflip)
1786         v4l2_ctrl_cluster(2, &sd->hflip);
1787     if (sd->autogain) {
1788         if (sd->sensor == SENSOR_SOI968)
1789             /* this sensor doesn't have the exposure control and
1790                autogain is clustered with gain instead. This works
1791                because sd->exposure == NULL. */
1792             v4l2_ctrl_auto_cluster(3, &sd->autogain, 0, false);
1793         else
1794             /* Otherwise autogain is clustered with exposure. */
1795             v4l2_ctrl_auto_cluster(2, &sd->autogain, 0, false);
1796     }
1797     return 0;
1798 }
1799 
1800 static int sd_init(struct gspca_dev *gspca_dev)
1801 {
1802     struct sd *sd = (struct sd *) gspca_dev;
1803     int i;
1804     u8 value;
1805     u8 i2c_init[9] = {
1806         0x80, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03
1807     };
1808 
1809     for (i = 0; i < ARRAY_SIZE(bridge_init); i++) {
1810         value = bridge_init[i][1];
1811         reg_w(gspca_dev, bridge_init[i][0], &value, 1);
1812         if (gspca_dev->usb_err < 0) {
1813             pr_err("Device initialization failed\n");
1814             return gspca_dev->usb_err;
1815         }
1816     }
1817 
1818     if (sd->flags & LED_REVERSE)
1819         reg_w1(gspca_dev, 0x1006, 0x00);
1820     else
1821         reg_w1(gspca_dev, 0x1006, 0x20);
1822 
1823     reg_w(gspca_dev, 0x10c0, i2c_init, 9);
1824     if (gspca_dev->usb_err < 0) {
1825         pr_err("Device initialization failed\n");
1826         return gspca_dev->usb_err;
1827     }
1828 
1829     switch (sd->sensor) {
1830     case SENSOR_OV9650:
1831         ov9650_init_sensor(gspca_dev);
1832         if (gspca_dev->usb_err < 0)
1833             break;
1834         pr_info("OV9650 sensor detected\n");
1835         break;
1836     case SENSOR_OV9655:
1837         ov9655_init_sensor(gspca_dev);
1838         if (gspca_dev->usb_err < 0)
1839             break;
1840         pr_info("OV9655 sensor detected\n");
1841         break;
1842     case SENSOR_SOI968:
1843         soi968_init_sensor(gspca_dev);
1844         if (gspca_dev->usb_err < 0)
1845             break;
1846         pr_info("SOI968 sensor detected\n");
1847         break;
1848     case SENSOR_OV7660:
1849         ov7660_init_sensor(gspca_dev);
1850         if (gspca_dev->usb_err < 0)
1851             break;
1852         pr_info("OV7660 sensor detected\n");
1853         break;
1854     case SENSOR_OV7670:
1855         ov7670_init_sensor(gspca_dev);
1856         if (gspca_dev->usb_err < 0)
1857             break;
1858         pr_info("OV7670 sensor detected\n");
1859         break;
1860     case SENSOR_MT9VPRB:
1861         mt9v_init_sensor(gspca_dev);
1862         if (gspca_dev->usb_err < 0)
1863             break;
1864         pr_info("MT9VPRB sensor detected\n");
1865         break;
1866     case SENSOR_MT9M111:
1867         mt9m111_init_sensor(gspca_dev);
1868         if (gspca_dev->usb_err < 0)
1869             break;
1870         pr_info("MT9M111 sensor detected\n");
1871         break;
1872     case SENSOR_MT9M112:
1873         mt9m112_init_sensor(gspca_dev);
1874         if (gspca_dev->usb_err < 0)
1875             break;
1876         pr_info("MT9M112 sensor detected\n");
1877         break;
1878     case SENSOR_MT9M001:
1879         mt9m001_init_sensor(gspca_dev);
1880         if (gspca_dev->usb_err < 0)
1881             break;
1882         break;
1883     case SENSOR_HV7131R:
1884         hv7131r_init_sensor(gspca_dev);
1885         if (gspca_dev->usb_err < 0)
1886             break;
1887         pr_info("HV7131R sensor detected\n");
1888         break;
1889     default:
1890         pr_err("Unsupported sensor\n");
1891         gspca_dev->usb_err = -ENODEV;
1892     }
1893     return gspca_dev->usb_err;
1894 }
1895 
1896 static void configure_sensor_output(struct gspca_dev *gspca_dev, int mode)
1897 {
1898     struct sd *sd = (struct sd *) gspca_dev;
1899     u8 value;
1900 
1901     switch (sd->sensor) {
1902     case SENSOR_SOI968:
1903         if (mode & MODE_SXGA) {
1904             i2c_w1(gspca_dev, 0x17, 0x1d);
1905             i2c_w1(gspca_dev, 0x18, 0xbd);
1906             i2c_w1(gspca_dev, 0x19, 0x01);
1907             i2c_w1(gspca_dev, 0x1a, 0x81);
1908             i2c_w1(gspca_dev, 0x12, 0x00);
1909             sd->hstart = 140;
1910             sd->vstart = 19;
1911         } else {
1912             i2c_w1(gspca_dev, 0x17, 0x13);
1913             i2c_w1(gspca_dev, 0x18, 0x63);
1914             i2c_w1(gspca_dev, 0x19, 0x01);
1915             i2c_w1(gspca_dev, 0x1a, 0x79);
1916             i2c_w1(gspca_dev, 0x12, 0x40);
1917             sd->hstart = 60;
1918             sd->vstart = 11;
1919         }
1920         break;
1921     case SENSOR_OV9650:
1922         if (mode & MODE_SXGA) {
1923             i2c_w1(gspca_dev, 0x17, 0x1b);
1924             i2c_w1(gspca_dev, 0x18, 0xbc);
1925             i2c_w1(gspca_dev, 0x19, 0x01);
1926             i2c_w1(gspca_dev, 0x1a, 0x82);
1927             i2c_r1(gspca_dev, 0x12, &value);
1928             i2c_w1(gspca_dev, 0x12, value & 0x07);
1929         } else {
1930             i2c_w1(gspca_dev, 0x17, 0x24);
1931             i2c_w1(gspca_dev, 0x18, 0xc5);
1932             i2c_w1(gspca_dev, 0x19, 0x00);
1933             i2c_w1(gspca_dev, 0x1a, 0x3c);
1934             i2c_r1(gspca_dev, 0x12, &value);
1935             i2c_w1(gspca_dev, 0x12, (value & 0x7) | 0x40);
1936         }
1937         break;
1938     case SENSOR_MT9M112:
1939     case SENSOR_MT9M111:
1940         if (mode & MODE_SXGA) {
1941             i2c_w2(gspca_dev, 0xf0, 0x0002);
1942             i2c_w2(gspca_dev, 0xc8, 0x970b);
1943             i2c_w2(gspca_dev, 0xf0, 0x0000);
1944         } else {
1945             i2c_w2(gspca_dev, 0xf0, 0x0002);
1946             i2c_w2(gspca_dev, 0xc8, 0x8000);
1947             i2c_w2(gspca_dev, 0xf0, 0x0000);
1948         }
1949         break;
1950     }
1951 }
1952 
1953 static int sd_isoc_init(struct gspca_dev *gspca_dev)
1954 {
1955     struct usb_interface *intf;
1956     u32 flags = gspca_dev->cam.cam_mode[(int)gspca_dev->curr_mode].priv;
1957 
1958     /*
1959      * When using the SN9C20X_I420 fmt the sn9c20x needs more bandwidth
1960      * than our regular bandwidth calculations reserve, so we force the
1961      * use of a specific altsetting when using the SN9C20X_I420 fmt.
1962      */
1963     if (!(flags & (MODE_RAW | MODE_JPEG))) {
1964         intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface);
1965 
1966         if (intf->num_altsetting != 9) {
1967             pr_warn("sn9c20x camera with unknown number of alt settings (%d), please report!\n",
1968                 intf->num_altsetting);
1969             gspca_dev->alt = intf->num_altsetting;
1970             return 0;
1971         }
1972 
1973         switch (gspca_dev->pixfmt.width) {
1974         case 160: /* 160x120 */
1975             gspca_dev->alt = 2;
1976             break;
1977         case 320: /* 320x240 */
1978             gspca_dev->alt = 6;
1979             break;
1980         default:  /* >= 640x480 */
1981             gspca_dev->alt = 9;
1982             break;
1983         }
1984     }
1985 
1986     return 0;
1987 }
1988 
1989 #define HW_WIN(mode, hstart, vstart) \
1990 ((const u8 []){hstart, 0, vstart, 0, \
1991 (mode & MODE_SXGA ? 1280 >> 4 : 640 >> 4), \
1992 (mode & MODE_SXGA ? 1024 >> 3 : 480 >> 3)})
1993 
1994 #define CLR_WIN(width, height) \
1995 ((const u8 [])\
1996 {0, width >> 2, 0, height >> 1,\
1997 ((width >> 10) & 0x01) | ((height >> 8) & 0x6)})
1998 
1999 static int sd_start(struct gspca_dev *gspca_dev)
2000 {
2001     struct sd *sd = (struct sd *) gspca_dev;
2002     int mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
2003     int width = gspca_dev->pixfmt.width;
2004     int height = gspca_dev->pixfmt.height;
2005     u8 fmt, scale = 0;
2006 
2007     jpeg_define(sd->jpeg_hdr, height, width,
2008             0x21);
2009     jpeg_set_qual(sd->jpeg_hdr, v4l2_ctrl_g_ctrl(sd->jpegqual));
2010 
2011     if (mode & MODE_RAW)
2012         fmt = 0x2d;
2013     else if (mode & MODE_JPEG)
2014         fmt = 0x24;
2015     else
2016         fmt = 0x2f; /* YUV 420 */
2017     sd->fmt = fmt;
2018 
2019     switch (mode & SCALE_MASK) {
2020     case SCALE_1280x1024:
2021         scale = 0xc0;
2022         pr_info("Set 1280x1024\n");
2023         break;
2024     case SCALE_640x480:
2025         scale = 0x80;
2026         pr_info("Set 640x480\n");
2027         break;
2028     case SCALE_320x240:
2029         scale = 0x90;
2030         pr_info("Set 320x240\n");
2031         break;
2032     case SCALE_160x120:
2033         scale = 0xa0;
2034         pr_info("Set 160x120\n");
2035         break;
2036     }
2037 
2038     configure_sensor_output(gspca_dev, mode);
2039     reg_w(gspca_dev, 0x1100, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64);
2040     reg_w(gspca_dev, 0x1140, &sd->jpeg_hdr[JPEG_QT1_OFFSET], 64);
2041     reg_w(gspca_dev, 0x10fb, CLR_WIN(width, height), 5);
2042     reg_w(gspca_dev, 0x1180, HW_WIN(mode, sd->hstart, sd->vstart), 6);
2043     reg_w1(gspca_dev, 0x1189, scale);
2044     reg_w1(gspca_dev, 0x10e0, fmt);
2045 
2046     set_cmatrix(gspca_dev, v4l2_ctrl_g_ctrl(sd->brightness),
2047             v4l2_ctrl_g_ctrl(sd->contrast),
2048             v4l2_ctrl_g_ctrl(sd->saturation),
2049             v4l2_ctrl_g_ctrl(sd->hue));
2050     set_gamma(gspca_dev, v4l2_ctrl_g_ctrl(sd->gamma));
2051     set_redblue(gspca_dev, v4l2_ctrl_g_ctrl(sd->blue),
2052             v4l2_ctrl_g_ctrl(sd->red));
2053     if (sd->gain)
2054         set_gain(gspca_dev, v4l2_ctrl_g_ctrl(sd->gain));
2055     if (sd->exposure)
2056         set_exposure(gspca_dev, v4l2_ctrl_g_ctrl(sd->exposure));
2057     if (sd->hflip)
2058         set_hvflip(gspca_dev, v4l2_ctrl_g_ctrl(sd->hflip),
2059                 v4l2_ctrl_g_ctrl(sd->vflip));
2060 
2061     reg_w1(gspca_dev, 0x1007, 0x20);
2062     reg_w1(gspca_dev, 0x1061, 0x03);
2063 
2064     /* if JPEG, prepare the compression quality update */
2065     if (mode & MODE_JPEG) {
2066         sd->pktsz = sd->npkt = 0;
2067         sd->nchg = 0;
2068     }
2069     if (sd->led_mode)
2070         v4l2_ctrl_s_ctrl(sd->led_mode, 0);
2071 
2072     return gspca_dev->usb_err;
2073 }
2074 
2075 static void sd_stopN(struct gspca_dev *gspca_dev)
2076 {
2077     reg_w1(gspca_dev, 0x1007, 0x00);
2078     reg_w1(gspca_dev, 0x1061, 0x01);
2079 }
2080 
2081 /* called on streamoff with alt==0 and on disconnect */
2082 /* the usb_lock is held at entry - restore on exit */
2083 static void sd_stop0(struct gspca_dev *gspca_dev)
2084 {
2085     struct sd *sd = (struct sd *) gspca_dev;
2086 
2087     mutex_unlock(&gspca_dev->usb_lock);
2088     flush_work(&sd->work);
2089     mutex_lock(&gspca_dev->usb_lock);
2090 }
2091 
2092 static void do_autoexposure(struct gspca_dev *gspca_dev, u16 avg_lum)
2093 {
2094     struct sd *sd = (struct sd *) gspca_dev;
2095     s32 cur_exp = v4l2_ctrl_g_ctrl(sd->exposure);
2096     s32 max = sd->exposure->maximum - sd->exposure_step;
2097     s32 min = sd->exposure->minimum + sd->exposure_step;
2098     s16 new_exp;
2099 
2100     /*
2101      * some hardcoded values are present
2102      * like those for maximal/minimal exposure
2103      * and exposure steps
2104      */
2105     if (avg_lum < MIN_AVG_LUM) {
2106         if (cur_exp > max)
2107             return;
2108 
2109         new_exp = cur_exp + sd->exposure_step;
2110         if (new_exp > max)
2111             new_exp = max;
2112         if (new_exp < min)
2113             new_exp = min;
2114         v4l2_ctrl_s_ctrl(sd->exposure, new_exp);
2115 
2116         sd->older_step = sd->old_step;
2117         sd->old_step = 1;
2118 
2119         if (sd->old_step ^ sd->older_step)
2120             sd->exposure_step /= 2;
2121         else
2122             sd->exposure_step += 2;
2123     }
2124     if (avg_lum > MAX_AVG_LUM) {
2125         if (cur_exp < min)
2126             return;
2127         new_exp = cur_exp - sd->exposure_step;
2128         if (new_exp > max)
2129             new_exp = max;
2130         if (new_exp < min)
2131             new_exp = min;
2132         v4l2_ctrl_s_ctrl(sd->exposure, new_exp);
2133         sd->older_step = sd->old_step;
2134         sd->old_step = 0;
2135 
2136         if (sd->old_step ^ sd->older_step)
2137             sd->exposure_step /= 2;
2138         else
2139             sd->exposure_step += 2;
2140     }
2141 }
2142 
2143 static void do_autogain(struct gspca_dev *gspca_dev, u16 avg_lum)
2144 {
2145     struct sd *sd = (struct sd *) gspca_dev;
2146     s32 cur_gain = v4l2_ctrl_g_ctrl(sd->gain);
2147 
2148     if (avg_lum < MIN_AVG_LUM && cur_gain < sd->gain->maximum)
2149         v4l2_ctrl_s_ctrl(sd->gain, cur_gain + 1);
2150     if (avg_lum > MAX_AVG_LUM && cur_gain > sd->gain->minimum)
2151         v4l2_ctrl_s_ctrl(sd->gain, cur_gain - 1);
2152 }
2153 
2154 static void sd_dqcallback(struct gspca_dev *gspca_dev)
2155 {
2156     struct sd *sd = (struct sd *) gspca_dev;
2157     int avg_lum;
2158 
2159     if (sd->autogain == NULL || !v4l2_ctrl_g_ctrl(sd->autogain))
2160         return;
2161 
2162     avg_lum = atomic_read(&sd->avg_lum);
2163     if (sd->sensor == SENSOR_SOI968)
2164         do_autogain(gspca_dev, avg_lum);
2165     else
2166         do_autoexposure(gspca_dev, avg_lum);
2167 }
2168 
2169 /* JPEG quality update */
2170 /* This function is executed from a work queue. */
2171 static void qual_upd(struct work_struct *work)
2172 {
2173     struct sd *sd = container_of(work, struct sd, work);
2174     struct gspca_dev *gspca_dev = &sd->gspca_dev;
2175     s32 qual = v4l2_ctrl_g_ctrl(sd->jpegqual);
2176 
2177     /* To protect gspca_dev->usb_buf and gspca_dev->usb_err */
2178     mutex_lock(&gspca_dev->usb_lock);
2179     gspca_dbg(gspca_dev, D_STREAM, "qual_upd %d%%\n", qual);
2180     gspca_dev->usb_err = 0;
2181     set_quality(gspca_dev, qual);
2182     mutex_unlock(&gspca_dev->usb_lock);
2183 }
2184 
2185 #if IS_ENABLED(CONFIG_INPUT)
2186 static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
2187             u8 *data,       /* interrupt packet */
2188             int len)        /* interrupt packet length */
2189 {
2190     struct sd *sd = (struct sd *) gspca_dev;
2191 
2192     if (!(sd->flags & HAS_NO_BUTTON) && len == 1) {
2193         input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
2194         input_sync(gspca_dev->input_dev);
2195         input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
2196         input_sync(gspca_dev->input_dev);
2197         return 0;
2198     }
2199     return -EINVAL;
2200 }
2201 #endif
2202 
2203 /* check the JPEG compression */
2204 static void transfer_check(struct gspca_dev *gspca_dev,
2205             u8 *data)
2206 {
2207     struct sd *sd = (struct sd *) gspca_dev;
2208     int new_qual, r;
2209 
2210     new_qual = 0;
2211 
2212     /* if USB error, discard the frame and decrease the quality */
2213     if (data[6] & 0x08) {               /* USB FIFO full */
2214         gspca_dev->last_packet_type = DISCARD_PACKET;
2215         new_qual = -5;
2216     } else {
2217 
2218         /* else, compute the filling rate and a new JPEG quality */
2219         r = (sd->pktsz * 100) /
2220             (sd->npkt *
2221                 gspca_dev->urb[0]->iso_frame_desc[0].length);
2222         if (r >= 85)
2223             new_qual = -3;
2224         else if (r < 75)
2225             new_qual = 2;
2226     }
2227     if (new_qual != 0) {
2228         sd->nchg += new_qual;
2229         if (sd->nchg < -6 || sd->nchg >= 12) {
2230             /* Note: we are in interrupt context, so we can't
2231                use v4l2_ctrl_g/s_ctrl here. Access the value
2232                directly instead. */
2233             s32 curqual = sd->jpegqual->cur.val;
2234             sd->nchg = 0;
2235             new_qual += curqual;
2236             if (new_qual < sd->jpegqual->minimum)
2237                 new_qual = sd->jpegqual->minimum;
2238             else if (new_qual > sd->jpegqual->maximum)
2239                 new_qual = sd->jpegqual->maximum;
2240             if (new_qual != curqual) {
2241                 sd->jpegqual->cur.val = new_qual;
2242                 schedule_work(&sd->work);
2243             }
2244         }
2245     } else {
2246         sd->nchg = 0;
2247     }
2248     sd->pktsz = sd->npkt = 0;
2249 }
2250 
2251 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2252             u8 *data,           /* isoc packet */
2253             int len)            /* iso packet length */
2254 {
2255     struct sd *sd = (struct sd *) gspca_dev;
2256     int avg_lum, is_jpeg;
2257     static const u8 frame_header[] = {
2258         0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96
2259     };
2260 
2261     is_jpeg = (sd->fmt & 0x03) == 0;
2262     if (len >= 64 && memcmp(data, frame_header, 6) == 0) {
2263         avg_lum = ((data[35] >> 2) & 3) |
2264                (data[20] << 2) |
2265                (data[19] << 10);
2266         avg_lum += ((data[35] >> 4) & 3) |
2267                 (data[22] << 2) |
2268                 (data[21] << 10);
2269         avg_lum += ((data[35] >> 6) & 3) |
2270                 (data[24] << 2) |
2271                 (data[23] << 10);
2272         avg_lum += (data[36] & 3) |
2273                (data[26] << 2) |
2274                (data[25] << 10);
2275         avg_lum += ((data[36] >> 2) & 3) |
2276                 (data[28] << 2) |
2277                 (data[27] << 10);
2278         avg_lum += ((data[36] >> 4) & 3) |
2279                 (data[30] << 2) |
2280                 (data[29] << 10);
2281         avg_lum += ((data[36] >> 6) & 3) |
2282                 (data[32] << 2) |
2283                 (data[31] << 10);
2284         avg_lum += ((data[44] >> 4) & 3) |
2285                 (data[34] << 2) |
2286                 (data[33] << 10);
2287         avg_lum >>= 9;
2288         atomic_set(&sd->avg_lum, avg_lum);
2289 
2290         if (is_jpeg)
2291             transfer_check(gspca_dev, data);
2292 
2293         gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
2294         len -= 64;
2295         if (len == 0)
2296             return;
2297         data += 64;
2298     }
2299     if (gspca_dev->last_packet_type == LAST_PACKET) {
2300         if (is_jpeg) {
2301             gspca_frame_add(gspca_dev, FIRST_PACKET,
2302                 sd->jpeg_hdr, JPEG_HDR_SZ);
2303             gspca_frame_add(gspca_dev, INTER_PACKET,
2304                 data, len);
2305         } else {
2306             gspca_frame_add(gspca_dev, FIRST_PACKET,
2307                 data, len);
2308         }
2309     } else {
2310         /* if JPEG, count the packets and their size */
2311         if (is_jpeg) {
2312             sd->npkt++;
2313             sd->pktsz += len;
2314         }
2315         gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
2316     }
2317 }
2318 
2319 /* sub-driver description */
2320 static const struct sd_desc sd_desc = {
2321     .name = KBUILD_MODNAME,
2322     .config = sd_config,
2323     .init = sd_init,
2324     .init_controls = sd_init_controls,
2325     .isoc_init = sd_isoc_init,
2326     .start = sd_start,
2327     .stopN = sd_stopN,
2328     .stop0 = sd_stop0,
2329     .pkt_scan = sd_pkt_scan,
2330 #if IS_ENABLED(CONFIG_INPUT)
2331     .int_pkt_scan = sd_int_pkt_scan,
2332 #endif
2333     .dq_callback = sd_dqcallback,
2334 #ifdef CONFIG_VIDEO_ADV_DEBUG
2335     .set_register = sd_dbg_s_register,
2336     .get_register = sd_dbg_g_register,
2337     .get_chip_info = sd_chip_info,
2338 #endif
2339 };
2340 
2341 #define SN9C20X(sensor, i2c_addr, flags) \
2342     .driver_info =  ((flags & 0xff) << 16) \
2343             | (SENSOR_ ## sensor << 8) \
2344             | (i2c_addr)
2345 
2346 static const struct usb_device_id device_table[] = {
2347     {USB_DEVICE(0x0c45, 0x6240), SN9C20X(MT9M001, 0x5d, 0)},
2348     {USB_DEVICE(0x0c45, 0x6242), SN9C20X(MT9M111, 0x5d, HAS_LED_TORCH)},
2349     {USB_DEVICE(0x0c45, 0x6248), SN9C20X(OV9655, 0x30, 0)},
2350     {USB_DEVICE(0x0c45, 0x624c), SN9C20X(MT9M112, 0x5d, 0)},
2351     {USB_DEVICE(0x0c45, 0x624e), SN9C20X(SOI968, 0x30, LED_REVERSE)},
2352     {USB_DEVICE(0x0c45, 0x624f), SN9C20X(OV9650, 0x30,
2353                          (FLIP_DETECT | HAS_NO_BUTTON))},
2354     {USB_DEVICE(0x0c45, 0x6251), SN9C20X(OV9650, 0x30, 0)},
2355     {USB_DEVICE(0x0c45, 0x6253), SN9C20X(OV9650, 0x30, 0)},
2356     {USB_DEVICE(0x0c45, 0x6260), SN9C20X(OV7670, 0x21, 0)},
2357     {USB_DEVICE(0x0c45, 0x6270), SN9C20X(MT9VPRB, 0x00, 0)},
2358     {USB_DEVICE(0x0c45, 0x627b), SN9C20X(OV7660, 0x21, FLIP_DETECT)},
2359     {USB_DEVICE(0x0c45, 0x627c), SN9C20X(HV7131R, 0x11, 0)},
2360     {USB_DEVICE(0x0c45, 0x627f), SN9C20X(OV9650, 0x30, 0)},
2361     {USB_DEVICE(0x0c45, 0x6280), SN9C20X(MT9M001, 0x5d, 0)},
2362     {USB_DEVICE(0x0c45, 0x6282), SN9C20X(MT9M111, 0x5d, 0)},
2363     {USB_DEVICE(0x0c45, 0x6288), SN9C20X(OV9655, 0x30, 0)},
2364     {USB_DEVICE(0x0c45, 0x628c), SN9C20X(MT9M112, 0x5d, 0)},
2365     {USB_DEVICE(0x0c45, 0x628e), SN9C20X(SOI968, 0x30, 0)},
2366     {USB_DEVICE(0x0c45, 0x628f), SN9C20X(OV9650, 0x30, 0)},
2367     {USB_DEVICE(0x0c45, 0x62a0), SN9C20X(OV7670, 0x21, 0)},
2368     {USB_DEVICE(0x0c45, 0x62b0), SN9C20X(MT9VPRB, 0x00, 0)},
2369     {USB_DEVICE(0x0c45, 0x62b3), SN9C20X(OV9655, 0x30, LED_REVERSE)},
2370     {USB_DEVICE(0x0c45, 0x62bb), SN9C20X(OV7660, 0x21, LED_REVERSE)},
2371     {USB_DEVICE(0x0c45, 0x62bc), SN9C20X(HV7131R, 0x11, 0)},
2372     {USB_DEVICE(0x045e, 0x00f4), SN9C20X(OV9650, 0x30, 0)},
2373     {USB_DEVICE(0x145f, 0x013d), SN9C20X(OV7660, 0x21, 0)},
2374     {USB_DEVICE(0x0458, 0x7029), SN9C20X(HV7131R, 0x11, 0)},
2375     {USB_DEVICE(0x0458, 0x7045), SN9C20X(MT9M112, 0x5d, LED_REVERSE)},
2376     {USB_DEVICE(0x0458, 0x704a), SN9C20X(MT9M112, 0x5d, 0)},
2377     {USB_DEVICE(0x0458, 0x704c), SN9C20X(MT9M112, 0x5d, 0)},
2378     {USB_DEVICE(0xa168, 0x0610), SN9C20X(HV7131R, 0x11, 0)},
2379     {USB_DEVICE(0xa168, 0x0611), SN9C20X(HV7131R, 0x11, 0)},
2380     {USB_DEVICE(0xa168, 0x0613), SN9C20X(HV7131R, 0x11, 0)},
2381     {USB_DEVICE(0xa168, 0x0618), SN9C20X(HV7131R, 0x11, 0)},
2382     {USB_DEVICE(0xa168, 0x0614), SN9C20X(MT9M111, 0x5d, 0)},
2383     {USB_DEVICE(0xa168, 0x0615), SN9C20X(MT9M111, 0x5d, 0)},
2384     {USB_DEVICE(0xa168, 0x0617), SN9C20X(MT9M111, 0x5d, 0)},
2385     {}
2386 };
2387 MODULE_DEVICE_TABLE(usb, device_table);
2388 
2389 /* -- device connect -- */
2390 static int sd_probe(struct usb_interface *intf,
2391             const struct usb_device_id *id)
2392 {
2393     return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
2394                 THIS_MODULE);
2395 }
2396 
2397 static struct usb_driver sd_driver = {
2398     .name = KBUILD_MODNAME,
2399     .id_table = device_table,
2400     .probe = sd_probe,
2401     .disconnect = gspca_disconnect,
2402 #ifdef CONFIG_PM
2403     .suspend = gspca_suspend,
2404     .resume = gspca_resume,
2405     .reset_resume = gspca_resume,
2406 #endif
2407 };
2408 
2409 module_usb_driver(sd_driver);