diff options
author | Jean-Francois Moine <moinejf@free.fr> | 2008-09-03 15:47:25 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-09-03 17:36:29 -0400 |
commit | 49b57dba2f6425e9b42874b4dec2433b335fa69c (patch) | |
tree | 36654b65fc2ff12ce5db8fe7c3dcebcbb1b0e5c1 /drivers | |
parent | d2d16e9084ee44088974c3312b803d54dd9b46d7 (diff) |
V4L/DVB (8664): gspca: The bridge/sensor of the webcam 093a:2621 is a PAC 7302.
Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/video/gspca/pac7311.c | 418 |
1 files changed, 294 insertions, 124 deletions
diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c index 96cd7f644adf..034c00d6c0ab 100644 --- a/drivers/media/video/gspca/pac7311.c +++ b/drivers/media/video/gspca/pac7311.c | |||
@@ -44,6 +44,10 @@ struct sd { | |||
44 | char tosof; /* number of bytes before next start of frame */ | 44 | char tosof; /* number of bytes before next start of frame */ |
45 | signed char ag_cnt; | 45 | signed char ag_cnt; |
46 | #define AG_CNT_START 13 | 46 | #define AG_CNT_START 13 |
47 | |||
48 | __u8 sensor; | ||
49 | #define SENSOR_PAC7302 0 | ||
50 | #define SENSOR_PAC7311 1 | ||
47 | }; | 51 | }; |
48 | 52 | ||
49 | /* V4L2 controls supported by the driver */ | 53 | /* V4L2 controls supported by the driver */ |
@@ -206,9 +210,158 @@ static const __u8 pac7311_jpeg_header[] = { | |||
206 | 0x11, 0x00, 0x3f, 0x00 | 210 | 0x11, 0x00, 0x3f, 0x00 |
207 | }; | 211 | }; |
208 | 212 | ||
213 | /* pac 7302 */ | ||
214 | static const __u8 probe_7302[] = { | ||
215 | /* index,value */ | ||
216 | 0xff, 0x01, /* page 1 */ | ||
217 | 0x78, 0x00, /* deactivate */ | ||
218 | 0xff, 0x01, | ||
219 | 0x78, 0x40, /* led off */ | ||
220 | }; | ||
221 | static const __u8 start_7302[] = { | ||
222 | /* index, len, [value]* */ | ||
223 | 0x00, 12, 0x01, 0x40, 0x40, 0x40, 0x01, 0xe0, 0x02, 0x80, | ||
224 | 0x00, 0x00, 0x00, 0x00, | ||
225 | 0x0d, 24, 0x03, 0x01, 0x00, 0xb5, 0x07, 0xcb, 0x00, 0x00, | ||
226 | 0x07, 0xc8, 0x00, 0xea, 0x07, 0xcf, 0x07, 0xf7, | ||
227 | 0x07, 0x7e, 0x01, 0x0b, 0x00, 0x00, 0x00, 0x11, | ||
228 | 0x26, 2, 0xaa, 0xaa, | ||
229 | 0x2e, 1, 0x31, | ||
230 | 0x38, 1, 0x01, | ||
231 | 0x3a, 3, 0x14, 0xff, 0x5a, | ||
232 | 0x43, 11, 0x00, 0x0a, 0x18, 0x11, 0x01, 0x2c, 0x88, 0x11, | ||
233 | 0x00, 0x54, 0x11, | ||
234 | 0x55, 1, 0x00, | ||
235 | 0x62, 4, 0x10, 0x1e, 0x1e, 0x18, | ||
236 | 0x6b, 1, 0x00, | ||
237 | 0x6e, 3, 0x08, 0x06, 0x00, | ||
238 | 0x72, 3, 0x00, 0xff, 0x00, | ||
239 | 0x7d, 23, 0x01, 0x01, 0x58, 0x46, 0x50, 0x3c, 0x50, 0x3c, | ||
240 | 0x54, 0x46, 0x54, 0x56, 0x52, 0x50, 0x52, 0x50, | ||
241 | 0x56, 0x64, 0xa4, 0x00, 0xda, 0x00, 0x00, | ||
242 | 0xa2, 10, 0x22, 0x2c, 0x3c, 0x54, 0x69, 0x7c, 0x9c, 0xb9, | ||
243 | 0xd2, 0xeb, | ||
244 | 0xaf, 1, 0x02, | ||
245 | 0xb5, 2, 0x08, 0x08, | ||
246 | 0xb8, 2, 0x08, 0x88, | ||
247 | 0xc4, 4, 0xae, 0x01, 0x04, 0x01, | ||
248 | 0xcc, 1, 0x00, | ||
249 | 0xd1, 11, 0x01, 0x30, 0x49, 0x5e, 0x6f, 0x7f, 0x8e, 0xa9, | ||
250 | 0xc1, 0xd7, 0xec, | ||
251 | 0xdc, 1, 0x01, | ||
252 | 0xff, 1, 0x01, | ||
253 | 0x12, 3, 0x02, 0x00, 0x01, | ||
254 | 0x3e, 2, 0x00, 0x00, | ||
255 | 0x76, 5, 0x01, 0x20, 0x40, 0x00, 0xf2, | ||
256 | 0x7c, 1, 0x00, | ||
257 | 0x7f, 10, 0x4b, 0x0f, 0x01, 0x2c, 0x02, 0x58, 0x03, 0x20, | ||
258 | 0x02, 0x00, | ||
259 | 0x96, 5, 0x01, 0x10, 0x04, 0x01, 0x04, | ||
260 | 0xc8, 17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, | ||
261 | 0x07, 0x00, 0x01, 0x07, 0x04, 0x01, | ||
262 | 0x01, | ||
263 | 0xdb, 2, 0x00, 0x01, | ||
264 | 0xde, 8, 0x00, 0x01, 0x04, 0x04, 0x00, 0x00, 0x00, | ||
265 | 0xe6, 4, 0x00, 0x00, 0x00, 0x01, | ||
266 | 0xeb, 1, 0x00, | ||
267 | 0xff, 1, 0x02, | ||
268 | 0x22, 1, 0x00, | ||
269 | 0xff, 1, 0x03, | ||
270 | 0x00, 255, /* load the page 3 */ | ||
271 | 0x11, 1, 0x01, | ||
272 | 0xff, 1, 0x02, | ||
273 | 0x13, 1, 0x00, | ||
274 | 0x22, 4, 0x1f, 0xa4, 0xf0, 0x96, | ||
275 | 0x27, 2, 0x14, 0x0c, | ||
276 | 0x2a, 5, 0xc8, 0x00, 0x18, 0x12, 0x22, | ||
277 | 0x64, 8, 0x00, 0x00, 0xf0, 0x01, 0x14, 0x44, 0x44, 0x44, | ||
278 | 0x6e, 1, 0x08, | ||
279 | 0xff, 1, 0x03, | ||
280 | 0x78, 1, 0x00, | ||
281 | 0, 0 /* end of sequence */ | ||
282 | }; | ||
283 | |||
284 | /* page 3 - the value 0xaa says skip the index - see reg_w_page() */ | ||
285 | static const __u8 page3_7302[] = { | ||
286 | 0x90, 0x40, 0x03, 0x50, 0xc2, 0x01, 0x14, 0x16, | ||
287 | 0x14, 0x12, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00, | ||
288 | 0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
289 | 0x00, 0x00, 0x00, 0x47, 0x01, 0xb3, 0x01, 0x00, | ||
290 | 0x00, 0x08, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x21, | ||
291 | 0x00, 0x00, 0x00, 0x54, 0xf4, 0x02, 0x52, 0x54, | ||
292 | 0xa4, 0xb8, 0xe0, 0x2a, 0xf6, 0x00, 0x00, 0x00, | ||
293 | 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
294 | 0x00, 0xfc, 0x00, 0xf2, 0x1f, 0x04, 0x00, 0x00, | ||
295 | 0x00, 0x00, 0x00, 0xc0, 0xc0, 0x10, 0x00, 0x00, | ||
296 | 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
297 | 0x00, 0x40, 0xff, 0x03, 0x19, 0x00, 0x00, 0x00, | ||
298 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
299 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc8, 0xc8, | ||
300 | 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, | ||
301 | 0x08, 0x10, 0x24, 0x40, 0x00, 0x00, 0x00, 0x00, | ||
302 | 0x01, 0x00, 0x02, 0x47, 0x00, 0x00, 0x00, 0x00, | ||
303 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
304 | 0x00, 0x02, 0xfa, 0x00, 0x64, 0x5a, 0x28, 0x00, | ||
305 | 0x00 | ||
306 | }; | ||
307 | |||
308 | /* pac 7311 */ | ||
309 | static const __u8 probe_7311[] = { | ||
310 | 0x78, 0x40, /* Bit_0=start stream, Bit_7=LED */ | ||
311 | 0x78, 0x40, /* Bit_0=start stream, Bit_7=LED */ | ||
312 | 0x78, 0x44, /* Bit_0=start stream, Bit_7=LED */ | ||
313 | 0xff, 0x04, | ||
314 | 0x27, 0x80, | ||
315 | 0x28, 0xca, | ||
316 | 0x29, 0x53, | ||
317 | 0x2a, 0x0e, | ||
318 | 0xff, 0x01, | ||
319 | 0x3e, 0x20, | ||
320 | }; | ||
321 | |||
322 | static const __u8 start_7311[] = { | ||
323 | /* index, len, [value]* */ | ||
324 | 0xff, 1, 0x01, | ||
325 | 0x02, 53, 0x48, 0x0a, 0x40, 0x08, 0x00, 0x00, 0x08, 0x00, | ||
326 | 0x06, 0xff, 0x11, 0xff, 0x5a, 0x30, 0x90, 0x4c, | ||
327 | 0x00, 0x07, 0x00, 0x0a, 0x10, 0x00, 0xa0, 0x10, | ||
328 | 0x02, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x01, 0x00, | ||
329 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
330 | 0x00, 0x00, 0x00, | ||
331 | 0x3e, 52, 0x00, 0x00, 0x78, 0x52, 0x4a, 0x52, 0x78, 0x6e, | ||
332 | 0x48, 0x46, 0x48, 0x6e, 0x5f, 0x49, 0x42, 0x49, | ||
333 | 0x5f, 0x5f, 0x49, 0x42, 0x49, 0x5f, 0x6e, 0x48, | ||
334 | 0x46, 0x48, 0x6e, 0x78, 0x52, 0x4a, 0x52, 0x78, | ||
335 | 0x00, 0x00, 0x09, 0x1b, 0x34, 0x49, 0x5c, 0x9b, | ||
336 | 0xd0, 0xff, | ||
337 | 0x78, 6, 0x44, 0x00, 0xf2, 0x01, 0x01, 0x80, | ||
338 | 0x7f, 18, 0x2a, 0x1c, 0x00, 0xc8, 0x02, 0x58, 0x03, 0x84, | ||
339 | 0x12, 0x00, 0x1a, 0x04, 0x08, 0x0c, 0x10, 0x14, | ||
340 | 0x18, 0x20, | ||
341 | 0x96, 3, 0x01, 0x08, 0x04, | ||
342 | 0xa0, 4, 0x44, 0x44, 0x44, 0x04, | ||
343 | 0xf0, 13, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x20, 0x00, | ||
344 | 0x3f, 0x00, 0x0a, 0x01, 0x00, | ||
345 | 0xff, 1, 0x04, | ||
346 | 0x00, 254, /* load the page 4 */ | ||
347 | 0x11, 1, 0x01, | ||
348 | 0, 0 /* end of sequence */ | ||
349 | }; | ||
350 | |||
351 | /* page 4 - the value 0xaa says skip the index - see reg_w_page() */ | ||
352 | static const __u8 page4_7311[] = { | ||
353 | 0xaa, 0xaa, 0x04, 0x54, 0x07, 0x2b, 0x09, 0x0f, | ||
354 | 0x09, 0x00, 0xaa, 0xaa, 0x07, 0x00, 0x00, 0x62, | ||
355 | 0x08, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
356 | 0x00, 0x00, 0x00, 0x03, 0xa0, 0x01, 0xf4, 0xaa, | ||
357 | 0xaa, 0x00, 0x08, 0xaa, 0x03, 0xaa, 0x00, 0x01, | ||
358 | 0xca, 0x10, 0x06, 0x78, 0x00, 0x00, 0x00, 0x00, | ||
359 | 0x23, 0x28, 0x04, 0x11, 0x00, 0x00 | ||
360 | }; | ||
361 | |||
209 | static void reg_w_buf(struct gspca_dev *gspca_dev, | 362 | static void reg_w_buf(struct gspca_dev *gspca_dev, |
210 | __u16 index, | 363 | __u8 index, |
211 | const char *buffer, __u16 len) | 364 | const char *buffer, int len) |
212 | { | 365 | { |
213 | memcpy(gspca_dev->usb_buf, buffer, len); | 366 | memcpy(gspca_dev->usb_buf, buffer, len); |
214 | usb_control_msg(gspca_dev->dev, | 367 | usb_control_msg(gspca_dev->dev, |
@@ -221,7 +374,7 @@ static void reg_w_buf(struct gspca_dev *gspca_dev, | |||
221 | } | 374 | } |
222 | 375 | ||
223 | static __u8 reg_r(struct gspca_dev *gspca_dev, | 376 | static __u8 reg_r(struct gspca_dev *gspca_dev, |
224 | __u16 index) | 377 | __u8 index) |
225 | { | 378 | { |
226 | usb_control_msg(gspca_dev->dev, | 379 | usb_control_msg(gspca_dev->dev, |
227 | usb_rcvctrlpipe(gspca_dev->dev, 0), | 380 | usb_rcvctrlpipe(gspca_dev->dev, 0), |
@@ -234,7 +387,7 @@ static __u8 reg_r(struct gspca_dev *gspca_dev, | |||
234 | } | 387 | } |
235 | 388 | ||
236 | static void reg_w(struct gspca_dev *gspca_dev, | 389 | static void reg_w(struct gspca_dev *gspca_dev, |
237 | __u16 index, | 390 | __u8 index, |
238 | __u8 value) | 391 | __u8 value) |
239 | { | 392 | { |
240 | gspca_dev->usb_buf[0] = value; | 393 | gspca_dev->usb_buf[0] = value; |
@@ -246,6 +399,74 @@ static void reg_w(struct gspca_dev *gspca_dev, | |||
246 | 500); | 399 | 500); |
247 | } | 400 | } |
248 | 401 | ||
402 | static void reg_w_seq(struct gspca_dev *gspca_dev, | ||
403 | const __u8 *seq, int len) | ||
404 | { | ||
405 | while (--len >= 0) { | ||
406 | reg_w(gspca_dev, seq[0], seq[1]); | ||
407 | seq += 2; | ||
408 | } | ||
409 | } | ||
410 | |||
411 | /* load the beginning of a page */ | ||
412 | static void reg_w_page(struct gspca_dev *gspca_dev, | ||
413 | const __u8 *page, int len) | ||
414 | { | ||
415 | int index; | ||
416 | |||
417 | for (index = 0; index < len; index++) { | ||
418 | if (page[index] == 0xaa) /* skip this index */ | ||
419 | continue; | ||
420 | gspca_dev->usb_buf[0] = page[index]; | ||
421 | usb_control_msg(gspca_dev->dev, | ||
422 | usb_sndctrlpipe(gspca_dev->dev, 0), | ||
423 | 0, /* request */ | ||
424 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
425 | 0, index, gspca_dev->usb_buf, 1, | ||
426 | 500); | ||
427 | } | ||
428 | } | ||
429 | |||
430 | /* output a variable sequence */ | ||
431 | static void reg_w_var(struct gspca_dev *gspca_dev, | ||
432 | const __u8 *seq) | ||
433 | { | ||
434 | int index, len; | ||
435 | |||
436 | for (;;) { | ||
437 | index = *seq++; | ||
438 | len = *seq++; | ||
439 | switch (len) { | ||
440 | case 0: | ||
441 | return; | ||
442 | case 254: | ||
443 | reg_w_page(gspca_dev, page4_7311, sizeof page4_7311); | ||
444 | break; | ||
445 | case 255: | ||
446 | reg_w_page(gspca_dev, page3_7302, sizeof page3_7302); | ||
447 | break; | ||
448 | default: | ||
449 | if (len > 32) { | ||
450 | PDEBUG(D_ERR|D_STREAM, | ||
451 | "Incorrect variable sequence"); | ||
452 | return; | ||
453 | } | ||
454 | while (len > 0) { | ||
455 | if (len < 8) { | ||
456 | reg_w_buf(gspca_dev, index, seq, len); | ||
457 | seq += len; | ||
458 | break; | ||
459 | } | ||
460 | reg_w_buf(gspca_dev, index, seq, 8); | ||
461 | seq += 8; | ||
462 | index += 8; | ||
463 | len -= 8; | ||
464 | } | ||
465 | } | ||
466 | } | ||
467 | /* not reached */ | ||
468 | } | ||
469 | |||
249 | /* this function is called at probe time */ | 470 | /* this function is called at probe time */ |
250 | static int sd_config(struct gspca_dev *gspca_dev, | 471 | static int sd_config(struct gspca_dev *gspca_dev, |
251 | const struct usb_device_id *id) | 472 | const struct usb_device_id *id) |
@@ -253,22 +474,23 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
253 | struct sd *sd = (struct sd *) gspca_dev; | 474 | struct sd *sd = (struct sd *) gspca_dev; |
254 | struct cam *cam; | 475 | struct cam *cam; |
255 | 476 | ||
256 | PDEBUG(D_CONF, "Find Sensor PAC7311"); | ||
257 | reg_w(gspca_dev, 0x78, 0x40); /* Bit_0=start stream, Bit_7=LED */ | ||
258 | reg_w(gspca_dev, 0x78, 0x40); /* Bit_0=start stream, Bit_7=LED */ | ||
259 | reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */ | ||
260 | reg_w(gspca_dev, 0xff, 0x04); | ||
261 | reg_w(gspca_dev, 0x27, 0x80); | ||
262 | reg_w(gspca_dev, 0x28, 0xca); | ||
263 | reg_w(gspca_dev, 0x29, 0x53); | ||
264 | reg_w(gspca_dev, 0x2a, 0x0e); | ||
265 | reg_w(gspca_dev, 0xff, 0x01); | ||
266 | reg_w(gspca_dev, 0x3e, 0x20); | ||
267 | |||
268 | cam = &gspca_dev->cam; | 477 | cam = &gspca_dev->cam; |
269 | cam->epaddr = 0x05; | 478 | cam->epaddr = 0x05; |
270 | cam->cam_mode = vga_mode; | 479 | |
271 | cam->nmodes = ARRAY_SIZE(vga_mode); | 480 | sd->sensor = id->driver_info; |
481 | if (sd->sensor == SENSOR_PAC7302) { | ||
482 | PDEBUG(D_CONF, "Find Sensor PAC7302"); | ||
483 | reg_w_seq(gspca_dev, probe_7302, sizeof probe_7302); | ||
484 | |||
485 | cam->cam_mode = &vga_mode[2]; /* only 640x480 */ | ||
486 | cam->nmodes = 1; | ||
487 | } else { | ||
488 | PDEBUG(D_CONF, "Find Sensor PAC7311"); | ||
489 | reg_w_seq(gspca_dev, probe_7302, sizeof probe_7302); | ||
490 | |||
491 | cam->cam_mode = vga_mode; | ||
492 | cam->nmodes = ARRAY_SIZE(vga_mode); | ||
493 | } | ||
272 | 494 | ||
273 | sd->brightness = BRIGHTNESS_DEF; | 495 | sd->brightness = BRIGHTNESS_DEF; |
274 | sd->contrast = CONTRAST_DEF; | 496 | sd->contrast = CONTRAST_DEF; |
@@ -283,10 +505,11 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
283 | struct sd *sd = (struct sd *) gspca_dev; | 505 | struct sd *sd = (struct sd *) gspca_dev; |
284 | int brightness; | 506 | int brightness; |
285 | 507 | ||
508 | if (sd->sensor == SENSOR_PAC7302) | ||
509 | return; | ||
286 | /*jfm: inverted?*/ | 510 | /*jfm: inverted?*/ |
287 | brightness = BRIGHTNESS_MAX - sd->brightness; | 511 | brightness = BRIGHTNESS_MAX - sd->brightness; |
288 | reg_w(gspca_dev, 0xff, 0x04); | 512 | reg_w(gspca_dev, 0xff, 0x04); |
289 | /* reg_w(gspca_dev, 0x0e, 0x00); */ | ||
290 | reg_w(gspca_dev, 0x0f, brightness); | 513 | reg_w(gspca_dev, 0x0f, brightness); |
291 | /* load registers to sensor (Bit 0, auto clear) */ | 514 | /* load registers to sensor (Bit 0, auto clear) */ |
292 | reg_w(gspca_dev, 0x11, 0x01); | 515 | reg_w(gspca_dev, 0x11, 0x01); |
@@ -297,6 +520,8 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
297 | { | 520 | { |
298 | struct sd *sd = (struct sd *) gspca_dev; | 521 | struct sd *sd = (struct sd *) gspca_dev; |
299 | 522 | ||
523 | if (sd->sensor == SENSOR_PAC7302) | ||
524 | return; | ||
300 | reg_w(gspca_dev, 0xff, 0x01); | 525 | reg_w(gspca_dev, 0xff, 0x01); |
301 | reg_w(gspca_dev, 0x80, sd->contrast); | 526 | reg_w(gspca_dev, 0x80, sd->contrast); |
302 | /* load registers to sensor (Bit 0, auto clear) */ | 527 | /* load registers to sensor (Bit 0, auto clear) */ |
@@ -308,6 +533,8 @@ static void setcolors(struct gspca_dev *gspca_dev) | |||
308 | { | 533 | { |
309 | struct sd *sd = (struct sd *) gspca_dev; | 534 | struct sd *sd = (struct sd *) gspca_dev; |
310 | 535 | ||
536 | if (sd->sensor == SENSOR_PAC7302) | ||
537 | return; | ||
311 | reg_w(gspca_dev, 0xff, 0x01); | 538 | reg_w(gspca_dev, 0xff, 0x01); |
312 | reg_w(gspca_dev, 0x10, sd->colors); | 539 | reg_w(gspca_dev, 0x10, sd->colors); |
313 | /* load registers to sensor (Bit 0, auto clear) */ | 540 | /* load registers to sensor (Bit 0, auto clear) */ |
@@ -340,75 +567,12 @@ static void sd_start(struct gspca_dev *gspca_dev) | |||
340 | 567 | ||
341 | sd->ffnb = 0; | 568 | sd->ffnb = 0; |
342 | sd->tosof = 0; | 569 | sd->tosof = 0; |
343 | reg_w(gspca_dev, 0xff, 0x01); | ||
344 | reg_w_buf(gspca_dev, 0x0002, "\x48\x0a\x40\x08\x00\x00\x08\x00", 8); | ||
345 | reg_w_buf(gspca_dev, 0x000a, "\x06\xff\x11\xff\x5a\x30\x90\x4c", 8); | ||
346 | reg_w_buf(gspca_dev, 0x0012, "\x00\x07\x00\x0a\x10\x00\xa0\x10", 8); | ||
347 | reg_w_buf(gspca_dev, 0x001a, "\x02\x00\x00\x00\x00\x0b\x01\x00", 8); | ||
348 | reg_w_buf(gspca_dev, 0x0022, "\x00\x00\x00\x00\x00\x00\x00\x00", 8); | ||
349 | reg_w_buf(gspca_dev, 0x002a, "\x00\x00\x00", 3); | ||
350 | reg_w_buf(gspca_dev, 0x003e, "\x00\x00\x78\x52\x4a\x52\x78\x6e", 8); | ||
351 | reg_w_buf(gspca_dev, 0x0046, "\x48\x46\x48\x6e\x5f\x49\x42\x49", 8); | ||
352 | reg_w_buf(gspca_dev, 0x004e, "\x5f\x5f\x49\x42\x49\x5f\x6e\x48", 8); | ||
353 | reg_w_buf(gspca_dev, 0x0056, "\x46\x48\x6e\x78\x52\x4a\x52\x78", 8); | ||
354 | reg_w_buf(gspca_dev, 0x005e, "\x00\x00\x09\x1b\x34\x49\x5c\x9b", 8); | ||
355 | reg_w_buf(gspca_dev, 0x0066, "\xd0\xff", 2); | ||
356 | reg_w_buf(gspca_dev, 0x0078, "\x44\x00\xf2\x01\x01\x80", 6); | ||
357 | reg_w_buf(gspca_dev, 0x007f, "\x2a\x1c\x00\xc8\x02\x58\x03\x84", 8); | ||
358 | reg_w_buf(gspca_dev, 0x0087, "\x12\x00\x1a\x04\x08\x0c\x10\x14", 8); | ||
359 | reg_w_buf(gspca_dev, 0x008f, "\x18\x20", 2); | ||
360 | reg_w_buf(gspca_dev, 0x0096, "\x01\x08\x04", 3); | ||
361 | reg_w_buf(gspca_dev, 0x00a0, "\x44\x44\x44\x04", 4); | ||
362 | reg_w_buf(gspca_dev, 0x00f0, "\x01\x00\x00\x00\x22\x00\x20\x00", 8); | ||
363 | reg_w_buf(gspca_dev, 0x00f8, "\x3f\x00\x0a\x01\x00", 5); | ||
364 | 570 | ||
365 | reg_w(gspca_dev, 0xff, 0x04); | 571 | if (sd->sensor == SENSOR_PAC7302) |
366 | reg_w(gspca_dev, 0x02, 0x04); | 572 | reg_w_var(gspca_dev, start_7302); |
367 | reg_w(gspca_dev, 0x03, 0x54); | 573 | else |
368 | reg_w(gspca_dev, 0x04, 0x07); | 574 | reg_w_var(gspca_dev, start_7311); |
369 | reg_w(gspca_dev, 0x05, 0x2b); | 575 | |
370 | reg_w(gspca_dev, 0x06, 0x09); | ||
371 | reg_w(gspca_dev, 0x07, 0x0f); | ||
372 | reg_w(gspca_dev, 0x08, 0x09); | ||
373 | reg_w(gspca_dev, 0x09, 0x00); | ||
374 | reg_w(gspca_dev, 0x0c, 0x07); | ||
375 | reg_w(gspca_dev, 0x0d, 0x00); | ||
376 | reg_w(gspca_dev, 0x0e, 0x00); | ||
377 | reg_w(gspca_dev, 0x0f, 0x62); | ||
378 | reg_w(gspca_dev, 0x10, 0x08); | ||
379 | reg_w(gspca_dev, 0x12, 0x07); | ||
380 | reg_w(gspca_dev, 0x13, 0x00); | ||
381 | reg_w(gspca_dev, 0x14, 0x00); | ||
382 | reg_w(gspca_dev, 0x15, 0x00); | ||
383 | reg_w(gspca_dev, 0x16, 0x00); | ||
384 | reg_w(gspca_dev, 0x17, 0x00); | ||
385 | reg_w(gspca_dev, 0x18, 0x00); | ||
386 | reg_w(gspca_dev, 0x19, 0x00); | ||
387 | reg_w(gspca_dev, 0x1a, 0x00); | ||
388 | reg_w(gspca_dev, 0x1b, 0x03); | ||
389 | reg_w(gspca_dev, 0x1c, 0xa0); | ||
390 | reg_w(gspca_dev, 0x1d, 0x01); | ||
391 | reg_w(gspca_dev, 0x1e, 0xf4); | ||
392 | reg_w(gspca_dev, 0x21, 0x00); | ||
393 | reg_w(gspca_dev, 0x22, 0x08); | ||
394 | reg_w(gspca_dev, 0x24, 0x03); | ||
395 | reg_w(gspca_dev, 0x26, 0x00); | ||
396 | reg_w(gspca_dev, 0x27, 0x01); | ||
397 | reg_w(gspca_dev, 0x28, 0xca); | ||
398 | reg_w(gspca_dev, 0x29, 0x10); | ||
399 | reg_w(gspca_dev, 0x2a, 0x06); | ||
400 | reg_w(gspca_dev, 0x2b, 0x78); | ||
401 | reg_w(gspca_dev, 0x2c, 0x00); | ||
402 | reg_w(gspca_dev, 0x2d, 0x00); | ||
403 | reg_w(gspca_dev, 0x2e, 0x00); | ||
404 | reg_w(gspca_dev, 0x2f, 0x00); | ||
405 | reg_w(gspca_dev, 0x30, 0x23); | ||
406 | reg_w(gspca_dev, 0x31, 0x28); | ||
407 | reg_w(gspca_dev, 0x32, 0x04); | ||
408 | reg_w(gspca_dev, 0x33, 0x11); | ||
409 | reg_w(gspca_dev, 0x34, 0x00); | ||
410 | reg_w(gspca_dev, 0x35, 0x00); | ||
411 | reg_w(gspca_dev, 0x11, 0x01); | ||
412 | setcontrast(gspca_dev); | 576 | setcontrast(gspca_dev); |
413 | setbrightness(gspca_dev); | 577 | setbrightness(gspca_dev); |
414 | setcolors(gspca_dev); | 578 | setcolors(gspca_dev); |
@@ -416,7 +580,7 @@ static void sd_start(struct gspca_dev *gspca_dev) | |||
416 | 580 | ||
417 | /* set correct resolution */ | 581 | /* set correct resolution */ |
418 | switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { | 582 | switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { |
419 | case 2: /* 160x120 */ | 583 | case 2: /* 160x120 pac7311 */ |
420 | reg_w(gspca_dev, 0xff, 0x04); | 584 | reg_w(gspca_dev, 0xff, 0x04); |
421 | reg_w(gspca_dev, 0x02, 0x03); | 585 | reg_w(gspca_dev, 0x02, 0x03); |
422 | reg_w(gspca_dev, 0xff, 0x01); | 586 | reg_w(gspca_dev, 0xff, 0x01); |
@@ -426,7 +590,7 @@ static void sd_start(struct gspca_dev *gspca_dev) | |||
426 | /* reg_w(gspca_dev, 0x80, 0x69); */ | 590 | /* reg_w(gspca_dev, 0x80, 0x69); */ |
427 | reg_w(gspca_dev, 0x87, 0x10); | 591 | reg_w(gspca_dev, 0x87, 0x10); |
428 | break; | 592 | break; |
429 | case 1: /* 320x240 */ | 593 | case 1: /* 320x240 pac7311 */ |
430 | reg_w(gspca_dev, 0xff, 0x04); | 594 | reg_w(gspca_dev, 0xff, 0x04); |
431 | reg_w(gspca_dev, 0x02, 0x03); | 595 | reg_w(gspca_dev, 0x02, 0x03); |
432 | reg_w(gspca_dev, 0xff, 0x01); | 596 | reg_w(gspca_dev, 0xff, 0x01); |
@@ -436,6 +600,8 @@ static void sd_start(struct gspca_dev *gspca_dev) | |||
436 | reg_w(gspca_dev, 0x87, 0x11); | 600 | reg_w(gspca_dev, 0x87, 0x11); |
437 | break; | 601 | break; |
438 | case 0: /* 640x480 */ | 602 | case 0: /* 640x480 */ |
603 | if (sd->sensor == SENSOR_PAC7302) | ||
604 | break; | ||
439 | reg_w(gspca_dev, 0xff, 0x04); | 605 | reg_w(gspca_dev, 0xff, 0x04); |
440 | reg_w(gspca_dev, 0x02, 0x03); | 606 | reg_w(gspca_dev, 0x02, 0x03); |
441 | reg_w(gspca_dev, 0xff, 0x01); | 607 | reg_w(gspca_dev, 0xff, 0x01); |
@@ -448,12 +614,25 @@ static void sd_start(struct gspca_dev *gspca_dev) | |||
448 | 614 | ||
449 | /* start stream */ | 615 | /* start stream */ |
450 | reg_w(gspca_dev, 0xff, 0x01); | 616 | reg_w(gspca_dev, 0xff, 0x01); |
451 | reg_w(gspca_dev, 0x78, 0x04); | 617 | if (sd->sensor == SENSOR_PAC7302) { |
452 | reg_w(gspca_dev, 0x78, 0x05); | 618 | reg_w(gspca_dev, 0x78, 0x01); |
619 | reg_w(gspca_dev, 0xff, 0x01); | ||
620 | reg_w(gspca_dev, 0x78, 0x01); | ||
621 | } else { | ||
622 | reg_w(gspca_dev, 0x78, 0x04); | ||
623 | reg_w(gspca_dev, 0x78, 0x05); | ||
624 | } | ||
453 | } | 625 | } |
454 | 626 | ||
455 | static void sd_stopN(struct gspca_dev *gspca_dev) | 627 | static void sd_stopN(struct gspca_dev *gspca_dev) |
456 | { | 628 | { |
629 | struct sd *sd = (struct sd *) gspca_dev; | ||
630 | |||
631 | if (sd->sensor == SENSOR_PAC7302) { | ||
632 | reg_w(gspca_dev, 0x78, 0x00); | ||
633 | reg_w(gspca_dev, 0x78, 0x00); | ||
634 | return; | ||
635 | } | ||
457 | reg_w(gspca_dev, 0xff, 0x04); | 636 | reg_w(gspca_dev, 0xff, 0x04); |
458 | reg_w(gspca_dev, 0x27, 0x80); | 637 | reg_w(gspca_dev, 0x27, 0x80); |
459 | reg_w(gspca_dev, 0x28, 0xca); | 638 | reg_w(gspca_dev, 0x28, 0xca); |
@@ -468,21 +647,17 @@ static void sd_stopN(struct gspca_dev *gspca_dev) | |||
468 | 647 | ||
469 | static void sd_stop0(struct gspca_dev *gspca_dev) | 648 | static void sd_stop0(struct gspca_dev *gspca_dev) |
470 | { | 649 | { |
650 | struct sd *sd = (struct sd *) gspca_dev; | ||
651 | |||
652 | if (sd->sensor == SENSOR_PAC7302) { | ||
653 | reg_w(gspca_dev, 0xff, 0x01); | ||
654 | reg_w(gspca_dev, 0x78, 0x40); | ||
655 | } | ||
471 | } | 656 | } |
472 | 657 | ||
473 | /* this function is called at close time */ | 658 | /* this function is called at close time */ |
474 | static void sd_close(struct gspca_dev *gspca_dev) | 659 | static void sd_close(struct gspca_dev *gspca_dev) |
475 | { | 660 | { |
476 | reg_w(gspca_dev, 0xff, 0x04); | ||
477 | reg_w(gspca_dev, 0x27, 0x80); | ||
478 | reg_w(gspca_dev, 0x28, 0xca); | ||
479 | reg_w(gspca_dev, 0x29, 0x53); | ||
480 | reg_w(gspca_dev, 0x2a, 0x0e); | ||
481 | reg_w(gspca_dev, 0xff, 0x01); | ||
482 | reg_w(gspca_dev, 0x3e, 0x20); | ||
483 | reg_w(gspca_dev, 0x78, 0x04); /* Bit_0=start stream, Bit_7=LED */ | ||
484 | reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */ | ||
485 | reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */ | ||
486 | } | 661 | } |
487 | 662 | ||
488 | static void do_autogain(struct gspca_dev *gspca_dev) | 663 | static void do_autogain(struct gspca_dev *gspca_dev) |
@@ -509,10 +684,17 @@ static void do_autogain(struct gspca_dev *gspca_dev) | |||
509 | else if (Gbright < 4) | 684 | else if (Gbright < 4) |
510 | Gbright = 4; | 685 | Gbright = 4; |
511 | PDEBUG(D_FRAM, "gbright %d", Gbright); | 686 | PDEBUG(D_FRAM, "gbright %d", Gbright); |
512 | reg_w(gspca_dev, 0xff, 0x04); | 687 | if (sd->sensor == SENSOR_PAC7302) { |
513 | reg_w(gspca_dev, 0x0f, Gbright); | 688 | reg_w(gspca_dev, 0xff, 0x03); |
514 | /* load registers to sensor (Bit 0, auto clear) */ | 689 | reg_w(gspca_dev, 0x10, Gbright); |
515 | reg_w(gspca_dev, 0x11, 0x01); | 690 | /* load registers to sensor (Bit 0, auto clear) */ |
691 | reg_w(gspca_dev, 0x11, 0x01); | ||
692 | } else { | ||
693 | reg_w(gspca_dev, 0xff, 0x04); | ||
694 | reg_w(gspca_dev, 0x0f, Gbright); | ||
695 | /* load registers to sensor (Bit 0, auto clear) */ | ||
696 | reg_w(gspca_dev, 0x11, 0x01); | ||
697 | } | ||
516 | } | 698 | } |
517 | } | 699 | } |
518 | 700 | ||
@@ -636,15 +818,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
636 | } | 818 | } |
637 | } | 819 | } |
638 | 820 | ||
639 | static void getbrightness(struct gspca_dev *gspca_dev) | ||
640 | { | ||
641 | /* sd->brightness = reg_r(gspca_dev, 0x08); | ||
642 | return sd->brightness; */ | ||
643 | /* PDEBUG(D_CONF, "Called pac7311_getbrightness: Not implemented yet"); */ | ||
644 | } | ||
645 | |||
646 | |||
647 | |||
648 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | 821 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) |
649 | { | 822 | { |
650 | struct sd *sd = (struct sd *) gspca_dev; | 823 | struct sd *sd = (struct sd *) gspca_dev; |
@@ -659,7 +832,6 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | |||
659 | { | 832 | { |
660 | struct sd *sd = (struct sd *) gspca_dev; | 833 | struct sd *sd = (struct sd *) gspca_dev; |
661 | 834 | ||
662 | getbrightness(gspca_dev); | ||
663 | *val = sd->brightness; | 835 | *val = sd->brightness; |
664 | return 0; | 836 | return 0; |
665 | } | 837 | } |
@@ -678,7 +850,6 @@ static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) | |||
678 | { | 850 | { |
679 | struct sd *sd = (struct sd *) gspca_dev; | 851 | struct sd *sd = (struct sd *) gspca_dev; |
680 | 852 | ||
681 | /* getcontrast(gspca_dev); */ | ||
682 | *val = sd->contrast; | 853 | *val = sd->contrast; |
683 | return 0; | 854 | return 0; |
684 | } | 855 | } |
@@ -697,7 +868,6 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) | |||
697 | { | 868 | { |
698 | struct sd *sd = (struct sd *) gspca_dev; | 869 | struct sd *sd = (struct sd *) gspca_dev; |
699 | 870 | ||
700 | /* getcolors(gspca_dev); */ | ||
701 | *val = sd->colors; | 871 | *val = sd->colors; |
702 | return 0; | 872 | return 0; |
703 | } | 873 | } |
@@ -737,13 +907,13 @@ static struct sd_desc sd_desc = { | |||
737 | 907 | ||
738 | /* -- module initialisation -- */ | 908 | /* -- module initialisation -- */ |
739 | static __devinitdata struct usb_device_id device_table[] = { | 909 | static __devinitdata struct usb_device_id device_table[] = { |
740 | {USB_DEVICE(0x093a, 0x2600)}, | 910 | {USB_DEVICE(0x093a, 0x2600), .driver_info = SENSOR_PAC7311}, |
741 | {USB_DEVICE(0x093a, 0x2601)}, | 911 | {USB_DEVICE(0x093a, 0x2601), .driver_info = SENSOR_PAC7311}, |
742 | {USB_DEVICE(0x093a, 0x2603)}, | 912 | {USB_DEVICE(0x093a, 0x2603), .driver_info = SENSOR_PAC7311}, |
743 | {USB_DEVICE(0x093a, 0x2608)}, | 913 | {USB_DEVICE(0x093a, 0x2608), .driver_info = SENSOR_PAC7311}, |
744 | {USB_DEVICE(0x093a, 0x260e)}, | 914 | {USB_DEVICE(0x093a, 0x260e), .driver_info = SENSOR_PAC7311}, |
745 | {USB_DEVICE(0x093a, 0x260f)}, | 915 | {USB_DEVICE(0x093a, 0x260f), .driver_info = SENSOR_PAC7311}, |
746 | {USB_DEVICE(0x093a, 0x2621)}, | 916 | {USB_DEVICE(0x093a, 0x2621), .driver_info = SENSOR_PAC7302}, |
747 | {} | 917 | {} |
748 | }; | 918 | }; |
749 | MODULE_DEVICE_TABLE(usb, device_table); | 919 | MODULE_DEVICE_TABLE(usb, device_table); |