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