aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca/spca561.c
diff options
context:
space:
mode:
authorJean-Francois Moine <moinejf@free.fr>2008-09-03 15:47:51 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2008-09-03 17:36:44 -0400
commitd698dc6b0477d3165a7f320b3ce36d1cbd361c94 (patch)
treef4cc54f22c9cbc526fbf9592f15e32fb543e69c4 /drivers/media/video/gspca/spca561.c
parent0058717a1ef0c87deeccbe0a3b17def173fee9a9 (diff)
V4L/DVB (8703): gspca: Do controls work for spca561 revision 12a.
Signed-off-by: Jean-Francois Moine <moinejf@free.fr> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/gspca/spca561.c')
-rw-r--r--drivers/media/video/gspca/spca561.c73
1 files changed, 46 insertions, 27 deletions
diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c
index 0a2b8bc5b855..0a1e66201a65 100644
--- a/drivers/media/video/gspca/spca561.c
+++ b/drivers/media/video/gspca/spca561.c
@@ -38,9 +38,9 @@ struct sd {
38#define CONTRAST_MAX 0x3fff 38#define CONTRAST_MAX 0x3fff
39 39
40 __u16 exposure; /* rev12a only */ 40 __u16 exposure; /* rev12a only */
41#define EXPOSURE_MIN 0x0120 41#define EXPOSURE_MIN 0x2001
42#define EXPOSURE_DEF 0x20ae 42#define EXPOSURE_DEF 0x20ae
43#define EXPOSURE_MAX 0x5720 43#define EXPOSURE_MAX 0x421d
44 44
45 __u8 brightness; /* rev72a only */ 45 __u8 brightness; /* rev72a only */
46#define BRIGHTNESS_MIN 0 46#define BRIGHTNESS_MIN 0
@@ -62,6 +62,9 @@ struct sd {
62#define GAIN_DEF 0x24 62#define GAIN_DEF 0x24
63#define GAIN_MAX 0x24 63#define GAIN_MAX 0x24
64 64
65#define EXPO12A_DEF 3
66 __u8 expo12a; /* expo/gain? for rev 12a */
67
65 __u8 chip_revision; 68 __u8 chip_revision;
66#define Rev012A 0 69#define Rev012A 0
67#define Rev072A 1 70#define Rev072A 1
@@ -553,6 +556,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
553 sd->exposure = EXPOSURE_DEF; 556 sd->exposure = EXPOSURE_DEF;
554 sd->autogain = AUTOGAIN_DEF; 557 sd->autogain = AUTOGAIN_DEF;
555 sd->gain = GAIN_DEF; 558 sd->gain = GAIN_DEF;
559 sd->expo12a = EXPO12A_DEF;
556 return 0; 560 return 0;
557} 561}
558 562
@@ -609,12 +613,9 @@ static void setwhite(struct gspca_dev *gspca_dev)
609 return; 613 return;
610 } 614 }
611 /* try to emulate MS-win as possible */ 615 /* try to emulate MS-win as possible */
612 if (white < 0x45) 616 reg8616 = 0x90 - white * 5 / 8;
613 reg8616 = white;
614 else
615 reg8616 = 0x93 + (white >> 2);
616 reg8614 = 0x28 + (white >> 4);
617 reg_w_val(gspca_dev->dev, 0x8616, reg8616); 617 reg_w_val(gspca_dev->dev, 0x8616, reg8616);
618 reg8614 = 0x20 + white * 3 / 8;
618 reg_w_val(gspca_dev->dev, 0x8614, reg8614); 619 reg_w_val(gspca_dev->dev, 0x8614, reg8614);
619} 620}
620 621
@@ -622,30 +623,32 @@ static void setwhite(struct gspca_dev *gspca_dev)
622static void setexposure(struct gspca_dev *gspca_dev) 623static void setexposure(struct gspca_dev *gspca_dev)
623{ 624{
624 struct sd *sd = (struct sd *) gspca_dev; 625 struct sd *sd = (struct sd *) gspca_dev;
625 struct usb_device *dev = gspca_dev->dev; 626 __u8 data[2];
626 627
627 reg_w_val(dev, 0x8309, sd->gain); 628 data[0] = sd->exposure;
629 data[1] = sd->exposure >> 8;
630 reg_w_buf(gspca_dev, 0x8309, data, 2);
628} 631}
629 632
630/* rev 12a only */ 633/* rev 12a only */
631static void setgain(struct gspca_dev *gspca_dev) 634static void setgain(struct gspca_dev *gspca_dev)
632{ 635{
633 struct sd *sd = (struct sd *) gspca_dev; 636 struct sd *sd = (struct sd *) gspca_dev;
634 struct usb_device *dev = gspca_dev->dev; 637 __u8 data[2];
635 638
636 reg_w_val(dev, 0x8335, sd->gain); 639 data[0] = sd->gain;
640 data[1] = 0;
641 reg_w_buf(gspca_dev, 0x8335, data, 2);
637} 642}
638 643
639static void setautogain(struct gspca_dev *gspca_dev) 644static void setautogain(struct gspca_dev *gspca_dev)
640{ 645{
641 struct sd *sd = (struct sd *) gspca_dev; 646 struct sd *sd = (struct sd *) gspca_dev;
642 647
643 if (sd->chip_revision == Rev072A) { 648 if (sd->autogain)
644 if (sd->autogain) 649 sd->ag_cnt = AG_CNT_START;
645 sd->ag_cnt = AG_CNT_START; 650 else
646 else 651 sd->ag_cnt = -1;
647 sd->ag_cnt = -1;
648 }
649} 652}
650 653
651static void sd_start_12a(struct gspca_dev *gspca_dev) 654static void sd_start_12a(struct gspca_dev *gspca_dev)
@@ -684,6 +687,7 @@ static void sd_start_12a(struct gspca_dev *gspca_dev)
684 reg_w_val(gspca_dev->dev, 0x850b, 0x03); 687 reg_w_val(gspca_dev->dev, 0x850b, 0x03);
685 setcontrast(gspca_dev); 688 setcontrast(gspca_dev);
686 setwhite(gspca_dev); 689 setwhite(gspca_dev);
690 setautogain(gspca_dev);
687} 691}
688static void sd_start_72a(struct gspca_dev *gspca_dev) 692static void sd_start_72a(struct gspca_dev *gspca_dev)
689{ 693{
@@ -713,12 +717,24 @@ static void sd_start_72a(struct gspca_dev *gspca_dev)
713 717
714static void sd_stopN(struct gspca_dev *gspca_dev) 718static void sd_stopN(struct gspca_dev *gspca_dev)
715{ 719{
716 reg_w_val(gspca_dev->dev, 0x8112, 0x20); 720 struct sd *sd = (struct sd *) gspca_dev;
717 reg_w_val(gspca_dev->dev, 0x8102, 0x00); /* white balance - new */ 721
722 if (sd->chip_revision == Rev012A) {
723 reg_w_val(gspca_dev->dev, 0x8112, 0x0e);
724 } else {
725 reg_w_val(gspca_dev->dev, 0x8112, 0x20);
726/* reg_w_val(gspca_dev->dev, 0x8102, 0x00); ?? */
727 }
718} 728}
719 729
720static void sd_stop0(struct gspca_dev *gspca_dev) 730static void sd_stop0(struct gspca_dev *gspca_dev)
721{ 731{
732 struct sd *sd = (struct sd *) gspca_dev;
733
734 if (sd->chip_revision == Rev012A) {
735 reg_w_val(gspca_dev->dev, 0x8118, 0x29);
736 reg_w_val(gspca_dev->dev, 0x8114, 0x08);
737 }
722} 738}
723 739
724/* this function is called at close time */ 740/* this function is called at close time */
@@ -727,7 +743,6 @@ static void sd_close(struct gspca_dev *gspca_dev)
727 reg_w_val(gspca_dev->dev, 0x8114, 0); 743 reg_w_val(gspca_dev->dev, 0x8114, 0);
728} 744}
729 745
730/* rev72a only */
731static void do_autogain(struct gspca_dev *gspca_dev) 746static void do_autogain(struct gspca_dev *gspca_dev)
732{ 747{
733 struct sd *sd = (struct sd *) gspca_dev; 748 struct sd *sd = (struct sd *) gspca_dev;
@@ -739,6 +754,7 @@ static void do_autogain(struct gspca_dev *gspca_dev)
739 __u8 luma_mean = 110; 754 __u8 luma_mean = 110;
740 __u8 luma_delta = 20; 755 __u8 luma_delta = 20;
741 __u8 spring = 4; 756 __u8 spring = 4;
757 __u8 reg8339[2];
742 758
743 if (sd->ag_cnt < 0) 759 if (sd->ag_cnt < 0)
744 return; 760 return;
@@ -793,13 +809,16 @@ static void do_autogain(struct gspca_dev *gspca_dev)
793 } 809 }
794 break; 810 break;
795 case Rev012A: 811 case Rev012A:
796 /* sensor registers is access and memory mapped to 0x8300 */ 812 reg_r(gspca_dev, 0x8330, 2);
797 /* readind all 0x83xx block the sensor */ 813 if (gspca_dev->usb_buf[1] > 0x08) {
798 /* 814 reg8339[0] = ++sd->expo12a;
799 * The data from the header seem wrong where is the luma 815 reg8339[1] = 0;
800 * and chroma mean value 816 reg_w_buf(gspca_dev, 0x8339, reg8339, 2);
801 * at the moment set exposure in contrast set 817 } else if (gspca_dev->usb_buf[1] < 0x02) {
802 */ 818 reg8339[0] = --sd->expo12a;
819 reg8339[1] = 0;
820 reg_w_buf(gspca_dev, 0x8339, reg8339, 2);
821 }
803 break; 822 break;
804 } 823 }
805} 824}