xref: /linux/drivers/media/usb/gspca/xirlink_cit.c (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
1c942fddfSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
20c0d06caSMauro Carvalho Chehab /*
30c0d06caSMauro Carvalho Chehab  * USB IBM C-It Video Camera driver
40c0d06caSMauro Carvalho Chehab  *
50c0d06caSMauro Carvalho Chehab  * Supports Xirlink C-It Video Camera, IBM PC Camera,
60c0d06caSMauro Carvalho Chehab  * IBM NetCamera and Veo Stingray.
70c0d06caSMauro Carvalho Chehab  *
80c0d06caSMauro Carvalho Chehab  * Copyright (C) 2010 Hans de Goede <hdegoede@redhat.com>
90c0d06caSMauro Carvalho Chehab  *
100c0d06caSMauro Carvalho Chehab  * This driver is based on earlier work of:
110c0d06caSMauro Carvalho Chehab  *
120c0d06caSMauro Carvalho Chehab  * (C) Copyright 1999 Johannes Erdfelt
130c0d06caSMauro Carvalho Chehab  * (C) Copyright 1999 Randy Dunlap
140c0d06caSMauro Carvalho Chehab  */
150c0d06caSMauro Carvalho Chehab 
160c0d06caSMauro Carvalho Chehab #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
170c0d06caSMauro Carvalho Chehab 
180c0d06caSMauro Carvalho Chehab #define MODULE_NAME "xirlink-cit"
190c0d06caSMauro Carvalho Chehab 
200c0d06caSMauro Carvalho Chehab #include <linux/input.h>
210c0d06caSMauro Carvalho Chehab #include "gspca.h"
220c0d06caSMauro Carvalho Chehab 
230c0d06caSMauro Carvalho Chehab MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
240c0d06caSMauro Carvalho Chehab MODULE_DESCRIPTION("Xirlink C-IT");
250c0d06caSMauro Carvalho Chehab MODULE_LICENSE("GPL");
260c0d06caSMauro Carvalho Chehab 
270c0d06caSMauro Carvalho Chehab /* FIXME we should autodetect this */
280c0d06caSMauro Carvalho Chehab static int ibm_netcam_pro;
290c0d06caSMauro Carvalho Chehab module_param(ibm_netcam_pro, int, 0);
300c0d06caSMauro Carvalho Chehab MODULE_PARM_DESC(ibm_netcam_pro,
310c0d06caSMauro Carvalho Chehab 		 "Use IBM Netcamera Pro init sequences for Model 3 cams");
320c0d06caSMauro Carvalho Chehab 
330c0d06caSMauro Carvalho Chehab /* FIXME this should be handled through the V4L2 input selection API */
340c0d06caSMauro Carvalho Chehab static int rca_input;
350c0d06caSMauro Carvalho Chehab module_param(rca_input, int, 0644);
360c0d06caSMauro Carvalho Chehab MODULE_PARM_DESC(rca_input,
370c0d06caSMauro Carvalho Chehab 		 "Use rca input instead of ccd sensor on Model 3 cams");
380c0d06caSMauro Carvalho Chehab 
390c0d06caSMauro Carvalho Chehab /* specific webcam descriptor */
400c0d06caSMauro Carvalho Chehab struct sd {
410c0d06caSMauro Carvalho Chehab 	struct gspca_dev gspca_dev;		/* !! must be the first item */
420c0d06caSMauro Carvalho Chehab 	struct v4l2_ctrl *lighting;
430c0d06caSMauro Carvalho Chehab 	u8 model;
440c0d06caSMauro Carvalho Chehab #define CIT_MODEL0 0 /* bcd version 0.01 cams ie the xvp-500 */
450c0d06caSMauro Carvalho Chehab #define CIT_MODEL1 1 /* The model 1 - 4 nomenclature comes from the old */
460c0d06caSMauro Carvalho Chehab #define CIT_MODEL2 2 /* ibmcam driver */
470c0d06caSMauro Carvalho Chehab #define CIT_MODEL3 3
480c0d06caSMauro Carvalho Chehab #define CIT_MODEL4 4
490c0d06caSMauro Carvalho Chehab #define CIT_IBM_NETCAM_PRO 5
500c0d06caSMauro Carvalho Chehab 	u8 input_index;
510c0d06caSMauro Carvalho Chehab 	u8 button_state;
520c0d06caSMauro Carvalho Chehab 	u8 stop_on_control_change;
530c0d06caSMauro Carvalho Chehab 	u8 sof_read;
540c0d06caSMauro Carvalho Chehab 	u8 sof_len;
550c0d06caSMauro Carvalho Chehab };
560c0d06caSMauro Carvalho Chehab 
570c0d06caSMauro Carvalho Chehab static void sd_stop0(struct gspca_dev *gspca_dev);
580c0d06caSMauro Carvalho Chehab 
590c0d06caSMauro Carvalho Chehab static const struct v4l2_pix_format cif_yuv_mode[] = {
600c0d06caSMauro Carvalho Chehab 	{176, 144, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
610c0d06caSMauro Carvalho Chehab 		.bytesperline = 176,
620c0d06caSMauro Carvalho Chehab 		.sizeimage = 176 * 144 * 3 / 2 + 4,
630c0d06caSMauro Carvalho Chehab 		.colorspace = V4L2_COLORSPACE_SRGB},
640c0d06caSMauro Carvalho Chehab 	{352, 288, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
650c0d06caSMauro Carvalho Chehab 		.bytesperline = 352,
660c0d06caSMauro Carvalho Chehab 		.sizeimage = 352 * 288 * 3 / 2 + 4,
670c0d06caSMauro Carvalho Chehab 		.colorspace = V4L2_COLORSPACE_SRGB},
680c0d06caSMauro Carvalho Chehab };
690c0d06caSMauro Carvalho Chehab 
700c0d06caSMauro Carvalho Chehab static const struct v4l2_pix_format vga_yuv_mode[] = {
710c0d06caSMauro Carvalho Chehab 	{160, 120, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
720c0d06caSMauro Carvalho Chehab 		.bytesperline = 160,
730c0d06caSMauro Carvalho Chehab 		.sizeimage = 160 * 120 * 3 / 2 + 4,
740c0d06caSMauro Carvalho Chehab 		.colorspace = V4L2_COLORSPACE_SRGB},
750c0d06caSMauro Carvalho Chehab 	{320, 240, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
760c0d06caSMauro Carvalho Chehab 		.bytesperline = 320,
770c0d06caSMauro Carvalho Chehab 		.sizeimage = 320 * 240 * 3 / 2 + 4,
780c0d06caSMauro Carvalho Chehab 		.colorspace = V4L2_COLORSPACE_SRGB},
790c0d06caSMauro Carvalho Chehab 	{640, 480, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
800c0d06caSMauro Carvalho Chehab 		.bytesperline = 640,
810c0d06caSMauro Carvalho Chehab 		.sizeimage = 640 * 480 * 3 / 2 + 4,
820c0d06caSMauro Carvalho Chehab 		.colorspace = V4L2_COLORSPACE_SRGB},
830c0d06caSMauro Carvalho Chehab };
840c0d06caSMauro Carvalho Chehab 
850c0d06caSMauro Carvalho Chehab static const struct v4l2_pix_format model0_mode[] = {
860c0d06caSMauro Carvalho Chehab 	{160, 120, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
870c0d06caSMauro Carvalho Chehab 		.bytesperline = 160,
880c0d06caSMauro Carvalho Chehab 		.sizeimage = 160 * 120 * 3 / 2 + 4,
890c0d06caSMauro Carvalho Chehab 		.colorspace = V4L2_COLORSPACE_SRGB},
900c0d06caSMauro Carvalho Chehab 	{176, 144, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
910c0d06caSMauro Carvalho Chehab 		.bytesperline = 176,
920c0d06caSMauro Carvalho Chehab 		.sizeimage = 176 * 144 * 3 / 2 + 4,
930c0d06caSMauro Carvalho Chehab 		.colorspace = V4L2_COLORSPACE_SRGB},
940c0d06caSMauro Carvalho Chehab 	{320, 240, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
950c0d06caSMauro Carvalho Chehab 		.bytesperline = 320,
960c0d06caSMauro Carvalho Chehab 		.sizeimage = 320 * 240 * 3 / 2 + 4,
970c0d06caSMauro Carvalho Chehab 		.colorspace = V4L2_COLORSPACE_SRGB},
980c0d06caSMauro Carvalho Chehab };
990c0d06caSMauro Carvalho Chehab 
1000c0d06caSMauro Carvalho Chehab static const struct v4l2_pix_format model2_mode[] = {
1010c0d06caSMauro Carvalho Chehab 	{160, 120, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
1020c0d06caSMauro Carvalho Chehab 		.bytesperline = 160,
1030c0d06caSMauro Carvalho Chehab 		.sizeimage = 160 * 120 * 3 / 2 + 4,
1040c0d06caSMauro Carvalho Chehab 		.colorspace = V4L2_COLORSPACE_SRGB},
1050c0d06caSMauro Carvalho Chehab 	{176, 144, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
1060c0d06caSMauro Carvalho Chehab 		.bytesperline = 176,
1070c0d06caSMauro Carvalho Chehab 		.sizeimage = 176 * 144 * 3 / 2 + 4,
1080c0d06caSMauro Carvalho Chehab 		.colorspace = V4L2_COLORSPACE_SRGB},
1090c0d06caSMauro Carvalho Chehab 	{320, 240, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
1100c0d06caSMauro Carvalho Chehab 		.bytesperline = 320,
1110c0d06caSMauro Carvalho Chehab 		.sizeimage = 320 * 240 + 4,
1120c0d06caSMauro Carvalho Chehab 		.colorspace = V4L2_COLORSPACE_SRGB},
1130c0d06caSMauro Carvalho Chehab 	{352, 288, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
1140c0d06caSMauro Carvalho Chehab 		.bytesperline = 352,
1150c0d06caSMauro Carvalho Chehab 		.sizeimage = 352 * 288 + 4,
1160c0d06caSMauro Carvalho Chehab 		.colorspace = V4L2_COLORSPACE_SRGB},
1170c0d06caSMauro Carvalho Chehab };
1180c0d06caSMauro Carvalho Chehab 
1190c0d06caSMauro Carvalho Chehab /*
1200c0d06caSMauro Carvalho Chehab  * 01.01.08 - Added for RCA video in support -LO
1210c0d06caSMauro Carvalho Chehab  * This struct is used to init the Model3 cam to use the RCA video in port
1220c0d06caSMauro Carvalho Chehab  * instead of the CCD sensor.
1230c0d06caSMauro Carvalho Chehab  */
1240c0d06caSMauro Carvalho Chehab static const u16 rca_initdata[][3] = {
1250c0d06caSMauro Carvalho Chehab 	{0, 0x0000, 0x010c},
1260c0d06caSMauro Carvalho Chehab 	{0, 0x0006, 0x012c},
1270c0d06caSMauro Carvalho Chehab 	{0, 0x0078, 0x012d},
1280c0d06caSMauro Carvalho Chehab 	{0, 0x0046, 0x012f},
1290c0d06caSMauro Carvalho Chehab 	{0, 0xd141, 0x0124},
1300c0d06caSMauro Carvalho Chehab 	{0, 0x0000, 0x0127},
1310c0d06caSMauro Carvalho Chehab 	{0, 0xfea8, 0x0124},
1320c0d06caSMauro Carvalho Chehab 	{1, 0x0000, 0x0116},
1330c0d06caSMauro Carvalho Chehab 	{0, 0x0064, 0x0116},
1340c0d06caSMauro Carvalho Chehab 	{1, 0x0000, 0x0115},
1350c0d06caSMauro Carvalho Chehab 	{0, 0x0003, 0x0115},
1360c0d06caSMauro Carvalho Chehab 	{0, 0x0008, 0x0123},
1370c0d06caSMauro Carvalho Chehab 	{0, 0x0000, 0x0117},
1380c0d06caSMauro Carvalho Chehab 	{0, 0x0000, 0x0112},
1390c0d06caSMauro Carvalho Chehab 	{0, 0x0080, 0x0100},
1400c0d06caSMauro Carvalho Chehab 	{0, 0x0000, 0x0100},
1410c0d06caSMauro Carvalho Chehab 	{1, 0x0000, 0x0116},
1420c0d06caSMauro Carvalho Chehab 	{0, 0x0060, 0x0116},
1430c0d06caSMauro Carvalho Chehab 	{0, 0x0002, 0x0112},
1440c0d06caSMauro Carvalho Chehab 	{0, 0x0000, 0x0123},
1450c0d06caSMauro Carvalho Chehab 	{0, 0x0001, 0x0117},
1460c0d06caSMauro Carvalho Chehab 	{0, 0x0040, 0x0108},
1470c0d06caSMauro Carvalho Chehab 	{0, 0x0019, 0x012c},
1480c0d06caSMauro Carvalho Chehab 	{0, 0x0040, 0x0116},
1490c0d06caSMauro Carvalho Chehab 	{0, 0x000a, 0x0115},
1500c0d06caSMauro Carvalho Chehab 	{0, 0x000b, 0x0115},
1510c0d06caSMauro Carvalho Chehab 	{0, 0x0078, 0x012d},
1520c0d06caSMauro Carvalho Chehab 	{0, 0x0046, 0x012f},
1530c0d06caSMauro Carvalho Chehab 	{0, 0xd141, 0x0124},
1540c0d06caSMauro Carvalho Chehab 	{0, 0x0000, 0x0127},
1550c0d06caSMauro Carvalho Chehab 	{0, 0xfea8, 0x0124},
1560c0d06caSMauro Carvalho Chehab 	{0, 0x0064, 0x0116},
1570c0d06caSMauro Carvalho Chehab 	{0, 0x0000, 0x0115},
1580c0d06caSMauro Carvalho Chehab 	{0, 0x0001, 0x0115},
1590c0d06caSMauro Carvalho Chehab 	{0, 0xffff, 0x0124},
1600c0d06caSMauro Carvalho Chehab 	{0, 0xfff9, 0x0124},
1610c0d06caSMauro Carvalho Chehab 	{0, 0x0086, 0x0127},
1620c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
1630c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
1640c0d06caSMauro Carvalho Chehab 	{0, 0x00aa, 0x0127},
1650c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
1660c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
1670c0d06caSMauro Carvalho Chehab 	{0, 0x0000, 0x0127},
1680c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
1690c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
1700c0d06caSMauro Carvalho Chehab 	{0, 0xfffa, 0x0124},
1710c0d06caSMauro Carvalho Chehab 	{0, 0xffff, 0x0124},
1720c0d06caSMauro Carvalho Chehab 	{0, 0xfff9, 0x0124},
1730c0d06caSMauro Carvalho Chehab 	{0, 0x0086, 0x0127},
1740c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
1750c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
1760c0d06caSMauro Carvalho Chehab 	{0, 0x00f2, 0x0127},
1770c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
1780c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
1790c0d06caSMauro Carvalho Chehab 	{0, 0x000f, 0x0127},
1800c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
1810c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
1820c0d06caSMauro Carvalho Chehab 	{0, 0xfffa, 0x0124},
1830c0d06caSMauro Carvalho Chehab 	{0, 0xffff, 0x0124},
1840c0d06caSMauro Carvalho Chehab 	{0, 0xfff9, 0x0124},
1850c0d06caSMauro Carvalho Chehab 	{0, 0x0086, 0x0127},
1860c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
1870c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
1880c0d06caSMauro Carvalho Chehab 	{0, 0x00f8, 0x0127},
1890c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
1900c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
1910c0d06caSMauro Carvalho Chehab 	{0, 0x00fc, 0x0127},
1920c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
1930c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
1940c0d06caSMauro Carvalho Chehab 	{0, 0xfffa, 0x0124},
1950c0d06caSMauro Carvalho Chehab 	{0, 0xffff, 0x0124},
1960c0d06caSMauro Carvalho Chehab 	{0, 0xfff9, 0x0124},
1970c0d06caSMauro Carvalho Chehab 	{0, 0x0086, 0x0127},
1980c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
1990c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
2000c0d06caSMauro Carvalho Chehab 	{0, 0x00f9, 0x0127},
2010c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
2020c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
2030c0d06caSMauro Carvalho Chehab 	{0, 0x003c, 0x0127},
2040c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
2050c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
2060c0d06caSMauro Carvalho Chehab 	{0, 0xfffa, 0x0124},
2070c0d06caSMauro Carvalho Chehab 	{0, 0xffff, 0x0124},
2080c0d06caSMauro Carvalho Chehab 	{0, 0xfff9, 0x0124},
2090c0d06caSMauro Carvalho Chehab 	{0, 0x0086, 0x0127},
2100c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
2110c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
2120c0d06caSMauro Carvalho Chehab 	{0, 0x0027, 0x0127},
2130c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
2140c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
2150c0d06caSMauro Carvalho Chehab 	{0, 0x0019, 0x0127},
2160c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
2170c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
2180c0d06caSMauro Carvalho Chehab 	{0, 0xfffa, 0x0124},
2190c0d06caSMauro Carvalho Chehab 	{0, 0xfff9, 0x0124},
2200c0d06caSMauro Carvalho Chehab 	{0, 0x0086, 0x0127},
2210c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
2220c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
2230c0d06caSMauro Carvalho Chehab 	{0, 0x0037, 0x0127},
2240c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
2250c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
2260c0d06caSMauro Carvalho Chehab 	{0, 0x0000, 0x0127},
2270c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
2280c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
2290c0d06caSMauro Carvalho Chehab 	{0, 0x0021, 0x0127},
2300c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
2310c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
2320c0d06caSMauro Carvalho Chehab 	{0, 0xfffa, 0x0124},
2330c0d06caSMauro Carvalho Chehab 	{0, 0xfff9, 0x0124},
2340c0d06caSMauro Carvalho Chehab 	{0, 0x0086, 0x0127},
2350c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
2360c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
2370c0d06caSMauro Carvalho Chehab 	{0, 0x0038, 0x0127},
2380c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
2390c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
2400c0d06caSMauro Carvalho Chehab 	{0, 0x0006, 0x0127},
2410c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
2420c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
2430c0d06caSMauro Carvalho Chehab 	{0, 0x0045, 0x0127},
2440c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
2450c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
2460c0d06caSMauro Carvalho Chehab 	{0, 0xfffa, 0x0124},
2470c0d06caSMauro Carvalho Chehab 	{0, 0xfff9, 0x0124},
2480c0d06caSMauro Carvalho Chehab 	{0, 0x0086, 0x0127},
2490c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
2500c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
2510c0d06caSMauro Carvalho Chehab 	{0, 0x0037, 0x0127},
2520c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
2530c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
2540c0d06caSMauro Carvalho Chehab 	{0, 0x0001, 0x0127},
2550c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
2560c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
2570c0d06caSMauro Carvalho Chehab 	{0, 0x002a, 0x0127},
2580c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
2590c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
2600c0d06caSMauro Carvalho Chehab 	{0, 0xfffa, 0x0124},
2610c0d06caSMauro Carvalho Chehab 	{0, 0xfff9, 0x0124},
2620c0d06caSMauro Carvalho Chehab 	{0, 0x0086, 0x0127},
2630c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
2640c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
2650c0d06caSMauro Carvalho Chehab 	{0, 0x0038, 0x0127},
2660c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
2670c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
2680c0d06caSMauro Carvalho Chehab 	{0, 0x0000, 0x0127},
2690c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
2700c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
2710c0d06caSMauro Carvalho Chehab 	{0, 0x000e, 0x0127},
2720c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
2730c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
2740c0d06caSMauro Carvalho Chehab 	{0, 0xfffa, 0x0124},
2750c0d06caSMauro Carvalho Chehab 	{0, 0xfff9, 0x0124},
2760c0d06caSMauro Carvalho Chehab 	{0, 0x0086, 0x0127},
2770c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
2780c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
2790c0d06caSMauro Carvalho Chehab 	{0, 0x0037, 0x0127},
2800c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
2810c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
2820c0d06caSMauro Carvalho Chehab 	{0, 0x0001, 0x0127},
2830c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
2840c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
2850c0d06caSMauro Carvalho Chehab 	{0, 0x002b, 0x0127},
2860c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
2870c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
2880c0d06caSMauro Carvalho Chehab 	{0, 0xfffa, 0x0124},
2890c0d06caSMauro Carvalho Chehab 	{0, 0xfff9, 0x0124},
2900c0d06caSMauro Carvalho Chehab 	{0, 0x0086, 0x0127},
2910c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
2920c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
2930c0d06caSMauro Carvalho Chehab 	{0, 0x0038, 0x0127},
2940c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
2950c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
2960c0d06caSMauro Carvalho Chehab 	{0, 0x0001, 0x0127},
2970c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
2980c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
2990c0d06caSMauro Carvalho Chehab 	{0, 0x00f4, 0x0127},
3000c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
3010c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
3020c0d06caSMauro Carvalho Chehab 	{0, 0xfffa, 0x0124},
3030c0d06caSMauro Carvalho Chehab 	{0, 0xfff9, 0x0124},
3040c0d06caSMauro Carvalho Chehab 	{0, 0x0086, 0x0127},
3050c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
3060c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
3070c0d06caSMauro Carvalho Chehab 	{0, 0x0037, 0x0127},
3080c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
3090c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
3100c0d06caSMauro Carvalho Chehab 	{0, 0x0001, 0x0127},
3110c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
3120c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
3130c0d06caSMauro Carvalho Chehab 	{0, 0x002c, 0x0127},
3140c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
3150c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
3160c0d06caSMauro Carvalho Chehab 	{0, 0xfffa, 0x0124},
3170c0d06caSMauro Carvalho Chehab 	{0, 0xfff9, 0x0124},
3180c0d06caSMauro Carvalho Chehab 	{0, 0x0086, 0x0127},
3190c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
3200c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
3210c0d06caSMauro Carvalho Chehab 	{0, 0x0038, 0x0127},
3220c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
3230c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
3240c0d06caSMauro Carvalho Chehab 	{0, 0x0001, 0x0127},
3250c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
3260c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
3270c0d06caSMauro Carvalho Chehab 	{0, 0x0004, 0x0127},
3280c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
3290c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
3300c0d06caSMauro Carvalho Chehab 	{0, 0xfffa, 0x0124},
3310c0d06caSMauro Carvalho Chehab 	{0, 0xfff9, 0x0124},
3320c0d06caSMauro Carvalho Chehab 	{0, 0x0086, 0x0127},
3330c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
3340c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
3350c0d06caSMauro Carvalho Chehab 	{0, 0x0037, 0x0127},
3360c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
3370c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
3380c0d06caSMauro Carvalho Chehab 	{0, 0x0001, 0x0127},
3390c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
3400c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
3410c0d06caSMauro Carvalho Chehab 	{0, 0x002d, 0x0127},
3420c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
3430c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
3440c0d06caSMauro Carvalho Chehab 	{0, 0xfffa, 0x0124},
3450c0d06caSMauro Carvalho Chehab 	{0, 0xfff9, 0x0124},
3460c0d06caSMauro Carvalho Chehab 	{0, 0x0086, 0x0127},
3470c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
3480c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
3490c0d06caSMauro Carvalho Chehab 	{0, 0x0038, 0x0127},
3500c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
3510c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
3520c0d06caSMauro Carvalho Chehab 	{0, 0x0000, 0x0127},
3530c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
3540c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
3550c0d06caSMauro Carvalho Chehab 	{0, 0x0014, 0x0127},
3560c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
3570c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
3580c0d06caSMauro Carvalho Chehab 	{0, 0xfffa, 0x0124},
3590c0d06caSMauro Carvalho Chehab 	{0, 0xfff9, 0x0124},
3600c0d06caSMauro Carvalho Chehab 	{0, 0x0086, 0x0127},
3610c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
3620c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
3630c0d06caSMauro Carvalho Chehab 	{0, 0x0037, 0x0127},
3640c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
3650c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
3660c0d06caSMauro Carvalho Chehab 	{0, 0x0001, 0x0127},
3670c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
3680c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
3690c0d06caSMauro Carvalho Chehab 	{0, 0x002e, 0x0127},
3700c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
3710c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
3720c0d06caSMauro Carvalho Chehab 	{0, 0xfffa, 0x0124},
3730c0d06caSMauro Carvalho Chehab 	{0, 0xfff9, 0x0124},
3740c0d06caSMauro Carvalho Chehab 	{0, 0x0086, 0x0127},
3750c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
3760c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
3770c0d06caSMauro Carvalho Chehab 	{0, 0x0038, 0x0127},
3780c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
3790c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
3800c0d06caSMauro Carvalho Chehab 	{0, 0x0003, 0x0127},
3810c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
3820c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
3830c0d06caSMauro Carvalho Chehab 	{0, 0x0000, 0x0127},
3840c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
3850c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
3860c0d06caSMauro Carvalho Chehab 	{0, 0xfffa, 0x0124},
3870c0d06caSMauro Carvalho Chehab 	{0, 0xfff9, 0x0124},
3880c0d06caSMauro Carvalho Chehab 	{0, 0x0086, 0x0127},
3890c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
3900c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
3910c0d06caSMauro Carvalho Chehab 	{0, 0x0037, 0x0127},
3920c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
3930c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
3940c0d06caSMauro Carvalho Chehab 	{0, 0x0001, 0x0127},
3950c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
3960c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
3970c0d06caSMauro Carvalho Chehab 	{0, 0x002f, 0x0127},
3980c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
3990c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
4000c0d06caSMauro Carvalho Chehab 	{0, 0xfffa, 0x0124},
4010c0d06caSMauro Carvalho Chehab 	{0, 0xfff9, 0x0124},
4020c0d06caSMauro Carvalho Chehab 	{0, 0x0086, 0x0127},
4030c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
4040c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
4050c0d06caSMauro Carvalho Chehab 	{0, 0x0038, 0x0127},
4060c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
4070c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
4080c0d06caSMauro Carvalho Chehab 	{0, 0x0003, 0x0127},
4090c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
4100c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
4110c0d06caSMauro Carvalho Chehab 	{0, 0x0014, 0x0127},
4120c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
4130c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
4140c0d06caSMauro Carvalho Chehab 	{0, 0xfffa, 0x0124},
4150c0d06caSMauro Carvalho Chehab 	{0, 0xfff9, 0x0124},
4160c0d06caSMauro Carvalho Chehab 	{0, 0x0086, 0x0127},
4170c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
4180c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
4190c0d06caSMauro Carvalho Chehab 	{0, 0x0037, 0x0127},
4200c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
4210c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
4220c0d06caSMauro Carvalho Chehab 	{0, 0x0001, 0x0127},
4230c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
4240c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
4250c0d06caSMauro Carvalho Chehab 	{0, 0x0040, 0x0127},
4260c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
4270c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
4280c0d06caSMauro Carvalho Chehab 	{0, 0xfffa, 0x0124},
4290c0d06caSMauro Carvalho Chehab 	{0, 0xfff9, 0x0124},
4300c0d06caSMauro Carvalho Chehab 	{0, 0x0086, 0x0127},
4310c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
4320c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
4330c0d06caSMauro Carvalho Chehab 	{0, 0x0038, 0x0127},
4340c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
4350c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
4360c0d06caSMauro Carvalho Chehab 	{0, 0x0000, 0x0127},
4370c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
4380c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
4390c0d06caSMauro Carvalho Chehab 	{0, 0x0040, 0x0127},
4400c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
4410c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
4420c0d06caSMauro Carvalho Chehab 	{0, 0xfffa, 0x0124},
4430c0d06caSMauro Carvalho Chehab 	{0, 0xfff9, 0x0124},
4440c0d06caSMauro Carvalho Chehab 	{0, 0x0086, 0x0127},
4450c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
4460c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
4470c0d06caSMauro Carvalho Chehab 	{0, 0x0037, 0x0127},
4480c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
4490c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
4500c0d06caSMauro Carvalho Chehab 	{0, 0x0001, 0x0127},
4510c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
4520c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
4530c0d06caSMauro Carvalho Chehab 	{0, 0x0053, 0x0127},
4540c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
4550c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
4560c0d06caSMauro Carvalho Chehab 	{0, 0xfffa, 0x0124},
4570c0d06caSMauro Carvalho Chehab 	{0, 0xfff9, 0x0124},
4580c0d06caSMauro Carvalho Chehab 	{0, 0x0086, 0x0127},
4590c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
4600c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
4610c0d06caSMauro Carvalho Chehab 	{0, 0x0038, 0x0127},
4620c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
4630c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
4640c0d06caSMauro Carvalho Chehab 	{0, 0x0000, 0x0127},
4650c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
4660c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
4670c0d06caSMauro Carvalho Chehab 	{0, 0x0038, 0x0127},
4680c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
4690c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
4700c0d06caSMauro Carvalho Chehab 	{0, 0xfffa, 0x0124},
4710c0d06caSMauro Carvalho Chehab 	{0, 0x0000, 0x0101},
4720c0d06caSMauro Carvalho Chehab 	{0, 0x00a0, 0x0103},
4730c0d06caSMauro Carvalho Chehab 	{0, 0x0078, 0x0105},
4740c0d06caSMauro Carvalho Chehab 	{0, 0x0000, 0x010a},
4750c0d06caSMauro Carvalho Chehab 	{0, 0x0024, 0x010b},
4760c0d06caSMauro Carvalho Chehab 	{0, 0x0028, 0x0119},
4770c0d06caSMauro Carvalho Chehab 	{0, 0x0088, 0x011b},
4780c0d06caSMauro Carvalho Chehab 	{0, 0x0002, 0x011d},
4790c0d06caSMauro Carvalho Chehab 	{0, 0x0003, 0x011e},
4800c0d06caSMauro Carvalho Chehab 	{0, 0x0000, 0x0129},
4810c0d06caSMauro Carvalho Chehab 	{0, 0x00fc, 0x012b},
4820c0d06caSMauro Carvalho Chehab 	{0, 0x0008, 0x0102},
4830c0d06caSMauro Carvalho Chehab 	{0, 0x0000, 0x0104},
4840c0d06caSMauro Carvalho Chehab 	{0, 0x0008, 0x011a},
4850c0d06caSMauro Carvalho Chehab 	{0, 0x0028, 0x011c},
4860c0d06caSMauro Carvalho Chehab 	{0, 0x0021, 0x012a},
4870c0d06caSMauro Carvalho Chehab 	{0, 0x0000, 0x0118},
4880c0d06caSMauro Carvalho Chehab 	{0, 0x0000, 0x0132},
4890c0d06caSMauro Carvalho Chehab 	{0, 0x0000, 0x0109},
4900c0d06caSMauro Carvalho Chehab 	{0, 0xfff9, 0x0124},
4910c0d06caSMauro Carvalho Chehab 	{0, 0x0086, 0x0127},
4920c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
4930c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
4940c0d06caSMauro Carvalho Chehab 	{0, 0x0037, 0x0127},
4950c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
4960c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
4970c0d06caSMauro Carvalho Chehab 	{0, 0x0001, 0x0127},
4980c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
4990c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
5000c0d06caSMauro Carvalho Chehab 	{0, 0x0031, 0x0127},
5010c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
5020c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
5030c0d06caSMauro Carvalho Chehab 	{0, 0xfffa, 0x0124},
5040c0d06caSMauro Carvalho Chehab 	{0, 0xfff9, 0x0124},
5050c0d06caSMauro Carvalho Chehab 	{0, 0x0086, 0x0127},
5060c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
5070c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
5080c0d06caSMauro Carvalho Chehab 	{0, 0x0038, 0x0127},
5090c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
5100c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
5110c0d06caSMauro Carvalho Chehab 	{0, 0x0000, 0x0127},
5120c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
5130c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
5140c0d06caSMauro Carvalho Chehab 	{0, 0x0000, 0x0127},
5150c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
5160c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
5170c0d06caSMauro Carvalho Chehab 	{0, 0xfffa, 0x0124},
5180c0d06caSMauro Carvalho Chehab 	{0, 0xfff9, 0x0124},
5190c0d06caSMauro Carvalho Chehab 	{0, 0x0086, 0x0127},
5200c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
5210c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
5220c0d06caSMauro Carvalho Chehab 	{0, 0x0037, 0x0127},
5230c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
5240c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
5250c0d06caSMauro Carvalho Chehab 	{0, 0x0001, 0x0127},
5260c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
5270c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
5280c0d06caSMauro Carvalho Chehab 	{0, 0x0040, 0x0127},
5290c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
5300c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
5310c0d06caSMauro Carvalho Chehab 	{0, 0xfffa, 0x0124},
5320c0d06caSMauro Carvalho Chehab 	{0, 0xfff9, 0x0124},
5330c0d06caSMauro Carvalho Chehab 	{0, 0x0086, 0x0127},
5340c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
5350c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
5360c0d06caSMauro Carvalho Chehab 	{0, 0x0038, 0x0127},
5370c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
5380c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
5390c0d06caSMauro Carvalho Chehab 	{0, 0x0000, 0x0127},
5400c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
5410c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
5420c0d06caSMauro Carvalho Chehab 	{0, 0x0040, 0x0127},
5430c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
5440c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
5450c0d06caSMauro Carvalho Chehab 	{0, 0xfffa, 0x0124},
5460c0d06caSMauro Carvalho Chehab 	{0, 0xfff9, 0x0124},
5470c0d06caSMauro Carvalho Chehab 	{0, 0x0086, 0x0127},
5480c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
5490c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
5500c0d06caSMauro Carvalho Chehab 	{0, 0x0037, 0x0127},
5510c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
5520c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
5530c0d06caSMauro Carvalho Chehab 	{0, 0x0000, 0x0127},
5540c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
5550c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
5560c0d06caSMauro Carvalho Chehab 	{0, 0x00dc, 0x0127},
5570c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
5580c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
5590c0d06caSMauro Carvalho Chehab 	{0, 0xfffa, 0x0124},
5600c0d06caSMauro Carvalho Chehab 	{0, 0xfff9, 0x0124},
5610c0d06caSMauro Carvalho Chehab 	{0, 0x0086, 0x0127},
5620c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
5630c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
5640c0d06caSMauro Carvalho Chehab 	{0, 0x0038, 0x0127},
5650c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
5660c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
5670c0d06caSMauro Carvalho Chehab 	{0, 0x0000, 0x0127},
5680c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
5690c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
5700c0d06caSMauro Carvalho Chehab 	{0, 0x0000, 0x0127},
5710c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
5720c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
5730c0d06caSMauro Carvalho Chehab 	{0, 0xfffa, 0x0124},
5740c0d06caSMauro Carvalho Chehab 	{0, 0xfff9, 0x0124},
5750c0d06caSMauro Carvalho Chehab 	{0, 0x0086, 0x0127},
5760c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
5770c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
5780c0d06caSMauro Carvalho Chehab 	{0, 0x0037, 0x0127},
5790c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
5800c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
5810c0d06caSMauro Carvalho Chehab 	{0, 0x0001, 0x0127},
5820c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
5830c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
5840c0d06caSMauro Carvalho Chehab 	{0, 0x0032, 0x0127},
5850c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
5860c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
5870c0d06caSMauro Carvalho Chehab 	{0, 0xfffa, 0x0124},
5880c0d06caSMauro Carvalho Chehab 	{0, 0xfff9, 0x0124},
5890c0d06caSMauro Carvalho Chehab 	{0, 0x0086, 0x0127},
5900c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
5910c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
5920c0d06caSMauro Carvalho Chehab 	{0, 0x0038, 0x0127},
5930c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
5940c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
5950c0d06caSMauro Carvalho Chehab 	{0, 0x0001, 0x0127},
5960c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
5970c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
5980c0d06caSMauro Carvalho Chehab 	{0, 0x0020, 0x0127},
5990c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
6000c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
6010c0d06caSMauro Carvalho Chehab 	{0, 0xfffa, 0x0124},
6020c0d06caSMauro Carvalho Chehab 	{0, 0xfff9, 0x0124},
6030c0d06caSMauro Carvalho Chehab 	{0, 0x0086, 0x0127},
6040c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
6050c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
6060c0d06caSMauro Carvalho Chehab 	{0, 0x0037, 0x0127},
6070c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
6080c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
6090c0d06caSMauro Carvalho Chehab 	{0, 0x0001, 0x0127},
6100c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
6110c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
6120c0d06caSMauro Carvalho Chehab 	{0, 0x0040, 0x0127},
6130c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
6140c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
6150c0d06caSMauro Carvalho Chehab 	{0, 0xfffa, 0x0124},
6160c0d06caSMauro Carvalho Chehab 	{0, 0xfff9, 0x0124},
6170c0d06caSMauro Carvalho Chehab 	{0, 0x0086, 0x0127},
6180c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
6190c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
6200c0d06caSMauro Carvalho Chehab 	{0, 0x0038, 0x0127},
6210c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
6220c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
6230c0d06caSMauro Carvalho Chehab 	{0, 0x0000, 0x0127},
6240c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
6250c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
6260c0d06caSMauro Carvalho Chehab 	{0, 0x0040, 0x0127},
6270c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
6280c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
6290c0d06caSMauro Carvalho Chehab 	{0, 0xfffa, 0x0124},
6300c0d06caSMauro Carvalho Chehab 	{0, 0xfff9, 0x0124},
6310c0d06caSMauro Carvalho Chehab 	{0, 0x0086, 0x0127},
6320c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
6330c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
6340c0d06caSMauro Carvalho Chehab 	{0, 0x0037, 0x0127},
6350c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
6360c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
6370c0d06caSMauro Carvalho Chehab 	{0, 0x0000, 0x0127},
6380c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
6390c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
6400c0d06caSMauro Carvalho Chehab 	{0, 0x0030, 0x0127},
6410c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
6420c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
6430c0d06caSMauro Carvalho Chehab 	{0, 0xfffa, 0x0124},
6440c0d06caSMauro Carvalho Chehab 	{0, 0xfff9, 0x0124},
6450c0d06caSMauro Carvalho Chehab 	{0, 0x0086, 0x0127},
6460c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
6470c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
6480c0d06caSMauro Carvalho Chehab 	{0, 0x0038, 0x0127},
6490c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
6500c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
6510c0d06caSMauro Carvalho Chehab 	{0, 0x0008, 0x0127},
6520c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
6530c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
6540c0d06caSMauro Carvalho Chehab 	{0, 0x0000, 0x0127},
6550c0d06caSMauro Carvalho Chehab 	{0, 0xfff8, 0x0124},
6560c0d06caSMauro Carvalho Chehab 	{0, 0xfffd, 0x0124},
6570c0d06caSMauro Carvalho Chehab 	{0, 0xfffa, 0x0124},
6580c0d06caSMauro Carvalho Chehab 	{0, 0x0003, 0x0111},
6590c0d06caSMauro Carvalho Chehab };
6600c0d06caSMauro Carvalho Chehab 
6610c0d06caSMauro Carvalho Chehab /* TESTME the old ibmcam driver repeats certain commands to Model1 cameras, we
6620c0d06caSMauro Carvalho Chehab    do the same for now (testing needed to see if this is really necessary) */
6630c0d06caSMauro Carvalho Chehab static const int cit_model1_ntries = 5;
6640c0d06caSMauro Carvalho Chehab static const int cit_model1_ntries2 = 2;
6650c0d06caSMauro Carvalho Chehab 
cit_write_reg(struct gspca_dev * gspca_dev,u16 value,u16 index)6660c0d06caSMauro Carvalho Chehab static int cit_write_reg(struct gspca_dev *gspca_dev, u16 value, u16 index)
6670c0d06caSMauro Carvalho Chehab {
6680c0d06caSMauro Carvalho Chehab 	struct usb_device *udev = gspca_dev->dev;
6690c0d06caSMauro Carvalho Chehab 	int err;
6700c0d06caSMauro Carvalho Chehab 
6710c0d06caSMauro Carvalho Chehab 	err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00,
6720c0d06caSMauro Carvalho Chehab 			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT,
6730c0d06caSMauro Carvalho Chehab 			value, index, NULL, 0, 1000);
6740c0d06caSMauro Carvalho Chehab 	if (err < 0)
6750c0d06caSMauro Carvalho Chehab 		pr_err("Failed to write a register (index 0x%04X, value 0x%02X, error %d)\n",
6760c0d06caSMauro Carvalho Chehab 		       index, value, err);
6770c0d06caSMauro Carvalho Chehab 
6780c0d06caSMauro Carvalho Chehab 	return 0;
6790c0d06caSMauro Carvalho Chehab }
6800c0d06caSMauro Carvalho Chehab 
cit_read_reg(struct gspca_dev * gspca_dev,u16 index,int verbose)6810c0d06caSMauro Carvalho Chehab static int cit_read_reg(struct gspca_dev *gspca_dev, u16 index, int verbose)
6820c0d06caSMauro Carvalho Chehab {
6830c0d06caSMauro Carvalho Chehab 	struct usb_device *udev = gspca_dev->dev;
6840c0d06caSMauro Carvalho Chehab 	__u8 *buf = gspca_dev->usb_buf;
6850c0d06caSMauro Carvalho Chehab 	int res;
6860c0d06caSMauro Carvalho Chehab 
6870c0d06caSMauro Carvalho Chehab 	res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x01,
6880c0d06caSMauro Carvalho Chehab 			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT,
6890c0d06caSMauro Carvalho Chehab 			0x00, index, buf, 8, 1000);
6900c0d06caSMauro Carvalho Chehab 	if (res < 0) {
6910c0d06caSMauro Carvalho Chehab 		pr_err("Failed to read a register (index 0x%04X, error %d)\n",
6920c0d06caSMauro Carvalho Chehab 		       index, res);
6930c0d06caSMauro Carvalho Chehab 		return res;
6940c0d06caSMauro Carvalho Chehab 	}
6950c0d06caSMauro Carvalho Chehab 
6960c0d06caSMauro Carvalho Chehab 	if (verbose)
69737d5efb0SJoe Perches 		gspca_dbg(gspca_dev, D_PROBE, "Register %04x value: %02x\n",
69837d5efb0SJoe Perches 			  index, buf[0]);
6990c0d06caSMauro Carvalho Chehab 
7000c0d06caSMauro Carvalho Chehab 	return 0;
7010c0d06caSMauro Carvalho Chehab }
7020c0d06caSMauro Carvalho Chehab 
7030c0d06caSMauro Carvalho Chehab /*
7040c0d06caSMauro Carvalho Chehab  * cit_send_FF_04_02()
7050c0d06caSMauro Carvalho Chehab  *
7060c0d06caSMauro Carvalho Chehab  * This procedure sends magic 3-command prefix to the camera.
7070c0d06caSMauro Carvalho Chehab  * The purpose of this prefix is not known.
7080c0d06caSMauro Carvalho Chehab  *
7090c0d06caSMauro Carvalho Chehab  * History:
7100c0d06caSMauro Carvalho Chehab  * 1/2/00   Created.
7110c0d06caSMauro Carvalho Chehab  */
cit_send_FF_04_02(struct gspca_dev * gspca_dev)7120c0d06caSMauro Carvalho Chehab static void cit_send_FF_04_02(struct gspca_dev *gspca_dev)
7130c0d06caSMauro Carvalho Chehab {
7140c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x00FF, 0x0127);
7150c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0004, 0x0124);
7160c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0002, 0x0124);
7170c0d06caSMauro Carvalho Chehab }
7180c0d06caSMauro Carvalho Chehab 
cit_send_00_04_06(struct gspca_dev * gspca_dev)7190c0d06caSMauro Carvalho Chehab static void cit_send_00_04_06(struct gspca_dev *gspca_dev)
7200c0d06caSMauro Carvalho Chehab {
7210c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0000, 0x0127);
7220c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0004, 0x0124);
7230c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0006, 0x0124);
7240c0d06caSMauro Carvalho Chehab }
7250c0d06caSMauro Carvalho Chehab 
cit_send_x_00(struct gspca_dev * gspca_dev,unsigned short x)7260c0d06caSMauro Carvalho Chehab static void cit_send_x_00(struct gspca_dev *gspca_dev, unsigned short x)
7270c0d06caSMauro Carvalho Chehab {
7280c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, x,      0x0127);
7290c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0000, 0x0124);
7300c0d06caSMauro Carvalho Chehab }
7310c0d06caSMauro Carvalho Chehab 
cit_send_x_00_05(struct gspca_dev * gspca_dev,unsigned short x)7320c0d06caSMauro Carvalho Chehab static void cit_send_x_00_05(struct gspca_dev *gspca_dev, unsigned short x)
7330c0d06caSMauro Carvalho Chehab {
7340c0d06caSMauro Carvalho Chehab 	cit_send_x_00(gspca_dev, x);
7350c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0005, 0x0124);
7360c0d06caSMauro Carvalho Chehab }
7370c0d06caSMauro Carvalho Chehab 
cit_send_x_00_05_02(struct gspca_dev * gspca_dev,unsigned short x)7380c0d06caSMauro Carvalho Chehab static void cit_send_x_00_05_02(struct gspca_dev *gspca_dev, unsigned short x)
7390c0d06caSMauro Carvalho Chehab {
7400c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, x,      0x0127);
7410c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0000, 0x0124);
7420c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0005, 0x0124);
7430c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0002, 0x0124);
7440c0d06caSMauro Carvalho Chehab }
7450c0d06caSMauro Carvalho Chehab 
cit_send_x_01_00_05(struct gspca_dev * gspca_dev,u16 x)7460c0d06caSMauro Carvalho Chehab static void cit_send_x_01_00_05(struct gspca_dev *gspca_dev, u16 x)
7470c0d06caSMauro Carvalho Chehab {
7480c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, x,      0x0127);
7490c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0001, 0x0124);
7500c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0000, 0x0124);
7510c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0005, 0x0124);
7520c0d06caSMauro Carvalho Chehab }
7530c0d06caSMauro Carvalho Chehab 
cit_send_x_00_05_02_01(struct gspca_dev * gspca_dev,u16 x)7540c0d06caSMauro Carvalho Chehab static void cit_send_x_00_05_02_01(struct gspca_dev *gspca_dev, u16 x)
7550c0d06caSMauro Carvalho Chehab {
7560c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, x,      0x0127);
7570c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0000, 0x0124);
7580c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0005, 0x0124);
7590c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0002, 0x0124);
7600c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0001, 0x0124);
7610c0d06caSMauro Carvalho Chehab }
7620c0d06caSMauro Carvalho Chehab 
cit_send_x_00_05_02_08_01(struct gspca_dev * gspca_dev,u16 x)7630c0d06caSMauro Carvalho Chehab static void cit_send_x_00_05_02_08_01(struct gspca_dev *gspca_dev, u16 x)
7640c0d06caSMauro Carvalho Chehab {
7650c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, x,      0x0127);
7660c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0000, 0x0124);
7670c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0005, 0x0124);
7680c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0002, 0x0124);
7690c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0008, 0x0124);
7700c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0001, 0x0124);
7710c0d06caSMauro Carvalho Chehab }
7720c0d06caSMauro Carvalho Chehab 
cit_Packet_Format1(struct gspca_dev * gspca_dev,u16 fkey,u16 val)7730c0d06caSMauro Carvalho Chehab static void cit_Packet_Format1(struct gspca_dev *gspca_dev, u16 fkey, u16 val)
7740c0d06caSMauro Carvalho Chehab {
7750c0d06caSMauro Carvalho Chehab 	cit_send_x_01_00_05(gspca_dev, 0x0088);
7760c0d06caSMauro Carvalho Chehab 	cit_send_x_00_05(gspca_dev, fkey);
7770c0d06caSMauro Carvalho Chehab 	cit_send_x_00_05_02_08_01(gspca_dev, val);
7780c0d06caSMauro Carvalho Chehab 	cit_send_x_00_05(gspca_dev, 0x0088);
7790c0d06caSMauro Carvalho Chehab 	cit_send_x_00_05_02_01(gspca_dev, fkey);
7800c0d06caSMauro Carvalho Chehab 	cit_send_x_00_05(gspca_dev, 0x0089);
7810c0d06caSMauro Carvalho Chehab 	cit_send_x_00(gspca_dev, fkey);
7820c0d06caSMauro Carvalho Chehab 	cit_send_00_04_06(gspca_dev);
7830c0d06caSMauro Carvalho Chehab 	cit_read_reg(gspca_dev, 0x0126, 0);
7840c0d06caSMauro Carvalho Chehab 	cit_send_FF_04_02(gspca_dev);
7850c0d06caSMauro Carvalho Chehab }
7860c0d06caSMauro Carvalho Chehab 
cit_PacketFormat2(struct gspca_dev * gspca_dev,u16 fkey,u16 val)7870c0d06caSMauro Carvalho Chehab static void cit_PacketFormat2(struct gspca_dev *gspca_dev, u16 fkey, u16 val)
7880c0d06caSMauro Carvalho Chehab {
7890c0d06caSMauro Carvalho Chehab 	cit_send_x_01_00_05(gspca_dev, 0x0088);
7900c0d06caSMauro Carvalho Chehab 	cit_send_x_00_05(gspca_dev, fkey);
7910c0d06caSMauro Carvalho Chehab 	cit_send_x_00_05_02(gspca_dev, val);
7920c0d06caSMauro Carvalho Chehab }
7930c0d06caSMauro Carvalho Chehab 
cit_model2_Packet2(struct gspca_dev * gspca_dev)7940c0d06caSMauro Carvalho Chehab static void cit_model2_Packet2(struct gspca_dev *gspca_dev)
7950c0d06caSMauro Carvalho Chehab {
7960c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x00ff, 0x012d);
7970c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0xfea3, 0x0124);
7980c0d06caSMauro Carvalho Chehab }
7990c0d06caSMauro Carvalho Chehab 
cit_model2_Packet1(struct gspca_dev * gspca_dev,u16 v1,u16 v2)8000c0d06caSMauro Carvalho Chehab static void cit_model2_Packet1(struct gspca_dev *gspca_dev, u16 v1, u16 v2)
8010c0d06caSMauro Carvalho Chehab {
8020c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x00aa, 0x012d);
8030c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x00ff, 0x012e);
8040c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, v1,     0x012f);
8050c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x00ff, 0x0130);
8060c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0xc719, 0x0124);
8070c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, v2,     0x0127);
8080c0d06caSMauro Carvalho Chehab 
8090c0d06caSMauro Carvalho Chehab 	cit_model2_Packet2(gspca_dev);
8100c0d06caSMauro Carvalho Chehab }
8110c0d06caSMauro Carvalho Chehab 
8120c0d06caSMauro Carvalho Chehab /*
8130c0d06caSMauro Carvalho Chehab  * cit_model3_Packet1()
8140c0d06caSMauro Carvalho Chehab  *
8150c0d06caSMauro Carvalho Chehab  * 00_0078_012d
8160c0d06caSMauro Carvalho Chehab  * 00_0097_012f
8170c0d06caSMauro Carvalho Chehab  * 00_d141_0124
8180c0d06caSMauro Carvalho Chehab  * 00_0096_0127
8190c0d06caSMauro Carvalho Chehab  * 00_fea8_0124
8200c0d06caSMauro Carvalho Chehab  */
cit_model3_Packet1(struct gspca_dev * gspca_dev,u16 v1,u16 v2)8210c0d06caSMauro Carvalho Chehab static void cit_model3_Packet1(struct gspca_dev *gspca_dev, u16 v1, u16 v2)
8220c0d06caSMauro Carvalho Chehab {
8230c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0078, 0x012d);
8240c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, v1,     0x012f);
8250c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0xd141, 0x0124);
8260c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, v2,     0x0127);
8270c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0xfea8, 0x0124);
8280c0d06caSMauro Carvalho Chehab }
8290c0d06caSMauro Carvalho Chehab 
cit_model4_Packet1(struct gspca_dev * gspca_dev,u16 v1,u16 v2)8300c0d06caSMauro Carvalho Chehab static void cit_model4_Packet1(struct gspca_dev *gspca_dev, u16 v1, u16 v2)
8310c0d06caSMauro Carvalho Chehab {
8320c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x00aa, 0x012d);
8330c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, v1,     0x012f);
8340c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0xd141, 0x0124);
8350c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, v2,     0x0127);
8360c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0xfea8, 0x0124);
8370c0d06caSMauro Carvalho Chehab }
8380c0d06caSMauro Carvalho Chehab 
cit_model4_BrightnessPacket(struct gspca_dev * gspca_dev,u16 val)8390c0d06caSMauro Carvalho Chehab static void cit_model4_BrightnessPacket(struct gspca_dev *gspca_dev, u16 val)
8400c0d06caSMauro Carvalho Chehab {
8410c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x00aa, 0x012d);
8420c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0026, 0x012f);
8430c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0xd141, 0x0124);
8440c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, val,    0x0127);
8450c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x00aa, 0x0130);
8460c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x82a8, 0x0124);
8470c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0038, 0x012d);
8480c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0004, 0x012f);
8490c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0xd145, 0x0124);
8500c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0xfffa, 0x0124);
8510c0d06caSMauro Carvalho Chehab }
8520c0d06caSMauro Carvalho Chehab 
8530c0d06caSMauro Carvalho Chehab /* this function is called at probe time */
sd_config(struct gspca_dev * gspca_dev,const struct usb_device_id * id)8540c0d06caSMauro Carvalho Chehab static int sd_config(struct gspca_dev *gspca_dev,
8550c0d06caSMauro Carvalho Chehab 		     const struct usb_device_id *id)
8560c0d06caSMauro Carvalho Chehab {
8570c0d06caSMauro Carvalho Chehab 	struct sd *sd = (struct sd *) gspca_dev;
8580c0d06caSMauro Carvalho Chehab 	struct cam *cam;
8590c0d06caSMauro Carvalho Chehab 
8600c0d06caSMauro Carvalho Chehab 	sd->model = id->driver_info;
8610c0d06caSMauro Carvalho Chehab 	if (sd->model == CIT_MODEL3 && ibm_netcam_pro)
8620c0d06caSMauro Carvalho Chehab 		sd->model = CIT_IBM_NETCAM_PRO;
8630c0d06caSMauro Carvalho Chehab 
8640c0d06caSMauro Carvalho Chehab 	cam = &gspca_dev->cam;
8650c0d06caSMauro Carvalho Chehab 	switch (sd->model) {
8660c0d06caSMauro Carvalho Chehab 	case CIT_MODEL0:
8670c0d06caSMauro Carvalho Chehab 		cam->cam_mode = model0_mode;
8680c0d06caSMauro Carvalho Chehab 		cam->nmodes = ARRAY_SIZE(model0_mode);
8690c0d06caSMauro Carvalho Chehab 		sd->sof_len = 4;
8700c0d06caSMauro Carvalho Chehab 		break;
8710c0d06caSMauro Carvalho Chehab 	case CIT_MODEL1:
8720c0d06caSMauro Carvalho Chehab 		cam->cam_mode = cif_yuv_mode;
8730c0d06caSMauro Carvalho Chehab 		cam->nmodes = ARRAY_SIZE(cif_yuv_mode);
8740c0d06caSMauro Carvalho Chehab 		sd->sof_len = 4;
8750c0d06caSMauro Carvalho Chehab 		break;
8760c0d06caSMauro Carvalho Chehab 	case CIT_MODEL2:
8770c0d06caSMauro Carvalho Chehab 		cam->cam_mode = model2_mode + 1; /* no 160x120 */
8780c0d06caSMauro Carvalho Chehab 		cam->nmodes = 3;
8790c0d06caSMauro Carvalho Chehab 		break;
8800c0d06caSMauro Carvalho Chehab 	case CIT_MODEL3:
8810c0d06caSMauro Carvalho Chehab 		cam->cam_mode = vga_yuv_mode;
8820c0d06caSMauro Carvalho Chehab 		cam->nmodes = ARRAY_SIZE(vga_yuv_mode);
8830c0d06caSMauro Carvalho Chehab 		sd->stop_on_control_change = 1;
8840c0d06caSMauro Carvalho Chehab 		sd->sof_len = 4;
8850c0d06caSMauro Carvalho Chehab 		break;
8860c0d06caSMauro Carvalho Chehab 	case CIT_MODEL4:
8870c0d06caSMauro Carvalho Chehab 		cam->cam_mode = model2_mode;
8880c0d06caSMauro Carvalho Chehab 		cam->nmodes = ARRAY_SIZE(model2_mode);
8890c0d06caSMauro Carvalho Chehab 		break;
8900c0d06caSMauro Carvalho Chehab 	case CIT_IBM_NETCAM_PRO:
8910c0d06caSMauro Carvalho Chehab 		cam->cam_mode = vga_yuv_mode;
8920c0d06caSMauro Carvalho Chehab 		cam->nmodes = 2; /* no 640 x 480 */
8930c0d06caSMauro Carvalho Chehab 		cam->input_flags = V4L2_IN_ST_VFLIP;
8940c0d06caSMauro Carvalho Chehab 		sd->stop_on_control_change = 1;
8950c0d06caSMauro Carvalho Chehab 		sd->sof_len = 4;
8960c0d06caSMauro Carvalho Chehab 		break;
8970c0d06caSMauro Carvalho Chehab 	}
8980c0d06caSMauro Carvalho Chehab 
8990c0d06caSMauro Carvalho Chehab 	return 0;
9000c0d06caSMauro Carvalho Chehab }
9010c0d06caSMauro Carvalho Chehab 
cit_init_model0(struct gspca_dev * gspca_dev)9020c0d06caSMauro Carvalho Chehab static int cit_init_model0(struct gspca_dev *gspca_dev)
9030c0d06caSMauro Carvalho Chehab {
9040c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0000, 0x0100); /* turn on led */
9050c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0001, 0x0112); /* turn on autogain ? */
9060c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0000, 0x0400);
9070c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0001, 0x0400);
9080c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0000, 0x0420);
9090c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0001, 0x0420);
9100c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x000d, 0x0409);
9110c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0002, 0x040a);
9120c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0018, 0x0405);
9130c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0008, 0x0435);
9140c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0026, 0x040b);
9150c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0007, 0x0437);
9160c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0015, 0x042f);
9170c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x002b, 0x0439);
9180c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0026, 0x043a);
9190c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0008, 0x0438);
9200c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x001e, 0x042b);
9210c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0041, 0x042c);
9220c0d06caSMauro Carvalho Chehab 
9230c0d06caSMauro Carvalho Chehab 	return 0;
9240c0d06caSMauro Carvalho Chehab }
9250c0d06caSMauro Carvalho Chehab 
cit_init_ibm_netcam_pro(struct gspca_dev * gspca_dev)9260c0d06caSMauro Carvalho Chehab static int cit_init_ibm_netcam_pro(struct gspca_dev *gspca_dev)
9270c0d06caSMauro Carvalho Chehab {
9280c0d06caSMauro Carvalho Chehab 	cit_read_reg(gspca_dev, 0x128, 1);
9290c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0003, 0x0133);
9300c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0000, 0x0117);
9310c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0008, 0x0123);
9320c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0000, 0x0100);
9330c0d06caSMauro Carvalho Chehab 	cit_read_reg(gspca_dev, 0x0116, 0);
9340c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0060, 0x0116);
9350c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0002, 0x0112);
9360c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0000, 0x0133);
9370c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0000, 0x0123);
9380c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0001, 0x0117);
9390c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0040, 0x0108);
9400c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0019, 0x012c);
9410c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0060, 0x0116);
9420c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0002, 0x0115);
9430c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x000b, 0x0115);
9440c0d06caSMauro Carvalho Chehab 
9450c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0078, 0x012d);
9460c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0001, 0x012f);
9470c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0xd141, 0x0124);
9480c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0079, 0x012d);
9490c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x00ff, 0x0130);
9500c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0xcd41, 0x0124);
9510c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0xfffa, 0x0124);
9520c0d06caSMauro Carvalho Chehab 	cit_read_reg(gspca_dev, 0x0126, 1);
9530c0d06caSMauro Carvalho Chehab 
9540c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0000, 0x0000);
9550c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0000, 0x0001);
9560c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x000b, 0x0000);
9570c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x000c, 0x0008);
9580c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x000d, 0x003a);
9590c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x000e, 0x0060);
9600c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x000f, 0x0060);
9610c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0010, 0x0008);
9620c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0011, 0x0004);
9630c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0012, 0x0028);
9640c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0013, 0x0002);
9650c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0014, 0x0000);
9660c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0015, 0x00fb);
9670c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0016, 0x0002);
9680c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0017, 0x0037);
9690c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0018, 0x0036);
9700c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x001e, 0x0000);
9710c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x001f, 0x0008);
9720c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0020, 0x00c1);
9730c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0021, 0x0034);
9740c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0022, 0x0034);
9750c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0025, 0x0002);
9760c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0028, 0x0022);
9770c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0029, 0x000a);
9780c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x002b, 0x0000);
9790c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x002c, 0x0000);
9800c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x002d, 0x00ff);
9810c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x002e, 0x00ff);
9820c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x002f, 0x00ff);
9830c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0030, 0x00ff);
9840c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0031, 0x00ff);
9850c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0032, 0x0007);
9860c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0033, 0x0005);
9870c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0037, 0x0040);
9880c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0039, 0x0000);
9890c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x003a, 0x0000);
9900c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x003b, 0x0001);
9910c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x003c, 0x0000);
9920c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0040, 0x000c);
9930c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0041, 0x00fb);
9940c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0042, 0x0002);
9950c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0043, 0x0000);
9960c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0045, 0x0000);
9970c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0046, 0x0000);
9980c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0047, 0x0000);
9990c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0048, 0x0000);
10000c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0049, 0x0000);
10010c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x004a, 0x00ff);
10020c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x004b, 0x00ff);
10030c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x004c, 0x00ff);
10040c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x004f, 0x0000);
10050c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0050, 0x0000);
10060c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0051, 0x0002);
10070c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0055, 0x0000);
10080c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0056, 0x0000);
10090c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0057, 0x0000);
10100c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0058, 0x0002);
10110c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0059, 0x0000);
10120c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x005c, 0x0016);
10130c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x005d, 0x0022);
10140c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x005e, 0x003c);
10150c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x005f, 0x0050);
10160c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0060, 0x0044);
10170c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0061, 0x0005);
10180c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x006a, 0x007e);
10190c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x006f, 0x0000);
10200c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0072, 0x001b);
10210c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0073, 0x0005);
10220c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0074, 0x000a);
10230c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0075, 0x001b);
10240c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0076, 0x002a);
10250c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0077, 0x003c);
10260c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0078, 0x0050);
10270c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x007b, 0x0000);
10280c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x007c, 0x0011);
10290c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x007d, 0x0024);
10300c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x007e, 0x0043);
10310c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x007f, 0x005a);
10320c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0084, 0x0020);
10330c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0085, 0x0033);
10340c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0086, 0x000a);
10350c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0087, 0x0030);
10360c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0088, 0x0070);
10370c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x008b, 0x0008);
10380c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x008f, 0x0000);
10390c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0090, 0x0006);
10400c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0091, 0x0028);
10410c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0092, 0x005a);
10420c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0093, 0x0082);
10430c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0096, 0x0014);
10440c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0097, 0x0020);
10450c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0098, 0x0000);
10460c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x00b0, 0x0046);
10470c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x00b1, 0x0000);
10480c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x00b2, 0x0000);
10490c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x00b3, 0x0004);
10500c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x00b4, 0x0007);
10510c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x00b6, 0x0002);
10520c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x00b7, 0x0004);
10530c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x00bb, 0x0000);
10540c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x00bc, 0x0001);
10550c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x00bd, 0x0000);
10560c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x00bf, 0x0000);
10570c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x00c0, 0x00c8);
10580c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x00c1, 0x0014);
10590c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x00c2, 0x0001);
10600c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x00c3, 0x0000);
10610c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x00c4, 0x0004);
10620c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x00cb, 0x00bf);
10630c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x00cc, 0x00bf);
10640c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x00cd, 0x00bf);
10650c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x00ce, 0x0000);
10660c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x00cf, 0x0020);
10670c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x00d0, 0x0040);
10680c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x00d1, 0x00bf);
10690c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x00d1, 0x00bf);
10700c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x00d2, 0x00bf);
10710c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x00d3, 0x00bf);
10720c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x00ea, 0x0008);
10730c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x00eb, 0x0000);
10740c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x00ec, 0x00e8);
10750c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x00ed, 0x0001);
10760c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x00ef, 0x0022);
10770c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x00f0, 0x0000);
10780c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x00f2, 0x0028);
10790c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x00f4, 0x0002);
10800c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x00f5, 0x0000);
10810c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x00fa, 0x0000);
10820c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x00fb, 0x0001);
10830c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x00fc, 0x0000);
10840c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x00fd, 0x0000);
10850c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x00fe, 0x0000);
10860c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x00ff, 0x0000);
10870c0d06caSMauro Carvalho Chehab 
10880c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x00be, 0x0003);
10890c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x00c8, 0x0000);
10900c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x00c9, 0x0020);
10910c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x00ca, 0x0040);
10920c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0053, 0x0001);
10930c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0082, 0x000e);
10940c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0083, 0x0020);
10950c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0034, 0x003c);
10960c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x006e, 0x0055);
10970c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0062, 0x0005);
10980c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0063, 0x0008);
10990c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0066, 0x000a);
11000c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0067, 0x0006);
11010c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x006b, 0x0010);
11020c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x005a, 0x0001);
11030c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x005b, 0x000a);
11040c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0023, 0x0006);
11050c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0026, 0x0004);
11060c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0036, 0x0069);
11070c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0038, 0x0064);
11080c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x003d, 0x0003);
11090c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x003e, 0x0001);
11100c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x00b8, 0x0014);
11110c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x00b9, 0x0014);
11120c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x00e6, 0x0004);
11130c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x00e8, 0x0001);
11140c0d06caSMauro Carvalho Chehab 
11150c0d06caSMauro Carvalho Chehab 	return 0;
11160c0d06caSMauro Carvalho Chehab }
11170c0d06caSMauro Carvalho Chehab 
11180c0d06caSMauro Carvalho Chehab /* this function is called at probe and resume time */
sd_init(struct gspca_dev * gspca_dev)11190c0d06caSMauro Carvalho Chehab static int sd_init(struct gspca_dev *gspca_dev)
11200c0d06caSMauro Carvalho Chehab {
11210c0d06caSMauro Carvalho Chehab 	struct sd *sd = (struct sd *) gspca_dev;
11220c0d06caSMauro Carvalho Chehab 
11230c0d06caSMauro Carvalho Chehab 	switch (sd->model) {
11240c0d06caSMauro Carvalho Chehab 	case CIT_MODEL0:
11250c0d06caSMauro Carvalho Chehab 		cit_init_model0(gspca_dev);
11260c0d06caSMauro Carvalho Chehab 		sd_stop0(gspca_dev);
11270c0d06caSMauro Carvalho Chehab 		break;
11280c0d06caSMauro Carvalho Chehab 	case CIT_MODEL1:
11290c0d06caSMauro Carvalho Chehab 	case CIT_MODEL2:
11300c0d06caSMauro Carvalho Chehab 	case CIT_MODEL3:
11310c0d06caSMauro Carvalho Chehab 	case CIT_MODEL4:
11320c0d06caSMauro Carvalho Chehab 		break; /* All is done in sd_start */
11330c0d06caSMauro Carvalho Chehab 	case CIT_IBM_NETCAM_PRO:
11340c0d06caSMauro Carvalho Chehab 		cit_init_ibm_netcam_pro(gspca_dev);
11350c0d06caSMauro Carvalho Chehab 		sd_stop0(gspca_dev);
11360c0d06caSMauro Carvalho Chehab 		break;
11370c0d06caSMauro Carvalho Chehab 	}
11380c0d06caSMauro Carvalho Chehab 	return 0;
11390c0d06caSMauro Carvalho Chehab }
11400c0d06caSMauro Carvalho Chehab 
cit_set_brightness(struct gspca_dev * gspca_dev,s32 val)11410c0d06caSMauro Carvalho Chehab static int cit_set_brightness(struct gspca_dev *gspca_dev, s32 val)
11420c0d06caSMauro Carvalho Chehab {
11430c0d06caSMauro Carvalho Chehab 	struct sd *sd = (struct sd *) gspca_dev;
11440c0d06caSMauro Carvalho Chehab 	int i;
11450c0d06caSMauro Carvalho Chehab 
11460c0d06caSMauro Carvalho Chehab 	switch (sd->model) {
11470c0d06caSMauro Carvalho Chehab 	case CIT_MODEL0:
11480c0d06caSMauro Carvalho Chehab 	case CIT_IBM_NETCAM_PRO:
11490c0d06caSMauro Carvalho Chehab 		/* No (known) brightness control for these */
11500c0d06caSMauro Carvalho Chehab 		break;
11510c0d06caSMauro Carvalho Chehab 	case CIT_MODEL1:
11520c0d06caSMauro Carvalho Chehab 		/* Model 1: Brightness range 0 - 63 */
11530c0d06caSMauro Carvalho Chehab 		cit_Packet_Format1(gspca_dev, 0x0031, val);
11540c0d06caSMauro Carvalho Chehab 		cit_Packet_Format1(gspca_dev, 0x0032, val);
11550c0d06caSMauro Carvalho Chehab 		cit_Packet_Format1(gspca_dev, 0x0033, val);
11560c0d06caSMauro Carvalho Chehab 		break;
11570c0d06caSMauro Carvalho Chehab 	case CIT_MODEL2:
11580c0d06caSMauro Carvalho Chehab 		/* Model 2: Brightness range 0x60 - 0xee */
11590c0d06caSMauro Carvalho Chehab 		/* Scale 0 - 63 to 0x60 - 0xee */
11600c0d06caSMauro Carvalho Chehab 		i = 0x60 + val * 2254 / 1000;
11610c0d06caSMauro Carvalho Chehab 		cit_model2_Packet1(gspca_dev, 0x001a, i);
11620c0d06caSMauro Carvalho Chehab 		break;
11630c0d06caSMauro Carvalho Chehab 	case CIT_MODEL3:
11640c0d06caSMauro Carvalho Chehab 		/* Model 3: Brightness range 'i' in [0x0C..0x3F] */
11650c0d06caSMauro Carvalho Chehab 		i = val;
11660c0d06caSMauro Carvalho Chehab 		if (i < 0x0c)
11670c0d06caSMauro Carvalho Chehab 			i = 0x0c;
11680c0d06caSMauro Carvalho Chehab 		cit_model3_Packet1(gspca_dev, 0x0036, i);
11690c0d06caSMauro Carvalho Chehab 		break;
11700c0d06caSMauro Carvalho Chehab 	case CIT_MODEL4:
11710c0d06caSMauro Carvalho Chehab 		/* Model 4: Brightness range 'i' in [0x04..0xb4] */
11720c0d06caSMauro Carvalho Chehab 		/* Scale 0 - 63 to 0x04 - 0xb4 */
11730c0d06caSMauro Carvalho Chehab 		i = 0x04 + val * 2794 / 1000;
11740c0d06caSMauro Carvalho Chehab 		cit_model4_BrightnessPacket(gspca_dev, i);
11750c0d06caSMauro Carvalho Chehab 		break;
11760c0d06caSMauro Carvalho Chehab 	}
11770c0d06caSMauro Carvalho Chehab 
11780c0d06caSMauro Carvalho Chehab 	return 0;
11790c0d06caSMauro Carvalho Chehab }
11800c0d06caSMauro Carvalho Chehab 
cit_set_contrast(struct gspca_dev * gspca_dev,s32 val)11810c0d06caSMauro Carvalho Chehab static int cit_set_contrast(struct gspca_dev *gspca_dev, s32 val)
11820c0d06caSMauro Carvalho Chehab {
11830c0d06caSMauro Carvalho Chehab 	struct sd *sd = (struct sd *) gspca_dev;
11840c0d06caSMauro Carvalho Chehab 
11850c0d06caSMauro Carvalho Chehab 	switch (sd->model) {
11860c0d06caSMauro Carvalho Chehab 	case CIT_MODEL0: {
11870c0d06caSMauro Carvalho Chehab 		int i;
11880c0d06caSMauro Carvalho Chehab 		/* gain 0-15, 0-20 -> 0-15 */
11890c0d06caSMauro Carvalho Chehab 		i = val * 1000 / 1333;
11900c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, i, 0x0422);
11910c0d06caSMauro Carvalho Chehab 		/* gain 0-31, may not be lower then 0x0422, 0-20 -> 0-31 */
11920c0d06caSMauro Carvalho Chehab 		i = val * 2000 / 1333;
11930c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, i, 0x0423);
11940c0d06caSMauro Carvalho Chehab 		/* gain 0-127, may not be lower then 0x0423, 0-20 -> 0-63  */
11950c0d06caSMauro Carvalho Chehab 		i = val * 4000 / 1333;
11960c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, i, 0x0424);
11970c0d06caSMauro Carvalho Chehab 		/* gain 0-127, may not be lower then 0x0424, , 0-20 -> 0-127 */
11980c0d06caSMauro Carvalho Chehab 		i = val * 8000 / 1333;
11990c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, i, 0x0425);
12000c0d06caSMauro Carvalho Chehab 		break;
12010c0d06caSMauro Carvalho Chehab 	}
12020c0d06caSMauro Carvalho Chehab 	case CIT_MODEL2:
12030c0d06caSMauro Carvalho Chehab 	case CIT_MODEL4:
12040c0d06caSMauro Carvalho Chehab 		/* These models do not have this control. */
12050c0d06caSMauro Carvalho Chehab 		break;
12060c0d06caSMauro Carvalho Chehab 	case CIT_MODEL1:
12070c0d06caSMauro Carvalho Chehab 	{
12080c0d06caSMauro Carvalho Chehab 		/* Scale 0 - 20 to 15 - 0 */
12090c0d06caSMauro Carvalho Chehab 		int i, new_contrast = (20 - val) * 1000 / 1333;
12100c0d06caSMauro Carvalho Chehab 		for (i = 0; i < cit_model1_ntries; i++) {
12110c0d06caSMauro Carvalho Chehab 			cit_Packet_Format1(gspca_dev, 0x0014, new_contrast);
12120c0d06caSMauro Carvalho Chehab 			cit_send_FF_04_02(gspca_dev);
12130c0d06caSMauro Carvalho Chehab 		}
12140c0d06caSMauro Carvalho Chehab 		break;
12150c0d06caSMauro Carvalho Chehab 	}
12160c0d06caSMauro Carvalho Chehab 	case CIT_MODEL3:
12170c0d06caSMauro Carvalho Chehab 	{	/* Preset hardware values */
12180c0d06caSMauro Carvalho Chehab 		static const struct {
12190c0d06caSMauro Carvalho Chehab 			unsigned short cv1;
12200c0d06caSMauro Carvalho Chehab 			unsigned short cv2;
12210c0d06caSMauro Carvalho Chehab 			unsigned short cv3;
12220c0d06caSMauro Carvalho Chehab 		} cv[7] = {
12230c0d06caSMauro Carvalho Chehab 			{ 0x05, 0x05, 0x0f },	/* Minimum */
12240c0d06caSMauro Carvalho Chehab 			{ 0x04, 0x04, 0x16 },
12250c0d06caSMauro Carvalho Chehab 			{ 0x02, 0x03, 0x16 },
12260c0d06caSMauro Carvalho Chehab 			{ 0x02, 0x08, 0x16 },
12270c0d06caSMauro Carvalho Chehab 			{ 0x01, 0x0c, 0x16 },
12280c0d06caSMauro Carvalho Chehab 			{ 0x01, 0x0e, 0x16 },
12290c0d06caSMauro Carvalho Chehab 			{ 0x01, 0x10, 0x16 }	/* Maximum */
12300c0d06caSMauro Carvalho Chehab 		};
12310c0d06caSMauro Carvalho Chehab 		int i = val / 3;
12320c0d06caSMauro Carvalho Chehab 		cit_model3_Packet1(gspca_dev, 0x0067, cv[i].cv1);
12330c0d06caSMauro Carvalho Chehab 		cit_model3_Packet1(gspca_dev, 0x005b, cv[i].cv2);
12340c0d06caSMauro Carvalho Chehab 		cit_model3_Packet1(gspca_dev, 0x005c, cv[i].cv3);
12350c0d06caSMauro Carvalho Chehab 		break;
12360c0d06caSMauro Carvalho Chehab 	}
12370c0d06caSMauro Carvalho Chehab 	case CIT_IBM_NETCAM_PRO:
12380c0d06caSMauro Carvalho Chehab 		cit_model3_Packet1(gspca_dev, 0x005b, val + 1);
12390c0d06caSMauro Carvalho Chehab 		break;
12400c0d06caSMauro Carvalho Chehab 	}
12410c0d06caSMauro Carvalho Chehab 	return 0;
12420c0d06caSMauro Carvalho Chehab }
12430c0d06caSMauro Carvalho Chehab 
cit_set_hue(struct gspca_dev * gspca_dev,s32 val)12440c0d06caSMauro Carvalho Chehab static int cit_set_hue(struct gspca_dev *gspca_dev, s32 val)
12450c0d06caSMauro Carvalho Chehab {
12460c0d06caSMauro Carvalho Chehab 	struct sd *sd = (struct sd *) gspca_dev;
12470c0d06caSMauro Carvalho Chehab 
12480c0d06caSMauro Carvalho Chehab 	switch (sd->model) {
12490c0d06caSMauro Carvalho Chehab 	case CIT_MODEL0:
12500c0d06caSMauro Carvalho Chehab 	case CIT_MODEL1:
12510c0d06caSMauro Carvalho Chehab 	case CIT_IBM_NETCAM_PRO:
12520c0d06caSMauro Carvalho Chehab 		/* No hue control for these models */
12530c0d06caSMauro Carvalho Chehab 		break;
12540c0d06caSMauro Carvalho Chehab 	case CIT_MODEL2:
12550c0d06caSMauro Carvalho Chehab 		cit_model2_Packet1(gspca_dev, 0x0024, val);
12560c0d06caSMauro Carvalho Chehab 		/* cit_model2_Packet1(gspca_dev, 0x0020, sat); */
12570c0d06caSMauro Carvalho Chehab 		break;
12580c0d06caSMauro Carvalho Chehab 	case CIT_MODEL3: {
12590c0d06caSMauro Carvalho Chehab 		/* Model 3: Brightness range 'i' in [0x05..0x37] */
12600c0d06caSMauro Carvalho Chehab 		/* TESTME according to the ibmcam driver this does not work */
12610c0d06caSMauro Carvalho Chehab 		if (0) {
12620c0d06caSMauro Carvalho Chehab 			/* Scale 0 - 127 to 0x05 - 0x37 */
12630c0d06caSMauro Carvalho Chehab 			int i = 0x05 + val * 1000 / 2540;
12640c0d06caSMauro Carvalho Chehab 			cit_model3_Packet1(gspca_dev, 0x007e, i);
12650c0d06caSMauro Carvalho Chehab 		}
12660c0d06caSMauro Carvalho Chehab 		break;
12670c0d06caSMauro Carvalho Chehab 	}
12680c0d06caSMauro Carvalho Chehab 	case CIT_MODEL4:
12690c0d06caSMauro Carvalho Chehab 		/* HDG: taken from ibmcam, setting the color gains does not
12700c0d06caSMauro Carvalho Chehab 		 * really belong here.
12710c0d06caSMauro Carvalho Chehab 		 *
12720c0d06caSMauro Carvalho Chehab 		 * I am not sure r/g/b_gain variables exactly control gain
12730c0d06caSMauro Carvalho Chehab 		 * of those channels. Most likely they subtly change some
12740c0d06caSMauro Carvalho Chehab 		 * very internal image processing settings in the camera.
12750c0d06caSMauro Carvalho Chehab 		 * In any case, here is what they do, and feel free to tweak:
12760c0d06caSMauro Carvalho Chehab 		 *
12770c0d06caSMauro Carvalho Chehab 		 * r_gain: seriously affects red gain
12780c0d06caSMauro Carvalho Chehab 		 * g_gain: seriously affects green gain
12790c0d06caSMauro Carvalho Chehab 		 * b_gain: seriously affects blue gain
12800c0d06caSMauro Carvalho Chehab 		 * hue: changes average color from violet (0) to red (0xFF)
12810c0d06caSMauro Carvalho Chehab 		 */
12820c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
12830c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x001e, 0x012f);
12840c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xd141, 0x0124);
12850c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev,    160, 0x0127);  /* Green gain */
12860c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev,    160, 0x012e);  /* Red gain */
12870c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev,    160, 0x0130);  /* Blue gain */
12880c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x8a28, 0x0124);
12890c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, val, 0x012d); /* Hue */
12900c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xf545, 0x0124);
12910c0d06caSMauro Carvalho Chehab 		break;
12920c0d06caSMauro Carvalho Chehab 	}
12930c0d06caSMauro Carvalho Chehab 	return 0;
12940c0d06caSMauro Carvalho Chehab }
12950c0d06caSMauro Carvalho Chehab 
cit_set_sharpness(struct gspca_dev * gspca_dev,s32 val)12960c0d06caSMauro Carvalho Chehab static int cit_set_sharpness(struct gspca_dev *gspca_dev, s32 val)
12970c0d06caSMauro Carvalho Chehab {
12980c0d06caSMauro Carvalho Chehab 	struct sd *sd = (struct sd *) gspca_dev;
12990c0d06caSMauro Carvalho Chehab 
13000c0d06caSMauro Carvalho Chehab 	switch (sd->model) {
13010c0d06caSMauro Carvalho Chehab 	case CIT_MODEL0:
13020c0d06caSMauro Carvalho Chehab 	case CIT_MODEL2:
13030c0d06caSMauro Carvalho Chehab 	case CIT_MODEL4:
13040c0d06caSMauro Carvalho Chehab 	case CIT_IBM_NETCAM_PRO:
13050c0d06caSMauro Carvalho Chehab 		/* These models do not have this control */
13060c0d06caSMauro Carvalho Chehab 		break;
13070c0d06caSMauro Carvalho Chehab 	case CIT_MODEL1: {
13080c0d06caSMauro Carvalho Chehab 		int i;
1309d4a06464SColin Ian King 		static const unsigned short sa[] = {
13100c0d06caSMauro Carvalho Chehab 			0x11, 0x13, 0x16, 0x18, 0x1a, 0x8, 0x0a };
13110c0d06caSMauro Carvalho Chehab 
13120c0d06caSMauro Carvalho Chehab 		for (i = 0; i < cit_model1_ntries; i++)
13130c0d06caSMauro Carvalho Chehab 			cit_PacketFormat2(gspca_dev, 0x0013, sa[val]);
13140c0d06caSMauro Carvalho Chehab 		break;
13150c0d06caSMauro Carvalho Chehab 	}
13160c0d06caSMauro Carvalho Chehab 	case CIT_MODEL3:
13170c0d06caSMauro Carvalho Chehab 	{	/*
13180c0d06caSMauro Carvalho Chehab 		 * "Use a table of magic numbers.
13190c0d06caSMauro Carvalho Chehab 		 *  This setting doesn't really change much.
13200c0d06caSMauro Carvalho Chehab 		 *  But that's how Windows does it."
13210c0d06caSMauro Carvalho Chehab 		 */
13220c0d06caSMauro Carvalho Chehab 		static const struct {
13230c0d06caSMauro Carvalho Chehab 			unsigned short sv1;
13240c0d06caSMauro Carvalho Chehab 			unsigned short sv2;
13250c0d06caSMauro Carvalho Chehab 			unsigned short sv3;
13260c0d06caSMauro Carvalho Chehab 			unsigned short sv4;
13270c0d06caSMauro Carvalho Chehab 		} sv[7] = {
13280c0d06caSMauro Carvalho Chehab 			{ 0x00, 0x00, 0x05, 0x14 },	/* Smoothest */
13290c0d06caSMauro Carvalho Chehab 			{ 0x01, 0x04, 0x05, 0x14 },
13300c0d06caSMauro Carvalho Chehab 			{ 0x02, 0x04, 0x05, 0x14 },
13310c0d06caSMauro Carvalho Chehab 			{ 0x03, 0x04, 0x05, 0x14 },
13320c0d06caSMauro Carvalho Chehab 			{ 0x03, 0x05, 0x05, 0x14 },
13330c0d06caSMauro Carvalho Chehab 			{ 0x03, 0x06, 0x05, 0x14 },
13340c0d06caSMauro Carvalho Chehab 			{ 0x03, 0x07, 0x05, 0x14 }	/* Sharpest */
13350c0d06caSMauro Carvalho Chehab 		};
13360c0d06caSMauro Carvalho Chehab 		cit_model3_Packet1(gspca_dev, 0x0060, sv[val].sv1);
13370c0d06caSMauro Carvalho Chehab 		cit_model3_Packet1(gspca_dev, 0x0061, sv[val].sv2);
13380c0d06caSMauro Carvalho Chehab 		cit_model3_Packet1(gspca_dev, 0x0062, sv[val].sv3);
13390c0d06caSMauro Carvalho Chehab 		cit_model3_Packet1(gspca_dev, 0x0063, sv[val].sv4);
13400c0d06caSMauro Carvalho Chehab 		break;
13410c0d06caSMauro Carvalho Chehab 	}
13420c0d06caSMauro Carvalho Chehab 	}
13430c0d06caSMauro Carvalho Chehab 	return 0;
13440c0d06caSMauro Carvalho Chehab }
13450c0d06caSMauro Carvalho Chehab 
13460c0d06caSMauro Carvalho Chehab /*
13470c0d06caSMauro Carvalho Chehab  * cit_set_lighting()
13480c0d06caSMauro Carvalho Chehab  *
13490c0d06caSMauro Carvalho Chehab  * Camera model 1:
13500c0d06caSMauro Carvalho Chehab  * We have 3 levels of lighting conditions: 0=Bright, 1=Medium, 2=Low.
13510c0d06caSMauro Carvalho Chehab  *
13520c0d06caSMauro Carvalho Chehab  * Camera model 2:
13530c0d06caSMauro Carvalho Chehab  * We have 16 levels of lighting, 0 for bright light and up to 15 for
13540c0d06caSMauro Carvalho Chehab  * low light. But values above 5 or so are useless because camera is
13550c0d06caSMauro Carvalho Chehab  * not really capable to produce anything worth viewing at such light.
13560c0d06caSMauro Carvalho Chehab  * This setting may be altered only in certain camera state.
13570c0d06caSMauro Carvalho Chehab  *
13580c0d06caSMauro Carvalho Chehab  * Low lighting forces slower FPS.
13590c0d06caSMauro Carvalho Chehab  *
13600c0d06caSMauro Carvalho Chehab  * History:
13610c0d06caSMauro Carvalho Chehab  * 1/5/00   Created.
13620c0d06caSMauro Carvalho Chehab  * 2/20/00  Added support for Model 2 cameras.
13630c0d06caSMauro Carvalho Chehab  */
cit_set_lighting(struct gspca_dev * gspca_dev,s32 val)13640c0d06caSMauro Carvalho Chehab static void cit_set_lighting(struct gspca_dev *gspca_dev, s32 val)
13650c0d06caSMauro Carvalho Chehab {
13660c0d06caSMauro Carvalho Chehab 	struct sd *sd = (struct sd *) gspca_dev;
13670c0d06caSMauro Carvalho Chehab 
13680c0d06caSMauro Carvalho Chehab 	switch (sd->model) {
13690c0d06caSMauro Carvalho Chehab 	case CIT_MODEL0:
13700c0d06caSMauro Carvalho Chehab 	case CIT_MODEL2:
13710c0d06caSMauro Carvalho Chehab 	case CIT_MODEL3:
13720c0d06caSMauro Carvalho Chehab 	case CIT_MODEL4:
13730c0d06caSMauro Carvalho Chehab 	case CIT_IBM_NETCAM_PRO:
13740c0d06caSMauro Carvalho Chehab 		break;
13750c0d06caSMauro Carvalho Chehab 	case CIT_MODEL1: {
13760c0d06caSMauro Carvalho Chehab 		int i;
13770c0d06caSMauro Carvalho Chehab 		for (i = 0; i < cit_model1_ntries; i++)
13780c0d06caSMauro Carvalho Chehab 			cit_Packet_Format1(gspca_dev, 0x0027, val);
13790c0d06caSMauro Carvalho Chehab 		break;
13800c0d06caSMauro Carvalho Chehab 	}
13810c0d06caSMauro Carvalho Chehab 	}
13820c0d06caSMauro Carvalho Chehab }
13830c0d06caSMauro Carvalho Chehab 
cit_set_hflip(struct gspca_dev * gspca_dev,s32 val)13840c0d06caSMauro Carvalho Chehab static void cit_set_hflip(struct gspca_dev *gspca_dev, s32 val)
13850c0d06caSMauro Carvalho Chehab {
13860c0d06caSMauro Carvalho Chehab 	struct sd *sd = (struct sd *) gspca_dev;
13870c0d06caSMauro Carvalho Chehab 
13880c0d06caSMauro Carvalho Chehab 	switch (sd->model) {
13890c0d06caSMauro Carvalho Chehab 	case CIT_MODEL0:
13900c0d06caSMauro Carvalho Chehab 		if (val)
13910c0d06caSMauro Carvalho Chehab 			cit_write_reg(gspca_dev, 0x0020, 0x0115);
13920c0d06caSMauro Carvalho Chehab 		else
13930c0d06caSMauro Carvalho Chehab 			cit_write_reg(gspca_dev, 0x0040, 0x0115);
13940c0d06caSMauro Carvalho Chehab 		break;
13950c0d06caSMauro Carvalho Chehab 	case CIT_MODEL1:
13960c0d06caSMauro Carvalho Chehab 	case CIT_MODEL2:
13970c0d06caSMauro Carvalho Chehab 	case CIT_MODEL3:
13980c0d06caSMauro Carvalho Chehab 	case CIT_MODEL4:
13990c0d06caSMauro Carvalho Chehab 	case CIT_IBM_NETCAM_PRO:
14000c0d06caSMauro Carvalho Chehab 		break;
14010c0d06caSMauro Carvalho Chehab 	}
14020c0d06caSMauro Carvalho Chehab }
14030c0d06caSMauro Carvalho Chehab 
cit_restart_stream(struct gspca_dev * gspca_dev)14040c0d06caSMauro Carvalho Chehab static int cit_restart_stream(struct gspca_dev *gspca_dev)
14050c0d06caSMauro Carvalho Chehab {
14060c0d06caSMauro Carvalho Chehab 	struct sd *sd = (struct sd *) gspca_dev;
14070c0d06caSMauro Carvalho Chehab 
14080c0d06caSMauro Carvalho Chehab 	switch (sd->model) {
14090c0d06caSMauro Carvalho Chehab 	case CIT_MODEL0:
14100c0d06caSMauro Carvalho Chehab 	case CIT_MODEL1:
14110c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0001, 0x0114);
1412*1771e9fbSGustavo A. R. Silva 		fallthrough;
14130c0d06caSMauro Carvalho Chehab 	case CIT_MODEL2:
14140c0d06caSMauro Carvalho Chehab 	case CIT_MODEL4:
14150c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00c0, 0x010c); /* Go! */
14160c0d06caSMauro Carvalho Chehab 		usb_clear_halt(gspca_dev->dev, gspca_dev->urb[0]->pipe);
14170c0d06caSMauro Carvalho Chehab 		break;
14180c0d06caSMauro Carvalho Chehab 	case CIT_MODEL3:
14190c0d06caSMauro Carvalho Chehab 	case CIT_IBM_NETCAM_PRO:
14200c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0001, 0x0114);
14210c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00c0, 0x010c); /* Go! */
14220c0d06caSMauro Carvalho Chehab 		usb_clear_halt(gspca_dev->dev, gspca_dev->urb[0]->pipe);
14230c0d06caSMauro Carvalho Chehab 		/* Clear button events from while we were not streaming */
14240c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0001, 0x0113);
14250c0d06caSMauro Carvalho Chehab 		break;
14260c0d06caSMauro Carvalho Chehab 	}
14270c0d06caSMauro Carvalho Chehab 
14280c0d06caSMauro Carvalho Chehab 	sd->sof_read = 0;
14290c0d06caSMauro Carvalho Chehab 
14300c0d06caSMauro Carvalho Chehab 	return 0;
14310c0d06caSMauro Carvalho Chehab }
14320c0d06caSMauro Carvalho Chehab 
cit_get_packet_size(struct gspca_dev * gspca_dev)14330c0d06caSMauro Carvalho Chehab static int cit_get_packet_size(struct gspca_dev *gspca_dev)
14340c0d06caSMauro Carvalho Chehab {
14350c0d06caSMauro Carvalho Chehab 	struct usb_host_interface *alt;
14360c0d06caSMauro Carvalho Chehab 	struct usb_interface *intf;
14370c0d06caSMauro Carvalho Chehab 
14380c0d06caSMauro Carvalho Chehab 	intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface);
14390c0d06caSMauro Carvalho Chehab 	alt = usb_altnum_to_altsetting(intf, gspca_dev->alt);
14400c0d06caSMauro Carvalho Chehab 	if (!alt) {
14410c0d06caSMauro Carvalho Chehab 		pr_err("Couldn't get altsetting\n");
14420c0d06caSMauro Carvalho Chehab 		return -EIO;
14430c0d06caSMauro Carvalho Chehab 	}
14440c0d06caSMauro Carvalho Chehab 
1445a246b4d5SJohan Hovold 	if (alt->desc.bNumEndpoints < 1)
1446a246b4d5SJohan Hovold 		return -ENODEV;
1447a246b4d5SJohan Hovold 
14480c0d06caSMauro Carvalho Chehab 	return le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
14490c0d06caSMauro Carvalho Chehab }
14500c0d06caSMauro Carvalho Chehab 
14510c0d06caSMauro Carvalho Chehab /* Calculate the clockdiv giving us max fps given the available bandwidth */
cit_get_clock_div(struct gspca_dev * gspca_dev)14520c0d06caSMauro Carvalho Chehab static int cit_get_clock_div(struct gspca_dev *gspca_dev)
14530c0d06caSMauro Carvalho Chehab {
14540c0d06caSMauro Carvalho Chehab 	int clock_div = 7; /* 0=30 1=25 2=20 3=15 4=12 5=7.5 6=6 7=3fps ?? */
14550c0d06caSMauro Carvalho Chehab 	int fps[8] = { 30, 25, 20, 15, 12, 8, 6, 3 };
14560c0d06caSMauro Carvalho Chehab 	int packet_size;
14570c0d06caSMauro Carvalho Chehab 
14580c0d06caSMauro Carvalho Chehab 	packet_size = cit_get_packet_size(gspca_dev);
14590c0d06caSMauro Carvalho Chehab 	if (packet_size < 0)
14600c0d06caSMauro Carvalho Chehab 		return packet_size;
14610c0d06caSMauro Carvalho Chehab 
14620c0d06caSMauro Carvalho Chehab 	while (clock_div > 3 &&
14630c0d06caSMauro Carvalho Chehab 			1000 * packet_size >
14641966bc2aSOndrej Zary 			gspca_dev->pixfmt.width * gspca_dev->pixfmt.height *
14650c0d06caSMauro Carvalho Chehab 			fps[clock_div - 1] * 3 / 2)
14660c0d06caSMauro Carvalho Chehab 		clock_div--;
14670c0d06caSMauro Carvalho Chehab 
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]);
14730c0d06caSMauro Carvalho Chehab 
14740c0d06caSMauro Carvalho Chehab 	return clock_div;
14750c0d06caSMauro Carvalho Chehab }
14760c0d06caSMauro Carvalho Chehab 
cit_start_model0(struct gspca_dev * gspca_dev)14770c0d06caSMauro Carvalho Chehab static int cit_start_model0(struct gspca_dev *gspca_dev)
14780c0d06caSMauro Carvalho Chehab {
14790c0d06caSMauro Carvalho Chehab 	const unsigned short compression = 0; /* 0=none, 7=best frame rate */
14800c0d06caSMauro Carvalho Chehab 	int clock_div;
14810c0d06caSMauro Carvalho Chehab 
14820c0d06caSMauro Carvalho Chehab 	clock_div = cit_get_clock_div(gspca_dev);
14830c0d06caSMauro Carvalho Chehab 	if (clock_div < 0)
14840c0d06caSMauro Carvalho Chehab 		return clock_div;
14850c0d06caSMauro Carvalho Chehab 
14860c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0000, 0x0100); /* turn on led */
14870c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0003, 0x0438);
14880c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x001e, 0x042b);
14890c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0041, 0x042c);
14900c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0008, 0x0436);
14910c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0024, 0x0403);
14920c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x002c, 0x0404);
14930c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0002, 0x0426);
14940c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0014, 0x0427);
14950c0d06caSMauro Carvalho Chehab 
14961966bc2aSOndrej Zary 	switch (gspca_dev->pixfmt.width) {
14970c0d06caSMauro Carvalho Chehab 	case 160: /* 160x120 */
14980c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0004, 0x010b);
14990c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0001, 0x010a);
15000c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0010, 0x0102);
15010c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00a0, 0x0103);
15020c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0000, 0x0104);
15030c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0078, 0x0105);
15040c0d06caSMauro Carvalho Chehab 		break;
15050c0d06caSMauro Carvalho Chehab 
15060c0d06caSMauro Carvalho Chehab 	case 176: /* 176x144 */
15070c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0006, 0x010b);
15080c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0000, 0x010a);
15090c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0005, 0x0102);
15100c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00b0, 0x0103);
15110c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0000, 0x0104);
15120c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0090, 0x0105);
15130c0d06caSMauro Carvalho Chehab 		break;
15140c0d06caSMauro Carvalho Chehab 
15150c0d06caSMauro Carvalho Chehab 	case 320: /* 320x240 */
15160c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0008, 0x010b);
15170c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0004, 0x010a);
15180c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0005, 0x0102);
15190c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00a0, 0x0103);
15200c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0010, 0x0104);
15210c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0078, 0x0105);
15220c0d06caSMauro Carvalho Chehab 		break;
15230c0d06caSMauro Carvalho Chehab 	}
15240c0d06caSMauro Carvalho Chehab 
15250c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, compression, 0x0109);
15260c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, clock_div, 0x0111);
15270c0d06caSMauro Carvalho Chehab 
15280c0d06caSMauro Carvalho Chehab 	return 0;
15290c0d06caSMauro Carvalho Chehab }
15300c0d06caSMauro Carvalho Chehab 
cit_start_model1(struct gspca_dev * gspca_dev)15310c0d06caSMauro Carvalho Chehab static int cit_start_model1(struct gspca_dev *gspca_dev)
15320c0d06caSMauro Carvalho Chehab {
15330c0d06caSMauro Carvalho Chehab 	struct sd *sd = (struct sd *) gspca_dev;
15340c0d06caSMauro Carvalho Chehab 	int i, clock_div;
15350c0d06caSMauro Carvalho Chehab 
15360c0d06caSMauro Carvalho Chehab 	clock_div = cit_get_clock_div(gspca_dev);
15370c0d06caSMauro Carvalho Chehab 	if (clock_div < 0)
15380c0d06caSMauro Carvalho Chehab 		return clock_div;
15390c0d06caSMauro Carvalho Chehab 
15400c0d06caSMauro Carvalho Chehab 	cit_read_reg(gspca_dev, 0x0128, 1);
15410c0d06caSMauro Carvalho Chehab 	cit_read_reg(gspca_dev, 0x0100, 0);
15420c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x01, 0x0100);	/* LED On  */
15430c0d06caSMauro Carvalho Chehab 	cit_read_reg(gspca_dev, 0x0100, 0);
15440c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x81, 0x0100);	/* LED Off */
15450c0d06caSMauro Carvalho Chehab 	cit_read_reg(gspca_dev, 0x0100, 0);
15460c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x01, 0x0100);	/* LED On  */
15470c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x01, 0x0108);
15480c0d06caSMauro Carvalho Chehab 
15490c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x03, 0x0112);
15500c0d06caSMauro Carvalho Chehab 	cit_read_reg(gspca_dev, 0x0115, 0);
15510c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x06, 0x0115);
15520c0d06caSMauro Carvalho Chehab 	cit_read_reg(gspca_dev, 0x0116, 0);
15530c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x44, 0x0116);
15540c0d06caSMauro Carvalho Chehab 	cit_read_reg(gspca_dev, 0x0116, 0);
15550c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x40, 0x0116);
15560c0d06caSMauro Carvalho Chehab 	cit_read_reg(gspca_dev, 0x0115, 0);
15570c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0e, 0x0115);
15580c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x19, 0x012c);
15590c0d06caSMauro Carvalho Chehab 
15600c0d06caSMauro Carvalho Chehab 	cit_Packet_Format1(gspca_dev, 0x00, 0x1e);
15610c0d06caSMauro Carvalho Chehab 	cit_Packet_Format1(gspca_dev, 0x39, 0x0d);
15620c0d06caSMauro Carvalho Chehab 	cit_Packet_Format1(gspca_dev, 0x39, 0x09);
15630c0d06caSMauro Carvalho Chehab 	cit_Packet_Format1(gspca_dev, 0x3b, 0x00);
15640c0d06caSMauro Carvalho Chehab 	cit_Packet_Format1(gspca_dev, 0x28, 0x22);
15650c0d06caSMauro Carvalho Chehab 	cit_Packet_Format1(gspca_dev, 0x27, 0x00);
15660c0d06caSMauro Carvalho Chehab 	cit_Packet_Format1(gspca_dev, 0x2b, 0x1f);
15670c0d06caSMauro Carvalho Chehab 	cit_Packet_Format1(gspca_dev, 0x39, 0x08);
15680c0d06caSMauro Carvalho Chehab 
15690c0d06caSMauro Carvalho Chehab 	for (i = 0; i < cit_model1_ntries; i++)
15700c0d06caSMauro Carvalho Chehab 		cit_Packet_Format1(gspca_dev, 0x2c, 0x00);
15710c0d06caSMauro Carvalho Chehab 
15720c0d06caSMauro Carvalho Chehab 	for (i = 0; i < cit_model1_ntries; i++)
15730c0d06caSMauro Carvalho Chehab 		cit_Packet_Format1(gspca_dev, 0x30, 0x14);
15740c0d06caSMauro Carvalho Chehab 
15750c0d06caSMauro Carvalho Chehab 	cit_PacketFormat2(gspca_dev, 0x39, 0x02);
15760c0d06caSMauro Carvalho Chehab 	cit_PacketFormat2(gspca_dev, 0x01, 0xe1);
15770c0d06caSMauro Carvalho Chehab 	cit_PacketFormat2(gspca_dev, 0x02, 0xcd);
15780c0d06caSMauro Carvalho Chehab 	cit_PacketFormat2(gspca_dev, 0x03, 0xcd);
15790c0d06caSMauro Carvalho Chehab 	cit_PacketFormat2(gspca_dev, 0x04, 0xfa);
15800c0d06caSMauro Carvalho Chehab 	cit_PacketFormat2(gspca_dev, 0x3f, 0xff);
15810c0d06caSMauro Carvalho Chehab 	cit_PacketFormat2(gspca_dev, 0x39, 0x00);
15820c0d06caSMauro Carvalho Chehab 
15830c0d06caSMauro Carvalho Chehab 	cit_PacketFormat2(gspca_dev, 0x39, 0x02);
15840c0d06caSMauro Carvalho Chehab 	cit_PacketFormat2(gspca_dev, 0x0a, 0x37);
15850c0d06caSMauro Carvalho Chehab 	cit_PacketFormat2(gspca_dev, 0x0b, 0xb8);
15860c0d06caSMauro Carvalho Chehab 	cit_PacketFormat2(gspca_dev, 0x0c, 0xf3);
15870c0d06caSMauro Carvalho Chehab 	cit_PacketFormat2(gspca_dev, 0x0d, 0xe3);
15880c0d06caSMauro Carvalho Chehab 	cit_PacketFormat2(gspca_dev, 0x0e, 0x0d);
15890c0d06caSMauro Carvalho Chehab 	cit_PacketFormat2(gspca_dev, 0x0f, 0xf2);
15900c0d06caSMauro Carvalho Chehab 	cit_PacketFormat2(gspca_dev, 0x10, 0xd5);
15910c0d06caSMauro Carvalho Chehab 	cit_PacketFormat2(gspca_dev, 0x11, 0xba);
15920c0d06caSMauro Carvalho Chehab 	cit_PacketFormat2(gspca_dev, 0x12, 0x53);
15930c0d06caSMauro Carvalho Chehab 	cit_PacketFormat2(gspca_dev, 0x3f, 0xff);
15940c0d06caSMauro Carvalho Chehab 	cit_PacketFormat2(gspca_dev, 0x39, 0x00);
15950c0d06caSMauro Carvalho Chehab 
15960c0d06caSMauro Carvalho Chehab 	cit_PacketFormat2(gspca_dev, 0x39, 0x02);
15970c0d06caSMauro Carvalho Chehab 	cit_PacketFormat2(gspca_dev, 0x16, 0x00);
15980c0d06caSMauro Carvalho Chehab 	cit_PacketFormat2(gspca_dev, 0x17, 0x28);
15990c0d06caSMauro Carvalho Chehab 	cit_PacketFormat2(gspca_dev, 0x18, 0x7d);
16000c0d06caSMauro Carvalho Chehab 	cit_PacketFormat2(gspca_dev, 0x19, 0xbe);
16010c0d06caSMauro Carvalho Chehab 	cit_PacketFormat2(gspca_dev, 0x3f, 0xff);
16020c0d06caSMauro Carvalho Chehab 	cit_PacketFormat2(gspca_dev, 0x39, 0x00);
16030c0d06caSMauro Carvalho Chehab 
16040c0d06caSMauro Carvalho Chehab 	for (i = 0; i < cit_model1_ntries; i++)
16050c0d06caSMauro Carvalho Chehab 		cit_Packet_Format1(gspca_dev, 0x00, 0x18);
16060c0d06caSMauro Carvalho Chehab 	for (i = 0; i < cit_model1_ntries; i++)
16070c0d06caSMauro Carvalho Chehab 		cit_Packet_Format1(gspca_dev, 0x13, 0x18);
16080c0d06caSMauro Carvalho Chehab 	for (i = 0; i < cit_model1_ntries; i++)
16090c0d06caSMauro Carvalho Chehab 		cit_Packet_Format1(gspca_dev, 0x14, 0x06);
16100c0d06caSMauro Carvalho Chehab 
16110c0d06caSMauro Carvalho Chehab 	/* TESTME These are handled through controls
16120c0d06caSMauro Carvalho Chehab 	   KEEP until someone can test leaving this out is ok */
16130c0d06caSMauro Carvalho Chehab 	if (0) {
16140c0d06caSMauro Carvalho Chehab 		/* This is default brightness */
16150c0d06caSMauro Carvalho Chehab 		for (i = 0; i < cit_model1_ntries; i++)
16160c0d06caSMauro Carvalho Chehab 			cit_Packet_Format1(gspca_dev, 0x31, 0x37);
16170c0d06caSMauro Carvalho Chehab 		for (i = 0; i < cit_model1_ntries; i++)
16180c0d06caSMauro Carvalho Chehab 			cit_Packet_Format1(gspca_dev, 0x32, 0x46);
16190c0d06caSMauro Carvalho Chehab 		for (i = 0; i < cit_model1_ntries; i++)
16200c0d06caSMauro Carvalho Chehab 			cit_Packet_Format1(gspca_dev, 0x33, 0x55);
16210c0d06caSMauro Carvalho Chehab 	}
16220c0d06caSMauro Carvalho Chehab 
16230c0d06caSMauro Carvalho Chehab 	cit_Packet_Format1(gspca_dev, 0x2e, 0x04);
16240c0d06caSMauro Carvalho Chehab 	for (i = 0; i < cit_model1_ntries; i++)
16250c0d06caSMauro Carvalho Chehab 		cit_Packet_Format1(gspca_dev, 0x2d, 0x04);
16260c0d06caSMauro Carvalho Chehab 	for (i = 0; i < cit_model1_ntries; i++)
16270c0d06caSMauro Carvalho Chehab 		cit_Packet_Format1(gspca_dev, 0x29, 0x80);
16280c0d06caSMauro Carvalho Chehab 	cit_Packet_Format1(gspca_dev, 0x2c, 0x01);
16290c0d06caSMauro Carvalho Chehab 	cit_Packet_Format1(gspca_dev, 0x30, 0x17);
16300c0d06caSMauro Carvalho Chehab 	cit_Packet_Format1(gspca_dev, 0x39, 0x08);
16310c0d06caSMauro Carvalho Chehab 	for (i = 0; i < cit_model1_ntries; i++)
16320c0d06caSMauro Carvalho Chehab 		cit_Packet_Format1(gspca_dev, 0x34, 0x00);
16330c0d06caSMauro Carvalho Chehab 
16340c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x00, 0x0101);
16350c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x00, 0x010a);
16360c0d06caSMauro Carvalho Chehab 
16371966bc2aSOndrej Zary 	switch (gspca_dev->pixfmt.width) {
16380c0d06caSMauro Carvalho Chehab 	case 128: /* 128x96 */
16390c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x80, 0x0103);
16400c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x60, 0x0105);
16410c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0c, 0x010b);
16420c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x04, 0x011b);	/* Same everywhere */
16430c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0b, 0x011d);
16440c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00, 0x011e);	/* Same everywhere */
16450c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00, 0x0129);
16460c0d06caSMauro Carvalho Chehab 		break;
16470c0d06caSMauro Carvalho Chehab 	case 176: /* 176x144 */
16480c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xb0, 0x0103);
16490c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x8f, 0x0105);
16500c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x06, 0x010b);
16510c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x04, 0x011b);	/* Same everywhere */
16520c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0d, 0x011d);
16530c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00, 0x011e);	/* Same everywhere */
16540c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x03, 0x0129);
16550c0d06caSMauro Carvalho Chehab 		break;
16560c0d06caSMauro Carvalho Chehab 	case 352: /* 352x288 */
16570c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xb0, 0x0103);
16580c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x90, 0x0105);
16590c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x02, 0x010b);
16600c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x04, 0x011b);	/* Same everywhere */
16610c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x05, 0x011d);
16620c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00, 0x011e);	/* Same everywhere */
16630c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00, 0x0129);
16640c0d06caSMauro Carvalho Chehab 		break;
16650c0d06caSMauro Carvalho Chehab 	}
16660c0d06caSMauro Carvalho Chehab 
16670c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0xff, 0x012b);
16680c0d06caSMauro Carvalho Chehab 
16690c0d06caSMauro Carvalho Chehab 	/* TESTME These are handled through controls
16700c0d06caSMauro Carvalho Chehab 	   KEEP until someone can test leaving this out is ok */
16710c0d06caSMauro Carvalho Chehab 	if (0) {
16720c0d06caSMauro Carvalho Chehab 		/* This is another brightness - don't know why */
16730c0d06caSMauro Carvalho Chehab 		for (i = 0; i < cit_model1_ntries; i++)
16740c0d06caSMauro Carvalho Chehab 			cit_Packet_Format1(gspca_dev, 0x31, 0xc3);
16750c0d06caSMauro Carvalho Chehab 		for (i = 0; i < cit_model1_ntries; i++)
16760c0d06caSMauro Carvalho Chehab 			cit_Packet_Format1(gspca_dev, 0x32, 0xd2);
16770c0d06caSMauro Carvalho Chehab 		for (i = 0; i < cit_model1_ntries; i++)
16780c0d06caSMauro Carvalho Chehab 			cit_Packet_Format1(gspca_dev, 0x33, 0xe1);
16790c0d06caSMauro Carvalho Chehab 
16800c0d06caSMauro Carvalho Chehab 		/* Default contrast */
16810c0d06caSMauro Carvalho Chehab 		for (i = 0; i < cit_model1_ntries; i++)
16820c0d06caSMauro Carvalho Chehab 			cit_Packet_Format1(gspca_dev, 0x14, 0x0a);
16830c0d06caSMauro Carvalho Chehab 
16840c0d06caSMauro Carvalho Chehab 		/* Default sharpness */
16850c0d06caSMauro Carvalho Chehab 		for (i = 0; i < cit_model1_ntries2; i++)
16860c0d06caSMauro Carvalho Chehab 			cit_PacketFormat2(gspca_dev, 0x13, 0x1a);
16870c0d06caSMauro Carvalho Chehab 
16880c0d06caSMauro Carvalho Chehab 		/* Default lighting conditions */
16890c0d06caSMauro Carvalho Chehab 		cit_Packet_Format1(gspca_dev, 0x0027,
16900c0d06caSMauro Carvalho Chehab 				   v4l2_ctrl_g_ctrl(sd->lighting));
16910c0d06caSMauro Carvalho Chehab 	}
16920c0d06caSMauro Carvalho Chehab 
16930c0d06caSMauro Carvalho Chehab 	/* Assorted init */
16941966bc2aSOndrej Zary 	switch (gspca_dev->pixfmt.width) {
16950c0d06caSMauro Carvalho Chehab 	case 128: /* 128x96 */
16960c0d06caSMauro Carvalho Chehab 		cit_Packet_Format1(gspca_dev, 0x2b, 0x1e);
16970c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xc9, 0x0119);	/* Same everywhere */
16980c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x80, 0x0109);	/* Same everywhere */
16990c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x36, 0x0102);
17000c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x1a, 0x0104);
17010c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x04, 0x011a);	/* Same everywhere */
17020c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x2b, 0x011c);
17030c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x23, 0x012a);	/* Same everywhere */
17040c0d06caSMauro Carvalho Chehab 		break;
17050c0d06caSMauro Carvalho Chehab 	case 176: /* 176x144 */
17060c0d06caSMauro Carvalho Chehab 		cit_Packet_Format1(gspca_dev, 0x2b, 0x1e);
17070c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xc9, 0x0119);	/* Same everywhere */
17080c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x80, 0x0109);	/* Same everywhere */
17090c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x04, 0x0102);
17100c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x02, 0x0104);
17110c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x04, 0x011a);	/* Same everywhere */
17120c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x2b, 0x011c);
17130c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x23, 0x012a);	/* Same everywhere */
17140c0d06caSMauro Carvalho Chehab 		break;
17150c0d06caSMauro Carvalho Chehab 	case 352: /* 352x288 */
17160c0d06caSMauro Carvalho Chehab 		cit_Packet_Format1(gspca_dev, 0x2b, 0x1f);
17170c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xc9, 0x0119);	/* Same everywhere */
17180c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x80, 0x0109);	/* Same everywhere */
17190c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x08, 0x0102);
17200c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x01, 0x0104);
17210c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x04, 0x011a);	/* Same everywhere */
17220c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x2f, 0x011c);
17230c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x23, 0x012a);	/* Same everywhere */
17240c0d06caSMauro Carvalho Chehab 		break;
17250c0d06caSMauro Carvalho Chehab 	}
17260c0d06caSMauro Carvalho Chehab 
17270c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x01, 0x0100);	/* LED On  */
17280c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, clock_div, 0x0111);
17290c0d06caSMauro Carvalho Chehab 
17300c0d06caSMauro Carvalho Chehab 	return 0;
17310c0d06caSMauro Carvalho Chehab }
17320c0d06caSMauro Carvalho Chehab 
cit_start_model2(struct gspca_dev * gspca_dev)17330c0d06caSMauro Carvalho Chehab static int cit_start_model2(struct gspca_dev *gspca_dev)
17340c0d06caSMauro Carvalho Chehab {
17350c0d06caSMauro Carvalho Chehab 	struct sd *sd = (struct sd *) gspca_dev;
17360c0d06caSMauro Carvalho Chehab 	int clock_div = 0;
17370c0d06caSMauro Carvalho Chehab 
17380c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0000, 0x0100);	/* LED on */
17390c0d06caSMauro Carvalho Chehab 	cit_read_reg(gspca_dev, 0x0116, 0);
17400c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0060, 0x0116);
17410c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0002, 0x0112);
17420c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x00bc, 0x012c);
17430c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0008, 0x012b);
17440c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0000, 0x0108);
17450c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0001, 0x0133);
17460c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0001, 0x0102);
17471966bc2aSOndrej Zary 	switch (gspca_dev->pixfmt.width) {
17480c0d06caSMauro Carvalho Chehab 	case 176: /* 176x144 */
17490c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x002c, 0x0103);	/* All except 320x240 */
17500c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0000, 0x0104);	/* Same */
17510c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0024, 0x0105);	/* 176x144, 352x288 */
17520c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00b9, 0x010a);	/* Unique to this mode */
17530c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0038, 0x0119);	/* Unique to this mode */
17540c0d06caSMauro Carvalho Chehab 		/* TESTME HDG: this does not seem right
17550c0d06caSMauro Carvalho Chehab 		   (it is 2 for all other resolutions) */
17560c0d06caSMauro Carvalho Chehab 		sd->sof_len = 10;
17570c0d06caSMauro Carvalho Chehab 		break;
17580c0d06caSMauro Carvalho Chehab 	case 320: /* 320x240 */
17590c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0028, 0x0103);	/* Unique to this mode */
17600c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0000, 0x0104);	/* Same */
17610c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x001e, 0x0105);	/* 320x240, 352x240 */
17620c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0039, 0x010a);	/* All except 176x144 */
17630c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0070, 0x0119);	/* All except 176x144 */
17640c0d06caSMauro Carvalho Chehab 		sd->sof_len = 2;
17650c0d06caSMauro Carvalho Chehab 		break;
1766cd65d24eSMauro Carvalho Chehab #if 0
1767cd65d24eSMauro Carvalho Chehab 	case VIDEOSIZE_352x240:
17680c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x002c, 0x0103);	/* All except 320x240 */
17690c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0000, 0x0104);	/* Same */
17700c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x001e, 0x0105);	/* 320x240, 352x240 */
17710c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0039, 0x010a);	/* All except 176x144 */
17720c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0070, 0x0119);	/* All except 176x144 */
17730c0d06caSMauro Carvalho Chehab 		sd->sof_len = 2;
17740c0d06caSMauro Carvalho Chehab 		break;
1775cd65d24eSMauro Carvalho Chehab #endif
17760c0d06caSMauro Carvalho Chehab 	case 352: /* 352x288 */
17770c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x002c, 0x0103);	/* All except 320x240 */
17780c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0000, 0x0104);	/* Same */
17790c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0024, 0x0105);	/* 176x144, 352x288 */
17800c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0039, 0x010a);	/* All except 176x144 */
17810c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0070, 0x0119);	/* All except 176x144 */
17820c0d06caSMauro Carvalho Chehab 		sd->sof_len = 2;
17830c0d06caSMauro Carvalho Chehab 		break;
17840c0d06caSMauro Carvalho Chehab 	}
17850c0d06caSMauro Carvalho Chehab 
17860c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0000, 0x0100);	/* LED on */
17870c0d06caSMauro Carvalho Chehab 
17881966bc2aSOndrej Zary 	switch (gspca_dev->pixfmt.width) {
17890c0d06caSMauro Carvalho Chehab 	case 176: /* 176x144 */
17900c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0050, 0x0111);
17910c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00d0, 0x0111);
17920c0d06caSMauro Carvalho Chehab 		break;
17930c0d06caSMauro Carvalho Chehab 	case 320: /* 320x240 */
17940c0d06caSMauro Carvalho Chehab 	case 352: /* 352x288 */
17950c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0040, 0x0111);
17960c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00c0, 0x0111);
17970c0d06caSMauro Carvalho Chehab 		break;
17980c0d06caSMauro Carvalho Chehab 	}
17990c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x009b, 0x010f);
18000c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x00bb, 0x010f);
18010c0d06caSMauro Carvalho Chehab 
18020c0d06caSMauro Carvalho Chehab 	/*
18030c0d06caSMauro Carvalho Chehab 	 * Hardware settings, may affect CMOS sensor; not user controls!
18040c0d06caSMauro Carvalho Chehab 	 * -------------------------------------------------------------
18050c0d06caSMauro Carvalho Chehab 	 * 0x0004: no effect
18060c0d06caSMauro Carvalho Chehab 	 * 0x0006: hardware effect
18070c0d06caSMauro Carvalho Chehab 	 * 0x0008: no effect
18080c0d06caSMauro Carvalho Chehab 	 * 0x000a: stops video stream, probably important h/w setting
18090c0d06caSMauro Carvalho Chehab 	 * 0x000c: changes color in hardware manner (not user setting)
18100c0d06caSMauro Carvalho Chehab 	 * 0x0012: changes number of colors (does not affect speed)
18110c0d06caSMauro Carvalho Chehab 	 * 0x002a: no effect
18120c0d06caSMauro Carvalho Chehab 	 * 0x002c: hardware setting (related to scan lines)
18130c0d06caSMauro Carvalho Chehab 	 * 0x002e: stops video stream, probably important h/w setting
18140c0d06caSMauro Carvalho Chehab 	 */
18150c0d06caSMauro Carvalho Chehab 	cit_model2_Packet1(gspca_dev, 0x000a, 0x005c);
18160c0d06caSMauro Carvalho Chehab 	cit_model2_Packet1(gspca_dev, 0x0004, 0x0000);
18170c0d06caSMauro Carvalho Chehab 	cit_model2_Packet1(gspca_dev, 0x0006, 0x00fb);
18180c0d06caSMauro Carvalho Chehab 	cit_model2_Packet1(gspca_dev, 0x0008, 0x0000);
18190c0d06caSMauro Carvalho Chehab 	cit_model2_Packet1(gspca_dev, 0x000c, 0x0009);
18200c0d06caSMauro Carvalho Chehab 	cit_model2_Packet1(gspca_dev, 0x0012, 0x000a);
18210c0d06caSMauro Carvalho Chehab 	cit_model2_Packet1(gspca_dev, 0x002a, 0x0000);
18220c0d06caSMauro Carvalho Chehab 	cit_model2_Packet1(gspca_dev, 0x002c, 0x0000);
18230c0d06caSMauro Carvalho Chehab 	cit_model2_Packet1(gspca_dev, 0x002e, 0x0008);
18240c0d06caSMauro Carvalho Chehab 
18250c0d06caSMauro Carvalho Chehab 	/*
18260c0d06caSMauro Carvalho Chehab 	 * Function 0x0030 pops up all over the place. Apparently
18270c0d06caSMauro Carvalho Chehab 	 * it is a hardware control register, with every bit assigned to
18280c0d06caSMauro Carvalho Chehab 	 * do something.
18290c0d06caSMauro Carvalho Chehab 	 */
18300c0d06caSMauro Carvalho Chehab 	cit_model2_Packet1(gspca_dev, 0x0030, 0x0000);
18310c0d06caSMauro Carvalho Chehab 
18320c0d06caSMauro Carvalho Chehab 	/*
18330c0d06caSMauro Carvalho Chehab 	 * Magic control of CMOS sensor. Only lower values like
18340c0d06caSMauro Carvalho Chehab 	 * 0-3 work, and picture shifts left or right. Don't change.
18350c0d06caSMauro Carvalho Chehab 	 */
18361966bc2aSOndrej Zary 	switch (gspca_dev->pixfmt.width) {
18370c0d06caSMauro Carvalho Chehab 	case 176: /* 176x144 */
18380c0d06caSMauro Carvalho Chehab 		cit_model2_Packet1(gspca_dev, 0x0014, 0x0002);
18390c0d06caSMauro Carvalho Chehab 		cit_model2_Packet1(gspca_dev, 0x0016, 0x0002); /* Horizontal shift */
18400c0d06caSMauro Carvalho Chehab 		cit_model2_Packet1(gspca_dev, 0x0018, 0x004a); /* Another hardware setting */
18410c0d06caSMauro Carvalho Chehab 		clock_div = 6;
18420c0d06caSMauro Carvalho Chehab 		break;
18430c0d06caSMauro Carvalho Chehab 	case 320: /* 320x240 */
18440c0d06caSMauro Carvalho Chehab 		cit_model2_Packet1(gspca_dev, 0x0014, 0x0009);
18450c0d06caSMauro Carvalho Chehab 		cit_model2_Packet1(gspca_dev, 0x0016, 0x0005); /* Horizontal shift */
18460c0d06caSMauro Carvalho Chehab 		cit_model2_Packet1(gspca_dev, 0x0018, 0x0044); /* Another hardware setting */
18470c0d06caSMauro Carvalho Chehab 		clock_div = 8;
18480c0d06caSMauro Carvalho Chehab 		break;
1849cd65d24eSMauro Carvalho Chehab #if 0
1850cd65d24eSMauro Carvalho Chehab 	case VIDEOSIZE_352x240:
18510c0d06caSMauro Carvalho Chehab 		/* This mode doesn't work as Windows programs it; changed to work */
18520c0d06caSMauro Carvalho Chehab 		cit_model2_Packet1(gspca_dev, 0x0014, 0x0009); /* Windows sets this to 8 */
18530c0d06caSMauro Carvalho Chehab 		cit_model2_Packet1(gspca_dev, 0x0016, 0x0003); /* Horizontal shift */
18540c0d06caSMauro Carvalho Chehab 		cit_model2_Packet1(gspca_dev, 0x0018, 0x0044); /* Windows sets this to 0x0045 */
18550c0d06caSMauro Carvalho Chehab 		clock_div = 10;
18560c0d06caSMauro Carvalho Chehab 		break;
1857cd65d24eSMauro Carvalho Chehab #endif
18580c0d06caSMauro Carvalho Chehab 	case 352: /* 352x288 */
18590c0d06caSMauro Carvalho Chehab 		cit_model2_Packet1(gspca_dev, 0x0014, 0x0003);
18600c0d06caSMauro Carvalho Chehab 		cit_model2_Packet1(gspca_dev, 0x0016, 0x0002); /* Horizontal shift */
18610c0d06caSMauro Carvalho Chehab 		cit_model2_Packet1(gspca_dev, 0x0018, 0x004a); /* Another hardware setting */
18620c0d06caSMauro Carvalho Chehab 		clock_div = 16;
18630c0d06caSMauro Carvalho Chehab 		break;
18640c0d06caSMauro Carvalho Chehab 	}
18650c0d06caSMauro Carvalho Chehab 
18660c0d06caSMauro Carvalho Chehab 	/* TESTME These are handled through controls
18670c0d06caSMauro Carvalho Chehab 	   KEEP until someone can test leaving this out is ok */
18680c0d06caSMauro Carvalho Chehab 	if (0)
18690c0d06caSMauro Carvalho Chehab 		cit_model2_Packet1(gspca_dev, 0x001a, 0x005a);
18700c0d06caSMauro Carvalho Chehab 
18710c0d06caSMauro Carvalho Chehab 	/*
18720c0d06caSMauro Carvalho Chehab 	 * We have our own frame rate setting varying from 0 (slowest) to 6
18730c0d06caSMauro Carvalho Chehab 	 * (fastest). The camera model 2 allows frame rate in range [0..0x1F]
18740c0d06caSMauro Carvalho Chehab 	 # where 0 is also the slowest setting. However for all practical
18750c0d06caSMauro Carvalho Chehab 	 # reasons high settings make no sense because USB is not fast enough
18760c0d06caSMauro Carvalho Chehab 	 # to support high FPS. Be aware that the picture datastream will be
18770c0d06caSMauro Carvalho Chehab 	 # severely disrupted if you ask for frame rate faster than allowed
18780c0d06caSMauro Carvalho Chehab 	 # for the video size - see below:
18790c0d06caSMauro Carvalho Chehab 	 *
18800c0d06caSMauro Carvalho Chehab 	 * Allowable ranges (obtained experimentally on OHCI, K6-3, 450 MHz):
18810c0d06caSMauro Carvalho Chehab 	 * -----------------------------------------------------------------
18820c0d06caSMauro Carvalho Chehab 	 * 176x144: [6..31]
18830c0d06caSMauro Carvalho Chehab 	 * 320x240: [8..31]
18840c0d06caSMauro Carvalho Chehab 	 * 352x240: [10..31]
18850c0d06caSMauro Carvalho Chehab 	 * 352x288: [16..31] I have to raise lower threshold for stability...
18860c0d06caSMauro Carvalho Chehab 	 *
18870c0d06caSMauro Carvalho Chehab 	 * As usual, slower FPS provides better sensitivity.
18880c0d06caSMauro Carvalho Chehab 	 */
18890c0d06caSMauro Carvalho Chehab 	cit_model2_Packet1(gspca_dev, 0x001c, clock_div);
18900c0d06caSMauro Carvalho Chehab 
18910c0d06caSMauro Carvalho Chehab 	/*
18920c0d06caSMauro Carvalho Chehab 	 * This setting does not visibly affect pictures; left it here
18930c0d06caSMauro Carvalho Chehab 	 * because it was present in Windows USB data stream. This function
18940c0d06caSMauro Carvalho Chehab 	 * does not allow arbitrary values and apparently is a bit mask, to
18950c0d06caSMauro Carvalho Chehab 	 * be activated only at appropriate time. Don't change it randomly!
18960c0d06caSMauro Carvalho Chehab 	 */
18971966bc2aSOndrej Zary 	switch (gspca_dev->pixfmt.width) {
18980c0d06caSMauro Carvalho Chehab 	case 176: /* 176x144 */
18990c0d06caSMauro Carvalho Chehab 		cit_model2_Packet1(gspca_dev, 0x0026, 0x00c2);
19000c0d06caSMauro Carvalho Chehab 		break;
19010c0d06caSMauro Carvalho Chehab 	case 320: /* 320x240 */
19020c0d06caSMauro Carvalho Chehab 		cit_model2_Packet1(gspca_dev, 0x0026, 0x0044);
19030c0d06caSMauro Carvalho Chehab 		break;
1904cd65d24eSMauro Carvalho Chehab #if 0
1905cd65d24eSMauro Carvalho Chehab 	case VIDEOSIZE_352x240:
19060c0d06caSMauro Carvalho Chehab 		cit_model2_Packet1(gspca_dev, 0x0026, 0x0046);
19070c0d06caSMauro Carvalho Chehab 		break;
1908cd65d24eSMauro Carvalho Chehab #endif
19090c0d06caSMauro Carvalho Chehab 	case 352: /* 352x288 */
19100c0d06caSMauro Carvalho Chehab 		cit_model2_Packet1(gspca_dev, 0x0026, 0x0048);
19110c0d06caSMauro Carvalho Chehab 		break;
19120c0d06caSMauro Carvalho Chehab 	}
19130c0d06caSMauro Carvalho Chehab 
19140c0d06caSMauro Carvalho Chehab 	cit_model2_Packet1(gspca_dev, 0x0028, v4l2_ctrl_g_ctrl(sd->lighting));
19150c0d06caSMauro Carvalho Chehab 	/* model2 cannot change the backlight compensation while streaming */
19160c0d06caSMauro Carvalho Chehab 	v4l2_ctrl_grab(sd->lighting, true);
19170c0d06caSMauro Carvalho Chehab 
19180c0d06caSMauro Carvalho Chehab 	/* color balance rg2 */
19190c0d06caSMauro Carvalho Chehab 	cit_model2_Packet1(gspca_dev, 0x001e, 0x002f);
19200c0d06caSMauro Carvalho Chehab 	/* saturation */
19210c0d06caSMauro Carvalho Chehab 	cit_model2_Packet1(gspca_dev, 0x0020, 0x0034);
19220c0d06caSMauro Carvalho Chehab 	/* color balance yb */
19230c0d06caSMauro Carvalho Chehab 	cit_model2_Packet1(gspca_dev, 0x0022, 0x00a0);
19240c0d06caSMauro Carvalho Chehab 
19250c0d06caSMauro Carvalho Chehab 	/* Hardware control command */
19260c0d06caSMauro Carvalho Chehab 	cit_model2_Packet1(gspca_dev, 0x0030, 0x0004);
19270c0d06caSMauro Carvalho Chehab 
19280c0d06caSMauro Carvalho Chehab 	return 0;
19290c0d06caSMauro Carvalho Chehab }
19300c0d06caSMauro Carvalho Chehab 
cit_start_model3(struct gspca_dev * gspca_dev)19310c0d06caSMauro Carvalho Chehab static int cit_start_model3(struct gspca_dev *gspca_dev)
19320c0d06caSMauro Carvalho Chehab {
19330c0d06caSMauro Carvalho Chehab 	const unsigned short compression = 0; /* 0=none, 7=best frame rate */
19340c0d06caSMauro Carvalho Chehab 	int i, clock_div = 0;
19350c0d06caSMauro Carvalho Chehab 
19360c0d06caSMauro Carvalho Chehab 	/* HDG not in ibmcam driver, added to see if it helps with
19370c0d06caSMauro Carvalho Chehab 	   auto-detecting between model3 and ibm netcamera pro */
19380c0d06caSMauro Carvalho Chehab 	cit_read_reg(gspca_dev, 0x128, 1);
19390c0d06caSMauro Carvalho Chehab 
19400c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0000, 0x0100);
19410c0d06caSMauro Carvalho Chehab 	cit_read_reg(gspca_dev, 0x0116, 0);
19420c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0060, 0x0116);
19430c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0002, 0x0112);
19440c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0000, 0x0123);
19450c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0001, 0x0117);
19460c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0040, 0x0108);
19470c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0019, 0x012c);
19480c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0060, 0x0116);
19490c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0002, 0x0115);
19500c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0003, 0x0115);
19510c0d06caSMauro Carvalho Chehab 	cit_read_reg(gspca_dev, 0x0115, 0);
19520c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x000b, 0x0115);
19530c0d06caSMauro Carvalho Chehab 
19540c0d06caSMauro Carvalho Chehab 	/* TESTME HDG not in ibmcam driver, added to see if it helps with
19550c0d06caSMauro Carvalho Chehab 	   auto-detecting between model3 and ibm netcamera pro */
19560c0d06caSMauro Carvalho Chehab 	if (0) {
19570c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0078, 0x012d);
19580c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0001, 0x012f);
19590c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xd141, 0x0124);
19600c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0079, 0x012d);
19610c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00ff, 0x0130);
19620c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xcd41, 0x0124);
19630c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xfffa, 0x0124);
19640c0d06caSMauro Carvalho Chehab 		cit_read_reg(gspca_dev, 0x0126, 1);
19650c0d06caSMauro Carvalho Chehab 	}
19660c0d06caSMauro Carvalho Chehab 
19670c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x000a, 0x0040);
19680c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x000b, 0x00f6);
19690c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x000c, 0x0002);
19700c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x000d, 0x0020);
19710c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x000e, 0x0033);
19720c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x000f, 0x0007);
19730c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0010, 0x0000);
19740c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0011, 0x0070);
19750c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0012, 0x0030);
19760c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0013, 0x0000);
19770c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0014, 0x0001);
19780c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0015, 0x0001);
19790c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0016, 0x0001);
19800c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0017, 0x0001);
19810c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0018, 0x0000);
19820c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x001e, 0x00c3);
19830c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0020, 0x0000);
19840c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0028, 0x0010);
19850c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0029, 0x0054);
19860c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x002a, 0x0013);
19870c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x002b, 0x0007);
19880c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x002d, 0x0028);
19890c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x002e, 0x0000);
19900c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0031, 0x0000);
19910c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0032, 0x0000);
19920c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0033, 0x0000);
19930c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0034, 0x0000);
19940c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0035, 0x0038);
19950c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x003a, 0x0001);
19960c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x003c, 0x001e);
19970c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x003f, 0x000a);
19980c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0041, 0x0000);
19990c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0046, 0x003f);
20000c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0047, 0x0000);
20010c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0050, 0x0005);
20020c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0052, 0x001a);
20030c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0053, 0x0003);
20040c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x005a, 0x006b);
20050c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x005d, 0x001e);
20060c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x005e, 0x0030);
20070c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x005f, 0x0041);
20080c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0064, 0x0008);
20090c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0065, 0x0015);
20100c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0068, 0x000f);
20110c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0079, 0x0000);
20120c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x007a, 0x0000);
20130c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x007c, 0x003f);
20140c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0082, 0x000f);
20150c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0085, 0x0000);
20160c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0099, 0x0000);
20170c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x009b, 0x0023);
20180c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x009c, 0x0022);
20190c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x009d, 0x0096);
20200c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x009e, 0x0096);
20210c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x009f, 0x000a);
20220c0d06caSMauro Carvalho Chehab 
20231966bc2aSOndrej Zary 	switch (gspca_dev->pixfmt.width) {
20240c0d06caSMauro Carvalho Chehab 	case 160:
20250c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0000, 0x0101); /* Same on 160x120, 320x240 */
20260c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00a0, 0x0103); /* Same on 160x120, 320x240 */
20270c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0078, 0x0105); /* Same on 160x120, 320x240 */
20280c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0000, 0x010a); /* Same */
20290c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0024, 0x010b); /* Differs everywhere */
20300c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00a9, 0x0119);
20310c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0016, 0x011b);
20320c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0002, 0x011d); /* Same on 160x120, 320x240 */
20330c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0003, 0x011e); /* Same on 160x120, 640x480 */
20340c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0000, 0x0129); /* Same */
20350c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00fc, 0x012b); /* Same */
20360c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0018, 0x0102);
20370c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0004, 0x0104);
20380c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0004, 0x011a);
20390c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0028, 0x011c);
20400c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0022, 0x012a); /* Same */
20410c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0000, 0x0118);
20420c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0000, 0x0132);
20430c0d06caSMauro Carvalho Chehab 		cit_model3_Packet1(gspca_dev, 0x0021, 0x0001); /* Same */
20440c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, compression, 0x0109);
20450c0d06caSMauro Carvalho Chehab 		clock_div = 3;
20460c0d06caSMauro Carvalho Chehab 		break;
20470c0d06caSMauro Carvalho Chehab 	case 320:
20480c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0000, 0x0101); /* Same on 160x120, 320x240 */
20490c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00a0, 0x0103); /* Same on 160x120, 320x240 */
20500c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0078, 0x0105); /* Same on 160x120, 320x240 */
20510c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0000, 0x010a); /* Same */
20520c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0028, 0x010b); /* Differs everywhere */
20530c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0002, 0x011d); /* Same */
20540c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0000, 0x011e);
20550c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0000, 0x0129); /* Same */
20560c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00fc, 0x012b); /* Same */
20570c0d06caSMauro Carvalho Chehab 		/* 4 commands from 160x120 skipped */
20580c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0022, 0x012a); /* Same */
20590c0d06caSMauro Carvalho Chehab 		cit_model3_Packet1(gspca_dev, 0x0021, 0x0001); /* Same */
20600c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, compression, 0x0109);
20610c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00d9, 0x0119);
20620c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0006, 0x011b);
20630c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0021, 0x0102); /* Same on 320x240, 640x480 */
20640c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0010, 0x0104);
20650c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0004, 0x011a);
20660c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x003f, 0x011c);
20670c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x001c, 0x0118);
20680c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0000, 0x0132);
20690c0d06caSMauro Carvalho Chehab 		clock_div = 5;
20700c0d06caSMauro Carvalho Chehab 		break;
20710c0d06caSMauro Carvalho Chehab 	case 640:
20720c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00f0, 0x0105);
20730c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0000, 0x010a); /* Same */
20740c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0038, 0x010b); /* Differs everywhere */
20750c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00d9, 0x0119); /* Same on 320x240, 640x480 */
20760c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0006, 0x011b); /* Same on 320x240, 640x480 */
20770c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0004, 0x011d); /* NC */
20780c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0003, 0x011e); /* Same on 160x120, 640x480 */
20790c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0000, 0x0129); /* Same */
20800c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00fc, 0x012b); /* Same */
20810c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0021, 0x0102); /* Same on 320x240, 640x480 */
20820c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0016, 0x0104); /* NC */
20830c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0004, 0x011a); /* Same on 320x240, 640x480 */
20840c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x003f, 0x011c); /* Same on 320x240, 640x480 */
20850c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0022, 0x012a); /* Same */
20860c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x001c, 0x0118); /* Same on 320x240, 640x480 */
20870c0d06caSMauro Carvalho Chehab 		cit_model3_Packet1(gspca_dev, 0x0021, 0x0001); /* Same */
20880c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, compression, 0x0109);
20890c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0040, 0x0101);
20900c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0040, 0x0103);
20910c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0000, 0x0132); /* Same on 320x240, 640x480 */
20920c0d06caSMauro Carvalho Chehab 		clock_div = 7;
20930c0d06caSMauro Carvalho Chehab 		break;
20940c0d06caSMauro Carvalho Chehab 	}
20950c0d06caSMauro Carvalho Chehab 
20960c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x007e, 0x000e);	/* Hue */
20970c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0036, 0x0011);	/* Brightness */
20980c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0060, 0x0002);	/* Sharpness */
20990c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0061, 0x0004);	/* Sharpness */
21000c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0062, 0x0005);	/* Sharpness */
21010c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0063, 0x0014);	/* Sharpness */
21020c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0096, 0x00a0);	/* Red sharpness */
21030c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0097, 0x0096);	/* Blue sharpness */
21040c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0067, 0x0001);	/* Contrast */
21050c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x005b, 0x000c);	/* Contrast */
21060c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x005c, 0x0016);	/* Contrast */
21070c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0098, 0x000b);
21080c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x002c, 0x0003);	/* Was 1, broke 640x480 */
21090c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x002f, 0x002a);
21100c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0030, 0x0029);
21110c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0037, 0x0002);
21120c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0038, 0x0059);
21130c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x003d, 0x002e);
21140c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x003e, 0x0028);
21150c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0078, 0x0005);
21160c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x007b, 0x0011);
21170c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x007d, 0x004b);
21180c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x007f, 0x0022);
21190c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0080, 0x000c);
21200c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0081, 0x000b);
21210c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0083, 0x00fd);
21220c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0086, 0x000b);
21230c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0087, 0x000b);
21240c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x007e, 0x000e);
21250c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0096, 0x00a0);	/* Red sharpness */
21260c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0097, 0x0096);	/* Blue sharpness */
21270c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0098, 0x000b);
21280c0d06caSMauro Carvalho Chehab 
21290c0d06caSMauro Carvalho Chehab 	/* FIXME we should probably use cit_get_clock_div() here (in
21300c0d06caSMauro Carvalho Chehab 	   combination with isoc negotiation using the programmable isoc size)
21310c0d06caSMauro Carvalho Chehab 	   like with the IBM netcam pro). */
21320c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, clock_div, 0x0111); /* Clock Divider */
21330c0d06caSMauro Carvalho Chehab 
21341966bc2aSOndrej Zary 	switch (gspca_dev->pixfmt.width) {
21350c0d06caSMauro Carvalho Chehab 	case 160:
21360c0d06caSMauro Carvalho Chehab 		cit_model3_Packet1(gspca_dev, 0x001f, 0x0000); /* Same */
21370c0d06caSMauro Carvalho Chehab 		cit_model3_Packet1(gspca_dev, 0x0039, 0x001f); /* Same */
21380c0d06caSMauro Carvalho Chehab 		cit_model3_Packet1(gspca_dev, 0x003b, 0x003c); /* Same */
21390c0d06caSMauro Carvalho Chehab 		cit_model3_Packet1(gspca_dev, 0x0040, 0x000a);
21400c0d06caSMauro Carvalho Chehab 		cit_model3_Packet1(gspca_dev, 0x0051, 0x000a);
21410c0d06caSMauro Carvalho Chehab 		break;
21420c0d06caSMauro Carvalho Chehab 	case 320:
21430c0d06caSMauro Carvalho Chehab 		cit_model3_Packet1(gspca_dev, 0x001f, 0x0000); /* Same */
21440c0d06caSMauro Carvalho Chehab 		cit_model3_Packet1(gspca_dev, 0x0039, 0x001f); /* Same */
21450c0d06caSMauro Carvalho Chehab 		cit_model3_Packet1(gspca_dev, 0x003b, 0x003c); /* Same */
21460c0d06caSMauro Carvalho Chehab 		cit_model3_Packet1(gspca_dev, 0x0040, 0x0008);
21470c0d06caSMauro Carvalho Chehab 		cit_model3_Packet1(gspca_dev, 0x0051, 0x000b);
21480c0d06caSMauro Carvalho Chehab 		break;
21490c0d06caSMauro Carvalho Chehab 	case 640:
21500c0d06caSMauro Carvalho Chehab 		cit_model3_Packet1(gspca_dev, 0x001f, 0x0002);	/* !Same */
21510c0d06caSMauro Carvalho Chehab 		cit_model3_Packet1(gspca_dev, 0x0039, 0x003e);	/* !Same */
21520c0d06caSMauro Carvalho Chehab 		cit_model3_Packet1(gspca_dev, 0x0040, 0x0008);
21530c0d06caSMauro Carvalho Chehab 		cit_model3_Packet1(gspca_dev, 0x0051, 0x000a);
21540c0d06caSMauro Carvalho Chehab 		break;
21550c0d06caSMauro Carvalho Chehab 	}
21560c0d06caSMauro Carvalho Chehab 
21570c0d06caSMauro Carvalho Chehab /*	if (sd->input_index) { */
21580c0d06caSMauro Carvalho Chehab 	if (rca_input) {
21590c0d06caSMauro Carvalho Chehab 		for (i = 0; i < ARRAY_SIZE(rca_initdata); i++) {
21600c0d06caSMauro Carvalho Chehab 			if (rca_initdata[i][0])
21610c0d06caSMauro Carvalho Chehab 				cit_read_reg(gspca_dev, rca_initdata[i][2], 0);
21620c0d06caSMauro Carvalho Chehab 			else
21630c0d06caSMauro Carvalho Chehab 				cit_write_reg(gspca_dev, rca_initdata[i][1],
21640c0d06caSMauro Carvalho Chehab 					      rca_initdata[i][2]);
21650c0d06caSMauro Carvalho Chehab 		}
21660c0d06caSMauro Carvalho Chehab 	}
21670c0d06caSMauro Carvalho Chehab 
21680c0d06caSMauro Carvalho Chehab 	return 0;
21690c0d06caSMauro Carvalho Chehab }
21700c0d06caSMauro Carvalho Chehab 
cit_start_model4(struct gspca_dev * gspca_dev)21710c0d06caSMauro Carvalho Chehab static int cit_start_model4(struct gspca_dev *gspca_dev)
21720c0d06caSMauro Carvalho Chehab {
21730c0d06caSMauro Carvalho Chehab 	struct sd *sd = (struct sd *) gspca_dev;
21740c0d06caSMauro Carvalho Chehab 
21750c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0000, 0x0100);
21760c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x00c0, 0x0111);
21770c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x00bc, 0x012c);
21780c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0080, 0x012b);
21790c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0000, 0x0108);
21800c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0001, 0x0133);
21810c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x009b, 0x010f);
21820c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x00bb, 0x010f);
21830c0d06caSMauro Carvalho Chehab 	cit_model4_Packet1(gspca_dev, 0x0038, 0x0000);
21840c0d06caSMauro Carvalho Chehab 	cit_model4_Packet1(gspca_dev, 0x000a, 0x005c);
21850c0d06caSMauro Carvalho Chehab 
21860c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x00aa, 0x012d);
21870c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0004, 0x012f);
21880c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0xd141, 0x0124);
21890c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0000, 0x0127);
21900c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x00fb, 0x012e);
21910c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0000, 0x0130);
21920c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x8a28, 0x0124);
21930c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x00aa, 0x012f);
21940c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0xd055, 0x0124);
21950c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x000c, 0x0127);
21960c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0009, 0x012e);
21970c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0xaa28, 0x0124);
21980c0d06caSMauro Carvalho Chehab 
21990c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x00aa, 0x012d);
22000c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0012, 0x012f);
22010c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0xd141, 0x0124);
22020c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0008, 0x0127);
22030c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x00aa, 0x0130);
22040c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x82a8, 0x0124);
22050c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x002a, 0x012d);
22060c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0000, 0x012f);
22070c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0xd145, 0x0124);
22080c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0xfffa, 0x0124);
22090c0d06caSMauro Carvalho Chehab 	cit_model4_Packet1(gspca_dev, 0x0034, 0x0000);
22100c0d06caSMauro Carvalho Chehab 
22111966bc2aSOndrej Zary 	switch (gspca_dev->pixfmt.width) {
22120c0d06caSMauro Carvalho Chehab 	case 128: /* 128x96 */
22130c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0070, 0x0119);
22140c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00d0, 0x0111);
22150c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0039, 0x010a);
22160c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0001, 0x0102);
22170c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0028, 0x0103);
22180c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0000, 0x0104);
22190c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x001e, 0x0105);
22200c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
22210c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0016, 0x012f);
22220c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xd141, 0x0124);
22230c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x000a, 0x0127);
22240c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00aa, 0x0130);
22250c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x82a8, 0x0124);
22260c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0014, 0x012d);
22270c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0008, 0x012f);
22280c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xd145, 0x0124);
22290c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00aa, 0x012e);
22300c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x001a, 0x0130);
22310c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x8a0a, 0x0124);
22320c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x005a, 0x012d);
22330c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x9545, 0x0124);
22340c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00aa, 0x0127);
22350c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0018, 0x012e);
22360c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0043, 0x0130);
22370c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x8a28, 0x0124);
22380c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00aa, 0x012f);
22390c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xd055, 0x0124);
22400c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x001c, 0x0127);
22410c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00eb, 0x012e);
22420c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xaa28, 0x0124);
22430c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
22440c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0032, 0x012f);
22450c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xd141, 0x0124);
22460c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0000, 0x0127);
22470c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00aa, 0x0130);
22480c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x82a8, 0x0124);
22490c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0036, 0x012d);
22500c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0008, 0x012f);
22510c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xd145, 0x0124);
22520c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xfffa, 0x0124);
22530c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
22540c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x001e, 0x012f);
22550c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xd141, 0x0124);
22560c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0017, 0x0127);
22570c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0013, 0x012e);
22580c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0031, 0x0130);
22590c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x8a28, 0x0124);
22600c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0017, 0x012d);
22610c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0078, 0x012f);
22620c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xd145, 0x0124);
22630c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0000, 0x0127);
22640c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xfea8, 0x0124);
22650c0d06caSMauro Carvalho Chehab 		sd->sof_len = 2;
22660c0d06caSMauro Carvalho Chehab 		break;
22670c0d06caSMauro Carvalho Chehab 	case 160: /* 160x120 */
22680c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0038, 0x0119);
22690c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00d0, 0x0111);
22700c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00b9, 0x010a);
22710c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0001, 0x0102);
22720c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0028, 0x0103);
22730c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0000, 0x0104);
22740c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x001e, 0x0105);
22750c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
22760c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0016, 0x012f);
22770c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xd141, 0x0124);
22780c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x000b, 0x0127);
22790c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00aa, 0x0130);
22800c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x82a8, 0x0124);
22810c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0014, 0x012d);
22820c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0008, 0x012f);
22830c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xd145, 0x0124);
22840c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00aa, 0x012e);
22850c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x001a, 0x0130);
22860c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x8a0a, 0x0124);
22870c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x005a, 0x012d);
22880c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x9545, 0x0124);
22890c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00aa, 0x0127);
22900c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0018, 0x012e);
22910c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0043, 0x0130);
22920c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x8a28, 0x0124);
22930c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00aa, 0x012f);
22940c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xd055, 0x0124);
22950c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x001c, 0x0127);
22960c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00c7, 0x012e);
22970c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xaa28, 0x0124);
22980c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
22990c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0032, 0x012f);
23000c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xd141, 0x0124);
23010c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0025, 0x0127);
23020c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00aa, 0x0130);
23030c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x82a8, 0x0124);
23040c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0036, 0x012d);
23050c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0008, 0x012f);
23060c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xd145, 0x0124);
23070c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xfffa, 0x0124);
23080c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
23090c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x001e, 0x012f);
23100c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xd141, 0x0124);
23110c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0048, 0x0127);
23120c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0035, 0x012e);
23130c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00d0, 0x0130);
23140c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x8a28, 0x0124);
23150c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0048, 0x012d);
23160c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0090, 0x012f);
23170c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xd145, 0x0124);
23180c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0001, 0x0127);
23190c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xfea8, 0x0124);
23200c0d06caSMauro Carvalho Chehab 		sd->sof_len = 2;
23210c0d06caSMauro Carvalho Chehab 		break;
23220c0d06caSMauro Carvalho Chehab 	case 176: /* 176x144 */
23230c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0038, 0x0119);
23240c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00d0, 0x0111);
23250c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00b9, 0x010a);
23260c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0001, 0x0102);
23270c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x002c, 0x0103);
23280c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0000, 0x0104);
23290c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0024, 0x0105);
23300c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
23310c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0016, 0x012f);
23320c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xd141, 0x0124);
23330c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0007, 0x0127);
23340c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00aa, 0x0130);
23350c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x82a8, 0x0124);
23360c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0014, 0x012d);
23370c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0001, 0x012f);
23380c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xd145, 0x0124);
23390c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00aa, 0x012e);
23400c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x001a, 0x0130);
23410c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x8a0a, 0x0124);
23420c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x005e, 0x012d);
23430c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x9545, 0x0124);
23440c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00aa, 0x0127);
23450c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0018, 0x012e);
23460c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0049, 0x0130);
23470c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x8a28, 0x0124);
23480c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00aa, 0x012f);
23490c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xd055, 0x0124);
23500c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x001c, 0x0127);
23510c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00c7, 0x012e);
23520c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xaa28, 0x0124);
23530c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
23540c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0032, 0x012f);
23550c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xd141, 0x0124);
23560c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0028, 0x0127);
23570c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00aa, 0x0130);
23580c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x82a8, 0x0124);
23590c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0036, 0x012d);
23600c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0008, 0x012f);
23610c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xd145, 0x0124);
23620c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xfffa, 0x0124);
23630c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
23640c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x001e, 0x012f);
23650c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xd141, 0x0124);
23660c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0010, 0x0127);
23670c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0013, 0x012e);
23680c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x002a, 0x0130);
23690c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x8a28, 0x0124);
23700c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0010, 0x012d);
23710c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x006d, 0x012f);
23720c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xd145, 0x0124);
23730c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0001, 0x0127);
23740c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xfea8, 0x0124);
23750c0d06caSMauro Carvalho Chehab 		/* TESTME HDG: this does not seem right
23760c0d06caSMauro Carvalho Chehab 		   (it is 2 for all other resolutions) */
23770c0d06caSMauro Carvalho Chehab 		sd->sof_len = 10;
23780c0d06caSMauro Carvalho Chehab 		break;
23790c0d06caSMauro Carvalho Chehab 	case 320: /* 320x240 */
23800c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0070, 0x0119);
23810c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00d0, 0x0111);
23820c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0039, 0x010a);
23830c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0001, 0x0102);
23840c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0028, 0x0103);
23850c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0000, 0x0104);
23860c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x001e, 0x0105);
23870c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
23880c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0016, 0x012f);
23890c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xd141, 0x0124);
23900c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x000a, 0x0127);
23910c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00aa, 0x0130);
23920c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x82a8, 0x0124);
23930c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0014, 0x012d);
23940c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0008, 0x012f);
23950c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xd145, 0x0124);
23960c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00aa, 0x012e);
23970c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x001a, 0x0130);
23980c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x8a0a, 0x0124);
23990c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x005a, 0x012d);
24000c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x9545, 0x0124);
24010c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00aa, 0x0127);
24020c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0018, 0x012e);
24030c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0043, 0x0130);
24040c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x8a28, 0x0124);
24050c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00aa, 0x012f);
24060c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xd055, 0x0124);
24070c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x001c, 0x0127);
24080c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00eb, 0x012e);
24090c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xaa28, 0x0124);
24100c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
24110c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0032, 0x012f);
24120c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xd141, 0x0124);
24130c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0000, 0x0127);
24140c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00aa, 0x0130);
24150c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x82a8, 0x0124);
24160c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0036, 0x012d);
24170c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0008, 0x012f);
24180c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xd145, 0x0124);
24190c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xfffa, 0x0124);
24200c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
24210c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x001e, 0x012f);
24220c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xd141, 0x0124);
24230c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0017, 0x0127);
24240c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0013, 0x012e);
24250c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0031, 0x0130);
24260c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x8a28, 0x0124);
24270c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0017, 0x012d);
24280c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0078, 0x012f);
24290c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xd145, 0x0124);
24300c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0000, 0x0127);
24310c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xfea8, 0x0124);
24320c0d06caSMauro Carvalho Chehab 		sd->sof_len = 2;
24330c0d06caSMauro Carvalho Chehab 		break;
24340c0d06caSMauro Carvalho Chehab 	case 352: /* 352x288 */
24350c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0070, 0x0119);
24360c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00c0, 0x0111);
24370c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0039, 0x010a);
24380c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0001, 0x0102);
24390c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x002c, 0x0103);
24400c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0000, 0x0104);
24410c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0024, 0x0105);
24420c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
24430c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0016, 0x012f);
24440c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xd141, 0x0124);
24450c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0006, 0x0127);
24460c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00aa, 0x0130);
24470c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x82a8, 0x0124);
24480c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0014, 0x012d);
24490c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0002, 0x012f);
24500c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xd145, 0x0124);
24510c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00aa, 0x012e);
24520c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x001a, 0x0130);
24530c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x8a0a, 0x0124);
24540c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x005e, 0x012d);
24550c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x9545, 0x0124);
24560c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00aa, 0x0127);
24570c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0018, 0x012e);
24580c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0049, 0x0130);
24590c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x8a28, 0x0124);
24600c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00aa, 0x012f);
24610c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xd055, 0x0124);
24620c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x001c, 0x0127);
24630c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00cf, 0x012e);
24640c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xaa28, 0x0124);
24650c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
24660c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0032, 0x012f);
24670c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xd141, 0x0124);
24680c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0000, 0x0127);
24690c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00aa, 0x0130);
24700c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x82a8, 0x0124);
24710c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0036, 0x012d);
24720c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0008, 0x012f);
24730c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xd145, 0x0124);
24740c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xfffa, 0x0124);
24750c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
24760c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x001e, 0x012f);
24770c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xd141, 0x0124);
24780c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0010, 0x0127);
24790c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0013, 0x012e);
24800c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0025, 0x0130);
24810c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x8a28, 0x0124);
24820c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0010, 0x012d);
24830c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0048, 0x012f);
24840c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xd145, 0x0124);
24850c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0000, 0x0127);
24860c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0xfea8, 0x0124);
24870c0d06caSMauro Carvalho Chehab 		sd->sof_len = 2;
24880c0d06caSMauro Carvalho Chehab 		break;
24890c0d06caSMauro Carvalho Chehab 	}
24900c0d06caSMauro Carvalho Chehab 
24910c0d06caSMauro Carvalho Chehab 	cit_model4_Packet1(gspca_dev, 0x0038, 0x0004);
24920c0d06caSMauro Carvalho Chehab 
24930c0d06caSMauro Carvalho Chehab 	return 0;
24940c0d06caSMauro Carvalho Chehab }
24950c0d06caSMauro Carvalho Chehab 
cit_start_ibm_netcam_pro(struct gspca_dev * gspca_dev)24960c0d06caSMauro Carvalho Chehab static int cit_start_ibm_netcam_pro(struct gspca_dev *gspca_dev)
24970c0d06caSMauro Carvalho Chehab {
24980c0d06caSMauro Carvalho Chehab 	const unsigned short compression = 0; /* 0=none, 7=best frame rate */
24990c0d06caSMauro Carvalho Chehab 	int i, clock_div;
25000c0d06caSMauro Carvalho Chehab 
25010c0d06caSMauro Carvalho Chehab 	clock_div = cit_get_clock_div(gspca_dev);
25020c0d06caSMauro Carvalho Chehab 	if (clock_div < 0)
25030c0d06caSMauro Carvalho Chehab 		return clock_div;
25040c0d06caSMauro Carvalho Chehab 
25050c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0003, 0x0133);
25060c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0000, 0x0117);
25070c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0008, 0x0123);
25080c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0000, 0x0100);
25090c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0060, 0x0116);
25100c0d06caSMauro Carvalho Chehab 	/* cit_write_reg(gspca_dev, 0x0002, 0x0112); see sd_stop0 */
25110c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0000, 0x0133);
25120c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0000, 0x0123);
25130c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0001, 0x0117);
25140c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0040, 0x0108);
25150c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0019, 0x012c);
25160c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0060, 0x0116);
25170c0d06caSMauro Carvalho Chehab 	/* cit_write_reg(gspca_dev, 0x000b, 0x0115); see sd_stop0 */
25180c0d06caSMauro Carvalho Chehab 
25190c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0049, 0x0000);
25200c0d06caSMauro Carvalho Chehab 
25210c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0000, 0x0101); /* Same on 160x120, 320x240 */
25220c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x003a, 0x0102); /* Hstart */
25230c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x00a0, 0x0103); /* Same on 160x120, 320x240 */
25240c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0078, 0x0105); /* Same on 160x120, 320x240 */
25250c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0000, 0x010a); /* Same */
25260c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0002, 0x011d); /* Same on 160x120, 320x240 */
25270c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0000, 0x0129); /* Same */
25280c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x00fc, 0x012b); /* Same */
25290c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0022, 0x012a); /* Same */
25300c0d06caSMauro Carvalho Chehab 
25311966bc2aSOndrej Zary 	switch (gspca_dev->pixfmt.width) {
25320c0d06caSMauro Carvalho Chehab 	case 160: /* 160x120 */
25330c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0024, 0x010b);
25340c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0089, 0x0119);
25350c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x000a, 0x011b);
25360c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0003, 0x011e);
25370c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0007, 0x0104);
25380c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0009, 0x011a);
25390c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x008b, 0x011c);
25400c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0008, 0x0118);
25410c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0000, 0x0132);
25420c0d06caSMauro Carvalho Chehab 		break;
25430c0d06caSMauro Carvalho Chehab 	case 320: /* 320x240 */
25440c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0028, 0x010b);
25450c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00d9, 0x0119);
25460c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0006, 0x011b);
25470c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0000, 0x011e);
25480c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x000e, 0x0104);
25490c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0004, 0x011a);
25500c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x003f, 0x011c);
25510c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x000c, 0x0118);
25520c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0000, 0x0132);
25530c0d06caSMauro Carvalho Chehab 		break;
25540c0d06caSMauro Carvalho Chehab 	}
25550c0d06caSMauro Carvalho Chehab 
25560c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0019, 0x0031);
25570c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x001a, 0x0003);
25580c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x001b, 0x0038);
25590c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x001c, 0x0000);
25600c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0024, 0x0001);
25610c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0027, 0x0001);
25620c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x002a, 0x0004);
25630c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0035, 0x000b);
25640c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x003f, 0x0001);
25650c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0044, 0x0000);
25660c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x0054, 0x0000);
25670c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x00c4, 0x0000);
25680c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x00e7, 0x0001);
25690c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x00e9, 0x0001);
25700c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x00ee, 0x0000);
25710c0d06caSMauro Carvalho Chehab 	cit_model3_Packet1(gspca_dev, 0x00f3, 0x00c0);
25720c0d06caSMauro Carvalho Chehab 
25730c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, compression, 0x0109);
25740c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, clock_div, 0x0111);
25750c0d06caSMauro Carvalho Chehab 
25760c0d06caSMauro Carvalho Chehab /*	if (sd->input_index) { */
25770c0d06caSMauro Carvalho Chehab 	if (rca_input) {
25780c0d06caSMauro Carvalho Chehab 		for (i = 0; i < ARRAY_SIZE(rca_initdata); i++) {
25790c0d06caSMauro Carvalho Chehab 			if (rca_initdata[i][0])
25800c0d06caSMauro Carvalho Chehab 				cit_read_reg(gspca_dev, rca_initdata[i][2], 0);
25810c0d06caSMauro Carvalho Chehab 			else
25820c0d06caSMauro Carvalho Chehab 				cit_write_reg(gspca_dev, rca_initdata[i][1],
25830c0d06caSMauro Carvalho Chehab 					      rca_initdata[i][2]);
25840c0d06caSMauro Carvalho Chehab 		}
25850c0d06caSMauro Carvalho Chehab 	}
25860c0d06caSMauro Carvalho Chehab 
25870c0d06caSMauro Carvalho Chehab 	return 0;
25880c0d06caSMauro Carvalho Chehab }
25890c0d06caSMauro Carvalho Chehab 
25900c0d06caSMauro Carvalho Chehab /* -- start the camera -- */
sd_start(struct gspca_dev * gspca_dev)25910c0d06caSMauro Carvalho Chehab static int sd_start(struct gspca_dev *gspca_dev)
25920c0d06caSMauro Carvalho Chehab {
25930c0d06caSMauro Carvalho Chehab 	struct sd *sd = (struct sd *) gspca_dev;
25940c0d06caSMauro Carvalho Chehab 	int packet_size;
25950c0d06caSMauro Carvalho Chehab 
25960c0d06caSMauro Carvalho Chehab 	packet_size = cit_get_packet_size(gspca_dev);
25970c0d06caSMauro Carvalho Chehab 	if (packet_size < 0)
25980c0d06caSMauro Carvalho Chehab 		return packet_size;
25990c0d06caSMauro Carvalho Chehab 
26000c0d06caSMauro Carvalho Chehab 	switch (sd->model) {
26010c0d06caSMauro Carvalho Chehab 	case CIT_MODEL0:
26020c0d06caSMauro Carvalho Chehab 		cit_start_model0(gspca_dev);
26030c0d06caSMauro Carvalho Chehab 		break;
26040c0d06caSMauro Carvalho Chehab 	case CIT_MODEL1:
26050c0d06caSMauro Carvalho Chehab 		cit_start_model1(gspca_dev);
26060c0d06caSMauro Carvalho Chehab 		break;
26070c0d06caSMauro Carvalho Chehab 	case CIT_MODEL2:
26080c0d06caSMauro Carvalho Chehab 		cit_start_model2(gspca_dev);
26090c0d06caSMauro Carvalho Chehab 		break;
26100c0d06caSMauro Carvalho Chehab 	case CIT_MODEL3:
26110c0d06caSMauro Carvalho Chehab 		cit_start_model3(gspca_dev);
26120c0d06caSMauro Carvalho Chehab 		break;
26130c0d06caSMauro Carvalho Chehab 	case CIT_MODEL4:
26140c0d06caSMauro Carvalho Chehab 		cit_start_model4(gspca_dev);
26150c0d06caSMauro Carvalho Chehab 		break;
26160c0d06caSMauro Carvalho Chehab 	case CIT_IBM_NETCAM_PRO:
26170c0d06caSMauro Carvalho Chehab 		cit_start_ibm_netcam_pro(gspca_dev);
26180c0d06caSMauro Carvalho Chehab 		break;
26190c0d06caSMauro Carvalho Chehab 	}
26200c0d06caSMauro Carvalho Chehab 
26210c0d06caSMauro Carvalho Chehab 	/* Program max isoc packet size */
26220c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, packet_size >> 8, 0x0106);
26230c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, packet_size & 0xff, 0x0107);
26240c0d06caSMauro Carvalho Chehab 
26250c0d06caSMauro Carvalho Chehab 	cit_restart_stream(gspca_dev);
26260c0d06caSMauro Carvalho Chehab 
26270c0d06caSMauro Carvalho Chehab 	return 0;
26280c0d06caSMauro Carvalho Chehab }
26290c0d06caSMauro Carvalho Chehab 
sd_isoc_init(struct gspca_dev * gspca_dev)26300c0d06caSMauro Carvalho Chehab static int sd_isoc_init(struct gspca_dev *gspca_dev)
26310c0d06caSMauro Carvalho Chehab {
2632a246b4d5SJohan Hovold 	struct usb_interface_cache *intfc;
26330c0d06caSMauro Carvalho Chehab 	struct usb_host_interface *alt;
26340c0d06caSMauro Carvalho Chehab 	int max_packet_size;
26350c0d06caSMauro Carvalho Chehab 
26361966bc2aSOndrej Zary 	switch (gspca_dev->pixfmt.width) {
26370c0d06caSMauro Carvalho Chehab 	case 160:
26380c0d06caSMauro Carvalho Chehab 		max_packet_size = 450;
26390c0d06caSMauro Carvalho Chehab 		break;
26400c0d06caSMauro Carvalho Chehab 	case 176:
26410c0d06caSMauro Carvalho Chehab 		max_packet_size = 600;
26420c0d06caSMauro Carvalho Chehab 		break;
26430c0d06caSMauro Carvalho Chehab 	default:
26440c0d06caSMauro Carvalho Chehab 		max_packet_size = 1022;
26450c0d06caSMauro Carvalho Chehab 		break;
26460c0d06caSMauro Carvalho Chehab 	}
26470c0d06caSMauro Carvalho Chehab 
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 
26580c0d06caSMauro Carvalho Chehab 	/* Start isoc bandwidth "negotiation" at max isoc bandwidth */
26590c0d06caSMauro Carvalho Chehab 	alt->endpoint[0].desc.wMaxPacketSize = cpu_to_le16(max_packet_size);
26600c0d06caSMauro Carvalho Chehab 
26610c0d06caSMauro Carvalho Chehab 	return 0;
26620c0d06caSMauro Carvalho Chehab }
26630c0d06caSMauro Carvalho Chehab 
sd_isoc_nego(struct gspca_dev * gspca_dev)26640c0d06caSMauro Carvalho Chehab static int sd_isoc_nego(struct gspca_dev *gspca_dev)
26650c0d06caSMauro Carvalho Chehab {
26660c0d06caSMauro Carvalho Chehab 	int ret, packet_size, min_packet_size;
26670c0d06caSMauro Carvalho Chehab 	struct usb_host_interface *alt;
26680c0d06caSMauro Carvalho Chehab 
26691966bc2aSOndrej Zary 	switch (gspca_dev->pixfmt.width) {
26700c0d06caSMauro Carvalho Chehab 	case 160:
26710c0d06caSMauro Carvalho Chehab 		min_packet_size = 200;
26720c0d06caSMauro Carvalho Chehab 		break;
26730c0d06caSMauro Carvalho Chehab 	case 176:
26740c0d06caSMauro Carvalho Chehab 		min_packet_size = 266;
26750c0d06caSMauro Carvalho Chehab 		break;
26760c0d06caSMauro Carvalho Chehab 	default:
26770c0d06caSMauro Carvalho Chehab 		min_packet_size = 400;
26780c0d06caSMauro Carvalho Chehab 		break;
26790c0d06caSMauro Carvalho Chehab 	}
26800c0d06caSMauro Carvalho Chehab 
2681a246b4d5SJohan Hovold 	/*
2682a246b4d5SJohan Hovold 	 * Existence of altsetting and endpoint was verified in sd_isoc_init()
2683a246b4d5SJohan Hovold 	 */
26840c0d06caSMauro Carvalho Chehab 	alt = &gspca_dev->dev->actconfig->intf_cache[0]->altsetting[1];
26850c0d06caSMauro Carvalho Chehab 	packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
26860c0d06caSMauro Carvalho Chehab 	if (packet_size <= min_packet_size)
26870c0d06caSMauro Carvalho Chehab 		return -EIO;
26880c0d06caSMauro Carvalho Chehab 
26890c0d06caSMauro Carvalho Chehab 	packet_size -= 100;
26900c0d06caSMauro Carvalho Chehab 	if (packet_size < min_packet_size)
26910c0d06caSMauro Carvalho Chehab 		packet_size = min_packet_size;
26920c0d06caSMauro Carvalho Chehab 	alt->endpoint[0].desc.wMaxPacketSize = cpu_to_le16(packet_size);
26930c0d06caSMauro Carvalho Chehab 
26940c0d06caSMauro Carvalho Chehab 	ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1);
26950c0d06caSMauro Carvalho Chehab 	if (ret < 0)
26960c0d06caSMauro Carvalho Chehab 		pr_err("set alt 1 err %d\n", ret);
26970c0d06caSMauro Carvalho Chehab 
26980c0d06caSMauro Carvalho Chehab 	return ret;
26990c0d06caSMauro Carvalho Chehab }
27000c0d06caSMauro Carvalho Chehab 
sd_stopN(struct gspca_dev * gspca_dev)27010c0d06caSMauro Carvalho Chehab static void sd_stopN(struct gspca_dev *gspca_dev)
27020c0d06caSMauro Carvalho Chehab {
27030c0d06caSMauro Carvalho Chehab 	cit_write_reg(gspca_dev, 0x0000, 0x010c);
27040c0d06caSMauro Carvalho Chehab }
27050c0d06caSMauro Carvalho Chehab 
sd_stop0(struct gspca_dev * gspca_dev)27060c0d06caSMauro Carvalho Chehab static void sd_stop0(struct gspca_dev *gspca_dev)
27070c0d06caSMauro Carvalho Chehab {
27080c0d06caSMauro Carvalho Chehab 	struct sd *sd = (struct sd *) gspca_dev;
27090c0d06caSMauro Carvalho Chehab 
2710345321dcSHans de Goede 	if (!gspca_dev->present)
27110c0d06caSMauro Carvalho Chehab 		return;
27120c0d06caSMauro Carvalho Chehab 
27130c0d06caSMauro Carvalho Chehab 	switch (sd->model) {
27140c0d06caSMauro Carvalho Chehab 	case CIT_MODEL0:
27150c0d06caSMauro Carvalho Chehab 		/* HDG windows does this, but it causes the cams autogain to
27160c0d06caSMauro Carvalho Chehab 		   restart from a gain of 0, which does not look good when
27170c0d06caSMauro Carvalho Chehab 		   changing resolutions. */
27180c0d06caSMauro Carvalho Chehab 		/* cit_write_reg(gspca_dev, 0x0000, 0x0112); */
27190c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00c0, 0x0100); /* LED Off */
27200c0d06caSMauro Carvalho Chehab 		break;
27210c0d06caSMauro Carvalho Chehab 	case CIT_MODEL1:
27220c0d06caSMauro Carvalho Chehab 		cit_send_FF_04_02(gspca_dev);
27230c0d06caSMauro Carvalho Chehab 		cit_read_reg(gspca_dev, 0x0100, 0);
27240c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x81, 0x0100);	/* LED Off */
27250c0d06caSMauro Carvalho Chehab 		break;
27260c0d06caSMauro Carvalho Chehab 	case CIT_MODEL2:
27270c0d06caSMauro Carvalho Chehab 		v4l2_ctrl_grab(sd->lighting, false);
2728*1771e9fbSGustavo A. R. Silva 		fallthrough;
27290c0d06caSMauro Carvalho Chehab 	case CIT_MODEL4:
27300c0d06caSMauro Carvalho Chehab 		cit_model2_Packet1(gspca_dev, 0x0030, 0x0004);
27310c0d06caSMauro Carvalho Chehab 
27320c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0080, 0x0100);	/* LED Off */
27330c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0020, 0x0111);
27340c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00a0, 0x0111);
27350c0d06caSMauro Carvalho Chehab 
27360c0d06caSMauro Carvalho Chehab 		cit_model2_Packet1(gspca_dev, 0x0030, 0x0002);
27370c0d06caSMauro Carvalho Chehab 
27380c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0020, 0x0111);
27390c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0000, 0x0112);
27400c0d06caSMauro Carvalho Chehab 		break;
27410c0d06caSMauro Carvalho Chehab 	case CIT_MODEL3:
27420c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0006, 0x012c);
27430c0d06caSMauro Carvalho Chehab 		cit_model3_Packet1(gspca_dev, 0x0046, 0x0000);
27440c0d06caSMauro Carvalho Chehab 		cit_read_reg(gspca_dev, 0x0116, 0);
27450c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0064, 0x0116);
27460c0d06caSMauro Carvalho Chehab 		cit_read_reg(gspca_dev, 0x0115, 0);
27470c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0003, 0x0115);
27480c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0008, 0x0123);
27490c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0000, 0x0117);
27500c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0000, 0x0112);
27510c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0080, 0x0100);
27520c0d06caSMauro Carvalho Chehab 		break;
27530c0d06caSMauro Carvalho Chehab 	case CIT_IBM_NETCAM_PRO:
27540c0d06caSMauro Carvalho Chehab 		cit_model3_Packet1(gspca_dev, 0x0049, 0x00ff);
27550c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0006, 0x012c);
27560c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0000, 0x0116);
27570c0d06caSMauro Carvalho Chehab 		/* HDG windows does this, but I cannot get the camera
27580c0d06caSMauro Carvalho Chehab 		   to restart with this without redoing the entire init
27590c0d06caSMauro Carvalho Chehab 		   sequence which makes switching modes really slow */
27600c0d06caSMauro Carvalho Chehab 		/* cit_write_reg(gspca_dev, 0x0006, 0x0115); */
27610c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0008, 0x0123);
27620c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0000, 0x0117);
27630c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0003, 0x0133);
27640c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x0000, 0x0111);
27650c0d06caSMauro Carvalho Chehab 		/* HDG windows does this, but I get a green picture when
27660c0d06caSMauro Carvalho Chehab 		   restarting the stream after this */
27670c0d06caSMauro Carvalho Chehab 		/* cit_write_reg(gspca_dev, 0x0000, 0x0112); */
27680c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x00c0, 0x0100);
27690c0d06caSMauro Carvalho Chehab 		break;
27700c0d06caSMauro Carvalho Chehab 	}
27710c0d06caSMauro Carvalho Chehab 
2772e32d6eb8SPeter Senna Tschudin #if IS_ENABLED(CONFIG_INPUT)
27730c0d06caSMauro Carvalho Chehab 	/* If the last button state is pressed, release it now! */
27740c0d06caSMauro Carvalho Chehab 	if (sd->button_state) {
27750c0d06caSMauro Carvalho Chehab 		input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
27760c0d06caSMauro Carvalho Chehab 		input_sync(gspca_dev->input_dev);
27770c0d06caSMauro Carvalho Chehab 		sd->button_state = 0;
27780c0d06caSMauro Carvalho Chehab 	}
27790c0d06caSMauro Carvalho Chehab #endif
27800c0d06caSMauro Carvalho Chehab }
27810c0d06caSMauro Carvalho Chehab 
cit_find_sof(struct gspca_dev * gspca_dev,u8 * data,int len)27820c0d06caSMauro Carvalho Chehab static u8 *cit_find_sof(struct gspca_dev *gspca_dev, u8 *data, int len)
27830c0d06caSMauro Carvalho Chehab {
27840c0d06caSMauro Carvalho Chehab 	struct sd *sd = (struct sd *) gspca_dev;
27850c0d06caSMauro Carvalho Chehab 	u8 byte3 = 0, byte4 = 0;
27860c0d06caSMauro Carvalho Chehab 	int i;
27870c0d06caSMauro Carvalho Chehab 
27880c0d06caSMauro Carvalho Chehab 	switch (sd->model) {
27890c0d06caSMauro Carvalho Chehab 	case CIT_MODEL0:
27900c0d06caSMauro Carvalho Chehab 	case CIT_MODEL1:
27910c0d06caSMauro Carvalho Chehab 	case CIT_MODEL3:
27920c0d06caSMauro Carvalho Chehab 	case CIT_IBM_NETCAM_PRO:
27931966bc2aSOndrej Zary 		switch (gspca_dev->pixfmt.width) {
27940c0d06caSMauro Carvalho Chehab 		case 160: /* 160x120 */
27950c0d06caSMauro Carvalho Chehab 			byte3 = 0x02;
27960c0d06caSMauro Carvalho Chehab 			byte4 = 0x0a;
27970c0d06caSMauro Carvalho Chehab 			break;
27980c0d06caSMauro Carvalho Chehab 		case 176: /* 176x144 */
27990c0d06caSMauro Carvalho Chehab 			byte3 = 0x02;
28000c0d06caSMauro Carvalho Chehab 			byte4 = 0x0e;
28010c0d06caSMauro Carvalho Chehab 			break;
28020c0d06caSMauro Carvalho Chehab 		case 320: /* 320x240 */
28030c0d06caSMauro Carvalho Chehab 			byte3 = 0x02;
28040c0d06caSMauro Carvalho Chehab 			byte4 = 0x08;
28050c0d06caSMauro Carvalho Chehab 			break;
28060c0d06caSMauro Carvalho Chehab 		case 352: /* 352x288 */
28070c0d06caSMauro Carvalho Chehab 			byte3 = 0x02;
28080c0d06caSMauro Carvalho Chehab 			byte4 = 0x00;
28090c0d06caSMauro Carvalho Chehab 			break;
28100c0d06caSMauro Carvalho Chehab 		case 640:
28110c0d06caSMauro Carvalho Chehab 			byte3 = 0x03;
28120c0d06caSMauro Carvalho Chehab 			byte4 = 0x08;
28130c0d06caSMauro Carvalho Chehab 			break;
28140c0d06caSMauro Carvalho Chehab 		}
28150c0d06caSMauro Carvalho Chehab 
28160c0d06caSMauro Carvalho Chehab 		/* These have a different byte3 */
28170c0d06caSMauro Carvalho Chehab 		if (sd->model <= CIT_MODEL1)
28180c0d06caSMauro Carvalho Chehab 			byte3 = 0x00;
28190c0d06caSMauro Carvalho Chehab 
28200c0d06caSMauro Carvalho Chehab 		for (i = 0; i < len; i++) {
28210c0d06caSMauro Carvalho Chehab 			/* For this model the SOF always starts at offset 0
28220c0d06caSMauro Carvalho Chehab 			   so no need to search the entire frame */
28230c0d06caSMauro Carvalho Chehab 			if (sd->model == CIT_MODEL0 && sd->sof_read != i)
28240c0d06caSMauro Carvalho Chehab 				break;
28250c0d06caSMauro Carvalho Chehab 
28260c0d06caSMauro Carvalho Chehab 			switch (sd->sof_read) {
28270c0d06caSMauro Carvalho Chehab 			case 0:
28280c0d06caSMauro Carvalho Chehab 				if (data[i] == 0x00)
28290c0d06caSMauro Carvalho Chehab 					sd->sof_read++;
28300c0d06caSMauro Carvalho Chehab 				break;
28310c0d06caSMauro Carvalho Chehab 			case 1:
28320c0d06caSMauro Carvalho Chehab 				if (data[i] == 0xff)
28330c0d06caSMauro Carvalho Chehab 					sd->sof_read++;
28340c0d06caSMauro Carvalho Chehab 				else if (data[i] == 0x00)
28350c0d06caSMauro Carvalho Chehab 					sd->sof_read = 1;
28360c0d06caSMauro Carvalho Chehab 				else
28370c0d06caSMauro Carvalho Chehab 					sd->sof_read = 0;
28380c0d06caSMauro Carvalho Chehab 				break;
28390c0d06caSMauro Carvalho Chehab 			case 2:
28400c0d06caSMauro Carvalho Chehab 				if (data[i] == byte3)
28410c0d06caSMauro Carvalho Chehab 					sd->sof_read++;
28420c0d06caSMauro Carvalho Chehab 				else if (data[i] == 0x00)
28430c0d06caSMauro Carvalho Chehab 					sd->sof_read = 1;
28440c0d06caSMauro Carvalho Chehab 				else
28450c0d06caSMauro Carvalho Chehab 					sd->sof_read = 0;
28460c0d06caSMauro Carvalho Chehab 				break;
28470c0d06caSMauro Carvalho Chehab 			case 3:
28480c0d06caSMauro Carvalho Chehab 				if (data[i] == byte4) {
28490c0d06caSMauro Carvalho Chehab 					sd->sof_read = 0;
28500c0d06caSMauro Carvalho Chehab 					return data + i + (sd->sof_len - 3);
28510c0d06caSMauro Carvalho Chehab 				}
28520c0d06caSMauro Carvalho Chehab 				if (byte3 == 0x00 && data[i] == 0xff)
28530c0d06caSMauro Carvalho Chehab 					sd->sof_read = 2;
28540c0d06caSMauro Carvalho Chehab 				else if (data[i] == 0x00)
28550c0d06caSMauro Carvalho Chehab 					sd->sof_read = 1;
28560c0d06caSMauro Carvalho Chehab 				else
28570c0d06caSMauro Carvalho Chehab 					sd->sof_read = 0;
28580c0d06caSMauro Carvalho Chehab 				break;
28590c0d06caSMauro Carvalho Chehab 			}
28600c0d06caSMauro Carvalho Chehab 		}
28610c0d06caSMauro Carvalho Chehab 		break;
28620c0d06caSMauro Carvalho Chehab 	case CIT_MODEL2:
28630c0d06caSMauro Carvalho Chehab 	case CIT_MODEL4:
28640c0d06caSMauro Carvalho Chehab 		/* TESTME we need to find a longer sof signature to avoid
28650c0d06caSMauro Carvalho Chehab 		   false positives */
28660c0d06caSMauro Carvalho Chehab 		for (i = 0; i < len; i++) {
28670c0d06caSMauro Carvalho Chehab 			switch (sd->sof_read) {
28680c0d06caSMauro Carvalho Chehab 			case 0:
28690c0d06caSMauro Carvalho Chehab 				if (data[i] == 0x00)
28700c0d06caSMauro Carvalho Chehab 					sd->sof_read++;
28710c0d06caSMauro Carvalho Chehab 				break;
28720c0d06caSMauro Carvalho Chehab 			case 1:
28730c0d06caSMauro Carvalho Chehab 				sd->sof_read = 0;
28740c0d06caSMauro Carvalho Chehab 				if (data[i] == 0xff) {
28750c0d06caSMauro Carvalho Chehab 					if (i >= 4)
287637d5efb0SJoe Perches 						gspca_dbg(gspca_dev, D_FRAM,
287737d5efb0SJoe Perches 							  "header found at offset: %d: %02x %02x 00 %3ph\n\n",
28780c0d06caSMauro Carvalho Chehab 							  i - 1,
28790c0d06caSMauro Carvalho Chehab 							  data[i - 4],
28800c0d06caSMauro Carvalho Chehab 							  data[i - 3],
2881ee35fa22SAndy Shevchenko 							  &data[i]);
28820c0d06caSMauro Carvalho Chehab 					else
288337d5efb0SJoe Perches 						gspca_dbg(gspca_dev, D_FRAM,
288437d5efb0SJoe Perches 							  "header found at offset: %d: 00 %3ph\n\n",
28850c0d06caSMauro Carvalho Chehab 							  i - 1,
2886ee35fa22SAndy Shevchenko 							  &data[i]);
28870c0d06caSMauro Carvalho Chehab 					return data + i + (sd->sof_len - 1);
28880c0d06caSMauro Carvalho Chehab 				}
28890c0d06caSMauro Carvalho Chehab 				break;
28900c0d06caSMauro Carvalho Chehab 			}
28910c0d06caSMauro Carvalho Chehab 		}
28920c0d06caSMauro Carvalho Chehab 		break;
28930c0d06caSMauro Carvalho Chehab 	}
28940c0d06caSMauro Carvalho Chehab 	return NULL;
28950c0d06caSMauro Carvalho Chehab }
28960c0d06caSMauro Carvalho Chehab 
sd_pkt_scan(struct gspca_dev * gspca_dev,u8 * data,int len)28970c0d06caSMauro Carvalho Chehab static void sd_pkt_scan(struct gspca_dev *gspca_dev,
28980c0d06caSMauro Carvalho Chehab 			u8 *data, int len)
28990c0d06caSMauro Carvalho Chehab {
29000c0d06caSMauro Carvalho Chehab 	struct sd *sd = (struct sd *) gspca_dev;
29010c0d06caSMauro Carvalho Chehab 	unsigned char *sof;
29020c0d06caSMauro Carvalho Chehab 
29030c0d06caSMauro Carvalho Chehab 	sof = cit_find_sof(gspca_dev, data, len);
29040c0d06caSMauro Carvalho Chehab 	if (sof) {
29050c0d06caSMauro Carvalho Chehab 		int n;
29060c0d06caSMauro Carvalho Chehab 
29070c0d06caSMauro Carvalho Chehab 		/* finish decoding current frame */
29080c0d06caSMauro Carvalho Chehab 		n = sof - data;
29090c0d06caSMauro Carvalho Chehab 		if (n > sd->sof_len)
29100c0d06caSMauro Carvalho Chehab 			n -= sd->sof_len;
29110c0d06caSMauro Carvalho Chehab 		else
29120c0d06caSMauro Carvalho Chehab 			n = 0;
29130c0d06caSMauro Carvalho Chehab 		gspca_frame_add(gspca_dev, LAST_PACKET,
29140c0d06caSMauro Carvalho Chehab 				data, n);
29150c0d06caSMauro Carvalho Chehab 		gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
29160c0d06caSMauro Carvalho Chehab 		len -= sof - data;
29170c0d06caSMauro Carvalho Chehab 		data = sof;
29180c0d06caSMauro Carvalho Chehab 	}
29190c0d06caSMauro Carvalho Chehab 
29200c0d06caSMauro Carvalho Chehab 	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
29210c0d06caSMauro Carvalho Chehab }
29220c0d06caSMauro Carvalho Chehab 
2923e32d6eb8SPeter Senna Tschudin #if IS_ENABLED(CONFIG_INPUT)
cit_check_button(struct gspca_dev * gspca_dev)29240c0d06caSMauro Carvalho Chehab static void cit_check_button(struct gspca_dev *gspca_dev)
29250c0d06caSMauro Carvalho Chehab {
29260c0d06caSMauro Carvalho Chehab 	int new_button_state;
29270c0d06caSMauro Carvalho Chehab 	struct sd *sd = (struct sd *)gspca_dev;
29280c0d06caSMauro Carvalho Chehab 
29290c0d06caSMauro Carvalho Chehab 	switch (sd->model) {
29300c0d06caSMauro Carvalho Chehab 	case CIT_MODEL3:
29310c0d06caSMauro Carvalho Chehab 	case CIT_IBM_NETCAM_PRO:
29320c0d06caSMauro Carvalho Chehab 		break;
29330c0d06caSMauro Carvalho Chehab 	default: /* TEST ME unknown if this works on other models too */
29340c0d06caSMauro Carvalho Chehab 		return;
29350c0d06caSMauro Carvalho Chehab 	}
29360c0d06caSMauro Carvalho Chehab 
29370c0d06caSMauro Carvalho Chehab 	/* Read the button state */
29380c0d06caSMauro Carvalho Chehab 	cit_read_reg(gspca_dev, 0x0113, 0);
29390c0d06caSMauro Carvalho Chehab 	new_button_state = !gspca_dev->usb_buf[0];
29400c0d06caSMauro Carvalho Chehab 
29410c0d06caSMauro Carvalho Chehab 	/* Tell the cam we've seen the button press, notice that this
29420c0d06caSMauro Carvalho Chehab 	   is a nop (iow the cam keeps reporting pressed) until the
29430c0d06caSMauro Carvalho Chehab 	   button is actually released. */
29440c0d06caSMauro Carvalho Chehab 	if (new_button_state)
29450c0d06caSMauro Carvalho Chehab 		cit_write_reg(gspca_dev, 0x01, 0x0113);
29460c0d06caSMauro Carvalho Chehab 
29470c0d06caSMauro Carvalho Chehab 	if (sd->button_state != new_button_state) {
29480c0d06caSMauro Carvalho Chehab 		input_report_key(gspca_dev->input_dev, KEY_CAMERA,
29490c0d06caSMauro Carvalho Chehab 				 new_button_state);
29500c0d06caSMauro Carvalho Chehab 		input_sync(gspca_dev->input_dev);
29510c0d06caSMauro Carvalho Chehab 		sd->button_state = new_button_state;
29520c0d06caSMauro Carvalho Chehab 	}
29530c0d06caSMauro Carvalho Chehab }
29540c0d06caSMauro Carvalho Chehab #endif
29550c0d06caSMauro Carvalho Chehab 
sd_s_ctrl(struct v4l2_ctrl * ctrl)29560c0d06caSMauro Carvalho Chehab static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
29570c0d06caSMauro Carvalho Chehab {
29580c0d06caSMauro Carvalho Chehab 	struct gspca_dev *gspca_dev =
29590c0d06caSMauro Carvalho Chehab 		container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
29600c0d06caSMauro Carvalho Chehab 	struct sd *sd = (struct sd *)gspca_dev;
29610c0d06caSMauro Carvalho Chehab 
29620c0d06caSMauro Carvalho Chehab 	gspca_dev->usb_err = 0;
29630c0d06caSMauro Carvalho Chehab 
29640c0d06caSMauro Carvalho Chehab 	if (!gspca_dev->streaming)
29650c0d06caSMauro Carvalho Chehab 		return 0;
29660c0d06caSMauro Carvalho Chehab 
29670c0d06caSMauro Carvalho Chehab 	if (sd->stop_on_control_change)
29680c0d06caSMauro Carvalho Chehab 		sd_stopN(gspca_dev);
29690c0d06caSMauro Carvalho Chehab 	switch (ctrl->id) {
29700c0d06caSMauro Carvalho Chehab 	case V4L2_CID_BRIGHTNESS:
29710c0d06caSMauro Carvalho Chehab 		cit_set_brightness(gspca_dev, ctrl->val);
29720c0d06caSMauro Carvalho Chehab 		break;
29730c0d06caSMauro Carvalho Chehab 	case V4L2_CID_CONTRAST:
29740c0d06caSMauro Carvalho Chehab 		cit_set_contrast(gspca_dev, ctrl->val);
29750c0d06caSMauro Carvalho Chehab 		break;
29760c0d06caSMauro Carvalho Chehab 	case V4L2_CID_HUE:
29770c0d06caSMauro Carvalho Chehab 		cit_set_hue(gspca_dev, ctrl->val);
29780c0d06caSMauro Carvalho Chehab 		break;
29790c0d06caSMauro Carvalho Chehab 	case V4L2_CID_HFLIP:
29800c0d06caSMauro Carvalho Chehab 		cit_set_hflip(gspca_dev, ctrl->val);
29810c0d06caSMauro Carvalho Chehab 		break;
29820c0d06caSMauro Carvalho Chehab 	case V4L2_CID_SHARPNESS:
29830c0d06caSMauro Carvalho Chehab 		cit_set_sharpness(gspca_dev, ctrl->val);
29840c0d06caSMauro Carvalho Chehab 		break;
29850c0d06caSMauro Carvalho Chehab 	case V4L2_CID_BACKLIGHT_COMPENSATION:
29860c0d06caSMauro Carvalho Chehab 		cit_set_lighting(gspca_dev, ctrl->val);
29870c0d06caSMauro Carvalho Chehab 		break;
29880c0d06caSMauro Carvalho Chehab 	}
29890c0d06caSMauro Carvalho Chehab 	if (sd->stop_on_control_change)
29900c0d06caSMauro Carvalho Chehab 		cit_restart_stream(gspca_dev);
29910c0d06caSMauro Carvalho Chehab 	return gspca_dev->usb_err;
29920c0d06caSMauro Carvalho Chehab }
29930c0d06caSMauro Carvalho Chehab 
29940c0d06caSMauro Carvalho Chehab static const struct v4l2_ctrl_ops sd_ctrl_ops = {
29950c0d06caSMauro Carvalho Chehab 	.s_ctrl = sd_s_ctrl,
29960c0d06caSMauro Carvalho Chehab };
29970c0d06caSMauro Carvalho Chehab 
sd_init_controls(struct gspca_dev * gspca_dev)29980c0d06caSMauro Carvalho Chehab static int sd_init_controls(struct gspca_dev *gspca_dev)
29990c0d06caSMauro Carvalho Chehab {
30000c0d06caSMauro Carvalho Chehab 	struct sd *sd = (struct sd *)gspca_dev;
30010c0d06caSMauro Carvalho Chehab 	struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
30020c0d06caSMauro Carvalho Chehab 	bool has_brightness;
30030c0d06caSMauro Carvalho Chehab 	bool has_contrast;
30040c0d06caSMauro Carvalho Chehab 	bool has_hue;
30050c0d06caSMauro Carvalho Chehab 	bool has_sharpness;
30060c0d06caSMauro Carvalho Chehab 	bool has_lighting;
30070c0d06caSMauro Carvalho Chehab 	bool has_hflip;
30080c0d06caSMauro Carvalho Chehab 
30090c0d06caSMauro Carvalho Chehab 	has_brightness = has_contrast = has_hue =
30100c0d06caSMauro Carvalho Chehab 		has_sharpness = has_hflip = has_lighting = false;
30110c0d06caSMauro Carvalho Chehab 	switch (sd->model) {
30120c0d06caSMauro Carvalho Chehab 	case CIT_MODEL0:
30130c0d06caSMauro Carvalho Chehab 		has_contrast = has_hflip = true;
30140c0d06caSMauro Carvalho Chehab 		break;
30150c0d06caSMauro Carvalho Chehab 	case CIT_MODEL1:
30160c0d06caSMauro Carvalho Chehab 		has_brightness = has_contrast =
30170c0d06caSMauro Carvalho Chehab 			has_sharpness = has_lighting = true;
30180c0d06caSMauro Carvalho Chehab 		break;
30190c0d06caSMauro Carvalho Chehab 	case CIT_MODEL2:
30200c0d06caSMauro Carvalho Chehab 		has_brightness = has_hue = has_lighting = true;
30210c0d06caSMauro Carvalho Chehab 		break;
30220c0d06caSMauro Carvalho Chehab 	case CIT_MODEL3:
30230c0d06caSMauro Carvalho Chehab 		has_brightness = has_contrast = has_sharpness = true;
30240c0d06caSMauro Carvalho Chehab 		break;
30250c0d06caSMauro Carvalho Chehab 	case CIT_MODEL4:
30260c0d06caSMauro Carvalho Chehab 		has_brightness = has_hue = true;
30270c0d06caSMauro Carvalho Chehab 		break;
30280c0d06caSMauro Carvalho Chehab 	case CIT_IBM_NETCAM_PRO:
30290c0d06caSMauro Carvalho Chehab 		has_brightness = has_hue =
30300c0d06caSMauro Carvalho Chehab 			has_sharpness = has_hflip = has_lighting = true;
30310c0d06caSMauro Carvalho Chehab 		break;
30320c0d06caSMauro Carvalho Chehab 	}
30330c0d06caSMauro Carvalho Chehab 	gspca_dev->vdev.ctrl_handler = hdl;
30340c0d06caSMauro Carvalho Chehab 	v4l2_ctrl_handler_init(hdl, 5);
30350c0d06caSMauro Carvalho Chehab 	if (has_brightness)
30360c0d06caSMauro Carvalho Chehab 		v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
30370c0d06caSMauro Carvalho Chehab 			V4L2_CID_BRIGHTNESS, 0, 63, 1, 32);
30380c0d06caSMauro Carvalho Chehab 	if (has_contrast)
30390c0d06caSMauro Carvalho Chehab 		v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
30400c0d06caSMauro Carvalho Chehab 			V4L2_CID_CONTRAST, 0, 20, 1, 10);
30410c0d06caSMauro Carvalho Chehab 	if (has_hue)
30420c0d06caSMauro Carvalho Chehab 		v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
30430c0d06caSMauro Carvalho Chehab 			V4L2_CID_HUE, 0, 127, 1, 63);
30440c0d06caSMauro Carvalho Chehab 	if (has_sharpness)
30450c0d06caSMauro Carvalho Chehab 		v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
30460c0d06caSMauro Carvalho Chehab 			V4L2_CID_SHARPNESS, 0, 6, 1, 3);
30470c0d06caSMauro Carvalho Chehab 	if (has_lighting)
30480c0d06caSMauro Carvalho Chehab 		sd->lighting = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
30490c0d06caSMauro Carvalho Chehab 			V4L2_CID_BACKLIGHT_COMPENSATION, 0, 2, 1, 1);
30500c0d06caSMauro Carvalho Chehab 	if (has_hflip)
30510c0d06caSMauro Carvalho Chehab 		v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
30520c0d06caSMauro Carvalho Chehab 			V4L2_CID_HFLIP, 0, 1, 1, 0);
30530c0d06caSMauro Carvalho Chehab 
30540c0d06caSMauro Carvalho Chehab 	if (hdl->error) {
30550c0d06caSMauro Carvalho Chehab 		pr_err("Could not initialize controls\n");
30560c0d06caSMauro Carvalho Chehab 		return hdl->error;
30570c0d06caSMauro Carvalho Chehab 	}
30580c0d06caSMauro Carvalho Chehab 	return 0;
30590c0d06caSMauro Carvalho Chehab }
30600c0d06caSMauro Carvalho Chehab 
30610c0d06caSMauro Carvalho Chehab /* sub-driver description */
30620c0d06caSMauro Carvalho Chehab static const struct sd_desc sd_desc = {
30630c0d06caSMauro Carvalho Chehab 	.name = MODULE_NAME,
30640c0d06caSMauro Carvalho Chehab 	.config = sd_config,
30650c0d06caSMauro Carvalho Chehab 	.init = sd_init,
30660c0d06caSMauro Carvalho Chehab 	.init_controls = sd_init_controls,
30670c0d06caSMauro Carvalho Chehab 	.start = sd_start,
30680c0d06caSMauro Carvalho Chehab 	.stopN = sd_stopN,
30690c0d06caSMauro Carvalho Chehab 	.stop0 = sd_stop0,
30700c0d06caSMauro Carvalho Chehab 	.pkt_scan = sd_pkt_scan,
3071e32d6eb8SPeter Senna Tschudin #if IS_ENABLED(CONFIG_INPUT)
30720c0d06caSMauro Carvalho Chehab 	.dq_callback = cit_check_button,
30730c0d06caSMauro Carvalho Chehab 	.other_input = 1,
30740c0d06caSMauro Carvalho Chehab #endif
30750c0d06caSMauro Carvalho Chehab };
30760c0d06caSMauro Carvalho Chehab 
30770c0d06caSMauro Carvalho Chehab static const struct sd_desc sd_desc_isoc_nego = {
30780c0d06caSMauro Carvalho Chehab 	.name = MODULE_NAME,
30790c0d06caSMauro Carvalho Chehab 	.config = sd_config,
30800c0d06caSMauro Carvalho Chehab 	.init = sd_init,
30810c0d06caSMauro Carvalho Chehab 	.init_controls = sd_init_controls,
30820c0d06caSMauro Carvalho Chehab 	.start = sd_start,
30830c0d06caSMauro Carvalho Chehab 	.isoc_init = sd_isoc_init,
30840c0d06caSMauro Carvalho Chehab 	.isoc_nego = sd_isoc_nego,
30850c0d06caSMauro Carvalho Chehab 	.stopN = sd_stopN,
30860c0d06caSMauro Carvalho Chehab 	.stop0 = sd_stop0,
30870c0d06caSMauro Carvalho Chehab 	.pkt_scan = sd_pkt_scan,
3088e32d6eb8SPeter Senna Tschudin #if IS_ENABLED(CONFIG_INPUT)
30890c0d06caSMauro Carvalho Chehab 	.dq_callback = cit_check_button,
30900c0d06caSMauro Carvalho Chehab 	.other_input = 1,
30910c0d06caSMauro Carvalho Chehab #endif
30920c0d06caSMauro Carvalho Chehab };
30930c0d06caSMauro Carvalho Chehab 
30940c0d06caSMauro Carvalho Chehab /* -- module initialisation -- */
30950c0d06caSMauro Carvalho Chehab static const struct usb_device_id device_table[] = {
30960c0d06caSMauro Carvalho Chehab 	{ USB_DEVICE_VER(0x0545, 0x8080, 0x0001, 0x0001), .driver_info = CIT_MODEL0 },
30970c0d06caSMauro Carvalho Chehab 	{ USB_DEVICE_VER(0x0545, 0x8080, 0x0002, 0x0002), .driver_info = CIT_MODEL1 },
30980c0d06caSMauro Carvalho Chehab 	{ USB_DEVICE_VER(0x0545, 0x8080, 0x030a, 0x030a), .driver_info = CIT_MODEL2 },
30990c0d06caSMauro Carvalho Chehab 	{ USB_DEVICE_VER(0x0545, 0x8080, 0x0301, 0x0301), .driver_info = CIT_MODEL3 },
31000c0d06caSMauro Carvalho Chehab 	{ USB_DEVICE_VER(0x0545, 0x8002, 0x030a, 0x030a), .driver_info = CIT_MODEL4 },
31010c0d06caSMauro Carvalho Chehab 	{ USB_DEVICE_VER(0x0545, 0x800c, 0x030a, 0x030a), .driver_info = CIT_MODEL2 },
31020c0d06caSMauro Carvalho Chehab 	{ USB_DEVICE_VER(0x0545, 0x800d, 0x030a, 0x030a), .driver_info = CIT_MODEL4 },
31030c0d06caSMauro Carvalho Chehab 	{}
31040c0d06caSMauro Carvalho Chehab };
31050c0d06caSMauro Carvalho Chehab MODULE_DEVICE_TABLE(usb, device_table);
31060c0d06caSMauro Carvalho Chehab 
31070c0d06caSMauro Carvalho Chehab /* -- device connect -- */
sd_probe(struct usb_interface * intf,const struct usb_device_id * id)31080c0d06caSMauro Carvalho Chehab static int sd_probe(struct usb_interface *intf,
31090c0d06caSMauro Carvalho Chehab 			const struct usb_device_id *id)
31100c0d06caSMauro Carvalho Chehab {
31110c0d06caSMauro Carvalho Chehab 	const struct sd_desc *desc = &sd_desc;
31120c0d06caSMauro Carvalho Chehab 
31130c0d06caSMauro Carvalho Chehab 	switch (id->driver_info) {
31140c0d06caSMauro Carvalho Chehab 	case CIT_MODEL0:
31150c0d06caSMauro Carvalho Chehab 	case CIT_MODEL1:
31160c0d06caSMauro Carvalho Chehab 		if (intf->cur_altsetting->desc.bInterfaceNumber != 2)
31170c0d06caSMauro Carvalho Chehab 			return -ENODEV;
31180c0d06caSMauro Carvalho Chehab 		break;
31190c0d06caSMauro Carvalho Chehab 	case CIT_MODEL2:
31200c0d06caSMauro Carvalho Chehab 	case CIT_MODEL4:
31210c0d06caSMauro Carvalho Chehab 		if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
31220c0d06caSMauro Carvalho Chehab 			return -ENODEV;
31230c0d06caSMauro Carvalho Chehab 		break;
31240c0d06caSMauro Carvalho Chehab 	case CIT_MODEL3:
31250c0d06caSMauro Carvalho Chehab 		if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
31260c0d06caSMauro Carvalho Chehab 			return -ENODEV;
31270c0d06caSMauro Carvalho Chehab 		/* FIXME this likely applies to all model3 cams and probably
31280c0d06caSMauro Carvalho Chehab 		   to other models too. */
31290c0d06caSMauro Carvalho Chehab 		if (ibm_netcam_pro)
31300c0d06caSMauro Carvalho Chehab 			desc = &sd_desc_isoc_nego;
31310c0d06caSMauro Carvalho Chehab 		break;
31320c0d06caSMauro Carvalho Chehab 	}
31330c0d06caSMauro Carvalho Chehab 
31340c0d06caSMauro Carvalho Chehab 	return gspca_dev_probe2(intf, id, desc, sizeof(struct sd), THIS_MODULE);
31350c0d06caSMauro Carvalho Chehab }
31360c0d06caSMauro Carvalho Chehab 
31370c0d06caSMauro Carvalho Chehab static struct usb_driver sd_driver = {
31380c0d06caSMauro Carvalho Chehab 	.name = MODULE_NAME,
31390c0d06caSMauro Carvalho Chehab 	.id_table = device_table,
31400c0d06caSMauro Carvalho Chehab 	.probe = sd_probe,
31410c0d06caSMauro Carvalho Chehab 	.disconnect = gspca_disconnect,
31420c0d06caSMauro Carvalho Chehab #ifdef CONFIG_PM
31430c0d06caSMauro Carvalho Chehab 	.suspend = gspca_suspend,
31440c0d06caSMauro Carvalho Chehab 	.resume = gspca_resume,
31450c0d06caSMauro Carvalho Chehab 	.reset_resume = gspca_resume,
31460c0d06caSMauro Carvalho Chehab #endif
31470c0d06caSMauro Carvalho Chehab };
31480c0d06caSMauro Carvalho Chehab 
31490c0d06caSMauro Carvalho Chehab module_usb_driver(sd_driver);
3150