aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorJean-Francois Moine <moinejf@free.fr>2009-11-24 03:22:05 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-12-05 15:42:07 -0500
commitc22c4a20a6ac7b10e43eab6963f941795c5e92aa (patch)
treeecf7b92e15701785d6ceefc4d2ef0cf5bbb71049 /drivers/media
parentb8c8a5bf833db5ad80266a6a9e5ad496ab01d434 (diff)
V4L/DVB (13490): gspca - ov534: Add controls for sensor ov965x.
Signed-off-by: Jean-Francois Moine <moinejf@free.fr> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/video/gspca/ov534.c479
1 files changed, 407 insertions, 72 deletions
diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c
index 6817fccd6fd8..4dbb882c83dc 100644
--- a/drivers/media/video/gspca/ov534.c
+++ b/drivers/media/video/gspca/ov534.c
@@ -65,9 +65,11 @@ struct sd {
65 u8 hue; 65 u8 hue;
66 u8 autogain; 66 u8 autogain;
67 u8 awb; 67 u8 awb;
68 u8 sharpness; 68 s8 sharpness;
69 u8 hflip; 69 u8 hflip;
70 u8 vflip; 70 u8 vflip;
71 u8 satur;
72 u8 lightfreq;
71 73
72 u8 sensor; 74 u8 sensor;
73#define SENSOR_OV772X 0 75#define SENSOR_OV772X 0
@@ -99,6 +101,10 @@ static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
99static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); 101static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
100static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); 102static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
101static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); 103static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
104static int sd_setsatur(struct gspca_dev *gspca_dev, __s32 val);
105static int sd_getsatur(struct gspca_dev *gspca_dev, __s32 *val);
106static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
107static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
102 108
103static struct ctrl sd_ctrls_ov772x[] = { 109static struct ctrl sd_ctrls_ov772x[] = {
104 { /* 0 */ 110 { /* 0 */
@@ -109,8 +115,8 @@ static struct ctrl sd_ctrls_ov772x[] = {
109 .minimum = 0, 115 .minimum = 0,
110 .maximum = 255, 116 .maximum = 255,
111 .step = 1, 117 .step = 1,
112#define BRIGHTNESS_DEF 20 118#define BRIGHTNESS_77_DEF 20
113 .default_value = BRIGHTNESS_DEF, 119 .default_value = BRIGHTNESS_77_DEF,
114 }, 120 },
115 .set = sd_setbrightness, 121 .set = sd_setbrightness,
116 .get = sd_getbrightness, 122 .get = sd_getbrightness,
@@ -123,8 +129,8 @@ static struct ctrl sd_ctrls_ov772x[] = {
123 .minimum = 0, 129 .minimum = 0,
124 .maximum = 255, 130 .maximum = 255,
125 .step = 1, 131 .step = 1,
126#define CONTRAST_DEF 37 132#define CONTRAST_77_DEF 37
127 .default_value = CONTRAST_DEF, 133 .default_value = CONTRAST_77_DEF,
128 }, 134 },
129 .set = sd_setcontrast, 135 .set = sd_setcontrast,
130 .get = sd_getcontrast, 136 .get = sd_getcontrast,
@@ -151,8 +157,8 @@ static struct ctrl sd_ctrls_ov772x[] = {
151 .minimum = 0, 157 .minimum = 0,
152 .maximum = 255, 158 .maximum = 255,
153 .step = 1, 159 .step = 1,
154#define EXPO_DEF 120 160#define EXPO_77_DEF 120
155 .default_value = EXPO_DEF, 161 .default_value = EXPO_77_DEF,
156 }, 162 },
157 .set = sd_setexposure, 163 .set = sd_setexposure,
158 .get = sd_getexposure, 164 .get = sd_getexposure,
@@ -207,13 +213,13 @@ static struct ctrl sd_ctrls_ov772x[] = {
207 .minimum = 0, 213 .minimum = 0,
208 .maximum = 1, 214 .maximum = 1,
209 .step = 1, 215 .step = 1,
210#define AUTOGAIN_DEF 0 216#define AUTOGAIN_77_DEF 0
211 .default_value = AUTOGAIN_DEF, 217 .default_value = AUTOGAIN_77_DEF,
212 }, 218 },
213 .set = sd_setautogain, 219 .set = sd_setautogain,
214 .get = sd_getautogain, 220 .get = sd_getautogain,
215 }, 221 },
216#define AWB_IDX 8 222#define AWB_77_IDX 8
217 { /* 8 */ 223 { /* 8 */
218 { 224 {
219 .id = V4L2_CID_AUTO_WHITE_BALANCE, 225 .id = V4L2_CID_AUTO_WHITE_BALANCE,
@@ -236,8 +242,8 @@ static struct ctrl sd_ctrls_ov772x[] = {
236 .minimum = 0, 242 .minimum = 0,
237 .maximum = 63, 243 .maximum = 63,
238 .step = 1, 244 .step = 1,
239#define SHARPNESS_DEF 0 245#define SHARPNESS_77_DEF 0
240 .default_value = SHARPNESS_DEF, 246 .default_value = SHARPNESS_77_DEF,
241 }, 247 },
242 .set = sd_setsharpness, 248 .set = sd_setsharpness,
243 .get = sd_getsharpness, 249 .get = sd_getsharpness,
@@ -272,6 +278,105 @@ static struct ctrl sd_ctrls_ov772x[] = {
272 }, 278 },
273}; 279};
274static struct ctrl sd_ctrls_ov965x[] = { 280static struct ctrl sd_ctrls_ov965x[] = {
281 { /* 0 */
282 {
283 .id = V4L2_CID_BRIGHTNESS,
284 .type = V4L2_CTRL_TYPE_INTEGER,
285 .name = "Brightness",
286 .minimum = 0,
287 .maximum = 15,
288 .step = 1,
289#define BRIGHTNESS_96_DEF 7
290 .default_value = BRIGHTNESS_96_DEF,
291 },
292 .set = sd_setbrightness,
293 .get = sd_getbrightness,
294 },
295 { /* 1 */
296 {
297 .id = V4L2_CID_CONTRAST,
298 .type = V4L2_CTRL_TYPE_INTEGER,
299 .name = "Contrast",
300 .minimum = 0,
301 .maximum = 15,
302 .step = 1,
303#define CONTRAST_96_DEF 3
304 .default_value = CONTRAST_96_DEF,
305 },
306 .set = sd_setcontrast,
307 .get = sd_getcontrast,
308 },
309 { /* 2 */
310 {
311 .id = V4L2_CID_AUTOGAIN,
312 .type = V4L2_CTRL_TYPE_BOOLEAN,
313 .name = "Autogain",
314 .minimum = 0,
315 .maximum = 1,
316 .step = 1,
317#define AUTOGAIN_96_DEF 1
318 .default_value = AUTOGAIN_96_DEF,
319 },
320 .set = sd_setautogain,
321 .get = sd_getautogain,
322 },
323#define EXPO_96_IDX 3
324 { /* 3 */
325 {
326 .id = V4L2_CID_EXPOSURE,
327 .type = V4L2_CTRL_TYPE_INTEGER,
328 .name = "Exposure",
329 .minimum = 0,
330 .maximum = 3,
331 .step = 1,
332#define EXPO_96_DEF 0
333 .default_value = EXPO_96_DEF,
334 },
335 .set = sd_setexposure,
336 .get = sd_getexposure,
337 },
338 { /* 4 */
339 {
340 .id = V4L2_CID_SHARPNESS,
341 .type = V4L2_CTRL_TYPE_INTEGER,
342 .name = "Sharpness",
343 .minimum = -1, /* -1 = auto */
344 .maximum = 4,
345 .step = 1,
346#define SHARPNESS_96_DEF -1
347 .default_value = SHARPNESS_96_DEF,
348 },
349 .set = sd_setsharpness,
350 .get = sd_getsharpness,
351 },
352 { /* 5 */
353 {
354 .id = V4L2_CID_SATURATION,
355 .type = V4L2_CTRL_TYPE_INTEGER,
356 .name = "Saturation",
357 .minimum = 0,
358 .maximum = 4,
359 .step = 1,
360#define SATUR_DEF 2
361 .default_value = SATUR_DEF,
362 },
363 .set = sd_setsatur,
364 .get = sd_getsatur,
365 },
366 {
367 {
368 .id = V4L2_CID_POWER_LINE_FREQUENCY,
369 .type = V4L2_CTRL_TYPE_MENU,
370 .name = "Light frequency filter",
371 .minimum = 0,
372 .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
373 .step = 1,
374#define FREQ_DEF 0
375 .default_value = FREQ_DEF,
376 },
377 .set = sd_setfreq,
378 .get = sd_getfreq,
379 },
275}; 380};
276 381
277static const struct v4l2_pix_format ov772x_mode[] = { 382static const struct v4l2_pix_format ov772x_mode[] = {
@@ -314,6 +419,7 @@ static const struct v4l2_pix_format ov965x_mode[] = {
314 .colorspace = V4L2_COLORSPACE_JPEG, 419 .colorspace = V4L2_COLORSPACE_JPEG,
315 .priv = 0}, 420 .priv = 0},
316}; 421};
422
317static const u8 bridge_init_ov772x[][2] = { 423static const u8 bridge_init_ov772x[][2] = {
318 { 0xc2, 0x0c }, 424 { 0xc2, 0x0c },
319 { 0x88, 0xf8 }, 425 { 0x88, 0xf8 },
@@ -689,7 +795,7 @@ static const u8 sensor_init_ov965x[][2] = {
689 {0xcb, 0xf0}, 795 {0xcb, 0xf0},
690 {0xcc, 0xd8}, 796 {0xcc, 0xd8},
691 {0xcd, 0xf1}, 797 {0xcd, 0xf1},
692 {0x4f, 0x98}, 798 {0x4f, 0x98}, /* matrix */
693 {0x50, 0x98}, 799 {0x50, 0x98},
694 {0x51, 0x00}, 800 {0x51, 0x00},
695 {0x52, 0x28}, 801 {0x52, 0x28},
@@ -698,6 +804,7 @@ static const u8 sensor_init_ov965x[][2] = {
698 {0x58, 0x1a}, 804 {0x58, 0x1a},
699 {0xff, 0x41}, /* read 41, write ff 00 */ 805 {0xff, 0x41}, /* read 41, write ff 00 */
700 {0x41, 0x40}, /* com16 */ 806 {0x41, 0x40}, /* com16 */
807
701 {0xc5, 0x03}, /* 60 Hz banding filter */ 808 {0xc5, 0x03}, /* 60 Hz banding filter */
702 {0x6a, 0x02}, /* 50 Hz banding filter */ 809 {0x6a, 0x02}, /* 50 Hz banding filter */
703 810
@@ -741,8 +848,8 @@ static const u8 bridge_init_ov965x_2[][2] = {
741 {0x52, 0x3c}, 848 {0x52, 0x3c},
742 {0x53, 0x00}, 849 {0x53, 0x00},
743 {0x54, 0x00}, 850 {0x54, 0x00},
744 {0x55, 0x00}, /* brightness */ 851 {0x55, 0x00},
745 {0x57, 0x00}, /* contrast 2 */ 852 {0x57, 0x00},
746 {0x5c, 0x00}, 853 {0x5c, 0x00},
747 {0x5a, 0xa0}, 854 {0x5a, 0xa0},
748 {0x5b, 0x78}, 855 {0x5b, 0x78},
@@ -765,14 +872,16 @@ static const u8 sensor_init_ov965x_2[][2] = {
765 {0xa3, 0x3e}, 872 {0xa3, 0x3e},
766 {0x2d, 0x00}, 873 {0x2d, 0x00},
767 {0xff, 0x42}, /* read 42, write ff 00 */ 874 {0xff, 0x42}, /* read 42, write ff 00 */
768 {0x42, 0xc0}, 875 {0x42, 0xc0}, /* com17 */
769 {0x2d, 0x00}, 876 {0x2d, 0x00},
770 {0xff, 0x42}, /* read 42, write ff 00 */ 877 {0xff, 0x42}, /* read 42, write ff 00 */
771 {0x42, 0xc1}, 878 {0x42, 0xc1}, /* com17 */
879/* sharpness */
772 {0x3f, 0x01}, 880 {0x3f, 0x01},
773 {0xff, 0x42}, /* read 42, write ff 00 */ 881 {0xff, 0x42}, /* read 42, write ff 00 */
774 {0x42, 0xc1}, 882 {0x42, 0xc1}, /* com17 */
775 {0x4f, 0x98}, 883/* saturation */
884 {0x4f, 0x98}, /* matrix */
776 {0x50, 0x98}, 885 {0x50, 0x98},
777 {0x51, 0x00}, 886 {0x51, 0x00},
778 {0x52, 0x28}, 887 {0x52, 0x28},
@@ -781,8 +890,11 @@ static const u8 sensor_init_ov965x_2[][2] = {
781 {0x58, 0x1a}, 890 {0x58, 0x1a},
782 {0xff, 0x41}, /* read 41, write ff 00 */ 891 {0xff, 0x41}, /* read 41, write ff 00 */
783 {0x41, 0x40}, /* com16 */ 892 {0x41, 0x40}, /* com16 */
893/* contrast */
784 {0x56, 0x40}, 894 {0x56, 0x40},
895/* brightness */
785 {0x55, 0x8f}, 896 {0x55, 0x8f},
897/* expo */
786 {0x10, 0x25}, /* aech - exposure high bits */ 898 {0x10, 0x25}, /* aech - exposure high bits */
787 {0xff, 0x13}, /* read 13, write ff 00 */ 899 {0xff, 0x13}, /* read 13, write ff 00 */
788 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ 900 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
@@ -943,7 +1055,6 @@ static const u8 bridge_start_ov965x_svga[][2] = {
943 {0x8c, 0x00}, 1055 {0x8c, 0x00},
944 {0x8d, 0x1c}, 1056 {0x8d, 0x1c},
945 {0x34, 0x05}, 1057 {0x34, 0x05},
946
947 {0xc2, 0x4c}, 1058 {0xc2, 0x4c},
948 {0xc3, 0xf9}, 1059 {0xc3, 0xf9},
949 {0x50, 0x00}, 1060 {0x50, 0x00},
@@ -1052,7 +1163,6 @@ static const u8 sensor_start_ov965x_2_svga[][2] = { /* same for xga */
1052 {0xc5, 0x0f}, /* 60 Hz banding filter */ 1163 {0xc5, 0x0f}, /* 60 Hz banding filter */
1053 {0xa2, 0x4e}, /* bd50 */ 1164 {0xa2, 0x4e}, /* bd50 */
1054 {0xa3, 0x41}, /* bd60 */ 1165 {0xa3, 0x41}, /* bd60 */
1055 {0x2d, 0x00}, /* advfl */
1056}; 1166};
1057 1167
1058static const u8 sensor_start_ov965x_2_sxga[][2] = { 1168static const u8 sensor_start_ov965x_2_sxga[][2] = {
@@ -1067,15 +1177,8 @@ static const u8 sensor_start_ov965x_2_sxga[][2] = {
1067 {0xc5, 0x0f}, /* 60 Hz banding filter */ 1177 {0xc5, 0x0f}, /* 60 Hz banding filter */
1068 {0xa2, 0x4e}, /* bd50 */ 1178 {0xa2, 0x4e}, /* bd50 */
1069 {0xa3, 0x41}, /* bd60 */ 1179 {0xa3, 0x41}, /* bd60 */
1070 {0x2d, 0x00}, /* advfl */
1071};
1072
1073static const u8 sensor_start_ov965x_2[][2] = {
1074 {0xff, 0x42}, /* read 42, write ff 00 */
1075 {0x42, 0xc1}, /* com17 - 50 Hz filter */
1076}; 1180};
1077 1181
1078
1079static void ov534_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val) 1182static void ov534_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val)
1080{ 1183{
1081 struct usb_device *udev = gspca_dev->dev; 1184 struct usb_device *udev = gspca_dev->dev;
@@ -1257,14 +1360,14 @@ static void set_frame_rate(struct gspca_dev *gspca_dev)
1257 PDEBUG(D_PROBE, "frame_rate: %d", r->fps); 1360 PDEBUG(D_PROBE, "frame_rate: %d", r->fps);
1258} 1361}
1259 1362
1260static void setbrightness(struct gspca_dev *gspca_dev) 1363static void setbrightness_77(struct gspca_dev *gspca_dev)
1261{ 1364{
1262 struct sd *sd = (struct sd *) gspca_dev; 1365 struct sd *sd = (struct sd *) gspca_dev;
1263 1366
1264 sccb_reg_write(gspca_dev, 0x9B, sd->brightness); 1367 sccb_reg_write(gspca_dev, 0x9B, sd->brightness);
1265} 1368}
1266 1369
1267static void setcontrast(struct gspca_dev *gspca_dev) 1370static void setcontrast_77(struct gspca_dev *gspca_dev)
1268{ 1371{
1269 struct sd *sd = (struct sd *) gspca_dev; 1372 struct sd *sd = (struct sd *) gspca_dev;
1270 1373
@@ -1298,7 +1401,7 @@ static void setgain(struct gspca_dev *gspca_dev)
1298 sccb_reg_write(gspca_dev, 0x00, val); 1401 sccb_reg_write(gspca_dev, 0x00, val);
1299} 1402}
1300 1403
1301static void setexposure(struct gspca_dev *gspca_dev) 1404static void setexposure_77(struct gspca_dev *gspca_dev)
1302{ 1405{
1303 struct sd *sd = (struct sd *) gspca_dev; 1406 struct sd *sd = (struct sd *) gspca_dev;
1304 u8 val; 1407 u8 val;
@@ -1329,7 +1432,7 @@ static void sethue(struct gspca_dev *gspca_dev)
1329 sccb_reg_write(gspca_dev, 0x01, sd->hue); 1432 sccb_reg_write(gspca_dev, 0x01, sd->hue);
1330} 1433}
1331 1434
1332static void setautogain(struct gspca_dev *gspca_dev) 1435static void setautogain_77(struct gspca_dev *gspca_dev)
1333{ 1436{
1334 struct sd *sd = (struct sd *) gspca_dev; 1437 struct sd *sd = (struct sd *) gspca_dev;
1335 1438
@@ -1354,7 +1457,7 @@ static void setawb(struct gspca_dev *gspca_dev)
1354 sccb_reg_write(gspca_dev, 0x63, 0xaa); /* AWB off */ 1457 sccb_reg_write(gspca_dev, 0x63, 0xaa); /* AWB off */
1355} 1458}
1356 1459
1357static void setsharpness(struct gspca_dev *gspca_dev) 1460static void setsharpness_77(struct gspca_dev *gspca_dev)
1358{ 1461{
1359 struct sd *sd = (struct sd *) gspca_dev; 1462 struct sd *sd = (struct sd *) gspca_dev;
1360 u8 val; 1463 u8 val;
@@ -1388,6 +1491,132 @@ static void setvflip(struct gspca_dev *gspca_dev)
1388 sccb_reg_read(gspca_dev, 0x0c) & 0x7f); 1491 sccb_reg_read(gspca_dev, 0x0c) & 0x7f);
1389} 1492}
1390 1493
1494/* ov965x specific controls */
1495static void setbrightness_96(struct gspca_dev *gspca_dev)
1496{
1497 struct sd *sd = (struct sd *) gspca_dev;
1498 u8 val;
1499
1500 val = sd->brightness;
1501 if (val < 8)
1502 val = 15 - val; /* f .. 8 */
1503 else
1504 val = val - 8; /* 0 .. 7 */
1505 sccb_reg_write(gspca_dev, 0x55, /* brtn - brightness adjustment */
1506 0x0f | (val << 4));
1507}
1508
1509static void setcontrast_96(struct gspca_dev *gspca_dev)
1510{
1511 struct sd *sd = (struct sd *) gspca_dev;
1512
1513 sccb_reg_write(gspca_dev, 0x56, /* cnst1 - contrast 1 ctrl coeff */
1514 sd->contrast << 4);
1515}
1516
1517static void setexposure_96(struct gspca_dev *gspca_dev)
1518{
1519 struct sd *sd = (struct sd *) gspca_dev;
1520 u8 val;
1521 static const u8 expo[4] = {0x00, 0x25, 0x38, 0x5e};
1522
1523 sccb_reg_write(gspca_dev, 0x10, /* aec[9:2] */
1524 expo[sd->exposure]);
1525 val = sccb_reg_read(gspca_dev, 0x13); /* com8 */
1526 sccb_reg_write(gspca_dev, 0xff, 0x00);
1527 sccb_reg_write(gspca_dev, 0x13, val);
1528 val = sccb_reg_read(gspca_dev, 0xa1); /* aech */
1529 sccb_reg_write(gspca_dev, 0xff, 0x00);
1530 sccb_reg_write(gspca_dev, 0xa1, val & 0xe0); /* aec[15:10] = 0 */
1531}
1532
1533static void setsharpness_96(struct gspca_dev *gspca_dev)
1534{
1535 struct sd *sd = (struct sd *) gspca_dev;
1536 u8 val;
1537
1538 val = sd->sharpness;
1539 if (val < 0) { /* auto */
1540 val = sccb_reg_read(gspca_dev, 0x42); /* com17 */
1541 sccb_reg_write(gspca_dev, 0xff, 0x00);
1542 sccb_reg_write(gspca_dev, 0x42, val | 0x40);
1543 /* Edge enhancement strength auto adjust */
1544 return;
1545 }
1546 if (val != 0)
1547 val = 1 << (val - 1);
1548 sccb_reg_write(gspca_dev, 0x3f, /* edge - edge enhance. factor */
1549 val);
1550 val = sccb_reg_read(gspca_dev, 0x42); /* com17 */
1551 sccb_reg_write(gspca_dev, 0xff, 0x00);
1552 sccb_reg_write(gspca_dev, 0x42, val & 0xbf);
1553}
1554
1555static void setautogain_96(struct gspca_dev *gspca_dev)
1556{
1557 struct sd *sd = (struct sd *) gspca_dev;
1558 u8 val;
1559
1560/*fixme: should adjust agc/awb/aec by different controls */
1561 val = sd->autogain;
1562 val = sccb_reg_read(gspca_dev, 0x13); /* com8 */
1563 sccb_reg_write(gspca_dev, 0xff, 0x00);
1564 if (sd->autogain)
1565 val |= 0x05; /* agc & aec */
1566 else
1567 val &= 0xfa;
1568 sccb_reg_write(gspca_dev, 0x13, val);
1569}
1570
1571static void setsatur(struct gspca_dev *gspca_dev)
1572{
1573 struct sd *sd = (struct sd *) gspca_dev;
1574 u8 val1, val2, val3;
1575 static const u8 matrix[5][2] = {
1576 {0x14, 0x38},
1577 {0x1e, 0x54},
1578 {0x28, 0x70},
1579 {0x32, 0x8c},
1580 {0x48, 0x90}
1581 };
1582
1583 val1 = matrix[sd->satur][0];
1584 val2 = matrix[sd->satur][1];
1585 val3 = val1 + val2;
1586 sccb_reg_write(gspca_dev, 0x4f, val3); /* matrix coeff */
1587 sccb_reg_write(gspca_dev, 0x50, val3);
1588 sccb_reg_write(gspca_dev, 0x51, 0x00);
1589 sccb_reg_write(gspca_dev, 0x52, val1);
1590 sccb_reg_write(gspca_dev, 0x53, val2);
1591 sccb_reg_write(gspca_dev, 0x54, val3);
1592 sccb_reg_write(gspca_dev, 0x58, 0x1a); /* mtxs - coeff signs */
1593 val1 = sccb_reg_read(gspca_dev, 0x41); /* com16 */
1594 sccb_reg_write(gspca_dev, 0xff, 0x00);
1595 sccb_reg_write(gspca_dev, 0x41, val1);
1596}
1597
1598static void setfreq(struct gspca_dev *gspca_dev)
1599{
1600 struct sd *sd = (struct sd *) gspca_dev;
1601 u8 val;
1602
1603 val = sccb_reg_read(gspca_dev, 0x13); /* com8 */
1604 sccb_reg_write(gspca_dev, 0xff, 0x00);
1605 if (sd->lightfreq == 0) {
1606 sccb_reg_write(gspca_dev, 0x13, val & 0xdf);
1607 return;
1608 }
1609 sccb_reg_write(gspca_dev, 0x13, val | 0x20);
1610
1611 val = sccb_reg_read(gspca_dev, 0x42); /* com17 */
1612 sccb_reg_write(gspca_dev, 0xff, 0x00);
1613 if (sd->lightfreq == 1)
1614 val |= 0x01;
1615 else
1616 val &= 0xfe;
1617 sccb_reg_write(gspca_dev, 0x42, val);
1618}
1619
1391/* this function is called at probe time */ 1620/* this function is called at probe time */
1392static int sd_config(struct gspca_dev *gspca_dev, 1621static int sd_config(struct gspca_dev *gspca_dev,
1393 const struct usb_device_id *id) 1622 const struct usb_device_id *id)
@@ -1413,28 +1642,47 @@ static int sd_config(struct gspca_dev *gspca_dev,
1413 1642
1414 sd->frame_rate = 30; 1643 sd->frame_rate = 30;
1415 1644
1416 sd->brightness = BRIGHTNESS_DEF; 1645 if (sd->sensor == SENSOR_OV772X) {
1417 sd->contrast = CONTRAST_DEF; 1646 sd->brightness = BRIGHTNESS_77_DEF;
1418 sd->gain = GAIN_DEF; 1647 sd->contrast = CONTRAST_77_DEF;
1419 sd->exposure = EXPO_DEF; 1648 sd->gain = GAIN_DEF;
1420 sd->redblc = RED_BALANCE_DEF; 1649 sd->exposure = EXPO_77_DEF;
1421 sd->blueblc = BLUE_BALANCE_DEF; 1650 sd->redblc = RED_BALANCE_DEF;
1422 sd->hue = HUE_DEF; 1651 sd->blueblc = BLUE_BALANCE_DEF;
1423#if AUTOGAIN_DEF != 0 1652 sd->hue = HUE_DEF;
1424 sd->autogain = AUTOGAIN_DEF; 1653#if AUTOGAIN_77_DEF != 0
1654 sd->autogain = AUTOGAIN_77_DEF;
1425#else 1655#else
1426 gspca_dev->ctrl_inac |= (1 << AWB_IDX); 1656 gspca_dev->ctrl_inac |= (1 << AWB_77_IDX);
1427#endif 1657#endif
1428#if AWB_DEF != 0 1658#if AWB_DEF != 0
1429 sd->awb = AWB_DEF 1659 sd->awb = AWB_DEF
1660#endif
1661#if SHARPNESS_77_DEF != 0
1662 sd->sharpness = SHARPNESS_77_DEF;
1430#endif 1663#endif
1431 sd->sharpness = SHARPNESS_DEF;
1432#if HFLIP_DEF != 0 1664#if HFLIP_DEF != 0
1433 sd->hflip = HFLIP_DEF; 1665 sd->hflip = HFLIP_DEF;
1434#endif 1666#endif
1435#if VFLIP_DEF != 0 1667#if VFLIP_DEF != 0
1436 sd->vflip = VFLIP_DEF; 1668 sd->vflip = VFLIP_DEF;
1669#endif
1670 } else {
1671 sd->brightness = BRIGHTNESS_96_DEF;
1672 sd->contrast = CONTRAST_96_DEF;
1673#if AUTOGAIN_96_DEF != 0
1674 sd->autogain = AUTOGAIN_96_DEF;
1675 gspca_dev->ctrl_inac |= (1 << EXPO_96_IDX);
1676#endif
1677#if EXPO_96_DEF != 0
1678 sd->exposure = EXPO_96_DEF;
1679#endif
1680#if SHARPNESS_96_DEF != 0
1681 sd->sharpness = SHARPNESS_96_DEF;
1437#endif 1682#endif
1683 sd->satur = SATUR_DEF;
1684 sd->lightfreq = FREQ_DEF;
1685 }
1438 return 0; 1686 return 0;
1439} 1687}
1440 1688
@@ -1517,16 +1765,16 @@ static int sd_start_ov772x(struct gspca_dev *gspca_dev)
1517 } 1765 }
1518 set_frame_rate(gspca_dev); 1766 set_frame_rate(gspca_dev);
1519 1767
1520 setautogain(gspca_dev); 1768 setautogain_77(gspca_dev);
1521 setawb(gspca_dev); 1769 setawb(gspca_dev);
1522 setgain(gspca_dev); 1770 setgain(gspca_dev);
1523 setredblc(gspca_dev); 1771 setredblc(gspca_dev);
1524 setblueblc(gspca_dev); 1772 setblueblc(gspca_dev);
1525 sethue(gspca_dev); 1773 sethue(gspca_dev);
1526 setexposure(gspca_dev); 1774 setexposure_77(gspca_dev);
1527 setbrightness(gspca_dev); 1775 setbrightness_77(gspca_dev);
1528 setcontrast(gspca_dev); 1776 setcontrast_77(gspca_dev);
1529 setsharpness(gspca_dev); 1777 setsharpness_77(gspca_dev);
1530 setvflip(gspca_dev); 1778 setvflip(gspca_dev);
1531 sethflip(gspca_dev); 1779 sethflip(gspca_dev);
1532 1780
@@ -1583,8 +1831,14 @@ static int sd_start_ov965x(struct gspca_dev *gspca_dev)
1583 ARRAY_SIZE(sensor_start_ov965x_2_sxga)); 1831 ARRAY_SIZE(sensor_start_ov965x_2_sxga));
1584 break; 1832 break;
1585 } 1833 }
1586 sccb_w_array(gspca_dev, sensor_start_ov965x_2, 1834 setfreq(gspca_dev);
1587 ARRAY_SIZE(sensor_start_ov965x_2)); 1835 setautogain_96(gspca_dev);
1836 setbrightness_96(gspca_dev);
1837 setcontrast_96(gspca_dev);
1838 setexposure_96(gspca_dev);
1839 setsharpness_96(gspca_dev);
1840 setsatur(gspca_dev);
1841
1588 ov534_reg_write(gspca_dev, 0xe0, 0x00); 1842 ov534_reg_write(gspca_dev, 0xe0, 0x00);
1589 ov534_reg_write(gspca_dev, 0xe0, 0x00); 1843 ov534_reg_write(gspca_dev, 0xe0, 0x00);
1590 ov534_set_led(gspca_dev, 1); 1844 ov534_set_led(gspca_dev, 1);
@@ -1687,7 +1941,7 @@ scan_next:
1687 } while (remaining_len > 0); 1941 } while (remaining_len > 0);
1688} 1942}
1689 1943
1690/* ov772x controls */ 1944/* controls */
1691static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val) 1945static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
1692{ 1946{
1693 struct sd *sd = (struct sd *) gspca_dev; 1947 struct sd *sd = (struct sd *) gspca_dev;
@@ -1711,8 +1965,12 @@ static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
1711 struct sd *sd = (struct sd *) gspca_dev; 1965 struct sd *sd = (struct sd *) gspca_dev;
1712 1966
1713 sd->exposure = val; 1967 sd->exposure = val;
1714 if (gspca_dev->streaming) 1968 if (gspca_dev->streaming) {
1715 setexposure(gspca_dev); 1969 if (sd->sensor == SENSOR_OV772X)
1970 setexposure_77(gspca_dev);
1971 else
1972 setexposure_96(gspca_dev);
1973 }
1716 return 0; 1974 return 0;
1717} 1975}
1718 1976
@@ -1729,8 +1987,12 @@ static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1729 struct sd *sd = (struct sd *) gspca_dev; 1987 struct sd *sd = (struct sd *) gspca_dev;
1730 1988
1731 sd->brightness = val; 1989 sd->brightness = val;
1732 if (gspca_dev->streaming) 1990 if (gspca_dev->streaming) {
1733 setbrightness(gspca_dev); 1991 if (sd->sensor == SENSOR_OV772X)
1992 setbrightness_77(gspca_dev);
1993 else
1994 setbrightness_96(gspca_dev);
1995 }
1734 return 0; 1996 return 0;
1735} 1997}
1736 1998
@@ -1747,8 +2009,12 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1747 struct sd *sd = (struct sd *) gspca_dev; 2009 struct sd *sd = (struct sd *) gspca_dev;
1748 2010
1749 sd->contrast = val; 2011 sd->contrast = val;
1750 if (gspca_dev->streaming) 2012 if (gspca_dev->streaming) {
1751 setcontrast(gspca_dev); 2013 if (sd->sensor == SENSOR_OV772X)
2014 setcontrast_77(gspca_dev);
2015 else
2016 setcontrast_96(gspca_dev);
2017 }
1752 return 0; 2018 return 0;
1753} 2019}
1754 2020
@@ -1760,6 +2026,41 @@ static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1760 return 0; 2026 return 0;
1761} 2027}
1762 2028
2029static int sd_setsatur(struct gspca_dev *gspca_dev, __s32 val)
2030{
2031 struct sd *sd = (struct sd *) gspca_dev;
2032
2033 sd->satur = val;
2034 if (gspca_dev->streaming)
2035 setsatur(gspca_dev);
2036 return 0;
2037}
2038
2039static int sd_getsatur(struct gspca_dev *gspca_dev, __s32 *val)
2040{
2041 struct sd *sd = (struct sd *) gspca_dev;
2042
2043 *val = sd->satur;
2044 return 0;
2045}
2046static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
2047{
2048 struct sd *sd = (struct sd *) gspca_dev;
2049
2050 sd->lightfreq = val;
2051 if (gspca_dev->streaming)
2052 setfreq(gspca_dev);
2053 return 0;
2054}
2055
2056static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
2057{
2058 struct sd *sd = (struct sd *) gspca_dev;
2059
2060 *val = sd->lightfreq;
2061 return 0;
2062}
2063
1763static int sd_setredblc(struct gspca_dev *gspca_dev, __s32 val) 2064static int sd_setredblc(struct gspca_dev *gspca_dev, __s32 val)
1764{ 2065{
1765 struct sd *sd = (struct sd *) gspca_dev; 2066 struct sd *sd = (struct sd *) gspca_dev;
@@ -1820,14 +2121,24 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1820 2121
1821 sd->autogain = val; 2122 sd->autogain = val;
1822 2123
1823 /* the auto white balance control works only when auto gain is set */ 2124 if (gspca_dev->streaming) {
1824 if (val) 2125 if (sd->sensor == SENSOR_OV772X) {
1825 gspca_dev->ctrl_inac &= ~(1 << AWB_IDX);
1826 else
1827 gspca_dev->ctrl_inac |= (1 << AWB_IDX);
1828 2126
1829 if (gspca_dev->streaming) 2127 /* the auto white balance control works only
1830 setautogain(gspca_dev); 2128 * when auto gain is set */
2129 if (val)
2130 gspca_dev->ctrl_inac &= ~(1 << AWB_77_IDX);
2131 else
2132 gspca_dev->ctrl_inac |= (1 << AWB_77_IDX);
2133 setautogain_77(gspca_dev);
2134 } else {
2135 if (val)
2136 gspca_dev->ctrl_inac |= (1 << EXPO_96_IDX);
2137 else
2138 gspca_dev->ctrl_inac &= ~(1 << EXPO_96_IDX);
2139 setautogain_96(gspca_dev);
2140 }
2141 }
1831 return 0; 2142 return 0;
1832} 2143}
1833 2144
@@ -1862,8 +2173,12 @@ static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
1862 struct sd *sd = (struct sd *) gspca_dev; 2173 struct sd *sd = (struct sd *) gspca_dev;
1863 2174
1864 sd->sharpness = val; 2175 sd->sharpness = val;
1865 if (gspca_dev->streaming) 2176 if (gspca_dev->streaming) {
1866 setsharpness(gspca_dev); 2177 if (sd->sensor == SENSOR_OV772X)
2178 setsharpness_77(gspca_dev);
2179 else
2180 setsharpness_96(gspca_dev);
2181 }
1867 return 0; 2182 return 0;
1868} 2183}
1869 2184
@@ -1952,6 +2267,27 @@ static int sd_set_streamparm(struct gspca_dev *gspca_dev,
1952 return 0; 2267 return 0;
1953} 2268}
1954 2269
2270static int sd_querymenu(struct gspca_dev *gspca_dev,
2271 struct v4l2_querymenu *menu)
2272{
2273 switch (menu->id) {
2274 case V4L2_CID_POWER_LINE_FREQUENCY:
2275 switch (menu->index) {
2276 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
2277 strcpy((char *) menu->name, "NoFliker");
2278 return 0;
2279 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
2280 strcpy((char *) menu->name, "50 Hz");
2281 return 0;
2282 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
2283 strcpy((char *) menu->name, "60 Hz");
2284 return 0;
2285 }
2286 break;
2287 }
2288 return -EINVAL;
2289}
2290
1955/* sub-driver description */ 2291/* sub-driver description */
1956static const struct sd_desc sd_desc_ov772x = { 2292static const struct sd_desc sd_desc_ov772x = {
1957 .name = MODULE_NAME, 2293 .name = MODULE_NAME,
@@ -1975,8 +2311,7 @@ static const struct sd_desc sd_desc_ov965x = {
1975 .start = sd_start_ov965x, 2311 .start = sd_start_ov965x,
1976 .stopN = sd_stopN_ov965x, 2312 .stopN = sd_stopN_ov965x,
1977 .pkt_scan = sd_pkt_scan, 2313 .pkt_scan = sd_pkt_scan,
1978 .get_streamparm = sd_get_streamparm, 2314 .querymenu = sd_querymenu,
1979 .set_streamparm = sd_set_streamparm,
1980}; 2315};
1981 2316
1982/* -- module initialisation -- */ 2317/* -- module initialisation -- */