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 pr_fmt(fmt) KBUILD_MODNAME ": " fmt
24 #define MODULE_NAME "spca500"
29 MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
30 MODULE_DESCRIPTION("GSPCA/SPCA500 USB Camera Driver");
31 MODULE_LICENSE("GPL");
33 /* specific webcam descriptor */
35 struct gspca_dev gspca_dev
; /* !! must be the first item */
37 unsigned char brightness
;
38 unsigned char contrast
;
41 #define QUALITY_MIN 70
42 #define QUALITY_MAX 95
43 #define QUALITY_DEF 85
47 #define AiptekPocketDV 1
49 #define CreativePCCam300 3
52 #define IntelPocketPCCamera 6
54 #define LogitechClickSmart310 8
55 #define LogitechClickSmart510 9
56 #define LogitechTraveler 10
57 #define MustekGsmart300 11
59 #define PalmPixDC85 13
60 #define ToptroIndus 14
62 u8 jpeg_hdr
[JPEG_HDR_SZ
];
65 /* V4L2 controls supported by the driver */
66 static int sd_setbrightness(struct gspca_dev
*gspca_dev
, __s32 val
);
67 static int sd_getbrightness(struct gspca_dev
*gspca_dev
, __s32
*val
);
68 static int sd_setcontrast(struct gspca_dev
*gspca_dev
, __s32 val
);
69 static int sd_getcontrast(struct gspca_dev
*gspca_dev
, __s32
*val
);
70 static int sd_setcolors(struct gspca_dev
*gspca_dev
, __s32 val
);
71 static int sd_getcolors(struct gspca_dev
*gspca_dev
, __s32
*val
);
73 static const struct ctrl sd_ctrls
[] = {
76 .id
= V4L2_CID_BRIGHTNESS
,
77 .type
= V4L2_CTRL_TYPE_INTEGER
,
82 #define BRIGHTNESS_DEF 127
83 .default_value
= BRIGHTNESS_DEF
,
85 .set
= sd_setbrightness
,
86 .get
= sd_getbrightness
,
90 .id
= V4L2_CID_CONTRAST
,
91 .type
= V4L2_CTRL_TYPE_INTEGER
,
96 #define CONTRAST_DEF 31
97 .default_value
= CONTRAST_DEF
,
99 .set
= sd_setcontrast
,
100 .get
= sd_getcontrast
,
104 .id
= V4L2_CID_SATURATION
,
105 .type
= V4L2_CTRL_TYPE_INTEGER
,
111 .default_value
= COLOR_DEF
,
118 static const struct v4l2_pix_format vga_mode
[] = {
119 {320, 240, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
121 .sizeimage
= 320 * 240 * 3 / 8 + 590,
122 .colorspace
= V4L2_COLORSPACE_JPEG
,
124 {640, 480, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
126 .sizeimage
= 640 * 480 * 3 / 8 + 590,
127 .colorspace
= V4L2_COLORSPACE_JPEG
,
131 static const struct v4l2_pix_format sif_mode
[] = {
132 {176, 144, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
134 .sizeimage
= 176 * 144 * 3 / 8 + 590,
135 .colorspace
= V4L2_COLORSPACE_JPEG
,
137 {352, 288, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
139 .sizeimage
= 352 * 288 * 3 / 8 + 590,
140 .colorspace
= V4L2_COLORSPACE_JPEG
,
144 /* Frame packet header offsets for the spca500 */
145 #define SPCA500_OFFSET_PADDINGLB 2
146 #define SPCA500_OFFSET_PADDINGHB 3
147 #define SPCA500_OFFSET_MODE 4
148 #define SPCA500_OFFSET_IMGWIDTH 5
149 #define SPCA500_OFFSET_IMGHEIGHT 6
150 #define SPCA500_OFFSET_IMGMODE 7
151 #define SPCA500_OFFSET_QTBLINDEX 8
152 #define SPCA500_OFFSET_FRAMSEQ 9
153 #define SPCA500_OFFSET_CDSPINFO 10
154 #define SPCA500_OFFSET_GPIO 11
155 #define SPCA500_OFFSET_AUGPIO 12
156 #define SPCA500_OFFSET_DATA 16
159 static const __u16 spca500_visual_defaults
[][3] = {
160 {0x00, 0x0003, 0x816b}, /* SSI not active sync with vsync,
162 * saturation/hue enable,
163 * brightness/contrast enable.
165 {0x00, 0x0000, 0x8167}, /* brightness = 0 */
166 {0x00, 0x0020, 0x8168}, /* contrast = 0 */
167 {0x00, 0x0003, 0x816b}, /* SSI not active sync with vsync,
168 * hue (H byte) = 0, saturation/hue enable,
169 * brightness/contrast enable.
170 * was 0x0003, now 0x0000.
172 {0x00, 0x0000, 0x816a}, /* hue (L byte) = 0 */
173 {0x00, 0x0020, 0x8169}, /* saturation = 0x20 */
174 {0x00, 0x0050, 0x8157}, /* edge gain high threshold */
175 {0x00, 0x0030, 0x8158}, /* edge gain low threshold */
176 {0x00, 0x0028, 0x8159}, /* edge bandwidth high threshold */
177 {0x00, 0x000a, 0x815a}, /* edge bandwidth low threshold */
178 {0x00, 0x0001, 0x8202}, /* clock rate compensation = 1/25 sec/frame */
179 {0x0c, 0x0004, 0x0000},
183 static const __u16 Clicksmart510_defaults
[][3] = {
184 {0x00, 0x00, 0x8211},
185 {0x00, 0x01, 0x82c0},
186 {0x00, 0x10, 0x82cb},
187 {0x00, 0x0f, 0x800d},
188 {0x00, 0x82, 0x8225},
189 {0x00, 0x21, 0x8228},
190 {0x00, 0x00, 0x8203},
191 {0x00, 0x00, 0x8204},
192 {0x00, 0x08, 0x8205},
193 {0x00, 0xf8, 0x8206},
194 {0x00, 0x28, 0x8207},
195 {0x00, 0xa0, 0x8208},
196 {0x00, 0x08, 0x824a},
197 {0x00, 0x08, 0x8214},
198 {0x00, 0x80, 0x82c1},
199 {0x00, 0x00, 0x82c2},
200 {0x00, 0x00, 0x82ca},
201 {0x00, 0x80, 0x82c1},
202 {0x00, 0x04, 0x82c2},
203 {0x00, 0x00, 0x82ca},
204 {0x00, 0xfc, 0x8100},
205 {0x00, 0xfc, 0x8105},
206 {0x00, 0x30, 0x8101},
207 {0x00, 0x00, 0x8102},
208 {0x00, 0x00, 0x8103},
209 {0x00, 0x66, 0x8107},
210 {0x00, 0x00, 0x816b},
211 {0x00, 0x00, 0x8155},
212 {0x00, 0x01, 0x8156},
213 {0x00, 0x60, 0x8157},
214 {0x00, 0x40, 0x8158},
215 {0x00, 0x0a, 0x8159},
216 {0x00, 0x06, 0x815a},
217 {0x00, 0x00, 0x813f},
218 {0x00, 0x00, 0x8200},
219 {0x00, 0x19, 0x8201},
220 {0x00, 0x00, 0x82c1},
221 {0x00, 0xa0, 0x82c2},
222 {0x00, 0x00, 0x82ca},
223 {0x00, 0x00, 0x8117},
224 {0x00, 0x00, 0x8118},
225 {0x00, 0x65, 0x8119},
226 {0x00, 0x00, 0x811a},
227 {0x00, 0x00, 0x811b},
228 {0x00, 0x55, 0x811c},
229 {0x00, 0x65, 0x811d},
230 {0x00, 0x55, 0x811e},
231 {0x00, 0x16, 0x811f},
232 {0x00, 0x19, 0x8120},
233 {0x00, 0x80, 0x8103},
234 {0x00, 0x83, 0x816b},
235 {0x00, 0x25, 0x8168},
236 {0x00, 0x01, 0x820f},
237 {0x00, 0xff, 0x8115},
238 {0x00, 0x48, 0x8116},
239 {0x00, 0x50, 0x8151},
240 {0x00, 0x40, 0x8152},
241 {0x00, 0x78, 0x8153},
242 {0x00, 0x40, 0x8154},
243 {0x00, 0x00, 0x8167},
244 {0x00, 0x20, 0x8168},
245 {0x00, 0x00, 0x816a},
246 {0x00, 0x03, 0x816b},
247 {0x00, 0x20, 0x8169},
248 {0x00, 0x60, 0x8157},
249 {0x00, 0x00, 0x8190},
250 {0x00, 0x00, 0x81a1},
251 {0x00, 0x00, 0x81b2},
252 {0x00, 0x27, 0x8191},
253 {0x00, 0x27, 0x81a2},
254 {0x00, 0x27, 0x81b3},
255 {0x00, 0x4b, 0x8192},
256 {0x00, 0x4b, 0x81a3},
257 {0x00, 0x4b, 0x81b4},
258 {0x00, 0x66, 0x8193},
259 {0x00, 0x66, 0x81a4},
260 {0x00, 0x66, 0x81b5},
261 {0x00, 0x79, 0x8194},
262 {0x00, 0x79, 0x81a5},
263 {0x00, 0x79, 0x81b6},
264 {0x00, 0x8a, 0x8195},
265 {0x00, 0x8a, 0x81a6},
266 {0x00, 0x8a, 0x81b7},
267 {0x00, 0x9b, 0x8196},
268 {0x00, 0x9b, 0x81a7},
269 {0x00, 0x9b, 0x81b8},
270 {0x00, 0xa6, 0x8197},
271 {0x00, 0xa6, 0x81a8},
272 {0x00, 0xa6, 0x81b9},
273 {0x00, 0xb2, 0x8198},
274 {0x00, 0xb2, 0x81a9},
275 {0x00, 0xb2, 0x81ba},
276 {0x00, 0xbe, 0x8199},
277 {0x00, 0xbe, 0x81aa},
278 {0x00, 0xbe, 0x81bb},
279 {0x00, 0xc8, 0x819a},
280 {0x00, 0xc8, 0x81ab},
281 {0x00, 0xc8, 0x81bc},
282 {0x00, 0xd2, 0x819b},
283 {0x00, 0xd2, 0x81ac},
284 {0x00, 0xd2, 0x81bd},
285 {0x00, 0xdb, 0x819c},
286 {0x00, 0xdb, 0x81ad},
287 {0x00, 0xdb, 0x81be},
288 {0x00, 0xe4, 0x819d},
289 {0x00, 0xe4, 0x81ae},
290 {0x00, 0xe4, 0x81bf},
291 {0x00, 0xed, 0x819e},
292 {0x00, 0xed, 0x81af},
293 {0x00, 0xed, 0x81c0},
294 {0x00, 0xf7, 0x819f},
295 {0x00, 0xf7, 0x81b0},
296 {0x00, 0xf7, 0x81c1},
297 {0x00, 0xff, 0x81a0},
298 {0x00, 0xff, 0x81b1},
299 {0x00, 0xff, 0x81c2},
300 {0x00, 0x03, 0x8156},
301 {0x00, 0x00, 0x8211},
302 {0x00, 0x20, 0x8168},
303 {0x00, 0x01, 0x8202},
304 {0x00, 0x30, 0x8101},
305 {0x00, 0x00, 0x8111},
306 {0x00, 0x00, 0x8112},
307 {0x00, 0x00, 0x8113},
308 {0x00, 0x00, 0x8114},
312 static const __u8 qtable_creative_pccam
[2][64] = {
313 { /* Q-table Y-components */
314 0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12,
315 0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11,
316 0x04, 0x04, 0x05, 0x07, 0x0c, 0x11, 0x15, 0x11,
317 0x04, 0x05, 0x07, 0x09, 0x0f, 0x1a, 0x18, 0x13,
318 0x05, 0x07, 0x0b, 0x11, 0x14, 0x21, 0x1f, 0x17,
319 0x07, 0x0b, 0x11, 0x13, 0x18, 0x1f, 0x22, 0x1c,
320 0x0f, 0x13, 0x17, 0x1a, 0x1f, 0x24, 0x24, 0x1e,
321 0x16, 0x1c, 0x1d, 0x1d, 0x22, 0x1e, 0x1f, 0x1e},
322 { /* Q-table C-components */
323 0x05, 0x05, 0x07, 0x0e, 0x1e, 0x1e, 0x1e, 0x1e,
324 0x05, 0x06, 0x08, 0x14, 0x1e, 0x1e, 0x1e, 0x1e,
325 0x07, 0x08, 0x11, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
326 0x0e, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
327 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
328 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
329 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
330 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e}
333 static const __u8 qtable_kodak_ez200
[2][64] = {
334 { /* Q-table Y-components */
335 0x02, 0x01, 0x01, 0x02, 0x02, 0x04, 0x05, 0x06,
336 0x01, 0x01, 0x01, 0x02, 0x03, 0x06, 0x06, 0x06,
337 0x01, 0x01, 0x02, 0x02, 0x04, 0x06, 0x07, 0x06,
338 0x01, 0x02, 0x02, 0x03, 0x05, 0x09, 0x08, 0x06,
339 0x02, 0x02, 0x04, 0x06, 0x07, 0x0b, 0x0a, 0x08,
340 0x02, 0x04, 0x06, 0x06, 0x08, 0x0a, 0x0b, 0x09,
341 0x05, 0x06, 0x08, 0x09, 0x0a, 0x0c, 0x0c, 0x0a,
342 0x07, 0x09, 0x0a, 0x0a, 0x0b, 0x0a, 0x0a, 0x0a},
343 { /* Q-table C-components */
344 0x02, 0x02, 0x02, 0x05, 0x0a, 0x0a, 0x0a, 0x0a,
345 0x02, 0x02, 0x03, 0x07, 0x0a, 0x0a, 0x0a, 0x0a,
346 0x02, 0x03, 0x06, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
347 0x05, 0x07, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
348 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
349 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
350 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
351 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a}
354 static const __u8 qtable_pocketdv
[2][64] = {
355 { /* Q-table Y-components start registers 0x8800 */
356 0x06, 0x04, 0x04, 0x06, 0x0a, 0x10, 0x14, 0x18,
357 0x05, 0x05, 0x06, 0x08, 0x0a, 0x17, 0x18, 0x16,
358 0x06, 0x05, 0x06, 0x0a, 0x10, 0x17, 0x1c, 0x16,
359 0x06, 0x07, 0x09, 0x0c, 0x14, 0x23, 0x20, 0x19,
360 0x07, 0x09, 0x0f, 0x16, 0x1b, 0x2c, 0x29, 0x1f,
361 0x0a, 0x0e, 0x16, 0x1a, 0x20, 0x2a, 0x2d, 0x25,
362 0x14, 0x1a, 0x1f, 0x23, 0x29, 0x30, 0x30, 0x28,
363 0x1d, 0x25, 0x26, 0x27, 0x2d, 0x28, 0x29, 0x28,
365 { /* Q-table C-components start registers 0x8840 */
366 0x07, 0x07, 0x0a, 0x13, 0x28, 0x28, 0x28, 0x28,
367 0x07, 0x08, 0x0a, 0x1a, 0x28, 0x28, 0x28, 0x28,
368 0x0a, 0x0a, 0x16, 0x28, 0x28, 0x28, 0x28, 0x28,
369 0x13, 0x1a, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
370 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
371 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
372 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
373 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28}
376 /* read 'len' bytes to gspca_dev->usb_buf */
377 static void reg_r(struct gspca_dev
*gspca_dev
,
381 usb_control_msg(gspca_dev
->dev
,
382 usb_rcvctrlpipe(gspca_dev
->dev
, 0),
384 USB_DIR_IN
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
386 index
, gspca_dev
->usb_buf
, length
, 500);
389 static int reg_w(struct gspca_dev
*gspca_dev
,
390 __u16 req
, __u16 index
, __u16 value
)
394 PDEBUG(D_USBO
, "reg write: [0x%02x] = 0x%02x", index
, value
);
395 ret
= usb_control_msg(gspca_dev
->dev
,
396 usb_sndctrlpipe(gspca_dev
->dev
, 0),
398 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
399 value
, index
, NULL
, 0, 500);
401 pr_err("reg write: error %d\n", ret
);
405 /* returns: negative is error, pos or zero is data */
406 static int reg_r_12(struct gspca_dev
*gspca_dev
,
407 __u16 req
, /* bRequest */
408 __u16 index
, /* wIndex */
409 __u16 length
) /* wLength (1 or 2 only) */
413 gspca_dev
->usb_buf
[1] = 0;
414 ret
= usb_control_msg(gspca_dev
->dev
,
415 usb_rcvctrlpipe(gspca_dev
->dev
, 0),
417 USB_DIR_IN
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
420 gspca_dev
->usb_buf
, length
,
423 pr_err("reg_r_12 err %d\n", ret
);
426 return (gspca_dev
->usb_buf
[1] << 8) + gspca_dev
->usb_buf
[0];
430 * Simple function to wait for a given 8-bit value to be returned from
432 * Returns: negative is error or timeout, zero is success.
434 static int reg_r_wait(struct gspca_dev
*gspca_dev
,
435 __u16 reg
, __u16 index
, __u16 value
)
440 ret
= reg_r_12(gspca_dev
, reg
, index
, 1);
448 static int write_vector(struct gspca_dev
*gspca_dev
,
449 const __u16 data
[][3])
453 while (data
[i
][0] != 0 || data
[i
][1] != 0 || data
[i
][2] != 0) {
454 ret
= reg_w(gspca_dev
, data
[i
][0], data
[i
][2], data
[i
][1]);
462 static int spca50x_setup_qtable(struct gspca_dev
*gspca_dev
,
463 unsigned int request
,
466 const __u8 qtable
[2][64])
470 /* loop over y components */
471 for (i
= 0; i
< 64; i
++) {
472 err
= reg_w(gspca_dev
, request
, ybase
+ i
, qtable
[0][i
]);
477 /* loop over c components */
478 for (i
= 0; i
< 64; i
++) {
479 err
= reg_w(gspca_dev
, request
, cbase
+ i
, qtable
[1][i
]);
486 static void spca500_ping310(struct gspca_dev
*gspca_dev
)
488 reg_r(gspca_dev
, 0x0d04, 2);
489 PDEBUG(D_STREAM
, "ClickSmart310 ping 0x0d04 0x%02x 0x%02x",
490 gspca_dev
->usb_buf
[0], gspca_dev
->usb_buf
[1]);
493 static void spca500_clksmart310_init(struct gspca_dev
*gspca_dev
)
495 reg_r(gspca_dev
, 0x0d05, 2);
496 PDEBUG(D_STREAM
, "ClickSmart310 init 0x0d05 0x%02x 0x%02x",
497 gspca_dev
->usb_buf
[0], gspca_dev
->usb_buf
[1]);
498 reg_w(gspca_dev
, 0x00, 0x8167, 0x5a);
499 spca500_ping310(gspca_dev
);
501 reg_w(gspca_dev
, 0x00, 0x8168, 0x22);
502 reg_w(gspca_dev
, 0x00, 0x816a, 0xc0);
503 reg_w(gspca_dev
, 0x00, 0x816b, 0x0b);
504 reg_w(gspca_dev
, 0x00, 0x8169, 0x25);
505 reg_w(gspca_dev
, 0x00, 0x8157, 0x5b);
506 reg_w(gspca_dev
, 0x00, 0x8158, 0x5b);
507 reg_w(gspca_dev
, 0x00, 0x813f, 0x03);
508 reg_w(gspca_dev
, 0x00, 0x8151, 0x4a);
509 reg_w(gspca_dev
, 0x00, 0x8153, 0x78);
510 reg_w(gspca_dev
, 0x00, 0x0d01, 0x04);
511 /* 00 for adjust shutter */
512 reg_w(gspca_dev
, 0x00, 0x0d02, 0x01);
513 reg_w(gspca_dev
, 0x00, 0x8169, 0x25);
514 reg_w(gspca_dev
, 0x00, 0x0d01, 0x02);
517 static void spca500_setmode(struct gspca_dev
*gspca_dev
,
518 __u8 xmult
, __u8 ymult
)
522 /* set x multiplier */
523 reg_w(gspca_dev
, 0, 0x8001, xmult
);
525 /* set y multiplier */
526 reg_w(gspca_dev
, 0, 0x8002, ymult
);
528 /* use compressed mode, VGA, with mode specific subsample */
529 mode
= gspca_dev
->cam
.cam_mode
[(int) gspca_dev
->curr_mode
].priv
;
530 reg_w(gspca_dev
, 0, 0x8003, mode
<< 4);
533 static int spca500_full_reset(struct gspca_dev
*gspca_dev
)
537 /* send the reset command */
538 err
= reg_w(gspca_dev
, 0xe0, 0x0001, 0x0000);
542 /* wait for the reset to complete */
543 err
= reg_r_wait(gspca_dev
, 0x06, 0x0000, 0x0000);
546 err
= reg_w(gspca_dev
, 0xe0, 0x0000, 0x0000);
549 err
= reg_r_wait(gspca_dev
, 0x06, 0, 0);
551 PDEBUG(D_ERR
, "reg_r_wait() failed");
558 /* Synchro the Bridge with sensor */
559 /* Maybe that will work on all spca500 chip */
560 /* because i only own a clicksmart310 try for that chip */
561 /* using spca50x_set_packet_size() cause an Ooops here */
562 /* usb_set_interface from kernel 2.6.x clear all the urb stuff */
563 /* up-port the same feature as in 2.4.x kernel */
564 static int spca500_synch310(struct gspca_dev
*gspca_dev
)
566 if (usb_set_interface(gspca_dev
->dev
, gspca_dev
->iface
, 0) < 0) {
567 PDEBUG(D_ERR
, "Set packet size: set interface error");
570 spca500_ping310(gspca_dev
);
572 reg_r(gspca_dev
, 0x0d00, 1);
574 /* need alt setting here */
575 PDEBUG(D_PACK
, "ClickSmart310 sync alt: %d", gspca_dev
->alt
);
577 /* Windoze use pipe with altsetting 6 why 7 here */
578 if (usb_set_interface(gspca_dev
->dev
,
580 gspca_dev
->alt
) < 0) {
581 PDEBUG(D_ERR
, "Set packet size: set interface error");
589 static void spca500_reinit(struct gspca_dev
*gspca_dev
)
594 /* some unknown command from Aiptek pocket dv and family300 */
596 reg_w(gspca_dev
, 0x00, 0x0d01, 0x01);
597 reg_w(gspca_dev
, 0x00, 0x0d03, 0x00);
598 reg_w(gspca_dev
, 0x00, 0x0d02, 0x01);
600 /* enable drop packet */
601 reg_w(gspca_dev
, 0x00, 0x850a, 0x0001);
603 err
= spca50x_setup_qtable(gspca_dev
, 0x00, 0x8800, 0x8840,
606 PDEBUG(D_ERR
|D_STREAM
, "spca50x_setup_qtable failed on init");
608 /* set qtable index */
609 reg_w(gspca_dev
, 0x00, 0x8880, 2);
610 /* family cam Quicksmart stuff */
611 reg_w(gspca_dev
, 0x00, 0x800a, 0x00);
612 /* Set agc transfer: synced between frames */
613 reg_w(gspca_dev
, 0x00, 0x820f, 0x01);
614 /* Init SDRAM - needed for SDRAM access */
615 reg_w(gspca_dev
, 0x00, 0x870a, 0x04);
616 /*Start init sequence or stream */
617 reg_w(gspca_dev
, 0, 0x8003, 0x00);
618 /* switch to video camera mode */
619 reg_w(gspca_dev
, 0x00, 0x8000, 0x0004);
621 if (reg_r_wait(gspca_dev
, 0, 0x8000, 0x44) != 0) {
622 reg_r(gspca_dev
, 0x816b, 1);
623 Data
= gspca_dev
->usb_buf
[0];
624 reg_w(gspca_dev
, 0x00, 0x816b, Data
);
628 /* this function is called at probe time */
629 static int sd_config(struct gspca_dev
*gspca_dev
,
630 const struct usb_device_id
*id
)
632 struct sd
*sd
= (struct sd
*) gspca_dev
;
635 cam
= &gspca_dev
->cam
;
636 sd
->subtype
= id
->driver_info
;
637 if (sd
->subtype
!= LogitechClickSmart310
) {
638 cam
->cam_mode
= vga_mode
;
639 cam
->nmodes
= ARRAY_SIZE(vga_mode
);
641 cam
->cam_mode
= sif_mode
;
642 cam
->nmodes
= ARRAY_SIZE(sif_mode
);
644 sd
->brightness
= BRIGHTNESS_DEF
;
645 sd
->contrast
= CONTRAST_DEF
;
646 sd
->colors
= COLOR_DEF
;
647 sd
->quality
= QUALITY_DEF
;
651 /* this function is called at probe and resume time */
652 static int sd_init(struct gspca_dev
*gspca_dev
)
654 struct sd
*sd
= (struct sd
*) gspca_dev
;
656 /* initialisation of spca500 based cameras is deferred */
657 PDEBUG(D_STREAM
, "SPCA500 init");
658 if (sd
->subtype
== LogitechClickSmart310
)
659 spca500_clksmart310_init(gspca_dev
);
661 spca500_initialise(gspca_dev); */
662 PDEBUG(D_STREAM
, "SPCA500 init done");
666 static int sd_start(struct gspca_dev
*gspca_dev
)
668 struct sd
*sd
= (struct sd
*) gspca_dev
;
673 /* create the JPEG header */
674 jpeg_define(sd
->jpeg_hdr
, gspca_dev
->height
, gspca_dev
->width
,
675 0x22); /* JPEG 411 */
676 jpeg_set_qual(sd
->jpeg_hdr
, sd
->quality
);
678 if (sd
->subtype
== LogitechClickSmart310
) {
686 /* is there a sensor here ? */
687 reg_r(gspca_dev
, 0x8a04, 1);
688 PDEBUG(D_STREAM
, "Spca500 Sensor Address 0x%02x",
689 gspca_dev
->usb_buf
[0]);
690 PDEBUG(D_STREAM
, "Spca500 curr_mode: %d Xmult: 0x%02x, Ymult: 0x%02x",
691 gspca_dev
->curr_mode
, xmult
, ymult
);
694 switch (sd
->subtype
) {
695 case LogitechClickSmart310
:
696 spca500_setmode(gspca_dev
, xmult
, ymult
);
698 /* enable drop packet */
699 reg_w(gspca_dev
, 0x00, 0x850a, 0x0001);
700 reg_w(gspca_dev
, 0x00, 0x8880, 3);
701 err
= spca50x_setup_qtable(gspca_dev
,
702 0x00, 0x8800, 0x8840,
703 qtable_creative_pccam
);
705 PDEBUG(D_ERR
, "spca50x_setup_qtable failed");
706 /* Init SDRAM - needed for SDRAM access */
707 reg_w(gspca_dev
, 0x00, 0x870a, 0x04);
709 /* switch to video camera mode */
710 reg_w(gspca_dev
, 0x00, 0x8000, 0x0004);
712 if (reg_r_wait(gspca_dev
, 0, 0x8000, 0x44) != 0)
713 PDEBUG(D_ERR
, "reg_r_wait() failed");
715 reg_r(gspca_dev
, 0x816b, 1);
716 Data
= gspca_dev
->usb_buf
[0];
717 reg_w(gspca_dev
, 0x00, 0x816b, Data
);
719 spca500_synch310(gspca_dev
);
721 write_vector(gspca_dev
, spca500_visual_defaults
);
722 spca500_setmode(gspca_dev
, xmult
, ymult
);
723 /* enable drop packet */
724 err
= reg_w(gspca_dev
, 0x00, 0x850a, 0x0001);
726 PDEBUG(D_ERR
, "failed to enable drop packet");
727 reg_w(gspca_dev
, 0x00, 0x8880, 3);
728 err
= spca50x_setup_qtable(gspca_dev
,
729 0x00, 0x8800, 0x8840,
730 qtable_creative_pccam
);
732 PDEBUG(D_ERR
, "spca50x_setup_qtable failed");
734 /* Init SDRAM - needed for SDRAM access */
735 reg_w(gspca_dev
, 0x00, 0x870a, 0x04);
737 /* switch to video camera mode */
738 reg_w(gspca_dev
, 0x00, 0x8000, 0x0004);
740 if (reg_r_wait(gspca_dev
, 0, 0x8000, 0x44) != 0)
741 PDEBUG(D_ERR
, "reg_r_wait() failed");
743 reg_r(gspca_dev
, 0x816b, 1);
744 Data
= gspca_dev
->usb_buf
[0];
745 reg_w(gspca_dev
, 0x00, 0x816b, Data
);
747 case CreativePCCam300
: /* Creative PC-CAM 300 640x480 CCD */
748 case IntelPocketPCCamera
: /* FIXME: Temporary fix for
749 * Intel Pocket PC Camera
750 * - NWG (Sat 29th March 2003) */
752 /* do a full reset */
753 err
= spca500_full_reset(gspca_dev
);
755 PDEBUG(D_ERR
, "spca500_full_reset failed");
757 /* enable drop packet */
758 err
= reg_w(gspca_dev
, 0x00, 0x850a, 0x0001);
760 PDEBUG(D_ERR
, "failed to enable drop packet");
761 reg_w(gspca_dev
, 0x00, 0x8880, 3);
762 err
= spca50x_setup_qtable(gspca_dev
,
763 0x00, 0x8800, 0x8840,
764 qtable_creative_pccam
);
766 PDEBUG(D_ERR
, "spca50x_setup_qtable failed");
768 spca500_setmode(gspca_dev
, xmult
, ymult
);
769 reg_w(gspca_dev
, 0x20, 0x0001, 0x0004);
771 /* switch to video camera mode */
772 reg_w(gspca_dev
, 0x00, 0x8000, 0x0004);
774 if (reg_r_wait(gspca_dev
, 0, 0x8000, 0x44) != 0)
775 PDEBUG(D_ERR
, "reg_r_wait() failed");
777 reg_r(gspca_dev
, 0x816b, 1);
778 Data
= gspca_dev
->usb_buf
[0];
779 reg_w(gspca_dev
, 0x00, 0x816b, Data
);
781 /* write_vector(gspca_dev, spca500_visual_defaults); */
783 case KodakEZ200
: /* Kodak EZ200 */
785 /* do a full reset */
786 err
= spca500_full_reset(gspca_dev
);
788 PDEBUG(D_ERR
, "spca500_full_reset failed");
789 /* enable drop packet */
790 reg_w(gspca_dev
, 0x00, 0x850a, 0x0001);
791 reg_w(gspca_dev
, 0x00, 0x8880, 0);
792 err
= spca50x_setup_qtable(gspca_dev
,
793 0x00, 0x8800, 0x8840,
796 PDEBUG(D_ERR
, "spca50x_setup_qtable failed");
797 spca500_setmode(gspca_dev
, xmult
, ymult
);
799 reg_w(gspca_dev
, 0x20, 0x0001, 0x0004);
801 /* switch to video camera mode */
802 reg_w(gspca_dev
, 0x00, 0x8000, 0x0004);
804 if (reg_r_wait(gspca_dev
, 0, 0x8000, 0x44) != 0)
805 PDEBUG(D_ERR
, "reg_r_wait() failed");
807 reg_r(gspca_dev
, 0x816b, 1);
808 Data
= gspca_dev
->usb_buf
[0];
809 reg_w(gspca_dev
, 0x00, 0x816b, Data
);
811 /* write_vector(gspca_dev, spca500_visual_defaults); */
815 case DLinkDSC350
: /* FamilyCam 300 */
816 case AiptekPocketDV
: /* Aiptek PocketDV */
817 case Gsmartmini
: /*Mustek Gsmart Mini */
818 case MustekGsmart300
: /* Mustek Gsmart 300 */
823 spca500_reinit(gspca_dev
);
824 reg_w(gspca_dev
, 0x00, 0x0d01, 0x01);
825 /* enable drop packet */
826 reg_w(gspca_dev
, 0x00, 0x850a, 0x0001);
828 err
= spca50x_setup_qtable(gspca_dev
,
829 0x00, 0x8800, 0x8840, qtable_pocketdv
);
831 PDEBUG(D_ERR
, "spca50x_setup_qtable failed");
832 reg_w(gspca_dev
, 0x00, 0x8880, 2);
834 /* familycam Quicksmart pocketDV stuff */
835 reg_w(gspca_dev
, 0x00, 0x800a, 0x00);
836 /* Set agc transfer: synced between frames */
837 reg_w(gspca_dev
, 0x00, 0x820f, 0x01);
838 /* Init SDRAM - needed for SDRAM access */
839 reg_w(gspca_dev
, 0x00, 0x870a, 0x04);
841 spca500_setmode(gspca_dev
, xmult
, ymult
);
842 /* switch to video camera mode */
843 reg_w(gspca_dev
, 0x00, 0x8000, 0x0004);
845 reg_r_wait(gspca_dev
, 0, 0x8000, 0x44);
847 reg_r(gspca_dev
, 0x816b, 1);
848 Data
= gspca_dev
->usb_buf
[0];
849 reg_w(gspca_dev
, 0x00, 0x816b, Data
);
851 case LogitechTraveler
:
852 case LogitechClickSmart510
:
853 reg_w(gspca_dev
, 0x02, 0x00, 0x00);
854 /* enable drop packet */
855 reg_w(gspca_dev
, 0x00, 0x850a, 0x0001);
857 err
= spca50x_setup_qtable(gspca_dev
,
859 0x8840, qtable_creative_pccam
);
861 PDEBUG(D_ERR
, "spca50x_setup_qtable failed");
862 reg_w(gspca_dev
, 0x00, 0x8880, 3);
863 reg_w(gspca_dev
, 0x00, 0x800a, 0x00);
864 /* Init SDRAM - needed for SDRAM access */
865 reg_w(gspca_dev
, 0x00, 0x870a, 0x04);
867 spca500_setmode(gspca_dev
, xmult
, ymult
);
869 /* switch to video camera mode */
870 reg_w(gspca_dev
, 0x00, 0x8000, 0x0004);
871 reg_r_wait(gspca_dev
, 0, 0x8000, 0x44);
873 reg_r(gspca_dev
, 0x816b, 1);
874 Data
= gspca_dev
->usb_buf
[0];
875 reg_w(gspca_dev
, 0x00, 0x816b, Data
);
876 write_vector(gspca_dev
, Clicksmart510_defaults
);
882 static void sd_stopN(struct gspca_dev
*gspca_dev
)
884 reg_w(gspca_dev
, 0, 0x8003, 0x00);
886 /* switch to video camera mode */
887 reg_w(gspca_dev
, 0x00, 0x8000, 0x0004);
888 reg_r(gspca_dev
, 0x8000, 1);
889 PDEBUG(D_STREAM
, "stop SPCA500 done reg8000: 0x%2x",
890 gspca_dev
->usb_buf
[0]);
893 static void sd_pkt_scan(struct gspca_dev
*gspca_dev
,
894 u8
*data
, /* isoc packet */
895 int len
) /* iso packet length */
897 struct sd
*sd
= (struct sd
*) gspca_dev
;
899 static __u8 ffd9
[] = {0xff, 0xd9};
901 /* frames are jpeg 4.1.1 without 0xff escape */
902 if (data
[0] == 0xff) {
903 if (data
[1] != 0x01) { /* drop packet */
904 /* gspca_dev->last_packet_type = DISCARD_PACKET; */
907 gspca_frame_add(gspca_dev
, LAST_PACKET
,
910 /* put the JPEG header in the new frame */
911 gspca_frame_add(gspca_dev
, FIRST_PACKET
,
912 sd
->jpeg_hdr
, JPEG_HDR_SZ
);
914 data
+= SPCA500_OFFSET_DATA
;
915 len
-= SPCA500_OFFSET_DATA
;
921 /* add 0x00 after 0xff */
924 if (data
[i
] == 0xff) {
925 gspca_frame_add(gspca_dev
, INTER_PACKET
,
934 gspca_frame_add(gspca_dev
, INTER_PACKET
, data
, len
);
937 static void setbrightness(struct gspca_dev
*gspca_dev
)
939 struct sd
*sd
= (struct sd
*) gspca_dev
;
941 reg_w(gspca_dev
, 0x00, 0x8167,
942 (__u8
) (sd
->brightness
- 128));
945 static void setcontrast(struct gspca_dev
*gspca_dev
)
947 struct sd
*sd
= (struct sd
*) gspca_dev
;
949 reg_w(gspca_dev
, 0x00, 0x8168, sd
->contrast
);
952 static void setcolors(struct gspca_dev
*gspca_dev
)
954 struct sd
*sd
= (struct sd
*) gspca_dev
;
956 reg_w(gspca_dev
, 0x00, 0x8169, sd
->colors
);
959 static int sd_setbrightness(struct gspca_dev
*gspca_dev
, __s32 val
)
961 struct sd
*sd
= (struct sd
*) gspca_dev
;
963 sd
->brightness
= val
;
964 if (gspca_dev
->streaming
)
965 setbrightness(gspca_dev
);
969 static int sd_getbrightness(struct gspca_dev
*gspca_dev
, __s32
*val
)
971 struct sd
*sd
= (struct sd
*) gspca_dev
;
973 *val
= sd
->brightness
;
977 static int sd_setcontrast(struct gspca_dev
*gspca_dev
, __s32 val
)
979 struct sd
*sd
= (struct sd
*) gspca_dev
;
982 if (gspca_dev
->streaming
)
983 setcontrast(gspca_dev
);
987 static int sd_getcontrast(struct gspca_dev
*gspca_dev
, __s32
*val
)
989 struct sd
*sd
= (struct sd
*) gspca_dev
;
995 static int sd_setcolors(struct gspca_dev
*gspca_dev
, __s32 val
)
997 struct sd
*sd
= (struct sd
*) gspca_dev
;
1000 if (gspca_dev
->streaming
)
1001 setcolors(gspca_dev
);
1005 static int sd_getcolors(struct gspca_dev
*gspca_dev
, __s32
*val
)
1007 struct sd
*sd
= (struct sd
*) gspca_dev
;
1013 static int sd_set_jcomp(struct gspca_dev
*gspca_dev
,
1014 struct v4l2_jpegcompression
*jcomp
)
1016 struct sd
*sd
= (struct sd
*) gspca_dev
;
1018 if (jcomp
->quality
< QUALITY_MIN
)
1019 sd
->quality
= QUALITY_MIN
;
1020 else if (jcomp
->quality
> QUALITY_MAX
)
1021 sd
->quality
= QUALITY_MAX
;
1023 sd
->quality
= jcomp
->quality
;
1024 if (gspca_dev
->streaming
)
1025 jpeg_set_qual(sd
->jpeg_hdr
, sd
->quality
);
1029 static int sd_get_jcomp(struct gspca_dev
*gspca_dev
,
1030 struct v4l2_jpegcompression
*jcomp
)
1032 struct sd
*sd
= (struct sd
*) gspca_dev
;
1034 memset(jcomp
, 0, sizeof *jcomp
);
1035 jcomp
->quality
= sd
->quality
;
1036 jcomp
->jpeg_markers
= V4L2_JPEG_MARKER_DHT
1037 | V4L2_JPEG_MARKER_DQT
;
1041 /* sub-driver description */
1042 static const struct sd_desc sd_desc
= {
1043 .name
= MODULE_NAME
,
1045 .nctrls
= ARRAY_SIZE(sd_ctrls
),
1046 .config
= sd_config
,
1050 .pkt_scan
= sd_pkt_scan
,
1051 .get_jcomp
= sd_get_jcomp
,
1052 .set_jcomp
= sd_set_jcomp
,
1055 /* -- module initialisation -- */
1056 static const struct usb_device_id device_table
[] = {
1057 {USB_DEVICE(0x040a, 0x0300), .driver_info
= KodakEZ200
},
1058 {USB_DEVICE(0x041e, 0x400a), .driver_info
= CreativePCCam300
},
1059 {USB_DEVICE(0x046d, 0x0890), .driver_info
= LogitechTraveler
},
1060 {USB_DEVICE(0x046d, 0x0900), .driver_info
= LogitechClickSmart310
},
1061 {USB_DEVICE(0x046d, 0x0901), .driver_info
= LogitechClickSmart510
},
1062 {USB_DEVICE(0x04a5, 0x300c), .driver_info
= BenqDC1016
},
1063 {USB_DEVICE(0x04fc, 0x7333), .driver_info
= PalmPixDC85
},
1064 {USB_DEVICE(0x055f, 0xc200), .driver_info
= MustekGsmart300
},
1065 {USB_DEVICE(0x055f, 0xc220), .driver_info
= Gsmartmini
},
1066 {USB_DEVICE(0x06bd, 0x0404), .driver_info
= AgfaCl20
},
1067 {USB_DEVICE(0x06be, 0x0800), .driver_info
= Optimedia
},
1068 {USB_DEVICE(0x084d, 0x0003), .driver_info
= DLinkDSC350
},
1069 {USB_DEVICE(0x08ca, 0x0103), .driver_info
= AiptekPocketDV
},
1070 {USB_DEVICE(0x2899, 0x012c), .driver_info
= ToptroIndus
},
1071 {USB_DEVICE(0x8086, 0x0630), .driver_info
= IntelPocketPCCamera
},
1074 MODULE_DEVICE_TABLE(usb
, device_table
);
1076 /* -- device connect -- */
1077 static int sd_probe(struct usb_interface
*intf
,
1078 const struct usb_device_id
*id
)
1080 return gspca_dev_probe(intf
, id
, &sd_desc
, sizeof(struct sd
),
1084 static struct usb_driver sd_driver
= {
1085 .name
= MODULE_NAME
,
1086 .id_table
= device_table
,
1088 .disconnect
= gspca_disconnect
,
1090 .suspend
= gspca_suspend
,
1091 .resume
= gspca_resume
,
1095 module_usb_driver(sd_driver
);