xref: /linux/drivers/media/usb/gspca/pac7302.c (revision ebf68996de0ab250c5d520eb2291ab65643e9a1e)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Pixart PAC7302 driver
4  *
5  * Copyright (C) 2008-2012 Jean-Francois Moine <http://moinejf.free.fr>
6  * Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li
7  *
8  * Separated from Pixart PAC7311 library by Márton Németh
9  * Camera button input handling by Márton Németh <nm127@freemail.hu>
10  * Copyright (C) 2009-2010 Márton Németh <nm127@freemail.hu>
11  */
12 
13 /*
14  * Some documentation about various registers as determined by trial and error.
15  *
16  * Register page 0:
17  *
18  * Address	Description
19  * 0x01		Red balance control
20  * 0x02		Green balance control
21  * 0x03		Blue balance control
22  *		     The Windows driver uses a quadratic approach to map
23  *		     the settable values (0-200) on register values:
24  *		     min=0x20, default=0x40, max=0x80
25  * 0x0f-0x20	Color and saturation control
26  * 0xa2-0xab	Brightness, contrast and gamma control
27  * 0xb6		Sharpness control (bits 0-4)
28  *
29  * Register page 1:
30  *
31  * Address	Description
32  * 0x78		Global control, bit 6 controls the LED (inverted)
33  * 0x80		Compression balance, 2 interesting settings:
34  *		0x0f Default
35  *		0x50 Values >= this switch the camera to a lower compression,
36  *		     using the same table for both luminance and chrominance.
37  *		     This gives a sharper picture. Only usable when running
38  *		     at < 15 fps! Note currently the driver does not use this
39  *		     as the quality gain is small and the generated JPG-s are
40  *		     only understood by v4l-utils >= 0.8.9
41  *
42  * Register page 3:
43  *
44  * Address	Description
45  * 0x02		Clock divider 3-63, fps = 90 / val. Must be a multiple of 3 on
46  *		the 7302, so one of 3, 6, 9, ..., except when between 6 and 12?
47  * 0x03		Variable framerate ctrl reg2==3: 0 -> ~30 fps, 255 -> ~22fps
48  * 0x04		Another var framerate ctrl reg2==3, reg3==0: 0 -> ~30 fps,
49  *		63 -> ~27 fps, the 2 msb's must always be 1 !!
50  * 0x05		Another var framerate ctrl reg2==3, reg3==0, reg4==0xc0:
51  *		1 -> ~30 fps, 2 -> ~20 fps
52  * 0x0e		Exposure bits 0-7, 0-448, 0 = use full frame time
53  * 0x0f		Exposure bit 8, 0-448, 448 = no exposure at all
54  * 0x10		Gain 0-31
55  * 0x12		Another gain 0-31, unlike 0x10 this one seems to start with an
56  *		amplification value of 1 rather then 0 at its lowest setting
57  * 0x21		Bitfield: 0-1 unused, 2-3 vflip/hflip, 4-5 unknown, 6-7 unused
58  * 0x80		Another framerate control, best left at 1, moving it from 1 to
59  *		2 causes the framerate to become 3/4th of what it was, and
60  *		also seems to cause pixel averaging, resulting in an effective
61  *		resolution of 320x240 and thus a much blockier image
62  *
63  * The registers are accessed in the following functions:
64  *
65  * Page | Register   | Function
66  * -----+------------+---------------------------------------------------
67  *  0   | 0x01       | setredbalance()
68  *  0   | 0x03       | setbluebalance()
69  *  0   | 0x0f..0x20 | setcolors()
70  *  0   | 0xa2..0xab | setbrightcont()
71  *  0   | 0xb6       | setsharpness()
72  *  0   | 0xc6       | setwhitebalance()
73  *  0   | 0xdc       | setbrightcont(), setcolors()
74  *  3   | 0x02       | setexposure()
75  *  3   | 0x10, 0x12 | setgain()
76  *  3   | 0x11       | setcolors(), setgain(), setexposure(), sethvflip()
77  *  3   | 0x21       | sethvflip()
78  */
79 
80 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
81 
82 #include <linux/input.h>
83 #include "gspca.h"
84 /* Include pac common sof detection functions */
85 #include "pac_common.h"
86 
87 #define PAC7302_RGB_BALANCE_MIN		  0
88 #define PAC7302_RGB_BALANCE_MAX		200
89 #define PAC7302_RGB_BALANCE_DEFAULT	100
90 #define PAC7302_GAIN_DEFAULT		 15
91 #define PAC7302_GAIN_KNEE		 42
92 #define PAC7302_EXPOSURE_DEFAULT	 66 /* 33 ms / 30 fps */
93 #define PAC7302_EXPOSURE_KNEE		133 /* 66 ms / 15 fps */
94 
95 MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>, Thomas Kaiser thomas@kaiser-linux.li");
96 MODULE_DESCRIPTION("Pixart PAC7302");
97 MODULE_LICENSE("GPL");
98 
99 struct sd {
100 	struct gspca_dev gspca_dev;		/* !! must be the first item */
101 
102 	struct { /* brightness / contrast cluster */
103 		struct v4l2_ctrl *brightness;
104 		struct v4l2_ctrl *contrast;
105 	};
106 	struct v4l2_ctrl *saturation;
107 	struct v4l2_ctrl *white_balance;
108 	struct v4l2_ctrl *red_balance;
109 	struct v4l2_ctrl *blue_balance;
110 	struct { /* flip cluster */
111 		struct v4l2_ctrl *hflip;
112 		struct v4l2_ctrl *vflip;
113 	};
114 	struct v4l2_ctrl *sharpness;
115 	u8 flags;
116 #define FL_HFLIP 0x01		/* mirrored by default */
117 #define FL_VFLIP 0x02		/* vertical flipped by default */
118 
119 	u8 sof_read;
120 	s8 autogain_ignore_frames;
121 
122 	atomic_t avg_lum;
123 };
124 
125 static const struct v4l2_pix_format vga_mode[] = {
126 	{640, 480, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
127 		.bytesperline = 640,
128 		.sizeimage = 640 * 480 * 3 / 8 + 590,
129 		.colorspace = V4L2_COLORSPACE_JPEG,
130 	},
131 };
132 
133 #define LOAD_PAGE3		255
134 #define END_OF_SEQUENCE		0
135 
136 static const u8 init_7302[] = {
137 /*	index,value */
138 	0xff, 0x01,		/* page 1 */
139 	0x78, 0x00,		/* deactivate */
140 	0xff, 0x01,
141 	0x78, 0x40,		/* led off */
142 };
143 static const u8 start_7302[] = {
144 /*	index, len, [value]* */
145 	0xff, 1,	0x00,		/* page 0 */
146 	0x00, 12,	0x01, 0x40, 0x40, 0x40, 0x01, 0xe0, 0x02, 0x80,
147 			0x00, 0x00, 0x00, 0x00,
148 	0x0d, 24,	0x03, 0x01, 0x00, 0xb5, 0x07, 0xcb, 0x00, 0x00,
149 			0x07, 0xc8, 0x00, 0xea, 0x07, 0xcf, 0x07, 0xf7,
150 			0x07, 0x7e, 0x01, 0x0b, 0x00, 0x00, 0x00, 0x11,
151 	0x26, 2,	0xaa, 0xaa,
152 	0x2e, 1,	0x31,
153 	0x38, 1,	0x01,
154 	0x3a, 3,	0x14, 0xff, 0x5a,
155 	0x43, 11,	0x00, 0x0a, 0x18, 0x11, 0x01, 0x2c, 0x88, 0x11,
156 			0x00, 0x54, 0x11,
157 	0x55, 1,	0x00,
158 	0x62, 4,	0x10, 0x1e, 0x1e, 0x18,
159 	0x6b, 1,	0x00,
160 	0x6e, 3,	0x08, 0x06, 0x00,
161 	0x72, 3,	0x00, 0xff, 0x00,
162 	0x7d, 23,	0x01, 0x01, 0x58, 0x46, 0x50, 0x3c, 0x50, 0x3c,
163 			0x54, 0x46, 0x54, 0x56, 0x52, 0x50, 0x52, 0x50,
164 			0x56, 0x64, 0xa4, 0x00, 0xda, 0x00, 0x00,
165 	0xa2, 10,	0x22, 0x2c, 0x3c, 0x54, 0x69, 0x7c, 0x9c, 0xb9,
166 			0xd2, 0xeb,
167 	0xaf, 1,	0x02,
168 	0xb5, 2,	0x08, 0x08,
169 	0xb8, 2,	0x08, 0x88,
170 	0xc4, 4,	0xae, 0x01, 0x04, 0x01,
171 	0xcc, 1,	0x00,
172 	0xd1, 11,	0x01, 0x30, 0x49, 0x5e, 0x6f, 0x7f, 0x8e, 0xa9,
173 			0xc1, 0xd7, 0xec,
174 	0xdc, 1,	0x01,
175 	0xff, 1,	0x01,		/* page 1 */
176 	0x12, 3,	0x02, 0x00, 0x01,
177 	0x3e, 2,	0x00, 0x00,
178 	0x76, 5,	0x01, 0x20, 0x40, 0x00, 0xf2,
179 	0x7c, 1,	0x00,
180 	0x7f, 10,	0x4b, 0x0f, 0x01, 0x2c, 0x02, 0x58, 0x03, 0x20,
181 			0x02, 0x00,
182 	0x96, 5,	0x01, 0x10, 0x04, 0x01, 0x04,
183 	0xc8, 14,	0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
184 			0x07, 0x00, 0x01, 0x07, 0x04, 0x01,
185 	0xd8, 1,	0x01,
186 	0xdb, 2,	0x00, 0x01,
187 	0xde, 7,	0x00, 0x01, 0x04, 0x04, 0x00, 0x00, 0x00,
188 	0xe6, 4,	0x00, 0x00, 0x00, 0x01,
189 	0xeb, 1,	0x00,
190 	0xff, 1,	0x02,		/* page 2 */
191 	0x22, 1,	0x00,
192 	0xff, 1,	0x03,		/* page 3 */
193 	0, LOAD_PAGE3,			/* load the page 3 */
194 	0x11, 1,	0x01,
195 	0xff, 1,	0x02,		/* page 2 */
196 	0x13, 1,	0x00,
197 	0x22, 4,	0x1f, 0xa4, 0xf0, 0x96,
198 	0x27, 2,	0x14, 0x0c,
199 	0x2a, 5,	0xc8, 0x00, 0x18, 0x12, 0x22,
200 	0x64, 8,	0x00, 0x00, 0xf0, 0x01, 0x14, 0x44, 0x44, 0x44,
201 	0x6e, 1,	0x08,
202 	0xff, 1,	0x01,		/* page 1 */
203 	0x78, 1,	0x00,
204 	0, END_OF_SEQUENCE		/* end of sequence */
205 };
206 
207 #define SKIP		0xaa
208 /* page 3 - the value SKIP says skip the index - see reg_w_page() */
209 static const u8 page3_7302[] = {
210 	0x90, 0x40, 0x03, 0x00, 0xc0, 0x01, 0x14, 0x16,
211 	0x14, 0x12, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00,
212 	0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
213 	0x00, 0x00, 0x00, 0x47, 0x01, 0xb3, 0x01, 0x00,
214 	0x00, 0x08, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x21,
215 	0x00, 0x00, 0x00, 0x54, 0xf4, 0x02, 0x52, 0x54,
216 	0xa4, 0xb8, 0xe0, 0x2a, 0xf6, 0x00, 0x00, 0x00,
217 	0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
218 	0x00, 0xfc, 0x00, 0xf2, 0x1f, 0x04, 0x00, 0x00,
219 	SKIP, 0x00, 0x00, 0xc0, 0xc0, 0x10, 0x00, 0x00,
220 	0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
221 	0x00, 0x40, 0xff, 0x03, 0x19, 0x00, 0x00, 0x00,
222 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
223 	0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc8, 0xc8,
224 	0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
225 	0x08, 0x10, 0x24, 0x40, 0x00, 0x00, 0x00, 0x00,
226 	0x01, 0x00, 0x02, 0x47, 0x00, 0x00, 0x00, 0x00,
227 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
228 	0x00, 0x02, 0xfa, 0x00, 0x64, 0x5a, 0x28, 0x00,
229 	0x00
230 };
231 
232 static void reg_w_buf(struct gspca_dev *gspca_dev,
233 		u8 index,
234 		  const u8 *buffer, int len)
235 {
236 	int ret;
237 
238 	if (gspca_dev->usb_err < 0)
239 		return;
240 	memcpy(gspca_dev->usb_buf, buffer, len);
241 	ret = usb_control_msg(gspca_dev->dev,
242 			usb_sndctrlpipe(gspca_dev->dev, 0),
243 			0,		/* request */
244 			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
245 			0,		/* value */
246 			index, gspca_dev->usb_buf, len,
247 			500);
248 	if (ret < 0) {
249 		pr_err("reg_w_buf failed i: %02x error %d\n",
250 		       index, ret);
251 		gspca_dev->usb_err = ret;
252 	}
253 }
254 
255 
256 static void reg_w(struct gspca_dev *gspca_dev,
257 		u8 index,
258 		u8 value)
259 {
260 	int ret;
261 
262 	if (gspca_dev->usb_err < 0)
263 		return;
264 	gspca_dev->usb_buf[0] = value;
265 	ret = usb_control_msg(gspca_dev->dev,
266 			usb_sndctrlpipe(gspca_dev->dev, 0),
267 			0,			/* request */
268 			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
269 			0, index, gspca_dev->usb_buf, 1,
270 			500);
271 	if (ret < 0) {
272 		pr_err("reg_w() failed i: %02x v: %02x error %d\n",
273 		       index, value, ret);
274 		gspca_dev->usb_err = ret;
275 	}
276 }
277 
278 static void reg_w_seq(struct gspca_dev *gspca_dev,
279 		const u8 *seq, int len)
280 {
281 	while (--len >= 0) {
282 		reg_w(gspca_dev, seq[0], seq[1]);
283 		seq += 2;
284 	}
285 }
286 
287 /* load the beginning of a page */
288 static void reg_w_page(struct gspca_dev *gspca_dev,
289 			const u8 *page, int len)
290 {
291 	int index;
292 	int ret = 0;
293 
294 	if (gspca_dev->usb_err < 0)
295 		return;
296 	for (index = 0; index < len; index++) {
297 		if (page[index] == SKIP)		/* skip this index */
298 			continue;
299 		gspca_dev->usb_buf[0] = page[index];
300 		ret = usb_control_msg(gspca_dev->dev,
301 				usb_sndctrlpipe(gspca_dev->dev, 0),
302 				0,			/* request */
303 			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
304 				0, index, gspca_dev->usb_buf, 1,
305 				500);
306 		if (ret < 0) {
307 			pr_err("reg_w_page() failed i: %02x v: %02x error %d\n",
308 			       index, page[index], ret);
309 			gspca_dev->usb_err = ret;
310 			break;
311 		}
312 	}
313 }
314 
315 /* output a variable sequence */
316 static void reg_w_var(struct gspca_dev *gspca_dev,
317 			const u8 *seq,
318 			const u8 *page3, unsigned int page3_len)
319 {
320 	int index, len;
321 
322 	for (;;) {
323 		index = *seq++;
324 		len = *seq++;
325 		switch (len) {
326 		case END_OF_SEQUENCE:
327 			return;
328 		case LOAD_PAGE3:
329 			reg_w_page(gspca_dev, page3, page3_len);
330 			break;
331 		default:
332 			if (len > USB_BUF_SZ) {
333 				gspca_err(gspca_dev, "Incorrect variable sequence\n");
334 				return;
335 			}
336 			while (len > 0) {
337 				if (len < 8) {
338 					reg_w_buf(gspca_dev,
339 						index, seq, len);
340 					seq += len;
341 					break;
342 				}
343 				reg_w_buf(gspca_dev, index, seq, 8);
344 				seq += 8;
345 				index += 8;
346 				len -= 8;
347 			}
348 		}
349 	}
350 	/* not reached */
351 }
352 
353 /* this function is called at probe time for pac7302 */
354 static int sd_config(struct gspca_dev *gspca_dev,
355 			const struct usb_device_id *id)
356 {
357 	struct sd *sd = (struct sd *) gspca_dev;
358 	struct cam *cam;
359 
360 	cam = &gspca_dev->cam;
361 
362 	cam->cam_mode = vga_mode;	/* only 640x480 */
363 	cam->nmodes = ARRAY_SIZE(vga_mode);
364 
365 	sd->flags = id->driver_info;
366 	return 0;
367 }
368 
369 static void setbrightcont(struct gspca_dev *gspca_dev)
370 {
371 	struct sd *sd = (struct sd *) gspca_dev;
372 	int i, v;
373 	static const u8 max[10] =
374 		{0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb,
375 		 0xd4, 0xec};
376 	static const u8 delta[10] =
377 		{0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17,
378 		 0x11, 0x0b};
379 
380 	reg_w(gspca_dev, 0xff, 0x00);		/* page 0 */
381 	for (i = 0; i < 10; i++) {
382 		v = max[i];
383 		v += (sd->brightness->val - (s32)sd->brightness->maximum)
384 			* 150 / (s32)sd->brightness->maximum; /* 200 ? */
385 		v -= delta[i] * sd->contrast->val / (s32)sd->contrast->maximum;
386 		if (v < 0)
387 			v = 0;
388 		else if (v > 0xff)
389 			v = 0xff;
390 		reg_w(gspca_dev, 0xa2 + i, v);
391 	}
392 	reg_w(gspca_dev, 0xdc, 0x01);
393 }
394 
395 static void setcolors(struct gspca_dev *gspca_dev)
396 {
397 	struct sd *sd = (struct sd *) gspca_dev;
398 	int i, v;
399 	static const int a[9] =
400 		{217, -212, 0, -101, 170, -67, -38, -315, 355};
401 	static const int b[9] =
402 		{19, 106, 0, 19, 106, 1, 19, 106, 1};
403 
404 	reg_w(gspca_dev, 0xff, 0x03);			/* page 3 */
405 	reg_w(gspca_dev, 0x11, 0x01);
406 	reg_w(gspca_dev, 0xff, 0x00);			/* page 0 */
407 	for (i = 0; i < 9; i++) {
408 		v = a[i] * sd->saturation->val / (s32)sd->saturation->maximum;
409 		v += b[i];
410 		reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07);
411 		reg_w(gspca_dev, 0x0f + 2 * i + 1, v);
412 	}
413 	reg_w(gspca_dev, 0xdc, 0x01);
414 }
415 
416 static void setwhitebalance(struct gspca_dev *gspca_dev)
417 {
418 	struct sd *sd = (struct sd *) gspca_dev;
419 
420 	reg_w(gspca_dev, 0xff, 0x00);		/* page 0 */
421 	reg_w(gspca_dev, 0xc6, sd->white_balance->val);
422 
423 	reg_w(gspca_dev, 0xdc, 0x01);
424 }
425 
426 static u8 rgbbalance_ctrl_to_reg_value(s32 rgb_ctrl_val)
427 {
428 	const unsigned int k = 1000;	/* precision factor */
429 	unsigned int norm;
430 
431 	/* Normed value [0...k] */
432 	norm = k * (rgb_ctrl_val - PAC7302_RGB_BALANCE_MIN)
433 		    / (PAC7302_RGB_BALANCE_MAX - PAC7302_RGB_BALANCE_MIN);
434 	/* Qudratic apporach improves control at small (register) values: */
435 	return 64 * norm * norm / (k*k)  +  32 * norm / k  +  32;
436 	/* Y = 64*X*X + 32*X + 32
437 	 * => register values 0x20-0x80; Windows driver uses these limits */
438 
439 	/* NOTE: for full value range (0x00-0xff) use
440 	 *         Y = 254*X*X + X
441 	 *         => 254 * norm * norm / (k*k)  +  1 * norm / k	*/
442 }
443 
444 static void setredbalance(struct gspca_dev *gspca_dev)
445 {
446 	struct sd *sd = (struct sd *) gspca_dev;
447 
448 	reg_w(gspca_dev, 0xff, 0x00);			/* page 0 */
449 	reg_w(gspca_dev, 0x01,
450 	      rgbbalance_ctrl_to_reg_value(sd->red_balance->val));
451 
452 	reg_w(gspca_dev, 0xdc, 0x01);
453 }
454 
455 static void setbluebalance(struct gspca_dev *gspca_dev)
456 {
457 	struct sd *sd = (struct sd *) gspca_dev;
458 
459 	reg_w(gspca_dev, 0xff, 0x00);			/* page 0 */
460 	reg_w(gspca_dev, 0x03,
461 	      rgbbalance_ctrl_to_reg_value(sd->blue_balance->val));
462 
463 	reg_w(gspca_dev, 0xdc, 0x01);
464 }
465 
466 static void setgain(struct gspca_dev *gspca_dev)
467 {
468 	u8 reg10, reg12;
469 
470 	if (gspca_dev->gain->val < 32) {
471 		reg10 = gspca_dev->gain->val;
472 		reg12 = 0;
473 	} else {
474 		reg10 = 31;
475 		reg12 = gspca_dev->gain->val - 31;
476 	}
477 
478 	reg_w(gspca_dev, 0xff, 0x03);			/* page 3 */
479 	reg_w(gspca_dev, 0x10, reg10);
480 	reg_w(gspca_dev, 0x12, reg12);
481 
482 	/* load registers to sensor (Bit 0, auto clear) */
483 	reg_w(gspca_dev, 0x11, 0x01);
484 }
485 
486 static void setexposure(struct gspca_dev *gspca_dev)
487 {
488 	u8 clockdiv;
489 	u16 exposure;
490 
491 	/*
492 	 * Register 2 of frame 3 contains the clock divider configuring the
493 	 * no fps according to the formula: 90 / reg. sd->exposure is the
494 	 * desired exposure time in 0.5 ms.
495 	 */
496 	clockdiv = (90 * gspca_dev->exposure->val + 1999) / 2000;
497 
498 	/*
499 	 * Note clockdiv = 3 also works, but when running at 30 fps, depending
500 	 * on the scene being recorded, the camera switches to another
501 	 * quantization table for certain JPEG blocks, and we don't know how
502 	 * to decompress these blocks. So we cap the framerate at 15 fps.
503 	 */
504 	if (clockdiv < 6)
505 		clockdiv = 6;
506 	else if (clockdiv > 63)
507 		clockdiv = 63;
508 
509 	/*
510 	 * Register 2 MUST be a multiple of 3, except when between 6 and 12?
511 	 * Always round up, otherwise we cannot get the desired frametime
512 	 * using the partial frame time exposure control.
513 	 */
514 	if (clockdiv < 6 || clockdiv > 12)
515 		clockdiv = ((clockdiv + 2) / 3) * 3;
516 
517 	/*
518 	 * frame exposure time in ms = 1000 * clockdiv / 90    ->
519 	 * exposure = (sd->exposure / 2) * 448 / (1000 * clockdiv / 90)
520 	 */
521 	exposure = (gspca_dev->exposure->val * 45 * 448) / (1000 * clockdiv);
522 	/* 0 = use full frametime, 448 = no exposure, reverse it */
523 	exposure = 448 - exposure;
524 
525 	reg_w(gspca_dev, 0xff, 0x03);			/* page 3 */
526 	reg_w(gspca_dev, 0x02, clockdiv);
527 	reg_w(gspca_dev, 0x0e, exposure & 0xff);
528 	reg_w(gspca_dev, 0x0f, exposure >> 8);
529 
530 	/* load registers to sensor (Bit 0, auto clear) */
531 	reg_w(gspca_dev, 0x11, 0x01);
532 }
533 
534 static void sethvflip(struct gspca_dev *gspca_dev)
535 {
536 	struct sd *sd = (struct sd *) gspca_dev;
537 	u8 data, hflip, vflip;
538 
539 	hflip = sd->hflip->val;
540 	if (sd->flags & FL_HFLIP)
541 		hflip = !hflip;
542 	vflip = sd->vflip->val;
543 	if (sd->flags & FL_VFLIP)
544 		vflip = !vflip;
545 
546 	reg_w(gspca_dev, 0xff, 0x03);			/* page 3 */
547 	data = (hflip ? 0x08 : 0x00) | (vflip ? 0x04 : 0x00);
548 	reg_w(gspca_dev, 0x21, data);
549 
550 	/* load registers to sensor (Bit 0, auto clear) */
551 	reg_w(gspca_dev, 0x11, 0x01);
552 }
553 
554 static void setsharpness(struct gspca_dev *gspca_dev)
555 {
556 	struct sd *sd = (struct sd *) gspca_dev;
557 
558 	reg_w(gspca_dev, 0xff, 0x00);		/* page 0 */
559 	reg_w(gspca_dev, 0xb6, sd->sharpness->val);
560 
561 	reg_w(gspca_dev, 0xdc, 0x01);
562 }
563 
564 /* this function is called at probe and resume time for pac7302 */
565 static int sd_init(struct gspca_dev *gspca_dev)
566 {
567 	reg_w_seq(gspca_dev, init_7302, sizeof(init_7302)/2);
568 	return gspca_dev->usb_err;
569 }
570 
571 static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
572 {
573 	struct gspca_dev *gspca_dev =
574 		container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
575 	struct sd *sd = (struct sd *)gspca_dev;
576 
577 	gspca_dev->usb_err = 0;
578 
579 	if (ctrl->id == V4L2_CID_AUTOGAIN && ctrl->is_new && ctrl->val) {
580 		/* when switching to autogain set defaults to make sure
581 		   we are on a valid point of the autogain gain /
582 		   exposure knee graph, and give this change time to
583 		   take effect before doing autogain. */
584 		gspca_dev->exposure->val    = PAC7302_EXPOSURE_DEFAULT;
585 		gspca_dev->gain->val        = PAC7302_GAIN_DEFAULT;
586 		sd->autogain_ignore_frames  = PAC_AUTOGAIN_IGNORE_FRAMES;
587 	}
588 
589 	if (!gspca_dev->streaming)
590 		return 0;
591 
592 	switch (ctrl->id) {
593 	case V4L2_CID_BRIGHTNESS:
594 		setbrightcont(gspca_dev);
595 		break;
596 	case V4L2_CID_SATURATION:
597 		setcolors(gspca_dev);
598 		break;
599 	case V4L2_CID_WHITE_BALANCE_TEMPERATURE:
600 		setwhitebalance(gspca_dev);
601 		break;
602 	case V4L2_CID_RED_BALANCE:
603 		setredbalance(gspca_dev);
604 		break;
605 	case V4L2_CID_BLUE_BALANCE:
606 		setbluebalance(gspca_dev);
607 		break;
608 	case V4L2_CID_AUTOGAIN:
609 		if (gspca_dev->exposure->is_new || (ctrl->is_new && ctrl->val))
610 			setexposure(gspca_dev);
611 		if (gspca_dev->gain->is_new || (ctrl->is_new && ctrl->val))
612 			setgain(gspca_dev);
613 		break;
614 	case V4L2_CID_HFLIP:
615 		sethvflip(gspca_dev);
616 		break;
617 	case V4L2_CID_SHARPNESS:
618 		setsharpness(gspca_dev);
619 		break;
620 	default:
621 		return -EINVAL;
622 	}
623 	return gspca_dev->usb_err;
624 }
625 
626 static const struct v4l2_ctrl_ops sd_ctrl_ops = {
627 	.s_ctrl = sd_s_ctrl,
628 };
629 
630 /* this function is called at probe time */
631 static int sd_init_controls(struct gspca_dev *gspca_dev)
632 {
633 	struct sd *sd = (struct sd *) gspca_dev;
634 	struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
635 
636 	gspca_dev->vdev.ctrl_handler = hdl;
637 	v4l2_ctrl_handler_init(hdl, 12);
638 
639 	sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
640 					V4L2_CID_BRIGHTNESS, 0, 32, 1, 16);
641 	sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
642 					V4L2_CID_CONTRAST, 0, 255, 1, 127);
643 
644 	sd->saturation = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
645 					V4L2_CID_SATURATION, 0, 255, 1, 127);
646 	sd->white_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
647 					V4L2_CID_WHITE_BALANCE_TEMPERATURE,
648 					0, 255, 1, 55);
649 	sd->red_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
650 					V4L2_CID_RED_BALANCE,
651 					PAC7302_RGB_BALANCE_MIN,
652 					PAC7302_RGB_BALANCE_MAX,
653 					1, PAC7302_RGB_BALANCE_DEFAULT);
654 	sd->blue_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
655 					V4L2_CID_BLUE_BALANCE,
656 					PAC7302_RGB_BALANCE_MIN,
657 					PAC7302_RGB_BALANCE_MAX,
658 					1, PAC7302_RGB_BALANCE_DEFAULT);
659 
660 	gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
661 					V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
662 	gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
663 					V4L2_CID_EXPOSURE, 0, 1023, 1,
664 					PAC7302_EXPOSURE_DEFAULT);
665 	gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
666 					V4L2_CID_GAIN, 0, 62, 1,
667 					PAC7302_GAIN_DEFAULT);
668 
669 	sd->hflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
670 		V4L2_CID_HFLIP, 0, 1, 1, 0);
671 	sd->vflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
672 		V4L2_CID_VFLIP, 0, 1, 1, 0);
673 
674 	sd->sharpness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
675 					V4L2_CID_SHARPNESS, 0, 15, 1, 8);
676 
677 	if (hdl->error) {
678 		pr_err("Could not initialize controls\n");
679 		return hdl->error;
680 	}
681 
682 	v4l2_ctrl_cluster(2, &sd->brightness);
683 	v4l2_ctrl_auto_cluster(3, &gspca_dev->autogain, 0, false);
684 	v4l2_ctrl_cluster(2, &sd->hflip);
685 	return 0;
686 }
687 
688 /* -- start the camera -- */
689 static int sd_start(struct gspca_dev *gspca_dev)
690 {
691 	struct sd *sd = (struct sd *) gspca_dev;
692 
693 	reg_w_var(gspca_dev, start_7302,
694 		page3_7302, sizeof(page3_7302));
695 
696 	sd->sof_read = 0;
697 	sd->autogain_ignore_frames = 0;
698 	atomic_set(&sd->avg_lum, 270 + sd->brightness->val);
699 
700 	/* start stream */
701 	reg_w(gspca_dev, 0xff, 0x01);
702 	reg_w(gspca_dev, 0x78, 0x01);
703 
704 	return gspca_dev->usb_err;
705 }
706 
707 static void sd_stopN(struct gspca_dev *gspca_dev)
708 {
709 
710 	/* stop stream */
711 	reg_w(gspca_dev, 0xff, 0x01);
712 	reg_w(gspca_dev, 0x78, 0x00);
713 }
714 
715 /* called on streamoff with alt 0 and on disconnect for pac7302 */
716 static void sd_stop0(struct gspca_dev *gspca_dev)
717 {
718 	if (!gspca_dev->present)
719 		return;
720 	reg_w(gspca_dev, 0xff, 0x01);
721 	reg_w(gspca_dev, 0x78, 0x40);
722 }
723 
724 static void do_autogain(struct gspca_dev *gspca_dev)
725 {
726 	struct sd *sd = (struct sd *) gspca_dev;
727 	int avg_lum = atomic_read(&sd->avg_lum);
728 	int desired_lum;
729 	const int deadzone = 30;
730 
731 	if (sd->autogain_ignore_frames < 0)
732 		return;
733 
734 	if (sd->autogain_ignore_frames > 0) {
735 		sd->autogain_ignore_frames--;
736 	} else {
737 		desired_lum = 270 + sd->brightness->val;
738 
739 		if (gspca_expo_autogain(gspca_dev, avg_lum, desired_lum,
740 					deadzone, PAC7302_GAIN_KNEE,
741 					PAC7302_EXPOSURE_KNEE))
742 			sd->autogain_ignore_frames =
743 						PAC_AUTOGAIN_IGNORE_FRAMES;
744 	}
745 }
746 
747 /* JPEG header */
748 static const u8 jpeg_header[] = {
749 	0xff, 0xd8,	/* SOI: Start of Image */
750 
751 	0xff, 0xc0,	/* SOF0: Start of Frame (Baseline DCT) */
752 	0x00, 0x11,	/* length = 17 bytes (including this length field) */
753 	0x08,		/* Precision: 8 */
754 	0x02, 0x80,	/* height = 640 (image rotated) */
755 	0x01, 0xe0,	/* width = 480 */
756 	0x03,		/* Number of image components: 3 */
757 	0x01, 0x21, 0x00, /* ID=1, Subsampling 1x1, Quantization table: 0 */
758 	0x02, 0x11, 0x01, /* ID=2, Subsampling 2x1, Quantization table: 1 */
759 	0x03, 0x11, 0x01, /* ID=3, Subsampling 2x1, Quantization table: 1 */
760 
761 	0xff, 0xda,	/* SOS: Start Of Scan */
762 	0x00, 0x0c,	/* length = 12 bytes (including this length field) */
763 	0x03,		/* number of components: 3 */
764 	0x01, 0x00,	/* selector 1, table 0x00 */
765 	0x02, 0x11,	/* selector 2, table 0x11 */
766 	0x03, 0x11,	/* selector 3, table 0x11 */
767 	0x00, 0x3f,	/* Spectral selection: 0 .. 63 */
768 	0x00		/* Successive approximation: 0 */
769 };
770 
771 /* this function is run at interrupt level */
772 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
773 			u8 *data,			/* isoc packet */
774 			int len)			/* iso packet length */
775 {
776 	struct sd *sd = (struct sd *) gspca_dev;
777 	u8 *image;
778 	u8 *sof;
779 
780 	sof = pac_find_sof(gspca_dev, &sd->sof_read, data, len);
781 	if (sof) {
782 		int n, lum_offset, footer_length;
783 
784 		/*
785 		 * 6 bytes after the FF D9 EOF marker a number of lumination
786 		 * bytes are send corresponding to different parts of the
787 		 * image, the 14th and 15th byte after the EOF seem to
788 		 * correspond to the center of the image.
789 		 */
790 		lum_offset = 61 + sizeof pac_sof_marker;
791 		footer_length = 74;
792 
793 		/* Finish decoding current frame */
794 		n = (sof - data) - (footer_length + sizeof pac_sof_marker);
795 		if (n < 0) {
796 			gspca_dev->image_len += n;
797 			n = 0;
798 		} else {
799 			gspca_frame_add(gspca_dev, INTER_PACKET, data, n);
800 		}
801 
802 		image = gspca_dev->image;
803 		if (image != NULL
804 		 && image[gspca_dev->image_len - 2] == 0xff
805 		 && image[gspca_dev->image_len - 1] == 0xd9)
806 			gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
807 
808 		n = sof - data;
809 		len -= n;
810 		data = sof;
811 
812 		/* Get average lumination */
813 		if (gspca_dev->last_packet_type == LAST_PACKET &&
814 				n >= lum_offset)
815 			atomic_set(&sd->avg_lum, data[-lum_offset] +
816 						data[-lum_offset + 1]);
817 
818 		/* Start the new frame with the jpeg header */
819 		/* The PAC7302 has the image rotated 90 degrees */
820 		gspca_frame_add(gspca_dev, FIRST_PACKET,
821 				jpeg_header, sizeof jpeg_header);
822 	}
823 	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
824 }
825 
826 #ifdef CONFIG_VIDEO_ADV_DEBUG
827 static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
828 			const struct v4l2_dbg_register *reg)
829 {
830 	u8 index;
831 	u8 value;
832 
833 	/*
834 	 * reg->reg: bit0..15: reserved for register index (wIndex is 16bit
835 	 *		       long on the USB bus)
836 	 */
837 	if (reg->match.addr == 0 &&
838 	    (reg->reg < 0x000000ff) &&
839 	    (reg->val <= 0x000000ff)
840 	) {
841 		/* Currently writing to page 0 is only supported. */
842 		/* reg_w() only supports 8bit index */
843 		index = reg->reg;
844 		value = reg->val;
845 
846 		/*
847 		 * Note that there shall be no access to other page
848 		 * by any other function between the page switch and
849 		 * the actual register write.
850 		 */
851 		reg_w(gspca_dev, 0xff, 0x00);		/* page 0 */
852 		reg_w(gspca_dev, index, value);
853 
854 		reg_w(gspca_dev, 0xdc, 0x01);
855 	}
856 	return gspca_dev->usb_err;
857 }
858 #endif
859 
860 #if IS_ENABLED(CONFIG_INPUT)
861 static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
862 			u8 *data,		/* interrupt packet data */
863 			int len)		/* interrupt packet length */
864 {
865 	int ret = -EINVAL;
866 	u8 data0, data1;
867 
868 	if (len == 2) {
869 		data0 = data[0];
870 		data1 = data[1];
871 		if ((data0 == 0x00 && data1 == 0x11) ||
872 		    (data0 == 0x22 && data1 == 0x33) ||
873 		    (data0 == 0x44 && data1 == 0x55) ||
874 		    (data0 == 0x66 && data1 == 0x77) ||
875 		    (data0 == 0x88 && data1 == 0x99) ||
876 		    (data0 == 0xaa && data1 == 0xbb) ||
877 		    (data0 == 0xcc && data1 == 0xdd) ||
878 		    (data0 == 0xee && data1 == 0xff)) {
879 			input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
880 			input_sync(gspca_dev->input_dev);
881 			input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
882 			input_sync(gspca_dev->input_dev);
883 			ret = 0;
884 		}
885 	}
886 
887 	return ret;
888 }
889 #endif
890 
891 /* sub-driver description for pac7302 */
892 static const struct sd_desc sd_desc = {
893 	.name = KBUILD_MODNAME,
894 	.config = sd_config,
895 	.init = sd_init,
896 	.init_controls = sd_init_controls,
897 	.start = sd_start,
898 	.stopN = sd_stopN,
899 	.stop0 = sd_stop0,
900 	.pkt_scan = sd_pkt_scan,
901 	.dq_callback = do_autogain,
902 #ifdef CONFIG_VIDEO_ADV_DEBUG
903 	.set_register = sd_dbg_s_register,
904 #endif
905 #if IS_ENABLED(CONFIG_INPUT)
906 	.int_pkt_scan = sd_int_pkt_scan,
907 #endif
908 };
909 
910 /* -- module initialisation -- */
911 static const struct usb_device_id device_table[] = {
912 	{USB_DEVICE(0x06f8, 0x3009)},
913 	{USB_DEVICE(0x06f8, 0x301b)},
914 	{USB_DEVICE(0x093a, 0x2620)},
915 	{USB_DEVICE(0x093a, 0x2621)},
916 	{USB_DEVICE(0x093a, 0x2622), .driver_info = FL_VFLIP},
917 	{USB_DEVICE(0x093a, 0x2623), .driver_info = FL_VFLIP},
918 	{USB_DEVICE(0x093a, 0x2624), .driver_info = FL_VFLIP},
919 	{USB_DEVICE(0x093a, 0x2625)},
920 	{USB_DEVICE(0x093a, 0x2626)},
921 	{USB_DEVICE(0x093a, 0x2627), .driver_info = FL_VFLIP},
922 	{USB_DEVICE(0x093a, 0x2628)},
923 	{USB_DEVICE(0x093a, 0x2629), .driver_info = FL_VFLIP},
924 	{USB_DEVICE(0x093a, 0x262a)},
925 	{USB_DEVICE(0x093a, 0x262c)},
926 	{USB_DEVICE(0x145f, 0x013c)},
927 	{USB_DEVICE(0x1ae7, 0x2001)}, /* SpeedLink Snappy Mic SL-6825-SBK */
928 	{}
929 };
930 MODULE_DEVICE_TABLE(usb, device_table);
931 
932 /* -- device connect -- */
933 static int sd_probe(struct usb_interface *intf,
934 			const struct usb_device_id *id)
935 {
936 	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
937 				THIS_MODULE);
938 }
939 
940 static struct usb_driver sd_driver = {
941 	.name = KBUILD_MODNAME,
942 	.id_table = device_table,
943 	.probe = sd_probe,
944 	.disconnect = gspca_disconnect,
945 #ifdef CONFIG_PM
946 	.suspend = gspca_suspend,
947 	.resume = gspca_resume,
948 	.reset_resume = gspca_resume,
949 #endif
950 };
951 
952 module_usb_driver(sd_driver);
953