diff options
author | Hans de Goede <j.w.r.degoede@hhs.nl> | 2008-07-10 09:40:53 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-07-20 06:25:59 -0400 |
commit | dcef3237b652e1c02093feac0f443485a144f035 (patch) | |
tree | 81df2d056ef1c4179868512076d9339dbd98680a /drivers/media/video/gspca/pac207.c | |
parent | d0d0e39bc5912793405d3f84ffc982fa400e6cc0 (diff) |
V4L/DVB (8348): gspca: Add auto gain/exposure to sonixb and tas5110 / ov6650 sensors.
sonixb: Do auto gain for tas5110 / ov6650 sensors.
pac207: Move the auto_gain function to gspca.
gspca: New function gspca_auto_gain_n_exposure().
Signed-off-by: Hans de Goede <j.w.r.degoede@hhs.nl>
Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/gspca/pac207.c')
-rw-r--r-- | drivers/media/video/gspca/pac207.c | 68 |
1 files changed, 5 insertions, 63 deletions
diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c index 4f197c1f4a76..5d68d3f42262 100644 --- a/drivers/media/video/gspca/pac207.c +++ b/drivers/media/video/gspca/pac207.c | |||
@@ -357,70 +357,20 @@ static void sd_close(struct gspca_dev *gspca_dev) | |||
357 | { | 357 | { |
358 | } | 358 | } |
359 | 359 | ||
360 | /* auto gain and exposure algorithm based on the knee algorithm described here: | ||
361 | * <http://ytse.tricolour.net/docs/LowLightOptimization.html> */ | ||
362 | static void pac207_do_auto_gain(struct gspca_dev *gspca_dev) | 360 | static void pac207_do_auto_gain(struct gspca_dev *gspca_dev) |
363 | { | 361 | { |
364 | struct sd *sd = (struct sd *) gspca_dev; | 362 | struct sd *sd = (struct sd *) gspca_dev; |
365 | int i, steps, desired_avg_lum; | ||
366 | int orig_gain = sd->gain; | ||
367 | int orig_exposure = sd->exposure; | ||
368 | int avg_lum = atomic_read(&sd->avg_lum); | 363 | int avg_lum = atomic_read(&sd->avg_lum); |
369 | 364 | ||
370 | if (!sd->autogain || avg_lum == -1) | 365 | if (avg_lum == -1) |
371 | return; | 366 | return; |
372 | 367 | ||
373 | if (sd->autogain_ignore_frames > 0) { | 368 | if (sd->autogain_ignore_frames > 0) |
374 | sd->autogain_ignore_frames--; | 369 | sd->autogain_ignore_frames--; |
375 | return; | 370 | else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum, |
376 | } | 371 | 100 + sd->brightness / 2, PAC207_AUTOGAIN_DEADZONE, |
377 | 372 | PAC207_GAIN_KNEE, PAC207_EXPOSURE_KNEE)) | |
378 | /* correct desired lumination for the configured brightness */ | ||
379 | desired_avg_lum = 100 + sd->brightness / 2; | ||
380 | |||
381 | /* If we are of a multiple of deadzone, do multiple step to reach the | ||
382 | desired lumination fast (with the risc of a slight overshoot) */ | ||
383 | steps = abs(desired_avg_lum - avg_lum) / PAC207_AUTOGAIN_DEADZONE; | ||
384 | |||
385 | for (i = 0; i < steps; i++) { | ||
386 | if (avg_lum > desired_avg_lum) { | ||
387 | if (sd->gain > PAC207_GAIN_KNEE) | ||
388 | sd->gain--; | ||
389 | else if (sd->exposure > PAC207_EXPOSURE_KNEE) | ||
390 | sd->exposure--; | ||
391 | else if (sd->gain > PAC207_GAIN_DEFAULT) | ||
392 | sd->gain--; | ||
393 | else if (sd->exposure > PAC207_EXPOSURE_MIN) | ||
394 | sd->exposure--; | ||
395 | else if (sd->gain > PAC207_GAIN_MIN) | ||
396 | sd->gain--; | ||
397 | else | ||
398 | break; | ||
399 | } else { | ||
400 | if (sd->gain < PAC207_GAIN_DEFAULT) | ||
401 | sd->gain++; | ||
402 | else if (sd->exposure < PAC207_EXPOSURE_KNEE) | ||
403 | sd->exposure++; | ||
404 | else if (sd->gain < PAC207_GAIN_KNEE) | ||
405 | sd->gain++; | ||
406 | else if (sd->exposure < PAC207_EXPOSURE_MAX) | ||
407 | sd->exposure++; | ||
408 | else if (sd->gain < PAC207_GAIN_MAX) | ||
409 | sd->gain++; | ||
410 | else | ||
411 | break; | ||
412 | } | ||
413 | } | ||
414 | |||
415 | if (sd->exposure != orig_exposure || sd->gain != orig_gain) { | ||
416 | if (sd->exposure != orig_exposure) | ||
417 | pac207_write_reg(gspca_dev, 0x0002, sd->exposure); | ||
418 | if (sd->gain != orig_gain) | ||
419 | pac207_write_reg(gspca_dev, 0x000e, sd->gain); | ||
420 | pac207_write_reg(gspca_dev, 0x13, 0x01); /* load reg to sen */ | ||
421 | pac207_write_reg(gspca_dev, 0x1c, 0x01); /* not documented */ | ||
422 | sd->autogain_ignore_frames = PAC207_AUTOGAIN_IGNORE_FRAMES; | 373 | sd->autogain_ignore_frames = PAC207_AUTOGAIN_IGNORE_FRAMES; |
423 | } | ||
424 | } | 374 | } |
425 | 375 | ||
426 | static unsigned char *pac207_find_sof(struct gspca_dev *gspca_dev, | 376 | static unsigned char *pac207_find_sof(struct gspca_dev *gspca_dev, |
@@ -546,10 +496,6 @@ static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val) | |||
546 | { | 496 | { |
547 | struct sd *sd = (struct sd *) gspca_dev; | 497 | struct sd *sd = (struct sd *) gspca_dev; |
548 | 498 | ||
549 | /* don't allow mucking with exposure when using autogain */ | ||
550 | if (sd->autogain) | ||
551 | return -EINVAL; | ||
552 | |||
553 | sd->exposure = val; | 499 | sd->exposure = val; |
554 | if (gspca_dev->streaming) | 500 | if (gspca_dev->streaming) |
555 | setexposure(gspca_dev); | 501 | setexposure(gspca_dev); |
@@ -568,10 +514,6 @@ static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val) | |||
568 | { | 514 | { |
569 | struct sd *sd = (struct sd *) gspca_dev; | 515 | struct sd *sd = (struct sd *) gspca_dev; |
570 | 516 | ||
571 | /* don't allow mucking with gain when using autogain */ | ||
572 | if (sd->autogain) | ||
573 | return -EINVAL; | ||
574 | |||
575 | sd->gain = val; | 517 | sd->gain = val; |
576 | if (gspca_dev->streaming) | 518 | if (gspca_dev->streaming) |
577 | setgain(gspca_dev); | 519 | setgain(gspca_dev); |