cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

sonixj.c (95058B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Sonix sn9c102p sn9c105 sn9c120 (jpeg) subdriver
      4 *
      5 * Copyright (C) 2009-2011 Jean-François Moine <http://moinejf.free.fr>
      6 * Copyright (C) 2005 Michel Xhaard mxhaard@magic.fr
      7 */
      8
      9#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
     10
     11#define MODULE_NAME "sonixj"
     12
     13#include <linux/input.h>
     14#include "gspca.h"
     15#include "jpeg.h"
     16
     17MODULE_AUTHOR("Jean-François Moine <http://moinejf.free.fr>");
     18MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver");
     19MODULE_LICENSE("GPL");
     20
     21/* specific webcam descriptor */
     22struct sd {
     23	struct gspca_dev gspca_dev;	/* !! must be the first item */
     24
     25	atomic_t avg_lum;
     26	struct v4l2_ctrl *brightness;
     27	struct v4l2_ctrl *contrast;
     28	struct v4l2_ctrl *saturation;
     29	struct { /* red/blue balance control cluster */
     30		struct v4l2_ctrl *red_bal;
     31		struct v4l2_ctrl *blue_bal;
     32	};
     33	struct { /* hflip/vflip control cluster */
     34		struct v4l2_ctrl *vflip;
     35		struct v4l2_ctrl *hflip;
     36	};
     37	struct v4l2_ctrl *gamma;
     38	struct v4l2_ctrl *illum;
     39	struct v4l2_ctrl *sharpness;
     40	struct v4l2_ctrl *freq;
     41	u32 exposure;
     42
     43	struct work_struct work;
     44
     45	u32 pktsz;			/* (used by pkt_scan) */
     46	u16 npkt;
     47	s8 nchg;
     48	s8 short_mark;
     49
     50	u8 quality;			/* image quality */
     51#define QUALITY_MIN 25
     52#define QUALITY_MAX 90
     53#define QUALITY_DEF 70
     54
     55	u8 reg01;
     56	u8 reg17;
     57	u8 reg18;
     58	u8 flags;
     59
     60	s8 ag_cnt;
     61#define AG_CNT_START 13
     62
     63	u8 bridge;
     64#define BRIDGE_SN9C102P 0
     65#define BRIDGE_SN9C105 1
     66#define BRIDGE_SN9C110 2
     67#define BRIDGE_SN9C120 3
     68	u8 sensor;			/* Type of image sensor chip */
     69	u8 i2c_addr;
     70
     71	u8 jpeg_hdr[JPEG_HDR_SZ];
     72};
     73enum sensors {
     74	SENSOR_ADCM1700,
     75	SENSOR_GC0307,
     76	SENSOR_HV7131R,
     77	SENSOR_MI0360,
     78	SENSOR_MI0360B,
     79	SENSOR_MO4000,
     80	SENSOR_MT9V111,
     81	SENSOR_OM6802,
     82	SENSOR_OV7630,
     83	SENSOR_OV7648,
     84	SENSOR_OV7660,
     85	SENSOR_PO1030,
     86	SENSOR_PO2030N,
     87	SENSOR_SOI768,
     88	SENSOR_SP80708,
     89};
     90
     91static void qual_upd(struct work_struct *work);
     92
     93/* device flags */
     94#define F_PDN_INV	0x01	/* inverse pin S_PWR_DN / sn_xxx tables */
     95#define F_ILLUM		0x02	/* presence of illuminator */
     96
     97/* sn9c1xx definitions */
     98/* register 0x01 */
     99#define S_PWR_DN	0x01	/* sensor power down */
    100#define S_PDN_INV	0x02	/* inverse pin S_PWR_DN */
    101#define V_TX_EN		0x04	/* video transfer enable */
    102#define LED		0x08	/* output to pin LED */
    103#define SCL_SEL_OD	0x20	/* open-drain mode */
    104#define SYS_SEL_48M	0x40	/* system clock 0: 24MHz, 1: 48MHz */
    105/* register 0x17 */
    106#define MCK_SIZE_MASK	0x1f	/* sensor master clock */
    107#define SEN_CLK_EN	0x20	/* enable sensor clock */
    108#define DEF_EN		0x80	/* defect pixel by 0: soft, 1: hard */
    109
    110static const struct v4l2_pix_format cif_mode[] = {
    111	{352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
    112		.bytesperline = 352,
    113		.sizeimage = 352 * 288 * 4 / 8 + 590,
    114		.colorspace = V4L2_COLORSPACE_JPEG,
    115		.priv = 0},
    116};
    117static const struct v4l2_pix_format vga_mode[] = {
    118	{160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
    119		.bytesperline = 160,
    120		.sizeimage = 160 * 120 * 4 / 8 + 590,
    121		.colorspace = V4L2_COLORSPACE_JPEG,
    122		.priv = 2},
    123	{320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
    124		.bytesperline = 320,
    125		.sizeimage = 320 * 240 * 3 / 8 + 590,
    126		.colorspace = V4L2_COLORSPACE_JPEG,
    127		.priv = 1},
    128	{640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
    129		.bytesperline = 640,
    130		/* Note 3 / 8 is not large enough, not even 5 / 8 is ?! */
    131		.sizeimage = 640 * 480 * 3 / 4 + 590,
    132		.colorspace = V4L2_COLORSPACE_JPEG,
    133		.priv = 0},
    134};
    135
    136static const u8 sn_adcm1700[0x1c] = {
    137/*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
    138	0x00,	0x43,	0x60,	0x00,	0x1a,	0x00,	0x00,	0x00,
    139/*	reg8	reg9	rega	regb	regc	regd	rege	regf */
    140	0x80,	0x51,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
    141/*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
    142	0x03,	0x00,	0x05,	0x01,	0x05,	0x16,	0x12,	0x42,
    143/*	reg18	reg19	reg1a	reg1b */
    144	0x06,	0x00,	0x00,	0x00
    145};
    146
    147static const u8 sn_gc0307[0x1c] = {
    148/*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
    149	0x00,	0x61,	0x62,	0x00,	0x1a,	0x00,	0x00,	0x00,
    150/*	reg8	reg9	rega	regb	regc	regd	rege	regf */
    151	0x80,	0x21,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
    152/*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
    153	0x03,	0x00,	0x03,	0x01,	0x08,	0x28,	0x1e,	0x02,
    154/*	reg18	reg19	reg1a	reg1b */
    155	0x06,	0x00,	0x00,	0x00
    156};
    157
    158static const u8 sn_hv7131[0x1c] = {
    159/*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
    160	0x00,	0x03,	0x60,	0x00,	0x1a,	0x20,	0x20,	0x20,
    161/*	reg8	reg9	rega	regb	regc	regd	rege	regf */
    162	0x81,	0x11,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
    163/*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
    164	0x03,	0x00,	0x00,	0x01,	0x03,	0x28,	0x1e,	0x41,
    165/*	reg18	reg19	reg1a	reg1b */
    166	0x0a,	0x00,	0x00,	0x00
    167};
    168
    169static const u8 sn_mi0360[0x1c] = {
    170/*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
    171	0x00,	0x63,	0x40,	0x00,	0x1a,	0x20,	0x20,	0x20,
    172/*	reg8	reg9	rega	regb	regc	regd	rege	regf */
    173	0x81,	0x5d,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
    174/*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
    175	0x03,	0x00,	0x00,	0x02,	0x0a,	0x28,	0x1e,	0x61,
    176/*	reg18	reg19	reg1a	reg1b */
    177	0x06,	0x00,	0x00,	0x00
    178};
    179
    180static const u8 sn_mi0360b[0x1c] = {
    181/*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
    182	0x00,	0x61,	0x40,	0x00,	0x1a,	0x00,	0x00,	0x00,
    183/*	reg8	reg9	rega	regb	regc	regd	rege	regf */
    184	0x81,	0x5d,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
    185/*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
    186	0x03,	0x00,	0x00,	0x02,	0x0a,	0x28,	0x1e,	0x40,
    187/*	reg18	reg19	reg1a	reg1b */
    188	0x06,	0x00,	0x00,	0x00
    189};
    190
    191static const u8 sn_mo4000[0x1c] = {
    192/*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
    193	0x00,	0x23,	0x60,	0x00,	0x1a,	0x00,	0x20,	0x18,
    194/*	reg8	reg9	rega	regb	regc	regd	rege	regf */
    195	0x81,	0x21,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
    196/*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
    197	0x03,	 0x00,	0x0b,	0x0f,	0x14,	0x28,	0x1e,	0x40,
    198/*	reg18	reg19	reg1a	reg1b */
    199	0x08,	0x00,	0x00,	0x00
    200};
    201
    202static const u8 sn_mt9v111[0x1c] = {
    203/*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
    204	0x00,	0x61,	0x40,	0x00,	0x1a,	0x20,	0x20,	0x20,
    205/*	reg8	reg9	rega	regb	regc	regd	rege	regf */
    206	0x81,	0x5c,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
    207/*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
    208	0x03,	0x00,	0x00,	0x02,	0x1c,	0x28,	0x1e,	0x40,
    209/*	reg18	reg19	reg1a	reg1b */
    210	0x06,	0x00,	0x00,	0x00
    211};
    212
    213static const u8 sn_om6802[0x1c] = {
    214/*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
    215	0x00,	0x23,	0x72,	0x00,	0x1a,	0x20,	0x20,	0x19,
    216/*	reg8	reg9	rega	regb	regc	regd	rege	regf */
    217	0x80,	0x34,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
    218/*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
    219	0x03,	0x00,	0x51,	0x01,	0x00,	0x28,	0x1e,	0x40,
    220/*	reg18	reg19	reg1a	reg1b */
    221	0x05,	0x00,	0x00,	0x00
    222};
    223
    224static const u8 sn_ov7630[0x1c] = {
    225/*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
    226	0x00,	0x21,	0x40,	0x00,	0x1a,	0x00,	0x00,	0x00,
    227/*	reg8	reg9	rega	regb	regc	regd	rege	regf */
    228	0x81,	0x21,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
    229/*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
    230	0x03,	0x00,	0x04,	0x01,	0x0a,	0x28,	0x1e,	0xc2,
    231/*	reg18	reg19	reg1a	reg1b */
    232	0x0b,	0x00,	0x00,	0x00
    233};
    234
    235static const u8 sn_ov7648[0x1c] = {
    236/*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
    237	0x00,	0x63,	0x40,	0x00,	0x1a,	0x20,	0x20,	0x20,
    238/*	reg8	reg9	rega	regb	regc	regd	rege	regf */
    239	0x81,	0x21,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
    240/*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
    241	0x03,	0x00,	0x00,	0x01,	0x00,	0x28,	0x1e,	0x00,
    242/*	reg18	reg19	reg1a	reg1b */
    243	0x0b,	0x00,	0x00,	0x00
    244};
    245
    246static const u8 sn_ov7660[0x1c] = {
    247/*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
    248	0x00,	0x61,	0x40,	0x00,	0x1a,	0x00,	0x00,	0x00,
    249/*	reg8	reg9	rega	regb	regc	regd	rege	regf */
    250	0x81,	0x21,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
    251/*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
    252	0x03,	0x00,	0x01,	0x01,	0x08,	0x28,	0x1e,	0x20,
    253/*	reg18	reg19	reg1a	reg1b */
    254	0x07,	0x00,	0x00,	0x00
    255};
    256
    257static const u8 sn_po1030[0x1c] = {
    258/*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
    259	0x00,	0x21,	0x62,	0x00,	0x1a,	0x20,	0x20,	0x20,
    260/*	reg8	reg9	rega	regb	regc	regd	rege	regf */
    261	0x81,	0x6e,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
    262/*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
    263	0x03,	0x00,	0x00,	0x06,	0x06,	0x28,	0x1e,	0x00,
    264/*	reg18	reg19	reg1a	reg1b */
    265	0x07,	0x00,	0x00,	0x00
    266};
    267
    268static const u8 sn_po2030n[0x1c] = {
    269/*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
    270	0x00,	0x63,	0x40,	0x00,	0x1a,	0x00,	0x00,	0x00,
    271/*	reg8	reg9	rega	regb	regc	regd	rege	regf */
    272	0x81,	0x6e,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
    273/*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
    274	0x03,	0x00,	0x00,	0x01,	0x14,	0x28,	0x1e,	0x00,
    275/*	reg18	reg19	reg1a	reg1b */
    276	0x07,	0x00,	0x00,	0x00
    277};
    278
    279static const u8 sn_soi768[0x1c] = {
    280/*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
    281	0x00,	0x21,	0x40,	0x00,	0x1a,	0x00,	0x00,	0x00,
    282/*	reg8	reg9	rega	regb	regc	regd	rege	regf */
    283	0x81,	0x21,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
    284/*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
    285	0x03,	0x00,	0x00,	0x01,	0x08,	0x28,	0x1e,	0x00,
    286/*	reg18	reg19	reg1a	reg1b */
    287	0x07,	0x00,	0x00,	0x00
    288};
    289
    290static const u8 sn_sp80708[0x1c] = {
    291/*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
    292	0x00,	0x63,	0x60,	0x00,	0x1a,	0x20,	0x20,	0x20,
    293/*	reg8	reg9	rega	regb	regc	regd	rege	regf */
    294	0x81,	0x18,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
    295/*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
    296	0x03,	0x00,	0x00,	0x03,	0x04,	0x28,	0x1e,	0x00,
    297/*	reg18	reg19	reg1a	reg1b */
    298	0x07,	0x00,	0x00,	0x00
    299};
    300
    301/* sequence specific to the sensors - !! index = SENSOR_xxx */
    302static const u8 *sn_tb[] = {
    303[SENSOR_ADCM1700] =	sn_adcm1700,
    304[SENSOR_GC0307] =	sn_gc0307,
    305[SENSOR_HV7131R] =	sn_hv7131,
    306[SENSOR_MI0360] =	sn_mi0360,
    307[SENSOR_MI0360B] =	sn_mi0360b,
    308[SENSOR_MO4000] =	sn_mo4000,
    309[SENSOR_MT9V111] =	sn_mt9v111,
    310[SENSOR_OM6802] =	sn_om6802,
    311[SENSOR_OV7630] =	sn_ov7630,
    312[SENSOR_OV7648] =	sn_ov7648,
    313[SENSOR_OV7660] =	sn_ov7660,
    314[SENSOR_PO1030] =	sn_po1030,
    315[SENSOR_PO2030N] =	sn_po2030n,
    316[SENSOR_SOI768] =	sn_soi768,
    317[SENSOR_SP80708] =	sn_sp80708,
    318};
    319
    320/* default gamma table */
    321static const u8 gamma_def[17] = {
    322	0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
    323	0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
    324};
    325/* gamma for sensor ADCM1700 */
    326static const u8 gamma_spec_0[17] = {
    327	0x0f, 0x39, 0x5a, 0x74, 0x86, 0x95, 0xa6, 0xb4,
    328	0xbd, 0xc4, 0xcc, 0xd4, 0xd5, 0xde, 0xe4, 0xed, 0xf5
    329};
    330/* gamma for sensors HV7131R and MT9V111 */
    331static const u8 gamma_spec_1[17] = {
    332	0x08, 0x3a, 0x52, 0x65, 0x75, 0x83, 0x91, 0x9d,
    333	0xa9, 0xb4, 0xbe, 0xc8, 0xd2, 0xdb, 0xe4, 0xed, 0xf5
    334};
    335/* gamma for sensor GC0307 */
    336static const u8 gamma_spec_2[17] = {
    337	0x14, 0x37, 0x50, 0x6a, 0x7c, 0x8d, 0x9d, 0xab,
    338	0xb5, 0xbf, 0xc2, 0xcb, 0xd1, 0xd6, 0xdb, 0xe1, 0xeb
    339};
    340/* gamma for sensor SP80708 */
    341static const u8 gamma_spec_3[17] = {
    342	0x0a, 0x2d, 0x4e, 0x68, 0x7d, 0x8f, 0x9f, 0xab,
    343	0xb7, 0xc2, 0xcc, 0xd3, 0xd8, 0xde, 0xe2, 0xe5, 0xe6
    344};
    345
    346/* color matrix and offsets */
    347static const u8 reg84[] = {
    348	0x14, 0x00, 0x27, 0x00, 0x07, 0x00,	/* YR YG YB gains */
    349	0xe8, 0x0f, 0xda, 0x0f, 0x40, 0x00,	/* UR UG UB */
    350	0x3e, 0x00, 0xcd, 0x0f, 0xf7, 0x0f,	/* VR VG VB */
    351	0x00, 0x00, 0x00			/* YUV offsets */
    352};
    353
    354#define DELAY	0xdd
    355
    356static const u8 adcm1700_sensor_init[][8] = {
    357	{0xa0, 0x51, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x10},
    358	{0xb0, 0x51, 0x04, 0x08, 0x00, 0x00, 0x00, 0x10},	/* reset */
    359	{DELAY, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
    360	{0xb0, 0x51, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
    361	{DELAY, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
    362	{0xb0, 0x51, 0x0c, 0xe0, 0x2e, 0x00, 0x00, 0x10},
    363	{0xb0, 0x51, 0x10, 0x02, 0x02, 0x00, 0x00, 0x10},
    364	{0xb0, 0x51, 0x14, 0x0e, 0x0e, 0x00, 0x00, 0x10},
    365	{0xb0, 0x51, 0x1c, 0x00, 0x80, 0x00, 0x00, 0x10},
    366	{0xb0, 0x51, 0x20, 0x01, 0x00, 0x00, 0x00, 0x10},
    367	{DELAY, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
    368	{0xb0, 0x51, 0x04, 0x04, 0x00, 0x00, 0x00, 0x10},
    369	{DELAY, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
    370	{0xb0, 0x51, 0x04, 0x01, 0x00, 0x00, 0x00, 0x10},
    371	{0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10},
    372	{0xb0, 0x51, 0x14, 0x01, 0x00, 0x00, 0x00, 0x10},
    373	{0xb0, 0x51, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
    374	{}
    375};
    376static const u8 adcm1700_sensor_param1[][8] = {
    377	{0xb0, 0x51, 0x26, 0xf9, 0x01, 0x00, 0x00, 0x10},	/* exposure? */
    378	{0xd0, 0x51, 0x1e, 0x8e, 0x8e, 0x8e, 0x8e, 0x10},
    379
    380	{0xa0, 0x51, 0xfe, 0x01, 0x00, 0x00, 0x00, 0x10},
    381	{0xb0, 0x51, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10},
    382	{0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10},
    383	{0xb0, 0x51, 0x32, 0x00, 0x72, 0x00, 0x00, 0x10},
    384	{0xd0, 0x51, 0x1e, 0xbe, 0xd7, 0xe8, 0xbe, 0x10},	/* exposure? */
    385
    386	{0xa0, 0x51, 0xfe, 0x01, 0x00, 0x00, 0x00, 0x10},
    387	{0xb0, 0x51, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10},
    388	{0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10},
    389	{0xb0, 0x51, 0x32, 0x00, 0xa2, 0x00, 0x00, 0x10},
    390	{}
    391};
    392static const u8 gc0307_sensor_init[][8] = {
    393	{0xa0, 0x21, 0x43, 0x00, 0x00, 0x00, 0x00, 0x10},
    394	{0xa0, 0x21, 0x44, 0xa2, 0x00, 0x00, 0x00, 0x10},
    395	{0xa0, 0x21, 0x01, 0x6a, 0x00, 0x00, 0x00, 0x10},
    396	{0xa0, 0x21, 0x02, 0x70, 0x00, 0x00, 0x00, 0x10},
    397	{0xa0, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
    398	{0xa0, 0x21, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10},
    399	{0xa0, 0x21, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x10},
    400	{0xa0, 0x21, 0x11, 0x05, 0x00, 0x00, 0x00, 0x10},
    401	{0xa0, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
    402	{0xa0, 0x21, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10},
    403	{0xa0, 0x21, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10},
    404	{0xa0, 0x21, 0x08, 0x02, 0x00, 0x00, 0x00, 0x10},
    405	{0xa0, 0x21, 0x09, 0x01, 0x00, 0x00, 0x00, 0x10},
    406	{0xa0, 0x21, 0x0a, 0xe8, 0x00, 0x00, 0x00, 0x10},
    407	{0xa0, 0x21, 0x0b, 0x02, 0x00, 0x00, 0x00, 0x10},
    408	{0xa0, 0x21, 0x0c, 0x80, 0x00, 0x00, 0x00, 0x10},
    409	{0xa0, 0x21, 0x0d, 0x22, 0x00, 0x00, 0x00, 0x10},
    410	{0xa0, 0x21, 0x0e, 0x02, 0x00, 0x00, 0x00, 0x10},
    411	{0xa0, 0x21, 0x0f, 0xb2, 0x00, 0x00, 0x00, 0x10},
    412	{0xa0, 0x21, 0x12, 0x70, 0x00, 0x00, 0x00, 0x10},
    413	{DELAY, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*delay 10ms*/
    414	{0xa0, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00, 0x10},
    415	{0xa0, 0x21, 0x15, 0xb8, 0x00, 0x00, 0x00, 0x10},
    416	{0xa0, 0x21, 0x16, 0x13, 0x00, 0x00, 0x00, 0x10},
    417	{0xa0, 0x21, 0x17, 0x52, 0x00, 0x00, 0x00, 0x10},
    418	{0xa0, 0x21, 0x18, 0x50, 0x00, 0x00, 0x00, 0x10},
    419	{0xa0, 0x21, 0x1e, 0x0d, 0x00, 0x00, 0x00, 0x10},
    420	{0xa0, 0x21, 0x1f, 0x32, 0x00, 0x00, 0x00, 0x10},
    421	{0xa0, 0x21, 0x61, 0x90, 0x00, 0x00, 0x00, 0x10},
    422	{0xa0, 0x21, 0x63, 0x70, 0x00, 0x00, 0x00, 0x10},
    423	{0xa0, 0x21, 0x65, 0x98, 0x00, 0x00, 0x00, 0x10},
    424	{0xa0, 0x21, 0x67, 0x90, 0x00, 0x00, 0x00, 0x10},
    425	{0xa0, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
    426	{0xa0, 0x21, 0x04, 0x96, 0x00, 0x00, 0x00, 0x10},
    427	{0xa0, 0x21, 0x45, 0x27, 0x00, 0x00, 0x00, 0x10},
    428	{0xa0, 0x21, 0x47, 0x2c, 0x00, 0x00, 0x00, 0x10},
    429	{0xa0, 0x21, 0x43, 0x47, 0x00, 0x00, 0x00, 0x10},
    430	{0xa0, 0x21, 0x44, 0xd8, 0x00, 0x00, 0x00, 0x10},
    431	{}
    432};
    433static const u8 gc0307_sensor_param1[][8] = {
    434	{0xa0, 0x21, 0x68, 0x13, 0x00, 0x00, 0x00, 0x10},
    435	{0xd0, 0x21, 0x61, 0x80, 0x00, 0x80, 0x00, 0x10},
    436	{0xc0, 0x21, 0x65, 0x80, 0x00, 0x80, 0x00, 0x10},
    437	{0xc0, 0x21, 0x63, 0xa0, 0x00, 0xa6, 0x00, 0x10},
    438/*param3*/
    439	{0xa0, 0x21, 0x01, 0x6e, 0x00, 0x00, 0x00, 0x10},
    440	{0xa0, 0x21, 0x02, 0x88, 0x00, 0x00, 0x00, 0x10},
    441	{}
    442};
    443
    444static const u8 hv7131r_sensor_init[][8] = {
    445	{0xc1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
    446	{0xb1, 0x11, 0x34, 0x17, 0x7f, 0x00, 0x00, 0x10},
    447	{0xd1, 0x11, 0x40, 0xff, 0x7f, 0x7f, 0x7f, 0x10},
    448/*	{0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10}, */
    449	{0xd1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
    450	{0xd1, 0x11, 0x14, 0x01, 0xe2, 0x02, 0x82, 0x10},
    451/*	{0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10}, */
    452
    453	{0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
    454	{0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
    455	{0xc1, 0x11, 0x25, 0x00, 0x61, 0xa8, 0x00, 0x10},
    456	{0xa1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10},
    457	{0xc1, 0x11, 0x31, 0x20, 0x2e, 0x20, 0x00, 0x10},
    458	{0xc1, 0x11, 0x25, 0x00, 0xc3, 0x50, 0x00, 0x10},
    459	{0xa1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */
    460	{0xc1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */
    461
    462	{0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
    463	{0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
    464	{0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10},
    465	{0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
    466	{0xa1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10},
    467
    468	{0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
    469	{0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
    470	{0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10},
    471	{0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
    472	{0xa1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10},
    473	{0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10},
    474							/* set sensor clock */
    475	{}
    476};
    477static const u8 mi0360_sensor_init[][8] = {
    478	{0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
    479	{0xb1, 0x5d, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10},
    480	{0xb1, 0x5d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
    481	{0xd1, 0x5d, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
    482	{0xd1, 0x5d, 0x03, 0x01, 0xe2, 0x02, 0x82, 0x10},
    483	{0xd1, 0x5d, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10},
    484	{0xb1, 0x5d, 0x0d, 0x00, 0x02, 0x00, 0x00, 0x10},
    485	{0xd1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
    486	{0xd1, 0x5d, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10},
    487	{0xd1, 0x5d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
    488	{0xd1, 0x5d, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
    489	{0xd1, 0x5d, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
    490	{0xd1, 0x5d, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
    491	{0xd1, 0x5d, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
    492	{0xd1, 0x5d, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
    493	{0xd1, 0x5d, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x10},
    494	{0xd1, 0x5d, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10},
    495	{0xb1, 0x5d, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
    496	{0xd1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
    497	{0xd1, 0x5d, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
    498	{0xd1, 0x5d, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
    499	{0xd1, 0x5d, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
    500	{0xd1, 0x5d, 0x2f, 0xf7, 0xb0, 0x00, 0x04, 0x10},
    501	{0xd1, 0x5d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
    502	{0xd1, 0x5d, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
    503	{0xb1, 0x5d, 0x3d, 0x06, 0x8f, 0x00, 0x00, 0x10},
    504	{0xd1, 0x5d, 0x40, 0x01, 0xe0, 0x00, 0xd1, 0x10},
    505	{0xb1, 0x5d, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
    506	{0xd1, 0x5d, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
    507	{0xd1, 0x5d, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x10},
    508	{0xd1, 0x5d, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x10},
    509	{0xd1, 0x5d, 0x5e, 0x00, 0x00, 0xa3, 0x1d, 0x10},
    510	{0xb1, 0x5d, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
    511
    512	{0xb1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
    513	{0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
    514	{0xb1, 0x5d, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
    515	{0xd1, 0x5d, 0x2b, 0x00, 0xa0, 0x00, 0xb0, 0x10},
    516	{0xd1, 0x5d, 0x2d, 0x00, 0xa0, 0x00, 0xa0, 0x10},
    517
    518	{0xb1, 0x5d, 0x0a, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */
    519	{0xb1, 0x5d, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10},
    520	{0xb1, 0x5d, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10},
    521	{0xb1, 0x5d, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
    522
    523	{0xd1, 0x5d, 0x2b, 0x00, 0xb9, 0x00, 0xe3, 0x10},
    524	{0xd1, 0x5d, 0x2d, 0x00, 0x5f, 0x00, 0xb9, 0x10}, /* 42 */
    525/*	{0xb1, 0x5d, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */
    526/*	{0xb1, 0x5d, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */
    527	{0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
    528	{0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
    529	{}
    530};
    531static const u8 mi0360b_sensor_init[][8] = {
    532	{0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
    533	{0xb1, 0x5d, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10},
    534	{DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*delay 20ms*/
    535	{0xb1, 0x5d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
    536	{DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*delay 20ms*/
    537	{0xd1, 0x5d, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
    538	{0xd1, 0x5d, 0x03, 0x01, 0xe2, 0x02, 0x82, 0x10},
    539	{0xd1, 0x5d, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
    540	{0xb1, 0x5d, 0x0d, 0x00, 0x02, 0x00, 0x00, 0x10},
    541	{0xd1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
    542	{0xd1, 0x5d, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10},
    543	{0xd1, 0x5d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
    544	{0xd1, 0x5d, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
    545	{0xd1, 0x5d, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
    546	{0xd1, 0x5d, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
    547	{0xd1, 0x5d, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
    548	{0xd1, 0x5d, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
    549	{0xd1, 0x5d, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x10},
    550	{0xd1, 0x5d, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10},
    551	{0xb1, 0x5d, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
    552	{0xd1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
    553	{0xd1, 0x5d, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
    554	{0xd1, 0x5d, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
    555	{0xd1, 0x5d, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
    556	{0xd1, 0x5d, 0x2f, 0xf7, 0xb0, 0x00, 0x04, 0x10},
    557	{0xd1, 0x5d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
    558	{0xd1, 0x5d, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
    559	{0xb1, 0x5d, 0x3d, 0x06, 0x8f, 0x00, 0x00, 0x10},
    560	{0xd1, 0x5d, 0x40, 0x01, 0xe0, 0x00, 0xd1, 0x10},
    561	{0xb1, 0x5d, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
    562	{0xd1, 0x5d, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
    563	{0xd1, 0x5d, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x10},
    564	{0xd1, 0x5d, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x10},
    565	{0xd1, 0x5d, 0x5e, 0x00, 0x00, 0xa3, 0x1d, 0x10},
    566	{0xb1, 0x5d, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
    567
    568	{0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
    569	{0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
    570	{0xb1, 0x5d, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
    571	{0xd1, 0x5d, 0x2b, 0x00, 0x33, 0x00, 0xa0, 0x10},
    572	{0xd1, 0x5d, 0x2d, 0x00, 0xa0, 0x00, 0x33, 0x10},
    573	{}
    574};
    575static const u8 mi0360b_sensor_param1[][8] = {
    576	{0xb1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
    577	{0xb1, 0x5d, 0x06, 0x00, 0x53, 0x00, 0x00, 0x10},
    578	{0xb1, 0x5d, 0x05, 0x00, 0x09, 0x00, 0x00, 0x10},
    579	{0xb1, 0x5d, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
    580
    581	{0xd1, 0x5d, 0x2b, 0x00, 0xd1, 0x01, 0xc9, 0x10},
    582	{0xd1, 0x5d, 0x2d, 0x00, 0xed, 0x00, 0xd1, 0x10},
    583	{0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
    584	{0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
    585	{}
    586};
    587static const u8 mo4000_sensor_init[][8] = {
    588	{0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10},
    589	{0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10},
    590	{0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
    591	{0xa1, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
    592	{0xa1, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
    593	{0xa1, 0x21, 0x05, 0x04, 0x00, 0x00, 0x00, 0x10},
    594	{0xa1, 0x21, 0x06, 0x80, 0x00, 0x00, 0x00, 0x10},
    595	{0xa1, 0x21, 0x06, 0x81, 0x00, 0x00, 0x00, 0x10},
    596	{0xa1, 0x21, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
    597	{0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
    598	{0xa1, 0x21, 0x11, 0x20, 0x00, 0x00, 0x00, 0x10},
    599	{0xa1, 0x21, 0x11, 0x30, 0x00, 0x00, 0x00, 0x10},
    600	{0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
    601	{0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
    602	{0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
    603	{0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
    604	{0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10},
    605	{0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10},
    606	{0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
    607	{0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
    608	{}
    609};
    610static const u8 mt9v111_sensor_init[][8] = {
    611	{0xb1, 0x5c, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10}, /* reset? */
    612	{DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
    613	{0xb1, 0x5c, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
    614	{0xb1, 0x5c, 0x01, 0x00, 0x01, 0x00, 0x00, 0x10}, /* IFP select */
    615	{0xb1, 0x5c, 0x08, 0x04, 0x80, 0x00, 0x00, 0x10}, /* output fmt ctrl */
    616	{0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10}, /* op mode ctrl */
    617	{0xb1, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10}, /* sensor select */
    618	{0xb1, 0x5c, 0x08, 0x00, 0x08, 0x00, 0x00, 0x10}, /* row start */
    619	{0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10}, /* col start */
    620	{0xb1, 0x5c, 0x03, 0x01, 0xe7, 0x00, 0x00, 0x10}, /* window height */
    621	{0xb1, 0x5c, 0x04, 0x02, 0x87, 0x00, 0x00, 0x10}, /* window width */
    622	{0xb1, 0x5c, 0x07, 0x30, 0x02, 0x00, 0x00, 0x10}, /* output ctrl */
    623	{0xb1, 0x5c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10}, /* shutter delay */
    624	{0xb1, 0x5c, 0x12, 0x00, 0xb0, 0x00, 0x00, 0x10}, /* zoom col start */
    625	{0xb1, 0x5c, 0x13, 0x00, 0x7c, 0x00, 0x00, 0x10}, /* zoom row start */
    626	{0xb1, 0x5c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* digital zoom */
    627	{0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, /* read mode */
    628	{0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
    629	{}
    630};
    631static const u8 mt9v111_sensor_param1[][8] = {
    632	{0xd1, 0x5c, 0x2b, 0x00, 0x33, 0x00, 0xad, 0x10}, /* G1 and B gains */
    633	{0xd1, 0x5c, 0x2d, 0x00, 0xad, 0x00, 0x33, 0x10}, /* R and G2 gains */
    634	{0xb1, 0x5c, 0x06, 0x00, 0x40, 0x00, 0x00, 0x10}, /* vert blanking */
    635	{0xb1, 0x5c, 0x05, 0x00, 0x09, 0x00, 0x00, 0x10}, /* horiz blanking */
    636	{0xb1, 0x5c, 0x35, 0x01, 0xc0, 0x00, 0x00, 0x10}, /* global gain */
    637	{}
    638};
    639static const u8 om6802_init0[2][8] = {
    640/*fixme: variable*/
    641	{0xa0, 0x34, 0x29, 0x0e, 0x00, 0x00, 0x00, 0x10},
    642	{0xa0, 0x34, 0x23, 0xb0, 0x00, 0x00, 0x00, 0x10},
    643};
    644static const u8 om6802_sensor_init[][8] = {
    645	{0xa0, 0x34, 0xdf, 0x6d, 0x00, 0x00, 0x00, 0x10},
    646						/* factory mode */
    647	{0xa0, 0x34, 0xdd, 0x18, 0x00, 0x00, 0x00, 0x10},
    648						/* output raw RGB */
    649	{0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10},
    650/*	{0xa0, 0x34, 0xfb, 0x11, 0x00, 0x00, 0x00, 0x10}, */
    651	{0xa0, 0x34, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x10},
    652		/* auto-exposure speed (0) / white balance mode (auto RGB) */
    653/*	{0xa0, 0x34, 0xf1, 0x02, 0x00, 0x00, 0x00, 0x10},
    654							 * set color mode */
    655/*	{0xa0, 0x34, 0xfe, 0x5b, 0x00, 0x00, 0x00, 0x10},
    656						 * max AGC value in AE */
    657/*	{0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10},
    658							 * preset AGC */
    659/*	{0xa0, 0x34, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x10},
    660						 * preset brightness */
    661/*	{0xa0, 0x34, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x10},
    662							 * preset contrast */
    663/*	{0xa0, 0x34, 0xe8, 0x31, 0x00, 0x00, 0x00, 0x10},
    664							 * preset gamma */
    665	{0xa0, 0x34, 0xe9, 0x0f, 0x00, 0x00, 0x00, 0x10},
    666				/* luminance mode (0x4f -> AutoExpo on) */
    667	{0xa0, 0x34, 0xe4, 0xff, 0x00, 0x00, 0x00, 0x10},
    668							/* preset shutter */
    669/*	{0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10},
    670							 * auto frame rate */
    671/*	{0xa0, 0x34, 0xfb, 0xee, 0x00, 0x00, 0x00, 0x10}, */
    672	{0xa0, 0x34, 0x5d, 0x80, 0x00, 0x00, 0x00, 0x10},
    673	{}
    674};
    675static const u8 om6802_sensor_param1[][8] = {
    676	{0xa0, 0x34, 0x71, 0x84, 0x00, 0x00, 0x00, 0x10},
    677	{0xa0, 0x34, 0x72, 0x05, 0x00, 0x00, 0x00, 0x10},
    678	{0xa0, 0x34, 0x68, 0x80, 0x00, 0x00, 0x00, 0x10},
    679	{0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10},
    680	{}
    681};
    682static const u8 ov7630_sensor_init[][8] = {
    683	{0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10},
    684	{0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
    685	{DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
    686	{0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
    687	{0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
    688	{DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
    689	{0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
    690/* win: i2c_r from 00 to 80 */
    691	{0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10},
    692	{0xb1, 0x21, 0x0c, 0x20, 0x20, 0x00, 0x00, 0x10},
    693/* HDG: 0x11 was 0x00 change to 0x01 for better exposure (15 fps instead of 30)
    694	0x13 was 0xc0 change to 0xc3 for auto gain and exposure */
    695	{0xd1, 0x21, 0x11, 0x01, 0x48, 0xc3, 0x00, 0x10},
    696	{0xb1, 0x21, 0x15, 0x80, 0x03, 0x00, 0x00, 0x10},
    697	{0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
    698	{0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
    699	{0xd1, 0x21, 0x1f, 0x00, 0x80, 0x80, 0x80, 0x10},
    700	{0xd1, 0x21, 0x23, 0xde, 0x10, 0x8a, 0xa0, 0x10},
    701	{0xc1, 0x21, 0x27, 0xca, 0xa2, 0x74, 0x00, 0x10},
    702	{0xd1, 0x21, 0x2a, 0x88, 0x00, 0x88, 0x01, 0x10},
    703	{0xc1, 0x21, 0x2e, 0x80, 0x00, 0x18, 0x00, 0x10},
    704	{0xa1, 0x21, 0x21, 0x08, 0x00, 0x00, 0x00, 0x10},
    705	{0xa1, 0x21, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
    706	{0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
    707	{0xb1, 0x21, 0x32, 0xc2, 0x08, 0x00, 0x00, 0x10},
    708	{0xb1, 0x21, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x10},
    709	{0xd1, 0x21, 0x60, 0x05, 0x40, 0x12, 0x57, 0x10},
    710	{0xa1, 0x21, 0x64, 0x73, 0x00, 0x00, 0x00, 0x10},
    711	{0xd1, 0x21, 0x65, 0x00, 0x55, 0x01, 0xac, 0x10},
    712	{0xa1, 0x21, 0x69, 0x38, 0x00, 0x00, 0x00, 0x10},
    713	{0xd1, 0x21, 0x6f, 0x1f, 0x01, 0x00, 0x10, 0x10},
    714	{0xd1, 0x21, 0x73, 0x50, 0x20, 0x02, 0x01, 0x10},
    715	{0xd1, 0x21, 0x77, 0xf3, 0x90, 0x98, 0x98, 0x10},
    716	{0xc1, 0x21, 0x7b, 0x00, 0x4c, 0xf7, 0x00, 0x10},
    717	{0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
    718	{0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
    719	{}
    720};
    721static const u8 ov7630_sensor_param1[][8] = {
    722	{0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
    723	{0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
    724/*fixme: + 0x12, 0x04*/
    725/*	{0xa1, 0x21, 0x75, 0x82, 0x00, 0x00, 0x00, 0x10},  * COMN
    726							 * set by setvflip */
    727	{0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
    728	{0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
    729	{0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10},
    730/* */
    731/*	{0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10}, * set by setfreq */
    732/*	{0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10}, * set by setfreq */
    733/* */
    734	{0xa1, 0x21, 0x10, 0x83, 0x00, 0x00, 0x00, 0x10},
    735/*	{0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, */
    736	{}
    737};
    738
    739static const u8 ov7648_sensor_init[][8] = {
    740	{0xa1, 0x21, 0x76, 0x00, 0x00, 0x00, 0x00, 0x10},
    741	{0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},	/* reset */
    742	{DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
    743	{0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
    744	{0xd1, 0x21, 0x03, 0xa4, 0x30, 0x88, 0x00, 0x10},
    745	{0xb1, 0x21, 0x11, 0x80, 0x08, 0x00, 0x00, 0x10},
    746	{0xc1, 0x21, 0x13, 0xa0, 0x04, 0x84, 0x00, 0x10},
    747	{0xd1, 0x21, 0x17, 0x1a, 0x02, 0xba, 0xf4, 0x10},
    748	{0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
    749	{0xd1, 0x21, 0x1f, 0x41, 0xc0, 0x80, 0x80, 0x10},
    750	{0xd1, 0x21, 0x23, 0xde, 0xa0, 0x80, 0x32, 0x10},
    751	{0xd1, 0x21, 0x27, 0xfe, 0xa0, 0x00, 0x91, 0x10},
    752	{0xd1, 0x21, 0x2b, 0x00, 0x88, 0x85, 0x80, 0x10},
    753	{0xc1, 0x21, 0x2f, 0x9c, 0x00, 0xc4, 0x00, 0x10},
    754	{0xd1, 0x21, 0x60, 0xa6, 0x60, 0x88, 0x12, 0x10},
    755	{0xd1, 0x21, 0x64, 0x88, 0x00, 0x00, 0x94, 0x10},
    756	{0xd1, 0x21, 0x68, 0x7a, 0x0c, 0x00, 0x00, 0x10},
    757	{0xd1, 0x21, 0x6c, 0x11, 0x33, 0x22, 0x00, 0x10},
    758	{0xd1, 0x21, 0x70, 0x11, 0x00, 0x10, 0x50, 0x10},
    759	{0xd1, 0x21, 0x74, 0x20, 0x06, 0x00, 0xb5, 0x10},
    760	{0xd1, 0x21, 0x78, 0x8a, 0x00, 0x00, 0x00, 0x10},
    761	{0xb1, 0x21, 0x7c, 0x00, 0x43, 0x00, 0x00, 0x10},
    762
    763	{0xd1, 0x21, 0x21, 0x86, 0x00, 0xde, 0xa0, 0x10},
    764/*	{0xd1, 0x21, 0x25, 0x80, 0x32, 0xfe, 0xa0, 0x10}, jfm done */
    765/*	{0xd1, 0x21, 0x29, 0x00, 0x91, 0x00, 0x88, 0x10}, jfm done */
    766/*	{0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10}, set by setfreq */
    767	{}
    768};
    769static const u8 ov7648_sensor_param1[][8] = {
    770/*	{0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */
    771/*	{0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10},   * COMN
    772							 * set by setvflip */
    773	{0xa1, 0x21, 0x19, 0x02, 0x00, 0x00, 0x00, 0x10},
    774	{0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
    775/*	{0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
    776/*	{0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},  * GAIN - def */
    777/*	{0xb1, 0x21, 0x01, 0x6c, 0x6c, 0x00, 0x00, 0x10},  * B R - def: 80 */
    778/*...*/
    779	{0xa1, 0x21, 0x11, 0x81, 0x00, 0x00, 0x00, 0x10}, /* CLKRC */
    780/*	{0xa1, 0x21, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
    781/*	{0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
    782/*	{0xa1, 0x21, 0x2a, 0x91, 0x00, 0x00, 0x00, 0x10}, jfm done */
    783/*	{0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
    784/*	{0xb1, 0x21, 0x01, 0x64, 0x84, 0x00, 0x00, 0x10},  * B R - def: 80 */
    785
    786	{}
    787};
    788
    789static const u8 ov7660_sensor_init[][8] = {
    790	{0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
    791	{DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
    792	{0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
    793						/* Outformat = rawRGB */
    794	{0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
    795	{0xd1, 0x21, 0x00, 0x01, 0x74, 0x92, 0x00, 0x10},
    796						/* GAIN BLUE RED VREF */
    797	{0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10},
    798						/* COM 1 BAVE GEAVE AECHH */
    799	{0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */
    800	{0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */
    801	{0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10},
    802						/* AECH CLKRC COM7 COM8 */
    803	{0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */
    804	{0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10},
    805						/* HSTART HSTOP VSTRT VSTOP */
    806	{0xa1, 0x21, 0x1b, 0x02, 0x00, 0x00, 0x00, 0x10}, /* PSHFT */
    807	{0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */
    808	{0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10},
    809					/* BOS GBOS GROS ROS (BGGR offset) */
    810/*	{0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, */
    811	{0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10},
    812						/* AEW AEB VPT BBIAS */
    813	{0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10},
    814						/* GbBIAS RSVD EXHCH EXHCL */
    815	{0xd1, 0x21, 0x2c, 0x80, 0x00, 0x00, 0x62, 0x10},
    816						/* RBIAS ADVFL ASDVFH YAVE */
    817	{0xc1, 0x21, 0x30, 0x08, 0x30, 0xb4, 0x00, 0x10},
    818						/* HSYST HSYEN HREF */
    819	{0xd1, 0x21, 0x33, 0x00, 0x07, 0x84, 0x00, 0x10}, /* reserved */
    820	{0xd1, 0x21, 0x37, 0x0c, 0x02, 0x43, 0x00, 0x10},
    821						/* ADC ACOM OFON TSLB */
    822	{0xd1, 0x21, 0x3b, 0x02, 0x6c, 0x19, 0x0e, 0x10},
    823						/* COM11 COM12 COM13 COM14 */
    824	{0xd1, 0x21, 0x3f, 0x41, 0xc1, 0x22, 0x08, 0x10},
    825						/* EDGE COM15 COM16 COM17 */
    826	{0xd1, 0x21, 0x43, 0xf0, 0x10, 0x78, 0xa8, 0x10}, /* reserved */
    827	{0xd1, 0x21, 0x47, 0x60, 0x80, 0x00, 0x00, 0x10}, /* reserved */
    828	{0xd1, 0x21, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* reserved */
    829	{0xd1, 0x21, 0x4f, 0x46, 0x36, 0x0f, 0x17, 0x10}, /* MTX 1 2 3 4 */
    830	{0xd1, 0x21, 0x53, 0x7f, 0x96, 0x40, 0x40, 0x10}, /* MTX 5 6 7 8 */
    831	{0xb1, 0x21, 0x57, 0x40, 0x0f, 0x00, 0x00, 0x10}, /* MTX9 MTXS */
    832	{0xd1, 0x21, 0x59, 0xba, 0x9a, 0x22, 0xb9, 0x10}, /* reserved */
    833	{0xd1, 0x21, 0x5d, 0x9b, 0x10, 0xf0, 0x05, 0x10}, /* reserved */
    834	{0xa1, 0x21, 0x61, 0x60, 0x00, 0x00, 0x00, 0x10}, /* reserved */
    835	{0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10},
    836						/* LCC1 LCC2 LCC3 LCC4 */
    837	{0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */
    838	{0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, /* MANU */
    839	{0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10},
    840					/* band gap reference [0:3] DBLV */
    841	{0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */
    842	{0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */
    843	{0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */
    844	{0xd1, 0x21, 0x78, 0x34, 0x30, 0x2f, 0x2b, 0x10}, /* gamma curve */
    845	{0xd1, 0x21, 0x7c, 0x03, 0x07, 0x17, 0x34, 0x10}, /* gamma curve */
    846	{0xd1, 0x21, 0x80, 0x41, 0x4d, 0x58, 0x63, 0x10}, /* gamma curve */
    847	{0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */
    848	{0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
    849	{0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
    850	{0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
    851/* not in all ms-win traces*/
    852	{0xa1, 0x21, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x10},
    853	{}
    854};
    855static const u8 ov7660_sensor_param1[][8] = {
    856	{0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
    857						/* bits[3..0]reserved */
    858	{0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
    859	{0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
    860						/* VREF vertical frame ctrl */
    861	{0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
    862	{0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* AECH 0x20 */
    863	{0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFL */
    864	{0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFH */
    865	{0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */
    866/*	{0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */
    867/****** (some exchanges in the win trace) ******/
    868/*fixme:param2*/
    869	{0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */
    870	{0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */
    871	{0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */
    872	{0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCL */
    873/*	{0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10},  * RED */
    874/****** (some exchanges in the win trace) ******/
    875/******!! startsensor KO if changed !!****/
    876/*fixme: param3*/
    877	{0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10},
    878	{0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10},
    879	{0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
    880	{0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10},
    881	{}
    882};
    883
    884static const u8 po1030_sensor_init[][8] = {
    885/* the sensor registers are described in m5602/m5602_po1030.h */
    886	{0xa1, 0x6e, 0x3f, 0x20, 0x00, 0x00, 0x00, 0x10}, /* sensor reset */
    887	{DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
    888	{0xa1, 0x6e, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x10},
    889	{0xa1, 0x6e, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x10},
    890	{0xd1, 0x6e, 0x04, 0x02, 0xb1, 0x02, 0x39, 0x10},
    891	{0xd1, 0x6e, 0x08, 0x00, 0x01, 0x00, 0x00, 0x10},
    892	{0xd1, 0x6e, 0x0c, 0x02, 0x7f, 0x01, 0xe0, 0x10},
    893	{0xd1, 0x6e, 0x12, 0x03, 0x02, 0x00, 0x03, 0x10},
    894	{0xd1, 0x6e, 0x16, 0x85, 0x40, 0x4a, 0x40, 0x10}, /* r/g1/b/g2 gains */
    895	{0xc1, 0x6e, 0x1a, 0x00, 0x80, 0x00, 0x00, 0x10},
    896	{0xd1, 0x6e, 0x1d, 0x08, 0x03, 0x00, 0x00, 0x10},
    897	{0xd1, 0x6e, 0x23, 0x00, 0xb0, 0x00, 0x94, 0x10},
    898	{0xd1, 0x6e, 0x27, 0x58, 0x00, 0x00, 0x00, 0x10},
    899	{0xb1, 0x6e, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10},
    900	{0xd1, 0x6e, 0x2d, 0x14, 0x35, 0x61, 0x84, 0x10}, /* gamma corr */
    901	{0xd1, 0x6e, 0x31, 0xa2, 0xbd, 0xd8, 0xff, 0x10},
    902	{0xd1, 0x6e, 0x35, 0x06, 0x1e, 0x12, 0x02, 0x10}, /* color matrix */
    903	{0xd1, 0x6e, 0x39, 0xaa, 0x53, 0x37, 0xd5, 0x10},
    904	{0xa1, 0x6e, 0x3d, 0xf2, 0x00, 0x00, 0x00, 0x10},
    905	{0xd1, 0x6e, 0x3e, 0x00, 0x00, 0x80, 0x03, 0x10},
    906	{0xd1, 0x6e, 0x42, 0x03, 0x00, 0x00, 0x00, 0x10},
    907	{0xc1, 0x6e, 0x46, 0x00, 0x80, 0x80, 0x00, 0x10},
    908	{0xd1, 0x6e, 0x4b, 0x02, 0xef, 0x08, 0xcd, 0x10},
    909	{0xd1, 0x6e, 0x4f, 0x00, 0xd0, 0x00, 0xa0, 0x10},
    910	{0xd1, 0x6e, 0x53, 0x01, 0xaa, 0x01, 0x40, 0x10},
    911	{0xd1, 0x6e, 0x5a, 0x50, 0x04, 0x30, 0x03, 0x10}, /* raw rgb bayer */
    912	{0xa1, 0x6e, 0x5e, 0x00, 0x00, 0x00, 0x00, 0x10},
    913	{0xd1, 0x6e, 0x5f, 0x10, 0x40, 0xff, 0x00, 0x10},
    914
    915	{0xd1, 0x6e, 0x63, 0x40, 0x40, 0x00, 0x00, 0x10},
    916	{0xd1, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x00, 0x10},
    917	{0xd1, 0x6e, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x10},
    918	{0xd1, 0x6e, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x10},
    919	{0xc1, 0x6e, 0x73, 0x10, 0x80, 0xeb, 0x00, 0x10},
    920	{}
    921};
    922static const u8 po1030_sensor_param1[][8] = {
    923/* from ms-win traces - these values change with auto gain/expo/wb.. */
    924	{0xa1, 0x6e, 0x1e, 0x03, 0x00, 0x00, 0x00, 0x10},
    925	{0xa1, 0x6e, 0x1e, 0x03, 0x00, 0x00, 0x00, 0x10},
    926/* mean values */
    927	{0xc1, 0x6e, 0x1a, 0x02, 0xd4, 0xa4, 0x00, 0x10}, /* integlines */
    928	{0xa1, 0x6e, 0x15, 0x04, 0x00, 0x00, 0x00, 0x10}, /* global gain */
    929	{0xc1, 0x6e, 0x16, 0x40, 0x40, 0x40, 0x00, 0x10}, /* r/g1/b gains */
    930
    931	{0xa1, 0x6e, 0x1d, 0x08, 0x00, 0x00, 0x00, 0x10}, /* control1 */
    932	{0xa1, 0x6e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10}, /* frameheight */
    933	{0xa1, 0x6e, 0x07, 0xd5, 0x00, 0x00, 0x00, 0x10},
    934/*	{0xc1, 0x6e, 0x16, 0x49, 0x40, 0x45, 0x00, 0x10}, */
    935	{}
    936};
    937
    938static const u8 po2030n_sensor_init[][8] = {
    939	{0xa1, 0x6e, 0x1e, 0x1a, 0x00, 0x00, 0x00, 0x10},
    940	{0xa1, 0x6e, 0x1f, 0x99, 0x00, 0x00, 0x00, 0x10},
    941	{DELAY, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 10ms */
    942	{0xa1, 0x6e, 0x1e, 0x0a, 0x00, 0x00, 0x00, 0x10},
    943	{0xa1, 0x6e, 0x1f, 0x19, 0x00, 0x00, 0x00, 0x10},
    944	{DELAY, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 10ms */
    945	{0xa1, 0x6e, 0x20, 0x44, 0x00, 0x00, 0x00, 0x10},
    946	{0xa1, 0x6e, 0x04, 0x03, 0x00, 0x00, 0x00, 0x10},
    947	{0xa1, 0x6e, 0x05, 0x70, 0x00, 0x00, 0x00, 0x10},
    948	{0xa1, 0x6e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10},
    949	{0xa1, 0x6e, 0x07, 0x25, 0x00, 0x00, 0x00, 0x10},
    950	{0xd1, 0x6e, 0x08, 0x00, 0xd0, 0x00, 0x08, 0x10},
    951	{0xd1, 0x6e, 0x0c, 0x03, 0x50, 0x01, 0xe8, 0x10},
    952	{0xd1, 0x6e, 0x1d, 0x20, 0x0a, 0x19, 0x44, 0x10},
    953	{0xd1, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x00, 0x10},
    954	{0xd1, 0x6e, 0x25, 0x00, 0x00, 0x00, 0x00, 0x10},
    955	{0xd1, 0x6e, 0x29, 0x00, 0x00, 0x00, 0x00, 0x10},
    956	{0xd1, 0x6e, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10},
    957	{0xd1, 0x6e, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
    958	{0xd1, 0x6e, 0x35, 0x00, 0x00, 0x00, 0x00, 0x10},
    959	{0xd1, 0x6e, 0x39, 0x00, 0x00, 0x00, 0x00, 0x10},
    960	{0xd1, 0x6e, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x10},
    961	{0xd1, 0x6e, 0x41, 0x00, 0x00, 0x00, 0x00, 0x10},
    962	{0xd1, 0x6e, 0x45, 0x00, 0x00, 0x00, 0x00, 0x10},
    963	{0xd1, 0x6e, 0x49, 0x00, 0x00, 0x00, 0x00, 0x10},
    964	{0xd1, 0x6e, 0x4d, 0x00, 0x00, 0x00, 0xed, 0x10},
    965	{0xd1, 0x6e, 0x51, 0x17, 0x4a, 0x2f, 0xc0, 0x10},
    966	{0xd1, 0x6e, 0x55, 0x00, 0x00, 0x00, 0x00, 0x10},
    967	{0xd1, 0x6e, 0x59, 0x00, 0x00, 0x00, 0x00, 0x10},
    968	{0xd1, 0x6e, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x10},
    969	{0xd1, 0x6e, 0x61, 0x00, 0x00, 0x00, 0x00, 0x10},
    970	{0xd1, 0x6e, 0x65, 0x00, 0x00, 0x00, 0x00, 0x10},
    971	{0xd1, 0x6e, 0x69, 0x00, 0x00, 0x00, 0x00, 0x10},
    972	{0xd1, 0x6e, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x10},
    973	{0xd1, 0x6e, 0x71, 0x00, 0x00, 0x00, 0x00, 0x10},
    974	{0xd1, 0x6e, 0x75, 0x00, 0x00, 0x00, 0x00, 0x10},
    975	{0xd1, 0x6e, 0x79, 0x00, 0x00, 0x00, 0x00, 0x10},
    976	{0xd1, 0x6e, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x10},
    977	{0xd1, 0x6e, 0x81, 0x00, 0x00, 0x00, 0x00, 0x10},
    978	{0xd1, 0x6e, 0x85, 0x00, 0x00, 0x00, 0x08, 0x10},
    979	{0xd1, 0x6e, 0x89, 0x01, 0xe8, 0x00, 0x01, 0x10},
    980	{0xa1, 0x6e, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x10},
    981	{0xd1, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x00, 0x10},
    982	{0xd1, 0x6e, 0x25, 0x00, 0x00, 0x00, 0x01, 0x10},
    983	{0xd1, 0x6e, 0x29, 0xe6, 0x00, 0xbd, 0x03, 0x10},
    984	{0xd1, 0x6e, 0x2d, 0x41, 0x38, 0x68, 0x40, 0x10},
    985	{0xd1, 0x6e, 0x31, 0x2b, 0x00, 0x36, 0x00, 0x10},
    986	{0xd1, 0x6e, 0x35, 0x30, 0x30, 0x08, 0x00, 0x10},
    987	{0xd1, 0x6e, 0x39, 0x00, 0x00, 0x33, 0x06, 0x10},
    988	{0xb1, 0x6e, 0x3d, 0x06, 0x02, 0x00, 0x00, 0x10},
    989	{}
    990};
    991static const u8 po2030n_sensor_param1[][8] = {
    992	{0xa1, 0x6e, 0x1a, 0x01, 0x00, 0x00, 0x00, 0x10},
    993	{DELAY, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 8ms */
    994	{0xa1, 0x6e, 0x1b, 0xf4, 0x00, 0x00, 0x00, 0x10},
    995	{0xa1, 0x6e, 0x15, 0x04, 0x00, 0x00, 0x00, 0x10},
    996	{0xd1, 0x6e, 0x16, 0x40, 0x40, 0x40, 0x40, 0x10}, /* RGBG gains */
    997/*param2*/
    998	{0xa1, 0x6e, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x10},
    999	{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
   1006static 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};
   1015static 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
   1037static 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};
   1111static 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
   1122static 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 */
   1141static 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
   1173static 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}
   1196static 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 */
   1228static 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 */
   1269static 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 */
   1294static 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
   1325static 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 */
   1339static 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
   1357static 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
   1413static 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
   1439static 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 */
   1476static 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 */
   1515static 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 */
   1544static 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
   1610static int sd_s_ctrl(struct v4l2_ctrl *ctrl);
   1611
   1612static const struct v4l2_ctrl_ops sd_ctrl_ops = {
   1613	.s_ctrl = sd_s_ctrl,
   1614};
   1615
   1616/* this function is called at probe time */
   1617static 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
   1693static 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
   1797static 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
   1844static 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
   1861static 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
   1889static 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
   1908static 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
   1946static 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
   1963static 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
   1988static 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
   2001static 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
   2044static 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
   2051static 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
   2070static 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
   2125static 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. */
   2156static 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 -- */
   2170static 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
   2485static 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 */
   2560static 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
   2569static 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 */
   2639static 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. */
   2663static 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 */
   2738marker_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
   2805static 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)
   2855static 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 */
   2874static 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)
   2897static 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};
   2959MODULE_DEVICE_TABLE(usb, device_table);
   2960
   2961/* -- device connect -- */
   2962static 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
   2969static 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
   2981module_usb_driver(sd_driver);