diff options
Diffstat (limited to 'drivers/media')
25 files changed, 21808 insertions, 832 deletions
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index 2ec920dc32e0..d5f6eea7d2fd 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile | |||
@@ -117,6 +117,7 @@ obj-$(CONFIG_USB_SN9C102) += sn9c102/ | |||
117 | obj-$(CONFIG_USB_ET61X251) += et61x251/ | 117 | obj-$(CONFIG_USB_ET61X251) += et61x251/ |
118 | obj-$(CONFIG_USB_PWC) += pwc/ | 118 | obj-$(CONFIG_USB_PWC) += pwc/ |
119 | obj-$(CONFIG_USB_ZC0301) += zc0301/ | 119 | obj-$(CONFIG_USB_ZC0301) += zc0301/ |
120 | obj-$(CONFIG_USB_GSPCA) += gspca/ | ||
120 | 121 | ||
121 | obj-$(CONFIG_USB_IBMCAM) += usbvideo/ | 122 | obj-$(CONFIG_USB_IBMCAM) += usbvideo/ |
122 | obj-$(CONFIG_USB_KONICAWC) += usbvideo/ | 123 | obj-$(CONFIG_USB_KONICAWC) += usbvideo/ |
diff --git a/drivers/media/video/gspca/Kconfig b/drivers/media/video/gspca/Kconfig index a04e413e1258..42b90742b40b 100644 --- a/drivers/media/video/gspca/Kconfig +++ b/drivers/media/video/gspca/Kconfig | |||
@@ -2,7 +2,7 @@ config USB_GSPCA | |||
2 | tristate "USB GSPCA driver" | 2 | tristate "USB GSPCA driver" |
3 | depends on VIDEO_V4L2 | 3 | depends on VIDEO_V4L2 |
4 | ---help--- | 4 | ---help--- |
5 | Say Y here if you want support for various USB cameras. | 5 | Say Y here if you want support for various USB webcams. |
6 | 6 | ||
7 | See <file:Documentation/video4linux/gspca.txt> for more info. | 7 | See <file:Documentation/video4linux/gspca.txt> for more info. |
8 | 8 | ||
diff --git a/drivers/media/video/gspca/Makefile b/drivers/media/video/gspca/Makefile index d959f7771526..e68a8965297a 100644 --- a/drivers/media/video/gspca/Makefile +++ b/drivers/media/video/gspca/Makefile | |||
@@ -1,7 +1,29 @@ | |||
1 | obj-$(CONFIG_GSPCA) += gspca_main.o \ | 1 | obj-$(CONFIG_USB_GSPCA) += gspca_main.o \ |
2 | gspca_pac207.o gspca_stk014.o gspca_zc3xx.o | 2 | gspca_conex.o gspca_etoms.o gspca_mars.o \ |
3 | gspca_ov519.o gspca_pac207.o gspca_pac7311.o \ | ||
4 | gspca_sonixb.o gspca_sonixj.o gspca_spca500.o gspca_spca501.o \ | ||
5 | gspca_spca505.o gspca_spca506.o gspca_spca508.o gspca_spca561.o \ | ||
6 | gspca_sunplus.o gspca_stk014.o gspca_t613.o gspca_tv8532.o \ | ||
7 | gspca_vc032x.o gspca_zc3xx.o | ||
3 | 8 | ||
4 | gspca_main-objs := gspca.o | 9 | gspca_main-objs := gspca.o |
10 | gspca_conex-objs := conex.o | ||
11 | gspca_etoms-objs := etoms.o | ||
12 | gspca_mars-objs := mars.o | ||
13 | gspca_ov519-objs := ov519.o | ||
5 | gspca_pac207-objs := pac207.o | 14 | gspca_pac207-objs := pac207.o |
15 | gspca_pac7311-objs := pac7311.o | ||
16 | gspca_sonixb-objs := sonixb.o | ||
17 | gspca_sonixj-objs := sonixj.o | ||
18 | gspca_spca500-objs := spca500.o | ||
19 | gspca_spca501-objs := spca501.o | ||
20 | gspca_spca505-objs := spca505.o | ||
21 | gspca_spca506-objs := spca506.o | ||
22 | gspca_spca508-objs := spca508.o | ||
23 | gspca_spca561-objs := spca561.o | ||
6 | gspca_stk014-objs := stk014.o | 24 | gspca_stk014-objs := stk014.o |
25 | gspca_sunplus-objs := sunplus.o | ||
26 | gspca_t613-objs := t613.o | ||
27 | gspca_tv8532-objs := tv8532.o | ||
28 | gspca_vc032x-objs := vc032x.o | ||
7 | gspca_zc3xx-objs := zc3xx.o | 29 | gspca_zc3xx-objs := zc3xx.o |
diff --git a/drivers/media/video/gspca/conex.c b/drivers/media/video/gspca/conex.c new file mode 100644 index 000000000000..b0294c9274e3 --- /dev/null +++ b/drivers/media/video/gspca/conex.c | |||
@@ -0,0 +1,1059 @@ | |||
1 | /* | ||
2 | * Connexant Cx11646 library | ||
3 | * Copyright (C) 2004 Michel Xhaard mxhaard@magic.fr | ||
4 | * | ||
5 | * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | #define MODULE_NAME "conex" | ||
23 | |||
24 | #include "gspca.h" | ||
25 | #define CONEX_CAM 1 /* special JPEG header */ | ||
26 | #include "jpeg.h" | ||
27 | |||
28 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) | ||
29 | static const char version[] = "2.1.0"; | ||
30 | |||
31 | MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); | ||
32 | MODULE_DESCRIPTION("GSPCA USB Conexant Camera Driver"); | ||
33 | MODULE_LICENSE("GPL"); | ||
34 | |||
35 | /* specific webcam descriptor */ | ||
36 | struct sd { | ||
37 | struct gspca_dev gspca_dev; /* !! must be the first item */ | ||
38 | |||
39 | unsigned char brightness; | ||
40 | unsigned char contrast; | ||
41 | unsigned char colors; | ||
42 | |||
43 | unsigned char qindex; | ||
44 | }; | ||
45 | |||
46 | /* V4L2 controls supported by the driver */ | ||
47 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
48 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
49 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | ||
50 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | ||
51 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); | ||
52 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); | ||
53 | |||
54 | static struct ctrl sd_ctrls[] = { | ||
55 | #define SD_BRIGHTNESS 0 | ||
56 | { | ||
57 | { | ||
58 | .id = V4L2_CID_BRIGHTNESS, | ||
59 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
60 | .name = "Brightness", | ||
61 | .minimum = 0, | ||
62 | .maximum = 255, | ||
63 | .step = 1, | ||
64 | .default_value = 0xd4, | ||
65 | }, | ||
66 | .set = sd_setbrightness, | ||
67 | .get = sd_getbrightness, | ||
68 | }, | ||
69 | #define SD_CONTRAST 1 | ||
70 | { | ||
71 | { | ||
72 | .id = V4L2_CID_CONTRAST, | ||
73 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
74 | .name = "Contrast", | ||
75 | .minimum = 0x0a, | ||
76 | .maximum = 0x1f, | ||
77 | .step = 1, | ||
78 | .default_value = 0x0c, | ||
79 | }, | ||
80 | .set = sd_setcontrast, | ||
81 | .get = sd_getcontrast, | ||
82 | }, | ||
83 | #define SD_COLOR 2 | ||
84 | { | ||
85 | { | ||
86 | .id = V4L2_CID_SATURATION, | ||
87 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
88 | .name = "Color", | ||
89 | .minimum = 0, | ||
90 | .maximum = 7, | ||
91 | .step = 1, | ||
92 | .default_value = 3, | ||
93 | }, | ||
94 | .set = sd_setcolors, | ||
95 | .get = sd_getcolors, | ||
96 | }, | ||
97 | }; | ||
98 | |||
99 | static struct cam_mode vga_mode[] = { | ||
100 | {V4L2_PIX_FMT_JPEG, 176, 144, 3}, | ||
101 | {V4L2_PIX_FMT_JPEG, 320, 240, 2}, | ||
102 | {V4L2_PIX_FMT_JPEG, 352, 288, 1}, | ||
103 | {V4L2_PIX_FMT_JPEG, 640, 480, 0}, | ||
104 | }; | ||
105 | |||
106 | static void reg_r(struct usb_device *dev, | ||
107 | __u16 index, | ||
108 | __u8 *buffer, __u16 length) | ||
109 | { | ||
110 | usb_control_msg(dev, | ||
111 | usb_rcvctrlpipe(dev, 0), | ||
112 | 0, | ||
113 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
114 | 0, | ||
115 | index, buffer, length, | ||
116 | 500); | ||
117 | PDEBUG(D_USBI, "reg read i:%02x -> %02x", index, *buffer); | ||
118 | } | ||
119 | |||
120 | static void reg_w(struct usb_device *dev, | ||
121 | __u16 index, | ||
122 | const __u8 *buffer, __u16 length) | ||
123 | { | ||
124 | PDEBUG(D_USBO, "reg write i:%02x = %02x", index, *buffer); | ||
125 | usb_control_msg(dev, | ||
126 | usb_sndctrlpipe(dev, 0), | ||
127 | 0, | ||
128 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
129 | 0, | ||
130 | index, (__u8 *) buffer, length, | ||
131 | 500); | ||
132 | } | ||
133 | |||
134 | static const __u8 cx_sensor_init[][4] = { | ||
135 | {0x88, 0x11, 0x01, 0x01}, | ||
136 | {0x88, 0x12, 0x70, 0x01}, | ||
137 | {0x88, 0x0f, 0x00, 0x01}, | ||
138 | {0x88, 0x05, 0x01, 0x01}, | ||
139 | {} | ||
140 | }; | ||
141 | |||
142 | static const __u8 cx11646_fw1[][3] = { | ||
143 | {0x00, 0x02, 0x00}, | ||
144 | {0x01, 0x43, 0x00}, | ||
145 | {0x02, 0xA7, 0x00}, | ||
146 | {0x03, 0x8B, 0x01}, | ||
147 | {0x04, 0xE9, 0x02}, | ||
148 | {0x05, 0x08, 0x04}, | ||
149 | {0x06, 0x08, 0x05}, | ||
150 | {0x07, 0x07, 0x06}, | ||
151 | {0x08, 0xE7, 0x06}, | ||
152 | {0x09, 0xC6, 0x07}, | ||
153 | {0x0A, 0x86, 0x08}, | ||
154 | {0x0B, 0x46, 0x09}, | ||
155 | {0x0C, 0x05, 0x0A}, | ||
156 | {0x0D, 0xA5, 0x0A}, | ||
157 | {0x0E, 0x45, 0x0B}, | ||
158 | {0x0F, 0xE5, 0x0B}, | ||
159 | {0x10, 0x85, 0x0C}, | ||
160 | {0x11, 0x25, 0x0D}, | ||
161 | {0x12, 0xC4, 0x0D}, | ||
162 | {0x13, 0x45, 0x0E}, | ||
163 | {0x14, 0xE4, 0x0E}, | ||
164 | {0x15, 0x64, 0x0F}, | ||
165 | {0x16, 0xE4, 0x0F}, | ||
166 | {0x17, 0x64, 0x10}, | ||
167 | {0x18, 0xE4, 0x10}, | ||
168 | {0x19, 0x64, 0x11}, | ||
169 | {0x1A, 0xE4, 0x11}, | ||
170 | {0x1B, 0x64, 0x12}, | ||
171 | {0x1C, 0xE3, 0x12}, | ||
172 | {0x1D, 0x44, 0x13}, | ||
173 | {0x1E, 0xC3, 0x13}, | ||
174 | {0x1F, 0x24, 0x14}, | ||
175 | {0x20, 0xA3, 0x14}, | ||
176 | {0x21, 0x04, 0x15}, | ||
177 | {0x22, 0x83, 0x15}, | ||
178 | {0x23, 0xE3, 0x15}, | ||
179 | {0x24, 0x43, 0x16}, | ||
180 | {0x25, 0xA4, 0x16}, | ||
181 | {0x26, 0x23, 0x17}, | ||
182 | {0x27, 0x83, 0x17}, | ||
183 | {0x28, 0xE3, 0x17}, | ||
184 | {0x29, 0x43, 0x18}, | ||
185 | {0x2A, 0xA3, 0x18}, | ||
186 | {0x2B, 0x03, 0x19}, | ||
187 | {0x2C, 0x63, 0x19}, | ||
188 | {0x2D, 0xC3, 0x19}, | ||
189 | {0x2E, 0x22, 0x1A}, | ||
190 | {0x2F, 0x63, 0x1A}, | ||
191 | {0x30, 0xC3, 0x1A}, | ||
192 | {0x31, 0x23, 0x1B}, | ||
193 | {0x32, 0x83, 0x1B}, | ||
194 | {0x33, 0xE2, 0x1B}, | ||
195 | {0x34, 0x23, 0x1C}, | ||
196 | {0x35, 0x83, 0x1C}, | ||
197 | {0x36, 0xE2, 0x1C}, | ||
198 | {0x37, 0x23, 0x1D}, | ||
199 | {0x38, 0x83, 0x1D}, | ||
200 | {0x39, 0xE2, 0x1D}, | ||
201 | {0x3A, 0x23, 0x1E}, | ||
202 | {0x3B, 0x82, 0x1E}, | ||
203 | {0x3C, 0xC3, 0x1E}, | ||
204 | {0x3D, 0x22, 0x1F}, | ||
205 | {0x3E, 0x63, 0x1F}, | ||
206 | {0x3F, 0xC1, 0x1F}, | ||
207 | {} | ||
208 | }; | ||
209 | static void cx11646_fw(struct gspca_dev*gspca_dev) | ||
210 | { | ||
211 | __u8 val; | ||
212 | int i = 0; | ||
213 | |||
214 | val = 0x02; | ||
215 | reg_w(gspca_dev->dev, 0x006a, &val, 1); | ||
216 | while (cx11646_fw1[i][1]) { | ||
217 | reg_w(gspca_dev->dev, 0x006b, cx11646_fw1[i], 3); | ||
218 | i++; | ||
219 | } | ||
220 | val = 0x00; | ||
221 | reg_w(gspca_dev->dev, 0x006a, &val, 1); | ||
222 | } | ||
223 | |||
224 | static __u8 cxsensor[] = { | ||
225 | 0x88, 0x12, 0x70, 0x01, | ||
226 | 0x88, 0x0d, 0x02, 0x01, | ||
227 | 0x88, 0x0f, 0x00, 0x01, | ||
228 | 0x88, 0x03, 0x71, 0x01, 0x88, 0x04, 0x00, 0x01, /* 3 */ | ||
229 | 0x88, 0x02, 0x10, 0x01, | ||
230 | 0x88, 0x00, 0xD4, 0x01, 0x88, 0x01, 0x01, 0x01, /* 5 */ | ||
231 | 0x88, 0x0B, 0x00, 0x01, | ||
232 | 0x88, 0x0A, 0x0A, 0x01, | ||
233 | 0x88, 0x00, 0x08, 0x01, 0x88, 0x01, 0x00, 0x01, /* 8 */ | ||
234 | 0x88, 0x05, 0x01, 0x01, | ||
235 | 0xA1, 0x18, 0x00, 0x01, | ||
236 | 0x00 | ||
237 | }; | ||
238 | |||
239 | static __u8 reg20[] = { 0x10, 0x42, 0x81, 0x19, 0xd3, 0xff, 0xa7, 0xff }; | ||
240 | static __u8 reg28[] = { 0x87, 0x00, 0x87, 0x00, 0x8f, 0xff, 0xea, 0xff }; | ||
241 | static __u8 reg10[] = { 0xb1, 0xb1 }; | ||
242 | static __u8 reg71a[] = { 0x08, 0x18, 0x0a, 0x1e }; /* 640 */ | ||
243 | static __u8 reg71b[] = { 0x04, 0x0c, 0x05, 0x0f }; | ||
244 | /* 352{0x04,0x0a,0x06,0x12}; //352{0x05,0x0e,0x06,0x11}; //352 */ | ||
245 | static __u8 reg71c[] = { 0x02, 0x07, 0x03, 0x09 }; | ||
246 | /* 320{0x04,0x0c,0x05,0x0f}; //320 */ | ||
247 | static __u8 reg71d[] = { 0x02, 0x07, 0x03, 0x09 }; /* 176 */ | ||
248 | static __u8 reg7b[] = { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff }; | ||
249 | |||
250 | static void cx_sensor(struct gspca_dev*gspca_dev) | ||
251 | { | ||
252 | __u8 val = 0; | ||
253 | int i = 0; | ||
254 | __u8 bufread[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; | ||
255 | int length = 0; | ||
256 | __u8 *ptsensor = cxsensor; | ||
257 | |||
258 | reg_w(gspca_dev->dev, 0x0020, reg20, 8); | ||
259 | reg_w(gspca_dev->dev, 0x0028, reg28, 8); | ||
260 | reg_w(gspca_dev->dev, 0x0010, reg10, 8); | ||
261 | val = 0x03; | ||
262 | reg_w(gspca_dev->dev, 0x0092, &val, 1); | ||
263 | |||
264 | switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode) { | ||
265 | case 0: | ||
266 | reg_w(gspca_dev->dev, 0x0071, reg71a, 4); | ||
267 | break; | ||
268 | case 1: | ||
269 | reg_w(gspca_dev->dev, 0x0071, reg71b, 4); | ||
270 | break; | ||
271 | default: | ||
272 | /* case 2: */ | ||
273 | reg_w(gspca_dev->dev, 0x0071, reg71c, 4); | ||
274 | break; | ||
275 | case 3: | ||
276 | reg_w(gspca_dev->dev, 0x0071, reg71d, 4); | ||
277 | break; | ||
278 | } | ||
279 | reg_w(gspca_dev->dev, 0x007b, reg7b, 6); | ||
280 | val = 0x00; | ||
281 | reg_w(gspca_dev->dev, 0x00f8, &val, 1); | ||
282 | reg_w(gspca_dev->dev, 0x0010, reg10, 8); | ||
283 | val = 0x41; | ||
284 | reg_w(gspca_dev->dev, 0x0098, &val, 1); | ||
285 | for (i = 0; i < 11; i++) { | ||
286 | if (i == 3 || i == 5 || i == 8) | ||
287 | length = 8; | ||
288 | else | ||
289 | length = 4; | ||
290 | reg_w(gspca_dev->dev, 0x00e5, ptsensor, length); | ||
291 | if (length == 4) | ||
292 | reg_r(gspca_dev->dev, 0x00e8, &val, 1); | ||
293 | else | ||
294 | reg_r(gspca_dev->dev, 0x00e8, bufread, length); | ||
295 | ptsensor += length; | ||
296 | } | ||
297 | reg_r(gspca_dev->dev, 0x00e7, bufread, 8); | ||
298 | } | ||
299 | |||
300 | static __u8 cx_inits_176[] = { | ||
301 | 0x33, 0x81, 0xB0, 0x00, 0x90, 0x00, 0x0A, 0x03, /* 176x144 */ | ||
302 | 0x00, 0x03, 0x03, 0x03, 0x1B, 0x05, 0x30, 0x03, | ||
303 | 0x65, 0x15, 0x18, 0x25, 0x03, 0x25, 0x08, 0x30, | ||
304 | 0x3B, 0x25, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, | ||
305 | 0xDC, 0xFF, 0xEE, 0xFF, 0xC5, 0xFF, 0xBF, 0xFF, | ||
306 | 0xF7, 0xFF, 0x88, 0xFF, 0x66, 0x02, 0x28, 0x02, | ||
307 | 0x1E, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | ||
308 | }; | ||
309 | static __u8 cx_inits_320[] = { | ||
310 | 0x7f, 0x7f, 0x40, 0x01, 0xf0, 0x00, 0x02, 0x01, | ||
311 | 0x00, 0x01, 0x01, 0x01, 0x10, 0x00, 0x02, 0x01, | ||
312 | 0x65, 0x45, 0xfa, 0x4c, 0x2c, 0xdf, 0xb9, 0x81, | ||
313 | 0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, | ||
314 | 0xe2, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff, | ||
315 | 0xf5, 0xff, 0x6d, 0xff, 0xf6, 0x01, 0x43, 0x02, | ||
316 | 0xd3, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | ||
317 | }; | ||
318 | static __u8 cx_inits_352[] = { | ||
319 | 0x2e, 0x7c, 0x60, 0x01, 0x20, 0x01, 0x05, 0x03, | ||
320 | 0x00, 0x06, 0x03, 0x06, 0x1b, 0x10, 0x05, 0x3b, | ||
321 | 0x30, 0x25, 0x18, 0x25, 0x08, 0x30, 0x03, 0x25, | ||
322 | 0x3b, 0x30, 0x25, 0x1b, 0x10, 0x05, 0x00, 0x00, | ||
323 | 0xe3, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff, | ||
324 | 0xf5, 0xff, 0x6b, 0xff, 0xee, 0x01, 0x43, 0x02, | ||
325 | 0xe4, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | ||
326 | }; | ||
327 | static __u8 cx_inits_640[] = { | ||
328 | 0x7e, 0x7e, 0x80, 0x02, 0xe0, 0x01, 0x01, 0x01, | ||
329 | 0x00, 0x02, 0x01, 0x02, 0x10, 0x30, 0x01, 0x01, | ||
330 | 0x65, 0x45, 0xf7, 0x52, 0x2c, 0xdf, 0xb9, 0x81, | ||
331 | 0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, | ||
332 | 0xe2, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff, | ||
333 | 0xf6, 0xff, 0x7b, 0xff, 0x01, 0x02, 0x43, 0x02, | ||
334 | 0x77, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | ||
335 | }; | ||
336 | |||
337 | static int cx11646_initsize(struct gspca_dev *gspca_dev) | ||
338 | { | ||
339 | __u8 *cxinit; | ||
340 | __u8 val; | ||
341 | static const __u8 reg12[] = { 0x08, 0x05, 0x07, 0x04, 0x24 }; | ||
342 | static const __u8 reg17[] = | ||
343 | { 0x0a, 0x00, 0xf2, 0x01, 0x0f, 0x00, 0x97, 0x02 }; | ||
344 | |||
345 | switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode) { | ||
346 | case 0: | ||
347 | cxinit = cx_inits_640; | ||
348 | break; | ||
349 | case 1: | ||
350 | cxinit = cx_inits_352; | ||
351 | break; | ||
352 | default: | ||
353 | /* case 2: */ | ||
354 | cxinit = cx_inits_320; | ||
355 | break; | ||
356 | case 3: | ||
357 | cxinit = cx_inits_176; | ||
358 | break; | ||
359 | } | ||
360 | val = 0x01; | ||
361 | reg_w(gspca_dev->dev, 0x009a, &val, 1); | ||
362 | val = 0x10; | ||
363 | reg_w(gspca_dev->dev, 0x0010, &val, 1); | ||
364 | reg_w(gspca_dev->dev, 0x0012, reg12, 5); | ||
365 | reg_w(gspca_dev->dev, 0x0017, reg17, 8); | ||
366 | val = 0x00; | ||
367 | reg_w(gspca_dev->dev, 0x00c0, &val, 1); | ||
368 | val = 0x04; | ||
369 | reg_w(gspca_dev->dev, 0x00c1, &val, 1); | ||
370 | val = 0x04; | ||
371 | reg_w(gspca_dev->dev, 0x00c2, &val, 1); | ||
372 | |||
373 | reg_w(gspca_dev->dev, 0x0061, cxinit, 8); | ||
374 | cxinit += 8; | ||
375 | reg_w(gspca_dev->dev, 0x00ca, cxinit, 8); | ||
376 | cxinit += 8; | ||
377 | reg_w(gspca_dev->dev, 0x00d2, cxinit, 8); | ||
378 | cxinit += 8; | ||
379 | reg_w(gspca_dev->dev, 0x00da, cxinit, 6); | ||
380 | cxinit += 8; | ||
381 | reg_w(gspca_dev->dev, 0x0041, cxinit, 8); | ||
382 | cxinit += 8; | ||
383 | reg_w(gspca_dev->dev, 0x0049, cxinit, 8); | ||
384 | cxinit += 8; | ||
385 | reg_w(gspca_dev->dev, 0x0051, cxinit, 2); | ||
386 | |||
387 | reg_r(gspca_dev->dev, 0x0010, &val, 1); | ||
388 | return val; | ||
389 | } | ||
390 | |||
391 | static __u8 cx_jpeg_init[][8] = { | ||
392 | {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x15}, /* 1 */ | ||
393 | {0x0f, 0x10, 0x12, 0x10, 0x0d, 0x15, 0x12, 0x11}, | ||
394 | {0x12, 0x18, 0x16, 0x15, 0x19, 0x20, 0x35, 0x22}, | ||
395 | {0x20, 0x1d, 0x1d, 0x20, 0x41, 0x2e, 0x31, 0x26}, | ||
396 | {0x35, 0x4d, 0x43, 0x51, 0x4f, 0x4b, 0x43, 0x4a}, | ||
397 | {0x49, 0x55, 0x5F, 0x79, 0x67, 0x55, 0x5A, 0x73}, | ||
398 | {0x5B, 0x49, 0x4A, 0x6A, 0x90, 0x6B, 0x73, 0x7D}, | ||
399 | {0x81, 0x88, 0x89, 0x88, 0x52, 0x66, 0x95, 0xA0}, | ||
400 | {0x94, 0x84, 0x9E, 0x79, 0x85, 0x88, 0x83, 0x01}, | ||
401 | {0x15, 0x0F, 0x10, 0x12, 0x10, 0x0D, 0x15, 0x12}, | ||
402 | {0x11, 0x12, 0x18, 0x16, 0x15, 0x19, 0x20, 0x35}, | ||
403 | {0x22, 0x20, 0x1D, 0x1D, 0x20, 0x41, 0x2E, 0x31}, | ||
404 | {0x26, 0x35, 0x4D, 0x43, 0x51, 0x4F, 0x4B, 0x43}, | ||
405 | {0x4A, 0x49, 0x55, 0x5F, 0x79, 0x67, 0x55, 0x5A}, | ||
406 | {0x73, 0x5B, 0x49, 0x4A, 0x6A, 0x90, 0x6B, 0x73}, | ||
407 | {0x7D, 0x81, 0x88, 0x89, 0x88, 0x52, 0x66, 0x95}, | ||
408 | {0xA0, 0x94, 0x84, 0x9E, 0x79, 0x85, 0x88, 0x83}, | ||
409 | {0xFF, 0xC4, 0x01, 0xA2, 0x00, 0x00, 0x01, 0x05}, | ||
410 | {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00}, | ||
411 | {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02}, | ||
412 | {0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A}, | ||
413 | {0x0B, 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01}, | ||
414 | {0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00}, | ||
415 | {0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05}, | ||
416 | {0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x10, 0x00}, | ||
417 | {0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05}, | ||
418 | {0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7D, 0x01}, | ||
419 | {0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21}, | ||
420 | {0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22}, | ||
421 | {0x71, 0x14, 0x32, 0x81, 0x91, 0xA1, 0x08, 0x23}, | ||
422 | {0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24}, | ||
423 | {0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17}, | ||
424 | {0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29}, | ||
425 | {0x2A, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A}, | ||
426 | {0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A}, | ||
427 | {0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A}, | ||
428 | {0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A}, | ||
429 | {0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A}, | ||
430 | {0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A}, | ||
431 | {0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99}, | ||
432 | {0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8}, | ||
433 | {0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7}, | ||
434 | {0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6}, | ||
435 | {0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5}, | ||
436 | {0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE1, 0xE2, 0xE3}, | ||
437 | {0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF1}, | ||
438 | {0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9}, | ||
439 | {0xFA, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04}, | ||
440 | {0x03, 0x04, 0x07, 0x05, 0x04, 0x04, 0x00, 0x01}, | ||
441 | {0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04}, | ||
442 | {0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07}, | ||
443 | {0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14}, | ||
444 | {0x42, 0x91, 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33}, | ||
445 | {0x52, 0xF0, 0x15, 0x62, 0x72, 0xD1, 0x0A, 0x16}, | ||
446 | {0x24, 0x34, 0xE1, 0x25, 0xF1, 0x17, 0x18, 0x19}, | ||
447 | {0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x35, 0x36}, | ||
448 | {0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, 0x45, 0x46}, | ||
449 | {0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56}, | ||
450 | {0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66}, | ||
451 | {0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76}, | ||
452 | {0x77, 0x78, 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85}, | ||
453 | {0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94}, | ||
454 | {0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3}, | ||
455 | {0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2}, | ||
456 | {0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA}, | ||
457 | {0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9}, | ||
458 | {0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8}, | ||
459 | {0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7}, | ||
460 | {0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6}, | ||
461 | {0xF7, 0xF8, 0xF9, 0xFA, 0xFF, 0x20, 0x00, 0x1F}, | ||
462 | {0x02, 0x0C, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00}, | ||
463 | {0x00, 0x00, 0x11, 0x00, 0x11, 0x22, 0x00, 0x22}, | ||
464 | {0x22, 0x11, 0x22, 0x22, 0x11, 0x33, 0x33, 0x11}, | ||
465 | {0x44, 0x66, 0x22, 0x55, 0x66, 0xFF, 0xDD, 0x00}, | ||
466 | {0x04, 0x00, 0x14, 0xFF, 0xC0, 0x00, 0x11, 0x08}, | ||
467 | {0x00, 0xF0, 0x01, 0x40, 0x03, 0x00, 0x21, 0x00}, | ||
468 | {0x01, 0x11, 0x01, 0x02, 0x11, 0x01, 0xFF, 0xDA}, | ||
469 | {0x00, 0x0C, 0x03, 0x00, 0x00, 0x01, 0x11, 0x02}, | ||
470 | {0x11, 0x00, 0x3F, 0x00, 0xFF, 0xD9, 0x00, 0x00} /* 79 */ | ||
471 | }; | ||
472 | |||
473 | |||
474 | static __u8 cxjpeg_640[][8] = { | ||
475 | {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x10}, /* 1 */ | ||
476 | {0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, 0x0d}, | ||
477 | {0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28, 0x1a}, | ||
478 | {0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25, 0x1d}, | ||
479 | {0x28, 0x3a, 0x33, 0x3D, 0x3C, 0x39, 0x33, 0x38}, | ||
480 | {0x37, 0x40, 0x48, 0x5C, 0x4E, 0x40, 0x44, 0x57}, | ||
481 | {0x45, 0x37, 0x38, 0x50, 0x6D, 0x51, 0x57, 0x5F}, | ||
482 | {0x62, 0x67, 0x68, 0x67, 0x3E, 0x4D, 0x71, 0x79}, | ||
483 | {0x70, 0x64, 0x78, 0x5C, 0x65, 0x67, 0x63, 0x01}, | ||
484 | {0x10, 0x0B, 0x0C, 0x0E, 0x0C, 0x0A, 0x10, 0x0E}, | ||
485 | {0x0D, 0x0E, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28}, | ||
486 | {0x1A, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25}, | ||
487 | {0x1D, 0x28, 0x3A, 0x33, 0x3D, 0x3C, 0x39, 0x33}, | ||
488 | {0x38, 0x37, 0x40, 0x48, 0x5C, 0x4E, 0x40, 0x44}, | ||
489 | {0x57, 0x45, 0x37, 0x38, 0x50, 0x6D, 0x51, 0x57}, | ||
490 | {0x5F, 0x62, 0x67, 0x68, 0x67, 0x3E, 0x4D, 0x71}, | ||
491 | {0x79, 0x70, 0x64, 0x78, 0x5C, 0x65, 0x67, 0x63}, | ||
492 | {0xFF, 0x20, 0x00, 0x1F, 0x00, 0x83, 0x00, 0x00}, | ||
493 | {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00}, | ||
494 | {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22}, | ||
495 | {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55}, | ||
496 | {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x28, 0xFF}, | ||
497 | {0xC0, 0x00, 0x11, 0x08, 0x01, 0xE0, 0x02, 0x80}, | ||
498 | {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02}, | ||
499 | {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00}, | ||
500 | {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00}, | ||
501 | {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 27 */ | ||
502 | }; | ||
503 | static __u8 cxjpeg_352[][8] = { | ||
504 | {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x0d}, | ||
505 | {0x09, 0x09, 0x0b, 0x09, 0x08, 0x0D, 0x0b, 0x0a}, | ||
506 | {0x0b, 0x0e, 0x0d, 0x0d, 0x0f, 0x13, 0x1f, 0x14}, | ||
507 | {0x13, 0x11, 0x11, 0x13, 0x26, 0x1b, 0x1d, 0x17}, | ||
508 | {0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28, 0x2C}, | ||
509 | {0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35, 0x44}, | ||
510 | {0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44, 0x4A}, | ||
511 | {0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58, 0x5F}, | ||
512 | {0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D, 0x01}, | ||
513 | {0x0D, 0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B}, | ||
514 | {0x0A, 0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F}, | ||
515 | {0x14, 0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D}, | ||
516 | {0x17, 0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28}, | ||
517 | {0x2C, 0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35}, | ||
518 | {0x44, 0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44}, | ||
519 | {0x4A, 0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58}, | ||
520 | {0x5F, 0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D}, | ||
521 | {0xFF, 0x20, 0x00, 0x1F, 0x01, 0x83, 0x00, 0x00}, | ||
522 | {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00}, | ||
523 | {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22}, | ||
524 | {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55}, | ||
525 | {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x16, 0xFF}, | ||
526 | {0xC0, 0x00, 0x11, 0x08, 0x01, 0x20, 0x01, 0x60}, | ||
527 | {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02}, | ||
528 | {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00}, | ||
529 | {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00}, | ||
530 | {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} | ||
531 | }; | ||
532 | static __u8 cxjpeg_320[][8] = { | ||
533 | {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x05}, | ||
534 | {0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04, 0x04}, | ||
535 | {0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x0c, 0x08}, | ||
536 | {0x07, 0x07, 0x07, 0x07, 0x0f, 0x0b, 0x0b, 0x09}, | ||
537 | {0x0C, 0x11, 0x0F, 0x12, 0x12, 0x11, 0x0f, 0x11}, | ||
538 | {0x11, 0x13, 0x16, 0x1C, 0x17, 0x13, 0x14, 0x1A}, | ||
539 | {0x15, 0x11, 0x11, 0x18, 0x21, 0x18, 0x1A, 0x1D}, | ||
540 | {0x1D, 0x1F, 0x1F, 0x1F, 0x13, 0x17, 0x22, 0x24}, | ||
541 | {0x22, 0x1E, 0x24, 0x1C, 0x1E, 0x1F, 0x1E, 0x01}, | ||
542 | {0x05, 0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04}, | ||
543 | {0x04, 0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x0C}, | ||
544 | {0x08, 0x07, 0x07, 0x07, 0x07, 0x0F, 0x0B, 0x0B}, | ||
545 | {0x09, 0x0C, 0x11, 0x0F, 0x12, 0x12, 0x11, 0x0F}, | ||
546 | {0x11, 0x11, 0x13, 0x16, 0x1C, 0x17, 0x13, 0x14}, | ||
547 | {0x1A, 0x15, 0x11, 0x11, 0x18, 0x21, 0x18, 0x1A}, | ||
548 | {0x1D, 0x1D, 0x1F, 0x1F, 0x1F, 0x13, 0x17, 0x22}, | ||
549 | {0x24, 0x22, 0x1E, 0x24, 0x1C, 0x1E, 0x1F, 0x1E}, | ||
550 | {0xFF, 0x20, 0x00, 0x1F, 0x02, 0x0C, 0x00, 0x00}, | ||
551 | {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00}, | ||
552 | {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22}, | ||
553 | {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55}, | ||
554 | {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x14, 0xFF}, | ||
555 | {0xC0, 0x00, 0x11, 0x08, 0x00, 0xF0, 0x01, 0x40}, | ||
556 | {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02}, | ||
557 | {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00}, | ||
558 | {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00}, | ||
559 | {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 27 */ | ||
560 | }; | ||
561 | static __u8 cxjpeg_176[][8] = { | ||
562 | {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x0d}, | ||
563 | {0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B, 0x0A}, | ||
564 | {0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F, 0x14}, | ||
565 | {0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D, 0x17}, | ||
566 | {0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28, 0x2C}, | ||
567 | {0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35, 0x44}, | ||
568 | {0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44, 0x4A}, | ||
569 | {0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58, 0x5F}, | ||
570 | {0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D, 0x01}, | ||
571 | {0x0D, 0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B}, | ||
572 | {0x0A, 0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F}, | ||
573 | {0x14, 0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D}, | ||
574 | {0x17, 0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28}, | ||
575 | {0x2C, 0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35}, | ||
576 | {0x44, 0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44}, | ||
577 | {0x4A, 0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58}, | ||
578 | {0x5F, 0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D}, | ||
579 | {0xFF, 0x20, 0x00, 0x1F, 0x03, 0xA1, 0x00, 0x00}, | ||
580 | {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00}, | ||
581 | {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22}, | ||
582 | {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55}, | ||
583 | {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x0B, 0xFF}, | ||
584 | {0xC0, 0x00, 0x11, 0x08, 0x00, 0x90, 0x00, 0xB0}, | ||
585 | {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02}, | ||
586 | {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00}, | ||
587 | {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00}, | ||
588 | {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} | ||
589 | }; | ||
590 | static __u8 cxjpeg_qtable[][8] = { /* 640 take with the zcx30x part */ | ||
591 | {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x08}, | ||
592 | {0x06, 0x06, 0x07, 0x06, 0x05, 0x08, 0x07, 0x07}, | ||
593 | {0x07, 0x09, 0x09, 0x08, 0x0a, 0x0c, 0x14, 0x0a}, | ||
594 | {0x0c, 0x0b, 0x0b, 0x0c, 0x19, 0x12, 0x13, 0x0f}, | ||
595 | {0x14, 0x1d, 0x1a, 0x1f, 0x1e, 0x1d, 0x1a, 0x1c}, | ||
596 | {0x1c, 0x20, 0x24, 0x2e, 0x27, 0x20, 0x22, 0x2c}, | ||
597 | {0x23, 0x1c, 0x1c, 0x28, 0x37, 0x29, 0x2c, 0x30}, | ||
598 | {0x31, 0x34, 0x34, 0x34, 0x1f, 0x27, 0x39, 0x3d}, | ||
599 | {0x38, 0x32, 0x3c, 0x2e, 0x33, 0x34, 0x32, 0x01}, | ||
600 | {0x09, 0x09, 0x09, 0x0c, 0x0b, 0x0c, 0x18, 0x0a}, | ||
601 | {0x0a, 0x18, 0x32, 0x21, 0x1c, 0x21, 0x32, 0x32}, | ||
602 | {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32}, | ||
603 | {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32}, | ||
604 | {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32}, | ||
605 | {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32}, | ||
606 | {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32}, | ||
607 | {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32}, | ||
608 | {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 18 */ | ||
609 | }; | ||
610 | |||
611 | |||
612 | static void cx11646_jpegInit(struct gspca_dev*gspca_dev) | ||
613 | { | ||
614 | __u8 val; | ||
615 | int i; | ||
616 | int length; | ||
617 | |||
618 | val = 0x01; | ||
619 | reg_w(gspca_dev->dev, 0x00c0, &val, 1); | ||
620 | val = 0x00; | ||
621 | reg_w(gspca_dev->dev, 0x00c3, &val, 1); | ||
622 | val = 0x00; | ||
623 | reg_w(gspca_dev->dev, 0x00c0, &val, 1); | ||
624 | reg_r(gspca_dev->dev, 0x0001, &val, 1); | ||
625 | length = 8; | ||
626 | for (i = 0; i < 79; i++) { | ||
627 | if (i == 78) | ||
628 | length = 6; | ||
629 | reg_w(gspca_dev->dev, 0x0008, cx_jpeg_init[i], length); | ||
630 | } | ||
631 | reg_r(gspca_dev->dev, 0x0002, &val, 1); | ||
632 | val = 0x14; | ||
633 | reg_w(gspca_dev->dev, 0x0055, &val, 1); | ||
634 | } | ||
635 | |||
636 | static __u8 reg12[] = { 0x0a, 0x05, 0x07, 0x04, 0x19 }; | ||
637 | static __u8 regE5_8[] = { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 }; | ||
638 | static __u8 regE5a[] = { 0x88, 0x0a, 0x0c, 0x01 }; | ||
639 | static __u8 regE5b[] = { 0x88, 0x0b, 0x12, 0x01 }; | ||
640 | static __u8 regE5c[] = { 0x88, 0x05, 0x01, 0x01 }; | ||
641 | static __u8 reg51[] = { 0x77, 0x03 }; | ||
642 | static __u8 reg70 = 0x03; | ||
643 | |||
644 | static void cx11646_jpeg(struct gspca_dev*gspca_dev) | ||
645 | { | ||
646 | __u8 val; | ||
647 | int i; | ||
648 | int length = 8; | ||
649 | __u8 Reg55 = 0x14; | ||
650 | __u8 bufread[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; | ||
651 | int retry = 50; | ||
652 | |||
653 | val = 0x01; | ||
654 | reg_w(gspca_dev->dev, 0x00c0, &val, 1); | ||
655 | val = 0x00; | ||
656 | reg_w(gspca_dev->dev, 0x00c3, &val, 1); | ||
657 | val = 0x00; | ||
658 | reg_w(gspca_dev->dev, 0x00c0, &val, 1); | ||
659 | reg_r(gspca_dev->dev, 0x0001, &val, 1); | ||
660 | switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode) { | ||
661 | case 0: | ||
662 | for (i = 0; i < 27; i++) { | ||
663 | if (i == 26) | ||
664 | length = 2; | ||
665 | reg_w(gspca_dev->dev, 0x0008, | ||
666 | cxjpeg_640[i], length); | ||
667 | } | ||
668 | Reg55 = 0x28; | ||
669 | break; | ||
670 | case 1: | ||
671 | for (i = 0; i < 27; i++) { | ||
672 | if (i == 26) | ||
673 | length = 2; | ||
674 | reg_w(gspca_dev->dev, 0x0008, | ||
675 | cxjpeg_352[i], length); | ||
676 | } | ||
677 | Reg55 = 0x16; | ||
678 | break; | ||
679 | default: | ||
680 | /* case 2: */ | ||
681 | for (i = 0; i < 27; i++) { | ||
682 | if (i == 26) | ||
683 | length = 2; | ||
684 | reg_w(gspca_dev->dev, 0x0008, | ||
685 | cxjpeg_320[i], length); | ||
686 | } | ||
687 | Reg55 = 0x14; | ||
688 | break; | ||
689 | case 3: | ||
690 | for (i = 0; i < 27; i++) { | ||
691 | if (i == 26) | ||
692 | length = 2; | ||
693 | reg_w(gspca_dev->dev, 0x0008, | ||
694 | cxjpeg_176[i], length); | ||
695 | } | ||
696 | Reg55 = 0x0B; | ||
697 | break; | ||
698 | } | ||
699 | |||
700 | reg_r(gspca_dev->dev, 0x0002, &val, 1); | ||
701 | val = Reg55; | ||
702 | reg_w(gspca_dev->dev, 0x0055, &val, 1); | ||
703 | reg_r(gspca_dev->dev, 0x0002, &val, 1); | ||
704 | reg_w(gspca_dev->dev, 0x0010, reg10, 2); | ||
705 | val = 0x02; | ||
706 | reg_w(gspca_dev->dev, 0x0054, &val, 1); | ||
707 | val = 0x01; | ||
708 | reg_w(gspca_dev->dev, 0x0054, &val, 1); | ||
709 | val = 0x94; | ||
710 | reg_w(gspca_dev->dev, 0x0000, &val, 1); | ||
711 | val = 0xc0; | ||
712 | reg_w(gspca_dev->dev, 0x0053, &val, 1); | ||
713 | val = 0xe1; | ||
714 | reg_w(gspca_dev->dev, 0x00fc, &val, 1); | ||
715 | val = 0x00; | ||
716 | reg_w(gspca_dev->dev, 0x0000, &val, 1); | ||
717 | /* wait for completion */ | ||
718 | while (retry--) { | ||
719 | reg_r(gspca_dev->dev, 0x0002, &val, 1); | ||
720 | /* 0x07 until 0x00 */ | ||
721 | if (val == 0x00) | ||
722 | break; | ||
723 | val = 0x00; | ||
724 | reg_w(gspca_dev->dev, 0x0053, &val, 1); | ||
725 | } | ||
726 | if (retry == 0) | ||
727 | PDEBUG(D_ERR, "Damned Errors sending jpeg Table"); | ||
728 | /* send the qtable now */ | ||
729 | reg_r(gspca_dev->dev, 0x0001, &val, 1); /* -> 0x18 */ | ||
730 | length = 8; | ||
731 | for (i = 0; i < 18; i++) { | ||
732 | if (i == 17) | ||
733 | length = 2; | ||
734 | reg_w(gspca_dev->dev, 0x0008, | ||
735 | cxjpeg_qtable[i], length); | ||
736 | |||
737 | } | ||
738 | reg_r(gspca_dev->dev, 0x0002, &val, 1); /* 0x00 */ | ||
739 | reg_r(gspca_dev->dev, 0x0053, &val, 1); /* 0x00 */ | ||
740 | val = 0x02; | ||
741 | reg_w(gspca_dev->dev, 0x0054, &val, 1); | ||
742 | val = 0x01; | ||
743 | reg_w(gspca_dev->dev, 0x0054, &val, 1); | ||
744 | val = 0x94; | ||
745 | reg_w(gspca_dev->dev, 0x0000, &val, 1); | ||
746 | val = 0xc0; | ||
747 | reg_w(gspca_dev->dev, 0x0053, &val, 1); | ||
748 | |||
749 | reg_r(gspca_dev->dev, 0x0038, &val, 1); /* 0x40 */ | ||
750 | reg_r(gspca_dev->dev, 0x0038, &val, 1); /* 0x40 */ | ||
751 | reg_r(gspca_dev->dev, 0x001f, &val, 1); /* 0x38 */ | ||
752 | reg_w(gspca_dev->dev, 0x0012, reg12, 5); | ||
753 | reg_w(gspca_dev->dev, 0x00e5, regE5_8, 8); | ||
754 | reg_r(gspca_dev->dev, 0x00e8, bufread, 8); | ||
755 | reg_w(gspca_dev->dev, 0x00e5, regE5a, 4); | ||
756 | reg_r(gspca_dev->dev, 0x00e8, &val, 1); /* 0x00 */ | ||
757 | val = 0x01; | ||
758 | reg_w(gspca_dev->dev, 0x009a, &val, 1); | ||
759 | reg_w(gspca_dev->dev, 0x00e5, regE5b, 4); | ||
760 | reg_r(gspca_dev->dev, 0x00e8, &val, 1); /* 0x00 */ | ||
761 | reg_w(gspca_dev->dev, 0x00e5, regE5c, 4); | ||
762 | reg_r(gspca_dev->dev, 0x00e8, &val, 1); /* 0x00 */ | ||
763 | |||
764 | reg_w(gspca_dev->dev, 0x0051, reg51, 2); | ||
765 | reg_w(gspca_dev->dev, 0x0010, reg10, 2); | ||
766 | reg_w(gspca_dev->dev, 0x0070, ®70, 1); | ||
767 | } | ||
768 | |||
769 | static void cx11646_init1(struct gspca_dev *gspca_dev) | ||
770 | { | ||
771 | __u8 val; | ||
772 | int i = 0; | ||
773 | |||
774 | val = 0; | ||
775 | reg_w(gspca_dev->dev, 0x0010, &val, 1); | ||
776 | reg_w(gspca_dev->dev, 0x0053, &val, 1); | ||
777 | reg_w(gspca_dev->dev, 0x0052, &val, 1); | ||
778 | val = 0x2f; | ||
779 | reg_w(gspca_dev->dev, 0x009b, &val, 1); | ||
780 | val = 0x10; | ||
781 | reg_w(gspca_dev->dev, 0x009c, &val, 1); | ||
782 | reg_r(gspca_dev->dev, 0x0098, &val, 1); | ||
783 | val = 0x40; | ||
784 | reg_w(gspca_dev->dev, 0x0098, &val, 1); | ||
785 | reg_r(gspca_dev->dev, 0x0099, &val, 1); | ||
786 | val = 0x07; | ||
787 | reg_w(gspca_dev->dev, 0x0099, &val, 1); | ||
788 | val = 0x40; | ||
789 | reg_w(gspca_dev->dev, 0x0039, &val, 1); | ||
790 | val = 0xff; | ||
791 | reg_w(gspca_dev->dev, 0x003c, &val, 1); | ||
792 | val = 0x1f; | ||
793 | reg_w(gspca_dev->dev, 0x003f, &val, 1); | ||
794 | val = 0x40; | ||
795 | reg_w(gspca_dev->dev, 0x003d, &val, 1); | ||
796 | /* val= 0x60; */ | ||
797 | /* reg_w(gspca_dev->dev,0x00,0x00,0x003d,&val,1); */ | ||
798 | reg_r(gspca_dev->dev, 0x0099, &val, 1); /* ->0x07 */ | ||
799 | |||
800 | while (cx_sensor_init[i][0]) { | ||
801 | reg_w(gspca_dev->dev, 0x00e5, cx_sensor_init[i], 1); | ||
802 | reg_r(gspca_dev->dev, 0x00e8, &val, 1); /* -> 0x00 */ | ||
803 | if (i == 1) { | ||
804 | val = 1; | ||
805 | reg_w(gspca_dev->dev, 0x00ed, &val, 1); | ||
806 | reg_r(gspca_dev->dev, 0x00ed, &val, 1); /* -> 0x01 */ | ||
807 | } | ||
808 | i++; | ||
809 | } | ||
810 | val = 0x00; | ||
811 | reg_w(gspca_dev->dev, 0x00c3, &val, 1); | ||
812 | } | ||
813 | |||
814 | /* this function is called at probe time */ | ||
815 | static int sd_config(struct gspca_dev *gspca_dev, | ||
816 | const struct usb_device_id *id) | ||
817 | { | ||
818 | struct sd *sd = (struct sd *) gspca_dev; | ||
819 | struct cam *cam; | ||
820 | |||
821 | cam = &gspca_dev->cam; | ||
822 | cam->dev_name = (char *) id->driver_info; | ||
823 | cam->epaddr = 0x01; | ||
824 | cam->cam_mode = vga_mode; | ||
825 | cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; | ||
826 | |||
827 | sd->qindex = 0; /* set the quantization table */ | ||
828 | sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; | ||
829 | sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; | ||
830 | sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; | ||
831 | return 0; | ||
832 | } | ||
833 | |||
834 | /* this function is called at open time */ | ||
835 | static int sd_open(struct gspca_dev *gspca_dev) | ||
836 | { | ||
837 | cx11646_init1(gspca_dev); | ||
838 | cx11646_initsize(gspca_dev); | ||
839 | cx11646_fw(gspca_dev); | ||
840 | cx_sensor(gspca_dev); | ||
841 | cx11646_jpegInit(gspca_dev); | ||
842 | return 0; | ||
843 | } | ||
844 | |||
845 | static void sd_start(struct gspca_dev *gspca_dev) | ||
846 | { | ||
847 | cx11646_initsize(gspca_dev); | ||
848 | cx11646_fw(gspca_dev); | ||
849 | cx_sensor(gspca_dev); | ||
850 | cx11646_jpeg(gspca_dev); | ||
851 | } | ||
852 | |||
853 | static void sd_stopN(struct gspca_dev *gspca_dev) | ||
854 | { | ||
855 | } | ||
856 | |||
857 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
858 | { | ||
859 | int retry = 50; | ||
860 | __u8 val; | ||
861 | |||
862 | val = 0; | ||
863 | reg_w(gspca_dev->dev, 0x0000, &val, 1); | ||
864 | reg_r(gspca_dev->dev, 0x0002, &val, 1); | ||
865 | val = 0; | ||
866 | reg_w(gspca_dev->dev, 0x0053, &val, 1); | ||
867 | |||
868 | while (retry--) { | ||
869 | /* reg_r (gspca_dev->dev,0x00,0x00,0x0002,&val,1);*/ | ||
870 | reg_r(gspca_dev->dev, 0x0053, &val, 1); | ||
871 | if (val == 0) | ||
872 | break; | ||
873 | } | ||
874 | val = 0; | ||
875 | reg_w(gspca_dev->dev, 0x0000, &val, 1); | ||
876 | reg_r(gspca_dev->dev, 0x0002, &val, 1); | ||
877 | |||
878 | val = 0; | ||
879 | reg_w(gspca_dev->dev, 0x0010, &val, 1); | ||
880 | reg_r(gspca_dev->dev, 0x0033, &val, 1); | ||
881 | val = 0xe0; | ||
882 | reg_w(gspca_dev->dev, 0x00fc, &val, 1); | ||
883 | } | ||
884 | |||
885 | static void sd_close(struct gspca_dev *gspca_dev) | ||
886 | { | ||
887 | } | ||
888 | |||
889 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | ||
890 | struct gspca_frame *frame, /* target */ | ||
891 | unsigned char *data, /* isoc packet */ | ||
892 | int len) /* iso packet length */ | ||
893 | { | ||
894 | if (data[0] == 0xff && data[1] == 0xd8) { | ||
895 | |||
896 | /* start of frame */ | ||
897 | frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, | ||
898 | data, 0); | ||
899 | |||
900 | /* put the JPEG header in the new frame */ | ||
901 | jpeg_put_header(gspca_dev, frame, | ||
902 | ((struct sd *) gspca_dev)->qindex, | ||
903 | 0x22); | ||
904 | data += 2; | ||
905 | len -= 2; | ||
906 | } | ||
907 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); | ||
908 | } | ||
909 | |||
910 | static void setbrightness(struct gspca_dev*gspca_dev) | ||
911 | { | ||
912 | struct sd *sd = (struct sd *) gspca_dev; | ||
913 | __u8 regE5cbx[] = { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 }; | ||
914 | __u8 reg51c[] = { 0x77, 0x03 }; | ||
915 | __u8 bright; | ||
916 | __u8 colors; | ||
917 | __u8 val; | ||
918 | __u8 bufread[8]; | ||
919 | |||
920 | bright = sd->brightness; | ||
921 | colors = sd->colors; | ||
922 | regE5cbx[2] = bright; | ||
923 | reg51c[1] = colors; | ||
924 | reg_w(gspca_dev->dev, 0x00e5, regE5cbx, 8); | ||
925 | reg_r(gspca_dev->dev, 0x00e8, bufread, 8); | ||
926 | reg_w(gspca_dev->dev, 0x00e5, regE5c, 4); | ||
927 | reg_r(gspca_dev->dev, 0x00e8, &val, 1); /* 0x00 */ | ||
928 | |||
929 | reg_w(gspca_dev->dev, 0x0051, reg51c, 2); | ||
930 | reg_w(gspca_dev->dev, 0x0010, reg10, 2); | ||
931 | reg_w(gspca_dev->dev, 0x0070, ®70, 1); | ||
932 | } | ||
933 | |||
934 | static void setcontrast(struct gspca_dev*gspca_dev) | ||
935 | { | ||
936 | struct sd *sd = (struct sd *) gspca_dev; | ||
937 | __u8 regE5acx[] = { 0x88, 0x0a, 0x0c, 0x01 }; /* seem MSB */ | ||
938 | /* __u8 regE5bcx[]={0x88,0x0b,0x12,0x01}; // LSB */ | ||
939 | __u8 reg51c[] = { 0x77, 0x03 }; | ||
940 | __u8 val; | ||
941 | |||
942 | reg51c[1] = sd->colors; | ||
943 | regE5acx[2] = sd->contrast; | ||
944 | reg_w(gspca_dev->dev, 0x00e5, regE5acx, 4); | ||
945 | reg_r(gspca_dev->dev, 0x00e8, &val, 1); /* 0x00 */ | ||
946 | reg_w(gspca_dev->dev, 0x0051, reg51c, 2); | ||
947 | reg_w(gspca_dev->dev, 0x0010, reg10, 2); | ||
948 | reg_w(gspca_dev->dev, 0x0070, ®70, 1); | ||
949 | } | ||
950 | |||
951 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | ||
952 | { | ||
953 | struct sd *sd = (struct sd *) gspca_dev; | ||
954 | |||
955 | sd->brightness = val; | ||
956 | if (gspca_dev->streaming) | ||
957 | setbrightness(gspca_dev); | ||
958 | return 0; | ||
959 | } | ||
960 | |||
961 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
962 | { | ||
963 | struct sd *sd = (struct sd *) gspca_dev; | ||
964 | |||
965 | *val = sd->brightness; | ||
966 | return 0; | ||
967 | } | ||
968 | |||
969 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | ||
970 | { | ||
971 | struct sd *sd = (struct sd *) gspca_dev; | ||
972 | |||
973 | sd->contrast = val; | ||
974 | if (gspca_dev->streaming) | ||
975 | setcontrast(gspca_dev); | ||
976 | return 0; | ||
977 | } | ||
978 | |||
979 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) | ||
980 | { | ||
981 | struct sd *sd = (struct sd *) gspca_dev; | ||
982 | |||
983 | *val = sd->contrast; | ||
984 | return 0; | ||
985 | } | ||
986 | |||
987 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) | ||
988 | { | ||
989 | struct sd *sd = (struct sd *) gspca_dev; | ||
990 | |||
991 | sd->colors = val; | ||
992 | if (gspca_dev->streaming) { | ||
993 | setbrightness(gspca_dev); | ||
994 | setcontrast(gspca_dev); | ||
995 | } | ||
996 | return 0; | ||
997 | } | ||
998 | |||
999 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) | ||
1000 | { | ||
1001 | struct sd *sd = (struct sd *) gspca_dev; | ||
1002 | |||
1003 | *val = sd->colors; | ||
1004 | return 0; | ||
1005 | } | ||
1006 | |||
1007 | /* sub-driver description */ | ||
1008 | static struct sd_desc sd_desc = { | ||
1009 | .name = MODULE_NAME, | ||
1010 | .ctrls = sd_ctrls, | ||
1011 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
1012 | .config = sd_config, | ||
1013 | .open = sd_open, | ||
1014 | .start = sd_start, | ||
1015 | .stopN = sd_stopN, | ||
1016 | .stop0 = sd_stop0, | ||
1017 | .close = sd_close, | ||
1018 | .pkt_scan = sd_pkt_scan, | ||
1019 | }; | ||
1020 | |||
1021 | /* -- module initialisation -- */ | ||
1022 | #define DVNM(name) .driver_info = (kernel_ulong_t) name | ||
1023 | static __devinitdata struct usb_device_id device_table[] = { | ||
1024 | {USB_DEVICE(0x0572, 0x0041), DVNM("Creative Notebook cx11646")}, | ||
1025 | {} | ||
1026 | }; | ||
1027 | MODULE_DEVICE_TABLE(usb, device_table); | ||
1028 | |||
1029 | /* -- device connect -- */ | ||
1030 | static int sd_probe(struct usb_interface *intf, | ||
1031 | const struct usb_device_id *id) | ||
1032 | { | ||
1033 | return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), | ||
1034 | THIS_MODULE); | ||
1035 | } | ||
1036 | |||
1037 | static struct usb_driver sd_driver = { | ||
1038 | .name = MODULE_NAME, | ||
1039 | .id_table = device_table, | ||
1040 | .probe = sd_probe, | ||
1041 | .disconnect = gspca_disconnect, | ||
1042 | }; | ||
1043 | |||
1044 | /* -- module insert / remove -- */ | ||
1045 | static int __init sd_mod_init(void) | ||
1046 | { | ||
1047 | if (usb_register(&sd_driver) < 0) | ||
1048 | return -1; | ||
1049 | PDEBUG(D_PROBE, "v%s registered", version); | ||
1050 | return 0; | ||
1051 | } | ||
1052 | static void __exit sd_mod_exit(void) | ||
1053 | { | ||
1054 | usb_deregister(&sd_driver); | ||
1055 | PDEBUG(D_PROBE, "deregistered"); | ||
1056 | } | ||
1057 | |||
1058 | module_init(sd_mod_init); | ||
1059 | module_exit(sd_mod_exit); | ||
diff --git a/drivers/media/video/gspca/etoms.c b/drivers/media/video/gspca/etoms.c new file mode 100644 index 000000000000..c479f638413e --- /dev/null +++ b/drivers/media/video/gspca/etoms.c | |||
@@ -0,0 +1,1062 @@ | |||
1 | /* | ||
2 | * Etoms Et61x151 GPL Linux driver by Michel Xhaard (09/09/2004) | ||
3 | * | ||
4 | * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #define MODULE_NAME "etoms" | ||
22 | |||
23 | #include "gspca.h" | ||
24 | |||
25 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) | ||
26 | static const char version[] = "2.1.0"; | ||
27 | |||
28 | MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); | ||
29 | MODULE_DESCRIPTION("Etoms USB Camera Driver"); | ||
30 | MODULE_LICENSE("GPL"); | ||
31 | |||
32 | /* specific webcam descriptor */ | ||
33 | struct sd { | ||
34 | struct gspca_dev gspca_dev; /* !! must be the first item */ | ||
35 | |||
36 | unsigned char brightness; | ||
37 | unsigned char contrast; | ||
38 | unsigned char colors; | ||
39 | unsigned char autogain; | ||
40 | |||
41 | char sensor; | ||
42 | #define SENSOR_PAS106 0 | ||
43 | #define SENSOR_TAS5130CXX 1 | ||
44 | signed char ag_cnt; | ||
45 | #define AG_CNT_START 13 | ||
46 | }; | ||
47 | |||
48 | /* V4L2 controls supported by the driver */ | ||
49 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
50 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
51 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | ||
52 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | ||
53 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); | ||
54 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); | ||
55 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); | ||
56 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); | ||
57 | |||
58 | static struct ctrl sd_ctrls[] = { | ||
59 | #define SD_BRIGHTNESS 0 | ||
60 | { | ||
61 | { | ||
62 | .id = V4L2_CID_BRIGHTNESS, | ||
63 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
64 | .name = "Brightness", | ||
65 | .minimum = 1, | ||
66 | .maximum = 127, | ||
67 | .step = 1, | ||
68 | .default_value = 63, | ||
69 | }, | ||
70 | .set = sd_setbrightness, | ||
71 | .get = sd_getbrightness, | ||
72 | }, | ||
73 | #define SD_CONTRAST 1 | ||
74 | { | ||
75 | { | ||
76 | .id = V4L2_CID_CONTRAST, | ||
77 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
78 | .name = "Contrast", | ||
79 | .minimum = 0, | ||
80 | .maximum = 255, | ||
81 | .step = 1, | ||
82 | .default_value = 127, | ||
83 | }, | ||
84 | .set = sd_setcontrast, | ||
85 | .get = sd_getcontrast, | ||
86 | }, | ||
87 | #define SD_COLOR 2 | ||
88 | { | ||
89 | { | ||
90 | .id = V4L2_CID_SATURATION, | ||
91 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
92 | .name = "Color", | ||
93 | .minimum = 0, | ||
94 | .maximum = 15, | ||
95 | .step = 1, | ||
96 | .default_value = 7, | ||
97 | }, | ||
98 | .set = sd_setcolors, | ||
99 | .get = sd_getcolors, | ||
100 | }, | ||
101 | #define SD_AUTOGAIN 3 | ||
102 | { | ||
103 | { | ||
104 | .id = V4L2_CID_AUTOGAIN, | ||
105 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
106 | .name = "Auto Gain", | ||
107 | .minimum = 0, | ||
108 | .maximum = 1, | ||
109 | .step = 1, | ||
110 | .default_value = 1, | ||
111 | }, | ||
112 | .set = sd_setautogain, | ||
113 | .get = sd_getautogain, | ||
114 | }, | ||
115 | }; | ||
116 | |||
117 | static struct cam_mode vga_mode[] = { | ||
118 | {V4L2_PIX_FMT_SBGGR8, 320, 240, 1}, | ||
119 | /* {V4L2_PIX_FMT_SBGGR8, 640, 480, 0}, */ | ||
120 | }; | ||
121 | |||
122 | static struct cam_mode sif_mode[] = { | ||
123 | {V4L2_PIX_FMT_SBGGR8, 176, 144, 1}, | ||
124 | {V4L2_PIX_FMT_SBGGR8, 352, 288, 0}, | ||
125 | }; | ||
126 | |||
127 | #define ETOMS_ALT_SIZE_1000 12 | ||
128 | |||
129 | #define ET_GPIO_DIR_CTRL 0x04 /* Control IO bit[0..5] (0 in 1 out) */ | ||
130 | #define ET_GPIO_OUT 0x05 /* Only IO data */ | ||
131 | #define ET_GPIO_IN 0x06 /* Read Only IO data */ | ||
132 | #define ET_RESET_ALL 0x03 | ||
133 | #define ET_ClCK 0x01 | ||
134 | #define ET_CTRL 0x02 /* enable i2c OutClck Powerdown mode */ | ||
135 | |||
136 | #define ET_COMP 0x12 /* Compression register */ | ||
137 | #define ET_MAXQt 0x13 | ||
138 | #define ET_MINQt 0x14 | ||
139 | #define ET_COMP_VAL0 0x02 | ||
140 | #define ET_COMP_VAL1 0x03 | ||
141 | |||
142 | #define ET_REG1d 0x1d | ||
143 | #define ET_REG1e 0x1e | ||
144 | #define ET_REG1f 0x1f | ||
145 | #define ET_REG20 0x20 | ||
146 | #define ET_REG21 0x21 | ||
147 | #define ET_REG22 0x22 | ||
148 | #define ET_REG23 0x23 | ||
149 | #define ET_REG24 0x24 | ||
150 | #define ET_REG25 0x25 | ||
151 | /* base registers for luma calculation */ | ||
152 | #define ET_LUMA_CENTER 0x39 | ||
153 | |||
154 | #define ET_G_RED 0x4d | ||
155 | #define ET_G_GREEN1 0x4e | ||
156 | #define ET_G_BLUE 0x4f | ||
157 | #define ET_G_GREEN2 0x50 | ||
158 | #define ET_G_GR_H 0x51 | ||
159 | #define ET_G_GB_H 0x52 | ||
160 | |||
161 | #define ET_O_RED 0x34 | ||
162 | #define ET_O_GREEN1 0x35 | ||
163 | #define ET_O_BLUE 0x36 | ||
164 | #define ET_O_GREEN2 0x37 | ||
165 | |||
166 | #define ET_SYNCHRO 0x68 | ||
167 | #define ET_STARTX 0x69 | ||
168 | #define ET_STARTY 0x6a | ||
169 | #define ET_WIDTH_LOW 0x6b | ||
170 | #define ET_HEIGTH_LOW 0x6c | ||
171 | #define ET_W_H_HEIGTH 0x6d | ||
172 | |||
173 | #define ET_REG6e 0x6e /* OBW */ | ||
174 | #define ET_REG6f 0x6f /* OBW */ | ||
175 | #define ET_REG70 0x70 /* OBW_AWB */ | ||
176 | #define ET_REG71 0x71 /* OBW_AWB */ | ||
177 | #define ET_REG72 0x72 /* OBW_AWB */ | ||
178 | #define ET_REG73 0x73 /* Clkdelay ns */ | ||
179 | #define ET_REG74 0x74 /* test pattern */ | ||
180 | #define ET_REG75 0x75 /* test pattern */ | ||
181 | |||
182 | #define ET_I2C_CLK 0x8c | ||
183 | #define ET_PXL_CLK 0x60 | ||
184 | |||
185 | #define ET_I2C_BASE 0x89 | ||
186 | #define ET_I2C_COUNT 0x8a | ||
187 | #define ET_I2C_PREFETCH 0x8b | ||
188 | #define ET_I2C_REG 0x88 | ||
189 | #define ET_I2C_DATA7 0x87 | ||
190 | #define ET_I2C_DATA6 0x86 | ||
191 | #define ET_I2C_DATA5 0x85 | ||
192 | #define ET_I2C_DATA4 0x84 | ||
193 | #define ET_I2C_DATA3 0x83 | ||
194 | #define ET_I2C_DATA2 0x82 | ||
195 | #define ET_I2C_DATA1 0x81 | ||
196 | #define ET_I2C_DATA0 0x80 | ||
197 | |||
198 | #define PAS106_REG2 0x02 /* pxlClk = systemClk/(reg2) */ | ||
199 | #define PAS106_REG3 0x03 /* line/frame H [11..4] */ | ||
200 | #define PAS106_REG4 0x04 /* line/frame L [3..0] */ | ||
201 | #define PAS106_REG5 0x05 /* exposure time line offset(default 5) */ | ||
202 | #define PAS106_REG6 0x06 /* exposure time pixel offset(default 6) */ | ||
203 | #define PAS106_REG7 0x07 /* signbit Dac (default 0) */ | ||
204 | #define PAS106_REG9 0x09 | ||
205 | #define PAS106_REG0e 0x0e /* global gain [4..0](default 0x0e) */ | ||
206 | #define PAS106_REG13 0x13 /* end i2c write */ | ||
207 | |||
208 | static __u8 GainRGBG[] = { 0x80, 0x80, 0x80, 0x80, 0x00, 0x00 }; | ||
209 | |||
210 | static __u8 I2c2[] = { 0x08, 0x08, 0x08, 0x08, 0x0d }; | ||
211 | |||
212 | static __u8 I2c3[] = { 0x12, 0x05 }; | ||
213 | |||
214 | static __u8 I2c4[] = { 0x41, 0x08 }; | ||
215 | |||
216 | static void Et_RegRead(struct usb_device *dev, | ||
217 | __u16 index, __u8 *buffer, int len) | ||
218 | { | ||
219 | usb_control_msg(dev, | ||
220 | usb_rcvctrlpipe(dev, 0), | ||
221 | 0, | ||
222 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, | ||
223 | 0, index, buffer, len, 500); | ||
224 | } | ||
225 | |||
226 | static void Et_RegWrite(struct usb_device *dev, | ||
227 | __u16 index, __u8 *buffer, __u16 len) | ||
228 | { | ||
229 | usb_control_msg(dev, | ||
230 | usb_sndctrlpipe(dev, 0), | ||
231 | 0, | ||
232 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, | ||
233 | 0, index, buffer, len, 500); | ||
234 | } | ||
235 | |||
236 | static int Et_i2cwrite(struct usb_device *dev, __u8 reg, __u8 * buffer, | ||
237 | __u16 length, __u8 mode) | ||
238 | { | ||
239 | /* buffer should be [D0..D7] */ | ||
240 | int i, j; | ||
241 | __u8 base = 0x40; /* sensor base for the pas106 */ | ||
242 | __u8 ptchcount = 0; | ||
243 | |||
244 | ptchcount = (((length & 0x07) << 4) | (mode & 0x03)); | ||
245 | /* set the base address */ | ||
246 | Et_RegWrite(dev, ET_I2C_BASE, &base, 1); | ||
247 | /* set count and prefetch */ | ||
248 | Et_RegWrite(dev, ET_I2C_COUNT, &ptchcount, 1); | ||
249 | /* set the register base */ | ||
250 | Et_RegWrite(dev, ET_I2C_REG, ®, 1); | ||
251 | j = length - 1; | ||
252 | for (i = 0; i < length; i++) { | ||
253 | Et_RegWrite(dev, (ET_I2C_DATA0 + j), &buffer[j], 1); | ||
254 | j--; | ||
255 | } | ||
256 | return 0; | ||
257 | } | ||
258 | |||
259 | static int Et_i2cread(struct usb_device *dev, __u8 reg, __u8 * buffer, | ||
260 | __u16 length, __u8 mode) | ||
261 | { | ||
262 | /* buffer should be [D0..D7] */ | ||
263 | int i, j; | ||
264 | __u8 base = 0x40; /* sensor base for the pas106 */ | ||
265 | __u8 ptchcount; | ||
266 | __u8 prefetch = 0x02; | ||
267 | |||
268 | ptchcount = (((length & 0x07) << 4) | (mode & 0x03)); | ||
269 | /* set the base address */ | ||
270 | Et_RegWrite(dev, ET_I2C_BASE, &base, 1); | ||
271 | /* set count and prefetch */ | ||
272 | Et_RegWrite(dev, ET_I2C_COUNT, &ptchcount, 1); | ||
273 | /* set the register base */ | ||
274 | Et_RegWrite(dev, ET_I2C_REG, ®, 1); | ||
275 | Et_RegWrite(dev, ET_I2C_PREFETCH, &prefetch, 1); | ||
276 | prefetch = 0x00; | ||
277 | Et_RegWrite(dev, ET_I2C_PREFETCH, &prefetch, 1); | ||
278 | j = length - 1; | ||
279 | for (i = 0; i < length; i++) { | ||
280 | Et_RegRead(dev, (ET_I2C_DATA0 + j), &buffer[j], 1); | ||
281 | j--; | ||
282 | } | ||
283 | return 0; | ||
284 | } | ||
285 | |||
286 | static int Et_WaitStatus(struct usb_device *dev) | ||
287 | { | ||
288 | __u8 bytereceived; | ||
289 | int retry = 10; | ||
290 | |||
291 | while (retry--) { | ||
292 | Et_RegRead(dev, ET_ClCK, &bytereceived, 1); | ||
293 | if (bytereceived != 0) | ||
294 | return 1; | ||
295 | } | ||
296 | return 0; | ||
297 | } | ||
298 | |||
299 | static int Et_videoOff(struct usb_device *dev) | ||
300 | { | ||
301 | int err; | ||
302 | __u8 stopvideo = 0; | ||
303 | |||
304 | Et_RegWrite(dev, ET_GPIO_OUT, &stopvideo, 1); | ||
305 | err = Et_WaitStatus(dev); | ||
306 | if (!err) | ||
307 | PDEBUG(D_ERR, "timeout Et_waitStatus VideoON"); | ||
308 | return err; | ||
309 | } | ||
310 | |||
311 | static int Et_videoOn(struct usb_device *dev) | ||
312 | { | ||
313 | int err; | ||
314 | __u8 startvideo = 0x10; /* set Bit5 */ | ||
315 | |||
316 | Et_RegWrite(dev, ET_GPIO_OUT, &startvideo, 1); | ||
317 | err = Et_WaitStatus(dev); | ||
318 | if (!err) | ||
319 | PDEBUG(D_ERR, "timeout Et_waitStatus VideoOFF"); | ||
320 | return err; | ||
321 | } | ||
322 | |||
323 | static void Et_init2(struct gspca_dev *gspca_dev) | ||
324 | { | ||
325 | struct usb_device *dev = gspca_dev->dev; | ||
326 | __u8 value = 0x00; | ||
327 | __u8 received = 0x00; | ||
328 | __u8 FormLine[] = { 0x84, 0x03, 0x14, 0xf4, 0x01, 0x05 }; | ||
329 | |||
330 | PDEBUG(D_STREAM, "Open Init2 ET"); | ||
331 | value = 0x2f; | ||
332 | Et_RegWrite(dev, ET_GPIO_DIR_CTRL, &value, 1); | ||
333 | value = 0x10; | ||
334 | Et_RegWrite(dev, ET_GPIO_OUT, &value, 1); | ||
335 | Et_RegRead(dev, ET_GPIO_IN, &received, 1); | ||
336 | value = 0x14; /* 0x14 // 0x16 enabled pattern */ | ||
337 | Et_RegWrite(dev, ET_ClCK, &value, 1); | ||
338 | value = 0x1b; | ||
339 | Et_RegWrite(dev, ET_CTRL, &value, 1); | ||
340 | |||
341 | /* compression et subsampling */ | ||
342 | if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode) | ||
343 | value = ET_COMP_VAL1; /* 320 */ | ||
344 | else | ||
345 | value = ET_COMP_VAL0; /* 640 */ | ||
346 | Et_RegWrite(dev, ET_COMP, &value, 1); | ||
347 | value = 0x1f; | ||
348 | Et_RegWrite(dev, ET_MAXQt, &value, 1); | ||
349 | value = 0x04; | ||
350 | Et_RegWrite(dev, ET_MINQt, &value, 1); | ||
351 | /* undocumented registers */ | ||
352 | value = 0xff; | ||
353 | Et_RegWrite(dev, ET_REG1d, &value, 1); | ||
354 | value = 0xff; | ||
355 | Et_RegWrite(dev, ET_REG1e, &value, 1); | ||
356 | value = 0xff; | ||
357 | Et_RegWrite(dev, ET_REG1f, &value, 1); | ||
358 | value = 0x35; | ||
359 | Et_RegWrite(dev, ET_REG20, &value, 1); | ||
360 | value = 0x01; | ||
361 | Et_RegWrite(dev, ET_REG21, &value, 1); | ||
362 | value = 0x00; | ||
363 | Et_RegWrite(dev, ET_REG22, &value, 1); | ||
364 | value = 0xff; | ||
365 | Et_RegWrite(dev, ET_REG23, &value, 1); | ||
366 | value = 0xff; | ||
367 | Et_RegWrite(dev, ET_REG24, &value, 1); | ||
368 | value = 0x0f; | ||
369 | Et_RegWrite(dev, ET_REG25, &value, 1); | ||
370 | /* colors setting */ | ||
371 | value = 0x11; | ||
372 | Et_RegWrite(dev, 0x30, &value, 1); /* 0x30 */ | ||
373 | value = 0x40; | ||
374 | Et_RegWrite(dev, 0x31, &value, 1); | ||
375 | value = 0x00; | ||
376 | Et_RegWrite(dev, 0x32, &value, 1); | ||
377 | value = 0x00; | ||
378 | Et_RegWrite(dev, ET_O_RED, &value, 1); /* 0x34 */ | ||
379 | value = 0x00; | ||
380 | Et_RegWrite(dev, ET_O_GREEN1, &value, 1); | ||
381 | value = 0x00; | ||
382 | Et_RegWrite(dev, ET_O_BLUE, &value, 1); | ||
383 | value = 0x00; | ||
384 | Et_RegWrite(dev, ET_O_GREEN2, &value, 1); | ||
385 | /*************/ | ||
386 | value = 0x80; | ||
387 | Et_RegWrite(dev, ET_G_RED, &value, 1); /* 0x4d */ | ||
388 | value = 0x80; | ||
389 | Et_RegWrite(dev, ET_G_GREEN1, &value, 1); | ||
390 | value = 0x80; | ||
391 | Et_RegWrite(dev, ET_G_BLUE, &value, 1); | ||
392 | value = 0x80; | ||
393 | Et_RegWrite(dev, ET_G_GREEN2, &value, 1); | ||
394 | value = 0x00; | ||
395 | Et_RegWrite(dev, ET_G_GR_H, &value, 1); | ||
396 | value = 0x00; | ||
397 | Et_RegWrite(dev, ET_G_GB_H, &value, 1); /* 0x52 */ | ||
398 | /* Window control registers */ | ||
399 | |||
400 | value = 0x80; /* use cmc_out */ | ||
401 | Et_RegWrite(dev, 0x61, &value, 1); | ||
402 | |||
403 | value = 0x02; | ||
404 | Et_RegWrite(dev, 0x62, &value, 1); | ||
405 | value = 0x03; | ||
406 | Et_RegWrite(dev, 0x63, &value, 1); | ||
407 | value = 0x14; | ||
408 | Et_RegWrite(dev, 0x64, &value, 1); | ||
409 | value = 0x0e; | ||
410 | Et_RegWrite(dev, 0x65, &value, 1); | ||
411 | value = 0x02; | ||
412 | Et_RegWrite(dev, 0x66, &value, 1); | ||
413 | value = 0x02; | ||
414 | Et_RegWrite(dev, 0x67, &value, 1); | ||
415 | |||
416 | /**************************************/ | ||
417 | value = 0x8f; | ||
418 | Et_RegWrite(dev, ET_SYNCHRO, &value, 1); /* 0x68 */ | ||
419 | value = 0x69; /* 0x6a //0x69 */ | ||
420 | Et_RegWrite(dev, ET_STARTX, &value, 1); | ||
421 | value = 0x0d; /* 0x0d //0x0c */ | ||
422 | Et_RegWrite(dev, ET_STARTY, &value, 1); | ||
423 | value = 0x80; | ||
424 | Et_RegWrite(dev, ET_WIDTH_LOW, &value, 1); | ||
425 | value = 0xe0; | ||
426 | Et_RegWrite(dev, ET_HEIGTH_LOW, &value, 1); | ||
427 | value = 0x60; | ||
428 | Et_RegWrite(dev, ET_W_H_HEIGTH, &value, 1); /* 6d */ | ||
429 | value = 0x86; | ||
430 | Et_RegWrite(dev, ET_REG6e, &value, 1); | ||
431 | value = 0x01; | ||
432 | Et_RegWrite(dev, ET_REG6f, &value, 1); | ||
433 | value = 0x26; | ||
434 | Et_RegWrite(dev, ET_REG70, &value, 1); | ||
435 | value = 0x7a; | ||
436 | Et_RegWrite(dev, ET_REG71, &value, 1); | ||
437 | value = 0x01; | ||
438 | Et_RegWrite(dev, ET_REG72, &value, 1); | ||
439 | /* Clock Pattern registers ***************** */ | ||
440 | value = 0x00; | ||
441 | Et_RegWrite(dev, ET_REG73, &value, 1); | ||
442 | value = 0x18; /* 0x28 */ | ||
443 | Et_RegWrite(dev, ET_REG74, &value, 1); | ||
444 | value = 0x0f; /* 0x01 */ | ||
445 | Et_RegWrite(dev, ET_REG75, &value, 1); | ||
446 | /**********************************************/ | ||
447 | value = 0x20; | ||
448 | Et_RegWrite(dev, 0x8a, &value, 1); | ||
449 | value = 0x0f; | ||
450 | Et_RegWrite(dev, 0x8d, &value, 1); | ||
451 | value = 0x08; | ||
452 | Et_RegWrite(dev, 0x8e, &value, 1); | ||
453 | /**************************************/ | ||
454 | value = 0x08; | ||
455 | Et_RegWrite(dev, 0x03, &value, 1); | ||
456 | value = 0x03; | ||
457 | Et_RegWrite(dev, ET_PXL_CLK, &value, 1); | ||
458 | value = 0xff; | ||
459 | Et_RegWrite(dev, 0x81, &value, 1); | ||
460 | value = 0x00; | ||
461 | Et_RegWrite(dev, 0x80, &value, 1); | ||
462 | value = 0xff; | ||
463 | Et_RegWrite(dev, 0x81, &value, 1); | ||
464 | value = 0x20; | ||
465 | Et_RegWrite(dev, 0x80, &value, 1); | ||
466 | value = 0x01; | ||
467 | Et_RegWrite(dev, 0x03, &value, 1); | ||
468 | value = 0x00; | ||
469 | Et_RegWrite(dev, 0x03, &value, 1); | ||
470 | value = 0x08; | ||
471 | Et_RegWrite(dev, 0x03, &value, 1); | ||
472 | /********************************************/ | ||
473 | |||
474 | /* Et_RegRead(dev,0x0,ET_I2C_BASE,&received,1); | ||
475 | always 0x40 as the pas106 ??? */ | ||
476 | /* set the sensor */ | ||
477 | if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode) { | ||
478 | value = 0x04; /* 320 */ | ||
479 | Et_RegWrite(dev, ET_PXL_CLK, &value, 1); | ||
480 | /* now set by fifo the FormatLine setting */ | ||
481 | Et_RegWrite(dev, 0x62, FormLine, 6); | ||
482 | } else { /* 640 */ | ||
483 | /* setting PixelClock | ||
484 | 0x03 mean 24/(3+1) = 6 Mhz | ||
485 | 0x05 -> 24/(5+1) = 4 Mhz | ||
486 | 0x0b -> 24/(11+1) = 2 Mhz | ||
487 | 0x17 -> 24/(23+1) = 1 Mhz | ||
488 | */ | ||
489 | value = 0x1e; /* 0x17 */ | ||
490 | Et_RegWrite(dev, ET_PXL_CLK, &value, 1); | ||
491 | /* now set by fifo the FormatLine setting */ | ||
492 | Et_RegWrite(dev, 0x62, FormLine, 6); | ||
493 | } | ||
494 | |||
495 | /* set exposure times [ 0..0x78] 0->longvalue 0x78->shortvalue */ | ||
496 | value = 0x47; /* 0x47; */ | ||
497 | Et_RegWrite(dev, 0x81, &value, 1); | ||
498 | value = 0x40; /* 0x40; */ | ||
499 | Et_RegWrite(dev, 0x80, &value, 1); | ||
500 | /* Pedro change */ | ||
501 | /* Brightness change Brith+ decrease value */ | ||
502 | /* Brigth- increase value */ | ||
503 | /* original value = 0x70; */ | ||
504 | value = 0x30; /* 0x20; */ | ||
505 | Et_RegWrite(dev, 0x81, &value, 1); /* set brightness */ | ||
506 | value = 0x20; /* 0x20; */ | ||
507 | Et_RegWrite(dev, 0x80, &value, 1); | ||
508 | } | ||
509 | |||
510 | static void setcolors(struct gspca_dev *gspca_dev) | ||
511 | { | ||
512 | struct sd *sd = (struct sd *) gspca_dev; | ||
513 | struct usb_device *dev = gspca_dev->dev; | ||
514 | static __u8 I2cc[] = { 0x05, 0x02, 0x02, 0x05, 0x0d }; | ||
515 | __u8 i2cflags = 0x01; | ||
516 | /* __u8 green = 0; */ | ||
517 | __u8 colors = sd->colors; | ||
518 | |||
519 | I2cc[3] = colors; /* red */ | ||
520 | I2cc[0] = 15 - colors; /* blue */ | ||
521 | /* green = 15 - ((((7*I2cc[0]) >> 2 ) + I2cc[3]) >> 1); */ | ||
522 | /* I2cc[1] = I2cc[2] = green; */ | ||
523 | if (sd->sensor == SENSOR_PAS106) { | ||
524 | Et_i2cwrite(dev, PAS106_REG13, &i2cflags, 1, 3); | ||
525 | Et_i2cwrite(dev, PAS106_REG9, I2cc, sizeof(I2cc), 1); | ||
526 | } | ||
527 | /* PDEBUG(D_CONF , "Etoms red %d blue %d green %d", | ||
528 | I2cc[3], I2cc[0], green); */ | ||
529 | } | ||
530 | |||
531 | static void getcolors(struct gspca_dev *gspca_dev) | ||
532 | { | ||
533 | struct sd *sd = (struct sd *) gspca_dev; | ||
534 | /* __u8 valblue = 0; */ | ||
535 | __u8 valred; | ||
536 | |||
537 | if (sd->sensor == SENSOR_PAS106) { | ||
538 | /* Et_i2cread(gspca_dev->dev,PAS106_REG9,&valblue,1,1); */ | ||
539 | Et_i2cread(gspca_dev->dev, PAS106_REG9 + 3, &valred, 1, 1); | ||
540 | sd->colors = valred & 0x0f; | ||
541 | } | ||
542 | } | ||
543 | |||
544 | static void Et_init1(struct gspca_dev *gspca_dev) | ||
545 | { | ||
546 | struct usb_device *dev = gspca_dev->dev; | ||
547 | __u8 value = 0x00; | ||
548 | __u8 received = 0x00; | ||
549 | /* __u8 I2c0 [] ={0x0a,0x12,0x05,0x22,0xac,0x00,0x01,0x00}; */ | ||
550 | __u8 I2c0[] = { 0x0a, 0x12, 0x05, 0x6d, 0xcd, 0x00, 0x01, 0x00 }; | ||
551 | /* try 1/120 0x6d 0xcd 0x40 */ | ||
552 | /* __u8 I2c0 [] ={0x0a,0x12,0x05,0xfe,0xfe,0xc0,0x01,0x00}; | ||
553 | * 1/60000 hmm ?? */ | ||
554 | |||
555 | PDEBUG(D_STREAM, "Open Init1 ET"); | ||
556 | value = 7; | ||
557 | Et_RegWrite(dev, ET_GPIO_DIR_CTRL, &value, 1); | ||
558 | Et_RegRead(dev, ET_GPIO_IN, &received, 1); | ||
559 | value = 1; | ||
560 | Et_RegWrite(dev, ET_RESET_ALL, &value, 1); | ||
561 | value = 0; | ||
562 | Et_RegWrite(dev, ET_RESET_ALL, &value, 1); | ||
563 | value = 0x10; | ||
564 | Et_RegWrite(dev, ET_ClCK, &value, 1); | ||
565 | value = 0x19; | ||
566 | Et_RegWrite(dev, ET_CTRL, &value, 1); | ||
567 | /* compression et subsampling */ | ||
568 | if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode) | ||
569 | value = ET_COMP_VAL1; | ||
570 | else | ||
571 | value = ET_COMP_VAL0; | ||
572 | |||
573 | PDEBUG(D_STREAM, "Open mode %d Compression %d", | ||
574 | gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode, | ||
575 | value); | ||
576 | Et_RegWrite(dev, ET_COMP, &value, 1); | ||
577 | value = 0x1d; | ||
578 | Et_RegWrite(dev, ET_MAXQt, &value, 1); | ||
579 | value = 0x02; | ||
580 | Et_RegWrite(dev, ET_MINQt, &value, 1); | ||
581 | /* undocumented registers */ | ||
582 | value = 0xff; | ||
583 | Et_RegWrite(dev, ET_REG1d, &value, 1); | ||
584 | value = 0xff; | ||
585 | Et_RegWrite(dev, ET_REG1e, &value, 1); | ||
586 | value = 0xff; | ||
587 | Et_RegWrite(dev, ET_REG1f, &value, 1); | ||
588 | value = 0x35; | ||
589 | Et_RegWrite(dev, ET_REG20, &value, 1); | ||
590 | value = 0x01; | ||
591 | Et_RegWrite(dev, ET_REG21, &value, 1); | ||
592 | value = 0x00; | ||
593 | Et_RegWrite(dev, ET_REG22, &value, 1); | ||
594 | value = 0xf7; | ||
595 | Et_RegWrite(dev, ET_REG23, &value, 1); | ||
596 | value = 0xff; | ||
597 | Et_RegWrite(dev, ET_REG24, &value, 1); | ||
598 | value = 0x07; | ||
599 | Et_RegWrite(dev, ET_REG25, &value, 1); | ||
600 | /* colors setting */ | ||
601 | value = 0x80; | ||
602 | Et_RegWrite(dev, ET_G_RED, &value, 1); | ||
603 | value = 0x80; | ||
604 | Et_RegWrite(dev, ET_G_GREEN1, &value, 1); | ||
605 | value = 0x80; | ||
606 | Et_RegWrite(dev, ET_G_BLUE, &value, 1); | ||
607 | value = 0x80; | ||
608 | Et_RegWrite(dev, ET_G_GREEN2, &value, 1); | ||
609 | value = 0x00; | ||
610 | Et_RegWrite(dev, ET_G_GR_H, &value, 1); | ||
611 | value = 0x00; | ||
612 | Et_RegWrite(dev, ET_G_GB_H, &value, 1); | ||
613 | /* Window control registers */ | ||
614 | value = 0xf0; | ||
615 | Et_RegWrite(dev, ET_SYNCHRO, &value, 1); | ||
616 | value = 0x56; /* 0x56 */ | ||
617 | Et_RegWrite(dev, ET_STARTX, &value, 1); | ||
618 | value = 0x05; /* 0x04 */ | ||
619 | Et_RegWrite(dev, ET_STARTY, &value, 1); | ||
620 | value = 0x60; | ||
621 | Et_RegWrite(dev, ET_WIDTH_LOW, &value, 1); | ||
622 | value = 0x20; | ||
623 | Et_RegWrite(dev, ET_HEIGTH_LOW, &value, 1); | ||
624 | value = 0x50; | ||
625 | Et_RegWrite(dev, ET_W_H_HEIGTH, &value, 1); | ||
626 | value = 0x86; | ||
627 | Et_RegWrite(dev, ET_REG6e, &value, 1); | ||
628 | value = 0x01; | ||
629 | Et_RegWrite(dev, ET_REG6f, &value, 1); | ||
630 | value = 0x86; | ||
631 | Et_RegWrite(dev, ET_REG70, &value, 1); | ||
632 | value = 0x14; | ||
633 | Et_RegWrite(dev, ET_REG71, &value, 1); | ||
634 | value = 0x00; | ||
635 | Et_RegWrite(dev, ET_REG72, &value, 1); | ||
636 | /* Clock Pattern registers */ | ||
637 | value = 0x00; | ||
638 | Et_RegWrite(dev, ET_REG73, &value, 1); | ||
639 | value = 0x00; | ||
640 | Et_RegWrite(dev, ET_REG74, &value, 1); | ||
641 | value = 0x0a; | ||
642 | Et_RegWrite(dev, ET_REG75, &value, 1); | ||
643 | value = 0x04; | ||
644 | Et_RegWrite(dev, ET_I2C_CLK, &value, 1); | ||
645 | value = 0x01; | ||
646 | Et_RegWrite(dev, ET_PXL_CLK, &value, 1); | ||
647 | /* set the sensor */ | ||
648 | if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode) { | ||
649 | I2c0[0] = 0x06; | ||
650 | Et_i2cwrite(dev, PAS106_REG2, I2c0, sizeof(I2c0), 1); | ||
651 | Et_i2cwrite(dev, PAS106_REG9, I2c2, sizeof(I2c2), 1); | ||
652 | value = 0x06; | ||
653 | Et_i2cwrite(dev, PAS106_REG2, &value, 1, 1); | ||
654 | Et_i2cwrite(dev, PAS106_REG3, I2c3, sizeof(I2c3), 1); | ||
655 | /* value = 0x1f; */ | ||
656 | value = 0x04; | ||
657 | Et_i2cwrite(dev, PAS106_REG0e, &value, 1, 1); | ||
658 | } else { | ||
659 | I2c0[0] = 0x0a; | ||
660 | |||
661 | Et_i2cwrite(dev, PAS106_REG2, I2c0, sizeof(I2c0), 1); | ||
662 | Et_i2cwrite(dev, PAS106_REG9, I2c2, sizeof(I2c2), 1); | ||
663 | value = 0x0a; | ||
664 | |||
665 | Et_i2cwrite(dev, PAS106_REG2, &value, 1, 1); | ||
666 | Et_i2cwrite(dev, PAS106_REG3, I2c3, sizeof(I2c3), 1); | ||
667 | value = 0x04; | ||
668 | /* value = 0x10; */ | ||
669 | Et_i2cwrite(dev, PAS106_REG0e, &value, 1, 1); | ||
670 | /* bit 2 enable bit 1:2 select 0 1 2 3 | ||
671 | value = 0x07; * curve 0 * | ||
672 | Et_i2cwrite(dev,PAS106_REG0f,&value,1,1); | ||
673 | */ | ||
674 | } | ||
675 | |||
676 | /* value = 0x01; */ | ||
677 | /* value = 0x22; */ | ||
678 | /* Et_i2cwrite(dev, PAS106_REG5, &value, 1, 1); */ | ||
679 | /* magnetude and sign bit for DAC */ | ||
680 | Et_i2cwrite(dev, PAS106_REG7, I2c4, sizeof I2c4, 1); | ||
681 | /* now set by fifo the whole colors setting */ | ||
682 | Et_RegWrite(dev, ET_G_RED, GainRGBG, 6); | ||
683 | getcolors(gspca_dev); | ||
684 | setcolors(gspca_dev); | ||
685 | } | ||
686 | |||
687 | /* this function is called at probe time */ | ||
688 | static int sd_config(struct gspca_dev *gspca_dev, | ||
689 | const struct usb_device_id *id) | ||
690 | { | ||
691 | struct sd *sd = (struct sd *) gspca_dev; | ||
692 | struct cam *cam; | ||
693 | __u16 vendor; | ||
694 | __u16 product; | ||
695 | |||
696 | vendor = id->idVendor; | ||
697 | product = id->idProduct; | ||
698 | /* switch (vendor) { */ | ||
699 | /* case 0x102c: * Etoms */ | ||
700 | switch (product) { | ||
701 | case 0x6151: | ||
702 | sd->sensor = SENSOR_PAS106; /* Etoms61x151 */ | ||
703 | break; | ||
704 | case 0x6251: | ||
705 | sd->sensor = SENSOR_TAS5130CXX; /* Etoms61x251 */ | ||
706 | break; | ||
707 | /* } */ | ||
708 | /* break; */ | ||
709 | } | ||
710 | cam = &gspca_dev->cam; | ||
711 | cam->dev_name = (char *) id->driver_info; | ||
712 | cam->epaddr = 1; | ||
713 | if (sd->sensor == SENSOR_PAS106) { | ||
714 | cam->cam_mode = sif_mode; | ||
715 | cam->nmodes = sizeof sif_mode / sizeof sif_mode[0]; | ||
716 | } else { | ||
717 | cam->cam_mode = vga_mode; | ||
718 | cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; | ||
719 | } | ||
720 | sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; | ||
721 | sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; | ||
722 | sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; | ||
723 | sd->autogain = sd_ctrls[SD_AUTOGAIN].qctrl.default_value; | ||
724 | return 0; | ||
725 | } | ||
726 | |||
727 | /* this function is called at open time */ | ||
728 | static int sd_open(struct gspca_dev *gspca_dev) | ||
729 | { | ||
730 | struct sd *sd = (struct sd *) gspca_dev; | ||
731 | struct usb_device *dev = gspca_dev->dev; | ||
732 | int err; | ||
733 | __u8 value; | ||
734 | |||
735 | PDEBUG(D_STREAM, "Initialize ET1"); | ||
736 | if (sd->sensor == SENSOR_PAS106) | ||
737 | Et_init1(gspca_dev); | ||
738 | else | ||
739 | Et_init2(gspca_dev); | ||
740 | value = 0x08; | ||
741 | Et_RegWrite(dev, ET_RESET_ALL, &value, 1); | ||
742 | err = Et_videoOff(dev); | ||
743 | PDEBUG(D_STREAM, "Et_Init_VideoOff %d", err); | ||
744 | return 0; | ||
745 | } | ||
746 | |||
747 | /* -- start the camera -- */ | ||
748 | static void sd_start(struct gspca_dev *gspca_dev) | ||
749 | { | ||
750 | struct sd *sd = (struct sd *) gspca_dev; | ||
751 | struct usb_device *dev = gspca_dev->dev; | ||
752 | int err; | ||
753 | __u8 value; | ||
754 | |||
755 | if (sd->sensor == SENSOR_PAS106) | ||
756 | Et_init1(gspca_dev); | ||
757 | else | ||
758 | Et_init2(gspca_dev); | ||
759 | |||
760 | value = 0x08; | ||
761 | Et_RegWrite(dev, ET_RESET_ALL, &value, 1); | ||
762 | err = Et_videoOn(dev); | ||
763 | PDEBUG(D_STREAM, "Et_VideoOn %d", err); | ||
764 | } | ||
765 | |||
766 | static void sd_stopN(struct gspca_dev *gspca_dev) | ||
767 | { | ||
768 | int err; | ||
769 | |||
770 | err = Et_videoOff(gspca_dev->dev); | ||
771 | PDEBUG(D_STREAM, "Et_VideoOff %d", err); | ||
772 | |||
773 | } | ||
774 | |||
775 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
776 | { | ||
777 | } | ||
778 | |||
779 | static void sd_close(struct gspca_dev *gspca_dev) | ||
780 | { | ||
781 | } | ||
782 | |||
783 | static void setbrightness(struct gspca_dev *gspca_dev) | ||
784 | { | ||
785 | struct sd *sd = (struct sd *) gspca_dev; | ||
786 | int i; | ||
787 | __u8 brightness = sd->brightness; | ||
788 | |||
789 | for (i = 0; i < 4; i++) | ||
790 | Et_RegWrite(gspca_dev->dev, (ET_O_RED + i), &brightness, 1); | ||
791 | } | ||
792 | |||
793 | static void getbrightness(struct gspca_dev *gspca_dev) | ||
794 | { | ||
795 | struct sd *sd = (struct sd *) gspca_dev; | ||
796 | int i; | ||
797 | int brightness = 0; | ||
798 | __u8 value = 0; | ||
799 | |||
800 | for (i = 0; i < 4; i++) { | ||
801 | Et_RegRead(gspca_dev->dev, (ET_O_RED + i), &value, 1); | ||
802 | brightness += value; | ||
803 | } | ||
804 | sd->brightness = brightness >> 3; | ||
805 | } | ||
806 | |||
807 | static void setcontrast(struct gspca_dev *gspca_dev) | ||
808 | { | ||
809 | struct sd *sd = (struct sd *) gspca_dev; | ||
810 | __u8 RGBG[] = { 0x80, 0x80, 0x80, 0x80, 0x00, 0x00 }; | ||
811 | __u8 contrast = sd->contrast; | ||
812 | |||
813 | memset(RGBG, contrast, sizeof RGBG - 2); | ||
814 | Et_RegWrite(gspca_dev->dev, ET_G_RED, RGBG, 6); | ||
815 | } | ||
816 | |||
817 | static void getcontrast(struct gspca_dev *gspca_dev) | ||
818 | { | ||
819 | struct sd *sd = (struct sd *) gspca_dev; | ||
820 | int i; | ||
821 | int contrast = 0; | ||
822 | __u8 value = 0; | ||
823 | |||
824 | for (i = 0; i < 4; i++) { | ||
825 | Et_RegRead(gspca_dev->dev, (ET_G_RED + i), &value, 1); | ||
826 | contrast += value; | ||
827 | } | ||
828 | sd->contrast = contrast >> 2; | ||
829 | } | ||
830 | |||
831 | static __u8 Et_getgainG(struct gspca_dev *gspca_dev) | ||
832 | { | ||
833 | struct sd *sd = (struct sd *) gspca_dev; | ||
834 | __u8 value = 0; | ||
835 | |||
836 | if (sd->sensor == SENSOR_PAS106) { | ||
837 | Et_i2cread(gspca_dev->dev, PAS106_REG0e, &value, 1, 1); | ||
838 | PDEBUG(D_CONF, "Etoms gain G %d", value); | ||
839 | return value; | ||
840 | } | ||
841 | return 0x1f; | ||
842 | } | ||
843 | |||
844 | static void Et_setgainG(struct gspca_dev *gspca_dev, __u8 gain) | ||
845 | { | ||
846 | struct sd *sd = (struct sd *) gspca_dev; | ||
847 | struct usb_device *dev = gspca_dev->dev; | ||
848 | __u8 i2cflags = 0x01; | ||
849 | |||
850 | if (sd->sensor == SENSOR_PAS106) { | ||
851 | Et_i2cwrite(dev, PAS106_REG13, &i2cflags, 1, 3); | ||
852 | Et_i2cwrite(dev, PAS106_REG0e, &gain, 1, 1); | ||
853 | } | ||
854 | } | ||
855 | |||
856 | #define BLIMIT(bright) \ | ||
857 | (__u8)((bright > 0x1f)?0x1f:((bright < 4)?3:bright)) | ||
858 | #define LIMIT(color) \ | ||
859 | (unsigned char)((color > 0xff)?0xff:((color < 0)?0:color)) | ||
860 | |||
861 | static void setautogain(struct gspca_dev *gspca_dev) | ||
862 | { | ||
863 | struct usb_device *dev = gspca_dev->dev; | ||
864 | __u8 GRBG[] = { 0, 0, 0, 0 }; | ||
865 | __u8 luma = 0; | ||
866 | __u8 luma_mean = 128; | ||
867 | __u8 luma_delta = 20; | ||
868 | __u8 spring = 4; | ||
869 | int Gbright = 0; | ||
870 | __u8 r, g, b; | ||
871 | |||
872 | Gbright = Et_getgainG(gspca_dev); | ||
873 | Et_RegRead(dev, ET_LUMA_CENTER, GRBG, 4); | ||
874 | g = (GRBG[0] + GRBG[3]) >> 1; | ||
875 | r = GRBG[1]; | ||
876 | b = GRBG[2]; | ||
877 | r = ((r << 8) - (r << 4) - (r << 3)) >> 10; | ||
878 | b = ((b << 7) >> 10); | ||
879 | g = ((g << 9) + (g << 7) + (g << 5)) >> 10; | ||
880 | luma = LIMIT(r + g + b); | ||
881 | PDEBUG(D_FRAM, "Etoms luma G %d", luma); | ||
882 | if (luma < luma_mean - luma_delta || luma > luma_mean + luma_delta) { | ||
883 | Gbright += (luma_mean - luma) >> spring; | ||
884 | Gbright = BLIMIT(Gbright); | ||
885 | PDEBUG(D_FRAM, "Etoms Gbright %d", Gbright); | ||
886 | Et_setgainG(gspca_dev, (__u8) Gbright); | ||
887 | } | ||
888 | } | ||
889 | |||
890 | #undef BLIMIT | ||
891 | #undef LIMIT | ||
892 | |||
893 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | ||
894 | struct gspca_frame *frame, /* target */ | ||
895 | unsigned char *data, /* isoc packet */ | ||
896 | int len) /* iso packet length */ | ||
897 | { | ||
898 | struct sd *sd; | ||
899 | int seqframe; | ||
900 | |||
901 | seqframe = data[0] & 0x3f; | ||
902 | len = (int) (((data[0] & 0xc0) << 2) | data[1]); | ||
903 | if (seqframe == 0x3f) { | ||
904 | PDEBUG(D_FRAM, | ||
905 | "header packet found datalength %d !!", len); | ||
906 | PDEBUG(D_FRAM, "G %d R %d G %d B %d", | ||
907 | data[2], data[3], data[4], data[5]); | ||
908 | data += 30; | ||
909 | /* don't change datalength as the chips provided it */ | ||
910 | frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, | ||
911 | data, 0); | ||
912 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len); | ||
913 | sd = (struct sd *) gspca_dev; | ||
914 | if (sd->ag_cnt >= 0) { | ||
915 | if (--sd->ag_cnt < 0) { | ||
916 | sd->ag_cnt = AG_CNT_START; | ||
917 | setautogain(gspca_dev); | ||
918 | } | ||
919 | } | ||
920 | return; | ||
921 | } | ||
922 | if (len) { | ||
923 | data += 8; | ||
924 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); | ||
925 | } else { /* Drop Packet */ | ||
926 | gspca_dev->last_packet_type = DISCARD_PACKET; | ||
927 | } | ||
928 | } | ||
929 | |||
930 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | ||
931 | { | ||
932 | struct sd *sd = (struct sd *) gspca_dev; | ||
933 | |||
934 | sd->brightness = val; | ||
935 | if (gspca_dev->streaming) | ||
936 | setbrightness(gspca_dev); | ||
937 | return 0; | ||
938 | } | ||
939 | |||
940 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
941 | { | ||
942 | struct sd *sd = (struct sd *) gspca_dev; | ||
943 | |||
944 | getbrightness(gspca_dev); | ||
945 | *val = sd->brightness; | ||
946 | return 0; | ||
947 | } | ||
948 | |||
949 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | ||
950 | { | ||
951 | struct sd *sd = (struct sd *) gspca_dev; | ||
952 | |||
953 | sd->contrast = val; | ||
954 | if (gspca_dev->streaming) | ||
955 | setcontrast(gspca_dev); | ||
956 | return 0; | ||
957 | } | ||
958 | |||
959 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) | ||
960 | { | ||
961 | struct sd *sd = (struct sd *) gspca_dev; | ||
962 | |||
963 | getcontrast(gspca_dev); | ||
964 | *val = sd->contrast; | ||
965 | return 0; | ||
966 | } | ||
967 | |||
968 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) | ||
969 | { | ||
970 | struct sd *sd = (struct sd *) gspca_dev; | ||
971 | |||
972 | sd->colors = val; | ||
973 | if (gspca_dev->streaming) | ||
974 | setcolors(gspca_dev); | ||
975 | return 0; | ||
976 | } | ||
977 | |||
978 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) | ||
979 | { | ||
980 | struct sd *sd = (struct sd *) gspca_dev; | ||
981 | |||
982 | getcolors(gspca_dev); | ||
983 | *val = sd->colors; | ||
984 | return 0; | ||
985 | } | ||
986 | |||
987 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) | ||
988 | { | ||
989 | struct sd *sd = (struct sd *) gspca_dev; | ||
990 | |||
991 | sd->autogain = val; | ||
992 | if (val) | ||
993 | sd->ag_cnt = AG_CNT_START; | ||
994 | else | ||
995 | sd->ag_cnt = -1; | ||
996 | return 0; | ||
997 | } | ||
998 | |||
999 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) | ||
1000 | { | ||
1001 | struct sd *sd = (struct sd *) gspca_dev; | ||
1002 | |||
1003 | *val = sd->autogain; | ||
1004 | return 0; | ||
1005 | } | ||
1006 | |||
1007 | /* sub-driver description */ | ||
1008 | static struct sd_desc sd_desc = { | ||
1009 | .name = MODULE_NAME, | ||
1010 | .ctrls = sd_ctrls, | ||
1011 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
1012 | .config = sd_config, | ||
1013 | .open = sd_open, | ||
1014 | .start = sd_start, | ||
1015 | .stopN = sd_stopN, | ||
1016 | .stop0 = sd_stop0, | ||
1017 | .close = sd_close, | ||
1018 | .pkt_scan = sd_pkt_scan, | ||
1019 | }; | ||
1020 | |||
1021 | /* -- module initialisation -- */ | ||
1022 | #define DVNM(name) .driver_info = (kernel_ulong_t) name | ||
1023 | static __devinitdata struct usb_device_id device_table[] = { | ||
1024 | {USB_DEVICE(0x102c, 0x6151), DVNM("Qcam Sangha CIF")}, | ||
1025 | {USB_DEVICE(0x102c, 0x6251), DVNM("Qcam xxxxxx VGA")}, | ||
1026 | {} | ||
1027 | }; | ||
1028 | |||
1029 | MODULE_DEVICE_TABLE(usb, device_table); | ||
1030 | |||
1031 | /* -- device connect -- */ | ||
1032 | static int sd_probe(struct usb_interface *intf, | ||
1033 | const struct usb_device_id *id) | ||
1034 | { | ||
1035 | return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), | ||
1036 | THIS_MODULE); | ||
1037 | } | ||
1038 | |||
1039 | static struct usb_driver sd_driver = { | ||
1040 | .name = MODULE_NAME, | ||
1041 | .id_table = device_table, | ||
1042 | .probe = sd_probe, | ||
1043 | .disconnect = gspca_disconnect, | ||
1044 | }; | ||
1045 | |||
1046 | /* -- module insert / remove -- */ | ||
1047 | static int __init sd_mod_init(void) | ||
1048 | { | ||
1049 | if (usb_register(&sd_driver) < 0) | ||
1050 | return -1; | ||
1051 | PDEBUG(D_PROBE, "v%s registered", version); | ||
1052 | return 0; | ||
1053 | } | ||
1054 | |||
1055 | static void __exit sd_mod_exit(void) | ||
1056 | { | ||
1057 | usb_deregister(&sd_driver); | ||
1058 | PDEBUG(D_PROBE, "deregistered"); | ||
1059 | } | ||
1060 | |||
1061 | module_init(sd_mod_init); | ||
1062 | module_exit(sd_mod_exit); | ||
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 423ebbdc4b4f..5583c53e4863 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c | |||
@@ -35,24 +35,24 @@ | |||
35 | 35 | ||
36 | #include "gspca.h" | 36 | #include "gspca.h" |
37 | 37 | ||
38 | /* option */ | 38 | #undef CONFIG_VIDEO_V4L1_COMPAT |
39 | #define GSPCA_HLP 0 | ||
40 | 39 | ||
41 | /* global values */ | 40 | /* global values */ |
42 | #define DEF_NURBS 2 /* default number of URBs (mmap) */ | 41 | #define DEF_NURBS 2 /* default number of URBs (mmap) */ |
42 | #define USR_NURBS 5 /* default number of URBs (userptr) */ | ||
43 | 43 | ||
44 | MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>"); | 44 | MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>"); |
45 | MODULE_DESCRIPTION("GSPCA USB Camera Driver"); | 45 | MODULE_DESCRIPTION("GSPCA USB Camera Driver"); |
46 | MODULE_LICENSE("GPL"); | 46 | MODULE_LICENSE("GPL"); |
47 | 47 | ||
48 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(0, 2, 15) | 48 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) |
49 | static const char version[] = "0.2.15"; | 49 | static const char version[] = "2.1.0"; |
50 | 50 | ||
51 | static int video_nr = -1; | 51 | static int video_nr = -1; |
52 | 52 | ||
53 | static int comp_fac = 30; /* Buffer size ratio when compressed in % */ | 53 | static int comp_fac = 30; /* Buffer size ratio when compressed in % */ |
54 | 54 | ||
55 | #ifdef GSPCA_DEBUG | 55 | #ifdef VIDEO_ADV_DEBUG |
56 | int gspca_debug = D_ERR | D_PROBE; | 56 | int gspca_debug = D_ERR | D_PROBE; |
57 | EXPORT_SYMBOL(gspca_debug); | 57 | EXPORT_SYMBOL(gspca_debug); |
58 | 58 | ||
@@ -81,224 +81,7 @@ static void PDEBUG_MODE(char *txt, __u32 pixfmt, int w, int h) | |||
81 | #define GSPCA_MEMORY_NO 0 /* V4L2_MEMORY_xxx starts from 1 */ | 81 | #define GSPCA_MEMORY_NO 0 /* V4L2_MEMORY_xxx starts from 1 */ |
82 | #define GSPCA_MEMORY_READ 7 | 82 | #define GSPCA_MEMORY_READ 7 |
83 | 83 | ||
84 | #ifndef GSPCA_HLP | ||
85 | #define BUF_ALL_FLAGS (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE) | 84 | #define BUF_ALL_FLAGS (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE) |
86 | #else | ||
87 | #define GSPCA_BUF_FLAG_DECODE 0x1000 /* internal buffer flag */ | ||
88 | #define BUF_ALL_FLAGS (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE \ | ||
89 | | GSPCA_BUF_FLAG_DECODE) | ||
90 | |||
91 | static int autostart = 4; | ||
92 | module_param(autostart, int, 0644); | ||
93 | MODULE_PARM_DESC(autostart, | ||
94 | "Automatically start the helper process"); | ||
95 | |||
96 | /* try to start the helper process */ | ||
97 | static void start_hlp(void) | ||
98 | { | ||
99 | int ret; | ||
100 | static char *argv[] = {"gspca_hlp", NULL}; | ||
101 | static char *env[] = {NULL}; | ||
102 | |||
103 | if (autostart <= 0) { | ||
104 | if (autostart < 0) | ||
105 | PDEBUG(D_ERR|D_PROBE, "Too many helper restart"); | ||
106 | return; | ||
107 | } | ||
108 | autostart--; | ||
109 | if (autostart == 0) | ||
110 | autostart = -1; | ||
111 | ret = call_usermodehelper("/sbin/gspca_hlp", argv, env, | ||
112 | UMH_WAIT_EXEC); | ||
113 | if (ret != 0) | ||
114 | PDEBUG(D_ERR|D_PROBE, | ||
115 | "/sbin/gspca_hlp start failed %d", ret); | ||
116 | } | ||
117 | |||
118 | /* /dev/gspca_hlp stuff */ | ||
119 | #include <linux/miscdevice.h> | ||
120 | #include "gspca_hlp.h" | ||
121 | |||
122 | /* !! possible decodings defined in decoder.c */ | ||
123 | static __u32 bayer_to_tb[] = { | ||
124 | V4L2_PIX_FMT_SBGGR8, | ||
125 | V4L2_PIX_FMT_YUYV, | ||
126 | V4L2_PIX_FMT_YUV420, | ||
127 | V4L2_PIX_FMT_RGB24, | ||
128 | V4L2_PIX_FMT_BGR24, | ||
129 | V4L2_PIX_FMT_RGB565, | ||
130 | }; | ||
131 | static __u32 jpeg_to_tb[] = { | ||
132 | V4L2_PIX_FMT_JPEG, | ||
133 | V4L2_PIX_FMT_YUYV, | ||
134 | V4L2_PIX_FMT_YUV420, | ||
135 | V4L2_PIX_FMT_RGB24, | ||
136 | V4L2_PIX_FMT_BGR24, | ||
137 | V4L2_PIX_FMT_RGB565, | ||
138 | }; | ||
139 | |||
140 | /* /dev/gspca_hlp device */ | ||
141 | struct hlp_dev { | ||
142 | struct gspca_dev *gspca_dev; /* associated device */ | ||
143 | struct gspca_frame *frame; /* frame being decoded */ | ||
144 | __u32 pixfmt; /* webcam pixel format */ | ||
145 | atomic_t nevent; /* nb of frames ready to decode */ | ||
146 | wait_queue_head_t wq; /* wait queue */ | ||
147 | char fr_d; /* next frame to decode */ | ||
148 | } *hlp; | ||
149 | |||
150 | static int hlp_open(struct inode *inode, struct file *file) | ||
151 | { | ||
152 | struct hlp_dev *hlp_dev; | ||
153 | |||
154 | PDEBUG(D_CONF, "hlp open"); | ||
155 | if (hlp != 0) | ||
156 | return -EBUSY; | ||
157 | hlp_dev = kzalloc(sizeof *hlp_dev, GFP_KERNEL); | ||
158 | if (hlp_dev == NULL) { | ||
159 | err("couldn't kzalloc hlp struct"); | ||
160 | return -EIO; | ||
161 | } | ||
162 | init_waitqueue_head(&hlp_dev->wq); | ||
163 | file->private_data = hlp_dev; | ||
164 | hlp = hlp_dev; | ||
165 | return 0; | ||
166 | } | ||
167 | |||
168 | static int hlp_close(struct inode *inode, struct file *file) | ||
169 | { | ||
170 | struct gspca_dev *gspca_dev; | ||
171 | int mode; | ||
172 | |||
173 | PDEBUG(D_CONF, "hlp close"); | ||
174 | file->private_data = NULL; | ||
175 | |||
176 | /* stop decoding */ | ||
177 | gspca_dev = hlp->gspca_dev; | ||
178 | if (gspca_dev != 0) { | ||
179 | mode = gspca_dev->curr_mode; | ||
180 | gspca_dev->pixfmt = gspca_dev->cam.cam_mode[mode].pixfmt; | ||
181 | } | ||
182 | |||
183 | /* destroy the helper structure */ | ||
184 | kfree(hlp); | ||
185 | hlp = 0; | ||
186 | |||
187 | /* try to restart the helper process */ | ||
188 | start_hlp(); | ||
189 | return 0; | ||
190 | } | ||
191 | |||
192 | static ssize_t hlp_read(struct file *file, char __user *buf, | ||
193 | size_t cnt, loff_t *ppos) | ||
194 | { | ||
195 | struct hlp_dev *hlp_dev = file->private_data; | ||
196 | struct gspca_dev *gspca_dev; | ||
197 | struct gspca_frame *frame; | ||
198 | struct gspca_hlp_read_hd head; | ||
199 | int i, j, len, ret; | ||
200 | |||
201 | PDEBUG(D_FRAM, "hlp read (%d)", cnt); | ||
202 | |||
203 | /* check / wait till a frame is ready */ | ||
204 | for (;;) { | ||
205 | gspca_dev = hlp_dev->gspca_dev; | ||
206 | if (gspca_dev != 0 && gspca_dev->streaming) { | ||
207 | i = hlp_dev->fr_d; /* frame to decode */ | ||
208 | j = gspca_dev->fr_queue[i]; | ||
209 | frame = &gspca_dev->frame[j]; | ||
210 | if (frame->v4l2_buf.flags & GSPCA_BUF_FLAG_DECODE) | ||
211 | break; | ||
212 | } | ||
213 | ret = wait_event_interruptible(hlp_dev->wq, | ||
214 | atomic_read(&hlp_dev->nevent) > 0); | ||
215 | if (ret < 0) { /* helper process is killed */ | ||
216 | autostart = 0; /* don't restart it */ | ||
217 | return ret; | ||
218 | } | ||
219 | } | ||
220 | atomic_dec(&hlp_dev->nevent); | ||
221 | hlp_dev->fr_d = (i + 1) % gspca_dev->nframes; | ||
222 | PDEBUG(D_FRAM, "hlp read q:%d i:%d d:%d o:%d", | ||
223 | gspca_dev->fr_q, | ||
224 | gspca_dev->fr_i, | ||
225 | hlp_dev->fr_d, | ||
226 | gspca_dev->fr_o); | ||
227 | |||
228 | hlp_dev->frame = frame; /* memorize the current frame */ | ||
229 | len = frame->v4l2_buf.bytesused; | ||
230 | if (cnt < sizeof head - sizeof head.data + len) | ||
231 | /*fixme: special errno?*/ | ||
232 | return -EINVAL; | ||
233 | head.pixfmt_out = gspca_dev->pixfmt; | ||
234 | head.pixfmt_in = hlp_dev->pixfmt; | ||
235 | head.width = gspca_dev->width; | ||
236 | head.height = gspca_dev->height; | ||
237 | copy_to_user(buf, &head, sizeof head); | ||
238 | copy_to_user(buf + sizeof head - sizeof head.data, | ||
239 | frame->data, len); | ||
240 | return sizeof head - sizeof head.data + len; | ||
241 | } | ||
242 | |||
243 | static ssize_t hlp_write(struct file *file, | ||
244 | const char __user *buf, | ||
245 | size_t cnt, loff_t *ppos) | ||
246 | { | ||
247 | struct hlp_dev *hlp_dev = file->private_data; | ||
248 | struct gspca_dev *gspca_dev; | ||
249 | struct gspca_frame *frame; | ||
250 | |||
251 | PDEBUG(D_FRAM, "hlp write (%d)", cnt); | ||
252 | gspca_dev = hlp_dev->gspca_dev; | ||
253 | if (gspca_dev == 0) | ||
254 | return cnt; | ||
255 | if (mutex_lock_interruptible(&gspca_dev->queue_lock)) | ||
256 | return -ERESTARTSYS; | ||
257 | if (!gspca_dev->streaming) | ||
258 | goto out; | ||
259 | frame = hlp_dev->frame; | ||
260 | hlp_dev->frame = 0; | ||
261 | if (frame == 0) | ||
262 | goto out; | ||
263 | if (cnt > frame->v4l2_buf.length) { | ||
264 | PDEBUG(D_ERR|D_FRAM, "bad frame size %d - %d", | ||
265 | cnt, frame->v4l2_buf.length); | ||
266 | cnt = -EINVAL; | ||
267 | goto out; | ||
268 | } | ||
269 | copy_from_user(frame->data, buf, cnt); | ||
270 | frame->v4l2_buf.bytesused = cnt; | ||
271 | frame->v4l2_buf.flags &= ~(V4L2_BUF_FLAG_QUEUED | ||
272 | | GSPCA_BUF_FLAG_DECODE); | ||
273 | frame->v4l2_buf.flags |= V4L2_BUF_FLAG_DONE; | ||
274 | mutex_unlock(&gspca_dev->queue_lock); | ||
275 | atomic_inc(&gspca_dev->nevent); | ||
276 | wake_up_interruptible(&gspca_dev->wq); /* event = new frame */ | ||
277 | PDEBUG(D_FRAM, "hlp write q:%d i:%d d:%d o:%d", | ||
278 | gspca_dev->fr_q, | ||
279 | gspca_dev->fr_i, | ||
280 | hlp_dev->fr_d, | ||
281 | gspca_dev->fr_o); | ||
282 | return cnt; | ||
283 | out: | ||
284 | mutex_unlock(&gspca_dev->queue_lock); | ||
285 | return cnt; | ||
286 | } | ||
287 | |||
288 | static struct file_operations hlp_fops = { | ||
289 | .owner = THIS_MODULE, | ||
290 | .open = hlp_open, | ||
291 | .release = hlp_close, | ||
292 | .read = hlp_read, | ||
293 | .write = hlp_write, | ||
294 | .llseek = no_llseek | ||
295 | }; | ||
296 | static struct miscdevice hlp_device = { | ||
297 | .minor = MISC_DYNAMIC_MINOR, | ||
298 | .name = "gspca_hlp", | ||
299 | .fops = &hlp_fops, | ||
300 | }; | ||
301 | #endif | ||
302 | 85 | ||
303 | /* | 86 | /* |
304 | * VMA operations. | 87 | * VMA operations. |
@@ -331,10 +114,14 @@ static void fill_frame(struct gspca_dev *gspca_dev, | |||
331 | struct urb *urb) | 114 | struct urb *urb) |
332 | { | 115 | { |
333 | struct gspca_frame *frame; | 116 | struct gspca_frame *frame; |
334 | unsigned char *data; /* address of data in the iso message */ | 117 | __u8 *data; /* address of data in the iso message */ |
335 | int i, j, len, st; | 118 | int i, j, len, st; |
336 | cam_pkt_op pkt_scan; | 119 | cam_pkt_op pkt_scan; |
337 | 120 | ||
121 | if (urb->status != 0) { | ||
122 | PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status); | ||
123 | return; /* disconnection ? */ | ||
124 | } | ||
338 | pkt_scan = gspca_dev->sd_desc->pkt_scan; | 125 | pkt_scan = gspca_dev->sd_desc->pkt_scan; |
339 | for (i = 0; i < urb->number_of_packets; i++) { | 126 | for (i = 0; i < urb->number_of_packets; i++) { |
340 | 127 | ||
@@ -350,20 +137,21 @@ static void fill_frame(struct gspca_dev *gspca_dev, | |||
350 | 137 | ||
351 | /* check the packet status and length */ | 138 | /* check the packet status and length */ |
352 | len = urb->iso_frame_desc[i].actual_length; | 139 | len = urb->iso_frame_desc[i].actual_length; |
140 | if (len == 0) | ||
141 | continue; | ||
353 | st = urb->iso_frame_desc[i].status; | 142 | st = urb->iso_frame_desc[i].status; |
354 | if (st) { | 143 | if (st) { |
355 | PDEBUG(D_ERR, "ISOC data error: [%d] len=%d, status=%d", | 144 | PDEBUG(D_ERR, |
145 | "ISOC data error: [%d] len=%d, status=%d", | ||
356 | i, len, st); | 146 | i, len, st); |
357 | gspca_dev->last_packet_type = DISCARD_PACKET; | 147 | gspca_dev->last_packet_type = DISCARD_PACKET; |
358 | continue; | 148 | continue; |
359 | } | 149 | } |
360 | if (len == 0) | ||
361 | continue; | ||
362 | 150 | ||
363 | /* let the packet be analyzed by the subdriver */ | 151 | /* let the packet be analyzed by the subdriver */ |
364 | PDEBUG(D_PACK, "packet [%d] o:%d l:%d", | 152 | PDEBUG(D_PACK, "packet [%d] o:%d l:%d", |
365 | i, urb->iso_frame_desc[i].offset, len); | 153 | i, urb->iso_frame_desc[i].offset, len); |
366 | data = (unsigned char *) urb->transfer_buffer | 154 | data = (__u8 *) urb->transfer_buffer |
367 | + urb->iso_frame_desc[i].offset; | 155 | + urb->iso_frame_desc[i].offset; |
368 | pkt_scan(gspca_dev, frame, data, len); | 156 | pkt_scan(gspca_dev, frame, data, len); |
369 | } | 157 | } |
@@ -390,7 +178,8 @@ static void fill_frame(struct gspca_dev *gspca_dev, | |||
390 | * buffers are in user space (userptr). The frame detection | 178 | * buffers are in user space (userptr). The frame detection |
391 | * and copy is done by the application. | 179 | * and copy is done by the application. |
392 | */ | 180 | */ |
393 | static void isoc_irq_mmap(struct urb *urb) | 181 | static void isoc_irq_mmap(struct urb *urb |
182 | ) | ||
394 | { | 183 | { |
395 | struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context; | 184 | struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context; |
396 | 185 | ||
@@ -400,7 +189,8 @@ static void isoc_irq_mmap(struct urb *urb) | |||
400 | fill_frame(gspca_dev, urb); | 189 | fill_frame(gspca_dev, urb); |
401 | } | 190 | } |
402 | 191 | ||
403 | static void isoc_irq_user(struct urb *urb) | 192 | static void isoc_irq_user(struct urb *urb |
193 | ) | ||
404 | { | 194 | { |
405 | struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context; | 195 | struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context; |
406 | int i; | 196 | int i; |
@@ -459,7 +249,7 @@ static void isoc_transfer(struct gspca_dev *gspca_dev) | |||
459 | struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev, | 249 | struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev, |
460 | int packet_type, | 250 | int packet_type, |
461 | struct gspca_frame *frame, | 251 | struct gspca_frame *frame, |
462 | unsigned char *data, | 252 | __u8 *data, |
463 | int len) | 253 | int len) |
464 | { | 254 | { |
465 | int i, j; | 255 | int i, j; |
@@ -503,23 +293,10 @@ struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev, | |||
503 | /* if last packet, wake the application and advance in the queue */ | 293 | /* if last packet, wake the application and advance in the queue */ |
504 | if (packet_type == LAST_PACKET) { | 294 | if (packet_type == LAST_PACKET) { |
505 | frame->v4l2_buf.bytesused = frame->data_end - frame->data; | 295 | frame->v4l2_buf.bytesused = frame->data_end - frame->data; |
506 | #ifndef GSPCA_HLP | ||
507 | frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_QUEUED; | 296 | frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_QUEUED; |
508 | frame->v4l2_buf.flags |= V4L2_BUF_FLAG_DONE; | 297 | frame->v4l2_buf.flags |= V4L2_BUF_FLAG_DONE; |
509 | atomic_inc(&gspca_dev->nevent); | 298 | atomic_inc(&gspca_dev->nevent); |
510 | wake_up_interruptible(&gspca_dev->wq); /* event = new frame */ | 299 | wake_up_interruptible(&gspca_dev->wq); /* event = new frame */ |
511 | #else /*GSPCA_HLP*/ | ||
512 | if (hlp != 0 && hlp->gspca_dev == gspca_dev) { | ||
513 | frame->v4l2_buf.flags |= GSPCA_BUF_FLAG_DECODE; | ||
514 | atomic_inc(&hlp->nevent); | ||
515 | wake_up_interruptible(&hlp->wq); | ||
516 | } else { | ||
517 | frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_QUEUED; | ||
518 | frame->v4l2_buf.flags |= V4L2_BUF_FLAG_DONE; | ||
519 | atomic_inc(&gspca_dev->nevent); | ||
520 | wake_up_interruptible(&gspca_dev->wq); /* new frame */ | ||
521 | } | ||
522 | #endif /*GSPCA_HLP*/ | ||
523 | i = (gspca_dev->fr_i + 1) % gspca_dev->nframes; | 300 | i = (gspca_dev->fr_i + 1) % gspca_dev->nframes; |
524 | gspca_dev->fr_i = i; | 301 | gspca_dev->fr_i = i; |
525 | PDEBUG(D_FRAM, "frame complete len:%d q:%d i:%d o:%d", | 302 | PDEBUG(D_FRAM, "frame complete len:%d q:%d i:%d o:%d", |
@@ -581,13 +358,13 @@ static void rvfree(void *mem, unsigned long size) | |||
581 | static __u32 get_v4l2_depth(__u32 pixfmt) | 358 | static __u32 get_v4l2_depth(__u32 pixfmt) |
582 | { | 359 | { |
583 | switch (pixfmt) { | 360 | switch (pixfmt) { |
584 | case V4L2_PIX_FMT_BGR32: | 361 | /* case V4L2_PIX_FMT_BGR32: |
585 | case V4L2_PIX_FMT_RGB32: | 362 | case V4L2_PIX_FMT_RGB32: |
586 | return 32; | 363 | return 32; */ |
587 | case V4L2_PIX_FMT_RGB24: /* 'RGB3' */ | 364 | case V4L2_PIX_FMT_RGB24: /* 'RGB3' */ |
588 | case V4L2_PIX_FMT_BGR24: | 365 | case V4L2_PIX_FMT_BGR24: |
589 | return 24; | 366 | return 24; |
590 | case V4L2_PIX_FMT_RGB565: /* 'RGBP' */ | 367 | /* case V4L2_PIX_FMT_RGB565: * 'RGBP' */ |
591 | case V4L2_PIX_FMT_YUYV: /* 'YUYV' packed 4.2.2 */ | 368 | case V4L2_PIX_FMT_YUYV: /* 'YUYV' packed 4.2.2 */ |
592 | case V4L2_PIX_FMT_YYUV: /* 'YYUV' */ | 369 | case V4L2_PIX_FMT_YYUV: /* 'YYUV' */ |
593 | return 16; | 370 | return 16; |
@@ -596,6 +373,9 @@ static __u32 get_v4l2_depth(__u32 pixfmt) | |||
596 | case V4L2_PIX_FMT_MJPEG: | 373 | case V4L2_PIX_FMT_MJPEG: |
597 | case V4L2_PIX_FMT_JPEG: | 374 | case V4L2_PIX_FMT_JPEG: |
598 | case V4L2_PIX_FMT_SBGGR8: /* 'BA81' Bayer */ | 375 | case V4L2_PIX_FMT_SBGGR8: /* 'BA81' Bayer */ |
376 | case V4L2_PIX_FMT_SN9C10X: /* 'S910' SN9C10x compression */ | ||
377 | case V4L2_PIX_FMT_SPCA501: /* 'S501' YUYV per line */ | ||
378 | case V4L2_PIX_FMT_SPCA561: /* 'S561' compressed BGGR bayer */ | ||
599 | return 8; | 379 | return 8; |
600 | } | 380 | } |
601 | PDEBUG(D_ERR|D_CONF, "Unknown pixel format %c%c%c%c", | 381 | PDEBUG(D_ERR|D_CONF, "Unknown pixel format %c%c%c%c", |
@@ -603,7 +383,7 @@ static __u32 get_v4l2_depth(__u32 pixfmt) | |||
603 | (pixfmt >> 8) & 0xff, | 383 | (pixfmt >> 8) & 0xff, |
604 | (pixfmt >> 16) & 0xff, | 384 | (pixfmt >> 16) & 0xff, |
605 | pixfmt >> 24); | 385 | pixfmt >> 24); |
606 | return -EINVAL; | 386 | return 24; |
607 | } | 387 | } |
608 | 388 | ||
609 | static int gspca_get_buff_size(struct gspca_dev *gspca_dev) | 389 | static int gspca_get_buff_size(struct gspca_dev *gspca_dev) |
@@ -632,7 +412,7 @@ static int frame_alloc(struct gspca_dev *gspca_dev, | |||
632 | count = GSPCA_MAX_FRAMES; | 412 | count = GSPCA_MAX_FRAMES; |
633 | /* if compressed (JPEG), reduce the buffer size */ | 413 | /* if compressed (JPEG), reduce the buffer size */ |
634 | if (gspca_is_compressed(gspca_dev->pixfmt)) | 414 | if (gspca_is_compressed(gspca_dev->pixfmt)) |
635 | frsz = (frsz * comp_fac) / 100 + 600; /* plus JPEG header */ | 415 | frsz = (frsz * comp_fac) / 100 + 600; /* (+ JPEG header sz) */ |
636 | frsz = PAGE_ALIGN(frsz); | 416 | frsz = PAGE_ALIGN(frsz); |
637 | PDEBUG(D_STREAM, "new fr_sz: %d", frsz); | 417 | PDEBUG(D_STREAM, "new fr_sz: %d", frsz); |
638 | gspca_dev->frsz = frsz; | 418 | gspca_dev->frsz = frsz; |
@@ -660,17 +440,6 @@ static int frame_alloc(struct gspca_dev *gspca_dev, | |||
660 | } | 440 | } |
661 | } | 441 | } |
662 | gspca_dev->fr_i = gspca_dev->fr_o = gspca_dev->fr_q = 0; | 442 | gspca_dev->fr_i = gspca_dev->fr_o = gspca_dev->fr_q = 0; |
663 | #ifdef GSPCA_HLP | ||
664 | { | ||
665 | struct hlp_dev *hlp_dev; | ||
666 | |||
667 | hlp_dev = hlp; | ||
668 | if (hlp != 0 && hlp_dev->gspca_dev == gspca_dev) { | ||
669 | hlp_dev->fr_d = 0; | ||
670 | atomic_set(&hlp_dev->nevent, 0); | ||
671 | } | ||
672 | } | ||
673 | #endif /*GSPCA_HLP*/ | ||
674 | gspca_dev->last_packet_type = DISCARD_PACKET; | 443 | gspca_dev->last_packet_type = DISCARD_PACKET; |
675 | gspca_dev->sequence = 0; | 444 | gspca_dev->sequence = 0; |
676 | atomic_set(&gspca_dev->nevent, 0); | 445 | atomic_set(&gspca_dev->nevent, 0); |
@@ -752,13 +521,14 @@ struct usb_host_endpoint *get_isoc_ep(struct gspca_dev *gspca_dev) | |||
752 | int i, ret; | 521 | int i, ret; |
753 | 522 | ||
754 | intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface); | 523 | intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface); |
524 | ep = NULL; | ||
755 | i = gspca_dev->alt; /* previous alt setting */ | 525 | i = gspca_dev->alt; /* previous alt setting */ |
756 | while (--i > 0) { /* alt 0 is unusable */ | 526 | while (--i > 0) { /* alt 0 is unusable */ |
757 | ep = alt_isoc(&intf->altsetting[i], gspca_dev->cam.epaddr); | 527 | ep = alt_isoc(&intf->altsetting[i], gspca_dev->cam.epaddr); |
758 | if (ep) | 528 | if (ep) |
759 | break; | 529 | break; |
760 | } | 530 | } |
761 | if (i <= 0) { | 531 | if (ep == NULL) { |
762 | err("no ISOC endpoint found"); | 532 | err("no ISOC endpoint found"); |
763 | return NULL; | 533 | return NULL; |
764 | } | 534 | } |
@@ -796,11 +566,14 @@ static int create_urbs(struct gspca_dev *gspca_dev, | |||
796 | "isoc %d pkts size %d (bsize:%d)", npkt, psize, bsize); | 566 | "isoc %d pkts size %d (bsize:%d)", npkt, psize, bsize); |
797 | /*fixme:change for userptr*/ | 567 | /*fixme:change for userptr*/ |
798 | /*fixme:don't submit all URBs when userptr*/ | 568 | /*fixme:don't submit all URBs when userptr*/ |
799 | gspca_dev->nurbs = nurbs = DEF_NURBS; | 569 | if (gspca_dev->memory == V4L2_MEMORY_MMAP) { |
800 | if (gspca_dev->memory == V4L2_MEMORY_MMAP) | ||
801 | usb_complete = isoc_irq_mmap; | 570 | usb_complete = isoc_irq_mmap; |
802 | else | 571 | nurbs = DEF_NURBS; |
572 | } else { | ||
803 | usb_complete = isoc_irq_user; | 573 | usb_complete = isoc_irq_user; |
574 | nurbs = USR_NURBS; | ||
575 | } | ||
576 | gspca_dev->nurbs = nurbs; | ||
804 | for (n = 0; n < nurbs; n++) { | 577 | for (n = 0; n < nurbs; n++) { |
805 | urb = usb_alloc_urb(npkt, GFP_KERNEL); | 578 | urb = usb_alloc_urb(npkt, GFP_KERNEL); |
806 | if (!urb) { | 579 | if (!urb) { |
@@ -904,16 +677,6 @@ static void gspca_stream_off(struct gspca_dev *gspca_dev) | |||
904 | { | 677 | { |
905 | gspca_dev->streaming = 0; | 678 | gspca_dev->streaming = 0; |
906 | atomic_set(&gspca_dev->nevent, 0); | 679 | atomic_set(&gspca_dev->nevent, 0); |
907 | #ifdef GSPCA_HLP | ||
908 | { | ||
909 | struct hlp_dev *hlp_dev; | ||
910 | |||
911 | hlp_dev = hlp; | ||
912 | if (hlp_dev != 0 | ||
913 | && hlp_dev->gspca_dev == gspca_dev) | ||
914 | atomic_set(&hlp_dev->nevent, 0); | ||
915 | } | ||
916 | #endif | ||
917 | if (gspca_dev->present) { | 680 | if (gspca_dev->present) { |
918 | gspca_dev->sd_desc->stopN(gspca_dev); | 681 | gspca_dev->sd_desc->stopN(gspca_dev); |
919 | destroy_urbs(gspca_dev); | 682 | destroy_urbs(gspca_dev); |
@@ -979,15 +742,11 @@ static int vidioc_enum_fmt_cap(struct file *file, void *priv, | |||
979 | struct v4l2_fmtdesc *fmtdesc) | 742 | struct v4l2_fmtdesc *fmtdesc) |
980 | { | 743 | { |
981 | struct gspca_dev *gspca_dev = priv; | 744 | struct gspca_dev *gspca_dev = priv; |
982 | int i; | 745 | int i, j, index; |
983 | #ifndef GSPCA_HLP | ||
984 | int j, index; | ||
985 | __u32 fmt_tb[8]; | 746 | __u32 fmt_tb[8]; |
986 | #endif | ||
987 | 747 | ||
988 | PDEBUG(D_CONF, "enum fmt cap"); | 748 | PDEBUG(D_CONF, "enum fmt cap"); |
989 | 749 | ||
990 | #ifndef GSPCA_HLP | ||
991 | /* give an index to each format */ | 750 | /* give an index to each format */ |
992 | index = 0; | 751 | index = 0; |
993 | j = 0; | 752 | j = 0; |
@@ -1013,36 +772,6 @@ static int vidioc_enum_fmt_cap(struct file *file, void *priv, | |||
1013 | fmtdesc->pixelformat = fmt_tb[index]; | 772 | fmtdesc->pixelformat = fmt_tb[index]; |
1014 | if (gspca_is_compressed(fmt_tb[index])) | 773 | if (gspca_is_compressed(fmt_tb[index])) |
1015 | fmtdesc->flags = V4L2_FMT_FLAG_COMPRESSED; | 774 | fmtdesc->flags = V4L2_FMT_FLAG_COMPRESSED; |
1016 | #else /*GSPCA_HLP*/ | ||
1017 | /* !! code tied to the decoding functions in decoder.c */ | ||
1018 | i = gspca_dev->cam.nmodes - 1; | ||
1019 | if (fmtdesc->index == 0) { /* (assume one format per subdriver) */ | ||
1020 | fmtdesc->pixelformat = gspca_dev->cam.cam_mode[i].pixfmt; | ||
1021 | if (gspca_is_compressed(fmtdesc->pixelformat)) | ||
1022 | fmtdesc->flags = V4L2_FMT_FLAG_COMPRESSED; | ||
1023 | } else { | ||
1024 | if (hlp == 0 | ||
1025 | || (hlp->gspca_dev != 0 | ||
1026 | && hlp->gspca_dev != gspca_dev)) | ||
1027 | return -EINVAL; | ||
1028 | switch (gspca_dev->cam.cam_mode[i].pixfmt) { | ||
1029 | case V4L2_PIX_FMT_JPEG: | ||
1030 | if (fmtdesc->index >= sizeof jpeg_to_tb | ||
1031 | / sizeof jpeg_to_tb[0]) | ||
1032 | return -EINVAL; | ||
1033 | fmtdesc->pixelformat = jpeg_to_tb[fmtdesc->index]; | ||
1034 | break; | ||
1035 | case V4L2_PIX_FMT_SBGGR8: | ||
1036 | if (fmtdesc->index >= sizeof bayer_to_tb | ||
1037 | / sizeof bayer_to_tb[0]) | ||
1038 | return -EINVAL; | ||
1039 | fmtdesc->pixelformat = bayer_to_tb[fmtdesc->index]; | ||
1040 | break; | ||
1041 | default: | ||
1042 | return -EINVAL; | ||
1043 | } | ||
1044 | } | ||
1045 | #endif /*GSPCA_HLP*/ | ||
1046 | fmtdesc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 775 | fmtdesc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
1047 | fmtdesc->description[0] = fmtdesc->pixelformat & 0xff; | 776 | fmtdesc->description[0] = fmtdesc->pixelformat & 0xff; |
1048 | fmtdesc->description[1] = (fmtdesc->pixelformat >> 8) & 0xff; | 777 | fmtdesc->description[1] = (fmtdesc->pixelformat >> 8) & 0xff; |
@@ -1057,25 +786,12 @@ static int vidioc_g_fmt_cap(struct file *file, void *priv, | |||
1057 | { | 786 | { |
1058 | struct gspca_dev *gspca_dev = priv; | 787 | struct gspca_dev *gspca_dev = priv; |
1059 | 788 | ||
1060 | #ifdef GSPCA_HLP | 789 | if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
1061 | int i; | 790 | return -EINVAL; |
1062 | |||
1063 | /* if the pixel format is not the one of the device and | ||
1064 | * if the helper is inactive or busy, restore */ | ||
1065 | i = gspca_dev->curr_mode; | ||
1066 | if (gspca_dev->pixfmt != gspca_dev->cam.cam_mode[i].pixfmt) { | ||
1067 | struct hlp_dev *hlp_dev; | ||
1068 | |||
1069 | hlp_dev = hlp; | ||
1070 | if (hlp_dev == 0 || hlp_dev->gspca_dev != gspca_dev) | ||
1071 | gspca_dev->pixfmt = gspca_dev->cam.cam_mode[i].pixfmt; | ||
1072 | } | ||
1073 | #endif /*GSPCA_HLP*/ | ||
1074 | |||
1075 | fmt->fmt.pix.width = gspca_dev->width; | 791 | fmt->fmt.pix.width = gspca_dev->width; |
1076 | fmt->fmt.pix.height = gspca_dev->height; | 792 | fmt->fmt.pix.height = gspca_dev->height; |
1077 | fmt->fmt.pix.pixelformat = gspca_dev->pixfmt; | 793 | fmt->fmt.pix.pixelformat = gspca_dev->pixfmt; |
1078 | #ifdef GSPCA_DEBUG | 794 | #ifdef VIDEO_ADV_DEBUG |
1079 | if (gspca_debug & D_CONF) { | 795 | if (gspca_debug & D_CONF) { |
1080 | PDEBUG_MODE("get fmt cap", | 796 | PDEBUG_MODE("get fmt cap", |
1081 | fmt->fmt.pix.pixelformat, | 797 | fmt->fmt.pix.pixelformat, |
@@ -1099,13 +815,15 @@ static int try_fmt_cap(struct gspca_dev *gspca_dev, | |||
1099 | { | 815 | { |
1100 | int w, h, mode, mode2, frsz; | 816 | int w, h, mode, mode2, frsz; |
1101 | 817 | ||
818 | if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
819 | return -EINVAL; | ||
1102 | w = fmt->fmt.pix.width; | 820 | w = fmt->fmt.pix.width; |
1103 | h = fmt->fmt.pix.height; | 821 | h = fmt->fmt.pix.height; |
1104 | 822 | ||
1105 | /* (luvcview problem) */ | 823 | /* (luvcview problem) */ |
1106 | if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) | 824 | if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) |
1107 | fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_JPEG; | 825 | fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_JPEG; |
1108 | #ifdef GSPCA_DEBUG | 826 | #ifdef VIDEO_ADV_DEBUG |
1109 | if (gspca_debug & D_CONF) | 827 | if (gspca_debug & D_CONF) |
1110 | PDEBUG_MODE("try fmt cap", fmt->fmt.pix.pixelformat, w, h); | 828 | PDEBUG_MODE("try fmt cap", fmt->fmt.pix.pixelformat, w, h); |
1111 | #endif | 829 | #endif |
@@ -1121,44 +839,11 @@ static int try_fmt_cap(struct gspca_dev *gspca_dev, | |||
1121 | if (mode2 >= 0) { | 839 | if (mode2 >= 0) { |
1122 | mode = mode2; | 840 | mode = mode2; |
1123 | } else { | 841 | } else { |
1124 | __u32 pixfmt; | ||
1125 | |||
1126 | pixfmt = gspca_dev->cam.cam_mode[mode].pixfmt; | ||
1127 | #ifndef GSPCA_HLP | ||
1128 | 842 | ||
1129 | /* no chance, return this mode */ | 843 | /* no chance, return this mode */ |
1130 | fmt->fmt.pix.pixelformat = pixfmt; | 844 | fmt->fmt.pix.pixelformat = |
1131 | #else /*GSPCA_HLP*/ | 845 | gspca_dev->cam.cam_mode[mode].pixfmt; |
1132 | if (hlp != 0 | 846 | #ifdef VIDEO_ADV_DEBUG |
1133 | && (hlp->gspca_dev == 0 | ||
1134 | || hlp->gspca_dev == gspca_dev) | ||
1135 | /* decoding works for JPEG and Bayer only */ | ||
1136 | && (pixfmt == V4L2_PIX_FMT_JPEG | ||
1137 | || pixfmt == V4L2_PIX_FMT_SBGGR8)) { | ||
1138 | switch (fmt->fmt.pix.pixelformat) { | ||
1139 | case V4L2_PIX_FMT_YUYV: /* 'YUYV' */ | ||
1140 | case V4L2_PIX_FMT_BGR24: /* 'BGR3' */ | ||
1141 | case V4L2_PIX_FMT_RGB24: /* 'RGB3' */ | ||
1142 | case V4L2_PIX_FMT_YUV420: /* 'YU12' */ | ||
1143 | case V4L2_PIX_FMT_RGB565: /* 'RGBP' */ | ||
1144 | break; | ||
1145 | default: { | ||
1146 | /* return any of the supported fmt's */ | ||
1147 | __u8 u; | ||
1148 | |||
1149 | u = get_jiffies_64(); | ||
1150 | u %= sizeof bayer_to_tb | ||
1151 | / sizeof bayer_to_tb[0] - 1; | ||
1152 | fmt->fmt.pix.pixelformat = | ||
1153 | bayer_to_tb[u + 1]; | ||
1154 | break; | ||
1155 | } | ||
1156 | } | ||
1157 | } else { | ||
1158 | fmt->fmt.pix.pixelformat = pixfmt; | ||
1159 | } | ||
1160 | #endif /*GSPCA_HLP*/ | ||
1161 | #ifdef GSPCA_DEBUG | ||
1162 | if (gspca_debug & D_CONF) { | 847 | if (gspca_debug & D_CONF) { |
1163 | PDEBUG_MODE("new format", | 848 | PDEBUG_MODE("new format", |
1164 | fmt->fmt.pix.pixelformat, | 849 | fmt->fmt.pix.pixelformat, |
@@ -1198,7 +883,17 @@ static int vidioc_s_fmt_cap(struct file *file, void *priv, | |||
1198 | struct gspca_dev *gspca_dev = priv; | 883 | struct gspca_dev *gspca_dev = priv; |
1199 | int ret; | 884 | int ret; |
1200 | 885 | ||
1201 | #ifdef GSPCA_DEBUG | 886 | #ifdef CONFIG_VIDEO_V4L1_COMPAT |
887 | /* if v4l1 got JPEG */ | ||
888 | if (fmt->fmt.pix.pixelformat == 0 | ||
889 | && gspca_dev->streaming) { | ||
890 | fmt->fmt.pix.width = gspca_dev->width; | ||
891 | fmt->fmt.pix.height = gspca_dev->height; | ||
892 | fmt->fmt.pix.pixelformat = gspca_dev->pixfmt; | ||
893 | return 0; | ||
894 | } | ||
895 | #endif | ||
896 | #ifdef VIDEO_ADV_DEBUG | ||
1202 | if (gspca_debug & D_CONF) { | 897 | if (gspca_debug & D_CONF) { |
1203 | PDEBUG_MODE("set fmt cap", | 898 | PDEBUG_MODE("set fmt cap", |
1204 | fmt->fmt.pix.pixelformat, | 899 | fmt->fmt.pix.pixelformat, |
@@ -1218,14 +913,8 @@ static int vidioc_s_fmt_cap(struct file *file, void *priv, | |||
1218 | goto out; | 913 | goto out; |
1219 | } | 914 | } |
1220 | 915 | ||
1221 | #ifndef GSPCA_HLP | ||
1222 | if (ret == gspca_dev->curr_mode) | 916 | if (ret == gspca_dev->curr_mode) |
1223 | goto out; /* same mode */ | 917 | goto out; /* same mode */ |
1224 | #else /*GSPCA_HLP*/ | ||
1225 | if (ret == gspca_dev->curr_mode | ||
1226 | && gspca_dev->pixfmt == fmt->fmt.pix.pixelformat) | ||
1227 | goto out; /* same mode */ | ||
1228 | #endif /*GSPCA_HLP*/ | ||
1229 | 918 | ||
1230 | if (gspca_dev->streaming) { | 919 | if (gspca_dev->streaming) { |
1231 | ret = -EBUSY; | 920 | ret = -EBUSY; |
@@ -1236,26 +925,6 @@ static int vidioc_s_fmt_cap(struct file *file, void *priv, | |||
1236 | gspca_dev->pixfmt = fmt->fmt.pix.pixelformat; | 925 | gspca_dev->pixfmt = fmt->fmt.pix.pixelformat; |
1237 | gspca_dev->curr_mode = ret; | 926 | gspca_dev->curr_mode = ret; |
1238 | 927 | ||
1239 | #ifdef GSPCA_HLP | ||
1240 | /* if frame decoding is required */ | ||
1241 | if (gspca_dev->pixfmt != gspca_dev->cam.cam_mode[ret].pixfmt) { | ||
1242 | struct hlp_dev *hlp_dev; | ||
1243 | |||
1244 | hlp_dev = hlp; | ||
1245 | if (hlp_dev == 0 | ||
1246 | || (hlp_dev->gspca_dev != 0 | ||
1247 | && hlp_dev->gspca_dev != gspca_dev)) { /* helper busy */ | ||
1248 | fmt->fmt.pix.pixelformat = | ||
1249 | gspca_dev->pixfmt = | ||
1250 | gspca_dev->cam.cam_mode[ret].pixfmt; | ||
1251 | } else { /* helper active */ | ||
1252 | hlp_dev->gspca_dev = gspca_dev; | ||
1253 | hlp_dev->pixfmt = gspca_dev->cam.cam_mode[ret].pixfmt; | ||
1254 | hlp_dev->fr_d = gspca_dev->fr_i; | ||
1255 | } | ||
1256 | } else if (hlp != 0 && hlp->gspca_dev == gspca_dev) | ||
1257 | hlp->gspca_dev = 0; | ||
1258 | #endif /*GSPCA_HLP*/ | ||
1259 | ret = 0; | 928 | ret = 0; |
1260 | out: | 929 | out: |
1261 | mutex_unlock(&gspca_dev->queue_lock); | 930 | mutex_unlock(&gspca_dev->queue_lock); |
@@ -1294,7 +963,7 @@ static int dev_open(struct inode *inode, struct file *file) | |||
1294 | } | 963 | } |
1295 | gspca_dev->users++; | 964 | gspca_dev->users++; |
1296 | file->private_data = gspca_dev; | 965 | file->private_data = gspca_dev; |
1297 | #ifdef GSPCA_DEBUG | 966 | #ifdef VIDEO_ADV_DEBUG |
1298 | /* activate the v4l2 debug */ | 967 | /* activate the v4l2 debug */ |
1299 | if (gspca_debug & D_V4L2) | 968 | if (gspca_debug & D_V4L2) |
1300 | gspca_dev->vdev.debug |= 3; | 969 | gspca_dev->vdev.debug |= 3; |
@@ -1329,22 +998,6 @@ static int dev_close(struct inode *inode, struct file *file) | |||
1329 | frame_free(gspca_dev); | 998 | frame_free(gspca_dev); |
1330 | gspca_dev->capt_file = 0; | 999 | gspca_dev->capt_file = 0; |
1331 | gspca_dev->memory = GSPCA_MEMORY_NO; | 1000 | gspca_dev->memory = GSPCA_MEMORY_NO; |
1332 | #ifdef GSPCA_HLP | ||
1333 | { | ||
1334 | struct hlp_dev *hlp_dev; | ||
1335 | int mode; | ||
1336 | |||
1337 | hlp_dev = hlp; | ||
1338 | if (hlp_dev != 0 | ||
1339 | && hlp_dev->gspca_dev == gspca_dev) { | ||
1340 | hlp_dev->gspca_dev = 0; | ||
1341 | hlp_dev->frame = 0; | ||
1342 | mode = gspca_dev->curr_mode; | ||
1343 | gspca_dev->pixfmt = | ||
1344 | gspca_dev->cam.cam_mode[mode].pixfmt; | ||
1345 | } | ||
1346 | } | ||
1347 | #endif /*GSPCA_HLP*/ | ||
1348 | } | 1001 | } |
1349 | file->private_data = NULL; | 1002 | file->private_data = NULL; |
1350 | mutex_unlock(&gspca_dev->queue_lock); | 1003 | mutex_unlock(&gspca_dev->queue_lock); |
@@ -1370,23 +1023,38 @@ static int vidioc_querycap(struct file *file, void *priv, | |||
1370 | return 0; | 1023 | return 0; |
1371 | } | 1024 | } |
1372 | 1025 | ||
1026 | /* the use of V4L2_CTRL_FLAG_NEXT_CTRL asks for the controls to be sorted */ | ||
1373 | static int vidioc_queryctrl(struct file *file, void *priv, | 1027 | static int vidioc_queryctrl(struct file *file, void *priv, |
1374 | struct v4l2_queryctrl *q_ctrl) | 1028 | struct v4l2_queryctrl *q_ctrl) |
1375 | { | 1029 | { |
1376 | struct gspca_dev *gspca_dev = priv; | 1030 | struct gspca_dev *gspca_dev = priv; |
1377 | int i; | 1031 | int i; |
1378 | 1032 | u32 id; | |
1379 | PDEBUG(D_CONF, "queryctrl"); | 1033 | |
1034 | id = q_ctrl->id; | ||
1035 | if (id & V4L2_CTRL_FLAG_NEXT_CTRL) { | ||
1036 | id &= V4L2_CTRL_ID_MASK; | ||
1037 | id++; | ||
1038 | for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) { | ||
1039 | if (id >= gspca_dev->sd_desc->ctrls[i].qctrl.id) { | ||
1040 | memcpy(q_ctrl, | ||
1041 | &gspca_dev->sd_desc->ctrls[i].qctrl, | ||
1042 | sizeof *q_ctrl); | ||
1043 | return 0; | ||
1044 | } | ||
1045 | } | ||
1046 | return -EINVAL; | ||
1047 | } | ||
1380 | for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) { | 1048 | for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) { |
1381 | if (q_ctrl->id == gspca_dev->sd_desc->ctrls[i].qctrl.id) { | 1049 | if (id == gspca_dev->sd_desc->ctrls[i].qctrl.id) { |
1382 | memcpy(q_ctrl, | 1050 | memcpy(q_ctrl, |
1383 | &gspca_dev->sd_desc->ctrls[i].qctrl, | 1051 | &gspca_dev->sd_desc->ctrls[i].qctrl, |
1384 | sizeof *q_ctrl); | 1052 | sizeof *q_ctrl); |
1385 | return 0; | 1053 | return 0; |
1386 | } | 1054 | } |
1387 | } | 1055 | } |
1388 | if (q_ctrl->id >= V4L2_CID_BASE | 1056 | if (id >= V4L2_CID_BASE |
1389 | && q_ctrl->id <= V4L2_CID_LASTP1) { | 1057 | && id <= V4L2_CID_LASTP1) { |
1390 | q_ctrl->flags |= V4L2_CTRL_FLAG_DISABLED; | 1058 | q_ctrl->flags |= V4L2_CTRL_FLAG_DISABLED; |
1391 | return 0; | 1059 | return 0; |
1392 | } | 1060 | } |
@@ -1489,13 +1157,8 @@ static int vidioc_reqbufs(struct file *file, void *priv, | |||
1489 | return -EINVAL; | 1157 | return -EINVAL; |
1490 | switch (rb->memory) { | 1158 | switch (rb->memory) { |
1491 | case V4L2_MEMORY_MMAP: | 1159 | case V4L2_MEMORY_MMAP: |
1492 | break; | ||
1493 | case V4L2_MEMORY_USERPTR: | 1160 | case V4L2_MEMORY_USERPTR: |
1494 | #ifdef GSPCA_HLP | 1161 | break; |
1495 | if (hlp == 0 || hlp->gspca_dev != gspca_dev) | ||
1496 | break; | ||
1497 | #endif | ||
1498 | return -EINVAL; | ||
1499 | default: | 1162 | default: |
1500 | return -EINVAL; | 1163 | return -EINVAL; |
1501 | } | 1164 | } |
@@ -1578,7 +1241,7 @@ static int vidioc_streamon(struct file *file, void *priv, | |||
1578 | if (ret < 0) | 1241 | if (ret < 0) |
1579 | goto out; | 1242 | goto out; |
1580 | } | 1243 | } |
1581 | #ifdef GSPCA_DEBUG | 1244 | #ifdef VIDEO_ADV_DEBUG |
1582 | if (gspca_debug & D_STREAM) { | 1245 | if (gspca_debug & D_STREAM) { |
1583 | PDEBUG_MODE("stream on OK", | 1246 | PDEBUG_MODE("stream on OK", |
1584 | gspca_dev->pixfmt, | 1247 | gspca_dev->pixfmt, |
@@ -1657,7 +1320,7 @@ static int vidioc_g_parm(struct file *filp, void *priv, | |||
1657 | { | 1320 | { |
1658 | struct gspca_dev *gspca_dev = priv; | 1321 | struct gspca_dev *gspca_dev = priv; |
1659 | 1322 | ||
1660 | memset(parm, 0, sizeof parm); | 1323 | memset(parm, 0, sizeof *parm); |
1661 | parm->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 1324 | parm->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
1662 | parm->parm.capture.readbuffers = gspca_dev->nbufread; | 1325 | parm->parm.capture.readbuffers = gspca_dev->nbufread; |
1663 | return 0; | 1326 | return 0; |
@@ -1677,6 +1340,12 @@ static int vidioc_s_parm(struct file *filp, void *priv, | |||
1677 | return 0; | 1340 | return 0; |
1678 | } | 1341 | } |
1679 | 1342 | ||
1343 | static int vidioc_s_std(struct file *filp, void *priv, | ||
1344 | v4l2_std_id *parm) | ||
1345 | { | ||
1346 | return 0; | ||
1347 | } | ||
1348 | |||
1680 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | 1349 | #ifdef CONFIG_VIDEO_V4L1_COMPAT |
1681 | static int vidiocgmbuf(struct file *file, void *priv, | 1350 | static int vidiocgmbuf(struct file *file, void *priv, |
1682 | struct video_mbuf *mbuf) | 1351 | struct video_mbuf *mbuf) |
@@ -1686,29 +1355,32 @@ static int vidiocgmbuf(struct file *file, void *priv, | |||
1686 | 1355 | ||
1687 | PDEBUG(D_STREAM, "cgmbuf"); | 1356 | PDEBUG(D_STREAM, "cgmbuf"); |
1688 | if (gspca_dev->nframes == 0) { | 1357 | if (gspca_dev->nframes == 0) { |
1689 | struct v4l2_requestbuffers rb; | ||
1690 | int ret; | 1358 | int ret; |
1691 | __u32 pixfmt; | 1359 | |
1692 | short width, height; | 1360 | { |
1693 | 1361 | struct v4l2_format fmt; | |
1694 | /* as the final format is not yet defined, allocate | 1362 | |
1695 | buffers with the max size */ | 1363 | memset(&fmt, 0, sizeof fmt); |
1696 | pixfmt = gspca_dev->pixfmt; | 1364 | fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
1697 | width = gspca_dev->width; | 1365 | i = gspca_dev->cam.nmodes - 1; /* highest mode */ |
1698 | height = gspca_dev->height; | 1366 | fmt.fmt.pix.width = gspca_dev->cam.cam_mode[i].width; |
1699 | gspca_dev->pixfmt = V4L2_PIX_FMT_BGR32; | 1367 | fmt.fmt.pix.height = gspca_dev->cam.cam_mode[i].height; |
1700 | gspca_dev->width = 640; | 1368 | fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_BGR24; |
1701 | gspca_dev->height = 480; | 1369 | ret = vidioc_s_fmt_cap(file, priv, &fmt); |
1702 | memset(&rb, 0, sizeof rb); | 1370 | if (ret != 0) |
1703 | rb.count = 4; | 1371 | return ret; |
1704 | rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 1372 | } |
1705 | rb.memory = V4L2_MEMORY_MMAP; | 1373 | { |
1706 | ret = vidioc_reqbufs(file, priv, &rb); | 1374 | struct v4l2_requestbuffers rb; |
1707 | gspca_dev->pixfmt = pixfmt; | 1375 | |
1708 | gspca_dev->width = width; | 1376 | memset(&rb, 0, sizeof rb); |
1709 | gspca_dev->height = height; | 1377 | rb.count = 4; |
1710 | if (ret != 0) | 1378 | rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
1711 | return ret; | 1379 | rb.memory = V4L2_MEMORY_MMAP; |
1380 | ret = vidioc_reqbufs(file, priv, &rb); | ||
1381 | if (ret != 0) | ||
1382 | return ret; | ||
1383 | } | ||
1712 | } | 1384 | } |
1713 | mbuf->frames = gspca_dev->nframes; | 1385 | mbuf->frames = gspca_dev->nframes; |
1714 | mbuf->size = gspca_dev->frsz * gspca_dev->nframes; | 1386 | mbuf->size = gspca_dev->frsz * gspca_dev->nframes; |
@@ -1951,7 +1623,7 @@ static int vidioc_qbuf(struct file *file, void *priv, | |||
1951 | 1623 | ||
1952 | if (frame->v4l2_buf.memory == V4L2_MEMORY_USERPTR) { | 1624 | if (frame->v4l2_buf.memory == V4L2_MEMORY_USERPTR) { |
1953 | frame->data = frame->data_end = | 1625 | frame->data = frame->data_end = |
1954 | (unsigned char *) v4l2_buf->m.userptr; | 1626 | (__u8 *) v4l2_buf->m.userptr; |
1955 | frame->v4l2_buf.m.userptr = v4l2_buf->m.userptr; | 1627 | frame->v4l2_buf.m.userptr = v4l2_buf->m.userptr; |
1956 | frame->v4l2_buf.length = v4l2_buf->length; | 1628 | frame->v4l2_buf.length = v4l2_buf->length; |
1957 | } | 1629 | } |
@@ -2154,6 +1826,9 @@ static struct file_operations dev_fops = { | |||
2154 | .read = dev_read, | 1826 | .read = dev_read, |
2155 | .mmap = dev_mmap, | 1827 | .mmap = dev_mmap, |
2156 | .ioctl = video_ioctl2, | 1828 | .ioctl = video_ioctl2, |
1829 | #ifdef CONFIG_COMPAT | ||
1830 | .compat_ioctl = v4l_compat_ioctl32, | ||
1831 | #endif | ||
2157 | .llseek = no_llseek, | 1832 | .llseek = no_llseek, |
2158 | .poll = dev_poll, | 1833 | .poll = dev_poll, |
2159 | }; | 1834 | }; |
@@ -2186,6 +1861,7 @@ static struct video_device gspca_template = { | |||
2186 | .vidioc_s_jpegcomp = vidioc_s_jpegcomp, | 1861 | .vidioc_s_jpegcomp = vidioc_s_jpegcomp, |
2187 | .vidioc_g_parm = vidioc_g_parm, | 1862 | .vidioc_g_parm = vidioc_g_parm, |
2188 | .vidioc_s_parm = vidioc_s_parm, | 1863 | .vidioc_s_parm = vidioc_s_parm, |
1864 | .vidioc_s_std = vidioc_s_std, | ||
2189 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | 1865 | #ifdef CONFIG_VIDEO_V4L1_COMPAT |
2190 | .vidiocgmbuf = vidiocgmbuf, | 1866 | .vidiocgmbuf = vidiocgmbuf, |
2191 | #endif | 1867 | #endif |
@@ -2207,12 +1883,8 @@ int gspca_dev_probe(struct usb_interface *intf, | |||
2207 | struct gspca_dev *gspca_dev; | 1883 | struct gspca_dev *gspca_dev; |
2208 | struct usb_device *dev = interface_to_usbdev(intf); | 1884 | struct usb_device *dev = interface_to_usbdev(intf); |
2209 | int ret; | 1885 | int ret; |
2210 | __u16 vendor; | ||
2211 | __u16 product; | ||
2212 | 1886 | ||
2213 | vendor = id->idVendor; | 1887 | PDEBUG(D_PROBE, "probing %04x:%04x", id->idVendor, id->idProduct); |
2214 | product = id->idProduct; | ||
2215 | PDEBUG(D_PROBE, "probing %04x:%04x", vendor, product); | ||
2216 | 1888 | ||
2217 | /* we don't handle multi-config cameras */ | 1889 | /* we don't handle multi-config cameras */ |
2218 | if (dev->descriptor.bNumConfigurations != 1) | 1890 | if (dev->descriptor.bNumConfigurations != 1) |
@@ -2309,35 +1981,24 @@ EXPORT_SYMBOL(gspca_disconnect); | |||
2309 | /* -- module insert / remove -- */ | 1981 | /* -- module insert / remove -- */ |
2310 | static int __init gspca_init(void) | 1982 | static int __init gspca_init(void) |
2311 | { | 1983 | { |
2312 | #ifdef GSPCA_HLP | ||
2313 | int ret; | ||
2314 | |||
2315 | /* create /dev/gspca_hlp */ | ||
2316 | ret = misc_register(&hlp_device); | ||
2317 | if (ret < 0) | ||
2318 | err("misc_register err %d", ret); | ||
2319 | start_hlp(); /* try to start the helper process */ | ||
2320 | #endif | ||
2321 | info("main v%s registered", version); | 1984 | info("main v%s registered", version); |
2322 | return 0; | 1985 | return 0; |
2323 | } | 1986 | } |
2324 | static void __exit gspca_exit(void) | 1987 | static void __exit gspca_exit(void) |
2325 | { | 1988 | { |
2326 | #ifdef GSPCA_HLP | ||
2327 | misc_deregister(&hlp_device); | ||
2328 | #endif | ||
2329 | info("main deregistered"); | 1989 | info("main deregistered"); |
2330 | } | 1990 | } |
2331 | 1991 | ||
2332 | module_init(gspca_init); | 1992 | module_init(gspca_init); |
2333 | module_exit(gspca_exit); | 1993 | module_exit(gspca_exit); |
2334 | 1994 | ||
1995 | #ifdef VIDEO_ADV_DEBUG | ||
2335 | module_param_named(debug, gspca_debug, int, 0644); | 1996 | module_param_named(debug, gspca_debug, int, 0644); |
2336 | MODULE_PARM_DESC(debug, | 1997 | MODULE_PARM_DESC(debug, |
2337 | "Debug (bit) 0x01:error 0x02:probe 0x04:config" | 1998 | "Debug (bit) 0x01:error 0x02:probe 0x04:config" |
2338 | " 0x08:stream 0x10:frame 0x20:packet 0x40:USBin 0x80:USBout" | 1999 | " 0x08:stream 0x10:frame 0x20:packet 0x40:USBin 0x80:USBout" |
2339 | " 0x0100: v4l2"); | 2000 | " 0x0100: v4l2"); |
2340 | 2001 | #endif | |
2341 | module_param(comp_fac, int, 0644); | 2002 | module_param(comp_fac, int, 0644); |
2342 | MODULE_PARM_DESC(comp_fac, | 2003 | MODULE_PARM_DESC(comp_fac, |
2343 | "Buffer size ratio when compressed in percent"); | 2004 | "Buffer size ratio when compressed in percent"); |
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h index e69d8472a284..1581fa808b6f 100644 --- a/drivers/media/video/gspca/gspca.h +++ b/drivers/media/video/gspca/gspca.h | |||
@@ -9,7 +9,26 @@ | |||
9 | #include <media/v4l2-common.h> | 9 | #include <media/v4l2-common.h> |
10 | #include <linux/mutex.h> | 10 | #include <linux/mutex.h> |
11 | 11 | ||
12 | #ifdef GSPCA_DEBUG | 12 | /* values in 2.6.27 */ |
13 | #ifndef V4L2_PIX_FMT_SPCA501 | ||
14 | #define V4L2_PIX_FMT_SPCA501 v4l2_fourcc('S', '5', '0', '1') | ||
15 | #endif | ||
16 | #ifndef V4L2_PIX_FMT_SPCA561 | ||
17 | #define V4L2_PIX_FMT_SPCA561 v4l2_fourcc('S', '5', '6', '1') | ||
18 | #endif | ||
19 | |||
20 | /* values in 2.6.26 */ | ||
21 | #ifndef V4L2_CID_POWER_LINE_FREQUENCY | ||
22 | #define V4L2_CID_POWER_LINE_FREQUENCY (V4L2_CID_BASE+24) | ||
23 | #endif | ||
24 | #ifndef V4L2_CID_WHITE_BALANCE_TEMPERATURE | ||
25 | #define V4L2_CID_WHITE_BALANCE_TEMPERATURE (V4L2_CID_BASE + 26) | ||
26 | #endif | ||
27 | #ifndef V4L2_CID_SHARPNESS | ||
28 | #define V4L2_CID_SHARPNESS (V4L2_CID_BASE+27) | ||
29 | #endif | ||
30 | |||
31 | #ifdef VIDEO_ADV_DEBUG | ||
13 | /* GSPCA our debug messages */ | 32 | /* GSPCA our debug messages */ |
14 | extern int gspca_debug; | 33 | extern int gspca_debug; |
15 | #define PDEBUG(level, fmt, args...) \ | 34 | #define PDEBUG(level, fmt, args...) \ |
@@ -47,7 +66,7 @@ extern int gspca_debug; | |||
47 | 66 | ||
48 | #define GSPCA_MAX_FRAMES 16 /* maximum number of video frame buffers */ | 67 | #define GSPCA_MAX_FRAMES 16 /* maximum number of video frame buffers */ |
49 | /* ISOC transfers */ | 68 | /* ISOC transfers */ |
50 | #define MAX_NURBS 32 /* max number of URBs (read & userptr) */ | 69 | #define MAX_NURBS 16 /* max number of URBs */ |
51 | #define ISO_MAX_PKT 32 /* max number of packets in an ISOC transfer */ | 70 | #define ISO_MAX_PKT 32 /* max number of packets in an ISOC transfer */ |
52 | #define ISO_MAX_SIZE 0x8000 /* max size of one URB buffer (32 Kb) */ | 71 | #define ISO_MAX_SIZE 0x8000 /* max size of one URB buffer (32 Kb) */ |
53 | 72 | ||
@@ -79,7 +98,7 @@ typedef int (*cam_qmnu_op) (struct gspca_dev *, | |||
79 | struct v4l2_querymenu *); | 98 | struct v4l2_querymenu *); |
80 | typedef void (*cam_pkt_op) (struct gspca_dev *gspca_dev, | 99 | typedef void (*cam_pkt_op) (struct gspca_dev *gspca_dev, |
81 | struct gspca_frame *frame, | 100 | struct gspca_frame *frame, |
82 | unsigned char *data, | 101 | __u8 *data, |
83 | int len); | 102 | int len); |
84 | 103 | ||
85 | struct ctrl { | 104 | struct ctrl { |
@@ -116,8 +135,8 @@ struct sd_desc { | |||
116 | #define LAST_PACKET 3 | 135 | #define LAST_PACKET 3 |
117 | 136 | ||
118 | struct gspca_frame { | 137 | struct gspca_frame { |
119 | unsigned char *data; /* frame buffer */ | 138 | __u8 *data; /* frame buffer */ |
120 | unsigned char *data_end; /* end of frame while filling */ | 139 | __u8 *data_end; /* end of frame while filling */ |
121 | int vma_use_count; | 140 | int vma_use_count; |
122 | struct v4l2_buffer v4l2_buf; | 141 | struct v4l2_buffer v4l2_buf; |
123 | }; | 142 | }; |
@@ -135,7 +154,7 @@ struct gspca_dev { | |||
135 | 154 | ||
136 | __u8 *frbuf; /* buffer for nframes */ | 155 | __u8 *frbuf; /* buffer for nframes */ |
137 | struct gspca_frame frame[GSPCA_MAX_FRAMES]; | 156 | struct gspca_frame frame[GSPCA_MAX_FRAMES]; |
138 | unsigned int frsz; /* frame size */ | 157 | __u32 frsz; /* frame size */ |
139 | char nframes; /* number of frames */ | 158 | char nframes; /* number of frames */ |
140 | char fr_i; /* frame being filled */ | 159 | char fr_i; /* frame being filled */ |
141 | char fr_q; /* next frame to queue */ | 160 | char fr_q; /* next frame to queue */ |
@@ -145,10 +164,10 @@ struct gspca_dev { | |||
145 | 164 | ||
146 | __u8 iface; /* USB interface number */ | 165 | __u8 iface; /* USB interface number */ |
147 | __u8 alt; /* USB alternate setting */ | 166 | __u8 alt; /* USB alternate setting */ |
148 | unsigned char curr_mode; /* current camera mode */ | 167 | __u8 curr_mode; /* current camera mode */ |
149 | __u32 pixfmt; /* current mode parameters */ | 168 | __u32 pixfmt; /* current mode parameters */ |
150 | short width; | 169 | __u16 width; |
151 | short height; | 170 | __u16 height; |
152 | 171 | ||
153 | atomic_t nevent; /* number of frames done */ | 172 | atomic_t nevent; /* number of frames done */ |
154 | wait_queue_head_t wq; /* wait queue */ | 173 | wait_queue_head_t wq; /* wait queue */ |
@@ -176,6 +195,6 @@ void gspca_disconnect(struct usb_interface *intf); | |||
176 | struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev, | 195 | struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev, |
177 | int packet_type, | 196 | int packet_type, |
178 | struct gspca_frame *frame, | 197 | struct gspca_frame *frame, |
179 | unsigned char *data, | 198 | __u8 *data, |
180 | int len); | 199 | int len); |
181 | #endif /* GSPCAV2_H */ | 200 | #endif /* GSPCAV2_H */ |
diff --git a/drivers/media/video/gspca/mars.c b/drivers/media/video/gspca/mars.c new file mode 100644 index 000000000000..48b861d68299 --- /dev/null +++ b/drivers/media/video/gspca/mars.c | |||
@@ -0,0 +1,455 @@ | |||
1 | /* | ||
2 | * Mars-Semi MR97311A library | ||
3 | * Copyright (C) 2005 <bradlch@hotmail.com> | ||
4 | * | ||
5 | * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | #define MODULE_NAME "mars" | ||
23 | |||
24 | #include "gspca.h" | ||
25 | #include "jpeg.h" | ||
26 | |||
27 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) | ||
28 | static const char version[] = "2.1.0"; | ||
29 | |||
30 | MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); | ||
31 | MODULE_DESCRIPTION("GSPCA/Mars USB Camera Driver"); | ||
32 | MODULE_LICENSE("GPL"); | ||
33 | |||
34 | /* specific webcam descriptor */ | ||
35 | struct sd { | ||
36 | struct gspca_dev gspca_dev; /* !! must be the first item */ | ||
37 | |||
38 | char qindex; | ||
39 | }; | ||
40 | |||
41 | /* V4L2 controls supported by the driver */ | ||
42 | static struct ctrl sd_ctrls[] = { | ||
43 | }; | ||
44 | |||
45 | static struct cam_mode vga_mode[] = { | ||
46 | {V4L2_PIX_FMT_JPEG, 320, 240, 2}, | ||
47 | {V4L2_PIX_FMT_JPEG, 640, 480, 1}, | ||
48 | }; | ||
49 | |||
50 | /* MI Register table //elvis */ | ||
51 | enum { | ||
52 | REG_HW_MI_0, | ||
53 | REG_HW_MI_1, | ||
54 | REG_HW_MI_2, | ||
55 | REG_HW_MI_3, | ||
56 | REG_HW_MI_4, | ||
57 | REG_HW_MI_5, | ||
58 | REG_HW_MI_6, | ||
59 | REG_HW_MI_7, | ||
60 | REG_HW_MI_9 = 0x09, | ||
61 | REG_HW_MI_B = 0x0B, | ||
62 | REG_HW_MI_C, | ||
63 | REG_HW_MI_D, | ||
64 | REG_HW_MI_1E = 0x1E, | ||
65 | REG_HW_MI_20 = 0x20, | ||
66 | REG_HW_MI_2B = 0x2B, | ||
67 | REG_HW_MI_2C, | ||
68 | REG_HW_MI_2D, | ||
69 | REG_HW_MI_2E, | ||
70 | REG_HW_MI_35 = 0x35, | ||
71 | REG_HW_MI_5F = 0x5f, | ||
72 | REG_HW_MI_60, | ||
73 | REG_HW_MI_61, | ||
74 | REG_HW_MI_62, | ||
75 | REG_HW_MI_63, | ||
76 | REG_HW_MI_64, | ||
77 | REG_HW_MI_F1 = 0xf1, | ||
78 | ATTR_TOTAL_MI_REG = 242 | ||
79 | }; | ||
80 | |||
81 | static int pcam_reg_write(struct usb_device *dev, | ||
82 | __u16 index, unsigned char *value, int length) | ||
83 | { | ||
84 | int rc; | ||
85 | |||
86 | rc = usb_control_msg(dev, | ||
87 | usb_sndbulkpipe(dev, 4), | ||
88 | 0x12, | ||
89 | /* ?? 0xc8 = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_??? !? */ | ||
90 | 0xc8, | ||
91 | 0, /* value */ | ||
92 | index, value, length, 500); | ||
93 | PDEBUG(D_USBO, "reg write: 0x%02X , result = 0x%x", index, rc); | ||
94 | |||
95 | if (rc < 0) | ||
96 | PDEBUG(D_ERR, "reg write: error %d", rc); | ||
97 | return rc; | ||
98 | } | ||
99 | |||
100 | static void MISensor_BulkWrite(struct usb_device *dev, unsigned short *pch, | ||
101 | char Address) | ||
102 | { | ||
103 | int result; | ||
104 | unsigned char data[6]; | ||
105 | |||
106 | data[0] = 0x1f; | ||
107 | data[1] = 0; | ||
108 | data[2] = Address; | ||
109 | data[3] = *pch >> 8; /* high byte */ | ||
110 | data[4] = *pch; /* low byte */ | ||
111 | data[5] = 0; | ||
112 | |||
113 | result = usb_control_msg(dev, | ||
114 | usb_sndbulkpipe(dev, 4), | ||
115 | 0x12, | ||
116 | /* ?? 0xc8 = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_??? !? */ | ||
117 | 0xc8, | ||
118 | 0, /* value */ | ||
119 | Address, /* index */ | ||
120 | data, 5, 500); | ||
121 | PDEBUG(D_USBO, "bulk write 0x%02x = 0x%04x", Address, *pch); | ||
122 | |||
123 | if (result < 0) | ||
124 | PDEBUG(D_ERR, "reg write: error %d", result); | ||
125 | } | ||
126 | |||
127 | /* this function is called at probe time */ | ||
128 | static int sd_config(struct gspca_dev *gspca_dev, | ||
129 | const struct usb_device_id *id) | ||
130 | { | ||
131 | struct sd *sd = (struct sd *) gspca_dev; | ||
132 | struct cam *cam; | ||
133 | |||
134 | cam = &gspca_dev->cam; | ||
135 | cam->dev_name = (char *) id->driver_info; | ||
136 | cam->epaddr = 0x01; | ||
137 | cam->cam_mode = vga_mode; | ||
138 | cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; | ||
139 | sd->qindex = 1; /* set the quantization table */ | ||
140 | return 0; | ||
141 | } | ||
142 | |||
143 | /* this function is called at open time */ | ||
144 | static int sd_open(struct gspca_dev *gspca_dev) | ||
145 | { | ||
146 | return 0; | ||
147 | } | ||
148 | |||
149 | static void sd_start(struct gspca_dev *gspca_dev) | ||
150 | { | ||
151 | struct usb_device *dev = gspca_dev->dev; | ||
152 | int err_code; | ||
153 | __u8 data[12]; | ||
154 | __u16 MI_buf[242]; | ||
155 | int h_size, v_size; | ||
156 | int intpipe; | ||
157 | /* struct usb_device *dev = pcam->dev; */ | ||
158 | memset(data, 0, sizeof data); | ||
159 | memset(MI_buf, 0, sizeof MI_buf); | ||
160 | |||
161 | PDEBUG(D_STREAM, "camera start, iface %d, alt 8", gspca_dev->iface); | ||
162 | if (usb_set_interface(dev, gspca_dev->iface, 8) < 0) { | ||
163 | PDEBUG(D_ERR|D_STREAM, "Set packet size: set interface error"); | ||
164 | return; | ||
165 | } | ||
166 | |||
167 | data[0] = 0x01; /* address */ | ||
168 | data[1] = 0x01; | ||
169 | |||
170 | err_code = pcam_reg_write(dev, data[0], data, 0x02); | ||
171 | if (err_code < 0) | ||
172 | return; | ||
173 | |||
174 | /* | ||
175 | Initialize the MR97113 chip register | ||
176 | */ | ||
177 | data[0] = 0x00; /* address */ | ||
178 | data[1] = 0x0c | 0x01; /* reg 0 */ | ||
179 | data[2] = 0x01; /* reg 1 */ | ||
180 | h_size = gspca_dev->width; | ||
181 | v_size = gspca_dev->height; | ||
182 | data[3] = h_size / 8; /* h_size , reg 2 */ | ||
183 | data[4] = v_size / 8; /* v_size , reg 3 */ | ||
184 | data[5] = 0x30; /* reg 4, MI, PAS5101 : | ||
185 | * 0x30 for 24mhz , 0x28 for 12mhz */ | ||
186 | data[6] = 4; /* reg 5, H start */ | ||
187 | data[7] = 0xc0; /* reg 6, gamma 1.5 */ | ||
188 | data[8] = 3; /* reg 7, V start */ | ||
189 | /* if(h_size == 320 ) */ | ||
190 | /* data[9]= 0x56; * reg 8, 24MHz, 2:1 scale down */ | ||
191 | /* else */ | ||
192 | data[9] = 0x52; /* reg 8, 24MHz, no scale down */ | ||
193 | data[10] = 0x5d; /* reg 9, I2C device address | ||
194 | * [for PAS5101 (0x40)] [for MI (0x5d)] */ | ||
195 | |||
196 | err_code = pcam_reg_write(dev, data[0], data, 0x0b); | ||
197 | if (err_code < 0) | ||
198 | return; | ||
199 | |||
200 | data[0] = 0x23; /* address */ | ||
201 | data[1] = 0x09; /* reg 35, append frame header */ | ||
202 | |||
203 | err_code = pcam_reg_write(dev, data[0], data, 0x02); | ||
204 | if (err_code < 0) { | ||
205 | PDEBUG(D_ERR, "Register write failed"); | ||
206 | return; | ||
207 | } | ||
208 | |||
209 | data[0] = 0x3C; /* address */ | ||
210 | /* if (pcam->width == 1280) */ | ||
211 | /* data[1] = 200; * reg 60, pc-cam frame size | ||
212 | * (unit: 4KB) 800KB */ | ||
213 | /* else */ | ||
214 | data[1] = 50; /* 50 reg 60, pc-cam frame size | ||
215 | * (unit: 4KB) 200KB */ | ||
216 | err_code = pcam_reg_write(dev, data[0], data, 0x02); | ||
217 | if (err_code < 0) | ||
218 | return; | ||
219 | |||
220 | if (0) { /* fixed dark-gain */ | ||
221 | data[1] = 0; /* reg 94, Y Gain (1.75) */ | ||
222 | data[2] = 0; /* reg 95, UV Gain (1.75) */ | ||
223 | data[3] = 0x3f; /* reg 96, Y Gain/UV Gain/disable auto dark-gain */ | ||
224 | data[4] = 0; /* reg 97, set fixed dark level */ | ||
225 | data[5] = 0; /* reg 98, don't care */ | ||
226 | } else { /* auto dark-gain */ | ||
227 | data[1] = 0; /* reg 94, Y Gain (auto) */ | ||
228 | data[2] = 0; /* reg 95, UV Gain (1.75) */ | ||
229 | data[3] = 0x78; /* reg 96, Y Gain/UV Gain/disable auto dark-gain */ | ||
230 | switch (gspca_dev->width) { | ||
231 | /* case 1280: */ | ||
232 | /* data[4] = 154; | ||
233 | * reg 97, %3 shadow point (unit: 256 pixel) */ | ||
234 | /* data[5] = 51; | ||
235 | * reg 98, %1 highlight point | ||
236 | * (uint: 256 pixel) */ | ||
237 | /* break; */ | ||
238 | default: | ||
239 | /* case 640: */ | ||
240 | data[4] = 36; /* reg 97, %3 shadow point | ||
241 | * (unit: 256 pixel) */ | ||
242 | data[5] = 12; /* reg 98, %1 highlight point | ||
243 | * (uint: 256 pixel) */ | ||
244 | break; | ||
245 | case 320: | ||
246 | data[4] = 9; /* reg 97, %3 shadow point | ||
247 | * (unit: 256 pixel) */ | ||
248 | data[5] = 3; /* reg 98, %1 highlight point | ||
249 | * (uint: 256 pixel) */ | ||
250 | break; | ||
251 | } | ||
252 | } | ||
253 | /* auto dark-gain */ | ||
254 | data[0] = 0x5e; /* address */ | ||
255 | |||
256 | err_code = pcam_reg_write(dev, data[0], data, 0x06); | ||
257 | if (err_code < 0) | ||
258 | return; | ||
259 | |||
260 | data[0] = 0x67; | ||
261 | data[1] = 0x13; /* reg 103, first pixel B, disable sharpness */ | ||
262 | err_code = pcam_reg_write(dev, data[0], data, 0x02); | ||
263 | if (err_code < 0) | ||
264 | return; | ||
265 | |||
266 | /* | ||
267 | * initialize the value of MI sensor... | ||
268 | */ | ||
269 | MI_buf[REG_HW_MI_1] = 0x000a; | ||
270 | MI_buf[REG_HW_MI_2] = 0x000c; | ||
271 | MI_buf[REG_HW_MI_3] = 0x0405; | ||
272 | MI_buf[REG_HW_MI_4] = 0x0507; | ||
273 | /* mi_Attr_Reg_[REG_HW_MI_5] = 0x01ff;//13 */ | ||
274 | MI_buf[REG_HW_MI_5] = 0x0013; /* 13 */ | ||
275 | MI_buf[REG_HW_MI_6] = 0x001f; /* vertical blanking */ | ||
276 | /* mi_Attr_Reg_[REG_HW_MI_6] = 0x0400; // vertical blanking */ | ||
277 | MI_buf[REG_HW_MI_7] = 0x0002; | ||
278 | /* mi_Attr_Reg_[REG_HW_MI_9] = 0x015f; */ | ||
279 | /* mi_Attr_Reg_[REG_HW_MI_9] = 0x030f; */ | ||
280 | MI_buf[REG_HW_MI_9] = 0x0374; | ||
281 | MI_buf[REG_HW_MI_B] = 0x0000; | ||
282 | MI_buf[REG_HW_MI_C] = 0x0000; | ||
283 | MI_buf[REG_HW_MI_D] = 0x0000; | ||
284 | MI_buf[REG_HW_MI_1E] = 0x8000; | ||
285 | /* mi_Attr_Reg_[REG_HW_MI_20] = 0x1104; */ | ||
286 | MI_buf[REG_HW_MI_20] = 0x1104; /* 0x111c; */ | ||
287 | MI_buf[REG_HW_MI_2B] = 0x0008; | ||
288 | /* mi_Attr_Reg_[REG_HW_MI_2C] = 0x000f; */ | ||
289 | MI_buf[REG_HW_MI_2C] = 0x001f; /* lita suggest */ | ||
290 | MI_buf[REG_HW_MI_2D] = 0x0008; | ||
291 | MI_buf[REG_HW_MI_2E] = 0x0008; | ||
292 | MI_buf[REG_HW_MI_35] = 0x0051; | ||
293 | MI_buf[REG_HW_MI_5F] = 0x0904; /* fail to write */ | ||
294 | MI_buf[REG_HW_MI_60] = 0x0000; | ||
295 | MI_buf[REG_HW_MI_61] = 0x0000; | ||
296 | MI_buf[REG_HW_MI_62] = 0x0498; | ||
297 | MI_buf[REG_HW_MI_63] = 0x0000; | ||
298 | MI_buf[REG_HW_MI_64] = 0x0000; | ||
299 | MI_buf[REG_HW_MI_F1] = 0x0001; | ||
300 | /* changing while setting up the different value of dx/dy */ | ||
301 | |||
302 | if (gspca_dev->width != 1280) { | ||
303 | MI_buf[0x01] = 0x010a; | ||
304 | MI_buf[0x02] = 0x014c; | ||
305 | MI_buf[0x03] = 0x01e5; | ||
306 | MI_buf[0x04] = 0x0287; | ||
307 | } | ||
308 | MI_buf[0x20] = 0x1104; | ||
309 | |||
310 | MISensor_BulkWrite(dev, MI_buf + 1, 1); | ||
311 | MISensor_BulkWrite(dev, MI_buf + 2, 2); | ||
312 | MISensor_BulkWrite(dev, MI_buf + 3, 3); | ||
313 | MISensor_BulkWrite(dev, MI_buf + 4, 4); | ||
314 | MISensor_BulkWrite(dev, MI_buf + 5, 5); | ||
315 | MISensor_BulkWrite(dev, MI_buf + 6, 6); | ||
316 | MISensor_BulkWrite(dev, MI_buf + 7, 7); | ||
317 | MISensor_BulkWrite(dev, MI_buf + 9, 9); | ||
318 | MISensor_BulkWrite(dev, MI_buf + 0x0b, 0x0b); | ||
319 | MISensor_BulkWrite(dev, MI_buf + 0x0c, 0x0c); | ||
320 | MISensor_BulkWrite(dev, MI_buf + 0x0d, 0x0d); | ||
321 | MISensor_BulkWrite(dev, MI_buf + 0x1e, 0x1e); | ||
322 | MISensor_BulkWrite(dev, MI_buf + 0x20, 0x20); | ||
323 | MISensor_BulkWrite(dev, MI_buf + 0x2b, 0x2b); | ||
324 | MISensor_BulkWrite(dev, MI_buf + 0x2c, 0x2c); | ||
325 | MISensor_BulkWrite(dev, MI_buf + 0x2d, 0x2d); | ||
326 | MISensor_BulkWrite(dev, MI_buf + 0x2e, 0x2e); | ||
327 | MISensor_BulkWrite(dev, MI_buf + 0x35, 0x35); | ||
328 | MISensor_BulkWrite(dev, MI_buf + 0x5f, 0x5f); | ||
329 | MISensor_BulkWrite(dev, MI_buf + 0x60, 0x60); | ||
330 | MISensor_BulkWrite(dev, MI_buf + 0x61, 0x61); | ||
331 | MISensor_BulkWrite(dev, MI_buf + 0x62, 0x62); | ||
332 | MISensor_BulkWrite(dev, MI_buf + 0x63, 0x63); | ||
333 | MISensor_BulkWrite(dev, MI_buf + 0x64, 0x64); | ||
334 | MISensor_BulkWrite(dev, MI_buf + 0xf1, 0xf1); | ||
335 | |||
336 | intpipe = usb_sndintpipe(dev, 0); | ||
337 | err_code = usb_clear_halt(dev, intpipe); | ||
338 | |||
339 | data[0] = 0x00; | ||
340 | data[1] = 0x4d; /* ISOC transfering enable... */ | ||
341 | pcam_reg_write(dev, data[0], data, 0x02); | ||
342 | } | ||
343 | |||
344 | static void sd_stopN(struct gspca_dev *gspca_dev) | ||
345 | { | ||
346 | int result; | ||
347 | __u8 data[2]; | ||
348 | |||
349 | data[0] = 1; | ||
350 | data[1] = 0; | ||
351 | result = pcam_reg_write(gspca_dev->dev, data[0], data, 2); | ||
352 | if (result < 0) | ||
353 | PDEBUG(D_ERR, "Camera Stop failed"); | ||
354 | } | ||
355 | |||
356 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
357 | { | ||
358 | } | ||
359 | |||
360 | static void sd_close(struct gspca_dev *gspca_dev) | ||
361 | { | ||
362 | } | ||
363 | |||
364 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | ||
365 | struct gspca_frame *frame, /* target */ | ||
366 | unsigned char *data, /* isoc packet */ | ||
367 | int len) /* iso packet length */ | ||
368 | { | ||
369 | struct sd *sd = (struct sd *) gspca_dev; | ||
370 | int p; | ||
371 | |||
372 | if (len < 6) { | ||
373 | /* gspca_dev->last_packet_type = DISCARD_PACKET; */ | ||
374 | return; | ||
375 | } | ||
376 | for (p = 0; p < len - 6; p++) { | ||
377 | if (data[0 + p] == 0xff | ||
378 | && data[1 + p] == 0xff | ||
379 | && data[2 + p] == 0x00 | ||
380 | && data[3 + p] == 0xff | ||
381 | && data[4 + p] == 0x96) { | ||
382 | if (data[5 + p] == 0x64 | ||
383 | || data[5 + p] == 0x65 | ||
384 | || data[5 + p] == 0x66 | ||
385 | || data[5 + p] == 0x67) { | ||
386 | PDEBUG(D_PACK, "sof offset: %d leng: %d", | ||
387 | p, len); | ||
388 | frame = gspca_frame_add(gspca_dev, LAST_PACKET, | ||
389 | frame, data, 0); | ||
390 | |||
391 | /* put the JPEG header */ | ||
392 | jpeg_put_header(gspca_dev, frame, | ||
393 | sd->qindex, 0x21); | ||
394 | data += 16; | ||
395 | len -= 16; | ||
396 | break; | ||
397 | } | ||
398 | } | ||
399 | } | ||
400 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); | ||
401 | } | ||
402 | |||
403 | /* sub-driver description */ | ||
404 | static struct sd_desc sd_desc = { | ||
405 | .name = MODULE_NAME, | ||
406 | .ctrls = sd_ctrls, | ||
407 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
408 | .config = sd_config, | ||
409 | .open = sd_open, | ||
410 | .start = sd_start, | ||
411 | .stopN = sd_stopN, | ||
412 | .stop0 = sd_stop0, | ||
413 | .close = sd_close, | ||
414 | .pkt_scan = sd_pkt_scan, | ||
415 | }; | ||
416 | |||
417 | /* -- module initialisation -- */ | ||
418 | #define DVNM(name) .driver_info = (kernel_ulong_t) name | ||
419 | static __devinitdata struct usb_device_id device_table[] = { | ||
420 | {USB_DEVICE(0x093a, 0x050f), DVNM("Mars-Semi Pc-Camera")}, | ||
421 | {} | ||
422 | }; | ||
423 | MODULE_DEVICE_TABLE(usb, device_table); | ||
424 | |||
425 | /* -- device connect -- */ | ||
426 | static int sd_probe(struct usb_interface *intf, | ||
427 | const struct usb_device_id *id) | ||
428 | { | ||
429 | return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), | ||
430 | THIS_MODULE); | ||
431 | } | ||
432 | |||
433 | static struct usb_driver sd_driver = { | ||
434 | .name = MODULE_NAME, | ||
435 | .id_table = device_table, | ||
436 | .probe = sd_probe, | ||
437 | .disconnect = gspca_disconnect, | ||
438 | }; | ||
439 | |||
440 | /* -- module insert / remove -- */ | ||
441 | static int __init sd_mod_init(void) | ||
442 | { | ||
443 | if (usb_register(&sd_driver) < 0) | ||
444 | return -1; | ||
445 | PDEBUG(D_PROBE, "v%s registered", version); | ||
446 | return 0; | ||
447 | } | ||
448 | static void __exit sd_mod_exit(void) | ||
449 | { | ||
450 | usb_deregister(&sd_driver); | ||
451 | PDEBUG(D_PROBE, "deregistered"); | ||
452 | } | ||
453 | |||
454 | module_init(sd_mod_init); | ||
455 | module_exit(sd_mod_exit); | ||
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c new file mode 100644 index 000000000000..7d6237f18ba0 --- /dev/null +++ b/drivers/media/video/gspca/ov519.c | |||
@@ -0,0 +1,2174 @@ | |||
1 | /** | ||
2 | * OV519 driver | ||
3 | * | ||
4 | * Copyright (C) 2008 Jean-Francois Moine (http://moinejf.free.fr) | ||
5 | * | ||
6 | * (This module is adapted from the ov51x-jpeg package) | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
21 | * | ||
22 | */ | ||
23 | #define MODULE_NAME "ov519" | ||
24 | |||
25 | #include "gspca.h" | ||
26 | |||
27 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) | ||
28 | static const char version[] = "2.1.0"; | ||
29 | |||
30 | MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>"); | ||
31 | MODULE_DESCRIPTION("OV519 USB Camera Driver"); | ||
32 | MODULE_LICENSE("GPL"); | ||
33 | |||
34 | /* global parameters */ | ||
35 | static int frame_rate; | ||
36 | |||
37 | /* Number of times to retry a failed I2C transaction. Increase this if you | ||
38 | * are getting "Failed to read sensor ID..." */ | ||
39 | static int i2c_detect_tries = 10; | ||
40 | |||
41 | /* ov519 device descriptor */ | ||
42 | struct sd { | ||
43 | struct gspca_dev gspca_dev; /* !! must be the first item */ | ||
44 | |||
45 | /* Determined by sensor type */ | ||
46 | short maxwidth; | ||
47 | short maxheight; | ||
48 | |||
49 | unsigned char primary_i2c_slave; /* I2C write id of sensor */ | ||
50 | |||
51 | unsigned char brightness; | ||
52 | unsigned char contrast; | ||
53 | unsigned char colors; | ||
54 | |||
55 | char compress; /* Should the next frame be compressed? */ | ||
56 | char compress_inited; /* Are compression params uploaded? */ | ||
57 | char stopped; /* Streaming is temporarily paused */ | ||
58 | |||
59 | char frame_rate; /* current Framerate (OV519 only) */ | ||
60 | char clockdiv; /* clockdiv override for OV519 only */ | ||
61 | |||
62 | char sensor; /* Type of image sensor chip (SEN_*) */ | ||
63 | #define SEN_UNKNOWN 0 | ||
64 | #define SEN_OV6620 1 | ||
65 | #define SEN_OV6630 2 | ||
66 | #define SEN_OV7610 3 | ||
67 | #define SEN_OV7620 4 | ||
68 | #define SEN_OV7630 5 | ||
69 | #define SEN_OV7640 6 | ||
70 | #define SEN_OV7670 7 | ||
71 | #define SEN_OV76BE 8 | ||
72 | #define SEN_OV8610 9 | ||
73 | |||
74 | }; | ||
75 | |||
76 | /* V4L2 controls supported by the driver */ | ||
77 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
78 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
79 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | ||
80 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | ||
81 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); | ||
82 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); | ||
83 | |||
84 | static struct ctrl sd_ctrls[] = { | ||
85 | #define SD_BRIGHTNESS 0 | ||
86 | { | ||
87 | { | ||
88 | .id = V4L2_CID_BRIGHTNESS, | ||
89 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
90 | .name = "Brightness", | ||
91 | .minimum = 0, | ||
92 | .maximum = 255, | ||
93 | .step = 1, | ||
94 | .default_value = 127, | ||
95 | }, | ||
96 | .set = sd_setbrightness, | ||
97 | .get = sd_getbrightness, | ||
98 | }, | ||
99 | #define SD_CONTRAST 1 | ||
100 | { | ||
101 | { | ||
102 | .id = V4L2_CID_CONTRAST, | ||
103 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
104 | .name = "Contrast", | ||
105 | .minimum = 0, | ||
106 | .maximum = 255, | ||
107 | .step = 1, | ||
108 | .default_value = 127, | ||
109 | }, | ||
110 | .set = sd_setcontrast, | ||
111 | .get = sd_getcontrast, | ||
112 | }, | ||
113 | #define SD_COLOR 2 | ||
114 | { | ||
115 | { | ||
116 | .id = V4L2_CID_SATURATION, | ||
117 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
118 | .name = "Saturation", | ||
119 | .minimum = 0, | ||
120 | .maximum = 255, | ||
121 | .step = 1, | ||
122 | .default_value = 127, | ||
123 | }, | ||
124 | .set = sd_setcolors, | ||
125 | .get = sd_getcolors, | ||
126 | }, | ||
127 | }; | ||
128 | |||
129 | static struct cam_mode vga_mode[] = { | ||
130 | {V4L2_PIX_FMT_JPEG, 320, 240}, | ||
131 | {V4L2_PIX_FMT_JPEG, 640, 480}, | ||
132 | }; | ||
133 | static struct cam_mode sif_mode[] = { | ||
134 | {V4L2_PIX_FMT_JPEG, 176, 144}, | ||
135 | {V4L2_PIX_FMT_JPEG, 352, 288}, | ||
136 | }; | ||
137 | |||
138 | /* OV519 Camera interface register numbers */ | ||
139 | #define OV519_CAM_H_SIZE 0x10 | ||
140 | #define OV519_CAM_V_SIZE 0x11 | ||
141 | #define OV519_CAM_X_OFFSETL 0x12 | ||
142 | #define OV519_CAM_X_OFFSETH 0x13 | ||
143 | #define OV519_CAM_Y_OFFSETL 0x14 | ||
144 | #define OV519_CAM_Y_OFFSETH 0x15 | ||
145 | #define OV519_CAM_DIVIDER 0x16 | ||
146 | #define OV519_CAM_DFR 0x20 | ||
147 | #define OV519_CAM_FORMAT 0x25 | ||
148 | |||
149 | /* OV519 System Controller register numbers */ | ||
150 | #define OV519_SYS_RESET1 0x51 | ||
151 | #define OV519_SYS_EN_CLK1 0x54 | ||
152 | |||
153 | #define OV519_GPIO_DATA_OUT0 0x71 | ||
154 | #define OV519_GPIO_IO_CTRL0 0x72 | ||
155 | |||
156 | #define OV511_ENDPOINT_ADDRESS 1 /* Isoc endpoint number */ | ||
157 | |||
158 | /* I2C registers */ | ||
159 | #define R51x_I2C_W_SID 0x41 | ||
160 | #define R51x_I2C_SADDR_3 0x42 | ||
161 | #define R51x_I2C_SADDR_2 0x43 | ||
162 | #define R51x_I2C_R_SID 0x44 | ||
163 | #define R51x_I2C_DATA 0x45 | ||
164 | #define R518_I2C_CTL 0x47 /* OV518(+) only */ | ||
165 | |||
166 | /* I2C ADDRESSES */ | ||
167 | #define OV7xx0_SID 0x42 | ||
168 | #define OV8xx0_SID 0xa0 | ||
169 | #define OV6xx0_SID 0xc0 | ||
170 | |||
171 | /* OV7610 registers */ | ||
172 | #define OV7610_REG_GAIN 0x00 /* gain setting (5:0) */ | ||
173 | #define OV7610_REG_SAT 0x03 /* saturation */ | ||
174 | #define OV8610_REG_HUE 0x04 /* 04 reserved */ | ||
175 | #define OV7610_REG_CNT 0x05 /* Y contrast */ | ||
176 | #define OV7610_REG_BRT 0x06 /* Y brightness */ | ||
177 | #define OV7610_REG_COM_C 0x14 /* misc common regs */ | ||
178 | #define OV7610_REG_ID_HIGH 0x1c /* manufacturer ID MSB */ | ||
179 | #define OV7610_REG_ID_LOW 0x1d /* manufacturer ID LSB */ | ||
180 | #define OV7610_REG_COM_I 0x29 /* misc settings */ | ||
181 | |||
182 | /* OV7670 registers */ | ||
183 | #define OV7670_REG_GAIN 0x00 /* Gain lower 8 bits (rest in vref) */ | ||
184 | #define OV7670_REG_BLUE 0x01 /* blue gain */ | ||
185 | #define OV7670_REG_RED 0x02 /* red gain */ | ||
186 | #define OV7670_REG_VREF 0x03 /* Pieces of GAIN, VSTART, VSTOP */ | ||
187 | #define OV7670_REG_COM1 0x04 /* Control 1 */ | ||
188 | #define OV7670_REG_AECHH 0x07 /* AEC MS 5 bits */ | ||
189 | #define OV7670_REG_COM3 0x0c /* Control 3 */ | ||
190 | #define OV7670_REG_COM4 0x0d /* Control 4 */ | ||
191 | #define OV7670_REG_COM5 0x0e /* All "reserved" */ | ||
192 | #define OV7670_REG_COM6 0x0f /* Control 6 */ | ||
193 | #define OV7670_REG_AECH 0x10 /* More bits of AEC value */ | ||
194 | #define OV7670_REG_CLKRC 0x11 /* Clock control */ | ||
195 | #define OV7670_REG_COM7 0x12 /* Control 7 */ | ||
196 | #define OV7670_COM7_FMT_VGA 0x00 | ||
197 | #define OV7670_COM7_YUV 0x00 /* YUV */ | ||
198 | #define OV7670_COM7_FMT_QVGA 0x10 /* QVGA format */ | ||
199 | #define OV7670_COM7_FMT_MASK 0x38 | ||
200 | #define OV7670_COM7_RESET 0x80 /* Register reset */ | ||
201 | #define OV7670_REG_COM8 0x13 /* Control 8 */ | ||
202 | #define OV7670_COM8_AEC 0x01 /* Auto exposure enable */ | ||
203 | #define OV7670_COM8_AWB 0x02 /* White balance enable */ | ||
204 | #define OV7670_COM8_AGC 0x04 /* Auto gain enable */ | ||
205 | #define OV7670_COM8_BFILT 0x20 /* Band filter enable */ | ||
206 | #define OV7670_COM8_AECSTEP 0x40 /* Unlimited AEC step size */ | ||
207 | #define OV7670_COM8_FASTAEC 0x80 /* Enable fast AGC/AEC */ | ||
208 | #define OV7670_REG_COM9 0x14 /* Control 9 - gain ceiling */ | ||
209 | #define OV7670_REG_COM10 0x15 /* Control 10 */ | ||
210 | #define OV7670_REG_HSTART 0x17 /* Horiz start high bits */ | ||
211 | #define OV7670_REG_HSTOP 0x18 /* Horiz stop high bits */ | ||
212 | #define OV7670_REG_VSTART 0x19 /* Vert start high bits */ | ||
213 | #define OV7670_REG_VSTOP 0x1a /* Vert stop high bits */ | ||
214 | #define OV7670_REG_MVFP 0x1e /* Mirror / vflip */ | ||
215 | #define OV7670_MVFP_MIRROR 0x20 /* Mirror image */ | ||
216 | #define OV7670_REG_AEW 0x24 /* AGC upper limit */ | ||
217 | #define OV7670_REG_AEB 0x25 /* AGC lower limit */ | ||
218 | #define OV7670_REG_VPT 0x26 /* AGC/AEC fast mode op region */ | ||
219 | #define OV7670_REG_HREF 0x32 /* HREF pieces */ | ||
220 | #define OV7670_REG_TSLB 0x3a /* lots of stuff */ | ||
221 | #define OV7670_REG_COM11 0x3b /* Control 11 */ | ||
222 | #define OV7670_COM11_EXP 0x02 | ||
223 | #define OV7670_COM11_HZAUTO 0x10 /* Auto detect 50/60 Hz */ | ||
224 | #define OV7670_REG_COM12 0x3c /* Control 12 */ | ||
225 | #define OV7670_REG_COM13 0x3d /* Control 13 */ | ||
226 | #define OV7670_COM13_GAMMA 0x80 /* Gamma enable */ | ||
227 | #define OV7670_COM13_UVSAT 0x40 /* UV saturation auto adjustment */ | ||
228 | #define OV7670_REG_COM14 0x3e /* Control 14 */ | ||
229 | #define OV7670_REG_EDGE 0x3f /* Edge enhancement factor */ | ||
230 | #define OV7670_REG_COM15 0x40 /* Control 15 */ | ||
231 | #define OV7670_COM15_R00FF 0xc0 /* 00 to FF */ | ||
232 | #define OV7670_REG_COM16 0x41 /* Control 16 */ | ||
233 | #define OV7670_COM16_AWBGAIN 0x08 /* AWB gain enable */ | ||
234 | #define OV7670_REG_BRIGHT 0x55 /* Brightness */ | ||
235 | #define OV7670_REG_CONTRAS 0x56 /* Contrast control */ | ||
236 | #define OV7670_REG_GFIX 0x69 /* Fix gain control */ | ||
237 | #define OV7670_REG_RGB444 0x8c /* RGB 444 control */ | ||
238 | #define OV7670_REG_HAECC1 0x9f /* Hist AEC/AGC control 1 */ | ||
239 | #define OV7670_REG_HAECC2 0xa0 /* Hist AEC/AGC control 2 */ | ||
240 | #define OV7670_REG_BD50MAX 0xa5 /* 50hz banding step limit */ | ||
241 | #define OV7670_REG_HAECC3 0xa6 /* Hist AEC/AGC control 3 */ | ||
242 | #define OV7670_REG_HAECC4 0xa7 /* Hist AEC/AGC control 4 */ | ||
243 | #define OV7670_REG_HAECC5 0xa8 /* Hist AEC/AGC control 5 */ | ||
244 | #define OV7670_REG_HAECC6 0xa9 /* Hist AEC/AGC control 6 */ | ||
245 | #define OV7670_REG_HAECC7 0xaa /* Hist AEC/AGC control 7 */ | ||
246 | #define OV7670_REG_BD60MAX 0xab /* 60hz banding step limit */ | ||
247 | |||
248 | struct ovsensor_window { | ||
249 | short x; | ||
250 | short y; | ||
251 | short width; | ||
252 | short height; | ||
253 | /* int format; */ | ||
254 | short quarter; /* Scale width and height down 2x */ | ||
255 | short clockdiv; /* Clock divisor setting */ | ||
256 | }; | ||
257 | |||
258 | static unsigned char ov7670_abs_to_sm(unsigned char v) | ||
259 | { | ||
260 | if (v > 127) | ||
261 | return v & 0x7f; | ||
262 | return (128 - v) | 0x80; | ||
263 | } | ||
264 | |||
265 | /* Write a OV519 register */ | ||
266 | static int reg_w(struct sd *sd, __u16 index, __u8 value) | ||
267 | { | ||
268 | int ret; | ||
269 | __u8 buf[4]; | ||
270 | |||
271 | buf[0] = value; | ||
272 | ret = usb_control_msg(sd->gspca_dev.dev, | ||
273 | usb_sndctrlpipe(sd->gspca_dev.dev, 0), | ||
274 | 1, /* REQ_IO (ov518/519) */ | ||
275 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
276 | 0, index, | ||
277 | &buf[0], 1, 500); | ||
278 | if (ret < 0) | ||
279 | PDEBUG(D_ERR, "Write reg [%02x] %02x failed", index, value); | ||
280 | return ret; | ||
281 | } | ||
282 | |||
283 | /* Read from a OV519 register */ | ||
284 | /* returns: negative is error, pos or zero is data */ | ||
285 | static int reg_r(struct sd *sd, __u16 index) | ||
286 | { | ||
287 | int ret; | ||
288 | __u8 buf[4]; | ||
289 | |||
290 | ret = usb_control_msg(sd->gspca_dev.dev, | ||
291 | usb_rcvctrlpipe(sd->gspca_dev.dev, 0), | ||
292 | 1, /* REQ_IO */ | ||
293 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
294 | 0, index, &buf[0], 1, 500); | ||
295 | |||
296 | if (ret >= 0) | ||
297 | ret = buf[0]; | ||
298 | else | ||
299 | PDEBUG(D_ERR, "Read reg [0x%02x] failed", index); | ||
300 | return ret; | ||
301 | } | ||
302 | |||
303 | /* Read 8 values from a OV519 register */ | ||
304 | static int reg_r8(struct sd *sd, | ||
305 | __u16 index) | ||
306 | { | ||
307 | int ret; | ||
308 | __u8 buf[8]; | ||
309 | |||
310 | ret = usb_control_msg(sd->gspca_dev.dev, | ||
311 | usb_rcvctrlpipe(sd->gspca_dev.dev, 0), | ||
312 | 1, /* REQ_IO */ | ||
313 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
314 | 0, index, &buf[0], 8, 500); | ||
315 | |||
316 | if (ret >= 0) | ||
317 | ret = buf[0]; | ||
318 | else | ||
319 | PDEBUG(D_ERR, "Read reg 8 [0x%02x] failed", index); | ||
320 | return ret; | ||
321 | } | ||
322 | |||
323 | /* | ||
324 | * Writes bits at positions specified by mask to an OV51x reg. Bits that are in | ||
325 | * the same position as 1's in "mask" are cleared and set to "value". Bits | ||
326 | * that are in the same position as 0's in "mask" are preserved, regardless | ||
327 | * of their respective state in "value". | ||
328 | */ | ||
329 | static int reg_w_mask(struct sd *sd, | ||
330 | __u16 index, | ||
331 | __u8 value, | ||
332 | __u8 mask) | ||
333 | { | ||
334 | int ret; | ||
335 | __u8 oldval; | ||
336 | |||
337 | if (mask != 0xff) { | ||
338 | value &= mask; /* Enforce mask on value */ | ||
339 | ret = reg_r(sd, index); | ||
340 | if (ret < 0) | ||
341 | return ret; | ||
342 | |||
343 | oldval = ret & ~mask; /* Clear the masked bits */ | ||
344 | value |= oldval; /* Set the desired bits */ | ||
345 | } | ||
346 | return reg_w(sd, index, value); | ||
347 | } | ||
348 | |||
349 | /* | ||
350 | * The OV518 I2C I/O procedure is different, hence, this function. | ||
351 | * This is normally only called from i2c_w(). Note that this function | ||
352 | * always succeeds regardless of whether the sensor is present and working. | ||
353 | */ | ||
354 | static int i2c_w(struct sd *sd, | ||
355 | __u8 reg, | ||
356 | __u8 value) | ||
357 | { | ||
358 | int rc; | ||
359 | |||
360 | PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg); | ||
361 | |||
362 | /* Select camera register */ | ||
363 | rc = reg_w(sd, R51x_I2C_SADDR_3, reg); | ||
364 | if (rc < 0) | ||
365 | return rc; | ||
366 | |||
367 | /* Write "value" to I2C data port of OV511 */ | ||
368 | rc = reg_w(sd, R51x_I2C_DATA, value); | ||
369 | if (rc < 0) | ||
370 | return rc; | ||
371 | |||
372 | /* Initiate 3-byte write cycle */ | ||
373 | rc = reg_w(sd, R518_I2C_CTL, 0x01); | ||
374 | |||
375 | /* wait for write complete */ | ||
376 | msleep(4); | ||
377 | if (rc < 0) | ||
378 | return rc; | ||
379 | return reg_r8(sd, R518_I2C_CTL); | ||
380 | } | ||
381 | |||
382 | /* | ||
383 | * returns: negative is error, pos or zero is data | ||
384 | * | ||
385 | * The OV518 I2C I/O procedure is different, hence, this function. | ||
386 | * This is normally only called from i2c_r(). Note that this function | ||
387 | * always succeeds regardless of whether the sensor is present and working. | ||
388 | */ | ||
389 | static int i2c_r(struct sd *sd, __u8 reg) | ||
390 | { | ||
391 | int rc, value; | ||
392 | |||
393 | /* Select camera register */ | ||
394 | rc = reg_w(sd, R51x_I2C_SADDR_2, reg); | ||
395 | if (rc < 0) | ||
396 | return rc; | ||
397 | |||
398 | /* Initiate 2-byte write cycle */ | ||
399 | rc = reg_w(sd, R518_I2C_CTL, 0x03); | ||
400 | if (rc < 0) | ||
401 | return rc; | ||
402 | |||
403 | /* Initiate 2-byte read cycle */ | ||
404 | rc = reg_w(sd, R518_I2C_CTL, 0x05); | ||
405 | if (rc < 0) | ||
406 | return rc; | ||
407 | value = reg_r(sd, R51x_I2C_DATA); | ||
408 | PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, value); | ||
409 | return value; | ||
410 | } | ||
411 | |||
412 | /* Writes bits at positions specified by mask to an I2C reg. Bits that are in | ||
413 | * the same position as 1's in "mask" are cleared and set to "value". Bits | ||
414 | * that are in the same position as 0's in "mask" are preserved, regardless | ||
415 | * of their respective state in "value". | ||
416 | */ | ||
417 | static int i2c_w_mask(struct sd *sd, | ||
418 | __u8 reg, | ||
419 | __u8 value, | ||
420 | __u8 mask) | ||
421 | { | ||
422 | int rc; | ||
423 | __u8 oldval; | ||
424 | |||
425 | value &= mask; /* Enforce mask on value */ | ||
426 | rc = i2c_r(sd, reg); | ||
427 | if (rc < 0) | ||
428 | return rc; | ||
429 | oldval = rc & ~mask; /* Clear the masked bits */ | ||
430 | value |= oldval; /* Set the desired bits */ | ||
431 | return i2c_w(sd, reg, value); | ||
432 | } | ||
433 | |||
434 | /* Temporarily stops OV511 from functioning. Must do this before changing | ||
435 | * registers while the camera is streaming */ | ||
436 | static inline int ov51x_stop(struct sd *sd) | ||
437 | { | ||
438 | PDEBUG(D_STREAM, "stopping"); | ||
439 | sd->stopped = 1; | ||
440 | return reg_w(sd, OV519_SYS_RESET1, 0x0f); | ||
441 | } | ||
442 | |||
443 | /* Restarts OV511 after ov511_stop() is called. Has no effect if it is not | ||
444 | * actually stopped (for performance). */ | ||
445 | static inline int ov51x_restart(struct sd *sd) | ||
446 | { | ||
447 | PDEBUG(D_STREAM, "restarting"); | ||
448 | if (!sd->stopped) | ||
449 | return 0; | ||
450 | sd->stopped = 0; | ||
451 | |||
452 | /* Reinitialize the stream */ | ||
453 | return reg_w(sd, OV519_SYS_RESET1, 0x00); | ||
454 | } | ||
455 | |||
456 | /* This does an initial reset of an OmniVision sensor and ensures that I2C | ||
457 | * is synchronized. Returns <0 on failure. | ||
458 | */ | ||
459 | static int init_ov_sensor(struct sd *sd) | ||
460 | { | ||
461 | int i, success; | ||
462 | |||
463 | /* Reset the sensor */ | ||
464 | if (i2c_w(sd, 0x12, 0x80) < 0) | ||
465 | return -EIO; | ||
466 | |||
467 | /* Wait for it to initialize */ | ||
468 | msleep(150); | ||
469 | |||
470 | for (i = 0, success = 0; i < i2c_detect_tries && !success; i++) { | ||
471 | if (i2c_r(sd, OV7610_REG_ID_HIGH) == 0x7f && | ||
472 | i2c_r(sd, OV7610_REG_ID_LOW) == 0xa2) { | ||
473 | success = 1; | ||
474 | continue; | ||
475 | } | ||
476 | |||
477 | /* Reset the sensor */ | ||
478 | if (i2c_w(sd, 0x12, 0x80) < 0) | ||
479 | return -EIO; | ||
480 | /* Wait for it to initialize */ | ||
481 | msleep(150); | ||
482 | /* Dummy read to sync I2C */ | ||
483 | if (i2c_r(sd, 0x00) < 0) | ||
484 | return -EIO; | ||
485 | } | ||
486 | if (!success) | ||
487 | return -EIO; | ||
488 | PDEBUG(D_PROBE, "I2C synced in %d attempt(s)", i); | ||
489 | return 0; | ||
490 | } | ||
491 | |||
492 | /* Switch on standard JPEG compression. Returns 0 for success. */ | ||
493 | static int ov519_init_compression(struct sd *sd) | ||
494 | { | ||
495 | if (!sd->compress_inited) { | ||
496 | if (reg_w_mask(sd, OV519_SYS_EN_CLK1, 1 << 2, 1 << 2) < 0) { | ||
497 | PDEBUG(D_ERR, "Error switching to compressed mode"); | ||
498 | return -EIO; | ||
499 | } | ||
500 | sd->compress_inited = 1; | ||
501 | } | ||
502 | return 0; | ||
503 | } | ||
504 | |||
505 | /* Set the read and write slave IDs. The "slave" argument is the write slave, | ||
506 | * and the read slave will be set to (slave + 1). | ||
507 | * This should not be called from outside the i2c I/O functions. | ||
508 | * Sets I2C read and write slave IDs. Returns <0 for error | ||
509 | */ | ||
510 | static int ov51x_set_slave_ids(struct sd *sd, | ||
511 | __u8 slave) | ||
512 | { | ||
513 | int rc; | ||
514 | |||
515 | rc = reg_w(sd, R51x_I2C_W_SID, slave); | ||
516 | if (rc < 0) | ||
517 | return rc; | ||
518 | return reg_w(sd, R51x_I2C_R_SID, slave + 1); | ||
519 | } | ||
520 | |||
521 | struct ov_regvals { | ||
522 | __u8 reg; | ||
523 | __u8 val; | ||
524 | }; | ||
525 | struct ov_i2c_regvals { | ||
526 | __u8 reg; | ||
527 | __u8 val; | ||
528 | }; | ||
529 | |||
530 | static int write_regvals(struct sd *sd, | ||
531 | struct ov_regvals *regvals, | ||
532 | int n) | ||
533 | { | ||
534 | int rc; | ||
535 | |||
536 | while (--n >= 0) { | ||
537 | rc = reg_w(sd, regvals->reg, regvals->val); | ||
538 | if (rc < 0) | ||
539 | return rc; | ||
540 | regvals++; | ||
541 | } | ||
542 | return 0; | ||
543 | } | ||
544 | |||
545 | static int write_i2c_regvals(struct sd *sd, | ||
546 | struct ov_i2c_regvals *regvals, | ||
547 | int n) | ||
548 | { | ||
549 | int rc; | ||
550 | |||
551 | while (--n >= 0) { | ||
552 | rc = i2c_w(sd, regvals->reg, regvals->val); | ||
553 | if (rc < 0) | ||
554 | return rc; | ||
555 | regvals++; | ||
556 | } | ||
557 | return 0; | ||
558 | } | ||
559 | |||
560 | /**************************************************************************** | ||
561 | * | ||
562 | * OV511 and sensor configuration | ||
563 | * | ||
564 | ***************************************************************************/ | ||
565 | |||
566 | /* This initializes the OV8110, OV8610 sensor. The OV8110 uses | ||
567 | * the same register settings as the OV8610, since they are very similar. | ||
568 | */ | ||
569 | static int ov8xx0_configure(struct sd *sd) | ||
570 | { | ||
571 | int rc; | ||
572 | static struct ov_i2c_regvals norm_8610[] = { | ||
573 | { 0x12, 0x80 }, | ||
574 | { 0x00, 0x00 }, | ||
575 | { 0x01, 0x80 }, | ||
576 | { 0x02, 0x80 }, | ||
577 | { 0x03, 0xc0 }, | ||
578 | { 0x04, 0x30 }, | ||
579 | { 0x05, 0x30 }, /* was 0x10, new from windrv 090403 */ | ||
580 | { 0x06, 0x70 }, /* was 0x80, new from windrv 090403 */ | ||
581 | { 0x0a, 0x86 }, | ||
582 | { 0x0b, 0xb0 }, | ||
583 | { 0x0c, 0x20 }, | ||
584 | { 0x0d, 0x20 }, | ||
585 | { 0x11, 0x01 }, | ||
586 | { 0x12, 0x25 }, | ||
587 | { 0x13, 0x01 }, | ||
588 | { 0x14, 0x04 }, | ||
589 | { 0x15, 0x01 }, /* Lin and Win think different about UV order */ | ||
590 | { 0x16, 0x03 }, | ||
591 | { 0x17, 0x38 }, /* was 0x2f, new from windrv 090403 */ | ||
592 | { 0x18, 0xea }, /* was 0xcf, new from windrv 090403 */ | ||
593 | { 0x19, 0x02 }, /* was 0x06, new from windrv 090403 */ | ||
594 | { 0x1a, 0xf5 }, | ||
595 | { 0x1b, 0x00 }, | ||
596 | { 0x20, 0xd0 }, /* was 0x90, new from windrv 090403 */ | ||
597 | { 0x23, 0xc0 }, /* was 0x00, new from windrv 090403 */ | ||
598 | { 0x24, 0x30 }, /* was 0x1d, new from windrv 090403 */ | ||
599 | { 0x25, 0x50 }, /* was 0x57, new from windrv 090403 */ | ||
600 | { 0x26, 0xa2 }, | ||
601 | { 0x27, 0xea }, | ||
602 | { 0x28, 0x00 }, | ||
603 | { 0x29, 0x00 }, | ||
604 | { 0x2a, 0x80 }, | ||
605 | { 0x2b, 0xc8 }, /* was 0xcc, new from windrv 090403 */ | ||
606 | { 0x2c, 0xac }, | ||
607 | { 0x2d, 0x45 }, /* was 0xd5, new from windrv 090403 */ | ||
608 | { 0x2e, 0x80 }, | ||
609 | { 0x2f, 0x14 }, /* was 0x01, new from windrv 090403 */ | ||
610 | { 0x4c, 0x00 }, | ||
611 | { 0x4d, 0x30 }, /* was 0x10, new from windrv 090403 */ | ||
612 | { 0x60, 0x02 }, /* was 0x01, new from windrv 090403 */ | ||
613 | { 0x61, 0x00 }, /* was 0x09, new from windrv 090403 */ | ||
614 | { 0x62, 0x5f }, /* was 0xd7, new from windrv 090403 */ | ||
615 | { 0x63, 0xff }, | ||
616 | { 0x64, 0x53 }, /* new windrv 090403 says 0x57, | ||
617 | * maybe thats wrong */ | ||
618 | { 0x65, 0x00 }, | ||
619 | { 0x66, 0x55 }, | ||
620 | { 0x67, 0xb0 }, | ||
621 | { 0x68, 0xc0 }, /* was 0xaf, new from windrv 090403 */ | ||
622 | { 0x69, 0x02 }, | ||
623 | { 0x6a, 0x22 }, | ||
624 | { 0x6b, 0x00 }, | ||
625 | { 0x6c, 0x99 }, /* was 0x80, old windrv says 0x00, but | ||
626 | deleting bit7 colors the first images red */ | ||
627 | { 0x6d, 0x11 }, /* was 0x00, new from windrv 090403 */ | ||
628 | { 0x6e, 0x11 }, /* was 0x00, new from windrv 090403 */ | ||
629 | { 0x6f, 0x01 }, | ||
630 | { 0x70, 0x8b }, | ||
631 | { 0x71, 0x00 }, | ||
632 | { 0x72, 0x14 }, | ||
633 | { 0x73, 0x54 }, | ||
634 | { 0x74, 0x00 },/* 0x60? - was 0x00, new from windrv 090403 */ | ||
635 | { 0x75, 0x0e }, | ||
636 | { 0x76, 0x02 }, /* was 0x02, new from windrv 090403 */ | ||
637 | { 0x77, 0xff }, | ||
638 | { 0x78, 0x80 }, | ||
639 | { 0x79, 0x80 }, | ||
640 | { 0x7a, 0x80 }, | ||
641 | { 0x7b, 0x10 }, /* was 0x13, new from windrv 090403 */ | ||
642 | { 0x7c, 0x00 }, | ||
643 | { 0x7d, 0x08 }, /* was 0x09, new from windrv 090403 */ | ||
644 | { 0x7e, 0x08 }, /* was 0xc0, new from windrv 090403 */ | ||
645 | { 0x7f, 0xfb }, | ||
646 | { 0x80, 0x28 }, | ||
647 | { 0x81, 0x00 }, | ||
648 | { 0x82, 0x23 }, | ||
649 | { 0x83, 0x0b }, | ||
650 | { 0x84, 0x00 }, | ||
651 | { 0x85, 0x62 }, /* was 0x61, new from windrv 090403 */ | ||
652 | { 0x86, 0xc9 }, | ||
653 | { 0x87, 0x00 }, | ||
654 | { 0x88, 0x00 }, | ||
655 | { 0x89, 0x01 }, | ||
656 | { 0x12, 0x20 }, | ||
657 | { 0x12, 0x25 }, /* was 0x24, new from windrv 090403 */ | ||
658 | }; | ||
659 | |||
660 | PDEBUG(D_PROBE, "starting ov8xx0 configuration"); | ||
661 | |||
662 | if (init_ov_sensor(sd) < 0) | ||
663 | PDEBUG(D_ERR|D_PROBE, "Failed to read sensor ID"); | ||
664 | else | ||
665 | PDEBUG(D_PROBE, "OV86x0 initialized"); | ||
666 | |||
667 | /* Detect sensor (sub)type */ | ||
668 | rc = i2c_r(sd, OV7610_REG_COM_I); | ||
669 | if (rc < 0) { | ||
670 | PDEBUG(D_ERR, "Error detecting sensor type"); | ||
671 | return -1; | ||
672 | } | ||
673 | if ((rc & 3) == 1) { | ||
674 | PDEBUG(D_PROBE, "Sensor is an OV8610"); | ||
675 | sd->sensor = SEN_OV8610; | ||
676 | } else { | ||
677 | PDEBUG(D_ERR, "Unknown image sensor version: %d", rc & 3); | ||
678 | return -1; | ||
679 | } | ||
680 | PDEBUG(D_PROBE, "Writing 8610 registers"); | ||
681 | if (write_i2c_regvals(sd, | ||
682 | norm_8610, | ||
683 | sizeof norm_8610 / sizeof norm_8610[0])) | ||
684 | return -1; | ||
685 | |||
686 | /* Set sensor-specific vars */ | ||
687 | sd->maxwidth = 640; | ||
688 | sd->maxheight = 480; | ||
689 | return 0; | ||
690 | } | ||
691 | |||
692 | /* This initializes the OV7610, OV7620, or OV76BE sensor. The OV76BE uses | ||
693 | * the same register settings as the OV7610, since they are very similar. | ||
694 | */ | ||
695 | static int ov7xx0_configure(struct sd *sd) | ||
696 | { | ||
697 | int rc, high, low; | ||
698 | |||
699 | /* Lawrence Glaister <lg@jfm.bc.ca> reports: | ||
700 | * | ||
701 | * Register 0x0f in the 7610 has the following effects: | ||
702 | * | ||
703 | * 0x85 (AEC method 1): Best overall, good contrast range | ||
704 | * 0x45 (AEC method 2): Very overexposed | ||
705 | * 0xa5 (spec sheet default): Ok, but the black level is | ||
706 | * shifted resulting in loss of contrast | ||
707 | * 0x05 (old driver setting): very overexposed, too much | ||
708 | * contrast | ||
709 | */ | ||
710 | static struct ov_i2c_regvals norm_7610[] = { | ||
711 | { 0x10, 0xff }, | ||
712 | { 0x16, 0x06 }, | ||
713 | { 0x28, 0x24 }, | ||
714 | { 0x2b, 0xac }, | ||
715 | { 0x12, 0x00 }, | ||
716 | { 0x38, 0x81 }, | ||
717 | { 0x28, 0x24 }, /* 0c */ | ||
718 | { 0x0f, 0x85 }, /* lg's setting */ | ||
719 | { 0x15, 0x01 }, | ||
720 | { 0x20, 0x1c }, | ||
721 | { 0x23, 0x2a }, | ||
722 | { 0x24, 0x10 }, | ||
723 | { 0x25, 0x8a }, | ||
724 | { 0x26, 0xa2 }, | ||
725 | { 0x27, 0xc2 }, | ||
726 | { 0x2a, 0x04 }, | ||
727 | { 0x2c, 0xfe }, | ||
728 | { 0x2d, 0x93 }, | ||
729 | { 0x30, 0x71 }, | ||
730 | { 0x31, 0x60 }, | ||
731 | { 0x32, 0x26 }, | ||
732 | { 0x33, 0x20 }, | ||
733 | { 0x34, 0x48 }, | ||
734 | { 0x12, 0x24 }, | ||
735 | { 0x11, 0x01 }, | ||
736 | { 0x0c, 0x24 }, | ||
737 | { 0x0d, 0x24 }, | ||
738 | }; | ||
739 | |||
740 | static struct ov_i2c_regvals norm_7620[] = { | ||
741 | { 0x00, 0x00 }, /* gain */ | ||
742 | { 0x01, 0x80 }, /* blue gain */ | ||
743 | { 0x02, 0x80 }, /* red gain */ | ||
744 | { 0x03, 0xc0 }, /* OV7670_REG_VREF */ | ||
745 | { 0x06, 0x60 }, | ||
746 | { 0x07, 0x00 }, | ||
747 | { 0x0c, 0x24 }, | ||
748 | { 0x0c, 0x24 }, | ||
749 | { 0x0d, 0x24 }, | ||
750 | { 0x11, 0x01 }, | ||
751 | { 0x12, 0x24 }, | ||
752 | { 0x13, 0x01 }, | ||
753 | { 0x14, 0x84 }, | ||
754 | { 0x15, 0x01 }, | ||
755 | { 0x16, 0x03 }, | ||
756 | { 0x17, 0x2f }, | ||
757 | { 0x18, 0xcf }, | ||
758 | { 0x19, 0x06 }, | ||
759 | { 0x1a, 0xf5 }, | ||
760 | { 0x1b, 0x00 }, | ||
761 | { 0x20, 0x18 }, | ||
762 | { 0x21, 0x80 }, | ||
763 | { 0x22, 0x80 }, | ||
764 | { 0x23, 0x00 }, | ||
765 | { 0x26, 0xa2 }, | ||
766 | { 0x27, 0xea }, | ||
767 | { 0x28, 0x20 }, | ||
768 | { 0x29, 0x00 }, | ||
769 | { 0x2a, 0x10 }, | ||
770 | { 0x2b, 0x00 }, | ||
771 | { 0x2c, 0x88 }, | ||
772 | { 0x2d, 0x91 }, | ||
773 | { 0x2e, 0x80 }, | ||
774 | { 0x2f, 0x44 }, | ||
775 | { 0x60, 0x27 }, | ||
776 | { 0x61, 0x02 }, | ||
777 | { 0x62, 0x5f }, | ||
778 | { 0x63, 0xd5 }, | ||
779 | { 0x64, 0x57 }, | ||
780 | { 0x65, 0x83 }, | ||
781 | { 0x66, 0x55 }, | ||
782 | { 0x67, 0x92 }, | ||
783 | { 0x68, 0xcf }, | ||
784 | { 0x69, 0x76 }, | ||
785 | { 0x6a, 0x22 }, | ||
786 | { 0x6b, 0x00 }, | ||
787 | { 0x6c, 0x02 }, | ||
788 | { 0x6d, 0x44 }, | ||
789 | { 0x6e, 0x80 }, | ||
790 | { 0x6f, 0x1d }, | ||
791 | { 0x70, 0x8b }, | ||
792 | { 0x71, 0x00 }, | ||
793 | { 0x72, 0x14 }, | ||
794 | { 0x73, 0x54 }, | ||
795 | { 0x74, 0x00 }, | ||
796 | { 0x75, 0x8e }, | ||
797 | { 0x76, 0x00 }, | ||
798 | { 0x77, 0xff }, | ||
799 | { 0x78, 0x80 }, | ||
800 | { 0x79, 0x80 }, | ||
801 | { 0x7a, 0x80 }, | ||
802 | { 0x7b, 0xe2 }, | ||
803 | { 0x7c, 0x00 }, | ||
804 | }; | ||
805 | |||
806 | /* 7640 and 7648. The defaults should be OK for most registers. */ | ||
807 | static struct ov_i2c_regvals norm_7640[] = { | ||
808 | { 0x12, 0x80 }, | ||
809 | { 0x12, 0x14 }, | ||
810 | }; | ||
811 | |||
812 | /* 7670. Defaults taken from OmniVision provided data, | ||
813 | * as provided by Jonathan Corbet of OLPC */ | ||
814 | static struct ov_i2c_regvals norm_7670[] = { | ||
815 | { OV7670_REG_COM7, OV7670_COM7_RESET }, | ||
816 | { OV7670_REG_TSLB, 0x04 }, /* OV */ | ||
817 | { OV7670_REG_COM7, OV7670_COM7_FMT_VGA }, /* VGA */ | ||
818 | { OV7670_REG_CLKRC, 0x1 }, | ||
819 | /* | ||
820 | * Set the hardware window. These values from OV don't entirely | ||
821 | * make sense - hstop is less than hstart. But they work... | ||
822 | */ | ||
823 | { OV7670_REG_HSTART, 0x13 }, { OV7670_REG_HSTOP, 0x01 }, | ||
824 | { OV7670_REG_HREF, 0xb6 }, { OV7670_REG_VSTART, 0x02 }, | ||
825 | { OV7670_REG_VSTOP, 0x7a }, { OV7670_REG_VREF, 0x0a }, | ||
826 | |||
827 | { OV7670_REG_COM3, 0 }, { OV7670_REG_COM14, 0 }, | ||
828 | /* Mystery scaling numbers */ | ||
829 | { 0x70, 0x3a }, { 0x71, 0x35 }, | ||
830 | { 0x72, 0x11 }, { 0x73, 0xf0 }, | ||
831 | { 0xa2, 0x02 }, | ||
832 | /* jfm */ | ||
833 | /* { OV7670_REG_COM10, 0x0 }, */ | ||
834 | |||
835 | /* Gamma curve values */ | ||
836 | { 0x7a, 0x20 }, | ||
837 | /* jfm:win 7b=1c */ | ||
838 | { 0x7b, 0x10 }, | ||
839 | /* jfm:win 7c=28 */ | ||
840 | { 0x7c, 0x1e }, | ||
841 | /* jfm:win 7d=3c */ | ||
842 | { 0x7d, 0x35 }, | ||
843 | { 0x7e, 0x5a }, { 0x7f, 0x69 }, | ||
844 | { 0x80, 0x76 }, { 0x81, 0x80 }, | ||
845 | { 0x82, 0x88 }, { 0x83, 0x8f }, | ||
846 | { 0x84, 0x96 }, { 0x85, 0xa3 }, | ||
847 | { 0x86, 0xaf }, { 0x87, 0xc4 }, | ||
848 | { 0x88, 0xd7 }, { 0x89, 0xe8 }, | ||
849 | |||
850 | /* AGC and AEC parameters. Note we start by disabling those features, | ||
851 | then turn them only after tweaking the values. */ | ||
852 | { OV7670_REG_COM8, OV7670_COM8_FASTAEC | ||
853 | | OV7670_COM8_AECSTEP | ||
854 | | OV7670_COM8_BFILT }, | ||
855 | { OV7670_REG_GAIN, 0 }, { OV7670_REG_AECH, 0 }, | ||
856 | { OV7670_REG_COM4, 0x40 }, /* magic reserved bit */ | ||
857 | /* jfm:win 14=38 */ | ||
858 | { OV7670_REG_COM9, 0x18 }, /* 4x gain + magic rsvd bit */ | ||
859 | { OV7670_REG_BD50MAX, 0x05 }, { OV7670_REG_BD60MAX, 0x07 }, | ||
860 | { OV7670_REG_AEW, 0x95 }, { OV7670_REG_AEB, 0x33 }, | ||
861 | { OV7670_REG_VPT, 0xe3 }, { OV7670_REG_HAECC1, 0x78 }, | ||
862 | { OV7670_REG_HAECC2, 0x68 }, | ||
863 | /* jfm:win a1=0b */ | ||
864 | { 0xa1, 0x03 }, /* magic */ | ||
865 | { OV7670_REG_HAECC3, 0xd8 }, { OV7670_REG_HAECC4, 0xd8 }, | ||
866 | { OV7670_REG_HAECC5, 0xf0 }, { OV7670_REG_HAECC6, 0x90 }, | ||
867 | { OV7670_REG_HAECC7, 0x94 }, | ||
868 | { OV7670_REG_COM8, OV7670_COM8_FASTAEC | ||
869 | | OV7670_COM8_AECSTEP | ||
870 | | OV7670_COM8_BFILT | ||
871 | | OV7670_COM8_AGC | ||
872 | | OV7670_COM8_AEC }, | ||
873 | |||
874 | /* Almost all of these are magic "reserved" values. */ | ||
875 | { OV7670_REG_COM5, 0x61 }, { OV7670_REG_COM6, 0x4b }, | ||
876 | { 0x16, 0x02 }, | ||
877 | /* jfm */ | ||
878 | /* { OV7670_REG_MVFP, 0x07|OV7670_MVFP_MIRROR }, */ | ||
879 | { OV7670_REG_MVFP, 0x07 }, | ||
880 | { 0x21, 0x02 }, { 0x22, 0x91 }, | ||
881 | { 0x29, 0x07 }, { 0x33, 0x0b }, | ||
882 | { 0x35, 0x0b }, { 0x37, 0x1d }, | ||
883 | { 0x38, 0x71 }, { 0x39, 0x2a }, | ||
884 | { OV7670_REG_COM12, 0x78 }, { 0x4d, 0x40 }, | ||
885 | { 0x4e, 0x20 }, { OV7670_REG_GFIX, 0 }, | ||
886 | { 0x6b, 0x4a }, { 0x74, 0x10 }, | ||
887 | { 0x8d, 0x4f }, { 0x8e, 0 }, | ||
888 | { 0x8f, 0 }, { 0x90, 0 }, | ||
889 | { 0x91, 0 }, { 0x96, 0 }, | ||
890 | { 0x9a, 0 }, { 0xb0, 0x84 }, | ||
891 | { 0xb1, 0x0c }, { 0xb2, 0x0e }, | ||
892 | { 0xb3, 0x82 }, { 0xb8, 0x0a }, | ||
893 | |||
894 | /* More reserved magic, some of which tweaks white balance */ | ||
895 | { 0x43, 0x0a }, { 0x44, 0xf0 }, | ||
896 | { 0x45, 0x34 }, { 0x46, 0x58 }, | ||
897 | { 0x47, 0x28 }, { 0x48, 0x3a }, | ||
898 | { 0x59, 0x88 }, { 0x5a, 0x88 }, | ||
899 | { 0x5b, 0x44 }, { 0x5c, 0x67 }, | ||
900 | { 0x5d, 0x49 }, { 0x5e, 0x0e }, | ||
901 | { 0x6c, 0x0a }, { 0x6d, 0x55 }, | ||
902 | { 0x6e, 0x11 }, { 0x6f, 0x9f }, | ||
903 | /* "9e for advance AWB" */ | ||
904 | { 0x6a, 0x40 }, { OV7670_REG_BLUE, 0x40 }, | ||
905 | { OV7670_REG_RED, 0x60 }, | ||
906 | { OV7670_REG_COM8, OV7670_COM8_FASTAEC | ||
907 | | OV7670_COM8_AECSTEP | ||
908 | | OV7670_COM8_BFILT | ||
909 | | OV7670_COM8_AGC | ||
910 | | OV7670_COM8_AEC | ||
911 | | OV7670_COM8_AWB }, | ||
912 | |||
913 | /* Matrix coefficients */ | ||
914 | { 0x4f, 0x80 }, { 0x50, 0x80 }, | ||
915 | { 0x51, 0 }, { 0x52, 0x22 }, | ||
916 | { 0x53, 0x5e }, { 0x54, 0x80 }, | ||
917 | { 0x58, 0x9e }, | ||
918 | |||
919 | { OV7670_REG_COM16, OV7670_COM16_AWBGAIN }, | ||
920 | { OV7670_REG_EDGE, 0 }, | ||
921 | { 0x75, 0x05 }, { 0x76, 0xe1 }, | ||
922 | { 0x4c, 0 }, { 0x77, 0x01 }, | ||
923 | { OV7670_REG_COM13, 0xc3 }, { 0x4b, 0x09 }, | ||
924 | { 0xc9, 0x60 }, { OV7670_REG_COM16, 0x38 }, | ||
925 | { 0x56, 0x40 }, | ||
926 | |||
927 | { 0x34, 0x11 }, | ||
928 | { OV7670_REG_COM11, OV7670_COM11_EXP|OV7670_COM11_HZAUTO }, | ||
929 | { 0xa4, 0x88 }, { 0x96, 0 }, | ||
930 | { 0x97, 0x30 }, { 0x98, 0x20 }, | ||
931 | { 0x99, 0x30 }, { 0x9a, 0x84 }, | ||
932 | { 0x9b, 0x29 }, { 0x9c, 0x03 }, | ||
933 | { 0x9d, 0x4c }, { 0x9e, 0x3f }, | ||
934 | { 0x78, 0x04 }, | ||
935 | |||
936 | /* Extra-weird stuff. Some sort of multiplexor register */ | ||
937 | { 0x79, 0x01 }, { 0xc8, 0xf0 }, | ||
938 | { 0x79, 0x0f }, { 0xc8, 0x00 }, | ||
939 | { 0x79, 0x10 }, { 0xc8, 0x7e }, | ||
940 | { 0x79, 0x0a }, { 0xc8, 0x80 }, | ||
941 | { 0x79, 0x0b }, { 0xc8, 0x01 }, | ||
942 | { 0x79, 0x0c }, { 0xc8, 0x0f }, | ||
943 | { 0x79, 0x0d }, { 0xc8, 0x20 }, | ||
944 | { 0x79, 0x09 }, { 0xc8, 0x80 }, | ||
945 | { 0x79, 0x02 }, { 0xc8, 0xc0 }, | ||
946 | { 0x79, 0x03 }, { 0xc8, 0x40 }, | ||
947 | { 0x79, 0x05 }, { 0xc8, 0x30 }, | ||
948 | { 0x79, 0x26 }, | ||
949 | |||
950 | /* Format YUV422 */ | ||
951 | { OV7670_REG_COM7, OV7670_COM7_YUV }, /* Selects YUV mode */ | ||
952 | { OV7670_REG_RGB444, 0 }, /* No RGB444 please */ | ||
953 | { OV7670_REG_COM1, 0 }, | ||
954 | { OV7670_REG_COM15, OV7670_COM15_R00FF }, | ||
955 | { OV7670_REG_COM9, 0x18 }, | ||
956 | /* 4x gain ceiling; 0x8 is reserved bit */ | ||
957 | { 0x4f, 0x80 }, /* "matrix coefficient 1" */ | ||
958 | { 0x50, 0x80 }, /* "matrix coefficient 2" */ | ||
959 | { 0x52, 0x22 }, /* "matrix coefficient 4" */ | ||
960 | { 0x53, 0x5e }, /* "matrix coefficient 5" */ | ||
961 | { 0x54, 0x80 }, /* "matrix coefficient 6" */ | ||
962 | { OV7670_REG_COM13, OV7670_COM13_GAMMA|OV7670_COM13_UVSAT }, | ||
963 | }; | ||
964 | |||
965 | PDEBUG(D_PROBE, "starting OV7xx0 configuration"); | ||
966 | |||
967 | /* jfm:already done? */ | ||
968 | if (init_ov_sensor(sd) < 0) | ||
969 | PDEBUG(D_ERR, "Failed to read sensor ID"); | ||
970 | else | ||
971 | PDEBUG(D_PROBE, "OV7xx0 initialized"); | ||
972 | |||
973 | /* Detect sensor (sub)type */ | ||
974 | rc = i2c_r(sd, OV7610_REG_COM_I); | ||
975 | |||
976 | /* add OV7670 here | ||
977 | * it appears to be wrongly detected as a 7610 by default */ | ||
978 | if (rc < 0) { | ||
979 | PDEBUG(D_ERR, "Error detecting sensor type"); | ||
980 | return -1; | ||
981 | } | ||
982 | if ((rc & 3) == 3) { | ||
983 | /* quick hack to make OV7670s work */ | ||
984 | high = i2c_r(sd, 0x0a); | ||
985 | low = i2c_r(sd, 0x0b); | ||
986 | /* info("%x, %x", high, low); */ | ||
987 | if (high == 0x76 && low == 0x73) { | ||
988 | PDEBUG(D_PROBE, "Sensor is an OV7670"); | ||
989 | sd->sensor = SEN_OV7670; | ||
990 | } else { | ||
991 | PDEBUG(D_PROBE, "Sensor is an OV7610"); | ||
992 | sd->sensor = SEN_OV7610; | ||
993 | } | ||
994 | } else if ((rc & 3) == 1) { | ||
995 | /* I don't know what's different about the 76BE yet. */ | ||
996 | if (i2c_r(sd, 0x15) & 1) | ||
997 | PDEBUG(D_PROBE, "Sensor is an OV7620AE"); | ||
998 | else | ||
999 | PDEBUG(D_PROBE, "Sensor is an OV76BE"); | ||
1000 | |||
1001 | /* OV511+ will return all zero isoc data unless we | ||
1002 | * configure the sensor as a 7620. Someone needs to | ||
1003 | * find the exact reg. setting that causes this. */ | ||
1004 | sd->sensor = SEN_OV76BE; | ||
1005 | } else if ((rc & 3) == 0) { | ||
1006 | /* try to read product id registers */ | ||
1007 | high = i2c_r(sd, 0x0a); | ||
1008 | if (high < 0) { | ||
1009 | PDEBUG(D_ERR, "Error detecting camera chip PID"); | ||
1010 | return high; | ||
1011 | } | ||
1012 | low = i2c_r(sd, 0x0b); | ||
1013 | if (low < 0) { | ||
1014 | PDEBUG(D_ERR, "Error detecting camera chip VER"); | ||
1015 | return low; | ||
1016 | } | ||
1017 | if (high == 0x76) { | ||
1018 | if (low == 0x30) { | ||
1019 | PDEBUG(D_PROBE, "Sensor is an OV7630/OV7635"); | ||
1020 | sd->sensor = SEN_OV7630; | ||
1021 | } else if (low == 0x40) { | ||
1022 | PDEBUG(D_PROBE, "Sensor is an OV7645"); | ||
1023 | sd->sensor = SEN_OV7640; /* FIXME */ | ||
1024 | } else if (low == 0x45) { | ||
1025 | PDEBUG(D_PROBE, "Sensor is an OV7645B"); | ||
1026 | sd->sensor = SEN_OV7640; /* FIXME */ | ||
1027 | } else if (low == 0x48) { | ||
1028 | PDEBUG(D_PROBE, "Sensor is an OV7648"); | ||
1029 | sd->sensor = SEN_OV7640; /* FIXME */ | ||
1030 | } else { | ||
1031 | PDEBUG(D_PROBE, "Unknown sensor: 0x76%X", low); | ||
1032 | return -1; | ||
1033 | } | ||
1034 | } else { | ||
1035 | PDEBUG(D_PROBE, "Sensor is an OV7620"); | ||
1036 | sd->sensor = SEN_OV7620; | ||
1037 | } | ||
1038 | } else { | ||
1039 | PDEBUG(D_ERR, "Unknown image sensor version: %d", rc & 3); | ||
1040 | return -1; | ||
1041 | } | ||
1042 | |||
1043 | if (sd->sensor == SEN_OV7620) { | ||
1044 | PDEBUG(D_PROBE, "Writing 7620 registers"); | ||
1045 | if (write_i2c_regvals(sd, norm_7620, | ||
1046 | sizeof norm_7620 / sizeof norm_7620[0])) | ||
1047 | return -1; | ||
1048 | } else if (sd->sensor == SEN_OV7630) { | ||
1049 | PDEBUG(D_ERR, "7630 is not supported by this driver version"); | ||
1050 | return -1; | ||
1051 | } else if (sd->sensor == SEN_OV7640) { | ||
1052 | PDEBUG(D_PROBE, "Writing 7640 registers"); | ||
1053 | if (write_i2c_regvals(sd, norm_7640, | ||
1054 | sizeof norm_7640 / sizeof norm_7640[0])) | ||
1055 | return -1; | ||
1056 | } else if (sd->sensor == SEN_OV7670) { | ||
1057 | PDEBUG(D_PROBE, "Writing 7670 registers"); | ||
1058 | if (write_i2c_regvals(sd, norm_7670, | ||
1059 | sizeof norm_7670 / sizeof norm_7670[0])) | ||
1060 | return -1; | ||
1061 | } else { | ||
1062 | PDEBUG(D_PROBE, "Writing 7610 registers"); | ||
1063 | if (write_i2c_regvals(sd, norm_7610, | ||
1064 | sizeof norm_7610 / sizeof norm_7610[0])) | ||
1065 | return -1; | ||
1066 | } | ||
1067 | |||
1068 | /* Set sensor-specific vars */ | ||
1069 | sd->maxwidth = 640; | ||
1070 | sd->maxheight = 480; | ||
1071 | return 0; | ||
1072 | } | ||
1073 | |||
1074 | /* This initializes the OV6620, OV6630, OV6630AE, or OV6630AF sensor. */ | ||
1075 | static int ov6xx0_configure(struct sd *sd) | ||
1076 | { | ||
1077 | int rc; | ||
1078 | static struct ov_i2c_regvals norm_6x20[] = { | ||
1079 | { 0x12, 0x80 }, /* reset */ | ||
1080 | { 0x11, 0x01 }, | ||
1081 | { 0x03, 0x60 }, | ||
1082 | { 0x05, 0x7f }, /* For when autoadjust is off */ | ||
1083 | { 0x07, 0xa8 }, | ||
1084 | /* The ratio of 0x0c and 0x0d controls the white point */ | ||
1085 | { 0x0c, 0x24 }, | ||
1086 | { 0x0d, 0x24 }, | ||
1087 | { 0x0f, 0x15 }, /* COMS */ | ||
1088 | { 0x10, 0x75 }, /* AEC Exposure time */ | ||
1089 | { 0x12, 0x24 }, /* Enable AGC */ | ||
1090 | { 0x14, 0x04 }, | ||
1091 | /* 0x16: 0x06 helps frame stability with moving objects */ | ||
1092 | { 0x16, 0x06 }, | ||
1093 | /* { 0x20, 0x30 }, * Aperture correction enable */ | ||
1094 | { 0x26, 0xb2 }, /* BLC enable */ | ||
1095 | /* 0x28: 0x05 Selects RGB format if RGB on */ | ||
1096 | { 0x28, 0x05 }, | ||
1097 | { 0x2a, 0x04 }, /* Disable framerate adjust */ | ||
1098 | /* { 0x2b, 0xac }, * Framerate; Set 2a[7] first */ | ||
1099 | { 0x2d, 0x99 }, | ||
1100 | { 0x33, 0xa0 }, /* Color Processing Parameter */ | ||
1101 | { 0x34, 0xd2 }, /* Max A/D range */ | ||
1102 | { 0x38, 0x8b }, | ||
1103 | { 0x39, 0x40 }, | ||
1104 | |||
1105 | { 0x3c, 0x39 }, /* Enable AEC mode changing */ | ||
1106 | { 0x3c, 0x3c }, /* Change AEC mode */ | ||
1107 | { 0x3c, 0x24 }, /* Disable AEC mode changing */ | ||
1108 | |||
1109 | { 0x3d, 0x80 }, | ||
1110 | /* These next two registers (0x4a, 0x4b) are undocumented. | ||
1111 | * They control the color balance */ | ||
1112 | { 0x4a, 0x80 }, | ||
1113 | { 0x4b, 0x80 }, | ||
1114 | { 0x4d, 0xd2 }, /* This reduces noise a bit */ | ||
1115 | { 0x4e, 0xc1 }, | ||
1116 | { 0x4f, 0x04 }, | ||
1117 | /* Do 50-53 have any effect? */ | ||
1118 | /* Toggle 0x12[2] off and on here? */ | ||
1119 | }; | ||
1120 | |||
1121 | static struct ov_i2c_regvals norm_6x30[] = { | ||
1122 | { 0x12, 0x80 }, /* Reset */ | ||
1123 | { 0x00, 0x1f }, /* Gain */ | ||
1124 | { 0x01, 0x99 }, /* Blue gain */ | ||
1125 | { 0x02, 0x7c }, /* Red gain */ | ||
1126 | { 0x03, 0xc0 }, /* Saturation */ | ||
1127 | { 0x05, 0x0a }, /* Contrast */ | ||
1128 | { 0x06, 0x95 }, /* Brightness */ | ||
1129 | { 0x07, 0x2d }, /* Sharpness */ | ||
1130 | { 0x0c, 0x20 }, | ||
1131 | { 0x0d, 0x20 }, | ||
1132 | { 0x0e, 0x20 }, | ||
1133 | { 0x0f, 0x05 }, | ||
1134 | { 0x10, 0x9a }, | ||
1135 | { 0x11, 0x00 }, /* Pixel clock = fastest */ | ||
1136 | { 0x12, 0x24 }, /* Enable AGC and AWB */ | ||
1137 | { 0x13, 0x21 }, | ||
1138 | { 0x14, 0x80 }, | ||
1139 | { 0x15, 0x01 }, | ||
1140 | { 0x16, 0x03 }, | ||
1141 | { 0x17, 0x38 }, | ||
1142 | { 0x18, 0xea }, | ||
1143 | { 0x19, 0x04 }, | ||
1144 | { 0x1a, 0x93 }, | ||
1145 | { 0x1b, 0x00 }, | ||
1146 | { 0x1e, 0xc4 }, | ||
1147 | { 0x1f, 0x04 }, | ||
1148 | { 0x20, 0x20 }, | ||
1149 | { 0x21, 0x10 }, | ||
1150 | { 0x22, 0x88 }, | ||
1151 | { 0x23, 0xc0 }, /* Crystal circuit power level */ | ||
1152 | { 0x25, 0x9a }, /* Increase AEC black ratio */ | ||
1153 | { 0x26, 0xb2 }, /* BLC enable */ | ||
1154 | { 0x27, 0xa2 }, | ||
1155 | { 0x28, 0x00 }, | ||
1156 | { 0x29, 0x00 }, | ||
1157 | { 0x2a, 0x84 }, /* 60 Hz power */ | ||
1158 | { 0x2b, 0xa8 }, /* 60 Hz power */ | ||
1159 | { 0x2c, 0xa0 }, | ||
1160 | { 0x2d, 0x95 }, /* Enable auto-brightness */ | ||
1161 | { 0x2e, 0x88 }, | ||
1162 | { 0x33, 0x26 }, | ||
1163 | { 0x34, 0x03 }, | ||
1164 | { 0x36, 0x8f }, | ||
1165 | { 0x37, 0x80 }, | ||
1166 | { 0x38, 0x83 }, | ||
1167 | { 0x39, 0x80 }, | ||
1168 | { 0x3a, 0x0f }, | ||
1169 | { 0x3b, 0x3c }, | ||
1170 | { 0x3c, 0x1a }, | ||
1171 | { 0x3d, 0x80 }, | ||
1172 | { 0x3e, 0x80 }, | ||
1173 | { 0x3f, 0x0e }, | ||
1174 | { 0x40, 0x00 }, /* White bal */ | ||
1175 | { 0x41, 0x00 }, /* White bal */ | ||
1176 | { 0x42, 0x80 }, | ||
1177 | { 0x43, 0x3f }, /* White bal */ | ||
1178 | { 0x44, 0x80 }, | ||
1179 | { 0x45, 0x20 }, | ||
1180 | { 0x46, 0x20 }, | ||
1181 | { 0x47, 0x80 }, | ||
1182 | { 0x48, 0x7f }, | ||
1183 | { 0x49, 0x00 }, | ||
1184 | { 0x4a, 0x00 }, | ||
1185 | { 0x4b, 0x80 }, | ||
1186 | { 0x4c, 0xd0 }, | ||
1187 | { 0x4d, 0x10 }, /* U = 0.563u, V = 0.714v */ | ||
1188 | { 0x4e, 0x40 }, | ||
1189 | { 0x4f, 0x07 }, /* UV avg., col. killer: max */ | ||
1190 | { 0x50, 0xff }, | ||
1191 | { 0x54, 0x23 }, /* Max AGC gain: 18dB */ | ||
1192 | { 0x55, 0xff }, | ||
1193 | { 0x56, 0x12 }, | ||
1194 | { 0x57, 0x81 }, | ||
1195 | { 0x58, 0x75 }, | ||
1196 | { 0x59, 0x01 }, /* AGC dark current comp.: +1 */ | ||
1197 | { 0x5a, 0x2c }, | ||
1198 | { 0x5b, 0x0f }, /* AWB chrominance levels */ | ||
1199 | { 0x5c, 0x10 }, | ||
1200 | { 0x3d, 0x80 }, | ||
1201 | { 0x27, 0xa6 }, | ||
1202 | { 0x12, 0x20 }, /* Toggle AWB */ | ||
1203 | { 0x12, 0x24 }, | ||
1204 | }; | ||
1205 | |||
1206 | PDEBUG(D_PROBE, "starting sensor configuration"); | ||
1207 | |||
1208 | if (init_ov_sensor(sd) < 0) { | ||
1209 | PDEBUG(D_ERR, "Failed to read sensor ID."); | ||
1210 | return -1; | ||
1211 | } | ||
1212 | PDEBUG(D_PROBE, "OV6xx0 sensor detected"); | ||
1213 | |||
1214 | /* Detect sensor (sub)type */ | ||
1215 | rc = i2c_r(sd, OV7610_REG_COM_I); | ||
1216 | if (rc < 0) { | ||
1217 | PDEBUG(D_ERR, "Error detecting sensor type"); | ||
1218 | return -1; | ||
1219 | } | ||
1220 | |||
1221 | /* Ugh. The first two bits are the version bits, but | ||
1222 | * the entire register value must be used. I guess OVT | ||
1223 | * underestimated how many variants they would make. */ | ||
1224 | if (rc == 0x00) { | ||
1225 | sd->sensor = SEN_OV6630; | ||
1226 | PDEBUG(D_ERR, | ||
1227 | "WARNING: Sensor is an OV66308. Your camera may have"); | ||
1228 | PDEBUG(D_ERR, "been misdetected in previous driver versions."); | ||
1229 | } else if (rc == 0x01) { | ||
1230 | sd->sensor = SEN_OV6620; | ||
1231 | PDEBUG(D_PROBE, "Sensor is an OV6620"); | ||
1232 | } else if (rc == 0x02) { | ||
1233 | sd->sensor = SEN_OV6630; | ||
1234 | PDEBUG(D_PROBE, "Sensor is an OV66308AE"); | ||
1235 | } else if (rc == 0x03) { | ||
1236 | sd->sensor = SEN_OV6630; | ||
1237 | PDEBUG(D_PROBE, "Sensor is an OV66308AF"); | ||
1238 | } else if (rc == 0x90) { | ||
1239 | sd->sensor = SEN_OV6630; | ||
1240 | PDEBUG(D_ERR, | ||
1241 | "WARNING: Sensor is an OV66307. Your camera may have"); | ||
1242 | PDEBUG(D_ERR, "been misdetected in previous driver versions."); | ||
1243 | } else { | ||
1244 | PDEBUG(D_ERR, "FATAL: Unknown sensor version: 0x%02x", rc); | ||
1245 | return -1; | ||
1246 | } | ||
1247 | |||
1248 | /* Set sensor-specific vars */ | ||
1249 | sd->maxwidth = 352; | ||
1250 | sd->maxheight = 288; | ||
1251 | |||
1252 | if (sd->sensor == SEN_OV6620) { | ||
1253 | PDEBUG(D_PROBE, "Writing 6x20 registers"); | ||
1254 | if (write_i2c_regvals(sd, norm_6x20, | ||
1255 | sizeof norm_6x20 / sizeof norm_6x20[0])) | ||
1256 | return -1; | ||
1257 | } else { | ||
1258 | PDEBUG(D_PROBE, "Writing 6x30 registers"); | ||
1259 | if (write_i2c_regvals(sd, norm_6x30, | ||
1260 | sizeof norm_6x30 / sizeof norm_6x30[0])) | ||
1261 | return -1; | ||
1262 | } | ||
1263 | return 0; | ||
1264 | } | ||
1265 | |||
1266 | /* Turns on or off the LED. Only has an effect with OV511+/OV518(+)/OV519 */ | ||
1267 | static void ov51x_led_control(struct sd *sd, int on) | ||
1268 | { | ||
1269 | PDEBUG(D_STREAM, "LED (%s)", on ? "on" : "off"); | ||
1270 | |||
1271 | /* if (sd->bridge == BRG_OV511PLUS) */ | ||
1272 | /* reg_w(sd, R511_SYS_LED_CTL, on ? 1 : 0); */ | ||
1273 | /* else if (sd->bridge == BRG_OV519) */ | ||
1274 | reg_w_mask(sd, OV519_GPIO_DATA_OUT0, !on, 1); /* 0 / 1 */ | ||
1275 | /* else if (sd->bclass == BCL_OV518) */ | ||
1276 | /* reg_w_mask(sd, R518_GPIO_OUT, on ? 0x02 : 0x00, 0x02); */ | ||
1277 | } | ||
1278 | |||
1279 | /* this function is called at probe time */ | ||
1280 | static int sd_config(struct gspca_dev *gspca_dev, | ||
1281 | const struct usb_device_id *id) | ||
1282 | { | ||
1283 | struct sd *sd = (struct sd *) gspca_dev; | ||
1284 | struct cam *cam; | ||
1285 | |||
1286 | /* (from ov519_configure) */ | ||
1287 | static struct ov_regvals init_519[] = { | ||
1288 | { 0x5a, 0x6d }, /* EnableSystem */ | ||
1289 | /* jfm trace usbsnoop3-1.txt */ | ||
1290 | /* jfm 53 = fb */ | ||
1291 | { 0x53, 0x9b }, | ||
1292 | { 0x54, 0xff }, /* set bit2 to enable jpeg */ | ||
1293 | { 0x5d, 0x03 }, | ||
1294 | { 0x49, 0x01 }, | ||
1295 | { 0x48, 0x00 }, | ||
1296 | /* Set LED pin to output mode. Bit 4 must be cleared or sensor | ||
1297 | * detection will fail. This deserves further investigation. */ | ||
1298 | { OV519_GPIO_IO_CTRL0, 0xee }, | ||
1299 | { 0x51, 0x0f }, /* SetUsbInit */ | ||
1300 | { 0x51, 0x00 }, | ||
1301 | { 0x22, 0x00 }, | ||
1302 | /* windows reads 0x55 at this point*/ | ||
1303 | }; | ||
1304 | |||
1305 | if (write_regvals(sd, init_519, | ||
1306 | sizeof init_519 / sizeof init_519[0])) | ||
1307 | goto error; | ||
1308 | /* jfm: not seen in windows trace */ | ||
1309 | if (ov519_init_compression(sd)) | ||
1310 | goto error; | ||
1311 | ov51x_led_control(sd, 0); /* turn LED off */ | ||
1312 | |||
1313 | /* Test for 76xx */ | ||
1314 | sd->primary_i2c_slave = OV7xx0_SID; | ||
1315 | if (ov51x_set_slave_ids(sd, OV7xx0_SID) < 0) | ||
1316 | goto error; | ||
1317 | |||
1318 | /* The OV519 must be more aggressive about sensor detection since | ||
1319 | * I2C write will never fail if the sensor is not present. We have | ||
1320 | * to try to initialize the sensor to detect its presence */ | ||
1321 | if (init_ov_sensor(sd) < 0) { | ||
1322 | /* Test for 6xx0 */ | ||
1323 | sd->primary_i2c_slave = OV6xx0_SID; | ||
1324 | if (ov51x_set_slave_ids(sd, OV6xx0_SID) < 0) | ||
1325 | goto error; | ||
1326 | |||
1327 | if (init_ov_sensor(sd) < 0) { | ||
1328 | /* Test for 8xx0 */ | ||
1329 | sd->primary_i2c_slave = OV8xx0_SID; | ||
1330 | if (ov51x_set_slave_ids(sd, OV8xx0_SID) < 0) | ||
1331 | goto error; | ||
1332 | |||
1333 | if (init_ov_sensor(sd) < 0) { | ||
1334 | PDEBUG(D_ERR, | ||
1335 | "Can't determine sensor slave IDs"); | ||
1336 | goto error; | ||
1337 | } else { | ||
1338 | if (ov8xx0_configure(sd) < 0) { | ||
1339 | PDEBUG(D_ERR, | ||
1340 | "Failed to configure OV8xx0 sensor"); | ||
1341 | goto error; | ||
1342 | } | ||
1343 | } | ||
1344 | } else { | ||
1345 | if (ov6xx0_configure(sd) < 0) { | ||
1346 | PDEBUG(D_ERR, "Failed to configure OV6xx0"); | ||
1347 | goto error; | ||
1348 | } | ||
1349 | } | ||
1350 | } else { | ||
1351 | if (ov7xx0_configure(sd) < 0) { | ||
1352 | PDEBUG(D_ERR, "Failed to configure OV7xx0"); | ||
1353 | goto error; | ||
1354 | } | ||
1355 | } | ||
1356 | |||
1357 | cam = &gspca_dev->cam; | ||
1358 | cam->epaddr = OV511_ENDPOINT_ADDRESS; | ||
1359 | if (sd->maxwidth == 640) { | ||
1360 | cam->cam_mode = vga_mode; | ||
1361 | cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; | ||
1362 | } else { | ||
1363 | cam->cam_mode = sif_mode; | ||
1364 | cam->nmodes = sizeof sif_mode / sizeof sif_mode[0]; | ||
1365 | } | ||
1366 | cam->dev_name = (char *) id->driver_info; | ||
1367 | sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; | ||
1368 | sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; | ||
1369 | sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; | ||
1370 | return 0; | ||
1371 | error: | ||
1372 | PDEBUG(D_ERR, "OV519 Config failed"); | ||
1373 | return -EBUSY; | ||
1374 | } | ||
1375 | |||
1376 | /* this function is called at open time */ | ||
1377 | static int sd_open(struct gspca_dev *gspca_dev) | ||
1378 | { | ||
1379 | return 0; | ||
1380 | } | ||
1381 | |||
1382 | /* Sets up the OV519 with the given image parameters | ||
1383 | * | ||
1384 | * OV519 needs a completely different approach, until we can figure out what | ||
1385 | * the individual registers do. | ||
1386 | * | ||
1387 | * Do not put any sensor-specific code in here (including I2C I/O functions) | ||
1388 | */ | ||
1389 | static int ov519_mode_init_regs(struct sd *sd, | ||
1390 | int width, int height) | ||
1391 | { | ||
1392 | static struct ov_regvals mode_init_519_ov7670[] = { | ||
1393 | { 0x5d, 0x03 }, /* Turn off suspend mode */ | ||
1394 | { 0x53, 0x9f }, /* was 9b in 1.65-1.08 */ | ||
1395 | { 0x54, 0x0f }, /* bit2 (jpeg enable) */ | ||
1396 | { 0xa2, 0x20 }, /* a2-a5 are undocumented */ | ||
1397 | { 0xa3, 0x18 }, | ||
1398 | { 0xa4, 0x04 }, | ||
1399 | { 0xa5, 0x28 }, | ||
1400 | { 0x37, 0x00 }, /* SetUsbInit */ | ||
1401 | { 0x55, 0x02 }, /* 4.096 Mhz audio clock */ | ||
1402 | /* Enable both fields, YUV Input, disable defect comp (why?) */ | ||
1403 | { 0x20, 0x0c }, | ||
1404 | { 0x21, 0x38 }, | ||
1405 | { 0x22, 0x1d }, | ||
1406 | { 0x17, 0x50 }, /* undocumented */ | ||
1407 | { 0x37, 0x00 }, /* undocumented */ | ||
1408 | { 0x40, 0xff }, /* I2C timeout counter */ | ||
1409 | { 0x46, 0x00 }, /* I2C clock prescaler */ | ||
1410 | { 0x59, 0x04 }, /* new from windrv 090403 */ | ||
1411 | { 0xff, 0x00 }, /* undocumented */ | ||
1412 | /* windows reads 0x55 at this point, why? */ | ||
1413 | }; | ||
1414 | |||
1415 | static struct ov_regvals mode_init_519[] = { | ||
1416 | { 0x5d, 0x03 }, /* Turn off suspend mode */ | ||
1417 | { 0x53, 0x9f }, /* was 9b in 1.65-1.08 */ | ||
1418 | { 0x54, 0x0f }, /* bit2 (jpeg enable) */ | ||
1419 | { 0xa2, 0x20 }, /* a2-a5 are undocumented */ | ||
1420 | { 0xa3, 0x18 }, | ||
1421 | { 0xa4, 0x04 }, | ||
1422 | { 0xa5, 0x28 }, | ||
1423 | { 0x37, 0x00 }, /* SetUsbInit */ | ||
1424 | { 0x55, 0x02 }, /* 4.096 Mhz audio clock */ | ||
1425 | /* Enable both fields, YUV Input, disable defect comp (why?) */ | ||
1426 | { 0x22, 0x1d }, | ||
1427 | { 0x17, 0x50 }, /* undocumented */ | ||
1428 | { 0x37, 0x00 }, /* undocumented */ | ||
1429 | { 0x40, 0xff }, /* I2C timeout counter */ | ||
1430 | { 0x46, 0x00 }, /* I2C clock prescaler */ | ||
1431 | { 0x59, 0x04 }, /* new from windrv 090403 */ | ||
1432 | { 0xff, 0x00 }, /* undocumented */ | ||
1433 | /* windows reads 0x55 at this point, why? */ | ||
1434 | }; | ||
1435 | |||
1436 | /* int hi_res; */ | ||
1437 | |||
1438 | PDEBUG(D_CONF, "mode init %dx%d", width, height); | ||
1439 | |||
1440 | /* if (width >= 800 && height >= 600) | ||
1441 | hi_res = 1; | ||
1442 | else | ||
1443 | hi_res = 0; */ | ||
1444 | |||
1445 | /* if (ov51x_stop(sd) < 0) | ||
1446 | return -EIO; */ | ||
1447 | |||
1448 | /******** Set the mode ********/ | ||
1449 | if (sd->sensor != SEN_OV7670) { | ||
1450 | if (write_regvals(sd, mode_init_519, | ||
1451 | sizeof mode_init_519 / sizeof mode_init_519[0])) | ||
1452 | return -EIO; | ||
1453 | } else { | ||
1454 | if (write_regvals(sd, mode_init_519_ov7670, | ||
1455 | sizeof mode_init_519_ov7670 | ||
1456 | / sizeof mode_init_519_ov7670[0])) | ||
1457 | return -EIO; | ||
1458 | } | ||
1459 | |||
1460 | if (sd->sensor == SEN_OV7640) { | ||
1461 | /* Select 8-bit input mode */ | ||
1462 | reg_w_mask(sd, OV519_CAM_DFR, 0x10, 0x10); | ||
1463 | } | ||
1464 | |||
1465 | reg_w(sd, OV519_CAM_H_SIZE, width >> 4); | ||
1466 | reg_w(sd, OV519_CAM_V_SIZE, height >> 3); | ||
1467 | reg_w(sd, OV519_CAM_X_OFFSETL, 0x00); | ||
1468 | reg_w(sd, OV519_CAM_X_OFFSETH, 0x00); | ||
1469 | reg_w(sd, OV519_CAM_Y_OFFSETL, 0x00); | ||
1470 | reg_w(sd, OV519_CAM_Y_OFFSETH, 0x00); | ||
1471 | reg_w(sd, OV519_CAM_DIVIDER, 0x00); | ||
1472 | reg_w(sd, OV519_CAM_FORMAT, 0x03); /* YUV422 */ | ||
1473 | reg_w(sd, 0x26, 0x00); /* Undocumented */ | ||
1474 | |||
1475 | /******** Set the framerate ********/ | ||
1476 | if (frame_rate > 0) | ||
1477 | sd->frame_rate = frame_rate; | ||
1478 | |||
1479 | /* FIXME: These are only valid at the max resolution. */ | ||
1480 | sd->clockdiv = 0; | ||
1481 | if (sd->sensor == SEN_OV7640) { | ||
1482 | switch (sd->frame_rate) { | ||
1483 | /*jfm: default was 30 fps */ | ||
1484 | case 30: | ||
1485 | reg_w(sd, 0xa4, 0x0c); | ||
1486 | reg_w(sd, 0x23, 0xff); | ||
1487 | break; | ||
1488 | case 25: | ||
1489 | reg_w(sd, 0xa4, 0x0c); | ||
1490 | reg_w(sd, 0x23, 0x1f); | ||
1491 | break; | ||
1492 | case 20: | ||
1493 | reg_w(sd, 0xa4, 0x0c); | ||
1494 | reg_w(sd, 0x23, 0x1b); | ||
1495 | break; | ||
1496 | default: | ||
1497 | /* case 15: */ | ||
1498 | reg_w(sd, 0xa4, 0x04); | ||
1499 | reg_w(sd, 0x23, 0xff); | ||
1500 | sd->clockdiv = 1; | ||
1501 | break; | ||
1502 | case 10: | ||
1503 | reg_w(sd, 0xa4, 0x04); | ||
1504 | reg_w(sd, 0x23, 0x1f); | ||
1505 | sd->clockdiv = 1; | ||
1506 | break; | ||
1507 | case 5: | ||
1508 | reg_w(sd, 0xa4, 0x04); | ||
1509 | reg_w(sd, 0x23, 0x1b); | ||
1510 | sd->clockdiv = 1; | ||
1511 | break; | ||
1512 | } | ||
1513 | } else if (sd->sensor == SEN_OV8610) { | ||
1514 | switch (sd->frame_rate) { | ||
1515 | default: /* 15 fps */ | ||
1516 | /* case 15: */ | ||
1517 | reg_w(sd, 0xa4, 0x06); | ||
1518 | reg_w(sd, 0x23, 0xff); | ||
1519 | break; | ||
1520 | case 10: | ||
1521 | reg_w(sd, 0xa4, 0x06); | ||
1522 | reg_w(sd, 0x23, 0x1f); | ||
1523 | break; | ||
1524 | case 5: | ||
1525 | reg_w(sd, 0xa4, 0x06); | ||
1526 | reg_w(sd, 0x23, 0x1b); | ||
1527 | break; | ||
1528 | } | ||
1529 | sd->clockdiv = 0; | ||
1530 | } else if (sd->sensor == SEN_OV7670) { /* guesses, based on 7640 */ | ||
1531 | PDEBUG(D_STREAM, "Setting framerate to %d fps", | ||
1532 | (sd->frame_rate == 0) ? 15 : sd->frame_rate); | ||
1533 | switch (sd->frame_rate) { | ||
1534 | case 30: | ||
1535 | reg_w(sd, 0xa4, 0x10); | ||
1536 | reg_w(sd, 0x23, 0xff); | ||
1537 | break; | ||
1538 | case 20: | ||
1539 | reg_w(sd, 0xa4, 0x10); | ||
1540 | reg_w(sd, 0x23, 0x1b); | ||
1541 | break; | ||
1542 | default: /* 15 fps */ | ||
1543 | /* case 15: */ | ||
1544 | reg_w(sd, 0xa4, 0x10); | ||
1545 | reg_w(sd, 0x23, 0xff); | ||
1546 | sd->clockdiv = 1; | ||
1547 | break; | ||
1548 | } | ||
1549 | } | ||
1550 | |||
1551 | /* if (ov51x_restart(sd) < 0) | ||
1552 | return -EIO; */ | ||
1553 | |||
1554 | /* Reset it just for good measure */ | ||
1555 | /* if (ov51x_reset(sd, OV511_RESET_NOREGS) < 0) | ||
1556 | return -EIO; */ | ||
1557 | return 0; | ||
1558 | } | ||
1559 | |||
1560 | static int mode_init_ov_sensor_regs(struct sd *sd, | ||
1561 | struct ovsensor_window *win) | ||
1562 | { | ||
1563 | int qvga = win->quarter; | ||
1564 | |||
1565 | /******** Mode (VGA/QVGA) and sensor specific regs ********/ | ||
1566 | switch (sd->sensor) { | ||
1567 | case SEN_OV8610: | ||
1568 | /* For OV8610 qvga means qsvga */ | ||
1569 | i2c_w_mask(sd, OV7610_REG_COM_C, qvga ? (1 << 5) : 0, 1 << 5); | ||
1570 | break; | ||
1571 | case SEN_OV7610: | ||
1572 | i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); | ||
1573 | break; | ||
1574 | case SEN_OV7620: | ||
1575 | /* i2c_w(sd, 0x2b, 0x00); */ | ||
1576 | i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); | ||
1577 | i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20); | ||
1578 | i2c_w(sd, 0x24, qvga ? 0x20 : 0x3a); | ||
1579 | i2c_w(sd, 0x25, qvga ? 0x30 : 0x60); | ||
1580 | i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40); | ||
1581 | i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0); | ||
1582 | i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20); | ||
1583 | break; | ||
1584 | case SEN_OV76BE: | ||
1585 | /* i2c_w(sd, 0x2b, 0x00); */ | ||
1586 | i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); | ||
1587 | break; | ||
1588 | case SEN_OV7640: | ||
1589 | /* i2c_w(sd, 0x2b, 0x00); */ | ||
1590 | i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); | ||
1591 | i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20); | ||
1592 | /* i2c_w(sd, 0x24, qvga ? 0x20 : 0x3a); */ | ||
1593 | /* i2c_w(sd, 0x25, qvga ? 0x30 : 0x60); */ | ||
1594 | /* i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40); */ | ||
1595 | /* i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0); */ | ||
1596 | /* i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20); */ | ||
1597 | break; | ||
1598 | case SEN_OV7670: | ||
1599 | /* set COM7_FMT_VGA or COM7_FMT_QVGA | ||
1600 | * do we need to set anything else? | ||
1601 | * HSTART etc are set in set_ov_sensor_window itself */ | ||
1602 | i2c_w_mask(sd, OV7670_REG_COM7, | ||
1603 | qvga ? OV7670_COM7_FMT_QVGA : OV7670_COM7_FMT_VGA, | ||
1604 | OV7670_COM7_FMT_MASK); | ||
1605 | break; | ||
1606 | case SEN_OV6620: | ||
1607 | i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); | ||
1608 | break; | ||
1609 | case SEN_OV6630: | ||
1610 | i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); | ||
1611 | break; | ||
1612 | default: | ||
1613 | return -EINVAL; | ||
1614 | } | ||
1615 | |||
1616 | /******** Palette-specific regs ********/ | ||
1617 | /* Need to do work here for the OV7670 */ | ||
1618 | |||
1619 | if (sd->sensor == SEN_OV7610 || sd->sensor == SEN_OV76BE) { | ||
1620 | /* not valid on the OV6620/OV7620/6630? */ | ||
1621 | i2c_w_mask(sd, 0x0e, 0x00, 0x40); | ||
1622 | } | ||
1623 | |||
1624 | /* The OV518 needs special treatment. Although both the OV518 | ||
1625 | * and the OV6630 support a 16-bit video bus, only the 8 bit Y | ||
1626 | * bus is actually used. The UV bus is tied to ground. | ||
1627 | * Therefore, the OV6630 needs to be in 8-bit multiplexed | ||
1628 | * output mode */ | ||
1629 | |||
1630 | /* OV7640 is 8-bit only */ | ||
1631 | |||
1632 | if (sd->sensor != SEN_OV6630 && sd->sensor != SEN_OV7640) | ||
1633 | i2c_w_mask(sd, 0x13, 0x00, 0x20); | ||
1634 | /* } */ | ||
1635 | |||
1636 | /******** Clock programming ********/ | ||
1637 | /* The OV6620 needs special handling. This prevents the | ||
1638 | * severe banding that normally occurs */ | ||
1639 | if (sd->sensor == SEN_OV6620) { | ||
1640 | |||
1641 | /* Clock down */ | ||
1642 | i2c_w(sd, 0x2a, 0x04); | ||
1643 | i2c_w(sd, 0x11, win->clockdiv); | ||
1644 | i2c_w(sd, 0x2a, 0x84); | ||
1645 | /* This next setting is critical. It seems to improve | ||
1646 | * the gain or the contrast. The "reserved" bits seem | ||
1647 | * to have some effect in this case. */ | ||
1648 | i2c_w(sd, 0x2d, 0x85); | ||
1649 | } else if (win->clockdiv >= 0) { | ||
1650 | i2c_w(sd, 0x11, win->clockdiv); | ||
1651 | } | ||
1652 | |||
1653 | /******** Special Features ********/ | ||
1654 | /* no evidence this is possible with OV7670, either */ | ||
1655 | /* Test Pattern */ | ||
1656 | if (sd->sensor != SEN_OV7640 && sd->sensor != SEN_OV7670) | ||
1657 | i2c_w_mask(sd, 0x12, 0x00, 0x02); | ||
1658 | |||
1659 | /* Enable auto white balance */ | ||
1660 | if (sd->sensor == SEN_OV7670) | ||
1661 | i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_AWB, | ||
1662 | OV7670_COM8_AWB); | ||
1663 | else | ||
1664 | i2c_w_mask(sd, 0x12, 0x04, 0x04); | ||
1665 | |||
1666 | /* This will go away as soon as ov51x_mode_init_sensor_regs() */ | ||
1667 | /* is fully tested. */ | ||
1668 | /* 7620/6620/6630? don't have register 0x35, so play it safe */ | ||
1669 | if (sd->sensor == SEN_OV7610 || sd->sensor == SEN_OV76BE) { | ||
1670 | if (win->width == 640 /*&& win->height == 480*/) | ||
1671 | i2c_w(sd, 0x35, 0x9e); | ||
1672 | else | ||
1673 | i2c_w(sd, 0x35, 0x1e); | ||
1674 | } | ||
1675 | return 0; | ||
1676 | } | ||
1677 | |||
1678 | static int set_ov_sensor_window(struct sd *sd, | ||
1679 | struct ovsensor_window *win) | ||
1680 | { | ||
1681 | int hwsbase, hwebase, vwsbase, vwebase, hwscale, vwscale; | ||
1682 | int ret, hstart, hstop, vstop, vstart; | ||
1683 | __u8 v; | ||
1684 | |||
1685 | /* The different sensor ICs handle setting up of window differently. | ||
1686 | * IF YOU SET IT WRONG, YOU WILL GET ALL ZERO ISOC DATA FROM OV51x!! */ | ||
1687 | switch (sd->sensor) { | ||
1688 | case SEN_OV8610: | ||
1689 | hwsbase = 0x1e; | ||
1690 | hwebase = 0x1e; | ||
1691 | vwsbase = 0x02; | ||
1692 | vwebase = 0x02; | ||
1693 | break; | ||
1694 | case SEN_OV7610: | ||
1695 | case SEN_OV76BE: | ||
1696 | hwsbase = 0x38; | ||
1697 | hwebase = 0x3a; | ||
1698 | vwsbase = vwebase = 0x05; | ||
1699 | break; | ||
1700 | case SEN_OV6620: | ||
1701 | case SEN_OV6630: | ||
1702 | hwsbase = 0x38; | ||
1703 | hwebase = 0x3a; | ||
1704 | vwsbase = 0x05; | ||
1705 | vwebase = 0x06; | ||
1706 | break; | ||
1707 | case SEN_OV7620: | ||
1708 | hwsbase = 0x2f; /* From 7620.SET (spec is wrong) */ | ||
1709 | hwebase = 0x2f; | ||
1710 | vwsbase = vwebase = 0x05; | ||
1711 | break; | ||
1712 | case SEN_OV7640: | ||
1713 | hwsbase = 0x1a; | ||
1714 | hwebase = 0x1a; | ||
1715 | vwsbase = vwebase = 0x03; | ||
1716 | break; | ||
1717 | case SEN_OV7670: | ||
1718 | /*handling of OV7670 hardware sensor start and stop values | ||
1719 | * is very odd, compared to the other OV sensors */ | ||
1720 | vwsbase = vwebase = hwebase = hwsbase = 0x00; | ||
1721 | break; | ||
1722 | default: | ||
1723 | return -EINVAL; | ||
1724 | } | ||
1725 | |||
1726 | switch (sd->sensor) { | ||
1727 | case SEN_OV6620: | ||
1728 | case SEN_OV6630: | ||
1729 | if (win->quarter) { /* QCIF */ | ||
1730 | hwscale = 0; | ||
1731 | vwscale = 0; | ||
1732 | } else { /* CIF */ | ||
1733 | hwscale = 1; | ||
1734 | vwscale = 1; /* The datasheet says 0; | ||
1735 | * it's wrong */ | ||
1736 | } | ||
1737 | break; | ||
1738 | case SEN_OV8610: | ||
1739 | if (win->quarter) { /* QSVGA */ | ||
1740 | hwscale = 1; | ||
1741 | vwscale = 1; | ||
1742 | } else { /* SVGA */ | ||
1743 | hwscale = 2; | ||
1744 | vwscale = 2; | ||
1745 | } | ||
1746 | break; | ||
1747 | default: /* SEN_OV7xx0 */ | ||
1748 | if (win->quarter) { /* QVGA */ | ||
1749 | hwscale = 1; | ||
1750 | vwscale = 0; | ||
1751 | } else { /* VGA */ | ||
1752 | hwscale = 2; | ||
1753 | vwscale = 1; | ||
1754 | } | ||
1755 | } | ||
1756 | |||
1757 | ret = mode_init_ov_sensor_regs(sd, win); | ||
1758 | if (ret < 0) | ||
1759 | return ret; | ||
1760 | |||
1761 | if (sd->sensor == SEN_OV8610) { | ||
1762 | i2c_w_mask(sd, 0x2d, 0x05, 0x40); | ||
1763 | /* old 0x95, new 0x05 from windrv 090403 */ | ||
1764 | /* bits 5-7: reserved */ | ||
1765 | i2c_w_mask(sd, 0x28, 0x20, 0x20); | ||
1766 | /* bit 5: progressive mode on */ | ||
1767 | } | ||
1768 | |||
1769 | /* The below is wrong for OV7670s because their window registers | ||
1770 | * only store the high bits in 0x17 to 0x1a */ | ||
1771 | |||
1772 | /* SRH Use sd->max values instead of requested win values */ | ||
1773 | /* SCS Since we're sticking with only the max hardware widths | ||
1774 | * for a given mode */ | ||
1775 | /* I can hard code this for OV7670s */ | ||
1776 | /* Yes, these numbers do look odd, but they're tested and work! */ | ||
1777 | if (sd->sensor == SEN_OV7670) { | ||
1778 | if (win->quarter) { /* QVGA from ov7670.c by | ||
1779 | * Jonathan Corbet */ | ||
1780 | hstart = 164; | ||
1781 | hstop = 20; | ||
1782 | vstart = 14; | ||
1783 | vstop = 494; | ||
1784 | } else { /* VGA */ | ||
1785 | hstart = 158; | ||
1786 | hstop = 14; | ||
1787 | vstart = 10; | ||
1788 | vstop = 490; | ||
1789 | } | ||
1790 | /* OV7670 hardware window registers are split across | ||
1791 | * multiple locations */ | ||
1792 | i2c_w(sd, OV7670_REG_HSTART, (hstart >> 3) & 0xff); | ||
1793 | i2c_w(sd, OV7670_REG_HSTOP, (hstop >> 3) & 0xff); | ||
1794 | v = i2c_r(sd, OV7670_REG_HREF); | ||
1795 | v = (v & 0xc0) | ((hstop & 0x7) << 3) | (hstart & 0x07); | ||
1796 | msleep(10); /* need to sleep between read and write to | ||
1797 | * same reg! */ | ||
1798 | i2c_w(sd, OV7670_REG_HREF, v); | ||
1799 | |||
1800 | i2c_w(sd, OV7670_REG_VSTART, (vstart >> 2) & 0xff); | ||
1801 | i2c_w(sd, OV7670_REG_VSTOP, (vstop >> 2) & 0xff); | ||
1802 | v = i2c_r(sd, OV7670_REG_VREF); | ||
1803 | v = (v & 0xc0) | ((vstop & 0x3) << 2) | (vstart & 0x03); | ||
1804 | msleep(10); /* need to sleep between read and write to | ||
1805 | * same reg! */ | ||
1806 | i2c_w(sd, OV7670_REG_VREF, v); | ||
1807 | |||
1808 | } else { | ||
1809 | i2c_w(sd, 0x17, hwsbase + (win->x >> hwscale)); | ||
1810 | i2c_w(sd, 0x18, hwebase + ((win->x + win->width) >> hwscale)); | ||
1811 | i2c_w(sd, 0x19, vwsbase + (win->y >> vwscale)); | ||
1812 | i2c_w(sd, 0x1a, vwebase + ((win->y + win->height) >> vwscale)); | ||
1813 | } | ||
1814 | return 0; | ||
1815 | } | ||
1816 | |||
1817 | static int ov_sensor_mode_setup(struct sd *sd, | ||
1818 | int width, int height) | ||
1819 | { | ||
1820 | struct ovsensor_window win; | ||
1821 | |||
1822 | /* win.format = mode; */ | ||
1823 | |||
1824 | /* Unless subcapture is enabled, | ||
1825 | * center the image window and downsample | ||
1826 | * if possible to increase the field of view */ | ||
1827 | /* NOTE: OV518(+) and OV519 does downsampling on its own */ | ||
1828 | win.width = width; | ||
1829 | win.height = height; | ||
1830 | if (width == sd->maxwidth) | ||
1831 | win.quarter = 0; | ||
1832 | else | ||
1833 | win.quarter = 1; | ||
1834 | |||
1835 | /* Center it */ | ||
1836 | win.x = (win.width - width) / 2; | ||
1837 | win.y = (win.height - height) / 2; | ||
1838 | |||
1839 | /* Clock is determined by OV519 frame rate code */ | ||
1840 | win.clockdiv = sd->clockdiv; | ||
1841 | |||
1842 | PDEBUG(D_CONF, "Setting clock divider to %d", win.clockdiv); | ||
1843 | return set_ov_sensor_window(sd, &win); | ||
1844 | } | ||
1845 | |||
1846 | /* -- start the camera -- */ | ||
1847 | static void sd_start(struct gspca_dev *gspca_dev) | ||
1848 | { | ||
1849 | struct sd *sd = (struct sd *) gspca_dev; | ||
1850 | int ret; | ||
1851 | |||
1852 | |||
1853 | ret = ov519_mode_init_regs(sd, gspca_dev->width, gspca_dev->height); | ||
1854 | if (ret < 0) | ||
1855 | goto out; | ||
1856 | ret = ov_sensor_mode_setup(sd, gspca_dev->width, gspca_dev->height); | ||
1857 | if (ret < 0) | ||
1858 | goto out; | ||
1859 | |||
1860 | ret = ov51x_restart((struct sd *) gspca_dev); | ||
1861 | if (ret < 0) | ||
1862 | goto out; | ||
1863 | PDEBUG(D_STREAM, "camera started alt: 0x%02x", gspca_dev->alt); | ||
1864 | ov51x_led_control(sd, 1); | ||
1865 | return; | ||
1866 | out: | ||
1867 | PDEBUG(D_ERR, "camera start error:%d", ret); | ||
1868 | } | ||
1869 | |||
1870 | static void sd_stopN(struct gspca_dev *gspca_dev) | ||
1871 | { | ||
1872 | ov51x_stop((struct sd *) gspca_dev); | ||
1873 | ov51x_led_control((struct sd *) gspca_dev, 0); | ||
1874 | } | ||
1875 | |||
1876 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
1877 | { | ||
1878 | } | ||
1879 | |||
1880 | static void sd_close(struct gspca_dev *gspca_dev) | ||
1881 | { | ||
1882 | } | ||
1883 | |||
1884 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | ||
1885 | struct gspca_frame *frame, /* target */ | ||
1886 | unsigned char *data, /* isoc packet */ | ||
1887 | int len) /* iso packet length */ | ||
1888 | { | ||
1889 | /* Header of ov519 is 16 bytes: | ||
1890 | * Byte Value Description | ||
1891 | * 0 0xff magic | ||
1892 | * 1 0xff magic | ||
1893 | * 2 0xff magic | ||
1894 | * 3 0xXX 0x50 = SOF, 0x51 = EOF | ||
1895 | * 9 0xXX 0x01 initial frame without data, | ||
1896 | * 0x00 standard frame with image | ||
1897 | * 14 Lo in EOF: length of image data / 8 | ||
1898 | * 15 Hi | ||
1899 | */ | ||
1900 | |||
1901 | if (data[0] == 0xff && data[1] == 0xff && data[2] == 0xff) { | ||
1902 | switch (data[3]) { | ||
1903 | case 0x50: /* start of frame */ | ||
1904 | #define HDRSZ 16 | ||
1905 | data += HDRSZ; | ||
1906 | len -= HDRSZ; | ||
1907 | #undef HDRSZ | ||
1908 | if (data[0] == 0xff || data[1] == 0xd8) | ||
1909 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, | ||
1910 | data, len); | ||
1911 | else | ||
1912 | gspca_dev->last_packet_type = DISCARD_PACKET; | ||
1913 | return; | ||
1914 | case 0x51: /* end of frame */ | ||
1915 | if (data[9] != 0) | ||
1916 | gspca_dev->last_packet_type = DISCARD_PACKET; | ||
1917 | gspca_frame_add(gspca_dev, LAST_PACKET, frame, | ||
1918 | data, 0); | ||
1919 | return; | ||
1920 | } | ||
1921 | } | ||
1922 | |||
1923 | /* intermediate packet */ | ||
1924 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, | ||
1925 | data, len); | ||
1926 | } | ||
1927 | |||
1928 | /* -- management routines -- */ | ||
1929 | |||
1930 | static void setbrightness(struct gspca_dev *gspca_dev) | ||
1931 | { | ||
1932 | struct sd *sd = (struct sd *) gspca_dev; | ||
1933 | int val; | ||
1934 | /* int was_streaming; */ | ||
1935 | |||
1936 | val = sd->brightness; | ||
1937 | PDEBUG(D_CONF, "brightness:%d", val); | ||
1938 | /* was_streaming = gspca_dev->streaming; | ||
1939 | * if (was_streaming) | ||
1940 | * ov51x_stop(sd); */ | ||
1941 | switch (sd->sensor) { | ||
1942 | case SEN_OV8610: | ||
1943 | case SEN_OV7610: | ||
1944 | case SEN_OV76BE: | ||
1945 | case SEN_OV6620: | ||
1946 | case SEN_OV6630: | ||
1947 | case SEN_OV7640: | ||
1948 | i2c_w(sd, OV7610_REG_BRT, val); | ||
1949 | break; | ||
1950 | case SEN_OV7620: | ||
1951 | /* 7620 doesn't like manual changes when in auto mode */ | ||
1952 | /*fixme | ||
1953 | * if (!sd->auto_brt) */ | ||
1954 | i2c_w(sd, OV7610_REG_BRT, val); | ||
1955 | break; | ||
1956 | case SEN_OV7670: | ||
1957 | /*jfm - from windblows | ||
1958 | * i2c_w_mask(sd, OV7670_REG_COM8, 0, OV7670_COM8_AEC); */ | ||
1959 | i2c_w(sd, OV7670_REG_BRIGHT, ov7670_abs_to_sm(val)); | ||
1960 | break; | ||
1961 | } | ||
1962 | /* if (was_streaming) | ||
1963 | * ov51x_restart(sd); */ | ||
1964 | } | ||
1965 | |||
1966 | static void setcontrast(struct gspca_dev *gspca_dev) | ||
1967 | { | ||
1968 | struct sd *sd = (struct sd *) gspca_dev; | ||
1969 | int val; | ||
1970 | /* int was_streaming; */ | ||
1971 | |||
1972 | val = sd->contrast; | ||
1973 | PDEBUG(D_CONF, "contrast:%d", val); | ||
1974 | /* was_streaming = gspca_dev->streaming; | ||
1975 | if (was_streaming) | ||
1976 | ov51x_stop(sd); */ | ||
1977 | switch (sd->sensor) { | ||
1978 | case SEN_OV7610: | ||
1979 | case SEN_OV6620: | ||
1980 | i2c_w(sd, OV7610_REG_CNT, val); | ||
1981 | break; | ||
1982 | case SEN_OV6630: | ||
1983 | i2c_w_mask(sd, OV7610_REG_CNT, val >> 4, 0x0f); | ||
1984 | case SEN_OV8610: { | ||
1985 | static __u8 ctab[] = { | ||
1986 | 0x03, 0x09, 0x0b, 0x0f, 0x53, 0x6f, 0x35, 0x7f | ||
1987 | }; | ||
1988 | |||
1989 | /* Use Y gamma control instead. Bit 0 enables it. */ | ||
1990 | i2c_w(sd, 0x64, ctab[val >> 5]); | ||
1991 | break; | ||
1992 | } | ||
1993 | case SEN_OV7620: { | ||
1994 | static __u8 ctab[] = { | ||
1995 | 0x01, 0x05, 0x09, 0x11, 0x15, 0x35, 0x37, 0x57, | ||
1996 | 0x5b, 0xa5, 0xa7, 0xc7, 0xc9, 0xcf, 0xef, 0xff | ||
1997 | }; | ||
1998 | |||
1999 | /* Use Y gamma control instead. Bit 0 enables it. */ | ||
2000 | i2c_w(sd, 0x64, ctab[val >> 4]); | ||
2001 | break; | ||
2002 | } | ||
2003 | case SEN_OV7640: | ||
2004 | /* Use gain control instead. */ | ||
2005 | i2c_w(sd, OV7610_REG_GAIN, val >> 2); | ||
2006 | break; | ||
2007 | case SEN_OV7670: | ||
2008 | /* check that this isn't just the same as ov7610 */ | ||
2009 | i2c_w(sd, OV7670_REG_CONTRAS, val >> 1); | ||
2010 | break; | ||
2011 | } | ||
2012 | /* if (was_streaming) | ||
2013 | ov51x_restart(sd); */ | ||
2014 | } | ||
2015 | |||
2016 | static void setcolors(struct gspca_dev *gspca_dev) | ||
2017 | { | ||
2018 | struct sd *sd = (struct sd *) gspca_dev; | ||
2019 | int val; | ||
2020 | /* int was_streaming; */ | ||
2021 | |||
2022 | val = sd->colors; | ||
2023 | PDEBUG(D_CONF, "saturation:%d", val); | ||
2024 | /* was_streaming = gspca_dev->streaming; | ||
2025 | if (was_streaming) | ||
2026 | ov51x_stop(sd); */ | ||
2027 | switch (sd->sensor) { | ||
2028 | case SEN_OV8610: | ||
2029 | case SEN_OV7610: | ||
2030 | case SEN_OV76BE: | ||
2031 | case SEN_OV6620: | ||
2032 | case SEN_OV6630: | ||
2033 | i2c_w(sd, OV7610_REG_SAT, val); | ||
2034 | break; | ||
2035 | case SEN_OV7620: | ||
2036 | /* Use UV gamma control instead. Bits 0 & 7 are reserved. */ | ||
2037 | /* rc = ov_i2c_write(sd->dev, 0x62, (val >> 9) & 0x7e); | ||
2038 | if (rc < 0) | ||
2039 | goto out; */ | ||
2040 | i2c_w(sd, OV7610_REG_SAT, val); | ||
2041 | break; | ||
2042 | case SEN_OV7640: | ||
2043 | i2c_w(sd, OV7610_REG_SAT, val & 0xf0); | ||
2044 | break; | ||
2045 | case SEN_OV7670: | ||
2046 | /* supported later once I work out how to do it | ||
2047 | * transparently fail now! */ | ||
2048 | /* set REG_COM13 values for UV sat auto mode */ | ||
2049 | break; | ||
2050 | } | ||
2051 | /* if (was_streaming) | ||
2052 | ov51x_restart(sd); */ | ||
2053 | } | ||
2054 | |||
2055 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | ||
2056 | { | ||
2057 | struct sd *sd = (struct sd *) gspca_dev; | ||
2058 | |||
2059 | sd->brightness = val; | ||
2060 | setbrightness(gspca_dev); | ||
2061 | return 0; | ||
2062 | } | ||
2063 | |||
2064 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
2065 | { | ||
2066 | struct sd *sd = (struct sd *) gspca_dev; | ||
2067 | |||
2068 | *val = sd->brightness; | ||
2069 | return 0; | ||
2070 | } | ||
2071 | |||
2072 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | ||
2073 | { | ||
2074 | struct sd *sd = (struct sd *) gspca_dev; | ||
2075 | |||
2076 | sd->contrast = val; | ||
2077 | setcontrast(gspca_dev); | ||
2078 | return 0; | ||
2079 | } | ||
2080 | |||
2081 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) | ||
2082 | { | ||
2083 | struct sd *sd = (struct sd *) gspca_dev; | ||
2084 | |||
2085 | *val = sd->contrast; | ||
2086 | return 0; | ||
2087 | } | ||
2088 | |||
2089 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) | ||
2090 | { | ||
2091 | struct sd *sd = (struct sd *) gspca_dev; | ||
2092 | |||
2093 | sd->colors = val; | ||
2094 | setcolors(gspca_dev); | ||
2095 | return 0; | ||
2096 | } | ||
2097 | |||
2098 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) | ||
2099 | { | ||
2100 | struct sd *sd = (struct sd *) gspca_dev; | ||
2101 | |||
2102 | *val = sd->colors; | ||
2103 | return 0; | ||
2104 | } | ||
2105 | |||
2106 | /* sub-driver description */ | ||
2107 | static struct sd_desc sd_desc = { | ||
2108 | .name = MODULE_NAME, | ||
2109 | .ctrls = sd_ctrls, | ||
2110 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
2111 | .config = sd_config, | ||
2112 | .open = sd_open, | ||
2113 | .start = sd_start, | ||
2114 | .stopN = sd_stopN, | ||
2115 | .stop0 = sd_stop0, | ||
2116 | .close = sd_close, | ||
2117 | .pkt_scan = sd_pkt_scan, | ||
2118 | }; | ||
2119 | |||
2120 | /* -- module initialisation -- */ | ||
2121 | #define DVNM(name) .driver_info = (kernel_ulong_t) name | ||
2122 | static __devinitdata struct usb_device_id device_table[] = { | ||
2123 | {USB_DEVICE(0x041e, 0x4052), DVNM("Creative Live! VISTA IM")}, | ||
2124 | {USB_DEVICE(0x041e, 0x405f), DVNM("Creative Live! VISTA VF0330")}, | ||
2125 | {USB_DEVICE(0x041e, 0x4060), DVNM("Creative Live! VISTA VF0350")}, | ||
2126 | {USB_DEVICE(0x041e, 0x4061), DVNM("Creative Live! VISTA VF0400")}, | ||
2127 | {USB_DEVICE(0x041e, 0x4064), DVNM("Creative Live! VISTA VF0420")}, | ||
2128 | {USB_DEVICE(0x041e, 0x4068), DVNM("Creative Live! VISTA VF0470")}, | ||
2129 | {USB_DEVICE(0x045e, 0x028c), DVNM("Microsoft xbox cam")}, | ||
2130 | {USB_DEVICE(0x054c, 0x0154), DVNM("Sonny toy4")}, | ||
2131 | {USB_DEVICE(0x054c, 0x0155), DVNM("Sonny toy5")}, | ||
2132 | {USB_DEVICE(0x05a9, 0x0519), DVNM("OmniVision")}, | ||
2133 | {USB_DEVICE(0x05a9, 0x0530), DVNM("OmniVision")}, | ||
2134 | {USB_DEVICE(0x05a9, 0x4519), DVNM("OmniVision")}, | ||
2135 | {USB_DEVICE(0x05a9, 0x8519), DVNM("OmniVision")}, | ||
2136 | {} | ||
2137 | }; | ||
2138 | #undef DVNAME | ||
2139 | MODULE_DEVICE_TABLE(usb, device_table); | ||
2140 | |||
2141 | /* -- device connect -- */ | ||
2142 | static int sd_probe(struct usb_interface *intf, | ||
2143 | const struct usb_device_id *id) | ||
2144 | { | ||
2145 | return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), | ||
2146 | THIS_MODULE); | ||
2147 | } | ||
2148 | |||
2149 | static struct usb_driver sd_driver = { | ||
2150 | .name = MODULE_NAME, | ||
2151 | .id_table = device_table, | ||
2152 | .probe = sd_probe, | ||
2153 | .disconnect = gspca_disconnect, | ||
2154 | }; | ||
2155 | |||
2156 | /* -- module insert / remove -- */ | ||
2157 | static int __init sd_mod_init(void) | ||
2158 | { | ||
2159 | if (usb_register(&sd_driver) < 0) | ||
2160 | return -1; | ||
2161 | PDEBUG(D_PROBE, "v%s registered", version); | ||
2162 | return 0; | ||
2163 | } | ||
2164 | static void __exit sd_mod_exit(void) | ||
2165 | { | ||
2166 | usb_deregister(&sd_driver); | ||
2167 | PDEBUG(D_PROBE, "deregistered"); | ||
2168 | } | ||
2169 | |||
2170 | module_init(sd_mod_init); | ||
2171 | module_exit(sd_mod_exit); | ||
2172 | |||
2173 | module_param(frame_rate, int, 0644); | ||
2174 | MODULE_PARM_DESC(frame_rate, "Frame rate (5, 10, 15, 20 or 30 fps)"); | ||
diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c index 482ef4a6afc0..72a5b89cd59d 100644 --- a/drivers/media/video/gspca/pac207.c +++ b/drivers/media/video/gspca/pac207.c | |||
@@ -27,8 +27,8 @@ | |||
27 | 27 | ||
28 | #include "gspca.h" | 28 | #include "gspca.h" |
29 | 29 | ||
30 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(0, 2, 15) | 30 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) |
31 | static const char version[] = "0.2.15"; | 31 | static const char version[] = "2.1.0"; |
32 | 32 | ||
33 | MODULE_AUTHOR("Hans de Goede <j.w.r.degoede@hhs.nl>"); | 33 | MODULE_AUTHOR("Hans de Goede <j.w.r.degoede@hhs.nl>"); |
34 | MODULE_DESCRIPTION("Pixart PAC207"); | 34 | MODULE_DESCRIPTION("Pixart PAC207"); |
@@ -297,7 +297,6 @@ static int sd_open(struct gspca_dev *gspca_dev) | |||
297 | struct sd *sd = (struct sd *) gspca_dev; | 297 | struct sd *sd = (struct sd *) gspca_dev; |
298 | 298 | ||
299 | sd->autogain = 1; | 299 | sd->autogain = 1; |
300 | |||
301 | return 0; | 300 | return 0; |
302 | } | 301 | } |
303 | 302 | ||
@@ -338,7 +337,7 @@ static void sd_start(struct gspca_dev *gspca_dev) | |||
338 | 337 | ||
339 | pac207_write_reg(gspca_dev, 0x13, 0x01); /* Bit 0, auto clear */ | 338 | pac207_write_reg(gspca_dev, 0x13, 0x01); /* Bit 0, auto clear */ |
340 | pac207_write_reg(gspca_dev, 0x1c, 0x01); /* not documented */ | 339 | pac207_write_reg(gspca_dev, 0x1c, 0x01); /* not documented */ |
341 | udelay(1000); /* taken from gspca */ | 340 | msleep(10); |
342 | pac207_write_reg(gspca_dev, 0x40, 0x01); /* Start ISO pipe */ | 341 | pac207_write_reg(gspca_dev, 0x40, 0x01); /* Start ISO pipe */ |
343 | 342 | ||
344 | sd->sof_read = 0; | 343 | sd->sof_read = 0; |
@@ -743,8 +742,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
743 | PDEBUG(D_STREAM, "Incomplete frame"); | 742 | PDEBUG(D_STREAM, "Incomplete frame"); |
744 | } | 743 | } |
745 | pac207_decode_frame_init(gspca_dev); | 744 | pac207_decode_frame_init(gspca_dev); |
746 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, NULL, | 745 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, NULL, 0); |
747 | 0); | ||
748 | len -= sof - data; | 746 | len -= sof - data; |
749 | data = sof; | 747 | data = sof; |
750 | } | 748 | } |
diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c new file mode 100644 index 000000000000..8f51976db995 --- /dev/null +++ b/drivers/media/video/gspca/pac7311.c | |||
@@ -0,0 +1,754 @@ | |||
1 | /* | ||
2 | * Pixart PAC7311 library | ||
3 | * Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li | ||
4 | * | ||
5 | * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | #define MODULE_NAME "pac7311" | ||
23 | |||
24 | #include "gspca.h" | ||
25 | |||
26 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) | ||
27 | static const char version[] = "2.1.0"; | ||
28 | |||
29 | MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li"); | ||
30 | MODULE_DESCRIPTION("Pixart PAC7311"); | ||
31 | MODULE_LICENSE("GPL"); | ||
32 | |||
33 | /* specific webcam descriptor */ | ||
34 | struct sd { | ||
35 | struct gspca_dev gspca_dev; /* !! must be the first item */ | ||
36 | |||
37 | int avg_lum; | ||
38 | |||
39 | unsigned char brightness; | ||
40 | #define BRIGHTNESS_MAX 0x20 | ||
41 | unsigned char contrast; | ||
42 | unsigned char colors; | ||
43 | unsigned char autogain; | ||
44 | |||
45 | char ffseq; | ||
46 | signed char ag_cnt; | ||
47 | #define AG_CNT_START 13 | ||
48 | }; | ||
49 | |||
50 | /* V4L2 controls supported by the driver */ | ||
51 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
52 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
53 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | ||
54 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | ||
55 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); | ||
56 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); | ||
57 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); | ||
58 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); | ||
59 | |||
60 | static struct ctrl sd_ctrls[] = { | ||
61 | #define SD_BRIGHTNESS 0 | ||
62 | { | ||
63 | { | ||
64 | .id = V4L2_CID_BRIGHTNESS, | ||
65 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
66 | .name = "Brightness", | ||
67 | .minimum = 0, | ||
68 | .maximum = BRIGHTNESS_MAX, | ||
69 | .step = 1, | ||
70 | .default_value = 0x10, | ||
71 | }, | ||
72 | .set = sd_setbrightness, | ||
73 | .get = sd_getbrightness, | ||
74 | }, | ||
75 | #define SD_CONTRAST 1 | ||
76 | { | ||
77 | { | ||
78 | .id = V4L2_CID_CONTRAST, | ||
79 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
80 | .name = "Contrast", | ||
81 | .minimum = 0, | ||
82 | .maximum = 255, | ||
83 | .step = 1, | ||
84 | .default_value = 127, | ||
85 | }, | ||
86 | .set = sd_setcontrast, | ||
87 | .get = sd_getcontrast, | ||
88 | }, | ||
89 | #define SD_COLOR 2 | ||
90 | { | ||
91 | { | ||
92 | .id = V4L2_CID_SATURATION, | ||
93 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
94 | .name = "Color", | ||
95 | .minimum = 0, | ||
96 | .maximum = 255, | ||
97 | .step = 1, | ||
98 | .default_value = 127, | ||
99 | }, | ||
100 | .set = sd_setcolors, | ||
101 | .get = sd_getcolors, | ||
102 | }, | ||
103 | #define SD_AUTOGAIN 3 | ||
104 | { | ||
105 | { | ||
106 | .id = V4L2_CID_AUTOGAIN, | ||
107 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
108 | .name = "Auto Gain", | ||
109 | .minimum = 0, | ||
110 | .maximum = 1, | ||
111 | .step = 1, | ||
112 | .default_value = 1, | ||
113 | }, | ||
114 | .set = sd_setautogain, | ||
115 | .get = sd_getautogain, | ||
116 | }, | ||
117 | }; | ||
118 | |||
119 | static struct cam_mode vga_mode[] = { | ||
120 | {V4L2_PIX_FMT_JPEG, 160, 120, 2}, | ||
121 | {V4L2_PIX_FMT_JPEG, 320, 240, 1}, | ||
122 | {V4L2_PIX_FMT_JPEG, 640, 480, 0}, | ||
123 | }; | ||
124 | |||
125 | #define PAC7311_JPEG_HEADER_SIZE (sizeof pac7311_jpeg_header) /* (594) */ | ||
126 | |||
127 | const unsigned char pac7311_jpeg_header[] = { | ||
128 | 0xff, 0xd8, | ||
129 | 0xff, 0xe0, 0x00, 0x03, 0x20, | ||
130 | 0xff, 0xc0, 0x00, 0x11, 0x08, | ||
131 | 0x01, 0xe0, /* 12: height */ | ||
132 | 0x02, 0x80, /* 14: width */ | ||
133 | 0x03, /* 16 */ | ||
134 | 0x01, 0x21, 0x00, | ||
135 | 0x02, 0x11, 0x01, | ||
136 | 0x03, 0x11, 0x01, | ||
137 | 0xff, 0xdb, 0x00, 0x84, | ||
138 | 0x00, 0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, 0x0d, | ||
139 | 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28, 0x1a, 0x18, 0x16, | ||
140 | 0x16, 0x18, 0x31, 0x23, 0x25, 0x1d, 0x28, 0x3a, 0x33, 0x3d, | ||
141 | 0x3c, 0x39, 0x33, 0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, | ||
142 | 0x44, 0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0x51, 0x57, 0x5f, | ||
143 | 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71, 0x79, 0x70, 0x64, | ||
144 | 0x78, 0x5c, 0x65, 0x67, 0x63, 0x01, 0x11, 0x12, 0x12, 0x18, | ||
145 | 0x15, 0x18, 0x2f, 0x1a, 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, | ||
146 | 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, | ||
147 | 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, | ||
148 | 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, | ||
149 | 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, | ||
150 | 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, | ||
151 | 0xff, 0xc4, 0x01, 0xa2, 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, | ||
152 | 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
153 | 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, | ||
154 | 0x09, 0x0a, 0x0b, 0x10, 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, | ||
155 | 0x04, 0x03, 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d, | ||
156 | 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, | ||
157 | 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, | ||
158 | 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, | ||
159 | 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, | ||
160 | 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, | ||
161 | 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, | ||
162 | 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, | ||
163 | 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, | ||
164 | 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, | ||
165 | 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, | ||
166 | 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, | ||
167 | 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, | ||
168 | 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, | ||
169 | 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, | ||
170 | 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, | ||
171 | 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, | ||
172 | 0xf9, 0xfa, 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, | ||
173 | 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
174 | 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, | ||
175 | 0x0b, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, | ||
176 | 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77, 0x00, 0x01, | ||
177 | 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, | ||
178 | 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, | ||
179 | 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, | ||
180 | 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, | ||
181 | 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, | ||
182 | 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, | ||
183 | 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, | ||
184 | 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, | ||
185 | 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, | ||
186 | 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, | ||
187 | 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, | ||
188 | 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, | ||
189 | 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, | ||
190 | 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, | ||
191 | 0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, | ||
192 | 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, | ||
193 | 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, | ||
194 | 0x11, 0x00, 0x3f, 0x00 | ||
195 | }; | ||
196 | |||
197 | static void reg_w(struct usb_device *dev, | ||
198 | __u16 req, | ||
199 | __u16 value, | ||
200 | __u16 index, | ||
201 | __u8 *buffer, __u16 length) | ||
202 | { | ||
203 | usb_control_msg(dev, | ||
204 | usb_sndctrlpipe(dev, 0), | ||
205 | req, | ||
206 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
207 | value, index, buffer, length, | ||
208 | 500); | ||
209 | } | ||
210 | |||
211 | static void pac7311_reg_read(struct usb_device *dev, __u16 index, | ||
212 | __u8 *buffer) | ||
213 | { | ||
214 | usb_control_msg(dev, | ||
215 | usb_rcvctrlpipe(dev, 0), | ||
216 | 0, /* request */ | ||
217 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
218 | 0, /* value */ | ||
219 | index, buffer, 1, | ||
220 | 500); | ||
221 | } | ||
222 | |||
223 | static void pac7311_reg_write(struct usb_device *dev, | ||
224 | __u16 index, | ||
225 | __u8 value) | ||
226 | { | ||
227 | __u8 buf; | ||
228 | |||
229 | buf = value; | ||
230 | reg_w(dev, 0x00, value, index, &buf, 1); | ||
231 | } | ||
232 | |||
233 | /* this function is called at probe time */ | ||
234 | static int sd_config(struct gspca_dev *gspca_dev, | ||
235 | const struct usb_device_id *id) | ||
236 | { | ||
237 | struct sd *sd = (struct sd *) gspca_dev; | ||
238 | struct usb_device *dev = gspca_dev->dev; | ||
239 | struct cam *cam; | ||
240 | |||
241 | PDEBUG(D_CONF, "Find Sensor PAC7311"); | ||
242 | pac7311_reg_write(dev, 0x78, 0x40); /* Bit_0=start stream, Bit_7=LED */ | ||
243 | pac7311_reg_write(dev, 0x78, 0x40); /* Bit_0=start stream, Bit_7=LED */ | ||
244 | pac7311_reg_write(dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */ | ||
245 | pac7311_reg_write(dev, 0xff, 0x04); | ||
246 | pac7311_reg_write(dev, 0x27, 0x80); | ||
247 | pac7311_reg_write(dev, 0x28, 0xca); | ||
248 | pac7311_reg_write(dev, 0x29, 0x53); | ||
249 | pac7311_reg_write(dev, 0x2a, 0x0e); | ||
250 | pac7311_reg_write(dev, 0xff, 0x01); | ||
251 | pac7311_reg_write(dev, 0x3e, 0x20); | ||
252 | |||
253 | cam = &gspca_dev->cam; | ||
254 | cam->dev_name = (char *) id->driver_info; | ||
255 | cam->epaddr = 0x05; | ||
256 | cam->cam_mode = vga_mode; | ||
257 | cam->nmodes = ARRAY_SIZE(vga_mode); | ||
258 | |||
259 | sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; | ||
260 | sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; | ||
261 | sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; | ||
262 | sd->autogain = sd_ctrls[SD_AUTOGAIN].qctrl.default_value; | ||
263 | return 0; | ||
264 | } | ||
265 | |||
266 | static void setbrightness(struct gspca_dev *gspca_dev) | ||
267 | { | ||
268 | struct sd *sd = (struct sd *) gspca_dev; | ||
269 | int brightness; | ||
270 | |||
271 | /*jfm: inverted?*/ | ||
272 | brightness = BRIGHTNESS_MAX - sd->brightness; | ||
273 | pac7311_reg_write(gspca_dev->dev, 0xff, 0x04); | ||
274 | /* pac7311_reg_write(gspca_dev->dev, 0x0e, 0x00); */ | ||
275 | pac7311_reg_write(gspca_dev->dev, 0x0f, brightness); | ||
276 | /* load registers to sensor (Bit 0, auto clear) */ | ||
277 | pac7311_reg_write(gspca_dev->dev, 0x11, 0x01); | ||
278 | PDEBUG(D_CONF|D_STREAM, "brightness: %i", brightness); | ||
279 | } | ||
280 | |||
281 | static void setcontrast(struct gspca_dev *gspca_dev) | ||
282 | { | ||
283 | struct sd *sd = (struct sd *) gspca_dev; | ||
284 | |||
285 | pac7311_reg_write(gspca_dev->dev, 0xff, 0x01); | ||
286 | pac7311_reg_write(gspca_dev->dev, 0x80, sd->contrast); | ||
287 | /* load registers to sensor (Bit 0, auto clear) */ | ||
288 | pac7311_reg_write(gspca_dev->dev, 0x11, 0x01); | ||
289 | PDEBUG(D_CONF|D_STREAM, "contrast: %i", sd->contrast); | ||
290 | } | ||
291 | |||
292 | static void setcolors(struct gspca_dev *gspca_dev) | ||
293 | { | ||
294 | struct sd *sd = (struct sd *) gspca_dev; | ||
295 | |||
296 | pac7311_reg_write(gspca_dev->dev, 0xff, 0x01); | ||
297 | pac7311_reg_write(gspca_dev->dev, 0x10, sd->colors); | ||
298 | /* load registers to sensor (Bit 0, auto clear) */ | ||
299 | pac7311_reg_write(gspca_dev->dev, 0x11, 0x01); | ||
300 | PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors); | ||
301 | } | ||
302 | |||
303 | /* this function is called at open time */ | ||
304 | static int sd_open(struct gspca_dev *gspca_dev) | ||
305 | { | ||
306 | pac7311_reg_write(gspca_dev->dev, 0x78, 0x00); /* Turn on LED */ | ||
307 | return 0; | ||
308 | } | ||
309 | |||
310 | static void sd_start(struct gspca_dev *gspca_dev) | ||
311 | { | ||
312 | struct usb_device *dev = gspca_dev->dev; | ||
313 | struct sd *sd = (struct sd *) gspca_dev; | ||
314 | |||
315 | pac7311_reg_write(dev, 0xff, 0x01); | ||
316 | reg_w(dev, 0x01, 0, 0x0002, "\x48\x0a\x40\x08\x00\x00\x08\x00", 8); | ||
317 | reg_w(dev, 0x01, 0, 0x000a, "\x06\xff\x11\xff\x5a\x30\x90\x4c", 8); | ||
318 | reg_w(dev, 0x01, 0, 0x0012, "\x00\x07\x00\x0a\x10\x00\xa0\x10", 8); | ||
319 | reg_w(dev, 0x01, 0, 0x001a, "\x02\x00\x00\x00\x00\x0b\x01\x00", 8); | ||
320 | reg_w(dev, 0x01, 0, 0x0022, "\x00\x00\x00\x00\x00\x00\x00\x00", 8); | ||
321 | reg_w(dev, 0x01, 0, 0x002a, "\x00\x00\x00", 3); | ||
322 | reg_w(dev, 0x01, 0, 0x003e, "\x00\x00\x78\x52\x4a\x52\x78\x6e", 8); | ||
323 | reg_w(dev, 0x01, 0, 0x0046, "\x48\x46\x48\x6e\x5f\x49\x42\x49", 8); | ||
324 | reg_w(dev, 0x01, 0, 0x004e, "\x5f\x5f\x49\x42\x49\x5f\x6e\x48", 8); | ||
325 | reg_w(dev, 0x01, 0, 0x0056, "\x46\x48\x6e\x78\x52\x4a\x52\x78", 8); | ||
326 | reg_w(dev, 0x01, 0, 0x005e, "\x00\x00\x09\x1b\x34\x49\x5c\x9b", 8); | ||
327 | reg_w(dev, 0x01, 0, 0x0066, "\xd0\xff", 2); | ||
328 | reg_w(dev, 0x01, 0, 0x0078, "\x44\x00\xf2\x01\x01\x80", 6); | ||
329 | reg_w(dev, 0x01, 0, 0x007f, "\x2a\x1c\x00\xc8\x02\x58\x03\x84", 8); | ||
330 | reg_w(dev, 0x01, 0, 0x0087, "\x12\x00\x1a\x04\x08\x0c\x10\x14", 8); | ||
331 | reg_w(dev, 0x01, 0, 0x008f, "\x18\x20", 2); | ||
332 | reg_w(dev, 0x01, 0, 0x0096, "\x01\x08\x04", 3); | ||
333 | reg_w(dev, 0x01, 0, 0x00a0, "\x44\x44\x44\x04", 4); | ||
334 | reg_w(dev, 0x01, 0, 0x00f0, "\x01\x00\x00\x00\x22\x00\x20\x00", 8); | ||
335 | reg_w(dev, 0x01, 0, 0x00f8, "\x3f\x00\x0a\x01\x00", 5); | ||
336 | |||
337 | pac7311_reg_write(dev, 0xff, 0x04); | ||
338 | pac7311_reg_write(dev, 0x02, 0x04); | ||
339 | pac7311_reg_write(dev, 0x03, 0x54); | ||
340 | pac7311_reg_write(dev, 0x04, 0x07); | ||
341 | pac7311_reg_write(dev, 0x05, 0x2b); | ||
342 | pac7311_reg_write(dev, 0x06, 0x09); | ||
343 | pac7311_reg_write(dev, 0x07, 0x0f); | ||
344 | pac7311_reg_write(dev, 0x08, 0x09); | ||
345 | pac7311_reg_write(dev, 0x09, 0x00); | ||
346 | pac7311_reg_write(dev, 0x0c, 0x07); | ||
347 | pac7311_reg_write(dev, 0x0d, 0x00); | ||
348 | pac7311_reg_write(dev, 0x0e, 0x00); | ||
349 | pac7311_reg_write(dev, 0x0f, 0x62); | ||
350 | pac7311_reg_write(dev, 0x10, 0x08); | ||
351 | pac7311_reg_write(dev, 0x12, 0x07); | ||
352 | pac7311_reg_write(dev, 0x13, 0x00); | ||
353 | pac7311_reg_write(dev, 0x14, 0x00); | ||
354 | pac7311_reg_write(dev, 0x15, 0x00); | ||
355 | pac7311_reg_write(dev, 0x16, 0x00); | ||
356 | pac7311_reg_write(dev, 0x17, 0x00); | ||
357 | pac7311_reg_write(dev, 0x18, 0x00); | ||
358 | pac7311_reg_write(dev, 0x19, 0x00); | ||
359 | pac7311_reg_write(dev, 0x1a, 0x00); | ||
360 | pac7311_reg_write(dev, 0x1b, 0x03); | ||
361 | pac7311_reg_write(dev, 0x1c, 0xa0); | ||
362 | pac7311_reg_write(dev, 0x1d, 0x01); | ||
363 | pac7311_reg_write(dev, 0x1e, 0xf4); | ||
364 | pac7311_reg_write(dev, 0x21, 0x00); | ||
365 | pac7311_reg_write(dev, 0x22, 0x08); | ||
366 | pac7311_reg_write(dev, 0x24, 0x03); | ||
367 | pac7311_reg_write(dev, 0x26, 0x00); | ||
368 | pac7311_reg_write(dev, 0x27, 0x01); | ||
369 | pac7311_reg_write(dev, 0x28, 0xca); | ||
370 | pac7311_reg_write(dev, 0x29, 0x10); | ||
371 | pac7311_reg_write(dev, 0x2a, 0x06); | ||
372 | pac7311_reg_write(dev, 0x2b, 0x78); | ||
373 | pac7311_reg_write(dev, 0x2c, 0x00); | ||
374 | pac7311_reg_write(dev, 0x2d, 0x00); | ||
375 | pac7311_reg_write(dev, 0x2e, 0x00); | ||
376 | pac7311_reg_write(dev, 0x2f, 0x00); | ||
377 | pac7311_reg_write(dev, 0x30, 0x23); | ||
378 | pac7311_reg_write(dev, 0x31, 0x28); | ||
379 | pac7311_reg_write(dev, 0x32, 0x04); | ||
380 | pac7311_reg_write(dev, 0x33, 0x11); | ||
381 | pac7311_reg_write(dev, 0x34, 0x00); | ||
382 | pac7311_reg_write(dev, 0x35, 0x00); | ||
383 | pac7311_reg_write(dev, 0x11, 0x01); | ||
384 | setcontrast(gspca_dev); | ||
385 | setbrightness(gspca_dev); | ||
386 | setcolors(gspca_dev); | ||
387 | |||
388 | /* set correct resolution */ | ||
389 | switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode) { | ||
390 | case 2: /* 160x120 */ | ||
391 | pac7311_reg_write(dev, 0xff, 0x04); | ||
392 | pac7311_reg_write(dev, 0x02, 0x03); | ||
393 | pac7311_reg_write(dev, 0xff, 0x01); | ||
394 | pac7311_reg_write(dev, 0x08, 0x09); | ||
395 | pac7311_reg_write(dev, 0x17, 0x20); | ||
396 | pac7311_reg_write(dev, 0x1b, 0x00); | ||
397 | /* pac7311_reg_write(dev, 0x80, 0x69); */ | ||
398 | pac7311_reg_write(dev, 0x87, 0x10); | ||
399 | break; | ||
400 | case 1: /* 320x240 */ | ||
401 | pac7311_reg_write(dev, 0xff, 0x04); | ||
402 | pac7311_reg_write(dev, 0x02, 0x03); | ||
403 | pac7311_reg_write(dev, 0xff, 0x01); | ||
404 | pac7311_reg_write(dev, 0x08, 0x09); | ||
405 | pac7311_reg_write(dev, 0x17, 0x30); | ||
406 | /* pac7311_reg_write(dev, 0x80, 0x3f); */ | ||
407 | pac7311_reg_write(dev, 0x87, 0x11); | ||
408 | break; | ||
409 | case 0: /* 640x480 */ | ||
410 | pac7311_reg_write(dev, 0xff, 0x04); | ||
411 | pac7311_reg_write(dev, 0x02, 0x03); | ||
412 | pac7311_reg_write(dev, 0xff, 0x01); | ||
413 | pac7311_reg_write(dev, 0x08, 0x08); | ||
414 | pac7311_reg_write(dev, 0x17, 0x00); | ||
415 | /* pac7311_reg_write(dev, 0x80, 0x1c); */ | ||
416 | pac7311_reg_write(dev, 0x87, 0x12); | ||
417 | break; | ||
418 | } | ||
419 | |||
420 | /* start stream */ | ||
421 | pac7311_reg_write(dev, 0xff, 0x01); | ||
422 | pac7311_reg_write(dev, 0x78, 0x04); | ||
423 | pac7311_reg_write(dev, 0x78, 0x05); | ||
424 | |||
425 | if (sd->autogain) { | ||
426 | sd->ag_cnt = AG_CNT_START; | ||
427 | sd->avg_lum = 0; | ||
428 | } else { | ||
429 | sd->ag_cnt = -1; | ||
430 | } | ||
431 | } | ||
432 | |||
433 | static void sd_stopN(struct gspca_dev *gspca_dev) | ||
434 | { | ||
435 | struct usb_device *dev = gspca_dev->dev; | ||
436 | |||
437 | pac7311_reg_write(dev, 0xff, 0x04); | ||
438 | pac7311_reg_write(dev, 0x27, 0x80); | ||
439 | pac7311_reg_write(dev, 0x28, 0xca); | ||
440 | pac7311_reg_write(dev, 0x29, 0x53); | ||
441 | pac7311_reg_write(dev, 0x2a, 0x0e); | ||
442 | pac7311_reg_write(dev, 0xff, 0x01); | ||
443 | pac7311_reg_write(dev, 0x3e, 0x20); | ||
444 | pac7311_reg_write(dev, 0x78, 0x04); /* Bit_0=start stream, Bit_7=LED */ | ||
445 | pac7311_reg_write(dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */ | ||
446 | pac7311_reg_write(dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */ | ||
447 | } | ||
448 | |||
449 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
450 | { | ||
451 | } | ||
452 | |||
453 | /* this function is called at close time */ | ||
454 | static void sd_close(struct gspca_dev *gspca_dev) | ||
455 | { | ||
456 | struct usb_device *dev = gspca_dev->dev; | ||
457 | |||
458 | pac7311_reg_write(dev, 0xff, 0x04); | ||
459 | pac7311_reg_write(dev, 0x27, 0x80); | ||
460 | pac7311_reg_write(dev, 0x28, 0xca); | ||
461 | pac7311_reg_write(dev, 0x29, 0x53); | ||
462 | pac7311_reg_write(dev, 0x2a, 0x0e); | ||
463 | pac7311_reg_write(dev, 0xff, 0x01); | ||
464 | pac7311_reg_write(dev, 0x3e, 0x20); | ||
465 | pac7311_reg_write(dev, 0x78, 0x04); /* Bit_0=start stream, Bit_7=LED */ | ||
466 | pac7311_reg_write(dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */ | ||
467 | pac7311_reg_write(dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */ | ||
468 | } | ||
469 | |||
470 | static void setautogain(struct gspca_dev *gspca_dev, int luma) | ||
471 | { | ||
472 | int luma_mean = 128; | ||
473 | int luma_delta = 20; | ||
474 | __u8 spring = 5; | ||
475 | __u8 Pxclk; | ||
476 | int Gbright; | ||
477 | |||
478 | pac7311_reg_read(gspca_dev->dev, 0x02, &Pxclk); | ||
479 | Gbright = Pxclk; | ||
480 | PDEBUG(D_FRAM, "luma mean %d", luma); | ||
481 | if (luma < luma_mean - luma_delta || | ||
482 | luma > luma_mean + luma_delta) { | ||
483 | Gbright += (luma_mean - luma) >> spring; | ||
484 | if (Gbright > 0x1a) | ||
485 | Gbright = 0x1a; | ||
486 | else if (Gbright < 4) | ||
487 | Gbright = 4; | ||
488 | PDEBUG(D_FRAM, "gbright %d", Gbright); | ||
489 | pac7311_reg_write(gspca_dev->dev, 0xff, 0x04); | ||
490 | pac7311_reg_write(gspca_dev->dev, 0x0f, Gbright); | ||
491 | /* load registers to sensor (Bit 0, auto clear) */ | ||
492 | pac7311_reg_write(gspca_dev->dev, 0x11, 0x01); | ||
493 | } | ||
494 | } | ||
495 | |||
496 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | ||
497 | struct gspca_frame *frame, /* target */ | ||
498 | unsigned char *data, /* isoc packet */ | ||
499 | int len) /* iso packet length */ | ||
500 | { | ||
501 | struct sd *sd = (struct sd *) gspca_dev; | ||
502 | unsigned char tmpbuf[4]; | ||
503 | int i, p, ffseq; | ||
504 | |||
505 | /* if (len < 5) { */ | ||
506 | if (len < 6) { | ||
507 | /* gspca_dev->last_packet_type = DISCARD_PACKET; */ | ||
508 | return; | ||
509 | } | ||
510 | |||
511 | ffseq = sd->ffseq; | ||
512 | |||
513 | for (p = 0; p < len - 6; p++) { | ||
514 | if ((data[0 + p] == 0xff) | ||
515 | && (data[1 + p] == 0xff) | ||
516 | && (data[2 + p] == 0x00) | ||
517 | && (data[3 + p] == 0xff) | ||
518 | && (data[4 + p] == 0x96)) { | ||
519 | |||
520 | /* start of frame */ | ||
521 | if (sd->ag_cnt >= 0 && p > 28) { | ||
522 | sd->avg_lum += data[p - 23]; | ||
523 | if (--sd->ag_cnt < 0) { | ||
524 | sd->ag_cnt = AG_CNT_START; | ||
525 | setautogain(gspca_dev, | ||
526 | sd->avg_lum / AG_CNT_START); | ||
527 | sd->avg_lum = 0; | ||
528 | } | ||
529 | } | ||
530 | |||
531 | /* copy the end of data to the current frame */ | ||
532 | frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, | ||
533 | data, p); | ||
534 | |||
535 | /* put the JPEG header in the new frame */ | ||
536 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, | ||
537 | (unsigned char *) pac7311_jpeg_header, | ||
538 | 12); | ||
539 | tmpbuf[0] = gspca_dev->height >> 8; | ||
540 | tmpbuf[1] = gspca_dev->height & 0xff; | ||
541 | tmpbuf[2] = gspca_dev->width >> 8; | ||
542 | tmpbuf[3] = gspca_dev->width & 0xff; | ||
543 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, | ||
544 | tmpbuf, 4); | ||
545 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, | ||
546 | (unsigned char *) &pac7311_jpeg_header[16], | ||
547 | PAC7311_JPEG_HEADER_SIZE - 16); | ||
548 | |||
549 | data += p + 7; | ||
550 | len -= p + 7; | ||
551 | ffseq = 0; | ||
552 | break; | ||
553 | } | ||
554 | } | ||
555 | |||
556 | /* remove the 'ff ff ff xx' sequences */ | ||
557 | switch (ffseq) { | ||
558 | case 3: | ||
559 | data += 1; | ||
560 | len -= 1; | ||
561 | break; | ||
562 | case 2: | ||
563 | if (data[0] == 0xff) { | ||
564 | data += 2; | ||
565 | len -= 2; | ||
566 | frame->data_end -= 2; | ||
567 | } | ||
568 | break; | ||
569 | case 1: | ||
570 | if (data[0] == 0xff | ||
571 | && data[1] == 0xff) { | ||
572 | data += 3; | ||
573 | len -= 3; | ||
574 | frame->data_end -= 1; | ||
575 | } | ||
576 | break; | ||
577 | } | ||
578 | for (i = 0; i < len - 4; i++) { | ||
579 | if (data[i] == 0xff | ||
580 | && data[i + 1] == 0xff | ||
581 | && data[i + 2] == 0xff) { | ||
582 | memmove(&data[i], &data[i + 4], len - i - 4); | ||
583 | len -= 4; | ||
584 | } | ||
585 | } | ||
586 | ffseq = 0; | ||
587 | if (data[len - 4] == 0xff) { | ||
588 | if (data[len - 3] == 0xff | ||
589 | && data[len - 2] == 0xff) { | ||
590 | len -= 4; | ||
591 | } | ||
592 | } else if (data[len - 3] == 0xff) { | ||
593 | if (data[len - 2] == 0xff | ||
594 | && data[len - 1] == 0xff) | ||
595 | ffseq = 3; | ||
596 | } else if (data[len - 2] == 0xff) { | ||
597 | if (data[len - 1] == 0xff) | ||
598 | ffseq = 2; | ||
599 | } else if (data[len - 1] == 0xff) | ||
600 | ffseq = 1; | ||
601 | sd->ffseq = ffseq; | ||
602 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); | ||
603 | } | ||
604 | |||
605 | static void getbrightness(struct gspca_dev *gspca_dev) | ||
606 | { | ||
607 | /* __u8 brightness = 0; | ||
608 | |||
609 | pac7311_reg_read(gspca_dev->dev, 0x0008, &brightness); | ||
610 | spca50x->brightness = brightness; | ||
611 | return spca50x->brightness; */ | ||
612 | /* PDEBUG(D_CONF, "Called pac7311_getbrightness: Not implemented yet"); */ | ||
613 | } | ||
614 | |||
615 | |||
616 | |||
617 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | ||
618 | { | ||
619 | struct sd *sd = (struct sd *) gspca_dev; | ||
620 | |||
621 | sd->brightness = val; | ||
622 | if (gspca_dev->streaming) | ||
623 | setbrightness(gspca_dev); | ||
624 | return 0; | ||
625 | } | ||
626 | |||
627 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
628 | { | ||
629 | struct sd *sd = (struct sd *) gspca_dev; | ||
630 | |||
631 | getbrightness(gspca_dev); | ||
632 | *val = sd->brightness; | ||
633 | return 0; | ||
634 | } | ||
635 | |||
636 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | ||
637 | { | ||
638 | struct sd *sd = (struct sd *) gspca_dev; | ||
639 | |||
640 | sd->contrast = val; | ||
641 | if (gspca_dev->streaming) | ||
642 | setcontrast(gspca_dev); | ||
643 | return 0; | ||
644 | } | ||
645 | |||
646 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) | ||
647 | { | ||
648 | struct sd *sd = (struct sd *) gspca_dev; | ||
649 | |||
650 | /* getcontrast(gspca_dev); */ | ||
651 | *val = sd->contrast; | ||
652 | return 0; | ||
653 | } | ||
654 | |||
655 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) | ||
656 | { | ||
657 | struct sd *sd = (struct sd *) gspca_dev; | ||
658 | |||
659 | sd->colors = val; | ||
660 | if (gspca_dev->streaming) | ||
661 | setcolors(gspca_dev); | ||
662 | return 0; | ||
663 | } | ||
664 | |||
665 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) | ||
666 | { | ||
667 | struct sd *sd = (struct sd *) gspca_dev; | ||
668 | |||
669 | /* getcolors(gspca_dev); */ | ||
670 | *val = sd->colors; | ||
671 | return 0; | ||
672 | } | ||
673 | |||
674 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) | ||
675 | { | ||
676 | struct sd *sd = (struct sd *) gspca_dev; | ||
677 | |||
678 | sd->autogain = val; | ||
679 | if (val) { | ||
680 | sd->ag_cnt = AG_CNT_START; | ||
681 | sd->avg_lum = 0; | ||
682 | } else { | ||
683 | sd->ag_cnt = -1; | ||
684 | } | ||
685 | return 0; | ||
686 | } | ||
687 | |||
688 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) | ||
689 | { | ||
690 | struct sd *sd = (struct sd *) gspca_dev; | ||
691 | |||
692 | *val = sd->autogain; | ||
693 | return 0; | ||
694 | } | ||
695 | |||
696 | /* sub-driver description */ | ||
697 | static struct sd_desc sd_desc = { | ||
698 | .name = MODULE_NAME, | ||
699 | .ctrls = sd_ctrls, | ||
700 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
701 | .config = sd_config, | ||
702 | .open = sd_open, | ||
703 | .start = sd_start, | ||
704 | .stopN = sd_stopN, | ||
705 | .stop0 = sd_stop0, | ||
706 | .close = sd_close, | ||
707 | .pkt_scan = sd_pkt_scan, | ||
708 | }; | ||
709 | |||
710 | /* -- module initialisation -- */ | ||
711 | #define DVNM(name) .driver_info = (kernel_ulong_t) name | ||
712 | static __devinitdata struct usb_device_id device_table[] = { | ||
713 | {USB_DEVICE(0x093a, 0x2600), DVNM("Typhoon")}, | ||
714 | {USB_DEVICE(0x093a, 0x2601), DVNM("Philips SPC610NC")}, | ||
715 | {USB_DEVICE(0x093a, 0x2603), DVNM("PAC7312")}, | ||
716 | {USB_DEVICE(0x093a, 0x2608), DVNM("Trust WB-3300p")}, | ||
717 | {USB_DEVICE(0x093a, 0x260e), DVNM("Gigaware VGA PC Camera, Trust WB-3350p, SIGMA cam 2350")}, | ||
718 | {USB_DEVICE(0x093a, 0x260f), DVNM("SnakeCam")}, | ||
719 | {USB_DEVICE(0x093a, 0x2621), DVNM("PAC731x")}, | ||
720 | {} | ||
721 | }; | ||
722 | MODULE_DEVICE_TABLE(usb, device_table); | ||
723 | |||
724 | /* -- device connect -- */ | ||
725 | static int sd_probe(struct usb_interface *intf, | ||
726 | const struct usb_device_id *id) | ||
727 | { | ||
728 | return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), | ||
729 | THIS_MODULE); | ||
730 | } | ||
731 | |||
732 | static struct usb_driver sd_driver = { | ||
733 | .name = MODULE_NAME, | ||
734 | .id_table = device_table, | ||
735 | .probe = sd_probe, | ||
736 | .disconnect = gspca_disconnect, | ||
737 | }; | ||
738 | |||
739 | /* -- module insert / remove -- */ | ||
740 | static int __init sd_mod_init(void) | ||
741 | { | ||
742 | if (usb_register(&sd_driver) < 0) | ||
743 | return -1; | ||
744 | PDEBUG(D_PROBE, "v%s registered", version); | ||
745 | return 0; | ||
746 | } | ||
747 | static void __exit sd_mod_exit(void) | ||
748 | { | ||
749 | usb_deregister(&sd_driver); | ||
750 | PDEBUG(D_PROBE, "deregistered"); | ||
751 | } | ||
752 | |||
753 | module_init(sd_mod_init); | ||
754 | module_exit(sd_mod_exit); | ||
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c new file mode 100644 index 000000000000..d26255ddfd5b --- /dev/null +++ b/drivers/media/video/gspca/sonixb.c | |||
@@ -0,0 +1,879 @@ | |||
1 | /* | ||
2 | * sonix sn9c102 (bayer) library | ||
3 | * Copyright (C) 2003 2004 Michel Xhaard mxhaard@magic.fr | ||
4 | * Add Pas106 Stefano Mozzi (C) 2004 | ||
5 | * | ||
6 | * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
21 | */ | ||
22 | |||
23 | #define MODULE_NAME "sonixb" | ||
24 | |||
25 | #include "gspca.h" | ||
26 | |||
27 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) | ||
28 | static const char version[] = "2.1.0"; | ||
29 | |||
30 | MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); | ||
31 | MODULE_DESCRIPTION("GSPCA/SN9C102 USB Camera Driver"); | ||
32 | MODULE_LICENSE("GPL"); | ||
33 | |||
34 | /* specific webcam descriptor */ | ||
35 | struct sd { | ||
36 | struct gspca_dev gspca_dev; /* !! must be the first item */ | ||
37 | |||
38 | unsigned char brightness; | ||
39 | unsigned char contrast; | ||
40 | |||
41 | char sensor; /* Type of image sensor chip */ | ||
42 | #define SENSOR_HV7131R 0 | ||
43 | #define SENSOR_OV6650 1 | ||
44 | #define SENSOR_OV7630 2 | ||
45 | #define SENSOR_OV7630_3 3 | ||
46 | #define SENSOR_PAS106 4 | ||
47 | #define SENSOR_PAS202 5 | ||
48 | #define SENSOR_TAS5110 6 | ||
49 | #define SENSOR_TAS5130CXX 7 | ||
50 | }; | ||
51 | |||
52 | #define COMP2 0x8f | ||
53 | #define COMP 0xc7 /* 0x87 //0x07 */ | ||
54 | #define COMP1 0xc9 /* 0x89 //0x09 */ | ||
55 | |||
56 | #define MCK_INIT 0x63 | ||
57 | #define MCK_INIT1 0x20 /*fixme: Bayer - 0x50 for JPEG ??*/ | ||
58 | |||
59 | #define SYS_CLK 0x04 | ||
60 | |||
61 | /* V4L2 controls supported by the driver */ | ||
62 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
63 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
64 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | ||
65 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | ||
66 | |||
67 | static struct ctrl sd_ctrls[] = { | ||
68 | #define SD_BRIGHTNESS 0 | ||
69 | { | ||
70 | { | ||
71 | .id = V4L2_CID_BRIGHTNESS, | ||
72 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
73 | .name = "Brightness", | ||
74 | .minimum = 0, | ||
75 | .maximum = 255, | ||
76 | .step = 1, | ||
77 | .default_value = 127, | ||
78 | }, | ||
79 | .set = sd_setbrightness, | ||
80 | .get = sd_getbrightness, | ||
81 | }, | ||
82 | #define SD_CONTRAST 1 | ||
83 | { | ||
84 | { | ||
85 | .id = V4L2_CID_CONTRAST, | ||
86 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
87 | .name = "Contrast", | ||
88 | .minimum = 0, | ||
89 | .maximum = 255, | ||
90 | .step = 1, | ||
91 | .default_value = 127, | ||
92 | }, | ||
93 | .set = sd_setcontrast, | ||
94 | .get = sd_getcontrast, | ||
95 | }, | ||
96 | }; | ||
97 | |||
98 | /* fixme: should have V4L2_PIX_FMT_SN9C10X */ | ||
99 | static struct cam_mode vga_mode[] = { | ||
100 | {V4L2_PIX_FMT_SN9C10X, 160, 120, 2}, | ||
101 | {V4L2_PIX_FMT_SN9C10X, 320, 240, 1}, | ||
102 | {V4L2_PIX_FMT_SN9C10X, 640, 480, 0}, | ||
103 | }; | ||
104 | static struct cam_mode sif_mode[] = { | ||
105 | {V4L2_PIX_FMT_SN9C10X, 176, 144, 1}, | ||
106 | {V4L2_PIX_FMT_SN9C10X, 352, 288, 0}, | ||
107 | }; | ||
108 | |||
109 | static const __u8 probe_ov7630[] = {0x08, 0x44}; | ||
110 | |||
111 | static const __u8 initHv7131[] = { | ||
112 | 0x46, 0x77, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00, | ||
113 | 0x00, 0x00, | ||
114 | 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, /* shift from 0x02 0x01 0x00 */ | ||
115 | 0x28, 0x1e, 0x60, 0x8a, 0x20, | ||
116 | 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c | ||
117 | }; | ||
118 | static const __u8 hv7131_sensor_init[][8] = { | ||
119 | {0xc0, 0x11, 0x31, 0x38, 0x2a, 0x2e, 0x00, 0x10}, | ||
120 | {0xa0, 0x11, 0x01, 0x08, 0x2a, 0x2e, 0x00, 0x10}, | ||
121 | {0xb0, 0x11, 0x20, 0x00, 0xd0, 0x2e, 0x00, 0x10}, | ||
122 | {0xc0, 0x11, 0x25, 0x03, 0x0e, 0x28, 0x00, 0x16}, | ||
123 | {0xa0, 0x11, 0x30, 0x10, 0x0e, 0x28, 0x00, 0x15}, | ||
124 | }; | ||
125 | static const __u8 initOv6650[] = { | ||
126 | 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, | ||
127 | 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
128 | 0x00, 0x02, 0x01, 0x0a, 0x16, 0x12, 0x68, 0x0b, | ||
129 | 0x10, 0x1d, 0x10, 0x00, 0x06, 0x1f, 0x00 | ||
130 | }; | ||
131 | static const __u8 ov6650_sensor_init[][8] = | ||
132 | { | ||
133 | /* Bright, contrast, etc are set througth SCBB interface. | ||
134 | * AVCAP on win2 do not send any data on this controls. */ | ||
135 | /* Anyway, some registers appears to alter bright and constrat */ | ||
136 | {0xa0, 0x60, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, | ||
137 | {0xd0, 0x60, 0x11, 0xc0, 0x1b, 0x18, 0xc1, 0x10}, | ||
138 | {0xb0, 0x60, 0x15, 0x00, 0x02, 0x18, 0xc1, 0x10}, | ||
139 | /* {0xa0, 0x60, 0x1b, 0x01, 0x02, 0x18, 0xc1, 0x10}, | ||
140 | * THIS SET GREEN SCREEN | ||
141 | * (pixels could be innverted in decode kind of "brg", | ||
142 | * but blue wont be there. Avoid this data ... */ | ||
143 | {0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10}, /* format out? */ | ||
144 | {0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10}, | ||
145 | {0xa0, 0x60, 0x30, 0x3d, 0x0A, 0xd8, 0xa4, 0x10}, | ||
146 | {0xb0, 0x60, 0x60, 0x66, 0x68, 0xd8, 0xa4, 0x10}, | ||
147 | {0xa0, 0x60, 0x68, 0x04, 0x68, 0xd8, 0xa4, 0x10}, | ||
148 | {0xd0, 0x60, 0x17, 0x24, 0xd6, 0x04, 0x94, 0x10}, /* Clipreg */ | ||
149 | {0xa0, 0x60, 0x10, 0x5d, 0x99, 0x04, 0x94, 0x16}, | ||
150 | {0xa0, 0x60, 0x2d, 0x0a, 0x99, 0x04, 0x94, 0x16}, | ||
151 | {0xa0, 0x60, 0x32, 0x00, 0x99, 0x04, 0x94, 0x16}, | ||
152 | {0xa0, 0x60, 0x33, 0x40, 0x99, 0x04, 0x94, 0x16}, | ||
153 | {0xa0, 0x60, 0x11, 0xc0, 0x99, 0x04, 0x94, 0x16}, | ||
154 | {0xa0, 0x60, 0x00, 0x16, 0x99, 0x04, 0x94, 0x15}, /* bright / Lumino */ | ||
155 | {0xa0, 0x60, 0x2b, 0xab, 0x99, 0x04, 0x94, 0x15}, | ||
156 | /* ?flicker o brillo */ | ||
157 | {0xa0, 0x60, 0x2d, 0x2a, 0x99, 0x04, 0x94, 0x15}, | ||
158 | {0xa0, 0x60, 0x2d, 0x2b, 0x99, 0x04, 0x94, 0x16}, | ||
159 | {0xa0, 0x60, 0x32, 0x00, 0x99, 0x04, 0x94, 0x16}, | ||
160 | {0xa0, 0x60, 0x33, 0x00, 0x99, 0x04, 0x94, 0x16}, | ||
161 | {0xa0, 0x60, 0x10, 0x57, 0x99, 0x04, 0x94, 0x16}, | ||
162 | {0xa0, 0x60, 0x2d, 0x2b, 0x99, 0x04, 0x94, 0x16}, | ||
163 | {0xa0, 0x60, 0x32, 0x00, 0x99, 0x04, 0x94, 0x16}, | ||
164 | /* Low Light (Enabled: 0x32 0x1 | Disabled: 0x32 0x00) */ | ||
165 | {0xa0, 0x60, 0x33, 0x29, 0x99, 0x04, 0x94, 0x16}, | ||
166 | /* Low Ligth (Enabled: 0x33 0x13 | Disabled: 0x33 0x29) */ | ||
167 | /* {0xa0, 0x60, 0x11, 0xc1, 0x99, 0x04, 0x94, 0x16}, */ | ||
168 | {0xa0, 0x60, 0x00, 0x17, 0x99, 0x04, 0x94, 0x15}, /* clip? r */ | ||
169 | {0xa0, 0x60, 0x00, 0x18, 0x99, 0x04, 0x94, 0x15}, /* clip? r */ | ||
170 | }; | ||
171 | static const __u8 initOv7630[] = { | ||
172 | 0x04, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* r01 .. r08 */ | ||
173 | 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* r09 .. r10 */ | ||
174 | 0x00, 0x02, 0x01, 0x0a, /* r11 .. r14 */ | ||
175 | 0x28, 0x1e, /* H & V sizes r15 .. r16 */ | ||
176 | 0x68, COMP1, MCK_INIT1, /* r17 .. r19 */ | ||
177 | 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c /* r1a .. r1f */ | ||
178 | }; | ||
179 | static const __u8 initOv7630_3[] = { | ||
180 | 0x44, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0x80, /* r01 .. r08 */ | ||
181 | 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, /* r09 .. r10 */ | ||
182 | 0x00, 0x02, 0x01, 0x0a, /* r11 .. r14 */ | ||
183 | 0x28, 0x1e, /* H & V sizes r15 .. r16 */ | ||
184 | 0x68, COMP1, MCK_INIT1, /* r17 .. r19 */ | ||
185 | 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c /* r1a .. r1f */ | ||
186 | }; | ||
187 | static const __u8 ov7630_sensor_init_com[][8] = { | ||
188 | {0xa0, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, | ||
189 | {0xb0, 0x21, 0x01, 0x77, 0x3a, 0x00, 0x00, 0x10}, | ||
190 | /* {0xd0, 0x21, 0x12, 0x7c, 0x01, 0x80, 0x34, 0x10}, jfm */ | ||
191 | {0xd0, 0x21, 0x12, 0x78, 0x00, 0x80, 0x34, 0x10}, /* jfm */ | ||
192 | {0xa0, 0x21, 0x1b, 0x04, 0x00, 0x80, 0x34, 0x10}, | ||
193 | {0xa0, 0x21, 0x20, 0x44, 0x00, 0x80, 0x34, 0x10}, | ||
194 | {0xa0, 0x21, 0x23, 0xee, 0x00, 0x80, 0x34, 0x10}, | ||
195 | {0xd0, 0x21, 0x26, 0xa0, 0x9a, 0xa0, 0x30, 0x10}, | ||
196 | {0xb0, 0x21, 0x2a, 0x80, 0x00, 0xa0, 0x30, 0x10}, | ||
197 | {0xb0, 0x21, 0x2f, 0x3d, 0x24, 0xa0, 0x30, 0x10}, | ||
198 | {0xa0, 0x21, 0x32, 0x86, 0x24, 0xa0, 0x30, 0x10}, | ||
199 | /* {0xb0, 0x21, 0x60, 0xa9, 0x4a, 0xa0, 0x30, 0x10}, jfm */ | ||
200 | {0xb0, 0x21, 0x60, 0xa9, 0x42, 0xa0, 0x30, 0x10}, /* jfm */ | ||
201 | {0xa0, 0x21, 0x65, 0x00, 0x42, 0xa0, 0x30, 0x10}, | ||
202 | {0xa0, 0x21, 0x69, 0x38, 0x42, 0xa0, 0x30, 0x10}, | ||
203 | {0xc0, 0x21, 0x6f, 0x88, 0x0b, 0x00, 0x30, 0x10}, | ||
204 | {0xc0, 0x21, 0x74, 0x21, 0x8e, 0x00, 0x30, 0x10}, | ||
205 | {0xa0, 0x21, 0x7d, 0xf7, 0x8e, 0x00, 0x30, 0x10}, | ||
206 | {0xd0, 0x21, 0x17, 0x1c, 0xbd, 0x06, 0xf6, 0x10}, | ||
207 | }; | ||
208 | static const __u8 ov7630_sensor_init[][8] = { | ||
209 | {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 200ms */ | ||
210 | {0xa0, 0x21, 0x11, 0x01, 0xbd, 0x06, 0xf6, 0x10}, /* jfm */ | ||
211 | {0xa0, 0x21, 0x10, 0x57, 0xbd, 0x06, 0xf6, 0x16}, | ||
212 | {0xa0, 0x21, 0x76, 0x02, 0xbd, 0x06, 0xf6, 0x16}, | ||
213 | {0xa0, 0x21, 0x00, 0x10, 0xbd, 0x06, 0xf6, 0x15}, /* gain */ | ||
214 | }; | ||
215 | static const __u8 ov7630_sensor_init_3[][8] = { | ||
216 | {0xa0, 0x21, 0x10, 0x36, 0xbd, 0x06, 0xf6, 0x16}, /* exposure */ | ||
217 | {0xa0, 0x21, 0x76, 0x03, 0xbd, 0x06, 0xf6, 0x16}, | ||
218 | {0xa0, 0x21, 0x11, 0x01, 0xbd, 0x06, 0xf6, 0x16}, | ||
219 | {0xa0, 0x21, 0x00, 0x10, 0xbd, 0x06, 0xf6, 0x15}, /* gain */ | ||
220 | /* {0xb0, 0x21, 0x2a, 0xc0, 0x3c, 0x06, 0xf6, 0x1d}, | ||
221 | * a0 1c,a0 1f,c0 3c frame rate ?line interval from ov6630 */ | ||
222 | /* {0xb0, 0x21, 0x2a, 0xa0, 0x1f, 0x06, 0xf6, 0x1d}, * from win */ | ||
223 | {0xb0, 0x21, 0x2a, 0xa0, 0x1c, 0x06, 0xf6, 0x1d}, | ||
224 | }; | ||
225 | |||
226 | static const __u8 initPas106[] = { | ||
227 | 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x00, 0x00, | ||
228 | 0x00, 0x00, | ||
229 | 0x00, 0x00, 0x00, 0x05, 0x01, 0x00, | ||
230 | 0x16, 0x12, 0x28, COMP1, MCK_INIT1, | ||
231 | 0x18, 0x10, 0x04, 0x03, 0x11, 0x0c | ||
232 | }; | ||
233 | /* compression 0x86 mckinit1 0x2b */ | ||
234 | static const __u8 pas106_data[][2] = { | ||
235 | {0x02, 0x04}, /* Pixel Clock Divider 6 */ | ||
236 | {0x03, 0x13}, /* Frame Time MSB */ | ||
237 | /* {0x03, 0x12}, * Frame Time MSB */ | ||
238 | {0x04, 0x06}, /* Frame Time LSB */ | ||
239 | /* {0x04, 0x05}, * Frame Time LSB */ | ||
240 | {0x05, 0x65}, /* Shutter Time Line Offset */ | ||
241 | /* {0x05, 0x6d}, * Shutter Time Line Offset */ | ||
242 | /* {0x06, 0xb1}, * Shutter Time Pixel Offset */ | ||
243 | {0x06, 0xcd}, /* Shutter Time Pixel Offset */ | ||
244 | {0x07, 0xc1}, /* Black Level Subtract Sign */ | ||
245 | /* {0x07, 0x00}, * Black Level Subtract Sign */ | ||
246 | {0x08, 0x06}, /* Black Level Subtract Level */ | ||
247 | {0x08, 0x06}, /* Black Level Subtract Level */ | ||
248 | /* {0x08, 0x01}, * Black Level Subtract Level */ | ||
249 | {0x09, 0x05}, /* Color Gain B Pixel 5 a */ | ||
250 | {0x0a, 0x04}, /* Color Gain G1 Pixel 1 5 */ | ||
251 | {0x0b, 0x04}, /* Color Gain G2 Pixel 1 0 5 */ | ||
252 | {0x0c, 0x05}, /* Color Gain R Pixel 3 1 */ | ||
253 | {0x0d, 0x00}, /* Color GainH Pixel */ | ||
254 | {0x0e, 0x0e}, /* Global Gain */ | ||
255 | {0x0f, 0x00}, /* Contrast */ | ||
256 | {0x10, 0x06}, /* H&V synchro polarity */ | ||
257 | {0x11, 0x06}, /* ?default */ | ||
258 | {0x12, 0x06}, /* DAC scale */ | ||
259 | {0x14, 0x02}, /* ?default */ | ||
260 | {0x13, 0x01}, /* Validate Settings */ | ||
261 | }; | ||
262 | static const __u8 initPas202[] = { | ||
263 | 0x44, 0x44, 0x21, 0x30, 0x00, 0x00, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00, | ||
264 | 0x00, 0x00, | ||
265 | 0x00, 0x00, 0x00, 0x07, 0x03, 0x0a, /* 6 */ | ||
266 | 0x28, 0x1e, 0x28, 0x89, 0x30, | ||
267 | 0x00, 0x00, 0x02, 0x03, 0x0f, 0x0c | ||
268 | }; | ||
269 | static const __u8 pas202_sensor_init[][8] = { | ||
270 | {0xa0, 0x40, 0x02, 0x03, 0x00, 0x00, 0x00, 0x10}, | ||
271 | {0xd0, 0x40, 0x04, 0x07, 0x34, 0x00, 0x09, 0x10}, | ||
272 | {0xd0, 0x40, 0x08, 0x01, 0x00, 0x00, 0x01, 0x10}, | ||
273 | {0xd0, 0x40, 0x0C, 0x00, 0x0C, 0x00, 0x32, 0x10}, | ||
274 | {0xd0, 0x40, 0x10, 0x00, 0x01, 0x00, 0x63, 0x10}, | ||
275 | {0xa0, 0x40, 0x15, 0x70, 0x01, 0x00, 0x63, 0x10}, | ||
276 | {0xa0, 0x40, 0x18, 0x00, 0x01, 0x00, 0x63, 0x10}, | ||
277 | {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10}, | ||
278 | {0xa0, 0x40, 0x03, 0x56, 0x01, 0x00, 0x63, 0x10}, | ||
279 | {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10}, | ||
280 | {0xb0, 0x40, 0x04, 0x07, 0x2a, 0x00, 0x63, 0x10}, | ||
281 | {0xb0, 0x40, 0x0e, 0x00, 0x3d, 0x00, 0x63, 0x10}, | ||
282 | |||
283 | {0xa0, 0x40, 0x11, 0x01, 0x3d, 0x00, 0x63, 0x16}, | ||
284 | {0xa0, 0x40, 0x10, 0x08, 0x3d, 0x00, 0x63, 0x15}, | ||
285 | {0xa0, 0x40, 0x02, 0x04, 0x3d, 0x00, 0x63, 0x16}, | ||
286 | {0xa0, 0x40, 0x11, 0x01, 0x3d, 0x00, 0x63, 0x16}, | ||
287 | {0xb0, 0x40, 0x0e, 0x00, 0x31, 0x00, 0x63, 0x16}, | ||
288 | {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16}, | ||
289 | {0xa0, 0x40, 0x10, 0x0e, 0x31, 0x00, 0x63, 0x15}, | ||
290 | {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16}, | ||
291 | }; | ||
292 | |||
293 | static const __u8 initTas5110[] = { | ||
294 | 0x44, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00, | ||
295 | 0x00, 0x00, | ||
296 | 0x00, 0x01, 0x00, 0x46, 0x09, 0x0a, /* shift from 0x45 0x09 0x0a */ | ||
297 | 0x16, 0x12, 0x60, 0x86, 0x2b, | ||
298 | 0x14, 0x0a, 0x02, 0x02, 0x09, 0x07 | ||
299 | }; | ||
300 | static const __u8 tas5110_sensor_init[][8] = { | ||
301 | {0x30, 0x11, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10}, | ||
302 | {0x30, 0x11, 0x02, 0x20, 0xa9, 0x00, 0x00, 0x10}, | ||
303 | {0xa0, 0x61, 0x9a, 0xca, 0x00, 0x00, 0x00, 0x17}, | ||
304 | }; | ||
305 | |||
306 | static const __u8 initTas5130[] = { | ||
307 | 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00, | ||
308 | 0x00, 0x00, | ||
309 | 0x00, 0x01, 0x00, 0x69, 0x0c, 0x0a, | ||
310 | 0x28, 0x1e, 0x60, COMP, MCK_INIT, | ||
311 | 0x18, 0x10, 0x04, 0x03, 0x11, 0x0c | ||
312 | }; | ||
313 | static const __u8 tas5130_sensor_init[][8] = { | ||
314 | /* {0x30, 0x11, 0x00, 0x40, 0x47, 0x00, 0x00, 0x10}, | ||
315 | * shutter 0x47 short exposure? */ | ||
316 | {0x30, 0x11, 0x00, 0x40, 0x01, 0x00, 0x00, 0x10}, | ||
317 | /* shutter 0x01 long exposure */ | ||
318 | {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10}, | ||
319 | }; | ||
320 | |||
321 | static void reg_r(struct usb_device *dev, | ||
322 | __u16 value, __u8 *buffer) | ||
323 | { | ||
324 | usb_control_msg(dev, | ||
325 | usb_rcvctrlpipe(dev, 0), | ||
326 | 0, /* request */ | ||
327 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, | ||
328 | value, | ||
329 | 0, /* index */ | ||
330 | buffer, 1, | ||
331 | 500); | ||
332 | } | ||
333 | |||
334 | static void reg_w(struct usb_device *dev, | ||
335 | __u16 value, | ||
336 | const __u8 *buffer, | ||
337 | __u16 len) | ||
338 | { | ||
339 | usb_control_msg(dev, | ||
340 | usb_sndctrlpipe(dev, 0), | ||
341 | 0x08, /* request */ | ||
342 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, | ||
343 | value, | ||
344 | 0, /* index */ | ||
345 | (__u8 *) buffer, len, | ||
346 | 500); | ||
347 | } | ||
348 | |||
349 | static int i2c_w(struct usb_device *dev, const __u8 *buffer) | ||
350 | { | ||
351 | int retry = 60; | ||
352 | __u8 ByteReceive; | ||
353 | |||
354 | /* is i2c ready */ | ||
355 | reg_w(dev, 0x08, buffer, 8); | ||
356 | while (retry--) { | ||
357 | msleep(10); | ||
358 | reg_r(dev, 0x08, &ByteReceive); | ||
359 | if (ByteReceive == 4) | ||
360 | return 0; | ||
361 | } | ||
362 | return -1; | ||
363 | } | ||
364 | |||
365 | static void i2c_w_vector(struct usb_device *dev, | ||
366 | const __u8 buffer[][8], int len) | ||
367 | { | ||
368 | for (;;) { | ||
369 | reg_w(dev, 0x08, *buffer, 8); | ||
370 | len -= 8; | ||
371 | if (len <= 0) | ||
372 | break; | ||
373 | buffer++; | ||
374 | } | ||
375 | } | ||
376 | |||
377 | static void setbrightness(struct gspca_dev *gspca_dev) | ||
378 | { | ||
379 | struct sd *sd = (struct sd *) gspca_dev; | ||
380 | __u8 value; | ||
381 | |||
382 | switch (sd->sensor) { | ||
383 | case SENSOR_OV6650: { | ||
384 | __u8 i2cOV6650[] = | ||
385 | {0xa0, 0x60, 0x06, 0x11, 0x99, 0x04, 0x94, 0x15}; | ||
386 | |||
387 | i2cOV6650[3] = sd->brightness; | ||
388 | if (i2c_w(gspca_dev->dev, i2cOV6650) < 0) | ||
389 | goto err; | ||
390 | break; | ||
391 | } | ||
392 | case SENSOR_OV7630: { | ||
393 | __u8 i2cOV[] = | ||
394 | {0xa0, 0x21, 0x06, 0x36, 0xbd, 0x06, 0xf6, 0x16}; | ||
395 | |||
396 | /* change reg 0x06 */ | ||
397 | i2cOV[3] = sd->brightness; | ||
398 | if (i2c_w(gspca_dev->dev, i2cOV) < 0) | ||
399 | goto err; | ||
400 | break; | ||
401 | } | ||
402 | case SENSOR_PAS106: { | ||
403 | __u8 i2c1[] = | ||
404 | {0xa1, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14}; | ||
405 | |||
406 | i2c1[3] = sd->brightness >> 3; | ||
407 | i2c1[2] = 0x0e; | ||
408 | if (i2c_w(gspca_dev->dev, i2c1) < 0) | ||
409 | goto err; | ||
410 | i2c1[3] = 0x01; | ||
411 | i2c1[2] = 0x13; | ||
412 | if (i2c_w(gspca_dev->dev, i2c1) < 0) | ||
413 | goto err; | ||
414 | break; | ||
415 | } | ||
416 | case SENSOR_PAS202: { | ||
417 | /* __u8 i2cpexpo1[] = | ||
418 | {0xb0, 0x40, 0x04, 0x07, 0x2a, 0x00, 0x63, 0x16}; */ | ||
419 | __u8 i2cpexpo[] = | ||
420 | {0xb0, 0x40, 0x0e, 0x01, 0xab, 0x00, 0x63, 0x16}; | ||
421 | __u8 i2cp202[] = | ||
422 | {0xa0, 0x40, 0x10, 0x0e, 0x31, 0x00, 0x63, 0x15}; | ||
423 | static __u8 i2cpdoit[] = | ||
424 | {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16}; | ||
425 | |||
426 | /* change reg 0x10 */ | ||
427 | i2cpexpo[4] = 0xff - sd->brightness; | ||
428 | /* if(i2c_w(gspca_dev->dev,i2cpexpo1) < 0) | ||
429 | goto err; */ | ||
430 | /* if(i2c_w(gspca_dev->dev,i2cpdoit) < 0) | ||
431 | goto err; */ | ||
432 | if (i2c_w(gspca_dev->dev, i2cpexpo) < 0) | ||
433 | goto err; | ||
434 | if (i2c_w(gspca_dev->dev, i2cpdoit) < 0) | ||
435 | goto err; | ||
436 | i2cp202[3] = sd->brightness >> 3; | ||
437 | if (i2c_w(gspca_dev->dev, i2cp202) < 0) | ||
438 | goto err; | ||
439 | if (i2c_w(gspca_dev->dev, i2cpdoit) < 0) | ||
440 | goto err; | ||
441 | break; | ||
442 | } | ||
443 | case SENSOR_TAS5130CXX: | ||
444 | case SENSOR_TAS5110: { | ||
445 | __u8 i2c[] = | ||
446 | {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10}; | ||
447 | |||
448 | value = 0xff - sd->brightness; | ||
449 | i2c[4] = value; | ||
450 | PDEBUG(D_CONF, "brightness %d : %d", value, i2c[4]); | ||
451 | if (i2c_w(gspca_dev->dev, i2c) < 0) | ||
452 | goto err; | ||
453 | break; | ||
454 | } | ||
455 | } | ||
456 | return; | ||
457 | err: | ||
458 | PDEBUG(D_ERR, "i2c error brightness"); | ||
459 | } | ||
460 | static void setcontrast(struct gspca_dev *gspca_dev) | ||
461 | { | ||
462 | struct sd *sd = (struct sd *) gspca_dev; | ||
463 | __u8 gain; | ||
464 | __u8 rgb_value; | ||
465 | |||
466 | gain = sd->contrast >> 4; | ||
467 | /* red and blue gain */ | ||
468 | rgb_value = gain << 4 | gain; | ||
469 | reg_w(gspca_dev->dev, 0x10, &rgb_value, 1); | ||
470 | /* green gain */ | ||
471 | rgb_value = gain; | ||
472 | reg_w(gspca_dev->dev, 0x11, &rgb_value, 1); | ||
473 | } | ||
474 | |||
475 | /* this function is called at probe time */ | ||
476 | static int sd_config(struct gspca_dev *gspca_dev, | ||
477 | const struct usb_device_id *id) | ||
478 | { | ||
479 | struct sd *sd = (struct sd *) gspca_dev; | ||
480 | struct cam *cam; | ||
481 | /* __u16 vendor; */ | ||
482 | __u16 product; | ||
483 | int sif = 0; | ||
484 | |||
485 | /* vendor = id->idVendor; */ | ||
486 | product = id->idProduct; | ||
487 | /* switch (vendor) { */ | ||
488 | /* case 0x0c45: * Sonix */ | ||
489 | switch (product) { | ||
490 | case 0x6001: /* SN9C102 */ | ||
491 | case 0x6005: /* SN9C101 */ | ||
492 | case 0x6007: /* SN9C101 */ | ||
493 | sd->sensor = SENSOR_TAS5110; | ||
494 | sif = 1; | ||
495 | break; | ||
496 | case 0x6009: /* SN9C101 */ | ||
497 | case 0x600d: /* SN9C101 */ | ||
498 | case 0x6029: /* SN9C101 */ | ||
499 | sd->sensor = SENSOR_PAS106; | ||
500 | sif = 1; | ||
501 | break; | ||
502 | case 0x6011: /* SN9C101 - SN9C101G */ | ||
503 | sd->sensor = SENSOR_OV6650; | ||
504 | sif = 1; | ||
505 | break; | ||
506 | case 0x6019: /* SN9C101 */ | ||
507 | case 0x602c: /* SN9C102 */ | ||
508 | case 0x602e: /* SN9C102 */ | ||
509 | sd->sensor = SENSOR_OV7630; | ||
510 | break; | ||
511 | case 0x60b0: /* SN9C103 */ | ||
512 | sd->sensor = SENSOR_OV7630_3; | ||
513 | break; | ||
514 | case 0x6024: /* SN9C102 */ | ||
515 | case 0x6025: /* SN9C102 */ | ||
516 | sd->sensor = SENSOR_TAS5130CXX; | ||
517 | break; | ||
518 | case 0x6028: /* SN9C102 */ | ||
519 | sd->sensor = SENSOR_PAS202; | ||
520 | break; | ||
521 | case 0x602d: /* SN9C102 */ | ||
522 | sd->sensor = SENSOR_HV7131R; | ||
523 | break; | ||
524 | case 0x60af: /* SN9C103 */ | ||
525 | sd->sensor = SENSOR_PAS202; | ||
526 | break; | ||
527 | } | ||
528 | /* break; */ | ||
529 | /* } */ | ||
530 | |||
531 | cam = &gspca_dev->cam; | ||
532 | cam->dev_name = (char *) id->driver_info; | ||
533 | cam->epaddr = 0x01; | ||
534 | if (!sif) { | ||
535 | cam->cam_mode = vga_mode; | ||
536 | cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; | ||
537 | } else { | ||
538 | cam->cam_mode = sif_mode; | ||
539 | cam->nmodes = sizeof sif_mode / sizeof sif_mode[0]; | ||
540 | } | ||
541 | sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; | ||
542 | sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; | ||
543 | if (sd->sensor == SENSOR_OV7630_3) /* jfm: from win trace */ | ||
544 | reg_w(gspca_dev->dev, 0x01, probe_ov7630, sizeof probe_ov7630); | ||
545 | return 0; | ||
546 | } | ||
547 | |||
548 | /* this function is called at open time */ | ||
549 | static int sd_open(struct gspca_dev *gspca_dev) | ||
550 | { | ||
551 | __u8 ByteReceive; | ||
552 | |||
553 | reg_r(gspca_dev->dev, 0x00, &ByteReceive); | ||
554 | if (ByteReceive != 0x10) | ||
555 | return -ENODEV; | ||
556 | return 0; | ||
557 | } | ||
558 | |||
559 | static void pas106_i2cinit(struct usb_device *dev) | ||
560 | { | ||
561 | int i; | ||
562 | const __u8 *data; | ||
563 | __u8 i2c1[] = { 0xa1, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14 }; | ||
564 | |||
565 | i = ARRAY_SIZE(pas106_data); | ||
566 | data = pas106_data[0]; | ||
567 | while (--i >= 0) { | ||
568 | memcpy(&i2c1[2], data, 2); | ||
569 | /* copy 2 bytes from the template */ | ||
570 | if (i2c_w(dev, i2c1) < 0) | ||
571 | PDEBUG(D_ERR, "i2c error pas106"); | ||
572 | data += 2; | ||
573 | } | ||
574 | } | ||
575 | |||
576 | /* -- start the camera -- */ | ||
577 | static void sd_start(struct gspca_dev *gspca_dev) | ||
578 | { | ||
579 | struct sd *sd = (struct sd *) gspca_dev; | ||
580 | struct usb_device *dev = gspca_dev->dev; | ||
581 | int mode, l; | ||
582 | const __u8 *sn9c10x; | ||
583 | __u8 reg01, reg17; | ||
584 | __u8 reg17_19[3]; | ||
585 | |||
586 | mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode; | ||
587 | switch (sd->sensor) { | ||
588 | case SENSOR_HV7131R: | ||
589 | sn9c10x = initHv7131; | ||
590 | reg17_19[0] = 0x60; | ||
591 | reg17_19[1] = (mode << 4) | 0x8a; | ||
592 | reg17_19[2] = 0x20; | ||
593 | break; | ||
594 | case SENSOR_OV6650: | ||
595 | sn9c10x = initOv6650; | ||
596 | reg17_19[0] = 0x68; | ||
597 | reg17_19[1] = (mode << 4) | 0x8b; | ||
598 | reg17_19[2] = 0x20; | ||
599 | break; | ||
600 | case SENSOR_OV7630: | ||
601 | sn9c10x = initOv7630; | ||
602 | reg17_19[0] = 0x68; | ||
603 | reg17_19[1] = (mode << 4) | COMP2; | ||
604 | reg17_19[2] = MCK_INIT1; | ||
605 | break; | ||
606 | case SENSOR_OV7630_3: | ||
607 | sn9c10x = initOv7630_3; | ||
608 | reg17_19[0] = 0x68; | ||
609 | reg17_19[1] = (mode << 4) | COMP2; | ||
610 | reg17_19[2] = MCK_INIT1; | ||
611 | break; | ||
612 | case SENSOR_PAS106: | ||
613 | sn9c10x = initPas106; | ||
614 | reg17_19[0] = 0x24; /* 0x28 */ | ||
615 | reg17_19[1] = (mode << 4) | COMP1; | ||
616 | reg17_19[2] = MCK_INIT1; | ||
617 | break; | ||
618 | case SENSOR_PAS202: | ||
619 | sn9c10x = initPas202; | ||
620 | reg17_19[0] = mode ? 0x24 : 0x20; | ||
621 | reg17_19[1] = (mode << 4) | 0x89; | ||
622 | reg17_19[2] = 0x20; | ||
623 | break; | ||
624 | case SENSOR_TAS5110: | ||
625 | sn9c10x = initTas5110; | ||
626 | reg17_19[0] = 0x60; | ||
627 | reg17_19[1] = (mode << 4) | 0x86; | ||
628 | reg17_19[2] = 0x2b; /* 0xf3; */ | ||
629 | break; | ||
630 | default: | ||
631 | /* case SENSOR_TAS5130CXX: */ | ||
632 | sn9c10x = initTas5130; | ||
633 | reg17_19[0] = 0x60; | ||
634 | reg17_19[1] = (mode << 4) | COMP; | ||
635 | reg17_19[2] = mode ? 0x23 : 0x43; | ||
636 | break; | ||
637 | } | ||
638 | switch (sd->sensor) { | ||
639 | case SENSOR_OV7630: | ||
640 | reg01 = 0x06; | ||
641 | reg17 = 0x29; | ||
642 | l = 0x10; | ||
643 | break; | ||
644 | case SENSOR_OV7630_3: | ||
645 | reg01 = 0x44; | ||
646 | reg17 = 0x68; | ||
647 | l = 0x10; | ||
648 | break; | ||
649 | default: | ||
650 | reg01 = sn9c10x[0]; | ||
651 | reg17 = sn9c10x[0x17 - 1]; | ||
652 | l = 0x1f; | ||
653 | break; | ||
654 | } | ||
655 | |||
656 | /* reg 0x01 bit 2 video transfert on */ | ||
657 | reg_w(dev, 0x01, ®01, 1); | ||
658 | /* reg 0x17 SensorClk enable inv Clk 0x60 */ | ||
659 | reg_w(dev, 0x17, ®17, 1); | ||
660 | /*fixme: for ov7630 102 | ||
661 | reg_w(dev, 0x01, {0x06, sn9c10x[1]}, 2); */ | ||
662 | /* Set the registers from the template */ | ||
663 | reg_w(dev, 0x01, sn9c10x, l); | ||
664 | switch (sd->sensor) { | ||
665 | case SENSOR_HV7131R: | ||
666 | i2c_w_vector(dev, hv7131_sensor_init, | ||
667 | sizeof hv7131_sensor_init); | ||
668 | break; | ||
669 | case SENSOR_OV6650: | ||
670 | i2c_w_vector(dev, ov6650_sensor_init, | ||
671 | sizeof ov6650_sensor_init); | ||
672 | break; | ||
673 | case SENSOR_OV7630: | ||
674 | i2c_w_vector(dev, ov7630_sensor_init_com, | ||
675 | sizeof ov7630_sensor_init_com); | ||
676 | msleep(200); | ||
677 | i2c_w_vector(dev, ov7630_sensor_init, | ||
678 | sizeof ov7630_sensor_init); | ||
679 | break; | ||
680 | case SENSOR_OV7630_3: | ||
681 | i2c_w_vector(dev, ov7630_sensor_init_com, | ||
682 | sizeof ov7630_sensor_init_com); | ||
683 | msleep(200); | ||
684 | i2c_w_vector(dev, ov7630_sensor_init_3, | ||
685 | sizeof ov7630_sensor_init_3); | ||
686 | break; | ||
687 | case SENSOR_PAS106: | ||
688 | pas106_i2cinit(dev); | ||
689 | break; | ||
690 | case SENSOR_PAS202: | ||
691 | i2c_w_vector(dev, pas202_sensor_init, | ||
692 | sizeof pas202_sensor_init); | ||
693 | break; | ||
694 | case SENSOR_TAS5110: | ||
695 | i2c_w_vector(dev, tas5110_sensor_init, | ||
696 | sizeof tas5110_sensor_init); | ||
697 | break; | ||
698 | default: | ||
699 | /* case SENSOR_TAS5130CXX: */ | ||
700 | i2c_w_vector(dev, tas5130_sensor_init, | ||
701 | sizeof tas5130_sensor_init); | ||
702 | break; | ||
703 | } | ||
704 | /* H_size V_size 0x28, 0x1e maybe 640x480 */ | ||
705 | reg_w(dev, 0x15, &sn9c10x[0x15 - 1], 2); | ||
706 | /* compression register */ | ||
707 | reg_w(dev, 0x18, ®17_19[1], 1); | ||
708 | /* H_start */ /*fixme: not ov7630*/ | ||
709 | reg_w(dev, 0x12, &sn9c10x[0x12 - 1], 1); | ||
710 | /* V_START */ /*fixme: not ov7630*/ | ||
711 | reg_w(dev, 0x13, &sn9c10x[0x13 - 1], 1); | ||
712 | /* reset 0x17 SensorClk enable inv Clk 0x60 */ | ||
713 | /*fixme: ov7630 [17]=68 8f (+20 if 102)*/ | ||
714 | reg_w(dev, 0x17, ®17_19[0], 1); | ||
715 | /*MCKSIZE ->3 */ /*fixme: not ov7630*/ | ||
716 | reg_w(dev, 0x19, ®17_19[2], 1); | ||
717 | /* AE_STRX AE_STRY AE_ENDX AE_ENDY */ | ||
718 | reg_w(dev, 0x1c, &sn9c10x[0x1c - 1], 4); | ||
719 | /* Enable video transfert */ | ||
720 | reg_w(dev, 0x01, &sn9c10x[0], 1); | ||
721 | /* Compression */ | ||
722 | reg_w(dev, 0x18, ®17_19[1], 2); | ||
723 | msleep(20); | ||
724 | |||
725 | setcontrast(gspca_dev); | ||
726 | setbrightness(gspca_dev); | ||
727 | } | ||
728 | |||
729 | static void sd_stopN(struct gspca_dev *gspca_dev) | ||
730 | { | ||
731 | __u8 ByteSend = 0; | ||
732 | |||
733 | ByteSend = 0x09; /* 0X00 */ | ||
734 | reg_w(gspca_dev->dev, 0x01, &ByteSend, 1); | ||
735 | } | ||
736 | |||
737 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
738 | { | ||
739 | } | ||
740 | |||
741 | static void sd_close(struct gspca_dev *gspca_dev) | ||
742 | { | ||
743 | } | ||
744 | |||
745 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | ||
746 | struct gspca_frame *frame, /* target */ | ||
747 | unsigned char *data, /* isoc packet */ | ||
748 | int len) /* iso packet length */ | ||
749 | { | ||
750 | int p; | ||
751 | |||
752 | if (len > 6 && len < 24) { | ||
753 | for (p = 0; p < len - 6; p++) { | ||
754 | if (data[0 + p] == 0xff | ||
755 | && data[1 + p] == 0xff | ||
756 | && data[2 + p] == 0x00 | ||
757 | && data[3 + p] == 0xc4 | ||
758 | && data[4 + p] == 0xc4 | ||
759 | && data[5 + p] == 0x96) { /* start of frame */ | ||
760 | frame = gspca_frame_add(gspca_dev, | ||
761 | LAST_PACKET, | ||
762 | frame, | ||
763 | data, 0); | ||
764 | data += 12; | ||
765 | len -= 12; | ||
766 | gspca_frame_add(gspca_dev, FIRST_PACKET, | ||
767 | frame, data, len); | ||
768 | return; | ||
769 | } | ||
770 | } | ||
771 | } | ||
772 | gspca_frame_add(gspca_dev, INTER_PACKET, | ||
773 | frame, data, len); | ||
774 | } | ||
775 | |||
776 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | ||
777 | { | ||
778 | struct sd *sd = (struct sd *) gspca_dev; | ||
779 | |||
780 | sd->brightness = val; | ||
781 | if (gspca_dev->streaming) | ||
782 | setbrightness(gspca_dev); | ||
783 | return 0; | ||
784 | } | ||
785 | |||
786 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
787 | { | ||
788 | struct sd *sd = (struct sd *) gspca_dev; | ||
789 | |||
790 | *val = sd->brightness; | ||
791 | return 0; | ||
792 | } | ||
793 | |||
794 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | ||
795 | { | ||
796 | struct sd *sd = (struct sd *) gspca_dev; | ||
797 | |||
798 | sd->contrast = val; | ||
799 | if (gspca_dev->streaming) | ||
800 | setcontrast(gspca_dev); | ||
801 | return 0; | ||
802 | } | ||
803 | |||
804 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) | ||
805 | { | ||
806 | struct sd *sd = (struct sd *) gspca_dev; | ||
807 | |||
808 | *val = sd->contrast; | ||
809 | return 0; | ||
810 | } | ||
811 | |||
812 | /* sub-driver description */ | ||
813 | static struct sd_desc sd_desc = { | ||
814 | .name = MODULE_NAME, | ||
815 | .ctrls = sd_ctrls, | ||
816 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
817 | .config = sd_config, | ||
818 | .open = sd_open, | ||
819 | .start = sd_start, | ||
820 | .stopN = sd_stopN, | ||
821 | .stop0 = sd_stop0, | ||
822 | .close = sd_close, | ||
823 | .pkt_scan = sd_pkt_scan, | ||
824 | }; | ||
825 | |||
826 | /* -- module initialisation -- */ | ||
827 | #define DVNM(name) .driver_info = (kernel_ulong_t) name | ||
828 | static __devinitdata struct usb_device_id device_table[] = { | ||
829 | {USB_DEVICE(0x0c45, 0x6001), DVNM("Genius VideoCAM NB")}, | ||
830 | {USB_DEVICE(0x0c45, 0x6005), DVNM("Sweex Tas5110")}, | ||
831 | {USB_DEVICE(0x0c45, 0x6007), DVNM("Sonix sn9c101 + Tas5110D")}, | ||
832 | {USB_DEVICE(0x0c45, 0x6009), DVNM("spcaCam@120")}, | ||
833 | {USB_DEVICE(0x0c45, 0x600d), DVNM("spcaCam@120")}, | ||
834 | {USB_DEVICE(0x0c45, 0x6011), DVNM("MAX Webcam Microdia-OV6650-SN9C101G")}, | ||
835 | {USB_DEVICE(0x0c45, 0x6019), DVNM("Generic Sonix OV7630")}, | ||
836 | {USB_DEVICE(0x0c45, 0x6024), DVNM("Generic Sonix Tas5130c")}, | ||
837 | {USB_DEVICE(0x0c45, 0x6025), DVNM("Xcam Shanga")}, | ||
838 | {USB_DEVICE(0x0c45, 0x6028), DVNM("Sonix Btc Pc380")}, | ||
839 | {USB_DEVICE(0x0c45, 0x6029), DVNM("spcaCam@150")}, | ||
840 | {USB_DEVICE(0x0c45, 0x602c), DVNM("Generic Sonix OV7630")}, | ||
841 | {USB_DEVICE(0x0c45, 0x602d), DVNM("LIC-200 LG")}, | ||
842 | {USB_DEVICE(0x0c45, 0x602e), DVNM("Genius VideoCam Messenger")}, | ||
843 | {USB_DEVICE(0x0c45, 0x60af), DVNM("Trust WB3100P")}, | ||
844 | {USB_DEVICE(0x0c45, 0x60b0), DVNM("Genius VideoCam Look")}, | ||
845 | {} | ||
846 | }; | ||
847 | MODULE_DEVICE_TABLE(usb, device_table); | ||
848 | |||
849 | /* -- device connect -- */ | ||
850 | static int sd_probe(struct usb_interface *intf, | ||
851 | const struct usb_device_id *id) | ||
852 | { | ||
853 | return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), | ||
854 | THIS_MODULE); | ||
855 | } | ||
856 | |||
857 | static struct usb_driver sd_driver = { | ||
858 | .name = MODULE_NAME, | ||
859 | .id_table = device_table, | ||
860 | .probe = sd_probe, | ||
861 | .disconnect = gspca_disconnect, | ||
862 | }; | ||
863 | |||
864 | /* -- module insert / remove -- */ | ||
865 | static int __init sd_mod_init(void) | ||
866 | { | ||
867 | if (usb_register(&sd_driver) < 0) | ||
868 | return -1; | ||
869 | PDEBUG(D_PROBE, "v%s registered", version); | ||
870 | return 0; | ||
871 | } | ||
872 | static void __exit sd_mod_exit(void) | ||
873 | { | ||
874 | usb_deregister(&sd_driver); | ||
875 | PDEBUG(D_PROBE, "deregistered"); | ||
876 | } | ||
877 | |||
878 | module_init(sd_mod_init); | ||
879 | module_exit(sd_mod_exit); | ||
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c new file mode 100644 index 000000000000..6180bc565ca1 --- /dev/null +++ b/drivers/media/video/gspca/sonixj.c | |||
@@ -0,0 +1,1629 @@ | |||
1 | /* | ||
2 | * Sonix sn9c102p sn9c105 sn9c120 (jpeg) library | ||
3 | * Copyright (C) 2005 Michel Xhaard mxhaard@magic.fr | ||
4 | * | ||
5 | * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | #define MODULE_NAME "sonixj" | ||
23 | |||
24 | #include "gspca.h" | ||
25 | #include "jpeg.h" | ||
26 | |||
27 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) | ||
28 | static const char version[] = "2.1.0"; | ||
29 | |||
30 | MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); | ||
31 | MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver"); | ||
32 | MODULE_LICENSE("GPL"); | ||
33 | |||
34 | /* specific webcam descriptor */ | ||
35 | struct sd { | ||
36 | struct gspca_dev gspca_dev; /* !! must be the first item */ | ||
37 | |||
38 | int avg_lum; | ||
39 | unsigned int exposure; | ||
40 | |||
41 | unsigned short brightness; | ||
42 | unsigned char contrast; | ||
43 | unsigned char colors; | ||
44 | unsigned char autogain; | ||
45 | |||
46 | signed char ag_cnt; | ||
47 | #define AG_CNT_START 13 | ||
48 | |||
49 | char qindex; | ||
50 | char sensor; /* Type of image sensor chip */ | ||
51 | #define SENSOR_HV7131R 0 | ||
52 | #define SENSOR_MI0360 1 | ||
53 | #define SENSOR_MO4000 2 | ||
54 | #define SENSOR_OV7648 3 | ||
55 | #define SENSOR_OV7660 4 | ||
56 | unsigned char customid; | ||
57 | #define SN9C102P 0 | ||
58 | #define SN9C105 1 | ||
59 | #define SN9C110 2 | ||
60 | #define SN9C120 3 | ||
61 | #define SN9C325 4 | ||
62 | unsigned char i2c_base; | ||
63 | unsigned char i2c_ctrl_reg; | ||
64 | }; | ||
65 | |||
66 | /* V4L2 controls supported by the driver */ | ||
67 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
68 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
69 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | ||
70 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | ||
71 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); | ||
72 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); | ||
73 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); | ||
74 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); | ||
75 | |||
76 | static struct ctrl sd_ctrls[] = { | ||
77 | #define SD_BRIGHTNESS 0 | ||
78 | { | ||
79 | { | ||
80 | .id = V4L2_CID_BRIGHTNESS, | ||
81 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
82 | .name = "Brightness", | ||
83 | .minimum = 0, | ||
84 | .maximum = 0xffff, | ||
85 | .step = 1, | ||
86 | .default_value = 0x7fff, | ||
87 | }, | ||
88 | .set = sd_setbrightness, | ||
89 | .get = sd_getbrightness, | ||
90 | }, | ||
91 | #define SD_CONTRAST 1 | ||
92 | { | ||
93 | { | ||
94 | .id = V4L2_CID_CONTRAST, | ||
95 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
96 | .name = "Contrast", | ||
97 | .minimum = 0, | ||
98 | .maximum = 127, | ||
99 | .step = 1, | ||
100 | .default_value = 63, | ||
101 | }, | ||
102 | .set = sd_setcontrast, | ||
103 | .get = sd_getcontrast, | ||
104 | }, | ||
105 | #define SD_COLOR 2 | ||
106 | { | ||
107 | { | ||
108 | .id = V4L2_CID_SATURATION, | ||
109 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
110 | .name = "Color", | ||
111 | .minimum = 0, | ||
112 | .maximum = 255, | ||
113 | .step = 1, | ||
114 | .default_value = 127, | ||
115 | }, | ||
116 | .set = sd_setcolors, | ||
117 | .get = sd_getcolors, | ||
118 | }, | ||
119 | #define SD_AUTOGAIN 3 | ||
120 | { | ||
121 | { | ||
122 | .id = V4L2_CID_AUTOGAIN, | ||
123 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
124 | .name = "Auto Gain", | ||
125 | .minimum = 0, | ||
126 | .maximum = 1, | ||
127 | .step = 1, | ||
128 | .default_value = 1, | ||
129 | }, | ||
130 | .set = sd_setautogain, | ||
131 | .get = sd_getautogain, | ||
132 | }, | ||
133 | }; | ||
134 | |||
135 | static struct cam_mode vga_mode[] = { | ||
136 | {V4L2_PIX_FMT_JPEG, 160, 120, 2}, | ||
137 | {V4L2_PIX_FMT_JPEG, 320, 240, 1}, | ||
138 | {V4L2_PIX_FMT_JPEG, 640, 480, 0}, | ||
139 | }; | ||
140 | |||
141 | /*Data from sn9c102p+hv71331r */ | ||
142 | static __u8 sn_hv7131[] = { | ||
143 | 0x00, 0x03, 0x64, 0x00, 0x1A, 0x20, 0x20, 0x20, 0xA1, 0x11, | ||
144 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 reg9 */ | ||
145 | 0x02, 0x09, 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, /* 00 */ | ||
146 | /* rega regb regc regd rege regf reg10 reg11 */ | ||
147 | 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41, 0x0a, 0x00, 0x00, 0x00, | ||
148 | /* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a reg1b */ | ||
149 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | ||
150 | /* reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23 */ | ||
151 | }; | ||
152 | |||
153 | static __u8 sn_mi0360[] = { | ||
154 | 0x00, 0x61, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0xb1, 0x5d, | ||
155 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 reg9 */ | ||
156 | 0x07, 0x00, 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, | ||
157 | /* rega regb regc regd rege regf reg10 reg11 */ | ||
158 | 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61, 0x06, 0x00, 0x00, 0x00, | ||
159 | /* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a reg1b */ | ||
160 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | ||
161 | /* reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23 */ | ||
162 | }; | ||
163 | |||
164 | static __u8 sn_mo4000[] = { | ||
165 | 0x12, 0x23, 0x60, 0x00, 0x1A, 0x00, 0x20, 0x18, 0x81, | ||
166 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 */ | ||
167 | 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, | ||
168 | /* reg9 rega regb regc regd rege regf reg10 reg11*/ | ||
169 | 0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40, 0x08, 0x00, 0x00, | ||
170 | /* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a*/ | ||
171 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x25, 0x39, 0x4b, | ||
172 | /* reg1b reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23*/ | ||
173 | 0x5c, 0x6b, 0x79, 0x87, 0x95, 0xa2, 0xaf, 0xbb, 0xc7, | ||
174 | 0xd3, 0xdf, 0xea, 0xf5 | ||
175 | }; | ||
176 | |||
177 | static __u8 sn_ov7648[] = { | ||
178 | 0x00, 0x21, 0x62, 0x00, 0x1a, 0x20, 0x20, 0x20, 0xA1, 0x6E, 0x18, 0x65, | ||
179 | 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, 0x00, 0x06, 0x06, 0x28, 0x1E, 0x82, | ||
180 | 0x07, 0x00, 0x00, 0x00, 0x00, 0x00 | ||
181 | }; | ||
182 | |||
183 | static __u8 sn_ov7660[] = { | ||
184 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 */ | ||
185 | 0x00, 0x61, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x81, | ||
186 | /* reg9 rega regb regc regd rege regf reg10 reg11*/ | ||
187 | 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, | ||
188 | /* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a*/ | ||
189 | 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20, 0x07, 0x00, 0x00, | ||
190 | /* reg1b reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23*/ | ||
191 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | ||
192 | }; | ||
193 | |||
194 | /* sequence specific to the sensors - !! index = SENSOR_xxx */ | ||
195 | static __u8 *sn_tb[] = { | ||
196 | sn_hv7131, | ||
197 | sn_mi0360, | ||
198 | sn_mo4000, | ||
199 | sn_ov7648, | ||
200 | sn_ov7660 | ||
201 | }; | ||
202 | |||
203 | static __u8 regsn20[] = { | ||
204 | 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99, | ||
205 | 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff | ||
206 | }; | ||
207 | static __u8 regsn20_sn9c325[] = { | ||
208 | 0x0a, 0x3a, 0x56, 0x6c, 0x7e, 0x8d, 0x9a, 0xa4, | ||
209 | 0xaf, 0xbb, 0xc5, 0xcd, 0xd5, 0xde, 0xe8, 0xed, 0xf5 | ||
210 | }; | ||
211 | |||
212 | static __u8 reg84[] = { | ||
213 | 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, 0xe5, 0x0f, | ||
214 | 0xe4, 0x0f, 0x38, 0x00, 0x3e, 0x00, 0xc3, 0x0f, | ||
215 | /* 0x00, 0x00, 0x00, 0x00, 0x00 */ | ||
216 | 0xf7, 0x0f, 0x0a, 0x00, 0x00 | ||
217 | }; | ||
218 | static __u8 reg84_sn9c325[] = { | ||
219 | 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, 0xe4, 0x0f, | ||
220 | 0xd3, 0x0f, 0x4b, 0x00, 0x48, 0x00, 0xc0, 0x0f, | ||
221 | 0xf8, 0x0f, 0x00, 0x00, 0x00 | ||
222 | }; | ||
223 | |||
224 | static __u8 hv7131r_sensor_init[][8] = { | ||
225 | {0xC1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10}, | ||
226 | {0xB1, 0x11, 0x34, 0x17, 0x7F, 0x00, 0x00, 0x10}, | ||
227 | {0xD1, 0x11, 0x40, 0xFF, 0x7F, 0x7F, 0x7F, 0x10}, | ||
228 | {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
229 | {0xD1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
230 | {0xD1, 0x11, 0x14, 0x01, 0xE2, 0x02, 0x82, 0x10}, | ||
231 | {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
232 | |||
233 | {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10}, | ||
234 | {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10}, | ||
235 | {0xC1, 0x11, 0x25, 0x00, 0x61, 0xA8, 0x00, 0x10}, | ||
236 | {0xA1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10}, | ||
237 | {0xC1, 0x11, 0x31, 0x20, 0x2E, 0x20, 0x00, 0x10}, | ||
238 | {0xC1, 0x11, 0x25, 0x00, 0xC3, 0x50, 0x00, 0x10}, | ||
239 | {0xA1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */ | ||
240 | {0xC1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */ | ||
241 | |||
242 | {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10}, | ||
243 | {0xA1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
244 | {0xA1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10}, | ||
245 | {0xA1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
246 | {0xA1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10}, | ||
247 | |||
248 | {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10}, | ||
249 | {0xA1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
250 | {0xA1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10}, | ||
251 | {0xA1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
252 | {0xA1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10}, | ||
253 | {0, 0, 0, 0, 0, 0, 0, 0} | ||
254 | }; | ||
255 | static __u8 mi0360_sensor_init[][8] = { | ||
256 | {0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, | ||
257 | {0xB1, 0x5D, 0x0D, 0x00, 0x01, 0x00, 0x00, 0x10}, | ||
258 | {0xB1, 0x5D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
259 | {0xD1, 0x5D, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10}, | ||
260 | {0xD1, 0x5D, 0x03, 0x01, 0xE2, 0x02, 0x82, 0x10}, | ||
261 | {0xD1, 0x5D, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10}, | ||
262 | {0xB1, 0x5D, 0x0D, 0x00, 0x02, 0x00, 0x00, 0x10}, | ||
263 | {0xD1, 0x5D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
264 | {0xD1, 0x5D, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
265 | {0xD1, 0x5D, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
266 | {0xD1, 0x5D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
267 | {0xD1, 0x5D, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
268 | {0xD1, 0x5D, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
269 | {0xD1, 0x5D, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
270 | {0xD1, 0x5D, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
271 | {0xD1, 0x5D, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
272 | {0xD1, 0x5D, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
273 | {0xB1, 0x5D, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
274 | {0xD1, 0x5D, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10}, | ||
275 | {0xD1, 0x5D, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
276 | {0xD1, 0x5D, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
277 | {0xD1, 0x5D, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10}, | ||
278 | {0xD1, 0x5D, 0x2F, 0xF7, 0xB0, 0x00, 0x04, 0x10}, | ||
279 | {0xD1, 0x5D, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
280 | {0xD1, 0x5D, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10}, | ||
281 | {0xB1, 0x5D, 0x3D, 0x06, 0x8F, 0x00, 0x00, 0x10}, | ||
282 | {0xD1, 0x5D, 0x40, 0x01, 0xE0, 0x00, 0xD1, 0x10}, | ||
283 | {0xB1, 0x5D, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10}, | ||
284 | {0xD1, 0x5D, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10}, | ||
285 | {0xD1, 0x5D, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
286 | {0xD1, 0x5D, 0x5C, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
287 | {0xD1, 0x5D, 0x5E, 0x00, 0x00, 0xA3, 0x1D, 0x10}, | ||
288 | {0xB1, 0x5D, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10}, | ||
289 | |||
290 | {0xB1, 0x5D, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10}, | ||
291 | {0xB1, 0x5D, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10}, | ||
292 | {0xB1, 0x5D, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10}, | ||
293 | {0xD1, 0x5D, 0x2B, 0x00, 0xA0, 0x00, 0xB0, 0x10}, | ||
294 | {0xD1, 0x5D, 0x2D, 0x00, 0xA0, 0x00, 0xA0, 0x10}, | ||
295 | |||
296 | {0xB1, 0x5D, 0x0A, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */ | ||
297 | {0xB1, 0x5D, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10}, | ||
298 | {0xB1, 0x5D, 0x05, 0x00, 0x0A, 0x00, 0x00, 0x10}, | ||
299 | {0xB1, 0x5D, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */ | ||
300 | |||
301 | {0xD1, 0x5D, 0x2B, 0x00, 0xB9, 0x00, 0xE3, 0x10}, | ||
302 | {0xD1, 0x5D, 0x2D, 0x00, 0x5f, 0x00, 0xB9, 0x10}, /* 42 */ | ||
303 | /* {0xB1, 0x5D, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */ | ||
304 | /* {0xB1, 0x5D, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */ | ||
305 | {0xB1, 0x5D, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */ | ||
306 | {0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */ | ||
307 | {0, 0, 0, 0, 0, 0, 0, 0} | ||
308 | }; | ||
309 | static __u8 mo4000_sensor_init[][8] = { | ||
310 | {0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10}, | ||
311 | {0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
312 | {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
313 | {0xa1, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
314 | {0xa1, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
315 | {0xa1, 0x21, 0x05, 0x04, 0x00, 0x00, 0x00, 0x10}, | ||
316 | {0xa1, 0x21, 0x06, 0x80, 0x00, 0x00, 0x00, 0x10}, | ||
317 | {0xa1, 0x21, 0x06, 0x81, 0x00, 0x00, 0x00, 0x10}, | ||
318 | {0xa1, 0x21, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
319 | {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
320 | {0xa1, 0x21, 0x11, 0x20, 0x00, 0x00, 0x00, 0x10}, | ||
321 | {0xa1, 0x21, 0x11, 0x30, 0x00, 0x00, 0x00, 0x10}, | ||
322 | {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10}, | ||
323 | {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10}, | ||
324 | {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
325 | {0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
326 | {0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10}, | ||
327 | {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, | ||
328 | {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
329 | {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10}, | ||
330 | {0, 0, 0, 0, 0, 0, 0, 0} | ||
331 | }; | ||
332 | static __u8 ov7660_sensor_init[][8] = { | ||
333 | {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */ | ||
334 | {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10}, | ||
335 | /* Outformat ?? rawRGB */ | ||
336 | {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */ | ||
337 | /* {0xd1, 0x21, 0x00, 0x01, 0x74, 0x92, 0x00, 0x10}, | ||
338 | * GAIN BLUE RED VREF */ | ||
339 | {0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10}, | ||
340 | /* GAIN BLUE RED VREF */ | ||
341 | {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10}, | ||
342 | /* COM 1 BAVE GEAVE AECHH */ | ||
343 | {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */ | ||
344 | {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */ | ||
345 | /* {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xf8, 0x10}, | ||
346 | * AECH CLKRC COM7 COM8 */ | ||
347 | {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10}, | ||
348 | /* AECH CLKRC COM7 COM8 */ | ||
349 | {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */ | ||
350 | {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10}, | ||
351 | /* HSTART HSTOP VSTRT VSTOP */ | ||
352 | {0xa1, 0x21, 0x1b, 0x02, 0x00, 0x00, 0x00, 0x10}, /* PSHFT */ | ||
353 | {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */ | ||
354 | {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10}, | ||
355 | /* BOS GBOS GROS ROS (BGGR offset) */ | ||
356 | /* {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, | ||
357 | * AEW AEB VPT BBIAS */ | ||
358 | {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10}, | ||
359 | /* AEW AEB VPT BBIAS */ | ||
360 | {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10}, | ||
361 | /* GbBIAS RSVD EXHCH EXHCL */ | ||
362 | {0xd1, 0x21, 0x2c, 0x80, 0x00, 0x00, 0x62, 0x10}, | ||
363 | /* RBIAS ADVFL ASDVFH YAVE */ | ||
364 | {0xc1, 0x21, 0x30, 0x08, 0x30, 0xb4, 0x00, 0x10}, | ||
365 | /* HSYST HSYEN HREF */ | ||
366 | {0xd1, 0x21, 0x33, 0x00, 0x07, 0x84, 0x00, 0x10}, /* reserved */ | ||
367 | {0xd1, 0x21, 0x37, 0x0c, 0x02, 0x43, 0x00, 0x10}, | ||
368 | /* ADC ACOM OFON TSLB */ | ||
369 | {0xd1, 0x21, 0x3b, 0x02, 0x6c, 0x19, 0x0e, 0x10}, | ||
370 | /* COM11 COM12 COM13 COM14 */ | ||
371 | {0xd1, 0x21, 0x3f, 0x41, 0xc1, 0x22, 0x08, 0x10}, | ||
372 | /* EDGE COM15 COM16 COM17 */ | ||
373 | {0xd1, 0x21, 0x43, 0xf0, 0x10, 0x78, 0xa8, 0x10}, /* reserved */ | ||
374 | {0xd1, 0x21, 0x47, 0x60, 0x80, 0x00, 0x00, 0x10}, /* reserved */ | ||
375 | {0xd1, 0x21, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* reserved */ | ||
376 | {0xd1, 0x21, 0x4f, 0x46, 0x36, 0x0f, 0x17, 0x10}, /* MTX 1 2 3 4 */ | ||
377 | {0xd1, 0x21, 0x53, 0x7f, 0x96, 0x40, 0x40, 0x10}, /* MTX 5 6 7 8 */ | ||
378 | {0xb1, 0x21, 0x57, 0x40, 0x0f, 0x00, 0x00, 0x10}, /* MTX9 MTXS */ | ||
379 | {0xd1, 0x21, 0x59, 0xba, 0x9a, 0x22, 0xb9, 0x10}, /* reserved */ | ||
380 | {0xd1, 0x21, 0x5d, 0x9b, 0x10, 0xf0, 0x05, 0x10}, /* reserved */ | ||
381 | {0xa1, 0x21, 0x61, 0x60, 0x00, 0x00, 0x00, 0x10}, /* reserved */ | ||
382 | {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10}, | ||
383 | /* LCC1 LCC2 LCC3 LCC4 */ | ||
384 | {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */ | ||
385 | {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, | ||
386 | {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10}, | ||
387 | /* band gap reference [0..3] DBLV */ | ||
388 | {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */ | ||
389 | {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */ | ||
390 | {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */ | ||
391 | {0xd1, 0x21, 0x78, 0x34, 0x30, 0x2f, 0x2b, 0x10}, /* gamma curve */ | ||
392 | {0xd1, 0x21, 0x7c, 0x03, 0x07, 0x17, 0x34, 0x10}, /* gamma curve */ | ||
393 | {0xd1, 0x21, 0x80, 0x41, 0x4d, 0x58, 0x63, 0x10}, /* gamma curve */ | ||
394 | {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */ | ||
395 | {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */ | ||
396 | {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */ | ||
397 | {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
398 | /****** (some exchanges in the win trace) ******/ | ||
399 | {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, | ||
400 | /* bits[3..0]reserved */ | ||
401 | {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, | ||
402 | {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
403 | /* VREF vertical frame ctrl */ | ||
404 | {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
405 | {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* 0x20 */ | ||
406 | {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
407 | {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
408 | {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, | ||
409 | /* {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, */ | ||
410 | /****** (some exchanges in the win trace) ******/ | ||
411 | {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */ | ||
412 | {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10},/* dummy line low */ | ||
413 | {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
414 | {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
415 | /* {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, */ | ||
416 | /****** (some exchanges in the win trace) ******/ | ||
417 | /**********startsensor KO if changed !!****/ | ||
418 | {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10}, | ||
419 | {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10}, | ||
420 | {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
421 | {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10}, | ||
422 | /* here may start the isoc exchanges */ | ||
423 | {0, 0, 0, 0, 0, 0, 0, 0} | ||
424 | }; | ||
425 | /* reg0x04 reg0x07 reg 0x10 */ | ||
426 | /* expo = (COM1 & 0x02) | (AECHH & 0x2f <<10) [ (AECh << 2) */ | ||
427 | |||
428 | static __u8 ov7648_sensor_init[][8] = { | ||
429 | {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00}, | ||
430 | {0xC1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00}, | ||
431 | {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00}, | ||
432 | {0xA1, 0x6E, 0x3F, 0x20, 0x00, 0x00, 0x00, 0x10}, | ||
433 | {0xA1, 0x6E, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
434 | {0xA1, 0x6E, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
435 | {0xD1, 0x6E, 0x04, 0x02, 0xB1, 0x02, 0x39, 0x10}, | ||
436 | {0xD1, 0x6E, 0x08, 0x00, 0x01, 0x00, 0x00, 0x10}, | ||
437 | {0xD1, 0x6E, 0x0C, 0x02, 0x7F, 0x01, 0xE0, 0x10}, | ||
438 | {0xD1, 0x6E, 0x12, 0x03, 0x02, 0x00, 0x03, 0x10}, | ||
439 | {0xD1, 0x6E, 0x16, 0x85, 0x40, 0x4A, 0x40, 0x10}, | ||
440 | {0xC1, 0x6E, 0x1A, 0x00, 0x80, 0x00, 0x00, 0x10}, | ||
441 | {0xD1, 0x6E, 0x1D, 0x08, 0x03, 0x00, 0x00, 0x10}, | ||
442 | {0xD1, 0x6E, 0x23, 0x00, 0xB0, 0x00, 0x94, 0x10}, | ||
443 | {0xD1, 0x6E, 0x27, 0x58, 0x00, 0x00, 0x00, 0x10}, | ||
444 | {0xD1, 0x6E, 0x2D, 0x14, 0x35, 0x61, 0x84, 0x10}, | ||
445 | {0xD1, 0x6E, 0x31, 0xA2, 0xBD, 0xD8, 0xFF, 0x10}, | ||
446 | {0xD1, 0x6E, 0x35, 0x06, 0x1E, 0x12, 0x02, 0x10}, | ||
447 | {0xD1, 0x6E, 0x39, 0xAA, 0x53, 0x37, 0xD5, 0x10}, | ||
448 | {0xA1, 0x6E, 0x3D, 0xF2, 0x00, 0x00, 0x00, 0x10}, | ||
449 | {0xD1, 0x6E, 0x3E, 0x00, 0x00, 0x80, 0x03, 0x10}, | ||
450 | {0xD1, 0x6E, 0x42, 0x03, 0x00, 0x00, 0x00, 0x10}, | ||
451 | {0xC1, 0x6E, 0x46, 0x00, 0x80, 0x80, 0x00, 0x10}, | ||
452 | {0xD1, 0x6E, 0x4B, 0x02, 0xEF, 0x08, 0xCD, 0x10}, | ||
453 | {0xD1, 0x6E, 0x4F, 0x00, 0xD0, 0x00, 0xA0, 0x10}, | ||
454 | {0xD1, 0x6E, 0x53, 0x01, 0xAA, 0x01, 0x40, 0x10}, | ||
455 | {0xD1, 0x6E, 0x5A, 0x50, 0x04, 0x30, 0x03, 0x10}, | ||
456 | {0xA1, 0x6E, 0x5E, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
457 | {0xD1, 0x6E, 0x5F, 0x10, 0x40, 0xFF, 0x00, 0x10}, | ||
458 | /* {0xD1, 0x6E, 0x63, 0x40, 0x40, 0x00, 0x00, 0x10}, | ||
459 | {0xD1, 0x6E, 0x67, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
460 | * This is currently setting a | ||
461 | * blue tint, and some things more , i leave it here for future test if | ||
462 | * somene is having problems with color on this sensor | ||
463 | {0xD1, 0x6E, 0x6B, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
464 | {0xD1, 0x6E, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
465 | {0xC1, 0x6E, 0x73, 0x10, 0x80, 0xEB, 0x00, 0x10}, | ||
466 | {0xA1, 0x6E, 0x1E, 0x03, 0x00, 0x00, 0x00, 0x10}, | ||
467 | {0xA1, 0x6E, 0x15, 0x01, 0x00, 0x00, 0x00, 0x10}, | ||
468 | {0xC1, 0x6E, 0x16, 0x40, 0x40, 0x40, 0x00, 0x10}, | ||
469 | {0xA1, 0x6E, 0x1D, 0x08, 0x00, 0x00, 0x00, 0x10}, | ||
470 | {0xA1, 0x6E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10}, | ||
471 | {0xA1, 0x6E, 0x07, 0xB5, 0x00, 0x00, 0x00, 0x10}, | ||
472 | {0xA1, 0x6E, 0x18, 0x6B, 0x00, 0x00, 0x00, 0x10}, | ||
473 | {0xA1, 0x6E, 0x1D, 0x08, 0x00, 0x00, 0x00, 0x10}, | ||
474 | {0xA1, 0x6E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10}, | ||
475 | {0xA1, 0x6E, 0x07, 0xB8, 0x00, 0x00, 0x00, 0x10}, */ | ||
476 | {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00}, | ||
477 | {0xA1, 0x6E, 0x06, 0x03, 0x00, 0x00, 0x00, 0x10}, /* Bright... */ | ||
478 | {0xA1, 0x6E, 0x07, 0x66, 0x00, 0x00, 0x00, 0x10}, /* B.. */ | ||
479 | {0xC1, 0x6E, 0x1A, 0x03, 0x65, 0x90, 0x00, 0x10}, /* Bright/Witen....*/ | ||
480 | /* {0xC1, 0x6E, 0x16, 0x45, 0x40, 0x60, 0x00, 0x10}, * Bright/Witene */ | ||
481 | {0, 0, 0, 0, 0, 0, 0, 0} | ||
482 | }; | ||
483 | |||
484 | static __u8 qtable4[] = { | ||
485 | 0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06, 0x06, 0x06, 0x08, 0x06, | ||
486 | 0x06, 0x08, 0x0A, 0x11, | ||
487 | 0x0A, 0x0A, 0x08, 0x08, 0x0A, 0x15, 0x0F, 0x0F, 0x0C, 0x11, 0x19, 0x15, | ||
488 | 0x19, 0x19, 0x17, 0x15, | ||
489 | 0x17, 0x17, 0x1B, 0x1D, 0x25, 0x21, 0x1B, 0x1D, 0x23, 0x1D, 0x17, 0x17, | ||
490 | 0x21, 0x2E, 0x21, 0x23, | ||
491 | 0x27, 0x29, 0x2C, 0x2C, 0x2C, 0x19, 0x1F, 0x30, 0x32, 0x2E, 0x29, 0x32, | ||
492 | 0x25, 0x29, 0x2C, 0x29, | ||
493 | 0x06, 0x08, 0x08, 0x0A, 0x08, 0x0A, 0x13, 0x0A, 0x0A, 0x13, 0x29, 0x1B, | ||
494 | 0x17, 0x1B, 0x29, 0x29, | ||
495 | 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, | ||
496 | 0x29, 0x29, 0x29, 0x29, | ||
497 | 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, | ||
498 | 0x29, 0x29, 0x29, 0x29, | ||
499 | 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, | ||
500 | 0x29, 0x29, 0x29, 0x29 | ||
501 | }; | ||
502 | |||
503 | static void reg_r(struct usb_device *dev, | ||
504 | __u16 value, | ||
505 | __u8 *buffer, int len) | ||
506 | { | ||
507 | usb_control_msg(dev, | ||
508 | usb_rcvctrlpipe(dev, 0), | ||
509 | 0, | ||
510 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, | ||
511 | value, 0, | ||
512 | buffer, len, | ||
513 | 500); | ||
514 | } | ||
515 | |||
516 | static void reg_w(struct usb_device *dev, | ||
517 | __u16 value, | ||
518 | __u8 *buffer, | ||
519 | int len) | ||
520 | { | ||
521 | usb_control_msg(dev, | ||
522 | usb_sndctrlpipe(dev, 0), | ||
523 | 0x08, | ||
524 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, | ||
525 | value, 0, | ||
526 | buffer, len, | ||
527 | 500); | ||
528 | } | ||
529 | |||
530 | /* write 2 bytes */ | ||
531 | static void i2c_w2(struct gspca_dev *gspca_dev, | ||
532 | __u8 *buffer) | ||
533 | { | ||
534 | struct sd *sd = (struct sd *) gspca_dev; | ||
535 | struct usb_device *dev = gspca_dev->dev; | ||
536 | __u8 mode[8]; | ||
537 | |||
538 | /* is i2c ready */ | ||
539 | mode[0] = sd->i2c_ctrl_reg | (2 << 4); | ||
540 | mode[1] = sd->i2c_base; | ||
541 | mode[2] = buffer[0]; | ||
542 | mode[3] = buffer[1]; | ||
543 | mode[4] = 0; | ||
544 | mode[5] = 0; | ||
545 | mode[6] = 0; | ||
546 | mode[7] = 0x10; | ||
547 | reg_w(dev, 0x08, mode, 8); | ||
548 | } | ||
549 | |||
550 | /* write 8 bytes */ | ||
551 | static void i2c_w8(struct usb_device *dev, __u8 *buffer) | ||
552 | { | ||
553 | reg_w(dev, 0x08, buffer, 8); | ||
554 | msleep(1); | ||
555 | } | ||
556 | |||
557 | /* read 5 bytes */ | ||
558 | static void i2c_r5(struct gspca_dev *gspca_dev, __u8 reg, | ||
559 | __u8 *buffer) | ||
560 | { | ||
561 | struct sd *sd = (struct sd *) gspca_dev; | ||
562 | struct usb_device *dev = gspca_dev->dev; | ||
563 | __u8 mode[8]; | ||
564 | |||
565 | mode[0] = sd->i2c_ctrl_reg | 0x10; | ||
566 | mode[1] = sd->i2c_base; | ||
567 | mode[2] = reg; | ||
568 | mode[3] = 0; | ||
569 | mode[4] = 0; | ||
570 | mode[5] = 0; | ||
571 | mode[6] = 0; | ||
572 | mode[7] = 0x10; | ||
573 | i2c_w8(dev, mode); | ||
574 | mode[0] = sd->i2c_ctrl_reg | (5 << 4) | 0x02; | ||
575 | mode[2] = 0; | ||
576 | i2c_w8(dev, mode); | ||
577 | reg_r(dev, 0x0a, buffer, 5); | ||
578 | } | ||
579 | |||
580 | static int probesensor(struct gspca_dev *gspca_dev) | ||
581 | { | ||
582 | struct sd *sd = (struct sd *) gspca_dev; | ||
583 | struct usb_device *dev = gspca_dev->dev; | ||
584 | __u8 reg02; | ||
585 | static __u8 datasend[] = { 2, 0 }; | ||
586 | /* reg val1 val2 val3 val4 */ | ||
587 | __u8 datarecd[6]; | ||
588 | |||
589 | i2c_w2(gspca_dev, datasend); | ||
590 | /* should write 0xa1 0x11 0x02 0x00 0x00 0x00 0x00 the 0x10 is add by i2cw */ | ||
591 | msleep(10); | ||
592 | reg02 = 0x66; | ||
593 | reg_w(dev, 0x02, ®02, 1); /* Gpio on */ | ||
594 | msleep(10); | ||
595 | i2c_r5(gspca_dev, 0, datarecd); /* read sensor id */ | ||
596 | if (datarecd[0] == 0x02 | ||
597 | && datarecd[1] == 0x09 | ||
598 | && datarecd[2] == 0x01 | ||
599 | && datarecd[3] == 0x00 | ||
600 | && datarecd[4] == 0x00) { | ||
601 | PDEBUG(D_PROBE, "Find Sensor sn9c102P HV7131R"); | ||
602 | sd->sensor = SENSOR_HV7131R; | ||
603 | return SENSOR_HV7131R; | ||
604 | } | ||
605 | PDEBUG(D_PROBE, "Find Sensor %d %d %d", | ||
606 | datarecd[0], datarecd[1], datarecd[2]); | ||
607 | PDEBUG(D_PROBE, "Sensor sn9c102P Not found"); | ||
608 | return -ENODEV; | ||
609 | } | ||
610 | |||
611 | static int configure_gpio(struct gspca_dev *gspca_dev, | ||
612 | __u8 *sn9c1xx) | ||
613 | { | ||
614 | struct sd *sd = (struct sd *) gspca_dev; | ||
615 | struct usb_device *dev = gspca_dev->dev; | ||
616 | __u8 data; | ||
617 | __u8 regF1; | ||
618 | __u8 *reg9a; | ||
619 | static __u8 reg9a_def[] = | ||
620 | {0x08, 0x40, 0x20, 0x10, 0x00, 0x04}; | ||
621 | static __u8 reg9a_sn9c120[] = /* from win trace */ | ||
622 | {0x00, 0x40, 0x38, 0x30, 0x00, 0x20}; | ||
623 | static __u8 reg9a_sn9c325[] = | ||
624 | {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20}; | ||
625 | |||
626 | |||
627 | regF1 = 0x00; | ||
628 | reg_w(dev, 0xf1, ®F1, 1); | ||
629 | |||
630 | reg_w(dev, 0x01, &sn9c1xx[0], 1); /*fixme:jfm was [1] en v1*/ | ||
631 | |||
632 | /* configure gpio */ | ||
633 | reg_w(dev, 0x01, &sn9c1xx[1], 2); | ||
634 | reg_w(dev, 0x08, &sn9c1xx[8], 2); | ||
635 | reg_w(dev, 0x17, &sn9c1xx[0x17], 3); | ||
636 | switch (sd->customid) { | ||
637 | case SN9C325: | ||
638 | reg9a = reg9a_sn9c325; | ||
639 | break; | ||
640 | case SN9C120: | ||
641 | reg9a = reg9a_sn9c120; | ||
642 | break; | ||
643 | default: | ||
644 | reg9a = reg9a_def; | ||
645 | break; | ||
646 | } | ||
647 | reg_w(dev, 0x9a, reg9a, 6); | ||
648 | |||
649 | data = 0x60; /*fixme:jfm 60 00 00 (3) */ | ||
650 | reg_w(dev, 0xd4, &data, 1); | ||
651 | |||
652 | reg_w(dev, 0x03, &sn9c1xx[3], 0x0f); | ||
653 | |||
654 | switch (sd->customid) { | ||
655 | case SN9C120: /* from win trace */ | ||
656 | data = 0x61; | ||
657 | reg_w(dev, 0x01, &data, 1); | ||
658 | data = 0x20; | ||
659 | reg_w(dev, 0x17, &data, 1); | ||
660 | data = 0x60; | ||
661 | reg_w(dev, 0x01, &data, 1); | ||
662 | break; | ||
663 | case SN9C325: | ||
664 | data = 0x43; | ||
665 | reg_w(dev, 0x01, &data, 1); | ||
666 | data = 0xae; | ||
667 | reg_w(dev, 0x17, &data, 1); | ||
668 | data = 0x42; | ||
669 | reg_w(dev, 0x01, &data, 1); | ||
670 | break; | ||
671 | default: | ||
672 | data = 0x43; | ||
673 | reg_w(dev, 0x01, &data, 1); | ||
674 | data = 0x61; | ||
675 | reg_w(dev, 0x17, &data, 1); | ||
676 | data = 0x42; | ||
677 | reg_w(dev, 0x01, &data, 1); | ||
678 | } | ||
679 | |||
680 | if (sd->sensor == SENSOR_HV7131R) { | ||
681 | if (probesensor(gspca_dev) < 0) | ||
682 | return -ENODEV; | ||
683 | } | ||
684 | return 0; | ||
685 | } | ||
686 | |||
687 | static void hv7131R_InitSensor(struct gspca_dev *gspca_dev) | ||
688 | { | ||
689 | int i = 0; | ||
690 | struct usb_device *dev = gspca_dev->dev; | ||
691 | static __u8 SetSensorClk[] = /* 0x08 Mclk */ | ||
692 | { 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 }; | ||
693 | |||
694 | while (hv7131r_sensor_init[i][0]) { | ||
695 | i2c_w8(dev, hv7131r_sensor_init[i]); | ||
696 | i++; | ||
697 | } | ||
698 | i2c_w8(dev, SetSensorClk); | ||
699 | } | ||
700 | |||
701 | static void mi0360_InitSensor(struct gspca_dev *gspca_dev) | ||
702 | { | ||
703 | int i = 0; | ||
704 | struct usb_device *dev = gspca_dev->dev; | ||
705 | |||
706 | while (mi0360_sensor_init[i][0]) { | ||
707 | i2c_w8(dev, mi0360_sensor_init[i]); | ||
708 | i++; | ||
709 | } | ||
710 | } | ||
711 | |||
712 | static void mo4000_InitSensor(struct gspca_dev *gspca_dev) | ||
713 | { | ||
714 | int i = 0; | ||
715 | struct usb_device *dev = gspca_dev->dev; | ||
716 | |||
717 | while (mo4000_sensor_init[i][0]) { | ||
718 | i2c_w8(dev, mo4000_sensor_init[i]); | ||
719 | i++; | ||
720 | } | ||
721 | } | ||
722 | |||
723 | static void ov7648_InitSensor(struct gspca_dev *gspca_dev) | ||
724 | { | ||
725 | struct usb_device *dev = gspca_dev->dev; | ||
726 | int i = 0; | ||
727 | |||
728 | while (ov7648_sensor_init[i][0]) { | ||
729 | i2c_w8(dev, ov7648_sensor_init[i]); | ||
730 | i++; | ||
731 | } | ||
732 | } | ||
733 | |||
734 | static void ov7660_InitSensor(struct gspca_dev *gspca_dev) | ||
735 | { | ||
736 | int i = 0; | ||
737 | struct usb_device *dev = gspca_dev->dev; | ||
738 | |||
739 | while (ov7660_sensor_init[i][0]) { | ||
740 | i2c_w8(dev, ov7660_sensor_init[i]); | ||
741 | i++; | ||
742 | } | ||
743 | } | ||
744 | |||
745 | /* this function is called at probe time */ | ||
746 | static int sd_config(struct gspca_dev *gspca_dev, | ||
747 | const struct usb_device_id *id) | ||
748 | { | ||
749 | struct sd *sd = (struct sd *) gspca_dev; | ||
750 | struct cam *cam; | ||
751 | __u16 vendor; | ||
752 | __u16 product; | ||
753 | |||
754 | vendor = id->idVendor; | ||
755 | product = id->idProduct; | ||
756 | sd->sensor = -1; | ||
757 | switch (vendor) { | ||
758 | case 0x0458: /* Genius */ | ||
759 | /* switch (product) { | ||
760 | case 0x7025: */ | ||
761 | sd->customid = SN9C120; | ||
762 | sd->sensor = SENSOR_MI0360; | ||
763 | sd->i2c_ctrl_reg = 0x81; | ||
764 | sd->i2c_base = 0x5d; | ||
765 | /* break; | ||
766 | } */ | ||
767 | break; | ||
768 | case 0x045e: | ||
769 | /* switch (product) { | ||
770 | case 0x00f5: | ||
771 | case 0x00f7: */ | ||
772 | sd->customid = SN9C105; | ||
773 | sd->sensor = SENSOR_OV7660; | ||
774 | sd->i2c_ctrl_reg = 0x81; | ||
775 | sd->i2c_base = 0x21; | ||
776 | /* break; | ||
777 | } */ | ||
778 | break; | ||
779 | case 0x0471: /* Philips */ | ||
780 | /* switch (product) { | ||
781 | case 0x0327: | ||
782 | case 0x0328: | ||
783 | case 0x0330: */ | ||
784 | sd->customid = SN9C105; | ||
785 | sd->sensor = SENSOR_MI0360; | ||
786 | sd->i2c_ctrl_reg = 0x81; | ||
787 | sd->i2c_base = 0x5d; | ||
788 | /* break; | ||
789 | } */ | ||
790 | break; | ||
791 | case 0x0c45: /* Sonix */ | ||
792 | switch (product) { | ||
793 | case 0x6040: | ||
794 | sd->customid = SN9C102P; | ||
795 | sd->sensor = SENSOR_MI0360; /* from BW600.inf */ | ||
796 | /* sd->sensor = SENSOR_HV7131R; * gspcav1 value */ | ||
797 | sd->i2c_ctrl_reg = 0x81; | ||
798 | sd->i2c_base = 0x11; | ||
799 | break; | ||
800 | /* case 0x607a: * from BW600.inf | ||
801 | sd->customid = SN9C102P; | ||
802 | sd->sensor = SENSOR_OV7648; | ||
803 | sd->i2c_ctrl_reg = 0x??; | ||
804 | sd->i2c_base = 0x??; | ||
805 | break; */ | ||
806 | case 0x607c: | ||
807 | sd->customid = SN9C102P; | ||
808 | sd->sensor = SENSOR_HV7131R; | ||
809 | sd->i2c_ctrl_reg = 0x81; | ||
810 | sd->i2c_base = 0x11; | ||
811 | break; | ||
812 | /* case 0x607e: * from BW600.inf | ||
813 | sd->customid = SN9C102P; | ||
814 | sd->sensor = SENSOR_OV7630; | ||
815 | sd->i2c_ctrl_reg = 0x??; | ||
816 | sd->i2c_base = 0x??; | ||
817 | break; */ | ||
818 | case 0x60c0: | ||
819 | sd->customid = SN9C105; | ||
820 | sd->sensor = SENSOR_MI0360; | ||
821 | sd->i2c_ctrl_reg = 0x81; | ||
822 | sd->i2c_base = 0x5d; | ||
823 | break; | ||
824 | /* case 0x60c8: * from BW600.inf | ||
825 | sd->customid = SN9C105; | ||
826 | sd->sensor = SENSOR_OM6801; | ||
827 | sd->i2c_ctrl_reg = 0x??; | ||
828 | sd->i2c_base = 0x??; | ||
829 | break; */ | ||
830 | /* case 0x60cc: * from BW600.inf | ||
831 | sd->customid = SN9C105; | ||
832 | sd->sensor = SENSOR_HV7131GP; | ||
833 | sd->i2c_ctrl_reg = 0x??; | ||
834 | sd->i2c_base = 0x??; | ||
835 | break; */ | ||
836 | case 0x60ec: | ||
837 | sd->customid = SN9C105; | ||
838 | sd->sensor = SENSOR_MO4000; | ||
839 | sd->i2c_ctrl_reg = 0x81; | ||
840 | sd->i2c_base = 0x21; | ||
841 | break; | ||
842 | /* case 0x60ef: * from BW600.inf | ||
843 | sd->customid = SN9C105; | ||
844 | sd->sensor = SENSOR_ICM105C; | ||
845 | sd->i2c_ctrl_reg = 0x??; | ||
846 | sd->i2c_base = 0x??; | ||
847 | break; */ | ||
848 | /* case 0x60fa: * from BW600.inf | ||
849 | sd->customid = SN9C105; | ||
850 | sd->sensor = SENSOR_OV7648; | ||
851 | sd->i2c_ctrl_reg = 0x??; | ||
852 | sd->i2c_base = 0x??; | ||
853 | break; */ | ||
854 | case 0x60fb: | ||
855 | sd->customid = SN9C105; | ||
856 | sd->sensor = SENSOR_OV7660; | ||
857 | sd->i2c_ctrl_reg = 0x81; | ||
858 | sd->i2c_base = 0x21; | ||
859 | break; | ||
860 | case 0x60fc: | ||
861 | sd->customid = SN9C105; | ||
862 | sd->sensor = SENSOR_HV7131R; | ||
863 | sd->i2c_ctrl_reg = 0x81; | ||
864 | sd->i2c_base = 0x11; | ||
865 | break; | ||
866 | /* case 0x60fe: * from BW600.inf | ||
867 | sd->customid = SN9C105; | ||
868 | sd->sensor = SENSOR_OV7630; | ||
869 | sd->i2c_ctrl_reg = 0x??; | ||
870 | sd->i2c_base = 0x??; | ||
871 | break; */ | ||
872 | /* case 0x6108: * from BW600.inf | ||
873 | sd->customid = SN9C120; | ||
874 | sd->sensor = SENSOR_OM6801; | ||
875 | sd->i2c_ctrl_reg = 0x??; | ||
876 | sd->i2c_base = 0x??; | ||
877 | break; */ | ||
878 | /* case 0x6122: * from BW600.inf | ||
879 | sd->customid = SN9C110; | ||
880 | sd->sensor = SENSOR_ICM105C; | ||
881 | sd->i2c_ctrl_reg = 0x??; | ||
882 | sd->i2c_base = 0x??; | ||
883 | break; */ | ||
884 | case 0x612a: | ||
885 | /* sd->customid = SN9C110; * in BW600.inf */ | ||
886 | sd->customid = SN9C325; | ||
887 | sd->sensor = SENSOR_OV7648; | ||
888 | sd->i2c_ctrl_reg = 0x81; | ||
889 | sd->i2c_base = 0x21; | ||
890 | break; | ||
891 | /* case 0x6123: * from BW600.inf | ||
892 | sd->customid = SN9C110; | ||
893 | sd->sensor = SENSOR_SanyoCCD; | ||
894 | sd->i2c_ctrl_reg = 0x??; | ||
895 | sd->i2c_base = 0x??; | ||
896 | break; */ | ||
897 | case 0x612c: | ||
898 | sd->customid = SN9C110; | ||
899 | sd->sensor = SENSOR_MO4000; | ||
900 | sd->i2c_ctrl_reg = 0x81; | ||
901 | sd->i2c_base = 0x21; | ||
902 | break; | ||
903 | /* case 0x612e: * from BW600.inf | ||
904 | sd->customid = SN9C110; | ||
905 | sd->sensor = SENSOR_OV7630; | ||
906 | sd->i2c_ctrl_reg = 0x??; | ||
907 | sd->i2c_base = 0x??; | ||
908 | break; */ | ||
909 | /* case 0x612f: * from BW600.inf | ||
910 | sd->customid = SN9C110; | ||
911 | sd->sensor = SENSOR_ICM105C; | ||
912 | sd->i2c_ctrl_reg = 0x??; | ||
913 | sd->i2c_base = 0x??; | ||
914 | break; */ | ||
915 | case 0x6130: | ||
916 | sd->customid = SN9C120; | ||
917 | sd->sensor = SENSOR_MI0360; | ||
918 | sd->i2c_ctrl_reg = 0x81; | ||
919 | sd->i2c_base = 0x5d; | ||
920 | break; | ||
921 | case 0x6138: | ||
922 | sd->customid = SN9C120; | ||
923 | sd->sensor = SENSOR_MO4000; | ||
924 | sd->i2c_ctrl_reg = 0x81; | ||
925 | sd->i2c_base = 0x21; | ||
926 | break; | ||
927 | /* case 0x613a: * from BW600.inf | ||
928 | sd->customid = SN9C120; | ||
929 | sd->sensor = SENSOR_OV7648; | ||
930 | sd->i2c_ctrl_reg = 0x??; | ||
931 | sd->i2c_base = 0x??; | ||
932 | break; */ | ||
933 | case 0x613b: | ||
934 | sd->customid = SN9C120; | ||
935 | sd->sensor = SENSOR_OV7660; | ||
936 | sd->i2c_ctrl_reg = 0x81; | ||
937 | sd->i2c_base = 0x21; | ||
938 | break; | ||
939 | case 0x613c: | ||
940 | sd->customid = SN9C120; | ||
941 | sd->sensor = SENSOR_HV7131R; | ||
942 | sd->i2c_ctrl_reg = 0x81; | ||
943 | sd->i2c_base = 0x11; | ||
944 | break; | ||
945 | /* case 0x613e: * from BW600.inf | ||
946 | sd->customid = SN9C120; | ||
947 | sd->sensor = SENSOR_OV7630; | ||
948 | sd->i2c_ctrl_reg = 0x??; | ||
949 | sd->i2c_base = 0x??; | ||
950 | break; */ | ||
951 | } | ||
952 | break; | ||
953 | } | ||
954 | if (sd->sensor < 0) { | ||
955 | PDEBUG(D_ERR, "Invalid vendor/product %04x:%04x", | ||
956 | vendor, product); | ||
957 | return -EINVAL; | ||
958 | } | ||
959 | |||
960 | cam = &gspca_dev->cam; | ||
961 | cam->dev_name = (char *) id->driver_info; | ||
962 | cam->epaddr = 0x01; | ||
963 | cam->cam_mode = vga_mode; | ||
964 | cam->nmodes = ARRAY_SIZE(vga_mode); | ||
965 | sd->qindex = 4; /* set the quantization table */ | ||
966 | sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; | ||
967 | sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; | ||
968 | sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; | ||
969 | sd->autogain = sd_ctrls[SD_AUTOGAIN].qctrl.default_value; | ||
970 | return 0; | ||
971 | } | ||
972 | |||
973 | /* this function is called at open time */ | ||
974 | static int sd_open(struct gspca_dev *gspca_dev) | ||
975 | { | ||
976 | struct sd *sd = (struct sd *) gspca_dev; | ||
977 | struct usb_device *dev = gspca_dev->dev; | ||
978 | /* __u8 *sn9c1xx; */ | ||
979 | __u8 regF1; | ||
980 | __u8 regGpio[] = { 0x29, 0x74 }; | ||
981 | |||
982 | /* setup a selector by customid */ | ||
983 | regF1 = 0x01; | ||
984 | reg_w(dev, 0xf1, ®F1, 1); | ||
985 | reg_r(dev, 0x00, ®F1, 1); /* -> regF1 = 0x00 */ | ||
986 | reg_w(dev, 0xf1, ®F1, 1); | ||
987 | reg_r(dev, 0x00, ®F1, 1); | ||
988 | switch (sd->customid) { | ||
989 | case SN9C102P: | ||
990 | if (regF1 != 0x11) | ||
991 | return -ENODEV; | ||
992 | reg_w(dev, 0x02, ®Gpio[1], 1); | ||
993 | break; | ||
994 | case SN9C105: | ||
995 | if (regF1 != 0x11) | ||
996 | return -ENODEV; | ||
997 | reg_w(dev, 0x02, regGpio, 2); | ||
998 | break; | ||
999 | case SN9C110: | ||
1000 | if (regF1 != 0x12) | ||
1001 | return -ENODEV; | ||
1002 | regGpio[1] = 0x62; | ||
1003 | reg_w(dev, 0x02, ®Gpio[1], 1); | ||
1004 | break; | ||
1005 | case SN9C120: | ||
1006 | if (regF1 != 0x12) | ||
1007 | return -ENODEV; | ||
1008 | regGpio[1] = 0x70; | ||
1009 | reg_w(dev, 0x02, regGpio, 2); | ||
1010 | break; | ||
1011 | default: | ||
1012 | /* case SN9C325: */ | ||
1013 | if (regF1 != 0x12) | ||
1014 | return -ENODEV; | ||
1015 | regGpio[1] = 0x62; | ||
1016 | reg_w(dev, 0x02, ®Gpio[1], 1); | ||
1017 | break; | ||
1018 | } | ||
1019 | |||
1020 | regF1 = 0x01; | ||
1021 | reg_w(dev, 0xf1, ®F1, 1); | ||
1022 | |||
1023 | return 0; | ||
1024 | } | ||
1025 | |||
1026 | static unsigned int setexposure(struct gspca_dev *gspca_dev, | ||
1027 | unsigned int expo) | ||
1028 | { | ||
1029 | struct sd *sd = (struct sd *) gspca_dev; | ||
1030 | static __u8 doit[] = /* update sensor */ | ||
1031 | { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 }; | ||
1032 | static __u8 sensorgo[] = /* sensor on */ | ||
1033 | { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 }; | ||
1034 | static __u8 gainMo[] = | ||
1035 | { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d }; | ||
1036 | |||
1037 | switch (sd->sensor) { | ||
1038 | case SENSOR_HV7131R: { | ||
1039 | __u8 Expodoit[] = | ||
1040 | { 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 }; | ||
1041 | |||
1042 | Expodoit[3] = expo >> 16; | ||
1043 | Expodoit[4] = expo >> 8; | ||
1044 | Expodoit[5] = expo; | ||
1045 | i2c_w8(gspca_dev->dev, Expodoit); | ||
1046 | break; | ||
1047 | } | ||
1048 | case SENSOR_MI0360: { | ||
1049 | __u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */ | ||
1050 | { 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 }; | ||
1051 | |||
1052 | if (expo > 0x0635) | ||
1053 | expo = 0x0635; | ||
1054 | else if (expo < 0x0001) | ||
1055 | expo = 0x0001; | ||
1056 | expoMi[3] = expo >> 8; | ||
1057 | expoMi[4] = expo; | ||
1058 | i2c_w8(gspca_dev->dev, expoMi); | ||
1059 | i2c_w8(gspca_dev->dev, doit); | ||
1060 | i2c_w8(gspca_dev->dev, sensorgo); | ||
1061 | break; | ||
1062 | } | ||
1063 | case SENSOR_MO4000: { | ||
1064 | __u8 expoMof[] = | ||
1065 | { 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 }; | ||
1066 | __u8 expoMo10[] = | ||
1067 | { 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 }; | ||
1068 | |||
1069 | if (expo > 0x1fff) | ||
1070 | expo = 0x1fff; | ||
1071 | else if (expo < 0x0001) | ||
1072 | expo = 0x0001; | ||
1073 | expoMof[3] = (expo & 0x03fc) >> 2; | ||
1074 | i2c_w8(gspca_dev->dev, expoMof); | ||
1075 | expoMo10[3] = ((expo & 0x1c00) >> 10) | ||
1076 | | ((expo & 0x0003) << 4); | ||
1077 | i2c_w8(gspca_dev->dev, expoMo10); | ||
1078 | i2c_w8(gspca_dev->dev, gainMo); | ||
1079 | PDEBUG(D_CONF," set exposure %d", | ||
1080 | ((expoMo10[3] & 0x07) << 10) | ||
1081 | | (expoMof[3] << 2) | ||
1082 | | ((expoMo10[3] & 0x30) >> 4)); | ||
1083 | break; | ||
1084 | } | ||
1085 | } | ||
1086 | return expo; | ||
1087 | } | ||
1088 | |||
1089 | static void setbrightness(struct gspca_dev *gspca_dev) | ||
1090 | { | ||
1091 | struct sd *sd = (struct sd *) gspca_dev; | ||
1092 | unsigned int expo; | ||
1093 | __u8 k2; | ||
1094 | |||
1095 | switch (sd->sensor) { | ||
1096 | case SENSOR_HV7131R: | ||
1097 | expo = sd->brightness << 4; | ||
1098 | if (expo > 0x002dc6c0) | ||
1099 | expo = 0x002dc6c0; | ||
1100 | else if (expo < 0x02a0) | ||
1101 | expo = 0x02a0; | ||
1102 | sd->exposure = setexposure(gspca_dev, expo); | ||
1103 | break; | ||
1104 | case SENSOR_MI0360: | ||
1105 | expo = sd->brightness >> 4; | ||
1106 | sd->exposure = setexposure(gspca_dev, expo); | ||
1107 | break; | ||
1108 | case SENSOR_MO4000: | ||
1109 | expo = sd->brightness >> 4; | ||
1110 | sd->exposure = setexposure(gspca_dev, expo); | ||
1111 | break; | ||
1112 | case SENSOR_OV7660: | ||
1113 | return; /*jfm??*/ | ||
1114 | } | ||
1115 | |||
1116 | k2 = sd->brightness >> 10; | ||
1117 | reg_w(gspca_dev->dev, 0x96, &k2, 1); | ||
1118 | } | ||
1119 | |||
1120 | static void setcontrast(struct gspca_dev *gspca_dev) | ||
1121 | { | ||
1122 | struct sd *sd = (struct sd *) gspca_dev; | ||
1123 | __u8 k2; | ||
1124 | __u8 contrast[] = { 0x00, 0x00, 0x28, 0x00, 0x07, 0x00 }; | ||
1125 | |||
1126 | if (sd->sensor == SENSOR_OV7660) | ||
1127 | return; /*jfm??*/ | ||
1128 | k2 = sd->contrast; | ||
1129 | contrast[2] = k2; | ||
1130 | contrast[0] = (k2 + 1) >> 1; | ||
1131 | contrast[4] = (k2 + 1) / 5; | ||
1132 | reg_w(gspca_dev->dev, 0x84, contrast, 6); | ||
1133 | } | ||
1134 | |||
1135 | static void setcolors(struct gspca_dev *gspca_dev) | ||
1136 | { | ||
1137 | struct sd *sd = (struct sd *) gspca_dev; | ||
1138 | __u8 data; | ||
1139 | int colour; | ||
1140 | |||
1141 | colour = sd->colors - 128; | ||
1142 | if (colour > 0) | ||
1143 | data = (colour + 32) & 0x7f; /* blue */ | ||
1144 | else | ||
1145 | data = (-colour + 32) & 0x7f; /* red */ | ||
1146 | reg_w(gspca_dev->dev, 0x05, &data, 1); | ||
1147 | } | ||
1148 | |||
1149 | /* -- start the camera -- */ | ||
1150 | static void sd_start(struct gspca_dev *gspca_dev) | ||
1151 | { | ||
1152 | struct sd *sd = (struct sd *) gspca_dev; | ||
1153 | struct usb_device *dev = gspca_dev->dev; | ||
1154 | int i; | ||
1155 | __u8 data; | ||
1156 | __u8 reg1; | ||
1157 | __u8 reg17; | ||
1158 | __u8 *sn9c1xx; | ||
1159 | int mode; | ||
1160 | static __u8 DC29[] = { 0x6a, 0x50, 0x00, 0x00, 0x50, 0x3c }; | ||
1161 | static __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f }; | ||
1162 | static __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec }; | ||
1163 | static __u8 CA_sn9c120[] = { 0x14, 0xec, 0x0a, 0xf6 }; /* SN9C120 */ | ||
1164 | static __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */ | ||
1165 | static __u8 CE_sn9c325[] = | ||
1166 | { 0x32, 0xdd, 0x32, 0xdd }; /* OV7648 - SN9C325 */ | ||
1167 | |||
1168 | sn9c1xx = sn_tb[(int) sd->sensor]; | ||
1169 | configure_gpio(gspca_dev, sn9c1xx); | ||
1170 | |||
1171 | /*fixme:jfm this sequence should appear at end of sd_start */ | ||
1172 | /* with | ||
1173 | data = 0x44; | ||
1174 | reg_w(dev, 0x01, &data, 1); */ | ||
1175 | reg_w(dev, 0x15, &sn9c1xx[0x15], 1); | ||
1176 | reg_w(dev, 0x16, &sn9c1xx[0x16], 1); | ||
1177 | reg_w(dev, 0x12, &sn9c1xx[0x12], 1); | ||
1178 | reg_w(dev, 0x13, &sn9c1xx[0x13], 1); | ||
1179 | reg_w(dev, 0x18, &sn9c1xx[0x18], 1); | ||
1180 | reg_w(dev, 0xd2, &DC29[0], 1); | ||
1181 | reg_w(dev, 0xd3, &DC29[1], 1); | ||
1182 | reg_w(dev, 0xc6, &DC29[2], 1); | ||
1183 | reg_w(dev, 0xc7, &DC29[3], 1); | ||
1184 | reg_w(dev, 0xc8, &DC29[4], 1); | ||
1185 | reg_w(dev, 0xc9, &DC29[5], 1); | ||
1186 | /*fixme:jfm end of ending sequence */ | ||
1187 | reg_w(dev, 0x18, &sn9c1xx[0x18], 1); | ||
1188 | if (sd->customid == SN9C325) | ||
1189 | data = 0xae; | ||
1190 | else | ||
1191 | data = 0x60; | ||
1192 | reg_w(dev, 0x17, &data, 1); | ||
1193 | reg_w(dev, 0x05, &sn9c1xx[5], 1); | ||
1194 | reg_w(dev, 0x07, &sn9c1xx[7], 1); | ||
1195 | reg_w(dev, 0x06, &sn9c1xx[6], 1); | ||
1196 | reg_w(dev, 0x14, &sn9c1xx[0x14], 1); | ||
1197 | if (sd->customid == SN9C325) { | ||
1198 | reg_w(dev, 0x20, regsn20_sn9c325, 0x11); | ||
1199 | for (i = 0; i < 8; i++) | ||
1200 | reg_w(dev, 0x84, reg84_sn9c325, 0x15); | ||
1201 | data = 0x0a; | ||
1202 | reg_w(dev, 0x9a, &data, 1); | ||
1203 | data = 0x60; | ||
1204 | reg_w(dev, 0x99, &data, 1); | ||
1205 | } else { | ||
1206 | reg_w(dev, 0x20, regsn20, 0x11); | ||
1207 | for (i = 0; i < 8; i++) | ||
1208 | reg_w(dev, 0x84, reg84, 0x15); | ||
1209 | data = 0x08; | ||
1210 | reg_w(dev, 0x9a, &data, 1); | ||
1211 | data = 0x59; | ||
1212 | reg_w(dev, 0x99, &data, 1); | ||
1213 | } | ||
1214 | |||
1215 | mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode; | ||
1216 | reg1 = 0x02; | ||
1217 | reg17 = 0x61; | ||
1218 | switch (sd->sensor) { | ||
1219 | case SENSOR_HV7131R: | ||
1220 | hv7131R_InitSensor(gspca_dev); | ||
1221 | if (mode) | ||
1222 | reg1 = 0x46; /* 320 clk 48Mhz */ | ||
1223 | else | ||
1224 | reg1 = 0x06; /* 640 clk 24Mz */ | ||
1225 | break; | ||
1226 | case SENSOR_MI0360: | ||
1227 | mi0360_InitSensor(gspca_dev); | ||
1228 | if (mode) | ||
1229 | reg1 = 0x46; /* 320 clk 48Mhz */ | ||
1230 | else | ||
1231 | reg1 = 0x06; /* 640 clk 24Mz */ | ||
1232 | break; | ||
1233 | case SENSOR_MO4000: | ||
1234 | mo4000_InitSensor(gspca_dev); | ||
1235 | if (mode) { | ||
1236 | /* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */ | ||
1237 | reg1 = 0x06; /* clk 24Mz */ | ||
1238 | } else { | ||
1239 | reg17 = 0x22; /* 640 MCKSIZE */ | ||
1240 | reg1 = 0x06; /* 640 clk 24Mz */ | ||
1241 | } | ||
1242 | break; | ||
1243 | case SENSOR_OV7648: | ||
1244 | reg17 = 0xa2; | ||
1245 | reg1 = 0x44; | ||
1246 | ov7648_InitSensor(gspca_dev); | ||
1247 | /* if (mode) | ||
1248 | ; * 320x2... | ||
1249 | else | ||
1250 | ; * 640x... */ | ||
1251 | break; | ||
1252 | default: | ||
1253 | /* case SENSOR_OV7660: */ | ||
1254 | ov7660_InitSensor(gspca_dev); | ||
1255 | if (mode) { | ||
1256 | /* reg17 = 0x21; * 320 */ | ||
1257 | /* reg1 = 0x44; */ | ||
1258 | reg1 = 0x46; | ||
1259 | } else { | ||
1260 | reg17 = 0xa2; /* 640 */ | ||
1261 | reg1 = 0x40; | ||
1262 | } | ||
1263 | break; | ||
1264 | } | ||
1265 | reg_w(dev, 0xc0, C0, 6); | ||
1266 | switch (sd->customid) { | ||
1267 | case SN9C120: /*jfm ?? */ | ||
1268 | reg_w(dev, 0xca, CA_sn9c120, 4); | ||
1269 | break; | ||
1270 | default: | ||
1271 | reg_w(dev, 0xca, CA, 4); | ||
1272 | break; | ||
1273 | } | ||
1274 | switch (sd->customid) { | ||
1275 | case SN9C120: /*jfm ?? */ | ||
1276 | case SN9C325: | ||
1277 | reg_w(dev, 0xce, CE_sn9c325, 4); | ||
1278 | break; | ||
1279 | default: | ||
1280 | reg_w(dev, 0xce, CE, 4); | ||
1281 | /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */ | ||
1282 | break; | ||
1283 | } | ||
1284 | |||
1285 | /* here change size mode 0 -> VGA; 1 -> CIF */ | ||
1286 | data = 0x40 | sn9c1xx[0x18] | (mode << 4); | ||
1287 | reg_w(dev, 0x18, &data, 1); | ||
1288 | |||
1289 | reg_w(dev, 0x100, qtable4, 0x40); | ||
1290 | reg_w(dev, 0x140, qtable4 + 0x40, 0x40); | ||
1291 | |||
1292 | data = sn9c1xx[0x18] | (mode << 4); | ||
1293 | reg_w(dev, 0x18, &data, 1); | ||
1294 | |||
1295 | reg_w(dev, 0x17, ®17, 1); | ||
1296 | reg_w(dev, 0x01, ®1, 1); | ||
1297 | setbrightness(gspca_dev); | ||
1298 | setcontrast(gspca_dev); | ||
1299 | } | ||
1300 | |||
1301 | static void sd_stopN(struct gspca_dev *gspca_dev) | ||
1302 | { | ||
1303 | struct sd *sd = (struct sd *) gspca_dev; | ||
1304 | struct usb_device *dev = gspca_dev->dev; | ||
1305 | static __u8 stophv7131[] = | ||
1306 | { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 }; | ||
1307 | static __u8 stopmi0360[] = | ||
1308 | { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 }; | ||
1309 | __u8 regF1; | ||
1310 | __u8 data; | ||
1311 | __u8 *sn9c1xx; | ||
1312 | |||
1313 | data = 0x0b; | ||
1314 | switch (sd->sensor) { | ||
1315 | case SENSOR_HV7131R: | ||
1316 | i2c_w8(dev, stophv7131); | ||
1317 | data = 0x2b; | ||
1318 | break; | ||
1319 | case SENSOR_MI0360: | ||
1320 | i2c_w8(dev, stopmi0360); | ||
1321 | data = 0x29; | ||
1322 | break; | ||
1323 | case SENSOR_MO4000: | ||
1324 | break; | ||
1325 | case SENSOR_OV7648: | ||
1326 | data = 0x29; | ||
1327 | break; | ||
1328 | default: | ||
1329 | /* case SENSOR_OV7660: */ | ||
1330 | break; | ||
1331 | } | ||
1332 | sn9c1xx = sn_tb[(int) sd->sensor]; | ||
1333 | reg_w(dev, 0x01, &sn9c1xx[1], 1); | ||
1334 | reg_w(dev, 0x17, &sn9c1xx[0x17], 1); | ||
1335 | reg_w(dev, 0x01, &sn9c1xx[1], 1); | ||
1336 | reg_w(dev, 0x01, &data, 1); | ||
1337 | regF1 = 0x01; | ||
1338 | reg_w(dev, 0xf1, ®F1, 1); | ||
1339 | } | ||
1340 | |||
1341 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
1342 | { | ||
1343 | } | ||
1344 | |||
1345 | static void sd_close(struct gspca_dev *gspca_dev) | ||
1346 | { | ||
1347 | } | ||
1348 | |||
1349 | static void setautogain(struct gspca_dev *gspca_dev) | ||
1350 | { | ||
1351 | struct sd *sd = (struct sd *) gspca_dev; | ||
1352 | /* Thanks S., without your advice, autobright should not work :) */ | ||
1353 | int delta; | ||
1354 | int expotimes = 0; | ||
1355 | __u8 luma_mean = 130; | ||
1356 | __u8 luma_delta = 20; | ||
1357 | |||
1358 | delta = sd->avg_lum; | ||
1359 | if (delta < luma_mean - luma_delta || | ||
1360 | delta > luma_mean + luma_delta) { | ||
1361 | switch (sd->sensor) { | ||
1362 | case SENSOR_HV7131R: | ||
1363 | expotimes = sd->exposure >> 8; | ||
1364 | expotimes += (luma_mean - delta) >> 4; | ||
1365 | if (expotimes < 0) | ||
1366 | expotimes = 0; | ||
1367 | sd->exposure = setexposure(gspca_dev, | ||
1368 | (unsigned int) (expotimes << 8)); | ||
1369 | break; | ||
1370 | case SENSOR_MO4000: | ||
1371 | case SENSOR_MI0360: | ||
1372 | expotimes = sd->exposure; | ||
1373 | expotimes += (luma_mean - delta) >> 6; | ||
1374 | if (expotimes < 0) | ||
1375 | expotimes = 0; | ||
1376 | sd->exposure = setexposure(gspca_dev, | ||
1377 | (unsigned int) expotimes); | ||
1378 | setcolors(gspca_dev); | ||
1379 | break; | ||
1380 | } | ||
1381 | } | ||
1382 | } | ||
1383 | |||
1384 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | ||
1385 | struct gspca_frame *frame, /* target */ | ||
1386 | unsigned char *data, /* isoc packet */ | ||
1387 | int len) /* iso packet length */ | ||
1388 | { | ||
1389 | struct sd *sd = (struct sd *) gspca_dev; | ||
1390 | int sof, avg_lum; | ||
1391 | |||
1392 | sof = len - 64; | ||
1393 | if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) { | ||
1394 | |||
1395 | /* end of frame */ | ||
1396 | gspca_frame_add(gspca_dev, LAST_PACKET, | ||
1397 | frame, data, sof + 2); | ||
1398 | if (sd->ag_cnt < 0) | ||
1399 | return; | ||
1400 | if (--sd->ag_cnt >= 0) | ||
1401 | return; | ||
1402 | sd->ag_cnt = AG_CNT_START; | ||
1403 | /* w1 w2 w3 */ | ||
1404 | /* w4 w5 w6 */ | ||
1405 | /* w7 w8 */ | ||
1406 | /* w4 */ | ||
1407 | avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6; | ||
1408 | /* w6 */ | ||
1409 | avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6; | ||
1410 | /* w2 */ | ||
1411 | avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6; | ||
1412 | /* w8 */ | ||
1413 | avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6; | ||
1414 | /* w5 */ | ||
1415 | avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4; | ||
1416 | avg_lum >>= 4; | ||
1417 | sd->avg_lum = avg_lum; | ||
1418 | PDEBUG(D_PACK, "mean lum %d", avg_lum); | ||
1419 | setautogain(gspca_dev); | ||
1420 | return; | ||
1421 | } | ||
1422 | if (gspca_dev->last_packet_type == LAST_PACKET) { | ||
1423 | |||
1424 | /* put the JPEG 422 header */ | ||
1425 | jpeg_put_header(gspca_dev, frame, sd->qindex, 0x21); | ||
1426 | } | ||
1427 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); | ||
1428 | } | ||
1429 | |||
1430 | static unsigned int getexposure(struct gspca_dev *gspca_dev) | ||
1431 | { | ||
1432 | struct sd *sd = (struct sd *) gspca_dev; | ||
1433 | __u8 hexpo, mexpo, lexpo; | ||
1434 | __u8 expo[6]; | ||
1435 | |||
1436 | switch (sd->sensor) { | ||
1437 | case SENSOR_HV7131R: | ||
1438 | /* read sensor exposure */ | ||
1439 | i2c_r5(gspca_dev, 0x25, expo); | ||
1440 | return (expo[0] << 16) | (expo[1] << 8) | expo[2]; | ||
1441 | case SENSOR_MI0360: | ||
1442 | /* read sensor exposure */ | ||
1443 | i2c_r5(gspca_dev, 0x09, expo); | ||
1444 | return (expo[0] << 8) | expo[1]; | ||
1445 | case SENSOR_MO4000: | ||
1446 | i2c_r5(gspca_dev, 0x0e, expo); | ||
1447 | hexpo = 0; /* expo[1] & 0x07; */ | ||
1448 | mexpo = 0x40; /* expo[2] &0xff; */ | ||
1449 | lexpo = (expo[1] & 0x30) >> 4; | ||
1450 | PDEBUG(D_CONF, "exposure %d", | ||
1451 | (hexpo << 10) | (mexpo << 2) | lexpo); | ||
1452 | return (hexpo << 10) | (mexpo << 2) | lexpo; | ||
1453 | default: | ||
1454 | /* case SENSOR_OV7660: */ | ||
1455 | /* read sensor exposure */ | ||
1456 | i2c_r5(gspca_dev, 0x04, expo); | ||
1457 | hexpo = expo[3] & 0x2f; | ||
1458 | lexpo = expo[0] & 0x02; | ||
1459 | i2c_r5(gspca_dev, 0x08, expo); | ||
1460 | mexpo = expo[2]; | ||
1461 | return (hexpo << 10) | (mexpo << 2) | lexpo; | ||
1462 | } | ||
1463 | } | ||
1464 | |||
1465 | static void getbrightness(struct gspca_dev *gspca_dev) | ||
1466 | { | ||
1467 | struct sd *sd = (struct sd *) gspca_dev; | ||
1468 | |||
1469 | /* hardcoded registers seem not readable */ | ||
1470 | switch (sd->sensor) { | ||
1471 | case SENSOR_HV7131R: | ||
1472 | /* sd->brightness = 0x7fff; */ | ||
1473 | sd->brightness = getexposure(gspca_dev) >> 4; | ||
1474 | break; | ||
1475 | case SENSOR_MI0360: | ||
1476 | sd->brightness = getexposure(gspca_dev) << 4; | ||
1477 | break; | ||
1478 | case SENSOR_MO4000: | ||
1479 | /* sd->brightness = 0x1fff; */ | ||
1480 | sd->brightness = getexposure(gspca_dev) << 4; | ||
1481 | break; | ||
1482 | } | ||
1483 | } | ||
1484 | |||
1485 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | ||
1486 | { | ||
1487 | struct sd *sd = (struct sd *) gspca_dev; | ||
1488 | |||
1489 | sd->brightness = val; | ||
1490 | if (gspca_dev->streaming) | ||
1491 | setbrightness(gspca_dev); | ||
1492 | return 0; | ||
1493 | } | ||
1494 | |||
1495 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
1496 | { | ||
1497 | struct sd *sd = (struct sd *) gspca_dev; | ||
1498 | |||
1499 | getbrightness(gspca_dev); | ||
1500 | *val = sd->brightness; | ||
1501 | return 0; | ||
1502 | } | ||
1503 | |||
1504 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | ||
1505 | { | ||
1506 | struct sd *sd = (struct sd *) gspca_dev; | ||
1507 | |||
1508 | sd->contrast = val; | ||
1509 | if (gspca_dev->streaming) | ||
1510 | setcontrast(gspca_dev); | ||
1511 | return 0; | ||
1512 | } | ||
1513 | |||
1514 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) | ||
1515 | { | ||
1516 | struct sd *sd = (struct sd *) gspca_dev; | ||
1517 | |||
1518 | *val = sd->contrast; | ||
1519 | return 0; | ||
1520 | } | ||
1521 | |||
1522 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) | ||
1523 | { | ||
1524 | struct sd *sd = (struct sd *) gspca_dev; | ||
1525 | |||
1526 | sd->colors = val; | ||
1527 | if (gspca_dev->streaming) | ||
1528 | setcolors(gspca_dev); | ||
1529 | return 0; | ||
1530 | } | ||
1531 | |||
1532 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) | ||
1533 | { | ||
1534 | struct sd *sd = (struct sd *) gspca_dev; | ||
1535 | |||
1536 | *val = sd->colors; | ||
1537 | return 0; | ||
1538 | } | ||
1539 | |||
1540 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) | ||
1541 | { | ||
1542 | struct sd *sd = (struct sd *) gspca_dev; | ||
1543 | |||
1544 | sd->autogain = val; | ||
1545 | if (val) | ||
1546 | sd->ag_cnt = AG_CNT_START; | ||
1547 | else | ||
1548 | sd->ag_cnt = -1; | ||
1549 | return 0; | ||
1550 | } | ||
1551 | |||
1552 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) | ||
1553 | { | ||
1554 | struct sd *sd = (struct sd *) gspca_dev; | ||
1555 | |||
1556 | *val = sd->autogain; | ||
1557 | return 0; | ||
1558 | } | ||
1559 | |||
1560 | /* sub-driver description */ | ||
1561 | static struct sd_desc sd_desc = { | ||
1562 | .name = MODULE_NAME, | ||
1563 | .ctrls = sd_ctrls, | ||
1564 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
1565 | .config = sd_config, | ||
1566 | .open = sd_open, | ||
1567 | .start = sd_start, | ||
1568 | .stopN = sd_stopN, | ||
1569 | .stop0 = sd_stop0, | ||
1570 | .close = sd_close, | ||
1571 | .pkt_scan = sd_pkt_scan, | ||
1572 | }; | ||
1573 | |||
1574 | /* -- module initialisation -- */ | ||
1575 | #define DVNM(name) .driver_info = (kernel_ulong_t) name | ||
1576 | static __devinitdata struct usb_device_id device_table[] = { | ||
1577 | {USB_DEVICE(0x0458, 0x7025), DVNM("Genius Eye 311Q")}, | ||
1578 | {USB_DEVICE(0x045e, 0x00f5), DVNM("MicroSoft VX3000")}, | ||
1579 | {USB_DEVICE(0x045e, 0x00f7), DVNM("MicroSoft VX1000")}, | ||
1580 | {USB_DEVICE(0x0471, 0x0327), DVNM("Philips SPC 600 NC")}, | ||
1581 | {USB_DEVICE(0x0471, 0x0328), DVNM("Philips SPC 700 NC")}, | ||
1582 | {USB_DEVICE(0x0471, 0x0330), DVNM("Philips SPC 710NC")}, | ||
1583 | {USB_DEVICE(0x0c45, 0x6040), DVNM("Speed NVC 350K")}, | ||
1584 | {USB_DEVICE(0x0c45, 0x607c), DVNM("Sonix sn9c102p Hv7131R")}, | ||
1585 | {USB_DEVICE(0x0c45, 0x60c0), DVNM("Sangha Sn535")}, | ||
1586 | {USB_DEVICE(0x0c45, 0x60ec), DVNM("SN9C105+MO4000")}, | ||
1587 | {USB_DEVICE(0x0c45, 0x60fb), DVNM("Surfer NoName")}, | ||
1588 | {USB_DEVICE(0x0c45, 0x60fc), DVNM("LG-LIC300")}, | ||
1589 | {USB_DEVICE(0x0c45, 0x612a), DVNM("Avant Camera")}, | ||
1590 | {USB_DEVICE(0x0c45, 0x612c), DVNM("Typhoon Rasy Cam 1.3MPix")}, | ||
1591 | {USB_DEVICE(0x0c45, 0x6130), DVNM("Sonix Pccam")}, | ||
1592 | {USB_DEVICE(0x0c45, 0x6138), DVNM("Sn9c120 Mo4000")}, | ||
1593 | {USB_DEVICE(0x0c45, 0x613b), DVNM("Surfer SN-206")}, | ||
1594 | {USB_DEVICE(0x0c45, 0x613c), DVNM("Sonix Pccam168")}, | ||
1595 | {} | ||
1596 | }; | ||
1597 | MODULE_DEVICE_TABLE(usb, device_table); | ||
1598 | |||
1599 | /* -- device connect -- */ | ||
1600 | static int sd_probe(struct usb_interface *intf, | ||
1601 | const struct usb_device_id *id) | ||
1602 | { | ||
1603 | return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), | ||
1604 | THIS_MODULE); | ||
1605 | } | ||
1606 | |||
1607 | static struct usb_driver sd_driver = { | ||
1608 | .name = MODULE_NAME, | ||
1609 | .id_table = device_table, | ||
1610 | .probe = sd_probe, | ||
1611 | .disconnect = gspca_disconnect, | ||
1612 | }; | ||
1613 | |||
1614 | /* -- module insert / remove -- */ | ||
1615 | static int __init sd_mod_init(void) | ||
1616 | { | ||
1617 | if (usb_register(&sd_driver) < 0) | ||
1618 | return -1; | ||
1619 | info("v%s registered", version); | ||
1620 | return 0; | ||
1621 | } | ||
1622 | static void __exit sd_mod_exit(void) | ||
1623 | { | ||
1624 | usb_deregister(&sd_driver); | ||
1625 | info("deregistered"); | ||
1626 | } | ||
1627 | |||
1628 | module_init(sd_mod_init); | ||
1629 | module_exit(sd_mod_exit); | ||
diff --git a/drivers/media/video/gspca/spca500.c b/drivers/media/video/gspca/spca500.c new file mode 100644 index 000000000000..c0dd969a3106 --- /dev/null +++ b/drivers/media/video/gspca/spca500.c | |||
@@ -0,0 +1,1195 @@ | |||
1 | /* | ||
2 | * SPCA500 chip based cameras initialization data | ||
3 | * | ||
4 | * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #define MODULE_NAME "spca500" | ||
23 | |||
24 | #include "gspca.h" | ||
25 | #include "jpeg.h" | ||
26 | |||
27 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) | ||
28 | static const char version[] = "2.1.0"; | ||
29 | |||
30 | MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); | ||
31 | MODULE_DESCRIPTION("GSPCA/SPCA500 USB Camera Driver"); | ||
32 | MODULE_LICENSE("GPL"); | ||
33 | |||
34 | /* specific webcam descriptor */ | ||
35 | struct sd { | ||
36 | struct gspca_dev gspca_dev; /* !! must be the first item */ | ||
37 | |||
38 | unsigned char packet[ISO_MAX_SIZE + 128]; | ||
39 | /* !! no more than 128 ff in an ISO packet */ | ||
40 | |||
41 | unsigned char brightness; | ||
42 | unsigned char contrast; | ||
43 | unsigned char colors; | ||
44 | |||
45 | char qindex; | ||
46 | char subtype; | ||
47 | #define AgfaCl20 0 | ||
48 | #define AiptekPocketDV 1 | ||
49 | #define BenqDC1016 2 | ||
50 | #define CreativePCCam300 3 | ||
51 | #define DLinkDSC350 4 | ||
52 | #define Gsmartmini 5 | ||
53 | #define IntelPocketPCCamera 6 | ||
54 | #define KodakEZ200 7 | ||
55 | #define LogitechClickSmart310 8 | ||
56 | #define LogitechClickSmart510 9 | ||
57 | #define LogitechTraveler 10 | ||
58 | #define MustekGsmart300 11 | ||
59 | #define Optimedia 12 | ||
60 | #define PalmPixDC85 13 | ||
61 | #define ToptroIndus 14 | ||
62 | }; | ||
63 | |||
64 | /* V4L2 controls supported by the driver */ | ||
65 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
66 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
67 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | ||
68 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | ||
69 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); | ||
70 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); | ||
71 | |||
72 | static struct ctrl sd_ctrls[] = { | ||
73 | #define SD_BRIGHTNESS 0 | ||
74 | { | ||
75 | { | ||
76 | .id = V4L2_CID_BRIGHTNESS, | ||
77 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
78 | .name = "Brightness", | ||
79 | .minimum = 0, | ||
80 | .maximum = 0xff, | ||
81 | .step = 1, | ||
82 | .default_value = 0x7f, | ||
83 | }, | ||
84 | .set = sd_setbrightness, | ||
85 | .get = sd_getbrightness, | ||
86 | }, | ||
87 | #define SD_CONTRAST 1 | ||
88 | { | ||
89 | { | ||
90 | .id = V4L2_CID_CONTRAST, | ||
91 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
92 | .name = "Contrast", | ||
93 | .minimum = 0, | ||
94 | .maximum = 255, | ||
95 | .step = 1, | ||
96 | .default_value = 127, | ||
97 | }, | ||
98 | .set = sd_setcontrast, | ||
99 | .get = sd_getcontrast, | ||
100 | }, | ||
101 | #define SD_COLOR 2 | ||
102 | { | ||
103 | { | ||
104 | .id = V4L2_CID_SATURATION, | ||
105 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
106 | .name = "Color", | ||
107 | .minimum = 0, | ||
108 | .maximum = 255, | ||
109 | .step = 1, | ||
110 | .default_value = 127, | ||
111 | }, | ||
112 | .set = sd_setcolors, | ||
113 | .get = sd_getcolors, | ||
114 | }, | ||
115 | }; | ||
116 | |||
117 | static struct cam_mode vga_mode[] = { | ||
118 | {V4L2_PIX_FMT_JPEG, 320, 240, 1}, | ||
119 | {V4L2_PIX_FMT_JPEG, 640, 480, 0}, | ||
120 | }; | ||
121 | |||
122 | static struct cam_mode sif_mode[] = { | ||
123 | {V4L2_PIX_FMT_JPEG, 176, 144, 1}, | ||
124 | {V4L2_PIX_FMT_JPEG, 352, 288, 0}, | ||
125 | }; | ||
126 | |||
127 | /* Frame packet header offsets for the spca500 */ | ||
128 | #define SPCA500_OFFSET_PADDINGLB 2 | ||
129 | #define SPCA500_OFFSET_PADDINGHB 3 | ||
130 | #define SPCA500_OFFSET_MODE 4 | ||
131 | #define SPCA500_OFFSET_IMGWIDTH 5 | ||
132 | #define SPCA500_OFFSET_IMGHEIGHT 6 | ||
133 | #define SPCA500_OFFSET_IMGMODE 7 | ||
134 | #define SPCA500_OFFSET_QTBLINDEX 8 | ||
135 | #define SPCA500_OFFSET_FRAMSEQ 9 | ||
136 | #define SPCA500_OFFSET_CDSPINFO 10 | ||
137 | #define SPCA500_OFFSET_GPIO 11 | ||
138 | #define SPCA500_OFFSET_AUGPIO 12 | ||
139 | #define SPCA500_OFFSET_DATA 16 | ||
140 | |||
141 | |||
142 | static __u16 spca500_visual_defaults[][3] = { | ||
143 | {0x00, 0x0003, 0x816b}, /* SSI not active sync with vsync, | ||
144 | * hue (H byte) = 0, | ||
145 | * saturation/hue enable, | ||
146 | * brightness/contrast enable. | ||
147 | */ | ||
148 | {0x00, 0x0000, 0x8167}, /* brightness = 0 */ | ||
149 | {0x00, 0x0020, 0x8168}, /* contrast = 0 */ | ||
150 | {0x00, 0x0003, 0x816b}, /* SSI not active sync with vsync, | ||
151 | * hue (H byte) = 0, saturation/hue enable, | ||
152 | * brightness/contrast enable. | ||
153 | * was 0x0003, now 0x0000. | ||
154 | */ | ||
155 | {0x00, 0x0000, 0x816a}, /* hue (L byte) = 0 */ | ||
156 | {0x00, 0x0020, 0x8169}, /* saturation = 0x20 */ | ||
157 | {0x00, 0x0050, 0x8157}, /* edge gain high threshold */ | ||
158 | {0x00, 0x0030, 0x8158}, /* edge gain low threshold */ | ||
159 | {0x00, 0x0028, 0x8159}, /* edge bandwidth high threshold */ | ||
160 | {0x00, 0x000a, 0x815a}, /* edge bandwidth low threshold */ | ||
161 | {0x00, 0x0001, 0x8202}, /* clock rate compensation = 1/25 sec/frame */ | ||
162 | {0x0c, 0x0004, 0x0000}, | ||
163 | /* set interface */ | ||
164 | |||
165 | {0, 0, 0} | ||
166 | }; | ||
167 | static __u16 Clicksmart510_defaults[][3] = { | ||
168 | {0x00, 0x00, 0x8211}, | ||
169 | {0x00, 0x01, 0x82c0}, | ||
170 | {0x00, 0x10, 0x82cb}, | ||
171 | {0x00, 0x0f, 0x800d}, | ||
172 | {0x00, 0x82, 0x8225}, | ||
173 | {0x00, 0x21, 0x8228}, | ||
174 | {0x00, 0x00, 0x8203}, | ||
175 | {0x00, 0x00, 0x8204}, | ||
176 | {0x00, 0x08, 0x8205}, | ||
177 | {0x00, 0xf8, 0x8206}, | ||
178 | {0x00, 0x28, 0x8207}, | ||
179 | {0x00, 0xa0, 0x8208}, | ||
180 | {0x00, 0x08, 0x824a}, | ||
181 | {0x00, 0x08, 0x8214}, | ||
182 | {0x00, 0x80, 0x82c1}, | ||
183 | {0x00, 0x00, 0x82c2}, | ||
184 | {0x00, 0x00, 0x82ca}, | ||
185 | {0x00, 0x80, 0x82c1}, | ||
186 | {0x00, 0x04, 0x82c2}, | ||
187 | {0x00, 0x00, 0x82ca}, | ||
188 | {0x00, 0xfc, 0x8100}, | ||
189 | {0x00, 0xfc, 0x8105}, | ||
190 | {0x00, 0x30, 0x8101}, | ||
191 | {0x00, 0x00, 0x8102}, | ||
192 | {0x00, 0x00, 0x8103}, | ||
193 | {0x00, 0x66, 0x8107}, | ||
194 | {0x00, 0x00, 0x816b}, | ||
195 | {0x00, 0x00, 0x8155}, | ||
196 | {0x00, 0x01, 0x8156}, | ||
197 | {0x00, 0x60, 0x8157}, | ||
198 | {0x00, 0x40, 0x8158}, | ||
199 | {0x00, 0x0a, 0x8159}, | ||
200 | {0x00, 0x06, 0x815a}, | ||
201 | {0x00, 0x00, 0x813f}, | ||
202 | {0x00, 0x00, 0x8200}, | ||
203 | {0x00, 0x19, 0x8201}, | ||
204 | {0x00, 0x00, 0x82c1}, | ||
205 | {0x00, 0xa0, 0x82c2}, | ||
206 | {0x00, 0x00, 0x82ca}, | ||
207 | {0x00, 0x00, 0x8117}, | ||
208 | {0x00, 0x00, 0x8118}, | ||
209 | {0x00, 0x65, 0x8119}, | ||
210 | {0x00, 0x00, 0x811a}, | ||
211 | {0x00, 0x00, 0x811b}, | ||
212 | {0x00, 0x55, 0x811c}, | ||
213 | {0x00, 0x65, 0x811d}, | ||
214 | {0x00, 0x55, 0x811e}, | ||
215 | {0x00, 0x16, 0x811f}, | ||
216 | {0x00, 0x19, 0x8120}, | ||
217 | {0x00, 0x80, 0x8103}, | ||
218 | {0x00, 0x83, 0x816b}, | ||
219 | {0x00, 0x25, 0x8168}, | ||
220 | {0x00, 0x01, 0x820f}, | ||
221 | {0x00, 0xff, 0x8115}, | ||
222 | {0x00, 0x48, 0x8116}, | ||
223 | {0x00, 0x50, 0x8151}, | ||
224 | {0x00, 0x40, 0x8152}, | ||
225 | {0x00, 0x78, 0x8153}, | ||
226 | {0x00, 0x40, 0x8154}, | ||
227 | {0x00, 0x00, 0x8167}, | ||
228 | {0x00, 0x20, 0x8168}, | ||
229 | {0x00, 0x00, 0x816a}, | ||
230 | {0x00, 0x03, 0x816b}, | ||
231 | {0x00, 0x20, 0x8169}, | ||
232 | {0x00, 0x60, 0x8157}, | ||
233 | {0x00, 0x00, 0x8190}, | ||
234 | {0x00, 0x00, 0x81a1}, | ||
235 | {0x00, 0x00, 0x81b2}, | ||
236 | {0x00, 0x27, 0x8191}, | ||
237 | {0x00, 0x27, 0x81a2}, | ||
238 | {0x00, 0x27, 0x81b3}, | ||
239 | {0x00, 0x4b, 0x8192}, | ||
240 | {0x00, 0x4b, 0x81a3}, | ||
241 | {0x00, 0x4b, 0x81b4}, | ||
242 | {0x00, 0x66, 0x8193}, | ||
243 | {0x00, 0x66, 0x81a4}, | ||
244 | {0x00, 0x66, 0x81b5}, | ||
245 | {0x00, 0x79, 0x8194}, | ||
246 | {0x00, 0x79, 0x81a5}, | ||
247 | {0x00, 0x79, 0x81b6}, | ||
248 | {0x00, 0x8a, 0x8195}, | ||
249 | {0x00, 0x8a, 0x81a6}, | ||
250 | {0x00, 0x8a, 0x81b7}, | ||
251 | {0x00, 0x9b, 0x8196}, | ||
252 | {0x00, 0x9b, 0x81a7}, | ||
253 | {0x00, 0x9b, 0x81b8}, | ||
254 | {0x00, 0xa6, 0x8197}, | ||
255 | {0x00, 0xa6, 0x81a8}, | ||
256 | {0x00, 0xa6, 0x81b9}, | ||
257 | {0x00, 0xb2, 0x8198}, | ||
258 | {0x00, 0xb2, 0x81a9}, | ||
259 | {0x00, 0xb2, 0x81ba}, | ||
260 | {0x00, 0xbe, 0x8199}, | ||
261 | {0x00, 0xbe, 0x81aa}, | ||
262 | {0x00, 0xbe, 0x81bb}, | ||
263 | {0x00, 0xc8, 0x819a}, | ||
264 | {0x00, 0xc8, 0x81ab}, | ||
265 | {0x00, 0xc8, 0x81bc}, | ||
266 | {0x00, 0xd2, 0x819b}, | ||
267 | {0x00, 0xd2, 0x81ac}, | ||
268 | {0x00, 0xd2, 0x81bd}, | ||
269 | {0x00, 0xdb, 0x819c}, | ||
270 | {0x00, 0xdb, 0x81ad}, | ||
271 | {0x00, 0xdb, 0x81be}, | ||
272 | {0x00, 0xe4, 0x819d}, | ||
273 | {0x00, 0xe4, 0x81ae}, | ||
274 | {0x00, 0xe4, 0x81bf}, | ||
275 | {0x00, 0xed, 0x819e}, | ||
276 | {0x00, 0xed, 0x81af}, | ||
277 | {0x00, 0xed, 0x81c0}, | ||
278 | {0x00, 0xf7, 0x819f}, | ||
279 | {0x00, 0xf7, 0x81b0}, | ||
280 | {0x00, 0xf7, 0x81c1}, | ||
281 | {0x00, 0xff, 0x81a0}, | ||
282 | {0x00, 0xff, 0x81b1}, | ||
283 | {0x00, 0xff, 0x81c2}, | ||
284 | {0x00, 0x03, 0x8156}, | ||
285 | {0x00, 0x00, 0x8211}, | ||
286 | {0x00, 0x20, 0x8168}, | ||
287 | {0x00, 0x01, 0x8202}, | ||
288 | {0x00, 0x30, 0x8101}, | ||
289 | {0x00, 0x00, 0x8111}, | ||
290 | {0x00, 0x00, 0x8112}, | ||
291 | {0x00, 0x00, 0x8113}, | ||
292 | {0x00, 0x00, 0x8114}, | ||
293 | {} | ||
294 | }; | ||
295 | |||
296 | static unsigned char qtable_creative_pccam[2][64] = { | ||
297 | { /* Q-table Y-components */ | ||
298 | 0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12, | ||
299 | 0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11, | ||
300 | 0x04, 0x04, 0x05, 0x07, 0x0c, 0x11, 0x15, 0x11, | ||
301 | 0x04, 0x05, 0x07, 0x09, 0x0f, 0x1a, 0x18, 0x13, | ||
302 | 0x05, 0x07, 0x0b, 0x11, 0x14, 0x21, 0x1f, 0x17, | ||
303 | 0x07, 0x0b, 0x11, 0x13, 0x18, 0x1f, 0x22, 0x1c, | ||
304 | 0x0f, 0x13, 0x17, 0x1a, 0x1f, 0x24, 0x24, 0x1e, | ||
305 | 0x16, 0x1c, 0x1d, 0x1d, 0x22, 0x1e, 0x1f, 0x1e}, | ||
306 | { /* Q-table C-components */ | ||
307 | 0x05, 0x05, 0x07, 0x0e, 0x1e, 0x1e, 0x1e, 0x1e, | ||
308 | 0x05, 0x06, 0x08, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, | ||
309 | 0x07, 0x08, 0x11, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, | ||
310 | 0x0e, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, | ||
311 | 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, | ||
312 | 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, | ||
313 | 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, | ||
314 | 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e} | ||
315 | }; | ||
316 | |||
317 | static unsigned char qtable_kodak_ez200[2][64] = { | ||
318 | { /* Q-table Y-components */ | ||
319 | 0x02, 0x01, 0x01, 0x02, 0x02, 0x04, 0x05, 0x06, | ||
320 | 0x01, 0x01, 0x01, 0x02, 0x03, 0x06, 0x06, 0x06, | ||
321 | 0x01, 0x01, 0x02, 0x02, 0x04, 0x06, 0x07, 0x06, | ||
322 | 0x01, 0x02, 0x02, 0x03, 0x05, 0x09, 0x08, 0x06, | ||
323 | 0x02, 0x02, 0x04, 0x06, 0x07, 0x0b, 0x0a, 0x08, | ||
324 | 0x02, 0x04, 0x06, 0x06, 0x08, 0x0a, 0x0b, 0x09, | ||
325 | 0x05, 0x06, 0x08, 0x09, 0x0a, 0x0c, 0x0c, 0x0a, | ||
326 | 0x07, 0x09, 0x0a, 0x0a, 0x0b, 0x0a, 0x0a, 0x0a}, | ||
327 | { /* Q-table C-components */ | ||
328 | 0x02, 0x02, 0x02, 0x05, 0x0a, 0x0a, 0x0a, 0x0a, | ||
329 | 0x02, 0x02, 0x03, 0x07, 0x0a, 0x0a, 0x0a, 0x0a, | ||
330 | 0x02, 0x03, 0x06, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, | ||
331 | 0x05, 0x07, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, | ||
332 | 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, | ||
333 | 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, | ||
334 | 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, | ||
335 | 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a} | ||
336 | }; | ||
337 | |||
338 | static unsigned char qtable_pocketdv[2][64] = { | ||
339 | { /* Q-table Y-components start registers 0x8800 */ | ||
340 | 0x06, 0x04, 0x04, 0x06, 0x0a, 0x10, 0x14, 0x18, | ||
341 | 0x05, 0x05, 0x06, 0x08, 0x0a, 0x17, 0x18, 0x16, | ||
342 | 0x06, 0x05, 0x06, 0x0a, 0x10, 0x17, 0x1c, 0x16, | ||
343 | 0x06, 0x07, 0x09, 0x0c, 0x14, 0x23, 0x20, 0x19, | ||
344 | 0x07, 0x09, 0x0f, 0x16, 0x1b, 0x2c, 0x29, 0x1f, | ||
345 | 0x0a, 0x0e, 0x16, 0x1a, 0x20, 0x2a, 0x2d, 0x25, | ||
346 | 0x14, 0x1a, 0x1f, 0x23, 0x29, 0x30, 0x30, 0x28, | ||
347 | 0x1d, 0x25, 0x26, 0x27, 0x2d, 0x28, 0x29, 0x28, | ||
348 | }, | ||
349 | { /* Q-table C-components start registers 0x8840 */ | ||
350 | 0x07, 0x07, 0x0a, 0x13, 0x28, 0x28, 0x28, 0x28, | ||
351 | 0x07, 0x08, 0x0a, 0x1a, 0x28, 0x28, 0x28, 0x28, | ||
352 | 0x0a, 0x0a, 0x16, 0x28, 0x28, 0x28, 0x28, 0x28, | ||
353 | 0x13, 0x1a, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, | ||
354 | 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, | ||
355 | 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, | ||
356 | 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, | ||
357 | 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28} | ||
358 | }; | ||
359 | |||
360 | static void spca5xxRegRead(struct usb_device *dev, | ||
361 | __u16 index, | ||
362 | __u8 *buffer, __u16 length) | ||
363 | { | ||
364 | usb_control_msg(dev, | ||
365 | usb_rcvctrlpipe(dev, 0), | ||
366 | 0, | ||
367 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
368 | 0, /* value */ | ||
369 | index, buffer, length, 500); | ||
370 | } | ||
371 | |||
372 | static int reg_write(struct usb_device *dev, | ||
373 | __u16 req, __u16 index, __u16 value) | ||
374 | { | ||
375 | int ret; | ||
376 | |||
377 | ret = usb_control_msg(dev, | ||
378 | usb_sndctrlpipe(dev, 0), | ||
379 | req, | ||
380 | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
381 | value, index, NULL, 0, 500); | ||
382 | PDEBUG(D_USBO, "reg write: [0x%02x] = 0x%02x, 0x%x", | ||
383 | index, value, ret); | ||
384 | if (ret < 0) | ||
385 | PDEBUG(D_ERR, "reg write: error %d", ret); | ||
386 | return ret; | ||
387 | } | ||
388 | |||
389 | /* returns: negative is error, pos or zero is data */ | ||
390 | static int reg_read(struct usb_device *dev, | ||
391 | __u16 req, /* bRequest */ | ||
392 | __u16 index, /* wIndex */ | ||
393 | __u16 length) /* wLength (1 or 2 only) */ | ||
394 | { | ||
395 | int ret; | ||
396 | __u8 buf[2]; | ||
397 | |||
398 | buf[1] = 0; | ||
399 | ret = usb_control_msg(dev, | ||
400 | usb_rcvctrlpipe(dev, 0), | ||
401 | req, | ||
402 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
403 | 0, /* value */ | ||
404 | index, | ||
405 | buf, length, | ||
406 | 500); /* timeout */ | ||
407 | if (ret < 0) { | ||
408 | PDEBUG(D_ERR, "reg_read err %d", ret); | ||
409 | return -1; | ||
410 | } | ||
411 | return (buf[1] << 8) + buf[0]; | ||
412 | } | ||
413 | |||
414 | /* | ||
415 | * Simple function to wait for a given 8-bit value to be returned from | ||
416 | * a reg_read call. | ||
417 | * Returns: negative is error or timeout, zero is success. | ||
418 | */ | ||
419 | static int reg_readwait(struct usb_device *dev, | ||
420 | __u16 reg, __u16 index, __u16 value) | ||
421 | { | ||
422 | int ret, cnt = 20; | ||
423 | |||
424 | while (--cnt > 0) { | ||
425 | ret = reg_read(dev, reg, index, 1); | ||
426 | if (ret == value) | ||
427 | return 0; | ||
428 | msleep(50); | ||
429 | } | ||
430 | return -EIO; | ||
431 | } | ||
432 | |||
433 | static int write_vector(struct gspca_dev *gspca_dev, | ||
434 | __u16 data[][3]) | ||
435 | { | ||
436 | struct usb_device *dev = gspca_dev->dev; | ||
437 | int ret, i = 0; | ||
438 | |||
439 | while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) { | ||
440 | ret = reg_write(dev, data[i][0], data[i][2], data[i][1]); | ||
441 | if (ret < 0) | ||
442 | return ret; | ||
443 | i++; | ||
444 | } | ||
445 | return 0; | ||
446 | } | ||
447 | |||
448 | static int spca50x_setup_qtable(struct gspca_dev *gspca_dev, | ||
449 | unsigned int request, | ||
450 | unsigned int ybase, | ||
451 | unsigned int cbase, | ||
452 | unsigned char qtable[2][64]) | ||
453 | { | ||
454 | struct usb_device *dev = gspca_dev->dev; | ||
455 | int i, err; | ||
456 | |||
457 | /* loop over y components */ | ||
458 | for (i = 0; i < 64; i++) { | ||
459 | err = reg_write(dev, request, ybase + i, qtable[0][i]); | ||
460 | if (err < 0) | ||
461 | return err; | ||
462 | } | ||
463 | |||
464 | /* loop over c components */ | ||
465 | for (i = 0; i < 64; i++) { | ||
466 | err = reg_write(dev, request, cbase + i, qtable[1][i]); | ||
467 | if (err < 0) | ||
468 | return err; | ||
469 | } | ||
470 | return 0; | ||
471 | } | ||
472 | |||
473 | static void spca500_ping310(struct gspca_dev *gspca_dev) | ||
474 | { | ||
475 | __u8 Data[2]; | ||
476 | |||
477 | spca5xxRegRead(gspca_dev->dev, 0x0d04, Data, 2); | ||
478 | PDEBUG(D_PACK, "ClickSmart310 ping 0x0d04 0x%02x 0x%02x", | ||
479 | Data[0], Data[1]); | ||
480 | } | ||
481 | |||
482 | static void spca500_clksmart310_init(struct gspca_dev *gspca_dev) | ||
483 | { | ||
484 | __u8 Data[2]; | ||
485 | |||
486 | spca5xxRegRead(gspca_dev->dev, 0x0d05, Data, 2); | ||
487 | PDEBUG(D_PACK, "ClickSmart310 init 0x0d05 0x%02x 0x%02x", Data[0], | ||
488 | Data[1]); | ||
489 | reg_write(gspca_dev->dev, 0x00, 0x8167, 0x5a); | ||
490 | spca500_ping310(gspca_dev); | ||
491 | |||
492 | reg_write(gspca_dev->dev, 0x00, 0x8168, 0x22); | ||
493 | reg_write(gspca_dev->dev, 0x00, 0x816a, 0xc0); | ||
494 | reg_write(gspca_dev->dev, 0x00, 0x816b, 0x0b); | ||
495 | reg_write(gspca_dev->dev, 0x00, 0x8169, 0x25); | ||
496 | reg_write(gspca_dev->dev, 0x00, 0x8157, 0x5b); | ||
497 | reg_write(gspca_dev->dev, 0x00, 0x8158, 0x5b); | ||
498 | reg_write(gspca_dev->dev, 0x00, 0x813f, 0x03); | ||
499 | reg_write(gspca_dev->dev, 0x00, 0x8151, 0x4a); | ||
500 | reg_write(gspca_dev->dev, 0x00, 0x8153, 0x78); | ||
501 | reg_write(gspca_dev->dev, 0x00, 0x0d01, 0x04); | ||
502 | /* 00 for adjust shutter */ | ||
503 | reg_write(gspca_dev->dev, 0x00, 0x0d02, 0x01); | ||
504 | reg_write(gspca_dev->dev, 0x00, 0x8169, 0x25); | ||
505 | reg_write(gspca_dev->dev, 0x00, 0x0d01, 0x02); | ||
506 | } | ||
507 | |||
508 | static void spca500_setmode(struct gspca_dev *gspca_dev, | ||
509 | __u8 xmult, __u8 ymult) | ||
510 | { | ||
511 | int mode; | ||
512 | |||
513 | /* set x multiplier */ | ||
514 | reg_write(gspca_dev->dev, 0, 0x8001, xmult); | ||
515 | |||
516 | /* set y multiplier */ | ||
517 | reg_write(gspca_dev->dev, 0, 0x8002, ymult); | ||
518 | |||
519 | /* use compressed mode, VGA, with mode specific subsample */ | ||
520 | mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode; | ||
521 | reg_write(gspca_dev->dev, 0, 0x8003, mode << 4); | ||
522 | } | ||
523 | |||
524 | static int spca500_full_reset(struct gspca_dev *gspca_dev) | ||
525 | { | ||
526 | int err; | ||
527 | |||
528 | /* send the reset command */ | ||
529 | err = reg_write(gspca_dev->dev, 0xe0, 0x0001, 0x0000); | ||
530 | if (err < 0) | ||
531 | return err; | ||
532 | |||
533 | /* wait for the reset to complete */ | ||
534 | err = reg_readwait(gspca_dev->dev, 0x06, 0x0000, 0x0000); | ||
535 | if (err < 0) | ||
536 | return err; | ||
537 | err = reg_write(gspca_dev->dev, 0xe0, 0x0000, 0x0000); | ||
538 | if (err < 0) | ||
539 | return err; | ||
540 | err = reg_readwait(gspca_dev->dev, 0x06, 0, 0); | ||
541 | if (err < 0) { | ||
542 | PDEBUG(D_ERR, "reg_readwait() failed"); | ||
543 | return err; | ||
544 | } | ||
545 | /* all ok */ | ||
546 | return 0; | ||
547 | } | ||
548 | |||
549 | /* Synchro the Bridge with sensor */ | ||
550 | /* Maybe that will work on all spca500 chip */ | ||
551 | /* because i only own a clicksmart310 try for that chip */ | ||
552 | /* using spca50x_set_packet_size() cause an Ooops here */ | ||
553 | /* usb_set_interface from kernel 2.6.x clear all the urb stuff */ | ||
554 | /* up-port the same feature as in 2.4.x kernel */ | ||
555 | static int spca500_synch310(struct gspca_dev *gspca_dev) | ||
556 | { | ||
557 | __u8 Data; | ||
558 | |||
559 | if (usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0) < 0) { | ||
560 | PDEBUG(D_ERR, "Set packet size: set interface error"); | ||
561 | goto error; | ||
562 | } | ||
563 | spca500_ping310(gspca_dev); | ||
564 | |||
565 | spca5xxRegRead(gspca_dev->dev, 0x0d00, &Data, 1); | ||
566 | |||
567 | /* need alt setting here */ | ||
568 | PDEBUG(D_PACK, "ClickSmart310 sync alt: %d", gspca_dev->alt); | ||
569 | |||
570 | /* Windoze use pipe with altsetting 6 why 7 here */ | ||
571 | if (usb_set_interface(gspca_dev->dev, | ||
572 | gspca_dev->iface, | ||
573 | gspca_dev->alt) < 0) { | ||
574 | PDEBUG(D_ERR, "Set packet size: set interface error"); | ||
575 | goto error; | ||
576 | } | ||
577 | return 0; | ||
578 | error: | ||
579 | return -EBUSY; | ||
580 | } | ||
581 | |||
582 | static void spca500_reinit(struct gspca_dev *gspca_dev) | ||
583 | { | ||
584 | int err; | ||
585 | __u8 Data; | ||
586 | |||
587 | /* some unknow command from Aiptek pocket dv and family300 */ | ||
588 | |||
589 | reg_write(gspca_dev->dev, 0x00, 0x0d01, 0x01); | ||
590 | reg_write(gspca_dev->dev, 0x00, 0x0d03, 0x00); | ||
591 | reg_write(gspca_dev->dev, 0x00, 0x0d02, 0x01); | ||
592 | |||
593 | /* enable drop packet */ | ||
594 | reg_write(gspca_dev->dev, 0x00, 0x850a, 0x0001); | ||
595 | |||
596 | err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840, | ||
597 | qtable_pocketdv); | ||
598 | if (err < 0) | ||
599 | PDEBUG(D_ERR|D_STREAM, "spca50x_setup_qtable failed on init"); | ||
600 | |||
601 | /* set qtable index */ | ||
602 | reg_write(gspca_dev->dev, 0x00, 0x8880, 2); | ||
603 | /* family cam Quicksmart stuff */ | ||
604 | reg_write(gspca_dev->dev, 0x00, 0x800a, 0x00); | ||
605 | /* Set agc transfer: synced inbetween frames */ | ||
606 | reg_write(gspca_dev->dev, 0x00, 0x820f, 0x01); | ||
607 | /* Init SDRAM - needed for SDRAM access */ | ||
608 | reg_write(gspca_dev->dev, 0x00, 0x870a, 0x04); | ||
609 | /*Start init sequence or stream */ | ||
610 | |||
611 | reg_write(gspca_dev->dev, 0, 0x8003, 0x00); | ||
612 | /* switch to video camera mode */ | ||
613 | reg_write(gspca_dev->dev, 0x00, 0x8000, 0x0004); | ||
614 | msleep(2000); | ||
615 | if (reg_readwait(gspca_dev->dev, 0, 0x8000, 0x44) != 0) | ||
616 | spca5xxRegRead(gspca_dev->dev, 0x816b, &Data, 1); | ||
617 | reg_write(gspca_dev->dev, 0x00, 0x816b, Data); | ||
618 | } | ||
619 | |||
620 | /* this function is called at probe time */ | ||
621 | static int sd_config(struct gspca_dev *gspca_dev, | ||
622 | const struct usb_device_id *id) | ||
623 | { | ||
624 | struct sd *sd = (struct sd *) gspca_dev; | ||
625 | struct cam *cam; | ||
626 | __u16 vendor; | ||
627 | __u16 product; | ||
628 | |||
629 | vendor = id->idVendor; | ||
630 | product = id->idProduct; | ||
631 | switch (vendor) { | ||
632 | case 0x040a: /* Kodak cameras */ | ||
633 | /* switch (product) { */ | ||
634 | /* case 0x0300: */ | ||
635 | sd->subtype = KodakEZ200; | ||
636 | /* break; */ | ||
637 | /* } */ | ||
638 | break; | ||
639 | case 0x041e: /* Creative cameras */ | ||
640 | /* switch (product) { */ | ||
641 | /* case 0x400a: */ | ||
642 | sd->subtype = CreativePCCam300; | ||
643 | /* break; */ | ||
644 | /* } */ | ||
645 | break; | ||
646 | case 0x046d: /* Logitech Labtec */ | ||
647 | switch (product) { | ||
648 | case 0x0890: | ||
649 | sd->subtype = LogitechTraveler; | ||
650 | break; | ||
651 | case 0x0900: | ||
652 | sd->subtype = LogitechClickSmart310; | ||
653 | break; | ||
654 | case 0x0901: | ||
655 | sd->subtype = LogitechClickSmart510; | ||
656 | break; | ||
657 | } | ||
658 | break; | ||
659 | case 0x04a5: /* Benq */ | ||
660 | /* switch (product) { */ | ||
661 | /* case 0x300c: */ | ||
662 | sd->subtype = BenqDC1016; | ||
663 | /* break; */ | ||
664 | /* } */ | ||
665 | break; | ||
666 | case 0x04fc: /* SunPlus */ | ||
667 | /* switch (product) { */ | ||
668 | /* case 0x7333: */ | ||
669 | sd->subtype = PalmPixDC85; | ||
670 | /* break; */ | ||
671 | /* } */ | ||
672 | break; | ||
673 | case 0x055f: /* Mustek cameras */ | ||
674 | switch (product) { | ||
675 | case 0xc200: | ||
676 | sd->subtype = MustekGsmart300; | ||
677 | break; | ||
678 | case 0xc220: | ||
679 | sd->subtype = Gsmartmini; | ||
680 | break; | ||
681 | } | ||
682 | break; | ||
683 | case 0x06bd: /* Agfa Cl20 */ | ||
684 | /* switch (product) { */ | ||
685 | /* case 0x0404: */ | ||
686 | sd->subtype = AgfaCl20; | ||
687 | /* break; */ | ||
688 | /* } */ | ||
689 | break; | ||
690 | case 0x06be: /* Optimedia */ | ||
691 | /* switch (product) { */ | ||
692 | /* case 0x0800: */ | ||
693 | sd->subtype = Optimedia; | ||
694 | /* break; */ | ||
695 | /* } */ | ||
696 | break; | ||
697 | case 0x084d: /* D-Link / Minton */ | ||
698 | /* switch (product) { */ | ||
699 | /* case 0x0003: * DSC-350 / S-Cam F5 */ | ||
700 | sd->subtype = DLinkDSC350; | ||
701 | /* break; */ | ||
702 | /* } */ | ||
703 | break; | ||
704 | case 0x08ca: /* Aiptek */ | ||
705 | /* switch (product) { */ | ||
706 | /* case 0x0103: */ | ||
707 | sd->subtype = AiptekPocketDV; | ||
708 | /* break; */ | ||
709 | /* } */ | ||
710 | break; | ||
711 | case 0x2899: /* ToptroIndustrial */ | ||
712 | /* switch (product) { */ | ||
713 | /* case 0x012c: */ | ||
714 | sd->subtype = ToptroIndus; | ||
715 | /* break; */ | ||
716 | /* } */ | ||
717 | break; | ||
718 | case 0x8086: /* Intel */ | ||
719 | /* switch (product) { */ | ||
720 | /* case 0x0630: * Pocket PC Camera */ | ||
721 | sd->subtype = IntelPocketPCCamera; | ||
722 | /* break; */ | ||
723 | /* } */ | ||
724 | break; | ||
725 | } | ||
726 | cam = &gspca_dev->cam; | ||
727 | cam->dev_name = (char *) id->driver_info; | ||
728 | cam->epaddr = 0x01; | ||
729 | if (sd->subtype != LogitechClickSmart310) { | ||
730 | cam->cam_mode = vga_mode; | ||
731 | cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; | ||
732 | } else { | ||
733 | cam->cam_mode = sif_mode; | ||
734 | cam->nmodes = sizeof sif_mode / sizeof sif_mode[0]; | ||
735 | } | ||
736 | sd->qindex = 5; | ||
737 | sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; | ||
738 | sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; | ||
739 | sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; | ||
740 | return 0; | ||
741 | } | ||
742 | |||
743 | /* this function is called at open time */ | ||
744 | static int sd_open(struct gspca_dev *gspca_dev) | ||
745 | { | ||
746 | struct sd *sd = (struct sd *) gspca_dev; | ||
747 | |||
748 | /* initialisation of spca500 based cameras is deferred */ | ||
749 | PDEBUG(D_STREAM, "SPCA500 init"); | ||
750 | if (sd->subtype == LogitechClickSmart310) | ||
751 | spca500_clksmart310_init(gspca_dev); | ||
752 | /* else | ||
753 | spca500_initialise(gspca_dev); */ | ||
754 | PDEBUG(D_STREAM, "SPCA500 init done"); | ||
755 | return 0; | ||
756 | } | ||
757 | |||
758 | static void sd_start(struct gspca_dev *gspca_dev) | ||
759 | { | ||
760 | struct sd *sd = (struct sd *) gspca_dev; | ||
761 | int err; | ||
762 | __u8 Data; | ||
763 | __u8 xmult, ymult; | ||
764 | |||
765 | if (sd->subtype == LogitechClickSmart310) { | ||
766 | xmult = 0x16; | ||
767 | ymult = 0x12; | ||
768 | } else { | ||
769 | xmult = 0x28; | ||
770 | ymult = 0x1e; | ||
771 | } | ||
772 | |||
773 | /* is there a sensor here ? */ | ||
774 | spca5xxRegRead(gspca_dev->dev, 0x8a04, &Data, 1); | ||
775 | PDEBUG(D_STREAM, "Spca500 Sensor Address 0x%02X", Data); | ||
776 | PDEBUG(D_STREAM, "Spca500 curr_mode: %d Xmult: 0x%02X, Ymult: 0x%02X", | ||
777 | gspca_dev->curr_mode, xmult, ymult); | ||
778 | |||
779 | /* setup qtable */ | ||
780 | switch (sd->subtype) { | ||
781 | case LogitechClickSmart310: | ||
782 | spca500_setmode(gspca_dev, xmult, ymult); | ||
783 | |||
784 | /* enable drop packet */ | ||
785 | reg_write(gspca_dev->dev, 0x00, 0x850a, 0x0001); | ||
786 | reg_write(gspca_dev->dev, 0x00, 0x8880, 3); | ||
787 | err = spca50x_setup_qtable(gspca_dev, | ||
788 | 0x00, 0x8800, 0x8840, | ||
789 | qtable_creative_pccam); | ||
790 | if (err < 0) | ||
791 | PDEBUG(D_ERR, "spca50x_setup_qtable failed"); | ||
792 | /* Init SDRAM - needed for SDRAM access */ | ||
793 | reg_write(gspca_dev->dev, 0x00, 0x870a, 0x04); | ||
794 | |||
795 | /* switch to video camera mode */ | ||
796 | reg_write(gspca_dev->dev, 0x00, 0x8000, 0x0004); | ||
797 | msleep(500); | ||
798 | if (reg_readwait(gspca_dev->dev, 0, 0x8000, 0x44) != 0) | ||
799 | PDEBUG(D_ERR, "reg_readwait() failed"); | ||
800 | |||
801 | spca5xxRegRead(gspca_dev->dev, 0x816b, &Data, 1); | ||
802 | reg_write(gspca_dev->dev, 0x00, 0x816b, Data); | ||
803 | |||
804 | spca500_synch310(gspca_dev); | ||
805 | |||
806 | write_vector(gspca_dev, spca500_visual_defaults); | ||
807 | spca500_setmode(gspca_dev, xmult, ymult); | ||
808 | /* enable drop packet */ | ||
809 | reg_write(gspca_dev->dev, 0x00, 0x850a, 0x0001); | ||
810 | PDEBUG(D_ERR, "failed to enable drop packet"); | ||
811 | reg_write(gspca_dev->dev, 0x00, 0x8880, 3); | ||
812 | err = spca50x_setup_qtable(gspca_dev, | ||
813 | 0x00, 0x8800, 0x8840, | ||
814 | qtable_creative_pccam); | ||
815 | if (err < 0) | ||
816 | PDEBUG(D_ERR, "spca50x_setup_qtable failed"); | ||
817 | |||
818 | /* Init SDRAM - needed for SDRAM access */ | ||
819 | reg_write(gspca_dev->dev, 0x00, 0x870a, 0x04); | ||
820 | |||
821 | /* switch to video camera mode */ | ||
822 | reg_write(gspca_dev->dev, 0x00, 0x8000, 0x0004); | ||
823 | |||
824 | if (reg_readwait(gspca_dev->dev, 0, 0x8000, 0x44) != 0) | ||
825 | PDEBUG(D_ERR, "reg_readwait() failed"); | ||
826 | |||
827 | spca5xxRegRead(gspca_dev->dev, 0x816b, &Data, 1); | ||
828 | reg_write(gspca_dev->dev, 0x00, 0x816b, Data); | ||
829 | break; | ||
830 | case CreativePCCam300: /* Creative PC-CAM 300 640x480 CCD */ | ||
831 | case IntelPocketPCCamera: /* FIXME: Temporary fix for | ||
832 | * Intel Pocket PC Camera | ||
833 | * - NWG (Sat 29th March 2003) */ | ||
834 | |||
835 | /* do a full reset */ | ||
836 | if ((err = spca500_full_reset(gspca_dev)) < 0) | ||
837 | PDEBUG(D_ERR, "spca500_full_reset failed"); | ||
838 | |||
839 | /* enable drop packet */ | ||
840 | err = reg_write(gspca_dev->dev, 0x00, 0x850a, 0x0001); | ||
841 | if (err < 0) | ||
842 | PDEBUG(D_ERR, "failed to enable drop packet"); | ||
843 | reg_write(gspca_dev->dev, 0x00, 0x8880, 3); | ||
844 | err = spca50x_setup_qtable(gspca_dev, | ||
845 | 0x00, 0x8800, 0x8840, | ||
846 | qtable_creative_pccam); | ||
847 | if (err < 0) | ||
848 | PDEBUG(D_ERR, "spca50x_setup_qtable failed"); | ||
849 | |||
850 | spca500_setmode(gspca_dev, xmult, ymult); | ||
851 | reg_write(gspca_dev->dev, 0x20, 0x0001, 0x0004); | ||
852 | |||
853 | /* switch to video camera mode */ | ||
854 | reg_write(gspca_dev->dev, 0x00, 0x8000, 0x0004); | ||
855 | |||
856 | if (reg_readwait(gspca_dev->dev, 0, 0x8000, 0x44) != 0) | ||
857 | PDEBUG(D_ERR, "reg_readwait() failed"); | ||
858 | |||
859 | spca5xxRegRead(gspca_dev->dev, 0x816b, &Data, 1); | ||
860 | reg_write(gspca_dev->dev, 0x00, 0x816b, Data); | ||
861 | |||
862 | /* write_vector(gspca_dev, spca500_visual_defaults); */ | ||
863 | break; | ||
864 | case KodakEZ200: /* Kodak EZ200 */ | ||
865 | |||
866 | /* do a full reset */ | ||
867 | err = spca500_full_reset(gspca_dev); | ||
868 | if (err < 0) | ||
869 | PDEBUG(D_ERR, "spca500_full_reset failed"); | ||
870 | /* enable drop packet */ | ||
871 | reg_write(gspca_dev->dev, 0x00, 0x850a, 0x0001); | ||
872 | reg_write(gspca_dev->dev, 0x00, 0x8880, 0); | ||
873 | err = spca50x_setup_qtable(gspca_dev, | ||
874 | 0x00, 0x8800, 0x8840, | ||
875 | qtable_kodak_ez200); | ||
876 | if (err < 0) | ||
877 | PDEBUG(D_ERR, "spca50x_setup_qtable failed"); | ||
878 | spca500_setmode(gspca_dev, xmult, ymult); | ||
879 | |||
880 | reg_write(gspca_dev->dev, 0x20, 0x0001, 0x0004); | ||
881 | |||
882 | /* switch to video camera mode */ | ||
883 | reg_write(gspca_dev->dev, 0x00, 0x8000, 0x0004); | ||
884 | |||
885 | if (reg_readwait(gspca_dev->dev, 0, 0x8000, 0x44) != 0) | ||
886 | PDEBUG(D_ERR, "reg_readwait() failed"); | ||
887 | |||
888 | spca5xxRegRead(gspca_dev->dev, 0x816b, &Data, 1); | ||
889 | reg_write(gspca_dev->dev, 0x00, 0x816b, Data); | ||
890 | |||
891 | /* write_vector(gspca_dev, spca500_visual_defaults); */ | ||
892 | break; | ||
893 | |||
894 | case BenqDC1016: | ||
895 | case DLinkDSC350: /* FamilyCam 300 */ | ||
896 | case AiptekPocketDV: /* Aiptek PocketDV */ | ||
897 | case Gsmartmini: /*Mustek Gsmart Mini */ | ||
898 | case MustekGsmart300: /* Mustek Gsmart 300 */ | ||
899 | case PalmPixDC85: | ||
900 | case Optimedia: | ||
901 | case ToptroIndus: | ||
902 | case AgfaCl20: | ||
903 | spca500_reinit(gspca_dev); | ||
904 | reg_write(gspca_dev->dev, 0x00, 0x0d01, 0x01); | ||
905 | /* enable drop packet */ | ||
906 | reg_write(gspca_dev->dev, 0x00, 0x850a, 0x0001); | ||
907 | |||
908 | err = spca50x_setup_qtable(gspca_dev, | ||
909 | 0x00, 0x8800, 0x8840, qtable_pocketdv); | ||
910 | if (err < 0) | ||
911 | PDEBUG(D_ERR, "spca50x_setup_qtable failed"); | ||
912 | reg_write(gspca_dev->dev, 0x00, 0x8880, 2); | ||
913 | |||
914 | /* familycam Quicksmart pocketDV stuff */ | ||
915 | reg_write(gspca_dev->dev, 0x00, 0x800a, 0x00); | ||
916 | /* Set agc transfer: synced inbetween frames */ | ||
917 | reg_write(gspca_dev->dev, 0x00, 0x820f, 0x01); | ||
918 | /* Init SDRAM - needed for SDRAM access */ | ||
919 | reg_write(gspca_dev->dev, 0x00, 0x870a, 0x04); | ||
920 | |||
921 | spca500_setmode(gspca_dev,xmult,ymult); | ||
922 | /* switch to video camera mode */ | ||
923 | reg_write(gspca_dev->dev, 0x00, 0x8000, 0x0004); | ||
924 | |||
925 | reg_readwait(gspca_dev->dev, 0, 0x8000, 0x44); | ||
926 | |||
927 | spca5xxRegRead(gspca_dev->dev, 0x816b, &Data, 1); | ||
928 | reg_write(gspca_dev->dev, 0x00, 0x816b, Data); | ||
929 | break; | ||
930 | case LogitechTraveler: | ||
931 | case LogitechClickSmart510: | ||
932 | reg_write(gspca_dev->dev, 0x02, 0x00, 0x00); | ||
933 | /* enable drop packet */ | ||
934 | reg_write(gspca_dev->dev, 0x00, 0x850a, 0x0001); | ||
935 | |||
936 | err = spca50x_setup_qtable(gspca_dev, | ||
937 | 0x00, 0x8800, | ||
938 | 0x8840, qtable_creative_pccam); | ||
939 | if (err < 0) | ||
940 | PDEBUG(D_ERR, "spca50x_setup_qtable failed"); | ||
941 | reg_write(gspca_dev->dev, 0x00, 0x8880, 3); | ||
942 | reg_write(gspca_dev->dev, 0x00, 0x800a, 0x00); | ||
943 | /* Init SDRAM - needed for SDRAM access */ | ||
944 | reg_write(gspca_dev->dev, 0x00, 0x870a, 0x04); | ||
945 | |||
946 | spca500_setmode(gspca_dev, xmult, ymult); | ||
947 | |||
948 | /* switch to video camera mode */ | ||
949 | reg_write(gspca_dev->dev, 0x00, 0x8000, 0x0004); | ||
950 | reg_readwait(gspca_dev->dev, 0, 0x8000, 0x44); | ||
951 | |||
952 | spca5xxRegRead(gspca_dev->dev, 0x816b, &Data, 1); | ||
953 | reg_write(gspca_dev->dev, 0x00, 0x816b, Data); | ||
954 | write_vector(gspca_dev, Clicksmart510_defaults); | ||
955 | break; | ||
956 | } | ||
957 | } | ||
958 | |||
959 | static void sd_stopN(struct gspca_dev *gspca_dev) | ||
960 | { | ||
961 | __u8 data = 0; | ||
962 | |||
963 | reg_write(gspca_dev->dev, 0, 0x8003, 0x00); | ||
964 | |||
965 | /* switch to video camera mode */ | ||
966 | reg_write(gspca_dev->dev, 0x00, 0x8000, 0x0004); | ||
967 | spca5xxRegRead(gspca_dev->dev, 0x8000, &data, 1); | ||
968 | PDEBUG(D_STREAM, "stop SPCA500 done reg8000: 0x%2x", data); | ||
969 | } | ||
970 | |||
971 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
972 | { | ||
973 | } | ||
974 | |||
975 | static void sd_close(struct gspca_dev *gspca_dev) | ||
976 | { | ||
977 | } | ||
978 | |||
979 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | ||
980 | struct gspca_frame *frame, /* target */ | ||
981 | unsigned char *data, /* isoc packet */ | ||
982 | int len) /* iso packet length */ | ||
983 | { | ||
984 | struct sd *sd = (struct sd *) gspca_dev; | ||
985 | int i; | ||
986 | unsigned char *s, *d; | ||
987 | static unsigned char ffd9[] = {0xff, 0xd9}; | ||
988 | |||
989 | /* frames are jpeg 4.1.1 without 0xff escape */ | ||
990 | if (data[0] == 0xff) { | ||
991 | if (data[1] != 0x01) { /* drop packet */ | ||
992 | /* gspca_dev->last_packet_type = DISCARD_PACKET; */ | ||
993 | return; | ||
994 | } | ||
995 | frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, | ||
996 | ffd9, 2); | ||
997 | |||
998 | /* put the JPEG header in the new frame */ | ||
999 | jpeg_put_header(gspca_dev, frame, | ||
1000 | ((struct sd *) gspca_dev)->qindex, | ||
1001 | 0x22); | ||
1002 | |||
1003 | data += SPCA500_OFFSET_DATA; | ||
1004 | len -= SPCA500_OFFSET_DATA; | ||
1005 | } else { | ||
1006 | data += 1; | ||
1007 | len -= 1; | ||
1008 | } | ||
1009 | |||
1010 | /* add 0x00 after 0xff */ | ||
1011 | for (i = len; --i >= 0; ) | ||
1012 | if (data[i] == 0xff) | ||
1013 | break; | ||
1014 | if (i < 0) { /* no 0xff */ | ||
1015 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); | ||
1016 | return; | ||
1017 | } | ||
1018 | s = data; | ||
1019 | d = sd->packet; | ||
1020 | for (i = 0; i < len; i++) { | ||
1021 | *d++ = *s++; | ||
1022 | if (s[-1] == 0xff) | ||
1023 | *d++ = 0x00; | ||
1024 | } | ||
1025 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, | ||
1026 | sd->packet, d - sd->packet); | ||
1027 | } | ||
1028 | |||
1029 | static void setbrightness(struct gspca_dev *gspca_dev) | ||
1030 | { | ||
1031 | struct sd *sd = (struct sd *) gspca_dev; | ||
1032 | |||
1033 | reg_write(gspca_dev->dev, 0x00, 0x8167, | ||
1034 | (__u8) (sd->brightness - 128)); | ||
1035 | } | ||
1036 | |||
1037 | static void getbrightness(struct gspca_dev *gspca_dev) | ||
1038 | { | ||
1039 | struct sd *sd = (struct sd *) gspca_dev; | ||
1040 | |||
1041 | sd->brightness = reg_read(gspca_dev->dev, 0x00, 0x8167, 1) + 128; | ||
1042 | } | ||
1043 | |||
1044 | static void setcontrast(struct gspca_dev *gspca_dev) | ||
1045 | { | ||
1046 | struct sd *sd = (struct sd *) gspca_dev; | ||
1047 | |||
1048 | reg_write(gspca_dev->dev, 0x00, 0x8168, sd->contrast >> 2); | ||
1049 | } | ||
1050 | |||
1051 | static void getcontrast(struct gspca_dev *gspca_dev) | ||
1052 | { | ||
1053 | struct sd *sd = (struct sd *) gspca_dev; | ||
1054 | |||
1055 | sd->contrast = reg_read(gspca_dev->dev, 0x0, 0x8168, 1) << 2; | ||
1056 | } | ||
1057 | |||
1058 | static void setcolors(struct gspca_dev *gspca_dev) | ||
1059 | { | ||
1060 | struct sd *sd = (struct sd *) gspca_dev; | ||
1061 | |||
1062 | reg_write(gspca_dev->dev, 0x00, 0x8169, sd->colors >> 2); | ||
1063 | } | ||
1064 | |||
1065 | static void getcolors(struct gspca_dev *gspca_dev) | ||
1066 | { | ||
1067 | struct sd *sd = (struct sd *) gspca_dev; | ||
1068 | |||
1069 | sd->colors = reg_read(gspca_dev->dev, 0x0, 0x8169, 1) << 2; | ||
1070 | } | ||
1071 | |||
1072 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | ||
1073 | { | ||
1074 | struct sd *sd = (struct sd *) gspca_dev; | ||
1075 | |||
1076 | sd->brightness = val; | ||
1077 | if (gspca_dev->streaming) | ||
1078 | setbrightness(gspca_dev); | ||
1079 | return 0; | ||
1080 | } | ||
1081 | |||
1082 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
1083 | { | ||
1084 | struct sd *sd = (struct sd *) gspca_dev; | ||
1085 | |||
1086 | getbrightness(gspca_dev); | ||
1087 | *val = sd->brightness; | ||
1088 | return 0; | ||
1089 | } | ||
1090 | |||
1091 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | ||
1092 | { | ||
1093 | struct sd *sd = (struct sd *) gspca_dev; | ||
1094 | |||
1095 | sd->contrast = val; | ||
1096 | if (gspca_dev->streaming) | ||
1097 | setcontrast(gspca_dev); | ||
1098 | return 0; | ||
1099 | } | ||
1100 | |||
1101 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) | ||
1102 | { | ||
1103 | struct sd *sd = (struct sd *) gspca_dev; | ||
1104 | |||
1105 | getcontrast(gspca_dev); | ||
1106 | *val = sd->contrast; | ||
1107 | return 0; | ||
1108 | } | ||
1109 | |||
1110 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) | ||
1111 | { | ||
1112 | struct sd *sd = (struct sd *) gspca_dev; | ||
1113 | |||
1114 | sd->colors = val; | ||
1115 | if (gspca_dev->streaming) | ||
1116 | setcolors(gspca_dev); | ||
1117 | return 0; | ||
1118 | } | ||
1119 | |||
1120 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) | ||
1121 | { | ||
1122 | struct sd *sd = (struct sd *) gspca_dev; | ||
1123 | |||
1124 | getcolors(gspca_dev); | ||
1125 | *val = sd->colors; | ||
1126 | return 0; | ||
1127 | } | ||
1128 | |||
1129 | /* sub-driver description */ | ||
1130 | static struct sd_desc sd_desc = { | ||
1131 | .name = MODULE_NAME, | ||
1132 | .ctrls = sd_ctrls, | ||
1133 | .nctrls = sizeof sd_ctrls / sizeof sd_ctrls[0], | ||
1134 | .config = sd_config, | ||
1135 | .open = sd_open, | ||
1136 | .start = sd_start, | ||
1137 | .stopN = sd_stopN, | ||
1138 | .stop0 = sd_stop0, | ||
1139 | .close = sd_close, | ||
1140 | .pkt_scan = sd_pkt_scan, | ||
1141 | }; | ||
1142 | |||
1143 | /* -- module initialisation -- */ | ||
1144 | #define DVNM(name) .driver_info = (kernel_ulong_t) name | ||
1145 | static __devinitdata struct usb_device_id device_table[] = { | ||
1146 | {USB_DEVICE(0x040a, 0x0300), DVNM("Kodak EZ200")}, | ||
1147 | {USB_DEVICE(0x041e, 0x400a), DVNM("Creative PC-CAM 300")}, | ||
1148 | {USB_DEVICE(0x046d, 0x0890), DVNM("Logitech QuickCam traveler")}, | ||
1149 | {USB_DEVICE(0x046d, 0x0900), DVNM("Logitech Inc. ClickSmart 310")}, | ||
1150 | {USB_DEVICE(0x046d, 0x0901), DVNM("Logitech Inc. ClickSmart 510")}, | ||
1151 | {USB_DEVICE(0x04a5, 0x300c), DVNM("Benq DC1016")}, | ||
1152 | {USB_DEVICE(0x04fc, 0x7333), DVNM("PalmPixDC85")}, | ||
1153 | {USB_DEVICE(0x055f, 0xc200), DVNM("Mustek Gsmart 300")}, | ||
1154 | {USB_DEVICE(0x055f, 0xc220), DVNM("Gsmart Mini")}, | ||
1155 | {USB_DEVICE(0x06bd, 0x0404), DVNM("Agfa CL20")}, | ||
1156 | {USB_DEVICE(0x06be, 0x0800), DVNM("Optimedia")}, | ||
1157 | {USB_DEVICE(0x084d, 0x0003), DVNM("D-Link DSC-350")}, | ||
1158 | {USB_DEVICE(0x08ca, 0x0103), DVNM("Aiptek PocketDV")}, | ||
1159 | {USB_DEVICE(0x2899, 0x012c), DVNM("Toptro Industrial")}, | ||
1160 | {USB_DEVICE(0x8086, 0x0630), DVNM("Intel Pocket PC Camera")}, | ||
1161 | {} | ||
1162 | }; | ||
1163 | MODULE_DEVICE_TABLE(usb, device_table); | ||
1164 | |||
1165 | /* -- device connect -- */ | ||
1166 | static int sd_probe(struct usb_interface *intf, | ||
1167 | const struct usb_device_id *id) | ||
1168 | { | ||
1169 | return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), | ||
1170 | THIS_MODULE); | ||
1171 | } | ||
1172 | |||
1173 | static struct usb_driver sd_driver = { | ||
1174 | .name = MODULE_NAME, | ||
1175 | .id_table = device_table, | ||
1176 | .probe = sd_probe, | ||
1177 | .disconnect = gspca_disconnect, | ||
1178 | }; | ||
1179 | |||
1180 | /* -- module insert / remove -- */ | ||
1181 | static int __init sd_mod_init(void) | ||
1182 | { | ||
1183 | if (usb_register(&sd_driver) < 0) | ||
1184 | return -1; | ||
1185 | PDEBUG(D_PROBE, "v%s registered", version); | ||
1186 | return 0; | ||
1187 | } | ||
1188 | static void __exit sd_mod_exit(void) | ||
1189 | { | ||
1190 | usb_deregister(&sd_driver); | ||
1191 | PDEBUG(D_PROBE, "deregistered"); | ||
1192 | } | ||
1193 | |||
1194 | module_init(sd_mod_init); | ||
1195 | module_exit(sd_mod_exit); | ||
diff --git a/drivers/media/video/gspca/spca501.c b/drivers/media/video/gspca/spca501.c new file mode 100644 index 000000000000..c6468cf3506a --- /dev/null +++ b/drivers/media/video/gspca/spca501.c | |||
@@ -0,0 +1,2219 @@ | |||
1 | /* | ||
2 | * SPCA501 chip based cameras initialization data | ||
3 | * | ||
4 | * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #define MODULE_NAME "spca501" | ||
23 | |||
24 | #include "gspca.h" | ||
25 | |||
26 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) | ||
27 | static const char version[] = "2.1.0"; | ||
28 | |||
29 | MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); | ||
30 | MODULE_DESCRIPTION("GSPCA/SPCA501 USB Camera Driver"); | ||
31 | MODULE_LICENSE("GPL"); | ||
32 | |||
33 | /* specific webcam descriptor */ | ||
34 | struct sd { | ||
35 | struct gspca_dev gspca_dev; /* !! must be the first item */ | ||
36 | |||
37 | unsigned short contrast; | ||
38 | __u8 brightness; | ||
39 | __u8 colors; | ||
40 | |||
41 | char subtype; | ||
42 | #define Arowana300KCMOSCamera 0 | ||
43 | #define IntelCreateAndShare 1 | ||
44 | #define KodakDVC325 2 | ||
45 | #define MystFromOriUnknownCamera 3 | ||
46 | #define SmileIntlCamera 4 | ||
47 | #define ThreeComHomeConnectLite 5 | ||
48 | #define ViewQuestM318B 6 | ||
49 | }; | ||
50 | |||
51 | /* V4L2 controls supported by the driver */ | ||
52 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
53 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
54 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | ||
55 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | ||
56 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); | ||
57 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); | ||
58 | |||
59 | static struct ctrl sd_ctrls[] = { | ||
60 | #define MY_BRIGHTNESS 0 | ||
61 | { | ||
62 | { | ||
63 | .id = V4L2_CID_BRIGHTNESS, | ||
64 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
65 | .name = "Brightness", | ||
66 | .minimum = 0, | ||
67 | .maximum = 127, | ||
68 | .step = 1, | ||
69 | .default_value = 63, | ||
70 | }, | ||
71 | .set = sd_setbrightness, | ||
72 | .get = sd_getbrightness, | ||
73 | }, | ||
74 | #define MY_CONTRAST 1 | ||
75 | { | ||
76 | { | ||
77 | .id = V4L2_CID_CONTRAST, | ||
78 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
79 | .name = "Contrast", | ||
80 | .minimum = 0, | ||
81 | .maximum = 0xffff, | ||
82 | .step = 1, | ||
83 | .default_value = 0xaa00, | ||
84 | }, | ||
85 | .set = sd_setcontrast, | ||
86 | .get = sd_getcontrast, | ||
87 | }, | ||
88 | #define MY_COLOR 2 | ||
89 | { | ||
90 | { | ||
91 | .id = V4L2_CID_SATURATION, | ||
92 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
93 | .name = "Color", | ||
94 | .minimum = 0, | ||
95 | .maximum = 63, | ||
96 | .step = 1, | ||
97 | .default_value = 31, | ||
98 | }, | ||
99 | .set = sd_setcolors, | ||
100 | .get = sd_getcolors, | ||
101 | }, | ||
102 | }; | ||
103 | |||
104 | static struct cam_mode vga_mode[] = { | ||
105 | {V4L2_PIX_FMT_SPCA501, 160, 120, 2}, | ||
106 | {V4L2_PIX_FMT_SPCA501, 320, 240, 1}, | ||
107 | {V4L2_PIX_FMT_SPCA501, 640, 480, 0}, | ||
108 | }; | ||
109 | |||
110 | #define SPCA50X_REG_USB 0x2 /* spca505 501 */ | ||
111 | /* | ||
112 | * Data to initialize a SPCA501. From a capture file provided by Bill Roehl | ||
113 | * With SPCA501 chip description | ||
114 | */ | ||
115 | #define CCDSP_SET /* set CCDSP parameters */ | ||
116 | #define TG_SET /* set time generator set */ | ||
117 | #undef DSPWIN_SET /* set DSP windows parameters */ | ||
118 | #undef ALTER_GAMA /* Set alternate set to YUV transform coeffs. */ | ||
119 | #define SPCA501_SNAPBIT 0x80 | ||
120 | #define SPCA501_SNAPCTRL 0x10 | ||
121 | /* Frame packet header offsets for the spca501 */ | ||
122 | #define SPCA501_OFFSET_GPIO 1 | ||
123 | #define SPCA501_OFFSET_TYPE 2 | ||
124 | #define SPCA501_OFFSET_TURN3A 3 | ||
125 | #define SPCA501_OFFSET_FRAMSEQ 4 | ||
126 | #define SPCA501_OFFSET_COMPRESS 5 | ||
127 | #define SPCA501_OFFSET_QUANT 6 | ||
128 | #define SPCA501_OFFSET_QUANT2 7 | ||
129 | #define SPCA501_OFFSET_DATA 8 | ||
130 | |||
131 | #define SPCA501_PROP_COMP_ENABLE(d) ((d) & 1) | ||
132 | #define SPCA501_PROP_SNAP(d) ((d) & 0x40) | ||
133 | #define SPCA501_PROP_SNAP_CTRL(d) ((d) & 0x10) | ||
134 | #define SPCA501_PROP_COMP_THRESH(d) (((d) & 0x0e) >> 1) | ||
135 | #define SPCA501_PROP_COMP_QUANT(d) (((d) & 0x70) >> 4) | ||
136 | |||
137 | /* SPCA501 CCDSP control */ | ||
138 | #define SPCA501_REG_CCDSP 0x01 | ||
139 | /* SPCA501 control/status registers */ | ||
140 | #define SPCA501_REG_CTLRL 0x02 | ||
141 | |||
142 | /* registers for color correction and YUV transformation */ | ||
143 | #define SPCA501_A11 0x08 | ||
144 | #define SPCA501_A12 0x09 | ||
145 | #define SPCA501_A13 0x0A | ||
146 | #define SPCA501_A21 0x0B | ||
147 | #define SPCA501_A22 0x0C | ||
148 | #define SPCA501_A23 0x0D | ||
149 | #define SPCA501_A31 0x0E | ||
150 | #define SPCA501_A32 0x0F | ||
151 | #define SPCA501_A33 0x10 | ||
152 | |||
153 | /* Data for video camera initialization before capturing */ | ||
154 | static __u16 spca501_open_data[][3] = { | ||
155 | /* bmRequest,value,index */ | ||
156 | |||
157 | {0x2, 0x50, 0x00}, /* C/S enable soft reset */ | ||
158 | {0x2, 0x40, 0x00}, /* C/S disable soft reset */ | ||
159 | {0x2, 0x02, 0x05}, /* C/S general purpose I/O data */ | ||
160 | {0x2, 0x03, 0x05}, /* C/S general purpose I/O data */ | ||
161 | |||
162 | #ifdef CCDSP_SET | ||
163 | {0x1, 0x38, 0x01}, /* CCDSP options */ | ||
164 | {0x1, 0x05, 0x02}, /* CCDSP Optical black level for user settings */ | ||
165 | {0x1, 0xC0, 0x03}, /* CCDSP Optical black settings */ | ||
166 | |||
167 | {0x1, 0x67, 0x07}, | ||
168 | {0x1, 0x63, 0x3f}, /* CCDSP CCD gamma enable */ | ||
169 | {0x1, 0x03, 0x56}, /* Add gamma correction */ | ||
170 | |||
171 | {0x1, 0xFF, 0x15}, /* CCDSP High luminance for white balance */ | ||
172 | {0x1, 0x01, 0x16}, /* CCDSP Low luminance for white balance */ | ||
173 | |||
174 | /* Color correction and RGB-to-YUV transformation coefficients changing */ | ||
175 | #ifdef ALTER_GAMA | ||
176 | {0x0, 0x00, 0x08}, /* A11 */ | ||
177 | {0x0, 0x00, 0x09}, /* A12 */ | ||
178 | {0x0, 0x90, 0x0A}, /* A13 */ | ||
179 | {0x0, 0x12, 0x0B}, /* A21 */ | ||
180 | {0x0, 0x00, 0x0C}, /* A22 */ | ||
181 | {0x0, 0x00, 0x0D}, /* A23 */ | ||
182 | {0x0, 0x00, 0x0E}, /* A31 */ | ||
183 | {0x0, 0x02, 0x0F}, /* A32 */ | ||
184 | {0x0, 0x00, 0x10}, /* A33 */ | ||
185 | #else | ||
186 | {0x1, 0x2a, 0x08}, /* A11 0x31 */ | ||
187 | {0x1, 0xf8, 0x09}, /* A12 f8 */ | ||
188 | {0x1, 0xf8, 0x0A}, /* A13 f8 */ | ||
189 | {0x1, 0xf8, 0x0B}, /* A21 f8 */ | ||
190 | {0x1, 0x14, 0x0C}, /* A22 0x14 */ | ||
191 | {0x1, 0xf8, 0x0D}, /* A23 f8 */ | ||
192 | {0x1, 0xf8, 0x0E}, /* A31 f8 */ | ||
193 | {0x1, 0xf8, 0x0F}, /* A32 f8 */ | ||
194 | {0x1, 0x20, 0x10}, /* A33 0x20 */ | ||
195 | #endif | ||
196 | {0x1, 0x00, 0x11}, /* R offset */ | ||
197 | {0x1, 0x00, 0x12}, /* G offset */ | ||
198 | {0x1, 0x00, 0x13}, /* B offset */ | ||
199 | {0x1, 0x00, 0x14}, /* GB offset */ | ||
200 | |||
201 | #endif | ||
202 | |||
203 | #ifdef TG_SET | ||
204 | /* Time generator manipulations */ | ||
205 | {0x0, 0xfc, 0x0}, /* Set up high bits of shutter speed */ | ||
206 | {0x0, 0x01, 0x1}, /* Set up low bits of shutter speed */ | ||
207 | |||
208 | {0x0, 0xe4, 0x04}, /* DCLK*2 clock phase adjustment */ | ||
209 | {0x0, 0x08, 0x05}, /* ADCK phase adjustment, inv. ext. VB */ | ||
210 | {0x0, 0x03, 0x06}, /* FR phase adjustment */ | ||
211 | {0x0, 0x01, 0x07}, /* FCDS phase adjustment */ | ||
212 | {0x0, 0x39, 0x08}, /* FS phase adjustment */ | ||
213 | {0x0, 0x88, 0x0a}, /* FH1 phase and delay adjustment */ | ||
214 | {0x0, 0x03, 0x0f}, /* pixel identification */ | ||
215 | {0x0, 0x00, 0x11}, /* clock source selection (default) */ | ||
216 | |||
217 | /*VERY strange manipulations with | ||
218 | * select DMCLP or OBPX to be ADCLP output (0x0C) | ||
219 | * OPB always toggle or not (0x0D) but they allow | ||
220 | * us to set up brightness | ||
221 | */ | ||
222 | {0x0, 0x01, 0x0c}, | ||
223 | {0x0, 0xe0, 0x0d}, | ||
224 | /* Done */ | ||
225 | #endif | ||
226 | |||
227 | #ifdef DSPWIN_SET | ||
228 | {0x1, 0xa0, 0x01}, /* Setting image processing parameters */ | ||
229 | {0x1, 0x1c, 0x17}, /* Changing Windows positions X1 */ | ||
230 | {0x1, 0xe2, 0x19}, /* X2 */ | ||
231 | {0x1, 0x1c, 0x1b}, /* X3 */ | ||
232 | {0x1, 0xe2, 0x1d}, /* X4 */ | ||
233 | {0x1, 0x5f, 0x1f}, /* X5 */ | ||
234 | {0x1, 0x32, 0x20}, /* Y5 */ | ||
235 | {0x1, 0x01, 0x10}, /* Changing A33 */ | ||
236 | #endif | ||
237 | |||
238 | {0x2, 0x204a, 0x07},/* Setting video compression & resolution 160x120 */ | ||
239 | {0x2, 0x94, 0x06}, /* Setting video no compression */ | ||
240 | {} | ||
241 | }; | ||
242 | |||
243 | /* | ||
244 | The SPCAxxx docs from Sunplus document these values | ||
245 | in tables, one table per register number. In the data | ||
246 | below, dmRequest is the register number, index is the Addr, | ||
247 | and value is a combination of Bit values. | ||
248 | Bit Value (hex) | ||
249 | 0 01 | ||
250 | 1 02 | ||
251 | 2 04 | ||
252 | 3 08 | ||
253 | 4 10 | ||
254 | 5 20 | ||
255 | 6 40 | ||
256 | 7 80 | ||
257 | */ | ||
258 | |||
259 | /* Data for chip initialization (set default values) */ | ||
260 | static __u16 spca501_init_data[][3] = { | ||
261 | /* Set all the values to powerup defaults */ | ||
262 | /* bmRequest,value,index */ | ||
263 | {0x0, 0xAA, 0x00}, | ||
264 | {0x0, 0x02, 0x01}, | ||
265 | {0x0, 0x01, 0x02}, | ||
266 | {0x0, 0x02, 0x03}, | ||
267 | {0x0, 0xCE, 0x04}, | ||
268 | {0x0, 0x00, 0x05}, | ||
269 | {0x0, 0x00, 0x06}, | ||
270 | {0x0, 0x00, 0x07}, | ||
271 | {0x0, 0x00, 0x08}, | ||
272 | {0x0, 0x00, 0x09}, | ||
273 | {0x0, 0x90, 0x0A}, | ||
274 | {0x0, 0x12, 0x0B}, | ||
275 | {0x0, 0x00, 0x0C}, | ||
276 | {0x0, 0x00, 0x0D}, | ||
277 | {0x0, 0x00, 0x0E}, | ||
278 | {0x0, 0x02, 0x0F}, | ||
279 | {0x0, 0x00, 0x10}, | ||
280 | {0x0, 0x00, 0x11}, | ||
281 | {0x0, 0x00, 0x12}, | ||
282 | {0x0, 0x00, 0x13}, | ||
283 | {0x0, 0x00, 0x14}, | ||
284 | {0x0, 0x00, 0x15}, | ||
285 | {0x0, 0x00, 0x16}, | ||
286 | {0x0, 0x00, 0x17}, | ||
287 | {0x0, 0x00, 0x18}, | ||
288 | {0x0, 0x00, 0x19}, | ||
289 | {0x0, 0x00, 0x1A}, | ||
290 | {0x0, 0x00, 0x1B}, | ||
291 | {0x0, 0x00, 0x1C}, | ||
292 | {0x0, 0x00, 0x1D}, | ||
293 | {0x0, 0x00, 0x1E}, | ||
294 | {0x0, 0x00, 0x1F}, | ||
295 | {0x0, 0x00, 0x20}, | ||
296 | {0x0, 0x00, 0x21}, | ||
297 | {0x0, 0x00, 0x22}, | ||
298 | {0x0, 0x00, 0x23}, | ||
299 | {0x0, 0x00, 0x24}, | ||
300 | {0x0, 0x00, 0x25}, | ||
301 | {0x0, 0x00, 0x26}, | ||
302 | {0x0, 0x00, 0x27}, | ||
303 | {0x0, 0x00, 0x28}, | ||
304 | {0x0, 0x00, 0x29}, | ||
305 | {0x0, 0x00, 0x2A}, | ||
306 | {0x0, 0x00, 0x2B}, | ||
307 | {0x0, 0x00, 0x2C}, | ||
308 | {0x0, 0x00, 0x2D}, | ||
309 | {0x0, 0x00, 0x2E}, | ||
310 | {0x0, 0x00, 0x2F}, | ||
311 | {0x0, 0x00, 0x30}, | ||
312 | {0x0, 0x00, 0x31}, | ||
313 | {0x0, 0x00, 0x32}, | ||
314 | {0x0, 0x00, 0x33}, | ||
315 | {0x0, 0x00, 0x34}, | ||
316 | {0x0, 0x00, 0x35}, | ||
317 | {0x0, 0x00, 0x36}, | ||
318 | {0x0, 0x00, 0x37}, | ||
319 | {0x0, 0x00, 0x38}, | ||
320 | {0x0, 0x00, 0x39}, | ||
321 | {0x0, 0x00, 0x3A}, | ||
322 | {0x0, 0x00, 0x3B}, | ||
323 | {0x0, 0x00, 0x3C}, | ||
324 | {0x0, 0x00, 0x3D}, | ||
325 | {0x0, 0x00, 0x3E}, | ||
326 | {0x0, 0x00, 0x3F}, | ||
327 | {0x0, 0x00, 0x40}, | ||
328 | {0x0, 0x00, 0x41}, | ||
329 | {0x0, 0x00, 0x42}, | ||
330 | {0x0, 0x00, 0x43}, | ||
331 | {0x0, 0x00, 0x44}, | ||
332 | {0x0, 0x00, 0x45}, | ||
333 | {0x0, 0x00, 0x46}, | ||
334 | {0x0, 0x00, 0x47}, | ||
335 | {0x0, 0x00, 0x48}, | ||
336 | {0x0, 0x00, 0x49}, | ||
337 | {0x0, 0x00, 0x4A}, | ||
338 | {0x0, 0x00, 0x4B}, | ||
339 | {0x0, 0x00, 0x4C}, | ||
340 | {0x0, 0x00, 0x4D}, | ||
341 | {0x0, 0x00, 0x4E}, | ||
342 | {0x0, 0x00, 0x4F}, | ||
343 | {0x0, 0x00, 0x50}, | ||
344 | {0x0, 0x00, 0x51}, | ||
345 | {0x0, 0x00, 0x52}, | ||
346 | {0x0, 0x00, 0x53}, | ||
347 | {0x0, 0x00, 0x54}, | ||
348 | {0x0, 0x00, 0x55}, | ||
349 | {0x0, 0x00, 0x56}, | ||
350 | {0x0, 0x00, 0x57}, | ||
351 | {0x0, 0x00, 0x58}, | ||
352 | {0x0, 0x00, 0x59}, | ||
353 | {0x0, 0x00, 0x5A}, | ||
354 | {0x0, 0x00, 0x5B}, | ||
355 | {0x0, 0x00, 0x5C}, | ||
356 | {0x0, 0x00, 0x5D}, | ||
357 | {0x0, 0x00, 0x5E}, | ||
358 | {0x0, 0x00, 0x5F}, | ||
359 | {0x0, 0x00, 0x60}, | ||
360 | {0x0, 0x00, 0x61}, | ||
361 | {0x0, 0x00, 0x62}, | ||
362 | {0x0, 0x00, 0x63}, | ||
363 | {0x0, 0x00, 0x64}, | ||
364 | {0x0, 0x00, 0x65}, | ||
365 | {0x0, 0x00, 0x66}, | ||
366 | {0x0, 0x00, 0x67}, | ||
367 | {0x0, 0x00, 0x68}, | ||
368 | {0x0, 0x00, 0x69}, | ||
369 | {0x0, 0x00, 0x6A}, | ||
370 | {0x0, 0x00, 0x6B}, | ||
371 | {0x0, 0x00, 0x6C}, | ||
372 | {0x0, 0x00, 0x6D}, | ||
373 | {0x0, 0x00, 0x6E}, | ||
374 | {0x0, 0x00, 0x6F}, | ||
375 | {0x0, 0x00, 0x70}, | ||
376 | {0x0, 0x00, 0x71}, | ||
377 | {0x0, 0x00, 0x72}, | ||
378 | {0x0, 0x00, 0x73}, | ||
379 | {0x0, 0x00, 0x74}, | ||
380 | {0x0, 0x00, 0x75}, | ||
381 | {0x0, 0x00, 0x76}, | ||
382 | {0x0, 0x00, 0x77}, | ||
383 | {0x0, 0x00, 0x78}, | ||
384 | {0x0, 0x00, 0x79}, | ||
385 | {0x0, 0x00, 0x7A}, | ||
386 | {0x0, 0x00, 0x7B}, | ||
387 | {0x0, 0x00, 0x7C}, | ||
388 | {0x0, 0x00, 0x7D}, | ||
389 | {0x0, 0x00, 0x7E}, | ||
390 | {0x0, 0x00, 0x7F}, | ||
391 | {0x0, 0x00, 0x80}, | ||
392 | {0x0, 0x00, 0x81}, | ||
393 | {0x0, 0x00, 0x82}, | ||
394 | {0x0, 0x00, 0x83}, | ||
395 | {0x0, 0x00, 0x84}, | ||
396 | {0x0, 0x00, 0x85}, | ||
397 | {0x0, 0x00, 0x86}, | ||
398 | {0x0, 0x00, 0x87}, | ||
399 | {0x0, 0x00, 0x88}, | ||
400 | {0x0, 0x00, 0x89}, | ||
401 | {0x0, 0x00, 0x8A}, | ||
402 | {0x0, 0x00, 0x8B}, | ||
403 | {0x0, 0x00, 0x8C}, | ||
404 | {0x0, 0x00, 0x8D}, | ||
405 | {0x0, 0x00, 0x8E}, | ||
406 | {0x0, 0x00, 0x8F}, | ||
407 | {0x0, 0x00, 0x90}, | ||
408 | {0x0, 0x00, 0x91}, | ||
409 | {0x0, 0x00, 0x92}, | ||
410 | {0x0, 0x00, 0x93}, | ||
411 | {0x0, 0x00, 0x94}, | ||
412 | {0x0, 0x00, 0x95}, | ||
413 | {0x0, 0x00, 0x96}, | ||
414 | {0x0, 0x00, 0x97}, | ||
415 | {0x0, 0x00, 0x98}, | ||
416 | {0x0, 0x00, 0x99}, | ||
417 | {0x0, 0x00, 0x9A}, | ||
418 | {0x0, 0x00, 0x9B}, | ||
419 | {0x0, 0x00, 0x9C}, | ||
420 | {0x0, 0x00, 0x9D}, | ||
421 | {0x0, 0x00, 0x9E}, | ||
422 | {0x0, 0x00, 0x9F}, | ||
423 | {0x0, 0x00, 0xA0}, | ||
424 | {0x0, 0x00, 0xA1}, | ||
425 | {0x0, 0x00, 0xA2}, | ||
426 | {0x0, 0x00, 0xA3}, | ||
427 | {0x0, 0x00, 0xA4}, | ||
428 | {0x0, 0x00, 0xA5}, | ||
429 | {0x0, 0x00, 0xA6}, | ||
430 | {0x0, 0x00, 0xA7}, | ||
431 | {0x0, 0x00, 0xA8}, | ||
432 | {0x0, 0x00, 0xA9}, | ||
433 | {0x0, 0x00, 0xAA}, | ||
434 | {0x0, 0x00, 0xAB}, | ||
435 | {0x0, 0x00, 0xAC}, | ||
436 | {0x0, 0x00, 0xAD}, | ||
437 | {0x0, 0x00, 0xAE}, | ||
438 | {0x0, 0x00, 0xAF}, | ||
439 | {0x0, 0x00, 0xB0}, | ||
440 | {0x0, 0x00, 0xB1}, | ||
441 | {0x0, 0x00, 0xB2}, | ||
442 | {0x0, 0x00, 0xB3}, | ||
443 | {0x0, 0x00, 0xB4}, | ||
444 | {0x0, 0x00, 0xB5}, | ||
445 | {0x0, 0x00, 0xB6}, | ||
446 | {0x0, 0x00, 0xB7}, | ||
447 | {0x0, 0x00, 0xB8}, | ||
448 | {0x0, 0x00, 0xB9}, | ||
449 | {0x0, 0x00, 0xBA}, | ||
450 | {0x0, 0x00, 0xBB}, | ||
451 | {0x0, 0x00, 0xBC}, | ||
452 | {0x0, 0x00, 0xBD}, | ||
453 | {0x0, 0x00, 0xBE}, | ||
454 | {0x0, 0x00, 0xBF}, | ||
455 | {0x0, 0x00, 0xC0}, | ||
456 | {0x0, 0x00, 0xC1}, | ||
457 | {0x0, 0x00, 0xC2}, | ||
458 | {0x0, 0x00, 0xC3}, | ||
459 | {0x0, 0x00, 0xC4}, | ||
460 | {0x0, 0x00, 0xC5}, | ||
461 | {0x0, 0x00, 0xC6}, | ||
462 | {0x0, 0x00, 0xC7}, | ||
463 | {0x0, 0x00, 0xC8}, | ||
464 | {0x0, 0x00, 0xC9}, | ||
465 | {0x0, 0x00, 0xCA}, | ||
466 | {0x0, 0x00, 0xCB}, | ||
467 | {0x0, 0x00, 0xCC}, | ||
468 | {0x1, 0xF4, 0x00}, | ||
469 | {0x1, 0x38, 0x01}, | ||
470 | {0x1, 0x40, 0x02}, | ||
471 | {0x1, 0x0A, 0x03}, | ||
472 | {0x1, 0x40, 0x04}, | ||
473 | {0x1, 0x40, 0x05}, | ||
474 | {0x1, 0x40, 0x06}, | ||
475 | {0x1, 0x67, 0x07}, | ||
476 | {0x1, 0x31, 0x08}, | ||
477 | {0x1, 0x00, 0x09}, | ||
478 | {0x1, 0x00, 0x0A}, | ||
479 | {0x1, 0x00, 0x0B}, | ||
480 | {0x1, 0x14, 0x0C}, | ||
481 | {0x1, 0x00, 0x0D}, | ||
482 | {0x1, 0x00, 0x0E}, | ||
483 | {0x1, 0x00, 0x0F}, | ||
484 | {0x1, 0x1E, 0x10}, | ||
485 | {0x1, 0x00, 0x11}, | ||
486 | {0x1, 0x00, 0x12}, | ||
487 | {0x1, 0x00, 0x13}, | ||
488 | {0x1, 0x00, 0x14}, | ||
489 | {0x1, 0xFF, 0x15}, | ||
490 | {0x1, 0x01, 0x16}, | ||
491 | {0x1, 0x32, 0x17}, | ||
492 | {0x1, 0x23, 0x18}, | ||
493 | {0x1, 0xCE, 0x19}, | ||
494 | {0x1, 0x23, 0x1A}, | ||
495 | {0x1, 0x32, 0x1B}, | ||
496 | {0x1, 0x8D, 0x1C}, | ||
497 | {0x1, 0xCE, 0x1D}, | ||
498 | {0x1, 0x8D, 0x1E}, | ||
499 | {0x1, 0x00, 0x1F}, | ||
500 | {0x1, 0x00, 0x20}, | ||
501 | {0x1, 0xFF, 0x3E}, | ||
502 | {0x1, 0x02, 0x3F}, | ||
503 | {0x1, 0x00, 0x40}, | ||
504 | {0x1, 0x00, 0x41}, | ||
505 | {0x1, 0x00, 0x42}, | ||
506 | {0x1, 0x00, 0x43}, | ||
507 | {0x1, 0x00, 0x44}, | ||
508 | {0x1, 0x00, 0x45}, | ||
509 | {0x1, 0x00, 0x46}, | ||
510 | {0x1, 0x00, 0x47}, | ||
511 | {0x1, 0x00, 0x48}, | ||
512 | {0x1, 0x00, 0x49}, | ||
513 | {0x1, 0x00, 0x4A}, | ||
514 | {0x1, 0x00, 0x4B}, | ||
515 | {0x1, 0x00, 0x4C}, | ||
516 | {0x1, 0x00, 0x4D}, | ||
517 | {0x1, 0x00, 0x4E}, | ||
518 | {0x1, 0x00, 0x4F}, | ||
519 | {0x1, 0x00, 0x50}, | ||
520 | {0x1, 0x00, 0x51}, | ||
521 | {0x1, 0x00, 0x52}, | ||
522 | {0x1, 0x00, 0x53}, | ||
523 | {0x1, 0x00, 0x54}, | ||
524 | {0x1, 0x00, 0x55}, | ||
525 | {0x1, 0x00, 0x56}, | ||
526 | {0x1, 0x00, 0x57}, | ||
527 | {0x1, 0x00, 0x58}, | ||
528 | {0x1, 0x00, 0x59}, | ||
529 | {0x1, 0x00, 0x5A}, | ||
530 | {0x2, 0x03, 0x00}, | ||
531 | {0x2, 0x00, 0x01}, | ||
532 | {0x2, 0x00, 0x05}, | ||
533 | {0x2, 0x00, 0x06}, | ||
534 | {0x2, 0x00, 0x07}, | ||
535 | {0x2, 0x00, 0x10}, | ||
536 | {0x2, 0x00, 0x11}, | ||
537 | /* Strange - looks like the 501 driver doesn't do anything | ||
538 | * at insert time except read the EEPROM | ||
539 | */ | ||
540 | {} | ||
541 | }; | ||
542 | |||
543 | /* Data for video camera init before capture. | ||
544 | * Capture and decoding by Colin Peart. | ||
545 | * This is is for the 3com HomeConnect Lite which is spca501a based. | ||
546 | */ | ||
547 | static __u16 spca501_3com_open_data[][3] = { | ||
548 | /* bmRequest,value,index */ | ||
549 | {0x2, 0x0050, 0x0000}, /* C/S Enable TG soft reset, timing mode=010 */ | ||
550 | {0x2, 0x0043, 0x0000}, /* C/S Disable TG soft reset, timing mode=010 */ | ||
551 | {0x2, 0x0002, 0x0005}, /* C/S GPIO */ | ||
552 | {0x2, 0x0003, 0x0005}, /* C/S GPIO */ | ||
553 | |||
554 | #ifdef CCDSP_SET | ||
555 | {0x1, 0x0020, 0x0001}, /* CCDSP Options */ | ||
556 | |||
557 | {0x1, 0x0020, 0x0002}, /* CCDSP Black Level */ | ||
558 | {0x1, 0x006e, 0x0007}, /* CCDSP Gamma options */ | ||
559 | {0x1, 0x0090, 0x0015}, /* CCDSP Luminance Low */ | ||
560 | {0x1, 0x00ff, 0x0016}, /* CCDSP Luminance High */ | ||
561 | {0x1, 0x0003, 0x003F}, /* CCDSP Gamma correction toggle */ | ||
562 | |||
563 | #ifdef ALTER_GAMMA | ||
564 | {0x1, 0x0010, 0x0008}, /* CCDSP YUV A11 */ | ||
565 | {0x1, 0x0000, 0x0009}, /* CCDSP YUV A12 */ | ||
566 | {0x1, 0x0000, 0x000a}, /* CCDSP YUV A13 */ | ||
567 | {0x1, 0x0000, 0x000b}, /* CCDSP YUV A21 */ | ||
568 | {0x1, 0x0010, 0x000c}, /* CCDSP YUV A22 */ | ||
569 | {0x1, 0x0000, 0x000d}, /* CCDSP YUV A23 */ | ||
570 | {0x1, 0x0000, 0x000e}, /* CCDSP YUV A31 */ | ||
571 | {0x1, 0x0000, 0x000f}, /* CCDSP YUV A32 */ | ||
572 | {0x1, 0x0010, 0x0010}, /* CCDSP YUV A33 */ | ||
573 | {0x1, 0x0000, 0x0011}, /* CCDSP R Offset */ | ||
574 | {0x1, 0x0000, 0x0012}, /* CCDSP G Offset */ | ||
575 | {0x1, 0x0001, 0x0013}, /* CCDSP B Offset */ | ||
576 | {0x1, 0x0001, 0x0014}, /* CCDSP BG Offset */ | ||
577 | {0x1, 0x003f, 0x00C1}, /* CCDSP Gamma Correction Enable */ | ||
578 | #endif | ||
579 | #endif | ||
580 | |||
581 | #ifdef TG_SET | ||
582 | {0x0, 0x00fc, 0x0000}, /* TG Shutter Speed High Bits */ | ||
583 | {0x0, 0x0000, 0x0001}, /* TG Shutter Speed Low Bits */ | ||
584 | {0x0, 0x00e4, 0x0004}, /* TG DCLK*2 Adjust */ | ||
585 | {0x0, 0x0008, 0x0005}, /* TG ADCK Adjust */ | ||
586 | {0x0, 0x0003, 0x0006}, /* TG FR Phase Adjust */ | ||
587 | {0x0, 0x0001, 0x0007}, /* TG FCDS Phase Adjust */ | ||
588 | {0x0, 0x0039, 0x0008}, /* TG FS Phase Adjust */ | ||
589 | {0x0, 0x0088, 0x000a}, /* TG MH1 */ | ||
590 | {0x0, 0x0003, 0x000f}, /* TG Pixel ID */ | ||
591 | |||
592 | /* Like below, unexplained toglleing */ | ||
593 | {0x0, 0x0080, 0x000c}, | ||
594 | {0x0, 0x0000, 0x000d}, | ||
595 | {0x0, 0x0080, 0x000c}, | ||
596 | {0x0, 0x0004, 0x000d}, | ||
597 | {0x0, 0x0000, 0x000c}, | ||
598 | {0x0, 0x0000, 0x000d}, | ||
599 | {0x0, 0x0040, 0x000c}, | ||
600 | {0x0, 0x0017, 0x000d}, | ||
601 | {0x0, 0x00c0, 0x000c}, | ||
602 | {0x0, 0x0000, 0x000d}, | ||
603 | {0x0, 0x0080, 0x000c}, | ||
604 | {0x0, 0x0006, 0x000d}, | ||
605 | {0x0, 0x0080, 0x000c}, | ||
606 | {0x0, 0x0004, 0x000d}, | ||
607 | {0x0, 0x0002, 0x0003}, | ||
608 | #endif | ||
609 | |||
610 | #ifdef DSPWIN_SET | ||
611 | {0x1, 0x001c, 0x0017}, /* CCDSP W1 Start X */ | ||
612 | {0x1, 0x00e2, 0x0019}, /* CCDSP W2 Start X */ | ||
613 | {0x1, 0x001c, 0x001b}, /* CCDSP W3 Start X */ | ||
614 | {0x1, 0x00e2, 0x001d}, /* CCDSP W4 Start X */ | ||
615 | {0x1, 0x00aa, 0x001f}, /* CCDSP W5 Start X */ | ||
616 | {0x1, 0x0070, 0x0020}, /* CCDSP W5 Start Y */ | ||
617 | #endif | ||
618 | {0x0, 0x0001, 0x0010}, /* TG Start Clock */ | ||
619 | |||
620 | /* {0x2, 0x006a, 0x0001}, * C/S Enable ISOSYNCH Packet Engine */ | ||
621 | {0x2, 0x0068, 0x0001}, /* C/S Diable ISOSYNCH Packet Engine */ | ||
622 | {0x2, 0x0000, 0x0005}, | ||
623 | {0x2, 0x0043, 0x0000}, /* C/S Set Timing Mode, Disable TG soft reset */ | ||
624 | {0x2, 0x0043, 0x0000}, /* C/S Set Timing Mode, Disable TG soft reset */ | ||
625 | {0x2, 0x0002, 0x0005}, /* C/S GPIO */ | ||
626 | {0x2, 0x0003, 0x0005}, /* C/S GPIO */ | ||
627 | |||
628 | {0x2, 0x006a, 0x0001}, /* C/S Enable ISOSYNCH Packet Engine */ | ||
629 | {} | ||
630 | }; | ||
631 | |||
632 | /* | ||
633 | * Data used to initialize a SPCA501C with HV7131B sensor. | ||
634 | * From a capture file taken with USBSnoop v 1.5 | ||
635 | * I have a "SPCA501C pc camera chipset" manual by sunplus, but some | ||
636 | * of the value meanings are obscure or simply "reserved". | ||
637 | * to do list: | ||
638 | * 1) Understand what every value means | ||
639 | * 2) Understand why some values seem to appear more than once | ||
640 | * 3) Write a small comment for each line of the following arrays. | ||
641 | */ | ||
642 | static __u16 spca501c_arowana_open_data[][3] = { | ||
643 | /* bmRequest,value,index */ | ||
644 | {0x02, 0x0007, 0x0005}, | ||
645 | {0x02, 0xa048, 0x0000}, | ||
646 | {0x05, 0x0022, 0x0004}, | ||
647 | {0x01, 0x0006, 0x0011}, | ||
648 | {0x01, 0x00ff, 0x0012}, | ||
649 | {0x01, 0x0014, 0x0013}, | ||
650 | {0x01, 0x0000, 0x0014}, | ||
651 | {0x01, 0x0042, 0x0051}, | ||
652 | {0x01, 0x0040, 0x0052}, | ||
653 | {0x01, 0x0051, 0x0053}, | ||
654 | {0x01, 0x0040, 0x0054}, | ||
655 | {0x01, 0x0000, 0x0055}, | ||
656 | {0x00, 0x0025, 0x0000}, | ||
657 | {0x00, 0x0026, 0x0000}, | ||
658 | {0x00, 0x0001, 0x0000}, | ||
659 | {0x00, 0x0027, 0x0000}, | ||
660 | {0x00, 0x008a, 0x0000}, | ||
661 | {} | ||
662 | }; | ||
663 | |||
664 | static __u16 spca501c_arowana_init_data[][3] = { | ||
665 | /* bmRequest,value,index */ | ||
666 | {0x02, 0x0007, 0x0005}, | ||
667 | {0x02, 0xa048, 0x0000}, | ||
668 | {0x05, 0x0022, 0x0004}, | ||
669 | {0x01, 0x0006, 0x0011}, | ||
670 | {0x01, 0x00ff, 0x0012}, | ||
671 | {0x01, 0x0014, 0x0013}, | ||
672 | {0x01, 0x0000, 0x0014}, | ||
673 | {0x01, 0x0042, 0x0051}, | ||
674 | {0x01, 0x0040, 0x0052}, | ||
675 | {0x01, 0x0051, 0x0053}, | ||
676 | {0x01, 0x0040, 0x0054}, | ||
677 | {0x01, 0x0000, 0x0055}, | ||
678 | {0x00, 0x0025, 0x0000}, | ||
679 | {0x00, 0x0026, 0x0000}, | ||
680 | {0x00, 0x0001, 0x0000}, | ||
681 | {0x00, 0x0027, 0x0000}, | ||
682 | {0x00, 0x008a, 0x0000}, | ||
683 | {0x02, 0x0000, 0x0005}, | ||
684 | {0x02, 0x0007, 0x0005}, | ||
685 | {0x02, 0x2000, 0x0000}, | ||
686 | {0x05, 0x0022, 0x0004}, | ||
687 | {0x05, 0x0015, 0x0001}, | ||
688 | {0x05, 0x00ea, 0x0000}, | ||
689 | {0x05, 0x0021, 0x0001}, | ||
690 | {0x05, 0x00d2, 0x0000}, | ||
691 | {0x05, 0x0023, 0x0001}, | ||
692 | {0x05, 0x0003, 0x0000}, | ||
693 | {0x05, 0x0030, 0x0001}, | ||
694 | {0x05, 0x002b, 0x0000}, | ||
695 | {0x05, 0x0031, 0x0001}, | ||
696 | {0x05, 0x0023, 0x0000}, | ||
697 | {0x05, 0x0032, 0x0001}, | ||
698 | {0x05, 0x0023, 0x0000}, | ||
699 | {0x05, 0x0033, 0x0001}, | ||
700 | {0x05, 0x0023, 0x0000}, | ||
701 | {0x05, 0x0034, 0x0001}, | ||
702 | {0x05, 0x0002, 0x0000}, | ||
703 | {0x05, 0x0050, 0x0001}, | ||
704 | {0x05, 0x0000, 0x0000}, | ||
705 | {0x05, 0x0051, 0x0001}, | ||
706 | {0x05, 0x0000, 0x0000}, | ||
707 | {0x05, 0x0052, 0x0001}, | ||
708 | {0x05, 0x0000, 0x0000}, | ||
709 | {0x05, 0x0054, 0x0001}, | ||
710 | {0x05, 0x0001, 0x0000}, | ||
711 | {0x00, 0x0000, 0x0001}, | ||
712 | {0x00, 0x0000, 0x0002}, | ||
713 | {0x00, 0x000c, 0x0003}, | ||
714 | {0x00, 0x0000, 0x0004}, | ||
715 | {0x00, 0x0090, 0x0005}, | ||
716 | {0x00, 0x0000, 0x0006}, | ||
717 | {0x00, 0x0040, 0x0007}, | ||
718 | {0x00, 0x00c0, 0x0008}, | ||
719 | {0x00, 0x004a, 0x0009}, | ||
720 | {0x00, 0x0000, 0x000a}, | ||
721 | {0x00, 0x0000, 0x000b}, | ||
722 | {0x00, 0x0001, 0x000c}, | ||
723 | {0x00, 0x0001, 0x000d}, | ||
724 | {0x00, 0x0000, 0x000e}, | ||
725 | {0x00, 0x0002, 0x000f}, | ||
726 | {0x00, 0x0001, 0x0010}, | ||
727 | {0x00, 0x0000, 0x0011}, | ||
728 | {0x00, 0x0000, 0x0012}, | ||
729 | {0x00, 0x0002, 0x0020}, | ||
730 | {0x00, 0x0080, 0x0021}, | ||
731 | {0x00, 0x0001, 0x0022}, | ||
732 | {0x00, 0x00e0, 0x0023}, | ||
733 | {0x00, 0x0000, 0x0024}, | ||
734 | {0x00, 0x00d5, 0x0025}, | ||
735 | {0x00, 0x0000, 0x0026}, | ||
736 | {0x00, 0x000b, 0x0027}, | ||
737 | {0x00, 0x0000, 0x0046}, | ||
738 | {0x00, 0x0000, 0x0047}, | ||
739 | {0x00, 0x0000, 0x0048}, | ||
740 | {0x00, 0x0000, 0x0049}, | ||
741 | {0x00, 0x0008, 0x004a}, | ||
742 | {0xff, 0x0000, 0x00d0}, | ||
743 | {0xff, 0x00d8, 0x00d1}, | ||
744 | {0xff, 0x0000, 0x00d4}, | ||
745 | {0xff, 0x0000, 0x00d5}, | ||
746 | {0x01, 0x00a6, 0x0000}, | ||
747 | {0x01, 0x0028, 0x0001}, | ||
748 | {0x01, 0x0000, 0x0002}, | ||
749 | {0x01, 0x000a, 0x0003}, | ||
750 | {0x01, 0x0040, 0x0004}, | ||
751 | {0x01, 0x0066, 0x0007}, | ||
752 | {0x01, 0x0011, 0x0008}, | ||
753 | {0x01, 0x0032, 0x0009}, | ||
754 | {0x01, 0x00fd, 0x000a}, | ||
755 | {0x01, 0x0038, 0x000b}, | ||
756 | {0x01, 0x00d1, 0x000c}, | ||
757 | {0x01, 0x00f7, 0x000d}, | ||
758 | {0x01, 0x00ed, 0x000e}, | ||
759 | {0x01, 0x00d8, 0x000f}, | ||
760 | {0x01, 0x0038, 0x0010}, | ||
761 | {0x01, 0x00ff, 0x0015}, | ||
762 | {0x01, 0x0001, 0x0016}, | ||
763 | {0x01, 0x0032, 0x0017}, | ||
764 | {0x01, 0x0023, 0x0018}, | ||
765 | {0x01, 0x00ce, 0x0019}, | ||
766 | {0x01, 0x0023, 0x001a}, | ||
767 | {0x01, 0x0032, 0x001b}, | ||
768 | {0x01, 0x008d, 0x001c}, | ||
769 | {0x01, 0x00ce, 0x001d}, | ||
770 | {0x01, 0x008d, 0x001e}, | ||
771 | {0x01, 0x0000, 0x001f}, | ||
772 | {0x01, 0x0000, 0x0020}, | ||
773 | {0x01, 0x00ff, 0x003e}, | ||
774 | {0x01, 0x0003, 0x003f}, | ||
775 | {0x01, 0x0000, 0x0040}, | ||
776 | {0x01, 0x0035, 0x0041}, | ||
777 | {0x01, 0x0053, 0x0042}, | ||
778 | {0x01, 0x0069, 0x0043}, | ||
779 | {0x01, 0x007c, 0x0044}, | ||
780 | {0x01, 0x008c, 0x0045}, | ||
781 | {0x01, 0x009a, 0x0046}, | ||
782 | {0x01, 0x00a8, 0x0047}, | ||
783 | {0x01, 0x00b4, 0x0048}, | ||
784 | {0x01, 0x00bf, 0x0049}, | ||
785 | {0x01, 0x00ca, 0x004a}, | ||
786 | {0x01, 0x00d4, 0x004b}, | ||
787 | {0x01, 0x00dd, 0x004c}, | ||
788 | {0x01, 0x00e7, 0x004d}, | ||
789 | {0x01, 0x00ef, 0x004e}, | ||
790 | {0x01, 0x00f8, 0x004f}, | ||
791 | {0x01, 0x00ff, 0x0050}, | ||
792 | {0x01, 0x0001, 0x0056}, | ||
793 | {0x01, 0x0060, 0x0057}, | ||
794 | {0x01, 0x0040, 0x0058}, | ||
795 | {0x01, 0x0011, 0x0059}, | ||
796 | {0x01, 0x0001, 0x005a}, | ||
797 | {0x02, 0x0007, 0x0005}, | ||
798 | {0x02, 0xa048, 0x0000}, | ||
799 | {0x02, 0x0007, 0x0005}, | ||
800 | {0x02, 0x0015, 0x0006}, | ||
801 | {0x02, 0x100a, 0x0007}, | ||
802 | {0x02, 0xa048, 0x0000}, | ||
803 | {0x02, 0xc002, 0x0001}, | ||
804 | {0x02, 0x000f, 0x0005}, | ||
805 | {0x02, 0xa048, 0x0000}, | ||
806 | {0x05, 0x0022, 0x0004}, | ||
807 | {0x05, 0x0025, 0x0001}, | ||
808 | {0x05, 0x0000, 0x0000}, | ||
809 | {0x05, 0x0026, 0x0001}, | ||
810 | {0x05, 0x0001, 0x0000}, | ||
811 | {0x05, 0x0027, 0x0001}, | ||
812 | {0x05, 0x0000, 0x0000}, | ||
813 | {0x05, 0x0001, 0x0001}, | ||
814 | {0x05, 0x0000, 0x0000}, | ||
815 | {0x05, 0x0021, 0x0001}, | ||
816 | {0x05, 0x00d2, 0x0000}, | ||
817 | {0x05, 0x0020, 0x0001}, | ||
818 | {0x05, 0x0000, 0x0000}, | ||
819 | {0x00, 0x0090, 0x0005}, | ||
820 | {0x01, 0x00a6, 0x0000}, | ||
821 | {0x02, 0x0007, 0x0005}, | ||
822 | {0x02, 0x2000, 0x0000}, | ||
823 | {0x05, 0x0022, 0x0004}, | ||
824 | {0x05, 0x0015, 0x0001}, | ||
825 | {0x05, 0x00ea, 0x0000}, | ||
826 | {0x05, 0x0021, 0x0001}, | ||
827 | {0x05, 0x00d2, 0x0000}, | ||
828 | {0x05, 0x0023, 0x0001}, | ||
829 | {0x05, 0x0003, 0x0000}, | ||
830 | {0x05, 0x0030, 0x0001}, | ||
831 | {0x05, 0x002b, 0x0000}, | ||
832 | {0x05, 0x0031, 0x0001}, | ||
833 | {0x05, 0x0023, 0x0000}, | ||
834 | {0x05, 0x0032, 0x0001}, | ||
835 | {0x05, 0x0023, 0x0000}, | ||
836 | {0x05, 0x0033, 0x0001}, | ||
837 | {0x05, 0x0023, 0x0000}, | ||
838 | {0x05, 0x0034, 0x0001}, | ||
839 | {0x05, 0x0002, 0x0000}, | ||
840 | {0x05, 0x0050, 0x0001}, | ||
841 | {0x05, 0x0000, 0x0000}, | ||
842 | {0x05, 0x0051, 0x0001}, | ||
843 | {0x05, 0x0000, 0x0000}, | ||
844 | {0x05, 0x0052, 0x0001}, | ||
845 | {0x05, 0x0000, 0x0000}, | ||
846 | {0x05, 0x0054, 0x0001}, | ||
847 | {0x05, 0x0001, 0x0000}, | ||
848 | {0x00, 0x0000, 0x0001}, | ||
849 | {0x00, 0x0000, 0x0002}, | ||
850 | {0x00, 0x000c, 0x0003}, | ||
851 | {0x00, 0x0000, 0x0004}, | ||
852 | {0x00, 0x0090, 0x0005}, | ||
853 | {0x00, 0x0000, 0x0006}, | ||
854 | {0x00, 0x0040, 0x0007}, | ||
855 | {0x00, 0x00c0, 0x0008}, | ||
856 | {0x00, 0x004a, 0x0009}, | ||
857 | {0x00, 0x0000, 0x000a}, | ||
858 | {0x00, 0x0000, 0x000b}, | ||
859 | {0x00, 0x0001, 0x000c}, | ||
860 | {0x00, 0x0001, 0x000d}, | ||
861 | {0x00, 0x0000, 0x000e}, | ||
862 | {0x00, 0x0002, 0x000f}, | ||
863 | {0x00, 0x0001, 0x0010}, | ||
864 | {0x00, 0x0000, 0x0011}, | ||
865 | {0x00, 0x0000, 0x0012}, | ||
866 | {0x00, 0x0002, 0x0020}, | ||
867 | {0x00, 0x0080, 0x0021}, | ||
868 | {0x00, 0x0001, 0x0022}, | ||
869 | {0x00, 0x00e0, 0x0023}, | ||
870 | {0x00, 0x0000, 0x0024}, | ||
871 | {0x00, 0x00d5, 0x0025}, | ||
872 | {0x00, 0x0000, 0x0026}, | ||
873 | {0x00, 0x000b, 0x0027}, | ||
874 | {0x00, 0x0000, 0x0046}, | ||
875 | {0x00, 0x0000, 0x0047}, | ||
876 | {0x00, 0x0000, 0x0048}, | ||
877 | {0x00, 0x0000, 0x0049}, | ||
878 | {0x00, 0x0008, 0x004a}, | ||
879 | {0xff, 0x0000, 0x00d0}, | ||
880 | {0xff, 0x00d8, 0x00d1}, | ||
881 | {0xff, 0x0000, 0x00d4}, | ||
882 | {0xff, 0x0000, 0x00d5}, | ||
883 | {0x01, 0x00a6, 0x0000}, | ||
884 | {0x01, 0x0028, 0x0001}, | ||
885 | {0x01, 0x0000, 0x0002}, | ||
886 | {0x01, 0x000a, 0x0003}, | ||
887 | {0x01, 0x0040, 0x0004}, | ||
888 | {0x01, 0x0066, 0x0007}, | ||
889 | {0x01, 0x0011, 0x0008}, | ||
890 | {0x01, 0x0032, 0x0009}, | ||
891 | {0x01, 0x00fd, 0x000a}, | ||
892 | {0x01, 0x0038, 0x000b}, | ||
893 | {0x01, 0x00d1, 0x000c}, | ||
894 | {0x01, 0x00f7, 0x000d}, | ||
895 | {0x01, 0x00ed, 0x000e}, | ||
896 | {0x01, 0x00d8, 0x000f}, | ||
897 | {0x01, 0x0038, 0x0010}, | ||
898 | {0x01, 0x00ff, 0x0015}, | ||
899 | {0x01, 0x0001, 0x0016}, | ||
900 | {0x01, 0x0032, 0x0017}, | ||
901 | {0x01, 0x0023, 0x0018}, | ||
902 | {0x01, 0x00ce, 0x0019}, | ||
903 | {0x01, 0x0023, 0x001a}, | ||
904 | {0x01, 0x0032, 0x001b}, | ||
905 | {0x01, 0x008d, 0x001c}, | ||
906 | {0x01, 0x00ce, 0x001d}, | ||
907 | {0x01, 0x008d, 0x001e}, | ||
908 | {0x01, 0x0000, 0x001f}, | ||
909 | {0x01, 0x0000, 0x0020}, | ||
910 | {0x01, 0x00ff, 0x003e}, | ||
911 | {0x01, 0x0003, 0x003f}, | ||
912 | {0x01, 0x0000, 0x0040}, | ||
913 | {0x01, 0x0035, 0x0041}, | ||
914 | {0x01, 0x0053, 0x0042}, | ||
915 | {0x01, 0x0069, 0x0043}, | ||
916 | {0x01, 0x007c, 0x0044}, | ||
917 | {0x01, 0x008c, 0x0045}, | ||
918 | {0x01, 0x009a, 0x0046}, | ||
919 | {0x01, 0x00a8, 0x0047}, | ||
920 | {0x01, 0x00b4, 0x0048}, | ||
921 | {0x01, 0x00bf, 0x0049}, | ||
922 | {0x01, 0x00ca, 0x004a}, | ||
923 | {0x01, 0x00d4, 0x004b}, | ||
924 | {0x01, 0x00dd, 0x004c}, | ||
925 | {0x01, 0x00e7, 0x004d}, | ||
926 | {0x01, 0x00ef, 0x004e}, | ||
927 | {0x01, 0x00f8, 0x004f}, | ||
928 | {0x01, 0x00ff, 0x0050}, | ||
929 | {0x01, 0x0001, 0x0056}, | ||
930 | {0x01, 0x0060, 0x0057}, | ||
931 | {0x01, 0x0040, 0x0058}, | ||
932 | {0x01, 0x0011, 0x0059}, | ||
933 | {0x01, 0x0001, 0x005a}, | ||
934 | {0x02, 0x0007, 0x0005}, | ||
935 | {0x02, 0xa048, 0x0000}, | ||
936 | {0x02, 0x0007, 0x0005}, | ||
937 | {0x02, 0x0015, 0x0006}, | ||
938 | {0x02, 0x100a, 0x0007}, | ||
939 | {0x02, 0xa048, 0x0000}, | ||
940 | {0x02, 0xc002, 0x0001}, | ||
941 | {0x02, 0x000f, 0x0005}, | ||
942 | {0x02, 0xa048, 0x0000}, | ||
943 | {0x05, 0x0022, 0x0004}, | ||
944 | {0x05, 0x0025, 0x0001}, | ||
945 | {0x05, 0x0000, 0x0000}, | ||
946 | {0x05, 0x0026, 0x0001}, | ||
947 | {0x05, 0x0001, 0x0000}, | ||
948 | {0x05, 0x0027, 0x0001}, | ||
949 | {0x05, 0x0000, 0x0000}, | ||
950 | {0x05, 0x0001, 0x0001}, | ||
951 | {0x05, 0x0000, 0x0000}, | ||
952 | {0x05, 0x0021, 0x0001}, | ||
953 | {0x05, 0x00d2, 0x0000}, | ||
954 | {0x05, 0x0020, 0x0001}, | ||
955 | {0x05, 0x0000, 0x0000}, | ||
956 | {0x00, 0x0090, 0x0005}, | ||
957 | {0x01, 0x00a6, 0x0000}, | ||
958 | {0x01, 0x0003, 0x003f}, | ||
959 | {0x01, 0x0001, 0x0056}, | ||
960 | {0x01, 0x0011, 0x0008}, | ||
961 | {0x01, 0x0032, 0x0009}, | ||
962 | {0x01, 0xfffd, 0x000a}, | ||
963 | {0x01, 0x0023, 0x000b}, | ||
964 | {0x01, 0xffea, 0x000c}, | ||
965 | {0x01, 0xfff4, 0x000d}, | ||
966 | {0x01, 0xfffc, 0x000e}, | ||
967 | {0x01, 0xffe3, 0x000f}, | ||
968 | {0x01, 0x001f, 0x0010}, | ||
969 | {0x01, 0x00a8, 0x0001}, | ||
970 | {0x01, 0x0067, 0x0007}, | ||
971 | {0x01, 0x0032, 0x0017}, | ||
972 | {0x01, 0x0023, 0x0018}, | ||
973 | {0x01, 0x00ce, 0x0019}, | ||
974 | {0x01, 0x0023, 0x001a}, | ||
975 | {0x01, 0x0032, 0x001b}, | ||
976 | {0x01, 0x008d, 0x001c}, | ||
977 | {0x01, 0x00ce, 0x001d}, | ||
978 | {0x01, 0x008d, 0x001e}, | ||
979 | {0x01, 0x00c8, 0x0015}, | ||
980 | {0x01, 0x0032, 0x0016}, | ||
981 | {0x01, 0x0000, 0x0011}, | ||
982 | {0x01, 0x0000, 0x0012}, | ||
983 | {0x01, 0x0000, 0x0013}, | ||
984 | {0x01, 0x000a, 0x0003}, | ||
985 | {0x02, 0xc002, 0x0001}, | ||
986 | {0x02, 0x0007, 0x0005}, | ||
987 | {0x02, 0xc000, 0x0001}, | ||
988 | {0x02, 0x0000, 0x0005}, | ||
989 | {0x02, 0x0007, 0x0005}, | ||
990 | {0x02, 0x2000, 0x0000}, | ||
991 | {0x05, 0x0022, 0x0004}, | ||
992 | {0x05, 0x0015, 0x0001}, | ||
993 | {0x05, 0x00ea, 0x0000}, | ||
994 | {0x05, 0x0021, 0x0001}, | ||
995 | {0x05, 0x00d2, 0x0000}, | ||
996 | {0x05, 0x0023, 0x0001}, | ||
997 | {0x05, 0x0003, 0x0000}, | ||
998 | {0x05, 0x0030, 0x0001}, | ||
999 | {0x05, 0x002b, 0x0000}, | ||
1000 | {0x05, 0x0031, 0x0001}, | ||
1001 | {0x05, 0x0023, 0x0000}, | ||
1002 | {0x05, 0x0032, 0x0001}, | ||
1003 | {0x05, 0x0023, 0x0000}, | ||
1004 | {0x05, 0x0033, 0x0001}, | ||
1005 | {0x05, 0x0023, 0x0000}, | ||
1006 | {0x05, 0x0034, 0x0001}, | ||
1007 | {0x05, 0x0002, 0x0000}, | ||
1008 | {0x05, 0x0050, 0x0001}, | ||
1009 | {0x05, 0x0000, 0x0000}, | ||
1010 | {0x05, 0x0051, 0x0001}, | ||
1011 | {0x05, 0x0000, 0x0000}, | ||
1012 | {0x05, 0x0052, 0x0001}, | ||
1013 | {0x05, 0x0000, 0x0000}, | ||
1014 | {0x05, 0x0054, 0x0001}, | ||
1015 | {0x05, 0x0001, 0x0000}, | ||
1016 | {0x00, 0x0000, 0x0001}, | ||
1017 | {0x00, 0x0000, 0x0002}, | ||
1018 | {0x00, 0x000c, 0x0003}, | ||
1019 | {0x00, 0x0000, 0x0004}, | ||
1020 | {0x00, 0x0090, 0x0005}, | ||
1021 | {0x00, 0x0000, 0x0006}, | ||
1022 | {0x00, 0x0040, 0x0007}, | ||
1023 | {0x00, 0x00c0, 0x0008}, | ||
1024 | {0x00, 0x004a, 0x0009}, | ||
1025 | {0x00, 0x0000, 0x000a}, | ||
1026 | {0x00, 0x0000, 0x000b}, | ||
1027 | {0x00, 0x0001, 0x000c}, | ||
1028 | {0x00, 0x0001, 0x000d}, | ||
1029 | {0x00, 0x0000, 0x000e}, | ||
1030 | {0x00, 0x0002, 0x000f}, | ||
1031 | {0x00, 0x0001, 0x0010}, | ||
1032 | {0x00, 0x0000, 0x0011}, | ||
1033 | {0x00, 0x0000, 0x0012}, | ||
1034 | {0x00, 0x0002, 0x0020}, | ||
1035 | {0x00, 0x0080, 0x0021}, | ||
1036 | {0x00, 0x0001, 0x0022}, | ||
1037 | {0x00, 0x00e0, 0x0023}, | ||
1038 | {0x00, 0x0000, 0x0024}, | ||
1039 | {0x00, 0x00d5, 0x0025}, | ||
1040 | {0x00, 0x0000, 0x0026}, | ||
1041 | {0x00, 0x000b, 0x0027}, | ||
1042 | {0x00, 0x0000, 0x0046}, | ||
1043 | {0x00, 0x0000, 0x0047}, | ||
1044 | {0x00, 0x0000, 0x0048}, | ||
1045 | {0x00, 0x0000, 0x0049}, | ||
1046 | {0x00, 0x0008, 0x004a}, | ||
1047 | {0xff, 0x0000, 0x00d0}, | ||
1048 | {0xff, 0x00d8, 0x00d1}, | ||
1049 | {0xff, 0x0000, 0x00d4}, | ||
1050 | {0xff, 0x0000, 0x00d5}, | ||
1051 | {0x01, 0x00a6, 0x0000}, | ||
1052 | {0x01, 0x0028, 0x0001}, | ||
1053 | {0x01, 0x0000, 0x0002}, | ||
1054 | {0x01, 0x000a, 0x0003}, | ||
1055 | {0x01, 0x0040, 0x0004}, | ||
1056 | {0x01, 0x0066, 0x0007}, | ||
1057 | {0x01, 0x0011, 0x0008}, | ||
1058 | {0x01, 0x0032, 0x0009}, | ||
1059 | {0x01, 0x00fd, 0x000a}, | ||
1060 | {0x01, 0x0038, 0x000b}, | ||
1061 | {0x01, 0x00d1, 0x000c}, | ||
1062 | {0x01, 0x00f7, 0x000d}, | ||
1063 | {0x01, 0x00ed, 0x000e}, | ||
1064 | {0x01, 0x00d8, 0x000f}, | ||
1065 | {0x01, 0x0038, 0x0010}, | ||
1066 | {0x01, 0x00ff, 0x0015}, | ||
1067 | {0x01, 0x0001, 0x0016}, | ||
1068 | {0x01, 0x0032, 0x0017}, | ||
1069 | {0x01, 0x0023, 0x0018}, | ||
1070 | {0x01, 0x00ce, 0x0019}, | ||
1071 | {0x01, 0x0023, 0x001a}, | ||
1072 | {0x01, 0x0032, 0x001b}, | ||
1073 | {0x01, 0x008d, 0x001c}, | ||
1074 | {0x01, 0x00ce, 0x001d}, | ||
1075 | {0x01, 0x008d, 0x001e}, | ||
1076 | {0x01, 0x0000, 0x001f}, | ||
1077 | {0x01, 0x0000, 0x0020}, | ||
1078 | {0x01, 0x00ff, 0x003e}, | ||
1079 | {0x01, 0x0003, 0x003f}, | ||
1080 | {0x01, 0x0000, 0x0040}, | ||
1081 | {0x01, 0x0035, 0x0041}, | ||
1082 | {0x01, 0x0053, 0x0042}, | ||
1083 | {0x01, 0x0069, 0x0043}, | ||
1084 | {0x01, 0x007c, 0x0044}, | ||
1085 | {0x01, 0x008c, 0x0045}, | ||
1086 | {0x01, 0x009a, 0x0046}, | ||
1087 | {0x01, 0x00a8, 0x0047}, | ||
1088 | {0x01, 0x00b4, 0x0048}, | ||
1089 | {0x01, 0x00bf, 0x0049}, | ||
1090 | {0x01, 0x00ca, 0x004a}, | ||
1091 | {0x01, 0x00d4, 0x004b}, | ||
1092 | {0x01, 0x00dd, 0x004c}, | ||
1093 | {0x01, 0x00e7, 0x004d}, | ||
1094 | {0x01, 0x00ef, 0x004e}, | ||
1095 | {0x01, 0x00f8, 0x004f}, | ||
1096 | {0x01, 0x00ff, 0x0050}, | ||
1097 | {0x01, 0x0001, 0x0056}, | ||
1098 | {0x01, 0x0060, 0x0057}, | ||
1099 | {0x01, 0x0040, 0x0058}, | ||
1100 | {0x01, 0x0011, 0x0059}, | ||
1101 | {0x01, 0x0001, 0x005a}, | ||
1102 | {0x02, 0x0007, 0x0005}, | ||
1103 | {0x02, 0xa048, 0x0000}, | ||
1104 | {0x02, 0x0007, 0x0005}, | ||
1105 | {0x02, 0x0015, 0x0006}, | ||
1106 | {0x02, 0x100a, 0x0007}, | ||
1107 | {0x02, 0xa048, 0x0000}, | ||
1108 | {0x02, 0xc002, 0x0001}, | ||
1109 | {0x02, 0x000f, 0x0005}, | ||
1110 | {0x02, 0xa048, 0x0000}, | ||
1111 | {0x05, 0x0022, 0x0004}, | ||
1112 | {0x05, 0x0025, 0x0001}, | ||
1113 | {0x05, 0x0000, 0x0000}, | ||
1114 | {0x05, 0x0026, 0x0001}, | ||
1115 | {0x05, 0x0001, 0x0000}, | ||
1116 | {0x05, 0x0027, 0x0001}, | ||
1117 | {0x05, 0x0000, 0x0000}, | ||
1118 | {0x05, 0x0001, 0x0001}, | ||
1119 | {0x05, 0x0000, 0x0000}, | ||
1120 | {0x05, 0x0021, 0x0001}, | ||
1121 | {0x05, 0x00d2, 0x0000}, | ||
1122 | {0x05, 0x0020, 0x0001}, | ||
1123 | {0x05, 0x0000, 0x0000}, | ||
1124 | {0x00, 0x0090, 0x0005}, | ||
1125 | {0x01, 0x00a6, 0x0000}, | ||
1126 | {0x02, 0x0007, 0x0005}, | ||
1127 | {0x02, 0x2000, 0x0000}, | ||
1128 | {0x05, 0x0022, 0x0004}, | ||
1129 | {0x05, 0x0015, 0x0001}, | ||
1130 | {0x05, 0x00ea, 0x0000}, | ||
1131 | {0x05, 0x0021, 0x0001}, | ||
1132 | {0x05, 0x00d2, 0x0000}, | ||
1133 | {0x05, 0x0023, 0x0001}, | ||
1134 | {0x05, 0x0003, 0x0000}, | ||
1135 | {0x05, 0x0030, 0x0001}, | ||
1136 | {0x05, 0x002b, 0x0000}, | ||
1137 | {0x05, 0x0031, 0x0001}, | ||
1138 | {0x05, 0x0023, 0x0000}, | ||
1139 | {0x05, 0x0032, 0x0001}, | ||
1140 | {0x05, 0x0023, 0x0000}, | ||
1141 | {0x05, 0x0033, 0x0001}, | ||
1142 | {0x05, 0x0023, 0x0000}, | ||
1143 | {0x05, 0x0034, 0x0001}, | ||
1144 | {0x05, 0x0002, 0x0000}, | ||
1145 | {0x05, 0x0050, 0x0001}, | ||
1146 | {0x05, 0x0000, 0x0000}, | ||
1147 | {0x05, 0x0051, 0x0001}, | ||
1148 | {0x05, 0x0000, 0x0000}, | ||
1149 | {0x05, 0x0052, 0x0001}, | ||
1150 | {0x05, 0x0000, 0x0000}, | ||
1151 | {0x05, 0x0054, 0x0001}, | ||
1152 | {0x05, 0x0001, 0x0000}, | ||
1153 | {0x00, 0x0000, 0x0001}, | ||
1154 | {0x00, 0x0000, 0x0002}, | ||
1155 | {0x00, 0x000c, 0x0003}, | ||
1156 | {0x00, 0x0000, 0x0004}, | ||
1157 | {0x00, 0x0090, 0x0005}, | ||
1158 | {0x00, 0x0000, 0x0006}, | ||
1159 | {0x00, 0x0040, 0x0007}, | ||
1160 | {0x00, 0x00c0, 0x0008}, | ||
1161 | {0x00, 0x004a, 0x0009}, | ||
1162 | {0x00, 0x0000, 0x000a}, | ||
1163 | {0x00, 0x0000, 0x000b}, | ||
1164 | {0x00, 0x0001, 0x000c}, | ||
1165 | {0x00, 0x0001, 0x000d}, | ||
1166 | {0x00, 0x0000, 0x000e}, | ||
1167 | {0x00, 0x0002, 0x000f}, | ||
1168 | {0x00, 0x0001, 0x0010}, | ||
1169 | {0x00, 0x0000, 0x0011}, | ||
1170 | {0x00, 0x0000, 0x0012}, | ||
1171 | {0x00, 0x0002, 0x0020}, | ||
1172 | {0x00, 0x0080, 0x0021}, | ||
1173 | {0x00, 0x0001, 0x0022}, | ||
1174 | {0x00, 0x00e0, 0x0023}, | ||
1175 | {0x00, 0x0000, 0x0024}, | ||
1176 | {0x00, 0x00d5, 0x0025}, | ||
1177 | {0x00, 0x0000, 0x0026}, | ||
1178 | {0x00, 0x000b, 0x0027}, | ||
1179 | {0x00, 0x0000, 0x0046}, | ||
1180 | {0x00, 0x0000, 0x0047}, | ||
1181 | {0x00, 0x0000, 0x0048}, | ||
1182 | {0x00, 0x0000, 0x0049}, | ||
1183 | {0x00, 0x0008, 0x004a}, | ||
1184 | {0xff, 0x0000, 0x00d0}, | ||
1185 | {0xff, 0x00d8, 0x00d1}, | ||
1186 | {0xff, 0x0000, 0x00d4}, | ||
1187 | {0xff, 0x0000, 0x00d5}, | ||
1188 | {0x01, 0x00a6, 0x0000}, | ||
1189 | {0x01, 0x0028, 0x0001}, | ||
1190 | {0x01, 0x0000, 0x0002}, | ||
1191 | {0x01, 0x000a, 0x0003}, | ||
1192 | {0x01, 0x0040, 0x0004}, | ||
1193 | {0x01, 0x0066, 0x0007}, | ||
1194 | {0x01, 0x0011, 0x0008}, | ||
1195 | {0x01, 0x0032, 0x0009}, | ||
1196 | {0x01, 0x00fd, 0x000a}, | ||
1197 | {0x01, 0x0038, 0x000b}, | ||
1198 | {0x01, 0x00d1, 0x000c}, | ||
1199 | {0x01, 0x00f7, 0x000d}, | ||
1200 | {0x01, 0x00ed, 0x000e}, | ||
1201 | {0x01, 0x00d8, 0x000f}, | ||
1202 | {0x01, 0x0038, 0x0010}, | ||
1203 | {0x01, 0x00ff, 0x0015}, | ||
1204 | {0x01, 0x0001, 0x0016}, | ||
1205 | {0x01, 0x0032, 0x0017}, | ||
1206 | {0x01, 0x0023, 0x0018}, | ||
1207 | {0x01, 0x00ce, 0x0019}, | ||
1208 | {0x01, 0x0023, 0x001a}, | ||
1209 | {0x01, 0x0032, 0x001b}, | ||
1210 | {0x01, 0x008d, 0x001c}, | ||
1211 | {0x01, 0x00ce, 0x001d}, | ||
1212 | {0x01, 0x008d, 0x001e}, | ||
1213 | {0x01, 0x0000, 0x001f}, | ||
1214 | {0x01, 0x0000, 0x0020}, | ||
1215 | {0x01, 0x00ff, 0x003e}, | ||
1216 | {0x01, 0x0003, 0x003f}, | ||
1217 | {0x01, 0x0000, 0x0040}, | ||
1218 | {0x01, 0x0035, 0x0041}, | ||
1219 | {0x01, 0x0053, 0x0042}, | ||
1220 | {0x01, 0x0069, 0x0043}, | ||
1221 | {0x01, 0x007c, 0x0044}, | ||
1222 | {0x01, 0x008c, 0x0045}, | ||
1223 | {0x01, 0x009a, 0x0046}, | ||
1224 | {0x01, 0x00a8, 0x0047}, | ||
1225 | {0x01, 0x00b4, 0x0048}, | ||
1226 | {0x01, 0x00bf, 0x0049}, | ||
1227 | {0x01, 0x00ca, 0x004a}, | ||
1228 | {0x01, 0x00d4, 0x004b}, | ||
1229 | {0x01, 0x00dd, 0x004c}, | ||
1230 | {0x01, 0x00e7, 0x004d}, | ||
1231 | {0x01, 0x00ef, 0x004e}, | ||
1232 | {0x01, 0x00f8, 0x004f}, | ||
1233 | {0x01, 0x00ff, 0x0050}, | ||
1234 | {0x01, 0x0001, 0x0056}, | ||
1235 | {0x01, 0x0060, 0x0057}, | ||
1236 | {0x01, 0x0040, 0x0058}, | ||
1237 | {0x01, 0x0011, 0x0059}, | ||
1238 | {0x01, 0x0001, 0x005a}, | ||
1239 | {0x02, 0x0007, 0x0005}, | ||
1240 | {0x02, 0xa048, 0x0000}, | ||
1241 | {0x02, 0x0007, 0x0005}, | ||
1242 | {0x02, 0x0015, 0x0006}, | ||
1243 | {0x02, 0x100a, 0x0007}, | ||
1244 | {0x02, 0xa048, 0x0000}, | ||
1245 | {0x02, 0xc002, 0x0001}, | ||
1246 | {0x02, 0x000f, 0x0005}, | ||
1247 | {0x02, 0xa048, 0x0000}, | ||
1248 | {0x05, 0x0022, 0x0004}, | ||
1249 | {0x05, 0x0025, 0x0001}, | ||
1250 | {0x05, 0x0000, 0x0000}, | ||
1251 | {0x05, 0x0026, 0x0001}, | ||
1252 | {0x05, 0x0001, 0x0000}, | ||
1253 | {0x05, 0x0027, 0x0001}, | ||
1254 | {0x05, 0x0000, 0x0000}, | ||
1255 | {0x05, 0x0001, 0x0001}, | ||
1256 | {0x05, 0x0000, 0x0000}, | ||
1257 | {0x05, 0x0021, 0x0001}, | ||
1258 | {0x05, 0x00d2, 0x0000}, | ||
1259 | {0x05, 0x0020, 0x0001}, | ||
1260 | {0x05, 0x0000, 0x0000}, | ||
1261 | {0x00, 0x0090, 0x0005}, | ||
1262 | {0x01, 0x00a6, 0x0000}, | ||
1263 | {0x05, 0x0026, 0x0001}, | ||
1264 | {0x05, 0x0001, 0x0000}, | ||
1265 | {0x05, 0x0027, 0x0001}, | ||
1266 | {0x05, 0x000f, 0x0000}, | ||
1267 | {0x01, 0x0003, 0x003f}, | ||
1268 | {0x01, 0x0001, 0x0056}, | ||
1269 | {0x01, 0x0011, 0x0008}, | ||
1270 | {0x01, 0x0032, 0x0009}, | ||
1271 | {0x01, 0xfffd, 0x000a}, | ||
1272 | {0x01, 0x0023, 0x000b}, | ||
1273 | {0x01, 0xffea, 0x000c}, | ||
1274 | {0x01, 0xfff4, 0x000d}, | ||
1275 | {0x01, 0xfffc, 0x000e}, | ||
1276 | {0x01, 0xffe3, 0x000f}, | ||
1277 | {0x01, 0x001f, 0x0010}, | ||
1278 | {0x01, 0x00a8, 0x0001}, | ||
1279 | {0x01, 0x0067, 0x0007}, | ||
1280 | {0x01, 0x0042, 0x0051}, | ||
1281 | {0x01, 0x0051, 0x0053}, | ||
1282 | {0x01, 0x000a, 0x0003}, | ||
1283 | {0x02, 0xc002, 0x0001}, | ||
1284 | {0x02, 0x0007, 0x0005}, | ||
1285 | {0x02, 0xc000, 0x0001}, | ||
1286 | {0x02, 0x0000, 0x0005}, | ||
1287 | {0x02, 0x0007, 0x0005}, | ||
1288 | {0x02, 0x2000, 0x0000}, | ||
1289 | {0x05, 0x0022, 0x0004}, | ||
1290 | {0x05, 0x0015, 0x0001}, | ||
1291 | {0x05, 0x00ea, 0x0000}, | ||
1292 | {0x05, 0x0021, 0x0001}, | ||
1293 | {0x05, 0x00d2, 0x0000}, | ||
1294 | {0x05, 0x0023, 0x0001}, | ||
1295 | {0x05, 0x0003, 0x0000}, | ||
1296 | {0x05, 0x0030, 0x0001}, | ||
1297 | {0x05, 0x002b, 0x0000}, | ||
1298 | {0x05, 0x0031, 0x0001}, | ||
1299 | {0x05, 0x0023, 0x0000}, | ||
1300 | {0x05, 0x0032, 0x0001}, | ||
1301 | {0x05, 0x0023, 0x0000}, | ||
1302 | {0x05, 0x0033, 0x0001}, | ||
1303 | {0x05, 0x0023, 0x0000}, | ||
1304 | {0x05, 0x0034, 0x0001}, | ||
1305 | {0x05, 0x0002, 0x0000}, | ||
1306 | {0x05, 0x0050, 0x0001}, | ||
1307 | {0x05, 0x0000, 0x0000}, | ||
1308 | {0x05, 0x0051, 0x0001}, | ||
1309 | {0x05, 0x0000, 0x0000}, | ||
1310 | {0x05, 0x0052, 0x0001}, | ||
1311 | {0x05, 0x0000, 0x0000}, | ||
1312 | {0x05, 0x0054, 0x0001}, | ||
1313 | {0x05, 0x0001, 0x0000}, | ||
1314 | {0x00, 0x0000, 0x0001}, | ||
1315 | {0x00, 0x0000, 0x0002}, | ||
1316 | {0x00, 0x000c, 0x0003}, | ||
1317 | {0x00, 0x0000, 0x0004}, | ||
1318 | {0x00, 0x0090, 0x0005}, | ||
1319 | {0x00, 0x0000, 0x0006}, | ||
1320 | {0x00, 0x0040, 0x0007}, | ||
1321 | {0x00, 0x00c0, 0x0008}, | ||
1322 | {0x00, 0x004a, 0x0009}, | ||
1323 | {0x00, 0x0000, 0x000a}, | ||
1324 | {0x00, 0x0000, 0x000b}, | ||
1325 | {0x00, 0x0001, 0x000c}, | ||
1326 | {0x00, 0x0001, 0x000d}, | ||
1327 | {0x00, 0x0000, 0x000e}, | ||
1328 | {0x00, 0x0002, 0x000f}, | ||
1329 | {0x00, 0x0001, 0x0010}, | ||
1330 | {0x00, 0x0000, 0x0011}, | ||
1331 | {0x00, 0x0000, 0x0012}, | ||
1332 | {0x00, 0x0002, 0x0020}, | ||
1333 | {0x00, 0x0080, 0x0021}, | ||
1334 | {0x00, 0x0001, 0x0022}, | ||
1335 | {0x00, 0x00e0, 0x0023}, | ||
1336 | {0x00, 0x0000, 0x0024}, | ||
1337 | {0x00, 0x00d5, 0x0025}, | ||
1338 | {0x00, 0x0000, 0x0026}, | ||
1339 | {0x00, 0x000b, 0x0027}, | ||
1340 | {0x00, 0x0000, 0x0046}, | ||
1341 | {0x00, 0x0000, 0x0047}, | ||
1342 | {0x00, 0x0000, 0x0048}, | ||
1343 | {0x00, 0x0000, 0x0049}, | ||
1344 | {0x00, 0x0008, 0x004a}, | ||
1345 | {0xff, 0x0000, 0x00d0}, | ||
1346 | {0xff, 0x00d8, 0x00d1}, | ||
1347 | {0xff, 0x0000, 0x00d4}, | ||
1348 | {0xff, 0x0000, 0x00d5}, | ||
1349 | {0x01, 0x00a6, 0x0000}, | ||
1350 | {0x01, 0x0028, 0x0001}, | ||
1351 | {0x01, 0x0000, 0x0002}, | ||
1352 | {0x01, 0x000a, 0x0003}, | ||
1353 | {0x01, 0x0040, 0x0004}, | ||
1354 | {0x01, 0x0066, 0x0007}, | ||
1355 | {0x01, 0x0011, 0x0008}, | ||
1356 | {0x01, 0x0032, 0x0009}, | ||
1357 | {0x01, 0x00fd, 0x000a}, | ||
1358 | {0x01, 0x0038, 0x000b}, | ||
1359 | {0x01, 0x00d1, 0x000c}, | ||
1360 | {0x01, 0x00f7, 0x000d}, | ||
1361 | {0x01, 0x00ed, 0x000e}, | ||
1362 | {0x01, 0x00d8, 0x000f}, | ||
1363 | {0x01, 0x0038, 0x0010}, | ||
1364 | {0x01, 0x00ff, 0x0015}, | ||
1365 | {0x01, 0x0001, 0x0016}, | ||
1366 | {0x01, 0x0032, 0x0017}, | ||
1367 | {0x01, 0x0023, 0x0018}, | ||
1368 | {0x01, 0x00ce, 0x0019}, | ||
1369 | {0x01, 0x0023, 0x001a}, | ||
1370 | {0x01, 0x0032, 0x001b}, | ||
1371 | {0x01, 0x008d, 0x001c}, | ||
1372 | {0x01, 0x00ce, 0x001d}, | ||
1373 | {0x01, 0x008d, 0x001e}, | ||
1374 | {0x01, 0x0000, 0x001f}, | ||
1375 | {0x01, 0x0000, 0x0020}, | ||
1376 | {0x01, 0x00ff, 0x003e}, | ||
1377 | {0x01, 0x0003, 0x003f}, | ||
1378 | {0x01, 0x0000, 0x0040}, | ||
1379 | {0x01, 0x0035, 0x0041}, | ||
1380 | {0x01, 0x0053, 0x0042}, | ||
1381 | {0x01, 0x0069, 0x0043}, | ||
1382 | {0x01, 0x007c, 0x0044}, | ||
1383 | {0x01, 0x008c, 0x0045}, | ||
1384 | {0x01, 0x009a, 0x0046}, | ||
1385 | {0x01, 0x00a8, 0x0047}, | ||
1386 | {0x01, 0x00b4, 0x0048}, | ||
1387 | {0x01, 0x00bf, 0x0049}, | ||
1388 | {0x01, 0x00ca, 0x004a}, | ||
1389 | {0x01, 0x00d4, 0x004b}, | ||
1390 | {0x01, 0x00dd, 0x004c}, | ||
1391 | {0x01, 0x00e7, 0x004d}, | ||
1392 | {0x01, 0x00ef, 0x004e}, | ||
1393 | {0x01, 0x00f8, 0x004f}, | ||
1394 | {0x01, 0x00ff, 0x0050}, | ||
1395 | {0x01, 0x0001, 0x0056}, | ||
1396 | {0x01, 0x0060, 0x0057}, | ||
1397 | {0x01, 0x0040, 0x0058}, | ||
1398 | {0x01, 0x0011, 0x0059}, | ||
1399 | {0x01, 0x0001, 0x005a}, | ||
1400 | {0x02, 0x0007, 0x0005}, | ||
1401 | {0x02, 0xa048, 0x0000}, | ||
1402 | {0x02, 0x0007, 0x0005}, | ||
1403 | {0x02, 0x0015, 0x0006}, | ||
1404 | {0x02, 0x100a, 0x0007}, | ||
1405 | {0x02, 0xa048, 0x0000}, | ||
1406 | {0x02, 0xc002, 0x0001}, | ||
1407 | {0x02, 0x000f, 0x0005}, | ||
1408 | {0x02, 0xa048, 0x0000}, | ||
1409 | {0x05, 0x0022, 0x0004}, | ||
1410 | {0x05, 0x0025, 0x0001}, | ||
1411 | {0x05, 0x0000, 0x0000}, | ||
1412 | {0x05, 0x0026, 0x0001}, | ||
1413 | {0x05, 0x0001, 0x0000}, | ||
1414 | {0x05, 0x0027, 0x0001}, | ||
1415 | {0x05, 0x0000, 0x0000}, | ||
1416 | {0x05, 0x0001, 0x0001}, | ||
1417 | {0x05, 0x0000, 0x0000}, | ||
1418 | {0x05, 0x0021, 0x0001}, | ||
1419 | {0x05, 0x00d2, 0x0000}, | ||
1420 | {0x05, 0x0020, 0x0001}, | ||
1421 | {0x05, 0x0000, 0x0000}, | ||
1422 | {0x00, 0x0090, 0x0005}, | ||
1423 | {0x01, 0x00a6, 0x0000}, | ||
1424 | {0x02, 0x0007, 0x0005}, | ||
1425 | {0x02, 0x2000, 0x0000}, | ||
1426 | {0x05, 0x0022, 0x0004}, | ||
1427 | {0x05, 0x0015, 0x0001}, | ||
1428 | {0x05, 0x00ea, 0x0000}, | ||
1429 | {0x05, 0x0021, 0x0001}, | ||
1430 | {0x05, 0x00d2, 0x0000}, | ||
1431 | {0x05, 0x0023, 0x0001}, | ||
1432 | {0x05, 0x0003, 0x0000}, | ||
1433 | {0x05, 0x0030, 0x0001}, | ||
1434 | {0x05, 0x002b, 0x0000}, | ||
1435 | {0x05, 0x0031, 0x0001}, | ||
1436 | {0x05, 0x0023, 0x0000}, | ||
1437 | {0x05, 0x0032, 0x0001}, | ||
1438 | {0x05, 0x0023, 0x0000}, | ||
1439 | {0x05, 0x0033, 0x0001}, | ||
1440 | {0x05, 0x0023, 0x0000}, | ||
1441 | {0x05, 0x0034, 0x0001}, | ||
1442 | {0x05, 0x0002, 0x0000}, | ||
1443 | {0x05, 0x0050, 0x0001}, | ||
1444 | {0x05, 0x0000, 0x0000}, | ||
1445 | {0x05, 0x0051, 0x0001}, | ||
1446 | {0x05, 0x0000, 0x0000}, | ||
1447 | {0x05, 0x0052, 0x0001}, | ||
1448 | {0x05, 0x0000, 0x0000}, | ||
1449 | {0x05, 0x0054, 0x0001}, | ||
1450 | {0x05, 0x0001, 0x0000}, | ||
1451 | {0x00, 0x0000, 0x0001}, | ||
1452 | {0x00, 0x0000, 0x0002}, | ||
1453 | {0x00, 0x000c, 0x0003}, | ||
1454 | {0x00, 0x0000, 0x0004}, | ||
1455 | {0x00, 0x0090, 0x0005}, | ||
1456 | {0x00, 0x0000, 0x0006}, | ||
1457 | {0x00, 0x0040, 0x0007}, | ||
1458 | {0x00, 0x00c0, 0x0008}, | ||
1459 | {0x00, 0x004a, 0x0009}, | ||
1460 | {0x00, 0x0000, 0x000a}, | ||
1461 | {0x00, 0x0000, 0x000b}, | ||
1462 | {0x00, 0x0001, 0x000c}, | ||
1463 | {0x00, 0x0001, 0x000d}, | ||
1464 | {0x00, 0x0000, 0x000e}, | ||
1465 | {0x00, 0x0002, 0x000f}, | ||
1466 | {0x00, 0x0001, 0x0010}, | ||
1467 | {0x00, 0x0000, 0x0011}, | ||
1468 | {0x00, 0x0000, 0x0012}, | ||
1469 | {0x00, 0x0002, 0x0020}, | ||
1470 | {0x00, 0x0080, 0x0021}, | ||
1471 | {0x00, 0x0001, 0x0022}, | ||
1472 | {0x00, 0x00e0, 0x0023}, | ||
1473 | {0x00, 0x0000, 0x0024}, | ||
1474 | {0x00, 0x00d5, 0x0025}, | ||
1475 | {0x00, 0x0000, 0x0026}, | ||
1476 | {0x00, 0x000b, 0x0027}, | ||
1477 | {0x00, 0x0000, 0x0046}, | ||
1478 | {0x00, 0x0000, 0x0047}, | ||
1479 | {0x00, 0x0000, 0x0048}, | ||
1480 | {0x00, 0x0000, 0x0049}, | ||
1481 | {0x00, 0x0008, 0x004a}, | ||
1482 | {0xff, 0x0000, 0x00d0}, | ||
1483 | {0xff, 0x00d8, 0x00d1}, | ||
1484 | {0xff, 0x0000, 0x00d4}, | ||
1485 | {0xff, 0x0000, 0x00d5}, | ||
1486 | {0x01, 0x00a6, 0x0000}, | ||
1487 | {0x01, 0x0028, 0x0001}, | ||
1488 | {0x01, 0x0000, 0x0002}, | ||
1489 | {0x01, 0x000a, 0x0003}, | ||
1490 | {0x01, 0x0040, 0x0004}, | ||
1491 | {0x01, 0x0066, 0x0007}, | ||
1492 | {0x01, 0x0011, 0x0008}, | ||
1493 | {0x01, 0x0032, 0x0009}, | ||
1494 | {0x01, 0x00fd, 0x000a}, | ||
1495 | {0x01, 0x0038, 0x000b}, | ||
1496 | {0x01, 0x00d1, 0x000c}, | ||
1497 | {0x01, 0x00f7, 0x000d}, | ||
1498 | {0x01, 0x00ed, 0x000e}, | ||
1499 | {0x01, 0x00d8, 0x000f}, | ||
1500 | {0x01, 0x0038, 0x0010}, | ||
1501 | {0x01, 0x00ff, 0x0015}, | ||
1502 | {0x01, 0x0001, 0x0016}, | ||
1503 | {0x01, 0x0032, 0x0017}, | ||
1504 | {0x01, 0x0023, 0x0018}, | ||
1505 | {0x01, 0x00ce, 0x0019}, | ||
1506 | {0x01, 0x0023, 0x001a}, | ||
1507 | {0x01, 0x0032, 0x001b}, | ||
1508 | {0x01, 0x008d, 0x001c}, | ||
1509 | {0x01, 0x00ce, 0x001d}, | ||
1510 | {0x01, 0x008d, 0x001e}, | ||
1511 | {0x01, 0x0000, 0x001f}, | ||
1512 | {0x01, 0x0000, 0x0020}, | ||
1513 | {0x01, 0x00ff, 0x003e}, | ||
1514 | {0x01, 0x0003, 0x003f}, | ||
1515 | {0x01, 0x0000, 0x0040}, | ||
1516 | {0x01, 0x0035, 0x0041}, | ||
1517 | {0x01, 0x0053, 0x0042}, | ||
1518 | {0x01, 0x0069, 0x0043}, | ||
1519 | {0x01, 0x007c, 0x0044}, | ||
1520 | {0x01, 0x008c, 0x0045}, | ||
1521 | {0x01, 0x009a, 0x0046}, | ||
1522 | {0x01, 0x00a8, 0x0047}, | ||
1523 | {0x01, 0x00b4, 0x0048}, | ||
1524 | {0x01, 0x00bf, 0x0049}, | ||
1525 | {0x01, 0x00ca, 0x004a}, | ||
1526 | {0x01, 0x00d4, 0x004b}, | ||
1527 | {0x01, 0x00dd, 0x004c}, | ||
1528 | {0x01, 0x00e7, 0x004d}, | ||
1529 | {0x01, 0x00ef, 0x004e}, | ||
1530 | {0x01, 0x00f8, 0x004f}, | ||
1531 | {0x01, 0x00ff, 0x0050}, | ||
1532 | {0x01, 0x0001, 0x0056}, | ||
1533 | {0x01, 0x0060, 0x0057}, | ||
1534 | {0x01, 0x0040, 0x0058}, | ||
1535 | {0x01, 0x0011, 0x0059}, | ||
1536 | {0x01, 0x0001, 0x005a}, | ||
1537 | {0x02, 0x0007, 0x0005}, | ||
1538 | {0x02, 0xa048, 0x0000}, | ||
1539 | {0x02, 0x0007, 0x0005}, | ||
1540 | {0x02, 0x0015, 0x0006}, | ||
1541 | {0x02, 0x100a, 0x0007}, | ||
1542 | {0x02, 0xa048, 0x0000}, | ||
1543 | {0x02, 0xc002, 0x0001}, | ||
1544 | {0x02, 0x000f, 0x0005}, | ||
1545 | {0x02, 0xa048, 0x0000}, | ||
1546 | {0x05, 0x0022, 0x0004}, | ||
1547 | {0x05, 0x0025, 0x0001}, | ||
1548 | {0x05, 0x0000, 0x0000}, | ||
1549 | {0x05, 0x0026, 0x0001}, | ||
1550 | {0x05, 0x0001, 0x0000}, | ||
1551 | {0x05, 0x0027, 0x0001}, | ||
1552 | {0x05, 0x0000, 0x0000}, | ||
1553 | {0x05, 0x0001, 0x0001}, | ||
1554 | {0x05, 0x0000, 0x0000}, | ||
1555 | {0x05, 0x0021, 0x0001}, | ||
1556 | {0x05, 0x00d2, 0x0000}, | ||
1557 | {0x05, 0x0020, 0x0001}, | ||
1558 | {0x05, 0x0000, 0x0000}, | ||
1559 | {0x00, 0x0090, 0x0005}, | ||
1560 | {0x01, 0x00a6, 0x0000}, | ||
1561 | {0x05, 0x0026, 0x0001}, | ||
1562 | {0x05, 0x0001, 0x0000}, | ||
1563 | {0x05, 0x0027, 0x0001}, | ||
1564 | {0x05, 0x001e, 0x0000}, | ||
1565 | {0x01, 0x0003, 0x003f}, | ||
1566 | {0x01, 0x0001, 0x0056}, | ||
1567 | {0x01, 0x0011, 0x0008}, | ||
1568 | {0x01, 0x0032, 0x0009}, | ||
1569 | {0x01, 0xfffd, 0x000a}, | ||
1570 | {0x01, 0x0023, 0x000b}, | ||
1571 | {0x01, 0xffea, 0x000c}, | ||
1572 | {0x01, 0xfff4, 0x000d}, | ||
1573 | {0x01, 0xfffc, 0x000e}, | ||
1574 | {0x01, 0xffe3, 0x000f}, | ||
1575 | {0x01, 0x001f, 0x0010}, | ||
1576 | {0x01, 0x00a8, 0x0001}, | ||
1577 | {0x01, 0x0067, 0x0007}, | ||
1578 | {0x01, 0x0042, 0x0051}, | ||
1579 | {0x01, 0x0051, 0x0053}, | ||
1580 | {0x01, 0x000a, 0x0003}, | ||
1581 | {0x02, 0xc002, 0x0001}, | ||
1582 | {0x02, 0x0007, 0x0005}, | ||
1583 | {0x01, 0x0042, 0x0051}, | ||
1584 | {0x01, 0x0051, 0x0053}, | ||
1585 | {0x05, 0x0026, 0x0001}, | ||
1586 | {0x05, 0x0001, 0x0000}, | ||
1587 | {0x05, 0x0027, 0x0001}, | ||
1588 | {0x05, 0x002d, 0x0000}, | ||
1589 | {0x01, 0x0003, 0x003f}, | ||
1590 | {0x01, 0x0001, 0x0056}, | ||
1591 | {0x02, 0xc000, 0x0001}, | ||
1592 | {0x02, 0x0000, 0x0005}, | ||
1593 | {} | ||
1594 | }; | ||
1595 | |||
1596 | /* Unknow camera from Ori Usbid 0x0000:0x0000 */ | ||
1597 | /* Based on snoops from Ori Cohen */ | ||
1598 | static __u16 spca501c_mysterious_open_data[][3] = { | ||
1599 | {0x02, 0x000f, 0x0005}, | ||
1600 | {0x02, 0xa048, 0x0000}, | ||
1601 | {0x05, 0x0022, 0x0004}, | ||
1602 | /* DSP Registers */ | ||
1603 | {0x01, 0x0016, 0x0011}, /* RGB offset */ | ||
1604 | {0x01, 0x0000, 0x0012}, | ||
1605 | {0x01, 0x0006, 0x0013}, | ||
1606 | {0x01, 0x0078, 0x0051}, | ||
1607 | {0x01, 0x0040, 0x0052}, | ||
1608 | {0x01, 0x0046, 0x0053}, | ||
1609 | {0x01, 0x0040, 0x0054}, | ||
1610 | {0x00, 0x0025, 0x0000}, | ||
1611 | /* {0x00, 0x0000, 0x0000 }, */ | ||
1612 | /* Part 2 */ | ||
1613 | /* TG Registers */ | ||
1614 | {0x00, 0x0026, 0x0000}, | ||
1615 | {0x00, 0x0001, 0x0000}, | ||
1616 | {0x00, 0x0027, 0x0000}, | ||
1617 | {0x00, 0x008a, 0x0000}, | ||
1618 | {0x02, 0x0007, 0x0005}, | ||
1619 | {0x02, 0x2000, 0x0000}, | ||
1620 | {0x05, 0x0022, 0x0004}, | ||
1621 | {0x05, 0x0015, 0x0001}, | ||
1622 | {0x05, 0x00ea, 0x0000}, | ||
1623 | {0x05, 0x0021, 0x0001}, | ||
1624 | {0x05, 0x00d2, 0x0000}, | ||
1625 | {0x05, 0x0023, 0x0001}, | ||
1626 | {0x05, 0x0003, 0x0000}, | ||
1627 | {0x05, 0x0030, 0x0001}, | ||
1628 | {0x05, 0x002b, 0x0000}, | ||
1629 | {0x05, 0x0031, 0x0001}, | ||
1630 | {0x05, 0x0023, 0x0000}, | ||
1631 | {0x05, 0x0032, 0x0001}, | ||
1632 | {0x05, 0x0023, 0x0000}, | ||
1633 | {0x05, 0x0033, 0x0001}, | ||
1634 | {0x05, 0x0023, 0x0000}, | ||
1635 | {0x05, 0x0034, 0x0001}, | ||
1636 | {0x05, 0x0002, 0x0000}, | ||
1637 | {0x05, 0x0050, 0x0001}, | ||
1638 | {0x05, 0x0000, 0x0000}, | ||
1639 | {0x05, 0x0051, 0x0001}, | ||
1640 | {0x05, 0x0000, 0x0000}, | ||
1641 | {0x05, 0x0052, 0x0001}, | ||
1642 | {0x05, 0x0000, 0x0000}, | ||
1643 | {0x05, 0x0054, 0x0001}, | ||
1644 | {0x05, 0x0001, 0x0000}, | ||
1645 | {} | ||
1646 | }; | ||
1647 | |||
1648 | /* Based on snoops from Ori Cohen */ | ||
1649 | static __u16 spca501c_mysterious_init_data[][3] = { | ||
1650 | /* Part 3 */ | ||
1651 | /* TG registers */ | ||
1652 | /* {0x00, 0x0000, 0x0000}, */ | ||
1653 | {0x00, 0x0000, 0x0001}, | ||
1654 | {0x00, 0x0000, 0x0002}, | ||
1655 | {0x00, 0x0006, 0x0003}, | ||
1656 | {0x00, 0x0000, 0x0004}, | ||
1657 | {0x00, 0x0090, 0x0005}, | ||
1658 | {0x00, 0x0000, 0x0006}, | ||
1659 | {0x00, 0x0040, 0x0007}, | ||
1660 | {0x00, 0x00c0, 0x0008}, | ||
1661 | {0x00, 0x004a, 0x0009}, | ||
1662 | {0x00, 0x0000, 0x000a}, | ||
1663 | {0x00, 0x0000, 0x000b}, | ||
1664 | {0x00, 0x0001, 0x000c}, | ||
1665 | {0x00, 0x0001, 0x000d}, | ||
1666 | {0x00, 0x0000, 0x000e}, | ||
1667 | {0x00, 0x0002, 0x000f}, | ||
1668 | {0x00, 0x0001, 0x0010}, | ||
1669 | {0x00, 0x0000, 0x0011}, | ||
1670 | {0x00, 0x0001, 0x0012}, | ||
1671 | {0x00, 0x0002, 0x0020}, | ||
1672 | {0x00, 0x0080, 0x0021}, /* 640 */ | ||
1673 | {0x00, 0x0001, 0x0022}, | ||
1674 | {0x00, 0x00e0, 0x0023}, /* 480 */ | ||
1675 | {0x00, 0x0000, 0x0024}, /* Offset H hight */ | ||
1676 | {0x00, 0x00d3, 0x0025}, /* low */ | ||
1677 | {0x00, 0x0000, 0x0026}, /* Offset V */ | ||
1678 | {0x00, 0x000d, 0x0027}, /* low */ | ||
1679 | {0x00, 0x0000, 0x0046}, | ||
1680 | {0x00, 0x0000, 0x0047}, | ||
1681 | {0x00, 0x0000, 0x0048}, | ||
1682 | {0x00, 0x0000, 0x0049}, | ||
1683 | {0x00, 0x0008, 0x004a}, | ||
1684 | /* DSP Registers */ | ||
1685 | {0x01, 0x00a6, 0x0000}, | ||
1686 | {0x01, 0x0028, 0x0001}, | ||
1687 | {0x01, 0x0000, 0x0002}, | ||
1688 | {0x01, 0x000a, 0x0003}, /* Level Calc bit7 ->1 Auto */ | ||
1689 | {0x01, 0x0040, 0x0004}, | ||
1690 | {0x01, 0x0066, 0x0007}, | ||
1691 | {0x01, 0x000f, 0x0008}, /* A11 Color correction coeff */ | ||
1692 | {0x01, 0x002d, 0x0009}, /* A12 */ | ||
1693 | {0x01, 0x0005, 0x000a}, /* A13 */ | ||
1694 | {0x01, 0x0023, 0x000b}, /* A21 */ | ||
1695 | {0x01, 0x00e0, 0x000c}, /* A22 */ | ||
1696 | {0x01, 0x00fd, 0x000d}, /* A23 */ | ||
1697 | {0x01, 0x00f4, 0x000e}, /* A31 */ | ||
1698 | {0x01, 0x00e4, 0x000f}, /* A32 */ | ||
1699 | {0x01, 0x0028, 0x0010}, /* A33 */ | ||
1700 | {0x01, 0x00ff, 0x0015}, /* Reserved */ | ||
1701 | {0x01, 0x0001, 0x0016}, /* Reserved */ | ||
1702 | {0x01, 0x0032, 0x0017}, /* Win1 Start begin */ | ||
1703 | {0x01, 0x0023, 0x0018}, | ||
1704 | {0x01, 0x00ce, 0x0019}, | ||
1705 | {0x01, 0x0023, 0x001a}, | ||
1706 | {0x01, 0x0032, 0x001b}, | ||
1707 | {0x01, 0x008d, 0x001c}, | ||
1708 | {0x01, 0x00ce, 0x001d}, | ||
1709 | {0x01, 0x008d, 0x001e}, | ||
1710 | {0x01, 0x0000, 0x001f}, | ||
1711 | {0x01, 0x0000, 0x0020}, /* Win1 Start end */ | ||
1712 | {0x01, 0x00ff, 0x003e}, /* Reserved begin */ | ||
1713 | {0x01, 0x0002, 0x003f}, | ||
1714 | {0x01, 0x0000, 0x0040}, | ||
1715 | {0x01, 0x0035, 0x0041}, | ||
1716 | {0x01, 0x0053, 0x0042}, | ||
1717 | {0x01, 0x0069, 0x0043}, | ||
1718 | {0x01, 0x007c, 0x0044}, | ||
1719 | {0x01, 0x008c, 0x0045}, | ||
1720 | {0x01, 0x009a, 0x0046}, | ||
1721 | {0x01, 0x00a8, 0x0047}, | ||
1722 | {0x01, 0x00b4, 0x0048}, | ||
1723 | {0x01, 0x00bf, 0x0049}, | ||
1724 | {0x01, 0x00ca, 0x004a}, | ||
1725 | {0x01, 0x00d4, 0x004b}, | ||
1726 | {0x01, 0x00dd, 0x004c}, | ||
1727 | {0x01, 0x00e7, 0x004d}, | ||
1728 | {0x01, 0x00ef, 0x004e}, | ||
1729 | {0x01, 0x00f8, 0x004f}, | ||
1730 | {0x01, 0x00ff, 0x0050}, | ||
1731 | {0x01, 0x0003, 0x0056}, /* Reserved end */ | ||
1732 | {0x01, 0x0060, 0x0057}, /* Edge Gain */ | ||
1733 | {0x01, 0x0040, 0x0058}, | ||
1734 | {0x01, 0x0011, 0x0059}, /* Edge Bandwidth */ | ||
1735 | {0x01, 0x0001, 0x005a}, | ||
1736 | {0x02, 0x0007, 0x0005}, | ||
1737 | {0x02, 0xa048, 0x0000}, | ||
1738 | {0x02, 0x0007, 0x0005}, | ||
1739 | {0x02, 0x0015, 0x0006}, | ||
1740 | {0x02, 0x200a, 0x0007}, | ||
1741 | {0x02, 0xa048, 0x0000}, | ||
1742 | {0x02, 0xc000, 0x0001}, | ||
1743 | {0x02, 0x000f, 0x0005}, | ||
1744 | {0x02, 0xa048, 0x0000}, | ||
1745 | {0x05, 0x0022, 0x0004}, | ||
1746 | {0x05, 0x0025, 0x0001}, | ||
1747 | {0x05, 0x0000, 0x0000}, | ||
1748 | /* Part 4 */ | ||
1749 | {0x05, 0x0026, 0x0001}, | ||
1750 | {0x05, 0x0001, 0x0000}, | ||
1751 | {0x05, 0x0027, 0x0001}, | ||
1752 | {0x05, 0x0000, 0x0000}, | ||
1753 | {0x05, 0x0001, 0x0001}, | ||
1754 | {0x05, 0x0000, 0x0000}, | ||
1755 | {0x05, 0x0021, 0x0001}, | ||
1756 | {0x05, 0x00d2, 0x0000}, | ||
1757 | {0x05, 0x0020, 0x0001}, | ||
1758 | {0x05, 0x0000, 0x0000}, | ||
1759 | {0x00, 0x0090, 0x0005}, | ||
1760 | {0x01, 0x00a6, 0x0000}, | ||
1761 | {0x02, 0x0000, 0x0005}, | ||
1762 | {0x05, 0x0026, 0x0001}, | ||
1763 | {0x05, 0x0001, 0x0000}, | ||
1764 | {0x05, 0x0027, 0x0001}, | ||
1765 | {0x05, 0x004e, 0x0000}, | ||
1766 | /* Part 5 */ | ||
1767 | {0x01, 0x0003, 0x003f}, | ||
1768 | {0x01, 0x0001, 0x0056}, | ||
1769 | {0x01, 0x000f, 0x0008}, | ||
1770 | {0x01, 0x002d, 0x0009}, | ||
1771 | {0x01, 0x0005, 0x000a}, | ||
1772 | {0x01, 0x0023, 0x000b}, | ||
1773 | {0x01, 0xffe0, 0x000c}, | ||
1774 | {0x01, 0xfffd, 0x000d}, | ||
1775 | {0x01, 0xfff4, 0x000e}, | ||
1776 | {0x01, 0xffe4, 0x000f}, | ||
1777 | {0x01, 0x0028, 0x0010}, | ||
1778 | {0x01, 0x00a8, 0x0001}, | ||
1779 | {0x01, 0x0066, 0x0007}, | ||
1780 | {0x01, 0x0032, 0x0017}, | ||
1781 | {0x01, 0x0023, 0x0018}, | ||
1782 | {0x01, 0x00ce, 0x0019}, | ||
1783 | {0x01, 0x0023, 0x001a}, | ||
1784 | {0x01, 0x0032, 0x001b}, | ||
1785 | {0x01, 0x008d, 0x001c}, | ||
1786 | {0x01, 0x00ce, 0x001d}, | ||
1787 | {0x01, 0x008d, 0x001e}, | ||
1788 | {0x01, 0x00c8, 0x0015}, /* c8 Poids fort Luma */ | ||
1789 | {0x01, 0x0032, 0x0016}, /* 32 */ | ||
1790 | {0x01, 0x0016, 0x0011}, /* R 00 */ | ||
1791 | {0x01, 0x0016, 0x0012}, /* G 00 */ | ||
1792 | {0x01, 0x0016, 0x0013}, /* B 00 */ | ||
1793 | {0x01, 0x000a, 0x0003}, | ||
1794 | {0x02, 0xc002, 0x0001}, | ||
1795 | {0x02, 0x0007, 0x0005}, | ||
1796 | {} | ||
1797 | }; | ||
1798 | |||
1799 | static int reg_write(struct usb_device *dev, | ||
1800 | __u16 req, __u16 index, __u16 value) | ||
1801 | { | ||
1802 | int ret; | ||
1803 | |||
1804 | ret = usb_control_msg(dev, | ||
1805 | usb_sndctrlpipe(dev, 0), | ||
1806 | req, | ||
1807 | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
1808 | value, index, NULL, 0, 500); | ||
1809 | PDEBUG(D_USBO, "reg write: 0x%02x 0x%02x 0x%02x", | ||
1810 | req, index, value); | ||
1811 | if (ret < 0) | ||
1812 | PDEBUG(D_ERR, "reg write: error %d", ret); | ||
1813 | return ret; | ||
1814 | } | ||
1815 | |||
1816 | /* returns: negative is error, pos or zero is data */ | ||
1817 | static int reg_read(struct usb_device *dev, | ||
1818 | __u16 req, /* bRequest */ | ||
1819 | __u16 index, /* wIndex */ | ||
1820 | __u16 length) /* wLength (1 or 2 only) */ | ||
1821 | { | ||
1822 | int ret; | ||
1823 | __u8 buf[2]; | ||
1824 | |||
1825 | buf[1] = 0; | ||
1826 | ret = usb_control_msg(dev, | ||
1827 | usb_rcvctrlpipe(dev, 0), | ||
1828 | req, | ||
1829 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
1830 | 0, /* value */ | ||
1831 | index, | ||
1832 | buf, length, | ||
1833 | 500); /* timeout */ | ||
1834 | if (ret < 0) { | ||
1835 | PDEBUG(D_ERR, "reg_read err %d", ret); | ||
1836 | return -1; | ||
1837 | } | ||
1838 | return (buf[1] << 8) + buf[0]; | ||
1839 | } | ||
1840 | |||
1841 | static int write_vector(struct gspca_dev *gspca_dev, | ||
1842 | __u16 data[][3]) | ||
1843 | { | ||
1844 | struct usb_device *dev = gspca_dev->dev; | ||
1845 | int ret, i = 0; | ||
1846 | |||
1847 | while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) { | ||
1848 | ret = reg_write(dev, data[i][0], data[i][2], data[i][1]); | ||
1849 | if (ret < 0) { | ||
1850 | PDEBUG(D_ERR, | ||
1851 | "Reg write failed for 0x%02x,0x%02x,0x%02x", | ||
1852 | data[i][0], data[i][1], data[i][2]); | ||
1853 | return ret; | ||
1854 | } | ||
1855 | i++; | ||
1856 | } | ||
1857 | return 0; | ||
1858 | } | ||
1859 | |||
1860 | static void setbrightness(struct gspca_dev *gspca_dev) | ||
1861 | { | ||
1862 | struct sd *sd = (struct sd *) gspca_dev; | ||
1863 | |||
1864 | reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x11, sd->brightness); | ||
1865 | reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x12, sd->brightness); | ||
1866 | reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x13, sd->brightness); | ||
1867 | } | ||
1868 | |||
1869 | static void getbrightness(struct gspca_dev *gspca_dev) | ||
1870 | { | ||
1871 | struct sd *sd = (struct sd *) gspca_dev; | ||
1872 | __u16 brightness; | ||
1873 | |||
1874 | brightness = reg_read(gspca_dev->dev, SPCA501_REG_CCDSP, 0x11, 2); | ||
1875 | sd->brightness = brightness << 1; | ||
1876 | } | ||
1877 | |||
1878 | static void setcontrast(struct gspca_dev *gspca_dev) | ||
1879 | { | ||
1880 | struct sd *sd = (struct sd *) gspca_dev; | ||
1881 | |||
1882 | reg_write(gspca_dev->dev, 0x00, 0x00, | ||
1883 | (sd->contrast >> 8) & 0xff); | ||
1884 | reg_write(gspca_dev->dev, 0x00, 0x01, | ||
1885 | sd->contrast & 0xff); | ||
1886 | } | ||
1887 | |||
1888 | static void getcontrast(struct gspca_dev *gspca_dev) | ||
1889 | { | ||
1890 | /* spca50x->contrast = 0xaa01; */ | ||
1891 | } | ||
1892 | |||
1893 | static void setcolors(struct gspca_dev *gspca_dev) | ||
1894 | { | ||
1895 | struct sd *sd = (struct sd *) gspca_dev; | ||
1896 | |||
1897 | reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x0c, sd->colors); | ||
1898 | } | ||
1899 | |||
1900 | static void getcolors(struct gspca_dev *gspca_dev) | ||
1901 | { | ||
1902 | struct sd *sd = (struct sd *) gspca_dev; | ||
1903 | |||
1904 | sd->colors = reg_read(gspca_dev->dev, SPCA501_REG_CCDSP, 0x0c, 2); | ||
1905 | /* sd->hue = (reg_read(gspca_dev->dev, SPCA501_REG_CCDSP, 0x13, */ | ||
1906 | /* 2) & 0xFF) << 8; */ | ||
1907 | } | ||
1908 | |||
1909 | /* this function is called at probe time */ | ||
1910 | static int sd_config(struct gspca_dev *gspca_dev, | ||
1911 | const struct usb_device_id *id) | ||
1912 | { | ||
1913 | struct sd *sd = (struct sd *) gspca_dev; | ||
1914 | struct cam *cam; | ||
1915 | __u16 vendor; | ||
1916 | __u16 product; | ||
1917 | |||
1918 | vendor = id->idVendor; | ||
1919 | product = id->idProduct; | ||
1920 | switch (vendor) { | ||
1921 | case 0x0000: /* Unknow Camera */ | ||
1922 | /* switch (product) { */ | ||
1923 | /* case 0x0000: */ | ||
1924 | sd->subtype = MystFromOriUnknownCamera; | ||
1925 | /* break; */ | ||
1926 | /* } */ | ||
1927 | break; | ||
1928 | case 0x040a: /* Kodak cameras */ | ||
1929 | /* switch (product) { */ | ||
1930 | /* case 0x0002: */ | ||
1931 | sd->subtype = KodakDVC325; | ||
1932 | /* break; */ | ||
1933 | /* } */ | ||
1934 | break; | ||
1935 | case 0x0497: /* Smile International */ | ||
1936 | /* switch (product) { */ | ||
1937 | /* case 0xc001: */ | ||
1938 | sd->subtype = SmileIntlCamera; | ||
1939 | /* break; */ | ||
1940 | /* } */ | ||
1941 | break; | ||
1942 | case 0x0506: /* 3COM cameras */ | ||
1943 | /* switch (product) { */ | ||
1944 | /* case 0x00df: */ | ||
1945 | sd->subtype = ThreeComHomeConnectLite; | ||
1946 | /* break; */ | ||
1947 | /* } */ | ||
1948 | break; | ||
1949 | case 0x0733: /* Rebadged ViewQuest (Intel) and ViewQuest cameras */ | ||
1950 | switch (product) { | ||
1951 | case 0x0401: | ||
1952 | sd->subtype = IntelCreateAndShare; | ||
1953 | break; | ||
1954 | case 0x0402: | ||
1955 | sd->subtype = ViewQuestM318B; | ||
1956 | break; | ||
1957 | } | ||
1958 | break; | ||
1959 | case 0x1776: /* Arowana */ | ||
1960 | /* switch (product) { */ | ||
1961 | /* case 0x501c: */ | ||
1962 | sd->subtype = Arowana300KCMOSCamera; | ||
1963 | /* break; */ | ||
1964 | /* } */ | ||
1965 | break; | ||
1966 | } | ||
1967 | cam = &gspca_dev->cam; | ||
1968 | cam->dev_name = (char *) id->driver_info; | ||
1969 | cam->epaddr = 0x01; | ||
1970 | cam->cam_mode = vga_mode; | ||
1971 | cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; | ||
1972 | sd->brightness = sd_ctrls[MY_BRIGHTNESS].qctrl.default_value; | ||
1973 | sd->contrast = sd_ctrls[MY_CONTRAST].qctrl.default_value; | ||
1974 | sd->colors = sd_ctrls[MY_COLOR].qctrl.default_value; | ||
1975 | |||
1976 | switch (sd->subtype) { | ||
1977 | case Arowana300KCMOSCamera: | ||
1978 | case SmileIntlCamera: | ||
1979 | /* Arowana 300k CMOS Camera data */ | ||
1980 | if (write_vector(gspca_dev, spca501c_arowana_init_data)) | ||
1981 | goto error; | ||
1982 | break; | ||
1983 | case MystFromOriUnknownCamera: | ||
1984 | /* UnKnow Ori CMOS Camera data */ | ||
1985 | if (write_vector(gspca_dev, spca501c_mysterious_open_data)) | ||
1986 | goto error; | ||
1987 | break; | ||
1988 | default: | ||
1989 | /* generic spca501 init data */ | ||
1990 | if (write_vector(gspca_dev, spca501_init_data)) | ||
1991 | goto error; | ||
1992 | break; | ||
1993 | } | ||
1994 | return 0; | ||
1995 | error: | ||
1996 | return -EINVAL; | ||
1997 | } | ||
1998 | |||
1999 | /* this function is called at open time */ | ||
2000 | static int sd_open(struct gspca_dev *gspca_dev) | ||
2001 | { | ||
2002 | struct sd *sd = (struct sd *) gspca_dev; | ||
2003 | |||
2004 | PDEBUG(D_STREAM, "SPCA501 init"); | ||
2005 | switch (sd->subtype) { | ||
2006 | case ThreeComHomeConnectLite: | ||
2007 | /* Special handling for 3com data */ | ||
2008 | write_vector(gspca_dev, spca501_3com_open_data); | ||
2009 | break; | ||
2010 | case Arowana300KCMOSCamera: | ||
2011 | case SmileIntlCamera: | ||
2012 | /* Arowana 300k CMOS Camera data */ | ||
2013 | write_vector(gspca_dev, spca501c_arowana_open_data); | ||
2014 | break; | ||
2015 | case MystFromOriUnknownCamera: | ||
2016 | /* UnKnow CMOS Camera data */ | ||
2017 | write_vector(gspca_dev, spca501c_mysterious_init_data); | ||
2018 | break; | ||
2019 | default: | ||
2020 | /* Generic 501 open data */ | ||
2021 | write_vector(gspca_dev, spca501_open_data); | ||
2022 | } | ||
2023 | PDEBUG(D_STREAM, "Initializing SPCA501 finished"); | ||
2024 | return 0; | ||
2025 | } | ||
2026 | |||
2027 | static void sd_start(struct gspca_dev *gspca_dev) | ||
2028 | { | ||
2029 | struct usb_device *dev = gspca_dev->dev; | ||
2030 | int mode; | ||
2031 | |||
2032 | /* memorize the wanted pixel format */ | ||
2033 | mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode; | ||
2034 | |||
2035 | /* Enable ISO packet machine CTRL reg=2, | ||
2036 | * index=1 bitmask=0x2 (bit ordinal 1) */ | ||
2037 | reg_write(dev, SPCA50X_REG_USB, 0x6, 0x94); | ||
2038 | switch (mode) { | ||
2039 | case 0: /* 640x480 */ | ||
2040 | reg_write(dev, SPCA50X_REG_USB, 0x07, 0x004a); | ||
2041 | break; | ||
2042 | case 1: /* 320x240 */ | ||
2043 | reg_write(dev, SPCA50X_REG_USB, 0x07, 0x104a); | ||
2044 | break; | ||
2045 | default: | ||
2046 | /* case 2: * 160x120 */ | ||
2047 | reg_write(dev, SPCA50X_REG_USB, 0x07, 0x204a); | ||
2048 | break; | ||
2049 | } | ||
2050 | reg_write(dev, SPCA501_REG_CTLRL, 0x01, 0x02); | ||
2051 | |||
2052 | /* HDG atleast the Intel CreateAndShare needs to have one of its | ||
2053 | * brightness / contrast / color set otherwise it assumes wath seems | ||
2054 | * max contrast. Note that strange enough setting any of these is | ||
2055 | * enough to fix the max contrast problem, to be sure we set all 3 */ | ||
2056 | setbrightness(gspca_dev); | ||
2057 | setcontrast(gspca_dev); | ||
2058 | setcolors(gspca_dev); | ||
2059 | } | ||
2060 | |||
2061 | static void sd_stopN(struct gspca_dev *gspca_dev) | ||
2062 | { | ||
2063 | /* Disable ISO packet | ||
2064 | * machine CTRL reg=2, index=1 bitmask=0x0 (bit ordinal 1) */ | ||
2065 | reg_write(gspca_dev->dev, SPCA501_REG_CTLRL, 0x01, 0x00); | ||
2066 | } | ||
2067 | |||
2068 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
2069 | { | ||
2070 | } | ||
2071 | |||
2072 | /* this function is called at close time */ | ||
2073 | static void sd_close(struct gspca_dev *gspca_dev) | ||
2074 | { | ||
2075 | reg_write(gspca_dev->dev, SPCA501_REG_CTLRL, 0x05, 0x00); | ||
2076 | } | ||
2077 | |||
2078 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | ||
2079 | struct gspca_frame *frame, /* target */ | ||
2080 | __u8 *data, /* isoc packet */ | ||
2081 | int len) /* iso packet length */ | ||
2082 | { | ||
2083 | switch (data[0]) { | ||
2084 | case 0: /* start of frame */ | ||
2085 | frame = gspca_frame_add(gspca_dev, | ||
2086 | LAST_PACKET, | ||
2087 | frame, | ||
2088 | data, 0); | ||
2089 | data += SPCA501_OFFSET_DATA; | ||
2090 | len -= SPCA501_OFFSET_DATA; | ||
2091 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, | ||
2092 | data, len); | ||
2093 | return; | ||
2094 | case 0xff: /* drop */ | ||
2095 | /* gspca_dev->last_packet_type = DISCARD_PACKET; */ | ||
2096 | return; | ||
2097 | } | ||
2098 | data++; | ||
2099 | len--; | ||
2100 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, | ||
2101 | data, len); | ||
2102 | } | ||
2103 | |||
2104 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | ||
2105 | { | ||
2106 | struct sd *sd = (struct sd *) gspca_dev; | ||
2107 | |||
2108 | sd->brightness = val; | ||
2109 | if (gspca_dev->streaming) | ||
2110 | setbrightness(gspca_dev); | ||
2111 | return 0; | ||
2112 | } | ||
2113 | |||
2114 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
2115 | { | ||
2116 | struct sd *sd = (struct sd *) gspca_dev; | ||
2117 | |||
2118 | getbrightness(gspca_dev); | ||
2119 | *val = sd->brightness; | ||
2120 | return 0; | ||
2121 | } | ||
2122 | |||
2123 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | ||
2124 | { | ||
2125 | struct sd *sd = (struct sd *) gspca_dev; | ||
2126 | |||
2127 | sd->contrast = val; | ||
2128 | if (gspca_dev->streaming) | ||
2129 | setcontrast(gspca_dev); | ||
2130 | return 0; | ||
2131 | } | ||
2132 | |||
2133 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) | ||
2134 | { | ||
2135 | struct sd *sd = (struct sd *) gspca_dev; | ||
2136 | |||
2137 | getcontrast(gspca_dev); | ||
2138 | *val = sd->contrast; | ||
2139 | return 0; | ||
2140 | } | ||
2141 | |||
2142 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) | ||
2143 | { | ||
2144 | struct sd *sd = (struct sd *) gspca_dev; | ||
2145 | |||
2146 | sd->colors = val; | ||
2147 | if (gspca_dev->streaming) | ||
2148 | setcolors(gspca_dev); | ||
2149 | return 0; | ||
2150 | } | ||
2151 | |||
2152 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) | ||
2153 | { | ||
2154 | struct sd *sd = (struct sd *) gspca_dev; | ||
2155 | |||
2156 | getcolors(gspca_dev); | ||
2157 | *val = sd->colors; | ||
2158 | return 0; | ||
2159 | } | ||
2160 | |||
2161 | /* sub-driver description */ | ||
2162 | static struct sd_desc sd_desc = { | ||
2163 | .name = MODULE_NAME, | ||
2164 | .ctrls = sd_ctrls, | ||
2165 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
2166 | .config = sd_config, | ||
2167 | .open = sd_open, | ||
2168 | .start = sd_start, | ||
2169 | .stopN = sd_stopN, | ||
2170 | .stop0 = sd_stop0, | ||
2171 | .close = sd_close, | ||
2172 | .pkt_scan = sd_pkt_scan, | ||
2173 | }; | ||
2174 | |||
2175 | /* -- module initialisation -- */ | ||
2176 | #define DVNM(name) .driver_info = (kernel_ulong_t) name | ||
2177 | static __devinitdata struct usb_device_id device_table[] = { | ||
2178 | {USB_DEVICE(0x040a, 0x0002), DVNM("Kodak DVC-325")}, | ||
2179 | {USB_DEVICE(0x0497, 0xc001), DVNM("Smile International")}, | ||
2180 | {USB_DEVICE(0x0506, 0x00df), DVNM("3Com HomeConnect Lite")}, | ||
2181 | {USB_DEVICE(0x0733, 0x0401), DVNM("Intel Create and Share")}, | ||
2182 | {USB_DEVICE(0x0733, 0x0402), DVNM("ViewQuest M318B")}, | ||
2183 | {USB_DEVICE(0x1776, 0x501c), DVNM("Arowana 300K CMOS Camera")}, | ||
2184 | {USB_DEVICE(0x0000, 0x0000), DVNM("MystFromOri Unknow Camera")}, | ||
2185 | {} | ||
2186 | }; | ||
2187 | MODULE_DEVICE_TABLE(usb, device_table); | ||
2188 | |||
2189 | /* -- device connect -- */ | ||
2190 | static int sd_probe(struct usb_interface *intf, | ||
2191 | const struct usb_device_id *id) | ||
2192 | { | ||
2193 | return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), | ||
2194 | THIS_MODULE); | ||
2195 | } | ||
2196 | |||
2197 | static struct usb_driver sd_driver = { | ||
2198 | .name = MODULE_NAME, | ||
2199 | .id_table = device_table, | ||
2200 | .probe = sd_probe, | ||
2201 | .disconnect = gspca_disconnect, | ||
2202 | }; | ||
2203 | |||
2204 | /* -- module insert / remove -- */ | ||
2205 | static int __init sd_mod_init(void) | ||
2206 | { | ||
2207 | if (usb_register(&sd_driver) < 0) | ||
2208 | return -1; | ||
2209 | PDEBUG(D_PROBE, "v%s registered", version); | ||
2210 | return 0; | ||
2211 | } | ||
2212 | static void __exit sd_mod_exit(void) | ||
2213 | { | ||
2214 | usb_deregister(&sd_driver); | ||
2215 | PDEBUG(D_PROBE, "deregistered"); | ||
2216 | } | ||
2217 | |||
2218 | module_init(sd_mod_init); | ||
2219 | module_exit(sd_mod_exit); | ||
diff --git a/drivers/media/video/gspca/spca505.c b/drivers/media/video/gspca/spca505.c new file mode 100644 index 000000000000..5b23518d970d --- /dev/null +++ b/drivers/media/video/gspca/spca505.c | |||
@@ -0,0 +1,933 @@ | |||
1 | /* | ||
2 | * SPCA505 chip based cameras initialization data | ||
3 | * | ||
4 | * V4L2 by Jean-Francis Moine <http://moinejf.free.fr> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #define MODULE_NAME "spca505" | ||
23 | |||
24 | #include "gspca.h" | ||
25 | |||
26 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) | ||
27 | static const char version[] = "2.1.0"; | ||
28 | |||
29 | MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); | ||
30 | MODULE_DESCRIPTION("GSPCA/SPCA505 USB Camera Driver"); | ||
31 | MODULE_LICENSE("GPL"); | ||
32 | |||
33 | /* specific webcam descriptor */ | ||
34 | struct sd { | ||
35 | struct gspca_dev gspca_dev; /* !! must be the first item */ | ||
36 | |||
37 | int buflen; | ||
38 | unsigned char tmpbuf[640 * 480 * 3 / 2]; /* YYUV per line */ | ||
39 | unsigned char tmpbuf2[640 * 480 * 2]; /* YUYV */ | ||
40 | |||
41 | unsigned char brightness; | ||
42 | |||
43 | char subtype; | ||
44 | #define IntelPCCameraPro 0 | ||
45 | #define Nxultra 1 | ||
46 | }; | ||
47 | |||
48 | /* V4L2 controls supported by the driver */ | ||
49 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
50 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
51 | |||
52 | static struct ctrl sd_ctrls[] = { | ||
53 | #define SD_BRIGHTNESS 0 | ||
54 | { | ||
55 | { | ||
56 | .id = V4L2_CID_BRIGHTNESS, | ||
57 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
58 | .name = "Brightness", | ||
59 | .minimum = 0, | ||
60 | .maximum = 255, | ||
61 | .step = 1, | ||
62 | .default_value = 127, | ||
63 | }, | ||
64 | .set = sd_setbrightness, | ||
65 | .get = sd_getbrightness, | ||
66 | }, | ||
67 | }; | ||
68 | |||
69 | static struct cam_mode vga_mode[] = { | ||
70 | {V4L2_PIX_FMT_YUYV, 160, 120, 5}, | ||
71 | {V4L2_PIX_FMT_YUYV, 176, 144, 4}, | ||
72 | {V4L2_PIX_FMT_YUYV, 320, 240, 2}, | ||
73 | {V4L2_PIX_FMT_YUYV, 352, 288, 1}, | ||
74 | {V4L2_PIX_FMT_YUYV, 640, 480, 0}, | ||
75 | }; | ||
76 | |||
77 | #define SPCA50X_OFFSET_DATA 10 | ||
78 | |||
79 | #define SPCA50X_REG_USB 0x02 /* spca505 501 */ | ||
80 | |||
81 | #define SPCA50X_USB_CTRL 0x00 /* spca505 */ | ||
82 | #define SPCA50X_CUSB_ENABLE 0x01 /* spca505 */ | ||
83 | #define SPCA50X_REG_GLOBAL 0x03 /* spca505 */ | ||
84 | #define SPCA50X_GMISC0_IDSEL 0x01 /* Global control device ID select spca505 */ | ||
85 | #define SPCA50X_GLOBAL_MISC0 0x00 /* Global control miscellaneous 0 spca505 */ | ||
86 | |||
87 | #define SPCA50X_GLOBAL_MISC1 0x01 /* 505 */ | ||
88 | #define SPCA50X_GLOBAL_MISC3 0x03 /* 505 */ | ||
89 | #define SPCA50X_GMISC3_SAA7113RST 0x20 /* Not sure about this one spca505 */ | ||
90 | |||
91 | /* | ||
92 | * Data to initialize a SPCA505. Common to the CCD and external modes | ||
93 | */ | ||
94 | static __u16 spca505_init_data[][3] = { | ||
95 | /* line bmRequest,value,index */ | ||
96 | /* 1819 */ | ||
97 | {SPCA50X_REG_GLOBAL, SPCA50X_GMISC3_SAA7113RST, SPCA50X_GLOBAL_MISC3}, | ||
98 | /* Sensor reset */ | ||
99 | /* 1822 */ {SPCA50X_REG_GLOBAL, 0x00, SPCA50X_GLOBAL_MISC3}, | ||
100 | /* 1825 */ {SPCA50X_REG_GLOBAL, 0x00, SPCA50X_GLOBAL_MISC1}, | ||
101 | /* Block USB reset */ | ||
102 | /* 1828 */ {SPCA50X_REG_GLOBAL, SPCA50X_GMISC0_IDSEL, | ||
103 | SPCA50X_GLOBAL_MISC0}, | ||
104 | |||
105 | /* 1831 */ {0x5, 0x01, 0x10}, | ||
106 | /* Maybe power down some stuff */ | ||
107 | /* 1834 */ {0x5, 0x0f, 0x11}, | ||
108 | |||
109 | /* Setup internal CCD ? */ | ||
110 | /* 1837 */ {0x6, 0x10, 0x08}, | ||
111 | /* 1840 */ {0x6, 0x00, 0x09}, | ||
112 | /* 1843 */ {0x6, 0x00, 0x0a}, | ||
113 | /* 1846 */ {0x6, 0x00, 0x0b}, | ||
114 | /* 1849 */ {0x6, 0x10, 0x0c}, | ||
115 | /* 1852 */ {0x6, 0x00, 0x0d}, | ||
116 | /* 1855 */ {0x6, 0x00, 0x0e}, | ||
117 | /* 1858 */ {0x6, 0x00, 0x0f}, | ||
118 | /* 1861 */ {0x6, 0x10, 0x10}, | ||
119 | /* 1864 */ {0x6, 0x02, 0x11}, | ||
120 | /* 1867 */ {0x6, 0x00, 0x12}, | ||
121 | /* 1870 */ {0x6, 0x04, 0x13}, | ||
122 | /* 1873 */ {0x6, 0x02, 0x14}, | ||
123 | /* 1876 */ {0x6, 0x8a, 0x51}, | ||
124 | /* 1879 */ {0x6, 0x40, 0x52}, | ||
125 | /* 1882 */ {0x6, 0xb6, 0x53}, | ||
126 | /* 1885 */ {0x6, 0x3d, 0x54}, | ||
127 | {} | ||
128 | }; | ||
129 | |||
130 | /* | ||
131 | * Data to initialize the camera using the internal CCD | ||
132 | */ | ||
133 | static __u16 spca505_open_data_ccd[][3] = { | ||
134 | /* line bmRequest,value,index */ | ||
135 | /* Internal CCD data set */ | ||
136 | /* 1891 */ {0x3, 0x04, 0x01}, | ||
137 | /* This could be a reset */ | ||
138 | /* 1894 */ {0x3, 0x00, 0x01}, | ||
139 | |||
140 | /* Setup compression and image registers. 0x6 and 0x7 seem to be | ||
141 | related to H&V hold, and are resolution mode specific */ | ||
142 | /* 1897 */ {0x4, 0x10, 0x01}, | ||
143 | /* DIFF(0x50), was (0x10) */ | ||
144 | /* 1900 */ {0x4, 0x00, 0x04}, | ||
145 | /* 1903 */ {0x4, 0x00, 0x05}, | ||
146 | /* 1906 */ {0x4, 0x20, 0x06}, | ||
147 | /* 1909 */ {0x4, 0x20, 0x07}, | ||
148 | |||
149 | /* 1912 */ {0x8, 0x0a, 0x00}, | ||
150 | /* DIFF (0x4a), was (0xa) */ | ||
151 | |||
152 | /* 1915 */ {0x5, 0x00, 0x10}, | ||
153 | /* 1918 */ {0x5, 0x00, 0x11}, | ||
154 | /* 1921 */ {0x5, 0x00, 0x00}, | ||
155 | /* DIFF not written */ | ||
156 | /* 1924 */ {0x5, 0x00, 0x01}, | ||
157 | /* DIFF not written */ | ||
158 | /* 1927 */ {0x5, 0x00, 0x02}, | ||
159 | /* DIFF not written */ | ||
160 | /* 1930 */ {0x5, 0x00, 0x03}, | ||
161 | /* DIFF not written */ | ||
162 | /* 1933 */ {0x5, 0x00, 0x04}, | ||
163 | /* DIFF not written */ | ||
164 | /* 1936 */ {0x5, 0x80, 0x05}, | ||
165 | /* DIFF not written */ | ||
166 | /* 1939 */ {0x5, 0xe0, 0x06}, | ||
167 | /* DIFF not written */ | ||
168 | /* 1942 */ {0x5, 0x20, 0x07}, | ||
169 | /* DIFF not written */ | ||
170 | /* 1945 */ {0x5, 0xa0, 0x08}, | ||
171 | /* DIFF not written */ | ||
172 | /* 1948 */ {0x5, 0x0, 0x12}, | ||
173 | /* DIFF not written */ | ||
174 | /* 1951 */ {0x5, 0x02, 0x0f}, | ||
175 | /* DIFF not written */ | ||
176 | /* 1954 */ {0x5, 0x10, 0x46}, | ||
177 | /* DIFF not written */ | ||
178 | /* 1957 */ {0x5, 0x8, 0x4a}, | ||
179 | /* DIFF not written */ | ||
180 | |||
181 | /* 1960 */ {0x3, 0x08, 0x03}, | ||
182 | /* DIFF (0x3,0x28,0x3) */ | ||
183 | /* 1963 */ {0x3, 0x08, 0x01}, | ||
184 | /* 1966 */ {0x3, 0x0c, 0x03}, | ||
185 | /* DIFF not written */ | ||
186 | /* 1969 */ {0x3, 0x21, 0x00}, | ||
187 | /* DIFF (0x39) */ | ||
188 | |||
189 | /* Extra block copied from init to hopefully ensure CCD is in a sane state */ | ||
190 | /* 1837 */ {0x6, 0x10, 0x08}, | ||
191 | /* 1840 */ {0x6, 0x00, 0x09}, | ||
192 | /* 1843 */ {0x6, 0x00, 0x0a}, | ||
193 | /* 1846 */ {0x6, 0x00, 0x0b}, | ||
194 | /* 1849 */ {0x6, 0x10, 0x0c}, | ||
195 | /* 1852 */ {0x6, 0x00, 0x0d}, | ||
196 | /* 1855 */ {0x6, 0x00, 0x0e}, | ||
197 | /* 1858 */ {0x6, 0x00, 0x0f}, | ||
198 | /* 1861 */ {0x6, 0x10, 0x10}, | ||
199 | /* 1864 */ {0x6, 0x02, 0x11}, | ||
200 | /* 1867 */ {0x6, 0x00, 0x12}, | ||
201 | /* 1870 */ {0x6, 0x04, 0x13}, | ||
202 | /* 1873 */ {0x6, 0x02, 0x14}, | ||
203 | /* 1876 */ {0x6, 0x8a, 0x51}, | ||
204 | /* 1879 */ {0x6, 0x40, 0x52}, | ||
205 | /* 1882 */ {0x6, 0xb6, 0x53}, | ||
206 | /* 1885 */ {0x6, 0x3d, 0x54}, | ||
207 | /* End of extra block */ | ||
208 | |||
209 | /* 1972 */ {0x6, 0x3f, 0x1}, | ||
210 | /* Block skipped */ | ||
211 | /* 1975 */ {0x6, 0x10, 0x02}, | ||
212 | /* 1978 */ {0x6, 0x64, 0x07}, | ||
213 | /* 1981 */ {0x6, 0x10, 0x08}, | ||
214 | /* 1984 */ {0x6, 0x00, 0x09}, | ||
215 | /* 1987 */ {0x6, 0x00, 0x0a}, | ||
216 | /* 1990 */ {0x6, 0x00, 0x0b}, | ||
217 | /* 1993 */ {0x6, 0x10, 0x0c}, | ||
218 | /* 1996 */ {0x6, 0x00, 0x0d}, | ||
219 | /* 1999 */ {0x6, 0x00, 0x0e}, | ||
220 | /* 2002 */ {0x6, 0x00, 0x0f}, | ||
221 | /* 2005 */ {0x6, 0x10, 0x10}, | ||
222 | /* 2008 */ {0x6, 0x02, 0x11}, | ||
223 | /* 2011 */ {0x6, 0x00, 0x12}, | ||
224 | /* 2014 */ {0x6, 0x04, 0x13}, | ||
225 | /* 2017 */ {0x6, 0x02, 0x14}, | ||
226 | /* 2020 */ {0x6, 0x8a, 0x51}, | ||
227 | /* 2023 */ {0x6, 0x40, 0x52}, | ||
228 | /* 2026 */ {0x6, 0xb6, 0x53}, | ||
229 | /* 2029 */ {0x6, 0x3d, 0x54}, | ||
230 | /* 2032 */ {0x6, 0x60, 0x57}, | ||
231 | /* 2035 */ {0x6, 0x20, 0x58}, | ||
232 | /* 2038 */ {0x6, 0x15, 0x59}, | ||
233 | /* 2041 */ {0x6, 0x05, 0x5a}, | ||
234 | |||
235 | /* 2044 */ {0x5, 0x01, 0xc0}, | ||
236 | /* 2047 */ {0x5, 0x10, 0xcb}, | ||
237 | /* 2050 */ {0x5, 0x80, 0xc1}, | ||
238 | /* */ | ||
239 | /* 2053 */ {0x5, 0x0, 0xc2}, | ||
240 | /* 4 was 0 */ | ||
241 | /* 2056 */ {0x5, 0x00, 0xca}, | ||
242 | /* 2059 */ {0x5, 0x80, 0xc1}, | ||
243 | /* */ | ||
244 | /* 2062 */ {0x5, 0x04, 0xc2}, | ||
245 | /* 2065 */ {0x5, 0x00, 0xca}, | ||
246 | /* 2068 */ {0x5, 0x0, 0xc1}, | ||
247 | /* */ | ||
248 | /* 2071 */ {0x5, 0x00, 0xc2}, | ||
249 | /* 2074 */ {0x5, 0x00, 0xca}, | ||
250 | /* 2077 */ {0x5, 0x40, 0xc1}, | ||
251 | /* */ | ||
252 | /* 2080 */ {0x5, 0x17, 0xc2}, | ||
253 | /* 2083 */ {0x5, 0x00, 0xca}, | ||
254 | /* 2086 */ {0x5, 0x80, 0xc1}, | ||
255 | /* */ | ||
256 | /* 2089 */ {0x5, 0x06, 0xc2}, | ||
257 | /* 2092 */ {0x5, 0x00, 0xca}, | ||
258 | /* 2095 */ {0x5, 0x80, 0xc1}, | ||
259 | /* */ | ||
260 | /* 2098 */ {0x5, 0x04, 0xc2}, | ||
261 | /* 2101 */ {0x5, 0x00, 0xca}, | ||
262 | |||
263 | /* 2104 */ {0x3, 0x4c, 0x3}, | ||
264 | /* 2107 */ {0x3, 0x18, 0x1}, | ||
265 | |||
266 | /* 2110 */ {0x6, 0x70, 0x51}, | ||
267 | /* 2113 */ {0x6, 0xbe, 0x53}, | ||
268 | /* 2116 */ {0x6, 0x71, 0x57}, | ||
269 | /* 2119 */ {0x6, 0x20, 0x58}, | ||
270 | /* 2122 */ {0x6, 0x05, 0x59}, | ||
271 | /* 2125 */ {0x6, 0x15, 0x5a}, | ||
272 | |||
273 | /* 2128 */ {0x4, 0x00, 0x08}, | ||
274 | /* Compress = OFF (0x1 to turn on) */ | ||
275 | /* 2131 */ {0x4, 0x12, 0x09}, | ||
276 | /* 2134 */ {0x4, 0x21, 0x0a}, | ||
277 | /* 2137 */ {0x4, 0x10, 0x0b}, | ||
278 | /* 2140 */ {0x4, 0x21, 0x0c}, | ||
279 | /* 2143 */ {0x4, 0x05, 0x00}, | ||
280 | /* was 5 (Image Type ? ) */ | ||
281 | /* 2146 */ {0x4, 0x00, 0x01}, | ||
282 | |||
283 | /* 2149 */ {0x6, 0x3f, 0x01}, | ||
284 | |||
285 | /* 2152 */ {0x4, 0x00, 0x04}, | ||
286 | /* 2155 */ {0x4, 0x00, 0x05}, | ||
287 | /* 2158 */ {0x4, 0x40, 0x06}, | ||
288 | /* 2161 */ {0x4, 0x40, 0x07}, | ||
289 | |||
290 | /* 2164 */ {0x6, 0x1c, 0x17}, | ||
291 | /* 2167 */ {0x6, 0xe2, 0x19}, | ||
292 | /* 2170 */ {0x6, 0x1c, 0x1b}, | ||
293 | /* 2173 */ {0x6, 0xe2, 0x1d}, | ||
294 | /* 2176 */ {0x6, 0xaa, 0x1f}, | ||
295 | /* 2179 */ {0x6, 0x70, 0x20}, | ||
296 | |||
297 | /* 2182 */ {0x5, 0x01, 0x10}, | ||
298 | /* 2185 */ {0x5, 0x00, 0x11}, | ||
299 | /* 2188 */ {0x5, 0x01, 0x00}, | ||
300 | /* 2191 */ {0x5, 0x05, 0x01}, | ||
301 | /* 2194 */ {0x5, 0x00, 0xc1}, | ||
302 | /* */ | ||
303 | /* 2197 */ {0x5, 0x00, 0xc2}, | ||
304 | /* 2200 */ {0x5, 0x00, 0xca}, | ||
305 | |||
306 | /* 2203 */ {0x6, 0x70, 0x51}, | ||
307 | /* 2206 */ {0x6, 0xbe, 0x53}, | ||
308 | {} | ||
309 | }; | ||
310 | |||
311 | /* | ||
312 | Made by Tomasz Zablocki (skalamandra@poczta.onet.pl) | ||
313 | * SPCA505b chip based cameras initialization data | ||
314 | * | ||
315 | */ | ||
316 | /* jfm */ | ||
317 | #define initial_brightness 0x7f /* 0x0(white)-0xff(black) */ | ||
318 | /* #define initial_brightness 0x0 //0x0(white)-0xff(black) */ | ||
319 | /* | ||
320 | * Data to initialize a SPCA505. Common to the CCD and external modes | ||
321 | */ | ||
322 | static __u16 spca505b_init_data[][3] = { | ||
323 | /* start */ | ||
324 | {0x02, 0x00, 0x00}, /* init */ | ||
325 | {0x02, 0x00, 0x01}, | ||
326 | {0x02, 0x00, 0x02}, | ||
327 | {0x02, 0x00, 0x03}, | ||
328 | {0x02, 0x00, 0x04}, | ||
329 | {0x02, 0x00, 0x05}, | ||
330 | {0x02, 0x00, 0x06}, | ||
331 | {0x02, 0x00, 0x07}, | ||
332 | {0x02, 0x00, 0x08}, | ||
333 | {0x02, 0x00, 0x09}, | ||
334 | {0x03, 0x00, 0x00}, | ||
335 | {0x03, 0x00, 0x01}, | ||
336 | {0x03, 0x00, 0x02}, | ||
337 | {0x03, 0x00, 0x03}, | ||
338 | {0x03, 0x00, 0x04}, | ||
339 | {0x03, 0x00, 0x05}, | ||
340 | {0x03, 0x00, 0x06}, | ||
341 | {0x04, 0x00, 0x00}, | ||
342 | {0x04, 0x00, 0x02}, | ||
343 | {0x04, 0x00, 0x04}, | ||
344 | {0x04, 0x00, 0x05}, | ||
345 | {0x04, 0x00, 0x06}, | ||
346 | {0x04, 0x00, 0x07}, | ||
347 | {0x04, 0x00, 0x08}, | ||
348 | {0x04, 0x00, 0x09}, | ||
349 | {0x04, 0x00, 0x0a}, | ||
350 | {0x04, 0x00, 0x0b}, | ||
351 | {0x04, 0x00, 0x0c}, | ||
352 | {0x07, 0x00, 0x00}, | ||
353 | {0x07, 0x00, 0x03}, | ||
354 | {0x08, 0x00, 0x00}, | ||
355 | {0x08, 0x00, 0x01}, | ||
356 | {0x08, 0x00, 0x02}, | ||
357 | {0x00, 0x01, 0x00}, | ||
358 | {0x00, 0x01, 0x01}, | ||
359 | {0x00, 0x01, 0x34}, | ||
360 | {0x00, 0x01, 0x35}, | ||
361 | {0x06, 0x18, 0x08}, | ||
362 | {0x06, 0xfc, 0x09}, | ||
363 | {0x06, 0xfc, 0x0a}, | ||
364 | {0x06, 0xfc, 0x0b}, | ||
365 | {0x06, 0x18, 0x0c}, | ||
366 | {0x06, 0xfc, 0x0d}, | ||
367 | {0x06, 0xfc, 0x0e}, | ||
368 | {0x06, 0xfc, 0x0f}, | ||
369 | {0x06, 0x18, 0x10}, | ||
370 | {0x06, 0xfe, 0x12}, | ||
371 | {0x06, 0x00, 0x11}, | ||
372 | {0x06, 0x00, 0x14}, | ||
373 | {0x06, 0x00, 0x13}, | ||
374 | {0x06, 0x28, 0x51}, | ||
375 | {0x06, 0xff, 0x53}, | ||
376 | {0x02, 0x00, 0x08}, | ||
377 | |||
378 | {0x03, 0x00, 0x03}, | ||
379 | {0x03, 0x10, 0x03}, | ||
380 | {} | ||
381 | }; | ||
382 | |||
383 | /* | ||
384 | * Data to initialize the camera using the internal CCD | ||
385 | */ | ||
386 | static __u16 spca505b_open_data_ccd[][3] = { | ||
387 | |||
388 | /* {0x02,0x00,0x00}, */ | ||
389 | {0x03, 0x04, 0x01}, /* rst */ | ||
390 | {0x03, 0x00, 0x01}, | ||
391 | {0x03, 0x00, 0x00}, | ||
392 | {0x03, 0x21, 0x00}, | ||
393 | {0x03, 0x00, 0x04}, | ||
394 | {0x03, 0x00, 0x03}, | ||
395 | {0x03, 0x18, 0x03}, | ||
396 | {0x03, 0x08, 0x01}, | ||
397 | {0x03, 0x1c, 0x03}, | ||
398 | {0x03, 0x5c, 0x03}, | ||
399 | {0x03, 0x5c, 0x03}, | ||
400 | {0x03, 0x18, 0x01}, | ||
401 | |||
402 | /* same as 505 */ | ||
403 | {0x04, 0x10, 0x01}, | ||
404 | {0x04, 0x00, 0x04}, | ||
405 | {0x04, 0x00, 0x05}, | ||
406 | {0x04, 0x20, 0x06}, | ||
407 | {0x04, 0x20, 0x07}, | ||
408 | |||
409 | {0x08, 0x0a, 0x00}, | ||
410 | |||
411 | {0x05, 0x00, 0x10}, | ||
412 | {0x05, 0x00, 0x11}, | ||
413 | {0x05, 0x00, 0x12}, | ||
414 | {0x05, 0x6f, 0x00}, | ||
415 | {0x05, initial_brightness >> 6, 0x00}, | ||
416 | {0x05, initial_brightness << 2, 0x01}, | ||
417 | {0x05, 0x00, 0x02}, | ||
418 | {0x05, 0x01, 0x03}, | ||
419 | {0x05, 0x00, 0x04}, | ||
420 | {0x05, 0x03, 0x05}, | ||
421 | {0x05, 0xe0, 0x06}, | ||
422 | {0x05, 0x20, 0x07}, | ||
423 | {0x05, 0xa0, 0x08}, | ||
424 | {0x05, 0x00, 0x12}, | ||
425 | {0x05, 0x02, 0x0f}, | ||
426 | {0x05, 128, 0x14}, /* max exposure off (0=on) */ | ||
427 | {0x05, 0x01, 0xb0}, | ||
428 | {0x05, 0x01, 0xbf}, | ||
429 | {0x03, 0x02, 0x06}, | ||
430 | {0x05, 0x10, 0x46}, | ||
431 | {0x05, 0x08, 0x4a}, | ||
432 | |||
433 | {0x06, 0x00, 0x01}, | ||
434 | {0x06, 0x10, 0x02}, | ||
435 | {0x06, 0x64, 0x07}, | ||
436 | {0x06, 0x18, 0x08}, | ||
437 | {0x06, 0xfc, 0x09}, | ||
438 | {0x06, 0xfc, 0x0a}, | ||
439 | {0x06, 0xfc, 0x0b}, | ||
440 | {0x04, 0x00, 0x01}, | ||
441 | {0x06, 0x18, 0x0c}, | ||
442 | {0x06, 0xfc, 0x0d}, | ||
443 | {0x06, 0xfc, 0x0e}, | ||
444 | {0x06, 0xfc, 0x0f}, | ||
445 | {0x06, 0x11, 0x10}, /* contrast */ | ||
446 | {0x06, 0x00, 0x11}, | ||
447 | {0x06, 0xfe, 0x12}, | ||
448 | {0x06, 0x00, 0x13}, | ||
449 | {0x06, 0x00, 0x14}, | ||
450 | {0x06, 0x9d, 0x51}, | ||
451 | {0x06, 0x40, 0x52}, | ||
452 | {0x06, 0x7c, 0x53}, | ||
453 | {0x06, 0x40, 0x54}, | ||
454 | {0x06, 0x02, 0x57}, | ||
455 | {0x06, 0x03, 0x58}, | ||
456 | {0x06, 0x15, 0x59}, | ||
457 | {0x06, 0x05, 0x5a}, | ||
458 | {0x06, 0x03, 0x56}, | ||
459 | {0x06, 0x02, 0x3f}, | ||
460 | {0x06, 0x00, 0x40}, | ||
461 | {0x06, 0x39, 0x41}, | ||
462 | {0x06, 0x69, 0x42}, | ||
463 | {0x06, 0x87, 0x43}, | ||
464 | {0x06, 0x9e, 0x44}, | ||
465 | {0x06, 0xb1, 0x45}, | ||
466 | {0x06, 0xbf, 0x46}, | ||
467 | {0x06, 0xcc, 0x47}, | ||
468 | {0x06, 0xd5, 0x48}, | ||
469 | {0x06, 0xdd, 0x49}, | ||
470 | {0x06, 0xe3, 0x4a}, | ||
471 | {0x06, 0xe8, 0x4b}, | ||
472 | {0x06, 0xed, 0x4c}, | ||
473 | {0x06, 0xf2, 0x4d}, | ||
474 | {0x06, 0xf7, 0x4e}, | ||
475 | {0x06, 0xfc, 0x4f}, | ||
476 | {0x06, 0xff, 0x50}, | ||
477 | |||
478 | {0x05, 0x01, 0xc0}, | ||
479 | {0x05, 0x10, 0xcb}, | ||
480 | {0x05, 0x40, 0xc1}, | ||
481 | {0x05, 0x04, 0xc2}, | ||
482 | {0x05, 0x00, 0xca}, | ||
483 | {0x05, 0x40, 0xc1}, | ||
484 | {0x05, 0x09, 0xc2}, | ||
485 | {0x05, 0x00, 0xca}, | ||
486 | {0x05, 0xc0, 0xc1}, | ||
487 | {0x05, 0x09, 0xc2}, | ||
488 | {0x05, 0x00, 0xca}, | ||
489 | {0x05, 0x40, 0xc1}, | ||
490 | {0x05, 0x59, 0xc2}, | ||
491 | {0x05, 0x00, 0xca}, | ||
492 | {0x04, 0x00, 0x01}, | ||
493 | {0x05, 0x80, 0xc1}, | ||
494 | {0x05, 0xec, 0xc2}, | ||
495 | {0x05, 0x0, 0xca}, | ||
496 | |||
497 | {0x06, 0x02, 0x57}, | ||
498 | {0x06, 0x01, 0x58}, | ||
499 | {0x06, 0x15, 0x59}, | ||
500 | {0x06, 0x0a, 0x5a}, | ||
501 | {0x06, 0x01, 0x57}, | ||
502 | {0x06, 0x8a, 0x03}, | ||
503 | {0x06, 0x0a, 0x6c}, | ||
504 | {0x06, 0x30, 0x01}, | ||
505 | {0x06, 0x20, 0x02}, | ||
506 | {0x06, 0x00, 0x03}, | ||
507 | |||
508 | {0x05, 0x8c, 0x25}, | ||
509 | |||
510 | {0x06, 0x4d, 0x51}, /* maybe saturation (4d) */ | ||
511 | {0x06, 0x84, 0x53}, /* making green (84) */ | ||
512 | {0x06, 0x00, 0x57}, /* sharpness (1) */ | ||
513 | {0x06, 0x18, 0x08}, | ||
514 | {0x06, 0xfc, 0x09}, | ||
515 | {0x06, 0xfc, 0x0a}, | ||
516 | {0x06, 0xfc, 0x0b}, | ||
517 | {0x06, 0x18, 0x0c}, /* maybe hue (18) */ | ||
518 | {0x06, 0xfc, 0x0d}, | ||
519 | {0x06, 0xfc, 0x0e}, | ||
520 | {0x06, 0xfc, 0x0f}, | ||
521 | {0x06, 0x18, 0x10}, /* maybe contrast (18) */ | ||
522 | |||
523 | {0x05, 0x01, 0x02}, | ||
524 | |||
525 | {0x04, 0x00, 0x08}, /* compression */ | ||
526 | {0x04, 0x12, 0x09}, | ||
527 | {0x04, 0x21, 0x0a}, | ||
528 | {0x04, 0x10, 0x0b}, | ||
529 | {0x04, 0x21, 0x0c}, | ||
530 | {0x04, 0x1d, 0x00}, /* imagetype (1d) */ | ||
531 | {0x04, 0x41, 0x01}, /* hardware snapcontrol */ | ||
532 | |||
533 | {0x04, 0x00, 0x04}, | ||
534 | {0x04, 0x00, 0x05}, | ||
535 | {0x04, 0x10, 0x06}, | ||
536 | {0x04, 0x10, 0x07}, | ||
537 | {0x04, 0x40, 0x06}, | ||
538 | {0x04, 0x40, 0x07}, | ||
539 | {0x04, 0x00, 0x04}, | ||
540 | {0x04, 0x00, 0x05}, | ||
541 | |||
542 | {0x06, 0x1c, 0x17}, | ||
543 | {0x06, 0xe2, 0x19}, | ||
544 | {0x06, 0x1c, 0x1b}, | ||
545 | {0x06, 0xe2, 0x1d}, | ||
546 | {0x06, 0x5f, 0x1f}, | ||
547 | {0x06, 0x32, 0x20}, | ||
548 | |||
549 | {0x05, initial_brightness >> 6, 0x00}, | ||
550 | {0x05, initial_brightness << 2, 0x01}, | ||
551 | {0x05, 0x06, 0xc1}, | ||
552 | {0x05, 0x58, 0xc2}, | ||
553 | {0x05, 0x0, 0xca}, | ||
554 | {0x05, 0x0, 0x11}, | ||
555 | {} | ||
556 | }; | ||
557 | |||
558 | static int reg_write(struct usb_device *dev, | ||
559 | __u16 reg, __u16 index, __u16 value) | ||
560 | { | ||
561 | int ret; | ||
562 | |||
563 | ret = usb_control_msg(dev, | ||
564 | usb_sndctrlpipe(dev, 0), | ||
565 | reg, | ||
566 | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
567 | value, index, NULL, 0, 500); | ||
568 | PDEBUG(D_PACK, "reg write: 0x%02x,0x%02x:0x%02x, 0x%x", | ||
569 | reg, index, value, ret); | ||
570 | if (ret < 0) | ||
571 | PDEBUG(D_ERR, "reg write: error %d", ret); | ||
572 | return ret; | ||
573 | } | ||
574 | |||
575 | /* returns: negative is error, pos or zero is data */ | ||
576 | static int reg_read(struct usb_device *dev, | ||
577 | __u16 reg, /* bRequest */ | ||
578 | __u16 index, /* wIndex */ | ||
579 | __u16 length) /* wLength (1 or 2 only) */ | ||
580 | { | ||
581 | int ret; | ||
582 | unsigned char buf[4]; | ||
583 | |||
584 | buf[1] = 0; | ||
585 | ret = usb_control_msg(dev, | ||
586 | usb_rcvctrlpipe(dev, 0), | ||
587 | reg, | ||
588 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
589 | (__u16) 0, /* value */ | ||
590 | (__u16) index, | ||
591 | buf, | ||
592 | length, | ||
593 | 500); /* timeout */ | ||
594 | if (ret < 0) { | ||
595 | PDEBUG(D_ERR, "reg_read err %d", ret); | ||
596 | return -1; | ||
597 | } | ||
598 | return (buf[1] << 8) + buf[0]; | ||
599 | } | ||
600 | |||
601 | static int write_vector(struct gspca_dev *gspca_dev, | ||
602 | __u16 data[][3]) | ||
603 | { | ||
604 | struct usb_device *dev = gspca_dev->dev; | ||
605 | int ret, i = 0; | ||
606 | |||
607 | while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) { | ||
608 | ret = reg_write(dev, data[i][0], data[i][2], data[i][1]); | ||
609 | if (ret < 0) { | ||
610 | PDEBUG(D_ERR, | ||
611 | "Register write failed for 0x%x,0x%x,0x%x", | ||
612 | data[i][0], data[i][1], data[i][2]); | ||
613 | return ret; | ||
614 | } | ||
615 | i++; | ||
616 | } | ||
617 | return 0; | ||
618 | } | ||
619 | |||
620 | /* this function is called at probe time */ | ||
621 | static int sd_config(struct gspca_dev *gspca_dev, | ||
622 | const struct usb_device_id *id) | ||
623 | { | ||
624 | struct sd *sd = (struct sd *) gspca_dev; | ||
625 | struct cam *cam; | ||
626 | __u16 vendor; | ||
627 | __u16 product; | ||
628 | |||
629 | vendor = id->idVendor; | ||
630 | product = id->idProduct; | ||
631 | switch (vendor) { | ||
632 | case 0x041e: /* Creative cameras */ | ||
633 | /* switch (product) { */ | ||
634 | /* case 0x401d: * here505b */ | ||
635 | sd->subtype = Nxultra; | ||
636 | /* break; */ | ||
637 | /* } */ | ||
638 | break; | ||
639 | case 0x0733: /* Rebadged ViewQuest (Intel) and ViewQuest cameras */ | ||
640 | /* switch (product) { */ | ||
641 | /* case 0x0430: */ | ||
642 | /* fixme: may be UsbGrabberPV321 BRIDGE_SPCA506 SENSOR_SAA7113 */ | ||
643 | sd->subtype = IntelPCCameraPro; | ||
644 | /* break; */ | ||
645 | /* } */ | ||
646 | break; | ||
647 | } | ||
648 | |||
649 | cam = &gspca_dev->cam; | ||
650 | cam->dev_name = (char *) id->driver_info; | ||
651 | cam->epaddr = 0x01; | ||
652 | cam->cam_mode = vga_mode; | ||
653 | if (sd->subtype != IntelPCCameraPro) | ||
654 | cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; | ||
655 | else /* no 640x480 for IntelPCCameraPro */ | ||
656 | cam->nmodes = sizeof vga_mode / sizeof vga_mode[0] - 1; | ||
657 | sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; | ||
658 | |||
659 | if (sd->subtype == Nxultra) { | ||
660 | if (write_vector(gspca_dev, spca505b_init_data)) | ||
661 | return -EIO; | ||
662 | } else { | ||
663 | if (write_vector(gspca_dev, spca505_init_data)) | ||
664 | return -EIO; | ||
665 | } | ||
666 | return 0; | ||
667 | } | ||
668 | |||
669 | /* this function is called at open time */ | ||
670 | static int sd_open(struct gspca_dev *gspca_dev) | ||
671 | { | ||
672 | struct sd *sd = (struct sd *) gspca_dev; | ||
673 | int ret; | ||
674 | |||
675 | PDEBUG(D_STREAM, "Initializing SPCA505"); | ||
676 | if (sd->subtype == Nxultra) | ||
677 | write_vector(gspca_dev, spca505b_open_data_ccd); | ||
678 | else | ||
679 | write_vector(gspca_dev, spca505_open_data_ccd); | ||
680 | ret = reg_read(gspca_dev->dev, 6, 0x16, 2); | ||
681 | |||
682 | if (ret < 0) { | ||
683 | PDEBUG(D_ERR|D_STREAM, | ||
684 | "register read failed for after vector read err = %d", | ||
685 | ret); | ||
686 | return -EIO; | ||
687 | } | ||
688 | PDEBUG(D_STREAM, | ||
689 | "After vector read returns : 0x%x should be 0x0101", | ||
690 | ret & 0xffff); | ||
691 | |||
692 | ret = reg_write(gspca_dev->dev, 6, 0x16, 0x0a); | ||
693 | if (ret < 0) { | ||
694 | PDEBUG(D_ERR, "register write failed for (6,0xa,0x16) err=%d", | ||
695 | ret); | ||
696 | return -EIO; | ||
697 | } | ||
698 | reg_write(gspca_dev->dev, 5, 0xc2, 18); | ||
699 | return 0; | ||
700 | } | ||
701 | |||
702 | static void sd_start(struct gspca_dev *gspca_dev) | ||
703 | { | ||
704 | struct usb_device *dev = gspca_dev->dev; | ||
705 | int ret; | ||
706 | |||
707 | /* necessary because without it we can see stream | ||
708 | * only once after loading module */ | ||
709 | /* stopping usb registers Tomasz change */ | ||
710 | reg_write(dev, 0x02, 0x0, 0x0); | ||
711 | switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode) { | ||
712 | case 0: | ||
713 | reg_write(dev, 0x04, 0x00, 0x00); | ||
714 | reg_write(dev, 0x04, 0x06, 0x10); | ||
715 | reg_write(dev, 0x04, 0x07, 0x10); | ||
716 | break; | ||
717 | case 1: | ||
718 | reg_write(dev, 0x04, 0x00, 0x01); | ||
719 | reg_write(dev, 0x04, 0x06, 0x1a); | ||
720 | reg_write(dev, 0x04, 0x07, 0x1a); | ||
721 | break; | ||
722 | case 2: | ||
723 | reg_write(dev, 0x04, 0x00, 0x02); | ||
724 | reg_write(dev, 0x04, 0x06, 0x1c); | ||
725 | reg_write(dev, 0x04, 0x07, 0x1d); | ||
726 | break; | ||
727 | case 4: | ||
728 | reg_write(dev, 0x04, 0x00, 0x04); | ||
729 | reg_write(dev, 0x04, 0x06, 0x34); | ||
730 | reg_write(dev, 0x04, 0x07, 0x34); | ||
731 | break; | ||
732 | default: | ||
733 | /* case 5: */ | ||
734 | reg_write(dev, 0x04, 0x00, 0x05); | ||
735 | reg_write(dev, 0x04, 0x06, 0x40); | ||
736 | reg_write(dev, 0x04, 0x07, 0x40); | ||
737 | break; | ||
738 | } | ||
739 | /* Enable ISO packet machine - should we do this here or in ISOC init ? */ | ||
740 | ret = reg_write(dev, SPCA50X_REG_USB, | ||
741 | SPCA50X_USB_CTRL, | ||
742 | SPCA50X_CUSB_ENABLE); | ||
743 | |||
744 | /* reg_write(dev, 0x5, 0x0, 0x0); */ | ||
745 | /* reg_write(dev, 0x5, 0x0, 0x1); */ | ||
746 | /* reg_write(dev, 0x5, 0x11, 0x2); */ | ||
747 | } | ||
748 | |||
749 | static void sd_stopN(struct gspca_dev *gspca_dev) | ||
750 | { | ||
751 | /* Disable ISO packet machine */ | ||
752 | reg_write(gspca_dev->dev, 0x02, 0x00, 0x00); | ||
753 | } | ||
754 | |||
755 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
756 | { | ||
757 | } | ||
758 | |||
759 | /* this function is called at close time */ | ||
760 | static void sd_close(struct gspca_dev *gspca_dev) | ||
761 | { | ||
762 | /* This maybe reset or power control */ | ||
763 | reg_write(gspca_dev->dev, 0x03, 0x03, 0x20); | ||
764 | reg_write(gspca_dev->dev, 0x03, 0x01, 0x0); | ||
765 | reg_write(gspca_dev->dev, 0x03, 0x00, 0x1); | ||
766 | reg_write(gspca_dev->dev, 0x05, 0x10, 0x1); | ||
767 | reg_write(gspca_dev->dev, 0x05, 0x11, 0xf); | ||
768 | } | ||
769 | |||
770 | /* convert YYUV per line to YUYV (YUV 4:2:2) */ | ||
771 | static void yyuv_decode(unsigned char *out, | ||
772 | unsigned char *in, | ||
773 | int width, | ||
774 | int height) | ||
775 | { | ||
776 | unsigned char *Ui, *Vi, *yi, *yi1; | ||
777 | unsigned char *out1; | ||
778 | int i, j; | ||
779 | |||
780 | yi = in; | ||
781 | for (i = height / 2; --i >= 0; ) { | ||
782 | out1 = out + width * 2; /* next line */ | ||
783 | yi1 = yi + width; | ||
784 | Ui = yi1 + width; | ||
785 | Vi = Ui + width / 2; | ||
786 | for (j = width / 2; --j >= 0; ) { | ||
787 | *out++ = 128 + *yi++; | ||
788 | *out++ = 128 + *Ui; | ||
789 | *out++ = 128 + *yi++; | ||
790 | *out++ = 128 + *Vi; | ||
791 | |||
792 | *out1++ = 128 + *yi1++; | ||
793 | *out1++ = 128 + *Ui++; | ||
794 | *out1++ = 128 + *yi1++; | ||
795 | *out1++ = 128 + *Vi++; | ||
796 | } | ||
797 | yi += width * 2; | ||
798 | out = out1; | ||
799 | } | ||
800 | } | ||
801 | |||
802 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | ||
803 | struct gspca_frame *frame, /* target */ | ||
804 | unsigned char *data, /* isoc packet */ | ||
805 | int len) /* iso packet length */ | ||
806 | { | ||
807 | struct sd *sd = (struct sd *) gspca_dev; | ||
808 | |||
809 | switch (data[0]) { | ||
810 | case 0: /* start of frame */ | ||
811 | if (gspca_dev->last_packet_type == FIRST_PACKET) { | ||
812 | yyuv_decode(sd->tmpbuf2, sd->tmpbuf, | ||
813 | gspca_dev->width, | ||
814 | gspca_dev->height); | ||
815 | frame = gspca_frame_add(gspca_dev, | ||
816 | LAST_PACKET, | ||
817 | frame, | ||
818 | sd->tmpbuf2, | ||
819 | gspca_dev->width | ||
820 | * gspca_dev->height | ||
821 | * 2); | ||
822 | } | ||
823 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, | ||
824 | data, 0); | ||
825 | data += SPCA50X_OFFSET_DATA; | ||
826 | len -= SPCA50X_OFFSET_DATA; | ||
827 | if (len > 0) | ||
828 | memcpy(sd->tmpbuf, data, len); | ||
829 | else | ||
830 | len = 0; | ||
831 | sd->buflen = len; | ||
832 | return; | ||
833 | case 0xff: /* drop */ | ||
834 | /* gspca_dev->last_packet_type = DISCARD_PACKET; */ | ||
835 | return; | ||
836 | } | ||
837 | data += 1; | ||
838 | len -= 1; | ||
839 | memcpy(&sd->tmpbuf[sd->buflen], data, len); | ||
840 | sd->buflen += len; | ||
841 | } | ||
842 | |||
843 | static void setbrightness(struct gspca_dev *gspca_dev) | ||
844 | { | ||
845 | struct sd *sd = (struct sd *) gspca_dev; | ||
846 | |||
847 | __u8 brightness = sd->brightness; | ||
848 | reg_write(gspca_dev->dev, 5, 0x00, (255 - brightness) >> 6); | ||
849 | reg_write(gspca_dev->dev, 5, 0x01, (255 - brightness) << 2); | ||
850 | |||
851 | } | ||
852 | static void getbrightness(struct gspca_dev *gspca_dev) | ||
853 | { | ||
854 | struct sd *sd = (struct sd *) gspca_dev; | ||
855 | |||
856 | sd->brightness = 255 | ||
857 | - ((reg_read(gspca_dev->dev, 5, 0x01, 1) >> 2) | ||
858 | + (reg_read(gspca_dev->dev, 5, 0x0, 1) << 6)); | ||
859 | } | ||
860 | |||
861 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | ||
862 | { | ||
863 | struct sd *sd = (struct sd *) gspca_dev; | ||
864 | |||
865 | sd->brightness = val; | ||
866 | if (gspca_dev->streaming) | ||
867 | setbrightness(gspca_dev); | ||
868 | return 0; | ||
869 | } | ||
870 | |||
871 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
872 | { | ||
873 | struct sd *sd = (struct sd *) gspca_dev; | ||
874 | |||
875 | getbrightness(gspca_dev); | ||
876 | *val = sd->brightness; | ||
877 | return 0; | ||
878 | } | ||
879 | |||
880 | /* sub-driver description */ | ||
881 | static struct sd_desc sd_desc = { | ||
882 | .name = MODULE_NAME, | ||
883 | .ctrls = sd_ctrls, | ||
884 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
885 | .config = sd_config, | ||
886 | .open = sd_open, | ||
887 | .start = sd_start, | ||
888 | .stopN = sd_stopN, | ||
889 | .stop0 = sd_stop0, | ||
890 | .close = sd_close, | ||
891 | .pkt_scan = sd_pkt_scan, | ||
892 | }; | ||
893 | |||
894 | /* -- module initialisation -- */ | ||
895 | #define DVNM(name) .driver_info = (kernel_ulong_t) name | ||
896 | static __devinitdata struct usb_device_id device_table[] = { | ||
897 | {USB_DEVICE(0x041e, 0x401d), DVNM("Creative Webcam NX ULTRA")}, | ||
898 | {USB_DEVICE(0x0733, 0x0430), DVNM("Intel PC Camera Pro")}, | ||
899 | {} | ||
900 | }; | ||
901 | MODULE_DEVICE_TABLE(usb, device_table); | ||
902 | |||
903 | /* -- device connect -- */ | ||
904 | static int sd_probe(struct usb_interface *intf, | ||
905 | const struct usb_device_id *id) | ||
906 | { | ||
907 | return gspca_dev_probe(intf, id, &sd_desc, sizeof (struct sd), | ||
908 | THIS_MODULE); | ||
909 | } | ||
910 | |||
911 | static struct usb_driver sd_driver = { | ||
912 | .name = MODULE_NAME, | ||
913 | .id_table = device_table, | ||
914 | .probe = sd_probe, | ||
915 | .disconnect = gspca_disconnect, | ||
916 | }; | ||
917 | |||
918 | /* -- module insert / remove -- */ | ||
919 | static int __init sd_mod_init(void) | ||
920 | { | ||
921 | if (usb_register(&sd_driver) < 0) | ||
922 | return -1; | ||
923 | PDEBUG(D_PROBE, "v%s registered", version); | ||
924 | return 0; | ||
925 | } | ||
926 | static void __exit sd_mod_exit(void) | ||
927 | { | ||
928 | usb_deregister(&sd_driver); | ||
929 | PDEBUG(D_PROBE, "deregistered"); | ||
930 | } | ||
931 | |||
932 | module_init(sd_mod_init); | ||
933 | module_exit(sd_mod_exit); | ||
diff --git a/drivers/media/video/gspca/spca506.c b/drivers/media/video/gspca/spca506.c new file mode 100644 index 000000000000..614fb3ad7711 --- /dev/null +++ b/drivers/media/video/gspca/spca506.c | |||
@@ -0,0 +1,830 @@ | |||
1 | /* | ||
2 | * SPCA506 chip based cameras function | ||
3 | * M Xhaard 15/04/2004 based on different work Mark Taylor and others | ||
4 | * and my own snoopy file on a pv-321c donate by a german compagny | ||
5 | * "Firma Frank Gmbh" from Saarbruecken | ||
6 | * | ||
7 | * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
22 | */ | ||
23 | |||
24 | #define MODULE_NAME "spca506" | ||
25 | |||
26 | #include "gspca.h" | ||
27 | |||
28 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) | ||
29 | static const char version[] = "2.1.0"; | ||
30 | |||
31 | MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); | ||
32 | MODULE_DESCRIPTION("GSPCA/SPCA506 USB Camera Driver"); | ||
33 | MODULE_LICENSE("GPL"); | ||
34 | |||
35 | /* specific webcam descriptor */ | ||
36 | struct sd { | ||
37 | struct gspca_dev gspca_dev; /* !! must be the first item */ | ||
38 | |||
39 | int buflen; | ||
40 | unsigned char tmpbuf[640 * 480 * 3]; /* YYUV per line */ | ||
41 | unsigned char tmpbuf2[640 * 480 * 2]; /* YUYV */ | ||
42 | |||
43 | unsigned char brightness; | ||
44 | unsigned char contrast; | ||
45 | unsigned char colors; | ||
46 | unsigned char hue; | ||
47 | char norme; | ||
48 | char channel; | ||
49 | }; | ||
50 | |||
51 | /* V4L2 controls supported by the driver */ | ||
52 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
53 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
54 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | ||
55 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | ||
56 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); | ||
57 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); | ||
58 | static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val); | ||
59 | static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val); | ||
60 | |||
61 | static struct ctrl sd_ctrls[] = { | ||
62 | #define SD_BRIGHTNESS 0 | ||
63 | { | ||
64 | { | ||
65 | .id = V4L2_CID_BRIGHTNESS, | ||
66 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
67 | .name = "Brightness", | ||
68 | .minimum = 0, | ||
69 | .maximum = 0xff, | ||
70 | .step = 1, | ||
71 | .default_value = 0x80, | ||
72 | }, | ||
73 | .set = sd_setbrightness, | ||
74 | .get = sd_getbrightness, | ||
75 | }, | ||
76 | #define SD_CONTRAST 1 | ||
77 | { | ||
78 | { | ||
79 | .id = V4L2_CID_CONTRAST, | ||
80 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
81 | .name = "Contrast", | ||
82 | .minimum = 0, | ||
83 | .maximum = 0xff, | ||
84 | .step = 1, | ||
85 | .default_value = 0x47, | ||
86 | }, | ||
87 | .set = sd_setcontrast, | ||
88 | .get = sd_getcontrast, | ||
89 | }, | ||
90 | #define SD_COLOR 2 | ||
91 | { | ||
92 | { | ||
93 | .id = V4L2_CID_SATURATION, | ||
94 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
95 | .name = "Saturation", | ||
96 | .minimum = 0, | ||
97 | .maximum = 0xff, | ||
98 | .step = 1, | ||
99 | .default_value = 0x40, | ||
100 | }, | ||
101 | .set = sd_setcolors, | ||
102 | .get = sd_getcolors, | ||
103 | }, | ||
104 | #define SD_HUE 3 | ||
105 | { | ||
106 | { | ||
107 | .id = V4L2_CID_HUE, | ||
108 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
109 | .name = "Hue", | ||
110 | .minimum = 0, | ||
111 | .maximum = 0xff, | ||
112 | .step = 1, | ||
113 | .default_value = 0, | ||
114 | }, | ||
115 | .set = sd_sethue, | ||
116 | .get = sd_gethue, | ||
117 | }, | ||
118 | }; | ||
119 | |||
120 | static struct cam_mode vga_mode[] = { | ||
121 | {V4L2_PIX_FMT_YUYV, 160, 120, 5}, | ||
122 | {V4L2_PIX_FMT_YUYV, 176, 144, 4}, | ||
123 | {V4L2_PIX_FMT_YUYV, 320, 240, 2}, | ||
124 | {V4L2_PIX_FMT_YUYV, 352, 288, 1}, | ||
125 | {V4L2_PIX_FMT_YUYV, 640, 480, 0}, | ||
126 | }; | ||
127 | |||
128 | #define SPCA50X_OFFSET_DATA 10 | ||
129 | |||
130 | #define SAA7113_bright 0x0a /* defaults 0x80 */ | ||
131 | #define SAA7113_contrast 0x0b /* defaults 0x47 */ | ||
132 | #define SAA7113_saturation 0x0c /* defaults 0x40 */ | ||
133 | #define SAA7113_hue 0x0d /* defaults 0x00 */ | ||
134 | #define SAA7113_I2C_BASE_WRITE 0x4a | ||
135 | |||
136 | static void reg_r(struct usb_device *dev, | ||
137 | __u16 req, | ||
138 | __u16 index, | ||
139 | __u8 *buffer, __u16 length) | ||
140 | { | ||
141 | usb_control_msg(dev, | ||
142 | usb_rcvctrlpipe(dev, 0), | ||
143 | req, | ||
144 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
145 | 0, /* value */ | ||
146 | index, buffer, length, | ||
147 | 500); | ||
148 | } | ||
149 | |||
150 | static void reg_w(struct usb_device *dev, | ||
151 | __u16 req, | ||
152 | __u16 value, | ||
153 | __u16 index) | ||
154 | { | ||
155 | usb_control_msg(dev, | ||
156 | usb_sndctrlpipe(dev, 0), | ||
157 | req, | ||
158 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
159 | value, index, | ||
160 | NULL, 0, 500); | ||
161 | } | ||
162 | |||
163 | static void spca506_Initi2c(struct gspca_dev *gspca_dev) | ||
164 | { | ||
165 | reg_w(gspca_dev->dev, 0x07, SAA7113_I2C_BASE_WRITE, 0x0004); | ||
166 | } | ||
167 | |||
168 | static void spca506_WriteI2c(struct gspca_dev *gspca_dev, __u16 valeur, | ||
169 | __u16 reg) | ||
170 | { | ||
171 | int retry = 60; | ||
172 | unsigned char Data[2]; | ||
173 | |||
174 | reg_w(gspca_dev->dev, 0x07, reg, 0x0001); | ||
175 | reg_w(gspca_dev->dev, 0x07, valeur, 0x0000); | ||
176 | while (retry--) { | ||
177 | reg_r(gspca_dev->dev, 0x07, 0x0003, Data, 2); | ||
178 | if ((Data[0] | Data[1]) == 0x00) | ||
179 | break; | ||
180 | } | ||
181 | } | ||
182 | |||
183 | static int spca506_ReadI2c(struct gspca_dev *gspca_dev, __u16 reg) | ||
184 | { | ||
185 | int retry = 60; | ||
186 | unsigned char Data[2]; | ||
187 | unsigned char value; | ||
188 | |||
189 | reg_w(gspca_dev->dev, 0x07, SAA7113_I2C_BASE_WRITE, 0x0004); | ||
190 | reg_w(gspca_dev->dev, 0x07, reg, 0x0001); | ||
191 | reg_w(gspca_dev->dev, 0x07, 0x01, 0x0002); | ||
192 | while (--retry) { | ||
193 | reg_r(gspca_dev->dev, 0x07, 0x0003, Data, 2); | ||
194 | if ((Data[0] | Data[1]) == 0x00) | ||
195 | break; | ||
196 | } | ||
197 | if (retry == 0) | ||
198 | return -1; | ||
199 | reg_r(gspca_dev->dev, 0x07, 0x0000, &value, 1); | ||
200 | return value; | ||
201 | } | ||
202 | |||
203 | static void spca506_SetNormeInput(struct gspca_dev *gspca_dev, | ||
204 | __u16 norme, | ||
205 | __u16 channel) | ||
206 | { | ||
207 | struct sd *sd = (struct sd *) gspca_dev; | ||
208 | /* fixme: check if channel == 0..3 and 6..9 (8 values) */ | ||
209 | __u8 setbit0 = 0x00; | ||
210 | __u8 setbit1 = 0x00; | ||
211 | __u8 videomask = 0x00; | ||
212 | |||
213 | PDEBUG(D_STREAM, "** Open Set Norme **"); | ||
214 | spca506_Initi2c(gspca_dev); | ||
215 | /* NTSC bit0 -> 1(525 l) PAL SECAM bit0 -> 0 (625 l) */ | ||
216 | /* Composite channel bit1 -> 1 S-video bit 1 -> 0 */ | ||
217 | /* and exclude SAA7113 reserved channel set default 0 otherwise */ | ||
218 | if (norme & V4L2_STD_NTSC) | ||
219 | setbit0 = 0x01; | ||
220 | if (channel == 4 || channel == 5 || channel > 9) | ||
221 | channel = 0; | ||
222 | if (channel < 4) | ||
223 | setbit1 = 0x02; | ||
224 | videomask = (0x48 | setbit0 | setbit1); | ||
225 | reg_w(gspca_dev->dev, 0x08, videomask, 0x0000); | ||
226 | spca506_WriteI2c(gspca_dev, (0xc0 | (channel & 0x0F)), 0x02); | ||
227 | |||
228 | if (norme & V4L2_STD_NTSC) | ||
229 | spca506_WriteI2c(gspca_dev, 0x33, 0x0e); | ||
230 | /* Chrominance Control NTSC N */ | ||
231 | else if (norme & V4L2_STD_SECAM) | ||
232 | spca506_WriteI2c(gspca_dev, 0x53, 0x0e); | ||
233 | /* Chrominance Control SECAM */ | ||
234 | else | ||
235 | spca506_WriteI2c(gspca_dev, 0x03, 0x0e); | ||
236 | /* Chrominance Control PAL BGHIV */ | ||
237 | |||
238 | sd->norme = norme; | ||
239 | sd->channel = channel; | ||
240 | PDEBUG(D_STREAM, "Set Video Byte to 0x%2x", videomask); | ||
241 | PDEBUG(D_STREAM, "Set Norme: %08x Channel %d", norme, channel); | ||
242 | } | ||
243 | |||
244 | static void spca506_GetNormeInput(struct gspca_dev *gspca_dev, | ||
245 | __u16 *norme, __u16 *channel) | ||
246 | { | ||
247 | struct sd *sd = (struct sd *) gspca_dev; | ||
248 | |||
249 | /* Read the register is not so good value change so | ||
250 | we use your own copy in spca50x struct */ | ||
251 | *norme = sd->norme; | ||
252 | *channel = sd->channel; | ||
253 | PDEBUG(D_STREAM, "Get Norme: %d Channel %d", *norme, *channel); | ||
254 | } | ||
255 | |||
256 | static void spca506_Setsize(struct gspca_dev *gspca_dev, __u16 code, | ||
257 | __u16 xmult, __u16 ymult) | ||
258 | { | ||
259 | struct usb_device *dev = gspca_dev->dev; | ||
260 | |||
261 | PDEBUG(D_STREAM, "** SetSize **"); | ||
262 | reg_w(dev, 0x04, (0x18 | (code & 0x07)), 0x0000); | ||
263 | /* Soft snap 0x40 Hard 0x41 */ | ||
264 | reg_w(dev, 0x04, 0x41, 0x0001); | ||
265 | reg_w(dev, 0x04, 0x00, 0x0002); | ||
266 | /* reserved */ | ||
267 | reg_w(dev, 0x04, 0x00, 0x0003); | ||
268 | |||
269 | /* reserved */ | ||
270 | reg_w(dev, 0x04, 0x00, 0x0004); | ||
271 | /* reserved */ | ||
272 | reg_w(dev, 0x04, 0x01, 0x0005); | ||
273 | /* reserced */ | ||
274 | reg_w(dev, 0x04, xmult, 0x0006); | ||
275 | /* reserved */ | ||
276 | reg_w(dev, 0x04, ymult, 0x0007); | ||
277 | /* compression 1 */ | ||
278 | reg_w(dev, 0x04, 0x00, 0x0008); | ||
279 | /* T=64 -> 2 */ | ||
280 | reg_w(dev, 0x04, 0x00, 0x0009); | ||
281 | /* threshold2D */ | ||
282 | reg_w(dev, 0x04, 0x21, 0x000a); | ||
283 | /* quantization */ | ||
284 | reg_w(dev, 0x04, 0x00, 0x000b); | ||
285 | } | ||
286 | |||
287 | /* this function is called at probe time */ | ||
288 | static int sd_config(struct gspca_dev *gspca_dev, | ||
289 | const struct usb_device_id *id) | ||
290 | { | ||
291 | struct sd *sd = (struct sd *) gspca_dev; | ||
292 | struct cam *cam; | ||
293 | |||
294 | cam = &gspca_dev->cam; | ||
295 | cam->dev_name = (char *) id->driver_info; | ||
296 | cam->epaddr = 0x01; | ||
297 | cam->cam_mode = vga_mode; | ||
298 | cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; | ||
299 | sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; | ||
300 | sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; | ||
301 | sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; | ||
302 | sd->hue = sd_ctrls[SD_HUE].qctrl.default_value; | ||
303 | return 0; | ||
304 | } | ||
305 | |||
306 | /* this function is called at open time */ | ||
307 | static int sd_open(struct gspca_dev *gspca_dev) | ||
308 | { | ||
309 | struct usb_device *dev = gspca_dev->dev; | ||
310 | |||
311 | reg_w(dev, 0x03, 0x00, 0x0004); | ||
312 | reg_w(dev, 0x03, 0xFF, 0x0003); | ||
313 | reg_w(dev, 0x03, 0x00, 0x0000); | ||
314 | reg_w(dev, 0x03, 0x1c, 0x0001); | ||
315 | reg_w(dev, 0x03, 0x18, 0x0001); | ||
316 | /* Init on PAL and composite input0 */ | ||
317 | spca506_SetNormeInput(gspca_dev, 0, 0); | ||
318 | reg_w(dev, 0x03, 0x1c, 0x0001); | ||
319 | reg_w(dev, 0x03, 0x18, 0x0001); | ||
320 | reg_w(dev, 0x05, 0x00, 0x0000); | ||
321 | reg_w(dev, 0x05, 0xef, 0x0001); | ||
322 | reg_w(dev, 0x05, 0x00, 0x00c1); | ||
323 | reg_w(dev, 0x05, 0x00, 0x00c2); | ||
324 | reg_w(dev, 0x06, 0x18, 0x0002); | ||
325 | reg_w(dev, 0x06, 0xf5, 0x0011); | ||
326 | reg_w(dev, 0x06, 0x02, 0x0012); | ||
327 | reg_w(dev, 0x06, 0xfb, 0x0013); | ||
328 | reg_w(dev, 0x06, 0x00, 0x0014); | ||
329 | reg_w(dev, 0x06, 0xa4, 0x0051); | ||
330 | reg_w(dev, 0x06, 0x40, 0x0052); | ||
331 | reg_w(dev, 0x06, 0x71, 0x0053); | ||
332 | reg_w(dev, 0x06, 0x40, 0x0054); | ||
333 | /************************************************/ | ||
334 | reg_w(dev, 0x03, 0x00, 0x0004); | ||
335 | reg_w(dev, 0x03, 0x00, 0x0003); | ||
336 | reg_w(dev, 0x03, 0x00, 0x0004); | ||
337 | reg_w(dev, 0x03, 0xFF, 0x0003); | ||
338 | reg_w(dev, 0x02, 0x00, 0x0000); | ||
339 | reg_w(dev, 0x03, 0x60, 0x0000); | ||
340 | reg_w(dev, 0x03, 0x18, 0x0001); | ||
341 | /* for a better reading mx :) */ | ||
342 | /*sdca506_WriteI2c(value,register) */ | ||
343 | spca506_Initi2c(gspca_dev); | ||
344 | spca506_WriteI2c(gspca_dev, 0x08, 0x01); | ||
345 | spca506_WriteI2c(gspca_dev, 0xc0, 0x02); | ||
346 | /* input composite video */ | ||
347 | spca506_WriteI2c(gspca_dev, 0x33, 0x03); | ||
348 | spca506_WriteI2c(gspca_dev, 0x00, 0x04); | ||
349 | spca506_WriteI2c(gspca_dev, 0x00, 0x05); | ||
350 | spca506_WriteI2c(gspca_dev, 0x0d, 0x06); | ||
351 | spca506_WriteI2c(gspca_dev, 0xf0, 0x07); | ||
352 | spca506_WriteI2c(gspca_dev, 0x98, 0x08); | ||
353 | spca506_WriteI2c(gspca_dev, 0x03, 0x09); | ||
354 | spca506_WriteI2c(gspca_dev, 0x80, 0x0a); | ||
355 | spca506_WriteI2c(gspca_dev, 0x47, 0x0b); | ||
356 | spca506_WriteI2c(gspca_dev, 0x48, 0x0c); | ||
357 | spca506_WriteI2c(gspca_dev, 0x00, 0x0d); | ||
358 | spca506_WriteI2c(gspca_dev, 0x03, 0x0e); /* Chroma Pal adjust */ | ||
359 | spca506_WriteI2c(gspca_dev, 0x2a, 0x0f); | ||
360 | spca506_WriteI2c(gspca_dev, 0x00, 0x10); | ||
361 | spca506_WriteI2c(gspca_dev, 0x0c, 0x11); | ||
362 | spca506_WriteI2c(gspca_dev, 0xb8, 0x12); | ||
363 | spca506_WriteI2c(gspca_dev, 0x01, 0x13); | ||
364 | spca506_WriteI2c(gspca_dev, 0x00, 0x14); | ||
365 | spca506_WriteI2c(gspca_dev, 0x00, 0x15); | ||
366 | spca506_WriteI2c(gspca_dev, 0x00, 0x16); | ||
367 | spca506_WriteI2c(gspca_dev, 0x00, 0x17); | ||
368 | spca506_WriteI2c(gspca_dev, 0x00, 0x18); | ||
369 | spca506_WriteI2c(gspca_dev, 0x00, 0x19); | ||
370 | spca506_WriteI2c(gspca_dev, 0x00, 0x1a); | ||
371 | spca506_WriteI2c(gspca_dev, 0x00, 0x1b); | ||
372 | spca506_WriteI2c(gspca_dev, 0x00, 0x1c); | ||
373 | spca506_WriteI2c(gspca_dev, 0x00, 0x1d); | ||
374 | spca506_WriteI2c(gspca_dev, 0x00, 0x1e); | ||
375 | spca506_WriteI2c(gspca_dev, 0xa1, 0x1f); | ||
376 | spca506_WriteI2c(gspca_dev, 0x02, 0x40); | ||
377 | spca506_WriteI2c(gspca_dev, 0xff, 0x41); | ||
378 | spca506_WriteI2c(gspca_dev, 0xff, 0x42); | ||
379 | spca506_WriteI2c(gspca_dev, 0xff, 0x43); | ||
380 | spca506_WriteI2c(gspca_dev, 0xff, 0x44); | ||
381 | spca506_WriteI2c(gspca_dev, 0xff, 0x45); | ||
382 | spca506_WriteI2c(gspca_dev, 0xff, 0x46); | ||
383 | spca506_WriteI2c(gspca_dev, 0xff, 0x47); | ||
384 | spca506_WriteI2c(gspca_dev, 0xff, 0x48); | ||
385 | spca506_WriteI2c(gspca_dev, 0xff, 0x49); | ||
386 | spca506_WriteI2c(gspca_dev, 0xff, 0x4a); | ||
387 | spca506_WriteI2c(gspca_dev, 0xff, 0x4b); | ||
388 | spca506_WriteI2c(gspca_dev, 0xff, 0x4c); | ||
389 | spca506_WriteI2c(gspca_dev, 0xff, 0x4d); | ||
390 | spca506_WriteI2c(gspca_dev, 0xff, 0x4e); | ||
391 | spca506_WriteI2c(gspca_dev, 0xff, 0x4f); | ||
392 | spca506_WriteI2c(gspca_dev, 0xff, 0x50); | ||
393 | spca506_WriteI2c(gspca_dev, 0xff, 0x51); | ||
394 | spca506_WriteI2c(gspca_dev, 0xff, 0x52); | ||
395 | spca506_WriteI2c(gspca_dev, 0xff, 0x53); | ||
396 | spca506_WriteI2c(gspca_dev, 0xff, 0x54); | ||
397 | spca506_WriteI2c(gspca_dev, 0xff, 0x55); | ||
398 | spca506_WriteI2c(gspca_dev, 0xff, 0x56); | ||
399 | spca506_WriteI2c(gspca_dev, 0xff, 0x57); | ||
400 | spca506_WriteI2c(gspca_dev, 0x00, 0x58); | ||
401 | spca506_WriteI2c(gspca_dev, 0x54, 0x59); | ||
402 | spca506_WriteI2c(gspca_dev, 0x07, 0x5a); | ||
403 | spca506_WriteI2c(gspca_dev, 0x83, 0x5b); | ||
404 | spca506_WriteI2c(gspca_dev, 0x00, 0x5c); | ||
405 | spca506_WriteI2c(gspca_dev, 0x00, 0x5d); | ||
406 | spca506_WriteI2c(gspca_dev, 0x00, 0x5e); | ||
407 | spca506_WriteI2c(gspca_dev, 0x00, 0x5f); | ||
408 | spca506_WriteI2c(gspca_dev, 0x00, 0x60); | ||
409 | spca506_WriteI2c(gspca_dev, 0x05, 0x61); | ||
410 | spca506_WriteI2c(gspca_dev, 0x9f, 0x62); | ||
411 | PDEBUG(D_STREAM, "** Close Init *"); | ||
412 | return 0; | ||
413 | } | ||
414 | |||
415 | static void sd_start(struct gspca_dev *gspca_dev) | ||
416 | { | ||
417 | struct usb_device *dev = gspca_dev->dev; | ||
418 | __u16 norme; | ||
419 | __u16 channel; | ||
420 | __u8 Data[2]; | ||
421 | |||
422 | /**************************************/ | ||
423 | reg_w(dev, 0x03, 0x00, 0x0004); | ||
424 | reg_w(dev, 0x03, 0x00, 0x0003); | ||
425 | reg_w(dev, 0x03, 0x00, 0x0004); | ||
426 | reg_w(dev, 0x03, 0xFF, 0x0003); | ||
427 | reg_w(dev, 0x02, 0x00, 0x0000); | ||
428 | reg_w(dev, 0x03, 0x60, 0x0000); | ||
429 | reg_w(dev, 0x03, 0x18, 0x0001); | ||
430 | |||
431 | /*sdca506_WriteI2c(value,register) */ | ||
432 | spca506_Initi2c(gspca_dev); | ||
433 | spca506_WriteI2c(gspca_dev, 0x08, 0x01); /* Increment Delay */ | ||
434 | /* spca506_WriteI2c(gspca_dev, 0xc0, 0x02); * Analog Input Control 1 */ | ||
435 | spca506_WriteI2c(gspca_dev, 0x33, 0x03); | ||
436 | /* Analog Input Control 2 */ | ||
437 | spca506_WriteI2c(gspca_dev, 0x00, 0x04); | ||
438 | /* Analog Input Control 3 */ | ||
439 | spca506_WriteI2c(gspca_dev, 0x00, 0x05); | ||
440 | /* Analog Input Control 4 */ | ||
441 | spca506_WriteI2c(gspca_dev, 0x0d, 0x06); | ||
442 | /* Horizontal Sync Start 0xe9-0x0d */ | ||
443 | spca506_WriteI2c(gspca_dev, 0xf0, 0x07); | ||
444 | /* Horizontal Sync Stop 0x0d-0xf0 */ | ||
445 | |||
446 | spca506_WriteI2c(gspca_dev, 0x98, 0x08); /* Sync Control */ | ||
447 | /* Defaults value */ | ||
448 | spca506_WriteI2c(gspca_dev, 0x03, 0x09); /* Luminance Control */ | ||
449 | spca506_WriteI2c(gspca_dev, 0x80, 0x0a); | ||
450 | /* Luminance Brightness */ | ||
451 | spca506_WriteI2c(gspca_dev, 0x47, 0x0b); /* Luminance Contrast */ | ||
452 | spca506_WriteI2c(gspca_dev, 0x48, 0x0c); | ||
453 | /* Chrominance Saturation */ | ||
454 | spca506_WriteI2c(gspca_dev, 0x00, 0x0d); | ||
455 | /* Chrominance Hue Control */ | ||
456 | spca506_WriteI2c(gspca_dev, 0x2a, 0x0f); | ||
457 | /* Chrominance Gain Control */ | ||
458 | /**************************************/ | ||
459 | spca506_WriteI2c(gspca_dev, 0x00, 0x10); | ||
460 | /* Format/Delay Control */ | ||
461 | spca506_WriteI2c(gspca_dev, 0x0c, 0x11); /* Output Control 1 */ | ||
462 | spca506_WriteI2c(gspca_dev, 0xb8, 0x12); /* Output Control 2 */ | ||
463 | spca506_WriteI2c(gspca_dev, 0x01, 0x13); /* Output Control 3 */ | ||
464 | spca506_WriteI2c(gspca_dev, 0x00, 0x14); /* reserved */ | ||
465 | spca506_WriteI2c(gspca_dev, 0x00, 0x15); /* VGATE START */ | ||
466 | spca506_WriteI2c(gspca_dev, 0x00, 0x16); /* VGATE STOP */ | ||
467 | spca506_WriteI2c(gspca_dev, 0x00, 0x17); /* VGATE Control (MSB) */ | ||
468 | spca506_WriteI2c(gspca_dev, 0x00, 0x18); | ||
469 | spca506_WriteI2c(gspca_dev, 0x00, 0x19); | ||
470 | spca506_WriteI2c(gspca_dev, 0x00, 0x1a); | ||
471 | spca506_WriteI2c(gspca_dev, 0x00, 0x1b); | ||
472 | spca506_WriteI2c(gspca_dev, 0x00, 0x1c); | ||
473 | spca506_WriteI2c(gspca_dev, 0x00, 0x1d); | ||
474 | spca506_WriteI2c(gspca_dev, 0x00, 0x1e); | ||
475 | spca506_WriteI2c(gspca_dev, 0xa1, 0x1f); | ||
476 | spca506_WriteI2c(gspca_dev, 0x02, 0x40); | ||
477 | spca506_WriteI2c(gspca_dev, 0xff, 0x41); | ||
478 | spca506_WriteI2c(gspca_dev, 0xff, 0x42); | ||
479 | spca506_WriteI2c(gspca_dev, 0xff, 0x43); | ||
480 | spca506_WriteI2c(gspca_dev, 0xff, 0x44); | ||
481 | spca506_WriteI2c(gspca_dev, 0xff, 0x45); | ||
482 | spca506_WriteI2c(gspca_dev, 0xff, 0x46); | ||
483 | spca506_WriteI2c(gspca_dev, 0xff, 0x47); | ||
484 | spca506_WriteI2c(gspca_dev, 0xff, 0x48); | ||
485 | spca506_WriteI2c(gspca_dev, 0xff, 0x49); | ||
486 | spca506_WriteI2c(gspca_dev, 0xff, 0x4a); | ||
487 | spca506_WriteI2c(gspca_dev, 0xff, 0x4b); | ||
488 | spca506_WriteI2c(gspca_dev, 0xff, 0x4c); | ||
489 | spca506_WriteI2c(gspca_dev, 0xff, 0x4d); | ||
490 | spca506_WriteI2c(gspca_dev, 0xff, 0x4e); | ||
491 | spca506_WriteI2c(gspca_dev, 0xff, 0x4f); | ||
492 | spca506_WriteI2c(gspca_dev, 0xff, 0x50); | ||
493 | spca506_WriteI2c(gspca_dev, 0xff, 0x51); | ||
494 | spca506_WriteI2c(gspca_dev, 0xff, 0x52); | ||
495 | spca506_WriteI2c(gspca_dev, 0xff, 0x53); | ||
496 | spca506_WriteI2c(gspca_dev, 0xff, 0x54); | ||
497 | spca506_WriteI2c(gspca_dev, 0xff, 0x55); | ||
498 | spca506_WriteI2c(gspca_dev, 0xff, 0x56); | ||
499 | spca506_WriteI2c(gspca_dev, 0xff, 0x57); | ||
500 | spca506_WriteI2c(gspca_dev, 0x00, 0x58); | ||
501 | spca506_WriteI2c(gspca_dev, 0x54, 0x59); | ||
502 | spca506_WriteI2c(gspca_dev, 0x07, 0x5a); | ||
503 | spca506_WriteI2c(gspca_dev, 0x83, 0x5b); | ||
504 | spca506_WriteI2c(gspca_dev, 0x00, 0x5c); | ||
505 | spca506_WriteI2c(gspca_dev, 0x00, 0x5d); | ||
506 | spca506_WriteI2c(gspca_dev, 0x00, 0x5e); | ||
507 | spca506_WriteI2c(gspca_dev, 0x00, 0x5f); | ||
508 | spca506_WriteI2c(gspca_dev, 0x00, 0x60); | ||
509 | spca506_WriteI2c(gspca_dev, 0x05, 0x61); | ||
510 | spca506_WriteI2c(gspca_dev, 0x9f, 0x62); | ||
511 | /**************************************/ | ||
512 | reg_w(dev, 0x05, 0x00, 0x0003); | ||
513 | reg_w(dev, 0x05, 0x00, 0x0004); | ||
514 | reg_w(dev, 0x03, 0x10, 0x0001); | ||
515 | reg_w(dev, 0x03, 0x78, 0x0000); | ||
516 | switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode) { | ||
517 | case 0: | ||
518 | spca506_Setsize(gspca_dev, 0, 0x10, 0x10); | ||
519 | break; | ||
520 | case 1: | ||
521 | spca506_Setsize(gspca_dev, 1, 0x1a, 0x1a); | ||
522 | break; | ||
523 | case 2: | ||
524 | spca506_Setsize(gspca_dev, 2, 0x1c, 0x1c); | ||
525 | break; | ||
526 | case 4: | ||
527 | spca506_Setsize(gspca_dev, 4, 0x34, 0x34); | ||
528 | break; | ||
529 | default: | ||
530 | /* case 5: */ | ||
531 | spca506_Setsize(gspca_dev, 5, 0x40, 0x40); | ||
532 | break; | ||
533 | } | ||
534 | |||
535 | /* compress setting and size */ | ||
536 | /* set i2c luma */ | ||
537 | reg_w(dev, 0x02, 0x01, 0x0000); | ||
538 | reg_w(dev, 0x03, 0x12, 0x000); | ||
539 | reg_r(dev, 0x04, 0x0001, Data, 2); | ||
540 | PDEBUG(D_STREAM, "webcam started"); | ||
541 | spca506_GetNormeInput(gspca_dev, &norme, &channel); | ||
542 | spca506_SetNormeInput(gspca_dev, norme, channel); | ||
543 | } | ||
544 | |||
545 | static void sd_stopN(struct gspca_dev *gspca_dev) | ||
546 | { | ||
547 | struct usb_device *dev = gspca_dev->dev; | ||
548 | |||
549 | reg_w(dev, 0x02, 0x00, 0x0000); | ||
550 | reg_w(dev, 0x03, 0x00, 0x0004); | ||
551 | reg_w(dev, 0x03, 0x00, 0x0003); | ||
552 | } | ||
553 | |||
554 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
555 | { | ||
556 | } | ||
557 | |||
558 | static void sd_close(struct gspca_dev *gspca_dev) | ||
559 | { | ||
560 | } | ||
561 | |||
562 | /* convert YYUV per line to YUYV (YUV 4:2:2) */ | ||
563 | static void yyuv_decode(unsigned char *out, | ||
564 | unsigned char *in, | ||
565 | int width, | ||
566 | int height) | ||
567 | { | ||
568 | unsigned char *Ui, *Vi, *yi, *yi1; | ||
569 | unsigned char *out1; | ||
570 | int i, j; | ||
571 | |||
572 | yi = in; | ||
573 | for (i = height / 2; --i >= 0; ) { | ||
574 | out1 = out + width * 2; /* next line */ | ||
575 | yi1 = yi + width; | ||
576 | Ui = yi1 + width; | ||
577 | Vi = Ui + width / 2; | ||
578 | for (j = width / 2; --j >= 0; ) { | ||
579 | *out++ = 128 + *yi++; | ||
580 | *out++ = 128 + *Ui; | ||
581 | *out++ = 128 + *yi++; | ||
582 | *out++ = 128 + *Vi; | ||
583 | |||
584 | *out1++ = 128 + *yi1++; | ||
585 | *out1++ = 128 + *Ui++; | ||
586 | *out1++ = 128 + *yi1++; | ||
587 | *out1++ = 128 + *Vi++; | ||
588 | } | ||
589 | yi += width * 2; | ||
590 | out = out1; | ||
591 | } | ||
592 | } | ||
593 | |||
594 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | ||
595 | struct gspca_frame *frame, /* target */ | ||
596 | unsigned char *data, /* isoc packet */ | ||
597 | int len) /* iso packet length */ | ||
598 | { | ||
599 | struct sd *sd = (struct sd *) gspca_dev; | ||
600 | |||
601 | switch (data[0]) { | ||
602 | case 0: /* start of frame */ | ||
603 | if (gspca_dev->last_packet_type == FIRST_PACKET) { | ||
604 | yyuv_decode(sd->tmpbuf2, sd->tmpbuf, | ||
605 | gspca_dev->width, | ||
606 | gspca_dev->height); | ||
607 | frame = gspca_frame_add(gspca_dev, | ||
608 | LAST_PACKET, | ||
609 | frame, | ||
610 | sd->tmpbuf2, | ||
611 | gspca_dev->width | ||
612 | * gspca_dev->height | ||
613 | * 2); | ||
614 | } | ||
615 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, | ||
616 | data, 0); | ||
617 | data += SPCA50X_OFFSET_DATA; | ||
618 | len -= SPCA50X_OFFSET_DATA; | ||
619 | if (len > 0) | ||
620 | memcpy(sd->tmpbuf, data, len); | ||
621 | else | ||
622 | len = 0; | ||
623 | sd->buflen = len; | ||
624 | return; | ||
625 | case 0xff: /* drop */ | ||
626 | /* gspca_dev->last_packet_type = DISCARD_PACKET; */ | ||
627 | return; | ||
628 | } | ||
629 | data += 1; | ||
630 | len -= 1; | ||
631 | memcpy(&sd->tmpbuf[sd->buflen], data, len); | ||
632 | sd->buflen += len; | ||
633 | } | ||
634 | |||
635 | static void setbrightness(struct gspca_dev *gspca_dev) | ||
636 | { | ||
637 | struct sd *sd = (struct sd *) gspca_dev; | ||
638 | |||
639 | spca506_Initi2c(gspca_dev); | ||
640 | spca506_WriteI2c(gspca_dev, sd->brightness, SAA7113_bright); | ||
641 | spca506_WriteI2c(gspca_dev, 0x01, 0x09); | ||
642 | } | ||
643 | |||
644 | static void getbrightness(struct gspca_dev *gspca_dev) | ||
645 | { | ||
646 | struct sd *sd = (struct sd *) gspca_dev; | ||
647 | |||
648 | sd->brightness = spca506_ReadI2c(gspca_dev, SAA7113_bright); | ||
649 | } | ||
650 | |||
651 | static void setcontrast(struct gspca_dev *gspca_dev) | ||
652 | { | ||
653 | struct sd *sd = (struct sd *) gspca_dev; | ||
654 | |||
655 | spca506_Initi2c(gspca_dev); | ||
656 | spca506_WriteI2c(gspca_dev, sd->contrast, SAA7113_contrast); | ||
657 | spca506_WriteI2c(gspca_dev, 0x01, 0x09); | ||
658 | } | ||
659 | |||
660 | static void getcontrast(struct gspca_dev *gspca_dev) | ||
661 | { | ||
662 | struct sd *sd = (struct sd *) gspca_dev; | ||
663 | |||
664 | sd->contrast = spca506_ReadI2c(gspca_dev, SAA7113_contrast); | ||
665 | } | ||
666 | |||
667 | static void setcolors(struct gspca_dev *gspca_dev) | ||
668 | { | ||
669 | struct sd *sd = (struct sd *) gspca_dev; | ||
670 | |||
671 | spca506_Initi2c(gspca_dev); | ||
672 | spca506_WriteI2c(gspca_dev, sd->colors, SAA7113_saturation); | ||
673 | spca506_WriteI2c(gspca_dev, 0x01, 0x09); | ||
674 | } | ||
675 | |||
676 | static void getcolors(struct gspca_dev *gspca_dev) | ||
677 | { | ||
678 | struct sd *sd = (struct sd *) gspca_dev; | ||
679 | |||
680 | sd->colors = spca506_ReadI2c(gspca_dev, SAA7113_saturation); | ||
681 | } | ||
682 | |||
683 | static void sethue(struct gspca_dev *gspca_dev) | ||
684 | { | ||
685 | struct sd *sd = (struct sd *) gspca_dev; | ||
686 | |||
687 | spca506_Initi2c(gspca_dev); | ||
688 | spca506_WriteI2c(gspca_dev, sd->hue, SAA7113_hue); | ||
689 | spca506_WriteI2c(gspca_dev, 0x01, 0x09); | ||
690 | } | ||
691 | |||
692 | static void gethue(struct gspca_dev *gspca_dev) | ||
693 | { | ||
694 | struct sd *sd = (struct sd *) gspca_dev; | ||
695 | |||
696 | sd->hue = spca506_ReadI2c(gspca_dev, SAA7113_hue); | ||
697 | } | ||
698 | |||
699 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | ||
700 | { | ||
701 | struct sd *sd = (struct sd *) gspca_dev; | ||
702 | |||
703 | sd->brightness = val; | ||
704 | if (gspca_dev->streaming) | ||
705 | setbrightness(gspca_dev); | ||
706 | return 0; | ||
707 | } | ||
708 | |||
709 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
710 | { | ||
711 | struct sd *sd = (struct sd *) gspca_dev; | ||
712 | |||
713 | getbrightness(gspca_dev); | ||
714 | *val = sd->brightness; | ||
715 | return 0; | ||
716 | } | ||
717 | |||
718 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | ||
719 | { | ||
720 | struct sd *sd = (struct sd *) gspca_dev; | ||
721 | |||
722 | sd->contrast = val; | ||
723 | if (gspca_dev->streaming) | ||
724 | setcontrast(gspca_dev); | ||
725 | return 0; | ||
726 | } | ||
727 | |||
728 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) | ||
729 | { | ||
730 | struct sd *sd = (struct sd *) gspca_dev; | ||
731 | |||
732 | getcontrast(gspca_dev); | ||
733 | *val = sd->contrast; | ||
734 | return 0; | ||
735 | } | ||
736 | |||
737 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) | ||
738 | { | ||
739 | struct sd *sd = (struct sd *) gspca_dev; | ||
740 | |||
741 | sd->colors = val; | ||
742 | if (gspca_dev->streaming) | ||
743 | setcolors(gspca_dev); | ||
744 | return 0; | ||
745 | } | ||
746 | |||
747 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) | ||
748 | { | ||
749 | struct sd *sd = (struct sd *) gspca_dev; | ||
750 | |||
751 | getcolors(gspca_dev); | ||
752 | *val = sd->colors; | ||
753 | return 0; | ||
754 | } | ||
755 | |||
756 | static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val) | ||
757 | { | ||
758 | struct sd *sd = (struct sd *) gspca_dev; | ||
759 | |||
760 | sd->hue = val; | ||
761 | if (gspca_dev->streaming) | ||
762 | sethue(gspca_dev); | ||
763 | return 0; | ||
764 | } | ||
765 | |||
766 | static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val) | ||
767 | { | ||
768 | struct sd *sd = (struct sd *) gspca_dev; | ||
769 | |||
770 | gethue(gspca_dev); | ||
771 | *val = sd->hue; | ||
772 | return 0; | ||
773 | } | ||
774 | |||
775 | /* sub-driver description */ | ||
776 | static struct sd_desc sd_desc = { | ||
777 | .name = MODULE_NAME, | ||
778 | .ctrls = sd_ctrls, | ||
779 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
780 | .config = sd_config, | ||
781 | .open = sd_open, | ||
782 | .start = sd_start, | ||
783 | .stopN = sd_stopN, | ||
784 | .stop0 = sd_stop0, | ||
785 | .close = sd_close, | ||
786 | .pkt_scan = sd_pkt_scan, | ||
787 | }; | ||
788 | |||
789 | /* -- module initialisation -- */ | ||
790 | #define DVNM(name) .driver_info = (kernel_ulong_t) name | ||
791 | static __devinitdata struct usb_device_id device_table[] = { | ||
792 | {USB_DEVICE(0x06e1, 0xa190), DVNM("ADS Instant VCD")}, | ||
793 | /* {USB_DEVICE(0x0733, 0x0430), DVNM("UsbGrabber PV321c")}, */ | ||
794 | {USB_DEVICE(0x0734, 0x043b), DVNM("3DeMon USB Capture aka")}, | ||
795 | {USB_DEVICE(0x99fa, 0x8988), DVNM("Grandtec V.cap")}, | ||
796 | {} | ||
797 | }; | ||
798 | MODULE_DEVICE_TABLE(usb, device_table); | ||
799 | |||
800 | /* -- device connect -- */ | ||
801 | static int sd_probe(struct usb_interface *intf, | ||
802 | const struct usb_device_id *id) | ||
803 | { | ||
804 | return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), | ||
805 | THIS_MODULE); | ||
806 | } | ||
807 | |||
808 | static struct usb_driver sd_driver = { | ||
809 | .name = MODULE_NAME, | ||
810 | .id_table = device_table, | ||
811 | .probe = sd_probe, | ||
812 | .disconnect = gspca_disconnect, | ||
813 | }; | ||
814 | |||
815 | /* -- module insert / remove -- */ | ||
816 | static int __init sd_mod_init(void) | ||
817 | { | ||
818 | if (usb_register(&sd_driver) < 0) | ||
819 | return -1; | ||
820 | PDEBUG(D_PROBE, "v%s registered", version); | ||
821 | return 0; | ||
822 | } | ||
823 | static void __exit sd_mod_exit(void) | ||
824 | { | ||
825 | usb_deregister(&sd_driver); | ||
826 | PDEBUG(D_PROBE, "deregistered"); | ||
827 | } | ||
828 | |||
829 | module_init(sd_mod_init); | ||
830 | module_exit(sd_mod_exit); | ||
diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/video/gspca/spca508.c new file mode 100644 index 000000000000..566adf41f59f --- /dev/null +++ b/drivers/media/video/gspca/spca508.c | |||
@@ -0,0 +1,1774 @@ | |||
1 | /* | ||
2 | * SPCA508 chip based cameras subdriver | ||
3 | * | ||
4 | * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #define MODULE_NAME "spca508" | ||
22 | |||
23 | #include "gspca.h" | ||
24 | |||
25 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) | ||
26 | static const char version[] = "2.1.0"; | ||
27 | |||
28 | MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); | ||
29 | MODULE_DESCRIPTION("GSPCA/SPCA508 USB Camera Driver"); | ||
30 | MODULE_LICENSE("GPL"); | ||
31 | |||
32 | /* specific webcam descriptor */ | ||
33 | struct sd { | ||
34 | struct gspca_dev gspca_dev; /* !! must be the first item */ | ||
35 | |||
36 | int buflen; | ||
37 | unsigned char tmpbuf[352 * 288 * 3 / 2]; /* YUVY per line */ | ||
38 | unsigned char tmpbuf2[352 * 288 * 2]; /* YUYV */ | ||
39 | |||
40 | unsigned char brightness; | ||
41 | |||
42 | char subtype; | ||
43 | #define CreativeVista 0 | ||
44 | #define HamaUSBSightcam 1 | ||
45 | #define HamaUSBSightcam2 2 | ||
46 | #define IntelEasyPCCamera 3 | ||
47 | #define MicroInnovationIC200 4 | ||
48 | #define ViewQuestVQ110 5 | ||
49 | }; | ||
50 | |||
51 | /* V4L2 controls supported by the driver */ | ||
52 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
53 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
54 | |||
55 | static struct ctrl sd_ctrls[] = { | ||
56 | #define SD_BRIGHTNESS 0 | ||
57 | { | ||
58 | { | ||
59 | .id = V4L2_CID_BRIGHTNESS, | ||
60 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
61 | .name = "Brightness", | ||
62 | .minimum = 0, | ||
63 | .maximum = 0xff, | ||
64 | .step = 1, | ||
65 | .default_value = 0x80, | ||
66 | }, | ||
67 | .set = sd_setbrightness, | ||
68 | .get = sd_getbrightness, | ||
69 | }, | ||
70 | }; | ||
71 | |||
72 | static struct cam_mode sif_mode[] = { | ||
73 | {V4L2_PIX_FMT_YUYV, 160, 120, 3}, | ||
74 | {V4L2_PIX_FMT_YUYV, 176, 144, 2}, | ||
75 | {V4L2_PIX_FMT_YUYV, 320, 240, 1}, | ||
76 | {V4L2_PIX_FMT_YUYV, 352, 288, 0}, | ||
77 | }; | ||
78 | |||
79 | /* Frame packet header offsets for the spca508 */ | ||
80 | #define SPCA508_OFFSET_TYPE 1 | ||
81 | #define SPCA508_OFFSET_COMPRESS 2 | ||
82 | #define SPCA508_OFFSET_FRAMSEQ 8 | ||
83 | #define SPCA508_OFFSET_WIN1LUM 11 | ||
84 | #define SPCA508_OFFSET_DATA 37 | ||
85 | |||
86 | #define SPCA508_SNAPBIT 0x20 | ||
87 | #define SPCA508_SNAPCTRL 0x40 | ||
88 | /*************** I2c ****************/ | ||
89 | #define SPCA508_INDEX_I2C_BASE 0x8800 | ||
90 | |||
91 | /* | ||
92 | * Initialization data: this is the first set-up data written to the | ||
93 | * device (before the open data). | ||
94 | */ | ||
95 | static __u16 spca508_init_data[][3] = | ||
96 | #define IGN(x) /* nothing */ | ||
97 | { | ||
98 | /* line URB value, index */ | ||
99 | /* 44274 1804 */ {0x0000, 0x870b}, | ||
100 | |||
101 | /* 44299 1805 */ {0x0020, 0x8112}, | ||
102 | /* Video drop enable, ISO streaming disable */ | ||
103 | /* 44324 1806 */ {0x0003, 0x8111}, | ||
104 | /* Reset compression & memory */ | ||
105 | /* 44349 1807 */ {0x0000, 0x8110}, | ||
106 | /* Disable all outputs */ | ||
107 | /* 44372 1808 */ /* READ {0x0000, 0x8114} -> 0000: 00 */ | ||
108 | /* 44398 1809 */ {0x0000, 0x8114}, | ||
109 | /* SW GPIO data */ | ||
110 | /* 44423 1810 */ {0x0008, 0x8110}, | ||
111 | /* Enable charge pump output */ | ||
112 | /* 44527 1811 */ {0x0002, 0x8116}, | ||
113 | /* 200 kHz pump clock */ | ||
114 | /* 44555 1812 */ | ||
115 | /* UNKNOWN DIRECTION (URB_FUNCTION_SELECT_INTERFACE:) */ | ||
116 | /* 44590 1813 */ {0x0003, 0x8111}, | ||
117 | /* Reset compression & memory */ | ||
118 | /* 44615 1814 */ {0x0000, 0x8111}, | ||
119 | /* Normal mode (not reset) */ | ||
120 | /* 44640 1815 */ {0x0098, 0x8110}, | ||
121 | /* Enable charge pump output, sync.serial,external 2x clock */ | ||
122 | /* 44665 1816 */ {0x000d, 0x8114}, | ||
123 | /* SW GPIO data */ | ||
124 | /* 44690 1817 */ {0x0002, 0x8116}, | ||
125 | /* 200 kHz pump clock */ | ||
126 | /* 44715 1818 */ {0x0020, 0x8112}, | ||
127 | /* Video drop enable, ISO streaming disable */ | ||
128 | /* --------------------------------------- */ | ||
129 | /* 44740 1819 */ {0x000f, 0x8402}, | ||
130 | /* memory bank */ | ||
131 | /* 44765 1820 */ {0x0000, 0x8403}, | ||
132 | /* ... address */ | ||
133 | /* --------------------------------------- */ | ||
134 | /* 0x88__ is Synchronous Serial Interface. */ | ||
135 | /* TBD: This table could be expressed more compactly */ | ||
136 | /* using spca508_write_i2c_vector(). */ | ||
137 | /* TBD: Should see if the values in spca50x_i2c_data */ | ||
138 | /* would work with the VQ110 instead of the values */ | ||
139 | /* below. */ | ||
140 | /* 44790 1821 */ {0x00c0, 0x8804}, | ||
141 | /* SSI slave addr */ | ||
142 | /* 44815 1822 */ {0x0008, 0x8802}, | ||
143 | /* 375 Khz SSI clock */ | ||
144 | /* 44838 1823 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
145 | /* 44862 1824 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
146 | /* 44888 1825 */ {0x0008, 0x8802}, | ||
147 | /* 375 Khz SSI clock */ | ||
148 | /* 44913 1826 */ {0x0012, 0x8801}, | ||
149 | /* SSI reg addr */ | ||
150 | /* 44938 1827 */ {0x0080, 0x8800}, | ||
151 | /* SSI data to write */ | ||
152 | /* 44961 1828 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
153 | /* 44985 1829 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
154 | /* 45009 1830 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
155 | /* 45035 1831 */ {0x0008, 0x8802}, | ||
156 | /* 375 Khz SSI clock */ | ||
157 | /* 45060 1832 */ {0x0012, 0x8801}, | ||
158 | /* SSI reg addr */ | ||
159 | /* 45085 1833 */ {0x0000, 0x8800}, | ||
160 | /* SSI data to write */ | ||
161 | /* 45108 1834 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
162 | /* 45132 1835 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
163 | /* 45156 1836 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
164 | /* 45182 1837 */ {0x0008, 0x8802}, | ||
165 | /* 375 Khz SSI clock */ | ||
166 | /* 45207 1838 */ {0x0011, 0x8801}, | ||
167 | /* SSI reg addr */ | ||
168 | /* 45232 1839 */ {0x0040, 0x8800}, | ||
169 | /* SSI data to write */ | ||
170 | /* 45255 1840 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
171 | /* 45279 1841 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
172 | /* 45303 1842 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
173 | /* 45329 1843 */ {0x0008, 0x8802}, | ||
174 | /* 45354 1844 */ {0x0013, 0x8801}, | ||
175 | /* 45379 1845 */ {0x0000, 0x8800}, | ||
176 | /* 45402 1846 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
177 | /* 45426 1847 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
178 | /* 45450 1848 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
179 | /* 45476 1849 */ {0x0008, 0x8802}, | ||
180 | /* 45501 1850 */ {0x0014, 0x8801}, | ||
181 | /* 45526 1851 */ {0x0000, 0x8800}, | ||
182 | /* 45549 1852 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
183 | /* 45573 1853 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
184 | /* 45597 1854 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
185 | /* 45623 1855 */ {0x0008, 0x8802}, | ||
186 | /* 45648 1856 */ {0x0015, 0x8801}, | ||
187 | /* 45673 1857 */ {0x0001, 0x8800}, | ||
188 | /* 45696 1858 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
189 | /* 45720 1859 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
190 | /* 45744 1860 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
191 | /* 45770 1861 */ {0x0008, 0x8802}, | ||
192 | /* 45795 1862 */ {0x0016, 0x8801}, | ||
193 | /* 45820 1863 */ {0x0003, 0x8800}, | ||
194 | /* 45843 1864 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
195 | /* 45867 1865 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
196 | /* 45891 1866 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
197 | /* 45917 1867 */ {0x0008, 0x8802}, | ||
198 | /* 45942 1868 */ {0x0017, 0x8801}, | ||
199 | /* 45967 1869 */ {0x0036, 0x8800}, | ||
200 | /* 45990 1870 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
201 | /* 46014 1871 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
202 | /* 46038 1872 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
203 | /* 46064 1873 */ {0x0008, 0x8802}, | ||
204 | /* 46089 1874 */ {0x0018, 0x8801}, | ||
205 | /* 46114 1875 */ {0x00ec, 0x8800}, | ||
206 | /* 46137 1876 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
207 | /* 46161 1877 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
208 | /* 46185 1878 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
209 | /* 46211 1879 */ {0x0008, 0x8802}, | ||
210 | /* 46236 1880 */ {0x001a, 0x8801}, | ||
211 | /* 46261 1881 */ {0x0094, 0x8800}, | ||
212 | /* 46284 1882 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
213 | /* 46308 1883 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
214 | /* 46332 1884 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
215 | /* 46358 1885 */ {0x0008, 0x8802}, | ||
216 | /* 46383 1886 */ {0x001b, 0x8801}, | ||
217 | /* 46408 1887 */ {0x0000, 0x8800}, | ||
218 | /* 46431 1888 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
219 | /* 46455 1889 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
220 | /* 46479 1890 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
221 | /* 46505 1891 */ {0x0008, 0x8802}, | ||
222 | /* 46530 1892 */ {0x0027, 0x8801}, | ||
223 | /* 46555 1893 */ {0x00a2, 0x8800}, | ||
224 | /* 46578 1894 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
225 | /* 46602 1895 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
226 | /* 46626 1896 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
227 | /* 46652 1897 */ {0x0008, 0x8802}, | ||
228 | /* 46677 1898 */ {0x0028, 0x8801}, | ||
229 | /* 46702 1899 */ {0x0040, 0x8800}, | ||
230 | /* 46725 1900 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
231 | /* 46749 1901 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
232 | /* 46773 1902 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
233 | /* 46799 1903 */ {0x0008, 0x8802}, | ||
234 | /* 46824 1904 */ {0x002a, 0x8801}, | ||
235 | /* 46849 1905 */ {0x0084, 0x8800}, | ||
236 | /* 46872 1906 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
237 | /* 46896 1907 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
238 | /* 46920 1908 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
239 | /* 46946 1909 */ {0x0008, 0x8802}, | ||
240 | /* 46971 1910 */ {0x002b, 0x8801}, | ||
241 | /* 46996 1911 */ {0x00a8, 0x8800}, | ||
242 | /* 47019 1912 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
243 | /* 47043 1913 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
244 | /* 47067 1914 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
245 | /* 47093 1915 */ {0x0008, 0x8802}, | ||
246 | /* 47118 1916 */ {0x002c, 0x8801}, | ||
247 | /* 47143 1917 */ {0x00fe, 0x8800}, | ||
248 | /* 47166 1918 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
249 | /* 47190 1919 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
250 | /* 47214 1920 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
251 | /* 47240 1921 */ {0x0008, 0x8802}, | ||
252 | /* 47265 1922 */ {0x002d, 0x8801}, | ||
253 | /* 47290 1923 */ {0x0003, 0x8800}, | ||
254 | /* 47313 1924 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
255 | /* 47337 1925 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
256 | /* 47361 1926 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
257 | /* 47387 1927 */ {0x0008, 0x8802}, | ||
258 | /* 47412 1928 */ {0x0038, 0x8801}, | ||
259 | /* 47437 1929 */ {0x0083, 0x8800}, | ||
260 | /* 47460 1930 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
261 | /* 47484 1931 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
262 | /* 47508 1932 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
263 | /* 47534 1933 */ {0x0008, 0x8802}, | ||
264 | /* 47559 1934 */ {0x0033, 0x8801}, | ||
265 | /* 47584 1935 */ {0x0081, 0x8800}, | ||
266 | /* 47607 1936 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
267 | /* 47631 1937 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
268 | /* 47655 1938 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
269 | /* 47681 1939 */ {0x0008, 0x8802}, | ||
270 | /* 47706 1940 */ {0x0034, 0x8801}, | ||
271 | /* 47731 1941 */ {0x004a, 0x8800}, | ||
272 | /* 47754 1942 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
273 | /* 47778 1943 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
274 | /* 47802 1944 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
275 | /* 47828 1945 */ {0x0008, 0x8802}, | ||
276 | /* 47853 1946 */ {0x0039, 0x8801}, | ||
277 | /* 47878 1947 */ {0x0000, 0x8800}, | ||
278 | /* 47901 1948 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
279 | /* 47925 1949 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
280 | /* 47949 1950 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
281 | /* 47975 1951 */ {0x0008, 0x8802}, | ||
282 | /* 48000 1952 */ {0x0010, 0x8801}, | ||
283 | /* 48025 1953 */ {0x00a8, 0x8800}, | ||
284 | /* 48048 1954 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
285 | /* 48072 1955 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
286 | /* 48096 1956 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
287 | /* 48122 1957 */ {0x0008, 0x8802}, | ||
288 | /* 48147 1958 */ {0x0006, 0x8801}, | ||
289 | /* 48172 1959 */ {0x0058, 0x8800}, | ||
290 | /* 48195 1960 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
291 | /* 48219 1961 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
292 | /* 48243 1962 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
293 | /* 48269 1963 */ {0x0008, 0x8802}, | ||
294 | /* 48294 1964 */ {0x0000, 0x8801}, | ||
295 | /* 48319 1965 */ {0x0004, 0x8800}, | ||
296 | /* 48342 1966 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
297 | /* 48366 1967 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
298 | /* 48390 1968 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
299 | /* 48416 1969 */ {0x0008, 0x8802}, | ||
300 | /* 48441 1970 */ {0x0040, 0x8801}, | ||
301 | /* 48466 1971 */ {0x0080, 0x8800}, | ||
302 | /* 48489 1972 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
303 | /* 48513 1973 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
304 | /* 48537 1974 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
305 | /* 48563 1975 */ {0x0008, 0x8802}, | ||
306 | /* 48588 1976 */ {0x0041, 0x8801}, | ||
307 | /* 48613 1977 */ {0x000c, 0x8800}, | ||
308 | /* 48636 1978 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
309 | /* 48660 1979 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
310 | /* 48684 1980 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
311 | /* 48710 1981 */ {0x0008, 0x8802}, | ||
312 | /* 48735 1982 */ {0x0042, 0x8801}, | ||
313 | /* 48760 1983 */ {0x000c, 0x8800}, | ||
314 | /* 48783 1984 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
315 | /* 48807 1985 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
316 | /* 48831 1986 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
317 | /* 48857 1987 */ {0x0008, 0x8802}, | ||
318 | /* 48882 1988 */ {0x0043, 0x8801}, | ||
319 | /* 48907 1989 */ {0x0028, 0x8800}, | ||
320 | /* 48930 1990 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
321 | /* 48954 1991 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
322 | /* 48978 1992 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
323 | /* 49004 1993 */ {0x0008, 0x8802}, | ||
324 | /* 49029 1994 */ {0x0044, 0x8801}, | ||
325 | /* 49054 1995 */ {0x0080, 0x8800}, | ||
326 | /* 49077 1996 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
327 | /* 49101 1997 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
328 | /* 49125 1998 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
329 | /* 49151 1999 */ {0x0008, 0x8802}, | ||
330 | /* 49176 2000 */ {0x0045, 0x8801}, | ||
331 | /* 49201 2001 */ {0x0020, 0x8800}, | ||
332 | /* 49224 2002 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
333 | /* 49248 2003 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
334 | /* 49272 2004 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
335 | /* 49298 2005 */ {0x0008, 0x8802}, | ||
336 | /* 49323 2006 */ {0x0046, 0x8801}, | ||
337 | /* 49348 2007 */ {0x0020, 0x8800}, | ||
338 | /* 49371 2008 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
339 | /* 49395 2009 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
340 | /* 49419 2010 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
341 | /* 49445 2011 */ {0x0008, 0x8802}, | ||
342 | /* 49470 2012 */ {0x0047, 0x8801}, | ||
343 | /* 49495 2013 */ {0x0080, 0x8800}, | ||
344 | /* 49518 2014 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
345 | /* 49542 2015 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
346 | /* 49566 2016 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
347 | /* 49592 2017 */ {0x0008, 0x8802}, | ||
348 | /* 49617 2018 */ {0x0048, 0x8801}, | ||
349 | /* 49642 2019 */ {0x004c, 0x8800}, | ||
350 | /* 49665 2020 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
351 | /* 49689 2021 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
352 | /* 49713 2022 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
353 | /* 49739 2023 */ {0x0008, 0x8802}, | ||
354 | /* 49764 2024 */ {0x0049, 0x8801}, | ||
355 | /* 49789 2025 */ {0x0084, 0x8800}, | ||
356 | /* 49812 2026 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
357 | /* 49836 2027 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
358 | /* 49860 2028 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
359 | /* 49886 2029 */ {0x0008, 0x8802}, | ||
360 | /* 49911 2030 */ {0x004a, 0x8801}, | ||
361 | /* 49936 2031 */ {0x0084, 0x8800}, | ||
362 | /* 49959 2032 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
363 | /* 49983 2033 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
364 | /* 50007 2034 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
365 | /* 50033 2035 */ {0x0008, 0x8802}, | ||
366 | /* 50058 2036 */ {0x004b, 0x8801}, | ||
367 | /* 50083 2037 */ {0x0084, 0x8800}, | ||
368 | /* 50106 2038 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
369 | /* --------------------------------------- */ | ||
370 | /* 50132 2039 */ {0x0012, 0x8700}, | ||
371 | /* Clock speed 48Mhz/(2+2)/2= 6 Mhz */ | ||
372 | /* 50157 2040 */ {0x0000, 0x8701}, | ||
373 | /* CKx1 clock delay adj */ | ||
374 | /* 50182 2041 */ {0x0000, 0x8701}, | ||
375 | /* CKx1 clock delay adj */ | ||
376 | /* 50207 2042 */ {0x0001, 0x870c}, | ||
377 | /* CKOx2 output */ | ||
378 | /* --------------------------------------- */ | ||
379 | /* 50232 2043 */ {0x0080, 0x8600}, | ||
380 | /* Line memory read counter (L) */ | ||
381 | /* 50257 2044 */ {0x0001, 0x8606}, | ||
382 | /* reserved */ | ||
383 | /* 50282 2045 */ {0x0064, 0x8607}, | ||
384 | /* Line memory read counter (H) 0x6480=25,728 */ | ||
385 | /* 50307 2046 */ {0x002a, 0x8601}, | ||
386 | /* CDSP sharp interpolation mode, | ||
387 | * line sel for color sep, edge enhance enab */ | ||
388 | /* 50332 2047 */ {0x0000, 0x8602}, | ||
389 | /* optical black level for user settng = 0 */ | ||
390 | /* 50357 2048 */ {0x0080, 0x8600}, | ||
391 | /* Line memory read counter (L) */ | ||
392 | /* 50382 2049 */ {0x000a, 0x8603}, | ||
393 | /* optical black level calc mode: auto; optical black offset = 10 */ | ||
394 | /* 50407 2050 */ {0x00df, 0x865b}, | ||
395 | /* Horiz offset for valid pixels (L)=0xdf */ | ||
396 | /* 50432 2051 */ {0x0012, 0x865c}, | ||
397 | /* Vert offset for valid lines (L)=0x12 */ | ||
398 | |||
399 | /* The following two lines seem to be the "wrong" resolution. */ | ||
400 | /* But perhaps these indicate the actual size of the sensor */ | ||
401 | /* rather than the size of the current video mode. */ | ||
402 | /* 50457 2052 */ {0x0058, 0x865d}, | ||
403 | /* Horiz valid pixels (*4) (L) = 352 */ | ||
404 | /* 50482 2053 */ {0x0048, 0x865e}, | ||
405 | /* Vert valid lines (*4) (L) = 288 */ | ||
406 | |||
407 | /* 50507 2054 */ {0x0015, 0x8608}, | ||
408 | /* A11 Coef ... */ | ||
409 | /* 50532 2055 */ {0x0030, 0x8609}, | ||
410 | /* 50557 2056 */ {0x00fb, 0x860a}, | ||
411 | /* 50582 2057 */ {0x003e, 0x860b}, | ||
412 | /* 50607 2058 */ {0x00ce, 0x860c}, | ||
413 | /* 50632 2059 */ {0x00f4, 0x860d}, | ||
414 | /* 50657 2060 */ {0x00eb, 0x860e}, | ||
415 | /* 50682 2061 */ {0x00dc, 0x860f}, | ||
416 | /* 50707 2062 */ {0x0039, 0x8610}, | ||
417 | /* 50732 2063 */ {0x0001, 0x8611}, | ||
418 | /* R offset for white balance ... */ | ||
419 | /* 50757 2064 */ {0x0000, 0x8612}, | ||
420 | /* 50782 2065 */ {0x0001, 0x8613}, | ||
421 | /* 50807 2066 */ {0x0000, 0x8614}, | ||
422 | /* 50832 2067 */ {0x005b, 0x8651}, | ||
423 | /* R gain for white balance ... */ | ||
424 | /* 50857 2068 */ {0x0040, 0x8652}, | ||
425 | /* 50882 2069 */ {0x0060, 0x8653}, | ||
426 | /* 50907 2070 */ {0x0040, 0x8654}, | ||
427 | /* 50932 2071 */ {0x0000, 0x8655}, | ||
428 | /* 50957 2072 */ {0x0001, 0x863f}, | ||
429 | /* Fixed gamma correction enable, USB control, | ||
430 | * lum filter disable, lum noise clip disable */ | ||
431 | /* 50982 2073 */ {0x00a1, 0x8656}, | ||
432 | /* Window1 size 256x256, Windows2 size 64x64, | ||
433 | * gamma look-up disable, new edge enhancement enable */ | ||
434 | /* 51007 2074 */ {0x0018, 0x8657}, | ||
435 | /* Edge gain high thresh */ | ||
436 | /* 51032 2075 */ {0x0020, 0x8658}, | ||
437 | /* Edge gain low thresh */ | ||
438 | /* 51057 2076 */ {0x000a, 0x8659}, | ||
439 | /* Edge bandwidth high threshold */ | ||
440 | /* 51082 2077 */ {0x0005, 0x865a}, | ||
441 | /* Edge bandwidth low threshold */ | ||
442 | /* -------------------------------- */ | ||
443 | /* 51107 2078 */ {0x0030, 0x8112}, | ||
444 | /* Video drop enable, ISO streaming enable */ | ||
445 | /* 51130 2079 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
446 | /* 51154 2080 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
447 | /* 51180 2081 */ {0xa908, 0x8802}, | ||
448 | /* 51205 2082 */ {0x0034, 0x8801}, | ||
449 | /* SSI reg addr */ | ||
450 | /* 51230 2083 */ {0x00ca, 0x8800}, | ||
451 | /* SSI data to write */ | ||
452 | /* 51253 2084 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
453 | /* 51277 2085 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
454 | /* 51301 2086 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
455 | /* 51327 2087 */ {0x1f08, 0x8802}, | ||
456 | /* 51352 2088 */ {0x0006, 0x8801}, | ||
457 | /* 51377 2089 */ {0x0080, 0x8800}, | ||
458 | /* 51400 2090 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
459 | |||
460 | /* ----- Read back coefs we wrote earlier. */ | ||
461 | /* 51424 2091 */ /* READ { 0, 0x0000, 0x8608 } -> 0000: 15 */ | ||
462 | /* 51448 2092 */ /* READ { 0, 0x0000, 0x8609 } -> 0000: 30 */ | ||
463 | /* 51472 2093 */ /* READ { 0, 0x0000, 0x860a } -> 0000: fb */ | ||
464 | /* 51496 2094 */ /* READ { 0, 0x0000, 0x860b } -> 0000: 3e */ | ||
465 | /* 51520 2095 */ /* READ { 0, 0x0000, 0x860c } -> 0000: ce */ | ||
466 | /* 51544 2096 */ /* READ { 0, 0x0000, 0x860d } -> 0000: f4 */ | ||
467 | /* 51568 2097 */ /* READ { 0, 0x0000, 0x860e } -> 0000: eb */ | ||
468 | /* 51592 2098 */ /* READ { 0, 0x0000, 0x860f } -> 0000: dc */ | ||
469 | /* 51616 2099 */ /* READ { 0, 0x0000, 0x8610 } -> 0000: 39 */ | ||
470 | /* 51640 2100 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
471 | /* 51664 2101 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
472 | /* 51690 2102 */ {0xb008, 0x8802}, | ||
473 | /* 51715 2103 */ {0x0006, 0x8801}, | ||
474 | /* 51740 2104 */ {0x007d, 0x8800}, | ||
475 | /* 51763 2105 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
476 | |||
477 | |||
478 | /* This chunk is seemingly redundant with */ | ||
479 | /* earlier commands (A11 Coef...), but if I disable it, */ | ||
480 | /* the image appears too dark. Maybe there was some kind of */ | ||
481 | /* reset since the earlier commands, so this is necessary again. */ | ||
482 | /* 51789 2106 */ {0x0015, 0x8608}, | ||
483 | /* 51814 2107 */ {0x0030, 0x8609}, | ||
484 | /* 51839 2108 */ {0xfffb, 0x860a}, | ||
485 | /* 51864 2109 */ {0x003e, 0x860b}, | ||
486 | /* 51889 2110 */ {0xffce, 0x860c}, | ||
487 | /* 51914 2111 */ {0xfff4, 0x860d}, | ||
488 | /* 51939 2112 */ {0xffeb, 0x860e}, | ||
489 | /* 51964 2113 */ {0xffdc, 0x860f}, | ||
490 | /* 51989 2114 */ {0x0039, 0x8610}, | ||
491 | /* 52014 2115 */ {0x0018, 0x8657}, | ||
492 | |||
493 | /* 52039 2116 */ {0x0000, 0x8508}, | ||
494 | /* Disable compression. */ | ||
495 | /* Previous line was: | ||
496 | * 52039 2116 * { 0, 0x0021, 0x8508 }, * Enable compression. */ | ||
497 | /* 52064 2117 */ {0x0032, 0x850b}, | ||
498 | /* compression stuff */ | ||
499 | /* 52089 2118 */ {0x0003, 0x8509}, | ||
500 | /* compression stuff */ | ||
501 | /* 52114 2119 */ {0x0011, 0x850a}, | ||
502 | /* compression stuff */ | ||
503 | /* 52139 2120 */ {0x0021, 0x850d}, | ||
504 | /* compression stuff */ | ||
505 | /* 52164 2121 */ {0x0010, 0x850c}, | ||
506 | /* compression stuff */ | ||
507 | /* 52189 2122 */ {0x0003, 0x8500}, | ||
508 | /* *** Video mode: 160x120 */ | ||
509 | /* 52214 2123 */ {0x0001, 0x8501}, | ||
510 | /* Hardware-dominated snap control */ | ||
511 | /* 52239 2124 */ {0x0061, 0x8656}, | ||
512 | /* Window1 size 128x128, Windows2 size 128x128, | ||
513 | * gamma look-up disable, new edge enhancement enable */ | ||
514 | /* 52264 2125 */ {0x0018, 0x8617}, | ||
515 | /* Window1 start X (*2) */ | ||
516 | /* 52289 2126 */ {0x0008, 0x8618}, | ||
517 | /* Window1 start Y (*2) */ | ||
518 | /* 52314 2127 */ {0x0061, 0x8656}, | ||
519 | /* Window1 size 128x128, Windows2 size 128x128, | ||
520 | * gamma look-up disable, new edge enhancement enable */ | ||
521 | /* 52339 2128 */ {0x0058, 0x8619}, | ||
522 | /* Window2 start X (*2) */ | ||
523 | /* 52364 2129 */ {0x0008, 0x861a}, | ||
524 | /* Window2 start Y (*2) */ | ||
525 | /* 52389 2130 */ {0x00ff, 0x8615}, | ||
526 | /* High lum thresh for white balance */ | ||
527 | /* 52414 2131 */ {0x0000, 0x8616}, | ||
528 | /* Low lum thresh for white balance */ | ||
529 | /* 52439 2132 */ {0x0012, 0x8700}, | ||
530 | /* Clock speed 48Mhz/(2+2)/2= 6 Mhz */ | ||
531 | /* 52464 2133 */ {0x0012, 0x8700}, | ||
532 | /* Clock speed 48Mhz/(2+2)/2= 6 Mhz */ | ||
533 | /* 52487 2134 */ /* READ { 0, 0x0000, 0x8656 } -> 0000: 61 */ | ||
534 | /* 52513 2135 */ {0x0028, 0x8802}, | ||
535 | /* 375 Khz SSI clock, SSI r/w sync with VSYNC */ | ||
536 | /* 52536 2136 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
537 | /* 52560 2137 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 28 */ | ||
538 | /* 52586 2138 */ {0x1f28, 0x8802}, | ||
539 | /* 375 Khz SSI clock, SSI r/w sync with VSYNC */ | ||
540 | /* 52611 2139 */ {0x0010, 0x8801}, | ||
541 | /* SSI reg addr */ | ||
542 | /* 52636 2140 */ {0x003e, 0x8800}, | ||
543 | /* SSI data to write */ | ||
544 | /* 52659 2141 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
545 | /* 52685 2142 */ {0x0028, 0x8802}, | ||
546 | /* 52708 2143 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
547 | /* 52732 2144 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 28 */ | ||
548 | /* 52758 2145 */ {0x1f28, 0x8802}, | ||
549 | /* 52783 2146 */ {0x0000, 0x8801}, | ||
550 | /* 52808 2147 */ {0x001f, 0x8800}, | ||
551 | /* 52831 2148 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
552 | /* 52857 2149 */ {0x0001, 0x8602}, | ||
553 | /* optical black level for user settning = 1 */ | ||
554 | |||
555 | /* Original: */ | ||
556 | /* 52882 2150 */ {0x0023, 0x8700}, | ||
557 | /* Clock speed 48Mhz/(3+2)/4= 2.4 Mhz */ | ||
558 | /* 52907 2151 */ {0x000f, 0x8602}, | ||
559 | /* optical black level for user settning = 15 */ | ||
560 | |||
561 | /* 52932 2152 */ {0x0028, 0x8802}, | ||
562 | /* 52955 2153 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
563 | /* 52979 2154 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 28 */ | ||
564 | /* 53005 2155 */ {0x1f28, 0x8802}, | ||
565 | /* 53030 2156 */ {0x0010, 0x8801}, | ||
566 | /* 53055 2157 */ {0x007b, 0x8800}, | ||
567 | /* 53078 2158 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
568 | /* 53104 2159 */ {0x002f, 0x8651}, | ||
569 | /* R gain for white balance ... */ | ||
570 | /* 53129 2160 */ {0x0080, 0x8653}, | ||
571 | /* 53152 2161 */ /* READ { 0, 0x0000, 0x8655 } -> 0000: 00 */ | ||
572 | /* 53178 2162 */ {0x0000, 0x8655}, | ||
573 | |||
574 | /* 53203 2163 */ {0x0030, 0x8112}, | ||
575 | /* Video drop enable, ISO streaming enable */ | ||
576 | /* 53228 2164 */ {0x0020, 0x8112}, | ||
577 | /* Video drop enable, ISO streaming disable */ | ||
578 | /* 53252 2165 */ | ||
579 | /* UNKNOWN DIRECTION (URB_FUNCTION_SELECT_INTERFACE: (ALT=0) ) */ | ||
580 | {0, 0} | ||
581 | }; | ||
582 | |||
583 | |||
584 | /* | ||
585 | * Initialization data for Intel EasyPC Camera CS110 | ||
586 | */ | ||
587 | static __u16 spca508cs110_init_data[][3] = { | ||
588 | {0x0000, 0x870b}, /* Reset CTL3 */ | ||
589 | {0x0003, 0x8111}, /* Soft Reset compression, memory, TG & CDSP */ | ||
590 | {0x0000, 0x8111}, /* Normal operation on reset */ | ||
591 | {0x0090, 0x8110}, | ||
592 | /* External Clock 2x & Synchronous Serial Interface Output */ | ||
593 | {0x0020, 0x8112}, /* Video Drop packet enable */ | ||
594 | {0x0000, 0x8114}, /* Software GPIO output data */ | ||
595 | {0x0001, 0x8114}, | ||
596 | {0x0001, 0x8114}, | ||
597 | {0x0001, 0x8114}, | ||
598 | {0x0003, 0x8114}, | ||
599 | |||
600 | /* Initial sequence Synchronous Serial Interface */ | ||
601 | {0x000f, 0x8402}, /* Memory bank Address */ | ||
602 | {0x0000, 0x8403}, /* Memory bank Address */ | ||
603 | {0x00ba, 0x8804}, /* SSI Slave address */ | ||
604 | {0x0010, 0x8802}, /* 93.75kHz SSI Clock Two DataByte */ | ||
605 | {0x0010, 0x8802}, /* 93.75kHz SSI Clock two DataByte */ | ||
606 | |||
607 | {0x0001, 0x8801}, | ||
608 | {0x000a, 0x8805},/* a - NWG: Dunno what this is about */ | ||
609 | {0x0000, 0x8800}, | ||
610 | {0x0010, 0x8802}, | ||
611 | |||
612 | {0x0002, 0x8801}, | ||
613 | {0x0000, 0x8805}, | ||
614 | {0x0000, 0x8800}, | ||
615 | {0x0010, 0x8802}, | ||
616 | |||
617 | {0x0003, 0x8801}, | ||
618 | {0x0027, 0x8805}, | ||
619 | {0x0001, 0x8800}, | ||
620 | {0x0010, 0x8802}, | ||
621 | |||
622 | {0x0004, 0x8801}, | ||
623 | {0x0065, 0x8805}, | ||
624 | {0x0001, 0x8800}, | ||
625 | {0x0010, 0x8802}, | ||
626 | |||
627 | {0x0005, 0x8801}, | ||
628 | {0x0003, 0x8805}, | ||
629 | {0x0000, 0x8800}, | ||
630 | {0x0010, 0x8802}, | ||
631 | |||
632 | {0x0006, 0x8801}, | ||
633 | {0x001c, 0x8805}, | ||
634 | {0x0000, 0x8800}, | ||
635 | {0x0010, 0x8802}, | ||
636 | |||
637 | {0x0007, 0x8801}, | ||
638 | {0x002a, 0x8805}, | ||
639 | {0x0000, 0x8800}, | ||
640 | {0x0010, 0x8802}, | ||
641 | |||
642 | {0x0002, 0x8704}, /* External input CKIx1 */ | ||
643 | {0x0001, 0x8606}, /* 1 Line memory Read Counter (H) Result: (d)410 */ | ||
644 | {0x009a, 0x8600}, /* Line memory Read Counter (L) */ | ||
645 | {0x0001, 0x865b}, /* 1 Horizontal Offset for Valid Pixel(L) */ | ||
646 | {0x0003, 0x865c}, /* 3 Vertical Offset for Valid Lines(L) */ | ||
647 | {0x0058, 0x865d}, /* 58 Horizontal Valid Pixel Window(L) */ | ||
648 | |||
649 | {0x0006, 0x8660}, /* Nibble data + input order */ | ||
650 | |||
651 | {0x000a, 0x8602}, /* Optical black level set to 0x0a */ | ||
652 | /* 1945 */ {0x0000, 0x8603}, /* Optical black level Offset */ | ||
653 | |||
654 | /* 1962 * {0, 0x0000, 0x8611}, * 0 R Offset for white Balance */ | ||
655 | /* 1963 * {0, 0x0000, 0x8612}, * 1 Gr Offset for white Balance */ | ||
656 | /* 1964 * {0, 0x0000, 0x8613}, * 1f B Offset for white Balance */ | ||
657 | /* 1965 * {0, 0x0000, 0x8614}, * f0 Gb Offset for white Balance */ | ||
658 | |||
659 | {0x0040, 0x8651}, /* 2b BLUE gain for white balance good at all 60 */ | ||
660 | {0x0030, 0x8652}, /* 41 Gr Gain for white Balance (L) */ | ||
661 | {0x0035, 0x8653}, /* 26 RED gain for white balance */ | ||
662 | {0x0035, 0x8654}, /* 40Gb Gain for white Balance (L) */ | ||
663 | {0x0041, 0x863f}, | ||
664 | /* Fixed Gamma correction enabled (makes colours look better) */ | ||
665 | |||
666 | /* 2422 */ {0x0000, 0x8655}, | ||
667 | /* High bits for white balance*****brightness control*** */ | ||
668 | {} | ||
669 | }; | ||
670 | |||
671 | static __u16 spca508_sightcam_init_data[][3] = { | ||
672 | /* This line seems to setup the frame/canvas */ | ||
673 | /*368 */ {0x000f, 0x8402}, | ||
674 | |||
675 | /* Theese 6 lines are needed to startup the webcam */ | ||
676 | /*398 */ {0x0090, 0x8110}, | ||
677 | /*399 */ {0x0001, 0x8114}, | ||
678 | /*400 */ {0x0001, 0x8114}, | ||
679 | /*401 */ {0x0001, 0x8114}, | ||
680 | /*402 */ {0x0003, 0x8114}, | ||
681 | /*403 */ {0x0080, 0x8804}, | ||
682 | |||
683 | /* This part seems to make the pictures darker? (autobrightness?) */ | ||
684 | /*436 */ {0x0001, 0x8801}, | ||
685 | /*437 */ {0x0004, 0x8800}, | ||
686 | /*439 */ {0x0003, 0x8801}, | ||
687 | /*440 */ {0x00e0, 0x8800}, | ||
688 | /*442 */ {0x0004, 0x8801}, | ||
689 | /*443 */ {0x00b4, 0x8800}, | ||
690 | /*445 */ {0x0005, 0x8801}, | ||
691 | /*446 */ {0x0000, 0x8800}, | ||
692 | |||
693 | /*448 */ {0x0006, 0x8801}, | ||
694 | /*449 */ {0x00e0, 0x8800}, | ||
695 | /*451 */ {0x0007, 0x8801}, | ||
696 | /*452 */ {0x000c, 0x8800}, | ||
697 | |||
698 | /* This section is just needed, it probably | ||
699 | * does something like the previous section, | ||
700 | * but the cam won't start if it's not included. | ||
701 | */ | ||
702 | /*484 */ {0x0014, 0x8801}, | ||
703 | /*485 */ {0x0008, 0x8800}, | ||
704 | /*487 */ {0x0015, 0x8801}, | ||
705 | /*488 */ {0x0067, 0x8800}, | ||
706 | /*490 */ {0x0016, 0x8801}, | ||
707 | /*491 */ {0x0000, 0x8800}, | ||
708 | /*493 */ {0x0017, 0x8801}, | ||
709 | /*494 */ {0x0020, 0x8800}, | ||
710 | /*496 */ {0x0018, 0x8801}, | ||
711 | /*497 */ {0x0044, 0x8800}, | ||
712 | |||
713 | /* Makes the picture darker - and the | ||
714 | * cam won't start if not included | ||
715 | */ | ||
716 | /*505 */ {0x001e, 0x8801}, | ||
717 | /*506 */ {0x00ea, 0x8800}, | ||
718 | /*508 */ {0x001f, 0x8801}, | ||
719 | /*509 */ {0x0001, 0x8800}, | ||
720 | /*511 */ {0x0003, 0x8801}, | ||
721 | /*512 */ {0x00e0, 0x8800}, | ||
722 | |||
723 | /* seems to place the colors ontop of each other #1 */ | ||
724 | /*517 */ {0x0006, 0x8704}, | ||
725 | /*518 */ {0x0001, 0x870c}, | ||
726 | /*519 */ {0x0016, 0x8600}, | ||
727 | /*520 */ {0x0002, 0x8606}, | ||
728 | |||
729 | /* if not included the pictures becomes _very_ dark */ | ||
730 | /*521 */ {0x0064, 0x8607}, | ||
731 | /*522 */ {0x003a, 0x8601}, | ||
732 | /*523 */ {0x0000, 0x8602}, | ||
733 | |||
734 | /* seems to place the colors ontop of each other #2 */ | ||
735 | /*524 */ {0x0016, 0x8600}, | ||
736 | /*525 */ {0x0018, 0x8617}, | ||
737 | /*526 */ {0x0008, 0x8618}, | ||
738 | /*527 */ {0x00a1, 0x8656}, | ||
739 | |||
740 | /* webcam won't start if not included */ | ||
741 | /*528 */ {0x0007, 0x865b}, | ||
742 | /*529 */ {0x0001, 0x865c}, | ||
743 | /*530 */ {0x0058, 0x865d}, | ||
744 | /*531 */ {0x0048, 0x865e}, | ||
745 | |||
746 | /* adjusts the colors */ | ||
747 | /*541 */ {0x0049, 0x8651}, | ||
748 | /*542 */ {0x0040, 0x8652}, | ||
749 | /*543 */ {0x004c, 0x8653}, | ||
750 | /*544 */ {0x0040, 0x8654}, | ||
751 | |||
752 | {0, 0} | ||
753 | }; | ||
754 | |||
755 | static __u16 spca508_sightcam2_init_data[][3] = { | ||
756 | /* 35 */ {0x0020, 0x8112}, | ||
757 | |||
758 | /* 36 */ {0x000f, 0x8402}, | ||
759 | /* 37 */ {0x0000, 0x8403}, | ||
760 | |||
761 | /* 38 */ {0x0008, 0x8201}, | ||
762 | /* 39 */ {0x0008, 0x8200}, | ||
763 | /* 40 */ {0x0001, 0x8200}, | ||
764 | /* 43 */ {0x0009, 0x8201}, | ||
765 | /* 44 */ {0x0008, 0x8200}, | ||
766 | /* 45 */ {0x0001, 0x8200}, | ||
767 | /* 48 */ {0x000a, 0x8201}, | ||
768 | /* 49 */ {0x0008, 0x8200}, | ||
769 | /* 50 */ {0x0001, 0x8200}, | ||
770 | /* 53 */ {0x000b, 0x8201}, | ||
771 | /* 54 */ {0x0008, 0x8200}, | ||
772 | /* 55 */ {0x0001, 0x8200}, | ||
773 | /* 58 */ {0x000c, 0x8201}, | ||
774 | /* 59 */ {0x0008, 0x8200}, | ||
775 | /* 60 */ {0x0001, 0x8200}, | ||
776 | /* 63 */ {0x000d, 0x8201}, | ||
777 | /* 64 */ {0x0008, 0x8200}, | ||
778 | /* 65 */ {0x0001, 0x8200}, | ||
779 | /* 68 */ {0x000e, 0x8201}, | ||
780 | /* 69 */ {0x0008, 0x8200}, | ||
781 | /* 70 */ {0x0001, 0x8200}, | ||
782 | /* 73 */ {0x0007, 0x8201}, | ||
783 | /* 74 */ {0x0008, 0x8200}, | ||
784 | /* 75 */ {0x0001, 0x8200}, | ||
785 | /* 78 */ {0x000f, 0x8201}, | ||
786 | /* 79 */ {0x0008, 0x8200}, | ||
787 | /* 80 */ {0x0001, 0x8200}, | ||
788 | |||
789 | /* 84 */ {0x0018, 0x8660}, | ||
790 | /* 85 */ {0x0010, 0x8201}, | ||
791 | |||
792 | /* 86 */ {0x0008, 0x8200}, | ||
793 | /* 87 */ {0x0001, 0x8200}, | ||
794 | /* 90 */ {0x0011, 0x8201}, | ||
795 | /* 91 */ {0x0008, 0x8200}, | ||
796 | /* 92 */ {0x0001, 0x8200}, | ||
797 | |||
798 | /* 95 */ {0x0000, 0x86b0}, | ||
799 | /* 96 */ {0x0034, 0x86b1}, | ||
800 | /* 97 */ {0x0000, 0x86b2}, | ||
801 | /* 98 */ {0x0049, 0x86b3}, | ||
802 | /* 99 */ {0x0000, 0x86b4}, | ||
803 | /* 100 */ {0x0000, 0x86b4}, | ||
804 | |||
805 | /* 101 */ {0x0012, 0x8201}, | ||
806 | /* 102 */ {0x0008, 0x8200}, | ||
807 | /* 103 */ {0x0001, 0x8200}, | ||
808 | /* 106 */ {0x0013, 0x8201}, | ||
809 | /* 107 */ {0x0008, 0x8200}, | ||
810 | /* 108 */ {0x0001, 0x8200}, | ||
811 | |||
812 | /* 111 */ {0x0001, 0x86b0}, | ||
813 | /* 112 */ {0x00aa, 0x86b1}, | ||
814 | /* 113 */ {0x0000, 0x86b2}, | ||
815 | /* 114 */ {0x00e4, 0x86b3}, | ||
816 | /* 115 */ {0x0000, 0x86b4}, | ||
817 | /* 116 */ {0x0000, 0x86b4}, | ||
818 | |||
819 | /* 118 */ {0x0018, 0x8660}, | ||
820 | |||
821 | /* 119 */ {0x0090, 0x8110}, | ||
822 | /* 120 */ {0x0001, 0x8114}, | ||
823 | /* 121 */ {0x0001, 0x8114}, | ||
824 | /* 122 */ {0x0001, 0x8114}, | ||
825 | /* 123 */ {0x0003, 0x8114}, | ||
826 | |||
827 | /* 124 */ {0x0080, 0x8804}, | ||
828 | /* 157 */ {0x0003, 0x8801}, | ||
829 | /* 158 */ {0x0012, 0x8800}, | ||
830 | /* 160 */ {0x0004, 0x8801}, | ||
831 | /* 161 */ {0x0005, 0x8800}, | ||
832 | /* 163 */ {0x0005, 0x8801}, | ||
833 | /* 164 */ {0x0000, 0x8800}, | ||
834 | /* 166 */ {0x0006, 0x8801}, | ||
835 | /* 167 */ {0x0000, 0x8800}, | ||
836 | /* 169 */ {0x0007, 0x8801}, | ||
837 | /* 170 */ {0x0000, 0x8800}, | ||
838 | /* 172 */ {0x0008, 0x8801}, | ||
839 | /* 173 */ {0x0005, 0x8800}, | ||
840 | /* 175 */ {0x000a, 0x8700}, | ||
841 | /* 176 */ {0x000e, 0x8801}, | ||
842 | /* 177 */ {0x0004, 0x8800}, | ||
843 | /* 179 */ {0x0005, 0x8801}, | ||
844 | /* 180 */ {0x0047, 0x8800}, | ||
845 | /* 182 */ {0x0006, 0x8801}, | ||
846 | /* 183 */ {0x0000, 0x8800}, | ||
847 | /* 185 */ {0x0007, 0x8801}, | ||
848 | /* 186 */ {0x00c0, 0x8800}, | ||
849 | /* 188 */ {0x0008, 0x8801}, | ||
850 | /* 189 */ {0x0003, 0x8800}, | ||
851 | /* 191 */ {0x0013, 0x8801}, | ||
852 | /* 192 */ {0x0001, 0x8800}, | ||
853 | /* 194 */ {0x0009, 0x8801}, | ||
854 | /* 195 */ {0x0000, 0x8800}, | ||
855 | /* 197 */ {0x000a, 0x8801}, | ||
856 | /* 198 */ {0x0000, 0x8800}, | ||
857 | /* 200 */ {0x000b, 0x8801}, | ||
858 | /* 201 */ {0x0000, 0x8800}, | ||
859 | /* 203 */ {0x000c, 0x8801}, | ||
860 | /* 204 */ {0x0000, 0x8800}, | ||
861 | /* 206 */ {0x000e, 0x8801}, | ||
862 | /* 207 */ {0x0004, 0x8800}, | ||
863 | /* 209 */ {0x000f, 0x8801}, | ||
864 | /* 210 */ {0x0000, 0x8800}, | ||
865 | /* 212 */ {0x0010, 0x8801}, | ||
866 | /* 213 */ {0x0006, 0x8800}, | ||
867 | /* 215 */ {0x0011, 0x8801}, | ||
868 | /* 216 */ {0x0006, 0x8800}, | ||
869 | /* 218 */ {0x0012, 0x8801}, | ||
870 | /* 219 */ {0x0000, 0x8800}, | ||
871 | /* 221 */ {0x0013, 0x8801}, | ||
872 | /* 222 */ {0x0001, 0x8800}, | ||
873 | |||
874 | /* 224 */ {0x000a, 0x8700}, | ||
875 | /* 225 */ {0x0000, 0x8702}, | ||
876 | /* 226 */ {0x0000, 0x8703}, | ||
877 | /* 227 */ {0x00c2, 0x8704}, | ||
878 | /* 228 */ {0x0001, 0x870c}, | ||
879 | |||
880 | /* 229 */ {0x0044, 0x8600}, | ||
881 | /* 230 */ {0x0002, 0x8606}, | ||
882 | /* 231 */ {0x0064, 0x8607}, | ||
883 | /* 232 */ {0x003a, 0x8601}, | ||
884 | /* 233 */ {0x0008, 0x8602}, | ||
885 | /* 234 */ {0x0044, 0x8600}, | ||
886 | /* 235 */ {0x0018, 0x8617}, | ||
887 | /* 236 */ {0x0008, 0x8618}, | ||
888 | /* 237 */ {0x00a1, 0x8656}, | ||
889 | /* 238 */ {0x0004, 0x865b}, | ||
890 | /* 239 */ {0x0002, 0x865c}, | ||
891 | /* 240 */ {0x0058, 0x865d}, | ||
892 | /* 241 */ {0x0048, 0x865e}, | ||
893 | /* 242 */ {0x0012, 0x8608}, | ||
894 | /* 243 */ {0x002c, 0x8609}, | ||
895 | /* 244 */ {0x0002, 0x860a}, | ||
896 | /* 245 */ {0x002c, 0x860b}, | ||
897 | /* 246 */ {0x00db, 0x860c}, | ||
898 | /* 247 */ {0x00f9, 0x860d}, | ||
899 | /* 248 */ {0x00f1, 0x860e}, | ||
900 | /* 249 */ {0x00e3, 0x860f}, | ||
901 | /* 250 */ {0x002c, 0x8610}, | ||
902 | /* 251 */ {0x006c, 0x8651}, | ||
903 | /* 252 */ {0x0041, 0x8652}, | ||
904 | /* 253 */ {0x0059, 0x8653}, | ||
905 | /* 254 */ {0x0040, 0x8654}, | ||
906 | /* 255 */ {0x00fa, 0x8611}, | ||
907 | /* 256 */ {0x00ff, 0x8612}, | ||
908 | /* 257 */ {0x00f8, 0x8613}, | ||
909 | /* 258 */ {0x0000, 0x8614}, | ||
910 | /* 259 */ {0x0001, 0x863f}, | ||
911 | /* 260 */ {0x0000, 0x8640}, | ||
912 | /* 261 */ {0x0026, 0x8641}, | ||
913 | /* 262 */ {0x0045, 0x8642}, | ||
914 | /* 263 */ {0x0060, 0x8643}, | ||
915 | /* 264 */ {0x0075, 0x8644}, | ||
916 | /* 265 */ {0x0088, 0x8645}, | ||
917 | /* 266 */ {0x009b, 0x8646}, | ||
918 | /* 267 */ {0x00b0, 0x8647}, | ||
919 | /* 268 */ {0x00c5, 0x8648}, | ||
920 | /* 269 */ {0x00d2, 0x8649}, | ||
921 | /* 270 */ {0x00dc, 0x864a}, | ||
922 | /* 271 */ {0x00e5, 0x864b}, | ||
923 | /* 272 */ {0x00eb, 0x864c}, | ||
924 | /* 273 */ {0x00f0, 0x864d}, | ||
925 | /* 274 */ {0x00f6, 0x864e}, | ||
926 | /* 275 */ {0x00fa, 0x864f}, | ||
927 | /* 276 */ {0x00ff, 0x8650}, | ||
928 | /* 277 */ {0x0060, 0x8657}, | ||
929 | /* 278 */ {0x0010, 0x8658}, | ||
930 | /* 279 */ {0x0018, 0x8659}, | ||
931 | /* 280 */ {0x0005, 0x865a}, | ||
932 | /* 281 */ {0x0018, 0x8660}, | ||
933 | /* 282 */ {0x0003, 0x8509}, | ||
934 | /* 283 */ {0x0011, 0x850a}, | ||
935 | /* 284 */ {0x0032, 0x850b}, | ||
936 | /* 285 */ {0x0010, 0x850c}, | ||
937 | /* 286 */ {0x0021, 0x850d}, | ||
938 | /* 287 */ {0x0001, 0x8500}, | ||
939 | /* 288 */ {0x0000, 0x8508}, | ||
940 | /* 289 */ {0x0012, 0x8608}, | ||
941 | /* 290 */ {0x002c, 0x8609}, | ||
942 | /* 291 */ {0x0002, 0x860a}, | ||
943 | /* 292 */ {0x0039, 0x860b}, | ||
944 | /* 293 */ {0x00d0, 0x860c}, | ||
945 | /* 294 */ {0x00f7, 0x860d}, | ||
946 | /* 295 */ {0x00ed, 0x860e}, | ||
947 | /* 296 */ {0x00db, 0x860f}, | ||
948 | /* 297 */ {0x0039, 0x8610}, | ||
949 | /* 298 */ {0x0012, 0x8657}, | ||
950 | /* 299 */ {0x000c, 0x8619}, | ||
951 | /* 300 */ {0x0004, 0x861a}, | ||
952 | /* 301 */ {0x00a1, 0x8656}, | ||
953 | /* 302 */ {0x00c8, 0x8615}, | ||
954 | /* 303 */ {0x0032, 0x8616}, | ||
955 | |||
956 | /* 306 */ {0x0030, 0x8112}, | ||
957 | /* 313 */ {0x0020, 0x8112}, | ||
958 | /* 314 */ {0x0020, 0x8112}, | ||
959 | /* 315 */ {0x000f, 0x8402}, | ||
960 | /* 316 */ {0x0000, 0x8403}, | ||
961 | |||
962 | /* 317 */ {0x0090, 0x8110}, | ||
963 | /* 318 */ {0x0001, 0x8114}, | ||
964 | /* 319 */ {0x0001, 0x8114}, | ||
965 | /* 320 */ {0x0001, 0x8114}, | ||
966 | /* 321 */ {0x0003, 0x8114}, | ||
967 | /* 322 */ {0x0080, 0x8804}, | ||
968 | |||
969 | /* 355 */ {0x0003, 0x8801}, | ||
970 | /* 356 */ {0x0012, 0x8800}, | ||
971 | /* 358 */ {0x0004, 0x8801}, | ||
972 | /* 359 */ {0x0005, 0x8800}, | ||
973 | /* 361 */ {0x0005, 0x8801}, | ||
974 | /* 362 */ {0x0047, 0x8800}, | ||
975 | /* 364 */ {0x0006, 0x8801}, | ||
976 | /* 365 */ {0x0000, 0x8800}, | ||
977 | /* 367 */ {0x0007, 0x8801}, | ||
978 | /* 368 */ {0x00c0, 0x8800}, | ||
979 | /* 370 */ {0x0008, 0x8801}, | ||
980 | /* 371 */ {0x0003, 0x8800}, | ||
981 | /* 373 */ {0x000a, 0x8700}, | ||
982 | /* 374 */ {0x000e, 0x8801}, | ||
983 | /* 375 */ {0x0004, 0x8800}, | ||
984 | /* 377 */ {0x0005, 0x8801}, | ||
985 | /* 378 */ {0x0047, 0x8800}, | ||
986 | /* 380 */ {0x0006, 0x8801}, | ||
987 | /* 381 */ {0x0000, 0x8800}, | ||
988 | /* 383 */ {0x0007, 0x8801}, | ||
989 | /* 384 */ {0x00c0, 0x8800}, | ||
990 | /* 386 */ {0x0008, 0x8801}, | ||
991 | /* 387 */ {0x0003, 0x8800}, | ||
992 | /* 389 */ {0x0013, 0x8801}, | ||
993 | /* 390 */ {0x0001, 0x8800}, | ||
994 | /* 392 */ {0x0009, 0x8801}, | ||
995 | /* 393 */ {0x0000, 0x8800}, | ||
996 | /* 395 */ {0x000a, 0x8801}, | ||
997 | /* 396 */ {0x0000, 0x8800}, | ||
998 | /* 398 */ {0x000b, 0x8801}, | ||
999 | /* 399 */ {0x0000, 0x8800}, | ||
1000 | /* 401 */ {0x000c, 0x8801}, | ||
1001 | /* 402 */ {0x0000, 0x8800}, | ||
1002 | /* 404 */ {0x000e, 0x8801}, | ||
1003 | /* 405 */ {0x0004, 0x8800}, | ||
1004 | /* 407 */ {0x000f, 0x8801}, | ||
1005 | /* 408 */ {0x0000, 0x8800}, | ||
1006 | /* 410 */ {0x0010, 0x8801}, | ||
1007 | /* 411 */ {0x0006, 0x8800}, | ||
1008 | /* 413 */ {0x0011, 0x8801}, | ||
1009 | /* 414 */ {0x0006, 0x8800}, | ||
1010 | /* 416 */ {0x0012, 0x8801}, | ||
1011 | /* 417 */ {0x0000, 0x8800}, | ||
1012 | /* 419 */ {0x0013, 0x8801}, | ||
1013 | /* 420 */ {0x0001, 0x8800}, | ||
1014 | /* 422 */ {0x000a, 0x8700}, | ||
1015 | /* 423 */ {0x0000, 0x8702}, | ||
1016 | /* 424 */ {0x0000, 0x8703}, | ||
1017 | /* 425 */ {0x00c2, 0x8704}, | ||
1018 | /* 426 */ {0x0001, 0x870c}, | ||
1019 | /* 427 */ {0x0044, 0x8600}, | ||
1020 | /* 428 */ {0x0002, 0x8606}, | ||
1021 | /* 429 */ {0x0064, 0x8607}, | ||
1022 | /* 430 */ {0x003a, 0x8601}, | ||
1023 | /* 431 */ {0x0008, 0x8602}, | ||
1024 | /* 432 */ {0x0044, 0x8600}, | ||
1025 | /* 433 */ {0x0018, 0x8617}, | ||
1026 | /* 434 */ {0x0008, 0x8618}, | ||
1027 | /* 435 */ {0x00a1, 0x8656}, | ||
1028 | /* 436 */ {0x0004, 0x865b}, | ||
1029 | /* 437 */ {0x0002, 0x865c}, | ||
1030 | /* 438 */ {0x0058, 0x865d}, | ||
1031 | /* 439 */ {0x0048, 0x865e}, | ||
1032 | /* 440 */ {0x0012, 0x8608}, | ||
1033 | /* 441 */ {0x002c, 0x8609}, | ||
1034 | /* 442 */ {0x0002, 0x860a}, | ||
1035 | /* 443 */ {0x002c, 0x860b}, | ||
1036 | /* 444 */ {0x00db, 0x860c}, | ||
1037 | /* 445 */ {0x00f9, 0x860d}, | ||
1038 | /* 446 */ {0x00f1, 0x860e}, | ||
1039 | /* 447 */ {0x00e3, 0x860f}, | ||
1040 | /* 448 */ {0x002c, 0x8610}, | ||
1041 | /* 449 */ {0x006c, 0x8651}, | ||
1042 | /* 450 */ {0x0041, 0x8652}, | ||
1043 | /* 451 */ {0x0059, 0x8653}, | ||
1044 | /* 452 */ {0x0040, 0x8654}, | ||
1045 | /* 453 */ {0x00fa, 0x8611}, | ||
1046 | /* 454 */ {0x00ff, 0x8612}, | ||
1047 | /* 455 */ {0x00f8, 0x8613}, | ||
1048 | /* 456 */ {0x0000, 0x8614}, | ||
1049 | /* 457 */ {0x0001, 0x863f}, | ||
1050 | /* 458 */ {0x0000, 0x8640}, | ||
1051 | /* 459 */ {0x0026, 0x8641}, | ||
1052 | /* 460 */ {0x0045, 0x8642}, | ||
1053 | /* 461 */ {0x0060, 0x8643}, | ||
1054 | /* 462 */ {0x0075, 0x8644}, | ||
1055 | /* 463 */ {0x0088, 0x8645}, | ||
1056 | /* 464 */ {0x009b, 0x8646}, | ||
1057 | /* 465 */ {0x00b0, 0x8647}, | ||
1058 | /* 466 */ {0x00c5, 0x8648}, | ||
1059 | /* 467 */ {0x00d2, 0x8649}, | ||
1060 | /* 468 */ {0x00dc, 0x864a}, | ||
1061 | /* 469 */ {0x00e5, 0x864b}, | ||
1062 | /* 470 */ {0x00eb, 0x864c}, | ||
1063 | /* 471 */ {0x00f0, 0x864d}, | ||
1064 | /* 472 */ {0x00f6, 0x864e}, | ||
1065 | /* 473 */ {0x00fa, 0x864f}, | ||
1066 | /* 474 */ {0x00ff, 0x8650}, | ||
1067 | /* 475 */ {0x0060, 0x8657}, | ||
1068 | /* 476 */ {0x0010, 0x8658}, | ||
1069 | /* 477 */ {0x0018, 0x8659}, | ||
1070 | /* 478 */ {0x0005, 0x865a}, | ||
1071 | /* 479 */ {0x0018, 0x8660}, | ||
1072 | /* 480 */ {0x0003, 0x8509}, | ||
1073 | /* 481 */ {0x0011, 0x850a}, | ||
1074 | /* 482 */ {0x0032, 0x850b}, | ||
1075 | /* 483 */ {0x0010, 0x850c}, | ||
1076 | /* 484 */ {0x0021, 0x850d}, | ||
1077 | /* 485 */ {0x0001, 0x8500}, | ||
1078 | /* 486 */ {0x0000, 0x8508}, | ||
1079 | |||
1080 | /* 487 */ {0x0012, 0x8608}, | ||
1081 | /* 488 */ {0x002c, 0x8609}, | ||
1082 | /* 489 */ {0x0002, 0x860a}, | ||
1083 | /* 490 */ {0x0039, 0x860b}, | ||
1084 | /* 491 */ {0x00d0, 0x860c}, | ||
1085 | /* 492 */ {0x00f7, 0x860d}, | ||
1086 | /* 493 */ {0x00ed, 0x860e}, | ||
1087 | /* 494 */ {0x00db, 0x860f}, | ||
1088 | /* 495 */ {0x0039, 0x8610}, | ||
1089 | /* 496 */ {0x0012, 0x8657}, | ||
1090 | /* 497 */ {0x0064, 0x8619}, | ||
1091 | |||
1092 | /* This line starts it all, it is not needed here */ | ||
1093 | /* since it has been build into the driver */ | ||
1094 | /* jfm: don't start now */ | ||
1095 | /* 590 * {0x0030, 0x8112}, */ | ||
1096 | {} | ||
1097 | }; | ||
1098 | |||
1099 | /* | ||
1100 | * Initialization data for Creative Webcam Vista | ||
1101 | */ | ||
1102 | static __u16 spca508_vista_init_data[][3] = { | ||
1103 | {0x0008, 0x8200}, /* Clear register */ | ||
1104 | {0x0000, 0x870b}, /* Reset CTL3 */ | ||
1105 | {0x0020, 0x8112}, /* Video Drop packet enable */ | ||
1106 | {0x0003, 0x8111}, /* Soft Reset compression, memory, TG & CDSP */ | ||
1107 | {0x0000, 0x8110}, /* Disable everything */ | ||
1108 | {0x0000, 0x8114}, /* Software GPIO output data */ | ||
1109 | {0x0000, 0x8114}, | ||
1110 | |||
1111 | {0x0003, 0x8111}, | ||
1112 | {0x0000, 0x8111}, | ||
1113 | {0x0090, 0x8110}, /* Enable: SSI output, External 2X clock output */ | ||
1114 | {0x0020, 0x8112}, | ||
1115 | {0x0000, 0x8114}, | ||
1116 | {0x0001, 0x8114}, | ||
1117 | {0x0001, 0x8114}, | ||
1118 | {0x0001, 0x8114}, | ||
1119 | {0x0003, 0x8114}, | ||
1120 | |||
1121 | {0x000f, 0x8402}, /* Memory bank Address */ | ||
1122 | {0x0000, 0x8403}, /* Memory bank Address */ | ||
1123 | {0x00ba, 0x8804}, /* SSI Slave address */ | ||
1124 | {0x0010, 0x8802}, /* 93.75kHz SSI Clock Two DataByte */ | ||
1125 | |||
1126 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1127 | 0000: 00 */ | ||
1128 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1129 | 0000: 10 */ | ||
1130 | {0x0010, 0x8802}, /* Will write 2 bytes (DATA1+DATA2) */ | ||
1131 | {0x0020, 0x8801}, /* Register address for SSI read/write */ | ||
1132 | {0x0044, 0x8805}, /* DATA2 */ | ||
1133 | {0x0004, 0x8800}, /* DATA1 -> write triggered */ | ||
1134 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1135 | 0000: 00 */ | ||
1136 | |||
1137 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1138 | 0000: 00 */ | ||
1139 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1140 | 0000: 10 */ | ||
1141 | {0x0010, 0x8802}, | ||
1142 | {0x0009, 0x8801}, | ||
1143 | {0x0042, 0x8805}, | ||
1144 | {0x0001, 0x8800}, | ||
1145 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1146 | 0000: 00 */ | ||
1147 | |||
1148 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1149 | 0000: 00 */ | ||
1150 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1151 | 0000: 10 */ | ||
1152 | {0x0010, 0x8802}, | ||
1153 | {0x003c, 0x8801}, | ||
1154 | {0x0001, 0x8805}, | ||
1155 | {0x0000, 0x8800}, | ||
1156 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1157 | 0000: 00 */ | ||
1158 | |||
1159 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1160 | 0000: 00 */ | ||
1161 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1162 | 0000: 10 */ | ||
1163 | {0x0010, 0x8802}, | ||
1164 | {0x0001, 0x8801}, | ||
1165 | {0x000a, 0x8805}, | ||
1166 | {0x0000, 0x8800}, | ||
1167 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1168 | 0000: 00 */ | ||
1169 | |||
1170 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1171 | 0000: 00 */ | ||
1172 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1173 | 0000: 10 */ | ||
1174 | {0x0010, 0x8802}, | ||
1175 | {0x0002, 0x8801}, | ||
1176 | {0x0000, 0x8805}, | ||
1177 | {0x0000, 0x8800}, | ||
1178 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1179 | 0000: 00 */ | ||
1180 | |||
1181 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1182 | 0000: 00 */ | ||
1183 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1184 | 0000: 10 */ | ||
1185 | {0x0010, 0x8802}, | ||
1186 | {0x0003, 0x8801}, | ||
1187 | {0x0027, 0x8805}, | ||
1188 | {0x0001, 0x8800}, | ||
1189 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1190 | 0000: 00 */ | ||
1191 | |||
1192 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1193 | 0000: 00 */ | ||
1194 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1195 | 0000: 10 */ | ||
1196 | {0x0010, 0x8802}, | ||
1197 | {0x0004, 0x8801}, | ||
1198 | {0x0065, 0x8805}, | ||
1199 | {0x0001, 0x8800}, | ||
1200 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1201 | 0000: 00 */ | ||
1202 | |||
1203 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1204 | 0000: 00 */ | ||
1205 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1206 | 0000: 10 */ | ||
1207 | {0x0010, 0x8802}, | ||
1208 | {0x0005, 0x8801}, | ||
1209 | {0x0003, 0x8805}, | ||
1210 | {0x0000, 0x8800}, | ||
1211 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1212 | 0000: 00 */ | ||
1213 | |||
1214 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1215 | 0000: 00 */ | ||
1216 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1217 | 0000: 10 */ | ||
1218 | {0x0010, 0x8802}, | ||
1219 | {0x0006, 0x8801}, | ||
1220 | {0x001c, 0x8805}, | ||
1221 | {0x0000, 0x8800}, | ||
1222 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1223 | 0000: 00 */ | ||
1224 | |||
1225 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1226 | 0000: 00 */ | ||
1227 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1228 | 0000: 10 */ | ||
1229 | {0x0010, 0x8802}, | ||
1230 | {0x0007, 0x8801}, | ||
1231 | {0x002a, 0x8805}, | ||
1232 | {0x0000, 0x8800}, | ||
1233 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1234 | 0000: 00 */ | ||
1235 | |||
1236 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1237 | 0000: 00 */ | ||
1238 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1239 | 0000: 10 */ | ||
1240 | {0x0010, 0x8802}, | ||
1241 | {0x000e, 0x8801}, | ||
1242 | {0x0000, 0x8805}, | ||
1243 | {0x0000, 0x8800}, | ||
1244 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1245 | 0000: 00 */ | ||
1246 | |||
1247 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1248 | 0000: 00 */ | ||
1249 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1250 | 0000: 10 */ | ||
1251 | {0x0010, 0x8802}, | ||
1252 | {0x0028, 0x8801}, | ||
1253 | {0x002e, 0x8805}, | ||
1254 | {0x0000, 0x8800}, | ||
1255 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1256 | 0000: 00 */ | ||
1257 | |||
1258 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1259 | 0000: 00 */ | ||
1260 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1261 | 0000: 10 */ | ||
1262 | {0x0010, 0x8802}, | ||
1263 | {0x0039, 0x8801}, | ||
1264 | {0x0013, 0x8805}, | ||
1265 | {0x0000, 0x8800}, | ||
1266 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1267 | 0000: 00 */ | ||
1268 | |||
1269 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1270 | 0000: 00 */ | ||
1271 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1272 | 0000: 10 */ | ||
1273 | {0x0010, 0x8802}, | ||
1274 | {0x003b, 0x8801}, | ||
1275 | {0x000c, 0x8805}, | ||
1276 | {0x0000, 0x8800}, | ||
1277 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1278 | 0000: 00 */ | ||
1279 | |||
1280 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1281 | 0000: 00 */ | ||
1282 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1283 | 0000: 10 */ | ||
1284 | {0x0010, 0x8802}, | ||
1285 | {0x0035, 0x8801}, | ||
1286 | {0x0028, 0x8805}, | ||
1287 | {0x0000, 0x8800}, | ||
1288 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1289 | 0000: 00 */ | ||
1290 | |||
1291 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1292 | 0000: 00 */ | ||
1293 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1294 | 0000: 10 */ | ||
1295 | {0x0010, 0x8802}, | ||
1296 | {0x0009, 0x8801}, | ||
1297 | {0x0042, 0x8805}, | ||
1298 | {0x0001, 0x8800}, | ||
1299 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1300 | 0000: 00 */ | ||
1301 | |||
1302 | {0x0050, 0x8703}, | ||
1303 | {0x0002, 0x8704}, /* External input CKIx1 */ | ||
1304 | {0x0001, 0x870C}, /* Select CKOx2 output */ | ||
1305 | {0x009A, 0x8600}, /* Line memory Read Counter (L) */ | ||
1306 | {0x0001, 0x8606}, /* 1 Line memory Read Counter (H) Result: (d)410 */ | ||
1307 | {0x0023, 0x8601}, | ||
1308 | {0x0010, 0x8602}, | ||
1309 | {0x000A, 0x8603}, | ||
1310 | {0x009A, 0x8600}, | ||
1311 | {0x0001, 0x865B}, /* 1 Horizontal Offset for Valid Pixel(L) */ | ||
1312 | {0x0003, 0x865C}, /* Vertical offset for valid lines (L) */ | ||
1313 | {0x0058, 0x865D}, /* Horizontal valid pixels window (L) */ | ||
1314 | {0x0048, 0x865E}, /* Vertical valid lines window (L) */ | ||
1315 | {0x0000, 0x865F}, | ||
1316 | |||
1317 | {0x0006, 0x8660}, | ||
1318 | /* Enable nibble data input, select nibble input order */ | ||
1319 | |||
1320 | {0x0013, 0x8608}, /* A11 Coeficients for color correction */ | ||
1321 | {0x0028, 0x8609}, | ||
1322 | /* Note: these values are confirmed at the end of array */ | ||
1323 | {0x0005, 0x860A}, /* ... */ | ||
1324 | {0x0025, 0x860B}, | ||
1325 | {0x00E1, 0x860C}, | ||
1326 | {0x00FA, 0x860D}, | ||
1327 | {0x00F4, 0x860E}, | ||
1328 | {0x00E8, 0x860F}, | ||
1329 | {0x0025, 0x8610}, /* A33 Coef. */ | ||
1330 | {0x00FC, 0x8611}, /* White balance offset: R */ | ||
1331 | {0x0001, 0x8612}, /* White balance offset: Gr */ | ||
1332 | {0x00FE, 0x8613}, /* White balance offset: B */ | ||
1333 | {0x0000, 0x8614}, /* White balance offset: Gb */ | ||
1334 | |||
1335 | {0x0064, 0x8651}, /* R gain for white balance (L) */ | ||
1336 | {0x0040, 0x8652}, /* Gr gain for white balance (L) */ | ||
1337 | {0x0066, 0x8653}, /* B gain for white balance (L) */ | ||
1338 | {0x0040, 0x8654}, /* Gb gain for white balance (L) */ | ||
1339 | {0x0001, 0x863F}, /* Enable fixed gamma correction */ | ||
1340 | |||
1341 | {0x00A1, 0x8656}, /* Size - Window1: 256x256, Window2: 128x128 */ | ||
1342 | /* UV division: UV no change, Enable New edge enhancement */ | ||
1343 | {0x0018, 0x8657}, /* Edge gain high threshold */ | ||
1344 | {0x0020, 0x8658}, /* Edge gain low threshold */ | ||
1345 | {0x000A, 0x8659}, /* Edge bandwidth high threshold */ | ||
1346 | {0x0005, 0x865A}, /* Edge bandwidth low threshold */ | ||
1347 | {0x0064, 0x8607}, /* UV filter enable */ | ||
1348 | |||
1349 | {0x0016, 0x8660}, | ||
1350 | {0x0000, 0x86B0}, /* Bad pixels compensation address */ | ||
1351 | {0x00DC, 0x86B1}, /* X coord for bad pixels compensation (L) */ | ||
1352 | {0x0000, 0x86B2}, | ||
1353 | {0x0009, 0x86B3}, /* Y coord for bad pixels compensation (L) */ | ||
1354 | {0x0000, 0x86B4}, | ||
1355 | |||
1356 | {0x0001, 0x86B0}, | ||
1357 | {0x00F5, 0x86B1}, | ||
1358 | {0x0000, 0x86B2}, | ||
1359 | {0x00C6, 0x86B3}, | ||
1360 | {0x0000, 0x86B4}, | ||
1361 | |||
1362 | {0x0002, 0x86B0}, | ||
1363 | {0x001C, 0x86B1}, | ||
1364 | {0x0001, 0x86B2}, | ||
1365 | {0x00D7, 0x86B3}, | ||
1366 | {0x0000, 0x86B4}, | ||
1367 | |||
1368 | {0x0003, 0x86B0}, | ||
1369 | {0x001C, 0x86B1}, | ||
1370 | {0x0001, 0x86B2}, | ||
1371 | {0x00D8, 0x86B3}, | ||
1372 | {0x0000, 0x86B4}, | ||
1373 | |||
1374 | {0x0004, 0x86B0}, | ||
1375 | {0x001D, 0x86B1}, | ||
1376 | {0x0001, 0x86B2}, | ||
1377 | {0x00D8, 0x86B3}, | ||
1378 | {0x0000, 0x86B4}, | ||
1379 | {0x001E, 0x8660}, | ||
1380 | |||
1381 | /* READ { 0, 0x0000, 0x8608 } -> | ||
1382 | 0000: 13 */ | ||
1383 | /* READ { 0, 0x0000, 0x8609 } -> | ||
1384 | 0000: 28 */ | ||
1385 | /* READ { 0, 0x0000, 0x8610 } -> | ||
1386 | 0000: 05 */ | ||
1387 | /* READ { 0, 0x0000, 0x8611 } -> | ||
1388 | 0000: 25 */ | ||
1389 | /* READ { 0, 0x0000, 0x8612 } -> | ||
1390 | 0000: e1 */ | ||
1391 | /* READ { 0, 0x0000, 0x8613 } -> | ||
1392 | 0000: fa */ | ||
1393 | /* READ { 0, 0x0000, 0x8614 } -> | ||
1394 | 0000: f4 */ | ||
1395 | /* READ { 0, 0x0000, 0x8615 } -> | ||
1396 | 0000: e8 */ | ||
1397 | /* READ { 0, 0x0000, 0x8616 } -> | ||
1398 | 0000: 25 */ | ||
1399 | {} | ||
1400 | }; | ||
1401 | |||
1402 | static int reg_write(struct usb_device *dev, | ||
1403 | __u16 index, __u16 value) | ||
1404 | { | ||
1405 | int ret; | ||
1406 | |||
1407 | ret = usb_control_msg(dev, | ||
1408 | usb_sndctrlpipe(dev, 0), | ||
1409 | 0, /* request */ | ||
1410 | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
1411 | value, index, NULL, 0, 500); | ||
1412 | PDEBUG(D_USBO, "reg write i:0x%04x = 0x%02x", | ||
1413 | index, value); | ||
1414 | if (ret < 0) | ||
1415 | PDEBUG(D_ERR|D_USBO, "reg write: error %d", ret); | ||
1416 | return ret; | ||
1417 | } | ||
1418 | |||
1419 | /* read 1 byte */ | ||
1420 | /* returns: negative is error, pos or zero is data */ | ||
1421 | static int reg_read(struct usb_device *dev, | ||
1422 | __u16 index) /* wIndex */ | ||
1423 | { | ||
1424 | int ret; | ||
1425 | __u8 data; | ||
1426 | |||
1427 | ret = usb_control_msg(dev, | ||
1428 | usb_rcvctrlpipe(dev, 0), | ||
1429 | 0, /* register */ | ||
1430 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
1431 | (__u16) 0, /* value */ | ||
1432 | index, | ||
1433 | &data, 1, | ||
1434 | 500); /* timeout */ | ||
1435 | PDEBUG(D_USBI, "reg read i:%04x --> %02x", index, data); | ||
1436 | if (ret < 0) { | ||
1437 | PDEBUG(D_ERR|D_USBI, "reg_read err %d", ret); | ||
1438 | return ret; | ||
1439 | } | ||
1440 | return data; | ||
1441 | } | ||
1442 | |||
1443 | static int write_vector(struct gspca_dev *gspca_dev, | ||
1444 | __u16 data[][3]) | ||
1445 | { | ||
1446 | struct usb_device *dev = gspca_dev->dev; | ||
1447 | int ret, i = 0; | ||
1448 | |||
1449 | while (data[i][1] != 0) { | ||
1450 | ret = reg_write(dev, data[i][1], data[i][0]); | ||
1451 | if (ret < 0) | ||
1452 | return ret; | ||
1453 | i++; | ||
1454 | } | ||
1455 | return 0; | ||
1456 | } | ||
1457 | |||
1458 | /* this function is called at probe time */ | ||
1459 | static int sd_config(struct gspca_dev *gspca_dev, | ||
1460 | const struct usb_device_id *id) | ||
1461 | { | ||
1462 | struct sd *sd = (struct sd *) gspca_dev; | ||
1463 | struct usb_device *dev = gspca_dev->dev; | ||
1464 | struct cam *cam; | ||
1465 | __u16 vendor; | ||
1466 | __u16 product; | ||
1467 | int data1, data2; | ||
1468 | |||
1469 | vendor = id->idVendor; | ||
1470 | product = id->idProduct; | ||
1471 | switch (vendor) { | ||
1472 | case 0x041e: /* Creative cameras */ | ||
1473 | /* switch (product) { */ | ||
1474 | /* case 0x4018: */ | ||
1475 | sd->subtype = CreativeVista; | ||
1476 | /* break; */ | ||
1477 | /* } */ | ||
1478 | break; | ||
1479 | case 0x0461: /* MicroInnovation */ | ||
1480 | /* switch (product) { */ | ||
1481 | /* case 0x0815: */ | ||
1482 | sd->subtype = MicroInnovationIC200; | ||
1483 | /* break; */ | ||
1484 | /* } */ | ||
1485 | break; | ||
1486 | case 0x0733: /* Rebadged ViewQuest (Intel) and ViewQuest cameras */ | ||
1487 | /* switch (product) { */ | ||
1488 | /* case 0x110: */ | ||
1489 | sd->subtype = ViewQuestVQ110; | ||
1490 | /* break; */ | ||
1491 | /* } */ | ||
1492 | break; | ||
1493 | case 0x0af9: /* Hama cameras */ | ||
1494 | switch (product) { | ||
1495 | case 0x0010: | ||
1496 | sd->subtype = HamaUSBSightcam; | ||
1497 | break; | ||
1498 | case 0x0011: | ||
1499 | sd->subtype = HamaUSBSightcam2; | ||
1500 | break; | ||
1501 | } | ||
1502 | break; | ||
1503 | case 0x8086: /* Intel */ | ||
1504 | /* switch (product) { */ | ||
1505 | /* case 0x0110: */ | ||
1506 | sd->subtype = IntelEasyPCCamera; | ||
1507 | /* break; */ | ||
1508 | /* } */ | ||
1509 | break; | ||
1510 | } | ||
1511 | |||
1512 | /* Read from global register the USB product and vendor IDs, just to */ | ||
1513 | /* prove that we can communicate with the device. This works, which */ | ||
1514 | /* confirms at we are communicating properly and that the device */ | ||
1515 | /* is a 508. */ | ||
1516 | data1 = reg_read(dev, 0x8104); | ||
1517 | data2 = reg_read(dev, 0x8105); | ||
1518 | PDEBUG(D_PROBE, | ||
1519 | "Read from GLOBAL: USB Vendor ID 0x%02x%02x", data2, data1); | ||
1520 | |||
1521 | data1 = reg_read(dev, 0x8106); | ||
1522 | data2 = reg_read(dev, 0x8107); | ||
1523 | PDEBUG(D_PROBE, | ||
1524 | "Read from GLOBAL: USB Product ID 0x%02x%02x", data2, data1); | ||
1525 | |||
1526 | data1 = reg_read(dev, 0x8621); | ||
1527 | PDEBUG(D_PROBE, | ||
1528 | "Read from GLOBAL: Window 1 average luminance %d", data1); | ||
1529 | |||
1530 | cam = &gspca_dev->cam; | ||
1531 | cam->dev_name = (char *) id->driver_info; | ||
1532 | cam->epaddr = 0x01; | ||
1533 | cam->cam_mode = sif_mode; | ||
1534 | cam->nmodes = sizeof sif_mode / sizeof sif_mode[0]; | ||
1535 | sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; | ||
1536 | |||
1537 | switch (sd->subtype) { | ||
1538 | case ViewQuestVQ110: | ||
1539 | if (write_vector(gspca_dev, spca508_init_data)) | ||
1540 | return -1; | ||
1541 | break; | ||
1542 | default: | ||
1543 | /* case MicroInnovationIC200: */ | ||
1544 | /* case IntelEasyPCCamera: */ | ||
1545 | if (write_vector(gspca_dev, spca508cs110_init_data)) | ||
1546 | return -1; | ||
1547 | break; | ||
1548 | case HamaUSBSightcam: | ||
1549 | if (write_vector(gspca_dev, spca508_sightcam_init_data)) | ||
1550 | return -1; | ||
1551 | break; | ||
1552 | case HamaUSBSightcam2: | ||
1553 | if (write_vector(gspca_dev, spca508_sightcam2_init_data)) | ||
1554 | return -1; | ||
1555 | break; | ||
1556 | case CreativeVista: | ||
1557 | if (write_vector(gspca_dev, spca508_vista_init_data)) | ||
1558 | return -1; | ||
1559 | break; | ||
1560 | } | ||
1561 | return 0; /* success */ | ||
1562 | } | ||
1563 | |||
1564 | /* this function is called at open time */ | ||
1565 | static int sd_open(struct gspca_dev *gspca_dev) | ||
1566 | { | ||
1567 | /* write_vector(gspca_dev, spca508_open_data); */ | ||
1568 | return 0; | ||
1569 | } | ||
1570 | |||
1571 | static void sd_start(struct gspca_dev *gspca_dev) | ||
1572 | { | ||
1573 | int mode; | ||
1574 | |||
1575 | mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode; | ||
1576 | reg_write(gspca_dev->dev, 0x8500, mode); | ||
1577 | switch (mode) { | ||
1578 | case 0: | ||
1579 | case 1: | ||
1580 | reg_write(gspca_dev->dev, 0x8700, 0x28); /* clock */ | ||
1581 | break; | ||
1582 | default: | ||
1583 | /* case 2: */ | ||
1584 | /* case 3: */ | ||
1585 | reg_write(gspca_dev->dev, 0x8700, 0x23); /* clock */ | ||
1586 | break; | ||
1587 | } | ||
1588 | reg_write(gspca_dev->dev, 0x8112, 0x10 | 0x20); | ||
1589 | } | ||
1590 | |||
1591 | static void sd_stopN(struct gspca_dev *gspca_dev) | ||
1592 | { | ||
1593 | /* Video ISO disable, Video Drop Packet enable: */ | ||
1594 | reg_write(gspca_dev->dev, 0x8112, 0x20); | ||
1595 | } | ||
1596 | |||
1597 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
1598 | { | ||
1599 | } | ||
1600 | |||
1601 | /* this function is called at close time */ | ||
1602 | static void sd_close(struct gspca_dev *gspca_dev) | ||
1603 | { | ||
1604 | } | ||
1605 | |||
1606 | /* convert YUVY per line to YUYV (YUV 4:2:2) */ | ||
1607 | static void yuvy_decode(unsigned char *out, | ||
1608 | unsigned char *in, | ||
1609 | int width, | ||
1610 | int height) | ||
1611 | { | ||
1612 | unsigned char *Ui, *Vi, *yi, *yi1; | ||
1613 | unsigned char *out1; | ||
1614 | int i, j; | ||
1615 | |||
1616 | yi = in; | ||
1617 | for (i = height / 2; --i >= 0; ) { | ||
1618 | out1 = out + width * 2; /* next line */ | ||
1619 | Ui = yi + width; | ||
1620 | Vi = Ui + width / 2; | ||
1621 | yi1 = Vi + width / 2; | ||
1622 | for (j = width / 2; --j >= 0; ) { | ||
1623 | *out++ = 128 + *yi++; | ||
1624 | *out++ = 128 + *Ui; | ||
1625 | *out++ = 128 + *yi++; | ||
1626 | *out++ = 128 + *Vi; | ||
1627 | |||
1628 | *out1++ = 128 + *yi1++; | ||
1629 | *out1++ = 128 + *Ui++; | ||
1630 | *out1++ = 128 + *yi1++; | ||
1631 | *out1++ = 128 + *Vi++; | ||
1632 | } | ||
1633 | yi += width * 2; | ||
1634 | out = out1; | ||
1635 | } | ||
1636 | } | ||
1637 | |||
1638 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | ||
1639 | struct gspca_frame *frame, /* target */ | ||
1640 | unsigned char *data, /* isoc packet */ | ||
1641 | int len) /* iso packet length */ | ||
1642 | { | ||
1643 | struct sd *sd = (struct sd *) gspca_dev; | ||
1644 | |||
1645 | switch (data[0]) { | ||
1646 | case 0: /* start of frame */ | ||
1647 | if (gspca_dev->last_packet_type == FIRST_PACKET) { | ||
1648 | yuvy_decode(sd->tmpbuf2, sd->tmpbuf, | ||
1649 | gspca_dev->width, | ||
1650 | gspca_dev->height); | ||
1651 | frame = gspca_frame_add(gspca_dev, | ||
1652 | LAST_PACKET, | ||
1653 | frame, | ||
1654 | sd->tmpbuf2, | ||
1655 | gspca_dev->width | ||
1656 | * gspca_dev->height | ||
1657 | * 2); | ||
1658 | } | ||
1659 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, | ||
1660 | data, 0); | ||
1661 | data += SPCA508_OFFSET_DATA; | ||
1662 | len -= SPCA508_OFFSET_DATA; | ||
1663 | if (len > 0) | ||
1664 | memcpy(sd->tmpbuf, data, len); | ||
1665 | else | ||
1666 | len = 0; | ||
1667 | sd->buflen = len; | ||
1668 | return; | ||
1669 | case 0xff: /* drop */ | ||
1670 | /* gspca_dev->last_packet_type = DISCARD_PACKET; */ | ||
1671 | return; | ||
1672 | } | ||
1673 | data += 1; | ||
1674 | len -= 1; | ||
1675 | memcpy(&sd->tmpbuf[sd->buflen], data, len); | ||
1676 | sd->buflen += len; | ||
1677 | } | ||
1678 | |||
1679 | static void setbrightness(struct gspca_dev *gspca_dev) | ||
1680 | { | ||
1681 | struct sd *sd = (struct sd *) gspca_dev; | ||
1682 | __u8 brightness = sd->brightness; | ||
1683 | |||
1684 | /* MX seem contrast */ | ||
1685 | reg_write(gspca_dev->dev, 0x8651, brightness); | ||
1686 | reg_write(gspca_dev->dev, 0x8652, brightness); | ||
1687 | reg_write(gspca_dev->dev, 0x8653, brightness); | ||
1688 | reg_write(gspca_dev->dev, 0x8654, brightness); | ||
1689 | } | ||
1690 | |||
1691 | static void getbrightness(struct gspca_dev *gspca_dev) | ||
1692 | { | ||
1693 | struct sd *sd = (struct sd *) gspca_dev; | ||
1694 | |||
1695 | sd->brightness = reg_read(gspca_dev->dev, 0x8651); | ||
1696 | } | ||
1697 | |||
1698 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | ||
1699 | { | ||
1700 | struct sd *sd = (struct sd *) gspca_dev; | ||
1701 | |||
1702 | sd->brightness = val; | ||
1703 | if (gspca_dev->streaming) | ||
1704 | setbrightness(gspca_dev); | ||
1705 | return 0; | ||
1706 | } | ||
1707 | |||
1708 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
1709 | { | ||
1710 | struct sd *sd = (struct sd *) gspca_dev; | ||
1711 | |||
1712 | getbrightness(gspca_dev); | ||
1713 | *val = sd->brightness; | ||
1714 | return 0; | ||
1715 | } | ||
1716 | |||
1717 | /* sub-driver description */ | ||
1718 | static struct sd_desc sd_desc = { | ||
1719 | .name = MODULE_NAME, | ||
1720 | .ctrls = sd_ctrls, | ||
1721 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
1722 | .config = sd_config, | ||
1723 | .open = sd_open, | ||
1724 | .start = sd_start, | ||
1725 | .stopN = sd_stopN, | ||
1726 | .stop0 = sd_stop0, | ||
1727 | .close = sd_close, | ||
1728 | .pkt_scan = sd_pkt_scan, | ||
1729 | }; | ||
1730 | |||
1731 | /* -- module initialisation -- */ | ||
1732 | #define DVNM(name) .driver_info = (kernel_ulong_t) name | ||
1733 | static __devinitdata struct usb_device_id device_table[] = { | ||
1734 | {USB_DEVICE(0x041e, 0x4018), DVNM("Creative Webcam Vista (PD1100)")}, | ||
1735 | {USB_DEVICE(0x0461, 0x0815), DVNM("Micro Innovation IC200")}, | ||
1736 | {USB_DEVICE(0x0733, 0x0110), DVNM("ViewQuest VQ110")}, | ||
1737 | {USB_DEVICE(0x0af9, 0x0010), DVNM("Hama USB Sightcam 100")}, | ||
1738 | {USB_DEVICE(0x0af9, 0x0011), DVNM("Hama USB Sightcam 100")}, | ||
1739 | {USB_DEVICE(0x8086, 0x0110), DVNM("Intel Easy PC Camera")}, | ||
1740 | {} | ||
1741 | }; | ||
1742 | MODULE_DEVICE_TABLE(usb, device_table); | ||
1743 | |||
1744 | /* -- device connect -- */ | ||
1745 | static int sd_probe(struct usb_interface *intf, | ||
1746 | const struct usb_device_id *id) | ||
1747 | { | ||
1748 | return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), | ||
1749 | THIS_MODULE); | ||
1750 | } | ||
1751 | |||
1752 | static struct usb_driver sd_driver = { | ||
1753 | .name = MODULE_NAME, | ||
1754 | .id_table = device_table, | ||
1755 | .probe = sd_probe, | ||
1756 | .disconnect = gspca_disconnect, | ||
1757 | }; | ||
1758 | |||
1759 | /* -- module insert / remove -- */ | ||
1760 | static int __init sd_mod_init(void) | ||
1761 | { | ||
1762 | if (usb_register(&sd_driver) < 0) | ||
1763 | return -1; | ||
1764 | PDEBUG(D_PROBE, "v%s registered", version); | ||
1765 | return 0; | ||
1766 | } | ||
1767 | static void __exit sd_mod_exit(void) | ||
1768 | { | ||
1769 | usb_deregister(&sd_driver); | ||
1770 | PDEBUG(D_PROBE, "deregistered"); | ||
1771 | } | ||
1772 | |||
1773 | module_init(sd_mod_init); | ||
1774 | module_exit(sd_mod_exit); | ||
diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c new file mode 100644 index 000000000000..a94e6270115e --- /dev/null +++ b/drivers/media/video/gspca/spca561.c | |||
@@ -0,0 +1,1025 @@ | |||
1 | /* | ||
2 | * Sunplus spca561 subdriver | ||
3 | * | ||
4 | * Copyright (C) 2004 Michel Xhaard mxhaard@magic.fr | ||
5 | * | ||
6 | * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
21 | */ | ||
22 | |||
23 | #define MODULE_NAME "spca561" | ||
24 | |||
25 | #include "gspca.h" | ||
26 | |||
27 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) | ||
28 | static const char version[] = "2.1.0"; | ||
29 | |||
30 | MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); | ||
31 | MODULE_DESCRIPTION("GSPCA/SPCA561 USB Camera Driver"); | ||
32 | MODULE_LICENSE("GPL"); | ||
33 | |||
34 | /* specific webcam descriptor */ | ||
35 | struct sd { | ||
36 | struct gspca_dev gspca_dev; /* !! must be the first item */ | ||
37 | |||
38 | unsigned short contrast; | ||
39 | __u8 brightness; | ||
40 | __u8 autogain; | ||
41 | |||
42 | __u8 chip_revision; | ||
43 | signed char ag_cnt; | ||
44 | #define AG_CNT_START 13 | ||
45 | }; | ||
46 | |||
47 | /* V4L2 controls supported by the driver */ | ||
48 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
49 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
50 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | ||
51 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | ||
52 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); | ||
53 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); | ||
54 | |||
55 | static struct ctrl sd_ctrls[] = { | ||
56 | #define SD_BRIGHTNESS 0 | ||
57 | { | ||
58 | { | ||
59 | .id = V4L2_CID_BRIGHTNESS, | ||
60 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
61 | .name = "Brightness", | ||
62 | .minimum = 0, | ||
63 | .maximum = 63, | ||
64 | .step = 1, | ||
65 | .default_value = 32, | ||
66 | }, | ||
67 | .set = sd_setbrightness, | ||
68 | .get = sd_getbrightness, | ||
69 | }, | ||
70 | #define SD_CONTRAST 1 | ||
71 | { | ||
72 | { | ||
73 | .id = V4L2_CID_CONTRAST, | ||
74 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
75 | .name = "Contrast", | ||
76 | .minimum = 0, | ||
77 | .maximum = 0x3fff, | ||
78 | .step = 1, | ||
79 | .default_value = 0x2000, | ||
80 | }, | ||
81 | .set = sd_setcontrast, | ||
82 | .get = sd_getcontrast, | ||
83 | }, | ||
84 | #define SD_AUTOGAIN 2 | ||
85 | { | ||
86 | { | ||
87 | .id = V4L2_CID_AUTOGAIN, | ||
88 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
89 | .name = "Auto Gain", | ||
90 | .minimum = 0, | ||
91 | .maximum = 1, | ||
92 | .step = 1, | ||
93 | .default_value = 1, | ||
94 | }, | ||
95 | .set = sd_setautogain, | ||
96 | .get = sd_getautogain, | ||
97 | }, | ||
98 | }; | ||
99 | |||
100 | static struct cam_mode sif_mode[] = { | ||
101 | {V4L2_PIX_FMT_SPCA561, 160, 120, 3}, | ||
102 | {V4L2_PIX_FMT_SPCA561, 176, 144, 2}, | ||
103 | {V4L2_PIX_FMT_SPCA561, 320, 240, 1}, | ||
104 | {V4L2_PIX_FMT_SPCA561, 352, 288, 0}, | ||
105 | }; | ||
106 | |||
107 | /* | ||
108 | * Initialization data | ||
109 | * I'm not very sure how to split initialization from open data | ||
110 | * chunks. For now, we'll consider everything as initialization | ||
111 | */ | ||
112 | /* Frame packet header offsets for the spca561 */ | ||
113 | #define SPCA561_OFFSET_SNAP 1 | ||
114 | #define SPCA561_OFFSET_TYPE 2 | ||
115 | #define SPCA561_OFFSET_COMPRESS 3 | ||
116 | #define SPCA561_OFFSET_FRAMSEQ 4 | ||
117 | #define SPCA561_OFFSET_GPIO 5 | ||
118 | #define SPCA561_OFFSET_USBBUFF 6 | ||
119 | #define SPCA561_OFFSET_WIN2GRAVE 7 | ||
120 | #define SPCA561_OFFSET_WIN2RAVE 8 | ||
121 | #define SPCA561_OFFSET_WIN2BAVE 9 | ||
122 | #define SPCA561_OFFSET_WIN2GBAVE 10 | ||
123 | #define SPCA561_OFFSET_WIN1GRAVE 11 | ||
124 | #define SPCA561_OFFSET_WIN1RAVE 12 | ||
125 | #define SPCA561_OFFSET_WIN1BAVE 13 | ||
126 | #define SPCA561_OFFSET_WIN1GBAVE 14 | ||
127 | #define SPCA561_OFFSET_FREQ 15 | ||
128 | #define SPCA561_OFFSET_VSYNC 16 | ||
129 | #define SPCA561_OFFSET_DATA 1 | ||
130 | #define SPCA561_INDEX_I2C_BASE 0x8800 | ||
131 | #define SPCA561_SNAPBIT 0x20 | ||
132 | #define SPCA561_SNAPCTRL 0x40 | ||
133 | enum { | ||
134 | Rev072A = 0, | ||
135 | Rev012A, | ||
136 | }; | ||
137 | |||
138 | static void reg_w_val(struct usb_device *dev, __u16 index, __u16 value) | ||
139 | { | ||
140 | int ret; | ||
141 | |||
142 | ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | ||
143 | 0, /* request */ | ||
144 | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
145 | value, index, NULL, 0, 500); | ||
146 | PDEBUG(D_USBO, "reg write: 0x%02x:0x%02x", index, value); | ||
147 | if (ret < 0) | ||
148 | PDEBUG(D_ERR, "reg write: error %d", ret); | ||
149 | } | ||
150 | |||
151 | static void write_vector(struct gspca_dev *gspca_dev, __u16 data[][2]) | ||
152 | { | ||
153 | struct usb_device *dev = gspca_dev->dev; | ||
154 | int i; | ||
155 | |||
156 | i = 0; | ||
157 | while (data[i][1] != 0) { | ||
158 | reg_w_val(dev, data[i][1], data[i][0]); | ||
159 | i++; | ||
160 | } | ||
161 | } | ||
162 | |||
163 | static void reg_r(struct usb_device *dev, | ||
164 | __u16 index, __u8 *buffer, __u16 length) | ||
165 | { | ||
166 | usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), | ||
167 | 0, /* request */ | ||
168 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
169 | 0, /* value */ | ||
170 | index, buffer, length, 500); | ||
171 | } | ||
172 | |||
173 | static void reg_w_buf(struct usb_device *dev, | ||
174 | __u16 index, __u8 *buffer, __u16 length) | ||
175 | { | ||
176 | usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | ||
177 | 0, /* request */ | ||
178 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
179 | 0, /* value */ | ||
180 | index, buffer, length, 500); | ||
181 | } | ||
182 | |||
183 | static void i2c_init(struct gspca_dev *gspca_dev, __u8 mode) | ||
184 | { | ||
185 | reg_w_val(gspca_dev->dev, 0x92, 0x8804); | ||
186 | reg_w_val(gspca_dev->dev, mode, 0x8802); | ||
187 | } | ||
188 | |||
189 | static void i2c_write(struct gspca_dev *gspca_dev, __u16 valeur, __u16 reg) | ||
190 | { | ||
191 | int retry = 60; | ||
192 | __u8 DataLow; | ||
193 | __u8 DataHight; | ||
194 | __u8 Data; | ||
195 | |||
196 | DataLow = valeur; | ||
197 | DataHight = valeur >> 8; | ||
198 | reg_w_val(gspca_dev->dev, reg, 0x8801); | ||
199 | reg_w_val(gspca_dev->dev, DataLow, 0x8805); | ||
200 | reg_w_val(gspca_dev->dev, DataHight, 0x8800); | ||
201 | while (retry--) { | ||
202 | reg_r(gspca_dev->dev, 0x8803, &Data, 1); | ||
203 | if (!Data) | ||
204 | break; | ||
205 | } | ||
206 | } | ||
207 | |||
208 | static int i2c_read(struct gspca_dev *gspca_dev, __u16 reg, __u8 mode) | ||
209 | { | ||
210 | int retry = 60; | ||
211 | __u8 value; | ||
212 | __u8 vallsb; | ||
213 | __u8 Data; | ||
214 | |||
215 | reg_w_val(gspca_dev->dev, 0x92, 0x8804); | ||
216 | reg_w_val(gspca_dev->dev, reg, 0x8801); | ||
217 | reg_w_val(gspca_dev->dev, (mode | 0x01), 0x8802); | ||
218 | while (retry--) { | ||
219 | reg_r(gspca_dev->dev, 0x8803, &Data, 1); | ||
220 | if (!Data) | ||
221 | break; | ||
222 | } | ||
223 | if (retry == 0) | ||
224 | return -1; | ||
225 | reg_r(gspca_dev->dev, 0x8800, &value, 1); | ||
226 | reg_r(gspca_dev->dev, 0x8805, &vallsb, 1); | ||
227 | return ((int) value << 8) | vallsb; | ||
228 | } | ||
229 | |||
230 | static __u16 spca561_init_data[][2] = { | ||
231 | {0x0000, 0x8114}, /* Software GPIO output data */ | ||
232 | {0x0001, 0x8114}, /* Software GPIO output data */ | ||
233 | {0x0000, 0x8112}, /* Some kind of reset */ | ||
234 | {0x0003, 0x8701}, /* PCLK clock delay adjustment */ | ||
235 | {0x0001, 0x8703}, /* HSYNC from cmos inverted */ | ||
236 | {0x0011, 0x8118}, /* Enable and conf sensor */ | ||
237 | {0x0001, 0x8118}, /* Conf sensor */ | ||
238 | {0x0092, 0x8804}, /* I know nothing about these */ | ||
239 | {0x0010, 0x8802}, /* 0x88xx registers, so I won't */ | ||
240 | /***************/ | ||
241 | {0x000d, 0x8805}, /* sensor default setting */ | ||
242 | {0x0001, 0x8801}, /* 1 <- 0x0d */ | ||
243 | {0x0000, 0x8800}, | ||
244 | {0x0018, 0x8805}, | ||
245 | {0x0002, 0x8801}, /* 2 <- 0x18 */ | ||
246 | {0x0000, 0x8800}, | ||
247 | {0x0065, 0x8805}, | ||
248 | {0x0004, 0x8801}, /* 4 <- 0x01 0x65 */ | ||
249 | {0x0001, 0x8800}, | ||
250 | {0x0021, 0x8805}, | ||
251 | {0x0005, 0x8801}, /* 5 <- 0x21 */ | ||
252 | {0x0000, 0x8800}, | ||
253 | {0x00aa, 0x8805}, | ||
254 | {0x0007, 0x8801}, /* 7 <- 0xaa */ | ||
255 | {0x0000, 0x8800}, | ||
256 | {0x0004, 0x8805}, | ||
257 | {0x0020, 0x8801}, /* 0x20 <- 0x15 0x04 */ | ||
258 | {0x0015, 0x8800}, | ||
259 | {0x0002, 0x8805}, | ||
260 | {0x0039, 0x8801}, /* 0x39 <- 0x02 */ | ||
261 | {0x0000, 0x8800}, | ||
262 | {0x0010, 0x8805}, | ||
263 | {0x0035, 0x8801}, /* 0x35 <- 0x10 */ | ||
264 | {0x0000, 0x8800}, | ||
265 | {0x0049, 0x8805}, | ||
266 | {0x0009, 0x8801}, /* 0x09 <- 0x10 0x49 */ | ||
267 | {0x0010, 0x8800}, | ||
268 | {0x000b, 0x8805}, | ||
269 | {0x0028, 0x8801}, /* 0x28 <- 0x0b */ | ||
270 | {0x0000, 0x8800}, | ||
271 | {0x000f, 0x8805}, | ||
272 | {0x003b, 0x8801}, /* 0x3b <- 0x0f */ | ||
273 | {0x0000, 0x8800}, | ||
274 | {0x0000, 0x8805}, | ||
275 | {0x003c, 0x8801}, /* 0x3c <- 0x00 */ | ||
276 | {0x0000, 0x8800}, | ||
277 | /***************/ | ||
278 | {0x0018, 0x8601}, /* Pixel/line selection for color separation */ | ||
279 | {0x0000, 0x8602}, /* Optical black level for user setting */ | ||
280 | {0x0060, 0x8604}, /* Optical black horizontal offset */ | ||
281 | {0x0002, 0x8605}, /* Optical black vertical offset */ | ||
282 | {0x0000, 0x8603}, /* Non-automatic optical black level */ | ||
283 | {0x0002, 0x865b}, /* Horizontal offset for valid pixels */ | ||
284 | {0x0000, 0x865f}, /* Vertical valid pixels window (x2) */ | ||
285 | {0x00b0, 0x865d}, /* Horizontal valid pixels window (x2) */ | ||
286 | {0x0090, 0x865e}, /* Vertical valid lines window (x2) */ | ||
287 | {0x00e0, 0x8406}, /* Memory buffer threshold */ | ||
288 | {0x0000, 0x8660}, /* Compensation memory stuff */ | ||
289 | {0x0002, 0x8201}, /* Output address for r/w serial EEPROM */ | ||
290 | {0x0008, 0x8200}, /* Clear valid bit for serial EEPROM */ | ||
291 | {0x0001, 0x8200}, /* OprMode to be executed by hardware */ | ||
292 | {0x0007, 0x8201}, /* Output address for r/w serial EEPROM */ | ||
293 | {0x0008, 0x8200}, /* Clear valid bit for serial EEPROM */ | ||
294 | {0x0001, 0x8200}, /* OprMode to be executed by hardware */ | ||
295 | {0x0010, 0x8660}, /* Compensation memory stuff */ | ||
296 | {0x0018, 0x8660}, /* Compensation memory stuff */ | ||
297 | |||
298 | {0x0004, 0x8611}, /* R offset for white balance */ | ||
299 | {0x0004, 0x8612}, /* Gr offset for white balance */ | ||
300 | {0x0007, 0x8613}, /* B offset for white balance */ | ||
301 | {0x0000, 0x8614}, /* Gb offset for white balance */ | ||
302 | {0x008c, 0x8651}, /* R gain for white balance */ | ||
303 | {0x008c, 0x8652}, /* Gr gain for white balance */ | ||
304 | {0x00b5, 0x8653}, /* B gain for white balance */ | ||
305 | {0x008c, 0x8654}, /* Gb gain for white balance */ | ||
306 | {0x0002, 0x8502}, /* Maximum average bit rate stuff */ | ||
307 | |||
308 | {0x0011, 0x8802}, | ||
309 | {0x0087, 0x8700}, /* Set master clock (96Mhz????) */ | ||
310 | {0x0081, 0x8702}, /* Master clock output enable */ | ||
311 | |||
312 | {0x0000, 0x8500}, /* Set image type (352x288 no compression) */ | ||
313 | /* Originally was 0x0010 (352x288 compression) */ | ||
314 | |||
315 | {0x0002, 0x865b}, /* Horizontal offset for valid pixels */ | ||
316 | {0x0003, 0x865c}, /* Vertical offset for valid lines */ | ||
317 | /***************//* sensor active */ | ||
318 | {0x0003, 0x8801}, /* 0x03 <- 0x01 0x21 //289 */ | ||
319 | {0x0021, 0x8805}, | ||
320 | {0x0001, 0x8800}, | ||
321 | {0x0004, 0x8801}, /* 0x04 <- 0x01 0x65 //357 */ | ||
322 | {0x0065, 0x8805}, | ||
323 | {0x0001, 0x8800}, | ||
324 | {0x0005, 0x8801}, /* 0x05 <- 0x2f */ | ||
325 | {0x002f, 0x8805}, | ||
326 | {0x0000, 0x8800}, | ||
327 | {0x0006, 0x8801}, /* 0x06 <- 0 */ | ||
328 | {0x0000, 0x8805}, | ||
329 | {0x0000, 0x8800}, | ||
330 | {0x000a, 0x8801}, /* 0x0a <- 2 */ | ||
331 | {0x0002, 0x8805}, | ||
332 | {0x0000, 0x8800}, | ||
333 | {0x0009, 0x8801}, /* 0x09 <- 0x1061 */ | ||
334 | {0x0061, 0x8805}, | ||
335 | {0x0010, 0x8800}, | ||
336 | {0x0035, 0x8801}, /* 0x35 <-0x14 */ | ||
337 | {0x0014, 0x8805}, | ||
338 | {0x0000, 0x8800}, | ||
339 | {0x0030, 0x8112}, /* ISO and drop packet enable */ | ||
340 | {0x0000, 0x8112}, /* Some kind of reset ???? */ | ||
341 | {0x0009, 0x8118}, /* Enable sensor and set standby */ | ||
342 | {0x0000, 0x8114}, /* Software GPIO output data */ | ||
343 | {0x0000, 0x8114}, /* Software GPIO output data */ | ||
344 | {0x0001, 0x8114}, /* Software GPIO output data */ | ||
345 | {0x0000, 0x8112}, /* Some kind of reset ??? */ | ||
346 | {0x0003, 0x8701}, | ||
347 | {0x0001, 0x8703}, | ||
348 | {0x0011, 0x8118}, | ||
349 | {0x0001, 0x8118}, | ||
350 | /***************/ | ||
351 | {0x0092, 0x8804}, | ||
352 | {0x0010, 0x8802}, | ||
353 | {0x000d, 0x8805}, | ||
354 | {0x0001, 0x8801}, | ||
355 | {0x0000, 0x8800}, | ||
356 | {0x0018, 0x8805}, | ||
357 | {0x0002, 0x8801}, | ||
358 | {0x0000, 0x8800}, | ||
359 | {0x0065, 0x8805}, | ||
360 | {0x0004, 0x8801}, | ||
361 | {0x0001, 0x8800}, | ||
362 | {0x0021, 0x8805}, | ||
363 | {0x0005, 0x8801}, | ||
364 | {0x0000, 0x8800}, | ||
365 | {0x00aa, 0x8805}, | ||
366 | {0x0007, 0x8801}, /* mode 0xaa */ | ||
367 | {0x0000, 0x8800}, | ||
368 | {0x0004, 0x8805}, | ||
369 | {0x0020, 0x8801}, | ||
370 | {0x0015, 0x8800}, /* mode 0x0415 */ | ||
371 | {0x0002, 0x8805}, | ||
372 | {0x0039, 0x8801}, | ||
373 | {0x0000, 0x8800}, | ||
374 | {0x0010, 0x8805}, | ||
375 | {0x0035, 0x8801}, | ||
376 | {0x0000, 0x8800}, | ||
377 | {0x0049, 0x8805}, | ||
378 | {0x0009, 0x8801}, | ||
379 | {0x0010, 0x8800}, | ||
380 | {0x000b, 0x8805}, | ||
381 | {0x0028, 0x8801}, | ||
382 | {0x0000, 0x8800}, | ||
383 | {0x000f, 0x8805}, | ||
384 | {0x003b, 0x8801}, | ||
385 | {0x0000, 0x8800}, | ||
386 | {0x0000, 0x8805}, | ||
387 | {0x003c, 0x8801}, | ||
388 | {0x0000, 0x8800}, | ||
389 | {0x0002, 0x8502}, | ||
390 | {0x0039, 0x8801}, | ||
391 | {0x0000, 0x8805}, | ||
392 | {0x0000, 0x8800}, | ||
393 | |||
394 | {0x0087, 0x8700}, /* overwrite by start */ | ||
395 | {0x0081, 0x8702}, | ||
396 | {0x0000, 0x8500}, | ||
397 | /* {0x0010, 0x8500}, -- Previous line was this */ | ||
398 | {0x0002, 0x865b}, | ||
399 | {0x0003, 0x865c}, | ||
400 | /***************/ | ||
401 | {0x0003, 0x8801}, /* 0x121-> 289 */ | ||
402 | {0x0021, 0x8805}, | ||
403 | {0x0001, 0x8800}, | ||
404 | {0x0004, 0x8801}, /* 0x165 -> 357 */ | ||
405 | {0x0065, 0x8805}, | ||
406 | {0x0001, 0x8800}, | ||
407 | {0x0005, 0x8801}, /* 0x2f //blanking control colonne */ | ||
408 | {0x002f, 0x8805}, | ||
409 | {0x0000, 0x8800}, | ||
410 | {0x0006, 0x8801}, /* 0x00 //blanking mode row */ | ||
411 | {0x0000, 0x8805}, | ||
412 | {0x0000, 0x8800}, | ||
413 | {0x000a, 0x8801}, /* 0x01 //0x02 */ | ||
414 | {0x0001, 0x8805}, | ||
415 | {0x0000, 0x8800}, | ||
416 | {0x0009, 0x8801}, /* 0x1061 - setexposure times && pixel clock | ||
417 | * 0001 0 | 000 0110 0001 */ | ||
418 | {0x0061, 0x8805}, /* 61 31 */ | ||
419 | {0x0008, 0x8800}, /* 08 */ | ||
420 | {0x0035, 0x8801}, /* 0x14 - set gain general */ | ||
421 | {0x001f, 0x8805}, /* 0x14 */ | ||
422 | {0x0000, 0x8800}, | ||
423 | {0x0030, 0x8112}, | ||
424 | {} | ||
425 | }; | ||
426 | |||
427 | static void sensor_reset(struct gspca_dev *gspca_dev) | ||
428 | { | ||
429 | reg_w_val(gspca_dev->dev, 0x8631, 0xc8); | ||
430 | reg_w_val(gspca_dev->dev, 0x8634, 0xc8); | ||
431 | reg_w_val(gspca_dev->dev, 0x8112, 0x00); | ||
432 | reg_w_val(gspca_dev->dev, 0x8114, 0x00); | ||
433 | reg_w_val(gspca_dev->dev, 0x8118, 0x21); | ||
434 | i2c_init(gspca_dev, 0x14); | ||
435 | i2c_write(gspca_dev, 1, 0x0d); | ||
436 | i2c_write(gspca_dev, 0, 0x0d); | ||
437 | } | ||
438 | |||
439 | /******************** QC Express etch2 stuff ********************/ | ||
440 | static __u16 Pb100_1map8300[][2] = { | ||
441 | /* reg, value */ | ||
442 | {0x8320, 0x3304}, | ||
443 | |||
444 | {0x8303, 0x0125}, /* image area */ | ||
445 | {0x8304, 0x0169}, | ||
446 | {0x8328, 0x000b}, | ||
447 | {0x833c, 0x0001}, | ||
448 | |||
449 | {0x832f, 0x0419}, | ||
450 | {0x8307, 0x00aa}, | ||
451 | {0x8301, 0x0003}, | ||
452 | {0x8302, 0x000e}, | ||
453 | {} | ||
454 | }; | ||
455 | static __u16 Pb100_2map8300[][2] = { | ||
456 | /* reg, value */ | ||
457 | {0x8339, 0x0000}, | ||
458 | {0x8307, 0x00aa}, | ||
459 | {} | ||
460 | }; | ||
461 | |||
462 | static __u16 spca561_161rev12A_data1[][2] = { | ||
463 | {0x21, 0x8118}, | ||
464 | {0x01, 0x8114}, | ||
465 | {0x00, 0x8112}, | ||
466 | {0x92, 0x8804}, | ||
467 | {0x04, 0x8802}, /* windows uses 08 */ | ||
468 | {} | ||
469 | }; | ||
470 | static __u16 spca561_161rev12A_data2[][2] = { | ||
471 | {0x21, 0x8118}, | ||
472 | {0x10, 0x8500}, | ||
473 | {0x07, 0x8601}, | ||
474 | {0x07, 0x8602}, | ||
475 | {0x04, 0x8501}, | ||
476 | {0x21, 0x8118}, | ||
477 | |||
478 | {0x07, 0x8201}, /* windows uses 02 */ | ||
479 | {0x08, 0x8200}, | ||
480 | {0x01, 0x8200}, | ||
481 | |||
482 | {0x00, 0x8114}, | ||
483 | {0x01, 0x8114}, /* windows uses 00 */ | ||
484 | |||
485 | {0x90, 0x8604}, | ||
486 | {0x00, 0x8605}, | ||
487 | {0xb0, 0x8603}, | ||
488 | |||
489 | /* sensor gains */ | ||
490 | {0x00, 0x8610}, /* *red */ | ||
491 | {0x00, 0x8611}, /* 3f *green */ | ||
492 | {0x00, 0x8612}, /* green *blue */ | ||
493 | {0x00, 0x8613}, /* blue *green */ | ||
494 | {0x35, 0x8614}, /* green *red */ | ||
495 | {0x35, 0x8615}, /* 40 *green */ | ||
496 | {0x35, 0x8616}, /* 7a *blue */ | ||
497 | {0x35, 0x8617}, /* 40 *green */ | ||
498 | |||
499 | {0x0c, 0x8620}, /* 0c */ | ||
500 | {0xc8, 0x8631}, /* c8 */ | ||
501 | {0xc8, 0x8634}, /* c8 */ | ||
502 | {0x23, 0x8635}, /* 23 */ | ||
503 | {0x1f, 0x8636}, /* 1f */ | ||
504 | {0xdd, 0x8637}, /* dd */ | ||
505 | {0xe1, 0x8638}, /* e1 */ | ||
506 | {0x1d, 0x8639}, /* 1d */ | ||
507 | {0x21, 0x863a}, /* 21 */ | ||
508 | {0xe3, 0x863b}, /* e3 */ | ||
509 | {0xdf, 0x863c}, /* df */ | ||
510 | {0xf0, 0x8505}, | ||
511 | {0x32, 0x850a}, | ||
512 | {} | ||
513 | }; | ||
514 | |||
515 | static void sensor_mapwrite(struct gspca_dev *gspca_dev, | ||
516 | __u16 sensormap[][2]) | ||
517 | { | ||
518 | int i = 0; | ||
519 | __u8 usbval[2]; | ||
520 | |||
521 | while (sensormap[i][0]) { | ||
522 | usbval[0] = sensormap[i][1]; | ||
523 | usbval[1] = sensormap[i][1] >> 8; | ||
524 | reg_w_buf(gspca_dev->dev, sensormap[i][0], usbval, 2); | ||
525 | i++; | ||
526 | } | ||
527 | } | ||
528 | static void init_161rev12A(struct gspca_dev *gspca_dev) | ||
529 | { | ||
530 | sensor_reset(gspca_dev); | ||
531 | write_vector(gspca_dev, spca561_161rev12A_data1); | ||
532 | sensor_mapwrite(gspca_dev, Pb100_1map8300); | ||
533 | write_vector(gspca_dev, spca561_161rev12A_data2); | ||
534 | sensor_mapwrite(gspca_dev, Pb100_2map8300); | ||
535 | } | ||
536 | |||
537 | /* this function is called at probe time */ | ||
538 | static int sd_config(struct gspca_dev *gspca_dev, | ||
539 | const struct usb_device_id *id) | ||
540 | { | ||
541 | struct sd *sd = (struct sd *) gspca_dev; | ||
542 | struct usb_device *dev = gspca_dev->dev; | ||
543 | struct cam *cam; | ||
544 | __u16 vendor, product; | ||
545 | __u8 data1, data2; | ||
546 | |||
547 | /* Read frm global register the USB product and vendor IDs, just to | ||
548 | * prove that we can communicate with the device. This works, which | ||
549 | * confirms at we are communicating properly and that the device | ||
550 | * is a 561. */ | ||
551 | reg_r(dev, 0x8104, &data1, 1); | ||
552 | reg_r(dev, 0x8105, &data2, 1); | ||
553 | vendor = (data2 << 8) | data1; | ||
554 | reg_r(dev, 0x8106, &data1, 1); | ||
555 | reg_r(dev, 0x8107, &data2, 1); | ||
556 | product = (data2 << 8) | data1; | ||
557 | if (vendor != id->idVendor || product != id->idProduct) { | ||
558 | PDEBUG(D_PROBE, "Bad vendor / product from device"); | ||
559 | return -EINVAL; | ||
560 | } | ||
561 | switch (product) { | ||
562 | case 0x0928: | ||
563 | case 0x0929: | ||
564 | case 0x092a: | ||
565 | case 0x092b: | ||
566 | case 0x092c: | ||
567 | case 0x092d: | ||
568 | case 0x092e: | ||
569 | case 0x092f: | ||
570 | case 0x403b: | ||
571 | sd->chip_revision = Rev012A; | ||
572 | break; | ||
573 | default: | ||
574 | /* case 0x0561: | ||
575 | case 0x0815: * ?? in spca508.c | ||
576 | case 0x401a: | ||
577 | case 0x7004: | ||
578 | case 0x7e50: | ||
579 | case 0xa001: | ||
580 | case 0xcdee: */ | ||
581 | sd->chip_revision = Rev072A; | ||
582 | break; | ||
583 | } | ||
584 | cam = &gspca_dev->cam; | ||
585 | cam->dev_name = (char *) id->driver_info; | ||
586 | cam->epaddr = 0x01; | ||
587 | gspca_dev->nbalt = 7 + 1; /* choose alternate 7 first */ | ||
588 | cam->cam_mode = sif_mode; | ||
589 | cam->nmodes = sizeof sif_mode / sizeof sif_mode[0]; | ||
590 | sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; | ||
591 | sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; | ||
592 | sd->autogain = sd_ctrls[SD_AUTOGAIN].qctrl.default_value; | ||
593 | return 0; | ||
594 | } | ||
595 | |||
596 | /* this function is called at open time */ | ||
597 | static int sd_open(struct gspca_dev *gspca_dev) | ||
598 | { | ||
599 | struct sd *sd = (struct sd *) gspca_dev; | ||
600 | |||
601 | switch (sd->chip_revision) { | ||
602 | case Rev072A: | ||
603 | PDEBUG(D_STREAM, "Chip revision id: 072a"); | ||
604 | write_vector(gspca_dev, spca561_init_data); | ||
605 | break; | ||
606 | default: | ||
607 | /* case Rev012A: */ | ||
608 | PDEBUG(D_STREAM, "Chip revision id: 012a"); | ||
609 | init_161rev12A(gspca_dev); | ||
610 | break; | ||
611 | } | ||
612 | return 0; | ||
613 | } | ||
614 | |||
615 | static void setcontrast(struct gspca_dev *gspca_dev) | ||
616 | { | ||
617 | struct sd *sd = (struct sd *) gspca_dev; | ||
618 | struct usb_device *dev = gspca_dev->dev; | ||
619 | __u8 lowb; | ||
620 | int expotimes; | ||
621 | |||
622 | switch (sd->chip_revision) { | ||
623 | case Rev072A: | ||
624 | lowb = sd->contrast >> 8; | ||
625 | reg_w_val(dev, lowb, 0x8651); | ||
626 | reg_w_val(dev, lowb, 0x8652); | ||
627 | reg_w_val(dev, lowb, 0x8653); | ||
628 | reg_w_val(dev, lowb, 0x8654); | ||
629 | break; | ||
630 | case Rev012A: { | ||
631 | __u8 Reg8391[] = | ||
632 | { 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00 }; | ||
633 | |||
634 | /* Write camera sensor settings */ | ||
635 | expotimes = (sd->contrast >> 5) & 0x07ff; | ||
636 | Reg8391[0] = expotimes & 0xff; /* exposure */ | ||
637 | Reg8391[1] = 0x18 | (expotimes >> 8); | ||
638 | Reg8391[2] = sd->brightness; /* gain */ | ||
639 | reg_w_buf(dev, 0x8391, Reg8391, 8); | ||
640 | reg_w_buf(dev, 0x8390, Reg8391, 8); | ||
641 | break; | ||
642 | } | ||
643 | } | ||
644 | } | ||
645 | |||
646 | static void sd_start(struct gspca_dev *gspca_dev) | ||
647 | { | ||
648 | struct sd *sd = (struct sd *) gspca_dev; | ||
649 | struct usb_device *dev = gspca_dev->dev; | ||
650 | int Clck; | ||
651 | __u8 Reg8307[] = { 0xaa, 0x00 }; | ||
652 | int mode; | ||
653 | |||
654 | mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode; | ||
655 | switch (sd->chip_revision) { | ||
656 | case Rev072A: | ||
657 | switch (mode) { | ||
658 | default: | ||
659 | /* case 0: | ||
660 | case 1: */ | ||
661 | Clck = 0x25; | ||
662 | break; | ||
663 | case 2: | ||
664 | Clck = 0x22; | ||
665 | break; | ||
666 | case 3: | ||
667 | Clck = 0x21; | ||
668 | break; | ||
669 | } | ||
670 | reg_w_val(dev, 0x8500, mode); /* mode */ | ||
671 | reg_w_val(dev, 0x8700, Clck); /* 0x27 clock */ | ||
672 | reg_w_val(dev, 0x8112, 0x10 | 0x20); | ||
673 | break; | ||
674 | default: | ||
675 | /* case Rev012A: */ | ||
676 | switch (mode) { | ||
677 | case 0: | ||
678 | case 1: | ||
679 | Clck = 0x8a; | ||
680 | break; | ||
681 | case 2: | ||
682 | Clck = 0x85; | ||
683 | break; | ||
684 | default: | ||
685 | Clck = 0x83; | ||
686 | break; | ||
687 | } | ||
688 | if (mode <= 1) { | ||
689 | /* Use compression on 320x240 and above */ | ||
690 | reg_w_val(dev, 0x8500, 0x10 | mode); | ||
691 | } else { | ||
692 | /* I couldn't get the compression to work below 320x240 | ||
693 | * Fortunately at these resolutions the bandwidth | ||
694 | * is sufficient to push raw frames at ~20fps */ | ||
695 | reg_w_val(dev, 0x8500, mode); | ||
696 | } /* -- qq@kuku.eu.org */ | ||
697 | reg_w_buf(dev, 0x8307, Reg8307, 2); | ||
698 | reg_w_val(dev, 0x8700, Clck); /* 0x8f 0x85 0x27 clock */ | ||
699 | reg_w_val(dev, 0x8112, 0x1e | 0x20); | ||
700 | reg_w_val(dev, 0x850b, 0x03); | ||
701 | setcontrast(gspca_dev); | ||
702 | break; | ||
703 | } | ||
704 | } | ||
705 | |||
706 | static void sd_stopN(struct gspca_dev *gspca_dev) | ||
707 | { | ||
708 | reg_w_val(gspca_dev->dev, 0x8112, 0x20); | ||
709 | } | ||
710 | |||
711 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
712 | { | ||
713 | } | ||
714 | |||
715 | /* this function is called at close time */ | ||
716 | static void sd_close(struct gspca_dev *gspca_dev) | ||
717 | { | ||
718 | reg_w_val(gspca_dev->dev, 0x8114, 0); | ||
719 | } | ||
720 | |||
721 | static void setautogain(struct gspca_dev *gspca_dev) | ||
722 | { | ||
723 | struct sd *sd = (struct sd *) gspca_dev; | ||
724 | int expotimes = 0; | ||
725 | int pixelclk = 0; | ||
726 | int gainG = 0; | ||
727 | __u8 R, Gr, Gb, B; | ||
728 | int y; | ||
729 | __u8 luma_mean = 110; | ||
730 | __u8 luma_delta = 20; | ||
731 | __u8 spring = 4; | ||
732 | |||
733 | switch (sd->chip_revision) { | ||
734 | case Rev072A: | ||
735 | reg_r(gspca_dev->dev, 0x8621, &Gr, 1); | ||
736 | reg_r(gspca_dev->dev, 0x8622, &R, 1); | ||
737 | reg_r(gspca_dev->dev, 0x8623, &B, 1); | ||
738 | reg_r(gspca_dev->dev, 0x8624, &Gb, 1); | ||
739 | y = (77 * R + 75 * (Gr + Gb) + 29 * B) >> 8; | ||
740 | /* u= (128*B-(43*(Gr+Gb+R))) >> 8; */ | ||
741 | /* v= (128*R-(53*(Gr+Gb))-21*B) >> 8; */ | ||
742 | /* PDEBUG(D_CONF,"reading Y %d U %d V %d ",y,u,v); */ | ||
743 | |||
744 | if (y < luma_mean - luma_delta || | ||
745 | y > luma_mean + luma_delta) { | ||
746 | expotimes = i2c_read(gspca_dev, 0x09, 0x10); | ||
747 | pixelclk = 0x0800; | ||
748 | expotimes = expotimes & 0x07ff; | ||
749 | /* PDEBUG(D_PACK, | ||
750 | "Exposition Times 0x%03X Clock 0x%04X ", | ||
751 | expotimes,pixelclk); */ | ||
752 | gainG = i2c_read(gspca_dev, 0x35, 0x10); | ||
753 | /* PDEBUG(D_PACK, | ||
754 | "reading Gain register %d", gainG); */ | ||
755 | |||
756 | expotimes += (luma_mean - y) >> spring; | ||
757 | gainG += (luma_mean - y) / 50; | ||
758 | /* PDEBUG(D_PACK, | ||
759 | "compute expotimes %d gain %d", | ||
760 | expotimes,gainG); */ | ||
761 | |||
762 | if (gainG > 0x3f) | ||
763 | gainG = 0x3f; | ||
764 | else if (gainG < 4) | ||
765 | gainG = 3; | ||
766 | i2c_write(gspca_dev, gainG, 0x35); | ||
767 | |||
768 | if (expotimes >= 0x0256) | ||
769 | expotimes = 0x0256; | ||
770 | else if (expotimes < 4) | ||
771 | expotimes = 3; | ||
772 | i2c_write(gspca_dev, expotimes | pixelclk, 0x09); | ||
773 | } | ||
774 | break; | ||
775 | case Rev012A: | ||
776 | /* sensor registers is access and memory mapped to 0x8300 */ | ||
777 | /* readind all 0x83xx block the sensor */ | ||
778 | /* | ||
779 | * The data from the header seem wrong where is the luma | ||
780 | * and chroma mean value | ||
781 | * at the moment set exposure in contrast set | ||
782 | */ | ||
783 | break; | ||
784 | } | ||
785 | } | ||
786 | |||
787 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | ||
788 | struct gspca_frame *frame, /* target */ | ||
789 | __u8 *data, /* isoc packet */ | ||
790 | int len) /* iso packet length */ | ||
791 | { | ||
792 | struct sd *sd = (struct sd *) gspca_dev; | ||
793 | |||
794 | switch (data[0]) { | ||
795 | case 0: /* start of frame */ | ||
796 | frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, | ||
797 | data, 0); | ||
798 | if (sd->ag_cnt >= 0) { | ||
799 | if (--sd->ag_cnt < 0) { | ||
800 | sd->ag_cnt = AG_CNT_START; | ||
801 | setautogain(gspca_dev); | ||
802 | } | ||
803 | } | ||
804 | data += SPCA561_OFFSET_DATA; | ||
805 | len -= SPCA561_OFFSET_DATA; | ||
806 | if (data[1] & 0x10) { | ||
807 | /* compressed bayer */ | ||
808 | gspca_frame_add(gspca_dev, FIRST_PACKET, | ||
809 | frame, data, len); | ||
810 | } else { | ||
811 | /*fixme: which format?*/ | ||
812 | data += 20; | ||
813 | len -= 20; | ||
814 | gspca_frame_add(gspca_dev, FIRST_PACKET, | ||
815 | frame, data, len); | ||
816 | } | ||
817 | return; | ||
818 | case 0xff: /* drop */ | ||
819 | /* gspca_dev->last_packet_type = DISCARD_PACKET; */ | ||
820 | return; | ||
821 | } | ||
822 | data++; | ||
823 | len--; | ||
824 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); | ||
825 | } | ||
826 | |||
827 | static void setbrightness(struct gspca_dev *gspca_dev) | ||
828 | { | ||
829 | struct sd *sd = (struct sd *) gspca_dev; | ||
830 | __u8 value; | ||
831 | |||
832 | switch (sd->chip_revision) { | ||
833 | case Rev072A: | ||
834 | value = sd->brightness; | ||
835 | reg_w_val(gspca_dev->dev, value, 0x8611); | ||
836 | reg_w_val(gspca_dev->dev, value, 0x8612); | ||
837 | reg_w_val(gspca_dev->dev, value, 0x8613); | ||
838 | reg_w_val(gspca_dev->dev, value, 0x8614); | ||
839 | break; | ||
840 | default: | ||
841 | /* case Rev012A: */ | ||
842 | setcontrast(gspca_dev); | ||
843 | break; | ||
844 | } | ||
845 | } | ||
846 | |||
847 | static void getbrightness(struct gspca_dev *gspca_dev) | ||
848 | { | ||
849 | struct sd *sd = (struct sd *) gspca_dev; | ||
850 | __u8 value; | ||
851 | __u16 tot; | ||
852 | |||
853 | switch (sd->chip_revision) { | ||
854 | case Rev072A: | ||
855 | tot = 0; | ||
856 | reg_r(gspca_dev->dev, 0x8611, &value, 1); | ||
857 | tot += value; | ||
858 | reg_r(gspca_dev->dev, 0x8612, &value, 1); | ||
859 | tot += value; | ||
860 | reg_r(gspca_dev->dev, 0x8613, &value, 1); | ||
861 | tot += value; | ||
862 | reg_r(gspca_dev->dev, 0x8614, &value, 1); | ||
863 | tot += value; | ||
864 | sd->brightness = tot >> 2; | ||
865 | break; | ||
866 | default: | ||
867 | /* case Rev012A: */ | ||
868 | /* no way to read sensor settings */ | ||
869 | break; | ||
870 | } | ||
871 | } | ||
872 | |||
873 | static void getcontrast(struct gspca_dev *gspca_dev) | ||
874 | { | ||
875 | struct sd *sd = (struct sd *) gspca_dev; | ||
876 | __u8 value; | ||
877 | __u16 tot; | ||
878 | |||
879 | switch (sd->chip_revision) { | ||
880 | case Rev072A: | ||
881 | tot = 0; | ||
882 | reg_r(gspca_dev->dev, 0x8651, &value, 1); | ||
883 | tot += value; | ||
884 | reg_r(gspca_dev->dev, 0x8652, &value, 1); | ||
885 | tot += value; | ||
886 | reg_r(gspca_dev->dev, 0x8653, &value, 1); | ||
887 | tot += value; | ||
888 | reg_r(gspca_dev->dev, 0x8654, &value, 1); | ||
889 | tot += value; | ||
890 | sd->contrast = tot << 6; | ||
891 | break; | ||
892 | default: | ||
893 | /* case Rev012A: */ | ||
894 | /* no way to read sensor settings */ | ||
895 | break; | ||
896 | } | ||
897 | PDEBUG(D_CONF, "get contrast %d", sd->contrast); | ||
898 | } | ||
899 | |||
900 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | ||
901 | { | ||
902 | struct sd *sd = (struct sd *) gspca_dev; | ||
903 | |||
904 | sd->brightness = val; | ||
905 | if (gspca_dev->streaming) | ||
906 | setbrightness(gspca_dev); | ||
907 | return 0; | ||
908 | } | ||
909 | |||
910 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
911 | { | ||
912 | struct sd *sd = (struct sd *) gspca_dev; | ||
913 | |||
914 | getbrightness(gspca_dev); | ||
915 | *val = sd->brightness; | ||
916 | return 0; | ||
917 | } | ||
918 | |||
919 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | ||
920 | { | ||
921 | struct sd *sd = (struct sd *) gspca_dev; | ||
922 | |||
923 | sd->contrast = val; | ||
924 | if (gspca_dev->streaming) | ||
925 | setcontrast(gspca_dev); | ||
926 | return 0; | ||
927 | } | ||
928 | |||
929 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) | ||
930 | { | ||
931 | struct sd *sd = (struct sd *) gspca_dev; | ||
932 | |||
933 | getcontrast(gspca_dev); | ||
934 | *val = sd->contrast; | ||
935 | return 0; | ||
936 | } | ||
937 | |||
938 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) | ||
939 | { | ||
940 | struct sd *sd = (struct sd *) gspca_dev; | ||
941 | |||
942 | sd->autogain = val; | ||
943 | if (val) | ||
944 | sd->ag_cnt = AG_CNT_START; | ||
945 | else | ||
946 | sd->ag_cnt = -1; | ||
947 | return 0; | ||
948 | } | ||
949 | |||
950 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) | ||
951 | { | ||
952 | struct sd *sd = (struct sd *) gspca_dev; | ||
953 | |||
954 | *val = sd->autogain; | ||
955 | return 0; | ||
956 | } | ||
957 | |||
958 | /* sub-driver description */ | ||
959 | static struct sd_desc sd_desc = { | ||
960 | .name = MODULE_NAME, | ||
961 | .ctrls = sd_ctrls, | ||
962 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
963 | .config = sd_config, | ||
964 | .open = sd_open, | ||
965 | .start = sd_start, | ||
966 | .stopN = sd_stopN, | ||
967 | .stop0 = sd_stop0, | ||
968 | .close = sd_close, | ||
969 | .pkt_scan = sd_pkt_scan, | ||
970 | }; | ||
971 | |||
972 | /* -- module initialisation -- */ | ||
973 | #define DVNM(name) .driver_info = (kernel_ulong_t) name | ||
974 | static __devinitdata struct usb_device_id device_table[] = { | ||
975 | {USB_DEVICE(0x041e, 0x401a), DVNM("Creative Webcam Vista (PD1100)")}, | ||
976 | {USB_DEVICE(0x041e, 0x403b), DVNM("Creative Webcam Vista (VF0010)")}, | ||
977 | {USB_DEVICE(0x0458, 0x7004), DVNM("Genius VideoCAM Express V2")}, | ||
978 | {USB_DEVICE(0x046d, 0x0928), DVNM("Logitech QC Express Etch2")}, | ||
979 | {USB_DEVICE(0x046d, 0x0929), DVNM("Labtec Webcam Elch2")}, | ||
980 | {USB_DEVICE(0x046d, 0x092a), DVNM("Logitech QC for Notebook")}, | ||
981 | {USB_DEVICE(0x046d, 0x092b), DVNM("Labtec Webcam Plus")}, | ||
982 | {USB_DEVICE(0x046d, 0x092c), DVNM("Logitech QC chat Elch2")}, | ||
983 | {USB_DEVICE(0x046d, 0x092d), DVNM("Logitech QC Elch2")}, | ||
984 | {USB_DEVICE(0x046d, 0x092e), DVNM("Logitech QC Elch2")}, | ||
985 | {USB_DEVICE(0x046d, 0x092f), DVNM("Logitech QC Elch2")}, | ||
986 | {USB_DEVICE(0x04fc, 0x0561), DVNM("Flexcam 100")}, | ||
987 | {USB_DEVICE(0x060b, 0xa001), DVNM("Maxell Compact Pc PM3")}, | ||
988 | {USB_DEVICE(0x10fd, 0x7e50), DVNM("FlyCam Usb 100")}, | ||
989 | {USB_DEVICE(0xabcd, 0xcdee), DVNM("Petcam")}, | ||
990 | {} | ||
991 | }; | ||
992 | |||
993 | MODULE_DEVICE_TABLE(usb, device_table); | ||
994 | |||
995 | /* -- device connect -- */ | ||
996 | static int sd_probe(struct usb_interface *intf, | ||
997 | const struct usb_device_id *id) | ||
998 | { | ||
999 | return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), | ||
1000 | THIS_MODULE); | ||
1001 | } | ||
1002 | |||
1003 | static struct usb_driver sd_driver = { | ||
1004 | .name = MODULE_NAME, | ||
1005 | .id_table = device_table, | ||
1006 | .probe = sd_probe, | ||
1007 | .disconnect = gspca_disconnect, | ||
1008 | }; | ||
1009 | |||
1010 | /* -- module insert / remove -- */ | ||
1011 | static int __init sd_mod_init(void) | ||
1012 | { | ||
1013 | if (usb_register(&sd_driver) < 0) | ||
1014 | return -1; | ||
1015 | PDEBUG(D_PROBE, "v%s registered", version); | ||
1016 | return 0; | ||
1017 | } | ||
1018 | static void __exit sd_mod_exit(void) | ||
1019 | { | ||
1020 | usb_deregister(&sd_driver); | ||
1021 | PDEBUG(D_PROBE, "deregistered"); | ||
1022 | } | ||
1023 | |||
1024 | module_init(sd_mod_init); | ||
1025 | module_exit(sd_mod_exit); | ||
diff --git a/drivers/media/video/gspca/stk014.c b/drivers/media/video/gspca/stk014.c index d8c203e99cd3..6832fe0f3403 100644 --- a/drivers/media/video/gspca/stk014.c +++ b/drivers/media/video/gspca/stk014.c | |||
@@ -23,8 +23,8 @@ | |||
23 | #include "gspca.h" | 23 | #include "gspca.h" |
24 | #include "jpeg.h" | 24 | #include "jpeg.h" |
25 | 25 | ||
26 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(0, 2, 7) | 26 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) |
27 | static const char version[] = "0.2.7"; | 27 | static const char version[] = "2.1.0"; |
28 | 28 | ||
29 | MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>"); | 29 | MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>"); |
30 | MODULE_DESCRIPTION("Syntek DV4000 (STK014) USB Camera Driver"); | 30 | MODULE_DESCRIPTION("Syntek DV4000 (STK014) USB Camera Driver"); |
@@ -37,10 +37,10 @@ struct sd { | |||
37 | unsigned char brightness; | 37 | unsigned char brightness; |
38 | unsigned char contrast; | 38 | unsigned char contrast; |
39 | unsigned char colors; | 39 | unsigned char colors; |
40 | unsigned char lightfreq; | ||
40 | }; | 41 | }; |
41 | 42 | ||
42 | /* global parameters */ | 43 | /* global parameters */ |
43 | static int lightfreq = 50; | ||
44 | static int sd_quant = 7; /* <= 4 KO - 7: good (enough!) */ | 44 | static int sd_quant = 7; /* <= 4 KO - 7: good (enough!) */ |
45 | 45 | ||
46 | /* V4L2 controls supported by the driver */ | 46 | /* V4L2 controls supported by the driver */ |
@@ -50,6 +50,8 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | |||
50 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | 50 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); |
51 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); | 51 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); |
52 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); | 52 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); |
53 | static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); | ||
54 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); | ||
53 | 55 | ||
54 | static struct ctrl sd_ctrls[] = { | 56 | static struct ctrl sd_ctrls[] = { |
55 | #define SD_BRIGHTNESS 0 | 57 | #define SD_BRIGHTNESS 0 |
@@ -94,6 +96,20 @@ static struct ctrl sd_ctrls[] = { | |||
94 | .set = sd_setcolors, | 96 | .set = sd_setcolors, |
95 | .get = sd_getcolors, | 97 | .get = sd_getcolors, |
96 | }, | 98 | }, |
99 | #define SD_FREQ 3 | ||
100 | { | ||
101 | { | ||
102 | .id = V4L2_CID_POWER_LINE_FREQUENCY, | ||
103 | .type = V4L2_CTRL_TYPE_MENU, | ||
104 | .name = "Light frequency filter", | ||
105 | .minimum = 1, | ||
106 | .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */ | ||
107 | .step = 1, | ||
108 | .default_value = 1, | ||
109 | }, | ||
110 | .set = sd_setfreq, | ||
111 | .get = sd_getfreq, | ||
112 | }, | ||
97 | }; | 113 | }; |
98 | 114 | ||
99 | static struct cam_mode vga_mode[] = { | 115 | static struct cam_mode vga_mode[] = { |
@@ -102,11 +118,11 @@ static struct cam_mode vga_mode[] = { | |||
102 | }; | 118 | }; |
103 | 119 | ||
104 | /* -- read a register -- */ | 120 | /* -- read a register -- */ |
105 | static int reg_read(struct gspca_dev *gspca_dev, | 121 | static int reg_r(struct gspca_dev *gspca_dev, |
106 | __u16 index, __u8 *buf) | 122 | __u16 index, __u8 *buf) |
107 | { | 123 | { |
108 | int ret; | ||
109 | struct usb_device *dev = gspca_dev->dev; | 124 | struct usb_device *dev = gspca_dev->dev; |
125 | int ret; | ||
110 | 126 | ||
111 | ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), | 127 | ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), |
112 | 0x00, | 128 | 0x00, |
@@ -116,12 +132,12 @@ static int reg_read(struct gspca_dev *gspca_dev, | |||
116 | buf, 1, | 132 | buf, 1, |
117 | 500); | 133 | 500); |
118 | if (ret < 0) | 134 | if (ret < 0) |
119 | PDEBUG(D_ERR, "reg_read err %d", ret); | 135 | PDEBUG(D_ERR, "reg_r err %d", ret); |
120 | return ret; | 136 | return ret; |
121 | } | 137 | } |
122 | 138 | ||
123 | /* -- write a register -- */ | 139 | /* -- write a register -- */ |
124 | static int reg_write(struct gspca_dev *gspca_dev, | 140 | static int reg_w(struct gspca_dev *gspca_dev, |
125 | __u16 index, __u16 value) | 141 | __u16 index, __u16 value) |
126 | { | 142 | { |
127 | struct usb_device *dev = gspca_dev->dev; | 143 | struct usb_device *dev = gspca_dev->dev; |
@@ -136,7 +152,7 @@ static int reg_write(struct gspca_dev *gspca_dev, | |||
136 | 0, | 152 | 0, |
137 | 500); | 153 | 500); |
138 | if (ret < 0) | 154 | if (ret < 0) |
139 | PDEBUG(D_ERR, "reg_write err %d", ret); | 155 | PDEBUG(D_ERR, "reg_w err %d", ret); |
140 | return ret; | 156 | return ret; |
141 | } | 157 | } |
142 | 158 | ||
@@ -149,15 +165,15 @@ static int rcv_val(struct gspca_dev *gspca_dev, | |||
149 | int alen, ret; | 165 | int alen, ret; |
150 | unsigned char bulk_buf[4]; | 166 | unsigned char bulk_buf[4]; |
151 | 167 | ||
152 | reg_write(gspca_dev, 0x634, (ads >> 16) & 0xff); | 168 | reg_w(gspca_dev, 0x634, (ads >> 16) & 0xff); |
153 | reg_write(gspca_dev, 0x635, (ads >> 8) & 0xff); | 169 | reg_w(gspca_dev, 0x635, (ads >> 8) & 0xff); |
154 | reg_write(gspca_dev, 0x636, ads & 0xff); | 170 | reg_w(gspca_dev, 0x636, ads & 0xff); |
155 | reg_write(gspca_dev, 0x637, 0); | 171 | reg_w(gspca_dev, 0x637, 0); |
156 | reg_write(gspca_dev, 0x638, len & 0xff); | 172 | reg_w(gspca_dev, 0x638, len & 0xff); |
157 | reg_write(gspca_dev, 0x639, len >> 8); | 173 | reg_w(gspca_dev, 0x639, len >> 8); |
158 | reg_write(gspca_dev, 0x63a, 0); | 174 | reg_w(gspca_dev, 0x63a, 0); |
159 | reg_write(gspca_dev, 0x63b, 0); | 175 | reg_w(gspca_dev, 0x63b, 0); |
160 | reg_write(gspca_dev, 0x630, 5); | 176 | reg_w(gspca_dev, 0x630, 5); |
161 | if (len > sizeof bulk_buf) | 177 | if (len > sizeof bulk_buf) |
162 | return -1; | 178 | return -1; |
163 | ret = usb_bulk_msg(dev, | 179 | ret = usb_bulk_msg(dev, |
@@ -180,26 +196,26 @@ static int snd_val(struct gspca_dev *gspca_dev, | |||
180 | unsigned char bulk_buf[4]; | 196 | unsigned char bulk_buf[4]; |
181 | 197 | ||
182 | if (ads == 0x003f08) { | 198 | if (ads == 0x003f08) { |
183 | ret = reg_read(gspca_dev, 0x0704, &value); | 199 | ret = reg_r(gspca_dev, 0x0704, &value); |
184 | if (ret < 0) | 200 | if (ret < 0) |
185 | goto ko; | 201 | goto ko; |
186 | ret = reg_read(gspca_dev, 0x0705, &seq); | 202 | ret = reg_r(gspca_dev, 0x0705, &seq); |
187 | if (ret < 0) | 203 | if (ret < 0) |
188 | goto ko; | 204 | goto ko; |
189 | ret = reg_read(gspca_dev, 0x0650, &value); | 205 | ret = reg_r(gspca_dev, 0x0650, &value); |
190 | if (ret < 0) | 206 | if (ret < 0) |
191 | goto ko; | 207 | goto ko; |
192 | reg_write(gspca_dev, 0x654, seq); | 208 | reg_w(gspca_dev, 0x654, seq); |
193 | } else | 209 | } else |
194 | reg_write(gspca_dev, 0x654, (ads >> 16) & 0xff); | 210 | reg_w(gspca_dev, 0x654, (ads >> 16) & 0xff); |
195 | reg_write(gspca_dev, 0x655, (ads >> 8) & 0xff); | 211 | reg_w(gspca_dev, 0x655, (ads >> 8) & 0xff); |
196 | reg_write(gspca_dev, 0x656, ads & 0xff); | 212 | reg_w(gspca_dev, 0x656, ads & 0xff); |
197 | reg_write(gspca_dev, 0x657, 0); | 213 | reg_w(gspca_dev, 0x657, 0); |
198 | reg_write(gspca_dev, 0x658, 0x04); /* size */ | 214 | reg_w(gspca_dev, 0x658, 0x04); /* size */ |
199 | reg_write(gspca_dev, 0x659, 0); | 215 | reg_w(gspca_dev, 0x659, 0); |
200 | reg_write(gspca_dev, 0x65a, 0); | 216 | reg_w(gspca_dev, 0x65a, 0); |
201 | reg_write(gspca_dev, 0x65b, 0); | 217 | reg_w(gspca_dev, 0x65b, 0); |
202 | reg_write(gspca_dev, 0x650, 5); | 218 | reg_w(gspca_dev, 0x650, 5); |
203 | bulk_buf[0] = (val >> 24) & 0xff; | 219 | bulk_buf[0] = (val >> 24) & 0xff; |
204 | bulk_buf[1] = (val >> 16) & 0xff; | 220 | bulk_buf[1] = (val >> 16) & 0xff; |
205 | bulk_buf[2] = (val >> 8) & 0xff; | 221 | bulk_buf[2] = (val >> 8) & 0xff; |
@@ -215,7 +231,7 @@ static int snd_val(struct gspca_dev *gspca_dev, | |||
215 | if (ads == 0x003f08) { | 231 | if (ads == 0x003f08) { |
216 | seq += 4; | 232 | seq += 4; |
217 | seq &= 0x3f; | 233 | seq &= 0x3f; |
218 | reg_write(gspca_dev, 0x705, seq); | 234 | reg_w(gspca_dev, 0x705, seq); |
219 | } | 235 | } |
220 | return ret; | 236 | return ret; |
221 | ko: | 237 | ko: |
@@ -235,7 +251,6 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
235 | struct sd *sd = (struct sd *) gspca_dev; | 251 | struct sd *sd = (struct sd *) gspca_dev; |
236 | int parval; | 252 | int parval; |
237 | 253 | ||
238 | PDEBUG(D_CONF, "brightness: %d", sd->brightness); | ||
239 | parval = 0x06000000 /* whiteness */ | 254 | parval = 0x06000000 /* whiteness */ |
240 | + (sd->brightness << 16); | 255 | + (sd->brightness << 16); |
241 | set_par(gspca_dev, parval); | 256 | set_par(gspca_dev, parval); |
@@ -246,7 +261,6 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
246 | struct sd *sd = (struct sd *) gspca_dev; | 261 | struct sd *sd = (struct sd *) gspca_dev; |
247 | int parval; | 262 | int parval; |
248 | 263 | ||
249 | PDEBUG(D_CONF, "contrast: %d", sd->contrast); | ||
250 | parval = 0x07000000 /* contrast */ | 264 | parval = 0x07000000 /* contrast */ |
251 | + (sd->contrast << 16); | 265 | + (sd->contrast << 16); |
252 | set_par(gspca_dev, parval); | 266 | set_par(gspca_dev, parval); |
@@ -257,13 +271,20 @@ static void setcolors(struct gspca_dev *gspca_dev) | |||
257 | struct sd *sd = (struct sd *) gspca_dev; | 271 | struct sd *sd = (struct sd *) gspca_dev; |
258 | int parval; | 272 | int parval; |
259 | 273 | ||
260 | PDEBUG(D_CONF, "saturation: %d", | ||
261 | sd->colors); | ||
262 | parval = 0x08000000 /* saturation */ | 274 | parval = 0x08000000 /* saturation */ |
263 | + (sd->colors << 16); | 275 | + (sd->colors << 16); |
264 | set_par(gspca_dev, parval); | 276 | set_par(gspca_dev, parval); |
265 | } | 277 | } |
266 | 278 | ||
279 | static void setfreq(struct gspca_dev *gspca_dev) | ||
280 | { | ||
281 | struct sd *sd = (struct sd *) gspca_dev; | ||
282 | |||
283 | set_par(gspca_dev, sd->lightfreq == 1 | ||
284 | ? 0x33640000 /* 50 Hz */ | ||
285 | : 0x33780000); /* 60 Hz */ | ||
286 | } | ||
287 | |||
267 | /* this function is called at probe time */ | 288 | /* this function is called at probe time */ |
268 | static int sd_config(struct gspca_dev *gspca_dev, | 289 | static int sd_config(struct gspca_dev *gspca_dev, |
269 | const struct usb_device_id *id) | 290 | const struct usb_device_id *id) |
@@ -278,6 +299,7 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
278 | sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; | 299 | sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; |
279 | sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; | 300 | sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; |
280 | sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; | 301 | sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; |
302 | sd->lightfreq = sd_ctrls[SD_FREQ].qctrl.default_value; | ||
281 | return 0; | 303 | return 0; |
282 | } | 304 | } |
283 | 305 | ||
@@ -289,7 +311,7 @@ static int sd_open(struct gspca_dev *gspca_dev) | |||
289 | 311 | ||
290 | /* check if the device responds */ | 312 | /* check if the device responds */ |
291 | usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1); | 313 | usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1); |
292 | ret = reg_read(gspca_dev, 0x0740, &value); | 314 | ret = reg_r(gspca_dev, 0x0740, &value); |
293 | if (ret < 0) | 315 | if (ret < 0) |
294 | return ret; | 316 | return ret; |
295 | if (value != 0xff) { | 317 | if (value != 0xff) { |
@@ -320,21 +342,24 @@ static void sd_start(struct gspca_dev *gspca_dev) | |||
320 | ret = usb_set_interface(gspca_dev->dev, | 342 | ret = usb_set_interface(gspca_dev->dev, |
321 | gspca_dev->iface, | 343 | gspca_dev->iface, |
322 | gspca_dev->alt); | 344 | gspca_dev->alt); |
323 | if (ret < 0) | 345 | if (ret < 0) { |
346 | PDEBUG(D_ERR|D_STREAM, "set intf %d %d failed", | ||
347 | gspca_dev->iface, gspca_dev->alt); | ||
324 | goto out; | 348 | goto out; |
325 | ret = reg_read(gspca_dev, 0x0630, &dum); | 349 | } |
350 | ret = reg_r(gspca_dev, 0x0630, &dum); | ||
326 | if (ret < 0) | 351 | if (ret < 0) |
327 | goto out; | 352 | goto out; |
328 | rcv_val(gspca_dev, 0x000020, 4); /* << (value ff ff ff ff) */ | 353 | rcv_val(gspca_dev, 0x000020, 4); /* << (value ff ff ff ff) */ |
329 | ret = reg_read(gspca_dev, 0x0650, &dum); | 354 | ret = reg_r(gspca_dev, 0x0650, &dum); |
330 | if (ret < 0) | 355 | if (ret < 0) |
331 | goto out; | 356 | goto out; |
332 | snd_val(gspca_dev, 0x000020, 0xffffffff); | 357 | snd_val(gspca_dev, 0x000020, 0xffffffff); |
333 | reg_write(gspca_dev, 0x0620, 0); | 358 | reg_w(gspca_dev, 0x0620, 0); |
334 | reg_write(gspca_dev, 0x0630, 0); | 359 | reg_w(gspca_dev, 0x0630, 0); |
335 | reg_write(gspca_dev, 0x0640, 0); | 360 | reg_w(gspca_dev, 0x0640, 0); |
336 | reg_write(gspca_dev, 0x0650, 0); | 361 | reg_w(gspca_dev, 0x0650, 0); |
337 | reg_write(gspca_dev, 0x0660, 0); | 362 | reg_w(gspca_dev, 0x0660, 0); |
338 | setbrightness(gspca_dev); /* whiteness */ | 363 | setbrightness(gspca_dev); /* whiteness */ |
339 | setcontrast(gspca_dev); /* contrast */ | 364 | setcontrast(gspca_dev); /* contrast */ |
340 | setcolors(gspca_dev); /* saturation */ | 365 | setcolors(gspca_dev); /* saturation */ |
@@ -342,9 +367,7 @@ static void sd_start(struct gspca_dev *gspca_dev) | |||
342 | set_par(gspca_dev, 0x0a800000); /* Green ? */ | 367 | set_par(gspca_dev, 0x0a800000); /* Green ? */ |
343 | set_par(gspca_dev, 0x0b800000); /* Blue ? */ | 368 | set_par(gspca_dev, 0x0b800000); /* Blue ? */ |
344 | set_par(gspca_dev, 0x0d030000); /* Gamma ? */ | 369 | set_par(gspca_dev, 0x0d030000); /* Gamma ? */ |
345 | set_par(gspca_dev, lightfreq == 60 | 370 | setfreq(gspca_dev); /* light frequency */ |
346 | ? 0x33780000 /* 60 Hz */ | ||
347 | : 0x33640000); /* 50 Hz */ | ||
348 | 371 | ||
349 | /* start the video flow */ | 372 | /* start the video flow */ |
350 | set_par(gspca_dev, 0x01000000); | 373 | set_par(gspca_dev, 0x01000000); |
@@ -363,15 +386,15 @@ static void sd_stopN(struct gspca_dev *gspca_dev) | |||
363 | set_par(gspca_dev, 0x02000000); | 386 | set_par(gspca_dev, 0x02000000); |
364 | set_par(gspca_dev, 0x02000000); | 387 | set_par(gspca_dev, 0x02000000); |
365 | usb_set_interface(dev, gspca_dev->iface, 1); | 388 | usb_set_interface(dev, gspca_dev->iface, 1); |
366 | reg_read(gspca_dev, 0x0630, &value); | 389 | reg_r(gspca_dev, 0x0630, &value); |
367 | rcv_val(gspca_dev, 0x000020, 4); /* << (value ff ff ff ff) */ | 390 | rcv_val(gspca_dev, 0x000020, 4); /* << (value ff ff ff ff) */ |
368 | reg_read(gspca_dev, 0x0650, &value); | 391 | reg_r(gspca_dev, 0x0650, &value); |
369 | snd_val(gspca_dev, 0x000020, 0xffffffff); | 392 | snd_val(gspca_dev, 0x000020, 0xffffffff); |
370 | reg_write(gspca_dev, 0x0620, 0); | 393 | reg_w(gspca_dev, 0x0620, 0); |
371 | reg_write(gspca_dev, 0x0630, 0); | 394 | reg_w(gspca_dev, 0x0630, 0); |
372 | reg_write(gspca_dev, 0x0640, 0); | 395 | reg_w(gspca_dev, 0x0640, 0); |
373 | reg_write(gspca_dev, 0x0650, 0); | 396 | reg_w(gspca_dev, 0x0650, 0); |
374 | reg_write(gspca_dev, 0x0660, 0); | 397 | reg_w(gspca_dev, 0x0660, 0); |
375 | PDEBUG(D_STREAM, "camera stopped"); | 398 | PDEBUG(D_STREAM, "camera stopped"); |
376 | } | 399 | } |
377 | 400 | ||
@@ -470,6 +493,42 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) | |||
470 | return 0; | 493 | return 0; |
471 | } | 494 | } |
472 | 495 | ||
496 | static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val) | ||
497 | { | ||
498 | struct sd *sd = (struct sd *) gspca_dev; | ||
499 | |||
500 | sd->lightfreq = val; | ||
501 | if (gspca_dev->streaming) | ||
502 | setfreq(gspca_dev); | ||
503 | return 0; | ||
504 | } | ||
505 | |||
506 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val) | ||
507 | { | ||
508 | struct sd *sd = (struct sd *) gspca_dev; | ||
509 | |||
510 | *val = sd->lightfreq; | ||
511 | return 0; | ||
512 | } | ||
513 | |||
514 | static int sd_querymenu(struct gspca_dev *gspca_dev, | ||
515 | struct v4l2_querymenu *menu) | ||
516 | { | ||
517 | switch (menu->id) { | ||
518 | case V4L2_CID_POWER_LINE_FREQUENCY: | ||
519 | switch (menu->index) { | ||
520 | case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */ | ||
521 | strcpy(menu->name, "50 Hz"); | ||
522 | return 0; | ||
523 | case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */ | ||
524 | strcpy(menu->name, "60 Hz"); | ||
525 | return 0; | ||
526 | } | ||
527 | break; | ||
528 | } | ||
529 | return -EINVAL; | ||
530 | } | ||
531 | |||
473 | /* sub-driver description */ | 532 | /* sub-driver description */ |
474 | static struct sd_desc sd_desc = { | 533 | static struct sd_desc sd_desc = { |
475 | .name = MODULE_NAME, | 534 | .name = MODULE_NAME, |
@@ -482,6 +541,7 @@ static struct sd_desc sd_desc = { | |||
482 | .stop0 = sd_stop0, | 541 | .stop0 = sd_stop0, |
483 | .close = sd_close, | 542 | .close = sd_close, |
484 | .pkt_scan = sd_pkt_scan, | 543 | .pkt_scan = sd_pkt_scan, |
544 | .querymenu = sd_querymenu, | ||
485 | }; | 545 | }; |
486 | 546 | ||
487 | /* -- module initialisation -- */ | 547 | /* -- module initialisation -- */ |
@@ -524,7 +584,5 @@ static void __exit sd_mod_exit(void) | |||
524 | module_init(sd_mod_init); | 584 | module_init(sd_mod_init); |
525 | module_exit(sd_mod_exit); | 585 | module_exit(sd_mod_exit); |
526 | 586 | ||
527 | module_param(lightfreq, int, 0644); | ||
528 | MODULE_PARM_DESC(lightfreq, "Light frequency 50 or 60 Hz"); | ||
529 | module_param_named(quant, sd_quant, int, 0644); | 587 | module_param_named(quant, sd_quant, int, 0644); |
530 | MODULE_PARM_DESC(quant, "Quantization index (0..8)"); | 588 | MODULE_PARM_DESC(quant, "Quantization index (0..8)"); |
diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c new file mode 100644 index 000000000000..52d1b32523b1 --- /dev/null +++ b/drivers/media/video/gspca/sunplus.c | |||
@@ -0,0 +1,1638 @@ | |||
1 | /* | ||
2 | * Sunplus spca504(abc) spca533 spca536 library | ||
3 | * Copyright (C) 2005 Michel Xhaard mxhaard@magic.fr | ||
4 | * | ||
5 | * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | #define MODULE_NAME "sunplus" | ||
23 | |||
24 | #include "gspca.h" | ||
25 | #include "jpeg.h" | ||
26 | |||
27 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) | ||
28 | static const char version[] = "2.1.0"; | ||
29 | |||
30 | MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); | ||
31 | MODULE_DESCRIPTION("GSPCA/SPCA5xx USB Camera Driver"); | ||
32 | MODULE_LICENSE("GPL"); | ||
33 | |||
34 | /* specific webcam descriptor */ | ||
35 | struct sd { | ||
36 | struct gspca_dev gspca_dev; /* !! must be the first item */ | ||
37 | |||
38 | unsigned char packet[ISO_MAX_SIZE + 128]; | ||
39 | /* !! no more than 128 ff in an ISO packet */ | ||
40 | |||
41 | unsigned char brightness; | ||
42 | unsigned char contrast; | ||
43 | unsigned char colors; | ||
44 | unsigned char autogain; | ||
45 | |||
46 | char qindex; | ||
47 | char bridge; | ||
48 | #define BRIDGE_SPCA504 0 | ||
49 | #define BRIDGE_SPCA504B 1 | ||
50 | #define BRIDGE_SPCA504C 2 | ||
51 | #define BRIDGE_SPCA533 3 | ||
52 | #define BRIDGE_SPCA536 4 | ||
53 | char subtype; | ||
54 | #define AiptekMiniPenCam13 1 | ||
55 | #define LogitechClickSmart420 2 | ||
56 | #define LogitechClickSmart820 3 | ||
57 | #define MegapixV4 4 | ||
58 | }; | ||
59 | |||
60 | /* V4L2 controls supported by the driver */ | ||
61 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
62 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
63 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | ||
64 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | ||
65 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); | ||
66 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); | ||
67 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); | ||
68 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); | ||
69 | |||
70 | static struct ctrl sd_ctrls[] = { | ||
71 | #define SD_BRIGHTNESS 0 | ||
72 | { | ||
73 | { | ||
74 | .id = V4L2_CID_BRIGHTNESS, | ||
75 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
76 | .name = "Brightness", | ||
77 | .minimum = 0, | ||
78 | .maximum = 0xff, | ||
79 | .step = 1, | ||
80 | .default_value = 0, | ||
81 | }, | ||
82 | .set = sd_setbrightness, | ||
83 | .get = sd_getbrightness, | ||
84 | }, | ||
85 | #define SD_CONTRAST 1 | ||
86 | { | ||
87 | { | ||
88 | .id = V4L2_CID_CONTRAST, | ||
89 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
90 | .name = "Contrast", | ||
91 | .minimum = 0, | ||
92 | .maximum = 0xff, | ||
93 | .step = 1, | ||
94 | .default_value = 0x20, | ||
95 | }, | ||
96 | .set = sd_setcontrast, | ||
97 | .get = sd_getcontrast, | ||
98 | }, | ||
99 | #define SD_COLOR 2 | ||
100 | { | ||
101 | { | ||
102 | .id = V4L2_CID_SATURATION, | ||
103 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
104 | .name = "Color", | ||
105 | .minimum = 0, | ||
106 | .maximum = 0xff, | ||
107 | .step = 1, | ||
108 | .default_value = 0x1a, | ||
109 | }, | ||
110 | .set = sd_setcolors, | ||
111 | .get = sd_getcolors, | ||
112 | }, | ||
113 | #define SD_AUTOGAIN 3 | ||
114 | { | ||
115 | { | ||
116 | .id = V4L2_CID_AUTOGAIN, | ||
117 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
118 | .name = "Auto Gain", | ||
119 | .minimum = 0, | ||
120 | .maximum = 1, | ||
121 | .step = 1, | ||
122 | .default_value = 1, | ||
123 | }, | ||
124 | .set = sd_setautogain, | ||
125 | .get = sd_getautogain, | ||
126 | }, | ||
127 | }; | ||
128 | |||
129 | static struct cam_mode vga_mode[] = { | ||
130 | {V4L2_PIX_FMT_JPEG, 320, 240, 2}, | ||
131 | {V4L2_PIX_FMT_JPEG, 640, 480, 1}, | ||
132 | }; | ||
133 | |||
134 | static struct cam_mode custom_mode[] = { | ||
135 | {V4L2_PIX_FMT_JPEG, 320, 240, 2}, | ||
136 | {V4L2_PIX_FMT_JPEG, 464, 480, 1}, | ||
137 | }; | ||
138 | |||
139 | static struct cam_mode vga_mode2[] = { | ||
140 | {V4L2_PIX_FMT_JPEG, 176, 144, 4}, | ||
141 | {V4L2_PIX_FMT_JPEG, 320, 240, 3}, | ||
142 | {V4L2_PIX_FMT_JPEG, 352, 288, 2}, | ||
143 | {V4L2_PIX_FMT_JPEG, 640, 480, 1}, | ||
144 | }; | ||
145 | |||
146 | #define SPCA50X_OFFSET_DATA 10 | ||
147 | #define SPCA504_PCCAM600_OFFSET_SNAPSHOT 3 | ||
148 | #define SPCA504_PCCAM600_OFFSET_COMPRESS 4 | ||
149 | #define SPCA504_PCCAM600_OFFSET_MODE 5 | ||
150 | #define SPCA504_PCCAM600_OFFSET_DATA 14 | ||
151 | /* Frame packet header offsets for the spca533 */ | ||
152 | #define SPCA533_OFFSET_DATA 16 | ||
153 | #define SPCA533_OFFSET_FRAMSEQ 15 | ||
154 | /* Frame packet header offsets for the spca536 */ | ||
155 | #define SPCA536_OFFSET_DATA 4 | ||
156 | #define SPCA536_OFFSET_FRAMSEQ 1 | ||
157 | |||
158 | /* Initialisation data for the Creative PC-CAM 600 */ | ||
159 | static __u16 spca504_pccam600_init_data[][3] = { | ||
160 | /* {0xa0, 0x0000, 0x0503}, * capture mode */ | ||
161 | {0x00, 0x0000, 0x2000}, | ||
162 | {0x00, 0x0013, 0x2301}, | ||
163 | {0x00, 0x0003, 0x2000}, | ||
164 | {0x00, 0x0001, 0x21ac}, | ||
165 | {0x00, 0x0001, 0x21a6}, | ||
166 | {0x00, 0x0000, 0x21a7}, /* brightness */ | ||
167 | {0x00, 0x0020, 0x21a8}, /* contrast */ | ||
168 | {0x00, 0x0001, 0x21ac}, /* sat/hue */ | ||
169 | {0x00, 0x0000, 0x21ad}, /* hue */ | ||
170 | {0x00, 0x001a, 0x21ae}, /* saturation */ | ||
171 | {0x00, 0x0002, 0x21a3}, /* gamma */ | ||
172 | {0x30, 0x0154, 0x0008}, | ||
173 | {0x30, 0x0004, 0x0006}, | ||
174 | {0x30, 0x0258, 0x0009}, | ||
175 | {0x30, 0x0004, 0x0000}, | ||
176 | {0x30, 0x0093, 0x0004}, | ||
177 | {0x30, 0x0066, 0x0005}, | ||
178 | {0x00, 0x0000, 0x2000}, | ||
179 | {0x00, 0x0013, 0x2301}, | ||
180 | {0x00, 0x0003, 0x2000}, | ||
181 | {0x00, 0x0013, 0x2301}, | ||
182 | {0x00, 0x0003, 0x2000}, | ||
183 | {} | ||
184 | }; | ||
185 | |||
186 | /* Creative PC-CAM 600 specific open data, sent before using the | ||
187 | * generic initialisation data from spca504_open_data. | ||
188 | */ | ||
189 | static __u16 spca504_pccam600_open_data[][3] = { | ||
190 | {0x00, 0x0001, 0x2501}, | ||
191 | {0x20, 0x0500, 0x0001}, /* snapshot mode */ | ||
192 | {0x00, 0x0003, 0x2880}, | ||
193 | {0x00, 0x0001, 0x2881}, | ||
194 | {} | ||
195 | }; | ||
196 | |||
197 | /* Initialisation data for the logitech clicksmart 420 */ | ||
198 | static __u16 spca504A_clicksmart420_init_data[][3] = { | ||
199 | /* {0xa0, 0x0000, 0x0503}, * capture mode */ | ||
200 | {0x00, 0x0000, 0x2000}, | ||
201 | {0x00, 0x0013, 0x2301}, | ||
202 | {0x00, 0x0003, 0x2000}, | ||
203 | {0x00, 0x0001, 0x21ac}, | ||
204 | {0x00, 0x0001, 0x21a6}, | ||
205 | {0x00, 0x0000, 0x21a7}, /* brightness */ | ||
206 | {0x00, 0x0020, 0x21a8}, /* contrast */ | ||
207 | {0x00, 0x0001, 0x21ac}, /* sat/hue */ | ||
208 | {0x00, 0x0000, 0x21ad}, /* hue */ | ||
209 | {0x00, 0x001a, 0x21ae}, /* saturation */ | ||
210 | {0x00, 0x0002, 0x21a3}, /* gamma */ | ||
211 | {0x30, 0x0004, 0x000a}, | ||
212 | {0xb0, 0x0001, 0x0000}, | ||
213 | |||
214 | |||
215 | {0x0a1, 0x0080, 0x0001}, | ||
216 | {0x30, 0x0049, 0x0000}, | ||
217 | {0x30, 0x0060, 0x0005}, | ||
218 | {0x0c, 0x0004, 0x0000}, | ||
219 | {0x00, 0x0000, 0x0000}, | ||
220 | {0x00, 0x0000, 0x2000}, | ||
221 | {0x00, 0x0013, 0x2301}, | ||
222 | {0x00, 0x0003, 0x2000}, | ||
223 | {0x00, 0x0000, 0x2000}, | ||
224 | |||
225 | {} | ||
226 | }; | ||
227 | |||
228 | /* clicksmart 420 open data ? */ | ||
229 | static __u16 spca504A_clicksmart420_open_data[][3] = { | ||
230 | {0x00, 0x0001, 0x2501}, | ||
231 | {0x20, 0x0502, 0x0000}, | ||
232 | {0x06, 0x0000, 0x0000}, | ||
233 | {0x00, 0x0004, 0x2880}, | ||
234 | {0x00, 0x0001, 0x2881}, | ||
235 | /* look like setting a qTable */ | ||
236 | {0x00, 0x0006, 0x2800}, | ||
237 | {0x00, 0x0004, 0x2801}, | ||
238 | {0x00, 0x0004, 0x2802}, | ||
239 | {0x00, 0x0006, 0x2803}, | ||
240 | {0x00, 0x000a, 0x2804}, | ||
241 | {0x00, 0x0010, 0x2805}, | ||
242 | {0x00, 0x0014, 0x2806}, | ||
243 | {0x00, 0x0018, 0x2807}, | ||
244 | {0x00, 0x0005, 0x2808}, | ||
245 | {0x00, 0x0005, 0x2809}, | ||
246 | {0x00, 0x0006, 0x280a}, | ||
247 | {0x00, 0x0008, 0x280b}, | ||
248 | {0x00, 0x000a, 0x280c}, | ||
249 | {0x00, 0x0017, 0x280d}, | ||
250 | {0x00, 0x0018, 0x280e}, | ||
251 | {0x00, 0x0016, 0x280f}, | ||
252 | |||
253 | {0x00, 0x0006, 0x2810}, | ||
254 | {0x00, 0x0005, 0x2811}, | ||
255 | {0x00, 0x0006, 0x2812}, | ||
256 | {0x00, 0x000a, 0x2813}, | ||
257 | {0x00, 0x0010, 0x2814}, | ||
258 | {0x00, 0x0017, 0x2815}, | ||
259 | {0x00, 0x001c, 0x2816}, | ||
260 | {0x00, 0x0016, 0x2817}, | ||
261 | {0x00, 0x0006, 0x2818}, | ||
262 | {0x00, 0x0007, 0x2819}, | ||
263 | {0x00, 0x0009, 0x281a}, | ||
264 | {0x00, 0x000c, 0x281b}, | ||
265 | {0x00, 0x0014, 0x281c}, | ||
266 | {0x00, 0x0023, 0x281d}, | ||
267 | {0x00, 0x0020, 0x281e}, | ||
268 | {0x00, 0x0019, 0x281f}, | ||
269 | |||
270 | {0x00, 0x0007, 0x2820}, | ||
271 | {0x00, 0x0009, 0x2821}, | ||
272 | {0x00, 0x000f, 0x2822}, | ||
273 | {0x00, 0x0016, 0x2823}, | ||
274 | {0x00, 0x001b, 0x2824}, | ||
275 | {0x00, 0x002c, 0x2825}, | ||
276 | {0x00, 0x0029, 0x2826}, | ||
277 | {0x00, 0x001f, 0x2827}, | ||
278 | {0x00, 0x000a, 0x2828}, | ||
279 | {0x00, 0x000e, 0x2829}, | ||
280 | {0x00, 0x0016, 0x282a}, | ||
281 | {0x00, 0x001a, 0x282b}, | ||
282 | {0x00, 0x0020, 0x282c}, | ||
283 | {0x00, 0x002a, 0x282d}, | ||
284 | {0x00, 0x002d, 0x282e}, | ||
285 | {0x00, 0x0025, 0x282f}, | ||
286 | |||
287 | {0x00, 0x0014, 0x2830}, | ||
288 | {0x00, 0x001a, 0x2831}, | ||
289 | {0x00, 0x001f, 0x2832}, | ||
290 | {0x00, 0x0023, 0x2833}, | ||
291 | {0x00, 0x0029, 0x2834}, | ||
292 | {0x00, 0x0030, 0x2835}, | ||
293 | {0x00, 0x0030, 0x2836}, | ||
294 | {0x00, 0x0028, 0x2837}, | ||
295 | {0x00, 0x001d, 0x2838}, | ||
296 | {0x00, 0x0025, 0x2839}, | ||
297 | {0x00, 0x0026, 0x283a}, | ||
298 | {0x00, 0x0027, 0x283b}, | ||
299 | {0x00, 0x002d, 0x283c}, | ||
300 | {0x00, 0x0028, 0x283d}, | ||
301 | {0x00, 0x0029, 0x283e}, | ||
302 | {0x00, 0x0028, 0x283f}, | ||
303 | |||
304 | {0x00, 0x0007, 0x2840}, | ||
305 | {0x00, 0x0007, 0x2841}, | ||
306 | {0x00, 0x000a, 0x2842}, | ||
307 | {0x00, 0x0013, 0x2843}, | ||
308 | {0x00, 0x0028, 0x2844}, | ||
309 | {0x00, 0x0028, 0x2845}, | ||
310 | {0x00, 0x0028, 0x2846}, | ||
311 | {0x00, 0x0028, 0x2847}, | ||
312 | {0x00, 0x0007, 0x2848}, | ||
313 | {0x00, 0x0008, 0x2849}, | ||
314 | {0x00, 0x000a, 0x284a}, | ||
315 | {0x00, 0x001a, 0x284b}, | ||
316 | {0x00, 0x0028, 0x284c}, | ||
317 | {0x00, 0x0028, 0x284d}, | ||
318 | {0x00, 0x0028, 0x284e}, | ||
319 | {0x00, 0x0028, 0x284f}, | ||
320 | |||
321 | {0x00, 0x000a, 0x2850}, | ||
322 | {0x00, 0x000a, 0x2851}, | ||
323 | {0x00, 0x0016, 0x2852}, | ||
324 | {0x00, 0x0028, 0x2853}, | ||
325 | {0x00, 0x0028, 0x2854}, | ||
326 | {0x00, 0x0028, 0x2855}, | ||
327 | {0x00, 0x0028, 0x2856}, | ||
328 | {0x00, 0x0028, 0x2857}, | ||
329 | {0x00, 0x0013, 0x2858}, | ||
330 | {0x00, 0x001a, 0x2859}, | ||
331 | {0x00, 0x0028, 0x285a}, | ||
332 | {0x00, 0x0028, 0x285b}, | ||
333 | {0x00, 0x0028, 0x285c}, | ||
334 | {0x00, 0x0028, 0x285d}, | ||
335 | {0x00, 0x0028, 0x285e}, | ||
336 | {0x00, 0x0028, 0x285f}, | ||
337 | |||
338 | {0x00, 0x0028, 0x2860}, | ||
339 | {0x00, 0x0028, 0x2861}, | ||
340 | {0x00, 0x0028, 0x2862}, | ||
341 | {0x00, 0x0028, 0x2863}, | ||
342 | {0x00, 0x0028, 0x2864}, | ||
343 | {0x00, 0x0028, 0x2865}, | ||
344 | {0x00, 0x0028, 0x2866}, | ||
345 | {0x00, 0x0028, 0x2867}, | ||
346 | {0x00, 0x0028, 0x2868}, | ||
347 | {0x00, 0x0028, 0x2869}, | ||
348 | {0x00, 0x0028, 0x286a}, | ||
349 | {0x00, 0x0028, 0x286b}, | ||
350 | {0x00, 0x0028, 0x286c}, | ||
351 | {0x00, 0x0028, 0x286d}, | ||
352 | {0x00, 0x0028, 0x286e}, | ||
353 | {0x00, 0x0028, 0x286f}, | ||
354 | |||
355 | {0x00, 0x0028, 0x2870}, | ||
356 | {0x00, 0x0028, 0x2871}, | ||
357 | {0x00, 0x0028, 0x2872}, | ||
358 | {0x00, 0x0028, 0x2873}, | ||
359 | {0x00, 0x0028, 0x2874}, | ||
360 | {0x00, 0x0028, 0x2875}, | ||
361 | {0x00, 0x0028, 0x2876}, | ||
362 | {0x00, 0x0028, 0x2877}, | ||
363 | {0x00, 0x0028, 0x2878}, | ||
364 | {0x00, 0x0028, 0x2879}, | ||
365 | {0x00, 0x0028, 0x287a}, | ||
366 | {0x00, 0x0028, 0x287b}, | ||
367 | {0x00, 0x0028, 0x287c}, | ||
368 | {0x00, 0x0028, 0x287d}, | ||
369 | {0x00, 0x0028, 0x287e}, | ||
370 | {0x00, 0x0028, 0x287f}, | ||
371 | |||
372 | {0xa0, 0x0000, 0x0503}, | ||
373 | {} | ||
374 | }; | ||
375 | |||
376 | static unsigned char qtable_creative_pccam[2][64] = { | ||
377 | { /* Q-table Y-components */ | ||
378 | 0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12, | ||
379 | 0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11, | ||
380 | 0x04, 0x04, 0x05, 0x07, 0x0c, 0x11, 0x15, 0x11, | ||
381 | 0x04, 0x05, 0x07, 0x09, 0x0f, 0x1a, 0x18, 0x13, | ||
382 | 0x05, 0x07, 0x0b, 0x11, 0x14, 0x21, 0x1f, 0x17, | ||
383 | 0x07, 0x0b, 0x11, 0x13, 0x18, 0x1f, 0x22, 0x1c, | ||
384 | 0x0f, 0x13, 0x17, 0x1a, 0x1f, 0x24, 0x24, 0x1e, | ||
385 | 0x16, 0x1c, 0x1d, 0x1d, 0x22, 0x1e, 0x1f, 0x1e}, | ||
386 | { /* Q-table C-components */ | ||
387 | 0x05, 0x05, 0x07, 0x0e, 0x1e, 0x1e, 0x1e, 0x1e, | ||
388 | 0x05, 0x06, 0x08, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, | ||
389 | 0x07, 0x08, 0x11, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, | ||
390 | 0x0e, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, | ||
391 | 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, | ||
392 | 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, | ||
393 | 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, | ||
394 | 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e} | ||
395 | }; | ||
396 | |||
397 | /* FIXME: This Q-table is identical to the Creative PC-CAM one, | ||
398 | * except for one byte. Possibly a typo? | ||
399 | * NWG: 18/05/2003. | ||
400 | */ | ||
401 | static unsigned char qtable_spca504_default[2][64] = { | ||
402 | { /* Q-table Y-components */ | ||
403 | 0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12, | ||
404 | 0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11, | ||
405 | 0x04, 0x04, 0x05, 0x07, 0x0c, 0x11, 0x15, 0x11, | ||
406 | 0x04, 0x05, 0x07, 0x09, 0x0f, 0x1a, 0x18, 0x13, | ||
407 | 0x05, 0x07, 0x0b, 0x11, 0x14, 0x21, 0x1f, 0x17, | ||
408 | 0x07, 0x0b, 0x11, 0x13, 0x18, 0x1f, 0x22, 0x1c, | ||
409 | 0x0f, 0x13, 0x17, 0x1a, 0x1f, 0x24, 0x24, 0x1e, | ||
410 | 0x16, 0x1c, 0x1d, 0x1d, 0x1d /* 0x22 */ , 0x1e, 0x1f, 0x1e, | ||
411 | }, | ||
412 | { /* Q-table C-components */ | ||
413 | 0x05, 0x05, 0x07, 0x0e, 0x1e, 0x1e, 0x1e, 0x1e, | ||
414 | 0x05, 0x06, 0x08, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, | ||
415 | 0x07, 0x08, 0x11, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, | ||
416 | 0x0e, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, | ||
417 | 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, | ||
418 | 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, | ||
419 | 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, | ||
420 | 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e} | ||
421 | }; | ||
422 | |||
423 | static void spca5xxRegRead(struct usb_device *dev, | ||
424 | __u16 req, | ||
425 | __u16 index, | ||
426 | __u8 *buffer, __u16 length) | ||
427 | { | ||
428 | usb_control_msg(dev, | ||
429 | usb_rcvctrlpipe(dev, 0), | ||
430 | req, | ||
431 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
432 | 0, /* value */ | ||
433 | index, buffer, length, | ||
434 | 500); | ||
435 | } | ||
436 | |||
437 | static void spca5xxRegWrite(struct usb_device *dev, | ||
438 | __u16 req, | ||
439 | __u16 value, | ||
440 | __u16 index, | ||
441 | __u8 *buffer, __u16 length) | ||
442 | { | ||
443 | usb_control_msg(dev, | ||
444 | usb_sndctrlpipe(dev, 0), | ||
445 | req, | ||
446 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
447 | value, index, buffer, length, | ||
448 | 500); | ||
449 | } | ||
450 | |||
451 | static int reg_write(struct usb_device *dev, | ||
452 | __u16 req, __u16 index, __u16 value) | ||
453 | { | ||
454 | int ret; | ||
455 | |||
456 | ret = usb_control_msg(dev, | ||
457 | usb_sndctrlpipe(dev, 0), | ||
458 | req, | ||
459 | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
460 | value, index, NULL, 0, 500); | ||
461 | PDEBUG(D_PACK, "reg write: 0x%02x,0x%02x:0x%02x, 0x%x", | ||
462 | reg, index, value, ret); | ||
463 | if (ret < 0) | ||
464 | PDEBUG(D_ERR, "reg write: error %d", ret); | ||
465 | return ret; | ||
466 | } | ||
467 | |||
468 | static int reg_read_info(struct usb_device *dev, | ||
469 | __u16 value) /* wValue */ | ||
470 | { | ||
471 | int ret; | ||
472 | __u8 data; | ||
473 | |||
474 | ret = usb_control_msg(dev, | ||
475 | usb_rcvctrlpipe(dev, 0), | ||
476 | 0x20, /* request */ | ||
477 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
478 | value, | ||
479 | 0, /* index */ | ||
480 | &data, 1, | ||
481 | 500); /* timeout */ | ||
482 | if (ret < 0) { | ||
483 | PDEBUG(D_ERR, "reg_read_info err %d", ret); | ||
484 | return 0; | ||
485 | } | ||
486 | return data; | ||
487 | } | ||
488 | |||
489 | /* returns: negative is error, pos or zero is data */ | ||
490 | static int reg_read(struct usb_device *dev, | ||
491 | __u16 req, /* bRequest */ | ||
492 | __u16 index, /* wIndex */ | ||
493 | __u16 length) /* wLength (1 or 2 only) */ | ||
494 | { | ||
495 | int ret; | ||
496 | __u8 buf[2]; | ||
497 | |||
498 | buf[1] = 0; | ||
499 | ret = usb_control_msg(dev, | ||
500 | usb_rcvctrlpipe(dev, 0), | ||
501 | req, | ||
502 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
503 | 0, /* value */ | ||
504 | index, | ||
505 | buf, length, | ||
506 | 500); | ||
507 | if (ret < 0) { | ||
508 | PDEBUG(D_ERR, "reg_read err %d", ret); | ||
509 | return -1; | ||
510 | } | ||
511 | return (buf[1] << 8) + buf[0]; | ||
512 | } | ||
513 | |||
514 | static int write_vector(struct gspca_dev *gspca_dev, | ||
515 | __u16 data[][3]) | ||
516 | { | ||
517 | struct usb_device *dev = gspca_dev->dev; | ||
518 | int ret, i = 0; | ||
519 | |||
520 | while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) { | ||
521 | ret = reg_write(dev, data[i][0], data[i][2], data[i][1]); | ||
522 | if (ret < 0) { | ||
523 | PDEBUG(D_ERR, | ||
524 | "Register write failed for 0x%x,0x%x,0x%x", | ||
525 | data[i][0], data[i][1], data[i][2]); | ||
526 | return ret; | ||
527 | } | ||
528 | i++; | ||
529 | } | ||
530 | return 0; | ||
531 | } | ||
532 | |||
533 | static int spca50x_setup_qtable(struct gspca_dev *gspca_dev, | ||
534 | unsigned int request, | ||
535 | unsigned int ybase, | ||
536 | unsigned int cbase, | ||
537 | unsigned char qtable[2][64]) | ||
538 | { | ||
539 | struct usb_device *dev = gspca_dev->dev; | ||
540 | int i, err; | ||
541 | |||
542 | /* loop over y components */ | ||
543 | for (i = 0; i < 64; i++) { | ||
544 | err = reg_write(dev, request, ybase + i, qtable[0][i]); | ||
545 | if (err < 0) | ||
546 | return err; | ||
547 | } | ||
548 | |||
549 | /* loop over c components */ | ||
550 | for (i = 0; i < 64; i++) { | ||
551 | err = reg_write(dev, request, cbase + i, qtable[1][i]); | ||
552 | if (err < 0) | ||
553 | return err; | ||
554 | } | ||
555 | return 0; | ||
556 | } | ||
557 | |||
558 | static void spca504_acknowledged_command(struct gspca_dev *gspca_dev, | ||
559 | __u16 req, __u16 idx, __u16 val) | ||
560 | { | ||
561 | struct usb_device *dev = gspca_dev->dev; | ||
562 | __u8 notdone; | ||
563 | |||
564 | reg_write(dev, req, idx, val); | ||
565 | notdone = reg_read(dev, 0x01, 0x0001, 1); | ||
566 | reg_write(dev, req, idx, val); | ||
567 | |||
568 | PDEBUG(D_FRAM, "before wait 0x%x", notdone); | ||
569 | |||
570 | msleep(200); | ||
571 | notdone = reg_read(dev, 0x01, 0x0001, 1); | ||
572 | PDEBUG(D_FRAM, "after wait 0x%x", notdone); | ||
573 | } | ||
574 | |||
575 | static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev, | ||
576 | __u16 req, | ||
577 | __u16 idx, __u16 val, __u8 stat, __u8 count) | ||
578 | { | ||
579 | struct usb_device *dev = gspca_dev->dev; | ||
580 | __u8 status; | ||
581 | __u8 endcode; | ||
582 | |||
583 | reg_write(dev, req, idx, val); | ||
584 | status = reg_read(dev, 0x01, 0x0001, 1); | ||
585 | endcode = stat; | ||
586 | PDEBUG(D_FRAM, "Status 0x%x Need 0x%x", status, stat); | ||
587 | if (!count) | ||
588 | return; | ||
589 | count = 200; | ||
590 | while (--count > 0) { | ||
591 | msleep(10); | ||
592 | /* gsmart mini2 write a each wait setting 1 ms is enought */ | ||
593 | /* reg_write(dev, req, idx, val); */ | ||
594 | status = reg_read(dev, 0x01, 0x0001, 1); | ||
595 | if (status == endcode) { | ||
596 | PDEBUG(D_FRAM, "status 0x%x after wait 0x%x", | ||
597 | status, 200 - count); | ||
598 | break; | ||
599 | } | ||
600 | } | ||
601 | } | ||
602 | |||
603 | static int spca504B_PollingDataReady(struct usb_device *dev) | ||
604 | { | ||
605 | __u8 DataReady; | ||
606 | int count = 10; | ||
607 | |||
608 | while (--count > 0) { | ||
609 | spca5xxRegRead(dev, 0x21, 0, &DataReady, 1); | ||
610 | if ((DataReady & 0x01) == 0) | ||
611 | break; | ||
612 | msleep(10); | ||
613 | } | ||
614 | return DataReady; | ||
615 | } | ||
616 | |||
617 | static void spca504B_WaitCmdStatus(struct gspca_dev *gspca_dev) | ||
618 | { | ||
619 | struct usb_device *dev = gspca_dev->dev; | ||
620 | __u8 DataReady; | ||
621 | int count = 50; | ||
622 | |||
623 | while (--count > 0) { | ||
624 | spca5xxRegRead(dev, 0x21, 1, &DataReady, 1); | ||
625 | |||
626 | if (DataReady) { | ||
627 | DataReady = 0; | ||
628 | spca5xxRegWrite(dev, 0x21, 0, 1, &DataReady, 1); | ||
629 | spca5xxRegRead(dev, 0x21, 1, &DataReady, 1); | ||
630 | spca504B_PollingDataReady(dev); | ||
631 | break; | ||
632 | } | ||
633 | msleep(10); | ||
634 | } | ||
635 | } | ||
636 | |||
637 | static void spca50x_GetFirmware(struct gspca_dev *gspca_dev) | ||
638 | { | ||
639 | struct usb_device *dev = gspca_dev->dev; | ||
640 | __u8 FW[5]; | ||
641 | __u8 ProductInfo[64]; | ||
642 | |||
643 | spca5xxRegRead(dev, 0x20, 0, FW, 5); | ||
644 | PDEBUG(D_STREAM, "FirmWare : %d %d %d %d %d ", | ||
645 | FW[0], FW[1], FW[2], FW[3], FW[4]); | ||
646 | spca5xxRegRead(dev, 0x23, 0, ProductInfo, 64); | ||
647 | spca5xxRegRead(dev, 0x23, 1, ProductInfo, 64); | ||
648 | } | ||
649 | |||
650 | static void spca504B_SetSizeType(struct gspca_dev *gspca_dev) | ||
651 | { | ||
652 | struct sd *sd = (struct sd *) gspca_dev; | ||
653 | struct usb_device *dev = gspca_dev->dev; | ||
654 | __u8 Size; | ||
655 | __u8 Type; | ||
656 | int rc; | ||
657 | |||
658 | Size = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode; | ||
659 | Type = 0; | ||
660 | switch (sd->bridge) { | ||
661 | case BRIDGE_SPCA533: | ||
662 | spca5xxRegWrite(dev, 0x31, 0, 0, NULL, 0); | ||
663 | spca504B_WaitCmdStatus(gspca_dev); | ||
664 | rc = spca504B_PollingDataReady(dev); | ||
665 | spca50x_GetFirmware(gspca_dev); | ||
666 | Type = 2; | ||
667 | spca5xxRegWrite(dev, 0x24, 0, 8, &Type, 1); | ||
668 | spca5xxRegRead(dev, 0x24, 8, &Type, 1); | ||
669 | |||
670 | spca5xxRegWrite(dev, 0x25, 0, 4, &Size, 1); | ||
671 | spca5xxRegRead(dev, 0x25, 4, &Size, 1); | ||
672 | rc = spca504B_PollingDataReady(dev); | ||
673 | |||
674 | /* Init the cam width height with some values get on init ? */ | ||
675 | spca5xxRegWrite(dev, 0x31, 0, 4, NULL, 0); | ||
676 | spca504B_WaitCmdStatus(gspca_dev); | ||
677 | rc = spca504B_PollingDataReady(dev); | ||
678 | break; | ||
679 | default: | ||
680 | /* case BRIDGE_SPCA504B: */ | ||
681 | /* case BRIDGE_SPCA536: */ | ||
682 | Type = 6; | ||
683 | spca5xxRegWrite(dev, 0x25, 0, 4, &Size, 1); | ||
684 | spca5xxRegRead(dev, 0x25, 4, &Size, 1); | ||
685 | spca5xxRegWrite(dev, 0x27, 0, 0, &Type, 1); | ||
686 | spca5xxRegRead(dev, 0x27, 0, &Type, 1); | ||
687 | rc = spca504B_PollingDataReady(dev); | ||
688 | break; | ||
689 | case BRIDGE_SPCA504: | ||
690 | Size += 3; | ||
691 | if (sd->subtype == AiptekMiniPenCam13) { | ||
692 | /* spca504a aiptek */ | ||
693 | spca504A_acknowledged_command(gspca_dev, | ||
694 | 0x08, Size, 0, | ||
695 | 0x80 | (Size & 0x0f), 1); | ||
696 | spca504A_acknowledged_command(gspca_dev, | ||
697 | 1, 3, 0, 0x9f, 0); | ||
698 | } else { | ||
699 | spca504_acknowledged_command(gspca_dev, 0x08, Size, 0); | ||
700 | } | ||
701 | break; | ||
702 | case BRIDGE_SPCA504C: | ||
703 | /* capture mode */ | ||
704 | reg_write(dev, 0xa0, (0x0500 | (Size & 0x0f)), 0x0); | ||
705 | reg_write(dev, 0x20, 0x01, 0x0500 | (Size & 0x0f)); | ||
706 | break; | ||
707 | } | ||
708 | } | ||
709 | |||
710 | static void spca504_wait_status(struct gspca_dev *gspca_dev) | ||
711 | { | ||
712 | struct usb_device *dev = gspca_dev->dev; | ||
713 | int cnt; | ||
714 | |||
715 | cnt = 256; | ||
716 | while (--cnt > 0) { | ||
717 | /* With this we get the status, when return 0 it's all ok */ | ||
718 | if (reg_read(dev, 0x06, 0x00, 1) == 0) | ||
719 | return; | ||
720 | msleep(10); | ||
721 | } | ||
722 | } | ||
723 | |||
724 | static void spca504B_setQtable(struct gspca_dev *gspca_dev) | ||
725 | { | ||
726 | struct usb_device *dev = gspca_dev->dev; | ||
727 | __u8 Data = 3; | ||
728 | |||
729 | spca5xxRegWrite(dev, 0x26, 0, 0, &Data, 1); | ||
730 | spca5xxRegRead(dev, 0x26, 0, &Data, 1); | ||
731 | spca504B_PollingDataReady(dev); | ||
732 | } | ||
733 | |||
734 | static void sp5xx_initContBrigHueRegisters(struct gspca_dev *gspca_dev) | ||
735 | { | ||
736 | struct sd *sd = (struct sd *) gspca_dev; | ||
737 | struct usb_device *dev = gspca_dev->dev; | ||
738 | int pollreg = 1; | ||
739 | |||
740 | switch (sd->bridge) { | ||
741 | case BRIDGE_SPCA504: | ||
742 | case BRIDGE_SPCA504C: | ||
743 | pollreg = 0; | ||
744 | /* fall thru */ | ||
745 | default: | ||
746 | /* case BRIDGE_SPCA533: */ | ||
747 | /* case BRIDGE_SPCA504B: */ | ||
748 | spca5xxRegWrite(dev, 0, 0, 0x21a7, NULL, 0); /* brightness */ | ||
749 | spca5xxRegWrite(dev, 0, 0x20, 0x21a8, NULL, 0); /* contrast */ | ||
750 | spca5xxRegWrite(dev, 0, 0, 0x21ad, NULL, 0); /* hue */ | ||
751 | spca5xxRegWrite(dev, 0, 1, 0x21ac, NULL, 0); /* sat/hue */ | ||
752 | spca5xxRegWrite(dev, 0, 0x20, 0x21ae, NULL, 0); /* saturation */ | ||
753 | spca5xxRegWrite(dev, 0, 0, 0x21a3, NULL, 0); /* gamma */ | ||
754 | break; | ||
755 | case BRIDGE_SPCA536: | ||
756 | spca5xxRegWrite(dev, 0, 0, 0x20f0, NULL, 0); | ||
757 | spca5xxRegWrite(dev, 0, 0x21, 0x20f1, NULL, 0); | ||
758 | spca5xxRegWrite(dev, 0, 0x40, 0x20f5, NULL, 0); | ||
759 | spca5xxRegWrite(dev, 0, 1, 0x20f4, NULL, 0); | ||
760 | spca5xxRegWrite(dev, 0, 0x40, 0x20f6, NULL, 0); | ||
761 | spca5xxRegWrite(dev, 0, 0, 0x2089, NULL, 0); | ||
762 | break; | ||
763 | } | ||
764 | if (pollreg) | ||
765 | spca504B_PollingDataReady(dev); | ||
766 | } | ||
767 | |||
768 | /* this function is called at probe time */ | ||
769 | static int sd_config(struct gspca_dev *gspca_dev, | ||
770 | const struct usb_device_id *id) | ||
771 | { | ||
772 | struct sd *sd = (struct sd *) gspca_dev; | ||
773 | struct usb_device *dev = gspca_dev->dev; | ||
774 | struct cam *cam; | ||
775 | __u16 vendor; | ||
776 | __u16 product; | ||
777 | __u8 fw; | ||
778 | |||
779 | vendor = id->idVendor; | ||
780 | product = id->idProduct; | ||
781 | switch (vendor) { | ||
782 | case 0x041e: /* Creative cameras */ | ||
783 | /* switch (product) { */ | ||
784 | /* case 0x400b: */ | ||
785 | /* case 0x4012: */ | ||
786 | /* case 0x4013: */ | ||
787 | /* sd->bridge = BRIDGE_SPCA504C; */ | ||
788 | /* break; */ | ||
789 | /* } */ | ||
790 | break; | ||
791 | case 0x0458: /* Genius KYE cameras */ | ||
792 | /* switch (product) { */ | ||
793 | /* case 0x7006: */ | ||
794 | sd->bridge = BRIDGE_SPCA504B; | ||
795 | /* break; */ | ||
796 | /* } */ | ||
797 | break; | ||
798 | case 0x046d: /* Logitech Labtec */ | ||
799 | switch (product) { | ||
800 | case 0x0905: | ||
801 | sd->subtype = LogitechClickSmart820; | ||
802 | sd->bridge = BRIDGE_SPCA533; | ||
803 | break; | ||
804 | case 0x0960: | ||
805 | sd->subtype = LogitechClickSmart420; | ||
806 | sd->bridge = BRIDGE_SPCA504C; | ||
807 | break; | ||
808 | } | ||
809 | break; | ||
810 | case 0x0471: /* Philips */ | ||
811 | /* switch (product) { */ | ||
812 | /* case 0x0322: */ | ||
813 | sd->bridge = BRIDGE_SPCA504B; | ||
814 | /* break; */ | ||
815 | /* } */ | ||
816 | break; | ||
817 | case 0x04a5: /* Benq */ | ||
818 | switch (product) { | ||
819 | case 0x3003: | ||
820 | sd->bridge = BRIDGE_SPCA504B; | ||
821 | break; | ||
822 | case 0x3008: | ||
823 | case 0x300a: | ||
824 | sd->bridge = BRIDGE_SPCA533; | ||
825 | break; | ||
826 | } | ||
827 | break; | ||
828 | case 0x04f1: /* JVC */ | ||
829 | /* switch (product) { */ | ||
830 | /* case 0x1001: */ | ||
831 | sd->bridge = BRIDGE_SPCA504B; | ||
832 | /* break; */ | ||
833 | /* } */ | ||
834 | break; | ||
835 | case 0x04fc: /* SunPlus */ | ||
836 | switch (product) { | ||
837 | case 0x500c: | ||
838 | sd->bridge = BRIDGE_SPCA504B; | ||
839 | break; | ||
840 | case 0x504a: | ||
841 | /* try to get the firmware as some cam answer 2.0.1.2.2 | ||
842 | * and should be a spca504b then overwrite that setting */ | ||
843 | spca5xxRegRead(dev, 0x20, 0, &fw, 1); | ||
844 | if (fw == 1) { | ||
845 | sd->subtype = AiptekMiniPenCam13; | ||
846 | sd->bridge = BRIDGE_SPCA504; | ||
847 | } else if (fw == 2) { | ||
848 | sd->bridge = BRIDGE_SPCA504B; | ||
849 | } else | ||
850 | return -ENODEV; | ||
851 | break; | ||
852 | case 0x504b: | ||
853 | sd->bridge = BRIDGE_SPCA504B; | ||
854 | break; | ||
855 | case 0x5330: | ||
856 | sd->bridge = BRIDGE_SPCA533; | ||
857 | break; | ||
858 | case 0x5360: | ||
859 | sd->bridge = BRIDGE_SPCA536; | ||
860 | break; | ||
861 | case 0xffff: | ||
862 | sd->bridge = BRIDGE_SPCA504B; | ||
863 | break; | ||
864 | } | ||
865 | break; | ||
866 | case 0x052b: /* ?? Megapix */ | ||
867 | /* switch (product) { */ | ||
868 | /* case 0x1513: */ | ||
869 | sd->subtype = MegapixV4; | ||
870 | sd->bridge = BRIDGE_SPCA533; | ||
871 | /* break; */ | ||
872 | /* } */ | ||
873 | break; | ||
874 | case 0x0546: /* Polaroid */ | ||
875 | switch (product) { | ||
876 | case 0x3155: | ||
877 | sd->bridge = BRIDGE_SPCA533; | ||
878 | break; | ||
879 | case 0x3191: | ||
880 | case 0x3273: | ||
881 | sd->bridge = BRIDGE_SPCA504B; | ||
882 | break; | ||
883 | } | ||
884 | break; | ||
885 | case 0x055f: /* Mustek cameras */ | ||
886 | switch (product) { | ||
887 | case 0xc211: | ||
888 | sd->bridge = BRIDGE_SPCA536; | ||
889 | break; | ||
890 | case 0xc230: | ||
891 | case 0xc232: | ||
892 | sd->bridge = BRIDGE_SPCA533; | ||
893 | break; | ||
894 | case 0xc360: | ||
895 | sd->bridge = BRIDGE_SPCA536; | ||
896 | break; | ||
897 | case 0xc420: | ||
898 | sd->bridge = BRIDGE_SPCA504; | ||
899 | break; | ||
900 | case 0xc430: | ||
901 | case 0xc440: | ||
902 | sd->bridge = BRIDGE_SPCA533; | ||
903 | break; | ||
904 | case 0xc520: | ||
905 | sd->bridge = BRIDGE_SPCA504; | ||
906 | break; | ||
907 | case 0xc530: | ||
908 | case 0xc540: | ||
909 | case 0xc630: | ||
910 | case 0xc650: | ||
911 | sd->bridge = BRIDGE_SPCA533; | ||
912 | break; | ||
913 | } | ||
914 | break; | ||
915 | case 0x05da: /* Digital Dream cameras */ | ||
916 | /* switch (product) { */ | ||
917 | /* case 0x1018: */ | ||
918 | sd->bridge = BRIDGE_SPCA504B; | ||
919 | /* break; */ | ||
920 | /* } */ | ||
921 | break; | ||
922 | case 0x06d6: /* Trust */ | ||
923 | /* switch (product) { */ | ||
924 | /* case 0x0031: */ | ||
925 | sd->bridge = BRIDGE_SPCA533; /* SPCA533A */ | ||
926 | /* break; */ | ||
927 | /* } */ | ||
928 | break; | ||
929 | case 0x0733: /* Rebadged ViewQuest (Intel) and ViewQuest cameras */ | ||
930 | switch (product) { | ||
931 | case 0x1311: | ||
932 | case 0x1314: | ||
933 | case 0x2211: | ||
934 | case 0x2221: | ||
935 | sd->bridge = BRIDGE_SPCA533; | ||
936 | break; | ||
937 | case 0x3261: | ||
938 | case 0x3281: | ||
939 | sd->bridge = BRIDGE_SPCA536; | ||
940 | break; | ||
941 | } | ||
942 | break; | ||
943 | case 0x08ca: /* Aiptek */ | ||
944 | switch (product) { | ||
945 | case 0x0104: | ||
946 | case 0x0106: | ||
947 | sd->bridge = BRIDGE_SPCA533; | ||
948 | break; | ||
949 | case 0x2008: | ||
950 | sd->bridge = BRIDGE_SPCA504B; | ||
951 | break; | ||
952 | case 0x2010: | ||
953 | sd->bridge = BRIDGE_SPCA533; | ||
954 | break; | ||
955 | case 0x2016: | ||
956 | case 0x2018: | ||
957 | sd->bridge = BRIDGE_SPCA504B; | ||
958 | break; | ||
959 | case 0x2020: | ||
960 | case 0x2022: | ||
961 | sd->bridge = BRIDGE_SPCA533; | ||
962 | break; | ||
963 | case 0x2024: | ||
964 | sd->bridge = BRIDGE_SPCA536; | ||
965 | break; | ||
966 | case 0x2028: | ||
967 | sd->bridge = BRIDGE_SPCA533; | ||
968 | break; | ||
969 | case 0x2040: | ||
970 | case 0x2042: | ||
971 | case 0x2060: | ||
972 | sd->bridge = BRIDGE_SPCA536; | ||
973 | break; | ||
974 | } | ||
975 | break; | ||
976 | case 0x0d64: /* SunPlus */ | ||
977 | /* switch (product) { */ | ||
978 | /* case 0x0303: */ | ||
979 | sd->bridge = BRIDGE_SPCA536; | ||
980 | /* break; */ | ||
981 | /* } */ | ||
982 | break; | ||
983 | } | ||
984 | |||
985 | cam = &gspca_dev->cam; | ||
986 | cam->dev_name = (char *) id->driver_info; | ||
987 | cam->epaddr = 0x01; | ||
988 | |||
989 | switch (sd->bridge) { | ||
990 | default: | ||
991 | /* case BRIDGE_SPCA504B: */ | ||
992 | /* case BRIDGE_SPCA504: */ | ||
993 | /* case BRIDGE_SPCA536: */ | ||
994 | cam->cam_mode = vga_mode; | ||
995 | cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; | ||
996 | break; | ||
997 | case BRIDGE_SPCA533: | ||
998 | cam->cam_mode = custom_mode; | ||
999 | cam->nmodes = sizeof custom_mode / sizeof custom_mode[0]; | ||
1000 | break; | ||
1001 | case BRIDGE_SPCA504C: | ||
1002 | cam->cam_mode = vga_mode2; | ||
1003 | cam->nmodes = sizeof vga_mode2 / sizeof vga_mode2[0]; | ||
1004 | break; | ||
1005 | } | ||
1006 | sd->qindex = 5; /* set the quantization table */ | ||
1007 | sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; | ||
1008 | sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; | ||
1009 | sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; | ||
1010 | return 0; | ||
1011 | } | ||
1012 | |||
1013 | /* this function is called at open time */ | ||
1014 | static int sd_open(struct gspca_dev *gspca_dev) | ||
1015 | { | ||
1016 | struct sd *sd = (struct sd *) gspca_dev; | ||
1017 | struct usb_device *dev = gspca_dev->dev; | ||
1018 | int rc; | ||
1019 | __u8 Data; | ||
1020 | __u8 i; | ||
1021 | __u8 info[6]; | ||
1022 | int err_code; | ||
1023 | |||
1024 | switch (sd->bridge) { | ||
1025 | case BRIDGE_SPCA504B: | ||
1026 | spca5xxRegWrite(dev, 0x1d, 0, 0, NULL, 0); | ||
1027 | spca5xxRegWrite(dev, 0, 1, 0x2306, NULL, 0); | ||
1028 | spca5xxRegWrite(dev, 0, 0, 0x0d04, NULL, 0); | ||
1029 | spca5xxRegWrite(dev, 0, 0, 0x2000, NULL, 0); | ||
1030 | spca5xxRegWrite(dev, 0, 0x13, 0x2301, NULL, 0); | ||
1031 | spca5xxRegWrite(dev, 0, 0, 0x2306, NULL, 0); | ||
1032 | /* fall thru */ | ||
1033 | case BRIDGE_SPCA533: | ||
1034 | rc = spca504B_PollingDataReady(dev); | ||
1035 | spca50x_GetFirmware(gspca_dev); | ||
1036 | break; | ||
1037 | case BRIDGE_SPCA536: | ||
1038 | spca50x_GetFirmware(gspca_dev); | ||
1039 | spca5xxRegRead(dev, 0x00, 0x5002, &Data, 1); | ||
1040 | Data = 0; | ||
1041 | spca5xxRegWrite(dev, 0x24, 0, 0, &Data, 1); | ||
1042 | spca5xxRegRead(dev, 0x24, 0, &Data, 1); | ||
1043 | rc = spca504B_PollingDataReady(dev); | ||
1044 | spca5xxRegWrite(dev, 0x34, 0, 0, NULL, 0); | ||
1045 | spca504B_WaitCmdStatus(gspca_dev); | ||
1046 | break; | ||
1047 | case BRIDGE_SPCA504C: /* pccam600 */ | ||
1048 | PDEBUG(D_STREAM, "Opening SPCA504 (PC-CAM 600)"); | ||
1049 | reg_write(dev, 0xe0, 0x0000, 0x0000); | ||
1050 | reg_write(dev, 0xe0, 0x0000, 0x0001); /* reset */ | ||
1051 | spca504_wait_status(gspca_dev); | ||
1052 | if (sd->subtype == LogitechClickSmart420) | ||
1053 | write_vector(gspca_dev, | ||
1054 | spca504A_clicksmart420_open_data); | ||
1055 | else | ||
1056 | write_vector(gspca_dev, spca504_pccam600_open_data); | ||
1057 | err_code = spca50x_setup_qtable(gspca_dev, | ||
1058 | 0x00, 0x2800, | ||
1059 | 0x2840, qtable_creative_pccam); | ||
1060 | if (err_code < 0) { | ||
1061 | PDEBUG(D_ERR|D_STREAM, "spca50x_setup_qtable failed"); | ||
1062 | return err_code; | ||
1063 | } | ||
1064 | break; | ||
1065 | default: | ||
1066 | /* case BRIDGE_SPCA504: */ | ||
1067 | PDEBUG(D_STREAM, "Opening SPCA504"); | ||
1068 | if (sd->subtype == AiptekMiniPenCam13) { | ||
1069 | /*****************************/ | ||
1070 | for (i = 0; i < 6; i++) | ||
1071 | info[i] = reg_read_info(dev, i); | ||
1072 | PDEBUG(D_STREAM, | ||
1073 | "Read info: %d %d %d %d %d %d." | ||
1074 | " Should be 1,0,2,2,0,0", | ||
1075 | info[0], info[1], info[2], | ||
1076 | info[3], info[4], info[5]); | ||
1077 | /* spca504a aiptek */ | ||
1078 | /* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */ | ||
1079 | spca504A_acknowledged_command(gspca_dev, 0x24, | ||
1080 | 8, 3, 0x9e, 1); | ||
1081 | /* Twice sequencial need status 0xff->0x9e->0x9d */ | ||
1082 | spca504A_acknowledged_command(gspca_dev, 0x24, | ||
1083 | 8, 3, 0x9e, 0); | ||
1084 | |||
1085 | spca504A_acknowledged_command(gspca_dev, 0x24, | ||
1086 | 0, 0, 0x9d, 1); | ||
1087 | /******************************/ | ||
1088 | /* spca504a aiptek */ | ||
1089 | spca504A_acknowledged_command(gspca_dev, 0x08, | ||
1090 | 6, 0, 0x86, 1); | ||
1091 | /* reg_write (dev, 0, 0x2000, 0); */ | ||
1092 | /* reg_write (dev, 0, 0x2883, 1); */ | ||
1093 | /* spca504A_acknowledged_command (gspca_dev, 0x08, | ||
1094 | 6, 0, 0x86, 1); */ | ||
1095 | /* spca504A_acknowledged_command (gspca_dev, 0x24, | ||
1096 | 0, 0, 0x9D, 1); */ | ||
1097 | reg_write(dev, 0x0, 0x270c, 0x5); /* L92 sno1t.txt */ | ||
1098 | reg_write(dev, 0x0, 0x2310, 0x5); | ||
1099 | spca504A_acknowledged_command(gspca_dev, 0x01, | ||
1100 | 0x0f, 0, 0xff, 0); | ||
1101 | } | ||
1102 | /* setup qtable */ | ||
1103 | reg_write(dev, 0, 0x2000, 0); | ||
1104 | reg_write(dev, 0, 0x2883, 1); | ||
1105 | err_code = spca50x_setup_qtable(gspca_dev, | ||
1106 | 0x00, 0x2800, | ||
1107 | 0x2840, | ||
1108 | qtable_spca504_default); | ||
1109 | if (err_code < 0) { | ||
1110 | PDEBUG(D_ERR, "spca50x_setup_qtable failed"); | ||
1111 | return err_code; | ||
1112 | } | ||
1113 | break; | ||
1114 | } | ||
1115 | return 0; | ||
1116 | } | ||
1117 | |||
1118 | static void sd_start(struct gspca_dev *gspca_dev) | ||
1119 | { | ||
1120 | struct sd *sd = (struct sd *) gspca_dev; | ||
1121 | struct usb_device *dev = gspca_dev->dev; | ||
1122 | int rc; | ||
1123 | int enable; | ||
1124 | __u8 i; | ||
1125 | __u8 info[6]; | ||
1126 | |||
1127 | if (sd->bridge == BRIDGE_SPCA504B) | ||
1128 | spca504B_setQtable(gspca_dev); | ||
1129 | spca504B_SetSizeType(gspca_dev); | ||
1130 | switch (sd->bridge) { | ||
1131 | default: | ||
1132 | /* case BRIDGE_SPCA504B: */ | ||
1133 | /* case BRIDGE_SPCA533: */ | ||
1134 | /* case BRIDGE_SPCA536: */ | ||
1135 | if (sd->subtype == MegapixV4 || | ||
1136 | sd->subtype == LogitechClickSmart820) { | ||
1137 | spca5xxRegWrite(dev, 0xf0, 0, 0, NULL, 0); | ||
1138 | spca504B_WaitCmdStatus(gspca_dev); | ||
1139 | spca5xxRegRead(dev, 0xf0, 4, NULL, 0); | ||
1140 | spca504B_WaitCmdStatus(gspca_dev); | ||
1141 | } else { | ||
1142 | spca5xxRegWrite(dev, 0x31, 0, 4, NULL, 0); | ||
1143 | spca504B_WaitCmdStatus(gspca_dev); | ||
1144 | rc = spca504B_PollingDataReady(dev); | ||
1145 | } | ||
1146 | break; | ||
1147 | case BRIDGE_SPCA504: | ||
1148 | if (sd->subtype == AiptekMiniPenCam13) { | ||
1149 | for (i = 0; i < 6; i++) | ||
1150 | info[i] = reg_read_info(dev, i); | ||
1151 | PDEBUG(D_STREAM, | ||
1152 | "Read info: %d %d %d %d %d %d." | ||
1153 | " Should be 1,0,2,2,0,0", | ||
1154 | info[0], info[1], info[2], | ||
1155 | info[3], info[4], info[5]); | ||
1156 | /* spca504a aiptek */ | ||
1157 | /* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */ | ||
1158 | spca504A_acknowledged_command(gspca_dev, 0x24, | ||
1159 | 8, 3, 0x9e, 1); | ||
1160 | /* Twice sequencial need status 0xff->0x9e->0x9d */ | ||
1161 | spca504A_acknowledged_command(gspca_dev, 0x24, | ||
1162 | 8, 3, 0x9e, 0); | ||
1163 | spca504A_acknowledged_command(gspca_dev, 0x24, | ||
1164 | 0, 0, 0x9d, 1); | ||
1165 | } else { | ||
1166 | spca504_acknowledged_command(gspca_dev, 0x24, 8, 3); | ||
1167 | for (i = 0; i < 6; i++) | ||
1168 | info[i] = reg_read_info(dev, i); | ||
1169 | PDEBUG(D_STREAM, | ||
1170 | "Read info: %d %d %d %d %d %d." | ||
1171 | " Should be 1,0,2,2,0,0", | ||
1172 | info[0], info[1], info[2], | ||
1173 | info[3], info[4], info[5]); | ||
1174 | spca504_acknowledged_command(gspca_dev, 0x24, 8, 3); | ||
1175 | spca504_acknowledged_command(gspca_dev, 0x24, 0, 0); | ||
1176 | } | ||
1177 | spca504B_SetSizeType(gspca_dev); | ||
1178 | reg_write(dev, 0x0, 0x270c, 0x5); /* L92 sno1t.txt */ | ||
1179 | reg_write(dev, 0x0, 0x2310, 0x5); | ||
1180 | break; | ||
1181 | case BRIDGE_SPCA504C: | ||
1182 | if (sd->subtype == LogitechClickSmart420) { | ||
1183 | write_vector(gspca_dev, | ||
1184 | spca504A_clicksmart420_init_data); | ||
1185 | } else { | ||
1186 | write_vector(gspca_dev, spca504_pccam600_init_data); | ||
1187 | } | ||
1188 | enable = (sd->autogain ? 0x4 : 0x1); | ||
1189 | reg_write(dev, 0x0c, 0x0000, enable); /* auto exposure */ | ||
1190 | reg_write(dev, 0xb0, 0x0000, enable); /* auto whiteness */ | ||
1191 | |||
1192 | /* set default exposure compensation and whiteness balance */ | ||
1193 | reg_write(dev, 0x30, 0x0001, 800); /* ~ 20 fps */ | ||
1194 | reg_write(dev, 0x30, 0x0002, 1600); | ||
1195 | spca504B_SetSizeType(gspca_dev); | ||
1196 | break; | ||
1197 | } | ||
1198 | sp5xx_initContBrigHueRegisters(gspca_dev); | ||
1199 | } | ||
1200 | |||
1201 | static void sd_stopN(struct gspca_dev *gspca_dev) | ||
1202 | { | ||
1203 | struct sd *sd = (struct sd *) gspca_dev; | ||
1204 | struct usb_device *dev = gspca_dev->dev; | ||
1205 | |||
1206 | switch (sd->bridge) { | ||
1207 | default: | ||
1208 | /* case BRIDGE_SPCA533: */ | ||
1209 | /* case BRIDGE_SPCA536: */ | ||
1210 | /* case BRIDGE_SPCA504B: */ | ||
1211 | spca5xxRegWrite(dev, 0x31, 0, 0, NULL, 0); | ||
1212 | spca504B_WaitCmdStatus(gspca_dev); | ||
1213 | spca504B_PollingDataReady(dev); | ||
1214 | break; | ||
1215 | case BRIDGE_SPCA504: | ||
1216 | case BRIDGE_SPCA504C: | ||
1217 | reg_write(dev, 0x00, 0x2000, 0x0000); | ||
1218 | |||
1219 | if (sd->subtype == AiptekMiniPenCam13) { | ||
1220 | /* spca504a aiptek */ | ||
1221 | /* spca504A_acknowledged_command(gspca_dev, 0x08, | ||
1222 | 6, 0, 0x86, 1); */ | ||
1223 | spca504A_acknowledged_command(gspca_dev, 0x24, | ||
1224 | 0x00, 0x00, 0x9d, 1); | ||
1225 | spca504A_acknowledged_command(gspca_dev, 0x01, | ||
1226 | 0x0f, 0x00, 0xff, 1); | ||
1227 | } else { | ||
1228 | spca504_acknowledged_command(gspca_dev, 0x24, 0, 0); | ||
1229 | reg_write(dev, 0x01, 0x000f, 0x0); | ||
1230 | } | ||
1231 | break; | ||
1232 | } | ||
1233 | } | ||
1234 | |||
1235 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
1236 | { | ||
1237 | } | ||
1238 | |||
1239 | static void sd_close(struct gspca_dev *gspca_dev) | ||
1240 | { | ||
1241 | } | ||
1242 | |||
1243 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | ||
1244 | struct gspca_frame *frame, /* target */ | ||
1245 | unsigned char *data, /* isoc packet */ | ||
1246 | int len) /* iso packet length */ | ||
1247 | { | ||
1248 | struct sd *sd = (struct sd *) gspca_dev; | ||
1249 | int i, sof = 0; | ||
1250 | unsigned char *s, *d; | ||
1251 | static unsigned char ffd9[] = {0xff, 0xd9}; | ||
1252 | |||
1253 | /* frames are jpeg 4.1.1 without 0xff escape */ | ||
1254 | switch (sd->bridge) { | ||
1255 | case BRIDGE_SPCA533: | ||
1256 | if (data[0] == 0xff) { | ||
1257 | if (data[1] != 0x01) { /* drop packet */ | ||
1258 | /* gspca_dev->last_packet_type = DISCARD_PACKET; */ | ||
1259 | return; | ||
1260 | } | ||
1261 | sof = 1; | ||
1262 | data += SPCA533_OFFSET_DATA; | ||
1263 | len -= SPCA533_OFFSET_DATA; | ||
1264 | } else { | ||
1265 | data += 1; | ||
1266 | len -= 1; | ||
1267 | } | ||
1268 | break; | ||
1269 | case BRIDGE_SPCA536: | ||
1270 | if (data[0] == 0xff) { | ||
1271 | sof = 1; | ||
1272 | data += SPCA536_OFFSET_DATA; | ||
1273 | len -= SPCA536_OFFSET_DATA; | ||
1274 | } else { | ||
1275 | data += 2; | ||
1276 | len -= 2; | ||
1277 | } | ||
1278 | break; | ||
1279 | default: | ||
1280 | /* case BRIDGE_SPCA504: */ | ||
1281 | /* case BRIDGE_SPCA504B: */ | ||
1282 | switch (data[0]) { | ||
1283 | case 0xfe: /* start of frame */ | ||
1284 | sof = 1; | ||
1285 | data += SPCA50X_OFFSET_DATA; | ||
1286 | len -= SPCA50X_OFFSET_DATA; | ||
1287 | break; | ||
1288 | case 0xff: /* drop packet */ | ||
1289 | /* gspca_dev->last_packet_type = DISCARD_PACKET; */ | ||
1290 | return; | ||
1291 | default: | ||
1292 | data += 1; | ||
1293 | len -= 1; | ||
1294 | break; | ||
1295 | } | ||
1296 | break; | ||
1297 | case BRIDGE_SPCA504C: | ||
1298 | switch (data[0]) { | ||
1299 | case 0xfe: /* start of frame */ | ||
1300 | sof = 1; | ||
1301 | data += SPCA504_PCCAM600_OFFSET_DATA; | ||
1302 | len -= SPCA504_PCCAM600_OFFSET_DATA; | ||
1303 | break; | ||
1304 | case 0xff: /* drop packet */ | ||
1305 | /* gspca_dev->last_packet_type = DISCARD_PACKET; */ | ||
1306 | return; | ||
1307 | default: | ||
1308 | data += 1; | ||
1309 | len -= 1; | ||
1310 | break; | ||
1311 | } | ||
1312 | break; | ||
1313 | } | ||
1314 | if (sof) { /* start of frame */ | ||
1315 | frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, | ||
1316 | ffd9, 2); | ||
1317 | |||
1318 | /* put the JPEG header in the new frame */ | ||
1319 | jpeg_put_header(gspca_dev, frame, | ||
1320 | ((struct sd *) gspca_dev)->qindex, | ||
1321 | 0x22); | ||
1322 | } | ||
1323 | |||
1324 | /* add 0x00 after 0xff */ | ||
1325 | for (i = len; --i >= 0; ) | ||
1326 | if (data[i] == 0xff) | ||
1327 | break; | ||
1328 | if (i < 0) { /* no 0xff */ | ||
1329 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); | ||
1330 | return; | ||
1331 | } | ||
1332 | s = data; | ||
1333 | d = sd->packet; | ||
1334 | for (i = 0; i < len; i++) { | ||
1335 | *d++ = *s++; | ||
1336 | if (s[-1] == 0xff) | ||
1337 | *d++ = 0x00; | ||
1338 | } | ||
1339 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, | ||
1340 | sd->packet, d - sd->packet); | ||
1341 | } | ||
1342 | |||
1343 | static void setbrightness(struct gspca_dev *gspca_dev) | ||
1344 | { | ||
1345 | struct sd *sd = (struct sd *) gspca_dev; | ||
1346 | struct usb_device *dev = gspca_dev->dev; | ||
1347 | |||
1348 | switch (sd->bridge) { | ||
1349 | default: | ||
1350 | /* case BRIDGE_SPCA533: */ | ||
1351 | /* case BRIDGE_SPCA504B: */ | ||
1352 | /* case BRIDGE_SPCA504: */ | ||
1353 | /* case BRIDGE_SPCA504C: */ | ||
1354 | reg_write(dev, 0x0, 0x21a7, sd->brightness); | ||
1355 | break; | ||
1356 | case BRIDGE_SPCA536: | ||
1357 | reg_write(dev, 0x0, 0x20f0, sd->brightness); | ||
1358 | break; | ||
1359 | } | ||
1360 | } | ||
1361 | |||
1362 | static void getbrightness(struct gspca_dev *gspca_dev) | ||
1363 | { | ||
1364 | struct sd *sd = (struct sd *) gspca_dev; | ||
1365 | struct usb_device *dev = gspca_dev->dev; | ||
1366 | __u16 brightness = 0; | ||
1367 | |||
1368 | switch (sd->bridge) { | ||
1369 | default: | ||
1370 | /* case BRIDGE_SPCA533: */ | ||
1371 | /* case BRIDGE_SPCA504B: */ | ||
1372 | /* case BRIDGE_SPCA504: */ | ||
1373 | /* case BRIDGE_SPCA504C: */ | ||
1374 | brightness = reg_read(dev, 0x0, 0x21a7, 2); | ||
1375 | break; | ||
1376 | case BRIDGE_SPCA536: | ||
1377 | brightness = reg_read(dev, 0x0, 0x20f0, 2); | ||
1378 | break; | ||
1379 | } | ||
1380 | sd->brightness = ((brightness & 0xff) - 128) % 255; | ||
1381 | } | ||
1382 | |||
1383 | static void setcontrast(struct gspca_dev *gspca_dev) | ||
1384 | { | ||
1385 | struct sd *sd = (struct sd *) gspca_dev; | ||
1386 | struct usb_device *dev = gspca_dev->dev; | ||
1387 | |||
1388 | switch (sd->bridge) { | ||
1389 | default: | ||
1390 | /* case BRIDGE_SPCA533: */ | ||
1391 | /* case BRIDGE_SPCA504B: */ | ||
1392 | /* case BRIDGE_SPCA504: */ | ||
1393 | /* case BRIDGE_SPCA504C: */ | ||
1394 | reg_write(dev, 0x0, 0x21a8, sd->contrast); | ||
1395 | break; | ||
1396 | case BRIDGE_SPCA536: | ||
1397 | reg_write(dev, 0x0, 0x20f1, sd->contrast); | ||
1398 | break; | ||
1399 | } | ||
1400 | } | ||
1401 | |||
1402 | static void getcontrast(struct gspca_dev *gspca_dev) | ||
1403 | { | ||
1404 | struct sd *sd = (struct sd *) gspca_dev; | ||
1405 | struct usb_device *dev = gspca_dev->dev; | ||
1406 | |||
1407 | switch (sd->bridge) { | ||
1408 | default: | ||
1409 | /* case BRIDGE_SPCA533: */ | ||
1410 | /* case BRIDGE_SPCA504B: */ | ||
1411 | /* case BRIDGE_SPCA504: */ | ||
1412 | /* case BRIDGE_SPCA504C: */ | ||
1413 | sd->contrast = reg_read(dev, 0x0, 0x21a8, 2); | ||
1414 | break; | ||
1415 | case BRIDGE_SPCA536: | ||
1416 | sd->contrast = reg_read(dev, 0x0, 0x20f1, 2); | ||
1417 | break; | ||
1418 | } | ||
1419 | } | ||
1420 | |||
1421 | static void setcolors(struct gspca_dev *gspca_dev) | ||
1422 | { | ||
1423 | struct sd *sd = (struct sd *) gspca_dev; | ||
1424 | struct usb_device *dev = gspca_dev->dev; | ||
1425 | |||
1426 | switch (sd->bridge) { | ||
1427 | default: | ||
1428 | /* case BRIDGE_SPCA533: */ | ||
1429 | /* case BRIDGE_SPCA504B: */ | ||
1430 | /* case BRIDGE_SPCA504: */ | ||
1431 | /* case BRIDGE_SPCA504C: */ | ||
1432 | reg_write(dev, 0x0, 0x21ae, sd->colors); | ||
1433 | break; | ||
1434 | case BRIDGE_SPCA536: | ||
1435 | reg_write(dev, 0x0, 0x20f6, sd->colors); | ||
1436 | break; | ||
1437 | } | ||
1438 | } | ||
1439 | |||
1440 | static void getcolors(struct gspca_dev *gspca_dev) | ||
1441 | { | ||
1442 | struct sd *sd = (struct sd *) gspca_dev; | ||
1443 | struct usb_device *dev = gspca_dev->dev; | ||
1444 | |||
1445 | switch (sd->bridge) { | ||
1446 | default: | ||
1447 | /* case BRIDGE_SPCA533: */ | ||
1448 | /* case BRIDGE_SPCA504B: */ | ||
1449 | /* case BRIDGE_SPCA504: */ | ||
1450 | /* case BRIDGE_SPCA504C: */ | ||
1451 | sd->colors = reg_read(dev, 0x0, 0x21ae, 2) >> 1; | ||
1452 | break; | ||
1453 | case BRIDGE_SPCA536: | ||
1454 | sd->colors = reg_read(dev, 0x0, 0x20f6, 2) >> 1; | ||
1455 | break; | ||
1456 | } | ||
1457 | } | ||
1458 | |||
1459 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | ||
1460 | { | ||
1461 | struct sd *sd = (struct sd *) gspca_dev; | ||
1462 | |||
1463 | sd->brightness = val; | ||
1464 | if (gspca_dev->streaming) | ||
1465 | setbrightness(gspca_dev); | ||
1466 | return 0; | ||
1467 | } | ||
1468 | |||
1469 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
1470 | { | ||
1471 | struct sd *sd = (struct sd *) gspca_dev; | ||
1472 | |||
1473 | getbrightness(gspca_dev); | ||
1474 | *val = sd->brightness; | ||
1475 | return 0; | ||
1476 | } | ||
1477 | |||
1478 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | ||
1479 | { | ||
1480 | struct sd *sd = (struct sd *) gspca_dev; | ||
1481 | |||
1482 | sd->contrast = val; | ||
1483 | if (gspca_dev->streaming) | ||
1484 | setcontrast(gspca_dev); | ||
1485 | return 0; | ||
1486 | } | ||
1487 | |||
1488 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) | ||
1489 | { | ||
1490 | struct sd *sd = (struct sd *) gspca_dev; | ||
1491 | |||
1492 | getcontrast(gspca_dev); | ||
1493 | *val = sd->contrast; | ||
1494 | return 0; | ||
1495 | } | ||
1496 | |||
1497 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) | ||
1498 | { | ||
1499 | struct sd *sd = (struct sd *) gspca_dev; | ||
1500 | |||
1501 | sd->colors = val; | ||
1502 | if (gspca_dev->streaming) | ||
1503 | setcolors(gspca_dev); | ||
1504 | return 0; | ||
1505 | } | ||
1506 | |||
1507 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) | ||
1508 | { | ||
1509 | struct sd *sd = (struct sd *) gspca_dev; | ||
1510 | |||
1511 | getcolors(gspca_dev); | ||
1512 | *val = sd->colors; | ||
1513 | return 0; | ||
1514 | } | ||
1515 | |||
1516 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) | ||
1517 | { | ||
1518 | struct sd *sd = (struct sd *) gspca_dev; | ||
1519 | |||
1520 | sd->autogain = val; | ||
1521 | return 0; | ||
1522 | } | ||
1523 | |||
1524 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) | ||
1525 | { | ||
1526 | struct sd *sd = (struct sd *) gspca_dev; | ||
1527 | |||
1528 | *val = sd->autogain; | ||
1529 | return 0; | ||
1530 | } | ||
1531 | |||
1532 | /* sub-driver description */ | ||
1533 | static struct sd_desc sd_desc = { | ||
1534 | .name = MODULE_NAME, | ||
1535 | .ctrls = sd_ctrls, | ||
1536 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
1537 | .config = sd_config, | ||
1538 | .open = sd_open, | ||
1539 | .start = sd_start, | ||
1540 | .stopN = sd_stopN, | ||
1541 | .stop0 = sd_stop0, | ||
1542 | .close = sd_close, | ||
1543 | .pkt_scan = sd_pkt_scan, | ||
1544 | }; | ||
1545 | |||
1546 | /* -- module initialisation -- */ | ||
1547 | #define DVNM(name) .driver_info = (kernel_ulong_t) name | ||
1548 | static __devinitdata struct usb_device_id device_table[] = { | ||
1549 | {USB_DEVICE(0x041e, 0x400b), DVNM("Creative PC-CAM 600")}, | ||
1550 | {USB_DEVICE(0x041e, 0x4012), DVNM("PC-Cam350")}, | ||
1551 | {USB_DEVICE(0x041e, 0x4013), DVNM("Creative Pccam750")}, | ||
1552 | {USB_DEVICE(0x0458, 0x7006), DVNM("Genius Dsc 1.3 Smart")}, | ||
1553 | {USB_DEVICE(0x046d, 0x0905), DVNM("Logitech ClickSmart 820")}, | ||
1554 | {USB_DEVICE(0x046d, 0x0960), DVNM("Logitech ClickSmart 420")}, | ||
1555 | {USB_DEVICE(0x0471, 0x0322), DVNM("Philips DMVC1300K")}, | ||
1556 | {USB_DEVICE(0x04a5, 0x3003), DVNM("Benq DC 1300")}, | ||
1557 | {USB_DEVICE(0x04a5, 0x3008), DVNM("Benq DC 1500")}, | ||
1558 | {USB_DEVICE(0x04a5, 0x300a), DVNM("Benq DC3410")}, | ||
1559 | {USB_DEVICE(0x04f1, 0x1001), DVNM("JVC GC A50")}, | ||
1560 | {USB_DEVICE(0x04fc, 0x500c), DVNM("Sunplus CA500C")}, | ||
1561 | {USB_DEVICE(0x04fc, 0x504a), DVNM("Aiptek Mini PenCam 1.3")}, | ||
1562 | {USB_DEVICE(0x04fc, 0x504b), DVNM("Maxell MaxPocket LE 1.3")}, | ||
1563 | {USB_DEVICE(0x04fc, 0x5330), DVNM("Digitrex 2110")}, | ||
1564 | {USB_DEVICE(0x04fc, 0x5360), DVNM("Sunplus Generic")}, | ||
1565 | {USB_DEVICE(0x04fc, 0xffff), DVNM("Pure DigitalDakota")}, | ||
1566 | {USB_DEVICE(0x052b, 0x1513), DVNM("Megapix V4")}, | ||
1567 | {USB_DEVICE(0x0546, 0x3155), DVNM("Polaroid PDC3070")}, | ||
1568 | {USB_DEVICE(0x0546, 0x3191), DVNM("Polaroid Ion 80")}, | ||
1569 | {USB_DEVICE(0x0546, 0x3273), DVNM("Polaroid PDC2030")}, | ||
1570 | {USB_DEVICE(0x055f, 0xc211), DVNM("Kowa Bs888e Microcamera")}, | ||
1571 | {USB_DEVICE(0x055f, 0xc230), DVNM("Mustek Digicam 330K")}, | ||
1572 | {USB_DEVICE(0x055f, 0xc232), DVNM("Mustek MDC3500")}, | ||
1573 | {USB_DEVICE(0x055f, 0xc360), DVNM("Mustek DV4000 Mpeg4 ")}, | ||
1574 | {USB_DEVICE(0x055f, 0xc420), DVNM("Mustek gSmart Mini 2")}, | ||
1575 | {USB_DEVICE(0x055f, 0xc430), DVNM("Mustek Gsmart LCD 2")}, | ||
1576 | {USB_DEVICE(0x055f, 0xc440), DVNM("Mustek DV 3000")}, | ||
1577 | {USB_DEVICE(0x055f, 0xc520), DVNM("Mustek gSmart Mini 3")}, | ||
1578 | {USB_DEVICE(0x055f, 0xc530), DVNM("Mustek Gsmart LCD 3")}, | ||
1579 | {USB_DEVICE(0x055f, 0xc540), DVNM("Gsmart D30")}, | ||
1580 | {USB_DEVICE(0x055f, 0xc630), DVNM("Mustek MDC4000")}, | ||
1581 | {USB_DEVICE(0x055f, 0xc650), DVNM("Mustek MDC5500Z")}, | ||
1582 | {USB_DEVICE(0x05da, 0x1018), DVNM("Digital Dream Enigma 1.3")}, | ||
1583 | {USB_DEVICE(0x06d6, 0x0031), DVNM("Trust 610 LCD PowerC@m Zoom")}, | ||
1584 | {USB_DEVICE(0x0733, 0x1311), DVNM("Digital Dream Epsilon 1.3")}, | ||
1585 | {USB_DEVICE(0x0733, 0x1314), DVNM("Mercury 2.1MEG Deluxe Classic Cam")}, | ||
1586 | {USB_DEVICE(0x0733, 0x2211), DVNM("Jenoptik jdc 21 LCD")}, | ||
1587 | {USB_DEVICE(0x0733, 0x2221), DVNM("Mercury Digital Pro 3.1p")}, | ||
1588 | {USB_DEVICE(0x0733, 0x3261), DVNM("Concord 3045 spca536a")}, | ||
1589 | {USB_DEVICE(0x0733, 0x3281), DVNM("Cyberpix S550V")}, | ||
1590 | {USB_DEVICE(0x08ca, 0x0104), DVNM("Aiptek PocketDVII 1.3")}, | ||
1591 | {USB_DEVICE(0x08ca, 0x0106), DVNM("Aiptek Pocket DV3100+")}, | ||
1592 | {USB_DEVICE(0x08ca, 0x2008), DVNM("Aiptek Mini PenCam 2 M")}, | ||
1593 | {USB_DEVICE(0x08ca, 0x2010), DVNM("Aiptek PocketCam 3M")}, | ||
1594 | {USB_DEVICE(0x08ca, 0x2016), DVNM("Aiptek PocketCam 2 Mega")}, | ||
1595 | {USB_DEVICE(0x08ca, 0x2018), DVNM("Aiptek Pencam SD 2M")}, | ||
1596 | {USB_DEVICE(0x08ca, 0x2020), DVNM("Aiptek Slim 3000F")}, | ||
1597 | {USB_DEVICE(0x08ca, 0x2022), DVNM("Aiptek Slim 3200")}, | ||
1598 | {USB_DEVICE(0x08ca, 0x2024), DVNM("Aiptek DV3500 Mpeg4 ")}, | ||
1599 | {USB_DEVICE(0x08ca, 0x2028), DVNM("Aiptek PocketCam4M")}, | ||
1600 | {USB_DEVICE(0x08ca, 0x2040), DVNM("Aiptek PocketDV4100M")}, | ||
1601 | {USB_DEVICE(0x08ca, 0x2042), DVNM("Aiptek PocketDV5100")}, | ||
1602 | {USB_DEVICE(0x08ca, 0x2060), DVNM("Aiptek PocketDV5300")}, | ||
1603 | {USB_DEVICE(0x0d64, 0x0303), DVNM("Sunplus FashionCam DXG")}, | ||
1604 | {} | ||
1605 | }; | ||
1606 | MODULE_DEVICE_TABLE(usb, device_table); | ||
1607 | |||
1608 | /* -- device connect -- */ | ||
1609 | static int sd_probe(struct usb_interface *intf, | ||
1610 | const struct usb_device_id *id) | ||
1611 | { | ||
1612 | return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), | ||
1613 | THIS_MODULE); | ||
1614 | } | ||
1615 | |||
1616 | static struct usb_driver sd_driver = { | ||
1617 | .name = MODULE_NAME, | ||
1618 | .id_table = device_table, | ||
1619 | .probe = sd_probe, | ||
1620 | .disconnect = gspca_disconnect, | ||
1621 | }; | ||
1622 | |||
1623 | /* -- module insert / remove -- */ | ||
1624 | static int __init sd_mod_init(void) | ||
1625 | { | ||
1626 | if (usb_register(&sd_driver) < 0) | ||
1627 | return -1; | ||
1628 | PDEBUG(D_PROBE, "v%s registered", version); | ||
1629 | return 0; | ||
1630 | } | ||
1631 | static void __exit sd_mod_exit(void) | ||
1632 | { | ||
1633 | usb_deregister(&sd_driver); | ||
1634 | PDEBUG(D_PROBE, "deregistered"); | ||
1635 | } | ||
1636 | |||
1637 | module_init(sd_mod_init); | ||
1638 | module_exit(sd_mod_exit); | ||
diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c new file mode 100644 index 000000000000..c22b301ebae0 --- /dev/null +++ b/drivers/media/video/gspca/t613.c | |||
@@ -0,0 +1,1013 @@ | |||
1 | /* | ||
2 | *Notes: * t613 + tas5130A | ||
3 | * * Focus to light do not balance well as in win. | ||
4 | * Quality in win is not good, but its kinda better. | ||
5 | * * Fix some "extraneous bytes", most of apps will show the image anyway | ||
6 | * * Gamma table, is there, but its really doing something? | ||
7 | * * 7~8 Fps, its ok, max on win its 10. | ||
8 | * Costantino Leandro | ||
9 | * | ||
10 | * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify | ||
13 | * it under the terms of the GNU General Public License as published by | ||
14 | * the Free Software Foundation; either version 2 of the License, or | ||
15 | * any later version. | ||
16 | * | ||
17 | * This program is distributed in the hope that it will be useful, | ||
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
20 | * GNU General Public License for more details. | ||
21 | * | ||
22 | * You should have received a copy of the GNU General Public License | ||
23 | * along with this program; if not, write to the Free Software | ||
24 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
25 | */ | ||
26 | |||
27 | #define MODULE_NAME "t613" | ||
28 | #include "gspca.h" | ||
29 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) | ||
30 | static const char version[] = "2.1.0"; | ||
31 | |||
32 | struct control_menu_info { | ||
33 | int value; | ||
34 | char name[32]; | ||
35 | }; | ||
36 | |||
37 | #define MAX_GAMMA 0x10 /* 0 to 15 */ | ||
38 | |||
39 | /* From LUVCVIEW */ | ||
40 | #define V4L2_CID_EFFECTS (V4L2_CID_PRIVATE_BASE + 3) | ||
41 | |||
42 | MODULE_AUTHOR("Leandro Costantino <le_costantino@pixartargentina.com.ar>"); | ||
43 | MODULE_DESCRIPTION("GSPCA/T613 (JPEG Compliance) USB Camera Driver"); | ||
44 | MODULE_LICENSE("GPL"); | ||
45 | |||
46 | struct sd { | ||
47 | struct gspca_dev gspca_dev; /* !! must be the first item */ | ||
48 | |||
49 | unsigned char brightness; | ||
50 | unsigned char contrast; | ||
51 | unsigned char colors; | ||
52 | unsigned char autogain; | ||
53 | unsigned char gamma; | ||
54 | unsigned char sharpness; | ||
55 | unsigned char freq; | ||
56 | unsigned char whitebalance; | ||
57 | unsigned char mirror; | ||
58 | unsigned char effect; | ||
59 | }; | ||
60 | |||
61 | /* V4L2 controls supported by the driver */ | ||
62 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
63 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
64 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | ||
65 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | ||
66 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); | ||
67 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); | ||
68 | static int sd_setlowlight(struct gspca_dev *gspca_dev, __s32 val); | ||
69 | static int sd_getlowlight(struct gspca_dev *gspca_dev, __s32 *val); | ||
70 | static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val); | ||
71 | static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val); | ||
72 | static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val); | ||
73 | static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val); | ||
74 | static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); | ||
75 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); | ||
76 | static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val); | ||
77 | static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val); | ||
78 | static int sd_setflip(struct gspca_dev *gspca_dev, __s32 val); | ||
79 | static int sd_getflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
80 | static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val); | ||
81 | static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val); | ||
82 | static int sd_querymenu(struct gspca_dev *gspca_dev, | ||
83 | struct v4l2_querymenu *menu); | ||
84 | |||
85 | static struct ctrl sd_ctrls[] = { | ||
86 | #define SD_BRIGHTNESS 0 | ||
87 | { | ||
88 | { | ||
89 | .id = V4L2_CID_BRIGHTNESS, | ||
90 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
91 | .name = "Brightness", | ||
92 | .minimum = 0, | ||
93 | .maximum = 0x0f, | ||
94 | .step = 1, | ||
95 | .default_value = 0x09, | ||
96 | }, | ||
97 | .set = sd_setbrightness, | ||
98 | .get = sd_getbrightness, | ||
99 | }, | ||
100 | #define SD_CONTRAST 1 | ||
101 | { | ||
102 | { | ||
103 | .id = V4L2_CID_CONTRAST, | ||
104 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
105 | .name = "Contrast", | ||
106 | .minimum = 0, | ||
107 | .maximum = 0x0d, | ||
108 | .step = 1, | ||
109 | .default_value = 0x07, | ||
110 | }, | ||
111 | .set = sd_setcontrast, | ||
112 | .get = sd_getcontrast, | ||
113 | }, | ||
114 | #define SD_COLOR 2 | ||
115 | { | ||
116 | { | ||
117 | .id = V4L2_CID_SATURATION, | ||
118 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
119 | .name = "Color", | ||
120 | .minimum = 0, | ||
121 | .maximum = 0x0f, | ||
122 | .step = 1, | ||
123 | .default_value = 0x05, | ||
124 | }, | ||
125 | .set = sd_setcolors, | ||
126 | .get = sd_getcolors, | ||
127 | }, | ||
128 | #define SD_GAMMA 3 | ||
129 | { | ||
130 | { | ||
131 | .id = V4L2_CID_GAMMA, /* (gamma on win) */ | ||
132 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
133 | .name = "Gamma (Untested)", | ||
134 | .minimum = 0, | ||
135 | .maximum = MAX_GAMMA, | ||
136 | .step = 1, | ||
137 | .default_value = 0x09, | ||
138 | }, | ||
139 | .set = sd_setgamma, | ||
140 | .get = sd_getgamma, | ||
141 | }, | ||
142 | #define SD_AUTOGAIN 4 | ||
143 | { | ||
144 | { | ||
145 | .id = V4L2_CID_GAIN, /* here, i activate only the lowlight, | ||
146 | * some apps dont bring up the | ||
147 | * backligth_compensation control) */ | ||
148 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
149 | .name = "Low Light", | ||
150 | .minimum = 0, | ||
151 | .maximum = 1, | ||
152 | .step = 1, | ||
153 | .default_value = 0x01, | ||
154 | }, | ||
155 | .set = sd_setlowlight, | ||
156 | .get = sd_getlowlight, | ||
157 | }, | ||
158 | #define SD_MIRROR 5 | ||
159 | { | ||
160 | { | ||
161 | .id = V4L2_CID_HFLIP, | ||
162 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
163 | .name = "Mirror Image", | ||
164 | .minimum = 0, | ||
165 | .maximum = 1, | ||
166 | .step = 1, | ||
167 | .default_value = 0, | ||
168 | }, | ||
169 | .set = sd_setflip, | ||
170 | .get = sd_getflip | ||
171 | }, | ||
172 | #define SD_LIGHTFREQ 6 | ||
173 | { | ||
174 | { | ||
175 | .id = V4L2_CID_POWER_LINE_FREQUENCY, | ||
176 | .type = V4L2_CTRL_TYPE_MENU, | ||
177 | .name = "Light Frequency Filter", | ||
178 | .minimum = 1, /* 1 -> 0x50, 2->0x60 */ | ||
179 | .maximum = 2, | ||
180 | .step = 1, | ||
181 | .default_value = 1, | ||
182 | }, | ||
183 | .set = sd_setfreq, | ||
184 | .get = sd_getfreq}, | ||
185 | |||
186 | #define SD_WHITE_BALANCE 7 | ||
187 | { | ||
188 | { | ||
189 | .id = V4L2_CID_WHITE_BALANCE_TEMPERATURE, | ||
190 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
191 | .name = "White Balance", | ||
192 | .minimum = 0, | ||
193 | .maximum = 1, | ||
194 | .step = 1, | ||
195 | .default_value = 1, | ||
196 | }, | ||
197 | .set = sd_setwhitebalance, | ||
198 | .get = sd_getwhitebalance | ||
199 | }, | ||
200 | #define SD_SHARPNESS 8 /* (aka definition on win) */ | ||
201 | { | ||
202 | { | ||
203 | .id = V4L2_CID_SHARPNESS, | ||
204 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
205 | .name = "Sharpness", | ||
206 | .minimum = 0, | ||
207 | .maximum = MAX_GAMMA, /* 0 to 16 */ | ||
208 | .step = 1, | ||
209 | .default_value = 0x06, | ||
210 | }, | ||
211 | .set = sd_setsharpness, | ||
212 | .get = sd_getsharpness, | ||
213 | }, | ||
214 | #define SD_EFFECTS 9 | ||
215 | { | ||
216 | { | ||
217 | .id = V4L2_CID_EFFECTS, | ||
218 | .type = V4L2_CTRL_TYPE_MENU, | ||
219 | .name = "Webcam Effects", | ||
220 | .minimum = 0, | ||
221 | .maximum = 4, | ||
222 | .step = 1, | ||
223 | .default_value = 0, | ||
224 | }, | ||
225 | .set = sd_seteffect, | ||
226 | .get = sd_geteffect | ||
227 | }, | ||
228 | }; | ||
229 | |||
230 | static struct control_menu_info effects_control[] = { | ||
231 | {0, "Normal"}, | ||
232 | {1, "Emboss"}, /* disabled */ | ||
233 | {2, "Monochrome"}, | ||
234 | {3, "Sepia"}, | ||
235 | {4, "Sketch"}, | ||
236 | {5, "Sun Effect"}, /* disabled */ | ||
237 | {6, "Negative"}, | ||
238 | }; | ||
239 | |||
240 | #define NUM_EFFECTS_CONTROL \ | ||
241 | (sizeof(effects_control)/sizeof(effects_control[0])) | ||
242 | |||
243 | static struct cam_mode vga_mode_t16[] = { | ||
244 | {V4L2_PIX_FMT_JPEG, 160, 120, 4}, | ||
245 | {V4L2_PIX_FMT_JPEG, 176, 144, 3}, | ||
246 | {V4L2_PIX_FMT_JPEG, 320, 240, 2}, | ||
247 | {V4L2_PIX_FMT_JPEG, 352, 288, 1}, | ||
248 | {V4L2_PIX_FMT_JPEG, 640, 480, 0}, | ||
249 | }; | ||
250 | |||
251 | #define T16_OFFSET_DATA 631 | ||
252 | #define MAX_EFFECTS 7 | ||
253 | /* easily done by soft, this table could be removed, | ||
254 | * i keep it here just in case */ | ||
255 | unsigned char effects_table[MAX_EFFECTS][6] = { | ||
256 | {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x00}, /* Normal */ | ||
257 | {0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x04}, /* Repujar */ | ||
258 | {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x20}, /* Monochrome */ | ||
259 | {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x80}, /* Sepia */ | ||
260 | {0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x02}, /* Croquis */ | ||
261 | {0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x10}, /* Sun Effect */ | ||
262 | {0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x40}, /* Negative */ | ||
263 | }; | ||
264 | |||
265 | unsigned char gamma_table[MAX_GAMMA][34] = { | ||
266 | {0x90, 0x00, 0x91, 0x3e, 0x92, 0x69, 0x93, 0x85, | ||
267 | 0x94, 0x95, 0x95, 0xa1, 0x96, 0xae, 0x97, 0xb9, | ||
268 | 0x98, 0xc2, 0x99, 0xcb, 0x9a, 0xd4, 0x9b, 0xdb, | ||
269 | 0x9c, 0xe3, 0x9d, 0xea, 0x9e, 0xf1, 0x9f, 0xf8, | ||
270 | 0xa0, 0xff}, | ||
271 | {0x90, 0x00, 0x91, 0x33, 0x92, 0x5A, 0x93, 0x75, | ||
272 | 0x94, 0x85, 0x95, 0x93, 0x96, 0xA1, 0x97, 0xAD, | ||
273 | 0x98, 0xB7, 0x99, 0xC2, 0x9A, 0xCB, 0x9B, 0xD4, | ||
274 | 0x9C, 0xDE, 0x9D, 0xE7, 0x9E, 0xF0, 0x9F, 0xF7, | ||
275 | 0xa0, 0xff}, | ||
276 | {0x90, 0x00, 0x91, 0x2F, 0x92, 0x51, 0x93, 0x6B, | ||
277 | 0x94, 0x7C, 0x95, 0x8A, 0x96, 0x99, 0x97, 0xA6, | ||
278 | 0x98, 0xB1, 0x99, 0xBC, 0x9A, 0xC6, 0x9B, 0xD0, | ||
279 | 0x9C, 0xDB, 0x9D, 0xE4, 0x9E, 0xED, 0x9F, 0xF6, | ||
280 | 0xa0, 0xff}, | ||
281 | {0x90, 0x00, 0x91, 0x29, 0x92, 0x48, 0x93, 0x60, | ||
282 | 0x94, 0x72, 0x95, 0x81, 0x96, 0x90, 0x97, 0x9E, | ||
283 | 0x98, 0xAA, 0x99, 0xB5, 0x9A, 0xBF, 0x9B, 0xCB, | ||
284 | 0x9C, 0xD6, 0x9D, 0xE1, 0x9E, 0xEB, 0x9F, 0xF5, | ||
285 | 0xa0, 0xff}, | ||
286 | {0x90, 0x00, 0x91, 0x23, 0x92, 0x3F, 0x93, 0x55, | ||
287 | 0x94, 0x68, 0x95, 0x77, 0x96, 0x86, 0x97, 0x95, | ||
288 | 0x98, 0xA2, 0x99, 0xAD, 0x9A, 0xB9, 0x9B, 0xC6, | ||
289 | 0x9C, 0xD2, 0x9D, 0xDE, 0x9E, 0xE9, 0x9F, 0xF4, | ||
290 | 0xa0, 0xff}, | ||
291 | {0x90, 0x00, 0x91, 0x1B, 0x92, 0x33, 0x93, 0x48, | ||
292 | 0x94, 0x59, 0x95, 0x69, 0x96, 0x79, 0x97, 0x87, | ||
293 | 0x98, 0x96, 0x99, 0xA3, 0x9A, 0xB1, 0x9B, 0xBE, | ||
294 | 0x9C, 0xCC, 0x9D, 0xDA, 0x9E, 0xE7, 0x9F, 0xF3, | ||
295 | 0xa0, 0xff}, | ||
296 | {0x90, 0x00, 0x91, 0x02, 0x92, 0x10, 0x93, 0x20, | ||
297 | 0x94, 0x32, 0x95, 0x40, 0x96, 0x57, 0x97, 0x67, | ||
298 | 0x98, 0x77, 0x99, 0x88, 0x9a, 0x99, 0x9b, 0xaa, | ||
299 | 0x9c, 0xbb, 0x9d, 0xcc, 0x9e, 0xdd, 0x9f, 0xee, | ||
300 | 0xa0, 0xff}, | ||
301 | {0x90, 0x00, 0x91, 0x02, 0x92, 0x14, 0x93, 0x26, | ||
302 | 0x94, 0x38, 0x95, 0x4A, 0x96, 0x60, 0x97, 0x70, | ||
303 | 0x98, 0x80, 0x99, 0x90, 0x9A, 0xA0, 0x9B, 0xB0, | ||
304 | 0x9C, 0xC0, 0x9D, 0xD0, 0x9E, 0xE0, 0x9F, 0xF0, | ||
305 | 0xa0, 0xff}, | ||
306 | {0x90, 0x00, 0x91, 0x10, 0x92, 0x22, 0x93, 0x35, | ||
307 | 0x94, 0x47, 0x95, 0x5A, 0x96, 0x69, 0x97, 0x79, | ||
308 | 0x98, 0x88, 0x99, 0x97, 0x9A, 0xA7, 0x9B, 0xB6, | ||
309 | 0x9C, 0xC4, 0x9D, 0xD3, 0x9E, 0xE0, 0x9F, 0xF0, | ||
310 | 0xa0, 0xff}, | ||
311 | {0x90, 0x00, 0x91, 0x10, 0x92, 0x26, 0x93, 0x40, | ||
312 | 0x94, 0x54, 0x95, 0x65, 0x96, 0x75, 0x97, 0x84, | ||
313 | 0x98, 0x93, 0x99, 0xa1, 0x9a, 0xb0, 0x9b, 0xbd, | ||
314 | 0x9c, 0xca, 0x9d, 0xd6, 0x9e, 0xe0, 0x9f, 0xf0, | ||
315 | 0xa0, 0xff}, | ||
316 | {0x90, 0x00, 0x91, 0x18, 0x92, 0x2B, 0x93, 0x44, | ||
317 | 0x94, 0x60, 0x95, 0x70, 0x96, 0x80, 0x97, 0x8E, | ||
318 | 0x98, 0x9C, 0x99, 0xAA, 0x9A, 0xB7, 0x9B, 0xC4, | ||
319 | 0x9C, 0xD0, 0x9D, 0xD8, 0x9E, 0xE2, 0x9F, 0xF0, | ||
320 | 0xa0, 0xff}, | ||
321 | {0x90, 0x00, 0x91, 0x1A, 0x92, 0x34, 0x93, 0x52, | ||
322 | 0x94, 0x66, 0x95, 0x7E, 0x96, 0x8D, 0x97, 0x9B, | ||
323 | 0x98, 0xA8, 0x99, 0xB4, 0x9A, 0xC0, 0x9B, 0xCB, | ||
324 | 0x9C, 0xD6, 0x9D, 0xE1, 0x9E, 0xEB, 0x9F, 0xF5, | ||
325 | 0xa0, 0xff}, | ||
326 | {0x90, 0x00, 0x91, 0x3F, 0x92, 0x5A, 0x93, 0x6E, | ||
327 | 0x94, 0x7F, 0x95, 0x8E, 0x96, 0x9C, 0x97, 0xA8, | ||
328 | 0x98, 0xB4, 0x99, 0xBF, 0x9A, 0xC9, 0x9B, 0xD3, | ||
329 | 0x9C, 0xDC, 0x9D, 0xE5, 0x9E, 0xEE, 0x9F, 0xF6, | ||
330 | 0xA0, 0xFF}, | ||
331 | {0x90, 0x00, 0x91, 0x54, 0x92, 0x6F, 0x93, 0x83, | ||
332 | 0x94, 0x93, 0x95, 0xA0, 0x96, 0xAD, 0x97, 0xB7, | ||
333 | 0x98, 0xC2, 0x99, 0xCB, 0x9A, 0xD4, 0x9B, 0xDC, | ||
334 | 0x9C, 0xE4, 0x9D, 0xEB, 0x9E, 0xF2, 0x9F, 0xF9, | ||
335 | 0xa0, 0xff}, | ||
336 | {0x90, 0x00, 0x91, 0x6E, 0x92, 0x88, 0x93, 0x9A, | ||
337 | 0x94, 0xA8, 0x95, 0xB3, 0x96, 0xBD, 0x97, 0xC6, | ||
338 | 0x98, 0xCF, 0x99, 0xD6, 0x9A, 0xDD, 0x9B, 0xE3, | ||
339 | 0x9C, 0xE9, 0x9D, 0xEF, 0x9E, 0xF4, 0x9F, 0xFA, | ||
340 | 0xa0, 0xff}, | ||
341 | {0x90, 0x00, 0x91, 0x93, 0x92, 0xA8, 0x93, 0xB7, | ||
342 | 0x94, 0xC1, 0x95, 0xCA, 0x96, 0xD2, 0x97, 0xD8, | ||
343 | 0x98, 0xDE, 0x99, 0xE3, 0x9A, 0xE8, 0x9B, 0xED, | ||
344 | 0x9C, 0xF1, 0x9D, 0xF5, 0x9E, 0xF8, 0x9F, 0xFC, | ||
345 | 0xA0, 0xFF} | ||
346 | }; | ||
347 | |||
348 | static __u8 tas5130a_sensor_init[][8] = { | ||
349 | {0x62, 0x08, 0x63, 0x70, 0x64, 0x1d, 0x60, 0x09}, | ||
350 | {0x62, 0x20, 0x63, 0x01, 0x64, 0x02, 0x60, 0x09}, | ||
351 | {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09}, | ||
352 | {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09}, | ||
353 | {}, | ||
354 | }; | ||
355 | |||
356 | static void t16RegRead(struct usb_device *dev, | ||
357 | __u16 index, __u8 *buffer, __u16 length) | ||
358 | { | ||
359 | usb_control_msg(dev, | ||
360 | usb_rcvctrlpipe(dev, 0), | ||
361 | 0, /* request */ | ||
362 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
363 | 0, /* value */ | ||
364 | index, buffer, length, 500); | ||
365 | } | ||
366 | |||
367 | static void t16RegWrite(struct usb_device *dev, | ||
368 | __u16 value, | ||
369 | __u16 index, __u8 *buffer, __u16 length) | ||
370 | { | ||
371 | usb_control_msg(dev, | ||
372 | usb_sndctrlpipe(dev, 0), | ||
373 | 0, /* request */ | ||
374 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
375 | value, index, buffer, length, 500); | ||
376 | } | ||
377 | |||
378 | /* this function is called at probe time */ | ||
379 | static int sd_config(struct gspca_dev *gspca_dev, | ||
380 | const struct usb_device_id *id) | ||
381 | { | ||
382 | struct sd *sd = (struct sd *) gspca_dev; | ||
383 | struct cam *cam; | ||
384 | |||
385 | cam = &gspca_dev->cam; | ||
386 | cam->dev_name = (char *) id->driver_info; | ||
387 | cam->epaddr = 0x01; | ||
388 | |||
389 | cam->cam_mode = vga_mode_t16; | ||
390 | cam->nmodes = ARRAY_SIZE(vga_mode_t16); | ||
391 | |||
392 | sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; | ||
393 | sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; | ||
394 | sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; | ||
395 | sd->gamma = sd_ctrls[SD_GAMMA].qctrl.default_value; | ||
396 | sd->mirror = sd_ctrls[SD_MIRROR].qctrl.default_value; | ||
397 | sd->freq = sd_ctrls[SD_LIGHTFREQ].qctrl.default_value; | ||
398 | sd->whitebalance = sd_ctrls[SD_WHITE_BALANCE].qctrl.default_value; | ||
399 | sd->sharpness = sd_ctrls[SD_SHARPNESS].qctrl.default_value; | ||
400 | sd->effect = sd_ctrls[SD_EFFECTS].qctrl.default_value; | ||
401 | return 0; | ||
402 | } | ||
403 | |||
404 | static int init_default_parameters(struct gspca_dev *gspca_dev) | ||
405 | { | ||
406 | struct usb_device *dev = gspca_dev->dev; | ||
407 | |||
408 | /* some of this registers are not really neded, because | ||
409 | * they are overriden by setbrigthness, setcontrast, etc, | ||
410 | * but wont hurt anyway, and can help someone with similar webcam | ||
411 | * to see the initial parameters.*/ | ||
412 | int i = 0; | ||
413 | __u8 test_byte; | ||
414 | |||
415 | static unsigned char read_indexs[] = | ||
416 | { 0x06, 0x07, 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5, | ||
417 | 0xa6, 0xa8, 0xbb, 0xbc, 0xc6, 0x00, 0x00 }; | ||
418 | static unsigned char n1[6] = | ||
419 | {0x08, 0x03, 0x09, 0x03, 0x12, 0x04}; | ||
420 | static unsigned char n2[2] = | ||
421 | {0x08, 0x00}; | ||
422 | static unsigned char nset[6] = | ||
423 | { 0x61, 0x68, 0x62, 0xff, 0x60, 0x07 }; | ||
424 | static unsigned char n3[6] = | ||
425 | {0x61, 0x68, 0x65, 0x0a, 0x60, 0x04}; | ||
426 | static unsigned char n4[0x46] = | ||
427 | {0x09, 0x01, 0x12, 0x04, 0x66, 0x8a, 0x80, 0x3c, | ||
428 | 0x81, 0x22, 0x84, 0x50, 0x8a, 0x78, 0x8b, 0x68, | ||
429 | 0x8c, 0x88, 0x8e, 0x33, 0x8f, 0x24, 0xaa, 0xb1, | ||
430 | 0xa2, 0x60, 0xa5, 0x30, 0xa6, 0x3a, 0xa8, 0xe8, | ||
431 | 0xae, 0x05, 0xb1, 0x00, 0xbb, 0x04, 0xbc, 0x48, | ||
432 | 0xbe, 0x36, 0xc6, 0x88, 0xe9, 0x00, 0xc5, 0xc0, | ||
433 | 0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68, | ||
434 | 0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40, | ||
435 | 0xac, 0x84, 0xad, 0x86, 0xaf, 0x46}; | ||
436 | static unsigned char nset4[18] = { | ||
437 | 0xe0, 0x60, 0xe1, 0xa8, 0xe2, 0xe0, 0xe3, 0x60, 0xe4, 0xa8, | ||
438 | 0xe5, 0xe0, 0xe6, 0x60, 0xe7, 0xa8, | ||
439 | 0xe8, 0xe0 | ||
440 | }; | ||
441 | /* ojo puede ser 0xe6 en vez de 0xe9 */ | ||
442 | static unsigned char nset2[20] = { | ||
443 | 0xd0, 0xbb, 0xd1, 0x28, 0xd2, 0x10, 0xd3, 0x10, 0xd4, 0xbb, | ||
444 | 0xd5, 0x28, 0xd6, 0x1e, 0xd7, 0x27, | ||
445 | 0xd8, 0xc8, 0xd9, 0xfc | ||
446 | }; | ||
447 | static unsigned char missing[8] = | ||
448 | { 0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38 }; | ||
449 | static unsigned char nset3[18] = { | ||
450 | 0xc7, 0x60, 0xc8, 0xa8, 0xc9, 0xe0, 0xca, 0x60, 0xcb, 0xa8, | ||
451 | 0xcc, 0xe0, 0xcd, 0x60, 0xce, 0xa8, | ||
452 | 0xcf, 0xe0 | ||
453 | }; | ||
454 | static unsigned char nset5[4] = | ||
455 | { 0x8f, 0x24, 0xc3, 0x00 }; /* bright */ | ||
456 | static unsigned char nset6[34] = { | ||
457 | 0x90, 0x00, 0x91, 0x1c, 0x92, 0x30, 0x93, 0x43, 0x94, 0x54, | ||
458 | 0x95, 0x65, 0x96, 0x75, 0x97, 0x84, | ||
459 | 0x98, 0x93, 0x99, 0xa1, 0x9a, 0xb0, 0x9b, 0xbd, 0x9c, 0xca, | ||
460 | 0x9d, 0xd8, 0x9e, 0xe5, 0x9f, 0xf2, | ||
461 | 0xa0, 0xff | ||
462 | }; /* Gamma */ | ||
463 | static unsigned char nset7[4] = | ||
464 | { 0x66, 0xca, 0xa8, 0xf8 }; /* 50/60 Hz */ | ||
465 | static unsigned char nset9[4] = | ||
466 | { 0x0b, 0x04, 0x0a, 0x78 }; | ||
467 | static unsigned char nset8[6] = | ||
468 | { 0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00 }; | ||
469 | static unsigned char nset10[6] = | ||
470 | { 0x0c, 0x03, 0xab, 0x10, 0x81, 0x20 }; | ||
471 | |||
472 | t16RegWrite(dev, 0x01, 0x0000, n1, 0x06); | ||
473 | t16RegWrite(dev, 0x01, 0x0000, nset, 0x06); | ||
474 | t16RegRead(dev, 0x0063, &test_byte, 1); | ||
475 | t16RegWrite(dev, 0x01, 0x0000, n2, 0x02); | ||
476 | |||
477 | while (read_indexs[i] != 0x00) { | ||
478 | t16RegRead(dev, read_indexs[i], &test_byte, 1); | ||
479 | PDEBUG(D_CONF, "Reg 0x%x => 0x%x", read_indexs[i], | ||
480 | test_byte); | ||
481 | i++; | ||
482 | } | ||
483 | |||
484 | t16RegWrite(dev, 0x01, 0x0000, n3, 0x06); | ||
485 | t16RegWrite(dev, 0x01, 0x0000, n4, 0x46); | ||
486 | t16RegRead(dev, 0x0080, &test_byte, 1); | ||
487 | t16RegWrite(dev, 0x00, 0x2c80, 0x00, 0x0); | ||
488 | t16RegWrite(dev, 0x01, 0x0000, nset2, 0x14); | ||
489 | t16RegWrite(dev, 0x01, 0x0000, nset3, 0x12); | ||
490 | t16RegWrite(dev, 0x01, 0x0000, nset4, 0x12); | ||
491 | t16RegWrite(dev, 0x00, 0x3880, 0x00, 0x0); | ||
492 | t16RegWrite(dev, 0x00, 0x3880, 0x00, 0x0); | ||
493 | t16RegWrite(dev, 0x00, 0x338e, 0x00, 0x0); | ||
494 | t16RegWrite(dev, 0x01, 00, nset5, 0x04); | ||
495 | t16RegWrite(dev, 0x00, 0x00a9, 0x00, 0x0); | ||
496 | t16RegWrite(dev, 0x01, 00, nset6, 0x22); | ||
497 | t16RegWrite(dev, 0x00, 0x86bb, 0x00, 0x0); | ||
498 | t16RegWrite(dev, 0x00, 0x4aa6, 0x00, 0x0); | ||
499 | |||
500 | t16RegWrite(dev, 0x01, 00, missing, 0x08); | ||
501 | |||
502 | t16RegWrite(dev, 0x00, 0x2087, 0x00, 0x0); | ||
503 | t16RegWrite(dev, 0x00, 0x2088, 0x00, 0x0); | ||
504 | t16RegWrite(dev, 0x00, 0x2089, 0x00, 0x0); | ||
505 | |||
506 | t16RegWrite(dev, 0x01, 00, nset7, 0x4); | ||
507 | t16RegWrite(dev, 0x01, 00, nset10, 0x06); | ||
508 | t16RegWrite(dev, 0x01, 00, nset8, 0x06); | ||
509 | t16RegWrite(dev, 0x01, 00, nset9, 0x04); | ||
510 | |||
511 | t16RegWrite(dev, 0x00, 0x2880, 0x00, 0x0); | ||
512 | t16RegWrite(dev, 0x01, 0x0000, nset2, 0x14); | ||
513 | t16RegWrite(dev, 0x01, 0x0000, nset3, 0x12); | ||
514 | t16RegWrite(dev, 0x01, 0x0000, nset4, 0x12); | ||
515 | |||
516 | return 0; | ||
517 | } | ||
518 | |||
519 | static void setbrightness(struct gspca_dev *gspca_dev) | ||
520 | { | ||
521 | struct sd *sd = (struct sd *) gspca_dev; | ||
522 | struct usb_device *dev = gspca_dev->dev; | ||
523 | unsigned int brightness; | ||
524 | unsigned char set6[4] = { 0x8f, 0x26, 0xc3, 0x80 }; | ||
525 | brightness = sd->brightness; | ||
526 | |||
527 | if (brightness < 7) { | ||
528 | set6[3] = 0x70 - (brightness * 0xa); | ||
529 | } else { | ||
530 | set6[1] = 0x24; | ||
531 | set6[3] = 0x00 + ((brightness - 7) * 0xa); | ||
532 | } | ||
533 | |||
534 | t16RegWrite(dev, 0x01, 0x0000, set6, 4); | ||
535 | } | ||
536 | |||
537 | static void setflip(struct gspca_dev *gspca_dev) | ||
538 | { | ||
539 | struct sd *sd = (struct sd *) gspca_dev; | ||
540 | struct usb_device *dev = gspca_dev->dev; | ||
541 | |||
542 | unsigned char flipcmd[8] = | ||
543 | { 0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09 }; | ||
544 | |||
545 | if (sd->mirror == 1) | ||
546 | flipcmd[3] = 0x01; | ||
547 | |||
548 | t16RegWrite(dev, 0x01, 0x0000, flipcmd, 8); | ||
549 | } | ||
550 | |||
551 | static void seteffect(struct gspca_dev *gspca_dev) | ||
552 | { | ||
553 | struct sd *sd = (struct sd *) gspca_dev; | ||
554 | struct usb_device *dev = gspca_dev->dev; | ||
555 | |||
556 | t16RegWrite(dev, 0x01, 0x0000, effects_table[sd->effect], 0x06); | ||
557 | if (sd->effect == 1 || sd->effect == 5) { | ||
558 | PDEBUG(D_CONF, | ||
559 | "This effect have been disabled for webcam \"safety\""); | ||
560 | return; | ||
561 | } | ||
562 | |||
563 | if (sd->effect == 1 || sd->effect == 4) | ||
564 | t16RegWrite(dev, 0x00, 0x4aa6, 0x00, 0x00); | ||
565 | else | ||
566 | t16RegWrite(dev, 0x00, 0xfaa6, 0x00, 0x00); | ||
567 | } | ||
568 | |||
569 | static void setwhitebalance(struct gspca_dev *gspca_dev) | ||
570 | { | ||
571 | struct sd *sd = (struct sd *) gspca_dev; | ||
572 | struct usb_device *dev = gspca_dev->dev; | ||
573 | |||
574 | unsigned char white_balance[8] = | ||
575 | { 0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38 }; | ||
576 | |||
577 | if (sd->whitebalance == 1) | ||
578 | white_balance[7] = 0x3c; | ||
579 | |||
580 | t16RegWrite(dev, 0x01, 0x0000, white_balance, 8); | ||
581 | } | ||
582 | |||
583 | static void setlightfreq(struct gspca_dev *gspca_dev) | ||
584 | { | ||
585 | struct sd *sd = (struct sd *) gspca_dev; | ||
586 | struct usb_device *dev = gspca_dev->dev; | ||
587 | __u8 freq[4] = { 0x66, 0x40, 0xa8, 0xe8 }; | ||
588 | |||
589 | if (sd->freq == 2) /* 60hz */ | ||
590 | freq[1] = 0x00; | ||
591 | |||
592 | t16RegWrite(dev, 0x1, 0x0000, freq, 0x4); | ||
593 | } | ||
594 | |||
595 | static void setcontrast(struct gspca_dev *gspca_dev) | ||
596 | { | ||
597 | struct sd *sd = (struct sd *) gspca_dev; | ||
598 | struct usb_device *dev = gspca_dev->dev; | ||
599 | unsigned int contrast = sd->contrast; | ||
600 | __u16 reg_to_write = 0x00; | ||
601 | |||
602 | if (contrast < 7) | ||
603 | reg_to_write = 0x8ea9 - (0x200 * contrast); | ||
604 | else | ||
605 | reg_to_write = (0x00a9 + ((contrast - 7) * 0x200)); | ||
606 | |||
607 | t16RegWrite(dev, 0x00, reg_to_write, 0x00, 0); | ||
608 | |||
609 | } | ||
610 | |||
611 | static void setcolors(struct gspca_dev *gspca_dev) | ||
612 | { | ||
613 | struct sd *sd = (struct sd *) gspca_dev; | ||
614 | struct usb_device *dev = gspca_dev->dev; | ||
615 | __u16 reg_to_write = 0x00; | ||
616 | |||
617 | reg_to_write = 0xc0bb + sd->colors * 0x100; | ||
618 | t16RegWrite(dev, 0x00, reg_to_write, 0x00, 0); | ||
619 | } | ||
620 | |||
621 | static void setgamma(struct gspca_dev *gspca_dev) | ||
622 | { | ||
623 | } | ||
624 | |||
625 | static void setsharpness(struct gspca_dev *gspca_dev) | ||
626 | { | ||
627 | struct sd *sd = (struct sd *) gspca_dev; | ||
628 | struct usb_device *dev = gspca_dev->dev; | ||
629 | __u16 reg_to_write = 0x00; | ||
630 | |||
631 | reg_to_write = 0x0aa6 + 0x1000 * sd->sharpness; | ||
632 | |||
633 | t16RegWrite(dev, 0x00, reg_to_write, 0x00, 0x00); | ||
634 | } | ||
635 | |||
636 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | ||
637 | { | ||
638 | struct sd *sd = (struct sd *) gspca_dev; | ||
639 | |||
640 | sd->brightness = val; | ||
641 | if (gspca_dev->streaming) | ||
642 | setbrightness(gspca_dev); | ||
643 | return 0; | ||
644 | } | ||
645 | |||
646 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
647 | { | ||
648 | struct sd *sd = (struct sd *) gspca_dev; | ||
649 | *val = sd->brightness; | ||
650 | return *val; | ||
651 | } | ||
652 | |||
653 | static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val) | ||
654 | { | ||
655 | struct sd *sd = (struct sd *) gspca_dev; | ||
656 | |||
657 | sd->whitebalance = val; | ||
658 | if (gspca_dev->streaming) | ||
659 | setwhitebalance(gspca_dev); | ||
660 | return 0; | ||
661 | } | ||
662 | |||
663 | static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val) | ||
664 | { | ||
665 | struct sd *sd = (struct sd *) gspca_dev; | ||
666 | |||
667 | *val = sd->whitebalance; | ||
668 | return *val; | ||
669 | } | ||
670 | |||
671 | |||
672 | static int sd_setflip(struct gspca_dev *gspca_dev, __s32 val) | ||
673 | { | ||
674 | struct sd *sd = (struct sd *) gspca_dev; | ||
675 | |||
676 | sd->mirror = val; | ||
677 | if (gspca_dev->streaming) | ||
678 | setflip(gspca_dev); | ||
679 | return 0; | ||
680 | } | ||
681 | |||
682 | static int sd_getflip(struct gspca_dev *gspca_dev, __s32 *val) | ||
683 | { | ||
684 | struct sd *sd = (struct sd *) gspca_dev; | ||
685 | |||
686 | *val = sd->mirror; | ||
687 | return *val; | ||
688 | } | ||
689 | |||
690 | static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val) | ||
691 | { | ||
692 | struct sd *sd = (struct sd *) gspca_dev; | ||
693 | |||
694 | sd->effect = val; | ||
695 | if (gspca_dev->streaming) | ||
696 | seteffect(gspca_dev); | ||
697 | return 0; | ||
698 | } | ||
699 | |||
700 | static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val) | ||
701 | { | ||
702 | struct sd *sd = (struct sd *) gspca_dev; | ||
703 | |||
704 | *val = sd->effect; | ||
705 | return *val; | ||
706 | } | ||
707 | |||
708 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | ||
709 | { | ||
710 | struct sd *sd = (struct sd *) gspca_dev; | ||
711 | |||
712 | sd->contrast = val; | ||
713 | if (gspca_dev->streaming) | ||
714 | setcontrast(gspca_dev); | ||
715 | return 0; | ||
716 | } | ||
717 | |||
718 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) | ||
719 | { | ||
720 | struct sd *sd = (struct sd *) gspca_dev; | ||
721 | |||
722 | *val = sd->contrast; | ||
723 | return *val; | ||
724 | } | ||
725 | |||
726 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) | ||
727 | { | ||
728 | struct sd *sd = (struct sd *) gspca_dev; | ||
729 | |||
730 | sd->colors = val; | ||
731 | if (gspca_dev->streaming) | ||
732 | setcolors(gspca_dev); | ||
733 | return 0; | ||
734 | } | ||
735 | |||
736 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) | ||
737 | { | ||
738 | struct sd *sd = (struct sd *) gspca_dev; | ||
739 | |||
740 | *val = sd->colors; | ||
741 | return 0; | ||
742 | } | ||
743 | |||
744 | static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val) | ||
745 | { | ||
746 | struct sd *sd = (struct sd *) gspca_dev; | ||
747 | |||
748 | sd->gamma = val; | ||
749 | if (gspca_dev->streaming) | ||
750 | setgamma(gspca_dev); | ||
751 | return 0; | ||
752 | } | ||
753 | |||
754 | static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val) | ||
755 | { | ||
756 | struct sd *sd = (struct sd *) gspca_dev; | ||
757 | *val = sd->gamma; | ||
758 | return 0; | ||
759 | } | ||
760 | |||
761 | static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val) | ||
762 | { | ||
763 | struct sd *sd = (struct sd *) gspca_dev; | ||
764 | |||
765 | sd->freq = val; | ||
766 | if (gspca_dev->streaming) | ||
767 | setlightfreq(gspca_dev); | ||
768 | return 0; | ||
769 | } | ||
770 | |||
771 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val) | ||
772 | { | ||
773 | struct sd *sd = (struct sd *) gspca_dev; | ||
774 | |||
775 | *val = sd->freq; | ||
776 | return 0; | ||
777 | } | ||
778 | |||
779 | static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val) | ||
780 | { | ||
781 | struct sd *sd = (struct sd *) gspca_dev; | ||
782 | |||
783 | sd->sharpness = val; | ||
784 | if (gspca_dev->streaming) | ||
785 | setsharpness(gspca_dev); | ||
786 | return 0; | ||
787 | } | ||
788 | |||
789 | static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val) | ||
790 | { | ||
791 | struct sd *sd = (struct sd *) gspca_dev; | ||
792 | |||
793 | *val = sd->sharpness; | ||
794 | return 0; | ||
795 | } | ||
796 | |||
797 | /* Low Light set here......*/ | ||
798 | static int sd_setlowlight(struct gspca_dev *gspca_dev, __s32 val) | ||
799 | { | ||
800 | struct sd *sd = (struct sd *) gspca_dev; | ||
801 | struct usb_device *dev = gspca_dev->dev; | ||
802 | |||
803 | sd->autogain = val; | ||
804 | if (val != 0) | ||
805 | t16RegWrite(dev, 0x00, 0xf48e, 0x00, 0); | ||
806 | else | ||
807 | t16RegWrite(dev, 0x00, 0xb48e, 0x00, 0); | ||
808 | return 0; | ||
809 | } | ||
810 | |||
811 | static int sd_getlowlight(struct gspca_dev *gspca_dev, __s32 *val) | ||
812 | { | ||
813 | struct sd *sd = (struct sd *) gspca_dev; | ||
814 | |||
815 | *val = sd->autogain; | ||
816 | return 0; | ||
817 | } | ||
818 | |||
819 | static void sd_start(struct gspca_dev *gspca_dev) | ||
820 | { | ||
821 | struct usb_device *dev = gspca_dev->dev; | ||
822 | int mode; | ||
823 | __u8 test_byte; | ||
824 | |||
825 | static __u8 t1[] = { 0x66, 0x00, 0xa8, 0xe8 }; | ||
826 | __u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 }; | ||
827 | static __u8 t3[] = | ||
828 | { 0xb3, 0x07, 0xb4, 0x00, 0xb5, 0x88, 0xb6, 0x02, 0xb7, 0x06, | ||
829 | 0xb8, 0x00, 0xb9, 0xe7, 0xba, 0x01 }; | ||
830 | static __u8 t4[] = { 0x0b, 0x04, 0x0a, 0x40 }; | ||
831 | |||
832 | mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode]. mode; | ||
833 | switch (mode) { | ||
834 | case 1: /* 352x288 */ | ||
835 | t2[1] = 0x40; | ||
836 | break; | ||
837 | case 2: /* 320x240 */ | ||
838 | t2[1] = 0x10; | ||
839 | break; | ||
840 | case 3: /* 176x144 */ | ||
841 | t2[1] = 0x50; | ||
842 | break; | ||
843 | case 4: /* 160x120 */ | ||
844 | t2[1] = 0x20; | ||
845 | break; | ||
846 | default: /* 640x480 (0x00) */ | ||
847 | break; | ||
848 | } | ||
849 | |||
850 | t16RegWrite(dev, 0x01, 0x0000, tas5130a_sensor_init[0], 0x8); | ||
851 | t16RegWrite(dev, 0x01, 0x0000, tas5130a_sensor_init[1], 0x8); | ||
852 | t16RegWrite(dev, 0x01, 0x0000, tas5130a_sensor_init[2], 0x8); | ||
853 | t16RegWrite(dev, 0x01, 0x0000, tas5130a_sensor_init[3], 0x8); | ||
854 | t16RegWrite(dev, 0x00, 0x3c80, 0x00, 0x00); | ||
855 | /* just in case and to keep sync with logs (for mine) */ | ||
856 | t16RegWrite(dev, 0x01, 0x0000, tas5130a_sensor_init[3], 0x8); | ||
857 | t16RegWrite(dev, 0x00, 0x3c80, 0x00, 0x00); | ||
858 | /* just in case and to keep sync with logs (for mine) */ | ||
859 | t16RegWrite(dev, 0x01, 0x0000, t1, 4); | ||
860 | t16RegWrite(dev, 0x01, 0x0000, t2, 6); | ||
861 | t16RegRead(dev, 0x0012, &test_byte, 0x1); | ||
862 | t16RegWrite(dev, 0x01, 0x0000, t3, 0x10); | ||
863 | t16RegWrite(dev, 0x00, 0x0013, 0x00, 0x00); | ||
864 | t16RegWrite(dev, 0x01, 0x0000, t4, 0x4); | ||
865 | /* restart on each start, just in case, sometimes regs goes wrong | ||
866 | * when using controls from app */ | ||
867 | setbrightness(gspca_dev); | ||
868 | setcontrast(gspca_dev); | ||
869 | setcolors(gspca_dev); | ||
870 | } | ||
871 | |||
872 | static void sd_stopN(struct gspca_dev *gspca_dev) | ||
873 | { | ||
874 | } | ||
875 | |||
876 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
877 | { | ||
878 | } | ||
879 | |||
880 | static void sd_close(struct gspca_dev *gspca_dev) | ||
881 | { | ||
882 | } | ||
883 | |||
884 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | ||
885 | struct gspca_frame *frame, /* target */ | ||
886 | unsigned char *data, /* isoc packet */ | ||
887 | int len) /* iso packet length */ | ||
888 | { | ||
889 | int sof = 0; | ||
890 | static unsigned char ffd9[] = { 0xff, 0xd9 }; | ||
891 | |||
892 | if (data[0] == 0x5a) { | ||
893 | /* Control Packet, after this came the header again, | ||
894 | * but extra bytes came in the packet before this, | ||
895 | * sometimes an EOF arrives, sometimes not... */ | ||
896 | return; | ||
897 | } | ||
898 | |||
899 | if (data[len - 1] == 0xff && data[len] == 0xd9) { | ||
900 | /* Just in case, i have seen packets with the marker, | ||
901 | * other's do not include it... */ | ||
902 | data += 2; | ||
903 | len -= 4; | ||
904 | } else if (data[2] == 0xff && data[3] == 0xd8) { | ||
905 | sof = 1; | ||
906 | data += 2; | ||
907 | len -= 2; | ||
908 | } else { | ||
909 | data += 2; | ||
910 | len -= 2; | ||
911 | } | ||
912 | |||
913 | if (sof) { | ||
914 | /* extra bytes....., could be processed too but would be | ||
915 | * a waste of time, right now leave the application and | ||
916 | * libjpeg do it for ourserlves.. */ | ||
917 | frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, | ||
918 | ffd9, 2); | ||
919 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len); | ||
920 | return; | ||
921 | } | ||
922 | |||
923 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); | ||
924 | } | ||
925 | |||
926 | static int sd_querymenu(struct gspca_dev *gspca_dev, | ||
927 | struct v4l2_querymenu *menu) | ||
928 | { | ||
929 | memset(menu->name, 0, sizeof menu->name); | ||
930 | |||
931 | switch (menu->id) { | ||
932 | case V4L2_CID_POWER_LINE_FREQUENCY: | ||
933 | switch (menu->index) { | ||
934 | case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */ | ||
935 | strcpy(menu->name, "50 Hz"); | ||
936 | return 0; | ||
937 | case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */ | ||
938 | strcpy(menu->name, "60 Hz"); | ||
939 | return 0; | ||
940 | } | ||
941 | break; | ||
942 | case V4L2_CID_EFFECTS: | ||
943 | if (menu->index < 0 || menu->index >= NUM_EFFECTS_CONTROL) | ||
944 | return -EINVAL; | ||
945 | strncpy((char *) menu->name, | ||
946 | effects_control[menu->index].name, 32); | ||
947 | break; | ||
948 | } | ||
949 | return 0; | ||
950 | } | ||
951 | |||
952 | /* this function is called at open time */ | ||
953 | static int sd_open(struct gspca_dev *gspca_dev) | ||
954 | { | ||
955 | init_default_parameters(gspca_dev); | ||
956 | return 0; | ||
957 | } | ||
958 | |||
959 | /* sub-driver description */ | ||
960 | static struct sd_desc sd_desc = { | ||
961 | .name = MODULE_NAME, | ||
962 | .ctrls = sd_ctrls, | ||
963 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
964 | .config = sd_config, | ||
965 | .open = sd_open, | ||
966 | .start = sd_start, | ||
967 | .stopN = sd_stopN, | ||
968 | .stop0 = sd_stop0, | ||
969 | .close = sd_close, | ||
970 | .pkt_scan = sd_pkt_scan, | ||
971 | .querymenu = sd_querymenu, | ||
972 | }; | ||
973 | |||
974 | /* -- module initialisation -- */ | ||
975 | #define DVNM(name) .driver_info = (kernel_ulong_t) name | ||
976 | static __devinitdata struct usb_device_id device_table[] = { | ||
977 | {USB_DEVICE(0x17a1, 0x0128), DVNM("XPX Webcam")}, | ||
978 | {} | ||
979 | }; | ||
980 | |||
981 | MODULE_DEVICE_TABLE(usb, device_table); | ||
982 | |||
983 | /* -- device connect -- */ | ||
984 | static int sd_probe(struct usb_interface *intf, | ||
985 | const struct usb_device_id *id) | ||
986 | { | ||
987 | return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), | ||
988 | THIS_MODULE); | ||
989 | } | ||
990 | |||
991 | static struct usb_driver sd_driver = { | ||
992 | .name = MODULE_NAME, | ||
993 | .id_table = device_table, | ||
994 | .probe = sd_probe, | ||
995 | .disconnect = gspca_disconnect, | ||
996 | }; | ||
997 | |||
998 | /* -- module insert / remove -- */ | ||
999 | static int __init sd_mod_init(void) | ||
1000 | { | ||
1001 | if (usb_register(&sd_driver) < 0) | ||
1002 | return -1; | ||
1003 | PDEBUG(D_PROBE, "v%s registered", version); | ||
1004 | return 0; | ||
1005 | } | ||
1006 | static void __exit sd_mod_exit(void) | ||
1007 | { | ||
1008 | usb_deregister(&sd_driver); | ||
1009 | PDEBUG(D_PROBE, "deregistered"); | ||
1010 | } | ||
1011 | |||
1012 | module_init(sd_mod_init); | ||
1013 | module_exit(sd_mod_exit); | ||
diff --git a/drivers/media/video/gspca/tv8532.c b/drivers/media/video/gspca/tv8532.c new file mode 100644 index 000000000000..6218441ba1f0 --- /dev/null +++ b/drivers/media/video/gspca/tv8532.c | |||
@@ -0,0 +1,709 @@ | |||
1 | /* | ||
2 | * Quickcam cameras initialization data | ||
3 | * | ||
4 | * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | * | ||
20 | */ | ||
21 | #define MODULE_NAME "tv8532" | ||
22 | |||
23 | #include "gspca.h" | ||
24 | |||
25 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) | ||
26 | static const char version[] = "2.1.0"; | ||
27 | |||
28 | MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); | ||
29 | MODULE_DESCRIPTION("TV8532 USB Camera Driver"); | ||
30 | MODULE_LICENSE("GPL"); | ||
31 | |||
32 | /* specific webcam descriptor */ | ||
33 | struct sd { | ||
34 | struct gspca_dev gspca_dev; /* !! must be the first item */ | ||
35 | |||
36 | int buflen; /* current length of tmpbuf */ | ||
37 | __u8 tmpbuf[352 * 288 + 10 * 288]; /* no protection... */ | ||
38 | __u8 tmpbuf2[352 * 288]; /* no protection... */ | ||
39 | |||
40 | unsigned short brightness; | ||
41 | unsigned short contrast; | ||
42 | |||
43 | char packet; | ||
44 | char synchro; | ||
45 | }; | ||
46 | |||
47 | /* V4L2 controls supported by the driver */ | ||
48 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
49 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
50 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | ||
51 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | ||
52 | |||
53 | static struct ctrl sd_ctrls[] = { | ||
54 | #define SD_BRIGHTNESS 0 | ||
55 | { | ||
56 | { | ||
57 | .id = V4L2_CID_BRIGHTNESS, | ||
58 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
59 | .name = "Brightness", | ||
60 | .minimum = 1, | ||
61 | .maximum = 0x2ff, | ||
62 | .step = 1, | ||
63 | .default_value = 0x18f, | ||
64 | }, | ||
65 | .set = sd_setbrightness, | ||
66 | .get = sd_getbrightness, | ||
67 | }, | ||
68 | #define SD_CONTRAST 1 | ||
69 | { | ||
70 | { | ||
71 | .id = V4L2_CID_CONTRAST, | ||
72 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
73 | .name = "Contrast", | ||
74 | .minimum = 0, | ||
75 | .maximum = 0xffff, | ||
76 | .step = 1, | ||
77 | .default_value = 0x7fff, | ||
78 | }, | ||
79 | .set = sd_setcontrast, | ||
80 | .get = sd_getcontrast, | ||
81 | }, | ||
82 | }; | ||
83 | |||
84 | static struct cam_mode sif_mode[] = { | ||
85 | {V4L2_PIX_FMT_SBGGR8, 176, 144, 1}, | ||
86 | {V4L2_PIX_FMT_SBGGR8, 352, 288, 0}, | ||
87 | }; | ||
88 | |||
89 | /* | ||
90 | * Initialization data: this is the first set-up data written to the | ||
91 | * device (before the open data). | ||
92 | */ | ||
93 | #define TESTCLK 0x10 /* reg 0x2c -> 0x12 //10 */ | ||
94 | #define TESTCOMP 0x90 /* reg 0x28 -> 0x80 */ | ||
95 | #define TESTLINE 0x81 /* reg 0x29 -> 0x81 */ | ||
96 | #define QCIFLINE 0x41 /* reg 0x29 -> 0x81 */ | ||
97 | #define TESTPTL 0x14 /* reg 0x2D -> 0x14 */ | ||
98 | #define TESTPTH 0x01 /* reg 0x2E -> 0x01 */ | ||
99 | #define TESTPTBL 0x12 /* reg 0x2F -> 0x0a */ | ||
100 | #define TESTPTBH 0x01 /* reg 0x30 -> 0x01 */ | ||
101 | #define ADWIDTHL 0xe8 /* reg 0x0c -> 0xe8 */ | ||
102 | #define ADWIDTHH 0x03 /* reg 0x0d -> 0x03 */ | ||
103 | #define ADHEIGHL 0x90 /* reg 0x0e -> 0x91 //93 */ | ||
104 | #define ADHEIGHH 0x01 /* reg 0x0f -> 0x01 */ | ||
105 | #define EXPOL 0x8f /* reg 0x1c -> 0x8f */ | ||
106 | #define EXPOH 0x01 /* reg 0x1d -> 0x01 */ | ||
107 | #define ADCBEGINL 0x44 /* reg 0x10 -> 0x46 //47 */ | ||
108 | #define ADCBEGINH 0x00 /* reg 0x11 -> 0x00 */ | ||
109 | #define ADRBEGINL 0x0a /* reg 0x14 -> 0x0b //0x0c */ | ||
110 | #define ADRBEGINH 0x00 /* reg 0x15 -> 0x00 */ | ||
111 | #define TV8532_CMD_UPDATE 0x84 | ||
112 | |||
113 | #define TV8532_EEprom_Add 0x03 | ||
114 | #define TV8532_EEprom_DataL 0x04 | ||
115 | #define TV8532_EEprom_DataM 0x05 | ||
116 | #define TV8532_EEprom_DataH 0x06 | ||
117 | #define TV8532_EEprom_TableLength 0x07 | ||
118 | #define TV8532_EEprom_Write 0x08 | ||
119 | #define TV8532_PART_CTRL 0x00 | ||
120 | #define TV8532_CTRL 0x01 | ||
121 | #define TV8532_CMD_EEprom_Open 0x30 | ||
122 | #define TV8532_CMD_EEprom_Close 0x29 | ||
123 | #define TV8532_UDP_UPDATE 0x31 | ||
124 | #define TV8532_GPIO 0x39 | ||
125 | #define TV8532_GPIO_OE 0x3B | ||
126 | #define TV8532_REQ_RegWrite 0x02 | ||
127 | #define TV8532_REQ_RegRead 0x03 | ||
128 | |||
129 | #define TV8532_ADWIDTH_L 0x0C | ||
130 | #define TV8532_ADWIDTH_H 0x0D | ||
131 | #define TV8532_ADHEIGHT_L 0x0E | ||
132 | #define TV8532_ADHEIGHT_H 0x0F | ||
133 | #define TV8532_EXPOSURE 0x1C | ||
134 | #define TV8532_QUANT_COMP 0x28 | ||
135 | #define TV8532_MODE_PACKET 0x29 | ||
136 | #define TV8532_SETCLK 0x2C | ||
137 | #define TV8532_POINT_L 0x2D | ||
138 | #define TV8532_POINT_H 0x2E | ||
139 | #define TV8532_POINTB_L 0x2F | ||
140 | #define TV8532_POINTB_H 0x30 | ||
141 | #define TV8532_BUDGET_L 0x2A | ||
142 | #define TV8532_BUDGET_H 0x2B | ||
143 | #define TV8532_VID_L 0x34 | ||
144 | #define TV8532_VID_H 0x35 | ||
145 | #define TV8532_PID_L 0x36 | ||
146 | #define TV8532_PID_H 0x37 | ||
147 | #define TV8532_DeviceID 0x83 | ||
148 | #define TV8532_AD_SLOPE 0x91 | ||
149 | #define TV8532_AD_BITCTRL 0x94 | ||
150 | #define TV8532_AD_COLBEGIN_L 0x10 | ||
151 | #define TV8532_AD_COLBEGIN_H 0x11 | ||
152 | #define TV8532_AD_ROWBEGIN_L 0x14 | ||
153 | #define TV8532_AD_ROWBEGIN_H 0x15 | ||
154 | |||
155 | static __u32 tv_8532_eeprom_data[] = { | ||
156 | /* add dataL dataM dataH */ | ||
157 | 0x00010001, 0x01018011, 0x02050014, 0x0305001c, | ||
158 | 0x040d001e, 0x0505001f, 0x06050519, 0x0705011b, | ||
159 | 0x0805091e, 0x090d892e, 0x0a05892f, 0x0b050dd9, | ||
160 | 0x0c0509f1, 0 | ||
161 | }; | ||
162 | |||
163 | static void reg_r(struct usb_device *dev, | ||
164 | __u16 index, __u8 *buffer) | ||
165 | { | ||
166 | usb_control_msg(dev, | ||
167 | usb_rcvctrlpipe(dev, 0), | ||
168 | TV8532_REQ_RegRead, | ||
169 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
170 | 0, /* value */ | ||
171 | index, buffer, sizeof(__u8), | ||
172 | 500); | ||
173 | } | ||
174 | |||
175 | static void reg_w(struct usb_device *dev, | ||
176 | __u16 index, __u8 *buffer, __u16 length) | ||
177 | { | ||
178 | usb_control_msg(dev, | ||
179 | usb_sndctrlpipe(dev, 0), | ||
180 | TV8532_REQ_RegWrite, | ||
181 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
182 | 0, /* value */ | ||
183 | index, buffer, length, 500); | ||
184 | } | ||
185 | |||
186 | static void tv_8532WriteEEprom(struct gspca_dev *gspca_dev) | ||
187 | { | ||
188 | int i = 0; | ||
189 | __u8 reg, data0, data1, data2, datacmd; | ||
190 | struct usb_device *dev = gspca_dev->dev; | ||
191 | |||
192 | datacmd = 0xb0;; | ||
193 | reg_w(dev, TV8532_GPIO, &datacmd, 1); | ||
194 | datacmd = TV8532_CMD_EEprom_Open; | ||
195 | reg_w(dev, TV8532_CTRL, &datacmd, | ||
196 | 1); | ||
197 | /* msleep(1); */ | ||
198 | while (tv_8532_eeprom_data[i]) { | ||
199 | reg = (tv_8532_eeprom_data[i] & 0xff000000) >> 24; | ||
200 | reg_w(dev, TV8532_EEprom_Add, ®, 1); | ||
201 | /* msleep(1); */ | ||
202 | data0 = (tv_8532_eeprom_data[i] & 0x000000ff); | ||
203 | reg_w(dev, TV8532_EEprom_DataL, &data0, 1); | ||
204 | /* msleep(1); */ | ||
205 | data1 = (tv_8532_eeprom_data[i] & 0x0000FF00) >> 8; | ||
206 | reg_w(dev, TV8532_EEprom_DataM, &data1, 1); | ||
207 | /* msleep(1); */ | ||
208 | data2 = (tv_8532_eeprom_data[i] & 0x00FF0000) >> 16; | ||
209 | reg_w(dev, TV8532_EEprom_DataH, &data2, 1); | ||
210 | /* msleep(1); */ | ||
211 | datacmd = 0; | ||
212 | reg_w(dev, TV8532_EEprom_Write, &datacmd, 1); | ||
213 | /* msleep(10); */ | ||
214 | i++; | ||
215 | } | ||
216 | datacmd = i; | ||
217 | reg_w(dev, TV8532_EEprom_TableLength, &datacmd, 1); | ||
218 | /* msleep(1); */ | ||
219 | datacmd = TV8532_CMD_EEprom_Close; | ||
220 | reg_w(dev, TV8532_CTRL, &datacmd, 1); | ||
221 | msleep(10); | ||
222 | } | ||
223 | |||
224 | /* this function is called at probe time */ | ||
225 | static int sd_config(struct gspca_dev *gspca_dev, | ||
226 | const struct usb_device_id *id) | ||
227 | { | ||
228 | struct sd *sd = (struct sd *) gspca_dev; | ||
229 | struct cam *cam; | ||
230 | |||
231 | tv_8532WriteEEprom(gspca_dev); | ||
232 | |||
233 | cam = &gspca_dev->cam; | ||
234 | cam->dev_name = (char *) id->driver_info; | ||
235 | cam->epaddr = 1; | ||
236 | cam->cam_mode = sif_mode; | ||
237 | cam->nmodes = sizeof sif_mode / sizeof sif_mode[0]; | ||
238 | |||
239 | sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; | ||
240 | sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; | ||
241 | return 0; | ||
242 | } | ||
243 | |||
244 | static void tv_8532ReadRegisters(struct gspca_dev *gspca_dev) | ||
245 | { | ||
246 | struct usb_device *dev = gspca_dev->dev; | ||
247 | __u8 data = 0; | ||
248 | /* __u16 vid, pid; */ | ||
249 | |||
250 | reg_r(dev, 0x0001, &data); | ||
251 | PDEBUG(D_USBI, "register 0x01-> %x", data); | ||
252 | reg_r(dev, 0x0002, &data); | ||
253 | PDEBUG(D_USBI, "register 0x02-> %x", data); | ||
254 | reg_r(dev, TV8532_ADWIDTH_L, &data); | ||
255 | reg_r(dev, TV8532_ADWIDTH_H, &data); | ||
256 | reg_r(dev, TV8532_QUANT_COMP, &data); | ||
257 | reg_r(dev, TV8532_MODE_PACKET, &data); | ||
258 | reg_r(dev, TV8532_SETCLK, &data); | ||
259 | reg_r(dev, TV8532_POINT_L, &data); | ||
260 | reg_r(dev, TV8532_POINT_H, &data); | ||
261 | reg_r(dev, TV8532_POINTB_L, &data); | ||
262 | reg_r(dev, TV8532_POINTB_H, &data); | ||
263 | reg_r(dev, TV8532_BUDGET_L, &data); | ||
264 | reg_r(dev, TV8532_BUDGET_H, &data); | ||
265 | reg_r(dev, TV8532_VID_L, &data); | ||
266 | reg_r(dev, TV8532_VID_H, &data); | ||
267 | reg_r(dev, TV8532_PID_L, &data); | ||
268 | reg_r(dev, TV8532_PID_H, &data); | ||
269 | reg_r(dev, TV8532_DeviceID, &data); | ||
270 | reg_r(dev, TV8532_AD_COLBEGIN_L, &data); | ||
271 | reg_r(dev, TV8532_AD_COLBEGIN_H, &data); | ||
272 | reg_r(dev, TV8532_AD_ROWBEGIN_L, &data); | ||
273 | reg_r(dev, TV8532_AD_ROWBEGIN_H, &data); | ||
274 | } | ||
275 | |||
276 | static void tv_8532_setReg(struct gspca_dev *gspca_dev) | ||
277 | { | ||
278 | struct usb_device *dev = gspca_dev->dev; | ||
279 | __u8 data = 0; | ||
280 | __u8 value[2] = { 0, 0 }; | ||
281 | |||
282 | data = ADCBEGINL; | ||
283 | reg_w(dev, TV8532_AD_COLBEGIN_L, &data, 1); /* 0x10 */ | ||
284 | data = ADCBEGINH; /* also digital gain */ | ||
285 | reg_w(dev, TV8532_AD_COLBEGIN_H, &data, 1); | ||
286 | data = TV8532_CMD_UPDATE; | ||
287 | reg_w(dev, TV8532_PART_CTRL, &data, 1); /* 0x00<-0x84 */ | ||
288 | |||
289 | data = 0x0a; | ||
290 | reg_w(dev, TV8532_GPIO_OE, &data, 1); | ||
291 | /******************************************************/ | ||
292 | data = ADHEIGHL; | ||
293 | reg_w(dev, TV8532_ADHEIGHT_L, &data, 1); /* 0e */ | ||
294 | data = ADHEIGHH; | ||
295 | reg_w(dev, TV8532_ADHEIGHT_H, &data, 1); /* 0f */ | ||
296 | value[0] = EXPOL; | ||
297 | value[1] = EXPOH; /* 350d 0x014c; */ | ||
298 | reg_w(dev, TV8532_EXPOSURE, value, 2); /* 1c */ | ||
299 | data = ADCBEGINL; | ||
300 | reg_w(dev, TV8532_AD_COLBEGIN_L, &data, 1); /* 0x10 */ | ||
301 | data = ADCBEGINH; /* also digital gain */ | ||
302 | reg_w(dev, TV8532_AD_COLBEGIN_H, &data, 1); | ||
303 | data = ADRBEGINL; | ||
304 | reg_w(dev, TV8532_AD_ROWBEGIN_L, &data, 1); /* 0x14 */ | ||
305 | |||
306 | data = 0x00; | ||
307 | reg_w(dev, TV8532_AD_SLOPE, &data, 1); /* 0x91 */ | ||
308 | data = 0x02; | ||
309 | reg_w(dev, TV8532_AD_BITCTRL, &data, 1); /* 0x94 */ | ||
310 | |||
311 | |||
312 | data = TV8532_CMD_EEprom_Close; | ||
313 | reg_w(dev, TV8532_CTRL, &data, 1); /* 0x01 */ | ||
314 | |||
315 | data = 0x00; | ||
316 | reg_w(dev, TV8532_AD_SLOPE, &data, 1); /* 0x91 */ | ||
317 | data = TV8532_CMD_UPDATE; | ||
318 | reg_w(dev, TV8532_PART_CTRL, &data, 1); /* 0x00<-0x84 */ | ||
319 | } | ||
320 | |||
321 | static void tv_8532_PollReg(struct gspca_dev *gspca_dev) | ||
322 | { | ||
323 | struct usb_device *dev = gspca_dev->dev; | ||
324 | __u8 data = 0; | ||
325 | int i; | ||
326 | |||
327 | /* strange polling from tgc */ | ||
328 | for (i = 0; i < 10; i++) { | ||
329 | data = TESTCLK; /* 0x48; //0x08; */ | ||
330 | reg_w(dev, TV8532_SETCLK, &data, 1); /* 0x2c */ | ||
331 | data = TV8532_CMD_UPDATE; | ||
332 | reg_w(dev, TV8532_PART_CTRL, &data, 1); | ||
333 | data = 0x01; | ||
334 | reg_w(dev, TV8532_UDP_UPDATE, &data, 1); /* 0x31 */ | ||
335 | } | ||
336 | } | ||
337 | |||
338 | /* this function is called at open time */ | ||
339 | static int sd_open(struct gspca_dev *gspca_dev) | ||
340 | { | ||
341 | struct usb_device *dev = gspca_dev->dev; | ||
342 | __u8 data = 0; | ||
343 | __u8 dataStart = 0; | ||
344 | __u8 value[2] = { 0, 0 }; | ||
345 | |||
346 | data = 0x32; | ||
347 | reg_w(dev, TV8532_AD_SLOPE, &data, 1); | ||
348 | data = 0; | ||
349 | reg_w(dev, TV8532_AD_BITCTRL, &data, 1); | ||
350 | tv_8532ReadRegisters(gspca_dev); | ||
351 | data = 0x0b; | ||
352 | reg_w(dev, TV8532_GPIO_OE, &data, 1); | ||
353 | value[0] = ADHEIGHL; | ||
354 | value[1] = ADHEIGHH; /* 401d 0x0169; */ | ||
355 | reg_w(dev, TV8532_ADHEIGHT_L, value, 2); /* 0e */ | ||
356 | value[0] = EXPOL; | ||
357 | value[1] = EXPOH; /* 350d 0x014c; */ | ||
358 | reg_w(dev, TV8532_EXPOSURE, value, 2); /* 1c */ | ||
359 | data = ADWIDTHL; /* 0x20; */ | ||
360 | reg_w(dev, TV8532_ADWIDTH_L, &data, 1); /* 0x0c */ | ||
361 | data = ADWIDTHH; | ||
362 | reg_w(dev, TV8532_ADWIDTH_H, &data, 1); /* 0x0d */ | ||
363 | |||
364 | /*******************************************************************/ | ||
365 | data = TESTCOMP; /* 0x72 compressed mode */ | ||
366 | reg_w(dev, TV8532_QUANT_COMP, &data, 1); /* 0x28 */ | ||
367 | data = TESTLINE; /* 0x84; // CIF | 4 packet */ | ||
368 | reg_w(dev, TV8532_MODE_PACKET, &data, 1); /* 0x29 */ | ||
369 | |||
370 | /************************************************/ | ||
371 | data = TESTCLK; /* 0x48; //0x08; */ | ||
372 | reg_w(dev, TV8532_SETCLK, &data, 1); /* 0x2c */ | ||
373 | data = TESTPTL; /* 0x38; */ | ||
374 | reg_w(dev, TV8532_POINT_L, &data, 1); /* 0x2d */ | ||
375 | data = TESTPTH; /* 0x04; */ | ||
376 | reg_w(dev, TV8532_POINT_H, &data, 1); /* 0x2e */ | ||
377 | dataStart = TESTPTBL; /* 0x04; */ | ||
378 | reg_w(dev, TV8532_POINTB_L, &dataStart, 1); /* 0x2f */ | ||
379 | data = TESTPTBH; /* 0x04; */ | ||
380 | reg_w(dev, TV8532_POINTB_H, &data, 1); /* 0x30 */ | ||
381 | data = TV8532_CMD_UPDATE; | ||
382 | reg_w(dev, TV8532_PART_CTRL, &data, 1); /* 0x00<-0x84 */ | ||
383 | /*************************************************/ | ||
384 | data = 0x01; | ||
385 | reg_w(dev, TV8532_UDP_UPDATE, &data, 1); /* 0x31 */ | ||
386 | msleep(200); | ||
387 | data = 0x00; | ||
388 | reg_w(dev, TV8532_UDP_UPDATE, &data, 1); /* 0x31 */ | ||
389 | /*************************************************/ | ||
390 | tv_8532_setReg(gspca_dev); | ||
391 | /*************************************************/ | ||
392 | data = 0x0b; | ||
393 | reg_w(dev, TV8532_GPIO_OE, &data, | ||
394 | 1); | ||
395 | /*************************************************/ | ||
396 | tv_8532_setReg(gspca_dev); | ||
397 | /*************************************************/ | ||
398 | tv_8532_PollReg(gspca_dev); | ||
399 | return 0; | ||
400 | } | ||
401 | |||
402 | static void setbrightness(struct gspca_dev *gspca_dev) | ||
403 | { | ||
404 | struct sd *sd = (struct sd *) gspca_dev; | ||
405 | __u8 value[2]; | ||
406 | __u8 data; | ||
407 | int brightness = sd->brightness; | ||
408 | |||
409 | value[1] = (brightness >> 8) & 0xff; | ||
410 | value[0] = (brightness) & 0xff; | ||
411 | reg_w(gspca_dev->dev, TV8532_EXPOSURE, value, 2); /* 1c */ | ||
412 | data = TV8532_CMD_UPDATE; | ||
413 | reg_w(gspca_dev->dev, TV8532_PART_CTRL, &data, 1); | ||
414 | } | ||
415 | |||
416 | /* -- start the camera -- */ | ||
417 | static void sd_start(struct gspca_dev *gspca_dev) | ||
418 | { | ||
419 | struct usb_device *dev = gspca_dev->dev; | ||
420 | __u8 data = 0; | ||
421 | __u8 dataStart = 0; | ||
422 | __u8 value[2]; | ||
423 | |||
424 | data = 0x32; | ||
425 | reg_w(dev, TV8532_AD_SLOPE, &data, 1); | ||
426 | data = 0; | ||
427 | reg_w(dev, TV8532_AD_BITCTRL, &data, 1); | ||
428 | tv_8532ReadRegisters(gspca_dev); | ||
429 | data = 0x0b; | ||
430 | reg_w(dev, TV8532_GPIO_OE, &data, 1); | ||
431 | value[0] = ADHEIGHL; | ||
432 | value[1] = ADHEIGHH; /* 401d 0x0169; */ | ||
433 | reg_w(dev, TV8532_ADHEIGHT_L, value, 2); /* 0e */ | ||
434 | /* value[0] = EXPOL; value[1] =EXPOH; * 350d 0x014c; */ | ||
435 | /* reg_w(dev,TV8532_REQ_RegWrite,0,TV8532_EXPOSURE,value,2); * 1c */ | ||
436 | setbrightness(gspca_dev); | ||
437 | |||
438 | data = ADWIDTHL; /* 0x20; */ | ||
439 | reg_w(dev, TV8532_ADWIDTH_L, &data, 1); /* 0x0c */ | ||
440 | data = ADWIDTHH; | ||
441 | reg_w(dev, TV8532_ADWIDTH_H, &data, 1); /* 0x0d */ | ||
442 | |||
443 | /************************************************/ | ||
444 | data = TESTCOMP; /* 0x72 compressed mode */ | ||
445 | reg_w(dev, TV8532_QUANT_COMP, &data, 1); /* 0x28 */ | ||
446 | if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode) { | ||
447 | /* 176x144 */ | ||
448 | data = QCIFLINE; /* 0x84; // CIF | 4 packet */ | ||
449 | reg_w(dev, TV8532_MODE_PACKET, &data, 1); /* 0x29 */ | ||
450 | } else { | ||
451 | /* 352x288 */ | ||
452 | data = TESTLINE; /* 0x84; // CIF | 4 packet */ | ||
453 | reg_w(dev, TV8532_MODE_PACKET, &data, 1); /* 0x29 */ | ||
454 | } | ||
455 | /************************************************/ | ||
456 | data = TESTCLK; /* 0x48; //0x08; */ | ||
457 | reg_w(dev, TV8532_SETCLK, &data, 1); /* 0x2c */ | ||
458 | data = TESTPTL; /* 0x38; */ | ||
459 | reg_w(dev, TV8532_POINT_L, &data, 1); /* 0x2d */ | ||
460 | data = TESTPTH; /* 0x04; */ | ||
461 | reg_w(dev, TV8532_POINT_H, &data, 1); /* 0x2e */ | ||
462 | dataStart = TESTPTBL; /* 0x04; */ | ||
463 | reg_w(dev, TV8532_POINTB_L, &dataStart, 1); /* 0x2f */ | ||
464 | data = TESTPTBH; /* 0x04; */ | ||
465 | reg_w(dev, TV8532_POINTB_H, &data, 1); /* 0x30 */ | ||
466 | data = TV8532_CMD_UPDATE; | ||
467 | reg_w(dev, TV8532_PART_CTRL, &data, 1); /* 0x00<-0x84 */ | ||
468 | /************************************************/ | ||
469 | data = 0x01; | ||
470 | reg_w(dev, TV8532_UDP_UPDATE, &data, 1); /* 0x31 */ | ||
471 | msleep(200); | ||
472 | data = 0x00; | ||
473 | reg_w(dev, TV8532_UDP_UPDATE, &data, 1); /* 0x31 */ | ||
474 | /************************************************/ | ||
475 | tv_8532_setReg(gspca_dev); | ||
476 | /************************************************/ | ||
477 | data = 0x0b; | ||
478 | reg_w(dev, TV8532_GPIO_OE, &data, 1); | ||
479 | /************************************************/ | ||
480 | tv_8532_setReg(gspca_dev); | ||
481 | /************************************************/ | ||
482 | tv_8532_PollReg(gspca_dev); | ||
483 | data = 0x00; | ||
484 | reg_w(dev, TV8532_UDP_UPDATE, &data, 1); /* 0x31 */ | ||
485 | } | ||
486 | |||
487 | static void sd_stopN(struct gspca_dev *gspca_dev) | ||
488 | { | ||
489 | struct usb_device *dev = gspca_dev->dev; | ||
490 | __u8 data; | ||
491 | |||
492 | data = 0x0b; | ||
493 | reg_w(dev, TV8532_GPIO_OE, &data, 1); | ||
494 | } | ||
495 | |||
496 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
497 | { | ||
498 | } | ||
499 | |||
500 | static void sd_close(struct gspca_dev *gspca_dev) | ||
501 | { | ||
502 | } | ||
503 | |||
504 | static void tv8532_preprocess(struct gspca_dev *gspca_dev) | ||
505 | { | ||
506 | struct sd *sd = (struct sd *) gspca_dev; | ||
507 | /* we should received a whole frame with header and EOL marker | ||
508 | * in gspca_dev->tmpbuf and return a GBRG pattern in gspca_dev->tmpbuf2 | ||
509 | * sequence 2bytes header the Alternate pixels bayer GB 4 bytes | ||
510 | * Alternate pixels bayer RG 4 bytes EOL */ | ||
511 | int width = gspca_dev->width; | ||
512 | int height = gspca_dev->height; | ||
513 | unsigned char *dst = sd->tmpbuf2; | ||
514 | unsigned char *data = sd->tmpbuf; | ||
515 | int i; | ||
516 | |||
517 | /* precompute where is the good bayer line */ | ||
518 | if (((data[3] + data[width + 7]) >> 1) | ||
519 | + (data[4] >> 2) | ||
520 | + (data[width + 6] >> 1) >= ((data[2] + data[width + 6]) >> 1) | ||
521 | + (data[3] >> 2) | ||
522 | + (data[width + 5] >> 1)) | ||
523 | data += 3; | ||
524 | else | ||
525 | data += 2; | ||
526 | for (i = 0; i < height / 2; i++) { | ||
527 | memcpy(dst, data, width); | ||
528 | data += width + 3; | ||
529 | dst += width; | ||
530 | memcpy(dst, data, width); | ||
531 | data += width + 7; | ||
532 | dst += width; | ||
533 | } | ||
534 | } | ||
535 | |||
536 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | ||
537 | struct gspca_frame *frame, /* target */ | ||
538 | __u8 *data, /* isoc packet */ | ||
539 | int len) /* iso packet length */ | ||
540 | { | ||
541 | struct sd *sd = (struct sd *) gspca_dev; | ||
542 | |||
543 | if (data[0] != 0x80) { | ||
544 | sd->packet++; | ||
545 | if (sd->buflen + len > sizeof sd->tmpbuf) { | ||
546 | if (gspca_dev->last_packet_type != DISCARD_PACKET) { | ||
547 | PDEBUG(D_PACK, "buffer overflow"); | ||
548 | gspca_dev->last_packet_type = DISCARD_PACKET; | ||
549 | } | ||
550 | return; | ||
551 | } | ||
552 | memcpy(&sd->tmpbuf[sd->buflen], data, len); | ||
553 | sd->buflen += len; | ||
554 | return; | ||
555 | } | ||
556 | |||
557 | /* here we detect 0x80 */ | ||
558 | /* counter is limited so we need few header for a frame :) */ | ||
559 | |||
560 | /* header 0x80 0x80 0x80 0x80 0x80 */ | ||
561 | /* packet 00 63 127 145 00 */ | ||
562 | /* sof 0 1 1 0 0 */ | ||
563 | |||
564 | /* update sequence */ | ||
565 | if (sd->packet == 63 || sd->packet == 127) | ||
566 | sd->synchro = 1; | ||
567 | |||
568 | /* is there a frame start ? */ | ||
569 | if (sd->packet >= (gspca_dev->height >> 1) - 1) { | ||
570 | PDEBUG(D_PACK, "SOF > %d packet %d", sd->synchro, | ||
571 | sd->packet); | ||
572 | if (!sd->synchro) { /* start of frame */ | ||
573 | if (gspca_dev->last_packet_type == FIRST_PACKET) { | ||
574 | tv8532_preprocess(gspca_dev); | ||
575 | frame = gspca_frame_add(gspca_dev, | ||
576 | LAST_PACKET, | ||
577 | frame, sd->tmpbuf2, | ||
578 | gspca_dev->width * | ||
579 | gspca_dev->width); | ||
580 | } | ||
581 | gspca_frame_add(gspca_dev, FIRST_PACKET, | ||
582 | frame, data, 0); | ||
583 | memcpy(sd->tmpbuf, data, len); | ||
584 | sd->buflen = len; | ||
585 | sd->packet = 0; | ||
586 | return; | ||
587 | } | ||
588 | if (gspca_dev->last_packet_type != DISCARD_PACKET) { | ||
589 | PDEBUG(D_PACK, | ||
590 | "Warning wrong TV8532 frame detection %d", | ||
591 | sd->packet); | ||
592 | gspca_dev->last_packet_type = DISCARD_PACKET; | ||
593 | } | ||
594 | return; | ||
595 | } | ||
596 | |||
597 | if (!sd->synchro) { | ||
598 | /* Drop packet frame corrupt */ | ||
599 | PDEBUG(D_PACK, "DROP SOF %d packet %d", | ||
600 | sd->synchro, sd->packet); | ||
601 | sd->packet = 0; | ||
602 | gspca_dev->last_packet_type = DISCARD_PACKET; | ||
603 | return; | ||
604 | } | ||
605 | sd->synchro = 1; | ||
606 | sd->packet++; | ||
607 | memcpy(&sd->tmpbuf[sd->buflen], data, len); | ||
608 | sd->buflen += len; | ||
609 | } | ||
610 | |||
611 | static void setcontrast(struct gspca_dev *gspca_dev) | ||
612 | { | ||
613 | } | ||
614 | |||
615 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | ||
616 | { | ||
617 | struct sd *sd = (struct sd *) gspca_dev; | ||
618 | |||
619 | sd->brightness = val; | ||
620 | if (gspca_dev->streaming) | ||
621 | setbrightness(gspca_dev); | ||
622 | return 0; | ||
623 | } | ||
624 | |||
625 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
626 | { | ||
627 | struct sd *sd = (struct sd *) gspca_dev; | ||
628 | |||
629 | *val = sd->brightness; | ||
630 | return 0; | ||
631 | } | ||
632 | |||
633 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | ||
634 | { | ||
635 | struct sd *sd = (struct sd *) gspca_dev; | ||
636 | |||
637 | sd->contrast = val; | ||
638 | if (gspca_dev->streaming) | ||
639 | setcontrast(gspca_dev); | ||
640 | return 0; | ||
641 | } | ||
642 | |||
643 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) | ||
644 | { | ||
645 | struct sd *sd = (struct sd *) gspca_dev; | ||
646 | |||
647 | *val = sd->contrast; | ||
648 | return 0; | ||
649 | } | ||
650 | |||
651 | /* sub-driver description */ | ||
652 | static struct sd_desc sd_desc = { | ||
653 | .name = MODULE_NAME, | ||
654 | .ctrls = sd_ctrls, | ||
655 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
656 | .config = sd_config, | ||
657 | .open = sd_open, | ||
658 | .start = sd_start, | ||
659 | .stopN = sd_stopN, | ||
660 | .stop0 = sd_stop0, | ||
661 | .close = sd_close, | ||
662 | .pkt_scan = sd_pkt_scan, | ||
663 | }; | ||
664 | |||
665 | /* -- module initialisation -- */ | ||
666 | #define DVNM(name) .driver_info = (kernel_ulong_t) name | ||
667 | static __devinitdata struct usb_device_id device_table[] = { | ||
668 | {USB_DEVICE(0x046d, 0x0920), DVNM("QC Express")}, | ||
669 | {USB_DEVICE(0x046d, 0x0921), DVNM("Labtec Webcam")}, | ||
670 | {USB_DEVICE(0x0545, 0x808b), DVNM("Veo Stingray")}, | ||
671 | {USB_DEVICE(0x0545, 0x8333), DVNM("Veo Stingray")}, | ||
672 | {USB_DEVICE(0x0923, 0x010f), DVNM("ICM532 cams")}, | ||
673 | {} | ||
674 | }; | ||
675 | |||
676 | MODULE_DEVICE_TABLE(usb, device_table); | ||
677 | |||
678 | /* -- device connect -- */ | ||
679 | static int sd_probe(struct usb_interface *intf, | ||
680 | const struct usb_device_id *id) | ||
681 | { | ||
682 | return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), | ||
683 | THIS_MODULE); | ||
684 | } | ||
685 | |||
686 | static struct usb_driver sd_driver = { | ||
687 | .name = MODULE_NAME, | ||
688 | .id_table = device_table, | ||
689 | .probe = sd_probe, | ||
690 | .disconnect = gspca_disconnect, | ||
691 | }; | ||
692 | |||
693 | /* -- module insert / remove -- */ | ||
694 | static int __init sd_mod_init(void) | ||
695 | { | ||
696 | if (usb_register(&sd_driver) < 0) | ||
697 | return -1; | ||
698 | PDEBUG(D_PROBE, "v%s registered", version); | ||
699 | return 0; | ||
700 | } | ||
701 | |||
702 | static void __exit sd_mod_exit(void) | ||
703 | { | ||
704 | usb_deregister(&sd_driver); | ||
705 | PDEBUG(D_PROBE, "deregistered"); | ||
706 | } | ||
707 | |||
708 | module_init(sd_mod_init); | ||
709 | module_exit(sd_mod_exit); | ||
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c new file mode 100644 index 000000000000..8b5f6d17d2a5 --- /dev/null +++ b/drivers/media/video/gspca/vc032x.c | |||
@@ -0,0 +1,1816 @@ | |||
1 | /* | ||
2 | * Z-star vc0321 library | ||
3 | * Copyright (C) 2006 Koninski Artur takeshi87@o2.pl | ||
4 | * Copyright (C) 2006 Michel Xhaard | ||
5 | * | ||
6 | * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
21 | */ | ||
22 | |||
23 | #define MODULE_NAME "vc032x" | ||
24 | |||
25 | #include "gspca.h" | ||
26 | |||
27 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) | ||
28 | static const char version[] = "2.1.0"; | ||
29 | |||
30 | MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); | ||
31 | MODULE_DESCRIPTION("GSPCA/VC032X USB Camera Driver"); | ||
32 | MODULE_LICENSE("GPL"); | ||
33 | |||
34 | /* specific webcam descriptor */ | ||
35 | struct sd { | ||
36 | struct gspca_dev gspca_dev; /* !! must be the first item */ | ||
37 | |||
38 | unsigned char autogain; | ||
39 | unsigned char lightfreq; | ||
40 | |||
41 | char qindex; | ||
42 | char bridge; | ||
43 | #define BRIDGE_VC0321 0 | ||
44 | #define BRIDGE_VC0323 1 | ||
45 | char sensor; | ||
46 | #define SENSOR_HV7131R 0 | ||
47 | #define SENSOR_MI1320 1 | ||
48 | #define SENSOR_MI1310_SOC 2 | ||
49 | #define SENSOR_OV7660 3 | ||
50 | #define SENSOR_OV7670 4 | ||
51 | #define SENSOR_PO3130NC 5 | ||
52 | }; | ||
53 | |||
54 | /* V4L2 controls supported by the driver */ | ||
55 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); | ||
56 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); | ||
57 | static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); | ||
58 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); | ||
59 | |||
60 | static struct ctrl sd_ctrls[] = { | ||
61 | #define SD_AUTOGAIN 0 | ||
62 | { | ||
63 | { | ||
64 | .id = V4L2_CID_AUTOGAIN, | ||
65 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
66 | .name = "Auto Gain", | ||
67 | .minimum = 0, | ||
68 | .maximum = 1, | ||
69 | .step = 1, | ||
70 | .default_value = 1, | ||
71 | }, | ||
72 | .set = sd_setautogain, | ||
73 | .get = sd_getautogain, | ||
74 | }, | ||
75 | #define SD_FREQ 1 | ||
76 | { | ||
77 | { | ||
78 | .id = V4L2_CID_POWER_LINE_FREQUENCY, | ||
79 | .type = V4L2_CTRL_TYPE_MENU, | ||
80 | .name = "Light frequency filter", | ||
81 | .minimum = 0, | ||
82 | .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */ | ||
83 | .step = 1, | ||
84 | .default_value = 1, | ||
85 | }, | ||
86 | .set = sd_setfreq, | ||
87 | .get = sd_getfreq, | ||
88 | }, | ||
89 | }; | ||
90 | |||
91 | static struct cam_mode vc0321_mode[] = { | ||
92 | {V4L2_PIX_FMT_YUYV, 320, 240, 1}, | ||
93 | {V4L2_PIX_FMT_YUYV, 640, 480, 0}, | ||
94 | }; | ||
95 | static struct cam_mode vc0323_mode[] = { | ||
96 | {V4L2_PIX_FMT_JPEG, 320, 240, 1}, | ||
97 | {V4L2_PIX_FMT_JPEG, 640, 480, 0}, | ||
98 | }; | ||
99 | |||
100 | static __u8 mi1310_socinitVGA_JPG[][4] = { | ||
101 | {0xb0, 0x03, 0x19, 0xcc}, | ||
102 | {0xb0, 0x04, 0x02, 0xcc}, | ||
103 | {0xb3, 0x00, 0x64, 0xcc}, | ||
104 | {0xb3, 0x00, 0x65, 0xcc}, | ||
105 | {0xb3, 0x05, 0x00, 0xcc}, | ||
106 | {0xb3, 0x06, 0x00, 0xcc}, | ||
107 | {0xb3, 0x08, 0x01, 0xcc}, | ||
108 | {0xb3, 0x09, 0x0c, 0xcc}, | ||
109 | {0xb3, 0x34, 0x02, 0xcc}, | ||
110 | {0xb3, 0x35, 0xdd, 0xcc}, | ||
111 | {0xb3, 0x02, 0x00, 0xcc}, | ||
112 | {0xb3, 0x03, 0x0a, 0xcc}, | ||
113 | {0xb3, 0x04, 0x05, 0xcc}, | ||
114 | {0xb3, 0x20, 0x00, 0xcc}, | ||
115 | {0xb3, 0x21, 0x00, 0xcc}, | ||
116 | {0xb3, 0x22, 0x03, 0xcc}, | ||
117 | {0xb3, 0x23, 0xc0, 0xcc}, | ||
118 | {0xb3, 0x14, 0x00, 0xcc}, | ||
119 | {0xb3, 0x15, 0x00, 0xcc}, | ||
120 | {0xb3, 0x16, 0x04, 0xcc}, | ||
121 | {0xb3, 0x17, 0xff, 0xcc}, | ||
122 | {0xb3, 0x00, 0x65, 0xcc}, | ||
123 | {0xb8, 0x00, 0x00, 0xcc}, | ||
124 | {0xbc, 0x00, 0xd0, 0xcc}, | ||
125 | {0xbc, 0x01, 0x01, 0xcc}, | ||
126 | {0xf0, 0x00, 0x02, 0xbb}, | ||
127 | {0xc8, 0x9f, 0x0b, 0xbb}, | ||
128 | {0x5b, 0x00, 0x01, 0xbb}, | ||
129 | {0x2f, 0xde, 0x20, 0xbb}, | ||
130 | {0xf0, 0x00, 0x00, 0xbb}, | ||
131 | {0x20, 0x03, 0x02, 0xbb}, | ||
132 | {0xf0, 0x00, 0x01, 0xbb}, | ||
133 | {0x05, 0x00, 0x07, 0xbb}, | ||
134 | {0x34, 0x00, 0x00, 0xbb}, | ||
135 | {0x35, 0xff, 0x00, 0xbb}, | ||
136 | {0xdc, 0x07, 0x02, 0xbb}, | ||
137 | {0xdd, 0x3c, 0x18, 0xbb}, | ||
138 | {0xde, 0x92, 0x6d, 0xbb}, | ||
139 | {0xdf, 0xcd, 0xb1, 0xbb}, | ||
140 | {0xe0, 0xff, 0xe7, 0xbb}, | ||
141 | {0x06, 0xf0, 0x0d, 0xbb}, | ||
142 | {0x06, 0x70, 0x0e, 0xbb}, | ||
143 | {0x4c, 0x00, 0x01, 0xbb}, | ||
144 | {0x4d, 0x00, 0x01, 0xbb}, | ||
145 | {0xf0, 0x00, 0x02, 0xbb}, | ||
146 | {0x2e, 0x0c, 0x55, 0xbb}, | ||
147 | {0x21, 0xb6, 0x6e, 0xbb}, | ||
148 | {0x36, 0x30, 0x10, 0xbb}, | ||
149 | {0x37, 0x00, 0xc1, 0xbb}, | ||
150 | {0xf0, 0x00, 0x00, 0xbb}, | ||
151 | {0x07, 0x00, 0x84, 0xbb}, | ||
152 | {0x08, 0x02, 0x4a, 0xbb}, | ||
153 | {0x05, 0x01, 0x10, 0xbb}, | ||
154 | {0x06, 0x00, 0x39, 0xbb}, | ||
155 | {0xf0, 0x00, 0x02, 0xbb}, | ||
156 | {0x58, 0x02, 0x67, 0xbb}, | ||
157 | {0x57, 0x02, 0x00, 0xbb}, | ||
158 | {0x5a, 0x02, 0x67, 0xbb}, | ||
159 | {0x59, 0x02, 0x00, 0xbb}, | ||
160 | {0x5c, 0x12, 0x0d, 0xbb}, | ||
161 | {0x5d, 0x16, 0x11, 0xbb}, | ||
162 | {0x39, 0x06, 0x18, 0xbb}, | ||
163 | {0x3a, 0x06, 0x18, 0xbb}, | ||
164 | {0x3b, 0x06, 0x18, 0xbb}, | ||
165 | {0x3c, 0x06, 0x18, 0xbb}, | ||
166 | {0x64, 0x7b, 0x5b, 0xbb}, | ||
167 | {0xf0, 0x00, 0x02, 0xbb}, | ||
168 | {0x36, 0x30, 0x10, 0xbb}, | ||
169 | {0x37, 0x00, 0xc0, 0xbb}, | ||
170 | {0xbc, 0x0e, 0x00, 0xcc}, | ||
171 | {0xbc, 0x0f, 0x05, 0xcc}, | ||
172 | {0xbc, 0x10, 0xc0, 0xcc}, | ||
173 | {0xbc, 0x11, 0x03, 0xcc}, | ||
174 | {0xb6, 0x00, 0x00, 0xcc}, | ||
175 | {0xb6, 0x03, 0x02, 0xcc}, | ||
176 | {0xb6, 0x02, 0x80, 0xcc}, | ||
177 | {0xb6, 0x05, 0x01, 0xcc}, | ||
178 | {0xb6, 0x04, 0xe0, 0xcc}, | ||
179 | {0xb6, 0x12, 0xf8, 0xcc}, | ||
180 | {0xb6, 0x13, 0x25, 0xcc}, | ||
181 | {0xb6, 0x18, 0x02, 0xcc}, | ||
182 | {0xb6, 0x17, 0x58, 0xcc}, | ||
183 | {0xb6, 0x16, 0x00, 0xcc}, | ||
184 | {0xb6, 0x22, 0x12, 0xcc}, | ||
185 | {0xb6, 0x23, 0x0b, 0xcc}, | ||
186 | {0xbf, 0xc0, 0x39, 0xcc}, | ||
187 | {0xbf, 0xc1, 0x04, 0xcc}, | ||
188 | {0xbf, 0xcc, 0x00, 0xcc}, | ||
189 | {0xbc, 0x02, 0x18, 0xcc}, | ||
190 | {0xbc, 0x03, 0x50, 0xcc}, | ||
191 | {0xbc, 0x04, 0x18, 0xcc}, | ||
192 | {0xbc, 0x05, 0x00, 0xcc}, | ||
193 | {0xbc, 0x06, 0x00, 0xcc}, | ||
194 | {0xbc, 0x08, 0x30, 0xcc}, | ||
195 | {0xbc, 0x09, 0x40, 0xcc}, | ||
196 | {0xbc, 0x0a, 0x10, 0xcc}, | ||
197 | {0xbc, 0x0b, 0x00, 0xcc}, | ||
198 | {0xbc, 0x0c, 0x00, 0xcc}, | ||
199 | {0xb3, 0x5c, 0x01, 0xcc}, | ||
200 | {0xf0, 0x00, 0x01, 0xbb}, | ||
201 | {0x80, 0x00, 0x03, 0xbb}, | ||
202 | {0x81, 0xc7, 0x14, 0xbb}, | ||
203 | {0x82, 0xeb, 0xe8, 0xbb}, | ||
204 | {0x83, 0xfe, 0xf4, 0xbb}, | ||
205 | {0x84, 0xcd, 0x10, 0xbb}, | ||
206 | {0x85, 0xf3, 0xee, 0xbb}, | ||
207 | {0x86, 0xff, 0xf1, 0xbb}, | ||
208 | {0x87, 0xcd, 0x10, 0xbb}, | ||
209 | {0x88, 0xf3, 0xee, 0xbb}, | ||
210 | {0x89, 0x01, 0xf1, 0xbb}, | ||
211 | {0x8a, 0xe5, 0x17, 0xbb}, | ||
212 | {0x8b, 0xe8, 0xe2, 0xbb}, | ||
213 | {0x8c, 0xf7, 0xed, 0xbb}, | ||
214 | {0x8d, 0x00, 0xff, 0xbb}, | ||
215 | {0x8e, 0xec, 0x10, 0xbb}, | ||
216 | {0x8f, 0xf0, 0xed, 0xbb}, | ||
217 | {0x90, 0xf9, 0xf2, 0xbb}, | ||
218 | {0x91, 0x00, 0x00, 0xbb}, | ||
219 | {0x92, 0xe9, 0x0d, 0xbb}, | ||
220 | {0x93, 0xf4, 0xf2, 0xbb}, | ||
221 | {0x94, 0xfb, 0xf5, 0xbb}, | ||
222 | {0x95, 0x00, 0xff, 0xbb}, | ||
223 | {0xb6, 0x0f, 0x08, 0xbb}, | ||
224 | {0xb7, 0x3d, 0x16, 0xbb}, | ||
225 | {0xb8, 0x0c, 0x04, 0xbb}, | ||
226 | {0xb9, 0x1c, 0x07, 0xbb}, | ||
227 | {0xba, 0x0a, 0x03, 0xbb}, | ||
228 | {0xbb, 0x1b, 0x09, 0xbb}, | ||
229 | {0xbc, 0x17, 0x0d, 0xbb}, | ||
230 | {0xbd, 0x23, 0x1d, 0xbb}, | ||
231 | {0xbe, 0x00, 0x28, 0xbb}, | ||
232 | {0xbf, 0x11, 0x09, 0xbb}, | ||
233 | {0xc0, 0x16, 0x15, 0xbb}, | ||
234 | {0xc1, 0x00, 0x1b, 0xbb}, | ||
235 | {0xc2, 0x0e, 0x07, 0xbb}, | ||
236 | {0xc3, 0x14, 0x10, 0xbb}, | ||
237 | {0xc4, 0x00, 0x17, 0xbb}, | ||
238 | {0x06, 0x74, 0x8e, 0xbb}, | ||
239 | {0xf0, 0x00, 0x01, 0xbb}, | ||
240 | {0x06, 0xf4, 0x8e, 0xbb}, | ||
241 | {0x00, 0x00, 0x50, 0xdd}, | ||
242 | {0x06, 0x74, 0x8e, 0xbb}, | ||
243 | {0xf0, 0x00, 0x02, 0xbb}, | ||
244 | {0x24, 0x50, 0x20, 0xbb}, | ||
245 | {0xf0, 0x00, 0x02, 0xbb}, | ||
246 | {0x34, 0x0c, 0x50, 0xbb}, | ||
247 | {0xb3, 0x01, 0x41, 0xcc}, | ||
248 | {0xf0, 0x00, 0x00, 0xbb}, | ||
249 | {0x03, 0x03, 0xc0, 0xbb}, | ||
250 | {}, | ||
251 | }; | ||
252 | static __u8 mi1310_socinitQVGA_JPG[][4] = { | ||
253 | {0xb0, 0x03, 0x19, 0xcc}, {0xb0, 0x04, 0x02, 0xcc}, | ||
254 | {0xb3, 0x00, 0x64, 0xcc}, {0xb3, 0x00, 0x65, 0xcc}, | ||
255 | {0xb3, 0x05, 0x00, 0xcc}, {0xb3, 0x06, 0x00, 0xcc}, | ||
256 | {0xb3, 0x08, 0x01, 0xcc}, {0xb3, 0x09, 0x0c, 0xcc}, | ||
257 | {0xb3, 0x34, 0x02, 0xcc}, {0xb3, 0x35, 0xdd, 0xcc}, | ||
258 | {0xb3, 0x02, 0x00, 0xcc}, {0xb3, 0x03, 0x0a, 0xcc}, | ||
259 | {0xb3, 0x04, 0x05, 0xcc}, {0xb3, 0x20, 0x00, 0xcc}, | ||
260 | {0xb3, 0x21, 0x00, 0xcc}, {0xb3, 0x22, 0x03, 0xcc}, | ||
261 | {0xb3, 0x23, 0xc0, 0xcc}, {0xb3, 0x14, 0x00, 0xcc}, | ||
262 | {0xb3, 0x15, 0x00, 0xcc}, {0xb3, 0x16, 0x04, 0xcc}, | ||
263 | {0xb3, 0x17, 0xff, 0xcc}, {0xb3, 0x00, 0x65, 0xcc}, | ||
264 | {0xb8, 0x00, 0x00, 0xcc}, {0xbc, 0x00, 0xf0, 0xcc}, | ||
265 | {0xbc, 0x01, 0x01, 0xcc}, {0xf0, 0x00, 0x02, 0xbb}, | ||
266 | {0xc8, 0x9f, 0x0b, 0xbb}, {0x5b, 0x00, 0x01, 0xbb}, | ||
267 | {0x2f, 0xde, 0x20, 0xbb}, {0xf0, 0x00, 0x00, 0xbb}, | ||
268 | {0x20, 0x03, 0x02, 0xbb}, {0xf0, 0x00, 0x01, 0xbb}, | ||
269 | {0x05, 0x00, 0x07, 0xbb}, {0x34, 0x00, 0x00, 0xbb}, | ||
270 | {0x35, 0xff, 0x00, 0xbb}, {0xdc, 0x07, 0x02, 0xbb}, | ||
271 | {0xdd, 0x3c, 0x18, 0xbb}, {0xde, 0x92, 0x6d, 0xbb}, | ||
272 | {0xdf, 0xcd, 0xb1, 0xbb}, {0xe0, 0xff, 0xe7, 0xbb}, | ||
273 | {0x06, 0xf0, 0x0d, 0xbb}, {0x06, 0x70, 0x0e, 0xbb}, | ||
274 | {0x4c, 0x00, 0x01, 0xbb}, {0x4d, 0x00, 0x01, 0xbb}, | ||
275 | {0xf0, 0x00, 0x02, 0xbb}, {0x2e, 0x0c, 0x55, 0xbb}, | ||
276 | {0x21, 0xb6, 0x6e, 0xbb}, {0x36, 0x30, 0x10, 0xbb}, | ||
277 | {0x37, 0x00, 0xc1, 0xbb}, {0xf0, 0x00, 0x00, 0xbb}, | ||
278 | {0x07, 0x00, 0x84, 0xbb}, {0x08, 0x02, 0x4a, 0xbb}, | ||
279 | {0x05, 0x01, 0x10, 0xbb}, {0x06, 0x00, 0x39, 0xbb}, | ||
280 | {0xf0, 0x00, 0x02, 0xbb}, {0x58, 0x02, 0x67, 0xbb}, | ||
281 | {0x57, 0x02, 0x00, 0xbb}, {0x5a, 0x02, 0x67, 0xbb}, | ||
282 | {0x59, 0x02, 0x00, 0xbb}, {0x5c, 0x12, 0x0d, 0xbb}, | ||
283 | {0x5d, 0x16, 0x11, 0xbb}, {0x39, 0x06, 0x18, 0xbb}, | ||
284 | {0x3a, 0x06, 0x18, 0xbb}, {0x3b, 0x06, 0x18, 0xbb}, | ||
285 | {0x3c, 0x06, 0x18, 0xbb}, {0x64, 0x7b, 0x5b, 0xbb}, | ||
286 | {0xf0, 0x00, 0x02, 0xbb}, {0x36, 0x30, 0x10, 0xbb}, | ||
287 | {0x37, 0x00, 0xc0, 0xbb}, {0xbc, 0x0e, 0x00, 0xcc}, | ||
288 | {0xbc, 0x0f, 0x05, 0xcc}, {0xbc, 0x10, 0xc0, 0xcc}, | ||
289 | {0xbc, 0x11, 0x03, 0xcc}, {0xb6, 0x00, 0x00, 0xcc}, | ||
290 | {0xb6, 0x03, 0x01, 0xcc}, {0xb6, 0x02, 0x40, 0xcc}, | ||
291 | {0xb6, 0x05, 0x00, 0xcc}, {0xb6, 0x04, 0xf0, 0xcc}, | ||
292 | {0xb6, 0x12, 0xf8, 0xcc}, {0xb6, 0x13, 0x25, 0xcc}, | ||
293 | {0xb6, 0x18, 0x00, 0xcc}, {0xb6, 0x17, 0x96, 0xcc}, | ||
294 | {0xb6, 0x16, 0x00, 0xcc}, {0xb6, 0x22, 0x12, 0xcc}, | ||
295 | {0xb6, 0x23, 0x0b, 0xcc}, {0xbf, 0xc0, 0x39, 0xcc}, | ||
296 | {0xbf, 0xc1, 0x04, 0xcc}, {0xbf, 0xcc, 0x00, 0xcc}, | ||
297 | {0xb3, 0x5c, 0x01, 0xcc}, {0xf0, 0x00, 0x01, 0xbb}, | ||
298 | {0x80, 0x00, 0x03, 0xbb}, {0x81, 0xc7, 0x14, 0xbb}, | ||
299 | {0x82, 0xeb, 0xe8, 0xbb}, {0x83, 0xfe, 0xf4, 0xbb}, | ||
300 | {0x84, 0xcd, 0x10, 0xbb}, {0x85, 0xf3, 0xee, 0xbb}, | ||
301 | {0x86, 0xff, 0xf1, 0xbb}, {0x87, 0xcd, 0x10, 0xbb}, | ||
302 | {0x88, 0xf3, 0xee, 0xbb}, {0x89, 0x01, 0xf1, 0xbb}, | ||
303 | {0x8a, 0xe5, 0x17, 0xbb}, {0x8b, 0xe8, 0xe2, 0xbb}, | ||
304 | {0x8c, 0xf7, 0xed, 0xbb}, {0x8d, 0x00, 0xff, 0xbb}, | ||
305 | {0x8e, 0xec, 0x10, 0xbb}, {0x8f, 0xf0, 0xed, 0xbb}, | ||
306 | {0x90, 0xf9, 0xf2, 0xbb}, {0x91, 0x00, 0x00, 0xbb}, | ||
307 | {0x92, 0xe9, 0x0d, 0xbb}, {0x93, 0xf4, 0xf2, 0xbb}, | ||
308 | {0x94, 0xfb, 0xf5, 0xbb}, {0x95, 0x00, 0xff, 0xbb}, | ||
309 | {0xb6, 0x0f, 0x08, 0xbb}, {0xb7, 0x3d, 0x16, 0xbb}, | ||
310 | {0xb8, 0x0c, 0x04, 0xbb}, {0xb9, 0x1c, 0x07, 0xbb}, | ||
311 | {0xba, 0x0a, 0x03, 0xbb}, {0xbb, 0x1b, 0x09, 0xbb}, | ||
312 | {0xbc, 0x17, 0x0d, 0xbb}, {0xbd, 0x23, 0x1d, 0xbb}, | ||
313 | {0xbe, 0x00, 0x28, 0xbb}, {0xbf, 0x11, 0x09, 0xbb}, | ||
314 | {0xc0, 0x16, 0x15, 0xbb}, {0xc1, 0x00, 0x1b, 0xbb}, | ||
315 | {0xc2, 0x0e, 0x07, 0xbb}, {0xc3, 0x14, 0x10, 0xbb}, | ||
316 | {0xc4, 0x00, 0x17, 0xbb}, {0x06, 0x74, 0x8e, 0xbb}, | ||
317 | {0xf0, 0x00, 0x01, 0xbb}, {0x06, 0xf4, 0x8e, 0xbb}, | ||
318 | {0x00, 0x00, 0x50, 0xdd}, {0x06, 0x74, 0x8e, 0xbb}, | ||
319 | {0xf0, 0x00, 0x02, 0xbb}, {0x24, 0x50, 0x20, 0xbb}, | ||
320 | {0xf0, 0x00, 0x02, 0xbb}, {0x34, 0x0c, 0x50, 0xbb}, | ||
321 | {0xb3, 0x01, 0x41, 0xcc}, {0xf0, 0x00, 0x00, 0xbb}, | ||
322 | {0x03, 0x03, 0xc0, 0xbb}, | ||
323 | {}, | ||
324 | }; | ||
325 | |||
326 | static __u8 mi1320_gamma[17] = { | ||
327 | 0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8, | ||
328 | 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff | ||
329 | }; | ||
330 | static __u8 mi1320_matrix[9] = { | ||
331 | 0x54, 0xda, 0x06, 0xf1, 0x50, 0xf4, 0xf7, 0xea, 0x52 | ||
332 | }; | ||
333 | static __u8 mi1320_initVGA_data[][4] = { | ||
334 | {0xb3, 0x01, 0x01, 0xcc}, {0x00, 0x00, 0x33, 0xdd}, | ||
335 | {0xb0, 0x03, 0x19, 0xcc}, {0x00, 0x00, 0x33, 0xdd}, | ||
336 | {0xb0, 0x04, 0x02, 0xcc}, {0x00, 0x00, 0x33, 0xdd}, | ||
337 | {0xb3, 0x00, 0x64, 0xcc}, {0xb3, 0x00, 0x65, 0xcc}, | ||
338 | {0xb0, 0x16, 0x03, 0xcc}, {0xb3, 0x05, 0x00, 0xcc}, | ||
339 | {0xb3, 0x06, 0x00, 0xcc}, {0xb3, 0x08, 0x01, 0xcc}, | ||
340 | {0xb3, 0x09, 0x0c, 0xcc}, {0xb3, 0x34, 0x02, 0xcc}, | ||
341 | {0xb3, 0x35, 0xc8, 0xcc}, {0xb3, 0x02, 0x00, 0xcc}, | ||
342 | {0xb3, 0x03, 0x0a, 0xcc}, {0xb3, 0x04, 0x05, 0xcc}, | ||
343 | {0xb3, 0x20, 0x00, 0xcc}, {0xb3, 0x21, 0x00, 0xcc}, | ||
344 | {0xb3, 0x22, 0x03, 0xcc}, {0xb3, 0x23, 0xc0, 0xcc}, | ||
345 | {0xb3, 0x14, 0x00, 0xcc}, {0xb3, 0x15, 0x00, 0xcc}, | ||
346 | {0xb3, 0x16, 0x04, 0xcc}, {0xb3, 0x17, 0xff, 0xcc}, | ||
347 | {0xb3, 0x00, 0x67, 0xcc}, {0xbc, 0x00, 0xd0, 0xcc}, | ||
348 | {0xbc, 0x01, 0x01, 0xcc}, {0xf0, 0x00, 0x00, 0xbb}, | ||
349 | {0x0d, 0x00, 0x09, 0xbb}, {0x00, 0x01, 0x00, 0xdd}, | ||
350 | {0x0d, 0x00, 0x08, 0xbb}, {0xf0, 0x00, 0x01, 0xbb}, | ||
351 | {0xa1, 0x05, 0x00, 0xbb}, {0xa4, 0x03, 0xc0, 0xbb}, | ||
352 | {0xf0, 0x00, 0x02, 0xbb}, {0x00, 0x00, 0x10, 0xdd}, | ||
353 | {0xc8, 0x9f, 0x0b, 0xbb}, {0x00, 0x00, 0x10, 0xdd}, | ||
354 | {0xf0, 0x00, 0x00, 0xbb}, {0x00, 0x00, 0x10, 0xdd}, | ||
355 | {0x20, 0x01, 0x00, 0xbb}, {0x00, 0x00, 0x10, 0xdd}, | ||
356 | {0xf0, 0x00, 0x01, 0xbb}, {0x9d, 0x3c, 0xa0, 0xbb}, | ||
357 | {0x47, 0x30, 0x30, 0xbb}, {0xf0, 0x00, 0x00, 0xbb}, | ||
358 | {0x0a, 0x80, 0x11, 0xbb}, {0x35, 0x00, 0x22, 0xbb}, | ||
359 | {0xf0, 0x00, 0x02, 0xbb}, {0x9d, 0xc5, 0x05, 0xbb}, | ||
360 | {0xdc, 0x0f, 0xfc, 0xbb}, {0xf0, 0x00, 0x01, 0xbb}, | ||
361 | {0x06, 0x74, 0x0e, 0xbb}, {0x80, 0x00, 0x06, 0xbb}, | ||
362 | {0x81, 0x04, 0x00, 0xbb}, {0x82, 0x01, 0x02, 0xbb}, | ||
363 | {0x83, 0x03, 0x02, 0xbb}, {0x84, 0x05, 0x00, 0xbb}, | ||
364 | {0x85, 0x01, 0x00, 0xbb}, {0x86, 0x03, 0x02, 0xbb}, | ||
365 | {0x87, 0x05, 0x00, 0xbb}, {0x88, 0x01, 0x00, 0xbb}, | ||
366 | {0x89, 0x02, 0x02, 0xbb}, {0x8a, 0xfd, 0x04, 0xbb}, | ||
367 | {0x8b, 0xfc, 0xfd, 0xbb}, {0x8c, 0xff, 0xfd, 0xbb}, | ||
368 | {0x8d, 0x00, 0x00, 0xbb}, {0x8e, 0xfe, 0x05, 0xbb}, | ||
369 | {0x8f, 0xfc, 0xfd, 0xbb}, {0x90, 0xfe, 0xfd, 0xbb}, | ||
370 | {0x91, 0x00, 0x00, 0xbb}, {0x92, 0xfe, 0x03, 0xbb}, | ||
371 | {0x93, 0xfd, 0xfe, 0xbb}, {0x94, 0xff, 0xfd, 0xbb}, | ||
372 | {0x95, 0x00, 0x00, 0xbb}, {0xb6, 0x07, 0x05, 0xbb}, | ||
373 | {0xb7, 0x13, 0x06, 0xbb}, {0xb8, 0x08, 0x06, 0xbb}, | ||
374 | {0xb9, 0x14, 0x08, 0xbb}, {0xba, 0x06, 0x05, 0xbb}, | ||
375 | {0xbb, 0x13, 0x06, 0xbb}, {0xbc, 0x03, 0x01, 0xbb}, | ||
376 | {0xbd, 0x03, 0x04, 0xbb}, {0xbe, 0x00, 0x02, 0xbb}, | ||
377 | {0xbf, 0x03, 0x01, 0xbb}, {0xc0, 0x02, 0x04, 0xbb}, | ||
378 | {0xc1, 0x00, 0x04, 0xbb}, {0xc2, 0x02, 0x01, 0xbb}, | ||
379 | {0xc3, 0x01, 0x03, 0xbb}, {0xc4, 0x00, 0x04, 0xbb}, | ||
380 | {0xf0, 0x00, 0x00, 0xbb}, {0x05, 0x01, 0x13, 0xbb}, | ||
381 | {0x06, 0x00, 0x11, 0xbb}, {0x07, 0x00, 0x85, 0xbb}, | ||
382 | {0x08, 0x00, 0x27, 0xbb}, {0x20, 0x01, 0x03, 0xbb}, | ||
383 | {0x21, 0x80, 0x00, 0xbb}, {0x22, 0x0d, 0x0f, 0xbb}, | ||
384 | {0x24, 0x80, 0x00, 0xbb}, {0x59, 0x00, 0xff, 0xbb}, | ||
385 | {0xf0, 0x00, 0x02, 0xbb}, {0x39, 0x03, 0x0d, 0xbb}, | ||
386 | {0x3a, 0x06, 0x1b, 0xbb}, {0x3b, 0x00, 0x95, 0xbb}, | ||
387 | {0x3c, 0x04, 0xdb, 0xbb}, {0x57, 0x02, 0x00, 0xbb}, | ||
388 | {0x58, 0x02, 0x66, 0xbb}, {0x59, 0x00, 0xff, 0xbb}, | ||
389 | {0x5a, 0x01, 0x33, 0xbb}, {0x5c, 0x12, 0x0d, 0xbb}, | ||
390 | {0x5d, 0x16, 0x11, 0xbb}, {0x64, 0x5e, 0x1c, 0xbb}, | ||
391 | {0xf0, 0x00, 0x02, 0xbb}, {0x2f, 0xd1, 0x00, 0xbb}, | ||
392 | {0x5b, 0x00, 0x01, 0xbb}, {0xf0, 0x00, 0x02, 0xbb}, | ||
393 | {0x36, 0x68, 0x10, 0xbb}, {0x00, 0x00, 0x30, 0xdd}, | ||
394 | {0x37, 0x82, 0x00, 0xbb}, {0xbc, 0x0e, 0x00, 0xcc}, | ||
395 | {0xbc, 0x0f, 0x05, 0xcc}, {0xbc, 0x10, 0xc0, 0xcc}, | ||
396 | {0xbc, 0x11, 0x03, 0xcc}, {0xb6, 0x00, 0x00, 0xcc}, | ||
397 | {0xb6, 0x03, 0x05, 0xcc}, {0xb6, 0x02, 0x00, 0xcc}, | ||
398 | {0xb6, 0x05, 0x04, 0xcc}, {0xb6, 0x04, 0x00, 0xcc}, | ||
399 | {0xb6, 0x12, 0xf8, 0xcc}, {0xb6, 0x13, 0x29, 0xcc}, | ||
400 | {0xb6, 0x18, 0x0a, 0xcc}, {0xb6, 0x17, 0x00, 0xcc}, | ||
401 | {0xb6, 0x16, 0x00, 0xcc}, {0xb6, 0x22, 0x12, 0xcc}, | ||
402 | {0xb6, 0x23, 0x0b, 0xcc}, {0xbf, 0xc0, 0x26, 0xcc}, | ||
403 | {0xbf, 0xc1, 0x02, 0xcc}, {0xbf, 0xcc, 0x04, 0xcc}, | ||
404 | {0xbc, 0x02, 0x18, 0xcc}, {0xbc, 0x03, 0x50, 0xcc}, | ||
405 | {0xbc, 0x04, 0x18, 0xcc}, {0xbc, 0x05, 0x00, 0xcc}, | ||
406 | {0xbc, 0x06, 0x00, 0xcc}, {0xbc, 0x08, 0x30, 0xcc}, | ||
407 | {0xbc, 0x09, 0x40, 0xcc}, {0xbc, 0x0a, 0x10, 0xcc}, | ||
408 | {0xbc, 0x0b, 0x00, 0xcc}, {0xbc, 0x0c, 0x00, 0xcc}, | ||
409 | {0xb3, 0x5c, 0x01, 0xcc}, {0xb3, 0x01, 0x41, 0xcc}, | ||
410 | {} | ||
411 | }; | ||
412 | static __u8 mi1320_initQVGA_data[][4] = { | ||
413 | {0xb3, 0x01, 0x01, 0xcc}, {0x00, 0x00, 0x33, 0xdd}, | ||
414 | {0xb0, 0x03, 0x19, 0xcc}, {0x00, 0x00, 0x33, 0xdd}, | ||
415 | {0xb0, 0x04, 0x02, 0xcc}, {0x00, 0x00, 0x33, 0xdd}, | ||
416 | {0xb3, 0x00, 0x64, 0xcc}, {0xb3, 0x00, 0x65, 0xcc}, | ||
417 | {0xb0, 0x16, 0x03, 0xcc}, {0xb3, 0x05, 0x01, 0xcc}, | ||
418 | {0xb3, 0x06, 0x01, 0xcc}, {0xb3, 0x08, 0x01, 0xcc}, | ||
419 | {0xb3, 0x09, 0x0c, 0xcc}, {0xb3, 0x34, 0x02, 0xcc}, | ||
420 | {0xb3, 0x35, 0xc8, 0xcc}, {0xb3, 0x02, 0x00, 0xcc}, | ||
421 | {0xb3, 0x03, 0x0a, 0xcc}, {0xb3, 0x04, 0x05, 0xcc}, | ||
422 | {0xb3, 0x20, 0x00, 0xcc}, {0xb3, 0x21, 0x00, 0xcc}, | ||
423 | {0xb3, 0x22, 0x01, 0xcc}, {0xb3, 0x23, 0xe0, 0xcc}, | ||
424 | {0xb3, 0x14, 0x00, 0xcc}, {0xb3, 0x15, 0x00, 0xcc}, | ||
425 | {0xb3, 0x16, 0x02, 0xcc}, {0xb3, 0x17, 0x7f, 0xcc}, | ||
426 | {0xb3, 0x00, 0x65, 0xcc}, {0xb8, 0x00, 0x00, 0xcc}, | ||
427 | {0xbc, 0x00, 0xd0, 0xcc}, {0xbc, 0x01, 0x01, 0xcc}, | ||
428 | {0xf0, 0x00, 0x00, 0xbb}, {0x0d, 0x00, 0x09, 0xbb}, | ||
429 | {0x00, 0x01, 0x00, 0xdd}, {0x0d, 0x00, 0x08, 0xbb}, | ||
430 | {0xf0, 0x00, 0x00, 0xbb}, {0x02, 0x00, 0x64, 0xbb}, | ||
431 | {0x05, 0x01, 0x78, 0xbb}, {0x06, 0x00, 0x11, 0xbb}, | ||
432 | {0x07, 0x01, 0x42, 0xbb}, {0x08, 0x00, 0x11, 0xbb}, | ||
433 | {0x20, 0x01, 0x00, 0xbb}, {0x21, 0x80, 0x00, 0xbb}, | ||
434 | {0x22, 0x0d, 0x0f, 0xbb}, {0x24, 0x80, 0x00, 0xbb}, | ||
435 | {0x59, 0x00, 0xff, 0xbb}, {0xf0, 0x00, 0x01, 0xbb}, | ||
436 | {0x9d, 0x3c, 0xa0, 0xbb}, {0x47, 0x30, 0x30, 0xbb}, | ||
437 | {0xf0, 0x00, 0x00, 0xbb}, {0x0a, 0x80, 0x11, 0xbb}, | ||
438 | {0x35, 0x00, 0x22, 0xbb}, {0xf0, 0x00, 0x02, 0xbb}, | ||
439 | {0x9d, 0xc5, 0x05, 0xbb}, {0xdc, 0x0f, 0xfc, 0xbb}, | ||
440 | {0xf0, 0x00, 0x01, 0xbb}, {0x06, 0x74, 0x0e, 0xbb}, | ||
441 | {0x80, 0x00, 0x06, 0xbb}, {0x81, 0x04, 0x00, 0xbb}, | ||
442 | {0x82, 0x01, 0x02, 0xbb}, {0x83, 0x03, 0x02, 0xbb}, | ||
443 | {0x84, 0x05, 0x00, 0xbb}, {0x85, 0x01, 0x00, 0xbb}, | ||
444 | {0x86, 0x03, 0x02, 0xbb}, {0x87, 0x05, 0x00, 0xbb}, | ||
445 | {0x88, 0x01, 0x00, 0xbb}, {0x89, 0x02, 0x02, 0xbb}, | ||
446 | {0x8a, 0xfd, 0x04, 0xbb}, {0x8b, 0xfc, 0xfd, 0xbb}, | ||
447 | {0x8c, 0xff, 0xfd, 0xbb}, {0x8d, 0x00, 0x00, 0xbb}, | ||
448 | {0x8e, 0xfe, 0x05, 0xbb}, {0x8f, 0xfc, 0xfd, 0xbb}, | ||
449 | {0x90, 0xfe, 0xfd, 0xbb}, {0x91, 0x00, 0x00, 0xbb}, | ||
450 | {0x92, 0xfe, 0x03, 0xbb}, {0x93, 0xfd, 0xfe, 0xbb}, | ||
451 | {0x94, 0xff, 0xfd, 0xbb}, {0x95, 0x00, 0x00, 0xbb}, | ||
452 | {0xb6, 0x07, 0x05, 0xbb}, {0xb7, 0x13, 0x06, 0xbb}, | ||
453 | {0xb8, 0x08, 0x06, 0xbb}, {0xb9, 0x14, 0x08, 0xbb}, | ||
454 | {0xba, 0x06, 0x05, 0xbb}, {0xbb, 0x13, 0x06, 0xbb}, | ||
455 | {0xbc, 0x03, 0x01, 0xbb}, {0xbd, 0x03, 0x04, 0xbb}, | ||
456 | {0xbe, 0x00, 0x02, 0xbb}, {0xbf, 0x03, 0x01, 0xbb}, | ||
457 | {0xc0, 0x02, 0x04, 0xbb}, {0xc1, 0x00, 0x04, 0xbb}, | ||
458 | {0xc2, 0x02, 0x01, 0xbb}, {0xc3, 0x01, 0x03, 0xbb}, | ||
459 | {0xc4, 0x00, 0x04, 0xbb}, {0xf0, 0x00, 0x02, 0xbb}, | ||
460 | {0xc8, 0x00, 0x00, 0xbb}, {0x2e, 0x00, 0x00, 0xbb}, | ||
461 | {0x2e, 0x0c, 0x5b, 0xbb}, {0x2f, 0xd1, 0x00, 0xbb}, | ||
462 | {0x39, 0x03, 0xca, 0xbb}, {0x3a, 0x06, 0x80, 0xbb}, | ||
463 | {0x3b, 0x01, 0x52, 0xbb}, {0x3c, 0x05, 0x40, 0xbb}, | ||
464 | {0x57, 0x01, 0x9c, 0xbb}, {0x58, 0x01, 0xee, 0xbb}, | ||
465 | {0x59, 0x00, 0xf0, 0xbb}, {0x5a, 0x01, 0x20, 0xbb}, | ||
466 | {0x5c, 0x1d, 0x17, 0xbb}, {0x5d, 0x22, 0x1c, 0xbb}, | ||
467 | {0x64, 0x1e, 0x1c, 0xbb}, {0x5b, 0x00, 0x01, 0xbb}, | ||
468 | {0xf0, 0x00, 0x02, 0xbb}, {0x36, 0x68, 0x10, 0xbb}, | ||
469 | {0x00, 0x00, 0x30, 0xdd}, {0x37, 0x81, 0x00, 0xbb}, | ||
470 | {0xbc, 0x02, 0x18, 0xcc}, {0xbc, 0x03, 0x50, 0xcc}, | ||
471 | {0xbc, 0x04, 0x18, 0xcc}, {0xbc, 0x05, 0x00, 0xcc}, | ||
472 | {0xbc, 0x06, 0x00, 0xcc}, {0xbc, 0x08, 0x30, 0xcc}, | ||
473 | {0xbc, 0x09, 0x40, 0xcc}, {0xbc, 0x0a, 0x10, 0xcc}, | ||
474 | {0xbc, 0x0b, 0x00, 0xcc}, {0xbc, 0x0c, 0x00, 0xcc}, | ||
475 | {0xbf, 0xc0, 0x26, 0xcc}, {0xbf, 0xc1, 0x02, 0xcc}, | ||
476 | {0xbf, 0xcc, 0x04, 0xcc}, {0xb3, 0x5c, 0x01, 0xcc}, | ||
477 | {0xb3, 0x01, 0x41, 0xcc}, | ||
478 | {} | ||
479 | }; | ||
480 | |||
481 | static __u8 po3130_gamma[17] = { | ||
482 | 0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8, | ||
483 | 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff | ||
484 | }; | ||
485 | static __u8 po3130_matrix[9] = { | ||
486 | 0x5f, 0xec, 0xf5, 0xf1, 0x5a, 0xf5, 0xf1, 0xec, 0x63 | ||
487 | }; | ||
488 | |||
489 | static __u8 po3130_initVGA_data[][4] = { | ||
490 | {0xb0, 0x4d, 0x00, 0xcc}, {0xb3, 0x01, 0x01, 0xcc}, | ||
491 | {0x00, 0x00, 0x50, 0xdd}, {0xb0, 0x03, 0x01, 0xcc}, | ||
492 | {0xb3, 0x00, 0x04, 0xcc}, {0xb3, 0x00, 0x24, 0xcc}, | ||
493 | {0xb3, 0x00, 0x25, 0xcc}, {0xb3, 0x08, 0x01, 0xcc}, | ||
494 | {0xb3, 0x09, 0x0c, 0xcc}, {0xb3, 0x05, 0x00, 0xcc}, | ||
495 | {0xb3, 0x06, 0x01, 0xcc}, {0xb3, 0x03, 0x1a, 0xcc}, | ||
496 | {0xb3, 0x04, 0x15, 0xcc}, {0xb3, 0x20, 0x00, 0xcc}, | ||
497 | {0xb3, 0x21, 0x00, 0xcc}, {0xb3, 0x22, 0x01, 0xcc}, | ||
498 | {0xb3, 0x23, 0xe8, 0xcc}, {0xb8, 0x08, 0xe8, 0xcc}, | ||
499 | {0xb3, 0x14, 0x00, 0xcc}, {0xb3, 0x15, 0x00, 0xcc}, | ||
500 | {0xb3, 0x16, 0x02, 0xcc}, {0xb3, 0x17, 0x7f, 0xcc}, | ||
501 | {0xb3, 0x34, 0x01, 0xcc}, {0xb3, 0x35, 0xf6, 0xcc}, | ||
502 | {0xb3, 0x00, 0x27, 0xcc}, {0xbc, 0x00, 0x71, 0xcc}, | ||
503 | {0xb8, 0x00, 0x21, 0xcc}, {0xb8, 0x27, 0x20, 0xcc}, | ||
504 | {0xb8, 0x01, 0x79, 0xcc}, {0xb8, 0x81, 0x09, 0xcc}, | ||
505 | {0xb8, 0x2c, 0x50, 0xcc}, {0xb8, 0x2d, 0xf8, 0xcc}, | ||
506 | {0xb8, 0x2e, 0xf8, 0xcc}, {0xb8, 0x2f, 0xf8, 0xcc}, | ||
507 | {0xb8, 0x30, 0x50, 0xcc}, {0xb8, 0x31, 0xf8, 0xcc}, | ||
508 | {0xb8, 0x32, 0xf8, 0xcc}, {0xb8, 0x33, 0xf8, 0xcc}, | ||
509 | {0xb8, 0x34, 0x50, 0xcc}, {0xb8, 0x35, 0x00, 0xcc}, | ||
510 | {0xb8, 0x36, 0x00, 0xcc}, {0xb8, 0x37, 0x00, 0xcc}, | ||
511 | {0x00, 0x1e, 0xc6, 0xaa}, {0x00, 0x20, 0x44, 0xaa}, | ||
512 | {0x00, 0xad, 0x02, 0xaa}, {0x00, 0xae, 0x2c, 0xaa}, | ||
513 | {0x00, 0x12, 0x08, 0xaa}, {0x00, 0x17, 0x41, 0xaa}, | ||
514 | {0x00, 0x19, 0x41, 0xaa}, {0x00, 0x1e, 0x06, 0xaa}, | ||
515 | {0x00, 0x21, 0x00, 0xaa}, {0x00, 0x36, 0xc0, 0xaa}, | ||
516 | {0x00, 0x37, 0xc8, 0xaa}, {0x00, 0x3b, 0x36, 0xaa}, | ||
517 | {0x00, 0x4b, 0xfe, 0xaa}, {0x00, 0x51, 0x1c, 0xaa}, | ||
518 | {0x00, 0x52, 0x01, 0xaa}, {0x00, 0x55, 0x0a, 0xaa}, | ||
519 | {0x00, 0x59, 0x02, 0xaa}, {0x00, 0x5a, 0x04, 0xaa}, | ||
520 | {0x00, 0x5c, 0x10, 0xaa}, {0x00, 0x5d, 0x10, 0xaa}, | ||
521 | {0x00, 0x5e, 0x10, 0xaa}, {0x00, 0x5f, 0x10, 0xaa}, | ||
522 | {0x00, 0x61, 0x00, 0xaa}, {0x00, 0x62, 0x18, 0xaa}, | ||
523 | {0x00, 0x63, 0x30, 0xaa}, {0x00, 0x70, 0x68, 0xaa}, | ||
524 | {0x00, 0x80, 0x71, 0xaa}, {0x00, 0x81, 0x08, 0xaa}, | ||
525 | {0x00, 0x82, 0x00, 0xaa}, {0x00, 0x83, 0x55, 0xaa}, | ||
526 | {0x00, 0x84, 0x06, 0xaa}, {0x00, 0x85, 0x06, 0xaa}, | ||
527 | {0x00, 0x86, 0x13, 0xaa}, {0x00, 0x87, 0x18, 0xaa}, | ||
528 | {0x00, 0xaa, 0x3f, 0xaa}, {0x00, 0xab, 0x44, 0xaa}, | ||
529 | {0x00, 0xb0, 0x68, 0xaa}, {0x00, 0xb5, 0x10, 0xaa}, | ||
530 | {0x00, 0xb8, 0x20, 0xaa}, {0x00, 0xb9, 0xa0, 0xaa}, | ||
531 | {0x00, 0xbc, 0x04, 0xaa}, {0x00, 0x8b, 0x40, 0xaa}, | ||
532 | {0x00, 0x8c, 0x91, 0xaa}, {0x00, 0x8d, 0x8f, 0xaa}, | ||
533 | {0x00, 0x8e, 0x91, 0xaa}, {0x00, 0x8f, 0x43, 0xaa}, | ||
534 | {0x00, 0x90, 0x92, 0xaa}, {0x00, 0x91, 0x89, 0xaa}, | ||
535 | {0x00, 0x92, 0x9d, 0xaa}, {0x00, 0x93, 0x46, 0xaa}, | ||
536 | {0x00, 0xd6, 0x22, 0xaa}, {0x00, 0x73, 0x00, 0xaa}, | ||
537 | {0x00, 0x74, 0x10, 0xaa}, {0x00, 0x75, 0x20, 0xaa}, | ||
538 | {0x00, 0x76, 0x2b, 0xaa}, {0x00, 0x77, 0x36, 0xaa}, | ||
539 | {0x00, 0x78, 0x49, 0xaa}, {0x00, 0x79, 0x5a, 0xaa}, | ||
540 | {0x00, 0x7a, 0x7f, 0xaa}, {0x00, 0x7b, 0x9b, 0xaa}, | ||
541 | {0x00, 0x7c, 0xba, 0xaa}, {0x00, 0x7d, 0xd4, 0xaa}, | ||
542 | {0x00, 0x7e, 0xea, 0xaa}, {0x00, 0xd6, 0x62, 0xaa}, | ||
543 | {0x00, 0x73, 0x00, 0xaa}, {0x00, 0x74, 0x10, 0xaa}, | ||
544 | {0x00, 0x75, 0x20, 0xaa}, {0x00, 0x76, 0x2b, 0xaa}, | ||
545 | {0x00, 0x77, 0x36, 0xaa}, {0x00, 0x78, 0x49, 0xaa}, | ||
546 | {0x00, 0x79, 0x5a, 0xaa}, {0x00, 0x7a, 0x7f, 0xaa}, | ||
547 | {0x00, 0x7b, 0x9b, 0xaa}, {0x00, 0x7c, 0xba, 0xaa}, | ||
548 | {0x00, 0x7d, 0xd4, 0xaa}, {0x00, 0x7e, 0xea, 0xaa}, | ||
549 | {0x00, 0xd6, 0xa2, 0xaa}, {0x00, 0x73, 0x00, 0xaa}, | ||
550 | {0x00, 0x74, 0x10, 0xaa}, {0x00, 0x75, 0x20, 0xaa}, | ||
551 | {0x00, 0x76, 0x2b, 0xaa}, {0x00, 0x77, 0x36, 0xaa}, | ||
552 | {0x00, 0x78, 0x49, 0xaa}, {0x00, 0x79, 0x5a, 0xaa}, | ||
553 | {0x00, 0x7a, 0x7f, 0xaa}, {0x00, 0x7b, 0x9b, 0xaa}, | ||
554 | {0x00, 0x7c, 0xba, 0xaa}, {0x00, 0x7d, 0xd4, 0xaa}, | ||
555 | {0x00, 0x7e, 0xea, 0xaa}, | ||
556 | {0x00, 0x4c, 0x07, 0xaa}, | ||
557 | {0x00, 0x4b, 0xe0, 0xaa}, {0x00, 0x4e, 0x77, 0xaa}, | ||
558 | {0x00, 0x59, 0x02, 0xaa}, {0x00, 0x4d, 0x0a, 0xaa}, | ||
559 | /* {0x00, 0xd1, 0x00, 0xaa}, {0x00, 0x20, 0xc4, 0xaa}, | ||
560 | {0xb8, 0x8e, 0x00, 0xcc}, {0xb8, 0x8f, 0xff, 0xcc}, */ | ||
561 | {0x00, 0xd1, 0x3c, 0xaa}, {0x00, 0x20, 0xc4, 0xaa}, | ||
562 | {0xb8, 0x8e, 0x00, 0xcc}, {0xb8, 0x8f, 0xff, 0xcc}, | ||
563 | {0xb8, 0xfe, 0x00, 0xcc}, {0xb8, 0xff, 0x28, 0xcc}, | ||
564 | {0xb9, 0x00, 0x28, 0xcc}, {0xb9, 0x01, 0x28, 0xcc}, | ||
565 | {0xb9, 0x02, 0x28, 0xcc}, {0xb9, 0x03, 0x00, 0xcc}, | ||
566 | {0xb9, 0x04, 0x00, 0xcc}, {0xb9, 0x05, 0x3c, 0xcc}, | ||
567 | {0xb9, 0x06, 0x3c, 0xcc}, {0xb9, 0x07, 0x3c, 0xcc}, | ||
568 | {0xb9, 0x08, 0x3c, 0xcc}, {0x00, 0x05, 0x00, 0xaa}, | ||
569 | {0xb3, 0x5c, 0x00, 0xcc}, {0xb3, 0x01, 0x41, 0xcc}, | ||
570 | {} | ||
571 | }; | ||
572 | static __u8 po3130_rundata[][4] = { | ||
573 | {0x00, 0x47, 0x45, 0xaa}, {0x00, 0x48, 0x9b, 0xaa}, | ||
574 | {0x00, 0x49, 0x3a, 0xaa}, {0x00, 0x4a, 0x01, 0xaa}, | ||
575 | {0x00, 0x44, 0x40, 0xaa}, | ||
576 | /* {0x00, 0xd5, 0x7c, 0xaa}, */ | ||
577 | {0x00, 0xad, 0x04, 0xaa}, {0x00, 0xae, 0x00, 0xaa}, | ||
578 | {0x00, 0xb0, 0x78, 0xaa}, {0x00, 0x98, 0x02, 0xaa}, | ||
579 | {0x00, 0x94, 0x25, 0xaa}, {0x00, 0x95, 0x25, 0xaa}, | ||
580 | {0x00, 0x59, 0x68, 0xaa}, {0x00, 0x44, 0x20, 0xaa}, | ||
581 | {0x00, 0x17, 0x50, 0xaa}, {0x00, 0x19, 0x50, 0xaa}, | ||
582 | {0x00, 0xd1, 0x3c, 0xaa}, {0x00, 0xd1, 0x3c, 0xaa}, | ||
583 | {0x00, 0x1e, 0x06, 0xaa}, {0x00, 0x1e, 0x06, 0xaa}, | ||
584 | {} | ||
585 | }; | ||
586 | |||
587 | static __u8 po3130_initQVGA_data[][4] = { | ||
588 | {0xb0, 0x4d, 0x00, 0xcc}, {0xb3, 0x01, 0x01, 0xcc}, | ||
589 | {0x00, 0x00, 0x50, 0xdd}, {0xb0, 0x03, 0x09, 0xcc}, | ||
590 | {0xb3, 0x00, 0x04, 0xcc}, {0xb3, 0x00, 0x24, 0xcc}, | ||
591 | {0xb3, 0x00, 0x25, 0xcc}, {0xb3, 0x08, 0x01, 0xcc}, | ||
592 | {0xb3, 0x09, 0x0c, 0xcc}, {0xb3, 0x05, 0x00, 0xcc}, | ||
593 | {0xb3, 0x06, 0x01, 0xcc}, {0xb3, 0x03, 0x1a, 0xcc}, | ||
594 | {0xb3, 0x04, 0x15, 0xcc}, {0xb3, 0x20, 0x00, 0xcc}, | ||
595 | {0xb3, 0x21, 0x00, 0xcc}, {0xb3, 0x22, 0x01, 0xcc}, | ||
596 | {0xb3, 0x23, 0xe0, 0xcc}, {0xb8, 0x08, 0xe0, 0xcc}, | ||
597 | {0xb3, 0x14, 0x00, 0xcc}, {0xb3, 0x15, 0x00, 0xcc}, | ||
598 | {0xb3, 0x16, 0x02, 0xcc}, {0xb3, 0x17, 0x7f, 0xcc}, | ||
599 | {0xb3, 0x34, 0x01, 0xcc}, {0xb3, 0x35, 0xf6, 0xcc}, | ||
600 | {0xb3, 0x00, 0x27, 0xcc}, {0xbc, 0x00, 0xd1, 0xcc}, | ||
601 | {0xb8, 0x00, 0x21, 0xcc}, {0xb8, 0x27, 0x20, 0xcc}, | ||
602 | {0xb8, 0x01, 0x79, 0xcc}, {0xb8, 0x81, 0x09, 0xcc}, | ||
603 | {0xb8, 0x2c, 0x50, 0xcc}, {0xb8, 0x2d, 0xf8, 0xcc}, | ||
604 | {0xb8, 0x2e, 0xf8, 0xcc}, {0xb8, 0x2f, 0xf8, 0xcc}, | ||
605 | {0xb8, 0x30, 0x50, 0xcc}, {0xb8, 0x31, 0xf8, 0xcc}, | ||
606 | {0xb8, 0x32, 0xf8, 0xcc}, {0xb8, 0x33, 0xf8, 0xcc}, | ||
607 | {0xb8, 0x34, 0x50, 0xcc}, {0xb8, 0x35, 0x00, 0xcc}, | ||
608 | {0xb8, 0x36, 0x00, 0xcc}, {0xb8, 0x37, 0x00, 0xcc}, | ||
609 | {0x00, 0x1e, 0xc6, 0xaa}, {0x00, 0x20, 0x44, 0xaa}, | ||
610 | {0x00, 0xad, 0x02, 0xaa}, {0x00, 0xae, 0x2c, 0xaa}, | ||
611 | {0x00, 0x12, 0x08, 0xaa}, {0x00, 0x17, 0x41, 0xaa}, | ||
612 | {0x00, 0x19, 0x41, 0xaa}, {0x00, 0x1e, 0x06, 0xaa}, | ||
613 | {0x00, 0x21, 0x00, 0xaa}, {0x00, 0x36, 0xc0, 0xaa}, | ||
614 | {0x00, 0x37, 0xc8, 0xaa}, {0x00, 0x3b, 0x36, 0xaa}, | ||
615 | {0x00, 0x4b, 0xfe, 0xaa}, {0x00, 0x51, 0x1c, 0xaa}, | ||
616 | {0x00, 0x52, 0x01, 0xaa}, {0x00, 0x55, 0x0a, 0xaa}, | ||
617 | {0x00, 0x59, 0x6f, 0xaa}, {0x00, 0x5a, 0x04, 0xaa}, | ||
618 | {0x00, 0x5c, 0x10, 0xaa}, {0x00, 0x5d, 0x10, 0xaa}, | ||
619 | {0x00, 0x5e, 0x10, 0xaa}, {0x00, 0x5f, 0x10, 0xaa}, | ||
620 | {0x00, 0x61, 0x00, 0xaa}, {0x00, 0x62, 0x18, 0xaa}, | ||
621 | {0x00, 0x63, 0x30, 0xaa}, {0x00, 0x70, 0x68, 0xaa}, | ||
622 | {0x00, 0x80, 0x71, 0xaa}, {0x00, 0x81, 0x08, 0xaa}, | ||
623 | {0x00, 0x82, 0x00, 0xaa}, {0x00, 0x83, 0x55, 0xaa}, | ||
624 | {0x00, 0x84, 0x06, 0xaa}, {0x00, 0x85, 0x06, 0xaa}, | ||
625 | {0x00, 0x86, 0x13, 0xaa}, {0x00, 0x87, 0x18, 0xaa}, | ||
626 | {0x00, 0xaa, 0x3f, 0xaa}, {0x00, 0xab, 0x44, 0xaa}, | ||
627 | {0x00, 0xb0, 0x68, 0xaa}, {0x00, 0xb5, 0x10, 0xaa}, | ||
628 | {0x00, 0xb8, 0x20, 0xaa}, {0x00, 0xb9, 0xa0, 0xaa}, | ||
629 | {0x00, 0xbc, 0x04, 0xaa}, {0x00, 0x8b, 0x40, 0xaa}, | ||
630 | {0x00, 0x8c, 0x91, 0xaa}, {0x00, 0x8d, 0x8f, 0xaa}, | ||
631 | {0x00, 0x8e, 0x91, 0xaa}, {0x00, 0x8f, 0x43, 0xaa}, | ||
632 | {0x00, 0x90, 0x92, 0xaa}, {0x00, 0x91, 0x89, 0xaa}, | ||
633 | {0x00, 0x92, 0x9d, 0xaa}, {0x00, 0x93, 0x46, 0xaa}, | ||
634 | {0x00, 0xd6, 0x22, 0xaa}, {0x00, 0x73, 0x00, 0xaa}, | ||
635 | {0x00, 0x74, 0x10, 0xaa}, {0x00, 0x75, 0x20, 0xaa}, | ||
636 | {0x00, 0x76, 0x2b, 0xaa}, {0x00, 0x77, 0x36, 0xaa}, | ||
637 | {0x00, 0x78, 0x49, 0xaa}, {0x00, 0x79, 0x5a, 0xaa}, | ||
638 | {0x00, 0x7a, 0x7f, 0xaa}, {0x00, 0x7b, 0x9b, 0xaa}, | ||
639 | {0x00, 0x7c, 0xba, 0xaa}, {0x00, 0x7d, 0xd4, 0xaa}, | ||
640 | {0x00, 0x7e, 0xea, 0xaa}, {0x00, 0xd6, 0x62, 0xaa}, | ||
641 | {0x00, 0x73, 0x00, 0xaa}, {0x00, 0x74, 0x10, 0xaa}, | ||
642 | {0x00, 0x75, 0x20, 0xaa}, {0x00, 0x76, 0x2b, 0xaa}, | ||
643 | {0x00, 0x77, 0x36, 0xaa}, {0x00, 0x78, 0x49, 0xaa}, | ||
644 | {0x00, 0x79, 0x5a, 0xaa}, {0x00, 0x7a, 0x7f, 0xaa}, | ||
645 | {0x00, 0x7b, 0x9b, 0xaa}, {0x00, 0x7c, 0xba, 0xaa}, | ||
646 | {0x00, 0x7d, 0xd4, 0xaa}, {0x00, 0x7e, 0xea, 0xaa}, | ||
647 | {0x00, 0xd6, 0xa2, 0xaa}, {0x00, 0x73, 0x00, 0xaa}, | ||
648 | {0x00, 0x74, 0x10, 0xaa}, {0x00, 0x75, 0x20, 0xaa}, | ||
649 | {0x00, 0x76, 0x2b, 0xaa}, {0x00, 0x77, 0x36, 0xaa}, | ||
650 | {0x00, 0x78, 0x49, 0xaa}, {0x00, 0x79, 0x5a, 0xaa}, | ||
651 | {0x00, 0x7a, 0x7f, 0xaa}, {0x00, 0x7b, 0x9b, 0xaa}, | ||
652 | {0x00, 0x7c, 0xba, 0xaa}, {0x00, 0x7d, 0xd4, 0xaa}, | ||
653 | {0x00, 0x7e, 0xea, 0xaa}, {0x00, 0x4c, 0x07, 0xaa}, | ||
654 | {0x00, 0x4b, 0xe0, 0xaa}, {0x00, 0x4e, 0x77, 0xaa}, | ||
655 | {0x00, 0x59, 0x66, 0xaa}, {0x00, 0x4d, 0x0a, 0xaa}, | ||
656 | {0x00, 0xd1, 0x00, 0xaa}, {0x00, 0x20, 0xc4, 0xaa}, | ||
657 | {0xb8, 0x8e, 0x00, 0xcc}, {0xb8, 0x8f, 0xff, 0xcc}, | ||
658 | {0xb8, 0xfe, 0x00, 0xcc}, {0xb8, 0xff, 0x28, 0xcc}, | ||
659 | {0xb9, 0x00, 0x28, 0xcc}, {0xb9, 0x01, 0x28, 0xcc}, | ||
660 | {0xb9, 0x02, 0x28, 0xcc}, {0xb9, 0x03, 0x00, 0xcc}, | ||
661 | {0xb9, 0x04, 0x00, 0xcc}, {0xb9, 0x05, 0x3c, 0xcc}, | ||
662 | {0xb9, 0x06, 0x3c, 0xcc}, {0xb9, 0x07, 0x3c, 0xcc}, | ||
663 | {0xb9, 0x08, 0x3c, 0xcc}, {0xbc, 0x02, 0x18, 0xcc}, | ||
664 | {0xbc, 0x03, 0x50, 0xcc}, {0xbc, 0x04, 0x18, 0xcc}, | ||
665 | {0xbc, 0x05, 0x00, 0xcc}, {0xbc, 0x06, 0x00, 0xcc}, | ||
666 | {0xbc, 0x08, 0x30, 0xcc}, {0xbc, 0x09, 0x40, 0xcc}, | ||
667 | {0xbc, 0x0a, 0x10, 0xcc}, {0xbc, 0x0b, 0x00, 0xcc}, | ||
668 | {0xbc, 0x0c, 0x00, 0xcc}, {0x00, 0x05, 0x00, 0xaa}, | ||
669 | {0xb3, 0x5c, 0x00, 0xcc}, {0xb3, 0x01, 0x41, 0xcc}, | ||
670 | {} | ||
671 | }; | ||
672 | |||
673 | static __u8 hv7131r_gamma[17] = { | ||
674 | /* 0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8, | ||
675 | * 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff */ | ||
676 | 0x04, 0x1a, 0x36, 0x55, 0x6f, 0x87, 0x9d, 0xb0, 0xc1, | ||
677 | 0xcf, 0xda, 0xe4, 0xec, 0xf3, 0xf8, 0xfd, 0xff | ||
678 | }; | ||
679 | static __u8 hv7131r_matrix[9] = { | ||
680 | 0x5f, 0xec, 0xf5, 0xf1, 0x5a, 0xf5, 0xf1, 0xec, 0x63 | ||
681 | }; | ||
682 | static __u8 hv7131r_initVGA_data[][4] = { | ||
683 | {0xb0, 0x4d, 0x00, 0xcc}, {0xb3, 0x01, 0x01, 0xcc}, | ||
684 | {0x00, 0x00, 0x50, 0xdd}, {0xb0, 0x03, 0x01, 0xcc}, | ||
685 | {0xb3, 0x00, 0x24, 0xcc}, | ||
686 | {0xb3, 0x00, 0x25, 0xcc}, {0xb3, 0x08, 0x01, 0xcc}, | ||
687 | {0xb3, 0x09, 0x0c, 0xcc}, {0xb3, 0x05, 0x00, 0xcc}, | ||
688 | {0xb3, 0x06, 0x01, 0xcc}, | ||
689 | {0xb3, 0x01, 0x45, 0xcc}, {0xb3, 0x03, 0x0b, 0xcc}, | ||
690 | {0xb3, 0x04, 0x05, 0xcc}, {0xb3, 0x20, 0x00, 0xcc}, | ||
691 | {0xb3, 0x21, 0x00, 0xcc}, | ||
692 | {0xb3, 0x22, 0x01, 0xcc}, {0xb3, 0x23, 0xe0, 0xcc}, | ||
693 | {0xb3, 0x14, 0x00, 0xcc}, {0xb3, 0x15, 0x00, 0xcc}, | ||
694 | {0xb3, 0x16, 0x02, 0xcc}, | ||
695 | {0xb3, 0x17, 0x7f, 0xcc}, {0xb3, 0x34, 0x01, 0xcc}, | ||
696 | {0xb3, 0x35, 0x91, 0xcc}, {0xb3, 0x00, 0x27, 0xcc}, | ||
697 | {0xbc, 0x00, 0x73, 0xcc}, | ||
698 | {0xb8, 0x00, 0x23, 0xcc}, {0x00, 0x01, 0x0c, 0xaa}, | ||
699 | {0x00, 0x14, 0x01, 0xaa}, {0x00, 0x15, 0xe6, 0xaa}, | ||
700 | {0x00, 0x16, 0x02, 0xaa}, | ||
701 | {0x00, 0x17, 0x86, 0xaa}, {0x00, 0x23, 0x00, 0xaa}, | ||
702 | {0x00, 0x25, 0x09, 0xaa}, {0x00, 0x26, 0x27, 0xaa}, | ||
703 | {0x00, 0x27, 0xc0, 0xaa}, | ||
704 | {0xb8, 0x2c, 0x60, 0xcc}, {0xb8, 0x2d, 0xf8, 0xcc}, | ||
705 | {0xb8, 0x2e, 0xf8, 0xcc}, {0xb8, 0x2f, 0xf8, 0xcc}, | ||
706 | {0xb8, 0x30, 0x50, 0xcc}, | ||
707 | {0xb8, 0x31, 0xf8, 0xcc}, {0xb8, 0x32, 0xf8, 0xcc}, | ||
708 | {0xb8, 0x33, 0xf8, 0xcc}, {0xb8, 0x34, 0x65, 0xcc}, | ||
709 | {0xb8, 0x35, 0x00, 0xcc}, | ||
710 | {0xb8, 0x36, 0x00, 0xcc}, {0xb8, 0x37, 0x00, 0xcc}, | ||
711 | {0xb8, 0x27, 0x20, 0xcc}, {0xb8, 0x01, 0x7d, 0xcc}, | ||
712 | {0xb8, 0x81, 0x09, 0xcc}, | ||
713 | {0xb3, 0x01, 0x41, 0xcc}, {0xb8, 0xfe, 0x00, 0xcc}, | ||
714 | {0xb8, 0xff, 0x28, 0xcc}, {0xb9, 0x00, 0x28, 0xcc}, | ||
715 | {0xb9, 0x01, 0x28, 0xcc}, | ||
716 | {0xb9, 0x02, 0x28, 0xcc}, {0xb9, 0x03, 0x00, 0xcc}, | ||
717 | {0xb9, 0x04, 0x00, 0xcc}, {0xb9, 0x05, 0x3c, 0xcc}, | ||
718 | {0xb9, 0x06, 0x3c, 0xcc}, | ||
719 | {0xb9, 0x07, 0x3c, 0xcc}, {0xb9, 0x08, 0x3c, 0xcc}, | ||
720 | {0xb8, 0x8e, 0x00, 0xcc}, {0xb8, 0x8f, 0xff, 0xcc}, | ||
721 | {0x00, 0x30, 0x18, 0xaa}, | ||
722 | {} | ||
723 | }; | ||
724 | |||
725 | static __u8 hv7131r_initQVGA_data[][4] = { | ||
726 | {0xb0, 0x4d, 0x00, 0xcc}, {0xb3, 0x01, 0x01, 0xcc}, | ||
727 | {0x00, 0x00, 0x50, 0xdd}, {0xb0, 0x03, 0x01, 0xcc}, | ||
728 | {0xb3, 0x00, 0x24, 0xcc}, | ||
729 | {0xb3, 0x00, 0x25, 0xcc}, {0xb3, 0x08, 0x01, 0xcc}, | ||
730 | {0xb3, 0x09, 0x0c, 0xcc}, {0xb3, 0x05, 0x00, 0xcc}, | ||
731 | {0xb3, 0x06, 0x01, 0xcc}, | ||
732 | {0xb3, 0x03, 0x0b, 0xcc}, {0xb3, 0x04, 0x05, 0xcc}, | ||
733 | {0xb3, 0x20, 0x00, 0xcc}, {0xb3, 0x21, 0x00, 0xcc}, | ||
734 | {0xb3, 0x22, 0x01, 0xcc}, | ||
735 | {0xb3, 0x23, 0xe0, 0xcc}, {0xb3, 0x14, 0x00, 0xcc}, | ||
736 | {0xb3, 0x15, 0x00, 0xcc}, {0xb3, 0x16, 0x02, 0xcc}, | ||
737 | {0xb3, 0x17, 0x7f, 0xcc}, | ||
738 | {0xb3, 0x34, 0x01, 0xcc}, {0xb3, 0x35, 0x91, 0xcc}, | ||
739 | {0xb3, 0x00, 0x27, 0xcc}, {0xbc, 0x00, 0xd1, 0xcc}, | ||
740 | {0xb8, 0x00, 0x21, 0xcc}, | ||
741 | {0x00, 0x01, 0x0c, 0xaa}, {0x00, 0x14, 0x01, 0xaa}, | ||
742 | {0x00, 0x15, 0xe6, 0xaa}, {0x00, 0x16, 0x02, 0xaa}, | ||
743 | {0x00, 0x17, 0x86, 0xaa}, | ||
744 | {0x00, 0x23, 0x00, 0xaa}, {0x00, 0x25, 0x01, 0xaa}, | ||
745 | {0x00, 0x26, 0xd4, 0xaa}, {0x00, 0x27, 0xc0, 0xaa}, | ||
746 | {0xbc, 0x02, 0x08, 0xcc}, | ||
747 | {0xbc, 0x03, 0x70, 0xcc}, {0xbc, 0x04, 0x08, 0xcc}, | ||
748 | {0xbc, 0x05, 0x00, 0xcc}, {0xbc, 0x06, 0x00, 0xcc}, | ||
749 | {0xbc, 0x08, 0x3c, 0xcc}, | ||
750 | {0xbc, 0x09, 0x40, 0xcc}, {0xbc, 0x0a, 0x04, 0xcc}, | ||
751 | {0xbc, 0x0b, 0x00, 0xcc}, {0xbc, 0x0c, 0x00, 0xcc}, | ||
752 | {0xb8, 0xfe, 0x02, 0xcc}, | ||
753 | {0xb8, 0xff, 0x07, 0xcc}, {0xb9, 0x00, 0x14, 0xcc}, | ||
754 | {0xb9, 0x01, 0x14, 0xcc}, {0xb9, 0x02, 0x14, 0xcc}, | ||
755 | {0xb9, 0x03, 0x00, 0xcc}, | ||
756 | {0xb9, 0x04, 0x02, 0xcc}, {0xb9, 0x05, 0x05, 0xcc}, | ||
757 | {0xb9, 0x06, 0x0f, 0xcc}, {0xb9, 0x07, 0x0f, 0xcc}, | ||
758 | {0xb9, 0x08, 0x0f, 0xcc}, | ||
759 | {0xb8, 0x2c, 0x60, 0xcc}, {0xb8, 0x2d, 0xf8, 0xcc}, | ||
760 | {0xb8, 0x2e, 0xf8, 0xcc}, {0xb8, 0x2f, 0xf8, 0xcc}, | ||
761 | {0xb8, 0x30, 0x50, 0xcc}, | ||
762 | {0xb8, 0x31, 0xf8, 0xcc}, {0xb8, 0x32, 0xf8, 0xcc}, | ||
763 | {0xb8, 0x33, 0xf8, 0xcc}, | ||
764 | {0xb8, 0x34, 0x65, 0xcc}, {0xb8, 0x35, 0x00, 0xcc}, | ||
765 | {0xb8, 0x36, 0x00, 0xcc}, {0xb8, 0x37, 0x00, 0xcc}, | ||
766 | {0xb8, 0x27, 0x20, 0xcc}, | ||
767 | {0xb8, 0x01, 0x7d, 0xcc}, {0xb8, 0x81, 0x09, 0xcc}, | ||
768 | {0xb3, 0x01, 0x41, 0xcc}, {0xb8, 0xfe, 0x00, 0xcc}, | ||
769 | {0xb8, 0xff, 0x28, 0xcc}, | ||
770 | {0xb9, 0x00, 0x28, 0xcc}, {0xb9, 0x01, 0x28, 0xcc}, | ||
771 | {0xb9, 0x02, 0x28, 0xcc}, {0xb9, 0x03, 0x00, 0xcc}, | ||
772 | {0xb9, 0x04, 0x00, 0xcc}, | ||
773 | {0xb9, 0x05, 0x3c, 0xcc}, {0xb9, 0x06, 0x3c, 0xcc}, | ||
774 | {0xb9, 0x07, 0x3c, 0xcc}, {0xb9, 0x08, 0x3c, 0xcc}, | ||
775 | {0xb8, 0x8e, 0x00, 0xcc}, | ||
776 | {0xb8, 0x8f, 0xff, 0xcc}, {0x00, 0x30, 0x18, 0xaa}, | ||
777 | {} | ||
778 | }; | ||
779 | |||
780 | static __u8 ov7660_gamma[17] = { | ||
781 | 0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8, | ||
782 | 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff | ||
783 | }; | ||
784 | static __u8 ov7660_matrix[9] = { | ||
785 | 0x5a, 0xf0, 0xf6, 0xf3, 0x57, 0xf6, 0xf3, 0xef, 0x62 | ||
786 | }; | ||
787 | static __u8 ov7660_initVGA_data[][4] = { | ||
788 | {0xb0, 0x4d, 0x00, 0xcc}, {0xb3, 0x01, 0x01, 0xcc}, | ||
789 | {0x00, 0x00, 0x50, 0xdd}, | ||
790 | {0xb0, 0x03, 0x01, 0xcc}, | ||
791 | {0xb3, 0x00, 0x21, 0xcc}, {0xb3, 0x00, 0x26, 0xcc}, | ||
792 | {0xb3, 0x05, 0x01, 0xcc}, | ||
793 | {0xb3, 0x06, 0x03, 0xcc}, | ||
794 | {0xb3, 0x03, 0x1f, 0xcc}, {0xb3, 0x04, 0x05, 0xcc}, | ||
795 | {0xb3, 0x05, 0x00, 0xcc}, | ||
796 | {0xb3, 0x06, 0x01, 0xcc}, | ||
797 | {0xb3, 0x15, 0x00, 0xcc},/* 0xb315 <-0 href startl */ | ||
798 | {0xb3, 0x16, 0x02, 0xcc}, {0xb3, 0x17, 0x7f, 0xcc}, | ||
799 | {0xb3, 0x21, 0x00, 0xcc}, | ||
800 | {0xb3, 0x23, 0xe0, 0xcc}, {0xb3, 0x1d, 0x01, 0xcc}, | ||
801 | {0xb3, 0x1f, 0x02, 0xcc}, | ||
802 | {0xb3, 0x34, 0x01, 0xcc}, | ||
803 | {0xb3, 0x35, 0xa1, 0xcc}, {0xb3, 0x00, 0x26, 0xcc}, | ||
804 | {0xb8, 0x00, 0x33, 0xcc}, /* 13 */ | ||
805 | {0xb8, 0x01, 0x7d, 0xcc}, | ||
806 | {0xbc, 0x00, 0x73, 0xcc}, {0xb8, 0x81, 0x09, 0xcc}, | ||
807 | {0xb8, 0x27, 0x20, 0xcc}, | ||
808 | {0xb8, 0x8f, 0x50, 0xcc}, | ||
809 | {0x00, 0x01, 0x80, 0xaa}, {0x00, 0x02, 0x80, 0xaa}, | ||
810 | {0x00, 0x12, 0x80, 0xaa}, | ||
811 | {0x00, 0x12, 0x05, 0xaa}, | ||
812 | {0x00, 0x1e, 0x01, 0xaa}, | ||
813 | {0x00, 0x3d, 0x40, 0xaa}, /* 0x3d <-40 gamma 01 */ | ||
814 | {0x00, 0x41, 0x00, 0xaa}, /* edge 00 */ | ||
815 | {0x00, 0x0d, 0x48, 0xaa}, {0x00, 0x0e, 0x04, 0xaa}, | ||
816 | {0x00, 0x13, 0xa7, 0xaa}, | ||
817 | {0x00, 0x40, 0xc1, 0xaa}, {0x00, 0x35, 0x00, 0xaa}, | ||
818 | {0x00, 0x36, 0x00, 0xaa}, | ||
819 | {0x00, 0x3c, 0x68, 0xaa}, {0x00, 0x1b, 0x05, 0xaa}, | ||
820 | {0x00, 0x39, 0x43, 0xaa}, | ||
821 | {0x00, 0x8d, 0xcf, 0xaa}, | ||
822 | {0x00, 0x8b, 0xcc, 0xaa}, {0x00, 0x8c, 0xcc, 0xaa}, | ||
823 | {0x00, 0x0f, 0x62, 0xaa}, | ||
824 | {0x00, 0x35, 0x84, 0xaa}, | ||
825 | {0x00, 0x3b, 0x08, 0xaa}, /* 0 * Nightframe 1/4 + 50Hz -> 0xC8 */ | ||
826 | {0x00, 0x3a, 0x00, 0xaa}, /* mx change yuyv format 00, 04, 01; 08, 0c*/ | ||
827 | {0x00, 0x14, 0x2a, 0xaa}, /* agc ampli */ | ||
828 | {0x00, 0x9e, 0x40, 0xaa}, {0xb8, 0x8f, 0x50, 0xcc}, | ||
829 | {0x00, 0x01, 0x80, 0xaa}, | ||
830 | {0x00, 0x02, 0x80, 0xaa}, | ||
831 | {0xb8, 0xfe, 0x00, 0xcc}, {0xb8, 0xff, 0x28, 0xcc}, | ||
832 | {0xb9, 0x00, 0x28, 0xcc}, | ||
833 | {0xb9, 0x01, 0x28, 0xcc}, {0xb9, 0x02, 0x28, 0xcc}, | ||
834 | {0xb9, 0x03, 0x00, 0xcc}, | ||
835 | {0xb9, 0x04, 0x00, 0xcc}, | ||
836 | {0xb9, 0x05, 0x3c, 0xcc}, {0xb9, 0x06, 0x3c, 0xcc}, | ||
837 | {0xb9, 0x07, 0x3c, 0xcc}, | ||
838 | {0xb9, 0x08, 0x3c, 0xcc}, | ||
839 | |||
840 | {0xb8, 0x8e, 0x00, 0xcc}, {0xb8, 0x8f, 0xff, 0xcc}, | ||
841 | |||
842 | {0x00, 0x29, 0x3c, 0xaa}, {0xb3, 0x01, 0x45, 0xcc}, | ||
843 | {} | ||
844 | }; | ||
845 | static __u8 ov7660_initQVGA_data[][4] = { | ||
846 | {0xb0, 0x4d, 0x00, 0xcc}, {0xb3, 0x01, 0x01, 0xcc}, | ||
847 | {0x00, 0x00, 0x50, 0xdd}, {0xb0, 0x03, 0x01, 0xcc}, | ||
848 | {0xb3, 0x00, 0x21, 0xcc}, {0xb3, 0x00, 0x26, 0xcc}, | ||
849 | {0xb3, 0x05, 0x01, 0xcc}, {0xb3, 0x06, 0x03, 0xcc}, | ||
850 | {0xb3, 0x03, 0x1f, 0xcc}, {0xb3, 0x04, 0x05, 0xcc}, | ||
851 | {0xb3, 0x05, 0x00, 0xcc}, {0xb3, 0x06, 0x01, 0xcc}, | ||
852 | {0xb3, 0x15, 0x00, 0xcc},/* 0xb315 <-0 href startl */ | ||
853 | {0xb3, 0x16, 0x02, 0xcc}, {0xb3, 0x17, 0x7f, 0xcc}, | ||
854 | {0xb3, 0x21, 0x00, 0xcc}, | ||
855 | {0xb3, 0x23, 0xe0, 0xcc}, {0xb3, 0x1d, 0x01, 0xcc}, | ||
856 | {0xb3, 0x1f, 0x02, 0xcc}, {0xb3, 0x34, 0x01, 0xcc}, | ||
857 | {0xb3, 0x35, 0xa1, 0xcc}, {0xb3, 0x00, 0x26, 0xcc}, | ||
858 | {0xb8, 0x00, 0x33, 0xcc}, /* 13 */ | ||
859 | {0xb8, 0x01, 0x7d, 0xcc}, | ||
860 | /* sizer */ | ||
861 | {0xbc, 0x00, 0xd3, 0xcc}, | ||
862 | {0xb8, 0x81, 0x09, 0xcc}, {0xb8, 0x81, 0x09, 0xcc}, | ||
863 | {0xb8, 0x27, 0x20, 0xcc}, {0xb8, 0x8f, 0x50, 0xcc}, | ||
864 | {0x00, 0x01, 0x80, 0xaa}, {0x00, 0x02, 0x80, 0xaa}, | ||
865 | {0x00, 0x12, 0x80, 0xaa}, {0x00, 0x12, 0x05, 0xaa}, | ||
866 | {0x00, 0x1e, 0x01, 0xaa}, | ||
867 | {0x00, 0x3d, 0x40, 0xaa}, /* 0x3d <-40 gamma 01 */ | ||
868 | {0x00, 0x41, 0x00, 0xaa}, /* edge 00 */ | ||
869 | {0x00, 0x0d, 0x48, 0xaa}, {0x00, 0x0e, 0x04, 0xaa}, | ||
870 | {0x00, 0x13, 0xa7, 0xaa}, | ||
871 | {0x00, 0x40, 0xc1, 0xaa}, {0x00, 0x35, 0x00, 0xaa}, | ||
872 | {0x00, 0x36, 0x00, 0xaa}, | ||
873 | {0x00, 0x3c, 0x68, 0xaa}, {0x00, 0x1b, 0x05, 0xaa}, | ||
874 | {0x00, 0x39, 0x43, 0xaa}, {0x00, 0x8d, 0xcf, 0xaa}, | ||
875 | {0x00, 0x8b, 0xcc, 0xaa}, {0x00, 0x8c, 0xcc, 0xaa}, | ||
876 | {0x00, 0x0f, 0x62, 0xaa}, {0x00, 0x35, 0x84, 0xaa}, | ||
877 | {0x00, 0x3b, 0x08, 0xaa}, /* 0 * Nightframe 1/4 + 50Hz -> 0xC8 */ | ||
878 | {0x00, 0x3a, 0x00, 0xaa}, /* mx change yuyv format 00, 04, 01; 08, 0c*/ | ||
879 | {0x00, 0x14, 0x2a, 0xaa}, /* agc ampli */ | ||
880 | {0x00, 0x9e, 0x40, 0xaa}, {0xb8, 0x8f, 0x50, 0xcc}, | ||
881 | {0x00, 0x01, 0x80, 0xaa}, | ||
882 | {0x00, 0x02, 0x80, 0xaa}, | ||
883 | /* sizer filters */ | ||
884 | {0xbc, 0x02, 0x08, 0xcc}, | ||
885 | {0xbc, 0x03, 0x70, 0xcc}, | ||
886 | {0xb8, 0x35, 0x00, 0xcc}, | ||
887 | {0xb8, 0x36, 0x00, 0xcc}, | ||
888 | {0xb8, 0x37, 0x00, 0xcc}, | ||
889 | {0xbc, 0x04, 0x08, 0xcc}, | ||
890 | {0xbc, 0x05, 0x00, 0xcc}, | ||
891 | {0xbc, 0x06, 0x00, 0xcc}, | ||
892 | {0xbc, 0x08, 0x3c, 0xcc}, | ||
893 | {0xbc, 0x09, 0x40, 0xcc}, | ||
894 | {0xbc, 0x0a, 0x04, 0xcc}, | ||
895 | {0xbc, 0x0b, 0x00, 0xcc}, | ||
896 | {0xbc, 0x0c, 0x00, 0xcc}, | ||
897 | /* */ | ||
898 | {0xb8, 0xfe, 0x00, 0xcc}, | ||
899 | {0xb8, 0xff, 0x28, 0xcc}, | ||
900 | /* */ | ||
901 | {0xb9, 0x00, 0x28, 0xcc}, {0xb9, 0x01, 0x28, 0xcc}, | ||
902 | {0xb9, 0x02, 0x28, 0xcc}, {0xb9, 0x03, 0x00, 0xcc}, | ||
903 | {0xb9, 0x04, 0x00, 0xcc}, {0xb9, 0x05, 0x3c, 0xcc}, | ||
904 | {0xb9, 0x06, 0x3c, 0xcc}, {0xb9, 0x07, 0x3c, 0xcc}, | ||
905 | {0xb9, 0x08, 0x3c, 0xcc}, | ||
906 | /* */ | ||
907 | {0xb8, 0x8e, 0x00, 0xcc}, | ||
908 | {0xb8, 0x8f, 0xff, 0xcc}, /* ff */ | ||
909 | {0x00, 0x29, 0x3c, 0xaa}, | ||
910 | {0xb3, 0x01, 0x45, 0xcc}, /* 45 */ | ||
911 | {0x00, 0x00, 0x00, 0x00} | ||
912 | }; | ||
913 | |||
914 | static __u8 ov7660_50HZ[][4] = { | ||
915 | {0x00, 0x3b, 0x08, 0xaa}, | ||
916 | {0x00, 0x9d, 0x40, 0xaa}, | ||
917 | {0x00, 0x13, 0xa7, 0xaa}, | ||
918 | {0x00, 0x00, 0x00, 0x00} | ||
919 | }; | ||
920 | |||
921 | static __u8 ov7660_60HZ[][4] = { | ||
922 | {0x00, 0x3b, 0x00, 0xaa}, | ||
923 | {0x00, 0x9e, 0x40, 0xaa}, | ||
924 | {0x00, 0x13, 0xa7, 0xaa}, | ||
925 | {} | ||
926 | }; | ||
927 | |||
928 | static __u8 ov7660_NoFliker[][4] = { | ||
929 | {0x00, 0x13, 0x87, 0xaa}, | ||
930 | {} | ||
931 | }; | ||
932 | |||
933 | static __u8 ov7670_initVGA_JPG[][4] = { | ||
934 | {0xb3, 0x01, 0x05, 0xcc}, | ||
935 | {0x00, 0x00, 0x30, 0xdd}, {0xb0, 0x03, 0x19, 0xcc}, | ||
936 | {0x00, 0x00, 0x10, 0xdd}, | ||
937 | {0xb0, 0x04, 0x02, 0xcc}, {0x00, 0x00, 0x10, 0xdd}, | ||
938 | {0xb3, 0x00, 0x66, 0xcc}, {0xb3, 0x00, 0x67, 0xcc}, | ||
939 | {0xb3, 0x35, 0xa1, 0xcc}, {0xb3, 0x34, 0x01, 0xcc}, | ||
940 | {0xb3, 0x05, 0x01, 0xcc}, {0xb3, 0x06, 0x01, 0xcc}, | ||
941 | {0xb3, 0x08, 0x01, 0xcc}, {0xb3, 0x09, 0x0c, 0xcc}, | ||
942 | {0xb3, 0x02, 0x02, 0xcc}, {0xb3, 0x03, 0x1f, 0xcc}, | ||
943 | {0xb3, 0x14, 0x00, 0xcc}, {0xb3, 0x15, 0x00, 0xcc}, | ||
944 | {0xb3, 0x16, 0x02, 0xcc}, {0xb3, 0x17, 0x7f, 0xcc}, | ||
945 | {0xb3, 0x04, 0x05, 0xcc}, {0xb3, 0x20, 0x00, 0xcc}, | ||
946 | {0xb3, 0x21, 0x00, 0xcc}, {0xb3, 0x22, 0x01, 0xcc}, | ||
947 | {0xb3, 0x23, 0xe0, 0xcc}, {0xbc, 0x00, 0x41, 0xcc}, | ||
948 | {0xbc, 0x01, 0x01, 0xcc}, {0x00, 0x12, 0x80, 0xaa}, | ||
949 | {0x00, 0x00, 0x20, 0xdd}, {0x00, 0x12, 0x00, 0xaa}, | ||
950 | {0x00, 0x11, 0x40, 0xaa}, {0x00, 0x6b, 0x0a, 0xaa}, | ||
951 | {0x00, 0x3a, 0x04, 0xaa}, {0x00, 0x40, 0xc0, 0xaa}, | ||
952 | {0x00, 0x8c, 0x00, 0xaa}, {0x00, 0x7a, 0x29, 0xaa}, | ||
953 | {0x00, 0x7b, 0x0e, 0xaa}, {0x00, 0x7c, 0x1a, 0xaa}, | ||
954 | {0x00, 0x7d, 0x31, 0xaa}, {0x00, 0x7e, 0x53, 0xaa}, | ||
955 | {0x00, 0x7f, 0x60, 0xaa}, {0x00, 0x80, 0x6b, 0xaa}, | ||
956 | {0x00, 0x81, 0x73, 0xaa}, {0x00, 0x82, 0x7b, 0xaa}, | ||
957 | {0x00, 0x83, 0x82, 0xaa}, {0x00, 0x84, 0x89, 0xaa}, | ||
958 | {0x00, 0x85, 0x96, 0xaa}, {0x00, 0x86, 0xa1, 0xaa}, | ||
959 | {0x00, 0x87, 0xb7, 0xaa}, {0x00, 0x88, 0xcc, 0xaa}, | ||
960 | {0x00, 0x89, 0xe1, 0xaa}, {0x00, 0x13, 0xe0, 0xaa}, | ||
961 | {0x00, 0x00, 0x00, 0xaa}, {0x00, 0x10, 0x00, 0xaa}, | ||
962 | {0x00, 0x0d, 0x40, 0xaa}, {0x00, 0x14, 0x28, 0xaa}, | ||
963 | {0x00, 0xa5, 0x05, 0xaa}, {0x00, 0xab, 0x07, 0xaa}, | ||
964 | {0x00, 0x24, 0x95, 0xaa}, {0x00, 0x25, 0x33, 0xaa}, | ||
965 | {0x00, 0x26, 0xe3, 0xaa}, {0x00, 0x9f, 0x88, 0xaa}, | ||
966 | {0x00, 0xa0, 0x78, 0xaa}, {0x00, 0x55, 0x90, 0xaa}, | ||
967 | {0x00, 0xa1, 0x03, 0xaa}, {0x00, 0xa6, 0xe0, 0xaa}, | ||
968 | {0x00, 0xa7, 0xd8, 0xaa}, {0x00, 0xa8, 0xf0, 0xaa}, | ||
969 | {0x00, 0xa9, 0x90, 0xaa}, {0x00, 0xaa, 0x14, 0xaa}, | ||
970 | {0x00, 0x13, 0xe5, 0xaa}, {0x00, 0x0e, 0x61, 0xaa}, | ||
971 | {0x00, 0x0f, 0x4b, 0xaa}, {0x00, 0x16, 0x02, 0xaa}, | ||
972 | {0x00, 0x1e, 0x07, 0xaa}, {0x00, 0x21, 0x02, 0xaa}, | ||
973 | {0x00, 0x22, 0x91, 0xaa}, {0x00, 0x29, 0x07, 0xaa}, | ||
974 | {0x00, 0x33, 0x0b, 0xaa}, {0x00, 0x35, 0x0b, 0xaa}, | ||
975 | {0x00, 0x37, 0x1d, 0xaa}, {0x00, 0x38, 0x71, 0xaa}, | ||
976 | {0x00, 0x39, 0x2a, 0xaa}, {0x00, 0x3c, 0x78, 0xaa}, | ||
977 | {0x00, 0x4d, 0x40, 0xaa}, {0x00, 0x4e, 0x20, 0xaa}, | ||
978 | {0x00, 0x74, 0x19, 0xaa}, {0x00, 0x8d, 0x4f, 0xaa}, | ||
979 | {0x00, 0x8e, 0x00, 0xaa}, {0x00, 0x8f, 0x00, 0xaa}, | ||
980 | {0x00, 0x90, 0x00, 0xaa}, {0x00, 0x91, 0x00, 0xaa}, | ||
981 | {0x00, 0x96, 0x00, 0xaa}, {0x00, 0x9a, 0x80, 0xaa}, | ||
982 | {0x00, 0xb0, 0x84, 0xaa}, {0x00, 0xb1, 0x0c, 0xaa}, | ||
983 | {0x00, 0xb2, 0x0e, 0xaa}, {0x00, 0xb3, 0x82, 0xaa}, | ||
984 | {0x00, 0xb8, 0x0a, 0xaa}, {0x00, 0x43, 0x14, 0xaa}, | ||
985 | {0x00, 0x44, 0xf0, 0xaa}, {0x00, 0x45, 0x45, 0xaa}, | ||
986 | {0x00, 0x46, 0x63, 0xaa}, {0x00, 0x47, 0x2d, 0xaa}, | ||
987 | {0x00, 0x48, 0x46, 0xaa}, {0x00, 0x59, 0x88, 0xaa}, | ||
988 | {0x00, 0x5a, 0xa0, 0xaa}, {0x00, 0x5b, 0xc6, 0xaa}, | ||
989 | {0x00, 0x5c, 0x7d, 0xaa}, {0x00, 0x5d, 0x5f, 0xaa}, | ||
990 | {0x00, 0x5e, 0x19, 0xaa}, {0x00, 0x6c, 0x0a, 0xaa}, | ||
991 | {0x00, 0x6d, 0x55, 0xaa}, {0x00, 0x6e, 0x11, 0xaa}, | ||
992 | {0x00, 0x6f, 0x9e, 0xaa}, {0x00, 0x69, 0x00, 0xaa}, | ||
993 | {0x00, 0x6a, 0x40, 0xaa}, {0x00, 0x01, 0x40, 0xaa}, | ||
994 | {0x00, 0x02, 0x40, 0xaa}, {0x00, 0x13, 0xe7, 0xaa}, | ||
995 | {0x00, 0x5f, 0xf0, 0xaa}, {0x00, 0x60, 0xf0, 0xaa}, | ||
996 | {0x00, 0x61, 0xf0, 0xaa}, {0x00, 0x27, 0xa0, 0xaa}, | ||
997 | {0x00, 0x28, 0x80, 0xaa}, {0x00, 0x2c, 0x90, 0xaa}, | ||
998 | {0x00, 0x4f, 0x66, 0xaa}, {0x00, 0x50, 0x66, 0xaa}, | ||
999 | {0x00, 0x51, 0x00, 0xaa}, {0x00, 0x52, 0x22, 0xaa}, | ||
1000 | {0x00, 0x53, 0x5e, 0xaa}, {0x00, 0x54, 0x80, 0xaa}, | ||
1001 | {0x00, 0x58, 0x9e, 0xaa}, {0x00, 0x41, 0x08, 0xaa}, | ||
1002 | {0x00, 0x3f, 0x00, 0xaa}, {0x00, 0x75, 0x85, 0xaa}, | ||
1003 | {0x00, 0x76, 0xe1, 0xaa}, {0x00, 0x4c, 0x00, 0xaa}, | ||
1004 | {0x00, 0x77, 0x0a, 0xaa}, {0x00, 0x3d, 0x88, 0xaa}, | ||
1005 | {0x00, 0x4b, 0x09, 0xaa}, {0x00, 0xc9, 0x60, 0xaa}, | ||
1006 | {0x00, 0x41, 0x38, 0xaa}, {0x00, 0x62, 0x30, 0xaa}, | ||
1007 | {0x00, 0x63, 0x30, 0xaa}, {0x00, 0x64, 0x08, 0xaa}, | ||
1008 | {0x00, 0x94, 0x07, 0xaa}, {0x00, 0x95, 0x0b, 0xaa}, | ||
1009 | {0x00, 0x65, 0x00, 0xaa}, {0x00, 0x66, 0x05, 0xaa}, | ||
1010 | {0x00, 0x56, 0x50, 0xaa}, {0x00, 0x34, 0x11, 0xaa}, | ||
1011 | {0x00, 0xa4, 0x88, 0xaa}, {0x00, 0x96, 0x00, 0xaa}, | ||
1012 | {0x00, 0x97, 0x30, 0xaa}, {0x00, 0x98, 0x20, 0xaa}, | ||
1013 | {0x00, 0x99, 0x30, 0xaa}, {0x00, 0x9a, 0x84, 0xaa}, | ||
1014 | {0x00, 0x9b, 0x29, 0xaa}, {0x00, 0x9c, 0x03, 0xaa}, | ||
1015 | {0x00, 0x78, 0x04, 0xaa}, {0x00, 0x79, 0x01, 0xaa}, | ||
1016 | {0x00, 0xc8, 0xf0, 0xaa}, {0x00, 0x79, 0x0f, 0xaa}, | ||
1017 | {0x00, 0xc8, 0x00, 0xaa}, {0x00, 0x79, 0x10, 0xaa}, | ||
1018 | {0x00, 0xc8, 0x7e, 0xaa}, {0x00, 0x79, 0x0a, 0xaa}, | ||
1019 | {0x00, 0xc8, 0x80, 0xaa}, {0x00, 0x79, 0x0b, 0xaa}, | ||
1020 | {0x00, 0xc8, 0x01, 0xaa}, {0x00, 0x79, 0x0c, 0xaa}, | ||
1021 | {0x00, 0xc8, 0x0f, 0xaa}, {0x00, 0x79, 0x0d, 0xaa}, | ||
1022 | {0x00, 0xc8, 0x20, 0xaa}, {0x00, 0x79, 0x09, 0xaa}, | ||
1023 | {0x00, 0xc8, 0x80, 0xaa}, {0x00, 0x79, 0x02, 0xaa}, | ||
1024 | {0x00, 0xc8, 0xc0, 0xaa}, {0x00, 0x79, 0x03, 0xaa}, | ||
1025 | {0x00, 0xc8, 0x40, 0xaa}, {0x00, 0x79, 0x05, 0xaa}, | ||
1026 | {0x00, 0xc8, 0x30, 0xaa}, {0x00, 0x79, 0x26, 0xaa}, | ||
1027 | {0x00, 0x11, 0x40, 0xaa}, {0x00, 0x3a, 0x04, 0xaa}, | ||
1028 | {0x00, 0x12, 0x00, 0xaa}, {0x00, 0x40, 0xc0, 0xaa}, | ||
1029 | {0x00, 0x8c, 0x00, 0xaa}, {0x00, 0x17, 0x14, 0xaa}, | ||
1030 | {0x00, 0x18, 0x02, 0xaa}, {0x00, 0x32, 0x92, 0xaa}, | ||
1031 | {0x00, 0x19, 0x02, 0xaa}, {0x00, 0x1a, 0x7a, 0xaa}, | ||
1032 | {0x00, 0x03, 0x0a, 0xaa}, {0x00, 0x0c, 0x00, 0xaa}, | ||
1033 | {0x00, 0x3e, 0x00, 0xaa}, {0x00, 0x70, 0x3a, 0xaa}, | ||
1034 | {0x00, 0x71, 0x35, 0xaa}, {0x00, 0x72, 0x11, 0xaa}, | ||
1035 | {0x00, 0x73, 0xf0, 0xaa}, {0x00, 0xa2, 0x02, 0xaa}, | ||
1036 | {0x00, 0xb1, 0x00, 0xaa}, {0x00, 0xb1, 0x0c, 0xaa}, | ||
1037 | {0x00, 0x1e, 0x37, 0xaa}, {0x00, 0xaa, 0x14, 0xaa}, | ||
1038 | {0x00, 0x24, 0x80, 0xaa}, {0x00, 0x25, 0x74, 0xaa}, | ||
1039 | {0x00, 0x26, 0xd3, 0xaa}, {0x00, 0x0d, 0x00, 0xaa}, | ||
1040 | {0x00, 0x14, 0x18, 0xaa}, {0x00, 0x9d, 0x99, 0xaa}, | ||
1041 | {0x00, 0x9e, 0x7f, 0xaa}, {0x00, 0x64, 0x08, 0xaa}, | ||
1042 | {0x00, 0x94, 0x07, 0xaa}, {0x00, 0x95, 0x06, 0xaa}, | ||
1043 | {0x00, 0x66, 0x05, 0xaa}, {0x00, 0x41, 0x08, 0xaa}, | ||
1044 | {0x00, 0x3f, 0x00, 0xaa}, {0x00, 0x75, 0x07, 0xaa}, | ||
1045 | {0x00, 0x76, 0xe1, 0xaa}, {0x00, 0x4c, 0x00, 0xaa}, | ||
1046 | {0x00, 0x77, 0x00, 0xaa}, {0x00, 0x3d, 0xc2, 0xaa}, | ||
1047 | {0x00, 0x4b, 0x09, 0xaa}, {0x00, 0xc9, 0x60, 0xaa}, | ||
1048 | {0x00, 0x41, 0x38, 0xaa}, {0xb6, 0x00, 0x00, 0xcc}, | ||
1049 | {0xb6, 0x03, 0x02, 0xcc}, {0xb6, 0x02, 0x80, 0xcc}, | ||
1050 | {0xb6, 0x05, 0x01, 0xcc}, {0xb6, 0x04, 0xe0, 0xcc}, | ||
1051 | {0xb6, 0x12, 0xf8, 0xcc}, {0xb6, 0x13, 0x13, 0xcc}, | ||
1052 | {0xb6, 0x18, 0x02, 0xcc}, {0xb6, 0x17, 0x58, 0xcc}, | ||
1053 | {0xb6, 0x16, 0x00, 0xcc}, {0xb6, 0x22, 0x12, 0xcc}, | ||
1054 | {0xb6, 0x23, 0x0b, 0xcc}, {0xbf, 0xc0, 0x39, 0xcc}, | ||
1055 | {0xbf, 0xc1, 0x04, 0xcc}, {0xbf, 0xcc, 0x00, 0xcc}, | ||
1056 | {0xb3, 0x5c, 0x01, 0xcc}, {0xb3, 0x01, 0x45, 0xcc}, | ||
1057 | {0x00, 0x77, 0x05, 0xaa}, | ||
1058 | {}, | ||
1059 | }; | ||
1060 | |||
1061 | static __u8 ov7670_initQVGA_JPG[][4] = { | ||
1062 | {0xb3, 0x01, 0x05, 0xcc}, {0x00, 0x00, 0x30, 0xdd}, | ||
1063 | {0xb0, 0x03, 0x19, 0xcc}, {0x00, 0x00, 0x10, 0xdd}, | ||
1064 | {0xb0, 0x04, 0x02, 0xcc}, {0x00, 0x00, 0x10, 0xdd}, | ||
1065 | {0xb3, 0x00, 0x66, 0xcc}, {0xb3, 0x00, 0x67, 0xcc}, | ||
1066 | {0xb3, 0x35, 0xa1, 0xcc}, {0xb3, 0x34, 0x01, 0xcc}, | ||
1067 | {0xb3, 0x05, 0x01, 0xcc}, {0xb3, 0x06, 0x01, 0xcc}, | ||
1068 | {0xb3, 0x08, 0x01, 0xcc}, {0xb3, 0x09, 0x0c, 0xcc}, | ||
1069 | {0xb3, 0x02, 0x02, 0xcc}, {0xb3, 0x03, 0x1f, 0xcc}, | ||
1070 | {0xb3, 0x14, 0x00, 0xcc}, {0xb3, 0x15, 0x00, 0xcc}, | ||
1071 | {0xb3, 0x16, 0x02, 0xcc}, {0xb3, 0x17, 0x7f, 0xcc}, | ||
1072 | {0xb3, 0x04, 0x05, 0xcc}, {0xb3, 0x20, 0x00, 0xcc}, | ||
1073 | {0xb3, 0x21, 0x00, 0xcc}, {0xb3, 0x22, 0x01, 0xcc}, | ||
1074 | {0xb3, 0x23, 0xe0, 0xcc}, {0xbc, 0x00, 0xd1, 0xcc}, | ||
1075 | {0xbc, 0x01, 0x01, 0xcc}, {0x00, 0x12, 0x80, 0xaa}, | ||
1076 | {0x00, 0x00, 0x20, 0xdd}, {0x00, 0x12, 0x00, 0xaa}, | ||
1077 | {0x00, 0x11, 0x40, 0xaa}, {0x00, 0x6b, 0x0a, 0xaa}, | ||
1078 | {0x00, 0x3a, 0x04, 0xaa}, {0x00, 0x40, 0xc0, 0xaa}, | ||
1079 | {0x00, 0x8c, 0x00, 0xaa}, {0x00, 0x7a, 0x29, 0xaa}, | ||
1080 | {0x00, 0x7b, 0x0e, 0xaa}, {0x00, 0x7c, 0x1a, 0xaa}, | ||
1081 | {0x00, 0x7d, 0x31, 0xaa}, {0x00, 0x7e, 0x53, 0xaa}, | ||
1082 | {0x00, 0x7f, 0x60, 0xaa}, {0x00, 0x80, 0x6b, 0xaa}, | ||
1083 | {0x00, 0x81, 0x73, 0xaa}, {0x00, 0x82, 0x7b, 0xaa}, | ||
1084 | {0x00, 0x83, 0x82, 0xaa}, {0x00, 0x84, 0x89, 0xaa}, | ||
1085 | {0x00, 0x85, 0x96, 0xaa}, {0x00, 0x86, 0xa1, 0xaa}, | ||
1086 | {0x00, 0x87, 0xb7, 0xaa}, {0x00, 0x88, 0xcc, 0xaa}, | ||
1087 | {0x00, 0x89, 0xe1, 0xaa}, {0x00, 0x13, 0xe0, 0xaa}, | ||
1088 | {0x00, 0x00, 0x00, 0xaa}, {0x00, 0x10, 0x00, 0xaa}, | ||
1089 | {0x00, 0x0d, 0x40, 0xaa}, {0x00, 0x14, 0x28, 0xaa}, | ||
1090 | {0x00, 0xa5, 0x05, 0xaa}, {0x00, 0xab, 0x07, 0xaa}, | ||
1091 | {0x00, 0x24, 0x95, 0xaa}, {0x00, 0x25, 0x33, 0xaa}, | ||
1092 | {0x00, 0x26, 0xe3, 0xaa}, {0x00, 0x9f, 0x88, 0xaa}, | ||
1093 | {0x00, 0xa0, 0x78, 0xaa}, {0x00, 0x55, 0x90, 0xaa}, | ||
1094 | {0x00, 0xa1, 0x03, 0xaa}, {0x00, 0xa6, 0xe0, 0xaa}, | ||
1095 | {0x00, 0xa7, 0xd8, 0xaa}, {0x00, 0xa8, 0xf0, 0xaa}, | ||
1096 | {0x00, 0xa9, 0x90, 0xaa}, {0x00, 0xaa, 0x14, 0xaa}, | ||
1097 | {0x00, 0x13, 0xe5, 0xaa}, {0x00, 0x0e, 0x61, 0xaa}, | ||
1098 | {0x00, 0x0f, 0x4b, 0xaa}, {0x00, 0x16, 0x02, 0xaa}, | ||
1099 | {0x00, 0x1e, 0x07, 0xaa}, {0x00, 0x21, 0x02, 0xaa}, | ||
1100 | {0x00, 0x22, 0x91, 0xaa}, {0x00, 0x29, 0x07, 0xaa}, | ||
1101 | {0x00, 0x33, 0x0b, 0xaa}, {0x00, 0x35, 0x0b, 0xaa}, | ||
1102 | {0x00, 0x37, 0x1d, 0xaa}, {0x00, 0x38, 0x71, 0xaa}, | ||
1103 | {0x00, 0x39, 0x2a, 0xaa}, {0x00, 0x3c, 0x78, 0xaa}, | ||
1104 | {0x00, 0x4d, 0x40, 0xaa}, {0x00, 0x4e, 0x20, 0xaa}, | ||
1105 | {0x00, 0x74, 0x19, 0xaa}, {0x00, 0x8d, 0x4f, 0xaa}, | ||
1106 | {0x00, 0x8e, 0x00, 0xaa}, {0x00, 0x8f, 0x00, 0xaa}, | ||
1107 | {0x00, 0x90, 0x00, 0xaa}, {0x00, 0x91, 0x00, 0xaa}, | ||
1108 | {0x00, 0x96, 0x00, 0xaa}, {0x00, 0x9a, 0x80, 0xaa}, | ||
1109 | {0x00, 0xb0, 0x84, 0xaa}, {0x00, 0xb1, 0x0c, 0xaa}, | ||
1110 | {0x00, 0xb2, 0x0e, 0xaa}, {0x00, 0xb3, 0x82, 0xaa}, | ||
1111 | {0x00, 0xb8, 0x0a, 0xaa}, {0x00, 0x43, 0x14, 0xaa}, | ||
1112 | {0x00, 0x44, 0xf0, 0xaa}, {0x00, 0x45, 0x45, 0xaa}, | ||
1113 | {0x00, 0x46, 0x63, 0xaa}, {0x00, 0x47, 0x2d, 0xaa}, | ||
1114 | {0x00, 0x48, 0x46, 0xaa}, {0x00, 0x59, 0x88, 0xaa}, | ||
1115 | {0x00, 0x5a, 0xa0, 0xaa}, {0x00, 0x5b, 0xc6, 0xaa}, | ||
1116 | {0x00, 0x5c, 0x7d, 0xaa}, {0x00, 0x5d, 0x5f, 0xaa}, | ||
1117 | {0x00, 0x5e, 0x19, 0xaa}, {0x00, 0x6c, 0x0a, 0xaa}, | ||
1118 | {0x00, 0x6d, 0x55, 0xaa}, {0x00, 0x6e, 0x11, 0xaa}, | ||
1119 | {0x00, 0x6f, 0x9e, 0xaa}, {0x00, 0x69, 0x00, 0xaa}, | ||
1120 | {0x00, 0x6a, 0x40, 0xaa}, {0x00, 0x01, 0x40, 0xaa}, | ||
1121 | {0x00, 0x02, 0x40, 0xaa}, {0x00, 0x13, 0xe7, 0xaa}, | ||
1122 | {0x00, 0x5f, 0xf0, 0xaa}, {0x00, 0x60, 0xf0, 0xaa}, | ||
1123 | {0x00, 0x61, 0xf0, 0xaa}, {0x00, 0x27, 0xa0, 0xaa}, | ||
1124 | {0x00, 0x28, 0x80, 0xaa}, {0x00, 0x2c, 0x90, 0xaa}, | ||
1125 | {0x00, 0x4f, 0x66, 0xaa}, {0x00, 0x50, 0x66, 0xaa}, | ||
1126 | {0x00, 0x51, 0x00, 0xaa}, {0x00, 0x52, 0x22, 0xaa}, | ||
1127 | {0x00, 0x53, 0x5e, 0xaa}, {0x00, 0x54, 0x80, 0xaa}, | ||
1128 | {0x00, 0x58, 0x9e, 0xaa}, {0x00, 0x41, 0x08, 0xaa}, | ||
1129 | {0x00, 0x3f, 0x00, 0xaa}, {0x00, 0x75, 0x85, 0xaa}, | ||
1130 | {0x00, 0x76, 0xe1, 0xaa}, {0x00, 0x4c, 0x00, 0xaa}, | ||
1131 | {0x00, 0x77, 0x0a, 0xaa}, {0x00, 0x3d, 0x88, 0xaa}, | ||
1132 | {0x00, 0x4b, 0x09, 0xaa}, {0x00, 0xc9, 0x60, 0xaa}, | ||
1133 | {0x00, 0x41, 0x38, 0xaa}, {0x00, 0x62, 0x30, 0xaa}, | ||
1134 | {0x00, 0x63, 0x30, 0xaa}, {0x00, 0x64, 0x08, 0xaa}, | ||
1135 | {0x00, 0x94, 0x07, 0xaa}, {0x00, 0x95, 0x0b, 0xaa}, | ||
1136 | {0x00, 0x65, 0x00, 0xaa}, {0x00, 0x66, 0x05, 0xaa}, | ||
1137 | {0x00, 0x56, 0x50, 0xaa}, {0x00, 0x34, 0x11, 0xaa}, | ||
1138 | {0x00, 0xa4, 0x88, 0xaa}, {0x00, 0x96, 0x00, 0xaa}, | ||
1139 | {0x00, 0x97, 0x30, 0xaa}, {0x00, 0x98, 0x20, 0xaa}, | ||
1140 | {0x00, 0x99, 0x30, 0xaa}, {0x00, 0x9a, 0x84, 0xaa}, | ||
1141 | {0x00, 0x9b, 0x29, 0xaa}, {0x00, 0x9c, 0x03, 0xaa}, | ||
1142 | {0x00, 0x78, 0x04, 0xaa}, {0x00, 0x79, 0x01, 0xaa}, | ||
1143 | {0x00, 0xc8, 0xf0, 0xaa}, {0x00, 0x79, 0x0f, 0xaa}, | ||
1144 | {0x00, 0xc8, 0x00, 0xaa}, {0x00, 0x79, 0x10, 0xaa}, | ||
1145 | {0x00, 0xc8, 0x7e, 0xaa}, {0x00, 0x79, 0x0a, 0xaa}, | ||
1146 | {0x00, 0xc8, 0x80, 0xaa}, {0x00, 0x79, 0x0b, 0xaa}, | ||
1147 | {0x00, 0xc8, 0x01, 0xaa}, {0x00, 0x79, 0x0c, 0xaa}, | ||
1148 | {0x00, 0xc8, 0x0f, 0xaa}, {0x00, 0x79, 0x0d, 0xaa}, | ||
1149 | {0x00, 0xc8, 0x20, 0xaa}, {0x00, 0x79, 0x09, 0xaa}, | ||
1150 | {0x00, 0xc8, 0x80, 0xaa}, {0x00, 0x79, 0x02, 0xaa}, | ||
1151 | {0x00, 0xc8, 0xc0, 0xaa}, {0x00, 0x79, 0x03, 0xaa}, | ||
1152 | {0x00, 0xc8, 0x40, 0xaa}, {0x00, 0x79, 0x05, 0xaa}, | ||
1153 | {0x00, 0xc8, 0x30, 0xaa}, {0x00, 0x79, 0x26, 0xaa}, | ||
1154 | {0x00, 0x11, 0x40, 0xaa}, {0x00, 0x3a, 0x04, 0xaa}, | ||
1155 | {0x00, 0x12, 0x00, 0xaa}, {0x00, 0x40, 0xc0, 0xaa}, | ||
1156 | {0x00, 0x8c, 0x00, 0xaa}, {0x00, 0x17, 0x14, 0xaa}, | ||
1157 | {0x00, 0x18, 0x02, 0xaa}, {0x00, 0x32, 0x92, 0xaa}, | ||
1158 | {0x00, 0x19, 0x02, 0xaa}, {0x00, 0x1a, 0x7a, 0xaa}, | ||
1159 | {0x00, 0x03, 0x0a, 0xaa}, {0x00, 0x0c, 0x00, 0xaa}, | ||
1160 | {0x00, 0x3e, 0x00, 0xaa}, {0x00, 0x70, 0x3a, 0xaa}, | ||
1161 | {0x00, 0x71, 0x35, 0xaa}, {0x00, 0x72, 0x11, 0xaa}, | ||
1162 | {0x00, 0x73, 0xf0, 0xaa}, {0x00, 0xa2, 0x02, 0xaa}, | ||
1163 | {0x00, 0xb1, 0x00, 0xaa}, {0x00, 0xb1, 0x0c, 0xaa}, | ||
1164 | {0x00, 0x1e, 0x37, 0xaa}, {0x00, 0xaa, 0x14, 0xaa}, | ||
1165 | {0x00, 0x24, 0x80, 0xaa}, {0x00, 0x25, 0x74, 0xaa}, | ||
1166 | {0x00, 0x26, 0xd3, 0xaa}, {0x00, 0x0d, 0x00, 0xaa}, | ||
1167 | {0x00, 0x14, 0x18, 0xaa}, {0x00, 0x9d, 0x99, 0xaa}, | ||
1168 | {0x00, 0x9e, 0x7f, 0xaa}, {0x00, 0x64, 0x08, 0xaa}, | ||
1169 | {0x00, 0x94, 0x07, 0xaa}, {0x00, 0x95, 0x06, 0xaa}, | ||
1170 | {0x00, 0x66, 0x05, 0xaa}, {0x00, 0x41, 0x08, 0xaa}, | ||
1171 | {0x00, 0x3f, 0x00, 0xaa}, {0x00, 0x75, 0x07, 0xaa}, | ||
1172 | {0x00, 0x76, 0xe1, 0xaa}, {0x00, 0x4c, 0x00, 0xaa}, | ||
1173 | {0x00, 0x77, 0x00, 0xaa}, {0x00, 0x3d, 0xc2, 0xaa}, | ||
1174 | {0x00, 0x4b, 0x09, 0xaa}, {0x00, 0xc9, 0x60, 0xaa}, | ||
1175 | {0x00, 0x41, 0x38, 0xaa}, {0xb6, 0x00, 0x00, 0xcc}, | ||
1176 | {0xb6, 0x03, 0x01, 0xcc}, {0xb6, 0x02, 0x40, 0xcc}, | ||
1177 | {0xb6, 0x05, 0x00, 0xcc}, {0xb6, 0x04, 0xf0, 0xcc}, | ||
1178 | {0xb6, 0x12, 0xf8, 0xcc}, {0xb6, 0x13, 0x21, 0xcc}, | ||
1179 | {0xb6, 0x18, 0x00, 0xcc}, {0xb6, 0x17, 0x96, 0xcc}, | ||
1180 | {0xb6, 0x16, 0x00, 0xcc}, {0xb6, 0x22, 0x12, 0xcc}, | ||
1181 | {0xb6, 0x23, 0x0b, 0xcc}, {0xbf, 0xc0, 0x39, 0xcc}, | ||
1182 | {0xbf, 0xc1, 0x04, 0xcc}, {0xbf, 0xcc, 0x00, 0xcc}, | ||
1183 | {0xbc, 0x02, 0x18, 0xcc}, {0xbc, 0x03, 0x50, 0xcc}, | ||
1184 | {0xbc, 0x04, 0x18, 0xcc}, {0xbc, 0x05, 0x00, 0xcc}, | ||
1185 | {0xbc, 0x06, 0x00, 0xcc}, {0xbc, 0x08, 0x30, 0xcc}, | ||
1186 | {0xbc, 0x09, 0x40, 0xcc}, {0xbc, 0x0a, 0x10, 0xcc}, | ||
1187 | {0xbc, 0x0b, 0x00, 0xcc}, {0xbc, 0x0c, 0x00, 0xcc}, | ||
1188 | {0xb3, 0x5c, 0x01, 0xcc}, {0xb3, 0x01, 0x45, 0xcc}, | ||
1189 | {0x00, 0x77, 0x05, 0xaa }, | ||
1190 | {}, | ||
1191 | }; | ||
1192 | |||
1193 | struct sensor_info { | ||
1194 | int sensorId; | ||
1195 | __u8 I2cAdd; | ||
1196 | __u8 IdAdd; | ||
1197 | __u16 VpId; | ||
1198 | __u8 m1; | ||
1199 | __u8 m2; | ||
1200 | __u8 op; | ||
1201 | }; | ||
1202 | |||
1203 | static struct sensor_info sensor_info_data[] = { | ||
1204 | /* sensorId, I2cAdd, IdAdd, VpId, m1, m2, op */ | ||
1205 | {SENSOR_HV7131R, 0x80 | 0x11, 0x00, 0x0209, 0x24, 0x25, 0x01}, | ||
1206 | {SENSOR_OV7660, 0x80 | 0x21, 0x0a, 0x7660, 0x26, 0x26, 0x05}, | ||
1207 | {SENSOR_PO3130NC, 0x80 | 0x76, 0x00, 0x3130, 0x24, 0x25, 0x01}, | ||
1208 | {SENSOR_MI1320, 0x80 | 0xc8, 0x00, 0x148c, 0x64, 0x65, 0x01}, | ||
1209 | {SENSOR_OV7670, 0x80 | 0x21, 0x0a, 0x7673, 0x66, 0x67, 0x05}, | ||
1210 | {SENSOR_MI1310_SOC, 0x80 | 0x5d, 0x00, 0x143a, 0x24, 0x25, 0x01}, | ||
1211 | }; | ||
1212 | |||
1213 | static void reg_r(struct usb_device *dev, | ||
1214 | __u16 req, | ||
1215 | __u16 index, | ||
1216 | __u8 *buffer, __u16 length) | ||
1217 | { | ||
1218 | usb_control_msg(dev, | ||
1219 | usb_rcvctrlpipe(dev, 0), | ||
1220 | req, | ||
1221 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
1222 | 1, /* value */ | ||
1223 | index, buffer, length, | ||
1224 | 500); | ||
1225 | } | ||
1226 | |||
1227 | static void reg_w(struct usb_device *dev, | ||
1228 | __u16 req, | ||
1229 | __u16 value, | ||
1230 | __u16 index) | ||
1231 | { | ||
1232 | usb_control_msg(dev, | ||
1233 | usb_sndctrlpipe(dev, 0), | ||
1234 | req, | ||
1235 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
1236 | value, index, NULL, 0, | ||
1237 | 500); | ||
1238 | } | ||
1239 | |||
1240 | static void vc032x_read_sensor_register(struct usb_device *dev, | ||
1241 | __u16 address, __u16 *value) | ||
1242 | { | ||
1243 | __u8 ldata, mdata, hdata; | ||
1244 | __u8 tmpvalue = 0; | ||
1245 | int retry = 50; | ||
1246 | ldata = 0; | ||
1247 | mdata = 0; | ||
1248 | hdata = 0; | ||
1249 | *value = 0; | ||
1250 | |||
1251 | reg_r(dev, 0xa1, 0xb33f, &tmpvalue, 1); | ||
1252 | /*PDEBUG(D_PROBE, " I2c Bus Busy Wait 0x%02X ", tmpvalue); */ | ||
1253 | if (!(tmpvalue & 0x02)) { | ||
1254 | PDEBUG(D_ERR, "I2c Bus Busy Wait %d", tmpvalue & 0x02); | ||
1255 | return; | ||
1256 | } | ||
1257 | reg_w(dev, 0xa0, address, 0xb33a); | ||
1258 | reg_w(dev, 0xa0, 0x02, 0xb339); | ||
1259 | |||
1260 | tmpvalue = 0; | ||
1261 | reg_r(dev, 0xa1, 0xb33b, &tmpvalue, 1); | ||
1262 | while (retry-- && tmpvalue) { | ||
1263 | reg_r(dev, 0xa1, 0xb33b, &tmpvalue, 1); | ||
1264 | /* PDEBUG(D_PROBE, "Read again 0xb33b %d", tmpvalue); */ | ||
1265 | msleep(1); | ||
1266 | } | ||
1267 | reg_r(dev, 0xa1, 0xb33e, &hdata, 1); | ||
1268 | reg_r(dev, 0xa1, 0xb33d, &mdata, 1); | ||
1269 | reg_r(dev, 0xa1, 0xb33c, &ldata, 1); | ||
1270 | PDEBUG(D_PROBE, "Read Sensor h (0x%02X) m (0x%02X) l (0x%02X)", | ||
1271 | hdata, mdata, ldata); | ||
1272 | tmpvalue = 0; | ||
1273 | reg_r(dev, 0xa1, 0xb334, &tmpvalue, 1); | ||
1274 | if (tmpvalue == 0x02) | ||
1275 | *value = (ldata << 8) + mdata; | ||
1276 | else | ||
1277 | *value = ldata; | ||
1278 | } | ||
1279 | static int vc032x_probe_sensor(struct gspca_dev *gspca_dev) | ||
1280 | { | ||
1281 | struct usb_device *dev = gspca_dev->dev; | ||
1282 | int i; | ||
1283 | __u8 data; | ||
1284 | __u16 value; | ||
1285 | struct sensor_info *ptsensor_info; | ||
1286 | |||
1287 | reg_r(dev, 0xa1, 0xbfcf, &data, 1); | ||
1288 | PDEBUG(D_PROBE, "check sensor header %d", data); | ||
1289 | for (i = 0; i < ARRAY_SIZE(sensor_info_data); i++) { | ||
1290 | ptsensor_info = &sensor_info_data[i]; | ||
1291 | reg_w(dev, 0xa0, 0x02, 0xb334); | ||
1292 | reg_w(dev, 0xa0, ptsensor_info->m1, 0xb300); | ||
1293 | reg_w(dev, 0xa0, ptsensor_info->m2, 0xb300); | ||
1294 | reg_w(dev, 0xa0, 0x01, 0xb308); | ||
1295 | reg_w(dev, 0xa0, 0x0c, 0xb309); | ||
1296 | reg_w(dev, 0xa0, ptsensor_info->I2cAdd, 0xb335); | ||
1297 | /* PDEBUG(D_PROBE, | ||
1298 | "check sensor VC032X -> %d Add -> ox%02X!", | ||
1299 | i, ptsensor_info->I2cAdd); */ | ||
1300 | reg_w(dev, 0xa0, ptsensor_info->op, 0xb301); | ||
1301 | vc032x_read_sensor_register(dev, ptsensor_info->IdAdd, &value); | ||
1302 | if (value == ptsensor_info->VpId) { | ||
1303 | /* PDEBUG(D_PROBE, "find sensor VC032X -> ox%04X!", | ||
1304 | ptsensor_info->VpId); */ | ||
1305 | return ptsensor_info->sensorId; | ||
1306 | } | ||
1307 | } | ||
1308 | return -1; | ||
1309 | } | ||
1310 | |||
1311 | static __u8 i2c_write(struct usb_device *dev, | ||
1312 | __u8 reg, __u8 *val, __u8 size) | ||
1313 | { | ||
1314 | __u8 retbyte; | ||
1315 | |||
1316 | if (size > 3 || size < 1) | ||
1317 | return -EINVAL; | ||
1318 | reg_r(dev, 0xa1, 0xb33f, &retbyte, 1); | ||
1319 | reg_w(dev, 0xa0, size , 0xb334); | ||
1320 | reg_w(dev, 0xa0, reg , 0xb33a); | ||
1321 | switch (size) { | ||
1322 | case 1: | ||
1323 | reg_w(dev, 0xa0, val[0] , 0xb336); | ||
1324 | break; | ||
1325 | case 2: | ||
1326 | reg_w(dev, 0xa0, val[0] , 0xb336); | ||
1327 | reg_w(dev, 0xa0, val[1] , 0xb337); | ||
1328 | break; | ||
1329 | case 3: | ||
1330 | reg_w(dev, 0xa0, val[0] , 0xb336); | ||
1331 | reg_w(dev, 0xa0, val[1] , 0xb337); | ||
1332 | reg_w(dev, 0xa0, val[2] , 0xb338); | ||
1333 | break; | ||
1334 | default: | ||
1335 | reg_w(dev, 0xa0, 0x01, 0xb334); | ||
1336 | return -EINVAL; | ||
1337 | } | ||
1338 | reg_w(dev, 0xa0, 0x01, 0xb339); | ||
1339 | reg_r(dev, 0xa1, 0xb33b, &retbyte, 1); | ||
1340 | return retbyte == 0; | ||
1341 | } | ||
1342 | |||
1343 | static void put_tab_to_reg(struct gspca_dev *gspca_dev, | ||
1344 | __u8 *tab, __u8 tabsize, __u16 addr) | ||
1345 | { | ||
1346 | int j; | ||
1347 | __u16 ad = addr; | ||
1348 | |||
1349 | for (j = 0; j < tabsize; j++) | ||
1350 | reg_w(gspca_dev->dev, 0xa0, tab[j], ad++); | ||
1351 | } | ||
1352 | |||
1353 | static void usb_exchange(struct gspca_dev *gspca_dev, | ||
1354 | __u8 data[][4]) | ||
1355 | { | ||
1356 | struct usb_device *dev = gspca_dev->dev; | ||
1357 | int i = 0; | ||
1358 | |||
1359 | for (;;) { | ||
1360 | switch (data[i][3]) { | ||
1361 | default: | ||
1362 | return; | ||
1363 | case 0xcc: /* normal write */ | ||
1364 | reg_w(dev, 0xa0, data[i][2], | ||
1365 | ((data[i][0])<<8) | data[i][1]); | ||
1366 | break; | ||
1367 | case 0xaa: /* i2c op */ | ||
1368 | i2c_write(dev, data[i][1], &data[i][2], 1); | ||
1369 | break; | ||
1370 | case 0xbb: /* i2c op */ | ||
1371 | i2c_write(dev, data[i][0], &data[i][1], 2); | ||
1372 | break; | ||
1373 | case 0xdd: | ||
1374 | msleep(data[i][2] + 10); | ||
1375 | break; | ||
1376 | } | ||
1377 | i++; | ||
1378 | } | ||
1379 | /*not reached*/ | ||
1380 | } | ||
1381 | |||
1382 | /* | ||
1383 | "GammaT"=hex:04,17,31,4f,6a,83,99,ad,bf,ce,da,e5,ee,f5,fb,ff,ff | ||
1384 | "MatrixT"=hex:60,f9,e5,e7,50,05,f3,e6,66 | ||
1385 | */ | ||
1386 | |||
1387 | static void vc0321_reset(struct gspca_dev *gspca_dev) | ||
1388 | { | ||
1389 | reg_w(gspca_dev->dev, 0xa0, 0x00, 0xb04d); | ||
1390 | reg_w(gspca_dev->dev, 0xa0, 0x01, 0xb301); | ||
1391 | msleep(100); | ||
1392 | reg_w(gspca_dev->dev, 0xa0, 0x01, 0xb003); | ||
1393 | msleep(100); | ||
1394 | } | ||
1395 | |||
1396 | /* this function is called at probe time */ | ||
1397 | static int sd_config(struct gspca_dev *gspca_dev, | ||
1398 | const struct usb_device_id *id) | ||
1399 | { | ||
1400 | struct sd *sd = (struct sd *) gspca_dev; | ||
1401 | struct usb_device *dev = gspca_dev->dev; | ||
1402 | struct cam *cam; | ||
1403 | __u8 tmp2[4]; | ||
1404 | int sensor; | ||
1405 | __u16 vendor; | ||
1406 | __u16 product; | ||
1407 | |||
1408 | vendor = id->idVendor; | ||
1409 | product = id->idProduct; | ||
1410 | switch (vendor) { | ||
1411 | case 0x046d: /* Logitech Labtec */ | ||
1412 | /* switch (product) { */ | ||
1413 | /* case 0x0892: */ | ||
1414 | /* case 0x0896: */ | ||
1415 | sd->bridge = BRIDGE_VC0321; | ||
1416 | /* break; */ | ||
1417 | /* } */ | ||
1418 | break; | ||
1419 | case 0x0ac8: /* Vimicro z-star */ | ||
1420 | switch (product) { | ||
1421 | case 0x0321: | ||
1422 | case 0x0328: | ||
1423 | case 0xc001: | ||
1424 | case 0xc002: | ||
1425 | sd->bridge = BRIDGE_VC0321; | ||
1426 | break; | ||
1427 | case 0x0323: | ||
1428 | sd->bridge = BRIDGE_VC0323; | ||
1429 | break; | ||
1430 | } | ||
1431 | break; | ||
1432 | case 0x17ef: /* Lenovo */ | ||
1433 | /* switch (product) { */ | ||
1434 | /* case 0x4802: * Lenovo MI1310_SOC */ | ||
1435 | sd->bridge = BRIDGE_VC0323; | ||
1436 | /* break; */ | ||
1437 | /* } */ | ||
1438 | break; | ||
1439 | } | ||
1440 | |||
1441 | cam = &gspca_dev->cam; | ||
1442 | cam->dev_name = (char *) id->driver_info; | ||
1443 | cam->epaddr = 0x02; | ||
1444 | if (sd->bridge == BRIDGE_VC0321) { | ||
1445 | cam->cam_mode = vc0321_mode; | ||
1446 | cam->nmodes = sizeof vc0321_mode / sizeof vc0321_mode[0]; | ||
1447 | } else { | ||
1448 | cam->cam_mode = vc0323_mode; | ||
1449 | cam->nmodes = sizeof vc0323_mode / sizeof vc0323_mode[0]; | ||
1450 | } | ||
1451 | |||
1452 | vc0321_reset(gspca_dev); | ||
1453 | sensor = vc032x_probe_sensor(gspca_dev); | ||
1454 | switch (sensor) { | ||
1455 | case -1: | ||
1456 | PDEBUG(D_PROBE, "Unknown sensor..."); | ||
1457 | return -EINVAL; | ||
1458 | case SENSOR_HV7131R: | ||
1459 | PDEBUG(D_PROBE, "Find Sensor HV7131R"); | ||
1460 | sd->sensor = SENSOR_HV7131R; | ||
1461 | break; | ||
1462 | case SENSOR_MI1310_SOC: | ||
1463 | PDEBUG(D_PROBE, "Find Sensor MI1310_SOC"); | ||
1464 | sd->sensor = SENSOR_MI1310_SOC; | ||
1465 | break; | ||
1466 | case SENSOR_MI1320: | ||
1467 | PDEBUG(D_PROBE, "Find Sensor MI1320"); | ||
1468 | sd->sensor = SENSOR_MI1320; | ||
1469 | break; | ||
1470 | case SENSOR_OV7660: | ||
1471 | PDEBUG(D_PROBE, "Find Sensor OV7660"); | ||
1472 | sd->sensor = SENSOR_OV7660; | ||
1473 | break; | ||
1474 | case SENSOR_OV7670: | ||
1475 | PDEBUG(D_PROBE, "Find Sensor OV7670"); | ||
1476 | sd->sensor = SENSOR_OV7670; | ||
1477 | break; | ||
1478 | case SENSOR_PO3130NC: | ||
1479 | PDEBUG(D_PROBE, "Find Sensor PO3130NC"); | ||
1480 | sd->sensor = SENSOR_PO3130NC; | ||
1481 | break; | ||
1482 | } | ||
1483 | |||
1484 | sd->qindex = 7; | ||
1485 | sd->autogain = sd_ctrls[SD_AUTOGAIN].qctrl.default_value; | ||
1486 | |||
1487 | if (sd->bridge == BRIDGE_VC0321) { | ||
1488 | reg_r(dev, 0x8a, 0, tmp2, 3); | ||
1489 | reg_w(dev, 0x87, 0x00, 0x0f0f); | ||
1490 | |||
1491 | reg_r(dev, 0x8b, 0, tmp2, 3); | ||
1492 | reg_w(dev, 0x88, 0x00, 0x0202); | ||
1493 | } | ||
1494 | return 0; | ||
1495 | } | ||
1496 | |||
1497 | /* this function is called at open time */ | ||
1498 | static int sd_open(struct gspca_dev *gspca_dev) | ||
1499 | { | ||
1500 | return 0; | ||
1501 | } | ||
1502 | |||
1503 | static void setquality(struct gspca_dev *gspca_dev) | ||
1504 | { | ||
1505 | } | ||
1506 | |||
1507 | static void setautogain(struct gspca_dev *gspca_dev) | ||
1508 | { | ||
1509 | } | ||
1510 | |||
1511 | static void setlightfreq(struct gspca_dev *gspca_dev) | ||
1512 | { | ||
1513 | struct sd *sd = (struct sd *) gspca_dev; | ||
1514 | static __u8 (*ov7660_freq_tb[3])[4] = | ||
1515 | {ov7660_NoFliker, ov7660_50HZ, ov7660_60HZ}; | ||
1516 | |||
1517 | if (sd->sensor != SENSOR_OV7660) | ||
1518 | return; | ||
1519 | usb_exchange(gspca_dev, ov7660_freq_tb[sd->lightfreq]); | ||
1520 | } | ||
1521 | |||
1522 | static void sd_start(struct gspca_dev *gspca_dev) | ||
1523 | { | ||
1524 | struct sd *sd = (struct sd *) gspca_dev; | ||
1525 | /* __u8 tmp2; */ | ||
1526 | __u8 *GammaT = NULL; | ||
1527 | __u8 *MatrixT = NULL; | ||
1528 | int mode; | ||
1529 | |||
1530 | /* Assume start use the good resolution from gspca_dev->mode */ | ||
1531 | if (sd->bridge == BRIDGE_VC0321) { | ||
1532 | reg_w(gspca_dev->dev, 0xa0, 0xff, 0xbfec); | ||
1533 | reg_w(gspca_dev->dev, 0xa0, 0xff, 0xbfed); | ||
1534 | reg_w(gspca_dev->dev, 0xa0, 0xff, 0xbfee); | ||
1535 | reg_w(gspca_dev->dev, 0xa0, 0xff, 0xbfef); | ||
1536 | } | ||
1537 | |||
1538 | mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode; | ||
1539 | switch (sd->sensor) { | ||
1540 | case SENSOR_HV7131R: | ||
1541 | GammaT = hv7131r_gamma; | ||
1542 | MatrixT = hv7131r_matrix; | ||
1543 | if (mode) { | ||
1544 | /* 320x240 */ | ||
1545 | usb_exchange(gspca_dev, hv7131r_initQVGA_data); | ||
1546 | } else { | ||
1547 | /* 640x480 */ | ||
1548 | usb_exchange(gspca_dev, hv7131r_initVGA_data); | ||
1549 | } | ||
1550 | break; | ||
1551 | case SENSOR_OV7660: | ||
1552 | GammaT = ov7660_gamma; | ||
1553 | MatrixT = ov7660_matrix; | ||
1554 | if (mode) { | ||
1555 | /* 320x240 */ | ||
1556 | usb_exchange(gspca_dev, ov7660_initQVGA_data); | ||
1557 | } else { | ||
1558 | /* 640x480 */ | ||
1559 | usb_exchange(gspca_dev, ov7660_initVGA_data); | ||
1560 | } | ||
1561 | break; | ||
1562 | case SENSOR_OV7670: | ||
1563 | /*GammaT = ov7660_gamma; */ | ||
1564 | /*MatrixT = ov7660_matrix; */ | ||
1565 | if (mode) { | ||
1566 | /* 320x240 */ | ||
1567 | usb_exchange(gspca_dev, ov7670_initQVGA_JPG); | ||
1568 | } else { | ||
1569 | /* 640x480 */ | ||
1570 | usb_exchange(gspca_dev, ov7670_initVGA_JPG); | ||
1571 | } | ||
1572 | break; | ||
1573 | case SENSOR_MI1310_SOC: | ||
1574 | if (mode) { | ||
1575 | /* 320x240 */ | ||
1576 | usb_exchange(gspca_dev, mi1310_socinitQVGA_JPG); | ||
1577 | } else { | ||
1578 | /* 640x480 */ | ||
1579 | usb_exchange(gspca_dev, mi1310_socinitVGA_JPG); | ||
1580 | } | ||
1581 | break; | ||
1582 | case SENSOR_MI1320: | ||
1583 | GammaT = mi1320_gamma; | ||
1584 | MatrixT = mi1320_matrix; | ||
1585 | if (mode) { | ||
1586 | /* 320x240 */ | ||
1587 | usb_exchange(gspca_dev, mi1320_initQVGA_data); | ||
1588 | } else { | ||
1589 | /* 640x480 */ | ||
1590 | usb_exchange(gspca_dev, mi1320_initVGA_data); | ||
1591 | } | ||
1592 | break; | ||
1593 | case SENSOR_PO3130NC: | ||
1594 | GammaT = po3130_gamma; | ||
1595 | MatrixT = po3130_matrix; | ||
1596 | if (mode) { | ||
1597 | /* 320x240 */ | ||
1598 | usb_exchange(gspca_dev, po3130_initQVGA_data); | ||
1599 | } else { | ||
1600 | /* 640x480 */ | ||
1601 | usb_exchange(gspca_dev, po3130_initVGA_data); | ||
1602 | } | ||
1603 | usb_exchange(gspca_dev, po3130_rundata); | ||
1604 | break; | ||
1605 | default: | ||
1606 | PDEBUG(D_PROBE, "Damned !! no sensor found Bye"); | ||
1607 | return; | ||
1608 | } | ||
1609 | if (GammaT && MatrixT) { | ||
1610 | put_tab_to_reg(gspca_dev, GammaT, 17, 0xb84a); | ||
1611 | put_tab_to_reg(gspca_dev, GammaT, 17, 0xb85b); | ||
1612 | put_tab_to_reg(gspca_dev, GammaT, 17, 0xb86c); | ||
1613 | put_tab_to_reg(gspca_dev, MatrixT, 9, 0xb82c); | ||
1614 | |||
1615 | /* Seem SHARPNESS */ | ||
1616 | /* | ||
1617 | reg_w(gspca_dev->dev, 0xa0, 0x80, 0xb80a); | ||
1618 | reg_w(gspca_dev->dev, 0xa0, 0xff, 0xb80b); | ||
1619 | reg_w(gspca_dev->dev, 0xa0, 0xff, 0xb80e); | ||
1620 | */ | ||
1621 | /* all 0x40 ??? do nothing | ||
1622 | reg_w(gspca_dev->dev, 0xa0, 0x40, 0xb822); | ||
1623 | reg_w(gspca_dev->dev, 0xa0, 0x40, 0xb823); | ||
1624 | reg_w(gspca_dev->dev, 0xa0, 0x40, 0xb824); | ||
1625 | */ | ||
1626 | /* Only works for HV7131R ?? | ||
1627 | reg_r (gspca_dev->dev, 0xa1, 0xb881, &tmp2, 1); | ||
1628 | reg_w(gspca_dev->dev, 0xa0, 0xfe01, 0xb881); | ||
1629 | reg_w(gspca_dev->dev, 0xa0, 0x79, 0xb801); | ||
1630 | */ | ||
1631 | /* only hv7131r et ov7660 | ||
1632 | reg_w(gspca_dev->dev, 0xa0, 0x20, 0xb827); | ||
1633 | reg_w(gspca_dev->dev, 0xa0, 0xff, 0xb826); * ISP_GAIN 80 | ||
1634 | reg_w(gspca_dev->dev, 0xa0, 0x23, 0xb800); * ISP CTRL_BAS | ||
1635 | */ | ||
1636 | /* set the led on 0x0892 0x0896 */ | ||
1637 | reg_w(gspca_dev->dev, 0x89, 0xffff, 0xfdff); | ||
1638 | msleep(100); | ||
1639 | setquality(gspca_dev); | ||
1640 | setautogain(gspca_dev); | ||
1641 | setlightfreq(gspca_dev); | ||
1642 | } | ||
1643 | } | ||
1644 | |||
1645 | static void sd_stopN(struct gspca_dev *gspca_dev) | ||
1646 | { | ||
1647 | struct usb_device *dev = gspca_dev->dev; | ||
1648 | |||
1649 | reg_w(dev, 0x89, 0xffff, 0xffff); | ||
1650 | reg_w(dev, 0xa0, 0x01, 0xb301); | ||
1651 | reg_w(dev, 0xa0, 0x09, 0xb003); | ||
1652 | } | ||
1653 | |||
1654 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
1655 | { | ||
1656 | struct usb_device *dev = gspca_dev->dev; | ||
1657 | |||
1658 | reg_w(dev, 0x89, 0xffff, 0xffff); | ||
1659 | } | ||
1660 | |||
1661 | /* this function is called at close time */ | ||
1662 | static void sd_close(struct gspca_dev *gspca_dev) | ||
1663 | { | ||
1664 | /* struct usb_device *dev = gspca_dev->dev; | ||
1665 | __u8 buffread; | ||
1666 | |||
1667 | reg_w(dev, 0x89, 0xffff, 0xffff); | ||
1668 | reg_w(dev, 0xa0, 0x01, 0xb301); | ||
1669 | reg_w(dev, 0xa0, 0x09, 0xb303); | ||
1670 | reg_w(dev, 0x89, 0xffff, 0xffff); | ||
1671 | */ | ||
1672 | } | ||
1673 | |||
1674 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | ||
1675 | struct gspca_frame *frame, /* target */ | ||
1676 | unsigned char *data, /* isoc packet */ | ||
1677 | int len) /* iso pkt length */ | ||
1678 | { | ||
1679 | struct sd *sd = (struct sd *) gspca_dev; | ||
1680 | |||
1681 | if (data[0] == 0xff && data[1] == 0xd8) { | ||
1682 | PDEBUG(D_PACK, | ||
1683 | "vc032x header packet found len %d", len); | ||
1684 | frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, | ||
1685 | data, 0); | ||
1686 | if (sd->bridge == BRIDGE_VC0321) { | ||
1687 | #define VCHDRSZ 46 | ||
1688 | data += VCHDRSZ; | ||
1689 | len -= VCHDRSZ; | ||
1690 | #undef VCHDRSZ | ||
1691 | } | ||
1692 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, | ||
1693 | data, len); | ||
1694 | return; | ||
1695 | } | ||
1696 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); | ||
1697 | } | ||
1698 | |||
1699 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) | ||
1700 | { | ||
1701 | struct sd *sd = (struct sd *) gspca_dev; | ||
1702 | |||
1703 | sd->autogain = val; | ||
1704 | if (gspca_dev->streaming) | ||
1705 | setautogain(gspca_dev); | ||
1706 | return 0; | ||
1707 | } | ||
1708 | |||
1709 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) | ||
1710 | { | ||
1711 | struct sd *sd = (struct sd *) gspca_dev; | ||
1712 | |||
1713 | *val = sd->autogain; | ||
1714 | return 0; | ||
1715 | } | ||
1716 | |||
1717 | static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val) | ||
1718 | { | ||
1719 | struct sd *sd = (struct sd *) gspca_dev; | ||
1720 | |||
1721 | sd->lightfreq = val; | ||
1722 | if (gspca_dev->streaming) | ||
1723 | setlightfreq(gspca_dev); | ||
1724 | return 0; | ||
1725 | } | ||
1726 | |||
1727 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val) | ||
1728 | { | ||
1729 | struct sd *sd = (struct sd *) gspca_dev; | ||
1730 | |||
1731 | *val = sd->lightfreq; | ||
1732 | return 0; | ||
1733 | } | ||
1734 | |||
1735 | static int sd_querymenu(struct gspca_dev *gspca_dev, | ||
1736 | struct v4l2_querymenu *menu) | ||
1737 | { | ||
1738 | switch (menu->id) { | ||
1739 | case V4L2_CID_POWER_LINE_FREQUENCY: | ||
1740 | switch (menu->index) { | ||
1741 | case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */ | ||
1742 | strcpy(menu->name, "NoFliker"); | ||
1743 | return 0; | ||
1744 | case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */ | ||
1745 | strcpy(menu->name, "50 Hz"); | ||
1746 | return 0; | ||
1747 | case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */ | ||
1748 | strcpy(menu->name, "60 Hz"); | ||
1749 | return 0; | ||
1750 | } | ||
1751 | break; | ||
1752 | } | ||
1753 | return -EINVAL; | ||
1754 | } | ||
1755 | |||
1756 | /* sub-driver description */ | ||
1757 | static struct sd_desc sd_desc = { | ||
1758 | .name = MODULE_NAME, | ||
1759 | .ctrls = sd_ctrls, | ||
1760 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
1761 | .config = sd_config, | ||
1762 | .open = sd_open, | ||
1763 | .start = sd_start, | ||
1764 | .stopN = sd_stopN, | ||
1765 | .stop0 = sd_stop0, | ||
1766 | .close = sd_close, | ||
1767 | .pkt_scan = sd_pkt_scan, | ||
1768 | .querymenu = sd_querymenu, | ||
1769 | }; | ||
1770 | |||
1771 | /* -- module initialisation -- */ | ||
1772 | #define DVNM(name) .driver_info = (kernel_ulong_t) name | ||
1773 | static __devinitdata struct usb_device_id device_table[] = { | ||
1774 | {USB_DEVICE(0x046d, 0x0892), DVNM("Logitech Orbicam")}, | ||
1775 | {USB_DEVICE(0x046d, 0x0896), DVNM("Logitech Orbicam")}, | ||
1776 | {USB_DEVICE(0x0ac8, 0x0321), DVNM("Vimicro generic vc0321")}, | ||
1777 | {USB_DEVICE(0x0ac8, 0x0323), DVNM("Vimicro Vc0323")}, | ||
1778 | {USB_DEVICE(0x0ac8, 0x0328), DVNM("A4Tech PK-130MG")}, | ||
1779 | {USB_DEVICE(0x0ac8, 0xc001), DVNM("Sony embedded vimicro")}, | ||
1780 | {USB_DEVICE(0x0ac8, 0xc002), DVNM("Sony embedded vimicro")}, | ||
1781 | {USB_DEVICE(0x17ef, 0x4802), DVNM("Lenovo Vc0323+MI1310_SOC")}, | ||
1782 | {} | ||
1783 | }; | ||
1784 | MODULE_DEVICE_TABLE(usb, device_table); | ||
1785 | |||
1786 | /* -- device connect -- */ | ||
1787 | static int sd_probe(struct usb_interface *intf, | ||
1788 | const struct usb_device_id *id) | ||
1789 | { | ||
1790 | return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), | ||
1791 | THIS_MODULE); | ||
1792 | } | ||
1793 | |||
1794 | static struct usb_driver sd_driver = { | ||
1795 | .name = MODULE_NAME, | ||
1796 | .id_table = device_table, | ||
1797 | .probe = sd_probe, | ||
1798 | .disconnect = gspca_disconnect, | ||
1799 | }; | ||
1800 | |||
1801 | /* -- module insert / remove -- */ | ||
1802 | static int __init sd_mod_init(void) | ||
1803 | { | ||
1804 | if (usb_register(&sd_driver) < 0) | ||
1805 | return -1; | ||
1806 | PDEBUG(D_PROBE, "v%s registered", version); | ||
1807 | return 0; | ||
1808 | } | ||
1809 | static void __exit sd_mod_exit(void) | ||
1810 | { | ||
1811 | usb_deregister(&sd_driver); | ||
1812 | PDEBUG(D_PROBE, "deregistered"); | ||
1813 | } | ||
1814 | |||
1815 | module_init(sd_mod_init); | ||
1816 | module_exit(sd_mod_exit); | ||
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c index 03cc7fc58dbc..b767f32511bb 100644 --- a/drivers/media/video/gspca/zc3xx.c +++ b/drivers/media/video/gspca/zc3xx.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * Copyright (C) 2004 2005 2006 Michel Xhaard | 3 | * Copyright (C) 2004 2005 2006 Michel Xhaard |
4 | * mxhaard@magic.fr | 4 | * mxhaard@magic.fr |
5 | * | 5 | * |
6 | * V4L2 by Jean-François Moine <http://moinejf.free.fr> | 6 | * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License as published by | 9 | * it under the terms of the GNU General Public License as published by |
@@ -24,15 +24,14 @@ | |||
24 | 24 | ||
25 | #include "gspca.h" | 25 | #include "gspca.h" |
26 | 26 | ||
27 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(0, 2, 13) | 27 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) |
28 | static const char version[] = "0.2.13"; | 28 | static const char version[] = "2.1.0"; |
29 | 29 | ||
30 | MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>, " | 30 | MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>, " |
31 | "Serge A. Suchkov <Serge.A.S@tochka.ru>"); | 31 | "Serge A. Suchkov <Serge.A.S@tochka.ru>"); |
32 | MODULE_DESCRIPTION("GSPCA ZC03xx/VC3xx USB Camera Driver"); | 32 | MODULE_DESCRIPTION("GSPCA ZC03xx/VC3xx USB Camera Driver"); |
33 | MODULE_LICENSE("GPL"); | 33 | MODULE_LICENSE("GPL"); |
34 | 34 | ||
35 | static int lightfreq = 50; | ||
36 | static int force_sensor = -1; | 35 | static int force_sensor = -1; |
37 | 36 | ||
38 | #include "jpeg.h" | 37 | #include "jpeg.h" |
@@ -41,10 +40,12 @@ static int force_sensor = -1; | |||
41 | struct sd { | 40 | struct sd { |
42 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 41 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
43 | 42 | ||
44 | unsigned char brightness; | 43 | __u8 brightness; |
45 | unsigned char contrast; | 44 | __u8 contrast; |
46 | unsigned char autogain; | 45 | __u8 gamma; |
47 | unsigned char gamma; | 46 | __u8 autogain; |
47 | __u8 lightfreq; | ||
48 | __u8 sharpness; | ||
48 | 49 | ||
49 | char qindex; | 50 | char qindex; |
50 | char sensor; /* Type of image sensor chip */ | 51 | char sensor; /* Type of image sensor chip */ |
@@ -61,14 +62,13 @@ struct sd { | |||
61 | #define SENSOR_OV7620 9 | 62 | #define SENSOR_OV7620 9 |
62 | /*#define SENSOR_OV7648 9 - same values */ | 63 | /*#define SENSOR_OV7648 9 - same values */ |
63 | #define SENSOR_OV7630C 10 | 64 | #define SENSOR_OV7630C 10 |
64 | /*#define SENSOR_free 11 */ | 65 | #define SENSOR_PAS106 11 |
65 | #define SENSOR_PAS106 12 | 66 | #define SENSOR_PB0330 12 |
66 | #define SENSOR_PB0330 13 | 67 | #define SENSOR_PO2030 13 |
67 | #define SENSOR_PO2030 14 | 68 | #define SENSOR_TAS5130CK 14 |
68 | #define SENSOR_TAS5130CK 15 | 69 | #define SENSOR_TAS5130CXX 15 |
69 | #define SENSOR_TAS5130CXX 16 | 70 | #define SENSOR_TAS5130C_VF0250 16 |
70 | #define SENSOR_TAS5130C_VF0250 17 | 71 | #define SENSOR_MAX 17 |
71 | #define SENSOR_MAX 18 | ||
72 | unsigned short chip_revision; | 72 | unsigned short chip_revision; |
73 | }; | 73 | }; |
74 | 74 | ||
@@ -79,7 +79,12 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | |||
79 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | 79 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); |
80 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); | 80 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); |
81 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); | 81 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); |
82 | static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val); | ||
82 | static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val); | 83 | static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val); |
84 | static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); | ||
85 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); | ||
86 | static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val); | ||
87 | static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val); | ||
83 | 88 | ||
84 | static struct ctrl sd_ctrls[] = { | 89 | static struct ctrl sd_ctrls[] = { |
85 | #define SD_BRIGHTNESS 0 | 90 | #define SD_BRIGHTNESS 0 |
@@ -110,7 +115,21 @@ static struct ctrl sd_ctrls[] = { | |||
110 | .set = sd_setcontrast, | 115 | .set = sd_setcontrast, |
111 | .get = sd_getcontrast, | 116 | .get = sd_getcontrast, |
112 | }, | 117 | }, |
113 | #define SD_AUTOGAIN 2 | 118 | #define SD_GAMMA 2 |
119 | { | ||
120 | { | ||
121 | .id = V4L2_CID_GAMMA, | ||
122 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
123 | .name = "Gamma", | ||
124 | .minimum = 1, | ||
125 | .maximum = 6, | ||
126 | .step = 1, | ||
127 | .default_value = 4, | ||
128 | }, | ||
129 | .set = sd_setgamma, | ||
130 | .get = sd_getgamma, | ||
131 | }, | ||
132 | #define SD_AUTOGAIN 3 | ||
114 | { | 133 | { |
115 | { | 134 | { |
116 | .id = V4L2_CID_AUTOGAIN, | 135 | .id = V4L2_CID_AUTOGAIN, |
@@ -124,19 +143,33 @@ static struct ctrl sd_ctrls[] = { | |||
124 | .set = sd_setautogain, | 143 | .set = sd_setautogain, |
125 | .get = sd_getautogain, | 144 | .get = sd_getautogain, |
126 | }, | 145 | }, |
127 | #define SD_GAMMA 3 | 146 | #define SD_FREQ 4 |
128 | { | 147 | { |
129 | { | 148 | { |
130 | .id = V4L2_CID_GAMMA, | 149 | .id = V4L2_CID_POWER_LINE_FREQUENCY, |
150 | .type = V4L2_CTRL_TYPE_MENU, | ||
151 | .name = "Light frequency filter", | ||
152 | .minimum = 0, | ||
153 | .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */ | ||
154 | .step = 1, | ||
155 | .default_value = 1, | ||
156 | }, | ||
157 | .set = sd_setfreq, | ||
158 | .get = sd_getfreq, | ||
159 | }, | ||
160 | #define SD_SHARPNESS 5 | ||
161 | { | ||
162 | { | ||
163 | .id = V4L2_CID_SHARPNESS, | ||
131 | .type = V4L2_CTRL_TYPE_INTEGER, | 164 | .type = V4L2_CTRL_TYPE_INTEGER, |
132 | .name = "Gamma", | 165 | .name = "Sharpness", |
133 | .minimum = 1, | 166 | .minimum = 0, |
134 | .maximum = 6, | 167 | .maximum = 3, |
135 | .step = 1, | 168 | .step = 1, |
136 | .default_value = 4, | 169 | .default_value = 2, |
137 | }, | 170 | }, |
138 | .set = sd_setcontrast, | 171 | .set = sd_setsharpness, |
139 | .get = sd_getgamma, | 172 | .get = sd_getsharpness, |
140 | }, | 173 | }, |
141 | }; | 174 | }; |
142 | 175 | ||
@@ -211,11 +244,11 @@ static struct usb_action cs2102_Initial[] = { | |||
211 | {0xa1, 0x01, 0x0002}, | 244 | {0xa1, 0x01, 0x0002}, |
212 | {0xa1, 0x01, 0x0008}, | 245 | {0xa1, 0x01, 0x0008}, |
213 | {0xa0, 0x03, 0x0008}, /* 00 */ | 246 | {0xa0, 0x03, 0x0008}, /* 00 */ |
214 | {0xa0, 0x08, 0x01c6}, /* clock ? */ | 247 | {0xa0, 0x08, 0x01c6}, /* sharpness+ */ |
215 | {0xa1, 0x01, 0x01c8}, | 248 | {0xa1, 0x01, 0x01c8}, |
216 | {0xa1, 0x01, 0x01c9}, | 249 | {0xa1, 0x01, 0x01c9}, |
217 | {0xa1, 0x01, 0x01ca}, | 250 | {0xa1, 0x01, 0x01ca}, |
218 | {0xa0, 0x0f, 0x01cb}, | 251 | {0xa0, 0x0f, 0x01cb}, /* sharpness- */ |
219 | {0xa0, 0x24, 0x0120}, /* gamma 5 */ | 252 | {0xa0, 0x24, 0x0120}, /* gamma 5 */ |
220 | {0xa0, 0x44, 0x0121}, | 253 | {0xa0, 0x44, 0x0121}, |
221 | {0xa0, 0x64, 0x0122}, | 254 | {0xa0, 0x64, 0x0122}, |
@@ -284,7 +317,7 @@ static struct usb_action cs2102_Initial[] = { | |||
284 | {0xa0, 0x40, 0x0116}, | 317 | {0xa0, 0x40, 0x0116}, |
285 | {0xa0, 0x40, 0x0117}, | 318 | {0xa0, 0x40, 0x0117}, |
286 | {0xa0, 0x40, 0x0118}, | 319 | {0xa0, 0x40, 0x0118}, |
287 | {0, 0, 0} | 320 | {} |
288 | }; | 321 | }; |
289 | 322 | ||
290 | static struct usb_action cs2102_InitialScale[] = { | 323 | static struct usb_action cs2102_InitialScale[] = { |
@@ -341,11 +374,11 @@ static struct usb_action cs2102_InitialScale[] = { | |||
341 | {0xa1, 0x01, 0x0002}, | 374 | {0xa1, 0x01, 0x0002}, |
342 | {0xa1, 0x01, 0x0008}, | 375 | {0xa1, 0x01, 0x0008}, |
343 | {0xa0, 0x03, 0x0008}, /* 00 */ | 376 | {0xa0, 0x03, 0x0008}, /* 00 */ |
344 | {0xa0, 0x08, 0x01c6}, /* clock ? */ | 377 | {0xa0, 0x08, 0x01c6}, /* sharpness+ */ |
345 | {0xa1, 0x01, 0x01c8}, | 378 | {0xa1, 0x01, 0x01c8}, |
346 | {0xa1, 0x01, 0x01c9}, | 379 | {0xa1, 0x01, 0x01c9}, |
347 | {0xa1, 0x01, 0x01ca}, | 380 | {0xa1, 0x01, 0x01ca}, |
348 | {0xa0, 0x0f, 0x01cb}, | 381 | {0xa0, 0x0f, 0x01cb}, /* sharpness- */ |
349 | {0xa0, 0x24, 0x0120}, /* gamma 5 */ | 382 | {0xa0, 0x24, 0x0120}, /* gamma 5 */ |
350 | {0xa0, 0x44, 0x0121}, | 383 | {0xa0, 0x44, 0x0121}, |
351 | {0xa0, 0x64, 0x0122}, | 384 | {0xa0, 0x64, 0x0122}, |
@@ -414,7 +447,7 @@ static struct usb_action cs2102_InitialScale[] = { | |||
414 | {0xa0, 0x40, 0x0116}, | 447 | {0xa0, 0x40, 0x0116}, |
415 | {0xa0, 0x40, 0x0117}, | 448 | {0xa0, 0x40, 0x0117}, |
416 | {0xa0, 0x40, 0x0118}, | 449 | {0xa0, 0x40, 0x0118}, |
417 | {0, 0, 0} | 450 | {} |
418 | }; | 451 | }; |
419 | static struct usb_action cs2102_50HZ[] = { | 452 | static struct usb_action cs2102_50HZ[] = { |
420 | {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ | 453 | {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ |
@@ -439,7 +472,7 @@ static struct usb_action cs2102_50HZ[] = { | |||
439 | {0xa0, 0x8c, 0x001d}, /* 00,1d,8c,cc */ | 472 | {0xa0, 0x8c, 0x001d}, /* 00,1d,8c,cc */ |
440 | {0xa0, 0xb0, 0x001e}, /* 00,1e,b0,cc */ | 473 | {0xa0, 0xb0, 0x001e}, /* 00,1e,b0,cc */ |
441 | {0xa0, 0xd0, 0x001f}, /* 00,1f,d0,cc */ | 474 | {0xa0, 0xd0, 0x001f}, /* 00,1f,d0,cc */ |
442 | {0, 0, 0} | 475 | {} |
443 | }; | 476 | }; |
444 | static struct usb_action cs2102_50HZScale[] = { | 477 | static struct usb_action cs2102_50HZScale[] = { |
445 | {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ | 478 | {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ |
@@ -464,7 +497,7 @@ static struct usb_action cs2102_50HZScale[] = { | |||
464 | {0xa0, 0x93, 0x001d}, /* 00,1d,93,cc */ | 497 | {0xa0, 0x93, 0x001d}, /* 00,1d,93,cc */ |
465 | {0xa0, 0xb0, 0x001e}, /* 00,1e,b0,cc */ | 498 | {0xa0, 0xb0, 0x001e}, /* 00,1e,b0,cc */ |
466 | {0xa0, 0xd0, 0x001f}, /* 00,1f,d0,cc */ | 499 | {0xa0, 0xd0, 0x001f}, /* 00,1f,d0,cc */ |
467 | {0, 0, 0} | 500 | {} |
468 | }; | 501 | }; |
469 | static struct usb_action cs2102_60HZ[] = { | 502 | static struct usb_action cs2102_60HZ[] = { |
470 | {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ | 503 | {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ |
@@ -489,7 +522,7 @@ static struct usb_action cs2102_60HZ[] = { | |||
489 | {0xa0, 0x5d, 0x001d}, /* 00,1d,5d,cc */ | 522 | {0xa0, 0x5d, 0x001d}, /* 00,1d,5d,cc */ |
490 | {0xa0, 0x90, 0x001e}, /* 00,1e,90,cc */ | 523 | {0xa0, 0x90, 0x001e}, /* 00,1e,90,cc */ |
491 | {0xa0, 0xd0, 0x00c8}, /* 00,c8,d0,cc */ | 524 | {0xa0, 0xd0, 0x00c8}, /* 00,c8,d0,cc */ |
492 | {0, 0, 0} | 525 | {} |
493 | }; | 526 | }; |
494 | static struct usb_action cs2102_60HZScale[] = { | 527 | static struct usb_action cs2102_60HZScale[] = { |
495 | {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ | 528 | {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ |
@@ -514,7 +547,7 @@ static struct usb_action cs2102_60HZScale[] = { | |||
514 | {0xa0, 0xb7, 0x001d}, /* 00,1d,b7,cc */ | 547 | {0xa0, 0xb7, 0x001d}, /* 00,1d,b7,cc */ |
515 | {0xa0, 0xd0, 0x001e}, /* 00,1e,d0,cc */ | 548 | {0xa0, 0xd0, 0x001e}, /* 00,1e,d0,cc */ |
516 | {0xa0, 0xe8, 0x001f}, /* 00,1f,e8,cc */ | 549 | {0xa0, 0xe8, 0x001f}, /* 00,1f,e8,cc */ |
517 | {0, 0, 0} | 550 | {} |
518 | }; | 551 | }; |
519 | static struct usb_action cs2102_NoFliker[] = { | 552 | static struct usb_action cs2102_NoFliker[] = { |
520 | {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ | 553 | {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ |
@@ -539,7 +572,7 @@ static struct usb_action cs2102_NoFliker[] = { | |||
539 | {0xa0, 0x59, 0x001d}, /* 00,1d,59,cc */ | 572 | {0xa0, 0x59, 0x001d}, /* 00,1d,59,cc */ |
540 | {0xa0, 0x90, 0x001e}, /* 00,1e,90,cc */ | 573 | {0xa0, 0x90, 0x001e}, /* 00,1e,90,cc */ |
541 | {0xa0, 0xc8, 0x001f}, /* 00,1f,c8,cc */ | 574 | {0xa0, 0xc8, 0x001f}, /* 00,1f,c8,cc */ |
542 | {0, 0, 0} | 575 | {} |
543 | }; | 576 | }; |
544 | static struct usb_action cs2102_NoFlikerScale[] = { | 577 | static struct usb_action cs2102_NoFlikerScale[] = { |
545 | {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ | 578 | {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ |
@@ -564,7 +597,7 @@ static struct usb_action cs2102_NoFlikerScale[] = { | |||
564 | {0xa0, 0x59, 0x001d}, /* 00,1d,59,cc */ | 597 | {0xa0, 0x59, 0x001d}, /* 00,1d,59,cc */ |
565 | {0xa0, 0x90, 0x001e}, /* 00,1e,90,cc */ | 598 | {0xa0, 0x90, 0x001e}, /* 00,1e,90,cc */ |
566 | {0xa0, 0xc8, 0x001f}, /* 00,1f,c8,cc */ | 599 | {0xa0, 0xc8, 0x001f}, /* 00,1f,c8,cc */ |
567 | {0, 0, 0} | 600 | {} |
568 | }; | 601 | }; |
569 | 602 | ||
570 | /* CS2102_KOCOM */ | 603 | /* CS2102_KOCOM */ |
@@ -676,8 +709,8 @@ static struct usb_action cs2102K_Initial[] = { | |||
676 | {0xa0, 0x40, 0x0117}, | 709 | {0xa0, 0x40, 0x0117}, |
677 | {0xa0, 0x4c, 0x0118}, | 710 | {0xa0, 0x4c, 0x0118}, |
678 | {0xa0, 0x03, 0x0008}, /* clock ? */ | 711 | {0xa0, 0x03, 0x0008}, /* clock ? */ |
679 | {0xa0, 0x08, 0x01c6}, | 712 | {0xa0, 0x08, 0x01c6}, /* sharpness+ */ |
680 | {0xa0, 0x0f, 0x01cb}, | 713 | {0xa0, 0x0f, 0x01cb}, /* sharpness- */ |
681 | {0xa0, 0x13, 0x0120}, /* gamma 4 */ | 714 | {0xa0, 0x13, 0x0120}, /* gamma 4 */ |
682 | {0xa0, 0x38, 0x0121}, | 715 | {0xa0, 0x38, 0x0121}, |
683 | {0xa0, 0x59, 0x0122}, | 716 | {0xa0, 0x59, 0x0122}, |
@@ -824,7 +857,7 @@ static struct usb_action cs2102K_Initial[] = { | |||
824 | {0xa0, 0x00, 0x01a7}, | 857 | {0xa0, 0x00, 0x01a7}, |
825 | {0xa0, 0x04, 0x01a7}, | 858 | {0xa0, 0x04, 0x01a7}, |
826 | {0xa0, 0x00, 0x01a7}, | 859 | {0xa0, 0x00, 0x01a7}, |
827 | {0, 0, 0} | 860 | {} |
828 | }; | 861 | }; |
829 | 862 | ||
830 | static struct usb_action cs2102K_InitialScale[] = { | 863 | static struct usb_action cs2102K_InitialScale[] = { |
@@ -936,8 +969,8 @@ static struct usb_action cs2102K_InitialScale[] = { | |||
936 | {0xa0, 0x40, 0x0117}, | 969 | {0xa0, 0x40, 0x0117}, |
937 | {0xa0, 0x4c, 0x0118}, | 970 | {0xa0, 0x4c, 0x0118}, |
938 | {0xa0, 0x03, 0x0008}, /* clock ? */ | 971 | {0xa0, 0x03, 0x0008}, /* clock ? */ |
939 | {0xa0, 0x08, 0x01c6}, | 972 | {0xa0, 0x08, 0x01c6}, /* sharpness+ */ |
940 | {0xa0, 0x0f, 0x01cb}, | 973 | {0xa0, 0x0f, 0x01cb}, /* sharpness- */ |
941 | {0xa0, 0x13, 0x0120}, /* gamma 4 */ | 974 | {0xa0, 0x13, 0x0120}, /* gamma 4 */ |
942 | {0xa0, 0x38, 0x0121}, | 975 | {0xa0, 0x38, 0x0121}, |
943 | {0xa0, 0x59, 0x0122}, | 976 | {0xa0, 0x59, 0x0122}, |
@@ -1137,8 +1170,8 @@ static struct usb_action cs2102K_InitialScale[] = { | |||
1137 | {0xa0, 0x40, 0x0117}, | 1170 | {0xa0, 0x40, 0x0117}, |
1138 | {0xa0, 0x4c, 0x0118}, | 1171 | {0xa0, 0x4c, 0x0118}, |
1139 | {0xa0, 0x03, 0x0008}, /* clock ? */ | 1172 | {0xa0, 0x03, 0x0008}, /* clock ? */ |
1140 | {0xa0, 0x08, 0x01c6}, | 1173 | {0xa0, 0x08, 0x01c6}, /* sharpness+ */ |
1141 | {0xa0, 0x0f, 0x01cb}, | 1174 | {0xa0, 0x0f, 0x01cb}, /* sharpness- */ |
1142 | {0xa0, 0x13, 0x0120}, /* gamma 4 */ | 1175 | {0xa0, 0x13, 0x0120}, /* gamma 4 */ |
1143 | {0xa0, 0x38, 0x0121}, | 1176 | {0xa0, 0x38, 0x0121}, |
1144 | {0xa0, 0x59, 0x0122}, | 1177 | {0xa0, 0x59, 0x0122}, |
@@ -1401,7 +1434,7 @@ static struct usb_action cs2102K_InitialScale[] = { | |||
1401 | {0xa0, 0x04, 0x01a7}, | 1434 | {0xa0, 0x04, 0x01a7}, |
1402 | {0xa0, 0x00, 0x01a7}, | 1435 | {0xa0, 0x00, 0x01a7}, |
1403 | {0xa0, 0x04, 0x01a7}, | 1436 | {0xa0, 0x04, 0x01a7}, |
1404 | {0, 0, 0} | 1437 | {} |
1405 | }; | 1438 | }; |
1406 | 1439 | ||
1407 | static struct usb_action gc0305_Initial[] = { /* 640x480 */ | 1440 | static struct usb_action gc0305_Initial[] = { /* 640x480 */ |
@@ -1466,7 +1499,7 @@ static struct usb_action gc0305_Initial[] = { /* 640x480 */ | |||
1466 | {0xa0, 0x40, 0x0117}, /* 01,17,40,cc */ | 1499 | {0xa0, 0x40, 0x0117}, /* 01,17,40,cc */ |
1467 | {0xa0, 0x52, 0x0118}, /* 01,18,52,cc */ | 1500 | {0xa0, 0x52, 0x0118}, /* 01,18,52,cc */ |
1468 | {0xa0, 0x03, 0x0113}, /* 01,13,03,cc */ | 1501 | {0xa0, 0x03, 0x0113}, /* 01,13,03,cc */ |
1469 | {0,0,0} | 1502 | {} |
1470 | }; | 1503 | }; |
1471 | static struct usb_action gc0305_InitialScale[] = { /* 320x240 */ | 1504 | static struct usb_action gc0305_InitialScale[] = { /* 320x240 */ |
1472 | {0xa0, 0x01, 0x0000}, /* 00,00,01,cc */ | 1505 | {0xa0, 0x01, 0x0000}, /* 00,00,01,cc */ |
@@ -1529,7 +1562,7 @@ static struct usb_action gc0305_InitialScale[] = { /* 320x240 */ | |||
1529 | {0xa0, 0x40, 0x0117}, /* 01,17,40,cc */ | 1562 | {0xa0, 0x40, 0x0117}, /* 01,17,40,cc */ |
1530 | {0xa0, 0x52, 0x0118}, /* 01,18,52,cc */ | 1563 | {0xa0, 0x52, 0x0118}, /* 01,18,52,cc */ |
1531 | {0xa0, 0x03, 0x0113}, /* 01,13,03,cc */ | 1564 | {0xa0, 0x03, 0x0113}, /* 01,13,03,cc */ |
1532 | {0,0,0} | 1565 | {} |
1533 | }; | 1566 | }; |
1534 | static struct usb_action gc0305_50HZ[] = { | 1567 | static struct usb_action gc0305_50HZ[] = { |
1535 | {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ | 1568 | {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ |
@@ -1552,7 +1585,7 @@ static struct usb_action gc0305_50HZ[] = { | |||
1552 | {0xa0, 0x60, 0x011d}, /* 01,1d,60,cc */ | 1585 | {0xa0, 0x60, 0x011d}, /* 01,1d,60,cc */ |
1553 | {0xa0, 0x42, 0x0180}, /* 01,80,42,cc */ | 1586 | {0xa0, 0x42, 0x0180}, /* 01,80,42,cc */ |
1554 | /* {0xa0, 0x85, 0x018d}, * 01,8d,85,cc * * if 640x480 */ | 1587 | /* {0xa0, 0x85, 0x018d}, * 01,8d,85,cc * * if 640x480 */ |
1555 | {0,0,0} | 1588 | {} |
1556 | }; | 1589 | }; |
1557 | static struct usb_action gc0305_60HZ[] = { | 1590 | static struct usb_action gc0305_60HZ[] = { |
1558 | {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ | 1591 | {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ |
@@ -1575,7 +1608,7 @@ static struct usb_action gc0305_60HZ[] = { | |||
1575 | {0xa0, 0x60, 0x011d}, /* 01,1d,60,cc */ | 1608 | {0xa0, 0x60, 0x011d}, /* 01,1d,60,cc */ |
1576 | {0xa0, 0x42, 0x0180}, /* 01,80,42,cc */ | 1609 | {0xa0, 0x42, 0x0180}, /* 01,80,42,cc */ |
1577 | {0xa0, 0x80, 0x018d}, /* 01,8d,80,cc */ | 1610 | {0xa0, 0x80, 0x018d}, /* 01,8d,80,cc */ |
1578 | {0,0,0} | 1611 | {} |
1579 | }; | 1612 | }; |
1580 | 1613 | ||
1581 | static struct usb_action gc0305_NoFliker[] = { | 1614 | static struct usb_action gc0305_NoFliker[] = { |
@@ -1598,7 +1631,7 @@ static struct usb_action gc0305_NoFliker[] = { | |||
1598 | {0xa0, 0x60, 0x011d}, /* 01,1d,60,cc */ | 1631 | {0xa0, 0x60, 0x011d}, /* 01,1d,60,cc */ |
1599 | {0xa0, 0x03, 0x0180}, /* 01,80,03,cc */ | 1632 | {0xa0, 0x03, 0x0180}, /* 01,80,03,cc */ |
1600 | {0xa0, 0x80, 0x018d}, /* 01,8d,80,cc */ | 1633 | {0xa0, 0x80, 0x018d}, /* 01,8d,80,cc */ |
1601 | {0,0,0} | 1634 | {} |
1602 | }; | 1635 | }; |
1603 | 1636 | ||
1604 | /* play poker with registers at your own risk !! */ | 1637 | /* play poker with registers at your own risk !! */ |
@@ -1647,11 +1680,11 @@ static struct usb_action hdcs2020xx_Initial[] = { | |||
1647 | {0xa1, 0x01, 0x0002}, | 1680 | {0xa1, 0x01, 0x0002}, |
1648 | {0xa1, 0x01, 0x0008}, | 1681 | {0xa1, 0x01, 0x0008}, |
1649 | {0xa0, 0x03, 0x0008}, /* clock ? */ | 1682 | {0xa0, 0x03, 0x0008}, /* clock ? */ |
1650 | {0xa0, 0x04, 0x01c6}, | 1683 | {0xa0, 0x04, 0x01c6}, /* sharpness+ */ |
1651 | {0xa1, 0x01, 0x01c8}, | 1684 | {0xa1, 0x01, 0x01c8}, |
1652 | {0xa1, 0x01, 0x01c9}, | 1685 | {0xa1, 0x01, 0x01c9}, |
1653 | {0xa1, 0x01, 0x01ca}, | 1686 | {0xa1, 0x01, 0x01ca}, |
1654 | {0xa0, 0x07, 0x01cb}, | 1687 | {0xa0, 0x07, 0x01cb}, /* sharpness- */ |
1655 | {0xa0, 0x11, 0x0120}, /* gamma ~4 */ | 1688 | {0xa0, 0x11, 0x0120}, /* gamma ~4 */ |
1656 | {0xa0, 0x37, 0x0121}, | 1689 | {0xa0, 0x37, 0x0121}, |
1657 | {0xa0, 0x58, 0x0122}, | 1690 | {0xa0, 0x58, 0x0122}, |
@@ -1744,7 +1777,7 @@ static struct usb_action hdcs2020xx_Initial[] = { | |||
1744 | {0xa1, 0x01, 0x0118}, | 1777 | {0xa1, 0x01, 0x0118}, |
1745 | /* {0xa0, 0x02, 0x0008}, */ | 1778 | /* {0xa0, 0x02, 0x0008}, */ |
1746 | {0xa0, 0x00, 0x0007}, | 1779 | {0xa0, 0x00, 0x0007}, |
1747 | {0, 0, 0} | 1780 | {} |
1748 | }; | 1781 | }; |
1749 | 1782 | ||
1750 | static struct usb_action hdcs2020xx_InitialScale[] = { | 1783 | static struct usb_action hdcs2020xx_InitialScale[] = { |
@@ -1792,11 +1825,11 @@ static struct usb_action hdcs2020xx_InitialScale[] = { | |||
1792 | {0xa1, 0x01, 0x0002}, | 1825 | {0xa1, 0x01, 0x0002}, |
1793 | {0xa1, 0x01, 0x0008}, | 1826 | {0xa1, 0x01, 0x0008}, |
1794 | {0xa0, 0x03, 0x0008}, /* clock ? */ | 1827 | {0xa0, 0x03, 0x0008}, /* clock ? */ |
1795 | {0xa0, 0x04, 0x01c6}, | 1828 | {0xa0, 0x04, 0x01c6}, /* sharpness+ */ |
1796 | {0xa1, 0x01, 0x01c8}, | 1829 | {0xa1, 0x01, 0x01c8}, |
1797 | {0xa1, 0x01, 0x01c9}, | 1830 | {0xa1, 0x01, 0x01c9}, |
1798 | {0xa1, 0x01, 0x01ca}, | 1831 | {0xa1, 0x01, 0x01ca}, |
1799 | {0xa0, 0x07, 0x01cb}, | 1832 | {0xa0, 0x07, 0x01cb}, /* sharpness- */ |
1800 | {0xa0, 0x11, 0x0120}, /* gamma ~4*/ | 1833 | {0xa0, 0x11, 0x0120}, /* gamma ~4*/ |
1801 | {0xa0, 0x37, 0x0121}, | 1834 | {0xa0, 0x37, 0x0121}, |
1802 | {0xa0, 0x58, 0x0122}, | 1835 | {0xa0, 0x58, 0x0122}, |
@@ -1887,7 +1920,7 @@ static struct usb_action hdcs2020xx_InitialScale[] = { | |||
1887 | /* {0xa0, 0x02, 0x0008}, */ | 1920 | /* {0xa0, 0x02, 0x0008}, */ |
1888 | {0xa0, 0x00, 0x0007}, | 1921 | {0xa0, 0x00, 0x0007}, |
1889 | /* {0xa0, 0x18, 0x00fe}, */ | 1922 | /* {0xa0, 0x18, 0x00fe}, */ |
1890 | {0, 0, 0} | 1923 | {} |
1891 | }; | 1924 | }; |
1892 | static struct usb_action hdcs2020xb_Initial[] = { | 1925 | static struct usb_action hdcs2020xb_Initial[] = { |
1893 | {0xa0, 0x01, 0x0000}, | 1926 | {0xa0, 0x01, 0x0000}, |
@@ -1942,11 +1975,11 @@ static struct usb_action hdcs2020xb_Initial[] = { | |||
1942 | {0xa0, 0x40, 0x0118}, | 1975 | {0xa0, 0x40, 0x0118}, |
1943 | {0xa1, 0x01, 0x0008}, | 1976 | {0xa1, 0x01, 0x0008}, |
1944 | {0xa0, 0x03, 0x0008}, /* clock ? */ | 1977 | {0xa0, 0x03, 0x0008}, /* clock ? */ |
1945 | {0xa0, 0x08, 0x01c6}, | 1978 | {0xa0, 0x08, 0x01c6}, /* sharpness+ */ |
1946 | {0xa1, 0x01, 0x01c8}, | 1979 | {0xa1, 0x01, 0x01c8}, |
1947 | {0xa1, 0x01, 0x01c9}, | 1980 | {0xa1, 0x01, 0x01c9}, |
1948 | {0xa1, 0x01, 0x01ca}, | 1981 | {0xa1, 0x01, 0x01ca}, |
1949 | {0xa0, 0x0f, 0x01cb}, | 1982 | {0xa0, 0x0f, 0x01cb}, /* sharpness- */ |
1950 | {0xa0, 0x13, 0x0120}, /* gamma 4 */ | 1983 | {0xa0, 0x13, 0x0120}, /* gamma 4 */ |
1951 | {0xa0, 0x38, 0x0121}, | 1984 | {0xa0, 0x38, 0x0121}, |
1952 | {0xa0, 0x59, 0x0122}, | 1985 | {0xa0, 0x59, 0x0122}, |
@@ -2019,7 +2052,7 @@ static struct usb_action hdcs2020xb_Initial[] = { | |||
2019 | {0xa0, 0x40, 0x0116}, | 2052 | {0xa0, 0x40, 0x0116}, |
2020 | {0xa0, 0x40, 0x0117}, | 2053 | {0xa0, 0x40, 0x0117}, |
2021 | {0xa0, 0x40, 0x0118}, | 2054 | {0xa0, 0x40, 0x0118}, |
2022 | {0, 0, 0} | 2055 | {} |
2023 | }; | 2056 | }; |
2024 | static struct usb_action hdcs2020xb_InitialScale[] = { | 2057 | static struct usb_action hdcs2020xb_InitialScale[] = { |
2025 | {0xa0, 0x01, 0x0000}, | 2058 | {0xa0, 0x01, 0x0000}, |
@@ -2072,11 +2105,11 @@ static struct usb_action hdcs2020xb_InitialScale[] = { | |||
2072 | {0xa0, 0x40, 0x0118}, | 2105 | {0xa0, 0x40, 0x0118}, |
2073 | {0xa1, 0x01, 0x0008}, | 2106 | {0xa1, 0x01, 0x0008}, |
2074 | {0xa0, 0x03, 0x0008}, /* clock ? */ | 2107 | {0xa0, 0x03, 0x0008}, /* clock ? */ |
2075 | {0xa0, 0x08, 0x01c6}, | 2108 | {0xa0, 0x08, 0x01c6}, /* sharpness+ */ |
2076 | {0xa1, 0x01, 0x01c8}, | 2109 | {0xa1, 0x01, 0x01c8}, |
2077 | {0xa1, 0x01, 0x01c9}, | 2110 | {0xa1, 0x01, 0x01c9}, |
2078 | {0xa1, 0x01, 0x01ca}, | 2111 | {0xa1, 0x01, 0x01ca}, |
2079 | {0xa0, 0x0f, 0x01cb}, | 2112 | {0xa0, 0x0f, 0x01cb}, /* sharpness- */ |
2080 | {0xa0, 0x13, 0x0120}, /* gamma 4 */ | 2113 | {0xa0, 0x13, 0x0120}, /* gamma 4 */ |
2081 | {0xa0, 0x38, 0x0121}, | 2114 | {0xa0, 0x38, 0x0121}, |
2082 | {0xa0, 0x59, 0x0122}, | 2115 | {0xa0, 0x59, 0x0122}, |
@@ -2147,7 +2180,7 @@ static struct usb_action hdcs2020xb_InitialScale[] = { | |||
2147 | {0xa0, 0x40, 0x0116}, | 2180 | {0xa0, 0x40, 0x0116}, |
2148 | {0xa0, 0x40, 0x0117}, | 2181 | {0xa0, 0x40, 0x0117}, |
2149 | {0xa0, 0x40, 0x0118}, | 2182 | {0xa0, 0x40, 0x0118}, |
2150 | {0, 0, 0} | 2183 | {} |
2151 | }; | 2184 | }; |
2152 | static struct usb_action hdcs2020b_50HZ[] = { | 2185 | static struct usb_action hdcs2020b_50HZ[] = { |
2153 | {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ | 2186 | {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ |
@@ -2168,7 +2201,7 @@ static struct usb_action hdcs2020b_50HZ[] = { | |||
2168 | {0xa0, 0x05, 0x001d}, /* 00,1d,05,cc */ | 2201 | {0xa0, 0x05, 0x001d}, /* 00,1d,05,cc */ |
2169 | {0xa0, 0x1a, 0x001e}, /* 00,1e,1a,cc */ | 2202 | {0xa0, 0x1a, 0x001e}, /* 00,1e,1a,cc */ |
2170 | {0xa0, 0x2f, 0x001f}, /* 00,1f,2f,cc */ | 2203 | {0xa0, 0x2f, 0x001f}, /* 00,1f,2f,cc */ |
2171 | {0, 0, 0} | 2204 | {} |
2172 | }; | 2205 | }; |
2173 | static struct usb_action hdcs2020b_60HZ[] = { | 2206 | static struct usb_action hdcs2020b_60HZ[] = { |
2174 | {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ | 2207 | {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ |
@@ -2189,7 +2222,7 @@ static struct usb_action hdcs2020b_60HZ[] = { | |||
2189 | {0xa0, 0x04, 0x001d}, /* 00,1d,04,cc */ | 2222 | {0xa0, 0x04, 0x001d}, /* 00,1d,04,cc */ |
2190 | {0xa0, 0x18, 0x001e}, /* 00,1e,18,cc */ | 2223 | {0xa0, 0x18, 0x001e}, /* 00,1e,18,cc */ |
2191 | {0xa0, 0x2c, 0x001f}, /* 00,1f,2c,cc */ | 2224 | {0xa0, 0x2c, 0x001f}, /* 00,1f,2c,cc */ |
2192 | {0, 0, 0} | 2225 | {} |
2193 | }; | 2226 | }; |
2194 | static struct usb_action hdcs2020b_NoFliker[] = { | 2227 | static struct usb_action hdcs2020b_NoFliker[] = { |
2195 | {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ | 2228 | {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ |
@@ -2210,7 +2243,7 @@ static struct usb_action hdcs2020b_NoFliker[] = { | |||
2210 | {0xa0, 0x04, 0x001d}, /* 00,1d,04,cc */ | 2243 | {0xa0, 0x04, 0x001d}, /* 00,1d,04,cc */ |
2211 | {0xa0, 0x17, 0x001e}, /* 00,1e,17,cc */ | 2244 | {0xa0, 0x17, 0x001e}, /* 00,1e,17,cc */ |
2212 | {0xa0, 0x2a, 0x001f}, /* 00,1f,2a,cc */ | 2245 | {0xa0, 0x2a, 0x001f}, /* 00,1f,2a,cc */ |
2213 | {0, 0, 0} | 2246 | {} |
2214 | }; | 2247 | }; |
2215 | 2248 | ||
2216 | static struct usb_action hv7131bxx_Initial[] = { | 2249 | static struct usb_action hv7131bxx_Initial[] = { |
@@ -2266,11 +2299,11 @@ static struct usb_action hv7131bxx_Initial[] = { | |||
2266 | 2299 | ||
2267 | {0xa1, 0x01, 0x0008}, | 2300 | {0xa1, 0x01, 0x0008}, |
2268 | {0xa0, 0x03, 0x0008}, /* clock ? */ | 2301 | {0xa0, 0x03, 0x0008}, /* clock ? */ |
2269 | {0xa0, 0x08, 0x01c6}, | 2302 | {0xa0, 0x08, 0x01c6}, /* sharpness+ */ |
2270 | {0xa1, 0x01, 0x01c8}, | 2303 | {0xa1, 0x01, 0x01c8}, |
2271 | {0xa1, 0x01, 0x01c9}, | 2304 | {0xa1, 0x01, 0x01c9}, |
2272 | {0xa1, 0x01, 0x01ca}, | 2305 | {0xa1, 0x01, 0x01ca}, |
2273 | {0xa0, 0x0f, 0x01cb}, | 2306 | {0xa0, 0x0f, 0x01cb}, /* sharpness- */ |
2274 | 2307 | ||
2275 | {0xa0, 0x50, 0x010a}, /* matrix */ | 2308 | {0xa0, 0x50, 0x010a}, /* matrix */ |
2276 | {0xa0, 0xf8, 0x010b}, | 2309 | {0xa0, 0xf8, 0x010b}, |
@@ -2318,7 +2351,7 @@ static struct usb_action hv7131bxx_Initial[] = { | |||
2318 | {0xa0, 0x40, 0x0117}, | 2351 | {0xa0, 0x40, 0x0117}, |
2319 | {0xa0, 0x40, 0x0118}, | 2352 | {0xa0, 0x40, 0x0118}, |
2320 | /* {0xa0, 0x02, 0x0008}, */ | 2353 | /* {0xa0, 0x02, 0x0008}, */ |
2321 | {0, 0, 0} | 2354 | {} |
2322 | }; | 2355 | }; |
2323 | 2356 | ||
2324 | static struct usb_action hv7131bxx_InitialScale[] = { | 2357 | static struct usb_action hv7131bxx_InitialScale[] = { |
@@ -2373,11 +2406,11 @@ static struct usb_action hv7131bxx_InitialScale[] = { | |||
2373 | {0xa1, 0x01, 0x0096}, | 2406 | {0xa1, 0x01, 0x0096}, |
2374 | {0xa1, 0x01, 0x0008}, | 2407 | {0xa1, 0x01, 0x0008}, |
2375 | {0xa0, 0x03, 0x0008}, /* clock ? */ | 2408 | {0xa0, 0x03, 0x0008}, /* clock ? */ |
2376 | {0xa0, 0x08, 0x01c6}, | 2409 | {0xa0, 0x08, 0x01c6}, /* sharpness+ */ |
2377 | {0xa1, 0x01, 0x01c8}, | 2410 | {0xa1, 0x01, 0x01c8}, |
2378 | {0xa1, 0x01, 0x01c9}, | 2411 | {0xa1, 0x01, 0x01c9}, |
2379 | {0xa1, 0x01, 0x01ca}, | 2412 | {0xa1, 0x01, 0x01ca}, |
2380 | {0xa0, 0x0f, 0x01cb}, | 2413 | {0xa0, 0x0f, 0x01cb}, /* sharpness- */ |
2381 | 2414 | ||
2382 | {0xa0, 0x50, 0x010a}, /* matrix */ | 2415 | {0xa0, 0x50, 0x010a}, /* matrix */ |
2383 | {0xa0, 0xf8, 0x010b}, | 2416 | {0xa0, 0xf8, 0x010b}, |
@@ -2424,7 +2457,7 @@ static struct usb_action hv7131bxx_InitialScale[] = { | |||
2424 | {0xa0, 0x40, 0x0117}, | 2457 | {0xa0, 0x40, 0x0117}, |
2425 | {0xa0, 0x40, 0x0118}, | 2458 | {0xa0, 0x40, 0x0118}, |
2426 | /* {0xa0, 0x02, 0x0008}, */ | 2459 | /* {0xa0, 0x02, 0x0008}, */ |
2427 | {0, 0, 0} | 2460 | {} |
2428 | }; | 2461 | }; |
2429 | 2462 | ||
2430 | static struct usb_action hv7131cxx_Initial[] = { | 2463 | static struct usb_action hv7131cxx_Initial[] = { |
@@ -2478,11 +2511,11 @@ static struct usb_action hv7131cxx_Initial[] = { | |||
2478 | 2511 | ||
2479 | {0xa1, 0x01, 0x0008}, | 2512 | {0xa1, 0x01, 0x0008}, |
2480 | {0xa0, 0x03, 0x0008}, /* clock ? */ | 2513 | {0xa0, 0x03, 0x0008}, /* clock ? */ |
2481 | {0xa0, 0x08, 0x01c6}, | 2514 | {0xa0, 0x08, 0x01c6}, /* sharpness+ */ |
2482 | {0xa1, 0x01, 0x01c8}, | 2515 | {0xa1, 0x01, 0x01c8}, |
2483 | {0xa1, 0x01, 0x01c9}, | 2516 | {0xa1, 0x01, 0x01c9}, |
2484 | {0xa1, 0x01, 0x01ca}, | 2517 | {0xa1, 0x01, 0x01ca}, |
2485 | {0xa0, 0x0f, 0x01cb}, | 2518 | {0xa0, 0x0f, 0x01cb}, /* sharpness- */ |
2486 | 2519 | ||
2487 | {0xa0, 0x60, 0x010a}, /* matrix */ | 2520 | {0xa0, 0x60, 0x010a}, /* matrix */ |
2488 | {0xa0, 0xf0, 0x010b}, | 2521 | {0xa0, 0xf0, 0x010b}, |
@@ -2518,7 +2551,7 @@ static struct usb_action hv7131cxx_Initial[] = { | |||
2518 | {0xa0, 0x40, 0x0180}, | 2551 | {0xa0, 0x40, 0x0180}, |
2519 | {0xa1, 0x01, 0x0180}, | 2552 | {0xa1, 0x01, 0x0180}, |
2520 | {0xa0, 0x42, 0x0180}, | 2553 | {0xa0, 0x42, 0x0180}, |
2521 | {0, 0, 0} | 2554 | {} |
2522 | }; | 2555 | }; |
2523 | 2556 | ||
2524 | static struct usb_action hv7131cxx_InitialScale[] = { | 2557 | static struct usb_action hv7131cxx_InitialScale[] = { |
@@ -2577,11 +2610,11 @@ static struct usb_action hv7131cxx_InitialScale[] = { | |||
2577 | 2610 | ||
2578 | {0xa1, 0x01, 0x0008}, | 2611 | {0xa1, 0x01, 0x0008}, |
2579 | {0xa0, 0x03, 0x0008}, /* clock ? */ | 2612 | {0xa0, 0x03, 0x0008}, /* clock ? */ |
2580 | {0xa0, 0x08, 0x01c6}, | 2613 | {0xa0, 0x08, 0x01c6}, /* sharpness+ */ |
2581 | {0xa1, 0x01, 0x01c8}, | 2614 | {0xa1, 0x01, 0x01c8}, |
2582 | {0xa1, 0x01, 0x01c9}, | 2615 | {0xa1, 0x01, 0x01c9}, |
2583 | {0xa1, 0x01, 0x01ca}, | 2616 | {0xa1, 0x01, 0x01ca}, |
2584 | {0xa0, 0x0f, 0x01cb}, | 2617 | {0xa0, 0x0f, 0x01cb}, /* sharpness- */ |
2585 | 2618 | ||
2586 | {0xa0, 0x60, 0x010a}, /* matrix */ | 2619 | {0xa0, 0x60, 0x010a}, /* matrix */ |
2587 | {0xa0, 0xf0, 0x010b}, | 2620 | {0xa0, 0xf0, 0x010b}, |
@@ -2619,7 +2652,7 @@ static struct usb_action hv7131cxx_InitialScale[] = { | |||
2619 | {0xa0, 0x40, 0x0180}, | 2652 | {0xa0, 0x40, 0x0180}, |
2620 | {0xa1, 0x01, 0x0180}, | 2653 | {0xa1, 0x01, 0x0180}, |
2621 | {0xa0, 0x42, 0x0180}, | 2654 | {0xa0, 0x42, 0x0180}, |
2622 | {0, 0, 0} | 2655 | {} |
2623 | }; | 2656 | }; |
2624 | 2657 | ||
2625 | static struct usb_action icm105axx_Initial[] = { | 2658 | static struct usb_action icm105axx_Initial[] = { |
@@ -2743,11 +2776,11 @@ static struct usb_action icm105axx_Initial[] = { | |||
2743 | {0xa1, 0x01, 0x0008}, | 2776 | {0xa1, 0x01, 0x0008}, |
2744 | 2777 | ||
2745 | {0xa0, 0x03, 0x0008}, /* clock ? */ | 2778 | {0xa0, 0x03, 0x0008}, /* clock ? */ |
2746 | {0xa0, 0x08, 0x01c6}, | 2779 | {0xa0, 0x08, 0x01c6}, /* sharpness+ */ |
2747 | {0xa1, 0x01, 0x01c8}, | 2780 | {0xa1, 0x01, 0x01c8}, |
2748 | {0xa1, 0x01, 0x01c9}, | 2781 | {0xa1, 0x01, 0x01c9}, |
2749 | {0xa1, 0x01, 0x01ca}, | 2782 | {0xa1, 0x01, 0x01ca}, |
2750 | {0xa0, 0x0f, 0x01cb}, | 2783 | {0xa0, 0x0f, 0x01cb}, /* sharpness- */ |
2751 | {0xa0, 0x52, 0x010a}, /* matrix */ | 2784 | {0xa0, 0x52, 0x010a}, /* matrix */ |
2752 | {0xa0, 0xf7, 0x010b}, | 2785 | {0xa0, 0xf7, 0x010b}, |
2753 | {0xa0, 0xf7, 0x010c}, | 2786 | {0xa0, 0xf7, 0x010c}, |
@@ -2796,7 +2829,7 @@ static struct usb_action icm105axx_Initial[] = { | |||
2796 | {0xa0, 0x40, 0x0116}, | 2829 | {0xa0, 0x40, 0x0116}, |
2797 | {0xa0, 0x40, 0x0117}, | 2830 | {0xa0, 0x40, 0x0117}, |
2798 | {0xa0, 0x40, 0x0118}, | 2831 | {0xa0, 0x40, 0x0118}, |
2799 | {0, 0, 0} | 2832 | {} |
2800 | }; | 2833 | }; |
2801 | 2834 | ||
2802 | static struct usb_action icm105axx_InitialScale[] = { | 2835 | static struct usb_action icm105axx_InitialScale[] = { |
@@ -2924,11 +2957,11 @@ static struct usb_action icm105axx_InitialScale[] = { | |||
2924 | {0xa1, 0x01, 0x0008}, | 2957 | {0xa1, 0x01, 0x0008}, |
2925 | 2958 | ||
2926 | {0xa0, 0x03, 0x0008}, /* clock ? */ | 2959 | {0xa0, 0x03, 0x0008}, /* clock ? */ |
2927 | {0xa0, 0x08, 0x01c6}, | 2960 | {0xa0, 0x08, 0x01c6}, /* sharpness+ */ |
2928 | {0xa1, 0x01, 0x01c8}, | 2961 | {0xa1, 0x01, 0x01c8}, |
2929 | {0xa1, 0x01, 0x01c9}, | 2962 | {0xa1, 0x01, 0x01c9}, |
2930 | {0xa1, 0x01, 0x01ca}, | 2963 | {0xa1, 0x01, 0x01ca}, |
2931 | {0xa0, 0x0f, 0x01cb}, | 2964 | {0xa0, 0x0f, 0x01cb}, /* sharpness- */ |
2932 | 2965 | ||
2933 | {0xa0, 0x52, 0x010a}, /* matrix */ | 2966 | {0xa0, 0x52, 0x010a}, /* matrix */ |
2934 | {0xa0, 0xf7, 0x010b}, | 2967 | {0xa0, 0xf7, 0x010b}, |
@@ -2976,7 +3009,7 @@ static struct usb_action icm105axx_InitialScale[] = { | |||
2976 | {0xa0, 0x40, 0x0116}, | 3009 | {0xa0, 0x40, 0x0116}, |
2977 | {0xa0, 0x40, 0x0117}, | 3010 | {0xa0, 0x40, 0x0117}, |
2978 | {0xa0, 0x40, 0x0118}, | 3011 | {0xa0, 0x40, 0x0118}, |
2979 | {0, 0, 0} | 3012 | {} |
2980 | }; | 3013 | }; |
2981 | static struct usb_action icm105a_50HZ[] = { | 3014 | static struct usb_action icm105a_50HZ[] = { |
2982 | {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ | 3015 | {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ |
@@ -3007,7 +3040,7 @@ static struct usb_action icm105a_50HZ[] = { | |||
3007 | {0xa0, 0xd8, 0x001e}, /* 00,1e,d8,cc */ | 3040 | {0xa0, 0xd8, 0x001e}, /* 00,1e,d8,cc */ |
3008 | {0xa0, 0xea, 0x001f}, /* 00,1f,ea,cc */ | 3041 | {0xa0, 0xea, 0x001f}, /* 00,1f,ea,cc */ |
3009 | {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ | 3042 | {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ |
3010 | {0, 0, 0} | 3043 | {} |
3011 | }; | 3044 | }; |
3012 | static struct usb_action icm105a_50HZScale[] = { | 3045 | static struct usb_action icm105a_50HZScale[] = { |
3013 | {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ | 3046 | {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ |
@@ -3040,7 +3073,7 @@ static struct usb_action icm105a_50HZScale[] = { | |||
3040 | {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ | 3073 | {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ |
3041 | {0xa0, 0x00, 0x01a7}, /* 01,a7,00,cc */ | 3074 | {0xa0, 0x00, 0x01a7}, /* 01,a7,00,cc */ |
3042 | {0xa0, 0xc0, 0x01a8}, /* 01,a8,c0,cc */ | 3075 | {0xa0, 0xc0, 0x01a8}, /* 01,a8,c0,cc */ |
3043 | {0, 0, 0} | 3076 | {} |
3044 | }; | 3077 | }; |
3045 | static struct usb_action icm105a_60HZ[] = { | 3078 | static struct usb_action icm105a_60HZ[] = { |
3046 | {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ | 3079 | {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ |
@@ -3071,7 +3104,7 @@ static struct usb_action icm105a_60HZ[] = { | |||
3071 | {0xa0, 0xd4, 0x001e}, /* 00,1e,d4,cc */ | 3104 | {0xa0, 0xd4, 0x001e}, /* 00,1e,d4,cc */ |
3072 | {0xa0, 0xe8, 0x001f}, /* 00,1f,e8,cc */ | 3105 | {0xa0, 0xe8, 0x001f}, /* 00,1f,e8,cc */ |
3073 | {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ | 3106 | {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ |
3074 | {0, 0, 0} | 3107 | {} |
3075 | }; | 3108 | }; |
3076 | static struct usb_action icm105a_60HZScale[] = { | 3109 | static struct usb_action icm105a_60HZScale[] = { |
3077 | {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ | 3110 | {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ |
@@ -3104,7 +3137,7 @@ static struct usb_action icm105a_60HZScale[] = { | |||
3104 | {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ | 3137 | {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ |
3105 | {0xa0, 0x00, 0x01a7}, /* 01,a7,00,cc */ | 3138 | {0xa0, 0x00, 0x01a7}, /* 01,a7,00,cc */ |
3106 | {0xa0, 0xc0, 0x01a8}, /* 01,a8,c0,cc */ | 3139 | {0xa0, 0xc0, 0x01a8}, /* 01,a8,c0,cc */ |
3107 | {0, 0, 0} | 3140 | {} |
3108 | }; | 3141 | }; |
3109 | static struct usb_action icm105a_NoFliker[] = { | 3142 | static struct usb_action icm105a_NoFliker[] = { |
3110 | {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ | 3143 | {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ |
@@ -3135,7 +3168,7 @@ static struct usb_action icm105a_NoFliker[] = { | |||
3135 | {0xa0, 0xd4, 0x001e}, /* 00,1e,d4,cc */ | 3168 | {0xa0, 0xd4, 0x001e}, /* 00,1e,d4,cc */ |
3136 | {0xa0, 0xe8, 0x001f}, /* 00,1f,e8,cc */ | 3169 | {0xa0, 0xe8, 0x001f}, /* 00,1f,e8,cc */ |
3137 | {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ | 3170 | {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ |
3138 | {0, 0, 0} | 3171 | {} |
3139 | }; | 3172 | }; |
3140 | static struct usb_action icm105a_NoFlikerScale[] = { | 3173 | static struct usb_action icm105a_NoFlikerScale[] = { |
3141 | {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ | 3174 | {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ |
@@ -3168,7 +3201,7 @@ static struct usb_action icm105a_NoFlikerScale[] = { | |||
3168 | {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ | 3201 | {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ |
3169 | {0xa0, 0x00, 0x01a7}, /* 01,a7,00,cc */ | 3202 | {0xa0, 0x00, 0x01a7}, /* 01,a7,00,cc */ |
3170 | {0xa0, 0xc0, 0x01a8}, /* 01,a8,c0,cc */ | 3203 | {0xa0, 0xc0, 0x01a8}, /* 01,a8,c0,cc */ |
3171 | {0, 0, 0} | 3204 | {} |
3172 | }; | 3205 | }; |
3173 | 3206 | ||
3174 | static struct usb_action MC501CB_InitialScale[] = { | 3207 | static struct usb_action MC501CB_InitialScale[] = { |
@@ -3288,7 +3321,7 @@ static struct usb_action MC501CB_InitialScale[] = { | |||
3288 | {0xaa, 0x36, 0x001d}, /* 00,36,1D,aa */ | 3321 | {0xaa, 0x36, 0x001d}, /* 00,36,1D,aa */ |
3289 | {0xaa, 0x37, 0x004c}, /* 00,37,4C,aa */ | 3322 | {0xaa, 0x37, 0x004c}, /* 00,37,4C,aa */ |
3290 | {0xaa, 0x3b, 0x001d}, /* 00,3B,1D,aa */ | 3323 | {0xaa, 0x3b, 0x001d}, /* 00,3B,1D,aa */ |
3291 | {0, 0, 0} | 3324 | {} |
3292 | }; | 3325 | }; |
3293 | 3326 | ||
3294 | static struct usb_action MC501CB_Initial[] = { /* 320x240 */ | 3327 | static struct usb_action MC501CB_Initial[] = { /* 320x240 */ |
@@ -3407,7 +3440,7 @@ static struct usb_action MC501CB_Initial[] = { /* 320x240 */ | |||
3407 | {0xaa, 0x36, 0x001d}, /* 00,36,1D,aa */ | 3440 | {0xaa, 0x36, 0x001d}, /* 00,36,1D,aa */ |
3408 | {0xaa, 0x37, 0x004c}, /* 00,37,4C,aa */ | 3441 | {0xaa, 0x37, 0x004c}, /* 00,37,4C,aa */ |
3409 | {0xaa, 0x3b, 0x001d}, /* 00,3B,1D,aa */ | 3442 | {0xaa, 0x3b, 0x001d}, /* 00,3B,1D,aa */ |
3410 | {0, 0, 0} | 3443 | {} |
3411 | }; | 3444 | }; |
3412 | 3445 | ||
3413 | static struct usb_action MC501CB_50HZ[] = { | 3446 | static struct usb_action MC501CB_50HZ[] = { |
@@ -3424,7 +3457,7 @@ static struct usb_action MC501CB_50HZ[] = { | |||
3424 | {0xaa, 0x36, 0x003a}, /* 00,36,3A,aa */ | 3457 | {0xaa, 0x36, 0x003a}, /* 00,36,3A,aa */ |
3425 | {0xaa, 0x37, 0x0098}, /* 00,37,98,aa */ | 3458 | {0xaa, 0x37, 0x0098}, /* 00,37,98,aa */ |
3426 | {0xaa, 0x3b, 0x003a}, /* 00,3B,3A,aa */ | 3459 | {0xaa, 0x3b, 0x003a}, /* 00,3B,3A,aa */ |
3427 | {0, 0, 0} | 3460 | {} |
3428 | }; | 3461 | }; |
3429 | 3462 | ||
3430 | static struct usb_action MC501CB_50HZScale[] = { | 3463 | static struct usb_action MC501CB_50HZScale[] = { |
@@ -3441,7 +3474,7 @@ static struct usb_action MC501CB_50HZScale[] = { | |||
3441 | {0xaa, 0x36, 0x0018}, /* 00,36,18,aa */ | 3474 | {0xaa, 0x36, 0x0018}, /* 00,36,18,aa */ |
3442 | {0xaa, 0x37, 0x006a}, /* 00,37,6A,aa */ | 3475 | {0xaa, 0x37, 0x006a}, /* 00,37,6A,aa */ |
3443 | {0xaa, 0x3d, 0x0018}, /* 00,3D,18,aa */ | 3476 | {0xaa, 0x3d, 0x0018}, /* 00,3D,18,aa */ |
3444 | {0, 0, 0} | 3477 | {} |
3445 | }; | 3478 | }; |
3446 | 3479 | ||
3447 | static struct usb_action MC501CB_60HZ[] = { | 3480 | static struct usb_action MC501CB_60HZ[] = { |
@@ -3458,7 +3491,7 @@ static struct usb_action MC501CB_60HZ[] = { | |||
3458 | {0xaa, 0x36, 0x0030}, /* 00,36,30,aa */ | 3491 | {0xaa, 0x36, 0x0030}, /* 00,36,30,aa */ |
3459 | {0xaa, 0x37, 0x00d4}, /* 00,37,D4,aa */ | 3492 | {0xaa, 0x37, 0x00d4}, /* 00,37,D4,aa */ |
3460 | {0xaa, 0x3d, 0x0030}, /* 00,3D,30,aa */ | 3493 | {0xaa, 0x3d, 0x0030}, /* 00,3D,30,aa */ |
3461 | {0, 0, 0} | 3494 | {} |
3462 | }; | 3495 | }; |
3463 | 3496 | ||
3464 | static struct usb_action MC501CB_60HZScale[] = { | 3497 | static struct usb_action MC501CB_60HZScale[] = { |
@@ -3475,7 +3508,7 @@ static struct usb_action MC501CB_60HZScale[] = { | |||
3475 | {0xaa, 0x36, 0x0018}, /* 00,36,18,aa */ | 3508 | {0xaa, 0x36, 0x0018}, /* 00,36,18,aa */ |
3476 | {0xaa, 0x37, 0x006a}, /* 00,37,6A,aa */ | 3509 | {0xaa, 0x37, 0x006a}, /* 00,37,6A,aa */ |
3477 | {0xaa, 0x3d, 0x0018}, /* 00,3D,18,aa */ | 3510 | {0xaa, 0x3d, 0x0018}, /* 00,3D,18,aa */ |
3478 | {0, 0, 0} | 3511 | {} |
3479 | }; | 3512 | }; |
3480 | 3513 | ||
3481 | static struct usb_action MC501CB_NoFliker[] = { | 3514 | static struct usb_action MC501CB_NoFliker[] = { |
@@ -3492,7 +3525,7 @@ static struct usb_action MC501CB_NoFliker[] = { | |||
3492 | {0xaa, 0x36, 0x0030}, /* 00,36,30,aa */ | 3525 | {0xaa, 0x36, 0x0030}, /* 00,36,30,aa */ |
3493 | {0xaa, 0x37, 0x00d4}, /* 00,37,D4,aa */ | 3526 | {0xaa, 0x37, 0x00d4}, /* 00,37,D4,aa */ |
3494 | {0xaa, 0x3d, 0x0030}, /* 00,3D,30,aa */ | 3527 | {0xaa, 0x3d, 0x0030}, /* 00,3D,30,aa */ |
3495 | {0, 0, 0} | 3528 | {} |
3496 | }; | 3529 | }; |
3497 | 3530 | ||
3498 | static struct usb_action MC501CB_NoFlikerScale[] = { | 3531 | static struct usb_action MC501CB_NoFlikerScale[] = { |
@@ -3504,7 +3537,7 @@ static struct usb_action MC501CB_NoFlikerScale[] = { | |||
3504 | {0xaa, 0x3e, 0x00d4}, /* 00,3E,D4,aa */ | 3537 | {0xaa, 0x3e, 0x00d4}, /* 00,3E,D4,aa */ |
3505 | {0xaa, 0x3b, 0x0030}, /* 00,3B,30,aa */ | 3538 | {0xaa, 0x3b, 0x0030}, /* 00,3B,30,aa */ |
3506 | {0xaa, 0x3c, 0x00d4}, /* 00,3C,D4,aa */ | 3539 | {0xaa, 0x3c, 0x00d4}, /* 00,3C,D4,aa */ |
3507 | {0, 0, 0} | 3540 | {} |
3508 | }; | 3541 | }; |
3509 | 3542 | ||
3510 | /* from zs211.inf - HKR,%OV7620%,Initial - 640x480 */ | 3543 | /* from zs211.inf - HKR,%OV7620%,Initial - 640x480 */ |
@@ -3575,7 +3608,7 @@ static struct usb_action OV7620_mode0[] = { | |||
3575 | {0xa0, 0x40, 0x011d}, /* 01,1d,40,cc */ | 3608 | {0xa0, 0x40, 0x011d}, /* 01,1d,40,cc */ |
3576 | {0xa0, 0x02, 0x0180}, /* 01,80,02,cc */ | 3609 | {0xa0, 0x02, 0x0180}, /* 01,80,02,cc */ |
3577 | {0xa0, 0x50, 0x01a8}, /* 01,a8,50,cc */ | 3610 | {0xa0, 0x50, 0x01a8}, /* 01,a8,50,cc */ |
3578 | {0, 0, 0} | 3611 | {} |
3579 | }; | 3612 | }; |
3580 | 3613 | ||
3581 | /* from zs211.inf - HKR,%OV7620%,InitialScale - 320x240 */ | 3614 | /* from zs211.inf - HKR,%OV7620%,InitialScale - 320x240 */ |
@@ -3646,7 +3679,7 @@ static struct usb_action OV7620_mode1[] = { | |||
3646 | {0xa0, 0x50, 0x011d}, /* 01,1d,50,cc */ | 3679 | {0xa0, 0x50, 0x011d}, /* 01,1d,50,cc */ |
3647 | {0xa0, 0x02, 0x0180}, /* 01,80,02,cc */ | 3680 | {0xa0, 0x02, 0x0180}, /* 01,80,02,cc */ |
3648 | {0xa0, 0x50, 0x01a8}, /* 01,a8,50,cc */ | 3681 | {0xa0, 0x50, 0x01a8}, /* 01,a8,50,cc */ |
3649 | {0, 0, 0} | 3682 | {} |
3650 | }; | 3683 | }; |
3651 | 3684 | ||
3652 | /* from zs211.inf - HKR,%OV7620%\AE,50HZ */ | 3685 | /* from zs211.inf - HKR,%OV7620%\AE,50HZ */ |
@@ -3665,7 +3698,7 @@ static struct usb_action OV7620_50HZ[] = { | |||
3665 | {0xaa, 0x10, 0x0082}, /* 00,10,82,aa */ | 3698 | {0xaa, 0x10, 0x0082}, /* 00,10,82,aa */ |
3666 | {0xaa, 0x76, 0x0003}, /* 00,76,03,aa */ | 3699 | {0xaa, 0x76, 0x0003}, /* 00,76,03,aa */ |
3667 | /* {0xa0, 0x40, 0x0002}, * 00,02,40,cc - if mode0 (640x480) */ | 3700 | /* {0xa0, 0x40, 0x0002}, * 00,02,40,cc - if mode0 (640x480) */ |
3668 | {0, 0, 0} | 3701 | {} |
3669 | }; | 3702 | }; |
3670 | 3703 | ||
3671 | /* from zs211.inf - HKR,%OV7620%\AE,60HZ */ | 3704 | /* from zs211.inf - HKR,%OV7620%\AE,60HZ */ |
@@ -3687,7 +3720,7 @@ static struct usb_action OV7620_60HZ[] = { | |||
3687 | /* ?? in gspca v1, it was | 3720 | /* ?? in gspca v1, it was |
3688 | {0xa0, 0x00, 0x0039}, * 00,00,00,dd * | 3721 | {0xa0, 0x00, 0x0039}, * 00,00,00,dd * |
3689 | {0xa1, 0x01, 0x0037}, */ | 3722 | {0xa1, 0x01, 0x0037}, */ |
3690 | {0, 0, 0} | 3723 | {} |
3691 | }; | 3724 | }; |
3692 | 3725 | ||
3693 | /* from zs211.inf - HKR,%OV7620%\AE,NoFliker */ | 3726 | /* from zs211.inf - HKR,%OV7620%\AE,NoFliker */ |
@@ -3707,7 +3740,7 @@ static struct usb_action OV7620_NoFliker[] = { | |||
3707 | /* ?? was | 3740 | /* ?? was |
3708 | {0xa0, 0x00, 0x0039}, * 00,00,00,dd * | 3741 | {0xa0, 0x00, 0x0039}, * 00,00,00,dd * |
3709 | {0xa1, 0x01, 0x0037}, */ | 3742 | {0xa1, 0x01, 0x0037}, */ |
3710 | {0, 0, 0} | 3743 | {} |
3711 | }; | 3744 | }; |
3712 | 3745 | ||
3713 | static struct usb_action ov7630c_Initial[] = { | 3746 | static struct usb_action ov7630c_Initial[] = { |
@@ -3795,14 +3828,11 @@ static struct usb_action ov7630c_Initial[] = { | |||
3795 | /* 0x03, */ | 3828 | /* 0x03, */ |
3796 | {0xa1, 0x01, 0x0008}, | 3829 | {0xa1, 0x01, 0x0008}, |
3797 | {0xa0, 0x03, 0x0008}, /* clock ? */ | 3830 | {0xa0, 0x03, 0x0008}, /* clock ? */ |
3798 | {0xa0, 0x08, 0x01c6}, | 3831 | {0xa0, 0x08, 0x01c6}, /* sharpness+ */ |
3799 | /* 0x05, */ | ||
3800 | {0xa1, 0x01, 0x01c8}, | 3832 | {0xa1, 0x01, 0x01c8}, |
3801 | /* 0x07, */ | ||
3802 | {0xa1, 0x01, 0x01c9}, | 3833 | {0xa1, 0x01, 0x01c9}, |
3803 | /* 0x0f, */ | ||
3804 | {0xa1, 0x01, 0x01ca}, | 3834 | {0xa1, 0x01, 0x01ca}, |
3805 | {0xa0, 0x0f, 0x01cb}, | 3835 | {0xa0, 0x0f, 0x01cb}, /* sharpness- */ |
3806 | {0xa0, 0x01, 0x0120}, /* gamma 2 ?*/ | 3836 | {0xa0, 0x01, 0x0120}, /* gamma 2 ?*/ |
3807 | {0xa0, 0x0c, 0x0121}, | 3837 | {0xa0, 0x0c, 0x0121}, |
3808 | {0xa0, 0x1f, 0x0122}, | 3838 | {0xa0, 0x1f, 0x0122}, |
@@ -3867,7 +3897,7 @@ static struct usb_action ov7630c_Initial[] = { | |||
3867 | {0xaa, 0x13, 0x0083}, /* 40 */ | 3897 | {0xaa, 0x13, 0x0083}, /* 40 */ |
3868 | {0xa1, 0x01, 0x0180}, | 3898 | {0xa1, 0x01, 0x0180}, |
3869 | {0xa0, 0x42, 0x0180}, | 3899 | {0xa0, 0x42, 0x0180}, |
3870 | {0, 0, 0} | 3900 | {} |
3871 | }; | 3901 | }; |
3872 | 3902 | ||
3873 | static struct usb_action ov7630c_InitialScale[] = { | 3903 | static struct usb_action ov7630c_InitialScale[] = { |
@@ -3954,14 +3984,11 @@ static struct usb_action ov7630c_InitialScale[] = { | |||
3954 | 3984 | ||
3955 | {0xa1, 0x01, 0x0008}, | 3985 | {0xa1, 0x01, 0x0008}, |
3956 | {0xa0, 0x03, 0x0008}, /* clock ? */ | 3986 | {0xa0, 0x03, 0x0008}, /* clock ? */ |
3957 | {0xa0, 0x08, 0x01c6}, | 3987 | {0xa0, 0x08, 0x01c6}, /* sharpness+ */ |
3958 | |||
3959 | {0xa1, 0x01, 0x01c8}, | 3988 | {0xa1, 0x01, 0x01c8}, |
3960 | |||
3961 | {0xa1, 0x01, 0x01c9}, | 3989 | {0xa1, 0x01, 0x01c9}, |
3962 | |||
3963 | {0xa1, 0x01, 0x01ca}, | 3990 | {0xa1, 0x01, 0x01ca}, |
3964 | {0xa0, 0x0f, 0x01cb}, | 3991 | {0xa0, 0x0f, 0x01cb}, /* sharpness- */ |
3965 | {0xa0, 0x16, 0x0120}, /* gamma ~4 */ | 3992 | {0xa0, 0x16, 0x0120}, /* gamma ~4 */ |
3966 | {0xa0, 0x3a, 0x0121}, | 3993 | {0xa0, 0x3a, 0x0121}, |
3967 | {0xa0, 0x5b, 0x0122}, | 3994 | {0xa0, 0x5b, 0x0122}, |
@@ -4027,7 +4054,7 @@ static struct usb_action ov7630c_InitialScale[] = { | |||
4027 | 4054 | ||
4028 | {0xa1, 0x01, 0x0180}, | 4055 | {0xa1, 0x01, 0x0180}, |
4029 | {0xa0, 0x42, 0x0180}, | 4056 | {0xa0, 0x42, 0x0180}, |
4030 | {0, 0, 0} | 4057 | {} |
4031 | }; | 4058 | }; |
4032 | 4059 | ||
4033 | static struct usb_action pas106b_Initial_com[] = { | 4060 | static struct usb_action pas106b_Initial_com[] = { |
@@ -4041,7 +4068,7 @@ static struct usb_action pas106b_Initial_com[] = { | |||
4041 | {0xa0, 0x03, 0x003a}, | 4068 | {0xa0, 0x03, 0x003a}, |
4042 | {0xa0, 0x0c, 0x003b}, | 4069 | {0xa0, 0x0c, 0x003b}, |
4043 | {0xa0, 0x04, 0x0038}, | 4070 | {0xa0, 0x04, 0x0038}, |
4044 | {0, 0, 0} | 4071 | {} |
4045 | }; | 4072 | }; |
4046 | 4073 | ||
4047 | static struct usb_action pas106b_Initial[] = { /* 176x144 */ | 4074 | static struct usb_action pas106b_Initial[] = { /* 176x144 */ |
@@ -4099,10 +4126,8 @@ static struct usb_action pas106b_Initial[] = { /* 176x144 */ | |||
4099 | {0xa0, 0x08, 0x0301}, /* EEPROMAccess */ | 4126 | {0xa0, 0x08, 0x0301}, /* EEPROMAccess */ |
4100 | /* JPEG control */ | 4127 | /* JPEG control */ |
4101 | {0xa0, 0x03, 0x0008}, /* ClockSetting */ | 4128 | {0xa0, 0x03, 0x0008}, /* ClockSetting */ |
4102 | /* Unknown */ | 4129 | {0xa0, 0x08, 0x01c6}, /* sharpness+ */ |
4103 | {0xa0, 0x08, 0x01c6}, | 4130 | {0xa0, 0x0f, 0x01cb}, /* sharpness- */ |
4104 | /* Sharpness */ | ||
4105 | {0xa0, 0x0f, 0x01cb}, /* Sharpness05 */ | ||
4106 | /* Other registers */ | 4131 | /* Other registers */ |
4107 | {0xa0, 0x0d, 0x0100}, /* OperationMode */ | 4132 | {0xa0, 0x0d, 0x0100}, /* OperationMode */ |
4108 | /* Auto exposure and white balance */ | 4133 | /* Auto exposure and white balance */ |
@@ -4113,9 +4138,8 @@ static struct usb_action pas106b_Initial[] = { /* 176x144 */ | |||
4113 | {0xa0, 0x08, 0x0301}, /* EEPROMAccess */ | 4138 | {0xa0, 0x08, 0x0301}, /* EEPROMAccess */ |
4114 | /* JPEG control */ | 4139 | /* JPEG control */ |
4115 | {0xa0, 0x03, 0x0008}, /* ClockSetting */ | 4140 | {0xa0, 0x03, 0x0008}, /* ClockSetting */ |
4116 | /* Sharpness */ | 4141 | {0xa0, 0x08, 0x01c6}, /* sharpness+ */ |
4117 | {0xa0, 0x08, 0x01c6}, /* Sharpness00 */ | 4142 | {0xa0, 0x0f, 0x01cb}, /* sharpness- */ |
4118 | {0xa0, 0x0f, 0x01cb}, /* Sharpness05 */ | ||
4119 | 4143 | ||
4120 | {0xa0, 0x58, 0x010a}, /* matrix */ | 4144 | {0xa0, 0x58, 0x010a}, /* matrix */ |
4121 | {0xa0, 0xf4, 0x010b}, | 4145 | {0xa0, 0xf4, 0x010b}, |
@@ -4162,7 +4186,7 @@ static struct usb_action pas106b_Initial[] = { /* 176x144 */ | |||
4162 | {0xa0, 0x40, 0x0116}, /* RGain */ | 4186 | {0xa0, 0x40, 0x0116}, /* RGain */ |
4163 | {0xa0, 0x40, 0x0117}, /* GGain */ | 4187 | {0xa0, 0x40, 0x0117}, /* GGain */ |
4164 | {0xa0, 0x40, 0x0118}, /* BGain */ | 4188 | {0xa0, 0x40, 0x0118}, /* BGain */ |
4165 | {0, 0, 0} | 4189 | {} |
4166 | }; | 4190 | }; |
4167 | 4191 | ||
4168 | static struct usb_action pas106b_InitialScale[] = { /* 352x288 */ | 4192 | static struct usb_action pas106b_InitialScale[] = { /* 352x288 */ |
@@ -4221,10 +4245,8 @@ static struct usb_action pas106b_InitialScale[] = { /* 352x288 */ | |||
4221 | {0xa0, 0x08, 0x0301}, /* EEPROMAccess */ | 4245 | {0xa0, 0x08, 0x0301}, /* EEPROMAccess */ |
4222 | /* JPEG control */ | 4246 | /* JPEG control */ |
4223 | {0xa0, 0x03, 0x0008}, /* ClockSetting */ | 4247 | {0xa0, 0x03, 0x0008}, /* ClockSetting */ |
4224 | /* Unknown */ | 4248 | {0xa0, 0x08, 0x01c6}, /* sharpness+ */ |
4225 | {0xa0, 0x08, 0x01c6}, | 4249 | {0xa0, 0x0f, 0x01cb}, /* sharpness- */ |
4226 | /* Sharpness */ | ||
4227 | {0xa0, 0x0f, 0x01cb}, /* Sharpness05 */ | ||
4228 | /* Other registers */ | 4250 | /* Other registers */ |
4229 | {0xa0, 0x0d, 0x0100}, /* OperationMode */ | 4251 | {0xa0, 0x0d, 0x0100}, /* OperationMode */ |
4230 | /* Auto exposure and white balance */ | 4252 | /* Auto exposure and white balance */ |
@@ -4235,9 +4257,8 @@ static struct usb_action pas106b_InitialScale[] = { /* 352x288 */ | |||
4235 | {0xa0, 0x08, 0x0301}, /* EEPROMAccess */ | 4257 | {0xa0, 0x08, 0x0301}, /* EEPROMAccess */ |
4236 | /* JPEG control */ | 4258 | /* JPEG control */ |
4237 | {0xa0, 0x03, 0x0008}, /* ClockSetting */ | 4259 | {0xa0, 0x03, 0x0008}, /* ClockSetting */ |
4238 | /* Sharpness */ | 4260 | {0xa0, 0x08, 0x01c6}, /* sharpness+ */ |
4239 | {0xa0, 0x08, 0x01c6}, /* Sharpness00 */ | 4261 | {0xa0, 0x0f, 0x01cb}, /* sharpness- */ |
4240 | {0xa0, 0x0f, 0x01cb}, /* Sharpness05 */ | ||
4241 | 4262 | ||
4242 | {0xa0, 0x58, 0x010a}, /* matrix */ | 4263 | {0xa0, 0x58, 0x010a}, /* matrix */ |
4243 | {0xa0, 0xf4, 0x010b}, | 4264 | {0xa0, 0xf4, 0x010b}, |
@@ -4289,7 +4310,7 @@ static struct usb_action pas106b_InitialScale[] = { /* 352x288 */ | |||
4289 | 4310 | ||
4290 | {0xa0, 0x00, 0x0007}, /* AutoCorrectEnable */ | 4311 | {0xa0, 0x00, 0x0007}, /* AutoCorrectEnable */ |
4291 | {0xa0, 0xff, 0x0018}, /* Frame adjust */ | 4312 | {0xa0, 0xff, 0x0018}, /* Frame adjust */ |
4292 | {0, 0, 0} | 4313 | {} |
4293 | }; | 4314 | }; |
4294 | static struct usb_action pas106b_50HZ[] = { | 4315 | static struct usb_action pas106b_50HZ[] = { |
4295 | {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ | 4316 | {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ |
@@ -4305,7 +4326,7 @@ static struct usb_action pas106b_50HZ[] = { | |||
4305 | {0xaa, 0x05, 0x0002}, /* 00,05,02,aa */ | 4326 | {0xaa, 0x05, 0x0002}, /* 00,05,02,aa */ |
4306 | {0xaa, 0x07, 0x001c}, /* 00,07,1c,aa */ | 4327 | {0xaa, 0x07, 0x001c}, /* 00,07,1c,aa */ |
4307 | {0xa0, 0x04, 0x01a9}, /* 01,a9,04,cc */ | 4328 | {0xa0, 0x04, 0x01a9}, /* 01,a9,04,cc */ |
4308 | {0, 0, 0} | 4329 | {} |
4309 | }; | 4330 | }; |
4310 | static struct usb_action pas106b_60HZ[] = { | 4331 | static struct usb_action pas106b_60HZ[] = { |
4311 | {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ | 4332 | {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ |
@@ -4321,7 +4342,7 @@ static struct usb_action pas106b_60HZ[] = { | |||
4321 | {0xaa, 0x05, 0x0001}, /* 00,05,01,aa */ | 4342 | {0xaa, 0x05, 0x0001}, /* 00,05,01,aa */ |
4322 | {0xaa, 0x07, 0x00c4}, /* 00,07,c4,aa */ | 4343 | {0xaa, 0x07, 0x00c4}, /* 00,07,c4,aa */ |
4323 | {0xa0, 0x04, 0x01a9}, /* 01,a9,04,cc */ | 4344 | {0xa0, 0x04, 0x01a9}, /* 01,a9,04,cc */ |
4324 | {0, 0, 0} | 4345 | {} |
4325 | }; | 4346 | }; |
4326 | static struct usb_action pas106b_NoFliker[] = { | 4347 | static struct usb_action pas106b_NoFliker[] = { |
4327 | {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ | 4348 | {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ |
@@ -4337,10 +4358,9 @@ static struct usb_action pas106b_NoFliker[] = { | |||
4337 | {0xaa, 0x05, 0x0001}, /* 00,05,01,aa */ | 4358 | {0xaa, 0x05, 0x0001}, /* 00,05,01,aa */ |
4338 | {0xaa, 0x07, 0x0030}, /* 00,07,30,aa */ | 4359 | {0xaa, 0x07, 0x0030}, /* 00,07,30,aa */ |
4339 | {0xa0, 0x00, 0x01a9}, /* 01,a9,00,cc */ | 4360 | {0xa0, 0x00, 0x01a9}, /* 01,a9,00,cc */ |
4340 | {0, 0, 0} | 4361 | {} |
4341 | }; | 4362 | }; |
4342 | 4363 | ||
4343 | /* Aurelien setting from snoop */ | ||
4344 | static struct usb_action pb03303x_Initial[] = { | 4364 | static struct usb_action pb03303x_Initial[] = { |
4345 | {0xa0, 0x01, 0x0000}, | 4365 | {0xa0, 0x01, 0x0000}, |
4346 | {0xa0, 0x03, 0x0008}, | 4366 | {0xa0, 0x03, 0x0008}, |
@@ -4411,11 +4431,11 @@ static struct usb_action pb03303x_Initial[] = { | |||
4411 | 4431 | ||
4412 | {0xa1, 0x01, 0x0008}, | 4432 | {0xa1, 0x01, 0x0008}, |
4413 | {0xa0, 0x03, 0x0008}, /* clock ? */ | 4433 | {0xa0, 0x03, 0x0008}, /* clock ? */ |
4414 | {0xa0, 0x08, 0x01c6}, | 4434 | {0xa0, 0x08, 0x01c6}, /* sharpness+ */ |
4415 | {0xa1, 0x01, 0x01c8}, | 4435 | {0xa1, 0x01, 0x01c8}, |
4416 | {0xa1, 0x01, 0x01c9}, | 4436 | {0xa1, 0x01, 0x01c9}, |
4417 | {0xa1, 0x01, 0x01ca}, | 4437 | {0xa1, 0x01, 0x01ca}, |
4418 | {0xa0, 0x0f, 0x01cb}, | 4438 | {0xa0, 0x0f, 0x01cb}, /* sharpness- */ |
4419 | {0xa0, 0x13, 0x0120}, /* gamma 4 */ | 4439 | {0xa0, 0x13, 0x0120}, /* gamma 4 */ |
4420 | {0xa0, 0x38, 0x0121}, | 4440 | {0xa0, 0x38, 0x0121}, |
4421 | {0xa0, 0x59, 0x0122}, | 4441 | {0xa0, 0x59, 0x0122}, |
@@ -4484,7 +4504,7 @@ static struct usb_action pb03303x_Initial[] = { | |||
4484 | {0xa0, 0x40, 0x0180}, | 4504 | {0xa0, 0x40, 0x0180}, |
4485 | {0xa1, 0x01, 0x0180}, | 4505 | {0xa1, 0x01, 0x0180}, |
4486 | {0xa0, 0x42, 0x0180}, | 4506 | {0xa0, 0x42, 0x0180}, |
4487 | {0, 0, 0} | 4507 | {} |
4488 | }; | 4508 | }; |
4489 | 4509 | ||
4490 | static struct usb_action pb03303x_InitialScale[] = { | 4510 | static struct usb_action pb03303x_InitialScale[] = { |
@@ -4559,11 +4579,11 @@ static struct usb_action pb03303x_InitialScale[] = { | |||
4559 | 4579 | ||
4560 | {0xa1, 0x01, 0x0008}, | 4580 | {0xa1, 0x01, 0x0008}, |
4561 | {0xa0, 0x03, 0x0008}, /* clock ? */ | 4581 | {0xa0, 0x03, 0x0008}, /* clock ? */ |
4562 | {0xa0, 0x08, 0x01c6}, | 4582 | {0xa0, 0x08, 0x01c6}, /* sharpness+ */ |
4563 | {0xa1, 0x01, 0x01c8}, | 4583 | {0xa1, 0x01, 0x01c8}, |
4564 | {0xa1, 0x01, 0x01c9}, | 4584 | {0xa1, 0x01, 0x01c9}, |
4565 | {0xa1, 0x01, 0x01ca}, | 4585 | {0xa1, 0x01, 0x01ca}, |
4566 | {0xa0, 0x0f, 0x01cb}, | 4586 | {0xa0, 0x0f, 0x01cb}, /* sharpness- */ |
4567 | 4587 | ||
4568 | {0xa0, 0x13, 0x0120}, /* gamma 4 */ | 4588 | {0xa0, 0x13, 0x0120}, /* gamma 4 */ |
4569 | {0xa0, 0x38, 0x0121}, | 4589 | {0xa0, 0x38, 0x0121}, |
@@ -4633,7 +4653,7 @@ static struct usb_action pb03303x_InitialScale[] = { | |||
4633 | {0xa0, 0x40, 0x0180}, | 4653 | {0xa0, 0x40, 0x0180}, |
4634 | {0xa1, 0x01, 0x0180}, | 4654 | {0xa1, 0x01, 0x0180}, |
4635 | {0xa0, 0x42, 0x0180}, | 4655 | {0xa0, 0x42, 0x0180}, |
4636 | {0, 0, 0} | 4656 | {} |
4637 | }; | 4657 | }; |
4638 | static struct usb_action pb0330xx_Initial[] = { | 4658 | static struct usb_action pb0330xx_Initial[] = { |
4639 | {0xa1, 0x01, 0x0008}, | 4659 | {0xa1, 0x01, 0x0008}, |
@@ -4701,11 +4721,11 @@ static struct usb_action pb0330xx_Initial[] = { | |||
4701 | {0xa0, 0x50, 0x0112}, | 4721 | {0xa0, 0x50, 0x0112}, |
4702 | {0xa1, 0x01, 0x0008}, | 4722 | {0xa1, 0x01, 0x0008}, |
4703 | {0xa0, 0x03, 0x0008}, /* clock ? */ | 4723 | {0xa0, 0x03, 0x0008}, /* clock ? */ |
4704 | {0xa0, 0x08, 0x01c6}, | 4724 | {0xa0, 0x08, 0x01c6}, /* sharpness+ */ |
4705 | {0xa1, 0x01, 0x01c8}, | 4725 | {0xa1, 0x01, 0x01c8}, |
4706 | {0xa1, 0x01, 0x01c9}, | 4726 | {0xa1, 0x01, 0x01c9}, |
4707 | {0xa1, 0x01, 0x01ca}, | 4727 | {0xa1, 0x01, 0x01ca}, |
4708 | {0xa0, 0x0f, 0x01cb}, | 4728 | {0xa0, 0x0f, 0x01cb}, /* sharpness- */ |
4709 | 4729 | ||
4710 | {0xa0, 0x50, 0x010a}, /* matrix */ | 4730 | {0xa0, 0x50, 0x010a}, /* matrix */ |
4711 | {0xa0, 0xf8, 0x010b}, | 4731 | {0xa0, 0xf8, 0x010b}, |
@@ -4747,7 +4767,7 @@ static struct usb_action pb0330xx_Initial[] = { | |||
4747 | {0xa1, 0x01, 0x0007}, | 4767 | {0xa1, 0x01, 0x0007}, |
4748 | /* {0xa0, 0x30, 0x0007}, */ | 4768 | /* {0xa0, 0x30, 0x0007}, */ |
4749 | /* {0xa0, 0x00, 0x0007}, */ | 4769 | /* {0xa0, 0x00, 0x0007}, */ |
4750 | {0, 0, 0} | 4770 | {} |
4751 | }; | 4771 | }; |
4752 | 4772 | ||
4753 | static struct usb_action pb0330xx_InitialScale[] = { | 4773 | static struct usb_action pb0330xx_InitialScale[] = { |
@@ -4816,11 +4836,11 @@ static struct usb_action pb0330xx_InitialScale[] = { | |||
4816 | {0xa0, 0x50, 0x0112}, | 4836 | {0xa0, 0x50, 0x0112}, |
4817 | {0xa1, 0x01, 0x0008}, | 4837 | {0xa1, 0x01, 0x0008}, |
4818 | {0xa0, 0x03, 0x0008}, /* clock ? */ | 4838 | {0xa0, 0x03, 0x0008}, /* clock ? */ |
4819 | {0xa0, 0x08, 0x01c6}, | 4839 | {0xa0, 0x08, 0x01c6}, /* sharpness+ */ |
4820 | {0xa1, 0x01, 0x01c8}, | 4840 | {0xa1, 0x01, 0x01c8}, |
4821 | {0xa1, 0x01, 0x01c9}, | 4841 | {0xa1, 0x01, 0x01c9}, |
4822 | {0xa1, 0x01, 0x01ca}, | 4842 | {0xa1, 0x01, 0x01ca}, |
4823 | {0xa0, 0x0f, 0x01cb}, | 4843 | {0xa0, 0x0f, 0x01cb}, /* sharpness- */ |
4824 | 4844 | ||
4825 | {0xa0, 0x50, 0x010a}, /* matrix */ | 4845 | {0xa0, 0x50, 0x010a}, /* matrix */ |
4826 | {0xa0, 0xf8, 0x010b}, | 4846 | {0xa0, 0xf8, 0x010b}, |
@@ -4861,7 +4881,7 @@ static struct usb_action pb0330xx_InitialScale[] = { | |||
4861 | {0xa1, 0x01, 0x0007}, | 4881 | {0xa1, 0x01, 0x0007}, |
4862 | /* {0xa0, 0x30, 0x0007}, */ | 4882 | /* {0xa0, 0x30, 0x0007}, */ |
4863 | /* {0xa0, 0x00, 0x0007}, */ | 4883 | /* {0xa0, 0x00, 0x0007}, */ |
4864 | {0, 0, 0} | 4884 | {} |
4865 | }; | 4885 | }; |
4866 | static struct usb_action pb0330_50HZ[] = { | 4886 | static struct usb_action pb0330_50HZ[] = { |
4867 | {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ | 4887 | {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ |
@@ -4877,7 +4897,7 @@ static struct usb_action pb0330_50HZ[] = { | |||
4877 | {0xa0, 0x68, 0x001d}, /* 00,1d,68,cc */ | 4897 | {0xa0, 0x68, 0x001d}, /* 00,1d,68,cc */ |
4878 | {0xa0, 0x90, 0x001e}, /* 00,1e,90,cc */ | 4898 | {0xa0, 0x90, 0x001e}, /* 00,1e,90,cc */ |
4879 | {0xa0, 0xc8, 0x001f}, /* 00,1f,c8,cc */ | 4899 | {0xa0, 0xc8, 0x001f}, /* 00,1f,c8,cc */ |
4880 | {0, 0, 0} | 4900 | {} |
4881 | }; | 4901 | }; |
4882 | static struct usb_action pb0330_50HZScale[] = { | 4902 | static struct usb_action pb0330_50HZScale[] = { |
4883 | {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ | 4903 | {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ |
@@ -4894,7 +4914,7 @@ static struct usb_action pb0330_50HZScale[] = { | |||
4894 | {0xa0, 0xe5, 0x001d}, /* 00,1d,e5,cc */ | 4914 | {0xa0, 0xe5, 0x001d}, /* 00,1d,e5,cc */ |
4895 | {0xa0, 0xf0, 0x001e}, /* 00,1e,f0,cc */ | 4915 | {0xa0, 0xf0, 0x001e}, /* 00,1e,f0,cc */ |
4896 | {0xa0, 0xf8, 0x001f}, /* 00,1f,f8,cc */ | 4916 | {0xa0, 0xf8, 0x001f}, /* 00,1f,f8,cc */ |
4897 | {0, 0, 0} | 4917 | {} |
4898 | }; | 4918 | }; |
4899 | static struct usb_action pb0330_60HZ[] = { | 4919 | static struct usb_action pb0330_60HZ[] = { |
4900 | {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ | 4920 | {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ |
@@ -4911,7 +4931,7 @@ static struct usb_action pb0330_60HZ[] = { | |||
4911 | {0xa0, 0x43, 0x001d}, /* 00,1d,43,cc */ | 4931 | {0xa0, 0x43, 0x001d}, /* 00,1d,43,cc */ |
4912 | {0xa0, 0x50, 0x001e}, /* 00,1e,50,cc */ | 4932 | {0xa0, 0x50, 0x001e}, /* 00,1e,50,cc */ |
4913 | {0xa0, 0x90, 0x001f}, /* 00,1f,90,cc */ | 4933 | {0xa0, 0x90, 0x001f}, /* 00,1f,90,cc */ |
4914 | {0, 0, 0} | 4934 | {} |
4915 | }; | 4935 | }; |
4916 | static struct usb_action pb0330_60HZScale[] = { | 4936 | static struct usb_action pb0330_60HZScale[] = { |
4917 | {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ | 4937 | {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ |
@@ -4928,7 +4948,7 @@ static struct usb_action pb0330_60HZScale[] = { | |||
4928 | {0xa0, 0x41, 0x001d}, /* 00,1d,41,cc */ | 4948 | {0xa0, 0x41, 0x001d}, /* 00,1d,41,cc */ |
4929 | {0xa0, 0x50, 0x001e}, /* 00,1e,50,cc */ | 4949 | {0xa0, 0x50, 0x001e}, /* 00,1e,50,cc */ |
4930 | {0xa0, 0x90, 0x001f}, /* 00,1f,90,cc */ | 4950 | {0xa0, 0x90, 0x001f}, /* 00,1f,90,cc */ |
4931 | {0, 0, 0} | 4951 | {} |
4932 | }; | 4952 | }; |
4933 | static struct usb_action pb0330_NoFliker[] = { | 4953 | static struct usb_action pb0330_NoFliker[] = { |
4934 | {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ | 4954 | {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ |
@@ -4945,7 +4965,7 @@ static struct usb_action pb0330_NoFliker[] = { | |||
4945 | {0xa0, 0x09, 0x001d}, /* 00,1d,09,cc */ | 4965 | {0xa0, 0x09, 0x001d}, /* 00,1d,09,cc */ |
4946 | {0xa0, 0x40, 0x001e}, /* 00,1e,40,cc */ | 4966 | {0xa0, 0x40, 0x001e}, /* 00,1e,40,cc */ |
4947 | {0xa0, 0x90, 0x001f}, /* 00,1f,90,cc */ | 4967 | {0xa0, 0x90, 0x001f}, /* 00,1f,90,cc */ |
4948 | {0, 0, 0} | 4968 | {} |
4949 | }; | 4969 | }; |
4950 | static struct usb_action pb0330_NoFlikerScale[] = { | 4970 | static struct usb_action pb0330_NoFlikerScale[] = { |
4951 | {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ | 4971 | {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ |
@@ -4962,7 +4982,7 @@ static struct usb_action pb0330_NoFlikerScale[] = { | |||
4962 | {0xa0, 0x09, 0x001d}, /* 00,1d,09,cc */ | 4982 | {0xa0, 0x09, 0x001d}, /* 00,1d,09,cc */ |
4963 | {0xa0, 0x40, 0x001e}, /* 00,1e,40,cc */ | 4983 | {0xa0, 0x40, 0x001e}, /* 00,1e,40,cc */ |
4964 | {0xa0, 0x90, 0x001f}, /* 00,1f,90,cc */ | 4984 | {0xa0, 0x90, 0x001f}, /* 00,1f,90,cc */ |
4965 | {0, 0, 0} | 4985 | {} |
4966 | }; | 4986 | }; |
4967 | 4987 | ||
4968 | /* from oem9.inf - HKR,%PO2030%,Initial - 640x480 - (close to CS2102) */ | 4988 | /* from oem9.inf - HKR,%PO2030%,Initial - 640x480 - (close to CS2102) */ |
@@ -5039,7 +5059,7 @@ static struct usb_action PO2030_mode0[] = { | |||
5039 | {0xa0, 0x08, 0x0301}, /* 03,01,08,cc */ | 5059 | {0xa0, 0x08, 0x0301}, /* 03,01,08,cc */ |
5040 | {0xa0, 0x7a, 0x0116}, /* 01,16,7a,cc */ | 5060 | {0xa0, 0x7a, 0x0116}, /* 01,16,7a,cc */ |
5041 | {0xa0, 0x4a, 0x0118}, /* 01,18,4a,cc */ | 5061 | {0xa0, 0x4a, 0x0118}, /* 01,18,4a,cc */ |
5042 | {0, 0, 0} | 5062 | {} |
5043 | }; | 5063 | }; |
5044 | 5064 | ||
5045 | /* from oem9.inf - HKR,%PO2030%,InitialScale - 320x240 */ | 5065 | /* from oem9.inf - HKR,%PO2030%,InitialScale - 320x240 */ |
@@ -5116,7 +5136,7 @@ static struct usb_action PO2030_mode1[] = { | |||
5116 | {0xa0, 0x08, 0x0301}, /* 03,01,08,cc */ | 5136 | {0xa0, 0x08, 0x0301}, /* 03,01,08,cc */ |
5117 | {0xa0, 0x7a, 0x0116}, /* 01,16,7a,cc */ | 5137 | {0xa0, 0x7a, 0x0116}, /* 01,16,7a,cc */ |
5118 | {0xa0, 0x4a, 0x0118}, /* 01,18,4a,cc */ | 5138 | {0xa0, 0x4a, 0x0118}, /* 01,18,4a,cc */ |
5119 | {0, 0, 0} | 5139 | {} |
5120 | }; | 5140 | }; |
5121 | 5141 | ||
5122 | static struct usb_action PO2030_50HZ[] = { | 5142 | static struct usb_action PO2030_50HZ[] = { |
@@ -5138,7 +5158,7 @@ static struct usb_action PO2030_50HZ[] = { | |||
5138 | {0xa0, 0x88, 0x018d}, /* 01,8d,88,cc */ | 5158 | {0xa0, 0x88, 0x018d}, /* 01,8d,88,cc */ |
5139 | {0xa0, 0x58, 0x011d}, /* 01,1d,58,cc */ | 5159 | {0xa0, 0x58, 0x011d}, /* 01,1d,58,cc */ |
5140 | {0xa0, 0x42, 0x0180}, /* 01,80,42,cc */ | 5160 | {0xa0, 0x42, 0x0180}, /* 01,80,42,cc */ |
5141 | {0, 0, 0} | 5161 | {} |
5142 | }; | 5162 | }; |
5143 | 5163 | ||
5144 | static struct usb_action PO2030_60HZ[] = { | 5164 | static struct usb_action PO2030_60HZ[] = { |
@@ -5160,7 +5180,7 @@ static struct usb_action PO2030_60HZ[] = { | |||
5160 | {0xa0, 0x88, 0x018d}, /* 01,8d,88,cc */ /* win: 01,8d,80 */ | 5180 | {0xa0, 0x88, 0x018d}, /* 01,8d,88,cc */ /* win: 01,8d,80 */ |
5161 | {0xa0, 0x58, 0x011d}, /* 01,1d,58,cc */ | 5181 | {0xa0, 0x58, 0x011d}, /* 01,1d,58,cc */ |
5162 | {0xa0, 0x42, 0x0180}, /* 01,80,42,cc */ | 5182 | {0xa0, 0x42, 0x0180}, /* 01,80,42,cc */ |
5163 | {0, 0, 0} | 5183 | {} |
5164 | }; | 5184 | }; |
5165 | 5185 | ||
5166 | static struct usb_action PO2030_NoFliker[] = { | 5186 | static struct usb_action PO2030_NoFliker[] = { |
@@ -5171,7 +5191,7 @@ static struct usb_action PO2030_NoFliker[] = { | |||
5171 | {0xaa, 0x1c, 0x0078}, /* 00,1c,78,aa */ | 5191 | {0xaa, 0x1c, 0x0078}, /* 00,1c,78,aa */ |
5172 | {0xaa, 0x46, 0x0000}, /* 00,46,00,aa */ | 5192 | {0xaa, 0x46, 0x0000}, /* 00,46,00,aa */ |
5173 | {0xaa, 0x15, 0x0000}, /* 00,15,00,aa */ | 5193 | {0xaa, 0x15, 0x0000}, /* 00,15,00,aa */ |
5174 | {0, 0, 0} | 5194 | {} |
5175 | }; | 5195 | }; |
5176 | 5196 | ||
5177 | /* TEST */ | 5197 | /* TEST */ |
@@ -5302,8 +5322,8 @@ static struct usb_action tas5130CK_Initial[] = { | |||
5302 | {0xa0, 0x03, 0x0111}, | 5322 | {0xa0, 0x03, 0x0111}, |
5303 | {0xa0, 0x51, 0x0112}, | 5323 | {0xa0, 0x51, 0x0112}, |
5304 | {0xa0, 0x03, 0x0008}, | 5324 | {0xa0, 0x03, 0x0008}, |
5305 | {0xa0, 0x08, 0x01c6}, | 5325 | {0xa0, 0x08, 0x01c6}, /* sharpness+ */ |
5306 | {0xa0, 0x0f, 0x01cb}, | 5326 | {0xa0, 0x0f, 0x01cb}, /* sharpness- */ |
5307 | {0xa0, 0x38, 0x0120}, /* gamma > 5 */ | 5327 | {0xa0, 0x38, 0x0120}, /* gamma > 5 */ |
5308 | {0xa0, 0x51, 0x0121}, | 5328 | {0xa0, 0x51, 0x0121}, |
5309 | {0xa0, 0x6e, 0x0122}, | 5329 | {0xa0, 0x6e, 0x0122}, |
@@ -5375,7 +5395,7 @@ static struct usb_action tas5130CK_Initial[] = { | |||
5375 | {0xa0, 0x15, 0x01ae}, | 5395 | {0xa0, 0x15, 0x01ae}, |
5376 | {0xa0, 0x40, 0x0180}, | 5396 | {0xa0, 0x40, 0x0180}, |
5377 | {0xa0, 0x42, 0x0180}, | 5397 | {0xa0, 0x42, 0x0180}, |
5378 | {0, 0, 0} | 5398 | {} |
5379 | }; | 5399 | }; |
5380 | 5400 | ||
5381 | static struct usb_action tas5130CK_InitialScale[] = { | 5401 | static struct usb_action tas5130CK_InitialScale[] = { |
@@ -5505,8 +5525,8 @@ static struct usb_action tas5130CK_InitialScale[] = { | |||
5505 | {0xa0, 0x03, 0x0111}, | 5525 | {0xa0, 0x03, 0x0111}, |
5506 | {0xa0, 0x51, 0x0112}, | 5526 | {0xa0, 0x51, 0x0112}, |
5507 | {0xa0, 0x03, 0x0008}, | 5527 | {0xa0, 0x03, 0x0008}, |
5508 | {0xa0, 0x08, 0x01c6}, | 5528 | {0xa0, 0x08, 0x01c6}, /* sharpness+ */ |
5509 | {0xa0, 0x0f, 0x01cb}, | 5529 | {0xa0, 0x0f, 0x01cb}, /* sharpness- */ |
5510 | {0xa0, 0x38, 0x0120}, /* gamma > 5 */ | 5530 | {0xa0, 0x38, 0x0120}, /* gamma > 5 */ |
5511 | {0xa0, 0x51, 0x0121}, | 5531 | {0xa0, 0x51, 0x0121}, |
5512 | {0xa0, 0x6e, 0x0122}, | 5532 | {0xa0, 0x6e, 0x0122}, |
@@ -5583,7 +5603,7 @@ static struct usb_action tas5130CK_InitialScale[] = { | |||
5583 | {0xa0, 0x02, 0x0008}, | 5603 | {0xa0, 0x02, 0x0008}, |
5584 | {0xa0, 0x00, 0x0007}, | 5604 | {0xa0, 0x00, 0x0007}, |
5585 | {0xa0, 0x03, 0x0008}, | 5605 | {0xa0, 0x03, 0x0008}, |
5586 | {0, 0, 0} | 5606 | {} |
5587 | }; | 5607 | }; |
5588 | 5608 | ||
5589 | static struct usb_action tas5130cxx_Initial[] = { | 5609 | static struct usb_action tas5130cxx_Initial[] = { |
@@ -5625,11 +5645,11 @@ static struct usb_action tas5130cxx_Initial[] = { | |||
5625 | {0xa1, 0x01, 0x0002}, | 5645 | {0xa1, 0x01, 0x0002}, |
5626 | {0xa1, 0x01, 0x0008}, | 5646 | {0xa1, 0x01, 0x0008}, |
5627 | {0xa0, 0x03, 0x0008}, /* clock ? */ | 5647 | {0xa0, 0x03, 0x0008}, /* clock ? */ |
5628 | {0xa0, 0x08, 0x01c6}, | 5648 | {0xa0, 0x08, 0x01c6}, /* sharpness+ */ |
5629 | {0xa1, 0x01, 0x01c8}, | 5649 | {0xa1, 0x01, 0x01c8}, |
5630 | {0xa1, 0x01, 0x01c9}, | 5650 | {0xa1, 0x01, 0x01c9}, |
5631 | {0xa1, 0x01, 0x01ca}, | 5651 | {0xa1, 0x01, 0x01ca}, |
5632 | {0xa0, 0x0f, 0x01cb}, | 5652 | {0xa0, 0x0f, 0x01cb}, /* sharpness- */ |
5633 | 5653 | ||
5634 | {0xa0, 0x68, 0x010a}, /* matrix */ | 5654 | {0xa0, 0x68, 0x010a}, /* matrix */ |
5635 | {0xa0, 0xec, 0x010b}, | 5655 | {0xa0, 0xec, 0x010b}, |
@@ -5673,7 +5693,7 @@ static struct usb_action tas5130cxx_Initial[] = { | |||
5673 | {0xa0, 0x40, 0x0180}, | 5693 | {0xa0, 0x40, 0x0180}, |
5674 | {0xa1, 0x01, 0x0180}, | 5694 | {0xa1, 0x01, 0x0180}, |
5675 | {0xa0, 0x42, 0x0180}, | 5695 | {0xa0, 0x42, 0x0180}, |
5676 | {0, 0, 0} | 5696 | {} |
5677 | }; | 5697 | }; |
5678 | static struct usb_action tas5130cxx_InitialScale[] = { | 5698 | static struct usb_action tas5130cxx_InitialScale[] = { |
5679 | {0xa0, 0x01, 0x0000}, | 5699 | {0xa0, 0x01, 0x0000}, |
@@ -5718,11 +5738,11 @@ static struct usb_action tas5130cxx_InitialScale[] = { | |||
5718 | 5738 | ||
5719 | {0xa0, 0x03, 0x0008}, | 5739 | {0xa0, 0x03, 0x0008}, |
5720 | {0xa1, 0x01, 0x0008}, /* clock ? */ | 5740 | {0xa1, 0x01, 0x0008}, /* clock ? */ |
5721 | {0xa0, 0x08, 0x01c6}, | 5741 | {0xa0, 0x08, 0x01c6}, /* sharpness+ */ |
5722 | {0xa1, 0x01, 0x01c8}, | 5742 | {0xa1, 0x01, 0x01c8}, |
5723 | {0xa1, 0x01, 0x01c9}, | 5743 | {0xa1, 0x01, 0x01c9}, |
5724 | {0xa1, 0x01, 0x01ca}, | 5744 | {0xa1, 0x01, 0x01ca}, |
5725 | {0xa0, 0x0f, 0x01cb}, | 5745 | {0xa0, 0x0f, 0x01cb}, /* sharpness- */ |
5726 | 5746 | ||
5727 | {0xa0, 0x68, 0x010a}, /* matrix */ | 5747 | {0xa0, 0x68, 0x010a}, /* matrix */ |
5728 | {0xa0, 0xec, 0x010b}, | 5748 | {0xa0, 0xec, 0x010b}, |
@@ -5763,7 +5783,7 @@ static struct usb_action tas5130cxx_InitialScale[] = { | |||
5763 | {0xa0, 0x40, 0x0180}, | 5783 | {0xa0, 0x40, 0x0180}, |
5764 | {0xa1, 0x01, 0x0180}, | 5784 | {0xa1, 0x01, 0x0180}, |
5765 | {0xa0, 0x42, 0x0180}, | 5785 | {0xa0, 0x42, 0x0180}, |
5766 | {0, 0, 0} | 5786 | {} |
5767 | }; | 5787 | }; |
5768 | static struct usb_action tas5130cxx_50HZ[] = { | 5788 | static struct usb_action tas5130cxx_50HZ[] = { |
5769 | {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ | 5789 | {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ |
@@ -5786,7 +5806,7 @@ static struct usb_action tas5130cxx_50HZ[] = { | |||
5786 | {0xa0, 0xea, 0x001f}, /* 00,1f,ea,cc */ | 5806 | {0xa0, 0xea, 0x001f}, /* 00,1f,ea,cc */ |
5787 | {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ | 5807 | {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ |
5788 | {0xa0, 0x03, 0x009f}, /* 00,9f,03,cc */ | 5808 | {0xa0, 0x03, 0x009f}, /* 00,9f,03,cc */ |
5789 | {0, 0, 0} | 5809 | {} |
5790 | }; | 5810 | }; |
5791 | static struct usb_action tas5130cxx_50HZScale[] = { | 5811 | static struct usb_action tas5130cxx_50HZScale[] = { |
5792 | {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ | 5812 | {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ |
@@ -5809,7 +5829,7 @@ static struct usb_action tas5130cxx_50HZScale[] = { | |||
5809 | {0xa0, 0xf8, 0x001f}, /* 00,1f,f8,cc */ | 5829 | {0xa0, 0xf8, 0x001f}, /* 00,1f,f8,cc */ |
5810 | {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ | 5830 | {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ |
5811 | {0xa0, 0x03, 0x009f}, /* 00,9f,03,cc */ | 5831 | {0xa0, 0x03, 0x009f}, /* 00,9f,03,cc */ |
5812 | {0, 0, 0} | 5832 | {} |
5813 | }; | 5833 | }; |
5814 | static struct usb_action tas5130cxx_60HZ[] = { | 5834 | static struct usb_action tas5130cxx_60HZ[] = { |
5815 | {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ | 5835 | {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ |
@@ -5832,7 +5852,7 @@ static struct usb_action tas5130cxx_60HZ[] = { | |||
5832 | {0xa0, 0xe0, 0x001f}, /* 00,1f,e0,cc */ | 5852 | {0xa0, 0xe0, 0x001f}, /* 00,1f,e0,cc */ |
5833 | {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ | 5853 | {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ |
5834 | {0xa0, 0x03, 0x009f}, /* 00,9f,03,cc */ | 5854 | {0xa0, 0x03, 0x009f}, /* 00,9f,03,cc */ |
5835 | {0, 0, 0} | 5855 | {} |
5836 | }; | 5856 | }; |
5837 | static struct usb_action tas5130cxx_60HZScale[] = { | 5857 | static struct usb_action tas5130cxx_60HZScale[] = { |
5838 | {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ | 5858 | {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ |
@@ -5855,7 +5875,7 @@ static struct usb_action tas5130cxx_60HZScale[] = { | |||
5855 | {0xa0, 0xe0, 0x001f}, /* 00,1f,e0,cc */ | 5875 | {0xa0, 0xe0, 0x001f}, /* 00,1f,e0,cc */ |
5856 | {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ | 5876 | {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ |
5857 | {0xa0, 0x03, 0x009f}, /* 00,9f,03,cc */ | 5877 | {0xa0, 0x03, 0x009f}, /* 00,9f,03,cc */ |
5858 | {0, 0, 0} | 5878 | {} |
5859 | }; | 5879 | }; |
5860 | static struct usb_action tas5130cxx_NoFliker[] = { | 5880 | static struct usb_action tas5130cxx_NoFliker[] = { |
5861 | {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ | 5881 | {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ |
@@ -5878,7 +5898,7 @@ static struct usb_action tas5130cxx_NoFliker[] = { | |||
5878 | {0xa0, 0xe0, 0x001f}, /* 00,1f,e0,cc */ | 5898 | {0xa0, 0xe0, 0x001f}, /* 00,1f,e0,cc */ |
5879 | {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ | 5899 | {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ |
5880 | {0xa0, 0x02, 0x009f}, /* 00,9f,02,cc */ | 5900 | {0xa0, 0x02, 0x009f}, /* 00,9f,02,cc */ |
5881 | {0, 0, 0} | 5901 | {} |
5882 | }; | 5902 | }; |
5883 | 5903 | ||
5884 | static struct usb_action tas5130cxx_NoFlikerScale[] = { | 5904 | static struct usb_action tas5130cxx_NoFlikerScale[] = { |
@@ -5902,7 +5922,7 @@ static struct usb_action tas5130cxx_NoFlikerScale[] = { | |||
5902 | {0xa0, 0xe0, 0x001f}, /* 00,1f,e0,cc */ | 5922 | {0xa0, 0xe0, 0x001f}, /* 00,1f,e0,cc */ |
5903 | {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ | 5923 | {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ |
5904 | {0xa0, 0x02, 0x009f}, /* 00,9f,02,cc */ | 5924 | {0xa0, 0x02, 0x009f}, /* 00,9f,02,cc */ |
5905 | {0, 0, 0} | 5925 | {} |
5906 | }; | 5926 | }; |
5907 | 5927 | ||
5908 | static struct usb_action tas5130c_vf0250_Initial[] = { | 5928 | static struct usb_action tas5130c_vf0250_Initial[] = { |
@@ -5966,7 +5986,7 @@ static struct usb_action tas5130c_vf0250_Initial[] = { | |||
5966 | {0xa0, 0x60, 0x01a8}, /* 01,a8,60,cc, */ | 5986 | {0xa0, 0x60, 0x01a8}, /* 01,a8,60,cc, */ |
5967 | {0xa0, 0x61, 0x0116}, /* 01,16,61,cc, */ | 5987 | {0xa0, 0x61, 0x0116}, /* 01,16,61,cc, */ |
5968 | {0xa0, 0x65, 0x0118}, /* 01,18,65,cc */ | 5988 | {0xa0, 0x65, 0x0118}, /* 01,18,65,cc */ |
5969 | {0, 0, 0} | 5989 | {} |
5970 | }; | 5990 | }; |
5971 | 5991 | ||
5972 | static struct usb_action tas5130c_vf0250_InitialScale[] = { | 5992 | static struct usb_action tas5130c_vf0250_InitialScale[] = { |
@@ -6030,7 +6050,7 @@ static struct usb_action tas5130c_vf0250_InitialScale[] = { | |||
6030 | {0xa0, 0x60, 0x01a8}, /* 01,a8,60,cc, */ | 6050 | {0xa0, 0x60, 0x01a8}, /* 01,a8,60,cc, */ |
6031 | {0xa0, 0x61, 0x0116}, /* 01,16,61,cc, */ | 6051 | {0xa0, 0x61, 0x0116}, /* 01,16,61,cc, */ |
6032 | {0xa0, 0x65, 0x0118}, /* 01,18,65,cc */ | 6052 | {0xa0, 0x65, 0x0118}, /* 01,18,65,cc */ |
6033 | {0, 0, 0} | 6053 | {} |
6034 | }; | 6054 | }; |
6035 | /* "50HZ" light frequency banding filter */ | 6055 | /* "50HZ" light frequency banding filter */ |
6036 | static struct usb_action tas5130c_vf0250_50HZ[] = { | 6056 | static struct usb_action tas5130c_vf0250_50HZ[] = { |
@@ -6054,7 +6074,7 @@ static struct usb_action tas5130c_vf0250_50HZ[] = { | |||
6054 | {0xa0, 0x58, 0x011d}, /* 01,1d,58,cc, */ | 6074 | {0xa0, 0x58, 0x011d}, /* 01,1d,58,cc, */ |
6055 | {0xa0, 0x42, 0x0180}, /* 01,80,42,cc, */ | 6075 | {0xa0, 0x42, 0x0180}, /* 01,80,42,cc, */ |
6056 | {0xa0, 0x78, 0x018d}, /* 01,8d,78,cc */ | 6076 | {0xa0, 0x78, 0x018d}, /* 01,8d,78,cc */ |
6057 | {0, 0, 0} | 6077 | {} |
6058 | }; | 6078 | }; |
6059 | 6079 | ||
6060 | /* "50HZScale" light frequency banding filter */ | 6080 | /* "50HZScale" light frequency banding filter */ |
@@ -6079,7 +6099,7 @@ static struct usb_action tas5130c_vf0250_50HZScale[] = { | |||
6079 | {0xa0, 0x58, 0x011d}, /* 01,1d,58,cc, */ | 6099 | {0xa0, 0x58, 0x011d}, /* 01,1d,58,cc, */ |
6080 | {0xa0, 0x42, 0x0180}, /* 01,80,42,cc, */ | 6100 | {0xa0, 0x42, 0x0180}, /* 01,80,42,cc, */ |
6081 | {0xa0, 0x78, 0x018d}, /* 01,8d,78,cc */ | 6101 | {0xa0, 0x78, 0x018d}, /* 01,8d,78,cc */ |
6082 | {0, 0, 0} | 6102 | {} |
6083 | }; | 6103 | }; |
6084 | 6104 | ||
6085 | /* "60HZ" light frequency banding filter */ | 6105 | /* "60HZ" light frequency banding filter */ |
@@ -6104,7 +6124,7 @@ static struct usb_action tas5130c_vf0250_60HZ[] = { | |||
6104 | {0xa0, 0x58, 0x011d}, /* 01,1d,58,cc, */ | 6124 | {0xa0, 0x58, 0x011d}, /* 01,1d,58,cc, */ |
6105 | {0xa0, 0x42, 0x0180}, /* 01,80,42,cc, */ | 6125 | {0xa0, 0x42, 0x0180}, /* 01,80,42,cc, */ |
6106 | {0xa0, 0x78, 0x018d}, /* 01,8d,78,cc */ | 6126 | {0xa0, 0x78, 0x018d}, /* 01,8d,78,cc */ |
6107 | {0, 0, 0} | 6127 | {} |
6108 | }; | 6128 | }; |
6109 | 6129 | ||
6110 | /* "60HZScale" light frequency banding ilter */ | 6130 | /* "60HZScale" light frequency banding ilter */ |
@@ -6129,7 +6149,7 @@ static struct usb_action tas5130c_vf0250_60HZScale[] = { | |||
6129 | {0xa0, 0x58, 0x011d}, /* 01,d,58,cc, */ | 6149 | {0xa0, 0x58, 0x011d}, /* 01,d,58,cc, */ |
6130 | {0xa0, 0x42, 0x0180}, /* 01,80,42,cc, */ | 6150 | {0xa0, 0x42, 0x0180}, /* 01,80,42,cc, */ |
6131 | {0xa0, 0x78, 0x018d}, /* 01,d,78,cc */ | 6151 | {0xa0, 0x78, 0x018d}, /* 01,d,78,cc */ |
6132 | {0, 0, 0} | 6152 | {} |
6133 | }; | 6153 | }; |
6134 | 6154 | ||
6135 | /* "NoFliker" light frequency banding flter */ | 6155 | /* "NoFliker" light frequency banding flter */ |
@@ -6152,7 +6172,7 @@ static struct usb_action tas5130c_vf0250_NoFliker[] = { | |||
6152 | {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc, */ | 6172 | {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc, */ |
6153 | {0xa0, 0x58, 0x011d}, /* 01,1d,58,cc, */ | 6173 | {0xa0, 0x58, 0x011d}, /* 01,1d,58,cc, */ |
6154 | {0xa0, 0x03, 0x0180}, /* 01,80,03,cc */ | 6174 | {0xa0, 0x03, 0x0180}, /* 01,80,03,cc */ |
6155 | {0, 0, 0} | 6175 | {} |
6156 | }; | 6176 | }; |
6157 | 6177 | ||
6158 | /* "NoFlikerScale" light frequency banding filter */ | 6178 | /* "NoFlikerScale" light frequency banding filter */ |
@@ -6175,7 +6195,7 @@ static struct usb_action tas5130c_vf0250_NoFlikerScale[] = { | |||
6175 | {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc, */ | 6195 | {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc, */ |
6176 | {0xa0, 0x58, 0x011d}, /* 01,1d,58,cc, */ | 6196 | {0xa0, 0x58, 0x011d}, /* 01,1d,58,cc, */ |
6177 | {0xa0, 0x03, 0x0180}, /* 01,80,03,cc */ | 6197 | {0xa0, 0x03, 0x0180}, /* 01,80,03,cc */ |
6178 | {0, 0, 0} | 6198 | {} |
6179 | }; | 6199 | }; |
6180 | 6200 | ||
6181 | static void reg_r_i(struct usb_device *dev, | 6201 | static void reg_r_i(struct usb_device *dev, |
@@ -6325,7 +6345,7 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
6325 | case SENSOR_PO2030: | 6345 | case SENSOR_PO2030: |
6326 | return; | 6346 | return; |
6327 | } | 6347 | } |
6328 | /*fixme: is it really 011d 018d for all other sensors? */ | 6348 | /*fixme: is it really write to 011d and 018d for all other sensors? */ |
6329 | brightness = sd->brightness; | 6349 | brightness = sd->brightness; |
6330 | reg_w(gspca_dev->dev, brightness, 0x011d); | 6350 | reg_w(gspca_dev->dev, brightness, 0x011d); |
6331 | if (brightness < 0x70) | 6351 | if (brightness < 0x70) |
@@ -6348,20 +6368,7 @@ static void setsharpness(struct gspca_dev *gspca_dev) | |||
6348 | {0x10, 0x1e} | 6368 | {0x10, 0x1e} |
6349 | }; | 6369 | }; |
6350 | 6370 | ||
6351 | switch (sd->sensor) { | 6371 | sharpness = sd->sharpness; |
6352 | case SENSOR_GC0305: | ||
6353 | sharpness = 3; | ||
6354 | break; | ||
6355 | case SENSOR_OV7620: | ||
6356 | sharpness = 2; | ||
6357 | break; | ||
6358 | case SENSOR_PO2030: | ||
6359 | sharpness = 0; | ||
6360 | break; | ||
6361 | default: | ||
6362 | return; | ||
6363 | } | ||
6364 | /*fixme: sharpness set by V4L2_CID_SATURATION?*/ | ||
6365 | reg_w(dev, sharpness_tb[sharpness][0], 0x01c6); | 6372 | reg_w(dev, sharpness_tb[sharpness][0], 0x01c6); |
6366 | reg_r(dev, 0x01c8, &retbyte); | 6373 | reg_r(dev, 0x01c8, &retbyte); |
6367 | reg_r(dev, 0x01c9, &retbyte); | 6374 | reg_r(dev, 0x01c9, &retbyte); |
@@ -6411,7 +6418,7 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
6411 | static __u8 Tgradient_5[16] = | 6418 | static __u8 Tgradient_5[16] = |
6412 | {0x37, 0x26, 0x20, 0x1a, 0x14, 0x10, 0x0e, 0x0b, | 6419 | {0x37, 0x26, 0x20, 0x1a, 0x14, 0x10, 0x0e, 0x0b, |
6413 | 0x09, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x02}; | 6420 | 0x09, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x02}; |
6414 | static __u8 Tgamma_6[16] = /* ?? was gama 5 */ | 6421 | static __u8 Tgamma_6[16] = /* ?? was gamma 5 */ |
6415 | {0x24, 0x44, 0x64, 0x84, 0x9d, 0xb2, 0xc4, 0xd3, | 6422 | {0x24, 0x44, 0x64, 0x84, 0x9d, 0xb2, 0xc4, 0xd3, |
6416 | 0xe0, 0xeb, 0xf4, 0xff, 0xff, 0xff, 0xff, 0xff}; | 6423 | 0xe0, 0xeb, 0xf4, 0xff, 0xff, 0xff, 0xff, 0xff}; |
6417 | static __u8 Tgradient_6[16] = | 6424 | static __u8 Tgradient_6[16] = |
@@ -6425,7 +6432,7 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
6425 | 0, Tgradient_1, Tgradient_2, | 6432 | 0, Tgradient_1, Tgradient_2, |
6426 | Tgradient_3, Tgradient_4, Tgradient_5, Tgradient_6 | 6433 | Tgradient_3, Tgradient_4, Tgradient_5, Tgradient_6 |
6427 | }; | 6434 | }; |
6428 | #ifdef GSPCA_DEBUG | 6435 | #ifdef VIDEO_ADV_DEBUG |
6429 | __u8 v[16]; | 6436 | __u8 v[16]; |
6430 | #endif | 6437 | #endif |
6431 | 6438 | ||
@@ -6443,7 +6450,7 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
6443 | else if (g <= 0) | 6450 | else if (g <= 0) |
6444 | g = 1; | 6451 | g = 1; |
6445 | reg_w(dev, g, 0x0120 + i); /* gamma */ | 6452 | reg_w(dev, g, 0x0120 + i); /* gamma */ |
6446 | #ifdef GSPCA_DEBUG | 6453 | #ifdef VIDEO_ADV_DEBUG |
6447 | if (gspca_debug & D_CONF) | 6454 | if (gspca_debug & D_CONF) |
6448 | v[i] = g; | 6455 | v[i] = g; |
6449 | #endif | 6456 | #endif |
@@ -6463,7 +6470,7 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
6463 | g = 1; | 6470 | g = 1; |
6464 | } | 6471 | } |
6465 | reg_w(dev, g, 0x0130 + i); /* gradient */ | 6472 | reg_w(dev, g, 0x0130 + i); /* gradient */ |
6466 | #ifdef GSPCA_DEBUG | 6473 | #ifdef VIDEO_ADV_DEBUG |
6467 | if (gspca_debug & D_CONF) | 6474 | if (gspca_debug & D_CONF) |
6468 | v[i] = g; | 6475 | v[i] = g; |
6469 | #endif | 6476 | #endif |
@@ -6488,7 +6495,7 @@ static void setquality(struct gspca_dev *gspca_dev) | |||
6488 | return; | 6495 | return; |
6489 | } | 6496 | } |
6490 | /*fixme: is it really 0008 0007 0018 for all other sensors? */ | 6497 | /*fixme: is it really 0008 0007 0018 for all other sensors? */ |
6491 | quality = sd->qindex & 0x0f; | 6498 | quality = sd->qindex; |
6492 | reg_w(dev, quality, 0x0008); | 6499 | reg_w(dev, quality, 0x0008); |
6493 | frxt = 0x30; | 6500 | frxt = 0x30; |
6494 | reg_w(dev, frxt, 0x0007); | 6501 | reg_w(dev, frxt, 0x0007); |
@@ -6525,25 +6532,25 @@ static int setlightfreq(struct gspca_dev *gspca_dev) | |||
6525 | struct usb_action *zc3_freq; | 6532 | struct usb_action *zc3_freq; |
6526 | static struct usb_action *freq_tb[SENSOR_MAX][6] = { | 6533 | static struct usb_action *freq_tb[SENSOR_MAX][6] = { |
6527 | /* SENSOR_CS2102 0 */ | 6534 | /* SENSOR_CS2102 0 */ |
6528 | {cs2102_50HZ, cs2102_50HZScale, | 6535 | {cs2102_NoFliker, cs2102_NoFlikerScale, |
6529 | cs2102_60HZ, cs2102_60HZScale, | 6536 | cs2102_50HZ, cs2102_50HZScale, |
6530 | cs2102_NoFliker, cs2102_NoFlikerScale}, | 6537 | cs2102_60HZ, cs2102_60HZScale}, |
6531 | /* SENSOR_CS2102K 1 */ | 6538 | /* SENSOR_CS2102K 1 */ |
6532 | {cs2102_50HZ, cs2102_50HZScale, | 6539 | {cs2102_NoFliker, cs2102_NoFlikerScale, |
6533 | cs2102_60HZ, cs2102_60HZScale, | 6540 | cs2102_50HZ, cs2102_50HZScale, |
6534 | cs2102_NoFliker, cs2102_NoFlikerScale}, | 6541 | cs2102_60HZ, cs2102_60HZScale}, |
6535 | /* SENSOR_GC0305 2 */ | 6542 | /* SENSOR_GC0305 2 */ |
6536 | {gc0305_50HZ, gc0305_50HZ, | 6543 | {gc0305_NoFliker, gc0305_NoFliker, |
6537 | gc0305_60HZ, gc0305_60HZ, | 6544 | gc0305_50HZ, gc0305_50HZ, |
6538 | gc0305_NoFliker, gc0305_NoFliker}, | 6545 | gc0305_60HZ, gc0305_60HZ}, |
6539 | /* SENSOR_HDCS2020 3 */ | 6546 | /* SENSOR_HDCS2020 3 */ |
6540 | {0, 0, | 6547 | {0, 0, |
6541 | 0, 0, | 6548 | 0, 0, |
6542 | 0, 0}, | 6549 | 0, 0}, |
6543 | /* SENSOR_HDCS2020b 4 */ | 6550 | /* SENSOR_HDCS2020b 4 */ |
6544 | {hdcs2020b_50HZ, hdcs2020b_50HZ, | 6551 | {hdcs2020b_NoFliker, hdcs2020b_NoFliker, |
6545 | hdcs2020b_60HZ, hdcs2020b_60HZ, | 6552 | hdcs2020b_50HZ, hdcs2020b_50HZ, |
6546 | hdcs2020b_NoFliker, hdcs2020b_NoFliker}, | 6553 | hdcs2020b_60HZ, hdcs2020b_60HZ}, |
6547 | /* SENSOR_HV7131B 5 */ | 6554 | /* SENSOR_HV7131B 5 */ |
6548 | {0, 0, | 6555 | {0, 0, |
6549 | 0, 0, | 6556 | 0, 0, |
@@ -6553,66 +6560,48 @@ static int setlightfreq(struct gspca_dev *gspca_dev) | |||
6553 | 0, 0, | 6560 | 0, 0, |
6554 | 0, 0}, | 6561 | 0, 0}, |
6555 | /* SENSOR_ICM105A 7 */ | 6562 | /* SENSOR_ICM105A 7 */ |
6556 | {icm105a_50HZ, icm105a_50HZScale, | 6563 | {icm105a_NoFliker, icm105a_NoFlikerScale, |
6557 | icm105a_60HZ, icm105a_60HZScale, | 6564 | icm105a_50HZ, icm105a_50HZScale, |
6558 | icm105a_NoFliker, icm105a_NoFlikerScale}, | 6565 | icm105a_60HZ, icm105a_60HZScale}, |
6559 | /* SENSOR_MC501CB 8 */ | 6566 | /* SENSOR_MC501CB 8 */ |
6560 | {MC501CB_50HZ, MC501CB_50HZScale, | 6567 | {MC501CB_NoFliker, MC501CB_NoFlikerScale, |
6561 | MC501CB_60HZ, MC501CB_60HZScale, | 6568 | MC501CB_50HZ, MC501CB_50HZScale, |
6562 | MC501CB_NoFliker, MC501CB_NoFlikerScale}, | 6569 | MC501CB_60HZ, MC501CB_60HZScale}, |
6563 | /* SENSOR_OV7620 9 */ | 6570 | /* SENSOR_OV7620 9 */ |
6564 | {OV7620_50HZ, OV7620_50HZ, | 6571 | {OV7620_NoFliker, OV7620_NoFliker, |
6565 | OV7620_60HZ, OV7620_60HZ, | 6572 | OV7620_50HZ, OV7620_50HZ, |
6566 | OV7620_NoFliker, OV7620_NoFliker}, | 6573 | OV7620_60HZ, OV7620_60HZ}, |
6567 | /* SENSOR_OV7630C 10 */ | 6574 | /* SENSOR_OV7630C 10 */ |
6568 | {0, 0, | 6575 | {0, 0, |
6569 | 0, 0, | 6576 | 0, 0, |
6570 | 0, 0}, | 6577 | 0, 0}, |
6571 | /* SENSOR_free 11 */ | 6578 | /* SENSOR_PAS106 11 */ |
6572 | {0, 0, | 6579 | {pas106b_NoFliker, pas106b_NoFliker, |
6573 | 0, 0, | 6580 | pas106b_50HZ, pas106b_50HZ, |
6574 | 0, 0}, | 6581 | pas106b_60HZ, pas106b_60HZ}, |
6575 | /* SENSOR_PAS106 12 */ | 6582 | /* SENSOR_PB0330 12 */ |
6576 | {pas106b_50HZ, pas106b_50HZ, | 6583 | {pb0330_NoFliker, pb0330_NoFlikerScale, |
6577 | pas106b_60HZ, pas106b_60HZ, | 6584 | pb0330_50HZ, pb0330_50HZScale, |
6578 | pas106b_NoFliker, pas106b_NoFliker}, | 6585 | pb0330_60HZ, pb0330_60HZScale}, |
6579 | /* SENSOR_PB0330 13 */ | 6586 | /* SENSOR_PO2030 13 */ |
6580 | {pb0330_50HZ, pb0330_50HZScale, | 6587 | {PO2030_NoFliker, PO2030_NoFliker, |
6581 | pb0330_60HZ, pb0330_60HZScale, | 6588 | PO2030_50HZ, PO2030_50HZ, |
6582 | pb0330_NoFliker, pb0330_NoFlikerScale}, | 6589 | PO2030_60HZ, PO2030_60HZ}, |
6583 | /* SENSOR_PO2030 14 */ | 6590 | /* SENSOR_TAS5130CK 14 */ |
6584 | {PO2030_50HZ, PO2030_50HZ, | 6591 | {tas5130cxx_NoFliker, tas5130cxx_NoFlikerScale, |
6585 | PO2030_60HZ, PO2030_60HZ, | 6592 | tas5130cxx_50HZ, tas5130cxx_50HZScale, |
6586 | PO2030_NoFliker, PO2030_NoFliker}, | 6593 | tas5130cxx_60HZ, tas5130cxx_60HZScale}, |
6587 | /* SENSOR_TAS5130CK 15 */ | 6594 | /* SENSOR_TAS5130CXX 15 */ |
6588 | {tas5130cxx_50HZ, tas5130cxx_50HZScale, | 6595 | {tas5130cxx_NoFliker, tas5130cxx_NoFlikerScale, |
6589 | tas5130cxx_60HZ, tas5130cxx_60HZScale, | 6596 | tas5130cxx_50HZ, tas5130cxx_50HZScale, |
6590 | tas5130cxx_NoFliker, tas5130cxx_NoFlikerScale}, | 6597 | tas5130cxx_60HZ, tas5130cxx_60HZScale}, |
6591 | /* SENSOR_TAS5130CXX 16 */ | 6598 | /* SENSOR_TAS5130C_VF0250 16 */ |
6592 | {tas5130cxx_50HZ, tas5130cxx_50HZScale, | 6599 | {tas5130c_vf0250_NoFliker, tas5130c_vf0250_NoFlikerScale, |
6593 | tas5130cxx_60HZ, tas5130cxx_60HZScale, | 6600 | tas5130c_vf0250_50HZ, tas5130c_vf0250_50HZScale, |
6594 | tas5130cxx_NoFliker, tas5130cxx_NoFlikerScale}, | 6601 | tas5130c_vf0250_60HZ, tas5130c_vf0250_60HZScale}, |
6595 | /* SENSOR_TAS5130C_VF0250 17 */ | ||
6596 | {tas5130c_vf0250_50HZ, tas5130c_vf0250_50HZScale, | ||
6597 | tas5130c_vf0250_60HZ, tas5130c_vf0250_60HZScale, | ||
6598 | tas5130c_vf0250_NoFliker, tas5130c_vf0250_NoFlikerScale}, | ||
6599 | }; | 6602 | }; |
6600 | 6603 | ||
6601 | switch (lightfreq) { | 6604 | i = sd->lightfreq * 2; |
6602 | case 50: | ||
6603 | i = 0; | ||
6604 | break; | ||
6605 | case 60: | ||
6606 | i = 2; | ||
6607 | break; | ||
6608 | default: | ||
6609 | PDEBUG(D_ERR, "Invalid light freq value %d", lightfreq); | ||
6610 | lightfreq = 0; /* set to default filter value */ | ||
6611 | /* fall thru */ | ||
6612 | case 0: | ||
6613 | i = 4; | ||
6614 | break; | ||
6615 | } | ||
6616 | mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode; | 6605 | mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode; |
6617 | if (!mode) | 6606 | if (!mode) |
6618 | i++; /* 640x480 */ | 6607 | i++; /* 640x480 */ |
@@ -6622,13 +6611,13 @@ static int setlightfreq(struct gspca_dev *gspca_dev) | |||
6622 | switch (sd->sensor) { | 6611 | switch (sd->sensor) { |
6623 | case SENSOR_GC0305: | 6612 | case SENSOR_GC0305: |
6624 | if (mode /* if 320x240 */ | 6613 | if (mode /* if 320x240 */ |
6625 | && lightfreq == 50) | 6614 | && sd->lightfreq == 1) /* and 50Hz */ |
6626 | reg_w(gspca_dev->dev, 0x85, 0x018d); | 6615 | reg_w(gspca_dev->dev, 0x85, 0x018d); |
6627 | /* win: 0x80, 0x018d */ | 6616 | /* win: 0x80, 0x018d */ |
6628 | break; | 6617 | break; |
6629 | case SENSOR_OV7620: | 6618 | case SENSOR_OV7620: |
6630 | if (!mode) { /* if 640x480 */ | 6619 | if (!mode) { /* if 640x480 */ |
6631 | if (lightfreq != 0) /* 50 or 60 Hz */ | 6620 | if (sd->lightfreq != 0) /* and 50 or 60 Hz */ |
6632 | reg_w(gspca_dev->dev, 0x40, 0x0002); | 6621 | reg_w(gspca_dev->dev, 0x40, 0x0002); |
6633 | else | 6622 | else |
6634 | reg_w(gspca_dev->dev, 0x44, 0x0002); | 6623 | reg_w(gspca_dev->dev, 0x44, 0x0002); |
@@ -6653,9 +6642,9 @@ static void setautogain(struct gspca_dev *gspca_dev) | |||
6653 | 6642 | ||
6654 | static void send_unknown(struct usb_device *dev, int sensor) | 6643 | static void send_unknown(struct usb_device *dev, int sensor) |
6655 | { | 6644 | { |
6645 | reg_w(dev, 0x01, 0x0000); /* led off */ | ||
6656 | switch (sensor) { | 6646 | switch (sensor) { |
6657 | case SENSOR_PAS106: | 6647 | case SENSOR_PAS106: |
6658 | reg_w(dev, 0x01, 0x0000); | ||
6659 | reg_w(dev, 0x03, 0x003a); | 6648 | reg_w(dev, 0x03, 0x003a); |
6660 | reg_w(dev, 0x0c, 0x003b); | 6649 | reg_w(dev, 0x0c, 0x003b); |
6661 | reg_w(dev, 0x08, 0x0038); | 6650 | reg_w(dev, 0x08, 0x0038); |
@@ -6664,7 +6653,6 @@ static void send_unknown(struct usb_device *dev, int sensor) | |||
6664 | case SENSOR_OV7620: | 6653 | case SENSOR_OV7620: |
6665 | case SENSOR_PB0330: | 6654 | case SENSOR_PB0330: |
6666 | case SENSOR_PO2030: | 6655 | case SENSOR_PO2030: |
6667 | reg_w(dev, 0x01, 0x0000); | ||
6668 | reg_w(dev, 0x0d, 0x003a); | 6656 | reg_w(dev, 0x0d, 0x003a); |
6669 | reg_w(dev, 0x02, 0x003b); | 6657 | reg_w(dev, 0x02, 0x003b); |
6670 | reg_w(dev, 0x00, 0x0038); | 6658 | reg_w(dev, 0x00, 0x0038); |
@@ -6817,7 +6805,7 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev) | |||
6817 | 6805 | ||
6818 | /*fixme: lack of 8b=b3 (11,12)-> 10, 8b=e0 (14,15,16)-> 12 found in gspcav1*/ | 6806 | /*fixme: lack of 8b=b3 (11,12)-> 10, 8b=e0 (14,15,16)-> 12 found in gspcav1*/ |
6819 | reg_w(dev, 0x02, 0x0010); | 6807 | reg_w(dev, 0x02, 0x0010); |
6820 | reg_r(dev, 0x0010, &retbyte); | 6808 | reg_r(dev, 0x10, &retbyte); |
6821 | reg_w(dev, 0x01, 0x0000); | 6809 | reg_w(dev, 0x01, 0x0000); |
6822 | reg_w(dev, 0x00, 0x0010); | 6810 | reg_w(dev, 0x00, 0x0010); |
6823 | reg_w(dev, 0x01, 0x0001); | 6811 | reg_w(dev, 0x01, 0x0001); |
@@ -6964,7 +6952,7 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
6964 | int sensor; | 6952 | int sensor; |
6965 | __u8 bsensor; | 6953 | __u8 bsensor; |
6966 | int vga = 1; /* 1: vga, 0: sif */ | 6954 | int vga = 1; /* 1: vga, 0: sif */ |
6967 | static unsigned char gamma[SENSOR_MAX] = { | 6955 | static __u8 gamma[SENSOR_MAX] = { |
6968 | 5, /* SENSOR_CS2102 0 */ | 6956 | 5, /* SENSOR_CS2102 0 */ |
6969 | 5, /* SENSOR_CS2102K 1 */ | 6957 | 5, /* SENSOR_CS2102K 1 */ |
6970 | 4, /* SENSOR_GC0305 2 */ | 6958 | 4, /* SENSOR_GC0305 2 */ |
@@ -6976,16 +6964,16 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
6976 | 4, /* SENSOR_MC501CB 8 */ | 6964 | 4, /* SENSOR_MC501CB 8 */ |
6977 | 3, /* SENSOR_OV7620 9 */ | 6965 | 3, /* SENSOR_OV7620 9 */ |
6978 | 4, /* SENSOR_OV7630C 10 */ | 6966 | 4, /* SENSOR_OV7630C 10 */ |
6979 | 4, /* SENSOR_free 11 */ | 6967 | 4, /* SENSOR_PAS106 11 */ |
6980 | 4, /* SENSOR_PAS106 12 */ | 6968 | 4, /* SENSOR_PB0330 12 */ |
6981 | 4, /* SENSOR_PB0330 13 */ | 6969 | 4, /* SENSOR_PO2030 13 */ |
6982 | 4, /* SENSOR_PO2030 14 */ | 6970 | 4, /* SENSOR_TAS5130CK 14 */ |
6983 | 4, /* SENSOR_TAS5130CK 15 */ | 6971 | 4, /* SENSOR_TAS5130CXX 15 */ |
6984 | 4, /* SENSOR_TAS5130CXX 16 */ | 6972 | 3, /* SENSOR_TAS5130C_VF0250 16 */ |
6985 | 3, /* SENSOR_TAS5130C_VF0250 17 */ | ||
6986 | }; | 6973 | }; |
6987 | 6974 | ||
6988 | /* define some sensors from the vendor/product */ | 6975 | /* define some sensors from the vendor/product */ |
6976 | sd->sharpness = 2; | ||
6989 | switch (id->idVendor) { | 6977 | switch (id->idVendor) { |
6990 | case 0x041e: /* Creative */ | 6978 | case 0x041e: /* Creative */ |
6991 | switch (id->idProduct) { | 6979 | switch (id->idProduct) { |
@@ -7055,8 +7043,9 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
7055 | sd->sensor = SENSOR_ICM105A; | 7043 | sd->sensor = SENSOR_ICM105A; |
7056 | break; | 7044 | break; |
7057 | case 0x0e: | 7045 | case 0x0e: |
7058 | PDEBUG(D_PROBE, "Find Sensor PAS202BCB"); | 7046 | PDEBUG(D_PROBE, "Find Sensor HDCS2020"); |
7059 | sd->sensor = SENSOR_HDCS2020; | 7047 | sd->sensor = SENSOR_HDCS2020; |
7048 | sd->sharpness = 1; | ||
7060 | break; | 7049 | break; |
7061 | case 0x0f: | 7050 | case 0x0f: |
7062 | PDEBUG(D_PROBE, "Find Sensor PAS106"); | 7051 | PDEBUG(D_PROBE, "Find Sensor PAS106"); |
@@ -7097,6 +7086,7 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
7097 | case 0x2030: | 7086 | case 0x2030: |
7098 | PDEBUG(D_PROBE, "Find Sensor PO2030"); | 7087 | PDEBUG(D_PROBE, "Find Sensor PO2030"); |
7099 | sd->sensor = SENSOR_PO2030; | 7088 | sd->sensor = SENSOR_PO2030; |
7089 | sd->sharpness = 0; /* from win traces */ | ||
7100 | break; | 7090 | break; |
7101 | case 0x7620: | 7091 | case 0x7620: |
7102 | PDEBUG(D_PROBE, "Find Sensor OV7620"); | 7092 | PDEBUG(D_PROBE, "Find Sensor OV7620"); |
@@ -7134,13 +7124,13 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
7134 | sd->qindex = 1; | 7124 | sd->qindex = 1; |
7135 | sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; | 7125 | sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; |
7136 | sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; | 7126 | sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; |
7137 | sd->autogain = sd_ctrls[SD_AUTOGAIN].qctrl.default_value; | ||
7138 | sd->gamma = gamma[(int) sd->sensor]; | 7127 | sd->gamma = gamma[(int) sd->sensor]; |
7128 | sd->autogain = sd_ctrls[SD_AUTOGAIN].qctrl.default_value; | ||
7129 | sd->lightfreq = sd_ctrls[SD_FREQ].qctrl.default_value; | ||
7130 | sd->sharpness = sd_ctrls[SD_SHARPNESS].qctrl.default_value; | ||
7139 | 7131 | ||
7140 | /* switch the led off */ | 7132 | /* switch the led off */ |
7141 | /*fixme: other sensors? */ | 7133 | reg_w(gspca_dev->dev, 0x01, 0x0000); |
7142 | if (sensor == 0x06 || sensor == 0x11) | ||
7143 | reg_w(gspca_dev->dev, 0x01, 0x0000); | ||
7144 | return 0; | 7134 | return 0; |
7145 | } | 7135 | } |
7146 | 7136 | ||
@@ -7170,15 +7160,14 @@ static void sd_start(struct gspca_dev *gspca_dev) | |||
7170 | {MC501CB_InitialScale, MC501CB_Initial}, /* 9 */ | 7160 | {MC501CB_InitialScale, MC501CB_Initial}, /* 9 */ |
7171 | {OV7620_mode0, OV7620_mode1}, /* 9 */ | 7161 | {OV7620_mode0, OV7620_mode1}, /* 9 */ |
7172 | {ov7630c_InitialScale, ov7630c_Initial}, /* 10 */ | 7162 | {ov7630c_InitialScale, ov7630c_Initial}, /* 10 */ |
7173 | {0, 0}, /* 11 */ | 7163 | {pas106b_InitialScale, pas106b_Initial}, /* 11 */ |
7174 | {pas106b_InitialScale, pas106b_Initial}, /* 12 */ | 7164 | {pb0330xx_InitialScale, pb0330xx_Initial}, /* 12 */ |
7175 | {pb0330xx_InitialScale, pb0330xx_Initial}, /* 13 */ | ||
7176 | /* or {pb03303x_InitialScale, pb03303x_Initial}, */ | 7165 | /* or {pb03303x_InitialScale, pb03303x_Initial}, */ |
7177 | {PO2030_mode0, PO2030_mode1}, /* 14 */ | 7166 | {PO2030_mode0, PO2030_mode1}, /* 13 */ |
7178 | {tas5130CK_InitialScale, tas5130CK_Initial}, /* 15 */ | 7167 | {tas5130CK_InitialScale, tas5130CK_Initial}, /* 14 */ |
7179 | {tas5130cxx_InitialScale, tas5130cxx_Initial}, /* 16 */ | 7168 | {tas5130cxx_InitialScale, tas5130cxx_Initial}, /* 15 */ |
7180 | {tas5130c_vf0250_InitialScale, tas5130c_vf0250_Initial}, | 7169 | {tas5130c_vf0250_InitialScale, tas5130c_vf0250_Initial}, |
7181 | /* 17 */ | 7170 | /* 16 */ |
7182 | }; | 7171 | }; |
7183 | 7172 | ||
7184 | mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode; | 7173 | mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode; |
@@ -7324,7 +7313,7 @@ static void sd_close(struct gspca_dev *gspca_dev) | |||
7324 | 7313 | ||
7325 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | 7314 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, |
7326 | struct gspca_frame *frame, | 7315 | struct gspca_frame *frame, |
7327 | unsigned char *data, | 7316 | __u8 *data, |
7328 | int len) | 7317 | int len) |
7329 | { | 7318 | { |
7330 | 7319 | ||
@@ -7401,6 +7390,16 @@ static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) | |||
7401 | return 0; | 7390 | return 0; |
7402 | } | 7391 | } |
7403 | 7392 | ||
7393 | static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val) | ||
7394 | { | ||
7395 | struct sd *sd = (struct sd *) gspca_dev; | ||
7396 | |||
7397 | sd->gamma = val; | ||
7398 | if (gspca_dev->streaming) | ||
7399 | setcontrast(gspca_dev); | ||
7400 | return 0; | ||
7401 | } | ||
7402 | |||
7404 | static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val) | 7403 | static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val) |
7405 | { | 7404 | { |
7406 | struct sd *sd = (struct sd *) gspca_dev; | 7405 | struct sd *sd = (struct sd *) gspca_dev; |
@@ -7409,6 +7408,63 @@ static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val) | |||
7409 | return 0; | 7408 | return 0; |
7410 | } | 7409 | } |
7411 | 7410 | ||
7411 | static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val) | ||
7412 | { | ||
7413 | struct sd *sd = (struct sd *) gspca_dev; | ||
7414 | |||
7415 | sd->lightfreq = val; | ||
7416 | if (gspca_dev->streaming) | ||
7417 | setlightfreq(gspca_dev); | ||
7418 | return 0; | ||
7419 | } | ||
7420 | |||
7421 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val) | ||
7422 | { | ||
7423 | struct sd *sd = (struct sd *) gspca_dev; | ||
7424 | |||
7425 | *val = sd->lightfreq; | ||
7426 | return 0; | ||
7427 | } | ||
7428 | |||
7429 | static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val) | ||
7430 | { | ||
7431 | struct sd *sd = (struct sd *) gspca_dev; | ||
7432 | |||
7433 | sd->sharpness = val; | ||
7434 | if (gspca_dev->streaming) | ||
7435 | setsharpness(gspca_dev); | ||
7436 | return 0; | ||
7437 | } | ||
7438 | |||
7439 | static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val) | ||
7440 | { | ||
7441 | struct sd *sd = (struct sd *) gspca_dev; | ||
7442 | |||
7443 | *val = sd->sharpness; | ||
7444 | return 0; | ||
7445 | } | ||
7446 | |||
7447 | static int sd_querymenu(struct gspca_dev *gspca_dev, | ||
7448 | struct v4l2_querymenu *menu) | ||
7449 | { | ||
7450 | switch (menu->id) { | ||
7451 | case V4L2_CID_POWER_LINE_FREQUENCY: | ||
7452 | switch (menu->index) { | ||
7453 | case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */ | ||
7454 | strcpy(menu->name, "NoFliker"); | ||
7455 | return 0; | ||
7456 | case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */ | ||
7457 | strcpy(menu->name, "50 Hz"); | ||
7458 | return 0; | ||
7459 | case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */ | ||
7460 | strcpy(menu->name, "60 Hz"); | ||
7461 | return 0; | ||
7462 | } | ||
7463 | break; | ||
7464 | } | ||
7465 | return -EINVAL; | ||
7466 | } | ||
7467 | |||
7412 | static struct sd_desc sd_desc = { | 7468 | static struct sd_desc sd_desc = { |
7413 | .name = MODULE_NAME, | 7469 | .name = MODULE_NAME, |
7414 | .ctrls = sd_ctrls, | 7470 | .ctrls = sd_ctrls, |
@@ -7420,6 +7476,7 @@ static struct sd_desc sd_desc = { | |||
7420 | .stop0 = sd_stop0, | 7476 | .stop0 = sd_stop0, |
7421 | .close = sd_close, | 7477 | .close = sd_close, |
7422 | .pkt_scan = sd_pkt_scan, | 7478 | .pkt_scan = sd_pkt_scan, |
7479 | .querymenu = sd_querymenu, | ||
7423 | }; | 7480 | }; |
7424 | 7481 | ||
7425 | #define DVNM(name) .driver_info = (kernel_ulong_t) name | 7482 | #define DVNM(name) .driver_info = (kernel_ulong_t) name |
@@ -7514,10 +7571,6 @@ static void __exit sd_mod_exit(void) | |||
7514 | module_init(sd_mod_init); | 7571 | module_init(sd_mod_init); |
7515 | module_exit(sd_mod_exit); | 7572 | module_exit(sd_mod_exit); |
7516 | 7573 | ||
7517 | module_param(lightfreq, int, 0644); | ||
7518 | MODULE_PARM_DESC(lightfreq, | ||
7519 | "Light frequency banding filter: 50, 60 Hz or" | ||
7520 | " 0 to NoFliker (default=50)"); | ||
7521 | module_param(force_sensor, int, 0644); | 7574 | module_param(force_sensor, int, 0644); |
7522 | MODULE_PARM_DESC(force_sensor, | 7575 | MODULE_PARM_DESC(force_sensor, |
7523 | "Force sensor. Only for experts!!!"); | 7576 | "Force sensor. Only for experts!!!"); |