• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/drivers/media/video/gspca/
1/*
2 * SQ930x subdriver
3 *
4 * Copyright (C) 2010 Jean-Fran��ois Moine <http://moinejf.free.fr>
5 * Copyright (C) 2006 -2008 Gerard Klaver <gerard at gkall dot hobby dot nl>
6 * Copyright (C) 2007 Sam Revitch <samr7@cs.washington.edu>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#define MODULE_NAME "sq930x"
24
25#include "gspca.h"
26
27MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>\n"
28		"Gerard Klaver <gerard at gkall dot hobby dot nl\n"
29		"Sam Revitch <samr7@cs.washington.edu>");
30MODULE_DESCRIPTION("GSPCA/SQ930x USB Camera Driver");
31MODULE_LICENSE("GPL");
32
33/* Structure to hold all of our device specific stuff */
34struct sd {
35	struct gspca_dev gspca_dev;	/* !! must be the first item */
36
37	u16 expo;
38	u8 gain;
39
40	u8 do_ctrl;
41	u8 gpio[2];
42	u8 sensor;
43	u8 type;
44#define Generic 0
45#define Creative_live_motion 1
46};
47enum sensors {
48	SENSOR_ICX098BQ,
49	SENSOR_LZ24BP,
50	SENSOR_MI0360,
51	SENSOR_MT9V111,		/* = MI360SOC */
52	SENSOR_OV7660,
53	SENSOR_OV9630,
54};
55
56static int sd_setexpo(struct gspca_dev *gspca_dev, __s32 val);
57static int sd_getexpo(struct gspca_dev *gspca_dev, __s32 *val);
58static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
59static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
60
61static const struct ctrl sd_ctrls[] = {
62	{
63	    {
64		.id = V4L2_CID_EXPOSURE,
65		.type = V4L2_CTRL_TYPE_INTEGER,
66		.name = "Exposure",
67		.minimum = 0x0001,
68		.maximum = 0x0fff,
69		.step = 1,
70#define EXPO_DEF 0x0356
71		.default_value = EXPO_DEF,
72	    },
73	    .set = sd_setexpo,
74	    .get = sd_getexpo,
75	},
76	{
77	    {
78		.id = V4L2_CID_GAIN,
79		.type = V4L2_CTRL_TYPE_INTEGER,
80		.name = "Gain",
81		.minimum = 0x01,
82		.maximum = 0xff,
83		.step = 1,
84#define GAIN_DEF 0x8d
85		.default_value = GAIN_DEF,
86	    },
87	    .set = sd_setgain,
88	    .get = sd_getgain,
89	},
90};
91
92static struct v4l2_pix_format vga_mode[] = {
93	{320, 240, V4L2_PIX_FMT_SRGGB8, V4L2_FIELD_NONE,
94		.bytesperline = 320,
95		.sizeimage = 320 * 240,
96		.colorspace = V4L2_COLORSPACE_SRGB,
97		.priv = 0},
98	{640, 480, V4L2_PIX_FMT_SRGGB8, V4L2_FIELD_NONE,
99		.bytesperline = 640,
100		.sizeimage = 640 * 480,
101		.colorspace = V4L2_COLORSPACE_SRGB,
102		.priv = 1},
103};
104
105/* sq930x registers */
106#define SQ930_CTRL_UCBUS_IO	0x0001
107#define SQ930_CTRL_I2C_IO	0x0002
108#define SQ930_CTRL_GPIO		0x0005
109#define SQ930_CTRL_CAP_START	0x0010
110#define SQ930_CTRL_CAP_STOP	0x0011
111#define SQ930_CTRL_SET_EXPOSURE 0x001d
112#define SQ930_CTRL_RESET	0x001e
113#define SQ930_CTRL_GET_DEV_INFO 0x001f
114
115/* gpio 1 (8..15) */
116#define SQ930_GPIO_DFL_I2C_SDA	0x0001
117#define SQ930_GPIO_DFL_I2C_SCL	0x0002
118#define SQ930_GPIO_RSTBAR	0x0004
119#define SQ930_GPIO_EXTRA1	0x0040
120#define SQ930_GPIO_EXTRA2	0x0080
121/* gpio 3 (24..31) */
122#define SQ930_GPIO_POWER	0x0200
123#define SQ930_GPIO_DFL_LED	0x1000
124
125struct ucbus_write_cmd {
126	u16	bw_addr;
127	u8	bw_data;
128};
129struct i2c_write_cmd {
130	u8	reg;
131	u16	val;
132};
133
134static const struct ucbus_write_cmd icx098bq_start_0[] = {
135	{0x0354, 0x00}, {0x03fa, 0x00}, {0xf800, 0x02}, {0xf801, 0xce},
136	{0xf802, 0xc1}, {0xf804, 0x00}, {0xf808, 0x00}, {0xf809, 0x0e},
137	{0xf80a, 0x01}, {0xf80b, 0xee}, {0xf807, 0x60}, {0xf80c, 0x02},
138	{0xf80d, 0xf0}, {0xf80e, 0x03}, {0xf80f, 0x0a}, {0xf81c, 0x02},
139	{0xf81d, 0xf0}, {0xf81e, 0x03}, {0xf81f, 0x0a}, {0xf83a, 0x00},
140	{0xf83b, 0x10}, {0xf83c, 0x00}, {0xf83d, 0x4e}, {0xf810, 0x04},
141	{0xf811, 0x00}, {0xf812, 0x02}, {0xf813, 0x10}, {0xf803, 0x00},
142	{0xf814, 0x01}, {0xf815, 0x18}, {0xf816, 0x00}, {0xf817, 0x48},
143	{0xf818, 0x00}, {0xf819, 0x25}, {0xf81a, 0x00}, {0xf81b, 0x3c},
144	{0xf82f, 0x03}, {0xf820, 0xff}, {0xf821, 0x0d}, {0xf822, 0xff},
145	{0xf823, 0x07}, {0xf824, 0xff}, {0xf825, 0x03}, {0xf826, 0xff},
146	{0xf827, 0x06}, {0xf828, 0xff}, {0xf829, 0x03}, {0xf82a, 0xff},
147	{0xf82b, 0x0c}, {0xf82c, 0xfd}, {0xf82d, 0x01}, {0xf82e, 0x00},
148	{0xf830, 0x00}, {0xf831, 0x47}, {0xf832, 0x00}, {0xf833, 0x00},
149	{0xf850, 0x00}, {0xf851, 0x00}, {0xf852, 0x00}, {0xf853, 0x24},
150	{0xf854, 0x00}, {0xf855, 0x18}, {0xf856, 0x00}, {0xf857, 0x3c},
151	{0xf858, 0x00}, {0xf859, 0x0c}, {0xf85a, 0x00}, {0xf85b, 0x30},
152	{0xf85c, 0x00}, {0xf85d, 0x0c}, {0xf85e, 0x00}, {0xf85f, 0x30},
153	{0xf860, 0x00}, {0xf861, 0x48}, {0xf862, 0x01}, {0xf863, 0xdc},
154	{0xf864, 0xff}, {0xf865, 0x98}, {0xf866, 0xff}, {0xf867, 0xc0},
155	{0xf868, 0xff}, {0xf869, 0x70}, {0xf86c, 0xff}, {0xf86d, 0x00},
156	{0xf86a, 0xff}, {0xf86b, 0x48}, {0xf86e, 0xff}, {0xf86f, 0x00},
157	{0xf870, 0x01}, {0xf871, 0xdb}, {0xf872, 0x01}, {0xf873, 0xfa},
158	{0xf874, 0x01}, {0xf875, 0xdb}, {0xf876, 0x01}, {0xf877, 0xfa},
159	{0xf878, 0x0f}, {0xf879, 0x0f}, {0xf87a, 0xff}, {0xf87b, 0xff},
160	{0xf800, 0x03}
161};
162static const struct ucbus_write_cmd icx098bq_start_1[] = {
163	{0xf5f0, 0x00}, {0xf5f1, 0xcd}, {0xf5f2, 0x80}, {0xf5f3, 0x80},
164	{0xf5f4, 0xc0},
165	{0xf5f0, 0x49}, {0xf5f1, 0xcd}, {0xf5f2, 0x80}, {0xf5f3, 0x80},
166	{0xf5f4, 0xc0},
167	{0xf5fa, 0x00}, {0xf5f6, 0x00}, {0xf5f7, 0x00}, {0xf5f8, 0x00},
168	{0xf5f9, 0x00}
169};
170
171static const struct ucbus_write_cmd icx098bq_start_2[] = {
172	{0xf800, 0x02}, {0xf807, 0xff}, {0xf805, 0x82}, {0xf806, 0x00},
173	{0xf807, 0x7f}, {0xf800, 0x03},
174	{0xf800, 0x02}, {0xf807, 0xff}, {0xf805, 0x40}, {0xf806, 0x00},
175	{0xf807, 0x7f}, {0xf800, 0x03},
176	{0xf800, 0x02}, {0xf807, 0xff}, {0xf805, 0xcf}, {0xf806, 0xd0},
177	{0xf807, 0x7f}, {0xf800, 0x03},
178	{0xf800, 0x02}, {0xf807, 0xff}, {0xf805, 0x00}, {0xf806, 0x00},
179	{0xf807, 0x7f}, {0xf800, 0x03}
180};
181
182static const struct ucbus_write_cmd lz24bp_start_0[] = {
183	{0x0354, 0x00}, {0x03fa, 0x00}, {0xf800, 0x02}, {0xf801, 0xbe},
184	{0xf802, 0xc6}, {0xf804, 0x00}, {0xf808, 0x00}, {0xf809, 0x06},
185	{0xf80a, 0x01}, {0xf80b, 0xfe}, {0xf807, 0x84}, {0xf80c, 0x02},
186	{0xf80d, 0xf7}, {0xf80e, 0x03}, {0xf80f, 0x0b}, {0xf81c, 0x00},
187	{0xf81d, 0x49}, {0xf81e, 0x03}, {0xf81f, 0x0b}, {0xf83a, 0x00},
188	{0xf83b, 0x01}, {0xf83c, 0x00}, {0xf83d, 0x6b}, {0xf810, 0x03},
189	{0xf811, 0x10}, {0xf812, 0x02}, {0xf813, 0x6f}, {0xf803, 0x00},
190	{0xf814, 0x00}, {0xf815, 0x44}, {0xf816, 0x00}, {0xf817, 0x48},
191	{0xf818, 0x00}, {0xf819, 0x25}, {0xf81a, 0x00}, {0xf81b, 0x3c},
192	{0xf82f, 0x03}, {0xf820, 0xff}, {0xf821, 0x0d}, {0xf822, 0xff},
193	{0xf823, 0x07}, {0xf824, 0xfd}, {0xf825, 0x07}, {0xf826, 0xf0},
194	{0xf827, 0x0c}, {0xf828, 0xff}, {0xf829, 0x03}, {0xf82a, 0xff},
195	{0xf82b, 0x0c}, {0xf82c, 0xfc}, {0xf82d, 0x01}, {0xf82e, 0x00},
196	{0xf830, 0x00}, {0xf831, 0x47}, {0xf832, 0x00}, {0xf833, 0x00},
197	{0xf850, 0x00}, {0xf851, 0x00}, {0xf852, 0x00}, {0xf853, 0x24},
198	{0xf854, 0x00}, {0xf855, 0x0c}, {0xf856, 0x00}, {0xf857, 0x30},
199	{0xf858, 0x00}, {0xf859, 0x18}, {0xf85a, 0x00}, {0xf85b, 0x3c},
200	{0xf85c, 0x00}, {0xf85d, 0x18}, {0xf85e, 0x00}, {0xf85f, 0x3c},
201	{0xf860, 0xff}, {0xf861, 0x37}, {0xf862, 0xff}, {0xf863, 0x1d},
202	{0xf864, 0xff}, {0xf865, 0x98}, {0xf866, 0xff}, {0xf867, 0xc0},
203	{0xf868, 0x00}, {0xf869, 0x37}, {0xf86c, 0x02}, {0xf86d, 0x1d},
204	{0xf86a, 0x00}, {0xf86b, 0x37}, {0xf86e, 0x02}, {0xf86f, 0x1d},
205	{0xf870, 0x01}, {0xf871, 0xc6}, {0xf872, 0x02}, {0xf873, 0x04},
206	{0xf874, 0x01}, {0xf875, 0xc6}, {0xf876, 0x02}, {0xf877, 0x04},
207	{0xf878, 0x0f}, {0xf879, 0x0f}, {0xf87a, 0xff}, {0xf87b, 0xff},
208	{0xf800, 0x03}
209};
210static const struct ucbus_write_cmd lz24bp_start_1_gen[] = {
211	{0xf5f0, 0x00}, {0xf5f1, 0xff}, {0xf5f2, 0x80}, {0xf5f3, 0x80},
212	{0xf5f4, 0xb3},
213	{0xf5f0, 0x40}, {0xf5f1, 0xff}, {0xf5f2, 0x80}, {0xf5f3, 0x80},
214	{0xf5f4, 0xb3},
215	{0xf5fa, 0x00}, {0xf5f6, 0x00}, {0xf5f7, 0x00}, {0xf5f8, 0x00},
216	{0xf5f9, 0x00}
217};
218
219static const struct ucbus_write_cmd lz24bp_start_1_clm[] = {
220	{0xf5f0, 0x00}, {0xf5f1, 0xff}, {0xf5f2, 0x88}, {0xf5f3, 0x88},
221	{0xf5f4, 0xc0},
222	{0xf5f0, 0x40}, {0xf5f1, 0xff}, {0xf5f2, 0x88}, {0xf5f3, 0x88},
223	{0xf5f4, 0xc0},
224	{0xf5fa, 0x00}, {0xf5f6, 0x00}, {0xf5f7, 0x00}, {0xf5f8, 0x00},
225	{0xf5f9, 0x00}
226};
227
228static const struct ucbus_write_cmd lz24bp_start_2[] = {
229	{0xf800, 0x02}, {0xf807, 0xff}, {0xf805, 0x80}, {0xf806, 0x00},
230	{0xf807, 0x7f}, {0xf800, 0x03},
231	{0xf800, 0x02}, {0xf807, 0xff}, {0xf805, 0x4e}, {0xf806, 0x00},
232	{0xf807, 0x7f}, {0xf800, 0x03},
233	{0xf800, 0x02}, {0xf807, 0xff}, {0xf805, 0xc0}, {0xf806, 0x48},
234	{0xf807, 0x7f}, {0xf800, 0x03},
235	{0xf800, 0x02}, {0xf807, 0xff}, {0xf805, 0x00}, {0xf806, 0x00},
236	{0xf807, 0x7f}, {0xf800, 0x03}
237};
238
239static const struct ucbus_write_cmd mi0360_start_0[] = {
240	{0x0354, 0x00}, {0x03fa, 0x00}, {0xf332, 0xcc}, {0xf333, 0xcc},
241	{0xf334, 0xcc}, {0xf335, 0xcc}, {0xf33f, 0x00}
242};
243static const struct i2c_write_cmd mi0360_init_23[] = {
244	{0x30, 0x0040},		/* reserved - def 0x0005 */
245	{0x31, 0x0000},		/* reserved - def 0x002a */
246	{0x34, 0x0100},		/* reserved - def 0x0100 */
247	{0x3d, 0x068f},		/* reserved - def 0x068f */
248};
249static const struct i2c_write_cmd mi0360_init_24[] = {
250	{0x03, 0x01e5},		/* window height */
251	{0x04, 0x0285},		/* window width */
252};
253static const struct i2c_write_cmd mi0360_init_25[] = {
254	{0x35, 0x0020},		/* global gain */
255	{0x2b, 0x0020},		/* green1 gain */
256	{0x2c, 0x002a},		/* blue gain */
257	{0x2d, 0x0028},		/* red gain */
258	{0x2e, 0x0020},		/* green2 gain */
259};
260static const struct ucbus_write_cmd mi0360_start_1[] = {
261	{0xf5f0, 0x11}, {0xf5f1, 0x99}, {0xf5f2, 0x80}, {0xf5f3, 0x80},
262	{0xf5f4, 0xa6},
263	{0xf5f0, 0x51}, {0xf5f1, 0x99}, {0xf5f2, 0x80}, {0xf5f3, 0x80},
264	{0xf5f4, 0xa6},
265	{0xf5fa, 0x00}, {0xf5f6, 0x00}, {0xf5f7, 0x00}, {0xf5f8, 0x00},
266	{0xf5f9, 0x00}
267};
268static const struct i2c_write_cmd mi0360_start_2[] = {
269	{0x62, 0x041d},		/* reserved - def 0x0418 */
270};
271static const struct i2c_write_cmd mi0360_start_3[] = {
272	{0x05, 0x007b},		/* horiz blanking */
273};
274static const struct i2c_write_cmd mi0360_start_4[] = {
275	{0x05, 0x03f5},		/* horiz blanking */
276};
277
278static const struct i2c_write_cmd mt9v111_init_0[] = {
279	{0x01, 0x0001},		/* select IFP/SOC registers */
280	{0x06, 0x300c},		/* operating mode control */
281	{0x08, 0xcc00},		/* output format control (RGB) */
282	{0x01, 0x0004},		/* select sensor core registers */
283};
284static const struct i2c_write_cmd mt9v111_init_1[] = {
285	{0x03, 0x01e5},		/* window height */
286	{0x04, 0x0285},		/* window width */
287};
288static const struct i2c_write_cmd mt9v111_init_2[] = {
289	{0x30, 0x7800},
290	{0x31, 0x0000},
291	{0x07, 0x3002},		/* output control */
292	{0x35, 0x0020},		/* global gain */
293	{0x2b, 0x0020},		/* green1 gain */
294	{0x2c, 0x0020},		/* blue gain */
295	{0x2d, 0x0020},		/* red gain */
296	{0x2e, 0x0020},		/* green2 gain */
297};
298static const struct ucbus_write_cmd mt9v111_start_1[] = {
299	{0xf5f0, 0x11}, {0xf5f1, 0x96}, {0xf5f2, 0x80}, {0xf5f3, 0x80},
300	{0xf5f4, 0xaa},
301	{0xf5f0, 0x51}, {0xf5f1, 0x96}, {0xf5f2, 0x80}, {0xf5f3, 0x80},
302	{0xf5f4, 0xaa},
303	{0xf5fa, 0x00}, {0xf5f6, 0x0a}, {0xf5f7, 0x0a}, {0xf5f8, 0x0a},
304	{0xf5f9, 0x0a}
305};
306static const struct i2c_write_cmd mt9v111_init_3[] = {
307	{0x62, 0x0405},
308};
309static const struct i2c_write_cmd mt9v111_init_4[] = {
310/*	{0x05, 0x00ce}, */
311	{0x05, 0x005d},		/* horizontal blanking */
312};
313
314static const struct ucbus_write_cmd ov7660_start_0[] = {
315	{0x0354, 0x00}, {0x03fa, 0x00}, {0xf332, 0x00}, {0xf333, 0xc0},
316	{0xf334, 0x39}, {0xf335, 0xe7}, {0xf33f, 0x03}
317};
318
319static const struct ucbus_write_cmd ov9630_start_0[] = {
320	{0x0354, 0x00}, {0x03fa, 0x00}, {0xf332, 0x00}, {0xf333, 0x00},
321	{0xf334, 0x3e}, {0xf335, 0xf8}, {0xf33f, 0x03}
322};
323
324/* start parameters indexed by [sensor][mode] */
325static const struct cap_s {
326	u8	cc_sizeid;
327	u8	cc_bytes[32];
328} capconfig[4][2] = {
329	[SENSOR_ICX098BQ] = {
330		{2,				/* Bayer 320x240 */
331		  {0x05, 0x1f, 0x20, 0x0e, 0x00, 0x9f, 0x02, 0xee,
332		   0x01, 0x01, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
333		   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0,
334		   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
335		{4,				/* Bayer 640x480 */
336		  {0x01, 0x1f, 0x20, 0x0e, 0x00, 0x9f, 0x02, 0xee,
337		   0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
338		   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
339		   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
340	},
341	[SENSOR_LZ24BP] = {
342		{2,				/* Bayer 320x240 */
343		  {0x05, 0x22, 0x20, 0x0e, 0x00, 0xa2, 0x02, 0xee,
344		   0x01, 0x01, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
345		   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
346		   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
347		{4,				/* Bayer 640x480 */
348		  {0x01, 0x22, 0x20, 0x0e, 0x00, 0xa2, 0x02, 0xee,
349		   0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
350		   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
351		   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
352	},
353	[SENSOR_MI0360] = {
354		{2,				/* Bayer 320x240 */
355		  {0x05, 0x02, 0x20, 0x01, 0x20, 0x82, 0x02, 0xe1,
356		   0x01, 0x01, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
357		   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
358		   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
359		{4,				/* Bayer 640x480 */
360		  {0x01, 0x02, 0x20, 0x01, 0x20, 0x82, 0x02, 0xe1,
361		   0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
362		   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
363		   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
364	},
365	[SENSOR_MT9V111] = {
366		{2,				/* Bayer 320x240 */
367		  {0x05, 0x02, 0x20, 0x01, 0x20, 0x82, 0x02, 0xe1,
368		   0x01, 0x01, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
369		   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
370		   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
371		{4,				/* Bayer 640x480 */
372		  {0x01, 0x02, 0x20, 0x01, 0x20, 0x82, 0x02, 0xe1,
373		   0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
374		   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
375		   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
376	},
377};
378
379struct sensor_s {
380	const char *name;
381	u8 i2c_addr;
382	u8 i2c_dum;
383	u8 gpio[5];
384	u8 cmd_len;
385	const struct ucbus_write_cmd *cmd;
386};
387
388static const struct sensor_s sensor_tb[] = {
389	[SENSOR_ICX098BQ] = {
390		"icx098bp",
391		0x00, 0x00,
392		{0,
393		 SQ930_GPIO_DFL_I2C_SDA | SQ930_GPIO_DFL_I2C_SCL,
394		 SQ930_GPIO_DFL_I2C_SDA,
395		 0,
396		 SQ930_GPIO_RSTBAR
397		},
398		8, icx098bq_start_0
399	    },
400	[SENSOR_LZ24BP] = {
401		"lz24bp",
402		0x00, 0x00,
403		{0,
404		 SQ930_GPIO_DFL_I2C_SDA | SQ930_GPIO_DFL_I2C_SCL,
405		 SQ930_GPIO_DFL_I2C_SDA,
406		 0,
407		 SQ930_GPIO_RSTBAR
408		},
409		8, lz24bp_start_0
410	    },
411	[SENSOR_MI0360] = {
412		"mi0360",
413		0x5d, 0x80,
414		{SQ930_GPIO_RSTBAR,
415		 SQ930_GPIO_DFL_I2C_SDA | SQ930_GPIO_DFL_I2C_SCL,
416		 SQ930_GPIO_DFL_I2C_SDA,
417		 0,
418		 0
419		},
420		7, mi0360_start_0
421	    },
422	[SENSOR_MT9V111] = {
423		"mt9v111",
424		0x5c, 0x7f,
425		{SQ930_GPIO_RSTBAR,
426		 SQ930_GPIO_DFL_I2C_SDA | SQ930_GPIO_DFL_I2C_SCL,
427		 SQ930_GPIO_DFL_I2C_SDA,
428		 0,
429		 0
430		},
431		7, mi0360_start_0
432	    },
433	[SENSOR_OV7660] = {
434		"ov7660",
435		0x21, 0x00,
436		{0,
437		 SQ930_GPIO_DFL_I2C_SDA | SQ930_GPIO_DFL_I2C_SCL,
438		 SQ930_GPIO_DFL_I2C_SDA,
439		 0,
440		 SQ930_GPIO_RSTBAR
441		},
442		7, ov7660_start_0
443	    },
444	[SENSOR_OV9630] = {
445		"ov9630",
446		0x30, 0x00,
447		{0,
448		 SQ930_GPIO_DFL_I2C_SDA | SQ930_GPIO_DFL_I2C_SCL,
449		 SQ930_GPIO_DFL_I2C_SDA,
450		 0,
451		 SQ930_GPIO_RSTBAR
452		},
453		7, ov9630_start_0
454	    },
455};
456
457static void reg_r(struct gspca_dev *gspca_dev,
458		u16 value, int len)
459{
460	int ret;
461
462	if (gspca_dev->usb_err < 0)
463		return;
464	ret = usb_control_msg(gspca_dev->dev,
465			usb_rcvctrlpipe(gspca_dev->dev, 0),
466			0x0c,
467			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
468			value, 0, gspca_dev->usb_buf, len,
469			500);
470	if (ret < 0) {
471		PDEBUG(D_ERR, "reg_r %04x failed %d", value, ret);
472		gspca_dev->usb_err = ret;
473	}
474}
475
476static void reg_w(struct gspca_dev *gspca_dev, u16 value, u16 index)
477{
478	int ret;
479
480	if (gspca_dev->usb_err < 0)
481		return;
482	PDEBUG(D_USBO, "reg_w v: %04x i: %04x", value, index);
483	ret = usb_control_msg(gspca_dev->dev,
484			usb_sndctrlpipe(gspca_dev->dev, 0),
485			0x0c,			/* request */
486			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
487			value, index, NULL, 0,
488			500);
489	msleep(30);
490	if (ret < 0) {
491		PDEBUG(D_ERR, "reg_w %04x %04x failed %d", value, index, ret);
492		gspca_dev->usb_err = ret;
493	}
494}
495
496static void reg_wb(struct gspca_dev *gspca_dev, u16 value, u16 index,
497		const u8 *data, int len)
498{
499	int ret;
500
501	if (gspca_dev->usb_err < 0)
502		return;
503	PDEBUG(D_USBO, "reg_wb v: %04x i: %04x %02x...%02x",
504			value, index, *data, data[len - 1]);
505	memcpy(gspca_dev->usb_buf, data, len);
506	ret = usb_control_msg(gspca_dev->dev,
507			usb_sndctrlpipe(gspca_dev->dev, 0),
508			0x0c,			/* request */
509			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
510			value, index, gspca_dev->usb_buf, len,
511			1000);
512	msleep(30);
513	if (ret < 0) {
514		PDEBUG(D_ERR, "reg_wb %04x %04x failed %d", value, index, ret);
515		gspca_dev->usb_err = ret;
516	}
517}
518
519static void i2c_write(struct sd *sd,
520			const struct i2c_write_cmd *cmd,
521			int ncmds)
522{
523	struct gspca_dev *gspca_dev = &sd->gspca_dev;
524	const struct sensor_s *sensor;
525	u16 val, idx;
526	u8 *buf;
527	int ret;
528
529	if (gspca_dev->usb_err < 0)
530		return;
531
532	sensor = &sensor_tb[sd->sensor];
533
534	val = (sensor->i2c_addr << 8) | SQ930_CTRL_I2C_IO;
535	idx = (cmd->val & 0xff00) | cmd->reg;
536
537	buf = gspca_dev->usb_buf;
538	*buf++ = sensor->i2c_dum;
539	*buf++ = cmd->val;
540
541	while (--ncmds > 0) {
542		cmd++;
543		*buf++ = cmd->reg;
544		*buf++ = cmd->val >> 8;
545		*buf++ = sensor->i2c_dum;
546		*buf++ = cmd->val;
547	}
548
549	PDEBUG(D_USBO, "i2c_w v: %04x i: %04x %02x...%02x",
550			val, idx, gspca_dev->usb_buf[0], buf[-1]);
551	ret = usb_control_msg(gspca_dev->dev,
552			usb_sndctrlpipe(gspca_dev->dev, 0),
553			0x0c,			/* request */
554			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
555			val, idx,
556			gspca_dev->usb_buf, buf - gspca_dev->usb_buf,
557			500);
558	if (ret < 0) {
559		PDEBUG(D_ERR, "i2c_write failed %d", ret);
560		gspca_dev->usb_err = ret;
561	}
562}
563
564static void ucbus_write(struct gspca_dev *gspca_dev,
565			const struct ucbus_write_cmd *cmd,
566			int ncmds,
567			int batchsize)
568{
569	u8 *buf;
570	u16 val, idx;
571	int len, ret;
572
573	if (gspca_dev->usb_err < 0)
574		return;
575
576#ifdef GSPCA_DEBUG
577	if ((batchsize - 1) * 3 > USB_BUF_SZ) {
578		err("Bug: usb_buf overflow");
579		gspca_dev->usb_err = -ENOMEM;
580		return;
581	}
582#endif
583
584	for (;;) {
585		len = ncmds;
586		if (len > batchsize)
587			len = batchsize;
588		ncmds -= len;
589
590		val = (cmd->bw_addr << 8) | SQ930_CTRL_UCBUS_IO;
591		idx = (cmd->bw_data << 8) | (cmd->bw_addr >> 8);
592
593		buf = gspca_dev->usb_buf;
594		while (--len > 0) {
595			cmd++;
596			*buf++ = cmd->bw_addr;
597			*buf++ = cmd->bw_addr >> 8;
598			*buf++ = cmd->bw_data;
599		}
600		if (buf != gspca_dev->usb_buf)
601			PDEBUG(D_USBO, "ucbus v: %04x i: %04x %02x...%02x",
602					val, idx,
603					gspca_dev->usb_buf[0], buf[-1]);
604		else
605			PDEBUG(D_USBO, "ucbus v: %04x i: %04x",
606					val, idx);
607		ret = usb_control_msg(gspca_dev->dev,
608				usb_sndctrlpipe(gspca_dev->dev, 0),
609				0x0c,			/* request */
610			   USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
611				val, idx,
612				gspca_dev->usb_buf, buf - gspca_dev->usb_buf,
613				500);
614		if (ret < 0) {
615			PDEBUG(D_ERR, "ucbus_write failed %d", ret);
616			gspca_dev->usb_err = ret;
617			return;
618		}
619		msleep(30);
620		if (ncmds <= 0)
621			break;
622		cmd++;
623	}
624}
625
626static void gpio_set(struct sd *sd, u16 val, u16 mask)
627{
628	struct gspca_dev *gspca_dev = &sd->gspca_dev;
629
630	if (mask & 0x00ff) {
631		sd->gpio[0] &= ~mask;
632		sd->gpio[0] |= val;
633		reg_w(gspca_dev, 0x0100 | SQ930_CTRL_GPIO,
634			~sd->gpio[0] << 8);
635	}
636	mask >>= 8;
637	val >>= 8;
638	if (mask) {
639		sd->gpio[1] &= ~mask;
640		sd->gpio[1] |= val;
641		reg_w(gspca_dev, 0x0300 | SQ930_CTRL_GPIO,
642			~sd->gpio[1] << 8);
643	}
644}
645
646static void gpio_init(struct sd *sd,
647			const u8 *gpio)
648{
649	gpio_set(sd, *gpio++, 0x000f);
650	gpio_set(sd, *gpio++, 0x000f);
651	gpio_set(sd, *gpio++, 0x000f);
652	gpio_set(sd, *gpio++, 0x000f);
653	gpio_set(sd, *gpio, 0x000f);
654}
655
656static void bridge_init(struct sd *sd)
657{
658	static const struct ucbus_write_cmd clkfreq_cmd = {
659				0xf031, 0	/* SQ930_CLKFREQ_60MHZ */
660	};
661
662	ucbus_write(&sd->gspca_dev, &clkfreq_cmd, 1, 1);
663
664	gpio_set(sd, SQ930_GPIO_POWER, 0xff00);
665}
666
667static void cmos_probe(struct gspca_dev *gspca_dev)
668{
669	struct sd *sd = (struct sd *) gspca_dev;
670	int i;
671	const struct sensor_s *sensor;
672	static const u8 probe_order[] = {
673/*		SENSOR_LZ24BP,		(tested as ccd) */
674		SENSOR_OV9630,
675		SENSOR_MI0360,
676		SENSOR_OV7660,
677		SENSOR_MT9V111,
678	};
679
680	for (i = 0; i < ARRAY_SIZE(probe_order); i++) {
681		sensor = &sensor_tb[probe_order[i]];
682		ucbus_write(&sd->gspca_dev, sensor->cmd, sensor->cmd_len, 8);
683		gpio_init(sd, sensor->gpio);
684		msleep(100);
685		reg_r(gspca_dev, (sensor->i2c_addr << 8) | 0x001c, 1);
686		msleep(100);
687		if (gspca_dev->usb_buf[0] != 0)
688			break;
689	}
690	if (i >= ARRAY_SIZE(probe_order))
691		PDEBUG(D_PROBE, "Unknown sensor");
692	else
693		sd->sensor = probe_order[i];
694}
695
696static void mt9v111_init(struct gspca_dev *gspca_dev)
697{
698	int i, nwait;
699	static const u8 cmd_001b[] = {
700		0x00, 0x3b, 0xf6, 0x01, 0x03, 0x02, 0x00, 0x00,
701		0x00, 0x00, 0x00
702	};
703	static const u8 cmd_011b[][7] = {
704		{0x10, 0x01, 0x66, 0x08, 0x00, 0x00, 0x00},
705		{0x01, 0x00, 0x1a, 0x04, 0x00, 0x00, 0x00},
706		{0x20, 0x00, 0x10, 0x04, 0x00, 0x00, 0x00},
707		{0x02, 0x01, 0xae, 0x01, 0x00, 0x00, 0x00},
708	};
709
710	reg_wb(gspca_dev, 0x001b, 0x0000, cmd_001b, sizeof cmd_001b);
711	for (i = 0; i < ARRAY_SIZE(cmd_011b); i++) {
712		reg_wb(gspca_dev, 0x001b, 0x0000, cmd_011b[i],
713				ARRAY_SIZE(cmd_011b[0]));
714		msleep(400);
715		nwait = 20;
716		for (;;) {
717			reg_r(gspca_dev, 0x031b, 1);
718			if (gspca_dev->usb_buf[0] == 0
719			 || gspca_dev->usb_err != 0)
720				break;
721			if (--nwait < 0) {
722				PDEBUG(D_PROBE, "mt9v111_init timeout");
723				gspca_dev->usb_err = -ETIME;
724				return;
725			}
726			msleep(50);
727		}
728	}
729}
730
731static void global_init(struct sd *sd, int first_time)
732{
733	switch (sd->sensor) {
734	case SENSOR_ICX098BQ:
735		if (first_time)
736			ucbus_write(&sd->gspca_dev,
737					icx098bq_start_0,
738					8, 8);
739		gpio_init(sd, sensor_tb[sd->sensor].gpio);
740		break;
741	case SENSOR_LZ24BP:
742		if (sd->type != Creative_live_motion)
743			gpio_set(sd, SQ930_GPIO_EXTRA1, 0x00ff);
744		else
745			gpio_set(sd, 0, 0x00ff);
746		msleep(50);
747		if (first_time)
748			ucbus_write(&sd->gspca_dev,
749					lz24bp_start_0,
750					8, 8);
751		gpio_init(sd, sensor_tb[sd->sensor].gpio);
752		break;
753	case SENSOR_MI0360:
754		if (first_time)
755			ucbus_write(&sd->gspca_dev,
756					mi0360_start_0,
757					ARRAY_SIZE(mi0360_start_0),
758					8);
759		gpio_init(sd, sensor_tb[sd->sensor].gpio);
760		gpio_set(sd, SQ930_GPIO_EXTRA2, SQ930_GPIO_EXTRA2);
761		break;
762	default:
763/*	case SENSOR_MT9V111: */
764		if (first_time)
765			mt9v111_init(&sd->gspca_dev);
766		else
767			gpio_init(sd, sensor_tb[sd->sensor].gpio);
768		break;
769	}
770}
771
772static void lz24bp_ppl(struct sd *sd, u16 ppl)
773{
774	struct ucbus_write_cmd cmds[2] = {
775		{0xf810, ppl >> 8},
776		{0xf811, ppl}
777	};
778
779	ucbus_write(&sd->gspca_dev, cmds, ARRAY_SIZE(cmds), 2);
780}
781
782static void setexposure(struct gspca_dev *gspca_dev)
783{
784	struct sd *sd = (struct sd *) gspca_dev;
785	int i, integclks, intstartclk, frameclks, min_frclk;
786	const struct sensor_s *sensor;
787	u16 cmd;
788	u8 buf[15];
789
790	integclks = sd->expo;
791	i = 0;
792	cmd = SQ930_CTRL_SET_EXPOSURE;
793
794	switch (sd->sensor) {
795	case SENSOR_ICX098BQ:			/* ccd */
796	case SENSOR_LZ24BP:
797		min_frclk = sd->sensor == SENSOR_ICX098BQ ? 0x210 : 0x26f;
798		if (integclks >= min_frclk) {
799			intstartclk = 0;
800			frameclks = integclks;
801		} else {
802			intstartclk = min_frclk - integclks;
803			frameclks = min_frclk;
804		}
805		buf[i++] = intstartclk >> 8;
806		buf[i++] = intstartclk;
807		buf[i++] = frameclks >> 8;
808		buf[i++] = frameclks;
809		buf[i++] = sd->gain;
810		break;
811	default:				/* cmos */
812/*	case SENSOR_MI0360: */
813/*	case SENSOR_MT9V111: */
814		cmd |= 0x0100;
815		sensor = &sensor_tb[sd->sensor];
816		buf[i++] = sensor->i2c_addr;	/* i2c_slave_addr */
817		buf[i++] = 0x08;	/* 2 * ni2c */
818		buf[i++] = 0x09;	/* reg = shutter width */
819		buf[i++] = integclks >> 8; /* val H */
820		buf[i++] = sensor->i2c_dum;
821		buf[i++] = integclks;	/* val L */
822		buf[i++] = 0x35;	/* reg = global gain */
823		buf[i++] = 0x00;	/* val H */
824		buf[i++] = sensor->i2c_dum;
825		buf[i++] = 0x80 + sd->gain / 2; /* val L */
826		buf[i++] = 0x00;
827		buf[i++] = 0x00;
828		buf[i++] = 0x00;
829		buf[i++] = 0x00;
830		buf[i++] = 0x83;
831		break;
832	}
833	reg_wb(gspca_dev, cmd, 0, buf, i);
834}
835
836/* This function is called at probe time just before sd_init */
837static int sd_config(struct gspca_dev *gspca_dev,
838		const struct usb_device_id *id)
839{
840	struct sd *sd = (struct sd *) gspca_dev;
841	struct cam *cam = &gspca_dev->cam;
842
843	sd->sensor = id->driver_info >> 8;
844	sd->type = id->driver_info;
845
846	cam->cam_mode = vga_mode;
847	cam->nmodes = ARRAY_SIZE(vga_mode);
848
849	cam->bulk = 1;
850
851	sd->gain = GAIN_DEF;
852	sd->expo = EXPO_DEF;
853
854	return 0;
855}
856
857/* this function is called at probe and resume time */
858static int sd_init(struct gspca_dev *gspca_dev)
859{
860	struct sd *sd = (struct sd *) gspca_dev;
861
862	sd->gpio[0] = sd->gpio[1] = 0xff;	/* force gpio rewrite */
863
864
865	reg_r(gspca_dev, SQ930_CTRL_GET_DEV_INFO, 8);
866/* it returns:
867 * 03 00 12 93 0b f6 c9 00	live! ultra
868 * 03 00 07 93 0b f6 ca 00	live! ultra for notebook
869 * 03 00 12 93 0b fe c8 00	Trust WB-3500T
870 * 02 00 06 93 0b fe c8 00	Joy-IT 318S
871 * 03 00 12 93 0b f6 cf 00	icam tracer - sensor icx098bq
872 * 02 00 12 93 0b fe cf 00	ProQ Motion Webcam
873 *
874 * byte
875 * 0: 02 = usb 1.0 (12Mbit) / 03 = usb2.0 (480Mbit)
876 * 1: 00
877 * 2: 06 / 07 / 12 = mode webcam? firmware??
878 * 3: 93 chip = 930b (930b or 930c)
879 * 4: 0b
880 * 5: f6 = cdd (icx098bq, lz24bp) / fe or de = cmos (i2c) (other sensors)
881 * 6: c8 / c9 / ca / cf = mode webcam?, sensor? webcam?
882 * 7: 00
883 */
884	PDEBUG(D_PROBE, "info: %02x %02x %02x %02x %02x %02x %02x %02x",
885			gspca_dev->usb_buf[0],
886			gspca_dev->usb_buf[1],
887			gspca_dev->usb_buf[2],
888			gspca_dev->usb_buf[3],
889			gspca_dev->usb_buf[4],
890			gspca_dev->usb_buf[5],
891			gspca_dev->usb_buf[6],
892			gspca_dev->usb_buf[7]);
893
894	bridge_init(sd);
895
896	if (sd->sensor == SENSOR_MI0360) {
897
898		/* no sensor probe for icam tracer */
899		if (gspca_dev->usb_buf[5] == 0xf6)	/* if CMOS */
900			sd->sensor = SENSOR_ICX098BQ;
901		else
902			cmos_probe(gspca_dev);
903	}
904
905	PDEBUG(D_PROBE, "Sensor %s", sensor_tb[sd->sensor].name);
906
907	global_init(sd, 1);
908	return gspca_dev->usb_err;
909}
910
911/* send the start/stop commands to the webcam */
912static void send_start(struct gspca_dev *gspca_dev)
913{
914	struct sd *sd = (struct sd *) gspca_dev;
915	const struct cap_s *cap;
916	int mode;
917
918	mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
919	cap = &capconfig[sd->sensor][mode];
920	reg_wb(gspca_dev, 0x0900 | SQ930_CTRL_CAP_START,
921			0x0a00 | cap->cc_sizeid,
922			cap->cc_bytes, 32);
923}
924
925static void send_stop(struct gspca_dev *gspca_dev)
926{
927	reg_w(gspca_dev, SQ930_CTRL_CAP_STOP, 0);
928}
929
930/* function called at start time before URB creation */
931static int sd_isoc_init(struct gspca_dev *gspca_dev)
932{
933	struct sd *sd = (struct sd *) gspca_dev;
934
935	gspca_dev->cam.bulk_nurbs = 1;	/* there must be one URB only */
936	sd->do_ctrl = 0;
937	gspca_dev->cam.bulk_size = gspca_dev->width * gspca_dev->height + 8;
938	return 0;
939}
940
941/* start the capture */
942static int sd_start(struct gspca_dev *gspca_dev)
943{
944	struct sd *sd = (struct sd *) gspca_dev;
945	int mode;
946
947	bridge_init(sd);
948	global_init(sd, 0);
949	msleep(100);
950
951	switch (sd->sensor) {
952	case SENSOR_ICX098BQ:
953		ucbus_write(gspca_dev, icx098bq_start_0,
954				ARRAY_SIZE(icx098bq_start_0),
955				8);
956		ucbus_write(gspca_dev, icx098bq_start_1,
957				ARRAY_SIZE(icx098bq_start_1),
958				5);
959		ucbus_write(gspca_dev, icx098bq_start_2,
960				ARRAY_SIZE(icx098bq_start_2),
961				6);
962		msleep(50);
963
964		/* 1st start */
965		send_start(gspca_dev);
966		gpio_set(sd, SQ930_GPIO_EXTRA2 | SQ930_GPIO_RSTBAR, 0x00ff);
967		msleep(70);
968		reg_w(gspca_dev, SQ930_CTRL_CAP_STOP, 0x0000);
969		gpio_set(sd, 0x7f, 0x00ff);
970
971		/* 2nd start */
972		send_start(gspca_dev);
973		gpio_set(sd, SQ930_GPIO_EXTRA2 | SQ930_GPIO_RSTBAR, 0x00ff);
974		goto out;
975	case SENSOR_LZ24BP:
976		ucbus_write(gspca_dev, lz24bp_start_0,
977				ARRAY_SIZE(lz24bp_start_0),
978				8);
979		if (sd->type != Creative_live_motion)
980			ucbus_write(gspca_dev, lz24bp_start_1_gen,
981					ARRAY_SIZE(lz24bp_start_1_gen),
982					5);
983		else
984			ucbus_write(gspca_dev, lz24bp_start_1_clm,
985					ARRAY_SIZE(lz24bp_start_1_clm),
986					5);
987		ucbus_write(gspca_dev, lz24bp_start_2,
988				ARRAY_SIZE(lz24bp_start_2),
989				6);
990		mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
991		lz24bp_ppl(sd, mode == 1 ? 0x0564 : 0x0310);
992		msleep(10);
993		break;
994	case SENSOR_MI0360:
995		ucbus_write(gspca_dev, mi0360_start_0,
996				ARRAY_SIZE(mi0360_start_0),
997				8);
998		i2c_write(sd, mi0360_init_23,
999				ARRAY_SIZE(mi0360_init_23));
1000		i2c_write(sd, mi0360_init_24,
1001				ARRAY_SIZE(mi0360_init_24));
1002		i2c_write(sd, mi0360_init_25,
1003				ARRAY_SIZE(mi0360_init_25));
1004		ucbus_write(gspca_dev, mi0360_start_1,
1005				ARRAY_SIZE(mi0360_start_1),
1006				5);
1007		i2c_write(sd, mi0360_start_2,
1008				ARRAY_SIZE(mi0360_start_2));
1009		i2c_write(sd, mi0360_start_3,
1010				ARRAY_SIZE(mi0360_start_3));
1011
1012		/* 1st start */
1013		send_start(gspca_dev);
1014		msleep(60);
1015		send_stop(gspca_dev);
1016
1017		i2c_write(sd,
1018			mi0360_start_4, ARRAY_SIZE(mi0360_start_4));
1019		break;
1020	default:
1021/*	case SENSOR_MT9V111: */
1022		ucbus_write(gspca_dev, mi0360_start_0,
1023				ARRAY_SIZE(mi0360_start_0),
1024				8);
1025		i2c_write(sd, mt9v111_init_0,
1026				ARRAY_SIZE(mt9v111_init_0));
1027		i2c_write(sd, mt9v111_init_1,
1028				ARRAY_SIZE(mt9v111_init_1));
1029		i2c_write(sd, mt9v111_init_2,
1030				ARRAY_SIZE(mt9v111_init_2));
1031		ucbus_write(gspca_dev, mt9v111_start_1,
1032				ARRAY_SIZE(mt9v111_start_1),
1033				5);
1034		i2c_write(sd, mt9v111_init_3,
1035				ARRAY_SIZE(mt9v111_init_3));
1036		i2c_write(sd, mt9v111_init_4,
1037				ARRAY_SIZE(mt9v111_init_4));
1038		break;
1039	}
1040
1041	send_start(gspca_dev);
1042out:
1043	msleep(1000);
1044
1045	if (sd->sensor == SENSOR_MT9V111)
1046		gpio_set(sd, SQ930_GPIO_DFL_LED, SQ930_GPIO_DFL_LED);
1047
1048	sd->do_ctrl = 1;	/* set the exposure */
1049
1050	return gspca_dev->usb_err;
1051}
1052
1053static void sd_stopN(struct gspca_dev *gspca_dev)
1054{
1055	struct sd *sd = (struct sd *) gspca_dev;
1056
1057	if (sd->sensor == SENSOR_MT9V111)
1058		gpio_set(sd, 0, SQ930_GPIO_DFL_LED);
1059	send_stop(gspca_dev);
1060}
1061
1062/* function called when the application gets a new frame */
1063/* It sets the exposure if required and restart the bulk transfer. */
1064static void sd_dq_callback(struct gspca_dev *gspca_dev)
1065{
1066	struct sd *sd = (struct sd *) gspca_dev;
1067	int ret;
1068
1069	if (!sd->do_ctrl || gspca_dev->cam.bulk_nurbs != 0)
1070		return;
1071	sd->do_ctrl = 0;
1072
1073	setexposure(gspca_dev);
1074
1075	gspca_dev->cam.bulk_nurbs = 1;
1076	ret = usb_submit_urb(gspca_dev->urb[0], GFP_ATOMIC);
1077	if (ret < 0)
1078		PDEBUG(D_ERR|D_PACK, "sd_dq_callback() err %d", ret);
1079
1080	/* wait a little time, otherwise the webcam crashes */
1081	msleep(100);
1082}
1083
1084static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1085			u8 *data,		/* isoc packet */
1086			int len)		/* iso packet length */
1087{
1088	struct sd *sd = (struct sd *) gspca_dev;
1089
1090	if (sd->do_ctrl)
1091		gspca_dev->cam.bulk_nurbs = 0;
1092	gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
1093	gspca_frame_add(gspca_dev, INTER_PACKET, data, len - 8);
1094	gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
1095}
1096
1097static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
1098{
1099	struct sd *sd = (struct sd *) gspca_dev;
1100
1101	sd->gain = val;
1102	if (gspca_dev->streaming)
1103		sd->do_ctrl = 1;
1104	return 0;
1105}
1106
1107static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
1108{
1109	struct sd *sd = (struct sd *) gspca_dev;
1110
1111	*val = sd->gain;
1112	return 0;
1113}
1114static int sd_setexpo(struct gspca_dev *gspca_dev, __s32 val)
1115{
1116	struct sd *sd = (struct sd *) gspca_dev;
1117
1118	sd->expo = val;
1119	if (gspca_dev->streaming)
1120		sd->do_ctrl = 1;
1121	return 0;
1122}
1123
1124static int sd_getexpo(struct gspca_dev *gspca_dev, __s32 *val)
1125{
1126	struct sd *sd = (struct sd *) gspca_dev;
1127
1128	*val = sd->expo;
1129	return 0;
1130}
1131
1132/* sub-driver description */
1133static const struct sd_desc sd_desc = {
1134	.name   = MODULE_NAME,
1135	.ctrls = sd_ctrls,
1136	.nctrls = ARRAY_SIZE(sd_ctrls),
1137	.config = sd_config,
1138	.init   = sd_init,
1139	.isoc_init = sd_isoc_init,
1140	.start  = sd_start,
1141	.stopN  = sd_stopN,
1142	.pkt_scan = sd_pkt_scan,
1143	.dq_callback = sd_dq_callback,
1144};
1145
1146/* Table of supported USB devices */
1147#define ST(sensor, type) \
1148	.driver_info = (SENSOR_ ## sensor << 8) \
1149			| (type)
1150static const __devinitdata struct usb_device_id device_table[] = {
1151	{USB_DEVICE(0x041e, 0x4038), ST(MI0360, 0)},
1152	{USB_DEVICE(0x041e, 0x403c), ST(LZ24BP, 0)},
1153	{USB_DEVICE(0x041e, 0x403d), ST(LZ24BP, 0)},
1154	{USB_DEVICE(0x041e, 0x4041), ST(LZ24BP, Creative_live_motion)},
1155	{USB_DEVICE(0x2770, 0x930b), ST(MI0360, 0)},
1156	{USB_DEVICE(0x2770, 0x930c), ST(MI0360, 0)},
1157	{}
1158};
1159MODULE_DEVICE_TABLE(usb, device_table);
1160
1161
1162/* -- device connect -- */
1163static int sd_probe(struct usb_interface *intf,
1164		const struct usb_device_id *id)
1165{
1166	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1167			THIS_MODULE);
1168}
1169
1170static struct usb_driver sd_driver = {
1171	.name	    = MODULE_NAME,
1172	.id_table   = device_table,
1173	.probe	    = sd_probe,
1174	.disconnect = gspca_disconnect,
1175#ifdef CONFIG_PM
1176	.suspend    = gspca_suspend,
1177	.resume     = gspca_resume,
1178#endif
1179};
1180
1181/* -- module insert / remove -- */
1182static int __init sd_mod_init(void)
1183{
1184	int ret;
1185
1186	ret = usb_register(&sd_driver);
1187	if (ret < 0)
1188		return ret;
1189	info("registered");
1190	return 0;
1191}
1192static void __exit sd_mod_exit(void)
1193{
1194	usb_deregister(&sd_driver);
1195	info("deregistered");
1196}
1197
1198module_init(sd_mod_init);
1199module_exit(sd_mod_exit);
1200