aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2012-05-15 03:23:55 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-07-30 17:17:56 -0400
commit9153ac3ba4bccfdccb43e765cf1cf9bd9e65e657 (patch)
treea86e648eccf3c6ed9f06fd9d9727ade85345f4b4 /drivers/media/video/gspca
parent4848ea77e0e8131fe928a11e15dc2d5c47862bb5 (diff)
[media] gscpa_sonixb: Convert to the control framework
Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/gspca')
-rw-r--r--drivers/media/video/gspca/sonixb.c454
1 files changed, 200 insertions, 254 deletions
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c
index 65fa4f2fb0b2..1bfe5f8947b7 100644
--- a/drivers/media/video/gspca/sonixb.c
+++ b/drivers/media/video/gspca/sonixb.c
@@ -56,26 +56,16 @@ MODULE_AUTHOR("Jean-François Moine <http://moinejf.free.fr>");
56MODULE_DESCRIPTION("GSPCA/SN9C102 USB Camera Driver"); 56MODULE_DESCRIPTION("GSPCA/SN9C102 USB Camera Driver");
57MODULE_LICENSE("GPL"); 57MODULE_LICENSE("GPL");
58 58
59/* controls */
60enum e_ctrl {
61 BRIGHTNESS,
62 GAIN,
63 EXPOSURE,
64 AUTOGAIN,
65 FREQ,
66 NCTRLS /* number of controls */
67};
68
69/* specific webcam descriptor */ 59/* specific webcam descriptor */
70struct sd { 60struct sd {
71 struct gspca_dev gspca_dev; /* !! must be the first item */ 61 struct gspca_dev gspca_dev; /* !! must be the first item */
72 62
73 struct gspca_ctrl ctrls[NCTRLS]; 63 struct v4l2_ctrl *brightness;
64 struct v4l2_ctrl *plfreq;
74 65
75 atomic_t avg_lum; 66 atomic_t avg_lum;
76 int prev_avg_lum; 67 int prev_avg_lum;
77 int exp_too_low_cnt; 68 int exposure_knee;
78 int exp_too_high_cnt;
79 int header_read; 69 int header_read;
80 u8 header[12]; /* Header without sof marker */ 70 u8 header[12]; /* Header without sof marker */
81 71
@@ -107,24 +97,16 @@ struct sensor_data {
107 sensor_init_t *sensor_init; 97 sensor_init_t *sensor_init;
108 int sensor_init_size; 98 int sensor_init_size;
109 int flags; 99 int flags;
110 unsigned ctrl_dis;
111 __u8 sensor_addr; 100 __u8 sensor_addr;
112}; 101};
113 102
114/* sensor_data flags */ 103/* sensor_data flags */
115#define F_GAIN 0x01 /* has gain */ 104#define F_SIF 0x01 /* sif or vga */
116#define F_SIF 0x02 /* sif or vga */
117#define F_COARSE_EXPO 0x04 /* exposure control is coarse */
118 105
119/* priv field of struct v4l2_pix_format flags (do not use low nibble!) */ 106/* priv field of struct v4l2_pix_format flags (do not use low nibble!) */
120#define MODE_RAW 0x10 /* raw bayer mode */ 107#define MODE_RAW 0x10 /* raw bayer mode */
121#define MODE_REDUCED_SIF 0x20 /* vga mode (320x240 / 160x120) on sif cam */ 108#define MODE_REDUCED_SIF 0x20 /* vga mode (320x240 / 160x120) on sif cam */
122 109
123/* ctrl_dis helper macros */
124#define NO_EXPO ((1 << EXPOSURE) | (1 << AUTOGAIN))
125#define NO_FREQ (1 << FREQ)
126#define NO_BRIGHTNESS (1 << BRIGHTNESS)
127
128#define COMP 0xc7 /* 0x87 //0x07 */ 110#define COMP 0xc7 /* 0x87 //0x07 */
129#define COMP1 0xc9 /* 0x89 //0x09 */ 111#define COMP1 0xc9 /* 0x89 //0x09 */
130 112
@@ -133,12 +115,12 @@ struct sensor_data {
133 115
134#define SYS_CLK 0x04 116#define SYS_CLK 0x04
135 117
136#define SENS(bridge, sensor, _flags, _ctrl_dis, _sensor_addr) \ 118#define SENS(bridge, sensor, _flags, _sensor_addr) \
137{ \ 119{ \
138 .bridge_init = bridge, \ 120 .bridge_init = bridge, \
139 .sensor_init = sensor, \ 121 .sensor_init = sensor, \
140 .sensor_init_size = sizeof(sensor), \ 122 .sensor_init_size = sizeof(sensor), \
141 .flags = _flags, .ctrl_dis = _ctrl_dis, .sensor_addr = _sensor_addr \ 123 .flags = _flags, .sensor_addr = _sensor_addr \
142} 124}
143 125
144/* We calculate the autogain at the end of the transfer of a frame, at this 126/* We calculate the autogain at the end of the transfer of a frame, at this
@@ -147,87 +129,6 @@ struct sensor_data {
147 the new settings to come into effect before doing any other adjustments. */ 129 the new settings to come into effect before doing any other adjustments. */
148#define AUTOGAIN_IGNORE_FRAMES 1 130#define AUTOGAIN_IGNORE_FRAMES 1
149 131
150/* V4L2 controls supported by the driver */
151static void setbrightness(struct gspca_dev *gspca_dev);
152static void setgain(struct gspca_dev *gspca_dev);
153static void setexposure(struct gspca_dev *gspca_dev);
154static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
155static void setfreq(struct gspca_dev *gspca_dev);
156
157static const struct ctrl sd_ctrls[NCTRLS] = {
158[BRIGHTNESS] = {
159 {
160 .id = V4L2_CID_BRIGHTNESS,
161 .type = V4L2_CTRL_TYPE_INTEGER,
162 .name = "Brightness",
163 .minimum = 0,
164 .maximum = 255,
165 .step = 1,
166 .default_value = 127,
167 },
168 .set_control = setbrightness
169 },
170[GAIN] = {
171 {
172 .id = V4L2_CID_GAIN,
173 .type = V4L2_CTRL_TYPE_INTEGER,
174 .name = "Gain",
175 .minimum = 0,
176 .maximum = 255,
177 .step = 1,
178#define GAIN_KNEE 230
179 .default_value = 127,
180 },
181 .set_control = setgain
182 },
183[EXPOSURE] = {
184 {
185 .id = V4L2_CID_EXPOSURE,
186 .type = V4L2_CTRL_TYPE_INTEGER,
187 .name = "Exposure",
188 .minimum = 0,
189 .maximum = 1023,
190 .step = 1,
191 .default_value = 66,
192 /* 33 ms / 30 fps (except on PASXXX) */
193#define EXPOSURE_KNEE 200 /* 100 ms / 10 fps (except on PASXXX) */
194 .flags = 0,
195 },
196 .set_control = setexposure
197 },
198/* for coarse exposure */
199#define COARSE_EXPOSURE_MIN 2
200#define COARSE_EXPOSURE_MAX 15
201#define COARSE_EXPOSURE_DEF 2 /* 30 fps */
202[AUTOGAIN] = {
203 {
204 .id = V4L2_CID_AUTOGAIN,
205 .type = V4L2_CTRL_TYPE_BOOLEAN,
206 .name = "Automatic Gain (and Exposure)",
207 .minimum = 0,
208 .maximum = 1,
209 .step = 1,
210#define AUTOGAIN_DEF 1
211 .default_value = AUTOGAIN_DEF,
212 .flags = V4L2_CTRL_FLAG_UPDATE
213 },
214 .set = sd_setautogain,
215 },
216[FREQ] = {
217 {
218 .id = V4L2_CID_POWER_LINE_FREQUENCY,
219 .type = V4L2_CTRL_TYPE_MENU,
220 .name = "Light frequency filter",
221 .minimum = 0,
222 .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
223 .step = 1,
224#define FREQ_DEF 0
225 .default_value = FREQ_DEF,
226 },
227 .set_control = setfreq
228 },
229};
230
231static const struct v4l2_pix_format vga_mode[] = { 132static const struct v4l2_pix_format vga_mode[] = {
232 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 133 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
233 .bytesperline = 160, 134 .bytesperline = 160,
@@ -532,18 +433,15 @@ static const __u8 tas5130_sensor_init[][8] = {
532}; 433};
533 434
534static const struct sensor_data sensor_data[] = { 435static const struct sensor_data sensor_data[] = {
535SENS(initHv7131d, hv7131d_sensor_init, F_GAIN, NO_BRIGHTNESS|NO_FREQ, 0), 436 SENS(initHv7131d, hv7131d_sensor_init, 0, 0),
536SENS(initHv7131r, hv7131r_sensor_init, 0, NO_BRIGHTNESS|NO_EXPO|NO_FREQ, 0), 437 SENS(initHv7131r, hv7131r_sensor_init, 0, 0),
537SENS(initOv6650, ov6650_sensor_init, F_GAIN|F_SIF, 0, 0x60), 438 SENS(initOv6650, ov6650_sensor_init, F_SIF, 0x60),
538SENS(initOv7630, ov7630_sensor_init, F_GAIN, 0, 0x21), 439 SENS(initOv7630, ov7630_sensor_init, 0, 0x21),
539SENS(initPas106, pas106_sensor_init, F_GAIN|F_SIF, NO_FREQ, 0), 440 SENS(initPas106, pas106_sensor_init, F_SIF, 0),
540SENS(initPas202, pas202_sensor_init, F_GAIN, NO_FREQ, 0), 441 SENS(initPas202, pas202_sensor_init, 0, 0),
541SENS(initTas5110c, tas5110c_sensor_init, F_GAIN|F_SIF|F_COARSE_EXPO, 442 SENS(initTas5110c, tas5110c_sensor_init, F_SIF, 0),
542 NO_BRIGHTNESS|NO_FREQ, 0), 443 SENS(initTas5110d, tas5110d_sensor_init, F_SIF, 0),
543SENS(initTas5110d, tas5110d_sensor_init, F_GAIN|F_SIF|F_COARSE_EXPO, 444 SENS(initTas5130, tas5130_sensor_init, 0, 0),
544 NO_BRIGHTNESS|NO_FREQ, 0),
545SENS(initTas5130, tas5130_sensor_init, F_GAIN,
546 NO_BRIGHTNESS|NO_EXPO|NO_FREQ, 0),
547}; 445};
548 446
549/* get one byte in gspca_dev->usb_buf */ 447/* get one byte in gspca_dev->usb_buf */
@@ -652,7 +550,7 @@ static void setbrightness(struct gspca_dev *gspca_dev)
652 550
653 /* change reg 0x06 */ 551 /* change reg 0x06 */
654 i2cOV[1] = sensor_data[sd->sensor].sensor_addr; 552 i2cOV[1] = sensor_data[sd->sensor].sensor_addr;
655 i2cOV[3] = sd->ctrls[BRIGHTNESS].val; 553 i2cOV[3] = sd->brightness->val;
656 i2c_w(gspca_dev, i2cOV); 554 i2c_w(gspca_dev, i2cOV);
657 break; 555 break;
658 } 556 }
@@ -669,13 +567,13 @@ static void setbrightness(struct gspca_dev *gspca_dev)
669 i2cpdoit[2] = 0x13; 567 i2cpdoit[2] = 0x13;
670 } 568 }
671 569
672 if (sd->ctrls[BRIGHTNESS].val < 127) { 570 if (sd->brightness->val < 127) {
673 /* change reg 0x0b, signreg */ 571 /* change reg 0x0b, signreg */
674 i2cpbright[3] = 0x01; 572 i2cpbright[3] = 0x01;
675 /* set reg 0x0c, offset */ 573 /* set reg 0x0c, offset */
676 i2cpbright[4] = 127 - sd->ctrls[BRIGHTNESS].val; 574 i2cpbright[4] = 127 - sd->brightness->val;
677 } else 575 } else
678 i2cpbright[4] = sd->ctrls[BRIGHTNESS].val - 127; 576 i2cpbright[4] = sd->brightness->val - 127;
679 577
680 i2c_w(gspca_dev, i2cpbright); 578 i2c_w(gspca_dev, i2cpbright);
681 i2c_w(gspca_dev, i2cpdoit); 579 i2c_w(gspca_dev, i2cpdoit);
@@ -686,19 +584,19 @@ static void setbrightness(struct gspca_dev *gspca_dev)
686 } 584 }
687} 585}
688 586
689static void setsensorgain(struct gspca_dev *gspca_dev) 587static void setgain(struct gspca_dev *gspca_dev)
690{ 588{
691 struct sd *sd = (struct sd *) gspca_dev; 589 struct sd *sd = (struct sd *) gspca_dev;
692 u8 gain = sd->ctrls[GAIN].val; 590 u8 gain = gspca_dev->gain->val;
693 591
694 switch (sd->sensor) { 592 switch (sd->sensor) {
695 case SENSOR_HV7131D: { 593 case SENSOR_HV7131D: {
696 __u8 i2c[] = 594 __u8 i2c[] =
697 {0xc0, 0x11, 0x31, 0x00, 0x00, 0x00, 0x00, 0x17}; 595 {0xc0, 0x11, 0x31, 0x00, 0x00, 0x00, 0x00, 0x17};
698 596
699 i2c[3] = 0x3f - (gain / 4); 597 i2c[3] = 0x3f - gain;
700 i2c[4] = 0x3f - (gain / 4); 598 i2c[4] = 0x3f - gain;
701 i2c[5] = 0x3f - (gain / 4); 599 i2c[5] = 0x3f - gain;
702 600
703 i2c_w(gspca_dev, i2c); 601 i2c_w(gspca_dev, i2c);
704 break; 602 break;
@@ -729,13 +627,11 @@ static void setsensorgain(struct gspca_dev *gspca_dev)
729 break; 627 break;
730 } 628 }
731 case SENSOR_OV6650: 629 case SENSOR_OV6650:
732 gain >>= 1;
733 /* fall thru */
734 case SENSOR_OV7630: { 630 case SENSOR_OV7630: {
735 __u8 i2c[] = {0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}; 631 __u8 i2c[] = {0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
736 632
737 i2c[1] = sensor_data[sd->sensor].sensor_addr; 633 i2c[1] = sensor_data[sd->sensor].sensor_addr;
738 i2c[3] = gain >> 2; 634 i2c[3] = gain;
739 i2c_w(gspca_dev, i2c); 635 i2c_w(gspca_dev, i2c);
740 break; 636 break;
741 } 637 }
@@ -756,11 +652,11 @@ static void setsensorgain(struct gspca_dev *gspca_dev)
756 i2cpdoit[2] = 0x13; 652 i2cpdoit[2] = 0x13;
757 } 653 }
758 654
759 i2cpgain[3] = gain >> 3; 655 i2cpgain[3] = gain;
760 i2cpcolorgain[3] = gain >> 4; 656 i2cpcolorgain[3] = gain >> 1;
761 i2cpcolorgain[4] = gain >> 4; 657 i2cpcolorgain[4] = gain >> 1;
762 i2cpcolorgain[5] = gain >> 4; 658 i2cpcolorgain[5] = gain >> 1;
763 i2cpcolorgain[6] = gain >> 4; 659 i2cpcolorgain[6] = gain >> 1;
764 660
765 i2c_w(gspca_dev, i2cpgain); 661 i2c_w(gspca_dev, i2cpgain);
766 i2c_w(gspca_dev, i2cpcolorgain); 662 i2c_w(gspca_dev, i2cpcolorgain);
@@ -768,33 +664,15 @@ static void setsensorgain(struct gspca_dev *gspca_dev)
768 break; 664 break;
769 } 665 }
770 default: 666 default:
771 break; 667 if (sd->bridge == BRIDGE_103) {
772 } 668 u8 buf[3] = { gain, gain, gain }; /* R, G, B */
773} 669 reg_w(gspca_dev, 0x05, buf, 3);
774 670 } else {
775static void setgain(struct gspca_dev *gspca_dev) 671 u8 buf[2];
776{ 672 buf[0] = gain << 4 | gain; /* Red and blue */
777 struct sd *sd = (struct sd *) gspca_dev; 673 buf[1] = gain; /* Green */
778 __u8 gain; 674 reg_w(gspca_dev, 0x10, buf, 2);
779 __u8 buf[3] = { 0, 0, 0 }; 675 }
780
781 if (sensor_data[sd->sensor].flags & F_GAIN) {
782 /* Use the sensor gain to do the actual gain */
783 setsensorgain(gspca_dev);
784 return;
785 }
786
787 if (sd->bridge == BRIDGE_103) {
788 gain = sd->ctrls[GAIN].val >> 1;
789 buf[0] = gain; /* Red */
790 buf[1] = gain; /* Green */
791 buf[2] = gain; /* Blue */
792 reg_w(gspca_dev, 0x05, buf, 3);
793 } else {
794 gain = sd->ctrls[GAIN].val >> 4;
795 buf[0] = gain << 4 | gain; /* Red and blue */
796 buf[1] = gain; /* Green */
797 reg_w(gspca_dev, 0x10, buf, 2);
798 } 676 }
799} 677}
800 678
@@ -807,13 +685,7 @@ static void setexposure(struct gspca_dev *gspca_dev)
807 /* Note the datasheet wrongly says line mode exposure uses reg 685 /* Note the datasheet wrongly says line mode exposure uses reg
808 0x26 and 0x27, testing has shown 0x25 + 0x26 */ 686 0x26 and 0x27, testing has shown 0x25 + 0x26 */
809 __u8 i2c[] = {0xc0, 0x11, 0x25, 0x00, 0x00, 0x00, 0x00, 0x17}; 687 __u8 i2c[] = {0xc0, 0x11, 0x25, 0x00, 0x00, 0x00, 0x00, 0x17};
810 /* The HV7131D's exposure goes from 0 - 65535, we scale our 688 u16 reg = gspca_dev->exposure->val;
811 exposure of 0-1023 to 0-6138. There are 2 reasons for this:
812 1) This puts our exposure knee of 200 at approx the point
813 where the framerate starts dropping
814 2) At 6138 the framerate has already dropped to 2 fps,
815 going any lower makes little sense */
816 u16 reg = sd->ctrls[EXPOSURE].val * 6;
817 689
818 i2c[3] = reg >> 8; 690 i2c[3] = reg >> 8;
819 i2c[4] = reg & 0xff; 691 i2c[4] = reg & 0xff;
@@ -825,7 +697,7 @@ static void setexposure(struct gspca_dev *gspca_dev)
825 /* register 19's high nibble contains the sn9c10x clock divider 697 /* register 19's high nibble contains the sn9c10x clock divider
826 The high nibble configures the no fps according to the 698 The high nibble configures the no fps according to the
827 formula: 60 / high_nibble. With a maximum of 30 fps */ 699 formula: 60 / high_nibble. With a maximum of 30 fps */
828 u8 reg = sd->ctrls[EXPOSURE].val; 700 u8 reg = gspca_dev->exposure->val;
829 701
830 reg = (reg << 4) | 0x0b; 702 reg = (reg << 4) | 0x0b;
831 reg_w(gspca_dev, 0x19, &reg, 1); 703 reg_w(gspca_dev, 0x19, &reg, 1);
@@ -862,7 +734,7 @@ static void setexposure(struct gspca_dev *gspca_dev)
862 } else 734 } else
863 reg10_max = 0x41; 735 reg10_max = 0x41;
864 736
865 reg11 = (15 * sd->ctrls[EXPOSURE].val + 999) / 1000; 737 reg11 = (15 * gspca_dev->exposure->val + 999) / 1000;
866 if (reg11 < 1) 738 if (reg11 < 1)
867 reg11 = 1; 739 reg11 = 1;
868 else if (reg11 > 16) 740 else if (reg11 > 16)
@@ -875,16 +747,16 @@ static void setexposure(struct gspca_dev *gspca_dev)
875 reg11 = 4; 747 reg11 = 4;
876 748
877 /* frame exposure time in ms = 1000 * reg11 / 30 -> 749 /* frame exposure time in ms = 1000 * reg11 / 30 ->
878 reg10 = (sd->ctrls[EXPOSURE].val / 2) * reg10_max 750 reg10 = (gspca_dev->exposure->val / 2) * reg10_max
879 / (1000 * reg11 / 30) */ 751 / (1000 * reg11 / 30) */
880 reg10 = (sd->ctrls[EXPOSURE].val * 15 * reg10_max) 752 reg10 = (gspca_dev->exposure->val * 15 * reg10_max)
881 / (1000 * reg11); 753 / (1000 * reg11);
882 754
883 /* Don't allow this to get below 10 when using autogain, the 755 /* Don't allow this to get below 10 when using autogain, the
884 steps become very large (relatively) when below 10 causing 756 steps become very large (relatively) when below 10 causing
885 the image to oscilate from much too dark, to much too bright 757 the image to oscilate from much too dark, to much too bright
886 and back again. */ 758 and back again. */
887 if (sd->ctrls[AUTOGAIN].val && reg10 < 10) 759 if (gspca_dev->autogain->val && reg10 < 10)
888 reg10 = 10; 760 reg10 = 10;
889 else if (reg10 > reg10_max) 761 else if (reg10 > reg10_max)
890 reg10 = reg10_max; 762 reg10 = reg10_max;
@@ -922,15 +794,15 @@ static void setexposure(struct gspca_dev *gspca_dev)
922 frame exposure times (like we are doing with the ov chips), 794 frame exposure times (like we are doing with the ov chips),
923 as that sometimes leads to jumps in the exposure control, 795 as that sometimes leads to jumps in the exposure control,
924 which are bad for auto exposure. */ 796 which are bad for auto exposure. */
925 if (sd->ctrls[EXPOSURE].val < 200) { 797 if (gspca_dev->exposure->val < 200) {
926 i2cpexpo[3] = 255 - (sd->ctrls[EXPOSURE].val * 255) 798 i2cpexpo[3] = 255 - (gspca_dev->exposure->val * 255)
927 / 200; 799 / 200;
928 framerate_ctrl = 500; 800 framerate_ctrl = 500;
929 } else { 801 } else {
930 /* The PAS202's exposure control goes from 0 - 4095, 802 /* The PAS202's exposure control goes from 0 - 4095,
931 but anything below 500 causes vsync issues, so scale 803 but anything below 500 causes vsync issues, so scale
932 our 200-1023 to 500-4095 */ 804 our 200-1023 to 500-4095 */
933 framerate_ctrl = (sd->ctrls[EXPOSURE].val - 200) 805 framerate_ctrl = (gspca_dev->exposure->val - 200)
934 * 1000 / 229 + 500; 806 * 1000 / 229 + 500;
935 } 807 }
936 808
@@ -952,14 +824,14 @@ static void setexposure(struct gspca_dev *gspca_dev)
952 824
953 /* For values below 150 use partial frame exposure, above 825 /* For values below 150 use partial frame exposure, above
954 that use framerate ctrl */ 826 that use framerate ctrl */
955 if (sd->ctrls[EXPOSURE].val < 150) { 827 if (gspca_dev->exposure->val < 150) {
956 i2cpexpo[3] = 150 - sd->ctrls[EXPOSURE].val; 828 i2cpexpo[3] = 150 - gspca_dev->exposure->val;
957 framerate_ctrl = 300; 829 framerate_ctrl = 300;
958 } else { 830 } else {
959 /* The PAS106's exposure control goes from 0 - 4095, 831 /* The PAS106's exposure control goes from 0 - 4095,
960 but anything below 300 causes vsync issues, so scale 832 but anything below 300 causes vsync issues, so scale
961 our 150-1023 to 300-4095 */ 833 our 150-1023 to 300-4095 */
962 framerate_ctrl = (sd->ctrls[EXPOSURE].val - 150) 834 framerate_ctrl = (gspca_dev->exposure->val - 150)
963 * 1000 / 230 + 300; 835 * 1000 / 230 + 300;
964 } 836 }
965 837
@@ -985,7 +857,7 @@ static void setfreq(struct gspca_dev *gspca_dev)
985 0x2b register, see ov6630 datasheet. 857 0x2b register, see ov6630 datasheet.
986 0x4f / 0x8a -> (30 fps -> 25 fps), 0x00 -> no adjustment */ 858 0x4f / 0x8a -> (30 fps -> 25 fps), 0x00 -> no adjustment */
987 __u8 i2c[] = {0xa0, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}; 859 __u8 i2c[] = {0xa0, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10};
988 switch (sd->ctrls[FREQ].val) { 860 switch (sd->plfreq->val) {
989 default: 861 default:
990/* case 0: * no filter*/ 862/* case 0: * no filter*/
991/* case 2: * 60 hz */ 863/* case 2: * 60 hz */
@@ -1001,18 +873,13 @@ static void setfreq(struct gspca_dev *gspca_dev)
1001 } 873 }
1002} 874}
1003 875
1004#define WANT_REGULAR_AUTOGAIN
1005#define WANT_COARSE_EXPO_AUTOGAIN
1006#include "autogain_functions.h"
1007
1008static void do_autogain(struct gspca_dev *gspca_dev) 876static void do_autogain(struct gspca_dev *gspca_dev)
1009{ 877{
1010 int deadzone, desired_avg_lum, result;
1011 struct sd *sd = (struct sd *) gspca_dev; 878 struct sd *sd = (struct sd *) gspca_dev;
1012 int avg_lum = atomic_read(&sd->avg_lum); 879 int deadzone, desired_avg_lum, avg_lum;
1013 880
1014 if ((gspca_dev->ctrl_dis & (1 << AUTOGAIN)) || 881 avg_lum = atomic_read(&sd->avg_lum);
1015 avg_lum == -1 || !sd->ctrls[AUTOGAIN].val) 882 if (avg_lum == -1)
1016 return; 883 return;
1017 884
1018 if (sd->autogain_ignore_frames > 0) { 885 if (sd->autogain_ignore_frames > 0) {
@@ -1031,22 +898,18 @@ static void do_autogain(struct gspca_dev *gspca_dev)
1031 desired_avg_lum = 13000; 898 desired_avg_lum = 13000;
1032 } 899 }
1033 900
1034 if (sensor_data[sd->sensor].flags & F_COARSE_EXPO) 901 if (sd->brightness)
1035 result = coarse_grained_expo_autogain(gspca_dev, avg_lum, 902 desired_avg_lum = sd->brightness->val * desired_avg_lum / 127;
1036 sd->ctrls[BRIGHTNESS].val 903
1037 * desired_avg_lum / 127, 904 if (gspca_dev->exposure->maximum < 500) {
1038 deadzone); 905 if (gspca_coarse_grained_expo_autogain(gspca_dev, avg_lum,
1039 else 906 desired_avg_lum, deadzone))
1040 result = auto_gain_n_exposure(gspca_dev, avg_lum, 907 sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
1041 sd->ctrls[BRIGHTNESS].val 908 } else {
1042 * desired_avg_lum / 127, 909 int gain_knee = gspca_dev->gain->maximum * 9 / 10;
1043 deadzone, GAIN_KNEE, EXPOSURE_KNEE); 910 if (gspca_expo_autogain(gspca_dev, avg_lum, desired_avg_lum,
1044 911 deadzone, gain_knee, sd->exposure_knee))
1045 if (result) { 912 sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
1046 PDEBUG(D_FRAM, "autogain: gain changed: gain: %d expo: %d",
1047 (int) sd->ctrls[GAIN].val,
1048 (int) sd->ctrls[EXPOSURE].val);
1049 sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
1050 } 913 }
1051} 914}
1052 915
@@ -1065,14 +928,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
1065 sd->sensor = id->driver_info >> 8; 928 sd->sensor = id->driver_info >> 8;
1066 sd->bridge = id->driver_info & 0xff; 929 sd->bridge = id->driver_info & 0xff;
1067 930
1068 gspca_dev->ctrl_dis = sensor_data[sd->sensor].ctrl_dis;
1069#if AUTOGAIN_DEF
1070 if (!(gspca_dev->ctrl_dis & (1 << AUTOGAIN)))
1071 gspca_dev->ctrl_inac = (1 << GAIN) | (1 << EXPOSURE);
1072#endif
1073
1074 cam = &gspca_dev->cam; 931 cam = &gspca_dev->cam;
1075 cam->ctrls = sd->ctrls;
1076 if (!(sensor_data[sd->sensor].flags & F_SIF)) { 932 if (!(sensor_data[sd->sensor].flags & F_SIF)) {
1077 cam->cam_mode = vga_mode; 933 cam->cam_mode = vga_mode;
1078 cam->nmodes = ARRAY_SIZE(vga_mode); 934 cam->nmodes = ARRAY_SIZE(vga_mode);
@@ -1088,22 +944,144 @@ static int sd_config(struct gspca_dev *gspca_dev,
1088/* this function is called at probe and resume time */ 944/* this function is called at probe and resume time */
1089static int sd_init(struct gspca_dev *gspca_dev) 945static int sd_init(struct gspca_dev *gspca_dev)
1090{ 946{
1091 struct sd *sd = (struct sd *) gspca_dev;
1092 const __u8 stop = 0x09; /* Disable stream turn of LED */ 947 const __u8 stop = 0x09; /* Disable stream turn of LED */
1093 948
1094 if (sensor_data[sd->sensor].flags & F_COARSE_EXPO) { 949 reg_w(gspca_dev, 0x01, &stop, 1);
1095 sd->ctrls[EXPOSURE].min = COARSE_EXPOSURE_MIN; 950
1096 sd->ctrls[EXPOSURE].max = COARSE_EXPOSURE_MAX; 951 return gspca_dev->usb_err;
1097 sd->ctrls[EXPOSURE].def = COARSE_EXPOSURE_DEF; 952}
1098 if (sd->ctrls[EXPOSURE].val > COARSE_EXPOSURE_MAX) 953
1099 sd->ctrls[EXPOSURE].val = COARSE_EXPOSURE_DEF; 954static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
955{
956 struct gspca_dev *gspca_dev =
957 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
958 struct sd *sd = (struct sd *)gspca_dev;
959
960 gspca_dev->usb_err = 0;
961
962 if (ctrl->id == V4L2_CID_AUTOGAIN && ctrl->is_new && ctrl->val) {
963 /* when switching to autogain set defaults to make sure
964 we are on a valid point of the autogain gain /
965 exposure knee graph, and give this change time to
966 take effect before doing autogain. */
967 gspca_dev->gain->val = gspca_dev->gain->default_value;
968 gspca_dev->exposure->val = gspca_dev->exposure->default_value;
969 sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
1100 } 970 }
1101 971
1102 reg_w(gspca_dev, 0x01, &stop, 1); 972 if (!gspca_dev->streaming)
973 return 0;
1103 974
975 switch (ctrl->id) {
976 case V4L2_CID_BRIGHTNESS:
977 setbrightness(gspca_dev);
978 break;
979 case V4L2_CID_AUTOGAIN:
980 if (gspca_dev->exposure->is_new || (ctrl->is_new && ctrl->val))
981 setexposure(gspca_dev);
982 if (gspca_dev->gain->is_new || (ctrl->is_new && ctrl->val))
983 setgain(gspca_dev);
984 break;
985 case V4L2_CID_POWER_LINE_FREQUENCY:
986 setfreq(gspca_dev);
987 break;
988 default:
989 return -EINVAL;
990 }
1104 return gspca_dev->usb_err; 991 return gspca_dev->usb_err;
1105} 992}
1106 993
994static const struct v4l2_ctrl_ops sd_ctrl_ops = {
995 .s_ctrl = sd_s_ctrl,
996};
997
998/* this function is called at probe time */
999static int sd_init_controls(struct gspca_dev *gspca_dev)
1000{
1001 struct sd *sd = (struct sd *) gspca_dev;
1002 struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
1003
1004 gspca_dev->vdev.ctrl_handler = hdl;
1005 v4l2_ctrl_handler_init(hdl, 5);
1006
1007 if (sd->sensor == SENSOR_OV6650 || sd->sensor == SENSOR_OV7630 ||
1008 sd->sensor == SENSOR_PAS106 || sd->sensor == SENSOR_PAS202)
1009 sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1010 V4L2_CID_BRIGHTNESS, 0, 255, 1, 127);
1011
1012 /* Gain range is sensor dependent */
1013 switch (sd->sensor) {
1014 case SENSOR_OV6650:
1015 case SENSOR_PAS106:
1016 case SENSOR_PAS202:
1017 gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1018 V4L2_CID_GAIN, 0, 31, 1, 15);
1019 break;
1020 case SENSOR_HV7131D:
1021 case SENSOR_OV7630:
1022 gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1023 V4L2_CID_GAIN, 0, 63, 1, 31);
1024 break;
1025 case SENSOR_TAS5110C:
1026 case SENSOR_TAS5110D:
1027 case SENSOR_TAS5130CXX:
1028 gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1029 V4L2_CID_GAIN, 0, 255, 1, 127);
1030 break;
1031 default:
1032 if (sd->bridge == BRIDGE_103) {
1033 gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1034 V4L2_CID_GAIN, 0, 127, 1, 63);
1035 } else {
1036 gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1037 V4L2_CID_GAIN, 0, 15, 1, 7);
1038 }
1039 }
1040
1041 /* Exposure range is sensor dependent, and not all have exposure */
1042 switch (sd->sensor) {
1043 case SENSOR_HV7131D:
1044 gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1045 V4L2_CID_EXPOSURE, 0, 8191, 1, 482);
1046 sd->exposure_knee = 964;
1047 break;
1048 case SENSOR_OV6650:
1049 case SENSOR_OV7630:
1050 case SENSOR_PAS106:
1051 case SENSOR_PAS202:
1052 gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1053 V4L2_CID_EXPOSURE, 0, 1023, 1, 66);
1054 sd->exposure_knee = 200;
1055 break;
1056 case SENSOR_TAS5110C:
1057 case SENSOR_TAS5110D:
1058 gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1059 V4L2_CID_EXPOSURE, 2, 15, 1, 2);
1060 break;
1061 }
1062
1063 if (gspca_dev->exposure) {
1064 gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1065 V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
1066 }
1067
1068 if (sd->sensor == SENSOR_OV6650 || sd->sensor == SENSOR_OV7630)
1069 sd->plfreq = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops,
1070 V4L2_CID_POWER_LINE_FREQUENCY,
1071 V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0,
1072 V4L2_CID_POWER_LINE_FREQUENCY_DISABLED);
1073
1074 if (hdl->error) {
1075 pr_err("Could not initialize controls\n");
1076 return hdl->error;
1077 }
1078
1079 if (gspca_dev->autogain)
1080 v4l2_ctrl_auto_cluster(3, &gspca_dev->autogain, 0, false);
1081
1082 return 0;
1083}
1084
1107/* -- start the camera -- */ 1085/* -- start the camera -- */
1108static int sd_start(struct gspca_dev *gspca_dev) 1086static int sd_start(struct gspca_dev *gspca_dev)
1109{ 1087{
@@ -1243,8 +1221,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
1243 1221
1244 sd->frames_to_drop = 0; 1222 sd->frames_to_drop = 0;
1245 sd->autogain_ignore_frames = 0; 1223 sd->autogain_ignore_frames = 0;
1246 sd->exp_too_high_cnt = 0; 1224 gspca_dev->exp_too_high_cnt = 0;
1247 sd->exp_too_low_cnt = 0; 1225 gspca_dev->exp_too_low_cnt = 0;
1248 atomic_set(&sd->avg_lum, -1); 1226 atomic_set(&sd->avg_lum, -1);
1249 return gspca_dev->usb_err; 1227 return gspca_dev->usb_err;
1250} 1228}
@@ -1388,37 +1366,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1388 } 1366 }
1389} 1367}
1390 1368
1391static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1392{
1393 struct sd *sd = (struct sd *) gspca_dev;
1394
1395 sd->ctrls[AUTOGAIN].val = val;
1396 sd->exp_too_high_cnt = 0;
1397 sd->exp_too_low_cnt = 0;
1398
1399 /* when switching to autogain set defaults to make sure
1400 we are on a valid point of the autogain gain /
1401 exposure knee graph, and give this change time to
1402 take effect before doing autogain. */
1403 if (sd->ctrls[AUTOGAIN].val
1404 && !(sensor_data[sd->sensor].flags & F_COARSE_EXPO)) {
1405 sd->ctrls[EXPOSURE].val = sd->ctrls[EXPOSURE].def;
1406 sd->ctrls[GAIN].val = sd->ctrls[GAIN].def;
1407 if (gspca_dev->streaming) {
1408 sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
1409 setexposure(gspca_dev);
1410 setgain(gspca_dev);
1411 }
1412 }
1413
1414 if (sd->ctrls[AUTOGAIN].val)
1415 gspca_dev->ctrl_inac = (1 << GAIN) | (1 << EXPOSURE);
1416 else
1417 gspca_dev->ctrl_inac = 0;
1418
1419 return 0;
1420}
1421
1422static int sd_querymenu(struct gspca_dev *gspca_dev, 1369static int sd_querymenu(struct gspca_dev *gspca_dev,
1423 struct v4l2_querymenu *menu) 1370 struct v4l2_querymenu *menu)
1424{ 1371{
@@ -1462,10 +1409,9 @@ static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
1462/* sub-driver description */ 1409/* sub-driver description */
1463static const struct sd_desc sd_desc = { 1410static const struct sd_desc sd_desc = {
1464 .name = MODULE_NAME, 1411 .name = MODULE_NAME,
1465 .ctrls = sd_ctrls,
1466 .nctrls = ARRAY_SIZE(sd_ctrls),
1467 .config = sd_config, 1412 .config = sd_config,
1468 .init = sd_init, 1413 .init = sd_init,
1414 .init_controls = sd_init_controls,
1469 .start = sd_start, 1415 .start = sd_start,
1470 .stopN = sd_stopN, 1416 .stopN = sd_stopN,
1471 .pkt_scan = sd_pkt_scan, 1417 .pkt_scan = sd_pkt_scan,