Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Sonix sn9c102p sn9c105 sn9c120 (jpeg) subdriver
0004  *
0005  * Copyright (C) 2009-2011 Jean-François Moine <http://moinejf.free.fr>
0006  * Copyright (C) 2005 Michel Xhaard mxhaard@magic.fr
0007  */
0008 
0009 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0010 
0011 #define MODULE_NAME "sonixj"
0012 
0013 #include <linux/input.h>
0014 #include "gspca.h"
0015 #include "jpeg.h"
0016 
0017 MODULE_AUTHOR("Jean-François Moine <http://moinejf.free.fr>");
0018 MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver");
0019 MODULE_LICENSE("GPL");
0020 
0021 /* specific webcam descriptor */
0022 struct sd {
0023     struct gspca_dev gspca_dev; /* !! must be the first item */
0024 
0025     atomic_t avg_lum;
0026     struct v4l2_ctrl *brightness;
0027     struct v4l2_ctrl *contrast;
0028     struct v4l2_ctrl *saturation;
0029     struct { /* red/blue balance control cluster */
0030         struct v4l2_ctrl *red_bal;
0031         struct v4l2_ctrl *blue_bal;
0032     };
0033     struct { /* hflip/vflip control cluster */
0034         struct v4l2_ctrl *vflip;
0035         struct v4l2_ctrl *hflip;
0036     };
0037     struct v4l2_ctrl *gamma;
0038     struct v4l2_ctrl *illum;
0039     struct v4l2_ctrl *sharpness;
0040     struct v4l2_ctrl *freq;
0041     u32 exposure;
0042 
0043     struct work_struct work;
0044 
0045     u32 pktsz;          /* (used by pkt_scan) */
0046     u16 npkt;
0047     s8 nchg;
0048     s8 short_mark;
0049 
0050     u8 quality;         /* image quality */
0051 #define QUALITY_MIN 25
0052 #define QUALITY_MAX 90
0053 #define QUALITY_DEF 70
0054 
0055     u8 reg01;
0056     u8 reg17;
0057     u8 reg18;
0058     u8 flags;
0059 
0060     s8 ag_cnt;
0061 #define AG_CNT_START 13
0062 
0063     u8 bridge;
0064 #define BRIDGE_SN9C102P 0
0065 #define BRIDGE_SN9C105 1
0066 #define BRIDGE_SN9C110 2
0067 #define BRIDGE_SN9C120 3
0068     u8 sensor;          /* Type of image sensor chip */
0069     u8 i2c_addr;
0070 
0071     u8 jpeg_hdr[JPEG_HDR_SZ];
0072 };
0073 enum sensors {
0074     SENSOR_ADCM1700,
0075     SENSOR_GC0307,
0076     SENSOR_HV7131R,
0077     SENSOR_MI0360,
0078     SENSOR_MI0360B,
0079     SENSOR_MO4000,
0080     SENSOR_MT9V111,
0081     SENSOR_OM6802,
0082     SENSOR_OV7630,
0083     SENSOR_OV7648,
0084     SENSOR_OV7660,
0085     SENSOR_PO1030,
0086     SENSOR_PO2030N,
0087     SENSOR_SOI768,
0088     SENSOR_SP80708,
0089 };
0090 
0091 static void qual_upd(struct work_struct *work);
0092 
0093 /* device flags */
0094 #define F_PDN_INV   0x01    /* inverse pin S_PWR_DN / sn_xxx tables */
0095 #define F_ILLUM     0x02    /* presence of illuminator */
0096 
0097 /* sn9c1xx definitions */
0098 /* register 0x01 */
0099 #define S_PWR_DN    0x01    /* sensor power down */
0100 #define S_PDN_INV   0x02    /* inverse pin S_PWR_DN */
0101 #define V_TX_EN     0x04    /* video transfer enable */
0102 #define LED     0x08    /* output to pin LED */
0103 #define SCL_SEL_OD  0x20    /* open-drain mode */
0104 #define SYS_SEL_48M 0x40    /* system clock 0: 24MHz, 1: 48MHz */
0105 /* register 0x17 */
0106 #define MCK_SIZE_MASK   0x1f    /* sensor master clock */
0107 #define SEN_CLK_EN  0x20    /* enable sensor clock */
0108 #define DEF_EN      0x80    /* defect pixel by 0: soft, 1: hard */
0109 
0110 static const struct v4l2_pix_format cif_mode[] = {
0111     {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
0112         .bytesperline = 352,
0113         .sizeimage = 352 * 288 * 4 / 8 + 590,
0114         .colorspace = V4L2_COLORSPACE_JPEG,
0115         .priv = 0},
0116 };
0117 static const struct v4l2_pix_format vga_mode[] = {
0118     {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
0119         .bytesperline = 160,
0120         .sizeimage = 160 * 120 * 4 / 8 + 590,
0121         .colorspace = V4L2_COLORSPACE_JPEG,
0122         .priv = 2},
0123     {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
0124         .bytesperline = 320,
0125         .sizeimage = 320 * 240 * 3 / 8 + 590,
0126         .colorspace = V4L2_COLORSPACE_JPEG,
0127         .priv = 1},
0128     {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
0129         .bytesperline = 640,
0130         /* Note 3 / 8 is not large enough, not even 5 / 8 is ?! */
0131         .sizeimage = 640 * 480 * 3 / 4 + 590,
0132         .colorspace = V4L2_COLORSPACE_JPEG,
0133         .priv = 0},
0134 };
0135 
0136 static const u8 sn_adcm1700[0x1c] = {
0137 /*  reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
0138     0x00,   0x43,   0x60,   0x00,   0x1a,   0x00,   0x00,   0x00,
0139 /*  reg8    reg9    rega    regb    regc    regd    rege    regf */
0140     0x80,   0x51,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
0141 /*  reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
0142     0x03,   0x00,   0x05,   0x01,   0x05,   0x16,   0x12,   0x42,
0143 /*  reg18   reg19   reg1a   reg1b */
0144     0x06,   0x00,   0x00,   0x00
0145 };
0146 
0147 static const u8 sn_gc0307[0x1c] = {
0148 /*  reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
0149     0x00,   0x61,   0x62,   0x00,   0x1a,   0x00,   0x00,   0x00,
0150 /*  reg8    reg9    rega    regb    regc    regd    rege    regf */
0151     0x80,   0x21,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
0152 /*  reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
0153     0x03,   0x00,   0x03,   0x01,   0x08,   0x28,   0x1e,   0x02,
0154 /*  reg18   reg19   reg1a   reg1b */
0155     0x06,   0x00,   0x00,   0x00
0156 };
0157 
0158 static const u8 sn_hv7131[0x1c] = {
0159 /*  reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
0160     0x00,   0x03,   0x60,   0x00,   0x1a,   0x20,   0x20,   0x20,
0161 /*  reg8    reg9    rega    regb    regc    regd    rege    regf */
0162     0x81,   0x11,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
0163 /*  reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
0164     0x03,   0x00,   0x00,   0x01,   0x03,   0x28,   0x1e,   0x41,
0165 /*  reg18   reg19   reg1a   reg1b */
0166     0x0a,   0x00,   0x00,   0x00
0167 };
0168 
0169 static const u8 sn_mi0360[0x1c] = {
0170 /*  reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
0171     0x00,   0x63,   0x40,   0x00,   0x1a,   0x20,   0x20,   0x20,
0172 /*  reg8    reg9    rega    regb    regc    regd    rege    regf */
0173     0x81,   0x5d,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
0174 /*  reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
0175     0x03,   0x00,   0x00,   0x02,   0x0a,   0x28,   0x1e,   0x61,
0176 /*  reg18   reg19   reg1a   reg1b */
0177     0x06,   0x00,   0x00,   0x00
0178 };
0179 
0180 static const u8 sn_mi0360b[0x1c] = {
0181 /*  reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
0182     0x00,   0x61,   0x40,   0x00,   0x1a,   0x00,   0x00,   0x00,
0183 /*  reg8    reg9    rega    regb    regc    regd    rege    regf */
0184     0x81,   0x5d,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
0185 /*  reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
0186     0x03,   0x00,   0x00,   0x02,   0x0a,   0x28,   0x1e,   0x40,
0187 /*  reg18   reg19   reg1a   reg1b */
0188     0x06,   0x00,   0x00,   0x00
0189 };
0190 
0191 static const u8 sn_mo4000[0x1c] = {
0192 /*  reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
0193     0x00,   0x23,   0x60,   0x00,   0x1a,   0x00,   0x20,   0x18,
0194 /*  reg8    reg9    rega    regb    regc    regd    rege    regf */
0195     0x81,   0x21,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
0196 /*  reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
0197     0x03,    0x00,  0x0b,   0x0f,   0x14,   0x28,   0x1e,   0x40,
0198 /*  reg18   reg19   reg1a   reg1b */
0199     0x08,   0x00,   0x00,   0x00
0200 };
0201 
0202 static const u8 sn_mt9v111[0x1c] = {
0203 /*  reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
0204     0x00,   0x61,   0x40,   0x00,   0x1a,   0x20,   0x20,   0x20,
0205 /*  reg8    reg9    rega    regb    regc    regd    rege    regf */
0206     0x81,   0x5c,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
0207 /*  reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
0208     0x03,   0x00,   0x00,   0x02,   0x1c,   0x28,   0x1e,   0x40,
0209 /*  reg18   reg19   reg1a   reg1b */
0210     0x06,   0x00,   0x00,   0x00
0211 };
0212 
0213 static const u8 sn_om6802[0x1c] = {
0214 /*  reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
0215     0x00,   0x23,   0x72,   0x00,   0x1a,   0x20,   0x20,   0x19,
0216 /*  reg8    reg9    rega    regb    regc    regd    rege    regf */
0217     0x80,   0x34,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
0218 /*  reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
0219     0x03,   0x00,   0x51,   0x01,   0x00,   0x28,   0x1e,   0x40,
0220 /*  reg18   reg19   reg1a   reg1b */
0221     0x05,   0x00,   0x00,   0x00
0222 };
0223 
0224 static const u8 sn_ov7630[0x1c] = {
0225 /*  reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
0226     0x00,   0x21,   0x40,   0x00,   0x1a,   0x00,   0x00,   0x00,
0227 /*  reg8    reg9    rega    regb    regc    regd    rege    regf */
0228     0x81,   0x21,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
0229 /*  reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
0230     0x03,   0x00,   0x04,   0x01,   0x0a,   0x28,   0x1e,   0xc2,
0231 /*  reg18   reg19   reg1a   reg1b */
0232     0x0b,   0x00,   0x00,   0x00
0233 };
0234 
0235 static const u8 sn_ov7648[0x1c] = {
0236 /*  reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
0237     0x00,   0x63,   0x40,   0x00,   0x1a,   0x20,   0x20,   0x20,
0238 /*  reg8    reg9    rega    regb    regc    regd    rege    regf */
0239     0x81,   0x21,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
0240 /*  reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
0241     0x03,   0x00,   0x00,   0x01,   0x00,   0x28,   0x1e,   0x00,
0242 /*  reg18   reg19   reg1a   reg1b */
0243     0x0b,   0x00,   0x00,   0x00
0244 };
0245 
0246 static const u8 sn_ov7660[0x1c] = {
0247 /*  reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
0248     0x00,   0x61,   0x40,   0x00,   0x1a,   0x00,   0x00,   0x00,
0249 /*  reg8    reg9    rega    regb    regc    regd    rege    regf */
0250     0x81,   0x21,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
0251 /*  reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
0252     0x03,   0x00,   0x01,   0x01,   0x08,   0x28,   0x1e,   0x20,
0253 /*  reg18   reg19   reg1a   reg1b */
0254     0x07,   0x00,   0x00,   0x00
0255 };
0256 
0257 static const u8 sn_po1030[0x1c] = {
0258 /*  reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
0259     0x00,   0x21,   0x62,   0x00,   0x1a,   0x20,   0x20,   0x20,
0260 /*  reg8    reg9    rega    regb    regc    regd    rege    regf */
0261     0x81,   0x6e,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
0262 /*  reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
0263     0x03,   0x00,   0x00,   0x06,   0x06,   0x28,   0x1e,   0x00,
0264 /*  reg18   reg19   reg1a   reg1b */
0265     0x07,   0x00,   0x00,   0x00
0266 };
0267 
0268 static const u8 sn_po2030n[0x1c] = {
0269 /*  reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
0270     0x00,   0x63,   0x40,   0x00,   0x1a,   0x00,   0x00,   0x00,
0271 /*  reg8    reg9    rega    regb    regc    regd    rege    regf */
0272     0x81,   0x6e,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
0273 /*  reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
0274     0x03,   0x00,   0x00,   0x01,   0x14,   0x28,   0x1e,   0x00,
0275 /*  reg18   reg19   reg1a   reg1b */
0276     0x07,   0x00,   0x00,   0x00
0277 };
0278 
0279 static const u8 sn_soi768[0x1c] = {
0280 /*  reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
0281     0x00,   0x21,   0x40,   0x00,   0x1a,   0x00,   0x00,   0x00,
0282 /*  reg8    reg9    rega    regb    regc    regd    rege    regf */
0283     0x81,   0x21,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
0284 /*  reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
0285     0x03,   0x00,   0x00,   0x01,   0x08,   0x28,   0x1e,   0x00,
0286 /*  reg18   reg19   reg1a   reg1b */
0287     0x07,   0x00,   0x00,   0x00
0288 };
0289 
0290 static const u8 sn_sp80708[0x1c] = {
0291 /*  reg0    reg1    reg2    reg3    reg4    reg5    reg6    reg7 */
0292     0x00,   0x63,   0x60,   0x00,   0x1a,   0x20,   0x20,   0x20,
0293 /*  reg8    reg9    rega    regb    regc    regd    rege    regf */
0294     0x81,   0x18,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,
0295 /*  reg10   reg11   reg12   reg13   reg14   reg15   reg16   reg17 */
0296     0x03,   0x00,   0x00,   0x03,   0x04,   0x28,   0x1e,   0x00,
0297 /*  reg18   reg19   reg1a   reg1b */
0298     0x07,   0x00,   0x00,   0x00
0299 };
0300 
0301 /* sequence specific to the sensors - !! index = SENSOR_xxx */
0302 static const u8 *sn_tb[] = {
0303 [SENSOR_ADCM1700] = sn_adcm1700,
0304 [SENSOR_GC0307] =   sn_gc0307,
0305 [SENSOR_HV7131R] =  sn_hv7131,
0306 [SENSOR_MI0360] =   sn_mi0360,
0307 [SENSOR_MI0360B] =  sn_mi0360b,
0308 [SENSOR_MO4000] =   sn_mo4000,
0309 [SENSOR_MT9V111] =  sn_mt9v111,
0310 [SENSOR_OM6802] =   sn_om6802,
0311 [SENSOR_OV7630] =   sn_ov7630,
0312 [SENSOR_OV7648] =   sn_ov7648,
0313 [SENSOR_OV7660] =   sn_ov7660,
0314 [SENSOR_PO1030] =   sn_po1030,
0315 [SENSOR_PO2030N] =  sn_po2030n,
0316 [SENSOR_SOI768] =   sn_soi768,
0317 [SENSOR_SP80708] =  sn_sp80708,
0318 };
0319 
0320 /* default gamma table */
0321 static const u8 gamma_def[17] = {
0322     0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
0323     0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
0324 };
0325 /* gamma for sensor ADCM1700 */
0326 static const u8 gamma_spec_0[17] = {
0327     0x0f, 0x39, 0x5a, 0x74, 0x86, 0x95, 0xa6, 0xb4,
0328     0xbd, 0xc4, 0xcc, 0xd4, 0xd5, 0xde, 0xe4, 0xed, 0xf5
0329 };
0330 /* gamma for sensors HV7131R and MT9V111 */
0331 static const u8 gamma_spec_1[17] = {
0332     0x08, 0x3a, 0x52, 0x65, 0x75, 0x83, 0x91, 0x9d,
0333     0xa9, 0xb4, 0xbe, 0xc8, 0xd2, 0xdb, 0xe4, 0xed, 0xf5
0334 };
0335 /* gamma for sensor GC0307 */
0336 static const u8 gamma_spec_2[17] = {
0337     0x14, 0x37, 0x50, 0x6a, 0x7c, 0x8d, 0x9d, 0xab,
0338     0xb5, 0xbf, 0xc2, 0xcb, 0xd1, 0xd6, 0xdb, 0xe1, 0xeb
0339 };
0340 /* gamma for sensor SP80708 */
0341 static const u8 gamma_spec_3[17] = {
0342     0x0a, 0x2d, 0x4e, 0x68, 0x7d, 0x8f, 0x9f, 0xab,
0343     0xb7, 0xc2, 0xcc, 0xd3, 0xd8, 0xde, 0xe2, 0xe5, 0xe6
0344 };
0345 
0346 /* color matrix and offsets */
0347 static const u8 reg84[] = {
0348     0x14, 0x00, 0x27, 0x00, 0x07, 0x00, /* YR YG YB gains */
0349     0xe8, 0x0f, 0xda, 0x0f, 0x40, 0x00, /* UR UG UB */
0350     0x3e, 0x00, 0xcd, 0x0f, 0xf7, 0x0f, /* VR VG VB */
0351     0x00, 0x00, 0x00            /* YUV offsets */
0352 };
0353 
0354 #define DELAY   0xdd
0355 
0356 static const u8 adcm1700_sensor_init[][8] = {
0357     {0xa0, 0x51, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x10},
0358     {0xb0, 0x51, 0x04, 0x08, 0x00, 0x00, 0x00, 0x10},   /* reset */
0359     {DELAY, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
0360     {0xb0, 0x51, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
0361     {DELAY, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
0362     {0xb0, 0x51, 0x0c, 0xe0, 0x2e, 0x00, 0x00, 0x10},
0363     {0xb0, 0x51, 0x10, 0x02, 0x02, 0x00, 0x00, 0x10},
0364     {0xb0, 0x51, 0x14, 0x0e, 0x0e, 0x00, 0x00, 0x10},
0365     {0xb0, 0x51, 0x1c, 0x00, 0x80, 0x00, 0x00, 0x10},
0366     {0xb0, 0x51, 0x20, 0x01, 0x00, 0x00, 0x00, 0x10},
0367     {DELAY, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
0368     {0xb0, 0x51, 0x04, 0x04, 0x00, 0x00, 0x00, 0x10},
0369     {DELAY, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
0370     {0xb0, 0x51, 0x04, 0x01, 0x00, 0x00, 0x00, 0x10},
0371     {0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10},
0372     {0xb0, 0x51, 0x14, 0x01, 0x00, 0x00, 0x00, 0x10},
0373     {0xb0, 0x51, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
0374     {}
0375 };
0376 static const u8 adcm1700_sensor_param1[][8] = {
0377     {0xb0, 0x51, 0x26, 0xf9, 0x01, 0x00, 0x00, 0x10},   /* exposure? */
0378     {0xd0, 0x51, 0x1e, 0x8e, 0x8e, 0x8e, 0x8e, 0x10},
0379 
0380     {0xa0, 0x51, 0xfe, 0x01, 0x00, 0x00, 0x00, 0x10},
0381     {0xb0, 0x51, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10},
0382     {0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10},
0383     {0xb0, 0x51, 0x32, 0x00, 0x72, 0x00, 0x00, 0x10},
0384     {0xd0, 0x51, 0x1e, 0xbe, 0xd7, 0xe8, 0xbe, 0x10},   /* exposure? */
0385 
0386     {0xa0, 0x51, 0xfe, 0x01, 0x00, 0x00, 0x00, 0x10},
0387     {0xb0, 0x51, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10},
0388     {0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10},
0389     {0xb0, 0x51, 0x32, 0x00, 0xa2, 0x00, 0x00, 0x10},
0390     {}
0391 };
0392 static const u8 gc0307_sensor_init[][8] = {
0393     {0xa0, 0x21, 0x43, 0x00, 0x00, 0x00, 0x00, 0x10},
0394     {0xa0, 0x21, 0x44, 0xa2, 0x00, 0x00, 0x00, 0x10},
0395     {0xa0, 0x21, 0x01, 0x6a, 0x00, 0x00, 0x00, 0x10},
0396     {0xa0, 0x21, 0x02, 0x70, 0x00, 0x00, 0x00, 0x10},
0397     {0xa0, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
0398     {0xa0, 0x21, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10},
0399     {0xa0, 0x21, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x10},
0400     {0xa0, 0x21, 0x11, 0x05, 0x00, 0x00, 0x00, 0x10},
0401     {0xa0, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
0402     {0xa0, 0x21, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10},
0403     {0xa0, 0x21, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10},
0404     {0xa0, 0x21, 0x08, 0x02, 0x00, 0x00, 0x00, 0x10},
0405     {0xa0, 0x21, 0x09, 0x01, 0x00, 0x00, 0x00, 0x10},
0406     {0xa0, 0x21, 0x0a, 0xe8, 0x00, 0x00, 0x00, 0x10},
0407     {0xa0, 0x21, 0x0b, 0x02, 0x00, 0x00, 0x00, 0x10},
0408     {0xa0, 0x21, 0x0c, 0x80, 0x00, 0x00, 0x00, 0x10},
0409     {0xa0, 0x21, 0x0d, 0x22, 0x00, 0x00, 0x00, 0x10},
0410     {0xa0, 0x21, 0x0e, 0x02, 0x00, 0x00, 0x00, 0x10},
0411     {0xa0, 0x21, 0x0f, 0xb2, 0x00, 0x00, 0x00, 0x10},
0412     {0xa0, 0x21, 0x12, 0x70, 0x00, 0x00, 0x00, 0x10},
0413     {DELAY, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*delay 10ms*/
0414     {0xa0, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00, 0x10},
0415     {0xa0, 0x21, 0x15, 0xb8, 0x00, 0x00, 0x00, 0x10},
0416     {0xa0, 0x21, 0x16, 0x13, 0x00, 0x00, 0x00, 0x10},
0417     {0xa0, 0x21, 0x17, 0x52, 0x00, 0x00, 0x00, 0x10},
0418     {0xa0, 0x21, 0x18, 0x50, 0x00, 0x00, 0x00, 0x10},
0419     {0xa0, 0x21, 0x1e, 0x0d, 0x00, 0x00, 0x00, 0x10},
0420     {0xa0, 0x21, 0x1f, 0x32, 0x00, 0x00, 0x00, 0x10},
0421     {0xa0, 0x21, 0x61, 0x90, 0x00, 0x00, 0x00, 0x10},
0422     {0xa0, 0x21, 0x63, 0x70, 0x00, 0x00, 0x00, 0x10},
0423     {0xa0, 0x21, 0x65, 0x98, 0x00, 0x00, 0x00, 0x10},
0424     {0xa0, 0x21, 0x67, 0x90, 0x00, 0x00, 0x00, 0x10},
0425     {0xa0, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
0426     {0xa0, 0x21, 0x04, 0x96, 0x00, 0x00, 0x00, 0x10},
0427     {0xa0, 0x21, 0x45, 0x27, 0x00, 0x00, 0x00, 0x10},
0428     {0xa0, 0x21, 0x47, 0x2c, 0x00, 0x00, 0x00, 0x10},
0429     {0xa0, 0x21, 0x43, 0x47, 0x00, 0x00, 0x00, 0x10},
0430     {0xa0, 0x21, 0x44, 0xd8, 0x00, 0x00, 0x00, 0x10},
0431     {}
0432 };
0433 static const u8 gc0307_sensor_param1[][8] = {
0434     {0xa0, 0x21, 0x68, 0x13, 0x00, 0x00, 0x00, 0x10},
0435     {0xd0, 0x21, 0x61, 0x80, 0x00, 0x80, 0x00, 0x10},
0436     {0xc0, 0x21, 0x65, 0x80, 0x00, 0x80, 0x00, 0x10},
0437     {0xc0, 0x21, 0x63, 0xa0, 0x00, 0xa6, 0x00, 0x10},
0438 /*param3*/
0439     {0xa0, 0x21, 0x01, 0x6e, 0x00, 0x00, 0x00, 0x10},
0440     {0xa0, 0x21, 0x02, 0x88, 0x00, 0x00, 0x00, 0x10},
0441     {}
0442 };
0443 
0444 static const u8 hv7131r_sensor_init[][8] = {
0445     {0xc1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
0446     {0xb1, 0x11, 0x34, 0x17, 0x7f, 0x00, 0x00, 0x10},
0447     {0xd1, 0x11, 0x40, 0xff, 0x7f, 0x7f, 0x7f, 0x10},
0448 /*  {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10}, */
0449     {0xd1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
0450     {0xd1, 0x11, 0x14, 0x01, 0xe2, 0x02, 0x82, 0x10},
0451 /*  {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10}, */
0452 
0453     {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
0454     {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
0455     {0xc1, 0x11, 0x25, 0x00, 0x61, 0xa8, 0x00, 0x10},
0456     {0xa1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10},
0457     {0xc1, 0x11, 0x31, 0x20, 0x2e, 0x20, 0x00, 0x10},
0458     {0xc1, 0x11, 0x25, 0x00, 0xc3, 0x50, 0x00, 0x10},
0459     {0xa1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */
0460     {0xc1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */
0461 
0462     {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
0463     {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
0464     {0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10},
0465     {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
0466     {0xa1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10},
0467 
0468     {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
0469     {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
0470     {0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10},
0471     {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
0472     {0xa1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10},
0473     {0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10},
0474                             /* set sensor clock */
0475     {}
0476 };
0477 static const u8 mi0360_sensor_init[][8] = {
0478     {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
0479     {0xb1, 0x5d, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10},
0480     {0xb1, 0x5d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
0481     {0xd1, 0x5d, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
0482     {0xd1, 0x5d, 0x03, 0x01, 0xe2, 0x02, 0x82, 0x10},
0483     {0xd1, 0x5d, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10},
0484     {0xb1, 0x5d, 0x0d, 0x00, 0x02, 0x00, 0x00, 0x10},
0485     {0xd1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
0486     {0xd1, 0x5d, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10},
0487     {0xd1, 0x5d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
0488     {0xd1, 0x5d, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
0489     {0xd1, 0x5d, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
0490     {0xd1, 0x5d, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
0491     {0xd1, 0x5d, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
0492     {0xd1, 0x5d, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
0493     {0xd1, 0x5d, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x10},
0494     {0xd1, 0x5d, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10},
0495     {0xb1, 0x5d, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
0496     {0xd1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
0497     {0xd1, 0x5d, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
0498     {0xd1, 0x5d, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
0499     {0xd1, 0x5d, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
0500     {0xd1, 0x5d, 0x2f, 0xf7, 0xb0, 0x00, 0x04, 0x10},
0501     {0xd1, 0x5d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
0502     {0xd1, 0x5d, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
0503     {0xb1, 0x5d, 0x3d, 0x06, 0x8f, 0x00, 0x00, 0x10},
0504     {0xd1, 0x5d, 0x40, 0x01, 0xe0, 0x00, 0xd1, 0x10},
0505     {0xb1, 0x5d, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
0506     {0xd1, 0x5d, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
0507     {0xd1, 0x5d, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x10},
0508     {0xd1, 0x5d, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x10},
0509     {0xd1, 0x5d, 0x5e, 0x00, 0x00, 0xa3, 0x1d, 0x10},
0510     {0xb1, 0x5d, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
0511 
0512     {0xb1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
0513     {0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
0514     {0xb1, 0x5d, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
0515     {0xd1, 0x5d, 0x2b, 0x00, 0xa0, 0x00, 0xb0, 0x10},
0516     {0xd1, 0x5d, 0x2d, 0x00, 0xa0, 0x00, 0xa0, 0x10},
0517 
0518     {0xb1, 0x5d, 0x0a, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */
0519     {0xb1, 0x5d, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10},
0520     {0xb1, 0x5d, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10},
0521     {0xb1, 0x5d, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
0522 
0523     {0xd1, 0x5d, 0x2b, 0x00, 0xb9, 0x00, 0xe3, 0x10},
0524     {0xd1, 0x5d, 0x2d, 0x00, 0x5f, 0x00, 0xb9, 0x10}, /* 42 */
0525 /*  {0xb1, 0x5d, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */
0526 /*  {0xb1, 0x5d, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */
0527     {0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
0528     {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
0529     {}
0530 };
0531 static const u8 mi0360b_sensor_init[][8] = {
0532     {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
0533     {0xb1, 0x5d, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10},
0534     {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*delay 20ms*/
0535     {0xb1, 0x5d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
0536     {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*delay 20ms*/
0537     {0xd1, 0x5d, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
0538     {0xd1, 0x5d, 0x03, 0x01, 0xe2, 0x02, 0x82, 0x10},
0539     {0xd1, 0x5d, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
0540     {0xb1, 0x5d, 0x0d, 0x00, 0x02, 0x00, 0x00, 0x10},
0541     {0xd1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
0542     {0xd1, 0x5d, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10},
0543     {0xd1, 0x5d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
0544     {0xd1, 0x5d, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
0545     {0xd1, 0x5d, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
0546     {0xd1, 0x5d, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
0547     {0xd1, 0x5d, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
0548     {0xd1, 0x5d, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
0549     {0xd1, 0x5d, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x10},
0550     {0xd1, 0x5d, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10},
0551     {0xb1, 0x5d, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
0552     {0xd1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
0553     {0xd1, 0x5d, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
0554     {0xd1, 0x5d, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
0555     {0xd1, 0x5d, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
0556     {0xd1, 0x5d, 0x2f, 0xf7, 0xb0, 0x00, 0x04, 0x10},
0557     {0xd1, 0x5d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
0558     {0xd1, 0x5d, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
0559     {0xb1, 0x5d, 0x3d, 0x06, 0x8f, 0x00, 0x00, 0x10},
0560     {0xd1, 0x5d, 0x40, 0x01, 0xe0, 0x00, 0xd1, 0x10},
0561     {0xb1, 0x5d, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
0562     {0xd1, 0x5d, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
0563     {0xd1, 0x5d, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x10},
0564     {0xd1, 0x5d, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x10},
0565     {0xd1, 0x5d, 0x5e, 0x00, 0x00, 0xa3, 0x1d, 0x10},
0566     {0xb1, 0x5d, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
0567 
0568     {0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
0569     {0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
0570     {0xb1, 0x5d, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
0571     {0xd1, 0x5d, 0x2b, 0x00, 0x33, 0x00, 0xa0, 0x10},
0572     {0xd1, 0x5d, 0x2d, 0x00, 0xa0, 0x00, 0x33, 0x10},
0573     {}
0574 };
0575 static const u8 mi0360b_sensor_param1[][8] = {
0576     {0xb1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
0577     {0xb1, 0x5d, 0x06, 0x00, 0x53, 0x00, 0x00, 0x10},
0578     {0xb1, 0x5d, 0x05, 0x00, 0x09, 0x00, 0x00, 0x10},
0579     {0xb1, 0x5d, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
0580 
0581     {0xd1, 0x5d, 0x2b, 0x00, 0xd1, 0x01, 0xc9, 0x10},
0582     {0xd1, 0x5d, 0x2d, 0x00, 0xed, 0x00, 0xd1, 0x10},
0583     {0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
0584     {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
0585     {}
0586 };
0587 static const u8 mo4000_sensor_init[][8] = {
0588     {0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10},
0589     {0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10},
0590     {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
0591     {0xa1, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
0592     {0xa1, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
0593     {0xa1, 0x21, 0x05, 0x04, 0x00, 0x00, 0x00, 0x10},
0594     {0xa1, 0x21, 0x06, 0x80, 0x00, 0x00, 0x00, 0x10},
0595     {0xa1, 0x21, 0x06, 0x81, 0x00, 0x00, 0x00, 0x10},
0596     {0xa1, 0x21, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
0597     {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
0598     {0xa1, 0x21, 0x11, 0x20, 0x00, 0x00, 0x00, 0x10},
0599     {0xa1, 0x21, 0x11, 0x30, 0x00, 0x00, 0x00, 0x10},
0600     {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
0601     {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
0602     {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
0603     {0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
0604     {0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10},
0605     {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10},
0606     {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
0607     {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
0608     {}
0609 };
0610 static const u8 mt9v111_sensor_init[][8] = {
0611     {0xb1, 0x5c, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10}, /* reset? */
0612     {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
0613     {0xb1, 0x5c, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
0614     {0xb1, 0x5c, 0x01, 0x00, 0x01, 0x00, 0x00, 0x10}, /* IFP select */
0615     {0xb1, 0x5c, 0x08, 0x04, 0x80, 0x00, 0x00, 0x10}, /* output fmt ctrl */
0616     {0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10}, /* op mode ctrl */
0617     {0xb1, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10}, /* sensor select */
0618     {0xb1, 0x5c, 0x08, 0x00, 0x08, 0x00, 0x00, 0x10}, /* row start */
0619     {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10}, /* col start */
0620     {0xb1, 0x5c, 0x03, 0x01, 0xe7, 0x00, 0x00, 0x10}, /* window height */
0621     {0xb1, 0x5c, 0x04, 0x02, 0x87, 0x00, 0x00, 0x10}, /* window width */
0622     {0xb1, 0x5c, 0x07, 0x30, 0x02, 0x00, 0x00, 0x10}, /* output ctrl */
0623     {0xb1, 0x5c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10}, /* shutter delay */
0624     {0xb1, 0x5c, 0x12, 0x00, 0xb0, 0x00, 0x00, 0x10}, /* zoom col start */
0625     {0xb1, 0x5c, 0x13, 0x00, 0x7c, 0x00, 0x00, 0x10}, /* zoom row start */
0626     {0xb1, 0x5c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* digital zoom */
0627     {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, /* read mode */
0628     {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
0629     {}
0630 };
0631 static const u8 mt9v111_sensor_param1[][8] = {
0632     {0xd1, 0x5c, 0x2b, 0x00, 0x33, 0x00, 0xad, 0x10}, /* G1 and B gains */
0633     {0xd1, 0x5c, 0x2d, 0x00, 0xad, 0x00, 0x33, 0x10}, /* R and G2 gains */
0634     {0xb1, 0x5c, 0x06, 0x00, 0x40, 0x00, 0x00, 0x10}, /* vert blanking */
0635     {0xb1, 0x5c, 0x05, 0x00, 0x09, 0x00, 0x00, 0x10}, /* horiz blanking */
0636     {0xb1, 0x5c, 0x35, 0x01, 0xc0, 0x00, 0x00, 0x10}, /* global gain */
0637     {}
0638 };
0639 static const u8 om6802_init0[2][8] = {
0640 /*fixme: variable*/
0641     {0xa0, 0x34, 0x29, 0x0e, 0x00, 0x00, 0x00, 0x10},
0642     {0xa0, 0x34, 0x23, 0xb0, 0x00, 0x00, 0x00, 0x10},
0643 };
0644 static const u8 om6802_sensor_init[][8] = {
0645     {0xa0, 0x34, 0xdf, 0x6d, 0x00, 0x00, 0x00, 0x10},
0646                         /* factory mode */
0647     {0xa0, 0x34, 0xdd, 0x18, 0x00, 0x00, 0x00, 0x10},
0648                         /* output raw RGB */
0649     {0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10},
0650 /*  {0xa0, 0x34, 0xfb, 0x11, 0x00, 0x00, 0x00, 0x10}, */
0651     {0xa0, 0x34, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x10},
0652         /* auto-exposure speed (0) / white balance mode (auto RGB) */
0653 /*  {0xa0, 0x34, 0xf1, 0x02, 0x00, 0x00, 0x00, 0x10},
0654                              * set color mode */
0655 /*  {0xa0, 0x34, 0xfe, 0x5b, 0x00, 0x00, 0x00, 0x10},
0656                          * max AGC value in AE */
0657 /*  {0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10},
0658                              * preset AGC */
0659 /*  {0xa0, 0x34, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x10},
0660                          * preset brightness */
0661 /*  {0xa0, 0x34, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x10},
0662                              * preset contrast */
0663 /*  {0xa0, 0x34, 0xe8, 0x31, 0x00, 0x00, 0x00, 0x10},
0664                              * preset gamma */
0665     {0xa0, 0x34, 0xe9, 0x0f, 0x00, 0x00, 0x00, 0x10},
0666                 /* luminance mode (0x4f -> AutoExpo on) */
0667     {0xa0, 0x34, 0xe4, 0xff, 0x00, 0x00, 0x00, 0x10},
0668                             /* preset shutter */
0669 /*  {0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10},
0670                              * auto frame rate */
0671 /*  {0xa0, 0x34, 0xfb, 0xee, 0x00, 0x00, 0x00, 0x10}, */
0672     {0xa0, 0x34, 0x5d, 0x80, 0x00, 0x00, 0x00, 0x10},
0673     {}
0674 };
0675 static const u8 om6802_sensor_param1[][8] = {
0676     {0xa0, 0x34, 0x71, 0x84, 0x00, 0x00, 0x00, 0x10},
0677     {0xa0, 0x34, 0x72, 0x05, 0x00, 0x00, 0x00, 0x10},
0678     {0xa0, 0x34, 0x68, 0x80, 0x00, 0x00, 0x00, 0x10},
0679     {0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10},
0680     {}
0681 };
0682 static const u8 ov7630_sensor_init[][8] = {
0683     {0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10},
0684     {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
0685     {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
0686     {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
0687     {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
0688     {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
0689     {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
0690 /* win: i2c_r from 00 to 80 */
0691     {0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10},
0692     {0xb1, 0x21, 0x0c, 0x20, 0x20, 0x00, 0x00, 0x10},
0693 /* HDG: 0x11 was 0x00 change to 0x01 for better exposure (15 fps instead of 30)
0694     0x13 was 0xc0 change to 0xc3 for auto gain and exposure */
0695     {0xd1, 0x21, 0x11, 0x01, 0x48, 0xc3, 0x00, 0x10},
0696     {0xb1, 0x21, 0x15, 0x80, 0x03, 0x00, 0x00, 0x10},
0697     {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
0698     {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
0699     {0xd1, 0x21, 0x1f, 0x00, 0x80, 0x80, 0x80, 0x10},
0700     {0xd1, 0x21, 0x23, 0xde, 0x10, 0x8a, 0xa0, 0x10},
0701     {0xc1, 0x21, 0x27, 0xca, 0xa2, 0x74, 0x00, 0x10},
0702     {0xd1, 0x21, 0x2a, 0x88, 0x00, 0x88, 0x01, 0x10},
0703     {0xc1, 0x21, 0x2e, 0x80, 0x00, 0x18, 0x00, 0x10},
0704     {0xa1, 0x21, 0x21, 0x08, 0x00, 0x00, 0x00, 0x10},
0705     {0xa1, 0x21, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
0706     {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
0707     {0xb1, 0x21, 0x32, 0xc2, 0x08, 0x00, 0x00, 0x10},
0708     {0xb1, 0x21, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x10},
0709     {0xd1, 0x21, 0x60, 0x05, 0x40, 0x12, 0x57, 0x10},
0710     {0xa1, 0x21, 0x64, 0x73, 0x00, 0x00, 0x00, 0x10},
0711     {0xd1, 0x21, 0x65, 0x00, 0x55, 0x01, 0xac, 0x10},
0712     {0xa1, 0x21, 0x69, 0x38, 0x00, 0x00, 0x00, 0x10},
0713     {0xd1, 0x21, 0x6f, 0x1f, 0x01, 0x00, 0x10, 0x10},
0714     {0xd1, 0x21, 0x73, 0x50, 0x20, 0x02, 0x01, 0x10},
0715     {0xd1, 0x21, 0x77, 0xf3, 0x90, 0x98, 0x98, 0x10},
0716     {0xc1, 0x21, 0x7b, 0x00, 0x4c, 0xf7, 0x00, 0x10},
0717     {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
0718     {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
0719     {}
0720 };
0721 static const u8 ov7630_sensor_param1[][8] = {
0722     {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
0723     {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
0724 /*fixme: + 0x12, 0x04*/
0725 /*  {0xa1, 0x21, 0x75, 0x82, 0x00, 0x00, 0x00, 0x10},  * COMN
0726                              * set by setvflip */
0727     {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
0728     {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
0729     {0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10},
0730 /* */
0731 /*  {0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10}, * set by setfreq */
0732 /*  {0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10}, * set by setfreq */
0733 /* */
0734     {0xa1, 0x21, 0x10, 0x83, 0x00, 0x00, 0x00, 0x10},
0735 /*  {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, */
0736     {}
0737 };
0738 
0739 static const u8 ov7648_sensor_init[][8] = {
0740     {0xa1, 0x21, 0x76, 0x00, 0x00, 0x00, 0x00, 0x10},
0741     {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},   /* reset */
0742     {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
0743     {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
0744     {0xd1, 0x21, 0x03, 0xa4, 0x30, 0x88, 0x00, 0x10},
0745     {0xb1, 0x21, 0x11, 0x80, 0x08, 0x00, 0x00, 0x10},
0746     {0xc1, 0x21, 0x13, 0xa0, 0x04, 0x84, 0x00, 0x10},
0747     {0xd1, 0x21, 0x17, 0x1a, 0x02, 0xba, 0xf4, 0x10},
0748     {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
0749     {0xd1, 0x21, 0x1f, 0x41, 0xc0, 0x80, 0x80, 0x10},
0750     {0xd1, 0x21, 0x23, 0xde, 0xa0, 0x80, 0x32, 0x10},
0751     {0xd1, 0x21, 0x27, 0xfe, 0xa0, 0x00, 0x91, 0x10},
0752     {0xd1, 0x21, 0x2b, 0x00, 0x88, 0x85, 0x80, 0x10},
0753     {0xc1, 0x21, 0x2f, 0x9c, 0x00, 0xc4, 0x00, 0x10},
0754     {0xd1, 0x21, 0x60, 0xa6, 0x60, 0x88, 0x12, 0x10},
0755     {0xd1, 0x21, 0x64, 0x88, 0x00, 0x00, 0x94, 0x10},
0756     {0xd1, 0x21, 0x68, 0x7a, 0x0c, 0x00, 0x00, 0x10},
0757     {0xd1, 0x21, 0x6c, 0x11, 0x33, 0x22, 0x00, 0x10},
0758     {0xd1, 0x21, 0x70, 0x11, 0x00, 0x10, 0x50, 0x10},
0759     {0xd1, 0x21, 0x74, 0x20, 0x06, 0x00, 0xb5, 0x10},
0760     {0xd1, 0x21, 0x78, 0x8a, 0x00, 0x00, 0x00, 0x10},
0761     {0xb1, 0x21, 0x7c, 0x00, 0x43, 0x00, 0x00, 0x10},
0762 
0763     {0xd1, 0x21, 0x21, 0x86, 0x00, 0xde, 0xa0, 0x10},
0764 /*  {0xd1, 0x21, 0x25, 0x80, 0x32, 0xfe, 0xa0, 0x10}, jfm done */
0765 /*  {0xd1, 0x21, 0x29, 0x00, 0x91, 0x00, 0x88, 0x10}, jfm done */
0766 /*  {0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10}, set by setfreq */
0767     {}
0768 };
0769 static const u8 ov7648_sensor_param1[][8] = {
0770 /*  {0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */
0771 /*  {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10},   * COMN
0772                              * set by setvflip */
0773     {0xa1, 0x21, 0x19, 0x02, 0x00, 0x00, 0x00, 0x10},
0774     {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
0775 /*  {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
0776 /*  {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},  * GAIN - def */
0777 /*  {0xb1, 0x21, 0x01, 0x6c, 0x6c, 0x00, 0x00, 0x10},  * B R - def: 80 */
0778 /*...*/
0779     {0xa1, 0x21, 0x11, 0x81, 0x00, 0x00, 0x00, 0x10}, /* CLKRC */
0780 /*  {0xa1, 0x21, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
0781 /*  {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
0782 /*  {0xa1, 0x21, 0x2a, 0x91, 0x00, 0x00, 0x00, 0x10}, jfm done */
0783 /*  {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
0784 /*  {0xb1, 0x21, 0x01, 0x64, 0x84, 0x00, 0x00, 0x10},  * B R - def: 80 */
0785 
0786     {}
0787 };
0788 
0789 static const u8 ov7660_sensor_init[][8] = {
0790     {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
0791     {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
0792     {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
0793                         /* Outformat = rawRGB */
0794     {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
0795     {0xd1, 0x21, 0x00, 0x01, 0x74, 0x92, 0x00, 0x10},
0796                         /* GAIN BLUE RED VREF */
0797     {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10},
0798                         /* COM 1 BAVE GEAVE AECHH */
0799     {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */
0800     {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */
0801     {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10},
0802                         /* AECH CLKRC COM7 COM8 */
0803     {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */
0804     {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10},
0805                         /* HSTART HSTOP VSTRT VSTOP */
0806     {0xa1, 0x21, 0x1b, 0x02, 0x00, 0x00, 0x00, 0x10}, /* PSHFT */
0807     {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */
0808     {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10},
0809                     /* BOS GBOS GROS ROS (BGGR offset) */
0810 /*  {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, */
0811     {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10},
0812                         /* AEW AEB VPT BBIAS */
0813     {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10},
0814                         /* GbBIAS RSVD EXHCH EXHCL */
0815     {0xd1, 0x21, 0x2c, 0x80, 0x00, 0x00, 0x62, 0x10},
0816                         /* RBIAS ADVFL ASDVFH YAVE */
0817     {0xc1, 0x21, 0x30, 0x08, 0x30, 0xb4, 0x00, 0x10},
0818                         /* HSYST HSYEN HREF */
0819     {0xd1, 0x21, 0x33, 0x00, 0x07, 0x84, 0x00, 0x10}, /* reserved */
0820     {0xd1, 0x21, 0x37, 0x0c, 0x02, 0x43, 0x00, 0x10},
0821                         /* ADC ACOM OFON TSLB */
0822     {0xd1, 0x21, 0x3b, 0x02, 0x6c, 0x19, 0x0e, 0x10},
0823                         /* COM11 COM12 COM13 COM14 */
0824     {0xd1, 0x21, 0x3f, 0x41, 0xc1, 0x22, 0x08, 0x10},
0825                         /* EDGE COM15 COM16 COM17 */
0826     {0xd1, 0x21, 0x43, 0xf0, 0x10, 0x78, 0xa8, 0x10}, /* reserved */
0827     {0xd1, 0x21, 0x47, 0x60, 0x80, 0x00, 0x00, 0x10}, /* reserved */
0828     {0xd1, 0x21, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* reserved */
0829     {0xd1, 0x21, 0x4f, 0x46, 0x36, 0x0f, 0x17, 0x10}, /* MTX 1 2 3 4 */
0830     {0xd1, 0x21, 0x53, 0x7f, 0x96, 0x40, 0x40, 0x10}, /* MTX 5 6 7 8 */
0831     {0xb1, 0x21, 0x57, 0x40, 0x0f, 0x00, 0x00, 0x10}, /* MTX9 MTXS */
0832     {0xd1, 0x21, 0x59, 0xba, 0x9a, 0x22, 0xb9, 0x10}, /* reserved */
0833     {0xd1, 0x21, 0x5d, 0x9b, 0x10, 0xf0, 0x05, 0x10}, /* reserved */
0834     {0xa1, 0x21, 0x61, 0x60, 0x00, 0x00, 0x00, 0x10}, /* reserved */
0835     {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10},
0836                         /* LCC1 LCC2 LCC3 LCC4 */
0837     {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */
0838     {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, /* MANU */
0839     {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10},
0840                     /* band gap reference [0:3] DBLV */
0841     {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */
0842     {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */
0843     {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */
0844     {0xd1, 0x21, 0x78, 0x34, 0x30, 0x2f, 0x2b, 0x10}, /* gamma curve */
0845     {0xd1, 0x21, 0x7c, 0x03, 0x07, 0x17, 0x34, 0x10}, /* gamma curve */
0846     {0xd1, 0x21, 0x80, 0x41, 0x4d, 0x58, 0x63, 0x10}, /* gamma curve */
0847     {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */
0848     {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
0849     {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
0850     {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
0851 /* not in all ms-win traces*/
0852     {0xa1, 0x21, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x10},
0853     {}
0854 };
0855 static const u8 ov7660_sensor_param1[][8] = {
0856     {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
0857                         /* bits[3..0]reserved */
0858     {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
0859     {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
0860                         /* VREF vertical frame ctrl */
0861     {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
0862     {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* AECH 0x20 */
0863     {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFL */
0864     {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFH */
0865     {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */
0866 /*  {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */
0867 /****** (some exchanges in the win trace) ******/
0868 /*fixme:param2*/
0869     {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */
0870     {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */
0871     {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */
0872     {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCL */
0873 /*  {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10},  * RED */
0874 /****** (some exchanges in the win trace) ******/
0875 /******!! startsensor KO if changed !!****/
0876 /*fixme: param3*/
0877     {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10},
0878     {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10},
0879     {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
0880     {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10},
0881     {}
0882 };
0883 
0884 static const u8 po1030_sensor_init[][8] = {
0885 /* the sensor registers are described in m5602/m5602_po1030.h */
0886     {0xa1, 0x6e, 0x3f, 0x20, 0x00, 0x00, 0x00, 0x10}, /* sensor reset */
0887     {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
0888     {0xa1, 0x6e, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x10},
0889     {0xa1, 0x6e, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x10},
0890     {0xd1, 0x6e, 0x04, 0x02, 0xb1, 0x02, 0x39, 0x10},
0891     {0xd1, 0x6e, 0x08, 0x00, 0x01, 0x00, 0x00, 0x10},
0892     {0xd1, 0x6e, 0x0c, 0x02, 0x7f, 0x01, 0xe0, 0x10},
0893     {0xd1, 0x6e, 0x12, 0x03, 0x02, 0x00, 0x03, 0x10},
0894     {0xd1, 0x6e, 0x16, 0x85, 0x40, 0x4a, 0x40, 0x10}, /* r/g1/b/g2 gains */
0895     {0xc1, 0x6e, 0x1a, 0x00, 0x80, 0x00, 0x00, 0x10},
0896     {0xd1, 0x6e, 0x1d, 0x08, 0x03, 0x00, 0x00, 0x10},
0897     {0xd1, 0x6e, 0x23, 0x00, 0xb0, 0x00, 0x94, 0x10},
0898     {0xd1, 0x6e, 0x27, 0x58, 0x00, 0x00, 0x00, 0x10},
0899     {0xb1, 0x6e, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10},
0900     {0xd1, 0x6e, 0x2d, 0x14, 0x35, 0x61, 0x84, 0x10}, /* gamma corr */
0901     {0xd1, 0x6e, 0x31, 0xa2, 0xbd, 0xd8, 0xff, 0x10},
0902     {0xd1, 0x6e, 0x35, 0x06, 0x1e, 0x12, 0x02, 0x10}, /* color matrix */
0903     {0xd1, 0x6e, 0x39, 0xaa, 0x53, 0x37, 0xd5, 0x10},
0904     {0xa1, 0x6e, 0x3d, 0xf2, 0x00, 0x00, 0x00, 0x10},
0905     {0xd1, 0x6e, 0x3e, 0x00, 0x00, 0x80, 0x03, 0x10},
0906     {0xd1, 0x6e, 0x42, 0x03, 0x00, 0x00, 0x00, 0x10},
0907     {0xc1, 0x6e, 0x46, 0x00, 0x80, 0x80, 0x00, 0x10},
0908     {0xd1, 0x6e, 0x4b, 0x02, 0xef, 0x08, 0xcd, 0x10},
0909     {0xd1, 0x6e, 0x4f, 0x00, 0xd0, 0x00, 0xa0, 0x10},
0910     {0xd1, 0x6e, 0x53, 0x01, 0xaa, 0x01, 0x40, 0x10},
0911     {0xd1, 0x6e, 0x5a, 0x50, 0x04, 0x30, 0x03, 0x10}, /* raw rgb bayer */
0912     {0xa1, 0x6e, 0x5e, 0x00, 0x00, 0x00, 0x00, 0x10},
0913     {0xd1, 0x6e, 0x5f, 0x10, 0x40, 0xff, 0x00, 0x10},
0914 
0915     {0xd1, 0x6e, 0x63, 0x40, 0x40, 0x00, 0x00, 0x10},
0916     {0xd1, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x00, 0x10},
0917     {0xd1, 0x6e, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x10},
0918     {0xd1, 0x6e, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x10},
0919     {0xc1, 0x6e, 0x73, 0x10, 0x80, 0xeb, 0x00, 0x10},
0920     {}
0921 };
0922 static const u8 po1030_sensor_param1[][8] = {
0923 /* from ms-win traces - these values change with auto gain/expo/wb.. */
0924     {0xa1, 0x6e, 0x1e, 0x03, 0x00, 0x00, 0x00, 0x10},
0925     {0xa1, 0x6e, 0x1e, 0x03, 0x00, 0x00, 0x00, 0x10},
0926 /* mean values */
0927     {0xc1, 0x6e, 0x1a, 0x02, 0xd4, 0xa4, 0x00, 0x10}, /* integlines */
0928     {0xa1, 0x6e, 0x15, 0x04, 0x00, 0x00, 0x00, 0x10}, /* global gain */
0929     {0xc1, 0x6e, 0x16, 0x40, 0x40, 0x40, 0x00, 0x10}, /* r/g1/b gains */
0930 
0931     {0xa1, 0x6e, 0x1d, 0x08, 0x00, 0x00, 0x00, 0x10}, /* control1 */
0932     {0xa1, 0x6e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10}, /* frameheight */
0933     {0xa1, 0x6e, 0x07, 0xd5, 0x00, 0x00, 0x00, 0x10},
0934 /*  {0xc1, 0x6e, 0x16, 0x49, 0x40, 0x45, 0x00, 0x10}, */
0935     {}
0936 };
0937 
0938 static const u8 po2030n_sensor_init[][8] = {
0939     {0xa1, 0x6e, 0x1e, 0x1a, 0x00, 0x00, 0x00, 0x10},
0940     {0xa1, 0x6e, 0x1f, 0x99, 0x00, 0x00, 0x00, 0x10},
0941     {DELAY, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 10ms */
0942     {0xa1, 0x6e, 0x1e, 0x0a, 0x00, 0x00, 0x00, 0x10},
0943     {0xa1, 0x6e, 0x1f, 0x19, 0x00, 0x00, 0x00, 0x10},
0944     {DELAY, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 10ms */
0945     {0xa1, 0x6e, 0x20, 0x44, 0x00, 0x00, 0x00, 0x10},
0946     {0xa1, 0x6e, 0x04, 0x03, 0x00, 0x00, 0x00, 0x10},
0947     {0xa1, 0x6e, 0x05, 0x70, 0x00, 0x00, 0x00, 0x10},
0948     {0xa1, 0x6e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10},
0949     {0xa1, 0x6e, 0x07, 0x25, 0x00, 0x00, 0x00, 0x10},
0950     {0xd1, 0x6e, 0x08, 0x00, 0xd0, 0x00, 0x08, 0x10},
0951     {0xd1, 0x6e, 0x0c, 0x03, 0x50, 0x01, 0xe8, 0x10},
0952     {0xd1, 0x6e, 0x1d, 0x20, 0x0a, 0x19, 0x44, 0x10},
0953     {0xd1, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x00, 0x10},
0954     {0xd1, 0x6e, 0x25, 0x00, 0x00, 0x00, 0x00, 0x10},
0955     {0xd1, 0x6e, 0x29, 0x00, 0x00, 0x00, 0x00, 0x10},
0956     {0xd1, 0x6e, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10},
0957     {0xd1, 0x6e, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
0958     {0xd1, 0x6e, 0x35, 0x00, 0x00, 0x00, 0x00, 0x10},
0959     {0xd1, 0x6e, 0x39, 0x00, 0x00, 0x00, 0x00, 0x10},
0960     {0xd1, 0x6e, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x10},
0961     {0xd1, 0x6e, 0x41, 0x00, 0x00, 0x00, 0x00, 0x10},
0962     {0xd1, 0x6e, 0x45, 0x00, 0x00, 0x00, 0x00, 0x10},
0963     {0xd1, 0x6e, 0x49, 0x00, 0x00, 0x00, 0x00, 0x10},
0964     {0xd1, 0x6e, 0x4d, 0x00, 0x00, 0x00, 0xed, 0x10},
0965     {0xd1, 0x6e, 0x51, 0x17, 0x4a, 0x2f, 0xc0, 0x10},
0966     {0xd1, 0x6e, 0x55, 0x00, 0x00, 0x00, 0x00, 0x10},
0967     {0xd1, 0x6e, 0x59, 0x00, 0x00, 0x00, 0x00, 0x10},
0968     {0xd1, 0x6e, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x10},
0969     {0xd1, 0x6e, 0x61, 0x00, 0x00, 0x00, 0x00, 0x10},
0970     {0xd1, 0x6e, 0x65, 0x00, 0x00, 0x00, 0x00, 0x10},
0971     {0xd1, 0x6e, 0x69, 0x00, 0x00, 0x00, 0x00, 0x10},
0972     {0xd1, 0x6e, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x10},
0973     {0xd1, 0x6e, 0x71, 0x00, 0x00, 0x00, 0x00, 0x10},
0974     {0xd1, 0x6e, 0x75, 0x00, 0x00, 0x00, 0x00, 0x10},
0975     {0xd1, 0x6e, 0x79, 0x00, 0x00, 0x00, 0x00, 0x10},
0976     {0xd1, 0x6e, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x10},
0977     {0xd1, 0x6e, 0x81, 0x00, 0x00, 0x00, 0x00, 0x10},
0978     {0xd1, 0x6e, 0x85, 0x00, 0x00, 0x00, 0x08, 0x10},
0979     {0xd1, 0x6e, 0x89, 0x01, 0xe8, 0x00, 0x01, 0x10},
0980     {0xa1, 0x6e, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x10},
0981     {0xd1, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x00, 0x10},
0982     {0xd1, 0x6e, 0x25, 0x00, 0x00, 0x00, 0x01, 0x10},
0983     {0xd1, 0x6e, 0x29, 0xe6, 0x00, 0xbd, 0x03, 0x10},
0984     {0xd1, 0x6e, 0x2d, 0x41, 0x38, 0x68, 0x40, 0x10},
0985     {0xd1, 0x6e, 0x31, 0x2b, 0x00, 0x36, 0x00, 0x10},
0986     {0xd1, 0x6e, 0x35, 0x30, 0x30, 0x08, 0x00, 0x10},
0987     {0xd1, 0x6e, 0x39, 0x00, 0x00, 0x33, 0x06, 0x10},
0988     {0xb1, 0x6e, 0x3d, 0x06, 0x02, 0x00, 0x00, 0x10},
0989     {}
0990 };
0991 static const u8 po2030n_sensor_param1[][8] = {
0992     {0xa1, 0x6e, 0x1a, 0x01, 0x00, 0x00, 0x00, 0x10},
0993     {DELAY, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 8ms */
0994     {0xa1, 0x6e, 0x1b, 0xf4, 0x00, 0x00, 0x00, 0x10},
0995     {0xa1, 0x6e, 0x15, 0x04, 0x00, 0x00, 0x00, 0x10},
0996     {0xd1, 0x6e, 0x16, 0x40, 0x40, 0x40, 0x40, 0x10}, /* RGBG gains */
0997 /*param2*/
0998     {0xa1, 0x6e, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x10},
0999     {0xa1, 0x6e, 0x04, 0x03, 0x00, 0x00, 0x00, 0x10},
1000     {0xa1, 0x6e, 0x05, 0x6f, 0x00, 0x00, 0x00, 0x10},
1001     {0xa1, 0x6e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10},
1002     {0xa1, 0x6e, 0x07, 0x25, 0x00, 0x00, 0x00, 0x10},
1003     {}
1004 };
1005 
1006 static const u8 soi768_sensor_init[][8] = {
1007     {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */
1008     {DELAY, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 96ms */
1009     {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
1010     {0xa1, 0x21, 0x13, 0x80, 0x00, 0x00, 0x00, 0x10},
1011     {0xa1, 0x21, 0x0f, 0x03, 0x00, 0x00, 0x00, 0x10},
1012     {0xa1, 0x21, 0x19, 0x00, 0x00, 0x00, 0x00, 0x10},
1013     {}
1014 };
1015 static const u8 soi768_sensor_param1[][8] = {
1016     {0xa1, 0x21, 0x10, 0x10, 0x00, 0x00, 0x00, 0x10},
1017     {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10},
1018     {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
1019     {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1020     {0xb1, 0x21, 0x01, 0x7f, 0x7f, 0x00, 0x00, 0x10},
1021 /* */
1022 /*  {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, */
1023 /*  {0xa1, 0x21, 0x2d, 0x25, 0x00, 0x00, 0x00, 0x10}, */
1024     {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10},
1025 /*  {0xb1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, */
1026     {0xa1, 0x21, 0x02, 0x8d, 0x00, 0x00, 0x00, 0x10},
1027 /* the next sequence should be used for auto gain */
1028     {0xa1, 0x21, 0x00, 0x07, 0x00, 0x00, 0x00, 0x10},
1029             /* global gain ? : 07 - change with 0x15 at the end */
1030     {0xa1, 0x21, 0x10, 0x3f, 0x00, 0x00, 0x00, 0x10}, /* ???? : 063f */
1031     {0xa1, 0x21, 0x04, 0x06, 0x00, 0x00, 0x00, 0x10},
1032     {0xb1, 0x21, 0x2d, 0x63, 0x03, 0x00, 0x00, 0x10},
1033             /* exposure ? : 0200 - change with 0x1e at the end */
1034     {}
1035 };
1036 
1037 static const u8 sp80708_sensor_init[][8] = {
1038     {0xa1, 0x18, 0x06, 0xf9, 0x00, 0x00, 0x00, 0x10},
1039     {0xa1, 0x18, 0x09, 0x1f, 0x00, 0x00, 0x00, 0x10},
1040     {0xa1, 0x18, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
1041     {0xa1, 0x18, 0x0d, 0xc0, 0x00, 0x00, 0x00, 0x10},
1042     {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
1043     {0xa1, 0x18, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x10},
1044     {0xa1, 0x18, 0x10, 0x40, 0x00, 0x00, 0x00, 0x10},
1045     {0xa1, 0x18, 0x11, 0x4e, 0x00, 0x00, 0x00, 0x10},
1046     {0xa1, 0x18, 0x12, 0x53, 0x00, 0x00, 0x00, 0x10},
1047     {0xa1, 0x18, 0x15, 0x80, 0x00, 0x00, 0x00, 0x10},
1048     {0xa1, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x10},
1049     {0xa1, 0x18, 0x19, 0x18, 0x00, 0x00, 0x00, 0x10},
1050     {0xa1, 0x18, 0x1a, 0x10, 0x00, 0x00, 0x00, 0x10},
1051     {0xa1, 0x18, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x10},
1052     {0xa1, 0x18, 0x1c, 0x28, 0x00, 0x00, 0x00, 0x10},
1053     {0xa1, 0x18, 0x1d, 0x02, 0x00, 0x00, 0x00, 0x10},
1054     {0xa1, 0x18, 0x1e, 0x10, 0x00, 0x00, 0x00, 0x10},
1055     {0xa1, 0x18, 0x26, 0x04, 0x00, 0x00, 0x00, 0x10},
1056     {0xa1, 0x18, 0x27, 0x1e, 0x00, 0x00, 0x00, 0x10},
1057     {0xa1, 0x18, 0x28, 0x5a, 0x00, 0x00, 0x00, 0x10},
1058     {0xa1, 0x18, 0x29, 0x28, 0x00, 0x00, 0x00, 0x10},
1059     {0xa1, 0x18, 0x2a, 0x78, 0x00, 0x00, 0x00, 0x10},
1060     {0xa1, 0x18, 0x2b, 0x01, 0x00, 0x00, 0x00, 0x10},
1061     {0xa1, 0x18, 0x2c, 0xf7, 0x00, 0x00, 0x00, 0x10},
1062     {0xa1, 0x18, 0x2d, 0x2d, 0x00, 0x00, 0x00, 0x10},
1063     {0xa1, 0x18, 0x2e, 0xd5, 0x00, 0x00, 0x00, 0x10},
1064     {0xa1, 0x18, 0x39, 0x42, 0x00, 0x00, 0x00, 0x10},
1065     {0xa1, 0x18, 0x3a, 0x67, 0x00, 0x00, 0x00, 0x10},
1066     {0xa1, 0x18, 0x3b, 0x87, 0x00, 0x00, 0x00, 0x10},
1067     {0xa1, 0x18, 0x3c, 0xa3, 0x00, 0x00, 0x00, 0x10},
1068     {0xa1, 0x18, 0x3d, 0xb0, 0x00, 0x00, 0x00, 0x10},
1069     {0xa1, 0x18, 0x3e, 0xbc, 0x00, 0x00, 0x00, 0x10},
1070     {0xa1, 0x18, 0x3f, 0xc8, 0x00, 0x00, 0x00, 0x10},
1071     {0xa1, 0x18, 0x40, 0xd4, 0x00, 0x00, 0x00, 0x10},
1072     {0xa1, 0x18, 0x41, 0xdf, 0x00, 0x00, 0x00, 0x10},
1073     {0xa1, 0x18, 0x42, 0xea, 0x00, 0x00, 0x00, 0x10},
1074     {0xa1, 0x18, 0x43, 0xf5, 0x00, 0x00, 0x00, 0x10},
1075     {0xa1, 0x18, 0x45, 0x80, 0x00, 0x00, 0x00, 0x10},
1076     {0xa1, 0x18, 0x46, 0x60, 0x00, 0x00, 0x00, 0x10},
1077     {0xa1, 0x18, 0x47, 0x50, 0x00, 0x00, 0x00, 0x10},
1078     {0xa1, 0x18, 0x48, 0x30, 0x00, 0x00, 0x00, 0x10},
1079     {0xa1, 0x18, 0x49, 0x01, 0x00, 0x00, 0x00, 0x10},
1080     {0xa1, 0x18, 0x4d, 0xae, 0x00, 0x00, 0x00, 0x10},
1081     {0xa1, 0x18, 0x4e, 0x03, 0x00, 0x00, 0x00, 0x10},
1082     {0xa1, 0x18, 0x4f, 0x66, 0x00, 0x00, 0x00, 0x10},
1083     {0xa1, 0x18, 0x50, 0x1c, 0x00, 0x00, 0x00, 0x10},
1084     {0xa1, 0x18, 0x44, 0x10, 0x00, 0x00, 0x00, 0x10},
1085     {0xa1, 0x18, 0x4a, 0x30, 0x00, 0x00, 0x00, 0x10},
1086     {0xa1, 0x18, 0x51, 0x80, 0x00, 0x00, 0x00, 0x10},
1087     {0xa1, 0x18, 0x52, 0x80, 0x00, 0x00, 0x00, 0x10},
1088     {0xa1, 0x18, 0x53, 0x80, 0x00, 0x00, 0x00, 0x10},
1089     {0xa1, 0x18, 0x54, 0x80, 0x00, 0x00, 0x00, 0x10},
1090     {0xa1, 0x18, 0x55, 0x80, 0x00, 0x00, 0x00, 0x10},
1091     {0xa1, 0x18, 0x56, 0x80, 0x00, 0x00, 0x00, 0x10},
1092     {0xa1, 0x18, 0x57, 0xe0, 0x00, 0x00, 0x00, 0x10},
1093     {0xa1, 0x18, 0x58, 0xc0, 0x00, 0x00, 0x00, 0x10},
1094     {0xa1, 0x18, 0x59, 0xab, 0x00, 0x00, 0x00, 0x10},
1095     {0xa1, 0x18, 0x5a, 0xa0, 0x00, 0x00, 0x00, 0x10},
1096     {0xa1, 0x18, 0x5b, 0x99, 0x00, 0x00, 0x00, 0x10},
1097     {0xa1, 0x18, 0x5c, 0x90, 0x00, 0x00, 0x00, 0x10},
1098     {0xa1, 0x18, 0x5e, 0x24, 0x00, 0x00, 0x00, 0x10},
1099     {0xa1, 0x18, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x10},
1100     {0xa1, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x10},
1101     {0xa1, 0x18, 0x61, 0x73, 0x00, 0x00, 0x00, 0x10},
1102     {0xa1, 0x18, 0x63, 0x42, 0x00, 0x00, 0x00, 0x10},
1103     {0xa1, 0x18, 0x64, 0x42, 0x00, 0x00, 0x00, 0x10},
1104     {0xa1, 0x18, 0x65, 0x42, 0x00, 0x00, 0x00, 0x10},
1105     {0xa1, 0x18, 0x66, 0x24, 0x00, 0x00, 0x00, 0x10},
1106     {0xa1, 0x18, 0x67, 0x24, 0x00, 0x00, 0x00, 0x10},
1107     {0xa1, 0x18, 0x68, 0x08, 0x00, 0x00, 0x00, 0x10},
1108     {0xa1, 0x18, 0x2f, 0xc9, 0x00, 0x00, 0x00, 0x10},
1109     {}
1110 };
1111 static const u8 sp80708_sensor_param1[][8] = {
1112     {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
1113     {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
1114     {0xa1, 0x18, 0x03, 0x01, 0x00, 0x00, 0x00, 0x10},
1115     {0xa1, 0x18, 0x04, 0xa4, 0x00, 0x00, 0x00, 0x10},
1116     {0xa1, 0x18, 0x14, 0x3f, 0x00, 0x00, 0x00, 0x10},
1117     {0xa1, 0x18, 0x5d, 0x80, 0x00, 0x00, 0x00, 0x10},
1118     {0xb1, 0x18, 0x11, 0x40, 0x40, 0x00, 0x00, 0x10},
1119     {}
1120 };
1121 
1122 static const u8 (*sensor_init[])[8] = {
1123 [SENSOR_ADCM1700] = adcm1700_sensor_init,
1124 [SENSOR_GC0307] =   gc0307_sensor_init,
1125 [SENSOR_HV7131R] =  hv7131r_sensor_init,
1126 [SENSOR_MI0360] =   mi0360_sensor_init,
1127 [SENSOR_MI0360B] =  mi0360b_sensor_init,
1128 [SENSOR_MO4000] =   mo4000_sensor_init,
1129 [SENSOR_MT9V111] =  mt9v111_sensor_init,
1130 [SENSOR_OM6802] =   om6802_sensor_init,
1131 [SENSOR_OV7630] =   ov7630_sensor_init,
1132 [SENSOR_OV7648] =   ov7648_sensor_init,
1133 [SENSOR_OV7660] =   ov7660_sensor_init,
1134 [SENSOR_PO1030] =   po1030_sensor_init,
1135 [SENSOR_PO2030N] =  po2030n_sensor_init,
1136 [SENSOR_SOI768] =   soi768_sensor_init,
1137 [SENSOR_SP80708] =  sp80708_sensor_init,
1138 };
1139 
1140 /* read <len> bytes to gspca_dev->usb_buf */
1141 static void reg_r(struct gspca_dev *gspca_dev,
1142           u16 value, int len)
1143 {
1144     int ret;
1145 
1146     if (gspca_dev->usb_err < 0)
1147         return;
1148     if (len > USB_BUF_SZ) {
1149         gspca_err(gspca_dev, "reg_r: buffer overflow\n");
1150         return;
1151     }
1152 
1153     ret = usb_control_msg(gspca_dev->dev,
1154             usb_rcvctrlpipe(gspca_dev->dev, 0),
1155             0,
1156             USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1157             value, 0,
1158             gspca_dev->usb_buf, len,
1159             500);
1160     gspca_dbg(gspca_dev, D_USBI, "reg_r [%02x] -> %02x\n",
1161           value, gspca_dev->usb_buf[0]);
1162     if (ret < 0) {
1163         pr_err("reg_r err %d\n", ret);
1164         gspca_dev->usb_err = ret;
1165         /*
1166          * Make sure the buffer is zeroed to avoid uninitialized
1167          * values.
1168          */
1169         memset(gspca_dev->usb_buf, 0, USB_BUF_SZ);
1170     }
1171 }
1172 
1173 static void reg_w1(struct gspca_dev *gspca_dev,
1174            u16 value,
1175            u8 data)
1176 {
1177     int ret;
1178 
1179     if (gspca_dev->usb_err < 0)
1180         return;
1181     gspca_dbg(gspca_dev, D_USBO, "reg_w1 [%04x] = %02x\n", value, data);
1182     gspca_dev->usb_buf[0] = data;
1183     ret = usb_control_msg(gspca_dev->dev,
1184             usb_sndctrlpipe(gspca_dev->dev, 0),
1185             0x08,
1186             USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1187             value,
1188             0,
1189             gspca_dev->usb_buf, 1,
1190             500);
1191     if (ret < 0) {
1192         pr_err("reg_w1 err %d\n", ret);
1193         gspca_dev->usb_err = ret;
1194     }
1195 }
1196 static void reg_w(struct gspca_dev *gspca_dev,
1197               u16 value,
1198               const u8 *buffer,
1199               int len)
1200 {
1201     int ret;
1202 
1203     if (gspca_dev->usb_err < 0)
1204         return;
1205     gspca_dbg(gspca_dev, D_USBO, "reg_w [%04x] = %02x %02x ..\n",
1206           value, buffer[0], buffer[1]);
1207 
1208     if (len > USB_BUF_SZ) {
1209         gspca_err(gspca_dev, "reg_w: buffer overflow\n");
1210         return;
1211     }
1212 
1213     memcpy(gspca_dev->usb_buf, buffer, len);
1214     ret = usb_control_msg(gspca_dev->dev,
1215             usb_sndctrlpipe(gspca_dev->dev, 0),
1216             0x08,
1217             USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1218             value, 0,
1219             gspca_dev->usb_buf, len,
1220             500);
1221     if (ret < 0) {
1222         pr_err("reg_w err %d\n", ret);
1223         gspca_dev->usb_err = ret;
1224     }
1225 }
1226 
1227 /* I2C write 1 byte */
1228 static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
1229 {
1230     struct sd *sd = (struct sd *) gspca_dev;
1231     int ret;
1232 
1233     if (gspca_dev->usb_err < 0)
1234         return;
1235     gspca_dbg(gspca_dev, D_USBO, "i2c_w1 [%02x] = %02x\n", reg, val);
1236     switch (sd->sensor) {
1237     case SENSOR_ADCM1700:
1238     case SENSOR_OM6802:
1239     case SENSOR_GC0307:     /* i2c command = a0 (100 kHz) */
1240         gspca_dev->usb_buf[0] = 0x80 | (2 << 4);
1241         break;
1242     default:            /* i2c command = a1 (400 kHz) */
1243         gspca_dev->usb_buf[0] = 0x81 | (2 << 4);
1244         break;
1245     }
1246     gspca_dev->usb_buf[1] = sd->i2c_addr;
1247     gspca_dev->usb_buf[2] = reg;
1248     gspca_dev->usb_buf[3] = val;
1249     gspca_dev->usb_buf[4] = 0;
1250     gspca_dev->usb_buf[5] = 0;
1251     gspca_dev->usb_buf[6] = 0;
1252     gspca_dev->usb_buf[7] = 0x10;
1253     ret = usb_control_msg(gspca_dev->dev,
1254             usb_sndctrlpipe(gspca_dev->dev, 0),
1255             0x08,
1256             USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1257             0x08,           /* value = i2c */
1258             0,
1259             gspca_dev->usb_buf, 8,
1260             500);
1261     msleep(2);
1262     if (ret < 0) {
1263         pr_err("i2c_w1 err %d\n", ret);
1264         gspca_dev->usb_err = ret;
1265     }
1266 }
1267 
1268 /* I2C write 8 bytes */
1269 static void i2c_w8(struct gspca_dev *gspca_dev,
1270            const u8 *buffer)
1271 {
1272     int ret;
1273 
1274     if (gspca_dev->usb_err < 0)
1275         return;
1276     gspca_dbg(gspca_dev, D_USBO, "i2c_w8 [%02x] = %02x ..\n",
1277           buffer[2], buffer[3]);
1278     memcpy(gspca_dev->usb_buf, buffer, 8);
1279     ret = usb_control_msg(gspca_dev->dev,
1280             usb_sndctrlpipe(gspca_dev->dev, 0),
1281             0x08,
1282             USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1283             0x08, 0,        /* value, index */
1284             gspca_dev->usb_buf, 8,
1285             500);
1286     msleep(2);
1287     if (ret < 0) {
1288         pr_err("i2c_w8 err %d\n", ret);
1289         gspca_dev->usb_err = ret;
1290     }
1291 }
1292 
1293 /* sensor read 'len' (1..5) bytes in gspca_dev->usb_buf */
1294 static void i2c_r(struct gspca_dev *gspca_dev, u8 reg, int len)
1295 {
1296     struct sd *sd = (struct sd *) gspca_dev;
1297     u8 mode[8];
1298 
1299     switch (sd->sensor) {
1300     case SENSOR_ADCM1700:
1301     case SENSOR_OM6802:
1302     case SENSOR_GC0307:     /* i2c command = a0 (100 kHz) */
1303         mode[0] = 0x80 | 0x10;
1304         break;
1305     default:            /* i2c command = 91 (400 kHz) */
1306         mode[0] = 0x81 | 0x10;
1307         break;
1308     }
1309     mode[1] = sd->i2c_addr;
1310     mode[2] = reg;
1311     mode[3] = 0;
1312     mode[4] = 0;
1313     mode[5] = 0;
1314     mode[6] = 0;
1315     mode[7] = 0x10;
1316     i2c_w8(gspca_dev, mode);
1317     msleep(2);
1318     mode[0] = (mode[0] & 0x81) | (len << 4) | 0x02;
1319     mode[2] = 0;
1320     i2c_w8(gspca_dev, mode);
1321     msleep(2);
1322     reg_r(gspca_dev, 0x0a, 5);
1323 }
1324 
1325 static void i2c_w_seq(struct gspca_dev *gspca_dev,
1326             const u8 (*data)[8])
1327 {
1328     while ((*data)[0] != 0) {
1329         if ((*data)[0] != DELAY)
1330             i2c_w8(gspca_dev, *data);
1331         else
1332             msleep((*data)[1]);
1333         data++;
1334     }
1335 }
1336 
1337 /* check the ID of the hv7131 sensor */
1338 /* this sequence is needed because it activates the sensor */
1339 static void hv7131r_probe(struct gspca_dev *gspca_dev)
1340 {
1341     i2c_w1(gspca_dev, 0x02, 0);     /* sensor wakeup */
1342     msleep(10);
1343     reg_w1(gspca_dev, 0x02, 0x66);      /* Gpio on */
1344     msleep(10);
1345     i2c_r(gspca_dev, 0, 5);         /* read sensor id */
1346     if (gspca_dev->usb_buf[0] == 0x02   /* chip ID (02 is R) */
1347         && gspca_dev->usb_buf[1] == 0x09
1348         && gspca_dev->usb_buf[2] == 0x01) {
1349         gspca_dbg(gspca_dev, D_PROBE, "Sensor HV7131R found\n");
1350         return;
1351     }
1352     pr_warn("Erroneous HV7131R ID 0x%02x 0x%02x 0x%02x\n",
1353         gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
1354         gspca_dev->usb_buf[2]);
1355 }
1356 
1357 static void mi0360_probe(struct gspca_dev *gspca_dev)
1358 {
1359     struct sd *sd = (struct sd *) gspca_dev;
1360     int i, j;
1361     u16 val = 0;
1362     static const u8 probe_tb[][4][8] = {
1363         {                   /* mi0360 */
1364         {0xb0, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
1365         {0x90, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1366         {0xa2, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1367         {0xb0, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10}
1368         },
1369         {                   /* mt9v111 */
1370         {0xb0, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10},
1371         {0x90, 0x5c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x10},
1372         {0xa2, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1373         {}
1374         },
1375     };
1376 
1377     for (i = 0; i < ARRAY_SIZE(probe_tb); i++) {
1378         reg_w1(gspca_dev, 0x17, 0x62);
1379         reg_w1(gspca_dev, 0x01, 0x08);
1380         for (j = 0; j < 3; j++)
1381             i2c_w8(gspca_dev, probe_tb[i][j]);
1382         msleep(2);
1383         reg_r(gspca_dev, 0x0a, 5);
1384         val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1385         if (probe_tb[i][3][0] != 0)
1386             i2c_w8(gspca_dev, probe_tb[i][3]);
1387         reg_w1(gspca_dev, 0x01, 0x29);
1388         reg_w1(gspca_dev, 0x17, 0x42);
1389         if (val != 0xffff)
1390             break;
1391     }
1392     if (gspca_dev->usb_err < 0)
1393         return;
1394     switch (val) {
1395     case 0x8221:
1396         gspca_dbg(gspca_dev, D_PROBE, "Sensor mi0360b\n");
1397         sd->sensor = SENSOR_MI0360B;
1398         break;
1399     case 0x823a:
1400         gspca_dbg(gspca_dev, D_PROBE, "Sensor mt9v111\n");
1401         sd->sensor = SENSOR_MT9V111;
1402         break;
1403     case 0x8243:
1404         gspca_dbg(gspca_dev, D_PROBE, "Sensor mi0360\n");
1405         break;
1406     default:
1407         gspca_dbg(gspca_dev, D_PROBE, "Unknown sensor %04x - forced to mi0360\n",
1408               val);
1409         break;
1410     }
1411 }
1412 
1413 static void ov7630_probe(struct gspca_dev *gspca_dev)
1414 {
1415     struct sd *sd = (struct sd *) gspca_dev;
1416     u16 val;
1417 
1418     /* check ov76xx */
1419     reg_w1(gspca_dev, 0x17, 0x62);
1420     reg_w1(gspca_dev, 0x01, 0x08);
1421     sd->i2c_addr = 0x21;
1422     i2c_r(gspca_dev, 0x0a, 2);
1423     val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1424     reg_w1(gspca_dev, 0x01, 0x29);
1425     reg_w1(gspca_dev, 0x17, 0x42);
1426     if (gspca_dev->usb_err < 0)
1427         return;
1428     if (val == 0x7628) {            /* soi768 */
1429         sd->sensor = SENSOR_SOI768;
1430 /*fixme: only valid for 0c45:613e?*/
1431         gspca_dev->cam.input_flags =
1432                 V4L2_IN_ST_VFLIP | V4L2_IN_ST_HFLIP;
1433         gspca_dbg(gspca_dev, D_PROBE, "Sensor soi768\n");
1434         return;
1435     }
1436     gspca_dbg(gspca_dev, D_PROBE, "Sensor ov%04x\n", val);
1437 }
1438 
1439 static void ov7648_probe(struct gspca_dev *gspca_dev)
1440 {
1441     struct sd *sd = (struct sd *) gspca_dev;
1442     u16 val;
1443 
1444     /* check ov76xx */
1445     reg_w1(gspca_dev, 0x17, 0x62);
1446     reg_w1(gspca_dev, 0x01, 0x08);
1447     sd->i2c_addr = 0x21;
1448     i2c_r(gspca_dev, 0x0a, 2);
1449     val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1450     reg_w1(gspca_dev, 0x01, 0x29);
1451     reg_w1(gspca_dev, 0x17, 0x42);
1452     if ((val & 0xff00) == 0x7600) {     /* ov76xx */
1453         gspca_dbg(gspca_dev, D_PROBE, "Sensor ov%04x\n", val);
1454         return;
1455     }
1456 
1457     /* check po1030 */
1458     reg_w1(gspca_dev, 0x17, 0x62);
1459     reg_w1(gspca_dev, 0x01, 0x08);
1460     sd->i2c_addr = 0x6e;
1461     i2c_r(gspca_dev, 0x00, 2);
1462     val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1463     reg_w1(gspca_dev, 0x01, 0x29);
1464     reg_w1(gspca_dev, 0x17, 0x42);
1465     if (gspca_dev->usb_err < 0)
1466         return;
1467     if (val == 0x1030) {            /* po1030 */
1468         gspca_dbg(gspca_dev, D_PROBE, "Sensor po1030\n");
1469         sd->sensor = SENSOR_PO1030;
1470         return;
1471     }
1472     pr_err("Unknown sensor %04x\n", val);
1473 }
1474 
1475 /* 0c45:6142 sensor may be po2030n, gc0305 or gc0307 */
1476 static void po2030n_probe(struct gspca_dev *gspca_dev)
1477 {
1478     struct sd *sd = (struct sd *) gspca_dev;
1479     u16 val;
1480 
1481     /* check gc0307 */
1482     reg_w1(gspca_dev, 0x17, 0x62);
1483     reg_w1(gspca_dev, 0x01, 0x08);
1484     reg_w1(gspca_dev, 0x02, 0x22);
1485     sd->i2c_addr = 0x21;
1486     i2c_r(gspca_dev, 0x00, 1);
1487     val = gspca_dev->usb_buf[4];
1488     reg_w1(gspca_dev, 0x01, 0x29);      /* reset */
1489     reg_w1(gspca_dev, 0x17, 0x42);
1490     if (val == 0x99) {          /* gc0307 (?) */
1491         gspca_dbg(gspca_dev, D_PROBE, "Sensor gc0307\n");
1492         sd->sensor = SENSOR_GC0307;
1493         return;
1494     }
1495 
1496     /* check po2030n */
1497     reg_w1(gspca_dev, 0x17, 0x62);
1498     reg_w1(gspca_dev, 0x01, 0x0a);
1499     sd->i2c_addr = 0x6e;
1500     i2c_r(gspca_dev, 0x00, 2);
1501     val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1502     reg_w1(gspca_dev, 0x01, 0x29);
1503     reg_w1(gspca_dev, 0x17, 0x42);
1504     if (gspca_dev->usb_err < 0)
1505         return;
1506     if (val == 0x2030) {
1507         gspca_dbg(gspca_dev, D_PROBE, "Sensor po2030n\n");
1508 /*      sd->sensor = SENSOR_PO2030N; */
1509     } else {
1510         pr_err("Unknown sensor ID %04x\n", val);
1511     }
1512 }
1513 
1514 /* this function is called at probe time */
1515 static int sd_config(struct gspca_dev *gspca_dev,
1516             const struct usb_device_id *id)
1517 {
1518     struct sd *sd = (struct sd *) gspca_dev;
1519     struct cam *cam;
1520 
1521     sd->bridge = id->driver_info >> 16;
1522     sd->sensor = id->driver_info >> 8;
1523     sd->flags = id->driver_info;
1524 
1525     cam = &gspca_dev->cam;
1526     if (sd->sensor == SENSOR_ADCM1700) {
1527         cam->cam_mode = cif_mode;
1528         cam->nmodes = ARRAY_SIZE(cif_mode);
1529     } else {
1530         cam->cam_mode = vga_mode;
1531         cam->nmodes = ARRAY_SIZE(vga_mode);
1532     }
1533     cam->npkt = 24;         /* 24 packets per ISOC message */
1534 
1535     sd->ag_cnt = -1;
1536     sd->quality = QUALITY_DEF;
1537 
1538     INIT_WORK(&sd->work, qual_upd);
1539 
1540     return 0;
1541 }
1542 
1543 /* this function is called at probe and resume time */
1544 static int sd_init(struct gspca_dev *gspca_dev)
1545 {
1546     struct sd *sd = (struct sd *) gspca_dev;
1547     const u8 *sn9c1xx;
1548     u8 regGpio[] = { 0x29, 0x70 };      /* no audio */
1549     u8 regF1;
1550 
1551     /* setup a selector by bridge */
1552     reg_w1(gspca_dev, 0xf1, 0x01);
1553     reg_r(gspca_dev, 0x00, 1);
1554     reg_w1(gspca_dev, 0xf1, 0x00);
1555     reg_r(gspca_dev, 0x00, 1);      /* get sonix chip id */
1556     regF1 = gspca_dev->usb_buf[0];
1557     if (gspca_dev->usb_err < 0)
1558         return gspca_dev->usb_err;
1559     gspca_dbg(gspca_dev, D_PROBE, "Sonix chip id: %02x\n", regF1);
1560     if (gspca_dev->audio)
1561         regGpio[1] |= 0x04;     /* with audio */
1562     switch (sd->bridge) {
1563     case BRIDGE_SN9C102P:
1564     case BRIDGE_SN9C105:
1565         if (regF1 != 0x11)
1566             return -ENODEV;
1567         break;
1568     default:
1569 /*  case BRIDGE_SN9C110: */
1570 /*  case BRIDGE_SN9C120: */
1571         if (regF1 != 0x12)
1572             return -ENODEV;
1573     }
1574 
1575     switch (sd->sensor) {
1576     case SENSOR_MI0360:
1577         mi0360_probe(gspca_dev);
1578         break;
1579     case SENSOR_OV7630:
1580         ov7630_probe(gspca_dev);
1581         break;
1582     case SENSOR_OV7648:
1583         ov7648_probe(gspca_dev);
1584         break;
1585     case SENSOR_PO2030N:
1586         po2030n_probe(gspca_dev);
1587         break;
1588     }
1589 
1590     switch (sd->bridge) {
1591     case BRIDGE_SN9C102P:
1592         reg_w1(gspca_dev, 0x02, regGpio[1]);
1593         break;
1594     default:
1595         reg_w(gspca_dev, 0x01, regGpio, 2);
1596         break;
1597     }
1598 
1599     /* Note we do not disable the sensor clock here (power saving mode),
1600        as that also disables the button on the cam. */
1601     reg_w1(gspca_dev, 0xf1, 0x00);
1602 
1603     /* set the i2c address */
1604     sn9c1xx = sn_tb[sd->sensor];
1605     sd->i2c_addr = sn9c1xx[9];
1606 
1607     return gspca_dev->usb_err;
1608 }
1609 
1610 static int sd_s_ctrl(struct v4l2_ctrl *ctrl);
1611 
1612 static const struct v4l2_ctrl_ops sd_ctrl_ops = {
1613     .s_ctrl = sd_s_ctrl,
1614 };
1615 
1616 /* this function is called at probe time */
1617 static int sd_init_controls(struct gspca_dev *gspca_dev)
1618 {
1619     struct sd *sd = (struct sd *) gspca_dev;
1620     struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
1621 
1622     gspca_dev->vdev.ctrl_handler = hdl;
1623     v4l2_ctrl_handler_init(hdl, 14);
1624 
1625     sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1626             V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
1627 #define CONTRAST_MAX 127
1628     sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1629             V4L2_CID_CONTRAST, 0, CONTRAST_MAX, 1, 20);
1630 #define COLORS_DEF 25
1631     sd->saturation = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1632             V4L2_CID_SATURATION, 0, 40, 1, COLORS_DEF);
1633     sd->red_bal = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1634             V4L2_CID_RED_BALANCE, 24, 40, 1, 32);
1635     sd->blue_bal = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1636             V4L2_CID_BLUE_BALANCE, 24, 40, 1, 32);
1637 #define GAMMA_DEF 20
1638     sd->gamma = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1639             V4L2_CID_GAMMA, 0, 40, 1, GAMMA_DEF);
1640 
1641     if (sd->sensor == SENSOR_OM6802)
1642         sd->sharpness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1643             V4L2_CID_SHARPNESS, 0, 255, 1, 16);
1644     else
1645         sd->sharpness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1646             V4L2_CID_SHARPNESS, 0, 255, 1, 90);
1647 
1648     if (sd->flags & F_ILLUM)
1649         sd->illum = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1650             V4L2_CID_ILLUMINATORS_1, 0, 1, 1, 0);
1651 
1652     if (sd->sensor == SENSOR_PO2030N) {
1653         gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1654             V4L2_CID_EXPOSURE, 500, 1500, 1, 1024);
1655         gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1656             V4L2_CID_GAIN, 4, 49, 1, 15);
1657         sd->hflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1658             V4L2_CID_HFLIP, 0, 1, 1, 0);
1659     }
1660 
1661     if (sd->sensor != SENSOR_ADCM1700 && sd->sensor != SENSOR_OV7660 &&
1662         sd->sensor != SENSOR_PO1030 && sd->sensor != SENSOR_SOI768 &&
1663         sd->sensor != SENSOR_SP80708)
1664         gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1665             V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
1666 
1667     if (sd->sensor == SENSOR_HV7131R || sd->sensor == SENSOR_OV7630 ||
1668         sd->sensor == SENSOR_OV7648 || sd->sensor == SENSOR_PO2030N)
1669         sd->vflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1670             V4L2_CID_VFLIP, 0, 1, 1, 0);
1671 
1672     if (sd->sensor == SENSOR_OV7630 || sd->sensor == SENSOR_OV7648 ||
1673         sd->sensor == SENSOR_OV7660)
1674         sd->freq = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops,
1675             V4L2_CID_POWER_LINE_FREQUENCY,
1676             V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0,
1677             V4L2_CID_POWER_LINE_FREQUENCY_50HZ);
1678 
1679     if (hdl->error) {
1680         pr_err("Could not initialize controls\n");
1681         return hdl->error;
1682     }
1683 
1684     v4l2_ctrl_cluster(2, &sd->red_bal);
1685     if (sd->sensor == SENSOR_PO2030N) {
1686         v4l2_ctrl_cluster(2, &sd->vflip);
1687         v4l2_ctrl_auto_cluster(3, &gspca_dev->autogain, 0, false);
1688     }
1689 
1690     return 0;
1691 }
1692 
1693 static u32 expo_adjust(struct gspca_dev *gspca_dev,
1694             u32 expo)
1695 {
1696     struct sd *sd = (struct sd *) gspca_dev;
1697 
1698     switch (sd->sensor) {
1699     case SENSOR_GC0307: {
1700         int a, b;
1701 
1702         /* expo = 0..255 -> a = 19..43 */
1703         a = 19 + expo * 25 / 256;
1704         i2c_w1(gspca_dev, 0x68, a);
1705         a -= 12;
1706         b = a * a * 4;          /* heuristic */
1707         i2c_w1(gspca_dev, 0x03, b >> 8);
1708         i2c_w1(gspca_dev, 0x04, b);
1709         break;
1710         }
1711     case SENSOR_HV7131R: {
1712         u8 Expodoit[] =
1713             { 0xc1, 0x11, 0x25, 0x00, 0x00, 0x00, 0x00, 0x16 };
1714 
1715         Expodoit[3] = expo >> 16;
1716         Expodoit[4] = expo >> 8;
1717         Expodoit[5] = expo;
1718         i2c_w8(gspca_dev, Expodoit);
1719         break;
1720         }
1721     case SENSOR_MI0360:
1722     case SENSOR_MI0360B: {
1723         u8 expoMi[] =       /* exposure 0x0635 -> 4 fp/s 0x10 */
1724             { 0xb1, 0x5d, 0x09, 0x00, 0x00, 0x00, 0x00, 0x16 };
1725         static const u8 doit[] =        /* update sensor */
1726             { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
1727         static const u8 sensorgo[] =        /* sensor on */
1728             { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
1729 
1730         if (expo > 0x0635)
1731             expo = 0x0635;
1732         else if (expo < 0x0001)
1733             expo = 0x0001;
1734         expoMi[3] = expo >> 8;
1735         expoMi[4] = expo;
1736         i2c_w8(gspca_dev, expoMi);
1737         i2c_w8(gspca_dev, doit);
1738         i2c_w8(gspca_dev, sensorgo);
1739         break;
1740         }
1741     case SENSOR_MO4000: {
1742         u8 expoMof[] =
1743             { 0xa1, 0x21, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x10 };
1744         u8 expoMo10[] =
1745             { 0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10 };
1746         static const u8 gainMo[] =
1747             { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
1748 
1749         if (expo > 0x1fff)
1750             expo = 0x1fff;
1751         else if (expo < 0x0001)
1752             expo = 0x0001;
1753         expoMof[3] = (expo & 0x03fc) >> 2;
1754         i2c_w8(gspca_dev, expoMof);
1755         expoMo10[3] = ((expo & 0x1c00) >> 10)
1756                 | ((expo & 0x0003) << 4);
1757         i2c_w8(gspca_dev, expoMo10);
1758         i2c_w8(gspca_dev, gainMo);
1759         gspca_dbg(gspca_dev, D_FRAM, "set exposure %d\n",
1760               ((expoMo10[3] & 0x07) << 10)
1761               | (expoMof[3] << 2)
1762               | ((expoMo10[3] & 0x30) >> 4));
1763         break;
1764         }
1765     case SENSOR_MT9V111: {
1766         u8 expo_c1[] =
1767             { 0xb1, 0x5c, 0x09, 0x00, 0x00, 0x00, 0x00, 0x10 };
1768 
1769         if (expo > 0x0390)
1770             expo = 0x0390;
1771         else if (expo < 0x0060)
1772             expo = 0x0060;
1773         expo_c1[3] = expo >> 8;
1774         expo_c1[4] = expo;
1775         i2c_w8(gspca_dev, expo_c1);
1776         break;
1777         }
1778     case SENSOR_OM6802: {
1779         u8 gainOm[] =
1780             { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
1781                 /* preset AGC - works when AutoExpo = off */
1782 
1783         if (expo > 0x03ff)
1784             expo = 0x03ff;
1785         if (expo < 0x0001)
1786             expo = 0x0001;
1787         gainOm[3] = expo >> 2;
1788         i2c_w8(gspca_dev, gainOm);
1789         reg_w1(gspca_dev, 0x96, expo >> 5);
1790         gspca_dbg(gspca_dev, D_FRAM, "set exposure %d\n", gainOm[3]);
1791         break;
1792         }
1793     }
1794     return expo;
1795 }
1796 
1797 static void setbrightness(struct gspca_dev *gspca_dev)
1798 {
1799     struct sd *sd = (struct sd *) gspca_dev;
1800     unsigned int expo;
1801     int brightness = sd->brightness->val;
1802     u8 k2;
1803 
1804     k2 = (brightness - 0x80) >> 2;
1805     switch (sd->sensor) {
1806     case SENSOR_ADCM1700:
1807         if (k2 > 0x1f)
1808             k2 = 0;     /* only positive Y offset */
1809         break;
1810     case SENSOR_HV7131R:
1811         expo = brightness << 12;
1812         if (expo > 0x002dc6c0)
1813             expo = 0x002dc6c0;
1814         else if (expo < 0x02a0)
1815             expo = 0x02a0;
1816         sd->exposure = expo_adjust(gspca_dev, expo);
1817         break;
1818     case SENSOR_MI0360:
1819     case SENSOR_MO4000:
1820         expo = brightness << 4;
1821         sd->exposure = expo_adjust(gspca_dev, expo);
1822         break;
1823     case SENSOR_MI0360B:
1824         expo = brightness << 2;
1825         sd->exposure = expo_adjust(gspca_dev, expo);
1826         break;
1827     case SENSOR_GC0307:
1828         expo = brightness;
1829         sd->exposure = expo_adjust(gspca_dev, expo);
1830         return;         /* don't set the Y offset */
1831     case SENSOR_MT9V111:
1832         expo = brightness << 2;
1833         sd->exposure = expo_adjust(gspca_dev, expo);
1834         return;         /* don't set the Y offset */
1835     case SENSOR_OM6802:
1836         expo = brightness << 2;
1837         sd->exposure = expo_adjust(gspca_dev, expo);
1838         return;         /* Y offset already set */
1839     }
1840 
1841     reg_w1(gspca_dev, 0x96, k2);    /* color matrix Y offset */
1842 }
1843 
1844 static void setcontrast(struct gspca_dev *gspca_dev)
1845 {
1846     struct sd *sd = (struct sd *) gspca_dev;
1847     u8 k2;
1848     u8 contrast[6];
1849 
1850     k2 = sd->contrast->val * 37 / (CONTRAST_MAX + 1)
1851                 + 37;       /* 37..73 */
1852     contrast[0] = (k2 + 1) / 2;     /* red */
1853     contrast[1] = 0;
1854     contrast[2] = k2;           /* green */
1855     contrast[3] = 0;
1856     contrast[4] = k2 / 5;           /* blue */
1857     contrast[5] = 0;
1858     reg_w(gspca_dev, 0x84, contrast, sizeof contrast);
1859 }
1860 
1861 static void setcolors(struct gspca_dev *gspca_dev)
1862 {
1863     struct sd *sd = (struct sd *) gspca_dev;
1864     int i, v, colors;
1865     const s16 *uv;
1866     u8 reg8a[12];           /* U & V gains */
1867     static const s16 uv_com[6] = {  /* same as reg84 in signed decimal */
1868         -24, -38, 64,       /* UR UG UB */
1869          62, -51, -9        /* VR VG VB */
1870     };
1871     static const s16 uv_mi0360b[6] = {
1872         -20, -38, 64,       /* UR UG UB */
1873          60, -51, -9        /* VR VG VB */
1874     };
1875 
1876     colors = sd->saturation->val;
1877     if (sd->sensor == SENSOR_MI0360B)
1878         uv = uv_mi0360b;
1879     else
1880         uv = uv_com;
1881     for (i = 0; i < 6; i++) {
1882         v = uv[i] * colors / COLORS_DEF;
1883         reg8a[i * 2] = v;
1884         reg8a[i * 2 + 1] = (v >> 8) & 0x0f;
1885     }
1886     reg_w(gspca_dev, 0x8a, reg8a, sizeof reg8a);
1887 }
1888 
1889 static void setredblue(struct gspca_dev *gspca_dev)
1890 {
1891     struct sd *sd = (struct sd *) gspca_dev;
1892 
1893     if (sd->sensor == SENSOR_PO2030N) {
1894         u8 rg1b[] =     /* red  green1 blue (no g2) */
1895             {0xc1, 0x6e, 0x16, 0x00, 0x40, 0x00, 0x00, 0x10};
1896 
1897         /* 0x40 = normal value = gain x 1 */
1898         rg1b[3] = sd->red_bal->val * 2;
1899         rg1b[5] = sd->blue_bal->val * 2;
1900         i2c_w8(gspca_dev, rg1b);
1901         return;
1902     }
1903     reg_w1(gspca_dev, 0x05, sd->red_bal->val);
1904 /*  reg_w1(gspca_dev, 0x07, 32); */
1905     reg_w1(gspca_dev, 0x06, sd->blue_bal->val);
1906 }
1907 
1908 static void setgamma(struct gspca_dev *gspca_dev)
1909 {
1910     struct sd *sd = (struct sd *) gspca_dev;
1911     int i, val;
1912     u8 gamma[17];
1913     const u8 *gamma_base;
1914     static const u8 delta[17] = {
1915         0x00, 0x14, 0x1c, 0x1c, 0x1c, 0x1c, 0x1b, 0x1a,
1916         0x18, 0x13, 0x10, 0x0e, 0x08, 0x07, 0x04, 0x02, 0x00
1917     };
1918 
1919     switch (sd->sensor) {
1920     case SENSOR_ADCM1700:
1921         gamma_base = gamma_spec_0;
1922         break;
1923     case SENSOR_HV7131R:
1924     case SENSOR_MI0360B:
1925     case SENSOR_MT9V111:
1926         gamma_base = gamma_spec_1;
1927         break;
1928     case SENSOR_GC0307:
1929         gamma_base = gamma_spec_2;
1930         break;
1931     case SENSOR_SP80708:
1932         gamma_base = gamma_spec_3;
1933         break;
1934     default:
1935         gamma_base = gamma_def;
1936         break;
1937     }
1938 
1939     val = sd->gamma->val;
1940     for (i = 0; i < sizeof gamma; i++)
1941         gamma[i] = gamma_base[i]
1942             + delta[i] * (val - GAMMA_DEF) / 32;
1943     reg_w(gspca_dev, 0x20, gamma, sizeof gamma);
1944 }
1945 
1946 static void setexposure(struct gspca_dev *gspca_dev)
1947 {
1948     struct sd *sd = (struct sd *) gspca_dev;
1949 
1950     if (sd->sensor == SENSOR_PO2030N) {
1951         u8 rexpo[] =        /* 1a: expo H, 1b: expo M */
1952             {0xa1, 0x6e, 0x1a, 0x00, 0x40, 0x00, 0x00, 0x10};
1953 
1954         rexpo[3] = gspca_dev->exposure->val >> 8;
1955         i2c_w8(gspca_dev, rexpo);
1956         msleep(6);
1957         rexpo[2] = 0x1b;
1958         rexpo[3] = gspca_dev->exposure->val;
1959         i2c_w8(gspca_dev, rexpo);
1960     }
1961 }
1962 
1963 static void setautogain(struct gspca_dev *gspca_dev)
1964 {
1965     struct sd *sd = (struct sd *) gspca_dev;
1966 
1967     switch (sd->sensor) {
1968     case SENSOR_OV7630:
1969     case SENSOR_OV7648: {
1970         u8 comb;
1971 
1972         if (sd->sensor == SENSOR_OV7630)
1973             comb = 0xc0;
1974         else
1975             comb = 0xa0;
1976         if (gspca_dev->autogain->val)
1977             comb |= 0x03;
1978         i2c_w1(&sd->gspca_dev, 0x13, comb);
1979         return;
1980         }
1981     }
1982     if (gspca_dev->autogain->val)
1983         sd->ag_cnt = AG_CNT_START;
1984     else
1985         sd->ag_cnt = -1;
1986 }
1987 
1988 static void setgain(struct gspca_dev *gspca_dev)
1989 {
1990     struct sd *sd = (struct sd *) gspca_dev;
1991 
1992     if (sd->sensor == SENSOR_PO2030N) {
1993         u8 rgain[] =        /* 15: gain */
1994             {0xa1, 0x6e, 0x15, 0x00, 0x40, 0x00, 0x00, 0x15};
1995 
1996         rgain[3] = gspca_dev->gain->val;
1997         i2c_w8(gspca_dev, rgain);
1998     }
1999 }
2000 
2001 static void sethvflip(struct gspca_dev *gspca_dev)
2002 {
2003     struct sd *sd = (struct sd *) gspca_dev;
2004     u8 comn;
2005 
2006     switch (sd->sensor) {
2007     case SENSOR_HV7131R:
2008         comn = 0x18;            /* clkdiv = 1, ablcen = 1 */
2009         if (sd->vflip->val)
2010             comn |= 0x01;
2011         i2c_w1(gspca_dev, 0x01, comn);  /* sctra */
2012         break;
2013     case SENSOR_OV7630:
2014         comn = 0x02;
2015         if (!sd->vflip->val)
2016             comn |= 0x80;
2017         i2c_w1(gspca_dev, 0x75, comn);
2018         break;
2019     case SENSOR_OV7648:
2020         comn = 0x06;
2021         if (sd->vflip->val)
2022             comn |= 0x80;
2023         i2c_w1(gspca_dev, 0x75, comn);
2024         break;
2025     case SENSOR_PO2030N:
2026         /* Reg. 0x1E: Timing Generator Control Register 2 (Tgcontrol2)
2027          * (reset value: 0x0A)
2028          * bit7: HM: Horizontal Mirror: 0: disable, 1: enable
2029          * bit6: VM: Vertical Mirror: 0: disable, 1: enable
2030          * bit5: ST: Shutter Selection: 0: electrical, 1: mechanical
2031          * bit4: FT: Single Frame Transfer: 0: disable, 1: enable
2032          * bit3-0: X
2033          */
2034         comn = 0x0a;
2035         if (sd->hflip->val)
2036             comn |= 0x80;
2037         if (sd->vflip->val)
2038             comn |= 0x40;
2039         i2c_w1(&sd->gspca_dev, 0x1e, comn);
2040         break;
2041     }
2042 }
2043 
2044 static void setsharpness(struct gspca_dev *gspca_dev)
2045 {
2046     struct sd *sd = (struct sd *) gspca_dev;
2047 
2048     reg_w1(gspca_dev, 0x99, sd->sharpness->val);
2049 }
2050 
2051 static void setillum(struct gspca_dev *gspca_dev)
2052 {
2053     struct sd *sd = (struct sd *) gspca_dev;
2054 
2055     switch (sd->sensor) {
2056     case SENSOR_ADCM1700:
2057         reg_w1(gspca_dev, 0x02,             /* gpio */
2058             sd->illum->val ? 0x64 : 0x60);
2059         break;
2060     case SENSOR_MT9V111:
2061         reg_w1(gspca_dev, 0x02,
2062             sd->illum->val ? 0x77 : 0x74);
2063 /* should have been: */
2064 /*                      0x55 : 0x54);   * 370i */
2065 /*                      0x66 : 0x64);   * Clip */
2066         break;
2067     }
2068 }
2069 
2070 static void setfreq(struct gspca_dev *gspca_dev)
2071 {
2072     struct sd *sd = (struct sd *) gspca_dev;
2073 
2074     if (sd->sensor == SENSOR_OV7660) {
2075         u8 com8;
2076 
2077         com8 = 0xdf;        /* auto gain/wb/expo */
2078         switch (sd->freq->val) {
2079         case 0: /* Banding filter disabled */
2080             i2c_w1(gspca_dev, 0x13, com8 | 0x20);
2081             break;
2082         case 1: /* 50 hz */
2083             i2c_w1(gspca_dev, 0x13, com8);
2084             i2c_w1(gspca_dev, 0x3b, 0x0a);
2085             break;
2086         case 2: /* 60 hz */
2087             i2c_w1(gspca_dev, 0x13, com8);
2088             i2c_w1(gspca_dev, 0x3b, 0x02);
2089             break;
2090         }
2091     } else {
2092         u8 reg2a = 0, reg2b = 0, reg2d = 0;
2093 
2094         /* Get reg2a / reg2d base values */
2095         switch (sd->sensor) {
2096         case SENSOR_OV7630:
2097             reg2a = 0x08;
2098             reg2d = 0x01;
2099             break;
2100         case SENSOR_OV7648:
2101             reg2a = 0x11;
2102             reg2d = 0x81;
2103             break;
2104         }
2105 
2106         switch (sd->freq->val) {
2107         case 0: /* Banding filter disabled */
2108             break;
2109         case 1: /* 50 hz (filter on and framerate adj) */
2110             reg2a |= 0x80;
2111             reg2b = 0xac;
2112             reg2d |= 0x04;
2113             break;
2114         case 2: /* 60 hz (filter on, no framerate adj) */
2115             reg2a |= 0x80;
2116             reg2d |= 0x04;
2117             break;
2118         }
2119         i2c_w1(gspca_dev, 0x2a, reg2a);
2120         i2c_w1(gspca_dev, 0x2b, reg2b);
2121         i2c_w1(gspca_dev, 0x2d, reg2d);
2122     }
2123 }
2124 
2125 static void setjpegqual(struct gspca_dev *gspca_dev)
2126 {
2127     struct sd *sd = (struct sd *) gspca_dev;
2128 
2129     jpeg_set_qual(sd->jpeg_hdr, sd->quality);
2130 #if USB_BUF_SZ < 64
2131 #error "No room enough in usb_buf for quantization table"
2132 #endif
2133     memcpy(gspca_dev->usb_buf, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64);
2134     usb_control_msg(gspca_dev->dev,
2135             usb_sndctrlpipe(gspca_dev->dev, 0),
2136             0x08,
2137             USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
2138             0x0100, 0,
2139             gspca_dev->usb_buf, 64,
2140             500);
2141     memcpy(gspca_dev->usb_buf, &sd->jpeg_hdr[JPEG_QT1_OFFSET], 64);
2142     usb_control_msg(gspca_dev->dev,
2143             usb_sndctrlpipe(gspca_dev->dev, 0),
2144             0x08,
2145             USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
2146             0x0140, 0,
2147             gspca_dev->usb_buf, 64,
2148             500);
2149 
2150     sd->reg18 ^= 0x40;
2151     reg_w1(gspca_dev, 0x18, sd->reg18);
2152 }
2153 
2154 /* JPEG quality update */
2155 /* This function is executed from a work queue. */
2156 static void qual_upd(struct work_struct *work)
2157 {
2158     struct sd *sd = container_of(work, struct sd, work);
2159     struct gspca_dev *gspca_dev = &sd->gspca_dev;
2160 
2161     /* To protect gspca_dev->usb_buf and gspca_dev->usb_err */
2162     mutex_lock(&gspca_dev->usb_lock);
2163     gspca_dbg(gspca_dev, D_STREAM, "qual_upd %d%%\n", sd->quality);
2164     gspca_dev->usb_err = 0;
2165     setjpegqual(gspca_dev);
2166     mutex_unlock(&gspca_dev->usb_lock);
2167 }
2168 
2169 /* -- start the camera -- */
2170 static int sd_start(struct gspca_dev *gspca_dev)
2171 {
2172     struct sd *sd = (struct sd *) gspca_dev;
2173     int i;
2174     u8 reg01, reg17;
2175     u8 reg0102[2];
2176     const u8 *sn9c1xx;
2177     const u8 (*init)[8];
2178     const u8 *reg9a;
2179     int mode;
2180     static const u8 reg9a_def[] =
2181         {0x00, 0x40, 0x20, 0x00, 0x00, 0x00};
2182     static const u8 reg9a_spec[] =
2183         {0x00, 0x40, 0x38, 0x30, 0x00, 0x20};
2184     static const u8 regd4[] = {0x60, 0x00, 0x00};
2185     static const u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
2186     static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
2187     static const u8 CA_adcm1700[] =
2188                 { 0x14, 0xec, 0x0a, 0xf6 };
2189     static const u8 CA_po2030n[] =
2190                 { 0x1e, 0xe2, 0x14, 0xec };
2191     static const u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd };  /* MI0360 */
2192     static const u8 CE_gc0307[] =
2193                 { 0x32, 0xce, 0x2d, 0xd3 };
2194     static const u8 CE_ov76xx[] =
2195                 { 0x32, 0xdd, 0x32, 0xdd };
2196     static const u8 CE_po2030n[] =
2197                 { 0x14, 0xe7, 0x1e, 0xdd };
2198 
2199     /* create the JPEG header */
2200     jpeg_define(sd->jpeg_hdr, gspca_dev->pixfmt.height,
2201             gspca_dev->pixfmt.width,
2202             0x21);      /* JPEG 422 */
2203 
2204     /* initialize the bridge */
2205     sn9c1xx = sn_tb[sd->sensor];
2206 
2207     /* sensor clock already enabled in sd_init */
2208     /* reg_w1(gspca_dev, 0xf1, 0x00); */
2209     reg01 = sn9c1xx[1];
2210     if (sd->flags & F_PDN_INV)
2211         reg01 ^= S_PDN_INV;     /* power down inverted */
2212     reg_w1(gspca_dev, 0x01, reg01);
2213 
2214     /* configure gpio */
2215     reg0102[0] = reg01;
2216     reg0102[1] = sn9c1xx[2];
2217     if (gspca_dev->audio)
2218         reg0102[1] |= 0x04; /* keep the audio connection */
2219     reg_w(gspca_dev, 0x01, reg0102, 2);
2220     reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
2221     reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5);
2222     switch (sd->sensor) {
2223     case SENSOR_GC0307:
2224     case SENSOR_OV7660:
2225     case SENSOR_PO1030:
2226     case SENSOR_PO2030N:
2227     case SENSOR_SOI768:
2228     case SENSOR_SP80708:
2229         reg9a = reg9a_spec;
2230         break;
2231     default:
2232         reg9a = reg9a_def;
2233         break;
2234     }
2235     reg_w(gspca_dev, 0x9a, reg9a, 6);
2236 
2237     reg_w(gspca_dev, 0xd4, regd4, sizeof regd4);
2238 
2239     reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
2240 
2241     reg17 = sn9c1xx[0x17];
2242     switch (sd->sensor) {
2243     case SENSOR_GC0307:
2244         msleep(50);     /*fixme: is it useful? */
2245         break;
2246     case SENSOR_OM6802:
2247         msleep(10);
2248         reg_w1(gspca_dev, 0x02, 0x73);
2249         reg17 |= SEN_CLK_EN;
2250         reg_w1(gspca_dev, 0x17, reg17);
2251         reg_w1(gspca_dev, 0x01, 0x22);
2252         msleep(100);
2253         reg01 = SCL_SEL_OD | S_PDN_INV;
2254         reg17 &= ~MCK_SIZE_MASK;
2255         reg17 |= 0x04;      /* clock / 4 */
2256         break;
2257     }
2258     reg01 |= SYS_SEL_48M;
2259     reg_w1(gspca_dev, 0x01, reg01);
2260     reg17 |= SEN_CLK_EN;
2261     reg_w1(gspca_dev, 0x17, reg17);
2262     reg01 &= ~S_PWR_DN;     /* sensor power on */
2263     reg_w1(gspca_dev, 0x01, reg01);
2264     reg01 &= ~SCL_SEL_OD;       /* remove open-drain mode */
2265     reg_w1(gspca_dev, 0x01, reg01);
2266 
2267     switch (sd->sensor) {
2268     case SENSOR_HV7131R:
2269         hv7131r_probe(gspca_dev);   /*fixme: is it useful? */
2270         break;
2271     case SENSOR_OM6802:
2272         msleep(10);
2273         reg_w1(gspca_dev, 0x01, reg01);
2274         i2c_w8(gspca_dev, om6802_init0[0]);
2275         i2c_w8(gspca_dev, om6802_init0[1]);
2276         msleep(15);
2277         reg_w1(gspca_dev, 0x02, 0x71);
2278         msleep(150);
2279         break;
2280     case SENSOR_SP80708:
2281         msleep(100);
2282         reg_w1(gspca_dev, 0x02, 0x62);
2283         break;
2284     }
2285 
2286     /* initialize the sensor */
2287     i2c_w_seq(gspca_dev, sensor_init[sd->sensor]);
2288 
2289     reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
2290     reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
2291     reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
2292     reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]);
2293     reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
2294     if (sd->sensor == SENSOR_ADCM1700) {
2295         reg_w1(gspca_dev, 0xd2, 0x3a);  /* AE_H_SIZE = 116 */
2296         reg_w1(gspca_dev, 0xd3, 0x30);  /* AE_V_SIZE = 96 */
2297     } else {
2298         reg_w1(gspca_dev, 0xd2, 0x6a);  /* AE_H_SIZE = 212 */
2299         reg_w1(gspca_dev, 0xd3, 0x50);  /* AE_V_SIZE = 160 */
2300     }
2301     reg_w1(gspca_dev, 0xc6, 0x00);
2302     reg_w1(gspca_dev, 0xc7, 0x00);
2303     if (sd->sensor == SENSOR_ADCM1700) {
2304         reg_w1(gspca_dev, 0xc8, 0x2c);  /* AW_H_STOP = 352 */
2305         reg_w1(gspca_dev, 0xc9, 0x24);  /* AW_V_STOP = 288 */
2306     } else {
2307         reg_w1(gspca_dev, 0xc8, 0x50);  /* AW_H_STOP = 640 */
2308         reg_w1(gspca_dev, 0xc9, 0x3c);  /* AW_V_STOP = 480 */
2309     }
2310     reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
2311     switch (sd->sensor) {
2312     case SENSOR_OM6802:
2313 /*  case SENSOR_OV7648:     * fixme: sometimes */
2314         break;
2315     default:
2316         reg17 |= DEF_EN;
2317         break;
2318     }
2319     reg_w1(gspca_dev, 0x17, reg17);
2320 
2321     reg_w1(gspca_dev, 0x05, 0x00);      /* red */
2322     reg_w1(gspca_dev, 0x07, 0x00);      /* green */
2323     reg_w1(gspca_dev, 0x06, 0x00);      /* blue */
2324     reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
2325 
2326     setgamma(gspca_dev);
2327 
2328 /*fixme: 8 times with all zeroes and 1 or 2 times with normal values */
2329     for (i = 0; i < 8; i++)
2330         reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
2331     switch (sd->sensor) {
2332     case SENSOR_ADCM1700:
2333     case SENSOR_OV7660:
2334     case SENSOR_SP80708:
2335         reg_w1(gspca_dev, 0x9a, 0x05);
2336         break;
2337     case SENSOR_GC0307:
2338     case SENSOR_MT9V111:
2339     case SENSOR_MI0360B:
2340         reg_w1(gspca_dev, 0x9a, 0x07);
2341         break;
2342     case SENSOR_OV7630:
2343     case SENSOR_OV7648:
2344         reg_w1(gspca_dev, 0x9a, 0x0a);
2345         break;
2346     case SENSOR_PO2030N:
2347     case SENSOR_SOI768:
2348         reg_w1(gspca_dev, 0x9a, 0x06);
2349         break;
2350     default:
2351         reg_w1(gspca_dev, 0x9a, 0x08);
2352         break;
2353     }
2354     setsharpness(gspca_dev);
2355 
2356     reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
2357     reg_w1(gspca_dev, 0x05, 0x20);      /* red */
2358     reg_w1(gspca_dev, 0x07, 0x20);      /* green */
2359     reg_w1(gspca_dev, 0x06, 0x20);      /* blue */
2360 
2361     init = NULL;
2362     mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
2363     reg01 |= SYS_SEL_48M | V_TX_EN;
2364     reg17 &= ~MCK_SIZE_MASK;
2365     reg17 |= 0x02;          /* clock / 2 */
2366     switch (sd->sensor) {
2367     case SENSOR_ADCM1700:
2368         init = adcm1700_sensor_param1;
2369         break;
2370     case SENSOR_GC0307:
2371         init = gc0307_sensor_param1;
2372         break;
2373     case SENSOR_HV7131R:
2374     case SENSOR_MI0360:
2375         if (!mode)
2376             reg01 &= ~SYS_SEL_48M;  /* 640x480: clk 24Mhz */
2377         reg17 &= ~MCK_SIZE_MASK;
2378         reg17 |= 0x01;          /* clock / 1 */
2379         break;
2380     case SENSOR_MI0360B:
2381         init = mi0360b_sensor_param1;
2382         break;
2383     case SENSOR_MO4000:
2384         if (mode) {         /* if 320x240 */
2385             reg01 &= ~SYS_SEL_48M;  /* clk 24Mz */
2386             reg17 &= ~MCK_SIZE_MASK;
2387             reg17 |= 0x01;      /* clock / 1 */
2388         }
2389         break;
2390     case SENSOR_MT9V111:
2391         init = mt9v111_sensor_param1;
2392         break;
2393     case SENSOR_OM6802:
2394         init = om6802_sensor_param1;
2395         if (!mode) {            /* if 640x480 */
2396             reg17 &= ~MCK_SIZE_MASK;
2397             reg17 |= 0x04;      /* clock / 4 */
2398         } else {
2399             reg01 &= ~SYS_SEL_48M;  /* clk 24Mz */
2400             reg17 &= ~MCK_SIZE_MASK;
2401             reg17 |= 0x02;      /* clock / 2 */
2402         }
2403         break;
2404     case SENSOR_OV7630:
2405         init = ov7630_sensor_param1;
2406         break;
2407     case SENSOR_OV7648:
2408         init = ov7648_sensor_param1;
2409         reg17 &= ~MCK_SIZE_MASK;
2410         reg17 |= 0x01;          /* clock / 1 */
2411         break;
2412     case SENSOR_OV7660:
2413         init = ov7660_sensor_param1;
2414         break;
2415     case SENSOR_PO1030:
2416         init = po1030_sensor_param1;
2417         break;
2418     case SENSOR_PO2030N:
2419         init = po2030n_sensor_param1;
2420         break;
2421     case SENSOR_SOI768:
2422         init = soi768_sensor_param1;
2423         break;
2424     case SENSOR_SP80708:
2425         init = sp80708_sensor_param1;
2426         break;
2427     }
2428 
2429     /* more sensor initialization - param1 */
2430     if (init != NULL) {
2431         i2c_w_seq(gspca_dev, init);
2432 /*      init = NULL; */
2433     }
2434 
2435     reg_w(gspca_dev, 0xc0, C0, 6);
2436     switch (sd->sensor) {
2437     case SENSOR_ADCM1700:
2438     case SENSOR_GC0307:
2439     case SENSOR_SOI768:
2440         reg_w(gspca_dev, 0xca, CA_adcm1700, 4);
2441         break;
2442     case SENSOR_PO2030N:
2443         reg_w(gspca_dev, 0xca, CA_po2030n, 4);
2444         break;
2445     default:
2446         reg_w(gspca_dev, 0xca, CA, 4);
2447         break;
2448     }
2449     switch (sd->sensor) {
2450     case SENSOR_ADCM1700:
2451     case SENSOR_OV7630:
2452     case SENSOR_OV7648:
2453     case SENSOR_OV7660:
2454     case SENSOR_SOI768:
2455         reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
2456         break;
2457     case SENSOR_GC0307:
2458         reg_w(gspca_dev, 0xce, CE_gc0307, 4);
2459         break;
2460     case SENSOR_PO2030N:
2461         reg_w(gspca_dev, 0xce, CE_po2030n, 4);
2462         break;
2463     default:
2464         reg_w(gspca_dev, 0xce, CE, 4);
2465                     /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
2466         break;
2467     }
2468 
2469     /* here change size mode 0 -> VGA; 1 -> CIF */
2470     sd->reg18 = sn9c1xx[0x18] | (mode << 4) | 0x40;
2471     reg_w1(gspca_dev, 0x18, sd->reg18);
2472     setjpegqual(gspca_dev);
2473 
2474     reg_w1(gspca_dev, 0x17, reg17);
2475     reg_w1(gspca_dev, 0x01, reg01);
2476     sd->reg01 = reg01;
2477     sd->reg17 = reg17;
2478 
2479     sd->pktsz = sd->npkt = 0;
2480     sd->nchg = sd->short_mark = 0;
2481 
2482     return gspca_dev->usb_err;
2483 }
2484 
2485 static void sd_stopN(struct gspca_dev *gspca_dev)
2486 {
2487     struct sd *sd = (struct sd *) gspca_dev;
2488     static const u8 stophv7131[] =
2489         { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
2490     static const u8 stopmi0360[] =
2491         { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
2492     static const u8 stopov7648[] =
2493         { 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
2494     static const u8 stopsoi768[] =
2495         { 0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10 };
2496     u8 reg01;
2497     u8 reg17;
2498 
2499     reg01 = sd->reg01;
2500     reg17 = sd->reg17 & ~SEN_CLK_EN;
2501     switch (sd->sensor) {
2502     case SENSOR_ADCM1700:
2503     case SENSOR_GC0307:
2504     case SENSOR_PO2030N:
2505     case SENSOR_SP80708:
2506         reg01 |= LED;
2507         reg_w1(gspca_dev, 0x01, reg01);
2508         reg01 &= ~(LED | V_TX_EN);
2509         reg_w1(gspca_dev, 0x01, reg01);
2510 /*      reg_w1(gspca_dev, 0x02, 0x??);   * LED off ? */
2511         break;
2512     case SENSOR_HV7131R:
2513         reg01 &= ~V_TX_EN;
2514         reg_w1(gspca_dev, 0x01, reg01);
2515         i2c_w8(gspca_dev, stophv7131);
2516         break;
2517     case SENSOR_MI0360:
2518     case SENSOR_MI0360B:
2519         reg01 &= ~V_TX_EN;
2520         reg_w1(gspca_dev, 0x01, reg01);
2521 /*      reg_w1(gspca_dev, 0x02, 0x40);    * LED off ? */
2522         i2c_w8(gspca_dev, stopmi0360);
2523         break;
2524     case SENSOR_MT9V111:
2525     case SENSOR_OM6802:
2526     case SENSOR_PO1030:
2527         reg01 &= ~V_TX_EN;
2528         reg_w1(gspca_dev, 0x01, reg01);
2529         break;
2530     case SENSOR_OV7630:
2531     case SENSOR_OV7648:
2532         reg01 &= ~V_TX_EN;
2533         reg_w1(gspca_dev, 0x01, reg01);
2534         i2c_w8(gspca_dev, stopov7648);
2535         break;
2536     case SENSOR_OV7660:
2537         reg01 &= ~V_TX_EN;
2538         reg_w1(gspca_dev, 0x01, reg01);
2539         break;
2540     case SENSOR_SOI768:
2541         i2c_w8(gspca_dev, stopsoi768);
2542         break;
2543     }
2544 
2545     reg01 |= SCL_SEL_OD;
2546     reg_w1(gspca_dev, 0x01, reg01);
2547     reg01 |= S_PWR_DN;      /* sensor power down */
2548     reg_w1(gspca_dev, 0x01, reg01);
2549     reg_w1(gspca_dev, 0x17, reg17);
2550     reg01 &= ~SYS_SEL_48M;      /* clock 24MHz */
2551     reg_w1(gspca_dev, 0x01, reg01);
2552     reg01 |= LED;
2553     reg_w1(gspca_dev, 0x01, reg01);
2554     /* Don't disable sensor clock as that disables the button on the cam */
2555     /* reg_w1(gspca_dev, 0xf1, 0x01); */
2556 }
2557 
2558 /* called on streamoff with alt==0 and on disconnect */
2559 /* the usb_lock is held at entry - restore on exit */
2560 static void sd_stop0(struct gspca_dev *gspca_dev)
2561 {
2562     struct sd *sd = (struct sd *) gspca_dev;
2563 
2564     mutex_unlock(&gspca_dev->usb_lock);
2565     flush_work(&sd->work);
2566     mutex_lock(&gspca_dev->usb_lock);
2567 }
2568 
2569 static void do_autogain(struct gspca_dev *gspca_dev)
2570 {
2571     struct sd *sd = (struct sd *) gspca_dev;
2572     int delta;
2573     int expotimes;
2574     u8 luma_mean = 130;
2575     u8 luma_delta = 20;
2576 
2577     /* Thanks S., without your advice, autobright should not work :) */
2578     if (sd->ag_cnt < 0)
2579         return;
2580     if (--sd->ag_cnt >= 0)
2581         return;
2582     sd->ag_cnt = AG_CNT_START;
2583 
2584     delta = atomic_read(&sd->avg_lum);
2585     gspca_dbg(gspca_dev, D_FRAM, "mean lum %d\n", delta);
2586 
2587     if (sd->sensor == SENSOR_PO2030N) {
2588         gspca_expo_autogain(gspca_dev, delta, luma_mean, luma_delta,
2589                     15, 1024);
2590         return;
2591     }
2592 
2593     if (delta < luma_mean - luma_delta ||
2594         delta > luma_mean + luma_delta) {
2595         switch (sd->sensor) {
2596         case SENSOR_GC0307:
2597             expotimes = sd->exposure;
2598             expotimes += (luma_mean - delta) >> 6;
2599             if (expotimes < 0)
2600                 expotimes = 0;
2601             sd->exposure = expo_adjust(gspca_dev,
2602                            (unsigned int) expotimes);
2603             break;
2604         case SENSOR_HV7131R:
2605             expotimes = sd->exposure >> 8;
2606             expotimes += (luma_mean - delta) >> 4;
2607             if (expotimes < 0)
2608                 expotimes = 0;
2609             sd->exposure = expo_adjust(gspca_dev,
2610                     (unsigned int) (expotimes << 8));
2611             break;
2612         case SENSOR_OM6802:
2613         case SENSOR_MT9V111:
2614             expotimes = sd->exposure;
2615             expotimes += (luma_mean - delta) >> 2;
2616             if (expotimes < 0)
2617                 expotimes = 0;
2618             sd->exposure = expo_adjust(gspca_dev,
2619                            (unsigned int) expotimes);
2620             setredblue(gspca_dev);
2621             break;
2622         default:
2623 /*      case SENSOR_MO4000: */
2624 /*      case SENSOR_MI0360: */
2625 /*      case SENSOR_MI0360B: */
2626             expotimes = sd->exposure;
2627             expotimes += (luma_mean - delta) >> 6;
2628             if (expotimes < 0)
2629                 expotimes = 0;
2630             sd->exposure = expo_adjust(gspca_dev,
2631                            (unsigned int) expotimes);
2632             setredblue(gspca_dev);
2633             break;
2634         }
2635     }
2636 }
2637 
2638 /* set the average luminosity from an isoc marker */
2639 static void set_lum(struct sd *sd,
2640             u8 *data)
2641 {
2642     int avg_lum;
2643 
2644     /*  w0 w1 w2
2645      *  w3 w4 w5
2646      *  w6 w7 w8
2647      */
2648     avg_lum = (data[27] << 8) + data[28]        /* w3 */
2649 
2650         + (data[31] << 8) + data[32]        /* w5 */
2651 
2652         + (data[23] << 8) + data[24]        /* w1 */
2653 
2654         + (data[35] << 8) + data[36]        /* w7 */
2655 
2656         + (data[29] << 10) + (data[30] << 2);   /* w4 * 4 */
2657     avg_lum >>= 10;
2658     atomic_set(&sd->avg_lum, avg_lum);
2659 }
2660 
2661 /* scan the URB packets */
2662 /* This function is run at interrupt level. */
2663 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2664             u8 *data,           /* isoc packet */
2665             int len)            /* iso packet length */
2666 {
2667     struct sd *sd = (struct sd *) gspca_dev;
2668     int i, new_qual;
2669 
2670     /*
2671      * A frame ends on the marker
2672      *      ff ff 00 c4 c4 96 ..
2673      * which is 62 bytes long and is followed by various information
2674      * including statuses and luminosity.
2675      *
2676      * A marker may be split on two packets.
2677      *
2678      * The 6th byte of a marker contains the bits:
2679      *  0x08: USB full
2680      *  0xc0: frame sequence
2681      * When the bit 'USB full' is set, the frame must be discarded;
2682      * this is also the case when the 2 bytes before the marker are
2683      * not the JPEG end of frame ('ff d9').
2684      */
2685 
2686     /* count the packets and their size */
2687     sd->npkt++;
2688     sd->pktsz += len;
2689 
2690 /*fixme: assumption about the following code:
2691  *  - there can be only one marker in a packet
2692  */
2693 
2694     /* skip the remaining bytes of a short marker */
2695     i = sd->short_mark;
2696     if (i != 0) {
2697         sd->short_mark = 0;
2698         if (i < 0   /* if 'ff' at end of previous packet */
2699          && data[0] == 0xff
2700          && data[1] == 0x00)
2701             goto marker_found;
2702         if (data[0] == 0xff && data[1] == 0xff) {
2703             i = 0;
2704             goto marker_found;
2705         }
2706         len -= i;
2707         if (len <= 0)
2708             return;
2709         data += i;
2710     }
2711 
2712     /* search backwards if there is a marker in the packet */
2713     for (i = len - 1; --i >= 0; ) {
2714         if (data[i] != 0xff) {
2715             i--;
2716             continue;
2717         }
2718         if (data[i + 1] == 0xff) {
2719 
2720             /* (there may be 'ff ff' inside a marker) */
2721             if (i + 2 >= len || data[i + 2] == 0x00)
2722                 goto marker_found;
2723         }
2724     }
2725 
2726     /* no marker found */
2727     /* add the JPEG header if first fragment */
2728     if (data[len - 1] == 0xff)
2729         sd->short_mark = -1;
2730     if (gspca_dev->last_packet_type == LAST_PACKET)
2731         gspca_frame_add(gspca_dev, FIRST_PACKET,
2732                 sd->jpeg_hdr, JPEG_HDR_SZ);
2733     gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
2734     return;
2735 
2736     /* marker found */
2737     /* if some error, discard the frame and decrease the quality */
2738 marker_found:
2739     new_qual = 0;
2740     if (i > 2) {
2741         if (data[i - 2] != 0xff || data[i - 1] != 0xd9) {
2742             gspca_dev->last_packet_type = DISCARD_PACKET;
2743             new_qual = -3;
2744         }
2745     } else if (i + 6 < len) {
2746         if (data[i + 6] & 0x08) {
2747             gspca_dev->last_packet_type = DISCARD_PACKET;
2748             new_qual = -5;
2749         }
2750     }
2751 
2752     gspca_frame_add(gspca_dev, LAST_PACKET, data, i);
2753 
2754     /* compute the filling rate and a new JPEG quality */
2755     if (new_qual == 0) {
2756         int r;
2757 
2758         r = (sd->pktsz * 100) /
2759             (sd->npkt *
2760                 gspca_dev->urb[0]->iso_frame_desc[0].length);
2761         if (r >= 85)
2762             new_qual = -3;
2763         else if (r < 75)
2764             new_qual = 2;
2765     }
2766     if (new_qual != 0) {
2767         sd->nchg += new_qual;
2768         if (sd->nchg < -6 || sd->nchg >= 12) {
2769             sd->nchg = 0;
2770             new_qual += sd->quality;
2771             if (new_qual < QUALITY_MIN)
2772                 new_qual = QUALITY_MIN;
2773             else if (new_qual > QUALITY_MAX)
2774                 new_qual = QUALITY_MAX;
2775             if (new_qual != sd->quality) {
2776                 sd->quality = new_qual;
2777                 schedule_work(&sd->work);
2778             }
2779         }
2780     } else {
2781         sd->nchg = 0;
2782     }
2783     sd->pktsz = sd->npkt = 0;
2784 
2785     /* if the marker is smaller than 62 bytes,
2786      * memorize the number of bytes to skip in the next packet */
2787     if (i + 62 > len) {         /* no more usable data */
2788         sd->short_mark = i + 62 - len;
2789         return;
2790     }
2791     if (sd->ag_cnt >= 0)
2792         set_lum(sd, data + i);
2793 
2794     /* if more data, start a new frame */
2795     i += 62;
2796     if (i < len) {
2797         data += i;
2798         len -= i;
2799         gspca_frame_add(gspca_dev, FIRST_PACKET,
2800                 sd->jpeg_hdr, JPEG_HDR_SZ);
2801         gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
2802     }
2803 }
2804 
2805 static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
2806 {
2807     struct gspca_dev *gspca_dev =
2808         container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
2809 
2810     gspca_dev->usb_err = 0;
2811 
2812     if (!gspca_dev->streaming)
2813         return 0;
2814 
2815     switch (ctrl->id) {
2816     case V4L2_CID_BRIGHTNESS:
2817         setbrightness(gspca_dev);
2818         break;
2819     case V4L2_CID_CONTRAST:
2820         setcontrast(gspca_dev);
2821         break;
2822     case V4L2_CID_SATURATION:
2823         setcolors(gspca_dev);
2824         break;
2825     case V4L2_CID_RED_BALANCE:
2826         setredblue(gspca_dev);
2827         break;
2828     case V4L2_CID_GAMMA:
2829         setgamma(gspca_dev);
2830         break;
2831     case V4L2_CID_AUTOGAIN:
2832         setautogain(gspca_dev);
2833         setexposure(gspca_dev);
2834         setgain(gspca_dev);
2835         break;
2836     case V4L2_CID_VFLIP:
2837         sethvflip(gspca_dev);
2838         break;
2839     case V4L2_CID_SHARPNESS:
2840         setsharpness(gspca_dev);
2841         break;
2842     case V4L2_CID_ILLUMINATORS_1:
2843         setillum(gspca_dev);
2844         break;
2845     case V4L2_CID_POWER_LINE_FREQUENCY:
2846         setfreq(gspca_dev);
2847         break;
2848     default:
2849         return -EINVAL;
2850     }
2851     return gspca_dev->usb_err;
2852 }
2853 
2854 #if IS_ENABLED(CONFIG_INPUT)
2855 static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
2856             u8 *data,       /* interrupt packet data */
2857             int len)        /* interrupt packet length */
2858 {
2859     int ret = -EINVAL;
2860 
2861     if (len == 1 && data[0] == 1) {
2862         input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
2863         input_sync(gspca_dev->input_dev);
2864         input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
2865         input_sync(gspca_dev->input_dev);
2866         ret = 0;
2867     }
2868 
2869     return ret;
2870 }
2871 #endif
2872 
2873 /* sub-driver description */
2874 static const struct sd_desc sd_desc = {
2875     .name = MODULE_NAME,
2876     .config = sd_config,
2877     .init = sd_init,
2878     .init_controls = sd_init_controls,
2879     .start = sd_start,
2880     .stopN = sd_stopN,
2881     .stop0 = sd_stop0,
2882     .pkt_scan = sd_pkt_scan,
2883     .dq_callback = do_autogain,
2884 #if IS_ENABLED(CONFIG_INPUT)
2885     .int_pkt_scan = sd_int_pkt_scan,
2886 #endif
2887 };
2888 
2889 /* -- module initialisation -- */
2890 #define BS(bridge, sensor) \
2891     .driver_info = (BRIDGE_ ## bridge << 16) \
2892             | (SENSOR_ ## sensor << 8)
2893 #define BSF(bridge, sensor, flags) \
2894     .driver_info = (BRIDGE_ ## bridge << 16) \
2895             | (SENSOR_ ## sensor << 8) \
2896             | (flags)
2897 static const struct usb_device_id device_table[] = {
2898     {USB_DEVICE(0x0458, 0x7025), BSF(SN9C120, MI0360B, F_PDN_INV)},
2899     {USB_DEVICE(0x0458, 0x702e), BS(SN9C120, OV7660)},
2900     {USB_DEVICE(0x045e, 0x00f5), BSF(SN9C105, OV7660, F_PDN_INV)},
2901     {USB_DEVICE(0x045e, 0x00f7), BSF(SN9C105, OV7660, F_PDN_INV)},
2902     {USB_DEVICE(0x0471, 0x0327), BS(SN9C105, MI0360)},
2903     {USB_DEVICE(0x0471, 0x0328), BS(SN9C105, MI0360)},
2904     {USB_DEVICE(0x0471, 0x0330), BS(SN9C105, MI0360)},
2905     {USB_DEVICE(0x06f8, 0x3004), BS(SN9C105, OV7660)},
2906     {USB_DEVICE(0x06f8, 0x3008), BS(SN9C105, OV7660)},
2907 /*  {USB_DEVICE(0x0c45, 0x603a), BS(SN9C102P, OV7648)}, */
2908     {USB_DEVICE(0x0c45, 0x6040), BS(SN9C102P, HV7131R)},
2909 /*  {USB_DEVICE(0x0c45, 0x607a), BS(SN9C102P, OV7648)}, */
2910 /*  {USB_DEVICE(0x0c45, 0x607b), BS(SN9C102P, OV7660)}, */
2911     {USB_DEVICE(0x0c45, 0x607c), BS(SN9C102P, HV7131R)},
2912 /*  {USB_DEVICE(0x0c45, 0x607e), BS(SN9C102P, OV7630)}, */
2913     {USB_DEVICE(0x0c45, 0x60c0), BSF(SN9C105, MI0360, F_ILLUM)},
2914                         /* or MT9V111 */
2915 /*  {USB_DEVICE(0x0c45, 0x60c2), BS(SN9C105, P1030xC)}, */
2916 /*  {USB_DEVICE(0x0c45, 0x60c8), BS(SN9C105, OM6802)}, */
2917 /*  {USB_DEVICE(0x0c45, 0x60cc), BS(SN9C105, HV7131GP)}, */
2918     {USB_DEVICE(0x0c45, 0x60ce), BS(SN9C105, SP80708)},
2919     {USB_DEVICE(0x0c45, 0x60ec), BS(SN9C105, MO4000)},
2920 /*  {USB_DEVICE(0x0c45, 0x60ef), BS(SN9C105, ICM105C)}, */
2921 /*  {USB_DEVICE(0x0c45, 0x60fa), BS(SN9C105, OV7648)}, */
2922 /*  {USB_DEVICE(0x0c45, 0x60f2), BS(SN9C105, OV7660)}, */
2923     {USB_DEVICE(0x0c45, 0x60fb), BS(SN9C105, OV7660)},
2924     {USB_DEVICE(0x0c45, 0x60fc), BS(SN9C105, HV7131R)},
2925     {USB_DEVICE(0x0c45, 0x60fe), BS(SN9C105, OV7630)},
2926     {USB_DEVICE(0x0c45, 0x6100), BS(SN9C120, MI0360)},  /*sn9c128*/
2927     {USB_DEVICE(0x0c45, 0x6102), BS(SN9C120, PO2030N)}, /* /GC0305*/
2928 /*  {USB_DEVICE(0x0c45, 0x6108), BS(SN9C120, OM6802)}, */
2929     {USB_DEVICE(0x0c45, 0x610a), BS(SN9C120, OV7648)},  /*sn9c128*/
2930     {USB_DEVICE(0x0c45, 0x610b), BS(SN9C120, OV7660)},  /*sn9c128*/
2931     {USB_DEVICE(0x0c45, 0x610c), BS(SN9C120, HV7131R)}, /*sn9c128*/
2932     {USB_DEVICE(0x0c45, 0x610e), BS(SN9C120, OV7630)},  /*sn9c128*/
2933 /*  {USB_DEVICE(0x0c45, 0x610f), BS(SN9C120, S5K53BEB)}, */
2934 /*  {USB_DEVICE(0x0c45, 0x6122), BS(SN9C110, ICM105C)}, */
2935 /*  {USB_DEVICE(0x0c45, 0x6123), BS(SN9C110, SanyoCCD)}, */
2936     {USB_DEVICE(0x0c45, 0x6128), BS(SN9C120, OM6802)},  /*sn9c325?*/
2937 /*bw600.inf:*/
2938     {USB_DEVICE(0x0c45, 0x612a), BS(SN9C120, OV7648)},  /*sn9c325?*/
2939     {USB_DEVICE(0x0c45, 0x612b), BS(SN9C110, ADCM1700)},
2940     {USB_DEVICE(0x0c45, 0x612c), BS(SN9C110, MO4000)},
2941     {USB_DEVICE(0x0c45, 0x612e), BS(SN9C110, OV7630)},
2942 /*  {USB_DEVICE(0x0c45, 0x612f), BS(SN9C110, ICM105C)}, */
2943     {USB_DEVICE(0x0c45, 0x6130), BS(SN9C120, MI0360)},
2944                         /* or MT9V111 / MI0360B */
2945 /*  {USB_DEVICE(0x0c45, 0x6132), BS(SN9C120, OV7670)}, */
2946     {USB_DEVICE(0x0c45, 0x6138), BS(SN9C120, MO4000)},
2947     {USB_DEVICE(0x0c45, 0x613a), BS(SN9C120, OV7648)},
2948     {USB_DEVICE(0x0c45, 0x613b), BS(SN9C120, OV7660)},
2949     {USB_DEVICE(0x0c45, 0x613c), BS(SN9C120, HV7131R)},
2950     {USB_DEVICE(0x0c45, 0x613e), BS(SN9C120, OV7630)},
2951     {USB_DEVICE(0x0c45, 0x6142), BS(SN9C120, PO2030N)}, /*sn9c120b*/
2952                         /* or GC0305 / GC0307 */
2953     {USB_DEVICE(0x0c45, 0x6143), BS(SN9C120, SP80708)}, /*sn9c120b*/
2954     {USB_DEVICE(0x0c45, 0x6148), BS(SN9C120, OM6802)},  /*sn9c120b*/
2955     {USB_DEVICE(0x0c45, 0x614a), BSF(SN9C120, ADCM1700, F_ILLUM)},
2956 /*  {USB_DEVICE(0x0c45, 0x614c), BS(SN9C120, GC0306)}, */   /*sn9c120b*/
2957     {}
2958 };
2959 MODULE_DEVICE_TABLE(usb, device_table);
2960 
2961 /* -- device connect -- */
2962 static int sd_probe(struct usb_interface *intf,
2963             const struct usb_device_id *id)
2964 {
2965     return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
2966                 THIS_MODULE);
2967 }
2968 
2969 static struct usb_driver sd_driver = {
2970     .name = MODULE_NAME,
2971     .id_table = device_table,
2972     .probe = sd_probe,
2973     .disconnect = gspca_disconnect,
2974 #ifdef CONFIG_PM
2975     .suspend = gspca_suspend,
2976     .resume = gspca_resume,
2977     .reset_resume = gspca_resume,
2978 #endif
2979 };
2980 
2981 module_usb_driver(sd_driver);