diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-04 13:38:08 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-04 13:38:08 -0400 |
commit | f63b759c44b0561c76a67894c734157df3313b42 (patch) | |
tree | 4e9638f6c1aa5c0faa62ad4213282cc7cb39772a /drivers/media/video/gspca/t613.c | |
parent | 4a35cee066df1b1958e25e71595b3845d06b192e (diff) | |
parent | 844a9e93d7fcd910cd94f6eb262e2cc43cacbe56 (diff) |
Merge branch 'v4l_for_2.6.35' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6
* 'v4l_for_2.6.35' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (243 commits)
V4L/DVB: sms: Convert IR support to use the Remote Controller core
V4L/DVB: sms: properly initialize IR phys and IR name
V4L/DVB: standardize names at rc-dib0700 tables
V4L/DVB: smsusb: enable IR port for Hauppauge WinTV MiniStick
V4L/DVB: dib0700: Fix RC protocol logic to properly handle NEC/NECx and RC-5
V4L/DVB: dib0700: properly implement IR change_protocol
V4L/DVB: dib0700: break keytable into NEC and RC-5 variants
V4L/DVB: dib0700: avoid bad repeat
V4L/DVB: Port dib0700 to rc-core
V4L/DVB: Add a keymap file with dib0700 table
V4L/DVB: dvb-usb: add support for rc-core mode
V4L/DVB: dvb-usb: prepare drivers for using rc-core
V4L/DVB: dvb-usb: get rid of struct dvb_usb_rc_key
V4L/DVB: rj54n1cb0c: fix a comment in the driver
V4L/DVB: V4L2: sh_vou: VOU does support the full PAL resolution too
V4L/DVB: V4L2: sh_mobile_camera_ceu: add support for CSI2
V4L/DVB: V4L2: soc-camera: add a MIPI CSI-2 driver for SH-Mobile platforms
V4L/DVB: V4L2: soc-camera: export soc-camera bus type for notifications
V4L/DVB: V4L2: mediabus: add 12-bit Bayer and YUV420 pixel formats
V4L/DVB: mediabus: fix ambiguous pixel code names
...
Diffstat (limited to 'drivers/media/video/gspca/t613.c')
-rw-r--r-- | drivers/media/video/gspca/t613.c | 408 |
1 files changed, 217 insertions, 191 deletions
diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c index 63014372adbc..2a0f12d55e48 100644 --- a/drivers/media/video/gspca/t613.c +++ b/drivers/media/video/gspca/t613.c | |||
@@ -1,5 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> | 2 | * T613 subdriver |
3 | * | ||
4 | * Copyright (C) 2010 Jean-Francois Moine (http://moinejf.free.fr) | ||
3 | * | 5 | * |
4 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
5 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
@@ -26,6 +28,7 @@ | |||
26 | 28 | ||
27 | #define MODULE_NAME "t613" | 29 | #define MODULE_NAME "t613" |
28 | 30 | ||
31 | #include <linux/slab.h> | ||
29 | #include "gspca.h" | 32 | #include "gspca.h" |
30 | 33 | ||
31 | #define V4L2_CID_EFFECTS (V4L2_CID_PRIVATE_BASE + 0) | 34 | #define V4L2_CID_EFFECTS (V4L2_CID_PRIVATE_BASE + 0) |
@@ -44,18 +47,20 @@ struct sd { | |||
44 | u8 gamma; | 47 | u8 gamma; |
45 | u8 sharpness; | 48 | u8 sharpness; |
46 | u8 freq; | 49 | u8 freq; |
47 | u8 red_balance; /* split balance */ | 50 | u8 red_gain; |
48 | u8 blue_balance; | 51 | u8 blue_gain; |
49 | u8 global_gain; /* aka gain */ | 52 | u8 green_gain; |
50 | u8 whitebalance; /* set default r/g/b and activate */ | 53 | u8 awb; /* set default r/g/b and activate */ |
51 | u8 mirror; | 54 | u8 mirror; |
52 | u8 effect; | 55 | u8 effect; |
53 | 56 | ||
54 | u8 sensor; | 57 | u8 sensor; |
55 | #define SENSOR_OM6802 0 | 58 | enum { |
56 | #define SENSOR_OTHER 1 | 59 | SENSOR_OM6802, |
57 | #define SENSOR_TAS5130A 2 | 60 | SENSOR_OTHER, |
58 | #define SENSOR_LT168G 3 /* must verify if this is the actual model */ | 61 | SENSOR_TAS5130A, |
62 | SENSOR_LT168G, /* must verify if this is the actual model */ | ||
63 | } sensors; | ||
59 | }; | 64 | }; |
60 | 65 | ||
61 | /* V4L2 controls supported by the driver */ | 66 | /* V4L2 controls supported by the driver */ |
@@ -74,24 +79,22 @@ static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val); | |||
74 | static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); | 79 | static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); |
75 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); | 80 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); |
76 | 81 | ||
77 | 82 | static int sd_setawb(struct gspca_dev *gspca_dev, __s32 val); | |
78 | static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val); | 83 | static int sd_getawb(struct gspca_dev *gspca_dev, __s32 *val); |
79 | static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val); | 84 | static int sd_setblue_gain(struct gspca_dev *gspca_dev, __s32 val); |
80 | static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val); | 85 | static int sd_getblue_gain(struct gspca_dev *gspca_dev, __s32 *val); |
81 | static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val); | 86 | static int sd_setred_gain(struct gspca_dev *gspca_dev, __s32 val); |
82 | static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val); | 87 | static int sd_getred_gain(struct gspca_dev *gspca_dev, __s32 *val); |
83 | static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val); | 88 | static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val); |
84 | static int sd_setglobal_gain(struct gspca_dev *gspca_dev, __s32 val); | 89 | static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val); |
85 | static int sd_getglobal_gain(struct gspca_dev *gspca_dev, __s32 *val); | 90 | |
86 | 91 | static int sd_setmirror(struct gspca_dev *gspca_dev, __s32 val); | |
87 | static int sd_setflip(struct gspca_dev *gspca_dev, __s32 val); | 92 | static int sd_getmirror(struct gspca_dev *gspca_dev, __s32 *val); |
88 | static int sd_getflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
89 | static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val); | 93 | static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val); |
90 | static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val); | 94 | static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val); |
91 | static int sd_querymenu(struct gspca_dev *gspca_dev, | 95 | static int sd_querymenu(struct gspca_dev *gspca_dev, |
92 | struct v4l2_querymenu *menu); | 96 | struct v4l2_querymenu *menu); |
93 | 97 | ||
94 | |||
95 | static const struct ctrl sd_ctrls[] = { | 98 | static const struct ctrl sd_ctrls[] = { |
96 | { | 99 | { |
97 | { | 100 | { |
@@ -177,8 +180,8 @@ static const struct ctrl sd_ctrls[] = { | |||
177 | #define MIRROR_DEF 0 | 180 | #define MIRROR_DEF 0 |
178 | .default_value = MIRROR_DEF, | 181 | .default_value = MIRROR_DEF, |
179 | }, | 182 | }, |
180 | .set = sd_setflip, | 183 | .set = sd_setmirror, |
181 | .get = sd_getflip | 184 | .get = sd_getmirror |
182 | }, | 185 | }, |
183 | { | 186 | { |
184 | { | 187 | { |
@@ -198,15 +201,15 @@ static const struct ctrl sd_ctrls[] = { | |||
198 | { | 201 | { |
199 | .id = V4L2_CID_AUTO_WHITE_BALANCE, | 202 | .id = V4L2_CID_AUTO_WHITE_BALANCE, |
200 | .type = V4L2_CTRL_TYPE_INTEGER, | 203 | .type = V4L2_CTRL_TYPE_INTEGER, |
201 | .name = "White Balance", | 204 | .name = "Auto White Balance", |
202 | .minimum = 0, | 205 | .minimum = 0, |
203 | .maximum = 1, | 206 | .maximum = 1, |
204 | .step = 1, | 207 | .step = 1, |
205 | #define WHITE_BALANCE_DEF 0 | 208 | #define AWB_DEF 0 |
206 | .default_value = WHITE_BALANCE_DEF, | 209 | .default_value = AWB_DEF, |
207 | }, | 210 | }, |
208 | .set = sd_setwhitebalance, | 211 | .set = sd_setawb, |
209 | .get = sd_getwhitebalance | 212 | .get = sd_getawb |
210 | }, | 213 | }, |
211 | { | 214 | { |
212 | { | 215 | { |
@@ -244,11 +247,11 @@ static const struct ctrl sd_ctrls[] = { | |||
244 | .minimum = 0x10, | 247 | .minimum = 0x10, |
245 | .maximum = 0x40, | 248 | .maximum = 0x40, |
246 | .step = 1, | 249 | .step = 1, |
247 | #define BLUE_BALANCE_DEF 0x20 | 250 | #define BLUE_GAIN_DEF 0x20 |
248 | .default_value = BLUE_BALANCE_DEF, | 251 | .default_value = BLUE_GAIN_DEF, |
249 | }, | 252 | }, |
250 | .set = sd_setblue_balance, | 253 | .set = sd_setblue_gain, |
251 | .get = sd_getblue_balance, | 254 | .get = sd_getblue_gain, |
252 | }, | 255 | }, |
253 | { | 256 | { |
254 | { | 257 | { |
@@ -258,11 +261,11 @@ static const struct ctrl sd_ctrls[] = { | |||
258 | .minimum = 0x10, | 261 | .minimum = 0x10, |
259 | .maximum = 0x40, | 262 | .maximum = 0x40, |
260 | .step = 1, | 263 | .step = 1, |
261 | #define RED_BALANCE_DEF 0x20 | 264 | #define RED_GAIN_DEF 0x20 |
262 | .default_value = RED_BALANCE_DEF, | 265 | .default_value = RED_GAIN_DEF, |
263 | }, | 266 | }, |
264 | .set = sd_setred_balance, | 267 | .set = sd_setred_gain, |
265 | .get = sd_getred_balance, | 268 | .get = sd_getred_gain, |
266 | }, | 269 | }, |
267 | { | 270 | { |
268 | { | 271 | { |
@@ -272,24 +275,14 @@ static const struct ctrl sd_ctrls[] = { | |||
272 | .minimum = 0x10, | 275 | .minimum = 0x10, |
273 | .maximum = 0x40, | 276 | .maximum = 0x40, |
274 | .step = 1, | 277 | .step = 1, |
275 | #define global_gain_DEF 0x20 | 278 | #define GAIN_DEF 0x20 |
276 | .default_value = global_gain_DEF, | 279 | .default_value = GAIN_DEF, |
277 | }, | 280 | }, |
278 | .set = sd_setglobal_gain, | 281 | .set = sd_setgain, |
279 | .get = sd_getglobal_gain, | 282 | .get = sd_getgain, |
280 | }, | 283 | }, |
281 | }; | 284 | }; |
282 | 285 | ||
283 | static char *effects_control[] = { | ||
284 | "Normal", | ||
285 | "Emboss", /* disabled */ | ||
286 | "Monochrome", | ||
287 | "Sepia", | ||
288 | "Sketch", | ||
289 | "Sun Effect", /* disabled */ | ||
290 | "Negative", | ||
291 | }; | ||
292 | |||
293 | static const struct v4l2_pix_format vga_mode_t16[] = { | 286 | static const struct v4l2_pix_format vga_mode_t16[] = { |
294 | {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | 287 | {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, |
295 | .bytesperline = 160, | 288 | .bytesperline = 160, |
@@ -327,7 +320,6 @@ struct additional_sensor_data { | |||
327 | const u8 data1[10]; | 320 | const u8 data1[10]; |
328 | const u8 data2[9]; | 321 | const u8 data2[9]; |
329 | const u8 data3[9]; | 322 | const u8 data3[9]; |
330 | const u8 data4[4]; | ||
331 | const u8 data5[6]; | 323 | const u8 data5[6]; |
332 | const u8 stream[4]; | 324 | const u8 stream[4]; |
333 | }; | 325 | }; |
@@ -375,7 +367,7 @@ static const u8 n4_lt168g[] = { | |||
375 | }; | 367 | }; |
376 | 368 | ||
377 | static const struct additional_sensor_data sensor_data[] = { | 369 | static const struct additional_sensor_data sensor_data[] = { |
378 | { /* 0: OM6802 */ | 370 | [SENSOR_OM6802] = { |
379 | .n3 = | 371 | .n3 = |
380 | {0x61, 0x68, 0x65, 0x0a, 0x60, 0x04}, | 372 | {0x61, 0x68, 0x65, 0x0a, 0x60, 0x04}, |
381 | .n4 = n4_om6802, | 373 | .n4 = n4_om6802, |
@@ -392,14 +384,12 @@ static const struct additional_sensor_data sensor_data[] = { | |||
392 | .data3 = | 384 | .data3 = |
393 | {0x80, 0xff, 0xff, 0x80, 0xff, 0xff, 0x80, 0xff, | 385 | {0x80, 0xff, 0xff, 0x80, 0xff, 0xff, 0x80, 0xff, |
394 | 0xff}, | 386 | 0xff}, |
395 | .data4 = /*Freq (50/60Hz). Splitted for test purpose */ | ||
396 | {0x66, 0xca, 0xa8, 0xf0}, | ||
397 | .data5 = /* this could be removed later */ | 387 | .data5 = /* this could be removed later */ |
398 | {0x0c, 0x03, 0xab, 0x13, 0x81, 0x23}, | 388 | {0x0c, 0x03, 0xab, 0x13, 0x81, 0x23}, |
399 | .stream = | 389 | .stream = |
400 | {0x0b, 0x04, 0x0a, 0x78}, | 390 | {0x0b, 0x04, 0x0a, 0x78}, |
401 | }, | 391 | }, |
402 | { /* 1: OTHER */ | 392 | [SENSOR_OTHER] = { |
403 | .n3 = | 393 | .n3 = |
404 | {0x61, 0xc2, 0x65, 0x88, 0x60, 0x00}, | 394 | {0x61, 0xc2, 0x65, 0x88, 0x60, 0x00}, |
405 | .n4 = n4_other, | 395 | .n4 = n4_other, |
@@ -416,14 +406,12 @@ static const struct additional_sensor_data sensor_data[] = { | |||
416 | .data3 = | 406 | .data3 = |
417 | {0x4e, 0x9c, 0xec, 0x40, 0x80, 0xc0, 0x48, 0x96, | 407 | {0x4e, 0x9c, 0xec, 0x40, 0x80, 0xc0, 0x48, 0x96, |
418 | 0xd9}, | 408 | 0xd9}, |
419 | .data4 = | ||
420 | {0x66, 0x00, 0xa8, 0xa8}, | ||
421 | .data5 = | 409 | .data5 = |
422 | {0x0c, 0x03, 0xab, 0x29, 0x81, 0x69}, | 410 | {0x0c, 0x03, 0xab, 0x29, 0x81, 0x69}, |
423 | .stream = | 411 | .stream = |
424 | {0x0b, 0x04, 0x0a, 0x00}, | 412 | {0x0b, 0x04, 0x0a, 0x00}, |
425 | }, | 413 | }, |
426 | { /* 2: TAS5130A */ | 414 | [SENSOR_TAS5130A] = { |
427 | .n3 = | 415 | .n3 = |
428 | {0x61, 0xc2, 0x65, 0x0d, 0x60, 0x08}, | 416 | {0x61, 0xc2, 0x65, 0x0d, 0x60, 0x08}, |
429 | .n4 = n4_tas5130a, | 417 | .n4 = n4_tas5130a, |
@@ -440,14 +428,12 @@ static const struct additional_sensor_data sensor_data[] = { | |||
440 | .data3 = | 428 | .data3 = |
441 | {0x60, 0xa8, 0xe0, 0x60, 0xa8, 0xe0, 0x60, 0xa8, | 429 | {0x60, 0xa8, 0xe0, 0x60, 0xa8, 0xe0, 0x60, 0xa8, |
442 | 0xe0}, | 430 | 0xe0}, |
443 | .data4 = /* Freq (50/60Hz). Splitted for test purpose */ | ||
444 | {0x66, 0x00, 0xa8, 0xe8}, | ||
445 | .data5 = | 431 | .data5 = |
446 | {0x0c, 0x03, 0xab, 0x10, 0x81, 0x20}, | 432 | {0x0c, 0x03, 0xab, 0x10, 0x81, 0x20}, |
447 | .stream = | 433 | .stream = |
448 | {0x0b, 0x04, 0x0a, 0x40}, | 434 | {0x0b, 0x04, 0x0a, 0x40}, |
449 | }, | 435 | }, |
450 | { /* 3: LT168G */ | 436 | [SENSOR_LT168G] = { |
451 | .n3 = {0x61, 0xc2, 0x65, 0x68, 0x60, 0x00}, | 437 | .n3 = {0x61, 0xc2, 0x65, 0x68, 0x60, 0x00}, |
452 | .n4 = n4_lt168g, | 438 | .n4 = n4_lt168g, |
453 | .n4sz = sizeof n4_lt168g, | 439 | .n4sz = sizeof n4_lt168g, |
@@ -460,7 +446,6 @@ static const struct additional_sensor_data sensor_data[] = { | |||
460 | 0xff}, | 446 | 0xff}, |
461 | .data3 = {0x40, 0x80, 0xc0, 0x50, 0xa0, 0xf0, 0x53, 0xa6, | 447 | .data3 = {0x40, 0x80, 0xc0, 0x50, 0xa0, 0xf0, 0x53, 0xa6, |
462 | 0xff}, | 448 | 0xff}, |
463 | .data4 = {0x66, 0x41, 0xa8, 0xf0}, | ||
464 | .data5 = {0x0c, 0x03, 0xab, 0x4b, 0x81, 0x2b}, | 449 | .data5 = {0x0c, 0x03, 0xab, 0x4b, 0x81, 0x2b}, |
465 | .stream = {0x0b, 0x04, 0x0a, 0x28}, | 450 | .stream = {0x0b, 0x04, 0x0a, 0x28}, |
466 | }, | 451 | }, |
@@ -469,6 +454,15 @@ static const struct additional_sensor_data sensor_data[] = { | |||
469 | #define MAX_EFFECTS 7 | 454 | #define MAX_EFFECTS 7 |
470 | /* easily done by soft, this table could be removed, | 455 | /* easily done by soft, this table could be removed, |
471 | * i keep it here just in case */ | 456 | * i keep it here just in case */ |
457 | static char *effects_control[MAX_EFFECTS] = { | ||
458 | "Normal", | ||
459 | "Emboss", /* disabled */ | ||
460 | "Monochrome", | ||
461 | "Sepia", | ||
462 | "Sketch", | ||
463 | "Sun Effect", /* disabled */ | ||
464 | "Negative", | ||
465 | }; | ||
472 | static const u8 effects_table[MAX_EFFECTS][6] = { | 466 | static const u8 effects_table[MAX_EFFECTS][6] = { |
473 | {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x00}, /* Normal */ | 467 | {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x00}, /* Normal */ |
474 | {0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x04}, /* Repujar */ | 468 | {0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x04}, /* Repujar */ |
@@ -480,40 +474,41 @@ static const u8 effects_table[MAX_EFFECTS][6] = { | |||
480 | }; | 474 | }; |
481 | 475 | ||
482 | static const u8 gamma_table[GAMMA_MAX][17] = { | 476 | static const u8 gamma_table[GAMMA_MAX][17] = { |
483 | {0x00, 0x3e, 0x69, 0x85, 0x95, 0xa1, 0xae, 0xb9, /* 0 */ | 477 | /* gamma table from cam1690.ini */ |
484 | 0xc2, 0xcb, 0xd4, 0xdb, 0xe3, 0xea, 0xf1, 0xf8, | 478 | {0x00, 0x00, 0x01, 0x04, 0x08, 0x0e, 0x16, 0x21, /* 0 */ |
479 | 0x2e, 0x3d, 0x50, 0x65, 0x7d, 0x99, 0xb8, 0xdb, | ||
485 | 0xff}, | 480 | 0xff}, |
486 | {0x00, 0x33, 0x5a, 0x75, 0x85, 0x93, 0xa1, 0xad, /* 1 */ | 481 | {0x00, 0x01, 0x03, 0x08, 0x0e, 0x16, 0x21, 0x2d, /* 1 */ |
487 | 0xb7, 0xc2, 0xcb, 0xd4, 0xde, 0xe7, 0xf0, 0xf7, | 482 | 0x3c, 0x4d, 0x60, 0x75, 0x8d, 0xa6, 0xc2, 0xe1, |
488 | 0xff}, | 483 | 0xff}, |
489 | {0x00, 0x2f, 0x51, 0x6b, 0x7c, 0x8a, 0x99, 0xa6, /* 2 */ | 484 | {0x00, 0x01, 0x05, 0x0b, 0x12, 0x1c, 0x28, 0x35, /* 2 */ |
490 | 0xb1, 0xbc, 0xc6, 0xd0, 0xdb, 0xe4, 0xed, 0xf6, | 485 | 0x45, 0x56, 0x69, 0x7e, 0x95, 0xad, 0xc7, 0xe3, |
491 | 0xff}, | 486 | 0xff}, |
492 | {0x00, 0x29, 0x48, 0x60, 0x72, 0x81, 0x90, 0x9e, /* 3 */ | 487 | {0x00, 0x02, 0x07, 0x0f, 0x18, 0x24, 0x30, 0x3f, /* 3 */ |
493 | 0xaa, 0xb5, 0xbf, 0xcb, 0xd6, 0xe1, 0xeb, 0xf5, | 488 | 0x4f, 0x61, 0x73, 0x88, 0x9d, 0xb4, 0xcd, 0xe6, |
494 | 0xff}, | 489 | 0xff}, |
495 | {0x00, 0x23, 0x3f, 0x55, 0x68, 0x77, 0x86, 0x95, /* 4 */ | 490 | {0x00, 0x04, 0x0B, 0x15, 0x20, 0x2d, 0x3b, 0x4a, /* 4 */ |
496 | 0xa2, 0xad, 0xb9, 0xc6, 0xd2, 0xde, 0xe9, 0xf4, | 491 | 0x5b, 0x6c, 0x7f, 0x92, 0xa7, 0xbc, 0xd2, 0xe9, |
497 | 0xff}, | 492 | 0xff}, |
498 | {0x00, 0x1b, 0x33, 0x48, 0x59, 0x69, 0x79, 0x87, /* 5 */ | 493 | {0x00, 0x07, 0x11, 0x15, 0x20, 0x2d, 0x48, 0x58, /* 5 */ |
499 | 0x96, 0xa3, 0xb1, 0xbe, 0xcc, 0xda, 0xe7, 0xf3, | 494 | 0x68, 0x79, 0x8b, 0x9d, 0xb0, 0xc4, 0xd7, 0xec, |
500 | 0xff}, | 495 | 0xff}, |
501 | {0x00, 0x02, 0x10, 0x20, 0x32, 0x40, 0x57, 0x67, /* 6 */ | 496 | {0x00, 0x0c, 0x1a, 0x29, 0x38, 0x47, 0x57, 0x67, /* 6 */ |
502 | 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, | 497 | 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, |
503 | 0xff}, | 498 | 0xff}, |
504 | {0x00, 0x02, 0x14, 0x26, 0x38, 0x4a, 0x60, 0x70, /* 7 */ | 499 | {0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, /* 7 */ |
505 | 0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0, | 500 | 0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0, |
506 | 0xff}, | 501 | 0xff}, |
507 | {0x00, 0x10, 0x22, 0x35, 0x47, 0x5a, 0x69, 0x79, /* 8 */ | 502 | {0x00, 0x15, 0x27, 0x38, 0x49, 0x59, 0x69, 0x79, /* 8 */ |
508 | 0x88, 0x97, 0xa7, 0xb6, 0xc4, 0xd3, 0xe0, 0xf0, | 503 | 0x88, 0x97, 0xa7, 0xb6, 0xc4, 0xd3, 0xe2, 0xf0, |
509 | 0xff}, | 504 | 0xff}, |
510 | {0x00, 0x10, 0x26, 0x40, 0x54, 0x65, 0x75, 0x84, /* 9 */ | 505 | {0x00, 0x1c, 0x30, 0x43, 0x54, 0x65, 0x75, 0x84, /* 9 */ |
511 | 0x93, 0xa1, 0xb0, 0xbd, 0xca, 0xd6, 0xe0, 0xf0, | 506 | 0x93, 0xa1, 0xb0, 0xbd, 0xca, 0xd8, 0xe5, 0xf2, |
512 | 0xff}, | 507 | 0xff}, |
513 | {0x00, 0x18, 0x2b, 0x44, 0x60, 0x70, 0x80, 0x8e, /* 10 */ | 508 | {0x00, 0x24, 0x3b, 0x4f, 0x60, 0x70, 0x80, 0x8e, /* 10 */ |
514 | 0x9c, 0xaa, 0xb7, 0xc4, 0xd0, 0xd8, 0xe2, 0xf0, | 509 | 0x9c, 0xaa, 0xb7, 0xc4, 0xd0, 0xdc, 0xe8, 0xf3, |
515 | 0xff}, | 510 | 0xff}, |
516 | {0x00, 0x1a, 0x34, 0x52, 0x66, 0x7e, 0x8d, 0x9b, /* 11 */ | 511 | {0x00, 0x2a, 0x3c, 0x5d, 0x6e, 0x7e, 0x8d, 0x9b, /* 11 */ |
517 | 0xa8, 0xb4, 0xc0, 0xcb, 0xd6, 0xe1, 0xeb, 0xf5, | 512 | 0xa8, 0xb4, 0xc0, 0xcb, 0xd6, 0xe1, 0xeb, 0xf5, |
518 | 0xff}, | 513 | 0xff}, |
519 | {0x00, 0x3f, 0x5a, 0x6e, 0x7f, 0x8e, 0x9c, 0xa8, /* 12 */ | 514 | {0x00, 0x3f, 0x5a, 0x6e, 0x7f, 0x8e, 0x9c, 0xa8, /* 12 */ |
@@ -577,12 +572,11 @@ static void reg_w_buf(struct gspca_dev *gspca_dev, | |||
577 | } else { | 572 | } else { |
578 | u8 *tmpbuf; | 573 | u8 *tmpbuf; |
579 | 574 | ||
580 | tmpbuf = kmalloc(len, GFP_KERNEL); | 575 | tmpbuf = kmemdup(buffer, len, GFP_KERNEL); |
581 | if (!tmpbuf) { | 576 | if (!tmpbuf) { |
582 | err("Out of memory"); | 577 | err("Out of memory"); |
583 | return; | 578 | return; |
584 | } | 579 | } |
585 | memcpy(tmpbuf, buffer, len); | ||
586 | usb_control_msg(gspca_dev->dev, | 580 | usb_control_msg(gspca_dev->dev, |
587 | usb_sndctrlpipe(gspca_dev->dev, 0), | 581 | usb_sndctrlpipe(gspca_dev->dev, 0), |
588 | 0, | 582 | 0, |
@@ -625,7 +619,6 @@ static void reg_w_ixbuf(struct gspca_dev *gspca_dev, | |||
625 | kfree(tmpbuf); | 619 | kfree(tmpbuf); |
626 | } | 620 | } |
627 | 621 | ||
628 | /* Reported as OM6802*/ | ||
629 | static void om6802_sensor_init(struct gspca_dev *gspca_dev) | 622 | static void om6802_sensor_init(struct gspca_dev *gspca_dev) |
630 | { | 623 | { |
631 | int i; | 624 | int i; |
@@ -703,12 +696,12 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
703 | sd->autogain = AUTOGAIN_DEF; | 696 | sd->autogain = AUTOGAIN_DEF; |
704 | sd->mirror = MIRROR_DEF; | 697 | sd->mirror = MIRROR_DEF; |
705 | sd->freq = FREQ_DEF; | 698 | sd->freq = FREQ_DEF; |
706 | sd->whitebalance = WHITE_BALANCE_DEF; | 699 | sd->awb = AWB_DEF; |
707 | sd->sharpness = SHARPNESS_DEF; | 700 | sd->sharpness = SHARPNESS_DEF; |
708 | sd->effect = EFFECTS_DEF; | 701 | sd->effect = EFFECTS_DEF; |
709 | sd->red_balance = RED_BALANCE_DEF; | 702 | sd->red_gain = RED_GAIN_DEF; |
710 | sd->blue_balance = BLUE_BALANCE_DEF; | 703 | sd->blue_gain = BLUE_GAIN_DEF; |
711 | sd->global_gain = global_gain_DEF; | 704 | sd->green_gain = GAIN_DEF * 3 - RED_GAIN_DEF - BLUE_GAIN_DEF; |
712 | 705 | ||
713 | return 0; | 706 | return 0; |
714 | } | 707 | } |
@@ -761,40 +754,59 @@ static void setgamma(struct gspca_dev *gspca_dev) | |||
761 | reg_w_ixbuf(gspca_dev, 0x90, | 754 | reg_w_ixbuf(gspca_dev, 0x90, |
762 | gamma_table[sd->gamma], sizeof gamma_table[0]); | 755 | gamma_table[sd->gamma], sizeof gamma_table[0]); |
763 | } | 756 | } |
764 | static void setglobalgain(struct gspca_dev *gspca_dev) | ||
765 | { | ||
766 | 757 | ||
758 | static void setRGB(struct gspca_dev *gspca_dev) | ||
759 | { | ||
767 | struct sd *sd = (struct sd *) gspca_dev; | 760 | struct sd *sd = (struct sd *) gspca_dev; |
768 | reg_w(gspca_dev, (sd->red_balance << 8) + 0x87); | 761 | u8 all_gain_reg[6] = |
769 | reg_w(gspca_dev, (sd->blue_balance << 8) + 0x88); | 762 | {0x87, 0x00, 0x88, 0x00, 0x89, 0x00}; |
770 | reg_w(gspca_dev, (sd->global_gain << 8) + 0x89); | 763 | |
764 | all_gain_reg[1] = sd->red_gain; | ||
765 | all_gain_reg[3] = sd->blue_gain; | ||
766 | all_gain_reg[5] = sd->green_gain; | ||
767 | reg_w_buf(gspca_dev, all_gain_reg, sizeof all_gain_reg); | ||
771 | } | 768 | } |
772 | 769 | ||
773 | /* Generic fnc for r/b balance, exposure and whitebalance */ | 770 | /* Generic fnc for r/b balance, exposure and awb */ |
774 | static void setbalance(struct gspca_dev *gspca_dev) | 771 | static void setawb(struct gspca_dev *gspca_dev) |
775 | { | 772 | { |
776 | struct sd *sd = (struct sd *) gspca_dev; | 773 | struct sd *sd = (struct sd *) gspca_dev; |
774 | u16 reg80; | ||
777 | 775 | ||
778 | /* on whitebalance leave defaults values */ | 776 | reg80 = (sensor_data[sd->sensor].reg80 << 8) | 0x80; |
779 | if (sd->whitebalance) { | 777 | |
780 | reg_w(gspca_dev, 0x3c80); | 778 | /* on awb leave defaults values */ |
781 | } else { | 779 | if (!sd->awb) { |
782 | reg_w(gspca_dev, 0x3880); | ||
783 | /* shoud we wait here.. */ | 780 | /* shoud we wait here.. */ |
784 | /* update and reset 'global gain' with webcam parameters */ | 781 | /* update and reset RGB gains with webcam values */ |
785 | sd->red_balance = reg_r(gspca_dev, 0x0087); | 782 | sd->red_gain = reg_r(gspca_dev, 0x0087); |
786 | sd->blue_balance = reg_r(gspca_dev, 0x0088); | 783 | sd->blue_gain = reg_r(gspca_dev, 0x0088); |
787 | sd->global_gain = reg_r(gspca_dev, 0x0089); | 784 | sd->green_gain = reg_r(gspca_dev, 0x0089); |
788 | setglobalgain(gspca_dev); | 785 | reg80 &= ~0x0400; /* AWB off */ |
789 | } | 786 | } |
790 | 787 | reg_w(gspca_dev, reg80); | |
788 | reg_w(gspca_dev, reg80); | ||
791 | } | 789 | } |
792 | 790 | ||
793 | 791 | static void init_gains(struct gspca_dev *gspca_dev) | |
794 | |||
795 | static void setwhitebalance(struct gspca_dev *gspca_dev) | ||
796 | { | 792 | { |
797 | setbalance(gspca_dev); | 793 | struct sd *sd = (struct sd *) gspca_dev; |
794 | u16 reg80; | ||
795 | u8 all_gain_reg[8] = | ||
796 | {0x87, 0x00, 0x88, 0x00, 0x89, 0x00, 0x80, 0x00}; | ||
797 | |||
798 | all_gain_reg[1] = sd->red_gain; | ||
799 | all_gain_reg[3] = sd->blue_gain; | ||
800 | all_gain_reg[5] = sd->green_gain; | ||
801 | reg80 = sensor_data[sd->sensor].reg80; | ||
802 | if (!sd->awb) | ||
803 | reg80 &= ~0x04; | ||
804 | all_gain_reg[7] = reg80; | ||
805 | reg_w_buf(gspca_dev, all_gain_reg, sizeof all_gain_reg); | ||
806 | |||
807 | reg_w(gspca_dev, (sd->red_gain << 8) + 0x87); | ||
808 | reg_w(gspca_dev, (sd->blue_gain << 8) + 0x88); | ||
809 | reg_w(gspca_dev, (sd->green_gain << 8) + 0x89); | ||
798 | } | 810 | } |
799 | 811 | ||
800 | static void setsharpness(struct gspca_dev *gspca_dev) | 812 | static void setsharpness(struct gspca_dev *gspca_dev) |
@@ -807,6 +819,38 @@ static void setsharpness(struct gspca_dev *gspca_dev) | |||
807 | reg_w(gspca_dev, reg_to_write); | 819 | reg_w(gspca_dev, reg_to_write); |
808 | } | 820 | } |
809 | 821 | ||
822 | static void setfreq(struct gspca_dev *gspca_dev) | ||
823 | { | ||
824 | struct sd *sd = (struct sd *) gspca_dev; | ||
825 | u8 reg66; | ||
826 | u8 freq[4] = { 0x66, 0x00, 0xa8, 0xe8 }; | ||
827 | |||
828 | switch (sd->sensor) { | ||
829 | case SENSOR_LT168G: | ||
830 | if (sd->freq != 0) | ||
831 | freq[3] = 0xa8; | ||
832 | reg66 = 0x41; | ||
833 | break; | ||
834 | case SENSOR_OM6802: | ||
835 | reg66 = 0xca; | ||
836 | break; | ||
837 | default: | ||
838 | reg66 = 0x40; | ||
839 | break; | ||
840 | } | ||
841 | switch (sd->freq) { | ||
842 | case 0: /* no flicker */ | ||
843 | freq[3] = 0xf0; | ||
844 | break; | ||
845 | case 2: /* 60Hz */ | ||
846 | reg66 &= ~0x40; | ||
847 | break; | ||
848 | } | ||
849 | freq[1] = reg66; | ||
850 | |||
851 | reg_w_buf(gspca_dev, freq, sizeof freq); | ||
852 | } | ||
853 | |||
810 | /* this function is called at probe and resume time */ | 854 | /* this function is called at probe and resume time */ |
811 | static int sd_init(struct gspca_dev *gspca_dev) | 855 | static int sd_init(struct gspca_dev *gspca_dev) |
812 | { | 856 | { |
@@ -901,13 +945,9 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
901 | setgamma(gspca_dev); | 945 | setgamma(gspca_dev); |
902 | setcolors(gspca_dev); | 946 | setcolors(gspca_dev); |
903 | setsharpness(gspca_dev); | 947 | setsharpness(gspca_dev); |
904 | setwhitebalance(gspca_dev); | 948 | init_gains(gspca_dev); |
905 | 949 | setfreq(gspca_dev); | |
906 | reg_w(gspca_dev, 0x2087); /* tied to white balance? */ | ||
907 | reg_w(gspca_dev, 0x2088); | ||
908 | reg_w(gspca_dev, 0x2089); | ||
909 | 950 | ||
910 | reg_w_buf(gspca_dev, sensor->data4, sizeof sensor->data4); | ||
911 | reg_w_buf(gspca_dev, sensor->data5, sizeof sensor->data5); | 951 | reg_w_buf(gspca_dev, sensor->data5, sizeof sensor->data5); |
912 | reg_w_buf(gspca_dev, sensor->nset8, sizeof sensor->nset8); | 952 | reg_w_buf(gspca_dev, sensor->nset8, sizeof sensor->nset8); |
913 | reg_w_buf(gspca_dev, sensor->stream, sizeof sensor->stream); | 953 | reg_w_buf(gspca_dev, sensor->stream, sizeof sensor->stream); |
@@ -926,16 +966,16 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
926 | return 0; | 966 | return 0; |
927 | } | 967 | } |
928 | 968 | ||
929 | static void setflip(struct gspca_dev *gspca_dev) | 969 | static void setmirror(struct gspca_dev *gspca_dev) |
930 | { | 970 | { |
931 | struct sd *sd = (struct sd *) gspca_dev; | 971 | struct sd *sd = (struct sd *) gspca_dev; |
932 | u8 flipcmd[8] = | 972 | u8 hflipcmd[8] = |
933 | {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09}; | 973 | {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09}; |
934 | 974 | ||
935 | if (sd->mirror) | 975 | if (sd->mirror) |
936 | flipcmd[3] = 0x01; | 976 | hflipcmd[3] = 0x01; |
937 | 977 | ||
938 | reg_w_buf(gspca_dev, flipcmd, sizeof flipcmd); | 978 | reg_w_buf(gspca_dev, hflipcmd, sizeof hflipcmd); |
939 | } | 979 | } |
940 | 980 | ||
941 | static void seteffect(struct gspca_dev *gspca_dev) | 981 | static void seteffect(struct gspca_dev *gspca_dev) |
@@ -956,17 +996,6 @@ static void seteffect(struct gspca_dev *gspca_dev) | |||
956 | reg_w(gspca_dev, 0xfaa6); | 996 | reg_w(gspca_dev, 0xfaa6); |
957 | } | 997 | } |
958 | 998 | ||
959 | static void setlightfreq(struct gspca_dev *gspca_dev) | ||
960 | { | ||
961 | struct sd *sd = (struct sd *) gspca_dev; | ||
962 | u8 freq[4] = { 0x66, 0x40, 0xa8, 0xe8 }; | ||
963 | |||
964 | if (sd->freq == 2) /* 60hz */ | ||
965 | freq[1] = 0x00; | ||
966 | |||
967 | reg_w_buf(gspca_dev, freq, sizeof freq); | ||
968 | } | ||
969 | |||
970 | /* Is this really needed? | 999 | /* Is this really needed? |
971 | * i added some module parameters for test with some users */ | 1000 | * i added some module parameters for test with some users */ |
972 | static void poll_sensor(struct gspca_dev *gspca_dev) | 1001 | static void poll_sensor(struct gspca_dev *gspca_dev) |
@@ -979,9 +1008,7 @@ static void poll_sensor(struct gspca_dev *gspca_dev) | |||
979 | static const u8 poll2[] = | 1008 | static const u8 poll2[] = |
980 | {0x67, 0x02, 0x68, 0x71, 0x69, 0x72, 0x72, 0xa9, | 1009 | {0x67, 0x02, 0x68, 0x71, 0x69, 0x72, 0x72, 0xa9, |
981 | 0x73, 0x02, 0x73, 0x02, 0x60, 0x14}; | 1010 | 0x73, 0x02, 0x73, 0x02, 0x60, 0x14}; |
982 | static const u8 poll3[] = | 1011 | static const u8 noise03[] = /* (some differences / ms-drv) */ |
983 | {0x87, 0x3f, 0x88, 0x20, 0x89, 0x2d}; | ||
984 | static const u8 poll4[] = | ||
985 | {0xa6, 0x0a, 0xea, 0xcf, 0xbe, 0x26, 0xb1, 0x5f, | 1012 | {0xa6, 0x0a, 0xea, 0xcf, 0xbe, 0x26, 0xb1, 0x5f, |
986 | 0xa1, 0xb1, 0xda, 0x6b, 0xdb, 0x98, 0xdf, 0x0c, | 1013 | 0xa1, 0xb1, 0xda, 0x6b, 0xdb, 0x98, 0xdf, 0x0c, |
987 | 0xc2, 0x80, 0xc3, 0x10}; | 1014 | 0xc2, 0x80, 0xc3, 0x10}; |
@@ -989,8 +1016,7 @@ static void poll_sensor(struct gspca_dev *gspca_dev) | |||
989 | PDEBUG(D_STREAM, "[Sensor requires polling]"); | 1016 | PDEBUG(D_STREAM, "[Sensor requires polling]"); |
990 | reg_w_buf(gspca_dev, poll1, sizeof poll1); | 1017 | reg_w_buf(gspca_dev, poll1, sizeof poll1); |
991 | reg_w_buf(gspca_dev, poll2, sizeof poll2); | 1018 | reg_w_buf(gspca_dev, poll2, sizeof poll2); |
992 | reg_w_buf(gspca_dev, poll3, sizeof poll3); | 1019 | reg_w_buf(gspca_dev, noise03, sizeof noise03); |
993 | reg_w_buf(gspca_dev, poll4, sizeof poll4); | ||
994 | } | 1020 | } |
995 | 1021 | ||
996 | static int sd_start(struct gspca_dev *gspca_dev) | 1022 | static int sd_start(struct gspca_dev *gspca_dev) |
@@ -1025,12 +1051,7 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
1025 | case SENSOR_OM6802: | 1051 | case SENSOR_OM6802: |
1026 | om6802_sensor_init(gspca_dev); | 1052 | om6802_sensor_init(gspca_dev); |
1027 | break; | 1053 | break; |
1028 | case SENSOR_LT168G: | 1054 | case SENSOR_TAS5130A: |
1029 | break; | ||
1030 | case SENSOR_OTHER: | ||
1031 | break; | ||
1032 | default: | ||
1033 | /* case SENSOR_TAS5130A: */ | ||
1034 | i = 0; | 1055 | i = 0; |
1035 | for (;;) { | 1056 | for (;;) { |
1036 | reg_w_buf(gspca_dev, tas5130a_sensor_init[i], | 1057 | reg_w_buf(gspca_dev, tas5130a_sensor_init[i], |
@@ -1047,7 +1068,7 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
1047 | break; | 1068 | break; |
1048 | } | 1069 | } |
1049 | sensor = &sensor_data[sd->sensor]; | 1070 | sensor = &sensor_data[sd->sensor]; |
1050 | reg_w_buf(gspca_dev, sensor->data4, sizeof sensor->data4); | 1071 | setfreq(gspca_dev); |
1051 | reg_r(gspca_dev, 0x0012); | 1072 | reg_r(gspca_dev, 0x0012); |
1052 | reg_w_buf(gspca_dev, t2, sizeof t2); | 1073 | reg_w_buf(gspca_dev, t2, sizeof t2); |
1053 | reg_w_ixbuf(gspca_dev, 0xb3, t3, sizeof t3); | 1074 | reg_w_ixbuf(gspca_dev, 0xb3, t3, sizeof t3); |
@@ -1080,7 +1101,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
1080 | u8 *data, /* isoc packet */ | 1101 | u8 *data, /* isoc packet */ |
1081 | int len) /* iso packet length */ | 1102 | int len) /* iso packet length */ |
1082 | { | 1103 | { |
1083 | static u8 ffd9[] = { 0xff, 0xd9 }; | 1104 | int pkt_type; |
1084 | 1105 | ||
1085 | if (data[0] == 0x5a) { | 1106 | if (data[0] == 0x5a) { |
1086 | /* Control Packet, after this came the header again, | 1107 | /* Control Packet, after this came the header again, |
@@ -1090,84 +1111,88 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
1090 | } | 1111 | } |
1091 | data += 2; | 1112 | data += 2; |
1092 | len -= 2; | 1113 | len -= 2; |
1093 | if (data[0] == 0xff && data[1] == 0xd8) { | 1114 | if (data[0] == 0xff && data[1] == 0xd8) |
1094 | /* extra bytes....., could be processed too but would be | 1115 | pkt_type = FIRST_PACKET; |
1095 | * a waste of time, right now leave the application and | 1116 | else if (data[len - 2] == 0xff && data[len - 1] == 0xd9) |
1096 | * libjpeg do it for ourserlves.. */ | 1117 | pkt_type = LAST_PACKET; |
1097 | gspca_frame_add(gspca_dev, LAST_PACKET, | 1118 | else |
1098 | ffd9, 2); | 1119 | pkt_type = INTER_PACKET; |
1099 | gspca_frame_add(gspca_dev, FIRST_PACKET, data, len); | 1120 | gspca_frame_add(gspca_dev, pkt_type, data, len); |
1100 | return; | ||
1101 | } | ||
1102 | |||
1103 | if (data[len - 2] == 0xff && data[len - 1] == 0xd9) { | ||
1104 | /* Just in case, i have seen packets with the marker, | ||
1105 | * other's do not include it... */ | ||
1106 | len -= 2; | ||
1107 | } | ||
1108 | gspca_frame_add(gspca_dev, INTER_PACKET, data, len); | ||
1109 | } | 1121 | } |
1110 | 1122 | ||
1111 | 1123 | static int sd_setblue_gain(struct gspca_dev *gspca_dev, __s32 val) | |
1112 | static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val) | ||
1113 | { | 1124 | { |
1114 | struct sd *sd = (struct sd *) gspca_dev; | 1125 | struct sd *sd = (struct sd *) gspca_dev; |
1115 | 1126 | ||
1116 | sd->blue_balance = val; | 1127 | sd->blue_gain = val; |
1117 | if (gspca_dev->streaming) | 1128 | if (gspca_dev->streaming) |
1118 | reg_w(gspca_dev, (val << 8) + 0x88); | 1129 | reg_w(gspca_dev, (val << 8) + 0x88); |
1119 | return 0; | 1130 | return 0; |
1120 | } | 1131 | } |
1121 | 1132 | ||
1122 | static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val) | 1133 | static int sd_getblue_gain(struct gspca_dev *gspca_dev, __s32 *val) |
1123 | { | 1134 | { |
1124 | struct sd *sd = (struct sd *) gspca_dev; | 1135 | struct sd *sd = (struct sd *) gspca_dev; |
1125 | 1136 | ||
1126 | *val = sd->blue_balance; | 1137 | *val = sd->blue_gain; |
1127 | return 0; | 1138 | return 0; |
1128 | } | 1139 | } |
1129 | 1140 | ||
1130 | static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val) | 1141 | static int sd_setred_gain(struct gspca_dev *gspca_dev, __s32 val) |
1131 | { | 1142 | { |
1132 | struct sd *sd = (struct sd *) gspca_dev; | 1143 | struct sd *sd = (struct sd *) gspca_dev; |
1133 | 1144 | ||
1134 | sd->red_balance = val; | 1145 | sd->red_gain = val; |
1135 | if (gspca_dev->streaming) | 1146 | if (gspca_dev->streaming) |
1136 | reg_w(gspca_dev, (val << 8) + 0x87); | 1147 | reg_w(gspca_dev, (val << 8) + 0x87); |
1137 | 1148 | ||
1138 | return 0; | 1149 | return 0; |
1139 | } | 1150 | } |
1140 | 1151 | ||
1141 | static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val) | 1152 | static int sd_getred_gain(struct gspca_dev *gspca_dev, __s32 *val) |
1142 | { | 1153 | { |
1143 | struct sd *sd = (struct sd *) gspca_dev; | 1154 | struct sd *sd = (struct sd *) gspca_dev; |
1144 | 1155 | ||
1145 | *val = sd->red_balance; | 1156 | *val = sd->red_gain; |
1146 | return 0; | 1157 | return 0; |
1147 | } | 1158 | } |
1148 | 1159 | ||
1149 | 1160 | static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val) | |
1150 | |||
1151 | static int sd_setglobal_gain(struct gspca_dev *gspca_dev, __s32 val) | ||
1152 | { | 1161 | { |
1153 | struct sd *sd = (struct sd *) gspca_dev; | 1162 | struct sd *sd = (struct sd *) gspca_dev; |
1163 | u16 psg, nsg; | ||
1164 | |||
1165 | psg = sd->red_gain + sd->blue_gain + sd->green_gain; | ||
1166 | nsg = val * 3; | ||
1167 | sd->red_gain = sd->red_gain * nsg / psg; | ||
1168 | if (sd->red_gain > 0x40) | ||
1169 | sd->red_gain = 0x40; | ||
1170 | else if (sd->red_gain < 0x10) | ||
1171 | sd->red_gain = 0x10; | ||
1172 | sd->blue_gain = sd->blue_gain * nsg / psg; | ||
1173 | if (sd->blue_gain > 0x40) | ||
1174 | sd->blue_gain = 0x40; | ||
1175 | else if (sd->blue_gain < 0x10) | ||
1176 | sd->blue_gain = 0x10; | ||
1177 | sd->green_gain = sd->green_gain * nsg / psg; | ||
1178 | if (sd->green_gain > 0x40) | ||
1179 | sd->green_gain = 0x40; | ||
1180 | else if (sd->green_gain < 0x10) | ||
1181 | sd->green_gain = 0x10; | ||
1154 | 1182 | ||
1155 | sd->global_gain = val; | ||
1156 | if (gspca_dev->streaming) | 1183 | if (gspca_dev->streaming) |
1157 | setglobalgain(gspca_dev); | 1184 | setRGB(gspca_dev); |
1158 | |||
1159 | return 0; | 1185 | return 0; |
1160 | } | 1186 | } |
1161 | 1187 | ||
1162 | static int sd_getglobal_gain(struct gspca_dev *gspca_dev, __s32 *val) | 1188 | static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val) |
1163 | { | 1189 | { |
1164 | struct sd *sd = (struct sd *) gspca_dev; | 1190 | struct sd *sd = (struct sd *) gspca_dev; |
1165 | 1191 | ||
1166 | *val = sd->global_gain; | 1192 | *val = (sd->red_gain + sd->blue_gain + sd->green_gain) / 3; |
1167 | return 0; | 1193 | return 0; |
1168 | } | 1194 | } |
1169 | 1195 | ||
1170 | |||
1171 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | 1196 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) |
1172 | { | 1197 | { |
1173 | struct sd *sd = (struct sd *) gspca_dev; | 1198 | struct sd *sd = (struct sd *) gspca_dev; |
@@ -1186,35 +1211,35 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | |||
1186 | return *val; | 1211 | return *val; |
1187 | } | 1212 | } |
1188 | 1213 | ||
1189 | static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val) | 1214 | static int sd_setawb(struct gspca_dev *gspca_dev, __s32 val) |
1190 | { | 1215 | { |
1191 | struct sd *sd = (struct sd *) gspca_dev; | 1216 | struct sd *sd = (struct sd *) gspca_dev; |
1192 | 1217 | ||
1193 | sd->whitebalance = val; | 1218 | sd->awb = val; |
1194 | if (gspca_dev->streaming) | 1219 | if (gspca_dev->streaming) |
1195 | setwhitebalance(gspca_dev); | 1220 | setawb(gspca_dev); |
1196 | return 0; | 1221 | return 0; |
1197 | } | 1222 | } |
1198 | 1223 | ||
1199 | static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val) | 1224 | static int sd_getawb(struct gspca_dev *gspca_dev, __s32 *val) |
1200 | { | 1225 | { |
1201 | struct sd *sd = (struct sd *) gspca_dev; | 1226 | struct sd *sd = (struct sd *) gspca_dev; |
1202 | 1227 | ||
1203 | *val = sd->whitebalance; | 1228 | *val = sd->awb; |
1204 | return *val; | 1229 | return *val; |
1205 | } | 1230 | } |
1206 | 1231 | ||
1207 | static int sd_setflip(struct gspca_dev *gspca_dev, __s32 val) | 1232 | static int sd_setmirror(struct gspca_dev *gspca_dev, __s32 val) |
1208 | { | 1233 | { |
1209 | struct sd *sd = (struct sd *) gspca_dev; | 1234 | struct sd *sd = (struct sd *) gspca_dev; |
1210 | 1235 | ||
1211 | sd->mirror = val; | 1236 | sd->mirror = val; |
1212 | if (gspca_dev->streaming) | 1237 | if (gspca_dev->streaming) |
1213 | setflip(gspca_dev); | 1238 | setmirror(gspca_dev); |
1214 | return 0; | 1239 | return 0; |
1215 | } | 1240 | } |
1216 | 1241 | ||
1217 | static int sd_getflip(struct gspca_dev *gspca_dev, __s32 *val) | 1242 | static int sd_getmirror(struct gspca_dev *gspca_dev, __s32 *val) |
1218 | { | 1243 | { |
1219 | struct sd *sd = (struct sd *) gspca_dev; | 1244 | struct sd *sd = (struct sd *) gspca_dev; |
1220 | 1245 | ||
@@ -1300,7 +1325,7 @@ static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val) | |||
1300 | 1325 | ||
1301 | sd->freq = val; | 1326 | sd->freq = val; |
1302 | if (gspca_dev->streaming) | 1327 | if (gspca_dev->streaming) |
1303 | setlightfreq(gspca_dev); | 1328 | setfreq(gspca_dev); |
1304 | return 0; | 1329 | return 0; |
1305 | } | 1330 | } |
1306 | 1331 | ||
@@ -1368,7 +1393,8 @@ static int sd_querymenu(struct gspca_dev *gspca_dev, | |||
1368 | case V4L2_CID_EFFECTS: | 1393 | case V4L2_CID_EFFECTS: |
1369 | if ((unsigned) menu->index < ARRAY_SIZE(effects_control)) { | 1394 | if ((unsigned) menu->index < ARRAY_SIZE(effects_control)) { |
1370 | strncpy((char *) menu->name, | 1395 | strncpy((char *) menu->name, |
1371 | effects_control[menu->index], 32); | 1396 | effects_control[menu->index], |
1397 | sizeof menu->name); | ||
1372 | return 0; | 1398 | return 0; |
1373 | } | 1399 | } |
1374 | break; | 1400 | break; |