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.
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
22 #define MODULE_NAME "spca500"
27 MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
28 MODULE_DESCRIPTION("GSPCA/SPCA500 USB Camera Driver");
29 MODULE_LICENSE("GPL");
31 /* specific webcam descriptor */
33 struct gspca_dev gspca_dev
; /* !! must be the first item */
35 unsigned char brightness
;
36 unsigned char contrast
;
39 #define QUALITY_MIN 70
40 #define QUALITY_MAX 95
41 #define QUALITY_DEF 85
45 #define AiptekPocketDV 1
47 #define CreativePCCam300 3
50 #define IntelPocketPCCamera 6
52 #define LogitechClickSmart310 8
53 #define LogitechClickSmart510 9
54 #define LogitechTraveler 10
55 #define MustekGsmart300 11
57 #define PalmPixDC85 13
58 #define ToptroIndus 14
63 /* V4L2 controls supported by the driver */
64 static int sd_setbrightness(struct gspca_dev
*gspca_dev
, __s32 val
);
65 static int sd_getbrightness(struct gspca_dev
*gspca_dev
, __s32
*val
);
66 static int sd_setcontrast(struct gspca_dev
*gspca_dev
, __s32 val
);
67 static int sd_getcontrast(struct gspca_dev
*gspca_dev
, __s32
*val
);
68 static int sd_setcolors(struct gspca_dev
*gspca_dev
, __s32 val
);
69 static int sd_getcolors(struct gspca_dev
*gspca_dev
, __s32
*val
);
71 static struct ctrl sd_ctrls
[] = {
74 .id
= V4L2_CID_BRIGHTNESS
,
75 .type
= V4L2_CTRL_TYPE_INTEGER
,
80 #define BRIGHTNESS_DEF 127
81 .default_value
= BRIGHTNESS_DEF
,
83 .set
= sd_setbrightness
,
84 .get
= sd_getbrightness
,
88 .id
= V4L2_CID_CONTRAST
,
89 .type
= V4L2_CTRL_TYPE_INTEGER
,
94 #define CONTRAST_DEF 31
95 .default_value
= CONTRAST_DEF
,
97 .set
= sd_setcontrast
,
98 .get
= sd_getcontrast
,
102 .id
= V4L2_CID_SATURATION
,
103 .type
= V4L2_CTRL_TYPE_INTEGER
,
109 .default_value
= COLOR_DEF
,
116 static const struct v4l2_pix_format vga_mode
[] = {
117 {320, 240, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
119 .sizeimage
= 320 * 240 * 3 / 8 + 590,
120 .colorspace
= V4L2_COLORSPACE_JPEG
,
122 {640, 480, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
124 .sizeimage
= 640 * 480 * 3 / 8 + 590,
125 .colorspace
= V4L2_COLORSPACE_JPEG
,
129 static const struct v4l2_pix_format sif_mode
[] = {
130 {176, 144, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
132 .sizeimage
= 176 * 144 * 3 / 8 + 590,
133 .colorspace
= V4L2_COLORSPACE_JPEG
,
135 {352, 288, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
137 .sizeimage
= 352 * 288 * 3 / 8 + 590,
138 .colorspace
= V4L2_COLORSPACE_JPEG
,
142 /* Frame packet header offsets for the spca500 */
143 #define SPCA500_OFFSET_PADDINGLB 2
144 #define SPCA500_OFFSET_PADDINGHB 3
145 #define SPCA500_OFFSET_MODE 4
146 #define SPCA500_OFFSET_IMGWIDTH 5
147 #define SPCA500_OFFSET_IMGHEIGHT 6
148 #define SPCA500_OFFSET_IMGMODE 7
149 #define SPCA500_OFFSET_QTBLINDEX 8
150 #define SPCA500_OFFSET_FRAMSEQ 9
151 #define SPCA500_OFFSET_CDSPINFO 10
152 #define SPCA500_OFFSET_GPIO 11
153 #define SPCA500_OFFSET_AUGPIO 12
154 #define SPCA500_OFFSET_DATA 16
157 static const __u16 spca500_visual_defaults
[][3] = {
158 {0x00, 0x0003, 0x816b}, /* SSI not active sync with vsync,
160 * saturation/hue enable,
161 * brightness/contrast enable.
163 {0x00, 0x0000, 0x8167}, /* brightness = 0 */
164 {0x00, 0x0020, 0x8168}, /* contrast = 0 */
165 {0x00, 0x0003, 0x816b}, /* SSI not active sync with vsync,
166 * hue (H byte) = 0, saturation/hue enable,
167 * brightness/contrast enable.
168 * was 0x0003, now 0x0000.
170 {0x00, 0x0000, 0x816a}, /* hue (L byte) = 0 */
171 {0x00, 0x0020, 0x8169}, /* saturation = 0x20 */
172 {0x00, 0x0050, 0x8157}, /* edge gain high threshold */
173 {0x00, 0x0030, 0x8158}, /* edge gain low threshold */
174 {0x00, 0x0028, 0x8159}, /* edge bandwidth high threshold */
175 {0x00, 0x000a, 0x815a}, /* edge bandwidth low threshold */
176 {0x00, 0x0001, 0x8202}, /* clock rate compensation = 1/25 sec/frame */
177 {0x0c, 0x0004, 0x0000},
181 static const __u16 Clicksmart510_defaults
[][3] = {
182 {0x00, 0x00, 0x8211},
183 {0x00, 0x01, 0x82c0},
184 {0x00, 0x10, 0x82cb},
185 {0x00, 0x0f, 0x800d},
186 {0x00, 0x82, 0x8225},
187 {0x00, 0x21, 0x8228},
188 {0x00, 0x00, 0x8203},
189 {0x00, 0x00, 0x8204},
190 {0x00, 0x08, 0x8205},
191 {0x00, 0xf8, 0x8206},
192 {0x00, 0x28, 0x8207},
193 {0x00, 0xa0, 0x8208},
194 {0x00, 0x08, 0x824a},
195 {0x00, 0x08, 0x8214},
196 {0x00, 0x80, 0x82c1},
197 {0x00, 0x00, 0x82c2},
198 {0x00, 0x00, 0x82ca},
199 {0x00, 0x80, 0x82c1},
200 {0x00, 0x04, 0x82c2},
201 {0x00, 0x00, 0x82ca},
202 {0x00, 0xfc, 0x8100},
203 {0x00, 0xfc, 0x8105},
204 {0x00, 0x30, 0x8101},
205 {0x00, 0x00, 0x8102},
206 {0x00, 0x00, 0x8103},
207 {0x00, 0x66, 0x8107},
208 {0x00, 0x00, 0x816b},
209 {0x00, 0x00, 0x8155},
210 {0x00, 0x01, 0x8156},
211 {0x00, 0x60, 0x8157},
212 {0x00, 0x40, 0x8158},
213 {0x00, 0x0a, 0x8159},
214 {0x00, 0x06, 0x815a},
215 {0x00, 0x00, 0x813f},
216 {0x00, 0x00, 0x8200},
217 {0x00, 0x19, 0x8201},
218 {0x00, 0x00, 0x82c1},
219 {0x00, 0xa0, 0x82c2},
220 {0x00, 0x00, 0x82ca},
221 {0x00, 0x00, 0x8117},
222 {0x00, 0x00, 0x8118},
223 {0x00, 0x65, 0x8119},
224 {0x00, 0x00, 0x811a},
225 {0x00, 0x00, 0x811b},
226 {0x00, 0x55, 0x811c},
227 {0x00, 0x65, 0x811d},
228 {0x00, 0x55, 0x811e},
229 {0x00, 0x16, 0x811f},
230 {0x00, 0x19, 0x8120},
231 {0x00, 0x80, 0x8103},
232 {0x00, 0x83, 0x816b},
233 {0x00, 0x25, 0x8168},
234 {0x00, 0x01, 0x820f},
235 {0x00, 0xff, 0x8115},
236 {0x00, 0x48, 0x8116},
237 {0x00, 0x50, 0x8151},
238 {0x00, 0x40, 0x8152},
239 {0x00, 0x78, 0x8153},
240 {0x00, 0x40, 0x8154},
241 {0x00, 0x00, 0x8167},
242 {0x00, 0x20, 0x8168},
243 {0x00, 0x00, 0x816a},
244 {0x00, 0x03, 0x816b},
245 {0x00, 0x20, 0x8169},
246 {0x00, 0x60, 0x8157},
247 {0x00, 0x00, 0x8190},
248 {0x00, 0x00, 0x81a1},
249 {0x00, 0x00, 0x81b2},
250 {0x00, 0x27, 0x8191},
251 {0x00, 0x27, 0x81a2},
252 {0x00, 0x27, 0x81b3},
253 {0x00, 0x4b, 0x8192},
254 {0x00, 0x4b, 0x81a3},
255 {0x00, 0x4b, 0x81b4},
256 {0x00, 0x66, 0x8193},
257 {0x00, 0x66, 0x81a4},
258 {0x00, 0x66, 0x81b5},
259 {0x00, 0x79, 0x8194},
260 {0x00, 0x79, 0x81a5},
261 {0x00, 0x79, 0x81b6},
262 {0x00, 0x8a, 0x8195},
263 {0x00, 0x8a, 0x81a6},
264 {0x00, 0x8a, 0x81b7},
265 {0x00, 0x9b, 0x8196},
266 {0x00, 0x9b, 0x81a7},
267 {0x00, 0x9b, 0x81b8},
268 {0x00, 0xa6, 0x8197},
269 {0x00, 0xa6, 0x81a8},
270 {0x00, 0xa6, 0x81b9},
271 {0x00, 0xb2, 0x8198},
272 {0x00, 0xb2, 0x81a9},
273 {0x00, 0xb2, 0x81ba},
274 {0x00, 0xbe, 0x8199},
275 {0x00, 0xbe, 0x81aa},
276 {0x00, 0xbe, 0x81bb},
277 {0x00, 0xc8, 0x819a},
278 {0x00, 0xc8, 0x81ab},
279 {0x00, 0xc8, 0x81bc},
280 {0x00, 0xd2, 0x819b},
281 {0x00, 0xd2, 0x81ac},
282 {0x00, 0xd2, 0x81bd},
283 {0x00, 0xdb, 0x819c},
284 {0x00, 0xdb, 0x81ad},
285 {0x00, 0xdb, 0x81be},
286 {0x00, 0xe4, 0x819d},
287 {0x00, 0xe4, 0x81ae},
288 {0x00, 0xe4, 0x81bf},
289 {0x00, 0xed, 0x819e},
290 {0x00, 0xed, 0x81af},
291 {0x00, 0xed, 0x81c0},
292 {0x00, 0xf7, 0x819f},
293 {0x00, 0xf7, 0x81b0},
294 {0x00, 0xf7, 0x81c1},
295 {0x00, 0xff, 0x81a0},
296 {0x00, 0xff, 0x81b1},
297 {0x00, 0xff, 0x81c2},
298 {0x00, 0x03, 0x8156},
299 {0x00, 0x00, 0x8211},
300 {0x00, 0x20, 0x8168},
301 {0x00, 0x01, 0x8202},
302 {0x00, 0x30, 0x8101},
303 {0x00, 0x00, 0x8111},
304 {0x00, 0x00, 0x8112},
305 {0x00, 0x00, 0x8113},
306 {0x00, 0x00, 0x8114},
310 static const __u8 qtable_creative_pccam
[2][64] = {
311 { /* Q-table Y-components */
312 0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12,
313 0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11,
314 0x04, 0x04, 0x05, 0x07, 0x0c, 0x11, 0x15, 0x11,
315 0x04, 0x05, 0x07, 0x09, 0x0f, 0x1a, 0x18, 0x13,
316 0x05, 0x07, 0x0b, 0x11, 0x14, 0x21, 0x1f, 0x17,
317 0x07, 0x0b, 0x11, 0x13, 0x18, 0x1f, 0x22, 0x1c,
318 0x0f, 0x13, 0x17, 0x1a, 0x1f, 0x24, 0x24, 0x1e,
319 0x16, 0x1c, 0x1d, 0x1d, 0x22, 0x1e, 0x1f, 0x1e},
320 { /* Q-table C-components */
321 0x05, 0x05, 0x07, 0x0e, 0x1e, 0x1e, 0x1e, 0x1e,
322 0x05, 0x06, 0x08, 0x14, 0x1e, 0x1e, 0x1e, 0x1e,
323 0x07, 0x08, 0x11, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
324 0x0e, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
325 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
326 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
327 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
328 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e}
331 static const __u8 qtable_kodak_ez200
[2][64] = {
332 { /* Q-table Y-components */
333 0x02, 0x01, 0x01, 0x02, 0x02, 0x04, 0x05, 0x06,
334 0x01, 0x01, 0x01, 0x02, 0x03, 0x06, 0x06, 0x06,
335 0x01, 0x01, 0x02, 0x02, 0x04, 0x06, 0x07, 0x06,
336 0x01, 0x02, 0x02, 0x03, 0x05, 0x09, 0x08, 0x06,
337 0x02, 0x02, 0x04, 0x06, 0x07, 0x0b, 0x0a, 0x08,
338 0x02, 0x04, 0x06, 0x06, 0x08, 0x0a, 0x0b, 0x09,
339 0x05, 0x06, 0x08, 0x09, 0x0a, 0x0c, 0x0c, 0x0a,
340 0x07, 0x09, 0x0a, 0x0a, 0x0b, 0x0a, 0x0a, 0x0a},
341 { /* Q-table C-components */
342 0x02, 0x02, 0x02, 0x05, 0x0a, 0x0a, 0x0a, 0x0a,
343 0x02, 0x02, 0x03, 0x07, 0x0a, 0x0a, 0x0a, 0x0a,
344 0x02, 0x03, 0x06, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
345 0x05, 0x07, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
346 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
347 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
348 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
349 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a}
352 static const __u8 qtable_pocketdv
[2][64] = {
353 { /* Q-table Y-components start registers 0x8800 */
354 0x06, 0x04, 0x04, 0x06, 0x0a, 0x10, 0x14, 0x18,
355 0x05, 0x05, 0x06, 0x08, 0x0a, 0x17, 0x18, 0x16,
356 0x06, 0x05, 0x06, 0x0a, 0x10, 0x17, 0x1c, 0x16,
357 0x06, 0x07, 0x09, 0x0c, 0x14, 0x23, 0x20, 0x19,
358 0x07, 0x09, 0x0f, 0x16, 0x1b, 0x2c, 0x29, 0x1f,
359 0x0a, 0x0e, 0x16, 0x1a, 0x20, 0x2a, 0x2d, 0x25,
360 0x14, 0x1a, 0x1f, 0x23, 0x29, 0x30, 0x30, 0x28,
361 0x1d, 0x25, 0x26, 0x27, 0x2d, 0x28, 0x29, 0x28,
363 { /* Q-table C-components start registers 0x8840 */
364 0x07, 0x07, 0x0a, 0x13, 0x28, 0x28, 0x28, 0x28,
365 0x07, 0x08, 0x0a, 0x1a, 0x28, 0x28, 0x28, 0x28,
366 0x0a, 0x0a, 0x16, 0x28, 0x28, 0x28, 0x28, 0x28,
367 0x13, 0x1a, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
368 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
369 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
370 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
371 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28}
374 /* read 'len' bytes to gspca_dev->usb_buf */
375 static void reg_r(struct gspca_dev
*gspca_dev
,
379 usb_control_msg(gspca_dev
->dev
,
380 usb_rcvctrlpipe(gspca_dev
->dev
, 0),
382 USB_DIR_IN
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
384 index
, gspca_dev
->usb_buf
, length
, 500);
387 static int reg_w(struct gspca_dev
*gspca_dev
,
388 __u16 req
, __u16 index
, __u16 value
)
392 PDEBUG(D_USBO
, "reg write: [0x%02x] = 0x%02x", index
, value
);
393 ret
= usb_control_msg(gspca_dev
->dev
,
394 usb_sndctrlpipe(gspca_dev
->dev
, 0),
396 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
397 value
, index
, NULL
, 0, 500);
399 PDEBUG(D_ERR
, "reg write: error %d", ret
);
403 /* returns: negative is error, pos or zero is data */
404 static int reg_r_12(struct gspca_dev
*gspca_dev
,
405 __u16 req
, /* bRequest */
406 __u16 index
, /* wIndex */
407 __u16 length
) /* wLength (1 or 2 only) */
411 gspca_dev
->usb_buf
[1] = 0;
412 ret
= usb_control_msg(gspca_dev
->dev
,
413 usb_rcvctrlpipe(gspca_dev
->dev
, 0),
415 USB_DIR_IN
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
418 gspca_dev
->usb_buf
, length
,
421 PDEBUG(D_ERR
, "reg_r_12 err %d", ret
);
424 return (gspca_dev
->usb_buf
[1] << 8) + gspca_dev
->usb_buf
[0];
428 * Simple function to wait for a given 8-bit value to be returned from
430 * Returns: negative is error or timeout, zero is success.
432 static int reg_r_wait(struct gspca_dev
*gspca_dev
,
433 __u16 reg
, __u16 index
, __u16 value
)
438 ret
= reg_r_12(gspca_dev
, reg
, index
, 1);
446 static int write_vector(struct gspca_dev
*gspca_dev
,
447 const __u16 data
[][3])
451 while (data
[i
][0] != 0 || data
[i
][1] != 0 || data
[i
][2] != 0) {
452 ret
= reg_w(gspca_dev
, data
[i
][0], data
[i
][2], data
[i
][1]);
460 static int spca50x_setup_qtable(struct gspca_dev
*gspca_dev
,
461 unsigned int request
,
464 const __u8 qtable
[2][64])
468 /* loop over y components */
469 for (i
= 0; i
< 64; i
++) {
470 err
= reg_w(gspca_dev
, request
, ybase
+ i
, qtable
[0][i
]);
475 /* loop over c components */
476 for (i
= 0; i
< 64; i
++) {
477 err
= reg_w(gspca_dev
, request
, cbase
+ i
, qtable
[1][i
]);
484 static void spca500_ping310(struct gspca_dev
*gspca_dev
)
486 reg_r(gspca_dev
, 0x0d04, 2);
487 PDEBUG(D_STREAM
, "ClickSmart310 ping 0x0d04 0x%02x 0x%02x",
488 gspca_dev
->usb_buf
[0], gspca_dev
->usb_buf
[1]);
491 static void spca500_clksmart310_init(struct gspca_dev
*gspca_dev
)
493 reg_r(gspca_dev
, 0x0d05, 2);
494 PDEBUG(D_STREAM
, "ClickSmart310 init 0x0d05 0x%02x 0x%02x",
495 gspca_dev
->usb_buf
[0], gspca_dev
->usb_buf
[1]);
496 reg_w(gspca_dev
, 0x00, 0x8167, 0x5a);
497 spca500_ping310(gspca_dev
);
499 reg_w(gspca_dev
, 0x00, 0x8168, 0x22);
500 reg_w(gspca_dev
, 0x00, 0x816a, 0xc0);
501 reg_w(gspca_dev
, 0x00, 0x816b, 0x0b);
502 reg_w(gspca_dev
, 0x00, 0x8169, 0x25);
503 reg_w(gspca_dev
, 0x00, 0x8157, 0x5b);
504 reg_w(gspca_dev
, 0x00, 0x8158, 0x5b);
505 reg_w(gspca_dev
, 0x00, 0x813f, 0x03);
506 reg_w(gspca_dev
, 0x00, 0x8151, 0x4a);
507 reg_w(gspca_dev
, 0x00, 0x8153, 0x78);
508 reg_w(gspca_dev
, 0x00, 0x0d01, 0x04);
509 /* 00 for adjust shutter */
510 reg_w(gspca_dev
, 0x00, 0x0d02, 0x01);
511 reg_w(gspca_dev
, 0x00, 0x8169, 0x25);
512 reg_w(gspca_dev
, 0x00, 0x0d01, 0x02);
515 static void spca500_setmode(struct gspca_dev
*gspca_dev
,
516 __u8 xmult
, __u8 ymult
)
520 /* set x multiplier */
521 reg_w(gspca_dev
, 0, 0x8001, xmult
);
523 /* set y multiplier */
524 reg_w(gspca_dev
, 0, 0x8002, ymult
);
526 /* use compressed mode, VGA, with mode specific subsample */
527 mode
= gspca_dev
->cam
.cam_mode
[(int) gspca_dev
->curr_mode
].priv
;
528 reg_w(gspca_dev
, 0, 0x8003, mode
<< 4);
531 static int spca500_full_reset(struct gspca_dev
*gspca_dev
)
535 /* send the reset command */
536 err
= reg_w(gspca_dev
, 0xe0, 0x0001, 0x0000);
540 /* wait for the reset to complete */
541 err
= reg_r_wait(gspca_dev
, 0x06, 0x0000, 0x0000);
544 err
= reg_w(gspca_dev
, 0xe0, 0x0000, 0x0000);
547 err
= reg_r_wait(gspca_dev
, 0x06, 0, 0);
549 PDEBUG(D_ERR
, "reg_r_wait() failed");
556 /* Synchro the Bridge with sensor */
557 /* Maybe that will work on all spca500 chip */
558 /* because i only own a clicksmart310 try for that chip */
559 /* using spca50x_set_packet_size() cause an Ooops here */
560 /* usb_set_interface from kernel 2.6.x clear all the urb stuff */
561 /* up-port the same feature as in 2.4.x kernel */
562 static int spca500_synch310(struct gspca_dev
*gspca_dev
)
564 if (usb_set_interface(gspca_dev
->dev
, gspca_dev
->iface
, 0) < 0) {
565 PDEBUG(D_ERR
, "Set packet size: set interface error");
568 spca500_ping310(gspca_dev
);
570 reg_r(gspca_dev
, 0x0d00, 1);
572 /* need alt setting here */
573 PDEBUG(D_PACK
, "ClickSmart310 sync alt: %d", gspca_dev
->alt
);
575 /* Windoze use pipe with altsetting 6 why 7 here */
576 if (usb_set_interface(gspca_dev
->dev
,
578 gspca_dev
->alt
) < 0) {
579 PDEBUG(D_ERR
, "Set packet size: set interface error");
587 static void spca500_reinit(struct gspca_dev
*gspca_dev
)
592 /* some unknow command from Aiptek pocket dv and family300 */
594 reg_w(gspca_dev
, 0x00, 0x0d01, 0x01);
595 reg_w(gspca_dev
, 0x00, 0x0d03, 0x00);
596 reg_w(gspca_dev
, 0x00, 0x0d02, 0x01);
598 /* enable drop packet */
599 reg_w(gspca_dev
, 0x00, 0x850a, 0x0001);
601 err
= spca50x_setup_qtable(gspca_dev
, 0x00, 0x8800, 0x8840,
604 PDEBUG(D_ERR
|D_STREAM
, "spca50x_setup_qtable failed on init");
606 /* set qtable index */
607 reg_w(gspca_dev
, 0x00, 0x8880, 2);
608 /* family cam Quicksmart stuff */
609 reg_w(gspca_dev
, 0x00, 0x800a, 0x00);
610 /* Set agc transfer: synced inbetween frames */
611 reg_w(gspca_dev
, 0x00, 0x820f, 0x01);
612 /* Init SDRAM - needed for SDRAM access */
613 reg_w(gspca_dev
, 0x00, 0x870a, 0x04);
614 /*Start init sequence or stream */
615 reg_w(gspca_dev
, 0, 0x8003, 0x00);
616 /* switch to video camera mode */
617 reg_w(gspca_dev
, 0x00, 0x8000, 0x0004);
619 if (reg_r_wait(gspca_dev
, 0, 0x8000, 0x44) != 0) {
620 reg_r(gspca_dev
, 0x816b, 1);
621 Data
= gspca_dev
->usb_buf
[0];
622 reg_w(gspca_dev
, 0x00, 0x816b, Data
);
626 /* this function is called at probe time */
627 static int sd_config(struct gspca_dev
*gspca_dev
,
628 const struct usb_device_id
*id
)
630 struct sd
*sd
= (struct sd
*) gspca_dev
;
633 cam
= &gspca_dev
->cam
;
634 sd
->subtype
= id
->driver_info
;
635 if (sd
->subtype
!= LogitechClickSmart310
) {
636 cam
->cam_mode
= vga_mode
;
637 cam
->nmodes
= ARRAY_SIZE(vga_mode
);
639 cam
->cam_mode
= sif_mode
;
640 cam
->nmodes
= ARRAY_SIZE(sif_mode
);
642 sd
->brightness
= BRIGHTNESS_DEF
;
643 sd
->contrast
= CONTRAST_DEF
;
644 sd
->colors
= COLOR_DEF
;
645 sd
->quality
= QUALITY_DEF
;
649 /* this function is called at probe and resume time */
650 static int sd_init(struct gspca_dev
*gspca_dev
)
652 struct sd
*sd
= (struct sd
*) gspca_dev
;
654 /* initialisation of spca500 based cameras is deferred */
655 PDEBUG(D_STREAM
, "SPCA500 init");
656 if (sd
->subtype
== LogitechClickSmart310
)
657 spca500_clksmart310_init(gspca_dev
);
659 spca500_initialise(gspca_dev); */
660 PDEBUG(D_STREAM
, "SPCA500 init done");
664 static int sd_start(struct gspca_dev
*gspca_dev
)
666 struct sd
*sd
= (struct sd
*) gspca_dev
;
671 /* create the JPEG header */
672 sd
->jpeg_hdr
= kmalloc(JPEG_HDR_SZ
, GFP_KERNEL
);
673 jpeg_define(sd
->jpeg_hdr
, gspca_dev
->height
, gspca_dev
->width
,
674 0x22); /* JPEG 411 */
675 jpeg_set_qual(sd
->jpeg_hdr
, sd
->quality
);
677 if (sd
->subtype
== LogitechClickSmart310
) {
685 /* is there a sensor here ? */
686 reg_r(gspca_dev
, 0x8a04, 1);
687 PDEBUG(D_STREAM
, "Spca500 Sensor Address 0x%02x",
688 gspca_dev
->usb_buf
[0]);
689 PDEBUG(D_STREAM
, "Spca500 curr_mode: %d Xmult: 0x%02x, Ymult: 0x%02x",
690 gspca_dev
->curr_mode
, xmult
, ymult
);
693 switch (sd
->subtype
) {
694 case LogitechClickSmart310
:
695 spca500_setmode(gspca_dev
, xmult
, ymult
);
697 /* enable drop packet */
698 reg_w(gspca_dev
, 0x00, 0x850a, 0x0001);
699 reg_w(gspca_dev
, 0x00, 0x8880, 3);
700 err
= spca50x_setup_qtable(gspca_dev
,
701 0x00, 0x8800, 0x8840,
702 qtable_creative_pccam
);
704 PDEBUG(D_ERR
, "spca50x_setup_qtable failed");
705 /* Init SDRAM - needed for SDRAM access */
706 reg_w(gspca_dev
, 0x00, 0x870a, 0x04);
708 /* switch to video camera mode */
709 reg_w(gspca_dev
, 0x00, 0x8000, 0x0004);
711 if (reg_r_wait(gspca_dev
, 0, 0x8000, 0x44) != 0)
712 PDEBUG(D_ERR
, "reg_r_wait() failed");
714 reg_r(gspca_dev
, 0x816b, 1);
715 Data
= gspca_dev
->usb_buf
[0];
716 reg_w(gspca_dev
, 0x00, 0x816b, Data
);
718 spca500_synch310(gspca_dev
);
720 write_vector(gspca_dev
, spca500_visual_defaults
);
721 spca500_setmode(gspca_dev
, xmult
, ymult
);
722 /* enable drop packet */
723 err
= reg_w(gspca_dev
, 0x00, 0x850a, 0x0001);
725 PDEBUG(D_ERR
, "failed to enable drop packet");
726 reg_w(gspca_dev
, 0x00, 0x8880, 3);
727 err
= spca50x_setup_qtable(gspca_dev
,
728 0x00, 0x8800, 0x8840,
729 qtable_creative_pccam
);
731 PDEBUG(D_ERR
, "spca50x_setup_qtable failed");
733 /* Init SDRAM - needed for SDRAM access */
734 reg_w(gspca_dev
, 0x00, 0x870a, 0x04);
736 /* switch to video camera mode */
737 reg_w(gspca_dev
, 0x00, 0x8000, 0x0004);
739 if (reg_r_wait(gspca_dev
, 0, 0x8000, 0x44) != 0)
740 PDEBUG(D_ERR
, "reg_r_wait() failed");
742 reg_r(gspca_dev
, 0x816b, 1);
743 Data
= gspca_dev
->usb_buf
[0];
744 reg_w(gspca_dev
, 0x00, 0x816b, Data
);
746 case CreativePCCam300
: /* Creative PC-CAM 300 640x480 CCD */
747 case IntelPocketPCCamera
: /* FIXME: Temporary fix for
748 * Intel Pocket PC Camera
749 * - NWG (Sat 29th March 2003) */
751 /* do a full reset */
752 err
= spca500_full_reset(gspca_dev
);
754 PDEBUG(D_ERR
, "spca500_full_reset failed");
756 /* enable drop packet */
757 err
= reg_w(gspca_dev
, 0x00, 0x850a, 0x0001);
759 PDEBUG(D_ERR
, "failed to enable drop packet");
760 reg_w(gspca_dev
, 0x00, 0x8880, 3);
761 err
= spca50x_setup_qtable(gspca_dev
,
762 0x00, 0x8800, 0x8840,
763 qtable_creative_pccam
);
765 PDEBUG(D_ERR
, "spca50x_setup_qtable failed");
767 spca500_setmode(gspca_dev
, xmult
, ymult
);
768 reg_w(gspca_dev
, 0x20, 0x0001, 0x0004);
770 /* switch to video camera mode */
771 reg_w(gspca_dev
, 0x00, 0x8000, 0x0004);
773 if (reg_r_wait(gspca_dev
, 0, 0x8000, 0x44) != 0)
774 PDEBUG(D_ERR
, "reg_r_wait() failed");
776 reg_r(gspca_dev
, 0x816b, 1);
777 Data
= gspca_dev
->usb_buf
[0];
778 reg_w(gspca_dev
, 0x00, 0x816b, Data
);
780 /* write_vector(gspca_dev, spca500_visual_defaults); */
782 case KodakEZ200
: /* Kodak EZ200 */
784 /* do a full reset */
785 err
= spca500_full_reset(gspca_dev
);
787 PDEBUG(D_ERR
, "spca500_full_reset failed");
788 /* enable drop packet */
789 reg_w(gspca_dev
, 0x00, 0x850a, 0x0001);
790 reg_w(gspca_dev
, 0x00, 0x8880, 0);
791 err
= spca50x_setup_qtable(gspca_dev
,
792 0x00, 0x8800, 0x8840,
795 PDEBUG(D_ERR
, "spca50x_setup_qtable failed");
796 spca500_setmode(gspca_dev
, xmult
, ymult
);
798 reg_w(gspca_dev
, 0x20, 0x0001, 0x0004);
800 /* switch to video camera mode */
801 reg_w(gspca_dev
, 0x00, 0x8000, 0x0004);
803 if (reg_r_wait(gspca_dev
, 0, 0x8000, 0x44) != 0)
804 PDEBUG(D_ERR
, "reg_r_wait() failed");
806 reg_r(gspca_dev
, 0x816b, 1);
807 Data
= gspca_dev
->usb_buf
[0];
808 reg_w(gspca_dev
, 0x00, 0x816b, Data
);
810 /* write_vector(gspca_dev, spca500_visual_defaults); */
814 case DLinkDSC350
: /* FamilyCam 300 */
815 case AiptekPocketDV
: /* Aiptek PocketDV */
816 case Gsmartmini
: /*Mustek Gsmart Mini */
817 case MustekGsmart300
: /* Mustek Gsmart 300 */
822 spca500_reinit(gspca_dev
);
823 reg_w(gspca_dev
, 0x00, 0x0d01, 0x01);
824 /* enable drop packet */
825 reg_w(gspca_dev
, 0x00, 0x850a, 0x0001);
827 err
= spca50x_setup_qtable(gspca_dev
,
828 0x00, 0x8800, 0x8840, qtable_pocketdv
);
830 PDEBUG(D_ERR
, "spca50x_setup_qtable failed");
831 reg_w(gspca_dev
, 0x00, 0x8880, 2);
833 /* familycam Quicksmart pocketDV stuff */
834 reg_w(gspca_dev
, 0x00, 0x800a, 0x00);
835 /* Set agc transfer: synced inbetween frames */
836 reg_w(gspca_dev
, 0x00, 0x820f, 0x01);
837 /* Init SDRAM - needed for SDRAM access */
838 reg_w(gspca_dev
, 0x00, 0x870a, 0x04);
840 spca500_setmode(gspca_dev
, xmult
, ymult
);
841 /* switch to video camera mode */
842 reg_w(gspca_dev
, 0x00, 0x8000, 0x0004);
844 reg_r_wait(gspca_dev
, 0, 0x8000, 0x44);
846 reg_r(gspca_dev
, 0x816b, 1);
847 Data
= gspca_dev
->usb_buf
[0];
848 reg_w(gspca_dev
, 0x00, 0x816b, Data
);
850 case LogitechTraveler
:
851 case LogitechClickSmart510
:
852 reg_w(gspca_dev
, 0x02, 0x00, 0x00);
853 /* enable drop packet */
854 reg_w(gspca_dev
, 0x00, 0x850a, 0x0001);
856 err
= spca50x_setup_qtable(gspca_dev
,
858 0x8840, qtable_creative_pccam
);
860 PDEBUG(D_ERR
, "spca50x_setup_qtable failed");
861 reg_w(gspca_dev
, 0x00, 0x8880, 3);
862 reg_w(gspca_dev
, 0x00, 0x800a, 0x00);
863 /* Init SDRAM - needed for SDRAM access */
864 reg_w(gspca_dev
, 0x00, 0x870a, 0x04);
866 spca500_setmode(gspca_dev
, xmult
, ymult
);
868 /* switch to video camera mode */
869 reg_w(gspca_dev
, 0x00, 0x8000, 0x0004);
870 reg_r_wait(gspca_dev
, 0, 0x8000, 0x44);
872 reg_r(gspca_dev
, 0x816b, 1);
873 Data
= gspca_dev
->usb_buf
[0];
874 reg_w(gspca_dev
, 0x00, 0x816b, Data
);
875 write_vector(gspca_dev
, Clicksmart510_defaults
);
881 static void sd_stopN(struct gspca_dev
*gspca_dev
)
883 reg_w(gspca_dev
, 0, 0x8003, 0x00);
885 /* switch to video camera mode */
886 reg_w(gspca_dev
, 0x00, 0x8000, 0x0004);
887 reg_r(gspca_dev
, 0x8000, 1);
888 PDEBUG(D_STREAM
, "stop SPCA500 done reg8000: 0x%2x",
889 gspca_dev
->usb_buf
[0]);
892 static void sd_stop0(struct gspca_dev
*gspca_dev
)
894 struct sd
*sd
= (struct sd
*) gspca_dev
;
899 static void sd_pkt_scan(struct gspca_dev
*gspca_dev
,
900 struct gspca_frame
*frame
, /* target */
901 __u8
*data
, /* isoc packet */
902 int len
) /* iso packet length */
904 struct sd
*sd
= (struct sd
*) gspca_dev
;
906 static __u8 ffd9
[] = {0xff, 0xd9};
908 /* frames are jpeg 4.1.1 without 0xff escape */
909 if (data
[0] == 0xff) {
910 if (data
[1] != 0x01) { /* drop packet */
911 /* gspca_dev->last_packet_type = DISCARD_PACKET; */
914 frame
= gspca_frame_add(gspca_dev
, LAST_PACKET
, frame
,
917 /* put the JPEG header in the new frame */
918 gspca_frame_add(gspca_dev
, FIRST_PACKET
, frame
,
919 sd
->jpeg_hdr
, JPEG_HDR_SZ
);
921 data
+= SPCA500_OFFSET_DATA
;
922 len
-= SPCA500_OFFSET_DATA
;
928 /* add 0x00 after 0xff */
931 if (data
[i
] == 0xff) {
932 gspca_frame_add(gspca_dev
, INTER_PACKET
, frame
,
941 gspca_frame_add(gspca_dev
, INTER_PACKET
, frame
, data
, len
);
944 static void setbrightness(struct gspca_dev
*gspca_dev
)
946 struct sd
*sd
= (struct sd
*) gspca_dev
;
948 reg_w(gspca_dev
, 0x00, 0x8167,
949 (__u8
) (sd
->brightness
- 128));
952 static void setcontrast(struct gspca_dev
*gspca_dev
)
954 struct sd
*sd
= (struct sd
*) gspca_dev
;
956 reg_w(gspca_dev
, 0x00, 0x8168, sd
->contrast
);
959 static void setcolors(struct gspca_dev
*gspca_dev
)
961 struct sd
*sd
= (struct sd
*) gspca_dev
;
963 reg_w(gspca_dev
, 0x00, 0x8169, sd
->colors
);
966 static int sd_setbrightness(struct gspca_dev
*gspca_dev
, __s32 val
)
968 struct sd
*sd
= (struct sd
*) gspca_dev
;
970 sd
->brightness
= val
;
971 if (gspca_dev
->streaming
)
972 setbrightness(gspca_dev
);
976 static int sd_getbrightness(struct gspca_dev
*gspca_dev
, __s32
*val
)
978 struct sd
*sd
= (struct sd
*) gspca_dev
;
980 *val
= sd
->brightness
;
984 static int sd_setcontrast(struct gspca_dev
*gspca_dev
, __s32 val
)
986 struct sd
*sd
= (struct sd
*) gspca_dev
;
989 if (gspca_dev
->streaming
)
990 setcontrast(gspca_dev
);
994 static int sd_getcontrast(struct gspca_dev
*gspca_dev
, __s32
*val
)
996 struct sd
*sd
= (struct sd
*) gspca_dev
;
1002 static int sd_setcolors(struct gspca_dev
*gspca_dev
, __s32 val
)
1004 struct sd
*sd
= (struct sd
*) gspca_dev
;
1007 if (gspca_dev
->streaming
)
1008 setcolors(gspca_dev
);
1012 static int sd_getcolors(struct gspca_dev
*gspca_dev
, __s32
*val
)
1014 struct sd
*sd
= (struct sd
*) gspca_dev
;
1020 static int sd_set_jcomp(struct gspca_dev
*gspca_dev
,
1021 struct v4l2_jpegcompression
*jcomp
)
1023 struct sd
*sd
= (struct sd
*) gspca_dev
;
1025 if (jcomp
->quality
< QUALITY_MIN
)
1026 sd
->quality
= QUALITY_MIN
;
1027 else if (jcomp
->quality
> QUALITY_MAX
)
1028 sd
->quality
= QUALITY_MAX
;
1030 sd
->quality
= jcomp
->quality
;
1031 if (gspca_dev
->streaming
)
1032 jpeg_set_qual(sd
->jpeg_hdr
, sd
->quality
);
1036 static int sd_get_jcomp(struct gspca_dev
*gspca_dev
,
1037 struct v4l2_jpegcompression
*jcomp
)
1039 struct sd
*sd
= (struct sd
*) gspca_dev
;
1041 memset(jcomp
, 0, sizeof *jcomp
);
1042 jcomp
->quality
= sd
->quality
;
1043 jcomp
->jpeg_markers
= V4L2_JPEG_MARKER_DHT
1044 | V4L2_JPEG_MARKER_DQT
;
1048 /* sub-driver description */
1049 static struct sd_desc sd_desc
= {
1050 .name
= MODULE_NAME
,
1052 .nctrls
= ARRAY_SIZE(sd_ctrls
),
1053 .config
= sd_config
,
1058 .pkt_scan
= sd_pkt_scan
,
1059 .get_jcomp
= sd_get_jcomp
,
1060 .set_jcomp
= sd_set_jcomp
,
1063 /* -- module initialisation -- */
1064 static const __devinitdata
struct usb_device_id device_table
[] = {
1065 {USB_DEVICE(0x040a, 0x0300), .driver_info
= KodakEZ200
},
1066 {USB_DEVICE(0x041e, 0x400a), .driver_info
= CreativePCCam300
},
1067 {USB_DEVICE(0x046d, 0x0890), .driver_info
= LogitechTraveler
},
1068 {USB_DEVICE(0x046d, 0x0900), .driver_info
= LogitechClickSmart310
},
1069 {USB_DEVICE(0x046d, 0x0901), .driver_info
= LogitechClickSmart510
},
1070 {USB_DEVICE(0x04a5, 0x300c), .driver_info
= BenqDC1016
},
1071 {USB_DEVICE(0x04fc, 0x7333), .driver_info
= PalmPixDC85
},
1072 {USB_DEVICE(0x055f, 0xc200), .driver_info
= MustekGsmart300
},
1073 {USB_DEVICE(0x055f, 0xc220), .driver_info
= Gsmartmini
},
1074 {USB_DEVICE(0x06bd, 0x0404), .driver_info
= AgfaCl20
},
1075 {USB_DEVICE(0x06be, 0x0800), .driver_info
= Optimedia
},
1076 {USB_DEVICE(0x084d, 0x0003), .driver_info
= DLinkDSC350
},
1077 {USB_DEVICE(0x08ca, 0x0103), .driver_info
= AiptekPocketDV
},
1078 {USB_DEVICE(0x2899, 0x012c), .driver_info
= ToptroIndus
},
1079 {USB_DEVICE(0x8086, 0x0630), .driver_info
= IntelPocketPCCamera
},
1082 MODULE_DEVICE_TABLE(usb
, device_table
);
1084 /* -- device connect -- */
1085 static int sd_probe(struct usb_interface
*intf
,
1086 const struct usb_device_id
*id
)
1088 return gspca_dev_probe(intf
, id
, &sd_desc
, sizeof(struct sd
),
1092 static struct usb_driver sd_driver
= {
1093 .name
= MODULE_NAME
,
1094 .id_table
= device_table
,
1096 .disconnect
= gspca_disconnect
,
1098 .suspend
= gspca_suspend
,
1099 .resume
= gspca_resume
,
1103 /* -- module insert / remove -- */
1104 static int __init
sd_mod_init(void)
1107 ret
= usb_register(&sd_driver
);
1110 PDEBUG(D_PROBE
, "registered");
1113 static void __exit
sd_mod_exit(void)
1115 usb_deregister(&sd_driver
);
1116 PDEBUG(D_PROBE
, "deregistered");
1119 module_init(sd_mod_init
);
1120 module_exit(sd_mod_exit
);