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