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;
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
61 /* V4L2 controls supported by the driver */
62 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
63 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
64 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
65 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
66 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
67 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
69 static struct ctrl sd_ctrls[] = {
72 .id = V4L2_CID_BRIGHTNESS,
73 .type = V4L2_CTRL_TYPE_INTEGER,
78 #define BRIGHTNESS_DEF 127
79 .default_value = BRIGHTNESS_DEF,
81 .set = sd_setbrightness,
82 .get = sd_getbrightness,
86 .id = V4L2_CID_CONTRAST,
87 .type = V4L2_CTRL_TYPE_INTEGER,
92 #define CONTRAST_DEF 31
93 .default_value = CONTRAST_DEF,
95 .set = sd_setcontrast,
96 .get = sd_getcontrast,
100 .id = V4L2_CID_SATURATION,
101 .type = V4L2_CTRL_TYPE_INTEGER,
107 .default_value = COLOR_DEF,
114 static struct v4l2_pix_format vga_mode[] = {
115 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
117 .sizeimage = 320 * 240 * 3 / 8 + 590,
118 .colorspace = V4L2_COLORSPACE_JPEG,
120 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
122 .sizeimage = 640 * 480 * 3 / 8 + 590,
123 .colorspace = V4L2_COLORSPACE_JPEG,
127 static struct v4l2_pix_format sif_mode[] = {
128 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
130 .sizeimage = 176 * 144 * 3 / 8 + 590,
131 .colorspace = V4L2_COLORSPACE_JPEG,
133 {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
135 .sizeimage = 352 * 288 * 3 / 8 + 590,
136 .colorspace = V4L2_COLORSPACE_JPEG,
140 /* Frame packet header offsets for the spca500 */
141 #define SPCA500_OFFSET_PADDINGLB 2
142 #define SPCA500_OFFSET_PADDINGHB 3
143 #define SPCA500_OFFSET_MODE 4
144 #define SPCA500_OFFSET_IMGWIDTH 5
145 #define SPCA500_OFFSET_IMGHEIGHT 6
146 #define SPCA500_OFFSET_IMGMODE 7
147 #define SPCA500_OFFSET_QTBLINDEX 8
148 #define SPCA500_OFFSET_FRAMSEQ 9
149 #define SPCA500_OFFSET_CDSPINFO 10
150 #define SPCA500_OFFSET_GPIO 11
151 #define SPCA500_OFFSET_AUGPIO 12
152 #define SPCA500_OFFSET_DATA 16
155 static const __u16 spca500_visual_defaults[][3] = {
156 {0x00, 0x0003, 0x816b}, /* SSI not active sync with vsync,
158 * saturation/hue enable,
159 * brightness/contrast enable.
161 {0x00, 0x0000, 0x8167}, /* brightness = 0 */
162 {0x00, 0x0020, 0x8168}, /* contrast = 0 */
163 {0x00, 0x0003, 0x816b}, /* SSI not active sync with vsync,
164 * hue (H byte) = 0, saturation/hue enable,
165 * brightness/contrast enable.
166 * was 0x0003, now 0x0000.
168 {0x00, 0x0000, 0x816a}, /* hue (L byte) = 0 */
169 {0x00, 0x0020, 0x8169}, /* saturation = 0x20 */
170 {0x00, 0x0050, 0x8157}, /* edge gain high threshold */
171 {0x00, 0x0030, 0x8158}, /* edge gain low threshold */
172 {0x00, 0x0028, 0x8159}, /* edge bandwidth high threshold */
173 {0x00, 0x000a, 0x815a}, /* edge bandwidth low threshold */
174 {0x00, 0x0001, 0x8202}, /* clock rate compensation = 1/25 sec/frame */
175 {0x0c, 0x0004, 0x0000},
179 static const __u16 Clicksmart510_defaults[][3] = {
180 {0x00, 0x00, 0x8211},
181 {0x00, 0x01, 0x82c0},
182 {0x00, 0x10, 0x82cb},
183 {0x00, 0x0f, 0x800d},
184 {0x00, 0x82, 0x8225},
185 {0x00, 0x21, 0x8228},
186 {0x00, 0x00, 0x8203},
187 {0x00, 0x00, 0x8204},
188 {0x00, 0x08, 0x8205},
189 {0x00, 0xf8, 0x8206},
190 {0x00, 0x28, 0x8207},
191 {0x00, 0xa0, 0x8208},
192 {0x00, 0x08, 0x824a},
193 {0x00, 0x08, 0x8214},
194 {0x00, 0x80, 0x82c1},
195 {0x00, 0x00, 0x82c2},
196 {0x00, 0x00, 0x82ca},
197 {0x00, 0x80, 0x82c1},
198 {0x00, 0x04, 0x82c2},
199 {0x00, 0x00, 0x82ca},
200 {0x00, 0xfc, 0x8100},
201 {0x00, 0xfc, 0x8105},
202 {0x00, 0x30, 0x8101},
203 {0x00, 0x00, 0x8102},
204 {0x00, 0x00, 0x8103},
205 {0x00, 0x66, 0x8107},
206 {0x00, 0x00, 0x816b},
207 {0x00, 0x00, 0x8155},
208 {0x00, 0x01, 0x8156},
209 {0x00, 0x60, 0x8157},
210 {0x00, 0x40, 0x8158},
211 {0x00, 0x0a, 0x8159},
212 {0x00, 0x06, 0x815a},
213 {0x00, 0x00, 0x813f},
214 {0x00, 0x00, 0x8200},
215 {0x00, 0x19, 0x8201},
216 {0x00, 0x00, 0x82c1},
217 {0x00, 0xa0, 0x82c2},
218 {0x00, 0x00, 0x82ca},
219 {0x00, 0x00, 0x8117},
220 {0x00, 0x00, 0x8118},
221 {0x00, 0x65, 0x8119},
222 {0x00, 0x00, 0x811a},
223 {0x00, 0x00, 0x811b},
224 {0x00, 0x55, 0x811c},
225 {0x00, 0x65, 0x811d},
226 {0x00, 0x55, 0x811e},
227 {0x00, 0x16, 0x811f},
228 {0x00, 0x19, 0x8120},
229 {0x00, 0x80, 0x8103},
230 {0x00, 0x83, 0x816b},
231 {0x00, 0x25, 0x8168},
232 {0x00, 0x01, 0x820f},
233 {0x00, 0xff, 0x8115},
234 {0x00, 0x48, 0x8116},
235 {0x00, 0x50, 0x8151},
236 {0x00, 0x40, 0x8152},
237 {0x00, 0x78, 0x8153},
238 {0x00, 0x40, 0x8154},
239 {0x00, 0x00, 0x8167},
240 {0x00, 0x20, 0x8168},
241 {0x00, 0x00, 0x816a},
242 {0x00, 0x03, 0x816b},
243 {0x00, 0x20, 0x8169},
244 {0x00, 0x60, 0x8157},
245 {0x00, 0x00, 0x8190},
246 {0x00, 0x00, 0x81a1},
247 {0x00, 0x00, 0x81b2},
248 {0x00, 0x27, 0x8191},
249 {0x00, 0x27, 0x81a2},
250 {0x00, 0x27, 0x81b3},
251 {0x00, 0x4b, 0x8192},
252 {0x00, 0x4b, 0x81a3},
253 {0x00, 0x4b, 0x81b4},
254 {0x00, 0x66, 0x8193},
255 {0x00, 0x66, 0x81a4},
256 {0x00, 0x66, 0x81b5},
257 {0x00, 0x79, 0x8194},
258 {0x00, 0x79, 0x81a5},
259 {0x00, 0x79, 0x81b6},
260 {0x00, 0x8a, 0x8195},
261 {0x00, 0x8a, 0x81a6},
262 {0x00, 0x8a, 0x81b7},
263 {0x00, 0x9b, 0x8196},
264 {0x00, 0x9b, 0x81a7},
265 {0x00, 0x9b, 0x81b8},
266 {0x00, 0xa6, 0x8197},
267 {0x00, 0xa6, 0x81a8},
268 {0x00, 0xa6, 0x81b9},
269 {0x00, 0xb2, 0x8198},
270 {0x00, 0xb2, 0x81a9},
271 {0x00, 0xb2, 0x81ba},
272 {0x00, 0xbe, 0x8199},
273 {0x00, 0xbe, 0x81aa},
274 {0x00, 0xbe, 0x81bb},
275 {0x00, 0xc8, 0x819a},
276 {0x00, 0xc8, 0x81ab},
277 {0x00, 0xc8, 0x81bc},
278 {0x00, 0xd2, 0x819b},
279 {0x00, 0xd2, 0x81ac},
280 {0x00, 0xd2, 0x81bd},
281 {0x00, 0xdb, 0x819c},
282 {0x00, 0xdb, 0x81ad},
283 {0x00, 0xdb, 0x81be},
284 {0x00, 0xe4, 0x819d},
285 {0x00, 0xe4, 0x81ae},
286 {0x00, 0xe4, 0x81bf},
287 {0x00, 0xed, 0x819e},
288 {0x00, 0xed, 0x81af},
289 {0x00, 0xed, 0x81c0},
290 {0x00, 0xf7, 0x819f},
291 {0x00, 0xf7, 0x81b0},
292 {0x00, 0xf7, 0x81c1},
293 {0x00, 0xff, 0x81a0},
294 {0x00, 0xff, 0x81b1},
295 {0x00, 0xff, 0x81c2},
296 {0x00, 0x03, 0x8156},
297 {0x00, 0x00, 0x8211},
298 {0x00, 0x20, 0x8168},
299 {0x00, 0x01, 0x8202},
300 {0x00, 0x30, 0x8101},
301 {0x00, 0x00, 0x8111},
302 {0x00, 0x00, 0x8112},
303 {0x00, 0x00, 0x8113},
304 {0x00, 0x00, 0x8114},
308 static const __u8 qtable_creative_pccam[2][64] = {
309 { /* Q-table Y-components */
310 0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12,
311 0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11,
312 0x04, 0x04, 0x05, 0x07, 0x0c, 0x11, 0x15, 0x11,
313 0x04, 0x05, 0x07, 0x09, 0x0f, 0x1a, 0x18, 0x13,
314 0x05, 0x07, 0x0b, 0x11, 0x14, 0x21, 0x1f, 0x17,
315 0x07, 0x0b, 0x11, 0x13, 0x18, 0x1f, 0x22, 0x1c,
316 0x0f, 0x13, 0x17, 0x1a, 0x1f, 0x24, 0x24, 0x1e,
317 0x16, 0x1c, 0x1d, 0x1d, 0x22, 0x1e, 0x1f, 0x1e},
318 { /* Q-table C-components */
319 0x05, 0x05, 0x07, 0x0e, 0x1e, 0x1e, 0x1e, 0x1e,
320 0x05, 0x06, 0x08, 0x14, 0x1e, 0x1e, 0x1e, 0x1e,
321 0x07, 0x08, 0x11, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
322 0x0e, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
323 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
324 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
325 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
326 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e}
329 static const __u8 qtable_kodak_ez200[2][64] = {
330 { /* Q-table Y-components */
331 0x02, 0x01, 0x01, 0x02, 0x02, 0x04, 0x05, 0x06,
332 0x01, 0x01, 0x01, 0x02, 0x03, 0x06, 0x06, 0x06,
333 0x01, 0x01, 0x02, 0x02, 0x04, 0x06, 0x07, 0x06,
334 0x01, 0x02, 0x02, 0x03, 0x05, 0x09, 0x08, 0x06,
335 0x02, 0x02, 0x04, 0x06, 0x07, 0x0b, 0x0a, 0x08,
336 0x02, 0x04, 0x06, 0x06, 0x08, 0x0a, 0x0b, 0x09,
337 0x05, 0x06, 0x08, 0x09, 0x0a, 0x0c, 0x0c, 0x0a,
338 0x07, 0x09, 0x0a, 0x0a, 0x0b, 0x0a, 0x0a, 0x0a},
339 { /* Q-table C-components */
340 0x02, 0x02, 0x02, 0x05, 0x0a, 0x0a, 0x0a, 0x0a,
341 0x02, 0x02, 0x03, 0x07, 0x0a, 0x0a, 0x0a, 0x0a,
342 0x02, 0x03, 0x06, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
343 0x05, 0x07, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
344 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
345 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
346 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
347 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a}
350 static const __u8 qtable_pocketdv[2][64] = {
351 { /* Q-table Y-components start registers 0x8800 */
352 0x06, 0x04, 0x04, 0x06, 0x0a, 0x10, 0x14, 0x18,
353 0x05, 0x05, 0x06, 0x08, 0x0a, 0x17, 0x18, 0x16,
354 0x06, 0x05, 0x06, 0x0a, 0x10, 0x17, 0x1c, 0x16,
355 0x06, 0x07, 0x09, 0x0c, 0x14, 0x23, 0x20, 0x19,
356 0x07, 0x09, 0x0f, 0x16, 0x1b, 0x2c, 0x29, 0x1f,
357 0x0a, 0x0e, 0x16, 0x1a, 0x20, 0x2a, 0x2d, 0x25,
358 0x14, 0x1a, 0x1f, 0x23, 0x29, 0x30, 0x30, 0x28,
359 0x1d, 0x25, 0x26, 0x27, 0x2d, 0x28, 0x29, 0x28,
361 { /* Q-table C-components start registers 0x8840 */
362 0x07, 0x07, 0x0a, 0x13, 0x28, 0x28, 0x28, 0x28,
363 0x07, 0x08, 0x0a, 0x1a, 0x28, 0x28, 0x28, 0x28,
364 0x0a, 0x0a, 0x16, 0x28, 0x28, 0x28, 0x28, 0x28,
365 0x13, 0x1a, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
366 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
367 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
368 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
369 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28}
372 /* read 'len' bytes to gspca_dev->usb_buf */
373 static void reg_r(struct gspca_dev *gspca_dev,
377 usb_control_msg(gspca_dev->dev,
378 usb_rcvctrlpipe(gspca_dev->dev, 0),
380 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
382 index, gspca_dev->usb_buf, length, 500);
385 static int reg_w(struct gspca_dev *gspca_dev,
386 __u16 req, __u16 index, __u16 value)
390 PDEBUG(D_USBO, "reg write: [0x%02x] = 0x%02x", index, value);
391 ret = usb_control_msg(gspca_dev->dev,
392 usb_sndctrlpipe(gspca_dev->dev, 0),
394 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
395 value, index, NULL, 0, 500);
397 PDEBUG(D_ERR, "reg write: error %d", ret);
401 /* returns: negative is error, pos or zero is data */
402 static int reg_r_12(struct gspca_dev *gspca_dev,
403 __u16 req, /* bRequest */
404 __u16 index, /* wIndex */
405 __u16 length) /* wLength (1 or 2 only) */
409 gspca_dev->usb_buf[1] = 0;
410 ret = usb_control_msg(gspca_dev->dev,
411 usb_rcvctrlpipe(gspca_dev->dev, 0),
413 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
416 gspca_dev->usb_buf, length,
419 PDEBUG(D_ERR, "reg_r_12 err %d", ret);
422 return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0];
426 * Simple function to wait for a given 8-bit value to be returned from
428 * Returns: negative is error or timeout, zero is success.
430 static int reg_r_wait(struct gspca_dev *gspca_dev,
431 __u16 reg, __u16 index, __u16 value)
436 ret = reg_r_12(gspca_dev, reg, index, 1);
444 static int write_vector(struct gspca_dev *gspca_dev,
445 const __u16 data[][3])
449 while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) {
450 ret = reg_w(gspca_dev, data[i][0], data[i][2], data[i][1]);
458 static int spca50x_setup_qtable(struct gspca_dev *gspca_dev,
459 unsigned int request,
462 const __u8 qtable[2][64])
466 /* loop over y components */
467 for (i = 0; i < 64; i++) {
468 err = reg_w(gspca_dev, request, ybase + i, qtable[0][i]);
473 /* loop over c components */
474 for (i = 0; i < 64; i++) {
475 err = reg_w(gspca_dev, request, cbase + i, qtable[1][i]);
482 static void spca500_ping310(struct gspca_dev *gspca_dev)
484 reg_r(gspca_dev, 0x0d04, 2);
485 PDEBUG(D_STREAM, "ClickSmart310 ping 0x0d04 0x%02x 0x%02x",
486 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
489 static void spca500_clksmart310_init(struct gspca_dev *gspca_dev)
491 reg_r(gspca_dev, 0x0d05, 2);
492 PDEBUG(D_STREAM, "ClickSmart310 init 0x0d05 0x%02x 0x%02x",
493 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
494 reg_w(gspca_dev, 0x00, 0x8167, 0x5a);
495 spca500_ping310(gspca_dev);
497 reg_w(gspca_dev, 0x00, 0x8168, 0x22);
498 reg_w(gspca_dev, 0x00, 0x816a, 0xc0);
499 reg_w(gspca_dev, 0x00, 0x816b, 0x0b);
500 reg_w(gspca_dev, 0x00, 0x8169, 0x25);
501 reg_w(gspca_dev, 0x00, 0x8157, 0x5b);
502 reg_w(gspca_dev, 0x00, 0x8158, 0x5b);
503 reg_w(gspca_dev, 0x00, 0x813f, 0x03);
504 reg_w(gspca_dev, 0x00, 0x8151, 0x4a);
505 reg_w(gspca_dev, 0x00, 0x8153, 0x78);
506 reg_w(gspca_dev, 0x00, 0x0d01, 0x04);
507 /* 00 for adjust shutter */
508 reg_w(gspca_dev, 0x00, 0x0d02, 0x01);
509 reg_w(gspca_dev, 0x00, 0x8169, 0x25);
510 reg_w(gspca_dev, 0x00, 0x0d01, 0x02);
513 static void spca500_setmode(struct gspca_dev *gspca_dev,
514 __u8 xmult, __u8 ymult)
518 /* set x multiplier */
519 reg_w(gspca_dev, 0, 0x8001, xmult);
521 /* set y multiplier */
522 reg_w(gspca_dev, 0, 0x8002, ymult);
524 /* use compressed mode, VGA, with mode specific subsample */
525 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
526 reg_w(gspca_dev, 0, 0x8003, mode << 4);
529 static int spca500_full_reset(struct gspca_dev *gspca_dev)
533 /* send the reset command */
534 err = reg_w(gspca_dev, 0xe0, 0x0001, 0x0000);
538 /* wait for the reset to complete */
539 err = reg_r_wait(gspca_dev, 0x06, 0x0000, 0x0000);
542 err = reg_w(gspca_dev, 0xe0, 0x0000, 0x0000);
545 err = reg_r_wait(gspca_dev, 0x06, 0, 0);
547 PDEBUG(D_ERR, "reg_r_wait() failed");
554 /* Synchro the Bridge with sensor */
555 /* Maybe that will work on all spca500 chip */
556 /* because i only own a clicksmart310 try for that chip */
557 /* using spca50x_set_packet_size() cause an Ooops here */
558 /* usb_set_interface from kernel 2.6.x clear all the urb stuff */
559 /* up-port the same feature as in 2.4.x kernel */
560 static int spca500_synch310(struct gspca_dev *gspca_dev)
562 if (usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0) < 0) {
563 PDEBUG(D_ERR, "Set packet size: set interface error");
566 spca500_ping310(gspca_dev);
568 reg_r(gspca_dev, 0x0d00, 1);
570 /* need alt setting here */
571 PDEBUG(D_PACK, "ClickSmart310 sync alt: %d", gspca_dev->alt);
573 /* Windoze use pipe with altsetting 6 why 7 here */
574 if (usb_set_interface(gspca_dev->dev,
576 gspca_dev->alt) < 0) {
577 PDEBUG(D_ERR, "Set packet size: set interface error");
585 static void spca500_reinit(struct gspca_dev *gspca_dev)
590 /* some unknow command from Aiptek pocket dv and family300 */
592 reg_w(gspca_dev, 0x00, 0x0d01, 0x01);
593 reg_w(gspca_dev, 0x00, 0x0d03, 0x00);
594 reg_w(gspca_dev, 0x00, 0x0d02, 0x01);
596 /* enable drop packet */
597 reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
599 err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840,
602 PDEBUG(D_ERR|D_STREAM, "spca50x_setup_qtable failed on init");
604 /* set qtable index */
605 reg_w(gspca_dev, 0x00, 0x8880, 2);
606 /* family cam Quicksmart stuff */
607 reg_w(gspca_dev, 0x00, 0x800a, 0x00);
608 /* Set agc transfer: synced inbetween frames */
609 reg_w(gspca_dev, 0x00, 0x820f, 0x01);
610 /* Init SDRAM - needed for SDRAM access */
611 reg_w(gspca_dev, 0x00, 0x870a, 0x04);
612 /*Start init sequence or stream */
613 reg_w(gspca_dev, 0, 0x8003, 0x00);
614 /* switch to video camera mode */
615 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
617 if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0) {
618 reg_r(gspca_dev, 0x816b, 1);
619 Data = gspca_dev->usb_buf[0];
620 reg_w(gspca_dev, 0x00, 0x816b, Data);
624 /* this function is called at probe time */
625 static int sd_config(struct gspca_dev *gspca_dev,
626 const struct usb_device_id *id)
628 struct sd *sd = (struct sd *) gspca_dev;
633 vendor = id->idVendor;
634 product = id->idProduct;
636 case 0x040a: /* Kodak cameras */
637 /* switch (product) { */
639 sd->subtype = KodakEZ200;
643 case 0x041e: /* Creative cameras */
644 /* switch (product) { */
646 sd->subtype = CreativePCCam300;
650 case 0x046d: /* Logitech Labtec */
653 sd->subtype = LogitechTraveler;
656 sd->subtype = LogitechClickSmart310;
659 sd->subtype = LogitechClickSmart510;
663 case 0x04a5: /* Benq */
664 /* switch (product) { */
666 sd->subtype = BenqDC1016;
670 case 0x04fc: /* SunPlus */
671 /* switch (product) { */
673 sd->subtype = PalmPixDC85;
677 case 0x055f: /* Mustek cameras */
680 sd->subtype = MustekGsmart300;
683 sd->subtype = Gsmartmini;
687 case 0x06bd: /* Agfa Cl20 */
688 /* switch (product) { */
690 sd->subtype = AgfaCl20;
694 case 0x06be: /* Optimedia */
695 /* switch (product) { */
697 sd->subtype = Optimedia;
701 case 0x084d: /* D-Link / Minton */
702 /* switch (product) { */
703 /* case 0x0003: * DSC-350 / S-Cam F5 */
704 sd->subtype = DLinkDSC350;
708 case 0x08ca: /* Aiptek */
709 /* switch (product) { */
711 sd->subtype = AiptekPocketDV;
715 case 0x2899: /* ToptroIndustrial */
716 /* switch (product) { */
718 sd->subtype = ToptroIndus;
722 case 0x8086: /* Intel */
723 /* switch (product) { */
724 /* case 0x0630: * Pocket PC Camera */
725 sd->subtype = IntelPocketPCCamera;
730 cam = &gspca_dev->cam;
731 cam->dev_name = (char *) id->driver_info;
733 if (sd->subtype != LogitechClickSmart310) {
734 cam->cam_mode = vga_mode;
735 cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
737 cam->cam_mode = sif_mode;
738 cam->nmodes = sizeof sif_mode / sizeof sif_mode[0];
741 sd->brightness = BRIGHTNESS_DEF;
742 sd->contrast = CONTRAST_DEF;
743 sd->colors = COLOR_DEF;
747 /* this function is called at open time */
748 static int sd_open(struct gspca_dev *gspca_dev)
750 struct sd *sd = (struct sd *) gspca_dev;
752 /* initialisation of spca500 based cameras is deferred */
753 PDEBUG(D_STREAM, "SPCA500 init");
754 if (sd->subtype == LogitechClickSmart310)
755 spca500_clksmart310_init(gspca_dev);
757 spca500_initialise(gspca_dev); */
758 PDEBUG(D_STREAM, "SPCA500 init done");
762 static void sd_start(struct gspca_dev *gspca_dev)
764 struct sd *sd = (struct sd *) gspca_dev;
769 if (sd->subtype == LogitechClickSmart310) {
777 /* is there a sensor here ? */
778 reg_r(gspca_dev, 0x8a04, 1);
779 PDEBUG(D_STREAM, "Spca500 Sensor Address 0x%02x",
780 gspca_dev->usb_buf[0]);
781 PDEBUG(D_STREAM, "Spca500 curr_mode: %d Xmult: 0x%02x, Ymult: 0x%02x",
782 gspca_dev->curr_mode, xmult, ymult);
785 switch (sd->subtype) {
786 case LogitechClickSmart310:
787 spca500_setmode(gspca_dev, xmult, ymult);
789 /* enable drop packet */
790 reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
791 reg_w(gspca_dev, 0x00, 0x8880, 3);
792 err = spca50x_setup_qtable(gspca_dev,
793 0x00, 0x8800, 0x8840,
794 qtable_creative_pccam);
796 PDEBUG(D_ERR, "spca50x_setup_qtable failed");
797 /* Init SDRAM - needed for SDRAM access */
798 reg_w(gspca_dev, 0x00, 0x870a, 0x04);
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 spca500_synch310(gspca_dev);
812 write_vector(gspca_dev, spca500_visual_defaults);
813 spca500_setmode(gspca_dev, xmult, ymult);
814 /* enable drop packet */
815 reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
816 PDEBUG(D_ERR, "failed to enable drop packet");
817 reg_w(gspca_dev, 0x00, 0x8880, 3);
818 err = spca50x_setup_qtable(gspca_dev,
819 0x00, 0x8800, 0x8840,
820 qtable_creative_pccam);
822 PDEBUG(D_ERR, "spca50x_setup_qtable failed");
824 /* Init SDRAM - needed for SDRAM access */
825 reg_w(gspca_dev, 0x00, 0x870a, 0x04);
827 /* switch to video camera mode */
828 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
830 if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
831 PDEBUG(D_ERR, "reg_r_wait() failed");
833 reg_r(gspca_dev, 0x816b, 1);
834 Data = gspca_dev->usb_buf[0];
835 reg_w(gspca_dev, 0x00, 0x816b, Data);
837 case CreativePCCam300: /* Creative PC-CAM 300 640x480 CCD */
838 case IntelPocketPCCamera: /* FIXME: Temporary fix for
839 * Intel Pocket PC Camera
840 * - NWG (Sat 29th March 2003) */
842 /* do a full reset */
843 err = spca500_full_reset(gspca_dev);
845 PDEBUG(D_ERR, "spca500_full_reset failed");
847 /* enable drop packet */
848 err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
850 PDEBUG(D_ERR, "failed to enable drop packet");
851 reg_w(gspca_dev, 0x00, 0x8880, 3);
852 err = spca50x_setup_qtable(gspca_dev,
853 0x00, 0x8800, 0x8840,
854 qtable_creative_pccam);
856 PDEBUG(D_ERR, "spca50x_setup_qtable failed");
858 spca500_setmode(gspca_dev, xmult, ymult);
859 reg_w(gspca_dev, 0x20, 0x0001, 0x0004);
861 /* switch to video camera mode */
862 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
864 if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
865 PDEBUG(D_ERR, "reg_r_wait() failed");
867 reg_r(gspca_dev, 0x816b, 1);
868 Data = gspca_dev->usb_buf[0];
869 reg_w(gspca_dev, 0x00, 0x816b, Data);
871 /* write_vector(gspca_dev, spca500_visual_defaults); */
873 case KodakEZ200: /* Kodak EZ200 */
875 /* do a full reset */
876 err = spca500_full_reset(gspca_dev);
878 PDEBUG(D_ERR, "spca500_full_reset failed");
879 /* enable drop packet */
880 reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
881 reg_w(gspca_dev, 0x00, 0x8880, 0);
882 err = spca50x_setup_qtable(gspca_dev,
883 0x00, 0x8800, 0x8840,
886 PDEBUG(D_ERR, "spca50x_setup_qtable failed");
887 spca500_setmode(gspca_dev, xmult, ymult);
889 reg_w(gspca_dev, 0x20, 0x0001, 0x0004);
891 /* switch to video camera mode */
892 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
894 if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
895 PDEBUG(D_ERR, "reg_r_wait() failed");
897 reg_r(gspca_dev, 0x816b, 1);
898 Data = gspca_dev->usb_buf[0];
899 reg_w(gspca_dev, 0x00, 0x816b, Data);
901 /* write_vector(gspca_dev, spca500_visual_defaults); */
905 case DLinkDSC350: /* FamilyCam 300 */
906 case AiptekPocketDV: /* Aiptek PocketDV */
907 case Gsmartmini: /*Mustek Gsmart Mini */
908 case MustekGsmart300: /* Mustek Gsmart 300 */
913 spca500_reinit(gspca_dev);
914 reg_w(gspca_dev, 0x00, 0x0d01, 0x01);
915 /* enable drop packet */
916 reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
918 err = spca50x_setup_qtable(gspca_dev,
919 0x00, 0x8800, 0x8840, qtable_pocketdv);
921 PDEBUG(D_ERR, "spca50x_setup_qtable failed");
922 reg_w(gspca_dev, 0x00, 0x8880, 2);
924 /* familycam Quicksmart pocketDV stuff */
925 reg_w(gspca_dev, 0x00, 0x800a, 0x00);
926 /* Set agc transfer: synced inbetween frames */
927 reg_w(gspca_dev, 0x00, 0x820f, 0x01);
928 /* Init SDRAM - needed for SDRAM access */
929 reg_w(gspca_dev, 0x00, 0x870a, 0x04);
931 spca500_setmode(gspca_dev, xmult, ymult);
932 /* switch to video camera mode */
933 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
935 reg_r_wait(gspca_dev, 0, 0x8000, 0x44);
937 reg_r(gspca_dev, 0x816b, 1);
938 Data = gspca_dev->usb_buf[0];
939 reg_w(gspca_dev, 0x00, 0x816b, Data);
941 case LogitechTraveler:
942 case LogitechClickSmart510:
943 reg_w(gspca_dev, 0x02, 0x00, 0x00);
944 /* enable drop packet */
945 reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
947 err = spca50x_setup_qtable(gspca_dev,
949 0x8840, qtable_creative_pccam);
951 PDEBUG(D_ERR, "spca50x_setup_qtable failed");
952 reg_w(gspca_dev, 0x00, 0x8880, 3);
953 reg_w(gspca_dev, 0x00, 0x800a, 0x00);
954 /* Init SDRAM - needed for SDRAM access */
955 reg_w(gspca_dev, 0x00, 0x870a, 0x04);
957 spca500_setmode(gspca_dev, xmult, ymult);
959 /* switch to video camera mode */
960 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
961 reg_r_wait(gspca_dev, 0, 0x8000, 0x44);
963 reg_r(gspca_dev, 0x816b, 1);
964 Data = gspca_dev->usb_buf[0];
965 reg_w(gspca_dev, 0x00, 0x816b, Data);
966 write_vector(gspca_dev, Clicksmart510_defaults);
971 static void sd_stopN(struct gspca_dev *gspca_dev)
973 reg_w(gspca_dev, 0, 0x8003, 0x00);
975 /* switch to video camera mode */
976 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
977 reg_r(gspca_dev, 0x8000, 1);
978 PDEBUG(D_STREAM, "stop SPCA500 done reg8000: 0x%2x",
979 gspca_dev->usb_buf[0]);
982 static void sd_stop0(struct gspca_dev *gspca_dev)
986 static void sd_close(struct gspca_dev *gspca_dev)
990 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
991 struct gspca_frame *frame, /* target */
992 __u8 *data, /* isoc packet */
993 int len) /* iso packet length */
995 struct sd *sd = (struct sd *) gspca_dev;
998 static __u8 ffd9[] = {0xff, 0xd9};
1000 /* frames are jpeg 4.1.1 without 0xff escape */
1001 if (data[0] == 0xff) {
1002 if (data[1] != 0x01) { /* drop packet */
1003 /* gspca_dev->last_packet_type = DISCARD_PACKET; */
1006 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
1009 /* put the JPEG header in the new frame */
1010 jpeg_put_header(gspca_dev, frame, sd->qindex, 0x22);
1012 data += SPCA500_OFFSET_DATA;
1013 len -= SPCA500_OFFSET_DATA;
1019 /* add 0x00 after 0xff */
1020 for (i = len; --i >= 0; )
1021 if (data[i] == 0xff)
1023 if (i < 0) { /* no 0xff */
1024 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1029 for (i = 0; i < len; i++) {
1034 gspca_frame_add(gspca_dev, INTER_PACKET, frame,
1035 sd->packet, d - sd->packet);
1038 static void setbrightness(struct gspca_dev *gspca_dev)
1040 struct sd *sd = (struct sd *) gspca_dev;
1042 reg_w(gspca_dev, 0x00, 0x8167,
1043 (__u8) (sd->brightness - 128));
1046 static void getbrightness(struct gspca_dev *gspca_dev)
1048 struct sd *sd = (struct sd *) gspca_dev;
1051 ret = reg_r_12(gspca_dev, 0x00, 0x8167, 1);
1053 sd->brightness = ret + 128;
1056 static void setcontrast(struct gspca_dev *gspca_dev)
1058 struct sd *sd = (struct sd *) gspca_dev;
1060 reg_w(gspca_dev, 0x00, 0x8168, sd->contrast);
1063 static void getcontrast(struct gspca_dev *gspca_dev)
1065 struct sd *sd = (struct sd *) gspca_dev;
1068 ret = reg_r_12(gspca_dev, 0x0, 0x8168, 1);
1073 static void setcolors(struct gspca_dev *gspca_dev)
1075 struct sd *sd = (struct sd *) gspca_dev;
1077 reg_w(gspca_dev, 0x00, 0x8169, sd->colors);
1080 static void getcolors(struct gspca_dev *gspca_dev)
1082 struct sd *sd = (struct sd *) gspca_dev;
1085 ret = reg_r_12(gspca_dev, 0x0, 0x8169, 1);
1090 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1092 struct sd *sd = (struct sd *) gspca_dev;
1094 sd->brightness = val;
1095 if (gspca_dev->streaming)
1096 setbrightness(gspca_dev);
1100 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1102 struct sd *sd = (struct sd *) gspca_dev;
1104 getbrightness(gspca_dev);
1105 *val = sd->brightness;
1109 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1111 struct sd *sd = (struct sd *) gspca_dev;
1114 if (gspca_dev->streaming)
1115 setcontrast(gspca_dev);
1119 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1121 struct sd *sd = (struct sd *) gspca_dev;
1123 getcontrast(gspca_dev);
1124 *val = sd->contrast;
1128 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1130 struct sd *sd = (struct sd *) gspca_dev;
1133 if (gspca_dev->streaming)
1134 setcolors(gspca_dev);
1138 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1140 struct sd *sd = (struct sd *) gspca_dev;
1142 getcolors(gspca_dev);
1147 /* sub-driver description */
1148 static struct sd_desc sd_desc = {
1149 .name = MODULE_NAME,
1151 .nctrls = ARRAY_SIZE(sd_ctrls),
1152 .config = sd_config,
1158 .pkt_scan = sd_pkt_scan,
1161 /* -- module initialisation -- */
1162 #define DVNM(name) .driver_info = (kernel_ulong_t) name
1163 static const __devinitdata struct usb_device_id device_table[] = {
1164 {USB_DEVICE(0x040a, 0x0300), DVNM("Kodak EZ200")},
1165 {USB_DEVICE(0x041e, 0x400a), DVNM("Creative PC-CAM 300")},
1166 {USB_DEVICE(0x046d, 0x0890), DVNM("Logitech QuickCam traveler")},
1167 {USB_DEVICE(0x046d, 0x0900), DVNM("Logitech Inc. ClickSmart 310")},
1168 {USB_DEVICE(0x046d, 0x0901), DVNM("Logitech Inc. ClickSmart 510")},
1169 {USB_DEVICE(0x04a5, 0x300c), DVNM("Benq DC1016")},
1170 {USB_DEVICE(0x04fc, 0x7333), DVNM("PalmPixDC85")},
1171 {USB_DEVICE(0x055f, 0xc200), DVNM("Mustek Gsmart 300")},
1172 {USB_DEVICE(0x055f, 0xc220), DVNM("Gsmart Mini")},
1173 {USB_DEVICE(0x06bd, 0x0404), DVNM("Agfa CL20")},
1174 {USB_DEVICE(0x06be, 0x0800), DVNM("Optimedia")},
1175 {USB_DEVICE(0x084d, 0x0003), DVNM("D-Link DSC-350")},
1176 {USB_DEVICE(0x08ca, 0x0103), DVNM("Aiptek PocketDV")},
1177 {USB_DEVICE(0x2899, 0x012c), DVNM("Toptro Industrial")},
1178 {USB_DEVICE(0x8086, 0x0630), DVNM("Intel Pocket PC Camera")},
1181 MODULE_DEVICE_TABLE(usb, device_table);
1183 /* -- device connect -- */
1184 static int sd_probe(struct usb_interface *intf,
1185 const struct usb_device_id *id)
1187 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1191 static struct usb_driver sd_driver = {
1192 .name = MODULE_NAME,
1193 .id_table = device_table,
1195 .disconnect = gspca_disconnect,
1198 /* -- module insert / remove -- */
1199 static int __init sd_mod_init(void)
1201 if (usb_register(&sd_driver) < 0)
1203 PDEBUG(D_PROBE, "registered");
1206 static void __exit sd_mod_exit(void)
1208 usb_deregister(&sd_driver);
1209 PDEBUG(D_PROBE, "deregistered");
1212 module_init(sd_mod_init);
1213 module_exit(sd_mod_exit);