1
2
3
4
5
6
7
8#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
9
10#define MODULE_NAME "spca500"
11
12#include "gspca.h"
13#include "jpeg.h"
14
15MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
16MODULE_DESCRIPTION("GSPCA/SPCA500 USB Camera Driver");
17MODULE_LICENSE("GPL");
18
19#define QUALITY 85
20
21
22struct sd {
23 struct gspca_dev gspca_dev;
24
25 char subtype;
26#define AgfaCl20 0
27#define AiptekPocketDV 1
28#define BenqDC1016 2
29#define CreativePCCam300 3
30#define DLinkDSC350 4
31#define Gsmartmini 5
32#define IntelPocketPCCamera 6
33#define KodakEZ200 7
34#define LogitechClickSmart310 8
35#define LogitechClickSmart510 9
36#define LogitechTraveler 10
37#define MustekGsmart300 11
38#define Optimedia 12
39#define PalmPixDC85 13
40#define ToptroIndus 14
41
42 u8 jpeg_hdr[JPEG_HDR_SZ];
43};
44
45static const struct v4l2_pix_format vga_mode[] = {
46 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
47 .bytesperline = 320,
48 .sizeimage = 320 * 240 * 3 / 8 + 590,
49 .colorspace = V4L2_COLORSPACE_JPEG,
50 .priv = 1},
51 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
52 .bytesperline = 640,
53 .sizeimage = 640 * 480 * 3 / 8 + 590,
54 .colorspace = V4L2_COLORSPACE_JPEG,
55 .priv = 0},
56};
57
58static const struct v4l2_pix_format sif_mode[] = {
59 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
60 .bytesperline = 176,
61 .sizeimage = 176 * 144 * 3 / 8 + 590,
62 .colorspace = V4L2_COLORSPACE_JPEG,
63 .priv = 1},
64 {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
65 .bytesperline = 352,
66 .sizeimage = 352 * 288 * 3 / 8 + 590,
67 .colorspace = V4L2_COLORSPACE_JPEG,
68 .priv = 0},
69};
70
71
72#define SPCA500_OFFSET_PADDINGLB 2
73#define SPCA500_OFFSET_PADDINGHB 3
74#define SPCA500_OFFSET_MODE 4
75#define SPCA500_OFFSET_IMGWIDTH 5
76#define SPCA500_OFFSET_IMGHEIGHT 6
77#define SPCA500_OFFSET_IMGMODE 7
78#define SPCA500_OFFSET_QTBLINDEX 8
79#define SPCA500_OFFSET_FRAMSEQ 9
80#define SPCA500_OFFSET_CDSPINFO 10
81#define SPCA500_OFFSET_GPIO 11
82#define SPCA500_OFFSET_AUGPIO 12
83#define SPCA500_OFFSET_DATA 16
84
85
86static const __u16 spca500_visual_defaults[][3] = {
87 {0x00, 0x0003, 0x816b},
88
89
90
91
92 {0x00, 0x0000, 0x8167},
93 {0x00, 0x0020, 0x8168},
94 {0x00, 0x0003, 0x816b},
95
96
97
98
99 {0x00, 0x0000, 0x816a},
100 {0x00, 0x0020, 0x8169},
101 {0x00, 0x0050, 0x8157},
102 {0x00, 0x0030, 0x8158},
103 {0x00, 0x0028, 0x8159},
104 {0x00, 0x000a, 0x815a},
105 {0x00, 0x0001, 0x8202},
106 {0x0c, 0x0004, 0x0000},
107
108 {}
109};
110static const __u16 Clicksmart510_defaults[][3] = {
111 {0x00, 0x00, 0x8211},
112 {0x00, 0x01, 0x82c0},
113 {0x00, 0x10, 0x82cb},
114 {0x00, 0x0f, 0x800d},
115 {0x00, 0x82, 0x8225},
116 {0x00, 0x21, 0x8228},
117 {0x00, 0x00, 0x8203},
118 {0x00, 0x00, 0x8204},
119 {0x00, 0x08, 0x8205},
120 {0x00, 0xf8, 0x8206},
121 {0x00, 0x28, 0x8207},
122 {0x00, 0xa0, 0x8208},
123 {0x00, 0x08, 0x824a},
124 {0x00, 0x08, 0x8214},
125 {0x00, 0x80, 0x82c1},
126 {0x00, 0x00, 0x82c2},
127 {0x00, 0x00, 0x82ca},
128 {0x00, 0x80, 0x82c1},
129 {0x00, 0x04, 0x82c2},
130 {0x00, 0x00, 0x82ca},
131 {0x00, 0xfc, 0x8100},
132 {0x00, 0xfc, 0x8105},
133 {0x00, 0x30, 0x8101},
134 {0x00, 0x00, 0x8102},
135 {0x00, 0x00, 0x8103},
136 {0x00, 0x66, 0x8107},
137 {0x00, 0x00, 0x816b},
138 {0x00, 0x00, 0x8155},
139 {0x00, 0x01, 0x8156},
140 {0x00, 0x60, 0x8157},
141 {0x00, 0x40, 0x8158},
142 {0x00, 0x0a, 0x8159},
143 {0x00, 0x06, 0x815a},
144 {0x00, 0x00, 0x813f},
145 {0x00, 0x00, 0x8200},
146 {0x00, 0x19, 0x8201},
147 {0x00, 0x00, 0x82c1},
148 {0x00, 0xa0, 0x82c2},
149 {0x00, 0x00, 0x82ca},
150 {0x00, 0x00, 0x8117},
151 {0x00, 0x00, 0x8118},
152 {0x00, 0x65, 0x8119},
153 {0x00, 0x00, 0x811a},
154 {0x00, 0x00, 0x811b},
155 {0x00, 0x55, 0x811c},
156 {0x00, 0x65, 0x811d},
157 {0x00, 0x55, 0x811e},
158 {0x00, 0x16, 0x811f},
159 {0x00, 0x19, 0x8120},
160 {0x00, 0x80, 0x8103},
161 {0x00, 0x83, 0x816b},
162 {0x00, 0x25, 0x8168},
163 {0x00, 0x01, 0x820f},
164 {0x00, 0xff, 0x8115},
165 {0x00, 0x48, 0x8116},
166 {0x00, 0x50, 0x8151},
167 {0x00, 0x40, 0x8152},
168 {0x00, 0x78, 0x8153},
169 {0x00, 0x40, 0x8154},
170 {0x00, 0x00, 0x8167},
171 {0x00, 0x20, 0x8168},
172 {0x00, 0x00, 0x816a},
173 {0x00, 0x03, 0x816b},
174 {0x00, 0x20, 0x8169},
175 {0x00, 0x60, 0x8157},
176 {0x00, 0x00, 0x8190},
177 {0x00, 0x00, 0x81a1},
178 {0x00, 0x00, 0x81b2},
179 {0x00, 0x27, 0x8191},
180 {0x00, 0x27, 0x81a2},
181 {0x00, 0x27, 0x81b3},
182 {0x00, 0x4b, 0x8192},
183 {0x00, 0x4b, 0x81a3},
184 {0x00, 0x4b, 0x81b4},
185 {0x00, 0x66, 0x8193},
186 {0x00, 0x66, 0x81a4},
187 {0x00, 0x66, 0x81b5},
188 {0x00, 0x79, 0x8194},
189 {0x00, 0x79, 0x81a5},
190 {0x00, 0x79, 0x81b6},
191 {0x00, 0x8a, 0x8195},
192 {0x00, 0x8a, 0x81a6},
193 {0x00, 0x8a, 0x81b7},
194 {0x00, 0x9b, 0x8196},
195 {0x00, 0x9b, 0x81a7},
196 {0x00, 0x9b, 0x81b8},
197 {0x00, 0xa6, 0x8197},
198 {0x00, 0xa6, 0x81a8},
199 {0x00, 0xa6, 0x81b9},
200 {0x00, 0xb2, 0x8198},
201 {0x00, 0xb2, 0x81a9},
202 {0x00, 0xb2, 0x81ba},
203 {0x00, 0xbe, 0x8199},
204 {0x00, 0xbe, 0x81aa},
205 {0x00, 0xbe, 0x81bb},
206 {0x00, 0xc8, 0x819a},
207 {0x00, 0xc8, 0x81ab},
208 {0x00, 0xc8, 0x81bc},
209 {0x00, 0xd2, 0x819b},
210 {0x00, 0xd2, 0x81ac},
211 {0x00, 0xd2, 0x81bd},
212 {0x00, 0xdb, 0x819c},
213 {0x00, 0xdb, 0x81ad},
214 {0x00, 0xdb, 0x81be},
215 {0x00, 0xe4, 0x819d},
216 {0x00, 0xe4, 0x81ae},
217 {0x00, 0xe4, 0x81bf},
218 {0x00, 0xed, 0x819e},
219 {0x00, 0xed, 0x81af},
220 {0x00, 0xed, 0x81c0},
221 {0x00, 0xf7, 0x819f},
222 {0x00, 0xf7, 0x81b0},
223 {0x00, 0xf7, 0x81c1},
224 {0x00, 0xff, 0x81a0},
225 {0x00, 0xff, 0x81b1},
226 {0x00, 0xff, 0x81c2},
227 {0x00, 0x03, 0x8156},
228 {0x00, 0x00, 0x8211},
229 {0x00, 0x20, 0x8168},
230 {0x00, 0x01, 0x8202},
231 {0x00, 0x30, 0x8101},
232 {0x00, 0x00, 0x8111},
233 {0x00, 0x00, 0x8112},
234 {0x00, 0x00, 0x8113},
235 {0x00, 0x00, 0x8114},
236 {}
237};
238
239static const __u8 qtable_creative_pccam[2][64] = {
240 {
241 0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12,
242 0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11,
243 0x04, 0x04, 0x05, 0x07, 0x0c, 0x11, 0x15, 0x11,
244 0x04, 0x05, 0x07, 0x09, 0x0f, 0x1a, 0x18, 0x13,
245 0x05, 0x07, 0x0b, 0x11, 0x14, 0x21, 0x1f, 0x17,
246 0x07, 0x0b, 0x11, 0x13, 0x18, 0x1f, 0x22, 0x1c,
247 0x0f, 0x13, 0x17, 0x1a, 0x1f, 0x24, 0x24, 0x1e,
248 0x16, 0x1c, 0x1d, 0x1d, 0x22, 0x1e, 0x1f, 0x1e},
249 {
250 0x05, 0x05, 0x07, 0x0e, 0x1e, 0x1e, 0x1e, 0x1e,
251 0x05, 0x06, 0x08, 0x14, 0x1e, 0x1e, 0x1e, 0x1e,
252 0x07, 0x08, 0x11, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
253 0x0e, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
254 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
255 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
256 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
257 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e}
258};
259
260static const __u8 qtable_kodak_ez200[2][64] = {
261 {
262 0x02, 0x01, 0x01, 0x02, 0x02, 0x04, 0x05, 0x06,
263 0x01, 0x01, 0x01, 0x02, 0x03, 0x06, 0x06, 0x06,
264 0x01, 0x01, 0x02, 0x02, 0x04, 0x06, 0x07, 0x06,
265 0x01, 0x02, 0x02, 0x03, 0x05, 0x09, 0x08, 0x06,
266 0x02, 0x02, 0x04, 0x06, 0x07, 0x0b, 0x0a, 0x08,
267 0x02, 0x04, 0x06, 0x06, 0x08, 0x0a, 0x0b, 0x09,
268 0x05, 0x06, 0x08, 0x09, 0x0a, 0x0c, 0x0c, 0x0a,
269 0x07, 0x09, 0x0a, 0x0a, 0x0b, 0x0a, 0x0a, 0x0a},
270 {
271 0x02, 0x02, 0x02, 0x05, 0x0a, 0x0a, 0x0a, 0x0a,
272 0x02, 0x02, 0x03, 0x07, 0x0a, 0x0a, 0x0a, 0x0a,
273 0x02, 0x03, 0x06, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
274 0x05, 0x07, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
275 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
276 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
277 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
278 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a}
279};
280
281static const __u8 qtable_pocketdv[2][64] = {
282 {
283 0x06, 0x04, 0x04, 0x06, 0x0a, 0x10, 0x14, 0x18,
284 0x05, 0x05, 0x06, 0x08, 0x0a, 0x17, 0x18, 0x16,
285 0x06, 0x05, 0x06, 0x0a, 0x10, 0x17, 0x1c, 0x16,
286 0x06, 0x07, 0x09, 0x0c, 0x14, 0x23, 0x20, 0x19,
287 0x07, 0x09, 0x0f, 0x16, 0x1b, 0x2c, 0x29, 0x1f,
288 0x0a, 0x0e, 0x16, 0x1a, 0x20, 0x2a, 0x2d, 0x25,
289 0x14, 0x1a, 0x1f, 0x23, 0x29, 0x30, 0x30, 0x28,
290 0x1d, 0x25, 0x26, 0x27, 0x2d, 0x28, 0x29, 0x28,
291 },
292 {
293 0x07, 0x07, 0x0a, 0x13, 0x28, 0x28, 0x28, 0x28,
294 0x07, 0x08, 0x0a, 0x1a, 0x28, 0x28, 0x28, 0x28,
295 0x0a, 0x0a, 0x16, 0x28, 0x28, 0x28, 0x28, 0x28,
296 0x13, 0x1a, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
297 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
298 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
299 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
300 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28}
301};
302
303
304static void reg_r(struct gspca_dev *gspca_dev,
305 __u16 index,
306 __u16 length)
307{
308 usb_control_msg(gspca_dev->dev,
309 usb_rcvctrlpipe(gspca_dev->dev, 0),
310 0,
311 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
312 0,
313 index, gspca_dev->usb_buf, length, 500);
314}
315
316static int reg_w(struct gspca_dev *gspca_dev,
317 __u16 req, __u16 index, __u16 value)
318{
319 int ret;
320
321 gspca_dbg(gspca_dev, D_USBO, "reg write: [0x%02x] = 0x%02x\n",
322 index, value);
323 ret = usb_control_msg(gspca_dev->dev,
324 usb_sndctrlpipe(gspca_dev->dev, 0),
325 req,
326 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
327 value, index, NULL, 0, 500);
328 if (ret < 0)
329 pr_err("reg write: error %d\n", ret);
330 return ret;
331}
332
333
334static int reg_r_12(struct gspca_dev *gspca_dev,
335 __u16 req,
336 __u16 index,
337 __u16 length)
338{
339 int ret;
340
341 gspca_dev->usb_buf[1] = 0;
342 ret = usb_control_msg(gspca_dev->dev,
343 usb_rcvctrlpipe(gspca_dev->dev, 0),
344 req,
345 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
346 0,
347 index,
348 gspca_dev->usb_buf, length,
349 500);
350 if (ret < 0) {
351 pr_err("reg_r_12 err %d\n", ret);
352 return ret;
353 }
354 return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0];
355}
356
357
358
359
360
361
362static int reg_r_wait(struct gspca_dev *gspca_dev,
363 __u16 reg, __u16 index, __u16 value)
364{
365 int ret, cnt = 20;
366
367 while (--cnt > 0) {
368 ret = reg_r_12(gspca_dev, reg, index, 1);
369 if (ret == value)
370 return 0;
371 msleep(50);
372 }
373 return -EIO;
374}
375
376static int write_vector(struct gspca_dev *gspca_dev,
377 const __u16 data[][3])
378{
379 int ret, i = 0;
380
381 while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) {
382 ret = reg_w(gspca_dev, data[i][0], data[i][2], data[i][1]);
383 if (ret < 0)
384 return ret;
385 i++;
386 }
387 return 0;
388}
389
390static int spca50x_setup_qtable(struct gspca_dev *gspca_dev,
391 unsigned int request,
392 unsigned int ybase,
393 unsigned int cbase,
394 const __u8 qtable[2][64])
395{
396 int i, err;
397
398
399 for (i = 0; i < 64; i++) {
400 err = reg_w(gspca_dev, request, ybase + i, qtable[0][i]);
401 if (err < 0)
402 return err;
403 }
404
405
406 for (i = 0; i < 64; i++) {
407 err = reg_w(gspca_dev, request, cbase + i, qtable[1][i]);
408 if (err < 0)
409 return err;
410 }
411 return 0;
412}
413
414static void spca500_ping310(struct gspca_dev *gspca_dev)
415{
416 reg_r(gspca_dev, 0x0d04, 2);
417 gspca_dbg(gspca_dev, D_STREAM, "ClickSmart310 ping 0x0d04 0x%02x 0x%02x\n",
418 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
419}
420
421static void spca500_clksmart310_init(struct gspca_dev *gspca_dev)
422{
423 reg_r(gspca_dev, 0x0d05, 2);
424 gspca_dbg(gspca_dev, D_STREAM, "ClickSmart310 init 0x0d05 0x%02x 0x%02x\n",
425 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
426 reg_w(gspca_dev, 0x00, 0x8167, 0x5a);
427 spca500_ping310(gspca_dev);
428
429 reg_w(gspca_dev, 0x00, 0x8168, 0x22);
430 reg_w(gspca_dev, 0x00, 0x816a, 0xc0);
431 reg_w(gspca_dev, 0x00, 0x816b, 0x0b);
432 reg_w(gspca_dev, 0x00, 0x8169, 0x25);
433 reg_w(gspca_dev, 0x00, 0x8157, 0x5b);
434 reg_w(gspca_dev, 0x00, 0x8158, 0x5b);
435 reg_w(gspca_dev, 0x00, 0x813f, 0x03);
436 reg_w(gspca_dev, 0x00, 0x8151, 0x4a);
437 reg_w(gspca_dev, 0x00, 0x8153, 0x78);
438 reg_w(gspca_dev, 0x00, 0x0d01, 0x04);
439
440 reg_w(gspca_dev, 0x00, 0x0d02, 0x01);
441 reg_w(gspca_dev, 0x00, 0x8169, 0x25);
442 reg_w(gspca_dev, 0x00, 0x0d01, 0x02);
443}
444
445static void spca500_setmode(struct gspca_dev *gspca_dev,
446 __u8 xmult, __u8 ymult)
447{
448 int mode;
449
450
451 reg_w(gspca_dev, 0, 0x8001, xmult);
452
453
454 reg_w(gspca_dev, 0, 0x8002, ymult);
455
456
457 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
458 reg_w(gspca_dev, 0, 0x8003, mode << 4);
459}
460
461static int spca500_full_reset(struct gspca_dev *gspca_dev)
462{
463 int err;
464
465
466 err = reg_w(gspca_dev, 0xe0, 0x0001, 0x0000);
467 if (err < 0)
468 return err;
469
470
471 err = reg_r_wait(gspca_dev, 0x06, 0x0000, 0x0000);
472 if (err < 0)
473 return err;
474 err = reg_w(gspca_dev, 0xe0, 0x0000, 0x0000);
475 if (err < 0)
476 return err;
477 err = reg_r_wait(gspca_dev, 0x06, 0, 0);
478 if (err < 0) {
479 gspca_err(gspca_dev, "reg_r_wait() failed\n");
480 return err;
481 }
482
483 return 0;
484}
485
486
487
488
489
490
491
492static int spca500_synch310(struct gspca_dev *gspca_dev)
493{
494 if (usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0) < 0) {
495 gspca_err(gspca_dev, "Set packet size: set interface error\n");
496 goto error;
497 }
498 spca500_ping310(gspca_dev);
499
500 reg_r(gspca_dev, 0x0d00, 1);
501
502
503 gspca_dbg(gspca_dev, D_PACK, "ClickSmart310 sync alt: %d\n",
504 gspca_dev->alt);
505
506
507 if (usb_set_interface(gspca_dev->dev,
508 gspca_dev->iface,
509 gspca_dev->alt) < 0) {
510 gspca_err(gspca_dev, "Set packet size: set interface error\n");
511 goto error;
512 }
513 return 0;
514error:
515 return -EBUSY;
516}
517
518static void spca500_reinit(struct gspca_dev *gspca_dev)
519{
520 int err;
521 __u8 Data;
522
523
524
525 reg_w(gspca_dev, 0x00, 0x0d01, 0x01);
526 reg_w(gspca_dev, 0x00, 0x0d03, 0x00);
527 reg_w(gspca_dev, 0x00, 0x0d02, 0x01);
528
529
530 reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
531
532 err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840,
533 qtable_pocketdv);
534 if (err < 0)
535 gspca_err(gspca_dev, "spca50x_setup_qtable failed on init\n");
536
537
538 reg_w(gspca_dev, 0x00, 0x8880, 2);
539
540 reg_w(gspca_dev, 0x00, 0x800a, 0x00);
541
542 reg_w(gspca_dev, 0x00, 0x820f, 0x01);
543
544 reg_w(gspca_dev, 0x00, 0x870a, 0x04);
545
546 reg_w(gspca_dev, 0, 0x8003, 0x00);
547
548 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
549 msleep(2000);
550 if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0) {
551 reg_r(gspca_dev, 0x816b, 1);
552 Data = gspca_dev->usb_buf[0];
553 reg_w(gspca_dev, 0x00, 0x816b, Data);
554 }
555}
556
557
558static int sd_config(struct gspca_dev *gspca_dev,
559 const struct usb_device_id *id)
560{
561 struct sd *sd = (struct sd *) gspca_dev;
562 struct cam *cam;
563
564 cam = &gspca_dev->cam;
565 sd->subtype = id->driver_info;
566 if (sd->subtype != LogitechClickSmart310) {
567 cam->cam_mode = vga_mode;
568 cam->nmodes = ARRAY_SIZE(vga_mode);
569 } else {
570 cam->cam_mode = sif_mode;
571 cam->nmodes = ARRAY_SIZE(sif_mode);
572 }
573 return 0;
574}
575
576
577static int sd_init(struct gspca_dev *gspca_dev)
578{
579 struct sd *sd = (struct sd *) gspca_dev;
580
581
582 gspca_dbg(gspca_dev, D_STREAM, "SPCA500 init\n");
583 if (sd->subtype == LogitechClickSmart310)
584 spca500_clksmart310_init(gspca_dev);
585
586
587 gspca_dbg(gspca_dev, D_STREAM, "SPCA500 init done\n");
588 return 0;
589}
590
591static int sd_start(struct gspca_dev *gspca_dev)
592{
593 struct sd *sd = (struct sd *) gspca_dev;
594 int err;
595 __u8 Data;
596 __u8 xmult, ymult;
597
598
599 jpeg_define(sd->jpeg_hdr, gspca_dev->pixfmt.height,
600 gspca_dev->pixfmt.width,
601 0x22);
602 jpeg_set_qual(sd->jpeg_hdr, QUALITY);
603
604 if (sd->subtype == LogitechClickSmart310) {
605 xmult = 0x16;
606 ymult = 0x12;
607 } else {
608 xmult = 0x28;
609 ymult = 0x1e;
610 }
611
612
613 reg_r(gspca_dev, 0x8a04, 1);
614 gspca_dbg(gspca_dev, D_STREAM, "Spca500 Sensor Address 0x%02x\n",
615 gspca_dev->usb_buf[0]);
616 gspca_dbg(gspca_dev, D_STREAM, "Spca500 curr_mode: %d Xmult: 0x%02x, Ymult: 0x%02x",
617 gspca_dev->curr_mode, xmult, ymult);
618
619
620 switch (sd->subtype) {
621 case LogitechClickSmart310:
622 spca500_setmode(gspca_dev, xmult, ymult);
623
624
625 reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
626 reg_w(gspca_dev, 0x00, 0x8880, 3);
627 err = spca50x_setup_qtable(gspca_dev,
628 0x00, 0x8800, 0x8840,
629 qtable_creative_pccam);
630 if (err < 0)
631 gspca_err(gspca_dev, "spca50x_setup_qtable failed\n");
632
633 reg_w(gspca_dev, 0x00, 0x870a, 0x04);
634
635
636 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
637 msleep(500);
638 if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
639 gspca_err(gspca_dev, "reg_r_wait() failed\n");
640
641 reg_r(gspca_dev, 0x816b, 1);
642 Data = gspca_dev->usb_buf[0];
643 reg_w(gspca_dev, 0x00, 0x816b, Data);
644
645 spca500_synch310(gspca_dev);
646
647 write_vector(gspca_dev, spca500_visual_defaults);
648 spca500_setmode(gspca_dev, xmult, ymult);
649
650 err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
651 if (err < 0)
652 gspca_err(gspca_dev, "failed to enable drop packet\n");
653 reg_w(gspca_dev, 0x00, 0x8880, 3);
654 err = spca50x_setup_qtable(gspca_dev,
655 0x00, 0x8800, 0x8840,
656 qtable_creative_pccam);
657 if (err < 0)
658 gspca_err(gspca_dev, "spca50x_setup_qtable failed\n");
659
660
661 reg_w(gspca_dev, 0x00, 0x870a, 0x04);
662
663
664 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
665
666 if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
667 gspca_err(gspca_dev, "reg_r_wait() failed\n");
668
669 reg_r(gspca_dev, 0x816b, 1);
670 Data = gspca_dev->usb_buf[0];
671 reg_w(gspca_dev, 0x00, 0x816b, Data);
672 break;
673 case CreativePCCam300:
674 case IntelPocketPCCamera:
675
676
677
678
679 err = spca500_full_reset(gspca_dev);
680 if (err < 0)
681 gspca_err(gspca_dev, "spca500_full_reset failed\n");
682
683
684 err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
685 if (err < 0)
686 gspca_err(gspca_dev, "failed to enable drop packet\n");
687 reg_w(gspca_dev, 0x00, 0x8880, 3);
688 err = spca50x_setup_qtable(gspca_dev,
689 0x00, 0x8800, 0x8840,
690 qtable_creative_pccam);
691 if (err < 0)
692 gspca_err(gspca_dev, "spca50x_setup_qtable failed\n");
693
694 spca500_setmode(gspca_dev, xmult, ymult);
695 reg_w(gspca_dev, 0x20, 0x0001, 0x0004);
696
697
698 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
699
700 if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
701 gspca_err(gspca_dev, "reg_r_wait() failed\n");
702
703 reg_r(gspca_dev, 0x816b, 1);
704 Data = gspca_dev->usb_buf[0];
705 reg_w(gspca_dev, 0x00, 0x816b, Data);
706
707
708 break;
709 case KodakEZ200:
710
711
712 err = spca500_full_reset(gspca_dev);
713 if (err < 0)
714 gspca_err(gspca_dev, "spca500_full_reset failed\n");
715
716 reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
717 reg_w(gspca_dev, 0x00, 0x8880, 0);
718 err = spca50x_setup_qtable(gspca_dev,
719 0x00, 0x8800, 0x8840,
720 qtable_kodak_ez200);
721 if (err < 0)
722 gspca_err(gspca_dev, "spca50x_setup_qtable failed\n");
723 spca500_setmode(gspca_dev, xmult, ymult);
724
725 reg_w(gspca_dev, 0x20, 0x0001, 0x0004);
726
727
728 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
729
730 if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
731 gspca_err(gspca_dev, "reg_r_wait() failed\n");
732
733 reg_r(gspca_dev, 0x816b, 1);
734 Data = gspca_dev->usb_buf[0];
735 reg_w(gspca_dev, 0x00, 0x816b, Data);
736
737
738 break;
739
740 case BenqDC1016:
741 case DLinkDSC350:
742 case AiptekPocketDV:
743 case Gsmartmini:
744 case MustekGsmart300:
745 case PalmPixDC85:
746 case Optimedia:
747 case ToptroIndus:
748 case AgfaCl20:
749 spca500_reinit(gspca_dev);
750 reg_w(gspca_dev, 0x00, 0x0d01, 0x01);
751
752 reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
753
754 err = spca50x_setup_qtable(gspca_dev,
755 0x00, 0x8800, 0x8840, qtable_pocketdv);
756 if (err < 0)
757 gspca_err(gspca_dev, "spca50x_setup_qtable failed\n");
758 reg_w(gspca_dev, 0x00, 0x8880, 2);
759
760
761 reg_w(gspca_dev, 0x00, 0x800a, 0x00);
762
763 reg_w(gspca_dev, 0x00, 0x820f, 0x01);
764
765 reg_w(gspca_dev, 0x00, 0x870a, 0x04);
766
767 spca500_setmode(gspca_dev, xmult, ymult);
768
769 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
770
771 reg_r_wait(gspca_dev, 0, 0x8000, 0x44);
772
773 reg_r(gspca_dev, 0x816b, 1);
774 Data = gspca_dev->usb_buf[0];
775 reg_w(gspca_dev, 0x00, 0x816b, Data);
776 break;
777 case LogitechTraveler:
778 case LogitechClickSmart510:
779 reg_w(gspca_dev, 0x02, 0x00, 0x00);
780
781 reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
782
783 err = spca50x_setup_qtable(gspca_dev,
784 0x00, 0x8800,
785 0x8840, qtable_creative_pccam);
786 if (err < 0)
787 gspca_err(gspca_dev, "spca50x_setup_qtable failed\n");
788 reg_w(gspca_dev, 0x00, 0x8880, 3);
789 reg_w(gspca_dev, 0x00, 0x800a, 0x00);
790
791 reg_w(gspca_dev, 0x00, 0x870a, 0x04);
792
793 spca500_setmode(gspca_dev, xmult, ymult);
794
795
796 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
797 reg_r_wait(gspca_dev, 0, 0x8000, 0x44);
798
799 reg_r(gspca_dev, 0x816b, 1);
800 Data = gspca_dev->usb_buf[0];
801 reg_w(gspca_dev, 0x00, 0x816b, Data);
802 write_vector(gspca_dev, Clicksmart510_defaults);
803 break;
804 }
805 return 0;
806}
807
808static void sd_stopN(struct gspca_dev *gspca_dev)
809{
810 reg_w(gspca_dev, 0, 0x8003, 0x00);
811
812
813 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
814 reg_r(gspca_dev, 0x8000, 1);
815 gspca_dbg(gspca_dev, D_STREAM, "stop SPCA500 done reg8000: 0x%2x\n",
816 gspca_dev->usb_buf[0]);
817}
818
819static void sd_pkt_scan(struct gspca_dev *gspca_dev,
820 u8 *data,
821 int len)
822{
823 struct sd *sd = (struct sd *) gspca_dev;
824 int i;
825 static __u8 ffd9[] = {0xff, 0xd9};
826
827
828 if (data[0] == 0xff) {
829 if (data[1] != 0x01) {
830
831 return;
832 }
833 gspca_frame_add(gspca_dev, LAST_PACKET,
834 ffd9, 2);
835
836
837 gspca_frame_add(gspca_dev, FIRST_PACKET,
838 sd->jpeg_hdr, JPEG_HDR_SZ);
839
840 data += SPCA500_OFFSET_DATA;
841 len -= SPCA500_OFFSET_DATA;
842 } else {
843 data += 1;
844 len -= 1;
845 }
846
847
848 i = 0;
849 do {
850 if (data[i] == 0xff) {
851 gspca_frame_add(gspca_dev, INTER_PACKET,
852 data, i + 1);
853 len -= i;
854 data += i;
855 *data = 0x00;
856 i = 0;
857 }
858 i++;
859 } while (i < len);
860 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
861}
862
863static void setbrightness(struct gspca_dev *gspca_dev, s32 val)
864{
865 reg_w(gspca_dev, 0x00, 0x8167,
866 (__u8) (val - 128));
867}
868
869static void setcontrast(struct gspca_dev *gspca_dev, s32 val)
870{
871 reg_w(gspca_dev, 0x00, 0x8168, val);
872}
873
874static void setcolors(struct gspca_dev *gspca_dev, s32 val)
875{
876 reg_w(gspca_dev, 0x00, 0x8169, val);
877}
878
879static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
880{
881 struct gspca_dev *gspca_dev =
882 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
883
884 gspca_dev->usb_err = 0;
885
886 if (!gspca_dev->streaming)
887 return 0;
888
889 switch (ctrl->id) {
890 case V4L2_CID_BRIGHTNESS:
891 setbrightness(gspca_dev, ctrl->val);
892 break;
893 case V4L2_CID_CONTRAST:
894 setcontrast(gspca_dev, ctrl->val);
895 break;
896 case V4L2_CID_SATURATION:
897 setcolors(gspca_dev, ctrl->val);
898 break;
899 }
900 return gspca_dev->usb_err;
901}
902
903static const struct v4l2_ctrl_ops sd_ctrl_ops = {
904 .s_ctrl = sd_s_ctrl,
905};
906
907static int sd_init_controls(struct gspca_dev *gspca_dev)
908{
909 struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
910
911 gspca_dev->vdev.ctrl_handler = hdl;
912 v4l2_ctrl_handler_init(hdl, 3);
913 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
914 V4L2_CID_BRIGHTNESS, 0, 255, 1, 127);
915 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
916 V4L2_CID_CONTRAST, 0, 63, 1, 31);
917 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
918 V4L2_CID_SATURATION, 0, 63, 1, 31);
919
920 if (hdl->error) {
921 pr_err("Could not initialize controls\n");
922 return hdl->error;
923 }
924 return 0;
925}
926
927
928static const struct sd_desc sd_desc = {
929 .name = MODULE_NAME,
930 .config = sd_config,
931 .init = sd_init,
932 .init_controls = sd_init_controls,
933 .start = sd_start,
934 .stopN = sd_stopN,
935 .pkt_scan = sd_pkt_scan,
936};
937
938
939static const struct usb_device_id device_table[] = {
940 {USB_DEVICE(0x040a, 0x0300), .driver_info = KodakEZ200},
941 {USB_DEVICE(0x041e, 0x400a), .driver_info = CreativePCCam300},
942 {USB_DEVICE(0x046d, 0x0890), .driver_info = LogitechTraveler},
943 {USB_DEVICE(0x046d, 0x0900), .driver_info = LogitechClickSmart310},
944 {USB_DEVICE(0x046d, 0x0901), .driver_info = LogitechClickSmart510},
945 {USB_DEVICE(0x04a5, 0x300c), .driver_info = BenqDC1016},
946 {USB_DEVICE(0x04fc, 0x7333), .driver_info = PalmPixDC85},
947 {USB_DEVICE(0x055f, 0xc200), .driver_info = MustekGsmart300},
948 {USB_DEVICE(0x055f, 0xc220), .driver_info = Gsmartmini},
949 {USB_DEVICE(0x06bd, 0x0404), .driver_info = AgfaCl20},
950 {USB_DEVICE(0x06be, 0x0800), .driver_info = Optimedia},
951 {USB_DEVICE(0x084d, 0x0003), .driver_info = DLinkDSC350},
952 {USB_DEVICE(0x08ca, 0x0103), .driver_info = AiptekPocketDV},
953 {USB_DEVICE(0x2899, 0x012c), .driver_info = ToptroIndus},
954 {USB_DEVICE(0x8086, 0x0630), .driver_info = IntelPocketPCCamera},
955 {}
956};
957MODULE_DEVICE_TABLE(usb, device_table);
958
959
960static int sd_probe(struct usb_interface *intf,
961 const struct usb_device_id *id)
962{
963 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
964 THIS_MODULE);
965}
966
967static struct usb_driver sd_driver = {
968 .name = MODULE_NAME,
969 .id_table = device_table,
970 .probe = sd_probe,
971 .disconnect = gspca_disconnect,
972#ifdef CONFIG_PM
973 .suspend = gspca_suspend,
974 .resume = gspca_resume,
975 .reset_resume = gspca_resume,
976#endif
977};
978
979module_usb_driver(sd_driver);
980