aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJean-Francois Moine <moinejf@free.fr>2008-06-30 14:50:11 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-07-20 06:14:49 -0400
commit6a7eba24e4f0ff725d33159f6265e3a79d53a833 (patch)
tree3e50d669cb91affbcfad9333d74ddc452783094f /drivers
parentd43fa32fec442571f10f5d0c3b553413288728de (diff)
V4L/DVB (8157): gspca: all subdrivers
- remaning subdrivers added - remove the decoding helper and some specific frame decodings Signed-off-by: Jean-Francois Moine <moinejf@free.fr> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/video/Makefile1
-rw-r--r--drivers/media/video/gspca/Kconfig2
-rw-r--r--drivers/media/video/gspca/Makefile26
-rw-r--r--drivers/media/video/gspca/conex.c1059
-rw-r--r--drivers/media/video/gspca/etoms.c1062
-rw-r--r--drivers/media/video/gspca/gspca.c579
-rw-r--r--drivers/media/video/gspca/gspca.h39
-rw-r--r--drivers/media/video/gspca/mars.c455
-rw-r--r--drivers/media/video/gspca/ov519.c2174
-rw-r--r--drivers/media/video/gspca/pac207.c10
-rw-r--r--drivers/media/video/gspca/pac7311.c754
-rw-r--r--drivers/media/video/gspca/sonixb.c879
-rw-r--r--drivers/media/video/gspca/sonixj.c1629
-rw-r--r--drivers/media/video/gspca/spca500.c1195
-rw-r--r--drivers/media/video/gspca/spca501.c2219
-rw-r--r--drivers/media/video/gspca/spca505.c933
-rw-r--r--drivers/media/video/gspca/spca506.c830
-rw-r--r--drivers/media/video/gspca/spca508.c1774
-rw-r--r--drivers/media/video/gspca/spca561.c1025
-rw-r--r--drivers/media/video/gspca/stk014.c170
-rw-r--r--drivers/media/video/gspca/sunplus.c1638
-rw-r--r--drivers/media/video/gspca/t613.c1013
-rw-r--r--drivers/media/video/gspca/tv8532.c709
-rw-r--r--drivers/media/video/gspca/vc032x.c1816
-rw-r--r--drivers/media/video/gspca/zc3xx.c649
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/
117obj-$(CONFIG_USB_ET61X251) += et61x251/ 117obj-$(CONFIG_USB_ET61X251) += et61x251/
118obj-$(CONFIG_USB_PWC) += pwc/ 118obj-$(CONFIG_USB_PWC) += pwc/
119obj-$(CONFIG_USB_ZC0301) += zc0301/ 119obj-$(CONFIG_USB_ZC0301) += zc0301/
120obj-$(CONFIG_USB_GSPCA) += gspca/
120 121
121obj-$(CONFIG_USB_IBMCAM) += usbvideo/ 122obj-$(CONFIG_USB_IBMCAM) += usbvideo/
122obj-$(CONFIG_USB_KONICAWC) += usbvideo/ 123obj-$(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 @@
1obj-$(CONFIG_GSPCA) += gspca_main.o \ 1obj-$(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
4gspca_main-objs := gspca.o 9gspca_main-objs := gspca.o
10gspca_conex-objs := conex.o
11gspca_etoms-objs := etoms.o
12gspca_mars-objs := mars.o
13gspca_ov519-objs := ov519.o
5gspca_pac207-objs := pac207.o 14gspca_pac207-objs := pac207.o
15gspca_pac7311-objs := pac7311.o
16gspca_sonixb-objs := sonixb.o
17gspca_sonixj-objs := sonixj.o
18gspca_spca500-objs := spca500.o
19gspca_spca501-objs := spca501.o
20gspca_spca505-objs := spca505.o
21gspca_spca506-objs := spca506.o
22gspca_spca508-objs := spca508.o
23gspca_spca561-objs := spca561.o
6gspca_stk014-objs := stk014.o 24gspca_stk014-objs := stk014.o
25gspca_sunplus-objs := sunplus.o
26gspca_t613-objs := t613.o
27gspca_tv8532-objs := tv8532.o
28gspca_vc032x-objs := vc032x.o
7gspca_zc3xx-objs := zc3xx.o 29gspca_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)
29static const char version[] = "2.1.0";
30
31MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
32MODULE_DESCRIPTION("GSPCA USB Conexant Camera Driver");
33MODULE_LICENSE("GPL");
34
35/* specific webcam descriptor */
36struct 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 */
47static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
48static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
49static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
50static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
51static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
52static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
53
54static 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
99static 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
106static 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
120static 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
134static 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
142static 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};
209static 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
224static __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
239static __u8 reg20[] = { 0x10, 0x42, 0x81, 0x19, 0xd3, 0xff, 0xa7, 0xff };
240static __u8 reg28[] = { 0x87, 0x00, 0x87, 0x00, 0x8f, 0xff, 0xea, 0xff };
241static __u8 reg10[] = { 0xb1, 0xb1 };
242static __u8 reg71a[] = { 0x08, 0x18, 0x0a, 0x1e }; /* 640 */
243static __u8 reg71b[] = { 0x04, 0x0c, 0x05, 0x0f };
244 /* 352{0x04,0x0a,0x06,0x12}; //352{0x05,0x0e,0x06,0x11}; //352 */
245static __u8 reg71c[] = { 0x02, 0x07, 0x03, 0x09 };
246 /* 320{0x04,0x0c,0x05,0x0f}; //320 */
247static __u8 reg71d[] = { 0x02, 0x07, 0x03, 0x09 }; /* 176 */
248static __u8 reg7b[] = { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff };
249
250static 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
300static __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};
309static __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};
318static __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};
327static __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
337static 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
391static __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
474static __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};
503static __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};
532static __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};
561static __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};
590static __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
612static 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
636static __u8 reg12[] = { 0x0a, 0x05, 0x07, 0x04, 0x19 };
637static __u8 regE5_8[] = { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 };
638static __u8 regE5a[] = { 0x88, 0x0a, 0x0c, 0x01 };
639static __u8 regE5b[] = { 0x88, 0x0b, 0x12, 0x01 };
640static __u8 regE5c[] = { 0x88, 0x05, 0x01, 0x01 };
641static __u8 reg51[] = { 0x77, 0x03 };
642static __u8 reg70 = 0x03;
643
644static 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, &reg70, 1);
767}
768
769static 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 */
815static 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 */
835static 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
845static 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
853static void sd_stopN(struct gspca_dev *gspca_dev)
854{
855}
856
857static 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
885static void sd_close(struct gspca_dev *gspca_dev)
886{
887}
888
889static 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
910static 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, &reg70, 1);
932}
933
934static 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, &reg70, 1);
949}
950
951static 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
961static 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
969static 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
979static 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
987static 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
999static 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 */
1008static 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
1023static __devinitdata struct usb_device_id device_table[] = {
1024 {USB_DEVICE(0x0572, 0x0041), DVNM("Creative Notebook cx11646")},
1025 {}
1026};
1027MODULE_DEVICE_TABLE(usb, device_table);
1028
1029/* -- device connect -- */
1030static 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
1037static 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 -- */
1045static 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}
1052static void __exit sd_mod_exit(void)
1053{
1054 usb_deregister(&sd_driver);
1055 PDEBUG(D_PROBE, "deregistered");
1056}
1057
1058module_init(sd_mod_init);
1059module_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)
26static const char version[] = "2.1.0";
27
28MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
29MODULE_DESCRIPTION("Etoms USB Camera Driver");
30MODULE_LICENSE("GPL");
31
32/* specific webcam descriptor */
33struct 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 */
49static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
50static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
51static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
52static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
53static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
54static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
55static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
56static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
57
58static 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
117static struct cam_mode vga_mode[] = {
118 {V4L2_PIX_FMT_SBGGR8, 320, 240, 1},
119/* {V4L2_PIX_FMT_SBGGR8, 640, 480, 0}, */
120};
121
122static 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
208static __u8 GainRGBG[] = { 0x80, 0x80, 0x80, 0x80, 0x00, 0x00 };
209
210static __u8 I2c2[] = { 0x08, 0x08, 0x08, 0x08, 0x0d };
211
212static __u8 I2c3[] = { 0x12, 0x05 };
213
214static __u8 I2c4[] = { 0x41, 0x08 };
215
216static 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
226static 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
236static 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, &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
259static 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, &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
286static 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
299static 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
311static 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
323static 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
510static 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
531static 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
544static 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 */
688static 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 */
728static 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 -- */
748static 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
766static 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
775static void sd_stop0(struct gspca_dev *gspca_dev)
776{
777}
778
779static void sd_close(struct gspca_dev *gspca_dev)
780{
781}
782
783static 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
793static 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
807static 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
817static 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
831static __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
844static 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
861static 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
893static 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
930static 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
940static 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
949static 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
959static 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
968static 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
978static 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
987static 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
999static 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 */
1008static 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
1023static __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
1029MODULE_DEVICE_TABLE(usb, device_table);
1030
1031/* -- device connect -- */
1032static 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
1039static 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 -- */
1047static 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
1055static void __exit sd_mod_exit(void)
1056{
1057 usb_deregister(&sd_driver);
1058 PDEBUG(D_PROBE, "deregistered");
1059}
1060
1061module_init(sd_mod_init);
1062module_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
44MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>"); 44MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
45MODULE_DESCRIPTION("GSPCA USB Camera Driver"); 45MODULE_DESCRIPTION("GSPCA USB Camera Driver");
46MODULE_LICENSE("GPL"); 46MODULE_LICENSE("GPL");
47 47
48#define DRIVER_VERSION_NUMBER KERNEL_VERSION(0, 2, 15) 48#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0)
49static const char version[] = "0.2.15"; 49static const char version[] = "2.1.0";
50 50
51static int video_nr = -1; 51static int video_nr = -1;
52 52
53static int comp_fac = 30; /* Buffer size ratio when compressed in % */ 53static int comp_fac = 30; /* Buffer size ratio when compressed in % */
54 54
55#ifdef GSPCA_DEBUG 55#ifdef VIDEO_ADV_DEBUG
56int gspca_debug = D_ERR | D_PROBE; 56int gspca_debug = D_ERR | D_PROBE;
57EXPORT_SYMBOL(gspca_debug); 57EXPORT_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
91static int autostart = 4;
92module_param(autostart, int, 0644);
93MODULE_PARM_DESC(autostart,
94 "Automatically start the helper process");
95
96/* try to start the helper process */
97static 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 */
123static __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};
131static __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 */
141struct 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
150static 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
168static 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
192static 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
243static 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;
283out:
284 mutex_unlock(&gspca_dev->queue_lock);
285 return cnt;
286}
287
288static 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};
296static 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 */
393static void isoc_irq_mmap(struct urb *urb) 181static 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
403static void isoc_irq_user(struct urb *urb) 192static 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)
459struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev, 249struct 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)
581static __u32 get_v4l2_depth(__u32 pixfmt) 358static __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
609static int gspca_get_buff_size(struct gspca_dev *gspca_dev) 389static 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;
1260out: 929out:
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 */
1373static int vidioc_queryctrl(struct file *file, void *priv, 1027static 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
1343static 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
1681static int vidiocgmbuf(struct file *file, void *priv, 1350static 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 -- */
2310static int __init gspca_init(void) 1982static 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}
2324static void __exit gspca_exit(void) 1987static 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
2332module_init(gspca_init); 1992module_init(gspca_init);
2333module_exit(gspca_exit); 1993module_exit(gspca_exit);
2334 1994
1995#ifdef VIDEO_ADV_DEBUG
2335module_param_named(debug, gspca_debug, int, 0644); 1996module_param_named(debug, gspca_debug, int, 0644);
2336MODULE_PARM_DESC(debug, 1997MODULE_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
2341module_param(comp_fac, int, 0644); 2002module_param(comp_fac, int, 0644);
2342MODULE_PARM_DESC(comp_fac, 2003MODULE_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 */
14extern int gspca_debug; 33extern 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 *);
80typedef void (*cam_pkt_op) (struct gspca_dev *gspca_dev, 99typedef 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
85struct ctrl { 104struct ctrl {
@@ -116,8 +135,8 @@ struct sd_desc {
116#define LAST_PACKET 3 135#define LAST_PACKET 3
117 136
118struct gspca_frame { 137struct 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);
176struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev, 195struct 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)
28static const char version[] = "2.1.0";
29
30MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
31MODULE_DESCRIPTION("GSPCA/Mars USB Camera Driver");
32MODULE_LICENSE("GPL");
33
34/* specific webcam descriptor */
35struct 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 */
42static struct ctrl sd_ctrls[] = {
43};
44
45static 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 */
51enum {
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
81static 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
100static 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 */
128static 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 */
144static int sd_open(struct gspca_dev *gspca_dev)
145{
146 return 0;
147}
148
149static 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
344static 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
356static void sd_stop0(struct gspca_dev *gspca_dev)
357{
358}
359
360static void sd_close(struct gspca_dev *gspca_dev)
361{
362}
363
364static 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 */
404static 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
419static __devinitdata struct usb_device_id device_table[] = {
420 {USB_DEVICE(0x093a, 0x050f), DVNM("Mars-Semi Pc-Camera")},
421 {}
422};
423MODULE_DEVICE_TABLE(usb, device_table);
424
425/* -- device connect -- */
426static 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
433static 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 -- */
441static 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}
448static void __exit sd_mod_exit(void)
449{
450 usb_deregister(&sd_driver);
451 PDEBUG(D_PROBE, "deregistered");
452}
453
454module_init(sd_mod_init);
455module_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)
28static const char version[] = "2.1.0";
29
30MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
31MODULE_DESCRIPTION("OV519 USB Camera Driver");
32MODULE_LICENSE("GPL");
33
34/* global parameters */
35static 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..." */
39static int i2c_detect_tries = 10;
40
41/* ov519 device descriptor */
42struct 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 */
77static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
78static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
79static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
80static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
81static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
82static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
83
84static 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
129static struct cam_mode vga_mode[] = {
130 {V4L2_PIX_FMT_JPEG, 320, 240},
131 {V4L2_PIX_FMT_JPEG, 640, 480},
132};
133static 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
248struct 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
258static 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 */
266static 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 */
285static 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 */
304static 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 */
329static 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 */
354static 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 */
389static 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 */
417static 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 */
436static 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). */
445static 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 */
459static 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. */
493static 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 */
510static 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
521struct ov_regvals {
522 __u8 reg;
523 __u8 val;
524};
525struct ov_i2c_regvals {
526 __u8 reg;
527 __u8 val;
528};
529
530static 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
545static 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 */
569static 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 */
695static 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. */
1075static 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 */
1267static 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 */
1280static 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;
1371error:
1372 PDEBUG(D_ERR, "OV519 Config failed");
1373 return -EBUSY;
1374}
1375
1376/* this function is called at open time */
1377static 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 */
1389static 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
1560static 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
1678static 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
1817static 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 -- */
1847static 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;
1866out:
1867 PDEBUG(D_ERR, "camera start error:%d", ret);
1868}
1869
1870static 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
1876static void sd_stop0(struct gspca_dev *gspca_dev)
1877{
1878}
1879
1880static void sd_close(struct gspca_dev *gspca_dev)
1881{
1882}
1883
1884static 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
1930static 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
1966static 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
2016static 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
2055static 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
2064static 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
2072static 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
2081static 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
2089static 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
2098static 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 */
2107static 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
2122static __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
2139MODULE_DEVICE_TABLE(usb, device_table);
2140
2141/* -- device connect -- */
2142static 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
2149static 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 -- */
2157static 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}
2164static void __exit sd_mod_exit(void)
2165{
2166 usb_deregister(&sd_driver);
2167 PDEBUG(D_PROBE, "deregistered");
2168}
2169
2170module_init(sd_mod_init);
2171module_exit(sd_mod_exit);
2172
2173module_param(frame_rate, int, 0644);
2174MODULE_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)
31static const char version[] = "0.2.15"; 31static const char version[] = "2.1.0";
32 32
33MODULE_AUTHOR("Hans de Goede <j.w.r.degoede@hhs.nl>"); 33MODULE_AUTHOR("Hans de Goede <j.w.r.degoede@hhs.nl>");
34MODULE_DESCRIPTION("Pixart PAC207"); 34MODULE_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)
27static const char version[] = "2.1.0";
28
29MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li");
30MODULE_DESCRIPTION("Pixart PAC7311");
31MODULE_LICENSE("GPL");
32
33/* specific webcam descriptor */
34struct 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 */
51static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
52static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
53static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
54static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
55static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
56static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
57static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
58static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
59
60static 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
119static 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
127const 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
197static 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
211static 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
223static 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 */
234static 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
266static 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
281static 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
292static 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 */
304static 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
310static 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
433static 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
449static void sd_stop0(struct gspca_dev *gspca_dev)
450{
451}
452
453/* this function is called at close time */
454static 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
470static 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
496static 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
605static 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
617static 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
627static 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
636static 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
646static 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
655static 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
665static 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
674static 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
688static 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 */
697static 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
712static __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};
722MODULE_DEVICE_TABLE(usb, device_table);
723
724/* -- device connect -- */
725static 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
732static 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 -- */
740static 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}
747static void __exit sd_mod_exit(void)
748{
749 usb_deregister(&sd_driver);
750 PDEBUG(D_PROBE, "deregistered");
751}
752
753module_init(sd_mod_init);
754module_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)
28static const char version[] = "2.1.0";
29
30MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
31MODULE_DESCRIPTION("GSPCA/SN9C102 USB Camera Driver");
32MODULE_LICENSE("GPL");
33
34/* specific webcam descriptor */
35struct 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 */
62static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
63static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
64static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
65static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
66
67static 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 */
99static 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};
104static struct cam_mode sif_mode[] = {
105 {V4L2_PIX_FMT_SN9C10X, 176, 144, 1},
106 {V4L2_PIX_FMT_SN9C10X, 352, 288, 0},
107};
108
109static const __u8 probe_ov7630[] = {0x08, 0x44};
110
111static 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};
118static 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};
125static 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};
131static 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};
171static 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};
179static 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};
187static 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};
208static 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};
215static 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
226static 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 */
234static 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};
262static 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};
269static 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
293static 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};
300static 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
306static 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};
313static 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
321static 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
334static 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
349static 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
365static 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
377static 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;
457err:
458 PDEBUG(D_ERR, "i2c error brightness");
459}
460static 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 */
476static 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 */
549static 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
559static 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 -- */
577static 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, &reg01, 1);
658 /* reg 0x17 SensorClk enable inv Clk 0x60 */
659 reg_w(dev, 0x17, &reg17, 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, &reg17_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, &reg17_19[0], 1);
715 /*MCKSIZE ->3 */ /*fixme: not ov7630*/
716 reg_w(dev, 0x19, &reg17_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, &reg17_19[1], 2);
723 msleep(20);
724
725 setcontrast(gspca_dev);
726 setbrightness(gspca_dev);
727}
728
729static 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
737static void sd_stop0(struct gspca_dev *gspca_dev)
738{
739}
740
741static void sd_close(struct gspca_dev *gspca_dev)
742{
743}
744
745static 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
776static 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
786static 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
794static 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
804static 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 */
813static 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
828static __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};
847MODULE_DEVICE_TABLE(usb, device_table);
848
849/* -- device connect -- */
850static 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
857static 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 -- */
865static 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}
872static void __exit sd_mod_exit(void)
873{
874 usb_deregister(&sd_driver);
875 PDEBUG(D_PROBE, "deregistered");
876}
877
878module_init(sd_mod_init);
879module_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)
28static const char version[] = "2.1.0";
29
30MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
31MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver");
32MODULE_LICENSE("GPL");
33
34/* specific webcam descriptor */
35struct 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 */
67static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
68static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
69static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
70static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
71static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
72static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
73static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
74static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
75
76static 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
135static 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 */
142static __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
153static __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
164static __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
177static __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
183static __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 */
195static __u8 *sn_tb[] = {
196 sn_hv7131,
197 sn_mi0360,
198 sn_mo4000,
199 sn_ov7648,
200 sn_ov7660
201};
202
203static __u8 regsn20[] = {
204 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
205 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
206};
207static __u8 regsn20_sn9c325[] = {
208 0x0a, 0x3a, 0x56, 0x6c, 0x7e, 0x8d, 0x9a, 0xa4,
209 0xaf, 0xbb, 0xc5, 0xcd, 0xd5, 0xde, 0xe8, 0xed, 0xf5
210};
211
212static __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};
218static __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
224static __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};
255static __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};
309static __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};
332static __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
428static __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
484static __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
503static 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
516static 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 */
531static 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 */
551static 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 */
558static 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
580static 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, &reg02, 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
611static 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, &regF1, 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
687static 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
701static 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
712static 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
723static 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
734static 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 */
746static 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 */
974static 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, &regF1, 1);
985 reg_r(dev, 0x00, &regF1, 1); /* -> regF1 = 0x00 */
986 reg_w(dev, 0xf1, &regF1, 1);
987 reg_r(dev, 0x00, &regF1, 1);
988 switch (sd->customid) {
989 case SN9C102P:
990 if (regF1 != 0x11)
991 return -ENODEV;
992 reg_w(dev, 0x02, &regGpio[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, &regGpio[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, &regGpio[1], 1);
1017 break;
1018 }
1019
1020 regF1 = 0x01;
1021 reg_w(dev, 0xf1, &regF1, 1);
1022
1023 return 0;
1024}
1025
1026static 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
1089static 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
1120static 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
1135static 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 -- */
1150static 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, &reg17, 1);
1296 reg_w(dev, 0x01, &reg1, 1);
1297 setbrightness(gspca_dev);
1298 setcontrast(gspca_dev);
1299}
1300
1301static 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, &regF1, 1);
1339}
1340
1341static void sd_stop0(struct gspca_dev *gspca_dev)
1342{
1343}
1344
1345static void sd_close(struct gspca_dev *gspca_dev)
1346{
1347}
1348
1349static 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
1384static 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
1430static 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
1465static 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
1485static 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
1495static 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
1504static 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
1514static 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
1522static 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
1532static 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
1540static 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
1552static 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 */
1561static 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
1576static __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};
1597MODULE_DEVICE_TABLE(usb, device_table);
1598
1599/* -- device connect -- */
1600static 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
1607static 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 -- */
1615static 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}
1622static void __exit sd_mod_exit(void)
1623{
1624 usb_deregister(&sd_driver);
1625 info("deregistered");
1626}
1627
1628module_init(sd_mod_init);
1629module_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)
28static const char version[] = "2.1.0";
29
30MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
31MODULE_DESCRIPTION("GSPCA/SPCA500 USB Camera Driver");
32MODULE_LICENSE("GPL");
33
34/* specific webcam descriptor */
35struct 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 */
65static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
66static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
67static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
68static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
69static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
70static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
71
72static 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
117static struct cam_mode vga_mode[] = {
118 {V4L2_PIX_FMT_JPEG, 320, 240, 1},
119 {V4L2_PIX_FMT_JPEG, 640, 480, 0},
120};
121
122static 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
142static __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};
167static __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
296static 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
317static 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
338static 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
360static 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
372static 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 */
390static 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 */
419static 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
433static 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
448static 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
473static 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
482static 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
508static 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
524static 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 */
555static 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;
578error:
579 return -EBUSY;
580}
581
582static 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 */
621static 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 */
744static 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
758static 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
959static 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
971static void sd_stop0(struct gspca_dev *gspca_dev)
972{
973}
974
975static void sd_close(struct gspca_dev *gspca_dev)
976{
977}
978
979static 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
1029static 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
1037static 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
1044static 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
1051static 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
1058static 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
1065static 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
1072static 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
1082static 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
1091static 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
1101static 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
1110static 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
1120static 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 */
1130static 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
1145static __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};
1163MODULE_DEVICE_TABLE(usb, device_table);
1164
1165/* -- device connect -- */
1166static 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
1173static 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 -- */
1181static 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}
1188static void __exit sd_mod_exit(void)
1189{
1190 usb_deregister(&sd_driver);
1191 PDEBUG(D_PROBE, "deregistered");
1192}
1193
1194module_init(sd_mod_init);
1195module_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)
27static const char version[] = "2.1.0";
28
29MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
30MODULE_DESCRIPTION("GSPCA/SPCA501 USB Camera Driver");
31MODULE_LICENSE("GPL");
32
33/* specific webcam descriptor */
34struct 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 */
52static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
53static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
54static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
55static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
56static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
57static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
58
59static 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
104static 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 */
154static __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) */
260static __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 */
547static __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 */
642static __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
664static __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 */
1598static __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 */
1649static __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
1799static 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 */
1817static 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
1841static 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
1860static 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
1869static 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
1878static 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
1888static void getcontrast(struct gspca_dev *gspca_dev)
1889{
1890/* spca50x->contrast = 0xaa01; */
1891}
1892
1893static 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
1900static 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 */
1910static 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;
1995error:
1996 return -EINVAL;
1997}
1998
1999/* this function is called at open time */
2000static 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
2027static 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
2061static 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
2068static void sd_stop0(struct gspca_dev *gspca_dev)
2069{
2070}
2071
2072/* this function is called at close time */
2073static void sd_close(struct gspca_dev *gspca_dev)
2074{
2075 reg_write(gspca_dev->dev, SPCA501_REG_CTLRL, 0x05, 0x00);
2076}
2077
2078static 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
2104static 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
2114static 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
2123static 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
2133static 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
2142static 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
2152static 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 */
2162static 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
2177static __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};
2187MODULE_DEVICE_TABLE(usb, device_table);
2188
2189/* -- device connect -- */
2190static 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
2197static 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 -- */
2205static 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}
2212static void __exit sd_mod_exit(void)
2213{
2214 usb_deregister(&sd_driver);
2215 PDEBUG(D_PROBE, "deregistered");
2216}
2217
2218module_init(sd_mod_init);
2219module_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)
27static const char version[] = "2.1.0";
28
29MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
30MODULE_DESCRIPTION("GSPCA/SPCA505 USB Camera Driver");
31MODULE_LICENSE("GPL");
32
33/* specific webcam descriptor */
34struct 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 */
49static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
50static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
51
52static 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
69static 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 */
94static __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 */
133static __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 */
322static __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 */
386static __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
558static 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 */
576static 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
601static 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 */
621static 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 */
670static 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
702static 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
749static 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
755static void sd_stop0(struct gspca_dev *gspca_dev)
756{
757}
758
759/* this function is called at close time */
760static 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) */
771static 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
802static 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
843static 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}
852static 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
861static 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
871static 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 */
881static 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
896static __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};
901MODULE_DEVICE_TABLE(usb, device_table);
902
903/* -- device connect -- */
904static 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
911static 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 -- */
919static 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}
926static void __exit sd_mod_exit(void)
927{
928 usb_deregister(&sd_driver);
929 PDEBUG(D_PROBE, "deregistered");
930}
931
932module_init(sd_mod_init);
933module_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)
29static const char version[] = "2.1.0";
30
31MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
32MODULE_DESCRIPTION("GSPCA/SPCA506 USB Camera Driver");
33MODULE_LICENSE("GPL");
34
35/* specific webcam descriptor */
36struct 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 */
52static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
53static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
54static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
55static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
56static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
57static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
58static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val);
59static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val);
60
61static 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
120static 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
136static 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
150static 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
163static void spca506_Initi2c(struct gspca_dev *gspca_dev)
164{
165 reg_w(gspca_dev->dev, 0x07, SAA7113_I2C_BASE_WRITE, 0x0004);
166}
167
168static 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
183static 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
203static 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
244static 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
256static 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 */
288static 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 */
307static 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
415static 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
545static 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
554static void sd_stop0(struct gspca_dev *gspca_dev)
555{
556}
557
558static void sd_close(struct gspca_dev *gspca_dev)
559{
560}
561
562/* convert YYUV per line to YUYV (YUV 4:2:2) */
563static 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
594static 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
635static 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
644static 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
651static 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
660static 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
667static 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
676static 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
683static 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
692static 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
699static 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
709static 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
718static 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
728static 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
737static 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
747static 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
756static 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
766static 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 */
776static 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
791static __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};
798MODULE_DEVICE_TABLE(usb, device_table);
799
800/* -- device connect -- */
801static 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
808static 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 -- */
816static 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}
823static void __exit sd_mod_exit(void)
824{
825 usb_deregister(&sd_driver);
826 PDEBUG(D_PROBE, "deregistered");
827}
828
829module_init(sd_mod_init);
830module_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)
26static const char version[] = "2.1.0";
27
28MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
29MODULE_DESCRIPTION("GSPCA/SPCA508 USB Camera Driver");
30MODULE_LICENSE("GPL");
31
32/* specific webcam descriptor */
33struct 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 */
52static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
53static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
54
55static 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
72static 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 */
95static __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 */
587static __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
671static __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
755static __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 */
1102static __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
1402static 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 */
1421static 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
1443static 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 */
1459static 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 */
1565static int sd_open(struct gspca_dev *gspca_dev)
1566{
1567/* write_vector(gspca_dev, spca508_open_data); */
1568 return 0;
1569}
1570
1571static 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
1591static 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
1597static void sd_stop0(struct gspca_dev *gspca_dev)
1598{
1599}
1600
1601/* this function is called at close time */
1602static void sd_close(struct gspca_dev *gspca_dev)
1603{
1604}
1605
1606/* convert YUVY per line to YUYV (YUV 4:2:2) */
1607static 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
1638static 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
1679static 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
1691static 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
1698static 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
1708static 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 */
1718static 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
1733static __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};
1742MODULE_DEVICE_TABLE(usb, device_table);
1743
1744/* -- device connect -- */
1745static 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
1752static 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 -- */
1760static 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}
1767static void __exit sd_mod_exit(void)
1768{
1769 usb_deregister(&sd_driver);
1770 PDEBUG(D_PROBE, "deregistered");
1771}
1772
1773module_init(sd_mod_init);
1774module_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)
28static const char version[] = "2.1.0";
29
30MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
31MODULE_DESCRIPTION("GSPCA/SPCA561 USB Camera Driver");
32MODULE_LICENSE("GPL");
33
34/* specific webcam descriptor */
35struct 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 */
48static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
49static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
50static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
51static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
52static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
53static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
54
55static 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
100static 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
133enum {
134 Rev072A = 0,
135 Rev012A,
136};
137
138static 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
151static 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
163static 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
173static 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
183static 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
189static 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
208static 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
230static __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
427static 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 ********************/
440static __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};
455static __u16 Pb100_2map8300[][2] = {
456 /* reg, value */
457 {0x8339, 0x0000},
458 {0x8307, 0x00aa},
459 {}
460};
461
462static __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};
470static __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
515static 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}
528static 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 */
538static 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 */
597static 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
615static 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
646static 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
706static void sd_stopN(struct gspca_dev *gspca_dev)
707{
708 reg_w_val(gspca_dev->dev, 0x8112, 0x20);
709}
710
711static void sd_stop0(struct gspca_dev *gspca_dev)
712{
713}
714
715/* this function is called at close time */
716static void sd_close(struct gspca_dev *gspca_dev)
717{
718 reg_w_val(gspca_dev->dev, 0x8114, 0);
719}
720
721static 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
787static 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
827static 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
847static 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
873static 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
900static 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
910static 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
919static 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
929static 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
938static 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
950static 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 */
959static 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
974static __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
993MODULE_DEVICE_TABLE(usb, device_table);
994
995/* -- device connect -- */
996static 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
1003static 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 -- */
1011static 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}
1018static void __exit sd_mod_exit(void)
1019{
1020 usb_deregister(&sd_driver);
1021 PDEBUG(D_PROBE, "deregistered");
1022}
1023
1024module_init(sd_mod_init);
1025module_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)
27static const char version[] = "0.2.7"; 27static const char version[] = "2.1.0";
28 28
29MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>"); 29MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
30MODULE_DESCRIPTION("Syntek DV4000 (STK014) USB Camera Driver"); 30MODULE_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 */
43static int lightfreq = 50;
44static int sd_quant = 7; /* <= 4 KO - 7: good (enough!) */ 44static 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);
50static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); 50static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
51static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); 51static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
52static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); 52static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
53static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
54static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
53 55
54static struct ctrl sd_ctrls[] = { 56static 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
99static struct cam_mode vga_mode[] = { 115static 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 -- */
105static int reg_read(struct gspca_dev *gspca_dev, 121static 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 -- */
124static int reg_write(struct gspca_dev *gspca_dev, 140static 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;
221ko: 237ko:
@@ -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
279static 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 */
268static int sd_config(struct gspca_dev *gspca_dev, 289static 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
496static 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
506static 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
514static 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 */
474static struct sd_desc sd_desc = { 533static 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)
524module_init(sd_mod_init); 584module_init(sd_mod_init);
525module_exit(sd_mod_exit); 585module_exit(sd_mod_exit);
526 586
527module_param(lightfreq, int, 0644);
528MODULE_PARM_DESC(lightfreq, "Light frequency 50 or 60 Hz");
529module_param_named(quant, sd_quant, int, 0644); 587module_param_named(quant, sd_quant, int, 0644);
530MODULE_PARM_DESC(quant, "Quantization index (0..8)"); 588MODULE_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)
28static const char version[] = "2.1.0";
29
30MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
31MODULE_DESCRIPTION("GSPCA/SPCA5xx USB Camera Driver");
32MODULE_LICENSE("GPL");
33
34/* specific webcam descriptor */
35struct 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 */
61static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
62static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
63static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
64static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
65static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
66static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
67static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
68static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
69
70static 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
129static struct cam_mode vga_mode[] = {
130 {V4L2_PIX_FMT_JPEG, 320, 240, 2},
131 {V4L2_PIX_FMT_JPEG, 640, 480, 1},
132};
133
134static struct cam_mode custom_mode[] = {
135 {V4L2_PIX_FMT_JPEG, 320, 240, 2},
136 {V4L2_PIX_FMT_JPEG, 464, 480, 1},
137};
138
139static 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 */
159static __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 */
189static __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 */
198static __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 ? */
229static __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
376static 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 */
401static 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
423static 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
437static 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
451static 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
468static 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 */
490static 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
514static 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
533static 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
558static 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
575static 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
603static 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
617static 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
637static 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
650static 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
710static 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
724static 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
734static 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 */
769static 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 */
1014static 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
1118static 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
1201static 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
1235static void sd_stop0(struct gspca_dev *gspca_dev)
1236{
1237}
1238
1239static void sd_close(struct gspca_dev *gspca_dev)
1240{
1241}
1242
1243static 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
1343static 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
1362static 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
1383static 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
1402static 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
1421static 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
1440static 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
1459static 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
1469static 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
1478static 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
1488static 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
1497static 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
1507static 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
1516static 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
1524static 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 */
1533static 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
1548static __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};
1606MODULE_DEVICE_TABLE(usb, device_table);
1607
1608/* -- device connect -- */
1609static 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
1616static 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 -- */
1624static 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}
1631static void __exit sd_mod_exit(void)
1632{
1633 usb_deregister(&sd_driver);
1634 PDEBUG(D_PROBE, "deregistered");
1635}
1636
1637module_init(sd_mod_init);
1638module_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)
30static const char version[] = "2.1.0";
31
32struct 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
42MODULE_AUTHOR("Leandro Costantino <le_costantino@pixartargentina.com.ar>");
43MODULE_DESCRIPTION("GSPCA/T613 (JPEG Compliance) USB Camera Driver");
44MODULE_LICENSE("GPL");
45
46struct 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 */
62static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
63static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
64static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
65static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
66static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
67static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
68static int sd_setlowlight(struct gspca_dev *gspca_dev, __s32 val);
69static int sd_getlowlight(struct gspca_dev *gspca_dev, __s32 *val);
70static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val);
71static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val);
72static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
73static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
74static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
75static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
76static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val);
77static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val);
78static int sd_setflip(struct gspca_dev *gspca_dev, __s32 val);
79static int sd_getflip(struct gspca_dev *gspca_dev, __s32 *val);
80static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val);
81static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val);
82static int sd_querymenu(struct gspca_dev *gspca_dev,
83 struct v4l2_querymenu *menu);
84
85static 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
230static 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
243static 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 */
255unsigned 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
265unsigned 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
348static __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
356static 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
367static 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 */
379static 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
404static 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
519static 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
537static 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
551static 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
569static 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
583static 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
595static 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
611static 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
621static void setgamma(struct gspca_dev *gspca_dev)
622{
623}
624
625static 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
636static 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
646static 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
653static 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
663static 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
672static 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
682static 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
690static 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
700static 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
708static 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
718static 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
726static 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
736static 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
744static 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
754static 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
761static 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
771static 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
779static 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
789static 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......*/
798static 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
811static 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
819static 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
872static void sd_stopN(struct gspca_dev *gspca_dev)
873{
874}
875
876static void sd_stop0(struct gspca_dev *gspca_dev)
877{
878}
879
880static void sd_close(struct gspca_dev *gspca_dev)
881{
882}
883
884static 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
926static 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 */
953static int sd_open(struct gspca_dev *gspca_dev)
954{
955 init_default_parameters(gspca_dev);
956 return 0;
957}
958
959/* sub-driver description */
960static 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
976static __devinitdata struct usb_device_id device_table[] = {
977 {USB_DEVICE(0x17a1, 0x0128), DVNM("XPX Webcam")},
978 {}
979};
980
981MODULE_DEVICE_TABLE(usb, device_table);
982
983/* -- device connect -- */
984static 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
991static 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 -- */
999static 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}
1006static void __exit sd_mod_exit(void)
1007{
1008 usb_deregister(&sd_driver);
1009 PDEBUG(D_PROBE, "deregistered");
1010}
1011
1012module_init(sd_mod_init);
1013module_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)
26static const char version[] = "2.1.0";
27
28MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
29MODULE_DESCRIPTION("TV8532 USB Camera Driver");
30MODULE_LICENSE("GPL");
31
32/* specific webcam descriptor */
33struct 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 */
48static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
49static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
50static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
51static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
52
53static 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
84static 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
155static __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
163static 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
175static 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
186static 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, &reg, 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 */
225static 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
244static 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
276static 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
321static 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 */
339static 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
402static 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 -- */
417static 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
487static 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
496static void sd_stop0(struct gspca_dev *gspca_dev)
497{
498}
499
500static void sd_close(struct gspca_dev *gspca_dev)
501{
502}
503
504static 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
536static 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
611static void setcontrast(struct gspca_dev *gspca_dev)
612{
613}
614
615static 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
625static 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
633static 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
643static 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 */
652static 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
667static __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
676MODULE_DEVICE_TABLE(usb, device_table);
677
678/* -- device connect -- */
679static 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
686static 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 -- */
694static 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
702static void __exit sd_mod_exit(void)
703{
704 usb_deregister(&sd_driver);
705 PDEBUG(D_PROBE, "deregistered");
706}
707
708module_init(sd_mod_init);
709module_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)
28static const char version[] = "2.1.0";
29
30MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
31MODULE_DESCRIPTION("GSPCA/VC032X USB Camera Driver");
32MODULE_LICENSE("GPL");
33
34/* specific webcam descriptor */
35struct 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 */
55static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
56static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
57static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
58static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
59
60static 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
91static struct cam_mode vc0321_mode[] = {
92 {V4L2_PIX_FMT_YUYV, 320, 240, 1},
93 {V4L2_PIX_FMT_YUYV, 640, 480, 0},
94};
95static struct cam_mode vc0323_mode[] = {
96 {V4L2_PIX_FMT_JPEG, 320, 240, 1},
97 {V4L2_PIX_FMT_JPEG, 640, 480, 0},
98};
99
100static __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};
252static __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
326static __u8 mi1320_gamma[17] = {
327 0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8,
328 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff
329};
330static __u8 mi1320_matrix[9] = {
331 0x54, 0xda, 0x06, 0xf1, 0x50, 0xf4, 0xf7, 0xea, 0x52
332};
333static __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};
412static __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
481static __u8 po3130_gamma[17] = {
482 0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8,
483 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff
484};
485static __u8 po3130_matrix[9] = {
486 0x5f, 0xec, 0xf5, 0xf1, 0x5a, 0xf5, 0xf1, 0xec, 0x63
487};
488
489static __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};
572static __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
587static __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
673static __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};
679static __u8 hv7131r_matrix[9] = {
680 0x5f, 0xec, 0xf5, 0xf1, 0x5a, 0xf5, 0xf1, 0xec, 0x63
681};
682static __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
725static __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
780static __u8 ov7660_gamma[17] = {
781 0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8,
782 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff
783};
784static __u8 ov7660_matrix[9] = {
785 0x5a, 0xf0, 0xf6, 0xf3, 0x57, 0xf6, 0xf3, 0xef, 0x62
786};
787static __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};
845static __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
914static __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
921static __u8 ov7660_60HZ[][4] = {
922 {0x00, 0x3b, 0x00, 0xaa},
923 {0x00, 0x9e, 0x40, 0xaa},
924 {0x00, 0x13, 0xa7, 0xaa},
925 {}
926};
927
928static __u8 ov7660_NoFliker[][4] = {
929 {0x00, 0x13, 0x87, 0xaa},
930 {}
931};
932
933static __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
1061static __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
1193struct 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
1203static 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
1213static 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
1227static 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
1240static 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}
1279static 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
1311static __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
1343static 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
1353static 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
1387static 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 */
1397static 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 */
1498static int sd_open(struct gspca_dev *gspca_dev)
1499{
1500 return 0;
1501}
1502
1503static void setquality(struct gspca_dev *gspca_dev)
1504{
1505}
1506
1507static void setautogain(struct gspca_dev *gspca_dev)
1508{
1509}
1510
1511static 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
1522static 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
1645static 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
1654static 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 */
1662static 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
1674static 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
1699static 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
1709static 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
1717static 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
1727static 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
1735static 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 */
1757static 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
1773static __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};
1784MODULE_DEVICE_TABLE(usb, device_table);
1785
1786/* -- device connect -- */
1787static 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
1794static 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 -- */
1802static 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}
1809static void __exit sd_mod_exit(void)
1810{
1811 usb_deregister(&sd_driver);
1812 PDEBUG(D_PROBE, "deregistered");
1813}
1814
1815module_init(sd_mod_init);
1816module_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)
28static const char version[] = "0.2.13"; 28static const char version[] = "2.1.0";
29 29
30MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>, " 30MODULE_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>");
32MODULE_DESCRIPTION("GSPCA ZC03xx/VC3xx USB Camera Driver"); 32MODULE_DESCRIPTION("GSPCA ZC03xx/VC3xx USB Camera Driver");
33MODULE_LICENSE("GPL"); 33MODULE_LICENSE("GPL");
34 34
35static int lightfreq = 50;
36static int force_sensor = -1; 35static int force_sensor = -1;
37 36
38#include "jpeg.h" 37#include "jpeg.h"
@@ -41,10 +40,12 @@ static int force_sensor = -1;
41struct sd { 40struct 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);
79static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); 79static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
80static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); 80static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
81static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); 81static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
82static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val);
82static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val); 83static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val);
84static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
85static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
86static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
87static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
83 88
84static struct ctrl sd_ctrls[] = { 89static 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
290static struct usb_action cs2102_InitialScale[] = { 323static 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};
419static struct usb_action cs2102_50HZ[] = { 452static 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};
444static struct usb_action cs2102_50HZScale[] = { 477static 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};
469static struct usb_action cs2102_60HZ[] = { 502static 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};
494static struct usb_action cs2102_60HZScale[] = { 527static 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};
519static struct usb_action cs2102_NoFliker[] = { 552static 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};
544static struct usb_action cs2102_NoFlikerScale[] = { 577static 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
830static struct usb_action cs2102K_InitialScale[] = { 863static 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
1407static struct usb_action gc0305_Initial[] = { /* 640x480 */ 1440static 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};
1471static struct usb_action gc0305_InitialScale[] = { /* 320x240 */ 1504static 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};
1534static struct usb_action gc0305_50HZ[] = { 1567static 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};
1557static struct usb_action gc0305_60HZ[] = { 1590static 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
1581static struct usb_action gc0305_NoFliker[] = { 1614static 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
1750static struct usb_action hdcs2020xx_InitialScale[] = { 1783static 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};
1892static struct usb_action hdcs2020xb_Initial[] = { 1925static 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};
2024static struct usb_action hdcs2020xb_InitialScale[] = { 2057static 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};
2152static struct usb_action hdcs2020b_50HZ[] = { 2185static 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};
2173static struct usb_action hdcs2020b_60HZ[] = { 2206static 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};
2194static struct usb_action hdcs2020b_NoFliker[] = { 2227static 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
2216static struct usb_action hv7131bxx_Initial[] = { 2249static 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
2324static struct usb_action hv7131bxx_InitialScale[] = { 2357static 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
2430static struct usb_action hv7131cxx_Initial[] = { 2463static 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
2524static struct usb_action hv7131cxx_InitialScale[] = { 2557static 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
2625static struct usb_action icm105axx_Initial[] = { 2658static 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
2802static struct usb_action icm105axx_InitialScale[] = { 2835static 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};
2981static struct usb_action icm105a_50HZ[] = { 3014static 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};
3012static struct usb_action icm105a_50HZScale[] = { 3045static 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};
3045static struct usb_action icm105a_60HZ[] = { 3078static 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};
3076static struct usb_action icm105a_60HZScale[] = { 3109static 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};
3109static struct usb_action icm105a_NoFliker[] = { 3142static 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};
3140static struct usb_action icm105a_NoFlikerScale[] = { 3173static 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
3174static struct usb_action MC501CB_InitialScale[] = { 3207static 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
3294static struct usb_action MC501CB_Initial[] = { /* 320x240 */ 3327static 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
3413static struct usb_action MC501CB_50HZ[] = { 3446static 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
3430static struct usb_action MC501CB_50HZScale[] = { 3463static 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
3447static struct usb_action MC501CB_60HZ[] = { 3480static 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
3464static struct usb_action MC501CB_60HZScale[] = { 3497static 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
3481static struct usb_action MC501CB_NoFliker[] = { 3514static 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
3498static struct usb_action MC501CB_NoFlikerScale[] = { 3531static 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
3713static struct usb_action ov7630c_Initial[] = { 3746static 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
3873static struct usb_action ov7630c_InitialScale[] = { 3903static 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
4033static struct usb_action pas106b_Initial_com[] = { 4060static 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
4047static struct usb_action pas106b_Initial[] = { /* 176x144 */ 4074static 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
4168static struct usb_action pas106b_InitialScale[] = { /* 352x288 */ 4192static 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};
4294static struct usb_action pas106b_50HZ[] = { 4315static 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};
4310static struct usb_action pas106b_60HZ[] = { 4331static 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};
4326static struct usb_action pas106b_NoFliker[] = { 4347static 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 */
4344static struct usb_action pb03303x_Initial[] = { 4364static 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
4490static struct usb_action pb03303x_InitialScale[] = { 4510static 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};
4638static struct usb_action pb0330xx_Initial[] = { 4658static 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
4753static struct usb_action pb0330xx_InitialScale[] = { 4773static 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};
4866static struct usb_action pb0330_50HZ[] = { 4886static 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};
4882static struct usb_action pb0330_50HZScale[] = { 4902static 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};
4899static struct usb_action pb0330_60HZ[] = { 4919static 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};
4916static struct usb_action pb0330_60HZScale[] = { 4936static 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};
4933static struct usb_action pb0330_NoFliker[] = { 4953static 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};
4950static struct usb_action pb0330_NoFlikerScale[] = { 4970static 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
5122static struct usb_action PO2030_50HZ[] = { 5142static 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
5144static struct usb_action PO2030_60HZ[] = { 5164static 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
5166static struct usb_action PO2030_NoFliker[] = { 5186static 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
5381static struct usb_action tas5130CK_InitialScale[] = { 5401static 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
5589static struct usb_action tas5130cxx_Initial[] = { 5609static 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};
5678static struct usb_action tas5130cxx_InitialScale[] = { 5698static 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};
5768static struct usb_action tas5130cxx_50HZ[] = { 5788static 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};
5791static struct usb_action tas5130cxx_50HZScale[] = { 5811static 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};
5814static struct usb_action tas5130cxx_60HZ[] = { 5834static 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};
5837static struct usb_action tas5130cxx_60HZScale[] = { 5857static 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};
5860static struct usb_action tas5130cxx_NoFliker[] = { 5880static 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
5884static struct usb_action tas5130cxx_NoFlikerScale[] = { 5904static 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
5908static struct usb_action tas5130c_vf0250_Initial[] = { 5928static 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
5972static struct usb_action tas5130c_vf0250_InitialScale[] = { 5992static 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 */
6036static struct usb_action tas5130c_vf0250_50HZ[] = { 6056static 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
6181static void reg_r_i(struct usb_device *dev, 6201static 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
6654static void send_unknown(struct usb_device *dev, int sensor) 6643static 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
7325static void sd_pkt_scan(struct gspca_dev *gspca_dev, 7314static 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
7393static 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
7404static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val) 7403static 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
7411static 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
7421static 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
7429static 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
7439static 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
7447static 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
7412static struct sd_desc sd_desc = { 7468static 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)
7514module_init(sd_mod_init); 7571module_init(sd_mod_init);
7515module_exit(sd_mod_exit); 7572module_exit(sd_mod_exit);
7516 7573
7517module_param(lightfreq, int, 0644);
7518MODULE_PARM_DESC(lightfreq,
7519 "Light frequency banding filter: 50, 60 Hz or"
7520 " 0 to NoFliker (default=50)");
7521module_param(force_sensor, int, 0644); 7574module_param(force_sensor, int, 0644);
7522MODULE_PARM_DESC(force_sensor, 7575MODULE_PARM_DESC(force_sensor,
7523 "Force sensor. Only for experts!!!"); 7576 "Force sensor. Only for experts!!!");