2 * SPCA500 chip based cameras initialization data
4 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
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
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.
18 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
20 #define MODULE_NAME "spca500"
25 MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
26 MODULE_DESCRIPTION("GSPCA/SPCA500 USB Camera Driver");
27 MODULE_LICENSE("GPL");
31 /* specific webcam descriptor */
33 struct gspca_dev gspca_dev
; /* !! must be the first item */
37 #define AiptekPocketDV 1
39 #define CreativePCCam300 3
42 #define IntelPocketPCCamera 6
44 #define LogitechClickSmart310 8
45 #define LogitechClickSmart510 9
46 #define LogitechTraveler 10
47 #define MustekGsmart300 11
49 #define PalmPixDC85 13
50 #define ToptroIndus 14
52 u8 jpeg_hdr
[JPEG_HDR_SZ
];
55 static const struct v4l2_pix_format vga_mode
[] = {
56 {320, 240, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
58 .sizeimage
= 320 * 240 * 3 / 8 + 590,
59 .colorspace
= V4L2_COLORSPACE_JPEG
,
61 {640, 480, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
63 .sizeimage
= 640 * 480 * 3 / 8 + 590,
64 .colorspace
= V4L2_COLORSPACE_JPEG
,
68 static const struct v4l2_pix_format sif_mode
[] = {
69 {176, 144, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
71 .sizeimage
= 176 * 144 * 3 / 8 + 590,
72 .colorspace
= V4L2_COLORSPACE_JPEG
,
74 {352, 288, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
76 .sizeimage
= 352 * 288 * 3 / 8 + 590,
77 .colorspace
= V4L2_COLORSPACE_JPEG
,
81 /* Frame packet header offsets for the spca500 */
82 #define SPCA500_OFFSET_PADDINGLB 2
83 #define SPCA500_OFFSET_PADDINGHB 3
84 #define SPCA500_OFFSET_MODE 4
85 #define SPCA500_OFFSET_IMGWIDTH 5
86 #define SPCA500_OFFSET_IMGHEIGHT 6
87 #define SPCA500_OFFSET_IMGMODE 7
88 #define SPCA500_OFFSET_QTBLINDEX 8
89 #define SPCA500_OFFSET_FRAMSEQ 9
90 #define SPCA500_OFFSET_CDSPINFO 10
91 #define SPCA500_OFFSET_GPIO 11
92 #define SPCA500_OFFSET_AUGPIO 12
93 #define SPCA500_OFFSET_DATA 16
96 static const __u16 spca500_visual_defaults
[][3] = {
97 {0x00, 0x0003, 0x816b}, /* SSI not active sync with vsync,
99 * saturation/hue enable,
100 * brightness/contrast enable.
102 {0x00, 0x0000, 0x8167}, /* brightness = 0 */
103 {0x00, 0x0020, 0x8168}, /* contrast = 0 */
104 {0x00, 0x0003, 0x816b}, /* SSI not active sync with vsync,
105 * hue (H byte) = 0, saturation/hue enable,
106 * brightness/contrast enable.
107 * was 0x0003, now 0x0000.
109 {0x00, 0x0000, 0x816a}, /* hue (L byte) = 0 */
110 {0x00, 0x0020, 0x8169}, /* saturation = 0x20 */
111 {0x00, 0x0050, 0x8157}, /* edge gain high threshold */
112 {0x00, 0x0030, 0x8158}, /* edge gain low threshold */
113 {0x00, 0x0028, 0x8159}, /* edge bandwidth high threshold */
114 {0x00, 0x000a, 0x815a}, /* edge bandwidth low threshold */
115 {0x00, 0x0001, 0x8202}, /* clock rate compensation = 1/25 sec/frame */
116 {0x0c, 0x0004, 0x0000},
120 static const __u16 Clicksmart510_defaults
[][3] = {
121 {0x00, 0x00, 0x8211},
122 {0x00, 0x01, 0x82c0},
123 {0x00, 0x10, 0x82cb},
124 {0x00, 0x0f, 0x800d},
125 {0x00, 0x82, 0x8225},
126 {0x00, 0x21, 0x8228},
127 {0x00, 0x00, 0x8203},
128 {0x00, 0x00, 0x8204},
129 {0x00, 0x08, 0x8205},
130 {0x00, 0xf8, 0x8206},
131 {0x00, 0x28, 0x8207},
132 {0x00, 0xa0, 0x8208},
133 {0x00, 0x08, 0x824a},
134 {0x00, 0x08, 0x8214},
135 {0x00, 0x80, 0x82c1},
136 {0x00, 0x00, 0x82c2},
137 {0x00, 0x00, 0x82ca},
138 {0x00, 0x80, 0x82c1},
139 {0x00, 0x04, 0x82c2},
140 {0x00, 0x00, 0x82ca},
141 {0x00, 0xfc, 0x8100},
142 {0x00, 0xfc, 0x8105},
143 {0x00, 0x30, 0x8101},
144 {0x00, 0x00, 0x8102},
145 {0x00, 0x00, 0x8103},
146 {0x00, 0x66, 0x8107},
147 {0x00, 0x00, 0x816b},
148 {0x00, 0x00, 0x8155},
149 {0x00, 0x01, 0x8156},
150 {0x00, 0x60, 0x8157},
151 {0x00, 0x40, 0x8158},
152 {0x00, 0x0a, 0x8159},
153 {0x00, 0x06, 0x815a},
154 {0x00, 0x00, 0x813f},
155 {0x00, 0x00, 0x8200},
156 {0x00, 0x19, 0x8201},
157 {0x00, 0x00, 0x82c1},
158 {0x00, 0xa0, 0x82c2},
159 {0x00, 0x00, 0x82ca},
160 {0x00, 0x00, 0x8117},
161 {0x00, 0x00, 0x8118},
162 {0x00, 0x65, 0x8119},
163 {0x00, 0x00, 0x811a},
164 {0x00, 0x00, 0x811b},
165 {0x00, 0x55, 0x811c},
166 {0x00, 0x65, 0x811d},
167 {0x00, 0x55, 0x811e},
168 {0x00, 0x16, 0x811f},
169 {0x00, 0x19, 0x8120},
170 {0x00, 0x80, 0x8103},
171 {0x00, 0x83, 0x816b},
172 {0x00, 0x25, 0x8168},
173 {0x00, 0x01, 0x820f},
174 {0x00, 0xff, 0x8115},
175 {0x00, 0x48, 0x8116},
176 {0x00, 0x50, 0x8151},
177 {0x00, 0x40, 0x8152},
178 {0x00, 0x78, 0x8153},
179 {0x00, 0x40, 0x8154},
180 {0x00, 0x00, 0x8167},
181 {0x00, 0x20, 0x8168},
182 {0x00, 0x00, 0x816a},
183 {0x00, 0x03, 0x816b},
184 {0x00, 0x20, 0x8169},
185 {0x00, 0x60, 0x8157},
186 {0x00, 0x00, 0x8190},
187 {0x00, 0x00, 0x81a1},
188 {0x00, 0x00, 0x81b2},
189 {0x00, 0x27, 0x8191},
190 {0x00, 0x27, 0x81a2},
191 {0x00, 0x27, 0x81b3},
192 {0x00, 0x4b, 0x8192},
193 {0x00, 0x4b, 0x81a3},
194 {0x00, 0x4b, 0x81b4},
195 {0x00, 0x66, 0x8193},
196 {0x00, 0x66, 0x81a4},
197 {0x00, 0x66, 0x81b5},
198 {0x00, 0x79, 0x8194},
199 {0x00, 0x79, 0x81a5},
200 {0x00, 0x79, 0x81b6},
201 {0x00, 0x8a, 0x8195},
202 {0x00, 0x8a, 0x81a6},
203 {0x00, 0x8a, 0x81b7},
204 {0x00, 0x9b, 0x8196},
205 {0x00, 0x9b, 0x81a7},
206 {0x00, 0x9b, 0x81b8},
207 {0x00, 0xa6, 0x8197},
208 {0x00, 0xa6, 0x81a8},
209 {0x00, 0xa6, 0x81b9},
210 {0x00, 0xb2, 0x8198},
211 {0x00, 0xb2, 0x81a9},
212 {0x00, 0xb2, 0x81ba},
213 {0x00, 0xbe, 0x8199},
214 {0x00, 0xbe, 0x81aa},
215 {0x00, 0xbe, 0x81bb},
216 {0x00, 0xc8, 0x819a},
217 {0x00, 0xc8, 0x81ab},
218 {0x00, 0xc8, 0x81bc},
219 {0x00, 0xd2, 0x819b},
220 {0x00, 0xd2, 0x81ac},
221 {0x00, 0xd2, 0x81bd},
222 {0x00, 0xdb, 0x819c},
223 {0x00, 0xdb, 0x81ad},
224 {0x00, 0xdb, 0x81be},
225 {0x00, 0xe4, 0x819d},
226 {0x00, 0xe4, 0x81ae},
227 {0x00, 0xe4, 0x81bf},
228 {0x00, 0xed, 0x819e},
229 {0x00, 0xed, 0x81af},
230 {0x00, 0xed, 0x81c0},
231 {0x00, 0xf7, 0x819f},
232 {0x00, 0xf7, 0x81b0},
233 {0x00, 0xf7, 0x81c1},
234 {0x00, 0xff, 0x81a0},
235 {0x00, 0xff, 0x81b1},
236 {0x00, 0xff, 0x81c2},
237 {0x00, 0x03, 0x8156},
238 {0x00, 0x00, 0x8211},
239 {0x00, 0x20, 0x8168},
240 {0x00, 0x01, 0x8202},
241 {0x00, 0x30, 0x8101},
242 {0x00, 0x00, 0x8111},
243 {0x00, 0x00, 0x8112},
244 {0x00, 0x00, 0x8113},
245 {0x00, 0x00, 0x8114},
249 static const __u8 qtable_creative_pccam
[2][64] = {
250 { /* Q-table Y-components */
251 0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12,
252 0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11,
253 0x04, 0x04, 0x05, 0x07, 0x0c, 0x11, 0x15, 0x11,
254 0x04, 0x05, 0x07, 0x09, 0x0f, 0x1a, 0x18, 0x13,
255 0x05, 0x07, 0x0b, 0x11, 0x14, 0x21, 0x1f, 0x17,
256 0x07, 0x0b, 0x11, 0x13, 0x18, 0x1f, 0x22, 0x1c,
257 0x0f, 0x13, 0x17, 0x1a, 0x1f, 0x24, 0x24, 0x1e,
258 0x16, 0x1c, 0x1d, 0x1d, 0x22, 0x1e, 0x1f, 0x1e},
259 { /* Q-table C-components */
260 0x05, 0x05, 0x07, 0x0e, 0x1e, 0x1e, 0x1e, 0x1e,
261 0x05, 0x06, 0x08, 0x14, 0x1e, 0x1e, 0x1e, 0x1e,
262 0x07, 0x08, 0x11, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
263 0x0e, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
264 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
265 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
266 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
267 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e}
270 static const __u8 qtable_kodak_ez200
[2][64] = {
271 { /* Q-table Y-components */
272 0x02, 0x01, 0x01, 0x02, 0x02, 0x04, 0x05, 0x06,
273 0x01, 0x01, 0x01, 0x02, 0x03, 0x06, 0x06, 0x06,
274 0x01, 0x01, 0x02, 0x02, 0x04, 0x06, 0x07, 0x06,
275 0x01, 0x02, 0x02, 0x03, 0x05, 0x09, 0x08, 0x06,
276 0x02, 0x02, 0x04, 0x06, 0x07, 0x0b, 0x0a, 0x08,
277 0x02, 0x04, 0x06, 0x06, 0x08, 0x0a, 0x0b, 0x09,
278 0x05, 0x06, 0x08, 0x09, 0x0a, 0x0c, 0x0c, 0x0a,
279 0x07, 0x09, 0x0a, 0x0a, 0x0b, 0x0a, 0x0a, 0x0a},
280 { /* Q-table C-components */
281 0x02, 0x02, 0x02, 0x05, 0x0a, 0x0a, 0x0a, 0x0a,
282 0x02, 0x02, 0x03, 0x07, 0x0a, 0x0a, 0x0a, 0x0a,
283 0x02, 0x03, 0x06, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
284 0x05, 0x07, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
285 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
286 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
287 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
288 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a}
291 static const __u8 qtable_pocketdv
[2][64] = {
292 { /* Q-table Y-components start registers 0x8800 */
293 0x06, 0x04, 0x04, 0x06, 0x0a, 0x10, 0x14, 0x18,
294 0x05, 0x05, 0x06, 0x08, 0x0a, 0x17, 0x18, 0x16,
295 0x06, 0x05, 0x06, 0x0a, 0x10, 0x17, 0x1c, 0x16,
296 0x06, 0x07, 0x09, 0x0c, 0x14, 0x23, 0x20, 0x19,
297 0x07, 0x09, 0x0f, 0x16, 0x1b, 0x2c, 0x29, 0x1f,
298 0x0a, 0x0e, 0x16, 0x1a, 0x20, 0x2a, 0x2d, 0x25,
299 0x14, 0x1a, 0x1f, 0x23, 0x29, 0x30, 0x30, 0x28,
300 0x1d, 0x25, 0x26, 0x27, 0x2d, 0x28, 0x29, 0x28,
302 { /* Q-table C-components start registers 0x8840 */
303 0x07, 0x07, 0x0a, 0x13, 0x28, 0x28, 0x28, 0x28,
304 0x07, 0x08, 0x0a, 0x1a, 0x28, 0x28, 0x28, 0x28,
305 0x0a, 0x0a, 0x16, 0x28, 0x28, 0x28, 0x28, 0x28,
306 0x13, 0x1a, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
307 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
308 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
309 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
310 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28}
313 /* read 'len' bytes to gspca_dev->usb_buf */
314 static void reg_r(struct gspca_dev
*gspca_dev
,
318 usb_control_msg(gspca_dev
->dev
,
319 usb_rcvctrlpipe(gspca_dev
->dev
, 0),
321 USB_DIR_IN
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
323 index
, gspca_dev
->usb_buf
, length
, 500);
326 static int reg_w(struct gspca_dev
*gspca_dev
,
327 __u16 req
, __u16 index
, __u16 value
)
331 PDEBUG(D_USBO
, "reg write: [0x%02x] = 0x%02x", index
, value
);
332 ret
= usb_control_msg(gspca_dev
->dev
,
333 usb_sndctrlpipe(gspca_dev
->dev
, 0),
335 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
336 value
, index
, NULL
, 0, 500);
338 pr_err("reg write: error %d\n", ret
);
342 /* returns: negative is error, pos or zero is data */
343 static int reg_r_12(struct gspca_dev
*gspca_dev
,
344 __u16 req
, /* bRequest */
345 __u16 index
, /* wIndex */
346 __u16 length
) /* wLength (1 or 2 only) */
350 gspca_dev
->usb_buf
[1] = 0;
351 ret
= usb_control_msg(gspca_dev
->dev
,
352 usb_rcvctrlpipe(gspca_dev
->dev
, 0),
354 USB_DIR_IN
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
357 gspca_dev
->usb_buf
, length
,
360 pr_err("reg_r_12 err %d\n", ret
);
363 return (gspca_dev
->usb_buf
[1] << 8) + gspca_dev
->usb_buf
[0];
367 * Simple function to wait for a given 8-bit value to be returned from
369 * Returns: negative is error or timeout, zero is success.
371 static int reg_r_wait(struct gspca_dev
*gspca_dev
,
372 __u16 reg
, __u16 index
, __u16 value
)
377 ret
= reg_r_12(gspca_dev
, reg
, index
, 1);
385 static int write_vector(struct gspca_dev
*gspca_dev
,
386 const __u16 data
[][3])
390 while (data
[i
][0] != 0 || data
[i
][1] != 0 || data
[i
][2] != 0) {
391 ret
= reg_w(gspca_dev
, data
[i
][0], data
[i
][2], data
[i
][1]);
399 static int spca50x_setup_qtable(struct gspca_dev
*gspca_dev
,
400 unsigned int request
,
403 const __u8 qtable
[2][64])
407 /* loop over y components */
408 for (i
= 0; i
< 64; i
++) {
409 err
= reg_w(gspca_dev
, request
, ybase
+ i
, qtable
[0][i
]);
414 /* loop over c components */
415 for (i
= 0; i
< 64; i
++) {
416 err
= reg_w(gspca_dev
, request
, cbase
+ i
, qtable
[1][i
]);
423 static void spca500_ping310(struct gspca_dev
*gspca_dev
)
425 reg_r(gspca_dev
, 0x0d04, 2);
426 PDEBUG(D_STREAM
, "ClickSmart310 ping 0x0d04 0x%02x 0x%02x",
427 gspca_dev
->usb_buf
[0], gspca_dev
->usb_buf
[1]);
430 static void spca500_clksmart310_init(struct gspca_dev
*gspca_dev
)
432 reg_r(gspca_dev
, 0x0d05, 2);
433 PDEBUG(D_STREAM
, "ClickSmart310 init 0x0d05 0x%02x 0x%02x",
434 gspca_dev
->usb_buf
[0], gspca_dev
->usb_buf
[1]);
435 reg_w(gspca_dev
, 0x00, 0x8167, 0x5a);
436 spca500_ping310(gspca_dev
);
438 reg_w(gspca_dev
, 0x00, 0x8168, 0x22);
439 reg_w(gspca_dev
, 0x00, 0x816a, 0xc0);
440 reg_w(gspca_dev
, 0x00, 0x816b, 0x0b);
441 reg_w(gspca_dev
, 0x00, 0x8169, 0x25);
442 reg_w(gspca_dev
, 0x00, 0x8157, 0x5b);
443 reg_w(gspca_dev
, 0x00, 0x8158, 0x5b);
444 reg_w(gspca_dev
, 0x00, 0x813f, 0x03);
445 reg_w(gspca_dev
, 0x00, 0x8151, 0x4a);
446 reg_w(gspca_dev
, 0x00, 0x8153, 0x78);
447 reg_w(gspca_dev
, 0x00, 0x0d01, 0x04);
448 /* 00 for adjust shutter */
449 reg_w(gspca_dev
, 0x00, 0x0d02, 0x01);
450 reg_w(gspca_dev
, 0x00, 0x8169, 0x25);
451 reg_w(gspca_dev
, 0x00, 0x0d01, 0x02);
454 static void spca500_setmode(struct gspca_dev
*gspca_dev
,
455 __u8 xmult
, __u8 ymult
)
459 /* set x multiplier */
460 reg_w(gspca_dev
, 0, 0x8001, xmult
);
462 /* set y multiplier */
463 reg_w(gspca_dev
, 0, 0x8002, ymult
);
465 /* use compressed mode, VGA, with mode specific subsample */
466 mode
= gspca_dev
->cam
.cam_mode
[(int) gspca_dev
->curr_mode
].priv
;
467 reg_w(gspca_dev
, 0, 0x8003, mode
<< 4);
470 static int spca500_full_reset(struct gspca_dev
*gspca_dev
)
474 /* send the reset command */
475 err
= reg_w(gspca_dev
, 0xe0, 0x0001, 0x0000);
479 /* wait for the reset to complete */
480 err
= reg_r_wait(gspca_dev
, 0x06, 0x0000, 0x0000);
483 err
= reg_w(gspca_dev
, 0xe0, 0x0000, 0x0000);
486 err
= reg_r_wait(gspca_dev
, 0x06, 0, 0);
488 PERR("reg_r_wait() failed");
495 /* Synchro the Bridge with sensor */
496 /* Maybe that will work on all spca500 chip */
497 /* because i only own a clicksmart310 try for that chip */
498 /* using spca50x_set_packet_size() cause an Ooops here */
499 /* usb_set_interface from kernel 2.6.x clear all the urb stuff */
500 /* up-port the same feature as in 2.4.x kernel */
501 static int spca500_synch310(struct gspca_dev
*gspca_dev
)
503 if (usb_set_interface(gspca_dev
->dev
, gspca_dev
->iface
, 0) < 0) {
504 PERR("Set packet size: set interface error");
507 spca500_ping310(gspca_dev
);
509 reg_r(gspca_dev
, 0x0d00, 1);
511 /* need alt setting here */
512 PDEBUG(D_PACK
, "ClickSmart310 sync alt: %d", gspca_dev
->alt
);
514 /* Windoze use pipe with altsetting 6 why 7 here */
515 if (usb_set_interface(gspca_dev
->dev
,
517 gspca_dev
->alt
) < 0) {
518 PERR("Set packet size: set interface error");
526 static void spca500_reinit(struct gspca_dev
*gspca_dev
)
531 /* some unknown command from Aiptek pocket dv and family300 */
533 reg_w(gspca_dev
, 0x00, 0x0d01, 0x01);
534 reg_w(gspca_dev
, 0x00, 0x0d03, 0x00);
535 reg_w(gspca_dev
, 0x00, 0x0d02, 0x01);
537 /* enable drop packet */
538 reg_w(gspca_dev
, 0x00, 0x850a, 0x0001);
540 err
= spca50x_setup_qtable(gspca_dev
, 0x00, 0x8800, 0x8840,
543 PERR("spca50x_setup_qtable failed on init");
545 /* set qtable index */
546 reg_w(gspca_dev
, 0x00, 0x8880, 2);
547 /* family cam Quicksmart stuff */
548 reg_w(gspca_dev
, 0x00, 0x800a, 0x00);
549 /* Set agc transfer: synced between frames */
550 reg_w(gspca_dev
, 0x00, 0x820f, 0x01);
551 /* Init SDRAM - needed for SDRAM access */
552 reg_w(gspca_dev
, 0x00, 0x870a, 0x04);
553 /*Start init sequence or stream */
554 reg_w(gspca_dev
, 0, 0x8003, 0x00);
555 /* switch to video camera mode */
556 reg_w(gspca_dev
, 0x00, 0x8000, 0x0004);
558 if (reg_r_wait(gspca_dev
, 0, 0x8000, 0x44) != 0) {
559 reg_r(gspca_dev
, 0x816b, 1);
560 Data
= gspca_dev
->usb_buf
[0];
561 reg_w(gspca_dev
, 0x00, 0x816b, Data
);
565 /* this function is called at probe time */
566 static int sd_config(struct gspca_dev
*gspca_dev
,
567 const struct usb_device_id
*id
)
569 struct sd
*sd
= (struct sd
*) gspca_dev
;
572 cam
= &gspca_dev
->cam
;
573 sd
->subtype
= id
->driver_info
;
574 if (sd
->subtype
!= LogitechClickSmart310
) {
575 cam
->cam_mode
= vga_mode
;
576 cam
->nmodes
= ARRAY_SIZE(vga_mode
);
578 cam
->cam_mode
= sif_mode
;
579 cam
->nmodes
= ARRAY_SIZE(sif_mode
);
584 /* this function is called at probe and resume time */
585 static int sd_init(struct gspca_dev
*gspca_dev
)
587 struct sd
*sd
= (struct sd
*) gspca_dev
;
589 /* initialisation of spca500 based cameras is deferred */
590 PDEBUG(D_STREAM
, "SPCA500 init");
591 if (sd
->subtype
== LogitechClickSmart310
)
592 spca500_clksmart310_init(gspca_dev
);
594 spca500_initialise(gspca_dev); */
595 PDEBUG(D_STREAM
, "SPCA500 init done");
599 static int sd_start(struct gspca_dev
*gspca_dev
)
601 struct sd
*sd
= (struct sd
*) gspca_dev
;
606 /* create the JPEG header */
607 jpeg_define(sd
->jpeg_hdr
, gspca_dev
->pixfmt
.height
,
608 gspca_dev
->pixfmt
.width
,
609 0x22); /* JPEG 411 */
610 jpeg_set_qual(sd
->jpeg_hdr
, QUALITY
);
612 if (sd
->subtype
== LogitechClickSmart310
) {
620 /* is there a sensor here ? */
621 reg_r(gspca_dev
, 0x8a04, 1);
622 PDEBUG(D_STREAM
, "Spca500 Sensor Address 0x%02x",
623 gspca_dev
->usb_buf
[0]);
624 PDEBUG(D_STREAM
, "Spca500 curr_mode: %d Xmult: 0x%02x, Ymult: 0x%02x",
625 gspca_dev
->curr_mode
, xmult
, ymult
);
628 switch (sd
->subtype
) {
629 case LogitechClickSmart310
:
630 spca500_setmode(gspca_dev
, xmult
, ymult
);
632 /* enable drop packet */
633 reg_w(gspca_dev
, 0x00, 0x850a, 0x0001);
634 reg_w(gspca_dev
, 0x00, 0x8880, 3);
635 err
= spca50x_setup_qtable(gspca_dev
,
636 0x00, 0x8800, 0x8840,
637 qtable_creative_pccam
);
639 PERR("spca50x_setup_qtable failed");
640 /* Init SDRAM - needed for SDRAM access */
641 reg_w(gspca_dev
, 0x00, 0x870a, 0x04);
643 /* switch to video camera mode */
644 reg_w(gspca_dev
, 0x00, 0x8000, 0x0004);
646 if (reg_r_wait(gspca_dev
, 0, 0x8000, 0x44) != 0)
647 PERR("reg_r_wait() failed");
649 reg_r(gspca_dev
, 0x816b, 1);
650 Data
= gspca_dev
->usb_buf
[0];
651 reg_w(gspca_dev
, 0x00, 0x816b, Data
);
653 spca500_synch310(gspca_dev
);
655 write_vector(gspca_dev
, spca500_visual_defaults
);
656 spca500_setmode(gspca_dev
, xmult
, ymult
);
657 /* enable drop packet */
658 err
= reg_w(gspca_dev
, 0x00, 0x850a, 0x0001);
660 PERR("failed to enable drop packet");
661 reg_w(gspca_dev
, 0x00, 0x8880, 3);
662 err
= spca50x_setup_qtable(gspca_dev
,
663 0x00, 0x8800, 0x8840,
664 qtable_creative_pccam
);
666 PERR("spca50x_setup_qtable failed");
668 /* Init SDRAM - needed for SDRAM access */
669 reg_w(gspca_dev
, 0x00, 0x870a, 0x04);
671 /* switch to video camera mode */
672 reg_w(gspca_dev
, 0x00, 0x8000, 0x0004);
674 if (reg_r_wait(gspca_dev
, 0, 0x8000, 0x44) != 0)
675 PERR("reg_r_wait() failed");
677 reg_r(gspca_dev
, 0x816b, 1);
678 Data
= gspca_dev
->usb_buf
[0];
679 reg_w(gspca_dev
, 0x00, 0x816b, Data
);
681 case CreativePCCam300
: /* Creative PC-CAM 300 640x480 CCD */
682 case IntelPocketPCCamera
: /* FIXME: Temporary fix for
683 * Intel Pocket PC Camera
684 * - NWG (Sat 29th March 2003) */
686 /* do a full reset */
687 err
= spca500_full_reset(gspca_dev
);
689 PERR("spca500_full_reset failed");
691 /* enable drop packet */
692 err
= reg_w(gspca_dev
, 0x00, 0x850a, 0x0001);
694 PERR("failed to enable drop packet");
695 reg_w(gspca_dev
, 0x00, 0x8880, 3);
696 err
= spca50x_setup_qtable(gspca_dev
,
697 0x00, 0x8800, 0x8840,
698 qtable_creative_pccam
);
700 PERR("spca50x_setup_qtable failed");
702 spca500_setmode(gspca_dev
, xmult
, ymult
);
703 reg_w(gspca_dev
, 0x20, 0x0001, 0x0004);
705 /* switch to video camera mode */
706 reg_w(gspca_dev
, 0x00, 0x8000, 0x0004);
708 if (reg_r_wait(gspca_dev
, 0, 0x8000, 0x44) != 0)
709 PERR("reg_r_wait() failed");
711 reg_r(gspca_dev
, 0x816b, 1);
712 Data
= gspca_dev
->usb_buf
[0];
713 reg_w(gspca_dev
, 0x00, 0x816b, Data
);
715 /* write_vector(gspca_dev, spca500_visual_defaults); */
717 case KodakEZ200
: /* Kodak EZ200 */
719 /* do a full reset */
720 err
= spca500_full_reset(gspca_dev
);
722 PERR("spca500_full_reset failed");
723 /* enable drop packet */
724 reg_w(gspca_dev
, 0x00, 0x850a, 0x0001);
725 reg_w(gspca_dev
, 0x00, 0x8880, 0);
726 err
= spca50x_setup_qtable(gspca_dev
,
727 0x00, 0x8800, 0x8840,
730 PERR("spca50x_setup_qtable failed");
731 spca500_setmode(gspca_dev
, xmult
, ymult
);
733 reg_w(gspca_dev
, 0x20, 0x0001, 0x0004);
735 /* switch to video camera mode */
736 reg_w(gspca_dev
, 0x00, 0x8000, 0x0004);
738 if (reg_r_wait(gspca_dev
, 0, 0x8000, 0x44) != 0)
739 PERR("reg_r_wait() failed");
741 reg_r(gspca_dev
, 0x816b, 1);
742 Data
= gspca_dev
->usb_buf
[0];
743 reg_w(gspca_dev
, 0x00, 0x816b, Data
);
745 /* write_vector(gspca_dev, spca500_visual_defaults); */
749 case DLinkDSC350
: /* FamilyCam 300 */
750 case AiptekPocketDV
: /* Aiptek PocketDV */
751 case Gsmartmini
: /*Mustek Gsmart Mini */
752 case MustekGsmart300
: /* Mustek Gsmart 300 */
757 spca500_reinit(gspca_dev
);
758 reg_w(gspca_dev
, 0x00, 0x0d01, 0x01);
759 /* enable drop packet */
760 reg_w(gspca_dev
, 0x00, 0x850a, 0x0001);
762 err
= spca50x_setup_qtable(gspca_dev
,
763 0x00, 0x8800, 0x8840, qtable_pocketdv
);
765 PERR("spca50x_setup_qtable failed");
766 reg_w(gspca_dev
, 0x00, 0x8880, 2);
768 /* familycam Quicksmart pocketDV stuff */
769 reg_w(gspca_dev
, 0x00, 0x800a, 0x00);
770 /* Set agc transfer: synced between frames */
771 reg_w(gspca_dev
, 0x00, 0x820f, 0x01);
772 /* Init SDRAM - needed for SDRAM access */
773 reg_w(gspca_dev
, 0x00, 0x870a, 0x04);
775 spca500_setmode(gspca_dev
, xmult
, ymult
);
776 /* switch to video camera mode */
777 reg_w(gspca_dev
, 0x00, 0x8000, 0x0004);
779 reg_r_wait(gspca_dev
, 0, 0x8000, 0x44);
781 reg_r(gspca_dev
, 0x816b, 1);
782 Data
= gspca_dev
->usb_buf
[0];
783 reg_w(gspca_dev
, 0x00, 0x816b, Data
);
785 case LogitechTraveler
:
786 case LogitechClickSmart510
:
787 reg_w(gspca_dev
, 0x02, 0x00, 0x00);
788 /* enable drop packet */
789 reg_w(gspca_dev
, 0x00, 0x850a, 0x0001);
791 err
= spca50x_setup_qtable(gspca_dev
,
793 0x8840, qtable_creative_pccam
);
795 PERR("spca50x_setup_qtable failed");
796 reg_w(gspca_dev
, 0x00, 0x8880, 3);
797 reg_w(gspca_dev
, 0x00, 0x800a, 0x00);
798 /* Init SDRAM - needed for SDRAM access */
799 reg_w(gspca_dev
, 0x00, 0x870a, 0x04);
801 spca500_setmode(gspca_dev
, xmult
, ymult
);
803 /* switch to video camera mode */
804 reg_w(gspca_dev
, 0x00, 0x8000, 0x0004);
805 reg_r_wait(gspca_dev
, 0, 0x8000, 0x44);
807 reg_r(gspca_dev
, 0x816b, 1);
808 Data
= gspca_dev
->usb_buf
[0];
809 reg_w(gspca_dev
, 0x00, 0x816b, Data
);
810 write_vector(gspca_dev
, Clicksmart510_defaults
);
816 static void sd_stopN(struct gspca_dev
*gspca_dev
)
818 reg_w(gspca_dev
, 0, 0x8003, 0x00);
820 /* switch to video camera mode */
821 reg_w(gspca_dev
, 0x00, 0x8000, 0x0004);
822 reg_r(gspca_dev
, 0x8000, 1);
823 PDEBUG(D_STREAM
, "stop SPCA500 done reg8000: 0x%2x",
824 gspca_dev
->usb_buf
[0]);
827 static void sd_pkt_scan(struct gspca_dev
*gspca_dev
,
828 u8
*data
, /* isoc packet */
829 int len
) /* iso packet length */
831 struct sd
*sd
= (struct sd
*) gspca_dev
;
833 static __u8 ffd9
[] = {0xff, 0xd9};
835 /* frames are jpeg 4.1.1 without 0xff escape */
836 if (data
[0] == 0xff) {
837 if (data
[1] != 0x01) { /* drop packet */
838 /* gspca_dev->last_packet_type = DISCARD_PACKET; */
841 gspca_frame_add(gspca_dev
, LAST_PACKET
,
844 /* put the JPEG header in the new frame */
845 gspca_frame_add(gspca_dev
, FIRST_PACKET
,
846 sd
->jpeg_hdr
, JPEG_HDR_SZ
);
848 data
+= SPCA500_OFFSET_DATA
;
849 len
-= SPCA500_OFFSET_DATA
;
855 /* add 0x00 after 0xff */
858 if (data
[i
] == 0xff) {
859 gspca_frame_add(gspca_dev
, INTER_PACKET
,
868 gspca_frame_add(gspca_dev
, INTER_PACKET
, data
, len
);
871 static void setbrightness(struct gspca_dev
*gspca_dev
, s32 val
)
873 reg_w(gspca_dev
, 0x00, 0x8167,
877 static void setcontrast(struct gspca_dev
*gspca_dev
, s32 val
)
879 reg_w(gspca_dev
, 0x00, 0x8168, val
);
882 static void setcolors(struct gspca_dev
*gspca_dev
, s32 val
)
884 reg_w(gspca_dev
, 0x00, 0x8169, val
);
887 static int sd_s_ctrl(struct v4l2_ctrl
*ctrl
)
889 struct gspca_dev
*gspca_dev
=
890 container_of(ctrl
->handler
, struct gspca_dev
, ctrl_handler
);
892 gspca_dev
->usb_err
= 0;
894 if (!gspca_dev
->streaming
)
898 case V4L2_CID_BRIGHTNESS
:
899 setbrightness(gspca_dev
, ctrl
->val
);
901 case V4L2_CID_CONTRAST
:
902 setcontrast(gspca_dev
, ctrl
->val
);
904 case V4L2_CID_SATURATION
:
905 setcolors(gspca_dev
, ctrl
->val
);
908 return gspca_dev
->usb_err
;
911 static const struct v4l2_ctrl_ops sd_ctrl_ops
= {
915 static int sd_init_controls(struct gspca_dev
*gspca_dev
)
917 struct v4l2_ctrl_handler
*hdl
= &gspca_dev
->ctrl_handler
;
919 gspca_dev
->vdev
.ctrl_handler
= hdl
;
920 v4l2_ctrl_handler_init(hdl
, 3);
921 v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
922 V4L2_CID_BRIGHTNESS
, 0, 255, 1, 127);
923 v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
924 V4L2_CID_CONTRAST
, 0, 63, 1, 31);
925 v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
926 V4L2_CID_SATURATION
, 0, 63, 1, 31);
929 pr_err("Could not initialize controls\n");
935 /* sub-driver description */
936 static const struct sd_desc sd_desc
= {
940 .init_controls
= sd_init_controls
,
943 .pkt_scan
= sd_pkt_scan
,
946 /* -- module initialisation -- */
947 static const struct usb_device_id device_table
[] = {
948 {USB_DEVICE(0x040a, 0x0300), .driver_info
= KodakEZ200
},
949 {USB_DEVICE(0x041e, 0x400a), .driver_info
= CreativePCCam300
},
950 {USB_DEVICE(0x046d, 0x0890), .driver_info
= LogitechTraveler
},
951 {USB_DEVICE(0x046d, 0x0900), .driver_info
= LogitechClickSmart310
},
952 {USB_DEVICE(0x046d, 0x0901), .driver_info
= LogitechClickSmart510
},
953 {USB_DEVICE(0x04a5, 0x300c), .driver_info
= BenqDC1016
},
954 {USB_DEVICE(0x04fc, 0x7333), .driver_info
= PalmPixDC85
},
955 {USB_DEVICE(0x055f, 0xc200), .driver_info
= MustekGsmart300
},
956 {USB_DEVICE(0x055f, 0xc220), .driver_info
= Gsmartmini
},
957 {USB_DEVICE(0x06bd, 0x0404), .driver_info
= AgfaCl20
},
958 {USB_DEVICE(0x06be, 0x0800), .driver_info
= Optimedia
},
959 {USB_DEVICE(0x084d, 0x0003), .driver_info
= DLinkDSC350
},
960 {USB_DEVICE(0x08ca, 0x0103), .driver_info
= AiptekPocketDV
},
961 {USB_DEVICE(0x2899, 0x012c), .driver_info
= ToptroIndus
},
962 {USB_DEVICE(0x8086, 0x0630), .driver_info
= IntelPocketPCCamera
},
965 MODULE_DEVICE_TABLE(usb
, device_table
);
967 /* -- device connect -- */
968 static int sd_probe(struct usb_interface
*intf
,
969 const struct usb_device_id
*id
)
971 return gspca_dev_probe(intf
, id
, &sd_desc
, sizeof(struct sd
),
975 static struct usb_driver sd_driver
= {
977 .id_table
= device_table
,
979 .disconnect
= gspca_disconnect
,
981 .suspend
= gspca_suspend
,
982 .resume
= gspca_resume
,
983 .reset_resume
= gspca_resume
,
987 module_usb_driver(sd_driver
);