1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * T613 subdriver
4 *
5 * Copyright (C) 2010 Jean-Francois Moine (http://moinejf.free.fr)
6 *
7 *Notes: * t613  + tas5130A
8 *	* Focus to light do not balance well as in win.
9 *	  Quality in win is not good, but its kinda better.
10 *	 * Fix some "extraneous bytes", most of apps will show the image anyway
11 *	 * Gamma table, is there, but its really doing something?
12 *	 * 7~8 Fps, its ok, max on win its 10.
13 *			Costantino Leandro
14 */
15
16#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
17
18#define MODULE_NAME "t613"
19
20#include <linux/input.h>
21#include <linux/slab.h>
22#include "gspca.h"
23
24MODULE_AUTHOR("Leandro Costantino <le_costantino@pixartargentina.com.ar>");
25MODULE_DESCRIPTION("GSPCA/T613 (JPEG Compliance) USB Camera Driver");
26MODULE_LICENSE("GPL");
27
28struct sd {
29	struct gspca_dev gspca_dev;	/* !! must be the first item */
30	struct v4l2_ctrl *freq;
31	struct { /* awb / color gains control cluster */
32		struct v4l2_ctrl *awb;
33		struct v4l2_ctrl *gain;
34		struct v4l2_ctrl *red_balance;
35		struct v4l2_ctrl *blue_balance;
36	};
37
38	u8 sensor;
39	u8 button_pressed;
40};
41enum sensors {
42	SENSOR_OM6802,
43	SENSOR_OTHER,
44	SENSOR_TAS5130A,
45	SENSOR_LT168G,		/* must verify if this is the actual model */
46};
47
48static const struct v4l2_pix_format vga_mode_t16[] = {
49	{160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
50		.bytesperline = 160,
51		.sizeimage = 160 * 120 * 4 / 8 + 590,
52		.colorspace = V4L2_COLORSPACE_JPEG,
53		.priv = 4},
54#if 0 /* HDG: broken with my test cam, so lets disable it */
55	{176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
56		.bytesperline = 176,
57		.sizeimage = 176 * 144 * 3 / 8 + 590,
58		.colorspace = V4L2_COLORSPACE_JPEG,
59		.priv = 3},
60#endif
61	{320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
62		.bytesperline = 320,
63		.sizeimage = 320 * 240 * 3 / 8 + 590,
64		.colorspace = V4L2_COLORSPACE_JPEG,
65		.priv = 2},
66#if 0 /* HDG: broken with my test cam, so lets disable it */
67	{352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
68		.bytesperline = 352,
69		.sizeimage = 352 * 288 * 3 / 8 + 590,
70		.colorspace = V4L2_COLORSPACE_JPEG,
71		.priv = 1},
72#endif
73	{640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
74		.bytesperline = 640,
75		.sizeimage = 640 * 480 * 3 / 8 + 590,
76		.colorspace = V4L2_COLORSPACE_JPEG,
77		.priv = 0},
78};
79
80/* sensor specific data */
81struct additional_sensor_data {
82	const u8 n3[6];
83	const u8 *n4, n4sz;
84	const u8 reg80, reg8e;
85	const u8 nset8[6];
86	const u8 data1[10];
87	const u8 data2[9];
88	const u8 data3[9];
89	const u8 data5[6];
90	const u8 stream[4];
91};
92
93static const u8 n4_om6802[] = {
94	0x09, 0x01, 0x12, 0x04, 0x66, 0x8a, 0x80, 0x3c,
95	0x81, 0x22, 0x84, 0x50, 0x8a, 0x78, 0x8b, 0x68,
96	0x8c, 0x88, 0x8e, 0x33, 0x8f, 0x24, 0xaa, 0xb1,
97	0xa2, 0x60, 0xa5, 0x30, 0xa6, 0x3a, 0xa8, 0xe8,
98	0xae, 0x05, 0xb1, 0x00, 0xbb, 0x04, 0xbc, 0x48,
99	0xbe, 0x36, 0xc6, 0x88, 0xe9, 0x00, 0xc5, 0xc0,
100	0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68,
101	0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40,
102	0xac, 0x84, 0xad, 0x86, 0xaf, 0x46
103};
104static const u8 n4_other[] = {
105	0x66, 0x00, 0x7f, 0x00, 0x80, 0xac, 0x81, 0x69,
106	0x84, 0x40, 0x85, 0x70, 0x86, 0x20, 0x8a, 0x68,
107	0x8b, 0x58, 0x8c, 0x88, 0x8d, 0xff, 0x8e, 0xb8,
108	0x8f, 0x28, 0xa2, 0x60, 0xa5, 0x40, 0xa8, 0xa8,
109	0xac, 0x84, 0xad, 0x84, 0xae, 0x24, 0xaf, 0x56,
110	0xb0, 0x68, 0xb1, 0x00, 0xb2, 0x88, 0xbb, 0xc5,
111	0xbc, 0x4a, 0xbe, 0x36, 0xc2, 0x88, 0xc5, 0xc0,
112	0xc6, 0xda, 0xe9, 0x26, 0xeb, 0x00
113};
114static const u8 n4_tas5130a[] = {
115	0x80, 0x3c, 0x81, 0x68, 0x83, 0xa0, 0x84, 0x20,
116	0x8a, 0x68, 0x8b, 0x58, 0x8c, 0x88, 0x8e, 0xb4,
117	0x8f, 0x24, 0xa1, 0xb1, 0xa2, 0x30, 0xa5, 0x10,
118	0xa6, 0x4a, 0xae, 0x03, 0xb1, 0x44, 0xb2, 0x08,
119	0xb7, 0x06, 0xb9, 0xe7, 0xbb, 0xc4, 0xbc, 0x4a,
120	0xbe, 0x36, 0xbf, 0xff, 0xc2, 0x88, 0xc5, 0xc8,
121	0xc6, 0xda
122};
123static const u8 n4_lt168g[] = {
124	0x66, 0x01, 0x7f, 0x00, 0x80, 0x7c, 0x81, 0x28,
125	0x83, 0x44, 0x84, 0x20, 0x86, 0x20, 0x8a, 0x70,
126	0x8b, 0x58, 0x8c, 0x88, 0x8d, 0xa0, 0x8e, 0xb3,
127	0x8f, 0x24, 0xa1, 0xb0, 0xa2, 0x38, 0xa5, 0x20,
128	0xa6, 0x4a, 0xa8, 0xe8, 0xaf, 0x38, 0xb0, 0x68,
129	0xb1, 0x44, 0xb2, 0x88, 0xbb, 0x86, 0xbd, 0x40,
130	0xbe, 0x26, 0xc1, 0x05, 0xc2, 0x88, 0xc5, 0xc0,
131	0xda, 0x8e, 0xdb, 0xca, 0xdc, 0xa8, 0xdd, 0x8c,
132	0xde, 0x44, 0xdf, 0x0c, 0xe9, 0x80
133};
134
135static const struct additional_sensor_data sensor_data[] = {
136[SENSOR_OM6802] = {
137	.n3 =
138		{0x61, 0x68, 0x65, 0x0a, 0x60, 0x04},
139	.n4 = n4_om6802,
140	.n4sz = sizeof n4_om6802,
141	.reg80 = 0x3c,
142	.reg8e = 0x33,
143	.nset8 = {0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00},
144	.data1 =
145		{0xc2, 0x28, 0x0f, 0x22, 0xcd, 0x27, 0x2c, 0x06,
146		 0xb3, 0xfc},
147	.data2 =
148		{0x80, 0xff, 0xff, 0x80, 0xff, 0xff, 0x80, 0xff,
149		 0xff},
150	.data3 =
151		{0x80, 0xff, 0xff, 0x80, 0xff, 0xff, 0x80, 0xff,
152		 0xff},
153	.data5 =	/* this could be removed later */
154		{0x0c, 0x03, 0xab, 0x13, 0x81, 0x23},
155	.stream =
156		{0x0b, 0x04, 0x0a, 0x78},
157    },
158[SENSOR_OTHER] = {
159	.n3 =
160		{0x61, 0xc2, 0x65, 0x88, 0x60, 0x00},
161	.n4 = n4_other,
162	.n4sz = sizeof n4_other,
163	.reg80 = 0xac,
164	.reg8e = 0xb8,
165	.nset8 = {0xa8, 0xa8, 0xc6, 0xda, 0xc0, 0x00},
166	.data1 =
167		{0xc1, 0x48, 0x04, 0x1b, 0xca, 0x2e, 0x33, 0x3a,
168		 0xe8, 0xfc},
169	.data2 =
170		{0x4e, 0x9c, 0xec, 0x40, 0x80, 0xc0, 0x48, 0x96,
171		 0xd9},
172	.data3 =
173		{0x4e, 0x9c, 0xec, 0x40, 0x80, 0xc0, 0x48, 0x96,
174		 0xd9},
175	.data5 =
176		{0x0c, 0x03, 0xab, 0x29, 0x81, 0x69},
177	.stream =
178		{0x0b, 0x04, 0x0a, 0x00},
179    },
180[SENSOR_TAS5130A] = {
181	.n3 =
182		{0x61, 0xc2, 0x65, 0x0d, 0x60, 0x08},
183	.n4 = n4_tas5130a,
184	.n4sz = sizeof n4_tas5130a,
185	.reg80 = 0x3c,
186	.reg8e = 0xb4,
187	.nset8 = {0xa8, 0xf0, 0xc6, 0xda, 0xc0, 0x00},
188	.data1 =
189		{0xbb, 0x28, 0x10, 0x10, 0xbb, 0x28, 0x1e, 0x27,
190		 0xc8, 0xfc},
191	.data2 =
192		{0x60, 0xa8, 0xe0, 0x60, 0xa8, 0xe0, 0x60, 0xa8,
193		 0xe0},
194	.data3 =
195		{0x60, 0xa8, 0xe0, 0x60, 0xa8, 0xe0, 0x60, 0xa8,
196		 0xe0},
197	.data5 =
198		{0x0c, 0x03, 0xab, 0x10, 0x81, 0x20},
199	.stream =
200		{0x0b, 0x04, 0x0a, 0x40},
201    },
202[SENSOR_LT168G] = {
203	.n3 = {0x61, 0xc2, 0x65, 0x68, 0x60, 0x00},
204	.n4 = n4_lt168g,
205	.n4sz = sizeof n4_lt168g,
206	.reg80 = 0x7c,
207	.reg8e = 0xb3,
208	.nset8 = {0xa8, 0xf0, 0xc6, 0xba, 0xc0, 0x00},
209	.data1 = {0xc0, 0x38, 0x08, 0x10, 0xc0, 0x30, 0x10, 0x40,
210		 0xb0, 0xf4},
211	.data2 = {0x40, 0x80, 0xc0, 0x50, 0xa0, 0xf0, 0x53, 0xa6,
212		 0xff},
213	.data3 = {0x40, 0x80, 0xc0, 0x50, 0xa0, 0xf0, 0x53, 0xa6,
214		 0xff},
215	.data5 = {0x0c, 0x03, 0xab, 0x4b, 0x81, 0x2b},
216	.stream = {0x0b, 0x04, 0x0a, 0x28},
217    },
218};
219
220#define MAX_EFFECTS 7
221static const u8 effects_table[MAX_EFFECTS][6] = {
222	{0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x00},	/* Normal */
223	{0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x04},	/* Repujar */
224	{0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x20},	/* Monochrome */
225	{0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x80},	/* Sepia */
226	{0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x02},	/* Croquis */
227	{0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x10},	/* Sun Effect */
228	{0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x40},	/* Negative */
229};
230
231#define GAMMA_MAX (15)
232static const u8 gamma_table[GAMMA_MAX+1][17] = {
233/* gamma table from cam1690.ini */
234	{0x00, 0x00, 0x01, 0x04, 0x08, 0x0e, 0x16, 0x21,	/* 0 */
235	 0x2e, 0x3d, 0x50, 0x65, 0x7d, 0x99, 0xb8, 0xdb,
236	 0xff},
237	{0x00, 0x01, 0x03, 0x08, 0x0e, 0x16, 0x21, 0x2d,	/* 1 */
238	 0x3c, 0x4d, 0x60, 0x75, 0x8d, 0xa6, 0xc2, 0xe1,
239	 0xff},
240	{0x00, 0x01, 0x05, 0x0b, 0x12, 0x1c, 0x28, 0x35,	/* 2 */
241	 0x45, 0x56, 0x69, 0x7e, 0x95, 0xad, 0xc7, 0xe3,
242	 0xff},
243	{0x00, 0x02, 0x07, 0x0f, 0x18, 0x24, 0x30, 0x3f,	/* 3 */
244	 0x4f, 0x61, 0x73, 0x88, 0x9d, 0xb4, 0xcd, 0xe6,
245	 0xff},
246	{0x00, 0x04, 0x0b, 0x15, 0x20, 0x2d, 0x3b, 0x4a,	/* 4 */
247	 0x5b, 0x6c, 0x7f, 0x92, 0xa7, 0xbc, 0xd2, 0xe9,
248	 0xff},
249	{0x00, 0x07, 0x11, 0x15, 0x20, 0x2d, 0x48, 0x58,	/* 5 */
250	 0x68, 0x79, 0x8b, 0x9d, 0xb0, 0xc4, 0xd7, 0xec,
251	 0xff},
252	{0x00, 0x0c, 0x1a, 0x29, 0x38, 0x47, 0x57, 0x67,	/* 6 */
253	 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee,
254	 0xff},
255	{0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,	/* 7 */
256	 0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0,
257	 0xff},
258	{0x00, 0x15, 0x27, 0x38, 0x49, 0x59, 0x69, 0x79,	/* 8 */
259	 0x88, 0x97, 0xa7, 0xb6, 0xc4, 0xd3, 0xe2, 0xf0,
260	 0xff},
261	{0x00, 0x1c, 0x30, 0x43, 0x54, 0x65, 0x75, 0x84,	/* 9 */
262	 0x93, 0xa1, 0xb0, 0xbd, 0xca, 0xd8, 0xe5, 0xf2,
263	 0xff},
264	{0x00, 0x24, 0x3b, 0x4f, 0x60, 0x70, 0x80, 0x8e,	/* 10 */
265	 0x9c, 0xaa, 0xb7, 0xc4, 0xd0, 0xdc, 0xe8, 0xf3,
266	 0xff},
267	{0x00, 0x2a, 0x3c, 0x5d, 0x6e, 0x7e, 0x8d, 0x9b,	/* 11 */
268	 0xa8, 0xb4, 0xc0, 0xcb, 0xd6, 0xe1, 0xeb, 0xf5,
269	 0xff},
270	{0x00, 0x3f, 0x5a, 0x6e, 0x7f, 0x8e, 0x9c, 0xa8,	/* 12 */
271	 0xb4, 0xbf, 0xc9, 0xd3, 0xdc, 0xe5, 0xee, 0xf6,
272	 0xff},
273	{0x00, 0x54, 0x6f, 0x83, 0x93, 0xa0, 0xad, 0xb7,	/* 13 */
274	 0xc2, 0xcb, 0xd4, 0xdc, 0xe4, 0xeb, 0xf2, 0xf9,
275	 0xff},
276	{0x00, 0x6e, 0x88, 0x9a, 0xa8, 0xb3, 0xbd, 0xc6,	/* 14 */
277	 0xcf, 0xd6, 0xdd, 0xe3, 0xe9, 0xef, 0xf4, 0xfa,
278	 0xff},
279	{0x00, 0x93, 0xa8, 0xb7, 0xc1, 0xca, 0xd2, 0xd8,	/* 15 */
280	 0xde, 0xe3, 0xe8, 0xed, 0xf1, 0xf5, 0xf8, 0xfc,
281	 0xff}
282};
283
284static const u8 tas5130a_sensor_init[][8] = {
285	{0x62, 0x08, 0x63, 0x70, 0x64, 0x1d, 0x60, 0x09},
286	{0x62, 0x20, 0x63, 0x01, 0x64, 0x02, 0x60, 0x09},
287	{0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09},
288};
289
290static u8 sensor_reset[] = {0x61, 0x68, 0x62, 0xff, 0x60, 0x07};
291
292/* read 1 byte */
293static u8 reg_r(struct gspca_dev *gspca_dev,
294		   u16 index)
295{
296	usb_control_msg(gspca_dev->dev,
297			usb_rcvctrlpipe(gspca_dev->dev, 0),
298			0,		/* request */
299			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
300			0,		/* value */
301			index,
302			gspca_dev->usb_buf, 1, 500);
303	return gspca_dev->usb_buf[0];
304}
305
306static void reg_w(struct gspca_dev *gspca_dev,
307		  u16 index)
308{
309	usb_control_msg(gspca_dev->dev,
310			usb_sndctrlpipe(gspca_dev->dev, 0),
311			0,
312			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
313			0, index,
314			NULL, 0, 500);
315}
316
317static void reg_w_buf(struct gspca_dev *gspca_dev,
318		  const u8 *buffer, u16 len)
319{
320	if (len <= USB_BUF_SZ) {
321		memcpy(gspca_dev->usb_buf, buffer, len);
322		usb_control_msg(gspca_dev->dev,
323				usb_sndctrlpipe(gspca_dev->dev, 0),
324				0,
325			   USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
326				0x01, 0,
327				gspca_dev->usb_buf, len, 500);
328	} else {
329		u8 *tmpbuf;
330
331		tmpbuf = kmemdup(buffer, len, GFP_KERNEL);
332		if (!tmpbuf) {
333			pr_err("Out of memory\n");
334			return;
335		}
336		usb_control_msg(gspca_dev->dev,
337				usb_sndctrlpipe(gspca_dev->dev, 0),
338				0,
339			   USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
340				0x01, 0,
341				tmpbuf, len, 500);
342		kfree(tmpbuf);
343	}
344}
345
346/* write values to consecutive registers */
347static void reg_w_ixbuf(struct gspca_dev *gspca_dev,
348			u8 reg,
349			const u8 *buffer, u16 len)
350{
351	int i;
352	u8 *p, *tmpbuf;
353
354	if (len * 2 <= USB_BUF_SZ) {
355		p = tmpbuf = gspca_dev->usb_buf;
356	} else {
357		p = tmpbuf = kmalloc_array(len, 2, GFP_KERNEL);
358		if (!tmpbuf) {
359			pr_err("Out of memory\n");
360			return;
361		}
362	}
363	i = len;
364	while (--i >= 0) {
365		*p++ = reg++;
366		*p++ = *buffer++;
367	}
368	usb_control_msg(gspca_dev->dev,
369			usb_sndctrlpipe(gspca_dev->dev, 0),
370			0,
371			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
372			0x01, 0,
373			tmpbuf, len * 2, 500);
374	if (len * 2 > USB_BUF_SZ)
375		kfree(tmpbuf);
376}
377
378static void om6802_sensor_init(struct gspca_dev *gspca_dev)
379{
380	int i;
381	const u8 *p;
382	u8 byte;
383	u8 val[6] = {0x62, 0, 0x64, 0, 0x60, 0x05};
384	static const u8 sensor_init[] = {
385		0xdf, 0x6d,
386		0xdd, 0x18,
387		0x5a, 0xe0,
388		0x5c, 0x07,
389		0x5d, 0xb0,
390		0x5e, 0x1e,
391		0x60, 0x71,
392		0xef, 0x00,
393		0xe9, 0x00,
394		0xea, 0x00,
395		0x90, 0x24,
396		0x91, 0xb2,
397		0x82, 0x32,
398		0xfd, 0x41,
399		0x00			/* table end */
400	};
401
402	reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset);
403	msleep(100);
404	i = 4;
405	while (--i > 0) {
406		byte = reg_r(gspca_dev, 0x0060);
407		if (!(byte & 0x01))
408			break;
409		msleep(100);
410	}
411	byte = reg_r(gspca_dev, 0x0063);
412	if (byte != 0x17) {
413		pr_err("Bad sensor reset %02x\n", byte);
414		/* continue? */
415	}
416
417	p = sensor_init;
418	while (*p != 0) {
419		val[1] = *p++;
420		val[3] = *p++;
421		if (*p == 0)
422			reg_w(gspca_dev, 0x3c80);
423		reg_w_buf(gspca_dev, val, sizeof val);
424		i = 4;
425		while (--i >= 0) {
426			msleep(15);
427			byte = reg_r(gspca_dev, 0x60);
428			if (!(byte & 0x01))
429				break;
430		}
431	}
432	msleep(15);
433	reg_w(gspca_dev, 0x3c80);
434}
435
436/* this function is called at probe time */
437static int sd_config(struct gspca_dev *gspca_dev,
438		     const struct usb_device_id *id)
439{
440	struct cam *cam  = &gspca_dev->cam;
441
442	cam->cam_mode = vga_mode_t16;
443	cam->nmodes = ARRAY_SIZE(vga_mode_t16);
444
445	return 0;
446}
447
448static void setbrightness(struct gspca_dev *gspca_dev, s32 brightness)
449{
450	u8 set6[4] = { 0x8f, 0x24, 0xc3, 0x00 };
451
452	if (brightness < 7) {
453		set6[1] = 0x26;
454		set6[3] = 0x70 - brightness * 0x10;
455	} else {
456		set6[3] = 0x00 + ((brightness - 7) * 0x10);
457	}
458
459	reg_w_buf(gspca_dev, set6, sizeof set6);
460}
461
462static void setcontrast(struct gspca_dev *gspca_dev, s32 contrast)
463{
464	u16 reg_to_write;
465
466	if (contrast < 7)
467		reg_to_write = 0x8ea9 - contrast * 0x200;
468	else
469		reg_to_write = 0x00a9 + (contrast - 7) * 0x200;
470
471	reg_w(gspca_dev, reg_to_write);
472}
473
474static void setcolors(struct gspca_dev *gspca_dev, s32 val)
475{
476	u16 reg_to_write;
477
478	reg_to_write = 0x80bb + val * 0x100;	/* was 0xc0 */
479	reg_w(gspca_dev, reg_to_write);
480}
481
482static void setgamma(struct gspca_dev *gspca_dev, s32 val)
483{
484	gspca_dbg(gspca_dev, D_CONF, "Gamma: %d\n", val);
485	reg_w_ixbuf(gspca_dev, 0x90,
486		gamma_table[val], sizeof gamma_table[0]);
487}
488
489static void setawb_n_RGB(struct gspca_dev *gspca_dev)
490{
491	struct sd *sd = (struct sd *) gspca_dev;
492	u8 all_gain_reg[8] = {
493		0x87, 0x00, 0x88, 0x00, 0x89, 0x00, 0x80, 0x00 };
494	s32 red_gain, blue_gain, green_gain;
495
496	green_gain = sd->gain->val;
497
498	red_gain = green_gain + sd->red_balance->val;
499	if (red_gain > 0x40)
500		red_gain = 0x40;
501	else if (red_gain < 0x10)
502		red_gain = 0x10;
503
504	blue_gain = green_gain + sd->blue_balance->val;
505	if (blue_gain > 0x40)
506		blue_gain = 0x40;
507	else if (blue_gain < 0x10)
508		blue_gain = 0x10;
509
510	all_gain_reg[1] = red_gain;
511	all_gain_reg[3] = blue_gain;
512	all_gain_reg[5] = green_gain;
513	all_gain_reg[7] = sensor_data[sd->sensor].reg80;
514	if (!sd->awb->val)
515		all_gain_reg[7] &= ~0x04; /* AWB off */
516
517	reg_w_buf(gspca_dev, all_gain_reg, sizeof all_gain_reg);
518}
519
520static void setsharpness(struct gspca_dev *gspca_dev, s32 val)
521{
522	u16 reg_to_write;
523
524	reg_to_write = 0x0aa6 + 0x1000 * val;
525
526	reg_w(gspca_dev, reg_to_write);
527}
528
529static void setfreq(struct gspca_dev *gspca_dev, s32 val)
530{
531	struct sd *sd = (struct sd *) gspca_dev;
532	u8 reg66;
533	u8 freq[4] = { 0x66, 0x00, 0xa8, 0xe8 };
534
535	switch (sd->sensor) {
536	case SENSOR_LT168G:
537		if (val != 0)
538			freq[3] = 0xa8;
539		reg66 = 0x41;
540		break;
541	case SENSOR_OM6802:
542		reg66 = 0xca;
543		break;
544	default:
545		reg66 = 0x40;
546		break;
547	}
548	switch (val) {
549	case 0:				/* no flicker */
550		freq[3] = 0xf0;
551		break;
552	case 2:				/* 60Hz */
553		reg66 &= ~0x40;
554		break;
555	}
556	freq[1] = reg66;
557
558	reg_w_buf(gspca_dev, freq, sizeof freq);
559}
560
561/* this function is called at probe and resume time */
562static int sd_init(struct gspca_dev *gspca_dev)
563{
564	/* some of this registers are not really needed, because
565	 * they are overridden by setbrigthness, setcontrast, etc.,
566	 * but won't hurt anyway, and can help someone with similar webcam
567	 * to see the initial parameters.*/
568	struct sd *sd = (struct sd *) gspca_dev;
569	const struct additional_sensor_data *sensor;
570	int i;
571	u16 sensor_id;
572	u8 test_byte = 0;
573
574	static const u8 read_indexs[] =
575		{ 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5,
576		  0xa6, 0xa8, 0xbb, 0xbc, 0xc6, 0x00 };
577	static const u8 n1[] =
578			{0x08, 0x03, 0x09, 0x03, 0x12, 0x04};
579	static const u8 n2[] =
580			{0x08, 0x00};
581
582	sensor_id = (reg_r(gspca_dev, 0x06) << 8)
583			| reg_r(gspca_dev, 0x07);
584	switch (sensor_id & 0xff0f) {
585	case 0x0801:
586		gspca_dbg(gspca_dev, D_PROBE, "sensor tas5130a\n");
587		sd->sensor = SENSOR_TAS5130A;
588		break;
589	case 0x0802:
590		gspca_dbg(gspca_dev, D_PROBE, "sensor lt168g\n");
591		sd->sensor = SENSOR_LT168G;
592		break;
593	case 0x0803:
594		gspca_dbg(gspca_dev, D_PROBE, "sensor 'other'\n");
595		sd->sensor = SENSOR_OTHER;
596		break;
597	case 0x0807:
598		gspca_dbg(gspca_dev, D_PROBE, "sensor om6802\n");
599		sd->sensor = SENSOR_OM6802;
600		break;
601	default:
602		pr_err("unknown sensor %04x\n", sensor_id);
603		return -EINVAL;
604	}
605
606	if (sd->sensor == SENSOR_OM6802) {
607		reg_w_buf(gspca_dev, n1, sizeof n1);
608		i = 5;
609		while (--i >= 0) {
610			reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset);
611			test_byte = reg_r(gspca_dev, 0x0063);
612			msleep(100);
613			if (test_byte == 0x17)
614				break;		/* OK */
615		}
616		if (i < 0) {
617			pr_err("Bad sensor reset %02x\n", test_byte);
618			return -EIO;
619		}
620		reg_w_buf(gspca_dev, n2, sizeof n2);
621	}
622
623	i = 0;
624	while (read_indexs[i] != 0x00) {
625		test_byte = reg_r(gspca_dev, read_indexs[i]);
626		gspca_dbg(gspca_dev, D_STREAM, "Reg 0x%02x = 0x%02x\n",
627			  read_indexs[i], test_byte);
628		i++;
629	}
630
631	sensor = &sensor_data[sd->sensor];
632	reg_w_buf(gspca_dev, sensor->n3, sizeof sensor->n3);
633	reg_w_buf(gspca_dev, sensor->n4, sensor->n4sz);
634
635	if (sd->sensor == SENSOR_LT168G) {
636		test_byte = reg_r(gspca_dev, 0x80);
637		gspca_dbg(gspca_dev, D_STREAM, "Reg 0x%02x = 0x%02x\n", 0x80,
638			  test_byte);
639		reg_w(gspca_dev, 0x6c80);
640	}
641
642	reg_w_ixbuf(gspca_dev, 0xd0, sensor->data1, sizeof sensor->data1);
643	reg_w_ixbuf(gspca_dev, 0xc7, sensor->data2, sizeof sensor->data2);
644	reg_w_ixbuf(gspca_dev, 0xe0, sensor->data3, sizeof sensor->data3);
645
646	reg_w(gspca_dev, (sensor->reg80 << 8) + 0x80);
647	reg_w(gspca_dev, (sensor->reg80 << 8) + 0x80);
648	reg_w(gspca_dev, (sensor->reg8e << 8) + 0x8e);
649	reg_w(gspca_dev, (0x20 << 8) + 0x87);
650	reg_w(gspca_dev, (0x20 << 8) + 0x88);
651	reg_w(gspca_dev, (0x20 << 8) + 0x89);
652
653	reg_w_buf(gspca_dev, sensor->data5, sizeof sensor->data5);
654	reg_w_buf(gspca_dev, sensor->nset8, sizeof sensor->nset8);
655	reg_w_buf(gspca_dev, sensor->stream, sizeof sensor->stream);
656
657	if (sd->sensor == SENSOR_LT168G) {
658		test_byte = reg_r(gspca_dev, 0x80);
659		gspca_dbg(gspca_dev, D_STREAM, "Reg 0x%02x = 0x%02x\n", 0x80,
660			  test_byte);
661		reg_w(gspca_dev, 0x6c80);
662	}
663
664	reg_w_ixbuf(gspca_dev, 0xd0, sensor->data1, sizeof sensor->data1);
665	reg_w_ixbuf(gspca_dev, 0xc7, sensor->data2, sizeof sensor->data2);
666	reg_w_ixbuf(gspca_dev, 0xe0, sensor->data3, sizeof sensor->data3);
667
668	return 0;
669}
670
671static void setmirror(struct gspca_dev *gspca_dev, s32 val)
672{
673	u8 hflipcmd[8] =
674		{0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09};
675
676	if (val)
677		hflipcmd[3] = 0x01;
678
679	reg_w_buf(gspca_dev, hflipcmd, sizeof hflipcmd);
680}
681
682static void seteffect(struct gspca_dev *gspca_dev, s32 val)
683{
684	int idx = 0;
685
686	switch (val) {
687	case V4L2_COLORFX_NONE:
688		break;
689	case V4L2_COLORFX_BW:
690		idx = 2;
691		break;
692	case V4L2_COLORFX_SEPIA:
693		idx = 3;
694		break;
695	case V4L2_COLORFX_SKETCH:
696		idx = 4;
697		break;
698	case V4L2_COLORFX_NEGATIVE:
699		idx = 6;
700		break;
701	default:
702		break;
703	}
704
705	reg_w_buf(gspca_dev, effects_table[idx],
706				sizeof effects_table[0]);
707
708	if (val == V4L2_COLORFX_SKETCH)
709		reg_w(gspca_dev, 0x4aa6);
710	else
711		reg_w(gspca_dev, 0xfaa6);
712}
713
714/* Is this really needed?
715 * i added some module parameters for test with some users */
716static void poll_sensor(struct gspca_dev *gspca_dev)
717{
718	static const u8 poll1[] =
719		{0x67, 0x05, 0x68, 0x81, 0x69, 0x80, 0x6a, 0x82,
720		 0x6b, 0x68, 0x6c, 0x69, 0x72, 0xd9, 0x73, 0x34,
721		 0x74, 0x32, 0x75, 0x92, 0x76, 0x00, 0x09, 0x01,
722		 0x60, 0x14};
723	static const u8 poll2[] =
724		{0x67, 0x02, 0x68, 0x71, 0x69, 0x72, 0x72, 0xa9,
725		 0x73, 0x02, 0x73, 0x02, 0x60, 0x14};
726	static const u8 noise03[] =	/* (some differences / ms-drv) */
727		{0xa6, 0x0a, 0xea, 0xcf, 0xbe, 0x26, 0xb1, 0x5f,
728		 0xa1, 0xb1, 0xda, 0x6b, 0xdb, 0x98, 0xdf, 0x0c,
729		 0xc2, 0x80, 0xc3, 0x10};
730
731	gspca_dbg(gspca_dev, D_STREAM, "[Sensor requires polling]\n");
732	reg_w_buf(gspca_dev, poll1, sizeof poll1);
733	reg_w_buf(gspca_dev, poll2, sizeof poll2);
734	reg_w_buf(gspca_dev, noise03, sizeof noise03);
735}
736
737static int sd_start(struct gspca_dev *gspca_dev)
738{
739	struct sd *sd = (struct sd *) gspca_dev;
740	const struct additional_sensor_data *sensor;
741	int i, mode;
742	u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 };
743	static const u8 t3[] =
744		{ 0x07, 0x00, 0x88, 0x02, 0x06, 0x00, 0xe7, 0x01 };
745
746	mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
747	switch (mode) {
748	case 0:		/* 640x480 (0x00) */
749		break;
750	case 1:		/* 352x288 */
751		t2[1] = 0x40;
752		break;
753	case 2:		/* 320x240 */
754		t2[1] = 0x10;
755		break;
756	case 3:		/* 176x144 */
757		t2[1] = 0x50;
758		break;
759	default:
760/*	case 4:		 * 160x120 */
761		t2[1] = 0x20;
762		break;
763	}
764
765	switch (sd->sensor) {
766	case SENSOR_OM6802:
767		om6802_sensor_init(gspca_dev);
768		break;
769	case SENSOR_TAS5130A:
770		i = 0;
771		for (;;) {
772			reg_w_buf(gspca_dev, tas5130a_sensor_init[i],
773					 sizeof tas5130a_sensor_init[0]);
774			if (i >= ARRAY_SIZE(tas5130a_sensor_init) - 1)
775				break;
776			i++;
777		}
778		reg_w(gspca_dev, 0x3c80);
779		/* just in case and to keep sync with logs (for mine) */
780		reg_w_buf(gspca_dev, tas5130a_sensor_init[i],
781				 sizeof tas5130a_sensor_init[0]);
782		reg_w(gspca_dev, 0x3c80);
783		break;
784	}
785	sensor = &sensor_data[sd->sensor];
786	setfreq(gspca_dev, v4l2_ctrl_g_ctrl(sd->freq));
787	reg_r(gspca_dev, 0x0012);
788	reg_w_buf(gspca_dev, t2, sizeof t2);
789	reg_w_ixbuf(gspca_dev, 0xb3, t3, sizeof t3);
790	reg_w(gspca_dev, 0x0013);
791	msleep(15);
792	reg_w_buf(gspca_dev, sensor->stream, sizeof sensor->stream);
793	reg_w_buf(gspca_dev, sensor->stream, sizeof sensor->stream);
794
795	if (sd->sensor == SENSOR_OM6802)
796		poll_sensor(gspca_dev);
797
798	return 0;
799}
800
801static void sd_stopN(struct gspca_dev *gspca_dev)
802{
803	struct sd *sd = (struct sd *) gspca_dev;
804
805	reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
806			sizeof sensor_data[sd->sensor].stream);
807	reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
808			sizeof sensor_data[sd->sensor].stream);
809	if (sd->sensor == SENSOR_OM6802) {
810		msleep(20);
811		reg_w(gspca_dev, 0x0309);
812	}
813#if IS_ENABLED(CONFIG_INPUT)
814	/* If the last button state is pressed, release it now! */
815	if (sd->button_pressed) {
816		input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
817		input_sync(gspca_dev->input_dev);
818		sd->button_pressed = 0;
819	}
820#endif
821}
822
823static void sd_pkt_scan(struct gspca_dev *gspca_dev,
824			u8 *data,			/* isoc packet */
825			int len)			/* iso packet length */
826{
827	struct sd *sd __maybe_unused = (struct sd *) gspca_dev;
828	int pkt_type;
829
830	if (data[0] == 0x5a) {
831#if IS_ENABLED(CONFIG_INPUT)
832		if (len > 20) {
833			u8 state = (data[20] & 0x80) ? 1 : 0;
834			if (sd->button_pressed != state) {
835				input_report_key(gspca_dev->input_dev,
836						 KEY_CAMERA, state);
837				input_sync(gspca_dev->input_dev);
838				sd->button_pressed = state;
839			}
840		}
841#endif
842		/* Control Packet, after this came the header again,
843		 * but extra bytes came in the packet before this,
844		 * sometimes an EOF arrives, sometimes not... */
845		return;
846	}
847	data += 2;
848	len -= 2;
849	if (data[0] == 0xff && data[1] == 0xd8)
850		pkt_type = FIRST_PACKET;
851	else if (data[len - 2] == 0xff && data[len - 1] == 0xd9)
852		pkt_type = LAST_PACKET;
853	else
854		pkt_type = INTER_PACKET;
855	gspca_frame_add(gspca_dev, pkt_type, data, len);
856}
857
858static int sd_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
859{
860	struct gspca_dev *gspca_dev =
861		container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
862	struct sd *sd = (struct sd *)gspca_dev;
863	s32 red_gain, blue_gain, green_gain;
864
865	gspca_dev->usb_err = 0;
866
867	switch (ctrl->id) {
868	case V4L2_CID_AUTO_WHITE_BALANCE:
869		red_gain = reg_r(gspca_dev, 0x0087);
870		if (red_gain > 0x40)
871			red_gain = 0x40;
872		else if (red_gain < 0x10)
873			red_gain = 0x10;
874
875		blue_gain = reg_r(gspca_dev, 0x0088);
876		if (blue_gain > 0x40)
877			blue_gain = 0x40;
878		else if (blue_gain < 0x10)
879			blue_gain = 0x10;
880
881		green_gain = reg_r(gspca_dev, 0x0089);
882		if (green_gain > 0x40)
883			green_gain = 0x40;
884		else if (green_gain < 0x10)
885			green_gain = 0x10;
886
887		sd->gain->val = green_gain;
888		sd->red_balance->val = red_gain - green_gain;
889		sd->blue_balance->val = blue_gain - green_gain;
890		break;
891	}
892	return 0;
893}
894
895static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
896{
897	struct gspca_dev *gspca_dev =
898		container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
899
900	gspca_dev->usb_err = 0;
901
902	if (!gspca_dev->streaming)
903		return 0;
904
905	switch (ctrl->id) {
906	case V4L2_CID_BRIGHTNESS:
907		setbrightness(gspca_dev, ctrl->val);
908		break;
909	case V4L2_CID_CONTRAST:
910		setcontrast(gspca_dev, ctrl->val);
911		break;
912	case V4L2_CID_SATURATION:
913		setcolors(gspca_dev, ctrl->val);
914		break;
915	case V4L2_CID_GAMMA:
916		setgamma(gspca_dev, ctrl->val);
917		break;
918	case V4L2_CID_HFLIP:
919		setmirror(gspca_dev, ctrl->val);
920		break;
921	case V4L2_CID_SHARPNESS:
922		setsharpness(gspca_dev, ctrl->val);
923		break;
924	case V4L2_CID_POWER_LINE_FREQUENCY:
925		setfreq(gspca_dev, ctrl->val);
926		break;
927	case V4L2_CID_BACKLIGHT_COMPENSATION:
928		reg_w(gspca_dev, ctrl->val ? 0xf48e : 0xb48e);
929		break;
930	case V4L2_CID_AUTO_WHITE_BALANCE:
931		setawb_n_RGB(gspca_dev);
932		break;
933	case V4L2_CID_COLORFX:
934		seteffect(gspca_dev, ctrl->val);
935		break;
936	}
937	return gspca_dev->usb_err;
938}
939
940static const struct v4l2_ctrl_ops sd_ctrl_ops = {
941	.g_volatile_ctrl = sd_g_volatile_ctrl,
942	.s_ctrl = sd_s_ctrl,
943};
944
945static int sd_init_controls(struct gspca_dev *gspca_dev)
946{
947	struct sd *sd = (struct sd *)gspca_dev;
948	struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
949
950	gspca_dev->vdev.ctrl_handler = hdl;
951	v4l2_ctrl_handler_init(hdl, 12);
952	v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
953			V4L2_CID_BRIGHTNESS, 0, 14, 1, 8);
954	v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
955			V4L2_CID_CONTRAST, 0, 0x0d, 1, 7);
956	v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
957			V4L2_CID_SATURATION, 0, 0xf, 1, 5);
958	v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
959			V4L2_CID_GAMMA, 0, GAMMA_MAX, 1, 10);
960	/* Activate lowlight, some apps don't bring up the
961	   backlight_compensation control) */
962	v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
963			V4L2_CID_BACKLIGHT_COMPENSATION, 0, 1, 1, 1);
964	if (sd->sensor == SENSOR_TAS5130A)
965		v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
966				V4L2_CID_HFLIP, 0, 1, 1, 0);
967	sd->awb = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
968			V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 1);
969	sd->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
970			V4L2_CID_GAIN, 0x10, 0x40, 1, 0x20);
971	sd->blue_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
972			V4L2_CID_BLUE_BALANCE, -0x30, 0x30, 1, 0);
973	sd->red_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
974			V4L2_CID_RED_BALANCE, -0x30, 0x30, 1, 0);
975	v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
976			V4L2_CID_SHARPNESS, 0, 15, 1, 6);
977	v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops,
978			V4L2_CID_COLORFX, V4L2_COLORFX_SKETCH,
979			~((1 << V4L2_COLORFX_NONE) |
980			  (1 << V4L2_COLORFX_BW) |
981			  (1 << V4L2_COLORFX_SEPIA) |
982			  (1 << V4L2_COLORFX_SKETCH) |
983			  (1 << V4L2_COLORFX_NEGATIVE)),
984			V4L2_COLORFX_NONE);
985	sd->freq = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops,
986			V4L2_CID_POWER_LINE_FREQUENCY,
987			V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 1,
988			V4L2_CID_POWER_LINE_FREQUENCY_50HZ);
989
990	if (hdl->error) {
991		pr_err("Could not initialize controls\n");
992		return hdl->error;
993	}
994
995	v4l2_ctrl_auto_cluster(4, &sd->awb, 0, true);
996
997	return 0;
998}
999
1000/* sub-driver description */
1001static const struct sd_desc sd_desc = {
1002	.name = MODULE_NAME,
1003	.config = sd_config,
1004	.init = sd_init,
1005	.init_controls = sd_init_controls,
1006	.start = sd_start,
1007	.stopN = sd_stopN,
1008	.pkt_scan = sd_pkt_scan,
1009#if IS_ENABLED(CONFIG_INPUT)
1010	.other_input = 1,
1011#endif
1012};
1013
1014/* -- module initialisation -- */
1015static const struct usb_device_id device_table[] = {
1016	{USB_DEVICE(0x17a1, 0x0128)},
1017	{}
1018};
1019MODULE_DEVICE_TABLE(usb, device_table);
1020
1021/* -- device connect -- */
1022static int sd_probe(struct usb_interface *intf,
1023		    const struct usb_device_id *id)
1024{
1025	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1026			       THIS_MODULE);
1027}
1028
1029static struct usb_driver sd_driver = {
1030	.name = MODULE_NAME,
1031	.id_table = device_table,
1032	.probe = sd_probe,
1033	.disconnect = gspca_disconnect,
1034#ifdef CONFIG_PM
1035	.suspend = gspca_suspend,
1036	.resume = gspca_resume,
1037	.reset_resume = gspca_resume,
1038#endif
1039};
1040
1041module_usb_driver(sd_driver);
1042