Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6

* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (34 commits)
V4L/DVB (12303): cx23885: check pointers before dereferencing in dprintk macro
V4L/DVB (12302): cx23885-417: fix broken IOCTL handling
V4L/DVB (12300): bttv: fix regression: tvaudio must be loaded before tuner
V4L/DVB (12291): b2c2: fix frontends compiled into kernel
V4L/DVB (12286): sn9c20x: reorder includes to be like other drivers
V4L/DVB (12284): gspca - jpeg subdrivers: Check the result of kmalloc(jpeg header).
V4L/DVB (12283): gspca - sn9c20x: New subdriver for sn9c201 and sn9c202 bridges.
V4L/DVB (12282): gspca - main: Support for vidioc_g_chip_ident and vidioc_g/s_register.
V4L/DVB (12269): af9013: auto-detect parameters in case of garbage given by app
V4L/DVB (12267): gspca - sonixj: Bad sensor init of non ov76xx sensors.
V4L/DVB (12265): em28xx: fix tuning problem in HVR-900 (R1)
V4L/DVB (12263): em28xx: set demod profile for Pinnacle Hybrid Pro 320e
V4L/DVB (12262): em28xx: Make sure the tuner is initialized if generic empia USB id was used
V4L/DVB (12261): em28xx: set GPIO properly for Pinnacle Hybrid Pro analog support
V4L/DVB (12260): em28xx: make support work for the Pinnacle Hybrid Pro (eb1a:2881)
V4L/DVB (12258): em28xx: fix typo in mt352 init sequence for Terratec Cinergy T XS USB
V4L/DVB (12257): em28xx: make tuning work for Terratec Cinergy T XS USB (mt352 variant)
V4L/DVB (12245): em28xx: add support for mt9m001 webcams
V4L/DVB (12244): em28xx: adjust vinmode/vinctl based on the stream input format
V4L/DVB (12243): em28xx: allow specifying sensor xtal frequency
...

