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