diff options
| -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 -- */ |
