diff options
author | Jean-Francois Moine <moinejf@free.fr> | 2009-11-24 03:22:05 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-12-05 15:42:07 -0500 |
commit | c22c4a20a6ac7b10e43eab6963f941795c5e92aa (patch) | |
tree | ecf7b92e15701785d6ceefc4d2ef0cf5bbb71049 /drivers/media | |
parent | b8c8a5bf833db5ad80266a6a9e5ad496ab01d434 (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.c | 479 |
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); | |||
99 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | 101 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); |
100 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | 102 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); |
101 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | 103 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); |
104 | static int sd_setsatur(struct gspca_dev *gspca_dev, __s32 val); | ||
105 | static int sd_getsatur(struct gspca_dev *gspca_dev, __s32 *val); | ||
106 | static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); | ||
107 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); | ||
102 | 108 | ||
103 | static struct ctrl sd_ctrls_ov772x[] = { | 109 | static 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 | }; |
274 | static struct ctrl sd_ctrls_ov965x[] = { | 280 | static 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 | ||
277 | static const struct v4l2_pix_format ov772x_mode[] = { | 382 | static 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 | |||
317 | static const u8 bridge_init_ov772x[][2] = { | 423 | static 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 | ||
1058 | static const u8 sensor_start_ov965x_2_sxga[][2] = { | 1168 | static 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 | |||
1073 | static 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 | |||
1079 | static void ov534_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val) | 1182 | static 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 | ||
1260 | static void setbrightness(struct gspca_dev *gspca_dev) | 1363 | static 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 | ||
1267 | static void setcontrast(struct gspca_dev *gspca_dev) | 1370 | static 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 | ||
1301 | static void setexposure(struct gspca_dev *gspca_dev) | 1404 | static 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 | ||
1332 | static void setautogain(struct gspca_dev *gspca_dev) | 1435 | static 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 | ||
1357 | static void setsharpness(struct gspca_dev *gspca_dev) | 1460 | static 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 */ | ||
1495 | static 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 | |||
1509 | static 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 | |||
1517 | static 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 | |||
1533 | static 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 | |||
1555 | static 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 | |||
1571 | static 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 | |||
1598 | static 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 */ |
1392 | static int sd_config(struct gspca_dev *gspca_dev, | 1621 | static 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 */ |
1691 | static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val) | 1945 | static 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 | ||
2029 | static 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 | |||
2039 | static 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 | } | ||
2046 | static 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 | |||
2056 | static 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 | |||
1763 | static int sd_setredblc(struct gspca_dev *gspca_dev, __s32 val) | 2064 | static 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 | ||
2270 | static 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 */ |
1956 | static const struct sd_desc sd_desc_ov772x = { | 2292 | static 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 -- */ |