diff options
Diffstat (limited to 'drivers/media/video/gspca/pac7311.c')
-rw-r--r-- | drivers/media/video/gspca/pac7311.c | 54 |
1 files changed, 33 insertions, 21 deletions
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 -- */ |