]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - drivers/media/video/gspca/sq930x.c
V4L/DVB: gspca - main: Function gspca_dev_probe2 added
[mirror_ubuntu-artful-kernel.git] / drivers / media / video / gspca / sq930x.c
CommitLineData
618a864e
JFM
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#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{
359 usb_control_msg(gspca_dev->dev,
360 usb_rcvctrlpipe(gspca_dev->dev, 0),
361 0x0c,
362 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
363 value, 0, gspca_dev->usb_buf, len,
364 500);
365}
366
367static void reg_w(struct gspca_dev *gspca_dev, u16 value, u16 index)
368{
369 int ret;
370
371 if (gspca_dev->usb_err < 0)
372 return;
373 PDEBUG(D_USBO, "reg_w v: %04x i: %04x", value, index);
374 ret = usb_control_msg(gspca_dev->dev,
375 usb_sndctrlpipe(gspca_dev->dev, 0),
376 0x0c, /* request */
377 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
378 value, index, NULL, 0,
379 500);
380 msleep(30);
381 if (ret < 0) {
382 PDEBUG(D_ERR, "reg_w %04x %04x failed %d", value, index, ret);
383 gspca_dev->usb_err = ret;
384 }
385}
386
387static void reg_wb(struct gspca_dev *gspca_dev, u16 value, u16 index,
388 const u8 *data, int len)
389{
390 int ret;
391
392 if (gspca_dev->usb_err < 0)
393 return;
394 PDEBUG(D_USBO, "reg_wb v: %04x i: %04x %02x...%02x",
395 value, index, *data, data[len - 1]);
396 memcpy(gspca_dev->usb_buf, data, len);
397 ret = usb_control_msg(gspca_dev->dev,
398 usb_sndctrlpipe(gspca_dev->dev, 0),
399 0x0c, /* request */
400 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
401 value, index, gspca_dev->usb_buf, len,
402 1000);
403 msleep(30);
404 if (ret < 0) {
405 PDEBUG(D_ERR, "reg_wb %04x %04x failed %d", value, index, ret);
406 gspca_dev->usb_err = ret;
407 }
408}
409
410static void i2c_write(struct gspca_dev *gspca_dev,
411 const struct i2c_write_cmd *cmd,
412 int ncmds)
413{
414 u16 val, idx;
415 u8 *buf;
416 int ret;
417
418 if (gspca_dev->usb_err < 0)
419 return;
420
421 val = (0x5d << 8) | SQ930_CTRL_I2C_IO; /* 0x5d = mi0360 i2c addr */
422 idx = (cmd->val & 0xff00) | cmd->reg;
423
424 buf = gspca_dev->usb_buf;
425 *buf++ = 0x80;
426 *buf++ = cmd->val;
427
428 while (--ncmds > 0) {
429 cmd++;
430 *buf++ = cmd->reg;
431 *buf++ = cmd->val >> 8;
432 *buf++ = 0x80;
433 *buf++ = cmd->val;
434 }
435
436 PDEBUG(D_USBO, "i2c_w v: %04x i: %04x %02x...%02x",
437 val, idx, gspca_dev->usb_buf[0], buf[-1]);
438 ret = usb_control_msg(gspca_dev->dev,
439 usb_sndctrlpipe(gspca_dev->dev, 0),
440 0x0c, /* request */
441 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
442 val, idx,
443 gspca_dev->usb_buf, buf - gspca_dev->usb_buf,
444 500);
445 if (ret < 0) {
446 PDEBUG(D_ERR, "i2c_write failed %d", ret);
447 gspca_dev->usb_err = ret;
448 }
449}
450
451static void ucbus_write(struct gspca_dev *gspca_dev,
452 const struct ucbus_write_cmd *cmd,
453 int ncmds,
454 int batchsize)
455{
456 u8 *buf;
457 u16 val, idx;
458 int len, ret;
459
460 if (gspca_dev->usb_err < 0)
461 return;
462
463#ifdef GSPCA_DEBUG
464 if ((batchsize - 1) * 3 > USB_BUF_SZ) {
465 err("Bug: usb_buf overflow");
466 gspca_dev->usb_err = -ENOMEM;
467 return;
468 }
469#endif
470
471 for (;;) {
472 len = ncmds;
473 if (len > batchsize)
474 len = batchsize;
475 ncmds -= len;
476
477 val = (cmd->bw_addr << 8) | SQ930_CTRL_UCBUS_IO;
478 idx = (cmd->bw_data << 8) | (cmd->bw_addr >> 8);
479
480 buf = gspca_dev->usb_buf;
481 while (--len > 0) {
482 cmd++;
483 *buf++ = cmd->bw_addr;
484 *buf++ = cmd->bw_addr >> 8;
485 *buf++ = cmd->bw_data;
486 }
487 if (buf != gspca_dev->usb_buf)
488 PDEBUG(D_USBO, "ucbus v: %04x i: %04x %02x...%02x",
489 val, idx,
490 gspca_dev->usb_buf[0], buf[-1]);
491 else
492 PDEBUG(D_USBO, "ucbus v: %04x i: %04x",
493 val, idx);
494 ret = usb_control_msg(gspca_dev->dev,
495 usb_sndctrlpipe(gspca_dev->dev, 0),
496 0x0c, /* request */
497 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
498 val, idx,
499 gspca_dev->usb_buf, buf - gspca_dev->usb_buf,
500 500);
501 if (ret < 0) {
502 PDEBUG(D_ERR, "ucbus_write failed %d", ret);
503 gspca_dev->usb_err = ret;
504 return;
505 }
506 msleep(30);
507 if (ncmds <= 0)
508 break;
509 cmd++;
510 }
511}
512
513static void gpio_set(struct sd *sd, u16 val, u16 mask)
514{
515 struct gspca_dev *gspca_dev = &sd->gspca_dev;
516
517 if (mask & 0x00ff) {
518 sd->gpio[0] &= ~mask;
519 sd->gpio[0] |= val;
520 reg_w(gspca_dev, 0x0100 | SQ930_CTRL_GPIO,
521 ~sd->gpio[0] << 8);
522 }
523 mask >>= 8;
524 val >>= 8;
525 if (mask) {
526 sd->gpio[1] &= ~mask;
527 sd->gpio[1] |= val;
528 reg_w(gspca_dev, 0x0300 | SQ930_CTRL_GPIO,
529 ~sd->gpio[1] << 8);
530 }
531}
532
533static void global_init(struct sd *sd, int first_time)
534{
535 static const struct ucbus_write_cmd clkfreq_cmd = {
536 0xf031, 0 /* SQ930_CLKFREQ_60MHZ */
537 };
538
539 ucbus_write(&sd->gspca_dev, &clkfreq_cmd, 1, 1);
540
541 gpio_set(sd, SQ930_GPIO_POWER, 0xff00);
542 switch (sd->sensor) {
543 case SENSOR_ICX098BQ:
544 if (first_time)
545 ucbus_write(&sd->gspca_dev,
546 icx098bq_start_0,
547 8, 8);
548 gpio_set(sd, 0, 0x00ff);
549 gpio_set(sd, SQ930_GPIO_DFL_I2C_SCL | SQ930_GPIO_DFL_I2C_SDA,
550 SQ930_GPIO_DFL_I2C_SCL | SQ930_GPIO_DFL_I2C_SDA);
551 gpio_set(sd, 0, SQ930_GPIO_DFL_I2C_SCL);
552 gpio_set(sd, 0, SQ930_GPIO_DFL_I2C_SDA);
553 gpio_set(sd, SQ930_GPIO_RSTBAR,
554 SQ930_GPIO_RSTBAR);
555 break;
556 case SENSOR_LZ24BP:
557 if (sd->type != Creative_live_motion)
558 gpio_set(sd, SQ930_GPIO_EXTRA1, 0x00ff);
559 else
560 gpio_set(sd, 0, 0x00ff);
561 msleep(50);
562 if (first_time)
563 ucbus_write(&sd->gspca_dev,
564 lz24bp_start_0,
565 8, 8);
566 gpio_set(sd, 0, 0x0001); /* no change */
567 gpio_set(sd, SQ930_GPIO_DFL_I2C_SCL | SQ930_GPIO_DFL_I2C_SDA,
568 SQ930_GPIO_DFL_I2C_SCL | SQ930_GPIO_DFL_I2C_SDA);
569 gpio_set(sd, 0, SQ930_GPIO_DFL_I2C_SCL);
570 gpio_set(sd, 0, SQ930_GPIO_DFL_I2C_SDA);
571 gpio_set(sd, SQ930_GPIO_RSTBAR,
572 SQ930_GPIO_RSTBAR);
573 break;
574 default:
575/* case SENSOR_MI0360: */
576 if (first_time) {
577 ucbus_write(&sd->gspca_dev,
578 mi0360_start_0,
579 ARRAY_SIZE(mi0360_start_0),
580 8);
581 gpio_set(sd, SQ930_GPIO_RSTBAR, 0x00ff);
582 } else {
583 gpio_set(sd, SQ930_GPIO_EXTRA2 | SQ930_GPIO_RSTBAR,
584 0x00ff);
585 }
586 gpio_set(sd, SQ930_GPIO_DFL_I2C_SCL | SQ930_GPIO_DFL_I2C_SDA,
587 SQ930_GPIO_RSTBAR |
588 SQ930_GPIO_DFL_I2C_SCL | SQ930_GPIO_DFL_I2C_SDA);
589 gpio_set(sd, 0, SQ930_GPIO_DFL_I2C_SCL);
590 gpio_set(sd, 0, SQ930_GPIO_DFL_I2C_SDA);
591 gpio_set(sd, 0, SQ930_GPIO_DFL_I2C_SDA);
592 gpio_set(sd, SQ930_GPIO_EXTRA2, SQ930_GPIO_EXTRA2);
593 break;
594 }
595}
596
597static void lz24bp_ppl(struct sd *sd, u16 ppl)
598{
599 struct ucbus_write_cmd cmds[2] = {
600 {0xf810, ppl >> 8},
601 {0xf811, ppl}
602 };
603
604 ucbus_write(&sd->gspca_dev, cmds, ARRAY_SIZE(cmds), 2);
605}
606
607static void setexposure(struct gspca_dev *gspca_dev)
608{
609 struct sd *sd = (struct sd *) gspca_dev;
610 int i, integclks, intstartclk, frameclks, min_frclk;
611 u16 cmd;
612 u8 buf[15];
613
614 integclks = sd->expo;
615 i = 0;
616 cmd = SQ930_CTRL_SET_EXPOSURE;
617 if (sd->sensor == SENSOR_MI0360) {
618 cmd |= 0x0100;
619 buf[i++] = 0x5d; /* i2c_slave_addr */
620 buf[i++] = 0x08; /* 2 * ni2c */
621 buf[i++] = 0x09; /* reg = shutter width */
622 buf[i++] = integclks >> 8; /* val H */
623 buf[i++] = 0x80;
624 buf[i++] = integclks; /* val L */
625 buf[i++] = 0x35; /* reg = global gain */
626 buf[i++] = 0x00; /* val H */
627 buf[i++] = 0x80;
628 buf[i++] = sd->gain; /* val L */
629 buf[i++] = 0x00;
630 buf[i++] = 0x00;
631 buf[i++] = 0x00;
632 buf[i++] = 0x00;
633 buf[i++] = 0x83;
634 } else {
635 min_frclk = sd->sensor == SENSOR_ICX098BQ ? 0x210 : 0x26f;
636 if (integclks >= min_frclk) {
637 intstartclk = 0;
638 frameclks = integclks;
639 } else {
640 intstartclk = min_frclk - integclks;
641 frameclks = min_frclk;
642 }
643 buf[i++] = intstartclk >> 8;
644 buf[i++] = intstartclk;
645 buf[i++] = frameclks >> 8;
646 buf[i++] = frameclks;
647 buf[i++] = sd->gain;
648 }
649 reg_wb(gspca_dev, cmd, 0, buf, i);
650}
651
652/* This function is called at probe time just before sd_init */
653static int sd_config(struct gspca_dev *gspca_dev,
654 const struct usb_device_id *id)
655{
656 struct sd *sd = (struct sd *) gspca_dev;
657 struct cam *cam = &gspca_dev->cam;
658
659 sd->sensor = id->driver_info >> 8;
660 sd->type = id->driver_info;
661
662 cam->cam_mode = vga_mode;
663 cam->nmodes = ARRAY_SIZE(vga_mode);
664
665 cam->bulk = 1;
666 cam->bulk_size = BULK_TRANSFER_LEN;
667/* cam->bulk_nurbs = 2; fixme: if no setexpo sync */
668
669 sd->quality = QUALITY_DEF;
670 sd->gain = GAIN_DEF;
671 sd->expo = EXPO_DEF;
672
673 return 0;
674}
675
676/* this function is called at probe and resume time */
677static int sd_init(struct gspca_dev *gspca_dev)
678{
679 struct sd *sd = (struct sd *) gspca_dev;
680
681 sd->gpio[0] = sd->gpio[1] = 0xff; /* force gpio rewrite */
682
683 if (sd->sensor != SENSOR_LZ24BP)
684 reg_w(gspca_dev, SQ930_CTRL_RESET, 0x0000);
685
686 reg_r(gspca_dev, SQ930_CTRL_GET_DEV_INFO, 8);
687/* it returns:
688 * 03 00 12 93 0b f6 c9 00 live! ultra
689 * 03 00 07 93 0b f6 ca 00 live! ultra for notebook
690 * 03 00 12 93 0b fe c8 00 Trust WB-3500T
691 * 02 00 06 93 0b fe c8 00 Joy-IT 318S
692 * 03 00 12 93 0b f6 cf 00 icam tracer - sensor icx098bq
693 * 02 00 12 93 0b fe cf 00 ProQ Motion Webcam
694 *
695 * byte
696 * 0: 02 = usb 1.0 (12Mbit) / 03 = usb2.0 (480Mbit)
697 * 1: 00
698 * 2: 06 / 07 / 12 = mode webcam? firmware??
699 * 3: 93 chip = 930b (930b or 930c)
700 * 4: 0b
701 * 5: f6 = cdd (icx098bq, lz24bp) / fe = cmos (i2c) (mi0360, ov9630)
702 * 6: c8 / c9 / ca / cf = mode webcam?, sensor? webcam?
703 * 7: 00
704 */
705 PDEBUG(D_PROBE, "info: %02x %02x %02x %02x %02x %02x %02x %02x",
706 gspca_dev->usb_buf[0],
707 gspca_dev->usb_buf[1],
708 gspca_dev->usb_buf[2],
709 gspca_dev->usb_buf[3],
710 gspca_dev->usb_buf[4],
711 gspca_dev->usb_buf[5],
712 gspca_dev->usb_buf[6],
713 gspca_dev->usb_buf[7]);
714
715/*fixme: no sensor probe - special case for icam tracer */
716 if (gspca_dev->usb_buf[5] == 0xf6
717 && sd->sensor == SENSOR_MI0360) {
718 sd->sensor = SENSOR_ICX098BQ;
719 gspca_dev->cam.cam_mode = &vga_mode[1]; /* only 320x240 */
720 gspca_dev->cam.nmodes = 1;
721 }
722
723 global_init(sd, 1);
724 return gspca_dev->usb_err;
725}
726
727/* special function to create the quantization tables of the JPEG header */
728static void sd_jpeg_set_qual(u8 *jpeg_hdr,
729 int quality)
730{
731 int i, sc1, sc2;
732
733 quality = quality_tb[quality]; /* convert to JPEG quality */
734/*
735 * approximative qualities for Y and U/V:
736 * quant = 0:94%/91% 1:91%/87% 2:82%/73% 3:69%/56%
737 * should have:
738 * quant = 0:94%/91% 1:91%/87.5% 2:81.5%/72% 3:69%/54.5%
739 */
740 sc1 = 200 - quality * 2;
741 quality = quality * 7 / 5 - 40; /* UV quality */
742 sc2 = 200 - quality * 2;
743 for (i = 0; i < 64; i++) {
744 jpeg_hdr[JPEG_QT0_OFFSET + i] =
745 (jpeg_head[JPEG_QT0_OFFSET + i] * sc1 + 50) / 100;
746 jpeg_hdr[JPEG_QT1_OFFSET + i] =
747 (jpeg_head[JPEG_QT1_OFFSET + i] * sc2 + 50) / 100;
748 }
749}
750
751/* send the start/stop commands to the webcam */
752static void send_start(struct gspca_dev *gspca_dev)
753{
754 struct sd *sd = (struct sd *) gspca_dev;
755 const struct cap_s *cap;
756 int mode, quality;
757
758 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
759 cap = &capconfig[sd->sensor][mode];
760 quality = sd->quality;
761 reg_wb(gspca_dev, (quality << 12)
762 | 0x0a00 /* 900 for Bayer */
763 | SQ930_CTRL_CAP_START,
764 0x0500 /* a00 for Bayer */
765 | cap->cc_sizeid,
766 cap->cc_bytes, 32);
767};
768static void send_stop(struct gspca_dev *gspca_dev)
769{
770 reg_w(gspca_dev, SQ930_CTRL_CAP_STOP, 0);
771};
772
773/* function called at start time before URB creation */
774static int sd_isoc_init(struct gspca_dev *gspca_dev)
775{
776 struct sd *sd = (struct sd *) gspca_dev;
777
778 gspca_dev->cam.bulk_nurbs = 1; /* there must be one URB only */
779 sd->do_ctrl = 0;
780 return 0;
781}
782
783/* start the capture */
784static int sd_start(struct gspca_dev *gspca_dev)
785{
786 struct sd *sd = (struct sd *) gspca_dev;
787 int mode;
788
789 /* initialize the JPEG header */
790 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
791 0x21); /* JPEG 422 */
792 sd_jpeg_set_qual(sd->jpeg_hdr, sd->quality);
793
794 global_init(sd, 0);
795 msleep(100);
796
797 switch (sd->sensor) {
798 case SENSOR_ICX098BQ:
799 ucbus_write(gspca_dev, icx098bq_start_0,
800 ARRAY_SIZE(icx098bq_start_0),
801 8);
802 ucbus_write(gspca_dev, icx098bq_start_1,
803 ARRAY_SIZE(icx098bq_start_1),
804 5);
805 ucbus_write(gspca_dev, icx098bq_start_2,
806 ARRAY_SIZE(icx098bq_start_2),
807 6);
808 msleep(50);
809
810 /* 1st start */
811 send_start(gspca_dev);
812 gpio_set(sd, SQ930_GPIO_EXTRA2 | SQ930_GPIO_RSTBAR, 0x00ff);
813 msleep(70);
814 reg_w(gspca_dev, SQ930_CTRL_CAP_STOP, 0x0000);
815 gpio_set(sd, 0x7f, 0x00ff);
816
817 /* 2nd start */
818 send_start(gspca_dev);
819 gpio_set(sd, SQ930_GPIO_EXTRA2 | SQ930_GPIO_RSTBAR, 0x00ff);
820 goto out;
821 case SENSOR_LZ24BP:
822 ucbus_write(gspca_dev, lz24bp_start_0,
823 ARRAY_SIZE(lz24bp_start_0),
824 8);
825 if (sd->type != Creative_live_motion)
826 ucbus_write(gspca_dev, lz24bp_start_1_gen,
827 ARRAY_SIZE(lz24bp_start_1_gen),
828 5);
829 else
830 ucbus_write(gspca_dev, lz24bp_start_1_clm,
831 ARRAY_SIZE(lz24bp_start_1_clm),
832 5);
833 ucbus_write(gspca_dev, lz24bp_start_2,
834 ARRAY_SIZE(lz24bp_start_2),
835 6);
836 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
837 lz24bp_ppl(sd, mode == 2 ? 0x0564 : 0x0310);
838 msleep(10);
839 break;
840 default:
841/* case SENSOR_MI0360: */
842 ucbus_write(gspca_dev, mi0360_start_0,
843 ARRAY_SIZE(mi0360_start_0),
844 8);
845 i2c_write(gspca_dev, mi0360_init_23,
846 ARRAY_SIZE(mi0360_init_23));
847 i2c_write(gspca_dev, mi0360_init_24,
848 ARRAY_SIZE(mi0360_init_24));
849 i2c_write(gspca_dev, mi0360_init_25,
850 ARRAY_SIZE(mi0360_init_25));
851 ucbus_write(gspca_dev, mi0360_start_1,
852 ARRAY_SIZE(mi0360_start_1),
853 5);
854 i2c_write(gspca_dev, mi0360_start_2,
855 ARRAY_SIZE(mi0360_start_2));
856 i2c_write(gspca_dev, mi0360_start_3,
857 ARRAY_SIZE(mi0360_start_3));
858
859 /* 1st start */
860 send_start(gspca_dev);
861 msleep(60);
862 reg_w(gspca_dev, SQ930_CTRL_CAP_STOP, 0x0000);
863
864 i2c_write(gspca_dev,
865 mi0360_start_4, ARRAY_SIZE(mi0360_start_4));
866 break;
867 }
868
869 send_start(gspca_dev);
870out:
871 msleep(1000);
872
873 sd->eof_len = 0; /* init packet scan */
874
875 sd->do_ctrl = 1; /* set the exposure */
876
877 return gspca_dev->usb_err;
878}
879
880static void sd_stopN(struct gspca_dev *gspca_dev)
881{
882 send_stop(gspca_dev);
883}
884
885/* function called when the application gets a new frame */
886/* It sets the exposure if required and restart the bulk transfer. */
887static void sd_dq_callback(struct gspca_dev *gspca_dev)
888{
889 struct sd *sd = (struct sd *) gspca_dev;
890 int ret;
891
892 if (!sd->do_ctrl || gspca_dev->cam.bulk_nurbs != 0)
893 return;
894 sd->do_ctrl = 0;
895
896 setexposure(gspca_dev);
897
898 gspca_dev->cam.bulk_nurbs = 1;
899 ret = usb_submit_urb(gspca_dev->urb[0], GFP_ATOMIC);
900 if (ret < 0)
901 PDEBUG(D_ERR|D_PACK, "sd_dq_callback() err %d", ret);
902
903 /* wait a little time, otherwise the webcam crashes */
904 msleep(100);
905}
906
907/* move a packet adding 0x00 after 0xff */
908static void add_packet(struct gspca_dev *gspca_dev,
909 u8 *data,
910 int len)
911{
912 int i;
913
914 i = 0;
915 do {
916 if (data[i] == 0xff) {
917 gspca_frame_add(gspca_dev, INTER_PACKET,
918 data, i + 1);
919 len -= i;
920 data += i;
921 *data = 0x00;
922 i = 0;
923 }
924 } while (++i < len);
925 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
926}
927
928/* end a frame and start a new one */
929static void eof_sof(struct gspca_dev *gspca_dev)
930{
931 struct sd *sd = (struct sd *) gspca_dev;
932 static const u8 ffd9[] = {0xff, 0xd9};
933
934 /* if control set, stop bulk transfer */
935 if (sd->do_ctrl
936 && gspca_dev->last_packet_type == INTER_PACKET)
937 gspca_dev->cam.bulk_nurbs = 0;
938 gspca_frame_add(gspca_dev, LAST_PACKET,
939 ffd9, 2);
940 gspca_frame_add(gspca_dev, FIRST_PACKET,
941 sd->jpeg_hdr, JPEG_HDR_SZ);
942}
943
944static void sd_pkt_scan(struct gspca_dev *gspca_dev,
945 u8 *data, /* isoc packet */
946 int len) /* iso packet length */
947{
948 struct sd *sd = (struct sd *) gspca_dev;
949 u8 *p;
950 int l;
951
952 len -= 8; /* ignore last 8 bytes (00 00 55 aa 55 aa 00 00) */
953
954 /*
955 * the end/start of frame is indicated by
956 * 0x00 * 16 - 0xab * 8
957 * aligned on 8 bytes boundary
958 */
959 if (sd->eof_len != 0) { /* if 'abababab' in previous pkt */
960 if (*((u32 *) data) == 0xabababab) {
961 /*fixme: should remove previous 0000ababab*/
962 eof_sof(gspca_dev);
963 data += 4;
964 len -= 4;
965 }
966 sd->eof_len = 0;
967 }
968 p = data;
969 l = len;
970 for (;;) {
971 if (*((u32 *) p) == 0xabababab) {
972 if (l < 8) { /* (may be 4 only) */
973 sd->eof_len = 1;
974 break;
975 }
976 if (*((u32 *) p + 1) == 0xabababab) {
977 add_packet(gspca_dev, data, p - data - 16);
978 /* remove previous zeros */
979 eof_sof(gspca_dev);
980 p += 8;
981 l -= 8;
982 if (l <= 0)
983 return;
984 len = l;
985 data = p;
986 continue;
987 }
988 }
989 p += 4;
990 l -= 4;
991 if (l <= 0)
992 break;
993 }
994 add_packet(gspca_dev, data, len);
995}
996
997static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
998{
999 struct sd *sd = (struct sd *) gspca_dev;
1000
1001 sd->gain = val;
1002 if (gspca_dev->streaming)
1003 sd->do_ctrl = 1;
1004 return 0;
1005}
1006
1007static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
1008{
1009 struct sd *sd = (struct sd *) gspca_dev;
1010
1011 *val = sd->gain;
1012 return 0;
1013}
1014static int sd_setexpo(struct gspca_dev *gspca_dev, __s32 val)
1015{
1016 struct sd *sd = (struct sd *) gspca_dev;
1017
1018 sd->expo = val;
1019 if (gspca_dev->streaming)
1020 sd->do_ctrl = 1;
1021 return 0;
1022}
1023
1024static int sd_getexpo(struct gspca_dev *gspca_dev, __s32 *val)
1025{
1026 struct sd *sd = (struct sd *) gspca_dev;
1027
1028 *val = sd->expo;
1029 return 0;
1030}
1031
1032static int sd_set_jcomp(struct gspca_dev *gspca_dev,
1033 struct v4l2_jpegcompression *jcomp)
1034{
1035 struct sd *sd = (struct sd *) gspca_dev;
1036 int quality;
1037
1038 if (jcomp->quality >= (QUAL_0 + QUAL_1) / 2)
1039 quality = 0;
1040 else if (jcomp->quality >= (QUAL_1 + QUAL_2) / 2)
1041 quality = 1;
1042 else if (jcomp->quality >= (QUAL_2 + QUAL_3) / 2)
1043 quality = 2;
1044 else
1045 quality = 3;
1046
1047 if (quality != sd->quality) {
1048 sd->quality = quality;
1049 if (gspca_dev->streaming) {
1050 send_stop(gspca_dev);
1051 sd_jpeg_set_qual(sd->jpeg_hdr, sd->quality);
1052 msleep(70);
1053 send_start(gspca_dev);
1054 }
1055 }
1056 return gspca_dev->usb_err;
1057}
1058
1059static int sd_get_jcomp(struct gspca_dev *gspca_dev,
1060 struct v4l2_jpegcompression *jcomp)
1061{
1062 struct sd *sd = (struct sd *) gspca_dev;
1063
1064 memset(jcomp, 0, sizeof *jcomp);
1065 jcomp->quality = quality_tb[sd->quality];
1066 jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
1067 | V4L2_JPEG_MARKER_DQT;
1068 return 0;
1069}
1070
1071/* sub-driver description */
1072static const struct sd_desc sd_desc = {
1073 .name = MODULE_NAME,
1074 .ctrls = sd_ctrls,
1075 .nctrls = ARRAY_SIZE(sd_ctrls),
1076 .config = sd_config,
1077 .init = sd_init,
1078 .isoc_init = sd_isoc_init,
1079 .start = sd_start,
1080 .stopN = sd_stopN,
1081 .pkt_scan = sd_pkt_scan,
1082 .dq_callback = sd_dq_callback,
1083 .get_jcomp = sd_get_jcomp,
1084 .set_jcomp = sd_set_jcomp,
1085};
1086
1087/* Table of supported USB devices */
1088#define ST(sensor, type) \
1089 .driver_info = (SENSOR_ ## sensor << 8) \
1090 | (type)
1091static const __devinitdata struct usb_device_id device_table[] = {
1092 {USB_DEVICE(0x041e, 0x4038), ST(MI0360, 0)},
1093 {USB_DEVICE(0x041e, 0x403c), ST(LZ24BP, 0)},
1094 {USB_DEVICE(0x041e, 0x403d), ST(LZ24BP, 0)},
1095 {USB_DEVICE(0x041e, 0x4041), ST(LZ24BP, Creative_live_motion)},
1096 {USB_DEVICE(0x2770, 0x930b), ST(MI0360, 0)}, /* or ICX098BQ */
1097 {USB_DEVICE(0x2770, 0x930c), ST(MI0360, 0)},
1098 {}
1099};
1100MODULE_DEVICE_TABLE(usb, device_table);
1101
1102
1103/* -- device connect -- */
1104static int sd_probe(struct usb_interface *intf,
1105 const struct usb_device_id *id)
1106{
1107 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1108 THIS_MODULE);
1109}
1110
1111static struct usb_driver sd_driver = {
1112 .name = MODULE_NAME,
1113 .id_table = device_table,
1114 .probe = sd_probe,
1115 .disconnect = gspca_disconnect,
1116#ifdef CONFIG_PM
1117 .suspend = gspca_suspend,
1118 .resume = gspca_resume,
1119#endif
1120};
1121
1122/* -- module insert / remove -- */
1123static int __init sd_mod_init(void)
1124{
1125 int ret;
1126
1127 ret = usb_register(&sd_driver);
1128 if (ret < 0)
1129 return ret;
1130 info("registered");
1131 return 0;
1132}
1133static void __exit sd_mod_exit(void)
1134{
1135 usb_deregister(&sd_driver);
1136 info("deregistered");
1137}
1138
1139module_init(sd_mod_init);
1140module_exit(sd_mod_exit);