xref: /linux/drivers/media/usb/gspca/xirlink_cit.c (revision 4f6b838c378a52ea3ae0b15f12ca8a20849072fa)
1c942fddfSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
21f33de0fSHans de Goede /*
31f33de0fSHans de Goede  * USB IBM C-It Video Camera driver
41f33de0fSHans de Goede  *
51f33de0fSHans de Goede  * Supports Xirlink C-It Video Camera, IBM PC Camera,
61f33de0fSHans de Goede  * IBM NetCamera and Veo Stingray.
71f33de0fSHans de Goede  *
81fddcf0eSHans de Goede  * Copyright (C) 2010 Hans de Goede <hdegoede@redhat.com>
91f33de0fSHans de Goede  *
101f33de0fSHans de Goede  * This driver is based on earlier work of:
111f33de0fSHans de Goede  *
121f33de0fSHans de Goede  * (C) Copyright 1999 Johannes Erdfelt
131f33de0fSHans de Goede  * (C) Copyright 1999 Randy Dunlap
141f33de0fSHans de Goede  */
151f33de0fSHans de Goede 
16133a9fe9SJoe Perches #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
17133a9fe9SJoe Perches 
181f33de0fSHans de Goede #define MODULE_NAME "xirlink-cit"
191f33de0fSHans de Goede 
20e0657be5SHans de Goede #include <linux/input.h>
211f33de0fSHans de Goede #include "gspca.h"
221f33de0fSHans de Goede 
231fddcf0eSHans de Goede MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
241f33de0fSHans de Goede MODULE_DESCRIPTION("Xirlink C-IT");
251f33de0fSHans de Goede MODULE_LICENSE("GPL");
261f33de0fSHans de Goede 
271f33de0fSHans de Goede /* FIXME we should autodetect this */
281f33de0fSHans de Goede static int ibm_netcam_pro;
291f33de0fSHans de Goede module_param(ibm_netcam_pro, int, 0);
301f33de0fSHans de Goede MODULE_PARM_DESC(ibm_netcam_pro,
311f33de0fSHans de Goede 		 "Use IBM Netcamera Pro init sequences for Model 3 cams");
321f33de0fSHans de Goede 
331f33de0fSHans de Goede /* FIXME this should be handled through the V4L2 input selection API */
341f33de0fSHans de Goede static int rca_input;
351f33de0fSHans de Goede module_param(rca_input, int, 0644);
361f33de0fSHans de Goede MODULE_PARM_DESC(rca_input,
371f33de0fSHans de Goede 		 "Use rca input instead of ccd sensor on Model 3 cams");
381f33de0fSHans de Goede 
391f33de0fSHans de Goede /* specific webcam descriptor */
401f33de0fSHans de Goede struct sd {
411f33de0fSHans de Goede 	struct gspca_dev gspca_dev;		/* !! must be the first item */
42d5d875cbSHans Verkuil 	struct v4l2_ctrl *lighting;
431f33de0fSHans de Goede 	u8 model;
44659fefa0SHans de Goede #define CIT_MODEL0 0 /* bcd version 0.01 cams ie the xvp-500 */
45659fefa0SHans de Goede #define CIT_MODEL1 1 /* The model 1 - 4 nomenclature comes from the old */
46659fefa0SHans de Goede #define CIT_MODEL2 2 /* ibmcam driver */
47659fefa0SHans de Goede #define CIT_MODEL3 3
48659fefa0SHans de Goede #define CIT_MODEL4 4
49659fefa0SHans de Goede #define CIT_IBM_NETCAM_PRO 5
501f33de0fSHans de Goede 	u8 input_index;
51e0657be5SHans de Goede 	u8 button_state;
5259f90a01SHans de Goede 	u8 stop_on_control_change;
531f33de0fSHans de Goede 	u8 sof_read;
5459f90a01SHans de Goede 	u8 sof_len;
551f33de0fSHans de Goede };
561f33de0fSHans de Goede 
571f33de0fSHans de Goede static void sd_stop0(struct gspca_dev *gspca_dev);
581f33de0fSHans de Goede 
5959f90a01SHans de Goede static const struct v4l2_pix_format cif_yuv_mode[] = {
6059f90a01SHans de Goede 	{176, 144, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
6159f90a01SHans de Goede 		.bytesperline = 176,
622c4e776aSHans de Goede 		.sizeimage = 176 * 144 * 3 / 2 + 4,
6359f90a01SHans de Goede 		.colorspace = V4L2_COLORSPACE_SRGB},
6459f90a01SHans de Goede 	{352, 288, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
6559f90a01SHans de Goede 		.bytesperline = 352,
662c4e776aSHans de Goede 		.sizeimage = 352 * 288 * 3 / 2 + 4,
6759f90a01SHans de Goede 		.colorspace = V4L2_COLORSPACE_SRGB},
681f33de0fSHans de Goede };
691f33de0fSHans de Goede 
701f33de0fSHans de Goede static const struct v4l2_pix_format vga_yuv_mode[] = {
711f33de0fSHans de Goede 	{160, 120, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
721f33de0fSHans de Goede 		.bytesperline = 160,
732c4e776aSHans de Goede 		.sizeimage = 160 * 120 * 3 / 2 + 4,
741f33de0fSHans de Goede 		.colorspace = V4L2_COLORSPACE_SRGB},
751f33de0fSHans de Goede 	{320, 240, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
761f33de0fSHans de Goede 		.bytesperline = 320,
772c4e776aSHans de Goede 		.sizeimage = 320 * 240 * 3 / 2 + 4,
781f33de0fSHans de Goede 		.colorspace = V4L2_COLORSPACE_SRGB},
791f33de0fSHans de Goede 	{640, 480, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
801f33de0fSHans de Goede 		.bytesperline = 640,
812c4e776aSHans de Goede 		.sizeimage = 640 * 480 * 3 / 2 + 4,
821f33de0fSHans de Goede 		.colorspace = V4L2_COLORSPACE_SRGB},
831f33de0fSHans de Goede };
841f33de0fSHans de Goede 
85659fefa0SHans de Goede static const struct v4l2_pix_format model0_mode[] = {
86659fefa0SHans de Goede 	{160, 120, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
87659fefa0SHans de Goede 		.bytesperline = 160,
882c4e776aSHans de Goede 		.sizeimage = 160 * 120 * 3 / 2 + 4,
89659fefa0SHans de Goede 		.colorspace = V4L2_COLORSPACE_SRGB},
90659fefa0SHans de Goede 	{176, 144, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
91659fefa0SHans de Goede 		.bytesperline = 176,
922c4e776aSHans de Goede 		.sizeimage = 176 * 144 * 3 / 2 + 4,
93659fefa0SHans de Goede 		.colorspace = V4L2_COLORSPACE_SRGB},
94659fefa0SHans de Goede 	{320, 240, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
95659fefa0SHans de Goede 		.bytesperline = 320,
962c4e776aSHans de Goede 		.sizeimage = 320 * 240 * 3 / 2 + 4,
97659fefa0SHans de Goede 		.colorspace = V4L2_COLORSPACE_SRGB},
98659fefa0SHans de Goede };
99659fefa0SHans de Goede 
10059f90a01SHans de Goede static const struct v4l2_pix_format model2_mode[] = {
10159f90a01SHans de Goede 	{160, 120, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
10259f90a01SHans de Goede 		.bytesperline = 160,
1032c4e776aSHans de Goede 		.sizeimage = 160 * 120 * 3 / 2 + 4,
10459f90a01SHans de Goede 		.colorspace = V4L2_COLORSPACE_SRGB},
10559f90a01SHans de Goede 	{176, 144, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
10659f90a01SHans de Goede 		.bytesperline = 176,
1072c4e776aSHans de Goede 		.sizeimage = 176 * 144 * 3 / 2 + 4,
10859f90a01SHans de Goede 		.colorspace = V4L2_COLORSPACE_SRGB},
10959f90a01SHans de Goede 	{320, 240, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
11059f90a01SHans de Goede 		.bytesperline = 320,
1112c4e776aSHans de Goede 		.sizeimage = 320 * 240 + 4,
11259f90a01SHans de Goede 		.colorspace = V4L2_COLORSPACE_SRGB},
11359f90a01SHans de Goede 	{352, 288, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
11459f90a01SHans de Goede 		.bytesperline = 352,
1152c4e776aSHans de Goede 		.sizeimage = 352 * 288 + 4,
11659f90a01SHans de Goede 		.colorspace = V4L2_COLORSPACE_SRGB},
11759f90a01SHans de Goede };
11859f90a01SHans de Goede 
1191f33de0fSHans de Goede /*
1201f33de0fSHans de Goede  * 01.01.08 - Added for RCA video in support -LO
1211f33de0fSHans de Goede  * This struct is used to init the Model3 cam to use the RCA video in port
1221f33de0fSHans de Goede  * instead of the CCD sensor.
1231f33de0fSHans de Goede  */
1241f33de0fSHans de Goede static const u16 rca_initdata[][3] = {
1251f33de0fSHans de Goede 	{0, 0x0000, 0x010c},
1261f33de0fSHans de Goede 	{0, 0x0006, 0x012c},
1271f33de0fSHans de Goede 	{0, 0x0078, 0x012d},
1281f33de0fSHans de Goede 	{0, 0x0046, 0x012f},
1291f33de0fSHans de Goede 	{0, 0xd141, 0x0124},
1301f33de0fSHans de Goede 	{0, 0x0000, 0x0127},
1311f33de0fSHans de Goede 	{0, 0xfea8, 0x0124},
1321f33de0fSHans de Goede 	{1, 0x0000, 0x0116},
1331f33de0fSHans de Goede 	{0, 0x0064, 0x0116},
1341f33de0fSHans de Goede 	{1, 0x0000, 0x0115},
1351f33de0fSHans de Goede 	{0, 0x0003, 0x0115},
1361f33de0fSHans de Goede 	{0, 0x0008, 0x0123},
1371f33de0fSHans de Goede 	{0, 0x0000, 0x0117},
1381f33de0fSHans de Goede 	{0, 0x0000, 0x0112},
1391f33de0fSHans de Goede 	{0, 0x0080, 0x0100},
1401f33de0fSHans de Goede 	{0, 0x0000, 0x0100},
1411f33de0fSHans de Goede 	{1, 0x0000, 0x0116},
1421f33de0fSHans de Goede 	{0, 0x0060, 0x0116},
1431f33de0fSHans de Goede 	{0, 0x0002, 0x0112},
1441f33de0fSHans de Goede 	{0, 0x0000, 0x0123},
1451f33de0fSHans de Goede 	{0, 0x0001, 0x0117},
1461f33de0fSHans de Goede 	{0, 0x0040, 0x0108},
1471f33de0fSHans de Goede 	{0, 0x0019, 0x012c},
1481f33de0fSHans de Goede 	{0, 0x0040, 0x0116},
1491f33de0fSHans de Goede 	{0, 0x000a, 0x0115},
1501f33de0fSHans de Goede 	{0, 0x000b, 0x0115},
1511f33de0fSHans de Goede 	{0, 0x0078, 0x012d},
1521f33de0fSHans de Goede 	{0, 0x0046, 0x012f},
1531f33de0fSHans de Goede 	{0, 0xd141, 0x0124},
1541f33de0fSHans de Goede 	{0, 0x0000, 0x0127},
1551f33de0fSHans de Goede 	{0, 0xfea8, 0x0124},
1561f33de0fSHans de Goede 	{0, 0x0064, 0x0116},
1571f33de0fSHans de Goede 	{0, 0x0000, 0x0115},
1581f33de0fSHans de Goede 	{0, 0x0001, 0x0115},
1591f33de0fSHans de Goede 	{0, 0xffff, 0x0124},
1601f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
1611f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
1621f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
1631f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
1641f33de0fSHans de Goede 	{0, 0x00aa, 0x0127},
1651f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
1661f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
1671f33de0fSHans de Goede 	{0, 0x0000, 0x0127},
1681f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
1691f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
1701f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
1711f33de0fSHans de Goede 	{0, 0xffff, 0x0124},
1721f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
1731f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
1741f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
1751f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
1761f33de0fSHans de Goede 	{0, 0x00f2, 0x0127},
1771f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
1781f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
1791f33de0fSHans de Goede 	{0, 0x000f, 0x0127},
1801f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
1811f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
1821f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
1831f33de0fSHans de Goede 	{0, 0xffff, 0x0124},
1841f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
1851f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
1861f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
1871f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
1881f33de0fSHans de Goede 	{0, 0x00f8, 0x0127},
1891f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
1901f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
1911f33de0fSHans de Goede 	{0, 0x00fc, 0x0127},
1921f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
1931f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
1941f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
1951f33de0fSHans de Goede 	{0, 0xffff, 0x0124},
1961f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
1971f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
1981f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
1991f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2001f33de0fSHans de Goede 	{0, 0x00f9, 0x0127},
2011f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2021f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2031f33de0fSHans de Goede 	{0, 0x003c, 0x0127},
2041f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2051f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2061f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
2071f33de0fSHans de Goede 	{0, 0xffff, 0x0124},
2081f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
2091f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
2101f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2111f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2121f33de0fSHans de Goede 	{0, 0x0027, 0x0127},
2131f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2141f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2151f33de0fSHans de Goede 	{0, 0x0019, 0x0127},
2161f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2171f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2181f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
2191f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
2201f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
2211f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2221f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2231f33de0fSHans de Goede 	{0, 0x0037, 0x0127},
2241f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2251f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2261f33de0fSHans de Goede 	{0, 0x0000, 0x0127},
2271f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2281f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2291f33de0fSHans de Goede 	{0, 0x0021, 0x0127},
2301f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2311f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2321f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
2331f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
2341f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
2351f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2361f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2371f33de0fSHans de Goede 	{0, 0x0038, 0x0127},
2381f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2391f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2401f33de0fSHans de Goede 	{0, 0x0006, 0x0127},
2411f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2421f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2431f33de0fSHans de Goede 	{0, 0x0045, 0x0127},
2441f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2451f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2461f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
2471f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
2481f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
2491f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2501f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2511f33de0fSHans de Goede 	{0, 0x0037, 0x0127},
2521f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2531f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2541f33de0fSHans de Goede 	{0, 0x0001, 0x0127},
2551f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2561f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2571f33de0fSHans de Goede 	{0, 0x002a, 0x0127},
2581f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2591f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2601f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
2611f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
2621f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
2631f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2641f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2651f33de0fSHans de Goede 	{0, 0x0038, 0x0127},
2661f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2671f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2681f33de0fSHans de Goede 	{0, 0x0000, 0x0127},
2691f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2701f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2711f33de0fSHans de Goede 	{0, 0x000e, 0x0127},
2721f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2731f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2741f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
2751f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
2761f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
2771f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2781f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2791f33de0fSHans de Goede 	{0, 0x0037, 0x0127},
2801f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2811f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2821f33de0fSHans de Goede 	{0, 0x0001, 0x0127},
2831f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2841f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2851f33de0fSHans de Goede 	{0, 0x002b, 0x0127},
2861f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2871f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2881f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
2891f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
2901f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
2911f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2921f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2931f33de0fSHans de Goede 	{0, 0x0038, 0x0127},
2941f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2951f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2961f33de0fSHans de Goede 	{0, 0x0001, 0x0127},
2971f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
2981f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
2991f33de0fSHans de Goede 	{0, 0x00f4, 0x0127},
3001f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3011f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3021f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
3031f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
3041f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
3051f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3061f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3071f33de0fSHans de Goede 	{0, 0x0037, 0x0127},
3081f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3091f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3101f33de0fSHans de Goede 	{0, 0x0001, 0x0127},
3111f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3121f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3131f33de0fSHans de Goede 	{0, 0x002c, 0x0127},
3141f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3151f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3161f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
3171f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
3181f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
3191f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3201f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3211f33de0fSHans de Goede 	{0, 0x0038, 0x0127},
3221f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3231f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3241f33de0fSHans de Goede 	{0, 0x0001, 0x0127},
3251f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3261f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3271f33de0fSHans de Goede 	{0, 0x0004, 0x0127},
3281f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3291f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3301f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
3311f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
3321f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
3331f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3341f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3351f33de0fSHans de Goede 	{0, 0x0037, 0x0127},
3361f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3371f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3381f33de0fSHans de Goede 	{0, 0x0001, 0x0127},
3391f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3401f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3411f33de0fSHans de Goede 	{0, 0x002d, 0x0127},
3421f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3431f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3441f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
3451f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
3461f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
3471f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3481f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3491f33de0fSHans de Goede 	{0, 0x0038, 0x0127},
3501f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3511f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3521f33de0fSHans de Goede 	{0, 0x0000, 0x0127},
3531f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3541f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3551f33de0fSHans de Goede 	{0, 0x0014, 0x0127},
3561f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3571f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3581f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
3591f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
3601f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
3611f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3621f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3631f33de0fSHans de Goede 	{0, 0x0037, 0x0127},
3641f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3651f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3661f33de0fSHans de Goede 	{0, 0x0001, 0x0127},
3671f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3681f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3691f33de0fSHans de Goede 	{0, 0x002e, 0x0127},
3701f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3711f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3721f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
3731f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
3741f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
3751f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3761f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3771f33de0fSHans de Goede 	{0, 0x0038, 0x0127},
3781f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3791f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3801f33de0fSHans de Goede 	{0, 0x0003, 0x0127},
3811f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3821f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3831f33de0fSHans de Goede 	{0, 0x0000, 0x0127},
3841f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3851f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3861f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
3871f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
3881f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
3891f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3901f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3911f33de0fSHans de Goede 	{0, 0x0037, 0x0127},
3921f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3931f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3941f33de0fSHans de Goede 	{0, 0x0001, 0x0127},
3951f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3961f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
3971f33de0fSHans de Goede 	{0, 0x002f, 0x0127},
3981f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
3991f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
4001f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
4011f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
4021f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
4031f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
4041f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
4051f33de0fSHans de Goede 	{0, 0x0038, 0x0127},
4061f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
4071f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
4081f33de0fSHans de Goede 	{0, 0x0003, 0x0127},
4091f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
4101f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
4111f33de0fSHans de Goede 	{0, 0x0014, 0x0127},
4121f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
4131f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
4141f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
4151f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
4161f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
4171f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
4181f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
4191f33de0fSHans de Goede 	{0, 0x0037, 0x0127},
4201f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
4211f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
4221f33de0fSHans de Goede 	{0, 0x0001, 0x0127},
4231f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
4241f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
4251f33de0fSHans de Goede 	{0, 0x0040, 0x0127},
4261f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
4271f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
4281f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
4291f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
4301f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
4311f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
4321f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
4331f33de0fSHans de Goede 	{0, 0x0038, 0x0127},
4341f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
4351f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
4361f33de0fSHans de Goede 	{0, 0x0000, 0x0127},
4371f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
4381f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
4391f33de0fSHans de Goede 	{0, 0x0040, 0x0127},
4401f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
4411f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
4421f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
4431f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
4441f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
4451f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
4461f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
4471f33de0fSHans de Goede 	{0, 0x0037, 0x0127},
4481f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
4491f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
4501f33de0fSHans de Goede 	{0, 0x0001, 0x0127},
4511f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
4521f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
4531f33de0fSHans de Goede 	{0, 0x0053, 0x0127},
4541f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
4551f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
4561f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
4571f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
4581f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
4591f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
4601f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
4611f33de0fSHans de Goede 	{0, 0x0038, 0x0127},
4621f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
4631f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
4641f33de0fSHans de Goede 	{0, 0x0000, 0x0127},
4651f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
4661f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
4671f33de0fSHans de Goede 	{0, 0x0038, 0x0127},
4681f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
4691f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
4701f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
4711f33de0fSHans de Goede 	{0, 0x0000, 0x0101},
4721f33de0fSHans de Goede 	{0, 0x00a0, 0x0103},
4731f33de0fSHans de Goede 	{0, 0x0078, 0x0105},
4741f33de0fSHans de Goede 	{0, 0x0000, 0x010a},
4751f33de0fSHans de Goede 	{0, 0x0024, 0x010b},
4761f33de0fSHans de Goede 	{0, 0x0028, 0x0119},
4771f33de0fSHans de Goede 	{0, 0x0088, 0x011b},
4781f33de0fSHans de Goede 	{0, 0x0002, 0x011d},
4791f33de0fSHans de Goede 	{0, 0x0003, 0x011e},
4801f33de0fSHans de Goede 	{0, 0x0000, 0x0129},
4811f33de0fSHans de Goede 	{0, 0x00fc, 0x012b},
4821f33de0fSHans de Goede 	{0, 0x0008, 0x0102},
4831f33de0fSHans de Goede 	{0, 0x0000, 0x0104},
4841f33de0fSHans de Goede 	{0, 0x0008, 0x011a},
4851f33de0fSHans de Goede 	{0, 0x0028, 0x011c},
4861f33de0fSHans de Goede 	{0, 0x0021, 0x012a},
4871f33de0fSHans de Goede 	{0, 0x0000, 0x0118},
4881f33de0fSHans de Goede 	{0, 0x0000, 0x0132},
4891f33de0fSHans de Goede 	{0, 0x0000, 0x0109},
4901f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
4911f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
4921f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
4931f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
4941f33de0fSHans de Goede 	{0, 0x0037, 0x0127},
4951f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
4961f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
4971f33de0fSHans de Goede 	{0, 0x0001, 0x0127},
4981f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
4991f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5001f33de0fSHans de Goede 	{0, 0x0031, 0x0127},
5011f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5021f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5031f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
5041f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
5051f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
5061f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5071f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5081f33de0fSHans de Goede 	{0, 0x0038, 0x0127},
5091f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5101f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5111f33de0fSHans de Goede 	{0, 0x0000, 0x0127},
5121f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5131f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5141f33de0fSHans de Goede 	{0, 0x0000, 0x0127},
5151f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5161f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5171f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
5181f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
5191f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
5201f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5211f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5221f33de0fSHans de Goede 	{0, 0x0037, 0x0127},
5231f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5241f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5251f33de0fSHans de Goede 	{0, 0x0001, 0x0127},
5261f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5271f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5281f33de0fSHans de Goede 	{0, 0x0040, 0x0127},
5291f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5301f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5311f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
5321f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
5331f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
5341f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5351f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5361f33de0fSHans de Goede 	{0, 0x0038, 0x0127},
5371f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5381f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5391f33de0fSHans de Goede 	{0, 0x0000, 0x0127},
5401f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5411f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5421f33de0fSHans de Goede 	{0, 0x0040, 0x0127},
5431f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5441f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5451f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
5461f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
5471f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
5481f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5491f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5501f33de0fSHans de Goede 	{0, 0x0037, 0x0127},
5511f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5521f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5531f33de0fSHans de Goede 	{0, 0x0000, 0x0127},
5541f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5551f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5561f33de0fSHans de Goede 	{0, 0x00dc, 0x0127},
5571f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5581f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5591f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
5601f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
5611f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
5621f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5631f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5641f33de0fSHans de Goede 	{0, 0x0038, 0x0127},
5651f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5661f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5671f33de0fSHans de Goede 	{0, 0x0000, 0x0127},
5681f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5691f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5701f33de0fSHans de Goede 	{0, 0x0000, 0x0127},
5711f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5721f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5731f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
5741f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
5751f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
5761f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5771f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5781f33de0fSHans de Goede 	{0, 0x0037, 0x0127},
5791f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5801f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5811f33de0fSHans de Goede 	{0, 0x0001, 0x0127},
5821f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5831f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5841f33de0fSHans de Goede 	{0, 0x0032, 0x0127},
5851f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5861f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5871f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
5881f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
5891f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
5901f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5911f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5921f33de0fSHans de Goede 	{0, 0x0038, 0x0127},
5931f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5941f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5951f33de0fSHans de Goede 	{0, 0x0001, 0x0127},
5961f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
5971f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
5981f33de0fSHans de Goede 	{0, 0x0020, 0x0127},
5991f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
6001f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
6011f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
6021f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
6031f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
6041f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
6051f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
6061f33de0fSHans de Goede 	{0, 0x0037, 0x0127},
6071f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
6081f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
6091f33de0fSHans de Goede 	{0, 0x0001, 0x0127},
6101f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
6111f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
6121f33de0fSHans de Goede 	{0, 0x0040, 0x0127},
6131f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
6141f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
6151f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
6161f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
6171f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
6181f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
6191f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
6201f33de0fSHans de Goede 	{0, 0x0038, 0x0127},
6211f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
6221f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
6231f33de0fSHans de Goede 	{0, 0x0000, 0x0127},
6241f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
6251f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
6261f33de0fSHans de Goede 	{0, 0x0040, 0x0127},
6271f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
6281f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
6291f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
6301f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
6311f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
6321f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
6331f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
6341f33de0fSHans de Goede 	{0, 0x0037, 0x0127},
6351f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
6361f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
6371f33de0fSHans de Goede 	{0, 0x0000, 0x0127},
6381f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
6391f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
6401f33de0fSHans de Goede 	{0, 0x0030, 0x0127},
6411f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
6421f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
6431f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
6441f33de0fSHans de Goede 	{0, 0xfff9, 0x0124},
6451f33de0fSHans de Goede 	{0, 0x0086, 0x0127},
6461f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
6471f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
6481f33de0fSHans de Goede 	{0, 0x0038, 0x0127},
6491f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
6501f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
6511f33de0fSHans de Goede 	{0, 0x0008, 0x0127},
6521f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
6531f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
6541f33de0fSHans de Goede 	{0, 0x0000, 0x0127},
6551f33de0fSHans de Goede 	{0, 0xfff8, 0x0124},
6561f33de0fSHans de Goede 	{0, 0xfffd, 0x0124},
6571f33de0fSHans de Goede 	{0, 0xfffa, 0x0124},
6581f33de0fSHans de Goede 	{0, 0x0003, 0x0111},
6591f33de0fSHans de Goede };
6601f33de0fSHans de Goede 
66159f90a01SHans de Goede /* TESTME the old ibmcam driver repeats certain commands to Model1 cameras, we
66259f90a01SHans de Goede    do the same for now (testing needed to see if this is really necessary) */
66359f90a01SHans de Goede static const int cit_model1_ntries = 5;
66459f90a01SHans de Goede static const int cit_model1_ntries2 = 2;
66559f90a01SHans de Goede 
6661f33de0fSHans de Goede static int cit_write_reg(struct gspca_dev *gspca_dev, u16 value, u16 index)
6671f33de0fSHans de Goede {
6681f33de0fSHans de Goede 	struct usb_device *udev = gspca_dev->dev;
6691f33de0fSHans de Goede 	int err;
6701f33de0fSHans de Goede 
6711f33de0fSHans de Goede 	err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00,
6721f33de0fSHans de Goede 			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT,
6731f33de0fSHans de Goede 			value, index, NULL, 0, 1000);
6741f33de0fSHans de Goede 	if (err < 0)
675133a9fe9SJoe Perches 		pr_err("Failed to write a register (index 0x%04X, value 0x%02X, error %d)\n",
676133a9fe9SJoe Perches 		       index, value, err);
6771f33de0fSHans de Goede 
6781f33de0fSHans de Goede 	return 0;
6791f33de0fSHans de Goede }
6801f33de0fSHans de Goede 
681e0657be5SHans de Goede static int cit_read_reg(struct gspca_dev *gspca_dev, u16 index, int verbose)
6821f33de0fSHans de Goede {
6831f33de0fSHans de Goede 	struct usb_device *udev = gspca_dev->dev;
6841f33de0fSHans de Goede 	__u8 *buf = gspca_dev->usb_buf;
6851f33de0fSHans de Goede 	int res;
6861f33de0fSHans de Goede 
6871f33de0fSHans de Goede 	res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x01,
6881f33de0fSHans de Goede 			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT,
6891f33de0fSHans de Goede 			0x00, index, buf, 8, 1000);
6901f33de0fSHans de Goede 	if (res < 0) {
691133a9fe9SJoe Perches 		pr_err("Failed to read a register (index 0x%04X, error %d)\n",
6921f33de0fSHans de Goede 		       index, res);
6931f33de0fSHans de Goede 		return res;
6941f33de0fSHans de Goede 	}
6951f33de0fSHans de Goede 
696e0657be5SHans de Goede 	if (verbose)
69737d5efb0SJoe Perches 		gspca_dbg(gspca_dev, D_PROBE, "Register %04x value: %02x\n",
69837d5efb0SJoe Perches 			  index, buf[0]);
6991f33de0fSHans de Goede 
7001f33de0fSHans de Goede 	return 0;
7011f33de0fSHans de Goede }
7021f33de0fSHans de Goede 
7031f33de0fSHans de Goede /*
70459f90a01SHans de Goede  * cit_send_FF_04_02()
70559f90a01SHans de Goede  *
70659f90a01SHans de Goede  * This procedure sends magic 3-command prefix to the camera.
70759f90a01SHans de Goede  * The purpose of this prefix is not known.
70859f90a01SHans de Goede  *
70959f90a01SHans de Goede  * History:
71059f90a01SHans de Goede  * 1/2/00   Created.
71159f90a01SHans de Goede  */
71259f90a01SHans de Goede static void cit_send_FF_04_02(struct gspca_dev *gspca_dev)
71359f90a01SHans de Goede {
71459f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x00FF, 0x0127);
71559f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0004, 0x0124);
71659f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0002, 0x0124);
71759f90a01SHans de Goede }
71859f90a01SHans de Goede 
71959f90a01SHans de Goede static void cit_send_00_04_06(struct gspca_dev *gspca_dev)
72059f90a01SHans de Goede {
72159f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0127);
72259f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0004, 0x0124);
72359f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0006, 0x0124);
72459f90a01SHans de Goede }
72559f90a01SHans de Goede 
72659f90a01SHans de Goede static void cit_send_x_00(struct gspca_dev *gspca_dev, unsigned short x)
72759f90a01SHans de Goede {
72859f90a01SHans de Goede 	cit_write_reg(gspca_dev, x,      0x0127);
72959f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0124);
73059f90a01SHans de Goede }
73159f90a01SHans de Goede 
73259f90a01SHans de Goede static void cit_send_x_00_05(struct gspca_dev *gspca_dev, unsigned short x)
73359f90a01SHans de Goede {
73459f90a01SHans de Goede 	cit_send_x_00(gspca_dev, x);
73559f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0005, 0x0124);
73659f90a01SHans de Goede }
73759f90a01SHans de Goede 
73859f90a01SHans de Goede static void cit_send_x_00_05_02(struct gspca_dev *gspca_dev, unsigned short x)
73959f90a01SHans de Goede {
74059f90a01SHans de Goede 	cit_write_reg(gspca_dev, x,      0x0127);
74159f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0124);
74259f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0005, 0x0124);
74359f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0002, 0x0124);
74459f90a01SHans de Goede }
74559f90a01SHans de Goede 
74659f90a01SHans de Goede static void cit_send_x_01_00_05(struct gspca_dev *gspca_dev, u16 x)
74759f90a01SHans de Goede {
74859f90a01SHans de Goede 	cit_write_reg(gspca_dev, x,      0x0127);
74959f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0001, 0x0124);
75059f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0124);
75159f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0005, 0x0124);
75259f90a01SHans de Goede }
75359f90a01SHans de Goede 
75459f90a01SHans de Goede static void cit_send_x_00_05_02_01(struct gspca_dev *gspca_dev, u16 x)
75559f90a01SHans de Goede {
75659f90a01SHans de Goede 	cit_write_reg(gspca_dev, x,      0x0127);
75759f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0124);
75859f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0005, 0x0124);
75959f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0002, 0x0124);
76059f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0001, 0x0124);
76159f90a01SHans de Goede }
76259f90a01SHans de Goede 
76359f90a01SHans de Goede static void cit_send_x_00_05_02_08_01(struct gspca_dev *gspca_dev, u16 x)
76459f90a01SHans de Goede {
76559f90a01SHans de Goede 	cit_write_reg(gspca_dev, x,      0x0127);
76659f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0124);
76759f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0005, 0x0124);
76859f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0002, 0x0124);
76959f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0008, 0x0124);
77059f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0001, 0x0124);
77159f90a01SHans de Goede }
77259f90a01SHans de Goede 
77359f90a01SHans de Goede static void cit_Packet_Format1(struct gspca_dev *gspca_dev, u16 fkey, u16 val)
77459f90a01SHans de Goede {
77559f90a01SHans de Goede 	cit_send_x_01_00_05(gspca_dev, 0x0088);
77659f90a01SHans de Goede 	cit_send_x_00_05(gspca_dev, fkey);
77759f90a01SHans de Goede 	cit_send_x_00_05_02_08_01(gspca_dev, val);
77859f90a01SHans de Goede 	cit_send_x_00_05(gspca_dev, 0x0088);
77959f90a01SHans de Goede 	cit_send_x_00_05_02_01(gspca_dev, fkey);
78059f90a01SHans de Goede 	cit_send_x_00_05(gspca_dev, 0x0089);
78159f90a01SHans de Goede 	cit_send_x_00(gspca_dev, fkey);
78259f90a01SHans de Goede 	cit_send_00_04_06(gspca_dev);
783e0657be5SHans de Goede 	cit_read_reg(gspca_dev, 0x0126, 0);
78459f90a01SHans de Goede 	cit_send_FF_04_02(gspca_dev);
78559f90a01SHans de Goede }
78659f90a01SHans de Goede 
78759f90a01SHans de Goede static void cit_PacketFormat2(struct gspca_dev *gspca_dev, u16 fkey, u16 val)
78859f90a01SHans de Goede {
78959f90a01SHans de Goede 	cit_send_x_01_00_05(gspca_dev, 0x0088);
79059f90a01SHans de Goede 	cit_send_x_00_05(gspca_dev, fkey);
79159f90a01SHans de Goede 	cit_send_x_00_05_02(gspca_dev, val);
79259f90a01SHans de Goede }
79359f90a01SHans de Goede 
79459f90a01SHans de Goede static void cit_model2_Packet2(struct gspca_dev *gspca_dev)
79559f90a01SHans de Goede {
79659f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x00ff, 0x012d);
79759f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0xfea3, 0x0124);
79859f90a01SHans de Goede }
79959f90a01SHans de Goede 
80059f90a01SHans de Goede static void cit_model2_Packet1(struct gspca_dev *gspca_dev, u16 v1, u16 v2)
80159f90a01SHans de Goede {
80259f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x00aa, 0x012d);
80359f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x00ff, 0x012e);
80459f90a01SHans de Goede 	cit_write_reg(gspca_dev, v1,     0x012f);
80559f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x00ff, 0x0130);
80659f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0xc719, 0x0124);
80759f90a01SHans de Goede 	cit_write_reg(gspca_dev, v2,     0x0127);
80859f90a01SHans de Goede 
80959f90a01SHans de Goede 	cit_model2_Packet2(gspca_dev);
81059f90a01SHans de Goede }
81159f90a01SHans de Goede 
81259f90a01SHans de Goede /*
81359f90a01SHans de Goede  * cit_model3_Packet1()
8141f33de0fSHans de Goede  *
8151f33de0fSHans de Goede  * 00_0078_012d
8161f33de0fSHans de Goede  * 00_0097_012f
8171f33de0fSHans de Goede  * 00_d141_0124
8181f33de0fSHans de Goede  * 00_0096_0127
8191f33de0fSHans de Goede  * 00_fea8_0124
8201f33de0fSHans de Goede */
8211f33de0fSHans de Goede static void cit_model3_Packet1(struct gspca_dev *gspca_dev, u16 v1, u16 v2)
8221f33de0fSHans de Goede {
8231f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0078, 0x012d);
8241f33de0fSHans de Goede 	cit_write_reg(gspca_dev, v1,     0x012f);
8251f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0xd141, 0x0124);
8261f33de0fSHans de Goede 	cit_write_reg(gspca_dev, v2,     0x0127);
8271f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0xfea8, 0x0124);
8281f33de0fSHans de Goede }
8291f33de0fSHans de Goede 
83059f90a01SHans de Goede static void cit_model4_Packet1(struct gspca_dev *gspca_dev, u16 v1, u16 v2)
83159f90a01SHans de Goede {
83259f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x00aa, 0x012d);
83359f90a01SHans de Goede 	cit_write_reg(gspca_dev, v1,     0x012f);
83459f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0xd141, 0x0124);
83559f90a01SHans de Goede 	cit_write_reg(gspca_dev, v2,     0x0127);
83659f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0xfea8, 0x0124);
83759f90a01SHans de Goede }
83859f90a01SHans de Goede 
83959f90a01SHans de Goede static void cit_model4_BrightnessPacket(struct gspca_dev *gspca_dev, u16 val)
84059f90a01SHans de Goede {
84159f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x00aa, 0x012d);
84259f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0026, 0x012f);
84359f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0xd141, 0x0124);
84459f90a01SHans de Goede 	cit_write_reg(gspca_dev, val,    0x0127);
84559f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x00aa, 0x0130);
84659f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x82a8, 0x0124);
84759f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0038, 0x012d);
84859f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0004, 0x012f);
84959f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0xd145, 0x0124);
85059f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0xfffa, 0x0124);
85159f90a01SHans de Goede }
85259f90a01SHans de Goede 
8531f33de0fSHans de Goede /* this function is called at probe time */
8541f33de0fSHans de Goede static int sd_config(struct gspca_dev *gspca_dev,
8551f33de0fSHans de Goede 		     const struct usb_device_id *id)
8561f33de0fSHans de Goede {
8571f33de0fSHans de Goede 	struct sd *sd = (struct sd *) gspca_dev;
8581f33de0fSHans de Goede 	struct cam *cam;
8591f33de0fSHans de Goede 
8601f33de0fSHans de Goede 	sd->model = id->driver_info;
8611f33de0fSHans de Goede 	if (sd->model == CIT_MODEL3 && ibm_netcam_pro)
8621f33de0fSHans de Goede 		sd->model = CIT_IBM_NETCAM_PRO;
8631f33de0fSHans de Goede 
8641f33de0fSHans de Goede 	cam = &gspca_dev->cam;
8651f33de0fSHans de Goede 	switch (sd->model) {
866659fefa0SHans de Goede 	case CIT_MODEL0:
867659fefa0SHans de Goede 		cam->cam_mode = model0_mode;
868659fefa0SHans de Goede 		cam->nmodes = ARRAY_SIZE(model0_mode);
869659fefa0SHans de Goede 		sd->sof_len = 4;
870659fefa0SHans de Goede 		break;
87159f90a01SHans de Goede 	case CIT_MODEL1:
87259f90a01SHans de Goede 		cam->cam_mode = cif_yuv_mode;
87359f90a01SHans de Goede 		cam->nmodes = ARRAY_SIZE(cif_yuv_mode);
874659fefa0SHans de Goede 		sd->sof_len = 4;
87559f90a01SHans de Goede 		break;
87659f90a01SHans de Goede 	case CIT_MODEL2:
87759f90a01SHans de Goede 		cam->cam_mode = model2_mode + 1; /* no 160x120 */
87859f90a01SHans de Goede 		cam->nmodes = 3;
87959f90a01SHans de Goede 		break;
8801f33de0fSHans de Goede 	case CIT_MODEL3:
8811f33de0fSHans de Goede 		cam->cam_mode = vga_yuv_mode;
8821f33de0fSHans de Goede 		cam->nmodes = ARRAY_SIZE(vga_yuv_mode);
88359f90a01SHans de Goede 		sd->stop_on_control_change = 1;
884659fefa0SHans de Goede 		sd->sof_len = 4;
88559f90a01SHans de Goede 		break;
88659f90a01SHans de Goede 	case CIT_MODEL4:
88759f90a01SHans de Goede 		cam->cam_mode = model2_mode;
88859f90a01SHans de Goede 		cam->nmodes = ARRAY_SIZE(model2_mode);
8891f33de0fSHans de Goede 		break;
8901f33de0fSHans de Goede 	case CIT_IBM_NETCAM_PRO:
8911f33de0fSHans de Goede 		cam->cam_mode = vga_yuv_mode;
8921f33de0fSHans de Goede 		cam->nmodes = 2; /* no 640 x 480 */
8931f33de0fSHans de Goede 		cam->input_flags = V4L2_IN_ST_VFLIP;
89459f90a01SHans de Goede 		sd->stop_on_control_change = 1;
895659fefa0SHans de Goede 		sd->sof_len = 4;
8961f33de0fSHans de Goede 		break;
8971f33de0fSHans de Goede 	}
8981f33de0fSHans de Goede 
899659fefa0SHans de Goede 	return 0;
900659fefa0SHans de Goede }
901659fefa0SHans de Goede 
902659fefa0SHans de Goede static int cit_init_model0(struct gspca_dev *gspca_dev)
903659fefa0SHans de Goede {
904659fefa0SHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0100); /* turn on led */
905659fefa0SHans de Goede 	cit_write_reg(gspca_dev, 0x0001, 0x0112); /* turn on autogain ? */
906659fefa0SHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0400);
907659fefa0SHans de Goede 	cit_write_reg(gspca_dev, 0x0001, 0x0400);
908659fefa0SHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0420);
909659fefa0SHans de Goede 	cit_write_reg(gspca_dev, 0x0001, 0x0420);
910659fefa0SHans de Goede 	cit_write_reg(gspca_dev, 0x000d, 0x0409);
911659fefa0SHans de Goede 	cit_write_reg(gspca_dev, 0x0002, 0x040a);
912659fefa0SHans de Goede 	cit_write_reg(gspca_dev, 0x0018, 0x0405);
913659fefa0SHans de Goede 	cit_write_reg(gspca_dev, 0x0008, 0x0435);
914659fefa0SHans de Goede 	cit_write_reg(gspca_dev, 0x0026, 0x040b);
915659fefa0SHans de Goede 	cit_write_reg(gspca_dev, 0x0007, 0x0437);
916659fefa0SHans de Goede 	cit_write_reg(gspca_dev, 0x0015, 0x042f);
917659fefa0SHans de Goede 	cit_write_reg(gspca_dev, 0x002b, 0x0439);
918659fefa0SHans de Goede 	cit_write_reg(gspca_dev, 0x0026, 0x043a);
919659fefa0SHans de Goede 	cit_write_reg(gspca_dev, 0x0008, 0x0438);
920659fefa0SHans de Goede 	cit_write_reg(gspca_dev, 0x001e, 0x042b);
921659fefa0SHans de Goede 	cit_write_reg(gspca_dev, 0x0041, 0x042c);
9221f33de0fSHans de Goede 
9231f33de0fSHans de Goede 	return 0;
9241f33de0fSHans de Goede }
9251f33de0fSHans de Goede 
9261f33de0fSHans de Goede static int cit_init_ibm_netcam_pro(struct gspca_dev *gspca_dev)
9271f33de0fSHans de Goede {
928e0657be5SHans de Goede 	cit_read_reg(gspca_dev, 0x128, 1);
9291f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0003, 0x0133);
9301f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0117);
9311f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0008, 0x0123);
9321f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0100);
933e0657be5SHans de Goede 	cit_read_reg(gspca_dev, 0x0116, 0);
9341f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0060, 0x0116);
9351f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0002, 0x0112);
9361f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0133);
9371f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0123);
9381f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0001, 0x0117);
9391f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0040, 0x0108);
9401f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0019, 0x012c);
9411f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0060, 0x0116);
9421f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0002, 0x0115);
9431f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x000b, 0x0115);
9441f33de0fSHans de Goede 
9451f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0078, 0x012d);
9461f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0001, 0x012f);
9471f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0xd141, 0x0124);
9481f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0079, 0x012d);
9491f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x00ff, 0x0130);
9501f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0xcd41, 0x0124);
9511f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0xfffa, 0x0124);
952e0657be5SHans de Goede 	cit_read_reg(gspca_dev, 0x0126, 1);
9531f33de0fSHans de Goede 
9541f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0000, 0x0000);
9551f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0000, 0x0001);
9561f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x000b, 0x0000);
9571f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x000c, 0x0008);
9581f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x000d, 0x003a);
9591f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x000e, 0x0060);
9601f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x000f, 0x0060);
9611f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0010, 0x0008);
9621f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0011, 0x0004);
9631f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0012, 0x0028);
9641f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0013, 0x0002);
9651f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0014, 0x0000);
9661f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0015, 0x00fb);
9671f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0016, 0x0002);
9681f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0017, 0x0037);
9691f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0018, 0x0036);
9701f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x001e, 0x0000);
9711f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x001f, 0x0008);
9721f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0020, 0x00c1);
9731f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0021, 0x0034);
9741f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0022, 0x0034);
9751f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0025, 0x0002);
9761f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0028, 0x0022);
9771f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0029, 0x000a);
9781f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x002b, 0x0000);
9791f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x002c, 0x0000);
9801f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x002d, 0x00ff);
9811f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x002e, 0x00ff);
9821f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x002f, 0x00ff);
9831f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0030, 0x00ff);
9841f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0031, 0x00ff);
9851f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0032, 0x0007);
9861f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0033, 0x0005);
9871f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0037, 0x0040);
9881f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0039, 0x0000);
9891f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x003a, 0x0000);
9901f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x003b, 0x0001);
9911f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x003c, 0x0000);
9921f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0040, 0x000c);
9931f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0041, 0x00fb);
9941f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0042, 0x0002);
9951f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0043, 0x0000);
9961f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0045, 0x0000);
9971f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0046, 0x0000);
9981f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0047, 0x0000);
9991f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0048, 0x0000);
10001f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0049, 0x0000);
10011f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x004a, 0x00ff);
10021f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x004b, 0x00ff);
10031f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x004c, 0x00ff);
10041f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x004f, 0x0000);
10051f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0050, 0x0000);
10061f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0051, 0x0002);
10071f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0055, 0x0000);
10081f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0056, 0x0000);
10091f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0057, 0x0000);
10101f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0058, 0x0002);
10111f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0059, 0x0000);
10121f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x005c, 0x0016);
10131f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x005d, 0x0022);
10141f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x005e, 0x003c);
10151f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x005f, 0x0050);
10161f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0060, 0x0044);
10171f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0061, 0x0005);
10181f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x006a, 0x007e);
10191f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x006f, 0x0000);
10201f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0072, 0x001b);
10211f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0073, 0x0005);
10221f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0074, 0x000a);
10231f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0075, 0x001b);
10241f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0076, 0x002a);
10251f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0077, 0x003c);
10261f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0078, 0x0050);
10271f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x007b, 0x0000);
10281f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x007c, 0x0011);
10291f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x007d, 0x0024);
10301f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x007e, 0x0043);
10311f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x007f, 0x005a);
10321f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0084, 0x0020);
10331f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0085, 0x0033);
10341f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0086, 0x000a);
10351f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0087, 0x0030);
10361f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0088, 0x0070);
10371f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x008b, 0x0008);
10381f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x008f, 0x0000);
10391f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0090, 0x0006);
10401f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0091, 0x0028);
10411f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0092, 0x005a);
10421f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0093, 0x0082);
10431f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0096, 0x0014);
10441f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0097, 0x0020);
10451f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0098, 0x0000);
10461f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00b0, 0x0046);
10471f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00b1, 0x0000);
10481f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00b2, 0x0000);
10491f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00b3, 0x0004);
10501f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00b4, 0x0007);
10511f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00b6, 0x0002);
10521f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00b7, 0x0004);
10531f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00bb, 0x0000);
10541f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00bc, 0x0001);
10551f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00bd, 0x0000);
10561f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00bf, 0x0000);
10571f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00c0, 0x00c8);
10581f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00c1, 0x0014);
10591f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00c2, 0x0001);
10601f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00c3, 0x0000);
10611f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00c4, 0x0004);
10621f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00cb, 0x00bf);
10631f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00cc, 0x00bf);
10641f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00cd, 0x00bf);
10651f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00ce, 0x0000);
10661f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00cf, 0x0020);
10671f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00d0, 0x0040);
10681f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00d1, 0x00bf);
10691f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00d1, 0x00bf);
10701f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00d2, 0x00bf);
10711f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00d3, 0x00bf);
10721f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00ea, 0x0008);
10731f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00eb, 0x0000);
10741f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00ec, 0x00e8);
10751f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00ed, 0x0001);
10761f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00ef, 0x0022);
10771f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00f0, 0x0000);
10781f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00f2, 0x0028);
10791f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00f4, 0x0002);
10801f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00f5, 0x0000);
10811f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00fa, 0x0000);
10821f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00fb, 0x0001);
10831f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00fc, 0x0000);
10841f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00fd, 0x0000);
10851f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00fe, 0x0000);
10861f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00ff, 0x0000);
10871f33de0fSHans de Goede 
10881f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00be, 0x0003);
10891f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00c8, 0x0000);
10901f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00c9, 0x0020);
10911f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00ca, 0x0040);
10921f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0053, 0x0001);
10931f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0082, 0x000e);
10941f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0083, 0x0020);
10951f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0034, 0x003c);
10961f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x006e, 0x0055);
10971f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0062, 0x0005);
10981f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0063, 0x0008);
10991f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0066, 0x000a);
11001f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0067, 0x0006);
11011f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x006b, 0x0010);
11021f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x005a, 0x0001);
11031f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x005b, 0x000a);
11041f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0023, 0x0006);
11051f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0026, 0x0004);
11061f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0036, 0x0069);
11071f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0038, 0x0064);
11081f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x003d, 0x0003);
11091f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x003e, 0x0001);
11101f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00b8, 0x0014);
11111f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00b9, 0x0014);
11121f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00e6, 0x0004);
11131f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00e8, 0x0001);
11141f33de0fSHans de Goede 
11151f33de0fSHans de Goede 	return 0;
11161f33de0fSHans de Goede }
11171f33de0fSHans de Goede 
11181f33de0fSHans de Goede /* this function is called at probe and resume time */
11191f33de0fSHans de Goede static int sd_init(struct gspca_dev *gspca_dev)
11201f33de0fSHans de Goede {
11211f33de0fSHans de Goede 	struct sd *sd = (struct sd *) gspca_dev;
11221f33de0fSHans de Goede 
11231f33de0fSHans de Goede 	switch (sd->model) {
1124659fefa0SHans de Goede 	case CIT_MODEL0:
1125659fefa0SHans de Goede 		cit_init_model0(gspca_dev);
1126659fefa0SHans de Goede 		sd_stop0(gspca_dev);
1127659fefa0SHans de Goede 		break;
112859f90a01SHans de Goede 	case CIT_MODEL1:
112959f90a01SHans de Goede 	case CIT_MODEL2:
11301f33de0fSHans de Goede 	case CIT_MODEL3:
113159f90a01SHans de Goede 	case CIT_MODEL4:
11321f33de0fSHans de Goede 		break; /* All is done in sd_start */
11331f33de0fSHans de Goede 	case CIT_IBM_NETCAM_PRO:
11341f33de0fSHans de Goede 		cit_init_ibm_netcam_pro(gspca_dev);
11351f33de0fSHans de Goede 		sd_stop0(gspca_dev);
11361f33de0fSHans de Goede 		break;
11371f33de0fSHans de Goede 	}
11381f33de0fSHans de Goede 	return 0;
11391f33de0fSHans de Goede }
11401f33de0fSHans de Goede 
1141d5d875cbSHans Verkuil static int cit_set_brightness(struct gspca_dev *gspca_dev, s32 val)
11421f33de0fSHans de Goede {
11431f33de0fSHans de Goede 	struct sd *sd = (struct sd *) gspca_dev;
114459f90a01SHans de Goede 	int i;
11451f33de0fSHans de Goede 
11461f33de0fSHans de Goede 	switch (sd->model) {
1147659fefa0SHans de Goede 	case CIT_MODEL0:
1148659fefa0SHans de Goede 	case CIT_IBM_NETCAM_PRO:
1149659fefa0SHans de Goede 		/* No (known) brightness control for these */
1150659fefa0SHans de Goede 		break;
115159f90a01SHans de Goede 	case CIT_MODEL1:
115259f90a01SHans de Goede 		/* Model 1: Brightness range 0 - 63 */
1153d5d875cbSHans Verkuil 		cit_Packet_Format1(gspca_dev, 0x0031, val);
1154d5d875cbSHans Verkuil 		cit_Packet_Format1(gspca_dev, 0x0032, val);
1155d5d875cbSHans Verkuil 		cit_Packet_Format1(gspca_dev, 0x0033, val);
115659f90a01SHans de Goede 		break;
115759f90a01SHans de Goede 	case CIT_MODEL2:
115859f90a01SHans de Goede 		/* Model 2: Brightness range 0x60 - 0xee */
115959f90a01SHans de Goede 		/* Scale 0 - 63 to 0x60 - 0xee */
1160d5d875cbSHans Verkuil 		i = 0x60 + val * 2254 / 1000;
116159f90a01SHans de Goede 		cit_model2_Packet1(gspca_dev, 0x001a, i);
116259f90a01SHans de Goede 		break;
11631f33de0fSHans de Goede 	case CIT_MODEL3:
11641f33de0fSHans de Goede 		/* Model 3: Brightness range 'i' in [0x0C..0x3F] */
1165d5d875cbSHans Verkuil 		i = val;
116659f90a01SHans de Goede 		if (i < 0x0c)
116759f90a01SHans de Goede 			i = 0x0c;
116859f90a01SHans de Goede 		cit_model3_Packet1(gspca_dev, 0x0036, i);
116959f90a01SHans de Goede 		break;
117059f90a01SHans de Goede 	case CIT_MODEL4:
117159f90a01SHans de Goede 		/* Model 4: Brightness range 'i' in [0x04..0xb4] */
117259f90a01SHans de Goede 		/* Scale 0 - 63 to 0x04 - 0xb4 */
1173d5d875cbSHans Verkuil 		i = 0x04 + val * 2794 / 1000;
117459f90a01SHans de Goede 		cit_model4_BrightnessPacket(gspca_dev, i);
11751f33de0fSHans de Goede 		break;
11761f33de0fSHans de Goede 	}
11771f33de0fSHans de Goede 
11781f33de0fSHans de Goede 	return 0;
11791f33de0fSHans de Goede }
11801f33de0fSHans de Goede 
1181d5d875cbSHans Verkuil static int cit_set_contrast(struct gspca_dev *gspca_dev, s32 val)
11821f33de0fSHans de Goede {
11831f33de0fSHans de Goede 	struct sd *sd = (struct sd *) gspca_dev;
11841f33de0fSHans de Goede 
11851f33de0fSHans de Goede 	switch (sd->model) {
1186659fefa0SHans de Goede 	case CIT_MODEL0: {
1187659fefa0SHans de Goede 		int i;
1188659fefa0SHans de Goede 		/* gain 0-15, 0-20 -> 0-15 */
1189d5d875cbSHans Verkuil 		i = val * 1000 / 1333;
1190659fefa0SHans de Goede 		cit_write_reg(gspca_dev, i, 0x0422);
1191659fefa0SHans de Goede 		/* gain 0-31, may not be lower then 0x0422, 0-20 -> 0-31 */
1192d5d875cbSHans Verkuil 		i = val * 2000 / 1333;
1193659fefa0SHans de Goede 		cit_write_reg(gspca_dev, i, 0x0423);
1194659fefa0SHans de Goede 		/* gain 0-127, may not be lower then 0x0423, 0-20 -> 0-63  */
1195d5d875cbSHans Verkuil 		i = val * 4000 / 1333;
1196659fefa0SHans de Goede 		cit_write_reg(gspca_dev, i, 0x0424);
1197659fefa0SHans de Goede 		/* gain 0-127, may not be lower then 0x0424, , 0-20 -> 0-127 */
1198d5d875cbSHans Verkuil 		i = val * 8000 / 1333;
1199659fefa0SHans de Goede 		cit_write_reg(gspca_dev, i, 0x0425);
1200659fefa0SHans de Goede 		break;
1201659fefa0SHans de Goede 	}
1202659fefa0SHans de Goede 	case CIT_MODEL2:
1203659fefa0SHans de Goede 	case CIT_MODEL4:
1204659fefa0SHans de Goede 		/* These models do not have this control. */
1205659fefa0SHans de Goede 		break;
120659f90a01SHans de Goede 	case CIT_MODEL1:
120759f90a01SHans de Goede 	{
120859f90a01SHans de Goede 		/* Scale 0 - 20 to 15 - 0 */
1209d5d875cbSHans Verkuil 		int i, new_contrast = (20 - val) * 1000 / 1333;
121059f90a01SHans de Goede 		for (i = 0; i < cit_model1_ntries; i++) {
121159f90a01SHans de Goede 			cit_Packet_Format1(gspca_dev, 0x0014, new_contrast);
121259f90a01SHans de Goede 			cit_send_FF_04_02(gspca_dev);
121359f90a01SHans de Goede 		}
121459f90a01SHans de Goede 		break;
121559f90a01SHans de Goede 	}
12161f33de0fSHans de Goede 	case CIT_MODEL3:
12171f33de0fSHans de Goede 	{	/* Preset hardware values */
12181f33de0fSHans de Goede 		static const struct {
12191f33de0fSHans de Goede 			unsigned short cv1;
12201f33de0fSHans de Goede 			unsigned short cv2;
12211f33de0fSHans de Goede 			unsigned short cv3;
12221f33de0fSHans de Goede 		} cv[7] = {
12231f33de0fSHans de Goede 			{ 0x05, 0x05, 0x0f },	/* Minimum */
12241f33de0fSHans de Goede 			{ 0x04, 0x04, 0x16 },
12251f33de0fSHans de Goede 			{ 0x02, 0x03, 0x16 },
12261f33de0fSHans de Goede 			{ 0x02, 0x08, 0x16 },
12271f33de0fSHans de Goede 			{ 0x01, 0x0c, 0x16 },
12281f33de0fSHans de Goede 			{ 0x01, 0x0e, 0x16 },
12291f33de0fSHans de Goede 			{ 0x01, 0x10, 0x16 }	/* Maximum */
12301f33de0fSHans de Goede 		};
1231d5d875cbSHans Verkuil 		int i = val / 3;
12321f33de0fSHans de Goede 		cit_model3_Packet1(gspca_dev, 0x0067, cv[i].cv1);
12331f33de0fSHans de Goede 		cit_model3_Packet1(gspca_dev, 0x005b, cv[i].cv2);
12341f33de0fSHans de Goede 		cit_model3_Packet1(gspca_dev, 0x005c, cv[i].cv3);
12351f33de0fSHans de Goede 		break;
12361f33de0fSHans de Goede 	}
12371f33de0fSHans de Goede 	case CIT_IBM_NETCAM_PRO:
1238d5d875cbSHans Verkuil 		cit_model3_Packet1(gspca_dev, 0x005b, val + 1);
12391f33de0fSHans de Goede 		break;
12401f33de0fSHans de Goede 	}
12411f33de0fSHans de Goede 	return 0;
12421f33de0fSHans de Goede }
12431f33de0fSHans de Goede 
1244d5d875cbSHans Verkuil static int cit_set_hue(struct gspca_dev *gspca_dev, s32 val)
12451f33de0fSHans de Goede {
12461f33de0fSHans de Goede 	struct sd *sd = (struct sd *) gspca_dev;
12471f33de0fSHans de Goede 
12481f33de0fSHans de Goede 	switch (sd->model) {
1249659fefa0SHans de Goede 	case CIT_MODEL0:
125059f90a01SHans de Goede 	case CIT_MODEL1:
1251659fefa0SHans de Goede 	case CIT_IBM_NETCAM_PRO:
1252659fefa0SHans de Goede 		/* No hue control for these models */
125359f90a01SHans de Goede 		break;
125459f90a01SHans de Goede 	case CIT_MODEL2:
1255d5d875cbSHans Verkuil 		cit_model2_Packet1(gspca_dev, 0x0024, val);
125659f90a01SHans de Goede 		/* cit_model2_Packet1(gspca_dev, 0x0020, sat); */
125759f90a01SHans de Goede 		break;
125859f90a01SHans de Goede 	case CIT_MODEL3: {
125959f90a01SHans de Goede 		/* Model 3: Brightness range 'i' in [0x05..0x37] */
126059f90a01SHans de Goede 		/* TESTME according to the ibmcam driver this does not work */
126159f90a01SHans de Goede 		if (0) {
126259f90a01SHans de Goede 			/* Scale 0 - 127 to 0x05 - 0x37 */
1263d5d875cbSHans Verkuil 			int i = 0x05 + val * 1000 / 2540;
126459f90a01SHans de Goede 			cit_model3_Packet1(gspca_dev, 0x007e, i);
126559f90a01SHans de Goede 		}
126659f90a01SHans de Goede 		break;
126759f90a01SHans de Goede 	}
126859f90a01SHans de Goede 	case CIT_MODEL4:
126959f90a01SHans de Goede 		/* HDG: taken from ibmcam, setting the color gains does not
127059f90a01SHans de Goede 		 * really belong here.
127159f90a01SHans de Goede 		 *
127259f90a01SHans de Goede 		 * I am not sure r/g/b_gain variables exactly control gain
127359f90a01SHans de Goede 		 * of those channels. Most likely they subtly change some
127459f90a01SHans de Goede 		 * very internal image processing settings in the camera.
127559f90a01SHans de Goede 		 * In any case, here is what they do, and feel free to tweak:
127659f90a01SHans de Goede 		 *
127759f90a01SHans de Goede 		 * r_gain: seriously affects red gain
127859f90a01SHans de Goede 		 * g_gain: seriously affects green gain
127959f90a01SHans de Goede 		 * b_gain: seriously affects blue gain
128059f90a01SHans de Goede 		 * hue: changes average color from violet (0) to red (0xFF)
128159f90a01SHans de Goede 		 */
128259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
128359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x001e, 0x012f);
128459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd141, 0x0124);
128559f90a01SHans de Goede 		cit_write_reg(gspca_dev,    160, 0x0127);  /* Green gain */
128659f90a01SHans de Goede 		cit_write_reg(gspca_dev,    160, 0x012e);  /* Red gain */
128759f90a01SHans de Goede 		cit_write_reg(gspca_dev,    160, 0x0130);  /* Blue gain */
128859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x8a28, 0x0124);
1289d5d875cbSHans Verkuil 		cit_write_reg(gspca_dev, val, 0x012d); /* Hue */
129059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xf545, 0x0124);
12911f33de0fSHans de Goede 		break;
12921f33de0fSHans de Goede 	}
12931f33de0fSHans de Goede 	return 0;
12941f33de0fSHans de Goede }
12951f33de0fSHans de Goede 
1296d5d875cbSHans Verkuil static int cit_set_sharpness(struct gspca_dev *gspca_dev, s32 val)
12971f33de0fSHans de Goede {
12981f33de0fSHans de Goede 	struct sd *sd = (struct sd *) gspca_dev;
12991f33de0fSHans de Goede 
13001f33de0fSHans de Goede 	switch (sd->model) {
1301659fefa0SHans de Goede 	case CIT_MODEL0:
1302659fefa0SHans de Goede 	case CIT_MODEL2:
1303659fefa0SHans de Goede 	case CIT_MODEL4:
1304659fefa0SHans de Goede 	case CIT_IBM_NETCAM_PRO:
1305659fefa0SHans de Goede 		/* These models do not have this control */
1306659fefa0SHans de Goede 		break;
130759f90a01SHans de Goede 	case CIT_MODEL1: {
130859f90a01SHans de Goede 		int i;
1309d4a06464SColin Ian King 		static const unsigned short sa[] = {
131059f90a01SHans de Goede 			0x11, 0x13, 0x16, 0x18, 0x1a, 0x8, 0x0a };
131159f90a01SHans de Goede 
131259f90a01SHans de Goede 		for (i = 0; i < cit_model1_ntries; i++)
1313d5d875cbSHans Verkuil 			cit_PacketFormat2(gspca_dev, 0x0013, sa[val]);
131459f90a01SHans de Goede 		break;
131559f90a01SHans de Goede 	}
13161f33de0fSHans de Goede 	case CIT_MODEL3:
13171f33de0fSHans de Goede 	{	/*
13181f33de0fSHans de Goede 		 * "Use a table of magic numbers.
13191f33de0fSHans de Goede 		 *  This setting doesn't really change much.
13201f33de0fSHans de Goede 		 *  But that's how Windows does it."
13211f33de0fSHans de Goede 		 */
13221f33de0fSHans de Goede 		static const struct {
13231f33de0fSHans de Goede 			unsigned short sv1;
13241f33de0fSHans de Goede 			unsigned short sv2;
13251f33de0fSHans de Goede 			unsigned short sv3;
13261f33de0fSHans de Goede 			unsigned short sv4;
13271f33de0fSHans de Goede 		} sv[7] = {
13281f33de0fSHans de Goede 			{ 0x00, 0x00, 0x05, 0x14 },	/* Smoothest */
13291f33de0fSHans de Goede 			{ 0x01, 0x04, 0x05, 0x14 },
13301f33de0fSHans de Goede 			{ 0x02, 0x04, 0x05, 0x14 },
13311f33de0fSHans de Goede 			{ 0x03, 0x04, 0x05, 0x14 },
13321f33de0fSHans de Goede 			{ 0x03, 0x05, 0x05, 0x14 },
13331f33de0fSHans de Goede 			{ 0x03, 0x06, 0x05, 0x14 },
13341f33de0fSHans de Goede 			{ 0x03, 0x07, 0x05, 0x14 }	/* Sharpest */
13351f33de0fSHans de Goede 		};
1336d5d875cbSHans Verkuil 		cit_model3_Packet1(gspca_dev, 0x0060, sv[val].sv1);
1337d5d875cbSHans Verkuil 		cit_model3_Packet1(gspca_dev, 0x0061, sv[val].sv2);
1338d5d875cbSHans Verkuil 		cit_model3_Packet1(gspca_dev, 0x0062, sv[val].sv3);
1339d5d875cbSHans Verkuil 		cit_model3_Packet1(gspca_dev, 0x0063, sv[val].sv4);
13401f33de0fSHans de Goede 		break;
13411f33de0fSHans de Goede 	}
13421f33de0fSHans de Goede 	}
13431f33de0fSHans de Goede 	return 0;
13441f33de0fSHans de Goede }
13451f33de0fSHans de Goede 
134659f90a01SHans de Goede /*
134759f90a01SHans de Goede  * cit_set_lighting()
134859f90a01SHans de Goede  *
134959f90a01SHans de Goede  * Camera model 1:
135059f90a01SHans de Goede  * We have 3 levels of lighting conditions: 0=Bright, 1=Medium, 2=Low.
135159f90a01SHans de Goede  *
135259f90a01SHans de Goede  * Camera model 2:
135359f90a01SHans de Goede  * We have 16 levels of lighting, 0 for bright light and up to 15 for
135459f90a01SHans de Goede  * low light. But values above 5 or so are useless because camera is
135559f90a01SHans de Goede  * not really capable to produce anything worth viewing at such light.
135659f90a01SHans de Goede  * This setting may be altered only in certain camera state.
135759f90a01SHans de Goede  *
135859f90a01SHans de Goede  * Low lighting forces slower FPS.
135959f90a01SHans de Goede  *
136059f90a01SHans de Goede  * History:
136159f90a01SHans de Goede  * 1/5/00   Created.
136259f90a01SHans de Goede  * 2/20/00  Added support for Model 2 cameras.
136359f90a01SHans de Goede  */
1364d5d875cbSHans Verkuil static void cit_set_lighting(struct gspca_dev *gspca_dev, s32 val)
136559f90a01SHans de Goede {
136659f90a01SHans de Goede 	struct sd *sd = (struct sd *) gspca_dev;
136759f90a01SHans de Goede 
136859f90a01SHans de Goede 	switch (sd->model) {
1369659fefa0SHans de Goede 	case CIT_MODEL0:
1370659fefa0SHans de Goede 	case CIT_MODEL2:
1371659fefa0SHans de Goede 	case CIT_MODEL3:
1372659fefa0SHans de Goede 	case CIT_MODEL4:
1373659fefa0SHans de Goede 	case CIT_IBM_NETCAM_PRO:
1374659fefa0SHans de Goede 		break;
137559f90a01SHans de Goede 	case CIT_MODEL1: {
137659f90a01SHans de Goede 		int i;
137759f90a01SHans de Goede 		for (i = 0; i < cit_model1_ntries; i++)
1378d5d875cbSHans Verkuil 			cit_Packet_Format1(gspca_dev, 0x0027, val);
137959f90a01SHans de Goede 		break;
138059f90a01SHans de Goede 	}
1381659fefa0SHans de Goede 	}
1382659fefa0SHans de Goede }
1383659fefa0SHans de Goede 
1384d5d875cbSHans Verkuil static void cit_set_hflip(struct gspca_dev *gspca_dev, s32 val)
1385659fefa0SHans de Goede {
1386659fefa0SHans de Goede 	struct sd *sd = (struct sd *) gspca_dev;
1387659fefa0SHans de Goede 
1388659fefa0SHans de Goede 	switch (sd->model) {
1389659fefa0SHans de Goede 	case CIT_MODEL0:
1390d5d875cbSHans Verkuil 		if (val)
1391659fefa0SHans de Goede 			cit_write_reg(gspca_dev, 0x0020, 0x0115);
1392659fefa0SHans de Goede 		else
1393659fefa0SHans de Goede 			cit_write_reg(gspca_dev, 0x0040, 0x0115);
1394659fefa0SHans de Goede 		break;
1395659fefa0SHans de Goede 	case CIT_MODEL1:
139659f90a01SHans de Goede 	case CIT_MODEL2:
139759f90a01SHans de Goede 	case CIT_MODEL3:
139859f90a01SHans de Goede 	case CIT_MODEL4:
139959f90a01SHans de Goede 	case CIT_IBM_NETCAM_PRO:
140059f90a01SHans de Goede 		break;
140159f90a01SHans de Goede 	}
140259f90a01SHans de Goede }
140359f90a01SHans de Goede 
14041f33de0fSHans de Goede static int cit_restart_stream(struct gspca_dev *gspca_dev)
14051f33de0fSHans de Goede {
14061f33de0fSHans de Goede 	struct sd *sd = (struct sd *) gspca_dev;
14071f33de0fSHans de Goede 
14081f33de0fSHans de Goede 	switch (sd->model) {
1409659fefa0SHans de Goede 	case CIT_MODEL0:
141059f90a01SHans de Goede 	case CIT_MODEL1:
14111f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0001, 0x0114);
1412*1771e9fbSGustavo A. R. Silva 		fallthrough;
141359f90a01SHans de Goede 	case CIT_MODEL2:
141459f90a01SHans de Goede 	case CIT_MODEL4:
14151f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x00c0, 0x010c); /* Go! */
14161f33de0fSHans de Goede 		usb_clear_halt(gspca_dev->dev, gspca_dev->urb[0]->pipe);
1417e0657be5SHans de Goede 		break;
1418e0657be5SHans de Goede 	case CIT_MODEL3:
1419e0657be5SHans de Goede 	case CIT_IBM_NETCAM_PRO:
1420e0657be5SHans de Goede 		cit_write_reg(gspca_dev, 0x0001, 0x0114);
1421e0657be5SHans de Goede 		cit_write_reg(gspca_dev, 0x00c0, 0x010c); /* Go! */
1422e0657be5SHans de Goede 		usb_clear_halt(gspca_dev->dev, gspca_dev->urb[0]->pipe);
1423e0657be5SHans de Goede 		/* Clear button events from while we were not streaming */
1424e0657be5SHans de Goede 		cit_write_reg(gspca_dev, 0x0001, 0x0113);
142559f90a01SHans de Goede 		break;
14261f33de0fSHans de Goede 	}
14271f33de0fSHans de Goede 
14281f33de0fSHans de Goede 	sd->sof_read = 0;
14291f33de0fSHans de Goede 
14301f33de0fSHans de Goede 	return 0;
14311f33de0fSHans de Goede }
14321f33de0fSHans de Goede 
1433659fefa0SHans de Goede static int cit_get_packet_size(struct gspca_dev *gspca_dev)
1434659fefa0SHans de Goede {
1435659fefa0SHans de Goede 	struct usb_host_interface *alt;
1436659fefa0SHans de Goede 	struct usb_interface *intf;
1437659fefa0SHans de Goede 
1438659fefa0SHans de Goede 	intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface);
1439659fefa0SHans de Goede 	alt = usb_altnum_to_altsetting(intf, gspca_dev->alt);
1440659fefa0SHans de Goede 	if (!alt) {
1441133a9fe9SJoe Perches 		pr_err("Couldn't get altsetting\n");
1442659fefa0SHans de Goede 		return -EIO;
1443659fefa0SHans de Goede 	}
1444659fefa0SHans de Goede 
1445a246b4d5SJohan Hovold 	if (alt->desc.bNumEndpoints < 1)
1446a246b4d5SJohan Hovold 		return -ENODEV;
1447a246b4d5SJohan Hovold 
1448659fefa0SHans de Goede 	return le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
1449659fefa0SHans de Goede }
1450659fefa0SHans de Goede 
145141f424baSHans de Goede /* Calculate the clockdiv giving us max fps given the available bandwidth */
145241f424baSHans de Goede static int cit_get_clock_div(struct gspca_dev *gspca_dev)
1453659fefa0SHans de Goede {
1454659fefa0SHans de Goede 	int clock_div = 7; /* 0=30 1=25 2=20 3=15 4=12 5=7.5 6=6 7=3fps ?? */
1455659fefa0SHans de Goede 	int fps[8] = { 30, 25, 20, 15, 12, 8, 6, 3 };
1456659fefa0SHans de Goede 	int packet_size;
1457659fefa0SHans de Goede 
1458659fefa0SHans de Goede 	packet_size = cit_get_packet_size(gspca_dev);
1459659fefa0SHans de Goede 	if (packet_size < 0)
1460659fefa0SHans de Goede 		return packet_size;
1461659fefa0SHans de Goede 
1462659fefa0SHans de Goede 	while (clock_div > 3 &&
1463659fefa0SHans de Goede 			1000 * packet_size >
14641966bc2aSOndrej Zary 			gspca_dev->pixfmt.width * gspca_dev->pixfmt.height *
1465659fefa0SHans de Goede 			fps[clock_div - 1] * 3 / 2)
1466659fefa0SHans de Goede 		clock_div--;
1467659fefa0SHans de Goede 
146837d5efb0SJoe Perches 	gspca_dbg(gspca_dev, D_PROBE,
146937d5efb0SJoe Perches 		  "PacketSize: %d, res: %dx%d -> using clockdiv: %d (%d fps)\n",
147037d5efb0SJoe Perches 		  packet_size,
147137d5efb0SJoe Perches 		  gspca_dev->pixfmt.width, gspca_dev->pixfmt.height,
14721966bc2aSOndrej Zary 		  clock_div, fps[clock_div]);
147341f424baSHans de Goede 
147441f424baSHans de Goede 	return clock_div;
147541f424baSHans de Goede }
147641f424baSHans de Goede 
147741f424baSHans de Goede static int cit_start_model0(struct gspca_dev *gspca_dev)
147841f424baSHans de Goede {
147941f424baSHans de Goede 	const unsigned short compression = 0; /* 0=none, 7=best frame rate */
148041f424baSHans de Goede 	int clock_div;
148141f424baSHans de Goede 
148241f424baSHans de Goede 	clock_div = cit_get_clock_div(gspca_dev);
148341f424baSHans de Goede 	if (clock_div < 0)
148441f424baSHans de Goede 		return clock_div;
148541f424baSHans de Goede 
1486659fefa0SHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0100); /* turn on led */
1487659fefa0SHans de Goede 	cit_write_reg(gspca_dev, 0x0003, 0x0438);
1488659fefa0SHans de Goede 	cit_write_reg(gspca_dev, 0x001e, 0x042b);
1489659fefa0SHans de Goede 	cit_write_reg(gspca_dev, 0x0041, 0x042c);
1490659fefa0SHans de Goede 	cit_write_reg(gspca_dev, 0x0008, 0x0436);
1491659fefa0SHans de Goede 	cit_write_reg(gspca_dev, 0x0024, 0x0403);
1492659fefa0SHans de Goede 	cit_write_reg(gspca_dev, 0x002c, 0x0404);
1493659fefa0SHans de Goede 	cit_write_reg(gspca_dev, 0x0002, 0x0426);
1494659fefa0SHans de Goede 	cit_write_reg(gspca_dev, 0x0014, 0x0427);
1495659fefa0SHans de Goede 
14961966bc2aSOndrej Zary 	switch (gspca_dev->pixfmt.width) {
1497659fefa0SHans de Goede 	case 160: /* 160x120 */
1498659fefa0SHans de Goede 		cit_write_reg(gspca_dev, 0x0004, 0x010b);
1499659fefa0SHans de Goede 		cit_write_reg(gspca_dev, 0x0001, 0x010a);
1500659fefa0SHans de Goede 		cit_write_reg(gspca_dev, 0x0010, 0x0102);
1501659fefa0SHans de Goede 		cit_write_reg(gspca_dev, 0x00a0, 0x0103);
1502659fefa0SHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0104);
1503659fefa0SHans de Goede 		cit_write_reg(gspca_dev, 0x0078, 0x0105);
1504659fefa0SHans de Goede 		break;
1505659fefa0SHans de Goede 
1506659fefa0SHans de Goede 	case 176: /* 176x144 */
1507659fefa0SHans de Goede 		cit_write_reg(gspca_dev, 0x0006, 0x010b);
1508659fefa0SHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x010a);
1509659fefa0SHans de Goede 		cit_write_reg(gspca_dev, 0x0005, 0x0102);
1510659fefa0SHans de Goede 		cit_write_reg(gspca_dev, 0x00b0, 0x0103);
1511659fefa0SHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0104);
1512659fefa0SHans de Goede 		cit_write_reg(gspca_dev, 0x0090, 0x0105);
1513659fefa0SHans de Goede 		break;
1514659fefa0SHans de Goede 
1515659fefa0SHans de Goede 	case 320: /* 320x240 */
1516659fefa0SHans de Goede 		cit_write_reg(gspca_dev, 0x0008, 0x010b);
1517659fefa0SHans de Goede 		cit_write_reg(gspca_dev, 0x0004, 0x010a);
1518659fefa0SHans de Goede 		cit_write_reg(gspca_dev, 0x0005, 0x0102);
1519659fefa0SHans de Goede 		cit_write_reg(gspca_dev, 0x00a0, 0x0103);
1520659fefa0SHans de Goede 		cit_write_reg(gspca_dev, 0x0010, 0x0104);
1521659fefa0SHans de Goede 		cit_write_reg(gspca_dev, 0x0078, 0x0105);
1522659fefa0SHans de Goede 		break;
1523659fefa0SHans de Goede 	}
1524659fefa0SHans de Goede 
1525659fefa0SHans de Goede 	cit_write_reg(gspca_dev, compression, 0x0109);
1526659fefa0SHans de Goede 	cit_write_reg(gspca_dev, clock_div, 0x0111);
1527659fefa0SHans de Goede 
1528659fefa0SHans de Goede 	return 0;
1529659fefa0SHans de Goede }
1530659fefa0SHans de Goede 
153159f90a01SHans de Goede static int cit_start_model1(struct gspca_dev *gspca_dev)
153259f90a01SHans de Goede {
153359f90a01SHans de Goede 	struct sd *sd = (struct sd *) gspca_dev;
153441f424baSHans de Goede 	int i, clock_div;
153555c1b7d3SHans de Goede 
153641f424baSHans de Goede 	clock_div = cit_get_clock_div(gspca_dev);
153741f424baSHans de Goede 	if (clock_div < 0)
153841f424baSHans de Goede 		return clock_div;
153959f90a01SHans de Goede 
1540e0657be5SHans de Goede 	cit_read_reg(gspca_dev, 0x0128, 1);
1541e0657be5SHans de Goede 	cit_read_reg(gspca_dev, 0x0100, 0);
154259f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x01, 0x0100);	/* LED On  */
1543e0657be5SHans de Goede 	cit_read_reg(gspca_dev, 0x0100, 0);
154459f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x81, 0x0100);	/* LED Off */
1545e0657be5SHans de Goede 	cit_read_reg(gspca_dev, 0x0100, 0);
154659f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x01, 0x0100);	/* LED On  */
154759f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x01, 0x0108);
154859f90a01SHans de Goede 
154959f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x03, 0x0112);
1550e0657be5SHans de Goede 	cit_read_reg(gspca_dev, 0x0115, 0);
155159f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x06, 0x0115);
1552e0657be5SHans de Goede 	cit_read_reg(gspca_dev, 0x0116, 0);
155359f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x44, 0x0116);
1554e0657be5SHans de Goede 	cit_read_reg(gspca_dev, 0x0116, 0);
155559f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x40, 0x0116);
1556e0657be5SHans de Goede 	cit_read_reg(gspca_dev, 0x0115, 0);
155759f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0e, 0x0115);
155859f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x19, 0x012c);
155959f90a01SHans de Goede 
156059f90a01SHans de Goede 	cit_Packet_Format1(gspca_dev, 0x00, 0x1e);
156159f90a01SHans de Goede 	cit_Packet_Format1(gspca_dev, 0x39, 0x0d);
156259f90a01SHans de Goede 	cit_Packet_Format1(gspca_dev, 0x39, 0x09);
156359f90a01SHans de Goede 	cit_Packet_Format1(gspca_dev, 0x3b, 0x00);
156459f90a01SHans de Goede 	cit_Packet_Format1(gspca_dev, 0x28, 0x22);
156559f90a01SHans de Goede 	cit_Packet_Format1(gspca_dev, 0x27, 0x00);
156659f90a01SHans de Goede 	cit_Packet_Format1(gspca_dev, 0x2b, 0x1f);
156759f90a01SHans de Goede 	cit_Packet_Format1(gspca_dev, 0x39, 0x08);
156859f90a01SHans de Goede 
156959f90a01SHans de Goede 	for (i = 0; i < cit_model1_ntries; i++)
157059f90a01SHans de Goede 		cit_Packet_Format1(gspca_dev, 0x2c, 0x00);
157159f90a01SHans de Goede 
157259f90a01SHans de Goede 	for (i = 0; i < cit_model1_ntries; i++)
157359f90a01SHans de Goede 		cit_Packet_Format1(gspca_dev, 0x30, 0x14);
157459f90a01SHans de Goede 
157559f90a01SHans de Goede 	cit_PacketFormat2(gspca_dev, 0x39, 0x02);
157659f90a01SHans de Goede 	cit_PacketFormat2(gspca_dev, 0x01, 0xe1);
157759f90a01SHans de Goede 	cit_PacketFormat2(gspca_dev, 0x02, 0xcd);
157859f90a01SHans de Goede 	cit_PacketFormat2(gspca_dev, 0x03, 0xcd);
157959f90a01SHans de Goede 	cit_PacketFormat2(gspca_dev, 0x04, 0xfa);
158059f90a01SHans de Goede 	cit_PacketFormat2(gspca_dev, 0x3f, 0xff);
158159f90a01SHans de Goede 	cit_PacketFormat2(gspca_dev, 0x39, 0x00);
158259f90a01SHans de Goede 
158359f90a01SHans de Goede 	cit_PacketFormat2(gspca_dev, 0x39, 0x02);
158459f90a01SHans de Goede 	cit_PacketFormat2(gspca_dev, 0x0a, 0x37);
158559f90a01SHans de Goede 	cit_PacketFormat2(gspca_dev, 0x0b, 0xb8);
158659f90a01SHans de Goede 	cit_PacketFormat2(gspca_dev, 0x0c, 0xf3);
158759f90a01SHans de Goede 	cit_PacketFormat2(gspca_dev, 0x0d, 0xe3);
158859f90a01SHans de Goede 	cit_PacketFormat2(gspca_dev, 0x0e, 0x0d);
158959f90a01SHans de Goede 	cit_PacketFormat2(gspca_dev, 0x0f, 0xf2);
159059f90a01SHans de Goede 	cit_PacketFormat2(gspca_dev, 0x10, 0xd5);
159159f90a01SHans de Goede 	cit_PacketFormat2(gspca_dev, 0x11, 0xba);
159259f90a01SHans de Goede 	cit_PacketFormat2(gspca_dev, 0x12, 0x53);
159359f90a01SHans de Goede 	cit_PacketFormat2(gspca_dev, 0x3f, 0xff);
159459f90a01SHans de Goede 	cit_PacketFormat2(gspca_dev, 0x39, 0x00);
159559f90a01SHans de Goede 
159659f90a01SHans de Goede 	cit_PacketFormat2(gspca_dev, 0x39, 0x02);
159759f90a01SHans de Goede 	cit_PacketFormat2(gspca_dev, 0x16, 0x00);
159859f90a01SHans de Goede 	cit_PacketFormat2(gspca_dev, 0x17, 0x28);
159959f90a01SHans de Goede 	cit_PacketFormat2(gspca_dev, 0x18, 0x7d);
160059f90a01SHans de Goede 	cit_PacketFormat2(gspca_dev, 0x19, 0xbe);
160159f90a01SHans de Goede 	cit_PacketFormat2(gspca_dev, 0x3f, 0xff);
160259f90a01SHans de Goede 	cit_PacketFormat2(gspca_dev, 0x39, 0x00);
160359f90a01SHans de Goede 
160459f90a01SHans de Goede 	for (i = 0; i < cit_model1_ntries; i++)
160559f90a01SHans de Goede 		cit_Packet_Format1(gspca_dev, 0x00, 0x18);
160659f90a01SHans de Goede 	for (i = 0; i < cit_model1_ntries; i++)
160759f90a01SHans de Goede 		cit_Packet_Format1(gspca_dev, 0x13, 0x18);
160859f90a01SHans de Goede 	for (i = 0; i < cit_model1_ntries; i++)
160959f90a01SHans de Goede 		cit_Packet_Format1(gspca_dev, 0x14, 0x06);
161059f90a01SHans de Goede 
161159f90a01SHans de Goede 	/* TESTME These are handled through controls
161259f90a01SHans de Goede 	   KEEP until someone can test leaving this out is ok */
161359f90a01SHans de Goede 	if (0) {
161459f90a01SHans de Goede 		/* This is default brightness */
161559f90a01SHans de Goede 		for (i = 0; i < cit_model1_ntries; i++)
161659f90a01SHans de Goede 			cit_Packet_Format1(gspca_dev, 0x31, 0x37);
161759f90a01SHans de Goede 		for (i = 0; i < cit_model1_ntries; i++)
161859f90a01SHans de Goede 			cit_Packet_Format1(gspca_dev, 0x32, 0x46);
161959f90a01SHans de Goede 		for (i = 0; i < cit_model1_ntries; i++)
162059f90a01SHans de Goede 			cit_Packet_Format1(gspca_dev, 0x33, 0x55);
162159f90a01SHans de Goede 	}
162259f90a01SHans de Goede 
162359f90a01SHans de Goede 	cit_Packet_Format1(gspca_dev, 0x2e, 0x04);
162459f90a01SHans de Goede 	for (i = 0; i < cit_model1_ntries; i++)
162559f90a01SHans de Goede 		cit_Packet_Format1(gspca_dev, 0x2d, 0x04);
162659f90a01SHans de Goede 	for (i = 0; i < cit_model1_ntries; i++)
162759f90a01SHans de Goede 		cit_Packet_Format1(gspca_dev, 0x29, 0x80);
162859f90a01SHans de Goede 	cit_Packet_Format1(gspca_dev, 0x2c, 0x01);
162959f90a01SHans de Goede 	cit_Packet_Format1(gspca_dev, 0x30, 0x17);
163059f90a01SHans de Goede 	cit_Packet_Format1(gspca_dev, 0x39, 0x08);
163159f90a01SHans de Goede 	for (i = 0; i < cit_model1_ntries; i++)
163259f90a01SHans de Goede 		cit_Packet_Format1(gspca_dev, 0x34, 0x00);
163359f90a01SHans de Goede 
163459f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x00, 0x0101);
163559f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x00, 0x010a);
163659f90a01SHans de Goede 
16371966bc2aSOndrej Zary 	switch (gspca_dev->pixfmt.width) {
163859f90a01SHans de Goede 	case 128: /* 128x96 */
163959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x80, 0x0103);
164059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x60, 0x0105);
164159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0c, 0x010b);
164259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x04, 0x011b);	/* Same everywhere */
164359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0b, 0x011d);
164459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00, 0x011e);	/* Same everywhere */
164559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00, 0x0129);
164659f90a01SHans de Goede 		break;
164759f90a01SHans de Goede 	case 176: /* 176x144 */
164859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xb0, 0x0103);
164959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x8f, 0x0105);
165059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x06, 0x010b);
165159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x04, 0x011b);	/* Same everywhere */
165259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0d, 0x011d);
165359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00, 0x011e);	/* Same everywhere */
165459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x03, 0x0129);
165559f90a01SHans de Goede 		break;
165659f90a01SHans de Goede 	case 352: /* 352x288 */
165759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xb0, 0x0103);
165859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x90, 0x0105);
165959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x02, 0x010b);
166059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x04, 0x011b);	/* Same everywhere */
166159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x05, 0x011d);
166259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00, 0x011e);	/* Same everywhere */
166359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00, 0x0129);
166459f90a01SHans de Goede 		break;
166559f90a01SHans de Goede 	}
166659f90a01SHans de Goede 
166759f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0xff, 0x012b);
166859f90a01SHans de Goede 
166959f90a01SHans de Goede 	/* TESTME These are handled through controls
167059f90a01SHans de Goede 	   KEEP until someone can test leaving this out is ok */
167159f90a01SHans de Goede 	if (0) {
167259f90a01SHans de Goede 		/* This is another brightness - don't know why */
167359f90a01SHans de Goede 		for (i = 0; i < cit_model1_ntries; i++)
167459f90a01SHans de Goede 			cit_Packet_Format1(gspca_dev, 0x31, 0xc3);
167559f90a01SHans de Goede 		for (i = 0; i < cit_model1_ntries; i++)
167659f90a01SHans de Goede 			cit_Packet_Format1(gspca_dev, 0x32, 0xd2);
167759f90a01SHans de Goede 		for (i = 0; i < cit_model1_ntries; i++)
167859f90a01SHans de Goede 			cit_Packet_Format1(gspca_dev, 0x33, 0xe1);
167959f90a01SHans de Goede 
168059f90a01SHans de Goede 		/* Default contrast */
168159f90a01SHans de Goede 		for (i = 0; i < cit_model1_ntries; i++)
168259f90a01SHans de Goede 			cit_Packet_Format1(gspca_dev, 0x14, 0x0a);
168359f90a01SHans de Goede 
168459f90a01SHans de Goede 		/* Default sharpness */
168559f90a01SHans de Goede 		for (i = 0; i < cit_model1_ntries2; i++)
168659f90a01SHans de Goede 			cit_PacketFormat2(gspca_dev, 0x13, 0x1a);
168759f90a01SHans de Goede 
168859f90a01SHans de Goede 		/* Default lighting conditions */
1689d5d875cbSHans Verkuil 		cit_Packet_Format1(gspca_dev, 0x0027,
1690d5d875cbSHans Verkuil 				   v4l2_ctrl_g_ctrl(sd->lighting));
169159f90a01SHans de Goede 	}
169259f90a01SHans de Goede 
169359f90a01SHans de Goede 	/* Assorted init */
16941966bc2aSOndrej Zary 	switch (gspca_dev->pixfmt.width) {
169559f90a01SHans de Goede 	case 128: /* 128x96 */
169659f90a01SHans de Goede 		cit_Packet_Format1(gspca_dev, 0x2b, 0x1e);
169759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xc9, 0x0119);	/* Same everywhere */
169859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x80, 0x0109);	/* Same everywhere */
169959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x36, 0x0102);
170059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x1a, 0x0104);
170159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x04, 0x011a);	/* Same everywhere */
170259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x2b, 0x011c);
170359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x23, 0x012a);	/* Same everywhere */
170459f90a01SHans de Goede 		break;
170559f90a01SHans de Goede 	case 176: /* 176x144 */
170659f90a01SHans de Goede 		cit_Packet_Format1(gspca_dev, 0x2b, 0x1e);
170759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xc9, 0x0119);	/* Same everywhere */
170859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x80, 0x0109);	/* Same everywhere */
170959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x04, 0x0102);
171059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x02, 0x0104);
171159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x04, 0x011a);	/* Same everywhere */
171259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x2b, 0x011c);
171359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x23, 0x012a);	/* Same everywhere */
171459f90a01SHans de Goede 		break;
171559f90a01SHans de Goede 	case 352: /* 352x288 */
171659f90a01SHans de Goede 		cit_Packet_Format1(gspca_dev, 0x2b, 0x1f);
171759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xc9, 0x0119);	/* Same everywhere */
171859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x80, 0x0109);	/* Same everywhere */
171959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x08, 0x0102);
172059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x01, 0x0104);
172159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x04, 0x011a);	/* Same everywhere */
172259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x2f, 0x011c);
172359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x23, 0x012a);	/* Same everywhere */
172459f90a01SHans de Goede 		break;
172559f90a01SHans de Goede 	}
172659f90a01SHans de Goede 
172759f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x01, 0x0100);	/* LED On  */
172859f90a01SHans de Goede 	cit_write_reg(gspca_dev, clock_div, 0x0111);
172959f90a01SHans de Goede 
173059f90a01SHans de Goede 	return 0;
173159f90a01SHans de Goede }
173259f90a01SHans de Goede 
173359f90a01SHans de Goede static int cit_start_model2(struct gspca_dev *gspca_dev)
173459f90a01SHans de Goede {
173559f90a01SHans de Goede 	struct sd *sd = (struct sd *) gspca_dev;
173659f90a01SHans de Goede 	int clock_div = 0;
173759f90a01SHans de Goede 
173859f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0100);	/* LED on */
1739e0657be5SHans de Goede 	cit_read_reg(gspca_dev, 0x0116, 0);
174059f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0060, 0x0116);
174159f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0002, 0x0112);
174259f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x00bc, 0x012c);
174359f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0008, 0x012b);
174459f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0108);
174559f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0001, 0x0133);
174659f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0001, 0x0102);
17471966bc2aSOndrej Zary 	switch (gspca_dev->pixfmt.width) {
174859f90a01SHans de Goede 	case 176: /* 176x144 */
174959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x002c, 0x0103);	/* All except 320x240 */
175059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0104);	/* Same */
175159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0024, 0x0105);	/* 176x144, 352x288 */
175259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00b9, 0x010a);	/* Unique to this mode */
175359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0038, 0x0119);	/* Unique to this mode */
175459f90a01SHans de Goede 		/* TESTME HDG: this does not seem right
175559f90a01SHans de Goede 		   (it is 2 for all other resolutions) */
175659f90a01SHans de Goede 		sd->sof_len = 10;
175759f90a01SHans de Goede 		break;
175859f90a01SHans de Goede 	case 320: /* 320x240 */
175959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0028, 0x0103);	/* Unique to this mode */
176059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0104);	/* Same */
176159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x001e, 0x0105);	/* 320x240, 352x240 */
176259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0039, 0x010a);	/* All except 176x144 */
176359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0070, 0x0119);	/* All except 176x144 */
176459f90a01SHans de Goede 		sd->sof_len = 2;
176559f90a01SHans de Goede 		break;
1766cd65d24eSMauro Carvalho Chehab #if 0
1767cd65d24eSMauro Carvalho Chehab 	case VIDEOSIZE_352x240:
176859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x002c, 0x0103);	/* All except 320x240 */
176959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0104);	/* Same */
177059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x001e, 0x0105);	/* 320x240, 352x240 */
177159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0039, 0x010a);	/* All except 176x144 */
177259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0070, 0x0119);	/* All except 176x144 */
177359f90a01SHans de Goede 		sd->sof_len = 2;
177459f90a01SHans de Goede 		break;
1775cd65d24eSMauro Carvalho Chehab #endif
177659f90a01SHans de Goede 	case 352: /* 352x288 */
177759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x002c, 0x0103);	/* All except 320x240 */
177859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0104);	/* Same */
177959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0024, 0x0105);	/* 176x144, 352x288 */
178059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0039, 0x010a);	/* All except 176x144 */
178159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0070, 0x0119);	/* All except 176x144 */
178259f90a01SHans de Goede 		sd->sof_len = 2;
178359f90a01SHans de Goede 		break;
178459f90a01SHans de Goede 	}
178559f90a01SHans de Goede 
178659f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0100);	/* LED on */
178759f90a01SHans de Goede 
17881966bc2aSOndrej Zary 	switch (gspca_dev->pixfmt.width) {
178959f90a01SHans de Goede 	case 176: /* 176x144 */
179059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0050, 0x0111);
179159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00d0, 0x0111);
179259f90a01SHans de Goede 		break;
179359f90a01SHans de Goede 	case 320: /* 320x240 */
179459f90a01SHans de Goede 	case 352: /* 352x288 */
179559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0040, 0x0111);
179659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00c0, 0x0111);
179759f90a01SHans de Goede 		break;
179859f90a01SHans de Goede 	}
179959f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x009b, 0x010f);
180059f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x00bb, 0x010f);
180159f90a01SHans de Goede 
180259f90a01SHans de Goede 	/*
180359f90a01SHans de Goede 	 * Hardware settings, may affect CMOS sensor; not user controls!
180459f90a01SHans de Goede 	 * -------------------------------------------------------------
180559f90a01SHans de Goede 	 * 0x0004: no effect
180659f90a01SHans de Goede 	 * 0x0006: hardware effect
180759f90a01SHans de Goede 	 * 0x0008: no effect
180859f90a01SHans de Goede 	 * 0x000a: stops video stream, probably important h/w setting
180959f90a01SHans de Goede 	 * 0x000c: changes color in hardware manner (not user setting)
181059f90a01SHans de Goede 	 * 0x0012: changes number of colors (does not affect speed)
181159f90a01SHans de Goede 	 * 0x002a: no effect
181259f90a01SHans de Goede 	 * 0x002c: hardware setting (related to scan lines)
181359f90a01SHans de Goede 	 * 0x002e: stops video stream, probably important h/w setting
181459f90a01SHans de Goede 	 */
181559f90a01SHans de Goede 	cit_model2_Packet1(gspca_dev, 0x000a, 0x005c);
181659f90a01SHans de Goede 	cit_model2_Packet1(gspca_dev, 0x0004, 0x0000);
181759f90a01SHans de Goede 	cit_model2_Packet1(gspca_dev, 0x0006, 0x00fb);
181859f90a01SHans de Goede 	cit_model2_Packet1(gspca_dev, 0x0008, 0x0000);
181959f90a01SHans de Goede 	cit_model2_Packet1(gspca_dev, 0x000c, 0x0009);
182059f90a01SHans de Goede 	cit_model2_Packet1(gspca_dev, 0x0012, 0x000a);
182159f90a01SHans de Goede 	cit_model2_Packet1(gspca_dev, 0x002a, 0x0000);
182259f90a01SHans de Goede 	cit_model2_Packet1(gspca_dev, 0x002c, 0x0000);
182359f90a01SHans de Goede 	cit_model2_Packet1(gspca_dev, 0x002e, 0x0008);
182459f90a01SHans de Goede 
182559f90a01SHans de Goede 	/*
182659f90a01SHans de Goede 	 * Function 0x0030 pops up all over the place. Apparently
182759f90a01SHans de Goede 	 * it is a hardware control register, with every bit assigned to
182859f90a01SHans de Goede 	 * do something.
182959f90a01SHans de Goede 	 */
183059f90a01SHans de Goede 	cit_model2_Packet1(gspca_dev, 0x0030, 0x0000);
183159f90a01SHans de Goede 
183259f90a01SHans de Goede 	/*
183359f90a01SHans de Goede 	 * Magic control of CMOS sensor. Only lower values like
183459f90a01SHans de Goede 	 * 0-3 work, and picture shifts left or right. Don't change.
183559f90a01SHans de Goede 	 */
18361966bc2aSOndrej Zary 	switch (gspca_dev->pixfmt.width) {
183759f90a01SHans de Goede 	case 176: /* 176x144 */
183859f90a01SHans de Goede 		cit_model2_Packet1(gspca_dev, 0x0014, 0x0002);
183959f90a01SHans de Goede 		cit_model2_Packet1(gspca_dev, 0x0016, 0x0002); /* Horizontal shift */
184059f90a01SHans de Goede 		cit_model2_Packet1(gspca_dev, 0x0018, 0x004a); /* Another hardware setting */
184159f90a01SHans de Goede 		clock_div = 6;
184259f90a01SHans de Goede 		break;
184359f90a01SHans de Goede 	case 320: /* 320x240 */
184459f90a01SHans de Goede 		cit_model2_Packet1(gspca_dev, 0x0014, 0x0009);
184559f90a01SHans de Goede 		cit_model2_Packet1(gspca_dev, 0x0016, 0x0005); /* Horizontal shift */
184659f90a01SHans de Goede 		cit_model2_Packet1(gspca_dev, 0x0018, 0x0044); /* Another hardware setting */
184759f90a01SHans de Goede 		clock_div = 8;
184859f90a01SHans de Goede 		break;
1849cd65d24eSMauro Carvalho Chehab #if 0
1850cd65d24eSMauro Carvalho Chehab 	case VIDEOSIZE_352x240:
185159f90a01SHans de Goede 		/* This mode doesn't work as Windows programs it; changed to work */
185259f90a01SHans de Goede 		cit_model2_Packet1(gspca_dev, 0x0014, 0x0009); /* Windows sets this to 8 */
185359f90a01SHans de Goede 		cit_model2_Packet1(gspca_dev, 0x0016, 0x0003); /* Horizontal shift */
185459f90a01SHans de Goede 		cit_model2_Packet1(gspca_dev, 0x0018, 0x0044); /* Windows sets this to 0x0045 */
185559f90a01SHans de Goede 		clock_div = 10;
185659f90a01SHans de Goede 		break;
1857cd65d24eSMauro Carvalho Chehab #endif
185859f90a01SHans de Goede 	case 352: /* 352x288 */
185959f90a01SHans de Goede 		cit_model2_Packet1(gspca_dev, 0x0014, 0x0003);
186059f90a01SHans de Goede 		cit_model2_Packet1(gspca_dev, 0x0016, 0x0002); /* Horizontal shift */
186159f90a01SHans de Goede 		cit_model2_Packet1(gspca_dev, 0x0018, 0x004a); /* Another hardware setting */
186259f90a01SHans de Goede 		clock_div = 16;
186359f90a01SHans de Goede 		break;
186459f90a01SHans de Goede 	}
186559f90a01SHans de Goede 
186659f90a01SHans de Goede 	/* TESTME These are handled through controls
186759f90a01SHans de Goede 	   KEEP until someone can test leaving this out is ok */
186859f90a01SHans de Goede 	if (0)
186959f90a01SHans de Goede 		cit_model2_Packet1(gspca_dev, 0x001a, 0x005a);
187059f90a01SHans de Goede 
187159f90a01SHans de Goede 	/*
187259f90a01SHans de Goede 	 * We have our own frame rate setting varying from 0 (slowest) to 6
187359f90a01SHans de Goede 	 * (fastest). The camera model 2 allows frame rate in range [0..0x1F]
187459f90a01SHans de Goede 	 # where 0 is also the slowest setting. However for all practical
187559f90a01SHans de Goede 	 # reasons high settings make no sense because USB is not fast enough
187659f90a01SHans de Goede 	 # to support high FPS. Be aware that the picture datastream will be
187759f90a01SHans de Goede 	 # severely disrupted if you ask for frame rate faster than allowed
187859f90a01SHans de Goede 	 # for the video size - see below:
187959f90a01SHans de Goede 	 *
188059f90a01SHans de Goede 	 * Allowable ranges (obtained experimentally on OHCI, K6-3, 450 MHz):
188159f90a01SHans de Goede 	 * -----------------------------------------------------------------
188259f90a01SHans de Goede 	 * 176x144: [6..31]
188359f90a01SHans de Goede 	 * 320x240: [8..31]
188459f90a01SHans de Goede 	 * 352x240: [10..31]
188559f90a01SHans de Goede 	 * 352x288: [16..31] I have to raise lower threshold for stability...
188659f90a01SHans de Goede 	 *
188759f90a01SHans de Goede 	 * As usual, slower FPS provides better sensitivity.
188859f90a01SHans de Goede 	 */
188959f90a01SHans de Goede 	cit_model2_Packet1(gspca_dev, 0x001c, clock_div);
189059f90a01SHans de Goede 
189159f90a01SHans de Goede 	/*
189259f90a01SHans de Goede 	 * This setting does not visibly affect pictures; left it here
189359f90a01SHans de Goede 	 * because it was present in Windows USB data stream. This function
189459f90a01SHans de Goede 	 * does not allow arbitrary values and apparently is a bit mask, to
189559f90a01SHans de Goede 	 * be activated only at appropriate time. Don't change it randomly!
189659f90a01SHans de Goede 	 */
18971966bc2aSOndrej Zary 	switch (gspca_dev->pixfmt.width) {
189859f90a01SHans de Goede 	case 176: /* 176x144 */
189959f90a01SHans de Goede 		cit_model2_Packet1(gspca_dev, 0x0026, 0x00c2);
190059f90a01SHans de Goede 		break;
190159f90a01SHans de Goede 	case 320: /* 320x240 */
190259f90a01SHans de Goede 		cit_model2_Packet1(gspca_dev, 0x0026, 0x0044);
190359f90a01SHans de Goede 		break;
1904cd65d24eSMauro Carvalho Chehab #if 0
1905cd65d24eSMauro Carvalho Chehab 	case VIDEOSIZE_352x240:
190659f90a01SHans de Goede 		cit_model2_Packet1(gspca_dev, 0x0026, 0x0046);
190759f90a01SHans de Goede 		break;
1908cd65d24eSMauro Carvalho Chehab #endif
190959f90a01SHans de Goede 	case 352: /* 352x288 */
191059f90a01SHans de Goede 		cit_model2_Packet1(gspca_dev, 0x0026, 0x0048);
191159f90a01SHans de Goede 		break;
191259f90a01SHans de Goede 	}
191359f90a01SHans de Goede 
1914d5d875cbSHans Verkuil 	cit_model2_Packet1(gspca_dev, 0x0028, v4l2_ctrl_g_ctrl(sd->lighting));
1915872099e8SHans de Goede 	/* model2 cannot change the backlight compensation while streaming */
1916872099e8SHans de Goede 	v4l2_ctrl_grab(sd->lighting, true);
1917872099e8SHans de Goede 
191859f90a01SHans de Goede 	/* color balance rg2 */
191959f90a01SHans de Goede 	cit_model2_Packet1(gspca_dev, 0x001e, 0x002f);
192059f90a01SHans de Goede 	/* saturation */
192159f90a01SHans de Goede 	cit_model2_Packet1(gspca_dev, 0x0020, 0x0034);
192259f90a01SHans de Goede 	/* color balance yb */
192359f90a01SHans de Goede 	cit_model2_Packet1(gspca_dev, 0x0022, 0x00a0);
192459f90a01SHans de Goede 
192559f90a01SHans de Goede 	/* Hardware control command */
192659f90a01SHans de Goede 	cit_model2_Packet1(gspca_dev, 0x0030, 0x0004);
192759f90a01SHans de Goede 
192859f90a01SHans de Goede 	return 0;
192959f90a01SHans de Goede }
193059f90a01SHans de Goede 
19311f33de0fSHans de Goede static int cit_start_model3(struct gspca_dev *gspca_dev)
19321f33de0fSHans de Goede {
19331f33de0fSHans de Goede 	const unsigned short compression = 0; /* 0=none, 7=best frame rate */
19341f33de0fSHans de Goede 	int i, clock_div = 0;
19351f33de0fSHans de Goede 
19361f33de0fSHans de Goede 	/* HDG not in ibmcam driver, added to see if it helps with
19371f33de0fSHans de Goede 	   auto-detecting between model3 and ibm netcamera pro */
1938e0657be5SHans de Goede 	cit_read_reg(gspca_dev, 0x128, 1);
19391f33de0fSHans de Goede 
19401f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0100);
1941e0657be5SHans de Goede 	cit_read_reg(gspca_dev, 0x0116, 0);
19421f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0060, 0x0116);
19431f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0002, 0x0112);
19441f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0123);
19451f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0001, 0x0117);
19461f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0040, 0x0108);
19471f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0019, 0x012c);
19481f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0060, 0x0116);
19491f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0002, 0x0115);
19501f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0003, 0x0115);
1951e0657be5SHans de Goede 	cit_read_reg(gspca_dev, 0x0115, 0);
19521f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x000b, 0x0115);
19531f33de0fSHans de Goede 
195459f90a01SHans de Goede 	/* TESTME HDG not in ibmcam driver, added to see if it helps with
19551f33de0fSHans de Goede 	   auto-detecting between model3 and ibm netcamera pro */
19561f33de0fSHans de Goede 	if (0) {
19571f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0078, 0x012d);
19581f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0001, 0x012f);
19591f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0xd141, 0x0124);
19601f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0079, 0x012d);
19611f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x00ff, 0x0130);
19621f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0xcd41, 0x0124);
19631f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0xfffa, 0x0124);
1964e0657be5SHans de Goede 		cit_read_reg(gspca_dev, 0x0126, 1);
19651f33de0fSHans de Goede 	}
19661f33de0fSHans de Goede 
19671f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x000a, 0x0040);
19681f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x000b, 0x00f6);
19691f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x000c, 0x0002);
19701f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x000d, 0x0020);
19711f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x000e, 0x0033);
19721f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x000f, 0x0007);
19731f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0010, 0x0000);
19741f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0011, 0x0070);
19751f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0012, 0x0030);
19761f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0013, 0x0000);
19771f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0014, 0x0001);
19781f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0015, 0x0001);
19791f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0016, 0x0001);
19801f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0017, 0x0001);
19811f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0018, 0x0000);
19821f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x001e, 0x00c3);
19831f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0020, 0x0000);
19841f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0028, 0x0010);
19851f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0029, 0x0054);
19861f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x002a, 0x0013);
19871f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x002b, 0x0007);
19881f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x002d, 0x0028);
19891f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x002e, 0x0000);
19901f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0031, 0x0000);
19911f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0032, 0x0000);
19921f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0033, 0x0000);
19931f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0034, 0x0000);
19941f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0035, 0x0038);
19951f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x003a, 0x0001);
19961f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x003c, 0x001e);
19971f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x003f, 0x000a);
19981f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0041, 0x0000);
19991f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0046, 0x003f);
20001f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0047, 0x0000);
20011f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0050, 0x0005);
20021f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0052, 0x001a);
20031f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0053, 0x0003);
20041f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x005a, 0x006b);
20051f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x005d, 0x001e);
20061f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x005e, 0x0030);
20071f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x005f, 0x0041);
20081f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0064, 0x0008);
20091f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0065, 0x0015);
20101f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0068, 0x000f);
20111f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0079, 0x0000);
20121f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x007a, 0x0000);
20131f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x007c, 0x003f);
20141f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0082, 0x000f);
20151f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0085, 0x0000);
20161f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0099, 0x0000);
20171f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x009b, 0x0023);
20181f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x009c, 0x0022);
20191f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x009d, 0x0096);
20201f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x009e, 0x0096);
20211f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x009f, 0x000a);
20221f33de0fSHans de Goede 
20231966bc2aSOndrej Zary 	switch (gspca_dev->pixfmt.width) {
20241f33de0fSHans de Goede 	case 160:
20251f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0101); /* Same on 160x120, 320x240 */
20261f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x00a0, 0x0103); /* Same on 160x120, 320x240 */
20271f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0078, 0x0105); /* Same on 160x120, 320x240 */
20281f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x010a); /* Same */
20291f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0024, 0x010b); /* Differs everywhere */
20301f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x00a9, 0x0119);
20311f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0016, 0x011b);
20321f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0002, 0x011d); /* Same on 160x120, 320x240 */
20331f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0003, 0x011e); /* Same on 160x120, 640x480 */
20341f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0129); /* Same */
20351f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x00fc, 0x012b); /* Same */
20361f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0018, 0x0102);
20371f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0004, 0x0104);
20381f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0004, 0x011a);
20391f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0028, 0x011c);
20401f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0022, 0x012a); /* Same */
20411f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0118);
20421f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0132);
20431f33de0fSHans de Goede 		cit_model3_Packet1(gspca_dev, 0x0021, 0x0001); /* Same */
20441f33de0fSHans de Goede 		cit_write_reg(gspca_dev, compression, 0x0109);
20451f33de0fSHans de Goede 		clock_div = 3;
20461f33de0fSHans de Goede 		break;
20471f33de0fSHans de Goede 	case 320:
20481f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0101); /* Same on 160x120, 320x240 */
20491f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x00a0, 0x0103); /* Same on 160x120, 320x240 */
20501f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0078, 0x0105); /* Same on 160x120, 320x240 */
20511f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x010a); /* Same */
20521f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0028, 0x010b); /* Differs everywhere */
20531f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0002, 0x011d); /* Same */
20541f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x011e);
20551f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0129); /* Same */
20561f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x00fc, 0x012b); /* Same */
20571f33de0fSHans de Goede 		/* 4 commands from 160x120 skipped */
20581f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0022, 0x012a); /* Same */
20591f33de0fSHans de Goede 		cit_model3_Packet1(gspca_dev, 0x0021, 0x0001); /* Same */
20601f33de0fSHans de Goede 		cit_write_reg(gspca_dev, compression, 0x0109);
20611f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x00d9, 0x0119);
20621f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0006, 0x011b);
20631f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0021, 0x0102); /* Same on 320x240, 640x480 */
20641f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0010, 0x0104);
20651f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0004, 0x011a);
20661f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x003f, 0x011c);
20671f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x001c, 0x0118);
20681f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0132);
20691f33de0fSHans de Goede 		clock_div = 5;
20701f33de0fSHans de Goede 		break;
20711f33de0fSHans de Goede 	case 640:
20721f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x00f0, 0x0105);
20731f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x010a); /* Same */
20741f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0038, 0x010b); /* Differs everywhere */
20751f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x00d9, 0x0119); /* Same on 320x240, 640x480 */
20761f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0006, 0x011b); /* Same on 320x240, 640x480 */
20771f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0004, 0x011d); /* NC */
20781f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0003, 0x011e); /* Same on 160x120, 640x480 */
20791f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0129); /* Same */
20801f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x00fc, 0x012b); /* Same */
20811f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0021, 0x0102); /* Same on 320x240, 640x480 */
20821f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0016, 0x0104); /* NC */
20831f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0004, 0x011a); /* Same on 320x240, 640x480 */
20841f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x003f, 0x011c); /* Same on 320x240, 640x480 */
20851f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0022, 0x012a); /* Same */
20861f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x001c, 0x0118); /* Same on 320x240, 640x480 */
20871f33de0fSHans de Goede 		cit_model3_Packet1(gspca_dev, 0x0021, 0x0001); /* Same */
20881f33de0fSHans de Goede 		cit_write_reg(gspca_dev, compression, 0x0109);
20891f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0040, 0x0101);
20901f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0040, 0x0103);
20911f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0132); /* Same on 320x240, 640x480 */
20921f33de0fSHans de Goede 		clock_div = 7;
20931f33de0fSHans de Goede 		break;
20941f33de0fSHans de Goede 	}
20951f33de0fSHans de Goede 
20961f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x007e, 0x000e);	/* Hue */
20971f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0036, 0x0011);	/* Brightness */
20981f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0060, 0x0002);	/* Sharpness */
20991f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0061, 0x0004);	/* Sharpness */
21001f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0062, 0x0005);	/* Sharpness */
21011f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0063, 0x0014);	/* Sharpness */
21021f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0096, 0x00a0);	/* Red sharpness */
21031f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0097, 0x0096);	/* Blue sharpness */
21041f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0067, 0x0001);	/* Contrast */
21051f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x005b, 0x000c);	/* Contrast */
21061f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x005c, 0x0016);	/* Contrast */
21071f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0098, 0x000b);
21081f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x002c, 0x0003);	/* Was 1, broke 640x480 */
21091f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x002f, 0x002a);
21101f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0030, 0x0029);
21111f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0037, 0x0002);
21121f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0038, 0x0059);
21131f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x003d, 0x002e);
21141f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x003e, 0x0028);
21151f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0078, 0x0005);
21161f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x007b, 0x0011);
21171f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x007d, 0x004b);
21181f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x007f, 0x0022);
21191f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0080, 0x000c);
21201f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0081, 0x000b);
21211f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0083, 0x00fd);
21221f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0086, 0x000b);
21231f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0087, 0x000b);
21241f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x007e, 0x000e);
21251f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0096, 0x00a0);	/* Red sharpness */
21261f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0097, 0x0096);	/* Blue sharpness */
21271f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0098, 0x000b);
21281f33de0fSHans de Goede 
212941f424baSHans de Goede 	/* FIXME we should probably use cit_get_clock_div() here (in
213041f424baSHans de Goede 	   combination with isoc negotiation using the programmable isoc size)
213141f424baSHans de Goede 	   like with the IBM netcam pro). */
21321f33de0fSHans de Goede 	cit_write_reg(gspca_dev, clock_div, 0x0111); /* Clock Divider */
21331f33de0fSHans de Goede 
21341966bc2aSOndrej Zary 	switch (gspca_dev->pixfmt.width) {
21351f33de0fSHans de Goede 	case 160:
21361f33de0fSHans de Goede 		cit_model3_Packet1(gspca_dev, 0x001f, 0x0000); /* Same */
21371f33de0fSHans de Goede 		cit_model3_Packet1(gspca_dev, 0x0039, 0x001f); /* Same */
21381f33de0fSHans de Goede 		cit_model3_Packet1(gspca_dev, 0x003b, 0x003c); /* Same */
21391f33de0fSHans de Goede 		cit_model3_Packet1(gspca_dev, 0x0040, 0x000a);
21401f33de0fSHans de Goede 		cit_model3_Packet1(gspca_dev, 0x0051, 0x000a);
21411f33de0fSHans de Goede 		break;
21421f33de0fSHans de Goede 	case 320:
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, 0x0008);
21471f33de0fSHans de Goede 		cit_model3_Packet1(gspca_dev, 0x0051, 0x000b);
21481f33de0fSHans de Goede 		break;
21491f33de0fSHans de Goede 	case 640:
21501f33de0fSHans de Goede 		cit_model3_Packet1(gspca_dev, 0x001f, 0x0002);	/* !Same */
21511f33de0fSHans de Goede 		cit_model3_Packet1(gspca_dev, 0x0039, 0x003e);	/* !Same */
21521f33de0fSHans de Goede 		cit_model3_Packet1(gspca_dev, 0x0040, 0x0008);
21531f33de0fSHans de Goede 		cit_model3_Packet1(gspca_dev, 0x0051, 0x000a);
21541f33de0fSHans de Goede 		break;
21551f33de0fSHans de Goede 	}
21561f33de0fSHans de Goede 
21571f33de0fSHans de Goede /*	if (sd->input_index) { */
21581f33de0fSHans de Goede 	if (rca_input) {
21591f33de0fSHans de Goede 		for (i = 0; i < ARRAY_SIZE(rca_initdata); i++) {
21601f33de0fSHans de Goede 			if (rca_initdata[i][0])
2161e0657be5SHans de Goede 				cit_read_reg(gspca_dev, rca_initdata[i][2], 0);
21621f33de0fSHans de Goede 			else
21631f33de0fSHans de Goede 				cit_write_reg(gspca_dev, rca_initdata[i][1],
21641f33de0fSHans de Goede 					      rca_initdata[i][2]);
21651f33de0fSHans de Goede 		}
21661f33de0fSHans de Goede 	}
21671f33de0fSHans de Goede 
216859f90a01SHans de Goede 	return 0;
216959f90a01SHans de Goede }
217059f90a01SHans de Goede 
217159f90a01SHans de Goede static int cit_start_model4(struct gspca_dev *gspca_dev)
217259f90a01SHans de Goede {
217359f90a01SHans de Goede 	struct sd *sd = (struct sd *) gspca_dev;
217459f90a01SHans de Goede 
217559f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0100);
217659f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x00c0, 0x0111);
217759f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x00bc, 0x012c);
217859f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0080, 0x012b);
217959f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0108);
218059f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0001, 0x0133);
218159f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x009b, 0x010f);
218259f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x00bb, 0x010f);
218359f90a01SHans de Goede 	cit_model4_Packet1(gspca_dev, 0x0038, 0x0000);
218459f90a01SHans de Goede 	cit_model4_Packet1(gspca_dev, 0x000a, 0x005c);
218559f90a01SHans de Goede 
218659f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x00aa, 0x012d);
218759f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0004, 0x012f);
218859f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0xd141, 0x0124);
218959f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0127);
219059f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x00fb, 0x012e);
219159f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0130);
219259f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x8a28, 0x0124);
219359f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x00aa, 0x012f);
219459f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0xd055, 0x0124);
219559f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x000c, 0x0127);
219659f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0009, 0x012e);
219759f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0xaa28, 0x0124);
219859f90a01SHans de Goede 
219959f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x00aa, 0x012d);
220059f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0012, 0x012f);
220159f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0xd141, 0x0124);
220259f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0008, 0x0127);
220359f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x00aa, 0x0130);
220459f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x82a8, 0x0124);
220559f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x002a, 0x012d);
220659f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x012f);
220759f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0xd145, 0x0124);
220859f90a01SHans de Goede 	cit_write_reg(gspca_dev, 0xfffa, 0x0124);
220959f90a01SHans de Goede 	cit_model4_Packet1(gspca_dev, 0x0034, 0x0000);
221059f90a01SHans de Goede 
22111966bc2aSOndrej Zary 	switch (gspca_dev->pixfmt.width) {
221259f90a01SHans de Goede 	case 128: /* 128x96 */
221359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0070, 0x0119);
221459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00d0, 0x0111);
221559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0039, 0x010a);
221659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0001, 0x0102);
221759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0028, 0x0103);
221859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0104);
221959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x001e, 0x0105);
222059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
222159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0016, 0x012f);
222259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd141, 0x0124);
222359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x000a, 0x0127);
222459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x0130);
222559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x82a8, 0x0124);
222659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0014, 0x012d);
222759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0008, 0x012f);
222859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd145, 0x0124);
222959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x012e);
223059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x001a, 0x0130);
223159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x8a0a, 0x0124);
223259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x005a, 0x012d);
223359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x9545, 0x0124);
223459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x0127);
223559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0018, 0x012e);
223659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0043, 0x0130);
223759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x8a28, 0x0124);
223859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x012f);
223959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd055, 0x0124);
224059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x001c, 0x0127);
224159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00eb, 0x012e);
224259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xaa28, 0x0124);
224359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
224459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0032, 0x012f);
224559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd141, 0x0124);
224659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0127);
224759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x0130);
224859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x82a8, 0x0124);
224959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0036, 0x012d);
225059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0008, 0x012f);
225159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd145, 0x0124);
225259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xfffa, 0x0124);
225359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
225459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x001e, 0x012f);
225559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd141, 0x0124);
225659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0017, 0x0127);
225759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0013, 0x012e);
225859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0031, 0x0130);
225959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x8a28, 0x0124);
226059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0017, 0x012d);
226159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0078, 0x012f);
226259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd145, 0x0124);
226359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0127);
226459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xfea8, 0x0124);
226559f90a01SHans de Goede 		sd->sof_len = 2;
226659f90a01SHans de Goede 		break;
226759f90a01SHans de Goede 	case 160: /* 160x120 */
226859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0038, 0x0119);
226959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00d0, 0x0111);
227059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00b9, 0x010a);
227159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0001, 0x0102);
227259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0028, 0x0103);
227359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0104);
227459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x001e, 0x0105);
227559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
227659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0016, 0x012f);
227759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd141, 0x0124);
227859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x000b, 0x0127);
227959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x0130);
228059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x82a8, 0x0124);
228159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0014, 0x012d);
228259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0008, 0x012f);
228359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd145, 0x0124);
228459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x012e);
228559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x001a, 0x0130);
228659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x8a0a, 0x0124);
228759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x005a, 0x012d);
228859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x9545, 0x0124);
228959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x0127);
229059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0018, 0x012e);
229159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0043, 0x0130);
229259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x8a28, 0x0124);
229359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x012f);
229459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd055, 0x0124);
229559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x001c, 0x0127);
229659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00c7, 0x012e);
229759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xaa28, 0x0124);
229859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
229959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0032, 0x012f);
230059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd141, 0x0124);
230159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0025, 0x0127);
230259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x0130);
230359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x82a8, 0x0124);
230459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0036, 0x012d);
230559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0008, 0x012f);
230659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd145, 0x0124);
230759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xfffa, 0x0124);
230859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
230959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x001e, 0x012f);
231059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd141, 0x0124);
231159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0048, 0x0127);
231259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0035, 0x012e);
231359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00d0, 0x0130);
231459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x8a28, 0x0124);
231559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0048, 0x012d);
231659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0090, 0x012f);
231759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd145, 0x0124);
231859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0001, 0x0127);
231959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xfea8, 0x0124);
232059f90a01SHans de Goede 		sd->sof_len = 2;
232159f90a01SHans de Goede 		break;
232259f90a01SHans de Goede 	case 176: /* 176x144 */
232359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0038, 0x0119);
232459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00d0, 0x0111);
232559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00b9, 0x010a);
232659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0001, 0x0102);
232759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x002c, 0x0103);
232859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0104);
232959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0024, 0x0105);
233059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
233159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0016, 0x012f);
233259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd141, 0x0124);
233359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0007, 0x0127);
233459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x0130);
233559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x82a8, 0x0124);
233659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0014, 0x012d);
233759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0001, 0x012f);
233859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd145, 0x0124);
233959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x012e);
234059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x001a, 0x0130);
234159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x8a0a, 0x0124);
234259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x005e, 0x012d);
234359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x9545, 0x0124);
234459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x0127);
234559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0018, 0x012e);
234659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0049, 0x0130);
234759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x8a28, 0x0124);
234859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x012f);
234959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd055, 0x0124);
235059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x001c, 0x0127);
235159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00c7, 0x012e);
235259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xaa28, 0x0124);
235359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
235459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0032, 0x012f);
235559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd141, 0x0124);
235659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0028, 0x0127);
235759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x0130);
235859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x82a8, 0x0124);
235959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0036, 0x012d);
236059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0008, 0x012f);
236159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd145, 0x0124);
236259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xfffa, 0x0124);
236359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
236459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x001e, 0x012f);
236559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd141, 0x0124);
236659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0010, 0x0127);
236759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0013, 0x012e);
236859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x002a, 0x0130);
236959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x8a28, 0x0124);
237059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0010, 0x012d);
237159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x006d, 0x012f);
237259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd145, 0x0124);
237359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0001, 0x0127);
237459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xfea8, 0x0124);
237559f90a01SHans de Goede 		/* TESTME HDG: this does not seem right
237659f90a01SHans de Goede 		   (it is 2 for all other resolutions) */
237759f90a01SHans de Goede 		sd->sof_len = 10;
237859f90a01SHans de Goede 		break;
237959f90a01SHans de Goede 	case 320: /* 320x240 */
238059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0070, 0x0119);
238159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00d0, 0x0111);
238259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0039, 0x010a);
238359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0001, 0x0102);
238459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0028, 0x0103);
238559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0104);
238659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x001e, 0x0105);
238759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
238859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0016, 0x012f);
238959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd141, 0x0124);
239059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x000a, 0x0127);
239159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x0130);
239259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x82a8, 0x0124);
239359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0014, 0x012d);
239459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0008, 0x012f);
239559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd145, 0x0124);
239659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x012e);
239759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x001a, 0x0130);
239859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x8a0a, 0x0124);
239959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x005a, 0x012d);
240059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x9545, 0x0124);
240159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x0127);
240259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0018, 0x012e);
240359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0043, 0x0130);
240459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x8a28, 0x0124);
240559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x012f);
240659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd055, 0x0124);
240759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x001c, 0x0127);
240859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00eb, 0x012e);
240959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xaa28, 0x0124);
241059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
241159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0032, 0x012f);
241259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd141, 0x0124);
241359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0127);
241459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x0130);
241559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x82a8, 0x0124);
241659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0036, 0x012d);
241759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0008, 0x012f);
241859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd145, 0x0124);
241959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xfffa, 0x0124);
242059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
242159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x001e, 0x012f);
242259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd141, 0x0124);
242359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0017, 0x0127);
242459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0013, 0x012e);
242559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0031, 0x0130);
242659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x8a28, 0x0124);
242759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0017, 0x012d);
242859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0078, 0x012f);
242959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd145, 0x0124);
243059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0127);
243159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xfea8, 0x0124);
243259f90a01SHans de Goede 		sd->sof_len = 2;
243359f90a01SHans de Goede 		break;
243459f90a01SHans de Goede 	case 352: /* 352x288 */
243559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0070, 0x0119);
243659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00c0, 0x0111);
243759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0039, 0x010a);
243859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0001, 0x0102);
243959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x002c, 0x0103);
244059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0104);
244159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0024, 0x0105);
244259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
244359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0016, 0x012f);
244459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd141, 0x0124);
244559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0006, 0x0127);
244659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x0130);
244759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x82a8, 0x0124);
244859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0014, 0x012d);
244959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0002, 0x012f);
245059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd145, 0x0124);
245159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x012e);
245259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x001a, 0x0130);
245359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x8a0a, 0x0124);
245459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x005e, 0x012d);
245559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x9545, 0x0124);
245659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x0127);
245759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0018, 0x012e);
245859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0049, 0x0130);
245959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x8a28, 0x0124);
246059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x012f);
246159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd055, 0x0124);
246259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x001c, 0x0127);
246359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00cf, 0x012e);
246459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xaa28, 0x0124);
246559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
246659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0032, 0x012f);
246759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd141, 0x0124);
246859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0127);
246959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x0130);
247059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x82a8, 0x0124);
247159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0036, 0x012d);
247259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0008, 0x012f);
247359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd145, 0x0124);
247459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xfffa, 0x0124);
247559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
247659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x001e, 0x012f);
247759f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd141, 0x0124);
247859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0010, 0x0127);
247959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0013, 0x012e);
248059f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0025, 0x0130);
248159f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x8a28, 0x0124);
248259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0010, 0x012d);
248359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0048, 0x012f);
248459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xd145, 0x0124);
248559f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0127);
248659f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0xfea8, 0x0124);
248759f90a01SHans de Goede 		sd->sof_len = 2;
248859f90a01SHans de Goede 		break;
248959f90a01SHans de Goede 	}
249059f90a01SHans de Goede 
249159f90a01SHans de Goede 	cit_model4_Packet1(gspca_dev, 0x0038, 0x0004);
249259f90a01SHans de Goede 
24931f33de0fSHans de Goede 	return 0;
24941f33de0fSHans de Goede }
24951f33de0fSHans de Goede 
24961f33de0fSHans de Goede static int cit_start_ibm_netcam_pro(struct gspca_dev *gspca_dev)
24971f33de0fSHans de Goede {
24981f33de0fSHans de Goede 	const unsigned short compression = 0; /* 0=none, 7=best frame rate */
249941f424baSHans de Goede 	int i, clock_div;
250041f424baSHans de Goede 
250141f424baSHans de Goede 	clock_div = cit_get_clock_div(gspca_dev);
250241f424baSHans de Goede 	if (clock_div < 0)
250341f424baSHans de Goede 		return clock_div;
25041f33de0fSHans de Goede 
25051f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0003, 0x0133);
25061f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0117);
25071f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0008, 0x0123);
25081f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0100);
25091f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0060, 0x0116);
25101f33de0fSHans de Goede 	/* cit_write_reg(gspca_dev, 0x0002, 0x0112); see sd_stop0 */
25111f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0133);
25121f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0123);
25131f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0001, 0x0117);
25141f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0040, 0x0108);
25151f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0019, 0x012c);
25161f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0060, 0x0116);
25171f33de0fSHans de Goede 	/* cit_write_reg(gspca_dev, 0x000b, 0x0115); see sd_stop0 */
25181f33de0fSHans de Goede 
25191f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0049, 0x0000);
25201f33de0fSHans de Goede 
25211f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0101); /* Same on 160x120, 320x240 */
25221f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x003a, 0x0102); /* Hstart */
25231f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x00a0, 0x0103); /* Same on 160x120, 320x240 */
25241f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0078, 0x0105); /* Same on 160x120, 320x240 */
25251f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x010a); /* Same */
25261f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0002, 0x011d); /* Same on 160x120, 320x240 */
25271f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x0129); /* Same */
25281f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x00fc, 0x012b); /* Same */
25291f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0022, 0x012a); /* Same */
25301f33de0fSHans de Goede 
25311966bc2aSOndrej Zary 	switch (gspca_dev->pixfmt.width) {
2532659fefa0SHans de Goede 	case 160: /* 160x120 */
25331f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0024, 0x010b);
25341f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0089, 0x0119);
25351f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x000a, 0x011b);
25361f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0003, 0x011e);
25371f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0007, 0x0104);
25381f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0009, 0x011a);
25391f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x008b, 0x011c);
25401f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0008, 0x0118);
25411f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0132);
25421f33de0fSHans de Goede 		break;
2543659fefa0SHans de Goede 	case 320: /* 320x240 */
25441f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0028, 0x010b);
25451f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x00d9, 0x0119);
25461f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0006, 0x011b);
25471f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x011e);
25481f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x000e, 0x0104);
25491f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0004, 0x011a);
25501f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x003f, 0x011c);
25511f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x000c, 0x0118);
25521f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0132);
25531f33de0fSHans de Goede 		break;
25541f33de0fSHans de Goede 	}
25551f33de0fSHans de Goede 
25561f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0019, 0x0031);
25571f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x001a, 0x0003);
25581f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x001b, 0x0038);
25591f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x001c, 0x0000);
25601f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0024, 0x0001);
25611f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0027, 0x0001);
25621f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x002a, 0x0004);
25631f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0035, 0x000b);
25641f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x003f, 0x0001);
25651f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0044, 0x0000);
25661f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x0054, 0x0000);
25671f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00c4, 0x0000);
25681f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00e7, 0x0001);
25691f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00e9, 0x0001);
25701f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00ee, 0x0000);
25711f33de0fSHans de Goede 	cit_model3_Packet1(gspca_dev, 0x00f3, 0x00c0);
25721f33de0fSHans de Goede 
25731f33de0fSHans de Goede 	cit_write_reg(gspca_dev, compression, 0x0109);
25741f33de0fSHans de Goede 	cit_write_reg(gspca_dev, clock_div, 0x0111);
25751f33de0fSHans de Goede 
25761f33de0fSHans de Goede /*	if (sd->input_index) { */
25771f33de0fSHans de Goede 	if (rca_input) {
25781f33de0fSHans de Goede 		for (i = 0; i < ARRAY_SIZE(rca_initdata); i++) {
25791f33de0fSHans de Goede 			if (rca_initdata[i][0])
2580e0657be5SHans de Goede 				cit_read_reg(gspca_dev, rca_initdata[i][2], 0);
25811f33de0fSHans de Goede 			else
25821f33de0fSHans de Goede 				cit_write_reg(gspca_dev, rca_initdata[i][1],
25831f33de0fSHans de Goede 					      rca_initdata[i][2]);
25841f33de0fSHans de Goede 		}
25851f33de0fSHans de Goede 	}
25861f33de0fSHans de Goede 
25871f33de0fSHans de Goede 	return 0;
25881f33de0fSHans de Goede }
25891f33de0fSHans de Goede 
25901f33de0fSHans de Goede /* -- start the camera -- */
25911f33de0fSHans de Goede static int sd_start(struct gspca_dev *gspca_dev)
25921f33de0fSHans de Goede {
25931f33de0fSHans de Goede 	struct sd *sd = (struct sd *) gspca_dev;
25941f33de0fSHans de Goede 	int packet_size;
25951f33de0fSHans de Goede 
2596659fefa0SHans de Goede 	packet_size = cit_get_packet_size(gspca_dev);
2597659fefa0SHans de Goede 	if (packet_size < 0)
2598659fefa0SHans de Goede 		return packet_size;
2599659fefa0SHans de Goede 
26001f33de0fSHans de Goede 	switch (sd->model) {
2601659fefa0SHans de Goede 	case CIT_MODEL0:
2602659fefa0SHans de Goede 		cit_start_model0(gspca_dev);
2603659fefa0SHans de Goede 		break;
260459f90a01SHans de Goede 	case CIT_MODEL1:
260559f90a01SHans de Goede 		cit_start_model1(gspca_dev);
260659f90a01SHans de Goede 		break;
260759f90a01SHans de Goede 	case CIT_MODEL2:
260859f90a01SHans de Goede 		cit_start_model2(gspca_dev);
260959f90a01SHans de Goede 		break;
26101f33de0fSHans de Goede 	case CIT_MODEL3:
26111f33de0fSHans de Goede 		cit_start_model3(gspca_dev);
26121f33de0fSHans de Goede 		break;
261359f90a01SHans de Goede 	case CIT_MODEL4:
261459f90a01SHans de Goede 		cit_start_model4(gspca_dev);
261559f90a01SHans de Goede 		break;
26161f33de0fSHans de Goede 	case CIT_IBM_NETCAM_PRO:
26171f33de0fSHans de Goede 		cit_start_ibm_netcam_pro(gspca_dev);
26181f33de0fSHans de Goede 		break;
26191f33de0fSHans de Goede 	}
26201f33de0fSHans de Goede 
2621659fefa0SHans de Goede 	/* Program max isoc packet size */
26221f33de0fSHans de Goede 	cit_write_reg(gspca_dev, packet_size >> 8, 0x0106);
26231f33de0fSHans de Goede 	cit_write_reg(gspca_dev, packet_size & 0xff, 0x0107);
26241f33de0fSHans de Goede 
26251f33de0fSHans de Goede 	cit_restart_stream(gspca_dev);
26261f33de0fSHans de Goede 
26271f33de0fSHans de Goede 	return 0;
26281f33de0fSHans de Goede }
26291f33de0fSHans de Goede 
2630bc46bae6SHans de Goede static int sd_isoc_init(struct gspca_dev *gspca_dev)
2631bc46bae6SHans de Goede {
2632a246b4d5SJohan Hovold 	struct usb_interface_cache *intfc;
2633bc46bae6SHans de Goede 	struct usb_host_interface *alt;
2634bc46bae6SHans de Goede 	int max_packet_size;
2635bc46bae6SHans de Goede 
26361966bc2aSOndrej Zary 	switch (gspca_dev->pixfmt.width) {
2637bc46bae6SHans de Goede 	case 160:
2638bc46bae6SHans de Goede 		max_packet_size = 450;
2639bc46bae6SHans de Goede 		break;
2640bc46bae6SHans de Goede 	case 176:
2641bc46bae6SHans de Goede 		max_packet_size = 600;
2642bc46bae6SHans de Goede 		break;
2643bc46bae6SHans de Goede 	default:
2644bc46bae6SHans de Goede 		max_packet_size = 1022;
2645bc46bae6SHans de Goede 		break;
2646bc46bae6SHans de Goede 	}
2647bc46bae6SHans de Goede 
2648a246b4d5SJohan Hovold 	intfc = gspca_dev->dev->actconfig->intf_cache[0];
2649a246b4d5SJohan Hovold 
2650a246b4d5SJohan Hovold 	if (intfc->num_altsetting < 2)
2651a246b4d5SJohan Hovold 		return -ENODEV;
2652a246b4d5SJohan Hovold 
2653a246b4d5SJohan Hovold 	alt = &intfc->altsetting[1];
2654a246b4d5SJohan Hovold 
2655a246b4d5SJohan Hovold 	if (alt->desc.bNumEndpoints < 1)
2656a246b4d5SJohan Hovold 		return -ENODEV;
2657a246b4d5SJohan Hovold 
2658bc46bae6SHans de Goede 	/* Start isoc bandwidth "negotiation" at max isoc bandwidth */
2659bc46bae6SHans de Goede 	alt->endpoint[0].desc.wMaxPacketSize = cpu_to_le16(max_packet_size);
2660bc46bae6SHans de Goede 
2661bc46bae6SHans de Goede 	return 0;
2662bc46bae6SHans de Goede }
2663bc46bae6SHans de Goede 
266459f8b0bfSHans de Goede static int sd_isoc_nego(struct gspca_dev *gspca_dev)
266559f8b0bfSHans de Goede {
2666bc46bae6SHans de Goede 	int ret, packet_size, min_packet_size;
266759f8b0bfSHans de Goede 	struct usb_host_interface *alt;
266859f8b0bfSHans de Goede 
26691966bc2aSOndrej Zary 	switch (gspca_dev->pixfmt.width) {
2670bc46bae6SHans de Goede 	case 160:
2671bc46bae6SHans de Goede 		min_packet_size = 200;
2672bc46bae6SHans de Goede 		break;
2673bc46bae6SHans de Goede 	case 176:
2674bc46bae6SHans de Goede 		min_packet_size = 266;
2675bc46bae6SHans de Goede 		break;
2676bc46bae6SHans de Goede 	default:
2677bc46bae6SHans de Goede 		min_packet_size = 400;
2678bc46bae6SHans de Goede 		break;
2679bc46bae6SHans de Goede 	}
2680bc46bae6SHans de Goede 
2681a246b4d5SJohan Hovold 	/*
2682a246b4d5SJohan Hovold 	 * Existence of altsetting and endpoint was verified in sd_isoc_init()
2683a246b4d5SJohan Hovold 	 */
26845dae603dSHans de Goede 	alt = &gspca_dev->dev->actconfig->intf_cache[0]->altsetting[1];
268559f8b0bfSHans de Goede 	packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
2686bc46bae6SHans de Goede 	if (packet_size <= min_packet_size)
268759f8b0bfSHans de Goede 		return -EIO;
2688bc46bae6SHans de Goede 
2689bc46bae6SHans de Goede 	packet_size -= 100;
2690bc46bae6SHans de Goede 	if (packet_size < min_packet_size)
2691bc46bae6SHans de Goede 		packet_size = min_packet_size;
269259f8b0bfSHans de Goede 	alt->endpoint[0].desc.wMaxPacketSize = cpu_to_le16(packet_size);
269359f8b0bfSHans de Goede 
269459f8b0bfSHans de Goede 	ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1);
269559f8b0bfSHans de Goede 	if (ret < 0)
2696133a9fe9SJoe Perches 		pr_err("set alt 1 err %d\n", ret);
269759f8b0bfSHans de Goede 
269859f8b0bfSHans de Goede 	return ret;
269959f8b0bfSHans de Goede }
270059f8b0bfSHans de Goede 
27011f33de0fSHans de Goede static void sd_stopN(struct gspca_dev *gspca_dev)
27021f33de0fSHans de Goede {
27031f33de0fSHans de Goede 	cit_write_reg(gspca_dev, 0x0000, 0x010c);
27041f33de0fSHans de Goede }
27051f33de0fSHans de Goede 
27061f33de0fSHans de Goede static void sd_stop0(struct gspca_dev *gspca_dev)
27071f33de0fSHans de Goede {
27081f33de0fSHans de Goede 	struct sd *sd = (struct sd *) gspca_dev;
27091f33de0fSHans de Goede 
2710345321dcSHans de Goede 	if (!gspca_dev->present)
27111f33de0fSHans de Goede 		return;
27121f33de0fSHans de Goede 
27131f33de0fSHans de Goede 	switch (sd->model) {
2714659fefa0SHans de Goede 	case CIT_MODEL0:
2715659fefa0SHans de Goede 		/* HDG windows does this, but it causes the cams autogain to
2716659fefa0SHans de Goede 		   restart from a gain of 0, which does not look good when
2717659fefa0SHans de Goede 		   changing resolutions. */
2718659fefa0SHans de Goede 		/* cit_write_reg(gspca_dev, 0x0000, 0x0112); */
2719659fefa0SHans de Goede 		cit_write_reg(gspca_dev, 0x00c0, 0x0100); /* LED Off */
2720659fefa0SHans de Goede 		break;
272159f90a01SHans de Goede 	case CIT_MODEL1:
272259f90a01SHans de Goede 		cit_send_FF_04_02(gspca_dev);
2723e0657be5SHans de Goede 		cit_read_reg(gspca_dev, 0x0100, 0);
272459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x81, 0x0100);	/* LED Off */
272559f90a01SHans de Goede 		break;
272659f90a01SHans de Goede 	case CIT_MODEL2:
2727872099e8SHans de Goede 		v4l2_ctrl_grab(sd->lighting, false);
2728*1771e9fbSGustavo A. R. Silva 		fallthrough;
272959f90a01SHans de Goede 	case CIT_MODEL4:
273059f90a01SHans de Goede 		cit_model2_Packet1(gspca_dev, 0x0030, 0x0004);
273159f90a01SHans de Goede 
273259f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0080, 0x0100);	/* LED Off */
273359f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0020, 0x0111);
273459f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x00a0, 0x0111);
273559f90a01SHans de Goede 
273659f90a01SHans de Goede 		cit_model2_Packet1(gspca_dev, 0x0030, 0x0002);
273759f90a01SHans de Goede 
273859f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0020, 0x0111);
273959f90a01SHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0112);
274059f90a01SHans de Goede 		break;
27411f33de0fSHans de Goede 	case CIT_MODEL3:
27421f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0006, 0x012c);
27431f33de0fSHans de Goede 		cit_model3_Packet1(gspca_dev, 0x0046, 0x0000);
2744e0657be5SHans de Goede 		cit_read_reg(gspca_dev, 0x0116, 0);
27451f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0064, 0x0116);
2746e0657be5SHans de Goede 		cit_read_reg(gspca_dev, 0x0115, 0);
27471f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0003, 0x0115);
27481f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0008, 0x0123);
27491f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0117);
27501f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0112);
27511f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0080, 0x0100);
27521f33de0fSHans de Goede 		break;
27531f33de0fSHans de Goede 	case CIT_IBM_NETCAM_PRO:
27541f33de0fSHans de Goede 		cit_model3_Packet1(gspca_dev, 0x0049, 0x00ff);
27551f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0006, 0x012c);
27561f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0116);
27571f33de0fSHans de Goede 		/* HDG windows does this, but I cannot get the camera
27581f33de0fSHans de Goede 		   to restart with this without redoing the entire init
27591f33de0fSHans de Goede 		   sequence which makes switching modes really slow */
27601f33de0fSHans de Goede 		/* cit_write_reg(gspca_dev, 0x0006, 0x0115); */
27611f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0008, 0x0123);
27621f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0117);
27631f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0003, 0x0133);
27641f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x0000, 0x0111);
27651f33de0fSHans de Goede 		/* HDG windows does this, but I get a green picture when
27661f33de0fSHans de Goede 		   restarting the stream after this */
27671f33de0fSHans de Goede 		/* cit_write_reg(gspca_dev, 0x0000, 0x0112); */
27681f33de0fSHans de Goede 		cit_write_reg(gspca_dev, 0x00c0, 0x0100);
27691f33de0fSHans de Goede 		break;
27701f33de0fSHans de Goede 	}
2771e0657be5SHans de Goede 
2772e32d6eb8SPeter Senna Tschudin #if IS_ENABLED(CONFIG_INPUT)
2773e0657be5SHans de Goede 	/* If the last button state is pressed, release it now! */
2774e0657be5SHans de Goede 	if (sd->button_state) {
2775e0657be5SHans de Goede 		input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
2776e0657be5SHans de Goede 		input_sync(gspca_dev->input_dev);
2777e0657be5SHans de Goede 		sd->button_state = 0;
2778e0657be5SHans de Goede 	}
2779e0657be5SHans de Goede #endif
27801f33de0fSHans de Goede }
27811f33de0fSHans de Goede 
27821f33de0fSHans de Goede static u8 *cit_find_sof(struct gspca_dev *gspca_dev, u8 *data, int len)
27831f33de0fSHans de Goede {
27841f33de0fSHans de Goede 	struct sd *sd = (struct sd *) gspca_dev;
2785659fefa0SHans de Goede 	u8 byte3 = 0, byte4 = 0;
27861f33de0fSHans de Goede 	int i;
27871f33de0fSHans de Goede 
27881f33de0fSHans de Goede 	switch (sd->model) {
2789659fefa0SHans de Goede 	case CIT_MODEL0:
279059f90a01SHans de Goede 	case CIT_MODEL1:
27911f33de0fSHans de Goede 	case CIT_MODEL3:
27921f33de0fSHans de Goede 	case CIT_IBM_NETCAM_PRO:
27931966bc2aSOndrej Zary 		switch (gspca_dev->pixfmt.width) {
2794659fefa0SHans de Goede 		case 160: /* 160x120 */
279559f90a01SHans de Goede 			byte3 = 0x02;
2796659fefa0SHans de Goede 			byte4 = 0x0a;
2797659fefa0SHans de Goede 			break;
2798659fefa0SHans de Goede 		case 176: /* 176x144 */
2799659fefa0SHans de Goede 			byte3 = 0x02;
2800659fefa0SHans de Goede 			byte4 = 0x0e;
2801659fefa0SHans de Goede 			break;
2802659fefa0SHans de Goede 		case 320: /* 320x240 */
2803659fefa0SHans de Goede 			byte3 = 0x02;
2804659fefa0SHans de Goede 			byte4 = 0x08;
2805659fefa0SHans de Goede 			break;
2806659fefa0SHans de Goede 		case 352: /* 352x288 */
2807659fefa0SHans de Goede 			byte3 = 0x02;
2808659fefa0SHans de Goede 			byte4 = 0x00;
2809659fefa0SHans de Goede 			break;
2810659fefa0SHans de Goede 		case 640:
2811659fefa0SHans de Goede 			byte3 = 0x03;
2812659fefa0SHans de Goede 			byte4 = 0x08;
2813659fefa0SHans de Goede 			break;
2814659fefa0SHans de Goede 		}
2815659fefa0SHans de Goede 
2816659fefa0SHans de Goede 		/* These have a different byte3 */
2817659fefa0SHans de Goede 		if (sd->model <= CIT_MODEL1)
2818659fefa0SHans de Goede 			byte3 = 0x00;
281959f90a01SHans de Goede 
28201f33de0fSHans de Goede 		for (i = 0; i < len; i++) {
2821659fefa0SHans de Goede 			/* For this model the SOF always starts at offset 0
2822659fefa0SHans de Goede 			   so no need to search the entire frame */
2823659fefa0SHans de Goede 			if (sd->model == CIT_MODEL0 && sd->sof_read != i)
2824659fefa0SHans de Goede 				break;
2825659fefa0SHans de Goede 
28261f33de0fSHans de Goede 			switch (sd->sof_read) {
28271f33de0fSHans de Goede 			case 0:
28281f33de0fSHans de Goede 				if (data[i] == 0x00)
28291f33de0fSHans de Goede 					sd->sof_read++;
28301f33de0fSHans de Goede 				break;
28311f33de0fSHans de Goede 			case 1:
28321f33de0fSHans de Goede 				if (data[i] == 0xff)
28331f33de0fSHans de Goede 					sd->sof_read++;
2834659fefa0SHans de Goede 				else if (data[i] == 0x00)
2835659fefa0SHans de Goede 					sd->sof_read = 1;
28361f33de0fSHans de Goede 				else
28371f33de0fSHans de Goede 					sd->sof_read = 0;
28381f33de0fSHans de Goede 				break;
28391f33de0fSHans de Goede 			case 2:
2840659fefa0SHans de Goede 				if (data[i] == byte3)
2841659fefa0SHans de Goede 					sd->sof_read++;
2842659fefa0SHans de Goede 				else if (data[i] == 0x00)
2843659fefa0SHans de Goede 					sd->sof_read = 1;
2844659fefa0SHans de Goede 				else
28451f33de0fSHans de Goede 					sd->sof_read = 0;
2846659fefa0SHans de Goede 				break;
2847659fefa0SHans de Goede 			case 3:
2848659fefa0SHans de Goede 				if (data[i] == byte4) {
2849659fefa0SHans de Goede 					sd->sof_read = 0;
2850659fefa0SHans de Goede 					return data + i + (sd->sof_len - 3);
285159f90a01SHans de Goede 				}
2852659fefa0SHans de Goede 				if (byte3 == 0x00 && data[i] == 0xff)
2853659fefa0SHans de Goede 					sd->sof_read = 2;
2854659fefa0SHans de Goede 				else if (data[i] == 0x00)
2855659fefa0SHans de Goede 					sd->sof_read = 1;
2856659fefa0SHans de Goede 				else
2857659fefa0SHans de Goede 					sd->sof_read = 0;
285859f90a01SHans de Goede 				break;
285959f90a01SHans de Goede 			}
286059f90a01SHans de Goede 		}
286159f90a01SHans de Goede 		break;
286259f90a01SHans de Goede 	case CIT_MODEL2:
286359f90a01SHans de Goede 	case CIT_MODEL4:
286459f90a01SHans de Goede 		/* TESTME we need to find a longer sof signature to avoid
286559f90a01SHans de Goede 		   false positives */
286659f90a01SHans de Goede 		for (i = 0; i < len; i++) {
286759f90a01SHans de Goede 			switch (sd->sof_read) {
286859f90a01SHans de Goede 			case 0:
286959f90a01SHans de Goede 				if (data[i] == 0x00)
287059f90a01SHans de Goede 					sd->sof_read++;
287159f90a01SHans de Goede 				break;
287259f90a01SHans de Goede 			case 1:
287359f90a01SHans de Goede 				sd->sof_read = 0;
287459f90a01SHans de Goede 				if (data[i] == 0xff) {
287559f90a01SHans de Goede 					if (i >= 4)
287637d5efb0SJoe Perches 						gspca_dbg(gspca_dev, D_FRAM,
287737d5efb0SJoe Perches 							  "header found at offset: %d: %02x %02x 00 %3ph\n\n",
2878659fefa0SHans de Goede 							  i - 1,
287959f90a01SHans de Goede 							  data[i - 4],
288059f90a01SHans de Goede 							  data[i - 3],
2881ee35fa22SAndy Shevchenko 							  &data[i]);
2882659fefa0SHans de Goede 					else
288337d5efb0SJoe Perches 						gspca_dbg(gspca_dev, D_FRAM,
288437d5efb0SJoe Perches 							  "header found at offset: %d: 00 %3ph\n\n",
2885659fefa0SHans de Goede 							  i - 1,
2886ee35fa22SAndy Shevchenko 							  &data[i]);
2887659fefa0SHans de Goede 					return data + i + (sd->sof_len - 1);
28881f33de0fSHans de Goede 				}
28891f33de0fSHans de Goede 				break;
28901f33de0fSHans de Goede 			}
28911f33de0fSHans de Goede 		}
28921f33de0fSHans de Goede 		break;
28931f33de0fSHans de Goede 	}
28941f33de0fSHans de Goede 	return NULL;
28951f33de0fSHans de Goede }
28961f33de0fSHans de Goede 
28971f33de0fSHans de Goede static void sd_pkt_scan(struct gspca_dev *gspca_dev,
28981f33de0fSHans de Goede 			u8 *data, int len)
28991f33de0fSHans de Goede {
290059f90a01SHans de Goede 	struct sd *sd = (struct sd *) gspca_dev;
29011f33de0fSHans de Goede 	unsigned char *sof;
29021f33de0fSHans de Goede 
29031f33de0fSHans de Goede 	sof = cit_find_sof(gspca_dev, data, len);
29041f33de0fSHans de Goede 	if (sof) {
29051f33de0fSHans de Goede 		int n;
29061f33de0fSHans de Goede 
29071f33de0fSHans de Goede 		/* finish decoding current frame */
29081f33de0fSHans de Goede 		n = sof - data;
290959f90a01SHans de Goede 		if (n > sd->sof_len)
291059f90a01SHans de Goede 			n -= sd->sof_len;
29111f33de0fSHans de Goede 		else
29121f33de0fSHans de Goede 			n = 0;
29131f33de0fSHans de Goede 		gspca_frame_add(gspca_dev, LAST_PACKET,
29141f33de0fSHans de Goede 				data, n);
29151f33de0fSHans de Goede 		gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
29161f33de0fSHans de Goede 		len -= sof - data;
29171f33de0fSHans de Goede 		data = sof;
29181f33de0fSHans de Goede 	}
29191f33de0fSHans de Goede 
29201f33de0fSHans de Goede 	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
29211f33de0fSHans de Goede }
29221f33de0fSHans de Goede 
2923e32d6eb8SPeter Senna Tschudin #if IS_ENABLED(CONFIG_INPUT)
2924e0657be5SHans de Goede static void cit_check_button(struct gspca_dev *gspca_dev)
2925e0657be5SHans de Goede {
2926e0657be5SHans de Goede 	int new_button_state;
2927e0657be5SHans de Goede 	struct sd *sd = (struct sd *)gspca_dev;
2928e0657be5SHans de Goede 
2929e0657be5SHans de Goede 	switch (sd->model) {
2930e0657be5SHans de Goede 	case CIT_MODEL3:
2931e0657be5SHans de Goede 	case CIT_IBM_NETCAM_PRO:
2932e0657be5SHans de Goede 		break;
2933e0657be5SHans de Goede 	default: /* TEST ME unknown if this works on other models too */
2934e0657be5SHans de Goede 		return;
2935e0657be5SHans de Goede 	}
2936e0657be5SHans de Goede 
2937e0657be5SHans de Goede 	/* Read the button state */
2938e0657be5SHans de Goede 	cit_read_reg(gspca_dev, 0x0113, 0);
2939e0657be5SHans de Goede 	new_button_state = !gspca_dev->usb_buf[0];
2940e0657be5SHans de Goede 
2941e0657be5SHans de Goede 	/* Tell the cam we've seen the button press, notice that this
2942e0657be5SHans de Goede 	   is a nop (iow the cam keeps reporting pressed) until the
2943e0657be5SHans de Goede 	   button is actually released. */
2944e0657be5SHans de Goede 	if (new_button_state)
2945e0657be5SHans de Goede 		cit_write_reg(gspca_dev, 0x01, 0x0113);
2946e0657be5SHans de Goede 
2947e0657be5SHans de Goede 	if (sd->button_state != new_button_state) {
2948e0657be5SHans de Goede 		input_report_key(gspca_dev->input_dev, KEY_CAMERA,
2949e0657be5SHans de Goede 				 new_button_state);
2950e0657be5SHans de Goede 		input_sync(gspca_dev->input_dev);
2951e0657be5SHans de Goede 		sd->button_state = new_button_state;
2952e0657be5SHans de Goede 	}
2953e0657be5SHans de Goede }
2954e0657be5SHans de Goede #endif
29551f33de0fSHans de Goede 
2956d5d875cbSHans Verkuil static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
2957d5d875cbSHans Verkuil {
2958d5d875cbSHans Verkuil 	struct gspca_dev *gspca_dev =
2959d5d875cbSHans Verkuil 		container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
2960d5d875cbSHans Verkuil 	struct sd *sd = (struct sd *)gspca_dev;
2961d5d875cbSHans Verkuil 
2962d5d875cbSHans Verkuil 	gspca_dev->usb_err = 0;
2963d5d875cbSHans Verkuil 
2964d5d875cbSHans Verkuil 	if (!gspca_dev->streaming)
2965d5d875cbSHans Verkuil 		return 0;
2966d5d875cbSHans Verkuil 
2967d5d875cbSHans Verkuil 	if (sd->stop_on_control_change)
2968d5d875cbSHans Verkuil 		sd_stopN(gspca_dev);
2969d5d875cbSHans Verkuil 	switch (ctrl->id) {
2970d5d875cbSHans Verkuil 	case V4L2_CID_BRIGHTNESS:
2971d5d875cbSHans Verkuil 		cit_set_brightness(gspca_dev, ctrl->val);
2972d5d875cbSHans Verkuil 		break;
2973d5d875cbSHans Verkuil 	case V4L2_CID_CONTRAST:
2974d5d875cbSHans Verkuil 		cit_set_contrast(gspca_dev, ctrl->val);
2975d5d875cbSHans Verkuil 		break;
2976d5d875cbSHans Verkuil 	case V4L2_CID_HUE:
2977d5d875cbSHans Verkuil 		cit_set_hue(gspca_dev, ctrl->val);
2978d5d875cbSHans Verkuil 		break;
2979d5d875cbSHans Verkuil 	case V4L2_CID_HFLIP:
2980d5d875cbSHans Verkuil 		cit_set_hflip(gspca_dev, ctrl->val);
2981d5d875cbSHans Verkuil 		break;
2982d5d875cbSHans Verkuil 	case V4L2_CID_SHARPNESS:
2983d5d875cbSHans Verkuil 		cit_set_sharpness(gspca_dev, ctrl->val);
2984d5d875cbSHans Verkuil 		break;
2985d5d875cbSHans Verkuil 	case V4L2_CID_BACKLIGHT_COMPENSATION:
2986d5d875cbSHans Verkuil 		cit_set_lighting(gspca_dev, ctrl->val);
2987d5d875cbSHans Verkuil 		break;
2988d5d875cbSHans Verkuil 	}
2989d5d875cbSHans Verkuil 	if (sd->stop_on_control_change)
2990d5d875cbSHans Verkuil 		cit_restart_stream(gspca_dev);
2991d5d875cbSHans Verkuil 	return gspca_dev->usb_err;
2992d5d875cbSHans Verkuil }
2993d5d875cbSHans Verkuil 
2994d5d875cbSHans Verkuil static const struct v4l2_ctrl_ops sd_ctrl_ops = {
2995d5d875cbSHans Verkuil 	.s_ctrl = sd_s_ctrl,
2996d5d875cbSHans Verkuil };
2997d5d875cbSHans Verkuil 
2998d5d875cbSHans Verkuil static int sd_init_controls(struct gspca_dev *gspca_dev)
2999d5d875cbSHans Verkuil {
3000d5d875cbSHans Verkuil 	struct sd *sd = (struct sd *)gspca_dev;
3001d5d875cbSHans Verkuil 	struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
3002d5d875cbSHans Verkuil 	bool has_brightness;
3003d5d875cbSHans Verkuil 	bool has_contrast;
3004d5d875cbSHans Verkuil 	bool has_hue;
3005d5d875cbSHans Verkuil 	bool has_sharpness;
3006d5d875cbSHans Verkuil 	bool has_lighting;
3007d5d875cbSHans Verkuil 	bool has_hflip;
3008d5d875cbSHans Verkuil 
3009d5d875cbSHans Verkuil 	has_brightness = has_contrast = has_hue =
3010d5d875cbSHans Verkuil 		has_sharpness = has_hflip = has_lighting = false;
3011d5d875cbSHans Verkuil 	switch (sd->model) {
3012d5d875cbSHans Verkuil 	case CIT_MODEL0:
3013d5d875cbSHans Verkuil 		has_contrast = has_hflip = true;
3014d5d875cbSHans Verkuil 		break;
3015d5d875cbSHans Verkuil 	case CIT_MODEL1:
3016d5d875cbSHans Verkuil 		has_brightness = has_contrast =
3017d5d875cbSHans Verkuil 			has_sharpness = has_lighting = true;
3018d5d875cbSHans Verkuil 		break;
3019d5d875cbSHans Verkuil 	case CIT_MODEL2:
3020d5d875cbSHans Verkuil 		has_brightness = has_hue = has_lighting = true;
3021d5d875cbSHans Verkuil 		break;
3022d5d875cbSHans Verkuil 	case CIT_MODEL3:
3023d5d875cbSHans Verkuil 		has_brightness = has_contrast = has_sharpness = true;
3024d5d875cbSHans Verkuil 		break;
3025d5d875cbSHans Verkuil 	case CIT_MODEL4:
3026d5d875cbSHans Verkuil 		has_brightness = has_hue = true;
3027d5d875cbSHans Verkuil 		break;
3028d5d875cbSHans Verkuil 	case CIT_IBM_NETCAM_PRO:
3029d5d875cbSHans Verkuil 		has_brightness = has_hue =
3030d5d875cbSHans Verkuil 			has_sharpness = has_hflip = has_lighting = true;
3031d5d875cbSHans Verkuil 		break;
3032d5d875cbSHans Verkuil 	}
3033d5d875cbSHans Verkuil 	gspca_dev->vdev.ctrl_handler = hdl;
3034d5d875cbSHans Verkuil 	v4l2_ctrl_handler_init(hdl, 5);
3035d5d875cbSHans Verkuil 	if (has_brightness)
3036d5d875cbSHans Verkuil 		v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
3037d5d875cbSHans Verkuil 			V4L2_CID_BRIGHTNESS, 0, 63, 1, 32);
3038d5d875cbSHans Verkuil 	if (has_contrast)
3039d5d875cbSHans Verkuil 		v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
3040d5d875cbSHans Verkuil 			V4L2_CID_CONTRAST, 0, 20, 1, 10);
3041d5d875cbSHans Verkuil 	if (has_hue)
3042d5d875cbSHans Verkuil 		v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
3043d5d875cbSHans Verkuil 			V4L2_CID_HUE, 0, 127, 1, 63);
3044d5d875cbSHans Verkuil 	if (has_sharpness)
3045d5d875cbSHans Verkuil 		v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
3046d5d875cbSHans Verkuil 			V4L2_CID_SHARPNESS, 0, 6, 1, 3);
3047d5d875cbSHans Verkuil 	if (has_lighting)
3048d5d875cbSHans Verkuil 		sd->lighting = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
3049d5d875cbSHans Verkuil 			V4L2_CID_BACKLIGHT_COMPENSATION, 0, 2, 1, 1);
3050d5d875cbSHans Verkuil 	if (has_hflip)
3051d5d875cbSHans Verkuil 		v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
3052d5d875cbSHans Verkuil 			V4L2_CID_HFLIP, 0, 1, 1, 0);
3053d5d875cbSHans Verkuil 
3054d5d875cbSHans Verkuil 	if (hdl->error) {
3055d5d875cbSHans Verkuil 		pr_err("Could not initialize controls\n");
3056d5d875cbSHans Verkuil 		return hdl->error;
3057d5d875cbSHans Verkuil 	}
3058d5d875cbSHans Verkuil 	return 0;
3059d5d875cbSHans Verkuil }
3060d5d875cbSHans Verkuil 
30611f33de0fSHans de Goede /* sub-driver description */
30621f33de0fSHans de Goede static const struct sd_desc sd_desc = {
30631f33de0fSHans de Goede 	.name = MODULE_NAME,
30641f33de0fSHans de Goede 	.config = sd_config,
30651f33de0fSHans de Goede 	.init = sd_init,
3066d5d875cbSHans Verkuil 	.init_controls = sd_init_controls,
30671f33de0fSHans de Goede 	.start = sd_start,
30681f33de0fSHans de Goede 	.stopN = sd_stopN,
30691f33de0fSHans de Goede 	.stop0 = sd_stop0,
30701f33de0fSHans de Goede 	.pkt_scan = sd_pkt_scan,
3071e32d6eb8SPeter Senna Tschudin #if IS_ENABLED(CONFIG_INPUT)
3072e0657be5SHans de Goede 	.dq_callback = cit_check_button,
3073e0657be5SHans de Goede 	.other_input = 1,
3074e0657be5SHans de Goede #endif
30751f33de0fSHans de Goede };
30761f33de0fSHans de Goede 
307759f8b0bfSHans de Goede static const struct sd_desc sd_desc_isoc_nego = {
307859f8b0bfSHans de Goede 	.name = MODULE_NAME,
307959f8b0bfSHans de Goede 	.config = sd_config,
308059f8b0bfSHans de Goede 	.init = sd_init,
3081d5d875cbSHans Verkuil 	.init_controls = sd_init_controls,
308259f8b0bfSHans de Goede 	.start = sd_start,
3083bc46bae6SHans de Goede 	.isoc_init = sd_isoc_init,
308459f8b0bfSHans de Goede 	.isoc_nego = sd_isoc_nego,
308559f8b0bfSHans de Goede 	.stopN = sd_stopN,
308659f8b0bfSHans de Goede 	.stop0 = sd_stop0,
308759f8b0bfSHans de Goede 	.pkt_scan = sd_pkt_scan,
3088e32d6eb8SPeter Senna Tschudin #if IS_ENABLED(CONFIG_INPUT)
3089e0657be5SHans de Goede 	.dq_callback = cit_check_button,
3090e0657be5SHans de Goede 	.other_input = 1,
3091e0657be5SHans de Goede #endif
309259f8b0bfSHans de Goede };
309359f8b0bfSHans de Goede 
30941f33de0fSHans de Goede /* -- module initialisation -- */
309595c967c1SJean-François Moine static const struct usb_device_id device_table[] = {
3096659fefa0SHans de Goede 	{ USB_DEVICE_VER(0x0545, 0x8080, 0x0001, 0x0001), .driver_info = CIT_MODEL0 },
30971f33de0fSHans de Goede 	{ USB_DEVICE_VER(0x0545, 0x8080, 0x0002, 0x0002), .driver_info = CIT_MODEL1 },
30981f33de0fSHans de Goede 	{ USB_DEVICE_VER(0x0545, 0x8080, 0x030a, 0x030a), .driver_info = CIT_MODEL2 },
30991f33de0fSHans de Goede 	{ USB_DEVICE_VER(0x0545, 0x8080, 0x0301, 0x0301), .driver_info = CIT_MODEL3 },
31001f33de0fSHans de Goede 	{ USB_DEVICE_VER(0x0545, 0x8002, 0x030a, 0x030a), .driver_info = CIT_MODEL4 },
31011f33de0fSHans de Goede 	{ USB_DEVICE_VER(0x0545, 0x800c, 0x030a, 0x030a), .driver_info = CIT_MODEL2 },
31021f33de0fSHans de Goede 	{ USB_DEVICE_VER(0x0545, 0x800d, 0x030a, 0x030a), .driver_info = CIT_MODEL4 },
31031f33de0fSHans de Goede 	{}
31041f33de0fSHans de Goede };
31051f33de0fSHans de Goede MODULE_DEVICE_TABLE(usb, device_table);
31061f33de0fSHans de Goede 
31071f33de0fSHans de Goede /* -- device connect -- */
31081f33de0fSHans de Goede static int sd_probe(struct usb_interface *intf,
31091f33de0fSHans de Goede 			const struct usb_device_id *id)
31101f33de0fSHans de Goede {
311159f8b0bfSHans de Goede 	const struct sd_desc *desc = &sd_desc;
311259f8b0bfSHans de Goede 
3113659fefa0SHans de Goede 	switch (id->driver_info) {
3114659fefa0SHans de Goede 	case CIT_MODEL0:
3115659fefa0SHans de Goede 	case CIT_MODEL1:
3116659fefa0SHans de Goede 		if (intf->cur_altsetting->desc.bInterfaceNumber != 2)
3117659fefa0SHans de Goede 			return -ENODEV;
3118659fefa0SHans de Goede 		break;
3119659fefa0SHans de Goede 	case CIT_MODEL2:
3120659fefa0SHans de Goede 	case CIT_MODEL4:
3121659fefa0SHans de Goede 		if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
3122659fefa0SHans de Goede 			return -ENODEV;
3123659fefa0SHans de Goede 		break;
312459f8b0bfSHans de Goede 	case CIT_MODEL3:
312559f8b0bfSHans de Goede 		if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
312659f8b0bfSHans de Goede 			return -ENODEV;
312759f8b0bfSHans de Goede 		/* FIXME this likely applies to all model3 cams and probably
312859f8b0bfSHans de Goede 		   to other models too. */
312959f8b0bfSHans de Goede 		if (ibm_netcam_pro)
313059f8b0bfSHans de Goede 			desc = &sd_desc_isoc_nego;
313159f8b0bfSHans de Goede 		break;
3132659fefa0SHans de Goede 	}
3133659fefa0SHans de Goede 
313459f8b0bfSHans de Goede 	return gspca_dev_probe2(intf, id, desc, sizeof(struct sd), THIS_MODULE);
31351f33de0fSHans de Goede }
31361f33de0fSHans de Goede 
31371f33de0fSHans de Goede static struct usb_driver sd_driver = {
31381f33de0fSHans de Goede 	.name = MODULE_NAME,
31391f33de0fSHans de Goede 	.id_table = device_table,
31401f33de0fSHans de Goede 	.probe = sd_probe,
31411f33de0fSHans de Goede 	.disconnect = gspca_disconnect,
31421f33de0fSHans de Goede #ifdef CONFIG_PM
31431f33de0fSHans de Goede 	.suspend = gspca_suspend,
31441f33de0fSHans de Goede 	.resume = gspca_resume,
31458bb58964SHans de Goede 	.reset_resume = gspca_resume,
31461f33de0fSHans de Goede #endif
31471f33de0fSHans de Goede };
31481f33de0fSHans de Goede 
3149ecb3b2b3SGreg Kroah-Hartman module_usb_driver(sd_driver);
3150