aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean-Francois Moine <moinejf@free.fr>2009-11-11 05:46:28 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-12-05 15:41:49 -0500
commit189d92af707ead6aa4a3e14511662462e8e956e2 (patch)
tree8961adac8c132f12788f023a4a6f54ff889e3969
parent4bdf4a8342ca01ff794f5de8f9766cf15947a2ef (diff)
V4L/DVB (13422): gspca - ov534: ov772x changes from Richard Kaswy.
- 320x240 resolution added - controls added - different sd_desc tables Signed-off-by: Jean-Francois Moine <moinejf@free.fr> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/video/gspca/ov534.c676
1 files changed, 591 insertions, 85 deletions
diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c
index 4b528b372911..fa28316c06ed 100644
--- a/drivers/media/video/gspca/ov534.c
+++ b/drivers/media/video/gspca/ov534.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * ov534 gspca driver 2 * ov534 gspca driver
3 *
3 * Copyright (C) 2008 Antonio Ospite <ospite@studenti.unina.it> 4 * Copyright (C) 2008 Antonio Ospite <ospite@studenti.unina.it>
4 * Copyright (C) 2008 Jim Paris <jim@jtan.com> 5 * Copyright (C) 2008 Jim Paris <jim@jtan.com>
5 * Copyright (C) 2009 Jean-Francois Moine http://moinejf.free.fr 6 * Copyright (C) 2009 Jean-Francois Moine http://moinejf.free.fr
@@ -8,6 +9,8 @@
8 * USB protocol reverse engineered by Jim Paris <jim@jtan.com> 9 * USB protocol reverse engineered by Jim Paris <jim@jtan.com>
9 * https://jim.sh/svn/jim/devl/playstation/ps3/eye/test/ 10 * https://jim.sh/svn/jim/devl/playstation/ps3/eye/test/
10 * 11 *
12 * PS3 Eye camera enhanced by Richard Kaswy http://kaswy.free.fr
13 *
11 * This program is free software; you can redistribute it and/or modify 14 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by 15 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or 16 * the Free Software Foundation; either version 2 of the License, or
@@ -50,6 +53,14 @@ struct sd {
50 __u32 last_pts; 53 __u32 last_pts;
51 u16 last_fid; 54 u16 last_fid;
52 u8 frame_rate; 55 u8 frame_rate;
56 u8 gain;
57 u8 exposure;
58 u8 redblc;
59 u8 blueblc;
60 u8 autogain;
61 u8 sharpness;
62 u8 hflip;
63 u8 vflip;
53 64
54 u8 sensor; 65 u8 sensor;
55#define SENSOR_OV772X 0 66#define SENSOR_OV772X 0
@@ -57,10 +68,146 @@ struct sd {
57}; 68};
58 69
59/* V4L2 controls supported by the driver */ 70/* V4L2 controls supported by the driver */
60static struct ctrl sd_ctrls[] = { 71static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
72static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
73static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
74static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
75static int sd_setredblc(struct gspca_dev *gspca_dev, __s32 val);
76static int sd_getredblc(struct gspca_dev *gspca_dev, __s32 *val);
77static int sd_setblueblc(struct gspca_dev *gspca_dev, __s32 val);
78static int sd_getblueblc(struct gspca_dev *gspca_dev, __s32 *val);
79static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
80static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
81static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
82static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
83static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
84static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val);
85static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
86static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
87
88static struct ctrl sd_ctrls_ov772x[] = {
89 {
90 {
91 .id = V4L2_CID_GAIN,
92 .type = V4L2_CTRL_TYPE_INTEGER,
93 .name = "Main Gain",
94 .minimum = 0,
95 .maximum = 63,
96 .step = 1,
97#define GAIN_DEF 20
98 .default_value = GAIN_DEF,
99 },
100 .set = sd_setgain,
101 .get = sd_getgain,
102 },
103 {
104 {
105 .id = V4L2_CID_EXPOSURE,
106 .type = V4L2_CTRL_TYPE_INTEGER,
107 .name = "Exposure",
108 .minimum = 0,
109 .maximum = 255,
110 .step = 1,
111#define EXPO_DEF 255
112 .default_value = EXPO_DEF,
113 },
114 .set = sd_setexposure,
115 .get = sd_getexposure,
116 },
117 {
118 {
119 .id = V4L2_CID_RED_BALANCE,
120 .type = V4L2_CTRL_TYPE_INTEGER,
121 .name = "Red Balance",
122 .minimum = 0,
123 .maximum = 255,
124 .step = 1,
125#define RED_BALANCE_DEF 128
126 .default_value = RED_BALANCE_DEF,
127 },
128 .set = sd_setredblc,
129 .get = sd_getredblc,
130 },
131 {
132 {
133 .id = V4L2_CID_BLUE_BALANCE,
134 .type = V4L2_CTRL_TYPE_INTEGER,
135 .name = "Blue Balance",
136 .minimum = 0,
137 .maximum = 255,
138 .step = 1,
139#define BLUE_BALANCE_DEF 128
140 .default_value = BLUE_BALANCE_DEF,
141 },
142 .set = sd_setblueblc,
143 .get = sd_getblueblc,
144 },
145 {
146 {
147 .id = V4L2_CID_AUTOGAIN,
148 .type = V4L2_CTRL_TYPE_BOOLEAN,
149 .name = "Autogain",
150 .minimum = 0,
151 .maximum = 1,
152 .step = 1,
153#define AUTOGAIN_DEF 1
154 .default_value = AUTOGAIN_DEF,
155 },
156 .set = sd_setautogain,
157 .get = sd_getautogain,
158 },
159 {
160 {
161 .id = V4L2_CID_SHARPNESS,
162 .type = V4L2_CTRL_TYPE_INTEGER,
163 .name = "Sharpness",
164 .minimum = 0,
165 .maximum = 63,
166 .step = 1,
167#define SHARPNESS_DEF 4
168 .default_value = SHARPNESS_DEF,
169 },
170 .set = sd_setsharpness,
171 .get = sd_getsharpness,
172 },
173 {
174 {
175 .id = V4L2_CID_HFLIP,
176 .type = V4L2_CTRL_TYPE_BOOLEAN,
177 .name = "HFlip",
178 .minimum = 0,
179 .maximum = 1,
180 .step = 1,
181#define HFLIP_DEF 0
182 .default_value = HFLIP_DEF,
183 },
184 .set = sd_sethflip,
185 .get = sd_gethflip,
186 },
187 {
188 {
189 .id = V4L2_CID_VFLIP,
190 .type = V4L2_CTRL_TYPE_BOOLEAN,
191 .name = "VFlip",
192 .minimum = 0,
193 .maximum = 1,
194 .step = 1,
195#define VFLIP_DEF 0
196 .default_value = VFLIP_DEF,
197 },
198 .set = sd_setvflip,
199 .get = sd_getvflip,
200 },
201};
202static struct ctrl sd_ctrls_ov965x[] = {
61}; 203};
62 204
63static const struct v4l2_pix_format vga_yuyv_mode[] = { 205static 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,
210 .priv = 1},
64 {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, 211 {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
65 .bytesperline = 640 * 2, 212 .bytesperline = 640 * 2,
66 .sizeimage = 640 * 480 * 2, 213 .sizeimage = 640 * 480 * 2,
@@ -80,8 +227,7 @@ static const struct v4l2_pix_format vga_jpeg_mode[] = {
80 .colorspace = V4L2_COLORSPACE_JPEG, 227 .colorspace = V4L2_COLORSPACE_JPEG,
81 .priv = 0}, 228 .priv = 0},
82}; 229};
83 230static const u8 bridge_init_ov772x[][2] = {
84static const u8 bridge_init_ov722x[][2] = {
85 { 0xc2, 0x0c }, 231 { 0xc2, 0x0c },
86 { 0x88, 0xf8 }, 232 { 0x88, 0xf8 },
87 { 0xc3, 0x69 }, 233 { 0xc3, 0x69 },
@@ -122,6 +268,7 @@ static const u8 bridge_init_ov722x[][2] = {
122 { 0x1d, 0x40 }, 268 { 0x1d, 0x40 },
123 { 0x1d, 0x02 }, /* payload size 0x0200 * 4 = 2048 bytes */ 269 { 0x1d, 0x02 }, /* payload size 0x0200 * 4 = 2048 bytes */
124 { 0x1d, 0x00 }, /* payload size */ 270 { 0x1d, 0x00 }, /* payload size */
271
125 { 0x1d, 0x02 }, /* frame size 0x025800 * 4 = 614400 */ 272 { 0x1d, 0x02 }, /* frame size 0x025800 * 4 = 614400 */
126 { 0x1d, 0x58 }, /* frame size */ 273 { 0x1d, 0x58 }, /* frame size */
127 { 0x1d, 0x00 }, /* frame size */ 274 { 0x1d, 0x00 }, /* frame size */
@@ -138,10 +285,20 @@ static const u8 bridge_init_ov722x[][2] = {
138 { 0xc1, 0x3c }, 285 { 0xc1, 0x3c },
139 { 0xc2, 0x0c }, 286 { 0xc2, 0x0c },
140}; 287};
141 288static const u8 sensor_init_ov772x[][2] = {
142static const u8 sensor_init_ov722x[][2] = {
143 { 0x12, 0x80 }, 289 { 0x12, 0x80 },
144 { 0x11, 0x01 }, 290 { 0x11, 0x01 },
291/*fixme: better have a delay?*/
292 { 0x11, 0x01 },
293 { 0x11, 0x01 },
294 { 0x11, 0x01 },
295 { 0x11, 0x01 },
296 { 0x11, 0x01 },
297 { 0x11, 0x01 },
298 { 0x11, 0x01 },
299 { 0x11, 0x01 },
300 { 0x11, 0x01 },
301 { 0x11, 0x01 },
145 302
146 { 0x3d, 0x03 }, 303 { 0x3d, 0x03 },
147 { 0x17, 0x26 }, 304 { 0x17, 0x26 },
@@ -154,7 +311,7 @@ static const u8 sensor_init_ov722x[][2] = {
154 { 0x65, 0x20 }, 311 { 0x65, 0x20 },
155 { 0x11, 0x01 }, 312 { 0x11, 0x01 },
156 { 0x42, 0x7f }, 313 { 0x42, 0x7f },
157 { 0x63, 0xe0 }, 314 { 0x63, 0xaa }, /* was e0 */
158 { 0x64, 0xff }, 315 { 0x64, 0xff },
159 { 0x66, 0x00 }, 316 { 0x66, 0x00 },
160 { 0x13, 0xf0 }, 317 { 0x13, 0xf0 },
@@ -221,6 +378,46 @@ static const u8 sensor_init_ov722x[][2] = {
221 { 0x8e, 0x00 }, 378 { 0x8e, 0x00 },
222 { 0x0c, 0xd0 } 379 { 0x0c, 0xd0 }
223}; 380};
381static const u8 bridge_start_ov772x_vga[][2] = {
382 {0x1c, 0x00},
383 {0x1d, 0x40},
384 {0x1d, 0x02},
385 {0x1d, 0x00},
386 {0x1d, 0x02},
387 {0x1d, 0x58},
388 {0x1d, 0x00},
389 {0xc0, 0x50},
390 {0xc1, 0x3c},
391};
392static const u8 sensor_start_ov772x_vga[][2] = {
393 {0x12, 0x00},
394 {0x17, 0x26},
395 {0x18, 0xa0},
396 {0x19, 0x07},
397 {0x1a, 0xf0},
398 {0x29, 0xa0},
399 {0x2c, 0xf0},
400};
401static const u8 bridge_start_ov772x_qvga[][2] = {
402 {0x1c, 0x00},
403 {0x1d, 0x40},
404 {0x1d, 0x02},
405 {0x1d, 0x00},
406 {0x1d, 0x01},
407 {0x1d, 0x4b},
408 {0x1d, 0x00},
409 {0xc0, 0x28},
410 {0xc1, 0x1e},
411};
412static const u8 sensor_start_ov772x_qvga[][2] = {
413 {0x12, 0x40},
414 {0x17, 0x3f},
415 {0x18, 0x50},
416 {0x19, 0x03},
417 {0x1a, 0x78},
418 {0x29, 0x50},
419 {0x2c, 0x78},
420};
224 421
225static const u8 bridge_init_ov965x[][2] = { 422static const u8 bridge_init_ov965x[][2] = {
226 {0x88, 0xf8}, 423 {0x88, 0xf8},
@@ -757,35 +954,150 @@ static void sccb_w_array(struct gspca_dev *gspca_dev,
757static void ov534_set_frame_rate(struct gspca_dev *gspca_dev) 954static void ov534_set_frame_rate(struct gspca_dev *gspca_dev)
758{ 955{
759 struct sd *sd = (struct sd *) gspca_dev; 956 struct sd *sd = (struct sd *) gspca_dev;
760 int fr = sd->frame_rate; 957 int i;
958 struct rate_s {
959 u8 fps;
960 u8 r11;
961 u8 r0d;
962 u8 re5;
963 };
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},
971 };
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},
980 };
981
982 if (gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv == 0) {
983 r = rate_0;
984 i = ARRAY_SIZE(rate_0);
985 } else {
986 r = rate_1;
987 i = ARRAY_SIZE(rate_1);
988 }
989 while (--i > 0) {
990 if (sd->frame_rate >= r->fps)
991 break;
992 r++;
993 }
994
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);
998
999 PDEBUG(D_PROBE, "frame_rate: %d", r->fps);
1000}
1001
1002/* ov772x controls */
1003static void setgain(struct gspca_dev *gspca_dev)
1004{
1005 struct sd *sd = (struct sd *) gspca_dev;
1006 u8 val;
761 1007
762 switch (fr) { 1008 val = sd->gain;
763 case 50: 1009 switch (val & 0x30) {
764 sccb_reg_write(gspca_dev, 0x11, 0x01); 1010 case 0x00:
765 sccb_reg_write(gspca_dev, 0x0d, 0x41); 1011 val &= 0x0f;
766 ov534_reg_write(gspca_dev, 0xe5, 0x02);
767 break; 1012 break;
768 case 40: 1013 case 0x10:
769 sccb_reg_write(gspca_dev, 0x11, 0x02); 1014 val &= 0x0f;
770 sccb_reg_write(gspca_dev, 0x0d, 0xc1); 1015 val |= 0x30;
771 ov534_reg_write(gspca_dev, 0xe5, 0x04);
772 break; 1016 break;
773/* case 30: */ 1017 case 0x20:
774 default: 1018 val &= 0x0f;
775 fr = 30; 1019 val |= 0x70;
776 sccb_reg_write(gspca_dev, 0x11, 0x04);
777 sccb_reg_write(gspca_dev, 0x0d, 0x81);
778 ov534_reg_write(gspca_dev, 0xe5, 0x02);
779 break; 1020 break;
780 case 15: 1021 default:
781 sccb_reg_write(gspca_dev, 0x11, 0x03); 1022/* case 0x30: */
782 sccb_reg_write(gspca_dev, 0x0d, 0x41); 1023 val &= 0x0f;
783 ov534_reg_write(gspca_dev, 0xe5, 0x04); 1024 val |= 0xf0;
784 break; 1025 break;
785 } 1026 }
1027 sccb_reg_write(gspca_dev, 0x00, val);
1028}
1029
1030static void setexposure(struct gspca_dev *gspca_dev)
1031{
1032 struct sd *sd = (struct sd *) gspca_dev;
1033 u8 val;
1034
1035 val = sd->exposure;
1036 sccb_reg_write(gspca_dev, 0x08, val >> 7);
1037 sccb_reg_write(gspca_dev, 0x10, val << 1);
1038}
1039
1040static void setredblc(struct gspca_dev *gspca_dev)
1041{
1042 struct sd *sd = (struct sd *) gspca_dev;
786 1043
787 sd->frame_rate = fr; 1044 sccb_reg_write(gspca_dev, 0x43, sd->redblc);
788 PDEBUG(D_PROBE, "frame_rate: %d", fr); 1045}
1046
1047static void setblueblc(struct gspca_dev *gspca_dev)
1048{
1049 struct sd *sd = (struct sd *) gspca_dev;
1050
1051 sccb_reg_write(gspca_dev, 0x42, sd->blueblc);
1052}
1053
1054static void setautogain(struct gspca_dev *gspca_dev)
1055{
1056 struct sd *sd = (struct sd *) gspca_dev;
1057
1058 if (sd->autogain) {
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);
1062 } else {
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);
1066 }
1067}
1068
1069static void setsharpness(struct gspca_dev *gspca_dev)
1070{
1071 struct sd *sd = (struct sd *) gspca_dev;
1072 u8 val;
1073
1074 val = sd->sharpness;
1075 sccb_reg_write(gspca_dev, 0x91, val); /* vga noise */
1076 sccb_reg_write(gspca_dev, 0x8e, val); /* qvga noise */
1077}
1078
1079static void sethflip(struct gspca_dev *gspca_dev)
1080{
1081 struct sd *sd = (struct sd *) gspca_dev;
1082
1083 if (sd->hflip == 0)
1084 sccb_reg_write(gspca_dev, 0x0c,
1085 sccb_reg_read(gspca_dev, 0x0c) | 0x40);
1086 else
1087 sccb_reg_write(gspca_dev, 0x0c,
1088 sccb_reg_read(gspca_dev, 0x0c) & 0xbf);
1089}
1090
1091static void setvflip(struct gspca_dev *gspca_dev)
1092{
1093 struct sd *sd = (struct sd *) gspca_dev;
1094
1095 if (sd->vflip == 0)
1096 sccb_reg_write(gspca_dev, 0x0c,
1097 sccb_reg_read(gspca_dev, 0x0c) | 0x80);
1098 else
1099 sccb_reg_write(gspca_dev, 0x0c,
1100 sccb_reg_read(gspca_dev, 0x0c) & 0x7f);
789} 1101}
790 1102
791/* this function is called at probe time */ 1103/* this function is called at probe time */
@@ -811,6 +1123,19 @@ static int sd_config(struct gspca_dev *gspca_dev,
811 cam->nmodes = ARRAY_SIZE(vga_jpeg_mode); 1123 cam->nmodes = ARRAY_SIZE(vga_jpeg_mode);
812 } 1124 }
813 1125
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;
1133#if HFLIP_DEF != 0
1134 sd->hflip = HFLIP_DEF;
1135#endif
1136#if VFLIP_DEF != 0
1137 sd->vflip = VFLIP_DEF;
1138#endif
814 return 0; 1139 return 0;
815} 1140}
816 1141
@@ -847,11 +1172,11 @@ static int sd_init(struct gspca_dev *gspca_dev)
847 /* initialize */ 1172 /* initialize */
848 switch (sd->sensor) { 1173 switch (sd->sensor) {
849 case SENSOR_OV772X: 1174 case SENSOR_OV772X:
850 reg_w_array(gspca_dev, bridge_init_ov722x, 1175 reg_w_array(gspca_dev, bridge_init_ov772x,
851 ARRAY_SIZE(bridge_init_ov722x)); 1176 ARRAY_SIZE(bridge_init_ov772x));
852 ov534_set_led(gspca_dev, 1); 1177 ov534_set_led(gspca_dev, 1);
853 sccb_w_array(gspca_dev, sensor_init_ov722x, 1178 sccb_w_array(gspca_dev, sensor_init_ov772x,
854 ARRAY_SIZE(sensor_init_ov722x)); 1179 ARRAY_SIZE(sensor_init_ov772x));
855 ov534_reg_write(gspca_dev, 0xe0, 0x09); 1180 ov534_reg_write(gspca_dev, 0xe0, 0x09);
856 ov534_set_led(gspca_dev, 0); 1181 ov534_set_led(gspca_dev, 0);
857 ov534_set_frame_rate(gspca_dev); 1182 ov534_set_frame_rate(gspca_dev);
@@ -875,60 +1200,78 @@ static int sd_init(struct gspca_dev *gspca_dev)
875 return 0; 1200 return 0;
876} 1201}
877 1202
878static int sd_start(struct gspca_dev *gspca_dev) 1203static int sd_start_ov772x(struct gspca_dev *gspca_dev)
879{ 1204{
880 struct sd *sd = (struct sd *) gspca_dev;
881 int mode; 1205 int mode;
882 1206
883 switch (sd->sensor) { 1207 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
884 case SENSOR_OV772X: 1208 if (mode != 0) { /* 320x240 */
885 ov534_set_led(gspca_dev, 1); 1209 reg_w_array(gspca_dev, bridge_start_ov772x_qvga,
886 ov534_reg_write(gspca_dev, 0xe0, 0x00); 1210 ARRAY_SIZE(bridge_start_ov772x_qvga));
887 break; 1211 sccb_w_array(gspca_dev, sensor_start_ov772x_qvga,
888 default: 1212 ARRAY_SIZE(sensor_start_ov772x_qvga));
889/* case SENSOR_OV965X: */ 1213 } else { /* 640x480 */
890 1214 reg_w_array(gspca_dev, bridge_start_ov772x_vga,
891 sccb_w_array(gspca_dev, sensor_start_ov965x, 1215 ARRAY_SIZE(bridge_start_ov772x_vga));
892 ARRAY_SIZE(sensor_start_ov965x)); 1216 sccb_w_array(gspca_dev, sensor_start_ov772x_vga,
893 reg_w_array(gspca_dev, bridge_start_ov965x, 1217 ARRAY_SIZE(sensor_start_ov772x_vga));
894 ARRAY_SIZE(bridge_start_ov965x));
895 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
896 if (mode != 0) { /* 320x240 */
897 reg_w_array(gspca_dev, bridge_start_ov965x_cif,
898 ARRAY_SIZE(bridge_start_ov965x_cif));
899 sccb_w_array(gspca_dev, sensor_start_ov965x_cif,
900 ARRAY_SIZE(sensor_start_ov965x_cif));
901 } else { /* 640x480 */
902 reg_w_array(gspca_dev, bridge_start_ov965x_vga,
903 ARRAY_SIZE(bridge_start_ov965x_vga));
904 sccb_w_array(gspca_dev, sensor_start_ov965x_vga,
905 ARRAY_SIZE(sensor_start_ov965x_vga));
906 }
907 sccb_w_array(gspca_dev, sensor_start_ov965x_2,
908 ARRAY_SIZE(sensor_start_ov965x_2));
909 ov534_reg_write(gspca_dev, 0xe0, 0x00);
910 ov534_reg_write(gspca_dev, 0xe0, 0x00);
911 ov534_set_led(gspca_dev, 1);
912 } 1218 }
1219 ov534_set_frame_rate(gspca_dev);
1220
1221 setautogain(gspca_dev);
1222 setgain(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);
1229
1230 ov534_set_led(gspca_dev, 1);
1231 ov534_reg_write(gspca_dev, 0xe0, 0x00);
913 return 0; 1232 return 0;
914} 1233}
915 1234
916static void sd_stopN(struct gspca_dev *gspca_dev) 1235static int sd_start_ov965x(struct gspca_dev *gspca_dev)
917{ 1236{
918 struct sd *sd = (struct sd *) gspca_dev; 1237 int mode;
919 1238
920 switch (sd->sensor) { 1239 sccb_w_array(gspca_dev, sensor_start_ov965x,
921 case SENSOR_OV772X: 1240 ARRAY_SIZE(sensor_start_ov965x));
922 ov534_reg_write(gspca_dev, 0xe0, 0x09); 1241 reg_w_array(gspca_dev, bridge_start_ov965x,
923 ov534_set_led(gspca_dev, 0); 1242 ARRAY_SIZE(bridge_start_ov965x));
924 break; 1243
925 default: 1244 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
926/* case SENSOR_OV965X: */ 1245 if (mode != 0) { /* 320x240 */
927 ov534_reg_write(gspca_dev, 0xe0, 0x01); 1246 reg_w_array(gspca_dev, bridge_start_ov965x_cif,
928 ov534_set_led(gspca_dev, 0); 1247 ARRAY_SIZE(bridge_start_ov965x_cif));
929 ov534_reg_write(gspca_dev, 0xe0, 0x00); 1248 sccb_w_array(gspca_dev, sensor_start_ov965x_cif,
930 break; 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));
931 } 1255 }
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);
1261 return 0;
1262}
1263
1264static void sd_stopN_ov772x(struct gspca_dev *gspca_dev)
1265{
1266 ov534_reg_write(gspca_dev, 0xe0, 0x09);
1267 ov534_set_led(gspca_dev, 0);
1268}
1269
1270static void sd_stopN_ov965x(struct gspca_dev *gspca_dev)
1271{
1272 ov534_reg_write(gspca_dev, 0xe0, 0x01);
1273 ov534_set_led(gspca_dev, 0);
1274 ov534_reg_write(gspca_dev, 0xe0, 0x00);
932} 1275}
933 1276
934/* Values for bmHeaderInfo (Video and Still Image Payload Headers, 2.4.3.3) */ 1277/* Values for bmHeaderInfo (Video and Still Image Payload Headers, 2.4.3.3) */
@@ -1002,7 +1345,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame,
1002 data + 12, len - 12); 1345 data + 12, len - 12);
1003 } 1346 }
1004 1347
1005
1006 /* Done this payload */ 1348 /* Done this payload */
1007 goto scan_next; 1349 goto scan_next;
1008 1350
@@ -1016,6 +1358,151 @@ scan_next:
1016 } while (remaining_len > 0); 1358 } while (remaining_len > 0);
1017} 1359}
1018 1360
1361/* ov772x controls */
1362static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
1363{
1364 struct sd *sd = (struct sd *) gspca_dev;
1365
1366 sd->gain = val;
1367 if (gspca_dev->streaming)
1368 setgain(gspca_dev);
1369 return 0;
1370}
1371
1372static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
1373{
1374 struct sd *sd = (struct sd *) gspca_dev;
1375
1376 *val = sd->gain;
1377 return 0;
1378}
1379
1380static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
1381{
1382 struct sd *sd = (struct sd *) gspca_dev;
1383
1384 sd->exposure = val;
1385 if (gspca_dev->streaming)
1386 setexposure(gspca_dev);
1387 return 0;
1388}
1389
1390static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
1391{
1392 struct sd *sd = (struct sd *) gspca_dev;
1393
1394 *val = sd->exposure;
1395 return 0;
1396}
1397
1398static int sd_setredblc(struct gspca_dev *gspca_dev, __s32 val)
1399{
1400 struct sd *sd = (struct sd *) gspca_dev;
1401
1402 sd->redblc = val;
1403 if (gspca_dev->streaming)
1404 setredblc(gspca_dev);
1405 return 0;
1406}
1407
1408static int sd_getredblc(struct gspca_dev *gspca_dev, __s32 *val)
1409{
1410 struct sd *sd = (struct sd *) gspca_dev;
1411
1412 *val = sd->redblc;
1413 return 0;
1414}
1415
1416static int sd_setblueblc(struct gspca_dev *gspca_dev, __s32 val)
1417{
1418 struct sd *sd = (struct sd *) gspca_dev;
1419
1420 sd->blueblc = val;
1421 if (gspca_dev->streaming)
1422 setblueblc(gspca_dev);
1423 return 0;
1424}
1425
1426static int sd_getblueblc(struct gspca_dev *gspca_dev, __s32 *val)
1427{
1428 struct sd *sd = (struct sd *) gspca_dev;
1429
1430 *val = sd->blueblc;
1431 return 0;
1432}
1433
1434static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1435{
1436 struct sd *sd = (struct sd *) gspca_dev;
1437
1438 sd->autogain = val;
1439 if (gspca_dev->streaming)
1440 setautogain(gspca_dev);
1441 return 0;
1442}
1443
1444static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1445{
1446 struct sd *sd = (struct sd *) gspca_dev;
1447
1448 *val = sd->autogain;
1449 return 0;
1450}
1451
1452static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
1453{
1454 struct sd *sd = (struct sd *) gspca_dev;
1455
1456 sd->sharpness = val;
1457 if (gspca_dev->streaming)
1458 setsharpness(gspca_dev);
1459 return 0;
1460}
1461
1462static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
1463{
1464 struct sd *sd = (struct sd *) gspca_dev;
1465
1466 *val = sd->sharpness;
1467 return 0;
1468}
1469
1470static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
1471{
1472 struct sd *sd = (struct sd *) gspca_dev;
1473
1474 sd->hflip = val;
1475 if (gspca_dev->streaming)
1476 sethflip(gspca_dev);
1477 return 0;
1478}
1479
1480static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val)
1481{
1482 struct sd *sd = (struct sd *) gspca_dev;
1483
1484 *val = sd->hflip;
1485 return 0;
1486}
1487
1488static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
1489{
1490 struct sd *sd = (struct sd *) gspca_dev;
1491
1492 sd->vflip = val;
1493 if (gspca_dev->streaming)
1494 setvflip(gspca_dev);
1495 return 0;
1496}
1497
1498static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
1499{
1500 struct sd *sd = (struct sd *) gspca_dev;
1501
1502 *val = sd->vflip;
1503 return 0;
1504}
1505
1019/* get stream parameters (framerate) */ 1506/* get stream parameters (framerate) */
1020static int sd_get_streamparm(struct gspca_dev *gspca_dev, 1507static int sd_get_streamparm(struct gspca_dev *gspca_dev,
1021 struct v4l2_streamparm *parm) 1508 struct v4l2_streamparm *parm)
@@ -1047,7 +1534,8 @@ static int sd_set_streamparm(struct gspca_dev *gspca_dev,
1047 1534
1048 /* Set requested framerate */ 1535 /* Set requested framerate */
1049 sd->frame_rate = tpf->denominator / tpf->numerator; 1536 sd->frame_rate = tpf->denominator / tpf->numerator;
1050 ov534_set_frame_rate(gspca_dev); 1537 if (gspca_dev->streaming)
1538 ov534_set_frame_rate(gspca_dev);
1051 1539
1052 /* Return the actual framerate */ 1540 /* Return the actual framerate */
1053 tpf->numerator = 1; 1541 tpf->numerator = 1;
@@ -1057,14 +1545,27 @@ static int sd_set_streamparm(struct gspca_dev *gspca_dev,
1057} 1545}
1058 1546
1059/* sub-driver description */ 1547/* sub-driver description */
1060static const struct sd_desc sd_desc = { 1548static const struct sd_desc sd_desc_ov772x = {
1061 .name = MODULE_NAME, 1549 .name = MODULE_NAME,
1062 .ctrls = sd_ctrls, 1550 .ctrls = sd_ctrls_ov772x,
1063 .nctrls = ARRAY_SIZE(sd_ctrls), 1551 .nctrls = ARRAY_SIZE(sd_ctrls_ov772x),
1064 .config = sd_config, 1552 .config = sd_config,
1065 .init = sd_init, 1553 .init = sd_init,
1066 .start = sd_start, 1554 .start = sd_start_ov772x,
1067 .stopN = sd_stopN, 1555 .stopN = sd_stopN_ov772x,
1556 .pkt_scan = sd_pkt_scan,
1557 .get_streamparm = sd_get_streamparm,
1558 .set_streamparm = sd_set_streamparm,
1559};
1560
1561static 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,
1566 .init = sd_init,
1567 .start = sd_start_ov965x,
1568 .stopN = sd_stopN_ov965x,
1068 .pkt_scan = sd_pkt_scan, 1569 .pkt_scan = sd_pkt_scan,
1069 .get_streamparm = sd_get_streamparm, 1570 .get_streamparm = sd_get_streamparm,
1070 .set_streamparm = sd_set_streamparm, 1571 .set_streamparm = sd_set_streamparm,
@@ -1082,8 +1583,12 @@ MODULE_DEVICE_TABLE(usb, device_table);
1082/* -- device connect -- */ 1583/* -- device connect -- */
1083static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id) 1584static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id)
1084{ 1585{
1085 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), 1586 return gspca_dev_probe(intf, id,
1086 THIS_MODULE); 1587 id->driver_info == SENSOR_OV772X
1588 ? &sd_desc_ov772x
1589 : &sd_desc_ov965x,
1590 sizeof(struct sd),
1591 THIS_MODULE);
1087} 1592}
1088 1593
1089static struct usb_driver sd_driver = { 1594static struct usb_driver sd_driver = {
@@ -1101,6 +1606,7 @@ static struct usb_driver sd_driver = {
1101static int __init sd_mod_init(void) 1606static int __init sd_mod_init(void)
1102{ 1607{
1103 int ret; 1608 int ret;
1609
1104 ret = usb_register(&sd_driver); 1610 ret = usb_register(&sd_driver);
1105 if (ret < 0) 1611 if (ret < 0)
1106 return ret; 1612 return ret;