diff options
Diffstat (limited to 'drivers/media/video/gspca')
-rw-r--r-- | drivers/media/video/gspca/gl860/Makefile | 2 | ||||
-rw-r--r-- | drivers/media/video/gspca/m5602/Makefile | 2 | ||||
-rw-r--r-- | drivers/media/video/gspca/ov534_9.c | 49 | ||||
-rw-r--r-- | drivers/media/video/gspca/pac7302.c | 583 | ||||
-rw-r--r-- | drivers/media/video/gspca/sn9c20x.c | 1138 | ||||
-rw-r--r-- | drivers/media/video/gspca/sonixj.c | 185 | ||||
-rw-r--r-- | drivers/media/video/gspca/stv06xx/Makefile | 2 | ||||
-rw-r--r-- | drivers/media/video/gspca/zc3xx.c | 328 |
8 files changed, 1088 insertions, 1201 deletions
diff --git a/drivers/media/video/gspca/gl860/Makefile b/drivers/media/video/gspca/gl860/Makefile index f511eccdfd9c..773ea3426561 100644 --- a/drivers/media/video/gspca/gl860/Makefile +++ b/drivers/media/video/gspca/gl860/Makefile | |||
@@ -6,5 +6,5 @@ gspca_gl860-objs := gl860.o \ | |||
6 | gl860-ov9655.o \ | 6 | gl860-ov9655.o \ |
7 | gl860-mi2020.o | 7 | gl860-mi2020.o |
8 | 8 | ||
9 | ccflags-y += -Idrivers/media/video/gspca | 9 | ccflags-y += -I$(srctree)/drivers/media/video/gspca |
10 | 10 | ||
diff --git a/drivers/media/video/gspca/m5602/Makefile b/drivers/media/video/gspca/m5602/Makefile index 7f52961f439c..575b75bacb62 100644 --- a/drivers/media/video/gspca/m5602/Makefile +++ b/drivers/media/video/gspca/m5602/Makefile | |||
@@ -8,4 +8,4 @@ gspca_m5602-objs := m5602_core.o \ | |||
8 | m5602_s5k83a.o \ | 8 | m5602_s5k83a.o \ |
9 | m5602_s5k4aa.o | 9 | m5602_s5k4aa.o |
10 | 10 | ||
11 | ccflags-y += -Idrivers/media/video/gspca | 11 | ccflags-y += -I$(srctree)/drivers/media/video/gspca |
diff --git a/drivers/media/video/gspca/ov534_9.c b/drivers/media/video/gspca/ov534_9.c index fbfa02affa13..e6601b886032 100644 --- a/drivers/media/video/gspca/ov534_9.c +++ b/drivers/media/video/gspca/ov534_9.c | |||
@@ -1107,16 +1107,34 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
1107 | { | 1107 | { |
1108 | struct sd *sd = (struct sd *) gspca_dev; | 1108 | struct sd *sd = (struct sd *) gspca_dev; |
1109 | u8 val; | 1109 | u8 val; |
1110 | s8 sval; | ||
1110 | 1111 | ||
1111 | if (gspca_dev->ctrl_dis & (1 << BRIGHTNESS)) | 1112 | if (gspca_dev->ctrl_dis & (1 << BRIGHTNESS)) |
1112 | return; | 1113 | return; |
1113 | val = sd->ctrls[BRIGHTNESS].val; | 1114 | if (sd->sensor == SENSOR_OV562x) { |
1114 | if (val < 8) | 1115 | sval = sd->ctrls[BRIGHTNESS].val; |
1115 | val = 15 - val; /* f .. 8 */ | 1116 | val = 0x76; |
1116 | else | 1117 | val += sval; |
1117 | val = val - 8; /* 0 .. 7 */ | 1118 | sccb_write(gspca_dev, 0x24, val); |
1118 | sccb_write(gspca_dev, 0x55, /* brtn - brightness adjustment */ | 1119 | val = 0x6a; |
1119 | 0x0f | (val << 4)); | 1120 | val += sval; |
1121 | sccb_write(gspca_dev, 0x25, val); | ||
1122 | if (sval < -40) | ||
1123 | val = 0x71; | ||
1124 | else if (sval < 20) | ||
1125 | val = 0x94; | ||
1126 | else | ||
1127 | val = 0xe6; | ||
1128 | sccb_write(gspca_dev, 0x26, val); | ||
1129 | } else { | ||
1130 | val = sd->ctrls[BRIGHTNESS].val; | ||
1131 | if (val < 8) | ||
1132 | val = 15 - val; /* f .. 8 */ | ||
1133 | else | ||
1134 | val = val - 8; /* 0 .. 7 */ | ||
1135 | sccb_write(gspca_dev, 0x55, /* brtn - brightness adjustment */ | ||
1136 | 0x0f | (val << 4)); | ||
1137 | } | ||
1120 | } | 1138 | } |
1121 | 1139 | ||
1122 | static void setcontrast(struct gspca_dev *gspca_dev) | 1140 | static void setcontrast(struct gspca_dev *gspca_dev) |
@@ -1339,7 +1357,16 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
1339 | reg_w(gspca_dev, 0x56, 0x17); | 1357 | reg_w(gspca_dev, 0x56, 0x17); |
1340 | } else if ((sensor_id & 0xfff0) == 0x5620) { | 1358 | } else if ((sensor_id & 0xfff0) == 0x5620) { |
1341 | sd->sensor = SENSOR_OV562x; | 1359 | sd->sensor = SENSOR_OV562x; |
1342 | 1360 | gspca_dev->ctrl_dis = (1 << CONTRAST) | | |
1361 | (1 << AUTOGAIN) | | ||
1362 | (1 << EXPOSURE) | | ||
1363 | (1 << SHARPNESS) | | ||
1364 | (1 << SATUR) | | ||
1365 | (1 << LIGHTFREQ); | ||
1366 | |||
1367 | sd->ctrls[BRIGHTNESS].min = -90; | ||
1368 | sd->ctrls[BRIGHTNESS].max = 90; | ||
1369 | sd->ctrls[BRIGHTNESS].def = 0; | ||
1343 | gspca_dev->cam.cam_mode = ov562x_mode; | 1370 | gspca_dev->cam.cam_mode = ov562x_mode; |
1344 | gspca_dev->cam.nmodes = ARRAY_SIZE(ov562x_mode); | 1371 | gspca_dev->cam.nmodes = ARRAY_SIZE(ov562x_mode); |
1345 | 1372 | ||
@@ -1360,8 +1387,12 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
1360 | { | 1387 | { |
1361 | struct sd *sd = (struct sd *) gspca_dev; | 1388 | struct sd *sd = (struct sd *) gspca_dev; |
1362 | 1389 | ||
1363 | if (sd->sensor == SENSOR_OV971x || sd->sensor == SENSOR_OV562x) | 1390 | if (sd->sensor == SENSOR_OV971x) |
1364 | return gspca_dev->usb_err; | 1391 | return gspca_dev->usb_err; |
1392 | else if (sd->sensor == SENSOR_OV562x) { | ||
1393 | setbrightness(gspca_dev); | ||
1394 | return gspca_dev->usb_err; | ||
1395 | } | ||
1365 | switch (gspca_dev->curr_mode) { | 1396 | switch (gspca_dev->curr_mode) { |
1366 | case QVGA_MODE: /* 320x240 */ | 1397 | case QVGA_MODE: /* 320x240 */ |
1367 | sccb_w_array(gspca_dev, ov965x_start_1_vga, | 1398 | sccb_w_array(gspca_dev, ov965x_start_1_vga, |
diff --git a/drivers/media/video/gspca/pac7302.c b/drivers/media/video/gspca/pac7302.c index 9db2b34d172c..30662fccb0cf 100644 --- a/drivers/media/video/gspca/pac7302.c +++ b/drivers/media/video/gspca/pac7302.c | |||
@@ -1,8 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * Pixart PAC7302 library | 2 | * Pixart PAC7302 driver |
3 | * Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li | ||
4 | * | 3 | * |
5 | * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> | 4 | * Copyright (C) 2008-2012 Jean-Francois Moine <http://moinejf.free.fr> |
5 | * Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li | ||
6 | * | 6 | * |
7 | * Separated from Pixart PAC7311 library by Márton Németh | 7 | * Separated from Pixart PAC7311 library by Márton Németh |
8 | * Camera button input handling by Márton Németh <nm127@freemail.hu> | 8 | * Camera button input handling by Márton Németh <nm127@freemail.hu> |
@@ -63,67 +63,61 @@ | |||
63 | 63 | ||
64 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 64 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
65 | 65 | ||
66 | #define MODULE_NAME "pac7302" | ||
67 | |||
68 | #include <linux/input.h> | 66 | #include <linux/input.h> |
69 | #include <media/v4l2-chip-ident.h> | 67 | #include <media/v4l2-chip-ident.h> |
70 | #include "gspca.h" | 68 | #include "gspca.h" |
69 | /* Include pac common sof detection functions */ | ||
70 | #include "pac_common.h" | ||
71 | 71 | ||
72 | MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li"); | 72 | MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>, " |
73 | "Thomas Kaiser thomas@kaiser-linux.li"); | ||
73 | MODULE_DESCRIPTION("Pixart PAC7302"); | 74 | MODULE_DESCRIPTION("Pixart PAC7302"); |
74 | MODULE_LICENSE("GPL"); | 75 | MODULE_LICENSE("GPL"); |
75 | 76 | ||
77 | enum e_ctrl { | ||
78 | BRIGHTNESS, | ||
79 | CONTRAST, | ||
80 | COLORS, | ||
81 | WHITE_BALANCE, | ||
82 | RED_BALANCE, | ||
83 | BLUE_BALANCE, | ||
84 | GAIN, | ||
85 | AUTOGAIN, | ||
86 | EXPOSURE, | ||
87 | VFLIP, | ||
88 | HFLIP, | ||
89 | NCTRLS /* number of controls */ | ||
90 | }; | ||
91 | |||
76 | /* specific webcam descriptor for pac7302 */ | 92 | /* specific webcam descriptor for pac7302 */ |
77 | struct sd { | 93 | struct sd { |
78 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 94 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
79 | 95 | ||
80 | unsigned char brightness; | 96 | struct gspca_ctrl ctrls[NCTRLS]; |
81 | unsigned char contrast; | 97 | |
82 | unsigned char colors; | ||
83 | unsigned char white_balance; | ||
84 | unsigned char red_balance; | ||
85 | unsigned char blue_balance; | ||
86 | unsigned char gain; | ||
87 | unsigned char autogain; | ||
88 | unsigned short exposure; | ||
89 | __u8 hflip; | ||
90 | __u8 vflip; | ||
91 | u8 flags; | 98 | u8 flags; |
92 | #define FL_HFLIP 0x01 /* mirrored by default */ | 99 | #define FL_HFLIP 0x01 /* mirrored by default */ |
93 | #define FL_VFLIP 0x02 /* vertical flipped by default */ | 100 | #define FL_VFLIP 0x02 /* vertical flipped by default */ |
94 | 101 | ||
95 | u8 sof_read; | 102 | u8 sof_read; |
96 | u8 autogain_ignore_frames; | 103 | s8 autogain_ignore_frames; |
97 | 104 | ||
98 | atomic_t avg_lum; | 105 | atomic_t avg_lum; |
99 | }; | 106 | }; |
100 | 107 | ||
101 | /* V4L2 controls supported by the driver */ | 108 | /* V4L2 controls supported by the driver */ |
102 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | 109 | static void setbrightcont(struct gspca_dev *gspca_dev); |
103 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | 110 | static void setcolors(struct gspca_dev *gspca_dev); |
104 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | 111 | static void setwhitebalance(struct gspca_dev *gspca_dev); |
105 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | 112 | static void setredbalance(struct gspca_dev *gspca_dev); |
106 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); | 113 | static void setbluebalance(struct gspca_dev *gspca_dev); |
107 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); | 114 | static void setgain(struct gspca_dev *gspca_dev); |
108 | static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val); | 115 | static void setexposure(struct gspca_dev *gspca_dev); |
109 | static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val); | 116 | static void setautogain(struct gspca_dev *gspca_dev); |
110 | static int sd_setredbalance(struct gspca_dev *gspca_dev, __s32 val); | 117 | static void sethvflip(struct gspca_dev *gspca_dev); |
111 | static int sd_getredbalance(struct gspca_dev *gspca_dev, __s32 *val); | ||
112 | static int sd_setbluebalance(struct gspca_dev *gspca_dev, __s32 val); | ||
113 | static int sd_getbluebalance(struct gspca_dev *gspca_dev, __s32 *val); | ||
114 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); | ||
115 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); | ||
116 | static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val); | ||
117 | static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
118 | static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val); | ||
119 | static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
120 | static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val); | ||
121 | static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val); | ||
122 | static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val); | ||
123 | static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val); | ||
124 | 118 | ||
125 | static const struct ctrl sd_ctrls[] = { | 119 | static const struct ctrl sd_ctrls[] = { |
126 | { | 120 | [BRIGHTNESS] = { |
127 | { | 121 | { |
128 | .id = V4L2_CID_BRIGHTNESS, | 122 | .id = V4L2_CID_BRIGHTNESS, |
129 | .type = V4L2_CTRL_TYPE_INTEGER, | 123 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -132,13 +126,11 @@ static const struct ctrl sd_ctrls[] = { | |||
132 | #define BRIGHTNESS_MAX 0x20 | 126 | #define BRIGHTNESS_MAX 0x20 |
133 | .maximum = BRIGHTNESS_MAX, | 127 | .maximum = BRIGHTNESS_MAX, |
134 | .step = 1, | 128 | .step = 1, |
135 | #define BRIGHTNESS_DEF 0x10 | 129 | .default_value = 0x10, |
136 | .default_value = BRIGHTNESS_DEF, | ||
137 | }, | 130 | }, |
138 | .set = sd_setbrightness, | 131 | .set_control = setbrightcont |
139 | .get = sd_getbrightness, | ||
140 | }, | 132 | }, |
141 | { | 133 | [CONTRAST] = { |
142 | { | 134 | { |
143 | .id = V4L2_CID_CONTRAST, | 135 | .id = V4L2_CID_CONTRAST, |
144 | .type = V4L2_CTRL_TYPE_INTEGER, | 136 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -147,13 +139,11 @@ static const struct ctrl sd_ctrls[] = { | |||
147 | #define CONTRAST_MAX 255 | 139 | #define CONTRAST_MAX 255 |
148 | .maximum = CONTRAST_MAX, | 140 | .maximum = CONTRAST_MAX, |
149 | .step = 1, | 141 | .step = 1, |
150 | #define CONTRAST_DEF 127 | 142 | .default_value = 127, |
151 | .default_value = CONTRAST_DEF, | ||
152 | }, | 143 | }, |
153 | .set = sd_setcontrast, | 144 | .set_control = setbrightcont |
154 | .get = sd_getcontrast, | ||
155 | }, | 145 | }, |
156 | { | 146 | [COLORS] = { |
157 | { | 147 | { |
158 | .id = V4L2_CID_SATURATION, | 148 | .id = V4L2_CID_SATURATION, |
159 | .type = V4L2_CTRL_TYPE_INTEGER, | 149 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -162,13 +152,11 @@ static const struct ctrl sd_ctrls[] = { | |||
162 | #define COLOR_MAX 255 | 152 | #define COLOR_MAX 255 |
163 | .maximum = COLOR_MAX, | 153 | .maximum = COLOR_MAX, |
164 | .step = 1, | 154 | .step = 1, |
165 | #define COLOR_DEF 127 | 155 | .default_value = 127 |
166 | .default_value = COLOR_DEF, | ||
167 | }, | 156 | }, |
168 | .set = sd_setcolors, | 157 | .set_control = setcolors |
169 | .get = sd_getcolors, | ||
170 | }, | 158 | }, |
171 | { | 159 | [WHITE_BALANCE] = { |
172 | { | 160 | { |
173 | .id = V4L2_CID_WHITE_BALANCE_TEMPERATURE, | 161 | .id = V4L2_CID_WHITE_BALANCE_TEMPERATURE, |
174 | .type = V4L2_CTRL_TYPE_INTEGER, | 162 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -176,13 +164,11 @@ static const struct ctrl sd_ctrls[] = { | |||
176 | .minimum = 0, | 164 | .minimum = 0, |
177 | .maximum = 255, | 165 | .maximum = 255, |
178 | .step = 1, | 166 | .step = 1, |
179 | #define WHITEBALANCE_DEF 4 | 167 | .default_value = 4, |
180 | .default_value = WHITEBALANCE_DEF, | ||
181 | }, | 168 | }, |
182 | .set = sd_setwhitebalance, | 169 | .set_control = setwhitebalance |
183 | .get = sd_getwhitebalance, | ||
184 | }, | 170 | }, |
185 | { | 171 | [RED_BALANCE] = { |
186 | { | 172 | { |
187 | .id = V4L2_CID_RED_BALANCE, | 173 | .id = V4L2_CID_RED_BALANCE, |
188 | .type = V4L2_CTRL_TYPE_INTEGER, | 174 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -190,13 +176,11 @@ static const struct ctrl sd_ctrls[] = { | |||
190 | .minimum = 0, | 176 | .minimum = 0, |
191 | .maximum = 3, | 177 | .maximum = 3, |
192 | .step = 1, | 178 | .step = 1, |
193 | #define REDBALANCE_DEF 1 | 179 | .default_value = 1, |
194 | .default_value = REDBALANCE_DEF, | ||
195 | }, | 180 | }, |
196 | .set = sd_setredbalance, | 181 | .set_control = setredbalance |
197 | .get = sd_getredbalance, | ||
198 | }, | 182 | }, |
199 | { | 183 | [BLUE_BALANCE] = { |
200 | { | 184 | { |
201 | .id = V4L2_CID_BLUE_BALANCE, | 185 | .id = V4L2_CID_BLUE_BALANCE, |
202 | .type = V4L2_CTRL_TYPE_INTEGER, | 186 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -204,29 +188,25 @@ static const struct ctrl sd_ctrls[] = { | |||
204 | .minimum = 0, | 188 | .minimum = 0, |
205 | .maximum = 3, | 189 | .maximum = 3, |
206 | .step = 1, | 190 | .step = 1, |
207 | #define BLUEBALANCE_DEF 1 | 191 | .default_value = 1, |
208 | .default_value = BLUEBALANCE_DEF, | ||
209 | }, | 192 | }, |
210 | .set = sd_setbluebalance, | 193 | .set_control = setbluebalance |
211 | .get = sd_getbluebalance, | ||
212 | }, | 194 | }, |
213 | { | 195 | [GAIN] = { |
214 | { | 196 | { |
215 | .id = V4L2_CID_GAIN, | 197 | .id = V4L2_CID_GAIN, |
216 | .type = V4L2_CTRL_TYPE_INTEGER, | 198 | .type = V4L2_CTRL_TYPE_INTEGER, |
217 | .name = "Gain", | 199 | .name = "Gain", |
218 | .minimum = 0, | 200 | .minimum = 0, |
219 | #define GAIN_MAX 255 | 201 | .maximum = 255, |
220 | .maximum = GAIN_MAX, | ||
221 | .step = 1, | 202 | .step = 1, |
222 | #define GAIN_DEF 127 | 203 | #define GAIN_DEF 127 |
223 | #define GAIN_KNEE 255 /* Gain seems to cause little noise on the pac73xx */ | 204 | #define GAIN_KNEE 255 /* Gain seems to cause little noise on the pac73xx */ |
224 | .default_value = GAIN_DEF, | 205 | .default_value = GAIN_DEF, |
225 | }, | 206 | }, |
226 | .set = sd_setgain, | 207 | .set_control = setgain |
227 | .get = sd_getgain, | ||
228 | }, | 208 | }, |
229 | { | 209 | [EXPOSURE] = { |
230 | { | 210 | { |
231 | .id = V4L2_CID_EXPOSURE, | 211 | .id = V4L2_CID_EXPOSURE, |
232 | .type = V4L2_CTRL_TYPE_INTEGER, | 212 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -238,10 +218,9 @@ static const struct ctrl sd_ctrls[] = { | |||
238 | #define EXPOSURE_KNEE 133 /* 66 ms / 15 fps */ | 218 | #define EXPOSURE_KNEE 133 /* 66 ms / 15 fps */ |
239 | .default_value = EXPOSURE_DEF, | 219 | .default_value = EXPOSURE_DEF, |
240 | }, | 220 | }, |
241 | .set = sd_setexposure, | 221 | .set_control = setexposure |
242 | .get = sd_getexposure, | ||
243 | }, | 222 | }, |
244 | { | 223 | [AUTOGAIN] = { |
245 | { | 224 | { |
246 | .id = V4L2_CID_AUTOGAIN, | 225 | .id = V4L2_CID_AUTOGAIN, |
247 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 226 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
@@ -252,10 +231,9 @@ static const struct ctrl sd_ctrls[] = { | |||
252 | #define AUTOGAIN_DEF 1 | 231 | #define AUTOGAIN_DEF 1 |
253 | .default_value = AUTOGAIN_DEF, | 232 | .default_value = AUTOGAIN_DEF, |
254 | }, | 233 | }, |
255 | .set = sd_setautogain, | 234 | .set_control = setautogain, |
256 | .get = sd_getautogain, | ||
257 | }, | 235 | }, |
258 | { | 236 | [HFLIP] = { |
259 | { | 237 | { |
260 | .id = V4L2_CID_HFLIP, | 238 | .id = V4L2_CID_HFLIP, |
261 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 239 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
@@ -263,13 +241,11 @@ static const struct ctrl sd_ctrls[] = { | |||
263 | .minimum = 0, | 241 | .minimum = 0, |
264 | .maximum = 1, | 242 | .maximum = 1, |
265 | .step = 1, | 243 | .step = 1, |
266 | #define HFLIP_DEF 0 | 244 | .default_value = 0, |
267 | .default_value = HFLIP_DEF, | ||
268 | }, | 245 | }, |
269 | .set = sd_sethflip, | 246 | .set_control = sethvflip, |
270 | .get = sd_gethflip, | ||
271 | }, | 247 | }, |
272 | { | 248 | [VFLIP] = { |
273 | { | 249 | { |
274 | .id = V4L2_CID_VFLIP, | 250 | .id = V4L2_CID_VFLIP, |
275 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 251 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
@@ -277,11 +253,9 @@ static const struct ctrl sd_ctrls[] = { | |||
277 | .minimum = 0, | 253 | .minimum = 0, |
278 | .maximum = 1, | 254 | .maximum = 1, |
279 | .step = 1, | 255 | .step = 1, |
280 | #define VFLIP_DEF 0 | 256 | .default_value = 0, |
281 | .default_value = VFLIP_DEF, | ||
282 | }, | 257 | }, |
283 | .set = sd_setvflip, | 258 | .set_control = sethvflip |
284 | .get = sd_getvflip, | ||
285 | }, | 259 | }, |
286 | }; | 260 | }; |
287 | 261 | ||
@@ -290,21 +264,21 @@ static const struct v4l2_pix_format vga_mode[] = { | |||
290 | .bytesperline = 640, | 264 | .bytesperline = 640, |
291 | .sizeimage = 640 * 480 * 3 / 8 + 590, | 265 | .sizeimage = 640 * 480 * 3 / 8 + 590, |
292 | .colorspace = V4L2_COLORSPACE_JPEG, | 266 | .colorspace = V4L2_COLORSPACE_JPEG, |
293 | .priv = 0}, | 267 | }, |
294 | }; | 268 | }; |
295 | 269 | ||
296 | #define LOAD_PAGE3 255 | 270 | #define LOAD_PAGE3 255 |
297 | #define END_OF_SEQUENCE 0 | 271 | #define END_OF_SEQUENCE 0 |
298 | 272 | ||
299 | /* pac 7302 */ | 273 | /* pac 7302 */ |
300 | static const __u8 init_7302[] = { | 274 | static const u8 init_7302[] = { |
301 | /* index,value */ | 275 | /* index,value */ |
302 | 0xff, 0x01, /* page 1 */ | 276 | 0xff, 0x01, /* page 1 */ |
303 | 0x78, 0x00, /* deactivate */ | 277 | 0x78, 0x00, /* deactivate */ |
304 | 0xff, 0x01, | 278 | 0xff, 0x01, |
305 | 0x78, 0x40, /* led off */ | 279 | 0x78, 0x40, /* led off */ |
306 | }; | 280 | }; |
307 | static const __u8 start_7302[] = { | 281 | static const u8 start_7302[] = { |
308 | /* index, len, [value]* */ | 282 | /* index, len, [value]* */ |
309 | 0xff, 1, 0x00, /* page 0 */ | 283 | 0xff, 1, 0x00, /* page 0 */ |
310 | 0x00, 12, 0x01, 0x40, 0x40, 0x40, 0x01, 0xe0, 0x02, 0x80, | 284 | 0x00, 12, 0x01, 0x40, 0x40, 0x40, 0x01, 0xe0, 0x02, 0x80, |
@@ -319,7 +293,7 @@ static const __u8 start_7302[] = { | |||
319 | 0x43, 11, 0x00, 0x0a, 0x18, 0x11, 0x01, 0x2c, 0x88, 0x11, | 293 | 0x43, 11, 0x00, 0x0a, 0x18, 0x11, 0x01, 0x2c, 0x88, 0x11, |
320 | 0x00, 0x54, 0x11, | 294 | 0x00, 0x54, 0x11, |
321 | 0x55, 1, 0x00, | 295 | 0x55, 1, 0x00, |
322 | 0x62, 4, 0x10, 0x1e, 0x1e, 0x18, | 296 | 0x62, 4, 0x10, 0x1e, 0x1e, 0x18, |
323 | 0x6b, 1, 0x00, | 297 | 0x6b, 1, 0x00, |
324 | 0x6e, 3, 0x08, 0x06, 0x00, | 298 | 0x6e, 3, 0x08, 0x06, 0x00, |
325 | 0x72, 3, 0x00, 0xff, 0x00, | 299 | 0x72, 3, 0x00, 0xff, 0x00, |
@@ -370,7 +344,7 @@ static const __u8 start_7302[] = { | |||
370 | 344 | ||
371 | #define SKIP 0xaa | 345 | #define SKIP 0xaa |
372 | /* page 3 - the value SKIP says skip the index - see reg_w_page() */ | 346 | /* page 3 - the value SKIP says skip the index - see reg_w_page() */ |
373 | static const __u8 page3_7302[] = { | 347 | static const u8 page3_7302[] = { |
374 | 0x90, 0x40, 0x03, 0x00, 0xc0, 0x01, 0x14, 0x16, | 348 | 0x90, 0x40, 0x03, 0x00, 0xc0, 0x01, 0x14, 0x16, |
375 | 0x14, 0x12, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00, | 349 | 0x14, 0x12, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00, |
376 | 0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 350 | 0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
@@ -394,7 +368,7 @@ static const __u8 page3_7302[] = { | |||
394 | }; | 368 | }; |
395 | 369 | ||
396 | static void reg_w_buf(struct gspca_dev *gspca_dev, | 370 | static void reg_w_buf(struct gspca_dev *gspca_dev, |
397 | __u8 index, | 371 | u8 index, |
398 | const u8 *buffer, int len) | 372 | const u8 *buffer, int len) |
399 | { | 373 | { |
400 | int ret; | 374 | int ret; |
@@ -410,7 +384,7 @@ static void reg_w_buf(struct gspca_dev *gspca_dev, | |||
410 | index, gspca_dev->usb_buf, len, | 384 | index, gspca_dev->usb_buf, len, |
411 | 500); | 385 | 500); |
412 | if (ret < 0) { | 386 | if (ret < 0) { |
413 | pr_err("reg_w_buf failed index 0x%02x, error %d\n", | 387 | pr_err("reg_w_buf failed i: %02x error %d\n", |
414 | index, ret); | 388 | index, ret); |
415 | gspca_dev->usb_err = ret; | 389 | gspca_dev->usb_err = ret; |
416 | } | 390 | } |
@@ -418,8 +392,8 @@ static void reg_w_buf(struct gspca_dev *gspca_dev, | |||
418 | 392 | ||
419 | 393 | ||
420 | static void reg_w(struct gspca_dev *gspca_dev, | 394 | static void reg_w(struct gspca_dev *gspca_dev, |
421 | __u8 index, | 395 | u8 index, |
422 | __u8 value) | 396 | u8 value) |
423 | { | 397 | { |
424 | int ret; | 398 | int ret; |
425 | 399 | ||
@@ -433,14 +407,14 @@ static void reg_w(struct gspca_dev *gspca_dev, | |||
433 | 0, index, gspca_dev->usb_buf, 1, | 407 | 0, index, gspca_dev->usb_buf, 1, |
434 | 500); | 408 | 500); |
435 | if (ret < 0) { | 409 | if (ret < 0) { |
436 | pr_err("reg_w() failed index 0x%02x, value 0x%02x, error %d\n", | 410 | pr_err("reg_w() failed i: %02x v: %02x error %d\n", |
437 | index, value, ret); | 411 | index, value, ret); |
438 | gspca_dev->usb_err = ret; | 412 | gspca_dev->usb_err = ret; |
439 | } | 413 | } |
440 | } | 414 | } |
441 | 415 | ||
442 | static void reg_w_seq(struct gspca_dev *gspca_dev, | 416 | static void reg_w_seq(struct gspca_dev *gspca_dev, |
443 | const __u8 *seq, int len) | 417 | const u8 *seq, int len) |
444 | { | 418 | { |
445 | while (--len >= 0) { | 419 | while (--len >= 0) { |
446 | reg_w(gspca_dev, seq[0], seq[1]); | 420 | reg_w(gspca_dev, seq[0], seq[1]); |
@@ -450,7 +424,7 @@ static void reg_w_seq(struct gspca_dev *gspca_dev, | |||
450 | 424 | ||
451 | /* load the beginning of a page */ | 425 | /* load the beginning of a page */ |
452 | static void reg_w_page(struct gspca_dev *gspca_dev, | 426 | static void reg_w_page(struct gspca_dev *gspca_dev, |
453 | const __u8 *page, int len) | 427 | const u8 *page, int len) |
454 | { | 428 | { |
455 | int index; | 429 | int index; |
456 | int ret = 0; | 430 | int ret = 0; |
@@ -468,7 +442,7 @@ static void reg_w_page(struct gspca_dev *gspca_dev, | |||
468 | 0, index, gspca_dev->usb_buf, 1, | 442 | 0, index, gspca_dev->usb_buf, 1, |
469 | 500); | 443 | 500); |
470 | if (ret < 0) { | 444 | if (ret < 0) { |
471 | pr_err("reg_w_page() failed index 0x%02x, value 0x%02x, error %d\n", | 445 | pr_err("reg_w_page() failed i: %02x v: %02x error %d\n", |
472 | index, page[index], ret); | 446 | index, page[index], ret); |
473 | gspca_dev->usb_err = ret; | 447 | gspca_dev->usb_err = ret; |
474 | break; | 448 | break; |
@@ -478,8 +452,8 @@ static void reg_w_page(struct gspca_dev *gspca_dev, | |||
478 | 452 | ||
479 | /* output a variable sequence */ | 453 | /* output a variable sequence */ |
480 | static void reg_w_var(struct gspca_dev *gspca_dev, | 454 | static void reg_w_var(struct gspca_dev *gspca_dev, |
481 | const __u8 *seq, | 455 | const u8 *seq, |
482 | const __u8 *page3, unsigned int page3_len) | 456 | const u8 *page3, unsigned int page3_len) |
483 | { | 457 | { |
484 | int index, len; | 458 | int index, len; |
485 | 459 | ||
@@ -493,11 +467,13 @@ static void reg_w_var(struct gspca_dev *gspca_dev, | |||
493 | reg_w_page(gspca_dev, page3, page3_len); | 467 | reg_w_page(gspca_dev, page3, page3_len); |
494 | break; | 468 | break; |
495 | default: | 469 | default: |
470 | #ifdef GSPCA_DEBUG | ||
496 | if (len > USB_BUF_SZ) { | 471 | if (len > USB_BUF_SZ) { |
497 | PDEBUG(D_ERR|D_STREAM, | 472 | PDEBUG(D_ERR|D_STREAM, |
498 | "Incorrect variable sequence"); | 473 | "Incorrect variable sequence"); |
499 | return; | 474 | return; |
500 | } | 475 | } |
476 | #endif | ||
501 | while (len > 0) { | 477 | while (len > 0) { |
502 | if (len < 8) { | 478 | if (len < 8) { |
503 | reg_w_buf(gspca_dev, | 479 | reg_w_buf(gspca_dev, |
@@ -524,21 +500,11 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
524 | 500 | ||
525 | cam = &gspca_dev->cam; | 501 | cam = &gspca_dev->cam; |
526 | 502 | ||
527 | PDEBUG(D_CONF, "Find Sensor PAC7302"); | ||
528 | cam->cam_mode = vga_mode; /* only 640x480 */ | 503 | cam->cam_mode = vga_mode; /* only 640x480 */ |
529 | cam->nmodes = ARRAY_SIZE(vga_mode); | 504 | cam->nmodes = ARRAY_SIZE(vga_mode); |
530 | 505 | ||
531 | sd->brightness = BRIGHTNESS_DEF; | 506 | gspca_dev->cam.ctrls = sd->ctrls; |
532 | sd->contrast = CONTRAST_DEF; | 507 | |
533 | sd->colors = COLOR_DEF; | ||
534 | sd->white_balance = WHITEBALANCE_DEF; | ||
535 | sd->red_balance = REDBALANCE_DEF; | ||
536 | sd->blue_balance = BLUEBALANCE_DEF; | ||
537 | sd->gain = GAIN_DEF; | ||
538 | sd->exposure = EXPOSURE_DEF; | ||
539 | sd->autogain = AUTOGAIN_DEF; | ||
540 | sd->hflip = HFLIP_DEF; | ||
541 | sd->vflip = VFLIP_DEF; | ||
542 | sd->flags = id->driver_info; | 508 | sd->flags = id->driver_info; |
543 | return 0; | 509 | return 0; |
544 | } | 510 | } |
@@ -548,19 +514,19 @@ static void setbrightcont(struct gspca_dev *gspca_dev) | |||
548 | { | 514 | { |
549 | struct sd *sd = (struct sd *) gspca_dev; | 515 | struct sd *sd = (struct sd *) gspca_dev; |
550 | int i, v; | 516 | int i, v; |
551 | static const __u8 max[10] = | 517 | static const u8 max[10] = |
552 | {0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb, | 518 | {0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb, |
553 | 0xd4, 0xec}; | 519 | 0xd4, 0xec}; |
554 | static const __u8 delta[10] = | 520 | static const u8 delta[10] = |
555 | {0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17, | 521 | {0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17, |
556 | 0x11, 0x0b}; | 522 | 0x11, 0x0b}; |
557 | 523 | ||
558 | reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ | 524 | reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ |
559 | for (i = 0; i < 10; i++) { | 525 | for (i = 0; i < 10; i++) { |
560 | v = max[i]; | 526 | v = max[i]; |
561 | v += (sd->brightness - BRIGHTNESS_MAX) | 527 | v += (sd->ctrls[BRIGHTNESS].val - BRIGHTNESS_MAX) |
562 | * 150 / BRIGHTNESS_MAX; /* 200 ? */ | 528 | * 150 / BRIGHTNESS_MAX; /* 200 ? */ |
563 | v -= delta[i] * sd->contrast / CONTRAST_MAX; | 529 | v -= delta[i] * sd->ctrls[CONTRAST].val / CONTRAST_MAX; |
564 | if (v < 0) | 530 | if (v < 0) |
565 | v = 0; | 531 | v = 0; |
566 | else if (v > 0xff) | 532 | else if (v > 0xff) |
@@ -584,12 +550,11 @@ static void setcolors(struct gspca_dev *gspca_dev) | |||
584 | reg_w(gspca_dev, 0x11, 0x01); | 550 | reg_w(gspca_dev, 0x11, 0x01); |
585 | reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ | 551 | reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ |
586 | for (i = 0; i < 9; i++) { | 552 | for (i = 0; i < 9; i++) { |
587 | v = a[i] * sd->colors / COLOR_MAX + b[i]; | 553 | v = a[i] * sd->ctrls[COLORS].val / COLOR_MAX + b[i]; |
588 | reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07); | 554 | reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07); |
589 | reg_w(gspca_dev, 0x0f + 2 * i + 1, v); | 555 | reg_w(gspca_dev, 0x0f + 2 * i + 1, v); |
590 | } | 556 | } |
591 | reg_w(gspca_dev, 0xdc, 0x01); | 557 | reg_w(gspca_dev, 0xdc, 0x01); |
592 | PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors); | ||
593 | } | 558 | } |
594 | 559 | ||
595 | static void setwhitebalance(struct gspca_dev *gspca_dev) | 560 | static void setwhitebalance(struct gspca_dev *gspca_dev) |
@@ -597,10 +562,9 @@ static void setwhitebalance(struct gspca_dev *gspca_dev) | |||
597 | struct sd *sd = (struct sd *) gspca_dev; | 562 | struct sd *sd = (struct sd *) gspca_dev; |
598 | 563 | ||
599 | reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ | 564 | reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ |
600 | reg_w(gspca_dev, 0xc6, sd->white_balance); | 565 | reg_w(gspca_dev, 0xc6, sd->ctrls[WHITE_BALANCE].val); |
601 | 566 | ||
602 | reg_w(gspca_dev, 0xdc, 0x01); | 567 | reg_w(gspca_dev, 0xdc, 0x01); |
603 | PDEBUG(D_CONF|D_STREAM, "white_balance: %i", sd->white_balance); | ||
604 | } | 568 | } |
605 | 569 | ||
606 | static void setredbalance(struct gspca_dev *gspca_dev) | 570 | static void setredbalance(struct gspca_dev *gspca_dev) |
@@ -608,10 +572,9 @@ static void setredbalance(struct gspca_dev *gspca_dev) | |||
608 | struct sd *sd = (struct sd *) gspca_dev; | 572 | struct sd *sd = (struct sd *) gspca_dev; |
609 | 573 | ||
610 | reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ | 574 | reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ |
611 | reg_w(gspca_dev, 0xc5, sd->red_balance); | 575 | reg_w(gspca_dev, 0xc5, sd->ctrls[RED_BALANCE].val); |
612 | 576 | ||
613 | reg_w(gspca_dev, 0xdc, 0x01); | 577 | reg_w(gspca_dev, 0xdc, 0x01); |
614 | PDEBUG(D_CONF|D_STREAM, "red_balance: %i", sd->red_balance); | ||
615 | } | 578 | } |
616 | 579 | ||
617 | static void setbluebalance(struct gspca_dev *gspca_dev) | 580 | static void setbluebalance(struct gspca_dev *gspca_dev) |
@@ -619,10 +582,9 @@ static void setbluebalance(struct gspca_dev *gspca_dev) | |||
619 | struct sd *sd = (struct sd *) gspca_dev; | 582 | struct sd *sd = (struct sd *) gspca_dev; |
620 | 583 | ||
621 | reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ | 584 | reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ |
622 | reg_w(gspca_dev, 0xc7, sd->blue_balance); | 585 | reg_w(gspca_dev, 0xc7, sd->ctrls[BLUE_BALANCE].val); |
623 | 586 | ||
624 | reg_w(gspca_dev, 0xdc, 0x01); | 587 | reg_w(gspca_dev, 0xdc, 0x01); |
625 | PDEBUG(D_CONF|D_STREAM, "blue_balance: %i", sd->blue_balance); | ||
626 | } | 588 | } |
627 | 589 | ||
628 | static void setgain(struct gspca_dev *gspca_dev) | 590 | static void setgain(struct gspca_dev *gspca_dev) |
@@ -630,7 +592,7 @@ static void setgain(struct gspca_dev *gspca_dev) | |||
630 | struct sd *sd = (struct sd *) gspca_dev; | 592 | struct sd *sd = (struct sd *) gspca_dev; |
631 | 593 | ||
632 | reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ | 594 | reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ |
633 | reg_w(gspca_dev, 0x10, sd->gain >> 3); | 595 | reg_w(gspca_dev, 0x10, sd->ctrls[GAIN].val >> 3); |
634 | 596 | ||
635 | /* load registers to sensor (Bit 0, auto clear) */ | 597 | /* load registers to sensor (Bit 0, auto clear) */ |
636 | reg_w(gspca_dev, 0x11, 0x01); | 598 | reg_w(gspca_dev, 0x11, 0x01); |
@@ -639,13 +601,13 @@ static void setgain(struct gspca_dev *gspca_dev) | |||
639 | static void setexposure(struct gspca_dev *gspca_dev) | 601 | static void setexposure(struct gspca_dev *gspca_dev) |
640 | { | 602 | { |
641 | struct sd *sd = (struct sd *) gspca_dev; | 603 | struct sd *sd = (struct sd *) gspca_dev; |
642 | __u8 clockdiv; | 604 | u8 clockdiv; |
643 | __u16 exposure; | 605 | u16 exposure; |
644 | 606 | ||
645 | /* register 2 of frame 3 contains the clock divider configuring the | 607 | /* register 2 of frame 3 contains the clock divider configuring the |
646 | no fps according to the formula: 90 / reg. sd->exposure is the | 608 | no fps according to the formula: 90 / reg. sd->exposure is the |
647 | desired exposure time in 0.5 ms. */ | 609 | desired exposure time in 0.5 ms. */ |
648 | clockdiv = (90 * sd->exposure + 1999) / 2000; | 610 | clockdiv = (90 * sd->ctrls[EXPOSURE].val + 1999) / 2000; |
649 | 611 | ||
650 | /* Note clockdiv = 3 also works, but when running at 30 fps, depending | 612 | /* Note clockdiv = 3 also works, but when running at 30 fps, depending |
651 | on the scene being recorded, the camera switches to another | 613 | on the scene being recorded, the camera switches to another |
@@ -664,7 +626,7 @@ static void setexposure(struct gspca_dev *gspca_dev) | |||
664 | 626 | ||
665 | /* frame exposure time in ms = 1000 * clockdiv / 90 -> | 627 | /* frame exposure time in ms = 1000 * clockdiv / 90 -> |
666 | exposure = (sd->exposure / 2) * 448 / (1000 * clockdiv / 90) */ | 628 | exposure = (sd->exposure / 2) * 448 / (1000 * clockdiv / 90) */ |
667 | exposure = (sd->exposure * 45 * 448) / (1000 * clockdiv); | 629 | exposure = (sd->ctrls[EXPOSURE].val * 45 * 448) / (1000 * clockdiv); |
668 | /* 0 = use full frametime, 448 = no exposure, reverse it */ | 630 | /* 0 = use full frametime, 448 = no exposure, reverse it */ |
669 | exposure = 448 - exposure; | 631 | exposure = 448 - exposure; |
670 | 632 | ||
@@ -677,15 +639,35 @@ static void setexposure(struct gspca_dev *gspca_dev) | |||
677 | reg_w(gspca_dev, 0x11, 0x01); | 639 | reg_w(gspca_dev, 0x11, 0x01); |
678 | } | 640 | } |
679 | 641 | ||
642 | static void setautogain(struct gspca_dev *gspca_dev) | ||
643 | { | ||
644 | struct sd *sd = (struct sd *) gspca_dev; | ||
645 | |||
646 | /* when switching to autogain set defaults to make sure | ||
647 | we are on a valid point of the autogain gain / | ||
648 | exposure knee graph, and give this change time to | ||
649 | take effect before doing autogain. */ | ||
650 | if (sd->ctrls[AUTOGAIN].val) { | ||
651 | sd->ctrls[EXPOSURE].val = EXPOSURE_DEF; | ||
652 | sd->ctrls[GAIN].val = GAIN_DEF; | ||
653 | sd->autogain_ignore_frames = | ||
654 | PAC_AUTOGAIN_IGNORE_FRAMES; | ||
655 | } else { | ||
656 | sd->autogain_ignore_frames = -1; | ||
657 | } | ||
658 | setexposure(gspca_dev); | ||
659 | setgain(gspca_dev); | ||
660 | } | ||
661 | |||
680 | static void sethvflip(struct gspca_dev *gspca_dev) | 662 | static void sethvflip(struct gspca_dev *gspca_dev) |
681 | { | 663 | { |
682 | struct sd *sd = (struct sd *) gspca_dev; | 664 | struct sd *sd = (struct sd *) gspca_dev; |
683 | u8 data, hflip, vflip; | 665 | u8 data, hflip, vflip; |
684 | 666 | ||
685 | hflip = sd->hflip; | 667 | hflip = sd->ctrls[HFLIP].val; |
686 | if (sd->flags & FL_HFLIP) | 668 | if (sd->flags & FL_HFLIP) |
687 | hflip = !hflip; | 669 | hflip = !hflip; |
688 | vflip = sd->vflip; | 670 | vflip = sd->ctrls[VFLIP].val; |
689 | if (sd->flags & FL_VFLIP) | 671 | if (sd->flags & FL_VFLIP) |
690 | vflip = !vflip; | 672 | vflip = !vflip; |
691 | 673 | ||
@@ -708,8 +690,6 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
708 | { | 690 | { |
709 | struct sd *sd = (struct sd *) gspca_dev; | 691 | struct sd *sd = (struct sd *) gspca_dev; |
710 | 692 | ||
711 | sd->sof_read = 0; | ||
712 | |||
713 | reg_w_var(gspca_dev, start_7302, | 693 | reg_w_var(gspca_dev, start_7302, |
714 | page3_7302, sizeof(page3_7302)); | 694 | page3_7302, sizeof(page3_7302)); |
715 | setbrightcont(gspca_dev); | 695 | setbrightcont(gspca_dev); |
@@ -717,15 +697,13 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
717 | setwhitebalance(gspca_dev); | 697 | setwhitebalance(gspca_dev); |
718 | setredbalance(gspca_dev); | 698 | setredbalance(gspca_dev); |
719 | setbluebalance(gspca_dev); | 699 | setbluebalance(gspca_dev); |
720 | setgain(gspca_dev); | 700 | setautogain(gspca_dev); |
721 | setexposure(gspca_dev); | ||
722 | sethvflip(gspca_dev); | 701 | sethvflip(gspca_dev); |
723 | 702 | ||
724 | /* only resolution 640x480 is supported for pac7302 */ | 703 | /* only resolution 640x480 is supported for pac7302 */ |
725 | 704 | ||
726 | sd->sof_read = 0; | 705 | sd->sof_read = 0; |
727 | sd->autogain_ignore_frames = 0; | 706 | atomic_set(&sd->avg_lum, 270 + sd->ctrls[BRIGHTNESS].val); |
728 | atomic_set(&sd->avg_lum, -1); | ||
729 | 707 | ||
730 | /* start stream */ | 708 | /* start stream */ |
731 | reg_w(gspca_dev, 0xff, 0x01); | 709 | reg_w(gspca_dev, 0xff, 0x01); |
@@ -751,8 +729,10 @@ static void sd_stop0(struct gspca_dev *gspca_dev) | |||
751 | reg_w(gspca_dev, 0x78, 0x40); | 729 | reg_w(gspca_dev, 0x78, 0x40); |
752 | } | 730 | } |
753 | 731 | ||
754 | /* Include pac common sof detection functions */ | 732 | /* !! coarse_grained_expo_autogain is not used !! */ |
755 | #include "pac_common.h" | 733 | #define exp_too_low_cnt flags |
734 | #define exp_too_high_cnt sof_read | ||
735 | #include "autogain_functions.h" | ||
756 | 736 | ||
757 | static void do_autogain(struct gspca_dev *gspca_dev) | 737 | static void do_autogain(struct gspca_dev *gspca_dev) |
758 | { | 738 | { |
@@ -761,65 +741,44 @@ static void do_autogain(struct gspca_dev *gspca_dev) | |||
761 | int desired_lum; | 741 | int desired_lum; |
762 | const int deadzone = 30; | 742 | const int deadzone = 30; |
763 | 743 | ||
764 | if (avg_lum == -1) | 744 | if (sd->autogain_ignore_frames < 0) |
765 | return; | 745 | return; |
766 | 746 | ||
767 | desired_lum = 270 + sd->brightness; | 747 | if (sd->autogain_ignore_frames > 0) { |
768 | |||
769 | if (sd->autogain_ignore_frames > 0) | ||
770 | sd->autogain_ignore_frames--; | 748 | sd->autogain_ignore_frames--; |
771 | else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum, desired_lum, | 749 | } else { |
772 | deadzone, GAIN_KNEE, EXPOSURE_KNEE)) | 750 | desired_lum = 270 + sd->ctrls[BRIGHTNESS].val; |
751 | |||
752 | auto_gain_n_exposure(gspca_dev, avg_lum, desired_lum, | ||
753 | deadzone, GAIN_KNEE, EXPOSURE_KNEE); | ||
773 | sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES; | 754 | sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES; |
755 | } | ||
774 | } | 756 | } |
775 | 757 | ||
776 | /* JPEG header, part 1 */ | 758 | /* JPEG header */ |
777 | static const unsigned char pac_jpeg_header1[] = { | 759 | static const u8 jpeg_header[] = { |
778 | 0xff, 0xd8, /* SOI: Start of Image */ | 760 | 0xff, 0xd8, /* SOI: Start of Image */ |
779 | 761 | ||
780 | 0xff, 0xc0, /* SOF0: Start of Frame (Baseline DCT) */ | 762 | 0xff, 0xc0, /* SOF0: Start of Frame (Baseline DCT) */ |
781 | 0x00, 0x11, /* length = 17 bytes (including this length field) */ | 763 | 0x00, 0x11, /* length = 17 bytes (including this length field) */ |
782 | 0x08 /* Precision: 8 */ | 764 | 0x08, /* Precision: 8 */ |
783 | /* 2 bytes is placed here: number of image lines */ | 765 | 0x02, 0x80, /* height = 640 (image rotated) */ |
784 | /* 2 bytes is placed here: samples per line */ | 766 | 0x01, 0xe0, /* width = 480 */ |
785 | }; | 767 | 0x03, /* Number of image components: 3 */ |
786 | 768 | 0x01, 0x21, 0x00, /* ID=1, Subsampling 1x1, Quantization table: 0 */ | |
787 | /* JPEG header, continued */ | 769 | 0x02, 0x11, 0x01, /* ID=2, Subsampling 2x1, Quantization table: 1 */ |
788 | static const unsigned char pac_jpeg_header2[] = { | 770 | 0x03, 0x11, 0x01, /* ID=3, Subsampling 2x1, Quantization table: 1 */ |
789 | 0x03, /* Number of image components: 3 */ | 771 | |
790 | 0x01, 0x21, 0x00, /* ID=1, Subsampling 1x1, Quantization table: 0 */ | 772 | 0xff, 0xda, /* SOS: Start Of Scan */ |
791 | 0x02, 0x11, 0x01, /* ID=2, Subsampling 2x1, Quantization table: 1 */ | 773 | 0x00, 0x0c, /* length = 12 bytes (including this length field) */ |
792 | 0x03, 0x11, 0x01, /* ID=3, Subsampling 2x1, Quantization table: 1 */ | 774 | 0x03, /* number of components: 3 */ |
793 | 775 | 0x01, 0x00, /* selector 1, table 0x00 */ | |
794 | 0xff, 0xda, /* SOS: Start Of Scan */ | 776 | 0x02, 0x11, /* selector 2, table 0x11 */ |
795 | 0x00, 0x0c, /* length = 12 bytes (including this length field) */ | 777 | 0x03, 0x11, /* selector 3, table 0x11 */ |
796 | 0x03, /* number of components: 3 */ | 778 | 0x00, 0x3f, /* Spectral selection: 0 .. 63 */ |
797 | 0x01, 0x00, /* selector 1, table 0x00 */ | 779 | 0x00 /* Successive approximation: 0 */ |
798 | 0x02, 0x11, /* selector 2, table 0x11 */ | ||
799 | 0x03, 0x11, /* selector 3, table 0x11 */ | ||
800 | 0x00, 0x3f, /* Spectral selection: 0 .. 63 */ | ||
801 | 0x00 /* Successive approximation: 0 */ | ||
802 | }; | 780 | }; |
803 | 781 | ||
804 | static void pac_start_frame(struct gspca_dev *gspca_dev, | ||
805 | __u16 lines, __u16 samples_per_line) | ||
806 | { | ||
807 | unsigned char tmpbuf[4]; | ||
808 | |||
809 | gspca_frame_add(gspca_dev, FIRST_PACKET, | ||
810 | pac_jpeg_header1, sizeof(pac_jpeg_header1)); | ||
811 | |||
812 | tmpbuf[0] = lines >> 8; | ||
813 | tmpbuf[1] = lines & 0xff; | ||
814 | tmpbuf[2] = samples_per_line >> 8; | ||
815 | tmpbuf[3] = samples_per_line & 0xff; | ||
816 | |||
817 | gspca_frame_add(gspca_dev, INTER_PACKET, | ||
818 | tmpbuf, sizeof(tmpbuf)); | ||
819 | gspca_frame_add(gspca_dev, INTER_PACKET, | ||
820 | pac_jpeg_header2, sizeof(pac_jpeg_header2)); | ||
821 | } | ||
822 | |||
823 | /* this function is run at interrupt level */ | 782 | /* this function is run at interrupt level */ |
824 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | 783 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, |
825 | u8 *data, /* isoc packet */ | 784 | u8 *data, /* isoc packet */ |
@@ -827,7 +786,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
827 | { | 786 | { |
828 | struct sd *sd = (struct sd *) gspca_dev; | 787 | struct sd *sd = (struct sd *) gspca_dev; |
829 | u8 *image; | 788 | u8 *image; |
830 | unsigned char *sof; | 789 | u8 *sof; |
831 | 790 | ||
832 | sof = pac_find_sof(&sd->sof_read, data, len); | 791 | sof = pac_find_sof(&sd->sof_read, data, len); |
833 | if (sof) { | 792 | if (sof) { |
@@ -864,234 +823,21 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
864 | n >= lum_offset) | 823 | n >= lum_offset) |
865 | atomic_set(&sd->avg_lum, data[-lum_offset] + | 824 | atomic_set(&sd->avg_lum, data[-lum_offset] + |
866 | data[-lum_offset + 1]); | 825 | data[-lum_offset + 1]); |
867 | else | ||
868 | atomic_set(&sd->avg_lum, -1); | ||
869 | 826 | ||
870 | /* Start the new frame with the jpeg header */ | 827 | /* Start the new frame with the jpeg header */ |
871 | /* The PAC7302 has the image rotated 90 degrees */ | 828 | /* The PAC7302 has the image rotated 90 degrees */ |
872 | pac_start_frame(gspca_dev, | 829 | gspca_frame_add(gspca_dev, FIRST_PACKET, |
873 | gspca_dev->width, gspca_dev->height); | 830 | jpeg_header, sizeof jpeg_header); |
874 | } | 831 | } |
875 | gspca_frame_add(gspca_dev, INTER_PACKET, data, len); | 832 | gspca_frame_add(gspca_dev, INTER_PACKET, data, len); |
876 | } | 833 | } |
877 | 834 | ||
878 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | ||
879 | { | ||
880 | struct sd *sd = (struct sd *) gspca_dev; | ||
881 | |||
882 | sd->brightness = val; | ||
883 | if (gspca_dev->streaming) | ||
884 | setbrightcont(gspca_dev); | ||
885 | return gspca_dev->usb_err; | ||
886 | } | ||
887 | |||
888 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
889 | { | ||
890 | struct sd *sd = (struct sd *) gspca_dev; | ||
891 | |||
892 | *val = sd->brightness; | ||
893 | return 0; | ||
894 | } | ||
895 | |||
896 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | ||
897 | { | ||
898 | struct sd *sd = (struct sd *) gspca_dev; | ||
899 | |||
900 | sd->contrast = val; | ||
901 | if (gspca_dev->streaming) | ||
902 | setbrightcont(gspca_dev); | ||
903 | return gspca_dev->usb_err; | ||
904 | } | ||
905 | |||
906 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) | ||
907 | { | ||
908 | struct sd *sd = (struct sd *) gspca_dev; | ||
909 | |||
910 | *val = sd->contrast; | ||
911 | return 0; | ||
912 | } | ||
913 | |||
914 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) | ||
915 | { | ||
916 | struct sd *sd = (struct sd *) gspca_dev; | ||
917 | |||
918 | sd->colors = val; | ||
919 | if (gspca_dev->streaming) | ||
920 | setcolors(gspca_dev); | ||
921 | return gspca_dev->usb_err; | ||
922 | } | ||
923 | |||
924 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) | ||
925 | { | ||
926 | struct sd *sd = (struct sd *) gspca_dev; | ||
927 | |||
928 | *val = sd->colors; | ||
929 | return 0; | ||
930 | } | ||
931 | |||
932 | static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val) | ||
933 | { | ||
934 | struct sd *sd = (struct sd *) gspca_dev; | ||
935 | |||
936 | sd->white_balance = val; | ||
937 | if (gspca_dev->streaming) | ||
938 | setwhitebalance(gspca_dev); | ||
939 | return gspca_dev->usb_err; | ||
940 | } | ||
941 | |||
942 | static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val) | ||
943 | { | ||
944 | struct sd *sd = (struct sd *) gspca_dev; | ||
945 | |||
946 | *val = sd->white_balance; | ||
947 | return 0; | ||
948 | } | ||
949 | |||
950 | static int sd_setredbalance(struct gspca_dev *gspca_dev, __s32 val) | ||
951 | { | ||
952 | struct sd *sd = (struct sd *) gspca_dev; | ||
953 | |||
954 | sd->red_balance = val; | ||
955 | if (gspca_dev->streaming) | ||
956 | setredbalance(gspca_dev); | ||
957 | return gspca_dev->usb_err; | ||
958 | } | ||
959 | |||
960 | static int sd_getredbalance(struct gspca_dev *gspca_dev, __s32 *val) | ||
961 | { | ||
962 | struct sd *sd = (struct sd *) gspca_dev; | ||
963 | |||
964 | *val = sd->red_balance; | ||
965 | return 0; | ||
966 | } | ||
967 | |||
968 | static int sd_setbluebalance(struct gspca_dev *gspca_dev, __s32 val) | ||
969 | { | ||
970 | struct sd *sd = (struct sd *) gspca_dev; | ||
971 | |||
972 | sd->blue_balance = val; | ||
973 | if (gspca_dev->streaming) | ||
974 | setbluebalance(gspca_dev); | ||
975 | return gspca_dev->usb_err; | ||
976 | } | ||
977 | |||
978 | static int sd_getbluebalance(struct gspca_dev *gspca_dev, __s32 *val) | ||
979 | { | ||
980 | struct sd *sd = (struct sd *) gspca_dev; | ||
981 | |||
982 | *val = sd->blue_balance; | ||
983 | return 0; | ||
984 | } | ||
985 | |||
986 | static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val) | ||
987 | { | ||
988 | struct sd *sd = (struct sd *) gspca_dev; | ||
989 | |||
990 | sd->gain = val; | ||
991 | if (gspca_dev->streaming) | ||
992 | setgain(gspca_dev); | ||
993 | return gspca_dev->usb_err; | ||
994 | } | ||
995 | |||
996 | static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val) | ||
997 | { | ||
998 | struct sd *sd = (struct sd *) gspca_dev; | ||
999 | |||
1000 | *val = sd->gain; | ||
1001 | return 0; | ||
1002 | } | ||
1003 | |||
1004 | static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val) | ||
1005 | { | ||
1006 | struct sd *sd = (struct sd *) gspca_dev; | ||
1007 | |||
1008 | sd->exposure = val; | ||
1009 | if (gspca_dev->streaming) | ||
1010 | setexposure(gspca_dev); | ||
1011 | return gspca_dev->usb_err; | ||
1012 | } | ||
1013 | |||
1014 | static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val) | ||
1015 | { | ||
1016 | struct sd *sd = (struct sd *) gspca_dev; | ||
1017 | |||
1018 | *val = sd->exposure; | ||
1019 | return 0; | ||
1020 | } | ||
1021 | |||
1022 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) | ||
1023 | { | ||
1024 | struct sd *sd = (struct sd *) gspca_dev; | ||
1025 | |||
1026 | sd->autogain = val; | ||
1027 | /* when switching to autogain set defaults to make sure | ||
1028 | we are on a valid point of the autogain gain / | ||
1029 | exposure knee graph, and give this change time to | ||
1030 | take effect before doing autogain. */ | ||
1031 | if (sd->autogain) { | ||
1032 | sd->exposure = EXPOSURE_DEF; | ||
1033 | sd->gain = GAIN_DEF; | ||
1034 | if (gspca_dev->streaming) { | ||
1035 | sd->autogain_ignore_frames = | ||
1036 | PAC_AUTOGAIN_IGNORE_FRAMES; | ||
1037 | setexposure(gspca_dev); | ||
1038 | setgain(gspca_dev); | ||
1039 | } | ||
1040 | } | ||
1041 | |||
1042 | return gspca_dev->usb_err; | ||
1043 | } | ||
1044 | |||
1045 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) | ||
1046 | { | ||
1047 | struct sd *sd = (struct sd *) gspca_dev; | ||
1048 | |||
1049 | *val = sd->autogain; | ||
1050 | return 0; | ||
1051 | } | ||
1052 | |||
1053 | static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val) | ||
1054 | { | ||
1055 | struct sd *sd = (struct sd *) gspca_dev; | ||
1056 | |||
1057 | sd->hflip = val; | ||
1058 | if (gspca_dev->streaming) | ||
1059 | sethvflip(gspca_dev); | ||
1060 | return gspca_dev->usb_err; | ||
1061 | } | ||
1062 | |||
1063 | static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val) | ||
1064 | { | ||
1065 | struct sd *sd = (struct sd *) gspca_dev; | ||
1066 | |||
1067 | *val = sd->hflip; | ||
1068 | return 0; | ||
1069 | } | ||
1070 | |||
1071 | static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val) | ||
1072 | { | ||
1073 | struct sd *sd = (struct sd *) gspca_dev; | ||
1074 | |||
1075 | sd->vflip = val; | ||
1076 | if (gspca_dev->streaming) | ||
1077 | sethvflip(gspca_dev); | ||
1078 | return gspca_dev->usb_err; | ||
1079 | } | ||
1080 | |||
1081 | static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val) | ||
1082 | { | ||
1083 | struct sd *sd = (struct sd *) gspca_dev; | ||
1084 | |||
1085 | *val = sd->vflip; | ||
1086 | return 0; | ||
1087 | } | ||
1088 | |||
1089 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 835 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
1090 | static int sd_dbg_s_register(struct gspca_dev *gspca_dev, | 836 | static int sd_dbg_s_register(struct gspca_dev *gspca_dev, |
1091 | struct v4l2_dbg_register *reg) | 837 | struct v4l2_dbg_register *reg) |
1092 | { | 838 | { |
1093 | __u8 index; | 839 | u8 index; |
1094 | __u8 value; | 840 | u8 value; |
1095 | 841 | ||
1096 | /* reg->reg: bit0..15: reserved for register index (wIndex is 16bit | 842 | /* reg->reg: bit0..15: reserved for register index (wIndex is 16bit |
1097 | long on the USB bus) | 843 | long on the USB bus) |
@@ -1103,8 +849,8 @@ static int sd_dbg_s_register(struct gspca_dev *gspca_dev, | |||
1103 | ) { | 849 | ) { |
1104 | /* Currently writing to page 0 is only supported. */ | 850 | /* Currently writing to page 0 is only supported. */ |
1105 | /* reg_w() only supports 8bit index */ | 851 | /* reg_w() only supports 8bit index */ |
1106 | index = reg->reg & 0x000000ff; | 852 | index = reg->reg; |
1107 | value = reg->val & 0x000000ff; | 853 | value = reg->val; |
1108 | 854 | ||
1109 | /* Note that there shall be no access to other page | 855 | /* Note that there shall be no access to other page |
1110 | by any other function between the page swith and | 856 | by any other function between the page swith and |
@@ -1165,7 +911,7 @@ static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, | |||
1165 | 911 | ||
1166 | /* sub-driver description for pac7302 */ | 912 | /* sub-driver description for pac7302 */ |
1167 | static const struct sd_desc sd_desc = { | 913 | static const struct sd_desc sd_desc = { |
1168 | .name = MODULE_NAME, | 914 | .name = KBUILD_MODNAME, |
1169 | .ctrls = sd_ctrls, | 915 | .ctrls = sd_ctrls, |
1170 | .nctrls = ARRAY_SIZE(sd_ctrls), | 916 | .nctrls = ARRAY_SIZE(sd_ctrls), |
1171 | .config = sd_config, | 917 | .config = sd_config, |
@@ -1187,6 +933,7 @@ static const struct sd_desc sd_desc = { | |||
1187 | /* -- module initialisation -- */ | 933 | /* -- module initialisation -- */ |
1188 | static const struct usb_device_id device_table[] = { | 934 | static const struct usb_device_id device_table[] = { |
1189 | {USB_DEVICE(0x06f8, 0x3009)}, | 935 | {USB_DEVICE(0x06f8, 0x3009)}, |
936 | {USB_DEVICE(0x06f8, 0x301b)}, | ||
1190 | {USB_DEVICE(0x093a, 0x2620)}, | 937 | {USB_DEVICE(0x093a, 0x2620)}, |
1191 | {USB_DEVICE(0x093a, 0x2621)}, | 938 | {USB_DEVICE(0x093a, 0x2621)}, |
1192 | {USB_DEVICE(0x093a, 0x2622), .driver_info = FL_VFLIP}, | 939 | {USB_DEVICE(0x093a, 0x2622), .driver_info = FL_VFLIP}, |
@@ -1211,7 +958,7 @@ static int sd_probe(struct usb_interface *intf, | |||
1211 | } | 958 | } |
1212 | 959 | ||
1213 | static struct usb_driver sd_driver = { | 960 | static struct usb_driver sd_driver = { |
1214 | .name = MODULE_NAME, | 961 | .name = KBUILD_MODNAME, |
1215 | .id_table = device_table, | 962 | .id_table = device_table, |
1216 | .probe = sd_probe, | 963 | .probe = sd_probe, |
1217 | .disconnect = gspca_disconnect, | 964 | .disconnect = gspca_disconnect, |
diff --git a/drivers/media/video/gspca/sn9c20x.c b/drivers/media/video/gspca/sn9c20x.c index 9e198b45c3c8..7e71aa2d2522 100644 --- a/drivers/media/video/gspca/sn9c20x.c +++ b/drivers/media/video/gspca/sn9c20x.c | |||
@@ -1,5 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Sonix sn9c201 sn9c202 library | 2 | * Sonix sn9c201 sn9c202 library |
3 | * | ||
4 | * Copyright (C) 2012 Jean-Francois Moine <http://moinejf.free.fr> | ||
3 | * Copyright (C) 2008-2009 microdia project <microdia@googlegroups.com> | 5 | * Copyright (C) 2008-2009 microdia project <microdia@googlegroups.com> |
4 | * Copyright (C) 2009 Brian Johnson <brijohn@gmail.com> | 6 | * Copyright (C) 2009 Brian Johnson <brijohn@gmail.com> |
5 | * | 7 | * |
@@ -33,8 +35,6 @@ MODULE_AUTHOR("Brian Johnson <brijohn@gmail.com>, " | |||
33 | MODULE_DESCRIPTION("GSPCA/SN9C20X USB Camera Driver"); | 35 | MODULE_DESCRIPTION("GSPCA/SN9C20X USB Camera Driver"); |
34 | MODULE_LICENSE("GPL"); | 36 | MODULE_LICENSE("GPL"); |
35 | 37 | ||
36 | #define MODULE_NAME "sn9c20x" | ||
37 | |||
38 | /* | 38 | /* |
39 | * Pixel format private data | 39 | * Pixel format private data |
40 | */ | 40 | */ |
@@ -66,10 +66,37 @@ MODULE_LICENSE("GPL"); | |||
66 | #define LED_REVERSE 0x2 /* some cameras unset gpio to turn on leds */ | 66 | #define LED_REVERSE 0x2 /* some cameras unset gpio to turn on leds */ |
67 | #define FLIP_DETECT 0x4 | 67 | #define FLIP_DETECT 0x4 |
68 | 68 | ||
69 | enum e_ctrl { | ||
70 | BRIGHTNESS, | ||
71 | CONTRAST, | ||
72 | SATURATION, | ||
73 | HUE, | ||
74 | GAMMA, | ||
75 | BLUE, | ||
76 | RED, | ||
77 | VFLIP, | ||
78 | HFLIP, | ||
79 | EXPOSURE, | ||
80 | GAIN, | ||
81 | AUTOGAIN, | ||
82 | QUALITY, | ||
83 | NCTRLS /* number of controls */ | ||
84 | }; | ||
85 | |||
69 | /* specific webcam descriptor */ | 86 | /* specific webcam descriptor */ |
70 | struct sd { | 87 | struct sd { |
71 | struct gspca_dev gspca_dev; | 88 | struct gspca_dev gspca_dev; |
72 | 89 | ||
90 | struct gspca_ctrl ctrls[NCTRLS]; | ||
91 | |||
92 | struct work_struct work; | ||
93 | struct workqueue_struct *work_thread; | ||
94 | |||
95 | u32 pktsz; /* (used by pkt_scan) */ | ||
96 | u16 npkt; | ||
97 | s8 nchg; | ||
98 | u8 fmt; /* (used for JPEG QTAB update */ | ||
99 | |||
73 | #define MIN_AVG_LUM 80 | 100 | #define MIN_AVG_LUM 80 |
74 | #define MAX_AVG_LUM 130 | 101 | #define MAX_AVG_LUM 130 |
75 | atomic_t avg_lum; | 102 | atomic_t avg_lum; |
@@ -77,31 +104,18 @@ struct sd { | |||
77 | u8 older_step; | 104 | u8 older_step; |
78 | u8 exposure_step; | 105 | u8 exposure_step; |
79 | 106 | ||
80 | u8 brightness; | ||
81 | u8 contrast; | ||
82 | u8 saturation; | ||
83 | s16 hue; | ||
84 | u8 gamma; | ||
85 | u8 red; | ||
86 | u8 blue; | ||
87 | |||
88 | u8 hflip; | ||
89 | u8 vflip; | ||
90 | u8 gain; | ||
91 | u16 exposure; | ||
92 | u8 auto_exposure; | ||
93 | |||
94 | u8 i2c_addr; | 107 | u8 i2c_addr; |
95 | u8 sensor; | 108 | u8 sensor; |
96 | u8 hstart; | 109 | u8 hstart; |
97 | u8 vstart; | 110 | u8 vstart; |
98 | 111 | ||
99 | u8 jpeg_hdr[JPEG_HDR_SZ]; | 112 | u8 jpeg_hdr[JPEG_HDR_SZ]; |
100 | u8 quality; | ||
101 | 113 | ||
102 | u8 flags; | 114 | u8 flags; |
103 | }; | 115 | }; |
104 | 116 | ||
117 | static void qual_upd(struct work_struct *work); | ||
118 | |||
105 | struct i2c_reg_u8 { | 119 | struct i2c_reg_u8 { |
106 | u8 reg; | 120 | u8 reg; |
107 | u8 val; | 121 | u8 val; |
@@ -112,31 +126,6 @@ struct i2c_reg_u16 { | |||
112 | u16 val; | 126 | u16 val; |
113 | }; | 127 | }; |
114 | 128 | ||
115 | static int sd_setbrightness(struct gspca_dev *gspca_dev, s32 val); | ||
116 | static int sd_getbrightness(struct gspca_dev *gspca_dev, s32 *val); | ||
117 | static int sd_setcontrast(struct gspca_dev *gspca_dev, s32 val); | ||
118 | static int sd_getcontrast(struct gspca_dev *gspca_dev, s32 *val); | ||
119 | static int sd_setsaturation(struct gspca_dev *gspca_dev, s32 val); | ||
120 | static int sd_getsaturation(struct gspca_dev *gspca_dev, s32 *val); | ||
121 | static int sd_sethue(struct gspca_dev *gspca_dev, s32 val); | ||
122 | static int sd_gethue(struct gspca_dev *gspca_dev, s32 *val); | ||
123 | static int sd_setgamma(struct gspca_dev *gspca_dev, s32 val); | ||
124 | static int sd_getgamma(struct gspca_dev *gspca_dev, s32 *val); | ||
125 | static int sd_setredbalance(struct gspca_dev *gspca_dev, s32 val); | ||
126 | static int sd_getredbalance(struct gspca_dev *gspca_dev, s32 *val); | ||
127 | static int sd_setbluebalance(struct gspca_dev *gspca_dev, s32 val); | ||
128 | static int sd_getbluebalance(struct gspca_dev *gspca_dev, s32 *val); | ||
129 | static int sd_setvflip(struct gspca_dev *gspca_dev, s32 val); | ||
130 | static int sd_getvflip(struct gspca_dev *gspca_dev, s32 *val); | ||
131 | static int sd_sethflip(struct gspca_dev *gspca_dev, s32 val); | ||
132 | static int sd_gethflip(struct gspca_dev *gspca_dev, s32 *val); | ||
133 | static int sd_setgain(struct gspca_dev *gspca_dev, s32 val); | ||
134 | static int sd_getgain(struct gspca_dev *gspca_dev, s32 *val); | ||
135 | static int sd_setexposure(struct gspca_dev *gspca_dev, s32 val); | ||
136 | static int sd_getexposure(struct gspca_dev *gspca_dev, s32 *val); | ||
137 | static int sd_setautoexposure(struct gspca_dev *gspca_dev, s32 val); | ||
138 | static int sd_getautoexposure(struct gspca_dev *gspca_dev, s32 *val); | ||
139 | |||
140 | static const struct dmi_system_id flip_dmi_table[] = { | 129 | static const struct dmi_system_id flip_dmi_table[] = { |
141 | { | 130 | { |
142 | .ident = "MSI MS-1034", | 131 | .ident = "MSI MS-1034", |
@@ -177,9 +166,16 @@ static const struct dmi_system_id flip_dmi_table[] = { | |||
177 | {} | 166 | {} |
178 | }; | 167 | }; |
179 | 168 | ||
180 | static const struct ctrl sd_ctrls[] = { | 169 | static void set_cmatrix(struct gspca_dev *gspca_dev); |
181 | { | 170 | static void set_gamma(struct gspca_dev *gspca_dev); |
182 | #define BRIGHTNESS_IDX 0 | 171 | static void set_redblue(struct gspca_dev *gspca_dev); |
172 | static void set_hvflip(struct gspca_dev *gspca_dev); | ||
173 | static void set_exposure(struct gspca_dev *gspca_dev); | ||
174 | static void set_gain(struct gspca_dev *gspca_dev); | ||
175 | static void set_quality(struct gspca_dev *gspca_dev); | ||
176 | |||
177 | static const struct ctrl sd_ctrls[NCTRLS] = { | ||
178 | [BRIGHTNESS] = { | ||
183 | { | 179 | { |
184 | .id = V4L2_CID_BRIGHTNESS, | 180 | .id = V4L2_CID_BRIGHTNESS, |
185 | .type = V4L2_CTRL_TYPE_INTEGER, | 181 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -187,14 +183,11 @@ static const struct ctrl sd_ctrls[] = { | |||
187 | .minimum = 0, | 183 | .minimum = 0, |
188 | .maximum = 0xff, | 184 | .maximum = 0xff, |
189 | .step = 1, | 185 | .step = 1, |
190 | #define BRIGHTNESS_DEFAULT 0x7f | 186 | .default_value = 0x7f |
191 | .default_value = BRIGHTNESS_DEFAULT, | ||
192 | }, | 187 | }, |
193 | .set = sd_setbrightness, | 188 | .set_control = set_cmatrix |
194 | .get = sd_getbrightness, | ||
195 | }, | 189 | }, |
196 | { | 190 | [CONTRAST] = { |
197 | #define CONTRAST_IDX 1 | ||
198 | { | 191 | { |
199 | .id = V4L2_CID_CONTRAST, | 192 | .id = V4L2_CID_CONTRAST, |
200 | .type = V4L2_CTRL_TYPE_INTEGER, | 193 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -202,14 +195,11 @@ static const struct ctrl sd_ctrls[] = { | |||
202 | .minimum = 0, | 195 | .minimum = 0, |
203 | .maximum = 0xff, | 196 | .maximum = 0xff, |
204 | .step = 1, | 197 | .step = 1, |
205 | #define CONTRAST_DEFAULT 0x7f | 198 | .default_value = 0x7f |
206 | .default_value = CONTRAST_DEFAULT, | ||
207 | }, | 199 | }, |
208 | .set = sd_setcontrast, | 200 | .set_control = set_cmatrix |
209 | .get = sd_getcontrast, | ||
210 | }, | 201 | }, |
211 | { | 202 | [SATURATION] = { |
212 | #define SATURATION_IDX 2 | ||
213 | { | 203 | { |
214 | .id = V4L2_CID_SATURATION, | 204 | .id = V4L2_CID_SATURATION, |
215 | .type = V4L2_CTRL_TYPE_INTEGER, | 205 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -217,14 +207,11 @@ static const struct ctrl sd_ctrls[] = { | |||
217 | .minimum = 0, | 207 | .minimum = 0, |
218 | .maximum = 0xff, | 208 | .maximum = 0xff, |
219 | .step = 1, | 209 | .step = 1, |
220 | #define SATURATION_DEFAULT 0x7f | 210 | .default_value = 0x7f |
221 | .default_value = SATURATION_DEFAULT, | ||
222 | }, | 211 | }, |
223 | .set = sd_setsaturation, | 212 | .set_control = set_cmatrix |
224 | .get = sd_getsaturation, | ||
225 | }, | 213 | }, |
226 | { | 214 | [HUE] = { |
227 | #define HUE_IDX 3 | ||
228 | { | 215 | { |
229 | .id = V4L2_CID_HUE, | 216 | .id = V4L2_CID_HUE, |
230 | .type = V4L2_CTRL_TYPE_INTEGER, | 217 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -232,14 +219,11 @@ static const struct ctrl sd_ctrls[] = { | |||
232 | .minimum = -180, | 219 | .minimum = -180, |
233 | .maximum = 180, | 220 | .maximum = 180, |
234 | .step = 1, | 221 | .step = 1, |
235 | #define HUE_DEFAULT 0 | 222 | .default_value = 0 |
236 | .default_value = HUE_DEFAULT, | ||
237 | }, | 223 | }, |
238 | .set = sd_sethue, | 224 | .set_control = set_cmatrix |
239 | .get = sd_gethue, | ||
240 | }, | 225 | }, |
241 | { | 226 | [GAMMA] = { |
242 | #define GAMMA_IDX 4 | ||
243 | { | 227 | { |
244 | .id = V4L2_CID_GAMMA, | 228 | .id = V4L2_CID_GAMMA, |
245 | .type = V4L2_CTRL_TYPE_INTEGER, | 229 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -247,14 +231,11 @@ static const struct ctrl sd_ctrls[] = { | |||
247 | .minimum = 0, | 231 | .minimum = 0, |
248 | .maximum = 0xff, | 232 | .maximum = 0xff, |
249 | .step = 1, | 233 | .step = 1, |
250 | #define GAMMA_DEFAULT 0x10 | 234 | .default_value = 0x10 |
251 | .default_value = GAMMA_DEFAULT, | ||
252 | }, | 235 | }, |
253 | .set = sd_setgamma, | 236 | .set_control = set_gamma |
254 | .get = sd_getgamma, | ||
255 | }, | 237 | }, |
256 | { | 238 | [BLUE] = { |
257 | #define BLUE_IDX 5 | ||
258 | { | 239 | { |
259 | .id = V4L2_CID_BLUE_BALANCE, | 240 | .id = V4L2_CID_BLUE_BALANCE, |
260 | .type = V4L2_CTRL_TYPE_INTEGER, | 241 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -262,14 +243,11 @@ static const struct ctrl sd_ctrls[] = { | |||
262 | .minimum = 0, | 243 | .minimum = 0, |
263 | .maximum = 0x7f, | 244 | .maximum = 0x7f, |
264 | .step = 1, | 245 | .step = 1, |
265 | #define BLUE_DEFAULT 0x28 | 246 | .default_value = 0x28 |
266 | .default_value = BLUE_DEFAULT, | ||
267 | }, | 247 | }, |
268 | .set = sd_setbluebalance, | 248 | .set_control = set_redblue |
269 | .get = sd_getbluebalance, | ||
270 | }, | 249 | }, |
271 | { | 250 | [RED] = { |
272 | #define RED_IDX 6 | ||
273 | { | 251 | { |
274 | .id = V4L2_CID_RED_BALANCE, | 252 | .id = V4L2_CID_RED_BALANCE, |
275 | .type = V4L2_CTRL_TYPE_INTEGER, | 253 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -277,14 +255,11 @@ static const struct ctrl sd_ctrls[] = { | |||
277 | .minimum = 0, | 255 | .minimum = 0, |
278 | .maximum = 0x7f, | 256 | .maximum = 0x7f, |
279 | .step = 1, | 257 | .step = 1, |
280 | #define RED_DEFAULT 0x28 | 258 | .default_value = 0x28 |
281 | .default_value = RED_DEFAULT, | ||
282 | }, | 259 | }, |
283 | .set = sd_setredbalance, | 260 | .set_control = set_redblue |
284 | .get = sd_getredbalance, | ||
285 | }, | 261 | }, |
286 | { | 262 | [HFLIP] = { |
287 | #define HFLIP_IDX 7 | ||
288 | { | 263 | { |
289 | .id = V4L2_CID_HFLIP, | 264 | .id = V4L2_CID_HFLIP, |
290 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 265 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
@@ -292,14 +267,11 @@ static const struct ctrl sd_ctrls[] = { | |||
292 | .minimum = 0, | 267 | .minimum = 0, |
293 | .maximum = 1, | 268 | .maximum = 1, |
294 | .step = 1, | 269 | .step = 1, |
295 | #define HFLIP_DEFAULT 0 | 270 | .default_value = 0, |
296 | .default_value = HFLIP_DEFAULT, | ||
297 | }, | 271 | }, |
298 | .set = sd_sethflip, | 272 | .set_control = set_hvflip |
299 | .get = sd_gethflip, | ||
300 | }, | 273 | }, |
301 | { | 274 | [VFLIP] = { |
302 | #define VFLIP_IDX 8 | ||
303 | { | 275 | { |
304 | .id = V4L2_CID_VFLIP, | 276 | .id = V4L2_CID_VFLIP, |
305 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 277 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
@@ -307,14 +279,11 @@ static const struct ctrl sd_ctrls[] = { | |||
307 | .minimum = 0, | 279 | .minimum = 0, |
308 | .maximum = 1, | 280 | .maximum = 1, |
309 | .step = 1, | 281 | .step = 1, |
310 | #define VFLIP_DEFAULT 0 | 282 | .default_value = 0, |
311 | .default_value = VFLIP_DEFAULT, | ||
312 | }, | 283 | }, |
313 | .set = sd_setvflip, | 284 | .set_control = set_hvflip |
314 | .get = sd_getvflip, | ||
315 | }, | 285 | }, |
316 | { | 286 | [EXPOSURE] = { |
317 | #define EXPOSURE_IDX 9 | ||
318 | { | 287 | { |
319 | .id = V4L2_CID_EXPOSURE, | 288 | .id = V4L2_CID_EXPOSURE, |
320 | .type = V4L2_CTRL_TYPE_INTEGER, | 289 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -322,14 +291,11 @@ static const struct ctrl sd_ctrls[] = { | |||
322 | .minimum = 0, | 291 | .minimum = 0, |
323 | .maximum = 0x1780, | 292 | .maximum = 0x1780, |
324 | .step = 1, | 293 | .step = 1, |
325 | #define EXPOSURE_DEFAULT 0x33 | 294 | .default_value = 0x33, |
326 | .default_value = EXPOSURE_DEFAULT, | ||
327 | }, | 295 | }, |
328 | .set = sd_setexposure, | 296 | .set_control = set_exposure |
329 | .get = sd_getexposure, | ||
330 | }, | 297 | }, |
331 | { | 298 | [GAIN] = { |
332 | #define GAIN_IDX 10 | ||
333 | { | 299 | { |
334 | .id = V4L2_CID_GAIN, | 300 | .id = V4L2_CID_GAIN, |
335 | .type = V4L2_CTRL_TYPE_INTEGER, | 301 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -337,14 +303,11 @@ static const struct ctrl sd_ctrls[] = { | |||
337 | .minimum = 0, | 303 | .minimum = 0, |
338 | .maximum = 28, | 304 | .maximum = 28, |
339 | .step = 1, | 305 | .step = 1, |
340 | #define GAIN_DEFAULT 0x00 | 306 | .default_value = 0, |
341 | .default_value = GAIN_DEFAULT, | ||
342 | }, | 307 | }, |
343 | .set = sd_setgain, | 308 | .set_control = set_gain |
344 | .get = sd_getgain, | ||
345 | }, | 309 | }, |
346 | { | 310 | [AUTOGAIN] = { |
347 | #define AUTOGAIN_IDX 11 | ||
348 | { | 311 | { |
349 | .id = V4L2_CID_AUTOGAIN, | 312 | .id = V4L2_CID_AUTOGAIN, |
350 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 313 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
@@ -352,11 +315,23 @@ static const struct ctrl sd_ctrls[] = { | |||
352 | .minimum = 0, | 315 | .minimum = 0, |
353 | .maximum = 1, | 316 | .maximum = 1, |
354 | .step = 1, | 317 | .step = 1, |
355 | #define AUTO_EXPOSURE_DEFAULT 1 | 318 | .default_value = 1, |
356 | .default_value = AUTO_EXPOSURE_DEFAULT, | 319 | }, |
320 | }, | ||
321 | [QUALITY] = { | ||
322 | { | ||
323 | .id = V4L2_CID_JPEG_COMPRESSION_QUALITY, | ||
324 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
325 | .name = "Compression Quality", | ||
326 | #define QUALITY_MIN 50 | ||
327 | #define QUALITY_MAX 90 | ||
328 | #define QUALITY_DEF 80 | ||
329 | .minimum = QUALITY_MIN, | ||
330 | .maximum = QUALITY_MAX, | ||
331 | .step = 1, | ||
332 | .default_value = QUALITY_DEF, | ||
357 | }, | 333 | }, |
358 | .set = sd_setautoexposure, | 334 | .set_control = set_quality |
359 | .get = sd_getautoexposure, | ||
360 | }, | 335 | }, |
361 | }; | 336 | }; |
362 | 337 | ||
@@ -876,7 +851,7 @@ static u8 hv7131r_gain[] = { | |||
876 | }; | 851 | }; |
877 | 852 | ||
878 | static struct i2c_reg_u8 soi968_init[] = { | 853 | static struct i2c_reg_u8 soi968_init[] = { |
879 | {0x12, 0x80}, {0x0c, 0x00}, {0x0f, 0x1f}, | 854 | {0x0c, 0x00}, {0x0f, 0x1f}, |
880 | {0x11, 0x80}, {0x38, 0x52}, {0x1e, 0x00}, | 855 | {0x11, 0x80}, {0x38, 0x52}, {0x1e, 0x00}, |
881 | {0x33, 0x08}, {0x35, 0x8c}, {0x36, 0x0c}, | 856 | {0x33, 0x08}, {0x35, 0x8c}, {0x36, 0x0c}, |
882 | {0x37, 0x04}, {0x45, 0x04}, {0x47, 0xff}, | 857 | {0x37, 0x04}, {0x45, 0x04}, {0x47, 0xff}, |
@@ -902,7 +877,7 @@ static struct i2c_reg_u8 ov7660_init[] = { | |||
902 | }; | 877 | }; |
903 | 878 | ||
904 | static struct i2c_reg_u8 ov7670_init[] = { | 879 | static struct i2c_reg_u8 ov7670_init[] = { |
905 | {0x12, 0x80}, {0x11, 0x80}, {0x3a, 0x04}, {0x12, 0x01}, | 880 | {0x11, 0x80}, {0x3a, 0x04}, {0x12, 0x01}, |
906 | {0x32, 0xb6}, {0x03, 0x0a}, {0x0c, 0x00}, {0x3e, 0x00}, | 881 | {0x32, 0xb6}, {0x03, 0x0a}, {0x0c, 0x00}, {0x3e, 0x00}, |
907 | {0x70, 0x3a}, {0x71, 0x35}, {0x72, 0x11}, {0x73, 0xf0}, | 882 | {0x70, 0x3a}, {0x71, 0x35}, {0x72, 0x11}, {0x73, 0xf0}, |
908 | {0xa2, 0x02}, {0x13, 0xe0}, {0x00, 0x00}, {0x10, 0x00}, | 883 | {0xa2, 0x02}, {0x13, 0xe0}, {0x00, 0x00}, {0x10, 0x00}, |
@@ -959,7 +934,7 @@ static struct i2c_reg_u8 ov7670_init[] = { | |||
959 | }; | 934 | }; |
960 | 935 | ||
961 | static struct i2c_reg_u8 ov9650_init[] = { | 936 | static struct i2c_reg_u8 ov9650_init[] = { |
962 | {0x12, 0x80}, {0x00, 0x00}, {0x01, 0x78}, | 937 | {0x00, 0x00}, {0x01, 0x78}, |
963 | {0x02, 0x78}, {0x03, 0x36}, {0x04, 0x03}, | 938 | {0x02, 0x78}, {0x03, 0x36}, {0x04, 0x03}, |
964 | {0x05, 0x00}, {0x06, 0x00}, {0x08, 0x00}, | 939 | {0x05, 0x00}, {0x06, 0x00}, {0x08, 0x00}, |
965 | {0x09, 0x01}, {0x0c, 0x00}, {0x0d, 0x00}, | 940 | {0x09, 0x01}, {0x0c, 0x00}, {0x0d, 0x00}, |
@@ -989,7 +964,7 @@ static struct i2c_reg_u8 ov9650_init[] = { | |||
989 | }; | 964 | }; |
990 | 965 | ||
991 | static struct i2c_reg_u8 ov9655_init[] = { | 966 | static struct i2c_reg_u8 ov9655_init[] = { |
992 | {0x12, 0x80}, {0x0e, 0x61}, {0x11, 0x80}, {0x13, 0xba}, | 967 | {0x0e, 0x61}, {0x11, 0x80}, {0x13, 0xba}, |
993 | {0x14, 0x2e}, {0x16, 0x24}, {0x1e, 0x04}, {0x27, 0x08}, | 968 | {0x14, 0x2e}, {0x16, 0x24}, {0x1e, 0x04}, {0x27, 0x08}, |
994 | {0x28, 0x08}, {0x29, 0x15}, {0x2c, 0x08}, {0x34, 0x3d}, | 969 | {0x28, 0x08}, {0x29, 0x15}, {0x2c, 0x08}, {0x34, 0x3d}, |
995 | {0x35, 0x00}, {0x38, 0x12}, {0x0f, 0x42}, {0x39, 0x57}, | 970 | {0x35, 0x00}, {0x38, 0x12}, {0x0f, 0x42}, {0x39, 0x57}, |
@@ -1112,10 +1087,13 @@ static struct i2c_reg_u8 hv7131r_init[] = { | |||
1112 | {0x23, 0x09}, {0x01, 0x08}, | 1087 | {0x23, 0x09}, {0x01, 0x08}, |
1113 | }; | 1088 | }; |
1114 | 1089 | ||
1115 | static int reg_r(struct gspca_dev *gspca_dev, u16 reg, u16 length) | 1090 | static void reg_r(struct gspca_dev *gspca_dev, u16 reg, u16 length) |
1116 | { | 1091 | { |
1117 | struct usb_device *dev = gspca_dev->dev; | 1092 | struct usb_device *dev = gspca_dev->dev; |
1118 | int result; | 1093 | int result; |
1094 | |||
1095 | if (gspca_dev->usb_err < 0) | ||
1096 | return; | ||
1119 | result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), | 1097 | result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), |
1120 | 0x00, | 1098 | 0x00, |
1121 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, | 1099 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, |
@@ -1125,17 +1103,19 @@ static int reg_r(struct gspca_dev *gspca_dev, u16 reg, u16 length) | |||
1125 | length, | 1103 | length, |
1126 | 500); | 1104 | 500); |
1127 | if (unlikely(result < 0 || result != length)) { | 1105 | if (unlikely(result < 0 || result != length)) { |
1128 | pr_err("Read register failed 0x%02X\n", reg); | 1106 | pr_err("Read register %02x failed %d\n", reg, result); |
1129 | return -EIO; | 1107 | gspca_dev->usb_err = result; |
1130 | } | 1108 | } |
1131 | return 0; | ||
1132 | } | 1109 | } |
1133 | 1110 | ||
1134 | static int reg_w(struct gspca_dev *gspca_dev, u16 reg, | 1111 | static void reg_w(struct gspca_dev *gspca_dev, u16 reg, |
1135 | const u8 *buffer, int length) | 1112 | const u8 *buffer, int length) |
1136 | { | 1113 | { |
1137 | struct usb_device *dev = gspca_dev->dev; | 1114 | struct usb_device *dev = gspca_dev->dev; |
1138 | int result; | 1115 | int result; |
1116 | |||
1117 | if (gspca_dev->usb_err < 0) | ||
1118 | return; | ||
1139 | memcpy(gspca_dev->usb_buf, buffer, length); | 1119 | memcpy(gspca_dev->usb_buf, buffer, length); |
1140 | result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | 1120 | result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), |
1141 | 0x08, | 1121 | 0x08, |
@@ -1146,38 +1126,41 @@ static int reg_w(struct gspca_dev *gspca_dev, u16 reg, | |||
1146 | length, | 1126 | length, |
1147 | 500); | 1127 | 500); |
1148 | if (unlikely(result < 0 || result != length)) { | 1128 | if (unlikely(result < 0 || result != length)) { |
1149 | pr_err("Write register failed index 0x%02X\n", reg); | 1129 | pr_err("Write register %02x failed %d\n", reg, result); |
1150 | return -EIO; | 1130 | gspca_dev->usb_err = result; |
1151 | } | 1131 | } |
1152 | return 0; | ||
1153 | } | 1132 | } |
1154 | 1133 | ||
1155 | static int reg_w1(struct gspca_dev *gspca_dev, u16 reg, const u8 value) | 1134 | static void reg_w1(struct gspca_dev *gspca_dev, u16 reg, const u8 value) |
1156 | { | 1135 | { |
1157 | u8 data[1] = {value}; | 1136 | reg_w(gspca_dev, reg, &value, 1); |
1158 | return reg_w(gspca_dev, reg, data, 1); | ||
1159 | } | 1137 | } |
1160 | 1138 | ||
1161 | static int i2c_w(struct gspca_dev *gspca_dev, const u8 *buffer) | 1139 | static void i2c_w(struct gspca_dev *gspca_dev, const u8 *buffer) |
1162 | { | 1140 | { |
1163 | int i; | 1141 | int i; |
1142 | |||
1164 | reg_w(gspca_dev, 0x10c0, buffer, 8); | 1143 | reg_w(gspca_dev, 0x10c0, buffer, 8); |
1165 | for (i = 0; i < 5; i++) { | 1144 | for (i = 0; i < 5; i++) { |
1166 | reg_r(gspca_dev, 0x10c0, 1); | 1145 | reg_r(gspca_dev, 0x10c0, 1); |
1146 | if (gspca_dev->usb_err < 0) | ||
1147 | return; | ||
1167 | if (gspca_dev->usb_buf[0] & 0x04) { | 1148 | if (gspca_dev->usb_buf[0] & 0x04) { |
1168 | if (gspca_dev->usb_buf[0] & 0x08) | 1149 | if (gspca_dev->usb_buf[0] & 0x08) { |
1169 | return -EIO; | 1150 | pr_err("i2c_w error\n"); |
1170 | return 0; | 1151 | gspca_dev->usb_err = -EIO; |
1152 | } | ||
1153 | return; | ||
1171 | } | 1154 | } |
1172 | msleep(1); | 1155 | msleep(10); |
1173 | } | 1156 | } |
1174 | return -EIO; | 1157 | pr_err("i2c_w reg %02x no response\n", buffer[2]); |
1158 | /* gspca_dev->usb_err = -EIO; fixme: may occur */ | ||
1175 | } | 1159 | } |
1176 | 1160 | ||
1177 | static int i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val) | 1161 | static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val) |
1178 | { | 1162 | { |
1179 | struct sd *sd = (struct sd *) gspca_dev; | 1163 | struct sd *sd = (struct sd *) gspca_dev; |
1180 | |||
1181 | u8 row[8]; | 1164 | u8 row[8]; |
1182 | 1165 | ||
1183 | /* | 1166 | /* |
@@ -1193,10 +1176,19 @@ static int i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val) | |||
1193 | row[6] = 0x00; | 1176 | row[6] = 0x00; |
1194 | row[7] = 0x10; | 1177 | row[7] = 0x10; |
1195 | 1178 | ||
1196 | return i2c_w(gspca_dev, row); | 1179 | i2c_w(gspca_dev, row); |
1180 | } | ||
1181 | |||
1182 | static void i2c_w1_buf(struct gspca_dev *gspca_dev, | ||
1183 | struct i2c_reg_u8 *buf, int sz) | ||
1184 | { | ||
1185 | while (--sz >= 0) { | ||
1186 | i2c_w1(gspca_dev, buf->reg, buf->val); | ||
1187 | buf++; | ||
1188 | } | ||
1197 | } | 1189 | } |
1198 | 1190 | ||
1199 | static int i2c_w2(struct gspca_dev *gspca_dev, u8 reg, u16 val) | 1191 | static void i2c_w2(struct gspca_dev *gspca_dev, u8 reg, u16 val) |
1200 | { | 1192 | { |
1201 | struct sd *sd = (struct sd *) gspca_dev; | 1193 | struct sd *sd = (struct sd *) gspca_dev; |
1202 | u8 row[8]; | 1194 | u8 row[8]; |
@@ -1208,16 +1200,25 @@ static int i2c_w2(struct gspca_dev *gspca_dev, u8 reg, u16 val) | |||
1208 | row[0] = 0x81 | (3 << 4); | 1200 | row[0] = 0x81 | (3 << 4); |
1209 | row[1] = sd->i2c_addr; | 1201 | row[1] = sd->i2c_addr; |
1210 | row[2] = reg; | 1202 | row[2] = reg; |
1211 | row[3] = (val >> 8) & 0xff; | 1203 | row[3] = val >> 8; |
1212 | row[4] = val & 0xff; | 1204 | row[4] = val; |
1213 | row[5] = 0x00; | 1205 | row[5] = 0x00; |
1214 | row[6] = 0x00; | 1206 | row[6] = 0x00; |
1215 | row[7] = 0x10; | 1207 | row[7] = 0x10; |
1216 | 1208 | ||
1217 | return i2c_w(gspca_dev, row); | 1209 | i2c_w(gspca_dev, row); |
1210 | } | ||
1211 | |||
1212 | static void i2c_w2_buf(struct gspca_dev *gspca_dev, | ||
1213 | struct i2c_reg_u16 *buf, int sz) | ||
1214 | { | ||
1215 | while (--sz >= 0) { | ||
1216 | i2c_w2(gspca_dev, buf->reg, buf->val); | ||
1217 | buf++; | ||
1218 | } | ||
1218 | } | 1219 | } |
1219 | 1220 | ||
1220 | static int i2c_r1(struct gspca_dev *gspca_dev, u8 reg, u8 *val) | 1221 | static void i2c_r1(struct gspca_dev *gspca_dev, u8 reg, u8 *val) |
1221 | { | 1222 | { |
1222 | struct sd *sd = (struct sd *) gspca_dev; | 1223 | struct sd *sd = (struct sd *) gspca_dev; |
1223 | u8 row[8]; | 1224 | u8 row[8]; |
@@ -1230,19 +1231,15 @@ static int i2c_r1(struct gspca_dev *gspca_dev, u8 reg, u8 *val) | |||
1230 | row[5] = 0; | 1231 | row[5] = 0; |
1231 | row[6] = 0; | 1232 | row[6] = 0; |
1232 | row[7] = 0x10; | 1233 | row[7] = 0x10; |
1233 | if (i2c_w(gspca_dev, row) < 0) | 1234 | i2c_w(gspca_dev, row); |
1234 | return -EIO; | ||
1235 | row[0] = 0x81 | (1 << 4) | 0x02; | 1235 | row[0] = 0x81 | (1 << 4) | 0x02; |
1236 | row[2] = 0; | 1236 | row[2] = 0; |
1237 | if (i2c_w(gspca_dev, row) < 0) | 1237 | i2c_w(gspca_dev, row); |
1238 | return -EIO; | 1238 | reg_r(gspca_dev, 0x10c2, 5); |
1239 | if (reg_r(gspca_dev, 0x10c2, 5) < 0) | ||
1240 | return -EIO; | ||
1241 | *val = gspca_dev->usb_buf[4]; | 1239 | *val = gspca_dev->usb_buf[4]; |
1242 | return 0; | ||
1243 | } | 1240 | } |
1244 | 1241 | ||
1245 | static int i2c_r2(struct gspca_dev *gspca_dev, u8 reg, u16 *val) | 1242 | static void i2c_r2(struct gspca_dev *gspca_dev, u8 reg, u16 *val) |
1246 | { | 1243 | { |
1247 | struct sd *sd = (struct sd *) gspca_dev; | 1244 | struct sd *sd = (struct sd *) gspca_dev; |
1248 | u8 row[8]; | 1245 | u8 row[8]; |
@@ -1255,233 +1252,204 @@ static int i2c_r2(struct gspca_dev *gspca_dev, u8 reg, u16 *val) | |||
1255 | row[5] = 0; | 1252 | row[5] = 0; |
1256 | row[6] = 0; | 1253 | row[6] = 0; |
1257 | row[7] = 0x10; | 1254 | row[7] = 0x10; |
1258 | if (i2c_w(gspca_dev, row) < 0) | 1255 | i2c_w(gspca_dev, row); |
1259 | return -EIO; | ||
1260 | row[0] = 0x81 | (2 << 4) | 0x02; | 1256 | row[0] = 0x81 | (2 << 4) | 0x02; |
1261 | row[2] = 0; | 1257 | row[2] = 0; |
1262 | if (i2c_w(gspca_dev, row) < 0) | 1258 | i2c_w(gspca_dev, row); |
1263 | return -EIO; | 1259 | reg_r(gspca_dev, 0x10c2, 5); |
1264 | if (reg_r(gspca_dev, 0x10c2, 5) < 0) | ||
1265 | return -EIO; | ||
1266 | *val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4]; | 1260 | *val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4]; |
1267 | return 0; | ||
1268 | } | 1261 | } |
1269 | 1262 | ||
1270 | static int ov9650_init_sensor(struct gspca_dev *gspca_dev) | 1263 | static void ov9650_init_sensor(struct gspca_dev *gspca_dev) |
1271 | { | 1264 | { |
1272 | int i; | ||
1273 | u16 id; | 1265 | u16 id; |
1274 | struct sd *sd = (struct sd *) gspca_dev; | 1266 | struct sd *sd = (struct sd *) gspca_dev; |
1275 | 1267 | ||
1276 | if (i2c_r2(gspca_dev, 0x1c, &id) < 0) | 1268 | i2c_r2(gspca_dev, 0x1c, &id); |
1277 | return -EINVAL; | 1269 | if (gspca_dev->usb_err < 0) |
1270 | return; | ||
1278 | 1271 | ||
1279 | if (id != 0x7fa2) { | 1272 | if (id != 0x7fa2) { |
1280 | pr_err("sensor id for ov9650 doesn't match (0x%04x)\n", id); | 1273 | pr_err("sensor id for ov9650 doesn't match (0x%04x)\n", id); |
1281 | return -ENODEV; | 1274 | gspca_dev->usb_err = -ENODEV; |
1275 | return; | ||
1282 | } | 1276 | } |
1283 | 1277 | ||
1284 | for (i = 0; i < ARRAY_SIZE(ov9650_init); i++) { | 1278 | i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */ |
1285 | if (i2c_w1(gspca_dev, ov9650_init[i].reg, | 1279 | msleep(200); |
1286 | ov9650_init[i].val) < 0) { | 1280 | i2c_w1_buf(gspca_dev, ov9650_init, ARRAY_SIZE(ov9650_init)); |
1287 | pr_err("OV9650 sensor initialization failed\n"); | 1281 | if (gspca_dev->usb_err < 0) |
1288 | return -ENODEV; | 1282 | pr_err("OV9650 sensor initialization failed\n"); |
1289 | } | ||
1290 | } | ||
1291 | sd->hstart = 1; | 1283 | sd->hstart = 1; |
1292 | sd->vstart = 7; | 1284 | sd->vstart = 7; |
1293 | return 0; | ||
1294 | } | 1285 | } |
1295 | 1286 | ||
1296 | static int ov9655_init_sensor(struct gspca_dev *gspca_dev) | 1287 | static void ov9655_init_sensor(struct gspca_dev *gspca_dev) |
1297 | { | 1288 | { |
1298 | int i; | ||
1299 | struct sd *sd = (struct sd *) gspca_dev; | 1289 | struct sd *sd = (struct sd *) gspca_dev; |
1300 | 1290 | ||
1301 | for (i = 0; i < ARRAY_SIZE(ov9655_init); i++) { | 1291 | i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */ |
1302 | if (i2c_w1(gspca_dev, ov9655_init[i].reg, | 1292 | msleep(200); |
1303 | ov9655_init[i].val) < 0) { | 1293 | i2c_w1_buf(gspca_dev, ov9655_init, ARRAY_SIZE(ov9655_init)); |
1304 | pr_err("OV9655 sensor initialization failed\n"); | 1294 | if (gspca_dev->usb_err < 0) |
1305 | return -ENODEV; | 1295 | pr_err("OV9655 sensor initialization failed\n"); |
1306 | } | 1296 | |
1307 | } | ||
1308 | /* disable hflip and vflip */ | 1297 | /* disable hflip and vflip */ |
1309 | gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX); | 1298 | gspca_dev->ctrl_dis = (1 << HFLIP) | (1 << VFLIP); |
1310 | sd->hstart = 1; | 1299 | sd->hstart = 1; |
1311 | sd->vstart = 2; | 1300 | sd->vstart = 2; |
1312 | return 0; | ||
1313 | } | 1301 | } |
1314 | 1302 | ||
1315 | static int soi968_init_sensor(struct gspca_dev *gspca_dev) | 1303 | static void soi968_init_sensor(struct gspca_dev *gspca_dev) |
1316 | { | 1304 | { |
1317 | int i; | ||
1318 | struct sd *sd = (struct sd *) gspca_dev; | 1305 | struct sd *sd = (struct sd *) gspca_dev; |
1319 | 1306 | ||
1320 | for (i = 0; i < ARRAY_SIZE(soi968_init); i++) { | 1307 | i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */ |
1321 | if (i2c_w1(gspca_dev, soi968_init[i].reg, | 1308 | msleep(200); |
1322 | soi968_init[i].val) < 0) { | 1309 | i2c_w1_buf(gspca_dev, soi968_init, ARRAY_SIZE(soi968_init)); |
1323 | pr_err("SOI968 sensor initialization failed\n"); | 1310 | if (gspca_dev->usb_err < 0) |
1324 | return -ENODEV; | 1311 | pr_err("SOI968 sensor initialization failed\n"); |
1325 | } | 1312 | |
1326 | } | ||
1327 | /* disable hflip and vflip */ | 1313 | /* disable hflip and vflip */ |
1328 | gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX) | 1314 | gspca_dev->ctrl_dis = (1 << HFLIP) | (1 << VFLIP) |
1329 | | (1 << EXPOSURE_IDX); | 1315 | | (1 << EXPOSURE); |
1330 | sd->hstart = 60; | 1316 | sd->hstart = 60; |
1331 | sd->vstart = 11; | 1317 | sd->vstart = 11; |
1332 | return 0; | ||
1333 | } | 1318 | } |
1334 | 1319 | ||
1335 | static int ov7660_init_sensor(struct gspca_dev *gspca_dev) | 1320 | static void ov7660_init_sensor(struct gspca_dev *gspca_dev) |
1336 | { | 1321 | { |
1337 | int i; | ||
1338 | struct sd *sd = (struct sd *) gspca_dev; | 1322 | struct sd *sd = (struct sd *) gspca_dev; |
1339 | 1323 | ||
1340 | for (i = 0; i < ARRAY_SIZE(ov7660_init); i++) { | 1324 | i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */ |
1341 | if (i2c_w1(gspca_dev, ov7660_init[i].reg, | 1325 | msleep(200); |
1342 | ov7660_init[i].val) < 0) { | 1326 | i2c_w1_buf(gspca_dev, ov7660_init, ARRAY_SIZE(ov7660_init)); |
1343 | pr_err("OV7660 sensor initialization failed\n"); | 1327 | if (gspca_dev->usb_err < 0) |
1344 | return -ENODEV; | 1328 | pr_err("OV7660 sensor initialization failed\n"); |
1345 | } | ||
1346 | } | ||
1347 | sd->hstart = 3; | 1329 | sd->hstart = 3; |
1348 | sd->vstart = 3; | 1330 | sd->vstart = 3; |
1349 | return 0; | ||
1350 | } | 1331 | } |
1351 | 1332 | ||
1352 | static int ov7670_init_sensor(struct gspca_dev *gspca_dev) | 1333 | static void ov7670_init_sensor(struct gspca_dev *gspca_dev) |
1353 | { | 1334 | { |
1354 | int i; | ||
1355 | struct sd *sd = (struct sd *) gspca_dev; | 1335 | struct sd *sd = (struct sd *) gspca_dev; |
1356 | 1336 | ||
1357 | for (i = 0; i < ARRAY_SIZE(ov7670_init); i++) { | 1337 | i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */ |
1358 | if (i2c_w1(gspca_dev, ov7670_init[i].reg, | 1338 | msleep(200); |
1359 | ov7670_init[i].val) < 0) { | 1339 | i2c_w1_buf(gspca_dev, ov7670_init, ARRAY_SIZE(ov7670_init)); |
1360 | pr_err("OV7670 sensor initialization failed\n"); | 1340 | if (gspca_dev->usb_err < 0) |
1361 | return -ENODEV; | 1341 | pr_err("OV7670 sensor initialization failed\n"); |
1362 | } | 1342 | |
1363 | } | ||
1364 | /* disable hflip and vflip */ | 1343 | /* disable hflip and vflip */ |
1365 | gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX); | 1344 | gspca_dev->ctrl_dis = (1 << HFLIP) | (1 << VFLIP); |
1366 | sd->hstart = 0; | 1345 | sd->hstart = 0; |
1367 | sd->vstart = 1; | 1346 | sd->vstart = 1; |
1368 | return 0; | ||
1369 | } | 1347 | } |
1370 | 1348 | ||
1371 | static int mt9v_init_sensor(struct gspca_dev *gspca_dev) | 1349 | static void mt9v_init_sensor(struct gspca_dev *gspca_dev) |
1372 | { | 1350 | { |
1373 | struct sd *sd = (struct sd *) gspca_dev; | 1351 | struct sd *sd = (struct sd *) gspca_dev; |
1374 | int i; | ||
1375 | u16 value; | 1352 | u16 value; |
1376 | int ret; | ||
1377 | 1353 | ||
1378 | sd->i2c_addr = 0x5d; | 1354 | sd->i2c_addr = 0x5d; |
1379 | ret = i2c_r2(gspca_dev, 0xff, &value); | 1355 | i2c_r2(gspca_dev, 0xff, &value); |
1380 | if ((ret == 0) && (value == 0x8243)) { | 1356 | if (gspca_dev->usb_err >= 0 |
1381 | for (i = 0; i < ARRAY_SIZE(mt9v011_init); i++) { | 1357 | && value == 0x8243) { |
1382 | if (i2c_w2(gspca_dev, mt9v011_init[i].reg, | 1358 | i2c_w2_buf(gspca_dev, mt9v011_init, ARRAY_SIZE(mt9v011_init)); |
1383 | mt9v011_init[i].val) < 0) { | 1359 | if (gspca_dev->usb_err < 0) { |
1384 | pr_err("MT9V011 sensor initialization failed\n"); | 1360 | pr_err("MT9V011 sensor initialization failed\n"); |
1385 | return -ENODEV; | 1361 | return; |
1386 | } | ||
1387 | } | 1362 | } |
1388 | sd->hstart = 2; | 1363 | sd->hstart = 2; |
1389 | sd->vstart = 2; | 1364 | sd->vstart = 2; |
1390 | sd->sensor = SENSOR_MT9V011; | 1365 | sd->sensor = SENSOR_MT9V011; |
1391 | pr_info("MT9V011 sensor detected\n"); | 1366 | pr_info("MT9V011 sensor detected\n"); |
1392 | return 0; | 1367 | return; |
1393 | } | 1368 | } |
1394 | 1369 | ||
1370 | gspca_dev->usb_err = 0; | ||
1395 | sd->i2c_addr = 0x5c; | 1371 | sd->i2c_addr = 0x5c; |
1396 | i2c_w2(gspca_dev, 0x01, 0x0004); | 1372 | i2c_w2(gspca_dev, 0x01, 0x0004); |
1397 | ret = i2c_r2(gspca_dev, 0xff, &value); | 1373 | i2c_r2(gspca_dev, 0xff, &value); |
1398 | if ((ret == 0) && (value == 0x823a)) { | 1374 | if (gspca_dev->usb_err >= 0 |
1399 | for (i = 0; i < ARRAY_SIZE(mt9v111_init); i++) { | 1375 | && value == 0x823a) { |
1400 | if (i2c_w2(gspca_dev, mt9v111_init[i].reg, | 1376 | i2c_w2_buf(gspca_dev, mt9v111_init, ARRAY_SIZE(mt9v111_init)); |
1401 | mt9v111_init[i].val) < 0) { | 1377 | if (gspca_dev->usb_err < 0) { |
1402 | pr_err("MT9V111 sensor initialization failed\n"); | 1378 | pr_err("MT9V111 sensor initialization failed\n"); |
1403 | return -ENODEV; | 1379 | return; |
1404 | } | ||
1405 | } | 1380 | } |
1406 | gspca_dev->ctrl_dis = (1 << EXPOSURE_IDX) | 1381 | gspca_dev->ctrl_dis = (1 << EXPOSURE) |
1407 | | (1 << AUTOGAIN_IDX) | 1382 | | (1 << AUTOGAIN) |
1408 | | (1 << GAIN_IDX); | 1383 | | (1 << GAIN); |
1409 | sd->hstart = 2; | 1384 | sd->hstart = 2; |
1410 | sd->vstart = 2; | 1385 | sd->vstart = 2; |
1411 | sd->sensor = SENSOR_MT9V111; | 1386 | sd->sensor = SENSOR_MT9V111; |
1412 | pr_info("MT9V111 sensor detected\n"); | 1387 | pr_info("MT9V111 sensor detected\n"); |
1413 | return 0; | 1388 | return; |
1414 | } | 1389 | } |
1415 | 1390 | ||
1391 | gspca_dev->usb_err = 0; | ||
1416 | sd->i2c_addr = 0x5d; | 1392 | sd->i2c_addr = 0x5d; |
1417 | ret = i2c_w2(gspca_dev, 0xf0, 0x0000); | 1393 | i2c_w2(gspca_dev, 0xf0, 0x0000); |
1418 | if (ret < 0) { | 1394 | if (gspca_dev->usb_err < 0) { |
1395 | gspca_dev->usb_err = 0; | ||
1419 | sd->i2c_addr = 0x48; | 1396 | sd->i2c_addr = 0x48; |
1420 | i2c_w2(gspca_dev, 0xf0, 0x0000); | 1397 | i2c_w2(gspca_dev, 0xf0, 0x0000); |
1421 | } | 1398 | } |
1422 | ret = i2c_r2(gspca_dev, 0x00, &value); | 1399 | i2c_r2(gspca_dev, 0x00, &value); |
1423 | if ((ret == 0) && (value == 0x1229)) { | 1400 | if (gspca_dev->usb_err >= 0 |
1424 | for (i = 0; i < ARRAY_SIZE(mt9v112_init); i++) { | 1401 | && value == 0x1229) { |
1425 | if (i2c_w2(gspca_dev, mt9v112_init[i].reg, | 1402 | i2c_w2_buf(gspca_dev, mt9v112_init, ARRAY_SIZE(mt9v112_init)); |
1426 | mt9v112_init[i].val) < 0) { | 1403 | if (gspca_dev->usb_err < 0) { |
1427 | pr_err("MT9V112 sensor initialization failed\n"); | 1404 | pr_err("MT9V112 sensor initialization failed\n"); |
1428 | return -ENODEV; | 1405 | return; |
1429 | } | ||
1430 | } | 1406 | } |
1431 | sd->hstart = 6; | 1407 | sd->hstart = 6; |
1432 | sd->vstart = 2; | 1408 | sd->vstart = 2; |
1433 | sd->sensor = SENSOR_MT9V112; | 1409 | sd->sensor = SENSOR_MT9V112; |
1434 | pr_info("MT9V112 sensor detected\n"); | 1410 | pr_info("MT9V112 sensor detected\n"); |
1435 | return 0; | 1411 | return; |
1436 | } | 1412 | } |
1437 | 1413 | ||
1438 | return -ENODEV; | 1414 | gspca_dev->usb_err = -ENODEV; |
1439 | } | 1415 | } |
1440 | 1416 | ||
1441 | static int mt9m112_init_sensor(struct gspca_dev *gspca_dev) | 1417 | static void mt9m112_init_sensor(struct gspca_dev *gspca_dev) |
1442 | { | 1418 | { |
1443 | struct sd *sd = (struct sd *) gspca_dev; | 1419 | struct sd *sd = (struct sd *) gspca_dev; |
1444 | int i; | 1420 | |
1445 | for (i = 0; i < ARRAY_SIZE(mt9m112_init); i++) { | 1421 | i2c_w2_buf(gspca_dev, mt9m112_init, ARRAY_SIZE(mt9m112_init)); |
1446 | if (i2c_w2(gspca_dev, mt9m112_init[i].reg, | 1422 | if (gspca_dev->usb_err < 0) |
1447 | mt9m112_init[i].val) < 0) { | 1423 | pr_err("MT9M112 sensor initialization failed\n"); |
1448 | pr_err("MT9M112 sensor initialization failed\n"); | 1424 | |
1449 | return -ENODEV; | 1425 | gspca_dev->ctrl_dis = (1 << EXPOSURE) | (1 << AUTOGAIN) |
1450 | } | 1426 | | (1 << GAIN); |
1451 | } | ||
1452 | gspca_dev->ctrl_dis = (1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX) | ||
1453 | | (1 << GAIN_IDX); | ||
1454 | sd->hstart = 0; | 1427 | sd->hstart = 0; |
1455 | sd->vstart = 2; | 1428 | sd->vstart = 2; |
1456 | return 0; | ||
1457 | } | 1429 | } |
1458 | 1430 | ||
1459 | static int mt9m111_init_sensor(struct gspca_dev *gspca_dev) | 1431 | static void mt9m111_init_sensor(struct gspca_dev *gspca_dev) |
1460 | { | 1432 | { |
1461 | struct sd *sd = (struct sd *) gspca_dev; | 1433 | struct sd *sd = (struct sd *) gspca_dev; |
1462 | int i; | 1434 | |
1463 | for (i = 0; i < ARRAY_SIZE(mt9m111_init); i++) { | 1435 | i2c_w2_buf(gspca_dev, mt9m111_init, ARRAY_SIZE(mt9m111_init)); |
1464 | if (i2c_w2(gspca_dev, mt9m111_init[i].reg, | 1436 | if (gspca_dev->usb_err < 0) |
1465 | mt9m111_init[i].val) < 0) { | 1437 | pr_err("MT9M111 sensor initialization failed\n"); |
1466 | pr_err("MT9M111 sensor initialization failed\n"); | 1438 | |
1467 | return -ENODEV; | 1439 | gspca_dev->ctrl_dis = (1 << EXPOSURE) | (1 << AUTOGAIN) |
1468 | } | 1440 | | (1 << GAIN); |
1469 | } | ||
1470 | gspca_dev->ctrl_dis = (1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX) | ||
1471 | | (1 << GAIN_IDX); | ||
1472 | sd->hstart = 0; | 1441 | sd->hstart = 0; |
1473 | sd->vstart = 2; | 1442 | sd->vstart = 2; |
1474 | return 0; | ||
1475 | } | 1443 | } |
1476 | 1444 | ||
1477 | static int mt9m001_init_sensor(struct gspca_dev *gspca_dev) | 1445 | static void mt9m001_init_sensor(struct gspca_dev *gspca_dev) |
1478 | { | 1446 | { |
1479 | struct sd *sd = (struct sd *) gspca_dev; | 1447 | struct sd *sd = (struct sd *) gspca_dev; |
1480 | int i; | ||
1481 | u16 id; | 1448 | u16 id; |
1482 | 1449 | ||
1483 | if (i2c_r2(gspca_dev, 0x00, &id) < 0) | 1450 | i2c_r2(gspca_dev, 0x00, &id); |
1484 | return -EINVAL; | 1451 | if (gspca_dev->usb_err < 0) |
1452 | return; | ||
1485 | 1453 | ||
1486 | /* must be 0x8411 or 0x8421 for colour sensor and 8431 for bw */ | 1454 | /* must be 0x8411 or 0x8421 for colour sensor and 8431 for bw */ |
1487 | switch (id) { | 1455 | switch (id) { |
@@ -1494,85 +1462,78 @@ static int mt9m001_init_sensor(struct gspca_dev *gspca_dev) | |||
1494 | break; | 1462 | break; |
1495 | default: | 1463 | default: |
1496 | pr_err("No MT9M001 chip detected, ID = %x\n\n", id); | 1464 | pr_err("No MT9M001 chip detected, ID = %x\n\n", id); |
1497 | return -ENODEV; | 1465 | gspca_dev->usb_err = -ENODEV; |
1466 | return; | ||
1498 | } | 1467 | } |
1499 | 1468 | ||
1500 | for (i = 0; i < ARRAY_SIZE(mt9m001_init); i++) { | 1469 | i2c_w2_buf(gspca_dev, mt9m001_init, ARRAY_SIZE(mt9m001_init)); |
1501 | if (i2c_w2(gspca_dev, mt9m001_init[i].reg, | 1470 | if (gspca_dev->usb_err < 0) |
1502 | mt9m001_init[i].val) < 0) { | 1471 | pr_err("MT9M001 sensor initialization failed\n"); |
1503 | pr_err("MT9M001 sensor initialization failed\n"); | 1472 | |
1504 | return -ENODEV; | ||
1505 | } | ||
1506 | } | ||
1507 | /* disable hflip and vflip */ | 1473 | /* disable hflip and vflip */ |
1508 | gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX); | 1474 | gspca_dev->ctrl_dis = (1 << HFLIP) | (1 << VFLIP); |
1509 | sd->hstart = 1; | 1475 | sd->hstart = 1; |
1510 | sd->vstart = 1; | 1476 | sd->vstart = 1; |
1511 | return 0; | ||
1512 | } | 1477 | } |
1513 | 1478 | ||
1514 | static int hv7131r_init_sensor(struct gspca_dev *gspca_dev) | 1479 | static void hv7131r_init_sensor(struct gspca_dev *gspca_dev) |
1515 | { | 1480 | { |
1516 | int i; | ||
1517 | struct sd *sd = (struct sd *) gspca_dev; | 1481 | struct sd *sd = (struct sd *) gspca_dev; |
1518 | 1482 | ||
1519 | for (i = 0; i < ARRAY_SIZE(hv7131r_init); i++) { | 1483 | i2c_w1_buf(gspca_dev, hv7131r_init, ARRAY_SIZE(hv7131r_init)); |
1520 | if (i2c_w1(gspca_dev, hv7131r_init[i].reg, | 1484 | if (gspca_dev->usb_err < 0) |
1521 | hv7131r_init[i].val) < 0) { | 1485 | pr_err("HV7131R Sensor initialization failed\n"); |
1522 | pr_err("HV7131R Sensor initialization failed\n"); | 1486 | |
1523 | return -ENODEV; | ||
1524 | } | ||
1525 | } | ||
1526 | sd->hstart = 0; | 1487 | sd->hstart = 0; |
1527 | sd->vstart = 1; | 1488 | sd->vstart = 1; |
1528 | return 0; | ||
1529 | } | 1489 | } |
1530 | 1490 | ||
1531 | static int set_cmatrix(struct gspca_dev *gspca_dev) | 1491 | static void set_cmatrix(struct gspca_dev *gspca_dev) |
1532 | { | 1492 | { |
1533 | struct sd *sd = (struct sd *) gspca_dev; | 1493 | struct sd *sd = (struct sd *) gspca_dev; |
1534 | s32 hue_coord, hue_index = 180 + sd->hue; | 1494 | int satur; |
1495 | s32 hue_coord, hue_index = 180 + sd->ctrls[HUE].val; | ||
1535 | u8 cmatrix[21]; | 1496 | u8 cmatrix[21]; |
1536 | 1497 | ||
1537 | memset(cmatrix, 0, sizeof cmatrix); | 1498 | memset(cmatrix, 0, sizeof cmatrix); |
1538 | cmatrix[2] = (sd->contrast * 0x25 / 0x100) + 0x26; | 1499 | cmatrix[2] = (sd->ctrls[CONTRAST].val * 0x25 / 0x100) + 0x26; |
1539 | cmatrix[0] = 0x13 + (cmatrix[2] - 0x26) * 0x13 / 0x25; | 1500 | cmatrix[0] = 0x13 + (cmatrix[2] - 0x26) * 0x13 / 0x25; |
1540 | cmatrix[4] = 0x07 + (cmatrix[2] - 0x26) * 0x07 / 0x25; | 1501 | cmatrix[4] = 0x07 + (cmatrix[2] - 0x26) * 0x07 / 0x25; |
1541 | cmatrix[18] = sd->brightness - 0x80; | 1502 | cmatrix[18] = sd->ctrls[BRIGHTNESS].val - 0x80; |
1542 | 1503 | ||
1543 | hue_coord = (hsv_red_x[hue_index] * sd->saturation) >> 8; | 1504 | satur = sd->ctrls[SATURATION].val; |
1505 | hue_coord = (hsv_red_x[hue_index] * satur) >> 8; | ||
1544 | cmatrix[6] = hue_coord; | 1506 | cmatrix[6] = hue_coord; |
1545 | cmatrix[7] = (hue_coord >> 8) & 0x0f; | 1507 | cmatrix[7] = (hue_coord >> 8) & 0x0f; |
1546 | 1508 | ||
1547 | hue_coord = (hsv_red_y[hue_index] * sd->saturation) >> 8; | 1509 | hue_coord = (hsv_red_y[hue_index] * satur) >> 8; |
1548 | cmatrix[8] = hue_coord; | 1510 | cmatrix[8] = hue_coord; |
1549 | cmatrix[9] = (hue_coord >> 8) & 0x0f; | 1511 | cmatrix[9] = (hue_coord >> 8) & 0x0f; |
1550 | 1512 | ||
1551 | hue_coord = (hsv_green_x[hue_index] * sd->saturation) >> 8; | 1513 | hue_coord = (hsv_green_x[hue_index] * satur) >> 8; |
1552 | cmatrix[10] = hue_coord; | 1514 | cmatrix[10] = hue_coord; |
1553 | cmatrix[11] = (hue_coord >> 8) & 0x0f; | 1515 | cmatrix[11] = (hue_coord >> 8) & 0x0f; |
1554 | 1516 | ||
1555 | hue_coord = (hsv_green_y[hue_index] * sd->saturation) >> 8; | 1517 | hue_coord = (hsv_green_y[hue_index] * satur) >> 8; |
1556 | cmatrix[12] = hue_coord; | 1518 | cmatrix[12] = hue_coord; |
1557 | cmatrix[13] = (hue_coord >> 8) & 0x0f; | 1519 | cmatrix[13] = (hue_coord >> 8) & 0x0f; |
1558 | 1520 | ||
1559 | hue_coord = (hsv_blue_x[hue_index] * sd->saturation) >> 8; | 1521 | hue_coord = (hsv_blue_x[hue_index] * satur) >> 8; |
1560 | cmatrix[14] = hue_coord; | 1522 | cmatrix[14] = hue_coord; |
1561 | cmatrix[15] = (hue_coord >> 8) & 0x0f; | 1523 | cmatrix[15] = (hue_coord >> 8) & 0x0f; |
1562 | 1524 | ||
1563 | hue_coord = (hsv_blue_y[hue_index] * sd->saturation) >> 8; | 1525 | hue_coord = (hsv_blue_y[hue_index] * satur) >> 8; |
1564 | cmatrix[16] = hue_coord; | 1526 | cmatrix[16] = hue_coord; |
1565 | cmatrix[17] = (hue_coord >> 8) & 0x0f; | 1527 | cmatrix[17] = (hue_coord >> 8) & 0x0f; |
1566 | 1528 | ||
1567 | return reg_w(gspca_dev, 0x10e1, cmatrix, 21); | 1529 | reg_w(gspca_dev, 0x10e1, cmatrix, 21); |
1568 | } | 1530 | } |
1569 | 1531 | ||
1570 | static int set_gamma(struct gspca_dev *gspca_dev) | 1532 | static void set_gamma(struct gspca_dev *gspca_dev) |
1571 | { | 1533 | { |
1572 | struct sd *sd = (struct sd *) gspca_dev; | 1534 | struct sd *sd = (struct sd *) gspca_dev; |
1573 | u8 gamma[17]; | 1535 | u8 gamma[17]; |
1574 | u8 gval = sd->gamma * 0xb8 / 0x100; | 1536 | u8 gval = sd->ctrls[GAMMA].val * 0xb8 / 0x100; |
1575 | |||
1576 | 1537 | ||
1577 | gamma[0] = 0x0a; | 1538 | gamma[0] = 0x0a; |
1578 | gamma[1] = 0x13 + (gval * (0xcb - 0x13) / 0xb8); | 1539 | gamma[1] = 0x13 + (gval * (0xcb - 0x13) / 0xb8); |
@@ -1592,29 +1553,29 @@ static int set_gamma(struct gspca_dev *gspca_dev) | |||
1592 | gamma[15] = 0xea + (gval * (0xf9 - 0xea) / 0xb8); | 1553 | gamma[15] = 0xea + (gval * (0xf9 - 0xea) / 0xb8); |
1593 | gamma[16] = 0xf5; | 1554 | gamma[16] = 0xf5; |
1594 | 1555 | ||
1595 | return reg_w(gspca_dev, 0x1190, gamma, 17); | 1556 | reg_w(gspca_dev, 0x1190, gamma, 17); |
1596 | } | 1557 | } |
1597 | 1558 | ||
1598 | static int set_redblue(struct gspca_dev *gspca_dev) | 1559 | static void set_redblue(struct gspca_dev *gspca_dev) |
1599 | { | 1560 | { |
1600 | struct sd *sd = (struct sd *) gspca_dev; | 1561 | struct sd *sd = (struct sd *) gspca_dev; |
1601 | reg_w1(gspca_dev, 0x118c, sd->red); | 1562 | |
1602 | reg_w1(gspca_dev, 0x118f, sd->blue); | 1563 | reg_w1(gspca_dev, 0x118c, sd->ctrls[RED].val); |
1603 | return 0; | 1564 | reg_w1(gspca_dev, 0x118f, sd->ctrls[BLUE].val); |
1604 | } | 1565 | } |
1605 | 1566 | ||
1606 | static int set_hvflip(struct gspca_dev *gspca_dev) | 1567 | static void set_hvflip(struct gspca_dev *gspca_dev) |
1607 | { | 1568 | { |
1608 | u8 value, tslb, hflip, vflip; | 1569 | u8 value, tslb, hflip, vflip; |
1609 | u16 value2; | 1570 | u16 value2; |
1610 | struct sd *sd = (struct sd *) gspca_dev; | 1571 | struct sd *sd = (struct sd *) gspca_dev; |
1611 | 1572 | ||
1612 | if ((sd->flags & FLIP_DETECT) && dmi_check_system(flip_dmi_table)) { | 1573 | if ((sd->flags & FLIP_DETECT) && dmi_check_system(flip_dmi_table)) { |
1613 | hflip = !sd->hflip; | 1574 | hflip = !sd->ctrls[HFLIP].val; |
1614 | vflip = !sd->vflip; | 1575 | vflip = !sd->ctrls[VFLIP].val; |
1615 | } else { | 1576 | } else { |
1616 | hflip = sd->hflip; | 1577 | hflip = sd->ctrls[HFLIP].val; |
1617 | vflip = sd->vflip; | 1578 | vflip = sd->ctrls[VFLIP].val; |
1618 | } | 1579 | } |
1619 | 1580 | ||
1620 | switch (sd->sensor) { | 1581 | switch (sd->sensor) { |
@@ -1625,8 +1586,9 @@ static int set_hvflip(struct gspca_dev *gspca_dev) | |||
1625 | if (vflip) { | 1586 | if (vflip) { |
1626 | value |= 0x10; | 1587 | value |= 0x10; |
1627 | sd->vstart = 2; | 1588 | sd->vstart = 2; |
1628 | } else | 1589 | } else { |
1629 | sd->vstart = 3; | 1590 | sd->vstart = 3; |
1591 | } | ||
1630 | reg_w1(gspca_dev, 0x1182, sd->vstart); | 1592 | reg_w1(gspca_dev, 0x1182, sd->vstart); |
1631 | i2c_w1(gspca_dev, 0x1e, value); | 1593 | i2c_w1(gspca_dev, 0x1e, value); |
1632 | break; | 1594 | break; |
@@ -1674,13 +1636,15 @@ static int set_hvflip(struct gspca_dev *gspca_dev) | |||
1674 | i2c_w1(gspca_dev, 0x01, value); | 1636 | i2c_w1(gspca_dev, 0x01, value); |
1675 | break; | 1637 | break; |
1676 | } | 1638 | } |
1677 | return 0; | ||
1678 | } | 1639 | } |
1679 | 1640 | ||
1680 | static int set_exposure(struct gspca_dev *gspca_dev) | 1641 | static void set_exposure(struct gspca_dev *gspca_dev) |
1681 | { | 1642 | { |
1682 | struct sd *sd = (struct sd *) gspca_dev; | 1643 | struct sd *sd = (struct sd *) gspca_dev; |
1683 | u8 exp[8] = {0x81, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e}; | 1644 | u8 exp[8] = {0x81, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e}; |
1645 | int expo; | ||
1646 | |||
1647 | expo = sd->ctrls[EXPOSURE].val; | ||
1684 | switch (sd->sensor) { | 1648 | switch (sd->sensor) { |
1685 | case SENSOR_OV7660: | 1649 | case SENSOR_OV7660: |
1686 | case SENSOR_OV7670: | 1650 | case SENSOR_OV7670: |
@@ -1688,35 +1652,37 @@ static int set_exposure(struct gspca_dev *gspca_dev) | |||
1688 | case SENSOR_OV9650: | 1652 | case SENSOR_OV9650: |
1689 | exp[0] |= (3 << 4); | 1653 | exp[0] |= (3 << 4); |
1690 | exp[2] = 0x2d; | 1654 | exp[2] = 0x2d; |
1691 | exp[3] = sd->exposure & 0xff; | 1655 | exp[3] = expo; |
1692 | exp[4] = sd->exposure >> 8; | 1656 | exp[4] = expo >> 8; |
1693 | break; | 1657 | break; |
1694 | case SENSOR_MT9M001: | 1658 | case SENSOR_MT9M001: |
1695 | case SENSOR_MT9V112: | 1659 | case SENSOR_MT9V112: |
1696 | case SENSOR_MT9V011: | 1660 | case SENSOR_MT9V011: |
1697 | exp[0] |= (3 << 4); | 1661 | exp[0] |= (3 << 4); |
1698 | exp[2] = 0x09; | 1662 | exp[2] = 0x09; |
1699 | exp[3] = sd->exposure >> 8; | 1663 | exp[3] = expo >> 8; |
1700 | exp[4] = sd->exposure & 0xff; | 1664 | exp[4] = expo; |
1701 | break; | 1665 | break; |
1702 | case SENSOR_HV7131R: | 1666 | case SENSOR_HV7131R: |
1703 | exp[0] |= (4 << 4); | 1667 | exp[0] |= (4 << 4); |
1704 | exp[2] = 0x25; | 1668 | exp[2] = 0x25; |
1705 | exp[3] = (sd->exposure >> 5) & 0xff; | 1669 | exp[3] = expo >> 5; |
1706 | exp[4] = (sd->exposure << 3) & 0xff; | 1670 | exp[4] = expo << 3; |
1707 | exp[5] = 0; | 1671 | exp[5] = 0; |
1708 | break; | 1672 | break; |
1709 | default: | 1673 | default: |
1710 | return 0; | 1674 | return; |
1711 | } | 1675 | } |
1712 | i2c_w(gspca_dev, exp); | 1676 | i2c_w(gspca_dev, exp); |
1713 | return 0; | ||
1714 | } | 1677 | } |
1715 | 1678 | ||
1716 | static int set_gain(struct gspca_dev *gspca_dev) | 1679 | static void set_gain(struct gspca_dev *gspca_dev) |
1717 | { | 1680 | { |
1718 | struct sd *sd = (struct sd *) gspca_dev; | 1681 | struct sd *sd = (struct sd *) gspca_dev; |
1719 | u8 gain[8] = {0x81, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d}; | 1682 | u8 gain[8] = {0x81, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d}; |
1683 | int g; | ||
1684 | |||
1685 | g = sd->ctrls[GAIN].val; | ||
1720 | switch (sd->sensor) { | 1686 | switch (sd->sensor) { |
1721 | case SENSOR_OV7660: | 1687 | case SENSOR_OV7660: |
1722 | case SENSOR_OV7670: | 1688 | case SENSOR_OV7670: |
@@ -1724,238 +1690,50 @@ static int set_gain(struct gspca_dev *gspca_dev) | |||
1724 | case SENSOR_OV9655: | 1690 | case SENSOR_OV9655: |
1725 | case SENSOR_OV9650: | 1691 | case SENSOR_OV9650: |
1726 | gain[0] |= (2 << 4); | 1692 | gain[0] |= (2 << 4); |
1727 | gain[3] = ov_gain[sd->gain]; | 1693 | gain[3] = ov_gain[g]; |
1728 | break; | 1694 | break; |
1729 | case SENSOR_MT9V011: | 1695 | case SENSOR_MT9V011: |
1730 | gain[0] |= (3 << 4); | 1696 | gain[0] |= (3 << 4); |
1731 | gain[2] = 0x35; | 1697 | gain[2] = 0x35; |
1732 | gain[3] = micron1_gain[sd->gain] >> 8; | 1698 | gain[3] = micron1_gain[g] >> 8; |
1733 | gain[4] = micron1_gain[sd->gain] & 0xff; | 1699 | gain[4] = micron1_gain[g]; |
1734 | break; | 1700 | break; |
1735 | case SENSOR_MT9V112: | 1701 | case SENSOR_MT9V112: |
1736 | gain[0] |= (3 << 4); | 1702 | gain[0] |= (3 << 4); |
1737 | gain[2] = 0x2f; | 1703 | gain[2] = 0x2f; |
1738 | gain[3] = micron1_gain[sd->gain] >> 8; | 1704 | gain[3] = micron1_gain[g] >> 8; |
1739 | gain[4] = micron1_gain[sd->gain] & 0xff; | 1705 | gain[4] = micron1_gain[g]; |
1740 | break; | 1706 | break; |
1741 | case SENSOR_MT9M001: | 1707 | case SENSOR_MT9M001: |
1742 | gain[0] |= (3 << 4); | 1708 | gain[0] |= (3 << 4); |
1743 | gain[2] = 0x2f; | 1709 | gain[2] = 0x2f; |
1744 | gain[3] = micron2_gain[sd->gain] >> 8; | 1710 | gain[3] = micron2_gain[g] >> 8; |
1745 | gain[4] = micron2_gain[sd->gain] & 0xff; | 1711 | gain[4] = micron2_gain[g]; |
1746 | break; | 1712 | break; |
1747 | case SENSOR_HV7131R: | 1713 | case SENSOR_HV7131R: |
1748 | gain[0] |= (2 << 4); | 1714 | gain[0] |= (2 << 4); |
1749 | gain[2] = 0x30; | 1715 | gain[2] = 0x30; |
1750 | gain[3] = hv7131r_gain[sd->gain]; | 1716 | gain[3] = hv7131r_gain[g]; |
1751 | break; | 1717 | break; |
1752 | default: | 1718 | default: |
1753 | return 0; | 1719 | return; |
1754 | } | 1720 | } |
1755 | i2c_w(gspca_dev, gain); | 1721 | i2c_w(gspca_dev, gain); |
1756 | return 0; | ||
1757 | } | ||
1758 | |||
1759 | static int sd_setbrightness(struct gspca_dev *gspca_dev, s32 val) | ||
1760 | { | ||
1761 | struct sd *sd = (struct sd *) gspca_dev; | ||
1762 | |||
1763 | sd->brightness = val; | ||
1764 | if (gspca_dev->streaming) | ||
1765 | return set_cmatrix(gspca_dev); | ||
1766 | return 0; | ||
1767 | } | ||
1768 | |||
1769 | static int sd_getbrightness(struct gspca_dev *gspca_dev, s32 *val) | ||
1770 | { | ||
1771 | struct sd *sd = (struct sd *) gspca_dev; | ||
1772 | *val = sd->brightness; | ||
1773 | return 0; | ||
1774 | } | ||
1775 | |||
1776 | |||
1777 | static int sd_setcontrast(struct gspca_dev *gspca_dev, s32 val) | ||
1778 | { | ||
1779 | struct sd *sd = (struct sd *) gspca_dev; | ||
1780 | |||
1781 | sd->contrast = val; | ||
1782 | if (gspca_dev->streaming) | ||
1783 | return set_cmatrix(gspca_dev); | ||
1784 | return 0; | ||
1785 | } | ||
1786 | |||
1787 | static int sd_getcontrast(struct gspca_dev *gspca_dev, s32 *val) | ||
1788 | { | ||
1789 | struct sd *sd = (struct sd *) gspca_dev; | ||
1790 | *val = sd->contrast; | ||
1791 | return 0; | ||
1792 | } | ||
1793 | |||
1794 | static int sd_setsaturation(struct gspca_dev *gspca_dev, s32 val) | ||
1795 | { | ||
1796 | struct sd *sd = (struct sd *) gspca_dev; | ||
1797 | |||
1798 | sd->saturation = val; | ||
1799 | if (gspca_dev->streaming) | ||
1800 | return set_cmatrix(gspca_dev); | ||
1801 | return 0; | ||
1802 | } | 1722 | } |
1803 | 1723 | ||
1804 | static int sd_getsaturation(struct gspca_dev *gspca_dev, s32 *val) | 1724 | static void set_quality(struct gspca_dev *gspca_dev) |
1805 | { | 1725 | { |
1806 | struct sd *sd = (struct sd *) gspca_dev; | 1726 | struct sd *sd = (struct sd *) gspca_dev; |
1807 | *val = sd->saturation; | ||
1808 | return 0; | ||
1809 | } | ||
1810 | |||
1811 | static int sd_sethue(struct gspca_dev *gspca_dev, s32 val) | ||
1812 | { | ||
1813 | struct sd *sd = (struct sd *) gspca_dev; | ||
1814 | |||
1815 | sd->hue = val; | ||
1816 | if (gspca_dev->streaming) | ||
1817 | return set_cmatrix(gspca_dev); | ||
1818 | return 0; | ||
1819 | } | ||
1820 | |||
1821 | static int sd_gethue(struct gspca_dev *gspca_dev, s32 *val) | ||
1822 | { | ||
1823 | struct sd *sd = (struct sd *) gspca_dev; | ||
1824 | *val = sd->hue; | ||
1825 | return 0; | ||
1826 | } | ||
1827 | |||
1828 | static int sd_setgamma(struct gspca_dev *gspca_dev, s32 val) | ||
1829 | { | ||
1830 | struct sd *sd = (struct sd *) gspca_dev; | ||
1831 | |||
1832 | sd->gamma = val; | ||
1833 | if (gspca_dev->streaming) | ||
1834 | return set_gamma(gspca_dev); | ||
1835 | return 0; | ||
1836 | } | ||
1837 | |||
1838 | static int sd_getgamma(struct gspca_dev *gspca_dev, s32 *val) | ||
1839 | { | ||
1840 | struct sd *sd = (struct sd *) gspca_dev; | ||
1841 | *val = sd->gamma; | ||
1842 | return 0; | ||
1843 | } | ||
1844 | |||
1845 | static int sd_setredbalance(struct gspca_dev *gspca_dev, s32 val) | ||
1846 | { | ||
1847 | struct sd *sd = (struct sd *) gspca_dev; | ||
1848 | |||
1849 | sd->red = val; | ||
1850 | if (gspca_dev->streaming) | ||
1851 | return set_redblue(gspca_dev); | ||
1852 | return 0; | ||
1853 | } | ||
1854 | |||
1855 | static int sd_getredbalance(struct gspca_dev *gspca_dev, s32 *val) | ||
1856 | { | ||
1857 | struct sd *sd = (struct sd *) gspca_dev; | ||
1858 | *val = sd->red; | ||
1859 | return 0; | ||
1860 | } | ||
1861 | |||
1862 | static int sd_setbluebalance(struct gspca_dev *gspca_dev, s32 val) | ||
1863 | { | ||
1864 | struct sd *sd = (struct sd *) gspca_dev; | ||
1865 | |||
1866 | sd->blue = val; | ||
1867 | if (gspca_dev->streaming) | ||
1868 | return set_redblue(gspca_dev); | ||
1869 | return 0; | ||
1870 | } | ||
1871 | |||
1872 | static int sd_getbluebalance(struct gspca_dev *gspca_dev, s32 *val) | ||
1873 | { | ||
1874 | struct sd *sd = (struct sd *) gspca_dev; | ||
1875 | *val = sd->blue; | ||
1876 | return 0; | ||
1877 | } | ||
1878 | |||
1879 | static int sd_sethflip(struct gspca_dev *gspca_dev, s32 val) | ||
1880 | { | ||
1881 | struct sd *sd = (struct sd *) gspca_dev; | ||
1882 | |||
1883 | sd->hflip = val; | ||
1884 | if (gspca_dev->streaming) | ||
1885 | return set_hvflip(gspca_dev); | ||
1886 | return 0; | ||
1887 | } | ||
1888 | |||
1889 | static int sd_gethflip(struct gspca_dev *gspca_dev, s32 *val) | ||
1890 | { | ||
1891 | struct sd *sd = (struct sd *) gspca_dev; | ||
1892 | *val = sd->hflip; | ||
1893 | return 0; | ||
1894 | } | ||
1895 | |||
1896 | static int sd_setvflip(struct gspca_dev *gspca_dev, s32 val) | ||
1897 | { | ||
1898 | struct sd *sd = (struct sd *) gspca_dev; | ||
1899 | |||
1900 | sd->vflip = val; | ||
1901 | if (gspca_dev->streaming) | ||
1902 | return set_hvflip(gspca_dev); | ||
1903 | return 0; | ||
1904 | } | ||
1905 | |||
1906 | static int sd_getvflip(struct gspca_dev *gspca_dev, s32 *val) | ||
1907 | { | ||
1908 | struct sd *sd = (struct sd *) gspca_dev; | ||
1909 | *val = sd->vflip; | ||
1910 | return 0; | ||
1911 | } | ||
1912 | |||
1913 | static int sd_setexposure(struct gspca_dev *gspca_dev, s32 val) | ||
1914 | { | ||
1915 | struct sd *sd = (struct sd *) gspca_dev; | ||
1916 | |||
1917 | sd->exposure = val; | ||
1918 | if (gspca_dev->streaming) | ||
1919 | return set_exposure(gspca_dev); | ||
1920 | return 0; | ||
1921 | } | ||
1922 | |||
1923 | static int sd_getexposure(struct gspca_dev *gspca_dev, s32 *val) | ||
1924 | { | ||
1925 | struct sd *sd = (struct sd *) gspca_dev; | ||
1926 | *val = sd->exposure; | ||
1927 | return 0; | ||
1928 | } | ||
1929 | |||
1930 | static int sd_setgain(struct gspca_dev *gspca_dev, s32 val) | ||
1931 | { | ||
1932 | struct sd *sd = (struct sd *) gspca_dev; | ||
1933 | |||
1934 | sd->gain = val; | ||
1935 | if (gspca_dev->streaming) | ||
1936 | return set_gain(gspca_dev); | ||
1937 | return 0; | ||
1938 | } | ||
1939 | |||
1940 | static int sd_getgain(struct gspca_dev *gspca_dev, s32 *val) | ||
1941 | { | ||
1942 | struct sd *sd = (struct sd *) gspca_dev; | ||
1943 | *val = sd->gain; | ||
1944 | return 0; | ||
1945 | } | ||
1946 | |||
1947 | static int sd_setautoexposure(struct gspca_dev *gspca_dev, s32 val) | ||
1948 | { | ||
1949 | struct sd *sd = (struct sd *) gspca_dev; | ||
1950 | sd->auto_exposure = val; | ||
1951 | return 0; | ||
1952 | } | ||
1953 | 1727 | ||
1954 | static int sd_getautoexposure(struct gspca_dev *gspca_dev, s32 *val) | 1728 | jpeg_set_qual(sd->jpeg_hdr, sd->ctrls[QUALITY].val); |
1955 | { | 1729 | reg_w1(gspca_dev, 0x1061, 0x01); /* stop transfer */ |
1956 | struct sd *sd = (struct sd *) gspca_dev; | 1730 | reg_w1(gspca_dev, 0x10e0, sd->fmt | 0x20); /* write QTAB */ |
1957 | *val = sd->auto_exposure; | 1731 | reg_w(gspca_dev, 0x1100, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64); |
1958 | return 0; | 1732 | reg_w(gspca_dev, 0x1140, &sd->jpeg_hdr[JPEG_QT1_OFFSET], 64); |
1733 | reg_w1(gspca_dev, 0x1061, 0x03); /* restart transfer */ | ||
1734 | reg_w1(gspca_dev, 0x10e0, sd->fmt); | ||
1735 | sd->fmt ^= 0x0c; /* invert QTAB use + write */ | ||
1736 | reg_w1(gspca_dev, 0x10e0, sd->fmt); | ||
1959 | } | 1737 | } |
1960 | 1738 | ||
1961 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 1739 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
@@ -1963,28 +1741,26 @@ static int sd_dbg_g_register(struct gspca_dev *gspca_dev, | |||
1963 | struct v4l2_dbg_register *reg) | 1741 | struct v4l2_dbg_register *reg) |
1964 | { | 1742 | { |
1965 | struct sd *sd = (struct sd *) gspca_dev; | 1743 | struct sd *sd = (struct sd *) gspca_dev; |
1744 | |||
1966 | switch (reg->match.type) { | 1745 | switch (reg->match.type) { |
1967 | case V4L2_CHIP_MATCH_HOST: | 1746 | case V4L2_CHIP_MATCH_HOST: |
1968 | if (reg->match.addr != 0) | 1747 | if (reg->match.addr != 0) |
1969 | return -EINVAL; | 1748 | return -EINVAL; |
1970 | if (reg->reg < 0x1000 || reg->reg > 0x11ff) | 1749 | if (reg->reg < 0x1000 || reg->reg > 0x11ff) |
1971 | return -EINVAL; | 1750 | return -EINVAL; |
1972 | if (reg_r(gspca_dev, reg->reg, 1) < 0) | 1751 | reg_r(gspca_dev, reg->reg, 1); |
1973 | return -EINVAL; | ||
1974 | reg->val = gspca_dev->usb_buf[0]; | 1752 | reg->val = gspca_dev->usb_buf[0]; |
1975 | return 0; | 1753 | return gspca_dev->usb_err; |
1976 | case V4L2_CHIP_MATCH_I2C_ADDR: | 1754 | case V4L2_CHIP_MATCH_I2C_ADDR: |
1977 | if (reg->match.addr != sd->i2c_addr) | 1755 | if (reg->match.addr != sd->i2c_addr) |
1978 | return -EINVAL; | 1756 | return -EINVAL; |
1979 | if (sd->sensor >= SENSOR_MT9V011 && | 1757 | if (sd->sensor >= SENSOR_MT9V011 && |
1980 | sd->sensor <= SENSOR_MT9M112) { | 1758 | sd->sensor <= SENSOR_MT9M112) { |
1981 | if (i2c_r2(gspca_dev, reg->reg, (u16 *)®->val) < 0) | 1759 | i2c_r2(gspca_dev, reg->reg, (u16 *) ®->val); |
1982 | return -EINVAL; | ||
1983 | } else { | 1760 | } else { |
1984 | if (i2c_r1(gspca_dev, reg->reg, (u8 *)®->val) < 0) | 1761 | i2c_r1(gspca_dev, reg->reg, (u8 *) ®->val); |
1985 | return -EINVAL; | ||
1986 | } | 1762 | } |
1987 | return 0; | 1763 | return gspca_dev->usb_err; |
1988 | } | 1764 | } |
1989 | return -EINVAL; | 1765 | return -EINVAL; |
1990 | } | 1766 | } |
@@ -1993,27 +1769,25 @@ static int sd_dbg_s_register(struct gspca_dev *gspca_dev, | |||
1993 | struct v4l2_dbg_register *reg) | 1769 | struct v4l2_dbg_register *reg) |
1994 | { | 1770 | { |
1995 | struct sd *sd = (struct sd *) gspca_dev; | 1771 | struct sd *sd = (struct sd *) gspca_dev; |
1772 | |||
1996 | switch (reg->match.type) { | 1773 | switch (reg->match.type) { |
1997 | case V4L2_CHIP_MATCH_HOST: | 1774 | case V4L2_CHIP_MATCH_HOST: |
1998 | if (reg->match.addr != 0) | 1775 | if (reg->match.addr != 0) |
1999 | return -EINVAL; | 1776 | return -EINVAL; |
2000 | if (reg->reg < 0x1000 || reg->reg > 0x11ff) | 1777 | if (reg->reg < 0x1000 || reg->reg > 0x11ff) |
2001 | return -EINVAL; | 1778 | return -EINVAL; |
2002 | if (reg_w1(gspca_dev, reg->reg, reg->val) < 0) | 1779 | reg_w1(gspca_dev, reg->reg, reg->val); |
2003 | return -EINVAL; | 1780 | return gspca_dev->usb_err; |
2004 | return 0; | ||
2005 | case V4L2_CHIP_MATCH_I2C_ADDR: | 1781 | case V4L2_CHIP_MATCH_I2C_ADDR: |
2006 | if (reg->match.addr != sd->i2c_addr) | 1782 | if (reg->match.addr != sd->i2c_addr) |
2007 | return -EINVAL; | 1783 | return -EINVAL; |
2008 | if (sd->sensor >= SENSOR_MT9V011 && | 1784 | if (sd->sensor >= SENSOR_MT9V011 && |
2009 | sd->sensor <= SENSOR_MT9M112) { | 1785 | sd->sensor <= SENSOR_MT9M112) { |
2010 | if (i2c_w2(gspca_dev, reg->reg, reg->val) < 0) | 1786 | i2c_w2(gspca_dev, reg->reg, reg->val); |
2011 | return -EINVAL; | ||
2012 | } else { | 1787 | } else { |
2013 | if (i2c_w1(gspca_dev, reg->reg, reg->val) < 0) | 1788 | i2c_w1(gspca_dev, reg->reg, reg->val); |
2014 | return -EINVAL; | ||
2015 | } | 1789 | } |
2016 | return 0; | 1790 | return gspca_dev->usb_err; |
2017 | } | 1791 | } |
2018 | return -EINVAL; | 1792 | return -EINVAL; |
2019 | } | 1793 | } |
@@ -2050,9 +1824,9 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
2050 | cam = &gspca_dev->cam; | 1824 | cam = &gspca_dev->cam; |
2051 | cam->needs_full_bandwidth = 1; | 1825 | cam->needs_full_bandwidth = 1; |
2052 | 1826 | ||
2053 | sd->sensor = (id->driver_info >> 8) & 0xff; | 1827 | sd->sensor = id->driver_info >> 8; |
2054 | sd->i2c_addr = id->driver_info & 0xff; | 1828 | sd->i2c_addr = id->driver_info; |
2055 | sd->flags = (id->driver_info >> 16) & 0xff; | 1829 | sd->flags = id->driver_info >> 16; |
2056 | 1830 | ||
2057 | switch (sd->sensor) { | 1831 | switch (sd->sensor) { |
2058 | case SENSOR_MT9M112: | 1832 | case SENSOR_MT9M112: |
@@ -2076,21 +1850,9 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
2076 | sd->older_step = 0; | 1850 | sd->older_step = 0; |
2077 | sd->exposure_step = 16; | 1851 | sd->exposure_step = 16; |
2078 | 1852 | ||
2079 | sd->brightness = BRIGHTNESS_DEFAULT; | 1853 | gspca_dev->cam.ctrls = sd->ctrls; |
2080 | sd->contrast = CONTRAST_DEFAULT; | ||
2081 | sd->saturation = SATURATION_DEFAULT; | ||
2082 | sd->hue = HUE_DEFAULT; | ||
2083 | sd->gamma = GAMMA_DEFAULT; | ||
2084 | sd->red = RED_DEFAULT; | ||
2085 | sd->blue = BLUE_DEFAULT; | ||
2086 | 1854 | ||
2087 | sd->hflip = HFLIP_DEFAULT; | 1855 | INIT_WORK(&sd->work, qual_upd); |
2088 | sd->vflip = VFLIP_DEFAULT; | ||
2089 | sd->exposure = EXPOSURE_DEFAULT; | ||
2090 | sd->gain = GAIN_DEFAULT; | ||
2091 | sd->auto_exposure = AUTO_EXPOSURE_DEFAULT; | ||
2092 | |||
2093 | sd->quality = 95; | ||
2094 | 1856 | ||
2095 | return 0; | 1857 | return 0; |
2096 | } | 1858 | } |
@@ -2105,9 +1867,10 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
2105 | 1867 | ||
2106 | for (i = 0; i < ARRAY_SIZE(bridge_init); i++) { | 1868 | for (i = 0; i < ARRAY_SIZE(bridge_init); i++) { |
2107 | value = bridge_init[i][1]; | 1869 | value = bridge_init[i][1]; |
2108 | if (reg_w(gspca_dev, bridge_init[i][0], &value, 1) < 0) { | 1870 | reg_w(gspca_dev, bridge_init[i][0], &value, 1); |
1871 | if (gspca_dev->usb_err < 0) { | ||
2109 | pr_err("Device initialization failed\n"); | 1872 | pr_err("Device initialization failed\n"); |
2110 | return -ENODEV; | 1873 | return gspca_dev->usb_err; |
2111 | } | 1874 | } |
2112 | } | 1875 | } |
2113 | 1876 | ||
@@ -2116,72 +1879,85 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
2116 | else | 1879 | else |
2117 | reg_w1(gspca_dev, 0x1006, 0x20); | 1880 | reg_w1(gspca_dev, 0x1006, 0x20); |
2118 | 1881 | ||
2119 | if (reg_w(gspca_dev, 0x10c0, i2c_init, 9) < 0) { | 1882 | reg_w(gspca_dev, 0x10c0, i2c_init, 9); |
1883 | if (gspca_dev->usb_err < 0) { | ||
2120 | pr_err("Device initialization failed\n"); | 1884 | pr_err("Device initialization failed\n"); |
2121 | return -ENODEV; | 1885 | return gspca_dev->usb_err; |
2122 | } | 1886 | } |
2123 | 1887 | ||
2124 | switch (sd->sensor) { | 1888 | switch (sd->sensor) { |
2125 | case SENSOR_OV9650: | 1889 | case SENSOR_OV9650: |
2126 | if (ov9650_init_sensor(gspca_dev) < 0) | 1890 | ov9650_init_sensor(gspca_dev); |
2127 | return -ENODEV; | 1891 | if (gspca_dev->usb_err < 0) |
1892 | break; | ||
2128 | pr_info("OV9650 sensor detected\n"); | 1893 | pr_info("OV9650 sensor detected\n"); |
2129 | break; | 1894 | break; |
2130 | case SENSOR_OV9655: | 1895 | case SENSOR_OV9655: |
2131 | if (ov9655_init_sensor(gspca_dev) < 0) | 1896 | ov9655_init_sensor(gspca_dev); |
2132 | return -ENODEV; | 1897 | if (gspca_dev->usb_err < 0) |
1898 | break; | ||
2133 | pr_info("OV9655 sensor detected\n"); | 1899 | pr_info("OV9655 sensor detected\n"); |
2134 | break; | 1900 | break; |
2135 | case SENSOR_SOI968: | 1901 | case SENSOR_SOI968: |
2136 | if (soi968_init_sensor(gspca_dev) < 0) | 1902 | soi968_init_sensor(gspca_dev); |
2137 | return -ENODEV; | 1903 | if (gspca_dev->usb_err < 0) |
1904 | break; | ||
2138 | pr_info("SOI968 sensor detected\n"); | 1905 | pr_info("SOI968 sensor detected\n"); |
2139 | break; | 1906 | break; |
2140 | case SENSOR_OV7660: | 1907 | case SENSOR_OV7660: |
2141 | if (ov7660_init_sensor(gspca_dev) < 0) | 1908 | ov7660_init_sensor(gspca_dev); |
2142 | return -ENODEV; | 1909 | if (gspca_dev->usb_err < 0) |
1910 | break; | ||
2143 | pr_info("OV7660 sensor detected\n"); | 1911 | pr_info("OV7660 sensor detected\n"); |
2144 | break; | 1912 | break; |
2145 | case SENSOR_OV7670: | 1913 | case SENSOR_OV7670: |
2146 | if (ov7670_init_sensor(gspca_dev) < 0) | 1914 | ov7670_init_sensor(gspca_dev); |
2147 | return -ENODEV; | 1915 | if (gspca_dev->usb_err < 0) |
1916 | break; | ||
2148 | pr_info("OV7670 sensor detected\n"); | 1917 | pr_info("OV7670 sensor detected\n"); |
2149 | break; | 1918 | break; |
2150 | case SENSOR_MT9VPRB: | 1919 | case SENSOR_MT9VPRB: |
2151 | if (mt9v_init_sensor(gspca_dev) < 0) | 1920 | mt9v_init_sensor(gspca_dev); |
2152 | return -ENODEV; | 1921 | if (gspca_dev->usb_err < 0) |
1922 | break; | ||
1923 | pr_info("MT9VPRB sensor detected\n"); | ||
2153 | break; | 1924 | break; |
2154 | case SENSOR_MT9M111: | 1925 | case SENSOR_MT9M111: |
2155 | if (mt9m111_init_sensor(gspca_dev) < 0) | 1926 | mt9m111_init_sensor(gspca_dev); |
2156 | return -ENODEV; | 1927 | if (gspca_dev->usb_err < 0) |
1928 | break; | ||
2157 | pr_info("MT9M111 sensor detected\n"); | 1929 | pr_info("MT9M111 sensor detected\n"); |
2158 | break; | 1930 | break; |
2159 | case SENSOR_MT9M112: | 1931 | case SENSOR_MT9M112: |
2160 | if (mt9m112_init_sensor(gspca_dev) < 0) | 1932 | mt9m112_init_sensor(gspca_dev); |
2161 | return -ENODEV; | 1933 | if (gspca_dev->usb_err < 0) |
1934 | break; | ||
2162 | pr_info("MT9M112 sensor detected\n"); | 1935 | pr_info("MT9M112 sensor detected\n"); |
2163 | break; | 1936 | break; |
2164 | case SENSOR_MT9M001: | 1937 | case SENSOR_MT9M001: |
2165 | if (mt9m001_init_sensor(gspca_dev) < 0) | 1938 | mt9m001_init_sensor(gspca_dev); |
2166 | return -ENODEV; | 1939 | if (gspca_dev->usb_err < 0) |
1940 | break; | ||
2167 | break; | 1941 | break; |
2168 | case SENSOR_HV7131R: | 1942 | case SENSOR_HV7131R: |
2169 | if (hv7131r_init_sensor(gspca_dev) < 0) | 1943 | hv7131r_init_sensor(gspca_dev); |
2170 | return -ENODEV; | 1944 | if (gspca_dev->usb_err < 0) |
1945 | break; | ||
2171 | pr_info("HV7131R sensor detected\n"); | 1946 | pr_info("HV7131R sensor detected\n"); |
2172 | break; | 1947 | break; |
2173 | default: | 1948 | default: |
2174 | pr_info("Unsupported Sensor\n"); | 1949 | pr_err("Unsupported sensor\n"); |
2175 | return -ENODEV; | 1950 | gspca_dev->usb_err = -ENODEV; |
2176 | } | 1951 | } |
2177 | 1952 | ||
2178 | return 0; | 1953 | return gspca_dev->usb_err; |
2179 | } | 1954 | } |
2180 | 1955 | ||
2181 | static void configure_sensor_output(struct gspca_dev *gspca_dev, int mode) | 1956 | static void configure_sensor_output(struct gspca_dev *gspca_dev, int mode) |
2182 | { | 1957 | { |
2183 | struct sd *sd = (struct sd *) gspca_dev; | 1958 | struct sd *sd = (struct sd *) gspca_dev; |
2184 | u8 value; | 1959 | u8 value; |
1960 | |||
2185 | switch (sd->sensor) { | 1961 | switch (sd->sensor) { |
2186 | case SENSOR_SOI968: | 1962 | case SENSOR_SOI968: |
2187 | if (mode & MODE_SXGA) { | 1963 | if (mode & MODE_SXGA) { |
@@ -2264,6 +2040,7 @@ static int sd_isoc_init(struct gspca_dev *gspca_dev) | |||
2264 | break; | 2040 | break; |
2265 | default: /* >= 640x480 */ | 2041 | default: /* >= 640x480 */ |
2266 | gspca_dev->alt = 9; | 2042 | gspca_dev->alt = 9; |
2043 | break; | ||
2267 | } | 2044 | } |
2268 | } | 2045 | } |
2269 | 2046 | ||
@@ -2290,14 +2067,15 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
2290 | 2067 | ||
2291 | jpeg_define(sd->jpeg_hdr, height, width, | 2068 | jpeg_define(sd->jpeg_hdr, height, width, |
2292 | 0x21); | 2069 | 0x21); |
2293 | jpeg_set_qual(sd->jpeg_hdr, sd->quality); | 2070 | jpeg_set_qual(sd->jpeg_hdr, sd->ctrls[QUALITY].val); |
2294 | 2071 | ||
2295 | if (mode & MODE_RAW) | 2072 | if (mode & MODE_RAW) |
2296 | fmt = 0x2d; | 2073 | fmt = 0x2d; |
2297 | else if (mode & MODE_JPEG) | 2074 | else if (mode & MODE_JPEG) |
2298 | fmt = 0x2c; | 2075 | fmt = 0x24; |
2299 | else | 2076 | else |
2300 | fmt = 0x2f; /* YUV 420 */ | 2077 | fmt = 0x2f; /* YUV 420 */ |
2078 | sd->fmt = fmt; | ||
2301 | 2079 | ||
2302 | switch (mode & SCALE_MASK) { | 2080 | switch (mode & SCALE_MASK) { |
2303 | case SCALE_1280x1024: | 2081 | case SCALE_1280x1024: |
@@ -2334,18 +2112,37 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
2334 | set_hvflip(gspca_dev); | 2112 | set_hvflip(gspca_dev); |
2335 | 2113 | ||
2336 | reg_w1(gspca_dev, 0x1007, 0x20); | 2114 | reg_w1(gspca_dev, 0x1007, 0x20); |
2115 | reg_w1(gspca_dev, 0x1061, 0x03); | ||
2116 | |||
2117 | /* if JPEG, prepare the compression quality update */ | ||
2118 | if (mode & MODE_JPEG) { | ||
2119 | sd->pktsz = sd->npkt = 0; | ||
2120 | sd->nchg = 0; | ||
2121 | sd->work_thread = | ||
2122 | create_singlethread_workqueue(KBUILD_MODNAME); | ||
2123 | } | ||
2337 | 2124 | ||
2338 | reg_r(gspca_dev, 0x1061, 1); | 2125 | return gspca_dev->usb_err; |
2339 | reg_w1(gspca_dev, 0x1061, gspca_dev->usb_buf[0] | 0x02); | ||
2340 | return 0; | ||
2341 | } | 2126 | } |
2342 | 2127 | ||
2343 | static void sd_stopN(struct gspca_dev *gspca_dev) | 2128 | static void sd_stopN(struct gspca_dev *gspca_dev) |
2344 | { | 2129 | { |
2345 | reg_w1(gspca_dev, 0x1007, 0x00); | 2130 | reg_w1(gspca_dev, 0x1007, 0x00); |
2131 | reg_w1(gspca_dev, 0x1061, 0x01); | ||
2132 | } | ||
2133 | |||
2134 | /* called on streamoff with alt==0 and on disconnect */ | ||
2135 | /* the usb_lock is held at entry - restore on exit */ | ||
2136 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
2137 | { | ||
2138 | struct sd *sd = (struct sd *) gspca_dev; | ||
2346 | 2139 | ||
2347 | reg_r(gspca_dev, 0x1061, 1); | 2140 | if (sd->work_thread != NULL) { |
2348 | reg_w1(gspca_dev, 0x1061, gspca_dev->usb_buf[0] & ~0x02); | 2141 | mutex_unlock(&gspca_dev->usb_lock); |
2142 | destroy_workqueue(sd->work_thread); | ||
2143 | mutex_lock(&gspca_dev->usb_lock); | ||
2144 | sd->work_thread = NULL; | ||
2145 | } | ||
2349 | } | 2146 | } |
2350 | 2147 | ||
2351 | static void do_autoexposure(struct gspca_dev *gspca_dev, u16 avg_lum) | 2148 | static void do_autoexposure(struct gspca_dev *gspca_dev, u16 avg_lum) |
@@ -2359,15 +2156,15 @@ static void do_autoexposure(struct gspca_dev *gspca_dev, u16 avg_lum) | |||
2359 | * and exposure steps | 2156 | * and exposure steps |
2360 | */ | 2157 | */ |
2361 | if (avg_lum < MIN_AVG_LUM) { | 2158 | if (avg_lum < MIN_AVG_LUM) { |
2362 | if (sd->exposure > 0x1770) | 2159 | if (sd->ctrls[EXPOSURE].val > 0x1770) |
2363 | return; | 2160 | return; |
2364 | 2161 | ||
2365 | new_exp = sd->exposure + sd->exposure_step; | 2162 | new_exp = sd->ctrls[EXPOSURE].val + sd->exposure_step; |
2366 | if (new_exp > 0x1770) | 2163 | if (new_exp > 0x1770) |
2367 | new_exp = 0x1770; | 2164 | new_exp = 0x1770; |
2368 | if (new_exp < 0x10) | 2165 | if (new_exp < 0x10) |
2369 | new_exp = 0x10; | 2166 | new_exp = 0x10; |
2370 | sd->exposure = new_exp; | 2167 | sd->ctrls[EXPOSURE].val = new_exp; |
2371 | set_exposure(gspca_dev); | 2168 | set_exposure(gspca_dev); |
2372 | 2169 | ||
2373 | sd->older_step = sd->old_step; | 2170 | sd->older_step = sd->old_step; |
@@ -2379,14 +2176,14 @@ static void do_autoexposure(struct gspca_dev *gspca_dev, u16 avg_lum) | |||
2379 | sd->exposure_step += 2; | 2176 | sd->exposure_step += 2; |
2380 | } | 2177 | } |
2381 | if (avg_lum > MAX_AVG_LUM) { | 2178 | if (avg_lum > MAX_AVG_LUM) { |
2382 | if (sd->exposure < 0x10) | 2179 | if (sd->ctrls[EXPOSURE].val < 0x10) |
2383 | return; | 2180 | return; |
2384 | new_exp = sd->exposure - sd->exposure_step; | 2181 | new_exp = sd->ctrls[EXPOSURE].val - sd->exposure_step; |
2385 | if (new_exp > 0x1700) | 2182 | if (new_exp > 0x1700) |
2386 | new_exp = 0x1770; | 2183 | new_exp = 0x1770; |
2387 | if (new_exp < 0x10) | 2184 | if (new_exp < 0x10) |
2388 | new_exp = 0x10; | 2185 | new_exp = 0x10; |
2389 | sd->exposure = new_exp; | 2186 | sd->ctrls[EXPOSURE].val = new_exp; |
2390 | set_exposure(gspca_dev); | 2187 | set_exposure(gspca_dev); |
2391 | sd->older_step = sd->old_step; | 2188 | sd->older_step = sd->old_step; |
2392 | sd->old_step = 0; | 2189 | sd->old_step = 0; |
@@ -2403,14 +2200,14 @@ static void do_autogain(struct gspca_dev *gspca_dev, u16 avg_lum) | |||
2403 | struct sd *sd = (struct sd *) gspca_dev; | 2200 | struct sd *sd = (struct sd *) gspca_dev; |
2404 | 2201 | ||
2405 | if (avg_lum < MIN_AVG_LUM) { | 2202 | if (avg_lum < MIN_AVG_LUM) { |
2406 | if (sd->gain + 1 <= 28) { | 2203 | if (sd->ctrls[GAIN].val + 1 <= 28) { |
2407 | sd->gain++; | 2204 | sd->ctrls[GAIN].val++; |
2408 | set_gain(gspca_dev); | 2205 | set_gain(gspca_dev); |
2409 | } | 2206 | } |
2410 | } | 2207 | } |
2411 | if (avg_lum > MAX_AVG_LUM) { | 2208 | if (avg_lum > MAX_AVG_LUM) { |
2412 | if (sd->gain > 0) { | 2209 | if (sd->ctrls[GAIN].val > 0) { |
2413 | sd->gain--; | 2210 | sd->ctrls[GAIN].val--; |
2414 | set_gain(gspca_dev); | 2211 | set_gain(gspca_dev); |
2415 | } | 2212 | } |
2416 | } | 2213 | } |
@@ -2421,7 +2218,7 @@ static void sd_dqcallback(struct gspca_dev *gspca_dev) | |||
2421 | struct sd *sd = (struct sd *) gspca_dev; | 2218 | struct sd *sd = (struct sd *) gspca_dev; |
2422 | int avg_lum; | 2219 | int avg_lum; |
2423 | 2220 | ||
2424 | if (!sd->auto_exposure) | 2221 | if (!sd->ctrls[AUTOGAIN].val) |
2425 | return; | 2222 | return; |
2426 | 2223 | ||
2427 | avg_lum = atomic_read(&sd->avg_lum); | 2224 | avg_lum = atomic_read(&sd->avg_lum); |
@@ -2431,33 +2228,92 @@ static void sd_dqcallback(struct gspca_dev *gspca_dev) | |||
2431 | do_autoexposure(gspca_dev, avg_lum); | 2228 | do_autoexposure(gspca_dev, avg_lum); |
2432 | } | 2229 | } |
2433 | 2230 | ||
2231 | /* JPEG quality update */ | ||
2232 | /* This function is executed from a work queue. */ | ||
2233 | static void qual_upd(struct work_struct *work) | ||
2234 | { | ||
2235 | struct sd *sd = container_of(work, struct sd, work); | ||
2236 | struct gspca_dev *gspca_dev = &sd->gspca_dev; | ||
2237 | |||
2238 | mutex_lock(&gspca_dev->usb_lock); | ||
2239 | PDEBUG(D_STREAM, "qual_upd %d%%", sd->ctrls[QUALITY].val); | ||
2240 | set_quality(gspca_dev); | ||
2241 | mutex_unlock(&gspca_dev->usb_lock); | ||
2242 | } | ||
2243 | |||
2434 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) | 2244 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) |
2435 | static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, | 2245 | static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, |
2436 | u8 *data, /* interrupt packet */ | 2246 | u8 *data, /* interrupt packet */ |
2437 | int len) /* interrupt packet length */ | 2247 | int len) /* interrupt packet length */ |
2438 | { | 2248 | { |
2439 | struct sd *sd = (struct sd *) gspca_dev; | 2249 | struct sd *sd = (struct sd *) gspca_dev; |
2440 | int ret = -EINVAL; | 2250 | |
2441 | if (!(sd->flags & HAS_NO_BUTTON) && len == 1) { | 2251 | if (!(sd->flags & HAS_NO_BUTTON) && len == 1) { |
2442 | input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1); | 2252 | input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1); |
2443 | input_sync(gspca_dev->input_dev); | 2253 | input_sync(gspca_dev->input_dev); |
2444 | input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0); | 2254 | input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0); |
2445 | input_sync(gspca_dev->input_dev); | 2255 | input_sync(gspca_dev->input_dev); |
2446 | ret = 0; | 2256 | return 0; |
2447 | } | 2257 | } |
2448 | return ret; | 2258 | return -EINVAL; |
2449 | } | 2259 | } |
2450 | #endif | 2260 | #endif |
2451 | 2261 | ||
2262 | /* check the JPEG compression */ | ||
2263 | static void transfer_check(struct gspca_dev *gspca_dev, | ||
2264 | u8 *data) | ||
2265 | { | ||
2266 | struct sd *sd = (struct sd *) gspca_dev; | ||
2267 | int new_qual, r; | ||
2268 | |||
2269 | new_qual = 0; | ||
2270 | |||
2271 | /* if USB error, discard the frame and decrease the quality */ | ||
2272 | if (data[6] & 0x08) { /* USB FIFO full */ | ||
2273 | gspca_dev->last_packet_type = DISCARD_PACKET; | ||
2274 | new_qual = -5; | ||
2275 | } else { | ||
2276 | |||
2277 | /* else, compute the filling rate and a new JPEG quality */ | ||
2278 | r = (sd->pktsz * 100) / | ||
2279 | (sd->npkt * | ||
2280 | gspca_dev->urb[0]->iso_frame_desc[0].length); | ||
2281 | if (r >= 85) | ||
2282 | new_qual = -3; | ||
2283 | else if (r < 75) | ||
2284 | new_qual = 2; | ||
2285 | } | ||
2286 | if (new_qual != 0) { | ||
2287 | sd->nchg += new_qual; | ||
2288 | if (sd->nchg < -6 || sd->nchg >= 12) { | ||
2289 | sd->nchg = 0; | ||
2290 | new_qual += sd->ctrls[QUALITY].val; | ||
2291 | if (new_qual < QUALITY_MIN) | ||
2292 | new_qual = QUALITY_MIN; | ||
2293 | else if (new_qual > QUALITY_MAX) | ||
2294 | new_qual = QUALITY_MAX; | ||
2295 | if (new_qual != sd->ctrls[QUALITY].val) { | ||
2296 | sd->ctrls[QUALITY].val = new_qual; | ||
2297 | queue_work(sd->work_thread, &sd->work); | ||
2298 | } | ||
2299 | } | ||
2300 | } else { | ||
2301 | sd->nchg = 0; | ||
2302 | } | ||
2303 | sd->pktsz = sd->npkt = 0; | ||
2304 | } | ||
2305 | |||
2452 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | 2306 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, |
2453 | u8 *data, /* isoc packet */ | 2307 | u8 *data, /* isoc packet */ |
2454 | int len) /* iso packet length */ | 2308 | int len) /* iso packet length */ |
2455 | { | 2309 | { |
2456 | struct sd *sd = (struct sd *) gspca_dev; | 2310 | struct sd *sd = (struct sd *) gspca_dev; |
2457 | int avg_lum; | 2311 | int avg_lum, is_jpeg; |
2458 | static u8 frame_header[] = | 2312 | static u8 frame_header[] = |
2459 | {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96}; | 2313 | {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96}; |
2460 | if (len == 64 && memcmp(data, frame_header, 6) == 0) { | 2314 | |
2315 | is_jpeg = (sd->fmt & 0x03) == 0; | ||
2316 | if (len >= 64 && memcmp(data, frame_header, 6) == 0) { | ||
2461 | avg_lum = ((data[35] >> 2) & 3) | | 2317 | avg_lum = ((data[35] >> 2) & 3) | |
2462 | (data[20] << 2) | | 2318 | (data[20] << 2) | |
2463 | (data[19] << 10); | 2319 | (data[19] << 10); |
@@ -2484,12 +2340,18 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
2484 | (data[33] << 10); | 2340 | (data[33] << 10); |
2485 | avg_lum >>= 9; | 2341 | avg_lum >>= 9; |
2486 | atomic_set(&sd->avg_lum, avg_lum); | 2342 | atomic_set(&sd->avg_lum, avg_lum); |
2343 | |||
2344 | if (is_jpeg) | ||
2345 | transfer_check(gspca_dev, data); | ||
2346 | |||
2487 | gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); | 2347 | gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); |
2488 | return; | 2348 | len -= 64; |
2349 | if (len == 0) | ||
2350 | return; | ||
2351 | data += 64; | ||
2489 | } | 2352 | } |
2490 | if (gspca_dev->last_packet_type == LAST_PACKET) { | 2353 | if (gspca_dev->last_packet_type == LAST_PACKET) { |
2491 | if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv | 2354 | if (is_jpeg) { |
2492 | & MODE_JPEG) { | ||
2493 | gspca_frame_add(gspca_dev, FIRST_PACKET, | 2355 | gspca_frame_add(gspca_dev, FIRST_PACKET, |
2494 | sd->jpeg_hdr, JPEG_HDR_SZ); | 2356 | sd->jpeg_hdr, JPEG_HDR_SZ); |
2495 | gspca_frame_add(gspca_dev, INTER_PACKET, | 2357 | gspca_frame_add(gspca_dev, INTER_PACKET, |
@@ -2499,13 +2361,18 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
2499 | data, len); | 2361 | data, len); |
2500 | } | 2362 | } |
2501 | } else { | 2363 | } else { |
2364 | /* if JPEG, count the packets and their size */ | ||
2365 | if (is_jpeg) { | ||
2366 | sd->npkt++; | ||
2367 | sd->pktsz += len; | ||
2368 | } | ||
2502 | gspca_frame_add(gspca_dev, INTER_PACKET, data, len); | 2369 | gspca_frame_add(gspca_dev, INTER_PACKET, data, len); |
2503 | } | 2370 | } |
2504 | } | 2371 | } |
2505 | 2372 | ||
2506 | /* sub-driver description */ | 2373 | /* sub-driver description */ |
2507 | static const struct sd_desc sd_desc = { | 2374 | static const struct sd_desc sd_desc = { |
2508 | .name = MODULE_NAME, | 2375 | .name = KBUILD_MODNAME, |
2509 | .ctrls = sd_ctrls, | 2376 | .ctrls = sd_ctrls, |
2510 | .nctrls = ARRAY_SIZE(sd_ctrls), | 2377 | .nctrls = ARRAY_SIZE(sd_ctrls), |
2511 | .config = sd_config, | 2378 | .config = sd_config, |
@@ -2513,6 +2380,7 @@ static const struct sd_desc sd_desc = { | |||
2513 | .isoc_init = sd_isoc_init, | 2380 | .isoc_init = sd_isoc_init, |
2514 | .start = sd_start, | 2381 | .start = sd_start, |
2515 | .stopN = sd_stopN, | 2382 | .stopN = sd_stopN, |
2383 | .stop0 = sd_stop0, | ||
2516 | .pkt_scan = sd_pkt_scan, | 2384 | .pkt_scan = sd_pkt_scan, |
2517 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) | 2385 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) |
2518 | .int_pkt_scan = sd_int_pkt_scan, | 2386 | .int_pkt_scan = sd_int_pkt_scan, |
@@ -2581,7 +2449,7 @@ static int sd_probe(struct usb_interface *intf, | |||
2581 | } | 2449 | } |
2582 | 2450 | ||
2583 | static struct usb_driver sd_driver = { | 2451 | static struct usb_driver sd_driver = { |
2584 | .name = MODULE_NAME, | 2452 | .name = KBUILD_MODNAME, |
2585 | .id_table = device_table, | 2453 | .id_table = device_table, |
2586 | .probe = sd_probe, | 2454 | .probe = sd_probe, |
2587 | .disconnect = gspca_disconnect, | 2455 | .disconnect = gspca_disconnect, |
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index 0c9e6ddabd2c..db8e5084df06 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c | |||
@@ -39,7 +39,9 @@ enum e_ctrl { | |||
39 | BLUE, | 39 | BLUE, |
40 | RED, | 40 | RED, |
41 | GAMMA, | 41 | GAMMA, |
42 | EXPOSURE, | ||
42 | AUTOGAIN, | 43 | AUTOGAIN, |
44 | GAIN, | ||
43 | HFLIP, | 45 | HFLIP, |
44 | VFLIP, | 46 | VFLIP, |
45 | SHARPNESS, | 47 | SHARPNESS, |
@@ -131,7 +133,9 @@ static void setcontrast(struct gspca_dev *gspca_dev); | |||
131 | static void setcolors(struct gspca_dev *gspca_dev); | 133 | static void setcolors(struct gspca_dev *gspca_dev); |
132 | static void setredblue(struct gspca_dev *gspca_dev); | 134 | static void setredblue(struct gspca_dev *gspca_dev); |
133 | static void setgamma(struct gspca_dev *gspca_dev); | 135 | static void setgamma(struct gspca_dev *gspca_dev); |
134 | static void setautogain(struct gspca_dev *gspca_dev); | 136 | static void setexposure(struct gspca_dev *gspca_dev); |
137 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); | ||
138 | static void setgain(struct gspca_dev *gspca_dev); | ||
135 | static void sethvflip(struct gspca_dev *gspca_dev); | 139 | static void sethvflip(struct gspca_dev *gspca_dev); |
136 | static void setsharpness(struct gspca_dev *gspca_dev); | 140 | static void setsharpness(struct gspca_dev *gspca_dev); |
137 | static void setillum(struct gspca_dev *gspca_dev); | 141 | static void setillum(struct gspca_dev *gspca_dev); |
@@ -213,6 +217,18 @@ static const struct ctrl sd_ctrls[NCTRLS] = { | |||
213 | }, | 217 | }, |
214 | .set_control = setgamma | 218 | .set_control = setgamma |
215 | }, | 219 | }, |
220 | [EXPOSURE] = { | ||
221 | { | ||
222 | .id = V4L2_CID_EXPOSURE, | ||
223 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
224 | .name = "Exposure", | ||
225 | .minimum = 500, | ||
226 | .maximum = 1500, | ||
227 | .step = 1, | ||
228 | .default_value = 1024 | ||
229 | }, | ||
230 | .set_control = setexposure | ||
231 | }, | ||
216 | [AUTOGAIN] = { | 232 | [AUTOGAIN] = { |
217 | { | 233 | { |
218 | .id = V4L2_CID_AUTOGAIN, | 234 | .id = V4L2_CID_AUTOGAIN, |
@@ -223,7 +239,19 @@ static const struct ctrl sd_ctrls[NCTRLS] = { | |||
223 | .step = 1, | 239 | .step = 1, |
224 | .default_value = 1 | 240 | .default_value = 1 |
225 | }, | 241 | }, |
226 | .set_control = setautogain | 242 | .set = sd_setautogain, |
243 | }, | ||
244 | [GAIN] = { | ||
245 | { | ||
246 | .id = V4L2_CID_GAIN, | ||
247 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
248 | .name = "Gain", | ||
249 | .minimum = 4, | ||
250 | .maximum = 49, | ||
251 | .step = 1, | ||
252 | .default_value = 15 | ||
253 | }, | ||
254 | .set_control = setgain | ||
227 | }, | 255 | }, |
228 | [HFLIP] = { | 256 | [HFLIP] = { |
229 | { | 257 | { |
@@ -290,60 +318,87 @@ static const struct ctrl sd_ctrls[NCTRLS] = { | |||
290 | 318 | ||
291 | /* table of the disabled controls */ | 319 | /* table of the disabled controls */ |
292 | static const __u32 ctrl_dis[] = { | 320 | static const __u32 ctrl_dis[] = { |
293 | [SENSOR_ADCM1700] = (1 << AUTOGAIN) | | 321 | [SENSOR_ADCM1700] = (1 << EXPOSURE) | |
322 | (1 << AUTOGAIN) | | ||
323 | (1 << GAIN) | | ||
294 | (1 << HFLIP) | | 324 | (1 << HFLIP) | |
295 | (1 << VFLIP) | | 325 | (1 << VFLIP) | |
296 | (1 << FREQ), | 326 | (1 << FREQ), |
297 | 327 | ||
298 | [SENSOR_GC0307] = (1 << HFLIP) | | 328 | [SENSOR_GC0307] = (1 << EXPOSURE) | |
329 | (1 << GAIN) | | ||
330 | (1 << HFLIP) | | ||
299 | (1 << VFLIP) | | 331 | (1 << VFLIP) | |
300 | (1 << FREQ), | 332 | (1 << FREQ), |
301 | 333 | ||
302 | [SENSOR_HV7131R] = (1 << HFLIP) | | 334 | [SENSOR_HV7131R] = (1 << EXPOSURE) | |
335 | (1 << GAIN) | | ||
336 | (1 << HFLIP) | | ||
303 | (1 << FREQ), | 337 | (1 << FREQ), |
304 | 338 | ||
305 | [SENSOR_MI0360] = (1 << HFLIP) | | 339 | [SENSOR_MI0360] = (1 << EXPOSURE) | |
340 | (1 << GAIN) | | ||
341 | (1 << HFLIP) | | ||
306 | (1 << VFLIP) | | 342 | (1 << VFLIP) | |
307 | (1 << FREQ), | 343 | (1 << FREQ), |
308 | 344 | ||
309 | [SENSOR_MI0360B] = (1 << HFLIP) | | 345 | [SENSOR_MI0360B] = (1 << EXPOSURE) | |
346 | (1 << GAIN) | | ||
347 | (1 << HFLIP) | | ||
310 | (1 << VFLIP) | | 348 | (1 << VFLIP) | |
311 | (1 << FREQ), | 349 | (1 << FREQ), |
312 | 350 | ||
313 | [SENSOR_MO4000] = (1 << HFLIP) | | 351 | [SENSOR_MO4000] = (1 << EXPOSURE) | |
352 | (1 << GAIN) | | ||
353 | (1 << HFLIP) | | ||
314 | (1 << VFLIP) | | 354 | (1 << VFLIP) | |
315 | (1 << FREQ), | 355 | (1 << FREQ), |
316 | 356 | ||
317 | [SENSOR_MT9V111] = (1 << HFLIP) | | 357 | [SENSOR_MT9V111] = (1 << EXPOSURE) | |
358 | (1 << GAIN) | | ||
359 | (1 << HFLIP) | | ||
318 | (1 << VFLIP) | | 360 | (1 << VFLIP) | |
319 | (1 << FREQ), | 361 | (1 << FREQ), |
320 | 362 | ||
321 | [SENSOR_OM6802] = (1 << HFLIP) | | 363 | [SENSOR_OM6802] = (1 << EXPOSURE) | |
364 | (1 << GAIN) | | ||
365 | (1 << HFLIP) | | ||
322 | (1 << VFLIP) | | 366 | (1 << VFLIP) | |
323 | (1 << FREQ), | 367 | (1 << FREQ), |
324 | 368 | ||
325 | [SENSOR_OV7630] = (1 << HFLIP), | 369 | [SENSOR_OV7630] = (1 << EXPOSURE) | |
370 | (1 << GAIN) | | ||
371 | (1 << HFLIP), | ||
326 | 372 | ||
327 | [SENSOR_OV7648] = (1 << HFLIP), | 373 | [SENSOR_OV7648] = (1 << EXPOSURE) | |
374 | (1 << GAIN) | | ||
375 | (1 << HFLIP), | ||
328 | 376 | ||
329 | [SENSOR_OV7660] = (1 << AUTOGAIN) | | 377 | [SENSOR_OV7660] = (1 << EXPOSURE) | |
378 | (1 << AUTOGAIN) | | ||
379 | (1 << GAIN) | | ||
330 | (1 << HFLIP) | | 380 | (1 << HFLIP) | |
331 | (1 << VFLIP), | 381 | (1 << VFLIP), |
332 | 382 | ||
333 | [SENSOR_PO1030] = (1 << AUTOGAIN) | | 383 | [SENSOR_PO1030] = (1 << EXPOSURE) | |
384 | (1 << AUTOGAIN) | | ||
385 | (1 << GAIN) | | ||
334 | (1 << HFLIP) | | 386 | (1 << HFLIP) | |
335 | (1 << VFLIP) | | 387 | (1 << VFLIP) | |
336 | (1 << FREQ), | 388 | (1 << FREQ), |
337 | 389 | ||
338 | [SENSOR_PO2030N] = (1 << AUTOGAIN) | | 390 | [SENSOR_PO2030N] = (1 << FREQ), |
339 | (1 << FREQ), | ||
340 | 391 | ||
341 | [SENSOR_SOI768] = (1 << AUTOGAIN) | | 392 | [SENSOR_SOI768] = (1 << EXPOSURE) | |
393 | (1 << AUTOGAIN) | | ||
394 | (1 << GAIN) | | ||
342 | (1 << HFLIP) | | 395 | (1 << HFLIP) | |
343 | (1 << VFLIP) | | 396 | (1 << VFLIP) | |
344 | (1 << FREQ), | 397 | (1 << FREQ), |
345 | 398 | ||
346 | [SENSOR_SP80708] = (1 << AUTOGAIN) | | 399 | [SENSOR_SP80708] = (1 << EXPOSURE) | |
400 | (1 << AUTOGAIN) | | ||
401 | (1 << GAIN) | | ||
347 | (1 << HFLIP) | | 402 | (1 << HFLIP) | |
348 | (1 << VFLIP) | | 403 | (1 << VFLIP) | |
349 | (1 << FREQ), | 404 | (1 << FREQ), |
@@ -1242,14 +1297,6 @@ static const u8 po2030n_sensor_param1[][8] = { | |||
1242 | {0xa1, 0x6e, 0x05, 0x6f, 0x00, 0x00, 0x00, 0x10}, | 1297 | {0xa1, 0x6e, 0x05, 0x6f, 0x00, 0x00, 0x00, 0x10}, |
1243 | {0xa1, 0x6e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10}, | 1298 | {0xa1, 0x6e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10}, |
1244 | {0xa1, 0x6e, 0x07, 0x25, 0x00, 0x00, 0x00, 0x10}, | 1299 | {0xa1, 0x6e, 0x07, 0x25, 0x00, 0x00, 0x00, 0x10}, |
1245 | {0xa1, 0x6e, 0x15, 0x04, 0x00, 0x00, 0x00, 0x10}, | ||
1246 | {0xc1, 0x6e, 0x16, 0x52, 0x40, 0x48, 0x00, 0x10}, | ||
1247 | /*after start*/ | ||
1248 | {0xa1, 0x6e, 0x15, 0x0f, 0x00, 0x00, 0x00, 0x10}, | ||
1249 | {DELAY, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 5ms */ | ||
1250 | {0xa1, 0x6e, 0x1a, 0x05, 0x00, 0x00, 0x00, 0x10}, | ||
1251 | {DELAY, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 5ms */ | ||
1252 | {0xa1, 0x6e, 0x1b, 0x53, 0x00, 0x00, 0x00, 0x10}, | ||
1253 | {} | 1300 | {} |
1254 | }; | 1301 | }; |
1255 | 1302 | ||
@@ -1858,7 +1905,7 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
1858 | return gspca_dev->usb_err; | 1905 | return gspca_dev->usb_err; |
1859 | } | 1906 | } |
1860 | 1907 | ||
1861 | static u32 setexposure(struct gspca_dev *gspca_dev, | 1908 | static u32 expo_adjust(struct gspca_dev *gspca_dev, |
1862 | u32 expo) | 1909 | u32 expo) |
1863 | { | 1910 | { |
1864 | struct sd *sd = (struct sd *) gspca_dev; | 1911 | struct sd *sd = (struct sd *) gspca_dev; |
@@ -1982,28 +2029,28 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
1982 | expo = 0x002dc6c0; | 2029 | expo = 0x002dc6c0; |
1983 | else if (expo < 0x02a0) | 2030 | else if (expo < 0x02a0) |
1984 | expo = 0x02a0; | 2031 | expo = 0x02a0; |
1985 | sd->exposure = setexposure(gspca_dev, expo); | 2032 | sd->exposure = expo_adjust(gspca_dev, expo); |
1986 | break; | 2033 | break; |
1987 | case SENSOR_MI0360: | 2034 | case SENSOR_MI0360: |
1988 | case SENSOR_MO4000: | 2035 | case SENSOR_MO4000: |
1989 | expo = brightness << 4; | 2036 | expo = brightness << 4; |
1990 | sd->exposure = setexposure(gspca_dev, expo); | 2037 | sd->exposure = expo_adjust(gspca_dev, expo); |
1991 | break; | 2038 | break; |
1992 | case SENSOR_MI0360B: | 2039 | case SENSOR_MI0360B: |
1993 | expo = brightness << 2; | 2040 | expo = brightness << 2; |
1994 | sd->exposure = setexposure(gspca_dev, expo); | 2041 | sd->exposure = expo_adjust(gspca_dev, expo); |
1995 | break; | 2042 | break; |
1996 | case SENSOR_GC0307: | 2043 | case SENSOR_GC0307: |
1997 | expo = brightness; | 2044 | expo = brightness; |
1998 | sd->exposure = setexposure(gspca_dev, expo); | 2045 | sd->exposure = expo_adjust(gspca_dev, expo); |
1999 | return; /* don't set the Y offset */ | 2046 | return; /* don't set the Y offset */ |
2000 | case SENSOR_MT9V111: | 2047 | case SENSOR_MT9V111: |
2001 | expo = brightness << 2; | 2048 | expo = brightness << 2; |
2002 | sd->exposure = setexposure(gspca_dev, expo); | 2049 | sd->exposure = expo_adjust(gspca_dev, expo); |
2003 | return; /* don't set the Y offset */ | 2050 | return; /* don't set the Y offset */ |
2004 | case SENSOR_OM6802: | 2051 | case SENSOR_OM6802: |
2005 | expo = brightness << 2; | 2052 | expo = brightness << 2; |
2006 | sd->exposure = setexposure(gspca_dev, expo); | 2053 | sd->exposure = expo_adjust(gspca_dev, expo); |
2007 | return; /* Y offset already set */ | 2054 | return; /* Y offset already set */ |
2008 | } | 2055 | } |
2009 | 2056 | ||
@@ -2112,6 +2159,23 @@ static void setgamma(struct gspca_dev *gspca_dev) | |||
2112 | reg_w(gspca_dev, 0x20, gamma, sizeof gamma); | 2159 | reg_w(gspca_dev, 0x20, gamma, sizeof gamma); |
2113 | } | 2160 | } |
2114 | 2161 | ||
2162 | static void setexposure(struct gspca_dev *gspca_dev) | ||
2163 | { | ||
2164 | struct sd *sd = (struct sd *) gspca_dev; | ||
2165 | |||
2166 | if (sd->sensor == SENSOR_PO2030N) { | ||
2167 | u8 rexpo[] = /* 1a: expo H, 1b: expo M */ | ||
2168 | {0xa1, 0x6e, 0x1a, 0x00, 0x40, 0x00, 0x00, 0x10}; | ||
2169 | |||
2170 | rexpo[3] = sd->ctrls[EXPOSURE].val >> 8; | ||
2171 | i2c_w8(gspca_dev, rexpo); | ||
2172 | msleep(6); | ||
2173 | rexpo[2] = 0x1b; | ||
2174 | rexpo[3] = sd->ctrls[EXPOSURE].val; | ||
2175 | i2c_w8(gspca_dev, rexpo); | ||
2176 | } | ||
2177 | } | ||
2178 | |||
2115 | static void setautogain(struct gspca_dev *gspca_dev) | 2179 | static void setautogain(struct gspca_dev *gspca_dev) |
2116 | { | 2180 | { |
2117 | struct sd *sd = (struct sd *) gspca_dev; | 2181 | struct sd *sd = (struct sd *) gspca_dev; |
@@ -2139,6 +2203,19 @@ static void setautogain(struct gspca_dev *gspca_dev) | |||
2139 | sd->ag_cnt = -1; | 2203 | sd->ag_cnt = -1; |
2140 | } | 2204 | } |
2141 | 2205 | ||
2206 | static void setgain(struct gspca_dev *gspca_dev) | ||
2207 | { | ||
2208 | struct sd *sd = (struct sd *) gspca_dev; | ||
2209 | |||
2210 | if (sd->sensor == SENSOR_PO2030N) { | ||
2211 | u8 rgain[] = /* 15: gain */ | ||
2212 | {0xa1, 0x6e, 0x15, 0x00, 0x40, 0x00, 0x00, 0x15}; | ||
2213 | |||
2214 | rgain[3] = sd->ctrls[GAIN].val; | ||
2215 | i2c_w8(gspca_dev, rgain); | ||
2216 | } | ||
2217 | } | ||
2218 | |||
2142 | static void sethvflip(struct gspca_dev *gspca_dev) | 2219 | static void sethvflip(struct gspca_dev *gspca_dev) |
2143 | { | 2220 | { |
2144 | struct sd *sd = (struct sd *) gspca_dev; | 2221 | struct sd *sd = (struct sd *) gspca_dev; |
@@ -2623,6 +2700,10 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
2623 | setcontrast(gspca_dev); | 2700 | setcontrast(gspca_dev); |
2624 | setcolors(gspca_dev); | 2701 | setcolors(gspca_dev); |
2625 | setautogain(gspca_dev); | 2702 | setautogain(gspca_dev); |
2703 | if (!(gspca_dev->ctrl_inac & ((1 << EXPOSURE) | (1 << GAIN)))) { | ||
2704 | setexposure(gspca_dev); | ||
2705 | setgain(gspca_dev); | ||
2706 | } | ||
2626 | setfreq(gspca_dev); | 2707 | setfreq(gspca_dev); |
2627 | 2708 | ||
2628 | sd->pktsz = sd->npkt = 0; | 2709 | sd->pktsz = sd->npkt = 0; |
@@ -2719,6 +2800,12 @@ static void sd_stop0(struct gspca_dev *gspca_dev) | |||
2719 | } | 2800 | } |
2720 | } | 2801 | } |
2721 | 2802 | ||
2803 | /* !! coarse_grained_expo_autogain is not used !! */ | ||
2804 | #define exp_too_low_cnt bridge | ||
2805 | #define exp_too_high_cnt sensor | ||
2806 | |||
2807 | #include "autogain_functions.h" | ||
2808 | |||
2722 | static void do_autogain(struct gspca_dev *gspca_dev) | 2809 | static void do_autogain(struct gspca_dev *gspca_dev) |
2723 | { | 2810 | { |
2724 | struct sd *sd = (struct sd *) gspca_dev; | 2811 | struct sd *sd = (struct sd *) gspca_dev; |
@@ -2736,6 +2823,13 @@ static void do_autogain(struct gspca_dev *gspca_dev) | |||
2736 | 2823 | ||
2737 | delta = atomic_read(&sd->avg_lum); | 2824 | delta = atomic_read(&sd->avg_lum); |
2738 | PDEBUG(D_FRAM, "mean lum %d", delta); | 2825 | PDEBUG(D_FRAM, "mean lum %d", delta); |
2826 | |||
2827 | if (sd->sensor == SENSOR_PO2030N) { | ||
2828 | auto_gain_n_exposure(gspca_dev, delta, luma_mean, luma_delta, | ||
2829 | 15, 1024); | ||
2830 | return; | ||
2831 | } | ||
2832 | |||
2739 | if (delta < luma_mean - luma_delta || | 2833 | if (delta < luma_mean - luma_delta || |
2740 | delta > luma_mean + luma_delta) { | 2834 | delta > luma_mean + luma_delta) { |
2741 | switch (sd->sensor) { | 2835 | switch (sd->sensor) { |
@@ -2744,7 +2838,7 @@ static void do_autogain(struct gspca_dev *gspca_dev) | |||
2744 | expotimes += (luma_mean - delta) >> 6; | 2838 | expotimes += (luma_mean - delta) >> 6; |
2745 | if (expotimes < 0) | 2839 | if (expotimes < 0) |
2746 | expotimes = 0; | 2840 | expotimes = 0; |
2747 | sd->exposure = setexposure(gspca_dev, | 2841 | sd->exposure = expo_adjust(gspca_dev, |
2748 | (unsigned int) expotimes); | 2842 | (unsigned int) expotimes); |
2749 | break; | 2843 | break; |
2750 | case SENSOR_HV7131R: | 2844 | case SENSOR_HV7131R: |
@@ -2752,7 +2846,7 @@ static void do_autogain(struct gspca_dev *gspca_dev) | |||
2752 | expotimes += (luma_mean - delta) >> 4; | 2846 | expotimes += (luma_mean - delta) >> 4; |
2753 | if (expotimes < 0) | 2847 | if (expotimes < 0) |
2754 | expotimes = 0; | 2848 | expotimes = 0; |
2755 | sd->exposure = setexposure(gspca_dev, | 2849 | sd->exposure = expo_adjust(gspca_dev, |
2756 | (unsigned int) (expotimes << 8)); | 2850 | (unsigned int) (expotimes << 8)); |
2757 | break; | 2851 | break; |
2758 | case SENSOR_OM6802: | 2852 | case SENSOR_OM6802: |
@@ -2761,7 +2855,7 @@ static void do_autogain(struct gspca_dev *gspca_dev) | |||
2761 | expotimes += (luma_mean - delta) >> 2; | 2855 | expotimes += (luma_mean - delta) >> 2; |
2762 | if (expotimes < 0) | 2856 | if (expotimes < 0) |
2763 | expotimes = 0; | 2857 | expotimes = 0; |
2764 | sd->exposure = setexposure(gspca_dev, | 2858 | sd->exposure = expo_adjust(gspca_dev, |
2765 | (unsigned int) expotimes); | 2859 | (unsigned int) expotimes); |
2766 | setredblue(gspca_dev); | 2860 | setredblue(gspca_dev); |
2767 | break; | 2861 | break; |
@@ -2773,7 +2867,7 @@ static void do_autogain(struct gspca_dev *gspca_dev) | |||
2773 | expotimes += (luma_mean - delta) >> 6; | 2867 | expotimes += (luma_mean - delta) >> 6; |
2774 | if (expotimes < 0) | 2868 | if (expotimes < 0) |
2775 | expotimes = 0; | 2869 | expotimes = 0; |
2776 | sd->exposure = setexposure(gspca_dev, | 2870 | sd->exposure = expo_adjust(gspca_dev, |
2777 | (unsigned int) expotimes); | 2871 | (unsigned int) expotimes); |
2778 | setredblue(gspca_dev); | 2872 | setredblue(gspca_dev); |
2779 | break; | 2873 | break; |
@@ -2948,16 +3042,18 @@ marker_found: | |||
2948 | } | 3042 | } |
2949 | } | 3043 | } |
2950 | 3044 | ||
2951 | static int sd_get_jcomp(struct gspca_dev *gspca_dev, | 3045 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) |
2952 | struct v4l2_jpegcompression *jcomp) | ||
2953 | { | 3046 | { |
2954 | struct sd *sd = (struct sd *) gspca_dev; | 3047 | struct sd *sd = (struct sd *) gspca_dev; |
2955 | 3048 | ||
2956 | memset(jcomp, 0, sizeof *jcomp); | 3049 | sd->ctrls[AUTOGAIN].val = val; |
2957 | jcomp->quality = sd->quality; | 3050 | if (val) |
2958 | jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT | 3051 | gspca_dev->ctrl_inac |= (1 << EXPOSURE) | (1 << GAIN); |
2959 | | V4L2_JPEG_MARKER_DQT; | 3052 | else |
2960 | return 0; | 3053 | gspca_dev->ctrl_inac &= ~(1 << EXPOSURE) & ~(1 << GAIN); |
3054 | if (gspca_dev->streaming) | ||
3055 | setautogain(gspca_dev); | ||
3056 | return gspca_dev->usb_err; | ||
2961 | } | 3057 | } |
2962 | 3058 | ||
2963 | static int sd_querymenu(struct gspca_dev *gspca_dev, | 3059 | static int sd_querymenu(struct gspca_dev *gspca_dev, |
@@ -3012,7 +3108,6 @@ static const struct sd_desc sd_desc = { | |||
3012 | .stop0 = sd_stop0, | 3108 | .stop0 = sd_stop0, |
3013 | .pkt_scan = sd_pkt_scan, | 3109 | .pkt_scan = sd_pkt_scan, |
3014 | .dq_callback = do_autogain, | 3110 | .dq_callback = do_autogain, |
3015 | .get_jcomp = sd_get_jcomp, | ||
3016 | .querymenu = sd_querymenu, | 3111 | .querymenu = sd_querymenu, |
3017 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) | 3112 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) |
3018 | .int_pkt_scan = sd_int_pkt_scan, | 3113 | .int_pkt_scan = sd_int_pkt_scan, |
diff --git a/drivers/media/video/gspca/stv06xx/Makefile b/drivers/media/video/gspca/stv06xx/Makefile index 5b318faf9aa8..38bc41061d83 100644 --- a/drivers/media/video/gspca/stv06xx/Makefile +++ b/drivers/media/video/gspca/stv06xx/Makefile | |||
@@ -6,5 +6,5 @@ gspca_stv06xx-objs := stv06xx.o \ | |||
6 | stv06xx_pb0100.o \ | 6 | stv06xx_pb0100.o \ |
7 | stv06xx_st6422.o | 7 | stv06xx_st6422.o |
8 | 8 | ||
9 | ccflags-y += -Idrivers/media/video/gspca | 9 | ccflags-y += -I$(srctree)/drivers/media/video/gspca |
10 | 10 | ||
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c index b9e15bb0328b..7d9a4f1be9dc 100644 --- a/drivers/media/video/gspca/zc3xx.c +++ b/drivers/media/video/gspca/zc3xx.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Z-Star/Vimicro zc301/zc302p/vc30x library | 2 | * Z-Star/Vimicro zc301/zc302p/vc30x driver |
3 | * | 3 | * |
4 | * Copyright (C) 2009-2011 Jean-Francois Moine <http://moinejf.free.fr> | 4 | * Copyright (C) 2009-2012 Jean-Francois Moine <http://moinejf.free.fr> |
5 | * Copyright (C) 2004 2005 2006 Michel Xhaard mxhaard@magic.fr | 5 | * Copyright (C) 2004 2005 2006 Michel Xhaard mxhaard@magic.fr |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
@@ -21,8 +21,6 @@ | |||
21 | 21 | ||
22 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 22 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
23 | 23 | ||
24 | #define MODULE_NAME "zc3xx" | ||
25 | |||
26 | #include <linux/input.h> | 24 | #include <linux/input.h> |
27 | #include "gspca.h" | 25 | #include "gspca.h" |
28 | #include "jpeg.h" | 26 | #include "jpeg.h" |
@@ -34,7 +32,7 @@ MODULE_LICENSE("GPL"); | |||
34 | 32 | ||
35 | static int force_sensor = -1; | 33 | static int force_sensor = -1; |
36 | 34 | ||
37 | #define QUANT_VAL 1 /* quantization table */ | 35 | #define REG08_DEF 3 /* default JPEG compression (70%) */ |
38 | #include "zc3xx-reg.h" | 36 | #include "zc3xx-reg.h" |
39 | 37 | ||
40 | /* controls */ | 38 | /* controls */ |
@@ -46,6 +44,7 @@ enum e_ctrl { | |||
46 | AUTOGAIN, | 44 | AUTOGAIN, |
47 | LIGHTFREQ, | 45 | LIGHTFREQ, |
48 | SHARPNESS, | 46 | SHARPNESS, |
47 | QUALITY, | ||
49 | NCTRLS /* number of controls */ | 48 | NCTRLS /* number of controls */ |
50 | }; | 49 | }; |
51 | 50 | ||
@@ -57,10 +56,10 @@ struct sd { | |||
57 | 56 | ||
58 | struct gspca_ctrl ctrls[NCTRLS]; | 57 | struct gspca_ctrl ctrls[NCTRLS]; |
59 | 58 | ||
60 | u8 quality; /* image quality */ | 59 | struct work_struct work; |
61 | #define QUALITY_MIN 50 | 60 | struct workqueue_struct *work_thread; |
62 | #define QUALITY_MAX 80 | 61 | |
63 | #define QUALITY_DEF 70 | 62 | u8 reg08; /* webcam compression quality */ |
64 | 63 | ||
65 | u8 bridge; | 64 | u8 bridge; |
66 | u8 sensor; /* Type of image sensor chip */ | 65 | u8 sensor; /* Type of image sensor chip */ |
@@ -101,6 +100,7 @@ static void setexposure(struct gspca_dev *gspca_dev); | |||
101 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); | 100 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); |
102 | static void setlightfreq(struct gspca_dev *gspca_dev); | 101 | static void setlightfreq(struct gspca_dev *gspca_dev); |
103 | static void setsharpness(struct gspca_dev *gspca_dev); | 102 | static void setsharpness(struct gspca_dev *gspca_dev); |
103 | static int sd_setquality(struct gspca_dev *gspca_dev, __s32 val); | ||
104 | 104 | ||
105 | static const struct ctrl sd_ctrls[NCTRLS] = { | 105 | static const struct ctrl sd_ctrls[NCTRLS] = { |
106 | [BRIGHTNESS] = { | 106 | [BRIGHTNESS] = { |
@@ -188,6 +188,18 @@ static const struct ctrl sd_ctrls[NCTRLS] = { | |||
188 | }, | 188 | }, |
189 | .set_control = setsharpness | 189 | .set_control = setsharpness |
190 | }, | 190 | }, |
191 | [QUALITY] = { | ||
192 | { | ||
193 | .id = V4L2_CID_JPEG_COMPRESSION_QUALITY, | ||
194 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
195 | .name = "Compression Quality", | ||
196 | .minimum = 40, | ||
197 | .maximum = 70, | ||
198 | .step = 1, | ||
199 | .default_value = 70 /* updated in sd_init() */ | ||
200 | }, | ||
201 | .set = sd_setquality | ||
202 | }, | ||
191 | }; | 203 | }; |
192 | 204 | ||
193 | static const struct v4l2_pix_format vga_mode[] = { | 205 | static const struct v4l2_pix_format vga_mode[] = { |
@@ -229,6 +241,9 @@ static const struct v4l2_pix_format sif_mode[] = { | |||
229 | .priv = 0}, | 241 | .priv = 0}, |
230 | }; | 242 | }; |
231 | 243 | ||
244 | /* bridge reg08 -> JPEG quality conversion table */ | ||
245 | static u8 jpeg_qual[] = {40, 50, 60, 70, /*80*/}; | ||
246 | |||
232 | /* usb exchanges */ | 247 | /* usb exchanges */ |
233 | struct usb_action { | 248 | struct usb_action { |
234 | u8 req; | 249 | u8 req; |
@@ -3894,7 +3909,6 @@ static const struct usb_action pas106b_Initial[] = { /* 352x288 */ | |||
3894 | /* Gains */ | 3909 | /* Gains */ |
3895 | {0xa0, 0x20, ZC3XX_R1A9_DIGITALLIMITDIFF}, | 3910 | {0xa0, 0x20, ZC3XX_R1A9_DIGITALLIMITDIFF}, |
3896 | {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, | 3911 | {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, |
3897 | {0xa0, 0xa0, ZC3XX_R11D_GLOBALGAIN}, | ||
3898 | {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, | 3912 | {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, |
3899 | /* Auto correction */ | 3913 | /* Auto correction */ |
3900 | {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, | 3914 | {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, |
@@ -5640,7 +5654,7 @@ static const struct usb_action gc0303_NoFlikerScale[] = { | |||
5640 | {} | 5654 | {} |
5641 | }; | 5655 | }; |
5642 | 5656 | ||
5643 | static u8 reg_r_i(struct gspca_dev *gspca_dev, | 5657 | static u8 reg_r(struct gspca_dev *gspca_dev, |
5644 | u16 index) | 5658 | u16 index) |
5645 | { | 5659 | { |
5646 | int ret; | 5660 | int ret; |
@@ -5655,24 +5669,14 @@ static u8 reg_r_i(struct gspca_dev *gspca_dev, | |||
5655 | index, gspca_dev->usb_buf, 1, | 5669 | index, gspca_dev->usb_buf, 1, |
5656 | 500); | 5670 | 500); |
5657 | if (ret < 0) { | 5671 | if (ret < 0) { |
5658 | pr_err("reg_r_i err %d\n", ret); | 5672 | pr_err("reg_r err %d\n", ret); |
5659 | gspca_dev->usb_err = ret; | 5673 | gspca_dev->usb_err = ret; |
5660 | return 0; | 5674 | return 0; |
5661 | } | 5675 | } |
5662 | return gspca_dev->usb_buf[0]; | 5676 | return gspca_dev->usb_buf[0]; |
5663 | } | 5677 | } |
5664 | 5678 | ||
5665 | static u8 reg_r(struct gspca_dev *gspca_dev, | 5679 | static void reg_w(struct gspca_dev *gspca_dev, |
5666 | u16 index) | ||
5667 | { | ||
5668 | u8 ret; | ||
5669 | |||
5670 | ret = reg_r_i(gspca_dev, index); | ||
5671 | PDEBUG(D_USBI, "reg r [%04x] -> %02x", index, ret); | ||
5672 | return ret; | ||
5673 | } | ||
5674 | |||
5675 | static void reg_w_i(struct gspca_dev *gspca_dev, | ||
5676 | u8 value, | 5680 | u8 value, |
5677 | u16 index) | 5681 | u16 index) |
5678 | { | 5682 | { |
@@ -5692,14 +5696,6 @@ static void reg_w_i(struct gspca_dev *gspca_dev, | |||
5692 | } | 5696 | } |
5693 | } | 5697 | } |
5694 | 5698 | ||
5695 | static void reg_w(struct gspca_dev *gspca_dev, | ||
5696 | u8 value, | ||
5697 | u16 index) | ||
5698 | { | ||
5699 | PDEBUG(D_USBO, "reg w [%04x] = %02x", index, value); | ||
5700 | reg_w_i(gspca_dev, value, index); | ||
5701 | } | ||
5702 | |||
5703 | static u16 i2c_read(struct gspca_dev *gspca_dev, | 5699 | static u16 i2c_read(struct gspca_dev *gspca_dev, |
5704 | u8 reg) | 5700 | u8 reg) |
5705 | { | 5701 | { |
@@ -5708,16 +5704,14 @@ static u16 i2c_read(struct gspca_dev *gspca_dev, | |||
5708 | 5704 | ||
5709 | if (gspca_dev->usb_err < 0) | 5705 | if (gspca_dev->usb_err < 0) |
5710 | return 0; | 5706 | return 0; |
5711 | reg_w_i(gspca_dev, reg, 0x0092); | 5707 | reg_w(gspca_dev, reg, 0x0092); |
5712 | reg_w_i(gspca_dev, 0x02, 0x0090); /* <- read command */ | 5708 | reg_w(gspca_dev, 0x02, 0x0090); /* <- read command */ |
5713 | msleep(20); | 5709 | msleep(20); |
5714 | retbyte = reg_r_i(gspca_dev, 0x0091); /* read status */ | 5710 | retbyte = reg_r(gspca_dev, 0x0091); /* read status */ |
5715 | if (retbyte != 0x00) | 5711 | if (retbyte != 0x00) |
5716 | pr_err("i2c_r status error %02x\n", retbyte); | 5712 | pr_err("i2c_r status error %02x\n", retbyte); |
5717 | retval = reg_r_i(gspca_dev, 0x0095); /* read Lowbyte */ | 5713 | retval = reg_r(gspca_dev, 0x0095); /* read Lowbyte */ |
5718 | retval |= reg_r_i(gspca_dev, 0x0096) << 8; /* read Hightbyte */ | 5714 | retval |= reg_r(gspca_dev, 0x0096) << 8; /* read Hightbyte */ |
5719 | PDEBUG(D_USBI, "i2c r [%02x] -> %04x (%02x)", | ||
5720 | reg, retval, retbyte); | ||
5721 | return retval; | 5715 | return retval; |
5722 | } | 5716 | } |
5723 | 5717 | ||
@@ -5730,16 +5724,14 @@ static u8 i2c_write(struct gspca_dev *gspca_dev, | |||
5730 | 5724 | ||
5731 | if (gspca_dev->usb_err < 0) | 5725 | if (gspca_dev->usb_err < 0) |
5732 | return 0; | 5726 | return 0; |
5733 | reg_w_i(gspca_dev, reg, 0x92); | 5727 | reg_w(gspca_dev, reg, 0x92); |
5734 | reg_w_i(gspca_dev, valL, 0x93); | 5728 | reg_w(gspca_dev, valL, 0x93); |
5735 | reg_w_i(gspca_dev, valH, 0x94); | 5729 | reg_w(gspca_dev, valH, 0x94); |
5736 | reg_w_i(gspca_dev, 0x01, 0x90); /* <- write command */ | 5730 | reg_w(gspca_dev, 0x01, 0x90); /* <- write command */ |
5737 | msleep(1); | 5731 | msleep(1); |
5738 | retbyte = reg_r_i(gspca_dev, 0x0091); /* read status */ | 5732 | retbyte = reg_r(gspca_dev, 0x0091); /* read status */ |
5739 | if (retbyte != 0x00) | 5733 | if (retbyte != 0x00) |
5740 | pr_err("i2c_w status error %02x\n", retbyte); | 5734 | pr_err("i2c_w status error %02x\n", retbyte); |
5741 | PDEBUG(D_USBO, "i2c w [%02x] = %02x%02x (%02x)", | ||
5742 | reg, valH, valL, retbyte); | ||
5743 | return retbyte; | 5735 | return retbyte; |
5744 | } | 5736 | } |
5745 | 5737 | ||
@@ -5906,6 +5898,8 @@ static void getexposure(struct gspca_dev *gspca_dev) | |||
5906 | { | 5898 | { |
5907 | struct sd *sd = (struct sd *) gspca_dev; | 5899 | struct sd *sd = (struct sd *) gspca_dev; |
5908 | 5900 | ||
5901 | if (sd->sensor != SENSOR_HV7131R) | ||
5902 | return; | ||
5909 | sd->ctrls[EXPOSURE].val = (i2c_read(gspca_dev, 0x25) << 9) | 5903 | sd->ctrls[EXPOSURE].val = (i2c_read(gspca_dev, 0x25) << 9) |
5910 | | (i2c_read(gspca_dev, 0x26) << 1) | 5904 | | (i2c_read(gspca_dev, 0x26) << 1) |
5911 | | (i2c_read(gspca_dev, 0x27) >> 7); | 5905 | | (i2c_read(gspca_dev, 0x27) >> 7); |
@@ -5916,6 +5910,8 @@ static void setexposure(struct gspca_dev *gspca_dev) | |||
5916 | struct sd *sd = (struct sd *) gspca_dev; | 5910 | struct sd *sd = (struct sd *) gspca_dev; |
5917 | int val; | 5911 | int val; |
5918 | 5912 | ||
5913 | if (sd->sensor != SENSOR_HV7131R) | ||
5914 | return; | ||
5919 | val = sd->ctrls[EXPOSURE].val; | 5915 | val = sd->ctrls[EXPOSURE].val; |
5920 | i2c_write(gspca_dev, 0x25, val >> 9, 0x00); | 5916 | i2c_write(gspca_dev, 0x25, val >> 9, 0x00); |
5921 | i2c_write(gspca_dev, 0x26, val >> 1, 0x00); | 5917 | i2c_write(gspca_dev, 0x26, val >> 1, 0x00); |
@@ -5925,32 +5921,20 @@ static void setexposure(struct gspca_dev *gspca_dev) | |||
5925 | static void setquality(struct gspca_dev *gspca_dev) | 5921 | static void setquality(struct gspca_dev *gspca_dev) |
5926 | { | 5922 | { |
5927 | struct sd *sd = (struct sd *) gspca_dev; | 5923 | struct sd *sd = (struct sd *) gspca_dev; |
5928 | u8 frxt; | 5924 | s8 reg07; |
5929 | 5925 | ||
5926 | reg07 = 0; | ||
5930 | switch (sd->sensor) { | 5927 | switch (sd->sensor) { |
5931 | case SENSOR_ADCM2700: | ||
5932 | case SENSOR_GC0305: | ||
5933 | case SENSOR_HV7131B: | ||
5934 | case SENSOR_HV7131R: | ||
5935 | case SENSOR_OV7620: | 5928 | case SENSOR_OV7620: |
5929 | reg07 = 0x30; | ||
5930 | break; | ||
5931 | case SENSOR_HV7131R: | ||
5936 | case SENSOR_PAS202B: | 5932 | case SENSOR_PAS202B: |
5937 | case SENSOR_PO2030: | 5933 | return; /* done by work queue */ |
5938 | return; | ||
5939 | } | 5934 | } |
5940 | /*fixme: is it really 0008 0007 0018 for all other sensors? */ | 5935 | reg_w(gspca_dev, sd->reg08, ZC3XX_R008_CLOCKSETTING); |
5941 | reg_w(gspca_dev, QUANT_VAL, 0x0008); | 5936 | if (reg07 != 0) |
5942 | frxt = 0x30; | 5937 | reg_w(gspca_dev, reg07, 0x0007); |
5943 | reg_w(gspca_dev, frxt, 0x0007); | ||
5944 | #if QUANT_VAL == 0 || QUANT_VAL == 1 || QUANT_VAL == 2 | ||
5945 | frxt = 0xff; | ||
5946 | #elif QUANT_VAL == 3 | ||
5947 | frxt = 0xf0; | ||
5948 | #elif QUANT_VAL == 4 | ||
5949 | frxt = 0xe0; | ||
5950 | #else | ||
5951 | frxt = 0x20; | ||
5952 | #endif | ||
5953 | reg_w(gspca_dev, frxt, 0x0018); | ||
5954 | } | 5938 | } |
5955 | 5939 | ||
5956 | /* Matches the sensor's internal frame rate to the lighting frequency. | 5940 | /* Matches the sensor's internal frame rate to the lighting frequency. |
@@ -6084,6 +6068,115 @@ static void setautogain(struct gspca_dev *gspca_dev) | |||
6084 | reg_w(gspca_dev, autoval, 0x0180); | 6068 | reg_w(gspca_dev, autoval, 0x0180); |
6085 | } | 6069 | } |
6086 | 6070 | ||
6071 | /* update the transfer parameters */ | ||
6072 | /* This function is executed from a work queue. */ | ||
6073 | /* The exact use of the bridge registers 07 and 08 is not known. | ||
6074 | * The following algorithm has been adapted from ms-win traces */ | ||
6075 | static void transfer_update(struct work_struct *work) | ||
6076 | { | ||
6077 | struct sd *sd = container_of(work, struct sd, work); | ||
6078 | struct gspca_dev *gspca_dev = &sd->gspca_dev; | ||
6079 | int change, good; | ||
6080 | u8 reg07, reg11; | ||
6081 | |||
6082 | /* synchronize with the main driver and initialize the registers */ | ||
6083 | mutex_lock(&gspca_dev->usb_lock); | ||
6084 | reg07 = 0; /* max */ | ||
6085 | reg_w(gspca_dev, reg07, 0x0007); | ||
6086 | reg_w(gspca_dev, sd->reg08, ZC3XX_R008_CLOCKSETTING); | ||
6087 | mutex_unlock(&gspca_dev->usb_lock); | ||
6088 | |||
6089 | good = 0; | ||
6090 | for (;;) { | ||
6091 | msleep(100); | ||
6092 | |||
6093 | /* get the transfer status */ | ||
6094 | /* the bit 0 of the bridge register 11 indicates overflow */ | ||
6095 | mutex_lock(&gspca_dev->usb_lock); | ||
6096 | if (!gspca_dev->present || !gspca_dev->streaming) | ||
6097 | goto err; | ||
6098 | reg11 = reg_r(gspca_dev, 0x0011); | ||
6099 | if (gspca_dev->usb_err < 0 | ||
6100 | || !gspca_dev->present || !gspca_dev->streaming) | ||
6101 | goto err; | ||
6102 | |||
6103 | change = reg11 & 0x01; | ||
6104 | if (change) { /* overflow */ | ||
6105 | switch (reg07) { | ||
6106 | case 0: /* max */ | ||
6107 | reg07 = sd->sensor == SENSOR_HV7131R | ||
6108 | ? 0x30 : 0x32; | ||
6109 | if (sd->reg08 != 0) { | ||
6110 | change = 3; | ||
6111 | sd->reg08--; | ||
6112 | } | ||
6113 | break; | ||
6114 | case 0x32: | ||
6115 | reg07 -= 4; | ||
6116 | break; | ||
6117 | default: | ||
6118 | reg07 -= 2; | ||
6119 | break; | ||
6120 | case 2: | ||
6121 | change = 0; /* already min */ | ||
6122 | break; | ||
6123 | } | ||
6124 | good = 0; | ||
6125 | } else { /* no overflow */ | ||
6126 | if (reg07 != 0) { /* if not max */ | ||
6127 | good++; | ||
6128 | if (good >= 10) { | ||
6129 | good = 0; | ||
6130 | change = 1; | ||
6131 | reg07 += 2; | ||
6132 | switch (reg07) { | ||
6133 | case 0x30: | ||
6134 | if (sd->sensor == SENSOR_PAS202B) | ||
6135 | reg07 += 2; | ||
6136 | break; | ||
6137 | case 0x32: | ||
6138 | case 0x34: | ||
6139 | reg07 = 0; | ||
6140 | break; | ||
6141 | } | ||
6142 | } | ||
6143 | } else { /* reg07 max */ | ||
6144 | if (sd->reg08 < sizeof jpeg_qual - 1) { | ||
6145 | good++; | ||
6146 | if (good > 10) { | ||
6147 | sd->reg08++; | ||
6148 | change = 2; | ||
6149 | } | ||
6150 | } | ||
6151 | } | ||
6152 | } | ||
6153 | if (change) { | ||
6154 | if (change & 1) { | ||
6155 | reg_w(gspca_dev, reg07, 0x0007); | ||
6156 | if (gspca_dev->usb_err < 0 | ||
6157 | || !gspca_dev->present | ||
6158 | || !gspca_dev->streaming) | ||
6159 | goto err; | ||
6160 | } | ||
6161 | if (change & 2) { | ||
6162 | reg_w(gspca_dev, sd->reg08, | ||
6163 | ZC3XX_R008_CLOCKSETTING); | ||
6164 | if (gspca_dev->usb_err < 0 | ||
6165 | || !gspca_dev->present | ||
6166 | || !gspca_dev->streaming) | ||
6167 | goto err; | ||
6168 | sd->ctrls[QUALITY].val = jpeg_qual[sd->reg08]; | ||
6169 | jpeg_set_qual(sd->jpeg_hdr, | ||
6170 | jpeg_qual[sd->reg08]); | ||
6171 | } | ||
6172 | } | ||
6173 | mutex_unlock(&gspca_dev->usb_lock); | ||
6174 | } | ||
6175 | return; | ||
6176 | err: | ||
6177 | mutex_unlock(&gspca_dev->usb_lock); | ||
6178 | } | ||
6179 | |||
6087 | static void send_unknown(struct gspca_dev *gspca_dev, int sensor) | 6180 | static void send_unknown(struct gspca_dev *gspca_dev, int sensor) |
6088 | { | 6181 | { |
6089 | reg_w(gspca_dev, 0x01, 0x0000); /* bridge reset */ | 6182 | reg_w(gspca_dev, 0x01, 0x0000); /* bridge reset */ |
@@ -6411,7 +6504,9 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
6411 | sd->sensor = id->driver_info; | 6504 | sd->sensor = id->driver_info; |
6412 | 6505 | ||
6413 | gspca_dev->cam.ctrls = sd->ctrls; | 6506 | gspca_dev->cam.ctrls = sd->ctrls; |
6414 | sd->quality = QUALITY_DEF; | 6507 | sd->reg08 = REG08_DEF; |
6508 | |||
6509 | INIT_WORK(&sd->work, transfer_update); | ||
6415 | 6510 | ||
6416 | return 0; | 6511 | return 0; |
6417 | } | 6512 | } |
@@ -6464,6 +6559,27 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
6464 | [SENSOR_PO2030] = 1, | 6559 | [SENSOR_PO2030] = 1, |
6465 | [SENSOR_TAS5130C] = 1, | 6560 | [SENSOR_TAS5130C] = 1, |
6466 | }; | 6561 | }; |
6562 | static const u8 reg08_tb[SENSOR_MAX] = { | ||
6563 | [SENSOR_ADCM2700] = 1, | ||
6564 | [SENSOR_CS2102] = 3, | ||
6565 | [SENSOR_CS2102K] = 3, | ||
6566 | [SENSOR_GC0303] = 2, | ||
6567 | [SENSOR_GC0305] = 3, | ||
6568 | [SENSOR_HDCS2020] = 1, | ||
6569 | [SENSOR_HV7131B] = 3, | ||
6570 | [SENSOR_HV7131R] = 3, | ||
6571 | [SENSOR_ICM105A] = 3, | ||
6572 | [SENSOR_MC501CB] = 3, | ||
6573 | [SENSOR_MT9V111_1] = 3, | ||
6574 | [SENSOR_MT9V111_3] = 3, | ||
6575 | [SENSOR_OV7620] = 1, | ||
6576 | [SENSOR_OV7630C] = 3, | ||
6577 | [SENSOR_PAS106] = 3, | ||
6578 | [SENSOR_PAS202B] = 3, | ||
6579 | [SENSOR_PB0330] = 3, | ||
6580 | [SENSOR_PO2030] = 2, | ||
6581 | [SENSOR_TAS5130C] = 3, | ||
6582 | }; | ||
6467 | 6583 | ||
6468 | sensor = zcxx_probeSensor(gspca_dev); | 6584 | sensor = zcxx_probeSensor(gspca_dev); |
6469 | if (sensor >= 0) | 6585 | if (sensor >= 0) |
@@ -6528,7 +6644,6 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
6528 | case 0x0e: | 6644 | case 0x0e: |
6529 | PDEBUG(D_PROBE, "Find Sensor PAS202B"); | 6645 | PDEBUG(D_PROBE, "Find Sensor PAS202B"); |
6530 | sd->sensor = SENSOR_PAS202B; | 6646 | sd->sensor = SENSOR_PAS202B; |
6531 | /* sd->sharpness = 1; */ | ||
6532 | break; | 6647 | break; |
6533 | case 0x0f: | 6648 | case 0x0f: |
6534 | PDEBUG(D_PROBE, "Find Sensor PAS106"); | 6649 | PDEBUG(D_PROBE, "Find Sensor PAS106"); |
@@ -6616,13 +6731,21 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
6616 | } | 6731 | } |
6617 | 6732 | ||
6618 | sd->ctrls[GAMMA].def = gamma[sd->sensor]; | 6733 | sd->ctrls[GAMMA].def = gamma[sd->sensor]; |
6734 | sd->reg08 = reg08_tb[sd->sensor]; | ||
6735 | sd->ctrls[QUALITY].def = jpeg_qual[sd->reg08]; | ||
6736 | sd->ctrls[QUALITY].min = jpeg_qual[0]; | ||
6737 | sd->ctrls[QUALITY].max = jpeg_qual[ARRAY_SIZE(jpeg_qual) - 1]; | ||
6619 | 6738 | ||
6620 | switch (sd->sensor) { | 6739 | switch (sd->sensor) { |
6621 | case SENSOR_HV7131R: | 6740 | case SENSOR_HV7131R: |
6741 | gspca_dev->ctrl_dis = (1 << QUALITY); | ||
6622 | break; | 6742 | break; |
6623 | case SENSOR_OV7630C: | 6743 | case SENSOR_OV7630C: |
6624 | gspca_dev->ctrl_dis = (1 << LIGHTFREQ) | (1 << EXPOSURE); | 6744 | gspca_dev->ctrl_dis = (1 << LIGHTFREQ) | (1 << EXPOSURE); |
6625 | break; | 6745 | break; |
6746 | case SENSOR_PAS202B: | ||
6747 | gspca_dev->ctrl_dis = (1 << QUALITY) | (1 << EXPOSURE); | ||
6748 | break; | ||
6626 | default: | 6749 | default: |
6627 | gspca_dev->ctrl_dis = (1 << EXPOSURE); | 6750 | gspca_dev->ctrl_dis = (1 << EXPOSURE); |
6628 | break; | 6751 | break; |
@@ -6685,7 +6808,6 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
6685 | /* create the JPEG header */ | 6808 | /* create the JPEG header */ |
6686 | jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, | 6809 | jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, |
6687 | 0x21); /* JPEG 422 */ | 6810 | 0x21); /* JPEG 422 */ |
6688 | jpeg_set_qual(sd->jpeg_hdr, sd->quality); | ||
6689 | 6811 | ||
6690 | mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; | 6812 | mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; |
6691 | switch (sd->sensor) { | 6813 | switch (sd->sensor) { |
@@ -6761,10 +6883,9 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
6761 | reg_r(gspca_dev, 0x0180); /* from win */ | 6883 | reg_r(gspca_dev, 0x0180); /* from win */ |
6762 | reg_w(gspca_dev, 0x00, 0x0180); | 6884 | reg_w(gspca_dev, 0x00, 0x0180); |
6763 | break; | 6885 | break; |
6764 | default: | ||
6765 | setquality(gspca_dev); | ||
6766 | break; | ||
6767 | } | 6886 | } |
6887 | setquality(gspca_dev); | ||
6888 | jpeg_set_qual(sd->jpeg_hdr, jpeg_qual[sd->reg08]); | ||
6768 | setlightfreq(gspca_dev); | 6889 | setlightfreq(gspca_dev); |
6769 | 6890 | ||
6770 | switch (sd->sensor) { | 6891 | switch (sd->sensor) { |
@@ -6776,8 +6897,7 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
6776 | reg_w(gspca_dev, 0x40, 0x0117); | 6897 | reg_w(gspca_dev, 0x40, 0x0117); |
6777 | break; | 6898 | break; |
6778 | case SENSOR_HV7131R: | 6899 | case SENSOR_HV7131R: |
6779 | if (!sd->ctrls[AUTOGAIN].val) | 6900 | setexposure(gspca_dev); |
6780 | setexposure(gspca_dev); | ||
6781 | reg_w(gspca_dev, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN); | 6901 | reg_w(gspca_dev, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN); |
6782 | break; | 6902 | break; |
6783 | case SENSOR_GC0305: | 6903 | case SENSOR_GC0305: |
@@ -6802,13 +6922,19 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
6802 | } | 6922 | } |
6803 | 6923 | ||
6804 | setautogain(gspca_dev); | 6924 | setautogain(gspca_dev); |
6805 | switch (sd->sensor) { | 6925 | |
6806 | case SENSOR_PO2030: | 6926 | /* start the transfer update thread if needed */ |
6807 | msleep(50); | 6927 | if (gspca_dev->usb_err >= 0) { |
6808 | reg_w(gspca_dev, 0x00, 0x0007); /* (from win traces) */ | 6928 | switch (sd->sensor) { |
6809 | reg_w(gspca_dev, 0x02, ZC3XX_R008_CLOCKSETTING); | 6929 | case SENSOR_HV7131R: |
6810 | break; | 6930 | case SENSOR_PAS202B: |
6931 | sd->work_thread = | ||
6932 | create_singlethread_workqueue(KBUILD_MODNAME); | ||
6933 | queue_work(sd->work_thread, &sd->work); | ||
6934 | break; | ||
6935 | } | ||
6811 | } | 6936 | } |
6937 | |||
6812 | return gspca_dev->usb_err; | 6938 | return gspca_dev->usb_err; |
6813 | } | 6939 | } |
6814 | 6940 | ||
@@ -6817,6 +6943,12 @@ static void sd_stop0(struct gspca_dev *gspca_dev) | |||
6817 | { | 6943 | { |
6818 | struct sd *sd = (struct sd *) gspca_dev; | 6944 | struct sd *sd = (struct sd *) gspca_dev; |
6819 | 6945 | ||
6946 | if (sd->work_thread != NULL) { | ||
6947 | mutex_unlock(&gspca_dev->usb_lock); | ||
6948 | destroy_workqueue(sd->work_thread); | ||
6949 | mutex_lock(&gspca_dev->usb_lock); | ||
6950 | sd->work_thread = NULL; | ||
6951 | } | ||
6820 | if (!gspca_dev->present) | 6952 | if (!gspca_dev->present) |
6821 | return; | 6953 | return; |
6822 | send_unknown(gspca_dev, sd->sensor); | 6954 | send_unknown(gspca_dev, sd->sensor); |
@@ -6893,19 +7025,33 @@ static int sd_querymenu(struct gspca_dev *gspca_dev, | |||
6893 | return -EINVAL; | 7025 | return -EINVAL; |
6894 | } | 7026 | } |
6895 | 7027 | ||
7028 | static int sd_setquality(struct gspca_dev *gspca_dev, __s32 val) | ||
7029 | { | ||
7030 | struct sd *sd = (struct sd *) gspca_dev; | ||
7031 | int i; | ||
7032 | |||
7033 | for (i = 0; i < ARRAY_SIZE(jpeg_qual) - 1; i++) { | ||
7034 | if (val <= jpeg_qual[i]) | ||
7035 | break; | ||
7036 | } | ||
7037 | if (i > 0 | ||
7038 | && i == sd->reg08 | ||
7039 | && val < jpeg_qual[sd->reg08]) | ||
7040 | i--; | ||
7041 | sd->reg08 = i; | ||
7042 | sd->ctrls[QUALITY].val = jpeg_qual[i]; | ||
7043 | if (gspca_dev->streaming) | ||
7044 | jpeg_set_qual(sd->jpeg_hdr, sd->ctrls[QUALITY].val); | ||
7045 | return gspca_dev->usb_err; | ||
7046 | } | ||
7047 | |||
6896 | static int sd_set_jcomp(struct gspca_dev *gspca_dev, | 7048 | static int sd_set_jcomp(struct gspca_dev *gspca_dev, |
6897 | struct v4l2_jpegcompression *jcomp) | 7049 | struct v4l2_jpegcompression *jcomp) |
6898 | { | 7050 | { |
6899 | struct sd *sd = (struct sd *) gspca_dev; | 7051 | struct sd *sd = (struct sd *) gspca_dev; |
6900 | 7052 | ||
6901 | if (jcomp->quality < QUALITY_MIN) | 7053 | sd_setquality(gspca_dev, jcomp->quality); |
6902 | sd->quality = QUALITY_MIN; | 7054 | jcomp->quality = sd->ctrls[QUALITY].val; |
6903 | else if (jcomp->quality > QUALITY_MAX) | ||
6904 | sd->quality = QUALITY_MAX; | ||
6905 | else | ||
6906 | sd->quality = jcomp->quality; | ||
6907 | if (gspca_dev->streaming) | ||
6908 | jpeg_set_qual(sd->jpeg_hdr, sd->quality); | ||
6909 | return gspca_dev->usb_err; | 7055 | return gspca_dev->usb_err; |
6910 | } | 7056 | } |
6911 | 7057 | ||
@@ -6915,7 +7061,7 @@ static int sd_get_jcomp(struct gspca_dev *gspca_dev, | |||
6915 | struct sd *sd = (struct sd *) gspca_dev; | 7061 | struct sd *sd = (struct sd *) gspca_dev; |
6916 | 7062 | ||
6917 | memset(jcomp, 0, sizeof *jcomp); | 7063 | memset(jcomp, 0, sizeof *jcomp); |
6918 | jcomp->quality = sd->quality; | 7064 | jcomp->quality = sd->ctrls[QUALITY].val; |
6919 | jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT | 7065 | jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT |
6920 | | V4L2_JPEG_MARKER_DQT; | 7066 | | V4L2_JPEG_MARKER_DQT; |
6921 | return 0; | 7067 | return 0; |
@@ -6938,7 +7084,7 @@ static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, | |||
6938 | #endif | 7084 | #endif |
6939 | 7085 | ||
6940 | static const struct sd_desc sd_desc = { | 7086 | static const struct sd_desc sd_desc = { |
6941 | .name = MODULE_NAME, | 7087 | .name = KBUILD_MODNAME, |
6942 | .ctrls = sd_ctrls, | 7088 | .ctrls = sd_ctrls, |
6943 | .nctrls = ARRAY_SIZE(sd_ctrls), | 7089 | .nctrls = ARRAY_SIZE(sd_ctrls), |
6944 | .config = sd_config, | 7090 | .config = sd_config, |
@@ -7023,7 +7169,7 @@ static int sd_probe(struct usb_interface *intf, | |||
7023 | 7169 | ||
7024 | /* USB driver */ | 7170 | /* USB driver */ |
7025 | static struct usb_driver sd_driver = { | 7171 | static struct usb_driver sd_driver = { |
7026 | .name = MODULE_NAME, | 7172 | .name = KBUILD_MODNAME, |
7027 | .id_table = device_table, | 7173 | .id_table = device_table, |
7028 | .probe = sd_probe, | 7174 | .probe = sd_probe, |
7029 | .disconnect = gspca_disconnect, | 7175 | .disconnect = gspca_disconnect, |