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

sn9c20x.c (71484B)


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