[go: nahoru, domu]

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