4 * Copyright (C) 2008 Antonio Ospite <ospite@studenti.unina.it>
5 * Copyright (C) 2008 Jim Paris <jim@jtan.com>
6 * Copyright (C) 2009 Jean-Francois Moine http://moinejf.free.fr
8 * Based on a prototype written by Mark Ferrell <majortrips@gmail.com>
9 * USB protocol reverse engineered by Jim Paris <jim@jtan.com>
10 * https://jim.sh/svn/jim/devl/playstation/ps3/eye/test/
12 * PS3 Eye camera enhanced by Richard Kaswy http://kaswy.free.fr
13 * PS3 Eye camera, brightness, contrast, hue, AWB control added
14 * by Max Thrun <bear24rw@gmail.com>
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 #define MODULE_NAME "ov534"
35 #define OV534_REG_ADDRESS 0xf1 /* sensor address */
36 #define OV534_REG_SUBADDR 0xf2
37 #define OV534_REG_WRITE 0xf3
38 #define OV534_REG_READ 0xf4
39 #define OV534_REG_OPERATION 0xf5
40 #define OV534_REG_STATUS 0xf6
42 #define OV534_OP_WRITE_3 0x37
43 #define OV534_OP_WRITE_2 0x33
44 #define OV534_OP_READ_2 0xf9
46 #define CTRL_TIMEOUT 500
48 MODULE_AUTHOR("Antonio Ospite <ospite@studenti.unina.it>");
49 MODULE_DESCRIPTION("GSPCA/OV534 USB Camera Driver");
50 MODULE_LICENSE("GPL");
52 /* specific webcam descriptor */
54 struct gspca_dev gspca_dev
; /* !! must be the first item */
75 #define SENSOR_OV772X 0
76 #define SENSOR_OV965X 1
79 /* V4L2 controls supported by the driver */
80 static int sd_setgain(struct gspca_dev
*gspca_dev
, __s32 val
);
81 static int sd_getgain(struct gspca_dev
*gspca_dev
, __s32
*val
);
82 static int sd_setexposure(struct gspca_dev
*gspca_dev
, __s32 val
);
83 static int sd_getexposure(struct gspca_dev
*gspca_dev
, __s32
*val
);
84 static int sd_setredblc(struct gspca_dev
*gspca_dev
, __s32 val
);
85 static int sd_getredblc(struct gspca_dev
*gspca_dev
, __s32
*val
);
86 static int sd_setblueblc(struct gspca_dev
*gspca_dev
, __s32 val
);
87 static int sd_getblueblc(struct gspca_dev
*gspca_dev
, __s32
*val
);
88 static int sd_setautogain(struct gspca_dev
*gspca_dev
, __s32 val
);
89 static int sd_getautogain(struct gspca_dev
*gspca_dev
, __s32
*val
);
90 static int sd_setsharpness(struct gspca_dev
*gspca_dev
, __s32 val
);
91 static int sd_getsharpness(struct gspca_dev
*gspca_dev
, __s32
*val
);
92 static int sd_sethflip(struct gspca_dev
*gspca_dev
, __s32 val
);
93 static int sd_gethflip(struct gspca_dev
*gspca_dev
, __s32
*val
);
94 static int sd_setvflip(struct gspca_dev
*gspca_dev
, __s32 val
);
95 static int sd_getvflip(struct gspca_dev
*gspca_dev
, __s32
*val
);
96 static int sd_sethue(struct gspca_dev
*gspca_dev
, __s32 val
);
97 static int sd_gethue(struct gspca_dev
*gspca_dev
, __s32
*val
);
98 static int sd_setawb(struct gspca_dev
*gspca_dev
, __s32 val
);
99 static int sd_getawb(struct gspca_dev
*gspca_dev
, __s32
*val
);
100 static int sd_setbrightness(struct gspca_dev
*gspca_dev
, __s32 val
);
101 static int sd_getbrightness(struct gspca_dev
*gspca_dev
, __s32
*val
);
102 static int sd_setcontrast(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
);
109 static struct ctrl sd_ctrls_ov772x
[] = {
112 .id
= V4L2_CID_BRIGHTNESS
,
113 .type
= V4L2_CTRL_TYPE_INTEGER
,
114 .name
= "Brightness",
118 #define BRIGHTNESS_77_DEF 20
119 .default_value
= BRIGHTNESS_77_DEF
,
121 .set
= sd_setbrightness
,
122 .get
= sd_getbrightness
,
126 .id
= V4L2_CID_CONTRAST
,
127 .type
= V4L2_CTRL_TYPE_INTEGER
,
132 #define CONTRAST_77_DEF 37
133 .default_value
= CONTRAST_77_DEF
,
135 .set
= sd_setcontrast
,
136 .get
= sd_getcontrast
,
141 .type
= V4L2_CTRL_TYPE_INTEGER
,
147 .default_value
= GAIN_DEF
,
154 .id
= V4L2_CID_EXPOSURE
,
155 .type
= V4L2_CTRL_TYPE_INTEGER
,
160 #define EXPO_77_DEF 120
161 .default_value
= EXPO_77_DEF
,
163 .set
= sd_setexposure
,
164 .get
= sd_getexposure
,
168 .id
= V4L2_CID_RED_BALANCE
,
169 .type
= V4L2_CTRL_TYPE_INTEGER
,
170 .name
= "Red Balance",
174 #define RED_BALANCE_DEF 128
175 .default_value
= RED_BALANCE_DEF
,
182 .id
= V4L2_CID_BLUE_BALANCE
,
183 .type
= V4L2_CTRL_TYPE_INTEGER
,
184 .name
= "Blue Balance",
188 #define BLUE_BALANCE_DEF 128
189 .default_value
= BLUE_BALANCE_DEF
,
191 .set
= sd_setblueblc
,
192 .get
= sd_getblueblc
,
197 .type
= V4L2_CTRL_TYPE_INTEGER
,
203 .default_value
= HUE_DEF
,
210 .id
= V4L2_CID_AUTOGAIN
,
211 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
216 #define AUTOGAIN_77_DEF 0
217 .default_value
= AUTOGAIN_77_DEF
,
219 .set
= sd_setautogain
,
220 .get
= sd_getautogain
,
225 .id
= V4L2_CID_AUTO_WHITE_BALANCE
,
226 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
227 .name
= "Auto White Balance",
232 .default_value
= AWB_DEF
,
239 .id
= V4L2_CID_SHARPNESS
,
240 .type
= V4L2_CTRL_TYPE_INTEGER
,
245 #define SHARPNESS_77_DEF 0
246 .default_value
= SHARPNESS_77_DEF
,
248 .set
= sd_setsharpness
,
249 .get
= sd_getsharpness
,
253 .id
= V4L2_CID_HFLIP
,
254 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
260 .default_value
= HFLIP_DEF
,
267 .id
= V4L2_CID_VFLIP
,
268 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
274 .default_value
= VFLIP_DEF
,
280 static struct ctrl sd_ctrls_ov965x
[] = {
283 .id
= V4L2_CID_BRIGHTNESS
,
284 .type
= V4L2_CTRL_TYPE_INTEGER
,
285 .name
= "Brightness",
289 #define BRIGHTNESS_96_DEF 7
290 .default_value
= BRIGHTNESS_96_DEF
,
292 .set
= sd_setbrightness
,
293 .get
= sd_getbrightness
,
297 .id
= V4L2_CID_CONTRAST
,
298 .type
= V4L2_CTRL_TYPE_INTEGER
,
303 #define CONTRAST_96_DEF 3
304 .default_value
= CONTRAST_96_DEF
,
306 .set
= sd_setcontrast
,
307 .get
= sd_getcontrast
,
311 .id
= V4L2_CID_AUTOGAIN
,
312 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
317 #define AUTOGAIN_96_DEF 1
318 .default_value
= AUTOGAIN_96_DEF
,
320 .set
= sd_setautogain
,
321 .get
= sd_getautogain
,
323 #define EXPO_96_IDX 3
326 .id
= V4L2_CID_EXPOSURE
,
327 .type
= V4L2_CTRL_TYPE_INTEGER
,
332 #define EXPO_96_DEF 0
333 .default_value
= EXPO_96_DEF
,
335 .set
= sd_setexposure
,
336 .get
= sd_getexposure
,
340 .id
= V4L2_CID_SHARPNESS
,
341 .type
= V4L2_CTRL_TYPE_INTEGER
,
343 .minimum
= -1, /* -1 = auto */
346 #define SHARPNESS_96_DEF -1
347 .default_value
= SHARPNESS_96_DEF
,
349 .set
= sd_setsharpness
,
350 .get
= sd_getsharpness
,
354 .id
= V4L2_CID_SATURATION
,
355 .type
= V4L2_CTRL_TYPE_INTEGER
,
356 .name
= "Saturation",
361 .default_value
= SATUR_DEF
,
368 .id
= V4L2_CID_POWER_LINE_FREQUENCY
,
369 .type
= V4L2_CTRL_TYPE_MENU
,
370 .name
= "Light frequency filter",
372 .maximum
= 2, /* 0: 0, 1: 50Hz, 2:60Hz */
375 .default_value
= FREQ_DEF
,
382 static const struct v4l2_pix_format ov772x_mode
[] = {
383 {320, 240, V4L2_PIX_FMT_YUYV
, V4L2_FIELD_NONE
,
384 .bytesperline
= 320 * 2,
385 .sizeimage
= 320 * 240 * 2,
386 .colorspace
= V4L2_COLORSPACE_SRGB
,
388 {640, 480, V4L2_PIX_FMT_YUYV
, V4L2_FIELD_NONE
,
389 .bytesperline
= 640 * 2,
390 .sizeimage
= 640 * 480 * 2,
391 .colorspace
= V4L2_COLORSPACE_SRGB
,
395 static const struct v4l2_pix_format ov965x_mode
[] = {
396 {320, 240, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
398 .sizeimage
= 320 * 240 * 3 / 8 + 590,
399 .colorspace
= V4L2_COLORSPACE_JPEG
,
401 {640, 480, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
403 .sizeimage
= 640 * 480 * 3 / 8 + 590,
404 .colorspace
= V4L2_COLORSPACE_JPEG
,
406 {800, 600, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
408 .sizeimage
= 800 * 600 * 3 / 8 + 590,
409 .colorspace
= V4L2_COLORSPACE_JPEG
,
411 {1024, 768, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
412 .bytesperline
= 1024,
413 .sizeimage
= 1024 * 768 * 3 / 8 + 590,
414 .colorspace
= V4L2_COLORSPACE_JPEG
,
416 {1280, 1024, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
417 .bytesperline
= 1280,
418 .sizeimage
= 1280 * 1024 * 3 / 8 + 590,
419 .colorspace
= V4L2_COLORSPACE_JPEG
,
423 static const u8 bridge_init_ov772x
[][2] = {
462 { 0x1d, 0x02 }, /* payload size 0x0200 * 4 = 2048 bytes */
463 { 0x1d, 0x00 }, /* payload size */
465 { 0x1d, 0x02 }, /* frame size 0x025800 * 4 = 614400 */
466 { 0x1d, 0x58 }, /* frame size */
467 { 0x1d, 0x00 }, /* frame size */
470 { 0x1d, 0x08 }, /* turn on UVC header */
471 { 0x1d, 0x0e }, /* .. */
481 static const u8 sensor_init_ov772x
[][2] = {
484 /*fixme: better have a delay?*/
507 { 0x63, 0xaa }, /* AWB - was e0 */
510 { 0x13, 0xf0 }, /* com8 */
523 { 0x13, 0xff }, /* AWB */
571 { 0x8e, 0x00 }, /* De-noise threshold */
574 static const u8 bridge_start_ov772x_vga
[][2] = {
585 static const u8 sensor_start_ov772x_vga
[][2] = {
595 static const u8 bridge_start_ov772x_qvga
[][2] = {
606 static const u8 sensor_start_ov772x_qvga
[][2] = {
617 static const u8 bridge_init_ov965x
[][2] = {
651 static const u8 sensor_init_ov965x
[][2] = {
652 {0x12, 0x80}, /* com7 - SSCB reset */
653 {0x00, 0x00}, /* gain */
654 {0x01, 0x80}, /* blue */
655 {0x02, 0x80}, /* red */
656 {0x03, 0x1b}, /* vref */
657 {0x04, 0x03}, /* com1 - exposure low bits */
658 {0x0b, 0x57}, /* ver */
659 {0x0e, 0x61}, /* com5 */
660 {0x0f, 0x42}, /* com6 */
661 {0x11, 0x00}, /* clkrc */
662 {0x12, 0x02}, /* com7 - 15fps VGA YUYV */
663 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
664 {0x14, 0x28}, /* com9 */
665 {0x16, 0x24}, /* reg16 */
666 {0x17, 0x1d}, /* hstart*/
667 {0x18, 0xbd}, /* hstop */
668 {0x19, 0x01}, /* vstrt */
669 {0x1a, 0x81}, /* vstop*/
670 {0x1e, 0x04}, /* mvfp */
671 {0x24, 0x3c}, /* aew */
672 {0x25, 0x36}, /* aeb */
673 {0x26, 0x71}, /* vpt */
674 {0x27, 0x08}, /* bbias */
675 {0x28, 0x08}, /* gbbias */
676 {0x29, 0x15}, /* gr com */
677 {0x2a, 0x00}, /* exhch */
678 {0x2b, 0x00}, /* exhcl */
679 {0x2c, 0x08}, /* rbias */
680 {0x32, 0xff}, /* href */
681 {0x33, 0x00}, /* chlf */
682 {0x34, 0x3f}, /* aref1 */
683 {0x35, 0x00}, /* aref2 */
684 {0x36, 0xf8}, /* aref3 */
685 {0x38, 0x72}, /* adc2 */
686 {0x39, 0x57}, /* aref4 */
687 {0x3a, 0x80}, /* tslb - yuyv */
688 {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */
689 {0x3d, 0x99}, /* com13 */
690 {0x3f, 0xc1}, /* edge */
691 {0x40, 0xc0}, /* com15 */
692 {0x41, 0x40}, /* com16 */
693 {0x42, 0xc0}, /* com17 */
694 {0x43, 0x0a}, /* rsvd */
705 {0x4f, 0x98}, /* matrix */
711 {0x58, 0x1a}, /* matrix coef sign */
712 {0x59, 0x85}, /* AWB control */
718 {0x5f, 0xf0}, /* AWB blue limit */
719 {0x60, 0xf0}, /* AWB red limit */
720 {0x61, 0xf0}, /* AWB green limit */
721 {0x62, 0x00}, /* lcc1 */
722 {0x63, 0x00}, /* lcc2 */
723 {0x64, 0x02}, /* lcc3 */
724 {0x65, 0x16}, /* lcc4 */
725 {0x66, 0x01}, /* lcc5 */
726 {0x69, 0x02}, /* hv */
727 {0x6b, 0x5a}, /* dbvl */
732 {0x70, 0x21}, /* dnsth */
734 {0x72, 0x00}, /* poidx */
735 {0x73, 0x01}, /* pckdv */
736 {0x74, 0x3a}, /* xindx */
737 {0x75, 0x35}, /* yindx */
740 {0x7a, 0x12}, /* gamma curve */
757 {0x8c, 0x89}, /* com19 */
758 {0x14, 0x28}, /* com9 */
761 {0x9d, 0x03}, /* lcc6 */
762 {0x9e, 0x04}, /* lcc7 */
765 {0xa1, 0x40}, /* aechm */
766 {0xa4, 0x50}, /* com21 */
767 {0xa5, 0x68}, /* com26 */
768 {0xa6, 0x4a}, /* AWB green */
769 {0xa8, 0xc1}, /* refa8 */
770 {0xa9, 0xef}, /* refa9 */
773 {0xac, 0x80}, /* black level control */
779 {0xb4, 0x20}, /* ctrlb4 */
783 {0xbc, 0x7f}, /* ADC channel offsets */
792 {0xc7, 0x80}, /* com24 */
798 {0x4f, 0x98}, /* matrix */
805 {0xff, 0x41}, /* read 41, write ff 00 */
806 {0x41, 0x40}, /* com16 */
808 {0xc5, 0x03}, /* 60 Hz banding filter */
809 {0x6a, 0x02}, /* 50 Hz banding filter */
811 {0x12, 0x62}, /* com7 - 30fps VGA YUV */
812 {0x36, 0xfa}, /* aref3 */
813 {0x69, 0x0a}, /* hv */
814 {0x8c, 0x89}, /* com22 */
815 {0x14, 0x28}, /* com9 */
817 {0x41, 0x40}, /* com16 */
824 {0x03, 0x12}, /* vref */
825 {0x17, 0x16}, /* hstart */
826 {0x18, 0x02}, /* hstop */
827 {0x19, 0x01}, /* vstrt */
828 {0x1a, 0x3d}, /* vstop */
829 {0x32, 0xff}, /* href */
833 static const u8 bridge_init_ov965x_2
[][2] = {
861 static const u8 sensor_init_ov965x_2
[][2] = {
863 {0x1e, 0x04}, /* mvfp */
864 {0x13, 0xe0}, /* com8 */
865 {0x00, 0x00}, /* gain */
866 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
867 {0x11, 0x03}, /* clkrc */
868 {0x6b, 0x5a}, /* dblv */
874 {0xff, 0x42}, /* read 42, write ff 00 */
875 {0x42, 0xc0}, /* com17 */
877 {0xff, 0x42}, /* read 42, write ff 00 */
878 {0x42, 0xc1}, /* com17 */
881 {0xff, 0x42}, /* read 42, write ff 00 */
882 {0x42, 0xc1}, /* com17 */
884 {0x4f, 0x98}, /* matrix */
891 {0xff, 0x41}, /* read 41, write ff 00 */
892 {0x41, 0x40}, /* com16 */
898 {0x10, 0x25}, /* aech - exposure high bits */
899 {0xff, 0x13}, /* read 13, write ff 00 */
900 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
903 static const u8 sensor_start_ov965x_1_vga
[][2] = { /* same for qvga */
904 {0x12, 0x62}, /* com7 - 30fps VGA YUV */
905 {0x36, 0xfa}, /* aref3 */
906 {0x69, 0x0a}, /* hv */
907 {0x8c, 0x89}, /* com22 */
908 {0x14, 0x28}, /* com9 */
909 {0x3e, 0x0c}, /* com14 */
910 {0x41, 0x40}, /* com16 */
916 {0xc7, 0x80}, /* com24 */
917 {0x03, 0x12}, /* vref */
918 {0x17, 0x16}, /* hstart */
919 {0x18, 0x02}, /* hstop */
920 {0x19, 0x01}, /* vstrt */
921 {0x1a, 0x3d}, /* vstop */
922 {0x32, 0xff}, /* href */
926 static const u8 sensor_start_ov965x_1_svga
[][2] = {
927 {0x12, 0x02}, /* com7 - YUYV - VGA 15 full resolution */
928 {0x36, 0xf8}, /* aref3 */
929 {0x69, 0x02}, /* hv */
930 {0x8c, 0x0d}, /* com22 */
931 {0x3e, 0x0c}, /* com14 */
932 {0x41, 0x40}, /* com16 */
938 {0xc7, 0x80}, /* com24 */
939 {0x03, 0x1b}, /* vref */
940 {0x17, 0x1d}, /* hstart */
941 {0x18, 0xbd}, /* hstop */
942 {0x19, 0x01}, /* vstrt */
943 {0x1a, 0x81}, /* vstop */
944 {0x32, 0xff}, /* href */
948 static const u8 sensor_start_ov965x_1_xga
[][2] = {
949 {0x12, 0x02}, /* com7 */
950 {0x36, 0xf8}, /* aref3 */
951 {0x69, 0x02}, /* hv */
952 {0x8c, 0x89}, /* com22 */
953 {0x14, 0x28}, /* com9 */
954 {0x3e, 0x0c}, /* com14 */
955 {0x41, 0x40}, /* com16 */
961 {0xc7, 0x80}, /* com24 */
962 {0x03, 0x1b}, /* vref */
963 {0x17, 0x1d}, /* hstart */
964 {0x18, 0xbd}, /* hstop */
965 {0x19, 0x01}, /* vstrt */
966 {0x1a, 0x81}, /* vstop */
967 {0x32, 0xff}, /* href */
971 static const u8 sensor_start_ov965x_1_sxga
[][2] = {
972 {0x12, 0x02}, /* com7 */
973 {0x36, 0xf8}, /* aref3 */
974 {0x69, 0x02}, /* hv */
975 {0x8c, 0x89}, /* com22 */
976 {0x14, 0x28}, /* com9 */
977 {0x3e, 0x0c}, /* com14 */
978 {0x41, 0x40}, /* com16 */
984 {0xc7, 0x80}, /* com24 */
985 {0x03, 0x1b}, /* vref */
986 {0x17, 0x1d}, /* hstart */
987 {0x18, 0x02}, /* hstop */
988 {0x19, 0x01}, /* vstrt */
989 {0x1a, 0x81}, /* vstop */
990 {0x32, 0xff}, /* href */
994 static const u8 bridge_start_ov965x_qvga
[][2] = {
1022 static const u8 bridge_start_ov965x_vga
[][2] = {
1049 static const u8 bridge_start_ov965x_svga
[][2] = {
1076 static const u8 bridge_start_ov965x_xga
[][2] = {
1103 static const u8 bridge_start_ov965x_sxga
[][2] = {
1120 static const u8 sensor_start_ov965x_2_qvga
[][2] = {
1121 {0x3b, 0xe4}, /* com11 - night mode 1/4 frame rate */
1122 {0x1e, 0x04}, /* mvfp */
1123 {0x13, 0xe0}, /* com8 */
1125 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
1126 {0x11, 0x01}, /* clkrc */
1127 {0x6b, 0x5a}, /* dblv */
1128 {0x6a, 0x02}, /* 50 Hz banding filter */
1129 {0xc5, 0x03}, /* 60 Hz banding filter */
1130 {0xa2, 0x96}, /* bd50 */
1131 {0xa3, 0x7d}, /* bd60 */
1133 {0xff, 0x13}, /* read 13, write ff 00 */
1135 {0x3a, 0x80}, /* tslb - yuyv */
1138 static const u8 sensor_start_ov965x_2_vga
[][2] = {
1139 {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */
1140 {0x1e, 0x04}, /* mvfp */
1141 {0x13, 0xe0}, /* com8 */
1143 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
1144 {0x11, 0x03}, /* clkrc */
1145 {0x6b, 0x5a}, /* dblv */
1146 {0x6a, 0x05}, /* 50 Hz banding filter */
1147 {0xc5, 0x07}, /* 60 Hz banding filter */
1148 {0xa2, 0x4b}, /* bd50 */
1149 {0xa3, 0x3e}, /* bd60 */
1151 {0x2d, 0x00}, /* advfl */
1154 static const u8 sensor_start_ov965x_2_svga
[][2] = { /* same for xga */
1155 {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */
1156 {0x1e, 0x04}, /* mvfp */
1157 {0x13, 0xe0}, /* com8 */
1159 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
1160 {0x11, 0x01}, /* clkrc */
1161 {0x6b, 0x5a}, /* dblv */
1162 {0x6a, 0x0c}, /* 50 Hz banding filter */
1163 {0xc5, 0x0f}, /* 60 Hz banding filter */
1164 {0xa2, 0x4e}, /* bd50 */
1165 {0xa3, 0x41}, /* bd60 */
1168 static const u8 sensor_start_ov965x_2_sxga
[][2] = {
1169 {0x13, 0xe0}, /* com8 */
1171 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
1172 {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */
1173 {0x1e, 0x04}, /* mvfp */
1174 {0x11, 0x01}, /* clkrc */
1175 {0x6b, 0x5a}, /* dblv */
1176 {0x6a, 0x0c}, /* 50 Hz banding filter */
1177 {0xc5, 0x0f}, /* 60 Hz banding filter */
1178 {0xa2, 0x4e}, /* bd50 */
1179 {0xa3, 0x41}, /* bd60 */
1182 static void ov534_reg_write(struct gspca_dev
*gspca_dev
, u16 reg
, u8 val
)
1184 struct usb_device
*udev
= gspca_dev
->dev
;
1187 PDEBUG(D_USBO
, "reg=0x%04x, val=0%02x", reg
, val
);
1188 gspca_dev
->usb_buf
[0] = val
;
1189 ret
= usb_control_msg(udev
,
1190 usb_sndctrlpipe(udev
, 0),
1192 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
1193 0x00, reg
, gspca_dev
->usb_buf
, 1, CTRL_TIMEOUT
);
1195 PDEBUG(D_ERR
, "write failed");
1198 static u8
ov534_reg_read(struct gspca_dev
*gspca_dev
, u16 reg
)
1200 struct usb_device
*udev
= gspca_dev
->dev
;
1203 ret
= usb_control_msg(udev
,
1204 usb_rcvctrlpipe(udev
, 0),
1206 USB_DIR_IN
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
1207 0x00, reg
, gspca_dev
->usb_buf
, 1, CTRL_TIMEOUT
);
1208 PDEBUG(D_USBI
, "reg=0x%04x, data=0x%02x", reg
, gspca_dev
->usb_buf
[0]);
1210 PDEBUG(D_ERR
, "read failed");
1211 return gspca_dev
->usb_buf
[0];
1214 /* Two bits control LED: 0x21 bit 7 and 0x23 bit 7.
1215 * (direction and output)? */
1216 static void ov534_set_led(struct gspca_dev
*gspca_dev
, int status
)
1220 PDEBUG(D_CONF
, "led status: %d", status
);
1222 data
= ov534_reg_read(gspca_dev
, 0x21);
1224 ov534_reg_write(gspca_dev
, 0x21, data
);
1226 data
= ov534_reg_read(gspca_dev
, 0x23);
1232 ov534_reg_write(gspca_dev
, 0x23, data
);
1235 data
= ov534_reg_read(gspca_dev
, 0x21);
1237 ov534_reg_write(gspca_dev
, 0x21, data
);
1241 static int sccb_check_status(struct gspca_dev
*gspca_dev
)
1246 for (i
= 0; i
< 5; i
++) {
1247 data
= ov534_reg_read(gspca_dev
, OV534_REG_STATUS
);
1257 PDEBUG(D_ERR
, "sccb status 0x%02x, attempt %d/5",
1264 static void sccb_reg_write(struct gspca_dev
*gspca_dev
, u8 reg
, u8 val
)
1266 PDEBUG(D_USBO
, "reg: 0x%02x, val: 0x%02x", reg
, val
);
1267 ov534_reg_write(gspca_dev
, OV534_REG_SUBADDR
, reg
);
1268 ov534_reg_write(gspca_dev
, OV534_REG_WRITE
, val
);
1269 ov534_reg_write(gspca_dev
, OV534_REG_OPERATION
, OV534_OP_WRITE_3
);
1271 if (!sccb_check_status(gspca_dev
))
1272 PDEBUG(D_ERR
, "sccb_reg_write failed");
1275 static u8
sccb_reg_read(struct gspca_dev
*gspca_dev
, u16 reg
)
1277 ov534_reg_write(gspca_dev
, OV534_REG_SUBADDR
, reg
);
1278 ov534_reg_write(gspca_dev
, OV534_REG_OPERATION
, OV534_OP_WRITE_2
);
1279 if (!sccb_check_status(gspca_dev
))
1280 PDEBUG(D_ERR
, "sccb_reg_read failed 1");
1282 ov534_reg_write(gspca_dev
, OV534_REG_OPERATION
, OV534_OP_READ_2
);
1283 if (!sccb_check_status(gspca_dev
))
1284 PDEBUG(D_ERR
, "sccb_reg_read failed 2");
1286 return ov534_reg_read(gspca_dev
, OV534_REG_READ
);
1289 /* output a bridge sequence (reg - val) */
1290 static void reg_w_array(struct gspca_dev
*gspca_dev
,
1291 const u8 (*data
)[2], int len
)
1293 while (--len
>= 0) {
1294 ov534_reg_write(gspca_dev
, (*data
)[0], (*data
)[1]);
1299 /* output a sensor sequence (reg - val) */
1300 static void sccb_w_array(struct gspca_dev
*gspca_dev
,
1301 const u8 (*data
)[2], int len
)
1303 while (--len
>= 0) {
1304 if ((*data
)[0] != 0xff) {
1305 sccb_reg_write(gspca_dev
, (*data
)[0], (*data
)[1]);
1307 sccb_reg_read(gspca_dev
, (*data
)[1]);
1308 sccb_reg_write(gspca_dev
, 0xff, 0x00);
1314 /* ov772x specific controls */
1315 static void set_frame_rate(struct gspca_dev
*gspca_dev
)
1317 struct sd
*sd
= (struct sd
*) gspca_dev
;
1325 const struct rate_s
*r
;
1326 static const struct rate_s rate_0
[] = { /* 640x480 */
1327 {60, 0x01, 0xc1, 0x04},
1328 {50, 0x01, 0x41, 0x02},
1329 {40, 0x02, 0xc1, 0x04},
1330 {30, 0x04, 0x81, 0x02},
1331 {15, 0x03, 0x41, 0x04},
1333 static const struct rate_s rate_1
[] = { /* 320x240 */
1334 {125, 0x02, 0x81, 0x02},
1335 {100, 0x02, 0xc1, 0x04},
1336 {75, 0x03, 0xc1, 0x04},
1337 {60, 0x04, 0xc1, 0x04},
1338 {50, 0x02, 0x41, 0x04},
1339 {40, 0x03, 0x41, 0x04},
1340 {30, 0x04, 0x41, 0x04},
1343 if (gspca_dev
->cam
.cam_mode
[gspca_dev
->curr_mode
].priv
== 0) {
1345 i
= ARRAY_SIZE(rate_0
);
1348 i
= ARRAY_SIZE(rate_1
);
1351 if (sd
->frame_rate
>= r
->fps
)
1356 sccb_reg_write(gspca_dev
, 0x11, r
->r11
);
1357 sccb_reg_write(gspca_dev
, 0x0d, r
->r0d
);
1358 ov534_reg_write(gspca_dev
, 0xe5, r
->re5
);
1360 PDEBUG(D_PROBE
, "frame_rate: %d", r
->fps
);
1363 static void setbrightness_77(struct gspca_dev
*gspca_dev
)
1365 struct sd
*sd
= (struct sd
*) gspca_dev
;
1367 sccb_reg_write(gspca_dev
, 0x9B, sd
->brightness
);
1370 static void setcontrast_77(struct gspca_dev
*gspca_dev
)
1372 struct sd
*sd
= (struct sd
*) gspca_dev
;
1374 sccb_reg_write(gspca_dev
, 0x9C, sd
->contrast
);
1377 static void setgain(struct gspca_dev
*gspca_dev
)
1379 struct sd
*sd
= (struct sd
*) gspca_dev
;
1383 switch (val
& 0x30) {
1401 sccb_reg_write(gspca_dev
, 0x00, val
);
1404 static void setexposure_77(struct gspca_dev
*gspca_dev
)
1406 struct sd
*sd
= (struct sd
*) gspca_dev
;
1410 sccb_reg_write(gspca_dev
, 0x08, val
>> 7);
1411 sccb_reg_write(gspca_dev
, 0x10, val
<< 1);
1414 static void setredblc(struct gspca_dev
*gspca_dev
)
1416 struct sd
*sd
= (struct sd
*) gspca_dev
;
1418 sccb_reg_write(gspca_dev
, 0x43, sd
->redblc
);
1421 static void setblueblc(struct gspca_dev
*gspca_dev
)
1423 struct sd
*sd
= (struct sd
*) gspca_dev
;
1425 sccb_reg_write(gspca_dev
, 0x42, sd
->blueblc
);
1428 static void sethue(struct gspca_dev
*gspca_dev
)
1430 struct sd
*sd
= (struct sd
*) gspca_dev
;
1432 sccb_reg_write(gspca_dev
, 0x01, sd
->hue
);
1435 static void setautogain_77(struct gspca_dev
*gspca_dev
)
1437 struct sd
*sd
= (struct sd
*) gspca_dev
;
1440 sccb_reg_write(gspca_dev
, 0x13, 0xf7); /* AGC,AEC,AWB ON */
1441 sccb_reg_write(gspca_dev
, 0x64,
1442 sccb_reg_read(gspca_dev
, 0x64) | 0x03);
1444 sccb_reg_write(gspca_dev
, 0x13, 0xf0); /* AGC,AEC,AWB OFF */
1445 sccb_reg_write(gspca_dev
, 0x64,
1446 sccb_reg_read(gspca_dev
, 0x64) & 0xfc);
1450 static void setawb(struct gspca_dev
*gspca_dev
)
1452 struct sd
*sd
= (struct sd
*) gspca_dev
;
1455 sccb_reg_write(gspca_dev
, 0x63, 0xe0); /* AWB on */
1457 sccb_reg_write(gspca_dev
, 0x63, 0xaa); /* AWB off */
1460 static void setsharpness_77(struct gspca_dev
*gspca_dev
)
1462 struct sd
*sd
= (struct sd
*) gspca_dev
;
1465 val
= sd
->sharpness
;
1466 sccb_reg_write(gspca_dev
, 0x91, val
); /* vga noise */
1467 sccb_reg_write(gspca_dev
, 0x8e, val
); /* qvga noise */
1470 static void sethflip(struct gspca_dev
*gspca_dev
)
1472 struct sd
*sd
= (struct sd
*) gspca_dev
;
1475 sccb_reg_write(gspca_dev
, 0x0c,
1476 sccb_reg_read(gspca_dev
, 0x0c) | 0x40);
1478 sccb_reg_write(gspca_dev
, 0x0c,
1479 sccb_reg_read(gspca_dev
, 0x0c) & 0xbf);
1482 static void setvflip(struct gspca_dev
*gspca_dev
)
1484 struct sd
*sd
= (struct sd
*) gspca_dev
;
1487 sccb_reg_write(gspca_dev
, 0x0c,
1488 sccb_reg_read(gspca_dev
, 0x0c) | 0x80);
1490 sccb_reg_write(gspca_dev
, 0x0c,
1491 sccb_reg_read(gspca_dev
, 0x0c) & 0x7f);
1494 /* ov965x specific controls */
1495 static void setbrightness_96(struct gspca_dev
*gspca_dev
)
1497 struct sd
*sd
= (struct sd
*) gspca_dev
;
1500 val
= sd
->brightness
;
1502 val
= 15 - val
; /* f .. 8 */
1504 val
= val
- 8; /* 0 .. 7 */
1505 sccb_reg_write(gspca_dev
, 0x55, /* brtn - brightness adjustment */
1509 static void setcontrast_96(struct gspca_dev
*gspca_dev
)
1511 struct sd
*sd
= (struct sd
*) gspca_dev
;
1513 sccb_reg_write(gspca_dev
, 0x56, /* cnst1 - contrast 1 ctrl coeff */
1517 static void setexposure_96(struct gspca_dev
*gspca_dev
)
1519 struct sd
*sd
= (struct sd
*) gspca_dev
;
1521 static const u8 expo
[4] = {0x00, 0x25, 0x38, 0x5e};
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 */
1533 static void setsharpness_96(struct gspca_dev
*gspca_dev
)
1535 struct sd
*sd
= (struct sd
*) gspca_dev
;
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 */
1547 val
= 1 << (val
- 1);
1548 sccb_reg_write(gspca_dev
, 0x3f, /* edge - edge enhance. factor */
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);
1555 static void setautogain_96(struct gspca_dev
*gspca_dev
)
1557 struct sd
*sd
= (struct sd
*) gspca_dev
;
1560 /*fixme: should adjust agc/awb/aec by different controls */
1562 val
= sccb_reg_read(gspca_dev
, 0x13); /* com8 */
1563 sccb_reg_write(gspca_dev
, 0xff, 0x00);
1565 val
|= 0x05; /* agc & aec */
1568 sccb_reg_write(gspca_dev
, 0x13, val
);
1571 static void setsatur(struct gspca_dev
*gspca_dev
)
1573 struct sd
*sd
= (struct sd
*) gspca_dev
;
1574 u8 val1
, val2
, val3
;
1575 static const u8 matrix
[5][2] = {
1583 val1
= matrix
[sd
->satur
][0];
1584 val2
= matrix
[sd
->satur
][1];
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
);
1598 static void setfreq(struct gspca_dev
*gspca_dev
)
1600 struct sd
*sd
= (struct sd
*) gspca_dev
;
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);
1609 sccb_reg_write(gspca_dev
, 0x13, val
| 0x20);
1611 val
= sccb_reg_read(gspca_dev
, 0x42); /* com17 */
1612 sccb_reg_write(gspca_dev
, 0xff, 0x00);
1613 if (sd
->lightfreq
== 1)
1617 sccb_reg_write(gspca_dev
, 0x42, val
);
1620 /* this function is called at probe time */
1621 static int sd_config(struct gspca_dev
*gspca_dev
,
1622 const struct usb_device_id
*id
)
1624 struct sd
*sd
= (struct sd
*) gspca_dev
;
1627 sd
->sensor
= id
->driver_info
;
1629 cam
= &gspca_dev
->cam
;
1631 if (sd
->sensor
== SENSOR_OV772X
) {
1632 cam
->cam_mode
= ov772x_mode
;
1633 cam
->nmodes
= ARRAY_SIZE(ov772x_mode
);
1636 cam
->bulk_size
= 16384;
1637 cam
->bulk_nurbs
= 2;
1638 } else { /* ov965x */
1639 cam
->cam_mode
= ov965x_mode
;
1640 cam
->nmodes
= ARRAY_SIZE(ov965x_mode
);
1643 sd
->frame_rate
= 30;
1645 if (sd
->sensor
== SENSOR_OV772X
) {
1646 sd
->brightness
= BRIGHTNESS_77_DEF
;
1647 sd
->contrast
= CONTRAST_77_DEF
;
1648 sd
->gain
= GAIN_DEF
;
1649 sd
->exposure
= EXPO_77_DEF
;
1650 sd
->redblc
= RED_BALANCE_DEF
;
1651 sd
->blueblc
= BLUE_BALANCE_DEF
;
1653 #if AUTOGAIN_77_DEF != 0
1654 sd
->autogain
= AUTOGAIN_77_DEF
;
1656 gspca_dev
->ctrl_inac
|= (1 << AWB_77_IDX
);
1661 #if SHARPNESS_77_DEF != 0
1662 sd
->sharpness
= SHARPNESS_77_DEF
;
1665 sd
->hflip
= HFLIP_DEF
;
1668 sd
->vflip
= VFLIP_DEF
;
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
);
1677 #if EXPO_96_DEF != 0
1678 sd
->exposure
= EXPO_96_DEF
;
1680 #if SHARPNESS_96_DEF != 0
1681 sd
->sharpness
= SHARPNESS_96_DEF
;
1683 sd
->satur
= SATUR_DEF
;
1684 sd
->lightfreq
= FREQ_DEF
;
1689 /* this function is called at probe and resume time */
1690 static int sd_init(struct gspca_dev
*gspca_dev
)
1692 struct sd
*sd
= (struct sd
*) gspca_dev
;
1694 static const u8 sensor_addr
[2] = {
1695 0x42, /* 0 SENSOR_OV772X */
1696 0x60, /* 1 SENSOR_OV965X */
1700 ov534_reg_write(gspca_dev
, 0xe7, 0x3a);
1701 ov534_reg_write(gspca_dev
, 0xe0, 0x08);
1704 /* initialize the sensor address */
1705 ov534_reg_write(gspca_dev
, OV534_REG_ADDRESS
,
1706 sensor_addr
[sd
->sensor
]);
1709 sccb_reg_write(gspca_dev
, 0x12, 0x80);
1712 /* probe the sensor */
1713 sccb_reg_read(gspca_dev
, 0x0a);
1714 sensor_id
= sccb_reg_read(gspca_dev
, 0x0a) << 8;
1715 sccb_reg_read(gspca_dev
, 0x0b);
1716 sensor_id
|= sccb_reg_read(gspca_dev
, 0x0b);
1717 PDEBUG(D_PROBE
, "Sensor ID: %04x", sensor_id
);
1720 switch (sd
->sensor
) {
1722 reg_w_array(gspca_dev
, bridge_init_ov772x
,
1723 ARRAY_SIZE(bridge_init_ov772x
));
1724 ov534_set_led(gspca_dev
, 1);
1725 sccb_w_array(gspca_dev
, sensor_init_ov772x
,
1726 ARRAY_SIZE(sensor_init_ov772x
));
1727 ov534_reg_write(gspca_dev
, 0xe0, 0x09);
1728 ov534_set_led(gspca_dev
, 0);
1729 set_frame_rate(gspca_dev
);
1732 /* case SENSOR_OV965X: */
1733 reg_w_array(gspca_dev
, bridge_init_ov965x
,
1734 ARRAY_SIZE(bridge_init_ov965x
));
1735 sccb_w_array(gspca_dev
, sensor_init_ov965x
,
1736 ARRAY_SIZE(sensor_init_ov965x
));
1737 reg_w_array(gspca_dev
, bridge_init_ov965x_2
,
1738 ARRAY_SIZE(bridge_init_ov965x_2
));
1739 sccb_w_array(gspca_dev
, sensor_init_ov965x_2
,
1740 ARRAY_SIZE(sensor_init_ov965x_2
));
1741 ov534_reg_write(gspca_dev
, 0xe0, 0x00);
1742 ov534_reg_write(gspca_dev
, 0xe0, 0x01);
1743 ov534_set_led(gspca_dev
, 0);
1744 ov534_reg_write(gspca_dev
, 0xe0, 0x00);
1750 static int sd_start_ov772x(struct gspca_dev
*gspca_dev
)
1754 mode
= gspca_dev
->cam
.cam_mode
[gspca_dev
->curr_mode
].priv
;
1755 if (mode
!= 0) { /* 320x240 */
1756 reg_w_array(gspca_dev
, bridge_start_ov772x_qvga
,
1757 ARRAY_SIZE(bridge_start_ov772x_qvga
));
1758 sccb_w_array(gspca_dev
, sensor_start_ov772x_qvga
,
1759 ARRAY_SIZE(sensor_start_ov772x_qvga
));
1760 } else { /* 640x480 */
1761 reg_w_array(gspca_dev
, bridge_start_ov772x_vga
,
1762 ARRAY_SIZE(bridge_start_ov772x_vga
));
1763 sccb_w_array(gspca_dev
, sensor_start_ov772x_vga
,
1764 ARRAY_SIZE(sensor_start_ov772x_vga
));
1766 set_frame_rate(gspca_dev
);
1768 setautogain_77(gspca_dev
);
1771 setredblc(gspca_dev
);
1772 setblueblc(gspca_dev
);
1774 setexposure_77(gspca_dev
);
1775 setbrightness_77(gspca_dev
);
1776 setcontrast_77(gspca_dev
);
1777 setsharpness_77(gspca_dev
);
1778 setvflip(gspca_dev
);
1779 sethflip(gspca_dev
);
1781 ov534_set_led(gspca_dev
, 1);
1782 ov534_reg_write(gspca_dev
, 0xe0, 0x00);
1786 static int sd_start_ov965x(struct gspca_dev
*gspca_dev
)
1790 mode
= gspca_dev
->cam
.cam_mode
[gspca_dev
->curr_mode
].priv
;
1793 /* case 4: * 320x240 */
1794 sccb_w_array(gspca_dev
, sensor_start_ov965x_1_vga
,
1795 ARRAY_SIZE(sensor_start_ov965x_1_vga
));
1796 reg_w_array(gspca_dev
, bridge_start_ov965x_qvga
,
1797 ARRAY_SIZE(bridge_start_ov965x_qvga
));
1798 sccb_w_array(gspca_dev
, sensor_start_ov965x_2_qvga
,
1799 ARRAY_SIZE(sensor_start_ov965x_2_qvga
));
1801 case 3: /* 640x480 */
1802 sccb_w_array(gspca_dev
, sensor_start_ov965x_1_vga
,
1803 ARRAY_SIZE(sensor_start_ov965x_1_vga
));
1804 reg_w_array(gspca_dev
, bridge_start_ov965x_vga
,
1805 ARRAY_SIZE(bridge_start_ov965x_vga
));
1806 sccb_w_array(gspca_dev
, sensor_start_ov965x_2_vga
,
1807 ARRAY_SIZE(sensor_start_ov965x_2_vga
));
1809 case 2: /* 800x600 */
1810 sccb_w_array(gspca_dev
, sensor_start_ov965x_1_svga
,
1811 ARRAY_SIZE(sensor_start_ov965x_1_svga
));
1812 reg_w_array(gspca_dev
, bridge_start_ov965x_svga
,
1813 ARRAY_SIZE(bridge_start_ov965x_svga
));
1814 sccb_w_array(gspca_dev
, sensor_start_ov965x_2_svga
,
1815 ARRAY_SIZE(sensor_start_ov965x_2_svga
));
1817 case 1: /* 1024x768 */
1818 sccb_w_array(gspca_dev
, sensor_start_ov965x_1_xga
,
1819 ARRAY_SIZE(sensor_start_ov965x_1_xga
));
1820 reg_w_array(gspca_dev
, bridge_start_ov965x_xga
,
1821 ARRAY_SIZE(bridge_start_ov965x_xga
));
1822 sccb_w_array(gspca_dev
, sensor_start_ov965x_2_svga
,
1823 ARRAY_SIZE(sensor_start_ov965x_2_svga
));
1825 case 0: /* 1280x1024 */
1826 sccb_w_array(gspca_dev
, sensor_start_ov965x_1_sxga
,
1827 ARRAY_SIZE(sensor_start_ov965x_1_sxga
));
1828 reg_w_array(gspca_dev
, bridge_start_ov965x_sxga
,
1829 ARRAY_SIZE(bridge_start_ov965x_sxga
));
1830 sccb_w_array(gspca_dev
, sensor_start_ov965x_2_sxga
,
1831 ARRAY_SIZE(sensor_start_ov965x_2_sxga
));
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
);
1842 ov534_reg_write(gspca_dev
, 0xe0, 0x00);
1843 ov534_reg_write(gspca_dev
, 0xe0, 0x00);
1844 ov534_set_led(gspca_dev
, 1);
1848 static void sd_stopN_ov772x(struct gspca_dev
*gspca_dev
)
1850 ov534_reg_write(gspca_dev
, 0xe0, 0x09);
1851 ov534_set_led(gspca_dev
, 0);
1854 static void sd_stopN_ov965x(struct gspca_dev
*gspca_dev
)
1856 ov534_reg_write(gspca_dev
, 0xe0, 0x01);
1857 ov534_set_led(gspca_dev
, 0);
1858 ov534_reg_write(gspca_dev
, 0xe0, 0x00);
1861 /* Values for bmHeaderInfo (Video and Still Image Payload Headers, 2.4.3.3) */
1862 #define UVC_STREAM_EOH (1 << 7)
1863 #define UVC_STREAM_ERR (1 << 6)
1864 #define UVC_STREAM_STI (1 << 5)
1865 #define UVC_STREAM_RES (1 << 4)
1866 #define UVC_STREAM_SCR (1 << 3)
1867 #define UVC_STREAM_PTS (1 << 2)
1868 #define UVC_STREAM_EOF (1 << 1)
1869 #define UVC_STREAM_FID (1 << 0)
1871 static void sd_pkt_scan(struct gspca_dev
*gspca_dev
,
1874 struct sd
*sd
= (struct sd
*) gspca_dev
;
1877 int remaining_len
= len
;
1880 payload_len
= gspca_dev
->cam
.bulk
? 2048 : 2040;
1882 len
= min(remaining_len
, payload_len
);
1884 /* Payloads are prefixed with a UVC-style header. We
1885 consider a frame to start when the FID toggles, or the PTS
1886 changes. A frame ends when EOF is set, and we've received
1887 the correct number of bytes. */
1889 /* Verify UVC header. Header length is always 12 */
1890 if (data
[0] != 12 || len
< 12) {
1891 PDEBUG(D_PACK
, "bad header");
1896 if (data
[1] & UVC_STREAM_ERR
) {
1897 PDEBUG(D_PACK
, "payload error");
1901 /* Extract PTS and FID */
1902 if (!(data
[1] & UVC_STREAM_PTS
)) {
1903 PDEBUG(D_PACK
, "PTS not present");
1906 this_pts
= (data
[5] << 24) | (data
[4] << 16)
1907 | (data
[3] << 8) | data
[2];
1908 this_fid
= (data
[1] & UVC_STREAM_FID
) ? 1 : 0;
1910 /* If PTS or FID has changed, start a new frame. */
1911 if (this_pts
!= sd
->last_pts
|| this_fid
!= sd
->last_fid
) {
1912 if (gspca_dev
->last_packet_type
== INTER_PACKET
)
1913 gspca_frame_add(gspca_dev
, LAST_PACKET
,
1915 sd
->last_pts
= this_pts
;
1916 sd
->last_fid
= this_fid
;
1917 gspca_frame_add(gspca_dev
, FIRST_PACKET
,
1918 data
+ 12, len
- 12);
1919 /* If this packet is marked as EOF, end the frame */
1920 } else if (data
[1] & UVC_STREAM_EOF
) {
1922 gspca_frame_add(gspca_dev
, LAST_PACKET
,
1923 data
+ 12, len
- 12);
1926 /* Add the data from this payload */
1927 gspca_frame_add(gspca_dev
, INTER_PACKET
,
1928 data
+ 12, len
- 12);
1931 /* Done this payload */
1935 /* Discard data until a new frame starts. */
1936 gspca_dev
->last_packet_type
= DISCARD_PACKET
;
1939 remaining_len
-= len
;
1941 } while (remaining_len
> 0);
1945 static int sd_setgain(struct gspca_dev
*gspca_dev
, __s32 val
)
1947 struct sd
*sd
= (struct sd
*) gspca_dev
;
1950 if (gspca_dev
->streaming
)
1955 static int sd_getgain(struct gspca_dev
*gspca_dev
, __s32
*val
)
1957 struct sd
*sd
= (struct sd
*) gspca_dev
;
1963 static int sd_setexposure(struct gspca_dev
*gspca_dev
, __s32 val
)
1965 struct sd
*sd
= (struct sd
*) gspca_dev
;
1968 if (gspca_dev
->streaming
) {
1969 if (sd
->sensor
== SENSOR_OV772X
)
1970 setexposure_77(gspca_dev
);
1972 setexposure_96(gspca_dev
);
1977 static int sd_getexposure(struct gspca_dev
*gspca_dev
, __s32
*val
)
1979 struct sd
*sd
= (struct sd
*) gspca_dev
;
1981 *val
= sd
->exposure
;
1985 static int sd_setbrightness(struct gspca_dev
*gspca_dev
, __s32 val
)
1987 struct sd
*sd
= (struct sd
*) gspca_dev
;
1989 sd
->brightness
= val
;
1990 if (gspca_dev
->streaming
) {
1991 if (sd
->sensor
== SENSOR_OV772X
)
1992 setbrightness_77(gspca_dev
);
1994 setbrightness_96(gspca_dev
);
1999 static int sd_getbrightness(struct gspca_dev
*gspca_dev
, __s32
*val
)
2001 struct sd
*sd
= (struct sd
*) gspca_dev
;
2003 *val
= sd
->brightness
;
2007 static int sd_setcontrast(struct gspca_dev
*gspca_dev
, __s32 val
)
2009 struct sd
*sd
= (struct sd
*) gspca_dev
;
2012 if (gspca_dev
->streaming
) {
2013 if (sd
->sensor
== SENSOR_OV772X
)
2014 setcontrast_77(gspca_dev
);
2016 setcontrast_96(gspca_dev
);
2021 static int sd_getcontrast(struct gspca_dev
*gspca_dev
, __s32
*val
)
2023 struct sd
*sd
= (struct sd
*) gspca_dev
;
2025 *val
= sd
->contrast
;
2029 static int sd_setsatur(struct gspca_dev
*gspca_dev
, __s32 val
)
2031 struct sd
*sd
= (struct sd
*) gspca_dev
;
2034 if (gspca_dev
->streaming
)
2035 setsatur(gspca_dev
);
2039 static int sd_getsatur(struct gspca_dev
*gspca_dev
, __s32
*val
)
2041 struct sd
*sd
= (struct sd
*) gspca_dev
;
2046 static int sd_setfreq(struct gspca_dev
*gspca_dev
, __s32 val
)
2048 struct sd
*sd
= (struct sd
*) gspca_dev
;
2050 sd
->lightfreq
= val
;
2051 if (gspca_dev
->streaming
)
2056 static int sd_getfreq(struct gspca_dev
*gspca_dev
, __s32
*val
)
2058 struct sd
*sd
= (struct sd
*) gspca_dev
;
2060 *val
= sd
->lightfreq
;
2064 static int sd_setredblc(struct gspca_dev
*gspca_dev
, __s32 val
)
2066 struct sd
*sd
= (struct sd
*) gspca_dev
;
2069 if (gspca_dev
->streaming
)
2070 setredblc(gspca_dev
);
2074 static int sd_getredblc(struct gspca_dev
*gspca_dev
, __s32
*val
)
2076 struct sd
*sd
= (struct sd
*) gspca_dev
;
2082 static int sd_setblueblc(struct gspca_dev
*gspca_dev
, __s32 val
)
2084 struct sd
*sd
= (struct sd
*) gspca_dev
;
2087 if (gspca_dev
->streaming
)
2088 setblueblc(gspca_dev
);
2092 static int sd_getblueblc(struct gspca_dev
*gspca_dev
, __s32
*val
)
2094 struct sd
*sd
= (struct sd
*) gspca_dev
;
2100 static int sd_sethue(struct gspca_dev
*gspca_dev
, __s32 val
)
2102 struct sd
*sd
= (struct sd
*) gspca_dev
;
2105 if (gspca_dev
->streaming
)
2110 static int sd_gethue(struct gspca_dev
*gspca_dev
, __s32
*val
)
2112 struct sd
*sd
= (struct sd
*) gspca_dev
;
2118 static int sd_setautogain(struct gspca_dev
*gspca_dev
, __s32 val
)
2120 struct sd
*sd
= (struct sd
*) gspca_dev
;
2124 if (gspca_dev
->streaming
) {
2125 if (sd
->sensor
== SENSOR_OV772X
) {
2127 /* the auto white balance control works only
2128 * when auto gain is set */
2130 gspca_dev
->ctrl_inac
&= ~(1 << AWB_77_IDX
);
2132 gspca_dev
->ctrl_inac
|= (1 << AWB_77_IDX
);
2133 setautogain_77(gspca_dev
);
2136 gspca_dev
->ctrl_inac
|= (1 << EXPO_96_IDX
);
2138 gspca_dev
->ctrl_inac
&= ~(1 << EXPO_96_IDX
);
2139 setautogain_96(gspca_dev
);
2145 static int sd_getautogain(struct gspca_dev
*gspca_dev
, __s32
*val
)
2147 struct sd
*sd
= (struct sd
*) gspca_dev
;
2149 *val
= sd
->autogain
;
2153 static int sd_setawb(struct gspca_dev
*gspca_dev
, __s32 val
)
2155 struct sd
*sd
= (struct sd
*) gspca_dev
;
2158 if (gspca_dev
->streaming
)
2163 static int sd_getawb(struct gspca_dev
*gspca_dev
, __s32
*val
)
2165 struct sd
*sd
= (struct sd
*) gspca_dev
;
2171 static int sd_setsharpness(struct gspca_dev
*gspca_dev
, __s32 val
)
2173 struct sd
*sd
= (struct sd
*) gspca_dev
;
2175 sd
->sharpness
= val
;
2176 if (gspca_dev
->streaming
) {
2177 if (sd
->sensor
== SENSOR_OV772X
)
2178 setsharpness_77(gspca_dev
);
2180 setsharpness_96(gspca_dev
);
2185 static int sd_getsharpness(struct gspca_dev
*gspca_dev
, __s32
*val
)
2187 struct sd
*sd
= (struct sd
*) gspca_dev
;
2189 *val
= sd
->sharpness
;
2193 static int sd_sethflip(struct gspca_dev
*gspca_dev
, __s32 val
)
2195 struct sd
*sd
= (struct sd
*) gspca_dev
;
2198 if (gspca_dev
->streaming
)
2199 sethflip(gspca_dev
);
2203 static int sd_gethflip(struct gspca_dev
*gspca_dev
, __s32
*val
)
2205 struct sd
*sd
= (struct sd
*) gspca_dev
;
2211 static int sd_setvflip(struct gspca_dev
*gspca_dev
, __s32 val
)
2213 struct sd
*sd
= (struct sd
*) gspca_dev
;
2216 if (gspca_dev
->streaming
)
2217 setvflip(gspca_dev
);
2221 static int sd_getvflip(struct gspca_dev
*gspca_dev
, __s32
*val
)
2223 struct sd
*sd
= (struct sd
*) gspca_dev
;
2229 /* get stream parameters (framerate) */
2230 static int sd_get_streamparm(struct gspca_dev
*gspca_dev
,
2231 struct v4l2_streamparm
*parm
)
2233 struct v4l2_captureparm
*cp
= &parm
->parm
.capture
;
2234 struct v4l2_fract
*tpf
= &cp
->timeperframe
;
2235 struct sd
*sd
= (struct sd
*) gspca_dev
;
2237 if (parm
->type
!= V4L2_BUF_TYPE_VIDEO_CAPTURE
)
2240 cp
->capability
|= V4L2_CAP_TIMEPERFRAME
;
2242 tpf
->denominator
= sd
->frame_rate
;
2247 /* set stream parameters (framerate) */
2248 static int sd_set_streamparm(struct gspca_dev
*gspca_dev
,
2249 struct v4l2_streamparm
*parm
)
2251 struct v4l2_captureparm
*cp
= &parm
->parm
.capture
;
2252 struct v4l2_fract
*tpf
= &cp
->timeperframe
;
2253 struct sd
*sd
= (struct sd
*) gspca_dev
;
2255 if (parm
->type
!= V4L2_BUF_TYPE_VIDEO_CAPTURE
)
2258 /* Set requested framerate */
2259 sd
->frame_rate
= tpf
->denominator
/ tpf
->numerator
;
2260 if (gspca_dev
->streaming
&& sd
->sensor
== SENSOR_OV772X
)
2261 set_frame_rate(gspca_dev
);
2263 /* Return the actual framerate */
2265 tpf
->denominator
= sd
->frame_rate
;
2270 static int sd_querymenu(struct gspca_dev
*gspca_dev
,
2271 struct v4l2_querymenu
*menu
)
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");
2279 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
2280 strcpy((char *) menu
->name
, "50 Hz");
2282 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
2283 strcpy((char *) menu
->name
, "60 Hz");
2291 /* sub-driver description */
2292 static const struct sd_desc sd_desc_ov772x
= {
2293 .name
= MODULE_NAME
,
2294 .ctrls
= sd_ctrls_ov772x
,
2295 .nctrls
= ARRAY_SIZE(sd_ctrls_ov772x
),
2296 .config
= sd_config
,
2298 .start
= sd_start_ov772x
,
2299 .stopN
= sd_stopN_ov772x
,
2300 .pkt_scan
= sd_pkt_scan
,
2301 .get_streamparm
= sd_get_streamparm
,
2302 .set_streamparm
= sd_set_streamparm
,
2305 static const struct sd_desc sd_desc_ov965x
= {
2306 .name
= MODULE_NAME
,
2307 .ctrls
= sd_ctrls_ov965x
,
2308 .nctrls
= ARRAY_SIZE(sd_ctrls_ov965x
),
2309 .config
= sd_config
,
2311 .start
= sd_start_ov965x
,
2312 .stopN
= sd_stopN_ov965x
,
2313 .pkt_scan
= sd_pkt_scan
,
2314 .querymenu
= sd_querymenu
,
2317 /* -- module initialisation -- */
2318 static const __devinitdata
struct usb_device_id device_table
[] = {
2319 {USB_DEVICE(0x06f8, 0x3003), .driver_info
= SENSOR_OV965X
},
2320 {USB_DEVICE(0x1415, 0x2000), .driver_info
= SENSOR_OV772X
},
2324 MODULE_DEVICE_TABLE(usb
, device_table
);
2326 /* -- device connect -- */
2327 static int sd_probe(struct usb_interface
*intf
, const struct usb_device_id
*id
)
2329 return gspca_dev_probe(intf
, id
,
2330 id
->driver_info
== SENSOR_OV772X
2337 static struct usb_driver sd_driver
= {
2338 .name
= MODULE_NAME
,
2339 .id_table
= device_table
,
2341 .disconnect
= gspca_disconnect
,
2343 .suspend
= gspca_suspend
,
2344 .resume
= gspca_resume
,
2348 /* -- module insert / remove -- */
2349 static int __init
sd_mod_init(void)
2353 ret
= usb_register(&sd_driver
);
2356 PDEBUG(D_PROBE
, "registered");
2360 static void __exit
sd_mod_exit(void)
2362 usb_deregister(&sd_driver
);
2363 PDEBUG(D_PROBE
, "deregistered");
2366 module_init(sd_mod_init
);
2367 module_exit(sd_mod_exit
);