1 /*
2  * SPCA500 chip based cameras initialization data
3  *
4  * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  *
20  */
21 
22 #define MODULE_NAME "spca500"
23 
24 #include "gspca.h"
25 #include "jpeg.h"
26 
27 MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
28 MODULE_DESCRIPTION("GSPCA/SPCA500 USB Camera Driver");
29 MODULE_LICENSE("GPL");
30 
31 /* specific webcam descriptor */
32 struct sd {
33 	struct gspca_dev gspca_dev;		/* !! must be the first item */
34 
35 	unsigned char brightness;
36 	unsigned char contrast;
37 	unsigned char colors;
38 	u8 quality;
39 #define QUALITY_MIN 70
40 #define QUALITY_MAX 95
41 #define QUALITY_DEF 85
42 
43 	char subtype;
44 #define AgfaCl20 0
45 #define AiptekPocketDV 1
46 #define BenqDC1016 2
47 #define CreativePCCam300 3
48 #define DLinkDSC350 4
49 #define Gsmartmini 5
50 #define IntelPocketPCCamera 6
51 #define KodakEZ200 7
52 #define LogitechClickSmart310 8
53 #define LogitechClickSmart510 9
54 #define LogitechTraveler 10
55 #define MustekGsmart300 11
56 #define Optimedia 12
57 #define PalmPixDC85 13
58 #define ToptroIndus 14
59 
60 	u8 jpeg_hdr[JPEG_HDR_SZ];
61 };
62 
63 /* V4L2 controls supported by the driver */
64 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
65 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
66 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
67 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
68 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
69 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
70 
71 static const struct ctrl sd_ctrls[] = {
72 	{
73 	    {
74 		.id      = V4L2_CID_BRIGHTNESS,
75 		.type    = V4L2_CTRL_TYPE_INTEGER,
76 		.name    = "Brightness",
77 		.minimum = 0,
78 		.maximum = 255,
79 		.step    = 1,
80 #define BRIGHTNESS_DEF 127
81 		.default_value = BRIGHTNESS_DEF,
82 	    },
83 	    .set = sd_setbrightness,
84 	    .get = sd_getbrightness,
85 	},
86 	{
87 	    {
88 		.id      = V4L2_CID_CONTRAST,
89 		.type    = V4L2_CTRL_TYPE_INTEGER,
90 		.name    = "Contrast",
91 		.minimum = 0,
92 		.maximum = 63,
93 		.step    = 1,
94 #define CONTRAST_DEF 31
95 		.default_value = CONTRAST_DEF,
96 	    },
97 	    .set = sd_setcontrast,
98 	    .get = sd_getcontrast,
99 	},
100 	{
101 	    {
102 		.id      = V4L2_CID_SATURATION,
103 		.type    = V4L2_CTRL_TYPE_INTEGER,
104 		.name    = "Color",
105 		.minimum = 0,
106 		.maximum = 63,
107 		.step    = 1,
108 #define COLOR_DEF 31
109 		.default_value = COLOR_DEF,
110 	    },
111 	    .set = sd_setcolors,
112 	    .get = sd_getcolors,
113 	},
114 };
115 
116 static const struct v4l2_pix_format vga_mode[] = {
117 	{320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
118 		.bytesperline = 320,
119 		.sizeimage = 320 * 240 * 3 / 8 + 590,
120 		.colorspace = V4L2_COLORSPACE_JPEG,
121 		.priv = 1},
122 	{640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
123 		.bytesperline = 640,
124 		.sizeimage = 640 * 480 * 3 / 8 + 590,
125 		.colorspace = V4L2_COLORSPACE_JPEG,
126 		.priv = 0},
127 };
128 
129 static const struct v4l2_pix_format sif_mode[] = {
130 	{176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
131 		.bytesperline = 176,
132 		.sizeimage = 176 * 144 * 3 / 8 + 590,
133 		.colorspace = V4L2_COLORSPACE_JPEG,
134 		.priv = 1},
135 	{352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
136 		.bytesperline = 352,
137 		.sizeimage = 352 * 288 * 3 / 8 + 590,
138 		.colorspace = V4L2_COLORSPACE_JPEG,
139 		.priv = 0},
140 };
141 
142 /* Frame packet header offsets for the spca500 */
143 #define SPCA500_OFFSET_PADDINGLB 2
144 #define SPCA500_OFFSET_PADDINGHB 3
145 #define SPCA500_OFFSET_MODE      4
146 #define SPCA500_OFFSET_IMGWIDTH  5
147 #define SPCA500_OFFSET_IMGHEIGHT 6
148 #define SPCA500_OFFSET_IMGMODE   7
149 #define SPCA500_OFFSET_QTBLINDEX 8
150 #define SPCA500_OFFSET_FRAMSEQ   9
151 #define SPCA500_OFFSET_CDSPINFO  10
152 #define SPCA500_OFFSET_GPIO      11
153 #define SPCA500_OFFSET_AUGPIO    12
154 #define SPCA500_OFFSET_DATA      16
155 
156 
157 static const __u16 spca500_visual_defaults[][3] = {
158 	{0x00, 0x0003, 0x816b},	/* SSI not active sync with vsync,
159 				 * hue (H byte) = 0,
160 				 * saturation/hue enable,
161 				 * brightness/contrast enable.
162 				 */
163 	{0x00, 0x0000, 0x8167},	/* brightness = 0 */
164 	{0x00, 0x0020, 0x8168},	/* contrast = 0 */
165 	{0x00, 0x0003, 0x816b},	/* SSI not active sync with vsync,
166 				 * hue (H byte) = 0, saturation/hue enable,
167 				 * brightness/contrast enable.
168 				 * was 0x0003, now 0x0000.
169 				 */
170 	{0x00, 0x0000, 0x816a},	/* hue (L byte) = 0 */
171 	{0x00, 0x0020, 0x8169},	/* saturation = 0x20 */
172 	{0x00, 0x0050, 0x8157},	/* edge gain high threshold */
173 	{0x00, 0x0030, 0x8158},	/* edge gain low threshold */
174 	{0x00, 0x0028, 0x8159},	/* edge bandwidth high threshold */
175 	{0x00, 0x000a, 0x815a},	/* edge bandwidth low threshold */
176 	{0x00, 0x0001, 0x8202},	/* clock rate compensation = 1/25 sec/frame */
177 	{0x0c, 0x0004, 0x0000},
178 	/* set interface */
179 	{}
180 };
181 static const __u16 Clicksmart510_defaults[][3] = {
182 	{0x00, 0x00, 0x8211},
183 	{0x00, 0x01, 0x82c0},
184 	{0x00, 0x10, 0x82cb},
185 	{0x00, 0x0f, 0x800d},
186 	{0x00, 0x82, 0x8225},
187 	{0x00, 0x21, 0x8228},
188 	{0x00, 0x00, 0x8203},
189 	{0x00, 0x00, 0x8204},
190 	{0x00, 0x08, 0x8205},
191 	{0x00, 0xf8, 0x8206},
192 	{0x00, 0x28, 0x8207},
193 	{0x00, 0xa0, 0x8208},
194 	{0x00, 0x08, 0x824a},
195 	{0x00, 0x08, 0x8214},
196 	{0x00, 0x80, 0x82c1},
197 	{0x00, 0x00, 0x82c2},
198 	{0x00, 0x00, 0x82ca},
199 	{0x00, 0x80, 0x82c1},
200 	{0x00, 0x04, 0x82c2},
201 	{0x00, 0x00, 0x82ca},
202 	{0x00, 0xfc, 0x8100},
203 	{0x00, 0xfc, 0x8105},
204 	{0x00, 0x30, 0x8101},
205 	{0x00, 0x00, 0x8102},
206 	{0x00, 0x00, 0x8103},
207 	{0x00, 0x66, 0x8107},
208 	{0x00, 0x00, 0x816b},
209 	{0x00, 0x00, 0x8155},
210 	{0x00, 0x01, 0x8156},
211 	{0x00, 0x60, 0x8157},
212 	{0x00, 0x40, 0x8158},
213 	{0x00, 0x0a, 0x8159},
214 	{0x00, 0x06, 0x815a},
215 	{0x00, 0x00, 0x813f},
216 	{0x00, 0x00, 0x8200},
217 	{0x00, 0x19, 0x8201},
218 	{0x00, 0x00, 0x82c1},
219 	{0x00, 0xa0, 0x82c2},
220 	{0x00, 0x00, 0x82ca},
221 	{0x00, 0x00, 0x8117},
222 	{0x00, 0x00, 0x8118},
223 	{0x00, 0x65, 0x8119},
224 	{0x00, 0x00, 0x811a},
225 	{0x00, 0x00, 0x811b},
226 	{0x00, 0x55, 0x811c},
227 	{0x00, 0x65, 0x811d},
228 	{0x00, 0x55, 0x811e},
229 	{0x00, 0x16, 0x811f},
230 	{0x00, 0x19, 0x8120},
231 	{0x00, 0x80, 0x8103},
232 	{0x00, 0x83, 0x816b},
233 	{0x00, 0x25, 0x8168},
234 	{0x00, 0x01, 0x820f},
235 	{0x00, 0xff, 0x8115},
236 	{0x00, 0x48, 0x8116},
237 	{0x00, 0x50, 0x8151},
238 	{0x00, 0x40, 0x8152},
239 	{0x00, 0x78, 0x8153},
240 	{0x00, 0x40, 0x8154},
241 	{0x00, 0x00, 0x8167},
242 	{0x00, 0x20, 0x8168},
243 	{0x00, 0x00, 0x816a},
244 	{0x00, 0x03, 0x816b},
245 	{0x00, 0x20, 0x8169},
246 	{0x00, 0x60, 0x8157},
247 	{0x00, 0x00, 0x8190},
248 	{0x00, 0x00, 0x81a1},
249 	{0x00, 0x00, 0x81b2},
250 	{0x00, 0x27, 0x8191},
251 	{0x00, 0x27, 0x81a2},
252 	{0x00, 0x27, 0x81b3},
253 	{0x00, 0x4b, 0x8192},
254 	{0x00, 0x4b, 0x81a3},
255 	{0x00, 0x4b, 0x81b4},
256 	{0x00, 0x66, 0x8193},
257 	{0x00, 0x66, 0x81a4},
258 	{0x00, 0x66, 0x81b5},
259 	{0x00, 0x79, 0x8194},
260 	{0x00, 0x79, 0x81a5},
261 	{0x00, 0x79, 0x81b6},
262 	{0x00, 0x8a, 0x8195},
263 	{0x00, 0x8a, 0x81a6},
264 	{0x00, 0x8a, 0x81b7},
265 	{0x00, 0x9b, 0x8196},
266 	{0x00, 0x9b, 0x81a7},
267 	{0x00, 0x9b, 0x81b8},
268 	{0x00, 0xa6, 0x8197},
269 	{0x00, 0xa6, 0x81a8},
270 	{0x00, 0xa6, 0x81b9},
271 	{0x00, 0xb2, 0x8198},
272 	{0x00, 0xb2, 0x81a9},
273 	{0x00, 0xb2, 0x81ba},
274 	{0x00, 0xbe, 0x8199},
275 	{0x00, 0xbe, 0x81aa},
276 	{0x00, 0xbe, 0x81bb},
277 	{0x00, 0xc8, 0x819a},
278 	{0x00, 0xc8, 0x81ab},
279 	{0x00, 0xc8, 0x81bc},
280 	{0x00, 0xd2, 0x819b},
281 	{0x00, 0xd2, 0x81ac},
282 	{0x00, 0xd2, 0x81bd},
283 	{0x00, 0xdb, 0x819c},
284 	{0x00, 0xdb, 0x81ad},
285 	{0x00, 0xdb, 0x81be},
286 	{0x00, 0xe4, 0x819d},
287 	{0x00, 0xe4, 0x81ae},
288 	{0x00, 0xe4, 0x81bf},
289 	{0x00, 0xed, 0x819e},
290 	{0x00, 0xed, 0x81af},
291 	{0x00, 0xed, 0x81c0},
292 	{0x00, 0xf7, 0x819f},
293 	{0x00, 0xf7, 0x81b0},
294 	{0x00, 0xf7, 0x81c1},
295 	{0x00, 0xff, 0x81a0},
296 	{0x00, 0xff, 0x81b1},
297 	{0x00, 0xff, 0x81c2},
298 	{0x00, 0x03, 0x8156},
299 	{0x00, 0x00, 0x8211},
300 	{0x00, 0x20, 0x8168},
301 	{0x00, 0x01, 0x8202},
302 	{0x00, 0x30, 0x8101},
303 	{0x00, 0x00, 0x8111},
304 	{0x00, 0x00, 0x8112},
305 	{0x00, 0x00, 0x8113},
306 	{0x00, 0x00, 0x8114},
307 	{}
308 };
309 
310 static const __u8 qtable_creative_pccam[2][64] = {
311 	{				/* Q-table Y-components */
312 	 0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12,
313 	 0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11,
314 	 0x04, 0x04, 0x05, 0x07, 0x0c, 0x11, 0x15, 0x11,
315 	 0x04, 0x05, 0x07, 0x09, 0x0f, 0x1a, 0x18, 0x13,
316 	 0x05, 0x07, 0x0b, 0x11, 0x14, 0x21, 0x1f, 0x17,
317 	 0x07, 0x0b, 0x11, 0x13, 0x18, 0x1f, 0x22, 0x1c,
318 	 0x0f, 0x13, 0x17, 0x1a, 0x1f, 0x24, 0x24, 0x1e,
319 	 0x16, 0x1c, 0x1d, 0x1d, 0x22, 0x1e, 0x1f, 0x1e},
320 	{				/* Q-table C-components */
321 	 0x05, 0x05, 0x07, 0x0e, 0x1e, 0x1e, 0x1e, 0x1e,
322 	 0x05, 0x06, 0x08, 0x14, 0x1e, 0x1e, 0x1e, 0x1e,
323 	 0x07, 0x08, 0x11, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
324 	 0x0e, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
325 	 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
326 	 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
327 	 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
328 	 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e}
329 };
330 
331 static const __u8 qtable_kodak_ez200[2][64] = {
332 	{				/* Q-table Y-components */
333 	 0x02, 0x01, 0x01, 0x02, 0x02, 0x04, 0x05, 0x06,
334 	 0x01, 0x01, 0x01, 0x02, 0x03, 0x06, 0x06, 0x06,
335 	 0x01, 0x01, 0x02, 0x02, 0x04, 0x06, 0x07, 0x06,
336 	 0x01, 0x02, 0x02, 0x03, 0x05, 0x09, 0x08, 0x06,
337 	 0x02, 0x02, 0x04, 0x06, 0x07, 0x0b, 0x0a, 0x08,
338 	 0x02, 0x04, 0x06, 0x06, 0x08, 0x0a, 0x0b, 0x09,
339 	 0x05, 0x06, 0x08, 0x09, 0x0a, 0x0c, 0x0c, 0x0a,
340 	 0x07, 0x09, 0x0a, 0x0a, 0x0b, 0x0a, 0x0a, 0x0a},
341 	{				/* Q-table C-components */
342 	 0x02, 0x02, 0x02, 0x05, 0x0a, 0x0a, 0x0a, 0x0a,
343 	 0x02, 0x02, 0x03, 0x07, 0x0a, 0x0a, 0x0a, 0x0a,
344 	 0x02, 0x03, 0x06, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
345 	 0x05, 0x07, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
346 	 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
347 	 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
348 	 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
349 	 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a}
350 };
351 
352 static const __u8 qtable_pocketdv[2][64] = {
353 	{		/* Q-table Y-components start registers 0x8800 */
354 	 0x06, 0x04, 0x04, 0x06, 0x0a, 0x10, 0x14, 0x18,
355 	 0x05, 0x05, 0x06, 0x08, 0x0a, 0x17, 0x18, 0x16,
356 	 0x06, 0x05, 0x06, 0x0a, 0x10, 0x17, 0x1c, 0x16,
357 	 0x06, 0x07, 0x09, 0x0c, 0x14, 0x23, 0x20, 0x19,
358 	 0x07, 0x09, 0x0f, 0x16, 0x1b, 0x2c, 0x29, 0x1f,
359 	 0x0a, 0x0e, 0x16, 0x1a, 0x20, 0x2a, 0x2d, 0x25,
360 	 0x14, 0x1a, 0x1f, 0x23, 0x29, 0x30, 0x30, 0x28,
361 	 0x1d, 0x25, 0x26, 0x27, 0x2d, 0x28, 0x29, 0x28,
362 	 },
363 	{		/* Q-table C-components start registers 0x8840 */
364 	 0x07, 0x07, 0x0a, 0x13, 0x28, 0x28, 0x28, 0x28,
365 	 0x07, 0x08, 0x0a, 0x1a, 0x28, 0x28, 0x28, 0x28,
366 	 0x0a, 0x0a, 0x16, 0x28, 0x28, 0x28, 0x28, 0x28,
367 	 0x13, 0x1a, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
368 	 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
369 	 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
370 	 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
371 	 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28}
372 };
373 
374 /* read 'len' bytes to gspca_dev->usb_buf */
reg_r(struct gspca_dev * gspca_dev,__u16 index,__u16 length)375 static void reg_r(struct gspca_dev *gspca_dev,
376 		  __u16 index,
377 		  __u16 length)
378 {
379 	usb_control_msg(gspca_dev->dev,
380 			usb_rcvctrlpipe(gspca_dev->dev, 0),
381 			0,
382 			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
383 			0,		/* value */
384 			index, gspca_dev->usb_buf, length, 500);
385 }
386 
reg_w(struct gspca_dev * gspca_dev,__u16 req,__u16 index,__u16 value)387 static int reg_w(struct gspca_dev *gspca_dev,
388 		     __u16 req, __u16 index, __u16 value)
389 {
390 	int ret;
391 
392 	PDEBUG(D_USBO, "reg write: [0x%02x] = 0x%02x", index, value);
393 	ret = usb_control_msg(gspca_dev->dev,
394 			usb_sndctrlpipe(gspca_dev->dev, 0),
395 			req,
396 			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
397 			value, index, NULL, 0, 500);
398 	if (ret < 0)
399 		err("reg write: error %d", ret);
400 	return ret;
401 }
402 
403 /* returns: negative is error, pos or zero is data */
reg_r_12(struct gspca_dev * gspca_dev,__u16 req,__u16 index,__u16 length)404 static int reg_r_12(struct gspca_dev *gspca_dev,
405 			__u16 req,	/* bRequest */
406 			__u16 index,	/* wIndex */
407 			__u16 length)	/* wLength (1 or 2 only) */
408 {
409 	int ret;
410 
411 	gspca_dev->usb_buf[1] = 0;
412 	ret = usb_control_msg(gspca_dev->dev,
413 			usb_rcvctrlpipe(gspca_dev->dev, 0),
414 			req,
415 			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
416 			0,		/* value */
417 			index,
418 			gspca_dev->usb_buf, length,
419 			500);		/* timeout */
420 	if (ret < 0) {
421 		err("reg_r_12 err %d", ret);
422 		return ret;
423 	}
424 	return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0];
425 }
426 
427 /*
428  * Simple function to wait for a given 8-bit value to be returned from
429  * a reg_read call.
430  * Returns: negative is error or timeout, zero is success.
431  */
reg_r_wait(struct gspca_dev * gspca_dev,__u16 reg,__u16 index,__u16 value)432 static int reg_r_wait(struct gspca_dev *gspca_dev,
433 			__u16 reg, __u16 index, __u16 value)
434 {
435 	int ret, cnt = 20;
436 
437 	while (--cnt > 0) {
438 		ret = reg_r_12(gspca_dev, reg, index, 1);
439 		if (ret == value)
440 			return 0;
441 		msleep(50);
442 	}
443 	return -EIO;
444 }
445 
write_vector(struct gspca_dev * gspca_dev,const __u16 data[][3])446 static int write_vector(struct gspca_dev *gspca_dev,
447 			const __u16 data[][3])
448 {
449 	int ret, i = 0;
450 
451 	while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) {
452 		ret = reg_w(gspca_dev, data[i][0], data[i][2], data[i][1]);
453 		if (ret < 0)
454 			return ret;
455 		i++;
456 	}
457 	return 0;
458 }
459 
spca50x_setup_qtable(struct gspca_dev * gspca_dev,unsigned int request,unsigned int ybase,unsigned int cbase,const __u8 qtable[2][64])460 static int spca50x_setup_qtable(struct gspca_dev *gspca_dev,
461 				unsigned int request,
462 				unsigned int ybase,
463 				unsigned int cbase,
464 				const __u8 qtable[2][64])
465 {
466 	int i, err;
467 
468 	/* loop over y components */
469 	for (i = 0; i < 64; i++) {
470 		err = reg_w(gspca_dev, request, ybase + i, qtable[0][i]);
471 		if (err < 0)
472 			return err;
473 	}
474 
475 	/* loop over c components */
476 	for (i = 0; i < 64; i++) {
477 		err = reg_w(gspca_dev, request, cbase + i, qtable[1][i]);
478 		if (err < 0)
479 			return err;
480 	}
481 	return 0;
482 }
483 
spca500_ping310(struct gspca_dev * gspca_dev)484 static void spca500_ping310(struct gspca_dev *gspca_dev)
485 {
486 	reg_r(gspca_dev, 0x0d04, 2);
487 	PDEBUG(D_STREAM, "ClickSmart310 ping 0x0d04 0x%02x 0x%02x",
488 		gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
489 }
490 
spca500_clksmart310_init(struct gspca_dev * gspca_dev)491 static void spca500_clksmart310_init(struct gspca_dev *gspca_dev)
492 {
493 	reg_r(gspca_dev, 0x0d05, 2);
494 	PDEBUG(D_STREAM, "ClickSmart310 init 0x0d05 0x%02x 0x%02x",
495 		gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
496 	reg_w(gspca_dev, 0x00, 0x8167, 0x5a);
497 	spca500_ping310(gspca_dev);
498 
499 	reg_w(gspca_dev, 0x00, 0x8168, 0x22);
500 	reg_w(gspca_dev, 0x00, 0x816a, 0xc0);
501 	reg_w(gspca_dev, 0x00, 0x816b, 0x0b);
502 	reg_w(gspca_dev, 0x00, 0x8169, 0x25);
503 	reg_w(gspca_dev, 0x00, 0x8157, 0x5b);
504 	reg_w(gspca_dev, 0x00, 0x8158, 0x5b);
505 	reg_w(gspca_dev, 0x00, 0x813f, 0x03);
506 	reg_w(gspca_dev, 0x00, 0x8151, 0x4a);
507 	reg_w(gspca_dev, 0x00, 0x8153, 0x78);
508 	reg_w(gspca_dev, 0x00, 0x0d01, 0x04);
509 						/* 00 for adjust shutter */
510 	reg_w(gspca_dev, 0x00, 0x0d02, 0x01);
511 	reg_w(gspca_dev, 0x00, 0x8169, 0x25);
512 	reg_w(gspca_dev, 0x00, 0x0d01, 0x02);
513 }
514 
spca500_setmode(struct gspca_dev * gspca_dev,__u8 xmult,__u8 ymult)515 static void spca500_setmode(struct gspca_dev *gspca_dev,
516 			__u8 xmult, __u8 ymult)
517 {
518 	int mode;
519 
520 	/* set x multiplier */
521 	reg_w(gspca_dev, 0, 0x8001, xmult);
522 
523 	/* set y multiplier */
524 	reg_w(gspca_dev, 0, 0x8002, ymult);
525 
526 	/* use compressed mode, VGA, with mode specific subsample */
527 	mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
528 	reg_w(gspca_dev, 0, 0x8003, mode << 4);
529 }
530 
spca500_full_reset(struct gspca_dev * gspca_dev)531 static int spca500_full_reset(struct gspca_dev *gspca_dev)
532 {
533 	int err;
534 
535 	/* send the reset command */
536 	err = reg_w(gspca_dev, 0xe0, 0x0001, 0x0000);
537 	if (err < 0)
538 		return err;
539 
540 	/* wait for the reset to complete */
541 	err = reg_r_wait(gspca_dev, 0x06, 0x0000, 0x0000);
542 	if (err < 0)
543 		return err;
544 	err = reg_w(gspca_dev, 0xe0, 0x0000, 0x0000);
545 	if (err < 0)
546 		return err;
547 	err = reg_r_wait(gspca_dev, 0x06, 0, 0);
548 	if (err < 0) {
549 		PDEBUG(D_ERR, "reg_r_wait() failed");
550 		return err;
551 	}
552 	/* all ok */
553 	return 0;
554 }
555 
556 /* Synchro the Bridge with sensor */
557 /* Maybe that will work on all spca500 chip */
558 /* because i only own a clicksmart310 try for that chip */
559 /* using spca50x_set_packet_size() cause an Ooops here */
560 /* usb_set_interface from kernel 2.6.x clear all the urb stuff */
561 /* up-port the same feature as in 2.4.x kernel */
spca500_synch310(struct gspca_dev * gspca_dev)562 static int spca500_synch310(struct gspca_dev *gspca_dev)
563 {
564 	if (usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0) < 0) {
565 		PDEBUG(D_ERR, "Set packet size: set interface error");
566 		goto error;
567 	}
568 	spca500_ping310(gspca_dev);
569 
570 	reg_r(gspca_dev, 0x0d00, 1);
571 
572 	/* need alt setting here */
573 	PDEBUG(D_PACK, "ClickSmart310 sync alt: %d", gspca_dev->alt);
574 
575 	/* Windoze use pipe with altsetting 6 why 7 here */
576 	if (usb_set_interface(gspca_dev->dev,
577 				gspca_dev->iface,
578 				gspca_dev->alt) < 0) {
579 		PDEBUG(D_ERR, "Set packet size: set interface error");
580 		goto error;
581 	}
582 	return 0;
583 error:
584 	return -EBUSY;
585 }
586 
spca500_reinit(struct gspca_dev * gspca_dev)587 static void spca500_reinit(struct gspca_dev *gspca_dev)
588 {
589 	int err;
590 	__u8 Data;
591 
592 	/* some unknown command from Aiptek pocket dv and family300 */
593 
594 	reg_w(gspca_dev, 0x00, 0x0d01, 0x01);
595 	reg_w(gspca_dev, 0x00, 0x0d03, 0x00);
596 	reg_w(gspca_dev, 0x00, 0x0d02, 0x01);
597 
598 	/* enable drop packet */
599 	reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
600 
601 	err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840,
602 				 qtable_pocketdv);
603 	if (err < 0)
604 		PDEBUG(D_ERR|D_STREAM, "spca50x_setup_qtable failed on init");
605 
606 	/* set qtable index */
607 	reg_w(gspca_dev, 0x00, 0x8880, 2);
608 	/* family cam Quicksmart stuff */
609 	reg_w(gspca_dev, 0x00, 0x800a, 0x00);
610 	/* Set agc transfer: synced between frames */
611 	reg_w(gspca_dev, 0x00, 0x820f, 0x01);
612 	/* Init SDRAM - needed for SDRAM access */
613 	reg_w(gspca_dev, 0x00, 0x870a, 0x04);
614 	/*Start init sequence or stream */
615 	reg_w(gspca_dev, 0, 0x8003, 0x00);
616 	/* switch to video camera mode */
617 	reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
618 	msleep(2000);
619 	if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0) {
620 		reg_r(gspca_dev, 0x816b, 1);
621 		Data = gspca_dev->usb_buf[0];
622 		reg_w(gspca_dev, 0x00, 0x816b, Data);
623 	}
624 }
625 
626 /* this function is called at probe time */
sd_config(struct gspca_dev * gspca_dev,const struct usb_device_id * id)627 static int sd_config(struct gspca_dev *gspca_dev,
628 			const struct usb_device_id *id)
629 {
630 	struct sd *sd = (struct sd *) gspca_dev;
631 	struct cam *cam;
632 
633 	cam = &gspca_dev->cam;
634 	sd->subtype = id->driver_info;
635 	if (sd->subtype != LogitechClickSmart310) {
636 		cam->cam_mode = vga_mode;
637 		cam->nmodes = ARRAY_SIZE(vga_mode);
638 	} else {
639 		cam->cam_mode = sif_mode;
640 		cam->nmodes = ARRAY_SIZE(sif_mode);
641 	}
642 	sd->brightness = BRIGHTNESS_DEF;
643 	sd->contrast = CONTRAST_DEF;
644 	sd->colors = COLOR_DEF;
645 	sd->quality = QUALITY_DEF;
646 	return 0;
647 }
648 
649 /* this function is called at probe and resume time */
sd_init(struct gspca_dev * gspca_dev)650 static int sd_init(struct gspca_dev *gspca_dev)
651 {
652 	struct sd *sd = (struct sd *) gspca_dev;
653 
654 	/* initialisation of spca500 based cameras is deferred */
655 	PDEBUG(D_STREAM, "SPCA500 init");
656 	if (sd->subtype == LogitechClickSmart310)
657 		spca500_clksmart310_init(gspca_dev);
658 /*	else
659 		spca500_initialise(gspca_dev); */
660 	PDEBUG(D_STREAM, "SPCA500 init done");
661 	return 0;
662 }
663 
sd_start(struct gspca_dev * gspca_dev)664 static int sd_start(struct gspca_dev *gspca_dev)
665 {
666 	struct sd *sd = (struct sd *) gspca_dev;
667 	int err;
668 	__u8 Data;
669 	__u8 xmult, ymult;
670 
671 	/* create the JPEG header */
672 	jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
673 			0x22);		/* JPEG 411 */
674 	jpeg_set_qual(sd->jpeg_hdr, sd->quality);
675 
676 	if (sd->subtype == LogitechClickSmart310) {
677 		xmult = 0x16;
678 		ymult = 0x12;
679 	} else {
680 		xmult = 0x28;
681 		ymult = 0x1e;
682 	}
683 
684 	/* is there a sensor here ? */
685 	reg_r(gspca_dev, 0x8a04, 1);
686 	PDEBUG(D_STREAM, "Spca500 Sensor Address 0x%02x",
687 		gspca_dev->usb_buf[0]);
688 	PDEBUG(D_STREAM, "Spca500 curr_mode: %d Xmult: 0x%02x, Ymult: 0x%02x",
689 		gspca_dev->curr_mode, xmult, ymult);
690 
691 	/* setup qtable */
692 	switch (sd->subtype) {
693 	case LogitechClickSmart310:
694 		 spca500_setmode(gspca_dev, xmult, ymult);
695 
696 		/* enable drop packet */
697 		reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
698 		reg_w(gspca_dev, 0x00, 0x8880, 3);
699 		err = spca50x_setup_qtable(gspca_dev,
700 					   0x00, 0x8800, 0x8840,
701 					   qtable_creative_pccam);
702 		if (err < 0)
703 			PDEBUG(D_ERR, "spca50x_setup_qtable failed");
704 		/* Init SDRAM - needed for SDRAM access */
705 		reg_w(gspca_dev, 0x00, 0x870a, 0x04);
706 
707 		/* switch to video camera mode */
708 		reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
709 		msleep(500);
710 		if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
711 			PDEBUG(D_ERR, "reg_r_wait() failed");
712 
713 		reg_r(gspca_dev, 0x816b, 1);
714 		Data = gspca_dev->usb_buf[0];
715 		reg_w(gspca_dev, 0x00, 0x816b, Data);
716 
717 		spca500_synch310(gspca_dev);
718 
719 		write_vector(gspca_dev, spca500_visual_defaults);
720 		spca500_setmode(gspca_dev, xmult, ymult);
721 		/* enable drop packet */
722 		err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
723 		if (err < 0)
724 			PDEBUG(D_ERR, "failed to enable drop packet");
725 		reg_w(gspca_dev, 0x00, 0x8880, 3);
726 		err = spca50x_setup_qtable(gspca_dev,
727 					   0x00, 0x8800, 0x8840,
728 					   qtable_creative_pccam);
729 		if (err < 0)
730 			PDEBUG(D_ERR, "spca50x_setup_qtable failed");
731 
732 		/* Init SDRAM - needed for SDRAM access */
733 		reg_w(gspca_dev, 0x00, 0x870a, 0x04);
734 
735 		/* switch to video camera mode */
736 		reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
737 
738 		if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
739 			PDEBUG(D_ERR, "reg_r_wait() failed");
740 
741 		reg_r(gspca_dev, 0x816b, 1);
742 		Data = gspca_dev->usb_buf[0];
743 		reg_w(gspca_dev, 0x00, 0x816b, Data);
744 		break;
745 	case CreativePCCam300:		/* Creative PC-CAM 300 640x480 CCD */
746 	case IntelPocketPCCamera:	/* FIXME: Temporary fix for
747 					 *	Intel Pocket PC Camera
748 					 *	- NWG (Sat 29th March 2003) */
749 
750 		/* do a full reset */
751 		err = spca500_full_reset(gspca_dev);
752 		if (err < 0)
753 			PDEBUG(D_ERR, "spca500_full_reset failed");
754 
755 		/* enable drop packet */
756 		err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
757 		if (err < 0)
758 			PDEBUG(D_ERR, "failed to enable drop packet");
759 		reg_w(gspca_dev, 0x00, 0x8880, 3);
760 		err = spca50x_setup_qtable(gspca_dev,
761 					   0x00, 0x8800, 0x8840,
762 					   qtable_creative_pccam);
763 		if (err < 0)
764 			PDEBUG(D_ERR, "spca50x_setup_qtable failed");
765 
766 		spca500_setmode(gspca_dev, xmult, ymult);
767 		reg_w(gspca_dev, 0x20, 0x0001, 0x0004);
768 
769 		/* switch to video camera mode */
770 		reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
771 
772 		if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
773 			PDEBUG(D_ERR, "reg_r_wait() failed");
774 
775 		reg_r(gspca_dev, 0x816b, 1);
776 		Data = gspca_dev->usb_buf[0];
777 		reg_w(gspca_dev, 0x00, 0x816b, Data);
778 
779 /*		write_vector(gspca_dev, spca500_visual_defaults); */
780 		break;
781 	case KodakEZ200:		/* Kodak EZ200 */
782 
783 		/* do a full reset */
784 		err = spca500_full_reset(gspca_dev);
785 		if (err < 0)
786 			PDEBUG(D_ERR, "spca500_full_reset failed");
787 		/* enable drop packet */
788 		reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
789 		reg_w(gspca_dev, 0x00, 0x8880, 0);
790 		err = spca50x_setup_qtable(gspca_dev,
791 					   0x00, 0x8800, 0x8840,
792 					   qtable_kodak_ez200);
793 		if (err < 0)
794 			PDEBUG(D_ERR, "spca50x_setup_qtable failed");
795 		spca500_setmode(gspca_dev, xmult, ymult);
796 
797 		reg_w(gspca_dev, 0x20, 0x0001, 0x0004);
798 
799 		/* switch to video camera mode */
800 		reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
801 
802 		if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
803 			PDEBUG(D_ERR, "reg_r_wait() failed");
804 
805 		reg_r(gspca_dev, 0x816b, 1);
806 		Data = gspca_dev->usb_buf[0];
807 		reg_w(gspca_dev, 0x00, 0x816b, Data);
808 
809 /*		write_vector(gspca_dev, spca500_visual_defaults); */
810 		break;
811 
812 	case BenqDC1016:
813 	case DLinkDSC350:		/* FamilyCam 300 */
814 	case AiptekPocketDV:		/* Aiptek PocketDV */
815 	case Gsmartmini:		/*Mustek Gsmart Mini */
816 	case MustekGsmart300:		/* Mustek Gsmart 300 */
817 	case PalmPixDC85:
818 	case Optimedia:
819 	case ToptroIndus:
820 	case AgfaCl20:
821 		spca500_reinit(gspca_dev);
822 		reg_w(gspca_dev, 0x00, 0x0d01, 0x01);
823 		/* enable drop packet */
824 		reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
825 
826 		err = spca50x_setup_qtable(gspca_dev,
827 				   0x00, 0x8800, 0x8840, qtable_pocketdv);
828 		if (err < 0)
829 			PDEBUG(D_ERR, "spca50x_setup_qtable failed");
830 		reg_w(gspca_dev, 0x00, 0x8880, 2);
831 
832 		/* familycam Quicksmart pocketDV stuff */
833 		reg_w(gspca_dev, 0x00, 0x800a, 0x00);
834 		/* Set agc transfer: synced between frames */
835 		reg_w(gspca_dev, 0x00, 0x820f, 0x01);
836 		/* Init SDRAM - needed for SDRAM access */
837 		reg_w(gspca_dev, 0x00, 0x870a, 0x04);
838 
839 		spca500_setmode(gspca_dev, xmult, ymult);
840 		/* switch to video camera mode */
841 		reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
842 
843 		reg_r_wait(gspca_dev, 0, 0x8000, 0x44);
844 
845 		reg_r(gspca_dev, 0x816b, 1);
846 		Data = gspca_dev->usb_buf[0];
847 		reg_w(gspca_dev, 0x00, 0x816b, Data);
848 		break;
849 	case LogitechTraveler:
850 	case LogitechClickSmart510:
851 		reg_w(gspca_dev, 0x02, 0x00, 0x00);
852 		/* enable drop packet */
853 		reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
854 
855 		err = spca50x_setup_qtable(gspca_dev,
856 					0x00, 0x8800,
857 					0x8840, qtable_creative_pccam);
858 		if (err < 0)
859 			PDEBUG(D_ERR, "spca50x_setup_qtable failed");
860 		reg_w(gspca_dev, 0x00, 0x8880, 3);
861 		reg_w(gspca_dev, 0x00, 0x800a, 0x00);
862 		/* Init SDRAM - needed for SDRAM access */
863 		reg_w(gspca_dev, 0x00, 0x870a, 0x04);
864 
865 		spca500_setmode(gspca_dev, xmult, ymult);
866 
867 		/* switch to video camera mode */
868 		reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
869 		reg_r_wait(gspca_dev, 0, 0x8000, 0x44);
870 
871 		reg_r(gspca_dev, 0x816b, 1);
872 		Data = gspca_dev->usb_buf[0];
873 		reg_w(gspca_dev, 0x00, 0x816b, Data);
874 		write_vector(gspca_dev, Clicksmart510_defaults);
875 		break;
876 	}
877 	return 0;
878 }
879 
sd_stopN(struct gspca_dev * gspca_dev)880 static void sd_stopN(struct gspca_dev *gspca_dev)
881 {
882 	reg_w(gspca_dev, 0, 0x8003, 0x00);
883 
884 	/* switch to video camera mode */
885 	reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
886 	reg_r(gspca_dev, 0x8000, 1);
887 	PDEBUG(D_STREAM, "stop SPCA500 done reg8000: 0x%2x",
888 		gspca_dev->usb_buf[0]);
889 }
890 
sd_pkt_scan(struct gspca_dev * gspca_dev,u8 * data,int len)891 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
892 			u8 *data,			/* isoc packet */
893 			int len)			/* iso packet length */
894 {
895 	struct sd *sd = (struct sd *) gspca_dev;
896 	int i;
897 	static __u8 ffd9[] = {0xff, 0xd9};
898 
899 /* frames are jpeg 4.1.1 without 0xff escape */
900 	if (data[0] == 0xff) {
901 		if (data[1] != 0x01) {	/* drop packet */
902 /*			gspca_dev->last_packet_type = DISCARD_PACKET; */
903 			return;
904 		}
905 		gspca_frame_add(gspca_dev, LAST_PACKET,
906 					ffd9, 2);
907 
908 		/* put the JPEG header in the new frame */
909 		gspca_frame_add(gspca_dev, FIRST_PACKET,
910 			sd->jpeg_hdr, JPEG_HDR_SZ);
911 
912 		data += SPCA500_OFFSET_DATA;
913 		len -= SPCA500_OFFSET_DATA;
914 	} else {
915 		data += 1;
916 		len -= 1;
917 	}
918 
919 	/* add 0x00 after 0xff */
920 	i = 0;
921 	do {
922 		if (data[i] == 0xff) {
923 			gspca_frame_add(gspca_dev, INTER_PACKET,
924 					data, i + 1);
925 			len -= i;
926 			data += i;
927 			*data = 0x00;
928 			i = 0;
929 		}
930 		i++;
931 	} while (i < len);
932 	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
933 }
934 
setbrightness(struct gspca_dev * gspca_dev)935 static void setbrightness(struct gspca_dev *gspca_dev)
936 {
937 	struct sd *sd = (struct sd *) gspca_dev;
938 
939 	reg_w(gspca_dev, 0x00, 0x8167,
940 			(__u8) (sd->brightness - 128));
941 }
942 
setcontrast(struct gspca_dev * gspca_dev)943 static void setcontrast(struct gspca_dev *gspca_dev)
944 {
945 	struct sd *sd = (struct sd *) gspca_dev;
946 
947 	reg_w(gspca_dev, 0x00, 0x8168, sd->contrast);
948 }
949 
setcolors(struct gspca_dev * gspca_dev)950 static void setcolors(struct gspca_dev *gspca_dev)
951 {
952 	struct sd *sd = (struct sd *) gspca_dev;
953 
954 	reg_w(gspca_dev, 0x00, 0x8169, sd->colors);
955 }
956 
sd_setbrightness(struct gspca_dev * gspca_dev,__s32 val)957 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
958 {
959 	struct sd *sd = (struct sd *) gspca_dev;
960 
961 	sd->brightness = val;
962 	if (gspca_dev->streaming)
963 		setbrightness(gspca_dev);
964 	return 0;
965 }
966 
sd_getbrightness(struct gspca_dev * gspca_dev,__s32 * val)967 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
968 {
969 	struct sd *sd = (struct sd *) gspca_dev;
970 
971 	*val = sd->brightness;
972 	return 0;
973 }
974 
sd_setcontrast(struct gspca_dev * gspca_dev,__s32 val)975 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
976 {
977 	struct sd *sd = (struct sd *) gspca_dev;
978 
979 	sd->contrast = val;
980 	if (gspca_dev->streaming)
981 		setcontrast(gspca_dev);
982 	return 0;
983 }
984 
sd_getcontrast(struct gspca_dev * gspca_dev,__s32 * val)985 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
986 {
987 	struct sd *sd = (struct sd *) gspca_dev;
988 
989 	*val = sd->contrast;
990 	return 0;
991 }
992 
sd_setcolors(struct gspca_dev * gspca_dev,__s32 val)993 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
994 {
995 	struct sd *sd = (struct sd *) gspca_dev;
996 
997 	sd->colors = val;
998 	if (gspca_dev->streaming)
999 		setcolors(gspca_dev);
1000 	return 0;
1001 }
1002 
sd_getcolors(struct gspca_dev * gspca_dev,__s32 * val)1003 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1004 {
1005 	struct sd *sd = (struct sd *) gspca_dev;
1006 
1007 	*val = sd->colors;
1008 	return 0;
1009 }
1010 
sd_set_jcomp(struct gspca_dev * gspca_dev,struct v4l2_jpegcompression * jcomp)1011 static int sd_set_jcomp(struct gspca_dev *gspca_dev,
1012 			struct v4l2_jpegcompression *jcomp)
1013 {
1014 	struct sd *sd = (struct sd *) gspca_dev;
1015 
1016 	if (jcomp->quality < QUALITY_MIN)
1017 		sd->quality = QUALITY_MIN;
1018 	else if (jcomp->quality > QUALITY_MAX)
1019 		sd->quality = QUALITY_MAX;
1020 	else
1021 		sd->quality = jcomp->quality;
1022 	if (gspca_dev->streaming)
1023 		jpeg_set_qual(sd->jpeg_hdr, sd->quality);
1024 	return 0;
1025 }
1026 
sd_get_jcomp(struct gspca_dev * gspca_dev,struct v4l2_jpegcompression * jcomp)1027 static int sd_get_jcomp(struct gspca_dev *gspca_dev,
1028 			struct v4l2_jpegcompression *jcomp)
1029 {
1030 	struct sd *sd = (struct sd *) gspca_dev;
1031 
1032 	memset(jcomp, 0, sizeof *jcomp);
1033 	jcomp->quality = sd->quality;
1034 	jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
1035 			| V4L2_JPEG_MARKER_DQT;
1036 	return 0;
1037 }
1038 
1039 /* sub-driver description */
1040 static const struct sd_desc sd_desc = {
1041 	.name = MODULE_NAME,
1042 	.ctrls = sd_ctrls,
1043 	.nctrls = ARRAY_SIZE(sd_ctrls),
1044 	.config = sd_config,
1045 	.init = sd_init,
1046 	.start = sd_start,
1047 	.stopN = sd_stopN,
1048 	.pkt_scan = sd_pkt_scan,
1049 	.get_jcomp = sd_get_jcomp,
1050 	.set_jcomp = sd_set_jcomp,
1051 };
1052 
1053 /* -- module initialisation -- */
1054 static const struct usb_device_id device_table[] = {
1055 	{USB_DEVICE(0x040a, 0x0300), .driver_info = KodakEZ200},
1056 	{USB_DEVICE(0x041e, 0x400a), .driver_info = CreativePCCam300},
1057 	{USB_DEVICE(0x046d, 0x0890), .driver_info = LogitechTraveler},
1058 	{USB_DEVICE(0x046d, 0x0900), .driver_info = LogitechClickSmart310},
1059 	{USB_DEVICE(0x046d, 0x0901), .driver_info = LogitechClickSmart510},
1060 	{USB_DEVICE(0x04a5, 0x300c), .driver_info = BenqDC1016},
1061 	{USB_DEVICE(0x04fc, 0x7333), .driver_info = PalmPixDC85},
1062 	{USB_DEVICE(0x055f, 0xc200), .driver_info = MustekGsmart300},
1063 	{USB_DEVICE(0x055f, 0xc220), .driver_info = Gsmartmini},
1064 	{USB_DEVICE(0x06bd, 0x0404), .driver_info = AgfaCl20},
1065 	{USB_DEVICE(0x06be, 0x0800), .driver_info = Optimedia},
1066 	{USB_DEVICE(0x084d, 0x0003), .driver_info = DLinkDSC350},
1067 	{USB_DEVICE(0x08ca, 0x0103), .driver_info = AiptekPocketDV},
1068 	{USB_DEVICE(0x2899, 0x012c), .driver_info = ToptroIndus},
1069 	{USB_DEVICE(0x8086, 0x0630), .driver_info = IntelPocketPCCamera},
1070 	{}
1071 };
1072 MODULE_DEVICE_TABLE(usb, device_table);
1073 
1074 /* -- device connect -- */
sd_probe(struct usb_interface * intf,const struct usb_device_id * id)1075 static int sd_probe(struct usb_interface *intf,
1076 			const struct usb_device_id *id)
1077 {
1078 	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1079 				THIS_MODULE);
1080 }
1081 
1082 static struct usb_driver sd_driver = {
1083 	.name = MODULE_NAME,
1084 	.id_table = device_table,
1085 	.probe = sd_probe,
1086 	.disconnect = gspca_disconnect,
1087 #ifdef CONFIG_PM
1088 	.suspend = gspca_suspend,
1089 	.resume = gspca_resume,
1090 #endif
1091 };
1092 
1093 /* -- module insert / remove -- */
sd_mod_init(void)1094 static int __init sd_mod_init(void)
1095 {
1096 	return usb_register(&sd_driver);
1097 }
sd_mod_exit(void)1098 static void __exit sd_mod_exit(void)
1099 {
1100 	usb_deregister(&sd_driver);
1101 }
1102 
1103 module_init(sd_mod_init);
1104 module_exit(sd_mod_exit);
1105