18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * USB IBM C-It Video Camera driver
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Supports Xirlink C-It Video Camera, IBM PC Camera,
68c2ecf20Sopenharmony_ci * IBM NetCamera and Veo Stingray.
78c2ecf20Sopenharmony_ci *
88c2ecf20Sopenharmony_ci * Copyright (C) 2010 Hans de Goede <hdegoede@redhat.com>
98c2ecf20Sopenharmony_ci *
108c2ecf20Sopenharmony_ci * This driver is based on earlier work of:
118c2ecf20Sopenharmony_ci *
128c2ecf20Sopenharmony_ci * (C) Copyright 1999 Johannes Erdfelt
138c2ecf20Sopenharmony_ci * (C) Copyright 1999 Randy Dunlap
148c2ecf20Sopenharmony_ci */
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci#define MODULE_NAME "xirlink-cit"
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_ci#include <linux/input.h>
218c2ecf20Sopenharmony_ci#include "gspca.h"
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ciMODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
248c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("Xirlink C-IT");
258c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL");
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_ci/* FIXME we should autodetect this */
288c2ecf20Sopenharmony_cistatic int ibm_netcam_pro;
298c2ecf20Sopenharmony_cimodule_param(ibm_netcam_pro, int, 0);
308c2ecf20Sopenharmony_ciMODULE_PARM_DESC(ibm_netcam_pro,
318c2ecf20Sopenharmony_ci		 "Use IBM Netcamera Pro init sequences for Model 3 cams");
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_ci/* FIXME this should be handled through the V4L2 input selection API */
348c2ecf20Sopenharmony_cistatic int rca_input;
358c2ecf20Sopenharmony_cimodule_param(rca_input, int, 0644);
368c2ecf20Sopenharmony_ciMODULE_PARM_DESC(rca_input,
378c2ecf20Sopenharmony_ci		 "Use rca input instead of ccd sensor on Model 3 cams");
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ci/* specific webcam descriptor */
408c2ecf20Sopenharmony_cistruct sd {
418c2ecf20Sopenharmony_ci	struct gspca_dev gspca_dev;		/* !! must be the first item */
428c2ecf20Sopenharmony_ci	struct v4l2_ctrl *lighting;
438c2ecf20Sopenharmony_ci	u8 model;
448c2ecf20Sopenharmony_ci#define CIT_MODEL0 0 /* bcd version 0.01 cams ie the xvp-500 */
458c2ecf20Sopenharmony_ci#define CIT_MODEL1 1 /* The model 1 - 4 nomenclature comes from the old */
468c2ecf20Sopenharmony_ci#define CIT_MODEL2 2 /* ibmcam driver */
478c2ecf20Sopenharmony_ci#define CIT_MODEL3 3
488c2ecf20Sopenharmony_ci#define CIT_MODEL4 4
498c2ecf20Sopenharmony_ci#define CIT_IBM_NETCAM_PRO 5
508c2ecf20Sopenharmony_ci	u8 input_index;
518c2ecf20Sopenharmony_ci	u8 button_state;
528c2ecf20Sopenharmony_ci	u8 stop_on_control_change;
538c2ecf20Sopenharmony_ci	u8 sof_read;
548c2ecf20Sopenharmony_ci	u8 sof_len;
558c2ecf20Sopenharmony_ci};
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_cistatic void sd_stop0(struct gspca_dev *gspca_dev);
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_cistatic const struct v4l2_pix_format cif_yuv_mode[] = {
608c2ecf20Sopenharmony_ci	{176, 144, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
618c2ecf20Sopenharmony_ci		.bytesperline = 176,
628c2ecf20Sopenharmony_ci		.sizeimage = 176 * 144 * 3 / 2 + 4,
638c2ecf20Sopenharmony_ci		.colorspace = V4L2_COLORSPACE_SRGB},
648c2ecf20Sopenharmony_ci	{352, 288, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
658c2ecf20Sopenharmony_ci		.bytesperline = 352,
668c2ecf20Sopenharmony_ci		.sizeimage = 352 * 288 * 3 / 2 + 4,
678c2ecf20Sopenharmony_ci		.colorspace = V4L2_COLORSPACE_SRGB},
688c2ecf20Sopenharmony_ci};
698c2ecf20Sopenharmony_ci
708c2ecf20Sopenharmony_cistatic const struct v4l2_pix_format vga_yuv_mode[] = {
718c2ecf20Sopenharmony_ci	{160, 120, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
728c2ecf20Sopenharmony_ci		.bytesperline = 160,
738c2ecf20Sopenharmony_ci		.sizeimage = 160 * 120 * 3 / 2 + 4,
748c2ecf20Sopenharmony_ci		.colorspace = V4L2_COLORSPACE_SRGB},
758c2ecf20Sopenharmony_ci	{320, 240, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
768c2ecf20Sopenharmony_ci		.bytesperline = 320,
778c2ecf20Sopenharmony_ci		.sizeimage = 320 * 240 * 3 / 2 + 4,
788c2ecf20Sopenharmony_ci		.colorspace = V4L2_COLORSPACE_SRGB},
798c2ecf20Sopenharmony_ci	{640, 480, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
808c2ecf20Sopenharmony_ci		.bytesperline = 640,
818c2ecf20Sopenharmony_ci		.sizeimage = 640 * 480 * 3 / 2 + 4,
828c2ecf20Sopenharmony_ci		.colorspace = V4L2_COLORSPACE_SRGB},
838c2ecf20Sopenharmony_ci};
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_cistatic const struct v4l2_pix_format model0_mode[] = {
868c2ecf20Sopenharmony_ci	{160, 120, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
878c2ecf20Sopenharmony_ci		.bytesperline = 160,
888c2ecf20Sopenharmony_ci		.sizeimage = 160 * 120 * 3 / 2 + 4,
898c2ecf20Sopenharmony_ci		.colorspace = V4L2_COLORSPACE_SRGB},
908c2ecf20Sopenharmony_ci	{176, 144, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
918c2ecf20Sopenharmony_ci		.bytesperline = 176,
928c2ecf20Sopenharmony_ci		.sizeimage = 176 * 144 * 3 / 2 + 4,
938c2ecf20Sopenharmony_ci		.colorspace = V4L2_COLORSPACE_SRGB},
948c2ecf20Sopenharmony_ci	{320, 240, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
958c2ecf20Sopenharmony_ci		.bytesperline = 320,
968c2ecf20Sopenharmony_ci		.sizeimage = 320 * 240 * 3 / 2 + 4,
978c2ecf20Sopenharmony_ci		.colorspace = V4L2_COLORSPACE_SRGB},
988c2ecf20Sopenharmony_ci};
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_cistatic const struct v4l2_pix_format model2_mode[] = {
1018c2ecf20Sopenharmony_ci	{160, 120, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
1028c2ecf20Sopenharmony_ci		.bytesperline = 160,
1038c2ecf20Sopenharmony_ci		.sizeimage = 160 * 120 * 3 / 2 + 4,
1048c2ecf20Sopenharmony_ci		.colorspace = V4L2_COLORSPACE_SRGB},
1058c2ecf20Sopenharmony_ci	{176, 144, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
1068c2ecf20Sopenharmony_ci		.bytesperline = 176,
1078c2ecf20Sopenharmony_ci		.sizeimage = 176 * 144 * 3 / 2 + 4,
1088c2ecf20Sopenharmony_ci		.colorspace = V4L2_COLORSPACE_SRGB},
1098c2ecf20Sopenharmony_ci	{320, 240, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
1108c2ecf20Sopenharmony_ci		.bytesperline = 320,
1118c2ecf20Sopenharmony_ci		.sizeimage = 320 * 240 + 4,
1128c2ecf20Sopenharmony_ci		.colorspace = V4L2_COLORSPACE_SRGB},
1138c2ecf20Sopenharmony_ci	{352, 288, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
1148c2ecf20Sopenharmony_ci		.bytesperline = 352,
1158c2ecf20Sopenharmony_ci		.sizeimage = 352 * 288 + 4,
1168c2ecf20Sopenharmony_ci		.colorspace = V4L2_COLORSPACE_SRGB},
1178c2ecf20Sopenharmony_ci};
1188c2ecf20Sopenharmony_ci
1198c2ecf20Sopenharmony_ci/*
1208c2ecf20Sopenharmony_ci * 01.01.08 - Added for RCA video in support -LO
1218c2ecf20Sopenharmony_ci * This struct is used to init the Model3 cam to use the RCA video in port
1228c2ecf20Sopenharmony_ci * instead of the CCD sensor.
1238c2ecf20Sopenharmony_ci */
1248c2ecf20Sopenharmony_cistatic const u16 rca_initdata[][3] = {
1258c2ecf20Sopenharmony_ci	{0, 0x0000, 0x010c},
1268c2ecf20Sopenharmony_ci	{0, 0x0006, 0x012c},
1278c2ecf20Sopenharmony_ci	{0, 0x0078, 0x012d},
1288c2ecf20Sopenharmony_ci	{0, 0x0046, 0x012f},
1298c2ecf20Sopenharmony_ci	{0, 0xd141, 0x0124},
1308c2ecf20Sopenharmony_ci	{0, 0x0000, 0x0127},
1318c2ecf20Sopenharmony_ci	{0, 0xfea8, 0x0124},
1328c2ecf20Sopenharmony_ci	{1, 0x0000, 0x0116},
1338c2ecf20Sopenharmony_ci	{0, 0x0064, 0x0116},
1348c2ecf20Sopenharmony_ci	{1, 0x0000, 0x0115},
1358c2ecf20Sopenharmony_ci	{0, 0x0003, 0x0115},
1368c2ecf20Sopenharmony_ci	{0, 0x0008, 0x0123},
1378c2ecf20Sopenharmony_ci	{0, 0x0000, 0x0117},
1388c2ecf20Sopenharmony_ci	{0, 0x0000, 0x0112},
1398c2ecf20Sopenharmony_ci	{0, 0x0080, 0x0100},
1408c2ecf20Sopenharmony_ci	{0, 0x0000, 0x0100},
1418c2ecf20Sopenharmony_ci	{1, 0x0000, 0x0116},
1428c2ecf20Sopenharmony_ci	{0, 0x0060, 0x0116},
1438c2ecf20Sopenharmony_ci	{0, 0x0002, 0x0112},
1448c2ecf20Sopenharmony_ci	{0, 0x0000, 0x0123},
1458c2ecf20Sopenharmony_ci	{0, 0x0001, 0x0117},
1468c2ecf20Sopenharmony_ci	{0, 0x0040, 0x0108},
1478c2ecf20Sopenharmony_ci	{0, 0x0019, 0x012c},
1488c2ecf20Sopenharmony_ci	{0, 0x0040, 0x0116},
1498c2ecf20Sopenharmony_ci	{0, 0x000a, 0x0115},
1508c2ecf20Sopenharmony_ci	{0, 0x000b, 0x0115},
1518c2ecf20Sopenharmony_ci	{0, 0x0078, 0x012d},
1528c2ecf20Sopenharmony_ci	{0, 0x0046, 0x012f},
1538c2ecf20Sopenharmony_ci	{0, 0xd141, 0x0124},
1548c2ecf20Sopenharmony_ci	{0, 0x0000, 0x0127},
1558c2ecf20Sopenharmony_ci	{0, 0xfea8, 0x0124},
1568c2ecf20Sopenharmony_ci	{0, 0x0064, 0x0116},
1578c2ecf20Sopenharmony_ci	{0, 0x0000, 0x0115},
1588c2ecf20Sopenharmony_ci	{0, 0x0001, 0x0115},
1598c2ecf20Sopenharmony_ci	{0, 0xffff, 0x0124},
1608c2ecf20Sopenharmony_ci	{0, 0xfff9, 0x0124},
1618c2ecf20Sopenharmony_ci	{0, 0x0086, 0x0127},
1628c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
1638c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
1648c2ecf20Sopenharmony_ci	{0, 0x00aa, 0x0127},
1658c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
1668c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
1678c2ecf20Sopenharmony_ci	{0, 0x0000, 0x0127},
1688c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
1698c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
1708c2ecf20Sopenharmony_ci	{0, 0xfffa, 0x0124},
1718c2ecf20Sopenharmony_ci	{0, 0xffff, 0x0124},
1728c2ecf20Sopenharmony_ci	{0, 0xfff9, 0x0124},
1738c2ecf20Sopenharmony_ci	{0, 0x0086, 0x0127},
1748c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
1758c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
1768c2ecf20Sopenharmony_ci	{0, 0x00f2, 0x0127},
1778c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
1788c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
1798c2ecf20Sopenharmony_ci	{0, 0x000f, 0x0127},
1808c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
1818c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
1828c2ecf20Sopenharmony_ci	{0, 0xfffa, 0x0124},
1838c2ecf20Sopenharmony_ci	{0, 0xffff, 0x0124},
1848c2ecf20Sopenharmony_ci	{0, 0xfff9, 0x0124},
1858c2ecf20Sopenharmony_ci	{0, 0x0086, 0x0127},
1868c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
1878c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
1888c2ecf20Sopenharmony_ci	{0, 0x00f8, 0x0127},
1898c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
1908c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
1918c2ecf20Sopenharmony_ci	{0, 0x00fc, 0x0127},
1928c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
1938c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
1948c2ecf20Sopenharmony_ci	{0, 0xfffa, 0x0124},
1958c2ecf20Sopenharmony_ci	{0, 0xffff, 0x0124},
1968c2ecf20Sopenharmony_ci	{0, 0xfff9, 0x0124},
1978c2ecf20Sopenharmony_ci	{0, 0x0086, 0x0127},
1988c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
1998c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
2008c2ecf20Sopenharmony_ci	{0, 0x00f9, 0x0127},
2018c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
2028c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
2038c2ecf20Sopenharmony_ci	{0, 0x003c, 0x0127},
2048c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
2058c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
2068c2ecf20Sopenharmony_ci	{0, 0xfffa, 0x0124},
2078c2ecf20Sopenharmony_ci	{0, 0xffff, 0x0124},
2088c2ecf20Sopenharmony_ci	{0, 0xfff9, 0x0124},
2098c2ecf20Sopenharmony_ci	{0, 0x0086, 0x0127},
2108c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
2118c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
2128c2ecf20Sopenharmony_ci	{0, 0x0027, 0x0127},
2138c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
2148c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
2158c2ecf20Sopenharmony_ci	{0, 0x0019, 0x0127},
2168c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
2178c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
2188c2ecf20Sopenharmony_ci	{0, 0xfffa, 0x0124},
2198c2ecf20Sopenharmony_ci	{0, 0xfff9, 0x0124},
2208c2ecf20Sopenharmony_ci	{0, 0x0086, 0x0127},
2218c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
2228c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
2238c2ecf20Sopenharmony_ci	{0, 0x0037, 0x0127},
2248c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
2258c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
2268c2ecf20Sopenharmony_ci	{0, 0x0000, 0x0127},
2278c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
2288c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
2298c2ecf20Sopenharmony_ci	{0, 0x0021, 0x0127},
2308c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
2318c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
2328c2ecf20Sopenharmony_ci	{0, 0xfffa, 0x0124},
2338c2ecf20Sopenharmony_ci	{0, 0xfff9, 0x0124},
2348c2ecf20Sopenharmony_ci	{0, 0x0086, 0x0127},
2358c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
2368c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
2378c2ecf20Sopenharmony_ci	{0, 0x0038, 0x0127},
2388c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
2398c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
2408c2ecf20Sopenharmony_ci	{0, 0x0006, 0x0127},
2418c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
2428c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
2438c2ecf20Sopenharmony_ci	{0, 0x0045, 0x0127},
2448c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
2458c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
2468c2ecf20Sopenharmony_ci	{0, 0xfffa, 0x0124},
2478c2ecf20Sopenharmony_ci	{0, 0xfff9, 0x0124},
2488c2ecf20Sopenharmony_ci	{0, 0x0086, 0x0127},
2498c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
2508c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
2518c2ecf20Sopenharmony_ci	{0, 0x0037, 0x0127},
2528c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
2538c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
2548c2ecf20Sopenharmony_ci	{0, 0x0001, 0x0127},
2558c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
2568c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
2578c2ecf20Sopenharmony_ci	{0, 0x002a, 0x0127},
2588c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
2598c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
2608c2ecf20Sopenharmony_ci	{0, 0xfffa, 0x0124},
2618c2ecf20Sopenharmony_ci	{0, 0xfff9, 0x0124},
2628c2ecf20Sopenharmony_ci	{0, 0x0086, 0x0127},
2638c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
2648c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
2658c2ecf20Sopenharmony_ci	{0, 0x0038, 0x0127},
2668c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
2678c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
2688c2ecf20Sopenharmony_ci	{0, 0x0000, 0x0127},
2698c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
2708c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
2718c2ecf20Sopenharmony_ci	{0, 0x000e, 0x0127},
2728c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
2738c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
2748c2ecf20Sopenharmony_ci	{0, 0xfffa, 0x0124},
2758c2ecf20Sopenharmony_ci	{0, 0xfff9, 0x0124},
2768c2ecf20Sopenharmony_ci	{0, 0x0086, 0x0127},
2778c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
2788c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
2798c2ecf20Sopenharmony_ci	{0, 0x0037, 0x0127},
2808c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
2818c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
2828c2ecf20Sopenharmony_ci	{0, 0x0001, 0x0127},
2838c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
2848c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
2858c2ecf20Sopenharmony_ci	{0, 0x002b, 0x0127},
2868c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
2878c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
2888c2ecf20Sopenharmony_ci	{0, 0xfffa, 0x0124},
2898c2ecf20Sopenharmony_ci	{0, 0xfff9, 0x0124},
2908c2ecf20Sopenharmony_ci	{0, 0x0086, 0x0127},
2918c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
2928c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
2938c2ecf20Sopenharmony_ci	{0, 0x0038, 0x0127},
2948c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
2958c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
2968c2ecf20Sopenharmony_ci	{0, 0x0001, 0x0127},
2978c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
2988c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
2998c2ecf20Sopenharmony_ci	{0, 0x00f4, 0x0127},
3008c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
3018c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
3028c2ecf20Sopenharmony_ci	{0, 0xfffa, 0x0124},
3038c2ecf20Sopenharmony_ci	{0, 0xfff9, 0x0124},
3048c2ecf20Sopenharmony_ci	{0, 0x0086, 0x0127},
3058c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
3068c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
3078c2ecf20Sopenharmony_ci	{0, 0x0037, 0x0127},
3088c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
3098c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
3108c2ecf20Sopenharmony_ci	{0, 0x0001, 0x0127},
3118c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
3128c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
3138c2ecf20Sopenharmony_ci	{0, 0x002c, 0x0127},
3148c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
3158c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
3168c2ecf20Sopenharmony_ci	{0, 0xfffa, 0x0124},
3178c2ecf20Sopenharmony_ci	{0, 0xfff9, 0x0124},
3188c2ecf20Sopenharmony_ci	{0, 0x0086, 0x0127},
3198c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
3208c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
3218c2ecf20Sopenharmony_ci	{0, 0x0038, 0x0127},
3228c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
3238c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
3248c2ecf20Sopenharmony_ci	{0, 0x0001, 0x0127},
3258c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
3268c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
3278c2ecf20Sopenharmony_ci	{0, 0x0004, 0x0127},
3288c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
3298c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
3308c2ecf20Sopenharmony_ci	{0, 0xfffa, 0x0124},
3318c2ecf20Sopenharmony_ci	{0, 0xfff9, 0x0124},
3328c2ecf20Sopenharmony_ci	{0, 0x0086, 0x0127},
3338c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
3348c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
3358c2ecf20Sopenharmony_ci	{0, 0x0037, 0x0127},
3368c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
3378c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
3388c2ecf20Sopenharmony_ci	{0, 0x0001, 0x0127},
3398c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
3408c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
3418c2ecf20Sopenharmony_ci	{0, 0x002d, 0x0127},
3428c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
3438c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
3448c2ecf20Sopenharmony_ci	{0, 0xfffa, 0x0124},
3458c2ecf20Sopenharmony_ci	{0, 0xfff9, 0x0124},
3468c2ecf20Sopenharmony_ci	{0, 0x0086, 0x0127},
3478c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
3488c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
3498c2ecf20Sopenharmony_ci	{0, 0x0038, 0x0127},
3508c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
3518c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
3528c2ecf20Sopenharmony_ci	{0, 0x0000, 0x0127},
3538c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
3548c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
3558c2ecf20Sopenharmony_ci	{0, 0x0014, 0x0127},
3568c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
3578c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
3588c2ecf20Sopenharmony_ci	{0, 0xfffa, 0x0124},
3598c2ecf20Sopenharmony_ci	{0, 0xfff9, 0x0124},
3608c2ecf20Sopenharmony_ci	{0, 0x0086, 0x0127},
3618c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
3628c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
3638c2ecf20Sopenharmony_ci	{0, 0x0037, 0x0127},
3648c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
3658c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
3668c2ecf20Sopenharmony_ci	{0, 0x0001, 0x0127},
3678c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
3688c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
3698c2ecf20Sopenharmony_ci	{0, 0x002e, 0x0127},
3708c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
3718c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
3728c2ecf20Sopenharmony_ci	{0, 0xfffa, 0x0124},
3738c2ecf20Sopenharmony_ci	{0, 0xfff9, 0x0124},
3748c2ecf20Sopenharmony_ci	{0, 0x0086, 0x0127},
3758c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
3768c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
3778c2ecf20Sopenharmony_ci	{0, 0x0038, 0x0127},
3788c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
3798c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
3808c2ecf20Sopenharmony_ci	{0, 0x0003, 0x0127},
3818c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
3828c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
3838c2ecf20Sopenharmony_ci	{0, 0x0000, 0x0127},
3848c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
3858c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
3868c2ecf20Sopenharmony_ci	{0, 0xfffa, 0x0124},
3878c2ecf20Sopenharmony_ci	{0, 0xfff9, 0x0124},
3888c2ecf20Sopenharmony_ci	{0, 0x0086, 0x0127},
3898c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
3908c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
3918c2ecf20Sopenharmony_ci	{0, 0x0037, 0x0127},
3928c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
3938c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
3948c2ecf20Sopenharmony_ci	{0, 0x0001, 0x0127},
3958c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
3968c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
3978c2ecf20Sopenharmony_ci	{0, 0x002f, 0x0127},
3988c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
3998c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
4008c2ecf20Sopenharmony_ci	{0, 0xfffa, 0x0124},
4018c2ecf20Sopenharmony_ci	{0, 0xfff9, 0x0124},
4028c2ecf20Sopenharmony_ci	{0, 0x0086, 0x0127},
4038c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
4048c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
4058c2ecf20Sopenharmony_ci	{0, 0x0038, 0x0127},
4068c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
4078c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
4088c2ecf20Sopenharmony_ci	{0, 0x0003, 0x0127},
4098c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
4108c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
4118c2ecf20Sopenharmony_ci	{0, 0x0014, 0x0127},
4128c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
4138c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
4148c2ecf20Sopenharmony_ci	{0, 0xfffa, 0x0124},
4158c2ecf20Sopenharmony_ci	{0, 0xfff9, 0x0124},
4168c2ecf20Sopenharmony_ci	{0, 0x0086, 0x0127},
4178c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
4188c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
4198c2ecf20Sopenharmony_ci	{0, 0x0037, 0x0127},
4208c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
4218c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
4228c2ecf20Sopenharmony_ci	{0, 0x0001, 0x0127},
4238c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
4248c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
4258c2ecf20Sopenharmony_ci	{0, 0x0040, 0x0127},
4268c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
4278c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
4288c2ecf20Sopenharmony_ci	{0, 0xfffa, 0x0124},
4298c2ecf20Sopenharmony_ci	{0, 0xfff9, 0x0124},
4308c2ecf20Sopenharmony_ci	{0, 0x0086, 0x0127},
4318c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
4328c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
4338c2ecf20Sopenharmony_ci	{0, 0x0038, 0x0127},
4348c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
4358c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
4368c2ecf20Sopenharmony_ci	{0, 0x0000, 0x0127},
4378c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
4388c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
4398c2ecf20Sopenharmony_ci	{0, 0x0040, 0x0127},
4408c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
4418c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
4428c2ecf20Sopenharmony_ci	{0, 0xfffa, 0x0124},
4438c2ecf20Sopenharmony_ci	{0, 0xfff9, 0x0124},
4448c2ecf20Sopenharmony_ci	{0, 0x0086, 0x0127},
4458c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
4468c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
4478c2ecf20Sopenharmony_ci	{0, 0x0037, 0x0127},
4488c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
4498c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
4508c2ecf20Sopenharmony_ci	{0, 0x0001, 0x0127},
4518c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
4528c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
4538c2ecf20Sopenharmony_ci	{0, 0x0053, 0x0127},
4548c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
4558c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
4568c2ecf20Sopenharmony_ci	{0, 0xfffa, 0x0124},
4578c2ecf20Sopenharmony_ci	{0, 0xfff9, 0x0124},
4588c2ecf20Sopenharmony_ci	{0, 0x0086, 0x0127},
4598c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
4608c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
4618c2ecf20Sopenharmony_ci	{0, 0x0038, 0x0127},
4628c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
4638c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
4648c2ecf20Sopenharmony_ci	{0, 0x0000, 0x0127},
4658c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
4668c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
4678c2ecf20Sopenharmony_ci	{0, 0x0038, 0x0127},
4688c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
4698c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
4708c2ecf20Sopenharmony_ci	{0, 0xfffa, 0x0124},
4718c2ecf20Sopenharmony_ci	{0, 0x0000, 0x0101},
4728c2ecf20Sopenharmony_ci	{0, 0x00a0, 0x0103},
4738c2ecf20Sopenharmony_ci	{0, 0x0078, 0x0105},
4748c2ecf20Sopenharmony_ci	{0, 0x0000, 0x010a},
4758c2ecf20Sopenharmony_ci	{0, 0x0024, 0x010b},
4768c2ecf20Sopenharmony_ci	{0, 0x0028, 0x0119},
4778c2ecf20Sopenharmony_ci	{0, 0x0088, 0x011b},
4788c2ecf20Sopenharmony_ci	{0, 0x0002, 0x011d},
4798c2ecf20Sopenharmony_ci	{0, 0x0003, 0x011e},
4808c2ecf20Sopenharmony_ci	{0, 0x0000, 0x0129},
4818c2ecf20Sopenharmony_ci	{0, 0x00fc, 0x012b},
4828c2ecf20Sopenharmony_ci	{0, 0x0008, 0x0102},
4838c2ecf20Sopenharmony_ci	{0, 0x0000, 0x0104},
4848c2ecf20Sopenharmony_ci	{0, 0x0008, 0x011a},
4858c2ecf20Sopenharmony_ci	{0, 0x0028, 0x011c},
4868c2ecf20Sopenharmony_ci	{0, 0x0021, 0x012a},
4878c2ecf20Sopenharmony_ci	{0, 0x0000, 0x0118},
4888c2ecf20Sopenharmony_ci	{0, 0x0000, 0x0132},
4898c2ecf20Sopenharmony_ci	{0, 0x0000, 0x0109},
4908c2ecf20Sopenharmony_ci	{0, 0xfff9, 0x0124},
4918c2ecf20Sopenharmony_ci	{0, 0x0086, 0x0127},
4928c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
4938c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
4948c2ecf20Sopenharmony_ci	{0, 0x0037, 0x0127},
4958c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
4968c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
4978c2ecf20Sopenharmony_ci	{0, 0x0001, 0x0127},
4988c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
4998c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
5008c2ecf20Sopenharmony_ci	{0, 0x0031, 0x0127},
5018c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
5028c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
5038c2ecf20Sopenharmony_ci	{0, 0xfffa, 0x0124},
5048c2ecf20Sopenharmony_ci	{0, 0xfff9, 0x0124},
5058c2ecf20Sopenharmony_ci	{0, 0x0086, 0x0127},
5068c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
5078c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
5088c2ecf20Sopenharmony_ci	{0, 0x0038, 0x0127},
5098c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
5108c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
5118c2ecf20Sopenharmony_ci	{0, 0x0000, 0x0127},
5128c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
5138c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
5148c2ecf20Sopenharmony_ci	{0, 0x0000, 0x0127},
5158c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
5168c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
5178c2ecf20Sopenharmony_ci	{0, 0xfffa, 0x0124},
5188c2ecf20Sopenharmony_ci	{0, 0xfff9, 0x0124},
5198c2ecf20Sopenharmony_ci	{0, 0x0086, 0x0127},
5208c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
5218c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
5228c2ecf20Sopenharmony_ci	{0, 0x0037, 0x0127},
5238c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
5248c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
5258c2ecf20Sopenharmony_ci	{0, 0x0001, 0x0127},
5268c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
5278c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
5288c2ecf20Sopenharmony_ci	{0, 0x0040, 0x0127},
5298c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
5308c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
5318c2ecf20Sopenharmony_ci	{0, 0xfffa, 0x0124},
5328c2ecf20Sopenharmony_ci	{0, 0xfff9, 0x0124},
5338c2ecf20Sopenharmony_ci	{0, 0x0086, 0x0127},
5348c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
5358c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
5368c2ecf20Sopenharmony_ci	{0, 0x0038, 0x0127},
5378c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
5388c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
5398c2ecf20Sopenharmony_ci	{0, 0x0000, 0x0127},
5408c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
5418c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
5428c2ecf20Sopenharmony_ci	{0, 0x0040, 0x0127},
5438c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
5448c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
5458c2ecf20Sopenharmony_ci	{0, 0xfffa, 0x0124},
5468c2ecf20Sopenharmony_ci	{0, 0xfff9, 0x0124},
5478c2ecf20Sopenharmony_ci	{0, 0x0086, 0x0127},
5488c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
5498c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
5508c2ecf20Sopenharmony_ci	{0, 0x0037, 0x0127},
5518c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
5528c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
5538c2ecf20Sopenharmony_ci	{0, 0x0000, 0x0127},
5548c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
5558c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
5568c2ecf20Sopenharmony_ci	{0, 0x00dc, 0x0127},
5578c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
5588c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
5598c2ecf20Sopenharmony_ci	{0, 0xfffa, 0x0124},
5608c2ecf20Sopenharmony_ci	{0, 0xfff9, 0x0124},
5618c2ecf20Sopenharmony_ci	{0, 0x0086, 0x0127},
5628c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
5638c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
5648c2ecf20Sopenharmony_ci	{0, 0x0038, 0x0127},
5658c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
5668c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
5678c2ecf20Sopenharmony_ci	{0, 0x0000, 0x0127},
5688c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
5698c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
5708c2ecf20Sopenharmony_ci	{0, 0x0000, 0x0127},
5718c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
5728c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
5738c2ecf20Sopenharmony_ci	{0, 0xfffa, 0x0124},
5748c2ecf20Sopenharmony_ci	{0, 0xfff9, 0x0124},
5758c2ecf20Sopenharmony_ci	{0, 0x0086, 0x0127},
5768c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
5778c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
5788c2ecf20Sopenharmony_ci	{0, 0x0037, 0x0127},
5798c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
5808c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
5818c2ecf20Sopenharmony_ci	{0, 0x0001, 0x0127},
5828c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
5838c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
5848c2ecf20Sopenharmony_ci	{0, 0x0032, 0x0127},
5858c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
5868c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
5878c2ecf20Sopenharmony_ci	{0, 0xfffa, 0x0124},
5888c2ecf20Sopenharmony_ci	{0, 0xfff9, 0x0124},
5898c2ecf20Sopenharmony_ci	{0, 0x0086, 0x0127},
5908c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
5918c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
5928c2ecf20Sopenharmony_ci	{0, 0x0038, 0x0127},
5938c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
5948c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
5958c2ecf20Sopenharmony_ci	{0, 0x0001, 0x0127},
5968c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
5978c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
5988c2ecf20Sopenharmony_ci	{0, 0x0020, 0x0127},
5998c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
6008c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
6018c2ecf20Sopenharmony_ci	{0, 0xfffa, 0x0124},
6028c2ecf20Sopenharmony_ci	{0, 0xfff9, 0x0124},
6038c2ecf20Sopenharmony_ci	{0, 0x0086, 0x0127},
6048c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
6058c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
6068c2ecf20Sopenharmony_ci	{0, 0x0037, 0x0127},
6078c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
6088c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
6098c2ecf20Sopenharmony_ci	{0, 0x0001, 0x0127},
6108c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
6118c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
6128c2ecf20Sopenharmony_ci	{0, 0x0040, 0x0127},
6138c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
6148c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
6158c2ecf20Sopenharmony_ci	{0, 0xfffa, 0x0124},
6168c2ecf20Sopenharmony_ci	{0, 0xfff9, 0x0124},
6178c2ecf20Sopenharmony_ci	{0, 0x0086, 0x0127},
6188c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
6198c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
6208c2ecf20Sopenharmony_ci	{0, 0x0038, 0x0127},
6218c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
6228c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
6238c2ecf20Sopenharmony_ci	{0, 0x0000, 0x0127},
6248c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
6258c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
6268c2ecf20Sopenharmony_ci	{0, 0x0040, 0x0127},
6278c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
6288c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
6298c2ecf20Sopenharmony_ci	{0, 0xfffa, 0x0124},
6308c2ecf20Sopenharmony_ci	{0, 0xfff9, 0x0124},
6318c2ecf20Sopenharmony_ci	{0, 0x0086, 0x0127},
6328c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
6338c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
6348c2ecf20Sopenharmony_ci	{0, 0x0037, 0x0127},
6358c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
6368c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
6378c2ecf20Sopenharmony_ci	{0, 0x0000, 0x0127},
6388c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
6398c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
6408c2ecf20Sopenharmony_ci	{0, 0x0030, 0x0127},
6418c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
6428c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
6438c2ecf20Sopenharmony_ci	{0, 0xfffa, 0x0124},
6448c2ecf20Sopenharmony_ci	{0, 0xfff9, 0x0124},
6458c2ecf20Sopenharmony_ci	{0, 0x0086, 0x0127},
6468c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
6478c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
6488c2ecf20Sopenharmony_ci	{0, 0x0038, 0x0127},
6498c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
6508c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
6518c2ecf20Sopenharmony_ci	{0, 0x0008, 0x0127},
6528c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
6538c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
6548c2ecf20Sopenharmony_ci	{0, 0x0000, 0x0127},
6558c2ecf20Sopenharmony_ci	{0, 0xfff8, 0x0124},
6568c2ecf20Sopenharmony_ci	{0, 0xfffd, 0x0124},
6578c2ecf20Sopenharmony_ci	{0, 0xfffa, 0x0124},
6588c2ecf20Sopenharmony_ci	{0, 0x0003, 0x0111},
6598c2ecf20Sopenharmony_ci};
6608c2ecf20Sopenharmony_ci
6618c2ecf20Sopenharmony_ci/* TESTME the old ibmcam driver repeats certain commands to Model1 cameras, we
6628c2ecf20Sopenharmony_ci   do the same for now (testing needed to see if this is really necessary) */
6638c2ecf20Sopenharmony_cistatic const int cit_model1_ntries = 5;
6648c2ecf20Sopenharmony_cistatic const int cit_model1_ntries2 = 2;
6658c2ecf20Sopenharmony_ci
6668c2ecf20Sopenharmony_cistatic int cit_write_reg(struct gspca_dev *gspca_dev, u16 value, u16 index)
6678c2ecf20Sopenharmony_ci{
6688c2ecf20Sopenharmony_ci	struct usb_device *udev = gspca_dev->dev;
6698c2ecf20Sopenharmony_ci	int err;
6708c2ecf20Sopenharmony_ci
6718c2ecf20Sopenharmony_ci	err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00,
6728c2ecf20Sopenharmony_ci			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT,
6738c2ecf20Sopenharmony_ci			value, index, NULL, 0, 1000);
6748c2ecf20Sopenharmony_ci	if (err < 0)
6758c2ecf20Sopenharmony_ci		pr_err("Failed to write a register (index 0x%04X, value 0x%02X, error %d)\n",
6768c2ecf20Sopenharmony_ci		       index, value, err);
6778c2ecf20Sopenharmony_ci
6788c2ecf20Sopenharmony_ci	return 0;
6798c2ecf20Sopenharmony_ci}
6808c2ecf20Sopenharmony_ci
6818c2ecf20Sopenharmony_cistatic int cit_read_reg(struct gspca_dev *gspca_dev, u16 index, int verbose)
6828c2ecf20Sopenharmony_ci{
6838c2ecf20Sopenharmony_ci	struct usb_device *udev = gspca_dev->dev;
6848c2ecf20Sopenharmony_ci	__u8 *buf = gspca_dev->usb_buf;
6858c2ecf20Sopenharmony_ci	int res;
6868c2ecf20Sopenharmony_ci
6878c2ecf20Sopenharmony_ci	res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x01,
6888c2ecf20Sopenharmony_ci			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT,
6898c2ecf20Sopenharmony_ci			0x00, index, buf, 8, 1000);
6908c2ecf20Sopenharmony_ci	if (res < 0) {
6918c2ecf20Sopenharmony_ci		pr_err("Failed to read a register (index 0x%04X, error %d)\n",
6928c2ecf20Sopenharmony_ci		       index, res);
6938c2ecf20Sopenharmony_ci		return res;
6948c2ecf20Sopenharmony_ci	}
6958c2ecf20Sopenharmony_ci
6968c2ecf20Sopenharmony_ci	if (verbose)
6978c2ecf20Sopenharmony_ci		gspca_dbg(gspca_dev, D_PROBE, "Register %04x value: %02x\n",
6988c2ecf20Sopenharmony_ci			  index, buf[0]);
6998c2ecf20Sopenharmony_ci
7008c2ecf20Sopenharmony_ci	return 0;
7018c2ecf20Sopenharmony_ci}
7028c2ecf20Sopenharmony_ci
7038c2ecf20Sopenharmony_ci/*
7048c2ecf20Sopenharmony_ci * cit_send_FF_04_02()
7058c2ecf20Sopenharmony_ci *
7068c2ecf20Sopenharmony_ci * This procedure sends magic 3-command prefix to the camera.
7078c2ecf20Sopenharmony_ci * The purpose of this prefix is not known.
7088c2ecf20Sopenharmony_ci *
7098c2ecf20Sopenharmony_ci * History:
7108c2ecf20Sopenharmony_ci * 1/2/00   Created.
7118c2ecf20Sopenharmony_ci */
7128c2ecf20Sopenharmony_cistatic void cit_send_FF_04_02(struct gspca_dev *gspca_dev)
7138c2ecf20Sopenharmony_ci{
7148c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x00FF, 0x0127);
7158c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0004, 0x0124);
7168c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0002, 0x0124);
7178c2ecf20Sopenharmony_ci}
7188c2ecf20Sopenharmony_ci
7198c2ecf20Sopenharmony_cistatic void cit_send_00_04_06(struct gspca_dev *gspca_dev)
7208c2ecf20Sopenharmony_ci{
7218c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0127);
7228c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0004, 0x0124);
7238c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0006, 0x0124);
7248c2ecf20Sopenharmony_ci}
7258c2ecf20Sopenharmony_ci
7268c2ecf20Sopenharmony_cistatic void cit_send_x_00(struct gspca_dev *gspca_dev, unsigned short x)
7278c2ecf20Sopenharmony_ci{
7288c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, x,      0x0127);
7298c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0124);
7308c2ecf20Sopenharmony_ci}
7318c2ecf20Sopenharmony_ci
7328c2ecf20Sopenharmony_cistatic void cit_send_x_00_05(struct gspca_dev *gspca_dev, unsigned short x)
7338c2ecf20Sopenharmony_ci{
7348c2ecf20Sopenharmony_ci	cit_send_x_00(gspca_dev, x);
7358c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0005, 0x0124);
7368c2ecf20Sopenharmony_ci}
7378c2ecf20Sopenharmony_ci
7388c2ecf20Sopenharmony_cistatic void cit_send_x_00_05_02(struct gspca_dev *gspca_dev, unsigned short x)
7398c2ecf20Sopenharmony_ci{
7408c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, x,      0x0127);
7418c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0124);
7428c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0005, 0x0124);
7438c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0002, 0x0124);
7448c2ecf20Sopenharmony_ci}
7458c2ecf20Sopenharmony_ci
7468c2ecf20Sopenharmony_cistatic void cit_send_x_01_00_05(struct gspca_dev *gspca_dev, u16 x)
7478c2ecf20Sopenharmony_ci{
7488c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, x,      0x0127);
7498c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0001, 0x0124);
7508c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0124);
7518c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0005, 0x0124);
7528c2ecf20Sopenharmony_ci}
7538c2ecf20Sopenharmony_ci
7548c2ecf20Sopenharmony_cistatic void cit_send_x_00_05_02_01(struct gspca_dev *gspca_dev, u16 x)
7558c2ecf20Sopenharmony_ci{
7568c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, x,      0x0127);
7578c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0124);
7588c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0005, 0x0124);
7598c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0002, 0x0124);
7608c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0001, 0x0124);
7618c2ecf20Sopenharmony_ci}
7628c2ecf20Sopenharmony_ci
7638c2ecf20Sopenharmony_cistatic void cit_send_x_00_05_02_08_01(struct gspca_dev *gspca_dev, u16 x)
7648c2ecf20Sopenharmony_ci{
7658c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, x,      0x0127);
7668c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0124);
7678c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0005, 0x0124);
7688c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0002, 0x0124);
7698c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0008, 0x0124);
7708c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0001, 0x0124);
7718c2ecf20Sopenharmony_ci}
7728c2ecf20Sopenharmony_ci
7738c2ecf20Sopenharmony_cistatic void cit_Packet_Format1(struct gspca_dev *gspca_dev, u16 fkey, u16 val)
7748c2ecf20Sopenharmony_ci{
7758c2ecf20Sopenharmony_ci	cit_send_x_01_00_05(gspca_dev, 0x0088);
7768c2ecf20Sopenharmony_ci	cit_send_x_00_05(gspca_dev, fkey);
7778c2ecf20Sopenharmony_ci	cit_send_x_00_05_02_08_01(gspca_dev, val);
7788c2ecf20Sopenharmony_ci	cit_send_x_00_05(gspca_dev, 0x0088);
7798c2ecf20Sopenharmony_ci	cit_send_x_00_05_02_01(gspca_dev, fkey);
7808c2ecf20Sopenharmony_ci	cit_send_x_00_05(gspca_dev, 0x0089);
7818c2ecf20Sopenharmony_ci	cit_send_x_00(gspca_dev, fkey);
7828c2ecf20Sopenharmony_ci	cit_send_00_04_06(gspca_dev);
7838c2ecf20Sopenharmony_ci	cit_read_reg(gspca_dev, 0x0126, 0);
7848c2ecf20Sopenharmony_ci	cit_send_FF_04_02(gspca_dev);
7858c2ecf20Sopenharmony_ci}
7868c2ecf20Sopenharmony_ci
7878c2ecf20Sopenharmony_cistatic void cit_PacketFormat2(struct gspca_dev *gspca_dev, u16 fkey, u16 val)
7888c2ecf20Sopenharmony_ci{
7898c2ecf20Sopenharmony_ci	cit_send_x_01_00_05(gspca_dev, 0x0088);
7908c2ecf20Sopenharmony_ci	cit_send_x_00_05(gspca_dev, fkey);
7918c2ecf20Sopenharmony_ci	cit_send_x_00_05_02(gspca_dev, val);
7928c2ecf20Sopenharmony_ci}
7938c2ecf20Sopenharmony_ci
7948c2ecf20Sopenharmony_cistatic void cit_model2_Packet2(struct gspca_dev *gspca_dev)
7958c2ecf20Sopenharmony_ci{
7968c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x00ff, 0x012d);
7978c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0xfea3, 0x0124);
7988c2ecf20Sopenharmony_ci}
7998c2ecf20Sopenharmony_ci
8008c2ecf20Sopenharmony_cistatic void cit_model2_Packet1(struct gspca_dev *gspca_dev, u16 v1, u16 v2)
8018c2ecf20Sopenharmony_ci{
8028c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x00aa, 0x012d);
8038c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x00ff, 0x012e);
8048c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, v1,     0x012f);
8058c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x00ff, 0x0130);
8068c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0xc719, 0x0124);
8078c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, v2,     0x0127);
8088c2ecf20Sopenharmony_ci
8098c2ecf20Sopenharmony_ci	cit_model2_Packet2(gspca_dev);
8108c2ecf20Sopenharmony_ci}
8118c2ecf20Sopenharmony_ci
8128c2ecf20Sopenharmony_ci/*
8138c2ecf20Sopenharmony_ci * cit_model3_Packet1()
8148c2ecf20Sopenharmony_ci *
8158c2ecf20Sopenharmony_ci * 00_0078_012d
8168c2ecf20Sopenharmony_ci * 00_0097_012f
8178c2ecf20Sopenharmony_ci * 00_d141_0124
8188c2ecf20Sopenharmony_ci * 00_0096_0127
8198c2ecf20Sopenharmony_ci * 00_fea8_0124
8208c2ecf20Sopenharmony_ci*/
8218c2ecf20Sopenharmony_cistatic void cit_model3_Packet1(struct gspca_dev *gspca_dev, u16 v1, u16 v2)
8228c2ecf20Sopenharmony_ci{
8238c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0078, 0x012d);
8248c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, v1,     0x012f);
8258c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0xd141, 0x0124);
8268c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, v2,     0x0127);
8278c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0xfea8, 0x0124);
8288c2ecf20Sopenharmony_ci}
8298c2ecf20Sopenharmony_ci
8308c2ecf20Sopenharmony_cistatic void cit_model4_Packet1(struct gspca_dev *gspca_dev, u16 v1, u16 v2)
8318c2ecf20Sopenharmony_ci{
8328c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x00aa, 0x012d);
8338c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, v1,     0x012f);
8348c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0xd141, 0x0124);
8358c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, v2,     0x0127);
8368c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0xfea8, 0x0124);
8378c2ecf20Sopenharmony_ci}
8388c2ecf20Sopenharmony_ci
8398c2ecf20Sopenharmony_cistatic void cit_model4_BrightnessPacket(struct gspca_dev *gspca_dev, u16 val)
8408c2ecf20Sopenharmony_ci{
8418c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x00aa, 0x012d);
8428c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0026, 0x012f);
8438c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0xd141, 0x0124);
8448c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, val,    0x0127);
8458c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x00aa, 0x0130);
8468c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x82a8, 0x0124);
8478c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0038, 0x012d);
8488c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0004, 0x012f);
8498c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0xd145, 0x0124);
8508c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0xfffa, 0x0124);
8518c2ecf20Sopenharmony_ci}
8528c2ecf20Sopenharmony_ci
8538c2ecf20Sopenharmony_ci/* this function is called at probe time */
8548c2ecf20Sopenharmony_cistatic int sd_config(struct gspca_dev *gspca_dev,
8558c2ecf20Sopenharmony_ci		     const struct usb_device_id *id)
8568c2ecf20Sopenharmony_ci{
8578c2ecf20Sopenharmony_ci	struct sd *sd = (struct sd *) gspca_dev;
8588c2ecf20Sopenharmony_ci	struct cam *cam;
8598c2ecf20Sopenharmony_ci
8608c2ecf20Sopenharmony_ci	sd->model = id->driver_info;
8618c2ecf20Sopenharmony_ci	if (sd->model == CIT_MODEL3 && ibm_netcam_pro)
8628c2ecf20Sopenharmony_ci		sd->model = CIT_IBM_NETCAM_PRO;
8638c2ecf20Sopenharmony_ci
8648c2ecf20Sopenharmony_ci	cam = &gspca_dev->cam;
8658c2ecf20Sopenharmony_ci	switch (sd->model) {
8668c2ecf20Sopenharmony_ci	case CIT_MODEL0:
8678c2ecf20Sopenharmony_ci		cam->cam_mode = model0_mode;
8688c2ecf20Sopenharmony_ci		cam->nmodes = ARRAY_SIZE(model0_mode);
8698c2ecf20Sopenharmony_ci		sd->sof_len = 4;
8708c2ecf20Sopenharmony_ci		break;
8718c2ecf20Sopenharmony_ci	case CIT_MODEL1:
8728c2ecf20Sopenharmony_ci		cam->cam_mode = cif_yuv_mode;
8738c2ecf20Sopenharmony_ci		cam->nmodes = ARRAY_SIZE(cif_yuv_mode);
8748c2ecf20Sopenharmony_ci		sd->sof_len = 4;
8758c2ecf20Sopenharmony_ci		break;
8768c2ecf20Sopenharmony_ci	case CIT_MODEL2:
8778c2ecf20Sopenharmony_ci		cam->cam_mode = model2_mode + 1; /* no 160x120 */
8788c2ecf20Sopenharmony_ci		cam->nmodes = 3;
8798c2ecf20Sopenharmony_ci		break;
8808c2ecf20Sopenharmony_ci	case CIT_MODEL3:
8818c2ecf20Sopenharmony_ci		cam->cam_mode = vga_yuv_mode;
8828c2ecf20Sopenharmony_ci		cam->nmodes = ARRAY_SIZE(vga_yuv_mode);
8838c2ecf20Sopenharmony_ci		sd->stop_on_control_change = 1;
8848c2ecf20Sopenharmony_ci		sd->sof_len = 4;
8858c2ecf20Sopenharmony_ci		break;
8868c2ecf20Sopenharmony_ci	case CIT_MODEL4:
8878c2ecf20Sopenharmony_ci		cam->cam_mode = model2_mode;
8888c2ecf20Sopenharmony_ci		cam->nmodes = ARRAY_SIZE(model2_mode);
8898c2ecf20Sopenharmony_ci		break;
8908c2ecf20Sopenharmony_ci	case CIT_IBM_NETCAM_PRO:
8918c2ecf20Sopenharmony_ci		cam->cam_mode = vga_yuv_mode;
8928c2ecf20Sopenharmony_ci		cam->nmodes = 2; /* no 640 x 480 */
8938c2ecf20Sopenharmony_ci		cam->input_flags = V4L2_IN_ST_VFLIP;
8948c2ecf20Sopenharmony_ci		sd->stop_on_control_change = 1;
8958c2ecf20Sopenharmony_ci		sd->sof_len = 4;
8968c2ecf20Sopenharmony_ci		break;
8978c2ecf20Sopenharmony_ci	}
8988c2ecf20Sopenharmony_ci
8998c2ecf20Sopenharmony_ci	return 0;
9008c2ecf20Sopenharmony_ci}
9018c2ecf20Sopenharmony_ci
9028c2ecf20Sopenharmony_cistatic int cit_init_model0(struct gspca_dev *gspca_dev)
9038c2ecf20Sopenharmony_ci{
9048c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0100); /* turn on led */
9058c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0001, 0x0112); /* turn on autogain ? */
9068c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0400);
9078c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0001, 0x0400);
9088c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0420);
9098c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0001, 0x0420);
9108c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x000d, 0x0409);
9118c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0002, 0x040a);
9128c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0018, 0x0405);
9138c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0008, 0x0435);
9148c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0026, 0x040b);
9158c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0007, 0x0437);
9168c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0015, 0x042f);
9178c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x002b, 0x0439);
9188c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0026, 0x043a);
9198c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0008, 0x0438);
9208c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x001e, 0x042b);
9218c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0041, 0x042c);
9228c2ecf20Sopenharmony_ci
9238c2ecf20Sopenharmony_ci	return 0;
9248c2ecf20Sopenharmony_ci}
9258c2ecf20Sopenharmony_ci
9268c2ecf20Sopenharmony_cistatic int cit_init_ibm_netcam_pro(struct gspca_dev *gspca_dev)
9278c2ecf20Sopenharmony_ci{
9288c2ecf20Sopenharmony_ci	cit_read_reg(gspca_dev, 0x128, 1);
9298c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0003, 0x0133);
9308c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0117);
9318c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0008, 0x0123);
9328c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0100);
9338c2ecf20Sopenharmony_ci	cit_read_reg(gspca_dev, 0x0116, 0);
9348c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0060, 0x0116);
9358c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0002, 0x0112);
9368c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0133);
9378c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0123);
9388c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0001, 0x0117);
9398c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0040, 0x0108);
9408c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0019, 0x012c);
9418c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0060, 0x0116);
9428c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0002, 0x0115);
9438c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x000b, 0x0115);
9448c2ecf20Sopenharmony_ci
9458c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0078, 0x012d);
9468c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0001, 0x012f);
9478c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0xd141, 0x0124);
9488c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0079, 0x012d);
9498c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x00ff, 0x0130);
9508c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0xcd41, 0x0124);
9518c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0xfffa, 0x0124);
9528c2ecf20Sopenharmony_ci	cit_read_reg(gspca_dev, 0x0126, 1);
9538c2ecf20Sopenharmony_ci
9548c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0000, 0x0000);
9558c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0000, 0x0001);
9568c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x000b, 0x0000);
9578c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x000c, 0x0008);
9588c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x000d, 0x003a);
9598c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x000e, 0x0060);
9608c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x000f, 0x0060);
9618c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0010, 0x0008);
9628c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0011, 0x0004);
9638c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0012, 0x0028);
9648c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0013, 0x0002);
9658c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0014, 0x0000);
9668c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0015, 0x00fb);
9678c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0016, 0x0002);
9688c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0017, 0x0037);
9698c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0018, 0x0036);
9708c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x001e, 0x0000);
9718c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x001f, 0x0008);
9728c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0020, 0x00c1);
9738c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0021, 0x0034);
9748c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0022, 0x0034);
9758c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0025, 0x0002);
9768c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0028, 0x0022);
9778c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0029, 0x000a);
9788c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x002b, 0x0000);
9798c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x002c, 0x0000);
9808c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x002d, 0x00ff);
9818c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x002e, 0x00ff);
9828c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x002f, 0x00ff);
9838c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0030, 0x00ff);
9848c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0031, 0x00ff);
9858c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0032, 0x0007);
9868c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0033, 0x0005);
9878c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0037, 0x0040);
9888c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0039, 0x0000);
9898c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x003a, 0x0000);
9908c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x003b, 0x0001);
9918c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x003c, 0x0000);
9928c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0040, 0x000c);
9938c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0041, 0x00fb);
9948c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0042, 0x0002);
9958c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0043, 0x0000);
9968c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0045, 0x0000);
9978c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0046, 0x0000);
9988c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0047, 0x0000);
9998c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0048, 0x0000);
10008c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0049, 0x0000);
10018c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x004a, 0x00ff);
10028c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x004b, 0x00ff);
10038c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x004c, 0x00ff);
10048c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x004f, 0x0000);
10058c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0050, 0x0000);
10068c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0051, 0x0002);
10078c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0055, 0x0000);
10088c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0056, 0x0000);
10098c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0057, 0x0000);
10108c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0058, 0x0002);
10118c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0059, 0x0000);
10128c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x005c, 0x0016);
10138c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x005d, 0x0022);
10148c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x005e, 0x003c);
10158c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x005f, 0x0050);
10168c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0060, 0x0044);
10178c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0061, 0x0005);
10188c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x006a, 0x007e);
10198c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x006f, 0x0000);
10208c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0072, 0x001b);
10218c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0073, 0x0005);
10228c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0074, 0x000a);
10238c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0075, 0x001b);
10248c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0076, 0x002a);
10258c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0077, 0x003c);
10268c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0078, 0x0050);
10278c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x007b, 0x0000);
10288c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x007c, 0x0011);
10298c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x007d, 0x0024);
10308c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x007e, 0x0043);
10318c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x007f, 0x005a);
10328c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0084, 0x0020);
10338c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0085, 0x0033);
10348c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0086, 0x000a);
10358c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0087, 0x0030);
10368c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0088, 0x0070);
10378c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x008b, 0x0008);
10388c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x008f, 0x0000);
10398c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0090, 0x0006);
10408c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0091, 0x0028);
10418c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0092, 0x005a);
10428c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0093, 0x0082);
10438c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0096, 0x0014);
10448c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0097, 0x0020);
10458c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0098, 0x0000);
10468c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00b0, 0x0046);
10478c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00b1, 0x0000);
10488c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00b2, 0x0000);
10498c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00b3, 0x0004);
10508c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00b4, 0x0007);
10518c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00b6, 0x0002);
10528c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00b7, 0x0004);
10538c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00bb, 0x0000);
10548c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00bc, 0x0001);
10558c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00bd, 0x0000);
10568c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00bf, 0x0000);
10578c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00c0, 0x00c8);
10588c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00c1, 0x0014);
10598c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00c2, 0x0001);
10608c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00c3, 0x0000);
10618c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00c4, 0x0004);
10628c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00cb, 0x00bf);
10638c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00cc, 0x00bf);
10648c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00cd, 0x00bf);
10658c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00ce, 0x0000);
10668c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00cf, 0x0020);
10678c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00d0, 0x0040);
10688c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00d1, 0x00bf);
10698c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00d1, 0x00bf);
10708c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00d2, 0x00bf);
10718c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00d3, 0x00bf);
10728c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00ea, 0x0008);
10738c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00eb, 0x0000);
10748c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00ec, 0x00e8);
10758c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00ed, 0x0001);
10768c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00ef, 0x0022);
10778c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00f0, 0x0000);
10788c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00f2, 0x0028);
10798c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00f4, 0x0002);
10808c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00f5, 0x0000);
10818c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00fa, 0x0000);
10828c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00fb, 0x0001);
10838c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00fc, 0x0000);
10848c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00fd, 0x0000);
10858c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00fe, 0x0000);
10868c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00ff, 0x0000);
10878c2ecf20Sopenharmony_ci
10888c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00be, 0x0003);
10898c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00c8, 0x0000);
10908c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00c9, 0x0020);
10918c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00ca, 0x0040);
10928c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0053, 0x0001);
10938c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0082, 0x000e);
10948c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0083, 0x0020);
10958c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0034, 0x003c);
10968c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x006e, 0x0055);
10978c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0062, 0x0005);
10988c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0063, 0x0008);
10998c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0066, 0x000a);
11008c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0067, 0x0006);
11018c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x006b, 0x0010);
11028c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x005a, 0x0001);
11038c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x005b, 0x000a);
11048c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0023, 0x0006);
11058c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0026, 0x0004);
11068c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0036, 0x0069);
11078c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0038, 0x0064);
11088c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x003d, 0x0003);
11098c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x003e, 0x0001);
11108c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00b8, 0x0014);
11118c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00b9, 0x0014);
11128c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00e6, 0x0004);
11138c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00e8, 0x0001);
11148c2ecf20Sopenharmony_ci
11158c2ecf20Sopenharmony_ci	return 0;
11168c2ecf20Sopenharmony_ci}
11178c2ecf20Sopenharmony_ci
11188c2ecf20Sopenharmony_ci/* this function is called at probe and resume time */
11198c2ecf20Sopenharmony_cistatic int sd_init(struct gspca_dev *gspca_dev)
11208c2ecf20Sopenharmony_ci{
11218c2ecf20Sopenharmony_ci	struct sd *sd = (struct sd *) gspca_dev;
11228c2ecf20Sopenharmony_ci
11238c2ecf20Sopenharmony_ci	switch (sd->model) {
11248c2ecf20Sopenharmony_ci	case CIT_MODEL0:
11258c2ecf20Sopenharmony_ci		cit_init_model0(gspca_dev);
11268c2ecf20Sopenharmony_ci		sd_stop0(gspca_dev);
11278c2ecf20Sopenharmony_ci		break;
11288c2ecf20Sopenharmony_ci	case CIT_MODEL1:
11298c2ecf20Sopenharmony_ci	case CIT_MODEL2:
11308c2ecf20Sopenharmony_ci	case CIT_MODEL3:
11318c2ecf20Sopenharmony_ci	case CIT_MODEL4:
11328c2ecf20Sopenharmony_ci		break; /* All is done in sd_start */
11338c2ecf20Sopenharmony_ci	case CIT_IBM_NETCAM_PRO:
11348c2ecf20Sopenharmony_ci		cit_init_ibm_netcam_pro(gspca_dev);
11358c2ecf20Sopenharmony_ci		sd_stop0(gspca_dev);
11368c2ecf20Sopenharmony_ci		break;
11378c2ecf20Sopenharmony_ci	}
11388c2ecf20Sopenharmony_ci	return 0;
11398c2ecf20Sopenharmony_ci}
11408c2ecf20Sopenharmony_ci
11418c2ecf20Sopenharmony_cistatic int cit_set_brightness(struct gspca_dev *gspca_dev, s32 val)
11428c2ecf20Sopenharmony_ci{
11438c2ecf20Sopenharmony_ci	struct sd *sd = (struct sd *) gspca_dev;
11448c2ecf20Sopenharmony_ci	int i;
11458c2ecf20Sopenharmony_ci
11468c2ecf20Sopenharmony_ci	switch (sd->model) {
11478c2ecf20Sopenharmony_ci	case CIT_MODEL0:
11488c2ecf20Sopenharmony_ci	case CIT_IBM_NETCAM_PRO:
11498c2ecf20Sopenharmony_ci		/* No (known) brightness control for these */
11508c2ecf20Sopenharmony_ci		break;
11518c2ecf20Sopenharmony_ci	case CIT_MODEL1:
11528c2ecf20Sopenharmony_ci		/* Model 1: Brightness range 0 - 63 */
11538c2ecf20Sopenharmony_ci		cit_Packet_Format1(gspca_dev, 0x0031, val);
11548c2ecf20Sopenharmony_ci		cit_Packet_Format1(gspca_dev, 0x0032, val);
11558c2ecf20Sopenharmony_ci		cit_Packet_Format1(gspca_dev, 0x0033, val);
11568c2ecf20Sopenharmony_ci		break;
11578c2ecf20Sopenharmony_ci	case CIT_MODEL2:
11588c2ecf20Sopenharmony_ci		/* Model 2: Brightness range 0x60 - 0xee */
11598c2ecf20Sopenharmony_ci		/* Scale 0 - 63 to 0x60 - 0xee */
11608c2ecf20Sopenharmony_ci		i = 0x60 + val * 2254 / 1000;
11618c2ecf20Sopenharmony_ci		cit_model2_Packet1(gspca_dev, 0x001a, i);
11628c2ecf20Sopenharmony_ci		break;
11638c2ecf20Sopenharmony_ci	case CIT_MODEL3:
11648c2ecf20Sopenharmony_ci		/* Model 3: Brightness range 'i' in [0x0C..0x3F] */
11658c2ecf20Sopenharmony_ci		i = val;
11668c2ecf20Sopenharmony_ci		if (i < 0x0c)
11678c2ecf20Sopenharmony_ci			i = 0x0c;
11688c2ecf20Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x0036, i);
11698c2ecf20Sopenharmony_ci		break;
11708c2ecf20Sopenharmony_ci	case CIT_MODEL4:
11718c2ecf20Sopenharmony_ci		/* Model 4: Brightness range 'i' in [0x04..0xb4] */
11728c2ecf20Sopenharmony_ci		/* Scale 0 - 63 to 0x04 - 0xb4 */
11738c2ecf20Sopenharmony_ci		i = 0x04 + val * 2794 / 1000;
11748c2ecf20Sopenharmony_ci		cit_model4_BrightnessPacket(gspca_dev, i);
11758c2ecf20Sopenharmony_ci		break;
11768c2ecf20Sopenharmony_ci	}
11778c2ecf20Sopenharmony_ci
11788c2ecf20Sopenharmony_ci	return 0;
11798c2ecf20Sopenharmony_ci}
11808c2ecf20Sopenharmony_ci
11818c2ecf20Sopenharmony_cistatic int cit_set_contrast(struct gspca_dev *gspca_dev, s32 val)
11828c2ecf20Sopenharmony_ci{
11838c2ecf20Sopenharmony_ci	struct sd *sd = (struct sd *) gspca_dev;
11848c2ecf20Sopenharmony_ci
11858c2ecf20Sopenharmony_ci	switch (sd->model) {
11868c2ecf20Sopenharmony_ci	case CIT_MODEL0: {
11878c2ecf20Sopenharmony_ci		int i;
11888c2ecf20Sopenharmony_ci		/* gain 0-15, 0-20 -> 0-15 */
11898c2ecf20Sopenharmony_ci		i = val * 1000 / 1333;
11908c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, i, 0x0422);
11918c2ecf20Sopenharmony_ci		/* gain 0-31, may not be lower then 0x0422, 0-20 -> 0-31 */
11928c2ecf20Sopenharmony_ci		i = val * 2000 / 1333;
11938c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, i, 0x0423);
11948c2ecf20Sopenharmony_ci		/* gain 0-127, may not be lower then 0x0423, 0-20 -> 0-63  */
11958c2ecf20Sopenharmony_ci		i = val * 4000 / 1333;
11968c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, i, 0x0424);
11978c2ecf20Sopenharmony_ci		/* gain 0-127, may not be lower then 0x0424, , 0-20 -> 0-127 */
11988c2ecf20Sopenharmony_ci		i = val * 8000 / 1333;
11998c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, i, 0x0425);
12008c2ecf20Sopenharmony_ci		break;
12018c2ecf20Sopenharmony_ci	}
12028c2ecf20Sopenharmony_ci	case CIT_MODEL2:
12038c2ecf20Sopenharmony_ci	case CIT_MODEL4:
12048c2ecf20Sopenharmony_ci		/* These models do not have this control. */
12058c2ecf20Sopenharmony_ci		break;
12068c2ecf20Sopenharmony_ci	case CIT_MODEL1:
12078c2ecf20Sopenharmony_ci	{
12088c2ecf20Sopenharmony_ci		/* Scale 0 - 20 to 15 - 0 */
12098c2ecf20Sopenharmony_ci		int i, new_contrast = (20 - val) * 1000 / 1333;
12108c2ecf20Sopenharmony_ci		for (i = 0; i < cit_model1_ntries; i++) {
12118c2ecf20Sopenharmony_ci			cit_Packet_Format1(gspca_dev, 0x0014, new_contrast);
12128c2ecf20Sopenharmony_ci			cit_send_FF_04_02(gspca_dev);
12138c2ecf20Sopenharmony_ci		}
12148c2ecf20Sopenharmony_ci		break;
12158c2ecf20Sopenharmony_ci	}
12168c2ecf20Sopenharmony_ci	case CIT_MODEL3:
12178c2ecf20Sopenharmony_ci	{	/* Preset hardware values */
12188c2ecf20Sopenharmony_ci		static const struct {
12198c2ecf20Sopenharmony_ci			unsigned short cv1;
12208c2ecf20Sopenharmony_ci			unsigned short cv2;
12218c2ecf20Sopenharmony_ci			unsigned short cv3;
12228c2ecf20Sopenharmony_ci		} cv[7] = {
12238c2ecf20Sopenharmony_ci			{ 0x05, 0x05, 0x0f },	/* Minimum */
12248c2ecf20Sopenharmony_ci			{ 0x04, 0x04, 0x16 },
12258c2ecf20Sopenharmony_ci			{ 0x02, 0x03, 0x16 },
12268c2ecf20Sopenharmony_ci			{ 0x02, 0x08, 0x16 },
12278c2ecf20Sopenharmony_ci			{ 0x01, 0x0c, 0x16 },
12288c2ecf20Sopenharmony_ci			{ 0x01, 0x0e, 0x16 },
12298c2ecf20Sopenharmony_ci			{ 0x01, 0x10, 0x16 }	/* Maximum */
12308c2ecf20Sopenharmony_ci		};
12318c2ecf20Sopenharmony_ci		int i = val / 3;
12328c2ecf20Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x0067, cv[i].cv1);
12338c2ecf20Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x005b, cv[i].cv2);
12348c2ecf20Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x005c, cv[i].cv3);
12358c2ecf20Sopenharmony_ci		break;
12368c2ecf20Sopenharmony_ci	}
12378c2ecf20Sopenharmony_ci	case CIT_IBM_NETCAM_PRO:
12388c2ecf20Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x005b, val + 1);
12398c2ecf20Sopenharmony_ci		break;
12408c2ecf20Sopenharmony_ci	}
12418c2ecf20Sopenharmony_ci	return 0;
12428c2ecf20Sopenharmony_ci}
12438c2ecf20Sopenharmony_ci
12448c2ecf20Sopenharmony_cistatic int cit_set_hue(struct gspca_dev *gspca_dev, s32 val)
12458c2ecf20Sopenharmony_ci{
12468c2ecf20Sopenharmony_ci	struct sd *sd = (struct sd *) gspca_dev;
12478c2ecf20Sopenharmony_ci
12488c2ecf20Sopenharmony_ci	switch (sd->model) {
12498c2ecf20Sopenharmony_ci	case CIT_MODEL0:
12508c2ecf20Sopenharmony_ci	case CIT_MODEL1:
12518c2ecf20Sopenharmony_ci	case CIT_IBM_NETCAM_PRO:
12528c2ecf20Sopenharmony_ci		/* No hue control for these models */
12538c2ecf20Sopenharmony_ci		break;
12548c2ecf20Sopenharmony_ci	case CIT_MODEL2:
12558c2ecf20Sopenharmony_ci		cit_model2_Packet1(gspca_dev, 0x0024, val);
12568c2ecf20Sopenharmony_ci		/* cit_model2_Packet1(gspca_dev, 0x0020, sat); */
12578c2ecf20Sopenharmony_ci		break;
12588c2ecf20Sopenharmony_ci	case CIT_MODEL3: {
12598c2ecf20Sopenharmony_ci		/* Model 3: Brightness range 'i' in [0x05..0x37] */
12608c2ecf20Sopenharmony_ci		/* TESTME according to the ibmcam driver this does not work */
12618c2ecf20Sopenharmony_ci		if (0) {
12628c2ecf20Sopenharmony_ci			/* Scale 0 - 127 to 0x05 - 0x37 */
12638c2ecf20Sopenharmony_ci			int i = 0x05 + val * 1000 / 2540;
12648c2ecf20Sopenharmony_ci			cit_model3_Packet1(gspca_dev, 0x007e, i);
12658c2ecf20Sopenharmony_ci		}
12668c2ecf20Sopenharmony_ci		break;
12678c2ecf20Sopenharmony_ci	}
12688c2ecf20Sopenharmony_ci	case CIT_MODEL4:
12698c2ecf20Sopenharmony_ci		/* HDG: taken from ibmcam, setting the color gains does not
12708c2ecf20Sopenharmony_ci		 * really belong here.
12718c2ecf20Sopenharmony_ci		 *
12728c2ecf20Sopenharmony_ci		 * I am not sure r/g/b_gain variables exactly control gain
12738c2ecf20Sopenharmony_ci		 * of those channels. Most likely they subtly change some
12748c2ecf20Sopenharmony_ci		 * very internal image processing settings in the camera.
12758c2ecf20Sopenharmony_ci		 * In any case, here is what they do, and feel free to tweak:
12768c2ecf20Sopenharmony_ci		 *
12778c2ecf20Sopenharmony_ci		 * r_gain: seriously affects red gain
12788c2ecf20Sopenharmony_ci		 * g_gain: seriously affects green gain
12798c2ecf20Sopenharmony_ci		 * b_gain: seriously affects blue gain
12808c2ecf20Sopenharmony_ci		 * hue: changes average color from violet (0) to red (0xFF)
12818c2ecf20Sopenharmony_ci		 */
12828c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
12838c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x001e, 0x012f);
12848c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd141, 0x0124);
12858c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev,    160, 0x0127);  /* Green gain */
12868c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev,    160, 0x012e);  /* Red gain */
12878c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev,    160, 0x0130);  /* Blue gain */
12888c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x8a28, 0x0124);
12898c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, val, 0x012d); /* Hue */
12908c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xf545, 0x0124);
12918c2ecf20Sopenharmony_ci		break;
12928c2ecf20Sopenharmony_ci	}
12938c2ecf20Sopenharmony_ci	return 0;
12948c2ecf20Sopenharmony_ci}
12958c2ecf20Sopenharmony_ci
12968c2ecf20Sopenharmony_cistatic int cit_set_sharpness(struct gspca_dev *gspca_dev, s32 val)
12978c2ecf20Sopenharmony_ci{
12988c2ecf20Sopenharmony_ci	struct sd *sd = (struct sd *) gspca_dev;
12998c2ecf20Sopenharmony_ci
13008c2ecf20Sopenharmony_ci	switch (sd->model) {
13018c2ecf20Sopenharmony_ci	case CIT_MODEL0:
13028c2ecf20Sopenharmony_ci	case CIT_MODEL2:
13038c2ecf20Sopenharmony_ci	case CIT_MODEL4:
13048c2ecf20Sopenharmony_ci	case CIT_IBM_NETCAM_PRO:
13058c2ecf20Sopenharmony_ci		/* These models do not have this control */
13068c2ecf20Sopenharmony_ci		break;
13078c2ecf20Sopenharmony_ci	case CIT_MODEL1: {
13088c2ecf20Sopenharmony_ci		int i;
13098c2ecf20Sopenharmony_ci		static const unsigned short sa[] = {
13108c2ecf20Sopenharmony_ci			0x11, 0x13, 0x16, 0x18, 0x1a, 0x8, 0x0a };
13118c2ecf20Sopenharmony_ci
13128c2ecf20Sopenharmony_ci		for (i = 0; i < cit_model1_ntries; i++)
13138c2ecf20Sopenharmony_ci			cit_PacketFormat2(gspca_dev, 0x0013, sa[val]);
13148c2ecf20Sopenharmony_ci		break;
13158c2ecf20Sopenharmony_ci	}
13168c2ecf20Sopenharmony_ci	case CIT_MODEL3:
13178c2ecf20Sopenharmony_ci	{	/*
13188c2ecf20Sopenharmony_ci		 * "Use a table of magic numbers.
13198c2ecf20Sopenharmony_ci		 *  This setting doesn't really change much.
13208c2ecf20Sopenharmony_ci		 *  But that's how Windows does it."
13218c2ecf20Sopenharmony_ci		 */
13228c2ecf20Sopenharmony_ci		static const struct {
13238c2ecf20Sopenharmony_ci			unsigned short sv1;
13248c2ecf20Sopenharmony_ci			unsigned short sv2;
13258c2ecf20Sopenharmony_ci			unsigned short sv3;
13268c2ecf20Sopenharmony_ci			unsigned short sv4;
13278c2ecf20Sopenharmony_ci		} sv[7] = {
13288c2ecf20Sopenharmony_ci			{ 0x00, 0x00, 0x05, 0x14 },	/* Smoothest */
13298c2ecf20Sopenharmony_ci			{ 0x01, 0x04, 0x05, 0x14 },
13308c2ecf20Sopenharmony_ci			{ 0x02, 0x04, 0x05, 0x14 },
13318c2ecf20Sopenharmony_ci			{ 0x03, 0x04, 0x05, 0x14 },
13328c2ecf20Sopenharmony_ci			{ 0x03, 0x05, 0x05, 0x14 },
13338c2ecf20Sopenharmony_ci			{ 0x03, 0x06, 0x05, 0x14 },
13348c2ecf20Sopenharmony_ci			{ 0x03, 0x07, 0x05, 0x14 }	/* Sharpest */
13358c2ecf20Sopenharmony_ci		};
13368c2ecf20Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x0060, sv[val].sv1);
13378c2ecf20Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x0061, sv[val].sv2);
13388c2ecf20Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x0062, sv[val].sv3);
13398c2ecf20Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x0063, sv[val].sv4);
13408c2ecf20Sopenharmony_ci		break;
13418c2ecf20Sopenharmony_ci	}
13428c2ecf20Sopenharmony_ci	}
13438c2ecf20Sopenharmony_ci	return 0;
13448c2ecf20Sopenharmony_ci}
13458c2ecf20Sopenharmony_ci
13468c2ecf20Sopenharmony_ci/*
13478c2ecf20Sopenharmony_ci * cit_set_lighting()
13488c2ecf20Sopenharmony_ci *
13498c2ecf20Sopenharmony_ci * Camera model 1:
13508c2ecf20Sopenharmony_ci * We have 3 levels of lighting conditions: 0=Bright, 1=Medium, 2=Low.
13518c2ecf20Sopenharmony_ci *
13528c2ecf20Sopenharmony_ci * Camera model 2:
13538c2ecf20Sopenharmony_ci * We have 16 levels of lighting, 0 for bright light and up to 15 for
13548c2ecf20Sopenharmony_ci * low light. But values above 5 or so are useless because camera is
13558c2ecf20Sopenharmony_ci * not really capable to produce anything worth viewing at such light.
13568c2ecf20Sopenharmony_ci * This setting may be altered only in certain camera state.
13578c2ecf20Sopenharmony_ci *
13588c2ecf20Sopenharmony_ci * Low lighting forces slower FPS.
13598c2ecf20Sopenharmony_ci *
13608c2ecf20Sopenharmony_ci * History:
13618c2ecf20Sopenharmony_ci * 1/5/00   Created.
13628c2ecf20Sopenharmony_ci * 2/20/00  Added support for Model 2 cameras.
13638c2ecf20Sopenharmony_ci */
13648c2ecf20Sopenharmony_cistatic void cit_set_lighting(struct gspca_dev *gspca_dev, s32 val)
13658c2ecf20Sopenharmony_ci{
13668c2ecf20Sopenharmony_ci	struct sd *sd = (struct sd *) gspca_dev;
13678c2ecf20Sopenharmony_ci
13688c2ecf20Sopenharmony_ci	switch (sd->model) {
13698c2ecf20Sopenharmony_ci	case CIT_MODEL0:
13708c2ecf20Sopenharmony_ci	case CIT_MODEL2:
13718c2ecf20Sopenharmony_ci	case CIT_MODEL3:
13728c2ecf20Sopenharmony_ci	case CIT_MODEL4:
13738c2ecf20Sopenharmony_ci	case CIT_IBM_NETCAM_PRO:
13748c2ecf20Sopenharmony_ci		break;
13758c2ecf20Sopenharmony_ci	case CIT_MODEL1: {
13768c2ecf20Sopenharmony_ci		int i;
13778c2ecf20Sopenharmony_ci		for (i = 0; i < cit_model1_ntries; i++)
13788c2ecf20Sopenharmony_ci			cit_Packet_Format1(gspca_dev, 0x0027, val);
13798c2ecf20Sopenharmony_ci		break;
13808c2ecf20Sopenharmony_ci	}
13818c2ecf20Sopenharmony_ci	}
13828c2ecf20Sopenharmony_ci}
13838c2ecf20Sopenharmony_ci
13848c2ecf20Sopenharmony_cistatic void cit_set_hflip(struct gspca_dev *gspca_dev, s32 val)
13858c2ecf20Sopenharmony_ci{
13868c2ecf20Sopenharmony_ci	struct sd *sd = (struct sd *) gspca_dev;
13878c2ecf20Sopenharmony_ci
13888c2ecf20Sopenharmony_ci	switch (sd->model) {
13898c2ecf20Sopenharmony_ci	case CIT_MODEL0:
13908c2ecf20Sopenharmony_ci		if (val)
13918c2ecf20Sopenharmony_ci			cit_write_reg(gspca_dev, 0x0020, 0x0115);
13928c2ecf20Sopenharmony_ci		else
13938c2ecf20Sopenharmony_ci			cit_write_reg(gspca_dev, 0x0040, 0x0115);
13948c2ecf20Sopenharmony_ci		break;
13958c2ecf20Sopenharmony_ci	case CIT_MODEL1:
13968c2ecf20Sopenharmony_ci	case CIT_MODEL2:
13978c2ecf20Sopenharmony_ci	case CIT_MODEL3:
13988c2ecf20Sopenharmony_ci	case CIT_MODEL4:
13998c2ecf20Sopenharmony_ci	case CIT_IBM_NETCAM_PRO:
14008c2ecf20Sopenharmony_ci		break;
14018c2ecf20Sopenharmony_ci	}
14028c2ecf20Sopenharmony_ci}
14038c2ecf20Sopenharmony_ci
14048c2ecf20Sopenharmony_cistatic int cit_restart_stream(struct gspca_dev *gspca_dev)
14058c2ecf20Sopenharmony_ci{
14068c2ecf20Sopenharmony_ci	struct sd *sd = (struct sd *) gspca_dev;
14078c2ecf20Sopenharmony_ci
14088c2ecf20Sopenharmony_ci	switch (sd->model) {
14098c2ecf20Sopenharmony_ci	case CIT_MODEL0:
14108c2ecf20Sopenharmony_ci	case CIT_MODEL1:
14118c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0001, 0x0114);
14128c2ecf20Sopenharmony_ci		fallthrough;
14138c2ecf20Sopenharmony_ci	case CIT_MODEL2:
14148c2ecf20Sopenharmony_ci	case CIT_MODEL4:
14158c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00c0, 0x010c); /* Go! */
14168c2ecf20Sopenharmony_ci		usb_clear_halt(gspca_dev->dev, gspca_dev->urb[0]->pipe);
14178c2ecf20Sopenharmony_ci		break;
14188c2ecf20Sopenharmony_ci	case CIT_MODEL3:
14198c2ecf20Sopenharmony_ci	case CIT_IBM_NETCAM_PRO:
14208c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0001, 0x0114);
14218c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00c0, 0x010c); /* Go! */
14228c2ecf20Sopenharmony_ci		usb_clear_halt(gspca_dev->dev, gspca_dev->urb[0]->pipe);
14238c2ecf20Sopenharmony_ci		/* Clear button events from while we were not streaming */
14248c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0001, 0x0113);
14258c2ecf20Sopenharmony_ci		break;
14268c2ecf20Sopenharmony_ci	}
14278c2ecf20Sopenharmony_ci
14288c2ecf20Sopenharmony_ci	sd->sof_read = 0;
14298c2ecf20Sopenharmony_ci
14308c2ecf20Sopenharmony_ci	return 0;
14318c2ecf20Sopenharmony_ci}
14328c2ecf20Sopenharmony_ci
14338c2ecf20Sopenharmony_cistatic int cit_get_packet_size(struct gspca_dev *gspca_dev)
14348c2ecf20Sopenharmony_ci{
14358c2ecf20Sopenharmony_ci	struct usb_host_interface *alt;
14368c2ecf20Sopenharmony_ci	struct usb_interface *intf;
14378c2ecf20Sopenharmony_ci
14388c2ecf20Sopenharmony_ci	intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface);
14398c2ecf20Sopenharmony_ci	alt = usb_altnum_to_altsetting(intf, gspca_dev->alt);
14408c2ecf20Sopenharmony_ci	if (!alt) {
14418c2ecf20Sopenharmony_ci		pr_err("Couldn't get altsetting\n");
14428c2ecf20Sopenharmony_ci		return -EIO;
14438c2ecf20Sopenharmony_ci	}
14448c2ecf20Sopenharmony_ci
14458c2ecf20Sopenharmony_ci	if (alt->desc.bNumEndpoints < 1)
14468c2ecf20Sopenharmony_ci		return -ENODEV;
14478c2ecf20Sopenharmony_ci
14488c2ecf20Sopenharmony_ci	return le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
14498c2ecf20Sopenharmony_ci}
14508c2ecf20Sopenharmony_ci
14518c2ecf20Sopenharmony_ci/* Calculate the clockdiv giving us max fps given the available bandwidth */
14528c2ecf20Sopenharmony_cistatic int cit_get_clock_div(struct gspca_dev *gspca_dev)
14538c2ecf20Sopenharmony_ci{
14548c2ecf20Sopenharmony_ci	int clock_div = 7; /* 0=30 1=25 2=20 3=15 4=12 5=7.5 6=6 7=3fps ?? */
14558c2ecf20Sopenharmony_ci	int fps[8] = { 30, 25, 20, 15, 12, 8, 6, 3 };
14568c2ecf20Sopenharmony_ci	int packet_size;
14578c2ecf20Sopenharmony_ci
14588c2ecf20Sopenharmony_ci	packet_size = cit_get_packet_size(gspca_dev);
14598c2ecf20Sopenharmony_ci	if (packet_size < 0)
14608c2ecf20Sopenharmony_ci		return packet_size;
14618c2ecf20Sopenharmony_ci
14628c2ecf20Sopenharmony_ci	while (clock_div > 3 &&
14638c2ecf20Sopenharmony_ci			1000 * packet_size >
14648c2ecf20Sopenharmony_ci			gspca_dev->pixfmt.width * gspca_dev->pixfmt.height *
14658c2ecf20Sopenharmony_ci			fps[clock_div - 1] * 3 / 2)
14668c2ecf20Sopenharmony_ci		clock_div--;
14678c2ecf20Sopenharmony_ci
14688c2ecf20Sopenharmony_ci	gspca_dbg(gspca_dev, D_PROBE,
14698c2ecf20Sopenharmony_ci		  "PacketSize: %d, res: %dx%d -> using clockdiv: %d (%d fps)\n",
14708c2ecf20Sopenharmony_ci		  packet_size,
14718c2ecf20Sopenharmony_ci		  gspca_dev->pixfmt.width, gspca_dev->pixfmt.height,
14728c2ecf20Sopenharmony_ci		  clock_div, fps[clock_div]);
14738c2ecf20Sopenharmony_ci
14748c2ecf20Sopenharmony_ci	return clock_div;
14758c2ecf20Sopenharmony_ci}
14768c2ecf20Sopenharmony_ci
14778c2ecf20Sopenharmony_cistatic int cit_start_model0(struct gspca_dev *gspca_dev)
14788c2ecf20Sopenharmony_ci{
14798c2ecf20Sopenharmony_ci	const unsigned short compression = 0; /* 0=none, 7=best frame rate */
14808c2ecf20Sopenharmony_ci	int clock_div;
14818c2ecf20Sopenharmony_ci
14828c2ecf20Sopenharmony_ci	clock_div = cit_get_clock_div(gspca_dev);
14838c2ecf20Sopenharmony_ci	if (clock_div < 0)
14848c2ecf20Sopenharmony_ci		return clock_div;
14858c2ecf20Sopenharmony_ci
14868c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0100); /* turn on led */
14878c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0003, 0x0438);
14888c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x001e, 0x042b);
14898c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0041, 0x042c);
14908c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0008, 0x0436);
14918c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0024, 0x0403);
14928c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x002c, 0x0404);
14938c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0002, 0x0426);
14948c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0014, 0x0427);
14958c2ecf20Sopenharmony_ci
14968c2ecf20Sopenharmony_ci	switch (gspca_dev->pixfmt.width) {
14978c2ecf20Sopenharmony_ci	case 160: /* 160x120 */
14988c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0004, 0x010b);
14998c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0001, 0x010a);
15008c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0010, 0x0102);
15018c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00a0, 0x0103);
15028c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0104);
15038c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0078, 0x0105);
15048c2ecf20Sopenharmony_ci		break;
15058c2ecf20Sopenharmony_ci
15068c2ecf20Sopenharmony_ci	case 176: /* 176x144 */
15078c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0006, 0x010b);
15088c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x010a);
15098c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0005, 0x0102);
15108c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00b0, 0x0103);
15118c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0104);
15128c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0090, 0x0105);
15138c2ecf20Sopenharmony_ci		break;
15148c2ecf20Sopenharmony_ci
15158c2ecf20Sopenharmony_ci	case 320: /* 320x240 */
15168c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0008, 0x010b);
15178c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0004, 0x010a);
15188c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0005, 0x0102);
15198c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00a0, 0x0103);
15208c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0010, 0x0104);
15218c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0078, 0x0105);
15228c2ecf20Sopenharmony_ci		break;
15238c2ecf20Sopenharmony_ci	}
15248c2ecf20Sopenharmony_ci
15258c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, compression, 0x0109);
15268c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, clock_div, 0x0111);
15278c2ecf20Sopenharmony_ci
15288c2ecf20Sopenharmony_ci	return 0;
15298c2ecf20Sopenharmony_ci}
15308c2ecf20Sopenharmony_ci
15318c2ecf20Sopenharmony_cistatic int cit_start_model1(struct gspca_dev *gspca_dev)
15328c2ecf20Sopenharmony_ci{
15338c2ecf20Sopenharmony_ci	struct sd *sd = (struct sd *) gspca_dev;
15348c2ecf20Sopenharmony_ci	int i, clock_div;
15358c2ecf20Sopenharmony_ci
15368c2ecf20Sopenharmony_ci	clock_div = cit_get_clock_div(gspca_dev);
15378c2ecf20Sopenharmony_ci	if (clock_div < 0)
15388c2ecf20Sopenharmony_ci		return clock_div;
15398c2ecf20Sopenharmony_ci
15408c2ecf20Sopenharmony_ci	cit_read_reg(gspca_dev, 0x0128, 1);
15418c2ecf20Sopenharmony_ci	cit_read_reg(gspca_dev, 0x0100, 0);
15428c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x01, 0x0100);	/* LED On  */
15438c2ecf20Sopenharmony_ci	cit_read_reg(gspca_dev, 0x0100, 0);
15448c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x81, 0x0100);	/* LED Off */
15458c2ecf20Sopenharmony_ci	cit_read_reg(gspca_dev, 0x0100, 0);
15468c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x01, 0x0100);	/* LED On  */
15478c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x01, 0x0108);
15488c2ecf20Sopenharmony_ci
15498c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x03, 0x0112);
15508c2ecf20Sopenharmony_ci	cit_read_reg(gspca_dev, 0x0115, 0);
15518c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x06, 0x0115);
15528c2ecf20Sopenharmony_ci	cit_read_reg(gspca_dev, 0x0116, 0);
15538c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x44, 0x0116);
15548c2ecf20Sopenharmony_ci	cit_read_reg(gspca_dev, 0x0116, 0);
15558c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x40, 0x0116);
15568c2ecf20Sopenharmony_ci	cit_read_reg(gspca_dev, 0x0115, 0);
15578c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0e, 0x0115);
15588c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x19, 0x012c);
15598c2ecf20Sopenharmony_ci
15608c2ecf20Sopenharmony_ci	cit_Packet_Format1(gspca_dev, 0x00, 0x1e);
15618c2ecf20Sopenharmony_ci	cit_Packet_Format1(gspca_dev, 0x39, 0x0d);
15628c2ecf20Sopenharmony_ci	cit_Packet_Format1(gspca_dev, 0x39, 0x09);
15638c2ecf20Sopenharmony_ci	cit_Packet_Format1(gspca_dev, 0x3b, 0x00);
15648c2ecf20Sopenharmony_ci	cit_Packet_Format1(gspca_dev, 0x28, 0x22);
15658c2ecf20Sopenharmony_ci	cit_Packet_Format1(gspca_dev, 0x27, 0x00);
15668c2ecf20Sopenharmony_ci	cit_Packet_Format1(gspca_dev, 0x2b, 0x1f);
15678c2ecf20Sopenharmony_ci	cit_Packet_Format1(gspca_dev, 0x39, 0x08);
15688c2ecf20Sopenharmony_ci
15698c2ecf20Sopenharmony_ci	for (i = 0; i < cit_model1_ntries; i++)
15708c2ecf20Sopenharmony_ci		cit_Packet_Format1(gspca_dev, 0x2c, 0x00);
15718c2ecf20Sopenharmony_ci
15728c2ecf20Sopenharmony_ci	for (i = 0; i < cit_model1_ntries; i++)
15738c2ecf20Sopenharmony_ci		cit_Packet_Format1(gspca_dev, 0x30, 0x14);
15748c2ecf20Sopenharmony_ci
15758c2ecf20Sopenharmony_ci	cit_PacketFormat2(gspca_dev, 0x39, 0x02);
15768c2ecf20Sopenharmony_ci	cit_PacketFormat2(gspca_dev, 0x01, 0xe1);
15778c2ecf20Sopenharmony_ci	cit_PacketFormat2(gspca_dev, 0x02, 0xcd);
15788c2ecf20Sopenharmony_ci	cit_PacketFormat2(gspca_dev, 0x03, 0xcd);
15798c2ecf20Sopenharmony_ci	cit_PacketFormat2(gspca_dev, 0x04, 0xfa);
15808c2ecf20Sopenharmony_ci	cit_PacketFormat2(gspca_dev, 0x3f, 0xff);
15818c2ecf20Sopenharmony_ci	cit_PacketFormat2(gspca_dev, 0x39, 0x00);
15828c2ecf20Sopenharmony_ci
15838c2ecf20Sopenharmony_ci	cit_PacketFormat2(gspca_dev, 0x39, 0x02);
15848c2ecf20Sopenharmony_ci	cit_PacketFormat2(gspca_dev, 0x0a, 0x37);
15858c2ecf20Sopenharmony_ci	cit_PacketFormat2(gspca_dev, 0x0b, 0xb8);
15868c2ecf20Sopenharmony_ci	cit_PacketFormat2(gspca_dev, 0x0c, 0xf3);
15878c2ecf20Sopenharmony_ci	cit_PacketFormat2(gspca_dev, 0x0d, 0xe3);
15888c2ecf20Sopenharmony_ci	cit_PacketFormat2(gspca_dev, 0x0e, 0x0d);
15898c2ecf20Sopenharmony_ci	cit_PacketFormat2(gspca_dev, 0x0f, 0xf2);
15908c2ecf20Sopenharmony_ci	cit_PacketFormat2(gspca_dev, 0x10, 0xd5);
15918c2ecf20Sopenharmony_ci	cit_PacketFormat2(gspca_dev, 0x11, 0xba);
15928c2ecf20Sopenharmony_ci	cit_PacketFormat2(gspca_dev, 0x12, 0x53);
15938c2ecf20Sopenharmony_ci	cit_PacketFormat2(gspca_dev, 0x3f, 0xff);
15948c2ecf20Sopenharmony_ci	cit_PacketFormat2(gspca_dev, 0x39, 0x00);
15958c2ecf20Sopenharmony_ci
15968c2ecf20Sopenharmony_ci	cit_PacketFormat2(gspca_dev, 0x39, 0x02);
15978c2ecf20Sopenharmony_ci	cit_PacketFormat2(gspca_dev, 0x16, 0x00);
15988c2ecf20Sopenharmony_ci	cit_PacketFormat2(gspca_dev, 0x17, 0x28);
15998c2ecf20Sopenharmony_ci	cit_PacketFormat2(gspca_dev, 0x18, 0x7d);
16008c2ecf20Sopenharmony_ci	cit_PacketFormat2(gspca_dev, 0x19, 0xbe);
16018c2ecf20Sopenharmony_ci	cit_PacketFormat2(gspca_dev, 0x3f, 0xff);
16028c2ecf20Sopenharmony_ci	cit_PacketFormat2(gspca_dev, 0x39, 0x00);
16038c2ecf20Sopenharmony_ci
16048c2ecf20Sopenharmony_ci	for (i = 0; i < cit_model1_ntries; i++)
16058c2ecf20Sopenharmony_ci		cit_Packet_Format1(gspca_dev, 0x00, 0x18);
16068c2ecf20Sopenharmony_ci	for (i = 0; i < cit_model1_ntries; i++)
16078c2ecf20Sopenharmony_ci		cit_Packet_Format1(gspca_dev, 0x13, 0x18);
16088c2ecf20Sopenharmony_ci	for (i = 0; i < cit_model1_ntries; i++)
16098c2ecf20Sopenharmony_ci		cit_Packet_Format1(gspca_dev, 0x14, 0x06);
16108c2ecf20Sopenharmony_ci
16118c2ecf20Sopenharmony_ci	/* TESTME These are handled through controls
16128c2ecf20Sopenharmony_ci	   KEEP until someone can test leaving this out is ok */
16138c2ecf20Sopenharmony_ci	if (0) {
16148c2ecf20Sopenharmony_ci		/* This is default brightness */
16158c2ecf20Sopenharmony_ci		for (i = 0; i < cit_model1_ntries; i++)
16168c2ecf20Sopenharmony_ci			cit_Packet_Format1(gspca_dev, 0x31, 0x37);
16178c2ecf20Sopenharmony_ci		for (i = 0; i < cit_model1_ntries; i++)
16188c2ecf20Sopenharmony_ci			cit_Packet_Format1(gspca_dev, 0x32, 0x46);
16198c2ecf20Sopenharmony_ci		for (i = 0; i < cit_model1_ntries; i++)
16208c2ecf20Sopenharmony_ci			cit_Packet_Format1(gspca_dev, 0x33, 0x55);
16218c2ecf20Sopenharmony_ci	}
16228c2ecf20Sopenharmony_ci
16238c2ecf20Sopenharmony_ci	cit_Packet_Format1(gspca_dev, 0x2e, 0x04);
16248c2ecf20Sopenharmony_ci	for (i = 0; i < cit_model1_ntries; i++)
16258c2ecf20Sopenharmony_ci		cit_Packet_Format1(gspca_dev, 0x2d, 0x04);
16268c2ecf20Sopenharmony_ci	for (i = 0; i < cit_model1_ntries; i++)
16278c2ecf20Sopenharmony_ci		cit_Packet_Format1(gspca_dev, 0x29, 0x80);
16288c2ecf20Sopenharmony_ci	cit_Packet_Format1(gspca_dev, 0x2c, 0x01);
16298c2ecf20Sopenharmony_ci	cit_Packet_Format1(gspca_dev, 0x30, 0x17);
16308c2ecf20Sopenharmony_ci	cit_Packet_Format1(gspca_dev, 0x39, 0x08);
16318c2ecf20Sopenharmony_ci	for (i = 0; i < cit_model1_ntries; i++)
16328c2ecf20Sopenharmony_ci		cit_Packet_Format1(gspca_dev, 0x34, 0x00);
16338c2ecf20Sopenharmony_ci
16348c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x00, 0x0101);
16358c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x00, 0x010a);
16368c2ecf20Sopenharmony_ci
16378c2ecf20Sopenharmony_ci	switch (gspca_dev->pixfmt.width) {
16388c2ecf20Sopenharmony_ci	case 128: /* 128x96 */
16398c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x80, 0x0103);
16408c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x60, 0x0105);
16418c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0c, 0x010b);
16428c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x04, 0x011b);	/* Same everywhere */
16438c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0b, 0x011d);
16448c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00, 0x011e);	/* Same everywhere */
16458c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00, 0x0129);
16468c2ecf20Sopenharmony_ci		break;
16478c2ecf20Sopenharmony_ci	case 176: /* 176x144 */
16488c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xb0, 0x0103);
16498c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x8f, 0x0105);
16508c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x06, 0x010b);
16518c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x04, 0x011b);	/* Same everywhere */
16528c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0d, 0x011d);
16538c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00, 0x011e);	/* Same everywhere */
16548c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x03, 0x0129);
16558c2ecf20Sopenharmony_ci		break;
16568c2ecf20Sopenharmony_ci	case 352: /* 352x288 */
16578c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xb0, 0x0103);
16588c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x90, 0x0105);
16598c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x02, 0x010b);
16608c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x04, 0x011b);	/* Same everywhere */
16618c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x05, 0x011d);
16628c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00, 0x011e);	/* Same everywhere */
16638c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00, 0x0129);
16648c2ecf20Sopenharmony_ci		break;
16658c2ecf20Sopenharmony_ci	}
16668c2ecf20Sopenharmony_ci
16678c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0xff, 0x012b);
16688c2ecf20Sopenharmony_ci
16698c2ecf20Sopenharmony_ci	/* TESTME These are handled through controls
16708c2ecf20Sopenharmony_ci	   KEEP until someone can test leaving this out is ok */
16718c2ecf20Sopenharmony_ci	if (0) {
16728c2ecf20Sopenharmony_ci		/* This is another brightness - don't know why */
16738c2ecf20Sopenharmony_ci		for (i = 0; i < cit_model1_ntries; i++)
16748c2ecf20Sopenharmony_ci			cit_Packet_Format1(gspca_dev, 0x31, 0xc3);
16758c2ecf20Sopenharmony_ci		for (i = 0; i < cit_model1_ntries; i++)
16768c2ecf20Sopenharmony_ci			cit_Packet_Format1(gspca_dev, 0x32, 0xd2);
16778c2ecf20Sopenharmony_ci		for (i = 0; i < cit_model1_ntries; i++)
16788c2ecf20Sopenharmony_ci			cit_Packet_Format1(gspca_dev, 0x33, 0xe1);
16798c2ecf20Sopenharmony_ci
16808c2ecf20Sopenharmony_ci		/* Default contrast */
16818c2ecf20Sopenharmony_ci		for (i = 0; i < cit_model1_ntries; i++)
16828c2ecf20Sopenharmony_ci			cit_Packet_Format1(gspca_dev, 0x14, 0x0a);
16838c2ecf20Sopenharmony_ci
16848c2ecf20Sopenharmony_ci		/* Default sharpness */
16858c2ecf20Sopenharmony_ci		for (i = 0; i < cit_model1_ntries2; i++)
16868c2ecf20Sopenharmony_ci			cit_PacketFormat2(gspca_dev, 0x13, 0x1a);
16878c2ecf20Sopenharmony_ci
16888c2ecf20Sopenharmony_ci		/* Default lighting conditions */
16898c2ecf20Sopenharmony_ci		cit_Packet_Format1(gspca_dev, 0x0027,
16908c2ecf20Sopenharmony_ci				   v4l2_ctrl_g_ctrl(sd->lighting));
16918c2ecf20Sopenharmony_ci	}
16928c2ecf20Sopenharmony_ci
16938c2ecf20Sopenharmony_ci	/* Assorted init */
16948c2ecf20Sopenharmony_ci	switch (gspca_dev->pixfmt.width) {
16958c2ecf20Sopenharmony_ci	case 128: /* 128x96 */
16968c2ecf20Sopenharmony_ci		cit_Packet_Format1(gspca_dev, 0x2b, 0x1e);
16978c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xc9, 0x0119);	/* Same everywhere */
16988c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x80, 0x0109);	/* Same everywhere */
16998c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x36, 0x0102);
17008c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x1a, 0x0104);
17018c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x04, 0x011a);	/* Same everywhere */
17028c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x2b, 0x011c);
17038c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x23, 0x012a);	/* Same everywhere */
17048c2ecf20Sopenharmony_ci		break;
17058c2ecf20Sopenharmony_ci	case 176: /* 176x144 */
17068c2ecf20Sopenharmony_ci		cit_Packet_Format1(gspca_dev, 0x2b, 0x1e);
17078c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xc9, 0x0119);	/* Same everywhere */
17088c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x80, 0x0109);	/* Same everywhere */
17098c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x04, 0x0102);
17108c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x02, 0x0104);
17118c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x04, 0x011a);	/* Same everywhere */
17128c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x2b, 0x011c);
17138c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x23, 0x012a);	/* Same everywhere */
17148c2ecf20Sopenharmony_ci		break;
17158c2ecf20Sopenharmony_ci	case 352: /* 352x288 */
17168c2ecf20Sopenharmony_ci		cit_Packet_Format1(gspca_dev, 0x2b, 0x1f);
17178c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xc9, 0x0119);	/* Same everywhere */
17188c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x80, 0x0109);	/* Same everywhere */
17198c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x08, 0x0102);
17208c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x01, 0x0104);
17218c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x04, 0x011a);	/* Same everywhere */
17228c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x2f, 0x011c);
17238c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x23, 0x012a);	/* Same everywhere */
17248c2ecf20Sopenharmony_ci		break;
17258c2ecf20Sopenharmony_ci	}
17268c2ecf20Sopenharmony_ci
17278c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x01, 0x0100);	/* LED On  */
17288c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, clock_div, 0x0111);
17298c2ecf20Sopenharmony_ci
17308c2ecf20Sopenharmony_ci	return 0;
17318c2ecf20Sopenharmony_ci}
17328c2ecf20Sopenharmony_ci
17338c2ecf20Sopenharmony_cistatic int cit_start_model2(struct gspca_dev *gspca_dev)
17348c2ecf20Sopenharmony_ci{
17358c2ecf20Sopenharmony_ci	struct sd *sd = (struct sd *) gspca_dev;
17368c2ecf20Sopenharmony_ci	int clock_div = 0;
17378c2ecf20Sopenharmony_ci
17388c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0100);	/* LED on */
17398c2ecf20Sopenharmony_ci	cit_read_reg(gspca_dev, 0x0116, 0);
17408c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0060, 0x0116);
17418c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0002, 0x0112);
17428c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x00bc, 0x012c);
17438c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0008, 0x012b);
17448c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0108);
17458c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0001, 0x0133);
17468c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0001, 0x0102);
17478c2ecf20Sopenharmony_ci	switch (gspca_dev->pixfmt.width) {
17488c2ecf20Sopenharmony_ci	case 176: /* 176x144 */
17498c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x002c, 0x0103);	/* All except 320x240 */
17508c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0104);	/* Same */
17518c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0024, 0x0105);	/* 176x144, 352x288 */
17528c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00b9, 0x010a);	/* Unique to this mode */
17538c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0038, 0x0119);	/* Unique to this mode */
17548c2ecf20Sopenharmony_ci		/* TESTME HDG: this does not seem right
17558c2ecf20Sopenharmony_ci		   (it is 2 for all other resolutions) */
17568c2ecf20Sopenharmony_ci		sd->sof_len = 10;
17578c2ecf20Sopenharmony_ci		break;
17588c2ecf20Sopenharmony_ci	case 320: /* 320x240 */
17598c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0028, 0x0103);	/* Unique to this mode */
17608c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0104);	/* Same */
17618c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x001e, 0x0105);	/* 320x240, 352x240 */
17628c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0039, 0x010a);	/* All except 176x144 */
17638c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0070, 0x0119);	/* All except 176x144 */
17648c2ecf20Sopenharmony_ci		sd->sof_len = 2;
17658c2ecf20Sopenharmony_ci		break;
17668c2ecf20Sopenharmony_ci#if 0
17678c2ecf20Sopenharmony_ci	case VIDEOSIZE_352x240:
17688c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x002c, 0x0103);	/* All except 320x240 */
17698c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0104);	/* Same */
17708c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x001e, 0x0105);	/* 320x240, 352x240 */
17718c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0039, 0x010a);	/* All except 176x144 */
17728c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0070, 0x0119);	/* All except 176x144 */
17738c2ecf20Sopenharmony_ci		sd->sof_len = 2;
17748c2ecf20Sopenharmony_ci		break;
17758c2ecf20Sopenharmony_ci#endif
17768c2ecf20Sopenharmony_ci	case 352: /* 352x288 */
17778c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x002c, 0x0103);	/* All except 320x240 */
17788c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0104);	/* Same */
17798c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0024, 0x0105);	/* 176x144, 352x288 */
17808c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0039, 0x010a);	/* All except 176x144 */
17818c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0070, 0x0119);	/* All except 176x144 */
17828c2ecf20Sopenharmony_ci		sd->sof_len = 2;
17838c2ecf20Sopenharmony_ci		break;
17848c2ecf20Sopenharmony_ci	}
17858c2ecf20Sopenharmony_ci
17868c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0100);	/* LED on */
17878c2ecf20Sopenharmony_ci
17888c2ecf20Sopenharmony_ci	switch (gspca_dev->pixfmt.width) {
17898c2ecf20Sopenharmony_ci	case 176: /* 176x144 */
17908c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0050, 0x0111);
17918c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00d0, 0x0111);
17928c2ecf20Sopenharmony_ci		break;
17938c2ecf20Sopenharmony_ci	case 320: /* 320x240 */
17948c2ecf20Sopenharmony_ci	case 352: /* 352x288 */
17958c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0040, 0x0111);
17968c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00c0, 0x0111);
17978c2ecf20Sopenharmony_ci		break;
17988c2ecf20Sopenharmony_ci	}
17998c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x009b, 0x010f);
18008c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x00bb, 0x010f);
18018c2ecf20Sopenharmony_ci
18028c2ecf20Sopenharmony_ci	/*
18038c2ecf20Sopenharmony_ci	 * Hardware settings, may affect CMOS sensor; not user controls!
18048c2ecf20Sopenharmony_ci	 * -------------------------------------------------------------
18058c2ecf20Sopenharmony_ci	 * 0x0004: no effect
18068c2ecf20Sopenharmony_ci	 * 0x0006: hardware effect
18078c2ecf20Sopenharmony_ci	 * 0x0008: no effect
18088c2ecf20Sopenharmony_ci	 * 0x000a: stops video stream, probably important h/w setting
18098c2ecf20Sopenharmony_ci	 * 0x000c: changes color in hardware manner (not user setting)
18108c2ecf20Sopenharmony_ci	 * 0x0012: changes number of colors (does not affect speed)
18118c2ecf20Sopenharmony_ci	 * 0x002a: no effect
18128c2ecf20Sopenharmony_ci	 * 0x002c: hardware setting (related to scan lines)
18138c2ecf20Sopenharmony_ci	 * 0x002e: stops video stream, probably important h/w setting
18148c2ecf20Sopenharmony_ci	 */
18158c2ecf20Sopenharmony_ci	cit_model2_Packet1(gspca_dev, 0x000a, 0x005c);
18168c2ecf20Sopenharmony_ci	cit_model2_Packet1(gspca_dev, 0x0004, 0x0000);
18178c2ecf20Sopenharmony_ci	cit_model2_Packet1(gspca_dev, 0x0006, 0x00fb);
18188c2ecf20Sopenharmony_ci	cit_model2_Packet1(gspca_dev, 0x0008, 0x0000);
18198c2ecf20Sopenharmony_ci	cit_model2_Packet1(gspca_dev, 0x000c, 0x0009);
18208c2ecf20Sopenharmony_ci	cit_model2_Packet1(gspca_dev, 0x0012, 0x000a);
18218c2ecf20Sopenharmony_ci	cit_model2_Packet1(gspca_dev, 0x002a, 0x0000);
18228c2ecf20Sopenharmony_ci	cit_model2_Packet1(gspca_dev, 0x002c, 0x0000);
18238c2ecf20Sopenharmony_ci	cit_model2_Packet1(gspca_dev, 0x002e, 0x0008);
18248c2ecf20Sopenharmony_ci
18258c2ecf20Sopenharmony_ci	/*
18268c2ecf20Sopenharmony_ci	 * Function 0x0030 pops up all over the place. Apparently
18278c2ecf20Sopenharmony_ci	 * it is a hardware control register, with every bit assigned to
18288c2ecf20Sopenharmony_ci	 * do something.
18298c2ecf20Sopenharmony_ci	 */
18308c2ecf20Sopenharmony_ci	cit_model2_Packet1(gspca_dev, 0x0030, 0x0000);
18318c2ecf20Sopenharmony_ci
18328c2ecf20Sopenharmony_ci	/*
18338c2ecf20Sopenharmony_ci	 * Magic control of CMOS sensor. Only lower values like
18348c2ecf20Sopenharmony_ci	 * 0-3 work, and picture shifts left or right. Don't change.
18358c2ecf20Sopenharmony_ci	 */
18368c2ecf20Sopenharmony_ci	switch (gspca_dev->pixfmt.width) {
18378c2ecf20Sopenharmony_ci	case 176: /* 176x144 */
18388c2ecf20Sopenharmony_ci		cit_model2_Packet1(gspca_dev, 0x0014, 0x0002);
18398c2ecf20Sopenharmony_ci		cit_model2_Packet1(gspca_dev, 0x0016, 0x0002); /* Horizontal shift */
18408c2ecf20Sopenharmony_ci		cit_model2_Packet1(gspca_dev, 0x0018, 0x004a); /* Another hardware setting */
18418c2ecf20Sopenharmony_ci		clock_div = 6;
18428c2ecf20Sopenharmony_ci		break;
18438c2ecf20Sopenharmony_ci	case 320: /* 320x240 */
18448c2ecf20Sopenharmony_ci		cit_model2_Packet1(gspca_dev, 0x0014, 0x0009);
18458c2ecf20Sopenharmony_ci		cit_model2_Packet1(gspca_dev, 0x0016, 0x0005); /* Horizontal shift */
18468c2ecf20Sopenharmony_ci		cit_model2_Packet1(gspca_dev, 0x0018, 0x0044); /* Another hardware setting */
18478c2ecf20Sopenharmony_ci		clock_div = 8;
18488c2ecf20Sopenharmony_ci		break;
18498c2ecf20Sopenharmony_ci#if 0
18508c2ecf20Sopenharmony_ci	case VIDEOSIZE_352x240:
18518c2ecf20Sopenharmony_ci		/* This mode doesn't work as Windows programs it; changed to work */
18528c2ecf20Sopenharmony_ci		cit_model2_Packet1(gspca_dev, 0x0014, 0x0009); /* Windows sets this to 8 */
18538c2ecf20Sopenharmony_ci		cit_model2_Packet1(gspca_dev, 0x0016, 0x0003); /* Horizontal shift */
18548c2ecf20Sopenharmony_ci		cit_model2_Packet1(gspca_dev, 0x0018, 0x0044); /* Windows sets this to 0x0045 */
18558c2ecf20Sopenharmony_ci		clock_div = 10;
18568c2ecf20Sopenharmony_ci		break;
18578c2ecf20Sopenharmony_ci#endif
18588c2ecf20Sopenharmony_ci	case 352: /* 352x288 */
18598c2ecf20Sopenharmony_ci		cit_model2_Packet1(gspca_dev, 0x0014, 0x0003);
18608c2ecf20Sopenharmony_ci		cit_model2_Packet1(gspca_dev, 0x0016, 0x0002); /* Horizontal shift */
18618c2ecf20Sopenharmony_ci		cit_model2_Packet1(gspca_dev, 0x0018, 0x004a); /* Another hardware setting */
18628c2ecf20Sopenharmony_ci		clock_div = 16;
18638c2ecf20Sopenharmony_ci		break;
18648c2ecf20Sopenharmony_ci	}
18658c2ecf20Sopenharmony_ci
18668c2ecf20Sopenharmony_ci	/* TESTME These are handled through controls
18678c2ecf20Sopenharmony_ci	   KEEP until someone can test leaving this out is ok */
18688c2ecf20Sopenharmony_ci	if (0)
18698c2ecf20Sopenharmony_ci		cit_model2_Packet1(gspca_dev, 0x001a, 0x005a);
18708c2ecf20Sopenharmony_ci
18718c2ecf20Sopenharmony_ci	/*
18728c2ecf20Sopenharmony_ci	 * We have our own frame rate setting varying from 0 (slowest) to 6
18738c2ecf20Sopenharmony_ci	 * (fastest). The camera model 2 allows frame rate in range [0..0x1F]
18748c2ecf20Sopenharmony_ci	 # where 0 is also the slowest setting. However for all practical
18758c2ecf20Sopenharmony_ci	 # reasons high settings make no sense because USB is not fast enough
18768c2ecf20Sopenharmony_ci	 # to support high FPS. Be aware that the picture datastream will be
18778c2ecf20Sopenharmony_ci	 # severely disrupted if you ask for frame rate faster than allowed
18788c2ecf20Sopenharmony_ci	 # for the video size - see below:
18798c2ecf20Sopenharmony_ci	 *
18808c2ecf20Sopenharmony_ci	 * Allowable ranges (obtained experimentally on OHCI, K6-3, 450 MHz):
18818c2ecf20Sopenharmony_ci	 * -----------------------------------------------------------------
18828c2ecf20Sopenharmony_ci	 * 176x144: [6..31]
18838c2ecf20Sopenharmony_ci	 * 320x240: [8..31]
18848c2ecf20Sopenharmony_ci	 * 352x240: [10..31]
18858c2ecf20Sopenharmony_ci	 * 352x288: [16..31] I have to raise lower threshold for stability...
18868c2ecf20Sopenharmony_ci	 *
18878c2ecf20Sopenharmony_ci	 * As usual, slower FPS provides better sensitivity.
18888c2ecf20Sopenharmony_ci	 */
18898c2ecf20Sopenharmony_ci	cit_model2_Packet1(gspca_dev, 0x001c, clock_div);
18908c2ecf20Sopenharmony_ci
18918c2ecf20Sopenharmony_ci	/*
18928c2ecf20Sopenharmony_ci	 * This setting does not visibly affect pictures; left it here
18938c2ecf20Sopenharmony_ci	 * because it was present in Windows USB data stream. This function
18948c2ecf20Sopenharmony_ci	 * does not allow arbitrary values and apparently is a bit mask, to
18958c2ecf20Sopenharmony_ci	 * be activated only at appropriate time. Don't change it randomly!
18968c2ecf20Sopenharmony_ci	 */
18978c2ecf20Sopenharmony_ci	switch (gspca_dev->pixfmt.width) {
18988c2ecf20Sopenharmony_ci	case 176: /* 176x144 */
18998c2ecf20Sopenharmony_ci		cit_model2_Packet1(gspca_dev, 0x0026, 0x00c2);
19008c2ecf20Sopenharmony_ci		break;
19018c2ecf20Sopenharmony_ci	case 320: /* 320x240 */
19028c2ecf20Sopenharmony_ci		cit_model2_Packet1(gspca_dev, 0x0026, 0x0044);
19038c2ecf20Sopenharmony_ci		break;
19048c2ecf20Sopenharmony_ci#if 0
19058c2ecf20Sopenharmony_ci	case VIDEOSIZE_352x240:
19068c2ecf20Sopenharmony_ci		cit_model2_Packet1(gspca_dev, 0x0026, 0x0046);
19078c2ecf20Sopenharmony_ci		break;
19088c2ecf20Sopenharmony_ci#endif
19098c2ecf20Sopenharmony_ci	case 352: /* 352x288 */
19108c2ecf20Sopenharmony_ci		cit_model2_Packet1(gspca_dev, 0x0026, 0x0048);
19118c2ecf20Sopenharmony_ci		break;
19128c2ecf20Sopenharmony_ci	}
19138c2ecf20Sopenharmony_ci
19148c2ecf20Sopenharmony_ci	cit_model2_Packet1(gspca_dev, 0x0028, v4l2_ctrl_g_ctrl(sd->lighting));
19158c2ecf20Sopenharmony_ci	/* model2 cannot change the backlight compensation while streaming */
19168c2ecf20Sopenharmony_ci	v4l2_ctrl_grab(sd->lighting, true);
19178c2ecf20Sopenharmony_ci
19188c2ecf20Sopenharmony_ci	/* color balance rg2 */
19198c2ecf20Sopenharmony_ci	cit_model2_Packet1(gspca_dev, 0x001e, 0x002f);
19208c2ecf20Sopenharmony_ci	/* saturation */
19218c2ecf20Sopenharmony_ci	cit_model2_Packet1(gspca_dev, 0x0020, 0x0034);
19228c2ecf20Sopenharmony_ci	/* color balance yb */
19238c2ecf20Sopenharmony_ci	cit_model2_Packet1(gspca_dev, 0x0022, 0x00a0);
19248c2ecf20Sopenharmony_ci
19258c2ecf20Sopenharmony_ci	/* Hardware control command */
19268c2ecf20Sopenharmony_ci	cit_model2_Packet1(gspca_dev, 0x0030, 0x0004);
19278c2ecf20Sopenharmony_ci
19288c2ecf20Sopenharmony_ci	return 0;
19298c2ecf20Sopenharmony_ci}
19308c2ecf20Sopenharmony_ci
19318c2ecf20Sopenharmony_cistatic int cit_start_model3(struct gspca_dev *gspca_dev)
19328c2ecf20Sopenharmony_ci{
19338c2ecf20Sopenharmony_ci	const unsigned short compression = 0; /* 0=none, 7=best frame rate */
19348c2ecf20Sopenharmony_ci	int i, clock_div = 0;
19358c2ecf20Sopenharmony_ci
19368c2ecf20Sopenharmony_ci	/* HDG not in ibmcam driver, added to see if it helps with
19378c2ecf20Sopenharmony_ci	   auto-detecting between model3 and ibm netcamera pro */
19388c2ecf20Sopenharmony_ci	cit_read_reg(gspca_dev, 0x128, 1);
19398c2ecf20Sopenharmony_ci
19408c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0100);
19418c2ecf20Sopenharmony_ci	cit_read_reg(gspca_dev, 0x0116, 0);
19428c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0060, 0x0116);
19438c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0002, 0x0112);
19448c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0123);
19458c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0001, 0x0117);
19468c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0040, 0x0108);
19478c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0019, 0x012c);
19488c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0060, 0x0116);
19498c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0002, 0x0115);
19508c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0003, 0x0115);
19518c2ecf20Sopenharmony_ci	cit_read_reg(gspca_dev, 0x0115, 0);
19528c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x000b, 0x0115);
19538c2ecf20Sopenharmony_ci
19548c2ecf20Sopenharmony_ci	/* TESTME HDG not in ibmcam driver, added to see if it helps with
19558c2ecf20Sopenharmony_ci	   auto-detecting between model3 and ibm netcamera pro */
19568c2ecf20Sopenharmony_ci	if (0) {
19578c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0078, 0x012d);
19588c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0001, 0x012f);
19598c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd141, 0x0124);
19608c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0079, 0x012d);
19618c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00ff, 0x0130);
19628c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xcd41, 0x0124);
19638c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xfffa, 0x0124);
19648c2ecf20Sopenharmony_ci		cit_read_reg(gspca_dev, 0x0126, 1);
19658c2ecf20Sopenharmony_ci	}
19668c2ecf20Sopenharmony_ci
19678c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x000a, 0x0040);
19688c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x000b, 0x00f6);
19698c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x000c, 0x0002);
19708c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x000d, 0x0020);
19718c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x000e, 0x0033);
19728c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x000f, 0x0007);
19738c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0010, 0x0000);
19748c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0011, 0x0070);
19758c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0012, 0x0030);
19768c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0013, 0x0000);
19778c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0014, 0x0001);
19788c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0015, 0x0001);
19798c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0016, 0x0001);
19808c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0017, 0x0001);
19818c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0018, 0x0000);
19828c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x001e, 0x00c3);
19838c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0020, 0x0000);
19848c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0028, 0x0010);
19858c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0029, 0x0054);
19868c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x002a, 0x0013);
19878c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x002b, 0x0007);
19888c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x002d, 0x0028);
19898c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x002e, 0x0000);
19908c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0031, 0x0000);
19918c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0032, 0x0000);
19928c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0033, 0x0000);
19938c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0034, 0x0000);
19948c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0035, 0x0038);
19958c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x003a, 0x0001);
19968c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x003c, 0x001e);
19978c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x003f, 0x000a);
19988c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0041, 0x0000);
19998c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0046, 0x003f);
20008c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0047, 0x0000);
20018c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0050, 0x0005);
20028c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0052, 0x001a);
20038c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0053, 0x0003);
20048c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x005a, 0x006b);
20058c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x005d, 0x001e);
20068c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x005e, 0x0030);
20078c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x005f, 0x0041);
20088c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0064, 0x0008);
20098c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0065, 0x0015);
20108c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0068, 0x000f);
20118c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0079, 0x0000);
20128c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x007a, 0x0000);
20138c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x007c, 0x003f);
20148c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0082, 0x000f);
20158c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0085, 0x0000);
20168c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0099, 0x0000);
20178c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x009b, 0x0023);
20188c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x009c, 0x0022);
20198c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x009d, 0x0096);
20208c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x009e, 0x0096);
20218c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x009f, 0x000a);
20228c2ecf20Sopenharmony_ci
20238c2ecf20Sopenharmony_ci	switch (gspca_dev->pixfmt.width) {
20248c2ecf20Sopenharmony_ci	case 160:
20258c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0101); /* Same on 160x120, 320x240 */
20268c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00a0, 0x0103); /* Same on 160x120, 320x240 */
20278c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0078, 0x0105); /* Same on 160x120, 320x240 */
20288c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x010a); /* Same */
20298c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0024, 0x010b); /* Differs everywhere */
20308c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00a9, 0x0119);
20318c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0016, 0x011b);
20328c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0002, 0x011d); /* Same on 160x120, 320x240 */
20338c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0003, 0x011e); /* Same on 160x120, 640x480 */
20348c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0129); /* Same */
20358c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00fc, 0x012b); /* Same */
20368c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0018, 0x0102);
20378c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0004, 0x0104);
20388c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0004, 0x011a);
20398c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0028, 0x011c);
20408c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0022, 0x012a); /* Same */
20418c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0118);
20428c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0132);
20438c2ecf20Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x0021, 0x0001); /* Same */
20448c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, compression, 0x0109);
20458c2ecf20Sopenharmony_ci		clock_div = 3;
20468c2ecf20Sopenharmony_ci		break;
20478c2ecf20Sopenharmony_ci	case 320:
20488c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0101); /* Same on 160x120, 320x240 */
20498c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00a0, 0x0103); /* Same on 160x120, 320x240 */
20508c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0078, 0x0105); /* Same on 160x120, 320x240 */
20518c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x010a); /* Same */
20528c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0028, 0x010b); /* Differs everywhere */
20538c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0002, 0x011d); /* Same */
20548c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x011e);
20558c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0129); /* Same */
20568c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00fc, 0x012b); /* Same */
20578c2ecf20Sopenharmony_ci		/* 4 commands from 160x120 skipped */
20588c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0022, 0x012a); /* Same */
20598c2ecf20Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x0021, 0x0001); /* Same */
20608c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, compression, 0x0109);
20618c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00d9, 0x0119);
20628c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0006, 0x011b);
20638c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0021, 0x0102); /* Same on 320x240, 640x480 */
20648c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0010, 0x0104);
20658c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0004, 0x011a);
20668c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x003f, 0x011c);
20678c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x001c, 0x0118);
20688c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0132);
20698c2ecf20Sopenharmony_ci		clock_div = 5;
20708c2ecf20Sopenharmony_ci		break;
20718c2ecf20Sopenharmony_ci	case 640:
20728c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00f0, 0x0105);
20738c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x010a); /* Same */
20748c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0038, 0x010b); /* Differs everywhere */
20758c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00d9, 0x0119); /* Same on 320x240, 640x480 */
20768c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0006, 0x011b); /* Same on 320x240, 640x480 */
20778c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0004, 0x011d); /* NC */
20788c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0003, 0x011e); /* Same on 160x120, 640x480 */
20798c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0129); /* Same */
20808c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00fc, 0x012b); /* Same */
20818c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0021, 0x0102); /* Same on 320x240, 640x480 */
20828c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0016, 0x0104); /* NC */
20838c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0004, 0x011a); /* Same on 320x240, 640x480 */
20848c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x003f, 0x011c); /* Same on 320x240, 640x480 */
20858c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0022, 0x012a); /* Same */
20868c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x001c, 0x0118); /* Same on 320x240, 640x480 */
20878c2ecf20Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x0021, 0x0001); /* Same */
20888c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, compression, 0x0109);
20898c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0040, 0x0101);
20908c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0040, 0x0103);
20918c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0132); /* Same on 320x240, 640x480 */
20928c2ecf20Sopenharmony_ci		clock_div = 7;
20938c2ecf20Sopenharmony_ci		break;
20948c2ecf20Sopenharmony_ci	}
20958c2ecf20Sopenharmony_ci
20968c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x007e, 0x000e);	/* Hue */
20978c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0036, 0x0011);	/* Brightness */
20988c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0060, 0x0002);	/* Sharpness */
20998c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0061, 0x0004);	/* Sharpness */
21008c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0062, 0x0005);	/* Sharpness */
21018c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0063, 0x0014);	/* Sharpness */
21028c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0096, 0x00a0);	/* Red sharpness */
21038c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0097, 0x0096);	/* Blue sharpness */
21048c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0067, 0x0001);	/* Contrast */
21058c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x005b, 0x000c);	/* Contrast */
21068c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x005c, 0x0016);	/* Contrast */
21078c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0098, 0x000b);
21088c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x002c, 0x0003);	/* Was 1, broke 640x480 */
21098c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x002f, 0x002a);
21108c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0030, 0x0029);
21118c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0037, 0x0002);
21128c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0038, 0x0059);
21138c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x003d, 0x002e);
21148c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x003e, 0x0028);
21158c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0078, 0x0005);
21168c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x007b, 0x0011);
21178c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x007d, 0x004b);
21188c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x007f, 0x0022);
21198c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0080, 0x000c);
21208c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0081, 0x000b);
21218c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0083, 0x00fd);
21228c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0086, 0x000b);
21238c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0087, 0x000b);
21248c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x007e, 0x000e);
21258c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0096, 0x00a0);	/* Red sharpness */
21268c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0097, 0x0096);	/* Blue sharpness */
21278c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0098, 0x000b);
21288c2ecf20Sopenharmony_ci
21298c2ecf20Sopenharmony_ci	/* FIXME we should probably use cit_get_clock_div() here (in
21308c2ecf20Sopenharmony_ci	   combination with isoc negotiation using the programmable isoc size)
21318c2ecf20Sopenharmony_ci	   like with the IBM netcam pro). */
21328c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, clock_div, 0x0111); /* Clock Divider */
21338c2ecf20Sopenharmony_ci
21348c2ecf20Sopenharmony_ci	switch (gspca_dev->pixfmt.width) {
21358c2ecf20Sopenharmony_ci	case 160:
21368c2ecf20Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x001f, 0x0000); /* Same */
21378c2ecf20Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x0039, 0x001f); /* Same */
21388c2ecf20Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x003b, 0x003c); /* Same */
21398c2ecf20Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x0040, 0x000a);
21408c2ecf20Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x0051, 0x000a);
21418c2ecf20Sopenharmony_ci		break;
21428c2ecf20Sopenharmony_ci	case 320:
21438c2ecf20Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x001f, 0x0000); /* Same */
21448c2ecf20Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x0039, 0x001f); /* Same */
21458c2ecf20Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x003b, 0x003c); /* Same */
21468c2ecf20Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x0040, 0x0008);
21478c2ecf20Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x0051, 0x000b);
21488c2ecf20Sopenharmony_ci		break;
21498c2ecf20Sopenharmony_ci	case 640:
21508c2ecf20Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x001f, 0x0002);	/* !Same */
21518c2ecf20Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x0039, 0x003e);	/* !Same */
21528c2ecf20Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x0040, 0x0008);
21538c2ecf20Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x0051, 0x000a);
21548c2ecf20Sopenharmony_ci		break;
21558c2ecf20Sopenharmony_ci	}
21568c2ecf20Sopenharmony_ci
21578c2ecf20Sopenharmony_ci/*	if (sd->input_index) { */
21588c2ecf20Sopenharmony_ci	if (rca_input) {
21598c2ecf20Sopenharmony_ci		for (i = 0; i < ARRAY_SIZE(rca_initdata); i++) {
21608c2ecf20Sopenharmony_ci			if (rca_initdata[i][0])
21618c2ecf20Sopenharmony_ci				cit_read_reg(gspca_dev, rca_initdata[i][2], 0);
21628c2ecf20Sopenharmony_ci			else
21638c2ecf20Sopenharmony_ci				cit_write_reg(gspca_dev, rca_initdata[i][1],
21648c2ecf20Sopenharmony_ci					      rca_initdata[i][2]);
21658c2ecf20Sopenharmony_ci		}
21668c2ecf20Sopenharmony_ci	}
21678c2ecf20Sopenharmony_ci
21688c2ecf20Sopenharmony_ci	return 0;
21698c2ecf20Sopenharmony_ci}
21708c2ecf20Sopenharmony_ci
21718c2ecf20Sopenharmony_cistatic int cit_start_model4(struct gspca_dev *gspca_dev)
21728c2ecf20Sopenharmony_ci{
21738c2ecf20Sopenharmony_ci	struct sd *sd = (struct sd *) gspca_dev;
21748c2ecf20Sopenharmony_ci
21758c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0100);
21768c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x00c0, 0x0111);
21778c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x00bc, 0x012c);
21788c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0080, 0x012b);
21798c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0108);
21808c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0001, 0x0133);
21818c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x009b, 0x010f);
21828c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x00bb, 0x010f);
21838c2ecf20Sopenharmony_ci	cit_model4_Packet1(gspca_dev, 0x0038, 0x0000);
21848c2ecf20Sopenharmony_ci	cit_model4_Packet1(gspca_dev, 0x000a, 0x005c);
21858c2ecf20Sopenharmony_ci
21868c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x00aa, 0x012d);
21878c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0004, 0x012f);
21888c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0xd141, 0x0124);
21898c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0127);
21908c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x00fb, 0x012e);
21918c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0130);
21928c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x8a28, 0x0124);
21938c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x00aa, 0x012f);
21948c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0xd055, 0x0124);
21958c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x000c, 0x0127);
21968c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0009, 0x012e);
21978c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0xaa28, 0x0124);
21988c2ecf20Sopenharmony_ci
21998c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x00aa, 0x012d);
22008c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0012, 0x012f);
22018c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0xd141, 0x0124);
22028c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0008, 0x0127);
22038c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x00aa, 0x0130);
22048c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x82a8, 0x0124);
22058c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x002a, 0x012d);
22068c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x012f);
22078c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0xd145, 0x0124);
22088c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0xfffa, 0x0124);
22098c2ecf20Sopenharmony_ci	cit_model4_Packet1(gspca_dev, 0x0034, 0x0000);
22108c2ecf20Sopenharmony_ci
22118c2ecf20Sopenharmony_ci	switch (gspca_dev->pixfmt.width) {
22128c2ecf20Sopenharmony_ci	case 128: /* 128x96 */
22138c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0070, 0x0119);
22148c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00d0, 0x0111);
22158c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0039, 0x010a);
22168c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0001, 0x0102);
22178c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0028, 0x0103);
22188c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0104);
22198c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x001e, 0x0105);
22208c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
22218c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0016, 0x012f);
22228c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd141, 0x0124);
22238c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x000a, 0x0127);
22248c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x0130);
22258c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x82a8, 0x0124);
22268c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0014, 0x012d);
22278c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0008, 0x012f);
22288c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd145, 0x0124);
22298c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x012e);
22308c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x001a, 0x0130);
22318c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x8a0a, 0x0124);
22328c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x005a, 0x012d);
22338c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x9545, 0x0124);
22348c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x0127);
22358c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0018, 0x012e);
22368c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0043, 0x0130);
22378c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x8a28, 0x0124);
22388c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x012f);
22398c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd055, 0x0124);
22408c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x001c, 0x0127);
22418c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00eb, 0x012e);
22428c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xaa28, 0x0124);
22438c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
22448c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0032, 0x012f);
22458c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd141, 0x0124);
22468c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0127);
22478c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x0130);
22488c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x82a8, 0x0124);
22498c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0036, 0x012d);
22508c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0008, 0x012f);
22518c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd145, 0x0124);
22528c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xfffa, 0x0124);
22538c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
22548c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x001e, 0x012f);
22558c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd141, 0x0124);
22568c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0017, 0x0127);
22578c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0013, 0x012e);
22588c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0031, 0x0130);
22598c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x8a28, 0x0124);
22608c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0017, 0x012d);
22618c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0078, 0x012f);
22628c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd145, 0x0124);
22638c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0127);
22648c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xfea8, 0x0124);
22658c2ecf20Sopenharmony_ci		sd->sof_len = 2;
22668c2ecf20Sopenharmony_ci		break;
22678c2ecf20Sopenharmony_ci	case 160: /* 160x120 */
22688c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0038, 0x0119);
22698c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00d0, 0x0111);
22708c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00b9, 0x010a);
22718c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0001, 0x0102);
22728c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0028, 0x0103);
22738c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0104);
22748c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x001e, 0x0105);
22758c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
22768c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0016, 0x012f);
22778c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd141, 0x0124);
22788c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x000b, 0x0127);
22798c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x0130);
22808c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x82a8, 0x0124);
22818c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0014, 0x012d);
22828c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0008, 0x012f);
22838c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd145, 0x0124);
22848c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x012e);
22858c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x001a, 0x0130);
22868c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x8a0a, 0x0124);
22878c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x005a, 0x012d);
22888c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x9545, 0x0124);
22898c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x0127);
22908c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0018, 0x012e);
22918c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0043, 0x0130);
22928c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x8a28, 0x0124);
22938c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x012f);
22948c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd055, 0x0124);
22958c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x001c, 0x0127);
22968c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00c7, 0x012e);
22978c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xaa28, 0x0124);
22988c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
22998c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0032, 0x012f);
23008c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd141, 0x0124);
23018c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0025, 0x0127);
23028c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x0130);
23038c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x82a8, 0x0124);
23048c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0036, 0x012d);
23058c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0008, 0x012f);
23068c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd145, 0x0124);
23078c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xfffa, 0x0124);
23088c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
23098c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x001e, 0x012f);
23108c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd141, 0x0124);
23118c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0048, 0x0127);
23128c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0035, 0x012e);
23138c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00d0, 0x0130);
23148c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x8a28, 0x0124);
23158c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0048, 0x012d);
23168c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0090, 0x012f);
23178c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd145, 0x0124);
23188c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0001, 0x0127);
23198c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xfea8, 0x0124);
23208c2ecf20Sopenharmony_ci		sd->sof_len = 2;
23218c2ecf20Sopenharmony_ci		break;
23228c2ecf20Sopenharmony_ci	case 176: /* 176x144 */
23238c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0038, 0x0119);
23248c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00d0, 0x0111);
23258c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00b9, 0x010a);
23268c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0001, 0x0102);
23278c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x002c, 0x0103);
23288c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0104);
23298c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0024, 0x0105);
23308c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
23318c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0016, 0x012f);
23328c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd141, 0x0124);
23338c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0007, 0x0127);
23348c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x0130);
23358c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x82a8, 0x0124);
23368c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0014, 0x012d);
23378c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0001, 0x012f);
23388c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd145, 0x0124);
23398c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x012e);
23408c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x001a, 0x0130);
23418c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x8a0a, 0x0124);
23428c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x005e, 0x012d);
23438c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x9545, 0x0124);
23448c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x0127);
23458c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0018, 0x012e);
23468c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0049, 0x0130);
23478c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x8a28, 0x0124);
23488c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x012f);
23498c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd055, 0x0124);
23508c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x001c, 0x0127);
23518c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00c7, 0x012e);
23528c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xaa28, 0x0124);
23538c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
23548c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0032, 0x012f);
23558c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd141, 0x0124);
23568c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0028, 0x0127);
23578c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x0130);
23588c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x82a8, 0x0124);
23598c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0036, 0x012d);
23608c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0008, 0x012f);
23618c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd145, 0x0124);
23628c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xfffa, 0x0124);
23638c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
23648c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x001e, 0x012f);
23658c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd141, 0x0124);
23668c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0010, 0x0127);
23678c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0013, 0x012e);
23688c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x002a, 0x0130);
23698c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x8a28, 0x0124);
23708c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0010, 0x012d);
23718c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x006d, 0x012f);
23728c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd145, 0x0124);
23738c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0001, 0x0127);
23748c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xfea8, 0x0124);
23758c2ecf20Sopenharmony_ci		/* TESTME HDG: this does not seem right
23768c2ecf20Sopenharmony_ci		   (it is 2 for all other resolutions) */
23778c2ecf20Sopenharmony_ci		sd->sof_len = 10;
23788c2ecf20Sopenharmony_ci		break;
23798c2ecf20Sopenharmony_ci	case 320: /* 320x240 */
23808c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0070, 0x0119);
23818c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00d0, 0x0111);
23828c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0039, 0x010a);
23838c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0001, 0x0102);
23848c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0028, 0x0103);
23858c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0104);
23868c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x001e, 0x0105);
23878c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
23888c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0016, 0x012f);
23898c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd141, 0x0124);
23908c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x000a, 0x0127);
23918c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x0130);
23928c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x82a8, 0x0124);
23938c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0014, 0x012d);
23948c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0008, 0x012f);
23958c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd145, 0x0124);
23968c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x012e);
23978c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x001a, 0x0130);
23988c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x8a0a, 0x0124);
23998c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x005a, 0x012d);
24008c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x9545, 0x0124);
24018c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x0127);
24028c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0018, 0x012e);
24038c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0043, 0x0130);
24048c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x8a28, 0x0124);
24058c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x012f);
24068c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd055, 0x0124);
24078c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x001c, 0x0127);
24088c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00eb, 0x012e);
24098c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xaa28, 0x0124);
24108c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
24118c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0032, 0x012f);
24128c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd141, 0x0124);
24138c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0127);
24148c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x0130);
24158c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x82a8, 0x0124);
24168c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0036, 0x012d);
24178c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0008, 0x012f);
24188c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd145, 0x0124);
24198c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xfffa, 0x0124);
24208c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
24218c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x001e, 0x012f);
24228c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd141, 0x0124);
24238c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0017, 0x0127);
24248c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0013, 0x012e);
24258c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0031, 0x0130);
24268c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x8a28, 0x0124);
24278c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0017, 0x012d);
24288c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0078, 0x012f);
24298c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd145, 0x0124);
24308c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0127);
24318c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xfea8, 0x0124);
24328c2ecf20Sopenharmony_ci		sd->sof_len = 2;
24338c2ecf20Sopenharmony_ci		break;
24348c2ecf20Sopenharmony_ci	case 352: /* 352x288 */
24358c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0070, 0x0119);
24368c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00c0, 0x0111);
24378c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0039, 0x010a);
24388c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0001, 0x0102);
24398c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x002c, 0x0103);
24408c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0104);
24418c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0024, 0x0105);
24428c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
24438c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0016, 0x012f);
24448c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd141, 0x0124);
24458c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0006, 0x0127);
24468c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x0130);
24478c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x82a8, 0x0124);
24488c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0014, 0x012d);
24498c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0002, 0x012f);
24508c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd145, 0x0124);
24518c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x012e);
24528c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x001a, 0x0130);
24538c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x8a0a, 0x0124);
24548c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x005e, 0x012d);
24558c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x9545, 0x0124);
24568c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x0127);
24578c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0018, 0x012e);
24588c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0049, 0x0130);
24598c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x8a28, 0x0124);
24608c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x012f);
24618c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd055, 0x0124);
24628c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x001c, 0x0127);
24638c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00cf, 0x012e);
24648c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xaa28, 0x0124);
24658c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
24668c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0032, 0x012f);
24678c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd141, 0x0124);
24688c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0127);
24698c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x0130);
24708c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x82a8, 0x0124);
24718c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0036, 0x012d);
24728c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0008, 0x012f);
24738c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd145, 0x0124);
24748c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xfffa, 0x0124);
24758c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
24768c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x001e, 0x012f);
24778c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd141, 0x0124);
24788c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0010, 0x0127);
24798c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0013, 0x012e);
24808c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0025, 0x0130);
24818c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x8a28, 0x0124);
24828c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0010, 0x012d);
24838c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0048, 0x012f);
24848c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd145, 0x0124);
24858c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0127);
24868c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0xfea8, 0x0124);
24878c2ecf20Sopenharmony_ci		sd->sof_len = 2;
24888c2ecf20Sopenharmony_ci		break;
24898c2ecf20Sopenharmony_ci	}
24908c2ecf20Sopenharmony_ci
24918c2ecf20Sopenharmony_ci	cit_model4_Packet1(gspca_dev, 0x0038, 0x0004);
24928c2ecf20Sopenharmony_ci
24938c2ecf20Sopenharmony_ci	return 0;
24948c2ecf20Sopenharmony_ci}
24958c2ecf20Sopenharmony_ci
24968c2ecf20Sopenharmony_cistatic int cit_start_ibm_netcam_pro(struct gspca_dev *gspca_dev)
24978c2ecf20Sopenharmony_ci{
24988c2ecf20Sopenharmony_ci	const unsigned short compression = 0; /* 0=none, 7=best frame rate */
24998c2ecf20Sopenharmony_ci	int i, clock_div;
25008c2ecf20Sopenharmony_ci
25018c2ecf20Sopenharmony_ci	clock_div = cit_get_clock_div(gspca_dev);
25028c2ecf20Sopenharmony_ci	if (clock_div < 0)
25038c2ecf20Sopenharmony_ci		return clock_div;
25048c2ecf20Sopenharmony_ci
25058c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0003, 0x0133);
25068c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0117);
25078c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0008, 0x0123);
25088c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0100);
25098c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0060, 0x0116);
25108c2ecf20Sopenharmony_ci	/* cit_write_reg(gspca_dev, 0x0002, 0x0112); see sd_stop0 */
25118c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0133);
25128c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0123);
25138c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0001, 0x0117);
25148c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0040, 0x0108);
25158c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0019, 0x012c);
25168c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0060, 0x0116);
25178c2ecf20Sopenharmony_ci	/* cit_write_reg(gspca_dev, 0x000b, 0x0115); see sd_stop0 */
25188c2ecf20Sopenharmony_ci
25198c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0049, 0x0000);
25208c2ecf20Sopenharmony_ci
25218c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0101); /* Same on 160x120, 320x240 */
25228c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x003a, 0x0102); /* Hstart */
25238c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x00a0, 0x0103); /* Same on 160x120, 320x240 */
25248c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0078, 0x0105); /* Same on 160x120, 320x240 */
25258c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x010a); /* Same */
25268c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0002, 0x011d); /* Same on 160x120, 320x240 */
25278c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0129); /* Same */
25288c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x00fc, 0x012b); /* Same */
25298c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0022, 0x012a); /* Same */
25308c2ecf20Sopenharmony_ci
25318c2ecf20Sopenharmony_ci	switch (gspca_dev->pixfmt.width) {
25328c2ecf20Sopenharmony_ci	case 160: /* 160x120 */
25338c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0024, 0x010b);
25348c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0089, 0x0119);
25358c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x000a, 0x011b);
25368c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0003, 0x011e);
25378c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0007, 0x0104);
25388c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0009, 0x011a);
25398c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x008b, 0x011c);
25408c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0008, 0x0118);
25418c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0132);
25428c2ecf20Sopenharmony_ci		break;
25438c2ecf20Sopenharmony_ci	case 320: /* 320x240 */
25448c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0028, 0x010b);
25458c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00d9, 0x0119);
25468c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0006, 0x011b);
25478c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x011e);
25488c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x000e, 0x0104);
25498c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0004, 0x011a);
25508c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x003f, 0x011c);
25518c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x000c, 0x0118);
25528c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0132);
25538c2ecf20Sopenharmony_ci		break;
25548c2ecf20Sopenharmony_ci	}
25558c2ecf20Sopenharmony_ci
25568c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0019, 0x0031);
25578c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x001a, 0x0003);
25588c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x001b, 0x0038);
25598c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x001c, 0x0000);
25608c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0024, 0x0001);
25618c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0027, 0x0001);
25628c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x002a, 0x0004);
25638c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0035, 0x000b);
25648c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x003f, 0x0001);
25658c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0044, 0x0000);
25668c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0054, 0x0000);
25678c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00c4, 0x0000);
25688c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00e7, 0x0001);
25698c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00e9, 0x0001);
25708c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00ee, 0x0000);
25718c2ecf20Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00f3, 0x00c0);
25728c2ecf20Sopenharmony_ci
25738c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, compression, 0x0109);
25748c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, clock_div, 0x0111);
25758c2ecf20Sopenharmony_ci
25768c2ecf20Sopenharmony_ci/*	if (sd->input_index) { */
25778c2ecf20Sopenharmony_ci	if (rca_input) {
25788c2ecf20Sopenharmony_ci		for (i = 0; i < ARRAY_SIZE(rca_initdata); i++) {
25798c2ecf20Sopenharmony_ci			if (rca_initdata[i][0])
25808c2ecf20Sopenharmony_ci				cit_read_reg(gspca_dev, rca_initdata[i][2], 0);
25818c2ecf20Sopenharmony_ci			else
25828c2ecf20Sopenharmony_ci				cit_write_reg(gspca_dev, rca_initdata[i][1],
25838c2ecf20Sopenharmony_ci					      rca_initdata[i][2]);
25848c2ecf20Sopenharmony_ci		}
25858c2ecf20Sopenharmony_ci	}
25868c2ecf20Sopenharmony_ci
25878c2ecf20Sopenharmony_ci	return 0;
25888c2ecf20Sopenharmony_ci}
25898c2ecf20Sopenharmony_ci
25908c2ecf20Sopenharmony_ci/* -- start the camera -- */
25918c2ecf20Sopenharmony_cistatic int sd_start(struct gspca_dev *gspca_dev)
25928c2ecf20Sopenharmony_ci{
25938c2ecf20Sopenharmony_ci	struct sd *sd = (struct sd *) gspca_dev;
25948c2ecf20Sopenharmony_ci	int packet_size;
25958c2ecf20Sopenharmony_ci
25968c2ecf20Sopenharmony_ci	packet_size = cit_get_packet_size(gspca_dev);
25978c2ecf20Sopenharmony_ci	if (packet_size < 0)
25988c2ecf20Sopenharmony_ci		return packet_size;
25998c2ecf20Sopenharmony_ci
26008c2ecf20Sopenharmony_ci	switch (sd->model) {
26018c2ecf20Sopenharmony_ci	case CIT_MODEL0:
26028c2ecf20Sopenharmony_ci		cit_start_model0(gspca_dev);
26038c2ecf20Sopenharmony_ci		break;
26048c2ecf20Sopenharmony_ci	case CIT_MODEL1:
26058c2ecf20Sopenharmony_ci		cit_start_model1(gspca_dev);
26068c2ecf20Sopenharmony_ci		break;
26078c2ecf20Sopenharmony_ci	case CIT_MODEL2:
26088c2ecf20Sopenharmony_ci		cit_start_model2(gspca_dev);
26098c2ecf20Sopenharmony_ci		break;
26108c2ecf20Sopenharmony_ci	case CIT_MODEL3:
26118c2ecf20Sopenharmony_ci		cit_start_model3(gspca_dev);
26128c2ecf20Sopenharmony_ci		break;
26138c2ecf20Sopenharmony_ci	case CIT_MODEL4:
26148c2ecf20Sopenharmony_ci		cit_start_model4(gspca_dev);
26158c2ecf20Sopenharmony_ci		break;
26168c2ecf20Sopenharmony_ci	case CIT_IBM_NETCAM_PRO:
26178c2ecf20Sopenharmony_ci		cit_start_ibm_netcam_pro(gspca_dev);
26188c2ecf20Sopenharmony_ci		break;
26198c2ecf20Sopenharmony_ci	}
26208c2ecf20Sopenharmony_ci
26218c2ecf20Sopenharmony_ci	/* Program max isoc packet size */
26228c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, packet_size >> 8, 0x0106);
26238c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, packet_size & 0xff, 0x0107);
26248c2ecf20Sopenharmony_ci
26258c2ecf20Sopenharmony_ci	cit_restart_stream(gspca_dev);
26268c2ecf20Sopenharmony_ci
26278c2ecf20Sopenharmony_ci	return 0;
26288c2ecf20Sopenharmony_ci}
26298c2ecf20Sopenharmony_ci
26308c2ecf20Sopenharmony_cistatic int sd_isoc_init(struct gspca_dev *gspca_dev)
26318c2ecf20Sopenharmony_ci{
26328c2ecf20Sopenharmony_ci	struct usb_interface_cache *intfc;
26338c2ecf20Sopenharmony_ci	struct usb_host_interface *alt;
26348c2ecf20Sopenharmony_ci	int max_packet_size;
26358c2ecf20Sopenharmony_ci
26368c2ecf20Sopenharmony_ci	switch (gspca_dev->pixfmt.width) {
26378c2ecf20Sopenharmony_ci	case 160:
26388c2ecf20Sopenharmony_ci		max_packet_size = 450;
26398c2ecf20Sopenharmony_ci		break;
26408c2ecf20Sopenharmony_ci	case 176:
26418c2ecf20Sopenharmony_ci		max_packet_size = 600;
26428c2ecf20Sopenharmony_ci		break;
26438c2ecf20Sopenharmony_ci	default:
26448c2ecf20Sopenharmony_ci		max_packet_size = 1022;
26458c2ecf20Sopenharmony_ci		break;
26468c2ecf20Sopenharmony_ci	}
26478c2ecf20Sopenharmony_ci
26488c2ecf20Sopenharmony_ci	intfc = gspca_dev->dev->actconfig->intf_cache[0];
26498c2ecf20Sopenharmony_ci
26508c2ecf20Sopenharmony_ci	if (intfc->num_altsetting < 2)
26518c2ecf20Sopenharmony_ci		return -ENODEV;
26528c2ecf20Sopenharmony_ci
26538c2ecf20Sopenharmony_ci	alt = &intfc->altsetting[1];
26548c2ecf20Sopenharmony_ci
26558c2ecf20Sopenharmony_ci	if (alt->desc.bNumEndpoints < 1)
26568c2ecf20Sopenharmony_ci		return -ENODEV;
26578c2ecf20Sopenharmony_ci
26588c2ecf20Sopenharmony_ci	/* Start isoc bandwidth "negotiation" at max isoc bandwidth */
26598c2ecf20Sopenharmony_ci	alt->endpoint[0].desc.wMaxPacketSize = cpu_to_le16(max_packet_size);
26608c2ecf20Sopenharmony_ci
26618c2ecf20Sopenharmony_ci	return 0;
26628c2ecf20Sopenharmony_ci}
26638c2ecf20Sopenharmony_ci
26648c2ecf20Sopenharmony_cistatic int sd_isoc_nego(struct gspca_dev *gspca_dev)
26658c2ecf20Sopenharmony_ci{
26668c2ecf20Sopenharmony_ci	int ret, packet_size, min_packet_size;
26678c2ecf20Sopenharmony_ci	struct usb_host_interface *alt;
26688c2ecf20Sopenharmony_ci
26698c2ecf20Sopenharmony_ci	switch (gspca_dev->pixfmt.width) {
26708c2ecf20Sopenharmony_ci	case 160:
26718c2ecf20Sopenharmony_ci		min_packet_size = 200;
26728c2ecf20Sopenharmony_ci		break;
26738c2ecf20Sopenharmony_ci	case 176:
26748c2ecf20Sopenharmony_ci		min_packet_size = 266;
26758c2ecf20Sopenharmony_ci		break;
26768c2ecf20Sopenharmony_ci	default:
26778c2ecf20Sopenharmony_ci		min_packet_size = 400;
26788c2ecf20Sopenharmony_ci		break;
26798c2ecf20Sopenharmony_ci	}
26808c2ecf20Sopenharmony_ci
26818c2ecf20Sopenharmony_ci	/*
26828c2ecf20Sopenharmony_ci	 * Existence of altsetting and endpoint was verified in sd_isoc_init()
26838c2ecf20Sopenharmony_ci	 */
26848c2ecf20Sopenharmony_ci	alt = &gspca_dev->dev->actconfig->intf_cache[0]->altsetting[1];
26858c2ecf20Sopenharmony_ci	packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
26868c2ecf20Sopenharmony_ci	if (packet_size <= min_packet_size)
26878c2ecf20Sopenharmony_ci		return -EIO;
26888c2ecf20Sopenharmony_ci
26898c2ecf20Sopenharmony_ci	packet_size -= 100;
26908c2ecf20Sopenharmony_ci	if (packet_size < min_packet_size)
26918c2ecf20Sopenharmony_ci		packet_size = min_packet_size;
26928c2ecf20Sopenharmony_ci	alt->endpoint[0].desc.wMaxPacketSize = cpu_to_le16(packet_size);
26938c2ecf20Sopenharmony_ci
26948c2ecf20Sopenharmony_ci	ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1);
26958c2ecf20Sopenharmony_ci	if (ret < 0)
26968c2ecf20Sopenharmony_ci		pr_err("set alt 1 err %d\n", ret);
26978c2ecf20Sopenharmony_ci
26988c2ecf20Sopenharmony_ci	return ret;
26998c2ecf20Sopenharmony_ci}
27008c2ecf20Sopenharmony_ci
27018c2ecf20Sopenharmony_cistatic void sd_stopN(struct gspca_dev *gspca_dev)
27028c2ecf20Sopenharmony_ci{
27038c2ecf20Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x010c);
27048c2ecf20Sopenharmony_ci}
27058c2ecf20Sopenharmony_ci
27068c2ecf20Sopenharmony_cistatic void sd_stop0(struct gspca_dev *gspca_dev)
27078c2ecf20Sopenharmony_ci{
27088c2ecf20Sopenharmony_ci	struct sd *sd = (struct sd *) gspca_dev;
27098c2ecf20Sopenharmony_ci
27108c2ecf20Sopenharmony_ci	if (!gspca_dev->present)
27118c2ecf20Sopenharmony_ci		return;
27128c2ecf20Sopenharmony_ci
27138c2ecf20Sopenharmony_ci	switch (sd->model) {
27148c2ecf20Sopenharmony_ci	case CIT_MODEL0:
27158c2ecf20Sopenharmony_ci		/* HDG windows does this, but it causes the cams autogain to
27168c2ecf20Sopenharmony_ci		   restart from a gain of 0, which does not look good when
27178c2ecf20Sopenharmony_ci		   changing resolutions. */
27188c2ecf20Sopenharmony_ci		/* cit_write_reg(gspca_dev, 0x0000, 0x0112); */
27198c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00c0, 0x0100); /* LED Off */
27208c2ecf20Sopenharmony_ci		break;
27218c2ecf20Sopenharmony_ci	case CIT_MODEL1:
27228c2ecf20Sopenharmony_ci		cit_send_FF_04_02(gspca_dev);
27238c2ecf20Sopenharmony_ci		cit_read_reg(gspca_dev, 0x0100, 0);
27248c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x81, 0x0100);	/* LED Off */
27258c2ecf20Sopenharmony_ci		break;
27268c2ecf20Sopenharmony_ci	case CIT_MODEL2:
27278c2ecf20Sopenharmony_ci		v4l2_ctrl_grab(sd->lighting, false);
27288c2ecf20Sopenharmony_ci		fallthrough;
27298c2ecf20Sopenharmony_ci	case CIT_MODEL4:
27308c2ecf20Sopenharmony_ci		cit_model2_Packet1(gspca_dev, 0x0030, 0x0004);
27318c2ecf20Sopenharmony_ci
27328c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0080, 0x0100);	/* LED Off */
27338c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0020, 0x0111);
27348c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00a0, 0x0111);
27358c2ecf20Sopenharmony_ci
27368c2ecf20Sopenharmony_ci		cit_model2_Packet1(gspca_dev, 0x0030, 0x0002);
27378c2ecf20Sopenharmony_ci
27388c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0020, 0x0111);
27398c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0112);
27408c2ecf20Sopenharmony_ci		break;
27418c2ecf20Sopenharmony_ci	case CIT_MODEL3:
27428c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0006, 0x012c);
27438c2ecf20Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x0046, 0x0000);
27448c2ecf20Sopenharmony_ci		cit_read_reg(gspca_dev, 0x0116, 0);
27458c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0064, 0x0116);
27468c2ecf20Sopenharmony_ci		cit_read_reg(gspca_dev, 0x0115, 0);
27478c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0003, 0x0115);
27488c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0008, 0x0123);
27498c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0117);
27508c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0112);
27518c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0080, 0x0100);
27528c2ecf20Sopenharmony_ci		break;
27538c2ecf20Sopenharmony_ci	case CIT_IBM_NETCAM_PRO:
27548c2ecf20Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x0049, 0x00ff);
27558c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0006, 0x012c);
27568c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0116);
27578c2ecf20Sopenharmony_ci		/* HDG windows does this, but I cannot get the camera
27588c2ecf20Sopenharmony_ci		   to restart with this without redoing the entire init
27598c2ecf20Sopenharmony_ci		   sequence which makes switching modes really slow */
27608c2ecf20Sopenharmony_ci		/* cit_write_reg(gspca_dev, 0x0006, 0x0115); */
27618c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0008, 0x0123);
27628c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0117);
27638c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0003, 0x0133);
27648c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0111);
27658c2ecf20Sopenharmony_ci		/* HDG windows does this, but I get a green picture when
27668c2ecf20Sopenharmony_ci		   restarting the stream after this */
27678c2ecf20Sopenharmony_ci		/* cit_write_reg(gspca_dev, 0x0000, 0x0112); */
27688c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00c0, 0x0100);
27698c2ecf20Sopenharmony_ci		break;
27708c2ecf20Sopenharmony_ci	}
27718c2ecf20Sopenharmony_ci
27728c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_INPUT)
27738c2ecf20Sopenharmony_ci	/* If the last button state is pressed, release it now! */
27748c2ecf20Sopenharmony_ci	if (sd->button_state) {
27758c2ecf20Sopenharmony_ci		input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
27768c2ecf20Sopenharmony_ci		input_sync(gspca_dev->input_dev);
27778c2ecf20Sopenharmony_ci		sd->button_state = 0;
27788c2ecf20Sopenharmony_ci	}
27798c2ecf20Sopenharmony_ci#endif
27808c2ecf20Sopenharmony_ci}
27818c2ecf20Sopenharmony_ci
27828c2ecf20Sopenharmony_cistatic u8 *cit_find_sof(struct gspca_dev *gspca_dev, u8 *data, int len)
27838c2ecf20Sopenharmony_ci{
27848c2ecf20Sopenharmony_ci	struct sd *sd = (struct sd *) gspca_dev;
27858c2ecf20Sopenharmony_ci	u8 byte3 = 0, byte4 = 0;
27868c2ecf20Sopenharmony_ci	int i;
27878c2ecf20Sopenharmony_ci
27888c2ecf20Sopenharmony_ci	switch (sd->model) {
27898c2ecf20Sopenharmony_ci	case CIT_MODEL0:
27908c2ecf20Sopenharmony_ci	case CIT_MODEL1:
27918c2ecf20Sopenharmony_ci	case CIT_MODEL3:
27928c2ecf20Sopenharmony_ci	case CIT_IBM_NETCAM_PRO:
27938c2ecf20Sopenharmony_ci		switch (gspca_dev->pixfmt.width) {
27948c2ecf20Sopenharmony_ci		case 160: /* 160x120 */
27958c2ecf20Sopenharmony_ci			byte3 = 0x02;
27968c2ecf20Sopenharmony_ci			byte4 = 0x0a;
27978c2ecf20Sopenharmony_ci			break;
27988c2ecf20Sopenharmony_ci		case 176: /* 176x144 */
27998c2ecf20Sopenharmony_ci			byte3 = 0x02;
28008c2ecf20Sopenharmony_ci			byte4 = 0x0e;
28018c2ecf20Sopenharmony_ci			break;
28028c2ecf20Sopenharmony_ci		case 320: /* 320x240 */
28038c2ecf20Sopenharmony_ci			byte3 = 0x02;
28048c2ecf20Sopenharmony_ci			byte4 = 0x08;
28058c2ecf20Sopenharmony_ci			break;
28068c2ecf20Sopenharmony_ci		case 352: /* 352x288 */
28078c2ecf20Sopenharmony_ci			byte3 = 0x02;
28088c2ecf20Sopenharmony_ci			byte4 = 0x00;
28098c2ecf20Sopenharmony_ci			break;
28108c2ecf20Sopenharmony_ci		case 640:
28118c2ecf20Sopenharmony_ci			byte3 = 0x03;
28128c2ecf20Sopenharmony_ci			byte4 = 0x08;
28138c2ecf20Sopenharmony_ci			break;
28148c2ecf20Sopenharmony_ci		}
28158c2ecf20Sopenharmony_ci
28168c2ecf20Sopenharmony_ci		/* These have a different byte3 */
28178c2ecf20Sopenharmony_ci		if (sd->model <= CIT_MODEL1)
28188c2ecf20Sopenharmony_ci			byte3 = 0x00;
28198c2ecf20Sopenharmony_ci
28208c2ecf20Sopenharmony_ci		for (i = 0; i < len; i++) {
28218c2ecf20Sopenharmony_ci			/* For this model the SOF always starts at offset 0
28228c2ecf20Sopenharmony_ci			   so no need to search the entire frame */
28238c2ecf20Sopenharmony_ci			if (sd->model == CIT_MODEL0 && sd->sof_read != i)
28248c2ecf20Sopenharmony_ci				break;
28258c2ecf20Sopenharmony_ci
28268c2ecf20Sopenharmony_ci			switch (sd->sof_read) {
28278c2ecf20Sopenharmony_ci			case 0:
28288c2ecf20Sopenharmony_ci				if (data[i] == 0x00)
28298c2ecf20Sopenharmony_ci					sd->sof_read++;
28308c2ecf20Sopenharmony_ci				break;
28318c2ecf20Sopenharmony_ci			case 1:
28328c2ecf20Sopenharmony_ci				if (data[i] == 0xff)
28338c2ecf20Sopenharmony_ci					sd->sof_read++;
28348c2ecf20Sopenharmony_ci				else if (data[i] == 0x00)
28358c2ecf20Sopenharmony_ci					sd->sof_read = 1;
28368c2ecf20Sopenharmony_ci				else
28378c2ecf20Sopenharmony_ci					sd->sof_read = 0;
28388c2ecf20Sopenharmony_ci				break;
28398c2ecf20Sopenharmony_ci			case 2:
28408c2ecf20Sopenharmony_ci				if (data[i] == byte3)
28418c2ecf20Sopenharmony_ci					sd->sof_read++;
28428c2ecf20Sopenharmony_ci				else if (data[i] == 0x00)
28438c2ecf20Sopenharmony_ci					sd->sof_read = 1;
28448c2ecf20Sopenharmony_ci				else
28458c2ecf20Sopenharmony_ci					sd->sof_read = 0;
28468c2ecf20Sopenharmony_ci				break;
28478c2ecf20Sopenharmony_ci			case 3:
28488c2ecf20Sopenharmony_ci				if (data[i] == byte4) {
28498c2ecf20Sopenharmony_ci					sd->sof_read = 0;
28508c2ecf20Sopenharmony_ci					return data + i + (sd->sof_len - 3);
28518c2ecf20Sopenharmony_ci				}
28528c2ecf20Sopenharmony_ci				if (byte3 == 0x00 && data[i] == 0xff)
28538c2ecf20Sopenharmony_ci					sd->sof_read = 2;
28548c2ecf20Sopenharmony_ci				else if (data[i] == 0x00)
28558c2ecf20Sopenharmony_ci					sd->sof_read = 1;
28568c2ecf20Sopenharmony_ci				else
28578c2ecf20Sopenharmony_ci					sd->sof_read = 0;
28588c2ecf20Sopenharmony_ci				break;
28598c2ecf20Sopenharmony_ci			}
28608c2ecf20Sopenharmony_ci		}
28618c2ecf20Sopenharmony_ci		break;
28628c2ecf20Sopenharmony_ci	case CIT_MODEL2:
28638c2ecf20Sopenharmony_ci	case CIT_MODEL4:
28648c2ecf20Sopenharmony_ci		/* TESTME we need to find a longer sof signature to avoid
28658c2ecf20Sopenharmony_ci		   false positives */
28668c2ecf20Sopenharmony_ci		for (i = 0; i < len; i++) {
28678c2ecf20Sopenharmony_ci			switch (sd->sof_read) {
28688c2ecf20Sopenharmony_ci			case 0:
28698c2ecf20Sopenharmony_ci				if (data[i] == 0x00)
28708c2ecf20Sopenharmony_ci					sd->sof_read++;
28718c2ecf20Sopenharmony_ci				break;
28728c2ecf20Sopenharmony_ci			case 1:
28738c2ecf20Sopenharmony_ci				sd->sof_read = 0;
28748c2ecf20Sopenharmony_ci				if (data[i] == 0xff) {
28758c2ecf20Sopenharmony_ci					if (i >= 4)
28768c2ecf20Sopenharmony_ci						gspca_dbg(gspca_dev, D_FRAM,
28778c2ecf20Sopenharmony_ci							  "header found at offset: %d: %02x %02x 00 %3ph\n\n",
28788c2ecf20Sopenharmony_ci							  i - 1,
28798c2ecf20Sopenharmony_ci							  data[i - 4],
28808c2ecf20Sopenharmony_ci							  data[i - 3],
28818c2ecf20Sopenharmony_ci							  &data[i]);
28828c2ecf20Sopenharmony_ci					else
28838c2ecf20Sopenharmony_ci						gspca_dbg(gspca_dev, D_FRAM,
28848c2ecf20Sopenharmony_ci							  "header found at offset: %d: 00 %3ph\n\n",
28858c2ecf20Sopenharmony_ci							  i - 1,
28868c2ecf20Sopenharmony_ci							  &data[i]);
28878c2ecf20Sopenharmony_ci					return data + i + (sd->sof_len - 1);
28888c2ecf20Sopenharmony_ci				}
28898c2ecf20Sopenharmony_ci				break;
28908c2ecf20Sopenharmony_ci			}
28918c2ecf20Sopenharmony_ci		}
28928c2ecf20Sopenharmony_ci		break;
28938c2ecf20Sopenharmony_ci	}
28948c2ecf20Sopenharmony_ci	return NULL;
28958c2ecf20Sopenharmony_ci}
28968c2ecf20Sopenharmony_ci
28978c2ecf20Sopenharmony_cistatic void sd_pkt_scan(struct gspca_dev *gspca_dev,
28988c2ecf20Sopenharmony_ci			u8 *data, int len)
28998c2ecf20Sopenharmony_ci{
29008c2ecf20Sopenharmony_ci	struct sd *sd = (struct sd *) gspca_dev;
29018c2ecf20Sopenharmony_ci	unsigned char *sof;
29028c2ecf20Sopenharmony_ci
29038c2ecf20Sopenharmony_ci	sof = cit_find_sof(gspca_dev, data, len);
29048c2ecf20Sopenharmony_ci	if (sof) {
29058c2ecf20Sopenharmony_ci		int n;
29068c2ecf20Sopenharmony_ci
29078c2ecf20Sopenharmony_ci		/* finish decoding current frame */
29088c2ecf20Sopenharmony_ci		n = sof - data;
29098c2ecf20Sopenharmony_ci		if (n > sd->sof_len)
29108c2ecf20Sopenharmony_ci			n -= sd->sof_len;
29118c2ecf20Sopenharmony_ci		else
29128c2ecf20Sopenharmony_ci			n = 0;
29138c2ecf20Sopenharmony_ci		gspca_frame_add(gspca_dev, LAST_PACKET,
29148c2ecf20Sopenharmony_ci				data, n);
29158c2ecf20Sopenharmony_ci		gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
29168c2ecf20Sopenharmony_ci		len -= sof - data;
29178c2ecf20Sopenharmony_ci		data = sof;
29188c2ecf20Sopenharmony_ci	}
29198c2ecf20Sopenharmony_ci
29208c2ecf20Sopenharmony_ci	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
29218c2ecf20Sopenharmony_ci}
29228c2ecf20Sopenharmony_ci
29238c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_INPUT)
29248c2ecf20Sopenharmony_cistatic void cit_check_button(struct gspca_dev *gspca_dev)
29258c2ecf20Sopenharmony_ci{
29268c2ecf20Sopenharmony_ci	int new_button_state;
29278c2ecf20Sopenharmony_ci	struct sd *sd = (struct sd *)gspca_dev;
29288c2ecf20Sopenharmony_ci
29298c2ecf20Sopenharmony_ci	switch (sd->model) {
29308c2ecf20Sopenharmony_ci	case CIT_MODEL3:
29318c2ecf20Sopenharmony_ci	case CIT_IBM_NETCAM_PRO:
29328c2ecf20Sopenharmony_ci		break;
29338c2ecf20Sopenharmony_ci	default: /* TEST ME unknown if this works on other models too */
29348c2ecf20Sopenharmony_ci		return;
29358c2ecf20Sopenharmony_ci	}
29368c2ecf20Sopenharmony_ci
29378c2ecf20Sopenharmony_ci	/* Read the button state */
29388c2ecf20Sopenharmony_ci	cit_read_reg(gspca_dev, 0x0113, 0);
29398c2ecf20Sopenharmony_ci	new_button_state = !gspca_dev->usb_buf[0];
29408c2ecf20Sopenharmony_ci
29418c2ecf20Sopenharmony_ci	/* Tell the cam we've seen the button press, notice that this
29428c2ecf20Sopenharmony_ci	   is a nop (iow the cam keeps reporting pressed) until the
29438c2ecf20Sopenharmony_ci	   button is actually released. */
29448c2ecf20Sopenharmony_ci	if (new_button_state)
29458c2ecf20Sopenharmony_ci		cit_write_reg(gspca_dev, 0x01, 0x0113);
29468c2ecf20Sopenharmony_ci
29478c2ecf20Sopenharmony_ci	if (sd->button_state != new_button_state) {
29488c2ecf20Sopenharmony_ci		input_report_key(gspca_dev->input_dev, KEY_CAMERA,
29498c2ecf20Sopenharmony_ci				 new_button_state);
29508c2ecf20Sopenharmony_ci		input_sync(gspca_dev->input_dev);
29518c2ecf20Sopenharmony_ci		sd->button_state = new_button_state;
29528c2ecf20Sopenharmony_ci	}
29538c2ecf20Sopenharmony_ci}
29548c2ecf20Sopenharmony_ci#endif
29558c2ecf20Sopenharmony_ci
29568c2ecf20Sopenharmony_cistatic int sd_s_ctrl(struct v4l2_ctrl *ctrl)
29578c2ecf20Sopenharmony_ci{
29588c2ecf20Sopenharmony_ci	struct gspca_dev *gspca_dev =
29598c2ecf20Sopenharmony_ci		container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
29608c2ecf20Sopenharmony_ci	struct sd *sd = (struct sd *)gspca_dev;
29618c2ecf20Sopenharmony_ci
29628c2ecf20Sopenharmony_ci	gspca_dev->usb_err = 0;
29638c2ecf20Sopenharmony_ci
29648c2ecf20Sopenharmony_ci	if (!gspca_dev->streaming)
29658c2ecf20Sopenharmony_ci		return 0;
29668c2ecf20Sopenharmony_ci
29678c2ecf20Sopenharmony_ci	if (sd->stop_on_control_change)
29688c2ecf20Sopenharmony_ci		sd_stopN(gspca_dev);
29698c2ecf20Sopenharmony_ci	switch (ctrl->id) {
29708c2ecf20Sopenharmony_ci	case V4L2_CID_BRIGHTNESS:
29718c2ecf20Sopenharmony_ci		cit_set_brightness(gspca_dev, ctrl->val);
29728c2ecf20Sopenharmony_ci		break;
29738c2ecf20Sopenharmony_ci	case V4L2_CID_CONTRAST:
29748c2ecf20Sopenharmony_ci		cit_set_contrast(gspca_dev, ctrl->val);
29758c2ecf20Sopenharmony_ci		break;
29768c2ecf20Sopenharmony_ci	case V4L2_CID_HUE:
29778c2ecf20Sopenharmony_ci		cit_set_hue(gspca_dev, ctrl->val);
29788c2ecf20Sopenharmony_ci		break;
29798c2ecf20Sopenharmony_ci	case V4L2_CID_HFLIP:
29808c2ecf20Sopenharmony_ci		cit_set_hflip(gspca_dev, ctrl->val);
29818c2ecf20Sopenharmony_ci		break;
29828c2ecf20Sopenharmony_ci	case V4L2_CID_SHARPNESS:
29838c2ecf20Sopenharmony_ci		cit_set_sharpness(gspca_dev, ctrl->val);
29848c2ecf20Sopenharmony_ci		break;
29858c2ecf20Sopenharmony_ci	case V4L2_CID_BACKLIGHT_COMPENSATION:
29868c2ecf20Sopenharmony_ci		cit_set_lighting(gspca_dev, ctrl->val);
29878c2ecf20Sopenharmony_ci		break;
29888c2ecf20Sopenharmony_ci	}
29898c2ecf20Sopenharmony_ci	if (sd->stop_on_control_change)
29908c2ecf20Sopenharmony_ci		cit_restart_stream(gspca_dev);
29918c2ecf20Sopenharmony_ci	return gspca_dev->usb_err;
29928c2ecf20Sopenharmony_ci}
29938c2ecf20Sopenharmony_ci
29948c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_ops sd_ctrl_ops = {
29958c2ecf20Sopenharmony_ci	.s_ctrl = sd_s_ctrl,
29968c2ecf20Sopenharmony_ci};
29978c2ecf20Sopenharmony_ci
29988c2ecf20Sopenharmony_cistatic int sd_init_controls(struct gspca_dev *gspca_dev)
29998c2ecf20Sopenharmony_ci{
30008c2ecf20Sopenharmony_ci	struct sd *sd = (struct sd *)gspca_dev;
30018c2ecf20Sopenharmony_ci	struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
30028c2ecf20Sopenharmony_ci	bool has_brightness;
30038c2ecf20Sopenharmony_ci	bool has_contrast;
30048c2ecf20Sopenharmony_ci	bool has_hue;
30058c2ecf20Sopenharmony_ci	bool has_sharpness;
30068c2ecf20Sopenharmony_ci	bool has_lighting;
30078c2ecf20Sopenharmony_ci	bool has_hflip;
30088c2ecf20Sopenharmony_ci
30098c2ecf20Sopenharmony_ci	has_brightness = has_contrast = has_hue =
30108c2ecf20Sopenharmony_ci		has_sharpness = has_hflip = has_lighting = false;
30118c2ecf20Sopenharmony_ci	switch (sd->model) {
30128c2ecf20Sopenharmony_ci	case CIT_MODEL0:
30138c2ecf20Sopenharmony_ci		has_contrast = has_hflip = true;
30148c2ecf20Sopenharmony_ci		break;
30158c2ecf20Sopenharmony_ci	case CIT_MODEL1:
30168c2ecf20Sopenharmony_ci		has_brightness = has_contrast =
30178c2ecf20Sopenharmony_ci			has_sharpness = has_lighting = true;
30188c2ecf20Sopenharmony_ci		break;
30198c2ecf20Sopenharmony_ci	case CIT_MODEL2:
30208c2ecf20Sopenharmony_ci		has_brightness = has_hue = has_lighting = true;
30218c2ecf20Sopenharmony_ci		break;
30228c2ecf20Sopenharmony_ci	case CIT_MODEL3:
30238c2ecf20Sopenharmony_ci		has_brightness = has_contrast = has_sharpness = true;
30248c2ecf20Sopenharmony_ci		break;
30258c2ecf20Sopenharmony_ci	case CIT_MODEL4:
30268c2ecf20Sopenharmony_ci		has_brightness = has_hue = true;
30278c2ecf20Sopenharmony_ci		break;
30288c2ecf20Sopenharmony_ci	case CIT_IBM_NETCAM_PRO:
30298c2ecf20Sopenharmony_ci		has_brightness = has_hue =
30308c2ecf20Sopenharmony_ci			has_sharpness = has_hflip = has_lighting = true;
30318c2ecf20Sopenharmony_ci		break;
30328c2ecf20Sopenharmony_ci	}
30338c2ecf20Sopenharmony_ci	gspca_dev->vdev.ctrl_handler = hdl;
30348c2ecf20Sopenharmony_ci	v4l2_ctrl_handler_init(hdl, 5);
30358c2ecf20Sopenharmony_ci	if (has_brightness)
30368c2ecf20Sopenharmony_ci		v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
30378c2ecf20Sopenharmony_ci			V4L2_CID_BRIGHTNESS, 0, 63, 1, 32);
30388c2ecf20Sopenharmony_ci	if (has_contrast)
30398c2ecf20Sopenharmony_ci		v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
30408c2ecf20Sopenharmony_ci			V4L2_CID_CONTRAST, 0, 20, 1, 10);
30418c2ecf20Sopenharmony_ci	if (has_hue)
30428c2ecf20Sopenharmony_ci		v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
30438c2ecf20Sopenharmony_ci			V4L2_CID_HUE, 0, 127, 1, 63);
30448c2ecf20Sopenharmony_ci	if (has_sharpness)
30458c2ecf20Sopenharmony_ci		v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
30468c2ecf20Sopenharmony_ci			V4L2_CID_SHARPNESS, 0, 6, 1, 3);
30478c2ecf20Sopenharmony_ci	if (has_lighting)
30488c2ecf20Sopenharmony_ci		sd->lighting = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
30498c2ecf20Sopenharmony_ci			V4L2_CID_BACKLIGHT_COMPENSATION, 0, 2, 1, 1);
30508c2ecf20Sopenharmony_ci	if (has_hflip)
30518c2ecf20Sopenharmony_ci		v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
30528c2ecf20Sopenharmony_ci			V4L2_CID_HFLIP, 0, 1, 1, 0);
30538c2ecf20Sopenharmony_ci
30548c2ecf20Sopenharmony_ci	if (hdl->error) {
30558c2ecf20Sopenharmony_ci		pr_err("Could not initialize controls\n");
30568c2ecf20Sopenharmony_ci		return hdl->error;
30578c2ecf20Sopenharmony_ci	}
30588c2ecf20Sopenharmony_ci	return 0;
30598c2ecf20Sopenharmony_ci}
30608c2ecf20Sopenharmony_ci
30618c2ecf20Sopenharmony_ci/* sub-driver description */
30628c2ecf20Sopenharmony_cistatic const struct sd_desc sd_desc = {
30638c2ecf20Sopenharmony_ci	.name = MODULE_NAME,
30648c2ecf20Sopenharmony_ci	.config = sd_config,
30658c2ecf20Sopenharmony_ci	.init = sd_init,
30668c2ecf20Sopenharmony_ci	.init_controls = sd_init_controls,
30678c2ecf20Sopenharmony_ci	.start = sd_start,
30688c2ecf20Sopenharmony_ci	.stopN = sd_stopN,
30698c2ecf20Sopenharmony_ci	.stop0 = sd_stop0,
30708c2ecf20Sopenharmony_ci	.pkt_scan = sd_pkt_scan,
30718c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_INPUT)
30728c2ecf20Sopenharmony_ci	.dq_callback = cit_check_button,
30738c2ecf20Sopenharmony_ci	.other_input = 1,
30748c2ecf20Sopenharmony_ci#endif
30758c2ecf20Sopenharmony_ci};
30768c2ecf20Sopenharmony_ci
30778c2ecf20Sopenharmony_cistatic const struct sd_desc sd_desc_isoc_nego = {
30788c2ecf20Sopenharmony_ci	.name = MODULE_NAME,
30798c2ecf20Sopenharmony_ci	.config = sd_config,
30808c2ecf20Sopenharmony_ci	.init = sd_init,
30818c2ecf20Sopenharmony_ci	.init_controls = sd_init_controls,
30828c2ecf20Sopenharmony_ci	.start = sd_start,
30838c2ecf20Sopenharmony_ci	.isoc_init = sd_isoc_init,
30848c2ecf20Sopenharmony_ci	.isoc_nego = sd_isoc_nego,
30858c2ecf20Sopenharmony_ci	.stopN = sd_stopN,
30868c2ecf20Sopenharmony_ci	.stop0 = sd_stop0,
30878c2ecf20Sopenharmony_ci	.pkt_scan = sd_pkt_scan,
30888c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_INPUT)
30898c2ecf20Sopenharmony_ci	.dq_callback = cit_check_button,
30908c2ecf20Sopenharmony_ci	.other_input = 1,
30918c2ecf20Sopenharmony_ci#endif
30928c2ecf20Sopenharmony_ci};
30938c2ecf20Sopenharmony_ci
30948c2ecf20Sopenharmony_ci/* -- module initialisation -- */
30958c2ecf20Sopenharmony_cistatic const struct usb_device_id device_table[] = {
30968c2ecf20Sopenharmony_ci	{ USB_DEVICE_VER(0x0545, 0x8080, 0x0001, 0x0001), .driver_info = CIT_MODEL0 },
30978c2ecf20Sopenharmony_ci	{ USB_DEVICE_VER(0x0545, 0x8080, 0x0002, 0x0002), .driver_info = CIT_MODEL1 },
30988c2ecf20Sopenharmony_ci	{ USB_DEVICE_VER(0x0545, 0x8080, 0x030a, 0x030a), .driver_info = CIT_MODEL2 },
30998c2ecf20Sopenharmony_ci	{ USB_DEVICE_VER(0x0545, 0x8080, 0x0301, 0x0301), .driver_info = CIT_MODEL3 },
31008c2ecf20Sopenharmony_ci	{ USB_DEVICE_VER(0x0545, 0x8002, 0x030a, 0x030a), .driver_info = CIT_MODEL4 },
31018c2ecf20Sopenharmony_ci	{ USB_DEVICE_VER(0x0545, 0x800c, 0x030a, 0x030a), .driver_info = CIT_MODEL2 },
31028c2ecf20Sopenharmony_ci	{ USB_DEVICE_VER(0x0545, 0x800d, 0x030a, 0x030a), .driver_info = CIT_MODEL4 },
31038c2ecf20Sopenharmony_ci	{}
31048c2ecf20Sopenharmony_ci};
31058c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(usb, device_table);
31068c2ecf20Sopenharmony_ci
31078c2ecf20Sopenharmony_ci/* -- device connect -- */
31088c2ecf20Sopenharmony_cistatic int sd_probe(struct usb_interface *intf,
31098c2ecf20Sopenharmony_ci			const struct usb_device_id *id)
31108c2ecf20Sopenharmony_ci{
31118c2ecf20Sopenharmony_ci	const struct sd_desc *desc = &sd_desc;
31128c2ecf20Sopenharmony_ci
31138c2ecf20Sopenharmony_ci	switch (id->driver_info) {
31148c2ecf20Sopenharmony_ci	case CIT_MODEL0:
31158c2ecf20Sopenharmony_ci	case CIT_MODEL1:
31168c2ecf20Sopenharmony_ci		if (intf->cur_altsetting->desc.bInterfaceNumber != 2)
31178c2ecf20Sopenharmony_ci			return -ENODEV;
31188c2ecf20Sopenharmony_ci		break;
31198c2ecf20Sopenharmony_ci	case CIT_MODEL2:
31208c2ecf20Sopenharmony_ci	case CIT_MODEL4:
31218c2ecf20Sopenharmony_ci		if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
31228c2ecf20Sopenharmony_ci			return -ENODEV;
31238c2ecf20Sopenharmony_ci		break;
31248c2ecf20Sopenharmony_ci	case CIT_MODEL3:
31258c2ecf20Sopenharmony_ci		if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
31268c2ecf20Sopenharmony_ci			return -ENODEV;
31278c2ecf20Sopenharmony_ci		/* FIXME this likely applies to all model3 cams and probably
31288c2ecf20Sopenharmony_ci		   to other models too. */
31298c2ecf20Sopenharmony_ci		if (ibm_netcam_pro)
31308c2ecf20Sopenharmony_ci			desc = &sd_desc_isoc_nego;
31318c2ecf20Sopenharmony_ci		break;
31328c2ecf20Sopenharmony_ci	}
31338c2ecf20Sopenharmony_ci
31348c2ecf20Sopenharmony_ci	return gspca_dev_probe2(intf, id, desc, sizeof(struct sd), THIS_MODULE);
31358c2ecf20Sopenharmony_ci}
31368c2ecf20Sopenharmony_ci
31378c2ecf20Sopenharmony_cistatic struct usb_driver sd_driver = {
31388c2ecf20Sopenharmony_ci	.name = MODULE_NAME,
31398c2ecf20Sopenharmony_ci	.id_table = device_table,
31408c2ecf20Sopenharmony_ci	.probe = sd_probe,
31418c2ecf20Sopenharmony_ci	.disconnect = gspca_disconnect,
31428c2ecf20Sopenharmony_ci#ifdef CONFIG_PM
31438c2ecf20Sopenharmony_ci	.suspend = gspca_suspend,
31448c2ecf20Sopenharmony_ci	.resume = gspca_resume,
31458c2ecf20Sopenharmony_ci	.reset_resume = gspca_resume,
31468c2ecf20Sopenharmony_ci#endif
31478c2ecf20Sopenharmony_ci};
31488c2ecf20Sopenharmony_ci
31498c2ecf20Sopenharmony_cimodule_usb_driver(sd_driver);
3150