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
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 #define MODULE_NAME "ov534"
33 #define OV534_REG_ADDRESS 0xf1 /* sensor address */
34 #define OV534_REG_SUBADDR 0xf2
35 #define OV534_REG_WRITE 0xf3
36 #define OV534_REG_READ 0xf4
37 #define OV534_REG_OPERATION 0xf5
38 #define OV534_REG_STATUS 0xf6
40 #define OV534_OP_WRITE_3 0x37
41 #define OV534_OP_WRITE_2 0x33
42 #define OV534_OP_READ_2 0xf9
44 #define CTRL_TIMEOUT 500
46 MODULE_AUTHOR("Antonio Ospite <ospite@studenti.unina.it>");
47 MODULE_DESCRIPTION("GSPCA/OV534 USB Camera Driver");
48 MODULE_LICENSE("GPL");
50 /* specific webcam descriptor */
52 struct gspca_dev gspca_dev
; /* !! must be the first item */
66 #define SENSOR_OV772X 0
67 #define SENSOR_OV965X 1
70 /* V4L2 controls supported by the driver */
71 static int sd_setgain(struct gspca_dev
*gspca_dev
, __s32 val
);
72 static int sd_getgain(struct gspca_dev
*gspca_dev
, __s32
*val
);
73 static int sd_setexposure(struct gspca_dev
*gspca_dev
, __s32 val
);
74 static int sd_getexposure(struct gspca_dev
*gspca_dev
, __s32
*val
);
75 static int sd_setredblc(struct gspca_dev
*gspca_dev
, __s32 val
);
76 static int sd_getredblc(struct gspca_dev
*gspca_dev
, __s32
*val
);
77 static int sd_setblueblc(struct gspca_dev
*gspca_dev
, __s32 val
);
78 static int sd_getblueblc(struct gspca_dev
*gspca_dev
, __s32
*val
);
79 static int sd_setautogain(struct gspca_dev
*gspca_dev
, __s32 val
);
80 static int sd_getautogain(struct gspca_dev
*gspca_dev
, __s32
*val
);
81 static int sd_setsharpness(struct gspca_dev
*gspca_dev
, __s32 val
);
82 static int sd_getsharpness(struct gspca_dev
*gspca_dev
, __s32
*val
);
83 static int sd_sethflip(struct gspca_dev
*gspca_dev
, __s32 val
);
84 static int sd_gethflip(struct gspca_dev
*gspca_dev
, __s32
*val
);
85 static int sd_setvflip(struct gspca_dev
*gspca_dev
, __s32 val
);
86 static int sd_getvflip(struct gspca_dev
*gspca_dev
, __s32
*val
);
88 static struct ctrl sd_ctrls_ov772x
[] = {
92 .type
= V4L2_CTRL_TYPE_INTEGER
,
98 .default_value
= GAIN_DEF
,
105 .id
= V4L2_CID_EXPOSURE
,
106 .type
= V4L2_CTRL_TYPE_INTEGER
,
112 .default_value
= EXPO_DEF
,
114 .set
= sd_setexposure
,
115 .get
= sd_getexposure
,
119 .id
= V4L2_CID_RED_BALANCE
,
120 .type
= V4L2_CTRL_TYPE_INTEGER
,
121 .name
= "Red Balance",
125 #define RED_BALANCE_DEF 128
126 .default_value
= RED_BALANCE_DEF
,
133 .id
= V4L2_CID_BLUE_BALANCE
,
134 .type
= V4L2_CTRL_TYPE_INTEGER
,
135 .name
= "Blue Balance",
139 #define BLUE_BALANCE_DEF 128
140 .default_value
= BLUE_BALANCE_DEF
,
142 .set
= sd_setblueblc
,
143 .get
= sd_getblueblc
,
147 .id
= V4L2_CID_AUTOGAIN
,
148 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
153 #define AUTOGAIN_DEF 1
154 .default_value
= AUTOGAIN_DEF
,
156 .set
= sd_setautogain
,
157 .get
= sd_getautogain
,
161 .id
= V4L2_CID_SHARPNESS
,
162 .type
= V4L2_CTRL_TYPE_INTEGER
,
167 #define SHARPNESS_DEF 4
168 .default_value
= SHARPNESS_DEF
,
170 .set
= sd_setsharpness
,
171 .get
= sd_getsharpness
,
175 .id
= V4L2_CID_HFLIP
,
176 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
182 .default_value
= HFLIP_DEF
,
189 .id
= V4L2_CID_VFLIP
,
190 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
196 .default_value
= VFLIP_DEF
,
202 static struct ctrl sd_ctrls_ov965x
[] = {
205 static const struct v4l2_pix_format vga_yuyv_mode
[] = {
206 {320, 240, V4L2_PIX_FMT_YUYV
, V4L2_FIELD_NONE
,
207 .bytesperline
= 320 * 2,
208 .sizeimage
= 320 * 240 * 2,
209 .colorspace
= V4L2_COLORSPACE_JPEG
,
211 {640, 480, V4L2_PIX_FMT_YUYV
, V4L2_FIELD_NONE
,
212 .bytesperline
= 640 * 2,
213 .sizeimage
= 640 * 480 * 2,
214 .colorspace
= V4L2_COLORSPACE_SRGB
,
218 static const struct v4l2_pix_format vga_jpeg_mode
[] = {
219 {320, 240, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
221 .sizeimage
= 320 * 240 * 3 / 8 + 590,
222 .colorspace
= V4L2_COLORSPACE_JPEG
,
224 {640, 480, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
226 .sizeimage
= 640 * 480 * 3 / 8 + 590,
227 .colorspace
= V4L2_COLORSPACE_JPEG
,
230 static const u8 bridge_init_ov772x
[][2] = {
269 { 0x1d, 0x02 }, /* payload size 0x0200 * 4 = 2048 bytes */
270 { 0x1d, 0x00 }, /* payload size */
272 { 0x1d, 0x02 }, /* frame size 0x025800 * 4 = 614400 */
273 { 0x1d, 0x58 }, /* frame size */
274 { 0x1d, 0x00 }, /* frame size */
277 { 0x1d, 0x08 }, /* turn on UVC header */
278 { 0x1d, 0x0e }, /* .. */
288 static const u8 sensor_init_ov772x
[][2] = {
291 /*fixme: better have a delay?*/
314 { 0x63, 0xaa }, /* was e0 */
381 static const u8 bridge_start_ov772x_vga
[][2] = {
392 static const u8 sensor_start_ov772x_vga
[][2] = {
401 static const u8 bridge_start_ov772x_qvga
[][2] = {
412 static const u8 sensor_start_ov772x_qvga
[][2] = {
422 static const u8 bridge_init_ov965x
[][2] = {
456 static const u8 sensor_init_ov965x
[][2] = {
457 {0x12, 0x80}, /* com7 - SSCB reset */
458 {0x00, 0x00}, /* gain */
459 {0x01, 0x80}, /* blue */
460 {0x02, 0x80}, /* red */
461 {0x03, 0x1b}, /* vref */
462 {0x04, 0x03}, /* com1 - exposure low bits */
463 {0x0b, 0x57}, /* ver */
464 {0x0e, 0x61}, /* com5 */
465 {0x0f, 0x42}, /* com6 */
466 {0x11, 0x00}, /* clkrc */
467 {0x12, 0x02}, /* com7 - 15fps VGA YUYV */
468 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
469 {0x14, 0x28}, /* com9 */
470 {0x16, 0x24}, /* reg16 */
471 {0x17, 0x1d}, /* hstart*/
472 {0x18, 0xbd}, /* hstop */
473 {0x19, 0x01}, /* vstrt */
474 {0x1a, 0x81}, /* vstop*/
475 {0x1e, 0x04}, /* mvfp */
476 {0x24, 0x3c}, /* aew */
477 {0x25, 0x36}, /* aeb */
478 {0x26, 0x71}, /* vpt */
479 {0x27, 0x08}, /* bbias */
480 {0x28, 0x08}, /* gbbias */
481 {0x29, 0x15}, /* gr com */
482 {0x2a, 0x00}, /* exhch */
483 {0x2b, 0x00}, /* exhcl */
484 {0x2c, 0x08}, /* rbias */
485 {0x32, 0xff}, /* href */
486 {0x33, 0x00}, /* chlf */
487 {0x34, 0x3f}, /* aref1 */
488 {0x35, 0x00}, /* aref2 */
489 {0x36, 0xf8}, /* aref3 */
490 {0x38, 0x72}, /* adc2 */
491 {0x39, 0x57}, /* aref4 */
492 {0x3a, 0x80}, /* tslb - yuyv */
493 {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */
494 {0x3d, 0x99}, /* com13 */
495 {0x3f, 0xc1}, /* edge */
496 {0x40, 0xc0}, /* com15 */
497 {0x41, 0x40}, /* com16 */
498 {0x42, 0xc0}, /* com17 */
499 {0x43, 0x0a}, /* rsvd */
510 {0x4f, 0x98}, /* matrix */
516 {0x58, 0x1a}, /* matrix coef sign */
517 {0x59, 0x85}, /* AWB control */
523 {0x5f, 0xf0}, /* AWB blue limit */
524 {0x60, 0xf0}, /* AWB red limit */
525 {0x61, 0xf0}, /* AWB green limit */
526 {0x62, 0x00}, /* lcc1 */
527 {0x63, 0x00}, /* lcc2 */
528 {0x64, 0x02}, /* lcc3 */
529 {0x65, 0x16}, /* lcc4 */
530 {0x66, 0x01}, /* lcc5 */
531 {0x69, 0x02}, /* hv */
532 {0x6b, 0x5a}, /* dbvl */
537 {0x70, 0x21}, /* dnsth */
539 {0x72, 0x00}, /* poidx */
540 {0x73, 0x01}, /* pckdv */
541 {0x74, 0x3a}, /* xindx */
542 {0x75, 0x35}, /* yindx */
545 {0x7a, 0x12}, /* gamma curve */
562 {0x8c, 0x89}, /* com19 */
563 {0x14, 0x28}, /* com9 */
566 {0x9d, 0x03}, /* lcc6 */
567 {0x9e, 0x04}, /* lcc7 */
570 {0xa1, 0x40}, /* aechm */
571 {0xa4, 0x50}, /* com21 */
572 {0xa5, 0x68}, /* com26 */
573 {0xa6, 0x4a}, /* AWB green */
574 {0xa8, 0xc1}, /* refa8 */
575 {0xa9, 0xef}, /* refa9 */
578 {0xac, 0x80}, /* black level control */
584 {0xb4, 0x20}, /* ctrlb4 */
588 {0xbc, 0x7f}, /* ADC channel offsets */
597 {0xc7, 0x80}, /* com24 */
610 {0xff, 0x41}, /* read 41, write ff 00 */
611 {0x41, 0x40}, /* com16 */
612 {0xc5, 0x03}, /* 60 Hz banding filter */
613 {0x6a, 0x02}, /* 50 Hz banding filter */
615 {0x12, 0x62}, /* com7 - 30fps VGA YUV */
616 {0x36, 0xfa}, /* aref3 */
617 {0x69, 0x0a}, /* hv */
618 {0x8c, 0x89}, /* com22 */
619 {0x14, 0x28}, /* com9 */
621 {0x41, 0x40}, /* com16 */
628 {0x03, 0x12}, /* vref */
629 {0x17, 0x16}, /* hstart */
630 {0x18, 0x02}, /* hstop */
631 {0x19, 0x01}, /* vstrt */
632 {0x1a, 0x3d}, /* vstop */
633 {0x32, 0xff}, /* href */
637 static const u8 bridge_init_ov965x_2
[][2] = {
655 {0x55, 0x00}, /* brightness */
656 {0x57, 0x00}, /* contrast 2 */
665 static const u8 sensor_init_ov965x_2
[][2] = {
667 {0x1e, 0x04}, /* mvfp */
668 {0x13, 0xe0}, /* com8 */
669 {0x00, 0x00}, /* gain */
670 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
671 {0x11, 0x03}, /* clkrc */
672 {0x6b, 0x5a}, /* dblv */
678 {0xff, 0x42}, /* read 42, write ff 00 */
681 {0xff, 0x42}, /* read 42, write ff 00 */
684 {0xff, 0x42}, /* read 42, write ff 00 */
693 {0xff, 0x41}, /* read 41, write ff 00 */
694 {0x41, 0x40}, /* com16 */
697 {0x10, 0x25}, /* aech - exposure high bits */
698 {0xff, 0x13}, /* read 13, write ff 00 */
699 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
702 static const u8 sensor_start_ov965x
[][2] = {
703 {0x12, 0x62}, /* com7 - 30fps VGA YUV */
704 {0x36, 0xfa}, /* aref3 */
705 {0x69, 0x0a}, /* hv */
706 {0x8c, 0x89}, /* com22 */
707 {0x14, 0x28}, /* com9 */
708 {0x3e, 0x0c}, /* com14 */
709 {0x41, 0x40}, /* com16 */
715 {0xc7, 0x80}, /* com24 */
716 {0x03, 0x12}, /* vref */
717 {0x17, 0x16}, /* hstart */
718 {0x18, 0x02}, /* hstop */
719 {0x19, 0x01}, /* vstrt */
720 {0x1a, 0x3d}, /* vstop */
721 {0x32, 0xff}, /* href */
726 static const u8 bridge_start_ov965x
[][2] = {
738 static const u8 bridge_start_ov965x_vga
[][2] = {
758 static const u8 bridge_start_ov965x_cif
[][2] = {
778 static const u8 sensor_start_ov965x_vga
[][2] = {
779 {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */
780 {0x1e, 0x04}, /* mvfp */
781 {0x13, 0xe0}, /* com8 */
783 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
784 {0x11, 0x03}, /* clkrc */
785 {0x6b, 0x5a}, /* dblv */
786 {0x6a, 0x05}, /* 50 Hz banding filter */
787 {0xc5, 0x07}, /* 60 Hz banding filter */
788 {0xa2, 0x4b}, /* bd50 */
789 {0xa3, 0x3e}, /* bd60 */
791 {0x2d, 0x00}, /* advfl */
795 static const u8 sensor_start_ov965x_cif
[][2] = {
796 {0x3b, 0xe4}, /* com11 - night mode 1/4 frame rate */
797 {0x1e, 0x04}, /* mvfp */
798 {0x13, 0xe0}, /* com8 */
800 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
801 {0x11, 0x01}, /* clkrc */
802 {0x6b, 0x5a}, /* dblv */
803 {0x6a, 0x02}, /* 50 Hz banding filter */
804 {0xc5, 0x03}, /* 60 Hz banding filter */
805 {0xa2, 0x96}, /* bd50 */
806 {0xa3, 0x7d}, /* bd60 */
808 {0xff, 0x13}, /* read 13, write ff 00 */
810 {0x3a, 0x80}, /* tslb - yuyv */
814 static const u8 sensor_start_ov965x_2
[][2] = {
815 {0xff, 0x42}, /* read 42, write ff 00 */
816 {0x42, 0xc1}, /* com17 - 50 Hz filter */
821 static void ov534_reg_write(struct gspca_dev
*gspca_dev
, u16 reg
, u8 val
)
823 struct usb_device
*udev
= gspca_dev
->dev
;
826 PDEBUG(D_USBO
, "reg=0x%04x, val=0%02x", reg
, val
);
827 gspca_dev
->usb_buf
[0] = val
;
828 ret
= usb_control_msg(udev
,
829 usb_sndctrlpipe(udev
, 0),
831 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
832 0x00, reg
, gspca_dev
->usb_buf
, 1, CTRL_TIMEOUT
);
834 PDEBUG(D_ERR
, "write failed");
837 static u8
ov534_reg_read(struct gspca_dev
*gspca_dev
, u16 reg
)
839 struct usb_device
*udev
= gspca_dev
->dev
;
842 ret
= usb_control_msg(udev
,
843 usb_rcvctrlpipe(udev
, 0),
845 USB_DIR_IN
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
846 0x00, reg
, gspca_dev
->usb_buf
, 1, CTRL_TIMEOUT
);
847 PDEBUG(D_USBI
, "reg=0x%04x, data=0x%02x", reg
, gspca_dev
->usb_buf
[0]);
849 PDEBUG(D_ERR
, "read failed");
850 return gspca_dev
->usb_buf
[0];
853 /* Two bits control LED: 0x21 bit 7 and 0x23 bit 7.
854 * (direction and output)? */
855 static void ov534_set_led(struct gspca_dev
*gspca_dev
, int status
)
859 PDEBUG(D_CONF
, "led status: %d", status
);
861 data
= ov534_reg_read(gspca_dev
, 0x21);
863 ov534_reg_write(gspca_dev
, 0x21, data
);
865 data
= ov534_reg_read(gspca_dev
, 0x23);
871 ov534_reg_write(gspca_dev
, 0x23, data
);
874 data
= ov534_reg_read(gspca_dev
, 0x21);
876 ov534_reg_write(gspca_dev
, 0x21, data
);
880 static int sccb_check_status(struct gspca_dev
*gspca_dev
)
885 for (i
= 0; i
< 5; i
++) {
886 data
= ov534_reg_read(gspca_dev
, OV534_REG_STATUS
);
896 PDEBUG(D_ERR
, "sccb status 0x%02x, attempt %d/5",
903 static void sccb_reg_write(struct gspca_dev
*gspca_dev
, u8 reg
, u8 val
)
905 PDEBUG(D_USBO
, "reg: 0x%02x, val: 0x%02x", reg
, val
);
906 ov534_reg_write(gspca_dev
, OV534_REG_SUBADDR
, reg
);
907 ov534_reg_write(gspca_dev
, OV534_REG_WRITE
, val
);
908 ov534_reg_write(gspca_dev
, OV534_REG_OPERATION
, OV534_OP_WRITE_3
);
910 if (!sccb_check_status(gspca_dev
))
911 PDEBUG(D_ERR
, "sccb_reg_write failed");
914 static u8
sccb_reg_read(struct gspca_dev
*gspca_dev
, u16 reg
)
916 ov534_reg_write(gspca_dev
, OV534_REG_SUBADDR
, reg
);
917 ov534_reg_write(gspca_dev
, OV534_REG_OPERATION
, OV534_OP_WRITE_2
);
918 if (!sccb_check_status(gspca_dev
))
919 PDEBUG(D_ERR
, "sccb_reg_read failed 1");
921 ov534_reg_write(gspca_dev
, OV534_REG_OPERATION
, OV534_OP_READ_2
);
922 if (!sccb_check_status(gspca_dev
))
923 PDEBUG(D_ERR
, "sccb_reg_read failed 2");
925 return ov534_reg_read(gspca_dev
, OV534_REG_READ
);
928 /* output a bridge sequence (reg - val) */
929 static void reg_w_array(struct gspca_dev
*gspca_dev
,
930 const u8 (*data
)[2], int len
)
933 ov534_reg_write(gspca_dev
, (*data
)[0], (*data
)[1]);
938 /* output a sensor sequence (reg - val) */
939 static void sccb_w_array(struct gspca_dev
*gspca_dev
,
940 const u8 (*data
)[2], int len
)
943 if ((*data
)[0] != 0xff) {
944 sccb_reg_write(gspca_dev
, (*data
)[0], (*data
)[1]);
946 sccb_reg_read(gspca_dev
, (*data
)[1]);
947 sccb_reg_write(gspca_dev
, 0xff, 0x00);
954 static void ov534_set_frame_rate(struct gspca_dev
*gspca_dev
)
956 struct sd
*sd
= (struct sd
*) gspca_dev
;
964 const struct rate_s
*r
;
965 static const struct rate_s rate_0
[] = { /* 640x480 */
966 {60, 0x01, 0xc1, 0x04},
967 {50, 0x01, 0x41, 0x02},
968 {40, 0x02, 0xc1, 0x04},
969 {30, 0x04, 0x81, 0x02},
970 {15, 0x03, 0x41, 0x04},
972 static const struct rate_s rate_1
[] = { /* 320x240 */
973 {125, 0x02, 0x81, 0x02},
974 {100, 0x02, 0xc1, 0x04},
975 {75, 0x03, 0xc1, 0x04},
976 {60, 0x04, 0xc1, 0x04},
977 {50, 0x02, 0x41, 0x04},
978 {40, 0x03, 0x41, 0x04},
979 {30, 0x04, 0x41, 0x04},
982 if (gspca_dev
->cam
.cam_mode
[gspca_dev
->curr_mode
].priv
== 0) {
984 i
= ARRAY_SIZE(rate_0
);
987 i
= ARRAY_SIZE(rate_1
);
990 if (sd
->frame_rate
>= r
->fps
)
995 sccb_reg_write(gspca_dev
, 0x11, r
->r11
);
996 sccb_reg_write(gspca_dev
, 0x0d, r
->r0d
);
997 ov534_reg_write(gspca_dev
, 0xe5, r
->re5
);
999 PDEBUG(D_PROBE
, "frame_rate: %d", r
->fps
);
1002 /* ov772x controls */
1003 static void setgain(struct gspca_dev
*gspca_dev
)
1005 struct sd
*sd
= (struct sd
*) gspca_dev
;
1009 switch (val
& 0x30) {
1027 sccb_reg_write(gspca_dev
, 0x00, val
);
1030 static void setexposure(struct gspca_dev
*gspca_dev
)
1032 struct sd
*sd
= (struct sd
*) gspca_dev
;
1036 sccb_reg_write(gspca_dev
, 0x08, val
>> 7);
1037 sccb_reg_write(gspca_dev
, 0x10, val
<< 1);
1040 static void setredblc(struct gspca_dev
*gspca_dev
)
1042 struct sd
*sd
= (struct sd
*) gspca_dev
;
1044 sccb_reg_write(gspca_dev
, 0x43, sd
->redblc
);
1047 static void setblueblc(struct gspca_dev
*gspca_dev
)
1049 struct sd
*sd
= (struct sd
*) gspca_dev
;
1051 sccb_reg_write(gspca_dev
, 0x42, sd
->blueblc
);
1054 static void setautogain(struct gspca_dev
*gspca_dev
)
1056 struct sd
*sd
= (struct sd
*) gspca_dev
;
1059 sccb_reg_write(gspca_dev
, 0x13, 0xf7); /* AGC,AEC,AWB ON */
1060 sccb_reg_write(gspca_dev
, 0x64,
1061 sccb_reg_read(gspca_dev
, 0x64) | 0x03);
1063 sccb_reg_write(gspca_dev
, 0x13, 0xf0); /* AGC,AEC,AWB OFF */
1064 sccb_reg_write(gspca_dev
, 0x64,
1065 sccb_reg_read(gspca_dev
, 0x64) & 0xfc);
1069 static void setsharpness(struct gspca_dev
*gspca_dev
)
1071 struct sd
*sd
= (struct sd
*) gspca_dev
;
1074 val
= sd
->sharpness
;
1075 sccb_reg_write(gspca_dev
, 0x91, val
); /* vga noise */
1076 sccb_reg_write(gspca_dev
, 0x8e, val
); /* qvga noise */
1079 static void sethflip(struct gspca_dev
*gspca_dev
)
1081 struct sd
*sd
= (struct sd
*) gspca_dev
;
1084 sccb_reg_write(gspca_dev
, 0x0c,
1085 sccb_reg_read(gspca_dev
, 0x0c) | 0x40);
1087 sccb_reg_write(gspca_dev
, 0x0c,
1088 sccb_reg_read(gspca_dev
, 0x0c) & 0xbf);
1091 static void setvflip(struct gspca_dev
*gspca_dev
)
1093 struct sd
*sd
= (struct sd
*) gspca_dev
;
1096 sccb_reg_write(gspca_dev
, 0x0c,
1097 sccb_reg_read(gspca_dev
, 0x0c) | 0x80);
1099 sccb_reg_write(gspca_dev
, 0x0c,
1100 sccb_reg_read(gspca_dev
, 0x0c) & 0x7f);
1103 /* this function is called at probe time */
1104 static int sd_config(struct gspca_dev
*gspca_dev
,
1105 const struct usb_device_id
*id
)
1107 struct sd
*sd
= (struct sd
*) gspca_dev
;
1110 sd
->sensor
= id
->driver_info
;
1112 cam
= &gspca_dev
->cam
;
1114 if (sd
->sensor
== SENSOR_OV772X
) {
1115 cam
->cam_mode
= vga_yuyv_mode
;
1116 cam
->nmodes
= ARRAY_SIZE(vga_yuyv_mode
);
1119 cam
->bulk_size
= 16384;
1120 cam
->bulk_nurbs
= 2;
1121 } else { /* ov965x */
1122 cam
->cam_mode
= vga_jpeg_mode
;
1123 cam
->nmodes
= ARRAY_SIZE(vga_jpeg_mode
);
1126 sd
->frame_rate
= 30;
1127 sd
->gain
= GAIN_DEF
;
1128 sd
->exposure
= EXPO_DEF
;
1129 sd
->redblc
= RED_BALANCE_DEF
;
1130 sd
->blueblc
= BLUE_BALANCE_DEF
;
1131 sd
->autogain
= AUTOGAIN_DEF
;
1132 sd
->sharpness
= SHARPNESS_DEF
;
1134 sd
->hflip
= HFLIP_DEF
;
1137 sd
->vflip
= VFLIP_DEF
;
1142 /* this function is called at probe and resume time */
1143 static int sd_init(struct gspca_dev
*gspca_dev
)
1145 struct sd
*sd
= (struct sd
*) gspca_dev
;
1147 static const u8 sensor_addr
[2] = {
1148 0x42, /* 0 SENSOR_OV772X */
1149 0x60, /* 1 SENSOR_OV965X */
1153 ov534_reg_write(gspca_dev
, 0xe7, 0x3a);
1154 ov534_reg_write(gspca_dev
, 0xe0, 0x08);
1157 /* initialize the sensor address */
1158 ov534_reg_write(gspca_dev
, OV534_REG_ADDRESS
,
1159 sensor_addr
[sd
->sensor
]);
1162 sccb_reg_write(gspca_dev
, 0x12, 0x80);
1165 /* probe the sensor */
1166 sccb_reg_read(gspca_dev
, 0x0a);
1167 sensor_id
= sccb_reg_read(gspca_dev
, 0x0a) << 8;
1168 sccb_reg_read(gspca_dev
, 0x0b);
1169 sensor_id
|= sccb_reg_read(gspca_dev
, 0x0b);
1170 PDEBUG(D_PROBE
, "Sensor ID: %04x", sensor_id
);
1173 switch (sd
->sensor
) {
1175 reg_w_array(gspca_dev
, bridge_init_ov772x
,
1176 ARRAY_SIZE(bridge_init_ov772x
));
1177 ov534_set_led(gspca_dev
, 1);
1178 sccb_w_array(gspca_dev
, sensor_init_ov772x
,
1179 ARRAY_SIZE(sensor_init_ov772x
));
1180 ov534_reg_write(gspca_dev
, 0xe0, 0x09);
1181 ov534_set_led(gspca_dev
, 0);
1182 ov534_set_frame_rate(gspca_dev
);
1185 /* case SENSOR_OV965X: */
1186 reg_w_array(gspca_dev
, bridge_init_ov965x
,
1187 ARRAY_SIZE(bridge_init_ov965x
));
1188 sccb_w_array(gspca_dev
, sensor_init_ov965x
,
1189 ARRAY_SIZE(sensor_init_ov965x
));
1190 reg_w_array(gspca_dev
, bridge_init_ov965x_2
,
1191 ARRAY_SIZE(bridge_init_ov965x_2
));
1192 sccb_w_array(gspca_dev
, sensor_init_ov965x_2
,
1193 ARRAY_SIZE(sensor_init_ov965x_2
));
1194 ov534_reg_write(gspca_dev
, 0xe0, 0x00);
1195 ov534_reg_write(gspca_dev
, 0xe0, 0x01);
1196 ov534_set_led(gspca_dev
, 0);
1197 ov534_reg_write(gspca_dev
, 0xe0, 0x00);
1203 static int sd_start_ov772x(struct gspca_dev
*gspca_dev
)
1207 mode
= gspca_dev
->cam
.cam_mode
[gspca_dev
->curr_mode
].priv
;
1208 if (mode
!= 0) { /* 320x240 */
1209 reg_w_array(gspca_dev
, bridge_start_ov772x_qvga
,
1210 ARRAY_SIZE(bridge_start_ov772x_qvga
));
1211 sccb_w_array(gspca_dev
, sensor_start_ov772x_qvga
,
1212 ARRAY_SIZE(sensor_start_ov772x_qvga
));
1213 } else { /* 640x480 */
1214 reg_w_array(gspca_dev
, bridge_start_ov772x_vga
,
1215 ARRAY_SIZE(bridge_start_ov772x_vga
));
1216 sccb_w_array(gspca_dev
, sensor_start_ov772x_vga
,
1217 ARRAY_SIZE(sensor_start_ov772x_vga
));
1219 ov534_set_frame_rate(gspca_dev
);
1221 setautogain(gspca_dev
);
1223 setredblc(gspca_dev
);
1224 setblueblc(gspca_dev
);
1225 setexposure(gspca_dev
);
1226 setsharpness(gspca_dev
);
1227 setvflip(gspca_dev
);
1228 sethflip(gspca_dev
);
1230 ov534_set_led(gspca_dev
, 1);
1231 ov534_reg_write(gspca_dev
, 0xe0, 0x00);
1235 static int sd_start_ov965x(struct gspca_dev
*gspca_dev
)
1239 sccb_w_array(gspca_dev
, sensor_start_ov965x
,
1240 ARRAY_SIZE(sensor_start_ov965x
));
1241 reg_w_array(gspca_dev
, bridge_start_ov965x
,
1242 ARRAY_SIZE(bridge_start_ov965x
));
1244 mode
= gspca_dev
->cam
.cam_mode
[gspca_dev
->curr_mode
].priv
;
1245 if (mode
!= 0) { /* 320x240 */
1246 reg_w_array(gspca_dev
, bridge_start_ov965x_cif
,
1247 ARRAY_SIZE(bridge_start_ov965x_cif
));
1248 sccb_w_array(gspca_dev
, sensor_start_ov965x_cif
,
1249 ARRAY_SIZE(sensor_start_ov965x_cif
));
1250 } else { /* 640x480 */
1251 reg_w_array(gspca_dev
, bridge_start_ov965x_vga
,
1252 ARRAY_SIZE(bridge_start_ov965x_vga
));
1253 sccb_w_array(gspca_dev
, sensor_start_ov965x_vga
,
1254 ARRAY_SIZE(sensor_start_ov965x_vga
));
1256 sccb_w_array(gspca_dev
, sensor_start_ov965x_2
,
1257 ARRAY_SIZE(sensor_start_ov965x_2
));
1258 ov534_reg_write(gspca_dev
, 0xe0, 0x00);
1259 ov534_reg_write(gspca_dev
, 0xe0, 0x00);
1260 ov534_set_led(gspca_dev
, 1);
1264 static void sd_stopN_ov772x(struct gspca_dev
*gspca_dev
)
1266 ov534_reg_write(gspca_dev
, 0xe0, 0x09);
1267 ov534_set_led(gspca_dev
, 0);
1270 static void sd_stopN_ov965x(struct gspca_dev
*gspca_dev
)
1272 ov534_reg_write(gspca_dev
, 0xe0, 0x01);
1273 ov534_set_led(gspca_dev
, 0);
1274 ov534_reg_write(gspca_dev
, 0xe0, 0x00);
1277 /* Values for bmHeaderInfo (Video and Still Image Payload Headers, 2.4.3.3) */
1278 #define UVC_STREAM_EOH (1 << 7)
1279 #define UVC_STREAM_ERR (1 << 6)
1280 #define UVC_STREAM_STI (1 << 5)
1281 #define UVC_STREAM_RES (1 << 4)
1282 #define UVC_STREAM_SCR (1 << 3)
1283 #define UVC_STREAM_PTS (1 << 2)
1284 #define UVC_STREAM_EOF (1 << 1)
1285 #define UVC_STREAM_FID (1 << 0)
1287 static void sd_pkt_scan(struct gspca_dev
*gspca_dev
, struct gspca_frame
*frame
,
1288 __u8
*data
, int len
)
1290 struct sd
*sd
= (struct sd
*) gspca_dev
;
1293 int remaining_len
= len
;
1296 payload_len
= gspca_dev
->cam
.bulk
? 2048 : 2040;
1298 len
= min(remaining_len
, payload_len
);
1300 /* Payloads are prefixed with a UVC-style header. We
1301 consider a frame to start when the FID toggles, or the PTS
1302 changes. A frame ends when EOF is set, and we've received
1303 the correct number of bytes. */
1305 /* Verify UVC header. Header length is always 12 */
1306 if (data
[0] != 12 || len
< 12) {
1307 PDEBUG(D_PACK
, "bad header");
1312 if (data
[1] & UVC_STREAM_ERR
) {
1313 PDEBUG(D_PACK
, "payload error");
1317 /* Extract PTS and FID */
1318 if (!(data
[1] & UVC_STREAM_PTS
)) {
1319 PDEBUG(D_PACK
, "PTS not present");
1322 this_pts
= (data
[5] << 24) | (data
[4] << 16)
1323 | (data
[3] << 8) | data
[2];
1324 this_fid
= (data
[1] & UVC_STREAM_FID
) ? 1 : 0;
1326 /* If PTS or FID has changed, start a new frame. */
1327 if (this_pts
!= sd
->last_pts
|| this_fid
!= sd
->last_fid
) {
1328 if (gspca_dev
->last_packet_type
== INTER_PACKET
)
1329 frame
= gspca_frame_add(gspca_dev
,
1332 sd
->last_pts
= this_pts
;
1333 sd
->last_fid
= this_fid
;
1334 gspca_frame_add(gspca_dev
, FIRST_PACKET
, frame
,
1335 data
+ 12, len
- 12);
1336 /* If this packet is marked as EOF, end the frame */
1337 } else if (data
[1] & UVC_STREAM_EOF
) {
1339 frame
= gspca_frame_add(gspca_dev
, LAST_PACKET
, frame
,
1340 data
+ 12, len
- 12);
1343 /* Add the data from this payload */
1344 gspca_frame_add(gspca_dev
, INTER_PACKET
, frame
,
1345 data
+ 12, len
- 12);
1348 /* Done this payload */
1352 /* Discard data until a new frame starts. */
1353 gspca_frame_add(gspca_dev
, DISCARD_PACKET
, frame
, NULL
, 0);
1356 remaining_len
-= len
;
1358 } while (remaining_len
> 0);
1361 /* ov772x controls */
1362 static int sd_setgain(struct gspca_dev
*gspca_dev
, __s32 val
)
1364 struct sd
*sd
= (struct sd
*) gspca_dev
;
1367 if (gspca_dev
->streaming
)
1372 static int sd_getgain(struct gspca_dev
*gspca_dev
, __s32
*val
)
1374 struct sd
*sd
= (struct sd
*) gspca_dev
;
1380 static int sd_setexposure(struct gspca_dev
*gspca_dev
, __s32 val
)
1382 struct sd
*sd
= (struct sd
*) gspca_dev
;
1385 if (gspca_dev
->streaming
)
1386 setexposure(gspca_dev
);
1390 static int sd_getexposure(struct gspca_dev
*gspca_dev
, __s32
*val
)
1392 struct sd
*sd
= (struct sd
*) gspca_dev
;
1394 *val
= sd
->exposure
;
1398 static int sd_setredblc(struct gspca_dev
*gspca_dev
, __s32 val
)
1400 struct sd
*sd
= (struct sd
*) gspca_dev
;
1403 if (gspca_dev
->streaming
)
1404 setredblc(gspca_dev
);
1408 static int sd_getredblc(struct gspca_dev
*gspca_dev
, __s32
*val
)
1410 struct sd
*sd
= (struct sd
*) gspca_dev
;
1416 static int sd_setblueblc(struct gspca_dev
*gspca_dev
, __s32 val
)
1418 struct sd
*sd
= (struct sd
*) gspca_dev
;
1421 if (gspca_dev
->streaming
)
1422 setblueblc(gspca_dev
);
1426 static int sd_getblueblc(struct gspca_dev
*gspca_dev
, __s32
*val
)
1428 struct sd
*sd
= (struct sd
*) gspca_dev
;
1434 static int sd_setautogain(struct gspca_dev
*gspca_dev
, __s32 val
)
1436 struct sd
*sd
= (struct sd
*) gspca_dev
;
1439 if (gspca_dev
->streaming
)
1440 setautogain(gspca_dev
);
1444 static int sd_getautogain(struct gspca_dev
*gspca_dev
, __s32
*val
)
1446 struct sd
*sd
= (struct sd
*) gspca_dev
;
1448 *val
= sd
->autogain
;
1452 static int sd_setsharpness(struct gspca_dev
*gspca_dev
, __s32 val
)
1454 struct sd
*sd
= (struct sd
*) gspca_dev
;
1456 sd
->sharpness
= val
;
1457 if (gspca_dev
->streaming
)
1458 setsharpness(gspca_dev
);
1462 static int sd_getsharpness(struct gspca_dev
*gspca_dev
, __s32
*val
)
1464 struct sd
*sd
= (struct sd
*) gspca_dev
;
1466 *val
= sd
->sharpness
;
1470 static int sd_sethflip(struct gspca_dev
*gspca_dev
, __s32 val
)
1472 struct sd
*sd
= (struct sd
*) gspca_dev
;
1475 if (gspca_dev
->streaming
)
1476 sethflip(gspca_dev
);
1480 static int sd_gethflip(struct gspca_dev
*gspca_dev
, __s32
*val
)
1482 struct sd
*sd
= (struct sd
*) gspca_dev
;
1488 static int sd_setvflip(struct gspca_dev
*gspca_dev
, __s32 val
)
1490 struct sd
*sd
= (struct sd
*) gspca_dev
;
1493 if (gspca_dev
->streaming
)
1494 setvflip(gspca_dev
);
1498 static int sd_getvflip(struct gspca_dev
*gspca_dev
, __s32
*val
)
1500 struct sd
*sd
= (struct sd
*) gspca_dev
;
1506 /* get stream parameters (framerate) */
1507 static int sd_get_streamparm(struct gspca_dev
*gspca_dev
,
1508 struct v4l2_streamparm
*parm
)
1510 struct v4l2_captureparm
*cp
= &parm
->parm
.capture
;
1511 struct v4l2_fract
*tpf
= &cp
->timeperframe
;
1512 struct sd
*sd
= (struct sd
*) gspca_dev
;
1514 if (parm
->type
!= V4L2_BUF_TYPE_VIDEO_CAPTURE
)
1517 cp
->capability
|= V4L2_CAP_TIMEPERFRAME
;
1519 tpf
->denominator
= sd
->frame_rate
;
1524 /* set stream parameters (framerate) */
1525 static int sd_set_streamparm(struct gspca_dev
*gspca_dev
,
1526 struct v4l2_streamparm
*parm
)
1528 struct v4l2_captureparm
*cp
= &parm
->parm
.capture
;
1529 struct v4l2_fract
*tpf
= &cp
->timeperframe
;
1530 struct sd
*sd
= (struct sd
*) gspca_dev
;
1532 if (parm
->type
!= V4L2_BUF_TYPE_VIDEO_CAPTURE
)
1535 /* Set requested framerate */
1536 sd
->frame_rate
= tpf
->denominator
/ tpf
->numerator
;
1537 if (gspca_dev
->streaming
)
1538 ov534_set_frame_rate(gspca_dev
);
1540 /* Return the actual framerate */
1542 tpf
->denominator
= sd
->frame_rate
;
1547 /* sub-driver description */
1548 static const struct sd_desc sd_desc_ov772x
= {
1549 .name
= MODULE_NAME
,
1550 .ctrls
= sd_ctrls_ov772x
,
1551 .nctrls
= ARRAY_SIZE(sd_ctrls_ov772x
),
1552 .config
= sd_config
,
1554 .start
= sd_start_ov772x
,
1555 .stopN
= sd_stopN_ov772x
,
1556 .pkt_scan
= sd_pkt_scan
,
1557 .get_streamparm
= sd_get_streamparm
,
1558 .set_streamparm
= sd_set_streamparm
,
1561 static const struct sd_desc sd_desc_ov965x
= {
1562 .name
= MODULE_NAME
,
1563 .ctrls
= sd_ctrls_ov965x
,
1564 .nctrls
= ARRAY_SIZE(sd_ctrls_ov965x
),
1565 .config
= sd_config
,
1567 .start
= sd_start_ov965x
,
1568 .stopN
= sd_stopN_ov965x
,
1569 .pkt_scan
= sd_pkt_scan
,
1570 .get_streamparm
= sd_get_streamparm
,
1571 .set_streamparm
= sd_set_streamparm
,
1574 /* -- module initialisation -- */
1575 static const __devinitdata
struct usb_device_id device_table
[] = {
1576 {USB_DEVICE(0x06f8, 0x3003), .driver_info
= SENSOR_OV965X
},
1577 {USB_DEVICE(0x1415, 0x2000), .driver_info
= SENSOR_OV772X
},
1581 MODULE_DEVICE_TABLE(usb
, device_table
);
1583 /* -- device connect -- */
1584 static int sd_probe(struct usb_interface
*intf
, const struct usb_device_id
*id
)
1586 return gspca_dev_probe(intf
, id
,
1587 id
->driver_info
== SENSOR_OV772X
1594 static struct usb_driver sd_driver
= {
1595 .name
= MODULE_NAME
,
1596 .id_table
= device_table
,
1598 .disconnect
= gspca_disconnect
,
1600 .suspend
= gspca_suspend
,
1601 .resume
= gspca_resume
,
1605 /* -- module insert / remove -- */
1606 static int __init
sd_mod_init(void)
1610 ret
= usb_register(&sd_driver
);
1613 PDEBUG(D_PROBE
, "registered");
1617 static void __exit
sd_mod_exit(void)
1619 usb_deregister(&sd_driver
);
1620 PDEBUG(D_PROBE
, "deregistered");
1623 module_init(sd_mod_init
);
1624 module_exit(sd_mod_exit
);