diff options
30 files changed, 2973 insertions, 170 deletions
diff --git a/Documentation/video4linux/CARDLIST.em28xx b/Documentation/video4linux/CARDLIST.em28xx index 014d255231fc..68c236c01846 100644 --- a/Documentation/video4linux/CARDLIST.em28xx +++ b/Documentation/video4linux/CARDLIST.em28xx | |||
| @@ -20,7 +20,7 @@ | |||
| 20 | 19 -> EM2860/SAA711X Reference Design (em2860) | 20 | 19 -> EM2860/SAA711X Reference Design (em2860) |
| 21 | 20 -> AMD ATI TV Wonder HD 600 (em2880) [0438:b002] | 21 | 20 -> AMD ATI TV Wonder HD 600 (em2880) [0438:b002] |
| 22 | 21 -> eMPIA Technology, Inc. GrabBeeX+ Video Encoder (em2800) [eb1a:2801] | 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 | 23 -> Huaqi DLCW-130 (em2750) | 24 | 23 -> Huaqi DLCW-130 (em2750) |
| 25 | 24 -> D-Link DUB-T210 TV Tuner (em2820/em2840) [2001:f112] | 25 | 24 -> D-Link DUB-T210 TV Tuner (em2820/em2840) [2001:f112] |
| 26 | 25 -> Gadmei UTV310 (em2820/em2840) | 26 | 25 -> Gadmei UTV310 (em2820/em2840) |
diff --git a/Documentation/video4linux/gspca.txt b/Documentation/video4linux/gspca.txt index 2bcf78896e22..573f95b58807 100644 --- a/Documentation/video4linux/gspca.txt +++ b/Documentation/video4linux/gspca.txt | |||
| @@ -44,7 +44,9 @@ zc3xx 0458:7007 Genius VideoCam V2 | |||
| 44 | zc3xx 0458:700c Genius VideoCam V3 | 44 | zc3xx 0458:700c Genius VideoCam V3 |
| 45 | zc3xx 0458:700f Genius VideoCam Web V2 | 45 | zc3xx 0458:700f Genius VideoCam Web V2 |
| 46 | sonixj 0458:7025 Genius Eye 311Q | 46 | sonixj 0458:7025 Genius Eye 311Q |
| 47 | sn9c20x 0458:7029 Genius Look 320s | ||
| 47 | sonixj 0458:702e Genius Slim 310 NB | 48 | sonixj 0458:702e Genius Slim 310 NB |
| 49 | sn9c20x 045e:00f4 LifeCam VX-6000 (SN9C20x + OV9650) | ||
| 48 | sonixj 045e:00f5 MicroSoft VX3000 | 50 | sonixj 045e:00f5 MicroSoft VX3000 |
| 49 | sonixj 045e:00f7 MicroSoft VX1000 | 51 | sonixj 045e:00f7 MicroSoft VX1000 |
| 50 | ov519 045e:028c Micro$oft xbox cam | 52 | ov519 045e:028c Micro$oft xbox cam |
| @@ -282,6 +284,28 @@ sonixj 0c45:613a Microdia Sonix PC Camera | |||
| 282 | sonixj 0c45:613b Surfer SN-206 | 284 | sonixj 0c45:613b Surfer SN-206 |
| 283 | sonixj 0c45:613c Sonix Pccam168 | 285 | sonixj 0c45:613c Sonix Pccam168 |
| 284 | sonixj 0c45:6143 Sonix Pccam168 | 286 | sonixj 0c45:6143 Sonix Pccam168 |
| 287 | sn9c20x 0c45:6240 PC Camera (SN9C201 + MT9M001) | ||
| 288 | sn9c20x 0c45:6242 PC Camera (SN9C201 + MT9M111) | ||
| 289 | sn9c20x 0c45:6248 PC Camera (SN9C201 + OV9655) | ||
| 290 | sn9c20x 0c45:624e PC Camera (SN9C201 + SOI968) | ||
| 291 | sn9c20x 0c45:624f PC Camera (SN9C201 + OV9650) | ||
| 292 | sn9c20x 0c45:6251 PC Camera (SN9C201 + OV9650) | ||
| 293 | sn9c20x 0c45:6253 PC Camera (SN9C201 + OV9650) | ||
| 294 | sn9c20x 0c45:6260 PC Camera (SN9C201 + OV7670) | ||
| 295 | sn9c20x 0c45:6270 PC Camera (SN9C201 + MT9V011/MT9V111/MT9V112) | ||
| 296 | sn9c20x 0c45:627b PC Camera (SN9C201 + OV7660) | ||
| 297 | sn9c20x 0c45:627c PC Camera (SN9C201 + HV7131R) | ||
| 298 | sn9c20x 0c45:627f PC Camera (SN9C201 + OV9650) | ||
| 299 | sn9c20x 0c45:6280 PC Camera (SN9C202 + MT9M001) | ||
| 300 | sn9c20x 0c45:6282 PC Camera (SN9C202 + MT9M111) | ||
| 301 | sn9c20x 0c45:6288 PC Camera (SN9C202 + OV9655) | ||
| 302 | sn9c20x 0c45:628e PC Camera (SN9C202 + SOI968) | ||
| 303 | sn9c20x 0c45:628f PC Camera (SN9C202 + OV9650) | ||
| 304 | sn9c20x 0c45:62a0 PC Camera (SN9C202 + OV7670) | ||
| 305 | sn9c20x 0c45:62b0 PC Camera (SN9C202 + MT9V011/MT9V111/MT9V112) | ||
| 306 | sn9c20x 0c45:62b3 PC Camera (SN9C202 + OV9655) | ||
| 307 | sn9c20x 0c45:62bb PC Camera (SN9C202 + OV7660) | ||
| 308 | sn9c20x 0c45:62bc PC Camera (SN9C202 + HV7131R) | ||
| 285 | sunplus 0d64:0303 Sunplus FashionCam DXG | 309 | sunplus 0d64:0303 Sunplus FashionCam DXG |
| 286 | etoms 102c:6151 Qcam Sangha CIF | 310 | etoms 102c:6151 Qcam Sangha CIF |
| 287 | etoms 102c:6251 Qcam xxxxxx VGA | 311 | etoms 102c:6251 Qcam xxxxxx VGA |
| @@ -290,6 +314,7 @@ spca561 10fd:7e50 FlyCam Usb 100 | |||
| 290 | zc3xx 10fd:8050 Typhoon Webshot II USB 300k | 314 | zc3xx 10fd:8050 Typhoon Webshot II USB 300k |
| 291 | ov534 1415:2000 Sony HD Eye for PS3 (SLEH 00201) | 315 | ov534 1415:2000 Sony HD Eye for PS3 (SLEH 00201) |
| 292 | pac207 145f:013a Trust WB-1300N | 316 | pac207 145f:013a Trust WB-1300N |
| 317 | sn9c20x 145f:013d Trust WB-3600R | ||
| 293 | vc032x 15b8:6001 HP 2.0 Megapixel | 318 | vc032x 15b8:6001 HP 2.0 Megapixel |
| 294 | vc032x 15b8:6002 HP 2.0 Megapixel rz406aa | 319 | vc032x 15b8:6002 HP 2.0 Megapixel rz406aa |
| 295 | spca501 1776:501c Arowana 300K CMOS Camera | 320 | spca501 1776:501c Arowana 300K CMOS Camera |
| @@ -300,4 +325,11 @@ spca500 2899:012c Toptro Industrial | |||
| 300 | spca508 8086:0110 Intel Easy PC Camera | 325 | spca508 8086:0110 Intel Easy PC Camera |
| 301 | spca500 8086:0630 Intel Pocket PC Camera | 326 | spca500 8086:0630 Intel Pocket PC Camera |
| 302 | spca506 99fa:8988 Grandtec V.cap | 327 | spca506 99fa:8988 Grandtec V.cap |
| 328 | sn9c20x a168:0610 Dino-Lite Digital Microscope (SN9C201 + HV7131R) | ||
| 329 | sn9c20x a168:0611 Dino-Lite Digital Microscope (SN9C201 + HV7131R) | ||
| 330 | sn9c20x a168:0613 Dino-Lite Digital Microscope (SN9C201 + HV7131R) | ||
| 331 | sn9c20x a168:0618 Dino-Lite Digital Microscope (SN9C201 + HV7131R) | ||
| 332 | sn9c20x a168:0614 Dino-Lite Digital Microscope (SN9C201 + MT9M111) | ||
| 333 | sn9c20x a168:0615 Dino-Lite Digital Microscope (SN9C201 + MT9M111) | ||
| 334 | sn9c20x a168:0617 Dino-Lite Digital Microscope (SN9C201 + MT9M111) | ||
| 303 | spca561 abcd:cdee Petcam | 335 | spca561 abcd:cdee Petcam |
diff --git a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c index efb4a6c2b57a..9a6307a347b2 100644 --- a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c +++ b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c | |||
| @@ -20,8 +20,14 @@ | |||
| 20 | #include "tuner-simple.h" | 20 | #include "tuner-simple.h" |
| 21 | #include "stv0297.h" | 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 | /* lnb control */ | 29 | /* lnb control */ |
| 24 | #if defined(CONFIG_DVB_MT312_MODULE) || defined(CONFIG_DVB_STV0299_MODULE) | 30 | #if FE_SUPPORTED(MT312) || FE_SUPPORTED(STV0299) |
| 25 | static int flexcop_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) | 31 | static int flexcop_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) |
| 26 | { | 32 | { |
| 27 | struct flexcop_device *fc = fe->dvb->priv; | 33 | struct flexcop_device *fc = fe->dvb->priv; |
| @@ -49,8 +55,7 @@ static int flexcop_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage | |||
| 49 | } | 55 | } |
| 50 | #endif | 56 | #endif |
| 51 | 57 | ||
| 52 | #if defined(CONFIG_DVB_S5H1420_MODULE) || defined(CONFIG_DVB_STV0299_MODULE) \ | 58 | #if FE_SUPPORTED(S5H1420) || FE_SUPPORTED(STV0299) || FE_SUPPORTED(MT312) |
| 53 | || defined(CONFIG_DVB_MT312_MODULE) | ||
| 54 | static int flexcop_sleep(struct dvb_frontend* fe) | 59 | static int flexcop_sleep(struct dvb_frontend* fe) |
| 55 | { | 60 | { |
| 56 | struct flexcop_device *fc = fe->dvb->priv; | 61 | struct flexcop_device *fc = fe->dvb->priv; |
| @@ -61,7 +66,7 @@ static int flexcop_sleep(struct dvb_frontend* fe) | |||
| 61 | #endif | 66 | #endif |
| 62 | 67 | ||
| 63 | /* SkyStar2 DVB-S rev 2.3 */ | 68 | /* SkyStar2 DVB-S rev 2.3 */ |
| 64 | #if defined(CONFIG_DVB_MT312_MODULE) | 69 | #if FE_SUPPORTED(MT312) |
| 65 | static int flexcop_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) | 70 | static int flexcop_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) |
| 66 | { | 71 | { |
| 67 | /* u16 wz_half_period_for_45_mhz[] = { 0x01ff, 0x0154, 0x00ff, 0x00cc }; */ | 72 | /* u16 wz_half_period_for_45_mhz[] = { 0x01ff, 0x0154, 0x00ff, 0x00cc }; */ |
| @@ -193,10 +198,12 @@ static int skystar2_rev23_attach(struct flexcop_device *fc, | |||
| 193 | } | 198 | } |
| 194 | return 0; | 199 | return 0; |
| 195 | } | 200 | } |
| 201 | #else | ||
| 202 | #define skystar2_rev23_attach NULL | ||
| 196 | #endif | 203 | #endif |
| 197 | 204 | ||
| 198 | /* SkyStar2 DVB-S rev 2.6 */ | 205 | /* SkyStar2 DVB-S rev 2.6 */ |
| 199 | #if defined(CONFIG_DVB_STV0299_MODULE) | 206 | #if FE_SUPPORTED(STV0299) |
| 200 | static int samsung_tbmu24112_set_symbol_rate(struct dvb_frontend *fe, | 207 | static int samsung_tbmu24112_set_symbol_rate(struct dvb_frontend *fe, |
| 201 | u32 srate, u32 ratio) | 208 | u32 srate, u32 ratio) |
| 202 | { | 209 | { |
| @@ -321,10 +328,12 @@ static int skystar2_rev26_attach(struct flexcop_device *fc, | |||
| 321 | } | 328 | } |
| 322 | return 0; | 329 | return 0; |
| 323 | } | 330 | } |
| 331 | #else | ||
| 332 | #define skystar2_rev26_attach NULL | ||
| 324 | #endif | 333 | #endif |
| 325 | 334 | ||
| 326 | /* SkyStar2 DVB-S rev 2.7 */ | 335 | /* SkyStar2 DVB-S rev 2.7 */ |
| 327 | #if defined(CONFIG_DVB_S5H1420_MODULE) | 336 | #if FE_SUPPORTED(S5H1420) && FE_SUPPORTED(ISL6421) && FE_SUPPORTED(TUNER_ITD1000) |
| 328 | static struct s5h1420_config skystar2_rev2_7_s5h1420_config = { | 337 | static struct s5h1420_config skystar2_rev2_7_s5h1420_config = { |
| 329 | .demod_address = 0x53, | 338 | .demod_address = 0x53, |
| 330 | .invert = 1, | 339 | .invert = 1, |
| @@ -385,10 +394,12 @@ fail: | |||
| 385 | fc->fc_i2c_adap[0].no_base_addr = 0; | 394 | fc->fc_i2c_adap[0].no_base_addr = 0; |
| 386 | return 0; | 395 | return 0; |
| 387 | } | 396 | } |
| 397 | #else | ||
| 398 | #define skystar2_rev27_attach NULL | ||
| 388 | #endif | 399 | #endif |
| 389 | 400 | ||
| 390 | /* SkyStar2 rev 2.8 */ | 401 | /* SkyStar2 rev 2.8 */ |
| 391 | #if defined(CONFIG_DVB_CX24123_MODULE) | 402 | #if FE_SUPPORTED(CX24123) && FE_SUPPORTED(ISL6421) && FE_SUPPORTED(TUNER_CX24113) |
| 392 | static struct cx24123_config skystar2_rev2_8_cx24123_config = { | 403 | static struct cx24123_config skystar2_rev2_8_cx24123_config = { |
| 393 | .demod_address = 0x55, | 404 | .demod_address = 0x55, |
| 394 | .dont_use_pll = 1, | 405 | .dont_use_pll = 1, |
| @@ -433,10 +444,12 @@ static int skystar2_rev28_attach(struct flexcop_device *fc, | |||
| 433 | * IR-receiver (PIC16F818) - but the card has no input for that ??? */ | 444 | * IR-receiver (PIC16F818) - but the card has no input for that ??? */ |
| 434 | return 1; | 445 | return 1; |
| 435 | } | 446 | } |
| 447 | #else | ||
| 448 | #define skystar2_rev28_attach NULL | ||
| 436 | #endif | 449 | #endif |
| 437 | 450 | ||
| 438 | /* AirStar DVB-T */ | 451 | /* AirStar DVB-T */ |
| 439 | #if defined(CONFIG_DVB_MT352_MODULE) | 452 | #if FE_SUPPORTED(MT352) |
| 440 | static int samsung_tdtc9251dh0_demod_init(struct dvb_frontend *fe) | 453 | static int samsung_tdtc9251dh0_demod_init(struct dvb_frontend *fe) |
| 441 | { | 454 | { |
| 442 | static u8 mt352_clock_config[] = { 0x89, 0x18, 0x2d }; | 455 | static u8 mt352_clock_config[] = { 0x89, 0x18, 0x2d }; |
| @@ -495,10 +508,12 @@ static int airstar_dvbt_attach(struct flexcop_device *fc, | |||
| 495 | } | 508 | } |
| 496 | return 0; | 509 | return 0; |
| 497 | } | 510 | } |
| 511 | #else | ||
| 512 | #define airstar_dvbt_attach NULL | ||
| 498 | #endif | 513 | #endif |
| 499 | 514 | ||
| 500 | /* AirStar ATSC 1st generation */ | 515 | /* AirStar ATSC 1st generation */ |
| 501 | #if defined(CONFIG_DVB_BCM3510_MODULE) | 516 | #if FE_SUPPORTED(BCM3510) |
| 502 | static int flexcop_fe_request_firmware(struct dvb_frontend *fe, | 517 | static int flexcop_fe_request_firmware(struct dvb_frontend *fe, |
| 503 | const struct firmware **fw, char* name) | 518 | const struct firmware **fw, char* name) |
| 504 | { | 519 | { |
| @@ -517,10 +532,12 @@ static int airstar_atsc1_attach(struct flexcop_device *fc, | |||
| 517 | fc->fe = dvb_attach(bcm3510_attach, &air2pc_atsc_first_gen_config, i2c); | 532 | fc->fe = dvb_attach(bcm3510_attach, &air2pc_atsc_first_gen_config, i2c); |
| 518 | return fc->fe != NULL; | 533 | return fc->fe != NULL; |
| 519 | } | 534 | } |
| 535 | #else | ||
| 536 | #define airstar_atsc1_attach NULL | ||
| 520 | #endif | 537 | #endif |
| 521 | 538 | ||
| 522 | /* AirStar ATSC 2nd generation */ | 539 | /* AirStar ATSC 2nd generation */ |
| 523 | #if defined(CONFIG_DVB_NXT200X_MODULE) | 540 | #if FE_SUPPORTED(NXT200X) && FE_SUPPORTED(PLL) |
| 524 | static struct nxt200x_config samsung_tbmv_config = { | 541 | static struct nxt200x_config samsung_tbmv_config = { |
| 525 | .demod_address = 0x0a, | 542 | .demod_address = 0x0a, |
| 526 | }; | 543 | }; |
| @@ -535,10 +552,12 @@ static int airstar_atsc2_attach(struct flexcop_device *fc, | |||
| 535 | return !!dvb_attach(dvb_pll_attach, fc->fe, 0x61, NULL, | 552 | return !!dvb_attach(dvb_pll_attach, fc->fe, 0x61, NULL, |
| 536 | DVB_PLL_SAMSUNG_TBMV); | 553 | DVB_PLL_SAMSUNG_TBMV); |
| 537 | } | 554 | } |
| 555 | #else | ||
| 556 | #define airstar_atsc2_attach NULL | ||
| 538 | #endif | 557 | #endif |
| 539 | 558 | ||
| 540 | /* AirStar ATSC 3rd generation */ | 559 | /* AirStar ATSC 3rd generation */ |
| 541 | #if defined(CONFIG_DVB_LGDT330X_MODULE) | 560 | #if FE_SUPPORTED(LGDT330X) |
| 542 | static struct lgdt330x_config air2pc_atsc_hd5000_config = { | 561 | static struct lgdt330x_config air2pc_atsc_hd5000_config = { |
| 543 | .demod_address = 0x59, | 562 | .demod_address = 0x59, |
| 544 | .demod_chip = LGDT3303, | 563 | .demod_chip = LGDT3303, |
| @@ -556,10 +575,12 @@ static int airstar_atsc3_attach(struct flexcop_device *fc, | |||
| 556 | return !!dvb_attach(simple_tuner_attach, fc->fe, i2c, 0x61, | 575 | return !!dvb_attach(simple_tuner_attach, fc->fe, i2c, 0x61, |
| 557 | TUNER_LG_TDVS_H06XF); | 576 | TUNER_LG_TDVS_H06XF); |
| 558 | } | 577 | } |
| 578 | #else | ||
| 579 | #define airstar_atsc3_attach NULL | ||
| 559 | #endif | 580 | #endif |
| 560 | 581 | ||
| 561 | /* CableStar2 DVB-C */ | 582 | /* CableStar2 DVB-C */ |
| 562 | #if defined(CONFIG_DVB_STV0297_MODULE) | 583 | #if FE_SUPPORTED(STV0297) |
| 563 | static int alps_tdee4_stv0297_tuner_set_params(struct dvb_frontend* fe, | 584 | static int alps_tdee4_stv0297_tuner_set_params(struct dvb_frontend* fe, |
| 564 | struct dvb_frontend_parameters *fep) | 585 | struct dvb_frontend_parameters *fep) |
| 565 | { | 586 | { |
| @@ -698,39 +719,23 @@ static int cablestar2_attach(struct flexcop_device *fc, | |||
| 698 | fc->fe->ops.tuner_ops.set_params = alps_tdee4_stv0297_tuner_set_params; | 719 | fc->fe->ops.tuner_ops.set_params = alps_tdee4_stv0297_tuner_set_params; |
| 699 | return 1; | 720 | return 1; |
| 700 | } | 721 | } |
| 722 | #else | ||
| 723 | #define cablestar2_attach NULL | ||
| 701 | #endif | 724 | #endif |
| 702 | 725 | ||
| 703 | static struct { | 726 | static struct { |
| 704 | flexcop_device_type_t type; | 727 | flexcop_device_type_t type; |
| 705 | int (*attach)(struct flexcop_device *, struct i2c_adapter *); | 728 | int (*attach)(struct flexcop_device *, struct i2c_adapter *); |
| 706 | } flexcop_frontends[] = { | 729 | } flexcop_frontends[] = { |
| 707 | #if defined(CONFIG_DVB_S5H1420_MODULE) | ||
| 708 | { FC_SKY_REV27, skystar2_rev27_attach }, | 730 | { FC_SKY_REV27, skystar2_rev27_attach }, |
| 709 | #endif | ||
| 710 | #if defined(CONFIG_DVB_CX24123_MODULE) | ||
| 711 | { FC_SKY_REV28, skystar2_rev28_attach }, | 731 | { FC_SKY_REV28, skystar2_rev28_attach }, |
| 712 | #endif | ||
| 713 | #if defined(CONFIG_DVB_STV0299_MODULE) | ||
| 714 | { FC_SKY_REV26, skystar2_rev26_attach }, | 732 | { FC_SKY_REV26, skystar2_rev26_attach }, |
| 715 | #endif | ||
| 716 | #if defined(CONFIG_DVB_MT352_MODULE) | ||
| 717 | { FC_AIR_DVBT, airstar_dvbt_attach }, | 733 | { FC_AIR_DVBT, airstar_dvbt_attach }, |
| 718 | #endif | ||
| 719 | #if defined(CONFIG_DVB_NXT200X_MODULE) | ||
| 720 | { FC_AIR_ATSC2, airstar_atsc2_attach }, | 734 | { FC_AIR_ATSC2, airstar_atsc2_attach }, |
| 721 | #endif | ||
| 722 | #if defined(CONFIG_DVB_LGDT330X_MODULE) | ||
| 723 | { FC_AIR_ATSC3, airstar_atsc3_attach }, | 735 | { FC_AIR_ATSC3, airstar_atsc3_attach }, |
| 724 | #endif | ||
| 725 | #if defined(CONFIG_DVB_BCM3510_MODULE) | ||
| 726 | { FC_AIR_ATSC1, airstar_atsc1_attach }, | 736 | { FC_AIR_ATSC1, airstar_atsc1_attach }, |
| 727 | #endif | ||
| 728 | #if defined(CONFIG_DVB_STV0297_MODULE) | ||
| 729 | { FC_CABLE, cablestar2_attach }, | 737 | { FC_CABLE, cablestar2_attach }, |
| 730 | #endif | ||
| 731 | #if defined(CONFIG_DVB_MT312_MODULE) | ||
| 732 | { FC_SKY_REV23, skystar2_rev23_attach }, | 738 | { FC_SKY_REV23, skystar2_rev23_attach }, |
| 733 | #endif | ||
| 734 | }; | 739 | }; |
| 735 | 740 | ||
| 736 | /* try to figure out the frontend */ | 741 | /* try to figure out the frontend */ |
| @@ -738,6 +743,8 @@ int flexcop_frontend_init(struct flexcop_device *fc) | |||
| 738 | { | 743 | { |
| 739 | int i; | 744 | int i; |
| 740 | for (i = 0; i < ARRAY_SIZE(flexcop_frontends); i++) { | 745 | for (i = 0; i < ARRAY_SIZE(flexcop_frontends); i++) { |
| 746 | if (!flexcop_frontends[i].attach) | ||
| 747 | continue; | ||
| 741 | /* type needs to be set before, because of some workarounds | 748 | /* type needs to be set before, because of some workarounds |
| 742 | * done based on the probed card type */ | 749 | * done based on the probed card type */ |
| 743 | fc->dev_type = flexcop_frontends[i].type; | 750 | fc->dev_type = flexcop_frontends[i].type; |
diff --git a/drivers/media/dvb/frontends/af9013.c b/drivers/media/dvb/frontends/af9013.c index 136c5863d81b..12e018b4107d 100644 --- a/drivers/media/dvb/frontends/af9013.c +++ b/drivers/media/dvb/frontends/af9013.c | |||
| @@ -527,6 +527,10 @@ static int af9013_set_ofdm_params(struct af9013_state *state, | |||
| 527 | u8 i, buf[3] = {0, 0, 0}; | 527 | u8 i, buf[3] = {0, 0, 0}; |
| 528 | *auto_mode = 0; /* set if parameters are requested to auto set */ | 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 | switch (params->transmission_mode) { | 534 | switch (params->transmission_mode) { |
| 531 | case TRANSMISSION_MODE_AUTO: | 535 | case TRANSMISSION_MODE_AUTO: |
| 532 | *auto_mode = 1; | 536 | *auto_mode = 1; |
| @@ -536,7 +540,8 @@ static int af9013_set_ofdm_params(struct af9013_state *state, | |||
| 536 | buf[0] |= (1 << 0); | 540 | buf[0] |= (1 << 0); |
| 537 | break; | 541 | break; |
| 538 | default: | 542 | default: |
| 539 | return -EINVAL; | 543 | deb_info("%s: invalid transmission_mode\n", __func__); |
| 544 | *auto_mode = 1; | ||
| 540 | } | 545 | } |
| 541 | 546 | ||
| 542 | switch (params->guard_interval) { | 547 | switch (params->guard_interval) { |
| @@ -554,7 +559,8 @@ static int af9013_set_ofdm_params(struct af9013_state *state, | |||
| 554 | buf[0] |= (3 << 2); | 559 | buf[0] |= (3 << 2); |
| 555 | break; | 560 | break; |
| 556 | default: | 561 | default: |
| 557 | return -EINVAL; | 562 | deb_info("%s: invalid guard_interval\n", __func__); |
| 563 | *auto_mode = 1; | ||
| 558 | } | 564 | } |
| 559 | 565 | ||
| 560 | switch (params->hierarchy_information) { | 566 | switch (params->hierarchy_information) { |
| @@ -572,7 +578,8 @@ static int af9013_set_ofdm_params(struct af9013_state *state, | |||
| 572 | buf[0] |= (3 << 4); | 578 | buf[0] |= (3 << 4); |
| 573 | break; | 579 | break; |
| 574 | default: | 580 | default: |
| 575 | return -EINVAL; | 581 | deb_info("%s: invalid hierarchy_information\n", __func__); |
| 582 | *auto_mode = 1; | ||
| 576 | }; | 583 | }; |
| 577 | 584 | ||
| 578 | switch (params->constellation) { | 585 | switch (params->constellation) { |
| @@ -587,7 +594,8 @@ static int af9013_set_ofdm_params(struct af9013_state *state, | |||
| 587 | buf[1] |= (2 << 6); | 594 | buf[1] |= (2 << 6); |
| 588 | break; | 595 | break; |
| 589 | default: | 596 | default: |
| 590 | return -EINVAL; | 597 | deb_info("%s: invalid constellation\n", __func__); |
| 598 | *auto_mode = 1; | ||
| 591 | } | 599 | } |
| 592 | 600 | ||
| 593 | /* Use HP. How and which case we can switch to LP? */ | 601 | /* Use HP. How and which case we can switch to LP? */ |
| @@ -611,7 +619,8 @@ static int af9013_set_ofdm_params(struct af9013_state *state, | |||
| 611 | buf[2] |= (4 << 0); | 619 | buf[2] |= (4 << 0); |
| 612 | break; | 620 | break; |
| 613 | default: | 621 | default: |
| 614 | return -EINVAL; | 622 | deb_info("%s: invalid code_rate_HP\n", __func__); |
| 623 | *auto_mode = 1; | ||
| 615 | } | 624 | } |
| 616 | 625 | ||
| 617 | switch (params->code_rate_LP) { | 626 | switch (params->code_rate_LP) { |
| @@ -638,7 +647,8 @@ static int af9013_set_ofdm_params(struct af9013_state *state, | |||
| 638 | if (params->hierarchy_information == HIERARCHY_AUTO) | 647 | if (params->hierarchy_information == HIERARCHY_AUTO) |
| 639 | break; | 648 | break; |
| 640 | default: | 649 | default: |
| 641 | return -EINVAL; | 650 | deb_info("%s: invalid code_rate_LP\n", __func__); |
| 651 | *auto_mode = 1; | ||
| 642 | } | 652 | } |
| 643 | 653 | ||
| 644 | switch (params->bandwidth) { | 654 | switch (params->bandwidth) { |
| @@ -651,7 +661,8 @@ static int af9013_set_ofdm_params(struct af9013_state *state, | |||
| 651 | buf[1] |= (2 << 2); | 661 | buf[1] |= (2 << 2); |
| 652 | break; | 662 | break; |
| 653 | default: | 663 | default: |
| 654 | return -EINVAL; | 664 | deb_info("%s: invalid bandwidth\n", __func__); |
| 665 | buf[1] |= (2 << 2); /* cannot auto-detect BW, try 8 MHz */ | ||
| 655 | } | 666 | } |
| 656 | 667 | ||
| 657 | /* program */ | 668 | /* program */ |
diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c index fdb4adff3d28..ca6558c394be 100644 --- a/drivers/media/video/bt8xx/bttv-cards.c +++ b/drivers/media/video/bt8xx/bttv-cards.c | |||
| @@ -3324,8 +3324,6 @@ void __devinit bttv_init_card1(struct bttv *btv) | |||
| 3324 | /* initialization part two -- after registering i2c bus */ | 3324 | /* initialization part two -- after registering i2c bus */ |
| 3325 | void __devinit bttv_init_card2(struct bttv *btv) | 3325 | void __devinit bttv_init_card2(struct bttv *btv) |
| 3326 | { | 3326 | { |
| 3327 | int addr=ADDR_UNSET; | ||
| 3328 | |||
| 3329 | btv->tuner_type = UNSET; | 3327 | btv->tuner_type = UNSET; |
| 3330 | 3328 | ||
| 3331 | if (BTTV_BOARD_UNKNOWN == btv->c.type) { | 3329 | if (BTTV_BOARD_UNKNOWN == btv->c.type) { |
| @@ -3470,9 +3468,6 @@ void __devinit bttv_init_card2(struct bttv *btv) | |||
| 3470 | btv->pll.pll_current = -1; | 3468 | btv->pll.pll_current = -1; |
| 3471 | 3469 | ||
| 3472 | /* tuner configuration (from card list / autodetect / insmod option) */ | 3470 | /* tuner configuration (from card list / autodetect / insmod option) */ |
| 3473 | if (ADDR_UNSET != bttv_tvcards[btv->c.type].tuner_addr) | ||
| 3474 | addr = bttv_tvcards[btv->c.type].tuner_addr; | ||
| 3475 | |||
| 3476 | if (UNSET != bttv_tvcards[btv->c.type].tuner_type) | 3471 | if (UNSET != bttv_tvcards[btv->c.type].tuner_type) |
| 3477 | if (UNSET == btv->tuner_type) | 3472 | if (UNSET == btv->tuner_type) |
| 3478 | btv->tuner_type = bttv_tvcards[btv->c.type].tuner_type; | 3473 | btv->tuner_type = bttv_tvcards[btv->c.type].tuner_type; |
| @@ -3496,40 +3491,6 @@ void __devinit bttv_init_card2(struct bttv *btv) | |||
| 3496 | if (UNSET == btv->tuner_type) | 3491 | if (UNSET == btv->tuner_type) |
| 3497 | btv->tuner_type = TUNER_ABSENT; | 3492 | btv->tuner_type = TUNER_ABSENT; |
| 3498 | 3493 | ||
| 3499 | if (btv->tuner_type != TUNER_ABSENT) { | ||
| 3500 | struct tuner_setup tun_setup; | ||
| 3501 | |||
| 3502 | /* Load tuner module before issuing tuner config call! */ | ||
| 3503 | if (bttv_tvcards[btv->c.type].has_radio) | ||
| 3504 | v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev, | ||
| 3505 | &btv->c.i2c_adap, "tuner", "tuner", | ||
| 3506 | v4l2_i2c_tuner_addrs(ADDRS_RADIO)); | ||
| 3507 | v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev, | ||
| 3508 | &btv->c.i2c_adap, "tuner", "tuner", | ||
| 3509 | v4l2_i2c_tuner_addrs(ADDRS_DEMOD)); | ||
| 3510 | v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev, | ||
| 3511 | &btv->c.i2c_adap, "tuner", "tuner", | ||
| 3512 | v4l2_i2c_tuner_addrs(ADDRS_TV_WITH_DEMOD)); | ||
| 3513 | |||
| 3514 | tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV; | ||
| 3515 | tun_setup.type = btv->tuner_type; | ||
| 3516 | tun_setup.addr = addr; | ||
| 3517 | |||
| 3518 | if (bttv_tvcards[btv->c.type].has_radio) | ||
| 3519 | tun_setup.mode_mask |= T_RADIO; | ||
| 3520 | |||
| 3521 | bttv_call_all(btv, tuner, s_type_addr, &tun_setup); | ||
| 3522 | } | ||
| 3523 | |||
| 3524 | if (btv->tda9887_conf) { | ||
| 3525 | struct v4l2_priv_tun_config tda9887_cfg; | ||
| 3526 | |||
| 3527 | tda9887_cfg.tuner = TUNER_TDA9887; | ||
| 3528 | tda9887_cfg.priv = &btv->tda9887_conf; | ||
| 3529 | |||
| 3530 | bttv_call_all(btv, tuner, s_config, &tda9887_cfg); | ||
| 3531 | } | ||
| 3532 | |||
| 3533 | btv->dig = bttv_tvcards[btv->c.type].has_dig_in ? | 3494 | btv->dig = bttv_tvcards[btv->c.type].has_dig_in ? |
| 3534 | bttv_tvcards[btv->c.type].video_inputs - 1 : UNSET; | 3495 | bttv_tvcards[btv->c.type].video_inputs - 1 : UNSET; |
| 3535 | btv->svhs = bttv_tvcards[btv->c.type].svhs == NO_SVHS ? | 3496 | btv->svhs = bttv_tvcards[btv->c.type].svhs == NO_SVHS ? |
| @@ -3540,15 +3501,15 @@ void __devinit bttv_init_card2(struct bttv *btv) | |||
| 3540 | btv->has_remote = remote[btv->c.nr]; | 3501 | btv->has_remote = remote[btv->c.nr]; |
| 3541 | 3502 | ||
| 3542 | if (bttv_tvcards[btv->c.type].has_radio) | 3503 | if (bttv_tvcards[btv->c.type].has_radio) |
| 3543 | btv->has_radio=1; | 3504 | btv->has_radio = 1; |
| 3544 | if (bttv_tvcards[btv->c.type].has_remote) | 3505 | if (bttv_tvcards[btv->c.type].has_remote) |
| 3545 | btv->has_remote=1; | 3506 | btv->has_remote = 1; |
| 3546 | if (!bttv_tvcards[btv->c.type].no_gpioirq) | 3507 | if (!bttv_tvcards[btv->c.type].no_gpioirq) |
| 3547 | btv->gpioirq=1; | 3508 | btv->gpioirq = 1; |
| 3548 | if (bttv_tvcards[btv->c.type].volume_gpio) | 3509 | if (bttv_tvcards[btv->c.type].volume_gpio) |
| 3549 | btv->volume_gpio=bttv_tvcards[btv->c.type].volume_gpio; | 3510 | btv->volume_gpio = bttv_tvcards[btv->c.type].volume_gpio; |
| 3550 | if (bttv_tvcards[btv->c.type].audio_mode_gpio) | 3511 | if (bttv_tvcards[btv->c.type].audio_mode_gpio) |
| 3551 | btv->audio_mode_gpio=bttv_tvcards[btv->c.type].audio_mode_gpio; | 3512 | btv->audio_mode_gpio = bttv_tvcards[btv->c.type].audio_mode_gpio; |
| 3552 | 3513 | ||
| 3553 | if (btv->tuner_type == TUNER_ABSENT) | 3514 | if (btv->tuner_type == TUNER_ABSENT) |
| 3554 | return; /* no tuner or related drivers to load */ | 3515 | return; /* no tuner or related drivers to load */ |
| @@ -3666,6 +3627,49 @@ no_audio: | |||
| 3666 | } | 3627 | } |
| 3667 | 3628 | ||
| 3668 | 3629 | ||
| 3630 | /* initialize the tuner */ | ||
| 3631 | void __devinit bttv_init_tuner(struct bttv *btv) | ||
| 3632 | { | ||
| 3633 | int addr = ADDR_UNSET; | ||
| 3634 | |||
| 3635 | if (ADDR_UNSET != bttv_tvcards[btv->c.type].tuner_addr) | ||
| 3636 | addr = bttv_tvcards[btv->c.type].tuner_addr; | ||
| 3637 | |||
| 3638 | if (btv->tuner_type != TUNER_ABSENT) { | ||
| 3639 | struct tuner_setup tun_setup; | ||
| 3640 | |||
| 3641 | /* Load tuner module before issuing tuner config call! */ | ||
| 3642 | if (bttv_tvcards[btv->c.type].has_radio) | ||
| 3643 | v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev, | ||
| 3644 | &btv->c.i2c_adap, "tuner", "tuner", | ||
| 3645 | v4l2_i2c_tuner_addrs(ADDRS_RADIO)); | ||
| 3646 | v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev, | ||
| 3647 | &btv->c.i2c_adap, "tuner", "tuner", | ||
| 3648 | v4l2_i2c_tuner_addrs(ADDRS_DEMOD)); | ||
| 3649 | v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev, | ||
| 3650 | &btv->c.i2c_adap, "tuner", "tuner", | ||
| 3651 | v4l2_i2c_tuner_addrs(ADDRS_TV_WITH_DEMOD)); | ||
| 3652 | |||
| 3653 | tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV; | ||
| 3654 | tun_setup.type = btv->tuner_type; | ||
| 3655 | tun_setup.addr = addr; | ||
| 3656 | |||
| 3657 | if (bttv_tvcards[btv->c.type].has_radio) | ||
| 3658 | tun_setup.mode_mask |= T_RADIO; | ||
| 3659 | |||
| 3660 | bttv_call_all(btv, tuner, s_type_addr, &tun_setup); | ||
| 3661 | } | ||
| 3662 | |||
| 3663 | if (btv->tda9887_conf) { | ||
| 3664 | struct v4l2_priv_tun_config tda9887_cfg; | ||
| 3665 | |||
| 3666 | tda9887_cfg.tuner = TUNER_TDA9887; | ||
| 3667 | tda9887_cfg.priv = &btv->tda9887_conf; | ||
| 3668 | |||
| 3669 | bttv_call_all(btv, tuner, s_config, &tda9887_cfg); | ||
| 3670 | } | ||
| 3671 | } | ||
| 3672 | |||
| 3669 | /* ----------------------------------------------------------------------- */ | 3673 | /* ----------------------------------------------------------------------- */ |
| 3670 | 3674 | ||
| 3671 | static void modtec_eeprom(struct bttv *btv) | 3675 | static void modtec_eeprom(struct bttv *btv) |
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index d147d29bb0d3..8cc6dd28d6a7 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c | |||
| @@ -4419,6 +4419,7 @@ static int __devinit bttv_probe(struct pci_dev *dev, | |||
| 4419 | 4419 | ||
| 4420 | /* some card-specific stuff (needs working i2c) */ | 4420 | /* some card-specific stuff (needs working i2c) */ |
| 4421 | bttv_init_card2(btv); | 4421 | bttv_init_card2(btv); |
| 4422 | bttv_init_tuner(btv); | ||
| 4422 | init_irqreg(btv); | 4423 | init_irqreg(btv); |
| 4423 | 4424 | ||
| 4424 | /* register video4linux + input */ | 4425 | /* register video4linux + input */ |
diff --git a/drivers/media/video/bt8xx/bttv.h b/drivers/media/video/bt8xx/bttv.h index 3d36daf206f3..3ec2402c6b4a 100644 --- a/drivers/media/video/bt8xx/bttv.h +++ b/drivers/media/video/bt8xx/bttv.h | |||
| @@ -283,6 +283,7 @@ extern struct tvcard bttv_tvcards[]; | |||
| 283 | extern void bttv_idcard(struct bttv *btv); | 283 | extern void bttv_idcard(struct bttv *btv); |
| 284 | extern void bttv_init_card1(struct bttv *btv); | 284 | extern void bttv_init_card1(struct bttv *btv); |
| 285 | extern void bttv_init_card2(struct bttv *btv); | 285 | extern void bttv_init_card2(struct bttv *btv); |
| 286 | extern void bttv_init_tuner(struct bttv *btv); | ||
| 286 | 287 | ||
| 287 | /* card-specific funtions */ | 288 | /* card-specific funtions */ |
| 288 | extern void tea5757_set_freq(struct bttv *btv, unsigned short freq); | 289 | extern void tea5757_set_freq(struct bttv *btv, unsigned short freq); |
diff --git a/drivers/media/video/cx23885/cx23885-417.c b/drivers/media/video/cx23885/cx23885-417.c index 428f0c45e6b7..e0cf21e0b1bf 100644 --- a/drivers/media/video/cx23885/cx23885-417.c +++ b/drivers/media/video/cx23885/cx23885-417.c | |||
| @@ -58,7 +58,8 @@ MODULE_PARM_DESC(v4l_debug, "enable V4L debug messages"); | |||
| 58 | 58 | ||
| 59 | #define dprintk(level, fmt, arg...)\ | 59 | #define dprintk(level, fmt, arg...)\ |
| 60 | do { if (v4l_debug >= level) \ | 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 | } while (0) | 63 | } while (0) |
| 63 | 64 | ||
| 64 | static struct cx23885_tvnorm cx23885_tvnorms[] = { | 65 | static struct cx23885_tvnorm cx23885_tvnorms[] = { |
| @@ -1677,6 +1678,7 @@ static struct v4l2_file_operations mpeg_fops = { | |||
| 1677 | .read = mpeg_read, | 1678 | .read = mpeg_read, |
| 1678 | .poll = mpeg_poll, | 1679 | .poll = mpeg_poll, |
| 1679 | .mmap = mpeg_mmap, | 1680 | .mmap = mpeg_mmap, |
| 1681 | .ioctl = video_ioctl2, | ||
| 1680 | }; | 1682 | }; |
| 1681 | 1683 | ||
| 1682 | static const struct v4l2_ioctl_ops mpeg_ioctl_ops = { | 1684 | static const struct v4l2_ioctl_ops mpeg_ioctl_ops = { |
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index ebd24a25fb85..320f1f60276e 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c | |||
| @@ -58,8 +58,6 @@ static unsigned int card[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; | |||
| 58 | module_param_array(card, int, NULL, 0444); | 58 | module_param_array(card, int, NULL, 0444); |
| 59 | MODULE_PARM_DESC(card, "card type"); | 59 | MODULE_PARM_DESC(card, "card type"); |
| 60 | 60 | ||
| 61 | #define MT9V011_VERSION 0x8243 | ||
| 62 | |||
| 63 | /* Bitmask marking allocated devices from 0 to EM28XX_MAXBOARDS */ | 61 | /* Bitmask marking allocated devices from 0 to EM28XX_MAXBOARDS */ |
| 64 | static unsigned long em28xx_devused; | 62 | static unsigned long em28xx_devused; |
| 65 | 63 | ||
| @@ -159,6 +157,20 @@ static struct em28xx_reg_seq evga_indtube_digital[] = { | |||
| 159 | { -1, -1, -1, -1}, | 157 | { -1, -1, -1, -1}, |
| 160 | }; | 158 | }; |
| 161 | 159 | ||
| 160 | /* Pinnacle Hybrid Pro eb1a:2881 */ | ||
| 161 | static struct em28xx_reg_seq pinnacle_hybrid_pro_analog[] = { | ||
| 162 | {EM28XX_R08_GPIO, 0xfd, ~EM_GPIO_4, 10}, | ||
| 163 | { -1, -1, -1, -1}, | ||
| 164 | }; | ||
| 165 | |||
| 166 | static struct em28xx_reg_seq pinnacle_hybrid_pro_digital[] = { | ||
| 167 | {EM28XX_R08_GPIO, 0x6e, ~EM_GPIO_4, 10}, | ||
| 168 | {EM2880_R04_GPO, 0x04, 0xff, 100},/* zl10353 reset */ | ||
| 169 | {EM2880_R04_GPO, 0x0c, 0xff, 1}, | ||
| 170 | { -1, -1, -1, -1}, | ||
| 171 | }; | ||
| 172 | |||
| 173 | |||
| 162 | /* Callback for the most boards */ | 174 | /* Callback for the most boards */ |
| 163 | static struct em28xx_reg_seq default_tuner_gpio[] = { | 175 | static struct em28xx_reg_seq default_tuner_gpio[] = { |
| 164 | {EM28XX_R08_GPIO, EM_GPIO_4, EM_GPIO_4, 10}, | 176 | {EM28XX_R08_GPIO, EM_GPIO_4, EM_GPIO_4, 10}, |
| @@ -205,13 +217,15 @@ static struct em28xx_reg_seq silvercrest_reg_seq[] = { | |||
| 205 | */ | 217 | */ |
| 206 | struct em28xx_board em28xx_boards[] = { | 218 | struct em28xx_board em28xx_boards[] = { |
| 207 | [EM2750_BOARD_UNKNOWN] = { | 219 | [EM2750_BOARD_UNKNOWN] = { |
| 208 | .name = "Unknown EM2750/EM2751 webcam grabber", | 220 | .name = "EM2710/EM2750/EM2751 webcam grabber", |
| 209 | .xclk = EM28XX_XCLK_FREQUENCY_48MHZ, | 221 | .xclk = EM28XX_XCLK_FREQUENCY_48MHZ, |
| 210 | .tuner_type = TUNER_ABSENT, /* This is a webcam */ | 222 | .tuner_type = TUNER_ABSENT, |
| 223 | .is_webcam = 1, | ||
| 211 | .input = { { | 224 | .input = { { |
| 212 | .type = EM28XX_VMUX_COMPOSITE1, | 225 | .type = EM28XX_VMUX_COMPOSITE1, |
| 213 | .vmux = 0, | 226 | .vmux = 0, |
| 214 | .amux = EM28XX_AMUX_VIDEO, | 227 | .amux = EM28XX_AMUX_VIDEO, |
| 228 | .gpio = silvercrest_reg_seq, | ||
| 215 | } }, | 229 | } }, |
| 216 | }, | 230 | }, |
| 217 | [EM2800_BOARD_UNKNOWN] = { | 231 | [EM2800_BOARD_UNKNOWN] = { |
| @@ -233,13 +247,15 @@ struct em28xx_board em28xx_boards[] = { | |||
| 233 | [EM2820_BOARD_UNKNOWN] = { | 247 | [EM2820_BOARD_UNKNOWN] = { |
| 234 | .name = "Unknown EM2750/28xx video grabber", | 248 | .name = "Unknown EM2750/28xx video grabber", |
| 235 | .tuner_type = TUNER_ABSENT, | 249 | .tuner_type = TUNER_ABSENT, |
| 250 | .is_webcam = 1, /* To enable sensor probe */ | ||
| 236 | }, | 251 | }, |
| 237 | [EM2750_BOARD_DLCW_130] = { | 252 | [EM2750_BOARD_DLCW_130] = { |
| 238 | /* Beijing Huaqi Information Digital Technology Co., Ltd */ | 253 | /* Beijing Huaqi Information Digital Technology Co., Ltd */ |
| 239 | .name = "Huaqi DLCW-130", | 254 | .name = "Huaqi DLCW-130", |
| 240 | .valid = EM28XX_BOARD_NOT_VALIDATED, | 255 | .valid = EM28XX_BOARD_NOT_VALIDATED, |
| 241 | .xclk = EM28XX_XCLK_FREQUENCY_48MHZ, | 256 | .xclk = EM28XX_XCLK_FREQUENCY_48MHZ, |
| 242 | .tuner_type = TUNER_ABSENT, /* This is a webcam */ | 257 | .tuner_type = TUNER_ABSENT, |
| 258 | .is_webcam = 1, | ||
| 243 | .input = { { | 259 | .input = { { |
| 244 | .type = EM28XX_VMUX_COMPOSITE1, | 260 | .type = EM28XX_VMUX_COMPOSITE1, |
| 245 | .vmux = 0, | 261 | .vmux = 0, |
| @@ -440,7 +456,8 @@ struct em28xx_board em28xx_boards[] = { | |||
| 440 | [EM2820_BOARD_VIDEOLOGY_20K14XUSB] = { | 456 | [EM2820_BOARD_VIDEOLOGY_20K14XUSB] = { |
| 441 | .name = "Videology 20K14XUSB USB2.0", | 457 | .name = "Videology 20K14XUSB USB2.0", |
| 442 | .valid = EM28XX_BOARD_NOT_VALIDATED, | 458 | .valid = EM28XX_BOARD_NOT_VALIDATED, |
| 443 | .tuner_type = TUNER_ABSENT, /* This is a webcam */ | 459 | .tuner_type = TUNER_ABSENT, |
| 460 | .is_webcam = 1, | ||
| 444 | .input = { { | 461 | .input = { { |
| 445 | .type = EM28XX_VMUX_COMPOSITE1, | 462 | .type = EM28XX_VMUX_COMPOSITE1, |
| 446 | .vmux = 0, | 463 | .vmux = 0, |
| @@ -450,8 +467,7 @@ struct em28xx_board em28xx_boards[] = { | |||
| 450 | [EM2820_BOARD_SILVERCREST_WEBCAM] = { | 467 | [EM2820_BOARD_SILVERCREST_WEBCAM] = { |
| 451 | .name = "Silvercrest Webcam 1.3mpix", | 468 | .name = "Silvercrest Webcam 1.3mpix", |
| 452 | .tuner_type = TUNER_ABSENT, | 469 | .tuner_type = TUNER_ABSENT, |
| 453 | .is_27xx = 1, | 470 | .is_webcam = 1, |
| 454 | .decoder = EM28XX_MT9V011, | ||
| 455 | .input = { { | 471 | .input = { { |
| 456 | .type = EM28XX_VMUX_COMPOSITE1, | 472 | .type = EM28XX_VMUX_COMPOSITE1, |
| 457 | .vmux = 0, | 473 | .vmux = 0, |
| @@ -500,7 +516,8 @@ struct em28xx_board em28xx_boards[] = { | |||
| 500 | /* Beijing Huaqi Information Digital Technology Co., Ltd */ | 516 | /* Beijing Huaqi Information Digital Technology Co., Ltd */ |
| 501 | .name = "NetGMBH Cam", | 517 | .name = "NetGMBH Cam", |
| 502 | .valid = EM28XX_BOARD_NOT_VALIDATED, | 518 | .valid = EM28XX_BOARD_NOT_VALIDATED, |
| 503 | .tuner_type = TUNER_ABSENT, /* This is a webcam */ | 519 | .tuner_type = TUNER_ABSENT, |
| 520 | .is_webcam = 1, | ||
| 504 | .input = { { | 521 | .input = { { |
| 505 | .type = EM28XX_VMUX_COMPOSITE1, | 522 | .type = EM28XX_VMUX_COMPOSITE1, |
| 506 | .vmux = 0, | 523 | .vmux = 0, |
| @@ -1250,25 +1267,26 @@ struct em28xx_board em28xx_boards[] = { | |||
| 1250 | }, | 1267 | }, |
| 1251 | [EM2881_BOARD_PINNACLE_HYBRID_PRO] = { | 1268 | [EM2881_BOARD_PINNACLE_HYBRID_PRO] = { |
| 1252 | .name = "Pinnacle Hybrid Pro", | 1269 | .name = "Pinnacle Hybrid Pro", |
| 1253 | .valid = EM28XX_BOARD_NOT_VALIDATED, | ||
| 1254 | .tuner_type = TUNER_XC2028, | 1270 | .tuner_type = TUNER_XC2028, |
| 1255 | .tuner_gpio = default_tuner_gpio, | 1271 | .tuner_gpio = default_tuner_gpio, |
| 1256 | .decoder = EM28XX_TVP5150, | 1272 | .decoder = EM28XX_TVP5150, |
| 1273 | .has_dvb = 1, | ||
| 1274 | .dvb_gpio = pinnacle_hybrid_pro_digital, | ||
| 1257 | .input = { { | 1275 | .input = { { |
| 1258 | .type = EM28XX_VMUX_TELEVISION, | 1276 | .type = EM28XX_VMUX_TELEVISION, |
| 1259 | .vmux = TVP5150_COMPOSITE0, | 1277 | .vmux = TVP5150_COMPOSITE0, |
| 1260 | .amux = EM28XX_AMUX_VIDEO, | 1278 | .amux = EM28XX_AMUX_VIDEO, |
| 1261 | .gpio = default_analog, | 1279 | .gpio = pinnacle_hybrid_pro_analog, |
| 1262 | }, { | 1280 | }, { |
| 1263 | .type = EM28XX_VMUX_COMPOSITE1, | 1281 | .type = EM28XX_VMUX_COMPOSITE1, |
| 1264 | .vmux = TVP5150_COMPOSITE1, | 1282 | .vmux = TVP5150_COMPOSITE1, |
| 1265 | .amux = EM28XX_AMUX_LINE_IN, | 1283 | .amux = EM28XX_AMUX_LINE_IN, |
| 1266 | .gpio = default_analog, | 1284 | .gpio = pinnacle_hybrid_pro_analog, |
| 1267 | }, { | 1285 | }, { |
| 1268 | .type = EM28XX_VMUX_SVIDEO, | 1286 | .type = EM28XX_VMUX_SVIDEO, |
| 1269 | .vmux = TVP5150_SVIDEO, | 1287 | .vmux = TVP5150_SVIDEO, |
| 1270 | .amux = EM28XX_AMUX_LINE_IN, | 1288 | .amux = EM28XX_AMUX_LINE_IN, |
| 1271 | .gpio = default_analog, | 1289 | .gpio = pinnacle_hybrid_pro_analog, |
| 1272 | } }, | 1290 | } }, |
| 1273 | }, | 1291 | }, |
| 1274 | [EM2882_BOARD_PINNACLE_HYBRID_PRO] = { | 1292 | [EM2882_BOARD_PINNACLE_HYBRID_PRO] = { |
| @@ -1638,6 +1656,7 @@ static struct em28xx_hash_table em28xx_eeprom_hash[] = { | |||
| 1638 | {0x966a0441, EM2880_BOARD_KWORLD_DVB_310U, TUNER_XC2028}, | 1656 | {0x966a0441, EM2880_BOARD_KWORLD_DVB_310U, TUNER_XC2028}, |
| 1639 | {0x9567eb1a, EM2880_BOARD_EMPIRE_DUAL_TV, TUNER_XC2028}, | 1657 | {0x9567eb1a, EM2880_BOARD_EMPIRE_DUAL_TV, TUNER_XC2028}, |
| 1640 | {0xcee44a99, EM2882_BOARD_EVGA_INDTUBE, TUNER_XC2028}, | 1658 | {0xcee44a99, EM2882_BOARD_EVGA_INDTUBE, TUNER_XC2028}, |
| 1659 | {0xb8846b20, EM2881_BOARD_PINNACLE_HYBRID_PRO, TUNER_XC2028}, | ||
| 1641 | }; | 1660 | }; |
| 1642 | 1661 | ||
| 1643 | /* I2C devicelist hash table for devices with generic USB IDs */ | 1662 | /* I2C devicelist hash table for devices with generic USB IDs */ |
| @@ -1704,6 +1723,32 @@ static inline void em28xx_set_model(struct em28xx *dev) | |||
| 1704 | EM28XX_I2C_FREQ_100_KHZ; | 1723 | EM28XX_I2C_FREQ_100_KHZ; |
| 1705 | } | 1724 | } |
| 1706 | 1725 | ||
| 1726 | /* FIXME: Should be replaced by a proper mt9m001 driver */ | ||
| 1727 | static int em28xx_initialize_mt9m001(struct em28xx *dev) | ||
| 1728 | { | ||
| 1729 | int i; | ||
| 1730 | unsigned char regs[][3] = { | ||
| 1731 | { 0x0d, 0x00, 0x01, }, | ||
| 1732 | { 0x0d, 0x00, 0x00, }, | ||
| 1733 | { 0x04, 0x05, 0x00, }, /* hres = 1280 */ | ||
| 1734 | { 0x03, 0x04, 0x00, }, /* vres = 1024 */ | ||
| 1735 | { 0x20, 0x11, 0x00, }, | ||
| 1736 | { 0x06, 0x00, 0x10, }, | ||
| 1737 | { 0x2b, 0x00, 0x24, }, | ||
| 1738 | { 0x2e, 0x00, 0x24, }, | ||
| 1739 | { 0x35, 0x00, 0x24, }, | ||
| 1740 | { 0x2d, 0x00, 0x20, }, | ||
| 1741 | { 0x2c, 0x00, 0x20, }, | ||
| 1742 | { 0x09, 0x0a, 0xd4, }, | ||
| 1743 | { 0x35, 0x00, 0x57, }, | ||
| 1744 | }; | ||
| 1745 | |||
| 1746 | for (i = 0; i < ARRAY_SIZE(regs); i++) | ||
| 1747 | i2c_master_send(&dev->i2c_client, ®s[i][0], 3); | ||
| 1748 | |||
| 1749 | return 0; | ||
| 1750 | } | ||
| 1751 | |||
| 1707 | /* HINT method: webcam I2C chips | 1752 | /* HINT method: webcam I2C chips |
| 1708 | * | 1753 | * |
| 1709 | * This method work for webcams with Micron sensors | 1754 | * This method work for webcams with Micron sensors |
| @@ -1716,9 +1761,6 @@ static int em28xx_hint_sensor(struct em28xx *dev) | |||
| 1716 | __be16 version_be; | 1761 | __be16 version_be; |
| 1717 | u16 version; | 1762 | u16 version; |
| 1718 | 1763 | ||
| 1719 | if (dev->model != EM2820_BOARD_UNKNOWN) | ||
| 1720 | return 0; | ||
| 1721 | |||
| 1722 | dev->i2c_client.addr = 0xba >> 1; | 1764 | dev->i2c_client.addr = 0xba >> 1; |
| 1723 | cmd = 0; | 1765 | cmd = 0; |
| 1724 | i2c_master_send(&dev->i2c_client, &cmd, 1); | 1766 | i2c_master_send(&dev->i2c_client, &cmd, 1); |
| @@ -1729,16 +1771,38 @@ static int em28xx_hint_sensor(struct em28xx *dev) | |||
| 1729 | version = be16_to_cpu(version_be); | 1771 | version = be16_to_cpu(version_be); |
| 1730 | 1772 | ||
| 1731 | switch (version) { | 1773 | switch (version) { |
| 1732 | case MT9V011_VERSION: | 1774 | case 0x8243: /* mt9v011 640x480 1.3 Mpix sensor */ |
| 1733 | dev->model = EM2820_BOARD_SILVERCREST_WEBCAM; | 1775 | dev->model = EM2820_BOARD_SILVERCREST_WEBCAM; |
| 1734 | sensor_name = "mt9v011"; | 1776 | sensor_name = "mt9v011"; |
| 1777 | dev->em28xx_sensor = EM28XX_MT9V011; | ||
| 1778 | dev->sensor_xres = 640; | ||
| 1779 | dev->sensor_yres = 480; | ||
| 1780 | dev->sensor_xtal = 6300000; | ||
| 1781 | |||
| 1782 | /* probably means GRGB 16 bit bayer */ | ||
| 1783 | dev->vinmode = 0x0d; | ||
| 1784 | dev->vinctl = 0x00; | ||
| 1785 | |||
| 1786 | break; | ||
| 1787 | case 0x8431: | ||
| 1788 | dev->model = EM2750_BOARD_UNKNOWN; | ||
| 1789 | sensor_name = "mt9m001"; | ||
| 1790 | dev->em28xx_sensor = EM28XX_MT9M001; | ||
| 1791 | em28xx_initialize_mt9m001(dev); | ||
| 1792 | dev->sensor_xres = 1280; | ||
| 1793 | dev->sensor_yres = 1024; | ||
| 1794 | |||
| 1795 | /* probably means BGGR 16 bit bayer */ | ||
| 1796 | dev->vinmode = 0x0c; | ||
| 1797 | dev->vinctl = 0x00; | ||
| 1798 | |||
| 1735 | break; | 1799 | break; |
| 1736 | default: | 1800 | default: |
| 1737 | printk("Unknown Sensor 0x%04x\n", be16_to_cpu(version)); | 1801 | printk("Unknown Micron Sensor 0x%04x\n", be16_to_cpu(version)); |
| 1738 | return -EINVAL; | 1802 | return -EINVAL; |
| 1739 | } | 1803 | } |
| 1740 | 1804 | ||
| 1741 | em28xx_errdev("Sensor is %s, assuming that webcam is %s\n", | 1805 | em28xx_errdev("Sensor is %s, using model %s entry.\n", |
| 1742 | sensor_name, em28xx_boards[dev->model].name); | 1806 | sensor_name, em28xx_boards[dev->model].name); |
| 1743 | 1807 | ||
| 1744 | return 0; | 1808 | return 0; |
| @@ -1772,10 +1836,7 @@ void em28xx_pre_card_setup(struct em28xx *dev) | |||
| 1772 | em28xx_info("chip ID is em2750\n"); | 1836 | em28xx_info("chip ID is em2750\n"); |
| 1773 | break; | 1837 | break; |
| 1774 | case CHIP_ID_EM2820: | 1838 | case CHIP_ID_EM2820: |
| 1775 | if (dev->board.is_27xx) | 1839 | em28xx_info("chip ID is em2710 or em2820\n"); |
| 1776 | em28xx_info("chip is em2710\n"); | ||
| 1777 | else | ||
| 1778 | em28xx_info("chip ID is em2820\n"); | ||
| 1779 | break; | 1840 | break; |
| 1780 | case CHIP_ID_EM2840: | 1841 | case CHIP_ID_EM2840: |
| 1781 | em28xx_info("chip ID is em2840\n"); | 1842 | em28xx_info("chip ID is em2840\n"); |
| @@ -1929,6 +1990,7 @@ static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl) | |||
| 1929 | ctl->demod = XC3028_FE_ZARLINK456; | 1990 | ctl->demod = XC3028_FE_ZARLINK456; |
| 1930 | break; | 1991 | break; |
| 1931 | case EM2880_BOARD_TERRATEC_HYBRID_XS: | 1992 | case EM2880_BOARD_TERRATEC_HYBRID_XS: |
| 1993 | case EM2881_BOARD_PINNACLE_HYBRID_PRO: | ||
| 1932 | ctl->demod = XC3028_FE_ZARLINK456; | 1994 | ctl->demod = XC3028_FE_ZARLINK456; |
| 1933 | break; | 1995 | break; |
| 1934 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2: | 1996 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2: |
| @@ -2225,6 +2287,7 @@ void em28xx_card_setup(struct em28xx *dev) | |||
| 2225 | em28xx_set_mode() in em28xx_pre_card_setup() was a no-op, | 2287 | em28xx_set_mode() in em28xx_pre_card_setup() was a no-op, |
| 2226 | so make the call now so the analog GPIOs are set properly | 2288 | so make the call now so the analog GPIOs are set properly |
| 2227 | before probing the i2c bus. */ | 2289 | before probing the i2c bus. */ |
| 2290 | em28xx_gpio_set(dev, dev->board.tuner_gpio); | ||
| 2228 | em28xx_set_mode(dev, EM28XX_ANALOG_MODE); | 2291 | em28xx_set_mode(dev, EM28XX_ANALOG_MODE); |
| 2229 | break; | 2292 | break; |
| 2230 | case EM2820_BOARD_SILVERCREST_WEBCAM: | 2293 | case EM2820_BOARD_SILVERCREST_WEBCAM: |
| @@ -2262,9 +2325,14 @@ void em28xx_card_setup(struct em28xx *dev) | |||
| 2262 | v4l2_i2c_new_probed_subdev(&dev->v4l2_dev, &dev->i2c_adap, | 2325 | v4l2_i2c_new_probed_subdev(&dev->v4l2_dev, &dev->i2c_adap, |
| 2263 | "tvp5150", "tvp5150", tvp5150_addrs); | 2326 | "tvp5150", "tvp5150", tvp5150_addrs); |
| 2264 | 2327 | ||
| 2265 | if (dev->board.decoder == EM28XX_MT9V011) | 2328 | if (dev->em28xx_sensor == EM28XX_MT9V011) { |
| 2266 | v4l2_i2c_new_probed_subdev(&dev->v4l2_dev, &dev->i2c_adap, | 2329 | struct v4l2_subdev *sd; |
| 2267 | "mt9v011", "mt9v011", mt9v011_addrs); | 2330 | |
| 2331 | sd = v4l2_i2c_new_probed_subdev(&dev->v4l2_dev, | ||
| 2332 | &dev->i2c_adap, "mt9v011", "mt9v011", mt9v011_addrs); | ||
| 2333 | v4l2_subdev_call(sd, core, s_config, 0, &dev->sensor_xtal); | ||
| 2334 | } | ||
| 2335 | |||
| 2268 | 2336 | ||
| 2269 | if (dev->board.adecoder == EM28XX_TVAUDIO) | 2337 | if (dev->board.adecoder == EM28XX_TVAUDIO) |
| 2270 | v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, | 2338 | v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, |
| @@ -2410,7 +2478,19 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, | |||
| 2410 | return errCode; | 2478 | return errCode; |
| 2411 | } | 2479 | } |
| 2412 | 2480 | ||
| 2413 | em28xx_hint_sensor(dev); | 2481 | /* |
| 2482 | * Default format, used for tvp5150 or saa711x output formats | ||
| 2483 | */ | ||
| 2484 | dev->vinmode = 0x10; | ||
| 2485 | dev->vinctl = 0x11; | ||
| 2486 | |||
| 2487 | /* | ||
| 2488 | * If the device can be a webcam, seek for a sensor. | ||
| 2489 | * If sensor is not found, then it isn't a webcam. | ||
| 2490 | */ | ||
| 2491 | if (dev->board.is_webcam) | ||
| 2492 | if (em28xx_hint_sensor(dev) < 0) | ||
| 2493 | dev->board.is_webcam = 0; | ||
| 2414 | 2494 | ||
| 2415 | /* Do board specific init and eeprom reading */ | 2495 | /* Do board specific init and eeprom reading */ |
| 2416 | em28xx_card_setup(dev); | 2496 | em28xx_card_setup(dev); |
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c index 079ab4d563a6..5b78e199abd1 100644 --- a/drivers/media/video/em28xx/em28xx-core.c +++ b/drivers/media/video/em28xx/em28xx-core.c | |||
| @@ -648,28 +648,17 @@ int em28xx_capture_start(struct em28xx *dev, int start) | |||
| 648 | int em28xx_set_outfmt(struct em28xx *dev) | 648 | int em28xx_set_outfmt(struct em28xx *dev) |
| 649 | { | 649 | { |
| 650 | int ret; | 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 | ret = em28xx_write_reg_bits(dev, EM28XX_R27_OUTFMT, | 652 | ret = em28xx_write_reg_bits(dev, EM28XX_R27_OUTFMT, |
| 664 | outfmt | 0x20, 0xff); | 653 | dev->format->reg | 0x20, 0xff); |
| 665 | if (ret < 0) | 654 | if (ret < 0) |
| 666 | return ret; | 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 | if (ret < 0) | 658 | if (ret < 0) |
| 670 | return ret; | 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 | static int em28xx_accumulator_set(struct em28xx *dev, u8 xmin, u8 xmax, | 664 | static int em28xx_accumulator_set(struct em28xx *dev, u8 xmin, u8 xmax, |
| @@ -707,10 +696,7 @@ static int em28xx_scaler_set(struct em28xx *dev, u16 h, u16 v) | |||
| 707 | u8 mode; | 696 | u8 mode; |
| 708 | /* the em2800 scaler only supports scaling down to 50% */ | 697 | /* the em2800 scaler only supports scaling down to 50% */ |
| 709 | 698 | ||
| 710 | if (dev->board.is_27xx) { | 699 | if (dev->board.is_em2800) { |
| 711 | /* FIXME: Don't use the scaler yet */ | ||
| 712 | mode = 0; | ||
| 713 | } else if (dev->board.is_em2800) { | ||
| 714 | mode = (v ? 0x20 : 0x00) | (h ? 0x10 : 0x00); | 700 | mode = (v ? 0x20 : 0x00) | (h ? 0x10 : 0x00); |
| 715 | } else { | 701 | } else { |
| 716 | u8 buf[2]; | 702 | u8 buf[2]; |
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c index 3da97c32b8fa..cf0ac7f2a30d 100644 --- a/drivers/media/video/em28xx/em28xx-dvb.c +++ b/drivers/media/video/em28xx/em28xx-dvb.c | |||
| @@ -31,6 +31,8 @@ | |||
| 31 | #include "lgdt330x.h" | 31 | #include "lgdt330x.h" |
| 32 | #include "zl10353.h" | 32 | #include "zl10353.h" |
| 33 | #include "s5h1409.h" | 33 | #include "s5h1409.h" |
| 34 | #include "mt352.h" | ||
| 35 | #include "mt352_priv.h" /* FIXME */ | ||
| 34 | 36 | ||
| 35 | MODULE_DESCRIPTION("driver for em28xx based DVB cards"); | 37 | MODULE_DESCRIPTION("driver for em28xx based DVB cards"); |
| 36 | MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>"); | 38 | MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>"); |
| @@ -243,7 +245,7 @@ static struct s5h1409_config em28xx_s5h1409_with_xc3028 = { | |||
| 243 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK | 245 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK |
| 244 | }; | 246 | }; |
| 245 | 247 | ||
| 246 | static struct zl10353_config em28xx_terratec_xs_zl10353_xc3028 = { | 248 | static struct zl10353_config em28xx_zl10353_xc3028_no_i2c_gate = { |
| 247 | .demod_address = (0x1e >> 1), | 249 | .demod_address = (0x1e >> 1), |
| 248 | .no_tuner = 1, | 250 | .no_tuner = 1, |
| 249 | .disable_i2c_gate_ctrl = 1, | 251 | .disable_i2c_gate_ctrl = 1, |
| @@ -258,6 +260,41 @@ static struct drx397xD_config em28xx_drx397xD_with_xc3028 = { | |||
| 258 | }; | 260 | }; |
| 259 | #endif | 261 | #endif |
| 260 | 262 | ||
| 263 | static int mt352_terratec_xs_init(struct dvb_frontend *fe) | ||
| 264 | { | ||
| 265 | /* Values extracted from a USB trace of the Terratec Windows driver */ | ||
| 266 | static u8 clock_config[] = { CLOCK_CTL, 0x38, 0x2c }; | ||
| 267 | static u8 reset[] = { RESET, 0x80 }; | ||
| 268 | static u8 adc_ctl_1_cfg[] = { ADC_CTL_1, 0x40 }; | ||
| 269 | static u8 agc_cfg[] = { AGC_TARGET, 0x28, 0xa0 }; | ||
| 270 | static u8 input_freq_cfg[] = { INPUT_FREQ_1, 0x31, 0xb8 }; | ||
| 271 | static u8 rs_err_cfg[] = { RS_ERR_PER_1, 0x00, 0x4d }; | ||
| 272 | static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 }; | ||
| 273 | static u8 trl_nom_cfg[] = { TRL_NOMINAL_RATE_1, 0x64, 0x00 }; | ||
| 274 | static u8 tps_given_cfg[] = { TPS_GIVEN_1, 0x40, 0x80, 0x50 }; | ||
| 275 | static u8 tuner_go[] = { TUNER_GO, 0x01}; | ||
| 276 | |||
| 277 | mt352_write(fe, clock_config, sizeof(clock_config)); | ||
| 278 | udelay(200); | ||
| 279 | mt352_write(fe, reset, sizeof(reset)); | ||
| 280 | mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg)); | ||
| 281 | mt352_write(fe, agc_cfg, sizeof(agc_cfg)); | ||
| 282 | mt352_write(fe, input_freq_cfg, sizeof(input_freq_cfg)); | ||
| 283 | mt352_write(fe, rs_err_cfg, sizeof(rs_err_cfg)); | ||
| 284 | mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg)); | ||
| 285 | mt352_write(fe, trl_nom_cfg, sizeof(trl_nom_cfg)); | ||
| 286 | mt352_write(fe, tps_given_cfg, sizeof(tps_given_cfg)); | ||
| 287 | mt352_write(fe, tuner_go, sizeof(tuner_go)); | ||
| 288 | return 0; | ||
| 289 | } | ||
| 290 | |||
| 291 | static struct mt352_config terratec_xs_mt352_cfg = { | ||
| 292 | .demod_address = (0x1e >> 1), | ||
| 293 | .no_tuner = 1, | ||
| 294 | .if2 = 45600, | ||
| 295 | .demod_init = mt352_terratec_xs_init, | ||
| 296 | }; | ||
| 297 | |||
| 261 | /* ------------------------------------------------------------------ */ | 298 | /* ------------------------------------------------------------------ */ |
| 262 | 299 | ||
| 263 | static int attach_xc3028(u8 addr, struct em28xx *dev) | 300 | static int attach_xc3028(u8 addr, struct em28xx *dev) |
| @@ -440,7 +477,6 @@ static int dvb_init(struct em28xx *dev) | |||
| 440 | goto out_free; | 477 | goto out_free; |
| 441 | } | 478 | } |
| 442 | break; | 479 | break; |
| 443 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: | ||
| 444 | case EM2880_BOARD_KWORLD_DVB_310U: | 480 | case EM2880_BOARD_KWORLD_DVB_310U: |
| 445 | case EM2880_BOARD_EMPIRE_DUAL_TV: | 481 | case EM2880_BOARD_EMPIRE_DUAL_TV: |
| 446 | dvb->frontend = dvb_attach(zl10353_attach, | 482 | dvb->frontend = dvb_attach(zl10353_attach, |
| @@ -451,20 +487,28 @@ static int dvb_init(struct em28xx *dev) | |||
| 451 | goto out_free; | 487 | goto out_free; |
| 452 | } | 488 | } |
| 453 | break; | 489 | break; |
| 490 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: | ||
| 491 | dvb->frontend = dvb_attach(zl10353_attach, | ||
| 492 | &em28xx_zl10353_xc3028_no_i2c_gate, | ||
| 493 | &dev->i2c_adap); | ||
| 494 | if (attach_xc3028(0x61, dev) < 0) { | ||
| 495 | result = -EINVAL; | ||
| 496 | goto out_free; | ||
| 497 | } | ||
| 498 | break; | ||
| 454 | case EM2880_BOARD_TERRATEC_HYBRID_XS: | 499 | case EM2880_BOARD_TERRATEC_HYBRID_XS: |
| 500 | case EM2881_BOARD_PINNACLE_HYBRID_PRO: | ||
| 455 | dvb->frontend = dvb_attach(zl10353_attach, | 501 | dvb->frontend = dvb_attach(zl10353_attach, |
| 456 | &em28xx_terratec_xs_zl10353_xc3028, | 502 | &em28xx_zl10353_xc3028_no_i2c_gate, |
| 457 | &dev->i2c_adap); | 503 | &dev->i2c_adap); |
| 458 | if (dvb->frontend == NULL) { | 504 | if (dvb->frontend == NULL) { |
| 459 | /* This board could have either a zl10353 or a mt352. | 505 | /* This board could have either a zl10353 or a mt352. |
| 460 | If the chip id isn't for zl10353, try mt352 */ | 506 | If the chip id isn't for zl10353, try mt352 */ |
| 461 | 507 | dvb->frontend = dvb_attach(mt352_attach, | |
| 462 | /* FIXME: make support for mt352 work */ | 508 | &terratec_xs_mt352_cfg, |
| 463 | printk(KERN_ERR "version of this board with mt352 not " | 509 | &dev->i2c_adap); |
| 464 | "currently supported\n"); | ||
| 465 | result = -EINVAL; | ||
| 466 | goto out_free; | ||
| 467 | } | 510 | } |
| 511 | |||
| 468 | if (attach_xc3028(0x61, dev) < 0) { | 512 | if (attach_xc3028(0x61, dev) < 0) { |
| 469 | result = -EINVAL; | 513 | result = -EINVAL; |
| 470 | goto out_free; | 514 | goto out_free; |
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index 14316c912179..ff37b4c15f44 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c | |||
| @@ -657,8 +657,8 @@ static void get_scale(struct em28xx *dev, | |||
| 657 | unsigned int width, unsigned int height, | 657 | unsigned int width, unsigned int height, |
| 658 | unsigned int *hscale, unsigned int *vscale) | 658 | unsigned int *hscale, unsigned int *vscale) |
| 659 | { | 659 | { |
| 660 | unsigned int maxw = norm_maxw(dev); | 660 | unsigned int maxw = norm_maxw(dev); |
| 661 | unsigned int maxh = norm_maxh(dev); | 661 | unsigned int maxh = norm_maxh(dev); |
| 662 | 662 | ||
| 663 | *hscale = (((unsigned long)maxw) << 12) / width - 4096L; | 663 | *hscale = (((unsigned long)maxw) << 12) / width - 4096L; |
| 664 | if (*hscale >= 0x4000) | 664 | if (*hscale >= 0x4000) |
| @@ -726,11 +726,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, | |||
| 726 | return -EINVAL; | 726 | return -EINVAL; |
| 727 | } | 727 | } |
| 728 | 728 | ||
| 729 | if (dev->board.is_27xx) { | 729 | if (dev->board.is_em2800) { |
| 730 | /* FIXME: This is the only supported fmt */ | ||
| 731 | width = 640; | ||
| 732 | height = 480; | ||
| 733 | } else if (dev->board.is_em2800) { | ||
| 734 | /* the em2800 can only scale down to 50% */ | 730 | /* the em2800 can only scale down to 50% */ |
| 735 | height = height > (3 * maxh / 4) ? maxh : maxh / 2; | 731 | height = height > (3 * maxh / 4) ? maxh : maxh / 2; |
| 736 | width = width > (3 * maxw / 4) ? maxw : maxw / 2; | 732 | width = width > (3 * maxw / 4) ? maxw : maxw / 2; |
| @@ -767,12 +763,6 @@ static int em28xx_set_video_format(struct em28xx *dev, unsigned int fourcc, | |||
| 767 | { | 763 | { |
| 768 | struct em28xx_fmt *fmt; | 764 | struct em28xx_fmt *fmt; |
| 769 | 765 | ||
| 770 | /* FIXME: This is the only supported fmt */ | ||
| 771 | if (dev->board.is_27xx) { | ||
| 772 | width = 640; | ||
| 773 | height = 480; | ||
| 774 | } | ||
| 775 | |||
| 776 | fmt = format_by_fourcc(fourcc); | 766 | fmt = format_by_fourcc(fourcc); |
| 777 | if (!fmt) | 767 | if (!fmt) |
| 778 | return -EINVAL; | 768 | return -EINVAL; |
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index d90fef463764..45bd513f62dc 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h | |||
| @@ -358,10 +358,15 @@ struct em28xx_input { | |||
| 358 | #define INPUT(nr) (&em28xx_boards[dev->model].input[nr]) | 358 | #define INPUT(nr) (&em28xx_boards[dev->model].input[nr]) |
| 359 | 359 | ||
| 360 | enum em28xx_decoder { | 360 | enum em28xx_decoder { |
| 361 | EM28XX_NODECODER, | 361 | EM28XX_NODECODER = 0, |
| 362 | EM28XX_TVP5150, | 362 | EM28XX_TVP5150, |
| 363 | EM28XX_SAA711X, | 363 | EM28XX_SAA711X, |
| 364 | }; | ||
| 365 | |||
| 366 | enum em28xx_sensor { | ||
| 367 | EM28XX_NOSENSOR = 0, | ||
| 364 | EM28XX_MT9V011, | 368 | EM28XX_MT9V011, |
| 369 | EM28XX_MT9M001, | ||
| 365 | }; | 370 | }; |
| 366 | 371 | ||
| 367 | enum em28xx_adecoder { | 372 | enum em28xx_adecoder { |
| @@ -390,7 +395,7 @@ struct em28xx_board { | |||
| 390 | unsigned int max_range_640_480:1; | 395 | unsigned int max_range_640_480:1; |
| 391 | unsigned int has_dvb:1; | 396 | unsigned int has_dvb:1; |
| 392 | unsigned int has_snapshot_button:1; | 397 | unsigned int has_snapshot_button:1; |
| 393 | unsigned int is_27xx:1; | 398 | unsigned int is_webcam:1; |
| 394 | unsigned int valid:1; | 399 | unsigned int valid:1; |
| 395 | 400 | ||
| 396 | unsigned char xclk, i2c_speed; | 401 | unsigned char xclk, i2c_speed; |
| @@ -474,6 +479,14 @@ struct em28xx { | |||
| 474 | struct v4l2_device v4l2_dev; | 479 | struct v4l2_device v4l2_dev; |
| 475 | struct em28xx_board board; | 480 | struct em28xx_board board; |
| 476 | 481 | ||
| 482 | /* Webcam specific fields */ | ||
| 483 | enum em28xx_sensor em28xx_sensor; | ||
| 484 | int sensor_xres, sensor_yres; | ||
| 485 | int sensor_xtal; | ||
| 486 | |||
| 487 | /* Vinmode/Vinctl used at the driver */ | ||
| 488 | int vinmode, vinctl; | ||
| 489 | |||
| 477 | unsigned int stream_on:1; /* Locks streams */ | 490 | unsigned int stream_on:1; /* Locks streams */ |
| 478 | unsigned int has_audio_class:1; | 491 | unsigned int has_audio_class:1; |
| 479 | unsigned int has_alsa_audio:1; | 492 | unsigned int has_alsa_audio:1; |
| @@ -754,17 +767,23 @@ static inline int em28xx_gamma_set(struct em28xx *dev, s32 val) | |||
| 754 | /*FIXME: maxw should be dependent of alt mode */ | 767 | /*FIXME: maxw should be dependent of alt mode */ |
| 755 | static inline unsigned int norm_maxw(struct em28xx *dev) | 768 | static inline unsigned int norm_maxw(struct em28xx *dev) |
| 756 | { | 769 | { |
| 770 | if (dev->board.is_webcam) | ||
| 771 | return dev->sensor_xres; | ||
| 772 | |||
| 757 | if (dev->board.max_range_640_480) | 773 | if (dev->board.max_range_640_480) |
| 758 | return 640; | 774 | return 640; |
| 759 | else | 775 | |
| 760 | return 720; | 776 | return 720; |
| 761 | } | 777 | } |
| 762 | 778 | ||
| 763 | static inline unsigned int norm_maxh(struct em28xx *dev) | 779 | static inline unsigned int norm_maxh(struct em28xx *dev) |
| 764 | { | 780 | { |
| 781 | if (dev->board.is_webcam) | ||
| 782 | return dev->sensor_yres; | ||
| 783 | |||
| 765 | if (dev->board.max_range_640_480) | 784 | if (dev->board.max_range_640_480) |
| 766 | return 480; | 785 | return 480; |
| 767 | else | 786 | |
| 768 | return (dev->norm & V4L2_STD_625_50) ? 576 : 480; | 787 | return (dev->norm & V4L2_STD_625_50) ? 576 : 480; |
| 769 | } | 788 | } |
| 770 | #endif | 789 | #endif |
diff --git a/drivers/media/video/gspca/Kconfig b/drivers/media/video/gspca/Kconfig index 578dc4ffc965..34f46f2bc040 100644 --- a/drivers/media/video/gspca/Kconfig +++ b/drivers/media/video/gspca/Kconfig | |||
| @@ -102,6 +102,22 @@ config USB_GSPCA_PAC7311 | |||
| 102 | To compile this driver as a module, choose M here: the | 102 | To compile this driver as a module, choose M here: the |
| 103 | module will be called gspca_pac7311. | 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 | config USB_GSPCA_SONIXB | 121 | config USB_GSPCA_SONIXB |
| 106 | tristate "SONIX Bayer USB Camera Driver" | 122 | tristate "SONIX Bayer USB Camera Driver" |
| 107 | depends on VIDEO_V4L2 && USB_GSPCA | 123 | depends on VIDEO_V4L2 && USB_GSPCA |
diff --git a/drivers/media/video/gspca/Makefile b/drivers/media/video/gspca/Makefile index 8a6643e8eb96..f6d3b86e9ad5 100644 --- a/drivers/media/video/gspca/Makefile +++ b/drivers/media/video/gspca/Makefile | |||
| @@ -8,6 +8,7 @@ obj-$(CONFIG_USB_GSPCA_OV519) += gspca_ov519.o | |||
| 8 | obj-$(CONFIG_USB_GSPCA_OV534) += gspca_ov534.o | 8 | obj-$(CONFIG_USB_GSPCA_OV534) += gspca_ov534.o |
| 9 | obj-$(CONFIG_USB_GSPCA_PAC207) += gspca_pac207.o | 9 | obj-$(CONFIG_USB_GSPCA_PAC207) += gspca_pac207.o |
| 10 | obj-$(CONFIG_USB_GSPCA_PAC7311) += gspca_pac7311.o | 10 | obj-$(CONFIG_USB_GSPCA_PAC7311) += gspca_pac7311.o |
| 11 | obj-$(CONFIG_USB_GSPCA_SN9C20X) += gspca_sn9c20x.o | ||
| 11 | obj-$(CONFIG_USB_GSPCA_SONIXB) += gspca_sonixb.o | 12 | obj-$(CONFIG_USB_GSPCA_SONIXB) += gspca_sonixb.o |
| 12 | obj-$(CONFIG_USB_GSPCA_SONIXJ) += gspca_sonixj.o | 13 | obj-$(CONFIG_USB_GSPCA_SONIXJ) += gspca_sonixj.o |
| 13 | obj-$(CONFIG_USB_GSPCA_SPCA500) += gspca_spca500.o | 14 | obj-$(CONFIG_USB_GSPCA_SPCA500) += gspca_spca500.o |
| @@ -35,6 +36,7 @@ gspca_ov519-objs := ov519.o | |||
| 35 | gspca_ov534-objs := ov534.o | 36 | gspca_ov534-objs := ov534.o |
| 36 | gspca_pac207-objs := pac207.o | 37 | gspca_pac207-objs := pac207.o |
| 37 | gspca_pac7311-objs := pac7311.o | 38 | gspca_pac7311-objs := pac7311.o |
| 39 | gspca_sn9c20x-objs := sn9c20x.o | ||
| 38 | gspca_sonixb-objs := sonixb.o | 40 | gspca_sonixb-objs := sonixb.o |
| 39 | gspca_sonixj-objs := sonixj.o | 41 | gspca_sonixj-objs := sonixj.o |
| 40 | gspca_spca500-objs := spca500.o | 42 | gspca_spca500-objs := spca500.o |
diff --git a/drivers/media/video/gspca/conex.c b/drivers/media/video/gspca/conex.c index 219cfa6fb877..8d48ea1742c2 100644 --- a/drivers/media/video/gspca/conex.c +++ b/drivers/media/video/gspca/conex.c | |||
| @@ -846,6 +846,8 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
| 846 | 846 | ||
| 847 | /* create the JPEG header */ | 847 | /* create the JPEG header */ |
| 848 | sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); | 848 | sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); |
| 849 | if (!sd->jpeg_hdr) | ||
| 850 | return -ENOMEM; | ||
| 849 | jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, | 851 | jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, |
| 850 | 0x22); /* JPEG 411 */ | 852 | 0x22); /* JPEG 411 */ |
| 851 | jpeg_set_qual(sd->jpeg_hdr, sd->quality); | 853 | jpeg_set_qual(sd->jpeg_hdr, sd->quality); |
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 1e89600986c8..b8561dfb6c8c 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c | |||
| @@ -727,6 +727,74 @@ static int gspca_get_mode(struct gspca_dev *gspca_dev, | |||
| 727 | return -EINVAL; | 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 | static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, | 798 | static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, |
| 731 | struct v4l2_fmtdesc *fmtdesc) | 799 | struct v4l2_fmtdesc *fmtdesc) |
| 732 | { | 800 | { |
| @@ -1883,6 +1951,11 @@ static const struct v4l2_ioctl_ops dev_ioctl_ops = { | |||
| 1883 | .vidioc_s_parm = vidioc_s_parm, | 1951 | .vidioc_s_parm = vidioc_s_parm, |
| 1884 | .vidioc_s_std = vidioc_s_std, | 1952 | .vidioc_s_std = vidioc_s_std, |
| 1885 | .vidioc_enum_framesizes = vidioc_enum_framesizes, | 1953 | .vidioc_enum_framesizes = vidioc_enum_framesizes, |
| 1954 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
| 1955 | .vidioc_g_register = vidioc_g_register, | ||
| 1956 | .vidioc_s_register = vidioc_s_register, | ||
| 1957 | #endif | ||
| 1958 | .vidioc_g_chip_ident = vidioc_g_chip_ident, | ||
| 1886 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | 1959 | #ifdef CONFIG_VIDEO_V4L1_COMPAT |
| 1887 | .vidiocgmbuf = vidiocgmbuf, | 1960 | .vidiocgmbuf = vidiocgmbuf, |
| 1888 | #endif | 1961 | #endif |
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h index bd1faff88644..46c4effdfcd5 100644 --- a/drivers/media/video/gspca/gspca.h +++ b/drivers/media/video/gspca/gspca.h | |||
| @@ -69,6 +69,10 @@ typedef void (*cam_v_op) (struct gspca_dev *); | |||
| 69 | typedef int (*cam_cf_op) (struct gspca_dev *, const struct usb_device_id *); | 69 | typedef int (*cam_cf_op) (struct gspca_dev *, const struct usb_device_id *); |
| 70 | typedef int (*cam_jpg_op) (struct gspca_dev *, | 70 | typedef int (*cam_jpg_op) (struct gspca_dev *, |
| 71 | struct v4l2_jpegcompression *); | 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 | typedef int (*cam_streamparm_op) (struct gspca_dev *, | 76 | typedef int (*cam_streamparm_op) (struct gspca_dev *, |
| 73 | struct v4l2_streamparm *); | 77 | struct v4l2_streamparm *); |
| 74 | typedef int (*cam_qmnu_op) (struct gspca_dev *, | 78 | typedef int (*cam_qmnu_op) (struct gspca_dev *, |
| @@ -105,6 +109,11 @@ struct sd_desc { | |||
| 105 | cam_qmnu_op querymenu; | 109 | cam_qmnu_op querymenu; |
| 106 | cam_streamparm_op get_streamparm; | 110 | cam_streamparm_op get_streamparm; |
| 107 | cam_streamparm_op set_streamparm; | 111 | cam_streamparm_op set_streamparm; |
| 112 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
| 113 | cam_reg_op set_register; | ||
| 114 | cam_reg_op get_register; | ||
| 115 | #endif | ||
| 116 | cam_ident_op get_chip_ident; | ||
| 108 | }; | 117 | }; |
| 109 | 118 | ||
| 110 | /* packet types when moving from iso buf to frame buf */ | 119 | /* packet types when moving from iso buf to frame buf */ |
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c index 191bcd718979..0163903d1c0f 100644 --- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c +++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c | |||
| @@ -476,9 +476,6 @@ static int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | |||
| 476 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | 476 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); |
| 477 | if (err < 0) | 477 | if (err < 0) |
| 478 | return err; | 478 | return err; |
| 479 | err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); | ||
| 480 | if (err < 0) | ||
| 481 | return err; | ||
| 482 | 479 | ||
| 483 | err = m5602_read_sensor(sd, S5K4AA_READ_MODE, &data, 1); | 480 | err = m5602_read_sensor(sd, S5K4AA_READ_MODE, &data, 1); |
| 484 | if (err < 0) | 481 | if (err < 0) |
| @@ -524,9 +521,6 @@ static int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | |||
| 524 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | 521 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); |
| 525 | if (err < 0) | 522 | if (err < 0) |
| 526 | return err; | 523 | return err; |
| 527 | err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); | ||
| 528 | if (err < 0) | ||
| 529 | return err; | ||
| 530 | 524 | ||
| 531 | err = m5602_read_sensor(sd, S5K4AA_READ_MODE, &data, 1); | 525 | err = m5602_read_sensor(sd, S5K4AA_READ_MODE, &data, 1); |
| 532 | if (err < 0) | 526 | if (err < 0) |
diff --git a/drivers/media/video/gspca/mars.c b/drivers/media/video/gspca/mars.c index 75e8d14e4ac7..de769caf013d 100644 --- a/drivers/media/video/gspca/mars.c +++ b/drivers/media/video/gspca/mars.c | |||
| @@ -201,6 +201,8 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
| 201 | 201 | ||
| 202 | /* create the JPEG header */ | 202 | /* create the JPEG header */ |
| 203 | sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); | 203 | sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); |
| 204 | if (!sd->jpeg_hdr) | ||
| 205 | return -ENOMEM; | ||
| 204 | jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, | 206 | jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, |
| 205 | 0x21); /* JPEG 422 */ | 207 | 0x21); /* JPEG 422 */ |
| 206 | jpeg_set_qual(sd->jpeg_hdr, sd->quality); | 208 | jpeg_set_qual(sd->jpeg_hdr, sd->quality); |
diff --git a/drivers/media/video/gspca/sn9c20x.c b/drivers/media/video/gspca/sn9c20x.c new file mode 100644 index 000000000000..fcfbbd329b4c --- /dev/null +++ b/drivers/media/video/gspca/sn9c20x.c | |||
| @@ -0,0 +1,2434 @@ | |||
| 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 *)®->val) < 0) | ||
| 1919 | return -EINVAL; | ||
| 1920 | } else { | ||
| 1921 | if (i2c_r1(gspca_dev, reg->reg, (u8 *)®->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); | ||
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index 0d02f41fa7d0..d6332ab80669 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c | |||
| @@ -1634,6 +1634,8 @@ static void setfreq(struct gspca_dev *gspca_dev) | |||
| 1634 | { | 1634 | { |
| 1635 | struct sd *sd = (struct sd *) gspca_dev; | 1635 | struct sd *sd = (struct sd *) gspca_dev; |
| 1636 | 1636 | ||
| 1637 | if (gspca_dev->ctrl_dis & (1 << FREQ_IDX)) | ||
| 1638 | return; | ||
| 1637 | if (sd->sensor == SENSOR_OV7660) { | 1639 | if (sd->sensor == SENSOR_OV7660) { |
| 1638 | switch (sd->freq) { | 1640 | switch (sd->freq) { |
| 1639 | case 0: /* Banding filter disabled */ | 1641 | case 0: /* Banding filter disabled */ |
| @@ -1735,6 +1737,8 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
| 1735 | 1737 | ||
| 1736 | /* create the JPEG header */ | 1738 | /* create the JPEG header */ |
| 1737 | sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); | 1739 | sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); |
| 1740 | if (!sd->jpeg_hdr) | ||
| 1741 | return -ENOMEM; | ||
| 1738 | jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, | 1742 | jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, |
| 1739 | 0x21); /* JPEG 422 */ | 1743 | 0x21); /* JPEG 422 */ |
| 1740 | jpeg_set_qual(sd->jpeg_hdr, sd->quality); | 1744 | jpeg_set_qual(sd->jpeg_hdr, sd->quality); |
diff --git a/drivers/media/video/gspca/spca500.c b/drivers/media/video/gspca/spca500.c index 8806b2ff82be..fab7ef85a6c1 100644 --- a/drivers/media/video/gspca/spca500.c +++ b/drivers/media/video/gspca/spca500.c | |||
| @@ -670,6 +670,8 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
| 670 | 670 | ||
| 671 | /* create the JPEG header */ | 671 | /* create the JPEG header */ |
| 672 | sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); | 672 | sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); |
| 673 | if (!sd->jpeg_hdr) | ||
| 674 | return -ENOMEM; | ||
| 673 | jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, | 675 | jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, |
| 674 | 0x22); /* JPEG 411 */ | 676 | 0x22); /* JPEG 411 */ |
| 675 | jpeg_set_qual(sd->jpeg_hdr, sd->quality); | 677 | jpeg_set_qual(sd->jpeg_hdr, sd->quality); |
diff --git a/drivers/media/video/gspca/stk014.c b/drivers/media/video/gspca/stk014.c index f25be20cf1a6..47628964801e 100644 --- a/drivers/media/video/gspca/stk014.c +++ b/drivers/media/video/gspca/stk014.c | |||
| @@ -333,6 +333,8 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
| 333 | 333 | ||
| 334 | /* create the JPEG header */ | 334 | /* create the JPEG header */ |
| 335 | sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); | 335 | sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); |
| 336 | if (!sd->jpeg_hdr) | ||
| 337 | return -ENOMEM; | ||
| 336 | jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, | 338 | jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, |
| 337 | 0x22); /* JPEG 411 */ | 339 | 0x22); /* JPEG 411 */ |
| 338 | jpeg_set_qual(sd->jpeg_hdr, sd->quality); | 340 | jpeg_set_qual(sd->jpeg_hdr, sd->quality); |
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c index 3039ec208f3a..e5024c8496ef 100644 --- a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c +++ b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c | |||
| @@ -64,7 +64,7 @@ static struct v4l2_pix_format hdcs1x00_mode[] = { | |||
| 64 | { | 64 | { |
| 65 | HDCS_1X00_DEF_WIDTH, | 65 | HDCS_1X00_DEF_WIDTH, |
| 66 | HDCS_1X00_DEF_HEIGHT, | 66 | HDCS_1X00_DEF_HEIGHT, |
| 67 | V4L2_PIX_FMT_SBGGR8, | 67 | V4L2_PIX_FMT_SGRBG8, |
| 68 | V4L2_FIELD_NONE, | 68 | V4L2_FIELD_NONE, |
| 69 | .sizeimage = | 69 | .sizeimage = |
| 70 | HDCS_1X00_DEF_WIDTH * HDCS_1X00_DEF_HEIGHT, | 70 | HDCS_1X00_DEF_WIDTH * HDCS_1X00_DEF_HEIGHT, |
| @@ -80,7 +80,7 @@ static struct v4l2_pix_format hdcs1020_mode[] = { | |||
| 80 | { | 80 | { |
| 81 | HDCS_1020_DEF_WIDTH, | 81 | HDCS_1020_DEF_WIDTH, |
| 82 | HDCS_1020_DEF_HEIGHT, | 82 | HDCS_1020_DEF_HEIGHT, |
| 83 | V4L2_PIX_FMT_SBGGR8, | 83 | V4L2_PIX_FMT_SGRBG8, |
| 84 | V4L2_FIELD_NONE, | 84 | V4L2_FIELD_NONE, |
| 85 | .sizeimage = | 85 | .sizeimage = |
| 86 | HDCS_1020_DEF_WIDTH * HDCS_1020_DEF_HEIGHT, | 86 | HDCS_1020_DEF_WIDTH * HDCS_1020_DEF_HEIGHT, |
| @@ -131,9 +131,11 @@ static int hdcs_reg_write_seq(struct sd *sd, u8 reg, u8 *vals, u8 len) | |||
| 131 | (reg + len > 0xff))) | 131 | (reg + len > 0xff))) |
| 132 | return -EINVAL; | 132 | return -EINVAL; |
| 133 | 133 | ||
| 134 | for (i = 0; i < len; i++, reg++) { | 134 | for (i = 0; i < len; i++) { |
| 135 | regs[2*i] = reg; | 135 | regs[2 * i] = reg; |
| 136 | regs[2*i+1] = vals[i]; | 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 | return stv06xx_write_sensor_bytes(sd, regs, len); | 141 | return stv06xx_write_sensor_bytes(sd, regs, len); |
| @@ -174,7 +176,9 @@ static int hdcs_set_state(struct sd *sd, enum hdcs_power_state state) | |||
| 174 | } | 176 | } |
| 175 | 177 | ||
| 176 | ret = stv06xx_write_sensor(sd, HDCS_REG_CONTROL(sd), val); | 178 | ret = stv06xx_write_sensor(sd, HDCS_REG_CONTROL(sd), val); |
| 177 | if (ret < 0) | 179 | |
| 180 | /* Update the state if the write succeeded */ | ||
| 181 | if (!ret) | ||
| 178 | hdcs->state = state; | 182 | hdcs->state = state; |
| 179 | 183 | ||
| 180 | return ret; | 184 | return ret; |
diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c index 9623f294bdac..5127bbf9dd26 100644 --- a/drivers/media/video/gspca/sunplus.c +++ b/drivers/media/video/gspca/sunplus.c | |||
| @@ -973,6 +973,8 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
| 973 | 973 | ||
| 974 | /* create the JPEG header */ | 974 | /* create the JPEG header */ |
| 975 | sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); | 975 | sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); |
| 976 | if (!sd->jpeg_hdr) | ||
| 977 | return -ENOMEM; | ||
| 976 | jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, | 978 | jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, |
| 977 | 0x22); /* JPEG 411 */ | 979 | 0x22); /* JPEG 411 */ |
| 978 | jpeg_set_qual(sd->jpeg_hdr, sd->quality); | 980 | jpeg_set_qual(sd->jpeg_hdr, sd->quality); |
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c index 08422d315e68..3d2756f7874a 100644 --- a/drivers/media/video/gspca/zc3xx.c +++ b/drivers/media/video/gspca/zc3xx.c | |||
| @@ -7243,6 +7243,8 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
| 7243 | 7243 | ||
| 7244 | /* create the JPEG header */ | 7244 | /* create the JPEG header */ |
| 7245 | sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); | 7245 | sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); |
| 7246 | if (!sd->jpeg_hdr) | ||
| 7247 | return -ENOMEM; | ||
| 7246 | jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, | 7248 | jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, |
| 7247 | 0x21); /* JPEG 422 */ | 7249 | 0x21); /* JPEG 422 */ |
| 7248 | jpeg_set_qual(sd->jpeg_hdr, sd->quality); | 7250 | jpeg_set_qual(sd->jpeg_hdr, sd->quality); |
diff --git a/drivers/media/video/mt9v011.c b/drivers/media/video/mt9v011.c index 1fe8fc9183a7..b2260de645f0 100644 --- a/drivers/media/video/mt9v011.c +++ b/drivers/media/video/mt9v011.c | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | #include <linux/i2c.h> | 8 | #include <linux/i2c.h> |
| 9 | #include <linux/videodev2.h> | 9 | #include <linux/videodev2.h> |
| 10 | #include <linux/delay.h> | 10 | #include <linux/delay.h> |
| 11 | #include <asm/div64.h> | ||
| 11 | #include <media/v4l2-device.h> | 12 | #include <media/v4l2-device.h> |
| 12 | #include "mt9v011.h" | 13 | #include "mt9v011.h" |
| 13 | #include <media/v4l2-i2c-drv.h> | 14 | #include <media/v4l2-i2c-drv.h> |
| @@ -57,6 +58,7 @@ static struct v4l2_queryctrl mt9v011_qctrl[] = { | |||
| 57 | struct mt9v011 { | 58 | struct mt9v011 { |
| 58 | struct v4l2_subdev sd; | 59 | struct v4l2_subdev sd; |
| 59 | unsigned width, height; | 60 | unsigned width, height; |
| 61 | unsigned xtal; | ||
| 60 | 62 | ||
| 61 | u16 global_gain, red_bal, blue_bal; | 63 | u16 global_gain, red_bal, blue_bal; |
| 62 | }; | 64 | }; |
| @@ -131,7 +133,7 @@ static const struct i2c_reg_value mt9v011_init_default[] = { | |||
| 131 | { R1E_MT9V011_DIGITAL_ZOOM, 0x0000 }, | 133 | { R1E_MT9V011_DIGITAL_ZOOM, 0x0000 }, |
| 132 | { R20_MT9V011_READ_MODE, 0x1000 }, | 134 | { R20_MT9V011_READ_MODE, 0x1000 }, |
| 133 | 135 | ||
| 134 | { R07_MT9V011_OUT_CTRL, 0x000a }, /* chip enable */ | 136 | { R07_MT9V011_OUT_CTRL, 0x0002 }, /* chip enable */ |
| 135 | }; | 137 | }; |
| 136 | 138 | ||
| 137 | static void set_balance(struct v4l2_subdev *sd) | 139 | static void set_balance(struct v4l2_subdev *sd) |
| @@ -154,6 +156,31 @@ static void set_balance(struct v4l2_subdev *sd) | |||
| 154 | mt9v011_write(sd, R2D_MT9V011_RED_GAIN, red_gain); | 156 | mt9v011_write(sd, R2D_MT9V011_RED_GAIN, red_gain); |
| 155 | } | 157 | } |
| 156 | 158 | ||
| 159 | static void calc_fps(struct v4l2_subdev *sd) | ||
| 160 | { | ||
| 161 | struct mt9v011 *core = to_mt9v011(sd); | ||
| 162 | unsigned height, width, hblank, vblank, speed; | ||
| 163 | unsigned row_time, t_time; | ||
| 164 | u64 frames_per_ms; | ||
| 165 | unsigned tmp; | ||
| 166 | |||
| 167 | height = mt9v011_read(sd, R03_MT9V011_HEIGHT); | ||
| 168 | width = mt9v011_read(sd, R04_MT9V011_WIDTH); | ||
| 169 | hblank = mt9v011_read(sd, R05_MT9V011_HBLANK); | ||
| 170 | vblank = mt9v011_read(sd, R06_MT9V011_VBLANK); | ||
| 171 | speed = mt9v011_read(sd, R0A_MT9V011_CLK_SPEED); | ||
| 172 | |||
| 173 | row_time = (width + 113 + hblank) * (speed + 2); | ||
| 174 | t_time = row_time * (height + vblank + 1); | ||
| 175 | |||
| 176 | frames_per_ms = core->xtal * 1000l; | ||
| 177 | do_div(frames_per_ms, t_time); | ||
| 178 | tmp = frames_per_ms; | ||
| 179 | |||
| 180 | v4l2_dbg(1, debug, sd, "Programmed to %u.%03u fps (%d pixel clcks)\n", | ||
| 181 | tmp / 1000, tmp % 1000, t_time); | ||
| 182 | } | ||
| 183 | |||
| 157 | static void set_res(struct v4l2_subdev *sd) | 184 | static void set_res(struct v4l2_subdev *sd) |
| 158 | { | 185 | { |
| 159 | struct mt9v011 *core = to_mt9v011(sd); | 186 | struct mt9v011 *core = to_mt9v011(sd); |
| @@ -175,10 +202,12 @@ static void set_res(struct v4l2_subdev *sd) | |||
| 175 | mt9v011_write(sd, R04_MT9V011_WIDTH, core->width); | 202 | mt9v011_write(sd, R04_MT9V011_WIDTH, core->width); |
| 176 | mt9v011_write(sd, R05_MT9V011_HBLANK, 771 - core->width); | 203 | mt9v011_write(sd, R05_MT9V011_HBLANK, 771 - core->width); |
| 177 | 204 | ||
| 178 | vstart = 8 + (640 - core->height) / 2; | 205 | vstart = 8 + (480 - core->height) / 2; |
| 179 | mt9v011_write(sd, R01_MT9V011_ROWSTART, vstart); | 206 | mt9v011_write(sd, R01_MT9V011_ROWSTART, vstart); |
| 180 | mt9v011_write(sd, R03_MT9V011_HEIGHT, core->height); | 207 | mt9v011_write(sd, R03_MT9V011_HEIGHT, core->height); |
| 181 | mt9v011_write(sd, R06_MT9V011_VBLANK, 508 - core->height); | 208 | mt9v011_write(sd, R06_MT9V011_VBLANK, 508 - core->height); |
| 209 | |||
| 210 | calc_fps(sd); | ||
| 182 | }; | 211 | }; |
| 183 | 212 | ||
| 184 | static int mt9v011_reset(struct v4l2_subdev *sd, u32 val) | 213 | static int mt9v011_reset(struct v4l2_subdev *sd, u32 val) |
| @@ -215,6 +244,23 @@ static int mt9v011_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
| 215 | return -EINVAL; | 244 | return -EINVAL; |
| 216 | } | 245 | } |
| 217 | 246 | ||
| 247 | static int mt9v011_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) | ||
| 248 | { | ||
| 249 | int i; | ||
| 250 | |||
| 251 | v4l2_dbg(1, debug, sd, "queryctrl called\n"); | ||
| 252 | |||
| 253 | for (i = 0; i < ARRAY_SIZE(mt9v011_qctrl); i++) | ||
| 254 | if (qc->id && qc->id == mt9v011_qctrl[i].id) { | ||
| 255 | memcpy(qc, &(mt9v011_qctrl[i]), | ||
| 256 | sizeof(*qc)); | ||
| 257 | return 0; | ||
| 258 | } | ||
| 259 | |||
| 260 | return -EINVAL; | ||
| 261 | } | ||
| 262 | |||
| 263 | |||
| 218 | static int mt9v011_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | 264 | static int mt9v011_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) |
| 219 | { | 265 | { |
| 220 | struct mt9v011 *core = to_mt9v011(sd); | 266 | struct mt9v011 *core = to_mt9v011(sd); |
| @@ -294,6 +340,22 @@ static int mt9v011_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) | |||
| 294 | return 0; | 340 | return 0; |
| 295 | } | 341 | } |
| 296 | 342 | ||
| 343 | static int mt9v011_s_config(struct v4l2_subdev *sd, int dumb, void *data) | ||
| 344 | { | ||
| 345 | struct mt9v011 *core = to_mt9v011(sd); | ||
| 346 | unsigned *xtal = data; | ||
| 347 | |||
| 348 | v4l2_dbg(1, debug, sd, "s_config called\n"); | ||
| 349 | |||
| 350 | if (xtal) { | ||
| 351 | core->xtal = *xtal; | ||
| 352 | v4l2_dbg(1, debug, sd, "xtal set to %d.%03d MHz\n", | ||
| 353 | *xtal / 1000000, (*xtal / 1000) % 1000); | ||
| 354 | } | ||
| 355 | |||
| 356 | return 0; | ||
| 357 | } | ||
| 358 | |||
| 297 | 359 | ||
| 298 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 360 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
| 299 | static int mt9v011_g_register(struct v4l2_subdev *sd, | 361 | static int mt9v011_g_register(struct v4l2_subdev *sd, |
| @@ -338,9 +400,11 @@ static int mt9v011_g_chip_ident(struct v4l2_subdev *sd, | |||
| 338 | } | 400 | } |
| 339 | 401 | ||
| 340 | static const struct v4l2_subdev_core_ops mt9v011_core_ops = { | 402 | static const struct v4l2_subdev_core_ops mt9v011_core_ops = { |
| 403 | .queryctrl = mt9v011_queryctrl, | ||
| 341 | .g_ctrl = mt9v011_g_ctrl, | 404 | .g_ctrl = mt9v011_g_ctrl, |
| 342 | .s_ctrl = mt9v011_s_ctrl, | 405 | .s_ctrl = mt9v011_s_ctrl, |
| 343 | .reset = mt9v011_reset, | 406 | .reset = mt9v011_reset, |
| 407 | .s_config = mt9v011_s_config, | ||
| 344 | .g_chip_ident = mt9v011_g_chip_ident, | 408 | .g_chip_ident = mt9v011_g_chip_ident, |
| 345 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 409 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
| 346 | .g_register = mt9v011_g_register, | 410 | .g_register = mt9v011_g_register, |
| @@ -395,6 +459,7 @@ static int mt9v011_probe(struct i2c_client *c, | |||
| 395 | core->global_gain = 0x0024; | 459 | core->global_gain = 0x0024; |
| 396 | core->width = 640; | 460 | core->width = 640; |
| 397 | core->height = 480; | 461 | core->height = 480; |
| 462 | core->xtal = 27000000; /* Hz */ | ||
| 398 | 463 | ||
| 399 | v4l_info(c, "chip found @ 0x%02x (%s)\n", | 464 | v4l_info(c, "chip found @ 0x%02x (%s)\n", |
| 400 | c->addr << 1, c->adapter->name); | 465 | c->addr << 1, c->adapter->name); |
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index 95846d988011..74f16876f38d 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h | |||
| @@ -338,6 +338,7 @@ struct v4l2_pix_format { | |||
| 338 | /* Vendor-specific formats */ | 338 | /* Vendor-specific formats */ |
| 339 | #define V4L2_PIX_FMT_WNVA v4l2_fourcc('W', 'N', 'V', 'A') /* Winnov hw compress */ | 339 | #define V4L2_PIX_FMT_WNVA v4l2_fourcc('W', 'N', 'V', 'A') /* Winnov hw compress */ |
| 340 | #define V4L2_PIX_FMT_SN9C10X v4l2_fourcc('S', '9', '1', '0') /* SN9C10x compression */ | 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 | #define V4L2_PIX_FMT_PWC1 v4l2_fourcc('P', 'W', 'C', '1') /* pwc older webcam */ | 342 | #define V4L2_PIX_FMT_PWC1 v4l2_fourcc('P', 'W', 'C', '1') /* pwc older webcam */ |
| 342 | #define V4L2_PIX_FMT_PWC2 v4l2_fourcc('P', 'W', 'C', '2') /* pwc newer webcam */ | 343 | #define V4L2_PIX_FMT_PWC2 v4l2_fourcc('P', 'W', 'C', '2') /* pwc newer webcam */ |
| 343 | #define V4L2_PIX_FMT_ET61X251 v4l2_fourcc('E', '6', '2', '5') /* ET61X251 compression */ | 344 | #define V4L2_PIX_FMT_ET61X251 v4l2_fourcc('E', '6', '2', '5') /* ET61X251 compression */ |
diff --git a/include/media/v4l2-chip-ident.h b/include/media/v4l2-chip-ident.h index 11a4a2d3e364..94e908c0d7a0 100644 --- a/include/media/v4l2-chip-ident.h +++ b/include/media/v4l2-chip-ident.h | |||
| @@ -60,6 +60,10 @@ enum { | |||
| 60 | V4L2_IDENT_OV7670 = 250, | 60 | V4L2_IDENT_OV7670 = 250, |
| 61 | V4L2_IDENT_OV7720 = 251, | 61 | V4L2_IDENT_OV7720 = 251, |
| 62 | V4L2_IDENT_OV7725 = 252, | 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 | /* module saa7146: reserved range 300-309 */ | 68 | /* module saa7146: reserved range 300-309 */ |
| 65 | V4L2_IDENT_SAA7146 = 300, | 69 | V4L2_IDENT_SAA7146 = 300, |
| @@ -161,6 +165,9 @@ enum { | |||
| 161 | /* module tw9910: just ident 9910 */ | 165 | /* module tw9910: just ident 9910 */ |
| 162 | V4L2_IDENT_TW9910 = 9910, | 166 | V4L2_IDENT_TW9910 = 9910, |
| 163 | 167 | ||
| 168 | /* module sn9c20x: just ident 10000 */ | ||
| 169 | V4L2_IDENT_SN9C20X = 10000, | ||
| 170 | |||
| 164 | /* module msp3400: reserved range 34000-34999 and 44000-44999 */ | 171 | /* module msp3400: reserved range 34000-34999 and 44000-44999 */ |
| 165 | V4L2_IDENT_MSPX4XX = 34000, /* generic MSPX4XX identifier, only | 172 | V4L2_IDENT_MSPX4XX = 34000, /* generic MSPX4XX identifier, only |
| 166 | use internally (tveeprom.c). */ | 173 | use internally (tveeprom.c). */ |
| @@ -237,6 +244,11 @@ enum { | |||
| 237 | V4L2_IDENT_MT9V022IX7ATC = 45010, /* No way to detect "normal" I77ATx */ | 244 | V4L2_IDENT_MT9V022IX7ATC = 45010, /* No way to detect "normal" I77ATx */ |
| 238 | V4L2_IDENT_MT9V022IX7ATM = 45015, /* and "lead free" IA7ATx chips */ | 245 | V4L2_IDENT_MT9V022IX7ATM = 45015, /* and "lead free" IA7ATx chips */ |
| 239 | V4L2_IDENT_MT9T031 = 45020, | 246 | V4L2_IDENT_MT9T031 = 45020, |
| 247 | V4L2_IDENT_MT9V111 = 45031, | ||
| 248 | V4L2_IDENT_MT9V112 = 45032, | ||
| 249 | |||
| 250 | /* HV7131R CMOS sensor: just ident 46000 */ | ||
| 251 | V4L2_IDENT_HV7131R = 46000, | ||
| 240 | 252 | ||
| 241 | /* module cs53132a: just ident 53132 */ | 253 | /* module cs53132a: just ident 53132 */ |
| 242 | V4L2_IDENT_CS53l32A = 53132, | 254 | V4L2_IDENT_CS53l32A = 53132, |
