aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca
diff options
context:
space:
mode:
authorJean-François Moine <moinejf@free.fr>2011-03-13 14:04:11 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-03-22 03:54:44 -0400
commitf51a8caafedfc643b3dfa2ffdfb02da31a13db3f (patch)
tree4ba159d9c5560ea2f4413e0c2690f982de11b6ef /drivers/media/video/gspca
parentfa85bb6f9b101d92940f54c7ab1b8557aaa35a6d (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.c286
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>");
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
59/* specific webcam descriptor */ 69/* specific webcam descriptor */
60struct sd { 70struct 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 */
144static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); 151static void setbrightness(struct gspca_dev *gspca_dev);
145static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); 152static void setgain(struct gspca_dev *gspca_dev);
146static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val); 153static void setexposure(struct gspca_dev *gspca_dev);
147static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
148static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
149static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
150static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); 154static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
151static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); 155static void setfreq(struct gspca_dev *gspca_dev);
152static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
153static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
154 156
155static const struct ctrl sd_ctrls[] = { 157static 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:
687static void setsensorgain(struct gspca_dev *gspca_dev) 665static 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, &reg, 1); 817 reg_w(gspca_dev, 0x19, &reg, 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
1022static void do_autogain(struct gspca_dev *gspca_dev) 1005static 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
1401static 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
1411static 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
1419static 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
1429static 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
1437static 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
1447static 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
1455static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) 1380static 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
1480static 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
1488static 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
1498static 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
1506static int sd_querymenu(struct gspca_dev *gspca_dev, 1406static int sd_querymenu(struct gspca_dev *gspca_dev,
1507 struct v4l2_querymenu *menu) 1407 struct v4l2_querymenu *menu)
1508{ 1408{