diff options
Diffstat (limited to 'drivers/media/video')
-rw-r--r-- | drivers/media/video/gspca/etoms.c | 133 | ||||
-rw-r--r-- | drivers/media/video/gspca/pac7311.c | 54 | ||||
-rw-r--r-- | drivers/media/video/gspca/sonixj.c | 57 | ||||
-rw-r--r-- | drivers/media/video/gspca/spca561.c | 42 |
4 files changed, 171 insertions, 115 deletions
diff --git a/drivers/media/video/gspca/etoms.c b/drivers/media/video/gspca/etoms.c index 6a4e68286ef4..1dbe92d01e6a 100644 --- a/drivers/media/video/gspca/etoms.c +++ b/drivers/media/video/gspca/etoms.c | |||
@@ -461,6 +461,52 @@ static void Et_init2(struct gspca_dev *gspca_dev) | |||
461 | reg_w_val(gspca_dev, 0x80, 0x20); /* 0x20; */ | 461 | reg_w_val(gspca_dev, 0x80, 0x20); /* 0x20; */ |
462 | } | 462 | } |
463 | 463 | ||
464 | static void setbrightness(struct gspca_dev *gspca_dev) | ||
465 | { | ||
466 | struct sd *sd = (struct sd *) gspca_dev; | ||
467 | int i; | ||
468 | __u8 brightness = sd->brightness; | ||
469 | |||
470 | for (i = 0; i < 4; i++) | ||
471 | reg_w_val(gspca_dev, ET_O_RED + i, brightness); | ||
472 | } | ||
473 | |||
474 | static void getbrightness(struct gspca_dev *gspca_dev) | ||
475 | { | ||
476 | struct sd *sd = (struct sd *) gspca_dev; | ||
477 | int i; | ||
478 | int brightness = 0; | ||
479 | |||
480 | for (i = 0; i < 4; i++) { | ||
481 | reg_r(gspca_dev, ET_O_RED + i, 1); | ||
482 | brightness += gspca_dev->usb_buf[0]; | ||
483 | } | ||
484 | sd->brightness = brightness >> 3; | ||
485 | } | ||
486 | |||
487 | static void setcontrast(struct gspca_dev *gspca_dev) | ||
488 | { | ||
489 | struct sd *sd = (struct sd *) gspca_dev; | ||
490 | __u8 RGBG[] = { 0x80, 0x80, 0x80, 0x80, 0x00, 0x00 }; | ||
491 | __u8 contrast = sd->contrast; | ||
492 | |||
493 | memset(RGBG, contrast, sizeof(RGBG) - 2); | ||
494 | reg_w(gspca_dev, ET_G_RED, RGBG, 6); | ||
495 | } | ||
496 | |||
497 | static void getcontrast(struct gspca_dev *gspca_dev) | ||
498 | { | ||
499 | struct sd *sd = (struct sd *) gspca_dev; | ||
500 | int i; | ||
501 | int contrast = 0; | ||
502 | |||
503 | for (i = 0; i < 4; i++) { | ||
504 | reg_r(gspca_dev, ET_G_RED + i, 1); | ||
505 | contrast += gspca_dev->usb_buf[0]; | ||
506 | } | ||
507 | sd->contrast = contrast >> 2; | ||
508 | } | ||
509 | |||
464 | static void setcolors(struct gspca_dev *gspca_dev) | 510 | static void setcolors(struct gspca_dev *gspca_dev) |
465 | { | 511 | { |
466 | struct sd *sd = (struct sd *) gspca_dev; | 512 | struct sd *sd = (struct sd *) gspca_dev; |
@@ -492,6 +538,16 @@ static void getcolors(struct gspca_dev *gspca_dev) | |||
492 | } | 538 | } |
493 | } | 539 | } |
494 | 540 | ||
541 | static void setautogain(struct gspca_dev *gspca_dev) | ||
542 | { | ||
543 | struct sd *sd = (struct sd *) gspca_dev; | ||
544 | |||
545 | if (sd->autogain) | ||
546 | sd->ag_cnt = AG_CNT_START; | ||
547 | else | ||
548 | sd->ag_cnt = -1; | ||
549 | } | ||
550 | |||
495 | static void Et_init1(struct gspca_dev *gspca_dev) | 551 | static void Et_init1(struct gspca_dev *gspca_dev) |
496 | { | 552 | { |
497 | __u8 value; | 553 | __u8 value; |
@@ -614,6 +670,7 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
614 | sd->contrast = CONTRAST_DEF; | 670 | sd->contrast = CONTRAST_DEF; |
615 | sd->colors = COLOR_DEF; | 671 | sd->colors = COLOR_DEF; |
616 | sd->autogain = AUTOGAIN_DEF; | 672 | sd->autogain = AUTOGAIN_DEF; |
673 | sd->ag_cnt = -1; | ||
617 | return 0; | 674 | return 0; |
618 | } | 675 | } |
619 | 676 | ||
@@ -641,6 +698,8 @@ static void sd_start(struct gspca_dev *gspca_dev) | |||
641 | else | 698 | else |
642 | Et_init2(gspca_dev); | 699 | Et_init2(gspca_dev); |
643 | 700 | ||
701 | setautogain(gspca_dev); | ||
702 | |||
644 | reg_w_val(gspca_dev, ET_RESET_ALL, 0x08); | 703 | reg_w_val(gspca_dev, ET_RESET_ALL, 0x08); |
645 | et_video(gspca_dev, 1); /* video on */ | 704 | et_video(gspca_dev, 1); /* video on */ |
646 | } | 705 | } |
@@ -658,52 +717,6 @@ static void sd_close(struct gspca_dev *gspca_dev) | |||
658 | { | 717 | { |
659 | } | 718 | } |
660 | 719 | ||
661 | static void setbrightness(struct gspca_dev *gspca_dev) | ||
662 | { | ||
663 | struct sd *sd = (struct sd *) gspca_dev; | ||
664 | int i; | ||
665 | __u8 brightness = sd->brightness; | ||
666 | |||
667 | for (i = 0; i < 4; i++) | ||
668 | reg_w_val(gspca_dev, ET_O_RED + i, brightness); | ||
669 | } | ||
670 | |||
671 | static void getbrightness(struct gspca_dev *gspca_dev) | ||
672 | { | ||
673 | struct sd *sd = (struct sd *) gspca_dev; | ||
674 | int i; | ||
675 | int brightness = 0; | ||
676 | |||
677 | for (i = 0; i < 4; i++) { | ||
678 | reg_r(gspca_dev, ET_O_RED + i, 1); | ||
679 | brightness += gspca_dev->usb_buf[0]; | ||
680 | } | ||
681 | sd->brightness = brightness >> 3; | ||
682 | } | ||
683 | |||
684 | static void setcontrast(struct gspca_dev *gspca_dev) | ||
685 | { | ||
686 | struct sd *sd = (struct sd *) gspca_dev; | ||
687 | __u8 RGBG[] = { 0x80, 0x80, 0x80, 0x80, 0x00, 0x00 }; | ||
688 | __u8 contrast = sd->contrast; | ||
689 | |||
690 | memset(RGBG, contrast, sizeof(RGBG) - 2); | ||
691 | reg_w(gspca_dev, ET_G_RED, RGBG, 6); | ||
692 | } | ||
693 | |||
694 | static void getcontrast(struct gspca_dev *gspca_dev) | ||
695 | { | ||
696 | struct sd *sd = (struct sd *) gspca_dev; | ||
697 | int i; | ||
698 | int contrast = 0; | ||
699 | |||
700 | for (i = 0; i < 4; i++) { | ||
701 | reg_r(gspca_dev, ET_G_RED + i, 1); | ||
702 | contrast += gspca_dev->usb_buf[0]; | ||
703 | } | ||
704 | sd->contrast = contrast >> 2; | ||
705 | } | ||
706 | |||
707 | static __u8 Et_getgainG(struct gspca_dev *gspca_dev) | 720 | static __u8 Et_getgainG(struct gspca_dev *gspca_dev) |
708 | { | 721 | { |
709 | struct sd *sd = (struct sd *) gspca_dev; | 722 | struct sd *sd = (struct sd *) gspca_dev; |
@@ -733,15 +746,22 @@ static void Et_setgainG(struct gspca_dev *gspca_dev, __u8 gain) | |||
733 | #define LIMIT(color) \ | 746 | #define LIMIT(color) \ |
734 | (unsigned char)((color > 0xff)?0xff:((color < 0)?0:color)) | 747 | (unsigned char)((color > 0xff)?0xff:((color < 0)?0:color)) |
735 | 748 | ||
736 | static void setautogain(struct gspca_dev *gspca_dev) | 749 | static void do_autogain(struct gspca_dev *gspca_dev) |
737 | { | 750 | { |
738 | __u8 luma = 0; | 751 | struct sd *sd = (struct sd *) gspca_dev; |
752 | __u8 luma; | ||
739 | __u8 luma_mean = 128; | 753 | __u8 luma_mean = 128; |
740 | __u8 luma_delta = 20; | 754 | __u8 luma_delta = 20; |
741 | __u8 spring = 4; | 755 | __u8 spring = 4; |
742 | int Gbright = 0; | 756 | int Gbright; |
743 | __u8 r, g, b; | 757 | __u8 r, g, b; |
744 | 758 | ||
759 | if (sd->ag_cnt < 0) | ||
760 | return; | ||
761 | if (--sd->ag_cnt >= 0) | ||
762 | return; | ||
763 | sd->ag_cnt = AG_CNT_START; | ||
764 | |||
745 | Gbright = Et_getgainG(gspca_dev); | 765 | Gbright = Et_getgainG(gspca_dev); |
746 | reg_r(gspca_dev, ET_LUMA_CENTER, 4); | 766 | reg_r(gspca_dev, ET_LUMA_CENTER, 4); |
747 | g = (gspca_dev->usb_buf[0] + gspca_dev->usb_buf[3]) >> 1; | 767 | g = (gspca_dev->usb_buf[0] + gspca_dev->usb_buf[3]) >> 1; |
@@ -768,7 +788,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
768 | __u8 *data, /* isoc packet */ | 788 | __u8 *data, /* isoc packet */ |
769 | int len) /* iso packet length */ | 789 | int len) /* iso packet length */ |
770 | { | 790 | { |
771 | struct sd *sd; | ||
772 | int seqframe; | 791 | int seqframe; |
773 | 792 | ||
774 | seqframe = data[0] & 0x3f; | 793 | seqframe = data[0] & 0x3f; |
@@ -783,13 +802,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
783 | frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, | 802 | frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, |
784 | data, 0); | 803 | data, 0); |
785 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len); | 804 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len); |
786 | sd = (struct sd *) gspca_dev; | ||
787 | if (sd->ag_cnt >= 0) { | ||
788 | if (--sd->ag_cnt < 0) { | ||
789 | sd->ag_cnt = AG_CNT_START; | ||
790 | setautogain(gspca_dev); | ||
791 | } | ||
792 | } | ||
793 | return; | 805 | return; |
794 | } | 806 | } |
795 | if (len) { | 807 | if (len) { |
@@ -862,10 +874,8 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) | |||
862 | struct sd *sd = (struct sd *) gspca_dev; | 874 | struct sd *sd = (struct sd *) gspca_dev; |
863 | 875 | ||
864 | sd->autogain = val; | 876 | sd->autogain = val; |
865 | if (val) | 877 | if (gspca_dev->streaming) |
866 | sd->ag_cnt = AG_CNT_START; | 878 | setautogain(gspca_dev); |
867 | else | ||
868 | sd->ag_cnt = -1; | ||
869 | return 0; | 879 | return 0; |
870 | } | 880 | } |
871 | 881 | ||
@@ -889,6 +899,7 @@ static struct sd_desc sd_desc = { | |||
889 | .stop0 = sd_stop0, | 899 | .stop0 = sd_stop0, |
890 | .close = sd_close, | 900 | .close = sd_close, |
891 | .pkt_scan = sd_pkt_scan, | 901 | .pkt_scan = sd_pkt_scan, |
902 | .dq_callback = do_autogain, | ||
892 | }; | 903 | }; |
893 | 904 | ||
894 | /* -- module initialisation -- */ | 905 | /* -- module initialisation -- */ |
diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c index ea3d7021f401..815bea6edc44 100644 --- a/drivers/media/video/gspca/pac7311.c +++ b/drivers/media/video/gspca/pac7311.c | |||
@@ -31,7 +31,9 @@ MODULE_LICENSE("GPL"); | |||
31 | struct sd { | 31 | struct sd { |
32 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 32 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
33 | 33 | ||
34 | int avg_lum; | 34 | int lum_sum; |
35 | atomic_t avg_lum; | ||
36 | atomic_t do_gain; | ||
35 | 37 | ||
36 | unsigned char brightness; | 38 | unsigned char brightness; |
37 | unsigned char contrast; | 39 | unsigned char contrast; |
@@ -271,6 +273,7 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
271 | sd->contrast = CONTRAST_DEF; | 273 | sd->contrast = CONTRAST_DEF; |
272 | sd->colors = COLOR_DEF; | 274 | sd->colors = COLOR_DEF; |
273 | sd->autogain = AUTOGAIN_DEF; | 275 | sd->autogain = AUTOGAIN_DEF; |
276 | sd->ag_cnt = -1; | ||
274 | return 0; | 277 | return 0; |
275 | } | 278 | } |
276 | 279 | ||
@@ -311,6 +314,18 @@ static void setcolors(struct gspca_dev *gspca_dev) | |||
311 | PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors); | 314 | PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors); |
312 | } | 315 | } |
313 | 316 | ||
317 | static void setautogain(struct gspca_dev *gspca_dev) | ||
318 | { | ||
319 | struct sd *sd = (struct sd *) gspca_dev; | ||
320 | |||
321 | if (sd->autogain) { | ||
322 | sd->lum_sum = 0; | ||
323 | sd->ag_cnt = AG_CNT_START; | ||
324 | } else { | ||
325 | sd->ag_cnt = -1; | ||
326 | } | ||
327 | } | ||
328 | |||
314 | /* this function is called at open time */ | 329 | /* this function is called at open time */ |
315 | static int sd_open(struct gspca_dev *gspca_dev) | 330 | static int sd_open(struct gspca_dev *gspca_dev) |
316 | { | 331 | { |
@@ -320,8 +335,6 @@ static int sd_open(struct gspca_dev *gspca_dev) | |||
320 | 335 | ||
321 | static void sd_start(struct gspca_dev *gspca_dev) | 336 | static void sd_start(struct gspca_dev *gspca_dev) |
322 | { | 337 | { |
323 | struct sd *sd = (struct sd *) gspca_dev; | ||
324 | |||
325 | reg_w(gspca_dev, 0xff, 0x01); | 338 | reg_w(gspca_dev, 0xff, 0x01); |
326 | reg_w_buf(gspca_dev, 0x0002, "\x48\x0a\x40\x08\x00\x00\x08\x00", 8); | 339 | reg_w_buf(gspca_dev, 0x0002, "\x48\x0a\x40\x08\x00\x00\x08\x00", 8); |
327 | reg_w_buf(gspca_dev, 0x000a, "\x06\xff\x11\xff\x5a\x30\x90\x4c", 8); | 340 | reg_w_buf(gspca_dev, 0x000a, "\x06\xff\x11\xff\x5a\x30\x90\x4c", 8); |
@@ -394,6 +407,7 @@ static void sd_start(struct gspca_dev *gspca_dev) | |||
394 | setcontrast(gspca_dev); | 407 | setcontrast(gspca_dev); |
395 | setbrightness(gspca_dev); | 408 | setbrightness(gspca_dev); |
396 | setcolors(gspca_dev); | 409 | setcolors(gspca_dev); |
410 | setautogain(gspca_dev); | ||
397 | 411 | ||
398 | /* set correct resolution */ | 412 | /* set correct resolution */ |
399 | switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { | 413 | switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { |
@@ -431,13 +445,6 @@ static void sd_start(struct gspca_dev *gspca_dev) | |||
431 | reg_w(gspca_dev, 0xff, 0x01); | 445 | reg_w(gspca_dev, 0xff, 0x01); |
432 | reg_w(gspca_dev, 0x78, 0x04); | 446 | reg_w(gspca_dev, 0x78, 0x04); |
433 | reg_w(gspca_dev, 0x78, 0x05); | 447 | reg_w(gspca_dev, 0x78, 0x05); |
434 | |||
435 | if (sd->autogain) { | ||
436 | sd->ag_cnt = AG_CNT_START; | ||
437 | sd->avg_lum = 0; | ||
438 | } else { | ||
439 | sd->ag_cnt = -1; | ||
440 | } | ||
441 | } | 448 | } |
442 | 449 | ||
443 | static void sd_stopN(struct gspca_dev *gspca_dev) | 450 | static void sd_stopN(struct gspca_dev *gspca_dev) |
@@ -473,13 +480,20 @@ static void sd_close(struct gspca_dev *gspca_dev) | |||
473 | reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */ | 480 | reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */ |
474 | } | 481 | } |
475 | 482 | ||
476 | static void setautogain(struct gspca_dev *gspca_dev, int luma) | 483 | static void do_autogain(struct gspca_dev *gspca_dev) |
477 | { | 484 | { |
485 | struct sd *sd = (struct sd *) gspca_dev; | ||
486 | int luma; | ||
478 | int luma_mean = 128; | 487 | int luma_mean = 128; |
479 | int luma_delta = 20; | 488 | int luma_delta = 20; |
480 | __u8 spring = 5; | 489 | __u8 spring = 5; |
481 | int Gbright; | 490 | int Gbright; |
482 | 491 | ||
492 | if (!atomic_read(&sd->do_gain)) | ||
493 | return; | ||
494 | atomic_set(&sd->do_gain, 0); | ||
495 | |||
496 | luma = atomic_read(&sd->avg_lum); | ||
483 | Gbright = reg_r(gspca_dev, 0x02); | 497 | Gbright = reg_r(gspca_dev, 0x02); |
484 | PDEBUG(D_FRAM, "luma mean %d", luma); | 498 | PDEBUG(D_FRAM, "luma mean %d", luma); |
485 | if (luma < luma_mean - luma_delta || | 499 | if (luma < luma_mean - luma_delta || |
@@ -523,12 +537,13 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
523 | 537 | ||
524 | /* start of frame */ | 538 | /* start of frame */ |
525 | if (sd->ag_cnt >= 0 && p > 28) { | 539 | if (sd->ag_cnt >= 0 && p > 28) { |
526 | sd->avg_lum += data[p - 23]; | 540 | sd->lum_sum += data[p - 23]; |
527 | if (--sd->ag_cnt < 0) { | 541 | if (--sd->ag_cnt < 0) { |
528 | sd->ag_cnt = AG_CNT_START; | 542 | sd->ag_cnt = AG_CNT_START; |
529 | setautogain(gspca_dev, | 543 | atomic_set(&sd->avg_lum, |
530 | sd->avg_lum / AG_CNT_START); | 544 | sd->lum_sum / AG_CNT_START); |
531 | sd->avg_lum = 0; | 545 | sd->lum_sum = 0; |
546 | atomic_set(&sd->do_gain, 1); | ||
532 | } | 547 | } |
533 | } | 548 | } |
534 | 549 | ||
@@ -677,12 +692,8 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) | |||
677 | struct sd *sd = (struct sd *) gspca_dev; | 692 | struct sd *sd = (struct sd *) gspca_dev; |
678 | 693 | ||
679 | sd->autogain = val; | 694 | sd->autogain = val; |
680 | if (val) { | 695 | if (gspca_dev->streaming) |
681 | sd->ag_cnt = AG_CNT_START; | 696 | setautogain(gspca_dev); |
682 | sd->avg_lum = 0; | ||
683 | } else { | ||
684 | sd->ag_cnt = -1; | ||
685 | } | ||
686 | return 0; | 697 | return 0; |
687 | } | 698 | } |
688 | 699 | ||
@@ -706,6 +717,7 @@ static struct sd_desc sd_desc = { | |||
706 | .stop0 = sd_stop0, | 717 | .stop0 = sd_stop0, |
707 | .close = sd_close, | 718 | .close = sd_close, |
708 | .pkt_scan = sd_pkt_scan, | 719 | .pkt_scan = sd_pkt_scan, |
720 | .dq_callback = do_autogain, | ||
709 | }; | 721 | }; |
710 | 722 | ||
711 | /* -- module initialisation -- */ | 723 | /* -- module initialisation -- */ |
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index b60ff600a757..245a30ec5fb1 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c | |||
@@ -32,7 +32,7 @@ MODULE_LICENSE("GPL"); | |||
32 | struct sd { | 32 | struct sd { |
33 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 33 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
34 | 34 | ||
35 | int avg_lum; | 35 | atomic_t avg_lum; |
36 | unsigned int exposure; | 36 | unsigned int exposure; |
37 | 37 | ||
38 | unsigned short brightness; | 38 | unsigned short brightness; |
@@ -781,6 +781,8 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
781 | sd->contrast = CONTRAST_DEF; | 781 | sd->contrast = CONTRAST_DEF; |
782 | sd->colors = COLOR_DEF; | 782 | sd->colors = COLOR_DEF; |
783 | sd->autogain = AUTOGAIN_DEF; | 783 | sd->autogain = AUTOGAIN_DEF; |
784 | sd->ag_cnt = -1; | ||
785 | |||
784 | return 0; | 786 | return 0; |
785 | } | 787 | } |
786 | 788 | ||
@@ -946,6 +948,22 @@ static void setcolors(struct gspca_dev *gspca_dev) | |||
946 | reg_w1(gspca_dev, 0x05, data); | 948 | reg_w1(gspca_dev, 0x05, data); |
947 | } | 949 | } |
948 | 950 | ||
951 | static void setautogain(struct gspca_dev *gspca_dev) | ||
952 | { | ||
953 | struct sd *sd = (struct sd *) gspca_dev; | ||
954 | |||
955 | switch (sd->sensor) { | ||
956 | case SENSOR_HV7131R: | ||
957 | case SENSOR_MO4000: | ||
958 | case SENSOR_MI0360: | ||
959 | if (sd->autogain) | ||
960 | sd->ag_cnt = AG_CNT_START; | ||
961 | else | ||
962 | sd->ag_cnt = -1; | ||
963 | break; | ||
964 | } | ||
965 | } | ||
966 | |||
949 | /* -- start the camera -- */ | 967 | /* -- start the camera -- */ |
950 | static void sd_start(struct gspca_dev *gspca_dev) | 968 | static void sd_start(struct gspca_dev *gspca_dev) |
951 | { | 969 | { |
@@ -1078,6 +1096,7 @@ static void sd_start(struct gspca_dev *gspca_dev) | |||
1078 | reg_w1(gspca_dev, 0x01, reg1); | 1096 | reg_w1(gspca_dev, 0x01, reg1); |
1079 | setbrightness(gspca_dev); | 1097 | setbrightness(gspca_dev); |
1080 | setcontrast(gspca_dev); | 1098 | setcontrast(gspca_dev); |
1099 | setautogain(gspca_dev); | ||
1081 | } | 1100 | } |
1082 | 1101 | ||
1083 | static void sd_stopN(struct gspca_dev *gspca_dev) | 1102 | static void sd_stopN(struct gspca_dev *gspca_dev) |
@@ -1124,16 +1143,23 @@ static void sd_close(struct gspca_dev *gspca_dev) | |||
1124 | { | 1143 | { |
1125 | } | 1144 | } |
1126 | 1145 | ||
1127 | static void setautogain(struct gspca_dev *gspca_dev) | 1146 | static void do_autogain(struct gspca_dev *gspca_dev) |
1128 | { | 1147 | { |
1129 | struct sd *sd = (struct sd *) gspca_dev; | 1148 | struct sd *sd = (struct sd *) gspca_dev; |
1130 | /* Thanks S., without your advice, autobright should not work :) */ | ||
1131 | int delta; | 1149 | int delta; |
1132 | int expotimes = 0; | 1150 | int expotimes; |
1133 | __u8 luma_mean = 130; | 1151 | __u8 luma_mean = 130; |
1134 | __u8 luma_delta = 20; | 1152 | __u8 luma_delta = 20; |
1135 | 1153 | ||
1136 | delta = sd->avg_lum; | 1154 | /* Thanks S., without your advice, autobright should not work :) */ |
1155 | if (sd->ag_cnt < 0) | ||
1156 | return; | ||
1157 | if (--sd->ag_cnt >= 0) | ||
1158 | return; | ||
1159 | sd->ag_cnt = AG_CNT_START; | ||
1160 | |||
1161 | delta = atomic_read(&sd->avg_lum); | ||
1162 | PDEBUG(D_FRAM, "mean lum %d", delta); | ||
1137 | if (delta < luma_mean - luma_delta || | 1163 | if (delta < luma_mean - luma_delta || |
1138 | delta > luma_mean + luma_delta) { | 1164 | delta > luma_mean + luma_delta) { |
1139 | switch (sd->sensor) { | 1165 | switch (sd->sensor) { |
@@ -1145,8 +1171,9 @@ static void setautogain(struct gspca_dev *gspca_dev) | |||
1145 | sd->exposure = setexposure(gspca_dev, | 1171 | sd->exposure = setexposure(gspca_dev, |
1146 | (unsigned int) (expotimes << 8)); | 1172 | (unsigned int) (expotimes << 8)); |
1147 | break; | 1173 | break; |
1148 | case SENSOR_MO4000: | 1174 | default: |
1149 | case SENSOR_MI0360: | 1175 | /* case SENSOR_MO4000: */ |
1176 | /* case SENSOR_MI0360: */ | ||
1150 | expotimes = sd->exposure; | 1177 | expotimes = sd->exposure; |
1151 | expotimes += (luma_mean - delta) >> 6; | 1178 | expotimes += (luma_mean - delta) >> 6; |
1152 | if (expotimes < 0) | 1179 | if (expotimes < 0) |
@@ -1159,6 +1186,8 @@ static void setautogain(struct gspca_dev *gspca_dev) | |||
1159 | } | 1186 | } |
1160 | } | 1187 | } |
1161 | 1188 | ||
1189 | /* scan the URB packets */ | ||
1190 | /* This function is run at interrupt level. */ | ||
1162 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | 1191 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, |
1163 | struct gspca_frame *frame, /* target */ | 1192 | struct gspca_frame *frame, /* target */ |
1164 | __u8 *data, /* isoc packet */ | 1193 | __u8 *data, /* isoc packet */ |
@@ -1175,9 +1204,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
1175 | frame, data, sof + 2); | 1204 | frame, data, sof + 2); |
1176 | if (sd->ag_cnt < 0) | 1205 | if (sd->ag_cnt < 0) |
1177 | return; | 1206 | return; |
1178 | if (--sd->ag_cnt >= 0) | ||
1179 | return; | ||
1180 | sd->ag_cnt = AG_CNT_START; | ||
1181 | /* w1 w2 w3 */ | 1207 | /* w1 w2 w3 */ |
1182 | /* w4 w5 w6 */ | 1208 | /* w4 w5 w6 */ |
1183 | /* w7 w8 */ | 1209 | /* w7 w8 */ |
@@ -1192,9 +1218,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
1192 | /* w5 */ | 1218 | /* w5 */ |
1193 | avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4; | 1219 | avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4; |
1194 | avg_lum >>= 4; | 1220 | avg_lum >>= 4; |
1195 | sd->avg_lum = avg_lum; | 1221 | atomic_set(&sd->avg_lum, avg_lum); |
1196 | PDEBUG(D_PACK, "mean lum %d", avg_lum); | ||
1197 | setautogain(gspca_dev); | ||
1198 | return; | 1222 | return; |
1199 | } | 1223 | } |
1200 | if (gspca_dev->last_packet_type == LAST_PACKET) { | 1224 | if (gspca_dev->last_packet_type == LAST_PACKET) { |
@@ -1321,10 +1345,8 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) | |||
1321 | struct sd *sd = (struct sd *) gspca_dev; | 1345 | struct sd *sd = (struct sd *) gspca_dev; |
1322 | 1346 | ||
1323 | sd->autogain = val; | 1347 | sd->autogain = val; |
1324 | if (val) | 1348 | if (gspca_dev->streaming) |
1325 | sd->ag_cnt = AG_CNT_START; | 1349 | setautogain(gspca_dev); |
1326 | else | ||
1327 | sd->ag_cnt = -1; | ||
1328 | return 0; | 1350 | return 0; |
1329 | } | 1351 | } |
1330 | 1352 | ||
@@ -1348,6 +1370,7 @@ static const struct sd_desc sd_desc = { | |||
1348 | .stop0 = sd_stop0, | 1370 | .stop0 = sd_stop0, |
1349 | .close = sd_close, | 1371 | .close = sd_close, |
1350 | .pkt_scan = sd_pkt_scan, | 1372 | .pkt_scan = sd_pkt_scan, |
1373 | .dq_callback = do_autogain, | ||
1351 | }; | 1374 | }; |
1352 | 1375 | ||
1353 | /* -- module initialisation -- */ | 1376 | /* -- module initialisation -- */ |
diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c index a26174508cb9..1073ac3d2ec6 100644 --- a/drivers/media/video/gspca/spca561.c +++ b/drivers/media/video/gspca/spca561.c | |||
@@ -644,6 +644,18 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
644 | } | 644 | } |
645 | } | 645 | } |
646 | 646 | ||
647 | static void setautogain(struct gspca_dev *gspca_dev) | ||
648 | { | ||
649 | struct sd *sd = (struct sd *) gspca_dev; | ||
650 | |||
651 | if (sd->chip_revision == Rev072A) { | ||
652 | if (sd->autogain) | ||
653 | sd->ag_cnt = AG_CNT_START; | ||
654 | else | ||
655 | sd->ag_cnt = -1; | ||
656 | } | ||
657 | } | ||
658 | |||
647 | static void sd_start(struct gspca_dev *gspca_dev) | 659 | static void sd_start(struct gspca_dev *gspca_dev) |
648 | { | 660 | { |
649 | struct sd *sd = (struct sd *) gspca_dev; | 661 | struct sd *sd = (struct sd *) gspca_dev; |
@@ -671,6 +683,7 @@ static void sd_start(struct gspca_dev *gspca_dev) | |||
671 | reg_w_val(dev, 0x8500, mode); /* mode */ | 683 | reg_w_val(dev, 0x8500, mode); /* mode */ |
672 | reg_w_val(dev, 0x8700, Clck); /* 0x27 clock */ | 684 | reg_w_val(dev, 0x8700, Clck); /* 0x27 clock */ |
673 | reg_w_val(dev, 0x8112, 0x10 | 0x20); | 685 | reg_w_val(dev, 0x8112, 0x10 | 0x20); |
686 | setautogain(gspca_dev); | ||
674 | break; | 687 | break; |
675 | default: | 688 | default: |
676 | /* case Rev012A: */ | 689 | /* case Rev012A: */ |
@@ -720,18 +733,24 @@ static void sd_close(struct gspca_dev *gspca_dev) | |||
720 | reg_w_val(gspca_dev->dev, 0x8114, 0); | 733 | reg_w_val(gspca_dev->dev, 0x8114, 0); |
721 | } | 734 | } |
722 | 735 | ||
723 | static void setautogain(struct gspca_dev *gspca_dev) | 736 | static void do_autogain(struct gspca_dev *gspca_dev) |
724 | { | 737 | { |
725 | struct sd *sd = (struct sd *) gspca_dev; | 738 | struct sd *sd = (struct sd *) gspca_dev; |
726 | int expotimes = 0; | 739 | int expotimes; |
727 | int pixelclk = 0; | 740 | int pixelclk; |
728 | int gainG = 0; | 741 | int gainG; |
729 | __u8 R, Gr, Gb, B; | 742 | __u8 R, Gr, Gb, B; |
730 | int y; | 743 | int y; |
731 | __u8 luma_mean = 110; | 744 | __u8 luma_mean = 110; |
732 | __u8 luma_delta = 20; | 745 | __u8 luma_delta = 20; |
733 | __u8 spring = 4; | 746 | __u8 spring = 4; |
734 | 747 | ||
748 | if (sd->ag_cnt < 0) | ||
749 | return; | ||
750 | if (--sd->ag_cnt >= 0) | ||
751 | return; | ||
752 | sd->ag_cnt = AG_CNT_START; | ||
753 | |||
735 | switch (sd->chip_revision) { | 754 | switch (sd->chip_revision) { |
736 | case Rev072A: | 755 | case Rev072A: |
737 | reg_r(gspca_dev, 0x8621, 1); | 756 | reg_r(gspca_dev, 0x8621, 1); |
@@ -795,18 +814,10 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
795 | __u8 *data, /* isoc packet */ | 814 | __u8 *data, /* isoc packet */ |
796 | int len) /* iso packet length */ | 815 | int len) /* iso packet length */ |
797 | { | 816 | { |
798 | struct sd *sd = (struct sd *) gspca_dev; | ||
799 | |||
800 | switch (data[0]) { | 817 | switch (data[0]) { |
801 | case 0: /* start of frame */ | 818 | case 0: /* start of frame */ |
802 | frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, | 819 | frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, |
803 | data, 0); | 820 | data, 0); |
804 | if (sd->ag_cnt >= 0) { | ||
805 | if (--sd->ag_cnt < 0) { | ||
806 | sd->ag_cnt = AG_CNT_START; | ||
807 | setautogain(gspca_dev); | ||
808 | } | ||
809 | } | ||
810 | data += SPCA561_OFFSET_DATA; | 821 | data += SPCA561_OFFSET_DATA; |
811 | len -= SPCA561_OFFSET_DATA; | 822 | len -= SPCA561_OFFSET_DATA; |
812 | if (data[1] & 0x10) { | 823 | if (data[1] & 0x10) { |
@@ -944,10 +955,8 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) | |||
944 | struct sd *sd = (struct sd *) gspca_dev; | 955 | struct sd *sd = (struct sd *) gspca_dev; |
945 | 956 | ||
946 | sd->autogain = val; | 957 | sd->autogain = val; |
947 | if (val) | 958 | if (gspca_dev->streaming) |
948 | sd->ag_cnt = AG_CNT_START; | 959 | setautogain(gspca_dev); |
949 | else | ||
950 | sd->ag_cnt = -1; | ||
951 | return 0; | 960 | return 0; |
952 | } | 961 | } |
953 | 962 | ||
@@ -971,6 +980,7 @@ static const struct sd_desc sd_desc = { | |||
971 | .stop0 = sd_stop0, | 980 | .stop0 = sd_stop0, |
972 | .close = sd_close, | 981 | .close = sd_close, |
973 | .pkt_scan = sd_pkt_scan, | 982 | .pkt_scan = sd_pkt_scan, |
983 | .dq_callback = do_autogain, | ||
974 | }; | 984 | }; |
975 | 985 | ||
976 | /* -- module initialisation -- */ | 986 | /* -- module initialisation -- */ |