+2974 -171
+1 -1
Documentation/video4linux/CARDLIST.em28xx
··· 20 20 19 -> EM2860/SAA711X Reference Design (em2860) 21 21 20 -> AMD ATI TV Wonder HD 600 (em2880) [0438:b002] 22 22 21 -> eMPIA Technology, Inc. GrabBeeX+ Video Encoder (em2800) [eb1a:2801] 23 - 22 -> Unknown EM2750/EM2751 webcam grabber (em2750) [eb1a:2750,eb1a:2751] 23 + 22 -> EM2710/EM2750/EM2751 webcam grabber (em2750) [eb1a:2750,eb1a:2751] 24 24 23 -> Huaqi DLCW-130 (em2750) 25 25 24 -> D-Link DUB-T210 TV Tuner (em2820/em2840) [2001:f112] 26 26 25 -> Gadmei UTV310 (em2820/em2840)
+32
Documentation/video4linux/gspca.txt
··· 44 44 zc3xx 0458:700c Genius VideoCam V3 45 45 zc3xx 0458:700f Genius VideoCam Web V2 46 46 sonixj 0458:7025 Genius Eye 311Q 47 + sn9c20x 0458:7029 Genius Look 320s 47 48 sonixj 0458:702e Genius Slim 310 NB 49 + sn9c20x 045e:00f4 LifeCam VX-6000 (SN9C20x + OV9650) 48 50 sonixj 045e:00f5 MicroSoft VX3000 49 51 sonixj 045e:00f7 MicroSoft VX1000 50 52 ov519 045e:028c Micro$oft xbox cam ··· 284 282 sonixj 0c45:613b Surfer SN-206 285 283 sonixj 0c45:613c Sonix Pccam168 286 284 sonixj 0c45:6143 Sonix Pccam168 285 + sn9c20x 0c45:6240 PC Camera (SN9C201 + MT9M001) 286 + sn9c20x 0c45:6242 PC Camera (SN9C201 + MT9M111) 287 + sn9c20x 0c45:6248 PC Camera (SN9C201 + OV9655) 288 + sn9c20x 0c45:624e PC Camera (SN9C201 + SOI968) 289 + sn9c20x 0c45:624f PC Camera (SN9C201 + OV9650) 290 + sn9c20x 0c45:6251 PC Camera (SN9C201 + OV9650) 291 + sn9c20x 0c45:6253 PC Camera (SN9C201 + OV9650) 292 + sn9c20x 0c45:6260 PC Camera (SN9C201 + OV7670) 293 + sn9c20x 0c45:6270 PC Camera (SN9C201 + MT9V011/MT9V111/MT9V112) 294 + sn9c20x 0c45:627b PC Camera (SN9C201 + OV7660) 295 + sn9c20x 0c45:627c PC Camera (SN9C201 + HV7131R) 296 + sn9c20x 0c45:627f PC Camera (SN9C201 + OV9650) 297 + sn9c20x 0c45:6280 PC Camera (SN9C202 + MT9M001) 298 + sn9c20x 0c45:6282 PC Camera (SN9C202 + MT9M111) 299 + sn9c20x 0c45:6288 PC Camera (SN9C202 + OV9655) 300 + sn9c20x 0c45:628e PC Camera (SN9C202 + SOI968) 301 + sn9c20x 0c45:628f PC Camera (SN9C202 + OV9650) 302 + sn9c20x 0c45:62a0 PC Camera (SN9C202 + OV7670) 303 + sn9c20x 0c45:62b0 PC Camera (SN9C202 + MT9V011/MT9V111/MT9V112) 304 + sn9c20x 0c45:62b3 PC Camera (SN9C202 + OV9655) 305 + sn9c20x 0c45:62bb PC Camera (SN9C202 + OV7660) 306 + sn9c20x 0c45:62bc PC Camera (SN9C202 + HV7131R) 287 307 sunplus 0d64:0303 Sunplus FashionCam DXG 288 308 etoms 102c:6151 Qcam Sangha CIF 289 309 etoms 102c:6251 Qcam xxxxxx VGA ··· 314 290 zc3xx 10fd:8050 Typhoon Webshot II USB 300k 315 291 ov534 1415:2000 Sony HD Eye for PS3 (SLEH 00201) 316 292 pac207 145f:013a Trust WB-1300N 293 + sn9c20x 145f:013d Trust WB-3600R 317 294 vc032x 15b8:6001 HP 2.0 Megapixel 318 295 vc032x 15b8:6002 HP 2.0 Megapixel rz406aa 319 296 spca501 1776:501c Arowana 300K CMOS Camera ··· 325 300 spca508 8086:0110 Intel Easy PC Camera 326 301 spca500 8086:0630 Intel Pocket PC Camera 327 302 spca506 99fa:8988 Grandtec V.cap 303 + sn9c20x a168:0610 Dino-Lite Digital Microscope (SN9C201 + HV7131R) 304 + sn9c20x a168:0611 Dino-Lite Digital Microscope (SN9C201 + HV7131R) 305 + sn9c20x a168:0613 Dino-Lite Digital Microscope (SN9C201 + HV7131R) 306 + sn9c20x a168:0618 Dino-Lite Digital Microscope (SN9C201 + HV7131R) 307 + sn9c20x a168:0614 Dino-Lite Digital Microscope (SN9C201 + MT9M111) 308 + sn9c20x a168:0615 Dino-Lite Digital Microscope (SN9C201 + MT9M111) 309 + sn9c20x a168:0617 Dino-Lite Digital Microscope (SN9C201 + MT9M111) 328 310 spca561 abcd:cdee Petcam
+37 -30
drivers/media/dvb/b2c2/flexcop-fe-tuner.c
··· 20 20 #include "tuner-simple.h" 21 21 #include "stv0297.h" 22 22 23 + 24 + /* Can we use the specified front-end? Remember that if we are compiled 25 + * into the kernel we can't call code that's in modules. */ 26 + #define FE_SUPPORTED(fe) (defined(CONFIG_DVB_##fe) || \ 27 + (defined(CONFIG_DVB_##fe##_MODULE) && defined(MODULE))) 28 + 23 29 /* lnb control */ 24 - #if defined(CONFIG_DVB_MT312_MODULE) || defined(CONFIG_DVB_STV0299_MODULE) 30 + #if FE_SUPPORTED(MT312) || FE_SUPPORTED(STV0299) 25 31 static int flexcop_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) 26 32 { 27 33 struct flexcop_device *fc = fe->dvb->priv; ··· 55 49 } 56 50 #endif 57 51 58 - #if defined(CONFIG_DVB_S5H1420_MODULE) || defined(CONFIG_DVB_STV0299_MODULE) \ 59 - || defined(CONFIG_DVB_MT312_MODULE) 52 + #if FE_SUPPORTED(S5H1420) || FE_SUPPORTED(STV0299) || FE_SUPPORTED(MT312) 60 53 static int flexcop_sleep(struct dvb_frontend* fe) 61 54 { 62 55 struct flexcop_device *fc = fe->dvb->priv; ··· 66 61 #endif 67 62 68 63 /* SkyStar2 DVB-S rev 2.3 */ 69 - #if defined(CONFIG_DVB_MT312_MODULE) 64 + #if FE_SUPPORTED(MT312) 70 65 static int flexcop_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) 71 66 { 72 67 /* u16 wz_half_period_for_45_mhz[] = { 0x01ff, 0x0154, 0x00ff, 0x00cc }; */ ··· 198 193 } 199 194 return 0; 200 195 } 196 + #else 197 + #define skystar2_rev23_attach NULL 201 198 #endif 202 199 203 200 /* SkyStar2 DVB-S rev 2.6 */ 204 - #if defined(CONFIG_DVB_STV0299_MODULE) 201 + #if FE_SUPPORTED(STV0299) 205 202 static int samsung_tbmu24112_set_symbol_rate(struct dvb_frontend *fe, 206 203 u32 srate, u32 ratio) 207 204 { ··· 328 321 } 329 322 return 0; 330 323 } 324 + #else 325 + #define skystar2_rev26_attach NULL 331 326 #endif 332 327 333 328 /* SkyStar2 DVB-S rev 2.7 */ 334 - #if defined(CONFIG_DVB_S5H1420_MODULE) 329 + #if FE_SUPPORTED(S5H1420) && FE_SUPPORTED(ISL6421) && FE_SUPPORTED(TUNER_ITD1000) 335 330 static struct s5h1420_config skystar2_rev2_7_s5h1420_config = { 336 331 .demod_address = 0x53, 337 332 .invert = 1, ··· 394 385 fc->fc_i2c_adap[0].no_base_addr = 0; 395 386 return 0; 396 387 } 388 + #else 389 + #define skystar2_rev27_attach NULL 397 390 #endif 398 391 399 392 /* SkyStar2 rev 2.8 */ 400 - #if defined(CONFIG_DVB_CX24123_MODULE) 393 + #if FE_SUPPORTED(CX24123) && FE_SUPPORTED(ISL6421) && FE_SUPPORTED(TUNER_CX24113) 401 394 static struct cx24123_config skystar2_rev2_8_cx24123_config = { 402 395 .demod_address = 0x55, 403 396 .dont_use_pll = 1, ··· 444 433 * IR-receiver (PIC16F818) - but the card has no input for that ??? */ 445 434 return 1; 446 435 } 436 + #else 437 + #define skystar2_rev28_attach NULL 447 438 #endif 448 439 449 440 /* AirStar DVB-T */ 450 - #if defined(CONFIG_DVB_MT352_MODULE) 441 + #if FE_SUPPORTED(MT352) 451 442 static int samsung_tdtc9251dh0_demod_init(struct dvb_frontend *fe) 452 443 { 453 444 static u8 mt352_clock_config[] = { 0x89, 0x18, 0x2d }; ··· 508 495 } 509 496 return 0; 510 497 } 498 + #else 499 + #define airstar_dvbt_attach NULL 511 500 #endif 512 501 513 502 /* AirStar ATSC 1st generation */ 514 - #if defined(CONFIG_DVB_BCM3510_MODULE) 503 + #if FE_SUPPORTED(BCM3510) 515 504 static int flexcop_fe_request_firmware(struct dvb_frontend *fe, 516 505 const struct firmware **fw, char* name) 517 506 { ··· 532 517 fc->fe = dvb_attach(bcm3510_attach, &air2pc_atsc_first_gen_config, i2c); 533 518 return fc->fe != NULL; 534 519 } 520 + #else 521 + #define airstar_atsc1_attach NULL 535 522 #endif 536 523 537 524 /* AirStar ATSC 2nd generation */ 538 - #if defined(CONFIG_DVB_NXT200X_MODULE) 525 + #if FE_SUPPORTED(NXT200X) && FE_SUPPORTED(PLL) 539 526 static struct nxt200x_config samsung_tbmv_config = { 540 527 .demod_address = 0x0a, 541 528 }; ··· 552 535 return !!dvb_attach(dvb_pll_attach, fc->fe, 0x61, NULL, 553 536 DVB_PLL_SAMSUNG_TBMV); 554 537 } 538 + #else 539 + #define airstar_atsc2_attach NULL 555 540 #endif 556 541 557 542 /* AirStar ATSC 3rd generation */ 558 - #if defined(CONFIG_DVB_LGDT330X_MODULE) 543 + #if FE_SUPPORTED(LGDT330X) 559 544 static struct lgdt330x_config air2pc_atsc_hd5000_config = { 560 545 .demod_address = 0x59, 561 546 .demod_chip = LGDT3303, ··· 575 556 return !!dvb_attach(simple_tuner_attach, fc->fe, i2c, 0x61, 576 557 TUNER_LG_TDVS_H06XF); 577 558 } 559 + #else 560 + #define airstar_atsc3_attach NULL 578 561 #endif 579 562 580 563 /* CableStar2 DVB-C */ 581 - #if defined(CONFIG_DVB_STV0297_MODULE) 564 + #if FE_SUPPORTED(STV0297) 582 565 static int alps_tdee4_stv0297_tuner_set_params(struct dvb_frontend* fe, 583 566 struct dvb_frontend_parameters *fep) 584 567 { ··· 719 698 fc->fe->ops.tuner_ops.set_params = alps_tdee4_stv0297_tuner_set_params; 720 699 return 1; 721 700 } 701 + #else 702 + #define cablestar2_attach NULL 722 703 #endif 723 704 724 705 static struct { 725 706 flexcop_device_type_t type; 726 707 int (*attach)(struct flexcop_device *, struct i2c_adapter *); 727 708 } flexcop_frontends[] = { 728 - #if defined(CONFIG_DVB_S5H1420_MODULE) 729 709 { FC_SKY_REV27, skystar2_rev27_attach }, 730 - #endif 731 - #if defined(CONFIG_DVB_CX24123_MODULE) 732 710 { FC_SKY_REV28, skystar2_rev28_attach }, 733 - #endif 734 - #if defined(CONFIG_DVB_STV0299_MODULE) 735 711 { FC_SKY_REV26, skystar2_rev26_attach }, 736 - #endif 737 - #if defined(CONFIG_DVB_MT352_MODULE) 738 712 { FC_AIR_DVBT, airstar_dvbt_attach }, 739 - #endif 740 - #if defined(CONFIG_DVB_NXT200X_MODULE) 741 713 { FC_AIR_ATSC2, airstar_atsc2_attach }, 742 - #endif 743 - #if defined(CONFIG_DVB_LGDT330X_MODULE) 744 714 { FC_AIR_ATSC3, airstar_atsc3_attach }, 745 - #endif 746 - #if defined(CONFIG_DVB_BCM3510_MODULE) 747 715 { FC_AIR_ATSC1, airstar_atsc1_attach }, 748 - #endif 749 - #if defined(CONFIG_DVB_STV0297_MODULE) 750 716 { FC_CABLE, cablestar2_attach }, 751 - #endif 752 - #if defined(CONFIG_DVB_MT312_MODULE) 753 717 { FC_SKY_REV23, skystar2_rev23_attach }, 754 - #endif 755 718 }; 756 719 757 720 /* try to figure out the frontend */ ··· 743 738 { 744 739 int i; 745 740 for (i = 0; i < ARRAY_SIZE(flexcop_frontends); i++) { 741 + if (!flexcop_frontends[i].attach) 742 + continue; 746 743 /* type needs to be set before, because of some workarounds 747 744 * done based on the probed card type */ 748 745 fc->dev_type = flexcop_frontends[i].type;
+18 -7
drivers/media/dvb/frontends/af9013.c
··· 527 527 u8 i, buf[3] = {0, 0, 0}; 528 528 *auto_mode = 0; /* set if parameters are requested to auto set */ 529 529 530 + /* Try auto-detect transmission parameters in case of AUTO requested or 531 + garbage parameters given by application for compatibility. 532 + MPlayer seems to provide garbage parameters currently. */ 533 + 530 534 switch (params->transmission_mode) { 531 535 case TRANSMISSION_MODE_AUTO: 532 536 *auto_mode = 1; ··· 540 536 buf[0] |= (1 << 0); 541 537 break; 542 538 default: 543 - return -EINVAL; 539 + deb_info("%s: invalid transmission_mode\n", __func__); 540 + *auto_mode = 1; 544 541 } 545 542 546 543 switch (params->guard_interval) { ··· 559 554 buf[0] |= (3 << 2); 560 555 break; 561 556 default: 562 - return -EINVAL; 557 + deb_info("%s: invalid guard_interval\n", __func__); 558 + *auto_mode = 1; 563 559 } 564 560 565 561 switch (params->hierarchy_information) { ··· 578 572 buf[0] |= (3 << 4); 579 573 break; 580 574 default: 581 - return -EINVAL; 575 + deb_info("%s: invalid hierarchy_information\n", __func__); 576 + *auto_mode = 1; 582 577 }; 583 578 584 579 switch (params->constellation) { ··· 594 587 buf[1] |= (2 << 6); 595 588 break; 596 589 default: 597 - return -EINVAL; 590 + deb_info("%s: invalid constellation\n", __func__); 591 + *auto_mode = 1; 598 592 } 599 593 600 594 /* Use HP. How and which case we can switch to LP? */ ··· 619 611 buf[2] |= (4 << 0); 620 612 break; 621 613 default: 622 - return -EINVAL; 614 + deb_info("%s: invalid code_rate_HP\n", __func__); 615 + *auto_mode = 1; 623 616 } 624 617 625 618 switch (params->code_rate_LP) { ··· 647 638 if (params->hierarchy_information == HIERARCHY_AUTO) 648 639 break; 649 640 default: 650 - return -EINVAL; 641 + deb_info("%s: invalid code_rate_LP\n", __func__); 642 + *auto_mode = 1; 651 643 } 652 644 653 645 switch (params->bandwidth) { ··· 661 651 buf[1] |= (2 << 2); 662 652 break; 663 653 default: 664 - return -EINVAL; 654 + deb_info("%s: invalid bandwidth\n", __func__); 655 + buf[1] |= (2 << 2); /* cannot auto-detect BW, try 8 MHz */ 665 656 } 666 657 667 658 /* program */
+48 -44
drivers/media/video/bt8xx/bttv-cards.c
··· 3324 3324 /* initialization part two -- after registering i2c bus */ 3325 3325 void __devinit bttv_init_card2(struct bttv *btv) 3326 3326 { 3327 - int addr=ADDR_UNSET; 3328 - 3329 3327 btv->tuner_type = UNSET; 3330 3328 3331 3329 if (BTTV_BOARD_UNKNOWN == btv->c.type) { ··· 3468 3470 btv->pll.pll_current = -1; 3469 3471 3470 3472 /* tuner configuration (from card list / autodetect / insmod option) */ 3471 - if (ADDR_UNSET != bttv_tvcards[btv->c.type].tuner_addr) 3472 - addr = bttv_tvcards[btv->c.type].tuner_addr; 3473 - 3474 3473 if (UNSET != bttv_tvcards[btv->c.type].tuner_type) 3475 3474 if (UNSET == btv->tuner_type) 3476 3475 btv->tuner_type = bttv_tvcards[btv->c.type].tuner_type; ··· 3491 3496 if (UNSET == btv->tuner_type) 3492 3497 btv->tuner_type = TUNER_ABSENT; 3493 3498 3494 - if (btv->tuner_type != TUNER_ABSENT) { 3495 - struct tuner_setup tun_setup; 3496 - 3497 - /* Load tuner module before issuing tuner config call! */ 3498 - if (bttv_tvcards[btv->c.type].has_radio) 3499 - v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev, 3500 - &btv->c.i2c_adap, "tuner", "tuner", 3501 - v4l2_i2c_tuner_addrs(ADDRS_RADIO)); 3502 - v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev, 3503 - &btv->c.i2c_adap, "tuner", "tuner", 3504 - v4l2_i2c_tuner_addrs(ADDRS_DEMOD)); 3505 - v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev, 3506 - &btv->c.i2c_adap, "tuner", "tuner", 3507 - v4l2_i2c_tuner_addrs(ADDRS_TV_WITH_DEMOD)); 3508 - 3509 - tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV; 3510 - tun_setup.type = btv->tuner_type; 3511 - tun_setup.addr = addr; 3512 - 3513 - if (bttv_tvcards[btv->c.type].has_radio) 3514 - tun_setup.mode_mask |= T_RADIO; 3515 - 3516 - bttv_call_all(btv, tuner, s_type_addr, &tun_setup); 3517 - } 3518 - 3519 - if (btv->tda9887_conf) { 3520 - struct v4l2_priv_tun_config tda9887_cfg; 3521 - 3522 - tda9887_cfg.tuner = TUNER_TDA9887; 3523 - tda9887_cfg.priv = &btv->tda9887_conf; 3524 - 3525 - bttv_call_all(btv, tuner, s_config, &tda9887_cfg); 3526 - } 3527 - 3528 3499 btv->dig = bttv_tvcards[btv->c.type].has_dig_in ? 3529 3500 bttv_tvcards[btv->c.type].video_inputs - 1 : UNSET; 3530 3501 btv->svhs = bttv_tvcards[btv->c.type].svhs == NO_SVHS ? ··· 3501 3540 btv->has_remote = remote[btv->c.nr]; 3502 3541 3503 3542 if (bttv_tvcards[btv->c.type].has_radio) 3504 - btv->has_radio=1; 3543 + btv->has_radio = 1; 3505 3544 if (bttv_tvcards[btv->c.type].has_remote) 3506 - btv->has_remote=1; 3545 + btv->has_remote = 1; 3507 3546 if (!bttv_tvcards[btv->c.type].no_gpioirq) 3508 - btv->gpioirq=1; 3547 + btv->gpioirq = 1; 3509 3548 if (bttv_tvcards[btv->c.type].volume_gpio) 3510 - btv->volume_gpio=bttv_tvcards[btv->c.type].volume_gpio; 3549 + btv->volume_gpio = bttv_tvcards[btv->c.type].volume_gpio; 3511 3550 if (bttv_tvcards[btv->c.type].audio_mode_gpio) 3512 - btv->audio_mode_gpio=bttv_tvcards[btv->c.type].audio_mode_gpio; 3551 + btv->audio_mode_gpio = bttv_tvcards[btv->c.type].audio_mode_gpio; 3513 3552 3514 3553 if (btv->tuner_type == TUNER_ABSENT) 3515 3554 return; /* no tuner or related drivers to load */ ··· 3626 3665 btv->c.nr); 3627 3666 } 3628 3667 3668 + 3669 + /* initialize the tuner */ 3670 + void __devinit bttv_init_tuner(struct bttv *btv) 3671 + { 3672 + int addr = ADDR_UNSET; 3673 + 3674 + if (ADDR_UNSET != bttv_tvcards[btv->c.type].tuner_addr) 3675 + addr = bttv_tvcards[btv->c.type].tuner_addr; 3676 + 3677 + if (btv->tuner_type != TUNER_ABSENT) { 3678 + struct tuner_setup tun_setup; 3679 + 3680 + /* Load tuner module before issuing tuner config call! */ 3681 + if (bttv_tvcards[btv->c.type].has_radio) 3682 + v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev, 3683 + &btv->c.i2c_adap, "tuner", "tuner", 3684 + v4l2_i2c_tuner_addrs(ADDRS_RADIO)); 3685 + v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev, 3686 + &btv->c.i2c_adap, "tuner", "tuner", 3687 + v4l2_i2c_tuner_addrs(ADDRS_DEMOD)); 3688 + v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev, 3689 + &btv->c.i2c_adap, "tuner", "tuner", 3690 + v4l2_i2c_tuner_addrs(ADDRS_TV_WITH_DEMOD)); 3691 + 3692 + tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV; 3693 + tun_setup.type = btv->tuner_type; 3694 + tun_setup.addr = addr; 3695 + 3696 + if (bttv_tvcards[btv->c.type].has_radio) 3697 + tun_setup.mode_mask |= T_RADIO; 3698 + 3699 + bttv_call_all(btv, tuner, s_type_addr, &tun_setup); 3700 + } 3701 + 3702 + if (btv->tda9887_conf) { 3703 + struct v4l2_priv_tun_config tda9887_cfg; 3704 + 3705 + tda9887_cfg.tuner = TUNER_TDA9887; 3706 + tda9887_cfg.priv = &btv->tda9887_conf; 3707 + 3708 + bttv_call_all(btv, tuner, s_config, &tda9887_cfg); 3709 + } 3710 + } 3629 3711 3630 3712 /* ----------------------------------------------------------------------- */ 3631 3713
+1
drivers/media/video/bt8xx/bttv-driver.c
··· 4419 4419 4420 4420 /* some card-specific stuff (needs working i2c) */ 4421 4421 bttv_init_card2(btv); 4422 + bttv_init_tuner(btv); 4422 4423 init_irqreg(btv); 4423 4424 4424 4425 /* register video4linux + input */
+1
drivers/media/video/bt8xx/bttv.h
··· 283 283 extern void bttv_idcard(struct bttv *btv); 284 284 extern void bttv_init_card1(struct bttv *btv); 285 285 extern void bttv_init_card2(struct bttv *btv); 286 + extern void bttv_init_tuner(struct bttv *btv); 286 287 287 288 /* card-specific funtions */ 288 289 extern void tea5757_set_freq(struct bttv *btv, unsigned short freq);
+3 -1
drivers/media/video/cx23885/cx23885-417.c
··· 58 58 59 59 #define dprintk(level, fmt, arg...)\ 60 60 do { if (v4l_debug >= level) \ 61 - printk(KERN_DEBUG "%s: " fmt, dev->name , ## arg);\ 61 + printk(KERN_DEBUG "%s: " fmt, \ 62 + (dev) ? dev->name : "cx23885[?]", ## arg); \ 62 63 } while (0) 63 64 64 65 static struct cx23885_tvnorm cx23885_tvnorms[] = { ··· 1678 1677 .read = mpeg_read, 1679 1678 .poll = mpeg_poll, 1680 1679 .mmap = mpeg_mmap, 1680 + .ioctl = video_ioctl2, 1681 1681 }; 1682 1682 1683 1683 static const struct v4l2_ioctl_ops mpeg_ioctl_ops = {
+107 -27
drivers/media/video/em28xx/em28xx-cards.c
··· 58 58 module_param_array(card, int, NULL, 0444); 59 59 MODULE_PARM_DESC(card, "card type"); 60 60 61 - #define MT9V011_VERSION 0x8243 62 - 63 61 /* Bitmask marking allocated devices from 0 to EM28XX_MAXBOARDS */ 64 62 static unsigned long em28xx_devused; 65 63 ··· 157 159 { -1, -1, -1, -1}, 158 160 }; 159 161 162 + /* Pinnacle Hybrid Pro eb1a:2881 */ 163 + static struct em28xx_reg_seq pinnacle_hybrid_pro_analog[] = { 164 + {EM28XX_R08_GPIO, 0xfd, ~EM_GPIO_4, 10}, 165 + { -1, -1, -1, -1}, 166 + }; 167 + 168 + static struct em28xx_reg_seq pinnacle_hybrid_pro_digital[] = { 169 + {EM28XX_R08_GPIO, 0x6e, ~EM_GPIO_4, 10}, 170 + {EM2880_R04_GPO, 0x04, 0xff, 100},/* zl10353 reset */ 171 + {EM2880_R04_GPO, 0x0c, 0xff, 1}, 172 + { -1, -1, -1, -1}, 173 + }; 174 + 175 + 160 176 /* Callback for the most boards */ 161 177 static struct em28xx_reg_seq default_tuner_gpio[] = { 162 178 {EM28XX_R08_GPIO, EM_GPIO_4, EM_GPIO_4, 10}, ··· 217 205 */ 218 206 struct em28xx_board em28xx_boards[] = { 219 207 [EM2750_BOARD_UNKNOWN] = { 220 - .name = "Unknown EM2750/EM2751 webcam grabber", 208 + .name = "EM2710/EM2750/EM2751 webcam grabber", 221 209 .xclk = EM28XX_XCLK_FREQUENCY_48MHZ, 222 - .tuner_type = TUNER_ABSENT, /* This is a webcam */ 210 + .tuner_type = TUNER_ABSENT, 211 + .is_webcam = 1, 223 212 .input = { { 224 213 .type = EM28XX_VMUX_COMPOSITE1, 225 214 .vmux = 0, 226 215 .amux = EM28XX_AMUX_VIDEO, 216 + .gpio = silvercrest_reg_seq, 227 217 } }, 228 218 }, 229 219 [EM2800_BOARD_UNKNOWN] = { ··· 247 233 [EM2820_BOARD_UNKNOWN] = { 248 234 .name = "Unknown EM2750/28xx video grabber", 249 235 .tuner_type = TUNER_ABSENT, 236 + .is_webcam = 1, /* To enable sensor probe */ 250 237 }, 251 238 [EM2750_BOARD_DLCW_130] = { 252 239 /* Beijing Huaqi Information Digital Technology Co., Ltd */ 253 240 .name = "Huaqi DLCW-130", 254 241 .valid = EM28XX_BOARD_NOT_VALIDATED, 255 242 .xclk = EM28XX_XCLK_FREQUENCY_48MHZ, 256 - .tuner_type = TUNER_ABSENT, /* This is a webcam */ 243 + .tuner_type = TUNER_ABSENT, 244 + .is_webcam = 1, 257 245 .input = { { 258 246 .type = EM28XX_VMUX_COMPOSITE1, 259 247 .vmux = 0, ··· 456 440 [EM2820_BOARD_VIDEOLOGY_20K14XUSB] = { 457 441 .name = "Videology 20K14XUSB USB2.0", 458 442 .valid = EM28XX_BOARD_NOT_VALIDATED, 459 - .tuner_type = TUNER_ABSENT, /* This is a webcam */ 443 + .tuner_type = TUNER_ABSENT, 444 + .is_webcam = 1, 460 445 .input = { { 461 446 .type = EM28XX_VMUX_COMPOSITE1, 462 447 .vmux = 0, ··· 467 450 [EM2820_BOARD_SILVERCREST_WEBCAM] = { 468 451 .name = "Silvercrest Webcam 1.3mpix", 469 452 .tuner_type = TUNER_ABSENT, 470 - .is_27xx = 1, 471 - .decoder = EM28XX_MT9V011, 453 + .is_webcam = 1, 472 454 .input = { { 473 455 .type = EM28XX_VMUX_COMPOSITE1, 474 456 .vmux = 0, ··· 516 500 /* Beijing Huaqi Information Digital Technology Co., Ltd */ 517 501 .name = "NetGMBH Cam", 518 502 .valid = EM28XX_BOARD_NOT_VALIDATED, 519 - .tuner_type = TUNER_ABSENT, /* This is a webcam */ 503 + .tuner_type = TUNER_ABSENT, 504 + .is_webcam = 1, 520 505 .input = { { 521 506 .type = EM28XX_VMUX_COMPOSITE1, 522 507 .vmux = 0, ··· 1267 1250 }, 1268 1251 [EM2881_BOARD_PINNACLE_HYBRID_PRO] = { 1269 1252 .name = "Pinnacle Hybrid Pro", 1270 - .valid = EM28XX_BOARD_NOT_VALIDATED, 1271 1253 .tuner_type = TUNER_XC2028, 1272 1254 .tuner_gpio = default_tuner_gpio, 1273 1255 .decoder = EM28XX_TVP5150, 1256 + .has_dvb = 1, 1257 + .dvb_gpio = pinnacle_hybrid_pro_digital, 1274 1258 .input = { { 1275 1259 .type = EM28XX_VMUX_TELEVISION, 1276 1260 .vmux = TVP5150_COMPOSITE0, 1277 1261 .amux = EM28XX_AMUX_VIDEO, 1278 - .gpio = default_analog, 1262 + .gpio = pinnacle_hybrid_pro_analog, 1279 1263 }, { 1280 1264 .type = EM28XX_VMUX_COMPOSITE1, 1281 1265 .vmux = TVP5150_COMPOSITE1, 1282 1266 .amux = EM28XX_AMUX_LINE_IN, 1283 - .gpio = default_analog, 1267 + .gpio = pinnacle_hybrid_pro_analog, 1284 1268 }, { 1285 1269 .type = EM28XX_VMUX_SVIDEO, 1286 1270 .vmux = TVP5150_SVIDEO, 1287 1271 .amux = EM28XX_AMUX_LINE_IN, 1288 - .gpio = default_analog, 1272 + .gpio = pinnacle_hybrid_pro_analog, 1289 1273 } }, 1290 1274 }, 1291 1275 [EM2882_BOARD_PINNACLE_HYBRID_PRO] = { ··· 1656 1638 {0x966a0441, EM2880_BOARD_KWORLD_DVB_310U, TUNER_XC2028}, 1657 1639 {0x9567eb1a, EM2880_BOARD_EMPIRE_DUAL_TV, TUNER_XC2028}, 1658 1640 {0xcee44a99, EM2882_BOARD_EVGA_INDTUBE, TUNER_XC2028}, 1641 + {0xb8846b20, EM2881_BOARD_PINNACLE_HYBRID_PRO, TUNER_XC2028}, 1659 1642 }; 1660 1643 1661 1644 /* I2C devicelist hash table for devices with generic USB IDs */ ··· 1723 1704 EM28XX_I2C_FREQ_100_KHZ; 1724 1705 } 1725 1706 1707 + /* FIXME: Should be replaced by a proper mt9m001 driver */ 1708 + static int em28xx_initialize_mt9m001(struct em28xx *dev) 1709 + { 1710 + int i; 1711 + unsigned char regs[][3] = { 1712 + { 0x0d, 0x00, 0x01, }, 1713 + { 0x0d, 0x00, 0x00, }, 1714 + { 0x04, 0x05, 0x00, }, /* hres = 1280 */ 1715 + { 0x03, 0x04, 0x00, }, /* vres = 1024 */ 1716 + { 0x20, 0x11, 0x00, }, 1717 + { 0x06, 0x00, 0x10, }, 1718 + { 0x2b, 0x00, 0x24, }, 1719 + { 0x2e, 0x00, 0x24, }, 1720 + { 0x35, 0x00, 0x24, }, 1721 + { 0x2d, 0x00, 0x20, }, 1722 + { 0x2c, 0x00, 0x20, }, 1723 + { 0x09, 0x0a, 0xd4, }, 1724 + { 0x35, 0x00, 0x57, }, 1725 + }; 1726 + 1727 + for (i = 0; i < ARRAY_SIZE(regs); i++) 1728 + i2c_master_send(&dev->i2c_client, &regs[i][0], 3); 1729 + 1730 + return 0; 1731 + } 1732 + 1726 1733 /* HINT method: webcam I2C chips 1727 1734 * 1728 1735 * This method work for webcams with Micron sensors ··· 1761 1716 __be16 version_be; 1762 1717 u16 version; 1763 1718 1764 - if (dev->model != EM2820_BOARD_UNKNOWN) 1765 - return 0; 1766 - 1767 1719 dev->i2c_client.addr = 0xba >> 1; 1768 1720 cmd = 0; 1769 1721 i2c_master_send(&dev->i2c_client, &cmd, 1); ··· 1771 1729 version = be16_to_cpu(version_be); 1772 1730 1773 1731 switch (version) { 1774 - case MT9V011_VERSION: 1732 + case 0x8243: /* mt9v011 640x480 1.3 Mpix sensor */ 1775 1733 dev->model = EM2820_BOARD_SILVERCREST_WEBCAM; 1776 1734 sensor_name = "mt9v011"; 1735 + dev->em28xx_sensor = EM28XX_MT9V011; 1736 + dev->sensor_xres = 640; 1737 + dev->sensor_yres = 480; 1738 + dev->sensor_xtal = 6300000; 1739 + 1740 + /* probably means GRGB 16 bit bayer */ 1741 + dev->vinmode = 0x0d; 1742 + dev->vinctl = 0x00; 1743 + 1744 + break; 1745 + case 0x8431: 1746 + dev->model = EM2750_BOARD_UNKNOWN; 1747 + sensor_name = "mt9m001"; 1748 + dev->em28xx_sensor = EM28XX_MT9M001; 1749 + em28xx_initialize_mt9m001(dev); 1750 + dev->sensor_xres = 1280; 1751 + dev->sensor_yres = 1024; 1752 + 1753 + /* probably means BGGR 16 bit bayer */ 1754 + dev->vinmode = 0x0c; 1755 + dev->vinctl = 0x00; 1756 + 1777 1757 break; 1778 1758 default: 1779 - printk("Unknown Sensor 0x%04x\n", be16_to_cpu(version)); 1759 + printk("Unknown Micron Sensor 0x%04x\n", be16_to_cpu(version)); 1780 1760 return -EINVAL; 1781 1761 } 1782 1762 1783 - em28xx_errdev("Sensor is %s, assuming that webcam is %s\n", 1763 + em28xx_errdev("Sensor is %s, using model %s entry.\n", 1784 1764 sensor_name, em28xx_boards[dev->model].name); 1785 1765 1786 1766 return 0; ··· 1836 1772 em28xx_info("chip ID is em2750\n"); 1837 1773 break; 1838 1774 case CHIP_ID_EM2820: 1839 - if (dev->board.is_27xx) 1840 - em28xx_info("chip is em2710\n"); 1841 - else 1842 - em28xx_info("chip ID is em2820\n"); 1775 + em28xx_info("chip ID is em2710 or em2820\n"); 1843 1776 break; 1844 1777 case CHIP_ID_EM2840: 1845 1778 em28xx_info("chip ID is em2840\n"); ··· 1990 1929 ctl->demod = XC3028_FE_ZARLINK456; 1991 1930 break; 1992 1931 case EM2880_BOARD_TERRATEC_HYBRID_XS: 1932 + case EM2881_BOARD_PINNACLE_HYBRID_PRO: 1993 1933 ctl->demod = XC3028_FE_ZARLINK456; 1994 1934 break; 1995 1935 case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2: ··· 2287 2225 em28xx_set_mode() in em28xx_pre_card_setup() was a no-op, 2288 2226 so make the call now so the analog GPIOs are set properly 2289 2227 before probing the i2c bus. */ 2228 + em28xx_gpio_set(dev, dev->board.tuner_gpio); 2290 2229 em28xx_set_mode(dev, EM28XX_ANALOG_MODE); 2291 2230 break; 2292 2231 case EM2820_BOARD_SILVERCREST_WEBCAM: ··· 2325 2262 v4l2_i2c_new_probed_subdev(&dev->v4l2_dev, &dev->i2c_adap, 2326 2263 "tvp5150", "tvp5150", tvp5150_addrs); 2327 2264 2328 - if (dev->board.decoder == EM28XX_MT9V011) 2329 - v4l2_i2c_new_probed_subdev(&dev->v4l2_dev, &dev->i2c_adap, 2330 - "mt9v011", "mt9v011", mt9v011_addrs); 2265 + if (dev->em28xx_sensor == EM28XX_MT9V011) { 2266 + struct v4l2_subdev *sd; 2267 + 2268 + sd = v4l2_i2c_new_probed_subdev(&dev->v4l2_dev, 2269 + &dev->i2c_adap, "mt9v011", "mt9v011", mt9v011_addrs); 2270 + v4l2_subdev_call(sd, core, s_config, 0, &dev->sensor_xtal); 2271 + } 2272 + 2331 2273 2332 2274 if (dev->board.adecoder == EM28XX_TVAUDIO) 2333 2275 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, ··· 2478 2410 return errCode; 2479 2411 } 2480 2412 2481 - em28xx_hint_sensor(dev); 2413 + /* 2414 + * Default format, used for tvp5150 or saa711x output formats 2415 + */ 2416 + dev->vinmode = 0x10; 2417 + dev->vinctl = 0x11; 2418 + 2419 + /* 2420 + * If the device can be a webcam, seek for a sensor. 2421 + * If sensor is not found, then it isn't a webcam. 2422 + */ 2423 + if (dev->board.is_webcam) 2424 + if (em28xx_hint_sensor(dev) < 0) 2425 + dev->board.is_webcam = 0; 2482 2426 2483 2427 /* Do board specific init and eeprom reading */ 2484 2428 em28xx_card_setup(dev);
+4 -18
drivers/media/video/em28xx/em28xx-core.c
··· 648 648 int em28xx_set_outfmt(struct em28xx *dev) 649 649 { 650 650 int ret; 651 - int vinmode, vinctl, outfmt; 652 - 653 - outfmt = dev->format->reg; 654 - 655 - if (dev->board.is_27xx) { 656 - vinmode = 0x0d; 657 - vinctl = 0x00; 658 - } else { 659 - vinmode = 0x10; 660 - vinctl = 0x11; 661 - } 662 651 663 652 ret = em28xx_write_reg_bits(dev, EM28XX_R27_OUTFMT, 664 - outfmt | 0x20, 0xff); 653 + dev->format->reg | 0x20, 0xff); 665 654 if (ret < 0) 666 655 return ret; 667 656 668 - ret = em28xx_write_reg(dev, EM28XX_R10_VINMODE, vinmode); 657 + ret = em28xx_write_reg(dev, EM28XX_R10_VINMODE, dev->vinmode); 669 658 if (ret < 0) 670 659 return ret; 671 660 672 - return em28xx_write_reg(dev, EM28XX_R11_VINCTRL, vinctl); 661 + return em28xx_write_reg(dev, EM28XX_R11_VINCTRL, dev->vinctl); 673 662 } 674 663 675 664 static int em28xx_accumulator_set(struct em28xx *dev, u8 xmin, u8 xmax, ··· 696 707 u8 mode; 697 708 /* the em2800 scaler only supports scaling down to 50% */ 698 709 699 - if (dev->board.is_27xx) { 700 - /* FIXME: Don't use the scaler yet */ 701 - mode = 0; 702 - } else if (dev->board.is_em2800) { 710 + if (dev->board.is_em2800) { 703 711 mode = (v ? 0x20 : 0x00) | (h ? 0x10 : 0x00); 704 712 } else { 705 713 u8 buf[2];
+54 -10
drivers/media/video/em28xx/em28xx-dvb.c
··· 31 31 #include "lgdt330x.h" 32 32 #include "zl10353.h" 33 33 #include "s5h1409.h" 34 + #include "mt352.h" 35 + #include "mt352_priv.h" /* FIXME */ 34 36 35 37 MODULE_DESCRIPTION("driver for em28xx based DVB cards"); 36 38 MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>"); ··· 245 243 .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK 246 244 }; 247 245 248 - static struct zl10353_config em28xx_terratec_xs_zl10353_xc3028 = { 246 + static struct zl10353_config em28xx_zl10353_xc3028_no_i2c_gate = { 249 247 .demod_address = (0x1e >> 1), 250 248 .no_tuner = 1, 251 249 .disable_i2c_gate_ctrl = 1, ··· 259 257 .demod_address = (0xe0 >> 1), 260 258 }; 261 259 #endif 260 + 261 + static int mt352_terratec_xs_init(struct dvb_frontend *fe) 262 + { 263 + /* Values extracted from a USB trace of the Terratec Windows driver */ 264 + static u8 clock_config[] = { CLOCK_CTL, 0x38, 0x2c }; 265 + static u8 reset[] = { RESET, 0x80 }; 266 + static u8 adc_ctl_1_cfg[] = { ADC_CTL_1, 0x40 }; 267 + static u8 agc_cfg[] = { AGC_TARGET, 0x28, 0xa0 }; 268 + static u8 input_freq_cfg[] = { INPUT_FREQ_1, 0x31, 0xb8 }; 269 + static u8 rs_err_cfg[] = { RS_ERR_PER_1, 0x00, 0x4d }; 270 + static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 }; 271 + static u8 trl_nom_cfg[] = { TRL_NOMINAL_RATE_1, 0x64, 0x00 }; 272 + static u8 tps_given_cfg[] = { TPS_GIVEN_1, 0x40, 0x80, 0x50 }; 273 + static u8 tuner_go[] = { TUNER_GO, 0x01}; 274 + 275 + mt352_write(fe, clock_config, sizeof(clock_config)); 276 + udelay(200); 277 + mt352_write(fe, reset, sizeof(reset)); 278 + mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg)); 279 + mt352_write(fe, agc_cfg, sizeof(agc_cfg)); 280 + mt352_write(fe, input_freq_cfg, sizeof(input_freq_cfg)); 281 + mt352_write(fe, rs_err_cfg, sizeof(rs_err_cfg)); 282 + mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg)); 283 + mt352_write(fe, trl_nom_cfg, sizeof(trl_nom_cfg)); 284 + mt352_write(fe, tps_given_cfg, sizeof(tps_given_cfg)); 285 + mt352_write(fe, tuner_go, sizeof(tuner_go)); 286 + return 0; 287 + } 288 + 289 + static struct mt352_config terratec_xs_mt352_cfg = { 290 + .demod_address = (0x1e >> 1), 291 + .no_tuner = 1, 292 + .if2 = 45600, 293 + .demod_init = mt352_terratec_xs_init, 294 + }; 262 295 263 296 /* ------------------------------------------------------------------ */ 264 297 ··· 477 440 goto out_free; 478 441 } 479 442 break; 480 - case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: 481 443 case EM2880_BOARD_KWORLD_DVB_310U: 482 444 case EM2880_BOARD_EMPIRE_DUAL_TV: 483 445 dvb->frontend = dvb_attach(zl10353_attach, ··· 487 451 goto out_free; 488 452 } 489 453 break; 490 - case EM2880_BOARD_TERRATEC_HYBRID_XS: 454 + case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: 491 455 dvb->frontend = dvb_attach(zl10353_attach, 492 - &em28xx_terratec_xs_zl10353_xc3028, 456 + &em28xx_zl10353_xc3028_no_i2c_gate, 457 + &dev->i2c_adap); 458 + if (attach_xc3028(0x61, dev) < 0) { 459 + result = -EINVAL; 460 + goto out_free; 461 + } 462 + break; 463 + case EM2880_BOARD_TERRATEC_HYBRID_XS: 464 + case EM2881_BOARD_PINNACLE_HYBRID_PRO: 465 + dvb->frontend = dvb_attach(zl10353_attach, 466 + &em28xx_zl10353_xc3028_no_i2c_gate, 493 467 &dev->i2c_adap); 494 468 if (dvb->frontend == NULL) { 495 469 /* This board could have either a zl10353 or a mt352. 496 470 If the chip id isn't for zl10353, try mt352 */ 497 - 498 - /* FIXME: make support for mt352 work */ 499 - printk(KERN_ERR "version of this board with mt352 not " 500 - "currently supported\n"); 501 - result = -EINVAL; 502 - goto out_free; 471 + dvb->frontend = dvb_attach(mt352_attach, 472 + &terratec_xs_mt352_cfg, 473 + &dev->i2c_adap); 503 474 } 475 + 504 476 if (attach_xc3028(0x61, dev) < 0) { 505 477 result = -EINVAL; 506 478 goto out_free;
+3 -13
drivers/media/video/em28xx/em28xx-video.c
··· 657 657 unsigned int width, unsigned int height, 658 658 unsigned int *hscale, unsigned int *vscale) 659 659 { 660 - unsigned int maxw = norm_maxw(dev); 661 - unsigned int maxh = norm_maxh(dev); 660 + unsigned int maxw = norm_maxw(dev); 661 + unsigned int maxh = norm_maxh(dev); 662 662 663 663 *hscale = (((unsigned long)maxw) << 12) / width - 4096L; 664 664 if (*hscale >= 0x4000) ··· 726 726 return -EINVAL; 727 727 } 728 728 729 - if (dev->board.is_27xx) { 730 - /* FIXME: This is the only supported fmt */ 731 - width = 640; 732 - height = 480; 733 - } else if (dev->board.is_em2800) { 729 + if (dev->board.is_em2800) { 734 730 /* the em2800 can only scale down to 50% */ 735 731 height = height > (3 * maxh / 4) ? maxh : maxh / 2; 736 732 width = width > (3 * maxw / 4) ? maxw : maxw / 2; ··· 762 766 unsigned width, unsigned height) 763 767 { 764 768 struct em28xx_fmt *fmt; 765 - 766 - /* FIXME: This is the only supported fmt */ 767 - if (dev->board.is_27xx) { 768 - width = 640; 769 - height = 480; 770 - } 771 769 772 770 fmt = format_by_fourcc(fourcc); 773 771 if (!fmt)
+25 -6
drivers/media/video/em28xx/em28xx.h
··· 358 358 #define INPUT(nr) (&em28xx_boards[dev->model].input[nr]) 359 359 360 360 enum em28xx_decoder { 361 - EM28XX_NODECODER, 361 + EM28XX_NODECODER = 0, 362 362 EM28XX_TVP5150, 363 363 EM28XX_SAA711X, 364 + }; 365 + 366 + enum em28xx_sensor { 367 + EM28XX_NOSENSOR = 0, 364 368 EM28XX_MT9V011, 369 + EM28XX_MT9M001, 365 370 }; 366 371 367 372 enum em28xx_adecoder { ··· 395 390 unsigned int max_range_640_480:1; 396 391 unsigned int has_dvb:1; 397 392 unsigned int has_snapshot_button:1; 398 - unsigned int is_27xx:1; 393 + unsigned int is_webcam:1; 399 394 unsigned int valid:1; 400 395 401 396 unsigned char xclk, i2c_speed; ··· 478 473 479 474 struct v4l2_device v4l2_dev; 480 475 struct em28xx_board board; 476 + 477 + /* Webcam specific fields */ 478 + enum em28xx_sensor em28xx_sensor; 479 + int sensor_xres, sensor_yres; 480 + int sensor_xtal; 481 + 482 + /* Vinmode/Vinctl used at the driver */ 483 + int vinmode, vinctl; 481 484 482 485 unsigned int stream_on:1; /* Locks streams */ 483 486 unsigned int has_audio_class:1; ··· 767 754 /*FIXME: maxw should be dependent of alt mode */ 768 755 static inline unsigned int norm_maxw(struct em28xx *dev) 769 756 { 757 + if (dev->board.is_webcam) 758 + return dev->sensor_xres; 759 + 770 760 if (dev->board.max_range_640_480) 771 761 return 640; 772 - else 773 - return 720; 762 + 763 + return 720; 774 764 } 775 765 776 766 static inline unsigned int norm_maxh(struct em28xx *dev) 777 767 { 768 + if (dev->board.is_webcam) 769 + return dev->sensor_yres; 770 + 778 771 if (dev->board.max_range_640_480) 779 772 return 480; 780 - else 781 - return (dev->norm & V4L2_STD_625_50) ? 576 : 480; 773 + 774 + return (dev->norm & V4L2_STD_625_50) ? 576 : 480; 782 775 } 783 776 #endif
+16
drivers/media/video/gspca/Kconfig
··· 102 102 To compile this driver as a module, choose M here: the 103 103 module will be called gspca_pac7311. 104 104 105 + config USB_GSPCA_SN9C20X 106 + tristate "SN9C20X USB Camera Driver" 107 + depends on VIDEO_V4L2 && USB_GSPCA 108 + help 109 + Say Y here if you want support for cameras based on the 110 + sn9c20x chips (SN9C201 and SN9C202). 111 + 112 + To compile this driver as a module, choose M here: the 113 + module will be called gspca_sn9c20x. 114 + 115 + config USB_GSPCA_SN9C20X_EVDEV 116 + bool "Enable evdev support" 117 + depends on USB_GSPCA_SN9C20X 118 + ---help--- 119 + Say Y here in order to enable evdev support for sn9c20x webcam button. 120 + 105 121 config USB_GSPCA_SONIXB 106 122 tristate "SONIX Bayer USB Camera Driver" 107 123 depends on VIDEO_V4L2 && USB_GSPCA
+2
drivers/media/video/gspca/Makefile
··· 8 8 obj-$(CONFIG_USB_GSPCA_OV534) += gspca_ov534.o 9 9 obj-$(CONFIG_USB_GSPCA_PAC207) += gspca_pac207.o 10 10 obj-$(CONFIG_USB_GSPCA_PAC7311) += gspca_pac7311.o 11 + obj-$(CONFIG_USB_GSPCA_SN9C20X) += gspca_sn9c20x.o 11 12 obj-$(CONFIG_USB_GSPCA_SONIXB) += gspca_sonixb.o 12 13 obj-$(CONFIG_USB_GSPCA_SONIXJ) += gspca_sonixj.o 13 14 obj-$(CONFIG_USB_GSPCA_SPCA500) += gspca_spca500.o ··· 36 35 gspca_ov534-objs := ov534.o 37 36 gspca_pac207-objs := pac207.o 38 37 gspca_pac7311-objs := pac7311.o 38 + gspca_sn9c20x-objs := sn9c20x.o 39 39 gspca_sonixb-objs := sonixb.o 40 40 gspca_sonixj-objs := sonixj.o 41 41 gspca_spca500-objs := spca500.o
+2
drivers/media/video/gspca/conex.c
··· 846 846 847 847 /* create the JPEG header */ 848 848 sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); 849 + if (!sd->jpeg_hdr) 850 + return -ENOMEM; 849 851 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, 850 852 0x22); /* JPEG 411 */ 851 853 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+73
drivers/media/video/gspca/gspca.c
··· 727 727 return -EINVAL; 728 728 } 729 729 730 + #ifdef CONFIG_VIDEO_ADV_DEBUG 731 + static int vidioc_g_register(struct file *file, void *priv, 732 + struct v4l2_dbg_register *reg) 733 + { 734 + int ret; 735 + struct gspca_dev *gspca_dev = priv; 736 + 737 + if (!gspca_dev->sd_desc->get_chip_ident) 738 + return -EINVAL; 739 + 740 + if (!gspca_dev->sd_desc->get_register) 741 + return -EINVAL; 742 + 743 + if (mutex_lock_interruptible(&gspca_dev->usb_lock)) 744 + return -ERESTARTSYS; 745 + if (gspca_dev->present) 746 + ret = gspca_dev->sd_desc->get_register(gspca_dev, reg); 747 + else 748 + ret = -ENODEV; 749 + mutex_unlock(&gspca_dev->usb_lock); 750 + 751 + return ret; 752 + } 753 + 754 + static int vidioc_s_register(struct file *file, void *priv, 755 + struct v4l2_dbg_register *reg) 756 + { 757 + int ret; 758 + struct gspca_dev *gspca_dev = priv; 759 + 760 + if (!gspca_dev->sd_desc->get_chip_ident) 761 + return -EINVAL; 762 + 763 + if (!gspca_dev->sd_desc->set_register) 764 + return -EINVAL; 765 + 766 + if (mutex_lock_interruptible(&gspca_dev->usb_lock)) 767 + return -ERESTARTSYS; 768 + if (gspca_dev->present) 769 + ret = gspca_dev->sd_desc->set_register(gspca_dev, reg); 770 + else 771 + ret = -ENODEV; 772 + mutex_unlock(&gspca_dev->usb_lock); 773 + 774 + return ret; 775 + } 776 + #endif 777 + 778 + static int vidioc_g_chip_ident(struct file *file, void *priv, 779 + struct v4l2_dbg_chip_ident *chip) 780 + { 781 + int ret; 782 + struct gspca_dev *gspca_dev = priv; 783 + 784 + if (!gspca_dev->sd_desc->get_chip_ident) 785 + return -EINVAL; 786 + 787 + if (mutex_lock_interruptible(&gspca_dev->usb_lock)) 788 + return -ERESTARTSYS; 789 + if (gspca_dev->present) 790 + ret = gspca_dev->sd_desc->get_chip_ident(gspca_dev, chip); 791 + else 792 + ret = -ENODEV; 793 + mutex_unlock(&gspca_dev->usb_lock); 794 + 795 + return ret; 796 + } 797 + 730 798 static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, 731 799 struct v4l2_fmtdesc *fmtdesc) 732 800 { ··· 1951 1883 .vidioc_s_parm = vidioc_s_parm, 1952 1884 .vidioc_s_std = vidioc_s_std, 1953 1885 .vidioc_enum_framesizes = vidioc_enum_framesizes, 1886 + #ifdef CONFIG_VIDEO_ADV_DEBUG 1887 + .vidioc_g_register = vidioc_g_register, 1888 + .vidioc_s_register = vidioc_s_register, 1889 + #endif 1890 + .vidioc_g_chip_ident = vidioc_g_chip_ident, 1954 1891 #ifdef CONFIG_VIDEO_V4L1_COMPAT 1955 1892 .vidiocgmbuf = vidiocgmbuf, 1956 1893 #endif
+9
drivers/media/video/gspca/gspca.h
··· 69 69 typedef int (*cam_cf_op) (struct gspca_dev *, const struct usb_device_id *); 70 70 typedef int (*cam_jpg_op) (struct gspca_dev *, 71 71 struct v4l2_jpegcompression *); 72 + typedef int (*cam_reg_op) (struct gspca_dev *, 73 + struct v4l2_dbg_register *); 74 + typedef int (*cam_ident_op) (struct gspca_dev *, 75 + struct v4l2_dbg_chip_ident *); 72 76 typedef int (*cam_streamparm_op) (struct gspca_dev *, 73 77 struct v4l2_streamparm *); 74 78 typedef int (*cam_qmnu_op) (struct gspca_dev *, ··· 109 105 cam_qmnu_op querymenu; 110 106 cam_streamparm_op get_streamparm; 111 107 cam_streamparm_op set_streamparm; 108 + #ifdef CONFIG_VIDEO_ADV_DEBUG 109 + cam_reg_op set_register; 110 + cam_reg_op get_register; 111 + #endif 112 + cam_ident_op get_chip_ident; 112 113 }; 113 114 114 115 /* packet types when moving from iso buf to frame buf */
-6
drivers/media/video/gspca/m5602/m5602_s5k4aa.c
··· 476 476 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); 477 477 if (err < 0) 478 478 return err; 479 - err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); 480 - if (err < 0) 481 - return err; 482 479 483 480 err = m5602_read_sensor(sd, S5K4AA_READ_MODE, &data, 1); 484 481 if (err < 0) ··· 519 522 520 523 PDEBUG(D_V4L2, "Set horizontal flip to %d", val); 521 524 err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); 522 - if (err < 0) 523 - return err; 524 - err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); 525 525 if (err < 0) 526 526 return err; 527 527
+2
drivers/media/video/gspca/mars.c
··· 201 201 202 202 /* create the JPEG header */ 203 203 sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); 204 + if (!sd->jpeg_hdr) 205 + return -ENOMEM; 204 206 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, 205 207 0x21); /* JPEG 422 */ 206 208 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+2434
drivers/media/video/gspca/sn9c20x.c
··· 1 + /* 2 + * Sonix sn9c201 sn9c202 library 3 + * Copyright (C) 2008-2009 microdia project <microdia@googlegroups.com> 4 + * Copyright (C) 2009 Brian Johnson <brijohn@gmail.com> 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License as published by 8 + * the Free Software Foundation; either version 2 of the License, or 9 + * any later version. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + * 16 + * You should have received a copy of the GNU General Public License 17 + * along with this program; if not, write to the Free Software 18 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 + */ 20 + 21 + #ifdef CONFIG_USB_GSPCA_SN9C20X_EVDEV 22 + #include <linux/kthread.h> 23 + #include <linux/freezer.h> 24 + #include <linux/usb/input.h> 25 + #include <linux/input.h> 26 + #endif 27 + 28 + #include "gspca.h" 29 + #include "jpeg.h" 30 + 31 + #include <media/v4l2-chip-ident.h> 32 + 33 + MODULE_AUTHOR("Brian Johnson <brijohn@gmail.com>, " 34 + "microdia project <microdia@googlegroups.com>"); 35 + MODULE_DESCRIPTION("GSPCA/SN9C20X USB Camera Driver"); 36 + MODULE_LICENSE("GPL"); 37 + 38 + #define MODULE_NAME "sn9c20x" 39 + 40 + #define MODE_RAW 0x10 41 + #define MODE_JPEG 0x20 42 + #define MODE_SXGA 0x80 43 + 44 + #define SENSOR_OV9650 0 45 + #define SENSOR_OV9655 1 46 + #define SENSOR_SOI968 2 47 + #define SENSOR_OV7660 3 48 + #define SENSOR_OV7670 4 49 + #define SENSOR_MT9V011 5 50 + #define SENSOR_MT9V111 6 51 + #define SENSOR_MT9V112 7 52 + #define SENSOR_MT9M001 8 53 + #define SENSOR_MT9M111 9 54 + #define SENSOR_HV7131R 10 55 + #define SENSOR_MT9VPRB 20 56 + 57 + /* specific webcam descriptor */ 58 + struct sd { 59 + struct gspca_dev gspca_dev; 60 + 61 + #define MIN_AVG_LUM 80 62 + #define MAX_AVG_LUM 130 63 + atomic_t avg_lum; 64 + u8 old_step; 65 + u8 older_step; 66 + u8 exposure_step; 67 + 68 + u8 brightness; 69 + u8 contrast; 70 + u8 saturation; 71 + s16 hue; 72 + u8 gamma; 73 + u8 red; 74 + u8 blue; 75 + 76 + u8 hflip; 77 + u8 vflip; 78 + u8 gain; 79 + u16 exposure; 80 + u8 auto_exposure; 81 + 82 + u8 i2c_addr; 83 + u8 sensor; 84 + u8 hstart; 85 + u8 vstart; 86 + 87 + u8 *jpeg_hdr; 88 + u8 quality; 89 + 90 + #ifdef CONFIG_USB_GSPCA_SN9C20X_EVDEV 91 + struct input_dev *input_dev; 92 + u8 input_gpio; 93 + struct task_struct *input_task; 94 + #endif 95 + }; 96 + 97 + static int sd_setbrightness(struct gspca_dev *gspca_dev, s32 val); 98 + static int sd_getbrightness(struct gspca_dev *gspca_dev, s32 *val); 99 + static int sd_setcontrast(struct gspca_dev *gspca_dev, s32 val); 100 + static int sd_getcontrast(struct gspca_dev *gspca_dev, s32 *val); 101 + static int sd_setsaturation(struct gspca_dev *gspca_dev, s32 val); 102 + static int sd_getsaturation(struct gspca_dev *gspca_dev, s32 *val); 103 + static int sd_sethue(struct gspca_dev *gspca_dev, s32 val); 104 + static int sd_gethue(struct gspca_dev *gspca_dev, s32 *val); 105 + static int sd_setgamma(struct gspca_dev *gspca_dev, s32 val); 106 + static int sd_getgamma(struct gspca_dev *gspca_dev, s32 *val); 107 + static int sd_setredbalance(struct gspca_dev *gspca_dev, s32 val); 108 + static int sd_getredbalance(struct gspca_dev *gspca_dev, s32 *val); 109 + static int sd_setbluebalance(struct gspca_dev *gspca_dev, s32 val); 110 + static int sd_getbluebalance(struct gspca_dev *gspca_dev, s32 *val); 111 + static int sd_setvflip(struct gspca_dev *gspca_dev, s32 val); 112 + static int sd_getvflip(struct gspca_dev *gspca_dev, s32 *val); 113 + static int sd_sethflip(struct gspca_dev *gspca_dev, s32 val); 114 + static int sd_gethflip(struct gspca_dev *gspca_dev, s32 *val); 115 + static int sd_setgain(struct gspca_dev *gspca_dev, s32 val); 116 + static int sd_getgain(struct gspca_dev *gspca_dev, s32 *val); 117 + static int sd_setexposure(struct gspca_dev *gspca_dev, s32 val); 118 + static int sd_getexposure(struct gspca_dev *gspca_dev, s32 *val); 119 + static int sd_setautoexposure(struct gspca_dev *gspca_dev, s32 val); 120 + static int sd_getautoexposure(struct gspca_dev *gspca_dev, s32 *val); 121 + 122 + static struct ctrl sd_ctrls[] = { 123 + { 124 + #define BRIGHTNESS_IDX 0 125 + { 126 + .id = V4L2_CID_BRIGHTNESS, 127 + .type = V4L2_CTRL_TYPE_INTEGER, 128 + .name = "Brightness", 129 + .minimum = 0, 130 + .maximum = 0xff, 131 + .step = 1, 132 + #define BRIGHTNESS_DEFAULT 0x7f 133 + .default_value = BRIGHTNESS_DEFAULT, 134 + }, 135 + .set = sd_setbrightness, 136 + .get = sd_getbrightness, 137 + }, 138 + { 139 + #define CONTRAST_IDX 1 140 + { 141 + .id = V4L2_CID_CONTRAST, 142 + .type = V4L2_CTRL_TYPE_INTEGER, 143 + .name = "Contrast", 144 + .minimum = 0, 145 + .maximum = 0xff, 146 + .step = 1, 147 + #define CONTRAST_DEFAULT 0x7f 148 + .default_value = CONTRAST_DEFAULT, 149 + }, 150 + .set = sd_setcontrast, 151 + .get = sd_getcontrast, 152 + }, 153 + { 154 + #define SATURATION_IDX 2 155 + { 156 + .id = V4L2_CID_SATURATION, 157 + .type = V4L2_CTRL_TYPE_INTEGER, 158 + .name = "Saturation", 159 + .minimum = 0, 160 + .maximum = 0xff, 161 + .step = 1, 162 + #define SATURATION_DEFAULT 0x7f 163 + .default_value = SATURATION_DEFAULT, 164 + }, 165 + .set = sd_setsaturation, 166 + .get = sd_getsaturation, 167 + }, 168 + { 169 + #define HUE_IDX 3 170 + { 171 + .id = V4L2_CID_HUE, 172 + .type = V4L2_CTRL_TYPE_INTEGER, 173 + .name = "Hue", 174 + .minimum = -180, 175 + .maximum = 180, 176 + .step = 1, 177 + #define HUE_DEFAULT 0 178 + .default_value = HUE_DEFAULT, 179 + }, 180 + .set = sd_sethue, 181 + .get = sd_gethue, 182 + }, 183 + { 184 + #define GAMMA_IDX 4 185 + { 186 + .id = V4L2_CID_GAMMA, 187 + .type = V4L2_CTRL_TYPE_INTEGER, 188 + .name = "Gamma", 189 + .minimum = 0, 190 + .maximum = 0xff, 191 + .step = 1, 192 + #define GAMMA_DEFAULT 0x10 193 + .default_value = GAMMA_DEFAULT, 194 + }, 195 + .set = sd_setgamma, 196 + .get = sd_getgamma, 197 + }, 198 + { 199 + #define BLUE_IDX 5 200 + { 201 + .id = V4L2_CID_BLUE_BALANCE, 202 + .type = V4L2_CTRL_TYPE_INTEGER, 203 + .name = "Blue Balance", 204 + .minimum = 0, 205 + .maximum = 0x7f, 206 + .step = 1, 207 + #define BLUE_DEFAULT 0x28 208 + .default_value = BLUE_DEFAULT, 209 + }, 210 + .set = sd_setbluebalance, 211 + .get = sd_getbluebalance, 212 + }, 213 + { 214 + #define RED_IDX 6 215 + { 216 + .id = V4L2_CID_RED_BALANCE, 217 + .type = V4L2_CTRL_TYPE_INTEGER, 218 + .name = "Red Balance", 219 + .minimum = 0, 220 + .maximum = 0x7f, 221 + .step = 1, 222 + #define RED_DEFAULT 0x28 223 + .default_value = RED_DEFAULT, 224 + }, 225 + .set = sd_setredbalance, 226 + .get = sd_getredbalance, 227 + }, 228 + { 229 + #define HFLIP_IDX 7 230 + { 231 + .id = V4L2_CID_HFLIP, 232 + .type = V4L2_CTRL_TYPE_BOOLEAN, 233 + .name = "Horizontal Flip", 234 + .minimum = 0, 235 + .maximum = 1, 236 + .step = 1, 237 + #define HFLIP_DEFAULT 0 238 + .default_value = HFLIP_DEFAULT, 239 + }, 240 + .set = sd_sethflip, 241 + .get = sd_gethflip, 242 + }, 243 + { 244 + #define VFLIP_IDX 8 245 + { 246 + .id = V4L2_CID_VFLIP, 247 + .type = V4L2_CTRL_TYPE_BOOLEAN, 248 + .name = "Vertical Flip", 249 + .minimum = 0, 250 + .maximum = 1, 251 + .step = 1, 252 + #define VFLIP_DEFAULT 0 253 + .default_value = VFLIP_DEFAULT, 254 + }, 255 + .set = sd_setvflip, 256 + .get = sd_getvflip, 257 + }, 258 + { 259 + #define EXPOSURE_IDX 9 260 + { 261 + .id = V4L2_CID_EXPOSURE, 262 + .type = V4L2_CTRL_TYPE_INTEGER, 263 + .name = "Exposure", 264 + .minimum = 0, 265 + .maximum = 0x1780, 266 + .step = 1, 267 + #define EXPOSURE_DEFAULT 0x33 268 + .default_value = EXPOSURE_DEFAULT, 269 + }, 270 + .set = sd_setexposure, 271 + .get = sd_getexposure, 272 + }, 273 + { 274 + #define GAIN_IDX 10 275 + { 276 + .id = V4L2_CID_GAIN, 277 + .type = V4L2_CTRL_TYPE_INTEGER, 278 + .name = "Gain", 279 + .minimum = 0, 280 + .maximum = 28, 281 + .step = 1, 282 + #define GAIN_DEFAULT 0x00 283 + .default_value = GAIN_DEFAULT, 284 + }, 285 + .set = sd_setgain, 286 + .get = sd_getgain, 287 + }, 288 + { 289 + #define AUTOGAIN_IDX 11 290 + { 291 + .id = V4L2_CID_AUTOGAIN, 292 + .type = V4L2_CTRL_TYPE_BOOLEAN, 293 + .name = "Auto Exposure", 294 + .minimum = 0, 295 + .maximum = 1, 296 + .step = 1, 297 + #define AUTO_EXPOSURE_DEFAULT 1 298 + .default_value = AUTO_EXPOSURE_DEFAULT, 299 + }, 300 + .set = sd_setautoexposure, 301 + .get = sd_getautoexposure, 302 + }, 303 + }; 304 + 305 + static const struct v4l2_pix_format vga_mode[] = { 306 + {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 307 + .bytesperline = 240, 308 + .sizeimage = 240 * 120, 309 + .colorspace = V4L2_COLORSPACE_JPEG, 310 + .priv = 0 | MODE_JPEG}, 311 + {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 312 + .bytesperline = 160, 313 + .sizeimage = 160 * 120, 314 + .colorspace = V4L2_COLORSPACE_SRGB, 315 + .priv = 0 | MODE_RAW}, 316 + {160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE, 317 + .bytesperline = 240, 318 + .sizeimage = 240 * 120, 319 + .colorspace = V4L2_COLORSPACE_SRGB, 320 + .priv = 0}, 321 + {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 322 + .bytesperline = 480, 323 + .sizeimage = 480 * 240 , 324 + .colorspace = V4L2_COLORSPACE_JPEG, 325 + .priv = 1 | MODE_JPEG}, 326 + {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 327 + .bytesperline = 320, 328 + .sizeimage = 320 * 240 , 329 + .colorspace = V4L2_COLORSPACE_SRGB, 330 + .priv = 1 | MODE_RAW}, 331 + {320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE, 332 + .bytesperline = 480, 333 + .sizeimage = 480 * 240 , 334 + .colorspace = V4L2_COLORSPACE_SRGB, 335 + .priv = 1}, 336 + {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 337 + .bytesperline = 960, 338 + .sizeimage = 960 * 480, 339 + .colorspace = V4L2_COLORSPACE_JPEG, 340 + .priv = 2 | MODE_JPEG}, 341 + {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 342 + .bytesperline = 640, 343 + .sizeimage = 640 * 480, 344 + .colorspace = V4L2_COLORSPACE_SRGB, 345 + .priv = 2 | MODE_RAW}, 346 + {640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE, 347 + .bytesperline = 960, 348 + .sizeimage = 960 * 480, 349 + .colorspace = V4L2_COLORSPACE_SRGB, 350 + .priv = 2}, 351 + }; 352 + 353 + static const struct v4l2_pix_format sxga_mode[] = { 354 + {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 355 + .bytesperline = 240, 356 + .sizeimage = 240 * 120, 357 + .colorspace = V4L2_COLORSPACE_JPEG, 358 + .priv = 0 | MODE_JPEG}, 359 + {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 360 + .bytesperline = 160, 361 + .sizeimage = 160 * 120, 362 + .colorspace = V4L2_COLORSPACE_SRGB, 363 + .priv = 0 | MODE_RAW}, 364 + {160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE, 365 + .bytesperline = 240, 366 + .sizeimage = 240 * 120, 367 + .colorspace = V4L2_COLORSPACE_SRGB, 368 + .priv = 0}, 369 + {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 370 + .bytesperline = 480, 371 + .sizeimage = 480 * 240 , 372 + .colorspace = V4L2_COLORSPACE_JPEG, 373 + .priv = 1 | MODE_JPEG}, 374 + {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 375 + .bytesperline = 320, 376 + .sizeimage = 320 * 240 , 377 + .colorspace = V4L2_COLORSPACE_SRGB, 378 + .priv = 1 | MODE_RAW}, 379 + {320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE, 380 + .bytesperline = 480, 381 + .sizeimage = 480 * 240 , 382 + .colorspace = V4L2_COLORSPACE_SRGB, 383 + .priv = 1}, 384 + {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 385 + .bytesperline = 960, 386 + .sizeimage = 960 * 480, 387 + .colorspace = V4L2_COLORSPACE_JPEG, 388 + .priv = 2 | MODE_JPEG}, 389 + {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 390 + .bytesperline = 640, 391 + .sizeimage = 640 * 480, 392 + .colorspace = V4L2_COLORSPACE_SRGB, 393 + .priv = 2 | MODE_RAW}, 394 + {640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE, 395 + .bytesperline = 960, 396 + .sizeimage = 960 * 480, 397 + .colorspace = V4L2_COLORSPACE_SRGB, 398 + .priv = 2}, 399 + {1280, 1024, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 400 + .bytesperline = 1280, 401 + .sizeimage = (1280 * 1024) + 64, 402 + .colorspace = V4L2_COLORSPACE_SRGB, 403 + .priv = 3 | MODE_RAW | MODE_SXGA}, 404 + }; 405 + 406 + static const int hsv_red_x[] = { 407 + 41, 44, 46, 48, 50, 52, 54, 56, 408 + 58, 60, 62, 64, 66, 68, 70, 72, 409 + 74, 76, 78, 80, 81, 83, 85, 87, 410 + 88, 90, 92, 93, 95, 97, 98, 100, 411 + 101, 102, 104, 105, 107, 108, 109, 110, 412 + 112, 113, 114, 115, 116, 117, 118, 119, 413 + 120, 121, 122, 123, 123, 124, 125, 125, 414 + 126, 127, 127, 128, 128, 129, 129, 129, 415 + 130, 130, 130, 130, 131, 131, 131, 131, 416 + 131, 131, 131, 131, 130, 130, 130, 130, 417 + 129, 129, 129, 128, 128, 127, 127, 126, 418 + 125, 125, 124, 123, 122, 122, 121, 120, 419 + 119, 118, 117, 116, 115, 114, 112, 111, 420 + 110, 109, 107, 106, 105, 103, 102, 101, 421 + 99, 98, 96, 94, 93, 91, 90, 88, 422 + 86, 84, 83, 81, 79, 77, 75, 74, 423 + 72, 70, 68, 66, 64, 62, 60, 58, 424 + 56, 54, 52, 49, 47, 45, 43, 41, 425 + 39, 36, 34, 32, 30, 28, 25, 23, 426 + 21, 19, 16, 14, 12, 9, 7, 5, 427 + 3, 0, -1, -3, -6, -8, -10, -12, 428 + -15, -17, -19, -22, -24, -26, -28, -30, 429 + -33, -35, -37, -39, -41, -44, -46, -48, 430 + -50, -52, -54, -56, -58, -60, -62, -64, 431 + -66, -68, -70, -72, -74, -76, -78, -80, 432 + -81, -83, -85, -87, -88, -90, -92, -93, 433 + -95, -97, -98, -100, -101, -102, -104, -105, 434 + -107, -108, -109, -110, -112, -113, -114, -115, 435 + -116, -117, -118, -119, -120, -121, -122, -123, 436 + -123, -124, -125, -125, -126, -127, -127, -128, 437 + -128, -128, -128, -128, -128, -128, -128, -128, 438 + -128, -128, -128, -128, -128, -128, -128, -128, 439 + -128, -128, -128, -128, -128, -128, -128, -128, 440 + -128, -127, -127, -126, -125, -125, -124, -123, 441 + -122, -122, -121, -120, -119, -118, -117, -116, 442 + -115, -114, -112, -111, -110, -109, -107, -106, 443 + -105, -103, -102, -101, -99, -98, -96, -94, 444 + -93, -91, -90, -88, -86, -84, -83, -81, 445 + -79, -77, -75, -74, -72, -70, -68, -66, 446 + -64, -62, -60, -58, -56, -54, -52, -49, 447 + -47, -45, -43, -41, -39, -36, -34, -32, 448 + -30, -28, -25, -23, -21, -19, -16, -14, 449 + -12, -9, -7, -5, -3, 0, 1, 3, 450 + 6, 8, 10, 12, 15, 17, 19, 22, 451 + 24, 26, 28, 30, 33, 35, 37, 39, 41 452 + }; 453 + 454 + static const int hsv_red_y[] = { 455 + 82, 80, 78, 76, 74, 73, 71, 69, 456 + 67, 65, 63, 61, 58, 56, 54, 52, 457 + 50, 48, 46, 44, 41, 39, 37, 35, 458 + 32, 30, 28, 26, 23, 21, 19, 16, 459 + 14, 12, 10, 7, 5, 3, 0, -1, 460 + -3, -6, -8, -10, -13, -15, -17, -19, 461 + -22, -24, -26, -29, -31, -33, -35, -38, 462 + -40, -42, -44, -46, -48, -51, -53, -55, 463 + -57, -59, -61, -63, -65, -67, -69, -71, 464 + -73, -75, -77, -79, -81, -82, -84, -86, 465 + -88, -89, -91, -93, -94, -96, -98, -99, 466 + -101, -102, -104, -105, -106, -108, -109, -110, 467 + -112, -113, -114, -115, -116, -117, -119, -120, 468 + -120, -121, -122, -123, -124, -125, -126, -126, 469 + -127, -128, -128, -128, -128, -128, -128, -128, 470 + -128, -128, -128, -128, -128, -128, -128, -128, 471 + -128, -128, -128, -128, -128, -128, -128, -128, 472 + -128, -128, -128, -128, -128, -128, -128, -128, 473 + -127, -127, -126, -125, -125, -124, -123, -122, 474 + -121, -120, -119, -118, -117, -116, -115, -114, 475 + -113, -111, -110, -109, -107, -106, -105, -103, 476 + -102, -100, -99, -97, -96, -94, -92, -91, 477 + -89, -87, -85, -84, -82, -80, -78, -76, 478 + -74, -73, -71, -69, -67, -65, -63, -61, 479 + -58, -56, -54, -52, -50, -48, -46, -44, 480 + -41, -39, -37, -35, -32, -30, -28, -26, 481 + -23, -21, -19, -16, -14, -12, -10, -7, 482 + -5, -3, 0, 1, 3, 6, 8, 10, 483 + 13, 15, 17, 19, 22, 24, 26, 29, 484 + 31, 33, 35, 38, 40, 42, 44, 46, 485 + 48, 51, 53, 55, 57, 59, 61, 63, 486 + 65, 67, 69, 71, 73, 75, 77, 79, 487 + 81, 82, 84, 86, 88, 89, 91, 93, 488 + 94, 96, 98, 99, 101, 102, 104, 105, 489 + 106, 108, 109, 110, 112, 113, 114, 115, 490 + 116, 117, 119, 120, 120, 121, 122, 123, 491 + 124, 125, 126, 126, 127, 128, 128, 129, 492 + 129, 130, 130, 131, 131, 131, 131, 132, 493 + 132, 132, 132, 132, 132, 132, 132, 132, 494 + 132, 132, 132, 131, 131, 131, 130, 130, 495 + 130, 129, 129, 128, 127, 127, 126, 125, 496 + 125, 124, 123, 122, 121, 120, 119, 118, 497 + 117, 116, 115, 114, 113, 111, 110, 109, 498 + 107, 106, 105, 103, 102, 100, 99, 97, 499 + 96, 94, 92, 91, 89, 87, 85, 84, 82 500 + }; 501 + 502 + static const int hsv_green_x[] = { 503 + -124, -124, -125, -125, -125, -125, -125, -125, 504 + -125, -126, -126, -125, -125, -125, -125, -125, 505 + -125, -124, -124, -124, -123, -123, -122, -122, 506 + -121, -121, -120, -120, -119, -118, -117, -117, 507 + -116, -115, -114, -113, -112, -111, -110, -109, 508 + -108, -107, -105, -104, -103, -102, -100, -99, 509 + -98, -96, -95, -93, -92, -91, -89, -87, 510 + -86, -84, -83, -81, -79, -77, -76, -74, 511 + -72, -70, -69, -67, -65, -63, -61, -59, 512 + -57, -55, -53, -51, -49, -47, -45, -43, 513 + -41, -39, -37, -35, -33, -30, -28, -26, 514 + -24, -22, -20, -18, -15, -13, -11, -9, 515 + -7, -4, -2, 0, 1, 3, 6, 8, 516 + 10, 12, 14, 17, 19, 21, 23, 25, 517 + 27, 29, 32, 34, 36, 38, 40, 42, 518 + 44, 46, 48, 50, 52, 54, 56, 58, 519 + 60, 62, 64, 66, 68, 70, 71, 73, 520 + 75, 77, 78, 80, 82, 83, 85, 87, 521 + 88, 90, 91, 93, 94, 96, 97, 98, 522 + 100, 101, 102, 104, 105, 106, 107, 108, 523 + 109, 111, 112, 113, 113, 114, 115, 116, 524 + 117, 118, 118, 119, 120, 120, 121, 122, 525 + 122, 123, 123, 124, 124, 124, 125, 125, 526 + 125, 125, 125, 125, 125, 126, 126, 125, 527 + 125, 125, 125, 125, 125, 124, 124, 124, 528 + 123, 123, 122, 122, 121, 121, 120, 120, 529 + 119, 118, 117, 117, 116, 115, 114, 113, 530 + 112, 111, 110, 109, 108, 107, 105, 104, 531 + 103, 102, 100, 99, 98, 96, 95, 93, 532 + 92, 91, 89, 87, 86, 84, 83, 81, 533 + 79, 77, 76, 74, 72, 70, 69, 67, 534 + 65, 63, 61, 59, 57, 55, 53, 51, 535 + 49, 47, 45, 43, 41, 39, 37, 35, 536 + 33, 30, 28, 26, 24, 22, 20, 18, 537 + 15, 13, 11, 9, 7, 4, 2, 0, 538 + -1, -3, -6, -8, -10, -12, -14, -17, 539 + -19, -21, -23, -25, -27, -29, -32, -34, 540 + -36, -38, -40, -42, -44, -46, -48, -50, 541 + -52, -54, -56, -58, -60, -62, -64, -66, 542 + -68, -70, -71, -73, -75, -77, -78, -80, 543 + -82, -83, -85, -87, -88, -90, -91, -93, 544 + -94, -96, -97, -98, -100, -101, -102, -104, 545 + -105, -106, -107, -108, -109, -111, -112, -113, 546 + -113, -114, -115, -116, -117, -118, -118, -119, 547 + -120, -120, -121, -122, -122, -123, -123, -124, -124 548 + }; 549 + 550 + static const int hsv_green_y[] = { 551 + -100, -99, -98, -97, -95, -94, -93, -91, 552 + -90, -89, -87, -86, -84, -83, -81, -80, 553 + -78, -76, -75, -73, -71, -70, -68, -66, 554 + -64, -63, -61, -59, -57, -55, -53, -51, 555 + -49, -48, -46, -44, -42, -40, -38, -36, 556 + -34, -32, -30, -27, -25, -23, -21, -19, 557 + -17, -15, -13, -11, -9, -7, -4, -2, 558 + 0, 1, 3, 5, 7, 9, 11, 14, 559 + 16, 18, 20, 22, 24, 26, 28, 30, 560 + 32, 34, 36, 38, 40, 42, 44, 46, 561 + 48, 50, 52, 54, 56, 58, 59, 61, 562 + 63, 65, 67, 68, 70, 72, 74, 75, 563 + 77, 78, 80, 82, 83, 85, 86, 88, 564 + 89, 90, 92, 93, 95, 96, 97, 98, 565 + 100, 101, 102, 103, 104, 105, 106, 107, 566 + 108, 109, 110, 111, 112, 112, 113, 114, 567 + 115, 115, 116, 116, 117, 117, 118, 118, 568 + 119, 119, 119, 120, 120, 120, 120, 120, 569 + 121, 121, 121, 121, 121, 121, 120, 120, 570 + 120, 120, 120, 119, 119, 119, 118, 118, 571 + 117, 117, 116, 116, 115, 114, 114, 113, 572 + 112, 111, 111, 110, 109, 108, 107, 106, 573 + 105, 104, 103, 102, 100, 99, 98, 97, 574 + 95, 94, 93, 91, 90, 89, 87, 86, 575 + 84, 83, 81, 80, 78, 76, 75, 73, 576 + 71, 70, 68, 66, 64, 63, 61, 59, 577 + 57, 55, 53, 51, 49, 48, 46, 44, 578 + 42, 40, 38, 36, 34, 32, 30, 27, 579 + 25, 23, 21, 19, 17, 15, 13, 11, 580 + 9, 7, 4, 2, 0, -1, -3, -5, 581 + -7, -9, -11, -14, -16, -18, -20, -22, 582 + -24, -26, -28, -30, -32, -34, -36, -38, 583 + -40, -42, -44, -46, -48, -50, -52, -54, 584 + -56, -58, -59, -61, -63, -65, -67, -68, 585 + -70, -72, -74, -75, -77, -78, -80, -82, 586 + -83, -85, -86, -88, -89, -90, -92, -93, 587 + -95, -96, -97, -98, -100, -101, -102, -103, 588 + -104, -105, -106, -107, -108, -109, -110, -111, 589 + -112, -112, -113, -114, -115, -115, -116, -116, 590 + -117, -117, -118, -118, -119, -119, -119, -120, 591 + -120, -120, -120, -120, -121, -121, -121, -121, 592 + -121, -121, -120, -120, -120, -120, -120, -119, 593 + -119, -119, -118, -118, -117, -117, -116, -116, 594 + -115, -114, -114, -113, -112, -111, -111, -110, 595 + -109, -108, -107, -106, -105, -104, -103, -102, -100 596 + }; 597 + 598 + static const int hsv_blue_x[] = { 599 + 112, 113, 114, 114, 115, 116, 117, 117, 600 + 118, 118, 119, 119, 120, 120, 120, 121, 601 + 121, 121, 122, 122, 122, 122, 122, 122, 602 + 122, 122, 122, 122, 122, 122, 121, 121, 603 + 121, 120, 120, 120, 119, 119, 118, 118, 604 + 117, 116, 116, 115, 114, 113, 113, 112, 605 + 111, 110, 109, 108, 107, 106, 105, 104, 606 + 103, 102, 100, 99, 98, 97, 95, 94, 607 + 93, 91, 90, 88, 87, 85, 84, 82, 608 + 80, 79, 77, 76, 74, 72, 70, 69, 609 + 67, 65, 63, 61, 60, 58, 56, 54, 610 + 52, 50, 48, 46, 44, 42, 40, 38, 611 + 36, 34, 32, 30, 28, 26, 24, 22, 612 + 19, 17, 15, 13, 11, 9, 7, 5, 613 + 2, 0, -1, -3, -5, -7, -9, -12, 614 + -14, -16, -18, -20, -22, -24, -26, -28, 615 + -31, -33, -35, -37, -39, -41, -43, -45, 616 + -47, -49, -51, -53, -54, -56, -58, -60, 617 + -62, -64, -66, -67, -69, -71, -73, -74, 618 + -76, -78, -79, -81, -83, -84, -86, -87, 619 + -89, -90, -92, -93, -94, -96, -97, -98, 620 + -99, -101, -102, -103, -104, -105, -106, -107, 621 + -108, -109, -110, -111, -112, -113, -114, -114, 622 + -115, -116, -117, -117, -118, -118, -119, -119, 623 + -120, -120, -120, -121, -121, -121, -122, -122, 624 + -122, -122, -122, -122, -122, -122, -122, -122, 625 + -122, -122, -121, -121, -121, -120, -120, -120, 626 + -119, -119, -118, -118, -117, -116, -116, -115, 627 + -114, -113, -113, -112, -111, -110, -109, -108, 628 + -107, -106, -105, -104, -103, -102, -100, -99, 629 + -98, -97, -95, -94, -93, -91, -90, -88, 630 + -87, -85, -84, -82, -80, -79, -77, -76, 631 + -74, -72, -70, -69, -67, -65, -63, -61, 632 + -60, -58, -56, -54, -52, -50, -48, -46, 633 + -44, -42, -40, -38, -36, -34, -32, -30, 634 + -28, -26, -24, -22, -19, -17, -15, -13, 635 + -11, -9, -7, -5, -2, 0, 1, 3, 636 + 5, 7, 9, 12, 14, 16, 18, 20, 637 + 22, 24, 26, 28, 31, 33, 35, 37, 638 + 39, 41, 43, 45, 47, 49, 51, 53, 639 + 54, 56, 58, 60, 62, 64, 66, 67, 640 + 69, 71, 73, 74, 76, 78, 79, 81, 641 + 83, 84, 86, 87, 89, 90, 92, 93, 642 + 94, 96, 97, 98, 99, 101, 102, 103, 643 + 104, 105, 106, 107, 108, 109, 110, 111, 112 644 + }; 645 + 646 + static const int hsv_blue_y[] = { 647 + -11, -13, -15, -17, -19, -21, -23, -25, 648 + -27, -29, -31, -33, -35, -37, -39, -41, 649 + -43, -45, -46, -48, -50, -52, -54, -55, 650 + -57, -59, -61, -62, -64, -66, -67, -69, 651 + -71, -72, -74, -75, -77, -78, -80, -81, 652 + -83, -84, -86, -87, -88, -90, -91, -92, 653 + -93, -95, -96, -97, -98, -99, -100, -101, 654 + -102, -103, -104, -105, -106, -106, -107, -108, 655 + -109, -109, -110, -111, -111, -112, -112, -113, 656 + -113, -114, -114, -114, -115, -115, -115, -115, 657 + -116, -116, -116, -116, -116, -116, -116, -116, 658 + -116, -115, -115, -115, -115, -114, -114, -114, 659 + -113, -113, -112, -112, -111, -111, -110, -110, 660 + -109, -108, -108, -107, -106, -105, -104, -103, 661 + -102, -101, -100, -99, -98, -97, -96, -95, 662 + -94, -93, -91, -90, -89, -88, -86, -85, 663 + -84, -82, -81, -79, -78, -76, -75, -73, 664 + -71, -70, -68, -67, -65, -63, -62, -60, 665 + -58, -56, -55, -53, -51, -49, -47, -45, 666 + -44, -42, -40, -38, -36, -34, -32, -30, 667 + -28, -26, -24, -22, -20, -18, -16, -14, 668 + -12, -10, -8, -6, -4, -2, 0, 1, 669 + 3, 5, 7, 9, 11, 13, 15, 17, 670 + 19, 21, 23, 25, 27, 29, 31, 33, 671 + 35, 37, 39, 41, 43, 45, 46, 48, 672 + 50, 52, 54, 55, 57, 59, 61, 62, 673 + 64, 66, 67, 69, 71, 72, 74, 75, 674 + 77, 78, 80, 81, 83, 84, 86, 87, 675 + 88, 90, 91, 92, 93, 95, 96, 97, 676 + 98, 99, 100, 101, 102, 103, 104, 105, 677 + 106, 106, 107, 108, 109, 109, 110, 111, 678 + 111, 112, 112, 113, 113, 114, 114, 114, 679 + 115, 115, 115, 115, 116, 116, 116, 116, 680 + 116, 116, 116, 116, 116, 115, 115, 115, 681 + 115, 114, 114, 114, 113, 113, 112, 112, 682 + 111, 111, 110, 110, 109, 108, 108, 107, 683 + 106, 105, 104, 103, 102, 101, 100, 99, 684 + 98, 97, 96, 95, 94, 93, 91, 90, 685 + 89, 88, 86, 85, 84, 82, 81, 79, 686 + 78, 76, 75, 73, 71, 70, 68, 67, 687 + 65, 63, 62, 60, 58, 56, 55, 53, 688 + 51, 49, 47, 45, 44, 42, 40, 38, 689 + 36, 34, 32, 30, 28, 26, 24, 22, 690 + 20, 18, 16, 14, 12, 10, 8, 6, 691 + 4, 2, 0, -1, -3, -5, -7, -9, -11 692 + }; 693 + 694 + static u16 i2c_ident[] = { 695 + V4L2_IDENT_OV9650, 696 + V4L2_IDENT_OV9655, 697 + V4L2_IDENT_SOI968, 698 + V4L2_IDENT_OV7660, 699 + V4L2_IDENT_OV7670, 700 + V4L2_IDENT_MT9V011, 701 + V4L2_IDENT_MT9V111, 702 + V4L2_IDENT_MT9V112, 703 + V4L2_IDENT_MT9M001C12ST, 704 + V4L2_IDENT_MT9M111, 705 + V4L2_IDENT_HV7131R, 706 + }; 707 + 708 + static u16 bridge_init[][2] = { 709 + {0x1000, 0x78}, {0x1001, 0x40}, {0x1002, 0x1c}, 710 + {0x1020, 0x80}, {0x1061, 0x01}, {0x1067, 0x40}, 711 + {0x1068, 0x30}, {0x1069, 0x20}, {0x106a, 0x10}, 712 + {0x106b, 0x08}, {0x1188, 0x87}, {0x11a1, 0x00}, 713 + {0x11a2, 0x00}, {0x11a3, 0x6a}, {0x11a4, 0x50}, 714 + {0x11ab, 0x00}, {0x11ac, 0x00}, {0x11ad, 0x50}, 715 + {0x11ae, 0x3c}, {0x118a, 0x04}, {0x0395, 0x04}, 716 + {0x11b8, 0x3a}, {0x118b, 0x0e}, {0x10f7, 0x05}, 717 + {0x10f8, 0x14}, {0x10fa, 0xff}, {0x10f9, 0x00}, 718 + {0x11ba, 0x0a}, {0x11a5, 0x2d}, {0x11a6, 0x2d}, 719 + {0x11a7, 0x3a}, {0x11a8, 0x05}, {0x11a9, 0x04}, 720 + {0x11aa, 0x3f}, {0x11af, 0x28}, {0x11b0, 0xd8}, 721 + {0x11b1, 0x14}, {0x11b2, 0xec}, {0x11b3, 0x32}, 722 + {0x11b4, 0xdd}, {0x11b5, 0x32}, {0x11b6, 0xdd}, 723 + {0x10e0, 0x2c}, {0x11bc, 0x40}, {0x11bd, 0x01}, 724 + {0x11be, 0xf0}, {0x11bf, 0x00}, {0x118c, 0x1f}, 725 + {0x118d, 0x1f}, {0x118e, 0x1f}, {0x118f, 0x1f}, 726 + {0x1180, 0x01}, {0x1181, 0x00}, {0x1182, 0x01}, 727 + {0x1183, 0x00}, {0x1184, 0x50}, {0x1185, 0x80} 728 + }; 729 + 730 + /* Gain = (bit[3:0] / 16 + 1) * (bit[4] + 1) * (bit[5] + 1) * (bit[6] + 1) */ 731 + static u8 ov_gain[] = { 732 + 0x00 /* 1x */, 0x04 /* 1.25x */, 0x08 /* 1.5x */, 0x0c /* 1.75x */, 733 + 0x10 /* 2x */, 0x12 /* 2.25x */, 0x14 /* 2.5x */, 0x16 /* 2.75x */, 734 + 0x18 /* 3x */, 0x1a /* 3.25x */, 0x1c /* 3.5x */, 0x1e /* 3.75x */, 735 + 0x30 /* 4x */, 0x31 /* 4.25x */, 0x32 /* 4.5x */, 0x33 /* 4.75x */, 736 + 0x34 /* 5x */, 0x35 /* 5.25x */, 0x36 /* 5.5x */, 0x37 /* 5.75x */, 737 + 0x38 /* 6x */, 0x39 /* 6.25x */, 0x3a /* 6.5x */, 0x3b /* 6.75x */, 738 + 0x3c /* 7x */, 0x3d /* 7.25x */, 0x3e /* 7.5x */, 0x3f /* 7.75x */, 739 + 0x70 /* 8x */ 740 + }; 741 + 742 + /* Gain = (bit[8] + 1) * (bit[7] + 1) * (bit[6:0] * 0.03125) */ 743 + static u16 micron1_gain[] = { 744 + /* 1x 1.25x 1.5x 1.75x */ 745 + 0x0020, 0x0028, 0x0030, 0x0038, 746 + /* 2x 2.25x 2.5x 2.75x */ 747 + 0x00a0, 0x00a4, 0x00a8, 0x00ac, 748 + /* 3x 3.25x 3.5x 3.75x */ 749 + 0x00b0, 0x00b4, 0x00b8, 0x00bc, 750 + /* 4x 4.25x 4.5x 4.75x */ 751 + 0x00c0, 0x00c4, 0x00c8, 0x00cc, 752 + /* 5x 5.25x 5.5x 5.75x */ 753 + 0x00d0, 0x00d4, 0x00d8, 0x00dc, 754 + /* 6x 6.25x 6.5x 6.75x */ 755 + 0x00e0, 0x00e4, 0x00e8, 0x00ec, 756 + /* 7x 7.25x 7.5x 7.75x */ 757 + 0x00f0, 0x00f4, 0x00f8, 0x00fc, 758 + /* 8x */ 759 + 0x01c0 760 + }; 761 + 762 + /* mt9m001 sensor uses a different gain formula then other micron sensors */ 763 + /* Gain = (bit[6] + 1) * (bit[5-0] * 0.125) */ 764 + static u16 micron2_gain[] = { 765 + /* 1x 1.25x 1.5x 1.75x */ 766 + 0x0008, 0x000a, 0x000c, 0x000e, 767 + /* 2x 2.25x 2.5x 2.75x */ 768 + 0x0010, 0x0012, 0x0014, 0x0016, 769 + /* 3x 3.25x 3.5x 3.75x */ 770 + 0x0018, 0x001a, 0x001c, 0x001e, 771 + /* 4x 4.25x 4.5x 4.75x */ 772 + 0x0020, 0x0051, 0x0052, 0x0053, 773 + /* 5x 5.25x 5.5x 5.75x */ 774 + 0x0054, 0x0055, 0x0056, 0x0057, 775 + /* 6x 6.25x 6.5x 6.75x */ 776 + 0x0058, 0x0059, 0x005a, 0x005b, 777 + /* 7x 7.25x 7.5x 7.75x */ 778 + 0x005c, 0x005d, 0x005e, 0x005f, 779 + /* 8x */ 780 + 0x0060 781 + }; 782 + 783 + /* Gain = .5 + bit[7:0] / 16 */ 784 + static u8 hv7131r_gain[] = { 785 + 0x08 /* 1x */, 0x0c /* 1.25x */, 0x10 /* 1.5x */, 0x14 /* 1.75x */, 786 + 0x18 /* 2x */, 0x1c /* 2.25x */, 0x20 /* 2.5x */, 0x24 /* 2.75x */, 787 + 0x28 /* 3x */, 0x2c /* 3.25x */, 0x30 /* 3.5x */, 0x34 /* 3.75x */, 788 + 0x38 /* 4x */, 0x3c /* 4.25x */, 0x40 /* 4.5x */, 0x44 /* 4.75x */, 789 + 0x48 /* 5x */, 0x4c /* 5.25x */, 0x50 /* 5.5x */, 0x54 /* 5.75x */, 790 + 0x58 /* 6x */, 0x5c /* 6.25x */, 0x60 /* 6.5x */, 0x64 /* 6.75x */, 791 + 0x68 /* 7x */, 0x6c /* 7.25x */, 0x70 /* 7.5x */, 0x74 /* 7.75x */, 792 + 0x78 /* 8x */ 793 + }; 794 + 795 + static u8 soi968_init[][2] = { 796 + {0x12, 0x80}, {0x0c, 0x00}, {0x0f, 0x1f}, 797 + {0x11, 0x80}, {0x38, 0x52}, {0x1e, 0x00}, 798 + {0x33, 0x08}, {0x35, 0x8c}, {0x36, 0x0c}, 799 + {0x37, 0x04}, {0x45, 0x04}, {0x47, 0xff}, 800 + {0x3e, 0x00}, {0x3f, 0x00}, {0x3b, 0x20}, 801 + {0x3a, 0x96}, {0x3d, 0x0a}, {0x14, 0x8e}, 802 + {0x13, 0x8a}, {0x12, 0x40}, {0x17, 0x13}, 803 + {0x18, 0x63}, {0x19, 0x01}, {0x1a, 0x79}, 804 + {0x32, 0x24}, {0x03, 0x00}, {0x11, 0x40}, 805 + {0x2a, 0x10}, {0x2b, 0xe0}, {0x10, 0x32}, 806 + {0x00, 0x00}, {0x01, 0x80}, {0x02, 0x80}, 807 + }; 808 + 809 + static u8 ov7660_init[][2] = { 810 + {0x0e, 0x80}, {0x0d, 0x08}, {0x0f, 0xc3}, 811 + {0x04, 0xc3}, {0x10, 0x40}, {0x11, 0x40}, 812 + {0x12, 0x05}, {0x13, 0xba}, {0x14, 0x2a}, 813 + {0x37, 0x0f}, {0x38, 0x02}, {0x39, 0x43}, 814 + {0x3a, 0x00}, {0x69, 0x90}, {0x2d, 0xf6}, 815 + {0x2e, 0x0b}, {0x01, 0x78}, {0x02, 0x50}, 816 + }; 817 + 818 + static u8 ov7670_init[][2] = { 819 + {0x12, 0x80}, {0x11, 0x80}, {0x3a, 0x04}, {0x12, 0x01}, 820 + {0x32, 0xb6}, {0x03, 0x0a}, {0x0c, 0x00}, {0x3e, 0x00}, 821 + {0x70, 0x3a}, {0x71, 0x35}, {0x72, 0x11}, {0x73, 0xf0}, 822 + {0xa2, 0x02}, {0x13, 0xe0}, {0x00, 0x00}, {0x10, 0x00}, 823 + {0x0d, 0x40}, {0x14, 0x28}, {0xa5, 0x05}, {0xab, 0x07}, 824 + {0x24, 0x95}, {0x25, 0x33}, {0x26, 0xe3}, {0x9f, 0x75}, 825 + {0xa0, 0x65}, {0xa1, 0x0b}, {0xa6, 0xd8}, {0xa7, 0xd8}, 826 + {0xa8, 0xf0}, {0xa9, 0x90}, {0xaa, 0x94}, {0x13, 0xe5}, 827 + {0x0e, 0x61}, {0x0f, 0x4b}, {0x16, 0x02}, {0x1e, 0x27}, 828 + {0x21, 0x02}, {0x22, 0x91}, {0x29, 0x07}, {0x33, 0x0b}, 829 + {0x35, 0x0b}, {0x37, 0x1d}, {0x38, 0x71}, {0x39, 0x2a}, 830 + {0x3c, 0x78}, {0x4d, 0x40}, {0x4e, 0x20}, {0x69, 0x00}, 831 + {0x74, 0x19}, {0x8d, 0x4f}, {0x8e, 0x00}, {0x8f, 0x00}, 832 + {0x90, 0x00}, {0x91, 0x00}, {0x96, 0x00}, {0x9a, 0x80}, 833 + {0xb0, 0x84}, {0xb1, 0x0c}, {0xb2, 0x0e}, {0xb3, 0x82}, 834 + {0xb8, 0x0a}, {0x43, 0x0a}, {0x44, 0xf0}, {0x45, 0x20}, 835 + {0x46, 0x7d}, {0x47, 0x29}, {0x48, 0x4a}, {0x59, 0x8c}, 836 + {0x5a, 0xa5}, {0x5b, 0xde}, {0x5c, 0x96}, {0x5d, 0x66}, 837 + {0x5e, 0x10}, {0x6c, 0x0a}, {0x6d, 0x55}, {0x6e, 0x11}, 838 + {0x6f, 0x9e}, {0x6a, 0x40}, {0x01, 0x40}, {0x02, 0x40}, 839 + {0x13, 0xe7}, {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x02}, 840 + {0x52, 0x1d}, {0x53, 0x56}, {0x54, 0x73}, {0x55, 0x0a}, 841 + {0x56, 0x55}, {0x57, 0x80}, {0x58, 0x9e}, {0x41, 0x08}, 842 + {0x3f, 0x02}, {0x75, 0x03}, {0x76, 0x63}, {0x4c, 0x04}, 843 + {0x77, 0x06}, {0x3d, 0x02}, {0x4b, 0x09}, {0xc9, 0x30}, 844 + {0x41, 0x08}, {0x56, 0x48}, {0x34, 0x11}, {0xa4, 0x88}, 845 + {0x96, 0x00}, {0x97, 0x30}, {0x98, 0x20}, {0x99, 0x30}, 846 + {0x9a, 0x84}, {0x9b, 0x29}, {0x9c, 0x03}, {0x9d, 0x99}, 847 + {0x9e, 0x7f}, {0x78, 0x04}, {0x79, 0x01}, {0xc8, 0xf0}, 848 + {0x79, 0x0f}, {0xc8, 0x00}, {0x79, 0x10}, {0xc8, 0x7e}, 849 + {0x79, 0x0a}, {0xc8, 0x80}, {0x79, 0x0b}, {0xc8, 0x01}, 850 + {0x79, 0x0c}, {0xc8, 0x0f}, {0x79, 0x0d}, {0xc8, 0x20}, 851 + {0x79, 0x09}, {0xc8, 0x80}, {0x79, 0x02}, {0xc8, 0xc0}, 852 + {0x79, 0x03}, {0xc8, 0x40}, {0x79, 0x05}, {0xc8, 0x30}, 853 + {0x79, 0x26}, {0x62, 0x20}, {0x63, 0x00}, {0x64, 0x06}, 854 + {0x65, 0x00}, {0x66, 0x05}, {0x94, 0x05}, {0x95, 0x0a}, 855 + {0x17, 0x13}, {0x18, 0x01}, {0x19, 0x02}, {0x1a, 0x7a}, 856 + {0x46, 0x59}, {0x47, 0x30}, {0x58, 0x9a}, {0x59, 0x84}, 857 + {0x5a, 0x91}, {0x5b, 0x57}, {0x5c, 0x75}, {0x5d, 0x6d}, 858 + {0x5e, 0x13}, {0x64, 0x07}, {0x94, 0x07}, {0x95, 0x0d}, 859 + {0xa6, 0xdf}, {0xa7, 0xdf}, {0x48, 0x4d}, {0x51, 0x00}, 860 + {0x6b, 0x0a}, {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00}, 861 + {0x92, 0x00}, {0x93, 0x00}, {0x55, 0x0a}, {0x56, 0x60}, 862 + {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d}, 863 + {0x53, 0x56}, {0x54, 0x73}, {0x58, 0x9a}, {0x4f, 0x6e}, 864 + {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d}, {0x53, 0x56}, 865 + {0x54, 0x73}, {0x58, 0x9a}, {0x3f, 0x01}, {0x7b, 0x03}, 866 + {0x7c, 0x09}, {0x7d, 0x16}, {0x7e, 0x38}, {0x7f, 0x47}, 867 + {0x80, 0x53}, {0x81, 0x5e}, {0x82, 0x6a}, {0x83, 0x74}, 868 + {0x84, 0x80}, {0x85, 0x8c}, {0x86, 0x9b}, {0x87, 0xb2}, 869 + {0x88, 0xcc}, {0x89, 0xe5}, {0x7a, 0x24}, {0x3b, 0x00}, 870 + {0x9f, 0x76}, {0xa0, 0x65}, {0x13, 0xe2}, {0x6b, 0x0a}, 871 + {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00}, {0x92, 0x00}, 872 + {0x93, 0x00}, 873 + }; 874 + 875 + static u8 ov9650_init[][2] = { 876 + {0x12, 0x80}, {0x00, 0x00}, {0x01, 0x78}, 877 + {0x02, 0x78}, {0x03, 0x36}, {0x04, 0x03}, 878 + {0x05, 0x00}, {0x06, 0x00}, {0x08, 0x00}, 879 + {0x09, 0x01}, {0x0c, 0x00}, {0x0d, 0x00}, 880 + {0x0e, 0xa0}, {0x0f, 0x52}, {0x10, 0x7c}, 881 + {0x11, 0x80}, {0x12, 0x45}, {0x13, 0xc2}, 882 + {0x14, 0x2e}, {0x15, 0x00}, {0x16, 0x07}, 883 + {0x17, 0x24}, {0x18, 0xc5}, {0x19, 0x00}, 884 + {0x1a, 0x3c}, {0x1b, 0x00}, {0x1e, 0x04}, 885 + {0x1f, 0x00}, {0x24, 0x78}, {0x25, 0x68}, 886 + {0x26, 0xd4}, {0x27, 0x80}, {0x28, 0x80}, 887 + {0x29, 0x30}, {0x2a, 0x00}, {0x2b, 0x00}, 888 + {0x2c, 0x80}, {0x2d, 0x00}, {0x2e, 0x00}, 889 + {0x2f, 0x00}, {0x30, 0x08}, {0x31, 0x30}, 890 + {0x32, 0x84}, {0x33, 0xe2}, {0x34, 0xbf}, 891 + {0x35, 0x81}, {0x36, 0xf9}, {0x37, 0x00}, 892 + {0x38, 0x93}, {0x39, 0x50}, {0x3a, 0x01}, 893 + {0x3b, 0x01}, {0x3c, 0x73}, {0x3d, 0x19}, 894 + {0x3e, 0x0b}, {0x3f, 0x80}, {0x40, 0xc1}, 895 + {0x41, 0x00}, {0x42, 0x08}, {0x67, 0x80}, 896 + {0x68, 0x80}, {0x69, 0x40}, {0x6a, 0x00}, 897 + {0x6b, 0x0a}, {0x8b, 0x06}, {0x8c, 0x20}, 898 + {0x8d, 0x00}, {0x8e, 0x00}, {0x8f, 0xdf}, 899 + {0x92, 0x00}, {0x93, 0x00}, {0x94, 0x88}, 900 + {0x95, 0x88}, {0x96, 0x04}, {0xa1, 0x00}, 901 + {0xa5, 0x80}, {0xa8, 0x80}, {0xa9, 0xb8}, 902 + {0xaa, 0x92}, {0xab, 0x0a}, 903 + }; 904 + 905 + static u8 ov9655_init[][2] = { 906 + {0x12, 0x80}, {0x12, 0x01}, {0x0d, 0x00}, {0x0e, 0x61}, 907 + {0x11, 0x80}, {0x13, 0xba}, {0x14, 0x2e}, {0x16, 0x24}, 908 + {0x1e, 0x04}, {0x1e, 0x04}, {0x1e, 0x04}, {0x27, 0x08}, 909 + {0x28, 0x08}, {0x29, 0x15}, {0x2c, 0x08}, {0x32, 0xbf}, 910 + {0x34, 0x3d}, {0x35, 0x00}, {0x36, 0xf8}, {0x38, 0x12}, 911 + {0x39, 0x57}, {0x3a, 0x00}, {0x3b, 0xcc}, {0x3c, 0x0c}, 912 + {0x3d, 0x19}, {0x3e, 0x0c}, {0x3f, 0x01}, {0x41, 0x40}, 913 + {0x42, 0x80}, {0x45, 0x46}, {0x46, 0x62}, {0x47, 0x2a}, 914 + {0x48, 0x3c}, {0x4a, 0xf0}, {0x4b, 0xdc}, {0x4c, 0xdc}, 915 + {0x4d, 0xdc}, {0x4e, 0xdc}, {0x69, 0x02}, {0x6c, 0x04}, 916 + {0x6f, 0x9e}, {0x70, 0x05}, {0x71, 0x78}, {0x77, 0x02}, 917 + {0x8a, 0x23}, {0x8c, 0x0d}, {0x90, 0x7e}, {0x91, 0x7c}, 918 + {0x9f, 0x6e}, {0xa0, 0x6e}, {0xa5, 0x68}, {0xa6, 0x60}, 919 + {0xa8, 0xc1}, {0xa9, 0xfa}, {0xaa, 0x92}, {0xab, 0x04}, 920 + {0xac, 0x80}, {0xad, 0x80}, {0xae, 0x80}, {0xaf, 0x80}, 921 + {0xb2, 0xf2}, {0xb3, 0x20}, {0xb5, 0x00}, {0xb6, 0xaf}, 922 + {0xbb, 0xae}, {0xbc, 0x44}, {0xbd, 0x44}, {0xbe, 0x3b}, 923 + {0xbf, 0x3a}, {0xc0, 0xe2}, {0xc1, 0xc8}, {0xc2, 0x01}, 924 + {0xc4, 0x00}, {0xc6, 0x85}, {0xc7, 0x81}, {0xc9, 0xe0}, 925 + {0xca, 0xe8}, {0xcc, 0xd8}, {0xcd, 0x93}, {0x12, 0x61}, 926 + {0x36, 0xfa}, {0x8c, 0x8d}, {0xc0, 0xaa}, {0x69, 0x0a}, 927 + {0x03, 0x12}, {0x17, 0x14}, {0x18, 0x00}, {0x19, 0x01}, 928 + {0x1a, 0x3d}, {0x32, 0xbf}, {0x11, 0x80}, {0x2a, 0x10}, 929 + {0x2b, 0x0a}, {0x92, 0x00}, {0x93, 0x00}, {0x1e, 0x04}, 930 + {0x1e, 0x04}, {0x10, 0x7c}, {0x04, 0x03}, {0xa1, 0x00}, 931 + {0x2d, 0x00}, {0x2e, 0x00}, {0x00, 0x00}, {0x01, 0x80}, 932 + {0x02, 0x80}, {0x12, 0x61}, {0x36, 0xfa}, {0x8c, 0x8d}, 933 + {0xc0, 0xaa}, {0x69, 0x0a}, {0x03, 0x12}, {0x17, 0x14}, 934 + {0x18, 0x00}, {0x19, 0x01}, {0x1a, 0x3d}, {0x32, 0xbf}, 935 + {0x11, 0x80}, {0x2a, 0x10}, {0x2b, 0x0a}, {0x92, 0x00}, 936 + {0x93, 0x00}, {0x04, 0x01}, {0x10, 0x1f}, {0xa1, 0x00}, 937 + {0x00, 0x0a}, {0xa1, 0x00}, {0x10, 0x5d}, {0x04, 0x03}, 938 + {0x00, 0x01}, {0xa1, 0x00}, {0x10, 0x7c}, {0x04, 0x03}, 939 + {0x00, 0x03}, {0x00, 0x0a}, {0x00, 0x10}, {0x00, 0x13}, 940 + }; 941 + 942 + static u16 mt9v112_init[][2] = { 943 + {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0020}, 944 + {0x34, 0xc019}, {0x0a, 0x0011}, {0x0b, 0x000b}, 945 + {0x20, 0x0703}, {0x35, 0x2022}, {0xf0, 0x0001}, 946 + {0x05, 0x0000}, {0x06, 0x340c}, {0x3b, 0x042a}, 947 + {0x3c, 0x0400}, {0xf0, 0x0002}, {0x2e, 0x0c58}, 948 + {0x5b, 0x0001}, {0xc8, 0x9f0b}, {0xf0, 0x0001}, 949 + {0x9b, 0x5300}, {0xf0, 0x0000}, {0x2b, 0x0020}, 950 + {0x2c, 0x002a}, {0x2d, 0x0032}, {0x2e, 0x0020}, 951 + {0x09, 0x01dc}, {0x01, 0x000c}, {0x02, 0x0020}, 952 + {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c}, 953 + {0x05, 0x0098}, {0x20, 0x0703}, {0x09, 0x01f2}, 954 + {0x2b, 0x00a0}, {0x2c, 0x00a0}, {0x2d, 0x00a0}, 955 + {0x2e, 0x00a0}, {0x01, 0x000c}, {0x02, 0x0020}, 956 + {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c}, 957 + {0x05, 0x0098}, {0x09, 0x01c1}, {0x2b, 0x00ae}, 958 + {0x2c, 0x00ae}, {0x2d, 0x00ae}, {0x2e, 0x00ae}, 959 + }; 960 + 961 + static u16 mt9v111_init[][2] = { 962 + {0x01, 0x0004}, {0x0d, 0x0001}, {0x0d, 0x0000}, 963 + {0x01, 0x0001}, {0x02, 0x0016}, {0x03, 0x01e1}, 964 + {0x04, 0x0281}, {0x05, 0x0004}, {0x07, 0x3002}, 965 + {0x21, 0x0000}, {0x25, 0x4024}, {0x26, 0xff03}, 966 + {0x27, 0xff10}, {0x2b, 0x7828}, {0x2c, 0xb43c}, 967 + {0x2d, 0xf0a0}, {0x2e, 0x0c64}, {0x2f, 0x0064}, 968 + {0x67, 0x4010}, {0x06, 0x301e}, {0x08, 0x0480}, 969 + {0x01, 0x0004}, {0x02, 0x0016}, {0x03, 0x01e6}, 970 + {0x04, 0x0286}, {0x05, 0x0004}, {0x06, 0x0000}, 971 + {0x07, 0x3002}, {0x08, 0x0008}, {0x0c, 0x0000}, 972 + {0x0d, 0x0000}, {0x0e, 0x0000}, {0x0f, 0x0000}, 973 + {0x10, 0x0000}, {0x11, 0x0000}, {0x12, 0x00b0}, 974 + {0x13, 0x007c}, {0x14, 0x0000}, {0x15, 0x0000}, 975 + {0x16, 0x0000}, {0x17, 0x0000}, {0x18, 0x0000}, 976 + {0x19, 0x0000}, {0x1a, 0x0000}, {0x1b, 0x0000}, 977 + {0x1c, 0x0000}, {0x1d, 0x0000}, {0x30, 0x0000}, 978 + {0x30, 0x0005}, {0x31, 0x0000}, {0x02, 0x0016}, 979 + {0x03, 0x01e1}, {0x04, 0x0281}, {0x05, 0x0004}, 980 + {0x06, 0x0000}, {0x07, 0x3002}, {0x06, 0x002d}, 981 + {0x05, 0x0004}, {0x09, 0x0064}, {0x2b, 0x00a0}, 982 + {0x2c, 0x00a0}, {0x2d, 0x00a0}, {0x2e, 0x00a0}, 983 + {0x02, 0x0016}, {0x03, 0x01e1}, {0x04, 0x0281}, 984 + {0x05, 0x0004}, {0x06, 0x002d}, {0x07, 0x3002}, 985 + {0x0e, 0x0008}, {0x06, 0x002d}, {0x05, 0x0004}, 986 + }; 987 + 988 + static u16 mt9v011_init[][2] = { 989 + {0x07, 0x0002}, {0x0d, 0x0001}, {0x0d, 0x0000}, 990 + {0x01, 0x0008}, {0x02, 0x0016}, {0x03, 0x01e1}, 991 + {0x04, 0x0281}, {0x05, 0x0083}, {0x06, 0x0006}, 992 + {0x0d, 0x0002}, {0x0a, 0x0000}, {0x0b, 0x0000}, 993 + {0x0c, 0x0000}, {0x0d, 0x0000}, {0x0e, 0x0000}, 994 + {0x0f, 0x0000}, {0x10, 0x0000}, {0x11, 0x0000}, 995 + {0x12, 0x0000}, {0x13, 0x0000}, {0x14, 0x0000}, 996 + {0x15, 0x0000}, {0x16, 0x0000}, {0x17, 0x0000}, 997 + {0x18, 0x0000}, {0x19, 0x0000}, {0x1a, 0x0000}, 998 + {0x1b, 0x0000}, {0x1c, 0x0000}, {0x1d, 0x0000}, 999 + {0x32, 0x0000}, {0x20, 0x1101}, {0x21, 0x0000}, 1000 + {0x22, 0x0000}, {0x23, 0x0000}, {0x24, 0x0000}, 1001 + {0x25, 0x0000}, {0x26, 0x0000}, {0x27, 0x0024}, 1002 + {0x2f, 0xf7b0}, {0x30, 0x0005}, {0x31, 0x0000}, 1003 + {0x32, 0x0000}, {0x33, 0x0000}, {0x34, 0x0100}, 1004 + {0x3d, 0x068f}, {0x40, 0x01e0}, {0x41, 0x00d1}, 1005 + {0x44, 0x0082}, {0x5a, 0x0000}, {0x5b, 0x0000}, 1006 + {0x5c, 0x0000}, {0x5d, 0x0000}, {0x5e, 0x0000}, 1007 + {0x5f, 0xa31d}, {0x62, 0x0611}, {0x0a, 0x0000}, 1008 + {0x06, 0x0029}, {0x05, 0x0009}, {0x20, 0x1101}, 1009 + {0x20, 0x1101}, {0x09, 0x0064}, {0x07, 0x0003}, 1010 + {0x2b, 0x0033}, {0x2c, 0x00a0}, {0x2d, 0x00a0}, 1011 + {0x2e, 0x0033}, {0x07, 0x0002}, {0x06, 0x0000}, 1012 + {0x06, 0x0029}, {0x05, 0x0009}, 1013 + }; 1014 + 1015 + static u16 mt9m001_init[][2] = { 1016 + {0x0d, 0x0001}, {0x0d, 0x0000}, {0x01, 0x000e}, 1017 + {0x02, 0x0014}, {0x03, 0x03c1}, {0x04, 0x0501}, 1018 + {0x05, 0x0083}, {0x06, 0x0006}, {0x0d, 0x0002}, 1019 + {0x0a, 0x0000}, {0x0c, 0x0000}, {0x11, 0x0000}, 1020 + {0x1e, 0x8000}, {0x5f, 0x8904}, {0x60, 0x0000}, 1021 + {0x61, 0x0000}, {0x62, 0x0498}, {0x63, 0x0000}, 1022 + {0x64, 0x0000}, {0x20, 0x111d}, {0x06, 0x00f2}, 1023 + {0x05, 0x0013}, {0x09, 0x10f2}, {0x07, 0x0003}, 1024 + {0x2b, 0x002a}, {0x2d, 0x002a}, {0x2c, 0x002a}, 1025 + {0x2e, 0x0029}, {0x07, 0x0002}, 1026 + }; 1027 + 1028 + static u16 mt9m111_init[][2] = { 1029 + {0xf0, 0x0000}, {0x0d, 0x0008}, {0x0d, 0x0009}, 1030 + {0x0d, 0x0008}, {0xf0, 0x0001}, {0x3a, 0x4300}, 1031 + {0x9b, 0x4300}, {0xa1, 0x0280}, {0xa4, 0x0200}, 1032 + {0x06, 0x308e}, {0xf0, 0x0000}, 1033 + }; 1034 + 1035 + static u8 hv7131r_init[][2] = { 1036 + {0x02, 0x08}, {0x02, 0x00}, {0x01, 0x08}, 1037 + {0x02, 0x00}, {0x20, 0x00}, {0x21, 0xd0}, 1038 + {0x22, 0x00}, {0x23, 0x09}, {0x01, 0x08}, 1039 + {0x01, 0x08}, {0x01, 0x08}, {0x25, 0x07}, 1040 + {0x26, 0xc3}, {0x27, 0x50}, {0x30, 0x62}, 1041 + {0x31, 0x10}, {0x32, 0x06}, {0x33, 0x10}, 1042 + {0x20, 0x00}, {0x21, 0xd0}, {0x22, 0x00}, 1043 + {0x23, 0x09}, {0x01, 0x08}, 1044 + }; 1045 + 1046 + int reg_r(struct gspca_dev *gspca_dev, u16 reg, u16 length) 1047 + { 1048 + struct usb_device *dev = gspca_dev->dev; 1049 + int result; 1050 + result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 1051 + 0x00, 1052 + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, 1053 + reg, 1054 + 0x00, 1055 + gspca_dev->usb_buf, 1056 + length, 1057 + 500); 1058 + if (unlikely(result < 0 || result != length)) { 1059 + err("Read register failed 0x%02X", reg); 1060 + return -EIO; 1061 + } 1062 + return 0; 1063 + } 1064 + 1065 + int reg_w(struct gspca_dev *gspca_dev, u16 reg, const u8 *buffer, int length) 1066 + { 1067 + struct usb_device *dev = gspca_dev->dev; 1068 + int result; 1069 + memcpy(gspca_dev->usb_buf, buffer, length); 1070 + result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 1071 + 0x08, 1072 + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, 1073 + reg, 1074 + 0x00, 1075 + gspca_dev->usb_buf, 1076 + length, 1077 + 500); 1078 + if (unlikely(result < 0 || result != length)) { 1079 + err("Write register failed index 0x%02X", reg); 1080 + return -EIO; 1081 + } 1082 + return 0; 1083 + } 1084 + 1085 + int reg_w1(struct gspca_dev *gspca_dev, u16 reg, const u8 value) 1086 + { 1087 + u8 data[1] = {value}; 1088 + return reg_w(gspca_dev, reg, data, 1); 1089 + } 1090 + 1091 + int i2c_w(struct gspca_dev *gspca_dev, const u8 *buffer) 1092 + { 1093 + int i; 1094 + reg_w(gspca_dev, 0x10c0, buffer, 8); 1095 + for (i = 0; i < 5; i++) { 1096 + reg_r(gspca_dev, 0x10c0, 1); 1097 + if (gspca_dev->usb_buf[0] & 0x04) { 1098 + if (gspca_dev->usb_buf[0] & 0x08) 1099 + return -1; 1100 + return 0; 1101 + } 1102 + msleep(1); 1103 + } 1104 + return -1; 1105 + } 1106 + 1107 + int i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val) 1108 + { 1109 + struct sd *sd = (struct sd *) gspca_dev; 1110 + 1111 + u8 row[8]; 1112 + 1113 + /* 1114 + * from the point of view of the bridge, the length 1115 + * includes the address 1116 + */ 1117 + row[0] = 0x81 | (2 << 4); 1118 + row[1] = sd->i2c_addr; 1119 + row[2] = reg; 1120 + row[3] = val; 1121 + row[4] = 0x00; 1122 + row[5] = 0x00; 1123 + row[6] = 0x00; 1124 + row[7] = 0x10; 1125 + 1126 + return i2c_w(gspca_dev, row); 1127 + } 1128 + 1129 + int i2c_w2(struct gspca_dev *gspca_dev, u8 reg, u16 val) 1130 + { 1131 + struct sd *sd = (struct sd *) gspca_dev; 1132 + u8 row[8]; 1133 + 1134 + /* 1135 + * from the point of view of the bridge, the length 1136 + * includes the address 1137 + */ 1138 + row[0] = 0x81 | (3 << 4); 1139 + row[1] = sd->i2c_addr; 1140 + row[2] = reg; 1141 + row[3] = (val >> 8) & 0xff; 1142 + row[4] = val & 0xff; 1143 + row[5] = 0x00; 1144 + row[6] = 0x00; 1145 + row[7] = 0x10; 1146 + 1147 + return i2c_w(gspca_dev, row); 1148 + } 1149 + 1150 + int i2c_r1(struct gspca_dev *gspca_dev, u8 reg, u8 *val) 1151 + { 1152 + struct sd *sd = (struct sd *) gspca_dev; 1153 + u8 row[8]; 1154 + 1155 + row[0] = 0x81 | 0x10; 1156 + row[1] = sd->i2c_addr; 1157 + row[2] = reg; 1158 + row[3] = 0; 1159 + row[4] = 0; 1160 + row[5] = 0; 1161 + row[6] = 0; 1162 + row[7] = 0x10; 1163 + reg_w(gspca_dev, 0x10c0, row, 8); 1164 + msleep(1); 1165 + row[0] = 0x81 | (2 << 4) | 0x02; 1166 + row[2] = 0; 1167 + reg_w(gspca_dev, 0x10c0, row, 8); 1168 + msleep(1); 1169 + reg_r(gspca_dev, 0x10c2, 5); 1170 + *val = gspca_dev->usb_buf[3]; 1171 + return 0; 1172 + } 1173 + 1174 + int i2c_r2(struct gspca_dev *gspca_dev, u8 reg, u16 *val) 1175 + { 1176 + struct sd *sd = (struct sd *) gspca_dev; 1177 + u8 row[8]; 1178 + 1179 + row[0] = 0x81 | 0x10; 1180 + row[1] = sd->i2c_addr; 1181 + row[2] = reg; 1182 + row[3] = 0; 1183 + row[4] = 0; 1184 + row[5] = 0; 1185 + row[6] = 0; 1186 + row[7] = 0x10; 1187 + reg_w(gspca_dev, 0x10c0, row, 8); 1188 + msleep(1); 1189 + row[0] = 0x81 | (3 << 4) | 0x02; 1190 + row[2] = 0; 1191 + reg_w(gspca_dev, 0x10c0, row, 8); 1192 + msleep(1); 1193 + reg_r(gspca_dev, 0x10c2, 5); 1194 + *val = (gspca_dev->usb_buf[2] << 8) | gspca_dev->usb_buf[3]; 1195 + return 0; 1196 + } 1197 + 1198 + static int ov9650_init_sensor(struct gspca_dev *gspca_dev) 1199 + { 1200 + int i; 1201 + struct sd *sd = (struct sd *) gspca_dev; 1202 + 1203 + for (i = 0; i < ARRAY_SIZE(ov9650_init); i++) { 1204 + if (i2c_w1(gspca_dev, ov9650_init[i][0], 1205 + ov9650_init[i][1]) < 0) { 1206 + err("OV9650 sensor initialization failed"); 1207 + return -ENODEV; 1208 + } 1209 + } 1210 + sd->hstart = 1; 1211 + sd->vstart = 7; 1212 + return 0; 1213 + } 1214 + 1215 + static int ov9655_init_sensor(struct gspca_dev *gspca_dev) 1216 + { 1217 + int i; 1218 + struct sd *sd = (struct sd *) gspca_dev; 1219 + 1220 + for (i = 0; i < ARRAY_SIZE(ov9655_init); i++) { 1221 + if (i2c_w1(gspca_dev, ov9655_init[i][0], 1222 + ov9655_init[i][1]) < 0) { 1223 + err("OV9655 sensor initialization failed"); 1224 + return -ENODEV; 1225 + } 1226 + } 1227 + /* disable hflip and vflip */ 1228 + gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX); 1229 + sd->hstart = 0; 1230 + sd->vstart = 7; 1231 + return 0; 1232 + } 1233 + 1234 + static int soi968_init_sensor(struct gspca_dev *gspca_dev) 1235 + { 1236 + int i; 1237 + struct sd *sd = (struct sd *) gspca_dev; 1238 + 1239 + for (i = 0; i < ARRAY_SIZE(soi968_init); i++) { 1240 + if (i2c_w1(gspca_dev, soi968_init[i][0], 1241 + soi968_init[i][1]) < 0) { 1242 + err("SOI968 sensor initialization failed"); 1243 + return -ENODEV; 1244 + } 1245 + } 1246 + /* disable hflip and vflip */ 1247 + gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX); 1248 + sd->hstart = 60; 1249 + sd->vstart = 11; 1250 + return 0; 1251 + } 1252 + 1253 + static int ov7660_init_sensor(struct gspca_dev *gspca_dev) 1254 + { 1255 + int i; 1256 + struct sd *sd = (struct sd *) gspca_dev; 1257 + 1258 + for (i = 0; i < ARRAY_SIZE(ov7660_init); i++) { 1259 + if (i2c_w1(gspca_dev, ov7660_init[i][0], 1260 + ov7660_init[i][1]) < 0) { 1261 + err("OV7660 sensor initialization failed"); 1262 + return -ENODEV; 1263 + } 1264 + } 1265 + /* disable hflip and vflip */ 1266 + gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX); 1267 + sd->hstart = 1; 1268 + sd->vstart = 1; 1269 + return 0; 1270 + } 1271 + 1272 + static int ov7670_init_sensor(struct gspca_dev *gspca_dev) 1273 + { 1274 + int i; 1275 + struct sd *sd = (struct sd *) gspca_dev; 1276 + 1277 + for (i = 0; i < ARRAY_SIZE(ov7670_init); i++) { 1278 + if (i2c_w1(gspca_dev, ov7670_init[i][0], 1279 + ov7670_init[i][1]) < 0) { 1280 + err("OV7670 sensor initialization failed"); 1281 + return -ENODEV; 1282 + } 1283 + } 1284 + /* disable hflip and vflip */ 1285 + gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX); 1286 + sd->hstart = 0; 1287 + sd->vstart = 1; 1288 + return 0; 1289 + } 1290 + 1291 + static int mt9v_init_sensor(struct gspca_dev *gspca_dev) 1292 + { 1293 + struct sd *sd = (struct sd *) gspca_dev; 1294 + int i; 1295 + u16 value; 1296 + int ret; 1297 + 1298 + sd->i2c_addr = 0x5d; 1299 + ret = i2c_r2(gspca_dev, 0xff, &value); 1300 + if ((ret == 0) && (value == 0x8243)) { 1301 + for (i = 0; i < ARRAY_SIZE(mt9v011_init); i++) { 1302 + if (i2c_w2(gspca_dev, mt9v011_init[i][0], 1303 + mt9v011_init[i][1]) < 0) { 1304 + err("MT9V011 sensor initialization failed"); 1305 + return -ENODEV; 1306 + } 1307 + } 1308 + sd->hstart = 2; 1309 + sd->vstart = 2; 1310 + sd->sensor = SENSOR_MT9V011; 1311 + info("MT9V011 sensor detected"); 1312 + return 0; 1313 + } 1314 + 1315 + sd->i2c_addr = 0x5c; 1316 + i2c_w2(gspca_dev, 0x01, 0x0004); 1317 + ret = i2c_r2(gspca_dev, 0xff, &value); 1318 + if ((ret == 0) && (value == 0x823a)) { 1319 + for (i = 0; i < ARRAY_SIZE(mt9v111_init); i++) { 1320 + if (i2c_w2(gspca_dev, mt9v111_init[i][0], 1321 + mt9v111_init[i][1]) < 0) { 1322 + err("MT9V111 sensor initialization failed"); 1323 + return -ENODEV; 1324 + } 1325 + } 1326 + sd->hstart = 2; 1327 + sd->vstart = 2; 1328 + sd->sensor = SENSOR_MT9V111; 1329 + info("MT9V111 sensor detected"); 1330 + return 0; 1331 + } 1332 + 1333 + sd->i2c_addr = 0x5d; 1334 + ret = i2c_w2(gspca_dev, 0xf0, 0x0000); 1335 + if (ret < 0) { 1336 + sd->i2c_addr = 0x48; 1337 + i2c_w2(gspca_dev, 0xf0, 0x0000); 1338 + } 1339 + ret = i2c_r2(gspca_dev, 0x00, &value); 1340 + if ((ret == 0) && (value == 0x1229)) { 1341 + for (i = 0; i < ARRAY_SIZE(mt9v112_init); i++) { 1342 + if (i2c_w2(gspca_dev, mt9v112_init[i][0], 1343 + mt9v112_init[i][1]) < 0) { 1344 + err("MT9V112 sensor initialization failed"); 1345 + return -ENODEV; 1346 + } 1347 + } 1348 + sd->hstart = 6; 1349 + sd->vstart = 2; 1350 + sd->sensor = SENSOR_MT9V112; 1351 + info("MT9V112 sensor detected"); 1352 + return 0; 1353 + } 1354 + 1355 + return -ENODEV; 1356 + } 1357 + 1358 + static int mt9m111_init_sensor(struct gspca_dev *gspca_dev) 1359 + { 1360 + struct sd *sd = (struct sd *) gspca_dev; 1361 + int i; 1362 + for (i = 0; i < ARRAY_SIZE(mt9m111_init); i++) { 1363 + if (i2c_w2(gspca_dev, mt9m111_init[i][0], 1364 + mt9m111_init[i][1]) < 0) { 1365 + err("MT9M111 sensor initialization failed"); 1366 + return -ENODEV; 1367 + } 1368 + } 1369 + sd->hstart = 0; 1370 + sd->vstart = 2; 1371 + return 0; 1372 + } 1373 + 1374 + static int mt9m001_init_sensor(struct gspca_dev *gspca_dev) 1375 + { 1376 + struct sd *sd = (struct sd *) gspca_dev; 1377 + int i; 1378 + for (i = 0; i < ARRAY_SIZE(mt9m001_init); i++) { 1379 + if (i2c_w2(gspca_dev, mt9m001_init[i][0], 1380 + mt9m001_init[i][1]) < 0) { 1381 + err("MT9M001 sensor initialization failed"); 1382 + return -ENODEV; 1383 + } 1384 + } 1385 + /* disable hflip and vflip */ 1386 + gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX); 1387 + sd->hstart = 2; 1388 + sd->vstart = 2; 1389 + return 0; 1390 + } 1391 + 1392 + static int hv7131r_init_sensor(struct gspca_dev *gspca_dev) 1393 + { 1394 + int i; 1395 + struct sd *sd = (struct sd *) gspca_dev; 1396 + 1397 + for (i = 0; i < ARRAY_SIZE(hv7131r_init); i++) { 1398 + if (i2c_w1(gspca_dev, hv7131r_init[i][0], 1399 + hv7131r_init[i][1]) < 0) { 1400 + err("HV7131R Sensor initialization failed"); 1401 + return -ENODEV; 1402 + } 1403 + } 1404 + sd->hstart = 0; 1405 + sd->vstart = 1; 1406 + return 0; 1407 + } 1408 + 1409 + #ifdef CONFIG_USB_GSPCA_SN9C20X_EVDEV 1410 + static int input_kthread(void *data) 1411 + { 1412 + struct gspca_dev *gspca_dev = (struct gspca_dev *)data; 1413 + struct sd *sd = (struct sd *) gspca_dev; 1414 + 1415 + DECLARE_WAIT_QUEUE_HEAD(wait); 1416 + set_freezable(); 1417 + for (;;) { 1418 + if (kthread_should_stop()) 1419 + break; 1420 + 1421 + if (reg_r(gspca_dev, 0x1005, 1) < 0) 1422 + continue; 1423 + 1424 + input_report_key(sd->input_dev, 1425 + KEY_CAMERA, 1426 + gspca_dev->usb_buf[0] & sd->input_gpio); 1427 + input_sync(sd->input_dev); 1428 + 1429 + wait_event_freezable_timeout(wait, 1430 + kthread_should_stop(), 1431 + msecs_to_jiffies(100)); 1432 + } 1433 + return 0; 1434 + } 1435 + 1436 + 1437 + static int sn9c20x_input_init(struct gspca_dev *gspca_dev) 1438 + { 1439 + struct sd *sd = (struct sd *) gspca_dev; 1440 + if (sd->input_gpio == 0) 1441 + return 0; 1442 + 1443 + sd->input_dev = input_allocate_device(); 1444 + if (!sd->input_dev) 1445 + return -ENOMEM; 1446 + 1447 + sd->input_dev->name = "SN9C20X Webcam"; 1448 + 1449 + sd->input_dev->phys = kasprintf(GFP_KERNEL, "usb-%s-%s", 1450 + gspca_dev->dev->bus->bus_name, 1451 + gspca_dev->dev->devpath); 1452 + 1453 + if (!sd->input_dev->phys) 1454 + return -ENOMEM; 1455 + 1456 + usb_to_input_id(gspca_dev->dev, &sd->input_dev->id); 1457 + sd->input_dev->dev.parent = &gspca_dev->dev->dev; 1458 + 1459 + set_bit(EV_KEY, sd->input_dev->evbit); 1460 + set_bit(KEY_CAMERA, sd->input_dev->keybit); 1461 + 1462 + if (input_register_device(sd->input_dev)) 1463 + return -EINVAL; 1464 + 1465 + sd->input_task = kthread_run(input_kthread, gspca_dev, "sn9c20x/%d", 1466 + gspca_dev->vdev.minor); 1467 + 1468 + if (IS_ERR(sd->input_task)) 1469 + return -EINVAL; 1470 + 1471 + return 0; 1472 + } 1473 + 1474 + static void sn9c20x_input_cleanup(struct gspca_dev *gspca_dev) 1475 + { 1476 + struct sd *sd = (struct sd *) gspca_dev; 1477 + if (sd->input_task != NULL && !IS_ERR(sd->input_task)) 1478 + kthread_stop(sd->input_task); 1479 + 1480 + if (sd->input_dev != NULL) { 1481 + input_unregister_device(sd->input_dev); 1482 + kfree(sd->input_dev->phys); 1483 + input_free_device(sd->input_dev); 1484 + sd->input_dev = NULL; 1485 + } 1486 + } 1487 + #endif 1488 + 1489 + static int set_cmatrix(struct gspca_dev *gspca_dev) 1490 + { 1491 + struct sd *sd = (struct sd *) gspca_dev; 1492 + s32 hue_coord, hue_index = 180 + sd->hue; 1493 + u8 cmatrix[21]; 1494 + memset(cmatrix, 0, 21); 1495 + 1496 + cmatrix[2] = (sd->contrast * 0x25 / 0x100) + 0x26; 1497 + cmatrix[0] = 0x13 + (cmatrix[2] - 0x26) * 0x13 / 0x25; 1498 + cmatrix[4] = 0x07 + (cmatrix[2] - 0x26) * 0x07 / 0x25; 1499 + cmatrix[18] = sd->brightness - 0x80; 1500 + 1501 + hue_coord = (hsv_red_x[hue_index] * sd->saturation) >> 8; 1502 + cmatrix[6] = (unsigned char)(hue_coord & 0xff); 1503 + cmatrix[7] = (unsigned char)((hue_coord >> 8) & 0x0f); 1504 + 1505 + hue_coord = (hsv_red_y[hue_index] * sd->saturation) >> 8; 1506 + cmatrix[8] = (unsigned char)(hue_coord & 0xff); 1507 + cmatrix[9] = (unsigned char)((hue_coord >> 8) & 0x0f); 1508 + 1509 + hue_coord = (hsv_green_x[hue_index] * sd->saturation) >> 8; 1510 + cmatrix[10] = (unsigned char)(hue_coord & 0xff); 1511 + cmatrix[11] = (unsigned char)((hue_coord >> 8) & 0x0f); 1512 + 1513 + hue_coord = (hsv_green_y[hue_index] * sd->saturation) >> 8; 1514 + cmatrix[12] = (unsigned char)(hue_coord & 0xff); 1515 + cmatrix[13] = (unsigned char)((hue_coord >> 8) & 0x0f); 1516 + 1517 + hue_coord = (hsv_blue_x[hue_index] * sd->saturation) >> 8; 1518 + cmatrix[14] = (unsigned char)(hue_coord & 0xff); 1519 + cmatrix[15] = (unsigned char)((hue_coord >> 8) & 0x0f); 1520 + 1521 + hue_coord = (hsv_blue_y[hue_index] * sd->saturation) >> 8; 1522 + cmatrix[16] = (unsigned char)(hue_coord & 0xff); 1523 + cmatrix[17] = (unsigned char)((hue_coord >> 8) & 0x0f); 1524 + 1525 + return reg_w(gspca_dev, 0x10e1, cmatrix, 21); 1526 + } 1527 + 1528 + static int set_gamma(struct gspca_dev *gspca_dev) 1529 + { 1530 + struct sd *sd = (struct sd *) gspca_dev; 1531 + u8 gamma[17]; 1532 + u8 gval = sd->gamma * 0xb8 / 0x100; 1533 + 1534 + 1535 + gamma[0] = 0x0a; 1536 + gamma[1] = 0x13 + (gval * (0xcb - 0x13) / 0xb8); 1537 + gamma[2] = 0x25 + (gval * (0xee - 0x25) / 0xb8); 1538 + gamma[3] = 0x37 + (gval * (0xfa - 0x37) / 0xb8); 1539 + gamma[4] = 0x45 + (gval * (0xfc - 0x45) / 0xb8); 1540 + gamma[5] = 0x55 + (gval * (0xfb - 0x55) / 0xb8); 1541 + gamma[6] = 0x65 + (gval * (0xfc - 0x65) / 0xb8); 1542 + gamma[7] = 0x74 + (gval * (0xfd - 0x74) / 0xb8); 1543 + gamma[8] = 0x83 + (gval * (0xfe - 0x83) / 0xb8); 1544 + gamma[9] = 0x92 + (gval * (0xfc - 0x92) / 0xb8); 1545 + gamma[10] = 0xa1 + (gval * (0xfc - 0xa1) / 0xb8); 1546 + gamma[11] = 0xb0 + (gval * (0xfc - 0xb0) / 0xb8); 1547 + gamma[12] = 0xbf + (gval * (0xfb - 0xbf) / 0xb8); 1548 + gamma[13] = 0xce + (gval * (0xfb - 0xce) / 0xb8); 1549 + gamma[14] = 0xdf + (gval * (0xfd - 0xdf) / 0xb8); 1550 + gamma[15] = 0xea + (gval * (0xf9 - 0xea) / 0xb8); 1551 + gamma[16] = 0xf5; 1552 + 1553 + return reg_w(gspca_dev, 0x1190, gamma, 17); 1554 + } 1555 + 1556 + static int set_redblue(struct gspca_dev *gspca_dev) 1557 + { 1558 + struct sd *sd = (struct sd *) gspca_dev; 1559 + reg_w1(gspca_dev, 0x118c, sd->red); 1560 + reg_w1(gspca_dev, 0x118f, sd->blue); 1561 + return 0; 1562 + } 1563 + 1564 + static int set_hvflip(struct gspca_dev *gspca_dev) 1565 + { 1566 + u8 value, tslb; 1567 + u16 value2; 1568 + struct sd *sd = (struct sd *) gspca_dev; 1569 + switch (sd->sensor) { 1570 + case SENSOR_OV9650: 1571 + i2c_r1(gspca_dev, 0x1e, &value); 1572 + value &= ~0x30; 1573 + tslb = 0x01; 1574 + if (sd->hflip) 1575 + value |= 0x20; 1576 + if (sd->vflip) { 1577 + value |= 0x10; 1578 + tslb = 0x49; 1579 + } 1580 + i2c_w1(gspca_dev, 0x1e, value); 1581 + i2c_w1(gspca_dev, 0x3a, tslb); 1582 + break; 1583 + case SENSOR_MT9V111: 1584 + case SENSOR_MT9V011: 1585 + i2c_r2(gspca_dev, 0x20, &value2); 1586 + value2 &= ~0xc0a0; 1587 + if (sd->hflip) 1588 + value2 |= 0x8080; 1589 + if (sd->vflip) 1590 + value2 |= 0x4020; 1591 + i2c_w2(gspca_dev, 0x20, value2); 1592 + break; 1593 + case SENSOR_MT9M111: 1594 + case SENSOR_MT9V112: 1595 + i2c_r2(gspca_dev, 0x20, &value2); 1596 + value2 &= ~0x0003; 1597 + if (sd->hflip) 1598 + value2 |= 0x0002; 1599 + if (sd->vflip) 1600 + value2 |= 0x0001; 1601 + i2c_w2(gspca_dev, 0x20, value2); 1602 + break; 1603 + case SENSOR_HV7131R: 1604 + i2c_r1(gspca_dev, 0x01, &value); 1605 + value &= ~0x03; 1606 + if (sd->vflip) 1607 + value |= 0x01; 1608 + if (sd->hflip) 1609 + value |= 0x02; 1610 + i2c_w1(gspca_dev, 0x01, value); 1611 + break; 1612 + } 1613 + return 0; 1614 + } 1615 + 1616 + static int set_exposure(struct gspca_dev *gspca_dev) 1617 + { 1618 + struct sd *sd = (struct sd *) gspca_dev; 1619 + u8 exp[8] = {0x81, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e}; 1620 + switch (sd->sensor) { 1621 + case SENSOR_OV7660: 1622 + case SENSOR_OV7670: 1623 + case SENSOR_SOI968: 1624 + case SENSOR_OV9655: 1625 + case SENSOR_OV9650: 1626 + exp[0] |= (3 << 4); 1627 + exp[2] = 0x2d; 1628 + exp[3] = sd->exposure & 0xff; 1629 + exp[4] = sd->exposure >> 8; 1630 + break; 1631 + case SENSOR_MT9M001: 1632 + case SENSOR_MT9M111: 1633 + case SENSOR_MT9V112: 1634 + case SENSOR_MT9V111: 1635 + case SENSOR_MT9V011: 1636 + exp[0] |= (3 << 4); 1637 + exp[2] = 0x09; 1638 + exp[3] = sd->exposure >> 8; 1639 + exp[4] = sd->exposure & 0xff; 1640 + break; 1641 + case SENSOR_HV7131R: 1642 + exp[0] |= (4 << 4); 1643 + exp[2] = 0x25; 1644 + exp[3] = ((sd->exposure * 0xffffff) / 0xffff) >> 16; 1645 + exp[4] = ((sd->exposure * 0xffffff) / 0xffff) >> 8; 1646 + exp[5] = ((sd->exposure * 0xffffff) / 0xffff) & 0xff; 1647 + break; 1648 + } 1649 + i2c_w(gspca_dev, exp); 1650 + return 0; 1651 + } 1652 + 1653 + static int set_gain(struct gspca_dev *gspca_dev) 1654 + { 1655 + struct sd *sd = (struct sd *) gspca_dev; 1656 + u8 gain[8] = {0x81, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d}; 1657 + switch (sd->sensor) { 1658 + case SENSOR_OV7660: 1659 + case SENSOR_OV7670: 1660 + case SENSOR_SOI968: 1661 + case SENSOR_OV9655: 1662 + case SENSOR_OV9650: 1663 + gain[0] |= (2 << 4); 1664 + gain[3] = ov_gain[sd->gain]; 1665 + break; 1666 + case SENSOR_MT9V011: 1667 + case SENSOR_MT9V111: 1668 + gain[0] |= (3 << 4); 1669 + gain[2] = 0x35; 1670 + gain[3] = micron1_gain[sd->gain] >> 8; 1671 + gain[4] = micron1_gain[sd->gain] & 0xff; 1672 + break; 1673 + case SENSOR_MT9V112: 1674 + case SENSOR_MT9M111: 1675 + gain[0] |= (3 << 4); 1676 + gain[2] = 0x2f; 1677 + gain[3] = micron1_gain[sd->gain] >> 8; 1678 + gain[4] = micron1_gain[sd->gain] & 0xff; 1679 + break; 1680 + case SENSOR_MT9M001: 1681 + gain[0] |= (3 << 4); 1682 + gain[2] = 0x2f; 1683 + gain[3] = micron2_gain[sd->gain] >> 8; 1684 + gain[4] = micron2_gain[sd->gain] & 0xff; 1685 + break; 1686 + case SENSOR_HV7131R: 1687 + gain[0] |= (2 << 4); 1688 + gain[2] = 0x30; 1689 + gain[3] = hv7131r_gain[sd->gain]; 1690 + break; 1691 + } 1692 + i2c_w(gspca_dev, gain); 1693 + return 0; 1694 + } 1695 + 1696 + static int sd_setbrightness(struct gspca_dev *gspca_dev, s32 val) 1697 + { 1698 + struct sd *sd = (struct sd *) gspca_dev; 1699 + 1700 + sd->brightness = val; 1701 + if (gspca_dev->streaming) 1702 + return set_cmatrix(gspca_dev); 1703 + return 0; 1704 + } 1705 + 1706 + static int sd_getbrightness(struct gspca_dev *gspca_dev, s32 *val) 1707 + { 1708 + struct sd *sd = (struct sd *) gspca_dev; 1709 + *val = sd->brightness; 1710 + return 0; 1711 + } 1712 + 1713 + 1714 + static int sd_setcontrast(struct gspca_dev *gspca_dev, s32 val) 1715 + { 1716 + struct sd *sd = (struct sd *) gspca_dev; 1717 + 1718 + sd->contrast = val; 1719 + if (gspca_dev->streaming) 1720 + return set_cmatrix(gspca_dev); 1721 + return 0; 1722 + } 1723 + 1724 + static int sd_getcontrast(struct gspca_dev *gspca_dev, s32 *val) 1725 + { 1726 + struct sd *sd = (struct sd *) gspca_dev; 1727 + *val = sd->contrast; 1728 + return 0; 1729 + } 1730 + 1731 + static int sd_setsaturation(struct gspca_dev *gspca_dev, s32 val) 1732 + { 1733 + struct sd *sd = (struct sd *) gspca_dev; 1734 + 1735 + sd->saturation = val; 1736 + if (gspca_dev->streaming) 1737 + return set_cmatrix(gspca_dev); 1738 + return 0; 1739 + } 1740 + 1741 + static int sd_getsaturation(struct gspca_dev *gspca_dev, s32 *val) 1742 + { 1743 + struct sd *sd = (struct sd *) gspca_dev; 1744 + *val = sd->saturation; 1745 + return 0; 1746 + } 1747 + 1748 + static int sd_sethue(struct gspca_dev *gspca_dev, s32 val) 1749 + { 1750 + struct sd *sd = (struct sd *) gspca_dev; 1751 + 1752 + sd->hue = val; 1753 + if (gspca_dev->streaming) 1754 + return set_cmatrix(gspca_dev); 1755 + return 0; 1756 + } 1757 + 1758 + static int sd_gethue(struct gspca_dev *gspca_dev, s32 *val) 1759 + { 1760 + struct sd *sd = (struct sd *) gspca_dev; 1761 + *val = sd->hue; 1762 + return 0; 1763 + } 1764 + 1765 + static int sd_setgamma(struct gspca_dev *gspca_dev, s32 val) 1766 + { 1767 + struct sd *sd = (struct sd *) gspca_dev; 1768 + 1769 + sd->gamma = val; 1770 + if (gspca_dev->streaming) 1771 + return set_gamma(gspca_dev); 1772 + return 0; 1773 + } 1774 + 1775 + static int sd_getgamma(struct gspca_dev *gspca_dev, s32 *val) 1776 + { 1777 + struct sd *sd = (struct sd *) gspca_dev; 1778 + *val = sd->gamma; 1779 + return 0; 1780 + } 1781 + 1782 + static int sd_setredbalance(struct gspca_dev *gspca_dev, s32 val) 1783 + { 1784 + struct sd *sd = (struct sd *) gspca_dev; 1785 + 1786 + sd->red = val; 1787 + if (gspca_dev->streaming) 1788 + return set_redblue(gspca_dev); 1789 + return 0; 1790 + } 1791 + 1792 + static int sd_getredbalance(struct gspca_dev *gspca_dev, s32 *val) 1793 + { 1794 + struct sd *sd = (struct sd *) gspca_dev; 1795 + *val = sd->red; 1796 + return 0; 1797 + } 1798 + 1799 + static int sd_setbluebalance(struct gspca_dev *gspca_dev, s32 val) 1800 + { 1801 + struct sd *sd = (struct sd *) gspca_dev; 1802 + 1803 + sd->blue = val; 1804 + if (gspca_dev->streaming) 1805 + return set_redblue(gspca_dev); 1806 + return 0; 1807 + } 1808 + 1809 + static int sd_getbluebalance(struct gspca_dev *gspca_dev, s32 *val) 1810 + { 1811 + struct sd *sd = (struct sd *) gspca_dev; 1812 + *val = sd->blue; 1813 + return 0; 1814 + } 1815 + 1816 + static int sd_sethflip(struct gspca_dev *gspca_dev, s32 val) 1817 + { 1818 + struct sd *sd = (struct sd *) gspca_dev; 1819 + 1820 + sd->hflip = val; 1821 + if (gspca_dev->streaming) 1822 + return set_hvflip(gspca_dev); 1823 + return 0; 1824 + } 1825 + 1826 + static int sd_gethflip(struct gspca_dev *gspca_dev, s32 *val) 1827 + { 1828 + struct sd *sd = (struct sd *) gspca_dev; 1829 + *val = sd->hflip; 1830 + return 0; 1831 + } 1832 + 1833 + static int sd_setvflip(struct gspca_dev *gspca_dev, s32 val) 1834 + { 1835 + struct sd *sd = (struct sd *) gspca_dev; 1836 + 1837 + sd->vflip = val; 1838 + if (gspca_dev->streaming) 1839 + return set_hvflip(gspca_dev); 1840 + return 0; 1841 + } 1842 + 1843 + static int sd_getvflip(struct gspca_dev *gspca_dev, s32 *val) 1844 + { 1845 + struct sd *sd = (struct sd *) gspca_dev; 1846 + *val = sd->vflip; 1847 + return 0; 1848 + } 1849 + 1850 + static int sd_setexposure(struct gspca_dev *gspca_dev, s32 val) 1851 + { 1852 + struct sd *sd = (struct sd *) gspca_dev; 1853 + 1854 + sd->exposure = val; 1855 + if (gspca_dev->streaming) 1856 + return set_exposure(gspca_dev); 1857 + return 0; 1858 + } 1859 + 1860 + static int sd_getexposure(struct gspca_dev *gspca_dev, s32 *val) 1861 + { 1862 + struct sd *sd = (struct sd *) gspca_dev; 1863 + *val = sd->exposure; 1864 + return 0; 1865 + } 1866 + 1867 + static int sd_setgain(struct gspca_dev *gspca_dev, s32 val) 1868 + { 1869 + struct sd *sd = (struct sd *) gspca_dev; 1870 + 1871 + sd->gain = val; 1872 + if (gspca_dev->streaming) 1873 + return set_gain(gspca_dev); 1874 + return 0; 1875 + } 1876 + 1877 + static int sd_getgain(struct gspca_dev *gspca_dev, s32 *val) 1878 + { 1879 + struct sd *sd = (struct sd *) gspca_dev; 1880 + *val = sd->gain; 1881 + return 0; 1882 + } 1883 + 1884 + static int sd_setautoexposure(struct gspca_dev *gspca_dev, s32 val) 1885 + { 1886 + struct sd *sd = (struct sd *) gspca_dev; 1887 + sd->auto_exposure = val; 1888 + return 0; 1889 + } 1890 + 1891 + static int sd_getautoexposure(struct gspca_dev *gspca_dev, s32 *val) 1892 + { 1893 + struct sd *sd = (struct sd *) gspca_dev; 1894 + *val = sd->auto_exposure; 1895 + return 0; 1896 + } 1897 + 1898 + #ifdef CONFIG_VIDEO_ADV_DEBUG 1899 + static int sd_dbg_g_register(struct gspca_dev *gspca_dev, 1900 + struct v4l2_dbg_register *reg) 1901 + { 1902 + struct sd *sd = (struct sd *) gspca_dev; 1903 + switch (reg->match.type) { 1904 + case V4L2_CHIP_MATCH_HOST: 1905 + if (reg->match.addr != 0) 1906 + return -EINVAL; 1907 + if (reg->reg < 0x1000 || reg->reg > 0x11ff) 1908 + return -EINVAL; 1909 + if (reg_r(gspca_dev, reg->reg, 1) < 0) 1910 + return -EINVAL; 1911 + reg->val = gspca_dev->usb_buf[0]; 1912 + return 0; 1913 + case V4L2_CHIP_MATCH_I2C_ADDR: 1914 + if (reg->match.addr != sd->i2c_addr) 1915 + return -EINVAL; 1916 + if (sd->sensor >= SENSOR_MT9V011 && 1917 + sd->sensor <= SENSOR_MT9M111) { 1918 + if (i2c_r2(gspca_dev, reg->reg, (u16 *)&reg->val) < 0) 1919 + return -EINVAL; 1920 + } else { 1921 + if (i2c_r1(gspca_dev, reg->reg, (u8 *)&reg->val) < 0) 1922 + return -EINVAL; 1923 + } 1924 + return 0; 1925 + } 1926 + return -EINVAL; 1927 + } 1928 + 1929 + static int sd_dbg_s_register(struct gspca_dev *gspca_dev, 1930 + struct v4l2_dbg_register *reg) 1931 + { 1932 + struct sd *sd = (struct sd *) gspca_dev; 1933 + switch (reg->match.type) { 1934 + case V4L2_CHIP_MATCH_HOST: 1935 + if (reg->match.addr != 0) 1936 + return -EINVAL; 1937 + if (reg->reg < 0x1000 || reg->reg > 0x11ff) 1938 + return -EINVAL; 1939 + if (reg_w1(gspca_dev, reg->reg, reg->val) < 0) 1940 + return -EINVAL; 1941 + return 0; 1942 + case V4L2_CHIP_MATCH_I2C_ADDR: 1943 + if (reg->match.addr != sd->i2c_addr) 1944 + return -EINVAL; 1945 + if (sd->sensor >= SENSOR_MT9V011 && 1946 + sd->sensor <= SENSOR_MT9M111) { 1947 + if (i2c_w2(gspca_dev, reg->reg, reg->val) < 0) 1948 + return -EINVAL; 1949 + } else { 1950 + if (i2c_w1(gspca_dev, reg->reg, reg->val) < 0) 1951 + return -EINVAL; 1952 + } 1953 + return 0; 1954 + } 1955 + return -EINVAL; 1956 + } 1957 + #endif 1958 + 1959 + static int sd_chip_ident(struct gspca_dev *gspca_dev, 1960 + struct v4l2_dbg_chip_ident *chip) 1961 + { 1962 + struct sd *sd = (struct sd *) gspca_dev; 1963 + 1964 + switch (chip->match.type) { 1965 + case V4L2_CHIP_MATCH_HOST: 1966 + if (chip->match.addr != 0) 1967 + return -EINVAL; 1968 + chip->revision = 0; 1969 + chip->ident = V4L2_IDENT_SN9C20X; 1970 + return 0; 1971 + case V4L2_CHIP_MATCH_I2C_ADDR: 1972 + if (chip->match.addr != sd->i2c_addr) 1973 + return -EINVAL; 1974 + chip->revision = 0; 1975 + chip->ident = i2c_ident[sd->sensor]; 1976 + return 0; 1977 + } 1978 + return -EINVAL; 1979 + } 1980 + 1981 + static int sd_config(struct gspca_dev *gspca_dev, 1982 + const struct usb_device_id *id) 1983 + { 1984 + struct sd *sd = (struct sd *) gspca_dev; 1985 + struct cam *cam; 1986 + 1987 + cam = &gspca_dev->cam; 1988 + 1989 + sd->sensor = (id->driver_info >> 8) & 0xff; 1990 + sd->i2c_addr = id->driver_info & 0xff; 1991 + 1992 + switch (sd->sensor) { 1993 + case SENSOR_OV9650: 1994 + cam->cam_mode = sxga_mode; 1995 + cam->nmodes = ARRAY_SIZE(sxga_mode); 1996 + break; 1997 + default: 1998 + cam->cam_mode = vga_mode; 1999 + cam->nmodes = ARRAY_SIZE(vga_mode); 2000 + } 2001 + 2002 + sd->old_step = 0; 2003 + sd->older_step = 0; 2004 + sd->exposure_step = 16; 2005 + 2006 + sd->brightness = BRIGHTNESS_DEFAULT; 2007 + sd->contrast = CONTRAST_DEFAULT; 2008 + sd->saturation = SATURATION_DEFAULT; 2009 + sd->hue = HUE_DEFAULT; 2010 + sd->gamma = GAMMA_DEFAULT; 2011 + sd->red = RED_DEFAULT; 2012 + sd->blue = BLUE_DEFAULT; 2013 + 2014 + sd->hflip = HFLIP_DEFAULT; 2015 + sd->vflip = VFLIP_DEFAULT; 2016 + sd->exposure = EXPOSURE_DEFAULT; 2017 + sd->gain = GAIN_DEFAULT; 2018 + sd->auto_exposure = AUTO_EXPOSURE_DEFAULT; 2019 + 2020 + sd->quality = 95; 2021 + 2022 + #ifdef CONFIG_USB_GSPCA_SN9C20X_EVDEV 2023 + sd->input_gpio = (id->driver_info >> 16) & 0xff; 2024 + if (sn9c20x_input_init(gspca_dev) < 0) 2025 + return -ENODEV; 2026 + #endif 2027 + return 0; 2028 + } 2029 + 2030 + static int sd_init(struct gspca_dev *gspca_dev) 2031 + { 2032 + struct sd *sd = (struct sd *) gspca_dev; 2033 + int i; 2034 + u8 value; 2035 + u8 i2c_init[9] = 2036 + {0x80, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03}; 2037 + 2038 + for (i = 0; i < ARRAY_SIZE(bridge_init); i++) { 2039 + value = bridge_init[i][1]; 2040 + if (reg_w(gspca_dev, bridge_init[i][0], &value, 1) < 0) { 2041 + err("Device initialization failed"); 2042 + return -ENODEV; 2043 + } 2044 + } 2045 + 2046 + if (reg_w(gspca_dev, 0x10c0, i2c_init, 9) < 0) { 2047 + err("Device initialization failed"); 2048 + return -ENODEV; 2049 + } 2050 + 2051 + switch (sd->sensor) { 2052 + case SENSOR_OV9650: 2053 + if (ov9650_init_sensor(gspca_dev) < 0) 2054 + return -ENODEV; 2055 + info("OV9650 sensor detected"); 2056 + break; 2057 + case SENSOR_OV9655: 2058 + if (ov9655_init_sensor(gspca_dev) < 0) 2059 + return -ENODEV; 2060 + info("OV9655 sensor detected"); 2061 + break; 2062 + case SENSOR_SOI968: 2063 + if (soi968_init_sensor(gspca_dev) < 0) 2064 + return -ENODEV; 2065 + info("SOI968 sensor detected"); 2066 + break; 2067 + case SENSOR_OV7660: 2068 + if (ov7660_init_sensor(gspca_dev) < 0) 2069 + return -ENODEV; 2070 + info("OV7660 sensor detected"); 2071 + break; 2072 + case SENSOR_OV7670: 2073 + if (ov7670_init_sensor(gspca_dev) < 0) 2074 + return -ENODEV; 2075 + info("OV7670 sensor detected"); 2076 + break; 2077 + case SENSOR_MT9VPRB: 2078 + if (mt9v_init_sensor(gspca_dev) < 0) 2079 + return -ENODEV; 2080 + break; 2081 + case SENSOR_MT9M111: 2082 + if (mt9m111_init_sensor(gspca_dev) < 0) 2083 + return -ENODEV; 2084 + info("MT9M111 sensor detected"); 2085 + break; 2086 + case SENSOR_MT9M001: 2087 + if (mt9m001_init_sensor(gspca_dev) < 0) 2088 + return -ENODEV; 2089 + info("MT9M001 sensor detected"); 2090 + break; 2091 + case SENSOR_HV7131R: 2092 + if (hv7131r_init_sensor(gspca_dev) < 0) 2093 + return -ENODEV; 2094 + info("HV7131R sensor detected"); 2095 + break; 2096 + default: 2097 + info("Unsupported Sensor"); 2098 + return -ENODEV; 2099 + } 2100 + 2101 + return 0; 2102 + } 2103 + 2104 + static void configure_sensor_output(struct gspca_dev *gspca_dev, int mode) 2105 + { 2106 + struct sd *sd = (struct sd *) gspca_dev; 2107 + u8 value; 2108 + switch (sd->sensor) { 2109 + case SENSOR_OV9650: 2110 + if (mode & MODE_SXGA) { 2111 + i2c_w1(gspca_dev, 0x17, 0x1b); 2112 + i2c_w1(gspca_dev, 0x18, 0xbc); 2113 + i2c_w1(gspca_dev, 0x19, 0x01); 2114 + i2c_w1(gspca_dev, 0x1a, 0x82); 2115 + i2c_r1(gspca_dev, 0x12, &value); 2116 + i2c_w1(gspca_dev, 0x12, value & 0x07); 2117 + } else { 2118 + i2c_w1(gspca_dev, 0x17, 0x24); 2119 + i2c_w1(gspca_dev, 0x18, 0xc5); 2120 + i2c_w1(gspca_dev, 0x19, 0x00); 2121 + i2c_w1(gspca_dev, 0x1a, 0x3c); 2122 + i2c_r1(gspca_dev, 0x12, &value); 2123 + i2c_w1(gspca_dev, 0x12, (value & 0x7) | 0x40); 2124 + } 2125 + break; 2126 + } 2127 + } 2128 + 2129 + #define HW_WIN(mode, hstart, vstart) \ 2130 + ((const u8 []){hstart & 0xff, hstart >> 8, \ 2131 + vstart & 0xff, vstart >> 8, \ 2132 + (mode & MODE_SXGA ? 1280 >> 4 : 640 >> 4), \ 2133 + (mode & MODE_SXGA ? 1024 >> 3 : 480 >> 3)}) 2134 + 2135 + #define CLR_WIN(width, height) \ 2136 + ((const u8 [])\ 2137 + {0, width >> 2, 0, height >> 1,\ 2138 + ((width >> 10) & 0x01) | ((height >> 8) & 0x6)}) 2139 + 2140 + static int sd_start(struct gspca_dev *gspca_dev) 2141 + { 2142 + struct sd *sd = (struct sd *) gspca_dev; 2143 + int mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; 2144 + int width = gspca_dev->width; 2145 + int height = gspca_dev->height; 2146 + u8 fmt, scale = 0; 2147 + 2148 + sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); 2149 + if (sd->jpeg_hdr == NULL) 2150 + return -ENOMEM; 2151 + 2152 + jpeg_define(sd->jpeg_hdr, height, width, 2153 + 0x21); 2154 + jpeg_set_qual(sd->jpeg_hdr, sd->quality); 2155 + 2156 + if (mode & MODE_RAW) 2157 + fmt = 0x2d; 2158 + else if (mode & MODE_JPEG) 2159 + fmt = 0x2c; 2160 + else 2161 + fmt = 0x2f; 2162 + 2163 + switch (mode & 0x0f) { 2164 + case 3: 2165 + scale = 0xc0; 2166 + info("Set 1280x1024"); 2167 + break; 2168 + case 2: 2169 + scale = 0x80; 2170 + info("Set 640x480"); 2171 + break; 2172 + case 1: 2173 + scale = 0x90; 2174 + info("Set 320x240"); 2175 + break; 2176 + case 0: 2177 + scale = 0xa0; 2178 + info("Set 160x120"); 2179 + break; 2180 + } 2181 + 2182 + configure_sensor_output(gspca_dev, mode); 2183 + reg_w(gspca_dev, 0x1100, sd->jpeg_hdr + JPEG_QT0_OFFSET, 64); 2184 + reg_w(gspca_dev, 0x1140, sd->jpeg_hdr + JPEG_QT1_OFFSET, 64); 2185 + reg_w(gspca_dev, 0x10fb, CLR_WIN(width, height), 5); 2186 + reg_w(gspca_dev, 0x1180, HW_WIN(mode, sd->hstart, sd->vstart), 6); 2187 + reg_w1(gspca_dev, 0x1189, scale); 2188 + reg_w1(gspca_dev, 0x10e0, fmt); 2189 + 2190 + set_cmatrix(gspca_dev); 2191 + set_gamma(gspca_dev); 2192 + set_redblue(gspca_dev); 2193 + set_gain(gspca_dev); 2194 + set_exposure(gspca_dev); 2195 + set_hvflip(gspca_dev); 2196 + 2197 + reg_r(gspca_dev, 0x1061, 1); 2198 + reg_w1(gspca_dev, 0x1061, gspca_dev->usb_buf[0] | 0x02); 2199 + return 0; 2200 + } 2201 + 2202 + static void sd_stopN(struct gspca_dev *gspca_dev) 2203 + { 2204 + reg_r(gspca_dev, 0x1061, 1); 2205 + reg_w1(gspca_dev, 0x1061, gspca_dev->usb_buf[0] & ~0x02); 2206 + } 2207 + 2208 + static void sd_stop0(struct gspca_dev *gspca_dev) 2209 + { 2210 + struct sd *sd = (struct sd *) gspca_dev; 2211 + kfree(sd->jpeg_hdr); 2212 + } 2213 + 2214 + static void do_autoexposure(struct gspca_dev *gspca_dev) 2215 + { 2216 + struct sd *sd = (struct sd *) gspca_dev; 2217 + int avg_lum, new_exp; 2218 + 2219 + if (!sd->auto_exposure) 2220 + return; 2221 + 2222 + avg_lum = atomic_read(&sd->avg_lum); 2223 + 2224 + /* 2225 + * some hardcoded values are present 2226 + * like those for maximal/minimal exposure 2227 + * and exposure steps 2228 + */ 2229 + if (avg_lum < MIN_AVG_LUM) { 2230 + if (sd->exposure > 0x1770) 2231 + return; 2232 + 2233 + new_exp = sd->exposure + sd->exposure_step; 2234 + if (new_exp > 0x1770) 2235 + new_exp = 0x1770; 2236 + if (new_exp < 0x10) 2237 + new_exp = 0x10; 2238 + sd->exposure = new_exp; 2239 + set_exposure(gspca_dev); 2240 + 2241 + sd->older_step = sd->old_step; 2242 + sd->old_step = 1; 2243 + 2244 + if (sd->old_step ^ sd->older_step) 2245 + sd->exposure_step /= 2; 2246 + else 2247 + sd->exposure_step += 2; 2248 + } 2249 + if (avg_lum > MAX_AVG_LUM) { 2250 + if (sd->exposure < 0x10) 2251 + return; 2252 + new_exp = sd->exposure - sd->exposure_step; 2253 + if (new_exp > 0x1700) 2254 + new_exp = 0x1770; 2255 + if (new_exp < 0x10) 2256 + new_exp = 0x10; 2257 + sd->exposure = new_exp; 2258 + set_exposure(gspca_dev); 2259 + sd->older_step = sd->old_step; 2260 + sd->old_step = 0; 2261 + 2262 + if (sd->old_step ^ sd->older_step) 2263 + sd->exposure_step /= 2; 2264 + else 2265 + sd->exposure_step += 2; 2266 + } 2267 + } 2268 + 2269 + static void sd_pkt_scan(struct gspca_dev *gspca_dev, 2270 + struct gspca_frame *frame, /* target */ 2271 + u8 *data, /* isoc packet */ 2272 + int len) /* iso packet length */ 2273 + { 2274 + struct sd *sd = (struct sd *) gspca_dev; 2275 + int avg_lum; 2276 + static unsigned char frame_header[] = 2277 + {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96}; 2278 + if (len == 64 && memcmp(data, frame_header, 6) == 0) { 2279 + avg_lum = ((data[35] >> 2) & 3) | 2280 + (data[20] << 2) | 2281 + (data[19] << 10); 2282 + avg_lum += ((data[35] >> 4) & 3) | 2283 + (data[22] << 2) | 2284 + (data[21] << 10); 2285 + avg_lum += ((data[35] >> 6) & 3) | 2286 + (data[24] << 2) | 2287 + (data[23] << 10); 2288 + avg_lum += (data[36] & 3) | 2289 + (data[26] << 2) | 2290 + (data[25] << 10); 2291 + avg_lum += ((data[36] >> 2) & 3) | 2292 + (data[28] << 2) | 2293 + (data[27] << 10); 2294 + avg_lum += ((data[36] >> 4) & 3) | 2295 + (data[30] << 2) | 2296 + (data[29] << 10); 2297 + avg_lum += ((data[36] >> 6) & 3) | 2298 + (data[32] << 2) | 2299 + (data[31] << 10); 2300 + avg_lum += ((data[44] >> 4) & 3) | 2301 + (data[34] << 2) | 2302 + (data[33] << 10); 2303 + avg_lum >>= 9; 2304 + atomic_set(&sd->avg_lum, avg_lum); 2305 + gspca_frame_add(gspca_dev, LAST_PACKET, 2306 + frame, data, len); 2307 + return; 2308 + } 2309 + if (gspca_dev->last_packet_type == LAST_PACKET) { 2310 + if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv 2311 + & MODE_JPEG) { 2312 + gspca_frame_add(gspca_dev, FIRST_PACKET, frame, 2313 + sd->jpeg_hdr, JPEG_HDR_SZ); 2314 + gspca_frame_add(gspca_dev, INTER_PACKET, frame, 2315 + data, len); 2316 + } else { 2317 + gspca_frame_add(gspca_dev, FIRST_PACKET, frame, 2318 + data, len); 2319 + } 2320 + } else { 2321 + gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); 2322 + } 2323 + } 2324 + 2325 + /* sub-driver description */ 2326 + static const struct sd_desc sd_desc = { 2327 + .name = MODULE_NAME, 2328 + .ctrls = sd_ctrls, 2329 + .nctrls = ARRAY_SIZE(sd_ctrls), 2330 + .config = sd_config, 2331 + .init = sd_init, 2332 + .start = sd_start, 2333 + .stopN = sd_stopN, 2334 + .stop0 = sd_stop0, 2335 + .pkt_scan = sd_pkt_scan, 2336 + .dq_callback = do_autoexposure, 2337 + #ifdef CONFIG_VIDEO_ADV_DEBUG 2338 + .set_register = sd_dbg_s_register, 2339 + .get_register = sd_dbg_g_register, 2340 + #endif 2341 + .get_chip_ident = sd_chip_ident, 2342 + }; 2343 + 2344 + #define SN9C20X(sensor, i2c_addr, button_mask) \ 2345 + .driver_info = (button_mask << 16) \ 2346 + | (SENSOR_ ## sensor << 8) \ 2347 + | (i2c_addr) 2348 + 2349 + static const __devinitdata struct usb_device_id device_table[] = { 2350 + {USB_DEVICE(0x0c45, 0x6240), SN9C20X(MT9M001, 0x5d, 0)}, 2351 + {USB_DEVICE(0x0c45, 0x6242), SN9C20X(MT9M111, 0x5d, 0)}, 2352 + {USB_DEVICE(0x0c45, 0x6248), SN9C20X(OV9655, 0x30, 0)}, 2353 + {USB_DEVICE(0x0c45, 0x624e), SN9C20X(SOI968, 0x30, 0x10)}, 2354 + {USB_DEVICE(0x0c45, 0x624f), SN9C20X(OV9650, 0x30, 0)}, 2355 + {USB_DEVICE(0x0c45, 0x6251), SN9C20X(OV9650, 0x30, 0)}, 2356 + {USB_DEVICE(0x0c45, 0x6253), SN9C20X(OV9650, 0x30, 0)}, 2357 + {USB_DEVICE(0x0c45, 0x6260), SN9C20X(OV7670, 0x21, 0)}, 2358 + {USB_DEVICE(0x0c45, 0x6270), SN9C20X(MT9VPRB, 0x00, 0)}, 2359 + {USB_DEVICE(0x0c45, 0x627b), SN9C20X(OV7660, 0x21, 0)}, 2360 + {USB_DEVICE(0x0c45, 0x627c), SN9C20X(HV7131R, 0x11, 0)}, 2361 + {USB_DEVICE(0x0c45, 0x627f), SN9C20X(OV9650, 0x30, 0)}, 2362 + {USB_DEVICE(0x0c45, 0x6280), SN9C20X(MT9M001, 0x5d, 0)}, 2363 + {USB_DEVICE(0x0c45, 0x6282), SN9C20X(MT9M111, 0x5d, 0)}, 2364 + {USB_DEVICE(0x0c45, 0x6288), SN9C20X(OV9655, 0x30, 0)}, 2365 + {USB_DEVICE(0x0c45, 0x628e), SN9C20X(SOI968, 0x30, 0)}, 2366 + {USB_DEVICE(0x0c45, 0x628f), SN9C20X(OV9650, 0x30, 0)}, 2367 + {USB_DEVICE(0x0c45, 0x62a0), SN9C20X(OV7670, 0x21, 0)}, 2368 + {USB_DEVICE(0x0c45, 0x62b0), SN9C20X(MT9VPRB, 0x00, 0)}, 2369 + {USB_DEVICE(0x0c45, 0x62b3), SN9C20X(OV9655, 0x30, 0)}, 2370 + {USB_DEVICE(0x0c45, 0x62bb), SN9C20X(OV7660, 0x21, 0)}, 2371 + {USB_DEVICE(0x0c45, 0x62bc), SN9C20X(HV7131R, 0x11, 0)}, 2372 + {USB_DEVICE(0x045e, 0x00f4), SN9C20X(OV9650, 0x30, 0)}, 2373 + {USB_DEVICE(0x145f, 0x013d), SN9C20X(OV7660, 0x21, 0)}, 2374 + {USB_DEVICE(0x0458, 0x7029), SN9C20X(HV7131R, 0x11, 0)}, 2375 + {USB_DEVICE(0xa168, 0x0610), SN9C20X(HV7131R, 0x11, 0)}, 2376 + {USB_DEVICE(0xa168, 0x0611), SN9C20X(HV7131R, 0x11, 0)}, 2377 + {USB_DEVICE(0xa168, 0x0613), SN9C20X(HV7131R, 0x11, 0)}, 2378 + {USB_DEVICE(0xa168, 0x0618), SN9C20X(HV7131R, 0x11, 0)}, 2379 + {USB_DEVICE(0xa168, 0x0614), SN9C20X(MT9M111, 0x5d, 0)}, 2380 + {USB_DEVICE(0xa168, 0x0615), SN9C20X(MT9M111, 0x5d, 0)}, 2381 + {USB_DEVICE(0xa168, 0x0617), SN9C20X(MT9M111, 0x5d, 0)}, 2382 + {} 2383 + }; 2384 + MODULE_DEVICE_TABLE(usb, device_table); 2385 + 2386 + /* -- device connect -- */ 2387 + static int sd_probe(struct usb_interface *intf, 2388 + const struct usb_device_id *id) 2389 + { 2390 + return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), 2391 + THIS_MODULE); 2392 + } 2393 + 2394 + static void sd_disconnect(struct usb_interface *intf) 2395 + { 2396 + #ifdef CONFIG_USB_GSPCA_SN9C20X_EVDEV 2397 + struct gspca_dev *gspca_dev = usb_get_intfdata(intf); 2398 + 2399 + sn9c20x_input_cleanup(gspca_dev); 2400 + #endif 2401 + 2402 + gspca_disconnect(intf); 2403 + } 2404 + 2405 + static struct usb_driver sd_driver = { 2406 + .name = MODULE_NAME, 2407 + .id_table = device_table, 2408 + .probe = sd_probe, 2409 + .disconnect = sd_disconnect, 2410 + #ifdef CONFIG_PM 2411 + .suspend = gspca_suspend, 2412 + .resume = gspca_resume, 2413 + .reset_resume = gspca_resume, 2414 + #endif 2415 + }; 2416 + 2417 + /* -- module insert / remove -- */ 2418 + static int __init sd_mod_init(void) 2419 + { 2420 + int ret; 2421 + ret = usb_register(&sd_driver); 2422 + if (ret < 0) 2423 + return ret; 2424 + info("registered"); 2425 + return 0; 2426 + } 2427 + static void __exit sd_mod_exit(void) 2428 + { 2429 + usb_deregister(&sd_driver); 2430 + info("deregistered"); 2431 + } 2432 + 2433 + module_init(sd_mod_init); 2434 + module_exit(sd_mod_exit);
+4
drivers/media/video/gspca/sonixj.c
··· 1634 1634 { 1635 1635 struct sd *sd = (struct sd *) gspca_dev; 1636 1636 1637 + if (gspca_dev->ctrl_dis & (1 << FREQ_IDX)) 1638 + return; 1637 1639 if (sd->sensor == SENSOR_OV7660) { 1638 1640 switch (sd->freq) { 1639 1641 case 0: /* Banding filter disabled */ ··· 1737 1735 1738 1736 /* create the JPEG header */ 1739 1737 sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); 1738 + if (!sd->jpeg_hdr) 1739 + return -ENOMEM; 1740 1740 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, 1741 1741 0x21); /* JPEG 422 */ 1742 1742 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+2
drivers/media/video/gspca/spca500.c
··· 670 670 671 671 /* create the JPEG header */ 672 672 sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); 673 + if (!sd->jpeg_hdr) 674 + return -ENOMEM; 673 675 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, 674 676 0x22); /* JPEG 411 */ 675 677 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+2
drivers/media/video/gspca/stk014.c
··· 333 333 334 334 /* create the JPEG header */ 335 335 sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); 336 + if (!sd->jpeg_hdr) 337 + return -ENOMEM; 336 338 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, 337 339 0x22); /* JPEG 411 */ 338 340 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+10 -6
drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c
··· 64 64 { 65 65 HDCS_1X00_DEF_WIDTH, 66 66 HDCS_1X00_DEF_HEIGHT, 67 - V4L2_PIX_FMT_SBGGR8, 67 + V4L2_PIX_FMT_SGRBG8, 68 68 V4L2_FIELD_NONE, 69 69 .sizeimage = 70 70 HDCS_1X00_DEF_WIDTH * HDCS_1X00_DEF_HEIGHT, ··· 80 80 { 81 81 HDCS_1020_DEF_WIDTH, 82 82 HDCS_1020_DEF_HEIGHT, 83 - V4L2_PIX_FMT_SBGGR8, 83 + V4L2_PIX_FMT_SGRBG8, 84 84 V4L2_FIELD_NONE, 85 85 .sizeimage = 86 86 HDCS_1020_DEF_WIDTH * HDCS_1020_DEF_HEIGHT, ··· 131 131 (reg + len > 0xff))) 132 132 return -EINVAL; 133 133 134 - for (i = 0; i < len; i++, reg++) { 135 - regs[2*i] = reg; 136 - regs[2*i+1] = vals[i]; 134 + for (i = 0; i < len; i++) { 135 + regs[2 * i] = reg; 136 + regs[2 * i + 1] = vals[i]; 137 + /* All addresses are shifted left one bit as bit 0 toggles r/w */ 138 + reg += 2; 137 139 } 138 140 139 141 return stv06xx_write_sensor_bytes(sd, regs, len); ··· 176 174 } 177 175 178 176 ret = stv06xx_write_sensor(sd, HDCS_REG_CONTROL(sd), val); 179 - if (ret < 0) 177 + 178 + /* Update the state if the write succeeded */ 179 + if (!ret) 180 180 hdcs->state = state; 181 181 182 182 return ret;
+2
drivers/media/video/gspca/sunplus.c
··· 973 973 974 974 /* create the JPEG header */ 975 975 sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); 976 + if (!sd->jpeg_hdr) 977 + return -ENOMEM; 976 978 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, 977 979 0x22); /* JPEG 411 */ 978 980 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+2
drivers/media/video/gspca/zc3xx.c
··· 7243 7243 7244 7244 /* create the JPEG header */ 7245 7245 sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); 7246 + if (!sd->jpeg_hdr) 7247 + return -ENOMEM; 7246 7248 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, 7247 7249 0x21); /* JPEG 422 */ 7248 7250 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+67 -2
drivers/media/video/mt9v011.c
··· 8 8 #include <linux/i2c.h> 9 9 #include <linux/videodev2.h> 10 10 #include <linux/delay.h> 11 + #include <asm/div64.h> 11 12 #include <media/v4l2-device.h> 12 13 #include "mt9v011.h" 13 14 #include <media/v4l2-i2c-drv.h> ··· 58 57 struct mt9v011 { 59 58 struct v4l2_subdev sd; 60 59 unsigned width, height; 60 + unsigned xtal; 61 61 62 62 u16 global_gain, red_bal, blue_bal; 63 63 }; ··· 133 131 { R1E_MT9V011_DIGITAL_ZOOM, 0x0000 }, 134 132 { R20_MT9V011_READ_MODE, 0x1000 }, 135 133 136 - { R07_MT9V011_OUT_CTRL, 0x000a }, /* chip enable */ 134 + { R07_MT9V011_OUT_CTRL, 0x0002 }, /* chip enable */ 137 135 }; 138 136 139 137 static void set_balance(struct v4l2_subdev *sd) ··· 154 152 mt9v011_write(sd, R2E_MT9V011_GREEN_2_GAIN, green1_gain); 155 153 mt9v011_write(sd, R2C_MT9V011_BLUE_GAIN, blue_gain); 156 154 mt9v011_write(sd, R2D_MT9V011_RED_GAIN, red_gain); 155 + } 156 + 157 + static void calc_fps(struct v4l2_subdev *sd) 158 + { 159 + struct mt9v011 *core = to_mt9v011(sd); 160 + unsigned height, width, hblank, vblank, speed; 161 + unsigned row_time, t_time; 162 + u64 frames_per_ms; 163 + unsigned tmp; 164 + 165 + height = mt9v011_read(sd, R03_MT9V011_HEIGHT); 166 + width = mt9v011_read(sd, R04_MT9V011_WIDTH); 167 + hblank = mt9v011_read(sd, R05_MT9V011_HBLANK); 168 + vblank = mt9v011_read(sd, R06_MT9V011_VBLANK); 169 + speed = mt9v011_read(sd, R0A_MT9V011_CLK_SPEED); 170 + 171 + row_time = (width + 113 + hblank) * (speed + 2); 172 + t_time = row_time * (height + vblank + 1); 173 + 174 + frames_per_ms = core->xtal * 1000l; 175 + do_div(frames_per_ms, t_time); 176 + tmp = frames_per_ms; 177 + 178 + v4l2_dbg(1, debug, sd, "Programmed to %u.%03u fps (%d pixel clcks)\n", 179 + tmp / 1000, tmp % 1000, t_time); 157 180 } 158 181 159 182 static void set_res(struct v4l2_subdev *sd) ··· 202 175 mt9v011_write(sd, R04_MT9V011_WIDTH, core->width); 203 176 mt9v011_write(sd, R05_MT9V011_HBLANK, 771 - core->width); 204 177 205 - vstart = 8 + (640 - core->height) / 2; 178 + vstart = 8 + (480 - core->height) / 2; 206 179 mt9v011_write(sd, R01_MT9V011_ROWSTART, vstart); 207 180 mt9v011_write(sd, R03_MT9V011_HEIGHT, core->height); 208 181 mt9v011_write(sd, R06_MT9V011_VBLANK, 508 - core->height); 182 + 183 + calc_fps(sd); 209 184 }; 210 185 211 186 static int mt9v011_reset(struct v4l2_subdev *sd, u32 val) ··· 243 214 } 244 215 return -EINVAL; 245 216 } 217 + 218 + static int mt9v011_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) 219 + { 220 + int i; 221 + 222 + v4l2_dbg(1, debug, sd, "queryctrl called\n"); 223 + 224 + for (i = 0; i < ARRAY_SIZE(mt9v011_qctrl); i++) 225 + if (qc->id && qc->id == mt9v011_qctrl[i].id) { 226 + memcpy(qc, &(mt9v011_qctrl[i]), 227 + sizeof(*qc)); 228 + return 0; 229 + } 230 + 231 + return -EINVAL; 232 + } 233 + 246 234 247 235 static int mt9v011_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) 248 236 { ··· 340 294 return 0; 341 295 } 342 296 297 + static int mt9v011_s_config(struct v4l2_subdev *sd, int dumb, void *data) 298 + { 299 + struct mt9v011 *core = to_mt9v011(sd); 300 + unsigned *xtal = data; 301 + 302 + v4l2_dbg(1, debug, sd, "s_config called\n"); 303 + 304 + if (xtal) { 305 + core->xtal = *xtal; 306 + v4l2_dbg(1, debug, sd, "xtal set to %d.%03d MHz\n", 307 + *xtal / 1000000, (*xtal / 1000) % 1000); 308 + } 309 + 310 + return 0; 311 + } 312 + 343 313 344 314 #ifdef CONFIG_VIDEO_ADV_DEBUG 345 315 static int mt9v011_g_register(struct v4l2_subdev *sd, ··· 400 338 } 401 339 402 340 static const struct v4l2_subdev_core_ops mt9v011_core_ops = { 341 + .queryctrl = mt9v011_queryctrl, 403 342 .g_ctrl = mt9v011_g_ctrl, 404 343 .s_ctrl = mt9v011_s_ctrl, 405 344 .reset = mt9v011_reset, 345 + .s_config = mt9v011_s_config, 406 346 .g_chip_ident = mt9v011_g_chip_ident, 407 347 #ifdef CONFIG_VIDEO_ADV_DEBUG 408 348 .g_register = mt9v011_g_register, ··· 459 395 core->global_gain = 0x0024; 460 396 core->width = 640; 461 397 core->height = 480; 398 + core->xtal = 27000000; /* Hz */ 462 399 463 400 v4l_info(c, "chip found @ 0x%02x (%s)\n", 464 401 c->addr << 1, c->adapter->name);
+1
include/linux/videodev2.h
··· 338 338 /* Vendor-specific formats */ 339 339 #define V4L2_PIX_FMT_WNVA v4l2_fourcc('W', 'N', 'V', 'A') /* Winnov hw compress */ 340 340 #define V4L2_PIX_FMT_SN9C10X v4l2_fourcc('S', '9', '1', '0') /* SN9C10x compression */ 341 + #define V4L2_PIX_FMT_SN9C20X_I420 v4l2_fourcc('S', '9', '2', '0') /* SN9C20x YUV 4:2:0 */ 341 342 #define V4L2_PIX_FMT_PWC1 v4l2_fourcc('P', 'W', 'C', '1') /* pwc older webcam */ 342 343 #define V4L2_PIX_FMT_PWC2 v4l2_fourcc('P', 'W', 'C', '2') /* pwc newer webcam */ 343 344 #define V4L2_PIX_FMT_ET61X251 v4l2_fourcc('E', '6', '2', '5') /* ET61X251 compression */
+12
include/media/v4l2-chip-ident.h
··· 60 60 V4L2_IDENT_OV7670 = 250, 61 61 V4L2_IDENT_OV7720 = 251, 62 62 V4L2_IDENT_OV7725 = 252, 63 + V4L2_IDENT_OV7660 = 253, 64 + V4L2_IDENT_OV9650 = 254, 65 + V4L2_IDENT_OV9655 = 255, 66 + V4L2_IDENT_SOI968 = 256, 63 67 64 68 /* module saa7146: reserved range 300-309 */ 65 69 V4L2_IDENT_SAA7146 = 300, ··· 165 161 /* module tw9910: just ident 9910 */ 166 162 V4L2_IDENT_TW9910 = 9910, 167 163 164 + /* module sn9c20x: just ident 10000 */ 165 + V4L2_IDENT_SN9C20X = 10000, 166 + 168 167 /* module msp3400: reserved range 34000-34999 and 44000-44999 */ 169 168 V4L2_IDENT_MSPX4XX = 34000, /* generic MSPX4XX identifier, only 170 169 use internally (tveeprom.c). */ ··· 244 237 V4L2_IDENT_MT9V022IX7ATC = 45010, /* No way to detect "normal" I77ATx */ 245 238 V4L2_IDENT_MT9V022IX7ATM = 45015, /* and "lead free" IA7ATx chips */ 246 239 V4L2_IDENT_MT9T031 = 45020, 240 + V4L2_IDENT_MT9V111 = 45031, 241 + V4L2_IDENT_MT9V112 = 45032, 242 + 243 + /* HV7131R CMOS sensor: just ident 46000 */ 244 + V4L2_IDENT_HV7131R = 46000, 247 245 248 246 /* module cs53132a: just ident 53132 */ 249 247 V4L2_IDENT_CS53l32A = 53132,