This source file includes following definitions.
- reg_r
- reg_w_1
- reg_w_riv
- write_vector
- setup_qtable
- spca504_acknowledged_command
- spca504_read_info
- spca504A_acknowledged_command
- spca504B_PollingDataReady
- spca504B_WaitCmdStatus
- spca50x_GetFirmware
- spca504B_SetSizeType
- spca504_wait_status
- spca504B_setQtable
- setbrightness
- setcontrast
- setcolors
- init_ctl_reg
- sd_config
- sd_init
- sd_start
- sd_stopN
- sd_pkt_scan
- sd_s_ctrl
- sd_init_controls
- sd_probe
1
2
3
4
5
6
7
8
9 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
10
11 #define MODULE_NAME "sunplus"
12
13 #include "gspca.h"
14 #include "jpeg.h"
15
16 MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
17 MODULE_DESCRIPTION("GSPCA/SPCA5xx USB Camera Driver");
18 MODULE_LICENSE("GPL");
19
20 #define QUALITY 85
21
22
23 struct sd {
24 struct gspca_dev gspca_dev;
25
26 bool autogain;
27
28 u8 bridge;
29 #define BRIDGE_SPCA504 0
30 #define BRIDGE_SPCA504B 1
31 #define BRIDGE_SPCA504C 2
32 #define BRIDGE_SPCA533 3
33 #define BRIDGE_SPCA536 4
34 u8 subtype;
35 #define AiptekMiniPenCam13 1
36 #define LogitechClickSmart420 2
37 #define LogitechClickSmart820 3
38 #define MegapixV4 4
39 #define MegaImageVI 5
40
41 u8 jpeg_hdr[JPEG_HDR_SZ];
42 };
43
44 static const struct v4l2_pix_format vga_mode[] = {
45 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
46 .bytesperline = 320,
47 .sizeimage = 320 * 240 * 3 / 8 + 590,
48 .colorspace = V4L2_COLORSPACE_JPEG,
49 .priv = 2},
50 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
51 .bytesperline = 640,
52 .sizeimage = 640 * 480 * 3 / 8 + 590,
53 .colorspace = V4L2_COLORSPACE_JPEG,
54 .priv = 1},
55 };
56
57 static const struct v4l2_pix_format custom_mode[] = {
58 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
59 .bytesperline = 320,
60 .sizeimage = 320 * 240 * 3 / 8 + 590,
61 .colorspace = V4L2_COLORSPACE_JPEG,
62 .priv = 2},
63 {464, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
64 .bytesperline = 464,
65 .sizeimage = 464 * 480 * 3 / 8 + 590,
66 .colorspace = V4L2_COLORSPACE_JPEG,
67 .priv = 1},
68 };
69
70 static const struct v4l2_pix_format vga_mode2[] = {
71 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
72 .bytesperline = 176,
73 .sizeimage = 176 * 144 * 3 / 8 + 590,
74 .colorspace = V4L2_COLORSPACE_JPEG,
75 .priv = 4},
76 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
77 .bytesperline = 320,
78 .sizeimage = 320 * 240 * 3 / 8 + 590,
79 .colorspace = V4L2_COLORSPACE_JPEG,
80 .priv = 3},
81 {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
82 .bytesperline = 352,
83 .sizeimage = 352 * 288 * 3 / 8 + 590,
84 .colorspace = V4L2_COLORSPACE_JPEG,
85 .priv = 2},
86 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
87 .bytesperline = 640,
88 .sizeimage = 640 * 480 * 3 / 8 + 590,
89 .colorspace = V4L2_COLORSPACE_JPEG,
90 .priv = 1},
91 };
92
93 #define SPCA50X_OFFSET_DATA 10
94 #define SPCA504_PCCAM600_OFFSET_SNAPSHOT 3
95 #define SPCA504_PCCAM600_OFFSET_COMPRESS 4
96 #define SPCA504_PCCAM600_OFFSET_MODE 5
97 #define SPCA504_PCCAM600_OFFSET_DATA 14
98
99 #define SPCA533_OFFSET_DATA 16
100 #define SPCA533_OFFSET_FRAMSEQ 15
101
102 #define SPCA536_OFFSET_DATA 4
103 #define SPCA536_OFFSET_FRAMSEQ 1
104
105 struct cmd {
106 u8 req;
107 u16 val;
108 u16 idx;
109 };
110
111
112 static const struct cmd spca504_pccam600_init_data[] = {
113
114 {0x00, 0x0000, 0x2000},
115 {0x00, 0x0013, 0x2301},
116 {0x00, 0x0003, 0x2000},
117 {0x00, 0x0001, 0x21ac},
118 {0x00, 0x0001, 0x21a6},
119 {0x00, 0x0000, 0x21a7},
120 {0x00, 0x0020, 0x21a8},
121 {0x00, 0x0001, 0x21ac},
122 {0x00, 0x0000, 0x21ad},
123 {0x00, 0x001a, 0x21ae},
124 {0x00, 0x0002, 0x21a3},
125 {0x30, 0x0154, 0x0008},
126 {0x30, 0x0004, 0x0006},
127 {0x30, 0x0258, 0x0009},
128 {0x30, 0x0004, 0x0000},
129 {0x30, 0x0093, 0x0004},
130 {0x30, 0x0066, 0x0005},
131 {0x00, 0x0000, 0x2000},
132 {0x00, 0x0013, 0x2301},
133 {0x00, 0x0003, 0x2000},
134 {0x00, 0x0013, 0x2301},
135 {0x00, 0x0003, 0x2000},
136 };
137
138
139
140
141 static const struct cmd spca504_pccam600_open_data[] = {
142 {0x00, 0x0001, 0x2501},
143 {0x20, 0x0500, 0x0001},
144 {0x00, 0x0003, 0x2880},
145 {0x00, 0x0001, 0x2881},
146 };
147
148
149 static const struct cmd spca504A_clicksmart420_init_data[] = {
150
151 {0x00, 0x0000, 0x2000},
152 {0x00, 0x0013, 0x2301},
153 {0x00, 0x0003, 0x2000},
154 {0x00, 0x0001, 0x21ac},
155 {0x00, 0x0001, 0x21a6},
156 {0x00, 0x0000, 0x21a7},
157 {0x00, 0x0020, 0x21a8},
158 {0x00, 0x0001, 0x21ac},
159 {0x00, 0x0000, 0x21ad},
160 {0x00, 0x001a, 0x21ae},
161 {0x00, 0x0002, 0x21a3},
162 {0x30, 0x0004, 0x000a},
163 {0xb0, 0x0001, 0x0000},
164
165 {0xa1, 0x0080, 0x0001},
166 {0x30, 0x0049, 0x0000},
167 {0x30, 0x0060, 0x0005},
168 {0x0c, 0x0004, 0x0000},
169 {0x00, 0x0000, 0x0000},
170 {0x00, 0x0000, 0x2000},
171 {0x00, 0x0013, 0x2301},
172 {0x00, 0x0003, 0x2000},
173 };
174
175
176 static const struct cmd spca504A_clicksmart420_open_data[] = {
177 {0x00, 0x0001, 0x2501},
178 {0x20, 0x0502, 0x0000},
179 {0x06, 0x0000, 0x0000},
180 {0x00, 0x0004, 0x2880},
181 {0x00, 0x0001, 0x2881},
182
183 {0xa0, 0x0000, 0x0503},
184 };
185
186 static const u8 qtable_creative_pccam[2][64] = {
187 {
188 0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12,
189 0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11,
190 0x04, 0x04, 0x05, 0x07, 0x0c, 0x11, 0x15, 0x11,
191 0x04, 0x05, 0x07, 0x09, 0x0f, 0x1a, 0x18, 0x13,
192 0x05, 0x07, 0x0b, 0x11, 0x14, 0x21, 0x1f, 0x17,
193 0x07, 0x0b, 0x11, 0x13, 0x18, 0x1f, 0x22, 0x1c,
194 0x0f, 0x13, 0x17, 0x1a, 0x1f, 0x24, 0x24, 0x1e,
195 0x16, 0x1c, 0x1d, 0x1d, 0x22, 0x1e, 0x1f, 0x1e},
196 {
197 0x05, 0x05, 0x07, 0x0e, 0x1e, 0x1e, 0x1e, 0x1e,
198 0x05, 0x06, 0x08, 0x14, 0x1e, 0x1e, 0x1e, 0x1e,
199 0x07, 0x08, 0x11, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
200 0x0e, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
201 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
202 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
203 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
204 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e}
205 };
206
207
208
209
210
211 static const u8 qtable_spca504_default[2][64] = {
212 {
213 0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12,
214 0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11,
215 0x04, 0x04, 0x05, 0x07, 0x0c, 0x11, 0x15, 0x11,
216 0x04, 0x05, 0x07, 0x09, 0x0f, 0x1a, 0x18, 0x13,
217 0x05, 0x07, 0x0b, 0x11, 0x14, 0x21, 0x1f, 0x17,
218 0x07, 0x0b, 0x11, 0x13, 0x18, 0x1f, 0x22, 0x1c,
219 0x0f, 0x13, 0x17, 0x1a, 0x1f, 0x24, 0x24, 0x1e,
220 0x16, 0x1c, 0x1d, 0x1d, 0x1d , 0x1e, 0x1f, 0x1e,
221 },
222 {
223 0x05, 0x05, 0x07, 0x0e, 0x1e, 0x1e, 0x1e, 0x1e,
224 0x05, 0x06, 0x08, 0x14, 0x1e, 0x1e, 0x1e, 0x1e,
225 0x07, 0x08, 0x11, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
226 0x0e, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
227 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
228 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
229 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
230 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e}
231 };
232
233
234 static void reg_r(struct gspca_dev *gspca_dev,
235 u8 req,
236 u16 index,
237 u16 len)
238 {
239 int ret;
240
241 if (len > USB_BUF_SZ) {
242 gspca_err(gspca_dev, "reg_r: buffer overflow\n");
243 return;
244 }
245 if (gspca_dev->usb_err < 0)
246 return;
247 ret = usb_control_msg(gspca_dev->dev,
248 usb_rcvctrlpipe(gspca_dev->dev, 0),
249 req,
250 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
251 0,
252 index,
253 len ? gspca_dev->usb_buf : NULL, len,
254 500);
255 if (ret < 0) {
256 pr_err("reg_r err %d\n", ret);
257 gspca_dev->usb_err = ret;
258
259
260
261
262 memset(gspca_dev->usb_buf, 0, USB_BUF_SZ);
263 }
264 }
265
266
267 static void reg_w_1(struct gspca_dev *gspca_dev,
268 u8 req,
269 u16 value,
270 u16 index,
271 u16 byte)
272 {
273 int ret;
274
275 if (gspca_dev->usb_err < 0)
276 return;
277 gspca_dev->usb_buf[0] = byte;
278 ret = usb_control_msg(gspca_dev->dev,
279 usb_sndctrlpipe(gspca_dev->dev, 0),
280 req,
281 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
282 value, index,
283 gspca_dev->usb_buf, 1,
284 500);
285 if (ret < 0) {
286 pr_err("reg_w_1 err %d\n", ret);
287 gspca_dev->usb_err = ret;
288 }
289 }
290
291
292 static void reg_w_riv(struct gspca_dev *gspca_dev,
293 u8 req, u16 index, u16 value)
294 {
295 struct usb_device *dev = gspca_dev->dev;
296 int ret;
297
298 if (gspca_dev->usb_err < 0)
299 return;
300 ret = usb_control_msg(dev,
301 usb_sndctrlpipe(dev, 0),
302 req,
303 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
304 value, index, NULL, 0, 500);
305 if (ret < 0) {
306 pr_err("reg_w_riv err %d\n", ret);
307 gspca_dev->usb_err = ret;
308 return;
309 }
310 gspca_dbg(gspca_dev, D_USBO, "reg_w_riv: 0x%02x,0x%04x:0x%04x\n",
311 req, index, value);
312 }
313
314 static void write_vector(struct gspca_dev *gspca_dev,
315 const struct cmd *data, int ncmds)
316 {
317 while (--ncmds >= 0) {
318 reg_w_riv(gspca_dev, data->req, data->idx, data->val);
319 data++;
320 }
321 }
322
323 static void setup_qtable(struct gspca_dev *gspca_dev,
324 const u8 qtable[2][64])
325 {
326 int i;
327
328
329 for (i = 0; i < 64; i++)
330 reg_w_riv(gspca_dev, 0x00, 0x2800 + i, qtable[0][i]);
331
332
333 for (i = 0; i < 64; i++)
334 reg_w_riv(gspca_dev, 0x00, 0x2840 + i, qtable[1][i]);
335 }
336
337 static void spca504_acknowledged_command(struct gspca_dev *gspca_dev,
338 u8 req, u16 idx, u16 val)
339 {
340 reg_w_riv(gspca_dev, req, idx, val);
341 reg_r(gspca_dev, 0x01, 0x0001, 1);
342 gspca_dbg(gspca_dev, D_FRAM, "before wait 0x%04x\n",
343 gspca_dev->usb_buf[0]);
344 reg_w_riv(gspca_dev, req, idx, val);
345
346 msleep(200);
347 reg_r(gspca_dev, 0x01, 0x0001, 1);
348 gspca_dbg(gspca_dev, D_FRAM, "after wait 0x%04x\n",
349 gspca_dev->usb_buf[0]);
350 }
351
352 static void spca504_read_info(struct gspca_dev *gspca_dev)
353 {
354 int i;
355 u8 info[6];
356
357 if (gspca_debug < D_STREAM)
358 return;
359
360 for (i = 0; i < 6; i++) {
361 reg_r(gspca_dev, 0, i, 1);
362 info[i] = gspca_dev->usb_buf[0];
363 }
364 gspca_dbg(gspca_dev, D_STREAM,
365 "Read info: %d %d %d %d %d %d. Should be 1,0,2,2,0,0\n",
366 info[0], info[1], info[2],
367 info[3], info[4], info[5]);
368 }
369
370 static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev,
371 u8 req,
372 u16 idx, u16 val, u8 endcode, u8 count)
373 {
374 u16 status;
375
376 reg_w_riv(gspca_dev, req, idx, val);
377 reg_r(gspca_dev, 0x01, 0x0001, 1);
378 if (gspca_dev->usb_err < 0)
379 return;
380 gspca_dbg(gspca_dev, D_FRAM, "Status 0x%02x Need 0x%02x\n",
381 gspca_dev->usb_buf[0], endcode);
382 if (!count)
383 return;
384 count = 200;
385 while (--count > 0) {
386 msleep(10);
387
388
389 reg_r(gspca_dev, 0x01, 0x0001, 1);
390 status = gspca_dev->usb_buf[0];
391 if (status == endcode) {
392 gspca_dbg(gspca_dev, D_FRAM, "status 0x%04x after wait %d\n",
393 status, 200 - count);
394 break;
395 }
396 }
397 }
398
399 static void spca504B_PollingDataReady(struct gspca_dev *gspca_dev)
400 {
401 int count = 10;
402
403 while (--count > 0) {
404 reg_r(gspca_dev, 0x21, 0, 1);
405 if ((gspca_dev->usb_buf[0] & 0x01) == 0)
406 break;
407 msleep(10);
408 }
409 }
410
411 static void spca504B_WaitCmdStatus(struct gspca_dev *gspca_dev)
412 {
413 int count = 50;
414
415 while (--count > 0) {
416 reg_r(gspca_dev, 0x21, 1, 1);
417 if (gspca_dev->usb_buf[0] != 0) {
418 reg_w_1(gspca_dev, 0x21, 0, 1, 0);
419 reg_r(gspca_dev, 0x21, 1, 1);
420 spca504B_PollingDataReady(gspca_dev);
421 break;
422 }
423 msleep(10);
424 }
425 }
426
427 static void spca50x_GetFirmware(struct gspca_dev *gspca_dev)
428 {
429 u8 *data;
430
431 if (gspca_debug < D_STREAM)
432 return;
433
434 data = gspca_dev->usb_buf;
435 reg_r(gspca_dev, 0x20, 0, 5);
436 gspca_dbg(gspca_dev, D_STREAM, "FirmWare: %d %d %d %d %d\n",
437 data[0], data[1], data[2], data[3], data[4]);
438 reg_r(gspca_dev, 0x23, 0, 64);
439 reg_r(gspca_dev, 0x23, 1, 64);
440 }
441
442 static void spca504B_SetSizeType(struct gspca_dev *gspca_dev)
443 {
444 struct sd *sd = (struct sd *) gspca_dev;
445 u8 Size;
446
447 Size = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
448 switch (sd->bridge) {
449 case BRIDGE_SPCA533:
450 reg_w_riv(gspca_dev, 0x31, 0, 0);
451 spca504B_WaitCmdStatus(gspca_dev);
452 spca504B_PollingDataReady(gspca_dev);
453 spca50x_GetFirmware(gspca_dev);
454
455 reg_w_1(gspca_dev, 0x24, 0, 8, 2);
456 reg_r(gspca_dev, 0x24, 8, 1);
457
458 reg_w_1(gspca_dev, 0x25, 0, 4, Size);
459 reg_r(gspca_dev, 0x25, 4, 1);
460 spca504B_PollingDataReady(gspca_dev);
461
462
463 reg_w_riv(gspca_dev, 0x31, 0x0004, 0x00);
464 spca504B_WaitCmdStatus(gspca_dev);
465 spca504B_PollingDataReady(gspca_dev);
466 break;
467 default:
468
469
470 reg_w_1(gspca_dev, 0x25, 0, 4, Size);
471 reg_r(gspca_dev, 0x25, 4, 1);
472 reg_w_1(gspca_dev, 0x27, 0, 0, 6);
473 reg_r(gspca_dev, 0x27, 0, 1);
474 spca504B_PollingDataReady(gspca_dev);
475 break;
476 case BRIDGE_SPCA504:
477 Size += 3;
478 if (sd->subtype == AiptekMiniPenCam13) {
479
480 spca504A_acknowledged_command(gspca_dev,
481 0x08, Size, 0,
482 0x80 | (Size & 0x0f), 1);
483 spca504A_acknowledged_command(gspca_dev,
484 1, 3, 0, 0x9f, 0);
485 } else {
486 spca504_acknowledged_command(gspca_dev, 0x08, Size, 0);
487 }
488 break;
489 case BRIDGE_SPCA504C:
490
491 reg_w_riv(gspca_dev, 0xa0, (0x0500 | (Size & 0x0f)), 0x00);
492 reg_w_riv(gspca_dev, 0x20, 0x01, 0x0500 | (Size & 0x0f));
493 break;
494 }
495 }
496
497 static void spca504_wait_status(struct gspca_dev *gspca_dev)
498 {
499 int cnt;
500
501 cnt = 256;
502 while (--cnt > 0) {
503
504 reg_r(gspca_dev, 0x06, 0x00, 1);
505 if (gspca_dev->usb_buf[0] == 0)
506 return;
507 msleep(10);
508 }
509 }
510
511 static void spca504B_setQtable(struct gspca_dev *gspca_dev)
512 {
513 reg_w_1(gspca_dev, 0x26, 0, 0, 3);
514 reg_r(gspca_dev, 0x26, 0, 1);
515 spca504B_PollingDataReady(gspca_dev);
516 }
517
518 static void setbrightness(struct gspca_dev *gspca_dev, s32 val)
519 {
520 struct sd *sd = (struct sd *) gspca_dev;
521 u16 reg;
522
523 reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f0 : 0x21a7;
524 reg_w_riv(gspca_dev, 0x00, reg, val);
525 }
526
527 static void setcontrast(struct gspca_dev *gspca_dev, s32 val)
528 {
529 struct sd *sd = (struct sd *) gspca_dev;
530 u16 reg;
531
532 reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f1 : 0x21a8;
533 reg_w_riv(gspca_dev, 0x00, reg, val);
534 }
535
536 static void setcolors(struct gspca_dev *gspca_dev, s32 val)
537 {
538 struct sd *sd = (struct sd *) gspca_dev;
539 u16 reg;
540
541 reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f6 : 0x21ae;
542 reg_w_riv(gspca_dev, 0x00, reg, val);
543 }
544
545 static void init_ctl_reg(struct gspca_dev *gspca_dev)
546 {
547 struct sd *sd = (struct sd *) gspca_dev;
548 int pollreg = 1;
549
550 switch (sd->bridge) {
551 case BRIDGE_SPCA504:
552 case BRIDGE_SPCA504C:
553 pollreg = 0;
554
555 default:
556
557
558 reg_w_riv(gspca_dev, 0, 0x21ad, 0x00);
559 reg_w_riv(gspca_dev, 0, 0x21ac, 0x01);
560 reg_w_riv(gspca_dev, 0, 0x21a3, 0x00);
561 break;
562 case BRIDGE_SPCA536:
563 reg_w_riv(gspca_dev, 0, 0x20f5, 0x40);
564 reg_w_riv(gspca_dev, 0, 0x20f4, 0x01);
565 reg_w_riv(gspca_dev, 0, 0x2089, 0x00);
566 break;
567 }
568 if (pollreg)
569 spca504B_PollingDataReady(gspca_dev);
570 }
571
572
573 static int sd_config(struct gspca_dev *gspca_dev,
574 const struct usb_device_id *id)
575 {
576 struct sd *sd = (struct sd *) gspca_dev;
577 struct cam *cam;
578
579 cam = &gspca_dev->cam;
580
581 sd->bridge = id->driver_info >> 8;
582 sd->subtype = id->driver_info;
583
584 if (sd->subtype == AiptekMiniPenCam13) {
585
586
587
588 reg_r(gspca_dev, 0x20, 0, 1);
589 switch (gspca_dev->usb_buf[0]) {
590 case 1:
591 break;
592 case 2:
593 sd->bridge = BRIDGE_SPCA504B;
594 sd->subtype = 0;
595 break;
596 default:
597 return -ENODEV;
598 }
599 }
600
601 switch (sd->bridge) {
602 default:
603
604
605
606 cam->cam_mode = vga_mode;
607 cam->nmodes = ARRAY_SIZE(vga_mode);
608 break;
609 case BRIDGE_SPCA533:
610 cam->cam_mode = custom_mode;
611 if (sd->subtype == MegaImageVI)
612 cam->nmodes = ARRAY_SIZE(custom_mode) - 1;
613 else
614 cam->nmodes = ARRAY_SIZE(custom_mode);
615 break;
616 case BRIDGE_SPCA504C:
617 cam->cam_mode = vga_mode2;
618 cam->nmodes = ARRAY_SIZE(vga_mode2);
619 break;
620 }
621 return 0;
622 }
623
624
625 static int sd_init(struct gspca_dev *gspca_dev)
626 {
627 struct sd *sd = (struct sd *) gspca_dev;
628
629 switch (sd->bridge) {
630 case BRIDGE_SPCA504B:
631 reg_w_riv(gspca_dev, 0x1d, 0x00, 0);
632 reg_w_riv(gspca_dev, 0x00, 0x2306, 0x01);
633 reg_w_riv(gspca_dev, 0x00, 0x0d04, 0x00);
634 reg_w_riv(gspca_dev, 0x00, 0x2000, 0x00);
635 reg_w_riv(gspca_dev, 0x00, 0x2301, 0x13);
636 reg_w_riv(gspca_dev, 0x00, 0x2306, 0x00);
637
638 case BRIDGE_SPCA533:
639 spca504B_PollingDataReady(gspca_dev);
640 spca50x_GetFirmware(gspca_dev);
641 break;
642 case BRIDGE_SPCA536:
643 spca50x_GetFirmware(gspca_dev);
644 reg_r(gspca_dev, 0x00, 0x5002, 1);
645 reg_w_1(gspca_dev, 0x24, 0, 0, 0);
646 reg_r(gspca_dev, 0x24, 0, 1);
647 spca504B_PollingDataReady(gspca_dev);
648 reg_w_riv(gspca_dev, 0x34, 0, 0);
649 spca504B_WaitCmdStatus(gspca_dev);
650 break;
651 case BRIDGE_SPCA504C:
652 gspca_dbg(gspca_dev, D_STREAM, "Opening SPCA504 (PC-CAM 600)\n");
653 reg_w_riv(gspca_dev, 0xe0, 0x0000, 0x0000);
654 reg_w_riv(gspca_dev, 0xe0, 0x0000, 0x0001);
655 spca504_wait_status(gspca_dev);
656 if (sd->subtype == LogitechClickSmart420)
657 write_vector(gspca_dev,
658 spca504A_clicksmart420_open_data,
659 ARRAY_SIZE(spca504A_clicksmart420_open_data));
660 else
661 write_vector(gspca_dev, spca504_pccam600_open_data,
662 ARRAY_SIZE(spca504_pccam600_open_data));
663 setup_qtable(gspca_dev, qtable_creative_pccam);
664 break;
665 default:
666
667 gspca_dbg(gspca_dev, D_STREAM, "Opening SPCA504\n");
668 if (sd->subtype == AiptekMiniPenCam13) {
669 spca504_read_info(gspca_dev);
670
671
672 spca504A_acknowledged_command(gspca_dev, 0x24,
673 8, 3, 0x9e, 1);
674
675 spca504A_acknowledged_command(gspca_dev, 0x24,
676 8, 3, 0x9e, 0);
677
678 spca504A_acknowledged_command(gspca_dev, 0x24,
679 0, 0, 0x9d, 1);
680
681
682 spca504A_acknowledged_command(gspca_dev, 0x08,
683 6, 0, 0x86, 1);
684
685
686
687
688
689
690 reg_w_riv(gspca_dev, 0x00, 0x270c, 0x05);
691
692 reg_w_riv(gspca_dev, 0x00, 0x2310, 0x05);
693 spca504A_acknowledged_command(gspca_dev, 0x01,
694 0x0f, 0, 0xff, 0);
695 }
696
697 reg_w_riv(gspca_dev, 0, 0x2000, 0);
698 reg_w_riv(gspca_dev, 0, 0x2883, 1);
699 setup_qtable(gspca_dev, qtable_spca504_default);
700 break;
701 }
702 return gspca_dev->usb_err;
703 }
704
705 static int sd_start(struct gspca_dev *gspca_dev)
706 {
707 struct sd *sd = (struct sd *) gspca_dev;
708 int enable;
709
710
711 jpeg_define(sd->jpeg_hdr, gspca_dev->pixfmt.height,
712 gspca_dev->pixfmt.width,
713 0x22);
714 jpeg_set_qual(sd->jpeg_hdr, QUALITY);
715
716 if (sd->bridge == BRIDGE_SPCA504B)
717 spca504B_setQtable(gspca_dev);
718 spca504B_SetSizeType(gspca_dev);
719 switch (sd->bridge) {
720 default:
721
722
723
724 switch (sd->subtype) {
725 case MegapixV4:
726 case LogitechClickSmart820:
727 case MegaImageVI:
728 reg_w_riv(gspca_dev, 0xf0, 0, 0);
729 spca504B_WaitCmdStatus(gspca_dev);
730 reg_r(gspca_dev, 0xf0, 4, 0);
731 spca504B_WaitCmdStatus(gspca_dev);
732 break;
733 default:
734 reg_w_riv(gspca_dev, 0x31, 0x0004, 0x00);
735 spca504B_WaitCmdStatus(gspca_dev);
736 spca504B_PollingDataReady(gspca_dev);
737 break;
738 }
739 break;
740 case BRIDGE_SPCA504:
741 if (sd->subtype == AiptekMiniPenCam13) {
742 spca504_read_info(gspca_dev);
743
744
745 spca504A_acknowledged_command(gspca_dev, 0x24,
746 8, 3, 0x9e, 1);
747
748 spca504A_acknowledged_command(gspca_dev, 0x24,
749 8, 3, 0x9e, 0);
750 spca504A_acknowledged_command(gspca_dev, 0x24,
751 0, 0, 0x9d, 1);
752 } else {
753 spca504_acknowledged_command(gspca_dev, 0x24, 8, 3);
754 spca504_read_info(gspca_dev);
755 spca504_acknowledged_command(gspca_dev, 0x24, 8, 3);
756 spca504_acknowledged_command(gspca_dev, 0x24, 0, 0);
757 }
758 spca504B_SetSizeType(gspca_dev);
759 reg_w_riv(gspca_dev, 0x00, 0x270c, 0x05);
760
761 reg_w_riv(gspca_dev, 0x00, 0x2310, 0x05);
762 break;
763 case BRIDGE_SPCA504C:
764 if (sd->subtype == LogitechClickSmart420) {
765 write_vector(gspca_dev,
766 spca504A_clicksmart420_init_data,
767 ARRAY_SIZE(spca504A_clicksmart420_init_data));
768 } else {
769 write_vector(gspca_dev, spca504_pccam600_init_data,
770 ARRAY_SIZE(spca504_pccam600_init_data));
771 }
772 enable = (sd->autogain ? 0x04 : 0x01);
773 reg_w_riv(gspca_dev, 0x0c, 0x0000, enable);
774
775 reg_w_riv(gspca_dev, 0xb0, 0x0000, enable);
776
777
778
779 reg_w_riv(gspca_dev, 0x30, 0x0001, 800);
780 reg_w_riv(gspca_dev, 0x30, 0x0002, 1600);
781 spca504B_SetSizeType(gspca_dev);
782 break;
783 }
784 init_ctl_reg(gspca_dev);
785 return gspca_dev->usb_err;
786 }
787
788 static void sd_stopN(struct gspca_dev *gspca_dev)
789 {
790 struct sd *sd = (struct sd *) gspca_dev;
791
792 switch (sd->bridge) {
793 default:
794
795
796
797 reg_w_riv(gspca_dev, 0x31, 0, 0);
798 spca504B_WaitCmdStatus(gspca_dev);
799 spca504B_PollingDataReady(gspca_dev);
800 break;
801 case BRIDGE_SPCA504:
802 case BRIDGE_SPCA504C:
803 reg_w_riv(gspca_dev, 0x00, 0x2000, 0x0000);
804
805 if (sd->subtype == AiptekMiniPenCam13) {
806
807
808
809 spca504A_acknowledged_command(gspca_dev, 0x24,
810 0x00, 0x00, 0x9d, 1);
811 spca504A_acknowledged_command(gspca_dev, 0x01,
812 0x0f, 0x00, 0xff, 1);
813 } else {
814 spca504_acknowledged_command(gspca_dev, 0x24, 0, 0);
815 reg_w_riv(gspca_dev, 0x01, 0x000f, 0x0000);
816 }
817 break;
818 }
819 }
820
821 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
822 u8 *data,
823 int len)
824 {
825 struct sd *sd = (struct sd *) gspca_dev;
826 int i, sof = 0;
827 static u8 ffd9[] = {0xff, 0xd9};
828
829
830 switch (sd->bridge) {
831 case BRIDGE_SPCA533:
832 if (data[0] == 0xff) {
833 if (data[1] != 0x01) {
834
835 return;
836 }
837 sof = 1;
838 data += SPCA533_OFFSET_DATA;
839 len -= SPCA533_OFFSET_DATA;
840 } else {
841 data += 1;
842 len -= 1;
843 }
844 break;
845 case BRIDGE_SPCA536:
846 if (data[0] == 0xff) {
847 sof = 1;
848 data += SPCA536_OFFSET_DATA;
849 len -= SPCA536_OFFSET_DATA;
850 } else {
851 data += 2;
852 len -= 2;
853 }
854 break;
855 default:
856
857
858 switch (data[0]) {
859 case 0xfe:
860 sof = 1;
861 data += SPCA50X_OFFSET_DATA;
862 len -= SPCA50X_OFFSET_DATA;
863 break;
864 case 0xff:
865
866 return;
867 default:
868 data += 1;
869 len -= 1;
870 break;
871 }
872 break;
873 case BRIDGE_SPCA504C:
874 switch (data[0]) {
875 case 0xfe:
876 sof = 1;
877 data += SPCA504_PCCAM600_OFFSET_DATA;
878 len -= SPCA504_PCCAM600_OFFSET_DATA;
879 break;
880 case 0xff:
881
882 return;
883 default:
884 data += 1;
885 len -= 1;
886 break;
887 }
888 break;
889 }
890 if (sof) {
891 gspca_frame_add(gspca_dev, LAST_PACKET,
892 ffd9, 2);
893
894
895 gspca_frame_add(gspca_dev, FIRST_PACKET,
896 sd->jpeg_hdr, JPEG_HDR_SZ);
897 }
898
899
900 i = 0;
901 do {
902 if (data[i] == 0xff) {
903 gspca_frame_add(gspca_dev, INTER_PACKET,
904 data, i + 1);
905 len -= i;
906 data += i;
907 *data = 0x00;
908 i = 0;
909 }
910 i++;
911 } while (i < len);
912 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
913 }
914
915 static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
916 {
917 struct gspca_dev *gspca_dev =
918 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
919 struct sd *sd = (struct sd *)gspca_dev;
920
921 gspca_dev->usb_err = 0;
922
923 if (!gspca_dev->streaming)
924 return 0;
925
926 switch (ctrl->id) {
927 case V4L2_CID_BRIGHTNESS:
928 setbrightness(gspca_dev, ctrl->val);
929 break;
930 case V4L2_CID_CONTRAST:
931 setcontrast(gspca_dev, ctrl->val);
932 break;
933 case V4L2_CID_SATURATION:
934 setcolors(gspca_dev, ctrl->val);
935 break;
936 case V4L2_CID_AUTOGAIN:
937 sd->autogain = ctrl->val;
938 break;
939 }
940 return gspca_dev->usb_err;
941 }
942
943 static const struct v4l2_ctrl_ops sd_ctrl_ops = {
944 .s_ctrl = sd_s_ctrl,
945 };
946
947 static int sd_init_controls(struct gspca_dev *gspca_dev)
948 {
949 struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
950
951 gspca_dev->vdev.ctrl_handler = hdl;
952 v4l2_ctrl_handler_init(hdl, 4);
953 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
954 V4L2_CID_BRIGHTNESS, -128, 127, 1, 0);
955 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
956 V4L2_CID_CONTRAST, 0, 255, 1, 0x20);
957 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
958 V4L2_CID_SATURATION, 0, 255, 1, 0x1a);
959 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
960 V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
961
962 if (hdl->error) {
963 pr_err("Could not initialize controls\n");
964 return hdl->error;
965 }
966 return 0;
967 }
968
969
970 static const struct sd_desc sd_desc = {
971 .name = MODULE_NAME,
972 .config = sd_config,
973 .init = sd_init,
974 .init_controls = sd_init_controls,
975 .start = sd_start,
976 .stopN = sd_stopN,
977 .pkt_scan = sd_pkt_scan,
978 };
979
980
981 #define BS(bridge, subtype) \
982 .driver_info = (BRIDGE_ ## bridge << 8) \
983 | (subtype)
984 static const struct usb_device_id device_table[] = {
985 {USB_DEVICE(0x041e, 0x400b), BS(SPCA504C, 0)},
986 {USB_DEVICE(0x041e, 0x4012), BS(SPCA504C, 0)},
987 {USB_DEVICE(0x041e, 0x4013), BS(SPCA504C, 0)},
988 {USB_DEVICE(0x0458, 0x7006), BS(SPCA504B, 0)},
989 {USB_DEVICE(0x0461, 0x0821), BS(SPCA533, 0)},
990 {USB_DEVICE(0x046d, 0x0905), BS(SPCA533, LogitechClickSmart820)},
991 {USB_DEVICE(0x046d, 0x0960), BS(SPCA504C, LogitechClickSmart420)},
992 {USB_DEVICE(0x0471, 0x0322), BS(SPCA504B, 0)},
993 {USB_DEVICE(0x04a5, 0x3003), BS(SPCA504B, 0)},
994 {USB_DEVICE(0x04a5, 0x3008), BS(SPCA533, 0)},
995 {USB_DEVICE(0x04a5, 0x300a), BS(SPCA533, 0)},
996 {USB_DEVICE(0x04f1, 0x1001), BS(SPCA504B, 0)},
997 {USB_DEVICE(0x04fc, 0x500c), BS(SPCA504B, 0)},
998 {USB_DEVICE(0x04fc, 0x504a), BS(SPCA504, AiptekMiniPenCam13)},
999 {USB_DEVICE(0x04fc, 0x504b), BS(SPCA504B, 0)},
1000 {USB_DEVICE(0x04fc, 0x5330), BS(SPCA533, 0)},
1001 {USB_DEVICE(0x04fc, 0x5360), BS(SPCA536, 0)},
1002 {USB_DEVICE(0x04fc, 0xffff), BS(SPCA504B, 0)},
1003 {USB_DEVICE(0x052b, 0x1507), BS(SPCA533, MegapixV4)},
1004 {USB_DEVICE(0x052b, 0x1513), BS(SPCA533, MegapixV4)},
1005 {USB_DEVICE(0x052b, 0x1803), BS(SPCA533, MegaImageVI)},
1006 {USB_DEVICE(0x0546, 0x3155), BS(SPCA533, 0)},
1007 {USB_DEVICE(0x0546, 0x3191), BS(SPCA504B, 0)},
1008 {USB_DEVICE(0x0546, 0x3273), BS(SPCA504B, 0)},
1009 {USB_DEVICE(0x055f, 0xc211), BS(SPCA536, 0)},
1010 {USB_DEVICE(0x055f, 0xc230), BS(SPCA533, 0)},
1011 {USB_DEVICE(0x055f, 0xc232), BS(SPCA533, 0)},
1012 {USB_DEVICE(0x055f, 0xc360), BS(SPCA536, 0)},
1013 {USB_DEVICE(0x055f, 0xc420), BS(SPCA504, 0)},
1014 {USB_DEVICE(0x055f, 0xc430), BS(SPCA533, 0)},
1015 {USB_DEVICE(0x055f, 0xc440), BS(SPCA533, 0)},
1016 {USB_DEVICE(0x055f, 0xc520), BS(SPCA504, 0)},
1017 {USB_DEVICE(0x055f, 0xc530), BS(SPCA533, 0)},
1018 {USB_DEVICE(0x055f, 0xc540), BS(SPCA533, 0)},
1019 {USB_DEVICE(0x055f, 0xc630), BS(SPCA533, 0)},
1020 {USB_DEVICE(0x055f, 0xc650), BS(SPCA533, 0)},
1021 {USB_DEVICE(0x05da, 0x1018), BS(SPCA504B, 0)},
1022 {USB_DEVICE(0x06d6, 0x0031), BS(SPCA533, 0)},
1023 {USB_DEVICE(0x06d6, 0x0041), BS(SPCA504B, 0)},
1024 {USB_DEVICE(0x0733, 0x1311), BS(SPCA533, 0)},
1025 {USB_DEVICE(0x0733, 0x1314), BS(SPCA533, 0)},
1026 {USB_DEVICE(0x0733, 0x2211), BS(SPCA533, 0)},
1027 {USB_DEVICE(0x0733, 0x2221), BS(SPCA533, 0)},
1028 {USB_DEVICE(0x0733, 0x3261), BS(SPCA536, 0)},
1029 {USB_DEVICE(0x0733, 0x3281), BS(SPCA536, 0)},
1030 {USB_DEVICE(0x08ca, 0x0104), BS(SPCA533, 0)},
1031 {USB_DEVICE(0x08ca, 0x0106), BS(SPCA533, 0)},
1032 {USB_DEVICE(0x08ca, 0x2008), BS(SPCA504B, 0)},
1033 {USB_DEVICE(0x08ca, 0x2010), BS(SPCA533, 0)},
1034 {USB_DEVICE(0x08ca, 0x2016), BS(SPCA504B, 0)},
1035 {USB_DEVICE(0x08ca, 0x2018), BS(SPCA504B, 0)},
1036 {USB_DEVICE(0x08ca, 0x2020), BS(SPCA533, 0)},
1037 {USB_DEVICE(0x08ca, 0x2022), BS(SPCA533, 0)},
1038 {USB_DEVICE(0x08ca, 0x2024), BS(SPCA536, 0)},
1039 {USB_DEVICE(0x08ca, 0x2028), BS(SPCA533, 0)},
1040 {USB_DEVICE(0x08ca, 0x2040), BS(SPCA536, 0)},
1041 {USB_DEVICE(0x08ca, 0x2042), BS(SPCA536, 0)},
1042 {USB_DEVICE(0x08ca, 0x2050), BS(SPCA536, 0)},
1043 {USB_DEVICE(0x08ca, 0x2060), BS(SPCA536, 0)},
1044 {USB_DEVICE(0x0d64, 0x0303), BS(SPCA536, 0)},
1045 {}
1046 };
1047 MODULE_DEVICE_TABLE(usb, device_table);
1048
1049
1050 static int sd_probe(struct usb_interface *intf,
1051 const struct usb_device_id *id)
1052 {
1053 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1054 THIS_MODULE);
1055 }
1056
1057 static struct usb_driver sd_driver = {
1058 .name = MODULE_NAME,
1059 .id_table = device_table,
1060 .probe = sd_probe,
1061 .disconnect = gspca_disconnect,
1062 #ifdef CONFIG_PM
1063 .suspend = gspca_suspend,
1064 .resume = gspca_resume,
1065 .reset_resume = gspca_resume,
1066 #endif
1067 };
1068
1069 module_usb_driver(sd_driver);