V4L/DVB (8356): gspca: 352x288 mode fix and source clean-up for Sonix bridges.
[deliverable/linux.git] / drivers / media / video / gspca / sonixj.c
1 /*
2 * Sonix sn9c102p sn9c105 sn9c120 (jpeg) library
3 * Copyright (C) 2005 Michel Xhaard mxhaard@magic.fr
4 *
5 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22 #define MODULE_NAME "sonixj"
23
24 #include "gspca.h"
25 #include "jpeg.h"
26
27 #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
28 static const char version[] = "2.1.7";
29
30 MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
31 MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver");
32 MODULE_LICENSE("GPL");
33
34 /* specific webcam descriptor */
35 struct sd {
36 struct gspca_dev gspca_dev; /* !! must be the first item */
37
38 int avg_lum;
39 unsigned int exposure;
40
41 unsigned short brightness;
42 unsigned char contrast;
43 unsigned char colors;
44 unsigned char autogain;
45
46 signed char ag_cnt;
47 #define AG_CNT_START 13
48
49 char qindex;
50 unsigned char bridge;
51 #define BRIDGE_SN9C102P 0
52 #define BRIDGE_SN9C105 1
53 #define BRIDGE_SN9C110 2
54 #define BRIDGE_SN9C120 3
55 #define BRIDGE_SN9C325 4
56 char sensor; /* Type of image sensor chip */
57 #define SENSOR_HV7131R 0
58 #define SENSOR_MI0360 1
59 #define SENSOR_MO4000 2
60 #define SENSOR_OV7648 3
61 #define SENSOR_OV7660 4
62 unsigned char i2c_base;
63 };
64
65 /* V4L2 controls supported by the driver */
66 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
67 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
68 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
69 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
70 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
71 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
72 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
73 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
74
75 static struct ctrl sd_ctrls[] = {
76 {
77 {
78 .id = V4L2_CID_BRIGHTNESS,
79 .type = V4L2_CTRL_TYPE_INTEGER,
80 .name = "Brightness",
81 .minimum = 0,
82 .maximum = 0xffff,
83 .step = 1,
84 #define BRIGHTNESS_DEF 0x7fff
85 .default_value = BRIGHTNESS_DEF,
86 },
87 .set = sd_setbrightness,
88 .get = sd_getbrightness,
89 },
90 {
91 {
92 .id = V4L2_CID_CONTRAST,
93 .type = V4L2_CTRL_TYPE_INTEGER,
94 .name = "Contrast",
95 .minimum = 0,
96 .maximum = 127,
97 .step = 1,
98 #define CONTRAST_DEF 63
99 .default_value = CONTRAST_DEF,
100 },
101 .set = sd_setcontrast,
102 .get = sd_getcontrast,
103 },
104 {
105 {
106 .id = V4L2_CID_SATURATION,
107 .type = V4L2_CTRL_TYPE_INTEGER,
108 .name = "Color",
109 .minimum = 0,
110 .maximum = 255,
111 .step = 1,
112 #define COLOR_DEF 127
113 .default_value = COLOR_DEF,
114 },
115 .set = sd_setcolors,
116 .get = sd_getcolors,
117 },
118 {
119 {
120 .id = V4L2_CID_AUTOGAIN,
121 .type = V4L2_CTRL_TYPE_BOOLEAN,
122 .name = "Auto Gain",
123 .minimum = 0,
124 .maximum = 1,
125 .step = 1,
126 #define AUTOGAIN_DEF 1
127 .default_value = AUTOGAIN_DEF,
128 },
129 .set = sd_setautogain,
130 .get = sd_getautogain,
131 },
132 };
133
134 static struct v4l2_pix_format vga_mode[] = {
135 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
136 .bytesperline = 160,
137 .sizeimage = 160 * 120 * 3 / 8 + 590,
138 .colorspace = V4L2_COLORSPACE_JPEG,
139 .priv = 2},
140 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
141 .bytesperline = 320,
142 .sizeimage = 320 * 240 * 3 / 8 + 590,
143 .colorspace = V4L2_COLORSPACE_JPEG,
144 .priv = 1},
145 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
146 .bytesperline = 640,
147 .sizeimage = 640 * 480 * 3 / 8 + 590,
148 .colorspace = V4L2_COLORSPACE_JPEG,
149 .priv = 0},
150 };
151
152 /*Data from sn9c102p+hv71331r */
153 static const __u8 sn_hv7131[] = {
154 0x00, 0x03, 0x64, 0x00, 0x1A, 0x20, 0x20, 0x20, 0xA1, 0x11,
155 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 reg9 */
156 0x02, 0x09, 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, /* 00 */
157 /* rega regb regc regd rege regf reg10 reg11 */
158 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41, 0x0a, 0x00, 0x00, 0x00,
159 /* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a reg1b */
160 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
161 /* reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23 */
162 };
163
164 static const __u8 sn_mi0360[] = {
165 0x00, 0x61, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0xb1, 0x5d,
166 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 reg9 */
167 0x07, 0x00, 0x00, 0x00, 0x00, 0x10, 0x03, 0x00,
168 /* rega regb regc regd rege regf reg10 reg11 */
169 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61, 0x06, 0x00, 0x00, 0x00,
170 /* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a reg1b */
171 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
172 /* reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23 */
173 };
174
175 static const __u8 sn_mo4000[] = {
176 0x12, 0x23, 0x60, 0x00, 0x1A, 0x00, 0x20, 0x18, 0x81,
177 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 */
178 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00,
179 /* reg9 rega regb regc regd rege regf reg10 reg11*/
180 0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40, 0x08, 0x00, 0x00,
181 /* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a*/
182 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x25, 0x39, 0x4b,
183 /* reg1b reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23*/
184 0x5c, 0x6b, 0x79, 0x87, 0x95, 0xa2, 0xaf, 0xbb, 0xc7,
185 0xd3, 0xdf, 0xea, 0xf5
186 };
187
188 static const __u8 sn_ov7648[] = {
189 0x00, 0x21, 0x62, 0x00, 0x1a, 0x20, 0x20, 0x20, 0xA1, 0x6E, 0x18, 0x65,
190 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, 0x00, 0x06, 0x06, 0x28, 0x1E, 0x82,
191 0x07, 0x00, 0x00, 0x00, 0x00, 0x00
192 };
193
194 static const __u8 sn_ov7660[] = {
195 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 */
196 0x00, 0x61, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x81,
197 /* reg9 rega regb regc regd rege regf reg10 reg11*/
198 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00,
199 /* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a*/
200 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20, 0x07, 0x00, 0x00,
201 /* reg1b reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23*/
202 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
203 };
204
205 /* sequence specific to the sensors - !! index = SENSOR_xxx */
206 static const __u8 *sn_tb[] = {
207 sn_hv7131,
208 sn_mi0360,
209 sn_mo4000,
210 sn_ov7648,
211 sn_ov7660
212 };
213
214 static const __u8 regsn20[] = {
215 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
216 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
217 };
218 static const __u8 regsn20_sn9c325[] = {
219 0x0a, 0x3a, 0x56, 0x6c, 0x7e, 0x8d, 0x9a, 0xa4,
220 0xaf, 0xbb, 0xc5, 0xcd, 0xd5, 0xde, 0xe8, 0xed, 0xf5
221 };
222
223 static const __u8 reg84[] = {
224 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, 0xe5, 0x0f,
225 0xe4, 0x0f, 0x38, 0x00, 0x3e, 0x00, 0xc3, 0x0f,
226 /* 0x00, 0x00, 0x00, 0x00, 0x00 */
227 0xf7, 0x0f, 0x0a, 0x00, 0x00
228 };
229 static const __u8 reg84_sn9c325[] = {
230 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, 0xe4, 0x0f,
231 0xd3, 0x0f, 0x4b, 0x00, 0x48, 0x00, 0xc0, 0x0f,
232 0xf8, 0x0f, 0x00, 0x00, 0x00
233 };
234
235 static const __u8 hv7131r_sensor_init[][8] = {
236 {0xC1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
237 {0xB1, 0x11, 0x34, 0x17, 0x7F, 0x00, 0x00, 0x10},
238 {0xD1, 0x11, 0x40, 0xFF, 0x7F, 0x7F, 0x7F, 0x10},
239 {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10},
240 {0xD1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
241 {0xD1, 0x11, 0x14, 0x01, 0xE2, 0x02, 0x82, 0x10},
242 {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
243
244 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
245 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
246 {0xC1, 0x11, 0x25, 0x00, 0x61, 0xA8, 0x00, 0x10},
247 {0xA1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10},
248 {0xC1, 0x11, 0x31, 0x20, 0x2E, 0x20, 0x00, 0x10},
249 {0xC1, 0x11, 0x25, 0x00, 0xC3, 0x50, 0x00, 0x10},
250 {0xA1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */
251 {0xC1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */
252
253 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
254 {0xA1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
255 {0xA1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
256 {0xA1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
257 {0xA1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10},
258
259 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
260 {0xA1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
261 {0xA1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
262 {0xA1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
263 {0xA1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10},
264 {}
265 };
266 static const __u8 mi0360_sensor_init[][8] = {
267 {0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
268 {0xB1, 0x5D, 0x0D, 0x00, 0x01, 0x00, 0x00, 0x10},
269 {0xB1, 0x5D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x10},
270 {0xD1, 0x5D, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
271 {0xD1, 0x5D, 0x03, 0x01, 0xE2, 0x02, 0x82, 0x10},
272 {0xD1, 0x5D, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10},
273 {0xB1, 0x5D, 0x0D, 0x00, 0x02, 0x00, 0x00, 0x10},
274 {0xD1, 0x5D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x10},
275 {0xD1, 0x5D, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x10},
276 {0xD1, 0x5D, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x10},
277 {0xD1, 0x5D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
278 {0xD1, 0x5D, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
279 {0xD1, 0x5D, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
280 {0xD1, 0x5D, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
281 {0xD1, 0x5D, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
282 {0xD1, 0x5D, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x10},
283 {0xD1, 0x5D, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x10},
284 {0xB1, 0x5D, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
285 {0xD1, 0x5D, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
286 {0xD1, 0x5D, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
287 {0xD1, 0x5D, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
288 {0xD1, 0x5D, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
289 {0xD1, 0x5D, 0x2F, 0xF7, 0xB0, 0x00, 0x04, 0x10},
290 {0xD1, 0x5D, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
291 {0xD1, 0x5D, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
292 {0xB1, 0x5D, 0x3D, 0x06, 0x8F, 0x00, 0x00, 0x10},
293 {0xD1, 0x5D, 0x40, 0x01, 0xE0, 0x00, 0xD1, 0x10},
294 {0xB1, 0x5D, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
295 {0xD1, 0x5D, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
296 {0xD1, 0x5D, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x10},
297 {0xD1, 0x5D, 0x5C, 0x00, 0x00, 0x00, 0x00, 0x10},
298 {0xD1, 0x5D, 0x5E, 0x00, 0x00, 0xA3, 0x1D, 0x10},
299 {0xB1, 0x5D, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
300
301 {0xB1, 0x5D, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
302 {0xB1, 0x5D, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
303 {0xB1, 0x5D, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
304 {0xD1, 0x5D, 0x2B, 0x00, 0xA0, 0x00, 0xB0, 0x10},
305 {0xD1, 0x5D, 0x2D, 0x00, 0xA0, 0x00, 0xA0, 0x10},
306
307 {0xB1, 0x5D, 0x0A, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */
308 {0xB1, 0x5D, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10},
309 {0xB1, 0x5D, 0x05, 0x00, 0x0A, 0x00, 0x00, 0x10},
310 {0xB1, 0x5D, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
311
312 {0xD1, 0x5D, 0x2B, 0x00, 0xB9, 0x00, 0xE3, 0x10},
313 {0xD1, 0x5D, 0x2D, 0x00, 0x5f, 0x00, 0xB9, 0x10}, /* 42 */
314 /* {0xB1, 0x5D, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */
315 /* {0xB1, 0x5D, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */
316 {0xB1, 0x5D, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
317 {0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
318 {}
319 };
320 static const __u8 mo4000_sensor_init[][8] = {
321 {0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10},
322 {0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10},
323 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
324 {0xa1, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
325 {0xa1, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
326 {0xa1, 0x21, 0x05, 0x04, 0x00, 0x00, 0x00, 0x10},
327 {0xa1, 0x21, 0x06, 0x80, 0x00, 0x00, 0x00, 0x10},
328 {0xa1, 0x21, 0x06, 0x81, 0x00, 0x00, 0x00, 0x10},
329 {0xa1, 0x21, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
330 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
331 {0xa1, 0x21, 0x11, 0x20, 0x00, 0x00, 0x00, 0x10},
332 {0xa1, 0x21, 0x11, 0x30, 0x00, 0x00, 0x00, 0x10},
333 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
334 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
335 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
336 {0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
337 {0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10},
338 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10},
339 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
340 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
341 {}
342 };
343 static const __u8 ov7660_sensor_init[][8] = {
344 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
345 {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
346 /* Outformat ?? rawRGB */
347 {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
348 /* {0xd1, 0x21, 0x00, 0x01, 0x74, 0x92, 0x00, 0x10},
349 * GAIN BLUE RED VREF */
350 {0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10},
351 /* GAIN BLUE RED VREF */
352 {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10},
353 /* COM 1 BAVE GEAVE AECHH */
354 {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */
355 {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */
356 /* {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xf8, 0x10},
357 * AECH CLKRC COM7 COM8 */
358 {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10},
359 /* AECH CLKRC COM7 COM8 */
360 {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */
361 {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10},
362 /* HSTART HSTOP VSTRT VSTOP */
363 {0xa1, 0x21, 0x1b, 0x02, 0x00, 0x00, 0x00, 0x10}, /* PSHFT */
364 {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */
365 {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10},
366 /* BOS GBOS GROS ROS (BGGR offset) */
367 /* {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10},
368 * AEW AEB VPT BBIAS */
369 {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10},
370 /* AEW AEB VPT BBIAS */
371 {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10},
372 /* GbBIAS RSVD EXHCH EXHCL */
373 {0xd1, 0x21, 0x2c, 0x80, 0x00, 0x00, 0x62, 0x10},
374 /* RBIAS ADVFL ASDVFH YAVE */
375 {0xc1, 0x21, 0x30, 0x08, 0x30, 0xb4, 0x00, 0x10},
376 /* HSYST HSYEN HREF */
377 {0xd1, 0x21, 0x33, 0x00, 0x07, 0x84, 0x00, 0x10}, /* reserved */
378 {0xd1, 0x21, 0x37, 0x0c, 0x02, 0x43, 0x00, 0x10},
379 /* ADC ACOM OFON TSLB */
380 {0xd1, 0x21, 0x3b, 0x02, 0x6c, 0x19, 0x0e, 0x10},
381 /* COM11 COM12 COM13 COM14 */
382 {0xd1, 0x21, 0x3f, 0x41, 0xc1, 0x22, 0x08, 0x10},
383 /* EDGE COM15 COM16 COM17 */
384 {0xd1, 0x21, 0x43, 0xf0, 0x10, 0x78, 0xa8, 0x10}, /* reserved */
385 {0xd1, 0x21, 0x47, 0x60, 0x80, 0x00, 0x00, 0x10}, /* reserved */
386 {0xd1, 0x21, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* reserved */
387 {0xd1, 0x21, 0x4f, 0x46, 0x36, 0x0f, 0x17, 0x10}, /* MTX 1 2 3 4 */
388 {0xd1, 0x21, 0x53, 0x7f, 0x96, 0x40, 0x40, 0x10}, /* MTX 5 6 7 8 */
389 {0xb1, 0x21, 0x57, 0x40, 0x0f, 0x00, 0x00, 0x10}, /* MTX9 MTXS */
390 {0xd1, 0x21, 0x59, 0xba, 0x9a, 0x22, 0xb9, 0x10}, /* reserved */
391 {0xd1, 0x21, 0x5d, 0x9b, 0x10, 0xf0, 0x05, 0x10}, /* reserved */
392 {0xa1, 0x21, 0x61, 0x60, 0x00, 0x00, 0x00, 0x10}, /* reserved */
393 {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10},
394 /* LCC1 LCC2 LCC3 LCC4 */
395 {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */
396 {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10},
397 {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10},
398 /* band gap reference [0..3] DBLV */
399 {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */
400 {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */
401 {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */
402 {0xd1, 0x21, 0x78, 0x34, 0x30, 0x2f, 0x2b, 0x10}, /* gamma curve */
403 {0xd1, 0x21, 0x7c, 0x03, 0x07, 0x17, 0x34, 0x10}, /* gamma curve */
404 {0xd1, 0x21, 0x80, 0x41, 0x4d, 0x58, 0x63, 0x10}, /* gamma curve */
405 {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */
406 {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
407 {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
408 {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10},
409 /****** (some exchanges in the win trace) ******/
410 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
411 /* bits[3..0]reserved */
412 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
413 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
414 /* VREF vertical frame ctrl */
415 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
416 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* 0x20 */
417 {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10},
418 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
419 {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10},
420 /* {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, */
421 /****** (some exchanges in the win trace) ******/
422 {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */
423 {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10},/* dummy line low */
424 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
425 {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10},
426 /* {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, */
427 /****** (some exchanges in the win trace) ******/
428 /**********startsensor KO if changed !!****/
429 {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10},
430 {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10},
431 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
432 {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10},
433 /* here may start the isoc exchanges */
434 {}
435 };
436 /* reg0x04 reg0x07 reg 0x10 */
437 /* expo = (COM1 & 0x02) | (AECHH & 0x2f <<10) [ (AECh << 2) */
438
439 static const __u8 ov7648_sensor_init[][8] = {
440 {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00},
441 {0xC1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00},
442 {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00},
443 {0xA1, 0x6E, 0x3F, 0x20, 0x00, 0x00, 0x00, 0x10},
444 {0xA1, 0x6E, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x10},
445 {0xA1, 0x6E, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x10},
446 {0xD1, 0x6E, 0x04, 0x02, 0xB1, 0x02, 0x39, 0x10},
447 {0xD1, 0x6E, 0x08, 0x00, 0x01, 0x00, 0x00, 0x10},
448 {0xD1, 0x6E, 0x0C, 0x02, 0x7F, 0x01, 0xE0, 0x10},
449 {0xD1, 0x6E, 0x12, 0x03, 0x02, 0x00, 0x03, 0x10},
450 {0xD1, 0x6E, 0x16, 0x85, 0x40, 0x4A, 0x40, 0x10},
451 {0xC1, 0x6E, 0x1A, 0x00, 0x80, 0x00, 0x00, 0x10},
452 {0xD1, 0x6E, 0x1D, 0x08, 0x03, 0x00, 0x00, 0x10},
453 {0xD1, 0x6E, 0x23, 0x00, 0xB0, 0x00, 0x94, 0x10},
454 {0xD1, 0x6E, 0x27, 0x58, 0x00, 0x00, 0x00, 0x10},
455 {0xD1, 0x6E, 0x2D, 0x14, 0x35, 0x61, 0x84, 0x10},
456 {0xD1, 0x6E, 0x31, 0xA2, 0xBD, 0xD8, 0xFF, 0x10},
457 {0xD1, 0x6E, 0x35, 0x06, 0x1E, 0x12, 0x02, 0x10},
458 {0xD1, 0x6E, 0x39, 0xAA, 0x53, 0x37, 0xD5, 0x10},
459 {0xA1, 0x6E, 0x3D, 0xF2, 0x00, 0x00, 0x00, 0x10},
460 {0xD1, 0x6E, 0x3E, 0x00, 0x00, 0x80, 0x03, 0x10},
461 {0xD1, 0x6E, 0x42, 0x03, 0x00, 0x00, 0x00, 0x10},
462 {0xC1, 0x6E, 0x46, 0x00, 0x80, 0x80, 0x00, 0x10},
463 {0xD1, 0x6E, 0x4B, 0x02, 0xEF, 0x08, 0xCD, 0x10},
464 {0xD1, 0x6E, 0x4F, 0x00, 0xD0, 0x00, 0xA0, 0x10},
465 {0xD1, 0x6E, 0x53, 0x01, 0xAA, 0x01, 0x40, 0x10},
466 {0xD1, 0x6E, 0x5A, 0x50, 0x04, 0x30, 0x03, 0x10},
467 {0xA1, 0x6E, 0x5E, 0x00, 0x00, 0x00, 0x00, 0x10},
468 {0xD1, 0x6E, 0x5F, 0x10, 0x40, 0xFF, 0x00, 0x10},
469 /* {0xD1, 0x6E, 0x63, 0x40, 0x40, 0x00, 0x00, 0x10},
470 {0xD1, 0x6E, 0x67, 0x00, 0x00, 0x00, 0x00, 0x10},
471 * This is currently setting a
472 * blue tint, and some things more , i leave it here for future test if
473 * somene is having problems with color on this sensor
474 {0xD1, 0x6E, 0x6B, 0x00, 0x00, 0x00, 0x00, 0x10},
475 {0xD1, 0x6E, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x10},
476 {0xC1, 0x6E, 0x73, 0x10, 0x80, 0xEB, 0x00, 0x10},
477 {0xA1, 0x6E, 0x1E, 0x03, 0x00, 0x00, 0x00, 0x10},
478 {0xA1, 0x6E, 0x15, 0x01, 0x00, 0x00, 0x00, 0x10},
479 {0xC1, 0x6E, 0x16, 0x40, 0x40, 0x40, 0x00, 0x10},
480 {0xA1, 0x6E, 0x1D, 0x08, 0x00, 0x00, 0x00, 0x10},
481 {0xA1, 0x6E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10},
482 {0xA1, 0x6E, 0x07, 0xB5, 0x00, 0x00, 0x00, 0x10},
483 {0xA1, 0x6E, 0x18, 0x6B, 0x00, 0x00, 0x00, 0x10},
484 {0xA1, 0x6E, 0x1D, 0x08, 0x00, 0x00, 0x00, 0x10},
485 {0xA1, 0x6E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10},
486 {0xA1, 0x6E, 0x07, 0xB8, 0x00, 0x00, 0x00, 0x10}, */
487 {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00},
488 {0xA1, 0x6E, 0x06, 0x03, 0x00, 0x00, 0x00, 0x10}, /* Bright... */
489 {0xA1, 0x6E, 0x07, 0x66, 0x00, 0x00, 0x00, 0x10}, /* B.. */
490 {0xC1, 0x6E, 0x1A, 0x03, 0x65, 0x90, 0x00, 0x10}, /* Bright/Witen....*/
491 /* {0xC1, 0x6E, 0x16, 0x45, 0x40, 0x60, 0x00, 0x10}, * Bright/Witene */
492 {}
493 };
494
495 static const __u8 qtable4[] = {
496 0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06, 0x06, 0x06, 0x08, 0x06,
497 0x06, 0x08, 0x0A, 0x11,
498 0x0A, 0x0A, 0x08, 0x08, 0x0A, 0x15, 0x0F, 0x0F, 0x0C, 0x11, 0x19, 0x15,
499 0x19, 0x19, 0x17, 0x15,
500 0x17, 0x17, 0x1B, 0x1D, 0x25, 0x21, 0x1B, 0x1D, 0x23, 0x1D, 0x17, 0x17,
501 0x21, 0x2E, 0x21, 0x23,
502 0x27, 0x29, 0x2C, 0x2C, 0x2C, 0x19, 0x1F, 0x30, 0x32, 0x2E, 0x29, 0x32,
503 0x25, 0x29, 0x2C, 0x29,
504 0x06, 0x08, 0x08, 0x0A, 0x08, 0x0A, 0x13, 0x0A, 0x0A, 0x13, 0x29, 0x1B,
505 0x17, 0x1B, 0x29, 0x29,
506 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
507 0x29, 0x29, 0x29, 0x29,
508 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
509 0x29, 0x29, 0x29, 0x29,
510 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
511 0x29, 0x29, 0x29, 0x29
512 };
513
514 /* read <len> bytes (len < sizeof gspca_dev->usb_buf) to gspca_dev->usb_buf */
515 static void reg_r(struct gspca_dev *gspca_dev,
516 __u16 value, int len)
517 {
518 usb_control_msg(gspca_dev->dev,
519 usb_rcvctrlpipe(gspca_dev->dev, 0),
520 0,
521 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
522 value, 0,
523 gspca_dev->usb_buf, len,
524 500);
525 }
526
527 static void reg_w(struct gspca_dev *gspca_dev,
528 __u16 value,
529 const __u8 *buffer,
530 int len)
531 {
532 if (len <= sizeof gspca_dev->usb_buf) {
533 memcpy(gspca_dev->usb_buf, buffer, len);
534 usb_control_msg(gspca_dev->dev,
535 usb_sndctrlpipe(gspca_dev->dev, 0),
536 0x08,
537 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
538 value, 0,
539 gspca_dev->usb_buf, len,
540 500);
541 } else {
542 __u8 *tmpbuf;
543
544 tmpbuf = kmalloc(len, GFP_KERNEL);
545 memcpy(tmpbuf, buffer, len);
546 usb_control_msg(gspca_dev->dev,
547 usb_sndctrlpipe(gspca_dev->dev, 0),
548 0x08,
549 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
550 value, 0,
551 tmpbuf, len,
552 500);
553 kfree(tmpbuf);
554 }
555 }
556
557 /* I2C write 2 bytes */
558 static void i2c_w2(struct gspca_dev *gspca_dev,
559 const __u8 *buffer)
560 {
561 struct sd *sd = (struct sd *) gspca_dev;
562 __u8 mode[8];
563
564 /* is i2c ready */
565 mode[0] = 0x81 | (2 << 4);
566 mode[1] = sd->i2c_base;
567 mode[2] = buffer[0];
568 mode[3] = buffer[1];
569 mode[4] = 0;
570 mode[5] = 0;
571 mode[6] = 0;
572 mode[7] = 0x10;
573 reg_w(gspca_dev, 0x08, mode, 8);
574 }
575
576 /* I2C write 8 bytes */
577 static void i2c_w8(struct gspca_dev *gspca_dev,
578 const __u8 *buffer)
579 {
580 reg_w(gspca_dev, 0x08, buffer, 8);
581 msleep(1);
582 }
583
584 /* read 5 bytes in gspca_dev->usb_buf */
585 static void i2c_r5(struct gspca_dev *gspca_dev, __u8 reg)
586 {
587 struct sd *sd = (struct sd *) gspca_dev;
588 __u8 mode[8];
589
590 mode[0] = 0x81 | 0x10;
591 mode[1] = sd->i2c_base;
592 mode[2] = reg;
593 mode[3] = 0;
594 mode[4] = 0;
595 mode[5] = 0;
596 mode[6] = 0;
597 mode[7] = 0x10;
598 i2c_w8(gspca_dev, mode);
599 mode[0] = 0x81 | (5 << 4) | 0x02;
600 mode[2] = 0;
601 i2c_w8(gspca_dev, mode);
602 reg_r(gspca_dev, 0x0a, 5);
603 }
604
605 static int probesensor(struct gspca_dev *gspca_dev)
606 {
607 struct sd *sd = (struct sd *) gspca_dev;
608 __u8 reg02;
609 static const __u8 datasend[] = { 2, 0 };
610 /* reg val1 val2 val3 val4 */
611
612 i2c_w2(gspca_dev, datasend);
613 /* should write 0xa1 0x11 0x02 0x00 0x00 0x00 0x00 the 0x10 is add by i2cw */
614 msleep(10);
615 reg02 = 0x66;
616 reg_w(gspca_dev, 0x02, &reg02, 1); /* Gpio on */
617 msleep(10);
618 i2c_r5(gspca_dev, 0); /* read sensor id */
619 if (gspca_dev->usb_buf[0] == 0x02
620 && gspca_dev->usb_buf[1] == 0x09
621 && gspca_dev->usb_buf[2] == 0x01
622 && gspca_dev->usb_buf[3] == 0x00
623 && gspca_dev->usb_buf[4] == 0x00) {
624 PDEBUG(D_PROBE, "Find Sensor sn9c102P HV7131R");
625 sd->sensor = SENSOR_HV7131R;
626 return SENSOR_HV7131R;
627 }
628 PDEBUG(D_PROBE, "Find Sensor %d %d %d",
629 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
630 gspca_dev->usb_buf[2]);
631 PDEBUG(D_PROBE, "Sensor sn9c102P Not found");
632 return -ENODEV;
633 }
634
635 static int configure_gpio(struct gspca_dev *gspca_dev,
636 const __u8 *sn9c1xx)
637 {
638 struct sd *sd = (struct sd *) gspca_dev;
639 __u8 data;
640 __u8 regF1;
641 const __u8 *reg9a;
642 static const __u8 reg9a_def[] =
643 {0x08, 0x40, 0x20, 0x10, 0x00, 0x04};
644 static const __u8 reg9a_sn9c120[] = /* from win trace */
645 {0x00, 0x40, 0x38, 0x30, 0x00, 0x20};
646 static const __u8 reg9a_sn9c325[] =
647 {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20};
648
649
650 regF1 = 0x00;
651 reg_w(gspca_dev, 0xf1, &regF1, 1);
652
653 reg_w(gspca_dev, 0x01, &sn9c1xx[0], 1);
654 /*fixme:jfm was [1] en v1*/
655
656 /* configure gpio */
657 reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
658 reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
659 reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 3);
660 switch (sd->bridge) {
661 case BRIDGE_SN9C325:
662 reg9a = reg9a_sn9c325;
663 break;
664 case BRIDGE_SN9C120:
665 reg9a = reg9a_sn9c120;
666 break;
667 default:
668 reg9a = reg9a_def;
669 break;
670 }
671 reg_w(gspca_dev, 0x9a, reg9a, 6);
672
673 data = 0x60; /*fixme:jfm 60 00 00 (3) */
674 reg_w(gspca_dev, 0xd4, &data, 1);
675
676 reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
677
678 switch (sd->bridge) {
679 case BRIDGE_SN9C120: /* from win trace */
680 data = 0x61;
681 reg_w(gspca_dev, 0x01, &data, 1);
682 data = 0x20;
683 reg_w(gspca_dev, 0x17, &data, 1);
684 data = 0x60;
685 reg_w(gspca_dev, 0x01, &data, 1);
686 break;
687 case BRIDGE_SN9C325:
688 data = 0x43;
689 reg_w(gspca_dev, 0x01, &data, 1);
690 data = 0xae;
691 reg_w(gspca_dev, 0x17, &data, 1);
692 data = 0x42;
693 reg_w(gspca_dev, 0x01, &data, 1);
694 break;
695 default:
696 data = 0x43;
697 reg_w(gspca_dev, 0x01, &data, 1);
698 data = 0x61;
699 reg_w(gspca_dev, 0x17, &data, 1);
700 data = 0x42;
701 reg_w(gspca_dev, 0x01, &data, 1);
702 }
703
704 if (sd->sensor == SENSOR_HV7131R) {
705 if (probesensor(gspca_dev) < 0)
706 return -ENODEV;
707 }
708 return 0;
709 }
710
711 static void hv7131R_InitSensor(struct gspca_dev *gspca_dev)
712 {
713 int i = 0;
714 static const __u8 SetSensorClk[] = /* 0x08 Mclk */
715 { 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 };
716
717 while (hv7131r_sensor_init[i][0]) {
718 i2c_w8(gspca_dev, hv7131r_sensor_init[i]);
719 i++;
720 }
721 i2c_w8(gspca_dev, SetSensorClk);
722 }
723
724 static void mi0360_InitSensor(struct gspca_dev *gspca_dev)
725 {
726 int i = 0;
727
728 while (mi0360_sensor_init[i][0]) {
729 i2c_w8(gspca_dev, mi0360_sensor_init[i]);
730 i++;
731 }
732 }
733
734 static void mo4000_InitSensor(struct gspca_dev *gspca_dev)
735 {
736 int i = 0;
737
738 while (mo4000_sensor_init[i][0]) {
739 i2c_w8(gspca_dev, mo4000_sensor_init[i]);
740 i++;
741 }
742 }
743
744 static void ov7648_InitSensor(struct gspca_dev *gspca_dev)
745 {
746 int i = 0;
747
748 while (ov7648_sensor_init[i][0]) {
749 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
750 i++;
751 }
752 }
753
754 static void ov7660_InitSensor(struct gspca_dev *gspca_dev)
755 {
756 int i = 0;
757
758 while (ov7660_sensor_init[i][0]) {
759 i2c_w8(gspca_dev, ov7660_sensor_init[i]);
760 i++;
761 }
762 }
763
764 /* this function is called at probe time */
765 static int sd_config(struct gspca_dev *gspca_dev,
766 const struct usb_device_id *id)
767 {
768 struct sd *sd = (struct sd *) gspca_dev;
769 struct cam *cam;
770 __u16 vendor;
771 __u16 product;
772
773 vendor = id->idVendor;
774 product = id->idProduct;
775 sd->sensor = -1;
776 switch (vendor) {
777 case 0x0458: /* Genius */
778 /* switch (product) {
779 case 0x7025: */
780 sd->bridge = BRIDGE_SN9C120;
781 sd->sensor = SENSOR_MI0360;
782 sd->i2c_base = 0x5d;
783 /* break;
784 } */
785 break;
786 case 0x045e:
787 /* switch (product) {
788 case 0x00f5:
789 case 0x00f7: */
790 sd->bridge = BRIDGE_SN9C105;
791 sd->sensor = SENSOR_OV7660;
792 sd->i2c_base = 0x21;
793 /* break;
794 } */
795 break;
796 case 0x0471: /* Philips */
797 /* switch (product) {
798 case 0x0327:
799 case 0x0328:
800 case 0x0330: */
801 sd->bridge = BRIDGE_SN9C105;
802 sd->sensor = SENSOR_MI0360;
803 sd->i2c_base = 0x5d;
804 /* break;
805 } */
806 break;
807 case 0x0c45: /* Sonix */
808 switch (product) {
809 case 0x6040:
810 sd->bridge = BRIDGE_SN9C102P;
811 sd->sensor = SENSOR_MI0360; /* from BW600.inf */
812 /* sd->sensor = SENSOR_HV7131R; * gspcav1 value */
813 sd->i2c_base = 0x11;
814 break;
815 /* case 0x607a: * from BW600.inf
816 sd->bridge = BRIDGE_SN9C102P;
817 sd->sensor = SENSOR_OV7648;
818 sd->i2c_base = 0x??;
819 break; */
820 case 0x607c:
821 sd->bridge = BRIDGE_SN9C102P;
822 sd->sensor = SENSOR_HV7131R;
823 sd->i2c_base = 0x11;
824 break;
825 /* case 0x607e: * from BW600.inf
826 sd->bridge = BRIDGE_SN9C102P;
827 sd->sensor = SENSOR_OV7630;
828 sd->i2c_base = 0x??;
829 break; */
830 case 0x60c0:
831 sd->bridge = BRIDGE_SN9C105;
832 sd->sensor = SENSOR_MI0360;
833 sd->i2c_base = 0x5d;
834 break;
835 /* case 0x60c8: * from BW600.inf
836 sd->bridge = BRIDGE_SN9C105;
837 sd->sensor = SENSOR_OM6801;
838 sd->i2c_base = 0x??;
839 break; */
840 /* case 0x60cc: * from BW600.inf
841 sd->bridge = BRIDGE_SN9C105;
842 sd->sensor = SENSOR_HV7131GP;
843 sd->i2c_base = 0x??;
844 break; */
845 case 0x60ec:
846 sd->bridge = BRIDGE_SN9C105;
847 sd->sensor = SENSOR_MO4000;
848 sd->i2c_base = 0x21;
849 break;
850 /* case 0x60ef: * from BW600.inf
851 sd->bridge = BRIDGE_SN9C105;
852 sd->sensor = SENSOR_ICM105C;
853 sd->i2c_base = 0x??;
854 break; */
855 /* case 0x60fa: * from BW600.inf
856 sd->bridge = BRIDGE_SN9C105;
857 sd->sensor = SENSOR_OV7648;
858 sd->i2c_base = 0x??;
859 break; */
860 case 0x60fb:
861 sd->bridge = BRIDGE_SN9C105;
862 sd->sensor = SENSOR_OV7660;
863 sd->i2c_base = 0x21;
864 break;
865 case 0x60fc:
866 sd->bridge = BRIDGE_SN9C105;
867 sd->sensor = SENSOR_HV7131R;
868 sd->i2c_base = 0x11;
869 break;
870 /* case 0x60fe: * from BW600.inf
871 sd->bridge = BRIDGE_SN9C105;
872 sd->sensor = SENSOR_OV7630;
873 sd->i2c_base = 0x??;
874 break; */
875 /* case 0x6108: * from BW600.inf
876 sd->bridge = BRIDGE_SN9C120;
877 sd->sensor = SENSOR_OM6801;
878 sd->i2c_base = 0x??;
879 break; */
880 /* case 0x6122: * from BW600.inf
881 sd->bridge = BRIDGE_SN9C110;
882 sd->sensor = SENSOR_ICM105C;
883 sd->i2c_base = 0x??;
884 break; */
885 case 0x612a:
886 /* sd->bridge = BRIDGE_SN9C110; * in BW600.inf */
887 sd->bridge = BRIDGE_SN9C325;
888 sd->sensor = SENSOR_OV7648;
889 sd->i2c_base = 0x21;
890 break;
891 /* case 0x6123: * from BW600.inf
892 sd->bridge = BRIDGE_SN9C110;
893 sd->sensor = SENSOR_SanyoCCD;
894 sd->i2c_base = 0x??;
895 break; */
896 case 0x612c:
897 sd->bridge = BRIDGE_SN9C110;
898 sd->sensor = SENSOR_MO4000;
899 sd->i2c_base = 0x21;
900 break;
901 /* case 0x612e: * from BW600.inf
902 sd->bridge = BRIDGE_SN9C110;
903 sd->sensor = SENSOR_OV7630;
904 sd->i2c_base = 0x??;
905 break; */
906 /* case 0x612f: * from BW600.inf
907 sd->bridge = BRIDGE_SN9C110;
908 sd->sensor = SENSOR_ICM105C;
909 sd->i2c_base = 0x??;
910 break; */
911 case 0x6130:
912 sd->bridge = BRIDGE_SN9C120;
913 sd->sensor = SENSOR_MI0360;
914 sd->i2c_base = 0x5d;
915 break;
916 case 0x6138:
917 sd->bridge = BRIDGE_SN9C120;
918 sd->sensor = SENSOR_MO4000;
919 sd->i2c_base = 0x21;
920 break;
921 /* case 0x613a: * from BW600.inf
922 sd->bridge = BRIDGE_SN9C120;
923 sd->sensor = SENSOR_OV7648;
924 sd->i2c_base = 0x??;
925 break; */
926 case 0x613b:
927 sd->bridge = BRIDGE_SN9C120;
928 sd->sensor = SENSOR_OV7660;
929 sd->i2c_base = 0x21;
930 break;
931 case 0x613c:
932 sd->bridge = BRIDGE_SN9C120;
933 sd->sensor = SENSOR_HV7131R;
934 sd->i2c_base = 0x11;
935 break;
936 /* case 0x613e: * from BW600.inf
937 sd->bridge = BRIDGE_SN9C120;
938 sd->sensor = SENSOR_OV7630;
939 sd->i2c_base = 0x??;
940 break; */
941 }
942 break;
943 }
944 if (sd->sensor < 0) {
945 PDEBUG(D_ERR, "Invalid vendor/product %04x:%04x",
946 vendor, product);
947 return -EINVAL;
948 }
949
950 cam = &gspca_dev->cam;
951 cam->dev_name = (char *) id->driver_info;
952 cam->epaddr = 0x01;
953 cam->cam_mode = vga_mode;
954 cam->nmodes = ARRAY_SIZE(vga_mode);
955
956 sd->qindex = 4; /* set the quantization table */
957 sd->brightness = BRIGHTNESS_DEF;
958 sd->contrast = CONTRAST_DEF;
959 sd->colors = COLOR_DEF;
960 sd->autogain = AUTOGAIN_DEF;
961 return 0;
962 }
963
964 /* this function is called at open time */
965 static int sd_open(struct gspca_dev *gspca_dev)
966 {
967 struct sd *sd = (struct sd *) gspca_dev;
968 /* const __u8 *sn9c1xx; */
969 __u8 regF1;
970 __u8 regGpio[] = { 0x29, 0x74 };
971
972 /* setup a selector by bridge */
973 regF1 = 0x01;
974 reg_w(gspca_dev, 0xf1, &regF1, 1);
975 reg_r(gspca_dev, 0x00, 1); /* -> regF1 = 0x00 */
976 regF1 = gspca_dev->usb_buf[0];
977 reg_w(gspca_dev, 0xf1, &regF1, 1);
978 reg_r(gspca_dev, 0x00, 1);
979 regF1 = gspca_dev->usb_buf[0];
980 switch (sd->bridge) {
981 case BRIDGE_SN9C102P:
982 if (regF1 != 0x11)
983 return -ENODEV;
984 reg_w(gspca_dev, 0x02, &regGpio[1], 1);
985 break;
986 case BRIDGE_SN9C105:
987 if (regF1 != 0x11)
988 return -ENODEV;
989 reg_w(gspca_dev, 0x02, regGpio, 2);
990 break;
991 case BRIDGE_SN9C110:
992 if (regF1 != 0x12)
993 return -ENODEV;
994 regGpio[1] = 0x62;
995 reg_w(gspca_dev, 0x02, &regGpio[1], 1);
996 break;
997 case BRIDGE_SN9C120:
998 if (regF1 != 0x12)
999 return -ENODEV;
1000 regGpio[1] = 0x70;
1001 reg_w(gspca_dev, 0x02, regGpio, 2);
1002 break;
1003 default:
1004 /* case BRIDGE_SN9C325: */
1005 if (regF1 != 0x12)
1006 return -ENODEV;
1007 regGpio[1] = 0x62;
1008 reg_w(gspca_dev, 0x02, &regGpio[1], 1);
1009 break;
1010 }
1011
1012 regF1 = 0x01;
1013 reg_w(gspca_dev, 0xf1, &regF1, 1);
1014
1015 return 0;
1016 }
1017
1018 static unsigned int setexposure(struct gspca_dev *gspca_dev,
1019 unsigned int expo)
1020 {
1021 struct sd *sd = (struct sd *) gspca_dev;
1022 static const __u8 doit[] = /* update sensor */
1023 { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
1024 static const __u8 sensorgo[] = /* sensor on */
1025 { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
1026 static const __u8 gainMo[] =
1027 { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
1028
1029 switch (sd->sensor) {
1030 case SENSOR_HV7131R: {
1031 __u8 Expodoit[] =
1032 { 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 };
1033
1034 Expodoit[3] = expo >> 16;
1035 Expodoit[4] = expo >> 8;
1036 Expodoit[5] = expo;
1037 i2c_w8(gspca_dev, Expodoit);
1038 break;
1039 }
1040 case SENSOR_MI0360: {
1041 __u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */
1042 { 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 };
1043
1044 if (expo > 0x0635)
1045 expo = 0x0635;
1046 else if (expo < 0x0001)
1047 expo = 0x0001;
1048 expoMi[3] = expo >> 8;
1049 expoMi[4] = expo;
1050 i2c_w8(gspca_dev, expoMi);
1051 i2c_w8(gspca_dev, doit);
1052 i2c_w8(gspca_dev, sensorgo);
1053 break;
1054 }
1055 case SENSOR_MO4000: {
1056 __u8 expoMof[] =
1057 { 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 };
1058 __u8 expoMo10[] =
1059 { 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 };
1060
1061 if (expo > 0x1fff)
1062 expo = 0x1fff;
1063 else if (expo < 0x0001)
1064 expo = 0x0001;
1065 expoMof[3] = (expo & 0x03fc) >> 2;
1066 i2c_w8(gspca_dev, expoMof);
1067 expoMo10[3] = ((expo & 0x1c00) >> 10)
1068 | ((expo & 0x0003) << 4);
1069 i2c_w8(gspca_dev, expoMo10);
1070 i2c_w8(gspca_dev, gainMo);
1071 PDEBUG(D_CONF, "set exposure %d",
1072 ((expoMo10[3] & 0x07) << 10)
1073 | (expoMof[3] << 2)
1074 | ((expoMo10[3] & 0x30) >> 4));
1075 break;
1076 }
1077 }
1078 return expo;
1079 }
1080
1081 static void setbrightness(struct gspca_dev *gspca_dev)
1082 {
1083 struct sd *sd = (struct sd *) gspca_dev;
1084 unsigned int expo;
1085 __u8 k2;
1086
1087 switch (sd->sensor) {
1088 case SENSOR_HV7131R:
1089 expo = sd->brightness << 4;
1090 if (expo > 0x002dc6c0)
1091 expo = 0x002dc6c0;
1092 else if (expo < 0x02a0)
1093 expo = 0x02a0;
1094 sd->exposure = setexposure(gspca_dev, expo);
1095 break;
1096 case SENSOR_MI0360:
1097 expo = sd->brightness >> 4;
1098 sd->exposure = setexposure(gspca_dev, expo);
1099 break;
1100 case SENSOR_MO4000:
1101 expo = sd->brightness >> 4;
1102 sd->exposure = setexposure(gspca_dev, expo);
1103 break;
1104 case SENSOR_OV7660:
1105 return; /*jfm??*/
1106 }
1107
1108 k2 = sd->brightness >> 10;
1109 reg_w(gspca_dev, 0x96, &k2, 1);
1110 }
1111
1112 static void setcontrast(struct gspca_dev *gspca_dev)
1113 {
1114 struct sd *sd = (struct sd *) gspca_dev;
1115 __u8 k2;
1116 __u8 contrast[] = { 0x00, 0x00, 0x28, 0x00, 0x07, 0x00 };
1117
1118 if (sd->sensor == SENSOR_OV7660)
1119 return; /*jfm??*/
1120 k2 = sd->contrast;
1121 contrast[2] = k2;
1122 contrast[0] = (k2 + 1) >> 1;
1123 contrast[4] = (k2 + 1) / 5;
1124 reg_w(gspca_dev, 0x84, contrast, 6);
1125 }
1126
1127 static void setcolors(struct gspca_dev *gspca_dev)
1128 {
1129 struct sd *sd = (struct sd *) gspca_dev;
1130 __u8 data;
1131 int colour;
1132
1133 colour = sd->colors - 128;
1134 if (colour > 0)
1135 data = (colour + 32) & 0x7f; /* blue */
1136 else
1137 data = (-colour + 32) & 0x7f; /* red */
1138 reg_w(gspca_dev, 0x05, &data, 1);
1139 }
1140
1141 /* -- start the camera -- */
1142 static void sd_start(struct gspca_dev *gspca_dev)
1143 {
1144 struct sd *sd = (struct sd *) gspca_dev;
1145 int i;
1146 __u8 data;
1147 __u8 reg1;
1148 __u8 reg17;
1149 const __u8 *sn9c1xx;
1150 int mode;
1151 static const __u8 DC29[] = { 0x6a, 0x50, 0x00, 0x00, 0x50, 0x3c };
1152 static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
1153 static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
1154 static const __u8 CA_sn9c120[] =
1155 { 0x14, 0xec, 0x0a, 0xf6 }; /* SN9C120 */
1156 static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
1157 static const __u8 CE_sn9c325[] =
1158 { 0x32, 0xdd, 0x32, 0xdd }; /* OV7648 - SN9C325 */
1159
1160 sn9c1xx = sn_tb[(int) sd->sensor];
1161 configure_gpio(gspca_dev, sn9c1xx);
1162
1163 /*fixme:jfm this sequence should appear at end of sd_start */
1164 /* with
1165 data = 0x44;
1166 reg_w(gspca_dev, 0x01, &data, 1); */
1167 reg_w(gspca_dev, 0x15, &sn9c1xx[0x15], 1);
1168 reg_w(gspca_dev, 0x16, &sn9c1xx[0x16], 1);
1169 reg_w(gspca_dev, 0x12, &sn9c1xx[0x12], 1);
1170 reg_w(gspca_dev, 0x13, &sn9c1xx[0x13], 1);
1171 reg_w(gspca_dev, 0x18, &sn9c1xx[0x18], 1);
1172 reg_w(gspca_dev, 0xd2, &DC29[0], 1);
1173 reg_w(gspca_dev, 0xd3, &DC29[1], 1);
1174 reg_w(gspca_dev, 0xc6, &DC29[2], 1);
1175 reg_w(gspca_dev, 0xc7, &DC29[3], 1);
1176 reg_w(gspca_dev, 0xc8, &DC29[4], 1);
1177 reg_w(gspca_dev, 0xc9, &DC29[5], 1);
1178 /*fixme:jfm end of ending sequence */
1179 reg_w(gspca_dev, 0x18, &sn9c1xx[0x18], 1);
1180 if (sd->bridge == BRIDGE_SN9C325)
1181 data = 0xae;
1182 else
1183 data = 0x60;
1184 reg_w(gspca_dev, 0x17, &data, 1);
1185 reg_w(gspca_dev, 0x05, &sn9c1xx[5], 1);
1186 reg_w(gspca_dev, 0x07, &sn9c1xx[7], 1);
1187 reg_w(gspca_dev, 0x06, &sn9c1xx[6], 1);
1188 reg_w(gspca_dev, 0x14, &sn9c1xx[0x14], 1);
1189 if (sd->bridge == BRIDGE_SN9C325) {
1190 reg_w(gspca_dev, 0x20, regsn20_sn9c325, 0x11);
1191 for (i = 0; i < 8; i++)
1192 reg_w(gspca_dev, 0x84, reg84_sn9c325, 0x15);
1193 data = 0x0a;
1194 reg_w(gspca_dev, 0x9a, &data, 1);
1195 data = 0x60;
1196 reg_w(gspca_dev, 0x99, &data, 1);
1197 } else {
1198 reg_w(gspca_dev, 0x20, regsn20, 0x11);
1199 for (i = 0; i < 8; i++)
1200 reg_w(gspca_dev, 0x84, reg84, 0x15);
1201 data = 0x08;
1202 reg_w(gspca_dev, 0x9a, &data, 1);
1203 data = 0x59;
1204 reg_w(gspca_dev, 0x99, &data, 1);
1205 }
1206
1207 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
1208 reg1 = 0x02;
1209 reg17 = 0x61;
1210 switch (sd->sensor) {
1211 case SENSOR_HV7131R:
1212 hv7131R_InitSensor(gspca_dev);
1213 if (mode)
1214 reg1 = 0x46; /* 320 clk 48Mhz */
1215 else
1216 reg1 = 0x06; /* 640 clk 24Mz */
1217 break;
1218 case SENSOR_MI0360:
1219 mi0360_InitSensor(gspca_dev);
1220 if (mode)
1221 reg1 = 0x46; /* 320 clk 48Mhz */
1222 else
1223 reg1 = 0x06; /* 640 clk 24Mz */
1224 break;
1225 case SENSOR_MO4000:
1226 mo4000_InitSensor(gspca_dev);
1227 if (mode) {
1228 /* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */
1229 reg1 = 0x06; /* clk 24Mz */
1230 } else {
1231 reg17 = 0x22; /* 640 MCKSIZE */
1232 reg1 = 0x06; /* 640 clk 24Mz */
1233 }
1234 break;
1235 case SENSOR_OV7648:
1236 reg17 = 0xa2;
1237 reg1 = 0x44;
1238 ov7648_InitSensor(gspca_dev);
1239 /* if (mode)
1240 ; * 320x2...
1241 else
1242 ; * 640x... */
1243 break;
1244 default:
1245 /* case SENSOR_OV7660: */
1246 ov7660_InitSensor(gspca_dev);
1247 if (mode) {
1248 /* reg17 = 0x21; * 320 */
1249 /* reg1 = 0x44; */
1250 reg1 = 0x46;
1251 } else {
1252 reg17 = 0xa2; /* 640 */
1253 reg1 = 0x40;
1254 }
1255 break;
1256 }
1257 reg_w(gspca_dev, 0xc0, C0, 6);
1258 switch (sd->bridge) {
1259 case BRIDGE_SN9C120: /*jfm ?? */
1260 reg_w(gspca_dev, 0xca, CA_sn9c120, 4);
1261 break;
1262 default:
1263 reg_w(gspca_dev, 0xca, CA, 4);
1264 break;
1265 }
1266 switch (sd->bridge) {
1267 case BRIDGE_SN9C120: /*jfm ?? */
1268 case BRIDGE_SN9C325:
1269 reg_w(gspca_dev, 0xce, CE_sn9c325, 4);
1270 break;
1271 default:
1272 reg_w(gspca_dev, 0xce, CE, 4);
1273 /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
1274 break;
1275 }
1276
1277 /* here change size mode 0 -> VGA; 1 -> CIF */
1278 data = 0x40 | sn9c1xx[0x18] | (mode << 4);
1279 reg_w(gspca_dev, 0x18, &data, 1);
1280
1281 reg_w(gspca_dev, 0x100, qtable4, 0x40);
1282 reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40);
1283
1284 data = sn9c1xx[0x18] | (mode << 4);
1285 reg_w(gspca_dev, 0x18, &data, 1);
1286
1287 reg_w(gspca_dev, 0x17, &reg17, 1);
1288 reg_w(gspca_dev, 0x01, &reg1, 1);
1289 setbrightness(gspca_dev);
1290 setcontrast(gspca_dev);
1291 }
1292
1293 static void sd_stopN(struct gspca_dev *gspca_dev)
1294 {
1295 struct sd *sd = (struct sd *) gspca_dev;
1296 static const __u8 stophv7131[] =
1297 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
1298 static const __u8 stopmi0360[] =
1299 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
1300 __u8 regF1;
1301 __u8 data;
1302 const __u8 *sn9c1xx;
1303
1304 data = 0x0b;
1305 switch (sd->sensor) {
1306 case SENSOR_HV7131R:
1307 i2c_w8(gspca_dev, stophv7131);
1308 data = 0x2b;
1309 break;
1310 case SENSOR_MI0360:
1311 i2c_w8(gspca_dev, stopmi0360);
1312 data = 0x29;
1313 break;
1314 case SENSOR_MO4000:
1315 break;
1316 case SENSOR_OV7648:
1317 data = 0x29;
1318 break;
1319 default:
1320 /* case SENSOR_OV7660: */
1321 break;
1322 }
1323 sn9c1xx = sn_tb[(int) sd->sensor];
1324 reg_w(gspca_dev, 0x01, &sn9c1xx[1], 1);
1325 reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 1);
1326 reg_w(gspca_dev, 0x01, &sn9c1xx[1], 1);
1327 reg_w(gspca_dev, 0x01, &data, 1);
1328 regF1 = 0x01;
1329 reg_w(gspca_dev, 0xf1, &regF1, 1);
1330 }
1331
1332 static void sd_stop0(struct gspca_dev *gspca_dev)
1333 {
1334 }
1335
1336 static void sd_close(struct gspca_dev *gspca_dev)
1337 {
1338 }
1339
1340 static void setautogain(struct gspca_dev *gspca_dev)
1341 {
1342 struct sd *sd = (struct sd *) gspca_dev;
1343 /* Thanks S., without your advice, autobright should not work :) */
1344 int delta;
1345 int expotimes = 0;
1346 __u8 luma_mean = 130;
1347 __u8 luma_delta = 20;
1348
1349 delta = sd->avg_lum;
1350 if (delta < luma_mean - luma_delta ||
1351 delta > luma_mean + luma_delta) {
1352 switch (sd->sensor) {
1353 case SENSOR_HV7131R:
1354 expotimes = sd->exposure >> 8;
1355 expotimes += (luma_mean - delta) >> 4;
1356 if (expotimes < 0)
1357 expotimes = 0;
1358 sd->exposure = setexposure(gspca_dev,
1359 (unsigned int) (expotimes << 8));
1360 break;
1361 case SENSOR_MO4000:
1362 case SENSOR_MI0360:
1363 expotimes = sd->exposure;
1364 expotimes += (luma_mean - delta) >> 6;
1365 if (expotimes < 0)
1366 expotimes = 0;
1367 sd->exposure = setexposure(gspca_dev,
1368 (unsigned int) expotimes);
1369 setcolors(gspca_dev);
1370 break;
1371 }
1372 }
1373 }
1374
1375 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1376 struct gspca_frame *frame, /* target */
1377 __u8 *data, /* isoc packet */
1378 int len) /* iso packet length */
1379 {
1380 struct sd *sd = (struct sd *) gspca_dev;
1381 int sof, avg_lum;
1382
1383 sof = len - 64;
1384 if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) {
1385
1386 /* end of frame */
1387 gspca_frame_add(gspca_dev, LAST_PACKET,
1388 frame, data, sof + 2);
1389 if (sd->ag_cnt < 0)
1390 return;
1391 if (--sd->ag_cnt >= 0)
1392 return;
1393 sd->ag_cnt = AG_CNT_START;
1394 /* w1 w2 w3 */
1395 /* w4 w5 w6 */
1396 /* w7 w8 */
1397 /* w4 */
1398 avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6;
1399 /* w6 */
1400 avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6;
1401 /* w2 */
1402 avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6;
1403 /* w8 */
1404 avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6;
1405 /* w5 */
1406 avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
1407 avg_lum >>= 4;
1408 sd->avg_lum = avg_lum;
1409 PDEBUG(D_PACK, "mean lum %d", avg_lum);
1410 setautogain(gspca_dev);
1411 return;
1412 }
1413 if (gspca_dev->last_packet_type == LAST_PACKET) {
1414
1415 /* put the JPEG 422 header */
1416 jpeg_put_header(gspca_dev, frame, sd->qindex, 0x21);
1417 }
1418 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1419 }
1420
1421 static unsigned int getexposure(struct gspca_dev *gspca_dev)
1422 {
1423 struct sd *sd = (struct sd *) gspca_dev;
1424 __u8 hexpo, mexpo, lexpo;
1425
1426 switch (sd->sensor) {
1427 case SENSOR_HV7131R:
1428 /* read sensor exposure */
1429 i2c_r5(gspca_dev, 0x25);
1430 return (gspca_dev->usb_buf[0] << 16)
1431 | (gspca_dev->usb_buf[1] << 8)
1432 | gspca_dev->usb_buf[2];
1433 case SENSOR_MI0360:
1434 /* read sensor exposure */
1435 i2c_r5(gspca_dev, 0x09);
1436 return (gspca_dev->usb_buf[0] << 8)
1437 | gspca_dev->usb_buf[1];
1438 case SENSOR_MO4000:
1439 i2c_r5(gspca_dev, 0x0e);
1440 hexpo = 0; /* gspca_dev->usb_buf[1] & 0x07; */
1441 mexpo = 0x40; /* gspca_dev->usb_buf[2] & 0xff; */
1442 lexpo = (gspca_dev->usb_buf[1] & 0x30) >> 4;
1443 PDEBUG(D_CONF, "exposure %d",
1444 (hexpo << 10) | (mexpo << 2) | lexpo);
1445 return (hexpo << 10) | (mexpo << 2) | lexpo;
1446 default:
1447 /* case SENSOR_OV7660: */
1448 /* read sensor exposure */
1449 i2c_r5(gspca_dev, 0x04);
1450 hexpo = gspca_dev->usb_buf[3] & 0x2f;
1451 lexpo = gspca_dev->usb_buf[0] & 0x02;
1452 i2c_r5(gspca_dev, 0x08);
1453 mexpo = gspca_dev->usb_buf[2];
1454 return (hexpo << 10) | (mexpo << 2) | lexpo;
1455 }
1456 }
1457
1458 static void getbrightness(struct gspca_dev *gspca_dev)
1459 {
1460 struct sd *sd = (struct sd *) gspca_dev;
1461
1462 /* hardcoded registers seem not readable */
1463 switch (sd->sensor) {
1464 case SENSOR_HV7131R:
1465 /* sd->brightness = 0x7fff; */
1466 sd->brightness = getexposure(gspca_dev) >> 4;
1467 break;
1468 case SENSOR_MI0360:
1469 sd->brightness = getexposure(gspca_dev) << 4;
1470 break;
1471 case SENSOR_MO4000:
1472 /* sd->brightness = 0x1fff; */
1473 sd->brightness = getexposure(gspca_dev) << 4;
1474 break;
1475 }
1476 }
1477
1478 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1479 {
1480 struct sd *sd = (struct sd *) gspca_dev;
1481
1482 sd->brightness = val;
1483 if (gspca_dev->streaming)
1484 setbrightness(gspca_dev);
1485 return 0;
1486 }
1487
1488 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1489 {
1490 struct sd *sd = (struct sd *) gspca_dev;
1491
1492 getbrightness(gspca_dev);
1493 *val = sd->brightness;
1494 return 0;
1495 }
1496
1497 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1498 {
1499 struct sd *sd = (struct sd *) gspca_dev;
1500
1501 sd->contrast = val;
1502 if (gspca_dev->streaming)
1503 setcontrast(gspca_dev);
1504 return 0;
1505 }
1506
1507 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1508 {
1509 struct sd *sd = (struct sd *) gspca_dev;
1510
1511 *val = sd->contrast;
1512 return 0;
1513 }
1514
1515 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1516 {
1517 struct sd *sd = (struct sd *) gspca_dev;
1518
1519 sd->colors = val;
1520 if (gspca_dev->streaming)
1521 setcolors(gspca_dev);
1522 return 0;
1523 }
1524
1525 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1526 {
1527 struct sd *sd = (struct sd *) gspca_dev;
1528
1529 *val = sd->colors;
1530 return 0;
1531 }
1532
1533 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1534 {
1535 struct sd *sd = (struct sd *) gspca_dev;
1536
1537 sd->autogain = val;
1538 if (val)
1539 sd->ag_cnt = AG_CNT_START;
1540 else
1541 sd->ag_cnt = -1;
1542 return 0;
1543 }
1544
1545 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1546 {
1547 struct sd *sd = (struct sd *) gspca_dev;
1548
1549 *val = sd->autogain;
1550 return 0;
1551 }
1552
1553 /* sub-driver description */
1554 static const struct sd_desc sd_desc = {
1555 .name = MODULE_NAME,
1556 .ctrls = sd_ctrls,
1557 .nctrls = ARRAY_SIZE(sd_ctrls),
1558 .config = sd_config,
1559 .open = sd_open,
1560 .start = sd_start,
1561 .stopN = sd_stopN,
1562 .stop0 = sd_stop0,
1563 .close = sd_close,
1564 .pkt_scan = sd_pkt_scan,
1565 };
1566
1567 /* -- module initialisation -- */
1568 #define DVNM(name) .driver_info = (kernel_ulong_t) name
1569 static const __devinitdata struct usb_device_id device_table[] = {
1570 #ifndef CONFIG_USB_SN9C102
1571 {USB_DEVICE(0x0458, 0x7025), DVNM("Genius Eye 311Q")},
1572 {USB_DEVICE(0x045e, 0x00f5), DVNM("MicroSoft VX3000")},
1573 {USB_DEVICE(0x045e, 0x00f7), DVNM("MicroSoft VX1000")},
1574 {USB_DEVICE(0x0471, 0x0327), DVNM("Philips SPC 600 NC")},
1575 {USB_DEVICE(0x0471, 0x0328), DVNM("Philips SPC 700 NC")},
1576 #endif
1577 {USB_DEVICE(0x0471, 0x0330), DVNM("Philips SPC 710NC")},
1578 {USB_DEVICE(0x0c45, 0x6040), DVNM("Speed NVC 350K")},
1579 {USB_DEVICE(0x0c45, 0x607c), DVNM("Sonix sn9c102p Hv7131R")},
1580 {USB_DEVICE(0x0c45, 0x60c0), DVNM("Sangha Sn535")},
1581 {USB_DEVICE(0x0c45, 0x60ec), DVNM("SN9C105+MO4000")},
1582 {USB_DEVICE(0x0c45, 0x60fb), DVNM("Surfer NoName")},
1583 {USB_DEVICE(0x0c45, 0x60fc), DVNM("LG-LIC300")},
1584 {USB_DEVICE(0x0c45, 0x612a), DVNM("Avant Camera")},
1585 {USB_DEVICE(0x0c45, 0x612c), DVNM("Typhoon Rasy Cam 1.3MPix")},
1586 #ifndef CONFIG_USB_SN9C102
1587 {USB_DEVICE(0x0c45, 0x6130), DVNM("Sonix Pccam")},
1588 {USB_DEVICE(0x0c45, 0x6138), DVNM("Sn9c120 Mo4000")},
1589 {USB_DEVICE(0x0c45, 0x613b), DVNM("Surfer SN-206")},
1590 {USB_DEVICE(0x0c45, 0x613c), DVNM("Sonix Pccam168")},
1591 #endif
1592 {}
1593 };
1594 MODULE_DEVICE_TABLE(usb, device_table);
1595
1596 /* -- device connect -- */
1597 static int sd_probe(struct usb_interface *intf,
1598 const struct usb_device_id *id)
1599 {
1600 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1601 THIS_MODULE);
1602 }
1603
1604 static struct usb_driver sd_driver = {
1605 .name = MODULE_NAME,
1606 .id_table = device_table,
1607 .probe = sd_probe,
1608 .disconnect = gspca_disconnect,
1609 };
1610
1611 /* -- module insert / remove -- */
1612 static int __init sd_mod_init(void)
1613 {
1614 if (usb_register(&sd_driver) < 0)
1615 return -1;
1616 info("v%s registered", version);
1617 return 0;
1618 }
1619 static void __exit sd_mod_exit(void)
1620 {
1621 usb_deregister(&sd_driver);
1622 info("deregistered");
1623 }
1624
1625 module_init(sd_mod_init);
1626 module_exit(sd_mod_exit);
This page took 0.078038 seconds and 5 git commands to generate.