aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video
diff options
context:
space:
mode:
authorJean-François Moine <moinejf@free.fr>2012-03-19 03:30:07 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-03-19 21:28:44 -0400
commitc5224d81aed8c174d6dd5f406f63f522213c9673 (patch)
tree77b617ee3facead76d415f7836d8262dc483288a /drivers/media/video
parent1f42df0db04356ff9384514e1ec027df9ce3d132 (diff)
[media] gspca - sn9c20x: Use the new video control mechanism
Signed-off-by: Jean-François Moine <moinejf@free.fr> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video')
-rw-r--r--drivers/media/video/gspca/sn9c20x.c529
1 files changed, 134 insertions, 395 deletions
diff --git a/drivers/media/video/gspca/sn9c20x.c b/drivers/media/video/gspca/sn9c20x.c
index e54bf54b3901..45092eed8fc7 100644
--- a/drivers/media/video/gspca/sn9c20x.c
+++ b/drivers/media/video/gspca/sn9c20x.c
@@ -66,10 +66,28 @@ 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
69enum 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 NCTRLS /* number of controls */
83};
84
69/* specific webcam descriptor */ 85/* specific webcam descriptor */
70struct sd { 86struct sd {
71 struct gspca_dev gspca_dev; 87 struct gspca_dev gspca_dev;
72 88
89 struct gspca_ctrl ctrls[NCTRLS];
90
73#define MIN_AVG_LUM 80 91#define MIN_AVG_LUM 80
74#define MAX_AVG_LUM 130 92#define MAX_AVG_LUM 130
75 atomic_t avg_lum; 93 atomic_t avg_lum;
@@ -77,20 +95,6 @@ struct sd {
77 u8 older_step; 95 u8 older_step;
78 u8 exposure_step; 96 u8 exposure_step;
79 97
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; 98 u8 i2c_addr;
95 u8 sensor; 99 u8 sensor;
96 u8 hstart; 100 u8 hstart;
@@ -112,31 +116,6 @@ struct i2c_reg_u16 {
112 u16 val; 116 u16 val;
113}; 117};
114 118
115static int sd_setbrightness(struct gspca_dev *gspca_dev, s32 val);
116static int sd_getbrightness(struct gspca_dev *gspca_dev, s32 *val);
117static int sd_setcontrast(struct gspca_dev *gspca_dev, s32 val);
118static int sd_getcontrast(struct gspca_dev *gspca_dev, s32 *val);
119static int sd_setsaturation(struct gspca_dev *gspca_dev, s32 val);
120static int sd_getsaturation(struct gspca_dev *gspca_dev, s32 *val);
121static int sd_sethue(struct gspca_dev *gspca_dev, s32 val);
122static int sd_gethue(struct gspca_dev *gspca_dev, s32 *val);
123static int sd_setgamma(struct gspca_dev *gspca_dev, s32 val);
124static int sd_getgamma(struct gspca_dev *gspca_dev, s32 *val);
125static int sd_setredbalance(struct gspca_dev *gspca_dev, s32 val);
126static int sd_getredbalance(struct gspca_dev *gspca_dev, s32 *val);
127static int sd_setbluebalance(struct gspca_dev *gspca_dev, s32 val);
128static int sd_getbluebalance(struct gspca_dev *gspca_dev, s32 *val);
129static int sd_setvflip(struct gspca_dev *gspca_dev, s32 val);
130static int sd_getvflip(struct gspca_dev *gspca_dev, s32 *val);
131static int sd_sethflip(struct gspca_dev *gspca_dev, s32 val);
132static int sd_gethflip(struct gspca_dev *gspca_dev, s32 *val);
133static int sd_setgain(struct gspca_dev *gspca_dev, s32 val);
134static int sd_getgain(struct gspca_dev *gspca_dev, s32 *val);
135static int sd_setexposure(struct gspca_dev *gspca_dev, s32 val);
136static int sd_getexposure(struct gspca_dev *gspca_dev, s32 *val);
137static int sd_setautoexposure(struct gspca_dev *gspca_dev, s32 val);
138static int sd_getautoexposure(struct gspca_dev *gspca_dev, s32 *val);
139
140static const struct dmi_system_id flip_dmi_table[] = { 119static const struct dmi_system_id flip_dmi_table[] = {
141 { 120 {
142 .ident = "MSI MS-1034", 121 .ident = "MSI MS-1034",
@@ -177,9 +156,15 @@ static const struct dmi_system_id flip_dmi_table[] = {
177 {} 156 {}
178}; 157};
179 158
180static const struct ctrl sd_ctrls[] = { 159static void set_cmatrix(struct gspca_dev *gspca_dev);
181 { 160static void set_gamma(struct gspca_dev *gspca_dev);
182#define BRIGHTNESS_IDX 0 161static void set_redblue(struct gspca_dev *gspca_dev);
162static void set_hvflip(struct gspca_dev *gspca_dev);
163static void set_exposure(struct gspca_dev *gspca_dev);
164static void set_gain(struct gspca_dev *gspca_dev);
165
166static const struct ctrl sd_ctrls[NCTRLS] = {
167[BRIGHTNESS] = {
183 { 168 {
184 .id = V4L2_CID_BRIGHTNESS, 169 .id = V4L2_CID_BRIGHTNESS,
185 .type = V4L2_CTRL_TYPE_INTEGER, 170 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -187,14 +172,11 @@ static const struct ctrl sd_ctrls[] = {
187 .minimum = 0, 172 .minimum = 0,
188 .maximum = 0xff, 173 .maximum = 0xff,
189 .step = 1, 174 .step = 1,
190#define BRIGHTNESS_DEFAULT 0x7f 175 .default_value = 0x7f
191 .default_value = BRIGHTNESS_DEFAULT,
192 }, 176 },
193 .set = sd_setbrightness, 177 .set_control = set_cmatrix
194 .get = sd_getbrightness,
195 }, 178 },
196 { 179[CONTRAST] = {
197#define CONTRAST_IDX 1
198 { 180 {
199 .id = V4L2_CID_CONTRAST, 181 .id = V4L2_CID_CONTRAST,
200 .type = V4L2_CTRL_TYPE_INTEGER, 182 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -202,14 +184,11 @@ static const struct ctrl sd_ctrls[] = {
202 .minimum = 0, 184 .minimum = 0,
203 .maximum = 0xff, 185 .maximum = 0xff,
204 .step = 1, 186 .step = 1,
205#define CONTRAST_DEFAULT 0x7f 187 .default_value = 0x7f
206 .default_value = CONTRAST_DEFAULT,
207 }, 188 },
208 .set = sd_setcontrast, 189 .set_control = set_cmatrix
209 .get = sd_getcontrast,
210 }, 190 },
211 { 191[SATURATION] = {
212#define SATURATION_IDX 2
213 { 192 {
214 .id = V4L2_CID_SATURATION, 193 .id = V4L2_CID_SATURATION,
215 .type = V4L2_CTRL_TYPE_INTEGER, 194 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -217,14 +196,11 @@ static const struct ctrl sd_ctrls[] = {
217 .minimum = 0, 196 .minimum = 0,
218 .maximum = 0xff, 197 .maximum = 0xff,
219 .step = 1, 198 .step = 1,
220#define SATURATION_DEFAULT 0x7f 199 .default_value = 0x7f
221 .default_value = SATURATION_DEFAULT,
222 }, 200 },
223 .set = sd_setsaturation, 201 .set_control = set_cmatrix
224 .get = sd_getsaturation,
225 }, 202 },
226 { 203[HUE] = {
227#define HUE_IDX 3
228 { 204 {
229 .id = V4L2_CID_HUE, 205 .id = V4L2_CID_HUE,
230 .type = V4L2_CTRL_TYPE_INTEGER, 206 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -232,14 +208,11 @@ static const struct ctrl sd_ctrls[] = {
232 .minimum = -180, 208 .minimum = -180,
233 .maximum = 180, 209 .maximum = 180,
234 .step = 1, 210 .step = 1,
235#define HUE_DEFAULT 0 211 .default_value = 0
236 .default_value = HUE_DEFAULT,
237 }, 212 },
238 .set = sd_sethue, 213 .set_control = set_cmatrix
239 .get = sd_gethue,
240 }, 214 },
241 { 215[GAMMA] = {
242#define GAMMA_IDX 4
243 { 216 {
244 .id = V4L2_CID_GAMMA, 217 .id = V4L2_CID_GAMMA,
245 .type = V4L2_CTRL_TYPE_INTEGER, 218 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -247,14 +220,11 @@ static const struct ctrl sd_ctrls[] = {
247 .minimum = 0, 220 .minimum = 0,
248 .maximum = 0xff, 221 .maximum = 0xff,
249 .step = 1, 222 .step = 1,
250#define GAMMA_DEFAULT 0x10 223 .default_value = 0x10
251 .default_value = GAMMA_DEFAULT,
252 }, 224 },
253 .set = sd_setgamma, 225 .set_control = set_gamma
254 .get = sd_getgamma,
255 }, 226 },
256 { 227[BLUE] = {
257#define BLUE_IDX 5
258 { 228 {
259 .id = V4L2_CID_BLUE_BALANCE, 229 .id = V4L2_CID_BLUE_BALANCE,
260 .type = V4L2_CTRL_TYPE_INTEGER, 230 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -262,14 +232,11 @@ static const struct ctrl sd_ctrls[] = {
262 .minimum = 0, 232 .minimum = 0,
263 .maximum = 0x7f, 233 .maximum = 0x7f,
264 .step = 1, 234 .step = 1,
265#define BLUE_DEFAULT 0x28 235 .default_value = 0x28
266 .default_value = BLUE_DEFAULT,
267 }, 236 },
268 .set = sd_setbluebalance, 237 .set_control = set_redblue
269 .get = sd_getbluebalance,
270 }, 238 },
271 { 239[RED] = {
272#define RED_IDX 6
273 { 240 {
274 .id = V4L2_CID_RED_BALANCE, 241 .id = V4L2_CID_RED_BALANCE,
275 .type = V4L2_CTRL_TYPE_INTEGER, 242 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -277,14 +244,11 @@ static const struct ctrl sd_ctrls[] = {
277 .minimum = 0, 244 .minimum = 0,
278 .maximum = 0x7f, 245 .maximum = 0x7f,
279 .step = 1, 246 .step = 1,
280#define RED_DEFAULT 0x28 247 .default_value = 0x28
281 .default_value = RED_DEFAULT,
282 }, 248 },
283 .set = sd_setredbalance, 249 .set_control = set_redblue
284 .get = sd_getredbalance,
285 }, 250 },
286 { 251[HFLIP] = {
287#define HFLIP_IDX 7
288 { 252 {
289 .id = V4L2_CID_HFLIP, 253 .id = V4L2_CID_HFLIP,
290 .type = V4L2_CTRL_TYPE_BOOLEAN, 254 .type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -292,14 +256,11 @@ static const struct ctrl sd_ctrls[] = {
292 .minimum = 0, 256 .minimum = 0,
293 .maximum = 1, 257 .maximum = 1,
294 .step = 1, 258 .step = 1,
295#define HFLIP_DEFAULT 0 259 .default_value = 0,
296 .default_value = HFLIP_DEFAULT,
297 }, 260 },
298 .set = sd_sethflip, 261 .set_control = set_hvflip
299 .get = sd_gethflip,
300 }, 262 },
301 { 263[VFLIP] = {
302#define VFLIP_IDX 8
303 { 264 {
304 .id = V4L2_CID_VFLIP, 265 .id = V4L2_CID_VFLIP,
305 .type = V4L2_CTRL_TYPE_BOOLEAN, 266 .type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -307,14 +268,11 @@ static const struct ctrl sd_ctrls[] = {
307 .minimum = 0, 268 .minimum = 0,
308 .maximum = 1, 269 .maximum = 1,
309 .step = 1, 270 .step = 1,
310#define VFLIP_DEFAULT 0 271 .default_value = 0,
311 .default_value = VFLIP_DEFAULT,
312 }, 272 },
313 .set = sd_setvflip, 273 .set_control = set_hvflip
314 .get = sd_getvflip,
315 }, 274 },
316 { 275[EXPOSURE] = {
317#define EXPOSURE_IDX 9
318 { 276 {
319 .id = V4L2_CID_EXPOSURE, 277 .id = V4L2_CID_EXPOSURE,
320 .type = V4L2_CTRL_TYPE_INTEGER, 278 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -322,14 +280,11 @@ static const struct ctrl sd_ctrls[] = {
322 .minimum = 0, 280 .minimum = 0,
323 .maximum = 0x1780, 281 .maximum = 0x1780,
324 .step = 1, 282 .step = 1,
325#define EXPOSURE_DEFAULT 0x33 283 .default_value = 0x33,
326 .default_value = EXPOSURE_DEFAULT,
327 }, 284 },
328 .set = sd_setexposure, 285 .set_control = set_exposure
329 .get = sd_getexposure,
330 }, 286 },
331 { 287[GAIN] = {
332#define GAIN_IDX 10
333 { 288 {
334 .id = V4L2_CID_GAIN, 289 .id = V4L2_CID_GAIN,
335 .type = V4L2_CTRL_TYPE_INTEGER, 290 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -337,14 +292,11 @@ static const struct ctrl sd_ctrls[] = {
337 .minimum = 0, 292 .minimum = 0,
338 .maximum = 28, 293 .maximum = 28,
339 .step = 1, 294 .step = 1,
340#define GAIN_DEFAULT 0x00 295 .default_value = 0,
341 .default_value = GAIN_DEFAULT,
342 }, 296 },
343 .set = sd_setgain, 297 .set_control = set_gain
344 .get = sd_getgain,
345 }, 298 },
346 { 299[AUTOGAIN] = {
347#define AUTOGAIN_IDX 11
348 { 300 {
349 .id = V4L2_CID_AUTOGAIN, 301 .id = V4L2_CID_AUTOGAIN,
350 .type = V4L2_CTRL_TYPE_BOOLEAN, 302 .type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -352,11 +304,8 @@ static const struct ctrl sd_ctrls[] = {
352 .minimum = 0, 304 .minimum = 0,
353 .maximum = 1, 305 .maximum = 1,
354 .step = 1, 306 .step = 1,
355#define AUTO_EXPOSURE_DEFAULT 1 307 .default_value = 1,
356 .default_value = AUTO_EXPOSURE_DEFAULT,
357 }, 308 },
358 .set = sd_setautoexposure,
359 .get = sd_getautoexposure,
360 }, 309 },
361}; 310};
362 311
@@ -1306,7 +1255,7 @@ static int ov9655_init_sensor(struct gspca_dev *gspca_dev)
1306 } 1255 }
1307 } 1256 }
1308 /* disable hflip and vflip */ 1257 /* disable hflip and vflip */
1309 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX); 1258 gspca_dev->ctrl_dis = (1 << HFLIP) | (1 << VFLIP);
1310 sd->hstart = 1; 1259 sd->hstart = 1;
1311 sd->vstart = 2; 1260 sd->vstart = 2;
1312 return 0; 1261 return 0;
@@ -1325,8 +1274,8 @@ static int soi968_init_sensor(struct gspca_dev *gspca_dev)
1325 } 1274 }
1326 } 1275 }
1327 /* disable hflip and vflip */ 1276 /* disable hflip and vflip */
1328 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX) 1277 gspca_dev->ctrl_dis = (1 << HFLIP) | (1 << VFLIP)
1329 | (1 << EXPOSURE_IDX); 1278 | (1 << EXPOSURE);
1330 sd->hstart = 60; 1279 sd->hstart = 60;
1331 sd->vstart = 11; 1280 sd->vstart = 11;
1332 return 0; 1281 return 0;
@@ -1362,7 +1311,7 @@ static int ov7670_init_sensor(struct gspca_dev *gspca_dev)
1362 } 1311 }
1363 } 1312 }
1364 /* disable hflip and vflip */ 1313 /* disable hflip and vflip */
1365 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX); 1314 gspca_dev->ctrl_dis = (1 << HFLIP) | (1 << VFLIP);
1366 sd->hstart = 0; 1315 sd->hstart = 0;
1367 sd->vstart = 1; 1316 sd->vstart = 1;
1368 return 0; 1317 return 0;
@@ -1403,9 +1352,9 @@ static int mt9v_init_sensor(struct gspca_dev *gspca_dev)
1403 return -ENODEV; 1352 return -ENODEV;
1404 } 1353 }
1405 } 1354 }
1406 gspca_dev->ctrl_dis = (1 << EXPOSURE_IDX) 1355 gspca_dev->ctrl_dis = (1 << EXPOSURE)
1407 | (1 << AUTOGAIN_IDX) 1356 | (1 << AUTOGAIN)
1408 | (1 << GAIN_IDX); 1357 | (1 << GAIN);
1409 sd->hstart = 2; 1358 sd->hstart = 2;
1410 sd->vstart = 2; 1359 sd->vstart = 2;
1411 sd->sensor = SENSOR_MT9V111; 1360 sd->sensor = SENSOR_MT9V111;
@@ -1449,8 +1398,8 @@ static int mt9m112_init_sensor(struct gspca_dev *gspca_dev)
1449 return -ENODEV; 1398 return -ENODEV;
1450 } 1399 }
1451 } 1400 }
1452 gspca_dev->ctrl_dis = (1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX) 1401 gspca_dev->ctrl_dis = (1 << EXPOSURE) | (1 << AUTOGAIN)
1453 | (1 << GAIN_IDX); 1402 | (1 << GAIN);
1454 sd->hstart = 0; 1403 sd->hstart = 0;
1455 sd->vstart = 2; 1404 sd->vstart = 2;
1456 return 0; 1405 return 0;
@@ -1467,8 +1416,8 @@ static int mt9m111_init_sensor(struct gspca_dev *gspca_dev)
1467 return -ENODEV; 1416 return -ENODEV;
1468 } 1417 }
1469 } 1418 }
1470 gspca_dev->ctrl_dis = (1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX) 1419 gspca_dev->ctrl_dis = (1 << EXPOSURE) | (1 << AUTOGAIN)
1471 | (1 << GAIN_IDX); 1420 | (1 << GAIN);
1472 sd->hstart = 0; 1421 sd->hstart = 0;
1473 sd->vstart = 2; 1422 sd->vstart = 2;
1474 return 0; 1423 return 0;
@@ -1505,7 +1454,7 @@ static int mt9m001_init_sensor(struct gspca_dev *gspca_dev)
1505 } 1454 }
1506 } 1455 }
1507 /* disable hflip and vflip */ 1456 /* disable hflip and vflip */
1508 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX); 1457 gspca_dev->ctrl_dis = (1 << HFLIP) | (1 << VFLIP);
1509 sd->hstart = 1; 1458 sd->hstart = 1;
1510 sd->vstart = 1; 1459 sd->vstart = 1;
1511 return 0; 1460 return 0;
@@ -1528,51 +1477,52 @@ static int hv7131r_init_sensor(struct gspca_dev *gspca_dev)
1528 return 0; 1477 return 0;
1529} 1478}
1530 1479
1531static int set_cmatrix(struct gspca_dev *gspca_dev) 1480static void set_cmatrix(struct gspca_dev *gspca_dev)
1532{ 1481{
1533 struct sd *sd = (struct sd *) gspca_dev; 1482 struct sd *sd = (struct sd *) gspca_dev;
1534 s32 hue_coord, hue_index = 180 + sd->hue; 1483 int satur;
1484 s32 hue_coord, hue_index = 180 + sd->ctrls[HUE].val;
1535 u8 cmatrix[21]; 1485 u8 cmatrix[21];
1536 1486
1537 memset(cmatrix, 0, sizeof cmatrix); 1487 memset(cmatrix, 0, sizeof cmatrix);
1538 cmatrix[2] = (sd->contrast * 0x25 / 0x100) + 0x26; 1488 cmatrix[2] = (sd->ctrls[CONTRAST].val * 0x25 / 0x100) + 0x26;
1539 cmatrix[0] = 0x13 + (cmatrix[2] - 0x26) * 0x13 / 0x25; 1489 cmatrix[0] = 0x13 + (cmatrix[2] - 0x26) * 0x13 / 0x25;
1540 cmatrix[4] = 0x07 + (cmatrix[2] - 0x26) * 0x07 / 0x25; 1490 cmatrix[4] = 0x07 + (cmatrix[2] - 0x26) * 0x07 / 0x25;
1541 cmatrix[18] = sd->brightness - 0x80; 1491 cmatrix[18] = sd->ctrls[BRIGHTNESS].val - 0x80;
1542 1492
1543 hue_coord = (hsv_red_x[hue_index] * sd->saturation) >> 8; 1493 satur = sd->ctrls[SATURATION].val;
1494 hue_coord = (hsv_red_x[hue_index] * satur) >> 8;
1544 cmatrix[6] = hue_coord; 1495 cmatrix[6] = hue_coord;
1545 cmatrix[7] = (hue_coord >> 8) & 0x0f; 1496 cmatrix[7] = (hue_coord >> 8) & 0x0f;
1546 1497
1547 hue_coord = (hsv_red_y[hue_index] * sd->saturation) >> 8; 1498 hue_coord = (hsv_red_y[hue_index] * satur) >> 8;
1548 cmatrix[8] = hue_coord; 1499 cmatrix[8] = hue_coord;
1549 cmatrix[9] = (hue_coord >> 8) & 0x0f; 1500 cmatrix[9] = (hue_coord >> 8) & 0x0f;
1550 1501
1551 hue_coord = (hsv_green_x[hue_index] * sd->saturation) >> 8; 1502 hue_coord = (hsv_green_x[hue_index] * satur) >> 8;
1552 cmatrix[10] = hue_coord; 1503 cmatrix[10] = hue_coord;
1553 cmatrix[11] = (hue_coord >> 8) & 0x0f; 1504 cmatrix[11] = (hue_coord >> 8) & 0x0f;
1554 1505
1555 hue_coord = (hsv_green_y[hue_index] * sd->saturation) >> 8; 1506 hue_coord = (hsv_green_y[hue_index] * satur) >> 8;
1556 cmatrix[12] = hue_coord; 1507 cmatrix[12] = hue_coord;
1557 cmatrix[13] = (hue_coord >> 8) & 0x0f; 1508 cmatrix[13] = (hue_coord >> 8) & 0x0f;
1558 1509
1559 hue_coord = (hsv_blue_x[hue_index] * sd->saturation) >> 8; 1510 hue_coord = (hsv_blue_x[hue_index] * satur) >> 8;
1560 cmatrix[14] = hue_coord; 1511 cmatrix[14] = hue_coord;
1561 cmatrix[15] = (hue_coord >> 8) & 0x0f; 1512 cmatrix[15] = (hue_coord >> 8) & 0x0f;
1562 1513
1563 hue_coord = (hsv_blue_y[hue_index] * sd->saturation) >> 8; 1514 hue_coord = (hsv_blue_y[hue_index] * satur) >> 8;
1564 cmatrix[16] = hue_coord; 1515 cmatrix[16] = hue_coord;
1565 cmatrix[17] = (hue_coord >> 8) & 0x0f; 1516 cmatrix[17] = (hue_coord >> 8) & 0x0f;
1566 1517
1567 return reg_w(gspca_dev, 0x10e1, cmatrix, 21); 1518 reg_w(gspca_dev, 0x10e1, cmatrix, 21);
1568} 1519}
1569 1520
1570static int set_gamma(struct gspca_dev *gspca_dev) 1521static void set_gamma(struct gspca_dev *gspca_dev)
1571{ 1522{
1572 struct sd *sd = (struct sd *) gspca_dev; 1523 struct sd *sd = (struct sd *) gspca_dev;
1573 u8 gamma[17]; 1524 u8 gamma[17];
1574 u8 gval = sd->gamma * 0xb8 / 0x100; 1525 u8 gval = sd->ctrls[GAMMA].val * 0xb8 / 0x100;
1575
1576 1526
1577 gamma[0] = 0x0a; 1527 gamma[0] = 0x0a;
1578 gamma[1] = 0x13 + (gval * (0xcb - 0x13) / 0xb8); 1528 gamma[1] = 0x13 + (gval * (0xcb - 0x13) / 0xb8);
@@ -1592,29 +1542,29 @@ static int set_gamma(struct gspca_dev *gspca_dev)
1592 gamma[15] = 0xea + (gval * (0xf9 - 0xea) / 0xb8); 1542 gamma[15] = 0xea + (gval * (0xf9 - 0xea) / 0xb8);
1593 gamma[16] = 0xf5; 1543 gamma[16] = 0xf5;
1594 1544
1595 return reg_w(gspca_dev, 0x1190, gamma, 17); 1545 reg_w(gspca_dev, 0x1190, gamma, 17);
1596} 1546}
1597 1547
1598static int set_redblue(struct gspca_dev *gspca_dev) 1548static void set_redblue(struct gspca_dev *gspca_dev)
1599{ 1549{
1600 struct sd *sd = (struct sd *) gspca_dev; 1550 struct sd *sd = (struct sd *) gspca_dev;
1601 reg_w1(gspca_dev, 0x118c, sd->red); 1551
1602 reg_w1(gspca_dev, 0x118f, sd->blue); 1552 reg_w1(gspca_dev, 0x118c, sd->ctrls[RED].val);
1603 return 0; 1553 reg_w1(gspca_dev, 0x118f, sd->ctrls[BLUE].val);
1604} 1554}
1605 1555
1606static int set_hvflip(struct gspca_dev *gspca_dev) 1556static void set_hvflip(struct gspca_dev *gspca_dev)
1607{ 1557{
1608 u8 value, tslb, hflip, vflip; 1558 u8 value, tslb, hflip, vflip;
1609 u16 value2; 1559 u16 value2;
1610 struct sd *sd = (struct sd *) gspca_dev; 1560 struct sd *sd = (struct sd *) gspca_dev;
1611 1561
1612 if ((sd->flags & FLIP_DETECT) && dmi_check_system(flip_dmi_table)) { 1562 if ((sd->flags & FLIP_DETECT) && dmi_check_system(flip_dmi_table)) {
1613 hflip = !sd->hflip; 1563 hflip = !sd->ctrls[HFLIP].val;
1614 vflip = !sd->vflip; 1564 vflip = !sd->ctrls[VFLIP].val;
1615 } else { 1565 } else {
1616 hflip = sd->hflip; 1566 hflip = sd->ctrls[HFLIP].val;
1617 vflip = sd->vflip; 1567 vflip = sd->ctrls[VFLIP].val;
1618 } 1568 }
1619 1569
1620 switch (sd->sensor) { 1570 switch (sd->sensor) {
@@ -1674,13 +1624,15 @@ static int set_hvflip(struct gspca_dev *gspca_dev)
1674 i2c_w1(gspca_dev, 0x01, value); 1624 i2c_w1(gspca_dev, 0x01, value);
1675 break; 1625 break;
1676 } 1626 }
1677 return 0;
1678} 1627}
1679 1628
1680static int set_exposure(struct gspca_dev *gspca_dev) 1629static void set_exposure(struct gspca_dev *gspca_dev)
1681{ 1630{
1682 struct sd *sd = (struct sd *) gspca_dev; 1631 struct sd *sd = (struct sd *) gspca_dev;
1683 u8 exp[8] = {0x81, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e}; 1632 u8 exp[8] = {0x81, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e};
1633 int expo;
1634
1635 expo = sd->ctrls[EXPOSURE].val;
1684 switch (sd->sensor) { 1636 switch (sd->sensor) {
1685 case SENSOR_OV7660: 1637 case SENSOR_OV7660:
1686 case SENSOR_OV7670: 1638 case SENSOR_OV7670:
@@ -1688,35 +1640,37 @@ static int set_exposure(struct gspca_dev *gspca_dev)
1688 case SENSOR_OV9650: 1640 case SENSOR_OV9650:
1689 exp[0] |= (3 << 4); 1641 exp[0] |= (3 << 4);
1690 exp[2] = 0x2d; 1642 exp[2] = 0x2d;
1691 exp[3] = sd->exposure & 0xff; 1643 exp[3] = expo;
1692 exp[4] = sd->exposure >> 8; 1644 exp[4] = expo >> 8;
1693 break; 1645 break;
1694 case SENSOR_MT9M001: 1646 case SENSOR_MT9M001:
1695 case SENSOR_MT9V112: 1647 case SENSOR_MT9V112:
1696 case SENSOR_MT9V011: 1648 case SENSOR_MT9V011:
1697 exp[0] |= (3 << 4); 1649 exp[0] |= (3 << 4);
1698 exp[2] = 0x09; 1650 exp[2] = 0x09;
1699 exp[3] = sd->exposure >> 8; 1651 exp[3] = expo >> 8;
1700 exp[4] = sd->exposure & 0xff; 1652 exp[4] = expo;
1701 break; 1653 break;
1702 case SENSOR_HV7131R: 1654 case SENSOR_HV7131R:
1703 exp[0] |= (4 << 4); 1655 exp[0] |= (4 << 4);
1704 exp[2] = 0x25; 1656 exp[2] = 0x25;
1705 exp[3] = (sd->exposure >> 5) & 0xff; 1657 exp[3] = expo >> 5;
1706 exp[4] = (sd->exposure << 3) & 0xff; 1658 exp[4] = expo << 3;
1707 exp[5] = 0; 1659 exp[5] = 0;
1708 break; 1660 break;
1709 default: 1661 default:
1710 return 0; 1662 return;
1711 } 1663 }
1712 i2c_w(gspca_dev, exp); 1664 i2c_w(gspca_dev, exp);
1713 return 0;
1714} 1665}
1715 1666
1716static int set_gain(struct gspca_dev *gspca_dev) 1667static void set_gain(struct gspca_dev *gspca_dev)
1717{ 1668{
1718 struct sd *sd = (struct sd *) gspca_dev; 1669 struct sd *sd = (struct sd *) gspca_dev;
1719 u8 gain[8] = {0x81, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d}; 1670 u8 gain[8] = {0x81, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d};
1671 int g;
1672
1673 g = sd->ctrls[GAIN].val;
1720 switch (sd->sensor) { 1674 switch (sd->sensor) {
1721 case SENSOR_OV7660: 1675 case SENSOR_OV7660:
1722 case SENSOR_OV7670: 1676 case SENSOR_OV7670:
@@ -1724,238 +1678,35 @@ static int set_gain(struct gspca_dev *gspca_dev)
1724 case SENSOR_OV9655: 1678 case SENSOR_OV9655:
1725 case SENSOR_OV9650: 1679 case SENSOR_OV9650:
1726 gain[0] |= (2 << 4); 1680 gain[0] |= (2 << 4);
1727 gain[3] = ov_gain[sd->gain]; 1681 gain[3] = ov_gain[g];
1728 break; 1682 break;
1729 case SENSOR_MT9V011: 1683 case SENSOR_MT9V011:
1730 gain[0] |= (3 << 4); 1684 gain[0] |= (3 << 4);
1731 gain[2] = 0x35; 1685 gain[2] = 0x35;
1732 gain[3] = micron1_gain[sd->gain] >> 8; 1686 gain[3] = micron1_gain[g] >> 8;
1733 gain[4] = micron1_gain[sd->gain] & 0xff; 1687 gain[4] = micron1_gain[g];
1734 break; 1688 break;
1735 case SENSOR_MT9V112: 1689 case SENSOR_MT9V112:
1736 gain[0] |= (3 << 4); 1690 gain[0] |= (3 << 4);
1737 gain[2] = 0x2f; 1691 gain[2] = 0x2f;
1738 gain[3] = micron1_gain[sd->gain] >> 8; 1692 gain[3] = micron1_gain[g] >> 8;
1739 gain[4] = micron1_gain[sd->gain] & 0xff; 1693 gain[4] = micron1_gain[g];
1740 break; 1694 break;
1741 case SENSOR_MT9M001: 1695 case SENSOR_MT9M001:
1742 gain[0] |= (3 << 4); 1696 gain[0] |= (3 << 4);
1743 gain[2] = 0x2f; 1697 gain[2] = 0x2f;
1744 gain[3] = micron2_gain[sd->gain] >> 8; 1698 gain[3] = micron2_gain[g] >> 8;
1745 gain[4] = micron2_gain[sd->gain] & 0xff; 1699 gain[4] = micron2_gain[g];
1746 break; 1700 break;
1747 case SENSOR_HV7131R: 1701 case SENSOR_HV7131R:
1748 gain[0] |= (2 << 4); 1702 gain[0] |= (2 << 4);
1749 gain[2] = 0x30; 1703 gain[2] = 0x30;
1750 gain[3] = hv7131r_gain[sd->gain]; 1704 gain[3] = hv7131r_gain[g];
1751 break; 1705 break;
1752 default: 1706 default:
1753 return 0; 1707 return;
1754 } 1708 }
1755 i2c_w(gspca_dev, gain); 1709 i2c_w(gspca_dev, gain);
1756 return 0;
1757}
1758
1759static 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
1769static 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
1777static 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
1787static 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
1794static 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}
1803
1804static int sd_getsaturation(struct gspca_dev *gspca_dev, s32 *val)
1805{
1806 struct sd *sd = (struct sd *) gspca_dev;
1807 *val = sd->saturation;
1808 return 0;
1809}
1810
1811static 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
1821static 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
1828static 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
1838static 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
1845static 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
1855static 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
1862static 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
1872static 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
1879static 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
1889static 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
1896static 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
1906static 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
1913static 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
1923static 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
1930static 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
1940static 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
1947static 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
1954static int sd_getautoexposure(struct gspca_dev *gspca_dev, s32 *val)
1955{
1956 struct sd *sd = (struct sd *) gspca_dev;
1957 *val = sd->auto_exposure;
1958 return 0;
1959} 1710}
1960 1711
1961#ifdef CONFIG_VIDEO_ADV_DEBUG 1712#ifdef CONFIG_VIDEO_ADV_DEBUG
@@ -2076,19 +1827,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
2076 sd->older_step = 0; 1827 sd->older_step = 0;
2077 sd->exposure_step = 16; 1828 sd->exposure_step = 16;
2078 1829
2079 sd->brightness = BRIGHTNESS_DEFAULT; 1830 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
2087 sd->hflip = HFLIP_DEFAULT;
2088 sd->vflip = VFLIP_DEFAULT;
2089 sd->exposure = EXPOSURE_DEFAULT;
2090 sd->gain = GAIN_DEFAULT;
2091 sd->auto_exposure = AUTO_EXPOSURE_DEFAULT;
2092 1831
2093 sd->quality = 95; 1832 sd->quality = 95;
2094 1833
@@ -2359,15 +2098,15 @@ static void do_autoexposure(struct gspca_dev *gspca_dev, u16 avg_lum)
2359 * and exposure steps 2098 * and exposure steps
2360 */ 2099 */
2361 if (avg_lum < MIN_AVG_LUM) { 2100 if (avg_lum < MIN_AVG_LUM) {
2362 if (sd->exposure > 0x1770) 2101 if (sd->ctrls[EXPOSURE].val > 0x1770)
2363 return; 2102 return;
2364 2103
2365 new_exp = sd->exposure + sd->exposure_step; 2104 new_exp = sd->ctrls[EXPOSURE].val + sd->exposure_step;
2366 if (new_exp > 0x1770) 2105 if (new_exp > 0x1770)
2367 new_exp = 0x1770; 2106 new_exp = 0x1770;
2368 if (new_exp < 0x10) 2107 if (new_exp < 0x10)
2369 new_exp = 0x10; 2108 new_exp = 0x10;
2370 sd->exposure = new_exp; 2109 sd->ctrls[EXPOSURE].val = new_exp;
2371 set_exposure(gspca_dev); 2110 set_exposure(gspca_dev);
2372 2111
2373 sd->older_step = sd->old_step; 2112 sd->older_step = sd->old_step;
@@ -2379,14 +2118,14 @@ static void do_autoexposure(struct gspca_dev *gspca_dev, u16 avg_lum)
2379 sd->exposure_step += 2; 2118 sd->exposure_step += 2;
2380 } 2119 }
2381 if (avg_lum > MAX_AVG_LUM) { 2120 if (avg_lum > MAX_AVG_LUM) {
2382 if (sd->exposure < 0x10) 2121 if (sd->ctrls[EXPOSURE].val < 0x10)
2383 return; 2122 return;
2384 new_exp = sd->exposure - sd->exposure_step; 2123 new_exp = sd->ctrls[EXPOSURE].val - sd->exposure_step;
2385 if (new_exp > 0x1700) 2124 if (new_exp > 0x1700)
2386 new_exp = 0x1770; 2125 new_exp = 0x1770;
2387 if (new_exp < 0x10) 2126 if (new_exp < 0x10)
2388 new_exp = 0x10; 2127 new_exp = 0x10;
2389 sd->exposure = new_exp; 2128 sd->ctrls[EXPOSURE].val = new_exp;
2390 set_exposure(gspca_dev); 2129 set_exposure(gspca_dev);
2391 sd->older_step = sd->old_step; 2130 sd->older_step = sd->old_step;
2392 sd->old_step = 0; 2131 sd->old_step = 0;
@@ -2403,14 +2142,14 @@ static void do_autogain(struct gspca_dev *gspca_dev, u16 avg_lum)
2403 struct sd *sd = (struct sd *) gspca_dev; 2142 struct sd *sd = (struct sd *) gspca_dev;
2404 2143
2405 if (avg_lum < MIN_AVG_LUM) { 2144 if (avg_lum < MIN_AVG_LUM) {
2406 if (sd->gain + 1 <= 28) { 2145 if (sd->ctrls[GAIN].val + 1 <= 28) {
2407 sd->gain++; 2146 sd->ctrls[GAIN].val++;
2408 set_gain(gspca_dev); 2147 set_gain(gspca_dev);
2409 } 2148 }
2410 } 2149 }
2411 if (avg_lum > MAX_AVG_LUM) { 2150 if (avg_lum > MAX_AVG_LUM) {
2412 if (sd->gain > 0) { 2151 if (sd->ctrls[GAIN].val > 0) {
2413 sd->gain--; 2152 sd->ctrls[GAIN].val--;
2414 set_gain(gspca_dev); 2153 set_gain(gspca_dev);
2415 } 2154 }
2416 } 2155 }
@@ -2421,7 +2160,7 @@ static void sd_dqcallback(struct gspca_dev *gspca_dev)
2421 struct sd *sd = (struct sd *) gspca_dev; 2160 struct sd *sd = (struct sd *) gspca_dev;
2422 int avg_lum; 2161 int avg_lum;
2423 2162
2424 if (!sd->auto_exposure) 2163 if (!sd->ctrls[AUTOGAIN].val)
2425 return; 2164 return;
2426 2165
2427 avg_lum = atomic_read(&sd->avg_lum); 2166 avg_lum = atomic_read(&sd->avg_lum);