• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  *		Pixart PAC7311 library
4  *		Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li
5  *
6  * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
7  */
8 
9 /* Some documentation about various registers as determined by trial and error.
10  *
11  * Register page 1:
12  *
13  * Address	Description
14  * 0x08		Unknown compressor related, must always be 8 except when not
15  *		in 640x480 resolution and page 4 reg 2 <= 3 then set it to 9 !
16  * 0x1b		Auto white balance related, bit 0 is AWB enable (inverted)
17  *		bits 345 seem to toggle per color gains on/off (inverted)
18  * 0x78		Global control, bit 6 controls the LED (inverted)
19  * 0x80		Compression balance, interesting settings:
20  *		0x01 Use this to allow the camera to switch to higher compr.
21  *		     on the fly. Needed to stay within bandwidth @ 640x480@30
22  *		0x1c From usb captures under Windows for 640x480
23  *		0x2a Values >= this switch the camera to a lower compression,
24  *		     using the same table for both luminance and chrominance.
25  *		     This gives a sharper picture. Usable only at 640x480@ <
26  *		     15 fps or 320x240 / 160x120. Note currently the driver
27  *		     does not use this as the quality gain is small and the
28  *		     generated JPG-s are only understood by v4l-utils >= 0.8.9
29  *		0x3f From usb captures under Windows for 320x240
30  *		0x69 From usb captures under Windows for 160x120
31  *
32  * Register page 4:
33  *
34  * Address	Description
35  * 0x02		Clock divider 2-63, fps =~ 60 / val. Must be a multiple of 3 on
36  *		the 7302, so one of 3, 6, 9, ..., except when between 6 and 12?
37  * 0x0f		Master gain 1-245, low value = high gain
38  * 0x10		Another gain 0-15, limited influence (1-2x gain I guess)
39  * 0x21		Bitfield: 0-1 unused, 2-3 vflip/hflip, 4-5 unknown, 6-7 unused
40  *		Note setting vflip disabled leads to a much lower image quality,
41  *		so we always vflip, and tell userspace to flip it back
42  * 0x27		Seems to toggle various gains on / off, Setting bit 7 seems to
43  *		completely disable the analog amplification block. Set to 0x68
44  *		for max gain, 0x14 for minimal gain.
45  */
46 
47 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
48 
49 #define MODULE_NAME "pac7311"
50 
51 #include <linux/input.h>
52 #include "gspca.h"
53 /* Include pac common sof detection functions */
54 #include "pac_common.h"
55 
56 #define PAC7311_GAIN_DEFAULT     122
57 #define PAC7311_EXPOSURE_DEFAULT   3 /* 20 fps, avoid using high compr. */
58 
59 MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li");
60 MODULE_DESCRIPTION("Pixart PAC7311");
61 MODULE_LICENSE("GPL");
62 
63 struct sd {
64 	struct gspca_dev gspca_dev;		/* !! must be the first item */
65 
66 	struct v4l2_ctrl *contrast;
67 	struct v4l2_ctrl *hflip;
68 
69 	u8 sof_read;
70 	u8 autogain_ignore_frames;
71 
72 	atomic_t avg_lum;
73 };
74 
75 static const struct v4l2_pix_format vga_mode[] = {
76 	{160, 120, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
77 		.bytesperline = 160,
78 		.sizeimage = 160 * 120 * 3 / 8 + 590,
79 		.colorspace = V4L2_COLORSPACE_JPEG,
80 		.priv = 2},
81 	{320, 240, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
82 		.bytesperline = 320,
83 		.sizeimage = 320 * 240 * 3 / 8 + 590,
84 		.colorspace = V4L2_COLORSPACE_JPEG,
85 		.priv = 1},
86 	{640, 480, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
87 		.bytesperline = 640,
88 		.sizeimage = 640 * 480 * 3 / 8 + 590,
89 		.colorspace = V4L2_COLORSPACE_JPEG,
90 		.priv = 0},
91 };
92 
93 #define LOAD_PAGE4		254
94 #define END_OF_SEQUENCE		0
95 
96 static const __u8 init_7311[] = {
97 	0xff, 0x01,
98 	0x78, 0x40,	/* Bit_0=start stream, Bit_6=LED */
99 	0x78, 0x40,	/* Bit_0=start stream, Bit_6=LED */
100 	0x78, 0x44,	/* Bit_0=start stream, Bit_6=LED */
101 	0xff, 0x04,
102 	0x27, 0x80,
103 	0x28, 0xca,
104 	0x29, 0x53,
105 	0x2a, 0x0e,
106 	0xff, 0x01,
107 	0x3e, 0x20,
108 };
109 
110 static const __u8 start_7311[] = {
111 /*	index, len, [value]* */
112 	0xff, 1,	0x01,		/* page 1 */
113 	0x02, 43,	0x48, 0x0a, 0x40, 0x08, 0x00, 0x00, 0x08, 0x00,
114 			0x06, 0xff, 0x11, 0xff, 0x5a, 0x30, 0x90, 0x4c,
115 			0x00, 0x07, 0x00, 0x0a, 0x10, 0x00, 0xa0, 0x10,
116 			0x02, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x01, 0x00,
117 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
118 			0x00, 0x00, 0x00,
119 	0x3e, 42,	0x00, 0x00, 0x78, 0x52, 0x4a, 0x52, 0x78, 0x6e,
120 			0x48, 0x46, 0x48, 0x6e, 0x5f, 0x49, 0x42, 0x49,
121 			0x5f, 0x5f, 0x49, 0x42, 0x49, 0x5f, 0x6e, 0x48,
122 			0x46, 0x48, 0x6e, 0x78, 0x52, 0x4a, 0x52, 0x78,
123 			0x00, 0x00, 0x09, 0x1b, 0x34, 0x49, 0x5c, 0x9b,
124 			0xd0, 0xff,
125 	0x78, 6,	0x44, 0x00, 0xf2, 0x01, 0x01, 0x80,
126 	0x7f, 18,	0x2a, 0x1c, 0x00, 0xc8, 0x02, 0x58, 0x03, 0x84,
127 			0x12, 0x00, 0x1a, 0x04, 0x08, 0x0c, 0x10, 0x14,
128 			0x18, 0x20,
129 	0x96, 3,	0x01, 0x08, 0x04,
130 	0xa0, 4,	0x44, 0x44, 0x44, 0x04,
131 	0xf0, 13,	0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x20, 0x00,
132 			0x3f, 0x00, 0x0a, 0x01, 0x00,
133 	0xff, 1,	0x04,		/* page 4 */
134 	0, LOAD_PAGE4,			/* load the page 4 */
135 	0x11, 1,	0x01,
136 	0, END_OF_SEQUENCE		/* end of sequence */
137 };
138 
139 #define SKIP		0xaa
140 /* page 4 - the value SKIP says skip the index - see reg_w_page() */
141 static const __u8 page4_7311[] = {
142 	SKIP, SKIP, 0x04, 0x54, 0x07, 0x2b, 0x09, 0x0f,
143 	0x09, 0x00, SKIP, SKIP, 0x07, 0x00, 0x00, 0x62,
144 	0x08, SKIP, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
145 	0x00, 0x00, 0x00, 0x03, 0xa0, 0x01, 0xf4, SKIP,
146 	SKIP, 0x00, 0x08, SKIP, 0x03, SKIP, 0x00, 0x68,
147 	0xca, 0x10, 0x06, 0x78, 0x00, 0x00, 0x00, 0x00,
148 	0x23, 0x28, 0x04, 0x11, 0x00, 0x00
149 };
150 
reg_w_buf(struct gspca_dev * gspca_dev,__u8 index,const u8 * buffer,int len)151 static void reg_w_buf(struct gspca_dev *gspca_dev,
152 		  __u8 index,
153 		  const u8 *buffer, int len)
154 {
155 	int ret;
156 
157 	if (gspca_dev->usb_err < 0)
158 		return;
159 	memcpy(gspca_dev->usb_buf, buffer, len);
160 	ret = usb_control_msg(gspca_dev->dev,
161 			usb_sndctrlpipe(gspca_dev->dev, 0),
162 			0,		/* request */
163 			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
164 			0,		/* value */
165 			index, gspca_dev->usb_buf, len,
166 			500);
167 	if (ret < 0) {
168 		pr_err("reg_w_buf() failed index 0x%02x, error %d\n",
169 		       index, ret);
170 		gspca_dev->usb_err = ret;
171 	}
172 }
173 
174 
reg_w(struct gspca_dev * gspca_dev,__u8 index,__u8 value)175 static void reg_w(struct gspca_dev *gspca_dev,
176 		  __u8 index,
177 		  __u8 value)
178 {
179 	int ret;
180 
181 	if (gspca_dev->usb_err < 0)
182 		return;
183 	gspca_dev->usb_buf[0] = value;
184 	ret = usb_control_msg(gspca_dev->dev,
185 			usb_sndctrlpipe(gspca_dev->dev, 0),
186 			0,			/* request */
187 			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
188 			0, index, gspca_dev->usb_buf, 1,
189 			500);
190 	if (ret < 0) {
191 		pr_err("reg_w() failed index 0x%02x, value 0x%02x, error %d\n",
192 		       index, value, ret);
193 		gspca_dev->usb_err = ret;
194 	}
195 }
196 
reg_w_seq(struct gspca_dev * gspca_dev,const __u8 * seq,int len)197 static void reg_w_seq(struct gspca_dev *gspca_dev,
198 		const __u8 *seq, int len)
199 {
200 	while (--len >= 0) {
201 		reg_w(gspca_dev, seq[0], seq[1]);
202 		seq += 2;
203 	}
204 }
205 
206 /* load the beginning of a page */
reg_w_page(struct gspca_dev * gspca_dev,const __u8 * page,int len)207 static void reg_w_page(struct gspca_dev *gspca_dev,
208 			const __u8 *page, int len)
209 {
210 	int index;
211 	int ret = 0;
212 
213 	if (gspca_dev->usb_err < 0)
214 		return;
215 	for (index = 0; index < len; index++) {
216 		if (page[index] == SKIP)		/* skip this index */
217 			continue;
218 		gspca_dev->usb_buf[0] = page[index];
219 		ret = usb_control_msg(gspca_dev->dev,
220 				usb_sndctrlpipe(gspca_dev->dev, 0),
221 				0,			/* request */
222 			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
223 				0, index, gspca_dev->usb_buf, 1,
224 				500);
225 		if (ret < 0) {
226 			pr_err("reg_w_page() failed index 0x%02x, value 0x%02x, error %d\n",
227 			       index, page[index], ret);
228 			gspca_dev->usb_err = ret;
229 			break;
230 		}
231 	}
232 }
233 
234 /* output a variable sequence */
reg_w_var(struct gspca_dev * gspca_dev,const __u8 * seq,const __u8 * page4,unsigned int page4_len)235 static void reg_w_var(struct gspca_dev *gspca_dev,
236 			const __u8 *seq,
237 			const __u8 *page4, unsigned int page4_len)
238 {
239 	int index, len;
240 
241 	for (;;) {
242 		index = *seq++;
243 		len = *seq++;
244 		switch (len) {
245 		case END_OF_SEQUENCE:
246 			return;
247 		case LOAD_PAGE4:
248 			reg_w_page(gspca_dev, page4, page4_len);
249 			break;
250 		default:
251 			if (len > USB_BUF_SZ) {
252 				gspca_err(gspca_dev, "Incorrect variable sequence\n");
253 				return;
254 			}
255 			while (len > 0) {
256 				if (len < 8) {
257 					reg_w_buf(gspca_dev,
258 						index, seq, len);
259 					seq += len;
260 					break;
261 				}
262 				reg_w_buf(gspca_dev, index, seq, 8);
263 				seq += 8;
264 				index += 8;
265 				len -= 8;
266 			}
267 		}
268 	}
269 	/* not reached */
270 }
271 
272 /* this function is called at probe time for pac7311 */
sd_config(struct gspca_dev * gspca_dev,const struct usb_device_id * id)273 static int sd_config(struct gspca_dev *gspca_dev,
274 			const struct usb_device_id *id)
275 {
276 	struct cam *cam = &gspca_dev->cam;
277 
278 	cam->cam_mode = vga_mode;
279 	cam->nmodes = ARRAY_SIZE(vga_mode);
280 	cam->input_flags = V4L2_IN_ST_VFLIP;
281 
282 	return 0;
283 }
284 
setcontrast(struct gspca_dev * gspca_dev,s32 val)285 static void setcontrast(struct gspca_dev *gspca_dev, s32 val)
286 {
287 	reg_w(gspca_dev, 0xff, 0x04);
288 	reg_w(gspca_dev, 0x10, val);
289 	/* load registers to sensor (Bit 0, auto clear) */
290 	reg_w(gspca_dev, 0x11, 0x01);
291 }
292 
setgain(struct gspca_dev * gspca_dev,s32 val)293 static void setgain(struct gspca_dev *gspca_dev, s32 val)
294 {
295 	reg_w(gspca_dev, 0xff, 0x04);			/* page 4 */
296 	reg_w(gspca_dev, 0x0e, 0x00);
297 	reg_w(gspca_dev, 0x0f, gspca_dev->gain->maximum - val + 1);
298 
299 	/* load registers to sensor (Bit 0, auto clear) */
300 	reg_w(gspca_dev, 0x11, 0x01);
301 }
302 
setexposure(struct gspca_dev * gspca_dev,s32 val)303 static void setexposure(struct gspca_dev *gspca_dev, s32 val)
304 {
305 	reg_w(gspca_dev, 0xff, 0x04);			/* page 4 */
306 	reg_w(gspca_dev, 0x02, val);
307 
308 	/* load registers to sensor (Bit 0, auto clear) */
309 	reg_w(gspca_dev, 0x11, 0x01);
310 
311 	/*
312 	 * Page 1 register 8 must always be 0x08 except when not in
313 	 *  640x480 mode and page 4 reg 2 <= 3 then it must be 9
314 	 */
315 	reg_w(gspca_dev, 0xff, 0x01);
316 	if (gspca_dev->pixfmt.width != 640 && val <= 3)
317 		reg_w(gspca_dev, 0x08, 0x09);
318 	else
319 		reg_w(gspca_dev, 0x08, 0x08);
320 
321 	/*
322 	 * Page1 register 80 sets the compression balance, normally we
323 	 * want / use 0x1c, but for 640x480@30fps we must allow the
324 	 * camera to use higher compression or we may run out of
325 	 * bandwidth.
326 	 */
327 	if (gspca_dev->pixfmt.width == 640 && val == 2)
328 		reg_w(gspca_dev, 0x80, 0x01);
329 	else
330 		reg_w(gspca_dev, 0x80, 0x1c);
331 
332 	/* load registers to sensor (Bit 0, auto clear) */
333 	reg_w(gspca_dev, 0x11, 0x01);
334 }
335 
sethvflip(struct gspca_dev * gspca_dev,s32 hflip,s32 vflip)336 static void sethvflip(struct gspca_dev *gspca_dev, s32 hflip, s32 vflip)
337 {
338 	__u8 data;
339 
340 	reg_w(gspca_dev, 0xff, 0x04);			/* page 4 */
341 	data = (hflip ? 0x04 : 0x00) |
342 	       (vflip ? 0x08 : 0x00);
343 	reg_w(gspca_dev, 0x21, data);
344 
345 	/* load registers to sensor (Bit 0, auto clear) */
346 	reg_w(gspca_dev, 0x11, 0x01);
347 }
348 
349 /* this function is called at probe and resume time for pac7311 */
sd_init(struct gspca_dev * gspca_dev)350 static int sd_init(struct gspca_dev *gspca_dev)
351 {
352 	reg_w_seq(gspca_dev, init_7311, sizeof(init_7311)/2);
353 	return gspca_dev->usb_err;
354 }
355 
sd_s_ctrl(struct v4l2_ctrl * ctrl)356 static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
357 {
358 	struct gspca_dev *gspca_dev =
359 		container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
360 	struct sd *sd = (struct sd *)gspca_dev;
361 
362 	gspca_dev->usb_err = 0;
363 
364 	if (ctrl->id == V4L2_CID_AUTOGAIN && ctrl->is_new && ctrl->val) {
365 		/* when switching to autogain set defaults to make sure
366 		   we are on a valid point of the autogain gain /
367 		   exposure knee graph, and give this change time to
368 		   take effect before doing autogain. */
369 		gspca_dev->exposure->val    = PAC7311_EXPOSURE_DEFAULT;
370 		gspca_dev->gain->val        = PAC7311_GAIN_DEFAULT;
371 		sd->autogain_ignore_frames  = PAC_AUTOGAIN_IGNORE_FRAMES;
372 	}
373 
374 	if (!gspca_dev->streaming)
375 		return 0;
376 
377 	switch (ctrl->id) {
378 	case V4L2_CID_CONTRAST:
379 		setcontrast(gspca_dev, ctrl->val);
380 		break;
381 	case V4L2_CID_AUTOGAIN:
382 		if (gspca_dev->exposure->is_new || (ctrl->is_new && ctrl->val))
383 			setexposure(gspca_dev, gspca_dev->exposure->val);
384 		if (gspca_dev->gain->is_new || (ctrl->is_new && ctrl->val))
385 			setgain(gspca_dev, gspca_dev->gain->val);
386 		break;
387 	case V4L2_CID_HFLIP:
388 		sethvflip(gspca_dev, sd->hflip->val, 1);
389 		break;
390 	default:
391 		return -EINVAL;
392 	}
393 	return gspca_dev->usb_err;
394 }
395 
396 static const struct v4l2_ctrl_ops sd_ctrl_ops = {
397 	.s_ctrl = sd_s_ctrl,
398 };
399 
400 /* this function is called at probe time */
sd_init_controls(struct gspca_dev * gspca_dev)401 static int sd_init_controls(struct gspca_dev *gspca_dev)
402 {
403 	struct sd *sd = (struct sd *) gspca_dev;
404 	struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
405 
406 	gspca_dev->vdev.ctrl_handler = hdl;
407 	v4l2_ctrl_handler_init(hdl, 5);
408 
409 	sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
410 					V4L2_CID_CONTRAST, 0, 15, 1, 7);
411 	gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
412 					V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
413 	gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
414 					V4L2_CID_EXPOSURE, 2, 63, 1,
415 					PAC7311_EXPOSURE_DEFAULT);
416 	gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
417 					V4L2_CID_GAIN, 0, 244, 1,
418 					PAC7311_GAIN_DEFAULT);
419 	sd->hflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
420 		V4L2_CID_HFLIP, 0, 1, 1, 0);
421 
422 	if (hdl->error) {
423 		pr_err("Could not initialize controls\n");
424 		return hdl->error;
425 	}
426 
427 	v4l2_ctrl_auto_cluster(3, &gspca_dev->autogain, 0, false);
428 	return 0;
429 }
430 
431 /* -- start the camera -- */
sd_start(struct gspca_dev * gspca_dev)432 static int sd_start(struct gspca_dev *gspca_dev)
433 {
434 	struct sd *sd = (struct sd *) gspca_dev;
435 
436 	sd->sof_read = 0;
437 
438 	reg_w_var(gspca_dev, start_7311,
439 		page4_7311, sizeof(page4_7311));
440 	setcontrast(gspca_dev, v4l2_ctrl_g_ctrl(sd->contrast));
441 	setgain(gspca_dev, v4l2_ctrl_g_ctrl(gspca_dev->gain));
442 	setexposure(gspca_dev, v4l2_ctrl_g_ctrl(gspca_dev->exposure));
443 	sethvflip(gspca_dev, v4l2_ctrl_g_ctrl(sd->hflip), 1);
444 
445 	/* set correct resolution */
446 	switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
447 	case 2:					/* 160x120 */
448 		reg_w(gspca_dev, 0xff, 0x01);
449 		reg_w(gspca_dev, 0x17, 0x20);
450 		reg_w(gspca_dev, 0x87, 0x10);
451 		break;
452 	case 1:					/* 320x240 */
453 		reg_w(gspca_dev, 0xff, 0x01);
454 		reg_w(gspca_dev, 0x17, 0x30);
455 		reg_w(gspca_dev, 0x87, 0x11);
456 		break;
457 	case 0:					/* 640x480 */
458 		reg_w(gspca_dev, 0xff, 0x01);
459 		reg_w(gspca_dev, 0x17, 0x00);
460 		reg_w(gspca_dev, 0x87, 0x12);
461 		break;
462 	}
463 
464 	sd->sof_read = 0;
465 	sd->autogain_ignore_frames = 0;
466 	atomic_set(&sd->avg_lum, -1);
467 
468 	/* start stream */
469 	reg_w(gspca_dev, 0xff, 0x01);
470 	reg_w(gspca_dev, 0x78, 0x05);
471 
472 	return gspca_dev->usb_err;
473 }
474 
sd_stopN(struct gspca_dev * gspca_dev)475 static void sd_stopN(struct gspca_dev *gspca_dev)
476 {
477 	reg_w(gspca_dev, 0xff, 0x04);
478 	reg_w(gspca_dev, 0x27, 0x80);
479 	reg_w(gspca_dev, 0x28, 0xca);
480 	reg_w(gspca_dev, 0x29, 0x53);
481 	reg_w(gspca_dev, 0x2a, 0x0e);
482 	reg_w(gspca_dev, 0xff, 0x01);
483 	reg_w(gspca_dev, 0x3e, 0x20);
484 	reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
485 	reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
486 	reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
487 }
488 
do_autogain(struct gspca_dev * gspca_dev)489 static void do_autogain(struct gspca_dev *gspca_dev)
490 {
491 	struct sd *sd = (struct sd *) gspca_dev;
492 	int avg_lum = atomic_read(&sd->avg_lum);
493 	int desired_lum, deadzone;
494 
495 	if (avg_lum == -1)
496 		return;
497 
498 	desired_lum = 170;
499 	deadzone = 20;
500 
501 	if (sd->autogain_ignore_frames > 0)
502 		sd->autogain_ignore_frames--;
503 	else if (gspca_coarse_grained_expo_autogain(gspca_dev, avg_lum,
504 						    desired_lum, deadzone))
505 		sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES;
506 }
507 
508 /* JPEG header, part 1 */
509 static const unsigned char pac_jpeg_header1[] = {
510   0xff, 0xd8,		/* SOI: Start of Image */
511 
512   0xff, 0xc0,		/* SOF0: Start of Frame (Baseline DCT) */
513   0x00, 0x11,		/* length = 17 bytes (including this length field) */
514   0x08			/* Precision: 8 */
515   /* 2 bytes is placed here: number of image lines */
516   /* 2 bytes is placed here: samples per line */
517 };
518 
519 /* JPEG header, continued */
520 static const unsigned char pac_jpeg_header2[] = {
521   0x03,			/* Number of image components: 3 */
522   0x01, 0x21, 0x00,	/* ID=1, Subsampling 1x1, Quantization table: 0 */
523   0x02, 0x11, 0x01,	/* ID=2, Subsampling 2x1, Quantization table: 1 */
524   0x03, 0x11, 0x01,	/* ID=3, Subsampling 2x1, Quantization table: 1 */
525 
526   0xff, 0xda,		/* SOS: Start Of Scan */
527   0x00, 0x0c,		/* length = 12 bytes (including this length field) */
528   0x03,			/* number of components: 3 */
529   0x01, 0x00,		/* selector 1, table 0x00 */
530   0x02, 0x11,		/* selector 2, table 0x11 */
531   0x03, 0x11,		/* selector 3, table 0x11 */
532   0x00, 0x3f,		/* Spectral selection: 0 .. 63 */
533   0x00			/* Successive approximation: 0 */
534 };
535 
pac_start_frame(struct gspca_dev * gspca_dev,__u16 lines,__u16 samples_per_line)536 static void pac_start_frame(struct gspca_dev *gspca_dev,
537 		__u16 lines, __u16 samples_per_line)
538 {
539 	unsigned char tmpbuf[4];
540 
541 	gspca_frame_add(gspca_dev, FIRST_PACKET,
542 		pac_jpeg_header1, sizeof(pac_jpeg_header1));
543 
544 	tmpbuf[0] = lines >> 8;
545 	tmpbuf[1] = lines & 0xff;
546 	tmpbuf[2] = samples_per_line >> 8;
547 	tmpbuf[3] = samples_per_line & 0xff;
548 
549 	gspca_frame_add(gspca_dev, INTER_PACKET,
550 		tmpbuf, sizeof(tmpbuf));
551 	gspca_frame_add(gspca_dev, INTER_PACKET,
552 		pac_jpeg_header2, sizeof(pac_jpeg_header2));
553 }
554 
555 /* this function is run at interrupt level */
sd_pkt_scan(struct gspca_dev * gspca_dev,u8 * data,int len)556 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
557 			u8 *data,			/* isoc packet */
558 			int len)			/* iso packet length */
559 {
560 	struct sd *sd = (struct sd *) gspca_dev;
561 	u8 *image;
562 	unsigned char *sof;
563 
564 	sof = pac_find_sof(gspca_dev, &sd->sof_read, data, len);
565 	if (sof) {
566 		int n, lum_offset, footer_length;
567 
568 		/*
569 		 * 6 bytes after the FF D9 EOF marker a number of lumination
570 		 * bytes are send corresponding to different parts of the
571 		 * image, the 14th and 15th byte after the EOF seem to
572 		 * correspond to the center of the image.
573 		 */
574 		lum_offset = 24 + sizeof pac_sof_marker;
575 		footer_length = 26;
576 
577 		/* Finish decoding current frame */
578 		n = (sof - data) - (footer_length + sizeof pac_sof_marker);
579 		if (n < 0) {
580 			gspca_dev->image_len += n;
581 			n = 0;
582 		} else {
583 			gspca_frame_add(gspca_dev, INTER_PACKET, data, n);
584 		}
585 		image = gspca_dev->image;
586 		if (image != NULL
587 		 && image[gspca_dev->image_len - 2] == 0xff
588 		 && image[gspca_dev->image_len - 1] == 0xd9)
589 			gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
590 
591 		n = sof - data;
592 		len -= n;
593 		data = sof;
594 
595 		/* Get average lumination */
596 		if (gspca_dev->last_packet_type == LAST_PACKET &&
597 				n >= lum_offset)
598 			atomic_set(&sd->avg_lum, data[-lum_offset] +
599 						data[-lum_offset + 1]);
600 		else
601 			atomic_set(&sd->avg_lum, -1);
602 
603 		/* Start the new frame with the jpeg header */
604 		pac_start_frame(gspca_dev,
605 			gspca_dev->pixfmt.height, gspca_dev->pixfmt.width);
606 	}
607 	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
608 }
609 
610 #if IS_ENABLED(CONFIG_INPUT)
sd_int_pkt_scan(struct gspca_dev * gspca_dev,u8 * data,int len)611 static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
612 			u8 *data,		/* interrupt packet data */
613 			int len)		/* interrupt packet length */
614 {
615 	int ret = -EINVAL;
616 	u8 data0, data1;
617 
618 	if (len == 2) {
619 		data0 = data[0];
620 		data1 = data[1];
621 		if ((data0 == 0x00 && data1 == 0x11) ||
622 		    (data0 == 0x22 && data1 == 0x33) ||
623 		    (data0 == 0x44 && data1 == 0x55) ||
624 		    (data0 == 0x66 && data1 == 0x77) ||
625 		    (data0 == 0x88 && data1 == 0x99) ||
626 		    (data0 == 0xaa && data1 == 0xbb) ||
627 		    (data0 == 0xcc && data1 == 0xdd) ||
628 		    (data0 == 0xee && data1 == 0xff)) {
629 			input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
630 			input_sync(gspca_dev->input_dev);
631 			input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
632 			input_sync(gspca_dev->input_dev);
633 			ret = 0;
634 		}
635 	}
636 
637 	return ret;
638 }
639 #endif
640 
641 static const struct sd_desc sd_desc = {
642 	.name = MODULE_NAME,
643 	.config = sd_config,
644 	.init = sd_init,
645 	.init_controls = sd_init_controls,
646 	.start = sd_start,
647 	.stopN = sd_stopN,
648 	.pkt_scan = sd_pkt_scan,
649 	.dq_callback = do_autogain,
650 #if IS_ENABLED(CONFIG_INPUT)
651 	.int_pkt_scan = sd_int_pkt_scan,
652 #endif
653 };
654 
655 /* -- module initialisation -- */
656 static const struct usb_device_id device_table[] = {
657 	{USB_DEVICE(0x093a, 0x2600)},
658 	{USB_DEVICE(0x093a, 0x2601)},
659 	{USB_DEVICE(0x093a, 0x2603)},
660 	{USB_DEVICE(0x093a, 0x2608)},
661 	{USB_DEVICE(0x093a, 0x260e)},
662 	{USB_DEVICE(0x093a, 0x260f)},
663 	{}
664 };
665 MODULE_DEVICE_TABLE(usb, device_table);
666 
667 /* -- device connect -- */
sd_probe(struct usb_interface * intf,const struct usb_device_id * id)668 static int sd_probe(struct usb_interface *intf,
669 			const struct usb_device_id *id)
670 {
671 	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
672 				THIS_MODULE);
673 }
674 
675 static struct usb_driver sd_driver = {
676 	.name = MODULE_NAME,
677 	.id_table = device_table,
678 	.probe = sd_probe,
679 	.disconnect = gspca_disconnect,
680 #ifdef CONFIG_PM
681 	.suspend = gspca_suspend,
682 	.resume = gspca_resume,
683 	.reset_resume = gspca_resume,
684 #endif
685 };
686 
687 module_usb_driver(sd_driver);
688