diff options
author | Jean-François Moine <moinejf@free.fr> | 2011-03-13 14:04:11 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-03-22 03:54:44 -0400 |
commit | f51a8caafedfc643b3dfa2ffdfb02da31a13db3f (patch) | |
tree | 4ba159d9c5560ea2f4413e0c2690f982de11b6ef /drivers/media/video/gspca | |
parent | fa85bb6f9b101d92940f54c7ab1b8557aaa35a6d (diff) |
[media] gspca - sonixb: Use the new control mechanism
Acked-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Jean-François Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/gspca')
-rw-r--r-- | drivers/media/video/gspca/sonixb.c | 286 |
1 files changed, 93 insertions, 193 deletions
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index c6cd68d66b5..13cca7a82cb 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c | |||
@@ -56,9 +56,22 @@ MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); | |||
56 | MODULE_DESCRIPTION("GSPCA/SN9C102 USB Camera Driver"); | 56 | MODULE_DESCRIPTION("GSPCA/SN9C102 USB Camera Driver"); |
57 | MODULE_LICENSE("GPL"); | 57 | MODULE_LICENSE("GPL"); |
58 | 58 | ||
59 | /* controls */ | ||
60 | enum e_ctrl { | ||
61 | BRIGHTNESS, | ||
62 | GAIN, | ||
63 | EXPOSURE, | ||
64 | AUTOGAIN, | ||
65 | FREQ, | ||
66 | NCTRLS /* number of controls */ | ||
67 | }; | ||
68 | |||
59 | /* specific webcam descriptor */ | 69 | /* specific webcam descriptor */ |
60 | struct sd { | 70 | struct sd { |
61 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 71 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
72 | |||
73 | struct gspca_ctrl ctrls[NCTRLS]; | ||
74 | |||
62 | atomic_t avg_lum; | 75 | atomic_t avg_lum; |
63 | int prev_avg_lum; | 76 | int prev_avg_lum; |
64 | int exp_too_low_cnt; | 77 | int exp_too_low_cnt; |
@@ -66,13 +79,8 @@ struct sd { | |||
66 | int header_read; | 79 | int header_read; |
67 | u8 header[12]; /* Header without sof marker */ | 80 | u8 header[12]; /* Header without sof marker */ |
68 | 81 | ||
69 | unsigned short exposure; | ||
70 | unsigned char gain; | ||
71 | unsigned char brightness; | ||
72 | unsigned char autogain; | ||
73 | unsigned char autogain_ignore_frames; | 82 | unsigned char autogain_ignore_frames; |
74 | unsigned char frames_to_drop; | 83 | unsigned char frames_to_drop; |
75 | unsigned char freq; /* light freq filter setting */ | ||
76 | 84 | ||
77 | __u8 bridge; /* Type of bridge */ | 85 | __u8 bridge; /* Type of bridge */ |
78 | #define BRIDGE_101 0 | 86 | #define BRIDGE_101 0 |
@@ -113,10 +121,9 @@ struct sensor_data { | |||
113 | #define MODE_REDUCED_SIF 0x20 /* vga mode (320x240 / 160x120) on sif cam */ | 121 | #define MODE_REDUCED_SIF 0x20 /* vga mode (320x240 / 160x120) on sif cam */ |
114 | 122 | ||
115 | /* ctrl_dis helper macros */ | 123 | /* ctrl_dis helper macros */ |
116 | #define NO_EXPO ((1 << EXPOSURE_IDX) | (1 << COARSE_EXPOSURE_IDX) | \ | 124 | #define NO_EXPO ((1 << EXPOSURE) | (1 << AUTOGAIN)) |
117 | (1 << AUTOGAIN_IDX)) | 125 | #define NO_FREQ (1 << FREQ) |
118 | #define NO_FREQ (1 << FREQ_IDX) | 126 | #define NO_BRIGHTNESS (1 << BRIGHTNESS) |
119 | #define NO_BRIGHTNESS (1 << BRIGHTNESS_IDX) | ||
120 | 127 | ||
121 | #define COMP 0xc7 /* 0x87 //0x07 */ | 128 | #define COMP 0xc7 /* 0x87 //0x07 */ |
122 | #define COMP1 0xc9 /* 0x89 //0x09 */ | 129 | #define COMP1 0xc9 /* 0x89 //0x09 */ |
@@ -141,20 +148,14 @@ struct sensor_data { | |||
141 | #define AUTOGAIN_IGNORE_FRAMES 1 | 148 | #define AUTOGAIN_IGNORE_FRAMES 1 |
142 | 149 | ||
143 | /* V4L2 controls supported by the driver */ | 150 | /* V4L2 controls supported by the driver */ |
144 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | 151 | static void setbrightness(struct gspca_dev *gspca_dev); |
145 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | 152 | static void setgain(struct gspca_dev *gspca_dev); |
146 | static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val); | 153 | static void setexposure(struct gspca_dev *gspca_dev); |
147 | static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val); | ||
148 | static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val); | ||
149 | static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val); | ||
150 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); | 154 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); |
151 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); | 155 | static void setfreq(struct gspca_dev *gspca_dev); |
152 | static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); | ||
153 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); | ||
154 | 156 | ||
155 | static const struct ctrl sd_ctrls[] = { | 157 | static const struct ctrl sd_ctrls[NCTRLS] = { |
156 | #define BRIGHTNESS_IDX 0 | 158 | [BRIGHTNESS] = { |
157 | { | ||
158 | { | 159 | { |
159 | .id = V4L2_CID_BRIGHTNESS, | 160 | .id = V4L2_CID_BRIGHTNESS, |
160 | .type = V4L2_CTRL_TYPE_INTEGER, | 161 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -162,14 +163,11 @@ static const struct ctrl sd_ctrls[] = { | |||
162 | .minimum = 0, | 163 | .minimum = 0, |
163 | .maximum = 255, | 164 | .maximum = 255, |
164 | .step = 1, | 165 | .step = 1, |
165 | #define BRIGHTNESS_DEF 127 | 166 | .default_value = 127, |
166 | .default_value = BRIGHTNESS_DEF, | ||
167 | }, | 167 | }, |
168 | .set = sd_setbrightness, | 168 | .set_control = setbrightness |
169 | .get = sd_getbrightness, | ||
170 | }, | 169 | }, |
171 | #define GAIN_IDX 1 | 170 | [GAIN] = { |
172 | { | ||
173 | { | 171 | { |
174 | .id = V4L2_CID_GAIN, | 172 | .id = V4L2_CID_GAIN, |
175 | .type = V4L2_CTRL_TYPE_INTEGER, | 173 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -177,48 +175,31 @@ static const struct ctrl sd_ctrls[] = { | |||
177 | .minimum = 0, | 175 | .minimum = 0, |
178 | .maximum = 255, | 176 | .maximum = 255, |
179 | .step = 1, | 177 | .step = 1, |
180 | #define GAIN_DEF 127 | ||
181 | #define GAIN_KNEE 230 | 178 | #define GAIN_KNEE 230 |
182 | .default_value = GAIN_DEF, | 179 | .default_value = 127, |
183 | }, | 180 | }, |
184 | .set = sd_setgain, | 181 | .set_control = setgain |
185 | .get = sd_getgain, | ||
186 | }, | 182 | }, |
187 | #define EXPOSURE_IDX 2 | 183 | [EXPOSURE] = { |
188 | { | ||
189 | { | 184 | { |
190 | .id = V4L2_CID_EXPOSURE, | 185 | .id = V4L2_CID_EXPOSURE, |
191 | .type = V4L2_CTRL_TYPE_INTEGER, | 186 | .type = V4L2_CTRL_TYPE_INTEGER, |
192 | .name = "Exposure", | 187 | .name = "Exposure", |
193 | #define EXPOSURE_DEF 66 /* 33 ms / 30 fps (except on PASXXX) */ | ||
194 | #define EXPOSURE_KNEE 200 /* 100 ms / 10 fps (except on PASXXX) */ | ||
195 | .minimum = 0, | 188 | .minimum = 0, |
196 | .maximum = 1023, | 189 | .maximum = 1023, |
197 | .step = 1, | 190 | .step = 1, |
198 | .default_value = EXPOSURE_DEF, | 191 | .default_value = 66, |
192 | /* 33 ms / 30 fps (except on PASXXX) */ | ||
193 | #define EXPOSURE_KNEE 200 /* 100 ms / 10 fps (except on PASXXX) */ | ||
199 | .flags = 0, | 194 | .flags = 0, |
200 | }, | 195 | }, |
201 | .set = sd_setexposure, | 196 | .set_control = setexposure |
202 | .get = sd_getexposure, | ||
203 | }, | 197 | }, |
204 | #define COARSE_EXPOSURE_IDX 3 | 198 | /* for coarse exposure */ |
205 | { | 199 | #define COARSE_EXPOSURE_MIN 2 |
206 | { | 200 | #define COARSE_EXPOSURE_MAX 15 |
207 | .id = V4L2_CID_EXPOSURE, | ||
208 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
209 | .name = "Exposure", | ||
210 | #define COARSE_EXPOSURE_DEF 2 /* 30 fps */ | 201 | #define COARSE_EXPOSURE_DEF 2 /* 30 fps */ |
211 | .minimum = 2, | 202 | [AUTOGAIN] = { |
212 | .maximum = 15, | ||
213 | .step = 1, | ||
214 | .default_value = COARSE_EXPOSURE_DEF, | ||
215 | .flags = 0, | ||
216 | }, | ||
217 | .set = sd_setexposure, | ||
218 | .get = sd_getexposure, | ||
219 | }, | ||
220 | #define AUTOGAIN_IDX 4 | ||
221 | { | ||
222 | { | 203 | { |
223 | .id = V4L2_CID_AUTOGAIN, | 204 | .id = V4L2_CID_AUTOGAIN, |
224 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 205 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
@@ -231,10 +212,8 @@ static const struct ctrl sd_ctrls[] = { | |||
231 | .flags = 0, | 212 | .flags = 0, |
232 | }, | 213 | }, |
233 | .set = sd_setautogain, | 214 | .set = sd_setautogain, |
234 | .get = sd_getautogain, | ||
235 | }, | 215 | }, |
236 | #define FREQ_IDX 5 | 216 | [FREQ] = { |
237 | { | ||
238 | { | 217 | { |
239 | .id = V4L2_CID_POWER_LINE_FREQUENCY, | 218 | .id = V4L2_CID_POWER_LINE_FREQUENCY, |
240 | .type = V4L2_CTRL_TYPE_MENU, | 219 | .type = V4L2_CTRL_TYPE_MENU, |
@@ -245,8 +224,7 @@ static const struct ctrl sd_ctrls[] = { | |||
245 | #define FREQ_DEF 0 | 224 | #define FREQ_DEF 0 |
246 | .default_value = FREQ_DEF, | 225 | .default_value = FREQ_DEF, |
247 | }, | 226 | }, |
248 | .set = sd_setfreq, | 227 | .set_control = setfreq |
249 | .get = sd_getfreq, | ||
250 | }, | 228 | }, |
251 | }; | 229 | }; |
252 | 230 | ||
@@ -646,7 +624,7 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
646 | 624 | ||
647 | /* change reg 0x06 */ | 625 | /* change reg 0x06 */ |
648 | i2cOV[1] = sensor_data[sd->sensor].sensor_addr; | 626 | i2cOV[1] = sensor_data[sd->sensor].sensor_addr; |
649 | i2cOV[3] = sd->brightness; | 627 | i2cOV[3] = sd->ctrls[BRIGHTNESS].val; |
650 | if (i2c_w(gspca_dev, i2cOV) < 0) | 628 | if (i2c_w(gspca_dev, i2cOV) < 0) |
651 | goto err; | 629 | goto err; |
652 | break; | 630 | break; |
@@ -664,13 +642,13 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
664 | i2cpdoit[2] = 0x13; | 642 | i2cpdoit[2] = 0x13; |
665 | } | 643 | } |
666 | 644 | ||
667 | if (sd->brightness < 127) { | 645 | if (sd->ctrls[BRIGHTNESS].val < 127) { |
668 | /* change reg 0x0b, signreg */ | 646 | /* change reg 0x0b, signreg */ |
669 | i2cpbright[3] = 0x01; | 647 | i2cpbright[3] = 0x01; |
670 | /* set reg 0x0c, offset */ | 648 | /* set reg 0x0c, offset */ |
671 | i2cpbright[4] = 127 - sd->brightness; | 649 | i2cpbright[4] = 127 - sd->ctrls[BRIGHTNESS].val; |
672 | } else | 650 | } else |
673 | i2cpbright[4] = sd->brightness - 127; | 651 | i2cpbright[4] = sd->ctrls[BRIGHTNESS].val - 127; |
674 | 652 | ||
675 | if (i2c_w(gspca_dev, i2cpbright) < 0) | 653 | if (i2c_w(gspca_dev, i2cpbright) < 0) |
676 | goto err; | 654 | goto err; |
@@ -687,16 +665,16 @@ err: | |||
687 | static void setsensorgain(struct gspca_dev *gspca_dev) | 665 | static void setsensorgain(struct gspca_dev *gspca_dev) |
688 | { | 666 | { |
689 | struct sd *sd = (struct sd *) gspca_dev; | 667 | struct sd *sd = (struct sd *) gspca_dev; |
690 | unsigned char gain = sd->gain; | 668 | u8 gain = sd->ctrls[GAIN].val; |
691 | 669 | ||
692 | switch (sd->sensor) { | 670 | switch (sd->sensor) { |
693 | case SENSOR_HV7131D: { | 671 | case SENSOR_HV7131D: { |
694 | __u8 i2c[] = | 672 | __u8 i2c[] = |
695 | {0xc0, 0x11, 0x31, 0x00, 0x00, 0x00, 0x00, 0x17}; | 673 | {0xc0, 0x11, 0x31, 0x00, 0x00, 0x00, 0x00, 0x17}; |
696 | 674 | ||
697 | i2c[3] = 0x3f - (sd->gain / 4); | 675 | i2c[3] = 0x3f - (gain / 4); |
698 | i2c[4] = 0x3f - (sd->gain / 4); | 676 | i2c[4] = 0x3f - (gain / 4); |
699 | i2c[5] = 0x3f - (sd->gain / 4); | 677 | i2c[5] = 0x3f - (gain / 4); |
700 | 678 | ||
701 | if (i2c_w(gspca_dev, i2c) < 0) | 679 | if (i2c_w(gspca_dev, i2c) < 0) |
702 | goto err; | 680 | goto err; |
@@ -759,11 +737,11 @@ static void setsensorgain(struct gspca_dev *gspca_dev) | |||
759 | i2cpdoit[2] = 0x13; | 737 | i2cpdoit[2] = 0x13; |
760 | } | 738 | } |
761 | 739 | ||
762 | i2cpgain[3] = sd->gain >> 3; | 740 | i2cpgain[3] = gain >> 3; |
763 | i2cpcolorgain[3] = sd->gain >> 4; | 741 | i2cpcolorgain[3] = gain >> 4; |
764 | i2cpcolorgain[4] = sd->gain >> 4; | 742 | i2cpcolorgain[4] = gain >> 4; |
765 | i2cpcolorgain[5] = sd->gain >> 4; | 743 | i2cpcolorgain[5] = gain >> 4; |
766 | i2cpcolorgain[6] = sd->gain >> 4; | 744 | i2cpcolorgain[6] = gain >> 4; |
767 | 745 | ||
768 | if (i2c_w(gspca_dev, i2cpgain) < 0) | 746 | if (i2c_w(gspca_dev, i2cpgain) < 0) |
769 | goto err; | 747 | goto err; |
@@ -792,13 +770,13 @@ static void setgain(struct gspca_dev *gspca_dev) | |||
792 | } | 770 | } |
793 | 771 | ||
794 | if (sd->bridge == BRIDGE_103) { | 772 | if (sd->bridge == BRIDGE_103) { |
795 | gain = sd->gain >> 1; | 773 | gain = sd->ctrls[GAIN].val >> 1; |
796 | buf[0] = gain; /* Red */ | 774 | buf[0] = gain; /* Red */ |
797 | buf[1] = gain; /* Green */ | 775 | buf[1] = gain; /* Green */ |
798 | buf[2] = gain; /* Blue */ | 776 | buf[2] = gain; /* Blue */ |
799 | reg_w(gspca_dev, 0x05, buf, 3); | 777 | reg_w(gspca_dev, 0x05, buf, 3); |
800 | } else { | 778 | } else { |
801 | gain = sd->gain >> 4; | 779 | gain = sd->ctrls[GAIN].val >> 4; |
802 | buf[0] = gain << 4 | gain; /* Red and blue */ | 780 | buf[0] = gain << 4 | gain; /* Red and blue */ |
803 | buf[1] = gain; /* Green */ | 781 | buf[1] = gain; /* Green */ |
804 | reg_w(gspca_dev, 0x10, buf, 2); | 782 | reg_w(gspca_dev, 0x10, buf, 2); |
@@ -820,7 +798,8 @@ static void setexposure(struct gspca_dev *gspca_dev) | |||
820 | where the framerate starts dropping | 798 | where the framerate starts dropping |
821 | 2) At 6138 the framerate has already dropped to 2 fps, | 799 | 2) At 6138 the framerate has already dropped to 2 fps, |
822 | going any lower makes little sense */ | 800 | going any lower makes little sense */ |
823 | __u16 reg = sd->exposure * 6; | 801 | u16 reg = sd->ctrls[EXPOSURE].val * 6; |
802 | |||
824 | i2c[3] = reg >> 8; | 803 | i2c[3] = reg >> 8; |
825 | i2c[4] = reg & 0xff; | 804 | i2c[4] = reg & 0xff; |
826 | if (i2c_w(gspca_dev, i2c) != 0) | 805 | if (i2c_w(gspca_dev, i2c) != 0) |
@@ -832,7 +811,8 @@ static void setexposure(struct gspca_dev *gspca_dev) | |||
832 | /* register 19's high nibble contains the sn9c10x clock divider | 811 | /* register 19's high nibble contains the sn9c10x clock divider |
833 | The high nibble configures the no fps according to the | 812 | The high nibble configures the no fps according to the |
834 | formula: 60 / high_nibble. With a maximum of 30 fps */ | 813 | formula: 60 / high_nibble. With a maximum of 30 fps */ |
835 | __u8 reg = sd->exposure; | 814 | u8 reg = sd->ctrls[EXPOSURE].val; |
815 | |||
836 | reg = (reg << 4) | 0x0b; | 816 | reg = (reg << 4) | 0x0b; |
837 | reg_w(gspca_dev, 0x19, ®, 1); | 817 | reg_w(gspca_dev, 0x19, ®, 1); |
838 | break; | 818 | break; |
@@ -868,7 +848,7 @@ static void setexposure(struct gspca_dev *gspca_dev) | |||
868 | } else | 848 | } else |
869 | reg10_max = 0x41; | 849 | reg10_max = 0x41; |
870 | 850 | ||
871 | reg11 = (15 * sd->exposure + 999) / 1000; | 851 | reg11 = (15 * sd->ctrls[EXPOSURE].val + 999) / 1000; |
872 | if (reg11 < 1) | 852 | if (reg11 < 1) |
873 | reg11 = 1; | 853 | reg11 = 1; |
874 | else if (reg11 > 16) | 854 | else if (reg11 > 16) |
@@ -881,14 +861,16 @@ static void setexposure(struct gspca_dev *gspca_dev) | |||
881 | reg11 = 4; | 861 | reg11 = 4; |
882 | 862 | ||
883 | /* frame exposure time in ms = 1000 * reg11 / 30 -> | 863 | /* frame exposure time in ms = 1000 * reg11 / 30 -> |
884 | reg10 = (sd->exposure / 2) * reg10_max / (1000 * reg11 / 30) */ | 864 | reg10 = (sd->ctrls[EXPOSURE].val / 2) * reg10_max |
885 | reg10 = (sd->exposure * 15 * reg10_max) / (1000 * reg11); | 865 | / (1000 * reg11 / 30) */ |
866 | reg10 = (sd->ctrls[EXPOSURE].val * 15 * reg10_max) | ||
867 | / (1000 * reg11); | ||
886 | 868 | ||
887 | /* Don't allow this to get below 10 when using autogain, the | 869 | /* Don't allow this to get below 10 when using autogain, the |
888 | steps become very large (relatively) when below 10 causing | 870 | steps become very large (relatively) when below 10 causing |
889 | the image to oscilate from much too dark, to much too bright | 871 | the image to oscilate from much too dark, to much too bright |
890 | and back again. */ | 872 | and back again. */ |
891 | if (sd->autogain && reg10 < 10) | 873 | if (sd->ctrls[AUTOGAIN].val && reg10 < 10) |
892 | reg10 = 10; | 874 | reg10 = 10; |
893 | else if (reg10 > reg10_max) | 875 | else if (reg10 > reg10_max) |
894 | reg10 = reg10_max; | 876 | reg10 = reg10_max; |
@@ -927,15 +909,16 @@ static void setexposure(struct gspca_dev *gspca_dev) | |||
927 | frame exposure times (like we are doing with the ov chips), | 909 | frame exposure times (like we are doing with the ov chips), |
928 | as that sometimes leads to jumps in the exposure control, | 910 | as that sometimes leads to jumps in the exposure control, |
929 | which are bad for auto exposure. */ | 911 | which are bad for auto exposure. */ |
930 | if (sd->exposure < 200) { | 912 | if (sd->ctrls[EXPOSURE].val < 200) { |
931 | i2cpexpo[3] = 255 - (sd->exposure * 255) / 200; | 913 | i2cpexpo[3] = 255 - (sd->ctrls[EXPOSURE].val * 255) |
914 | / 200; | ||
932 | framerate_ctrl = 500; | 915 | framerate_ctrl = 500; |
933 | } else { | 916 | } else { |
934 | /* The PAS202's exposure control goes from 0 - 4095, | 917 | /* The PAS202's exposure control goes from 0 - 4095, |
935 | but anything below 500 causes vsync issues, so scale | 918 | but anything below 500 causes vsync issues, so scale |
936 | our 200-1023 to 500-4095 */ | 919 | our 200-1023 to 500-4095 */ |
937 | framerate_ctrl = (sd->exposure - 200) * 1000 / 229 + | 920 | framerate_ctrl = (sd->ctrls[EXPOSURE].val - 200) |
938 | 500; | 921 | * 1000 / 229 + 500; |
939 | } | 922 | } |
940 | 923 | ||
941 | i2cpframerate[3] = framerate_ctrl >> 6; | 924 | i2cpframerate[3] = framerate_ctrl >> 6; |
@@ -959,15 +942,15 @@ static void setexposure(struct gspca_dev *gspca_dev) | |||
959 | 942 | ||
960 | /* For values below 150 use partial frame exposure, above | 943 | /* For values below 150 use partial frame exposure, above |
961 | that use framerate ctrl */ | 944 | that use framerate ctrl */ |
962 | if (sd->exposure < 150) { | 945 | if (sd->ctrls[EXPOSURE].val < 150) { |
963 | i2cpexpo[3] = 150 - sd->exposure; | 946 | i2cpexpo[3] = 150 - sd->ctrls[EXPOSURE].val; |
964 | framerate_ctrl = 300; | 947 | framerate_ctrl = 300; |
965 | } else { | 948 | } else { |
966 | /* The PAS106's exposure control goes from 0 - 4095, | 949 | /* The PAS106's exposure control goes from 0 - 4095, |
967 | but anything below 300 causes vsync issues, so scale | 950 | but anything below 300 causes vsync issues, so scale |
968 | our 150-1023 to 300-4095 */ | 951 | our 150-1023 to 300-4095 */ |
969 | framerate_ctrl = (sd->exposure - 150) * 1000 / 230 + | 952 | framerate_ctrl = (sd->ctrls[EXPOSURE].val - 150) |
970 | 300; | 953 | * 1000 / 230 + 300; |
971 | } | 954 | } |
972 | 955 | ||
973 | i2cpframerate[3] = framerate_ctrl >> 4; | 956 | i2cpframerate[3] = framerate_ctrl >> 4; |
@@ -998,7 +981,7 @@ static void setfreq(struct gspca_dev *gspca_dev) | |||
998 | 0x2b register, see ov6630 datasheet. | 981 | 0x2b register, see ov6630 datasheet. |
999 | 0x4f / 0x8a -> (30 fps -> 25 fps), 0x00 -> no adjustment */ | 982 | 0x4f / 0x8a -> (30 fps -> 25 fps), 0x00 -> no adjustment */ |
1000 | __u8 i2c[] = {0xa0, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}; | 983 | __u8 i2c[] = {0xa0, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}; |
1001 | switch (sd->freq) { | 984 | switch (sd->ctrls[FREQ].val) { |
1002 | default: | 985 | default: |
1003 | /* case 0: * no filter*/ | 986 | /* case 0: * no filter*/ |
1004 | /* case 2: * 60 hz */ | 987 | /* case 2: * 60 hz */ |
@@ -1017,7 +1000,7 @@ static void setfreq(struct gspca_dev *gspca_dev) | |||
1017 | } | 1000 | } |
1018 | } | 1001 | } |
1019 | 1002 | ||
1020 | #include "coarse_expo_autogain.h" | 1003 | #include "autogain_functions.h" |
1021 | 1004 | ||
1022 | static void do_autogain(struct gspca_dev *gspca_dev) | 1005 | static void do_autogain(struct gspca_dev *gspca_dev) |
1023 | { | 1006 | { |
@@ -1025,7 +1008,7 @@ static void do_autogain(struct gspca_dev *gspca_dev) | |||
1025 | struct sd *sd = (struct sd *) gspca_dev; | 1008 | struct sd *sd = (struct sd *) gspca_dev; |
1026 | int avg_lum = atomic_read(&sd->avg_lum); | 1009 | int avg_lum = atomic_read(&sd->avg_lum); |
1027 | 1010 | ||
1028 | if (avg_lum == -1 || !sd->autogain) | 1011 | if (avg_lum == -1 || !sd->ctrls[AUTOGAIN].val) |
1029 | return; | 1012 | return; |
1030 | 1013 | ||
1031 | if (sd->autogain_ignore_frames > 0) { | 1014 | if (sd->autogain_ignore_frames > 0) { |
@@ -1045,17 +1028,20 @@ static void do_autogain(struct gspca_dev *gspca_dev) | |||
1045 | } | 1028 | } |
1046 | 1029 | ||
1047 | if (sensor_data[sd->sensor].flags & F_COARSE_EXPO) | 1030 | if (sensor_data[sd->sensor].flags & F_COARSE_EXPO) |
1048 | result = gspca_coarse_grained_expo_autogain(gspca_dev, avg_lum, | 1031 | result = coarse_grained_expo_autogain(gspca_dev, avg_lum, |
1049 | sd->brightness * desired_avg_lum / 127, | 1032 | sd->ctrls[BRIGHTNESS].val |
1033 | * desired_avg_lum / 127, | ||
1050 | deadzone); | 1034 | deadzone); |
1051 | else | 1035 | else |
1052 | result = gspca_auto_gain_n_exposure(gspca_dev, avg_lum, | 1036 | result = auto_gain_n_exposure(gspca_dev, avg_lum, |
1053 | sd->brightness * desired_avg_lum / 127, | 1037 | sd->ctrls[BRIGHTNESS].val |
1038 | * desired_avg_lum / 127, | ||
1054 | deadzone, GAIN_KNEE, EXPOSURE_KNEE); | 1039 | deadzone, GAIN_KNEE, EXPOSURE_KNEE); |
1055 | 1040 | ||
1056 | if (result) { | 1041 | if (result) { |
1057 | PDEBUG(D_FRAM, "autogain: gain changed: gain: %d expo: %d", | 1042 | PDEBUG(D_FRAM, "autogain: gain changed: gain: %d expo: %d", |
1058 | (int)sd->gain, (int)sd->exposure); | 1043 | (int) sd->ctrls[GAIN].val, |
1044 | (int) sd->ctrls[EXPOSURE].val); | ||
1059 | sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES; | 1045 | sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES; |
1060 | } | 1046 | } |
1061 | } | 1047 | } |
@@ -1074,9 +1060,11 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
1074 | /* copy the webcam info from the device id */ | 1060 | /* copy the webcam info from the device id */ |
1075 | sd->sensor = id->driver_info >> 8; | 1061 | sd->sensor = id->driver_info >> 8; |
1076 | sd->bridge = id->driver_info & 0xff; | 1062 | sd->bridge = id->driver_info & 0xff; |
1063 | |||
1077 | gspca_dev->ctrl_dis = sensor_data[sd->sensor].ctrl_dis; | 1064 | gspca_dev->ctrl_dis = sensor_data[sd->sensor].ctrl_dis; |
1078 | 1065 | ||
1079 | cam = &gspca_dev->cam; | 1066 | cam = &gspca_dev->cam; |
1067 | cam->ctrls = sd->ctrls; | ||
1080 | if (!(sensor_data[sd->sensor].flags & F_SIF)) { | 1068 | if (!(sensor_data[sd->sensor].flags & F_SIF)) { |
1081 | cam->cam_mode = vga_mode; | 1069 | cam->cam_mode = vga_mode; |
1082 | cam->nmodes = ARRAY_SIZE(vga_mode); | 1070 | cam->nmodes = ARRAY_SIZE(vga_mode); |
@@ -1086,20 +1074,11 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
1086 | } | 1074 | } |
1087 | cam->npkt = 36; /* 36 packets per ISOC message */ | 1075 | cam->npkt = 36; /* 36 packets per ISOC message */ |
1088 | 1076 | ||
1089 | sd->brightness = BRIGHTNESS_DEF; | ||
1090 | sd->gain = GAIN_DEF; | ||
1091 | if (sensor_data[sd->sensor].flags & F_COARSE_EXPO) { | 1077 | if (sensor_data[sd->sensor].flags & F_COARSE_EXPO) { |
1092 | sd->exposure = COARSE_EXPOSURE_DEF; | 1078 | sd->ctrls[EXPOSURE].min = COARSE_EXPOSURE_MIN; |
1093 | gspca_dev->ctrl_dis |= (1 << EXPOSURE_IDX); | 1079 | sd->ctrls[EXPOSURE].max = COARSE_EXPOSURE_MAX; |
1094 | } else { | 1080 | sd->ctrls[EXPOSURE].def = COARSE_EXPOSURE_DEF; |
1095 | sd->exposure = EXPOSURE_DEF; | ||
1096 | gspca_dev->ctrl_dis |= (1 << COARSE_EXPOSURE_IDX); | ||
1097 | } | 1081 | } |
1098 | if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX)) | ||
1099 | sd->autogain = 0; /* Disable do_autogain callback */ | ||
1100 | else | ||
1101 | sd->autogain = AUTOGAIN_DEF; | ||
1102 | sd->freq = FREQ_DEF; | ||
1103 | 1082 | ||
1104 | return 0; | 1083 | return 0; |
1105 | } | 1084 | } |
@@ -1398,65 +1377,11 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
1398 | } | 1377 | } |
1399 | } | 1378 | } |
1400 | 1379 | ||
1401 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | ||
1402 | { | ||
1403 | struct sd *sd = (struct sd *) gspca_dev; | ||
1404 | |||
1405 | sd->brightness = val; | ||
1406 | if (gspca_dev->streaming) | ||
1407 | setbrightness(gspca_dev); | ||
1408 | return 0; | ||
1409 | } | ||
1410 | |||
1411 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
1412 | { | ||
1413 | struct sd *sd = (struct sd *) gspca_dev; | ||
1414 | |||
1415 | *val = sd->brightness; | ||
1416 | return 0; | ||
1417 | } | ||
1418 | |||
1419 | static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val) | ||
1420 | { | ||
1421 | struct sd *sd = (struct sd *) gspca_dev; | ||
1422 | |||
1423 | sd->gain = val; | ||
1424 | if (gspca_dev->streaming) | ||
1425 | setgain(gspca_dev); | ||
1426 | return 0; | ||
1427 | } | ||
1428 | |||
1429 | static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val) | ||
1430 | { | ||
1431 | struct sd *sd = (struct sd *) gspca_dev; | ||
1432 | |||
1433 | *val = sd->gain; | ||
1434 | return 0; | ||
1435 | } | ||
1436 | |||
1437 | static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val) | ||
1438 | { | ||
1439 | struct sd *sd = (struct sd *) gspca_dev; | ||
1440 | |||
1441 | sd->exposure = val; | ||
1442 | if (gspca_dev->streaming) | ||
1443 | setexposure(gspca_dev); | ||
1444 | return 0; | ||
1445 | } | ||
1446 | |||
1447 | static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val) | ||
1448 | { | ||
1449 | struct sd *sd = (struct sd *) gspca_dev; | ||
1450 | |||
1451 | *val = sd->exposure; | ||
1452 | return 0; | ||
1453 | } | ||
1454 | |||
1455 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) | 1380 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) |
1456 | { | 1381 | { |
1457 | struct sd *sd = (struct sd *) gspca_dev; | 1382 | struct sd *sd = (struct sd *) gspca_dev; |
1458 | 1383 | ||
1459 | sd->autogain = val; | 1384 | sd->ctrls[AUTOGAIN].val = val; |
1460 | sd->exp_too_high_cnt = 0; | 1385 | sd->exp_too_high_cnt = 0; |
1461 | sd->exp_too_low_cnt = 0; | 1386 | sd->exp_too_low_cnt = 0; |
1462 | 1387 | ||
@@ -1464,9 +1389,10 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) | |||
1464 | we are on a valid point of the autogain gain / | 1389 | we are on a valid point of the autogain gain / |
1465 | exposure knee graph, and give this change time to | 1390 | exposure knee graph, and give this change time to |
1466 | take effect before doing autogain. */ | 1391 | take effect before doing autogain. */ |
1467 | if (sd->autogain && !(sensor_data[sd->sensor].flags & F_COARSE_EXPO)) { | 1392 | if (sd->ctrls[AUTOGAIN].val |
1468 | sd->exposure = EXPOSURE_DEF; | 1393 | && !(sensor_data[sd->sensor].flags & F_COARSE_EXPO)) { |
1469 | sd->gain = GAIN_DEF; | 1394 | sd->ctrls[EXPOSURE].val = sd->ctrls[EXPOSURE].def; |
1395 | sd->ctrls[GAIN].val = sd->ctrls[GAIN].def; | ||
1470 | if (gspca_dev->streaming) { | 1396 | if (gspca_dev->streaming) { |
1471 | sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES; | 1397 | sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES; |
1472 | setexposure(gspca_dev); | 1398 | setexposure(gspca_dev); |
@@ -1477,32 +1403,6 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) | |||
1477 | return 0; | 1403 | return 0; |
1478 | } | 1404 | } |
1479 | 1405 | ||
1480 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) | ||
1481 | { | ||
1482 | struct sd *sd = (struct sd *) gspca_dev; | ||
1483 | |||
1484 | *val = sd->autogain; | ||
1485 | return 0; | ||
1486 | } | ||
1487 | |||
1488 | static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val) | ||
1489 | { | ||
1490 | struct sd *sd = (struct sd *) gspca_dev; | ||
1491 | |||
1492 | sd->freq = val; | ||
1493 | if (gspca_dev->streaming) | ||
1494 | setfreq(gspca_dev); | ||
1495 | return 0; | ||
1496 | } | ||
1497 | |||
1498 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val) | ||
1499 | { | ||
1500 | struct sd *sd = (struct sd *) gspca_dev; | ||
1501 | |||
1502 | *val = sd->freq; | ||
1503 | return 0; | ||
1504 | } | ||
1505 | |||
1506 | static int sd_querymenu(struct gspca_dev *gspca_dev, | 1406 | static int sd_querymenu(struct gspca_dev *gspca_dev, |
1507 | struct v4l2_querymenu *menu) | 1407 | struct v4l2_querymenu *menu) |
1508 | { | 1408 | { |