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 __u8 packet[ISO_MAX_SIZE + 128];
36 /* !! no more than 128 ff in an ISO packet */
38 unsigned char brightness;
39 unsigned char contrast;
42 #define QUALITY_MIN 70
43 #define QUALITY_MAX 95
44 #define QUALITY_DEF 85
48 #define AiptekPocketDV 1
50 #define CreativePCCam300 3
53 #define IntelPocketPCCamera 6
55 #define LogitechClickSmart310 8
56 #define LogitechClickSmart510 9
57 #define LogitechTraveler 10
58 #define MustekGsmart300 11
60 #define PalmPixDC85 13
61 #define ToptroIndus 14
66 /* V4L2 controls supported by the driver */
67 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
68 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
69 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
70 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
71 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
72 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
74 static struct ctrl sd_ctrls[] = {
77 .id = V4L2_CID_BRIGHTNESS,
78 .type = V4L2_CTRL_TYPE_INTEGER,
83 #define BRIGHTNESS_DEF 127
84 .default_value = BRIGHTNESS_DEF,
86 .set = sd_setbrightness,
87 .get = sd_getbrightness,
91 .id = V4L2_CID_CONTRAST,
92 .type = V4L2_CTRL_TYPE_INTEGER,
97 #define CONTRAST_DEF 31
98 .default_value = CONTRAST_DEF,
100 .set = sd_setcontrast,
101 .get = sd_getcontrast,
105 .id = V4L2_CID_SATURATION,
106 .type = V4L2_CTRL_TYPE_INTEGER,
112 .default_value = COLOR_DEF,
119 static const struct v4l2_pix_format vga_mode[] = {
120 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
122 .sizeimage = 320 * 240 * 3 / 8 + 590,
123 .colorspace = V4L2_COLORSPACE_JPEG,
125 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
127 .sizeimage = 640 * 480 * 3 / 8 + 590,
128 .colorspace = V4L2_COLORSPACE_JPEG,
132 static const struct v4l2_pix_format sif_mode[] = {
133 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
135 .sizeimage = 176 * 144 * 3 / 8 + 590,
136 .colorspace = V4L2_COLORSPACE_JPEG,
138 {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
140 .sizeimage = 352 * 288 * 3 / 8 + 590,
141 .colorspace = V4L2_COLORSPACE_JPEG,
145 /* Frame packet header offsets for the spca500 */
146 #define SPCA500_OFFSET_PADDINGLB 2
147 #define SPCA500_OFFSET_PADDINGHB 3
148 #define SPCA500_OFFSET_MODE 4
149 #define SPCA500_OFFSET_IMGWIDTH 5
150 #define SPCA500_OFFSET_IMGHEIGHT 6
151 #define SPCA500_OFFSET_IMGMODE 7
152 #define SPCA500_OFFSET_QTBLINDEX 8
153 #define SPCA500_OFFSET_FRAMSEQ 9
154 #define SPCA500_OFFSET_CDSPINFO 10
155 #define SPCA500_OFFSET_GPIO 11
156 #define SPCA500_OFFSET_AUGPIO 12
157 #define SPCA500_OFFSET_DATA 16
160 static const __u16 spca500_visual_defaults[][3] = {
161 {0x00, 0x0003, 0x816b}, /* SSI not active sync with vsync,
163 * saturation/hue enable,
164 * brightness/contrast enable.
166 {0x00, 0x0000, 0x8167}, /* brightness = 0 */
167 {0x00, 0x0020, 0x8168}, /* contrast = 0 */
168 {0x00, 0x0003, 0x816b}, /* SSI not active sync with vsync,
169 * hue (H byte) = 0, saturation/hue enable,
170 * brightness/contrast enable.
171 * was 0x0003, now 0x0000.
173 {0x00, 0x0000, 0x816a}, /* hue (L byte) = 0 */
174 {0x00, 0x0020, 0x8169}, /* saturation = 0x20 */
175 {0x00, 0x0050, 0x8157}, /* edge gain high threshold */
176 {0x00, 0x0030, 0x8158}, /* edge gain low threshold */
177 {0x00, 0x0028, 0x8159}, /* edge bandwidth high threshold */
178 {0x00, 0x000a, 0x815a}, /* edge bandwidth low threshold */
179 {0x00, 0x0001, 0x8202}, /* clock rate compensation = 1/25 sec/frame */
180 {0x0c, 0x0004, 0x0000},
184 static const __u16 Clicksmart510_defaults[][3] = {
185 {0x00, 0x00, 0x8211},
186 {0x00, 0x01, 0x82c0},
187 {0x00, 0x10, 0x82cb},
188 {0x00, 0x0f, 0x800d},
189 {0x00, 0x82, 0x8225},
190 {0x00, 0x21, 0x8228},
191 {0x00, 0x00, 0x8203},
192 {0x00, 0x00, 0x8204},
193 {0x00, 0x08, 0x8205},
194 {0x00, 0xf8, 0x8206},
195 {0x00, 0x28, 0x8207},
196 {0x00, 0xa0, 0x8208},
197 {0x00, 0x08, 0x824a},
198 {0x00, 0x08, 0x8214},
199 {0x00, 0x80, 0x82c1},
200 {0x00, 0x00, 0x82c2},
201 {0x00, 0x00, 0x82ca},
202 {0x00, 0x80, 0x82c1},
203 {0x00, 0x04, 0x82c2},
204 {0x00, 0x00, 0x82ca},
205 {0x00, 0xfc, 0x8100},
206 {0x00, 0xfc, 0x8105},
207 {0x00, 0x30, 0x8101},
208 {0x00, 0x00, 0x8102},
209 {0x00, 0x00, 0x8103},
210 {0x00, 0x66, 0x8107},
211 {0x00, 0x00, 0x816b},
212 {0x00, 0x00, 0x8155},
213 {0x00, 0x01, 0x8156},
214 {0x00, 0x60, 0x8157},
215 {0x00, 0x40, 0x8158},
216 {0x00, 0x0a, 0x8159},
217 {0x00, 0x06, 0x815a},
218 {0x00, 0x00, 0x813f},
219 {0x00, 0x00, 0x8200},
220 {0x00, 0x19, 0x8201},
221 {0x00, 0x00, 0x82c1},
222 {0x00, 0xa0, 0x82c2},
223 {0x00, 0x00, 0x82ca},
224 {0x00, 0x00, 0x8117},
225 {0x00, 0x00, 0x8118},
226 {0x00, 0x65, 0x8119},
227 {0x00, 0x00, 0x811a},
228 {0x00, 0x00, 0x811b},
229 {0x00, 0x55, 0x811c},
230 {0x00, 0x65, 0x811d},
231 {0x00, 0x55, 0x811e},
232 {0x00, 0x16, 0x811f},
233 {0x00, 0x19, 0x8120},
234 {0x00, 0x80, 0x8103},
235 {0x00, 0x83, 0x816b},
236 {0x00, 0x25, 0x8168},
237 {0x00, 0x01, 0x820f},
238 {0x00, 0xff, 0x8115},
239 {0x00, 0x48, 0x8116},
240 {0x00, 0x50, 0x8151},
241 {0x00, 0x40, 0x8152},
242 {0x00, 0x78, 0x8153},
243 {0x00, 0x40, 0x8154},
244 {0x00, 0x00, 0x8167},
245 {0x00, 0x20, 0x8168},
246 {0x00, 0x00, 0x816a},
247 {0x00, 0x03, 0x816b},
248 {0x00, 0x20, 0x8169},
249 {0x00, 0x60, 0x8157},
250 {0x00, 0x00, 0x8190},
251 {0x00, 0x00, 0x81a1},
252 {0x00, 0x00, 0x81b2},
253 {0x00, 0x27, 0x8191},
254 {0x00, 0x27, 0x81a2},
255 {0x00, 0x27, 0x81b3},
256 {0x00, 0x4b, 0x8192},
257 {0x00, 0x4b, 0x81a3},
258 {0x00, 0x4b, 0x81b4},
259 {0x00, 0x66, 0x8193},
260 {0x00, 0x66, 0x81a4},
261 {0x00, 0x66, 0x81b5},
262 {0x00, 0x79, 0x8194},
263 {0x00, 0x79, 0x81a5},
264 {0x00, 0x79, 0x81b6},
265 {0x00, 0x8a, 0x8195},
266 {0x00, 0x8a, 0x81a6},
267 {0x00, 0x8a, 0x81b7},
268 {0x00, 0x9b, 0x8196},
269 {0x00, 0x9b, 0x81a7},
270 {0x00, 0x9b, 0x81b8},
271 {0x00, 0xa6, 0x8197},
272 {0x00, 0xa6, 0x81a8},
273 {0x00, 0xa6, 0x81b9},
274 {0x00, 0xb2, 0x8198},
275 {0x00, 0xb2, 0x81a9},
276 {0x00, 0xb2, 0x81ba},
277 {0x00, 0xbe, 0x8199},
278 {0x00, 0xbe, 0x81aa},
279 {0x00, 0xbe, 0x81bb},
280 {0x00, 0xc8, 0x819a},
281 {0x00, 0xc8, 0x81ab},
282 {0x00, 0xc8, 0x81bc},
283 {0x00, 0xd2, 0x819b},
284 {0x00, 0xd2, 0x81ac},
285 {0x00, 0xd2, 0x81bd},
286 {0x00, 0xdb, 0x819c},
287 {0x00, 0xdb, 0x81ad},
288 {0x00, 0xdb, 0x81be},
289 {0x00, 0xe4, 0x819d},
290 {0x00, 0xe4, 0x81ae},
291 {0x00, 0xe4, 0x81bf},
292 {0x00, 0xed, 0x819e},
293 {0x00, 0xed, 0x81af},
294 {0x00, 0xed, 0x81c0},
295 {0x00, 0xf7, 0x819f},
296 {0x00, 0xf7, 0x81b0},
297 {0x00, 0xf7, 0x81c1},
298 {0x00, 0xff, 0x81a0},
299 {0x00, 0xff, 0x81b1},
300 {0x00, 0xff, 0x81c2},
301 {0x00, 0x03, 0x8156},
302 {0x00, 0x00, 0x8211},
303 {0x00, 0x20, 0x8168},
304 {0x00, 0x01, 0x8202},
305 {0x00, 0x30, 0x8101},
306 {0x00, 0x00, 0x8111},
307 {0x00, 0x00, 0x8112},
308 {0x00, 0x00, 0x8113},
309 {0x00, 0x00, 0x8114},
313 static const __u8 qtable_creative_pccam[2][64] = {
314 { /* Q-table Y-components */
315 0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12,
316 0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11,
317 0x04, 0x04, 0x05, 0x07, 0x0c, 0x11, 0x15, 0x11,
318 0x04, 0x05, 0x07, 0x09, 0x0f, 0x1a, 0x18, 0x13,
319 0x05, 0x07, 0x0b, 0x11, 0x14, 0x21, 0x1f, 0x17,
320 0x07, 0x0b, 0x11, 0x13, 0x18, 0x1f, 0x22, 0x1c,
321 0x0f, 0x13, 0x17, 0x1a, 0x1f, 0x24, 0x24, 0x1e,
322 0x16, 0x1c, 0x1d, 0x1d, 0x22, 0x1e, 0x1f, 0x1e},
323 { /* Q-table C-components */
324 0x05, 0x05, 0x07, 0x0e, 0x1e, 0x1e, 0x1e, 0x1e,
325 0x05, 0x06, 0x08, 0x14, 0x1e, 0x1e, 0x1e, 0x1e,
326 0x07, 0x08, 0x11, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
327 0x0e, 0x14, 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,
331 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e}
334 static const __u8 qtable_kodak_ez200[2][64] = {
335 { /* Q-table Y-components */
336 0x02, 0x01, 0x01, 0x02, 0x02, 0x04, 0x05, 0x06,
337 0x01, 0x01, 0x01, 0x02, 0x03, 0x06, 0x06, 0x06,
338 0x01, 0x01, 0x02, 0x02, 0x04, 0x06, 0x07, 0x06,
339 0x01, 0x02, 0x02, 0x03, 0x05, 0x09, 0x08, 0x06,
340 0x02, 0x02, 0x04, 0x06, 0x07, 0x0b, 0x0a, 0x08,
341 0x02, 0x04, 0x06, 0x06, 0x08, 0x0a, 0x0b, 0x09,
342 0x05, 0x06, 0x08, 0x09, 0x0a, 0x0c, 0x0c, 0x0a,
343 0x07, 0x09, 0x0a, 0x0a, 0x0b, 0x0a, 0x0a, 0x0a},
344 { /* Q-table C-components */
345 0x02, 0x02, 0x02, 0x05, 0x0a, 0x0a, 0x0a, 0x0a,
346 0x02, 0x02, 0x03, 0x07, 0x0a, 0x0a, 0x0a, 0x0a,
347 0x02, 0x03, 0x06, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
348 0x05, 0x07, 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,
352 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a}
355 static const __u8 qtable_pocketdv[2][64] = {
356 { /* Q-table Y-components start registers 0x8800 */
357 0x06, 0x04, 0x04, 0x06, 0x0a, 0x10, 0x14, 0x18,
358 0x05, 0x05, 0x06, 0x08, 0x0a, 0x17, 0x18, 0x16,
359 0x06, 0x05, 0x06, 0x0a, 0x10, 0x17, 0x1c, 0x16,
360 0x06, 0x07, 0x09, 0x0c, 0x14, 0x23, 0x20, 0x19,
361 0x07, 0x09, 0x0f, 0x16, 0x1b, 0x2c, 0x29, 0x1f,
362 0x0a, 0x0e, 0x16, 0x1a, 0x20, 0x2a, 0x2d, 0x25,
363 0x14, 0x1a, 0x1f, 0x23, 0x29, 0x30, 0x30, 0x28,
364 0x1d, 0x25, 0x26, 0x27, 0x2d, 0x28, 0x29, 0x28,
366 { /* Q-table C-components start registers 0x8840 */
367 0x07, 0x07, 0x0a, 0x13, 0x28, 0x28, 0x28, 0x28,
368 0x07, 0x08, 0x0a, 0x1a, 0x28, 0x28, 0x28, 0x28,
369 0x0a, 0x0a, 0x16, 0x28, 0x28, 0x28, 0x28, 0x28,
370 0x13, 0x1a, 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,
374 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28}
377 /* read 'len' bytes to gspca_dev->usb_buf */
378 static void reg_r(struct gspca_dev *gspca_dev,
382 usb_control_msg(gspca_dev->dev,
383 usb_rcvctrlpipe(gspca_dev->dev, 0),
385 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
387 index, gspca_dev->usb_buf, length, 500);
390 static int reg_w(struct gspca_dev *gspca_dev,
391 __u16 req, __u16 index, __u16 value)
395 PDEBUG(D_USBO, "reg write: [0x%02x] = 0x%02x", index, value);
396 ret = usb_control_msg(gspca_dev->dev,
397 usb_sndctrlpipe(gspca_dev->dev, 0),
399 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
400 value, index, NULL, 0, 500);
402 PDEBUG(D_ERR, "reg write: error %d", ret);
406 /* returns: negative is error, pos or zero is data */
407 static int reg_r_12(struct gspca_dev *gspca_dev,
408 __u16 req, /* bRequest */
409 __u16 index, /* wIndex */
410 __u16 length) /* wLength (1 or 2 only) */
414 gspca_dev->usb_buf[1] = 0;
415 ret = usb_control_msg(gspca_dev->dev,
416 usb_rcvctrlpipe(gspca_dev->dev, 0),
418 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
421 gspca_dev->usb_buf, length,
424 PDEBUG(D_ERR, "reg_r_12 err %d", ret);
427 return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0];
431 * Simple function to wait for a given 8-bit value to be returned from
433 * Returns: negative is error or timeout, zero is success.
435 static int reg_r_wait(struct gspca_dev *gspca_dev,
436 __u16 reg, __u16 index, __u16 value)
441 ret = reg_r_12(gspca_dev, reg, index, 1);
449 static int write_vector(struct gspca_dev *gspca_dev,
450 const __u16 data[][3])
454 while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) {
455 ret = reg_w(gspca_dev, data[i][0], data[i][2], data[i][1]);
463 static int spca50x_setup_qtable(struct gspca_dev *gspca_dev,
464 unsigned int request,
467 const __u8 qtable[2][64])
471 /* loop over y components */
472 for (i = 0; i < 64; i++) {
473 err = reg_w(gspca_dev, request, ybase + i, qtable[0][i]);
478 /* loop over c components */
479 for (i = 0; i < 64; i++) {
480 err = reg_w(gspca_dev, request, cbase + i, qtable[1][i]);
487 static void spca500_ping310(struct gspca_dev *gspca_dev)
489 reg_r(gspca_dev, 0x0d04, 2);
490 PDEBUG(D_STREAM, "ClickSmart310 ping 0x0d04 0x%02x 0x%02x",
491 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
494 static void spca500_clksmart310_init(struct gspca_dev *gspca_dev)
496 reg_r(gspca_dev, 0x0d05, 2);
497 PDEBUG(D_STREAM, "ClickSmart310 init 0x0d05 0x%02x 0x%02x",
498 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
499 reg_w(gspca_dev, 0x00, 0x8167, 0x5a);
500 spca500_ping310(gspca_dev);
502 reg_w(gspca_dev, 0x00, 0x8168, 0x22);
503 reg_w(gspca_dev, 0x00, 0x816a, 0xc0);
504 reg_w(gspca_dev, 0x00, 0x816b, 0x0b);
505 reg_w(gspca_dev, 0x00, 0x8169, 0x25);
506 reg_w(gspca_dev, 0x00, 0x8157, 0x5b);
507 reg_w(gspca_dev, 0x00, 0x8158, 0x5b);
508 reg_w(gspca_dev, 0x00, 0x813f, 0x03);
509 reg_w(gspca_dev, 0x00, 0x8151, 0x4a);
510 reg_w(gspca_dev, 0x00, 0x8153, 0x78);
511 reg_w(gspca_dev, 0x00, 0x0d01, 0x04);
512 /* 00 for adjust shutter */
513 reg_w(gspca_dev, 0x00, 0x0d02, 0x01);
514 reg_w(gspca_dev, 0x00, 0x8169, 0x25);
515 reg_w(gspca_dev, 0x00, 0x0d01, 0x02);
518 static void spca500_setmode(struct gspca_dev *gspca_dev,
519 __u8 xmult, __u8 ymult)
523 /* set x multiplier */
524 reg_w(gspca_dev, 0, 0x8001, xmult);
526 /* set y multiplier */
527 reg_w(gspca_dev, 0, 0x8002, ymult);
529 /* use compressed mode, VGA, with mode specific subsample */
530 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
531 reg_w(gspca_dev, 0, 0x8003, mode << 4);
534 static int spca500_full_reset(struct gspca_dev *gspca_dev)
538 /* send the reset command */
539 err = reg_w(gspca_dev, 0xe0, 0x0001, 0x0000);
543 /* wait for the reset to complete */
544 err = reg_r_wait(gspca_dev, 0x06, 0x0000, 0x0000);
547 err = reg_w(gspca_dev, 0xe0, 0x0000, 0x0000);
550 err = reg_r_wait(gspca_dev, 0x06, 0, 0);
552 PDEBUG(D_ERR, "reg_r_wait() failed");
559 /* Synchro the Bridge with sensor */
560 /* Maybe that will work on all spca500 chip */
561 /* because i only own a clicksmart310 try for that chip */
562 /* using spca50x_set_packet_size() cause an Ooops here */
563 /* usb_set_interface from kernel 2.6.x clear all the urb stuff */
564 /* up-port the same feature as in 2.4.x kernel */
565 static int spca500_synch310(struct gspca_dev *gspca_dev)
567 if (usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0) < 0) {
568 PDEBUG(D_ERR, "Set packet size: set interface error");
571 spca500_ping310(gspca_dev);
573 reg_r(gspca_dev, 0x0d00, 1);
575 /* need alt setting here */
576 PDEBUG(D_PACK, "ClickSmart310 sync alt: %d", gspca_dev->alt);
578 /* Windoze use pipe with altsetting 6 why 7 here */
579 if (usb_set_interface(gspca_dev->dev,
581 gspca_dev->alt) < 0) {
582 PDEBUG(D_ERR, "Set packet size: set interface error");
590 static void spca500_reinit(struct gspca_dev *gspca_dev)
595 /* some unknow command from Aiptek pocket dv and family300 */
597 reg_w(gspca_dev, 0x00, 0x0d01, 0x01);
598 reg_w(gspca_dev, 0x00, 0x0d03, 0x00);
599 reg_w(gspca_dev, 0x00, 0x0d02, 0x01);
601 /* enable drop packet */
602 reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
604 err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840,
607 PDEBUG(D_ERR|D_STREAM, "spca50x_setup_qtable failed on init");
609 /* set qtable index */
610 reg_w(gspca_dev, 0x00, 0x8880, 2);
611 /* family cam Quicksmart stuff */
612 reg_w(gspca_dev, 0x00, 0x800a, 0x00);
613 /* Set agc transfer: synced inbetween frames */
614 reg_w(gspca_dev, 0x00, 0x820f, 0x01);
615 /* Init SDRAM - needed for SDRAM access */
616 reg_w(gspca_dev, 0x00, 0x870a, 0x04);
617 /*Start init sequence or stream */
618 reg_w(gspca_dev, 0, 0x8003, 0x00);
619 /* switch to video camera mode */
620 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
622 if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0) {
623 reg_r(gspca_dev, 0x816b, 1);
624 Data = gspca_dev->usb_buf[0];
625 reg_w(gspca_dev, 0x00, 0x816b, Data);
629 /* this function is called at probe time */
630 static int sd_config(struct gspca_dev *gspca_dev,
631 const struct usb_device_id *id)
633 struct sd *sd = (struct sd *) gspca_dev;
636 cam = &gspca_dev->cam;
637 sd->subtype = id->driver_info;
638 if (sd->subtype != LogitechClickSmart310) {
639 cam->cam_mode = vga_mode;
640 cam->nmodes = ARRAY_SIZE(vga_mode);
642 cam->cam_mode = sif_mode;
643 cam->nmodes = ARRAY_SIZE(sif_mode);
645 sd->brightness = BRIGHTNESS_DEF;
646 sd->contrast = CONTRAST_DEF;
647 sd->colors = COLOR_DEF;
648 sd->quality = QUALITY_DEF;
652 /* this function is called at probe and resume time */
653 static int sd_init(struct gspca_dev *gspca_dev)
655 struct sd *sd = (struct sd *) gspca_dev;
657 /* initialisation of spca500 based cameras is deferred */
658 PDEBUG(D_STREAM, "SPCA500 init");
659 if (sd->subtype == LogitechClickSmart310)
660 spca500_clksmart310_init(gspca_dev);
662 spca500_initialise(gspca_dev); */
663 PDEBUG(D_STREAM, "SPCA500 init done");
667 static int sd_start(struct gspca_dev *gspca_dev)
669 struct sd *sd = (struct sd *) gspca_dev;
674 /* create the JPEG header */
675 sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
676 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
677 0x22); /* JPEG 411 */
678 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
680 if (sd->subtype == LogitechClickSmart310) {
688 /* is there a sensor here ? */
689 reg_r(gspca_dev, 0x8a04, 1);
690 PDEBUG(D_STREAM, "Spca500 Sensor Address 0x%02x",
691 gspca_dev->usb_buf[0]);
692 PDEBUG(D_STREAM, "Spca500 curr_mode: %d Xmult: 0x%02x, Ymult: 0x%02x",
693 gspca_dev->curr_mode, xmult, ymult);
696 switch (sd->subtype) {
697 case LogitechClickSmart310:
698 spca500_setmode(gspca_dev, xmult, ymult);
700 /* enable drop packet */
701 reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
702 reg_w(gspca_dev, 0x00, 0x8880, 3);
703 err = spca50x_setup_qtable(gspca_dev,
704 0x00, 0x8800, 0x8840,
705 qtable_creative_pccam);
707 PDEBUG(D_ERR, "spca50x_setup_qtable failed");
708 /* Init SDRAM - needed for SDRAM access */
709 reg_w(gspca_dev, 0x00, 0x870a, 0x04);
711 /* switch to video camera mode */
712 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
714 if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
715 PDEBUG(D_ERR, "reg_r_wait() failed");
717 reg_r(gspca_dev, 0x816b, 1);
718 Data = gspca_dev->usb_buf[0];
719 reg_w(gspca_dev, 0x00, 0x816b, Data);
721 spca500_synch310(gspca_dev);
723 write_vector(gspca_dev, spca500_visual_defaults);
724 spca500_setmode(gspca_dev, xmult, ymult);
725 /* enable drop packet */
726 err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
728 PDEBUG(D_ERR, "failed to enable drop packet");
729 reg_w(gspca_dev, 0x00, 0x8880, 3);
730 err = spca50x_setup_qtable(gspca_dev,
731 0x00, 0x8800, 0x8840,
732 qtable_creative_pccam);
734 PDEBUG(D_ERR, "spca50x_setup_qtable failed");
736 /* Init SDRAM - needed for SDRAM access */
737 reg_w(gspca_dev, 0x00, 0x870a, 0x04);
739 /* switch to video camera mode */
740 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
742 if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
743 PDEBUG(D_ERR, "reg_r_wait() failed");
745 reg_r(gspca_dev, 0x816b, 1);
746 Data = gspca_dev->usb_buf[0];
747 reg_w(gspca_dev, 0x00, 0x816b, Data);
749 case CreativePCCam300: /* Creative PC-CAM 300 640x480 CCD */
750 case IntelPocketPCCamera: /* FIXME: Temporary fix for
751 * Intel Pocket PC Camera
752 * - NWG (Sat 29th March 2003) */
754 /* do a full reset */
755 err = spca500_full_reset(gspca_dev);
757 PDEBUG(D_ERR, "spca500_full_reset failed");
759 /* enable drop packet */
760 err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
762 PDEBUG(D_ERR, "failed to enable drop packet");
763 reg_w(gspca_dev, 0x00, 0x8880, 3);
764 err = spca50x_setup_qtable(gspca_dev,
765 0x00, 0x8800, 0x8840,
766 qtable_creative_pccam);
768 PDEBUG(D_ERR, "spca50x_setup_qtable failed");
770 spca500_setmode(gspca_dev, xmult, ymult);
771 reg_w(gspca_dev, 0x20, 0x0001, 0x0004);
773 /* switch to video camera mode */
774 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
776 if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
777 PDEBUG(D_ERR, "reg_r_wait() failed");
779 reg_r(gspca_dev, 0x816b, 1);
780 Data = gspca_dev->usb_buf[0];
781 reg_w(gspca_dev, 0x00, 0x816b, Data);
783 /* write_vector(gspca_dev, spca500_visual_defaults); */
785 case KodakEZ200: /* Kodak EZ200 */
787 /* do a full reset */
788 err = spca500_full_reset(gspca_dev);
790 PDEBUG(D_ERR, "spca500_full_reset failed");
791 /* enable drop packet */
792 reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
793 reg_w(gspca_dev, 0x00, 0x8880, 0);
794 err = spca50x_setup_qtable(gspca_dev,
795 0x00, 0x8800, 0x8840,
798 PDEBUG(D_ERR, "spca50x_setup_qtable failed");
799 spca500_setmode(gspca_dev, xmult, ymult);
801 reg_w(gspca_dev, 0x20, 0x0001, 0x0004);
803 /* switch to video camera mode */
804 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
806 if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
807 PDEBUG(D_ERR, "reg_r_wait() failed");
809 reg_r(gspca_dev, 0x816b, 1);
810 Data = gspca_dev->usb_buf[0];
811 reg_w(gspca_dev, 0x00, 0x816b, Data);
813 /* write_vector(gspca_dev, spca500_visual_defaults); */
817 case DLinkDSC350: /* FamilyCam 300 */
818 case AiptekPocketDV: /* Aiptek PocketDV */
819 case Gsmartmini: /*Mustek Gsmart Mini */
820 case MustekGsmart300: /* Mustek Gsmart 300 */
825 spca500_reinit(gspca_dev);
826 reg_w(gspca_dev, 0x00, 0x0d01, 0x01);
827 /* enable drop packet */
828 reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
830 err = spca50x_setup_qtable(gspca_dev,
831 0x00, 0x8800, 0x8840, qtable_pocketdv);
833 PDEBUG(D_ERR, "spca50x_setup_qtable failed");
834 reg_w(gspca_dev, 0x00, 0x8880, 2);
836 /* familycam Quicksmart pocketDV stuff */
837 reg_w(gspca_dev, 0x00, 0x800a, 0x00);
838 /* Set agc transfer: synced inbetween frames */
839 reg_w(gspca_dev, 0x00, 0x820f, 0x01);
840 /* Init SDRAM - needed for SDRAM access */
841 reg_w(gspca_dev, 0x00, 0x870a, 0x04);
843 spca500_setmode(gspca_dev, xmult, ymult);
844 /* switch to video camera mode */
845 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
847 reg_r_wait(gspca_dev, 0, 0x8000, 0x44);
849 reg_r(gspca_dev, 0x816b, 1);
850 Data = gspca_dev->usb_buf[0];
851 reg_w(gspca_dev, 0x00, 0x816b, Data);
853 case LogitechTraveler:
854 case LogitechClickSmart510:
855 reg_w(gspca_dev, 0x02, 0x00, 0x00);
856 /* enable drop packet */
857 reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
859 err = spca50x_setup_qtable(gspca_dev,
861 0x8840, qtable_creative_pccam);
863 PDEBUG(D_ERR, "spca50x_setup_qtable failed");
864 reg_w(gspca_dev, 0x00, 0x8880, 3);
865 reg_w(gspca_dev, 0x00, 0x800a, 0x00);
866 /* Init SDRAM - needed for SDRAM access */
867 reg_w(gspca_dev, 0x00, 0x870a, 0x04);
869 spca500_setmode(gspca_dev, xmult, ymult);
871 /* switch to video camera mode */
872 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
873 reg_r_wait(gspca_dev, 0, 0x8000, 0x44);
875 reg_r(gspca_dev, 0x816b, 1);
876 Data = gspca_dev->usb_buf[0];
877 reg_w(gspca_dev, 0x00, 0x816b, Data);
878 write_vector(gspca_dev, Clicksmart510_defaults);
884 static void sd_stopN(struct gspca_dev *gspca_dev)
886 reg_w(gspca_dev, 0, 0x8003, 0x00);
888 /* switch to video camera mode */
889 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
890 reg_r(gspca_dev, 0x8000, 1);
891 PDEBUG(D_STREAM, "stop SPCA500 done reg8000: 0x%2x",
892 gspca_dev->usb_buf[0]);
895 static void sd_stop0(struct gspca_dev *gspca_dev)
897 struct sd *sd = (struct sd *) gspca_dev;
902 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
903 struct gspca_frame *frame, /* target */
904 __u8 *data, /* isoc packet */
905 int len) /* iso packet length */
907 struct sd *sd = (struct sd *) gspca_dev;
910 static __u8 ffd9[] = {0xff, 0xd9};
912 /* frames are jpeg 4.1.1 without 0xff escape */
913 if (data[0] == 0xff) {
914 if (data[1] != 0x01) { /* drop packet */
915 /* gspca_dev->last_packet_type = DISCARD_PACKET; */
918 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
921 /* put the JPEG header in the new frame */
922 gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
923 sd->jpeg_hdr, JPEG_HDR_SZ);
925 data += SPCA500_OFFSET_DATA;
926 len -= SPCA500_OFFSET_DATA;
932 /* add 0x00 after 0xff */
933 for (i = len; --i >= 0; )
936 if (i < 0) { /* no 0xff */
937 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
942 for (i = 0; i < len; i++) {
947 gspca_frame_add(gspca_dev, INTER_PACKET, frame,
948 sd->packet, d - sd->packet);
951 static void setbrightness(struct gspca_dev *gspca_dev)
953 struct sd *sd = (struct sd *) gspca_dev;
955 reg_w(gspca_dev, 0x00, 0x8167,
956 (__u8) (sd->brightness - 128));
959 static void setcontrast(struct gspca_dev *gspca_dev)
961 struct sd *sd = (struct sd *) gspca_dev;
963 reg_w(gspca_dev, 0x00, 0x8168, sd->contrast);
966 static void setcolors(struct gspca_dev *gspca_dev)
968 struct sd *sd = (struct sd *) gspca_dev;
970 reg_w(gspca_dev, 0x00, 0x8169, sd->colors);
973 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
975 struct sd *sd = (struct sd *) gspca_dev;
977 sd->brightness = val;
978 if (gspca_dev->streaming)
979 setbrightness(gspca_dev);
983 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
985 struct sd *sd = (struct sd *) gspca_dev;
987 *val = sd->brightness;
991 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
993 struct sd *sd = (struct sd *) gspca_dev;
996 if (gspca_dev->streaming)
997 setcontrast(gspca_dev);
1001 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1003 struct sd *sd = (struct sd *) gspca_dev;
1005 *val = sd->contrast;
1009 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1011 struct sd *sd = (struct sd *) gspca_dev;
1014 if (gspca_dev->streaming)
1015 setcolors(gspca_dev);
1019 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1021 struct sd *sd = (struct sd *) gspca_dev;
1027 static int sd_set_jcomp(struct gspca_dev *gspca_dev,
1028 struct v4l2_jpegcompression *jcomp)
1030 struct sd *sd = (struct sd *) gspca_dev;
1032 if (jcomp->quality < QUALITY_MIN)
1033 sd->quality = QUALITY_MIN;
1034 else if (jcomp->quality > QUALITY_MAX)
1035 sd->quality = QUALITY_MAX;
1037 sd->quality = jcomp->quality;
1038 if (gspca_dev->streaming)
1039 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
1043 static int sd_get_jcomp(struct gspca_dev *gspca_dev,
1044 struct v4l2_jpegcompression *jcomp)
1046 struct sd *sd = (struct sd *) gspca_dev;
1048 memset(jcomp, 0, sizeof *jcomp);
1049 jcomp->quality = sd->quality;
1050 jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
1051 | V4L2_JPEG_MARKER_DQT;
1055 /* sub-driver description */
1056 static struct sd_desc sd_desc = {
1057 .name = MODULE_NAME,
1059 .nctrls = ARRAY_SIZE(sd_ctrls),
1060 .config = sd_config,
1065 .pkt_scan = sd_pkt_scan,
1066 .get_jcomp = sd_get_jcomp,
1067 .set_jcomp = sd_set_jcomp,
1070 /* -- module initialisation -- */
1071 static const __devinitdata struct usb_device_id device_table[] = {
1072 {USB_DEVICE(0x040a, 0x0300), .driver_info = KodakEZ200},
1073 {USB_DEVICE(0x041e, 0x400a), .driver_info = CreativePCCam300},
1074 {USB_DEVICE(0x046d, 0x0890), .driver_info = LogitechTraveler},
1075 {USB_DEVICE(0x046d, 0x0900), .driver_info = LogitechClickSmart310},
1076 {USB_DEVICE(0x046d, 0x0901), .driver_info = LogitechClickSmart510},
1077 {USB_DEVICE(0x04a5, 0x300c), .driver_info = BenqDC1016},
1078 {USB_DEVICE(0x04fc, 0x7333), .driver_info = PalmPixDC85},
1079 {USB_DEVICE(0x055f, 0xc200), .driver_info = MustekGsmart300},
1080 {USB_DEVICE(0x055f, 0xc220), .driver_info = Gsmartmini},
1081 {USB_DEVICE(0x06bd, 0x0404), .driver_info = AgfaCl20},
1082 {USB_DEVICE(0x06be, 0x0800), .driver_info = Optimedia},
1083 {USB_DEVICE(0x084d, 0x0003), .driver_info = DLinkDSC350},
1084 {USB_DEVICE(0x08ca, 0x0103), .driver_info = AiptekPocketDV},
1085 {USB_DEVICE(0x2899, 0x012c), .driver_info = ToptroIndus},
1086 {USB_DEVICE(0x8086, 0x0630), .driver_info = IntelPocketPCCamera},
1089 MODULE_DEVICE_TABLE(usb, device_table);
1091 /* -- device connect -- */
1092 static int sd_probe(struct usb_interface *intf,
1093 const struct usb_device_id *id)
1095 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1099 static struct usb_driver sd_driver = {
1100 .name = MODULE_NAME,
1101 .id_table = device_table,
1103 .disconnect = gspca_disconnect,
1105 .suspend = gspca_suspend,
1106 .resume = gspca_resume,
1110 /* -- module insert / remove -- */
1111 static int __init sd_mod_init(void)
1114 ret = usb_register(&sd_driver);
1117 PDEBUG(D_PROBE, "registered");
1120 static void __exit sd_mod_exit(void)
1122 usb_deregister(&sd_driver);
1123 PDEBUG(D_PROBE, "deregistered");
1126 module_init(sd_mod_init);
1127 module_exit(sd_mod_exit);