162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * USB IBM C-It Video Camera driver
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Supports Xirlink C-It Video Camera, IBM PC Camera,
662306a36Sopenharmony_ci * IBM NetCamera and Veo Stingray.
762306a36Sopenharmony_ci *
862306a36Sopenharmony_ci * Copyright (C) 2010 Hans de Goede <hdegoede@redhat.com>
962306a36Sopenharmony_ci *
1062306a36Sopenharmony_ci * This driver is based on earlier work of:
1162306a36Sopenharmony_ci *
1262306a36Sopenharmony_ci * (C) Copyright 1999 Johannes Erdfelt
1362306a36Sopenharmony_ci * (C) Copyright 1999 Randy Dunlap
1462306a36Sopenharmony_ci */
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci#define MODULE_NAME "xirlink-cit"
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci#include <linux/input.h>
2162306a36Sopenharmony_ci#include "gspca.h"
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ciMODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
2462306a36Sopenharmony_ciMODULE_DESCRIPTION("Xirlink C-IT");
2562306a36Sopenharmony_ciMODULE_LICENSE("GPL");
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci/* FIXME we should autodetect this */
2862306a36Sopenharmony_cistatic int ibm_netcam_pro;
2962306a36Sopenharmony_cimodule_param(ibm_netcam_pro, int, 0);
3062306a36Sopenharmony_ciMODULE_PARM_DESC(ibm_netcam_pro,
3162306a36Sopenharmony_ci		 "Use IBM Netcamera Pro init sequences for Model 3 cams");
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci/* FIXME this should be handled through the V4L2 input selection API */
3462306a36Sopenharmony_cistatic int rca_input;
3562306a36Sopenharmony_cimodule_param(rca_input, int, 0644);
3662306a36Sopenharmony_ciMODULE_PARM_DESC(rca_input,
3762306a36Sopenharmony_ci		 "Use rca input instead of ccd sensor on Model 3 cams");
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci/* specific webcam descriptor */
4062306a36Sopenharmony_cistruct sd {
4162306a36Sopenharmony_ci	struct gspca_dev gspca_dev;		/* !! must be the first item */
4262306a36Sopenharmony_ci	struct v4l2_ctrl *lighting;
4362306a36Sopenharmony_ci	u8 model;
4462306a36Sopenharmony_ci#define CIT_MODEL0 0 /* bcd version 0.01 cams ie the xvp-500 */
4562306a36Sopenharmony_ci#define CIT_MODEL1 1 /* The model 1 - 4 nomenclature comes from the old */
4662306a36Sopenharmony_ci#define CIT_MODEL2 2 /* ibmcam driver */
4762306a36Sopenharmony_ci#define CIT_MODEL3 3
4862306a36Sopenharmony_ci#define CIT_MODEL4 4
4962306a36Sopenharmony_ci#define CIT_IBM_NETCAM_PRO 5
5062306a36Sopenharmony_ci	u8 input_index;
5162306a36Sopenharmony_ci	u8 button_state;
5262306a36Sopenharmony_ci	u8 stop_on_control_change;
5362306a36Sopenharmony_ci	u8 sof_read;
5462306a36Sopenharmony_ci	u8 sof_len;
5562306a36Sopenharmony_ci};
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_cistatic void sd_stop0(struct gspca_dev *gspca_dev);
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_cistatic const struct v4l2_pix_format cif_yuv_mode[] = {
6062306a36Sopenharmony_ci	{176, 144, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
6162306a36Sopenharmony_ci		.bytesperline = 176,
6262306a36Sopenharmony_ci		.sizeimage = 176 * 144 * 3 / 2 + 4,
6362306a36Sopenharmony_ci		.colorspace = V4L2_COLORSPACE_SRGB},
6462306a36Sopenharmony_ci	{352, 288, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
6562306a36Sopenharmony_ci		.bytesperline = 352,
6662306a36Sopenharmony_ci		.sizeimage = 352 * 288 * 3 / 2 + 4,
6762306a36Sopenharmony_ci		.colorspace = V4L2_COLORSPACE_SRGB},
6862306a36Sopenharmony_ci};
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_cistatic const struct v4l2_pix_format vga_yuv_mode[] = {
7162306a36Sopenharmony_ci	{160, 120, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
7262306a36Sopenharmony_ci		.bytesperline = 160,
7362306a36Sopenharmony_ci		.sizeimage = 160 * 120 * 3 / 2 + 4,
7462306a36Sopenharmony_ci		.colorspace = V4L2_COLORSPACE_SRGB},
7562306a36Sopenharmony_ci	{320, 240, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
7662306a36Sopenharmony_ci		.bytesperline = 320,
7762306a36Sopenharmony_ci		.sizeimage = 320 * 240 * 3 / 2 + 4,
7862306a36Sopenharmony_ci		.colorspace = V4L2_COLORSPACE_SRGB},
7962306a36Sopenharmony_ci	{640, 480, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
8062306a36Sopenharmony_ci		.bytesperline = 640,
8162306a36Sopenharmony_ci		.sizeimage = 640 * 480 * 3 / 2 + 4,
8262306a36Sopenharmony_ci		.colorspace = V4L2_COLORSPACE_SRGB},
8362306a36Sopenharmony_ci};
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_cistatic const struct v4l2_pix_format model0_mode[] = {
8662306a36Sopenharmony_ci	{160, 120, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
8762306a36Sopenharmony_ci		.bytesperline = 160,
8862306a36Sopenharmony_ci		.sizeimage = 160 * 120 * 3 / 2 + 4,
8962306a36Sopenharmony_ci		.colorspace = V4L2_COLORSPACE_SRGB},
9062306a36Sopenharmony_ci	{176, 144, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
9162306a36Sopenharmony_ci		.bytesperline = 176,
9262306a36Sopenharmony_ci		.sizeimage = 176 * 144 * 3 / 2 + 4,
9362306a36Sopenharmony_ci		.colorspace = V4L2_COLORSPACE_SRGB},
9462306a36Sopenharmony_ci	{320, 240, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
9562306a36Sopenharmony_ci		.bytesperline = 320,
9662306a36Sopenharmony_ci		.sizeimage = 320 * 240 * 3 / 2 + 4,
9762306a36Sopenharmony_ci		.colorspace = V4L2_COLORSPACE_SRGB},
9862306a36Sopenharmony_ci};
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_cistatic const struct v4l2_pix_format model2_mode[] = {
10162306a36Sopenharmony_ci	{160, 120, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
10262306a36Sopenharmony_ci		.bytesperline = 160,
10362306a36Sopenharmony_ci		.sizeimage = 160 * 120 * 3 / 2 + 4,
10462306a36Sopenharmony_ci		.colorspace = V4L2_COLORSPACE_SRGB},
10562306a36Sopenharmony_ci	{176, 144, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
10662306a36Sopenharmony_ci		.bytesperline = 176,
10762306a36Sopenharmony_ci		.sizeimage = 176 * 144 * 3 / 2 + 4,
10862306a36Sopenharmony_ci		.colorspace = V4L2_COLORSPACE_SRGB},
10962306a36Sopenharmony_ci	{320, 240, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
11062306a36Sopenharmony_ci		.bytesperline = 320,
11162306a36Sopenharmony_ci		.sizeimage = 320 * 240 + 4,
11262306a36Sopenharmony_ci		.colorspace = V4L2_COLORSPACE_SRGB},
11362306a36Sopenharmony_ci	{352, 288, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
11462306a36Sopenharmony_ci		.bytesperline = 352,
11562306a36Sopenharmony_ci		.sizeimage = 352 * 288 + 4,
11662306a36Sopenharmony_ci		.colorspace = V4L2_COLORSPACE_SRGB},
11762306a36Sopenharmony_ci};
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_ci/*
12062306a36Sopenharmony_ci * 01.01.08 - Added for RCA video in support -LO
12162306a36Sopenharmony_ci * This struct is used to init the Model3 cam to use the RCA video in port
12262306a36Sopenharmony_ci * instead of the CCD sensor.
12362306a36Sopenharmony_ci */
12462306a36Sopenharmony_cistatic const u16 rca_initdata[][3] = {
12562306a36Sopenharmony_ci	{0, 0x0000, 0x010c},
12662306a36Sopenharmony_ci	{0, 0x0006, 0x012c},
12762306a36Sopenharmony_ci	{0, 0x0078, 0x012d},
12862306a36Sopenharmony_ci	{0, 0x0046, 0x012f},
12962306a36Sopenharmony_ci	{0, 0xd141, 0x0124},
13062306a36Sopenharmony_ci	{0, 0x0000, 0x0127},
13162306a36Sopenharmony_ci	{0, 0xfea8, 0x0124},
13262306a36Sopenharmony_ci	{1, 0x0000, 0x0116},
13362306a36Sopenharmony_ci	{0, 0x0064, 0x0116},
13462306a36Sopenharmony_ci	{1, 0x0000, 0x0115},
13562306a36Sopenharmony_ci	{0, 0x0003, 0x0115},
13662306a36Sopenharmony_ci	{0, 0x0008, 0x0123},
13762306a36Sopenharmony_ci	{0, 0x0000, 0x0117},
13862306a36Sopenharmony_ci	{0, 0x0000, 0x0112},
13962306a36Sopenharmony_ci	{0, 0x0080, 0x0100},
14062306a36Sopenharmony_ci	{0, 0x0000, 0x0100},
14162306a36Sopenharmony_ci	{1, 0x0000, 0x0116},
14262306a36Sopenharmony_ci	{0, 0x0060, 0x0116},
14362306a36Sopenharmony_ci	{0, 0x0002, 0x0112},
14462306a36Sopenharmony_ci	{0, 0x0000, 0x0123},
14562306a36Sopenharmony_ci	{0, 0x0001, 0x0117},
14662306a36Sopenharmony_ci	{0, 0x0040, 0x0108},
14762306a36Sopenharmony_ci	{0, 0x0019, 0x012c},
14862306a36Sopenharmony_ci	{0, 0x0040, 0x0116},
14962306a36Sopenharmony_ci	{0, 0x000a, 0x0115},
15062306a36Sopenharmony_ci	{0, 0x000b, 0x0115},
15162306a36Sopenharmony_ci	{0, 0x0078, 0x012d},
15262306a36Sopenharmony_ci	{0, 0x0046, 0x012f},
15362306a36Sopenharmony_ci	{0, 0xd141, 0x0124},
15462306a36Sopenharmony_ci	{0, 0x0000, 0x0127},
15562306a36Sopenharmony_ci	{0, 0xfea8, 0x0124},
15662306a36Sopenharmony_ci	{0, 0x0064, 0x0116},
15762306a36Sopenharmony_ci	{0, 0x0000, 0x0115},
15862306a36Sopenharmony_ci	{0, 0x0001, 0x0115},
15962306a36Sopenharmony_ci	{0, 0xffff, 0x0124},
16062306a36Sopenharmony_ci	{0, 0xfff9, 0x0124},
16162306a36Sopenharmony_ci	{0, 0x0086, 0x0127},
16262306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
16362306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
16462306a36Sopenharmony_ci	{0, 0x00aa, 0x0127},
16562306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
16662306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
16762306a36Sopenharmony_ci	{0, 0x0000, 0x0127},
16862306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
16962306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
17062306a36Sopenharmony_ci	{0, 0xfffa, 0x0124},
17162306a36Sopenharmony_ci	{0, 0xffff, 0x0124},
17262306a36Sopenharmony_ci	{0, 0xfff9, 0x0124},
17362306a36Sopenharmony_ci	{0, 0x0086, 0x0127},
17462306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
17562306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
17662306a36Sopenharmony_ci	{0, 0x00f2, 0x0127},
17762306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
17862306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
17962306a36Sopenharmony_ci	{0, 0x000f, 0x0127},
18062306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
18162306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
18262306a36Sopenharmony_ci	{0, 0xfffa, 0x0124},
18362306a36Sopenharmony_ci	{0, 0xffff, 0x0124},
18462306a36Sopenharmony_ci	{0, 0xfff9, 0x0124},
18562306a36Sopenharmony_ci	{0, 0x0086, 0x0127},
18662306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
18762306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
18862306a36Sopenharmony_ci	{0, 0x00f8, 0x0127},
18962306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
19062306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
19162306a36Sopenharmony_ci	{0, 0x00fc, 0x0127},
19262306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
19362306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
19462306a36Sopenharmony_ci	{0, 0xfffa, 0x0124},
19562306a36Sopenharmony_ci	{0, 0xffff, 0x0124},
19662306a36Sopenharmony_ci	{0, 0xfff9, 0x0124},
19762306a36Sopenharmony_ci	{0, 0x0086, 0x0127},
19862306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
19962306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
20062306a36Sopenharmony_ci	{0, 0x00f9, 0x0127},
20162306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
20262306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
20362306a36Sopenharmony_ci	{0, 0x003c, 0x0127},
20462306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
20562306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
20662306a36Sopenharmony_ci	{0, 0xfffa, 0x0124},
20762306a36Sopenharmony_ci	{0, 0xffff, 0x0124},
20862306a36Sopenharmony_ci	{0, 0xfff9, 0x0124},
20962306a36Sopenharmony_ci	{0, 0x0086, 0x0127},
21062306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
21162306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
21262306a36Sopenharmony_ci	{0, 0x0027, 0x0127},
21362306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
21462306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
21562306a36Sopenharmony_ci	{0, 0x0019, 0x0127},
21662306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
21762306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
21862306a36Sopenharmony_ci	{0, 0xfffa, 0x0124},
21962306a36Sopenharmony_ci	{0, 0xfff9, 0x0124},
22062306a36Sopenharmony_ci	{0, 0x0086, 0x0127},
22162306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
22262306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
22362306a36Sopenharmony_ci	{0, 0x0037, 0x0127},
22462306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
22562306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
22662306a36Sopenharmony_ci	{0, 0x0000, 0x0127},
22762306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
22862306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
22962306a36Sopenharmony_ci	{0, 0x0021, 0x0127},
23062306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
23162306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
23262306a36Sopenharmony_ci	{0, 0xfffa, 0x0124},
23362306a36Sopenharmony_ci	{0, 0xfff9, 0x0124},
23462306a36Sopenharmony_ci	{0, 0x0086, 0x0127},
23562306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
23662306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
23762306a36Sopenharmony_ci	{0, 0x0038, 0x0127},
23862306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
23962306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
24062306a36Sopenharmony_ci	{0, 0x0006, 0x0127},
24162306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
24262306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
24362306a36Sopenharmony_ci	{0, 0x0045, 0x0127},
24462306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
24562306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
24662306a36Sopenharmony_ci	{0, 0xfffa, 0x0124},
24762306a36Sopenharmony_ci	{0, 0xfff9, 0x0124},
24862306a36Sopenharmony_ci	{0, 0x0086, 0x0127},
24962306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
25062306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
25162306a36Sopenharmony_ci	{0, 0x0037, 0x0127},
25262306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
25362306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
25462306a36Sopenharmony_ci	{0, 0x0001, 0x0127},
25562306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
25662306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
25762306a36Sopenharmony_ci	{0, 0x002a, 0x0127},
25862306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
25962306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
26062306a36Sopenharmony_ci	{0, 0xfffa, 0x0124},
26162306a36Sopenharmony_ci	{0, 0xfff9, 0x0124},
26262306a36Sopenharmony_ci	{0, 0x0086, 0x0127},
26362306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
26462306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
26562306a36Sopenharmony_ci	{0, 0x0038, 0x0127},
26662306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
26762306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
26862306a36Sopenharmony_ci	{0, 0x0000, 0x0127},
26962306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
27062306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
27162306a36Sopenharmony_ci	{0, 0x000e, 0x0127},
27262306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
27362306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
27462306a36Sopenharmony_ci	{0, 0xfffa, 0x0124},
27562306a36Sopenharmony_ci	{0, 0xfff9, 0x0124},
27662306a36Sopenharmony_ci	{0, 0x0086, 0x0127},
27762306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
27862306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
27962306a36Sopenharmony_ci	{0, 0x0037, 0x0127},
28062306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
28162306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
28262306a36Sopenharmony_ci	{0, 0x0001, 0x0127},
28362306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
28462306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
28562306a36Sopenharmony_ci	{0, 0x002b, 0x0127},
28662306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
28762306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
28862306a36Sopenharmony_ci	{0, 0xfffa, 0x0124},
28962306a36Sopenharmony_ci	{0, 0xfff9, 0x0124},
29062306a36Sopenharmony_ci	{0, 0x0086, 0x0127},
29162306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
29262306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
29362306a36Sopenharmony_ci	{0, 0x0038, 0x0127},
29462306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
29562306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
29662306a36Sopenharmony_ci	{0, 0x0001, 0x0127},
29762306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
29862306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
29962306a36Sopenharmony_ci	{0, 0x00f4, 0x0127},
30062306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
30162306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
30262306a36Sopenharmony_ci	{0, 0xfffa, 0x0124},
30362306a36Sopenharmony_ci	{0, 0xfff9, 0x0124},
30462306a36Sopenharmony_ci	{0, 0x0086, 0x0127},
30562306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
30662306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
30762306a36Sopenharmony_ci	{0, 0x0037, 0x0127},
30862306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
30962306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
31062306a36Sopenharmony_ci	{0, 0x0001, 0x0127},
31162306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
31262306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
31362306a36Sopenharmony_ci	{0, 0x002c, 0x0127},
31462306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
31562306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
31662306a36Sopenharmony_ci	{0, 0xfffa, 0x0124},
31762306a36Sopenharmony_ci	{0, 0xfff9, 0x0124},
31862306a36Sopenharmony_ci	{0, 0x0086, 0x0127},
31962306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
32062306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
32162306a36Sopenharmony_ci	{0, 0x0038, 0x0127},
32262306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
32362306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
32462306a36Sopenharmony_ci	{0, 0x0001, 0x0127},
32562306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
32662306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
32762306a36Sopenharmony_ci	{0, 0x0004, 0x0127},
32862306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
32962306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
33062306a36Sopenharmony_ci	{0, 0xfffa, 0x0124},
33162306a36Sopenharmony_ci	{0, 0xfff9, 0x0124},
33262306a36Sopenharmony_ci	{0, 0x0086, 0x0127},
33362306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
33462306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
33562306a36Sopenharmony_ci	{0, 0x0037, 0x0127},
33662306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
33762306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
33862306a36Sopenharmony_ci	{0, 0x0001, 0x0127},
33962306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
34062306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
34162306a36Sopenharmony_ci	{0, 0x002d, 0x0127},
34262306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
34362306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
34462306a36Sopenharmony_ci	{0, 0xfffa, 0x0124},
34562306a36Sopenharmony_ci	{0, 0xfff9, 0x0124},
34662306a36Sopenharmony_ci	{0, 0x0086, 0x0127},
34762306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
34862306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
34962306a36Sopenharmony_ci	{0, 0x0038, 0x0127},
35062306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
35162306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
35262306a36Sopenharmony_ci	{0, 0x0000, 0x0127},
35362306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
35462306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
35562306a36Sopenharmony_ci	{0, 0x0014, 0x0127},
35662306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
35762306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
35862306a36Sopenharmony_ci	{0, 0xfffa, 0x0124},
35962306a36Sopenharmony_ci	{0, 0xfff9, 0x0124},
36062306a36Sopenharmony_ci	{0, 0x0086, 0x0127},
36162306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
36262306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
36362306a36Sopenharmony_ci	{0, 0x0037, 0x0127},
36462306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
36562306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
36662306a36Sopenharmony_ci	{0, 0x0001, 0x0127},
36762306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
36862306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
36962306a36Sopenharmony_ci	{0, 0x002e, 0x0127},
37062306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
37162306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
37262306a36Sopenharmony_ci	{0, 0xfffa, 0x0124},
37362306a36Sopenharmony_ci	{0, 0xfff9, 0x0124},
37462306a36Sopenharmony_ci	{0, 0x0086, 0x0127},
37562306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
37662306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
37762306a36Sopenharmony_ci	{0, 0x0038, 0x0127},
37862306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
37962306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
38062306a36Sopenharmony_ci	{0, 0x0003, 0x0127},
38162306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
38262306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
38362306a36Sopenharmony_ci	{0, 0x0000, 0x0127},
38462306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
38562306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
38662306a36Sopenharmony_ci	{0, 0xfffa, 0x0124},
38762306a36Sopenharmony_ci	{0, 0xfff9, 0x0124},
38862306a36Sopenharmony_ci	{0, 0x0086, 0x0127},
38962306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
39062306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
39162306a36Sopenharmony_ci	{0, 0x0037, 0x0127},
39262306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
39362306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
39462306a36Sopenharmony_ci	{0, 0x0001, 0x0127},
39562306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
39662306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
39762306a36Sopenharmony_ci	{0, 0x002f, 0x0127},
39862306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
39962306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
40062306a36Sopenharmony_ci	{0, 0xfffa, 0x0124},
40162306a36Sopenharmony_ci	{0, 0xfff9, 0x0124},
40262306a36Sopenharmony_ci	{0, 0x0086, 0x0127},
40362306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
40462306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
40562306a36Sopenharmony_ci	{0, 0x0038, 0x0127},
40662306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
40762306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
40862306a36Sopenharmony_ci	{0, 0x0003, 0x0127},
40962306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
41062306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
41162306a36Sopenharmony_ci	{0, 0x0014, 0x0127},
41262306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
41362306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
41462306a36Sopenharmony_ci	{0, 0xfffa, 0x0124},
41562306a36Sopenharmony_ci	{0, 0xfff9, 0x0124},
41662306a36Sopenharmony_ci	{0, 0x0086, 0x0127},
41762306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
41862306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
41962306a36Sopenharmony_ci	{0, 0x0037, 0x0127},
42062306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
42162306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
42262306a36Sopenharmony_ci	{0, 0x0001, 0x0127},
42362306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
42462306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
42562306a36Sopenharmony_ci	{0, 0x0040, 0x0127},
42662306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
42762306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
42862306a36Sopenharmony_ci	{0, 0xfffa, 0x0124},
42962306a36Sopenharmony_ci	{0, 0xfff9, 0x0124},
43062306a36Sopenharmony_ci	{0, 0x0086, 0x0127},
43162306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
43262306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
43362306a36Sopenharmony_ci	{0, 0x0038, 0x0127},
43462306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
43562306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
43662306a36Sopenharmony_ci	{0, 0x0000, 0x0127},
43762306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
43862306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
43962306a36Sopenharmony_ci	{0, 0x0040, 0x0127},
44062306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
44162306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
44262306a36Sopenharmony_ci	{0, 0xfffa, 0x0124},
44362306a36Sopenharmony_ci	{0, 0xfff9, 0x0124},
44462306a36Sopenharmony_ci	{0, 0x0086, 0x0127},
44562306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
44662306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
44762306a36Sopenharmony_ci	{0, 0x0037, 0x0127},
44862306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
44962306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
45062306a36Sopenharmony_ci	{0, 0x0001, 0x0127},
45162306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
45262306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
45362306a36Sopenharmony_ci	{0, 0x0053, 0x0127},
45462306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
45562306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
45662306a36Sopenharmony_ci	{0, 0xfffa, 0x0124},
45762306a36Sopenharmony_ci	{0, 0xfff9, 0x0124},
45862306a36Sopenharmony_ci	{0, 0x0086, 0x0127},
45962306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
46062306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
46162306a36Sopenharmony_ci	{0, 0x0038, 0x0127},
46262306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
46362306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
46462306a36Sopenharmony_ci	{0, 0x0000, 0x0127},
46562306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
46662306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
46762306a36Sopenharmony_ci	{0, 0x0038, 0x0127},
46862306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
46962306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
47062306a36Sopenharmony_ci	{0, 0xfffa, 0x0124},
47162306a36Sopenharmony_ci	{0, 0x0000, 0x0101},
47262306a36Sopenharmony_ci	{0, 0x00a0, 0x0103},
47362306a36Sopenharmony_ci	{0, 0x0078, 0x0105},
47462306a36Sopenharmony_ci	{0, 0x0000, 0x010a},
47562306a36Sopenharmony_ci	{0, 0x0024, 0x010b},
47662306a36Sopenharmony_ci	{0, 0x0028, 0x0119},
47762306a36Sopenharmony_ci	{0, 0x0088, 0x011b},
47862306a36Sopenharmony_ci	{0, 0x0002, 0x011d},
47962306a36Sopenharmony_ci	{0, 0x0003, 0x011e},
48062306a36Sopenharmony_ci	{0, 0x0000, 0x0129},
48162306a36Sopenharmony_ci	{0, 0x00fc, 0x012b},
48262306a36Sopenharmony_ci	{0, 0x0008, 0x0102},
48362306a36Sopenharmony_ci	{0, 0x0000, 0x0104},
48462306a36Sopenharmony_ci	{0, 0x0008, 0x011a},
48562306a36Sopenharmony_ci	{0, 0x0028, 0x011c},
48662306a36Sopenharmony_ci	{0, 0x0021, 0x012a},
48762306a36Sopenharmony_ci	{0, 0x0000, 0x0118},
48862306a36Sopenharmony_ci	{0, 0x0000, 0x0132},
48962306a36Sopenharmony_ci	{0, 0x0000, 0x0109},
49062306a36Sopenharmony_ci	{0, 0xfff9, 0x0124},
49162306a36Sopenharmony_ci	{0, 0x0086, 0x0127},
49262306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
49362306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
49462306a36Sopenharmony_ci	{0, 0x0037, 0x0127},
49562306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
49662306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
49762306a36Sopenharmony_ci	{0, 0x0001, 0x0127},
49862306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
49962306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
50062306a36Sopenharmony_ci	{0, 0x0031, 0x0127},
50162306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
50262306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
50362306a36Sopenharmony_ci	{0, 0xfffa, 0x0124},
50462306a36Sopenharmony_ci	{0, 0xfff9, 0x0124},
50562306a36Sopenharmony_ci	{0, 0x0086, 0x0127},
50662306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
50762306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
50862306a36Sopenharmony_ci	{0, 0x0038, 0x0127},
50962306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
51062306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
51162306a36Sopenharmony_ci	{0, 0x0000, 0x0127},
51262306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
51362306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
51462306a36Sopenharmony_ci	{0, 0x0000, 0x0127},
51562306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
51662306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
51762306a36Sopenharmony_ci	{0, 0xfffa, 0x0124},
51862306a36Sopenharmony_ci	{0, 0xfff9, 0x0124},
51962306a36Sopenharmony_ci	{0, 0x0086, 0x0127},
52062306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
52162306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
52262306a36Sopenharmony_ci	{0, 0x0037, 0x0127},
52362306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
52462306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
52562306a36Sopenharmony_ci	{0, 0x0001, 0x0127},
52662306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
52762306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
52862306a36Sopenharmony_ci	{0, 0x0040, 0x0127},
52962306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
53062306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
53162306a36Sopenharmony_ci	{0, 0xfffa, 0x0124},
53262306a36Sopenharmony_ci	{0, 0xfff9, 0x0124},
53362306a36Sopenharmony_ci	{0, 0x0086, 0x0127},
53462306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
53562306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
53662306a36Sopenharmony_ci	{0, 0x0038, 0x0127},
53762306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
53862306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
53962306a36Sopenharmony_ci	{0, 0x0000, 0x0127},
54062306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
54162306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
54262306a36Sopenharmony_ci	{0, 0x0040, 0x0127},
54362306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
54462306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
54562306a36Sopenharmony_ci	{0, 0xfffa, 0x0124},
54662306a36Sopenharmony_ci	{0, 0xfff9, 0x0124},
54762306a36Sopenharmony_ci	{0, 0x0086, 0x0127},
54862306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
54962306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
55062306a36Sopenharmony_ci	{0, 0x0037, 0x0127},
55162306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
55262306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
55362306a36Sopenharmony_ci	{0, 0x0000, 0x0127},
55462306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
55562306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
55662306a36Sopenharmony_ci	{0, 0x00dc, 0x0127},
55762306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
55862306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
55962306a36Sopenharmony_ci	{0, 0xfffa, 0x0124},
56062306a36Sopenharmony_ci	{0, 0xfff9, 0x0124},
56162306a36Sopenharmony_ci	{0, 0x0086, 0x0127},
56262306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
56362306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
56462306a36Sopenharmony_ci	{0, 0x0038, 0x0127},
56562306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
56662306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
56762306a36Sopenharmony_ci	{0, 0x0000, 0x0127},
56862306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
56962306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
57062306a36Sopenharmony_ci	{0, 0x0000, 0x0127},
57162306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
57262306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
57362306a36Sopenharmony_ci	{0, 0xfffa, 0x0124},
57462306a36Sopenharmony_ci	{0, 0xfff9, 0x0124},
57562306a36Sopenharmony_ci	{0, 0x0086, 0x0127},
57662306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
57762306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
57862306a36Sopenharmony_ci	{0, 0x0037, 0x0127},
57962306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
58062306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
58162306a36Sopenharmony_ci	{0, 0x0001, 0x0127},
58262306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
58362306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
58462306a36Sopenharmony_ci	{0, 0x0032, 0x0127},
58562306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
58662306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
58762306a36Sopenharmony_ci	{0, 0xfffa, 0x0124},
58862306a36Sopenharmony_ci	{0, 0xfff9, 0x0124},
58962306a36Sopenharmony_ci	{0, 0x0086, 0x0127},
59062306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
59162306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
59262306a36Sopenharmony_ci	{0, 0x0038, 0x0127},
59362306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
59462306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
59562306a36Sopenharmony_ci	{0, 0x0001, 0x0127},
59662306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
59762306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
59862306a36Sopenharmony_ci	{0, 0x0020, 0x0127},
59962306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
60062306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
60162306a36Sopenharmony_ci	{0, 0xfffa, 0x0124},
60262306a36Sopenharmony_ci	{0, 0xfff9, 0x0124},
60362306a36Sopenharmony_ci	{0, 0x0086, 0x0127},
60462306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
60562306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
60662306a36Sopenharmony_ci	{0, 0x0037, 0x0127},
60762306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
60862306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
60962306a36Sopenharmony_ci	{0, 0x0001, 0x0127},
61062306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
61162306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
61262306a36Sopenharmony_ci	{0, 0x0040, 0x0127},
61362306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
61462306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
61562306a36Sopenharmony_ci	{0, 0xfffa, 0x0124},
61662306a36Sopenharmony_ci	{0, 0xfff9, 0x0124},
61762306a36Sopenharmony_ci	{0, 0x0086, 0x0127},
61862306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
61962306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
62062306a36Sopenharmony_ci	{0, 0x0038, 0x0127},
62162306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
62262306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
62362306a36Sopenharmony_ci	{0, 0x0000, 0x0127},
62462306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
62562306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
62662306a36Sopenharmony_ci	{0, 0x0040, 0x0127},
62762306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
62862306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
62962306a36Sopenharmony_ci	{0, 0xfffa, 0x0124},
63062306a36Sopenharmony_ci	{0, 0xfff9, 0x0124},
63162306a36Sopenharmony_ci	{0, 0x0086, 0x0127},
63262306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
63362306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
63462306a36Sopenharmony_ci	{0, 0x0037, 0x0127},
63562306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
63662306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
63762306a36Sopenharmony_ci	{0, 0x0000, 0x0127},
63862306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
63962306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
64062306a36Sopenharmony_ci	{0, 0x0030, 0x0127},
64162306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
64262306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
64362306a36Sopenharmony_ci	{0, 0xfffa, 0x0124},
64462306a36Sopenharmony_ci	{0, 0xfff9, 0x0124},
64562306a36Sopenharmony_ci	{0, 0x0086, 0x0127},
64662306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
64762306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
64862306a36Sopenharmony_ci	{0, 0x0038, 0x0127},
64962306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
65062306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
65162306a36Sopenharmony_ci	{0, 0x0008, 0x0127},
65262306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
65362306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
65462306a36Sopenharmony_ci	{0, 0x0000, 0x0127},
65562306a36Sopenharmony_ci	{0, 0xfff8, 0x0124},
65662306a36Sopenharmony_ci	{0, 0xfffd, 0x0124},
65762306a36Sopenharmony_ci	{0, 0xfffa, 0x0124},
65862306a36Sopenharmony_ci	{0, 0x0003, 0x0111},
65962306a36Sopenharmony_ci};
66062306a36Sopenharmony_ci
66162306a36Sopenharmony_ci/* TESTME the old ibmcam driver repeats certain commands to Model1 cameras, we
66262306a36Sopenharmony_ci   do the same for now (testing needed to see if this is really necessary) */
66362306a36Sopenharmony_cistatic const int cit_model1_ntries = 5;
66462306a36Sopenharmony_cistatic const int cit_model1_ntries2 = 2;
66562306a36Sopenharmony_ci
66662306a36Sopenharmony_cistatic int cit_write_reg(struct gspca_dev *gspca_dev, u16 value, u16 index)
66762306a36Sopenharmony_ci{
66862306a36Sopenharmony_ci	struct usb_device *udev = gspca_dev->dev;
66962306a36Sopenharmony_ci	int err;
67062306a36Sopenharmony_ci
67162306a36Sopenharmony_ci	err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00,
67262306a36Sopenharmony_ci			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT,
67362306a36Sopenharmony_ci			value, index, NULL, 0, 1000);
67462306a36Sopenharmony_ci	if (err < 0)
67562306a36Sopenharmony_ci		pr_err("Failed to write a register (index 0x%04X, value 0x%02X, error %d)\n",
67662306a36Sopenharmony_ci		       index, value, err);
67762306a36Sopenharmony_ci
67862306a36Sopenharmony_ci	return 0;
67962306a36Sopenharmony_ci}
68062306a36Sopenharmony_ci
68162306a36Sopenharmony_cistatic int cit_read_reg(struct gspca_dev *gspca_dev, u16 index, int verbose)
68262306a36Sopenharmony_ci{
68362306a36Sopenharmony_ci	struct usb_device *udev = gspca_dev->dev;
68462306a36Sopenharmony_ci	__u8 *buf = gspca_dev->usb_buf;
68562306a36Sopenharmony_ci	int res;
68662306a36Sopenharmony_ci
68762306a36Sopenharmony_ci	res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x01,
68862306a36Sopenharmony_ci			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT,
68962306a36Sopenharmony_ci			0x00, index, buf, 8, 1000);
69062306a36Sopenharmony_ci	if (res < 0) {
69162306a36Sopenharmony_ci		pr_err("Failed to read a register (index 0x%04X, error %d)\n",
69262306a36Sopenharmony_ci		       index, res);
69362306a36Sopenharmony_ci		return res;
69462306a36Sopenharmony_ci	}
69562306a36Sopenharmony_ci
69662306a36Sopenharmony_ci	if (verbose)
69762306a36Sopenharmony_ci		gspca_dbg(gspca_dev, D_PROBE, "Register %04x value: %02x\n",
69862306a36Sopenharmony_ci			  index, buf[0]);
69962306a36Sopenharmony_ci
70062306a36Sopenharmony_ci	return 0;
70162306a36Sopenharmony_ci}
70262306a36Sopenharmony_ci
70362306a36Sopenharmony_ci/*
70462306a36Sopenharmony_ci * cit_send_FF_04_02()
70562306a36Sopenharmony_ci *
70662306a36Sopenharmony_ci * This procedure sends magic 3-command prefix to the camera.
70762306a36Sopenharmony_ci * The purpose of this prefix is not known.
70862306a36Sopenharmony_ci *
70962306a36Sopenharmony_ci * History:
71062306a36Sopenharmony_ci * 1/2/00   Created.
71162306a36Sopenharmony_ci */
71262306a36Sopenharmony_cistatic void cit_send_FF_04_02(struct gspca_dev *gspca_dev)
71362306a36Sopenharmony_ci{
71462306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x00FF, 0x0127);
71562306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0004, 0x0124);
71662306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0002, 0x0124);
71762306a36Sopenharmony_ci}
71862306a36Sopenharmony_ci
71962306a36Sopenharmony_cistatic void cit_send_00_04_06(struct gspca_dev *gspca_dev)
72062306a36Sopenharmony_ci{
72162306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0127);
72262306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0004, 0x0124);
72362306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0006, 0x0124);
72462306a36Sopenharmony_ci}
72562306a36Sopenharmony_ci
72662306a36Sopenharmony_cistatic void cit_send_x_00(struct gspca_dev *gspca_dev, unsigned short x)
72762306a36Sopenharmony_ci{
72862306a36Sopenharmony_ci	cit_write_reg(gspca_dev, x,      0x0127);
72962306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0124);
73062306a36Sopenharmony_ci}
73162306a36Sopenharmony_ci
73262306a36Sopenharmony_cistatic void cit_send_x_00_05(struct gspca_dev *gspca_dev, unsigned short x)
73362306a36Sopenharmony_ci{
73462306a36Sopenharmony_ci	cit_send_x_00(gspca_dev, x);
73562306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0005, 0x0124);
73662306a36Sopenharmony_ci}
73762306a36Sopenharmony_ci
73862306a36Sopenharmony_cistatic void cit_send_x_00_05_02(struct gspca_dev *gspca_dev, unsigned short x)
73962306a36Sopenharmony_ci{
74062306a36Sopenharmony_ci	cit_write_reg(gspca_dev, x,      0x0127);
74162306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0124);
74262306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0005, 0x0124);
74362306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0002, 0x0124);
74462306a36Sopenharmony_ci}
74562306a36Sopenharmony_ci
74662306a36Sopenharmony_cistatic void cit_send_x_01_00_05(struct gspca_dev *gspca_dev, u16 x)
74762306a36Sopenharmony_ci{
74862306a36Sopenharmony_ci	cit_write_reg(gspca_dev, x,      0x0127);
74962306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0001, 0x0124);
75062306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0124);
75162306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0005, 0x0124);
75262306a36Sopenharmony_ci}
75362306a36Sopenharmony_ci
75462306a36Sopenharmony_cistatic void cit_send_x_00_05_02_01(struct gspca_dev *gspca_dev, u16 x)
75562306a36Sopenharmony_ci{
75662306a36Sopenharmony_ci	cit_write_reg(gspca_dev, x,      0x0127);
75762306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0124);
75862306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0005, 0x0124);
75962306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0002, 0x0124);
76062306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0001, 0x0124);
76162306a36Sopenharmony_ci}
76262306a36Sopenharmony_ci
76362306a36Sopenharmony_cistatic void cit_send_x_00_05_02_08_01(struct gspca_dev *gspca_dev, u16 x)
76462306a36Sopenharmony_ci{
76562306a36Sopenharmony_ci	cit_write_reg(gspca_dev, x,      0x0127);
76662306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0124);
76762306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0005, 0x0124);
76862306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0002, 0x0124);
76962306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0008, 0x0124);
77062306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0001, 0x0124);
77162306a36Sopenharmony_ci}
77262306a36Sopenharmony_ci
77362306a36Sopenharmony_cistatic void cit_Packet_Format1(struct gspca_dev *gspca_dev, u16 fkey, u16 val)
77462306a36Sopenharmony_ci{
77562306a36Sopenharmony_ci	cit_send_x_01_00_05(gspca_dev, 0x0088);
77662306a36Sopenharmony_ci	cit_send_x_00_05(gspca_dev, fkey);
77762306a36Sopenharmony_ci	cit_send_x_00_05_02_08_01(gspca_dev, val);
77862306a36Sopenharmony_ci	cit_send_x_00_05(gspca_dev, 0x0088);
77962306a36Sopenharmony_ci	cit_send_x_00_05_02_01(gspca_dev, fkey);
78062306a36Sopenharmony_ci	cit_send_x_00_05(gspca_dev, 0x0089);
78162306a36Sopenharmony_ci	cit_send_x_00(gspca_dev, fkey);
78262306a36Sopenharmony_ci	cit_send_00_04_06(gspca_dev);
78362306a36Sopenharmony_ci	cit_read_reg(gspca_dev, 0x0126, 0);
78462306a36Sopenharmony_ci	cit_send_FF_04_02(gspca_dev);
78562306a36Sopenharmony_ci}
78662306a36Sopenharmony_ci
78762306a36Sopenharmony_cistatic void cit_PacketFormat2(struct gspca_dev *gspca_dev, u16 fkey, u16 val)
78862306a36Sopenharmony_ci{
78962306a36Sopenharmony_ci	cit_send_x_01_00_05(gspca_dev, 0x0088);
79062306a36Sopenharmony_ci	cit_send_x_00_05(gspca_dev, fkey);
79162306a36Sopenharmony_ci	cit_send_x_00_05_02(gspca_dev, val);
79262306a36Sopenharmony_ci}
79362306a36Sopenharmony_ci
79462306a36Sopenharmony_cistatic void cit_model2_Packet2(struct gspca_dev *gspca_dev)
79562306a36Sopenharmony_ci{
79662306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x00ff, 0x012d);
79762306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0xfea3, 0x0124);
79862306a36Sopenharmony_ci}
79962306a36Sopenharmony_ci
80062306a36Sopenharmony_cistatic void cit_model2_Packet1(struct gspca_dev *gspca_dev, u16 v1, u16 v2)
80162306a36Sopenharmony_ci{
80262306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x00aa, 0x012d);
80362306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x00ff, 0x012e);
80462306a36Sopenharmony_ci	cit_write_reg(gspca_dev, v1,     0x012f);
80562306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x00ff, 0x0130);
80662306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0xc719, 0x0124);
80762306a36Sopenharmony_ci	cit_write_reg(gspca_dev, v2,     0x0127);
80862306a36Sopenharmony_ci
80962306a36Sopenharmony_ci	cit_model2_Packet2(gspca_dev);
81062306a36Sopenharmony_ci}
81162306a36Sopenharmony_ci
81262306a36Sopenharmony_ci/*
81362306a36Sopenharmony_ci * cit_model3_Packet1()
81462306a36Sopenharmony_ci *
81562306a36Sopenharmony_ci * 00_0078_012d
81662306a36Sopenharmony_ci * 00_0097_012f
81762306a36Sopenharmony_ci * 00_d141_0124
81862306a36Sopenharmony_ci * 00_0096_0127
81962306a36Sopenharmony_ci * 00_fea8_0124
82062306a36Sopenharmony_ci */
82162306a36Sopenharmony_cistatic void cit_model3_Packet1(struct gspca_dev *gspca_dev, u16 v1, u16 v2)
82262306a36Sopenharmony_ci{
82362306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0078, 0x012d);
82462306a36Sopenharmony_ci	cit_write_reg(gspca_dev, v1,     0x012f);
82562306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0xd141, 0x0124);
82662306a36Sopenharmony_ci	cit_write_reg(gspca_dev, v2,     0x0127);
82762306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0xfea8, 0x0124);
82862306a36Sopenharmony_ci}
82962306a36Sopenharmony_ci
83062306a36Sopenharmony_cistatic void cit_model4_Packet1(struct gspca_dev *gspca_dev, u16 v1, u16 v2)
83162306a36Sopenharmony_ci{
83262306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x00aa, 0x012d);
83362306a36Sopenharmony_ci	cit_write_reg(gspca_dev, v1,     0x012f);
83462306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0xd141, 0x0124);
83562306a36Sopenharmony_ci	cit_write_reg(gspca_dev, v2,     0x0127);
83662306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0xfea8, 0x0124);
83762306a36Sopenharmony_ci}
83862306a36Sopenharmony_ci
83962306a36Sopenharmony_cistatic void cit_model4_BrightnessPacket(struct gspca_dev *gspca_dev, u16 val)
84062306a36Sopenharmony_ci{
84162306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x00aa, 0x012d);
84262306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0026, 0x012f);
84362306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0xd141, 0x0124);
84462306a36Sopenharmony_ci	cit_write_reg(gspca_dev, val,    0x0127);
84562306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x00aa, 0x0130);
84662306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x82a8, 0x0124);
84762306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0038, 0x012d);
84862306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0004, 0x012f);
84962306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0xd145, 0x0124);
85062306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0xfffa, 0x0124);
85162306a36Sopenharmony_ci}
85262306a36Sopenharmony_ci
85362306a36Sopenharmony_ci/* this function is called at probe time */
85462306a36Sopenharmony_cistatic int sd_config(struct gspca_dev *gspca_dev,
85562306a36Sopenharmony_ci		     const struct usb_device_id *id)
85662306a36Sopenharmony_ci{
85762306a36Sopenharmony_ci	struct sd *sd = (struct sd *) gspca_dev;
85862306a36Sopenharmony_ci	struct cam *cam;
85962306a36Sopenharmony_ci
86062306a36Sopenharmony_ci	sd->model = id->driver_info;
86162306a36Sopenharmony_ci	if (sd->model == CIT_MODEL3 && ibm_netcam_pro)
86262306a36Sopenharmony_ci		sd->model = CIT_IBM_NETCAM_PRO;
86362306a36Sopenharmony_ci
86462306a36Sopenharmony_ci	cam = &gspca_dev->cam;
86562306a36Sopenharmony_ci	switch (sd->model) {
86662306a36Sopenharmony_ci	case CIT_MODEL0:
86762306a36Sopenharmony_ci		cam->cam_mode = model0_mode;
86862306a36Sopenharmony_ci		cam->nmodes = ARRAY_SIZE(model0_mode);
86962306a36Sopenharmony_ci		sd->sof_len = 4;
87062306a36Sopenharmony_ci		break;
87162306a36Sopenharmony_ci	case CIT_MODEL1:
87262306a36Sopenharmony_ci		cam->cam_mode = cif_yuv_mode;
87362306a36Sopenharmony_ci		cam->nmodes = ARRAY_SIZE(cif_yuv_mode);
87462306a36Sopenharmony_ci		sd->sof_len = 4;
87562306a36Sopenharmony_ci		break;
87662306a36Sopenharmony_ci	case CIT_MODEL2:
87762306a36Sopenharmony_ci		cam->cam_mode = model2_mode + 1; /* no 160x120 */
87862306a36Sopenharmony_ci		cam->nmodes = 3;
87962306a36Sopenharmony_ci		break;
88062306a36Sopenharmony_ci	case CIT_MODEL3:
88162306a36Sopenharmony_ci		cam->cam_mode = vga_yuv_mode;
88262306a36Sopenharmony_ci		cam->nmodes = ARRAY_SIZE(vga_yuv_mode);
88362306a36Sopenharmony_ci		sd->stop_on_control_change = 1;
88462306a36Sopenharmony_ci		sd->sof_len = 4;
88562306a36Sopenharmony_ci		break;
88662306a36Sopenharmony_ci	case CIT_MODEL4:
88762306a36Sopenharmony_ci		cam->cam_mode = model2_mode;
88862306a36Sopenharmony_ci		cam->nmodes = ARRAY_SIZE(model2_mode);
88962306a36Sopenharmony_ci		break;
89062306a36Sopenharmony_ci	case CIT_IBM_NETCAM_PRO:
89162306a36Sopenharmony_ci		cam->cam_mode = vga_yuv_mode;
89262306a36Sopenharmony_ci		cam->nmodes = 2; /* no 640 x 480 */
89362306a36Sopenharmony_ci		cam->input_flags = V4L2_IN_ST_VFLIP;
89462306a36Sopenharmony_ci		sd->stop_on_control_change = 1;
89562306a36Sopenharmony_ci		sd->sof_len = 4;
89662306a36Sopenharmony_ci		break;
89762306a36Sopenharmony_ci	}
89862306a36Sopenharmony_ci
89962306a36Sopenharmony_ci	return 0;
90062306a36Sopenharmony_ci}
90162306a36Sopenharmony_ci
90262306a36Sopenharmony_cistatic int cit_init_model0(struct gspca_dev *gspca_dev)
90362306a36Sopenharmony_ci{
90462306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0100); /* turn on led */
90562306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0001, 0x0112); /* turn on autogain ? */
90662306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0400);
90762306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0001, 0x0400);
90862306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0420);
90962306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0001, 0x0420);
91062306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x000d, 0x0409);
91162306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0002, 0x040a);
91262306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0018, 0x0405);
91362306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0008, 0x0435);
91462306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0026, 0x040b);
91562306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0007, 0x0437);
91662306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0015, 0x042f);
91762306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x002b, 0x0439);
91862306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0026, 0x043a);
91962306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0008, 0x0438);
92062306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x001e, 0x042b);
92162306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0041, 0x042c);
92262306a36Sopenharmony_ci
92362306a36Sopenharmony_ci	return 0;
92462306a36Sopenharmony_ci}
92562306a36Sopenharmony_ci
92662306a36Sopenharmony_cistatic int cit_init_ibm_netcam_pro(struct gspca_dev *gspca_dev)
92762306a36Sopenharmony_ci{
92862306a36Sopenharmony_ci	cit_read_reg(gspca_dev, 0x128, 1);
92962306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0003, 0x0133);
93062306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0117);
93162306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0008, 0x0123);
93262306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0100);
93362306a36Sopenharmony_ci	cit_read_reg(gspca_dev, 0x0116, 0);
93462306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0060, 0x0116);
93562306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0002, 0x0112);
93662306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0133);
93762306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0123);
93862306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0001, 0x0117);
93962306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0040, 0x0108);
94062306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0019, 0x012c);
94162306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0060, 0x0116);
94262306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0002, 0x0115);
94362306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x000b, 0x0115);
94462306a36Sopenharmony_ci
94562306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0078, 0x012d);
94662306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0001, 0x012f);
94762306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0xd141, 0x0124);
94862306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0079, 0x012d);
94962306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x00ff, 0x0130);
95062306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0xcd41, 0x0124);
95162306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0xfffa, 0x0124);
95262306a36Sopenharmony_ci	cit_read_reg(gspca_dev, 0x0126, 1);
95362306a36Sopenharmony_ci
95462306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0000, 0x0000);
95562306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0000, 0x0001);
95662306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x000b, 0x0000);
95762306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x000c, 0x0008);
95862306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x000d, 0x003a);
95962306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x000e, 0x0060);
96062306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x000f, 0x0060);
96162306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0010, 0x0008);
96262306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0011, 0x0004);
96362306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0012, 0x0028);
96462306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0013, 0x0002);
96562306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0014, 0x0000);
96662306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0015, 0x00fb);
96762306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0016, 0x0002);
96862306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0017, 0x0037);
96962306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0018, 0x0036);
97062306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x001e, 0x0000);
97162306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x001f, 0x0008);
97262306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0020, 0x00c1);
97362306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0021, 0x0034);
97462306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0022, 0x0034);
97562306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0025, 0x0002);
97662306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0028, 0x0022);
97762306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0029, 0x000a);
97862306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x002b, 0x0000);
97962306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x002c, 0x0000);
98062306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x002d, 0x00ff);
98162306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x002e, 0x00ff);
98262306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x002f, 0x00ff);
98362306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0030, 0x00ff);
98462306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0031, 0x00ff);
98562306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0032, 0x0007);
98662306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0033, 0x0005);
98762306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0037, 0x0040);
98862306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0039, 0x0000);
98962306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x003a, 0x0000);
99062306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x003b, 0x0001);
99162306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x003c, 0x0000);
99262306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0040, 0x000c);
99362306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0041, 0x00fb);
99462306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0042, 0x0002);
99562306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0043, 0x0000);
99662306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0045, 0x0000);
99762306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0046, 0x0000);
99862306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0047, 0x0000);
99962306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0048, 0x0000);
100062306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0049, 0x0000);
100162306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x004a, 0x00ff);
100262306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x004b, 0x00ff);
100362306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x004c, 0x00ff);
100462306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x004f, 0x0000);
100562306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0050, 0x0000);
100662306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0051, 0x0002);
100762306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0055, 0x0000);
100862306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0056, 0x0000);
100962306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0057, 0x0000);
101062306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0058, 0x0002);
101162306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0059, 0x0000);
101262306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x005c, 0x0016);
101362306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x005d, 0x0022);
101462306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x005e, 0x003c);
101562306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x005f, 0x0050);
101662306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0060, 0x0044);
101762306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0061, 0x0005);
101862306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x006a, 0x007e);
101962306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x006f, 0x0000);
102062306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0072, 0x001b);
102162306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0073, 0x0005);
102262306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0074, 0x000a);
102362306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0075, 0x001b);
102462306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0076, 0x002a);
102562306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0077, 0x003c);
102662306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0078, 0x0050);
102762306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x007b, 0x0000);
102862306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x007c, 0x0011);
102962306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x007d, 0x0024);
103062306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x007e, 0x0043);
103162306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x007f, 0x005a);
103262306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0084, 0x0020);
103362306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0085, 0x0033);
103462306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0086, 0x000a);
103562306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0087, 0x0030);
103662306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0088, 0x0070);
103762306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x008b, 0x0008);
103862306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x008f, 0x0000);
103962306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0090, 0x0006);
104062306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0091, 0x0028);
104162306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0092, 0x005a);
104262306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0093, 0x0082);
104362306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0096, 0x0014);
104462306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0097, 0x0020);
104562306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0098, 0x0000);
104662306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00b0, 0x0046);
104762306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00b1, 0x0000);
104862306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00b2, 0x0000);
104962306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00b3, 0x0004);
105062306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00b4, 0x0007);
105162306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00b6, 0x0002);
105262306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00b7, 0x0004);
105362306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00bb, 0x0000);
105462306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00bc, 0x0001);
105562306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00bd, 0x0000);
105662306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00bf, 0x0000);
105762306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00c0, 0x00c8);
105862306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00c1, 0x0014);
105962306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00c2, 0x0001);
106062306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00c3, 0x0000);
106162306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00c4, 0x0004);
106262306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00cb, 0x00bf);
106362306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00cc, 0x00bf);
106462306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00cd, 0x00bf);
106562306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00ce, 0x0000);
106662306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00cf, 0x0020);
106762306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00d0, 0x0040);
106862306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00d1, 0x00bf);
106962306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00d1, 0x00bf);
107062306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00d2, 0x00bf);
107162306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00d3, 0x00bf);
107262306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00ea, 0x0008);
107362306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00eb, 0x0000);
107462306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00ec, 0x00e8);
107562306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00ed, 0x0001);
107662306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00ef, 0x0022);
107762306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00f0, 0x0000);
107862306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00f2, 0x0028);
107962306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00f4, 0x0002);
108062306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00f5, 0x0000);
108162306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00fa, 0x0000);
108262306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00fb, 0x0001);
108362306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00fc, 0x0000);
108462306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00fd, 0x0000);
108562306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00fe, 0x0000);
108662306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00ff, 0x0000);
108762306a36Sopenharmony_ci
108862306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00be, 0x0003);
108962306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00c8, 0x0000);
109062306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00c9, 0x0020);
109162306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00ca, 0x0040);
109262306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0053, 0x0001);
109362306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0082, 0x000e);
109462306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0083, 0x0020);
109562306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0034, 0x003c);
109662306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x006e, 0x0055);
109762306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0062, 0x0005);
109862306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0063, 0x0008);
109962306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0066, 0x000a);
110062306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0067, 0x0006);
110162306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x006b, 0x0010);
110262306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x005a, 0x0001);
110362306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x005b, 0x000a);
110462306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0023, 0x0006);
110562306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0026, 0x0004);
110662306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0036, 0x0069);
110762306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0038, 0x0064);
110862306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x003d, 0x0003);
110962306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x003e, 0x0001);
111062306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00b8, 0x0014);
111162306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00b9, 0x0014);
111262306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00e6, 0x0004);
111362306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00e8, 0x0001);
111462306a36Sopenharmony_ci
111562306a36Sopenharmony_ci	return 0;
111662306a36Sopenharmony_ci}
111762306a36Sopenharmony_ci
111862306a36Sopenharmony_ci/* this function is called at probe and resume time */
111962306a36Sopenharmony_cistatic int sd_init(struct gspca_dev *gspca_dev)
112062306a36Sopenharmony_ci{
112162306a36Sopenharmony_ci	struct sd *sd = (struct sd *) gspca_dev;
112262306a36Sopenharmony_ci
112362306a36Sopenharmony_ci	switch (sd->model) {
112462306a36Sopenharmony_ci	case CIT_MODEL0:
112562306a36Sopenharmony_ci		cit_init_model0(gspca_dev);
112662306a36Sopenharmony_ci		sd_stop0(gspca_dev);
112762306a36Sopenharmony_ci		break;
112862306a36Sopenharmony_ci	case CIT_MODEL1:
112962306a36Sopenharmony_ci	case CIT_MODEL2:
113062306a36Sopenharmony_ci	case CIT_MODEL3:
113162306a36Sopenharmony_ci	case CIT_MODEL4:
113262306a36Sopenharmony_ci		break; /* All is done in sd_start */
113362306a36Sopenharmony_ci	case CIT_IBM_NETCAM_PRO:
113462306a36Sopenharmony_ci		cit_init_ibm_netcam_pro(gspca_dev);
113562306a36Sopenharmony_ci		sd_stop0(gspca_dev);
113662306a36Sopenharmony_ci		break;
113762306a36Sopenharmony_ci	}
113862306a36Sopenharmony_ci	return 0;
113962306a36Sopenharmony_ci}
114062306a36Sopenharmony_ci
114162306a36Sopenharmony_cistatic int cit_set_brightness(struct gspca_dev *gspca_dev, s32 val)
114262306a36Sopenharmony_ci{
114362306a36Sopenharmony_ci	struct sd *sd = (struct sd *) gspca_dev;
114462306a36Sopenharmony_ci	int i;
114562306a36Sopenharmony_ci
114662306a36Sopenharmony_ci	switch (sd->model) {
114762306a36Sopenharmony_ci	case CIT_MODEL0:
114862306a36Sopenharmony_ci	case CIT_IBM_NETCAM_PRO:
114962306a36Sopenharmony_ci		/* No (known) brightness control for these */
115062306a36Sopenharmony_ci		break;
115162306a36Sopenharmony_ci	case CIT_MODEL1:
115262306a36Sopenharmony_ci		/* Model 1: Brightness range 0 - 63 */
115362306a36Sopenharmony_ci		cit_Packet_Format1(gspca_dev, 0x0031, val);
115462306a36Sopenharmony_ci		cit_Packet_Format1(gspca_dev, 0x0032, val);
115562306a36Sopenharmony_ci		cit_Packet_Format1(gspca_dev, 0x0033, val);
115662306a36Sopenharmony_ci		break;
115762306a36Sopenharmony_ci	case CIT_MODEL2:
115862306a36Sopenharmony_ci		/* Model 2: Brightness range 0x60 - 0xee */
115962306a36Sopenharmony_ci		/* Scale 0 - 63 to 0x60 - 0xee */
116062306a36Sopenharmony_ci		i = 0x60 + val * 2254 / 1000;
116162306a36Sopenharmony_ci		cit_model2_Packet1(gspca_dev, 0x001a, i);
116262306a36Sopenharmony_ci		break;
116362306a36Sopenharmony_ci	case CIT_MODEL3:
116462306a36Sopenharmony_ci		/* Model 3: Brightness range 'i' in [0x0C..0x3F] */
116562306a36Sopenharmony_ci		i = val;
116662306a36Sopenharmony_ci		if (i < 0x0c)
116762306a36Sopenharmony_ci			i = 0x0c;
116862306a36Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x0036, i);
116962306a36Sopenharmony_ci		break;
117062306a36Sopenharmony_ci	case CIT_MODEL4:
117162306a36Sopenharmony_ci		/* Model 4: Brightness range 'i' in [0x04..0xb4] */
117262306a36Sopenharmony_ci		/* Scale 0 - 63 to 0x04 - 0xb4 */
117362306a36Sopenharmony_ci		i = 0x04 + val * 2794 / 1000;
117462306a36Sopenharmony_ci		cit_model4_BrightnessPacket(gspca_dev, i);
117562306a36Sopenharmony_ci		break;
117662306a36Sopenharmony_ci	}
117762306a36Sopenharmony_ci
117862306a36Sopenharmony_ci	return 0;
117962306a36Sopenharmony_ci}
118062306a36Sopenharmony_ci
118162306a36Sopenharmony_cistatic int cit_set_contrast(struct gspca_dev *gspca_dev, s32 val)
118262306a36Sopenharmony_ci{
118362306a36Sopenharmony_ci	struct sd *sd = (struct sd *) gspca_dev;
118462306a36Sopenharmony_ci
118562306a36Sopenharmony_ci	switch (sd->model) {
118662306a36Sopenharmony_ci	case CIT_MODEL0: {
118762306a36Sopenharmony_ci		int i;
118862306a36Sopenharmony_ci		/* gain 0-15, 0-20 -> 0-15 */
118962306a36Sopenharmony_ci		i = val * 1000 / 1333;
119062306a36Sopenharmony_ci		cit_write_reg(gspca_dev, i, 0x0422);
119162306a36Sopenharmony_ci		/* gain 0-31, may not be lower then 0x0422, 0-20 -> 0-31 */
119262306a36Sopenharmony_ci		i = val * 2000 / 1333;
119362306a36Sopenharmony_ci		cit_write_reg(gspca_dev, i, 0x0423);
119462306a36Sopenharmony_ci		/* gain 0-127, may not be lower then 0x0423, 0-20 -> 0-63  */
119562306a36Sopenharmony_ci		i = val * 4000 / 1333;
119662306a36Sopenharmony_ci		cit_write_reg(gspca_dev, i, 0x0424);
119762306a36Sopenharmony_ci		/* gain 0-127, may not be lower then 0x0424, , 0-20 -> 0-127 */
119862306a36Sopenharmony_ci		i = val * 8000 / 1333;
119962306a36Sopenharmony_ci		cit_write_reg(gspca_dev, i, 0x0425);
120062306a36Sopenharmony_ci		break;
120162306a36Sopenharmony_ci	}
120262306a36Sopenharmony_ci	case CIT_MODEL2:
120362306a36Sopenharmony_ci	case CIT_MODEL4:
120462306a36Sopenharmony_ci		/* These models do not have this control. */
120562306a36Sopenharmony_ci		break;
120662306a36Sopenharmony_ci	case CIT_MODEL1:
120762306a36Sopenharmony_ci	{
120862306a36Sopenharmony_ci		/* Scale 0 - 20 to 15 - 0 */
120962306a36Sopenharmony_ci		int i, new_contrast = (20 - val) * 1000 / 1333;
121062306a36Sopenharmony_ci		for (i = 0; i < cit_model1_ntries; i++) {
121162306a36Sopenharmony_ci			cit_Packet_Format1(gspca_dev, 0x0014, new_contrast);
121262306a36Sopenharmony_ci			cit_send_FF_04_02(gspca_dev);
121362306a36Sopenharmony_ci		}
121462306a36Sopenharmony_ci		break;
121562306a36Sopenharmony_ci	}
121662306a36Sopenharmony_ci	case CIT_MODEL3:
121762306a36Sopenharmony_ci	{	/* Preset hardware values */
121862306a36Sopenharmony_ci		static const struct {
121962306a36Sopenharmony_ci			unsigned short cv1;
122062306a36Sopenharmony_ci			unsigned short cv2;
122162306a36Sopenharmony_ci			unsigned short cv3;
122262306a36Sopenharmony_ci		} cv[7] = {
122362306a36Sopenharmony_ci			{ 0x05, 0x05, 0x0f },	/* Minimum */
122462306a36Sopenharmony_ci			{ 0x04, 0x04, 0x16 },
122562306a36Sopenharmony_ci			{ 0x02, 0x03, 0x16 },
122662306a36Sopenharmony_ci			{ 0x02, 0x08, 0x16 },
122762306a36Sopenharmony_ci			{ 0x01, 0x0c, 0x16 },
122862306a36Sopenharmony_ci			{ 0x01, 0x0e, 0x16 },
122962306a36Sopenharmony_ci			{ 0x01, 0x10, 0x16 }	/* Maximum */
123062306a36Sopenharmony_ci		};
123162306a36Sopenharmony_ci		int i = val / 3;
123262306a36Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x0067, cv[i].cv1);
123362306a36Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x005b, cv[i].cv2);
123462306a36Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x005c, cv[i].cv3);
123562306a36Sopenharmony_ci		break;
123662306a36Sopenharmony_ci	}
123762306a36Sopenharmony_ci	case CIT_IBM_NETCAM_PRO:
123862306a36Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x005b, val + 1);
123962306a36Sopenharmony_ci		break;
124062306a36Sopenharmony_ci	}
124162306a36Sopenharmony_ci	return 0;
124262306a36Sopenharmony_ci}
124362306a36Sopenharmony_ci
124462306a36Sopenharmony_cistatic int cit_set_hue(struct gspca_dev *gspca_dev, s32 val)
124562306a36Sopenharmony_ci{
124662306a36Sopenharmony_ci	struct sd *sd = (struct sd *) gspca_dev;
124762306a36Sopenharmony_ci
124862306a36Sopenharmony_ci	switch (sd->model) {
124962306a36Sopenharmony_ci	case CIT_MODEL0:
125062306a36Sopenharmony_ci	case CIT_MODEL1:
125162306a36Sopenharmony_ci	case CIT_IBM_NETCAM_PRO:
125262306a36Sopenharmony_ci		/* No hue control for these models */
125362306a36Sopenharmony_ci		break;
125462306a36Sopenharmony_ci	case CIT_MODEL2:
125562306a36Sopenharmony_ci		cit_model2_Packet1(gspca_dev, 0x0024, val);
125662306a36Sopenharmony_ci		/* cit_model2_Packet1(gspca_dev, 0x0020, sat); */
125762306a36Sopenharmony_ci		break;
125862306a36Sopenharmony_ci	case CIT_MODEL3: {
125962306a36Sopenharmony_ci		/* Model 3: Brightness range 'i' in [0x05..0x37] */
126062306a36Sopenharmony_ci		/* TESTME according to the ibmcam driver this does not work */
126162306a36Sopenharmony_ci		if (0) {
126262306a36Sopenharmony_ci			/* Scale 0 - 127 to 0x05 - 0x37 */
126362306a36Sopenharmony_ci			int i = 0x05 + val * 1000 / 2540;
126462306a36Sopenharmony_ci			cit_model3_Packet1(gspca_dev, 0x007e, i);
126562306a36Sopenharmony_ci		}
126662306a36Sopenharmony_ci		break;
126762306a36Sopenharmony_ci	}
126862306a36Sopenharmony_ci	case CIT_MODEL4:
126962306a36Sopenharmony_ci		/* HDG: taken from ibmcam, setting the color gains does not
127062306a36Sopenharmony_ci		 * really belong here.
127162306a36Sopenharmony_ci		 *
127262306a36Sopenharmony_ci		 * I am not sure r/g/b_gain variables exactly control gain
127362306a36Sopenharmony_ci		 * of those channels. Most likely they subtly change some
127462306a36Sopenharmony_ci		 * very internal image processing settings in the camera.
127562306a36Sopenharmony_ci		 * In any case, here is what they do, and feel free to tweak:
127662306a36Sopenharmony_ci		 *
127762306a36Sopenharmony_ci		 * r_gain: seriously affects red gain
127862306a36Sopenharmony_ci		 * g_gain: seriously affects green gain
127962306a36Sopenharmony_ci		 * b_gain: seriously affects blue gain
128062306a36Sopenharmony_ci		 * hue: changes average color from violet (0) to red (0xFF)
128162306a36Sopenharmony_ci		 */
128262306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
128362306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x001e, 0x012f);
128462306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd141, 0x0124);
128562306a36Sopenharmony_ci		cit_write_reg(gspca_dev,    160, 0x0127);  /* Green gain */
128662306a36Sopenharmony_ci		cit_write_reg(gspca_dev,    160, 0x012e);  /* Red gain */
128762306a36Sopenharmony_ci		cit_write_reg(gspca_dev,    160, 0x0130);  /* Blue gain */
128862306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x8a28, 0x0124);
128962306a36Sopenharmony_ci		cit_write_reg(gspca_dev, val, 0x012d); /* Hue */
129062306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xf545, 0x0124);
129162306a36Sopenharmony_ci		break;
129262306a36Sopenharmony_ci	}
129362306a36Sopenharmony_ci	return 0;
129462306a36Sopenharmony_ci}
129562306a36Sopenharmony_ci
129662306a36Sopenharmony_cistatic int cit_set_sharpness(struct gspca_dev *gspca_dev, s32 val)
129762306a36Sopenharmony_ci{
129862306a36Sopenharmony_ci	struct sd *sd = (struct sd *) gspca_dev;
129962306a36Sopenharmony_ci
130062306a36Sopenharmony_ci	switch (sd->model) {
130162306a36Sopenharmony_ci	case CIT_MODEL0:
130262306a36Sopenharmony_ci	case CIT_MODEL2:
130362306a36Sopenharmony_ci	case CIT_MODEL4:
130462306a36Sopenharmony_ci	case CIT_IBM_NETCAM_PRO:
130562306a36Sopenharmony_ci		/* These models do not have this control */
130662306a36Sopenharmony_ci		break;
130762306a36Sopenharmony_ci	case CIT_MODEL1: {
130862306a36Sopenharmony_ci		int i;
130962306a36Sopenharmony_ci		static const unsigned short sa[] = {
131062306a36Sopenharmony_ci			0x11, 0x13, 0x16, 0x18, 0x1a, 0x8, 0x0a };
131162306a36Sopenharmony_ci
131262306a36Sopenharmony_ci		for (i = 0; i < cit_model1_ntries; i++)
131362306a36Sopenharmony_ci			cit_PacketFormat2(gspca_dev, 0x0013, sa[val]);
131462306a36Sopenharmony_ci		break;
131562306a36Sopenharmony_ci	}
131662306a36Sopenharmony_ci	case CIT_MODEL3:
131762306a36Sopenharmony_ci	{	/*
131862306a36Sopenharmony_ci		 * "Use a table of magic numbers.
131962306a36Sopenharmony_ci		 *  This setting doesn't really change much.
132062306a36Sopenharmony_ci		 *  But that's how Windows does it."
132162306a36Sopenharmony_ci		 */
132262306a36Sopenharmony_ci		static const struct {
132362306a36Sopenharmony_ci			unsigned short sv1;
132462306a36Sopenharmony_ci			unsigned short sv2;
132562306a36Sopenharmony_ci			unsigned short sv3;
132662306a36Sopenharmony_ci			unsigned short sv4;
132762306a36Sopenharmony_ci		} sv[7] = {
132862306a36Sopenharmony_ci			{ 0x00, 0x00, 0x05, 0x14 },	/* Smoothest */
132962306a36Sopenharmony_ci			{ 0x01, 0x04, 0x05, 0x14 },
133062306a36Sopenharmony_ci			{ 0x02, 0x04, 0x05, 0x14 },
133162306a36Sopenharmony_ci			{ 0x03, 0x04, 0x05, 0x14 },
133262306a36Sopenharmony_ci			{ 0x03, 0x05, 0x05, 0x14 },
133362306a36Sopenharmony_ci			{ 0x03, 0x06, 0x05, 0x14 },
133462306a36Sopenharmony_ci			{ 0x03, 0x07, 0x05, 0x14 }	/* Sharpest */
133562306a36Sopenharmony_ci		};
133662306a36Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x0060, sv[val].sv1);
133762306a36Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x0061, sv[val].sv2);
133862306a36Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x0062, sv[val].sv3);
133962306a36Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x0063, sv[val].sv4);
134062306a36Sopenharmony_ci		break;
134162306a36Sopenharmony_ci	}
134262306a36Sopenharmony_ci	}
134362306a36Sopenharmony_ci	return 0;
134462306a36Sopenharmony_ci}
134562306a36Sopenharmony_ci
134662306a36Sopenharmony_ci/*
134762306a36Sopenharmony_ci * cit_set_lighting()
134862306a36Sopenharmony_ci *
134962306a36Sopenharmony_ci * Camera model 1:
135062306a36Sopenharmony_ci * We have 3 levels of lighting conditions: 0=Bright, 1=Medium, 2=Low.
135162306a36Sopenharmony_ci *
135262306a36Sopenharmony_ci * Camera model 2:
135362306a36Sopenharmony_ci * We have 16 levels of lighting, 0 for bright light and up to 15 for
135462306a36Sopenharmony_ci * low light. But values above 5 or so are useless because camera is
135562306a36Sopenharmony_ci * not really capable to produce anything worth viewing at such light.
135662306a36Sopenharmony_ci * This setting may be altered only in certain camera state.
135762306a36Sopenharmony_ci *
135862306a36Sopenharmony_ci * Low lighting forces slower FPS.
135962306a36Sopenharmony_ci *
136062306a36Sopenharmony_ci * History:
136162306a36Sopenharmony_ci * 1/5/00   Created.
136262306a36Sopenharmony_ci * 2/20/00  Added support for Model 2 cameras.
136362306a36Sopenharmony_ci */
136462306a36Sopenharmony_cistatic void cit_set_lighting(struct gspca_dev *gspca_dev, s32 val)
136562306a36Sopenharmony_ci{
136662306a36Sopenharmony_ci	struct sd *sd = (struct sd *) gspca_dev;
136762306a36Sopenharmony_ci
136862306a36Sopenharmony_ci	switch (sd->model) {
136962306a36Sopenharmony_ci	case CIT_MODEL0:
137062306a36Sopenharmony_ci	case CIT_MODEL2:
137162306a36Sopenharmony_ci	case CIT_MODEL3:
137262306a36Sopenharmony_ci	case CIT_MODEL4:
137362306a36Sopenharmony_ci	case CIT_IBM_NETCAM_PRO:
137462306a36Sopenharmony_ci		break;
137562306a36Sopenharmony_ci	case CIT_MODEL1: {
137662306a36Sopenharmony_ci		int i;
137762306a36Sopenharmony_ci		for (i = 0; i < cit_model1_ntries; i++)
137862306a36Sopenharmony_ci			cit_Packet_Format1(gspca_dev, 0x0027, val);
137962306a36Sopenharmony_ci		break;
138062306a36Sopenharmony_ci	}
138162306a36Sopenharmony_ci	}
138262306a36Sopenharmony_ci}
138362306a36Sopenharmony_ci
138462306a36Sopenharmony_cistatic void cit_set_hflip(struct gspca_dev *gspca_dev, s32 val)
138562306a36Sopenharmony_ci{
138662306a36Sopenharmony_ci	struct sd *sd = (struct sd *) gspca_dev;
138762306a36Sopenharmony_ci
138862306a36Sopenharmony_ci	switch (sd->model) {
138962306a36Sopenharmony_ci	case CIT_MODEL0:
139062306a36Sopenharmony_ci		if (val)
139162306a36Sopenharmony_ci			cit_write_reg(gspca_dev, 0x0020, 0x0115);
139262306a36Sopenharmony_ci		else
139362306a36Sopenharmony_ci			cit_write_reg(gspca_dev, 0x0040, 0x0115);
139462306a36Sopenharmony_ci		break;
139562306a36Sopenharmony_ci	case CIT_MODEL1:
139662306a36Sopenharmony_ci	case CIT_MODEL2:
139762306a36Sopenharmony_ci	case CIT_MODEL3:
139862306a36Sopenharmony_ci	case CIT_MODEL4:
139962306a36Sopenharmony_ci	case CIT_IBM_NETCAM_PRO:
140062306a36Sopenharmony_ci		break;
140162306a36Sopenharmony_ci	}
140262306a36Sopenharmony_ci}
140362306a36Sopenharmony_ci
140462306a36Sopenharmony_cistatic int cit_restart_stream(struct gspca_dev *gspca_dev)
140562306a36Sopenharmony_ci{
140662306a36Sopenharmony_ci	struct sd *sd = (struct sd *) gspca_dev;
140762306a36Sopenharmony_ci
140862306a36Sopenharmony_ci	switch (sd->model) {
140962306a36Sopenharmony_ci	case CIT_MODEL0:
141062306a36Sopenharmony_ci	case CIT_MODEL1:
141162306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0001, 0x0114);
141262306a36Sopenharmony_ci		fallthrough;
141362306a36Sopenharmony_ci	case CIT_MODEL2:
141462306a36Sopenharmony_ci	case CIT_MODEL4:
141562306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00c0, 0x010c); /* Go! */
141662306a36Sopenharmony_ci		usb_clear_halt(gspca_dev->dev, gspca_dev->urb[0]->pipe);
141762306a36Sopenharmony_ci		break;
141862306a36Sopenharmony_ci	case CIT_MODEL3:
141962306a36Sopenharmony_ci	case CIT_IBM_NETCAM_PRO:
142062306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0001, 0x0114);
142162306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00c0, 0x010c); /* Go! */
142262306a36Sopenharmony_ci		usb_clear_halt(gspca_dev->dev, gspca_dev->urb[0]->pipe);
142362306a36Sopenharmony_ci		/* Clear button events from while we were not streaming */
142462306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0001, 0x0113);
142562306a36Sopenharmony_ci		break;
142662306a36Sopenharmony_ci	}
142762306a36Sopenharmony_ci
142862306a36Sopenharmony_ci	sd->sof_read = 0;
142962306a36Sopenharmony_ci
143062306a36Sopenharmony_ci	return 0;
143162306a36Sopenharmony_ci}
143262306a36Sopenharmony_ci
143362306a36Sopenharmony_cistatic int cit_get_packet_size(struct gspca_dev *gspca_dev)
143462306a36Sopenharmony_ci{
143562306a36Sopenharmony_ci	struct usb_host_interface *alt;
143662306a36Sopenharmony_ci	struct usb_interface *intf;
143762306a36Sopenharmony_ci
143862306a36Sopenharmony_ci	intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface);
143962306a36Sopenharmony_ci	alt = usb_altnum_to_altsetting(intf, gspca_dev->alt);
144062306a36Sopenharmony_ci	if (!alt) {
144162306a36Sopenharmony_ci		pr_err("Couldn't get altsetting\n");
144262306a36Sopenharmony_ci		return -EIO;
144362306a36Sopenharmony_ci	}
144462306a36Sopenharmony_ci
144562306a36Sopenharmony_ci	if (alt->desc.bNumEndpoints < 1)
144662306a36Sopenharmony_ci		return -ENODEV;
144762306a36Sopenharmony_ci
144862306a36Sopenharmony_ci	return le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
144962306a36Sopenharmony_ci}
145062306a36Sopenharmony_ci
145162306a36Sopenharmony_ci/* Calculate the clockdiv giving us max fps given the available bandwidth */
145262306a36Sopenharmony_cistatic int cit_get_clock_div(struct gspca_dev *gspca_dev)
145362306a36Sopenharmony_ci{
145462306a36Sopenharmony_ci	int clock_div = 7; /* 0=30 1=25 2=20 3=15 4=12 5=7.5 6=6 7=3fps ?? */
145562306a36Sopenharmony_ci	int fps[8] = { 30, 25, 20, 15, 12, 8, 6, 3 };
145662306a36Sopenharmony_ci	int packet_size;
145762306a36Sopenharmony_ci
145862306a36Sopenharmony_ci	packet_size = cit_get_packet_size(gspca_dev);
145962306a36Sopenharmony_ci	if (packet_size < 0)
146062306a36Sopenharmony_ci		return packet_size;
146162306a36Sopenharmony_ci
146262306a36Sopenharmony_ci	while (clock_div > 3 &&
146362306a36Sopenharmony_ci			1000 * packet_size >
146462306a36Sopenharmony_ci			gspca_dev->pixfmt.width * gspca_dev->pixfmt.height *
146562306a36Sopenharmony_ci			fps[clock_div - 1] * 3 / 2)
146662306a36Sopenharmony_ci		clock_div--;
146762306a36Sopenharmony_ci
146862306a36Sopenharmony_ci	gspca_dbg(gspca_dev, D_PROBE,
146962306a36Sopenharmony_ci		  "PacketSize: %d, res: %dx%d -> using clockdiv: %d (%d fps)\n",
147062306a36Sopenharmony_ci		  packet_size,
147162306a36Sopenharmony_ci		  gspca_dev->pixfmt.width, gspca_dev->pixfmt.height,
147262306a36Sopenharmony_ci		  clock_div, fps[clock_div]);
147362306a36Sopenharmony_ci
147462306a36Sopenharmony_ci	return clock_div;
147562306a36Sopenharmony_ci}
147662306a36Sopenharmony_ci
147762306a36Sopenharmony_cistatic int cit_start_model0(struct gspca_dev *gspca_dev)
147862306a36Sopenharmony_ci{
147962306a36Sopenharmony_ci	const unsigned short compression = 0; /* 0=none, 7=best frame rate */
148062306a36Sopenharmony_ci	int clock_div;
148162306a36Sopenharmony_ci
148262306a36Sopenharmony_ci	clock_div = cit_get_clock_div(gspca_dev);
148362306a36Sopenharmony_ci	if (clock_div < 0)
148462306a36Sopenharmony_ci		return clock_div;
148562306a36Sopenharmony_ci
148662306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0100); /* turn on led */
148762306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0003, 0x0438);
148862306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x001e, 0x042b);
148962306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0041, 0x042c);
149062306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0008, 0x0436);
149162306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0024, 0x0403);
149262306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x002c, 0x0404);
149362306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0002, 0x0426);
149462306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0014, 0x0427);
149562306a36Sopenharmony_ci
149662306a36Sopenharmony_ci	switch (gspca_dev->pixfmt.width) {
149762306a36Sopenharmony_ci	case 160: /* 160x120 */
149862306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0004, 0x010b);
149962306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0001, 0x010a);
150062306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0010, 0x0102);
150162306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00a0, 0x0103);
150262306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0104);
150362306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0078, 0x0105);
150462306a36Sopenharmony_ci		break;
150562306a36Sopenharmony_ci
150662306a36Sopenharmony_ci	case 176: /* 176x144 */
150762306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0006, 0x010b);
150862306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x010a);
150962306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0005, 0x0102);
151062306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00b0, 0x0103);
151162306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0104);
151262306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0090, 0x0105);
151362306a36Sopenharmony_ci		break;
151462306a36Sopenharmony_ci
151562306a36Sopenharmony_ci	case 320: /* 320x240 */
151662306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0008, 0x010b);
151762306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0004, 0x010a);
151862306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0005, 0x0102);
151962306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00a0, 0x0103);
152062306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0010, 0x0104);
152162306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0078, 0x0105);
152262306a36Sopenharmony_ci		break;
152362306a36Sopenharmony_ci	}
152462306a36Sopenharmony_ci
152562306a36Sopenharmony_ci	cit_write_reg(gspca_dev, compression, 0x0109);
152662306a36Sopenharmony_ci	cit_write_reg(gspca_dev, clock_div, 0x0111);
152762306a36Sopenharmony_ci
152862306a36Sopenharmony_ci	return 0;
152962306a36Sopenharmony_ci}
153062306a36Sopenharmony_ci
153162306a36Sopenharmony_cistatic int cit_start_model1(struct gspca_dev *gspca_dev)
153262306a36Sopenharmony_ci{
153362306a36Sopenharmony_ci	struct sd *sd = (struct sd *) gspca_dev;
153462306a36Sopenharmony_ci	int i, clock_div;
153562306a36Sopenharmony_ci
153662306a36Sopenharmony_ci	clock_div = cit_get_clock_div(gspca_dev);
153762306a36Sopenharmony_ci	if (clock_div < 0)
153862306a36Sopenharmony_ci		return clock_div;
153962306a36Sopenharmony_ci
154062306a36Sopenharmony_ci	cit_read_reg(gspca_dev, 0x0128, 1);
154162306a36Sopenharmony_ci	cit_read_reg(gspca_dev, 0x0100, 0);
154262306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x01, 0x0100);	/* LED On  */
154362306a36Sopenharmony_ci	cit_read_reg(gspca_dev, 0x0100, 0);
154462306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x81, 0x0100);	/* LED Off */
154562306a36Sopenharmony_ci	cit_read_reg(gspca_dev, 0x0100, 0);
154662306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x01, 0x0100);	/* LED On  */
154762306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x01, 0x0108);
154862306a36Sopenharmony_ci
154962306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x03, 0x0112);
155062306a36Sopenharmony_ci	cit_read_reg(gspca_dev, 0x0115, 0);
155162306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x06, 0x0115);
155262306a36Sopenharmony_ci	cit_read_reg(gspca_dev, 0x0116, 0);
155362306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x44, 0x0116);
155462306a36Sopenharmony_ci	cit_read_reg(gspca_dev, 0x0116, 0);
155562306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x40, 0x0116);
155662306a36Sopenharmony_ci	cit_read_reg(gspca_dev, 0x0115, 0);
155762306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0e, 0x0115);
155862306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x19, 0x012c);
155962306a36Sopenharmony_ci
156062306a36Sopenharmony_ci	cit_Packet_Format1(gspca_dev, 0x00, 0x1e);
156162306a36Sopenharmony_ci	cit_Packet_Format1(gspca_dev, 0x39, 0x0d);
156262306a36Sopenharmony_ci	cit_Packet_Format1(gspca_dev, 0x39, 0x09);
156362306a36Sopenharmony_ci	cit_Packet_Format1(gspca_dev, 0x3b, 0x00);
156462306a36Sopenharmony_ci	cit_Packet_Format1(gspca_dev, 0x28, 0x22);
156562306a36Sopenharmony_ci	cit_Packet_Format1(gspca_dev, 0x27, 0x00);
156662306a36Sopenharmony_ci	cit_Packet_Format1(gspca_dev, 0x2b, 0x1f);
156762306a36Sopenharmony_ci	cit_Packet_Format1(gspca_dev, 0x39, 0x08);
156862306a36Sopenharmony_ci
156962306a36Sopenharmony_ci	for (i = 0; i < cit_model1_ntries; i++)
157062306a36Sopenharmony_ci		cit_Packet_Format1(gspca_dev, 0x2c, 0x00);
157162306a36Sopenharmony_ci
157262306a36Sopenharmony_ci	for (i = 0; i < cit_model1_ntries; i++)
157362306a36Sopenharmony_ci		cit_Packet_Format1(gspca_dev, 0x30, 0x14);
157462306a36Sopenharmony_ci
157562306a36Sopenharmony_ci	cit_PacketFormat2(gspca_dev, 0x39, 0x02);
157662306a36Sopenharmony_ci	cit_PacketFormat2(gspca_dev, 0x01, 0xe1);
157762306a36Sopenharmony_ci	cit_PacketFormat2(gspca_dev, 0x02, 0xcd);
157862306a36Sopenharmony_ci	cit_PacketFormat2(gspca_dev, 0x03, 0xcd);
157962306a36Sopenharmony_ci	cit_PacketFormat2(gspca_dev, 0x04, 0xfa);
158062306a36Sopenharmony_ci	cit_PacketFormat2(gspca_dev, 0x3f, 0xff);
158162306a36Sopenharmony_ci	cit_PacketFormat2(gspca_dev, 0x39, 0x00);
158262306a36Sopenharmony_ci
158362306a36Sopenharmony_ci	cit_PacketFormat2(gspca_dev, 0x39, 0x02);
158462306a36Sopenharmony_ci	cit_PacketFormat2(gspca_dev, 0x0a, 0x37);
158562306a36Sopenharmony_ci	cit_PacketFormat2(gspca_dev, 0x0b, 0xb8);
158662306a36Sopenharmony_ci	cit_PacketFormat2(gspca_dev, 0x0c, 0xf3);
158762306a36Sopenharmony_ci	cit_PacketFormat2(gspca_dev, 0x0d, 0xe3);
158862306a36Sopenharmony_ci	cit_PacketFormat2(gspca_dev, 0x0e, 0x0d);
158962306a36Sopenharmony_ci	cit_PacketFormat2(gspca_dev, 0x0f, 0xf2);
159062306a36Sopenharmony_ci	cit_PacketFormat2(gspca_dev, 0x10, 0xd5);
159162306a36Sopenharmony_ci	cit_PacketFormat2(gspca_dev, 0x11, 0xba);
159262306a36Sopenharmony_ci	cit_PacketFormat2(gspca_dev, 0x12, 0x53);
159362306a36Sopenharmony_ci	cit_PacketFormat2(gspca_dev, 0x3f, 0xff);
159462306a36Sopenharmony_ci	cit_PacketFormat2(gspca_dev, 0x39, 0x00);
159562306a36Sopenharmony_ci
159662306a36Sopenharmony_ci	cit_PacketFormat2(gspca_dev, 0x39, 0x02);
159762306a36Sopenharmony_ci	cit_PacketFormat2(gspca_dev, 0x16, 0x00);
159862306a36Sopenharmony_ci	cit_PacketFormat2(gspca_dev, 0x17, 0x28);
159962306a36Sopenharmony_ci	cit_PacketFormat2(gspca_dev, 0x18, 0x7d);
160062306a36Sopenharmony_ci	cit_PacketFormat2(gspca_dev, 0x19, 0xbe);
160162306a36Sopenharmony_ci	cit_PacketFormat2(gspca_dev, 0x3f, 0xff);
160262306a36Sopenharmony_ci	cit_PacketFormat2(gspca_dev, 0x39, 0x00);
160362306a36Sopenharmony_ci
160462306a36Sopenharmony_ci	for (i = 0; i < cit_model1_ntries; i++)
160562306a36Sopenharmony_ci		cit_Packet_Format1(gspca_dev, 0x00, 0x18);
160662306a36Sopenharmony_ci	for (i = 0; i < cit_model1_ntries; i++)
160762306a36Sopenharmony_ci		cit_Packet_Format1(gspca_dev, 0x13, 0x18);
160862306a36Sopenharmony_ci	for (i = 0; i < cit_model1_ntries; i++)
160962306a36Sopenharmony_ci		cit_Packet_Format1(gspca_dev, 0x14, 0x06);
161062306a36Sopenharmony_ci
161162306a36Sopenharmony_ci	/* TESTME These are handled through controls
161262306a36Sopenharmony_ci	   KEEP until someone can test leaving this out is ok */
161362306a36Sopenharmony_ci	if (0) {
161462306a36Sopenharmony_ci		/* This is default brightness */
161562306a36Sopenharmony_ci		for (i = 0; i < cit_model1_ntries; i++)
161662306a36Sopenharmony_ci			cit_Packet_Format1(gspca_dev, 0x31, 0x37);
161762306a36Sopenharmony_ci		for (i = 0; i < cit_model1_ntries; i++)
161862306a36Sopenharmony_ci			cit_Packet_Format1(gspca_dev, 0x32, 0x46);
161962306a36Sopenharmony_ci		for (i = 0; i < cit_model1_ntries; i++)
162062306a36Sopenharmony_ci			cit_Packet_Format1(gspca_dev, 0x33, 0x55);
162162306a36Sopenharmony_ci	}
162262306a36Sopenharmony_ci
162362306a36Sopenharmony_ci	cit_Packet_Format1(gspca_dev, 0x2e, 0x04);
162462306a36Sopenharmony_ci	for (i = 0; i < cit_model1_ntries; i++)
162562306a36Sopenharmony_ci		cit_Packet_Format1(gspca_dev, 0x2d, 0x04);
162662306a36Sopenharmony_ci	for (i = 0; i < cit_model1_ntries; i++)
162762306a36Sopenharmony_ci		cit_Packet_Format1(gspca_dev, 0x29, 0x80);
162862306a36Sopenharmony_ci	cit_Packet_Format1(gspca_dev, 0x2c, 0x01);
162962306a36Sopenharmony_ci	cit_Packet_Format1(gspca_dev, 0x30, 0x17);
163062306a36Sopenharmony_ci	cit_Packet_Format1(gspca_dev, 0x39, 0x08);
163162306a36Sopenharmony_ci	for (i = 0; i < cit_model1_ntries; i++)
163262306a36Sopenharmony_ci		cit_Packet_Format1(gspca_dev, 0x34, 0x00);
163362306a36Sopenharmony_ci
163462306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x00, 0x0101);
163562306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x00, 0x010a);
163662306a36Sopenharmony_ci
163762306a36Sopenharmony_ci	switch (gspca_dev->pixfmt.width) {
163862306a36Sopenharmony_ci	case 128: /* 128x96 */
163962306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x80, 0x0103);
164062306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x60, 0x0105);
164162306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0c, 0x010b);
164262306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x04, 0x011b);	/* Same everywhere */
164362306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0b, 0x011d);
164462306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00, 0x011e);	/* Same everywhere */
164562306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00, 0x0129);
164662306a36Sopenharmony_ci		break;
164762306a36Sopenharmony_ci	case 176: /* 176x144 */
164862306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xb0, 0x0103);
164962306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x8f, 0x0105);
165062306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x06, 0x010b);
165162306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x04, 0x011b);	/* Same everywhere */
165262306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0d, 0x011d);
165362306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00, 0x011e);	/* Same everywhere */
165462306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x03, 0x0129);
165562306a36Sopenharmony_ci		break;
165662306a36Sopenharmony_ci	case 352: /* 352x288 */
165762306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xb0, 0x0103);
165862306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x90, 0x0105);
165962306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x02, 0x010b);
166062306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x04, 0x011b);	/* Same everywhere */
166162306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x05, 0x011d);
166262306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00, 0x011e);	/* Same everywhere */
166362306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00, 0x0129);
166462306a36Sopenharmony_ci		break;
166562306a36Sopenharmony_ci	}
166662306a36Sopenharmony_ci
166762306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0xff, 0x012b);
166862306a36Sopenharmony_ci
166962306a36Sopenharmony_ci	/* TESTME These are handled through controls
167062306a36Sopenharmony_ci	   KEEP until someone can test leaving this out is ok */
167162306a36Sopenharmony_ci	if (0) {
167262306a36Sopenharmony_ci		/* This is another brightness - don't know why */
167362306a36Sopenharmony_ci		for (i = 0; i < cit_model1_ntries; i++)
167462306a36Sopenharmony_ci			cit_Packet_Format1(gspca_dev, 0x31, 0xc3);
167562306a36Sopenharmony_ci		for (i = 0; i < cit_model1_ntries; i++)
167662306a36Sopenharmony_ci			cit_Packet_Format1(gspca_dev, 0x32, 0xd2);
167762306a36Sopenharmony_ci		for (i = 0; i < cit_model1_ntries; i++)
167862306a36Sopenharmony_ci			cit_Packet_Format1(gspca_dev, 0x33, 0xe1);
167962306a36Sopenharmony_ci
168062306a36Sopenharmony_ci		/* Default contrast */
168162306a36Sopenharmony_ci		for (i = 0; i < cit_model1_ntries; i++)
168262306a36Sopenharmony_ci			cit_Packet_Format1(gspca_dev, 0x14, 0x0a);
168362306a36Sopenharmony_ci
168462306a36Sopenharmony_ci		/* Default sharpness */
168562306a36Sopenharmony_ci		for (i = 0; i < cit_model1_ntries2; i++)
168662306a36Sopenharmony_ci			cit_PacketFormat2(gspca_dev, 0x13, 0x1a);
168762306a36Sopenharmony_ci
168862306a36Sopenharmony_ci		/* Default lighting conditions */
168962306a36Sopenharmony_ci		cit_Packet_Format1(gspca_dev, 0x0027,
169062306a36Sopenharmony_ci				   v4l2_ctrl_g_ctrl(sd->lighting));
169162306a36Sopenharmony_ci	}
169262306a36Sopenharmony_ci
169362306a36Sopenharmony_ci	/* Assorted init */
169462306a36Sopenharmony_ci	switch (gspca_dev->pixfmt.width) {
169562306a36Sopenharmony_ci	case 128: /* 128x96 */
169662306a36Sopenharmony_ci		cit_Packet_Format1(gspca_dev, 0x2b, 0x1e);
169762306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xc9, 0x0119);	/* Same everywhere */
169862306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x80, 0x0109);	/* Same everywhere */
169962306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x36, 0x0102);
170062306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x1a, 0x0104);
170162306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x04, 0x011a);	/* Same everywhere */
170262306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x2b, 0x011c);
170362306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x23, 0x012a);	/* Same everywhere */
170462306a36Sopenharmony_ci		break;
170562306a36Sopenharmony_ci	case 176: /* 176x144 */
170662306a36Sopenharmony_ci		cit_Packet_Format1(gspca_dev, 0x2b, 0x1e);
170762306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xc9, 0x0119);	/* Same everywhere */
170862306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x80, 0x0109);	/* Same everywhere */
170962306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x04, 0x0102);
171062306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x02, 0x0104);
171162306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x04, 0x011a);	/* Same everywhere */
171262306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x2b, 0x011c);
171362306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x23, 0x012a);	/* Same everywhere */
171462306a36Sopenharmony_ci		break;
171562306a36Sopenharmony_ci	case 352: /* 352x288 */
171662306a36Sopenharmony_ci		cit_Packet_Format1(gspca_dev, 0x2b, 0x1f);
171762306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xc9, 0x0119);	/* Same everywhere */
171862306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x80, 0x0109);	/* Same everywhere */
171962306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x08, 0x0102);
172062306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x01, 0x0104);
172162306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x04, 0x011a);	/* Same everywhere */
172262306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x2f, 0x011c);
172362306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x23, 0x012a);	/* Same everywhere */
172462306a36Sopenharmony_ci		break;
172562306a36Sopenharmony_ci	}
172662306a36Sopenharmony_ci
172762306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x01, 0x0100);	/* LED On  */
172862306a36Sopenharmony_ci	cit_write_reg(gspca_dev, clock_div, 0x0111);
172962306a36Sopenharmony_ci
173062306a36Sopenharmony_ci	return 0;
173162306a36Sopenharmony_ci}
173262306a36Sopenharmony_ci
173362306a36Sopenharmony_cistatic int cit_start_model2(struct gspca_dev *gspca_dev)
173462306a36Sopenharmony_ci{
173562306a36Sopenharmony_ci	struct sd *sd = (struct sd *) gspca_dev;
173662306a36Sopenharmony_ci	int clock_div = 0;
173762306a36Sopenharmony_ci
173862306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0100);	/* LED on */
173962306a36Sopenharmony_ci	cit_read_reg(gspca_dev, 0x0116, 0);
174062306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0060, 0x0116);
174162306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0002, 0x0112);
174262306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x00bc, 0x012c);
174362306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0008, 0x012b);
174462306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0108);
174562306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0001, 0x0133);
174662306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0001, 0x0102);
174762306a36Sopenharmony_ci	switch (gspca_dev->pixfmt.width) {
174862306a36Sopenharmony_ci	case 176: /* 176x144 */
174962306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x002c, 0x0103);	/* All except 320x240 */
175062306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0104);	/* Same */
175162306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0024, 0x0105);	/* 176x144, 352x288 */
175262306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00b9, 0x010a);	/* Unique to this mode */
175362306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0038, 0x0119);	/* Unique to this mode */
175462306a36Sopenharmony_ci		/* TESTME HDG: this does not seem right
175562306a36Sopenharmony_ci		   (it is 2 for all other resolutions) */
175662306a36Sopenharmony_ci		sd->sof_len = 10;
175762306a36Sopenharmony_ci		break;
175862306a36Sopenharmony_ci	case 320: /* 320x240 */
175962306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0028, 0x0103);	/* Unique to this mode */
176062306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0104);	/* Same */
176162306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x001e, 0x0105);	/* 320x240, 352x240 */
176262306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0039, 0x010a);	/* All except 176x144 */
176362306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0070, 0x0119);	/* All except 176x144 */
176462306a36Sopenharmony_ci		sd->sof_len = 2;
176562306a36Sopenharmony_ci		break;
176662306a36Sopenharmony_ci#if 0
176762306a36Sopenharmony_ci	case VIDEOSIZE_352x240:
176862306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x002c, 0x0103);	/* All except 320x240 */
176962306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0104);	/* Same */
177062306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x001e, 0x0105);	/* 320x240, 352x240 */
177162306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0039, 0x010a);	/* All except 176x144 */
177262306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0070, 0x0119);	/* All except 176x144 */
177362306a36Sopenharmony_ci		sd->sof_len = 2;
177462306a36Sopenharmony_ci		break;
177562306a36Sopenharmony_ci#endif
177662306a36Sopenharmony_ci	case 352: /* 352x288 */
177762306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x002c, 0x0103);	/* All except 320x240 */
177862306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0104);	/* Same */
177962306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0024, 0x0105);	/* 176x144, 352x288 */
178062306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0039, 0x010a);	/* All except 176x144 */
178162306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0070, 0x0119);	/* All except 176x144 */
178262306a36Sopenharmony_ci		sd->sof_len = 2;
178362306a36Sopenharmony_ci		break;
178462306a36Sopenharmony_ci	}
178562306a36Sopenharmony_ci
178662306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0100);	/* LED on */
178762306a36Sopenharmony_ci
178862306a36Sopenharmony_ci	switch (gspca_dev->pixfmt.width) {
178962306a36Sopenharmony_ci	case 176: /* 176x144 */
179062306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0050, 0x0111);
179162306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00d0, 0x0111);
179262306a36Sopenharmony_ci		break;
179362306a36Sopenharmony_ci	case 320: /* 320x240 */
179462306a36Sopenharmony_ci	case 352: /* 352x288 */
179562306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0040, 0x0111);
179662306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00c0, 0x0111);
179762306a36Sopenharmony_ci		break;
179862306a36Sopenharmony_ci	}
179962306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x009b, 0x010f);
180062306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x00bb, 0x010f);
180162306a36Sopenharmony_ci
180262306a36Sopenharmony_ci	/*
180362306a36Sopenharmony_ci	 * Hardware settings, may affect CMOS sensor; not user controls!
180462306a36Sopenharmony_ci	 * -------------------------------------------------------------
180562306a36Sopenharmony_ci	 * 0x0004: no effect
180662306a36Sopenharmony_ci	 * 0x0006: hardware effect
180762306a36Sopenharmony_ci	 * 0x0008: no effect
180862306a36Sopenharmony_ci	 * 0x000a: stops video stream, probably important h/w setting
180962306a36Sopenharmony_ci	 * 0x000c: changes color in hardware manner (not user setting)
181062306a36Sopenharmony_ci	 * 0x0012: changes number of colors (does not affect speed)
181162306a36Sopenharmony_ci	 * 0x002a: no effect
181262306a36Sopenharmony_ci	 * 0x002c: hardware setting (related to scan lines)
181362306a36Sopenharmony_ci	 * 0x002e: stops video stream, probably important h/w setting
181462306a36Sopenharmony_ci	 */
181562306a36Sopenharmony_ci	cit_model2_Packet1(gspca_dev, 0x000a, 0x005c);
181662306a36Sopenharmony_ci	cit_model2_Packet1(gspca_dev, 0x0004, 0x0000);
181762306a36Sopenharmony_ci	cit_model2_Packet1(gspca_dev, 0x0006, 0x00fb);
181862306a36Sopenharmony_ci	cit_model2_Packet1(gspca_dev, 0x0008, 0x0000);
181962306a36Sopenharmony_ci	cit_model2_Packet1(gspca_dev, 0x000c, 0x0009);
182062306a36Sopenharmony_ci	cit_model2_Packet1(gspca_dev, 0x0012, 0x000a);
182162306a36Sopenharmony_ci	cit_model2_Packet1(gspca_dev, 0x002a, 0x0000);
182262306a36Sopenharmony_ci	cit_model2_Packet1(gspca_dev, 0x002c, 0x0000);
182362306a36Sopenharmony_ci	cit_model2_Packet1(gspca_dev, 0x002e, 0x0008);
182462306a36Sopenharmony_ci
182562306a36Sopenharmony_ci	/*
182662306a36Sopenharmony_ci	 * Function 0x0030 pops up all over the place. Apparently
182762306a36Sopenharmony_ci	 * it is a hardware control register, with every bit assigned to
182862306a36Sopenharmony_ci	 * do something.
182962306a36Sopenharmony_ci	 */
183062306a36Sopenharmony_ci	cit_model2_Packet1(gspca_dev, 0x0030, 0x0000);
183162306a36Sopenharmony_ci
183262306a36Sopenharmony_ci	/*
183362306a36Sopenharmony_ci	 * Magic control of CMOS sensor. Only lower values like
183462306a36Sopenharmony_ci	 * 0-3 work, and picture shifts left or right. Don't change.
183562306a36Sopenharmony_ci	 */
183662306a36Sopenharmony_ci	switch (gspca_dev->pixfmt.width) {
183762306a36Sopenharmony_ci	case 176: /* 176x144 */
183862306a36Sopenharmony_ci		cit_model2_Packet1(gspca_dev, 0x0014, 0x0002);
183962306a36Sopenharmony_ci		cit_model2_Packet1(gspca_dev, 0x0016, 0x0002); /* Horizontal shift */
184062306a36Sopenharmony_ci		cit_model2_Packet1(gspca_dev, 0x0018, 0x004a); /* Another hardware setting */
184162306a36Sopenharmony_ci		clock_div = 6;
184262306a36Sopenharmony_ci		break;
184362306a36Sopenharmony_ci	case 320: /* 320x240 */
184462306a36Sopenharmony_ci		cit_model2_Packet1(gspca_dev, 0x0014, 0x0009);
184562306a36Sopenharmony_ci		cit_model2_Packet1(gspca_dev, 0x0016, 0x0005); /* Horizontal shift */
184662306a36Sopenharmony_ci		cit_model2_Packet1(gspca_dev, 0x0018, 0x0044); /* Another hardware setting */
184762306a36Sopenharmony_ci		clock_div = 8;
184862306a36Sopenharmony_ci		break;
184962306a36Sopenharmony_ci#if 0
185062306a36Sopenharmony_ci	case VIDEOSIZE_352x240:
185162306a36Sopenharmony_ci		/* This mode doesn't work as Windows programs it; changed to work */
185262306a36Sopenharmony_ci		cit_model2_Packet1(gspca_dev, 0x0014, 0x0009); /* Windows sets this to 8 */
185362306a36Sopenharmony_ci		cit_model2_Packet1(gspca_dev, 0x0016, 0x0003); /* Horizontal shift */
185462306a36Sopenharmony_ci		cit_model2_Packet1(gspca_dev, 0x0018, 0x0044); /* Windows sets this to 0x0045 */
185562306a36Sopenharmony_ci		clock_div = 10;
185662306a36Sopenharmony_ci		break;
185762306a36Sopenharmony_ci#endif
185862306a36Sopenharmony_ci	case 352: /* 352x288 */
185962306a36Sopenharmony_ci		cit_model2_Packet1(gspca_dev, 0x0014, 0x0003);
186062306a36Sopenharmony_ci		cit_model2_Packet1(gspca_dev, 0x0016, 0x0002); /* Horizontal shift */
186162306a36Sopenharmony_ci		cit_model2_Packet1(gspca_dev, 0x0018, 0x004a); /* Another hardware setting */
186262306a36Sopenharmony_ci		clock_div = 16;
186362306a36Sopenharmony_ci		break;
186462306a36Sopenharmony_ci	}
186562306a36Sopenharmony_ci
186662306a36Sopenharmony_ci	/* TESTME These are handled through controls
186762306a36Sopenharmony_ci	   KEEP until someone can test leaving this out is ok */
186862306a36Sopenharmony_ci	if (0)
186962306a36Sopenharmony_ci		cit_model2_Packet1(gspca_dev, 0x001a, 0x005a);
187062306a36Sopenharmony_ci
187162306a36Sopenharmony_ci	/*
187262306a36Sopenharmony_ci	 * We have our own frame rate setting varying from 0 (slowest) to 6
187362306a36Sopenharmony_ci	 * (fastest). The camera model 2 allows frame rate in range [0..0x1F]
187462306a36Sopenharmony_ci	 # where 0 is also the slowest setting. However for all practical
187562306a36Sopenharmony_ci	 # reasons high settings make no sense because USB is not fast enough
187662306a36Sopenharmony_ci	 # to support high FPS. Be aware that the picture datastream will be
187762306a36Sopenharmony_ci	 # severely disrupted if you ask for frame rate faster than allowed
187862306a36Sopenharmony_ci	 # for the video size - see below:
187962306a36Sopenharmony_ci	 *
188062306a36Sopenharmony_ci	 * Allowable ranges (obtained experimentally on OHCI, K6-3, 450 MHz):
188162306a36Sopenharmony_ci	 * -----------------------------------------------------------------
188262306a36Sopenharmony_ci	 * 176x144: [6..31]
188362306a36Sopenharmony_ci	 * 320x240: [8..31]
188462306a36Sopenharmony_ci	 * 352x240: [10..31]
188562306a36Sopenharmony_ci	 * 352x288: [16..31] I have to raise lower threshold for stability...
188662306a36Sopenharmony_ci	 *
188762306a36Sopenharmony_ci	 * As usual, slower FPS provides better sensitivity.
188862306a36Sopenharmony_ci	 */
188962306a36Sopenharmony_ci	cit_model2_Packet1(gspca_dev, 0x001c, clock_div);
189062306a36Sopenharmony_ci
189162306a36Sopenharmony_ci	/*
189262306a36Sopenharmony_ci	 * This setting does not visibly affect pictures; left it here
189362306a36Sopenharmony_ci	 * because it was present in Windows USB data stream. This function
189462306a36Sopenharmony_ci	 * does not allow arbitrary values and apparently is a bit mask, to
189562306a36Sopenharmony_ci	 * be activated only at appropriate time. Don't change it randomly!
189662306a36Sopenharmony_ci	 */
189762306a36Sopenharmony_ci	switch (gspca_dev->pixfmt.width) {
189862306a36Sopenharmony_ci	case 176: /* 176x144 */
189962306a36Sopenharmony_ci		cit_model2_Packet1(gspca_dev, 0x0026, 0x00c2);
190062306a36Sopenharmony_ci		break;
190162306a36Sopenharmony_ci	case 320: /* 320x240 */
190262306a36Sopenharmony_ci		cit_model2_Packet1(gspca_dev, 0x0026, 0x0044);
190362306a36Sopenharmony_ci		break;
190462306a36Sopenharmony_ci#if 0
190562306a36Sopenharmony_ci	case VIDEOSIZE_352x240:
190662306a36Sopenharmony_ci		cit_model2_Packet1(gspca_dev, 0x0026, 0x0046);
190762306a36Sopenharmony_ci		break;
190862306a36Sopenharmony_ci#endif
190962306a36Sopenharmony_ci	case 352: /* 352x288 */
191062306a36Sopenharmony_ci		cit_model2_Packet1(gspca_dev, 0x0026, 0x0048);
191162306a36Sopenharmony_ci		break;
191262306a36Sopenharmony_ci	}
191362306a36Sopenharmony_ci
191462306a36Sopenharmony_ci	cit_model2_Packet1(gspca_dev, 0x0028, v4l2_ctrl_g_ctrl(sd->lighting));
191562306a36Sopenharmony_ci	/* model2 cannot change the backlight compensation while streaming */
191662306a36Sopenharmony_ci	v4l2_ctrl_grab(sd->lighting, true);
191762306a36Sopenharmony_ci
191862306a36Sopenharmony_ci	/* color balance rg2 */
191962306a36Sopenharmony_ci	cit_model2_Packet1(gspca_dev, 0x001e, 0x002f);
192062306a36Sopenharmony_ci	/* saturation */
192162306a36Sopenharmony_ci	cit_model2_Packet1(gspca_dev, 0x0020, 0x0034);
192262306a36Sopenharmony_ci	/* color balance yb */
192362306a36Sopenharmony_ci	cit_model2_Packet1(gspca_dev, 0x0022, 0x00a0);
192462306a36Sopenharmony_ci
192562306a36Sopenharmony_ci	/* Hardware control command */
192662306a36Sopenharmony_ci	cit_model2_Packet1(gspca_dev, 0x0030, 0x0004);
192762306a36Sopenharmony_ci
192862306a36Sopenharmony_ci	return 0;
192962306a36Sopenharmony_ci}
193062306a36Sopenharmony_ci
193162306a36Sopenharmony_cistatic int cit_start_model3(struct gspca_dev *gspca_dev)
193262306a36Sopenharmony_ci{
193362306a36Sopenharmony_ci	const unsigned short compression = 0; /* 0=none, 7=best frame rate */
193462306a36Sopenharmony_ci	int i, clock_div = 0;
193562306a36Sopenharmony_ci
193662306a36Sopenharmony_ci	/* HDG not in ibmcam driver, added to see if it helps with
193762306a36Sopenharmony_ci	   auto-detecting between model3 and ibm netcamera pro */
193862306a36Sopenharmony_ci	cit_read_reg(gspca_dev, 0x128, 1);
193962306a36Sopenharmony_ci
194062306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0100);
194162306a36Sopenharmony_ci	cit_read_reg(gspca_dev, 0x0116, 0);
194262306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0060, 0x0116);
194362306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0002, 0x0112);
194462306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0123);
194562306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0001, 0x0117);
194662306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0040, 0x0108);
194762306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0019, 0x012c);
194862306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0060, 0x0116);
194962306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0002, 0x0115);
195062306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0003, 0x0115);
195162306a36Sopenharmony_ci	cit_read_reg(gspca_dev, 0x0115, 0);
195262306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x000b, 0x0115);
195362306a36Sopenharmony_ci
195462306a36Sopenharmony_ci	/* TESTME HDG not in ibmcam driver, added to see if it helps with
195562306a36Sopenharmony_ci	   auto-detecting between model3 and ibm netcamera pro */
195662306a36Sopenharmony_ci	if (0) {
195762306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0078, 0x012d);
195862306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0001, 0x012f);
195962306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd141, 0x0124);
196062306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0079, 0x012d);
196162306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00ff, 0x0130);
196262306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xcd41, 0x0124);
196362306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xfffa, 0x0124);
196462306a36Sopenharmony_ci		cit_read_reg(gspca_dev, 0x0126, 1);
196562306a36Sopenharmony_ci	}
196662306a36Sopenharmony_ci
196762306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x000a, 0x0040);
196862306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x000b, 0x00f6);
196962306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x000c, 0x0002);
197062306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x000d, 0x0020);
197162306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x000e, 0x0033);
197262306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x000f, 0x0007);
197362306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0010, 0x0000);
197462306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0011, 0x0070);
197562306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0012, 0x0030);
197662306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0013, 0x0000);
197762306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0014, 0x0001);
197862306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0015, 0x0001);
197962306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0016, 0x0001);
198062306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0017, 0x0001);
198162306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0018, 0x0000);
198262306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x001e, 0x00c3);
198362306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0020, 0x0000);
198462306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0028, 0x0010);
198562306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0029, 0x0054);
198662306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x002a, 0x0013);
198762306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x002b, 0x0007);
198862306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x002d, 0x0028);
198962306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x002e, 0x0000);
199062306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0031, 0x0000);
199162306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0032, 0x0000);
199262306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0033, 0x0000);
199362306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0034, 0x0000);
199462306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0035, 0x0038);
199562306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x003a, 0x0001);
199662306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x003c, 0x001e);
199762306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x003f, 0x000a);
199862306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0041, 0x0000);
199962306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0046, 0x003f);
200062306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0047, 0x0000);
200162306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0050, 0x0005);
200262306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0052, 0x001a);
200362306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0053, 0x0003);
200462306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x005a, 0x006b);
200562306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x005d, 0x001e);
200662306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x005e, 0x0030);
200762306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x005f, 0x0041);
200862306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0064, 0x0008);
200962306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0065, 0x0015);
201062306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0068, 0x000f);
201162306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0079, 0x0000);
201262306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x007a, 0x0000);
201362306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x007c, 0x003f);
201462306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0082, 0x000f);
201562306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0085, 0x0000);
201662306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0099, 0x0000);
201762306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x009b, 0x0023);
201862306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x009c, 0x0022);
201962306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x009d, 0x0096);
202062306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x009e, 0x0096);
202162306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x009f, 0x000a);
202262306a36Sopenharmony_ci
202362306a36Sopenharmony_ci	switch (gspca_dev->pixfmt.width) {
202462306a36Sopenharmony_ci	case 160:
202562306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0101); /* Same on 160x120, 320x240 */
202662306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00a0, 0x0103); /* Same on 160x120, 320x240 */
202762306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0078, 0x0105); /* Same on 160x120, 320x240 */
202862306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x010a); /* Same */
202962306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0024, 0x010b); /* Differs everywhere */
203062306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00a9, 0x0119);
203162306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0016, 0x011b);
203262306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0002, 0x011d); /* Same on 160x120, 320x240 */
203362306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0003, 0x011e); /* Same on 160x120, 640x480 */
203462306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0129); /* Same */
203562306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00fc, 0x012b); /* Same */
203662306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0018, 0x0102);
203762306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0004, 0x0104);
203862306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0004, 0x011a);
203962306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0028, 0x011c);
204062306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0022, 0x012a); /* Same */
204162306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0118);
204262306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0132);
204362306a36Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x0021, 0x0001); /* Same */
204462306a36Sopenharmony_ci		cit_write_reg(gspca_dev, compression, 0x0109);
204562306a36Sopenharmony_ci		clock_div = 3;
204662306a36Sopenharmony_ci		break;
204762306a36Sopenharmony_ci	case 320:
204862306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0101); /* Same on 160x120, 320x240 */
204962306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00a0, 0x0103); /* Same on 160x120, 320x240 */
205062306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0078, 0x0105); /* Same on 160x120, 320x240 */
205162306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x010a); /* Same */
205262306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0028, 0x010b); /* Differs everywhere */
205362306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0002, 0x011d); /* Same */
205462306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x011e);
205562306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0129); /* Same */
205662306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00fc, 0x012b); /* Same */
205762306a36Sopenharmony_ci		/* 4 commands from 160x120 skipped */
205862306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0022, 0x012a); /* Same */
205962306a36Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x0021, 0x0001); /* Same */
206062306a36Sopenharmony_ci		cit_write_reg(gspca_dev, compression, 0x0109);
206162306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00d9, 0x0119);
206262306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0006, 0x011b);
206362306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0021, 0x0102); /* Same on 320x240, 640x480 */
206462306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0010, 0x0104);
206562306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0004, 0x011a);
206662306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x003f, 0x011c);
206762306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x001c, 0x0118);
206862306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0132);
206962306a36Sopenharmony_ci		clock_div = 5;
207062306a36Sopenharmony_ci		break;
207162306a36Sopenharmony_ci	case 640:
207262306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00f0, 0x0105);
207362306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x010a); /* Same */
207462306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0038, 0x010b); /* Differs everywhere */
207562306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00d9, 0x0119); /* Same on 320x240, 640x480 */
207662306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0006, 0x011b); /* Same on 320x240, 640x480 */
207762306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0004, 0x011d); /* NC */
207862306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0003, 0x011e); /* Same on 160x120, 640x480 */
207962306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0129); /* Same */
208062306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00fc, 0x012b); /* Same */
208162306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0021, 0x0102); /* Same on 320x240, 640x480 */
208262306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0016, 0x0104); /* NC */
208362306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0004, 0x011a); /* Same on 320x240, 640x480 */
208462306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x003f, 0x011c); /* Same on 320x240, 640x480 */
208562306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0022, 0x012a); /* Same */
208662306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x001c, 0x0118); /* Same on 320x240, 640x480 */
208762306a36Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x0021, 0x0001); /* Same */
208862306a36Sopenharmony_ci		cit_write_reg(gspca_dev, compression, 0x0109);
208962306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0040, 0x0101);
209062306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0040, 0x0103);
209162306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0132); /* Same on 320x240, 640x480 */
209262306a36Sopenharmony_ci		clock_div = 7;
209362306a36Sopenharmony_ci		break;
209462306a36Sopenharmony_ci	}
209562306a36Sopenharmony_ci
209662306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x007e, 0x000e);	/* Hue */
209762306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0036, 0x0011);	/* Brightness */
209862306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0060, 0x0002);	/* Sharpness */
209962306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0061, 0x0004);	/* Sharpness */
210062306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0062, 0x0005);	/* Sharpness */
210162306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0063, 0x0014);	/* Sharpness */
210262306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0096, 0x00a0);	/* Red sharpness */
210362306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0097, 0x0096);	/* Blue sharpness */
210462306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0067, 0x0001);	/* Contrast */
210562306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x005b, 0x000c);	/* Contrast */
210662306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x005c, 0x0016);	/* Contrast */
210762306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0098, 0x000b);
210862306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x002c, 0x0003);	/* Was 1, broke 640x480 */
210962306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x002f, 0x002a);
211062306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0030, 0x0029);
211162306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0037, 0x0002);
211262306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0038, 0x0059);
211362306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x003d, 0x002e);
211462306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x003e, 0x0028);
211562306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0078, 0x0005);
211662306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x007b, 0x0011);
211762306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x007d, 0x004b);
211862306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x007f, 0x0022);
211962306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0080, 0x000c);
212062306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0081, 0x000b);
212162306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0083, 0x00fd);
212262306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0086, 0x000b);
212362306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0087, 0x000b);
212462306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x007e, 0x000e);
212562306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0096, 0x00a0);	/* Red sharpness */
212662306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0097, 0x0096);	/* Blue sharpness */
212762306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0098, 0x000b);
212862306a36Sopenharmony_ci
212962306a36Sopenharmony_ci	/* FIXME we should probably use cit_get_clock_div() here (in
213062306a36Sopenharmony_ci	   combination with isoc negotiation using the programmable isoc size)
213162306a36Sopenharmony_ci	   like with the IBM netcam pro). */
213262306a36Sopenharmony_ci	cit_write_reg(gspca_dev, clock_div, 0x0111); /* Clock Divider */
213362306a36Sopenharmony_ci
213462306a36Sopenharmony_ci	switch (gspca_dev->pixfmt.width) {
213562306a36Sopenharmony_ci	case 160:
213662306a36Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x001f, 0x0000); /* Same */
213762306a36Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x0039, 0x001f); /* Same */
213862306a36Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x003b, 0x003c); /* Same */
213962306a36Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x0040, 0x000a);
214062306a36Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x0051, 0x000a);
214162306a36Sopenharmony_ci		break;
214262306a36Sopenharmony_ci	case 320:
214362306a36Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x001f, 0x0000); /* Same */
214462306a36Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x0039, 0x001f); /* Same */
214562306a36Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x003b, 0x003c); /* Same */
214662306a36Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x0040, 0x0008);
214762306a36Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x0051, 0x000b);
214862306a36Sopenharmony_ci		break;
214962306a36Sopenharmony_ci	case 640:
215062306a36Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x001f, 0x0002);	/* !Same */
215162306a36Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x0039, 0x003e);	/* !Same */
215262306a36Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x0040, 0x0008);
215362306a36Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x0051, 0x000a);
215462306a36Sopenharmony_ci		break;
215562306a36Sopenharmony_ci	}
215662306a36Sopenharmony_ci
215762306a36Sopenharmony_ci/*	if (sd->input_index) { */
215862306a36Sopenharmony_ci	if (rca_input) {
215962306a36Sopenharmony_ci		for (i = 0; i < ARRAY_SIZE(rca_initdata); i++) {
216062306a36Sopenharmony_ci			if (rca_initdata[i][0])
216162306a36Sopenharmony_ci				cit_read_reg(gspca_dev, rca_initdata[i][2], 0);
216262306a36Sopenharmony_ci			else
216362306a36Sopenharmony_ci				cit_write_reg(gspca_dev, rca_initdata[i][1],
216462306a36Sopenharmony_ci					      rca_initdata[i][2]);
216562306a36Sopenharmony_ci		}
216662306a36Sopenharmony_ci	}
216762306a36Sopenharmony_ci
216862306a36Sopenharmony_ci	return 0;
216962306a36Sopenharmony_ci}
217062306a36Sopenharmony_ci
217162306a36Sopenharmony_cistatic int cit_start_model4(struct gspca_dev *gspca_dev)
217262306a36Sopenharmony_ci{
217362306a36Sopenharmony_ci	struct sd *sd = (struct sd *) gspca_dev;
217462306a36Sopenharmony_ci
217562306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0100);
217662306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x00c0, 0x0111);
217762306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x00bc, 0x012c);
217862306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0080, 0x012b);
217962306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0108);
218062306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0001, 0x0133);
218162306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x009b, 0x010f);
218262306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x00bb, 0x010f);
218362306a36Sopenharmony_ci	cit_model4_Packet1(gspca_dev, 0x0038, 0x0000);
218462306a36Sopenharmony_ci	cit_model4_Packet1(gspca_dev, 0x000a, 0x005c);
218562306a36Sopenharmony_ci
218662306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x00aa, 0x012d);
218762306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0004, 0x012f);
218862306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0xd141, 0x0124);
218962306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0127);
219062306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x00fb, 0x012e);
219162306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0130);
219262306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x8a28, 0x0124);
219362306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x00aa, 0x012f);
219462306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0xd055, 0x0124);
219562306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x000c, 0x0127);
219662306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0009, 0x012e);
219762306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0xaa28, 0x0124);
219862306a36Sopenharmony_ci
219962306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x00aa, 0x012d);
220062306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0012, 0x012f);
220162306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0xd141, 0x0124);
220262306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0008, 0x0127);
220362306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x00aa, 0x0130);
220462306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x82a8, 0x0124);
220562306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x002a, 0x012d);
220662306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x012f);
220762306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0xd145, 0x0124);
220862306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0xfffa, 0x0124);
220962306a36Sopenharmony_ci	cit_model4_Packet1(gspca_dev, 0x0034, 0x0000);
221062306a36Sopenharmony_ci
221162306a36Sopenharmony_ci	switch (gspca_dev->pixfmt.width) {
221262306a36Sopenharmony_ci	case 128: /* 128x96 */
221362306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0070, 0x0119);
221462306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00d0, 0x0111);
221562306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0039, 0x010a);
221662306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0001, 0x0102);
221762306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0028, 0x0103);
221862306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0104);
221962306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x001e, 0x0105);
222062306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
222162306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0016, 0x012f);
222262306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd141, 0x0124);
222362306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x000a, 0x0127);
222462306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x0130);
222562306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x82a8, 0x0124);
222662306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0014, 0x012d);
222762306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0008, 0x012f);
222862306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd145, 0x0124);
222962306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x012e);
223062306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x001a, 0x0130);
223162306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x8a0a, 0x0124);
223262306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x005a, 0x012d);
223362306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x9545, 0x0124);
223462306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x0127);
223562306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0018, 0x012e);
223662306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0043, 0x0130);
223762306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x8a28, 0x0124);
223862306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x012f);
223962306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd055, 0x0124);
224062306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x001c, 0x0127);
224162306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00eb, 0x012e);
224262306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xaa28, 0x0124);
224362306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
224462306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0032, 0x012f);
224562306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd141, 0x0124);
224662306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0127);
224762306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x0130);
224862306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x82a8, 0x0124);
224962306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0036, 0x012d);
225062306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0008, 0x012f);
225162306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd145, 0x0124);
225262306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xfffa, 0x0124);
225362306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
225462306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x001e, 0x012f);
225562306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd141, 0x0124);
225662306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0017, 0x0127);
225762306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0013, 0x012e);
225862306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0031, 0x0130);
225962306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x8a28, 0x0124);
226062306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0017, 0x012d);
226162306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0078, 0x012f);
226262306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd145, 0x0124);
226362306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0127);
226462306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xfea8, 0x0124);
226562306a36Sopenharmony_ci		sd->sof_len = 2;
226662306a36Sopenharmony_ci		break;
226762306a36Sopenharmony_ci	case 160: /* 160x120 */
226862306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0038, 0x0119);
226962306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00d0, 0x0111);
227062306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00b9, 0x010a);
227162306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0001, 0x0102);
227262306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0028, 0x0103);
227362306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0104);
227462306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x001e, 0x0105);
227562306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
227662306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0016, 0x012f);
227762306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd141, 0x0124);
227862306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x000b, 0x0127);
227962306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x0130);
228062306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x82a8, 0x0124);
228162306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0014, 0x012d);
228262306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0008, 0x012f);
228362306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd145, 0x0124);
228462306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x012e);
228562306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x001a, 0x0130);
228662306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x8a0a, 0x0124);
228762306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x005a, 0x012d);
228862306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x9545, 0x0124);
228962306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x0127);
229062306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0018, 0x012e);
229162306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0043, 0x0130);
229262306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x8a28, 0x0124);
229362306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x012f);
229462306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd055, 0x0124);
229562306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x001c, 0x0127);
229662306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00c7, 0x012e);
229762306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xaa28, 0x0124);
229862306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
229962306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0032, 0x012f);
230062306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd141, 0x0124);
230162306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0025, 0x0127);
230262306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x0130);
230362306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x82a8, 0x0124);
230462306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0036, 0x012d);
230562306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0008, 0x012f);
230662306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd145, 0x0124);
230762306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xfffa, 0x0124);
230862306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
230962306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x001e, 0x012f);
231062306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd141, 0x0124);
231162306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0048, 0x0127);
231262306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0035, 0x012e);
231362306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00d0, 0x0130);
231462306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x8a28, 0x0124);
231562306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0048, 0x012d);
231662306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0090, 0x012f);
231762306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd145, 0x0124);
231862306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0001, 0x0127);
231962306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xfea8, 0x0124);
232062306a36Sopenharmony_ci		sd->sof_len = 2;
232162306a36Sopenharmony_ci		break;
232262306a36Sopenharmony_ci	case 176: /* 176x144 */
232362306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0038, 0x0119);
232462306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00d0, 0x0111);
232562306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00b9, 0x010a);
232662306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0001, 0x0102);
232762306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x002c, 0x0103);
232862306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0104);
232962306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0024, 0x0105);
233062306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
233162306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0016, 0x012f);
233262306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd141, 0x0124);
233362306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0007, 0x0127);
233462306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x0130);
233562306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x82a8, 0x0124);
233662306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0014, 0x012d);
233762306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0001, 0x012f);
233862306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd145, 0x0124);
233962306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x012e);
234062306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x001a, 0x0130);
234162306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x8a0a, 0x0124);
234262306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x005e, 0x012d);
234362306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x9545, 0x0124);
234462306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x0127);
234562306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0018, 0x012e);
234662306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0049, 0x0130);
234762306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x8a28, 0x0124);
234862306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x012f);
234962306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd055, 0x0124);
235062306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x001c, 0x0127);
235162306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00c7, 0x012e);
235262306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xaa28, 0x0124);
235362306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
235462306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0032, 0x012f);
235562306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd141, 0x0124);
235662306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0028, 0x0127);
235762306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x0130);
235862306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x82a8, 0x0124);
235962306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0036, 0x012d);
236062306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0008, 0x012f);
236162306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd145, 0x0124);
236262306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xfffa, 0x0124);
236362306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
236462306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x001e, 0x012f);
236562306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd141, 0x0124);
236662306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0010, 0x0127);
236762306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0013, 0x012e);
236862306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x002a, 0x0130);
236962306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x8a28, 0x0124);
237062306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0010, 0x012d);
237162306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x006d, 0x012f);
237262306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd145, 0x0124);
237362306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0001, 0x0127);
237462306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xfea8, 0x0124);
237562306a36Sopenharmony_ci		/* TESTME HDG: this does not seem right
237662306a36Sopenharmony_ci		   (it is 2 for all other resolutions) */
237762306a36Sopenharmony_ci		sd->sof_len = 10;
237862306a36Sopenharmony_ci		break;
237962306a36Sopenharmony_ci	case 320: /* 320x240 */
238062306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0070, 0x0119);
238162306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00d0, 0x0111);
238262306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0039, 0x010a);
238362306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0001, 0x0102);
238462306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0028, 0x0103);
238562306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0104);
238662306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x001e, 0x0105);
238762306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
238862306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0016, 0x012f);
238962306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd141, 0x0124);
239062306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x000a, 0x0127);
239162306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x0130);
239262306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x82a8, 0x0124);
239362306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0014, 0x012d);
239462306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0008, 0x012f);
239562306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd145, 0x0124);
239662306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x012e);
239762306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x001a, 0x0130);
239862306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x8a0a, 0x0124);
239962306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x005a, 0x012d);
240062306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x9545, 0x0124);
240162306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x0127);
240262306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0018, 0x012e);
240362306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0043, 0x0130);
240462306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x8a28, 0x0124);
240562306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x012f);
240662306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd055, 0x0124);
240762306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x001c, 0x0127);
240862306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00eb, 0x012e);
240962306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xaa28, 0x0124);
241062306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
241162306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0032, 0x012f);
241262306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd141, 0x0124);
241362306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0127);
241462306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x0130);
241562306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x82a8, 0x0124);
241662306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0036, 0x012d);
241762306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0008, 0x012f);
241862306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd145, 0x0124);
241962306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xfffa, 0x0124);
242062306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
242162306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x001e, 0x012f);
242262306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd141, 0x0124);
242362306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0017, 0x0127);
242462306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0013, 0x012e);
242562306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0031, 0x0130);
242662306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x8a28, 0x0124);
242762306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0017, 0x012d);
242862306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0078, 0x012f);
242962306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd145, 0x0124);
243062306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0127);
243162306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xfea8, 0x0124);
243262306a36Sopenharmony_ci		sd->sof_len = 2;
243362306a36Sopenharmony_ci		break;
243462306a36Sopenharmony_ci	case 352: /* 352x288 */
243562306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0070, 0x0119);
243662306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00c0, 0x0111);
243762306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0039, 0x010a);
243862306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0001, 0x0102);
243962306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x002c, 0x0103);
244062306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0104);
244162306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0024, 0x0105);
244262306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
244362306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0016, 0x012f);
244462306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd141, 0x0124);
244562306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0006, 0x0127);
244662306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x0130);
244762306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x82a8, 0x0124);
244862306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0014, 0x012d);
244962306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0002, 0x012f);
245062306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd145, 0x0124);
245162306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x012e);
245262306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x001a, 0x0130);
245362306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x8a0a, 0x0124);
245462306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x005e, 0x012d);
245562306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x9545, 0x0124);
245662306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x0127);
245762306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0018, 0x012e);
245862306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0049, 0x0130);
245962306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x8a28, 0x0124);
246062306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x012f);
246162306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd055, 0x0124);
246262306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x001c, 0x0127);
246362306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00cf, 0x012e);
246462306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xaa28, 0x0124);
246562306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
246662306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0032, 0x012f);
246762306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd141, 0x0124);
246862306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0127);
246962306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x0130);
247062306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x82a8, 0x0124);
247162306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0036, 0x012d);
247262306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0008, 0x012f);
247362306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd145, 0x0124);
247462306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xfffa, 0x0124);
247562306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00aa, 0x012d);
247662306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x001e, 0x012f);
247762306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd141, 0x0124);
247862306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0010, 0x0127);
247962306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0013, 0x012e);
248062306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0025, 0x0130);
248162306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x8a28, 0x0124);
248262306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0010, 0x012d);
248362306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0048, 0x012f);
248462306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xd145, 0x0124);
248562306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0127);
248662306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0xfea8, 0x0124);
248762306a36Sopenharmony_ci		sd->sof_len = 2;
248862306a36Sopenharmony_ci		break;
248962306a36Sopenharmony_ci	}
249062306a36Sopenharmony_ci
249162306a36Sopenharmony_ci	cit_model4_Packet1(gspca_dev, 0x0038, 0x0004);
249262306a36Sopenharmony_ci
249362306a36Sopenharmony_ci	return 0;
249462306a36Sopenharmony_ci}
249562306a36Sopenharmony_ci
249662306a36Sopenharmony_cistatic int cit_start_ibm_netcam_pro(struct gspca_dev *gspca_dev)
249762306a36Sopenharmony_ci{
249862306a36Sopenharmony_ci	const unsigned short compression = 0; /* 0=none, 7=best frame rate */
249962306a36Sopenharmony_ci	int i, clock_div;
250062306a36Sopenharmony_ci
250162306a36Sopenharmony_ci	clock_div = cit_get_clock_div(gspca_dev);
250262306a36Sopenharmony_ci	if (clock_div < 0)
250362306a36Sopenharmony_ci		return clock_div;
250462306a36Sopenharmony_ci
250562306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0003, 0x0133);
250662306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0117);
250762306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0008, 0x0123);
250862306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0100);
250962306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0060, 0x0116);
251062306a36Sopenharmony_ci	/* cit_write_reg(gspca_dev, 0x0002, 0x0112); see sd_stop0 */
251162306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0133);
251262306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0123);
251362306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0001, 0x0117);
251462306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0040, 0x0108);
251562306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0019, 0x012c);
251662306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0060, 0x0116);
251762306a36Sopenharmony_ci	/* cit_write_reg(gspca_dev, 0x000b, 0x0115); see sd_stop0 */
251862306a36Sopenharmony_ci
251962306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0049, 0x0000);
252062306a36Sopenharmony_ci
252162306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0101); /* Same on 160x120, 320x240 */
252262306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x003a, 0x0102); /* Hstart */
252362306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x00a0, 0x0103); /* Same on 160x120, 320x240 */
252462306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0078, 0x0105); /* Same on 160x120, 320x240 */
252562306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x010a); /* Same */
252662306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0002, 0x011d); /* Same on 160x120, 320x240 */
252762306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x0129); /* Same */
252862306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x00fc, 0x012b); /* Same */
252962306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0022, 0x012a); /* Same */
253062306a36Sopenharmony_ci
253162306a36Sopenharmony_ci	switch (gspca_dev->pixfmt.width) {
253262306a36Sopenharmony_ci	case 160: /* 160x120 */
253362306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0024, 0x010b);
253462306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0089, 0x0119);
253562306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x000a, 0x011b);
253662306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0003, 0x011e);
253762306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0007, 0x0104);
253862306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0009, 0x011a);
253962306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x008b, 0x011c);
254062306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0008, 0x0118);
254162306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0132);
254262306a36Sopenharmony_ci		break;
254362306a36Sopenharmony_ci	case 320: /* 320x240 */
254462306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0028, 0x010b);
254562306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00d9, 0x0119);
254662306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0006, 0x011b);
254762306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x011e);
254862306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x000e, 0x0104);
254962306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0004, 0x011a);
255062306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x003f, 0x011c);
255162306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x000c, 0x0118);
255262306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0132);
255362306a36Sopenharmony_ci		break;
255462306a36Sopenharmony_ci	}
255562306a36Sopenharmony_ci
255662306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0019, 0x0031);
255762306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x001a, 0x0003);
255862306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x001b, 0x0038);
255962306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x001c, 0x0000);
256062306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0024, 0x0001);
256162306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0027, 0x0001);
256262306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x002a, 0x0004);
256362306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0035, 0x000b);
256462306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x003f, 0x0001);
256562306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0044, 0x0000);
256662306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x0054, 0x0000);
256762306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00c4, 0x0000);
256862306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00e7, 0x0001);
256962306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00e9, 0x0001);
257062306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00ee, 0x0000);
257162306a36Sopenharmony_ci	cit_model3_Packet1(gspca_dev, 0x00f3, 0x00c0);
257262306a36Sopenharmony_ci
257362306a36Sopenharmony_ci	cit_write_reg(gspca_dev, compression, 0x0109);
257462306a36Sopenharmony_ci	cit_write_reg(gspca_dev, clock_div, 0x0111);
257562306a36Sopenharmony_ci
257662306a36Sopenharmony_ci/*	if (sd->input_index) { */
257762306a36Sopenharmony_ci	if (rca_input) {
257862306a36Sopenharmony_ci		for (i = 0; i < ARRAY_SIZE(rca_initdata); i++) {
257962306a36Sopenharmony_ci			if (rca_initdata[i][0])
258062306a36Sopenharmony_ci				cit_read_reg(gspca_dev, rca_initdata[i][2], 0);
258162306a36Sopenharmony_ci			else
258262306a36Sopenharmony_ci				cit_write_reg(gspca_dev, rca_initdata[i][1],
258362306a36Sopenharmony_ci					      rca_initdata[i][2]);
258462306a36Sopenharmony_ci		}
258562306a36Sopenharmony_ci	}
258662306a36Sopenharmony_ci
258762306a36Sopenharmony_ci	return 0;
258862306a36Sopenharmony_ci}
258962306a36Sopenharmony_ci
259062306a36Sopenharmony_ci/* -- start the camera -- */
259162306a36Sopenharmony_cistatic int sd_start(struct gspca_dev *gspca_dev)
259262306a36Sopenharmony_ci{
259362306a36Sopenharmony_ci	struct sd *sd = (struct sd *) gspca_dev;
259462306a36Sopenharmony_ci	int packet_size;
259562306a36Sopenharmony_ci
259662306a36Sopenharmony_ci	packet_size = cit_get_packet_size(gspca_dev);
259762306a36Sopenharmony_ci	if (packet_size < 0)
259862306a36Sopenharmony_ci		return packet_size;
259962306a36Sopenharmony_ci
260062306a36Sopenharmony_ci	switch (sd->model) {
260162306a36Sopenharmony_ci	case CIT_MODEL0:
260262306a36Sopenharmony_ci		cit_start_model0(gspca_dev);
260362306a36Sopenharmony_ci		break;
260462306a36Sopenharmony_ci	case CIT_MODEL1:
260562306a36Sopenharmony_ci		cit_start_model1(gspca_dev);
260662306a36Sopenharmony_ci		break;
260762306a36Sopenharmony_ci	case CIT_MODEL2:
260862306a36Sopenharmony_ci		cit_start_model2(gspca_dev);
260962306a36Sopenharmony_ci		break;
261062306a36Sopenharmony_ci	case CIT_MODEL3:
261162306a36Sopenharmony_ci		cit_start_model3(gspca_dev);
261262306a36Sopenharmony_ci		break;
261362306a36Sopenharmony_ci	case CIT_MODEL4:
261462306a36Sopenharmony_ci		cit_start_model4(gspca_dev);
261562306a36Sopenharmony_ci		break;
261662306a36Sopenharmony_ci	case CIT_IBM_NETCAM_PRO:
261762306a36Sopenharmony_ci		cit_start_ibm_netcam_pro(gspca_dev);
261862306a36Sopenharmony_ci		break;
261962306a36Sopenharmony_ci	}
262062306a36Sopenharmony_ci
262162306a36Sopenharmony_ci	/* Program max isoc packet size */
262262306a36Sopenharmony_ci	cit_write_reg(gspca_dev, packet_size >> 8, 0x0106);
262362306a36Sopenharmony_ci	cit_write_reg(gspca_dev, packet_size & 0xff, 0x0107);
262462306a36Sopenharmony_ci
262562306a36Sopenharmony_ci	cit_restart_stream(gspca_dev);
262662306a36Sopenharmony_ci
262762306a36Sopenharmony_ci	return 0;
262862306a36Sopenharmony_ci}
262962306a36Sopenharmony_ci
263062306a36Sopenharmony_cistatic int sd_isoc_init(struct gspca_dev *gspca_dev)
263162306a36Sopenharmony_ci{
263262306a36Sopenharmony_ci	struct usb_interface_cache *intfc;
263362306a36Sopenharmony_ci	struct usb_host_interface *alt;
263462306a36Sopenharmony_ci	int max_packet_size;
263562306a36Sopenharmony_ci
263662306a36Sopenharmony_ci	switch (gspca_dev->pixfmt.width) {
263762306a36Sopenharmony_ci	case 160:
263862306a36Sopenharmony_ci		max_packet_size = 450;
263962306a36Sopenharmony_ci		break;
264062306a36Sopenharmony_ci	case 176:
264162306a36Sopenharmony_ci		max_packet_size = 600;
264262306a36Sopenharmony_ci		break;
264362306a36Sopenharmony_ci	default:
264462306a36Sopenharmony_ci		max_packet_size = 1022;
264562306a36Sopenharmony_ci		break;
264662306a36Sopenharmony_ci	}
264762306a36Sopenharmony_ci
264862306a36Sopenharmony_ci	intfc = gspca_dev->dev->actconfig->intf_cache[0];
264962306a36Sopenharmony_ci
265062306a36Sopenharmony_ci	if (intfc->num_altsetting < 2)
265162306a36Sopenharmony_ci		return -ENODEV;
265262306a36Sopenharmony_ci
265362306a36Sopenharmony_ci	alt = &intfc->altsetting[1];
265462306a36Sopenharmony_ci
265562306a36Sopenharmony_ci	if (alt->desc.bNumEndpoints < 1)
265662306a36Sopenharmony_ci		return -ENODEV;
265762306a36Sopenharmony_ci
265862306a36Sopenharmony_ci	/* Start isoc bandwidth "negotiation" at max isoc bandwidth */
265962306a36Sopenharmony_ci	alt->endpoint[0].desc.wMaxPacketSize = cpu_to_le16(max_packet_size);
266062306a36Sopenharmony_ci
266162306a36Sopenharmony_ci	return 0;
266262306a36Sopenharmony_ci}
266362306a36Sopenharmony_ci
266462306a36Sopenharmony_cistatic int sd_isoc_nego(struct gspca_dev *gspca_dev)
266562306a36Sopenharmony_ci{
266662306a36Sopenharmony_ci	int ret, packet_size, min_packet_size;
266762306a36Sopenharmony_ci	struct usb_host_interface *alt;
266862306a36Sopenharmony_ci
266962306a36Sopenharmony_ci	switch (gspca_dev->pixfmt.width) {
267062306a36Sopenharmony_ci	case 160:
267162306a36Sopenharmony_ci		min_packet_size = 200;
267262306a36Sopenharmony_ci		break;
267362306a36Sopenharmony_ci	case 176:
267462306a36Sopenharmony_ci		min_packet_size = 266;
267562306a36Sopenharmony_ci		break;
267662306a36Sopenharmony_ci	default:
267762306a36Sopenharmony_ci		min_packet_size = 400;
267862306a36Sopenharmony_ci		break;
267962306a36Sopenharmony_ci	}
268062306a36Sopenharmony_ci
268162306a36Sopenharmony_ci	/*
268262306a36Sopenharmony_ci	 * Existence of altsetting and endpoint was verified in sd_isoc_init()
268362306a36Sopenharmony_ci	 */
268462306a36Sopenharmony_ci	alt = &gspca_dev->dev->actconfig->intf_cache[0]->altsetting[1];
268562306a36Sopenharmony_ci	packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
268662306a36Sopenharmony_ci	if (packet_size <= min_packet_size)
268762306a36Sopenharmony_ci		return -EIO;
268862306a36Sopenharmony_ci
268962306a36Sopenharmony_ci	packet_size -= 100;
269062306a36Sopenharmony_ci	if (packet_size < min_packet_size)
269162306a36Sopenharmony_ci		packet_size = min_packet_size;
269262306a36Sopenharmony_ci	alt->endpoint[0].desc.wMaxPacketSize = cpu_to_le16(packet_size);
269362306a36Sopenharmony_ci
269462306a36Sopenharmony_ci	ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1);
269562306a36Sopenharmony_ci	if (ret < 0)
269662306a36Sopenharmony_ci		pr_err("set alt 1 err %d\n", ret);
269762306a36Sopenharmony_ci
269862306a36Sopenharmony_ci	return ret;
269962306a36Sopenharmony_ci}
270062306a36Sopenharmony_ci
270162306a36Sopenharmony_cistatic void sd_stopN(struct gspca_dev *gspca_dev)
270262306a36Sopenharmony_ci{
270362306a36Sopenharmony_ci	cit_write_reg(gspca_dev, 0x0000, 0x010c);
270462306a36Sopenharmony_ci}
270562306a36Sopenharmony_ci
270662306a36Sopenharmony_cistatic void sd_stop0(struct gspca_dev *gspca_dev)
270762306a36Sopenharmony_ci{
270862306a36Sopenharmony_ci	struct sd *sd = (struct sd *) gspca_dev;
270962306a36Sopenharmony_ci
271062306a36Sopenharmony_ci	if (!gspca_dev->present)
271162306a36Sopenharmony_ci		return;
271262306a36Sopenharmony_ci
271362306a36Sopenharmony_ci	switch (sd->model) {
271462306a36Sopenharmony_ci	case CIT_MODEL0:
271562306a36Sopenharmony_ci		/* HDG windows does this, but it causes the cams autogain to
271662306a36Sopenharmony_ci		   restart from a gain of 0, which does not look good when
271762306a36Sopenharmony_ci		   changing resolutions. */
271862306a36Sopenharmony_ci		/* cit_write_reg(gspca_dev, 0x0000, 0x0112); */
271962306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00c0, 0x0100); /* LED Off */
272062306a36Sopenharmony_ci		break;
272162306a36Sopenharmony_ci	case CIT_MODEL1:
272262306a36Sopenharmony_ci		cit_send_FF_04_02(gspca_dev);
272362306a36Sopenharmony_ci		cit_read_reg(gspca_dev, 0x0100, 0);
272462306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x81, 0x0100);	/* LED Off */
272562306a36Sopenharmony_ci		break;
272662306a36Sopenharmony_ci	case CIT_MODEL2:
272762306a36Sopenharmony_ci		v4l2_ctrl_grab(sd->lighting, false);
272862306a36Sopenharmony_ci		fallthrough;
272962306a36Sopenharmony_ci	case CIT_MODEL4:
273062306a36Sopenharmony_ci		cit_model2_Packet1(gspca_dev, 0x0030, 0x0004);
273162306a36Sopenharmony_ci
273262306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0080, 0x0100);	/* LED Off */
273362306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0020, 0x0111);
273462306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00a0, 0x0111);
273562306a36Sopenharmony_ci
273662306a36Sopenharmony_ci		cit_model2_Packet1(gspca_dev, 0x0030, 0x0002);
273762306a36Sopenharmony_ci
273862306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0020, 0x0111);
273962306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0112);
274062306a36Sopenharmony_ci		break;
274162306a36Sopenharmony_ci	case CIT_MODEL3:
274262306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0006, 0x012c);
274362306a36Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x0046, 0x0000);
274462306a36Sopenharmony_ci		cit_read_reg(gspca_dev, 0x0116, 0);
274562306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0064, 0x0116);
274662306a36Sopenharmony_ci		cit_read_reg(gspca_dev, 0x0115, 0);
274762306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0003, 0x0115);
274862306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0008, 0x0123);
274962306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0117);
275062306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0112);
275162306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0080, 0x0100);
275262306a36Sopenharmony_ci		break;
275362306a36Sopenharmony_ci	case CIT_IBM_NETCAM_PRO:
275462306a36Sopenharmony_ci		cit_model3_Packet1(gspca_dev, 0x0049, 0x00ff);
275562306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0006, 0x012c);
275662306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0116);
275762306a36Sopenharmony_ci		/* HDG windows does this, but I cannot get the camera
275862306a36Sopenharmony_ci		   to restart with this without redoing the entire init
275962306a36Sopenharmony_ci		   sequence which makes switching modes really slow */
276062306a36Sopenharmony_ci		/* cit_write_reg(gspca_dev, 0x0006, 0x0115); */
276162306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0008, 0x0123);
276262306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0117);
276362306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0003, 0x0133);
276462306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x0000, 0x0111);
276562306a36Sopenharmony_ci		/* HDG windows does this, but I get a green picture when
276662306a36Sopenharmony_ci		   restarting the stream after this */
276762306a36Sopenharmony_ci		/* cit_write_reg(gspca_dev, 0x0000, 0x0112); */
276862306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x00c0, 0x0100);
276962306a36Sopenharmony_ci		break;
277062306a36Sopenharmony_ci	}
277162306a36Sopenharmony_ci
277262306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_INPUT)
277362306a36Sopenharmony_ci	/* If the last button state is pressed, release it now! */
277462306a36Sopenharmony_ci	if (sd->button_state) {
277562306a36Sopenharmony_ci		input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
277662306a36Sopenharmony_ci		input_sync(gspca_dev->input_dev);
277762306a36Sopenharmony_ci		sd->button_state = 0;
277862306a36Sopenharmony_ci	}
277962306a36Sopenharmony_ci#endif
278062306a36Sopenharmony_ci}
278162306a36Sopenharmony_ci
278262306a36Sopenharmony_cistatic u8 *cit_find_sof(struct gspca_dev *gspca_dev, u8 *data, int len)
278362306a36Sopenharmony_ci{
278462306a36Sopenharmony_ci	struct sd *sd = (struct sd *) gspca_dev;
278562306a36Sopenharmony_ci	u8 byte3 = 0, byte4 = 0;
278662306a36Sopenharmony_ci	int i;
278762306a36Sopenharmony_ci
278862306a36Sopenharmony_ci	switch (sd->model) {
278962306a36Sopenharmony_ci	case CIT_MODEL0:
279062306a36Sopenharmony_ci	case CIT_MODEL1:
279162306a36Sopenharmony_ci	case CIT_MODEL3:
279262306a36Sopenharmony_ci	case CIT_IBM_NETCAM_PRO:
279362306a36Sopenharmony_ci		switch (gspca_dev->pixfmt.width) {
279462306a36Sopenharmony_ci		case 160: /* 160x120 */
279562306a36Sopenharmony_ci			byte3 = 0x02;
279662306a36Sopenharmony_ci			byte4 = 0x0a;
279762306a36Sopenharmony_ci			break;
279862306a36Sopenharmony_ci		case 176: /* 176x144 */
279962306a36Sopenharmony_ci			byte3 = 0x02;
280062306a36Sopenharmony_ci			byte4 = 0x0e;
280162306a36Sopenharmony_ci			break;
280262306a36Sopenharmony_ci		case 320: /* 320x240 */
280362306a36Sopenharmony_ci			byte3 = 0x02;
280462306a36Sopenharmony_ci			byte4 = 0x08;
280562306a36Sopenharmony_ci			break;
280662306a36Sopenharmony_ci		case 352: /* 352x288 */
280762306a36Sopenharmony_ci			byte3 = 0x02;
280862306a36Sopenharmony_ci			byte4 = 0x00;
280962306a36Sopenharmony_ci			break;
281062306a36Sopenharmony_ci		case 640:
281162306a36Sopenharmony_ci			byte3 = 0x03;
281262306a36Sopenharmony_ci			byte4 = 0x08;
281362306a36Sopenharmony_ci			break;
281462306a36Sopenharmony_ci		}
281562306a36Sopenharmony_ci
281662306a36Sopenharmony_ci		/* These have a different byte3 */
281762306a36Sopenharmony_ci		if (sd->model <= CIT_MODEL1)
281862306a36Sopenharmony_ci			byte3 = 0x00;
281962306a36Sopenharmony_ci
282062306a36Sopenharmony_ci		for (i = 0; i < len; i++) {
282162306a36Sopenharmony_ci			/* For this model the SOF always starts at offset 0
282262306a36Sopenharmony_ci			   so no need to search the entire frame */
282362306a36Sopenharmony_ci			if (sd->model == CIT_MODEL0 && sd->sof_read != i)
282462306a36Sopenharmony_ci				break;
282562306a36Sopenharmony_ci
282662306a36Sopenharmony_ci			switch (sd->sof_read) {
282762306a36Sopenharmony_ci			case 0:
282862306a36Sopenharmony_ci				if (data[i] == 0x00)
282962306a36Sopenharmony_ci					sd->sof_read++;
283062306a36Sopenharmony_ci				break;
283162306a36Sopenharmony_ci			case 1:
283262306a36Sopenharmony_ci				if (data[i] == 0xff)
283362306a36Sopenharmony_ci					sd->sof_read++;
283462306a36Sopenharmony_ci				else if (data[i] == 0x00)
283562306a36Sopenharmony_ci					sd->sof_read = 1;
283662306a36Sopenharmony_ci				else
283762306a36Sopenharmony_ci					sd->sof_read = 0;
283862306a36Sopenharmony_ci				break;
283962306a36Sopenharmony_ci			case 2:
284062306a36Sopenharmony_ci				if (data[i] == byte3)
284162306a36Sopenharmony_ci					sd->sof_read++;
284262306a36Sopenharmony_ci				else if (data[i] == 0x00)
284362306a36Sopenharmony_ci					sd->sof_read = 1;
284462306a36Sopenharmony_ci				else
284562306a36Sopenharmony_ci					sd->sof_read = 0;
284662306a36Sopenharmony_ci				break;
284762306a36Sopenharmony_ci			case 3:
284862306a36Sopenharmony_ci				if (data[i] == byte4) {
284962306a36Sopenharmony_ci					sd->sof_read = 0;
285062306a36Sopenharmony_ci					return data + i + (sd->sof_len - 3);
285162306a36Sopenharmony_ci				}
285262306a36Sopenharmony_ci				if (byte3 == 0x00 && data[i] == 0xff)
285362306a36Sopenharmony_ci					sd->sof_read = 2;
285462306a36Sopenharmony_ci				else if (data[i] == 0x00)
285562306a36Sopenharmony_ci					sd->sof_read = 1;
285662306a36Sopenharmony_ci				else
285762306a36Sopenharmony_ci					sd->sof_read = 0;
285862306a36Sopenharmony_ci				break;
285962306a36Sopenharmony_ci			}
286062306a36Sopenharmony_ci		}
286162306a36Sopenharmony_ci		break;
286262306a36Sopenharmony_ci	case CIT_MODEL2:
286362306a36Sopenharmony_ci	case CIT_MODEL4:
286462306a36Sopenharmony_ci		/* TESTME we need to find a longer sof signature to avoid
286562306a36Sopenharmony_ci		   false positives */
286662306a36Sopenharmony_ci		for (i = 0; i < len; i++) {
286762306a36Sopenharmony_ci			switch (sd->sof_read) {
286862306a36Sopenharmony_ci			case 0:
286962306a36Sopenharmony_ci				if (data[i] == 0x00)
287062306a36Sopenharmony_ci					sd->sof_read++;
287162306a36Sopenharmony_ci				break;
287262306a36Sopenharmony_ci			case 1:
287362306a36Sopenharmony_ci				sd->sof_read = 0;
287462306a36Sopenharmony_ci				if (data[i] == 0xff) {
287562306a36Sopenharmony_ci					if (i >= 4)
287662306a36Sopenharmony_ci						gspca_dbg(gspca_dev, D_FRAM,
287762306a36Sopenharmony_ci							  "header found at offset: %d: %02x %02x 00 %3ph\n\n",
287862306a36Sopenharmony_ci							  i - 1,
287962306a36Sopenharmony_ci							  data[i - 4],
288062306a36Sopenharmony_ci							  data[i - 3],
288162306a36Sopenharmony_ci							  &data[i]);
288262306a36Sopenharmony_ci					else
288362306a36Sopenharmony_ci						gspca_dbg(gspca_dev, D_FRAM,
288462306a36Sopenharmony_ci							  "header found at offset: %d: 00 %3ph\n\n",
288562306a36Sopenharmony_ci							  i - 1,
288662306a36Sopenharmony_ci							  &data[i]);
288762306a36Sopenharmony_ci					return data + i + (sd->sof_len - 1);
288862306a36Sopenharmony_ci				}
288962306a36Sopenharmony_ci				break;
289062306a36Sopenharmony_ci			}
289162306a36Sopenharmony_ci		}
289262306a36Sopenharmony_ci		break;
289362306a36Sopenharmony_ci	}
289462306a36Sopenharmony_ci	return NULL;
289562306a36Sopenharmony_ci}
289662306a36Sopenharmony_ci
289762306a36Sopenharmony_cistatic void sd_pkt_scan(struct gspca_dev *gspca_dev,
289862306a36Sopenharmony_ci			u8 *data, int len)
289962306a36Sopenharmony_ci{
290062306a36Sopenharmony_ci	struct sd *sd = (struct sd *) gspca_dev;
290162306a36Sopenharmony_ci	unsigned char *sof;
290262306a36Sopenharmony_ci
290362306a36Sopenharmony_ci	sof = cit_find_sof(gspca_dev, data, len);
290462306a36Sopenharmony_ci	if (sof) {
290562306a36Sopenharmony_ci		int n;
290662306a36Sopenharmony_ci
290762306a36Sopenharmony_ci		/* finish decoding current frame */
290862306a36Sopenharmony_ci		n = sof - data;
290962306a36Sopenharmony_ci		if (n > sd->sof_len)
291062306a36Sopenharmony_ci			n -= sd->sof_len;
291162306a36Sopenharmony_ci		else
291262306a36Sopenharmony_ci			n = 0;
291362306a36Sopenharmony_ci		gspca_frame_add(gspca_dev, LAST_PACKET,
291462306a36Sopenharmony_ci				data, n);
291562306a36Sopenharmony_ci		gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
291662306a36Sopenharmony_ci		len -= sof - data;
291762306a36Sopenharmony_ci		data = sof;
291862306a36Sopenharmony_ci	}
291962306a36Sopenharmony_ci
292062306a36Sopenharmony_ci	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
292162306a36Sopenharmony_ci}
292262306a36Sopenharmony_ci
292362306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_INPUT)
292462306a36Sopenharmony_cistatic void cit_check_button(struct gspca_dev *gspca_dev)
292562306a36Sopenharmony_ci{
292662306a36Sopenharmony_ci	int new_button_state;
292762306a36Sopenharmony_ci	struct sd *sd = (struct sd *)gspca_dev;
292862306a36Sopenharmony_ci
292962306a36Sopenharmony_ci	switch (sd->model) {
293062306a36Sopenharmony_ci	case CIT_MODEL3:
293162306a36Sopenharmony_ci	case CIT_IBM_NETCAM_PRO:
293262306a36Sopenharmony_ci		break;
293362306a36Sopenharmony_ci	default: /* TEST ME unknown if this works on other models too */
293462306a36Sopenharmony_ci		return;
293562306a36Sopenharmony_ci	}
293662306a36Sopenharmony_ci
293762306a36Sopenharmony_ci	/* Read the button state */
293862306a36Sopenharmony_ci	cit_read_reg(gspca_dev, 0x0113, 0);
293962306a36Sopenharmony_ci	new_button_state = !gspca_dev->usb_buf[0];
294062306a36Sopenharmony_ci
294162306a36Sopenharmony_ci	/* Tell the cam we've seen the button press, notice that this
294262306a36Sopenharmony_ci	   is a nop (iow the cam keeps reporting pressed) until the
294362306a36Sopenharmony_ci	   button is actually released. */
294462306a36Sopenharmony_ci	if (new_button_state)
294562306a36Sopenharmony_ci		cit_write_reg(gspca_dev, 0x01, 0x0113);
294662306a36Sopenharmony_ci
294762306a36Sopenharmony_ci	if (sd->button_state != new_button_state) {
294862306a36Sopenharmony_ci		input_report_key(gspca_dev->input_dev, KEY_CAMERA,
294962306a36Sopenharmony_ci				 new_button_state);
295062306a36Sopenharmony_ci		input_sync(gspca_dev->input_dev);
295162306a36Sopenharmony_ci		sd->button_state = new_button_state;
295262306a36Sopenharmony_ci	}
295362306a36Sopenharmony_ci}
295462306a36Sopenharmony_ci#endif
295562306a36Sopenharmony_ci
295662306a36Sopenharmony_cistatic int sd_s_ctrl(struct v4l2_ctrl *ctrl)
295762306a36Sopenharmony_ci{
295862306a36Sopenharmony_ci	struct gspca_dev *gspca_dev =
295962306a36Sopenharmony_ci		container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
296062306a36Sopenharmony_ci	struct sd *sd = (struct sd *)gspca_dev;
296162306a36Sopenharmony_ci
296262306a36Sopenharmony_ci	gspca_dev->usb_err = 0;
296362306a36Sopenharmony_ci
296462306a36Sopenharmony_ci	if (!gspca_dev->streaming)
296562306a36Sopenharmony_ci		return 0;
296662306a36Sopenharmony_ci
296762306a36Sopenharmony_ci	if (sd->stop_on_control_change)
296862306a36Sopenharmony_ci		sd_stopN(gspca_dev);
296962306a36Sopenharmony_ci	switch (ctrl->id) {
297062306a36Sopenharmony_ci	case V4L2_CID_BRIGHTNESS:
297162306a36Sopenharmony_ci		cit_set_brightness(gspca_dev, ctrl->val);
297262306a36Sopenharmony_ci		break;
297362306a36Sopenharmony_ci	case V4L2_CID_CONTRAST:
297462306a36Sopenharmony_ci		cit_set_contrast(gspca_dev, ctrl->val);
297562306a36Sopenharmony_ci		break;
297662306a36Sopenharmony_ci	case V4L2_CID_HUE:
297762306a36Sopenharmony_ci		cit_set_hue(gspca_dev, ctrl->val);
297862306a36Sopenharmony_ci		break;
297962306a36Sopenharmony_ci	case V4L2_CID_HFLIP:
298062306a36Sopenharmony_ci		cit_set_hflip(gspca_dev, ctrl->val);
298162306a36Sopenharmony_ci		break;
298262306a36Sopenharmony_ci	case V4L2_CID_SHARPNESS:
298362306a36Sopenharmony_ci		cit_set_sharpness(gspca_dev, ctrl->val);
298462306a36Sopenharmony_ci		break;
298562306a36Sopenharmony_ci	case V4L2_CID_BACKLIGHT_COMPENSATION:
298662306a36Sopenharmony_ci		cit_set_lighting(gspca_dev, ctrl->val);
298762306a36Sopenharmony_ci		break;
298862306a36Sopenharmony_ci	}
298962306a36Sopenharmony_ci	if (sd->stop_on_control_change)
299062306a36Sopenharmony_ci		cit_restart_stream(gspca_dev);
299162306a36Sopenharmony_ci	return gspca_dev->usb_err;
299262306a36Sopenharmony_ci}
299362306a36Sopenharmony_ci
299462306a36Sopenharmony_cistatic const struct v4l2_ctrl_ops sd_ctrl_ops = {
299562306a36Sopenharmony_ci	.s_ctrl = sd_s_ctrl,
299662306a36Sopenharmony_ci};
299762306a36Sopenharmony_ci
299862306a36Sopenharmony_cistatic int sd_init_controls(struct gspca_dev *gspca_dev)
299962306a36Sopenharmony_ci{
300062306a36Sopenharmony_ci	struct sd *sd = (struct sd *)gspca_dev;
300162306a36Sopenharmony_ci	struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
300262306a36Sopenharmony_ci	bool has_brightness;
300362306a36Sopenharmony_ci	bool has_contrast;
300462306a36Sopenharmony_ci	bool has_hue;
300562306a36Sopenharmony_ci	bool has_sharpness;
300662306a36Sopenharmony_ci	bool has_lighting;
300762306a36Sopenharmony_ci	bool has_hflip;
300862306a36Sopenharmony_ci
300962306a36Sopenharmony_ci	has_brightness = has_contrast = has_hue =
301062306a36Sopenharmony_ci		has_sharpness = has_hflip = has_lighting = false;
301162306a36Sopenharmony_ci	switch (sd->model) {
301262306a36Sopenharmony_ci	case CIT_MODEL0:
301362306a36Sopenharmony_ci		has_contrast = has_hflip = true;
301462306a36Sopenharmony_ci		break;
301562306a36Sopenharmony_ci	case CIT_MODEL1:
301662306a36Sopenharmony_ci		has_brightness = has_contrast =
301762306a36Sopenharmony_ci			has_sharpness = has_lighting = true;
301862306a36Sopenharmony_ci		break;
301962306a36Sopenharmony_ci	case CIT_MODEL2:
302062306a36Sopenharmony_ci		has_brightness = has_hue = has_lighting = true;
302162306a36Sopenharmony_ci		break;
302262306a36Sopenharmony_ci	case CIT_MODEL3:
302362306a36Sopenharmony_ci		has_brightness = has_contrast = has_sharpness = true;
302462306a36Sopenharmony_ci		break;
302562306a36Sopenharmony_ci	case CIT_MODEL4:
302662306a36Sopenharmony_ci		has_brightness = has_hue = true;
302762306a36Sopenharmony_ci		break;
302862306a36Sopenharmony_ci	case CIT_IBM_NETCAM_PRO:
302962306a36Sopenharmony_ci		has_brightness = has_hue =
303062306a36Sopenharmony_ci			has_sharpness = has_hflip = has_lighting = true;
303162306a36Sopenharmony_ci		break;
303262306a36Sopenharmony_ci	}
303362306a36Sopenharmony_ci	gspca_dev->vdev.ctrl_handler = hdl;
303462306a36Sopenharmony_ci	v4l2_ctrl_handler_init(hdl, 5);
303562306a36Sopenharmony_ci	if (has_brightness)
303662306a36Sopenharmony_ci		v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
303762306a36Sopenharmony_ci			V4L2_CID_BRIGHTNESS, 0, 63, 1, 32);
303862306a36Sopenharmony_ci	if (has_contrast)
303962306a36Sopenharmony_ci		v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
304062306a36Sopenharmony_ci			V4L2_CID_CONTRAST, 0, 20, 1, 10);
304162306a36Sopenharmony_ci	if (has_hue)
304262306a36Sopenharmony_ci		v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
304362306a36Sopenharmony_ci			V4L2_CID_HUE, 0, 127, 1, 63);
304462306a36Sopenharmony_ci	if (has_sharpness)
304562306a36Sopenharmony_ci		v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
304662306a36Sopenharmony_ci			V4L2_CID_SHARPNESS, 0, 6, 1, 3);
304762306a36Sopenharmony_ci	if (has_lighting)
304862306a36Sopenharmony_ci		sd->lighting = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
304962306a36Sopenharmony_ci			V4L2_CID_BACKLIGHT_COMPENSATION, 0, 2, 1, 1);
305062306a36Sopenharmony_ci	if (has_hflip)
305162306a36Sopenharmony_ci		v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
305262306a36Sopenharmony_ci			V4L2_CID_HFLIP, 0, 1, 1, 0);
305362306a36Sopenharmony_ci
305462306a36Sopenharmony_ci	if (hdl->error) {
305562306a36Sopenharmony_ci		pr_err("Could not initialize controls\n");
305662306a36Sopenharmony_ci		return hdl->error;
305762306a36Sopenharmony_ci	}
305862306a36Sopenharmony_ci	return 0;
305962306a36Sopenharmony_ci}
306062306a36Sopenharmony_ci
306162306a36Sopenharmony_ci/* sub-driver description */
306262306a36Sopenharmony_cistatic const struct sd_desc sd_desc = {
306362306a36Sopenharmony_ci	.name = MODULE_NAME,
306462306a36Sopenharmony_ci	.config = sd_config,
306562306a36Sopenharmony_ci	.init = sd_init,
306662306a36Sopenharmony_ci	.init_controls = sd_init_controls,
306762306a36Sopenharmony_ci	.start = sd_start,
306862306a36Sopenharmony_ci	.stopN = sd_stopN,
306962306a36Sopenharmony_ci	.stop0 = sd_stop0,
307062306a36Sopenharmony_ci	.pkt_scan = sd_pkt_scan,
307162306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_INPUT)
307262306a36Sopenharmony_ci	.dq_callback = cit_check_button,
307362306a36Sopenharmony_ci	.other_input = 1,
307462306a36Sopenharmony_ci#endif
307562306a36Sopenharmony_ci};
307662306a36Sopenharmony_ci
307762306a36Sopenharmony_cistatic const struct sd_desc sd_desc_isoc_nego = {
307862306a36Sopenharmony_ci	.name = MODULE_NAME,
307962306a36Sopenharmony_ci	.config = sd_config,
308062306a36Sopenharmony_ci	.init = sd_init,
308162306a36Sopenharmony_ci	.init_controls = sd_init_controls,
308262306a36Sopenharmony_ci	.start = sd_start,
308362306a36Sopenharmony_ci	.isoc_init = sd_isoc_init,
308462306a36Sopenharmony_ci	.isoc_nego = sd_isoc_nego,
308562306a36Sopenharmony_ci	.stopN = sd_stopN,
308662306a36Sopenharmony_ci	.stop0 = sd_stop0,
308762306a36Sopenharmony_ci	.pkt_scan = sd_pkt_scan,
308862306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_INPUT)
308962306a36Sopenharmony_ci	.dq_callback = cit_check_button,
309062306a36Sopenharmony_ci	.other_input = 1,
309162306a36Sopenharmony_ci#endif
309262306a36Sopenharmony_ci};
309362306a36Sopenharmony_ci
309462306a36Sopenharmony_ci/* -- module initialisation -- */
309562306a36Sopenharmony_cistatic const struct usb_device_id device_table[] = {
309662306a36Sopenharmony_ci	{ USB_DEVICE_VER(0x0545, 0x8080, 0x0001, 0x0001), .driver_info = CIT_MODEL0 },
309762306a36Sopenharmony_ci	{ USB_DEVICE_VER(0x0545, 0x8080, 0x0002, 0x0002), .driver_info = CIT_MODEL1 },
309862306a36Sopenharmony_ci	{ USB_DEVICE_VER(0x0545, 0x8080, 0x030a, 0x030a), .driver_info = CIT_MODEL2 },
309962306a36Sopenharmony_ci	{ USB_DEVICE_VER(0x0545, 0x8080, 0x0301, 0x0301), .driver_info = CIT_MODEL3 },
310062306a36Sopenharmony_ci	{ USB_DEVICE_VER(0x0545, 0x8002, 0x030a, 0x030a), .driver_info = CIT_MODEL4 },
310162306a36Sopenharmony_ci	{ USB_DEVICE_VER(0x0545, 0x800c, 0x030a, 0x030a), .driver_info = CIT_MODEL2 },
310262306a36Sopenharmony_ci	{ USB_DEVICE_VER(0x0545, 0x800d, 0x030a, 0x030a), .driver_info = CIT_MODEL4 },
310362306a36Sopenharmony_ci	{}
310462306a36Sopenharmony_ci};
310562306a36Sopenharmony_ciMODULE_DEVICE_TABLE(usb, device_table);
310662306a36Sopenharmony_ci
310762306a36Sopenharmony_ci/* -- device connect -- */
310862306a36Sopenharmony_cistatic int sd_probe(struct usb_interface *intf,
310962306a36Sopenharmony_ci			const struct usb_device_id *id)
311062306a36Sopenharmony_ci{
311162306a36Sopenharmony_ci	const struct sd_desc *desc = &sd_desc;
311262306a36Sopenharmony_ci
311362306a36Sopenharmony_ci	switch (id->driver_info) {
311462306a36Sopenharmony_ci	case CIT_MODEL0:
311562306a36Sopenharmony_ci	case CIT_MODEL1:
311662306a36Sopenharmony_ci		if (intf->cur_altsetting->desc.bInterfaceNumber != 2)
311762306a36Sopenharmony_ci			return -ENODEV;
311862306a36Sopenharmony_ci		break;
311962306a36Sopenharmony_ci	case CIT_MODEL2:
312062306a36Sopenharmony_ci	case CIT_MODEL4:
312162306a36Sopenharmony_ci		if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
312262306a36Sopenharmony_ci			return -ENODEV;
312362306a36Sopenharmony_ci		break;
312462306a36Sopenharmony_ci	case CIT_MODEL3:
312562306a36Sopenharmony_ci		if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
312662306a36Sopenharmony_ci			return -ENODEV;
312762306a36Sopenharmony_ci		/* FIXME this likely applies to all model3 cams and probably
312862306a36Sopenharmony_ci		   to other models too. */
312962306a36Sopenharmony_ci		if (ibm_netcam_pro)
313062306a36Sopenharmony_ci			desc = &sd_desc_isoc_nego;
313162306a36Sopenharmony_ci		break;
313262306a36Sopenharmony_ci	}
313362306a36Sopenharmony_ci
313462306a36Sopenharmony_ci	return gspca_dev_probe2(intf, id, desc, sizeof(struct sd), THIS_MODULE);
313562306a36Sopenharmony_ci}
313662306a36Sopenharmony_ci
313762306a36Sopenharmony_cistatic struct usb_driver sd_driver = {
313862306a36Sopenharmony_ci	.name = MODULE_NAME,
313962306a36Sopenharmony_ci	.id_table = device_table,
314062306a36Sopenharmony_ci	.probe = sd_probe,
314162306a36Sopenharmony_ci	.disconnect = gspca_disconnect,
314262306a36Sopenharmony_ci#ifdef CONFIG_PM
314362306a36Sopenharmony_ci	.suspend = gspca_suspend,
314462306a36Sopenharmony_ci	.resume = gspca_resume,
314562306a36Sopenharmony_ci	.reset_resume = gspca_resume,
314662306a36Sopenharmony_ci#endif
314762306a36Sopenharmony_ci};
314862306a36Sopenharmony_ci
314962306a36Sopenharmony_cimodule_usb_driver(sd_driver);
3150