diff options
Diffstat (limited to 'drivers/media/video/gspca/sonixj.c')
| -rw-r--r-- | drivers/media/video/gspca/sonixj.c | 585 |
1 files changed, 493 insertions, 92 deletions
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index 1d61b92f6bfc..bb923efb75bd 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Sonix sn9c102p sn9c105 sn9c120 (jpeg) subdriver | 2 | * Sonix sn9c102p sn9c105 sn9c120 (jpeg) subdriver |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2009 Jean-Francois Moine <http://moinejf.free.fr> | 4 | * Copyright (C) 2009-2010 Jean-François Moine <http://moinejf.free.fr> |
| 5 | * Copyright (C) 2005 Michel Xhaard mxhaard@magic.fr | 5 | * Copyright (C) 2005 Michel Xhaard mxhaard@magic.fr |
| 6 | * | 6 | * |
| 7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
| @@ -28,7 +28,7 @@ | |||
| 28 | 28 | ||
| 29 | #define V4L2_CID_INFRARED (V4L2_CID_PRIVATE_BASE + 0) | 29 | #define V4L2_CID_INFRARED (V4L2_CID_PRIVATE_BASE + 0) |
| 30 | 30 | ||
| 31 | MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); | 31 | MODULE_AUTHOR("Jean-François Moine <http://moinejf.free.fr>"); |
| 32 | MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver"); | 32 | MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver"); |
| 33 | MODULE_LICENSE("GPL"); | 33 | MODULE_LICENSE("GPL"); |
| 34 | 34 | ||
| @@ -67,20 +67,25 @@ struct sd { | |||
| 67 | #define BRIDGE_SN9C110 2 | 67 | #define BRIDGE_SN9C110 2 |
| 68 | #define BRIDGE_SN9C120 3 | 68 | #define BRIDGE_SN9C120 3 |
| 69 | u8 sensor; /* Type of image sensor chip */ | 69 | u8 sensor; /* Type of image sensor chip */ |
| 70 | #define SENSOR_ADCM1700 0 | 70 | enum { |
| 71 | #define SENSOR_HV7131R 1 | 71 | SENSOR_ADCM1700, |
| 72 | #define SENSOR_MI0360 2 | 72 | SENSOR_GC0307, |
| 73 | #define SENSOR_MO4000 3 | 73 | SENSOR_HV7131R, |
| 74 | #define SENSOR_MT9V111 4 | 74 | SENSOR_MI0360, |
| 75 | #define SENSOR_OM6802 5 | 75 | SENSOR_MO4000, |
| 76 | #define SENSOR_OV7630 6 | 76 | SENSOR_MT9V111, |
| 77 | #define SENSOR_OV7648 7 | 77 | SENSOR_OM6802, |
| 78 | #define SENSOR_OV7660 8 | 78 | SENSOR_OV7630, |
| 79 | #define SENSOR_PO1030 9 | 79 | SENSOR_OV7648, |
| 80 | #define SENSOR_SP80708 10 | 80 | SENSOR_OV7660, |
| 81 | SENSOR_PO1030, | ||
| 82 | SENSOR_PO2030N, | ||
| 83 | SENSOR_SOI768, | ||
| 84 | SENSOR_SP80708, | ||
| 85 | } sensors; | ||
| 81 | u8 i2c_addr; | 86 | u8 i2c_addr; |
| 82 | 87 | ||
| 83 | u8 *jpeg_hdr; | 88 | u8 jpeg_hdr[JPEG_HDR_SZ]; |
| 84 | }; | 89 | }; |
| 85 | 90 | ||
| 86 | /* V4L2 controls supported by the driver */ | 91 | /* V4L2 controls supported by the driver */ |
| @@ -281,29 +286,60 @@ static const struct ctrl sd_ctrls[] = { | |||
| 281 | }; | 286 | }; |
| 282 | 287 | ||
| 283 | /* table of the disabled controls */ | 288 | /* table of the disabled controls */ |
| 284 | static __u32 ctrl_dis[] = { | 289 | static const __u32 ctrl_dis[] = { |
| 285 | (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX) | | 290 | [SENSOR_ADCM1700] = (1 << AUTOGAIN_IDX) | |
| 286 | (1 << AUTOGAIN_IDX), /* SENSOR_ADCM1700 0 */ | 291 | (1 << INFRARED_IDX) | |
| 287 | (1 << INFRARED_IDX) | (1 << FREQ_IDX), | 292 | (1 << VFLIP_IDX) | |
| 288 | /* SENSOR_HV7131R 1 */ | 293 | (1 << FREQ_IDX), |
| 289 | (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX), | 294 | |
| 290 | /* SENSOR_MI0360 2 */ | 295 | [SENSOR_GC0307] = (1 << INFRARED_IDX) | |
| 291 | (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX), | 296 | (1 << VFLIP_IDX) | |
| 292 | /* SENSOR_MO4000 3 */ | 297 | (1 << FREQ_IDX), |
| 293 | (1 << VFLIP_IDX) | (1 << FREQ_IDX), | 298 | |
| 294 | /* SENSOR_MT9V111 4 */ | 299 | [SENSOR_HV7131R] = (1 << INFRARED_IDX) | |
| 295 | (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX), | 300 | (1 << FREQ_IDX), |
| 296 | /* SENSOR_OM6802 5 */ | 301 | |
| 297 | (1 << INFRARED_IDX), | 302 | [SENSOR_MI0360] = (1 << INFRARED_IDX) | |
| 298 | /* SENSOR_OV7630 6 */ | 303 | (1 << VFLIP_IDX) | |
| 299 | (1 << INFRARED_IDX), | 304 | (1 << FREQ_IDX), |
| 300 | /* SENSOR_OV7648 7 */ | 305 | |
| 301 | (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX), | 306 | [SENSOR_MO4000] = (1 << INFRARED_IDX) | |
| 302 | /* SENSOR_OV7660 8 */ | 307 | (1 << VFLIP_IDX) | |
| 303 | (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | | 308 | (1 << FREQ_IDX), |
| 304 | (1 << FREQ_IDX), /* SENSOR_PO1030 9 */ | 309 | |
| 305 | (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | | 310 | [SENSOR_MT9V111] = (1 << VFLIP_IDX) | |
| 306 | (1 << FREQ_IDX), /* SENSOR_SP80708 10 */ | 311 | (1 << FREQ_IDX), |
| 312 | |||
| 313 | [SENSOR_OM6802] = (1 << INFRARED_IDX) | | ||
| 314 | (1 << VFLIP_IDX) | | ||
| 315 | (1 << FREQ_IDX), | ||
| 316 | |||
| 317 | [SENSOR_OV7630] = (1 << INFRARED_IDX), | ||
| 318 | |||
| 319 | [SENSOR_OV7648] = (1 << INFRARED_IDX), | ||
| 320 | |||
| 321 | [SENSOR_OV7660] = (1 << AUTOGAIN_IDX) | | ||
| 322 | (1 << INFRARED_IDX) | | ||
| 323 | (1 << VFLIP_IDX), | ||
| 324 | |||
| 325 | [SENSOR_PO1030] = (1 << AUTOGAIN_IDX) | | ||
| 326 | (1 << INFRARED_IDX) | | ||
| 327 | (1 << VFLIP_IDX) | | ||
| 328 | (1 << FREQ_IDX), | ||
| 329 | |||
| 330 | [SENSOR_PO2030N] = (1 << AUTOGAIN_IDX) | | ||
| 331 | (1 << INFRARED_IDX) | | ||
| 332 | (1 << VFLIP_IDX) | | ||
| 333 | (1 << FREQ_IDX), | ||
| 334 | [SENSOR_SOI768] = (1 << AUTOGAIN_IDX) | | ||
| 335 | (1 << INFRARED_IDX) | | ||
| 336 | (1 << VFLIP_IDX) | | ||
| 337 | (1 << FREQ_IDX), | ||
| 338 | |||
| 339 | [SENSOR_SP80708] = (1 << AUTOGAIN_IDX) | | ||
| 340 | (1 << INFRARED_IDX) | | ||
| 341 | (1 << VFLIP_IDX) | | ||
| 342 | (1 << FREQ_IDX), | ||
| 307 | }; | 343 | }; |
| 308 | 344 | ||
| 309 | static const struct v4l2_pix_format cif_mode[] = { | 345 | static const struct v4l2_pix_format cif_mode[] = { |
| @@ -343,7 +379,17 @@ static const u8 sn_adcm1700[0x1c] = { | |||
| 343 | 0x06, 0x00, 0x00, 0x00 | 379 | 0x06, 0x00, 0x00, 0x00 |
| 344 | }; | 380 | }; |
| 345 | 381 | ||
| 346 | /*Data from sn9c102p+hv7131r */ | 382 | static const u8 sn_gc0307[0x1c] = { |
| 383 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ | ||
| 384 | 0x00, 0x61, 0x62, 0x00, 0x1a, 0x00, 0x00, 0x00, | ||
| 385 | /* reg8 reg9 rega regb regc regd rege regf */ | ||
| 386 | 0x80, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
| 387 | /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ | ||
| 388 | 0x03, 0x00, 0x03, 0x01, 0x08, 0x28, 0x1e, 0x02, | ||
| 389 | /* reg18 reg19 reg1a reg1b */ | ||
| 390 | 0x06, 0x00, 0x00, 0x00 | ||
| 391 | }; | ||
| 392 | |||
| 347 | static const u8 sn_hv7131[0x1c] = { | 393 | static const u8 sn_hv7131[0x1c] = { |
| 348 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ | 394 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ |
| 349 | 0x00, 0x03, 0x64, 0x00, 0x1a, 0x20, 0x20, 0x20, | 395 | 0x00, 0x03, 0x64, 0x00, 0x1a, 0x20, 0x20, 0x20, |
| @@ -401,7 +447,7 @@ static const u8 sn_om6802[0x1c] = { | |||
| 401 | 447 | ||
| 402 | static const u8 sn_ov7630[0x1c] = { | 448 | static const u8 sn_ov7630[0x1c] = { |
| 403 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ | 449 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ |
| 404 | 0x00, 0x21, 0x40, 0x00, 0x1a, 0x20, 0x1f, 0x20, | 450 | 0x00, 0x21, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00, |
| 405 | /* reg8 reg9 rega regb regc regd rege regf */ | 451 | /* reg8 reg9 rega regb regc regd rege regf */ |
| 406 | 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 452 | 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 407 | /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ | 453 | /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ |
| @@ -443,6 +489,28 @@ static const u8 sn_po1030[0x1c] = { | |||
| 443 | 0x07, 0x00, 0x00, 0x00 | 489 | 0x07, 0x00, 0x00, 0x00 |
| 444 | }; | 490 | }; |
| 445 | 491 | ||
| 492 | static const u8 sn_po2030n[0x1c] = { | ||
| 493 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ | ||
| 494 | 0x00, 0x63, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00, | ||
| 495 | /* reg8 reg9 rega regb regc regd rege regf */ | ||
| 496 | 0x81, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
| 497 | /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ | ||
| 498 | 0x03, 0x00, 0x00, 0x01, 0x14, 0x28, 0x1e, 0x00, | ||
| 499 | /* reg18 reg19 reg1a reg1b */ | ||
| 500 | 0x07, 0x00, 0x00, 0x00 | ||
| 501 | }; | ||
| 502 | |||
| 503 | static const u8 sn_soi768[0x1c] = { | ||
| 504 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ | ||
| 505 | 0x00, 0x21, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00, | ||
| 506 | /* reg8 reg9 rega regb regc regd rege regf */ | ||
| 507 | 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
| 508 | /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ | ||
| 509 | 0x03, 0x00, 0x00, 0x01, 0x08, 0x28, 0x1e, 0x00, | ||
| 510 | /* reg18 reg19 reg1a reg1b */ | ||
| 511 | 0x07, 0x00, 0x00, 0x00 | ||
| 512 | }; | ||
| 513 | |||
| 446 | static const u8 sn_sp80708[0x1c] = { | 514 | static const u8 sn_sp80708[0x1c] = { |
| 447 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ | 515 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ |
| 448 | 0x00, 0x63, 0x60, 0x00, 0x1a, 0x20, 0x20, 0x20, | 516 | 0x00, 0x63, 0x60, 0x00, 0x1a, 0x20, 0x20, 0x20, |
| @@ -456,17 +524,20 @@ static const u8 sn_sp80708[0x1c] = { | |||
| 456 | 524 | ||
| 457 | /* sequence specific to the sensors - !! index = SENSOR_xxx */ | 525 | /* sequence specific to the sensors - !! index = SENSOR_xxx */ |
| 458 | static const u8 *sn_tb[] = { | 526 | static const u8 *sn_tb[] = { |
| 459 | sn_adcm1700, | 527 | [SENSOR_ADCM1700] = sn_adcm1700, |
| 460 | sn_hv7131, | 528 | [SENSOR_GC0307] = sn_gc0307, |
| 461 | sn_mi0360, | 529 | [SENSOR_HV7131R] = sn_hv7131, |
| 462 | sn_mo4000, | 530 | [SENSOR_MI0360] = sn_mi0360, |
| 463 | sn_mt9v111, | 531 | [SENSOR_MO4000] = sn_mo4000, |
| 464 | sn_om6802, | 532 | [SENSOR_MT9V111] = sn_mt9v111, |
| 465 | sn_ov7630, | 533 | [SENSOR_OM6802] = sn_om6802, |
| 466 | sn_ov7648, | 534 | [SENSOR_OV7630] = sn_ov7630, |
| 467 | sn_ov7660, | 535 | [SENSOR_OV7648] = sn_ov7648, |
| 468 | sn_po1030, | 536 | [SENSOR_OV7660] = sn_ov7660, |
| 469 | sn_sp80708 | 537 | [SENSOR_PO1030] = sn_po1030, |
| 538 | [SENSOR_PO2030N] = sn_po2030n, | ||
| 539 | [SENSOR_SOI768] = sn_soi768, | ||
| 540 | [SENSOR_SP80708] = sn_sp80708, | ||
| 470 | }; | 541 | }; |
| 471 | 542 | ||
| 472 | /* default gamma table */ | 543 | /* default gamma table */ |
| @@ -484,8 +555,13 @@ static const u8 gamma_spec_1[17] = { | |||
| 484 | 0x08, 0x3a, 0x52, 0x65, 0x75, 0x83, 0x91, 0x9d, | 555 | 0x08, 0x3a, 0x52, 0x65, 0x75, 0x83, 0x91, 0x9d, |
| 485 | 0xa9, 0xb4, 0xbe, 0xc8, 0xd2, 0xdb, 0xe4, 0xed, 0xf5 | 556 | 0xa9, 0xb4, 0xbe, 0xc8, 0xd2, 0xdb, 0xe4, 0xed, 0xf5 |
| 486 | }; | 557 | }; |
| 487 | /* gamma for sensor SP80708 */ | 558 | /* gamma for sensor GC0307 */ |
| 488 | static const u8 gamma_spec_2[17] = { | 559 | static const u8 gamma_spec_2[17] = { |
| 560 | 0x14, 0x37, 0x50, 0x6a, 0x7c, 0x8d, 0x9d, 0xab, | ||
| 561 | 0xb5, 0xbf, 0xc2, 0xcb, 0xd1, 0xd6, 0xdb, 0xe1, 0xeb | ||
| 562 | }; | ||
| 563 | /* gamma for sensor SP80708 */ | ||
| 564 | static const u8 gamma_spec_3[17] = { | ||
| 489 | 0x0a, 0x2d, 0x4e, 0x68, 0x7d, 0x8f, 0x9f, 0xab, | 565 | 0x0a, 0x2d, 0x4e, 0x68, 0x7d, 0x8f, 0x9f, 0xab, |
| 490 | 0xb7, 0xc2, 0xcc, 0xd3, 0xd8, 0xde, 0xe2, 0xe5, 0xe6 | 566 | 0xb7, 0xc2, 0xcc, 0xd3, 0xd8, 0xde, 0xe2, 0xe5, 0xe6 |
| 491 | }; | 567 | }; |
| @@ -533,6 +609,58 @@ static const u8 adcm1700_sensor_param1[][8] = { | |||
| 533 | {0xb0, 0x51, 0x32, 0x00, 0xa2, 0x00, 0x00, 0x10}, | 609 | {0xb0, 0x51, 0x32, 0x00, 0xa2, 0x00, 0x00, 0x10}, |
| 534 | {} | 610 | {} |
| 535 | }; | 611 | }; |
| 612 | static const u8 gc0307_sensor_init[][8] = { | ||
| 613 | {0xa0, 0x21, 0x43, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
| 614 | {0xa0, 0x21, 0x44, 0xa2, 0x00, 0x00, 0x00, 0x10}, | ||
| 615 | {0xa0, 0x21, 0x01, 0x6a, 0x00, 0x00, 0x00, 0x10}, | ||
| 616 | {0xa0, 0x21, 0x02, 0x70, 0x00, 0x00, 0x00, 0x10}, | ||
| 617 | {0xa0, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
| 618 | {0xa0, 0x21, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
| 619 | {0xa0, 0x21, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
| 620 | {0xa0, 0x21, 0x11, 0x05, 0x00, 0x00, 0x00, 0x10}, | ||
| 621 | {0xa0, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
| 622 | {0xa0, 0x21, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
| 623 | {0xa0, 0x21, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
| 624 | {0xa0, 0x21, 0x08, 0x02, 0x00, 0x00, 0x00, 0x10}, | ||
| 625 | {0xa0, 0x21, 0x09, 0x01, 0x00, 0x00, 0x00, 0x10}, | ||
| 626 | {0xa0, 0x21, 0x0a, 0xe8, 0x00, 0x00, 0x00, 0x10}, | ||
| 627 | {0xa0, 0x21, 0x0b, 0x02, 0x00, 0x00, 0x00, 0x10}, | ||
| 628 | {0xa0, 0x21, 0x0c, 0x80, 0x00, 0x00, 0x00, 0x10}, | ||
| 629 | {0xa0, 0x21, 0x0d, 0x22, 0x00, 0x00, 0x00, 0x10}, | ||
| 630 | {0xa0, 0x21, 0x0e, 0x02, 0x00, 0x00, 0x00, 0x10}, | ||
| 631 | {0xa0, 0x21, 0x0f, 0xb2, 0x00, 0x00, 0x00, 0x10}, | ||
| 632 | {0xa0, 0x21, 0x12, 0x70, 0x00, 0x00, 0x00, 0x10}, | ||
| 633 | {0xdd, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*delay 10ms*/ | ||
| 634 | {0xa0, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
| 635 | {0xa0, 0x21, 0x15, 0xb8, 0x00, 0x00, 0x00, 0x10}, | ||
| 636 | {0xa0, 0x21, 0x16, 0x13, 0x00, 0x00, 0x00, 0x10}, | ||
| 637 | {0xa0, 0x21, 0x17, 0x52, 0x00, 0x00, 0x00, 0x10}, | ||
| 638 | {0xa0, 0x21, 0x18, 0x50, 0x00, 0x00, 0x00, 0x10}, | ||
| 639 | {0xa0, 0x21, 0x1e, 0x0d, 0x00, 0x00, 0x00, 0x10}, | ||
| 640 | {0xa0, 0x21, 0x1f, 0x32, 0x00, 0x00, 0x00, 0x10}, | ||
| 641 | {0xa0, 0x21, 0x61, 0x90, 0x00, 0x00, 0x00, 0x10}, | ||
| 642 | {0xa0, 0x21, 0x63, 0x70, 0x00, 0x00, 0x00, 0x10}, | ||
| 643 | {0xa0, 0x21, 0x65, 0x98, 0x00, 0x00, 0x00, 0x10}, | ||
| 644 | {0xa0, 0x21, 0x67, 0x90, 0x00, 0x00, 0x00, 0x10}, | ||
| 645 | {0xa0, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
| 646 | {0xa0, 0x21, 0x04, 0x96, 0x00, 0x00, 0x00, 0x10}, | ||
| 647 | {0xa0, 0x21, 0x45, 0x27, 0x00, 0x00, 0x00, 0x10}, | ||
| 648 | {0xa0, 0x21, 0x47, 0x2c, 0x00, 0x00, 0x00, 0x10}, | ||
| 649 | {0xa0, 0x21, 0x43, 0x47, 0x00, 0x00, 0x00, 0x10}, | ||
| 650 | {0xa0, 0x21, 0x44, 0xd8, 0x00, 0x00, 0x00, 0x10}, | ||
| 651 | {} | ||
| 652 | }; | ||
| 653 | static const u8 gc0307_sensor_param1[][8] = { | ||
| 654 | {0xa0, 0x21, 0x68, 0x13, 0x00, 0x00, 0x00, 0x10}, | ||
| 655 | {0xd0, 0x21, 0x61, 0x80, 0x00, 0x80, 0x00, 0x10}, | ||
| 656 | {0xc0, 0x21, 0x65, 0x80, 0x00, 0x80, 0x00, 0x10}, | ||
| 657 | {0xc0, 0x21, 0x63, 0xa0, 0x00, 0xa6, 0x00, 0x10}, | ||
| 658 | /*param3*/ | ||
| 659 | {0xa0, 0x21, 0x01, 0x6e, 0x00, 0x00, 0x00, 0x10}, | ||
| 660 | {0xa0, 0x21, 0x02, 0x88, 0x00, 0x00, 0x00, 0x10}, | ||
| 661 | {} | ||
| 662 | }; | ||
| 663 | |||
| 536 | static const u8 hv7131r_sensor_init[][8] = { | 664 | static const u8 hv7131r_sensor_init[][8] = { |
| 537 | {0xc1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10}, | 665 | {0xc1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10}, |
| 538 | {0xb1, 0x11, 0x34, 0x17, 0x7f, 0x00, 0x00, 0x10}, | 666 | {0xb1, 0x11, 0x34, 0x17, 0x7f, 0x00, 0x00, 0x10}, |
| @@ -767,7 +895,9 @@ static const u8 ov7630_sensor_init[][8] = { | |||
| 767 | {0xc1, 0x21, 0x7b, 0x00, 0x4c, 0xf7, 0x00, 0x10}, | 895 | {0xc1, 0x21, 0x7b, 0x00, 0x4c, 0xf7, 0x00, 0x10}, |
| 768 | {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10}, | 896 | {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10}, |
| 769 | {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10}, | 897 | {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10}, |
| 770 | /* */ | 898 | {} |
| 899 | }; | ||
| 900 | static const u8 ov7630_sensor_param1[][8] = { | ||
| 771 | {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10}, | 901 | {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10}, |
| 772 | {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10}, | 902 | {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10}, |
| 773 | /*fixme: + 0x12, 0x04*/ | 903 | /*fixme: + 0x12, 0x04*/ |
| @@ -984,6 +1114,113 @@ static const u8 po1030_sensor_param1[][8] = { | |||
| 984 | {} | 1114 | {} |
| 985 | }; | 1115 | }; |
| 986 | 1116 | ||
| 1117 | static const u8 po2030n_sensor_init[][8] = { | ||
| 1118 | {0xa1, 0x6e, 0x1e, 0x1a, 0x00, 0x00, 0x00, 0x10}, | ||
| 1119 | {0xa1, 0x6e, 0x1f, 0x99, 0x00, 0x00, 0x00, 0x10}, | ||
| 1120 | {0xdd, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 10ms */ | ||
| 1121 | {0xa1, 0x6e, 0x1e, 0x0a, 0x00, 0x00, 0x00, 0x10}, | ||
| 1122 | {0xa1, 0x6e, 0x1f, 0x19, 0x00, 0x00, 0x00, 0x10}, | ||
| 1123 | {0xdd, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 10ms */ | ||
| 1124 | {0xa1, 0x6e, 0x20, 0x44, 0x00, 0x00, 0x00, 0x10}, | ||
| 1125 | {0xa1, 0x6e, 0x04, 0x03, 0x00, 0x00, 0x00, 0x10}, | ||
| 1126 | {0xa1, 0x6e, 0x05, 0x70, 0x00, 0x00, 0x00, 0x10}, | ||
| 1127 | {0xa1, 0x6e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10}, | ||
| 1128 | {0xa1, 0x6e, 0x07, 0x25, 0x00, 0x00, 0x00, 0x10}, | ||
| 1129 | {0xd1, 0x6e, 0x08, 0x00, 0xd0, 0x00, 0x08, 0x10}, | ||
| 1130 | {0xd1, 0x6e, 0x0c, 0x03, 0x50, 0x01, 0xe8, 0x10}, | ||
| 1131 | {0xd1, 0x6e, 0x1d, 0x20, 0x0a, 0x19, 0x44, 0x10}, | ||
| 1132 | {0xd1, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
| 1133 | {0xd1, 0x6e, 0x25, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
| 1134 | {0xd1, 0x6e, 0x29, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
| 1135 | {0xd1, 0x6e, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
| 1136 | {0xd1, 0x6e, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
| 1137 | {0xd1, 0x6e, 0x35, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
| 1138 | {0xd1, 0x6e, 0x39, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
| 1139 | {0xd1, 0x6e, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
| 1140 | {0xd1, 0x6e, 0x41, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
| 1141 | {0xd1, 0x6e, 0x45, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
| 1142 | {0xd1, 0x6e, 0x49, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
| 1143 | {0xd1, 0x6e, 0x4d, 0x00, 0x00, 0x00, 0xed, 0x10}, | ||
| 1144 | {0xd1, 0x6e, 0x51, 0x17, 0x4a, 0x2f, 0xc0, 0x10}, | ||
| 1145 | {0xd1, 0x6e, 0x55, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
| 1146 | {0xd1, 0x6e, 0x59, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
| 1147 | {0xd1, 0x6e, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
| 1148 | {0xd1, 0x6e, 0x61, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
| 1149 | {0xd1, 0x6e, 0x65, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
| 1150 | {0xd1, 0x6e, 0x69, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
| 1151 | {0xd1, 0x6e, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
| 1152 | {0xd1, 0x6e, 0x71, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
| 1153 | {0xd1, 0x6e, 0x75, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
| 1154 | {0xd1, 0x6e, 0x79, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
| 1155 | {0xd1, 0x6e, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
| 1156 | {0xd1, 0x6e, 0x81, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
| 1157 | {0xd1, 0x6e, 0x85, 0x00, 0x00, 0x00, 0x08, 0x10}, | ||
| 1158 | {0xd1, 0x6e, 0x89, 0x01, 0xe8, 0x00, 0x01, 0x10}, | ||
| 1159 | {0xa1, 0x6e, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
| 1160 | {0xd1, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
| 1161 | {0xd1, 0x6e, 0x25, 0x00, 0x00, 0x00, 0x01, 0x10}, | ||
| 1162 | {0xd1, 0x6e, 0x29, 0xe6, 0x00, 0xbd, 0x03, 0x10}, | ||
| 1163 | {0xd1, 0x6e, 0x2d, 0x41, 0x38, 0x68, 0x40, 0x10}, | ||
| 1164 | {0xd1, 0x6e, 0x31, 0x2b, 0x00, 0x36, 0x00, 0x10}, | ||
| 1165 | {0xd1, 0x6e, 0x35, 0x30, 0x30, 0x08, 0x00, 0x10}, | ||
| 1166 | {0xd1, 0x6e, 0x39, 0x00, 0x00, 0x33, 0x06, 0x10}, | ||
| 1167 | {0xb1, 0x6e, 0x3d, 0x06, 0x02, 0x00, 0x00, 0x10}, | ||
| 1168 | {} | ||
| 1169 | }; | ||
| 1170 | static const u8 po2030n_sensor_param1[][8] = { | ||
| 1171 | {0xa1, 0x6e, 0x1a, 0x01, 0x00, 0x00, 0x00, 0x10}, | ||
| 1172 | {0xdd, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 8ms */ | ||
| 1173 | {0xa1, 0x6e, 0x1b, 0xf4, 0x00, 0x00, 0x00, 0x10}, | ||
| 1174 | {0xa1, 0x6e, 0x15, 0x04, 0x00, 0x00, 0x00, 0x10}, | ||
| 1175 | {0xd1, 0x6e, 0x16, 0x50, 0x40, 0x49, 0x40, 0x10}, | ||
| 1176 | /*param2*/ | ||
| 1177 | {0xa1, 0x6e, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
| 1178 | {0xa1, 0x6e, 0x04, 0x03, 0x00, 0x00, 0x00, 0x10}, | ||
| 1179 | {0xa1, 0x6e, 0x05, 0x6f, 0x00, 0x00, 0x00, 0x10}, | ||
| 1180 | {0xa1, 0x6e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10}, | ||
| 1181 | {0xa1, 0x6e, 0x07, 0x25, 0x00, 0x00, 0x00, 0x10}, | ||
| 1182 | {0xa1, 0x6e, 0x15, 0x04, 0x00, 0x00, 0x00, 0x10}, | ||
| 1183 | {0xc1, 0x6e, 0x16, 0x52, 0x40, 0x48, 0x00, 0x10}, | ||
| 1184 | /*after start*/ | ||
| 1185 | {0xa1, 0x6e, 0x15, 0x0f, 0x00, 0x00, 0x00, 0x10}, | ||
| 1186 | {0xdd, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 5ms */ | ||
| 1187 | {0xa1, 0x6e, 0x1a, 0x05, 0x00, 0x00, 0x00, 0x10}, | ||
| 1188 | {0xdd, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 5ms */ | ||
| 1189 | {0xa1, 0x6e, 0x1b, 0x53, 0x00, 0x00, 0x00, 0x10}, | ||
| 1190 | {} | ||
| 1191 | }; | ||
| 1192 | |||
| 1193 | static const u8 soi768_sensor_init[][8] = { | ||
| 1194 | {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */ | ||
| 1195 | {0xdd, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 96ms */ | ||
| 1196 | {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
| 1197 | {0xa1, 0x21, 0x13, 0x80, 0x00, 0x00, 0x00, 0x10}, | ||
| 1198 | {0xa1, 0x21, 0x0f, 0x03, 0x00, 0x00, 0x00, 0x10}, | ||
| 1199 | {0xa1, 0x21, 0x19, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
| 1200 | {} | ||
| 1201 | }; | ||
| 1202 | static const u8 soi768_sensor_param1[][8] = { | ||
| 1203 | {0xa1, 0x21, 0x10, 0x10, 0x00, 0x00, 0x00, 0x10}, | ||
| 1204 | {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
| 1205 | {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
| 1206 | {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
| 1207 | {0xb1, 0x21, 0x01, 0x7f, 0x7f, 0x00, 0x00, 0x10}, | ||
| 1208 | /* */ | ||
| 1209 | /* {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, */ | ||
| 1210 | /* {0xa1, 0x21, 0x2d, 0x25, 0x00, 0x00, 0x00, 0x10}, */ | ||
| 1211 | {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
| 1212 | /* {0xb1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, */ | ||
| 1213 | {0xa1, 0x21, 0x02, 0x8d, 0x00, 0x00, 0x00, 0x10}, | ||
| 1214 | /* the next sequence should be used for auto gain */ | ||
| 1215 | {0xa1, 0x21, 0x00, 0x07, 0x00, 0x00, 0x00, 0x10}, | ||
| 1216 | /* global gain ? : 07 - change with 0x15 at the end */ | ||
| 1217 | {0xa1, 0x21, 0x10, 0x3f, 0x00, 0x00, 0x00, 0x10}, /* ???? : 063f */ | ||
| 1218 | {0xa1, 0x21, 0x04, 0x06, 0x00, 0x00, 0x00, 0x10}, | ||
| 1219 | {0xb1, 0x21, 0x2d, 0x00, 0x02, 0x00, 0x00, 0x10}, | ||
| 1220 | /* exposure ? : 0200 - change with 0x1e at the end */ | ||
| 1221 | {} | ||
| 1222 | }; | ||
| 1223 | |||
| 987 | static const u8 sp80708_sensor_init[][8] = { | 1224 | static const u8 sp80708_sensor_init[][8] = { |
| 988 | {0xa1, 0x18, 0x06, 0xf9, 0x00, 0x00, 0x00, 0x10}, | 1225 | {0xa1, 0x18, 0x06, 0xf9, 0x00, 0x00, 0x00, 0x10}, |
| 989 | {0xa1, 0x18, 0x09, 0x1f, 0x00, 0x00, 0x00, 0x10}, | 1226 | {0xa1, 0x18, 0x09, 0x1f, 0x00, 0x00, 0x00, 0x10}, |
| @@ -1069,18 +1306,21 @@ static const u8 sp80708_sensor_param1[][8] = { | |||
| 1069 | {} | 1306 | {} |
| 1070 | }; | 1307 | }; |
| 1071 | 1308 | ||
| 1072 | static const u8 (*sensor_init[11])[8] = { | 1309 | static const u8 (*sensor_init[])[8] = { |
| 1073 | adcm1700_sensor_init, /* ADCM1700 0 */ | 1310 | [SENSOR_ADCM1700] = adcm1700_sensor_init, |
| 1074 | hv7131r_sensor_init, /* HV7131R 1 */ | 1311 | [SENSOR_GC0307] = gc0307_sensor_init, |
| 1075 | mi0360_sensor_init, /* MI0360 2 */ | 1312 | [SENSOR_HV7131R] = hv7131r_sensor_init, |
| 1076 | mo4000_sensor_init, /* MO4000 3 */ | 1313 | [SENSOR_MI0360] = mi0360_sensor_init, |
| 1077 | mt9v111_sensor_init, /* MT9V111 4 */ | 1314 | [SENSOR_MO4000] = mo4000_sensor_init, |
| 1078 | om6802_sensor_init, /* OM6802 5 */ | 1315 | [SENSOR_MT9V111] = mt9v111_sensor_init, |
| 1079 | ov7630_sensor_init, /* OV7630 6 */ | 1316 | [SENSOR_OM6802] = om6802_sensor_init, |
| 1080 | ov7648_sensor_init, /* OV7648 7 */ | 1317 | [SENSOR_OV7630] = ov7630_sensor_init, |
| 1081 | ov7660_sensor_init, /* OV7660 8 */ | 1318 | [SENSOR_OV7648] = ov7648_sensor_init, |
| 1082 | po1030_sensor_init, /* PO1030 9 */ | 1319 | [SENSOR_OV7660] = ov7660_sensor_init, |
| 1083 | sp80708_sensor_init, /* SP80708 10 */ | 1320 | [SENSOR_PO1030] = po1030_sensor_init, |
| 1321 | [SENSOR_PO2030N] = po2030n_sensor_init, | ||
| 1322 | [SENSOR_SOI768] = soi768_sensor_init, | ||
| 1323 | [SENSOR_SP80708] = sp80708_sensor_init, | ||
| 1084 | }; | 1324 | }; |
| 1085 | 1325 | ||
| 1086 | /* read <len> bytes to gspca_dev->usb_buf */ | 1326 | /* read <len> bytes to gspca_dev->usb_buf */ |
| @@ -1146,10 +1386,11 @@ static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val) | |||
| 1146 | { | 1386 | { |
| 1147 | struct sd *sd = (struct sd *) gspca_dev; | 1387 | struct sd *sd = (struct sd *) gspca_dev; |
| 1148 | 1388 | ||
| 1149 | PDEBUG(D_USBO, "i2c_w2 [%02x] = %02x", reg, val); | 1389 | PDEBUG(D_USBO, "i2c_w1 [%02x] = %02x", reg, val); |
| 1150 | switch (sd->sensor) { | 1390 | switch (sd->sensor) { |
| 1151 | case SENSOR_ADCM1700: | 1391 | case SENSOR_ADCM1700: |
| 1152 | case SENSOR_OM6802: /* i2c command = a0 (100 kHz) */ | 1392 | case SENSOR_OM6802: |
| 1393 | case SENSOR_GC0307: /* i2c command = a0 (100 kHz) */ | ||
| 1153 | gspca_dev->usb_buf[0] = 0x80 | (2 << 4); | 1394 | gspca_dev->usb_buf[0] = 0x80 | (2 << 4); |
| 1154 | break; | 1395 | break; |
| 1155 | default: /* i2c command = a1 (400 kHz) */ | 1396 | default: /* i2c command = a1 (400 kHz) */ |
| @@ -1177,6 +1418,8 @@ static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val) | |||
| 1177 | static void i2c_w8(struct gspca_dev *gspca_dev, | 1418 | static void i2c_w8(struct gspca_dev *gspca_dev, |
| 1178 | const u8 *buffer) | 1419 | const u8 *buffer) |
| 1179 | { | 1420 | { |
| 1421 | PDEBUG(D_USBO, "i2c_w8 [%02x] = %02x ..", | ||
| 1422 | buffer[2], buffer[3]); | ||
| 1180 | memcpy(gspca_dev->usb_buf, buffer, 8); | 1423 | memcpy(gspca_dev->usb_buf, buffer, 8); |
| 1181 | usb_control_msg(gspca_dev->dev, | 1424 | usb_control_msg(gspca_dev->dev, |
| 1182 | usb_sndctrlpipe(gspca_dev->dev, 0), | 1425 | usb_sndctrlpipe(gspca_dev->dev, 0), |
| @@ -1196,7 +1439,8 @@ static void i2c_r(struct gspca_dev *gspca_dev, u8 reg, int len) | |||
| 1196 | 1439 | ||
| 1197 | switch (sd->sensor) { | 1440 | switch (sd->sensor) { |
| 1198 | case SENSOR_ADCM1700: | 1441 | case SENSOR_ADCM1700: |
| 1199 | case SENSOR_OM6802: /* i2c command = 90 (100 kHz) */ | 1442 | case SENSOR_OM6802: |
| 1443 | case SENSOR_GC0307: /* i2c command = a0 (100 kHz) */ | ||
| 1200 | mode[0] = 0x80 | 0x10; | 1444 | mode[0] = 0x80 | 0x10; |
| 1201 | break; | 1445 | break; |
| 1202 | default: /* i2c command = 91 (400 kHz) */ | 1446 | default: /* i2c command = 91 (400 kHz) */ |
| @@ -1300,39 +1544,100 @@ static void mi0360_probe(struct gspca_dev *gspca_dev) | |||
| 1300 | } | 1544 | } |
| 1301 | } | 1545 | } |
| 1302 | 1546 | ||
| 1303 | static void ov7648_probe(struct gspca_dev *gspca_dev) | 1547 | static void ov7630_probe(struct gspca_dev *gspca_dev) |
| 1304 | { | 1548 | { |
| 1305 | struct sd *sd = (struct sd *) gspca_dev; | 1549 | struct sd *sd = (struct sd *) gspca_dev; |
| 1550 | u16 val; | ||
| 1306 | 1551 | ||
| 1307 | /* check ov76xx */ | 1552 | /* check ov76xx */ |
| 1308 | reg_w1(gspca_dev, 0x17, 0x62); | 1553 | reg_w1(gspca_dev, 0x17, 0x62); |
| 1309 | reg_w1(gspca_dev, 0x01, 0x08); | 1554 | reg_w1(gspca_dev, 0x01, 0x08); |
| 1310 | sd->i2c_addr = 0x21; | 1555 | sd->i2c_addr = 0x21; |
| 1311 | i2c_r(gspca_dev, 0x0a, 2); | 1556 | i2c_r(gspca_dev, 0x0a, 2); |
| 1312 | if (gspca_dev->usb_buf[3] == 0x76) { /* ov76xx */ | 1557 | val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4]; |
| 1313 | PDEBUG(D_PROBE, "Sensor ov%02x%02x", | 1558 | reg_w1(gspca_dev, 0x01, 0x29); |
| 1314 | gspca_dev->usb_buf[3], gspca_dev->usb_buf[4]); | 1559 | reg_w1(gspca_dev, 0x17, 0x42); |
| 1560 | if (val == 0x7628) { /* soi768 */ | ||
| 1561 | sd->sensor = SENSOR_SOI768; | ||
| 1562 | /*fixme: only valid for 0c45:613e?*/ | ||
| 1563 | gspca_dev->cam.input_flags = | ||
| 1564 | V4L2_IN_ST_VFLIP | V4L2_IN_ST_HFLIP; | ||
| 1565 | PDEBUG(D_PROBE, "Sensor soi768"); | ||
| 1315 | return; | 1566 | return; |
| 1316 | } | 1567 | } |
| 1568 | PDEBUG(D_PROBE, "Sensor ov%04x", val); | ||
| 1569 | } | ||
| 1317 | 1570 | ||
| 1318 | /* reset */ | 1571 | static void ov7648_probe(struct gspca_dev *gspca_dev) |
| 1572 | { | ||
| 1573 | struct sd *sd = (struct sd *) gspca_dev; | ||
| 1574 | u16 val; | ||
| 1575 | |||
| 1576 | /* check ov76xx */ | ||
| 1577 | reg_w1(gspca_dev, 0x17, 0x62); | ||
| 1578 | reg_w1(gspca_dev, 0x01, 0x08); | ||
| 1579 | sd->i2c_addr = 0x21; | ||
| 1580 | i2c_r(gspca_dev, 0x0a, 2); | ||
| 1581 | val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4]; | ||
| 1319 | reg_w1(gspca_dev, 0x01, 0x29); | 1582 | reg_w1(gspca_dev, 0x01, 0x29); |
| 1320 | reg_w1(gspca_dev, 0x17, 0x42); | 1583 | reg_w1(gspca_dev, 0x17, 0x42); |
| 1584 | if ((val & 0xff00) == 0x7600) { /* ov76xx */ | ||
| 1585 | PDEBUG(D_PROBE, "Sensor ov%04x", val); | ||
| 1586 | return; | ||
| 1587 | } | ||
| 1321 | 1588 | ||
| 1322 | /* check po1030 */ | 1589 | /* check po1030 */ |
| 1323 | reg_w1(gspca_dev, 0x17, 0x62); | 1590 | reg_w1(gspca_dev, 0x17, 0x62); |
| 1324 | reg_w1(gspca_dev, 0x01, 0x08); | 1591 | reg_w1(gspca_dev, 0x01, 0x08); |
| 1325 | sd->i2c_addr = 0x6e; | 1592 | sd->i2c_addr = 0x6e; |
| 1326 | i2c_r(gspca_dev, 0x00, 2); | 1593 | i2c_r(gspca_dev, 0x00, 2); |
| 1327 | if (gspca_dev->usb_buf[3] == 0x10 /* po1030 */ | 1594 | val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4]; |
| 1328 | && gspca_dev->usb_buf[4] == 0x30) { | 1595 | reg_w1(gspca_dev, 0x01, 0x29); |
| 1596 | reg_w1(gspca_dev, 0x17, 0x42); | ||
| 1597 | if (val == 0x1030) { /* po1030 */ | ||
| 1329 | PDEBUG(D_PROBE, "Sensor po1030"); | 1598 | PDEBUG(D_PROBE, "Sensor po1030"); |
| 1330 | sd->sensor = SENSOR_PO1030; | 1599 | sd->sensor = SENSOR_PO1030; |
| 1331 | return; | 1600 | return; |
| 1332 | } | 1601 | } |
| 1333 | 1602 | ||
| 1334 | PDEBUG(D_PROBE, "Unknown sensor %02x%02x", | 1603 | PDEBUG(D_PROBE, "Unknown sensor %04x", val); |
| 1335 | gspca_dev->usb_buf[3], gspca_dev->usb_buf[4]); | 1604 | } |
| 1605 | |||
| 1606 | /* 0c45:6142 sensor may be po2030n, gc0305 or gc0307 */ | ||
| 1607 | static void po2030n_probe(struct gspca_dev *gspca_dev) | ||
| 1608 | { | ||
| 1609 | struct sd *sd = (struct sd *) gspca_dev; | ||
| 1610 | u16 val; | ||
| 1611 | |||
| 1612 | /* check gc0307 */ | ||
| 1613 | reg_w1(gspca_dev, 0x17, 0x62); | ||
| 1614 | reg_w1(gspca_dev, 0x01, 0x08); | ||
| 1615 | reg_w1(gspca_dev, 0x02, 0x22); | ||
| 1616 | sd->i2c_addr = 0x21; | ||
| 1617 | i2c_r(gspca_dev, 0x00, 1); | ||
| 1618 | val = gspca_dev->usb_buf[4]; | ||
| 1619 | reg_w1(gspca_dev, 0x01, 0x29); /* reset */ | ||
| 1620 | reg_w1(gspca_dev, 0x17, 0x42); | ||
| 1621 | if (val == 0x99) { /* gc0307 (?) */ | ||
| 1622 | PDEBUG(D_PROBE, "Sensor gc0307"); | ||
| 1623 | sd->sensor = SENSOR_GC0307; | ||
| 1624 | return; | ||
| 1625 | } | ||
| 1626 | |||
| 1627 | /* check po2030n */ | ||
| 1628 | reg_w1(gspca_dev, 0x17, 0x62); | ||
| 1629 | reg_w1(gspca_dev, 0x01, 0x0a); | ||
| 1630 | sd->i2c_addr = 0x6e; | ||
| 1631 | i2c_r(gspca_dev, 0x00, 2); | ||
| 1632 | val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4]; | ||
| 1633 | reg_w1(gspca_dev, 0x01, 0x29); | ||
| 1634 | reg_w1(gspca_dev, 0x17, 0x42); | ||
| 1635 | if (val == 0x2030) { | ||
| 1636 | PDEBUG(D_PROBE, "Sensor po2030n"); | ||
| 1637 | /* sd->sensor = SENSOR_PO2030N; */ | ||
| 1638 | } else { | ||
| 1639 | PDEBUG(D_PROBE, "Unknown sensor ID %04x", val); | ||
| 1640 | } | ||
| 1336 | } | 1641 | } |
| 1337 | 1642 | ||
| 1338 | static void bridge_init(struct gspca_dev *gspca_dev, | 1643 | static void bridge_init(struct gspca_dev *gspca_dev, |
| @@ -1355,8 +1660,11 @@ static void bridge_init(struct gspca_dev *gspca_dev, | |||
| 1355 | reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2); | 1660 | reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2); |
| 1356 | reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); | 1661 | reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); |
| 1357 | switch (sd->sensor) { | 1662 | switch (sd->sensor) { |
| 1663 | case SENSOR_GC0307: | ||
| 1358 | case SENSOR_OV7660: | 1664 | case SENSOR_OV7660: |
| 1359 | case SENSOR_PO1030: | 1665 | case SENSOR_PO1030: |
| 1666 | case SENSOR_PO2030N: | ||
| 1667 | case SENSOR_SOI768: | ||
| 1360 | case SENSOR_SP80708: | 1668 | case SENSOR_SP80708: |
| 1361 | reg9a = reg9a_spec; | 1669 | reg9a = reg9a_spec; |
| 1362 | break; | 1670 | break; |
| @@ -1377,6 +1685,14 @@ static void bridge_init(struct gspca_dev *gspca_dev, | |||
| 1377 | reg_w1(gspca_dev, 0x01, 0x42); | 1685 | reg_w1(gspca_dev, 0x01, 0x42); |
| 1378 | reg_w1(gspca_dev, 0x01, 0x42); | 1686 | reg_w1(gspca_dev, 0x01, 0x42); |
| 1379 | break; | 1687 | break; |
| 1688 | case SENSOR_GC0307: | ||
| 1689 | msleep(50); | ||
| 1690 | reg_w1(gspca_dev, 0x01, 0x61); | ||
| 1691 | reg_w1(gspca_dev, 0x17, 0x22); | ||
| 1692 | reg_w1(gspca_dev, 0x01, 0x60); | ||
| 1693 | reg_w1(gspca_dev, 0x01, 0x40); | ||
| 1694 | msleep(50); | ||
| 1695 | break; | ||
| 1380 | case SENSOR_MT9V111: | 1696 | case SENSOR_MT9V111: |
| 1381 | reg_w1(gspca_dev, 0x01, 0x61); | 1697 | reg_w1(gspca_dev, 0x01, 0x61); |
| 1382 | reg_w1(gspca_dev, 0x17, 0x61); | 1698 | reg_w1(gspca_dev, 0x17, 0x61); |
| @@ -1414,11 +1730,18 @@ static void bridge_init(struct gspca_dev *gspca_dev, | |||
| 1414 | reg_w1(gspca_dev, 0x01, 0x42); | 1730 | reg_w1(gspca_dev, 0x01, 0x42); |
| 1415 | break; | 1731 | break; |
| 1416 | case SENSOR_PO1030: | 1732 | case SENSOR_PO1030: |
| 1733 | case SENSOR_SOI768: | ||
| 1417 | reg_w1(gspca_dev, 0x01, 0x61); | 1734 | reg_w1(gspca_dev, 0x01, 0x61); |
| 1418 | reg_w1(gspca_dev, 0x17, 0x20); | 1735 | reg_w1(gspca_dev, 0x17, 0x20); |
| 1419 | reg_w1(gspca_dev, 0x01, 0x60); | 1736 | reg_w1(gspca_dev, 0x01, 0x60); |
| 1420 | reg_w1(gspca_dev, 0x01, 0x40); | 1737 | reg_w1(gspca_dev, 0x01, 0x40); |
| 1421 | break; | 1738 | break; |
| 1739 | case SENSOR_PO2030N: | ||
| 1740 | reg_w1(gspca_dev, 0x01, 0x63); | ||
| 1741 | reg_w1(gspca_dev, 0x17, 0x20); | ||
| 1742 | reg_w1(gspca_dev, 0x01, 0x62); | ||
| 1743 | reg_w1(gspca_dev, 0x01, 0x42); | ||
| 1744 | break; | ||
| 1422 | case SENSOR_OV7660: | 1745 | case SENSOR_OV7660: |
| 1423 | /* fall thru */ | 1746 | /* fall thru */ |
| 1424 | case SENSOR_SP80708: | 1747 | case SENSOR_SP80708: |
| @@ -1523,9 +1846,15 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
| 1523 | case SENSOR_MI0360: | 1846 | case SENSOR_MI0360: |
| 1524 | mi0360_probe(gspca_dev); | 1847 | mi0360_probe(gspca_dev); |
| 1525 | break; | 1848 | break; |
| 1849 | case SENSOR_OV7630: | ||
| 1850 | ov7630_probe(gspca_dev); | ||
| 1851 | break; | ||
| 1526 | case SENSOR_OV7648: | 1852 | case SENSOR_OV7648: |
| 1527 | ov7648_probe(gspca_dev); | 1853 | ov7648_probe(gspca_dev); |
| 1528 | break; | 1854 | break; |
| 1855 | case SENSOR_PO2030N: | ||
| 1856 | po2030n_probe(gspca_dev); | ||
| 1857 | break; | ||
| 1529 | } | 1858 | } |
| 1530 | regGpio[1] = 0x70; | 1859 | regGpio[1] = 0x70; |
| 1531 | reg_w(gspca_dev, 0x01, regGpio, 2); | 1860 | reg_w(gspca_dev, 0x01, regGpio, 2); |
| @@ -1558,6 +1887,18 @@ static u32 setexposure(struct gspca_dev *gspca_dev, | |||
| 1558 | struct sd *sd = (struct sd *) gspca_dev; | 1887 | struct sd *sd = (struct sd *) gspca_dev; |
| 1559 | 1888 | ||
| 1560 | switch (sd->sensor) { | 1889 | switch (sd->sensor) { |
| 1890 | case SENSOR_GC0307: { | ||
| 1891 | int a, b; | ||
| 1892 | |||
| 1893 | /* expo = 0..255 -> a = 19..43 */ | ||
| 1894 | a = 19 + expo * 25 / 256; | ||
| 1895 | i2c_w1(gspca_dev, 0x68, a); | ||
| 1896 | a -= 12; | ||
| 1897 | b = a * a * 4; /* heuristic */ | ||
| 1898 | i2c_w1(gspca_dev, 0x03, b >> 8); | ||
| 1899 | i2c_w1(gspca_dev, 0x04, b); | ||
| 1900 | break; | ||
| 1901 | } | ||
| 1561 | case SENSOR_HV7131R: { | 1902 | case SENSOR_HV7131R: { |
| 1562 | u8 Expodoit[] = | 1903 | u8 Expodoit[] = |
| 1563 | { 0xc1, 0x11, 0x25, 0x00, 0x00, 0x00, 0x00, 0x16 }; | 1904 | { 0xc1, 0x11, 0x25, 0x00, 0x00, 0x00, 0x00, 0x16 }; |
| @@ -1668,6 +2009,7 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
| 1668 | expo = sd->brightness >> 4; | 2009 | expo = sd->brightness >> 4; |
| 1669 | sd->exposure = setexposure(gspca_dev, expo); | 2010 | sd->exposure = setexposure(gspca_dev, expo); |
| 1670 | break; | 2011 | break; |
| 2012 | case SENSOR_GC0307: | ||
| 1671 | case SENSOR_MT9V111: | 2013 | case SENSOR_MT9V111: |
| 1672 | expo = sd->brightness >> 8; | 2014 | expo = sd->brightness >> 8; |
| 1673 | sd->exposure = setexposure(gspca_dev, expo); | 2015 | sd->exposure = setexposure(gspca_dev, expo); |
| @@ -1703,7 +2045,7 @@ static void setcolors(struct gspca_dev *gspca_dev) | |||
| 1703 | struct sd *sd = (struct sd *) gspca_dev; | 2045 | struct sd *sd = (struct sd *) gspca_dev; |
| 1704 | int i, v; | 2046 | int i, v; |
| 1705 | u8 reg8a[12]; /* U & V gains */ | 2047 | u8 reg8a[12]; /* U & V gains */ |
| 1706 | static s16 uv[6] = { /* same as reg84 in signed decimal */ | 2048 | static const s16 uv[6] = { /* same as reg84 in signed decimal */ |
| 1707 | -24, -38, 64, /* UR UG UB */ | 2049 | -24, -38, 64, /* UR UG UB */ |
| 1708 | 62, -51, -9 /* VR VG VB */ | 2050 | 62, -51, -9 /* VR VG VB */ |
| 1709 | }; | 2051 | }; |
| @@ -1744,9 +2086,12 @@ static void setgamma(struct gspca_dev *gspca_dev) | |||
| 1744 | case SENSOR_MT9V111: | 2086 | case SENSOR_MT9V111: |
| 1745 | gamma_base = gamma_spec_1; | 2087 | gamma_base = gamma_spec_1; |
| 1746 | break; | 2088 | break; |
| 1747 | case SENSOR_SP80708: | 2089 | case SENSOR_GC0307: |
| 1748 | gamma_base = gamma_spec_2; | 2090 | gamma_base = gamma_spec_2; |
| 1749 | break; | 2091 | break; |
| 2092 | case SENSOR_SP80708: | ||
| 2093 | gamma_base = gamma_spec_3; | ||
| 2094 | break; | ||
| 1750 | default: | 2095 | default: |
| 1751 | gamma_base = gamma_def; | 2096 | gamma_base = gamma_def; |
| 1752 | break; | 2097 | break; |
| @@ -1937,14 +2282,17 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
| 1937 | static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec }; | 2282 | static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec }; |
| 1938 | static const u8 CA_adcm1700[] = | 2283 | static const u8 CA_adcm1700[] = |
| 1939 | { 0x14, 0xec, 0x0a, 0xf6 }; | 2284 | { 0x14, 0xec, 0x0a, 0xf6 }; |
| 2285 | static const u8 CA_po2030n[] = | ||
| 2286 | { 0x1e, 0xe2, 0x14, 0xec }; | ||
| 1940 | static const u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */ | 2287 | static const u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */ |
| 2288 | static const u8 CE_gc0307[] = | ||
| 2289 | { 0x32, 0xce, 0x2d, 0xd3 }; | ||
| 1941 | static const u8 CE_ov76xx[] = | 2290 | static const u8 CE_ov76xx[] = |
| 1942 | { 0x32, 0xdd, 0x32, 0xdd }; | 2291 | { 0x32, 0xdd, 0x32, 0xdd }; |
| 2292 | static const u8 CE_po2030n[] = | ||
| 2293 | { 0x14, 0xe7, 0x1e, 0xdd }; | ||
| 1943 | 2294 | ||
| 1944 | /* create the JPEG header */ | 2295 | /* create the JPEG header */ |
| 1945 | sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); | ||
| 1946 | if (!sd->jpeg_hdr) | ||
| 1947 | return -ENOMEM; | ||
| 1948 | jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, | 2296 | jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, |
| 1949 | 0x21); /* JPEG 422 */ | 2297 | 0x21); /* JPEG 422 */ |
| 1950 | jpeg_set_qual(sd->jpeg_hdr, sd->quality); | 2298 | jpeg_set_qual(sd->jpeg_hdr, sd->quality); |
| @@ -1996,6 +2344,9 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
| 1996 | } | 2344 | } |
| 1997 | reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]); | 2345 | reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]); |
| 1998 | switch (sd->sensor) { | 2346 | switch (sd->sensor) { |
| 2347 | case SENSOR_GC0307: | ||
| 2348 | reg17 = 0xa2; | ||
| 2349 | break; | ||
| 1999 | case SENSOR_MT9V111: | 2350 | case SENSOR_MT9V111: |
| 2000 | reg17 = 0xe0; | 2351 | reg17 = 0xe0; |
| 2001 | break; | 2352 | break; |
| @@ -2007,9 +2358,11 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
| 2007 | reg17 = 0x20; | 2358 | reg17 = 0x20; |
| 2008 | break; | 2359 | break; |
| 2009 | case SENSOR_OV7660: | 2360 | case SENSOR_OV7660: |
| 2361 | case SENSOR_SOI768: | ||
| 2010 | reg17 = 0xa0; | 2362 | reg17 = 0xa0; |
| 2011 | break; | 2363 | break; |
| 2012 | case SENSOR_PO1030: | 2364 | case SENSOR_PO1030: |
| 2365 | case SENSOR_PO2030N: | ||
| 2013 | reg17 = 0xa0; | 2366 | reg17 = 0xa0; |
| 2014 | break; | 2367 | break; |
| 2015 | default: | 2368 | default: |
| @@ -2034,12 +2387,18 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
| 2034 | case SENSOR_SP80708: | 2387 | case SENSOR_SP80708: |
| 2035 | reg_w1(gspca_dev, 0x9a, 0x05); | 2388 | reg_w1(gspca_dev, 0x9a, 0x05); |
| 2036 | break; | 2389 | break; |
| 2390 | case SENSOR_GC0307: | ||
| 2037 | case SENSOR_MT9V111: | 2391 | case SENSOR_MT9V111: |
| 2038 | reg_w1(gspca_dev, 0x9a, 0x07); | 2392 | reg_w1(gspca_dev, 0x9a, 0x07); |
| 2039 | break; | 2393 | break; |
| 2394 | case SENSOR_OV7630: | ||
| 2040 | case SENSOR_OV7648: | 2395 | case SENSOR_OV7648: |
| 2041 | reg_w1(gspca_dev, 0x9a, 0x0a); | 2396 | reg_w1(gspca_dev, 0x9a, 0x0a); |
| 2042 | break; | 2397 | break; |
| 2398 | case SENSOR_PO2030N: | ||
| 2399 | case SENSOR_SOI768: | ||
| 2400 | reg_w1(gspca_dev, 0x9a, 0x06); | ||
| 2401 | break; | ||
| 2043 | default: | 2402 | default: |
| 2044 | reg_w1(gspca_dev, 0x9a, 0x08); | 2403 | reg_w1(gspca_dev, 0x9a, 0x08); |
| 2045 | break; | 2404 | break; |
| @@ -2064,6 +2423,11 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
| 2064 | reg1 = 0x46; | 2423 | reg1 = 0x46; |
| 2065 | reg17 = 0xe2; | 2424 | reg17 = 0xe2; |
| 2066 | break; | 2425 | break; |
| 2426 | case SENSOR_GC0307: | ||
| 2427 | init = gc0307_sensor_param1; | ||
| 2428 | reg17 = 0xa2; | ||
| 2429 | reg1 = 0x44; | ||
| 2430 | break; | ||
| 2067 | case SENSOR_MO4000: | 2431 | case SENSOR_MO4000: |
| 2068 | if (mode) { | 2432 | if (mode) { |
| 2069 | /* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */ | 2433 | /* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */ |
| @@ -2087,6 +2451,7 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
| 2087 | reg17 = 0x64; /* 640 MCKSIZE */ | 2451 | reg17 = 0x64; /* 640 MCKSIZE */ |
| 2088 | break; | 2452 | break; |
| 2089 | case SENSOR_OV7630: | 2453 | case SENSOR_OV7630: |
| 2454 | init = ov7630_sensor_param1; | ||
| 2090 | reg17 = 0xe2; | 2455 | reg17 = 0xe2; |
| 2091 | reg1 = 0x44; | 2456 | reg1 = 0x44; |
| 2092 | break; | 2457 | break; |
| @@ -2113,6 +2478,16 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
| 2113 | reg17 = 0xa2; | 2478 | reg17 = 0xa2; |
| 2114 | reg1 = 0x44; | 2479 | reg1 = 0x44; |
| 2115 | break; | 2480 | break; |
| 2481 | case SENSOR_PO2030N: | ||
| 2482 | init = po2030n_sensor_param1; | ||
| 2483 | reg1 = 0x46; | ||
| 2484 | reg17 = 0xa2; | ||
| 2485 | break; | ||
| 2486 | case SENSOR_SOI768: | ||
| 2487 | init = soi768_sensor_param1; | ||
| 2488 | reg1 = 0x44; | ||
| 2489 | reg17 = 0xa2; | ||
| 2490 | break; | ||
| 2116 | default: | 2491 | default: |
| 2117 | /* case SENSOR_SP80708: */ | 2492 | /* case SENSOR_SP80708: */ |
| 2118 | init = sp80708_sensor_param1; | 2493 | init = sp80708_sensor_param1; |
| @@ -2132,17 +2507,33 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
| 2132 | } | 2507 | } |
| 2133 | 2508 | ||
| 2134 | reg_w(gspca_dev, 0xc0, C0, 6); | 2509 | reg_w(gspca_dev, 0xc0, C0, 6); |
| 2135 | if (sd->sensor == SENSOR_ADCM1700) | 2510 | switch (sd->sensor) { |
| 2511 | case SENSOR_ADCM1700: | ||
| 2512 | case SENSOR_GC0307: | ||
| 2513 | case SENSOR_SOI768: | ||
| 2136 | reg_w(gspca_dev, 0xca, CA_adcm1700, 4); | 2514 | reg_w(gspca_dev, 0xca, CA_adcm1700, 4); |
| 2137 | else | 2515 | break; |
| 2516 | case SENSOR_PO2030N: | ||
| 2517 | reg_w(gspca_dev, 0xca, CA_po2030n, 4); | ||
| 2518 | break; | ||
| 2519 | default: | ||
| 2138 | reg_w(gspca_dev, 0xca, CA, 4); | 2520 | reg_w(gspca_dev, 0xca, CA, 4); |
| 2521 | break; | ||
| 2522 | } | ||
| 2139 | switch (sd->sensor) { | 2523 | switch (sd->sensor) { |
| 2140 | case SENSOR_ADCM1700: | 2524 | case SENSOR_ADCM1700: |
| 2141 | case SENSOR_OV7630: | 2525 | case SENSOR_OV7630: |
| 2142 | case SENSOR_OV7648: | 2526 | case SENSOR_OV7648: |
| 2143 | case SENSOR_OV7660: | 2527 | case SENSOR_OV7660: |
| 2528 | case SENSOR_SOI768: | ||
| 2144 | reg_w(gspca_dev, 0xce, CE_ov76xx, 4); | 2529 | reg_w(gspca_dev, 0xce, CE_ov76xx, 4); |
| 2145 | break; | 2530 | break; |
| 2531 | case SENSOR_GC0307: | ||
| 2532 | reg_w(gspca_dev, 0xce, CE_gc0307, 4); | ||
| 2533 | break; | ||
| 2534 | case SENSOR_PO2030N: | ||
| 2535 | reg_w(gspca_dev, 0xce, CE_po2030n, 4); | ||
| 2536 | break; | ||
| 2146 | default: | 2537 | default: |
| 2147 | reg_w(gspca_dev, 0xce, CE, 4); | 2538 | reg_w(gspca_dev, 0xce, CE, 4); |
| 2148 | /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */ | 2539 | /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */ |
| @@ -2161,6 +2552,7 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
| 2161 | setvflip(sd); | 2552 | setvflip(sd); |
| 2162 | setbrightness(gspca_dev); | 2553 | setbrightness(gspca_dev); |
| 2163 | setcontrast(gspca_dev); | 2554 | setcontrast(gspca_dev); |
| 2555 | setcolors(gspca_dev); | ||
| 2164 | setautogain(gspca_dev); | 2556 | setautogain(gspca_dev); |
| 2165 | setfreq(gspca_dev); | 2557 | setfreq(gspca_dev); |
| 2166 | return 0; | 2558 | return 0; |
| @@ -2175,11 +2567,16 @@ static void sd_stopN(struct gspca_dev *gspca_dev) | |||
| 2175 | { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 }; | 2567 | { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 }; |
| 2176 | static const u8 stopov7648[] = | 2568 | static const u8 stopov7648[] = |
| 2177 | { 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 }; | 2569 | { 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 }; |
| 2570 | static const u8 stopsoi768[] = | ||
| 2571 | { 0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10 }; | ||
| 2178 | u8 data; | 2572 | u8 data; |
| 2179 | const u8 *sn9c1xx; | 2573 | const u8 *sn9c1xx; |
| 2180 | 2574 | ||
| 2181 | data = 0x0b; | 2575 | data = 0x0b; |
| 2182 | switch (sd->sensor) { | 2576 | switch (sd->sensor) { |
| 2577 | case SENSOR_GC0307: | ||
| 2578 | data = 0x29; | ||
| 2579 | break; | ||
| 2183 | case SENSOR_HV7131R: | 2580 | case SENSOR_HV7131R: |
| 2184 | i2c_w8(gspca_dev, stophv7131); | 2581 | i2c_w8(gspca_dev, stophv7131); |
| 2185 | data = 0x2b; | 2582 | data = 0x2b; |
| @@ -2196,6 +2593,10 @@ static void sd_stopN(struct gspca_dev *gspca_dev) | |||
| 2196 | case SENSOR_PO1030: | 2593 | case SENSOR_PO1030: |
| 2197 | data = 0x29; | 2594 | data = 0x29; |
| 2198 | break; | 2595 | break; |
| 2596 | case SENSOR_SOI768: | ||
| 2597 | i2c_w8(gspca_dev, stopsoi768); | ||
| 2598 | data = 0x29; | ||
| 2599 | break; | ||
| 2199 | } | 2600 | } |
| 2200 | sn9c1xx = sn_tb[sd->sensor]; | 2601 | sn9c1xx = sn_tb[sd->sensor]; |
| 2201 | reg_w1(gspca_dev, 0x01, sn9c1xx[1]); | 2602 | reg_w1(gspca_dev, 0x01, sn9c1xx[1]); |
| @@ -2206,13 +2607,6 @@ static void sd_stopN(struct gspca_dev *gspca_dev) | |||
| 2206 | /* reg_w1(gspca_dev, 0xf1, 0x01); */ | 2607 | /* reg_w1(gspca_dev, 0xf1, 0x01); */ |
| 2207 | } | 2608 | } |
| 2208 | 2609 | ||
| 2209 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
| 2210 | { | ||
| 2211 | struct sd *sd = (struct sd *) gspca_dev; | ||
| 2212 | |||
| 2213 | kfree(sd->jpeg_hdr); | ||
| 2214 | } | ||
| 2215 | |||
| 2216 | static void do_autogain(struct gspca_dev *gspca_dev) | 2610 | static void do_autogain(struct gspca_dev *gspca_dev) |
| 2217 | { | 2611 | { |
| 2218 | struct sd *sd = (struct sd *) gspca_dev; | 2612 | struct sd *sd = (struct sd *) gspca_dev; |
| @@ -2233,6 +2627,14 @@ static void do_autogain(struct gspca_dev *gspca_dev) | |||
| 2233 | if (delta < luma_mean - luma_delta || | 2627 | if (delta < luma_mean - luma_delta || |
| 2234 | delta > luma_mean + luma_delta) { | 2628 | delta > luma_mean + luma_delta) { |
| 2235 | switch (sd->sensor) { | 2629 | switch (sd->sensor) { |
| 2630 | case SENSOR_GC0307: | ||
| 2631 | expotimes = sd->exposure; | ||
| 2632 | expotimes += (luma_mean - delta) >> 6; | ||
| 2633 | if (expotimes < 0) | ||
| 2634 | expotimes = 0; | ||
| 2635 | sd->exposure = setexposure(gspca_dev, | ||
| 2636 | (unsigned int) expotimes); | ||
| 2637 | break; | ||
| 2236 | case SENSOR_HV7131R: | 2638 | case SENSOR_HV7131R: |
| 2237 | expotimes = sd->exposure >> 8; | 2639 | expotimes = sd->exposure >> 8; |
| 2238 | expotimes += (luma_mean - delta) >> 4; | 2640 | expotimes += (luma_mean - delta) >> 4; |
| @@ -2584,7 +2986,6 @@ static const struct sd_desc sd_desc = { | |||
| 2584 | .init = sd_init, | 2986 | .init = sd_init, |
| 2585 | .start = sd_start, | 2987 | .start = sd_start, |
| 2586 | .stopN = sd_stopN, | 2988 | .stopN = sd_stopN, |
| 2587 | .stop0 = sd_stop0, | ||
| 2588 | .pkt_scan = sd_pkt_scan, | 2989 | .pkt_scan = sd_pkt_scan, |
| 2589 | .dq_callback = do_autogain, | 2990 | .dq_callback = do_autogain, |
| 2590 | .get_jcomp = sd_get_jcomp, | 2991 | .get_jcomp = sd_get_jcomp, |
| @@ -2656,7 +3057,7 @@ static const __devinitdata struct usb_device_id device_table[] = { | |||
| 2656 | #endif | 3057 | #endif |
| 2657 | {USB_DEVICE(0x0c45, 0x613c), BS(SN9C120, HV7131R)}, | 3058 | {USB_DEVICE(0x0c45, 0x613c), BS(SN9C120, HV7131R)}, |
| 2658 | {USB_DEVICE(0x0c45, 0x613e), BS(SN9C120, OV7630)}, | 3059 | {USB_DEVICE(0x0c45, 0x613e), BS(SN9C120, OV7630)}, |
| 2659 | /* {USB_DEVICE(0x0c45, 0x6142), BS(SN9C120, PO2030N)}, *sn9c120b*/ | 3060 | {USB_DEVICE(0x0c45, 0x6142), BS(SN9C120, PO2030N)}, /*sn9c120b*/ |
| 2660 | {USB_DEVICE(0x0c45, 0x6143), BS(SN9C120, SP80708)}, /*sn9c120b*/ | 3061 | {USB_DEVICE(0x0c45, 0x6143), BS(SN9C120, SP80708)}, /*sn9c120b*/ |
| 2661 | {USB_DEVICE(0x0c45, 0x6148), BS(SN9C120, OM6802)}, /*sn9c120b*/ | 3062 | {USB_DEVICE(0x0c45, 0x6148), BS(SN9C120, OM6802)}, /*sn9c120b*/ |
| 2662 | {USB_DEVICE(0x0c45, 0x614a), BS(SN9C120, ADCM1700)}, /*sn9c120b*/ | 3063 | {USB_DEVICE(0x0c45, 0x614a), BS(SN9C120, ADCM1700)}, /*sn9c120b*/ |
