xref: /linux/drivers/media/usb/gspca/xirlink_cit.c (revision 37d5efb01910752d8d3846a2c4db0528c1dfa137)
11f33de0fSHans de Goede /*
21f33de0fSHans de Goede  * USB IBM C-It Video Camera driver
31f33de0fSHans de Goede  *
41f33de0fSHans de Goede  * Supports Xirlink C-It Video Camera, IBM PC Camera,
51f33de0fSHans de Goede  * IBM NetCamera and Veo Stingray.
61f33de0fSHans de Goede  *
71fddcf0eSHans de Goede  * Copyright (C) 2010 Hans de Goede <hdegoede@redhat.com>
81f33de0fSHans de Goede  *
91f33de0fSHans de Goede  * This driver is based on earlier work of:
101f33de0fSHans de Goede  *
111f33de0fSHans de Goede  * (C) Copyright 1999 Johannes Erdfelt
121f33de0fSHans de Goede  * (C) Copyright 1999 Randy Dunlap
131f33de0fSHans de Goede  *
141f33de0fSHans de Goede  * This program is free software; you can redistribute it and/or modify
151f33de0fSHans de Goede  * it under the terms of the GNU General Public License as published by
161f33de0fSHans de Goede  * the Free Software Foundation; either version 2 of the License, or
171f33de0fSHans de Goede  * (at your option) any later version.
181f33de0fSHans de Goede  *
191f33de0fSHans de Goede  * This program is distributed in the hope that it will be useful,
201f33de0fSHans de Goede  * but WITHOUT ANY WARRANTY; without even the implied warranty of
211f33de0fSHans de Goede  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
221f33de0fSHans de Goede  * GNU General Public License for more details.
231f33de0fSHans de Goede  *
241f33de0fSHans de Goede  */
251f33de0fSHans de Goede 
26133a9fe9SJoe Perches #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
27133a9fe9SJoe Perches 
281f33de0fSHans de Goede #define MODULE_NAME "xirlink-cit"
291f33de0fSHans de Goede 
30e0657be5SHans de Goede #include <linux/input.h>
311f33de0fSHans de Goede #include "gspca.h"
321f33de0fSHans de Goede 
331fddcf0eSHans de Goede MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
341f33de0fSHans de Goede MODULE_DESCRIPTION("Xirlink C-IT");
351f33de0fSHans de Goede MODULE_LICENSE("GPL");
361f33de0fSHans de Goede 
371f33de0fSHans de Goede /* FIXME we should autodetect this */
381f33de0fSHans de Goede static int ibm_netcam_pro;
391f33de0fSHans de Goede module_param(ibm_netcam_pro, int, 0);
401f33de0fSHans de Goede MODULE_PARM_DESC(ibm_netcam_pro,
411f33de0fSHans de Goede 		 "Use IBM Netcamera Pro init sequences for Model 3 cams");
421f33de0fSHans de Goede 
431f33de0fSHans de Goede /* FIXME this should be handled through the V4L2 input selection API */
441f33de0fSHans de Goede static int rca_input;
451f33de0fSHans de Goede module_param(rca_input, int, 0644);
461f33de0fSHans de Goede MODULE_PARM_DESC(rca_input,
471f33de0fSHans de Goede 		 "Use rca input instead of ccd sensor on Model 3 cams");
481f33de0fSHans de Goede 
491f33de0fSHans de Goede /* specific webcam descriptor */
501f33de0fSHans de Goede struct sd {
511f33de0fSHans de Goede 	struct gspca_dev gspca_dev;		/* !! must be the first item */
52d5d875cbSHans Verkuil 	struct v4l2_ctrl *lighting;
531f33de0fSHans de Goede 	u8 model;
54659fefa0SHans de Goede #define CIT_MODEL0 0 /* bcd version 0.01 cams ie the xvp-500 */
55659fefa0SHans de Goede #define CIT_MODEL1 1 /* The model 1 - 4 nomenclature comes from the old */
56659fefa0SHans de Goede #define CIT_MODEL2 2 /* ibmcam driver */
57659fefa0SHans de Goede #define CIT_MODEL3 3
58659fefa0SHans de Goede #define CIT_MODEL4 4
59659fefa0SHans de Goede #define CIT_IBM_NETCAM_PRO 5
601f33de0fSHans de Goede 	u8 input_index;
61e0657be5SHans de Goede 	u8 button_state;
6259f90a01SHans de Goede 	u8 stop_on_control_change;
631f33de0fSHans de Goede 	u8 sof_read;
6459f90a01SHans de Goede 	u8 sof_len;
651f33de0fSHans de Goede };
661f33de0fSHans de Goede 
671f33de0fSHans de Goede static void sd_stop0(struct gspca_dev *gspca_dev);
681f33de0fSHans de Goede 
6959f90a01SHans de Goede static const struct v4l2_pix_format cif_yuv_mode[] = {
7059f90a01SHans de Goede 	{176, 144, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
7159f90a01SHans de Goede 		.bytesperline = 176,
722c4e776aSHans de Goede 		.sizeimage = 176 * 144 * 3 / 2 + 4,
7359f90a01SHans de Goede 		.colorspace = V4L2_COLORSPACE_SRGB},
7459f90a01SHans de Goede 	{352, 288, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
7559f90a01SHans de Goede 		.bytesperline = 352,
762c4e776aSHans de Goede 		.sizeimage = 352 * 288 * 3 / 2 + 4,
7759f90a01SHans de Goede 		.colorspace = V4L2_COLORSPACE_SRGB},
781f33de0fSHans de Goede };
791f33de0fSHans de Goede 
801f33de0fSHans de Goede static const struct v4l2_pix_format vga_yuv_mode[] = {
811f33de0fSHans de Goede 	{160, 120, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
821f33de0fSHans de Goede 		.bytesperline = 160,
832c4e776aSHans de Goede 		.sizeimage = 160 * 120 * 3 / 2 + 4,
841f33de0fSHans de Goede 		.colorspace = V4L2_COLORSPACE_SRGB},
851f33de0fSHans de Goede 	{320, 240, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
861f33de0fSHans de Goede 		.bytesperline = 320,
872c4e776aSHans de Goede 		.sizeimage = 320 * 240 * 3 / 2 + 4,
881f33de0fSHans de Goede 		.colorspace = V4L2_COLORSPACE_SRGB},
891f33de0fSHans de Goede 	{640, 480, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
901f33de0fSHans de Goede 		.bytesperline = 640,
912c4e776aSHans de Goede 		.sizeimage = 640 * 480 * 3 / 2 + 4,
921f33de0fSHans de Goede 		.colorspace = V4L2_COLORSPACE_SRGB},
931f33de0fSHans de Goede };
941f33de0fSHans de Goede 
95659fefa0SHans de Goede static const struct v4l2_pix_format model0_mode[] = {
96659fefa0SHans de Goede 	{160, 120, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
97659fefa0SHans de Goede 		.bytesperline = 160,
982c4e776aSHans de Goede 		.sizeimage = 160 * 120 * 3 / 2 + 4,
99659fefa0SHans de Goede 		.colorspace = V4L2_COLORSPACE_SRGB},
100659fefa0SHans de Goede 	{176, 144, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
101659fefa0SHans de Goede 		.bytesperline = 176,
1022c4e776aSHans de Goede 		.sizeimage = 176 * 144 * 3 / 2 + 4,
103659fefa0SHans de Goede 		.colorspace = V4L2_COLORSPACE_SRGB},
104659fefa0SHans de Goede 	{320, 240, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
105659fefa0SHans de Goede 		.bytesperline = 320,
1062c4e776aSHans de Goede 		.sizeimage = 320 * 240 * 3 / 2 + 4,
107659fefa0SHans de Goede 		.colorspace = V4L2_COLORSPACE_SRGB},
108659fefa0SHans de Goede };
109659fefa0SHans de Goede 
11059f90a01SHans de Goede static const struct v4l2_pix_format model2_mode[] = {
11159f90a01SHans de Goede 	{160, 120, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
11259f90a01SHans de Goede 		.bytesperline = 160,
1132c4e776aSHans de Goede 		.sizeimage = 160 * 120 * 3 / 2 + 4,
11459f90a01SHans de Goede 		.colorspace = V4L2_COLORSPACE_SRGB},
11559f90a01SHans de Goede 	{176, 144, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
11659f90a01SHans de Goede 		.bytesperline = 176,
1172c4e776aSHans de Goede 		.sizeimage = 176 * 144 * 3 / 2 + 4,
11859f90a01SHans de Goede 		.colorspace = V4L2_COLORSPACE_SRGB},
11959f90a01SHans de Goede 	{320, 240, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
12059f90a01SHans de Goede 		.bytesperline = 320,
1212c4e776aSHans de Goede 		.sizeimage = 320 * 240 + 4,
12259f90a01SHans de Goede 		.colorspace = V4L2_COLORSPACE_SRGB},
12359f90a01SHans de Goede 	{352, 288, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
12459f90a01SHans de Goede 		.bytesperline = 352,
1252c4e776aSHans de Goede 		.sizeimage = 352 * 288 + 4,
12659f90a01SHans de Goede 		.colorspace = V4L2_COLORSPACE_SRGB},
12759f90a01SHans de Goede };
12859f90a01SHans de Goede 
1291f33de0fSHans de Goede /*
1301f33de0fSHans de Goede  * 01.01.08 - Added for RCA video in support -LO
1311f33de0fSHans de Goede  * This struct is used to init the Model3 cam to use the RCA video in port
1321f33de0fSHans de Goede  * instead of the CCD sensor.
1331f33de0fSHans de Goede  */
1341f33de0fSHans de Goede static const u16 rca_initdata[][3] = {
1351f33de0fSHans de Goede 	{0, 0x0000, 0x010c},
1361f33de0fSHans de Goede 	{0, 0x0006, 0x012c},
1371f33de0fSHans de Goede 	{0, 0x0078, 0x012d},
1381f33de0fSHans de Goede 	{0, 0x0046, 0x012f},
1391f33de0fSHans de Goede 	{0, 0xd141, 0x0124},
1401f33de0fSHans de Goede 	{0, 0x0000, 0x0127},
1411f33de0fSHans de Goede 	{0, 0xfea8, 0x0124},
1421f33de0fSHans de Goede 	{1, 0x0000, 0x0116},
1431f33de0fSHans de Goede 	{0, 0x0064, 0x0116},
1441f33de0fSHans de Goede 	{1, 0x0000, 0x0115},
1451f33de0fSHans de Goede 	{0, 0x0003, 0x0115},
1461f33de0fSHans de Goede 	{0, 0x0008, 0x0123},
1471f33de0fSHans de Goede 	{0, 0x0000, 0x0117},
1481f33de0fSHans de Goede 	{0, 0x0000, 0x0112},
1491f33de0fSHans de Goede 	{0, 0x0080, 0x0100},
1501f33de0fSHans de Goede 	{0, 0x0000, 0x0100},
1511f33de0fSHans de Goede 	{1, 0x0000, 0x0116},
1521f33de0fSHans de Goede 	{0, 0x0060, 0x0116},
1531f33de0fSHans de Goede 	{0, 0x0002, 0x0112},
1541f33de0fSHans de Goede 	{0, 0x0000, 0x0123},
1551f33de0fSHans de Goede 	{0, 0x0001, 0x0117},
1561f33de0fSHans de Goede 	{0, 0x0040, 0x0108},
1571f33de0fSHans de Goede 	{0, 0x0019, 0x012c},
1581f33de0fSHans de Goede 	{0, 0x0040, 0x0116},
1591f33de0fSHans de Goede 	{0, 0x000a, 0x0115},
1601f33de0fSHans de Goede 	{0, 0x000b, 0x0115},
1611f33de0fSHans de Goede 	{0, 0x0078, 0x012d},
1621f33de0fSHans de Goede 	{0, 0x0046, 0x012f},
1631f33de0fSHans de Goede 	{0, 0xd141, 0x0124},
1641f33de0fSHans de Goede 	{0, 0x0000, 0x0127},
1651f33de0fSHans de Goede 	{0, 0xfea8, 0x0124},
1661f33de0fSHans de Goede 	{0, 0x0064, 0x0116},
1671f33de0fSHans de Goede 	{0, 0x0000, 0x0115},
1681f33de0fSHans de Goede 	{0, 0x0001, 0x0115},
1691f33de0fSHans de Goede 	{0, 0xffff, 0x0124},
1701f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
1711f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
1721f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
1731f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
1741f33de0fSHans de Goede 	{0, 0x00aa, 0x0127},
1751f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
1761f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
1771f33de0fSHans de Goede 	{0, 0x0000, 0x0127},
1781f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
1791f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
1801f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
1811f33de0fSHans de Goede 	{0, 0xffff, 0x0124},
1821f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
1831f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
1841f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
1851f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
1861f33de0fSHans de Goede 	{0, 0x00f2, 0x0127},
1871f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
1881f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
1891f33de0fSHans de Goede 	{0, 0x000f, 0x0127},
1901f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
1911f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
1921f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
1931f33de0fSHans de Goede 	{0, 0xffff, 0x0124},
1941f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
1951f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
1961f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
1971f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
1981f33de0fSHans de Goede 	{0, 0x00f8, 0x0127},
1991f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2001f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2011f33de0fSHans de Goede 	{0, 0x00fc, 0x0127},
2021f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2031f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2041f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
2051f33de0fSHans de Goede 	{0, 0xffff, 0x0124},
2061f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
2071f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
2081f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2091f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2101f33de0fSHans de Goede 	{0, 0x00f9, 0x0127},
2111f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2121f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2131f33de0fSHans de Goede 	{0, 0x003c, 0x0127},
2141f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2151f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2161f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
2171f33de0fSHans de Goede 	{0, 0xffff, 0x0124},
2181f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
2191f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
2201f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2211f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2221f33de0fSHans de Goede 	{0, 0x0027, 0x0127},
2231f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2241f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2251f33de0fSHans de Goede 	{0, 0x0019, 0x0127},
2261f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2271f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2281f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
2291f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
2301f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
2311f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2321f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2331f33de0fSHans de Goede 	{0, 0x0037, 0x0127},
2341f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2351f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2361f33de0fSHans de Goede 	{0, 0x0000, 0x0127},
2371f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2381f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2391f33de0fSHans de Goede 	{0, 0x0021, 0x0127},
2401f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2411f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2421f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
2431f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
2441f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
2451f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2461f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2471f33de0fSHans de Goede 	{0, 0x0038, 0x0127},
2481f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2491f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2501f33de0fSHans de Goede 	{0, 0x0006, 0x0127},
2511f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2521f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2531f33de0fSHans de Goede 	{0, 0x0045, 0x0127},
2541f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2551f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2561f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
2571f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
2581f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
2591f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2601f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2611f33de0fSHans de Goede 	{0, 0x0037, 0x0127},
2621f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2631f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2641f33de0fSHans de Goede 	{0, 0x0001, 0x0127},
2651f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2661f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2671f33de0fSHans de Goede 	{0, 0x002a, 0x0127},
2681f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2691f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2701f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
2711f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
2721f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
2731f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2741f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2751f33de0fSHans de Goede 	{0, 0x0038, 0x0127},
2761f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2771f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2781f33de0fSHans de Goede 	{0, 0x0000, 0x0127},
2791f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2801f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2811f33de0fSHans de Goede 	{0, 0x000e, 0x0127},
2821f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2831f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2841f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
2851f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
2861f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
2871f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2881f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2891f33de0fSHans de Goede 	{0, 0x0037, 0x0127},
2901f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2911f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2921f33de0fSHans de Goede 	{0, 0x0001, 0x0127},
2931f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2941f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2951f33de0fSHans de Goede 	{0, 0x002b, 0x0127},
2961f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2971f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2981f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
2991f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
3001f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
3011f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3021f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3031f33de0fSHans de Goede 	{0, 0x0038, 0x0127},
3041f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3051f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3061f33de0fSHans de Goede 	{0, 0x0001, 0x0127},
3071f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3081f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3091f33de0fSHans de Goede 	{0, 0x00f4, 0x0127},
3101f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3111f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3121f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
3131f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
3141f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
3151f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3161f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3171f33de0fSHans de Goede 	{0, 0x0037, 0x0127},
3181f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3191f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3201f33de0fSHans de Goede 	{0, 0x0001, 0x0127},
3211f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3221f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3231f33de0fSHans de Goede 	{0, 0x002c, 0x0127},
3241f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3251f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3261f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
3271f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
3281f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
3291f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3301f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3311f33de0fSHans de Goede 	{0, 0x0038, 0x0127},
3321f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3331f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3341f33de0fSHans de Goede 	{0, 0x0001, 0x0127},
3351f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3361f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3371f33de0fSHans de Goede 	{0, 0x0004, 0x0127},
3381f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3391f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3401f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
3411f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
3421f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
3431f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3441f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3451f33de0fSHans de Goede 	{0, 0x0037, 0x0127},
3461f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3471f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3481f33de0fSHans de Goede 	{0, 0x0001, 0x0127},
3491f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3501f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3511f33de0fSHans de Goede 	{0, 0x002d, 0x0127},
3521f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3531f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3541f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
3551f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
3561f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
3571f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3581f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3591f33de0fSHans de Goede 	{0, 0x0038, 0x0127},
3601f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3611f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3621f33de0fSHans de Goede 	{0, 0x0000, 0x0127},
3631f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3641f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3651f33de0fSHans de Goede 	{0, 0x0014, 0x0127},
3661f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3671f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3681f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
3691f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
3701f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
3711f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3721f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3731f33de0fSHans de Goede 	{0, 0x0037, 0x0127},
3741f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3751f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3761f33de0fSHans de Goede 	{0, 0x0001, 0x0127},
3771f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3781f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3791f33de0fSHans de Goede 	{0, 0x002e, 0x0127},
3801f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3811f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3821f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
3831f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
3841f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
3851f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3861f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3871f33de0fSHans de Goede 	{0, 0x0038, 0x0127},
3881f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3891f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3901f33de0fSHans de Goede 	{0, 0x0003, 0x0127},
3911f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3921f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3931f33de0fSHans de Goede 	{0, 0x0000, 0x0127},
3941f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3951f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3961f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
3971f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
3981f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
3991f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
4001f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
4011f33de0fSHans de Goede 	{0, 0x0037, 0x0127},
4021f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
4031f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
4041f33de0fSHans de Goede 	{0, 0x0001, 0x0127},
4051f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
4061f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
4071f33de0fSHans de Goede 	{0, 0x002f, 0x0127},
4081f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
4091f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
4101f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
4111f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
4121f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
4131f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
4141f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
4151f33de0fSHans de Goede 	{0, 0x0038, 0x0127},
4161f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
4171f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
4181f33de0fSHans de Goede 	{0, 0x0003, 0x0127},
4191f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
4201f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
4211f33de0fSHans de Goede 	{0, 0x0014, 0x0127},
4221f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
4231f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
4241f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
4251f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
4261f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
4271f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
4281f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
4291f33de0fSHans de Goede 	{0, 0x0037, 0x0127},
4301f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
4311f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
4321f33de0fSHans de Goede 	{0, 0x0001, 0x0127},
4331f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
4341f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
4351f33de0fSHans de Goede 	{0, 0x0040, 0x0127},
4361f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
4371f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
4381f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
4391f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
4401f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
4411f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
4421f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
4431f33de0fSHans de Goede 	{0, 0x0038, 0x0127},
4441f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
4451f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
4461f33de0fSHans de Goede 	{0, 0x0000, 0x0127},
4471f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
4481f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
4491f33de0fSHans de Goede 	{0, 0x0040, 0x0127},
4501f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
4511f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
4521f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
4531f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
4541f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
4551f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
4561f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
4571f33de0fSHans de Goede 	{0, 0x0037, 0x0127},
4581f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
4591f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
4601f33de0fSHans de Goede 	{0, 0x0001, 0x0127},
4611f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
4621f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
4631f33de0fSHans de Goede 	{0, 0x0053, 0x0127},
4641f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
4651f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
4661f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
4671f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
4681f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
4691f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
4701f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
4711f33de0fSHans de Goede 	{0, 0x0038, 0x0127},
4721f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
4731f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
4741f33de0fSHans de Goede 	{0, 0x0000, 0x0127},
4751f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
4761f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
4771f33de0fSHans de Goede 	{0, 0x0038, 0x0127},
4781f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
4791f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
4801f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
4811f33de0fSHans de Goede 	{0, 0x0000, 0x0101},
4821f33de0fSHans de Goede 	{0, 0x00a0, 0x0103},
4831f33de0fSHans de Goede 	{0, 0x0078, 0x0105},
4841f33de0fSHans de Goede 	{0, 0x0000, 0x010a},
4851f33de0fSHans de Goede 	{0, 0x0024, 0x010b},
4861f33de0fSHans de Goede 	{0, 0x0028, 0x0119},
4871f33de0fSHans de Goede 	{0, 0x0088, 0x011b},
4881f33de0fSHans de Goede 	{0, 0x0002, 0x011d},
4891f33de0fSHans de Goede 	{0, 0x0003, 0x011e},
4901f33de0fSHans de Goede 	{0, 0x0000, 0x0129},
4911f33de0fSHans de Goede 	{0, 0x00fc, 0x012b},
4921f33de0fSHans de Goede 	{0, 0x0008, 0x0102},
4931f33de0fSHans de Goede 	{0, 0x0000, 0x0104},
4941f33de0fSHans de Goede 	{0, 0x0008, 0x011a},
4951f33de0fSHans de Goede 	{0, 0x0028, 0x011c},
4961f33de0fSHans de Goede 	{0, 0x0021, 0x012a},
4971f33de0fSHans de Goede 	{0, 0x0000, 0x0118},
4981f33de0fSHans de Goede 	{0, 0x0000, 0x0132},
4991f33de0fSHans de Goede 	{0, 0x0000, 0x0109},
5001f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
5011f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
5021f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5031f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5041f33de0fSHans de Goede 	{0, 0x0037, 0x0127},
5051f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5061f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5071f33de0fSHans de Goede 	{0, 0x0001, 0x0127},
5081f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5091f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5101f33de0fSHans de Goede 	{0, 0x0031, 0x0127},
5111f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5121f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5131f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
5141f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
5151f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
5161f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5171f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5181f33de0fSHans de Goede 	{0, 0x0038, 0x0127},
5191f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5201f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5211f33de0fSHans de Goede 	{0, 0x0000, 0x0127},
5221f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5231f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5241f33de0fSHans de Goede 	{0, 0x0000, 0x0127},
5251f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5261f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5271f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
5281f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
5291f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
5301f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5311f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5321f33de0fSHans de Goede 	{0, 0x0037, 0x0127},
5331f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5341f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5351f33de0fSHans de Goede 	{0, 0x0001, 0x0127},
5361f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5371f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5381f33de0fSHans de Goede 	{0, 0x0040, 0x0127},
5391f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5401f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5411f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
5421f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
5431f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
5441f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5451f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5461f33de0fSHans de Goede 	{0, 0x0038, 0x0127},
5471f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5481f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5491f33de0fSHans de Goede 	{0, 0x0000, 0x0127},
5501f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5511f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5521f33de0fSHans de Goede 	{0, 0x0040, 0x0127},
5531f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5541f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5551f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
5561f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
5571f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
5581f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5591f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5601f33de0fSHans de Goede 	{0, 0x0037, 0x0127},
5611f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5621f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5631f33de0fSHans de Goede 	{0, 0x0000, 0x0127},
5641f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5651f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5661f33de0fSHans de Goede 	{0, 0x00dc, 0x0127},
5671f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5681f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5691f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
5701f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
5711f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
5721f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5731f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5741f33de0fSHans de Goede 	{0, 0x0038, 0x0127},
5751f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5761f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5771f33de0fSHans de Goede 	{0, 0x0000, 0x0127},
5781f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5791f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5801f33de0fSHans de Goede 	{0, 0x0000, 0x0127},
5811f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5821f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5831f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
5841f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
5851f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
5861f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5871f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5881f33de0fSHans de Goede 	{0, 0x0037, 0x0127},
5891f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5901f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5911f33de0fSHans de Goede 	{0, 0x0001, 0x0127},
5921f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5931f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5941f33de0fSHans de Goede 	{0, 0x0032, 0x0127},
5951f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5961f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5971f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
5981f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
5991f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
6001f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
6011f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
6021f33de0fSHans de Goede 	{0, 0x0038, 0x0127},
6031f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
6041f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
6051f33de0fSHans de Goede 	{0, 0x0001, 0x0127},
6061f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
6071f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
6081f33de0fSHans de Goede 	{0, 0x0020, 0x0127},
6091f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
6101f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
6111f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
6121f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
6131f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
6141f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
6151f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
6161f33de0fSHans de Goede 	{0, 0x0037, 0x0127},
6171f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
6181f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
6191f33de0fSHans de Goede 	{0, 0x0001, 0x0127},
6201f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
6211f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
6221f33de0fSHans de Goede 	{0, 0x0040, 0x0127},
6231f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
6241f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
6251f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
6261f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
6271f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
6281f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
6291f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
6301f33de0fSHans de Goede 	{0, 0x0038, 0x0127},
6311f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
6321f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
6331f33de0fSHans de Goede 	{0, 0x0000, 0x0127},
6341f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
6351f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
6361f33de0fSHans de Goede 	{0, 0x0040, 0x0127},
6371f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
6381f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
6391f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
6401f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
6411f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
6421f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
6431f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
6441f33de0fSHans de Goede 	{0, 0x0037, 0x0127},
6451f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
6461f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
6471f33de0fSHans de Goede 	{0, 0x0000, 0x0127},
6481f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
6491f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
6501f33de0fSHans de Goede 	{0, 0x0030, 0x0127},
6511f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
6521f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
6531f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
6541f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
6551f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
6561f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
6571f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
6581f33de0fSHans de Goede 	{0, 0x0038, 0x0127},
6591f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
6601f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
6611f33de0fSHans de Goede 	{0, 0x0008, 0x0127},
6621f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
6631f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
6641f33de0fSHans de Goede 	{0, 0x0000, 0x0127},
6651f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
6661f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
6671f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
6681f33de0fSHans de Goede 	{0, 0x0003, 0x0111},
6691f33de0fSHans de Goede };
6701f33de0fSHans de Goede 
67159f90a01SHans de Goede /* TESTME the old ibmcam driver repeats certain commands to Model1 cameras, we
67259f90a01SHans de Goede    do the same for now (testing needed to see if this is really necessary) */
67359f90a01SHans de Goede static const int cit_model1_ntries = 5;
67459f90a01SHans de Goede static const int cit_model1_ntries2 = 2;
67559f90a01SHans de Goede 
6761f33de0fSHans de Goede static int cit_write_reg(struct gspca_dev *gspca_dev, u16 value, u16 index)
6771f33de0fSHans de Goede {
6781f33de0fSHans de Goede 	struct usb_device *udev = gspca_dev->dev;
6791f33de0fSHans de Goede 	int err;
6801f33de0fSHans de Goede 
6811f33de0fSHans de Goede 	err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00,
6821f33de0fSHans de Goede 			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT,
6831f33de0fSHans de Goede 			value, index, NULL, 0, 1000);
6841f33de0fSHans de Goede 	if (err < 0)
685133a9fe9SJoe Perches 		pr_err("Failed to write a register (index 0x%04X, value 0x%02X, error %d)\n",
686133a9fe9SJoe Perches 		       index, value, err);
6871f33de0fSHans de Goede 
6881f33de0fSHans de Goede 	return 0;
6891f33de0fSHans de Goede }
6901f33de0fSHans de Goede 
691e0657be5SHans de Goede static int cit_read_reg(struct gspca_dev *gspca_dev, u16 index, int verbose)
6921f33de0fSHans de Goede {
6931f33de0fSHans de Goede 	struct usb_device *udev = gspca_dev->dev;
6941f33de0fSHans de Goede 	__u8 *buf = gspca_dev->usb_buf;
6951f33de0fSHans de Goede 	int res;
6961f33de0fSHans de Goede 
6971f33de0fSHans de Goede 	res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x01,
6981f33de0fSHans de Goede 			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT,
6991f33de0fSHans de Goede 			0x00, index, buf, 8, 1000);
7001f33de0fSHans de Goede 	if (res < 0) {
701133a9fe9SJoe Perches 		pr_err("Failed to read a register (index 0x%04X, error %d)\n",
7021f33de0fSHans de Goede 		       index, res);
7031f33de0fSHans de Goede 		return res;
7041f33de0fSHans de Goede 	}
7051f33de0fSHans de Goede 
706e0657be5SHans de Goede 	if (verbose)
707*37d5efb0SJoe Perches 		gspca_dbg(gspca_dev, D_PROBE, "Register %04x value: %02x\n",
708*37d5efb0SJoe Perches 			  index, buf[0]);
7091f33de0fSHans de Goede 
7101f33de0fSHans de Goede 	return 0;
7111f33de0fSHans de Goede }
7121f33de0fSHans de Goede 
7131f33de0fSHans de Goede /*
71459f90a01SHans de Goede  * cit_send_FF_04_02()
71559f90a01SHans de Goede  *
71659f90a01SHans de Goede  * This procedure sends magic 3-command prefix to the camera.
71759f90a01SHans de Goede  * The purpose of this prefix is not known.
71859f90a01SHans de Goede  *
71959f90a01SHans de Goede  * History:
72059f90a01SHans de Goede  * 1/2/00   Created.
72159f90a01SHans de Goede  */
72259f90a01SHans de Goede static void cit_send_FF_04_02(struct gspca_dev *gspca_dev)
72359f90a01SHans de Goede {
72459f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x00FF, 0x0127);
72559f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0004, 0x0124);
72659f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0002, 0x0124);
72759f90a01SHans de Goede }
72859f90a01SHans de Goede 
72959f90a01SHans de Goede static void cit_send_00_04_06(struct gspca_dev *gspca_dev)
73059f90a01SHans de Goede {
73159f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0127);
73259f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0004, 0x0124);
73359f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0006, 0x0124);
73459f90a01SHans de Goede }
73559f90a01SHans de Goede 
73659f90a01SHans de Goede static void cit_send_x_00(struct gspca_dev *gspca_dev, unsigned short x)
73759f90a01SHans de Goede {
73859f90a01SHans de Goede 	cit_write_reg(gspca_dev, x,      0x0127);
73959f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0124);
74059f90a01SHans de Goede }
74159f90a01SHans de Goede 
74259f90a01SHans de Goede static void cit_send_x_00_05(struct gspca_dev *gspca_dev, unsigned short x)
74359f90a01SHans de Goede {
74459f90a01SHans de Goede 	cit_send_x_00(gspca_dev, x);
74559f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0005, 0x0124);
74659f90a01SHans de Goede }
74759f90a01SHans de Goede 
74859f90a01SHans de Goede static void cit_send_x_00_05_02(struct gspca_dev *gspca_dev, unsigned short x)
74959f90a01SHans de Goede {
75059f90a01SHans de Goede 	cit_write_reg(gspca_dev, x,      0x0127);
75159f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0124);
75259f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0005, 0x0124);
75359f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0002, 0x0124);
75459f90a01SHans de Goede }
75559f90a01SHans de Goede 
75659f90a01SHans de Goede static void cit_send_x_01_00_05(struct gspca_dev *gspca_dev, u16 x)
75759f90a01SHans de Goede {
75859f90a01SHans de Goede 	cit_write_reg(gspca_dev, x,      0x0127);
75959f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0001, 0x0124);
76059f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0124);
76159f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0005, 0x0124);
76259f90a01SHans de Goede }
76359f90a01SHans de Goede 
76459f90a01SHans de Goede static void cit_send_x_00_05_02_01(struct gspca_dev *gspca_dev, u16 x)
76559f90a01SHans de Goede {
76659f90a01SHans de Goede 	cit_write_reg(gspca_dev, x,      0x0127);
76759f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0124);
76859f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0005, 0x0124);
76959f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0002, 0x0124);
77059f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0001, 0x0124);
77159f90a01SHans de Goede }
77259f90a01SHans de Goede 
77359f90a01SHans de Goede static void cit_send_x_00_05_02_08_01(struct gspca_dev *gspca_dev, u16 x)
77459f90a01SHans de Goede {
77559f90a01SHans de Goede 	cit_write_reg(gspca_dev, x,      0x0127);
77659f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0124);
77759f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0005, 0x0124);
77859f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0002, 0x0124);
77959f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0008, 0x0124);
78059f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0001, 0x0124);
78159f90a01SHans de Goede }
78259f90a01SHans de Goede 
78359f90a01SHans de Goede static void cit_Packet_Format1(struct gspca_dev *gspca_dev, u16 fkey, u16 val)
78459f90a01SHans de Goede {
78559f90a01SHans de Goede 	cit_send_x_01_00_05(gspca_dev, 0x0088);
78659f90a01SHans de Goede 	cit_send_x_00_05(gspca_dev, fkey);
78759f90a01SHans de Goede 	cit_send_x_00_05_02_08_01(gspca_dev, val);
78859f90a01SHans de Goede 	cit_send_x_00_05(gspca_dev, 0x0088);
78959f90a01SHans de Goede 	cit_send_x_00_05_02_01(gspca_dev, fkey);
79059f90a01SHans de Goede 	cit_send_x_00_05(gspca_dev, 0x0089);
79159f90a01SHans de Goede 	cit_send_x_00(gspca_dev, fkey);
79259f90a01SHans de Goede 	cit_send_00_04_06(gspca_dev);
793e0657be5SHans de Goede 	cit_read_reg(gspca_dev, 0x0126, 0);
79459f90a01SHans de Goede 	cit_send_FF_04_02(gspca_dev);
79559f90a01SHans de Goede }
79659f90a01SHans de Goede 
79759f90a01SHans de Goede static void cit_PacketFormat2(struct gspca_dev *gspca_dev, u16 fkey, u16 val)
79859f90a01SHans de Goede {
79959f90a01SHans de Goede 	cit_send_x_01_00_05(gspca_dev, 0x0088);
80059f90a01SHans de Goede 	cit_send_x_00_05(gspca_dev, fkey);
80159f90a01SHans de Goede 	cit_send_x_00_05_02(gspca_dev, val);
80259f90a01SHans de Goede }
80359f90a01SHans de Goede 
80459f90a01SHans de Goede static void cit_model2_Packet2(struct gspca_dev *gspca_dev)
80559f90a01SHans de Goede {
80659f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x00ff, 0x012d);
80759f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0xfea3, 0x0124);
80859f90a01SHans de Goede }
80959f90a01SHans de Goede 
81059f90a01SHans de Goede static void cit_model2_Packet1(struct gspca_dev *gspca_dev, u16 v1, u16 v2)
81159f90a01SHans de Goede {
81259f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x00aa, 0x012d);
81359f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x00ff, 0x012e);
81459f90a01SHans de Goede 	cit_write_reg(gspca_dev, v1,     0x012f);
81559f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x00ff, 0x0130);
81659f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0xc719, 0x0124);
81759f90a01SHans de Goede 	cit_write_reg(gspca_dev, v2,     0x0127);
81859f90a01SHans de Goede 
81959f90a01SHans de Goede 	cit_model2_Packet2(gspca_dev);
82059f90a01SHans de Goede }
82159f90a01SHans de Goede 
82259f90a01SHans de Goede /*
82359f90a01SHans de Goede  * cit_model3_Packet1()
8241f33de0fSHans de Goede  *
8251f33de0fSHans de Goede  * 00_0078_012d
8261f33de0fSHans de Goede  * 00_0097_012f
8271f33de0fSHans de Goede  * 00_d141_0124
8281f33de0fSHans de Goede  * 00_0096_0127
8291f33de0fSHans de Goede  * 00_fea8_0124
8301f33de0fSHans de Goede */
8311f33de0fSHans de Goede static void cit_model3_Packet1(struct gspca_dev *gspca_dev, u16 v1, u16 v2)
8321f33de0fSHans de Goede {
8331f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0078, 0x012d);
8341f33de0fSHans de Goede 	cit_write_reg(gspca_dev, v1,     0x012f);
8351f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0xd141, 0x0124);
8361f33de0fSHans de Goede 	cit_write_reg(gspca_dev, v2,     0x0127);
8371f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0xfea8, 0x0124);
8381f33de0fSHans de Goede }
8391f33de0fSHans de Goede 
84059f90a01SHans de Goede static void cit_model4_Packet1(struct gspca_dev *gspca_dev, u16 v1, u16 v2)
84159f90a01SHans de Goede {
84259f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x00aa, 0x012d);
84359f90a01SHans de Goede 	cit_write_reg(gspca_dev, v1,     0x012f);
84459f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0xd141, 0x0124);
84559f90a01SHans de Goede 	cit_write_reg(gspca_dev, v2,     0x0127);
84659f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0xfea8, 0x0124);
84759f90a01SHans de Goede }
84859f90a01SHans de Goede 
84959f90a01SHans de Goede static void cit_model4_BrightnessPacket(struct gspca_dev *gspca_dev, u16 val)
85059f90a01SHans de Goede {
85159f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x00aa, 0x012d);
85259f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0026, 0x012f);
85359f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0xd141, 0x0124);
85459f90a01SHans de Goede 	cit_write_reg(gspca_dev, val,    0x0127);
85559f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x00aa, 0x0130);
85659f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x82a8, 0x0124);
85759f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0038, 0x012d);
85859f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0004, 0x012f);
85959f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0xd145, 0x0124);
86059f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0xfffa, 0x0124);
86159f90a01SHans de Goede }
86259f90a01SHans de Goede 
8631f33de0fSHans de Goede /* this function is called at probe time */
8641f33de0fSHans de Goede static int sd_config(struct gspca_dev *gspca_dev,
8651f33de0fSHans de Goede 		     const struct usb_device_id *id)
8661f33de0fSHans de Goede {
8671f33de0fSHans de Goede 	struct sd *sd = (struct sd *) gspca_dev;
8681f33de0fSHans de Goede 	struct cam *cam;
8691f33de0fSHans de Goede 
8701f33de0fSHans de Goede 	sd->model = id->driver_info;
8711f33de0fSHans de Goede 	if (sd->model == CIT_MODEL3 && ibm_netcam_pro)
8721f33de0fSHans de Goede 		sd->model = CIT_IBM_NETCAM_PRO;
8731f33de0fSHans de Goede 
8741f33de0fSHans de Goede 	cam = &gspca_dev->cam;
8751f33de0fSHans de Goede 	switch (sd->model) {
876659fefa0SHans de Goede 	case CIT_MODEL0:
877659fefa0SHans de Goede 		cam->cam_mode = model0_mode;
878659fefa0SHans de Goede 		cam->nmodes = ARRAY_SIZE(model0_mode);
879659fefa0SHans de Goede 		sd->sof_len = 4;
880659fefa0SHans de Goede 		break;
88159f90a01SHans de Goede 	case CIT_MODEL1:
88259f90a01SHans de Goede 		cam->cam_mode = cif_yuv_mode;
88359f90a01SHans de Goede 		cam->nmodes = ARRAY_SIZE(cif_yuv_mode);
884659fefa0SHans de Goede 		sd->sof_len = 4;
88559f90a01SHans de Goede 		break;
88659f90a01SHans de Goede 	case CIT_MODEL2:
88759f90a01SHans de Goede 		cam->cam_mode = model2_mode + 1; /* no 160x120 */
88859f90a01SHans de Goede 		cam->nmodes = 3;
88959f90a01SHans de Goede 		break;
8901f33de0fSHans de Goede 	case CIT_MODEL3:
8911f33de0fSHans de Goede 		cam->cam_mode = vga_yuv_mode;
8921f33de0fSHans de Goede 		cam->nmodes = ARRAY_SIZE(vga_yuv_mode);
89359f90a01SHans de Goede 		sd->stop_on_control_change = 1;
894659fefa0SHans de Goede 		sd->sof_len = 4;
89559f90a01SHans de Goede 		break;
89659f90a01SHans de Goede 	case CIT_MODEL4:
89759f90a01SHans de Goede 		cam->cam_mode = model2_mode;
89859f90a01SHans de Goede 		cam->nmodes = ARRAY_SIZE(model2_mode);
8991f33de0fSHans de Goede 		break;
9001f33de0fSHans de Goede 	case CIT_IBM_NETCAM_PRO:
9011f33de0fSHans de Goede 		cam->cam_mode = vga_yuv_mode;
9021f33de0fSHans de Goede 		cam->nmodes = 2; /* no 640 x 480 */
9031f33de0fSHans de Goede 		cam->input_flags = V4L2_IN_ST_VFLIP;
90459f90a01SHans de Goede 		sd->stop_on_control_change = 1;
905659fefa0SHans de Goede 		sd->sof_len = 4;
9061f33de0fSHans de Goede 		break;
9071f33de0fSHans de Goede 	}
9081f33de0fSHans de Goede 
909659fefa0SHans de Goede 	return 0;
910659fefa0SHans de Goede }
911659fefa0SHans de Goede 
912659fefa0SHans de Goede static int cit_init_model0(struct gspca_dev *gspca_dev)
913659fefa0SHans de Goede {
914659fefa0SHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0100); /* turn on led */
915659fefa0SHans de Goede 	cit_write_reg(gspca_dev, 0x0001, 0x0112); /* turn on autogain ? */
916659fefa0SHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0400);
917659fefa0SHans de Goede 	cit_write_reg(gspca_dev, 0x0001, 0x0400);
918659fefa0SHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0420);
919659fefa0SHans de Goede 	cit_write_reg(gspca_dev, 0x0001, 0x0420);
920659fefa0SHans de Goede 	cit_write_reg(gspca_dev, 0x000d, 0x0409);
921659fefa0SHans de Goede 	cit_write_reg(gspca_dev, 0x0002, 0x040a);
922659fefa0SHans de Goede 	cit_write_reg(gspca_dev, 0x0018, 0x0405);
923659fefa0SHans de Goede 	cit_write_reg(gspca_dev, 0x0008, 0x0435);
924659fefa0SHans de Goede 	cit_write_reg(gspca_dev, 0x0026, 0x040b);
925659fefa0SHans de Goede 	cit_write_reg(gspca_dev, 0x0007, 0x0437);
926659fefa0SHans de Goede 	cit_write_reg(gspca_dev, 0x0015, 0x042f);
927659fefa0SHans de Goede 	cit_write_reg(gspca_dev, 0x002b, 0x0439);
928659fefa0SHans de Goede 	cit_write_reg(gspca_dev, 0x0026, 0x043a);
929659fefa0SHans de Goede 	cit_write_reg(gspca_dev, 0x0008, 0x0438);
930659fefa0SHans de Goede 	cit_write_reg(gspca_dev, 0x001e, 0x042b);
931659fefa0SHans de Goede 	cit_write_reg(gspca_dev, 0x0041, 0x042c);
9321f33de0fSHans de Goede 
9331f33de0fSHans de Goede 	return 0;
9341f33de0fSHans de Goede }
9351f33de0fSHans de Goede 
9361f33de0fSHans de Goede static int cit_init_ibm_netcam_pro(struct gspca_dev *gspca_dev)
9371f33de0fSHans de Goede {
938e0657be5SHans de Goede 	cit_read_reg(gspca_dev, 0x128, 1);
9391f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0003, 0x0133);
9401f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0117);
9411f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0008, 0x0123);
9421f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0100);
943e0657be5SHans de Goede 	cit_read_reg(gspca_dev, 0x0116, 0);
9441f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0060, 0x0116);
9451f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0002, 0x0112);
9461f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0133);
9471f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0123);
9481f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0001, 0x0117);
9491f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0040, 0x0108);
9501f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0019, 0x012c);
9511f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0060, 0x0116);
9521f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0002, 0x0115);
9531f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x000b, 0x0115);
9541f33de0fSHans de Goede 
9551f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0078, 0x012d);
9561f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0001, 0x012f);
9571f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0xd141, 0x0124);
9581f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0079, 0x012d);
9591f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x00ff, 0x0130);
9601f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0xcd41, 0x0124);
9611f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0xfffa, 0x0124);
962e0657be5SHans de Goede 	cit_read_reg(gspca_dev, 0x0126, 1);
9631f33de0fSHans de Goede 
9641f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0000, 0x0000);
9651f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0000, 0x0001);
9661f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x000b, 0x0000);
9671f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x000c, 0x0008);
9681f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x000d, 0x003a);
9691f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x000e, 0x0060);
9701f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x000f, 0x0060);
9711f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0010, 0x0008);
9721f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0011, 0x0004);
9731f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0012, 0x0028);
9741f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0013, 0x0002);
9751f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0014, 0x0000);
9761f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0015, 0x00fb);
9771f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0016, 0x0002);
9781f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0017, 0x0037);
9791f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0018, 0x0036);
9801f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x001e, 0x0000);
9811f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x001f, 0x0008);
9821f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0020, 0x00c1);
9831f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0021, 0x0034);
9841f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0022, 0x0034);
9851f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0025, 0x0002);
9861f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0028, 0x0022);
9871f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0029, 0x000a);
9881f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x002b, 0x0000);
9891f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x002c, 0x0000);
9901f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x002d, 0x00ff);
9911f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x002e, 0x00ff);
9921f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x002f, 0x00ff);
9931f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0030, 0x00ff);
9941f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0031, 0x00ff);
9951f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0032, 0x0007);
9961f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0033, 0x0005);
9971f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0037, 0x0040);
9981f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0039, 0x0000);
9991f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x003a, 0x0000);
10001f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x003b, 0x0001);
10011f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x003c, 0x0000);
10021f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0040, 0x000c);
10031f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0041, 0x00fb);
10041f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0042, 0x0002);
10051f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0043, 0x0000);
10061f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0045, 0x0000);
10071f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0046, 0x0000);
10081f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0047, 0x0000);
10091f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0048, 0x0000);
10101f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0049, 0x0000);
10111f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x004a, 0x00ff);
10121f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x004b, 0x00ff);
10131f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x004c, 0x00ff);
10141f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x004f, 0x0000);
10151f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0050, 0x0000);
10161f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0051, 0x0002);
10171f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0055, 0x0000);
10181f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0056, 0x0000);
10191f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0057, 0x0000);
10201f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0058, 0x0002);
10211f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0059, 0x0000);
10221f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x005c, 0x0016);
10231f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x005d, 0x0022);
10241f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x005e, 0x003c);
10251f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x005f, 0x0050);
10261f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0060, 0x0044);
10271f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0061, 0x0005);
10281f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x006a, 0x007e);
10291f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x006f, 0x0000);
10301f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0072, 0x001b);
10311f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0073, 0x0005);
10321f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0074, 0x000a);
10331f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0075, 0x001b);
10341f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0076, 0x002a);
10351f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0077, 0x003c);
10361f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0078, 0x0050);
10371f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x007b, 0x0000);
10381f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x007c, 0x0011);
10391f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x007d, 0x0024);
10401f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x007e, 0x0043);
10411f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x007f, 0x005a);
10421f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0084, 0x0020);
10431f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0085, 0x0033);
10441f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0086, 0x000a);
10451f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0087, 0x0030);
10461f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0088, 0x0070);
10471f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x008b, 0x0008);
10481f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x008f, 0x0000);
10491f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0090, 0x0006);
10501f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0091, 0x0028);
10511f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0092, 0x005a);
10521f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0093, 0x0082);
10531f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0096, 0x0014);
10541f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0097, 0x0020);
10551f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0098, 0x0000);
10561f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00b0, 0x0046);
10571f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00b1, 0x0000);
10581f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00b2, 0x0000);
10591f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00b3, 0x0004);
10601f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00b4, 0x0007);
10611f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00b6, 0x0002);
10621f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00b7, 0x0004);
10631f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00bb, 0x0000);
10641f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00bc, 0x0001);
10651f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00bd, 0x0000);
10661f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00bf, 0x0000);
10671f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00c0, 0x00c8);
10681f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00c1, 0x0014);
10691f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00c2, 0x0001);
10701f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00c3, 0x0000);
10711f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00c4, 0x0004);
10721f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00cb, 0x00bf);
10731f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00cc, 0x00bf);
10741f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00cd, 0x00bf);
10751f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00ce, 0x0000);
10761f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00cf, 0x0020);
10771f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00d0, 0x0040);
10781f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00d1, 0x00bf);
10791f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00d1, 0x00bf);
10801f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00d2, 0x00bf);
10811f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00d3, 0x00bf);
10821f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00ea, 0x0008);
10831f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00eb, 0x0000);
10841f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00ec, 0x00e8);
10851f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00ed, 0x0001);
10861f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00ef, 0x0022);
10871f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00f0, 0x0000);
10881f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00f2, 0x0028);
10891f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00f4, 0x0002);
10901f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00f5, 0x0000);
10911f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00fa, 0x0000);
10921f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00fb, 0x0001);
10931f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00fc, 0x0000);
10941f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00fd, 0x0000);
10951f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00fe, 0x0000);
10961f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00ff, 0x0000);
10971f33de0fSHans de Goede 
10981f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00be, 0x0003);
10991f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00c8, 0x0000);
11001f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00c9, 0x0020);
11011f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00ca, 0x0040);
11021f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0053, 0x0001);
11031f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0082, 0x000e);
11041f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0083, 0x0020);
11051f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0034, 0x003c);
11061f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x006e, 0x0055);
11071f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0062, 0x0005);
11081f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0063, 0x0008);
11091f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0066, 0x000a);
11101f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0067, 0x0006);
11111f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x006b, 0x0010);
11121f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x005a, 0x0001);
11131f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x005b, 0x000a);
11141f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0023, 0x0006);
11151f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0026, 0x0004);
11161f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0036, 0x0069);
11171f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0038, 0x0064);
11181f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x003d, 0x0003);
11191f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x003e, 0x0001);
11201f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00b8, 0x0014);
11211f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00b9, 0x0014);
11221f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00e6, 0x0004);
11231f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00e8, 0x0001);
11241f33de0fSHans de Goede 
11251f33de0fSHans de Goede 	return 0;
11261f33de0fSHans de Goede }
11271f33de0fSHans de Goede 
11281f33de0fSHans de Goede /* this function is called at probe and resume time */
11291f33de0fSHans de Goede static int sd_init(struct gspca_dev *gspca_dev)
11301f33de0fSHans de Goede {
11311f33de0fSHans de Goede 	struct sd *sd = (struct sd *) gspca_dev;
11321f33de0fSHans de Goede 
11331f33de0fSHans de Goede 	switch (sd->model) {
1134659fefa0SHans de Goede 	case CIT_MODEL0:
1135659fefa0SHans de Goede 		cit_init_model0(gspca_dev);
1136659fefa0SHans de Goede 		sd_stop0(gspca_dev);
1137659fefa0SHans de Goede 		break;
113859f90a01SHans de Goede 	case CIT_MODEL1:
113959f90a01SHans de Goede 	case CIT_MODEL2:
11401f33de0fSHans de Goede 	case CIT_MODEL3:
114159f90a01SHans de Goede 	case CIT_MODEL4:
11421f33de0fSHans de Goede 		break; /* All is done in sd_start */
11431f33de0fSHans de Goede 	case CIT_IBM_NETCAM_PRO:
11441f33de0fSHans de Goede 		cit_init_ibm_netcam_pro(gspca_dev);
11451f33de0fSHans de Goede 		sd_stop0(gspca_dev);
11461f33de0fSHans de Goede 		break;
11471f33de0fSHans de Goede 	}
11481f33de0fSHans de Goede 	return 0;
11491f33de0fSHans de Goede }
11501f33de0fSHans de Goede 
1151d5d875cbSHans Verkuil static int cit_set_brightness(struct gspca_dev *gspca_dev, s32 val)
11521f33de0fSHans de Goede {
11531f33de0fSHans de Goede 	struct sd *sd = (struct sd *) gspca_dev;
115459f90a01SHans de Goede 	int i;
11551f33de0fSHans de Goede 
11561f33de0fSHans de Goede 	switch (sd->model) {
1157659fefa0SHans de Goede 	case CIT_MODEL0:
1158659fefa0SHans de Goede 	case CIT_IBM_NETCAM_PRO:
1159659fefa0SHans de Goede 		/* No (known) brightness control for these */
1160659fefa0SHans de Goede 		break;
116159f90a01SHans de Goede 	case CIT_MODEL1:
116259f90a01SHans de Goede 		/* Model 1: Brightness range 0 - 63 */
1163d5d875cbSHans Verkuil 		cit_Packet_Format1(gspca_dev, 0x0031, val);
1164d5d875cbSHans Verkuil 		cit_Packet_Format1(gspca_dev, 0x0032, val);
1165d5d875cbSHans Verkuil 		cit_Packet_Format1(gspca_dev, 0x0033, val);
116659f90a01SHans de Goede 		break;
116759f90a01SHans de Goede 	case CIT_MODEL2:
116859f90a01SHans de Goede 		/* Model 2: Brightness range 0x60 - 0xee */
116959f90a01SHans de Goede 		/* Scale 0 - 63 to 0x60 - 0xee */
1170d5d875cbSHans Verkuil 		i = 0x60 + val * 2254 / 1000;
117159f90a01SHans de Goede 		cit_model2_Packet1(gspca_dev, 0x001a, i);
117259f90a01SHans de Goede 		break;
11731f33de0fSHans de Goede 	case CIT_MODEL3:
11741f33de0fSHans de Goede 		/* Model 3: Brightness range 'i' in [0x0C..0x3F] */
1175d5d875cbSHans Verkuil 		i = val;
117659f90a01SHans de Goede 		if (i < 0x0c)
117759f90a01SHans de Goede 			i = 0x0c;
117859f90a01SHans de Goede 		cit_model3_Packet1(gspca_dev, 0x0036, i);
117959f90a01SHans de Goede 		break;
118059f90a01SHans de Goede 	case CIT_MODEL4:
118159f90a01SHans de Goede 		/* Model 4: Brightness range 'i' in [0x04..0xb4] */
118259f90a01SHans de Goede 		/* Scale 0 - 63 to 0x04 - 0xb4 */
1183d5d875cbSHans Verkuil 		i = 0x04 + val * 2794 / 1000;
118459f90a01SHans de Goede 		cit_model4_BrightnessPacket(gspca_dev, i);
11851f33de0fSHans de Goede 		break;
11861f33de0fSHans de Goede 	}
11871f33de0fSHans de Goede 
11881f33de0fSHans de Goede 	return 0;
11891f33de0fSHans de Goede }
11901f33de0fSHans de Goede 
1191d5d875cbSHans Verkuil static int cit_set_contrast(struct gspca_dev *gspca_dev, s32 val)
11921f33de0fSHans de Goede {
11931f33de0fSHans de Goede 	struct sd *sd = (struct sd *) gspca_dev;
11941f33de0fSHans de Goede 
11951f33de0fSHans de Goede 	switch (sd->model) {
1196659fefa0SHans de Goede 	case CIT_MODEL0: {
1197659fefa0SHans de Goede 		int i;
1198659fefa0SHans de Goede 		/* gain 0-15, 0-20 -> 0-15 */
1199d5d875cbSHans Verkuil 		i = val * 1000 / 1333;
1200659fefa0SHans de Goede 		cit_write_reg(gspca_dev, i, 0x0422);
1201659fefa0SHans de Goede 		/* gain 0-31, may not be lower then 0x0422, 0-20 -> 0-31 */
1202d5d875cbSHans Verkuil 		i = val * 2000 / 1333;
1203659fefa0SHans de Goede 		cit_write_reg(gspca_dev, i, 0x0423);
1204659fefa0SHans de Goede 		/* gain 0-127, may not be lower then 0x0423, 0-20 -> 0-63  */
1205d5d875cbSHans Verkuil 		i = val * 4000 / 1333;
1206659fefa0SHans de Goede 		cit_write_reg(gspca_dev, i, 0x0424);
1207659fefa0SHans de Goede 		/* gain 0-127, may not be lower then 0x0424, , 0-20 -> 0-127 */
1208d5d875cbSHans Verkuil 		i = val * 8000 / 1333;
1209659fefa0SHans de Goede 		cit_write_reg(gspca_dev, i, 0x0425);
1210659fefa0SHans de Goede 		break;
1211659fefa0SHans de Goede 	}
1212659fefa0SHans de Goede 	case CIT_MODEL2:
1213659fefa0SHans de Goede 	case CIT_MODEL4:
1214659fefa0SHans de Goede 		/* These models do not have this control. */
1215659fefa0SHans de Goede 		break;
121659f90a01SHans de Goede 	case CIT_MODEL1:
121759f90a01SHans de Goede 	{
121859f90a01SHans de Goede 		/* Scale 0 - 20 to 15 - 0 */
1219d5d875cbSHans Verkuil 		int i, new_contrast = (20 - val) * 1000 / 1333;
122059f90a01SHans de Goede 		for (i = 0; i < cit_model1_ntries; i++) {
122159f90a01SHans de Goede 			cit_Packet_Format1(gspca_dev, 0x0014, new_contrast);
122259f90a01SHans de Goede 			cit_send_FF_04_02(gspca_dev);
122359f90a01SHans de Goede 		}
122459f90a01SHans de Goede 		break;
122559f90a01SHans de Goede 	}
12261f33de0fSHans de Goede 	case CIT_MODEL3:
12271f33de0fSHans de Goede 	{	/* Preset hardware values */
12281f33de0fSHans de Goede 		static const struct {
12291f33de0fSHans de Goede 			unsigned short cv1;
12301f33de0fSHans de Goede 			unsigned short cv2;
12311f33de0fSHans de Goede 			unsigned short cv3;
12321f33de0fSHans de Goede 		} cv[7] = {
12331f33de0fSHans de Goede 			{ 0x05, 0x05, 0x0f },	/* Minimum */
12341f33de0fSHans de Goede 			{ 0x04, 0x04, 0x16 },
12351f33de0fSHans de Goede 			{ 0x02, 0x03, 0x16 },
12361f33de0fSHans de Goede 			{ 0x02, 0x08, 0x16 },
12371f33de0fSHans de Goede 			{ 0x01, 0x0c, 0x16 },
12381f33de0fSHans de Goede 			{ 0x01, 0x0e, 0x16 },
12391f33de0fSHans de Goede 			{ 0x01, 0x10, 0x16 }	/* Maximum */
12401f33de0fSHans de Goede 		};
1241d5d875cbSHans Verkuil 		int i = val / 3;
12421f33de0fSHans de Goede 		cit_model3_Packet1(gspca_dev, 0x0067, cv[i].cv1);
12431f33de0fSHans de Goede 		cit_model3_Packet1(gspca_dev, 0x005b, cv[i].cv2);
12441f33de0fSHans de Goede 		cit_model3_Packet1(gspca_dev, 0x005c, cv[i].cv3);
12451f33de0fSHans de Goede 		break;
12461f33de0fSHans de Goede 	}
12471f33de0fSHans de Goede 	case CIT_IBM_NETCAM_PRO:
1248d5d875cbSHans Verkuil 		cit_model3_Packet1(gspca_dev, 0x005b, val + 1);
12491f33de0fSHans de Goede 		break;
12501f33de0fSHans de Goede 	}
12511f33de0fSHans de Goede 	return 0;
12521f33de0fSHans de Goede }
12531f33de0fSHans de Goede 
1254d5d875cbSHans Verkuil static int cit_set_hue(struct gspca_dev *gspca_dev, s32 val)
12551f33de0fSHans de Goede {
12561f33de0fSHans de Goede 	struct sd *sd = (struct sd *) gspca_dev;
12571f33de0fSHans de Goede 
12581f33de0fSHans de Goede 	switch (sd->model) {
1259659fefa0SHans de Goede 	case CIT_MODEL0:
126059f90a01SHans de Goede 	case CIT_MODEL1:
1261659fefa0SHans de Goede 	case CIT_IBM_NETCAM_PRO:
1262659fefa0SHans de Goede 		/* No hue control for these models */
126359f90a01SHans de Goede 		break;
126459f90a01SHans de Goede 	case CIT_MODEL2:
1265d5d875cbSHans Verkuil 		cit_model2_Packet1(gspca_dev, 0x0024, val);
126659f90a01SHans de Goede 		/* cit_model2_Packet1(gspca_dev, 0x0020, sat); */
126759f90a01SHans de Goede 		break;
126859f90a01SHans de Goede 	case CIT_MODEL3: {
126959f90a01SHans de Goede 		/* Model 3: Brightness range 'i' in [0x05..0x37] */
127059f90a01SHans de Goede 		/* TESTME according to the ibmcam driver this does not work */
127159f90a01SHans de Goede 		if (0) {
127259f90a01SHans de Goede 			/* Scale 0 - 127 to 0x05 - 0x37 */
1273d5d875cbSHans Verkuil 			int i = 0x05 + val * 1000 / 2540;
127459f90a01SHans de Goede 			cit_model3_Packet1(gspca_dev, 0x007e, i);
127559f90a01SHans de Goede 		}
127659f90a01SHans de Goede 		break;
127759f90a01SHans de Goede 	}
127859f90a01SHans de Goede 	case CIT_MODEL4:
127959f90a01SHans de Goede 		/* HDG: taken from ibmcam, setting the color gains does not
128059f90a01SHans de Goede 		 * really belong here.
128159f90a01SHans de Goede 		 *
128259f90a01SHans de Goede 		 * I am not sure r/g/b_gain variables exactly control gain
128359f90a01SHans de Goede 		 * of those channels. Most likely they subtly change some
128459f90a01SHans de Goede 		 * very internal image processing settings in the camera.
128559f90a01SHans de Goede 		 * In any case, here is what they do, and feel free to tweak:
128659f90a01SHans de Goede 		 *
128759f90a01SHans de Goede 		 * r_gain: seriously affects red gain
128859f90a01SHans de Goede 		 * g_gain: seriously affects green gain
128959f90a01SHans de Goede 		 * b_gain: seriously affects blue gain
129059f90a01SHans de Goede 		 * hue: changes average color from violet (0) to red (0xFF)
129159f90a01SHans de Goede 		 */
129259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
129359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x001e, 0x012f);
129459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd141, 0x0124);
129559f90a01SHans de Goede 		cit_write_reg(gspca_dev,    160, 0x0127);  /* Green gain */
129659f90a01SHans de Goede 		cit_write_reg(gspca_dev,    160, 0x012e);  /* Red gain */
129759f90a01SHans de Goede 		cit_write_reg(gspca_dev,    160, 0x0130);  /* Blue gain */
129859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x8a28, 0x0124);
1299d5d875cbSHans Verkuil 		cit_write_reg(gspca_dev, val, 0x012d); /* Hue */
130059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xf545, 0x0124);
13011f33de0fSHans de Goede 		break;
13021f33de0fSHans de Goede 	}
13031f33de0fSHans de Goede 	return 0;
13041f33de0fSHans de Goede }
13051f33de0fSHans de Goede 
1306d5d875cbSHans Verkuil static int cit_set_sharpness(struct gspca_dev *gspca_dev, s32 val)
13071f33de0fSHans de Goede {
13081f33de0fSHans de Goede 	struct sd *sd = (struct sd *) gspca_dev;
13091f33de0fSHans de Goede 
13101f33de0fSHans de Goede 	switch (sd->model) {
1311659fefa0SHans de Goede 	case CIT_MODEL0:
1312659fefa0SHans de Goede 	case CIT_MODEL2:
1313659fefa0SHans de Goede 	case CIT_MODEL4:
1314659fefa0SHans de Goede 	case CIT_IBM_NETCAM_PRO:
1315659fefa0SHans de Goede 		/* These models do not have this control */
1316659fefa0SHans de Goede 		break;
131759f90a01SHans de Goede 	case CIT_MODEL1: {
131859f90a01SHans de Goede 		int i;
1319d4a06464SColin Ian King 		static const unsigned short sa[] = {
132059f90a01SHans de Goede 			0x11, 0x13, 0x16, 0x18, 0x1a, 0x8, 0x0a };
132159f90a01SHans de Goede 
132259f90a01SHans de Goede 		for (i = 0; i < cit_model1_ntries; i++)
1323d5d875cbSHans Verkuil 			cit_PacketFormat2(gspca_dev, 0x0013, sa[val]);
132459f90a01SHans de Goede 		break;
132559f90a01SHans de Goede 	}
13261f33de0fSHans de Goede 	case CIT_MODEL3:
13271f33de0fSHans de Goede 	{	/*
13281f33de0fSHans de Goede 		 * "Use a table of magic numbers.
13291f33de0fSHans de Goede 		 *  This setting doesn't really change much.
13301f33de0fSHans de Goede 		 *  But that's how Windows does it."
13311f33de0fSHans de Goede 		 */
13321f33de0fSHans de Goede 		static const struct {
13331f33de0fSHans de Goede 			unsigned short sv1;
13341f33de0fSHans de Goede 			unsigned short sv2;
13351f33de0fSHans de Goede 			unsigned short sv3;
13361f33de0fSHans de Goede 			unsigned short sv4;
13371f33de0fSHans de Goede 		} sv[7] = {
13381f33de0fSHans de Goede 			{ 0x00, 0x00, 0x05, 0x14 },	/* Smoothest */
13391f33de0fSHans de Goede 			{ 0x01, 0x04, 0x05, 0x14 },
13401f33de0fSHans de Goede 			{ 0x02, 0x04, 0x05, 0x14 },
13411f33de0fSHans de Goede 			{ 0x03, 0x04, 0x05, 0x14 },
13421f33de0fSHans de Goede 			{ 0x03, 0x05, 0x05, 0x14 },
13431f33de0fSHans de Goede 			{ 0x03, 0x06, 0x05, 0x14 },
13441f33de0fSHans de Goede 			{ 0x03, 0x07, 0x05, 0x14 }	/* Sharpest */
13451f33de0fSHans de Goede 		};
1346d5d875cbSHans Verkuil 		cit_model3_Packet1(gspca_dev, 0x0060, sv[val].sv1);
1347d5d875cbSHans Verkuil 		cit_model3_Packet1(gspca_dev, 0x0061, sv[val].sv2);
1348d5d875cbSHans Verkuil 		cit_model3_Packet1(gspca_dev, 0x0062, sv[val].sv3);
1349d5d875cbSHans Verkuil 		cit_model3_Packet1(gspca_dev, 0x0063, sv[val].sv4);
13501f33de0fSHans de Goede 		break;
13511f33de0fSHans de Goede 	}
13521f33de0fSHans de Goede 	}
13531f33de0fSHans de Goede 	return 0;
13541f33de0fSHans de Goede }
13551f33de0fSHans de Goede 
135659f90a01SHans de Goede /*
135759f90a01SHans de Goede  * cit_set_lighting()
135859f90a01SHans de Goede  *
135959f90a01SHans de Goede  * Camera model 1:
136059f90a01SHans de Goede  * We have 3 levels of lighting conditions: 0=Bright, 1=Medium, 2=Low.
136159f90a01SHans de Goede  *
136259f90a01SHans de Goede  * Camera model 2:
136359f90a01SHans de Goede  * We have 16 levels of lighting, 0 for bright light and up to 15 for
136459f90a01SHans de Goede  * low light. But values above 5 or so are useless because camera is
136559f90a01SHans de Goede  * not really capable to produce anything worth viewing at such light.
136659f90a01SHans de Goede  * This setting may be altered only in certain camera state.
136759f90a01SHans de Goede  *
136859f90a01SHans de Goede  * Low lighting forces slower FPS.
136959f90a01SHans de Goede  *
137059f90a01SHans de Goede  * History:
137159f90a01SHans de Goede  * 1/5/00   Created.
137259f90a01SHans de Goede  * 2/20/00  Added support for Model 2 cameras.
137359f90a01SHans de Goede  */
1374d5d875cbSHans Verkuil static void cit_set_lighting(struct gspca_dev *gspca_dev, s32 val)
137559f90a01SHans de Goede {
137659f90a01SHans de Goede 	struct sd *sd = (struct sd *) gspca_dev;
137759f90a01SHans de Goede 
137859f90a01SHans de Goede 	switch (sd->model) {
1379659fefa0SHans de Goede 	case CIT_MODEL0:
1380659fefa0SHans de Goede 	case CIT_MODEL2:
1381659fefa0SHans de Goede 	case CIT_MODEL3:
1382659fefa0SHans de Goede 	case CIT_MODEL4:
1383659fefa0SHans de Goede 	case CIT_IBM_NETCAM_PRO:
1384659fefa0SHans de Goede 		break;
138559f90a01SHans de Goede 	case CIT_MODEL1: {
138659f90a01SHans de Goede 		int i;
138759f90a01SHans de Goede 		for (i = 0; i < cit_model1_ntries; i++)
1388d5d875cbSHans Verkuil 			cit_Packet_Format1(gspca_dev, 0x0027, val);
138959f90a01SHans de Goede 		break;
139059f90a01SHans de Goede 	}
1391659fefa0SHans de Goede 	}
1392659fefa0SHans de Goede }
1393659fefa0SHans de Goede 
1394d5d875cbSHans Verkuil static void cit_set_hflip(struct gspca_dev *gspca_dev, s32 val)
1395659fefa0SHans de Goede {
1396659fefa0SHans de Goede 	struct sd *sd = (struct sd *) gspca_dev;
1397659fefa0SHans de Goede 
1398659fefa0SHans de Goede 	switch (sd->model) {
1399659fefa0SHans de Goede 	case CIT_MODEL0:
1400d5d875cbSHans Verkuil 		if (val)
1401659fefa0SHans de Goede 			cit_write_reg(gspca_dev, 0x0020, 0x0115);
1402659fefa0SHans de Goede 		else
1403659fefa0SHans de Goede 			cit_write_reg(gspca_dev, 0x0040, 0x0115);
1404659fefa0SHans de Goede 		break;
1405659fefa0SHans de Goede 	case CIT_MODEL1:
140659f90a01SHans de Goede 	case CIT_MODEL2:
140759f90a01SHans de Goede 	case CIT_MODEL3:
140859f90a01SHans de Goede 	case CIT_MODEL4:
140959f90a01SHans de Goede 	case CIT_IBM_NETCAM_PRO:
141059f90a01SHans de Goede 		break;
141159f90a01SHans de Goede 	}
141259f90a01SHans de Goede }
141359f90a01SHans de Goede 
14141f33de0fSHans de Goede static int cit_restart_stream(struct gspca_dev *gspca_dev)
14151f33de0fSHans de Goede {
14161f33de0fSHans de Goede 	struct sd *sd = (struct sd *) gspca_dev;
14171f33de0fSHans de Goede 
14181f33de0fSHans de Goede 	switch (sd->model) {
1419659fefa0SHans de Goede 	case CIT_MODEL0:
142059f90a01SHans de Goede 	case CIT_MODEL1:
14211f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0001, 0x0114);
142259f90a01SHans de Goede 		/* Fall through */
142359f90a01SHans de Goede 	case CIT_MODEL2:
142459f90a01SHans de Goede 	case CIT_MODEL4:
14251f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x00c0, 0x010c); /* Go! */
14261f33de0fSHans de Goede 		usb_clear_halt(gspca_dev->dev, gspca_dev->urb[0]->pipe);
1427e0657be5SHans de Goede 		break;
1428e0657be5SHans de Goede 	case CIT_MODEL3:
1429e0657be5SHans de Goede 	case CIT_IBM_NETCAM_PRO:
1430e0657be5SHans de Goede 		cit_write_reg(gspca_dev, 0x0001, 0x0114);
1431e0657be5SHans de Goede 		cit_write_reg(gspca_dev, 0x00c0, 0x010c); /* Go! */
1432e0657be5SHans de Goede 		usb_clear_halt(gspca_dev->dev, gspca_dev->urb[0]->pipe);
1433e0657be5SHans de Goede 		/* Clear button events from while we were not streaming */
1434e0657be5SHans de Goede 		cit_write_reg(gspca_dev, 0x0001, 0x0113);
143559f90a01SHans de Goede 		break;
14361f33de0fSHans de Goede 	}
14371f33de0fSHans de Goede 
14381f33de0fSHans de Goede 	sd->sof_read = 0;
14391f33de0fSHans de Goede 
14401f33de0fSHans de Goede 	return 0;
14411f33de0fSHans de Goede }
14421f33de0fSHans de Goede 
1443659fefa0SHans de Goede static int cit_get_packet_size(struct gspca_dev *gspca_dev)
1444659fefa0SHans de Goede {
1445659fefa0SHans de Goede 	struct usb_host_interface *alt;
1446659fefa0SHans de Goede 	struct usb_interface *intf;
1447659fefa0SHans de Goede 
1448659fefa0SHans de Goede 	intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface);
1449659fefa0SHans de Goede 	alt = usb_altnum_to_altsetting(intf, gspca_dev->alt);
1450659fefa0SHans de Goede 	if (!alt) {
1451133a9fe9SJoe Perches 		pr_err("Couldn't get altsetting\n");
1452659fefa0SHans de Goede 		return -EIO;
1453659fefa0SHans de Goede 	}
1454659fefa0SHans de Goede 
1455659fefa0SHans de Goede 	return le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
1456659fefa0SHans de Goede }
1457659fefa0SHans de Goede 
145841f424baSHans de Goede /* Calculate the clockdiv giving us max fps given the available bandwidth */
145941f424baSHans de Goede static int cit_get_clock_div(struct gspca_dev *gspca_dev)
1460659fefa0SHans de Goede {
1461659fefa0SHans de Goede 	int clock_div = 7; /* 0=30 1=25 2=20 3=15 4=12 5=7.5 6=6 7=3fps ?? */
1462659fefa0SHans de Goede 	int fps[8] = { 30, 25, 20, 15, 12, 8, 6, 3 };
1463659fefa0SHans de Goede 	int packet_size;
1464659fefa0SHans de Goede 
1465659fefa0SHans de Goede 	packet_size = cit_get_packet_size(gspca_dev);
1466659fefa0SHans de Goede 	if (packet_size < 0)
1467659fefa0SHans de Goede 		return packet_size;
1468659fefa0SHans de Goede 
1469659fefa0SHans de Goede 	while (clock_div > 3 &&
1470659fefa0SHans de Goede 			1000 * packet_size >
14711966bc2aSOndrej Zary 			gspca_dev->pixfmt.width * gspca_dev->pixfmt.height *
1472659fefa0SHans de Goede 			fps[clock_div - 1] * 3 / 2)
1473659fefa0SHans de Goede 		clock_div--;
1474659fefa0SHans de Goede 
1475*37d5efb0SJoe Perches 	gspca_dbg(gspca_dev, D_PROBE,
1476*37d5efb0SJoe Perches 		  "PacketSize: %d, res: %dx%d -> using clockdiv: %d (%d fps)\n",
1477*37d5efb0SJoe Perches 		  packet_size,
1478*37d5efb0SJoe Perches 		  gspca_dev->pixfmt.width, gspca_dev->pixfmt.height,
14791966bc2aSOndrej Zary 		  clock_div, fps[clock_div]);
148041f424baSHans de Goede 
148141f424baSHans de Goede 	return clock_div;
148241f424baSHans de Goede }
148341f424baSHans de Goede 
148441f424baSHans de Goede static int cit_start_model0(struct gspca_dev *gspca_dev)
148541f424baSHans de Goede {
148641f424baSHans de Goede 	const unsigned short compression = 0; /* 0=none, 7=best frame rate */
148741f424baSHans de Goede 	int clock_div;
148841f424baSHans de Goede 
148941f424baSHans de Goede 	clock_div = cit_get_clock_div(gspca_dev);
149041f424baSHans de Goede 	if (clock_div < 0)
149141f424baSHans de Goede 		return clock_div;
149241f424baSHans de Goede 
1493659fefa0SHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0100); /* turn on led */
1494659fefa0SHans de Goede 	cit_write_reg(gspca_dev, 0x0003, 0x0438);
1495659fefa0SHans de Goede 	cit_write_reg(gspca_dev, 0x001e, 0x042b);
1496659fefa0SHans de Goede 	cit_write_reg(gspca_dev, 0x0041, 0x042c);
1497659fefa0SHans de Goede 	cit_write_reg(gspca_dev, 0x0008, 0x0436);
1498659fefa0SHans de Goede 	cit_write_reg(gspca_dev, 0x0024, 0x0403);
1499659fefa0SHans de Goede 	cit_write_reg(gspca_dev, 0x002c, 0x0404);
1500659fefa0SHans de Goede 	cit_write_reg(gspca_dev, 0x0002, 0x0426);
1501659fefa0SHans de Goede 	cit_write_reg(gspca_dev, 0x0014, 0x0427);
1502659fefa0SHans de Goede 
15031966bc2aSOndrej Zary 	switch (gspca_dev->pixfmt.width) {
1504659fefa0SHans de Goede 	case 160: /* 160x120 */
1505659fefa0SHans de Goede 		cit_write_reg(gspca_dev, 0x0004, 0x010b);
1506659fefa0SHans de Goede 		cit_write_reg(gspca_dev, 0x0001, 0x010a);
1507659fefa0SHans de Goede 		cit_write_reg(gspca_dev, 0x0010, 0x0102);
1508659fefa0SHans de Goede 		cit_write_reg(gspca_dev, 0x00a0, 0x0103);
1509659fefa0SHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0104);
1510659fefa0SHans de Goede 		cit_write_reg(gspca_dev, 0x0078, 0x0105);
1511659fefa0SHans de Goede 		break;
1512659fefa0SHans de Goede 
1513659fefa0SHans de Goede 	case 176: /* 176x144 */
1514659fefa0SHans de Goede 		cit_write_reg(gspca_dev, 0x0006, 0x010b);
1515659fefa0SHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x010a);
1516659fefa0SHans de Goede 		cit_write_reg(gspca_dev, 0x0005, 0x0102);
1517659fefa0SHans de Goede 		cit_write_reg(gspca_dev, 0x00b0, 0x0103);
1518659fefa0SHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0104);
1519659fefa0SHans de Goede 		cit_write_reg(gspca_dev, 0x0090, 0x0105);
1520659fefa0SHans de Goede 		break;
1521659fefa0SHans de Goede 
1522659fefa0SHans de Goede 	case 320: /* 320x240 */
1523659fefa0SHans de Goede 		cit_write_reg(gspca_dev, 0x0008, 0x010b);
1524659fefa0SHans de Goede 		cit_write_reg(gspca_dev, 0x0004, 0x010a);
1525659fefa0SHans de Goede 		cit_write_reg(gspca_dev, 0x0005, 0x0102);
1526659fefa0SHans de Goede 		cit_write_reg(gspca_dev, 0x00a0, 0x0103);
1527659fefa0SHans de Goede 		cit_write_reg(gspca_dev, 0x0010, 0x0104);
1528659fefa0SHans de Goede 		cit_write_reg(gspca_dev, 0x0078, 0x0105);
1529659fefa0SHans de Goede 		break;
1530659fefa0SHans de Goede 	}
1531659fefa0SHans de Goede 
1532659fefa0SHans de Goede 	cit_write_reg(gspca_dev, compression, 0x0109);
1533659fefa0SHans de Goede 	cit_write_reg(gspca_dev, clock_div, 0x0111);
1534659fefa0SHans de Goede 
1535659fefa0SHans de Goede 	return 0;
1536659fefa0SHans de Goede }
1537659fefa0SHans de Goede 
153859f90a01SHans de Goede static int cit_start_model1(struct gspca_dev *gspca_dev)
153959f90a01SHans de Goede {
154059f90a01SHans de Goede 	struct sd *sd = (struct sd *) gspca_dev;
154141f424baSHans de Goede 	int i, clock_div;
154255c1b7d3SHans de Goede 
154341f424baSHans de Goede 	clock_div = cit_get_clock_div(gspca_dev);
154441f424baSHans de Goede 	if (clock_div < 0)
154541f424baSHans de Goede 		return clock_div;
154659f90a01SHans de Goede 
1547e0657be5SHans de Goede 	cit_read_reg(gspca_dev, 0x0128, 1);
1548e0657be5SHans de Goede 	cit_read_reg(gspca_dev, 0x0100, 0);
154959f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x01, 0x0100);	/* LED On  */
1550e0657be5SHans de Goede 	cit_read_reg(gspca_dev, 0x0100, 0);
155159f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x81, 0x0100);	/* LED Off */
1552e0657be5SHans de Goede 	cit_read_reg(gspca_dev, 0x0100, 0);
155359f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x01, 0x0100);	/* LED On  */
155459f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x01, 0x0108);
155559f90a01SHans de Goede 
155659f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x03, 0x0112);
1557e0657be5SHans de Goede 	cit_read_reg(gspca_dev, 0x0115, 0);
155859f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x06, 0x0115);
1559e0657be5SHans de Goede 	cit_read_reg(gspca_dev, 0x0116, 0);
156059f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x44, 0x0116);
1561e0657be5SHans de Goede 	cit_read_reg(gspca_dev, 0x0116, 0);
156259f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x40, 0x0116);
1563e0657be5SHans de Goede 	cit_read_reg(gspca_dev, 0x0115, 0);
156459f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0e, 0x0115);
156559f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x19, 0x012c);
156659f90a01SHans de Goede 
156759f90a01SHans de Goede 	cit_Packet_Format1(gspca_dev, 0x00, 0x1e);
156859f90a01SHans de Goede 	cit_Packet_Format1(gspca_dev, 0x39, 0x0d);
156959f90a01SHans de Goede 	cit_Packet_Format1(gspca_dev, 0x39, 0x09);
157059f90a01SHans de Goede 	cit_Packet_Format1(gspca_dev, 0x3b, 0x00);
157159f90a01SHans de Goede 	cit_Packet_Format1(gspca_dev, 0x28, 0x22);
157259f90a01SHans de Goede 	cit_Packet_Format1(gspca_dev, 0x27, 0x00);
157359f90a01SHans de Goede 	cit_Packet_Format1(gspca_dev, 0x2b, 0x1f);
157459f90a01SHans de Goede 	cit_Packet_Format1(gspca_dev, 0x39, 0x08);
157559f90a01SHans de Goede 
157659f90a01SHans de Goede 	for (i = 0; i < cit_model1_ntries; i++)
157759f90a01SHans de Goede 		cit_Packet_Format1(gspca_dev, 0x2c, 0x00);
157859f90a01SHans de Goede 
157959f90a01SHans de Goede 	for (i = 0; i < cit_model1_ntries; i++)
158059f90a01SHans de Goede 		cit_Packet_Format1(gspca_dev, 0x30, 0x14);
158159f90a01SHans de Goede 
158259f90a01SHans de Goede 	cit_PacketFormat2(gspca_dev, 0x39, 0x02);
158359f90a01SHans de Goede 	cit_PacketFormat2(gspca_dev, 0x01, 0xe1);
158459f90a01SHans de Goede 	cit_PacketFormat2(gspca_dev, 0x02, 0xcd);
158559f90a01SHans de Goede 	cit_PacketFormat2(gspca_dev, 0x03, 0xcd);
158659f90a01SHans de Goede 	cit_PacketFormat2(gspca_dev, 0x04, 0xfa);
158759f90a01SHans de Goede 	cit_PacketFormat2(gspca_dev, 0x3f, 0xff);
158859f90a01SHans de Goede 	cit_PacketFormat2(gspca_dev, 0x39, 0x00);
158959f90a01SHans de Goede 
159059f90a01SHans de Goede 	cit_PacketFormat2(gspca_dev, 0x39, 0x02);
159159f90a01SHans de Goede 	cit_PacketFormat2(gspca_dev, 0x0a, 0x37);
159259f90a01SHans de Goede 	cit_PacketFormat2(gspca_dev, 0x0b, 0xb8);
159359f90a01SHans de Goede 	cit_PacketFormat2(gspca_dev, 0x0c, 0xf3);
159459f90a01SHans de Goede 	cit_PacketFormat2(gspca_dev, 0x0d, 0xe3);
159559f90a01SHans de Goede 	cit_PacketFormat2(gspca_dev, 0x0e, 0x0d);
159659f90a01SHans de Goede 	cit_PacketFormat2(gspca_dev, 0x0f, 0xf2);
159759f90a01SHans de Goede 	cit_PacketFormat2(gspca_dev, 0x10, 0xd5);
159859f90a01SHans de Goede 	cit_PacketFormat2(gspca_dev, 0x11, 0xba);
159959f90a01SHans de Goede 	cit_PacketFormat2(gspca_dev, 0x12, 0x53);
160059f90a01SHans de Goede 	cit_PacketFormat2(gspca_dev, 0x3f, 0xff);
160159f90a01SHans de Goede 	cit_PacketFormat2(gspca_dev, 0x39, 0x00);
160259f90a01SHans de Goede 
160359f90a01SHans de Goede 	cit_PacketFormat2(gspca_dev, 0x39, 0x02);
160459f90a01SHans de Goede 	cit_PacketFormat2(gspca_dev, 0x16, 0x00);
160559f90a01SHans de Goede 	cit_PacketFormat2(gspca_dev, 0x17, 0x28);
160659f90a01SHans de Goede 	cit_PacketFormat2(gspca_dev, 0x18, 0x7d);
160759f90a01SHans de Goede 	cit_PacketFormat2(gspca_dev, 0x19, 0xbe);
160859f90a01SHans de Goede 	cit_PacketFormat2(gspca_dev, 0x3f, 0xff);
160959f90a01SHans de Goede 	cit_PacketFormat2(gspca_dev, 0x39, 0x00);
161059f90a01SHans de Goede 
161159f90a01SHans de Goede 	for (i = 0; i < cit_model1_ntries; i++)
161259f90a01SHans de Goede 		cit_Packet_Format1(gspca_dev, 0x00, 0x18);
161359f90a01SHans de Goede 	for (i = 0; i < cit_model1_ntries; i++)
161459f90a01SHans de Goede 		cit_Packet_Format1(gspca_dev, 0x13, 0x18);
161559f90a01SHans de Goede 	for (i = 0; i < cit_model1_ntries; i++)
161659f90a01SHans de Goede 		cit_Packet_Format1(gspca_dev, 0x14, 0x06);
161759f90a01SHans de Goede 
161859f90a01SHans de Goede 	/* TESTME These are handled through controls
161959f90a01SHans de Goede 	   KEEP until someone can test leaving this out is ok */
162059f90a01SHans de Goede 	if (0) {
162159f90a01SHans de Goede 		/* This is default brightness */
162259f90a01SHans de Goede 		for (i = 0; i < cit_model1_ntries; i++)
162359f90a01SHans de Goede 			cit_Packet_Format1(gspca_dev, 0x31, 0x37);
162459f90a01SHans de Goede 		for (i = 0; i < cit_model1_ntries; i++)
162559f90a01SHans de Goede 			cit_Packet_Format1(gspca_dev, 0x32, 0x46);
162659f90a01SHans de Goede 		for (i = 0; i < cit_model1_ntries; i++)
162759f90a01SHans de Goede 			cit_Packet_Format1(gspca_dev, 0x33, 0x55);
162859f90a01SHans de Goede 	}
162959f90a01SHans de Goede 
163059f90a01SHans de Goede 	cit_Packet_Format1(gspca_dev, 0x2e, 0x04);
163159f90a01SHans de Goede 	for (i = 0; i < cit_model1_ntries; i++)
163259f90a01SHans de Goede 		cit_Packet_Format1(gspca_dev, 0x2d, 0x04);
163359f90a01SHans de Goede 	for (i = 0; i < cit_model1_ntries; i++)
163459f90a01SHans de Goede 		cit_Packet_Format1(gspca_dev, 0x29, 0x80);
163559f90a01SHans de Goede 	cit_Packet_Format1(gspca_dev, 0x2c, 0x01);
163659f90a01SHans de Goede 	cit_Packet_Format1(gspca_dev, 0x30, 0x17);
163759f90a01SHans de Goede 	cit_Packet_Format1(gspca_dev, 0x39, 0x08);
163859f90a01SHans de Goede 	for (i = 0; i < cit_model1_ntries; i++)
163959f90a01SHans de Goede 		cit_Packet_Format1(gspca_dev, 0x34, 0x00);
164059f90a01SHans de Goede 
164159f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x00, 0x0101);
164259f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x00, 0x010a);
164359f90a01SHans de Goede 
16441966bc2aSOndrej Zary 	switch (gspca_dev->pixfmt.width) {
164559f90a01SHans de Goede 	case 128: /* 128x96 */
164659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x80, 0x0103);
164759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x60, 0x0105);
164859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0c, 0x010b);
164959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x04, 0x011b);	/* Same everywhere */
165059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0b, 0x011d);
165159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00, 0x011e);	/* Same everywhere */
165259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00, 0x0129);
165359f90a01SHans de Goede 		break;
165459f90a01SHans de Goede 	case 176: /* 176x144 */
165559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xb0, 0x0103);
165659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x8f, 0x0105);
165759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x06, 0x010b);
165859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x04, 0x011b);	/* Same everywhere */
165959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0d, 0x011d);
166059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00, 0x011e);	/* Same everywhere */
166159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x03, 0x0129);
166259f90a01SHans de Goede 		break;
166359f90a01SHans de Goede 	case 352: /* 352x288 */
166459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xb0, 0x0103);
166559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x90, 0x0105);
166659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x02, 0x010b);
166759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x04, 0x011b);	/* Same everywhere */
166859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x05, 0x011d);
166959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00, 0x011e);	/* Same everywhere */
167059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00, 0x0129);
167159f90a01SHans de Goede 		break;
167259f90a01SHans de Goede 	}
167359f90a01SHans de Goede 
167459f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0xff, 0x012b);
167559f90a01SHans de Goede 
167659f90a01SHans de Goede 	/* TESTME These are handled through controls
167759f90a01SHans de Goede 	   KEEP until someone can test leaving this out is ok */
167859f90a01SHans de Goede 	if (0) {
167959f90a01SHans de Goede 		/* This is another brightness - don't know why */
168059f90a01SHans de Goede 		for (i = 0; i < cit_model1_ntries; i++)
168159f90a01SHans de Goede 			cit_Packet_Format1(gspca_dev, 0x31, 0xc3);
168259f90a01SHans de Goede 		for (i = 0; i < cit_model1_ntries; i++)
168359f90a01SHans de Goede 			cit_Packet_Format1(gspca_dev, 0x32, 0xd2);
168459f90a01SHans de Goede 		for (i = 0; i < cit_model1_ntries; i++)
168559f90a01SHans de Goede 			cit_Packet_Format1(gspca_dev, 0x33, 0xe1);
168659f90a01SHans de Goede 
168759f90a01SHans de Goede 		/* Default contrast */
168859f90a01SHans de Goede 		for (i = 0; i < cit_model1_ntries; i++)
168959f90a01SHans de Goede 			cit_Packet_Format1(gspca_dev, 0x14, 0x0a);
169059f90a01SHans de Goede 
169159f90a01SHans de Goede 		/* Default sharpness */
169259f90a01SHans de Goede 		for (i = 0; i < cit_model1_ntries2; i++)
169359f90a01SHans de Goede 			cit_PacketFormat2(gspca_dev, 0x13, 0x1a);
169459f90a01SHans de Goede 
169559f90a01SHans de Goede 		/* Default lighting conditions */
1696d5d875cbSHans Verkuil 		cit_Packet_Format1(gspca_dev, 0x0027,
1697d5d875cbSHans Verkuil 				   v4l2_ctrl_g_ctrl(sd->lighting));
169859f90a01SHans de Goede 	}
169959f90a01SHans de Goede 
170059f90a01SHans de Goede 	/* Assorted init */
17011966bc2aSOndrej Zary 	switch (gspca_dev->pixfmt.width) {
170259f90a01SHans de Goede 	case 128: /* 128x96 */
170359f90a01SHans de Goede 		cit_Packet_Format1(gspca_dev, 0x2b, 0x1e);
170459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xc9, 0x0119);	/* Same everywhere */
170559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x80, 0x0109);	/* Same everywhere */
170659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x36, 0x0102);
170759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x1a, 0x0104);
170859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x04, 0x011a);	/* Same everywhere */
170959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x2b, 0x011c);
171059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x23, 0x012a);	/* Same everywhere */
171159f90a01SHans de Goede 		break;
171259f90a01SHans de Goede 	case 176: /* 176x144 */
171359f90a01SHans de Goede 		cit_Packet_Format1(gspca_dev, 0x2b, 0x1e);
171459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xc9, 0x0119);	/* Same everywhere */
171559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x80, 0x0109);	/* Same everywhere */
171659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x04, 0x0102);
171759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x02, 0x0104);
171859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x04, 0x011a);	/* Same everywhere */
171959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x2b, 0x011c);
172059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x23, 0x012a);	/* Same everywhere */
172159f90a01SHans de Goede 		break;
172259f90a01SHans de Goede 	case 352: /* 352x288 */
172359f90a01SHans de Goede 		cit_Packet_Format1(gspca_dev, 0x2b, 0x1f);
172459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xc9, 0x0119);	/* Same everywhere */
172559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x80, 0x0109);	/* Same everywhere */
172659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x08, 0x0102);
172759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x01, 0x0104);
172859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x04, 0x011a);	/* Same everywhere */
172959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x2f, 0x011c);
173059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x23, 0x012a);	/* Same everywhere */
173159f90a01SHans de Goede 		break;
173259f90a01SHans de Goede 	}
173359f90a01SHans de Goede 
173459f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x01, 0x0100);	/* LED On  */
173559f90a01SHans de Goede 	cit_write_reg(gspca_dev, clock_div, 0x0111);
173659f90a01SHans de Goede 
173759f90a01SHans de Goede 	return 0;
173859f90a01SHans de Goede }
173959f90a01SHans de Goede 
174059f90a01SHans de Goede static int cit_start_model2(struct gspca_dev *gspca_dev)
174159f90a01SHans de Goede {
174259f90a01SHans de Goede 	struct sd *sd = (struct sd *) gspca_dev;
174359f90a01SHans de Goede 	int clock_div = 0;
174459f90a01SHans de Goede 
174559f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0100);	/* LED on */
1746e0657be5SHans de Goede 	cit_read_reg(gspca_dev, 0x0116, 0);
174759f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0060, 0x0116);
174859f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0002, 0x0112);
174959f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x00bc, 0x012c);
175059f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0008, 0x012b);
175159f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0108);
175259f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0001, 0x0133);
175359f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0001, 0x0102);
17541966bc2aSOndrej Zary 	switch (gspca_dev->pixfmt.width) {
175559f90a01SHans de Goede 	case 176: /* 176x144 */
175659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x002c, 0x0103);	/* All except 320x240 */
175759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0104);	/* Same */
175859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0024, 0x0105);	/* 176x144, 352x288 */
175959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00b9, 0x010a);	/* Unique to this mode */
176059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0038, 0x0119);	/* Unique to this mode */
176159f90a01SHans de Goede 		/* TESTME HDG: this does not seem right
176259f90a01SHans de Goede 		   (it is 2 for all other resolutions) */
176359f90a01SHans de Goede 		sd->sof_len = 10;
176459f90a01SHans de Goede 		break;
176559f90a01SHans de Goede 	case 320: /* 320x240 */
176659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0028, 0x0103);	/* Unique to this mode */
176759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0104);	/* Same */
176859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x001e, 0x0105);	/* 320x240, 352x240 */
176959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0039, 0x010a);	/* All except 176x144 */
177059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0070, 0x0119);	/* All except 176x144 */
177159f90a01SHans de Goede 		sd->sof_len = 2;
177259f90a01SHans de Goede 		break;
1773cd65d24eSMauro Carvalho Chehab #if 0
1774cd65d24eSMauro Carvalho Chehab 	case VIDEOSIZE_352x240:
177559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x002c, 0x0103);	/* All except 320x240 */
177659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0104);	/* Same */
177759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x001e, 0x0105);	/* 320x240, 352x240 */
177859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0039, 0x010a);	/* All except 176x144 */
177959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0070, 0x0119);	/* All except 176x144 */
178059f90a01SHans de Goede 		sd->sof_len = 2;
178159f90a01SHans de Goede 		break;
1782cd65d24eSMauro Carvalho Chehab #endif
178359f90a01SHans de Goede 	case 352: /* 352x288 */
178459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x002c, 0x0103);	/* All except 320x240 */
178559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0104);	/* Same */
178659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0024, 0x0105);	/* 176x144, 352x288 */
178759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0039, 0x010a);	/* All except 176x144 */
178859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0070, 0x0119);	/* All except 176x144 */
178959f90a01SHans de Goede 		sd->sof_len = 2;
179059f90a01SHans de Goede 		break;
179159f90a01SHans de Goede 	}
179259f90a01SHans de Goede 
179359f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0100);	/* LED on */
179459f90a01SHans de Goede 
17951966bc2aSOndrej Zary 	switch (gspca_dev->pixfmt.width) {
179659f90a01SHans de Goede 	case 176: /* 176x144 */
179759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0050, 0x0111);
179859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00d0, 0x0111);
179959f90a01SHans de Goede 		break;
180059f90a01SHans de Goede 	case 320: /* 320x240 */
180159f90a01SHans de Goede 	case 352: /* 352x288 */
180259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0040, 0x0111);
180359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00c0, 0x0111);
180459f90a01SHans de Goede 		break;
180559f90a01SHans de Goede 	}
180659f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x009b, 0x010f);
180759f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x00bb, 0x010f);
180859f90a01SHans de Goede 
180959f90a01SHans de Goede 	/*
181059f90a01SHans de Goede 	 * Hardware settings, may affect CMOS sensor; not user controls!
181159f90a01SHans de Goede 	 * -------------------------------------------------------------
181259f90a01SHans de Goede 	 * 0x0004: no effect
181359f90a01SHans de Goede 	 * 0x0006: hardware effect
181459f90a01SHans de Goede 	 * 0x0008: no effect
181559f90a01SHans de Goede 	 * 0x000a: stops video stream, probably important h/w setting
181659f90a01SHans de Goede 	 * 0x000c: changes color in hardware manner (not user setting)
181759f90a01SHans de Goede 	 * 0x0012: changes number of colors (does not affect speed)
181859f90a01SHans de Goede 	 * 0x002a: no effect
181959f90a01SHans de Goede 	 * 0x002c: hardware setting (related to scan lines)
182059f90a01SHans de Goede 	 * 0x002e: stops video stream, probably important h/w setting
182159f90a01SHans de Goede 	 */
182259f90a01SHans de Goede 	cit_model2_Packet1(gspca_dev, 0x000a, 0x005c);
182359f90a01SHans de Goede 	cit_model2_Packet1(gspca_dev, 0x0004, 0x0000);
182459f90a01SHans de Goede 	cit_model2_Packet1(gspca_dev, 0x0006, 0x00fb);
182559f90a01SHans de Goede 	cit_model2_Packet1(gspca_dev, 0x0008, 0x0000);
182659f90a01SHans de Goede 	cit_model2_Packet1(gspca_dev, 0x000c, 0x0009);
182759f90a01SHans de Goede 	cit_model2_Packet1(gspca_dev, 0x0012, 0x000a);
182859f90a01SHans de Goede 	cit_model2_Packet1(gspca_dev, 0x002a, 0x0000);
182959f90a01SHans de Goede 	cit_model2_Packet1(gspca_dev, 0x002c, 0x0000);
183059f90a01SHans de Goede 	cit_model2_Packet1(gspca_dev, 0x002e, 0x0008);
183159f90a01SHans de Goede 
183259f90a01SHans de Goede 	/*
183359f90a01SHans de Goede 	 * Function 0x0030 pops up all over the place. Apparently
183459f90a01SHans de Goede 	 * it is a hardware control register, with every bit assigned to
183559f90a01SHans de Goede 	 * do something.
183659f90a01SHans de Goede 	 */
183759f90a01SHans de Goede 	cit_model2_Packet1(gspca_dev, 0x0030, 0x0000);
183859f90a01SHans de Goede 
183959f90a01SHans de Goede 	/*
184059f90a01SHans de Goede 	 * Magic control of CMOS sensor. Only lower values like
184159f90a01SHans de Goede 	 * 0-3 work, and picture shifts left or right. Don't change.
184259f90a01SHans de Goede 	 */
18431966bc2aSOndrej Zary 	switch (gspca_dev->pixfmt.width) {
184459f90a01SHans de Goede 	case 176: /* 176x144 */
184559f90a01SHans de Goede 		cit_model2_Packet1(gspca_dev, 0x0014, 0x0002);
184659f90a01SHans de Goede 		cit_model2_Packet1(gspca_dev, 0x0016, 0x0002); /* Horizontal shift */
184759f90a01SHans de Goede 		cit_model2_Packet1(gspca_dev, 0x0018, 0x004a); /* Another hardware setting */
184859f90a01SHans de Goede 		clock_div = 6;
184959f90a01SHans de Goede 		break;
185059f90a01SHans de Goede 	case 320: /* 320x240 */
185159f90a01SHans de Goede 		cit_model2_Packet1(gspca_dev, 0x0014, 0x0009);
185259f90a01SHans de Goede 		cit_model2_Packet1(gspca_dev, 0x0016, 0x0005); /* Horizontal shift */
185359f90a01SHans de Goede 		cit_model2_Packet1(gspca_dev, 0x0018, 0x0044); /* Another hardware setting */
185459f90a01SHans de Goede 		clock_div = 8;
185559f90a01SHans de Goede 		break;
1856cd65d24eSMauro Carvalho Chehab #if 0
1857cd65d24eSMauro Carvalho Chehab 	case VIDEOSIZE_352x240:
185859f90a01SHans de Goede 		/* This mode doesn't work as Windows programs it; changed to work */
185959f90a01SHans de Goede 		cit_model2_Packet1(gspca_dev, 0x0014, 0x0009); /* Windows sets this to 8 */
186059f90a01SHans de Goede 		cit_model2_Packet1(gspca_dev, 0x0016, 0x0003); /* Horizontal shift */
186159f90a01SHans de Goede 		cit_model2_Packet1(gspca_dev, 0x0018, 0x0044); /* Windows sets this to 0x0045 */
186259f90a01SHans de Goede 		clock_div = 10;
186359f90a01SHans de Goede 		break;
1864cd65d24eSMauro Carvalho Chehab #endif
186559f90a01SHans de Goede 	case 352: /* 352x288 */
186659f90a01SHans de Goede 		cit_model2_Packet1(gspca_dev, 0x0014, 0x0003);
186759f90a01SHans de Goede 		cit_model2_Packet1(gspca_dev, 0x0016, 0x0002); /* Horizontal shift */
186859f90a01SHans de Goede 		cit_model2_Packet1(gspca_dev, 0x0018, 0x004a); /* Another hardware setting */
186959f90a01SHans de Goede 		clock_div = 16;
187059f90a01SHans de Goede 		break;
187159f90a01SHans de Goede 	}
187259f90a01SHans de Goede 
187359f90a01SHans de Goede 	/* TESTME These are handled through controls
187459f90a01SHans de Goede 	   KEEP until someone can test leaving this out is ok */
187559f90a01SHans de Goede 	if (0)
187659f90a01SHans de Goede 		cit_model2_Packet1(gspca_dev, 0x001a, 0x005a);
187759f90a01SHans de Goede 
187859f90a01SHans de Goede 	/*
187959f90a01SHans de Goede 	 * We have our own frame rate setting varying from 0 (slowest) to 6
188059f90a01SHans de Goede 	 * (fastest). The camera model 2 allows frame rate in range [0..0x1F]
188159f90a01SHans de Goede 	 # where 0 is also the slowest setting. However for all practical
188259f90a01SHans de Goede 	 # reasons high settings make no sense because USB is not fast enough
188359f90a01SHans de Goede 	 # to support high FPS. Be aware that the picture datastream will be
188459f90a01SHans de Goede 	 # severely disrupted if you ask for frame rate faster than allowed
188559f90a01SHans de Goede 	 # for the video size - see below:
188659f90a01SHans de Goede 	 *
188759f90a01SHans de Goede 	 * Allowable ranges (obtained experimentally on OHCI, K6-3, 450 MHz):
188859f90a01SHans de Goede 	 * -----------------------------------------------------------------
188959f90a01SHans de Goede 	 * 176x144: [6..31]
189059f90a01SHans de Goede 	 * 320x240: [8..31]
189159f90a01SHans de Goede 	 * 352x240: [10..31]
189259f90a01SHans de Goede 	 * 352x288: [16..31] I have to raise lower threshold for stability...
189359f90a01SHans de Goede 	 *
189459f90a01SHans de Goede 	 * As usual, slower FPS provides better sensitivity.
189559f90a01SHans de Goede 	 */
189659f90a01SHans de Goede 	cit_model2_Packet1(gspca_dev, 0x001c, clock_div);
189759f90a01SHans de Goede 
189859f90a01SHans de Goede 	/*
189959f90a01SHans de Goede 	 * This setting does not visibly affect pictures; left it here
190059f90a01SHans de Goede 	 * because it was present in Windows USB data stream. This function
190159f90a01SHans de Goede 	 * does not allow arbitrary values and apparently is a bit mask, to
190259f90a01SHans de Goede 	 * be activated only at appropriate time. Don't change it randomly!
190359f90a01SHans de Goede 	 */
19041966bc2aSOndrej Zary 	switch (gspca_dev->pixfmt.width) {
190559f90a01SHans de Goede 	case 176: /* 176x144 */
190659f90a01SHans de Goede 		cit_model2_Packet1(gspca_dev, 0x0026, 0x00c2);
190759f90a01SHans de Goede 		break;
190859f90a01SHans de Goede 	case 320: /* 320x240 */
190959f90a01SHans de Goede 		cit_model2_Packet1(gspca_dev, 0x0026, 0x0044);
191059f90a01SHans de Goede 		break;
1911cd65d24eSMauro Carvalho Chehab #if 0
1912cd65d24eSMauro Carvalho Chehab 	case VIDEOSIZE_352x240:
191359f90a01SHans de Goede 		cit_model2_Packet1(gspca_dev, 0x0026, 0x0046);
191459f90a01SHans de Goede 		break;
1915cd65d24eSMauro Carvalho Chehab #endif
191659f90a01SHans de Goede 	case 352: /* 352x288 */
191759f90a01SHans de Goede 		cit_model2_Packet1(gspca_dev, 0x0026, 0x0048);
191859f90a01SHans de Goede 		break;
191959f90a01SHans de Goede 	}
192059f90a01SHans de Goede 
1921d5d875cbSHans Verkuil 	cit_model2_Packet1(gspca_dev, 0x0028, v4l2_ctrl_g_ctrl(sd->lighting));
1922872099e8SHans de Goede 	/* model2 cannot change the backlight compensation while streaming */
1923872099e8SHans de Goede 	v4l2_ctrl_grab(sd->lighting, true);
1924872099e8SHans de Goede 
192559f90a01SHans de Goede 	/* color balance rg2 */
192659f90a01SHans de Goede 	cit_model2_Packet1(gspca_dev, 0x001e, 0x002f);
192759f90a01SHans de Goede 	/* saturation */
192859f90a01SHans de Goede 	cit_model2_Packet1(gspca_dev, 0x0020, 0x0034);
192959f90a01SHans de Goede 	/* color balance yb */
193059f90a01SHans de Goede 	cit_model2_Packet1(gspca_dev, 0x0022, 0x00a0);
193159f90a01SHans de Goede 
193259f90a01SHans de Goede 	/* Hardware control command */
193359f90a01SHans de Goede 	cit_model2_Packet1(gspca_dev, 0x0030, 0x0004);
193459f90a01SHans de Goede 
193559f90a01SHans de Goede 	return 0;
193659f90a01SHans de Goede }
193759f90a01SHans de Goede 
19381f33de0fSHans de Goede static int cit_start_model3(struct gspca_dev *gspca_dev)
19391f33de0fSHans de Goede {
19401f33de0fSHans de Goede 	const unsigned short compression = 0; /* 0=none, 7=best frame rate */
19411f33de0fSHans de Goede 	int i, clock_div = 0;
19421f33de0fSHans de Goede 
19431f33de0fSHans de Goede 	/* HDG not in ibmcam driver, added to see if it helps with
19441f33de0fSHans de Goede 	   auto-detecting between model3 and ibm netcamera pro */
1945e0657be5SHans de Goede 	cit_read_reg(gspca_dev, 0x128, 1);
19461f33de0fSHans de Goede 
19471f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0100);
1948e0657be5SHans de Goede 	cit_read_reg(gspca_dev, 0x0116, 0);
19491f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0060, 0x0116);
19501f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0002, 0x0112);
19511f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0123);
19521f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0001, 0x0117);
19531f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0040, 0x0108);
19541f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0019, 0x012c);
19551f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0060, 0x0116);
19561f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0002, 0x0115);
19571f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0003, 0x0115);
1958e0657be5SHans de Goede 	cit_read_reg(gspca_dev, 0x0115, 0);
19591f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x000b, 0x0115);
19601f33de0fSHans de Goede 
196159f90a01SHans de Goede 	/* TESTME HDG not in ibmcam driver, added to see if it helps with
19621f33de0fSHans de Goede 	   auto-detecting between model3 and ibm netcamera pro */
19631f33de0fSHans de Goede 	if (0) {
19641f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0078, 0x012d);
19651f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0001, 0x012f);
19661f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0xd141, 0x0124);
19671f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0079, 0x012d);
19681f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x00ff, 0x0130);
19691f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0xcd41, 0x0124);
19701f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0xfffa, 0x0124);
1971e0657be5SHans de Goede 		cit_read_reg(gspca_dev, 0x0126, 1);
19721f33de0fSHans de Goede 	}
19731f33de0fSHans de Goede 
19741f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x000a, 0x0040);
19751f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x000b, 0x00f6);
19761f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x000c, 0x0002);
19771f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x000d, 0x0020);
19781f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x000e, 0x0033);
19791f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x000f, 0x0007);
19801f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0010, 0x0000);
19811f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0011, 0x0070);
19821f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0012, 0x0030);
19831f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0013, 0x0000);
19841f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0014, 0x0001);
19851f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0015, 0x0001);
19861f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0016, 0x0001);
19871f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0017, 0x0001);
19881f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0018, 0x0000);
19891f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x001e, 0x00c3);
19901f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0020, 0x0000);
19911f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0028, 0x0010);
19921f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0029, 0x0054);
19931f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x002a, 0x0013);
19941f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x002b, 0x0007);
19951f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x002d, 0x0028);
19961f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x002e, 0x0000);
19971f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0031, 0x0000);
19981f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0032, 0x0000);
19991f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0033, 0x0000);
20001f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0034, 0x0000);
20011f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0035, 0x0038);
20021f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x003a, 0x0001);
20031f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x003c, 0x001e);
20041f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x003f, 0x000a);
20051f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0041, 0x0000);
20061f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0046, 0x003f);
20071f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0047, 0x0000);
20081f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0050, 0x0005);
20091f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0052, 0x001a);
20101f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0053, 0x0003);
20111f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x005a, 0x006b);
20121f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x005d, 0x001e);
20131f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x005e, 0x0030);
20141f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x005f, 0x0041);
20151f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0064, 0x0008);
20161f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0065, 0x0015);
20171f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0068, 0x000f);
20181f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0079, 0x0000);
20191f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x007a, 0x0000);
20201f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x007c, 0x003f);
20211f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0082, 0x000f);
20221f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0085, 0x0000);
20231f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0099, 0x0000);
20241f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x009b, 0x0023);
20251f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x009c, 0x0022);
20261f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x009d, 0x0096);
20271f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x009e, 0x0096);
20281f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x009f, 0x000a);
20291f33de0fSHans de Goede 
20301966bc2aSOndrej Zary 	switch (gspca_dev->pixfmt.width) {
20311f33de0fSHans de Goede 	case 160:
20321f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0101); /* Same on 160x120, 320x240 */
20331f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x00a0, 0x0103); /* Same on 160x120, 320x240 */
20341f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0078, 0x0105); /* Same on 160x120, 320x240 */
20351f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x010a); /* Same */
20361f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0024, 0x010b); /* Differs everywhere */
20371f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x00a9, 0x0119);
20381f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0016, 0x011b);
20391f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0002, 0x011d); /* Same on 160x120, 320x240 */
20401f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0003, 0x011e); /* Same on 160x120, 640x480 */
20411f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0129); /* Same */
20421f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x00fc, 0x012b); /* Same */
20431f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0018, 0x0102);
20441f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0004, 0x0104);
20451f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0004, 0x011a);
20461f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0028, 0x011c);
20471f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0022, 0x012a); /* Same */
20481f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0118);
20491f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0132);
20501f33de0fSHans de Goede 		cit_model3_Packet1(gspca_dev, 0x0021, 0x0001); /* Same */
20511f33de0fSHans de Goede 		cit_write_reg(gspca_dev, compression, 0x0109);
20521f33de0fSHans de Goede 		clock_div = 3;
20531f33de0fSHans de Goede 		break;
20541f33de0fSHans de Goede 	case 320:
20551f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0101); /* Same on 160x120, 320x240 */
20561f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x00a0, 0x0103); /* Same on 160x120, 320x240 */
20571f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0078, 0x0105); /* Same on 160x120, 320x240 */
20581f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x010a); /* Same */
20591f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0028, 0x010b); /* Differs everywhere */
20601f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0002, 0x011d); /* Same */
20611f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x011e);
20621f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0129); /* Same */
20631f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x00fc, 0x012b); /* Same */
20641f33de0fSHans de Goede 		/* 4 commands from 160x120 skipped */
20651f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0022, 0x012a); /* Same */
20661f33de0fSHans de Goede 		cit_model3_Packet1(gspca_dev, 0x0021, 0x0001); /* Same */
20671f33de0fSHans de Goede 		cit_write_reg(gspca_dev, compression, 0x0109);
20681f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x00d9, 0x0119);
20691f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0006, 0x011b);
20701f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0021, 0x0102); /* Same on 320x240, 640x480 */
20711f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0010, 0x0104);
20721f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0004, 0x011a);
20731f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x003f, 0x011c);
20741f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x001c, 0x0118);
20751f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0132);
20761f33de0fSHans de Goede 		clock_div = 5;
20771f33de0fSHans de Goede 		break;
20781f33de0fSHans de Goede 	case 640:
20791f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x00f0, 0x0105);
20801f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x010a); /* Same */
20811f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0038, 0x010b); /* Differs everywhere */
20821f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x00d9, 0x0119); /* Same on 320x240, 640x480 */
20831f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0006, 0x011b); /* Same on 320x240, 640x480 */
20841f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0004, 0x011d); /* NC */
20851f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0003, 0x011e); /* Same on 160x120, 640x480 */
20861f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0129); /* Same */
20871f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x00fc, 0x012b); /* Same */
20881f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0021, 0x0102); /* Same on 320x240, 640x480 */
20891f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0016, 0x0104); /* NC */
20901f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0004, 0x011a); /* Same on 320x240, 640x480 */
20911f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x003f, 0x011c); /* Same on 320x240, 640x480 */
20921f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0022, 0x012a); /* Same */
20931f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x001c, 0x0118); /* Same on 320x240, 640x480 */
20941f33de0fSHans de Goede 		cit_model3_Packet1(gspca_dev, 0x0021, 0x0001); /* Same */
20951f33de0fSHans de Goede 		cit_write_reg(gspca_dev, compression, 0x0109);
20961f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0040, 0x0101);
20971f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0040, 0x0103);
20981f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0132); /* Same on 320x240, 640x480 */
20991f33de0fSHans de Goede 		clock_div = 7;
21001f33de0fSHans de Goede 		break;
21011f33de0fSHans de Goede 	}
21021f33de0fSHans de Goede 
21031f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x007e, 0x000e);	/* Hue */
21041f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0036, 0x0011);	/* Brightness */
21051f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0060, 0x0002);	/* Sharpness */
21061f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0061, 0x0004);	/* Sharpness */
21071f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0062, 0x0005);	/* Sharpness */
21081f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0063, 0x0014);	/* Sharpness */
21091f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0096, 0x00a0);	/* Red sharpness */
21101f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0097, 0x0096);	/* Blue sharpness */
21111f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0067, 0x0001);	/* Contrast */
21121f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x005b, 0x000c);	/* Contrast */
21131f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x005c, 0x0016);	/* Contrast */
21141f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0098, 0x000b);
21151f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x002c, 0x0003);	/* Was 1, broke 640x480 */
21161f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x002f, 0x002a);
21171f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0030, 0x0029);
21181f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0037, 0x0002);
21191f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0038, 0x0059);
21201f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x003d, 0x002e);
21211f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x003e, 0x0028);
21221f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0078, 0x0005);
21231f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x007b, 0x0011);
21241f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x007d, 0x004b);
21251f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x007f, 0x0022);
21261f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0080, 0x000c);
21271f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0081, 0x000b);
21281f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0083, 0x00fd);
21291f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0086, 0x000b);
21301f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0087, 0x000b);
21311f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x007e, 0x000e);
21321f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0096, 0x00a0);	/* Red sharpness */
21331f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0097, 0x0096);	/* Blue sharpness */
21341f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0098, 0x000b);
21351f33de0fSHans de Goede 
213641f424baSHans de Goede 	/* FIXME we should probably use cit_get_clock_div() here (in
213741f424baSHans de Goede 	   combination with isoc negotiation using the programmable isoc size)
213841f424baSHans de Goede 	   like with the IBM netcam pro). */
21391f33de0fSHans de Goede 	cit_write_reg(gspca_dev, clock_div, 0x0111); /* Clock Divider */
21401f33de0fSHans de Goede 
21411966bc2aSOndrej Zary 	switch (gspca_dev->pixfmt.width) {
21421f33de0fSHans de Goede 	case 160:
21431f33de0fSHans de Goede 		cit_model3_Packet1(gspca_dev, 0x001f, 0x0000); /* Same */
21441f33de0fSHans de Goede 		cit_model3_Packet1(gspca_dev, 0x0039, 0x001f); /* Same */
21451f33de0fSHans de Goede 		cit_model3_Packet1(gspca_dev, 0x003b, 0x003c); /* Same */
21461f33de0fSHans de Goede 		cit_model3_Packet1(gspca_dev, 0x0040, 0x000a);
21471f33de0fSHans de Goede 		cit_model3_Packet1(gspca_dev, 0x0051, 0x000a);
21481f33de0fSHans de Goede 		break;
21491f33de0fSHans de Goede 	case 320:
21501f33de0fSHans de Goede 		cit_model3_Packet1(gspca_dev, 0x001f, 0x0000); /* Same */
21511f33de0fSHans de Goede 		cit_model3_Packet1(gspca_dev, 0x0039, 0x001f); /* Same */
21521f33de0fSHans de Goede 		cit_model3_Packet1(gspca_dev, 0x003b, 0x003c); /* Same */
21531f33de0fSHans de Goede 		cit_model3_Packet1(gspca_dev, 0x0040, 0x0008);
21541f33de0fSHans de Goede 		cit_model3_Packet1(gspca_dev, 0x0051, 0x000b);
21551f33de0fSHans de Goede 		break;
21561f33de0fSHans de Goede 	case 640:
21571f33de0fSHans de Goede 		cit_model3_Packet1(gspca_dev, 0x001f, 0x0002);	/* !Same */
21581f33de0fSHans de Goede 		cit_model3_Packet1(gspca_dev, 0x0039, 0x003e);	/* !Same */
21591f33de0fSHans de Goede 		cit_model3_Packet1(gspca_dev, 0x0040, 0x0008);
21601f33de0fSHans de Goede 		cit_model3_Packet1(gspca_dev, 0x0051, 0x000a);
21611f33de0fSHans de Goede 		break;
21621f33de0fSHans de Goede 	}
21631f33de0fSHans de Goede 
21641f33de0fSHans de Goede /*	if (sd->input_index) { */
21651f33de0fSHans de Goede 	if (rca_input) {
21661f33de0fSHans de Goede 		for (i = 0; i < ARRAY_SIZE(rca_initdata); i++) {
21671f33de0fSHans de Goede 			if (rca_initdata[i][0])
2168e0657be5SHans de Goede 				cit_read_reg(gspca_dev, rca_initdata[i][2], 0);
21691f33de0fSHans de Goede 			else
21701f33de0fSHans de Goede 				cit_write_reg(gspca_dev, rca_initdata[i][1],
21711f33de0fSHans de Goede 					      rca_initdata[i][2]);
21721f33de0fSHans de Goede 		}
21731f33de0fSHans de Goede 	}
21741f33de0fSHans de Goede 
217559f90a01SHans de Goede 	return 0;
217659f90a01SHans de Goede }
217759f90a01SHans de Goede 
217859f90a01SHans de Goede static int cit_start_model4(struct gspca_dev *gspca_dev)
217959f90a01SHans de Goede {
218059f90a01SHans de Goede 	struct sd *sd = (struct sd *) gspca_dev;
218159f90a01SHans de Goede 
218259f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0100);
218359f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x00c0, 0x0111);
218459f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x00bc, 0x012c);
218559f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0080, 0x012b);
218659f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0108);
218759f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0001, 0x0133);
218859f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x009b, 0x010f);
218959f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x00bb, 0x010f);
219059f90a01SHans de Goede 	cit_model4_Packet1(gspca_dev, 0x0038, 0x0000);
219159f90a01SHans de Goede 	cit_model4_Packet1(gspca_dev, 0x000a, 0x005c);
219259f90a01SHans de Goede 
219359f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x00aa, 0x012d);
219459f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0004, 0x012f);
219559f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0xd141, 0x0124);
219659f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0127);
219759f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x00fb, 0x012e);
219859f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0130);
219959f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x8a28, 0x0124);
220059f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x00aa, 0x012f);
220159f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0xd055, 0x0124);
220259f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x000c, 0x0127);
220359f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0009, 0x012e);
220459f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0xaa28, 0x0124);
220559f90a01SHans de Goede 
220659f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x00aa, 0x012d);
220759f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0012, 0x012f);
220859f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0xd141, 0x0124);
220959f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0008, 0x0127);
221059f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x00aa, 0x0130);
221159f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x82a8, 0x0124);
221259f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x002a, 0x012d);
221359f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x012f);
221459f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0xd145, 0x0124);
221559f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0xfffa, 0x0124);
221659f90a01SHans de Goede 	cit_model4_Packet1(gspca_dev, 0x0034, 0x0000);
221759f90a01SHans de Goede 
22181966bc2aSOndrej Zary 	switch (gspca_dev->pixfmt.width) {
221959f90a01SHans de Goede 	case 128: /* 128x96 */
222059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0070, 0x0119);
222159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00d0, 0x0111);
222259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0039, 0x010a);
222359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0001, 0x0102);
222459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0028, 0x0103);
222559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0104);
222659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x001e, 0x0105);
222759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
222859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0016, 0x012f);
222959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd141, 0x0124);
223059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x000a, 0x0127);
223159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x0130);
223259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x82a8, 0x0124);
223359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0014, 0x012d);
223459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0008, 0x012f);
223559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd145, 0x0124);
223659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x012e);
223759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x001a, 0x0130);
223859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x8a0a, 0x0124);
223959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x005a, 0x012d);
224059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x9545, 0x0124);
224159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x0127);
224259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0018, 0x012e);
224359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0043, 0x0130);
224459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x8a28, 0x0124);
224559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x012f);
224659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd055, 0x0124);
224759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x001c, 0x0127);
224859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00eb, 0x012e);
224959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xaa28, 0x0124);
225059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
225159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0032, 0x012f);
225259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd141, 0x0124);
225359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0127);
225459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x0130);
225559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x82a8, 0x0124);
225659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0036, 0x012d);
225759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0008, 0x012f);
225859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd145, 0x0124);
225959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xfffa, 0x0124);
226059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
226159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x001e, 0x012f);
226259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd141, 0x0124);
226359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0017, 0x0127);
226459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0013, 0x012e);
226559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0031, 0x0130);
226659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x8a28, 0x0124);
226759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0017, 0x012d);
226859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0078, 0x012f);
226959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd145, 0x0124);
227059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0127);
227159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xfea8, 0x0124);
227259f90a01SHans de Goede 		sd->sof_len = 2;
227359f90a01SHans de Goede 		break;
227459f90a01SHans de Goede 	case 160: /* 160x120 */
227559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0038, 0x0119);
227659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00d0, 0x0111);
227759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00b9, 0x010a);
227859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0001, 0x0102);
227959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0028, 0x0103);
228059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0104);
228159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x001e, 0x0105);
228259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
228359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0016, 0x012f);
228459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd141, 0x0124);
228559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x000b, 0x0127);
228659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x0130);
228759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x82a8, 0x0124);
228859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0014, 0x012d);
228959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0008, 0x012f);
229059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd145, 0x0124);
229159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x012e);
229259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x001a, 0x0130);
229359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x8a0a, 0x0124);
229459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x005a, 0x012d);
229559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x9545, 0x0124);
229659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x0127);
229759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0018, 0x012e);
229859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0043, 0x0130);
229959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x8a28, 0x0124);
230059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x012f);
230159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd055, 0x0124);
230259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x001c, 0x0127);
230359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00c7, 0x012e);
230459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xaa28, 0x0124);
230559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
230659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0032, 0x012f);
230759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd141, 0x0124);
230859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0025, 0x0127);
230959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x0130);
231059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x82a8, 0x0124);
231159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0036, 0x012d);
231259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0008, 0x012f);
231359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd145, 0x0124);
231459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xfffa, 0x0124);
231559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
231659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x001e, 0x012f);
231759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd141, 0x0124);
231859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0048, 0x0127);
231959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0035, 0x012e);
232059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00d0, 0x0130);
232159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x8a28, 0x0124);
232259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0048, 0x012d);
232359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0090, 0x012f);
232459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd145, 0x0124);
232559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0001, 0x0127);
232659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xfea8, 0x0124);
232759f90a01SHans de Goede 		sd->sof_len = 2;
232859f90a01SHans de Goede 		break;
232959f90a01SHans de Goede 	case 176: /* 176x144 */
233059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0038, 0x0119);
233159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00d0, 0x0111);
233259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00b9, 0x010a);
233359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0001, 0x0102);
233459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x002c, 0x0103);
233559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0104);
233659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0024, 0x0105);
233759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
233859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0016, 0x012f);
233959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd141, 0x0124);
234059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0007, 0x0127);
234159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x0130);
234259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x82a8, 0x0124);
234359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0014, 0x012d);
234459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0001, 0x012f);
234559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd145, 0x0124);
234659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x012e);
234759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x001a, 0x0130);
234859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x8a0a, 0x0124);
234959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x005e, 0x012d);
235059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x9545, 0x0124);
235159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x0127);
235259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0018, 0x012e);
235359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0049, 0x0130);
235459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x8a28, 0x0124);
235559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x012f);
235659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd055, 0x0124);
235759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x001c, 0x0127);
235859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00c7, 0x012e);
235959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xaa28, 0x0124);
236059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
236159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0032, 0x012f);
236259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd141, 0x0124);
236359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0028, 0x0127);
236459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x0130);
236559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x82a8, 0x0124);
236659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0036, 0x012d);
236759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0008, 0x012f);
236859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd145, 0x0124);
236959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xfffa, 0x0124);
237059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
237159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x001e, 0x012f);
237259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd141, 0x0124);
237359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0010, 0x0127);
237459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0013, 0x012e);
237559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x002a, 0x0130);
237659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x8a28, 0x0124);
237759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0010, 0x012d);
237859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x006d, 0x012f);
237959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd145, 0x0124);
238059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0001, 0x0127);
238159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xfea8, 0x0124);
238259f90a01SHans de Goede 		/* TESTME HDG: this does not seem right
238359f90a01SHans de Goede 		   (it is 2 for all other resolutions) */
238459f90a01SHans de Goede 		sd->sof_len = 10;
238559f90a01SHans de Goede 		break;
238659f90a01SHans de Goede 	case 320: /* 320x240 */
238759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0070, 0x0119);
238859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00d0, 0x0111);
238959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0039, 0x010a);
239059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0001, 0x0102);
239159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0028, 0x0103);
239259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0104);
239359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x001e, 0x0105);
239459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
239559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0016, 0x012f);
239659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd141, 0x0124);
239759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x000a, 0x0127);
239859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x0130);
239959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x82a8, 0x0124);
240059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0014, 0x012d);
240159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0008, 0x012f);
240259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd145, 0x0124);
240359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x012e);
240459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x001a, 0x0130);
240559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x8a0a, 0x0124);
240659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x005a, 0x012d);
240759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x9545, 0x0124);
240859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x0127);
240959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0018, 0x012e);
241059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0043, 0x0130);
241159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x8a28, 0x0124);
241259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x012f);
241359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd055, 0x0124);
241459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x001c, 0x0127);
241559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00eb, 0x012e);
241659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xaa28, 0x0124);
241759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
241859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0032, 0x012f);
241959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd141, 0x0124);
242059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0127);
242159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x0130);
242259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x82a8, 0x0124);
242359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0036, 0x012d);
242459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0008, 0x012f);
242559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd145, 0x0124);
242659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xfffa, 0x0124);
242759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
242859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x001e, 0x012f);
242959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd141, 0x0124);
243059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0017, 0x0127);
243159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0013, 0x012e);
243259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0031, 0x0130);
243359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x8a28, 0x0124);
243459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0017, 0x012d);
243559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0078, 0x012f);
243659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd145, 0x0124);
243759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0127);
243859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xfea8, 0x0124);
243959f90a01SHans de Goede 		sd->sof_len = 2;
244059f90a01SHans de Goede 		break;
244159f90a01SHans de Goede 	case 352: /* 352x288 */
244259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0070, 0x0119);
244359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00c0, 0x0111);
244459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0039, 0x010a);
244559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0001, 0x0102);
244659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x002c, 0x0103);
244759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0104);
244859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0024, 0x0105);
244959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
245059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0016, 0x012f);
245159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd141, 0x0124);
245259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0006, 0x0127);
245359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x0130);
245459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x82a8, 0x0124);
245559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0014, 0x012d);
245659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0002, 0x012f);
245759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd145, 0x0124);
245859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x012e);
245959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x001a, 0x0130);
246059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x8a0a, 0x0124);
246159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x005e, 0x012d);
246259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x9545, 0x0124);
246359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x0127);
246459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0018, 0x012e);
246559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0049, 0x0130);
246659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x8a28, 0x0124);
246759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x012f);
246859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd055, 0x0124);
246959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x001c, 0x0127);
247059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00cf, 0x012e);
247159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xaa28, 0x0124);
247259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
247359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0032, 0x012f);
247459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd141, 0x0124);
247559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0127);
247659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x0130);
247759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x82a8, 0x0124);
247859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0036, 0x012d);
247959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0008, 0x012f);
248059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd145, 0x0124);
248159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xfffa, 0x0124);
248259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
248359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x001e, 0x012f);
248459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd141, 0x0124);
248559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0010, 0x0127);
248659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0013, 0x012e);
248759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0025, 0x0130);
248859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x8a28, 0x0124);
248959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0010, 0x012d);
249059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0048, 0x012f);
249159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd145, 0x0124);
249259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0127);
249359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xfea8, 0x0124);
249459f90a01SHans de Goede 		sd->sof_len = 2;
249559f90a01SHans de Goede 		break;
249659f90a01SHans de Goede 	}
249759f90a01SHans de Goede 
249859f90a01SHans de Goede 	cit_model4_Packet1(gspca_dev, 0x0038, 0x0004);
249959f90a01SHans de Goede 
25001f33de0fSHans de Goede 	return 0;
25011f33de0fSHans de Goede }
25021f33de0fSHans de Goede 
25031f33de0fSHans de Goede static int cit_start_ibm_netcam_pro(struct gspca_dev *gspca_dev)
25041f33de0fSHans de Goede {
25051f33de0fSHans de Goede 	const unsigned short compression = 0; /* 0=none, 7=best frame rate */
250641f424baSHans de Goede 	int i, clock_div;
250741f424baSHans de Goede 
250841f424baSHans de Goede 	clock_div = cit_get_clock_div(gspca_dev);
250941f424baSHans de Goede 	if (clock_div < 0)
251041f424baSHans de Goede 		return clock_div;
25111f33de0fSHans de Goede 
25121f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0003, 0x0133);
25131f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0117);
25141f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0008, 0x0123);
25151f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0100);
25161f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0060, 0x0116);
25171f33de0fSHans de Goede 	/* cit_write_reg(gspca_dev, 0x0002, 0x0112); see sd_stop0 */
25181f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0133);
25191f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0123);
25201f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0001, 0x0117);
25211f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0040, 0x0108);
25221f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0019, 0x012c);
25231f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0060, 0x0116);
25241f33de0fSHans de Goede 	/* cit_write_reg(gspca_dev, 0x000b, 0x0115); see sd_stop0 */
25251f33de0fSHans de Goede 
25261f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0049, 0x0000);
25271f33de0fSHans de Goede 
25281f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0101); /* Same on 160x120, 320x240 */
25291f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x003a, 0x0102); /* Hstart */
25301f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x00a0, 0x0103); /* Same on 160x120, 320x240 */
25311f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0078, 0x0105); /* Same on 160x120, 320x240 */
25321f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x010a); /* Same */
25331f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0002, 0x011d); /* Same on 160x120, 320x240 */
25341f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0129); /* Same */
25351f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x00fc, 0x012b); /* Same */
25361f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0022, 0x012a); /* Same */
25371f33de0fSHans de Goede 
25381966bc2aSOndrej Zary 	switch (gspca_dev->pixfmt.width) {
2539659fefa0SHans de Goede 	case 160: /* 160x120 */
25401f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0024, 0x010b);
25411f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0089, 0x0119);
25421f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x000a, 0x011b);
25431f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0003, 0x011e);
25441f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0007, 0x0104);
25451f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0009, 0x011a);
25461f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x008b, 0x011c);
25471f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0008, 0x0118);
25481f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0132);
25491f33de0fSHans de Goede 		break;
2550659fefa0SHans de Goede 	case 320: /* 320x240 */
25511f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0028, 0x010b);
25521f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x00d9, 0x0119);
25531f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0006, 0x011b);
25541f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x011e);
25551f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x000e, 0x0104);
25561f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0004, 0x011a);
25571f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x003f, 0x011c);
25581f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x000c, 0x0118);
25591f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0132);
25601f33de0fSHans de Goede 		break;
25611f33de0fSHans de Goede 	}
25621f33de0fSHans de Goede 
25631f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0019, 0x0031);
25641f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x001a, 0x0003);
25651f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x001b, 0x0038);
25661f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x001c, 0x0000);
25671f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0024, 0x0001);
25681f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0027, 0x0001);
25691f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x002a, 0x0004);
25701f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0035, 0x000b);
25711f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x003f, 0x0001);
25721f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0044, 0x0000);
25731f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0054, 0x0000);
25741f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00c4, 0x0000);
25751f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00e7, 0x0001);
25761f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00e9, 0x0001);
25771f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00ee, 0x0000);
25781f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00f3, 0x00c0);
25791f33de0fSHans de Goede 
25801f33de0fSHans de Goede 	cit_write_reg(gspca_dev, compression, 0x0109);
25811f33de0fSHans de Goede 	cit_write_reg(gspca_dev, clock_div, 0x0111);
25821f33de0fSHans de Goede 
25831f33de0fSHans de Goede /*	if (sd->input_index) { */
25841f33de0fSHans de Goede 	if (rca_input) {
25851f33de0fSHans de Goede 		for (i = 0; i < ARRAY_SIZE(rca_initdata); i++) {
25861f33de0fSHans de Goede 			if (rca_initdata[i][0])
2587e0657be5SHans de Goede 				cit_read_reg(gspca_dev, rca_initdata[i][2], 0);
25881f33de0fSHans de Goede 			else
25891f33de0fSHans de Goede 				cit_write_reg(gspca_dev, rca_initdata[i][1],
25901f33de0fSHans de Goede 					      rca_initdata[i][2]);
25911f33de0fSHans de Goede 		}
25921f33de0fSHans de Goede 	}
25931f33de0fSHans de Goede 
25941f33de0fSHans de Goede 	return 0;
25951f33de0fSHans de Goede }
25961f33de0fSHans de Goede 
25971f33de0fSHans de Goede /* -- start the camera -- */
25981f33de0fSHans de Goede static int sd_start(struct gspca_dev *gspca_dev)
25991f33de0fSHans de Goede {
26001f33de0fSHans de Goede 	struct sd *sd = (struct sd *) gspca_dev;
26011f33de0fSHans de Goede 	int packet_size;
26021f33de0fSHans de Goede 
2603659fefa0SHans de Goede 	packet_size = cit_get_packet_size(gspca_dev);
2604659fefa0SHans de Goede 	if (packet_size < 0)
2605659fefa0SHans de Goede 		return packet_size;
2606659fefa0SHans de Goede 
26071f33de0fSHans de Goede 	switch (sd->model) {
2608659fefa0SHans de Goede 	case CIT_MODEL0:
2609659fefa0SHans de Goede 		cit_start_model0(gspca_dev);
2610659fefa0SHans de Goede 		break;
261159f90a01SHans de Goede 	case CIT_MODEL1:
261259f90a01SHans de Goede 		cit_start_model1(gspca_dev);
261359f90a01SHans de Goede 		break;
261459f90a01SHans de Goede 	case CIT_MODEL2:
261559f90a01SHans de Goede 		cit_start_model2(gspca_dev);
261659f90a01SHans de Goede 		break;
26171f33de0fSHans de Goede 	case CIT_MODEL3:
26181f33de0fSHans de Goede 		cit_start_model3(gspca_dev);
26191f33de0fSHans de Goede 		break;
262059f90a01SHans de Goede 	case CIT_MODEL4:
262159f90a01SHans de Goede 		cit_start_model4(gspca_dev);
262259f90a01SHans de Goede 		break;
26231f33de0fSHans de Goede 	case CIT_IBM_NETCAM_PRO:
26241f33de0fSHans de Goede 		cit_start_ibm_netcam_pro(gspca_dev);
26251f33de0fSHans de Goede 		break;
26261f33de0fSHans de Goede 	}
26271f33de0fSHans de Goede 
2628659fefa0SHans de Goede 	/* Program max isoc packet size */
26291f33de0fSHans de Goede 	cit_write_reg(gspca_dev, packet_size >> 8, 0x0106);
26301f33de0fSHans de Goede 	cit_write_reg(gspca_dev, packet_size & 0xff, 0x0107);
26311f33de0fSHans de Goede 
26321f33de0fSHans de Goede 	cit_restart_stream(gspca_dev);
26331f33de0fSHans de Goede 
26341f33de0fSHans de Goede 	return 0;
26351f33de0fSHans de Goede }
26361f33de0fSHans de Goede 
2637bc46bae6SHans de Goede static int sd_isoc_init(struct gspca_dev *gspca_dev)
2638bc46bae6SHans de Goede {
2639bc46bae6SHans de Goede 	struct usb_host_interface *alt;
2640bc46bae6SHans de Goede 	int max_packet_size;
2641bc46bae6SHans de Goede 
26421966bc2aSOndrej Zary 	switch (gspca_dev->pixfmt.width) {
2643bc46bae6SHans de Goede 	case 160:
2644bc46bae6SHans de Goede 		max_packet_size = 450;
2645bc46bae6SHans de Goede 		break;
2646bc46bae6SHans de Goede 	case 176:
2647bc46bae6SHans de Goede 		max_packet_size = 600;
2648bc46bae6SHans de Goede 		break;
2649bc46bae6SHans de Goede 	default:
2650bc46bae6SHans de Goede 		max_packet_size = 1022;
2651bc46bae6SHans de Goede 		break;
2652bc46bae6SHans de Goede 	}
2653bc46bae6SHans de Goede 
2654bc46bae6SHans de Goede 	/* Start isoc bandwidth "negotiation" at max isoc bandwidth */
26555dae603dSHans de Goede 	alt = &gspca_dev->dev->actconfig->intf_cache[0]->altsetting[1];
2656bc46bae6SHans de Goede 	alt->endpoint[0].desc.wMaxPacketSize = cpu_to_le16(max_packet_size);
2657bc46bae6SHans de Goede 
2658bc46bae6SHans de Goede 	return 0;
2659bc46bae6SHans de Goede }
2660bc46bae6SHans de Goede 
266159f8b0bfSHans de Goede static int sd_isoc_nego(struct gspca_dev *gspca_dev)
266259f8b0bfSHans de Goede {
2663bc46bae6SHans de Goede 	int ret, packet_size, min_packet_size;
266459f8b0bfSHans de Goede 	struct usb_host_interface *alt;
266559f8b0bfSHans de Goede 
26661966bc2aSOndrej Zary 	switch (gspca_dev->pixfmt.width) {
2667bc46bae6SHans de Goede 	case 160:
2668bc46bae6SHans de Goede 		min_packet_size = 200;
2669bc46bae6SHans de Goede 		break;
2670bc46bae6SHans de Goede 	case 176:
2671bc46bae6SHans de Goede 		min_packet_size = 266;
2672bc46bae6SHans de Goede 		break;
2673bc46bae6SHans de Goede 	default:
2674bc46bae6SHans de Goede 		min_packet_size = 400;
2675bc46bae6SHans de Goede 		break;
2676bc46bae6SHans de Goede 	}
2677bc46bae6SHans de Goede 
26785dae603dSHans de Goede 	alt = &gspca_dev->dev->actconfig->intf_cache[0]->altsetting[1];
267959f8b0bfSHans de Goede 	packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
2680bc46bae6SHans de Goede 	if (packet_size <= min_packet_size)
268159f8b0bfSHans de Goede 		return -EIO;
2682bc46bae6SHans de Goede 
2683bc46bae6SHans de Goede 	packet_size -= 100;
2684bc46bae6SHans de Goede 	if (packet_size < min_packet_size)
2685bc46bae6SHans de Goede 		packet_size = min_packet_size;
268659f8b0bfSHans de Goede 	alt->endpoint[0].desc.wMaxPacketSize = cpu_to_le16(packet_size);
268759f8b0bfSHans de Goede 
268859f8b0bfSHans de Goede 	ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1);
268959f8b0bfSHans de Goede 	if (ret < 0)
2690133a9fe9SJoe Perches 		pr_err("set alt 1 err %d\n", ret);
269159f8b0bfSHans de Goede 
269259f8b0bfSHans de Goede 	return ret;
269359f8b0bfSHans de Goede }
269459f8b0bfSHans de Goede 
26951f33de0fSHans de Goede static void sd_stopN(struct gspca_dev *gspca_dev)
26961f33de0fSHans de Goede {
26971f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x010c);
26981f33de0fSHans de Goede }
26991f33de0fSHans de Goede 
27001f33de0fSHans de Goede static void sd_stop0(struct gspca_dev *gspca_dev)
27011f33de0fSHans de Goede {
27021f33de0fSHans de Goede 	struct sd *sd = (struct sd *) gspca_dev;
27031f33de0fSHans de Goede 
2704345321dcSHans de Goede 	if (!gspca_dev->present)
27051f33de0fSHans de Goede 		return;
27061f33de0fSHans de Goede 
27071f33de0fSHans de Goede 	switch (sd->model) {
2708659fefa0SHans de Goede 	case CIT_MODEL0:
2709659fefa0SHans de Goede 		/* HDG windows does this, but it causes the cams autogain to
2710659fefa0SHans de Goede 		   restart from a gain of 0, which does not look good when
2711659fefa0SHans de Goede 		   changing resolutions. */
2712659fefa0SHans de Goede 		/* cit_write_reg(gspca_dev, 0x0000, 0x0112); */
2713659fefa0SHans de Goede 		cit_write_reg(gspca_dev, 0x00c0, 0x0100); /* LED Off */
2714659fefa0SHans de Goede 		break;
271559f90a01SHans de Goede 	case CIT_MODEL1:
271659f90a01SHans de Goede 		cit_send_FF_04_02(gspca_dev);
2717e0657be5SHans de Goede 		cit_read_reg(gspca_dev, 0x0100, 0);
271859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x81, 0x0100);	/* LED Off */
271959f90a01SHans de Goede 		break;
272059f90a01SHans de Goede 	case CIT_MODEL2:
2721872099e8SHans de Goede 		v4l2_ctrl_grab(sd->lighting, false);
2722872099e8SHans de Goede 		/* Fall through! */
272359f90a01SHans de Goede 	case CIT_MODEL4:
272459f90a01SHans de Goede 		cit_model2_Packet1(gspca_dev, 0x0030, 0x0004);
272559f90a01SHans de Goede 
272659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0080, 0x0100);	/* LED Off */
272759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0020, 0x0111);
272859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00a0, 0x0111);
272959f90a01SHans de Goede 
273059f90a01SHans de Goede 		cit_model2_Packet1(gspca_dev, 0x0030, 0x0002);
273159f90a01SHans de Goede 
273259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0020, 0x0111);
273359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0112);
273459f90a01SHans de Goede 		break;
27351f33de0fSHans de Goede 	case CIT_MODEL3:
27361f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0006, 0x012c);
27371f33de0fSHans de Goede 		cit_model3_Packet1(gspca_dev, 0x0046, 0x0000);
2738e0657be5SHans de Goede 		cit_read_reg(gspca_dev, 0x0116, 0);
27391f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0064, 0x0116);
2740e0657be5SHans de Goede 		cit_read_reg(gspca_dev, 0x0115, 0);
27411f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0003, 0x0115);
27421f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0008, 0x0123);
27431f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0117);
27441f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0112);
27451f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0080, 0x0100);
27461f33de0fSHans de Goede 		break;
27471f33de0fSHans de Goede 	case CIT_IBM_NETCAM_PRO:
27481f33de0fSHans de Goede 		cit_model3_Packet1(gspca_dev, 0x0049, 0x00ff);
27491f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0006, 0x012c);
27501f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0116);
27511f33de0fSHans de Goede 		/* HDG windows does this, but I cannot get the camera
27521f33de0fSHans de Goede 		   to restart with this without redoing the entire init
27531f33de0fSHans de Goede 		   sequence which makes switching modes really slow */
27541f33de0fSHans de Goede 		/* cit_write_reg(gspca_dev, 0x0006, 0x0115); */
27551f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0008, 0x0123);
27561f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0117);
27571f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0003, 0x0133);
27581f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0111);
27591f33de0fSHans de Goede 		/* HDG windows does this, but I get a green picture when
27601f33de0fSHans de Goede 		   restarting the stream after this */
27611f33de0fSHans de Goede 		/* cit_write_reg(gspca_dev, 0x0000, 0x0112); */
27621f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x00c0, 0x0100);
27631f33de0fSHans de Goede 		break;
27641f33de0fSHans de Goede 	}
2765e0657be5SHans de Goede 
2766e32d6eb8SPeter Senna Tschudin #if IS_ENABLED(CONFIG_INPUT)
2767e0657be5SHans de Goede 	/* If the last button state is pressed, release it now! */
2768e0657be5SHans de Goede 	if (sd->button_state) {
2769e0657be5SHans de Goede 		input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
2770e0657be5SHans de Goede 		input_sync(gspca_dev->input_dev);
2771e0657be5SHans de Goede 		sd->button_state = 0;
2772e0657be5SHans de Goede 	}
2773e0657be5SHans de Goede #endif
27741f33de0fSHans de Goede }
27751f33de0fSHans de Goede 
27761f33de0fSHans de Goede static u8 *cit_find_sof(struct gspca_dev *gspca_dev, u8 *data, int len)
27771f33de0fSHans de Goede {
27781f33de0fSHans de Goede 	struct sd *sd = (struct sd *) gspca_dev;
2779659fefa0SHans de Goede 	u8 byte3 = 0, byte4 = 0;
27801f33de0fSHans de Goede 	int i;
27811f33de0fSHans de Goede 
27821f33de0fSHans de Goede 	switch (sd->model) {
2783659fefa0SHans de Goede 	case CIT_MODEL0:
278459f90a01SHans de Goede 	case CIT_MODEL1:
27851f33de0fSHans de Goede 	case CIT_MODEL3:
27861f33de0fSHans de Goede 	case CIT_IBM_NETCAM_PRO:
27871966bc2aSOndrej Zary 		switch (gspca_dev->pixfmt.width) {
2788659fefa0SHans de Goede 		case 160: /* 160x120 */
278959f90a01SHans de Goede 			byte3 = 0x02;
2790659fefa0SHans de Goede 			byte4 = 0x0a;
2791659fefa0SHans de Goede 			break;
2792659fefa0SHans de Goede 		case 176: /* 176x144 */
2793659fefa0SHans de Goede 			byte3 = 0x02;
2794659fefa0SHans de Goede 			byte4 = 0x0e;
2795659fefa0SHans de Goede 			break;
2796659fefa0SHans de Goede 		case 320: /* 320x240 */
2797659fefa0SHans de Goede 			byte3 = 0x02;
2798659fefa0SHans de Goede 			byte4 = 0x08;
2799659fefa0SHans de Goede 			break;
2800659fefa0SHans de Goede 		case 352: /* 352x288 */
2801659fefa0SHans de Goede 			byte3 = 0x02;
2802659fefa0SHans de Goede 			byte4 = 0x00;
2803659fefa0SHans de Goede 			break;
2804659fefa0SHans de Goede 		case 640:
2805659fefa0SHans de Goede 			byte3 = 0x03;
2806659fefa0SHans de Goede 			byte4 = 0x08;
2807659fefa0SHans de Goede 			break;
2808659fefa0SHans de Goede 		}
2809659fefa0SHans de Goede 
2810659fefa0SHans de Goede 		/* These have a different byte3 */
2811659fefa0SHans de Goede 		if (sd->model <= CIT_MODEL1)
2812659fefa0SHans de Goede 			byte3 = 0x00;
281359f90a01SHans de Goede 
28141f33de0fSHans de Goede 		for (i = 0; i < len; i++) {
2815659fefa0SHans de Goede 			/* For this model the SOF always starts at offset 0
2816659fefa0SHans de Goede 			   so no need to search the entire frame */
2817659fefa0SHans de Goede 			if (sd->model == CIT_MODEL0 && sd->sof_read != i)
2818659fefa0SHans de Goede 				break;
2819659fefa0SHans de Goede 
28201f33de0fSHans de Goede 			switch (sd->sof_read) {
28211f33de0fSHans de Goede 			case 0:
28221f33de0fSHans de Goede 				if (data[i] == 0x00)
28231f33de0fSHans de Goede 					sd->sof_read++;
28241f33de0fSHans de Goede 				break;
28251f33de0fSHans de Goede 			case 1:
28261f33de0fSHans de Goede 				if (data[i] == 0xff)
28271f33de0fSHans de Goede 					sd->sof_read++;
2828659fefa0SHans de Goede 				else if (data[i] == 0x00)
2829659fefa0SHans de Goede 					sd->sof_read = 1;
28301f33de0fSHans de Goede 				else
28311f33de0fSHans de Goede 					sd->sof_read = 0;
28321f33de0fSHans de Goede 				break;
28331f33de0fSHans de Goede 			case 2:
2834659fefa0SHans de Goede 				if (data[i] == byte3)
2835659fefa0SHans de Goede 					sd->sof_read++;
2836659fefa0SHans de Goede 				else if (data[i] == 0x00)
2837659fefa0SHans de Goede 					sd->sof_read = 1;
2838659fefa0SHans de Goede 				else
28391f33de0fSHans de Goede 					sd->sof_read = 0;
2840659fefa0SHans de Goede 				break;
2841659fefa0SHans de Goede 			case 3:
2842659fefa0SHans de Goede 				if (data[i] == byte4) {
2843659fefa0SHans de Goede 					sd->sof_read = 0;
2844659fefa0SHans de Goede 					return data + i + (sd->sof_len - 3);
284559f90a01SHans de Goede 				}
2846659fefa0SHans de Goede 				if (byte3 == 0x00 && data[i] == 0xff)
2847659fefa0SHans de Goede 					sd->sof_read = 2;
2848659fefa0SHans de Goede 				else if (data[i] == 0x00)
2849659fefa0SHans de Goede 					sd->sof_read = 1;
2850659fefa0SHans de Goede 				else
2851659fefa0SHans de Goede 					sd->sof_read = 0;
285259f90a01SHans de Goede 				break;
285359f90a01SHans de Goede 			}
285459f90a01SHans de Goede 		}
285559f90a01SHans de Goede 		break;
285659f90a01SHans de Goede 	case CIT_MODEL2:
285759f90a01SHans de Goede 	case CIT_MODEL4:
285859f90a01SHans de Goede 		/* TESTME we need to find a longer sof signature to avoid
285959f90a01SHans de Goede 		   false positives */
286059f90a01SHans de Goede 		for (i = 0; i < len; i++) {
286159f90a01SHans de Goede 			switch (sd->sof_read) {
286259f90a01SHans de Goede 			case 0:
286359f90a01SHans de Goede 				if (data[i] == 0x00)
286459f90a01SHans de Goede 					sd->sof_read++;
286559f90a01SHans de Goede 				break;
286659f90a01SHans de Goede 			case 1:
286759f90a01SHans de Goede 				sd->sof_read = 0;
286859f90a01SHans de Goede 				if (data[i] == 0xff) {
286959f90a01SHans de Goede 					if (i >= 4)
2870*37d5efb0SJoe Perches 						gspca_dbg(gspca_dev, D_FRAM,
2871*37d5efb0SJoe Perches 							  "header found at offset: %d: %02x %02x 00 %3ph\n\n",
2872659fefa0SHans de Goede 							  i - 1,
287359f90a01SHans de Goede 							  data[i - 4],
287459f90a01SHans de Goede 							  data[i - 3],
2875ee35fa22SAndy Shevchenko 							  &data[i]);
2876659fefa0SHans de Goede 					else
2877*37d5efb0SJoe Perches 						gspca_dbg(gspca_dev, D_FRAM,
2878*37d5efb0SJoe Perches 							  "header found at offset: %d: 00 %3ph\n\n",
2879659fefa0SHans de Goede 							  i - 1,
2880ee35fa22SAndy Shevchenko 							  &data[i]);
2881659fefa0SHans de Goede 					return data + i + (sd->sof_len - 1);
28821f33de0fSHans de Goede 				}
28831f33de0fSHans de Goede 				break;
28841f33de0fSHans de Goede 			}
28851f33de0fSHans de Goede 		}
28861f33de0fSHans de Goede 		break;
28871f33de0fSHans de Goede 	}
28881f33de0fSHans de Goede 	return NULL;
28891f33de0fSHans de Goede }
28901f33de0fSHans de Goede 
28911f33de0fSHans de Goede static void sd_pkt_scan(struct gspca_dev *gspca_dev,
28921f33de0fSHans de Goede 			u8 *data, int len)
28931f33de0fSHans de Goede {
289459f90a01SHans de Goede 	struct sd *sd = (struct sd *) gspca_dev;
28951f33de0fSHans de Goede 	unsigned char *sof;
28961f33de0fSHans de Goede 
28971f33de0fSHans de Goede 	sof = cit_find_sof(gspca_dev, data, len);
28981f33de0fSHans de Goede 	if (sof) {
28991f33de0fSHans de Goede 		int n;
29001f33de0fSHans de Goede 
29011f33de0fSHans de Goede 		/* finish decoding current frame */
29021f33de0fSHans de Goede 		n = sof - data;
290359f90a01SHans de Goede 		if (n > sd->sof_len)
290459f90a01SHans de Goede 			n -= sd->sof_len;
29051f33de0fSHans de Goede 		else
29061f33de0fSHans de Goede 			n = 0;
29071f33de0fSHans de Goede 		gspca_frame_add(gspca_dev, LAST_PACKET,
29081f33de0fSHans de Goede 				data, n);
29091f33de0fSHans de Goede 		gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
29101f33de0fSHans de Goede 		len -= sof - data;
29111f33de0fSHans de Goede 		data = sof;
29121f33de0fSHans de Goede 	}
29131f33de0fSHans de Goede 
29141f33de0fSHans de Goede 	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
29151f33de0fSHans de Goede }
29161f33de0fSHans de Goede 
2917e32d6eb8SPeter Senna Tschudin #if IS_ENABLED(CONFIG_INPUT)
2918e0657be5SHans de Goede static void cit_check_button(struct gspca_dev *gspca_dev)
2919e0657be5SHans de Goede {
2920e0657be5SHans de Goede 	int new_button_state;
2921e0657be5SHans de Goede 	struct sd *sd = (struct sd *)gspca_dev;
2922e0657be5SHans de Goede 
2923e0657be5SHans de Goede 	switch (sd->model) {
2924e0657be5SHans de Goede 	case CIT_MODEL3:
2925e0657be5SHans de Goede 	case CIT_IBM_NETCAM_PRO:
2926e0657be5SHans de Goede 		break;
2927e0657be5SHans de Goede 	default: /* TEST ME unknown if this works on other models too */
2928e0657be5SHans de Goede 		return;
2929e0657be5SHans de Goede 	}
2930e0657be5SHans de Goede 
2931e0657be5SHans de Goede 	/* Read the button state */
2932e0657be5SHans de Goede 	cit_read_reg(gspca_dev, 0x0113, 0);
2933e0657be5SHans de Goede 	new_button_state = !gspca_dev->usb_buf[0];
2934e0657be5SHans de Goede 
2935e0657be5SHans de Goede 	/* Tell the cam we've seen the button press, notice that this
2936e0657be5SHans de Goede 	   is a nop (iow the cam keeps reporting pressed) until the
2937e0657be5SHans de Goede 	   button is actually released. */
2938e0657be5SHans de Goede 	if (new_button_state)
2939e0657be5SHans de Goede 		cit_write_reg(gspca_dev, 0x01, 0x0113);
2940e0657be5SHans de Goede 
2941e0657be5SHans de Goede 	if (sd->button_state != new_button_state) {
2942e0657be5SHans de Goede 		input_report_key(gspca_dev->input_dev, KEY_CAMERA,
2943e0657be5SHans de Goede 				 new_button_state);
2944e0657be5SHans de Goede 		input_sync(gspca_dev->input_dev);
2945e0657be5SHans de Goede 		sd->button_state = new_button_state;
2946e0657be5SHans de Goede 	}
2947e0657be5SHans de Goede }
2948e0657be5SHans de Goede #endif
29491f33de0fSHans de Goede 
2950d5d875cbSHans Verkuil static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
2951d5d875cbSHans Verkuil {
2952d5d875cbSHans Verkuil 	struct gspca_dev *gspca_dev =
2953d5d875cbSHans Verkuil 		container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
2954d5d875cbSHans Verkuil 	struct sd *sd = (struct sd *)gspca_dev;
2955d5d875cbSHans Verkuil 
2956d5d875cbSHans Verkuil 	gspca_dev->usb_err = 0;
2957d5d875cbSHans Verkuil 
2958d5d875cbSHans Verkuil 	if (!gspca_dev->streaming)
2959d5d875cbSHans Verkuil 		return 0;
2960d5d875cbSHans Verkuil 
2961d5d875cbSHans Verkuil 	if (sd->stop_on_control_change)
2962d5d875cbSHans Verkuil 		sd_stopN(gspca_dev);
2963d5d875cbSHans Verkuil 	switch (ctrl->id) {
2964d5d875cbSHans Verkuil 	case V4L2_CID_BRIGHTNESS:
2965d5d875cbSHans Verkuil 		cit_set_brightness(gspca_dev, ctrl->val);
2966d5d875cbSHans Verkuil 		break;
2967d5d875cbSHans Verkuil 	case V4L2_CID_CONTRAST:
2968d5d875cbSHans Verkuil 		cit_set_contrast(gspca_dev, ctrl->val);
2969d5d875cbSHans Verkuil 		break;
2970d5d875cbSHans Verkuil 	case V4L2_CID_HUE:
2971d5d875cbSHans Verkuil 		cit_set_hue(gspca_dev, ctrl->val);
2972d5d875cbSHans Verkuil 		break;
2973d5d875cbSHans Verkuil 	case V4L2_CID_HFLIP:
2974d5d875cbSHans Verkuil 		cit_set_hflip(gspca_dev, ctrl->val);
2975d5d875cbSHans Verkuil 		break;
2976d5d875cbSHans Verkuil 	case V4L2_CID_SHARPNESS:
2977d5d875cbSHans Verkuil 		cit_set_sharpness(gspca_dev, ctrl->val);
2978d5d875cbSHans Verkuil 		break;
2979d5d875cbSHans Verkuil 	case V4L2_CID_BACKLIGHT_COMPENSATION:
2980d5d875cbSHans Verkuil 		cit_set_lighting(gspca_dev, ctrl->val);
2981d5d875cbSHans Verkuil 		break;
2982d5d875cbSHans Verkuil 	}
2983d5d875cbSHans Verkuil 	if (sd->stop_on_control_change)
2984d5d875cbSHans Verkuil 		cit_restart_stream(gspca_dev);
2985d5d875cbSHans Verkuil 	return gspca_dev->usb_err;
2986d5d875cbSHans Verkuil }
2987d5d875cbSHans Verkuil 
2988d5d875cbSHans Verkuil static const struct v4l2_ctrl_ops sd_ctrl_ops = {
2989d5d875cbSHans Verkuil 	.s_ctrl = sd_s_ctrl,
2990d5d875cbSHans Verkuil };
2991d5d875cbSHans Verkuil 
2992d5d875cbSHans Verkuil static int sd_init_controls(struct gspca_dev *gspca_dev)
2993d5d875cbSHans Verkuil {
2994d5d875cbSHans Verkuil 	struct sd *sd = (struct sd *)gspca_dev;
2995d5d875cbSHans Verkuil 	struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
2996d5d875cbSHans Verkuil 	bool has_brightness;
2997d5d875cbSHans Verkuil 	bool has_contrast;
2998d5d875cbSHans Verkuil 	bool has_hue;
2999d5d875cbSHans Verkuil 	bool has_sharpness;
3000d5d875cbSHans Verkuil 	bool has_lighting;
3001d5d875cbSHans Verkuil 	bool has_hflip;
3002d5d875cbSHans Verkuil 
3003d5d875cbSHans Verkuil 	has_brightness = has_contrast = has_hue =
3004d5d875cbSHans Verkuil 		has_sharpness = has_hflip = has_lighting = false;
3005d5d875cbSHans Verkuil 	switch (sd->model) {
3006d5d875cbSHans Verkuil 	case CIT_MODEL0:
3007d5d875cbSHans Verkuil 		has_contrast = has_hflip = true;
3008d5d875cbSHans Verkuil 		break;
3009d5d875cbSHans Verkuil 	case CIT_MODEL1:
3010d5d875cbSHans Verkuil 		has_brightness = has_contrast =
3011d5d875cbSHans Verkuil 			has_sharpness = has_lighting = true;
3012d5d875cbSHans Verkuil 		break;
3013d5d875cbSHans Verkuil 	case CIT_MODEL2:
3014d5d875cbSHans Verkuil 		has_brightness = has_hue = has_lighting = true;
3015d5d875cbSHans Verkuil 		break;
3016d5d875cbSHans Verkuil 	case CIT_MODEL3:
3017d5d875cbSHans Verkuil 		has_brightness = has_contrast = has_sharpness = true;
3018d5d875cbSHans Verkuil 		break;
3019d5d875cbSHans Verkuil 	case CIT_MODEL4:
3020d5d875cbSHans Verkuil 		has_brightness = has_hue = true;
3021d5d875cbSHans Verkuil 		break;
3022d5d875cbSHans Verkuil 	case CIT_IBM_NETCAM_PRO:
3023d5d875cbSHans Verkuil 		has_brightness = has_hue =
3024d5d875cbSHans Verkuil 			has_sharpness = has_hflip = has_lighting = true;
3025d5d875cbSHans Verkuil 		break;
3026d5d875cbSHans Verkuil 	}
3027d5d875cbSHans Verkuil 	gspca_dev->vdev.ctrl_handler = hdl;
3028d5d875cbSHans Verkuil 	v4l2_ctrl_handler_init(hdl, 5);
3029d5d875cbSHans Verkuil 	if (has_brightness)
3030d5d875cbSHans Verkuil 		v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
3031d5d875cbSHans Verkuil 			V4L2_CID_BRIGHTNESS, 0, 63, 1, 32);
3032d5d875cbSHans Verkuil 	if (has_contrast)
3033d5d875cbSHans Verkuil 		v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
3034d5d875cbSHans Verkuil 			V4L2_CID_CONTRAST, 0, 20, 1, 10);
3035d5d875cbSHans Verkuil 	if (has_hue)
3036d5d875cbSHans Verkuil 		v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
3037d5d875cbSHans Verkuil 			V4L2_CID_HUE, 0, 127, 1, 63);
3038d5d875cbSHans Verkuil 	if (has_sharpness)
3039d5d875cbSHans Verkuil 		v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
3040d5d875cbSHans Verkuil 			V4L2_CID_SHARPNESS, 0, 6, 1, 3);
3041d5d875cbSHans Verkuil 	if (has_lighting)
3042d5d875cbSHans Verkuil 		sd->lighting = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
3043d5d875cbSHans Verkuil 			V4L2_CID_BACKLIGHT_COMPENSATION, 0, 2, 1, 1);
3044d5d875cbSHans Verkuil 	if (has_hflip)
3045d5d875cbSHans Verkuil 		v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
3046d5d875cbSHans Verkuil 			V4L2_CID_HFLIP, 0, 1, 1, 0);
3047d5d875cbSHans Verkuil 
3048d5d875cbSHans Verkuil 	if (hdl->error) {
3049d5d875cbSHans Verkuil 		pr_err("Could not initialize controls\n");
3050d5d875cbSHans Verkuil 		return hdl->error;
3051d5d875cbSHans Verkuil 	}
3052d5d875cbSHans Verkuil 	return 0;
3053d5d875cbSHans Verkuil }
3054d5d875cbSHans Verkuil 
30551f33de0fSHans de Goede /* sub-driver description */
30561f33de0fSHans de Goede static const struct sd_desc sd_desc = {
30571f33de0fSHans de Goede 	.name = MODULE_NAME,
30581f33de0fSHans de Goede 	.config = sd_config,
30591f33de0fSHans de Goede 	.init = sd_init,
3060d5d875cbSHans Verkuil 	.init_controls = sd_init_controls,
30611f33de0fSHans de Goede 	.start = sd_start,
30621f33de0fSHans de Goede 	.stopN = sd_stopN,
30631f33de0fSHans de Goede 	.stop0 = sd_stop0,
30641f33de0fSHans de Goede 	.pkt_scan = sd_pkt_scan,
3065e32d6eb8SPeter Senna Tschudin #if IS_ENABLED(CONFIG_INPUT)
3066e0657be5SHans de Goede 	.dq_callback = cit_check_button,
3067e0657be5SHans de Goede 	.other_input = 1,
3068e0657be5SHans de Goede #endif
30691f33de0fSHans de Goede };
30701f33de0fSHans de Goede 
307159f8b0bfSHans de Goede static const struct sd_desc sd_desc_isoc_nego = {
307259f8b0bfSHans de Goede 	.name = MODULE_NAME,
307359f8b0bfSHans de Goede 	.config = sd_config,
307459f8b0bfSHans de Goede 	.init = sd_init,
3075d5d875cbSHans Verkuil 	.init_controls = sd_init_controls,
307659f8b0bfSHans de Goede 	.start = sd_start,
3077bc46bae6SHans de Goede 	.isoc_init = sd_isoc_init,
307859f8b0bfSHans de Goede 	.isoc_nego = sd_isoc_nego,
307959f8b0bfSHans de Goede 	.stopN = sd_stopN,
308059f8b0bfSHans de Goede 	.stop0 = sd_stop0,
308159f8b0bfSHans de Goede 	.pkt_scan = sd_pkt_scan,
3082e32d6eb8SPeter Senna Tschudin #if IS_ENABLED(CONFIG_INPUT)
3083e0657be5SHans de Goede 	.dq_callback = cit_check_button,
3084e0657be5SHans de Goede 	.other_input = 1,
3085e0657be5SHans de Goede #endif
308659f8b0bfSHans de Goede };
308759f8b0bfSHans de Goede 
30881f33de0fSHans de Goede /* -- module initialisation -- */
308995c967c1SJean-François Moine static const struct usb_device_id device_table[] = {
3090659fefa0SHans de Goede 	{ USB_DEVICE_VER(0x0545, 0x8080, 0x0001, 0x0001), .driver_info = CIT_MODEL0 },
30911f33de0fSHans de Goede 	{ USB_DEVICE_VER(0x0545, 0x8080, 0x0002, 0x0002), .driver_info = CIT_MODEL1 },
30921f33de0fSHans de Goede 	{ USB_DEVICE_VER(0x0545, 0x8080, 0x030a, 0x030a), .driver_info = CIT_MODEL2 },
30931f33de0fSHans de Goede 	{ USB_DEVICE_VER(0x0545, 0x8080, 0x0301, 0x0301), .driver_info = CIT_MODEL3 },
30941f33de0fSHans de Goede 	{ USB_DEVICE_VER(0x0545, 0x8002, 0x030a, 0x030a), .driver_info = CIT_MODEL4 },
30951f33de0fSHans de Goede 	{ USB_DEVICE_VER(0x0545, 0x800c, 0x030a, 0x030a), .driver_info = CIT_MODEL2 },
30961f33de0fSHans de Goede 	{ USB_DEVICE_VER(0x0545, 0x800d, 0x030a, 0x030a), .driver_info = CIT_MODEL4 },
30971f33de0fSHans de Goede 	{}
30981f33de0fSHans de Goede };
30991f33de0fSHans de Goede MODULE_DEVICE_TABLE(usb, device_table);
31001f33de0fSHans de Goede 
31011f33de0fSHans de Goede /* -- device connect -- */
31021f33de0fSHans de Goede static int sd_probe(struct usb_interface *intf,
31031f33de0fSHans de Goede 			const struct usb_device_id *id)
31041f33de0fSHans de Goede {
310559f8b0bfSHans de Goede 	const struct sd_desc *desc = &sd_desc;
310659f8b0bfSHans de Goede 
3107659fefa0SHans de Goede 	switch (id->driver_info) {
3108659fefa0SHans de Goede 	case CIT_MODEL0:
3109659fefa0SHans de Goede 	case CIT_MODEL1:
3110659fefa0SHans de Goede 		if (intf->cur_altsetting->desc.bInterfaceNumber != 2)
3111659fefa0SHans de Goede 			return -ENODEV;
3112659fefa0SHans de Goede 		break;
3113659fefa0SHans de Goede 	case CIT_MODEL2:
3114659fefa0SHans de Goede 	case CIT_MODEL4:
3115659fefa0SHans de Goede 		if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
3116659fefa0SHans de Goede 			return -ENODEV;
3117659fefa0SHans de Goede 		break;
311859f8b0bfSHans de Goede 	case CIT_MODEL3:
311959f8b0bfSHans de Goede 		if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
312059f8b0bfSHans de Goede 			return -ENODEV;
312159f8b0bfSHans de Goede 		/* FIXME this likely applies to all model3 cams and probably
312259f8b0bfSHans de Goede 		   to other models too. */
312359f8b0bfSHans de Goede 		if (ibm_netcam_pro)
312459f8b0bfSHans de Goede 			desc = &sd_desc_isoc_nego;
312559f8b0bfSHans de Goede 		break;
3126659fefa0SHans de Goede 	}
3127659fefa0SHans de Goede 
312859f8b0bfSHans de Goede 	return gspca_dev_probe2(intf, id, desc, sizeof(struct sd), THIS_MODULE);
31291f33de0fSHans de Goede }
31301f33de0fSHans de Goede 
31311f33de0fSHans de Goede static struct usb_driver sd_driver = {
31321f33de0fSHans de Goede 	.name = MODULE_NAME,
31331f33de0fSHans de Goede 	.id_table = device_table,
31341f33de0fSHans de Goede 	.probe = sd_probe,
31351f33de0fSHans de Goede 	.disconnect = gspca_disconnect,
31361f33de0fSHans de Goede #ifdef CONFIG_PM
31371f33de0fSHans de Goede 	.suspend = gspca_suspend,
31381f33de0fSHans de Goede 	.resume = gspca_resume,
31398bb58964SHans de Goede 	.reset_resume = gspca_resume,
31401f33de0fSHans de Goede #endif
31411f33de0fSHans de Goede };
31421f33de0fSHans de Goede 
3143ecb3b2b3SGreg Kroah-Hartman module_usb_driver(sd_driver);
3144