1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * USB IBM C-It Video Camera driver
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Supports Xirlink C-It Video Camera, IBM PC Camera,
6*4882a593Smuzhiyun * IBM NetCamera and Veo Stingray.
7*4882a593Smuzhiyun *
8*4882a593Smuzhiyun * Copyright (C) 2010 Hans de Goede <hdegoede@redhat.com>
9*4882a593Smuzhiyun *
10*4882a593Smuzhiyun * This driver is based on earlier work of:
11*4882a593Smuzhiyun *
12*4882a593Smuzhiyun * (C) Copyright 1999 Johannes Erdfelt
13*4882a593Smuzhiyun * (C) Copyright 1999 Randy Dunlap
14*4882a593Smuzhiyun */
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
17*4882a593Smuzhiyun
18*4882a593Smuzhiyun #define MODULE_NAME "xirlink-cit"
19*4882a593Smuzhiyun
20*4882a593Smuzhiyun #include <linux/input.h>
21*4882a593Smuzhiyun #include "gspca.h"
22*4882a593Smuzhiyun
23*4882a593Smuzhiyun MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
24*4882a593Smuzhiyun MODULE_DESCRIPTION("Xirlink C-IT");
25*4882a593Smuzhiyun MODULE_LICENSE("GPL");
26*4882a593Smuzhiyun
27*4882a593Smuzhiyun /* FIXME we should autodetect this */
28*4882a593Smuzhiyun static int ibm_netcam_pro;
29*4882a593Smuzhiyun module_param(ibm_netcam_pro, int, 0);
30*4882a593Smuzhiyun MODULE_PARM_DESC(ibm_netcam_pro,
31*4882a593Smuzhiyun "Use IBM Netcamera Pro init sequences for Model 3 cams");
32*4882a593Smuzhiyun
33*4882a593Smuzhiyun /* FIXME this should be handled through the V4L2 input selection API */
34*4882a593Smuzhiyun static int rca_input;
35*4882a593Smuzhiyun module_param(rca_input, int, 0644);
36*4882a593Smuzhiyun MODULE_PARM_DESC(rca_input,
37*4882a593Smuzhiyun "Use rca input instead of ccd sensor on Model 3 cams");
38*4882a593Smuzhiyun
39*4882a593Smuzhiyun /* specific webcam descriptor */
40*4882a593Smuzhiyun struct sd {
41*4882a593Smuzhiyun struct gspca_dev gspca_dev; /* !! must be the first item */
42*4882a593Smuzhiyun struct v4l2_ctrl *lighting;
43*4882a593Smuzhiyun u8 model;
44*4882a593Smuzhiyun #define CIT_MODEL0 0 /* bcd version 0.01 cams ie the xvp-500 */
45*4882a593Smuzhiyun #define CIT_MODEL1 1 /* The model 1 - 4 nomenclature comes from the old */
46*4882a593Smuzhiyun #define CIT_MODEL2 2 /* ibmcam driver */
47*4882a593Smuzhiyun #define CIT_MODEL3 3
48*4882a593Smuzhiyun #define CIT_MODEL4 4
49*4882a593Smuzhiyun #define CIT_IBM_NETCAM_PRO 5
50*4882a593Smuzhiyun u8 input_index;
51*4882a593Smuzhiyun u8 button_state;
52*4882a593Smuzhiyun u8 stop_on_control_change;
53*4882a593Smuzhiyun u8 sof_read;
54*4882a593Smuzhiyun u8 sof_len;
55*4882a593Smuzhiyun };
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun static void sd_stop0(struct gspca_dev *gspca_dev);
58*4882a593Smuzhiyun
59*4882a593Smuzhiyun static const struct v4l2_pix_format cif_yuv_mode[] = {
60*4882a593Smuzhiyun {176, 144, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
61*4882a593Smuzhiyun .bytesperline = 176,
62*4882a593Smuzhiyun .sizeimage = 176 * 144 * 3 / 2 + 4,
63*4882a593Smuzhiyun .colorspace = V4L2_COLORSPACE_SRGB},
64*4882a593Smuzhiyun {352, 288, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
65*4882a593Smuzhiyun .bytesperline = 352,
66*4882a593Smuzhiyun .sizeimage = 352 * 288 * 3 / 2 + 4,
67*4882a593Smuzhiyun .colorspace = V4L2_COLORSPACE_SRGB},
68*4882a593Smuzhiyun };
69*4882a593Smuzhiyun
70*4882a593Smuzhiyun static const struct v4l2_pix_format vga_yuv_mode[] = {
71*4882a593Smuzhiyun {160, 120, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
72*4882a593Smuzhiyun .bytesperline = 160,
73*4882a593Smuzhiyun .sizeimage = 160 * 120 * 3 / 2 + 4,
74*4882a593Smuzhiyun .colorspace = V4L2_COLORSPACE_SRGB},
75*4882a593Smuzhiyun {320, 240, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
76*4882a593Smuzhiyun .bytesperline = 320,
77*4882a593Smuzhiyun .sizeimage = 320 * 240 * 3 / 2 + 4,
78*4882a593Smuzhiyun .colorspace = V4L2_COLORSPACE_SRGB},
79*4882a593Smuzhiyun {640, 480, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
80*4882a593Smuzhiyun .bytesperline = 640,
81*4882a593Smuzhiyun .sizeimage = 640 * 480 * 3 / 2 + 4,
82*4882a593Smuzhiyun .colorspace = V4L2_COLORSPACE_SRGB},
83*4882a593Smuzhiyun };
84*4882a593Smuzhiyun
85*4882a593Smuzhiyun static const struct v4l2_pix_format model0_mode[] = {
86*4882a593Smuzhiyun {160, 120, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
87*4882a593Smuzhiyun .bytesperline = 160,
88*4882a593Smuzhiyun .sizeimage = 160 * 120 * 3 / 2 + 4,
89*4882a593Smuzhiyun .colorspace = V4L2_COLORSPACE_SRGB},
90*4882a593Smuzhiyun {176, 144, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
91*4882a593Smuzhiyun .bytesperline = 176,
92*4882a593Smuzhiyun .sizeimage = 176 * 144 * 3 / 2 + 4,
93*4882a593Smuzhiyun .colorspace = V4L2_COLORSPACE_SRGB},
94*4882a593Smuzhiyun {320, 240, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
95*4882a593Smuzhiyun .bytesperline = 320,
96*4882a593Smuzhiyun .sizeimage = 320 * 240 * 3 / 2 + 4,
97*4882a593Smuzhiyun .colorspace = V4L2_COLORSPACE_SRGB},
98*4882a593Smuzhiyun };
99*4882a593Smuzhiyun
100*4882a593Smuzhiyun static const struct v4l2_pix_format model2_mode[] = {
101*4882a593Smuzhiyun {160, 120, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
102*4882a593Smuzhiyun .bytesperline = 160,
103*4882a593Smuzhiyun .sizeimage = 160 * 120 * 3 / 2 + 4,
104*4882a593Smuzhiyun .colorspace = V4L2_COLORSPACE_SRGB},
105*4882a593Smuzhiyun {176, 144, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE,
106*4882a593Smuzhiyun .bytesperline = 176,
107*4882a593Smuzhiyun .sizeimage = 176 * 144 * 3 / 2 + 4,
108*4882a593Smuzhiyun .colorspace = V4L2_COLORSPACE_SRGB},
109*4882a593Smuzhiyun {320, 240, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
110*4882a593Smuzhiyun .bytesperline = 320,
111*4882a593Smuzhiyun .sizeimage = 320 * 240 + 4,
112*4882a593Smuzhiyun .colorspace = V4L2_COLORSPACE_SRGB},
113*4882a593Smuzhiyun {352, 288, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
114*4882a593Smuzhiyun .bytesperline = 352,
115*4882a593Smuzhiyun .sizeimage = 352 * 288 + 4,
116*4882a593Smuzhiyun .colorspace = V4L2_COLORSPACE_SRGB},
117*4882a593Smuzhiyun };
118*4882a593Smuzhiyun
119*4882a593Smuzhiyun /*
120*4882a593Smuzhiyun * 01.01.08 - Added for RCA video in support -LO
121*4882a593Smuzhiyun * This struct is used to init the Model3 cam to use the RCA video in port
122*4882a593Smuzhiyun * instead of the CCD sensor.
123*4882a593Smuzhiyun */
124*4882a593Smuzhiyun static const u16 rca_initdata[][3] = {
125*4882a593Smuzhiyun {0, 0x0000, 0x010c},
126*4882a593Smuzhiyun {0, 0x0006, 0x012c},
127*4882a593Smuzhiyun {0, 0x0078, 0x012d},
128*4882a593Smuzhiyun {0, 0x0046, 0x012f},
129*4882a593Smuzhiyun {0, 0xd141, 0x0124},
130*4882a593Smuzhiyun {0, 0x0000, 0x0127},
131*4882a593Smuzhiyun {0, 0xfea8, 0x0124},
132*4882a593Smuzhiyun {1, 0x0000, 0x0116},
133*4882a593Smuzhiyun {0, 0x0064, 0x0116},
134*4882a593Smuzhiyun {1, 0x0000, 0x0115},
135*4882a593Smuzhiyun {0, 0x0003, 0x0115},
136*4882a593Smuzhiyun {0, 0x0008, 0x0123},
137*4882a593Smuzhiyun {0, 0x0000, 0x0117},
138*4882a593Smuzhiyun {0, 0x0000, 0x0112},
139*4882a593Smuzhiyun {0, 0x0080, 0x0100},
140*4882a593Smuzhiyun {0, 0x0000, 0x0100},
141*4882a593Smuzhiyun {1, 0x0000, 0x0116},
142*4882a593Smuzhiyun {0, 0x0060, 0x0116},
143*4882a593Smuzhiyun {0, 0x0002, 0x0112},
144*4882a593Smuzhiyun {0, 0x0000, 0x0123},
145*4882a593Smuzhiyun {0, 0x0001, 0x0117},
146*4882a593Smuzhiyun {0, 0x0040, 0x0108},
147*4882a593Smuzhiyun {0, 0x0019, 0x012c},
148*4882a593Smuzhiyun {0, 0x0040, 0x0116},
149*4882a593Smuzhiyun {0, 0x000a, 0x0115},
150*4882a593Smuzhiyun {0, 0x000b, 0x0115},
151*4882a593Smuzhiyun {0, 0x0078, 0x012d},
152*4882a593Smuzhiyun {0, 0x0046, 0x012f},
153*4882a593Smuzhiyun {0, 0xd141, 0x0124},
154*4882a593Smuzhiyun {0, 0x0000, 0x0127},
155*4882a593Smuzhiyun {0, 0xfea8, 0x0124},
156*4882a593Smuzhiyun {0, 0x0064, 0x0116},
157*4882a593Smuzhiyun {0, 0x0000, 0x0115},
158*4882a593Smuzhiyun {0, 0x0001, 0x0115},
159*4882a593Smuzhiyun {0, 0xffff, 0x0124},
160*4882a593Smuzhiyun {0, 0xfff9, 0x0124},
161*4882a593Smuzhiyun {0, 0x0086, 0x0127},
162*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
163*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
164*4882a593Smuzhiyun {0, 0x00aa, 0x0127},
165*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
166*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
167*4882a593Smuzhiyun {0, 0x0000, 0x0127},
168*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
169*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
170*4882a593Smuzhiyun {0, 0xfffa, 0x0124},
171*4882a593Smuzhiyun {0, 0xffff, 0x0124},
172*4882a593Smuzhiyun {0, 0xfff9, 0x0124},
173*4882a593Smuzhiyun {0, 0x0086, 0x0127},
174*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
175*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
176*4882a593Smuzhiyun {0, 0x00f2, 0x0127},
177*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
178*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
179*4882a593Smuzhiyun {0, 0x000f, 0x0127},
180*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
181*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
182*4882a593Smuzhiyun {0, 0xfffa, 0x0124},
183*4882a593Smuzhiyun {0, 0xffff, 0x0124},
184*4882a593Smuzhiyun {0, 0xfff9, 0x0124},
185*4882a593Smuzhiyun {0, 0x0086, 0x0127},
186*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
187*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
188*4882a593Smuzhiyun {0, 0x00f8, 0x0127},
189*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
190*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
191*4882a593Smuzhiyun {0, 0x00fc, 0x0127},
192*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
193*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
194*4882a593Smuzhiyun {0, 0xfffa, 0x0124},
195*4882a593Smuzhiyun {0, 0xffff, 0x0124},
196*4882a593Smuzhiyun {0, 0xfff9, 0x0124},
197*4882a593Smuzhiyun {0, 0x0086, 0x0127},
198*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
199*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
200*4882a593Smuzhiyun {0, 0x00f9, 0x0127},
201*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
202*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
203*4882a593Smuzhiyun {0, 0x003c, 0x0127},
204*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
205*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
206*4882a593Smuzhiyun {0, 0xfffa, 0x0124},
207*4882a593Smuzhiyun {0, 0xffff, 0x0124},
208*4882a593Smuzhiyun {0, 0xfff9, 0x0124},
209*4882a593Smuzhiyun {0, 0x0086, 0x0127},
210*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
211*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
212*4882a593Smuzhiyun {0, 0x0027, 0x0127},
213*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
214*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
215*4882a593Smuzhiyun {0, 0x0019, 0x0127},
216*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
217*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
218*4882a593Smuzhiyun {0, 0xfffa, 0x0124},
219*4882a593Smuzhiyun {0, 0xfff9, 0x0124},
220*4882a593Smuzhiyun {0, 0x0086, 0x0127},
221*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
222*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
223*4882a593Smuzhiyun {0, 0x0037, 0x0127},
224*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
225*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
226*4882a593Smuzhiyun {0, 0x0000, 0x0127},
227*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
228*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
229*4882a593Smuzhiyun {0, 0x0021, 0x0127},
230*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
231*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
232*4882a593Smuzhiyun {0, 0xfffa, 0x0124},
233*4882a593Smuzhiyun {0, 0xfff9, 0x0124},
234*4882a593Smuzhiyun {0, 0x0086, 0x0127},
235*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
236*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
237*4882a593Smuzhiyun {0, 0x0038, 0x0127},
238*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
239*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
240*4882a593Smuzhiyun {0, 0x0006, 0x0127},
241*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
242*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
243*4882a593Smuzhiyun {0, 0x0045, 0x0127},
244*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
245*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
246*4882a593Smuzhiyun {0, 0xfffa, 0x0124},
247*4882a593Smuzhiyun {0, 0xfff9, 0x0124},
248*4882a593Smuzhiyun {0, 0x0086, 0x0127},
249*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
250*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
251*4882a593Smuzhiyun {0, 0x0037, 0x0127},
252*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
253*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
254*4882a593Smuzhiyun {0, 0x0001, 0x0127},
255*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
256*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
257*4882a593Smuzhiyun {0, 0x002a, 0x0127},
258*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
259*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
260*4882a593Smuzhiyun {0, 0xfffa, 0x0124},
261*4882a593Smuzhiyun {0, 0xfff9, 0x0124},
262*4882a593Smuzhiyun {0, 0x0086, 0x0127},
263*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
264*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
265*4882a593Smuzhiyun {0, 0x0038, 0x0127},
266*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
267*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
268*4882a593Smuzhiyun {0, 0x0000, 0x0127},
269*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
270*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
271*4882a593Smuzhiyun {0, 0x000e, 0x0127},
272*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
273*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
274*4882a593Smuzhiyun {0, 0xfffa, 0x0124},
275*4882a593Smuzhiyun {0, 0xfff9, 0x0124},
276*4882a593Smuzhiyun {0, 0x0086, 0x0127},
277*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
278*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
279*4882a593Smuzhiyun {0, 0x0037, 0x0127},
280*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
281*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
282*4882a593Smuzhiyun {0, 0x0001, 0x0127},
283*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
284*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
285*4882a593Smuzhiyun {0, 0x002b, 0x0127},
286*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
287*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
288*4882a593Smuzhiyun {0, 0xfffa, 0x0124},
289*4882a593Smuzhiyun {0, 0xfff9, 0x0124},
290*4882a593Smuzhiyun {0, 0x0086, 0x0127},
291*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
292*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
293*4882a593Smuzhiyun {0, 0x0038, 0x0127},
294*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
295*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
296*4882a593Smuzhiyun {0, 0x0001, 0x0127},
297*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
298*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
299*4882a593Smuzhiyun {0, 0x00f4, 0x0127},
300*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
301*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
302*4882a593Smuzhiyun {0, 0xfffa, 0x0124},
303*4882a593Smuzhiyun {0, 0xfff9, 0x0124},
304*4882a593Smuzhiyun {0, 0x0086, 0x0127},
305*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
306*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
307*4882a593Smuzhiyun {0, 0x0037, 0x0127},
308*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
309*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
310*4882a593Smuzhiyun {0, 0x0001, 0x0127},
311*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
312*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
313*4882a593Smuzhiyun {0, 0x002c, 0x0127},
314*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
315*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
316*4882a593Smuzhiyun {0, 0xfffa, 0x0124},
317*4882a593Smuzhiyun {0, 0xfff9, 0x0124},
318*4882a593Smuzhiyun {0, 0x0086, 0x0127},
319*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
320*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
321*4882a593Smuzhiyun {0, 0x0038, 0x0127},
322*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
323*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
324*4882a593Smuzhiyun {0, 0x0001, 0x0127},
325*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
326*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
327*4882a593Smuzhiyun {0, 0x0004, 0x0127},
328*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
329*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
330*4882a593Smuzhiyun {0, 0xfffa, 0x0124},
331*4882a593Smuzhiyun {0, 0xfff9, 0x0124},
332*4882a593Smuzhiyun {0, 0x0086, 0x0127},
333*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
334*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
335*4882a593Smuzhiyun {0, 0x0037, 0x0127},
336*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
337*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
338*4882a593Smuzhiyun {0, 0x0001, 0x0127},
339*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
340*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
341*4882a593Smuzhiyun {0, 0x002d, 0x0127},
342*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
343*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
344*4882a593Smuzhiyun {0, 0xfffa, 0x0124},
345*4882a593Smuzhiyun {0, 0xfff9, 0x0124},
346*4882a593Smuzhiyun {0, 0x0086, 0x0127},
347*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
348*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
349*4882a593Smuzhiyun {0, 0x0038, 0x0127},
350*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
351*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
352*4882a593Smuzhiyun {0, 0x0000, 0x0127},
353*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
354*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
355*4882a593Smuzhiyun {0, 0x0014, 0x0127},
356*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
357*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
358*4882a593Smuzhiyun {0, 0xfffa, 0x0124},
359*4882a593Smuzhiyun {0, 0xfff9, 0x0124},
360*4882a593Smuzhiyun {0, 0x0086, 0x0127},
361*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
362*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
363*4882a593Smuzhiyun {0, 0x0037, 0x0127},
364*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
365*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
366*4882a593Smuzhiyun {0, 0x0001, 0x0127},
367*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
368*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
369*4882a593Smuzhiyun {0, 0x002e, 0x0127},
370*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
371*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
372*4882a593Smuzhiyun {0, 0xfffa, 0x0124},
373*4882a593Smuzhiyun {0, 0xfff9, 0x0124},
374*4882a593Smuzhiyun {0, 0x0086, 0x0127},
375*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
376*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
377*4882a593Smuzhiyun {0, 0x0038, 0x0127},
378*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
379*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
380*4882a593Smuzhiyun {0, 0x0003, 0x0127},
381*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
382*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
383*4882a593Smuzhiyun {0, 0x0000, 0x0127},
384*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
385*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
386*4882a593Smuzhiyun {0, 0xfffa, 0x0124},
387*4882a593Smuzhiyun {0, 0xfff9, 0x0124},
388*4882a593Smuzhiyun {0, 0x0086, 0x0127},
389*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
390*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
391*4882a593Smuzhiyun {0, 0x0037, 0x0127},
392*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
393*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
394*4882a593Smuzhiyun {0, 0x0001, 0x0127},
395*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
396*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
397*4882a593Smuzhiyun {0, 0x002f, 0x0127},
398*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
399*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
400*4882a593Smuzhiyun {0, 0xfffa, 0x0124},
401*4882a593Smuzhiyun {0, 0xfff9, 0x0124},
402*4882a593Smuzhiyun {0, 0x0086, 0x0127},
403*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
404*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
405*4882a593Smuzhiyun {0, 0x0038, 0x0127},
406*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
407*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
408*4882a593Smuzhiyun {0, 0x0003, 0x0127},
409*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
410*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
411*4882a593Smuzhiyun {0, 0x0014, 0x0127},
412*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
413*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
414*4882a593Smuzhiyun {0, 0xfffa, 0x0124},
415*4882a593Smuzhiyun {0, 0xfff9, 0x0124},
416*4882a593Smuzhiyun {0, 0x0086, 0x0127},
417*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
418*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
419*4882a593Smuzhiyun {0, 0x0037, 0x0127},
420*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
421*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
422*4882a593Smuzhiyun {0, 0x0001, 0x0127},
423*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
424*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
425*4882a593Smuzhiyun {0, 0x0040, 0x0127},
426*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
427*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
428*4882a593Smuzhiyun {0, 0xfffa, 0x0124},
429*4882a593Smuzhiyun {0, 0xfff9, 0x0124},
430*4882a593Smuzhiyun {0, 0x0086, 0x0127},
431*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
432*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
433*4882a593Smuzhiyun {0, 0x0038, 0x0127},
434*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
435*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
436*4882a593Smuzhiyun {0, 0x0000, 0x0127},
437*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
438*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
439*4882a593Smuzhiyun {0, 0x0040, 0x0127},
440*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
441*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
442*4882a593Smuzhiyun {0, 0xfffa, 0x0124},
443*4882a593Smuzhiyun {0, 0xfff9, 0x0124},
444*4882a593Smuzhiyun {0, 0x0086, 0x0127},
445*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
446*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
447*4882a593Smuzhiyun {0, 0x0037, 0x0127},
448*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
449*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
450*4882a593Smuzhiyun {0, 0x0001, 0x0127},
451*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
452*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
453*4882a593Smuzhiyun {0, 0x0053, 0x0127},
454*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
455*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
456*4882a593Smuzhiyun {0, 0xfffa, 0x0124},
457*4882a593Smuzhiyun {0, 0xfff9, 0x0124},
458*4882a593Smuzhiyun {0, 0x0086, 0x0127},
459*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
460*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
461*4882a593Smuzhiyun {0, 0x0038, 0x0127},
462*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
463*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
464*4882a593Smuzhiyun {0, 0x0000, 0x0127},
465*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
466*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
467*4882a593Smuzhiyun {0, 0x0038, 0x0127},
468*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
469*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
470*4882a593Smuzhiyun {0, 0xfffa, 0x0124},
471*4882a593Smuzhiyun {0, 0x0000, 0x0101},
472*4882a593Smuzhiyun {0, 0x00a0, 0x0103},
473*4882a593Smuzhiyun {0, 0x0078, 0x0105},
474*4882a593Smuzhiyun {0, 0x0000, 0x010a},
475*4882a593Smuzhiyun {0, 0x0024, 0x010b},
476*4882a593Smuzhiyun {0, 0x0028, 0x0119},
477*4882a593Smuzhiyun {0, 0x0088, 0x011b},
478*4882a593Smuzhiyun {0, 0x0002, 0x011d},
479*4882a593Smuzhiyun {0, 0x0003, 0x011e},
480*4882a593Smuzhiyun {0, 0x0000, 0x0129},
481*4882a593Smuzhiyun {0, 0x00fc, 0x012b},
482*4882a593Smuzhiyun {0, 0x0008, 0x0102},
483*4882a593Smuzhiyun {0, 0x0000, 0x0104},
484*4882a593Smuzhiyun {0, 0x0008, 0x011a},
485*4882a593Smuzhiyun {0, 0x0028, 0x011c},
486*4882a593Smuzhiyun {0, 0x0021, 0x012a},
487*4882a593Smuzhiyun {0, 0x0000, 0x0118},
488*4882a593Smuzhiyun {0, 0x0000, 0x0132},
489*4882a593Smuzhiyun {0, 0x0000, 0x0109},
490*4882a593Smuzhiyun {0, 0xfff9, 0x0124},
491*4882a593Smuzhiyun {0, 0x0086, 0x0127},
492*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
493*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
494*4882a593Smuzhiyun {0, 0x0037, 0x0127},
495*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
496*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
497*4882a593Smuzhiyun {0, 0x0001, 0x0127},
498*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
499*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
500*4882a593Smuzhiyun {0, 0x0031, 0x0127},
501*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
502*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
503*4882a593Smuzhiyun {0, 0xfffa, 0x0124},
504*4882a593Smuzhiyun {0, 0xfff9, 0x0124},
505*4882a593Smuzhiyun {0, 0x0086, 0x0127},
506*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
507*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
508*4882a593Smuzhiyun {0, 0x0038, 0x0127},
509*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
510*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
511*4882a593Smuzhiyun {0, 0x0000, 0x0127},
512*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
513*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
514*4882a593Smuzhiyun {0, 0x0000, 0x0127},
515*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
516*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
517*4882a593Smuzhiyun {0, 0xfffa, 0x0124},
518*4882a593Smuzhiyun {0, 0xfff9, 0x0124},
519*4882a593Smuzhiyun {0, 0x0086, 0x0127},
520*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
521*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
522*4882a593Smuzhiyun {0, 0x0037, 0x0127},
523*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
524*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
525*4882a593Smuzhiyun {0, 0x0001, 0x0127},
526*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
527*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
528*4882a593Smuzhiyun {0, 0x0040, 0x0127},
529*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
530*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
531*4882a593Smuzhiyun {0, 0xfffa, 0x0124},
532*4882a593Smuzhiyun {0, 0xfff9, 0x0124},
533*4882a593Smuzhiyun {0, 0x0086, 0x0127},
534*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
535*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
536*4882a593Smuzhiyun {0, 0x0038, 0x0127},
537*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
538*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
539*4882a593Smuzhiyun {0, 0x0000, 0x0127},
540*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
541*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
542*4882a593Smuzhiyun {0, 0x0040, 0x0127},
543*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
544*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
545*4882a593Smuzhiyun {0, 0xfffa, 0x0124},
546*4882a593Smuzhiyun {0, 0xfff9, 0x0124},
547*4882a593Smuzhiyun {0, 0x0086, 0x0127},
548*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
549*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
550*4882a593Smuzhiyun {0, 0x0037, 0x0127},
551*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
552*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
553*4882a593Smuzhiyun {0, 0x0000, 0x0127},
554*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
555*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
556*4882a593Smuzhiyun {0, 0x00dc, 0x0127},
557*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
558*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
559*4882a593Smuzhiyun {0, 0xfffa, 0x0124},
560*4882a593Smuzhiyun {0, 0xfff9, 0x0124},
561*4882a593Smuzhiyun {0, 0x0086, 0x0127},
562*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
563*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
564*4882a593Smuzhiyun {0, 0x0038, 0x0127},
565*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
566*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
567*4882a593Smuzhiyun {0, 0x0000, 0x0127},
568*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
569*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
570*4882a593Smuzhiyun {0, 0x0000, 0x0127},
571*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
572*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
573*4882a593Smuzhiyun {0, 0xfffa, 0x0124},
574*4882a593Smuzhiyun {0, 0xfff9, 0x0124},
575*4882a593Smuzhiyun {0, 0x0086, 0x0127},
576*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
577*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
578*4882a593Smuzhiyun {0, 0x0037, 0x0127},
579*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
580*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
581*4882a593Smuzhiyun {0, 0x0001, 0x0127},
582*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
583*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
584*4882a593Smuzhiyun {0, 0x0032, 0x0127},
585*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
586*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
587*4882a593Smuzhiyun {0, 0xfffa, 0x0124},
588*4882a593Smuzhiyun {0, 0xfff9, 0x0124},
589*4882a593Smuzhiyun {0, 0x0086, 0x0127},
590*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
591*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
592*4882a593Smuzhiyun {0, 0x0038, 0x0127},
593*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
594*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
595*4882a593Smuzhiyun {0, 0x0001, 0x0127},
596*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
597*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
598*4882a593Smuzhiyun {0, 0x0020, 0x0127},
599*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
600*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
601*4882a593Smuzhiyun {0, 0xfffa, 0x0124},
602*4882a593Smuzhiyun {0, 0xfff9, 0x0124},
603*4882a593Smuzhiyun {0, 0x0086, 0x0127},
604*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
605*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
606*4882a593Smuzhiyun {0, 0x0037, 0x0127},
607*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
608*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
609*4882a593Smuzhiyun {0, 0x0001, 0x0127},
610*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
611*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
612*4882a593Smuzhiyun {0, 0x0040, 0x0127},
613*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
614*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
615*4882a593Smuzhiyun {0, 0xfffa, 0x0124},
616*4882a593Smuzhiyun {0, 0xfff9, 0x0124},
617*4882a593Smuzhiyun {0, 0x0086, 0x0127},
618*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
619*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
620*4882a593Smuzhiyun {0, 0x0038, 0x0127},
621*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
622*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
623*4882a593Smuzhiyun {0, 0x0000, 0x0127},
624*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
625*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
626*4882a593Smuzhiyun {0, 0x0040, 0x0127},
627*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
628*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
629*4882a593Smuzhiyun {0, 0xfffa, 0x0124},
630*4882a593Smuzhiyun {0, 0xfff9, 0x0124},
631*4882a593Smuzhiyun {0, 0x0086, 0x0127},
632*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
633*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
634*4882a593Smuzhiyun {0, 0x0037, 0x0127},
635*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
636*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
637*4882a593Smuzhiyun {0, 0x0000, 0x0127},
638*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
639*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
640*4882a593Smuzhiyun {0, 0x0030, 0x0127},
641*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
642*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
643*4882a593Smuzhiyun {0, 0xfffa, 0x0124},
644*4882a593Smuzhiyun {0, 0xfff9, 0x0124},
645*4882a593Smuzhiyun {0, 0x0086, 0x0127},
646*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
647*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
648*4882a593Smuzhiyun {0, 0x0038, 0x0127},
649*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
650*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
651*4882a593Smuzhiyun {0, 0x0008, 0x0127},
652*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
653*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
654*4882a593Smuzhiyun {0, 0x0000, 0x0127},
655*4882a593Smuzhiyun {0, 0xfff8, 0x0124},
656*4882a593Smuzhiyun {0, 0xfffd, 0x0124},
657*4882a593Smuzhiyun {0, 0xfffa, 0x0124},
658*4882a593Smuzhiyun {0, 0x0003, 0x0111},
659*4882a593Smuzhiyun };
660*4882a593Smuzhiyun
661*4882a593Smuzhiyun /* TESTME the old ibmcam driver repeats certain commands to Model1 cameras, we
662*4882a593Smuzhiyun do the same for now (testing needed to see if this is really necessary) */
663*4882a593Smuzhiyun static const int cit_model1_ntries = 5;
664*4882a593Smuzhiyun static const int cit_model1_ntries2 = 2;
665*4882a593Smuzhiyun
cit_write_reg(struct gspca_dev * gspca_dev,u16 value,u16 index)666*4882a593Smuzhiyun static int cit_write_reg(struct gspca_dev *gspca_dev, u16 value, u16 index)
667*4882a593Smuzhiyun {
668*4882a593Smuzhiyun struct usb_device *udev = gspca_dev->dev;
669*4882a593Smuzhiyun int err;
670*4882a593Smuzhiyun
671*4882a593Smuzhiyun err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00,
672*4882a593Smuzhiyun USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT,
673*4882a593Smuzhiyun value, index, NULL, 0, 1000);
674*4882a593Smuzhiyun if (err < 0)
675*4882a593Smuzhiyun pr_err("Failed to write a register (index 0x%04X, value 0x%02X, error %d)\n",
676*4882a593Smuzhiyun index, value, err);
677*4882a593Smuzhiyun
678*4882a593Smuzhiyun return 0;
679*4882a593Smuzhiyun }
680*4882a593Smuzhiyun
cit_read_reg(struct gspca_dev * gspca_dev,u16 index,int verbose)681*4882a593Smuzhiyun static int cit_read_reg(struct gspca_dev *gspca_dev, u16 index, int verbose)
682*4882a593Smuzhiyun {
683*4882a593Smuzhiyun struct usb_device *udev = gspca_dev->dev;
684*4882a593Smuzhiyun __u8 *buf = gspca_dev->usb_buf;
685*4882a593Smuzhiyun int res;
686*4882a593Smuzhiyun
687*4882a593Smuzhiyun res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x01,
688*4882a593Smuzhiyun USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT,
689*4882a593Smuzhiyun 0x00, index, buf, 8, 1000);
690*4882a593Smuzhiyun if (res < 0) {
691*4882a593Smuzhiyun pr_err("Failed to read a register (index 0x%04X, error %d)\n",
692*4882a593Smuzhiyun index, res);
693*4882a593Smuzhiyun return res;
694*4882a593Smuzhiyun }
695*4882a593Smuzhiyun
696*4882a593Smuzhiyun if (verbose)
697*4882a593Smuzhiyun gspca_dbg(gspca_dev, D_PROBE, "Register %04x value: %02x\n",
698*4882a593Smuzhiyun index, buf[0]);
699*4882a593Smuzhiyun
700*4882a593Smuzhiyun return 0;
701*4882a593Smuzhiyun }
702*4882a593Smuzhiyun
703*4882a593Smuzhiyun /*
704*4882a593Smuzhiyun * cit_send_FF_04_02()
705*4882a593Smuzhiyun *
706*4882a593Smuzhiyun * This procedure sends magic 3-command prefix to the camera.
707*4882a593Smuzhiyun * The purpose of this prefix is not known.
708*4882a593Smuzhiyun *
709*4882a593Smuzhiyun * History:
710*4882a593Smuzhiyun * 1/2/00 Created.
711*4882a593Smuzhiyun */
cit_send_FF_04_02(struct gspca_dev * gspca_dev)712*4882a593Smuzhiyun static void cit_send_FF_04_02(struct gspca_dev *gspca_dev)
713*4882a593Smuzhiyun {
714*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00FF, 0x0127);
715*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0004, 0x0124);
716*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0002, 0x0124);
717*4882a593Smuzhiyun }
718*4882a593Smuzhiyun
cit_send_00_04_06(struct gspca_dev * gspca_dev)719*4882a593Smuzhiyun static void cit_send_00_04_06(struct gspca_dev *gspca_dev)
720*4882a593Smuzhiyun {
721*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0127);
722*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0004, 0x0124);
723*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0006, 0x0124);
724*4882a593Smuzhiyun }
725*4882a593Smuzhiyun
cit_send_x_00(struct gspca_dev * gspca_dev,unsigned short x)726*4882a593Smuzhiyun static void cit_send_x_00(struct gspca_dev *gspca_dev, unsigned short x)
727*4882a593Smuzhiyun {
728*4882a593Smuzhiyun cit_write_reg(gspca_dev, x, 0x0127);
729*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0124);
730*4882a593Smuzhiyun }
731*4882a593Smuzhiyun
cit_send_x_00_05(struct gspca_dev * gspca_dev,unsigned short x)732*4882a593Smuzhiyun static void cit_send_x_00_05(struct gspca_dev *gspca_dev, unsigned short x)
733*4882a593Smuzhiyun {
734*4882a593Smuzhiyun cit_send_x_00(gspca_dev, x);
735*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0005, 0x0124);
736*4882a593Smuzhiyun }
737*4882a593Smuzhiyun
cit_send_x_00_05_02(struct gspca_dev * gspca_dev,unsigned short x)738*4882a593Smuzhiyun static void cit_send_x_00_05_02(struct gspca_dev *gspca_dev, unsigned short x)
739*4882a593Smuzhiyun {
740*4882a593Smuzhiyun cit_write_reg(gspca_dev, x, 0x0127);
741*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0124);
742*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0005, 0x0124);
743*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0002, 0x0124);
744*4882a593Smuzhiyun }
745*4882a593Smuzhiyun
cit_send_x_01_00_05(struct gspca_dev * gspca_dev,u16 x)746*4882a593Smuzhiyun static void cit_send_x_01_00_05(struct gspca_dev *gspca_dev, u16 x)
747*4882a593Smuzhiyun {
748*4882a593Smuzhiyun cit_write_reg(gspca_dev, x, 0x0127);
749*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0001, 0x0124);
750*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0124);
751*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0005, 0x0124);
752*4882a593Smuzhiyun }
753*4882a593Smuzhiyun
cit_send_x_00_05_02_01(struct gspca_dev * gspca_dev,u16 x)754*4882a593Smuzhiyun static void cit_send_x_00_05_02_01(struct gspca_dev *gspca_dev, u16 x)
755*4882a593Smuzhiyun {
756*4882a593Smuzhiyun cit_write_reg(gspca_dev, x, 0x0127);
757*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0124);
758*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0005, 0x0124);
759*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0002, 0x0124);
760*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0001, 0x0124);
761*4882a593Smuzhiyun }
762*4882a593Smuzhiyun
cit_send_x_00_05_02_08_01(struct gspca_dev * gspca_dev,u16 x)763*4882a593Smuzhiyun static void cit_send_x_00_05_02_08_01(struct gspca_dev *gspca_dev, u16 x)
764*4882a593Smuzhiyun {
765*4882a593Smuzhiyun cit_write_reg(gspca_dev, x, 0x0127);
766*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0124);
767*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0005, 0x0124);
768*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0002, 0x0124);
769*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0008, 0x0124);
770*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0001, 0x0124);
771*4882a593Smuzhiyun }
772*4882a593Smuzhiyun
cit_Packet_Format1(struct gspca_dev * gspca_dev,u16 fkey,u16 val)773*4882a593Smuzhiyun static void cit_Packet_Format1(struct gspca_dev *gspca_dev, u16 fkey, u16 val)
774*4882a593Smuzhiyun {
775*4882a593Smuzhiyun cit_send_x_01_00_05(gspca_dev, 0x0088);
776*4882a593Smuzhiyun cit_send_x_00_05(gspca_dev, fkey);
777*4882a593Smuzhiyun cit_send_x_00_05_02_08_01(gspca_dev, val);
778*4882a593Smuzhiyun cit_send_x_00_05(gspca_dev, 0x0088);
779*4882a593Smuzhiyun cit_send_x_00_05_02_01(gspca_dev, fkey);
780*4882a593Smuzhiyun cit_send_x_00_05(gspca_dev, 0x0089);
781*4882a593Smuzhiyun cit_send_x_00(gspca_dev, fkey);
782*4882a593Smuzhiyun cit_send_00_04_06(gspca_dev);
783*4882a593Smuzhiyun cit_read_reg(gspca_dev, 0x0126, 0);
784*4882a593Smuzhiyun cit_send_FF_04_02(gspca_dev);
785*4882a593Smuzhiyun }
786*4882a593Smuzhiyun
cit_PacketFormat2(struct gspca_dev * gspca_dev,u16 fkey,u16 val)787*4882a593Smuzhiyun static void cit_PacketFormat2(struct gspca_dev *gspca_dev, u16 fkey, u16 val)
788*4882a593Smuzhiyun {
789*4882a593Smuzhiyun cit_send_x_01_00_05(gspca_dev, 0x0088);
790*4882a593Smuzhiyun cit_send_x_00_05(gspca_dev, fkey);
791*4882a593Smuzhiyun cit_send_x_00_05_02(gspca_dev, val);
792*4882a593Smuzhiyun }
793*4882a593Smuzhiyun
cit_model2_Packet2(struct gspca_dev * gspca_dev)794*4882a593Smuzhiyun static void cit_model2_Packet2(struct gspca_dev *gspca_dev)
795*4882a593Smuzhiyun {
796*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00ff, 0x012d);
797*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xfea3, 0x0124);
798*4882a593Smuzhiyun }
799*4882a593Smuzhiyun
cit_model2_Packet1(struct gspca_dev * gspca_dev,u16 v1,u16 v2)800*4882a593Smuzhiyun static void cit_model2_Packet1(struct gspca_dev *gspca_dev, u16 v1, u16 v2)
801*4882a593Smuzhiyun {
802*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00aa, 0x012d);
803*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00ff, 0x012e);
804*4882a593Smuzhiyun cit_write_reg(gspca_dev, v1, 0x012f);
805*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00ff, 0x0130);
806*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xc719, 0x0124);
807*4882a593Smuzhiyun cit_write_reg(gspca_dev, v2, 0x0127);
808*4882a593Smuzhiyun
809*4882a593Smuzhiyun cit_model2_Packet2(gspca_dev);
810*4882a593Smuzhiyun }
811*4882a593Smuzhiyun
812*4882a593Smuzhiyun /*
813*4882a593Smuzhiyun * cit_model3_Packet1()
814*4882a593Smuzhiyun *
815*4882a593Smuzhiyun * 00_0078_012d
816*4882a593Smuzhiyun * 00_0097_012f
817*4882a593Smuzhiyun * 00_d141_0124
818*4882a593Smuzhiyun * 00_0096_0127
819*4882a593Smuzhiyun * 00_fea8_0124
820*4882a593Smuzhiyun */
cit_model3_Packet1(struct gspca_dev * gspca_dev,u16 v1,u16 v2)821*4882a593Smuzhiyun static void cit_model3_Packet1(struct gspca_dev *gspca_dev, u16 v1, u16 v2)
822*4882a593Smuzhiyun {
823*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0078, 0x012d);
824*4882a593Smuzhiyun cit_write_reg(gspca_dev, v1, 0x012f);
825*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xd141, 0x0124);
826*4882a593Smuzhiyun cit_write_reg(gspca_dev, v2, 0x0127);
827*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xfea8, 0x0124);
828*4882a593Smuzhiyun }
829*4882a593Smuzhiyun
cit_model4_Packet1(struct gspca_dev * gspca_dev,u16 v1,u16 v2)830*4882a593Smuzhiyun static void cit_model4_Packet1(struct gspca_dev *gspca_dev, u16 v1, u16 v2)
831*4882a593Smuzhiyun {
832*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00aa, 0x012d);
833*4882a593Smuzhiyun cit_write_reg(gspca_dev, v1, 0x012f);
834*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xd141, 0x0124);
835*4882a593Smuzhiyun cit_write_reg(gspca_dev, v2, 0x0127);
836*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xfea8, 0x0124);
837*4882a593Smuzhiyun }
838*4882a593Smuzhiyun
cit_model4_BrightnessPacket(struct gspca_dev * gspca_dev,u16 val)839*4882a593Smuzhiyun static void cit_model4_BrightnessPacket(struct gspca_dev *gspca_dev, u16 val)
840*4882a593Smuzhiyun {
841*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00aa, 0x012d);
842*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0026, 0x012f);
843*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xd141, 0x0124);
844*4882a593Smuzhiyun cit_write_reg(gspca_dev, val, 0x0127);
845*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00aa, 0x0130);
846*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x82a8, 0x0124);
847*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0038, 0x012d);
848*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0004, 0x012f);
849*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xd145, 0x0124);
850*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xfffa, 0x0124);
851*4882a593Smuzhiyun }
852*4882a593Smuzhiyun
853*4882a593Smuzhiyun /* this function is called at probe time */
sd_config(struct gspca_dev * gspca_dev,const struct usb_device_id * id)854*4882a593Smuzhiyun static int sd_config(struct gspca_dev *gspca_dev,
855*4882a593Smuzhiyun const struct usb_device_id *id)
856*4882a593Smuzhiyun {
857*4882a593Smuzhiyun struct sd *sd = (struct sd *) gspca_dev;
858*4882a593Smuzhiyun struct cam *cam;
859*4882a593Smuzhiyun
860*4882a593Smuzhiyun sd->model = id->driver_info;
861*4882a593Smuzhiyun if (sd->model == CIT_MODEL3 && ibm_netcam_pro)
862*4882a593Smuzhiyun sd->model = CIT_IBM_NETCAM_PRO;
863*4882a593Smuzhiyun
864*4882a593Smuzhiyun cam = &gspca_dev->cam;
865*4882a593Smuzhiyun switch (sd->model) {
866*4882a593Smuzhiyun case CIT_MODEL0:
867*4882a593Smuzhiyun cam->cam_mode = model0_mode;
868*4882a593Smuzhiyun cam->nmodes = ARRAY_SIZE(model0_mode);
869*4882a593Smuzhiyun sd->sof_len = 4;
870*4882a593Smuzhiyun break;
871*4882a593Smuzhiyun case CIT_MODEL1:
872*4882a593Smuzhiyun cam->cam_mode = cif_yuv_mode;
873*4882a593Smuzhiyun cam->nmodes = ARRAY_SIZE(cif_yuv_mode);
874*4882a593Smuzhiyun sd->sof_len = 4;
875*4882a593Smuzhiyun break;
876*4882a593Smuzhiyun case CIT_MODEL2:
877*4882a593Smuzhiyun cam->cam_mode = model2_mode + 1; /* no 160x120 */
878*4882a593Smuzhiyun cam->nmodes = 3;
879*4882a593Smuzhiyun break;
880*4882a593Smuzhiyun case CIT_MODEL3:
881*4882a593Smuzhiyun cam->cam_mode = vga_yuv_mode;
882*4882a593Smuzhiyun cam->nmodes = ARRAY_SIZE(vga_yuv_mode);
883*4882a593Smuzhiyun sd->stop_on_control_change = 1;
884*4882a593Smuzhiyun sd->sof_len = 4;
885*4882a593Smuzhiyun break;
886*4882a593Smuzhiyun case CIT_MODEL4:
887*4882a593Smuzhiyun cam->cam_mode = model2_mode;
888*4882a593Smuzhiyun cam->nmodes = ARRAY_SIZE(model2_mode);
889*4882a593Smuzhiyun break;
890*4882a593Smuzhiyun case CIT_IBM_NETCAM_PRO:
891*4882a593Smuzhiyun cam->cam_mode = vga_yuv_mode;
892*4882a593Smuzhiyun cam->nmodes = 2; /* no 640 x 480 */
893*4882a593Smuzhiyun cam->input_flags = V4L2_IN_ST_VFLIP;
894*4882a593Smuzhiyun sd->stop_on_control_change = 1;
895*4882a593Smuzhiyun sd->sof_len = 4;
896*4882a593Smuzhiyun break;
897*4882a593Smuzhiyun }
898*4882a593Smuzhiyun
899*4882a593Smuzhiyun return 0;
900*4882a593Smuzhiyun }
901*4882a593Smuzhiyun
cit_init_model0(struct gspca_dev * gspca_dev)902*4882a593Smuzhiyun static int cit_init_model0(struct gspca_dev *gspca_dev)
903*4882a593Smuzhiyun {
904*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0100); /* turn on led */
905*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0001, 0x0112); /* turn on autogain ? */
906*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0400);
907*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0001, 0x0400);
908*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0420);
909*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0001, 0x0420);
910*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x000d, 0x0409);
911*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0002, 0x040a);
912*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0018, 0x0405);
913*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0008, 0x0435);
914*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0026, 0x040b);
915*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0007, 0x0437);
916*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0015, 0x042f);
917*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x002b, 0x0439);
918*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0026, 0x043a);
919*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0008, 0x0438);
920*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x001e, 0x042b);
921*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0041, 0x042c);
922*4882a593Smuzhiyun
923*4882a593Smuzhiyun return 0;
924*4882a593Smuzhiyun }
925*4882a593Smuzhiyun
cit_init_ibm_netcam_pro(struct gspca_dev * gspca_dev)926*4882a593Smuzhiyun static int cit_init_ibm_netcam_pro(struct gspca_dev *gspca_dev)
927*4882a593Smuzhiyun {
928*4882a593Smuzhiyun cit_read_reg(gspca_dev, 0x128, 1);
929*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0003, 0x0133);
930*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0117);
931*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0008, 0x0123);
932*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0100);
933*4882a593Smuzhiyun cit_read_reg(gspca_dev, 0x0116, 0);
934*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0060, 0x0116);
935*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0002, 0x0112);
936*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0133);
937*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0123);
938*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0001, 0x0117);
939*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0040, 0x0108);
940*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0019, 0x012c);
941*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0060, 0x0116);
942*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0002, 0x0115);
943*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x000b, 0x0115);
944*4882a593Smuzhiyun
945*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0078, 0x012d);
946*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0001, 0x012f);
947*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xd141, 0x0124);
948*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0079, 0x012d);
949*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00ff, 0x0130);
950*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xcd41, 0x0124);
951*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xfffa, 0x0124);
952*4882a593Smuzhiyun cit_read_reg(gspca_dev, 0x0126, 1);
953*4882a593Smuzhiyun
954*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0000, 0x0000);
955*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0000, 0x0001);
956*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x000b, 0x0000);
957*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x000c, 0x0008);
958*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x000d, 0x003a);
959*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x000e, 0x0060);
960*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x000f, 0x0060);
961*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0010, 0x0008);
962*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0011, 0x0004);
963*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0012, 0x0028);
964*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0013, 0x0002);
965*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0014, 0x0000);
966*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0015, 0x00fb);
967*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0016, 0x0002);
968*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0017, 0x0037);
969*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0018, 0x0036);
970*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x001e, 0x0000);
971*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x001f, 0x0008);
972*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0020, 0x00c1);
973*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0021, 0x0034);
974*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0022, 0x0034);
975*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0025, 0x0002);
976*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0028, 0x0022);
977*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0029, 0x000a);
978*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x002b, 0x0000);
979*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x002c, 0x0000);
980*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x002d, 0x00ff);
981*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x002e, 0x00ff);
982*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x002f, 0x00ff);
983*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0030, 0x00ff);
984*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0031, 0x00ff);
985*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0032, 0x0007);
986*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0033, 0x0005);
987*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0037, 0x0040);
988*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0039, 0x0000);
989*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x003a, 0x0000);
990*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x003b, 0x0001);
991*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x003c, 0x0000);
992*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0040, 0x000c);
993*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0041, 0x00fb);
994*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0042, 0x0002);
995*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0043, 0x0000);
996*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0045, 0x0000);
997*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0046, 0x0000);
998*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0047, 0x0000);
999*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0048, 0x0000);
1000*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0049, 0x0000);
1001*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x004a, 0x00ff);
1002*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x004b, 0x00ff);
1003*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x004c, 0x00ff);
1004*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x004f, 0x0000);
1005*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0050, 0x0000);
1006*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0051, 0x0002);
1007*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0055, 0x0000);
1008*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0056, 0x0000);
1009*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0057, 0x0000);
1010*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0058, 0x0002);
1011*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0059, 0x0000);
1012*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x005c, 0x0016);
1013*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x005d, 0x0022);
1014*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x005e, 0x003c);
1015*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x005f, 0x0050);
1016*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0060, 0x0044);
1017*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0061, 0x0005);
1018*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x006a, 0x007e);
1019*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x006f, 0x0000);
1020*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0072, 0x001b);
1021*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0073, 0x0005);
1022*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0074, 0x000a);
1023*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0075, 0x001b);
1024*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0076, 0x002a);
1025*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0077, 0x003c);
1026*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0078, 0x0050);
1027*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x007b, 0x0000);
1028*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x007c, 0x0011);
1029*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x007d, 0x0024);
1030*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x007e, 0x0043);
1031*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x007f, 0x005a);
1032*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0084, 0x0020);
1033*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0085, 0x0033);
1034*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0086, 0x000a);
1035*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0087, 0x0030);
1036*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0088, 0x0070);
1037*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x008b, 0x0008);
1038*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x008f, 0x0000);
1039*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0090, 0x0006);
1040*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0091, 0x0028);
1041*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0092, 0x005a);
1042*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0093, 0x0082);
1043*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0096, 0x0014);
1044*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0097, 0x0020);
1045*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0098, 0x0000);
1046*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x00b0, 0x0046);
1047*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x00b1, 0x0000);
1048*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x00b2, 0x0000);
1049*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x00b3, 0x0004);
1050*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x00b4, 0x0007);
1051*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x00b6, 0x0002);
1052*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x00b7, 0x0004);
1053*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x00bb, 0x0000);
1054*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x00bc, 0x0001);
1055*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x00bd, 0x0000);
1056*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x00bf, 0x0000);
1057*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x00c0, 0x00c8);
1058*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x00c1, 0x0014);
1059*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x00c2, 0x0001);
1060*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x00c3, 0x0000);
1061*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x00c4, 0x0004);
1062*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x00cb, 0x00bf);
1063*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x00cc, 0x00bf);
1064*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x00cd, 0x00bf);
1065*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x00ce, 0x0000);
1066*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x00cf, 0x0020);
1067*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x00d0, 0x0040);
1068*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x00d1, 0x00bf);
1069*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x00d1, 0x00bf);
1070*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x00d2, 0x00bf);
1071*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x00d3, 0x00bf);
1072*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x00ea, 0x0008);
1073*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x00eb, 0x0000);
1074*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x00ec, 0x00e8);
1075*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x00ed, 0x0001);
1076*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x00ef, 0x0022);
1077*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x00f0, 0x0000);
1078*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x00f2, 0x0028);
1079*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x00f4, 0x0002);
1080*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x00f5, 0x0000);
1081*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x00fa, 0x0000);
1082*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x00fb, 0x0001);
1083*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x00fc, 0x0000);
1084*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x00fd, 0x0000);
1085*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x00fe, 0x0000);
1086*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x00ff, 0x0000);
1087*4882a593Smuzhiyun
1088*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x00be, 0x0003);
1089*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x00c8, 0x0000);
1090*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x00c9, 0x0020);
1091*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x00ca, 0x0040);
1092*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0053, 0x0001);
1093*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0082, 0x000e);
1094*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0083, 0x0020);
1095*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0034, 0x003c);
1096*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x006e, 0x0055);
1097*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0062, 0x0005);
1098*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0063, 0x0008);
1099*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0066, 0x000a);
1100*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0067, 0x0006);
1101*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x006b, 0x0010);
1102*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x005a, 0x0001);
1103*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x005b, 0x000a);
1104*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0023, 0x0006);
1105*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0026, 0x0004);
1106*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0036, 0x0069);
1107*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0038, 0x0064);
1108*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x003d, 0x0003);
1109*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x003e, 0x0001);
1110*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x00b8, 0x0014);
1111*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x00b9, 0x0014);
1112*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x00e6, 0x0004);
1113*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x00e8, 0x0001);
1114*4882a593Smuzhiyun
1115*4882a593Smuzhiyun return 0;
1116*4882a593Smuzhiyun }
1117*4882a593Smuzhiyun
1118*4882a593Smuzhiyun /* this function is called at probe and resume time */
sd_init(struct gspca_dev * gspca_dev)1119*4882a593Smuzhiyun static int sd_init(struct gspca_dev *gspca_dev)
1120*4882a593Smuzhiyun {
1121*4882a593Smuzhiyun struct sd *sd = (struct sd *) gspca_dev;
1122*4882a593Smuzhiyun
1123*4882a593Smuzhiyun switch (sd->model) {
1124*4882a593Smuzhiyun case CIT_MODEL0:
1125*4882a593Smuzhiyun cit_init_model0(gspca_dev);
1126*4882a593Smuzhiyun sd_stop0(gspca_dev);
1127*4882a593Smuzhiyun break;
1128*4882a593Smuzhiyun case CIT_MODEL1:
1129*4882a593Smuzhiyun case CIT_MODEL2:
1130*4882a593Smuzhiyun case CIT_MODEL3:
1131*4882a593Smuzhiyun case CIT_MODEL4:
1132*4882a593Smuzhiyun break; /* All is done in sd_start */
1133*4882a593Smuzhiyun case CIT_IBM_NETCAM_PRO:
1134*4882a593Smuzhiyun cit_init_ibm_netcam_pro(gspca_dev);
1135*4882a593Smuzhiyun sd_stop0(gspca_dev);
1136*4882a593Smuzhiyun break;
1137*4882a593Smuzhiyun }
1138*4882a593Smuzhiyun return 0;
1139*4882a593Smuzhiyun }
1140*4882a593Smuzhiyun
cit_set_brightness(struct gspca_dev * gspca_dev,s32 val)1141*4882a593Smuzhiyun static int cit_set_brightness(struct gspca_dev *gspca_dev, s32 val)
1142*4882a593Smuzhiyun {
1143*4882a593Smuzhiyun struct sd *sd = (struct sd *) gspca_dev;
1144*4882a593Smuzhiyun int i;
1145*4882a593Smuzhiyun
1146*4882a593Smuzhiyun switch (sd->model) {
1147*4882a593Smuzhiyun case CIT_MODEL0:
1148*4882a593Smuzhiyun case CIT_IBM_NETCAM_PRO:
1149*4882a593Smuzhiyun /* No (known) brightness control for these */
1150*4882a593Smuzhiyun break;
1151*4882a593Smuzhiyun case CIT_MODEL1:
1152*4882a593Smuzhiyun /* Model 1: Brightness range 0 - 63 */
1153*4882a593Smuzhiyun cit_Packet_Format1(gspca_dev, 0x0031, val);
1154*4882a593Smuzhiyun cit_Packet_Format1(gspca_dev, 0x0032, val);
1155*4882a593Smuzhiyun cit_Packet_Format1(gspca_dev, 0x0033, val);
1156*4882a593Smuzhiyun break;
1157*4882a593Smuzhiyun case CIT_MODEL2:
1158*4882a593Smuzhiyun /* Model 2: Brightness range 0x60 - 0xee */
1159*4882a593Smuzhiyun /* Scale 0 - 63 to 0x60 - 0xee */
1160*4882a593Smuzhiyun i = 0x60 + val * 2254 / 1000;
1161*4882a593Smuzhiyun cit_model2_Packet1(gspca_dev, 0x001a, i);
1162*4882a593Smuzhiyun break;
1163*4882a593Smuzhiyun case CIT_MODEL3:
1164*4882a593Smuzhiyun /* Model 3: Brightness range 'i' in [0x0C..0x3F] */
1165*4882a593Smuzhiyun i = val;
1166*4882a593Smuzhiyun if (i < 0x0c)
1167*4882a593Smuzhiyun i = 0x0c;
1168*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0036, i);
1169*4882a593Smuzhiyun break;
1170*4882a593Smuzhiyun case CIT_MODEL4:
1171*4882a593Smuzhiyun /* Model 4: Brightness range 'i' in [0x04..0xb4] */
1172*4882a593Smuzhiyun /* Scale 0 - 63 to 0x04 - 0xb4 */
1173*4882a593Smuzhiyun i = 0x04 + val * 2794 / 1000;
1174*4882a593Smuzhiyun cit_model4_BrightnessPacket(gspca_dev, i);
1175*4882a593Smuzhiyun break;
1176*4882a593Smuzhiyun }
1177*4882a593Smuzhiyun
1178*4882a593Smuzhiyun return 0;
1179*4882a593Smuzhiyun }
1180*4882a593Smuzhiyun
cit_set_contrast(struct gspca_dev * gspca_dev,s32 val)1181*4882a593Smuzhiyun static int cit_set_contrast(struct gspca_dev *gspca_dev, s32 val)
1182*4882a593Smuzhiyun {
1183*4882a593Smuzhiyun struct sd *sd = (struct sd *) gspca_dev;
1184*4882a593Smuzhiyun
1185*4882a593Smuzhiyun switch (sd->model) {
1186*4882a593Smuzhiyun case CIT_MODEL0: {
1187*4882a593Smuzhiyun int i;
1188*4882a593Smuzhiyun /* gain 0-15, 0-20 -> 0-15 */
1189*4882a593Smuzhiyun i = val * 1000 / 1333;
1190*4882a593Smuzhiyun cit_write_reg(gspca_dev, i, 0x0422);
1191*4882a593Smuzhiyun /* gain 0-31, may not be lower then 0x0422, 0-20 -> 0-31 */
1192*4882a593Smuzhiyun i = val * 2000 / 1333;
1193*4882a593Smuzhiyun cit_write_reg(gspca_dev, i, 0x0423);
1194*4882a593Smuzhiyun /* gain 0-127, may not be lower then 0x0423, 0-20 -> 0-63 */
1195*4882a593Smuzhiyun i = val * 4000 / 1333;
1196*4882a593Smuzhiyun cit_write_reg(gspca_dev, i, 0x0424);
1197*4882a593Smuzhiyun /* gain 0-127, may not be lower then 0x0424, , 0-20 -> 0-127 */
1198*4882a593Smuzhiyun i = val * 8000 / 1333;
1199*4882a593Smuzhiyun cit_write_reg(gspca_dev, i, 0x0425);
1200*4882a593Smuzhiyun break;
1201*4882a593Smuzhiyun }
1202*4882a593Smuzhiyun case CIT_MODEL2:
1203*4882a593Smuzhiyun case CIT_MODEL4:
1204*4882a593Smuzhiyun /* These models do not have this control. */
1205*4882a593Smuzhiyun break;
1206*4882a593Smuzhiyun case CIT_MODEL1:
1207*4882a593Smuzhiyun {
1208*4882a593Smuzhiyun /* Scale 0 - 20 to 15 - 0 */
1209*4882a593Smuzhiyun int i, new_contrast = (20 - val) * 1000 / 1333;
1210*4882a593Smuzhiyun for (i = 0; i < cit_model1_ntries; i++) {
1211*4882a593Smuzhiyun cit_Packet_Format1(gspca_dev, 0x0014, new_contrast);
1212*4882a593Smuzhiyun cit_send_FF_04_02(gspca_dev);
1213*4882a593Smuzhiyun }
1214*4882a593Smuzhiyun break;
1215*4882a593Smuzhiyun }
1216*4882a593Smuzhiyun case CIT_MODEL3:
1217*4882a593Smuzhiyun { /* Preset hardware values */
1218*4882a593Smuzhiyun static const struct {
1219*4882a593Smuzhiyun unsigned short cv1;
1220*4882a593Smuzhiyun unsigned short cv2;
1221*4882a593Smuzhiyun unsigned short cv3;
1222*4882a593Smuzhiyun } cv[7] = {
1223*4882a593Smuzhiyun { 0x05, 0x05, 0x0f }, /* Minimum */
1224*4882a593Smuzhiyun { 0x04, 0x04, 0x16 },
1225*4882a593Smuzhiyun { 0x02, 0x03, 0x16 },
1226*4882a593Smuzhiyun { 0x02, 0x08, 0x16 },
1227*4882a593Smuzhiyun { 0x01, 0x0c, 0x16 },
1228*4882a593Smuzhiyun { 0x01, 0x0e, 0x16 },
1229*4882a593Smuzhiyun { 0x01, 0x10, 0x16 } /* Maximum */
1230*4882a593Smuzhiyun };
1231*4882a593Smuzhiyun int i = val / 3;
1232*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0067, cv[i].cv1);
1233*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x005b, cv[i].cv2);
1234*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x005c, cv[i].cv3);
1235*4882a593Smuzhiyun break;
1236*4882a593Smuzhiyun }
1237*4882a593Smuzhiyun case CIT_IBM_NETCAM_PRO:
1238*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x005b, val + 1);
1239*4882a593Smuzhiyun break;
1240*4882a593Smuzhiyun }
1241*4882a593Smuzhiyun return 0;
1242*4882a593Smuzhiyun }
1243*4882a593Smuzhiyun
cit_set_hue(struct gspca_dev * gspca_dev,s32 val)1244*4882a593Smuzhiyun static int cit_set_hue(struct gspca_dev *gspca_dev, s32 val)
1245*4882a593Smuzhiyun {
1246*4882a593Smuzhiyun struct sd *sd = (struct sd *) gspca_dev;
1247*4882a593Smuzhiyun
1248*4882a593Smuzhiyun switch (sd->model) {
1249*4882a593Smuzhiyun case CIT_MODEL0:
1250*4882a593Smuzhiyun case CIT_MODEL1:
1251*4882a593Smuzhiyun case CIT_IBM_NETCAM_PRO:
1252*4882a593Smuzhiyun /* No hue control for these models */
1253*4882a593Smuzhiyun break;
1254*4882a593Smuzhiyun case CIT_MODEL2:
1255*4882a593Smuzhiyun cit_model2_Packet1(gspca_dev, 0x0024, val);
1256*4882a593Smuzhiyun /* cit_model2_Packet1(gspca_dev, 0x0020, sat); */
1257*4882a593Smuzhiyun break;
1258*4882a593Smuzhiyun case CIT_MODEL3: {
1259*4882a593Smuzhiyun /* Model 3: Brightness range 'i' in [0x05..0x37] */
1260*4882a593Smuzhiyun /* TESTME according to the ibmcam driver this does not work */
1261*4882a593Smuzhiyun if (0) {
1262*4882a593Smuzhiyun /* Scale 0 - 127 to 0x05 - 0x37 */
1263*4882a593Smuzhiyun int i = 0x05 + val * 1000 / 2540;
1264*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x007e, i);
1265*4882a593Smuzhiyun }
1266*4882a593Smuzhiyun break;
1267*4882a593Smuzhiyun }
1268*4882a593Smuzhiyun case CIT_MODEL4:
1269*4882a593Smuzhiyun /* HDG: taken from ibmcam, setting the color gains does not
1270*4882a593Smuzhiyun * really belong here.
1271*4882a593Smuzhiyun *
1272*4882a593Smuzhiyun * I am not sure r/g/b_gain variables exactly control gain
1273*4882a593Smuzhiyun * of those channels. Most likely they subtly change some
1274*4882a593Smuzhiyun * very internal image processing settings in the camera.
1275*4882a593Smuzhiyun * In any case, here is what they do, and feel free to tweak:
1276*4882a593Smuzhiyun *
1277*4882a593Smuzhiyun * r_gain: seriously affects red gain
1278*4882a593Smuzhiyun * g_gain: seriously affects green gain
1279*4882a593Smuzhiyun * b_gain: seriously affects blue gain
1280*4882a593Smuzhiyun * hue: changes average color from violet (0) to red (0xFF)
1281*4882a593Smuzhiyun */
1282*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00aa, 0x012d);
1283*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x001e, 0x012f);
1284*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xd141, 0x0124);
1285*4882a593Smuzhiyun cit_write_reg(gspca_dev, 160, 0x0127); /* Green gain */
1286*4882a593Smuzhiyun cit_write_reg(gspca_dev, 160, 0x012e); /* Red gain */
1287*4882a593Smuzhiyun cit_write_reg(gspca_dev, 160, 0x0130); /* Blue gain */
1288*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x8a28, 0x0124);
1289*4882a593Smuzhiyun cit_write_reg(gspca_dev, val, 0x012d); /* Hue */
1290*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xf545, 0x0124);
1291*4882a593Smuzhiyun break;
1292*4882a593Smuzhiyun }
1293*4882a593Smuzhiyun return 0;
1294*4882a593Smuzhiyun }
1295*4882a593Smuzhiyun
cit_set_sharpness(struct gspca_dev * gspca_dev,s32 val)1296*4882a593Smuzhiyun static int cit_set_sharpness(struct gspca_dev *gspca_dev, s32 val)
1297*4882a593Smuzhiyun {
1298*4882a593Smuzhiyun struct sd *sd = (struct sd *) gspca_dev;
1299*4882a593Smuzhiyun
1300*4882a593Smuzhiyun switch (sd->model) {
1301*4882a593Smuzhiyun case CIT_MODEL0:
1302*4882a593Smuzhiyun case CIT_MODEL2:
1303*4882a593Smuzhiyun case CIT_MODEL4:
1304*4882a593Smuzhiyun case CIT_IBM_NETCAM_PRO:
1305*4882a593Smuzhiyun /* These models do not have this control */
1306*4882a593Smuzhiyun break;
1307*4882a593Smuzhiyun case CIT_MODEL1: {
1308*4882a593Smuzhiyun int i;
1309*4882a593Smuzhiyun static const unsigned short sa[] = {
1310*4882a593Smuzhiyun 0x11, 0x13, 0x16, 0x18, 0x1a, 0x8, 0x0a };
1311*4882a593Smuzhiyun
1312*4882a593Smuzhiyun for (i = 0; i < cit_model1_ntries; i++)
1313*4882a593Smuzhiyun cit_PacketFormat2(gspca_dev, 0x0013, sa[val]);
1314*4882a593Smuzhiyun break;
1315*4882a593Smuzhiyun }
1316*4882a593Smuzhiyun case CIT_MODEL3:
1317*4882a593Smuzhiyun { /*
1318*4882a593Smuzhiyun * "Use a table of magic numbers.
1319*4882a593Smuzhiyun * This setting doesn't really change much.
1320*4882a593Smuzhiyun * But that's how Windows does it."
1321*4882a593Smuzhiyun */
1322*4882a593Smuzhiyun static const struct {
1323*4882a593Smuzhiyun unsigned short sv1;
1324*4882a593Smuzhiyun unsigned short sv2;
1325*4882a593Smuzhiyun unsigned short sv3;
1326*4882a593Smuzhiyun unsigned short sv4;
1327*4882a593Smuzhiyun } sv[7] = {
1328*4882a593Smuzhiyun { 0x00, 0x00, 0x05, 0x14 }, /* Smoothest */
1329*4882a593Smuzhiyun { 0x01, 0x04, 0x05, 0x14 },
1330*4882a593Smuzhiyun { 0x02, 0x04, 0x05, 0x14 },
1331*4882a593Smuzhiyun { 0x03, 0x04, 0x05, 0x14 },
1332*4882a593Smuzhiyun { 0x03, 0x05, 0x05, 0x14 },
1333*4882a593Smuzhiyun { 0x03, 0x06, 0x05, 0x14 },
1334*4882a593Smuzhiyun { 0x03, 0x07, 0x05, 0x14 } /* Sharpest */
1335*4882a593Smuzhiyun };
1336*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0060, sv[val].sv1);
1337*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0061, sv[val].sv2);
1338*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0062, sv[val].sv3);
1339*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0063, sv[val].sv4);
1340*4882a593Smuzhiyun break;
1341*4882a593Smuzhiyun }
1342*4882a593Smuzhiyun }
1343*4882a593Smuzhiyun return 0;
1344*4882a593Smuzhiyun }
1345*4882a593Smuzhiyun
1346*4882a593Smuzhiyun /*
1347*4882a593Smuzhiyun * cit_set_lighting()
1348*4882a593Smuzhiyun *
1349*4882a593Smuzhiyun * Camera model 1:
1350*4882a593Smuzhiyun * We have 3 levels of lighting conditions: 0=Bright, 1=Medium, 2=Low.
1351*4882a593Smuzhiyun *
1352*4882a593Smuzhiyun * Camera model 2:
1353*4882a593Smuzhiyun * We have 16 levels of lighting, 0 for bright light and up to 15 for
1354*4882a593Smuzhiyun * low light. But values above 5 or so are useless because camera is
1355*4882a593Smuzhiyun * not really capable to produce anything worth viewing at such light.
1356*4882a593Smuzhiyun * This setting may be altered only in certain camera state.
1357*4882a593Smuzhiyun *
1358*4882a593Smuzhiyun * Low lighting forces slower FPS.
1359*4882a593Smuzhiyun *
1360*4882a593Smuzhiyun * History:
1361*4882a593Smuzhiyun * 1/5/00 Created.
1362*4882a593Smuzhiyun * 2/20/00 Added support for Model 2 cameras.
1363*4882a593Smuzhiyun */
cit_set_lighting(struct gspca_dev * gspca_dev,s32 val)1364*4882a593Smuzhiyun static void cit_set_lighting(struct gspca_dev *gspca_dev, s32 val)
1365*4882a593Smuzhiyun {
1366*4882a593Smuzhiyun struct sd *sd = (struct sd *) gspca_dev;
1367*4882a593Smuzhiyun
1368*4882a593Smuzhiyun switch (sd->model) {
1369*4882a593Smuzhiyun case CIT_MODEL0:
1370*4882a593Smuzhiyun case CIT_MODEL2:
1371*4882a593Smuzhiyun case CIT_MODEL3:
1372*4882a593Smuzhiyun case CIT_MODEL4:
1373*4882a593Smuzhiyun case CIT_IBM_NETCAM_PRO:
1374*4882a593Smuzhiyun break;
1375*4882a593Smuzhiyun case CIT_MODEL1: {
1376*4882a593Smuzhiyun int i;
1377*4882a593Smuzhiyun for (i = 0; i < cit_model1_ntries; i++)
1378*4882a593Smuzhiyun cit_Packet_Format1(gspca_dev, 0x0027, val);
1379*4882a593Smuzhiyun break;
1380*4882a593Smuzhiyun }
1381*4882a593Smuzhiyun }
1382*4882a593Smuzhiyun }
1383*4882a593Smuzhiyun
cit_set_hflip(struct gspca_dev * gspca_dev,s32 val)1384*4882a593Smuzhiyun static void cit_set_hflip(struct gspca_dev *gspca_dev, s32 val)
1385*4882a593Smuzhiyun {
1386*4882a593Smuzhiyun struct sd *sd = (struct sd *) gspca_dev;
1387*4882a593Smuzhiyun
1388*4882a593Smuzhiyun switch (sd->model) {
1389*4882a593Smuzhiyun case CIT_MODEL0:
1390*4882a593Smuzhiyun if (val)
1391*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0020, 0x0115);
1392*4882a593Smuzhiyun else
1393*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0040, 0x0115);
1394*4882a593Smuzhiyun break;
1395*4882a593Smuzhiyun case CIT_MODEL1:
1396*4882a593Smuzhiyun case CIT_MODEL2:
1397*4882a593Smuzhiyun case CIT_MODEL3:
1398*4882a593Smuzhiyun case CIT_MODEL4:
1399*4882a593Smuzhiyun case CIT_IBM_NETCAM_PRO:
1400*4882a593Smuzhiyun break;
1401*4882a593Smuzhiyun }
1402*4882a593Smuzhiyun }
1403*4882a593Smuzhiyun
cit_restart_stream(struct gspca_dev * gspca_dev)1404*4882a593Smuzhiyun static int cit_restart_stream(struct gspca_dev *gspca_dev)
1405*4882a593Smuzhiyun {
1406*4882a593Smuzhiyun struct sd *sd = (struct sd *) gspca_dev;
1407*4882a593Smuzhiyun
1408*4882a593Smuzhiyun switch (sd->model) {
1409*4882a593Smuzhiyun case CIT_MODEL0:
1410*4882a593Smuzhiyun case CIT_MODEL1:
1411*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0001, 0x0114);
1412*4882a593Smuzhiyun fallthrough;
1413*4882a593Smuzhiyun case CIT_MODEL2:
1414*4882a593Smuzhiyun case CIT_MODEL4:
1415*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00c0, 0x010c); /* Go! */
1416*4882a593Smuzhiyun usb_clear_halt(gspca_dev->dev, gspca_dev->urb[0]->pipe);
1417*4882a593Smuzhiyun break;
1418*4882a593Smuzhiyun case CIT_MODEL3:
1419*4882a593Smuzhiyun case CIT_IBM_NETCAM_PRO:
1420*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0001, 0x0114);
1421*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00c0, 0x010c); /* Go! */
1422*4882a593Smuzhiyun usb_clear_halt(gspca_dev->dev, gspca_dev->urb[0]->pipe);
1423*4882a593Smuzhiyun /* Clear button events from while we were not streaming */
1424*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0001, 0x0113);
1425*4882a593Smuzhiyun break;
1426*4882a593Smuzhiyun }
1427*4882a593Smuzhiyun
1428*4882a593Smuzhiyun sd->sof_read = 0;
1429*4882a593Smuzhiyun
1430*4882a593Smuzhiyun return 0;
1431*4882a593Smuzhiyun }
1432*4882a593Smuzhiyun
cit_get_packet_size(struct gspca_dev * gspca_dev)1433*4882a593Smuzhiyun static int cit_get_packet_size(struct gspca_dev *gspca_dev)
1434*4882a593Smuzhiyun {
1435*4882a593Smuzhiyun struct usb_host_interface *alt;
1436*4882a593Smuzhiyun struct usb_interface *intf;
1437*4882a593Smuzhiyun
1438*4882a593Smuzhiyun intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface);
1439*4882a593Smuzhiyun alt = usb_altnum_to_altsetting(intf, gspca_dev->alt);
1440*4882a593Smuzhiyun if (!alt) {
1441*4882a593Smuzhiyun pr_err("Couldn't get altsetting\n");
1442*4882a593Smuzhiyun return -EIO;
1443*4882a593Smuzhiyun }
1444*4882a593Smuzhiyun
1445*4882a593Smuzhiyun if (alt->desc.bNumEndpoints < 1)
1446*4882a593Smuzhiyun return -ENODEV;
1447*4882a593Smuzhiyun
1448*4882a593Smuzhiyun return le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
1449*4882a593Smuzhiyun }
1450*4882a593Smuzhiyun
1451*4882a593Smuzhiyun /* Calculate the clockdiv giving us max fps given the available bandwidth */
cit_get_clock_div(struct gspca_dev * gspca_dev)1452*4882a593Smuzhiyun static int cit_get_clock_div(struct gspca_dev *gspca_dev)
1453*4882a593Smuzhiyun {
1454*4882a593Smuzhiyun int clock_div = 7; /* 0=30 1=25 2=20 3=15 4=12 5=7.5 6=6 7=3fps ?? */
1455*4882a593Smuzhiyun int fps[8] = { 30, 25, 20, 15, 12, 8, 6, 3 };
1456*4882a593Smuzhiyun int packet_size;
1457*4882a593Smuzhiyun
1458*4882a593Smuzhiyun packet_size = cit_get_packet_size(gspca_dev);
1459*4882a593Smuzhiyun if (packet_size < 0)
1460*4882a593Smuzhiyun return packet_size;
1461*4882a593Smuzhiyun
1462*4882a593Smuzhiyun while (clock_div > 3 &&
1463*4882a593Smuzhiyun 1000 * packet_size >
1464*4882a593Smuzhiyun gspca_dev->pixfmt.width * gspca_dev->pixfmt.height *
1465*4882a593Smuzhiyun fps[clock_div - 1] * 3 / 2)
1466*4882a593Smuzhiyun clock_div--;
1467*4882a593Smuzhiyun
1468*4882a593Smuzhiyun gspca_dbg(gspca_dev, D_PROBE,
1469*4882a593Smuzhiyun "PacketSize: %d, res: %dx%d -> using clockdiv: %d (%d fps)\n",
1470*4882a593Smuzhiyun packet_size,
1471*4882a593Smuzhiyun gspca_dev->pixfmt.width, gspca_dev->pixfmt.height,
1472*4882a593Smuzhiyun clock_div, fps[clock_div]);
1473*4882a593Smuzhiyun
1474*4882a593Smuzhiyun return clock_div;
1475*4882a593Smuzhiyun }
1476*4882a593Smuzhiyun
cit_start_model0(struct gspca_dev * gspca_dev)1477*4882a593Smuzhiyun static int cit_start_model0(struct gspca_dev *gspca_dev)
1478*4882a593Smuzhiyun {
1479*4882a593Smuzhiyun const unsigned short compression = 0; /* 0=none, 7=best frame rate */
1480*4882a593Smuzhiyun int clock_div;
1481*4882a593Smuzhiyun
1482*4882a593Smuzhiyun clock_div = cit_get_clock_div(gspca_dev);
1483*4882a593Smuzhiyun if (clock_div < 0)
1484*4882a593Smuzhiyun return clock_div;
1485*4882a593Smuzhiyun
1486*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0100); /* turn on led */
1487*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0003, 0x0438);
1488*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x001e, 0x042b);
1489*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0041, 0x042c);
1490*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0008, 0x0436);
1491*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0024, 0x0403);
1492*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x002c, 0x0404);
1493*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0002, 0x0426);
1494*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0014, 0x0427);
1495*4882a593Smuzhiyun
1496*4882a593Smuzhiyun switch (gspca_dev->pixfmt.width) {
1497*4882a593Smuzhiyun case 160: /* 160x120 */
1498*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0004, 0x010b);
1499*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0001, 0x010a);
1500*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0010, 0x0102);
1501*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00a0, 0x0103);
1502*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0104);
1503*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0078, 0x0105);
1504*4882a593Smuzhiyun break;
1505*4882a593Smuzhiyun
1506*4882a593Smuzhiyun case 176: /* 176x144 */
1507*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0006, 0x010b);
1508*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x010a);
1509*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0005, 0x0102);
1510*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00b0, 0x0103);
1511*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0104);
1512*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0090, 0x0105);
1513*4882a593Smuzhiyun break;
1514*4882a593Smuzhiyun
1515*4882a593Smuzhiyun case 320: /* 320x240 */
1516*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0008, 0x010b);
1517*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0004, 0x010a);
1518*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0005, 0x0102);
1519*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00a0, 0x0103);
1520*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0010, 0x0104);
1521*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0078, 0x0105);
1522*4882a593Smuzhiyun break;
1523*4882a593Smuzhiyun }
1524*4882a593Smuzhiyun
1525*4882a593Smuzhiyun cit_write_reg(gspca_dev, compression, 0x0109);
1526*4882a593Smuzhiyun cit_write_reg(gspca_dev, clock_div, 0x0111);
1527*4882a593Smuzhiyun
1528*4882a593Smuzhiyun return 0;
1529*4882a593Smuzhiyun }
1530*4882a593Smuzhiyun
cit_start_model1(struct gspca_dev * gspca_dev)1531*4882a593Smuzhiyun static int cit_start_model1(struct gspca_dev *gspca_dev)
1532*4882a593Smuzhiyun {
1533*4882a593Smuzhiyun struct sd *sd = (struct sd *) gspca_dev;
1534*4882a593Smuzhiyun int i, clock_div;
1535*4882a593Smuzhiyun
1536*4882a593Smuzhiyun clock_div = cit_get_clock_div(gspca_dev);
1537*4882a593Smuzhiyun if (clock_div < 0)
1538*4882a593Smuzhiyun return clock_div;
1539*4882a593Smuzhiyun
1540*4882a593Smuzhiyun cit_read_reg(gspca_dev, 0x0128, 1);
1541*4882a593Smuzhiyun cit_read_reg(gspca_dev, 0x0100, 0);
1542*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x01, 0x0100); /* LED On */
1543*4882a593Smuzhiyun cit_read_reg(gspca_dev, 0x0100, 0);
1544*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x81, 0x0100); /* LED Off */
1545*4882a593Smuzhiyun cit_read_reg(gspca_dev, 0x0100, 0);
1546*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x01, 0x0100); /* LED On */
1547*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x01, 0x0108);
1548*4882a593Smuzhiyun
1549*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x03, 0x0112);
1550*4882a593Smuzhiyun cit_read_reg(gspca_dev, 0x0115, 0);
1551*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x06, 0x0115);
1552*4882a593Smuzhiyun cit_read_reg(gspca_dev, 0x0116, 0);
1553*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x44, 0x0116);
1554*4882a593Smuzhiyun cit_read_reg(gspca_dev, 0x0116, 0);
1555*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x40, 0x0116);
1556*4882a593Smuzhiyun cit_read_reg(gspca_dev, 0x0115, 0);
1557*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0e, 0x0115);
1558*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x19, 0x012c);
1559*4882a593Smuzhiyun
1560*4882a593Smuzhiyun cit_Packet_Format1(gspca_dev, 0x00, 0x1e);
1561*4882a593Smuzhiyun cit_Packet_Format1(gspca_dev, 0x39, 0x0d);
1562*4882a593Smuzhiyun cit_Packet_Format1(gspca_dev, 0x39, 0x09);
1563*4882a593Smuzhiyun cit_Packet_Format1(gspca_dev, 0x3b, 0x00);
1564*4882a593Smuzhiyun cit_Packet_Format1(gspca_dev, 0x28, 0x22);
1565*4882a593Smuzhiyun cit_Packet_Format1(gspca_dev, 0x27, 0x00);
1566*4882a593Smuzhiyun cit_Packet_Format1(gspca_dev, 0x2b, 0x1f);
1567*4882a593Smuzhiyun cit_Packet_Format1(gspca_dev, 0x39, 0x08);
1568*4882a593Smuzhiyun
1569*4882a593Smuzhiyun for (i = 0; i < cit_model1_ntries; i++)
1570*4882a593Smuzhiyun cit_Packet_Format1(gspca_dev, 0x2c, 0x00);
1571*4882a593Smuzhiyun
1572*4882a593Smuzhiyun for (i = 0; i < cit_model1_ntries; i++)
1573*4882a593Smuzhiyun cit_Packet_Format1(gspca_dev, 0x30, 0x14);
1574*4882a593Smuzhiyun
1575*4882a593Smuzhiyun cit_PacketFormat2(gspca_dev, 0x39, 0x02);
1576*4882a593Smuzhiyun cit_PacketFormat2(gspca_dev, 0x01, 0xe1);
1577*4882a593Smuzhiyun cit_PacketFormat2(gspca_dev, 0x02, 0xcd);
1578*4882a593Smuzhiyun cit_PacketFormat2(gspca_dev, 0x03, 0xcd);
1579*4882a593Smuzhiyun cit_PacketFormat2(gspca_dev, 0x04, 0xfa);
1580*4882a593Smuzhiyun cit_PacketFormat2(gspca_dev, 0x3f, 0xff);
1581*4882a593Smuzhiyun cit_PacketFormat2(gspca_dev, 0x39, 0x00);
1582*4882a593Smuzhiyun
1583*4882a593Smuzhiyun cit_PacketFormat2(gspca_dev, 0x39, 0x02);
1584*4882a593Smuzhiyun cit_PacketFormat2(gspca_dev, 0x0a, 0x37);
1585*4882a593Smuzhiyun cit_PacketFormat2(gspca_dev, 0x0b, 0xb8);
1586*4882a593Smuzhiyun cit_PacketFormat2(gspca_dev, 0x0c, 0xf3);
1587*4882a593Smuzhiyun cit_PacketFormat2(gspca_dev, 0x0d, 0xe3);
1588*4882a593Smuzhiyun cit_PacketFormat2(gspca_dev, 0x0e, 0x0d);
1589*4882a593Smuzhiyun cit_PacketFormat2(gspca_dev, 0x0f, 0xf2);
1590*4882a593Smuzhiyun cit_PacketFormat2(gspca_dev, 0x10, 0xd5);
1591*4882a593Smuzhiyun cit_PacketFormat2(gspca_dev, 0x11, 0xba);
1592*4882a593Smuzhiyun cit_PacketFormat2(gspca_dev, 0x12, 0x53);
1593*4882a593Smuzhiyun cit_PacketFormat2(gspca_dev, 0x3f, 0xff);
1594*4882a593Smuzhiyun cit_PacketFormat2(gspca_dev, 0x39, 0x00);
1595*4882a593Smuzhiyun
1596*4882a593Smuzhiyun cit_PacketFormat2(gspca_dev, 0x39, 0x02);
1597*4882a593Smuzhiyun cit_PacketFormat2(gspca_dev, 0x16, 0x00);
1598*4882a593Smuzhiyun cit_PacketFormat2(gspca_dev, 0x17, 0x28);
1599*4882a593Smuzhiyun cit_PacketFormat2(gspca_dev, 0x18, 0x7d);
1600*4882a593Smuzhiyun cit_PacketFormat2(gspca_dev, 0x19, 0xbe);
1601*4882a593Smuzhiyun cit_PacketFormat2(gspca_dev, 0x3f, 0xff);
1602*4882a593Smuzhiyun cit_PacketFormat2(gspca_dev, 0x39, 0x00);
1603*4882a593Smuzhiyun
1604*4882a593Smuzhiyun for (i = 0; i < cit_model1_ntries; i++)
1605*4882a593Smuzhiyun cit_Packet_Format1(gspca_dev, 0x00, 0x18);
1606*4882a593Smuzhiyun for (i = 0; i < cit_model1_ntries; i++)
1607*4882a593Smuzhiyun cit_Packet_Format1(gspca_dev, 0x13, 0x18);
1608*4882a593Smuzhiyun for (i = 0; i < cit_model1_ntries; i++)
1609*4882a593Smuzhiyun cit_Packet_Format1(gspca_dev, 0x14, 0x06);
1610*4882a593Smuzhiyun
1611*4882a593Smuzhiyun /* TESTME These are handled through controls
1612*4882a593Smuzhiyun KEEP until someone can test leaving this out is ok */
1613*4882a593Smuzhiyun if (0) {
1614*4882a593Smuzhiyun /* This is default brightness */
1615*4882a593Smuzhiyun for (i = 0; i < cit_model1_ntries; i++)
1616*4882a593Smuzhiyun cit_Packet_Format1(gspca_dev, 0x31, 0x37);
1617*4882a593Smuzhiyun for (i = 0; i < cit_model1_ntries; i++)
1618*4882a593Smuzhiyun cit_Packet_Format1(gspca_dev, 0x32, 0x46);
1619*4882a593Smuzhiyun for (i = 0; i < cit_model1_ntries; i++)
1620*4882a593Smuzhiyun cit_Packet_Format1(gspca_dev, 0x33, 0x55);
1621*4882a593Smuzhiyun }
1622*4882a593Smuzhiyun
1623*4882a593Smuzhiyun cit_Packet_Format1(gspca_dev, 0x2e, 0x04);
1624*4882a593Smuzhiyun for (i = 0; i < cit_model1_ntries; i++)
1625*4882a593Smuzhiyun cit_Packet_Format1(gspca_dev, 0x2d, 0x04);
1626*4882a593Smuzhiyun for (i = 0; i < cit_model1_ntries; i++)
1627*4882a593Smuzhiyun cit_Packet_Format1(gspca_dev, 0x29, 0x80);
1628*4882a593Smuzhiyun cit_Packet_Format1(gspca_dev, 0x2c, 0x01);
1629*4882a593Smuzhiyun cit_Packet_Format1(gspca_dev, 0x30, 0x17);
1630*4882a593Smuzhiyun cit_Packet_Format1(gspca_dev, 0x39, 0x08);
1631*4882a593Smuzhiyun for (i = 0; i < cit_model1_ntries; i++)
1632*4882a593Smuzhiyun cit_Packet_Format1(gspca_dev, 0x34, 0x00);
1633*4882a593Smuzhiyun
1634*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00, 0x0101);
1635*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00, 0x010a);
1636*4882a593Smuzhiyun
1637*4882a593Smuzhiyun switch (gspca_dev->pixfmt.width) {
1638*4882a593Smuzhiyun case 128: /* 128x96 */
1639*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x80, 0x0103);
1640*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x60, 0x0105);
1641*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0c, 0x010b);
1642*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x04, 0x011b); /* Same everywhere */
1643*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0b, 0x011d);
1644*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00, 0x011e); /* Same everywhere */
1645*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00, 0x0129);
1646*4882a593Smuzhiyun break;
1647*4882a593Smuzhiyun case 176: /* 176x144 */
1648*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xb0, 0x0103);
1649*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x8f, 0x0105);
1650*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x06, 0x010b);
1651*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x04, 0x011b); /* Same everywhere */
1652*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0d, 0x011d);
1653*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00, 0x011e); /* Same everywhere */
1654*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x03, 0x0129);
1655*4882a593Smuzhiyun break;
1656*4882a593Smuzhiyun case 352: /* 352x288 */
1657*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xb0, 0x0103);
1658*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x90, 0x0105);
1659*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x02, 0x010b);
1660*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x04, 0x011b); /* Same everywhere */
1661*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x05, 0x011d);
1662*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00, 0x011e); /* Same everywhere */
1663*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00, 0x0129);
1664*4882a593Smuzhiyun break;
1665*4882a593Smuzhiyun }
1666*4882a593Smuzhiyun
1667*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xff, 0x012b);
1668*4882a593Smuzhiyun
1669*4882a593Smuzhiyun /* TESTME These are handled through controls
1670*4882a593Smuzhiyun KEEP until someone can test leaving this out is ok */
1671*4882a593Smuzhiyun if (0) {
1672*4882a593Smuzhiyun /* This is another brightness - don't know why */
1673*4882a593Smuzhiyun for (i = 0; i < cit_model1_ntries; i++)
1674*4882a593Smuzhiyun cit_Packet_Format1(gspca_dev, 0x31, 0xc3);
1675*4882a593Smuzhiyun for (i = 0; i < cit_model1_ntries; i++)
1676*4882a593Smuzhiyun cit_Packet_Format1(gspca_dev, 0x32, 0xd2);
1677*4882a593Smuzhiyun for (i = 0; i < cit_model1_ntries; i++)
1678*4882a593Smuzhiyun cit_Packet_Format1(gspca_dev, 0x33, 0xe1);
1679*4882a593Smuzhiyun
1680*4882a593Smuzhiyun /* Default contrast */
1681*4882a593Smuzhiyun for (i = 0; i < cit_model1_ntries; i++)
1682*4882a593Smuzhiyun cit_Packet_Format1(gspca_dev, 0x14, 0x0a);
1683*4882a593Smuzhiyun
1684*4882a593Smuzhiyun /* Default sharpness */
1685*4882a593Smuzhiyun for (i = 0; i < cit_model1_ntries2; i++)
1686*4882a593Smuzhiyun cit_PacketFormat2(gspca_dev, 0x13, 0x1a);
1687*4882a593Smuzhiyun
1688*4882a593Smuzhiyun /* Default lighting conditions */
1689*4882a593Smuzhiyun cit_Packet_Format1(gspca_dev, 0x0027,
1690*4882a593Smuzhiyun v4l2_ctrl_g_ctrl(sd->lighting));
1691*4882a593Smuzhiyun }
1692*4882a593Smuzhiyun
1693*4882a593Smuzhiyun /* Assorted init */
1694*4882a593Smuzhiyun switch (gspca_dev->pixfmt.width) {
1695*4882a593Smuzhiyun case 128: /* 128x96 */
1696*4882a593Smuzhiyun cit_Packet_Format1(gspca_dev, 0x2b, 0x1e);
1697*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xc9, 0x0119); /* Same everywhere */
1698*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x80, 0x0109); /* Same everywhere */
1699*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x36, 0x0102);
1700*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x1a, 0x0104);
1701*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x04, 0x011a); /* Same everywhere */
1702*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x2b, 0x011c);
1703*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x23, 0x012a); /* Same everywhere */
1704*4882a593Smuzhiyun break;
1705*4882a593Smuzhiyun case 176: /* 176x144 */
1706*4882a593Smuzhiyun cit_Packet_Format1(gspca_dev, 0x2b, 0x1e);
1707*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xc9, 0x0119); /* Same everywhere */
1708*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x80, 0x0109); /* Same everywhere */
1709*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x04, 0x0102);
1710*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x02, 0x0104);
1711*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x04, 0x011a); /* Same everywhere */
1712*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x2b, 0x011c);
1713*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x23, 0x012a); /* Same everywhere */
1714*4882a593Smuzhiyun break;
1715*4882a593Smuzhiyun case 352: /* 352x288 */
1716*4882a593Smuzhiyun cit_Packet_Format1(gspca_dev, 0x2b, 0x1f);
1717*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xc9, 0x0119); /* Same everywhere */
1718*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x80, 0x0109); /* Same everywhere */
1719*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x08, 0x0102);
1720*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x01, 0x0104);
1721*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x04, 0x011a); /* Same everywhere */
1722*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x2f, 0x011c);
1723*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x23, 0x012a); /* Same everywhere */
1724*4882a593Smuzhiyun break;
1725*4882a593Smuzhiyun }
1726*4882a593Smuzhiyun
1727*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x01, 0x0100); /* LED On */
1728*4882a593Smuzhiyun cit_write_reg(gspca_dev, clock_div, 0x0111);
1729*4882a593Smuzhiyun
1730*4882a593Smuzhiyun return 0;
1731*4882a593Smuzhiyun }
1732*4882a593Smuzhiyun
cit_start_model2(struct gspca_dev * gspca_dev)1733*4882a593Smuzhiyun static int cit_start_model2(struct gspca_dev *gspca_dev)
1734*4882a593Smuzhiyun {
1735*4882a593Smuzhiyun struct sd *sd = (struct sd *) gspca_dev;
1736*4882a593Smuzhiyun int clock_div = 0;
1737*4882a593Smuzhiyun
1738*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0100); /* LED on */
1739*4882a593Smuzhiyun cit_read_reg(gspca_dev, 0x0116, 0);
1740*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0060, 0x0116);
1741*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0002, 0x0112);
1742*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00bc, 0x012c);
1743*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0008, 0x012b);
1744*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0108);
1745*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0001, 0x0133);
1746*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0001, 0x0102);
1747*4882a593Smuzhiyun switch (gspca_dev->pixfmt.width) {
1748*4882a593Smuzhiyun case 176: /* 176x144 */
1749*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x002c, 0x0103); /* All except 320x240 */
1750*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0104); /* Same */
1751*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0024, 0x0105); /* 176x144, 352x288 */
1752*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00b9, 0x010a); /* Unique to this mode */
1753*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0038, 0x0119); /* Unique to this mode */
1754*4882a593Smuzhiyun /* TESTME HDG: this does not seem right
1755*4882a593Smuzhiyun (it is 2 for all other resolutions) */
1756*4882a593Smuzhiyun sd->sof_len = 10;
1757*4882a593Smuzhiyun break;
1758*4882a593Smuzhiyun case 320: /* 320x240 */
1759*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0028, 0x0103); /* Unique to this mode */
1760*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0104); /* Same */
1761*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x001e, 0x0105); /* 320x240, 352x240 */
1762*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0039, 0x010a); /* All except 176x144 */
1763*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0070, 0x0119); /* All except 176x144 */
1764*4882a593Smuzhiyun sd->sof_len = 2;
1765*4882a593Smuzhiyun break;
1766*4882a593Smuzhiyun #if 0
1767*4882a593Smuzhiyun case VIDEOSIZE_352x240:
1768*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x002c, 0x0103); /* All except 320x240 */
1769*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0104); /* Same */
1770*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x001e, 0x0105); /* 320x240, 352x240 */
1771*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0039, 0x010a); /* All except 176x144 */
1772*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0070, 0x0119); /* All except 176x144 */
1773*4882a593Smuzhiyun sd->sof_len = 2;
1774*4882a593Smuzhiyun break;
1775*4882a593Smuzhiyun #endif
1776*4882a593Smuzhiyun case 352: /* 352x288 */
1777*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x002c, 0x0103); /* All except 320x240 */
1778*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0104); /* Same */
1779*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0024, 0x0105); /* 176x144, 352x288 */
1780*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0039, 0x010a); /* All except 176x144 */
1781*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0070, 0x0119); /* All except 176x144 */
1782*4882a593Smuzhiyun sd->sof_len = 2;
1783*4882a593Smuzhiyun break;
1784*4882a593Smuzhiyun }
1785*4882a593Smuzhiyun
1786*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0100); /* LED on */
1787*4882a593Smuzhiyun
1788*4882a593Smuzhiyun switch (gspca_dev->pixfmt.width) {
1789*4882a593Smuzhiyun case 176: /* 176x144 */
1790*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0050, 0x0111);
1791*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00d0, 0x0111);
1792*4882a593Smuzhiyun break;
1793*4882a593Smuzhiyun case 320: /* 320x240 */
1794*4882a593Smuzhiyun case 352: /* 352x288 */
1795*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0040, 0x0111);
1796*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00c0, 0x0111);
1797*4882a593Smuzhiyun break;
1798*4882a593Smuzhiyun }
1799*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x009b, 0x010f);
1800*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00bb, 0x010f);
1801*4882a593Smuzhiyun
1802*4882a593Smuzhiyun /*
1803*4882a593Smuzhiyun * Hardware settings, may affect CMOS sensor; not user controls!
1804*4882a593Smuzhiyun * -------------------------------------------------------------
1805*4882a593Smuzhiyun * 0x0004: no effect
1806*4882a593Smuzhiyun * 0x0006: hardware effect
1807*4882a593Smuzhiyun * 0x0008: no effect
1808*4882a593Smuzhiyun * 0x000a: stops video stream, probably important h/w setting
1809*4882a593Smuzhiyun * 0x000c: changes color in hardware manner (not user setting)
1810*4882a593Smuzhiyun * 0x0012: changes number of colors (does not affect speed)
1811*4882a593Smuzhiyun * 0x002a: no effect
1812*4882a593Smuzhiyun * 0x002c: hardware setting (related to scan lines)
1813*4882a593Smuzhiyun * 0x002e: stops video stream, probably important h/w setting
1814*4882a593Smuzhiyun */
1815*4882a593Smuzhiyun cit_model2_Packet1(gspca_dev, 0x000a, 0x005c);
1816*4882a593Smuzhiyun cit_model2_Packet1(gspca_dev, 0x0004, 0x0000);
1817*4882a593Smuzhiyun cit_model2_Packet1(gspca_dev, 0x0006, 0x00fb);
1818*4882a593Smuzhiyun cit_model2_Packet1(gspca_dev, 0x0008, 0x0000);
1819*4882a593Smuzhiyun cit_model2_Packet1(gspca_dev, 0x000c, 0x0009);
1820*4882a593Smuzhiyun cit_model2_Packet1(gspca_dev, 0x0012, 0x000a);
1821*4882a593Smuzhiyun cit_model2_Packet1(gspca_dev, 0x002a, 0x0000);
1822*4882a593Smuzhiyun cit_model2_Packet1(gspca_dev, 0x002c, 0x0000);
1823*4882a593Smuzhiyun cit_model2_Packet1(gspca_dev, 0x002e, 0x0008);
1824*4882a593Smuzhiyun
1825*4882a593Smuzhiyun /*
1826*4882a593Smuzhiyun * Function 0x0030 pops up all over the place. Apparently
1827*4882a593Smuzhiyun * it is a hardware control register, with every bit assigned to
1828*4882a593Smuzhiyun * do something.
1829*4882a593Smuzhiyun */
1830*4882a593Smuzhiyun cit_model2_Packet1(gspca_dev, 0x0030, 0x0000);
1831*4882a593Smuzhiyun
1832*4882a593Smuzhiyun /*
1833*4882a593Smuzhiyun * Magic control of CMOS sensor. Only lower values like
1834*4882a593Smuzhiyun * 0-3 work, and picture shifts left or right. Don't change.
1835*4882a593Smuzhiyun */
1836*4882a593Smuzhiyun switch (gspca_dev->pixfmt.width) {
1837*4882a593Smuzhiyun case 176: /* 176x144 */
1838*4882a593Smuzhiyun cit_model2_Packet1(gspca_dev, 0x0014, 0x0002);
1839*4882a593Smuzhiyun cit_model2_Packet1(gspca_dev, 0x0016, 0x0002); /* Horizontal shift */
1840*4882a593Smuzhiyun cit_model2_Packet1(gspca_dev, 0x0018, 0x004a); /* Another hardware setting */
1841*4882a593Smuzhiyun clock_div = 6;
1842*4882a593Smuzhiyun break;
1843*4882a593Smuzhiyun case 320: /* 320x240 */
1844*4882a593Smuzhiyun cit_model2_Packet1(gspca_dev, 0x0014, 0x0009);
1845*4882a593Smuzhiyun cit_model2_Packet1(gspca_dev, 0x0016, 0x0005); /* Horizontal shift */
1846*4882a593Smuzhiyun cit_model2_Packet1(gspca_dev, 0x0018, 0x0044); /* Another hardware setting */
1847*4882a593Smuzhiyun clock_div = 8;
1848*4882a593Smuzhiyun break;
1849*4882a593Smuzhiyun #if 0
1850*4882a593Smuzhiyun case VIDEOSIZE_352x240:
1851*4882a593Smuzhiyun /* This mode doesn't work as Windows programs it; changed to work */
1852*4882a593Smuzhiyun cit_model2_Packet1(gspca_dev, 0x0014, 0x0009); /* Windows sets this to 8 */
1853*4882a593Smuzhiyun cit_model2_Packet1(gspca_dev, 0x0016, 0x0003); /* Horizontal shift */
1854*4882a593Smuzhiyun cit_model2_Packet1(gspca_dev, 0x0018, 0x0044); /* Windows sets this to 0x0045 */
1855*4882a593Smuzhiyun clock_div = 10;
1856*4882a593Smuzhiyun break;
1857*4882a593Smuzhiyun #endif
1858*4882a593Smuzhiyun case 352: /* 352x288 */
1859*4882a593Smuzhiyun cit_model2_Packet1(gspca_dev, 0x0014, 0x0003);
1860*4882a593Smuzhiyun cit_model2_Packet1(gspca_dev, 0x0016, 0x0002); /* Horizontal shift */
1861*4882a593Smuzhiyun cit_model2_Packet1(gspca_dev, 0x0018, 0x004a); /* Another hardware setting */
1862*4882a593Smuzhiyun clock_div = 16;
1863*4882a593Smuzhiyun break;
1864*4882a593Smuzhiyun }
1865*4882a593Smuzhiyun
1866*4882a593Smuzhiyun /* TESTME These are handled through controls
1867*4882a593Smuzhiyun KEEP until someone can test leaving this out is ok */
1868*4882a593Smuzhiyun if (0)
1869*4882a593Smuzhiyun cit_model2_Packet1(gspca_dev, 0x001a, 0x005a);
1870*4882a593Smuzhiyun
1871*4882a593Smuzhiyun /*
1872*4882a593Smuzhiyun * We have our own frame rate setting varying from 0 (slowest) to 6
1873*4882a593Smuzhiyun * (fastest). The camera model 2 allows frame rate in range [0..0x1F]
1874*4882a593Smuzhiyun # where 0 is also the slowest setting. However for all practical
1875*4882a593Smuzhiyun # reasons high settings make no sense because USB is not fast enough
1876*4882a593Smuzhiyun # to support high FPS. Be aware that the picture datastream will be
1877*4882a593Smuzhiyun # severely disrupted if you ask for frame rate faster than allowed
1878*4882a593Smuzhiyun # for the video size - see below:
1879*4882a593Smuzhiyun *
1880*4882a593Smuzhiyun * Allowable ranges (obtained experimentally on OHCI, K6-3, 450 MHz):
1881*4882a593Smuzhiyun * -----------------------------------------------------------------
1882*4882a593Smuzhiyun * 176x144: [6..31]
1883*4882a593Smuzhiyun * 320x240: [8..31]
1884*4882a593Smuzhiyun * 352x240: [10..31]
1885*4882a593Smuzhiyun * 352x288: [16..31] I have to raise lower threshold for stability...
1886*4882a593Smuzhiyun *
1887*4882a593Smuzhiyun * As usual, slower FPS provides better sensitivity.
1888*4882a593Smuzhiyun */
1889*4882a593Smuzhiyun cit_model2_Packet1(gspca_dev, 0x001c, clock_div);
1890*4882a593Smuzhiyun
1891*4882a593Smuzhiyun /*
1892*4882a593Smuzhiyun * This setting does not visibly affect pictures; left it here
1893*4882a593Smuzhiyun * because it was present in Windows USB data stream. This function
1894*4882a593Smuzhiyun * does not allow arbitrary values and apparently is a bit mask, to
1895*4882a593Smuzhiyun * be activated only at appropriate time. Don't change it randomly!
1896*4882a593Smuzhiyun */
1897*4882a593Smuzhiyun switch (gspca_dev->pixfmt.width) {
1898*4882a593Smuzhiyun case 176: /* 176x144 */
1899*4882a593Smuzhiyun cit_model2_Packet1(gspca_dev, 0x0026, 0x00c2);
1900*4882a593Smuzhiyun break;
1901*4882a593Smuzhiyun case 320: /* 320x240 */
1902*4882a593Smuzhiyun cit_model2_Packet1(gspca_dev, 0x0026, 0x0044);
1903*4882a593Smuzhiyun break;
1904*4882a593Smuzhiyun #if 0
1905*4882a593Smuzhiyun case VIDEOSIZE_352x240:
1906*4882a593Smuzhiyun cit_model2_Packet1(gspca_dev, 0x0026, 0x0046);
1907*4882a593Smuzhiyun break;
1908*4882a593Smuzhiyun #endif
1909*4882a593Smuzhiyun case 352: /* 352x288 */
1910*4882a593Smuzhiyun cit_model2_Packet1(gspca_dev, 0x0026, 0x0048);
1911*4882a593Smuzhiyun break;
1912*4882a593Smuzhiyun }
1913*4882a593Smuzhiyun
1914*4882a593Smuzhiyun cit_model2_Packet1(gspca_dev, 0x0028, v4l2_ctrl_g_ctrl(sd->lighting));
1915*4882a593Smuzhiyun /* model2 cannot change the backlight compensation while streaming */
1916*4882a593Smuzhiyun v4l2_ctrl_grab(sd->lighting, true);
1917*4882a593Smuzhiyun
1918*4882a593Smuzhiyun /* color balance rg2 */
1919*4882a593Smuzhiyun cit_model2_Packet1(gspca_dev, 0x001e, 0x002f);
1920*4882a593Smuzhiyun /* saturation */
1921*4882a593Smuzhiyun cit_model2_Packet1(gspca_dev, 0x0020, 0x0034);
1922*4882a593Smuzhiyun /* color balance yb */
1923*4882a593Smuzhiyun cit_model2_Packet1(gspca_dev, 0x0022, 0x00a0);
1924*4882a593Smuzhiyun
1925*4882a593Smuzhiyun /* Hardware control command */
1926*4882a593Smuzhiyun cit_model2_Packet1(gspca_dev, 0x0030, 0x0004);
1927*4882a593Smuzhiyun
1928*4882a593Smuzhiyun return 0;
1929*4882a593Smuzhiyun }
1930*4882a593Smuzhiyun
cit_start_model3(struct gspca_dev * gspca_dev)1931*4882a593Smuzhiyun static int cit_start_model3(struct gspca_dev *gspca_dev)
1932*4882a593Smuzhiyun {
1933*4882a593Smuzhiyun const unsigned short compression = 0; /* 0=none, 7=best frame rate */
1934*4882a593Smuzhiyun int i, clock_div = 0;
1935*4882a593Smuzhiyun
1936*4882a593Smuzhiyun /* HDG not in ibmcam driver, added to see if it helps with
1937*4882a593Smuzhiyun auto-detecting between model3 and ibm netcamera pro */
1938*4882a593Smuzhiyun cit_read_reg(gspca_dev, 0x128, 1);
1939*4882a593Smuzhiyun
1940*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0100);
1941*4882a593Smuzhiyun cit_read_reg(gspca_dev, 0x0116, 0);
1942*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0060, 0x0116);
1943*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0002, 0x0112);
1944*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0123);
1945*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0001, 0x0117);
1946*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0040, 0x0108);
1947*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0019, 0x012c);
1948*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0060, 0x0116);
1949*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0002, 0x0115);
1950*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0003, 0x0115);
1951*4882a593Smuzhiyun cit_read_reg(gspca_dev, 0x0115, 0);
1952*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x000b, 0x0115);
1953*4882a593Smuzhiyun
1954*4882a593Smuzhiyun /* TESTME HDG not in ibmcam driver, added to see if it helps with
1955*4882a593Smuzhiyun auto-detecting between model3 and ibm netcamera pro */
1956*4882a593Smuzhiyun if (0) {
1957*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0078, 0x012d);
1958*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0001, 0x012f);
1959*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xd141, 0x0124);
1960*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0079, 0x012d);
1961*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00ff, 0x0130);
1962*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xcd41, 0x0124);
1963*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xfffa, 0x0124);
1964*4882a593Smuzhiyun cit_read_reg(gspca_dev, 0x0126, 1);
1965*4882a593Smuzhiyun }
1966*4882a593Smuzhiyun
1967*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x000a, 0x0040);
1968*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x000b, 0x00f6);
1969*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x000c, 0x0002);
1970*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x000d, 0x0020);
1971*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x000e, 0x0033);
1972*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x000f, 0x0007);
1973*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0010, 0x0000);
1974*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0011, 0x0070);
1975*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0012, 0x0030);
1976*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0013, 0x0000);
1977*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0014, 0x0001);
1978*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0015, 0x0001);
1979*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0016, 0x0001);
1980*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0017, 0x0001);
1981*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0018, 0x0000);
1982*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x001e, 0x00c3);
1983*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0020, 0x0000);
1984*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0028, 0x0010);
1985*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0029, 0x0054);
1986*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x002a, 0x0013);
1987*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x002b, 0x0007);
1988*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x002d, 0x0028);
1989*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x002e, 0x0000);
1990*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0031, 0x0000);
1991*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0032, 0x0000);
1992*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0033, 0x0000);
1993*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0034, 0x0000);
1994*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0035, 0x0038);
1995*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x003a, 0x0001);
1996*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x003c, 0x001e);
1997*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x003f, 0x000a);
1998*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0041, 0x0000);
1999*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0046, 0x003f);
2000*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0047, 0x0000);
2001*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0050, 0x0005);
2002*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0052, 0x001a);
2003*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0053, 0x0003);
2004*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x005a, 0x006b);
2005*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x005d, 0x001e);
2006*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x005e, 0x0030);
2007*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x005f, 0x0041);
2008*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0064, 0x0008);
2009*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0065, 0x0015);
2010*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0068, 0x000f);
2011*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0079, 0x0000);
2012*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x007a, 0x0000);
2013*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x007c, 0x003f);
2014*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0082, 0x000f);
2015*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0085, 0x0000);
2016*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0099, 0x0000);
2017*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x009b, 0x0023);
2018*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x009c, 0x0022);
2019*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x009d, 0x0096);
2020*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x009e, 0x0096);
2021*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x009f, 0x000a);
2022*4882a593Smuzhiyun
2023*4882a593Smuzhiyun switch (gspca_dev->pixfmt.width) {
2024*4882a593Smuzhiyun case 160:
2025*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0101); /* Same on 160x120, 320x240 */
2026*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00a0, 0x0103); /* Same on 160x120, 320x240 */
2027*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0078, 0x0105); /* Same on 160x120, 320x240 */
2028*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x010a); /* Same */
2029*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0024, 0x010b); /* Differs everywhere */
2030*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00a9, 0x0119);
2031*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0016, 0x011b);
2032*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0002, 0x011d); /* Same on 160x120, 320x240 */
2033*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0003, 0x011e); /* Same on 160x120, 640x480 */
2034*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0129); /* Same */
2035*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00fc, 0x012b); /* Same */
2036*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0018, 0x0102);
2037*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0004, 0x0104);
2038*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0004, 0x011a);
2039*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0028, 0x011c);
2040*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0022, 0x012a); /* Same */
2041*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0118);
2042*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0132);
2043*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0021, 0x0001); /* Same */
2044*4882a593Smuzhiyun cit_write_reg(gspca_dev, compression, 0x0109);
2045*4882a593Smuzhiyun clock_div = 3;
2046*4882a593Smuzhiyun break;
2047*4882a593Smuzhiyun case 320:
2048*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0101); /* Same on 160x120, 320x240 */
2049*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00a0, 0x0103); /* Same on 160x120, 320x240 */
2050*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0078, 0x0105); /* Same on 160x120, 320x240 */
2051*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x010a); /* Same */
2052*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0028, 0x010b); /* Differs everywhere */
2053*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0002, 0x011d); /* Same */
2054*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x011e);
2055*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0129); /* Same */
2056*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00fc, 0x012b); /* Same */
2057*4882a593Smuzhiyun /* 4 commands from 160x120 skipped */
2058*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0022, 0x012a); /* Same */
2059*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0021, 0x0001); /* Same */
2060*4882a593Smuzhiyun cit_write_reg(gspca_dev, compression, 0x0109);
2061*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00d9, 0x0119);
2062*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0006, 0x011b);
2063*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0021, 0x0102); /* Same on 320x240, 640x480 */
2064*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0010, 0x0104);
2065*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0004, 0x011a);
2066*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x003f, 0x011c);
2067*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x001c, 0x0118);
2068*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0132);
2069*4882a593Smuzhiyun clock_div = 5;
2070*4882a593Smuzhiyun break;
2071*4882a593Smuzhiyun case 640:
2072*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00f0, 0x0105);
2073*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x010a); /* Same */
2074*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0038, 0x010b); /* Differs everywhere */
2075*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00d9, 0x0119); /* Same on 320x240, 640x480 */
2076*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0006, 0x011b); /* Same on 320x240, 640x480 */
2077*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0004, 0x011d); /* NC */
2078*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0003, 0x011e); /* Same on 160x120, 640x480 */
2079*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0129); /* Same */
2080*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00fc, 0x012b); /* Same */
2081*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0021, 0x0102); /* Same on 320x240, 640x480 */
2082*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0016, 0x0104); /* NC */
2083*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0004, 0x011a); /* Same on 320x240, 640x480 */
2084*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x003f, 0x011c); /* Same on 320x240, 640x480 */
2085*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0022, 0x012a); /* Same */
2086*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x001c, 0x0118); /* Same on 320x240, 640x480 */
2087*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0021, 0x0001); /* Same */
2088*4882a593Smuzhiyun cit_write_reg(gspca_dev, compression, 0x0109);
2089*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0040, 0x0101);
2090*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0040, 0x0103);
2091*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0132); /* Same on 320x240, 640x480 */
2092*4882a593Smuzhiyun clock_div = 7;
2093*4882a593Smuzhiyun break;
2094*4882a593Smuzhiyun }
2095*4882a593Smuzhiyun
2096*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x007e, 0x000e); /* Hue */
2097*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0036, 0x0011); /* Brightness */
2098*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0060, 0x0002); /* Sharpness */
2099*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0061, 0x0004); /* Sharpness */
2100*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0062, 0x0005); /* Sharpness */
2101*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0063, 0x0014); /* Sharpness */
2102*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0096, 0x00a0); /* Red sharpness */
2103*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0097, 0x0096); /* Blue sharpness */
2104*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0067, 0x0001); /* Contrast */
2105*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x005b, 0x000c); /* Contrast */
2106*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x005c, 0x0016); /* Contrast */
2107*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0098, 0x000b);
2108*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x002c, 0x0003); /* Was 1, broke 640x480 */
2109*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x002f, 0x002a);
2110*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0030, 0x0029);
2111*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0037, 0x0002);
2112*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0038, 0x0059);
2113*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x003d, 0x002e);
2114*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x003e, 0x0028);
2115*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0078, 0x0005);
2116*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x007b, 0x0011);
2117*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x007d, 0x004b);
2118*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x007f, 0x0022);
2119*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0080, 0x000c);
2120*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0081, 0x000b);
2121*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0083, 0x00fd);
2122*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0086, 0x000b);
2123*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0087, 0x000b);
2124*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x007e, 0x000e);
2125*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0096, 0x00a0); /* Red sharpness */
2126*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0097, 0x0096); /* Blue sharpness */
2127*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0098, 0x000b);
2128*4882a593Smuzhiyun
2129*4882a593Smuzhiyun /* FIXME we should probably use cit_get_clock_div() here (in
2130*4882a593Smuzhiyun combination with isoc negotiation using the programmable isoc size)
2131*4882a593Smuzhiyun like with the IBM netcam pro). */
2132*4882a593Smuzhiyun cit_write_reg(gspca_dev, clock_div, 0x0111); /* Clock Divider */
2133*4882a593Smuzhiyun
2134*4882a593Smuzhiyun switch (gspca_dev->pixfmt.width) {
2135*4882a593Smuzhiyun case 160:
2136*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x001f, 0x0000); /* Same */
2137*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0039, 0x001f); /* Same */
2138*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x003b, 0x003c); /* Same */
2139*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0040, 0x000a);
2140*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0051, 0x000a);
2141*4882a593Smuzhiyun break;
2142*4882a593Smuzhiyun case 320:
2143*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x001f, 0x0000); /* Same */
2144*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0039, 0x001f); /* Same */
2145*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x003b, 0x003c); /* Same */
2146*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0040, 0x0008);
2147*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0051, 0x000b);
2148*4882a593Smuzhiyun break;
2149*4882a593Smuzhiyun case 640:
2150*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x001f, 0x0002); /* !Same */
2151*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0039, 0x003e); /* !Same */
2152*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0040, 0x0008);
2153*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0051, 0x000a);
2154*4882a593Smuzhiyun break;
2155*4882a593Smuzhiyun }
2156*4882a593Smuzhiyun
2157*4882a593Smuzhiyun /* if (sd->input_index) { */
2158*4882a593Smuzhiyun if (rca_input) {
2159*4882a593Smuzhiyun for (i = 0; i < ARRAY_SIZE(rca_initdata); i++) {
2160*4882a593Smuzhiyun if (rca_initdata[i][0])
2161*4882a593Smuzhiyun cit_read_reg(gspca_dev, rca_initdata[i][2], 0);
2162*4882a593Smuzhiyun else
2163*4882a593Smuzhiyun cit_write_reg(gspca_dev, rca_initdata[i][1],
2164*4882a593Smuzhiyun rca_initdata[i][2]);
2165*4882a593Smuzhiyun }
2166*4882a593Smuzhiyun }
2167*4882a593Smuzhiyun
2168*4882a593Smuzhiyun return 0;
2169*4882a593Smuzhiyun }
2170*4882a593Smuzhiyun
cit_start_model4(struct gspca_dev * gspca_dev)2171*4882a593Smuzhiyun static int cit_start_model4(struct gspca_dev *gspca_dev)
2172*4882a593Smuzhiyun {
2173*4882a593Smuzhiyun struct sd *sd = (struct sd *) gspca_dev;
2174*4882a593Smuzhiyun
2175*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0100);
2176*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00c0, 0x0111);
2177*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00bc, 0x012c);
2178*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0080, 0x012b);
2179*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0108);
2180*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0001, 0x0133);
2181*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x009b, 0x010f);
2182*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00bb, 0x010f);
2183*4882a593Smuzhiyun cit_model4_Packet1(gspca_dev, 0x0038, 0x0000);
2184*4882a593Smuzhiyun cit_model4_Packet1(gspca_dev, 0x000a, 0x005c);
2185*4882a593Smuzhiyun
2186*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00aa, 0x012d);
2187*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0004, 0x012f);
2188*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xd141, 0x0124);
2189*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0127);
2190*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00fb, 0x012e);
2191*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0130);
2192*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x8a28, 0x0124);
2193*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00aa, 0x012f);
2194*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xd055, 0x0124);
2195*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x000c, 0x0127);
2196*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0009, 0x012e);
2197*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xaa28, 0x0124);
2198*4882a593Smuzhiyun
2199*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00aa, 0x012d);
2200*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0012, 0x012f);
2201*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xd141, 0x0124);
2202*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0008, 0x0127);
2203*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00aa, 0x0130);
2204*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x82a8, 0x0124);
2205*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x002a, 0x012d);
2206*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x012f);
2207*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xd145, 0x0124);
2208*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xfffa, 0x0124);
2209*4882a593Smuzhiyun cit_model4_Packet1(gspca_dev, 0x0034, 0x0000);
2210*4882a593Smuzhiyun
2211*4882a593Smuzhiyun switch (gspca_dev->pixfmt.width) {
2212*4882a593Smuzhiyun case 128: /* 128x96 */
2213*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0070, 0x0119);
2214*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00d0, 0x0111);
2215*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0039, 0x010a);
2216*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0001, 0x0102);
2217*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0028, 0x0103);
2218*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0104);
2219*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x001e, 0x0105);
2220*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00aa, 0x012d);
2221*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0016, 0x012f);
2222*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xd141, 0x0124);
2223*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x000a, 0x0127);
2224*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00aa, 0x0130);
2225*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x82a8, 0x0124);
2226*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0014, 0x012d);
2227*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0008, 0x012f);
2228*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xd145, 0x0124);
2229*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00aa, 0x012e);
2230*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x001a, 0x0130);
2231*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x8a0a, 0x0124);
2232*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x005a, 0x012d);
2233*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x9545, 0x0124);
2234*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00aa, 0x0127);
2235*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0018, 0x012e);
2236*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0043, 0x0130);
2237*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x8a28, 0x0124);
2238*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00aa, 0x012f);
2239*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xd055, 0x0124);
2240*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x001c, 0x0127);
2241*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00eb, 0x012e);
2242*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xaa28, 0x0124);
2243*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00aa, 0x012d);
2244*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0032, 0x012f);
2245*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xd141, 0x0124);
2246*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0127);
2247*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00aa, 0x0130);
2248*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x82a8, 0x0124);
2249*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0036, 0x012d);
2250*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0008, 0x012f);
2251*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xd145, 0x0124);
2252*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xfffa, 0x0124);
2253*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00aa, 0x012d);
2254*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x001e, 0x012f);
2255*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xd141, 0x0124);
2256*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0017, 0x0127);
2257*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0013, 0x012e);
2258*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0031, 0x0130);
2259*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x8a28, 0x0124);
2260*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0017, 0x012d);
2261*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0078, 0x012f);
2262*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xd145, 0x0124);
2263*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0127);
2264*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xfea8, 0x0124);
2265*4882a593Smuzhiyun sd->sof_len = 2;
2266*4882a593Smuzhiyun break;
2267*4882a593Smuzhiyun case 160: /* 160x120 */
2268*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0038, 0x0119);
2269*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00d0, 0x0111);
2270*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00b9, 0x010a);
2271*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0001, 0x0102);
2272*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0028, 0x0103);
2273*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0104);
2274*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x001e, 0x0105);
2275*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00aa, 0x012d);
2276*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0016, 0x012f);
2277*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xd141, 0x0124);
2278*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x000b, 0x0127);
2279*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00aa, 0x0130);
2280*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x82a8, 0x0124);
2281*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0014, 0x012d);
2282*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0008, 0x012f);
2283*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xd145, 0x0124);
2284*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00aa, 0x012e);
2285*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x001a, 0x0130);
2286*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x8a0a, 0x0124);
2287*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x005a, 0x012d);
2288*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x9545, 0x0124);
2289*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00aa, 0x0127);
2290*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0018, 0x012e);
2291*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0043, 0x0130);
2292*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x8a28, 0x0124);
2293*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00aa, 0x012f);
2294*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xd055, 0x0124);
2295*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x001c, 0x0127);
2296*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00c7, 0x012e);
2297*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xaa28, 0x0124);
2298*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00aa, 0x012d);
2299*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0032, 0x012f);
2300*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xd141, 0x0124);
2301*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0025, 0x0127);
2302*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00aa, 0x0130);
2303*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x82a8, 0x0124);
2304*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0036, 0x012d);
2305*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0008, 0x012f);
2306*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xd145, 0x0124);
2307*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xfffa, 0x0124);
2308*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00aa, 0x012d);
2309*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x001e, 0x012f);
2310*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xd141, 0x0124);
2311*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0048, 0x0127);
2312*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0035, 0x012e);
2313*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00d0, 0x0130);
2314*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x8a28, 0x0124);
2315*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0048, 0x012d);
2316*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0090, 0x012f);
2317*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xd145, 0x0124);
2318*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0001, 0x0127);
2319*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xfea8, 0x0124);
2320*4882a593Smuzhiyun sd->sof_len = 2;
2321*4882a593Smuzhiyun break;
2322*4882a593Smuzhiyun case 176: /* 176x144 */
2323*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0038, 0x0119);
2324*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00d0, 0x0111);
2325*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00b9, 0x010a);
2326*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0001, 0x0102);
2327*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x002c, 0x0103);
2328*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0104);
2329*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0024, 0x0105);
2330*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00aa, 0x012d);
2331*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0016, 0x012f);
2332*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xd141, 0x0124);
2333*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0007, 0x0127);
2334*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00aa, 0x0130);
2335*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x82a8, 0x0124);
2336*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0014, 0x012d);
2337*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0001, 0x012f);
2338*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xd145, 0x0124);
2339*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00aa, 0x012e);
2340*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x001a, 0x0130);
2341*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x8a0a, 0x0124);
2342*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x005e, 0x012d);
2343*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x9545, 0x0124);
2344*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00aa, 0x0127);
2345*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0018, 0x012e);
2346*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0049, 0x0130);
2347*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x8a28, 0x0124);
2348*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00aa, 0x012f);
2349*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xd055, 0x0124);
2350*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x001c, 0x0127);
2351*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00c7, 0x012e);
2352*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xaa28, 0x0124);
2353*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00aa, 0x012d);
2354*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0032, 0x012f);
2355*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xd141, 0x0124);
2356*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0028, 0x0127);
2357*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00aa, 0x0130);
2358*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x82a8, 0x0124);
2359*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0036, 0x012d);
2360*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0008, 0x012f);
2361*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xd145, 0x0124);
2362*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xfffa, 0x0124);
2363*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00aa, 0x012d);
2364*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x001e, 0x012f);
2365*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xd141, 0x0124);
2366*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0010, 0x0127);
2367*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0013, 0x012e);
2368*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x002a, 0x0130);
2369*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x8a28, 0x0124);
2370*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0010, 0x012d);
2371*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x006d, 0x012f);
2372*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xd145, 0x0124);
2373*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0001, 0x0127);
2374*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xfea8, 0x0124);
2375*4882a593Smuzhiyun /* TESTME HDG: this does not seem right
2376*4882a593Smuzhiyun (it is 2 for all other resolutions) */
2377*4882a593Smuzhiyun sd->sof_len = 10;
2378*4882a593Smuzhiyun break;
2379*4882a593Smuzhiyun case 320: /* 320x240 */
2380*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0070, 0x0119);
2381*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00d0, 0x0111);
2382*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0039, 0x010a);
2383*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0001, 0x0102);
2384*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0028, 0x0103);
2385*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0104);
2386*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x001e, 0x0105);
2387*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00aa, 0x012d);
2388*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0016, 0x012f);
2389*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xd141, 0x0124);
2390*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x000a, 0x0127);
2391*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00aa, 0x0130);
2392*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x82a8, 0x0124);
2393*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0014, 0x012d);
2394*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0008, 0x012f);
2395*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xd145, 0x0124);
2396*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00aa, 0x012e);
2397*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x001a, 0x0130);
2398*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x8a0a, 0x0124);
2399*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x005a, 0x012d);
2400*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x9545, 0x0124);
2401*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00aa, 0x0127);
2402*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0018, 0x012e);
2403*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0043, 0x0130);
2404*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x8a28, 0x0124);
2405*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00aa, 0x012f);
2406*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xd055, 0x0124);
2407*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x001c, 0x0127);
2408*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00eb, 0x012e);
2409*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xaa28, 0x0124);
2410*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00aa, 0x012d);
2411*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0032, 0x012f);
2412*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xd141, 0x0124);
2413*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0127);
2414*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00aa, 0x0130);
2415*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x82a8, 0x0124);
2416*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0036, 0x012d);
2417*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0008, 0x012f);
2418*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xd145, 0x0124);
2419*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xfffa, 0x0124);
2420*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00aa, 0x012d);
2421*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x001e, 0x012f);
2422*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xd141, 0x0124);
2423*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0017, 0x0127);
2424*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0013, 0x012e);
2425*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0031, 0x0130);
2426*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x8a28, 0x0124);
2427*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0017, 0x012d);
2428*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0078, 0x012f);
2429*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xd145, 0x0124);
2430*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0127);
2431*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xfea8, 0x0124);
2432*4882a593Smuzhiyun sd->sof_len = 2;
2433*4882a593Smuzhiyun break;
2434*4882a593Smuzhiyun case 352: /* 352x288 */
2435*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0070, 0x0119);
2436*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00c0, 0x0111);
2437*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0039, 0x010a);
2438*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0001, 0x0102);
2439*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x002c, 0x0103);
2440*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0104);
2441*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0024, 0x0105);
2442*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00aa, 0x012d);
2443*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0016, 0x012f);
2444*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xd141, 0x0124);
2445*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0006, 0x0127);
2446*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00aa, 0x0130);
2447*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x82a8, 0x0124);
2448*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0014, 0x012d);
2449*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0002, 0x012f);
2450*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xd145, 0x0124);
2451*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00aa, 0x012e);
2452*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x001a, 0x0130);
2453*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x8a0a, 0x0124);
2454*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x005e, 0x012d);
2455*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x9545, 0x0124);
2456*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00aa, 0x0127);
2457*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0018, 0x012e);
2458*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0049, 0x0130);
2459*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x8a28, 0x0124);
2460*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00aa, 0x012f);
2461*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xd055, 0x0124);
2462*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x001c, 0x0127);
2463*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00cf, 0x012e);
2464*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xaa28, 0x0124);
2465*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00aa, 0x012d);
2466*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0032, 0x012f);
2467*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xd141, 0x0124);
2468*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0127);
2469*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00aa, 0x0130);
2470*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x82a8, 0x0124);
2471*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0036, 0x012d);
2472*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0008, 0x012f);
2473*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xd145, 0x0124);
2474*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xfffa, 0x0124);
2475*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00aa, 0x012d);
2476*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x001e, 0x012f);
2477*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xd141, 0x0124);
2478*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0010, 0x0127);
2479*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0013, 0x012e);
2480*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0025, 0x0130);
2481*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x8a28, 0x0124);
2482*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0010, 0x012d);
2483*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0048, 0x012f);
2484*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xd145, 0x0124);
2485*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0127);
2486*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0xfea8, 0x0124);
2487*4882a593Smuzhiyun sd->sof_len = 2;
2488*4882a593Smuzhiyun break;
2489*4882a593Smuzhiyun }
2490*4882a593Smuzhiyun
2491*4882a593Smuzhiyun cit_model4_Packet1(gspca_dev, 0x0038, 0x0004);
2492*4882a593Smuzhiyun
2493*4882a593Smuzhiyun return 0;
2494*4882a593Smuzhiyun }
2495*4882a593Smuzhiyun
cit_start_ibm_netcam_pro(struct gspca_dev * gspca_dev)2496*4882a593Smuzhiyun static int cit_start_ibm_netcam_pro(struct gspca_dev *gspca_dev)
2497*4882a593Smuzhiyun {
2498*4882a593Smuzhiyun const unsigned short compression = 0; /* 0=none, 7=best frame rate */
2499*4882a593Smuzhiyun int i, clock_div;
2500*4882a593Smuzhiyun
2501*4882a593Smuzhiyun clock_div = cit_get_clock_div(gspca_dev);
2502*4882a593Smuzhiyun if (clock_div < 0)
2503*4882a593Smuzhiyun return clock_div;
2504*4882a593Smuzhiyun
2505*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0003, 0x0133);
2506*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0117);
2507*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0008, 0x0123);
2508*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0100);
2509*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0060, 0x0116);
2510*4882a593Smuzhiyun /* cit_write_reg(gspca_dev, 0x0002, 0x0112); see sd_stop0 */
2511*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0133);
2512*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0123);
2513*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0001, 0x0117);
2514*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0040, 0x0108);
2515*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0019, 0x012c);
2516*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0060, 0x0116);
2517*4882a593Smuzhiyun /* cit_write_reg(gspca_dev, 0x000b, 0x0115); see sd_stop0 */
2518*4882a593Smuzhiyun
2519*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0049, 0x0000);
2520*4882a593Smuzhiyun
2521*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0101); /* Same on 160x120, 320x240 */
2522*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x003a, 0x0102); /* Hstart */
2523*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00a0, 0x0103); /* Same on 160x120, 320x240 */
2524*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0078, 0x0105); /* Same on 160x120, 320x240 */
2525*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x010a); /* Same */
2526*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0002, 0x011d); /* Same on 160x120, 320x240 */
2527*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0129); /* Same */
2528*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00fc, 0x012b); /* Same */
2529*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0022, 0x012a); /* Same */
2530*4882a593Smuzhiyun
2531*4882a593Smuzhiyun switch (gspca_dev->pixfmt.width) {
2532*4882a593Smuzhiyun case 160: /* 160x120 */
2533*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0024, 0x010b);
2534*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0089, 0x0119);
2535*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x000a, 0x011b);
2536*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0003, 0x011e);
2537*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0007, 0x0104);
2538*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0009, 0x011a);
2539*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x008b, 0x011c);
2540*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0008, 0x0118);
2541*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0132);
2542*4882a593Smuzhiyun break;
2543*4882a593Smuzhiyun case 320: /* 320x240 */
2544*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0028, 0x010b);
2545*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00d9, 0x0119);
2546*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0006, 0x011b);
2547*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x011e);
2548*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x000e, 0x0104);
2549*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0004, 0x011a);
2550*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x003f, 0x011c);
2551*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x000c, 0x0118);
2552*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0132);
2553*4882a593Smuzhiyun break;
2554*4882a593Smuzhiyun }
2555*4882a593Smuzhiyun
2556*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0019, 0x0031);
2557*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x001a, 0x0003);
2558*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x001b, 0x0038);
2559*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x001c, 0x0000);
2560*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0024, 0x0001);
2561*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0027, 0x0001);
2562*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x002a, 0x0004);
2563*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0035, 0x000b);
2564*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x003f, 0x0001);
2565*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0044, 0x0000);
2566*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0054, 0x0000);
2567*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x00c4, 0x0000);
2568*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x00e7, 0x0001);
2569*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x00e9, 0x0001);
2570*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x00ee, 0x0000);
2571*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x00f3, 0x00c0);
2572*4882a593Smuzhiyun
2573*4882a593Smuzhiyun cit_write_reg(gspca_dev, compression, 0x0109);
2574*4882a593Smuzhiyun cit_write_reg(gspca_dev, clock_div, 0x0111);
2575*4882a593Smuzhiyun
2576*4882a593Smuzhiyun /* if (sd->input_index) { */
2577*4882a593Smuzhiyun if (rca_input) {
2578*4882a593Smuzhiyun for (i = 0; i < ARRAY_SIZE(rca_initdata); i++) {
2579*4882a593Smuzhiyun if (rca_initdata[i][0])
2580*4882a593Smuzhiyun cit_read_reg(gspca_dev, rca_initdata[i][2], 0);
2581*4882a593Smuzhiyun else
2582*4882a593Smuzhiyun cit_write_reg(gspca_dev, rca_initdata[i][1],
2583*4882a593Smuzhiyun rca_initdata[i][2]);
2584*4882a593Smuzhiyun }
2585*4882a593Smuzhiyun }
2586*4882a593Smuzhiyun
2587*4882a593Smuzhiyun return 0;
2588*4882a593Smuzhiyun }
2589*4882a593Smuzhiyun
2590*4882a593Smuzhiyun /* -- start the camera -- */
sd_start(struct gspca_dev * gspca_dev)2591*4882a593Smuzhiyun static int sd_start(struct gspca_dev *gspca_dev)
2592*4882a593Smuzhiyun {
2593*4882a593Smuzhiyun struct sd *sd = (struct sd *) gspca_dev;
2594*4882a593Smuzhiyun int packet_size;
2595*4882a593Smuzhiyun
2596*4882a593Smuzhiyun packet_size = cit_get_packet_size(gspca_dev);
2597*4882a593Smuzhiyun if (packet_size < 0)
2598*4882a593Smuzhiyun return packet_size;
2599*4882a593Smuzhiyun
2600*4882a593Smuzhiyun switch (sd->model) {
2601*4882a593Smuzhiyun case CIT_MODEL0:
2602*4882a593Smuzhiyun cit_start_model0(gspca_dev);
2603*4882a593Smuzhiyun break;
2604*4882a593Smuzhiyun case CIT_MODEL1:
2605*4882a593Smuzhiyun cit_start_model1(gspca_dev);
2606*4882a593Smuzhiyun break;
2607*4882a593Smuzhiyun case CIT_MODEL2:
2608*4882a593Smuzhiyun cit_start_model2(gspca_dev);
2609*4882a593Smuzhiyun break;
2610*4882a593Smuzhiyun case CIT_MODEL3:
2611*4882a593Smuzhiyun cit_start_model3(gspca_dev);
2612*4882a593Smuzhiyun break;
2613*4882a593Smuzhiyun case CIT_MODEL4:
2614*4882a593Smuzhiyun cit_start_model4(gspca_dev);
2615*4882a593Smuzhiyun break;
2616*4882a593Smuzhiyun case CIT_IBM_NETCAM_PRO:
2617*4882a593Smuzhiyun cit_start_ibm_netcam_pro(gspca_dev);
2618*4882a593Smuzhiyun break;
2619*4882a593Smuzhiyun }
2620*4882a593Smuzhiyun
2621*4882a593Smuzhiyun /* Program max isoc packet size */
2622*4882a593Smuzhiyun cit_write_reg(gspca_dev, packet_size >> 8, 0x0106);
2623*4882a593Smuzhiyun cit_write_reg(gspca_dev, packet_size & 0xff, 0x0107);
2624*4882a593Smuzhiyun
2625*4882a593Smuzhiyun cit_restart_stream(gspca_dev);
2626*4882a593Smuzhiyun
2627*4882a593Smuzhiyun return 0;
2628*4882a593Smuzhiyun }
2629*4882a593Smuzhiyun
sd_isoc_init(struct gspca_dev * gspca_dev)2630*4882a593Smuzhiyun static int sd_isoc_init(struct gspca_dev *gspca_dev)
2631*4882a593Smuzhiyun {
2632*4882a593Smuzhiyun struct usb_interface_cache *intfc;
2633*4882a593Smuzhiyun struct usb_host_interface *alt;
2634*4882a593Smuzhiyun int max_packet_size;
2635*4882a593Smuzhiyun
2636*4882a593Smuzhiyun switch (gspca_dev->pixfmt.width) {
2637*4882a593Smuzhiyun case 160:
2638*4882a593Smuzhiyun max_packet_size = 450;
2639*4882a593Smuzhiyun break;
2640*4882a593Smuzhiyun case 176:
2641*4882a593Smuzhiyun max_packet_size = 600;
2642*4882a593Smuzhiyun break;
2643*4882a593Smuzhiyun default:
2644*4882a593Smuzhiyun max_packet_size = 1022;
2645*4882a593Smuzhiyun break;
2646*4882a593Smuzhiyun }
2647*4882a593Smuzhiyun
2648*4882a593Smuzhiyun intfc = gspca_dev->dev->actconfig->intf_cache[0];
2649*4882a593Smuzhiyun
2650*4882a593Smuzhiyun if (intfc->num_altsetting < 2)
2651*4882a593Smuzhiyun return -ENODEV;
2652*4882a593Smuzhiyun
2653*4882a593Smuzhiyun alt = &intfc->altsetting[1];
2654*4882a593Smuzhiyun
2655*4882a593Smuzhiyun if (alt->desc.bNumEndpoints < 1)
2656*4882a593Smuzhiyun return -ENODEV;
2657*4882a593Smuzhiyun
2658*4882a593Smuzhiyun /* Start isoc bandwidth "negotiation" at max isoc bandwidth */
2659*4882a593Smuzhiyun alt->endpoint[0].desc.wMaxPacketSize = cpu_to_le16(max_packet_size);
2660*4882a593Smuzhiyun
2661*4882a593Smuzhiyun return 0;
2662*4882a593Smuzhiyun }
2663*4882a593Smuzhiyun
sd_isoc_nego(struct gspca_dev * gspca_dev)2664*4882a593Smuzhiyun static int sd_isoc_nego(struct gspca_dev *gspca_dev)
2665*4882a593Smuzhiyun {
2666*4882a593Smuzhiyun int ret, packet_size, min_packet_size;
2667*4882a593Smuzhiyun struct usb_host_interface *alt;
2668*4882a593Smuzhiyun
2669*4882a593Smuzhiyun switch (gspca_dev->pixfmt.width) {
2670*4882a593Smuzhiyun case 160:
2671*4882a593Smuzhiyun min_packet_size = 200;
2672*4882a593Smuzhiyun break;
2673*4882a593Smuzhiyun case 176:
2674*4882a593Smuzhiyun min_packet_size = 266;
2675*4882a593Smuzhiyun break;
2676*4882a593Smuzhiyun default:
2677*4882a593Smuzhiyun min_packet_size = 400;
2678*4882a593Smuzhiyun break;
2679*4882a593Smuzhiyun }
2680*4882a593Smuzhiyun
2681*4882a593Smuzhiyun /*
2682*4882a593Smuzhiyun * Existence of altsetting and endpoint was verified in sd_isoc_init()
2683*4882a593Smuzhiyun */
2684*4882a593Smuzhiyun alt = &gspca_dev->dev->actconfig->intf_cache[0]->altsetting[1];
2685*4882a593Smuzhiyun packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
2686*4882a593Smuzhiyun if (packet_size <= min_packet_size)
2687*4882a593Smuzhiyun return -EIO;
2688*4882a593Smuzhiyun
2689*4882a593Smuzhiyun packet_size -= 100;
2690*4882a593Smuzhiyun if (packet_size < min_packet_size)
2691*4882a593Smuzhiyun packet_size = min_packet_size;
2692*4882a593Smuzhiyun alt->endpoint[0].desc.wMaxPacketSize = cpu_to_le16(packet_size);
2693*4882a593Smuzhiyun
2694*4882a593Smuzhiyun ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1);
2695*4882a593Smuzhiyun if (ret < 0)
2696*4882a593Smuzhiyun pr_err("set alt 1 err %d\n", ret);
2697*4882a593Smuzhiyun
2698*4882a593Smuzhiyun return ret;
2699*4882a593Smuzhiyun }
2700*4882a593Smuzhiyun
sd_stopN(struct gspca_dev * gspca_dev)2701*4882a593Smuzhiyun static void sd_stopN(struct gspca_dev *gspca_dev)
2702*4882a593Smuzhiyun {
2703*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x010c);
2704*4882a593Smuzhiyun }
2705*4882a593Smuzhiyun
sd_stop0(struct gspca_dev * gspca_dev)2706*4882a593Smuzhiyun static void sd_stop0(struct gspca_dev *gspca_dev)
2707*4882a593Smuzhiyun {
2708*4882a593Smuzhiyun struct sd *sd = (struct sd *) gspca_dev;
2709*4882a593Smuzhiyun
2710*4882a593Smuzhiyun if (!gspca_dev->present)
2711*4882a593Smuzhiyun return;
2712*4882a593Smuzhiyun
2713*4882a593Smuzhiyun switch (sd->model) {
2714*4882a593Smuzhiyun case CIT_MODEL0:
2715*4882a593Smuzhiyun /* HDG windows does this, but it causes the cams autogain to
2716*4882a593Smuzhiyun restart from a gain of 0, which does not look good when
2717*4882a593Smuzhiyun changing resolutions. */
2718*4882a593Smuzhiyun /* cit_write_reg(gspca_dev, 0x0000, 0x0112); */
2719*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00c0, 0x0100); /* LED Off */
2720*4882a593Smuzhiyun break;
2721*4882a593Smuzhiyun case CIT_MODEL1:
2722*4882a593Smuzhiyun cit_send_FF_04_02(gspca_dev);
2723*4882a593Smuzhiyun cit_read_reg(gspca_dev, 0x0100, 0);
2724*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x81, 0x0100); /* LED Off */
2725*4882a593Smuzhiyun break;
2726*4882a593Smuzhiyun case CIT_MODEL2:
2727*4882a593Smuzhiyun v4l2_ctrl_grab(sd->lighting, false);
2728*4882a593Smuzhiyun fallthrough;
2729*4882a593Smuzhiyun case CIT_MODEL4:
2730*4882a593Smuzhiyun cit_model2_Packet1(gspca_dev, 0x0030, 0x0004);
2731*4882a593Smuzhiyun
2732*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0080, 0x0100); /* LED Off */
2733*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0020, 0x0111);
2734*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00a0, 0x0111);
2735*4882a593Smuzhiyun
2736*4882a593Smuzhiyun cit_model2_Packet1(gspca_dev, 0x0030, 0x0002);
2737*4882a593Smuzhiyun
2738*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0020, 0x0111);
2739*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0112);
2740*4882a593Smuzhiyun break;
2741*4882a593Smuzhiyun case CIT_MODEL3:
2742*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0006, 0x012c);
2743*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0046, 0x0000);
2744*4882a593Smuzhiyun cit_read_reg(gspca_dev, 0x0116, 0);
2745*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0064, 0x0116);
2746*4882a593Smuzhiyun cit_read_reg(gspca_dev, 0x0115, 0);
2747*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0003, 0x0115);
2748*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0008, 0x0123);
2749*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0117);
2750*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0112);
2751*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0080, 0x0100);
2752*4882a593Smuzhiyun break;
2753*4882a593Smuzhiyun case CIT_IBM_NETCAM_PRO:
2754*4882a593Smuzhiyun cit_model3_Packet1(gspca_dev, 0x0049, 0x00ff);
2755*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0006, 0x012c);
2756*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0116);
2757*4882a593Smuzhiyun /* HDG windows does this, but I cannot get the camera
2758*4882a593Smuzhiyun to restart with this without redoing the entire init
2759*4882a593Smuzhiyun sequence which makes switching modes really slow */
2760*4882a593Smuzhiyun /* cit_write_reg(gspca_dev, 0x0006, 0x0115); */
2761*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0008, 0x0123);
2762*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0117);
2763*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0003, 0x0133);
2764*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x0000, 0x0111);
2765*4882a593Smuzhiyun /* HDG windows does this, but I get a green picture when
2766*4882a593Smuzhiyun restarting the stream after this */
2767*4882a593Smuzhiyun /* cit_write_reg(gspca_dev, 0x0000, 0x0112); */
2768*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x00c0, 0x0100);
2769*4882a593Smuzhiyun break;
2770*4882a593Smuzhiyun }
2771*4882a593Smuzhiyun
2772*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_INPUT)
2773*4882a593Smuzhiyun /* If the last button state is pressed, release it now! */
2774*4882a593Smuzhiyun if (sd->button_state) {
2775*4882a593Smuzhiyun input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
2776*4882a593Smuzhiyun input_sync(gspca_dev->input_dev);
2777*4882a593Smuzhiyun sd->button_state = 0;
2778*4882a593Smuzhiyun }
2779*4882a593Smuzhiyun #endif
2780*4882a593Smuzhiyun }
2781*4882a593Smuzhiyun
cit_find_sof(struct gspca_dev * gspca_dev,u8 * data,int len)2782*4882a593Smuzhiyun static u8 *cit_find_sof(struct gspca_dev *gspca_dev, u8 *data, int len)
2783*4882a593Smuzhiyun {
2784*4882a593Smuzhiyun struct sd *sd = (struct sd *) gspca_dev;
2785*4882a593Smuzhiyun u8 byte3 = 0, byte4 = 0;
2786*4882a593Smuzhiyun int i;
2787*4882a593Smuzhiyun
2788*4882a593Smuzhiyun switch (sd->model) {
2789*4882a593Smuzhiyun case CIT_MODEL0:
2790*4882a593Smuzhiyun case CIT_MODEL1:
2791*4882a593Smuzhiyun case CIT_MODEL3:
2792*4882a593Smuzhiyun case CIT_IBM_NETCAM_PRO:
2793*4882a593Smuzhiyun switch (gspca_dev->pixfmt.width) {
2794*4882a593Smuzhiyun case 160: /* 160x120 */
2795*4882a593Smuzhiyun byte3 = 0x02;
2796*4882a593Smuzhiyun byte4 = 0x0a;
2797*4882a593Smuzhiyun break;
2798*4882a593Smuzhiyun case 176: /* 176x144 */
2799*4882a593Smuzhiyun byte3 = 0x02;
2800*4882a593Smuzhiyun byte4 = 0x0e;
2801*4882a593Smuzhiyun break;
2802*4882a593Smuzhiyun case 320: /* 320x240 */
2803*4882a593Smuzhiyun byte3 = 0x02;
2804*4882a593Smuzhiyun byte4 = 0x08;
2805*4882a593Smuzhiyun break;
2806*4882a593Smuzhiyun case 352: /* 352x288 */
2807*4882a593Smuzhiyun byte3 = 0x02;
2808*4882a593Smuzhiyun byte4 = 0x00;
2809*4882a593Smuzhiyun break;
2810*4882a593Smuzhiyun case 640:
2811*4882a593Smuzhiyun byte3 = 0x03;
2812*4882a593Smuzhiyun byte4 = 0x08;
2813*4882a593Smuzhiyun break;
2814*4882a593Smuzhiyun }
2815*4882a593Smuzhiyun
2816*4882a593Smuzhiyun /* These have a different byte3 */
2817*4882a593Smuzhiyun if (sd->model <= CIT_MODEL1)
2818*4882a593Smuzhiyun byte3 = 0x00;
2819*4882a593Smuzhiyun
2820*4882a593Smuzhiyun for (i = 0; i < len; i++) {
2821*4882a593Smuzhiyun /* For this model the SOF always starts at offset 0
2822*4882a593Smuzhiyun so no need to search the entire frame */
2823*4882a593Smuzhiyun if (sd->model == CIT_MODEL0 && sd->sof_read != i)
2824*4882a593Smuzhiyun break;
2825*4882a593Smuzhiyun
2826*4882a593Smuzhiyun switch (sd->sof_read) {
2827*4882a593Smuzhiyun case 0:
2828*4882a593Smuzhiyun if (data[i] == 0x00)
2829*4882a593Smuzhiyun sd->sof_read++;
2830*4882a593Smuzhiyun break;
2831*4882a593Smuzhiyun case 1:
2832*4882a593Smuzhiyun if (data[i] == 0xff)
2833*4882a593Smuzhiyun sd->sof_read++;
2834*4882a593Smuzhiyun else if (data[i] == 0x00)
2835*4882a593Smuzhiyun sd->sof_read = 1;
2836*4882a593Smuzhiyun else
2837*4882a593Smuzhiyun sd->sof_read = 0;
2838*4882a593Smuzhiyun break;
2839*4882a593Smuzhiyun case 2:
2840*4882a593Smuzhiyun if (data[i] == byte3)
2841*4882a593Smuzhiyun sd->sof_read++;
2842*4882a593Smuzhiyun else if (data[i] == 0x00)
2843*4882a593Smuzhiyun sd->sof_read = 1;
2844*4882a593Smuzhiyun else
2845*4882a593Smuzhiyun sd->sof_read = 0;
2846*4882a593Smuzhiyun break;
2847*4882a593Smuzhiyun case 3:
2848*4882a593Smuzhiyun if (data[i] == byte4) {
2849*4882a593Smuzhiyun sd->sof_read = 0;
2850*4882a593Smuzhiyun return data + i + (sd->sof_len - 3);
2851*4882a593Smuzhiyun }
2852*4882a593Smuzhiyun if (byte3 == 0x00 && data[i] == 0xff)
2853*4882a593Smuzhiyun sd->sof_read = 2;
2854*4882a593Smuzhiyun else if (data[i] == 0x00)
2855*4882a593Smuzhiyun sd->sof_read = 1;
2856*4882a593Smuzhiyun else
2857*4882a593Smuzhiyun sd->sof_read = 0;
2858*4882a593Smuzhiyun break;
2859*4882a593Smuzhiyun }
2860*4882a593Smuzhiyun }
2861*4882a593Smuzhiyun break;
2862*4882a593Smuzhiyun case CIT_MODEL2:
2863*4882a593Smuzhiyun case CIT_MODEL4:
2864*4882a593Smuzhiyun /* TESTME we need to find a longer sof signature to avoid
2865*4882a593Smuzhiyun false positives */
2866*4882a593Smuzhiyun for (i = 0; i < len; i++) {
2867*4882a593Smuzhiyun switch (sd->sof_read) {
2868*4882a593Smuzhiyun case 0:
2869*4882a593Smuzhiyun if (data[i] == 0x00)
2870*4882a593Smuzhiyun sd->sof_read++;
2871*4882a593Smuzhiyun break;
2872*4882a593Smuzhiyun case 1:
2873*4882a593Smuzhiyun sd->sof_read = 0;
2874*4882a593Smuzhiyun if (data[i] == 0xff) {
2875*4882a593Smuzhiyun if (i >= 4)
2876*4882a593Smuzhiyun gspca_dbg(gspca_dev, D_FRAM,
2877*4882a593Smuzhiyun "header found at offset: %d: %02x %02x 00 %3ph\n\n",
2878*4882a593Smuzhiyun i - 1,
2879*4882a593Smuzhiyun data[i - 4],
2880*4882a593Smuzhiyun data[i - 3],
2881*4882a593Smuzhiyun &data[i]);
2882*4882a593Smuzhiyun else
2883*4882a593Smuzhiyun gspca_dbg(gspca_dev, D_FRAM,
2884*4882a593Smuzhiyun "header found at offset: %d: 00 %3ph\n\n",
2885*4882a593Smuzhiyun i - 1,
2886*4882a593Smuzhiyun &data[i]);
2887*4882a593Smuzhiyun return data + i + (sd->sof_len - 1);
2888*4882a593Smuzhiyun }
2889*4882a593Smuzhiyun break;
2890*4882a593Smuzhiyun }
2891*4882a593Smuzhiyun }
2892*4882a593Smuzhiyun break;
2893*4882a593Smuzhiyun }
2894*4882a593Smuzhiyun return NULL;
2895*4882a593Smuzhiyun }
2896*4882a593Smuzhiyun
sd_pkt_scan(struct gspca_dev * gspca_dev,u8 * data,int len)2897*4882a593Smuzhiyun static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2898*4882a593Smuzhiyun u8 *data, int len)
2899*4882a593Smuzhiyun {
2900*4882a593Smuzhiyun struct sd *sd = (struct sd *) gspca_dev;
2901*4882a593Smuzhiyun unsigned char *sof;
2902*4882a593Smuzhiyun
2903*4882a593Smuzhiyun sof = cit_find_sof(gspca_dev, data, len);
2904*4882a593Smuzhiyun if (sof) {
2905*4882a593Smuzhiyun int n;
2906*4882a593Smuzhiyun
2907*4882a593Smuzhiyun /* finish decoding current frame */
2908*4882a593Smuzhiyun n = sof - data;
2909*4882a593Smuzhiyun if (n > sd->sof_len)
2910*4882a593Smuzhiyun n -= sd->sof_len;
2911*4882a593Smuzhiyun else
2912*4882a593Smuzhiyun n = 0;
2913*4882a593Smuzhiyun gspca_frame_add(gspca_dev, LAST_PACKET,
2914*4882a593Smuzhiyun data, n);
2915*4882a593Smuzhiyun gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
2916*4882a593Smuzhiyun len -= sof - data;
2917*4882a593Smuzhiyun data = sof;
2918*4882a593Smuzhiyun }
2919*4882a593Smuzhiyun
2920*4882a593Smuzhiyun gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
2921*4882a593Smuzhiyun }
2922*4882a593Smuzhiyun
2923*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_INPUT)
cit_check_button(struct gspca_dev * gspca_dev)2924*4882a593Smuzhiyun static void cit_check_button(struct gspca_dev *gspca_dev)
2925*4882a593Smuzhiyun {
2926*4882a593Smuzhiyun int new_button_state;
2927*4882a593Smuzhiyun struct sd *sd = (struct sd *)gspca_dev;
2928*4882a593Smuzhiyun
2929*4882a593Smuzhiyun switch (sd->model) {
2930*4882a593Smuzhiyun case CIT_MODEL3:
2931*4882a593Smuzhiyun case CIT_IBM_NETCAM_PRO:
2932*4882a593Smuzhiyun break;
2933*4882a593Smuzhiyun default: /* TEST ME unknown if this works on other models too */
2934*4882a593Smuzhiyun return;
2935*4882a593Smuzhiyun }
2936*4882a593Smuzhiyun
2937*4882a593Smuzhiyun /* Read the button state */
2938*4882a593Smuzhiyun cit_read_reg(gspca_dev, 0x0113, 0);
2939*4882a593Smuzhiyun new_button_state = !gspca_dev->usb_buf[0];
2940*4882a593Smuzhiyun
2941*4882a593Smuzhiyun /* Tell the cam we've seen the button press, notice that this
2942*4882a593Smuzhiyun is a nop (iow the cam keeps reporting pressed) until the
2943*4882a593Smuzhiyun button is actually released. */
2944*4882a593Smuzhiyun if (new_button_state)
2945*4882a593Smuzhiyun cit_write_reg(gspca_dev, 0x01, 0x0113);
2946*4882a593Smuzhiyun
2947*4882a593Smuzhiyun if (sd->button_state != new_button_state) {
2948*4882a593Smuzhiyun input_report_key(gspca_dev->input_dev, KEY_CAMERA,
2949*4882a593Smuzhiyun new_button_state);
2950*4882a593Smuzhiyun input_sync(gspca_dev->input_dev);
2951*4882a593Smuzhiyun sd->button_state = new_button_state;
2952*4882a593Smuzhiyun }
2953*4882a593Smuzhiyun }
2954*4882a593Smuzhiyun #endif
2955*4882a593Smuzhiyun
sd_s_ctrl(struct v4l2_ctrl * ctrl)2956*4882a593Smuzhiyun static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
2957*4882a593Smuzhiyun {
2958*4882a593Smuzhiyun struct gspca_dev *gspca_dev =
2959*4882a593Smuzhiyun container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
2960*4882a593Smuzhiyun struct sd *sd = (struct sd *)gspca_dev;
2961*4882a593Smuzhiyun
2962*4882a593Smuzhiyun gspca_dev->usb_err = 0;
2963*4882a593Smuzhiyun
2964*4882a593Smuzhiyun if (!gspca_dev->streaming)
2965*4882a593Smuzhiyun return 0;
2966*4882a593Smuzhiyun
2967*4882a593Smuzhiyun if (sd->stop_on_control_change)
2968*4882a593Smuzhiyun sd_stopN(gspca_dev);
2969*4882a593Smuzhiyun switch (ctrl->id) {
2970*4882a593Smuzhiyun case V4L2_CID_BRIGHTNESS:
2971*4882a593Smuzhiyun cit_set_brightness(gspca_dev, ctrl->val);
2972*4882a593Smuzhiyun break;
2973*4882a593Smuzhiyun case V4L2_CID_CONTRAST:
2974*4882a593Smuzhiyun cit_set_contrast(gspca_dev, ctrl->val);
2975*4882a593Smuzhiyun break;
2976*4882a593Smuzhiyun case V4L2_CID_HUE:
2977*4882a593Smuzhiyun cit_set_hue(gspca_dev, ctrl->val);
2978*4882a593Smuzhiyun break;
2979*4882a593Smuzhiyun case V4L2_CID_HFLIP:
2980*4882a593Smuzhiyun cit_set_hflip(gspca_dev, ctrl->val);
2981*4882a593Smuzhiyun break;
2982*4882a593Smuzhiyun case V4L2_CID_SHARPNESS:
2983*4882a593Smuzhiyun cit_set_sharpness(gspca_dev, ctrl->val);
2984*4882a593Smuzhiyun break;
2985*4882a593Smuzhiyun case V4L2_CID_BACKLIGHT_COMPENSATION:
2986*4882a593Smuzhiyun cit_set_lighting(gspca_dev, ctrl->val);
2987*4882a593Smuzhiyun break;
2988*4882a593Smuzhiyun }
2989*4882a593Smuzhiyun if (sd->stop_on_control_change)
2990*4882a593Smuzhiyun cit_restart_stream(gspca_dev);
2991*4882a593Smuzhiyun return gspca_dev->usb_err;
2992*4882a593Smuzhiyun }
2993*4882a593Smuzhiyun
2994*4882a593Smuzhiyun static const struct v4l2_ctrl_ops sd_ctrl_ops = {
2995*4882a593Smuzhiyun .s_ctrl = sd_s_ctrl,
2996*4882a593Smuzhiyun };
2997*4882a593Smuzhiyun
sd_init_controls(struct gspca_dev * gspca_dev)2998*4882a593Smuzhiyun static int sd_init_controls(struct gspca_dev *gspca_dev)
2999*4882a593Smuzhiyun {
3000*4882a593Smuzhiyun struct sd *sd = (struct sd *)gspca_dev;
3001*4882a593Smuzhiyun struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
3002*4882a593Smuzhiyun bool has_brightness;
3003*4882a593Smuzhiyun bool has_contrast;
3004*4882a593Smuzhiyun bool has_hue;
3005*4882a593Smuzhiyun bool has_sharpness;
3006*4882a593Smuzhiyun bool has_lighting;
3007*4882a593Smuzhiyun bool has_hflip;
3008*4882a593Smuzhiyun
3009*4882a593Smuzhiyun has_brightness = has_contrast = has_hue =
3010*4882a593Smuzhiyun has_sharpness = has_hflip = has_lighting = false;
3011*4882a593Smuzhiyun switch (sd->model) {
3012*4882a593Smuzhiyun case CIT_MODEL0:
3013*4882a593Smuzhiyun has_contrast = has_hflip = true;
3014*4882a593Smuzhiyun break;
3015*4882a593Smuzhiyun case CIT_MODEL1:
3016*4882a593Smuzhiyun has_brightness = has_contrast =
3017*4882a593Smuzhiyun has_sharpness = has_lighting = true;
3018*4882a593Smuzhiyun break;
3019*4882a593Smuzhiyun case CIT_MODEL2:
3020*4882a593Smuzhiyun has_brightness = has_hue = has_lighting = true;
3021*4882a593Smuzhiyun break;
3022*4882a593Smuzhiyun case CIT_MODEL3:
3023*4882a593Smuzhiyun has_brightness = has_contrast = has_sharpness = true;
3024*4882a593Smuzhiyun break;
3025*4882a593Smuzhiyun case CIT_MODEL4:
3026*4882a593Smuzhiyun has_brightness = has_hue = true;
3027*4882a593Smuzhiyun break;
3028*4882a593Smuzhiyun case CIT_IBM_NETCAM_PRO:
3029*4882a593Smuzhiyun has_brightness = has_hue =
3030*4882a593Smuzhiyun has_sharpness = has_hflip = has_lighting = true;
3031*4882a593Smuzhiyun break;
3032*4882a593Smuzhiyun }
3033*4882a593Smuzhiyun gspca_dev->vdev.ctrl_handler = hdl;
3034*4882a593Smuzhiyun v4l2_ctrl_handler_init(hdl, 5);
3035*4882a593Smuzhiyun if (has_brightness)
3036*4882a593Smuzhiyun v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
3037*4882a593Smuzhiyun V4L2_CID_BRIGHTNESS, 0, 63, 1, 32);
3038*4882a593Smuzhiyun if (has_contrast)
3039*4882a593Smuzhiyun v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
3040*4882a593Smuzhiyun V4L2_CID_CONTRAST, 0, 20, 1, 10);
3041*4882a593Smuzhiyun if (has_hue)
3042*4882a593Smuzhiyun v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
3043*4882a593Smuzhiyun V4L2_CID_HUE, 0, 127, 1, 63);
3044*4882a593Smuzhiyun if (has_sharpness)
3045*4882a593Smuzhiyun v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
3046*4882a593Smuzhiyun V4L2_CID_SHARPNESS, 0, 6, 1, 3);
3047*4882a593Smuzhiyun if (has_lighting)
3048*4882a593Smuzhiyun sd->lighting = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
3049*4882a593Smuzhiyun V4L2_CID_BACKLIGHT_COMPENSATION, 0, 2, 1, 1);
3050*4882a593Smuzhiyun if (has_hflip)
3051*4882a593Smuzhiyun v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
3052*4882a593Smuzhiyun V4L2_CID_HFLIP, 0, 1, 1, 0);
3053*4882a593Smuzhiyun
3054*4882a593Smuzhiyun if (hdl->error) {
3055*4882a593Smuzhiyun pr_err("Could not initialize controls\n");
3056*4882a593Smuzhiyun return hdl->error;
3057*4882a593Smuzhiyun }
3058*4882a593Smuzhiyun return 0;
3059*4882a593Smuzhiyun }
3060*4882a593Smuzhiyun
3061*4882a593Smuzhiyun /* sub-driver description */
3062*4882a593Smuzhiyun static const struct sd_desc sd_desc = {
3063*4882a593Smuzhiyun .name = MODULE_NAME,
3064*4882a593Smuzhiyun .config = sd_config,
3065*4882a593Smuzhiyun .init = sd_init,
3066*4882a593Smuzhiyun .init_controls = sd_init_controls,
3067*4882a593Smuzhiyun .start = sd_start,
3068*4882a593Smuzhiyun .stopN = sd_stopN,
3069*4882a593Smuzhiyun .stop0 = sd_stop0,
3070*4882a593Smuzhiyun .pkt_scan = sd_pkt_scan,
3071*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_INPUT)
3072*4882a593Smuzhiyun .dq_callback = cit_check_button,
3073*4882a593Smuzhiyun .other_input = 1,
3074*4882a593Smuzhiyun #endif
3075*4882a593Smuzhiyun };
3076*4882a593Smuzhiyun
3077*4882a593Smuzhiyun static const struct sd_desc sd_desc_isoc_nego = {
3078*4882a593Smuzhiyun .name = MODULE_NAME,
3079*4882a593Smuzhiyun .config = sd_config,
3080*4882a593Smuzhiyun .init = sd_init,
3081*4882a593Smuzhiyun .init_controls = sd_init_controls,
3082*4882a593Smuzhiyun .start = sd_start,
3083*4882a593Smuzhiyun .isoc_init = sd_isoc_init,
3084*4882a593Smuzhiyun .isoc_nego = sd_isoc_nego,
3085*4882a593Smuzhiyun .stopN = sd_stopN,
3086*4882a593Smuzhiyun .stop0 = sd_stop0,
3087*4882a593Smuzhiyun .pkt_scan = sd_pkt_scan,
3088*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_INPUT)
3089*4882a593Smuzhiyun .dq_callback = cit_check_button,
3090*4882a593Smuzhiyun .other_input = 1,
3091*4882a593Smuzhiyun #endif
3092*4882a593Smuzhiyun };
3093*4882a593Smuzhiyun
3094*4882a593Smuzhiyun /* -- module initialisation -- */
3095*4882a593Smuzhiyun static const struct usb_device_id device_table[] = {
3096*4882a593Smuzhiyun { USB_DEVICE_VER(0x0545, 0x8080, 0x0001, 0x0001), .driver_info = CIT_MODEL0 },
3097*4882a593Smuzhiyun { USB_DEVICE_VER(0x0545, 0x8080, 0x0002, 0x0002), .driver_info = CIT_MODEL1 },
3098*4882a593Smuzhiyun { USB_DEVICE_VER(0x0545, 0x8080, 0x030a, 0x030a), .driver_info = CIT_MODEL2 },
3099*4882a593Smuzhiyun { USB_DEVICE_VER(0x0545, 0x8080, 0x0301, 0x0301), .driver_info = CIT_MODEL3 },
3100*4882a593Smuzhiyun { USB_DEVICE_VER(0x0545, 0x8002, 0x030a, 0x030a), .driver_info = CIT_MODEL4 },
3101*4882a593Smuzhiyun { USB_DEVICE_VER(0x0545, 0x800c, 0x030a, 0x030a), .driver_info = CIT_MODEL2 },
3102*4882a593Smuzhiyun { USB_DEVICE_VER(0x0545, 0x800d, 0x030a, 0x030a), .driver_info = CIT_MODEL4 },
3103*4882a593Smuzhiyun {}
3104*4882a593Smuzhiyun };
3105*4882a593Smuzhiyun MODULE_DEVICE_TABLE(usb, device_table);
3106*4882a593Smuzhiyun
3107*4882a593Smuzhiyun /* -- device connect -- */
sd_probe(struct usb_interface * intf,const struct usb_device_id * id)3108*4882a593Smuzhiyun static int sd_probe(struct usb_interface *intf,
3109*4882a593Smuzhiyun const struct usb_device_id *id)
3110*4882a593Smuzhiyun {
3111*4882a593Smuzhiyun const struct sd_desc *desc = &sd_desc;
3112*4882a593Smuzhiyun
3113*4882a593Smuzhiyun switch (id->driver_info) {
3114*4882a593Smuzhiyun case CIT_MODEL0:
3115*4882a593Smuzhiyun case CIT_MODEL1:
3116*4882a593Smuzhiyun if (intf->cur_altsetting->desc.bInterfaceNumber != 2)
3117*4882a593Smuzhiyun return -ENODEV;
3118*4882a593Smuzhiyun break;
3119*4882a593Smuzhiyun case CIT_MODEL2:
3120*4882a593Smuzhiyun case CIT_MODEL4:
3121*4882a593Smuzhiyun if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
3122*4882a593Smuzhiyun return -ENODEV;
3123*4882a593Smuzhiyun break;
3124*4882a593Smuzhiyun case CIT_MODEL3:
3125*4882a593Smuzhiyun if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
3126*4882a593Smuzhiyun return -ENODEV;
3127*4882a593Smuzhiyun /* FIXME this likely applies to all model3 cams and probably
3128*4882a593Smuzhiyun to other models too. */
3129*4882a593Smuzhiyun if (ibm_netcam_pro)
3130*4882a593Smuzhiyun desc = &sd_desc_isoc_nego;
3131*4882a593Smuzhiyun break;
3132*4882a593Smuzhiyun }
3133*4882a593Smuzhiyun
3134*4882a593Smuzhiyun return gspca_dev_probe2(intf, id, desc, sizeof(struct sd), THIS_MODULE);
3135*4882a593Smuzhiyun }
3136*4882a593Smuzhiyun
3137*4882a593Smuzhiyun static struct usb_driver sd_driver = {
3138*4882a593Smuzhiyun .name = MODULE_NAME,
3139*4882a593Smuzhiyun .id_table = device_table,
3140*4882a593Smuzhiyun .probe = sd_probe,
3141*4882a593Smuzhiyun .disconnect = gspca_disconnect,
3142*4882a593Smuzhiyun #ifdef CONFIG_PM
3143*4882a593Smuzhiyun .suspend = gspca_suspend,
3144*4882a593Smuzhiyun .resume = gspca_resume,
3145*4882a593Smuzhiyun .reset_resume = gspca_resume,
3146*4882a593Smuzhiyun #endif
3147*4882a593Smuzhiyun };
3148*4882a593Smuzhiyun
3149*4882a593Smuzhiyun module_usb_driver(sd_driver);
3150