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 #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
28 static const char version[] = "2.1.7";
30 MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
31 MODULE_DESCRIPTION("GSPCA/SPCA500 USB Camera Driver");
32 MODULE_LICENSE("GPL");
34 /* specific webcam descriptor */
36 struct gspca_dev gspca_dev; /* !! must be the first item */
38 __u8 packet[ISO_MAX_SIZE + 128];
39 /* !! no more than 128 ff in an ISO packet */
41 unsigned char brightness;
42 unsigned char contrast;
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
64 /* V4L2 controls supported by the driver */
65 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
66 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
67 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
68 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
69 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
70 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
72 static struct ctrl sd_ctrls[] = {
75 .id = V4L2_CID_BRIGHTNESS,
76 .type = V4L2_CTRL_TYPE_INTEGER,
81 #define BRIGHTNESS_DEF 127
82 .default_value = BRIGHTNESS_DEF,
84 .set = sd_setbrightness,
85 .get = sd_getbrightness,
89 .id = V4L2_CID_CONTRAST,
90 .type = V4L2_CTRL_TYPE_INTEGER,
95 #define CONTRAST_DEF 31
96 .default_value = CONTRAST_DEF,
98 .set = sd_setcontrast,
99 .get = sd_getcontrast,
103 .id = V4L2_CID_SATURATION,
104 .type = V4L2_CTRL_TYPE_INTEGER,
110 .default_value = COLOR_DEF,
117 static struct v4l2_pix_format vga_mode[] = {
118 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
120 .sizeimage = 320 * 240 * 3 / 8 + 590,
121 .colorspace = V4L2_COLORSPACE_JPEG,
123 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
125 .sizeimage = 640 * 480 * 3 / 8 + 590,
126 .colorspace = V4L2_COLORSPACE_JPEG,
130 static struct v4l2_pix_format sif_mode[] = {
131 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
133 .sizeimage = 176 * 144 * 3 / 8 + 590,
134 .colorspace = V4L2_COLORSPACE_JPEG,
136 {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
138 .sizeimage = 352 * 288 * 3 / 8 + 590,
139 .colorspace = V4L2_COLORSPACE_JPEG,
143 /* Frame packet header offsets for the spca500 */
144 #define SPCA500_OFFSET_PADDINGLB 2
145 #define SPCA500_OFFSET_PADDINGHB 3
146 #define SPCA500_OFFSET_MODE 4
147 #define SPCA500_OFFSET_IMGWIDTH 5
148 #define SPCA500_OFFSET_IMGHEIGHT 6
149 #define SPCA500_OFFSET_IMGMODE 7
150 #define SPCA500_OFFSET_QTBLINDEX 8
151 #define SPCA500_OFFSET_FRAMSEQ 9
152 #define SPCA500_OFFSET_CDSPINFO 10
153 #define SPCA500_OFFSET_GPIO 11
154 #define SPCA500_OFFSET_AUGPIO 12
155 #define SPCA500_OFFSET_DATA 16
158 static const __u16 spca500_visual_defaults[][3] = {
159 {0x00, 0x0003, 0x816b}, /* SSI not active sync with vsync,
161 * saturation/hue enable,
162 * brightness/contrast enable.
164 {0x00, 0x0000, 0x8167}, /* brightness = 0 */
165 {0x00, 0x0020, 0x8168}, /* contrast = 0 */
166 {0x00, 0x0003, 0x816b}, /* SSI not active sync with vsync,
167 * hue (H byte) = 0, saturation/hue enable,
168 * brightness/contrast enable.
169 * was 0x0003, now 0x0000.
171 {0x00, 0x0000, 0x816a}, /* hue (L byte) = 0 */
172 {0x00, 0x0020, 0x8169}, /* saturation = 0x20 */
173 {0x00, 0x0050, 0x8157}, /* edge gain high threshold */
174 {0x00, 0x0030, 0x8158}, /* edge gain low threshold */
175 {0x00, 0x0028, 0x8159}, /* edge bandwidth high threshold */
176 {0x00, 0x000a, 0x815a}, /* edge bandwidth low threshold */
177 {0x00, 0x0001, 0x8202}, /* clock rate compensation = 1/25 sec/frame */
178 {0x0c, 0x0004, 0x0000},
182 static const __u16 Clicksmart510_defaults[][3] = {
183 {0x00, 0x00, 0x8211},
184 {0x00, 0x01, 0x82c0},
185 {0x00, 0x10, 0x82cb},
186 {0x00, 0x0f, 0x800d},
187 {0x00, 0x82, 0x8225},
188 {0x00, 0x21, 0x8228},
189 {0x00, 0x00, 0x8203},
190 {0x00, 0x00, 0x8204},
191 {0x00, 0x08, 0x8205},
192 {0x00, 0xf8, 0x8206},
193 {0x00, 0x28, 0x8207},
194 {0x00, 0xa0, 0x8208},
195 {0x00, 0x08, 0x824a},
196 {0x00, 0x08, 0x8214},
197 {0x00, 0x80, 0x82c1},
198 {0x00, 0x00, 0x82c2},
199 {0x00, 0x00, 0x82ca},
200 {0x00, 0x80, 0x82c1},
201 {0x00, 0x04, 0x82c2},
202 {0x00, 0x00, 0x82ca},
203 {0x00, 0xfc, 0x8100},
204 {0x00, 0xfc, 0x8105},
205 {0x00, 0x30, 0x8101},
206 {0x00, 0x00, 0x8102},
207 {0x00, 0x00, 0x8103},
208 {0x00, 0x66, 0x8107},
209 {0x00, 0x00, 0x816b},
210 {0x00, 0x00, 0x8155},
211 {0x00, 0x01, 0x8156},
212 {0x00, 0x60, 0x8157},
213 {0x00, 0x40, 0x8158},
214 {0x00, 0x0a, 0x8159},
215 {0x00, 0x06, 0x815a},
216 {0x00, 0x00, 0x813f},
217 {0x00, 0x00, 0x8200},
218 {0x00, 0x19, 0x8201},
219 {0x00, 0x00, 0x82c1},
220 {0x00, 0xa0, 0x82c2},
221 {0x00, 0x00, 0x82ca},
222 {0x00, 0x00, 0x8117},
223 {0x00, 0x00, 0x8118},
224 {0x00, 0x65, 0x8119},
225 {0x00, 0x00, 0x811a},
226 {0x00, 0x00, 0x811b},
227 {0x00, 0x55, 0x811c},
228 {0x00, 0x65, 0x811d},
229 {0x00, 0x55, 0x811e},
230 {0x00, 0x16, 0x811f},
231 {0x00, 0x19, 0x8120},
232 {0x00, 0x80, 0x8103},
233 {0x00, 0x83, 0x816b},
234 {0x00, 0x25, 0x8168},
235 {0x00, 0x01, 0x820f},
236 {0x00, 0xff, 0x8115},
237 {0x00, 0x48, 0x8116},
238 {0x00, 0x50, 0x8151},
239 {0x00, 0x40, 0x8152},
240 {0x00, 0x78, 0x8153},
241 {0x00, 0x40, 0x8154},
242 {0x00, 0x00, 0x8167},
243 {0x00, 0x20, 0x8168},
244 {0x00, 0x00, 0x816a},
245 {0x00, 0x03, 0x816b},
246 {0x00, 0x20, 0x8169},
247 {0x00, 0x60, 0x8157},
248 {0x00, 0x00, 0x8190},
249 {0x00, 0x00, 0x81a1},
250 {0x00, 0x00, 0x81b2},
251 {0x00, 0x27, 0x8191},
252 {0x00, 0x27, 0x81a2},
253 {0x00, 0x27, 0x81b3},
254 {0x00, 0x4b, 0x8192},
255 {0x00, 0x4b, 0x81a3},
256 {0x00, 0x4b, 0x81b4},
257 {0x00, 0x66, 0x8193},
258 {0x00, 0x66, 0x81a4},
259 {0x00, 0x66, 0x81b5},
260 {0x00, 0x79, 0x8194},
261 {0x00, 0x79, 0x81a5},
262 {0x00, 0x79, 0x81b6},
263 {0x00, 0x8a, 0x8195},
264 {0x00, 0x8a, 0x81a6},
265 {0x00, 0x8a, 0x81b7},
266 {0x00, 0x9b, 0x8196},
267 {0x00, 0x9b, 0x81a7},
268 {0x00, 0x9b, 0x81b8},
269 {0x00, 0xa6, 0x8197},
270 {0x00, 0xa6, 0x81a8},
271 {0x00, 0xa6, 0x81b9},
272 {0x00, 0xb2, 0x8198},
273 {0x00, 0xb2, 0x81a9},
274 {0x00, 0xb2, 0x81ba},
275 {0x00, 0xbe, 0x8199},
276 {0x00, 0xbe, 0x81aa},
277 {0x00, 0xbe, 0x81bb},
278 {0x00, 0xc8, 0x819a},
279 {0x00, 0xc8, 0x81ab},
280 {0x00, 0xc8, 0x81bc},
281 {0x00, 0xd2, 0x819b},
282 {0x00, 0xd2, 0x81ac},
283 {0x00, 0xd2, 0x81bd},
284 {0x00, 0xdb, 0x819c},
285 {0x00, 0xdb, 0x81ad},
286 {0x00, 0xdb, 0x81be},
287 {0x00, 0xe4, 0x819d},
288 {0x00, 0xe4, 0x81ae},
289 {0x00, 0xe4, 0x81bf},
290 {0x00, 0xed, 0x819e},
291 {0x00, 0xed, 0x81af},
292 {0x00, 0xed, 0x81c0},
293 {0x00, 0xf7, 0x819f},
294 {0x00, 0xf7, 0x81b0},
295 {0x00, 0xf7, 0x81c1},
296 {0x00, 0xff, 0x81a0},
297 {0x00, 0xff, 0x81b1},
298 {0x00, 0xff, 0x81c2},
299 {0x00, 0x03, 0x8156},
300 {0x00, 0x00, 0x8211},
301 {0x00, 0x20, 0x8168},
302 {0x00, 0x01, 0x8202},
303 {0x00, 0x30, 0x8101},
304 {0x00, 0x00, 0x8111},
305 {0x00, 0x00, 0x8112},
306 {0x00, 0x00, 0x8113},
307 {0x00, 0x00, 0x8114},
311 static const __u8 qtable_creative_pccam[2][64] = {
312 { /* Q-table Y-components */
313 0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12,
314 0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11,
315 0x04, 0x04, 0x05, 0x07, 0x0c, 0x11, 0x15, 0x11,
316 0x04, 0x05, 0x07, 0x09, 0x0f, 0x1a, 0x18, 0x13,
317 0x05, 0x07, 0x0b, 0x11, 0x14, 0x21, 0x1f, 0x17,
318 0x07, 0x0b, 0x11, 0x13, 0x18, 0x1f, 0x22, 0x1c,
319 0x0f, 0x13, 0x17, 0x1a, 0x1f, 0x24, 0x24, 0x1e,
320 0x16, 0x1c, 0x1d, 0x1d, 0x22, 0x1e, 0x1f, 0x1e},
321 { /* Q-table C-components */
322 0x05, 0x05, 0x07, 0x0e, 0x1e, 0x1e, 0x1e, 0x1e,
323 0x05, 0x06, 0x08, 0x14, 0x1e, 0x1e, 0x1e, 0x1e,
324 0x07, 0x08, 0x11, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
325 0x0e, 0x14, 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,
329 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e}
332 static const __u8 qtable_kodak_ez200[2][64] = {
333 { /* Q-table Y-components */
334 0x02, 0x01, 0x01, 0x02, 0x02, 0x04, 0x05, 0x06,
335 0x01, 0x01, 0x01, 0x02, 0x03, 0x06, 0x06, 0x06,
336 0x01, 0x01, 0x02, 0x02, 0x04, 0x06, 0x07, 0x06,
337 0x01, 0x02, 0x02, 0x03, 0x05, 0x09, 0x08, 0x06,
338 0x02, 0x02, 0x04, 0x06, 0x07, 0x0b, 0x0a, 0x08,
339 0x02, 0x04, 0x06, 0x06, 0x08, 0x0a, 0x0b, 0x09,
340 0x05, 0x06, 0x08, 0x09, 0x0a, 0x0c, 0x0c, 0x0a,
341 0x07, 0x09, 0x0a, 0x0a, 0x0b, 0x0a, 0x0a, 0x0a},
342 { /* Q-table C-components */
343 0x02, 0x02, 0x02, 0x05, 0x0a, 0x0a, 0x0a, 0x0a,
344 0x02, 0x02, 0x03, 0x07, 0x0a, 0x0a, 0x0a, 0x0a,
345 0x02, 0x03, 0x06, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
346 0x05, 0x07, 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,
350 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a}
353 static const __u8 qtable_pocketdv[2][64] = {
354 { /* Q-table Y-components start registers 0x8800 */
355 0x06, 0x04, 0x04, 0x06, 0x0a, 0x10, 0x14, 0x18,
356 0x05, 0x05, 0x06, 0x08, 0x0a, 0x17, 0x18, 0x16,
357 0x06, 0x05, 0x06, 0x0a, 0x10, 0x17, 0x1c, 0x16,
358 0x06, 0x07, 0x09, 0x0c, 0x14, 0x23, 0x20, 0x19,
359 0x07, 0x09, 0x0f, 0x16, 0x1b, 0x2c, 0x29, 0x1f,
360 0x0a, 0x0e, 0x16, 0x1a, 0x20, 0x2a, 0x2d, 0x25,
361 0x14, 0x1a, 0x1f, 0x23, 0x29, 0x30, 0x30, 0x28,
362 0x1d, 0x25, 0x26, 0x27, 0x2d, 0x28, 0x29, 0x28,
364 { /* Q-table C-components start registers 0x8840 */
365 0x07, 0x07, 0x0a, 0x13, 0x28, 0x28, 0x28, 0x28,
366 0x07, 0x08, 0x0a, 0x1a, 0x28, 0x28, 0x28, 0x28,
367 0x0a, 0x0a, 0x16, 0x28, 0x28, 0x28, 0x28, 0x28,
368 0x13, 0x1a, 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,
372 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28}
375 /* read 'len' bytes to gspca_dev->usb_buf */
376 static void reg_r(struct gspca_dev *gspca_dev,
380 usb_control_msg(gspca_dev->dev,
381 usb_rcvctrlpipe(gspca_dev->dev, 0),
383 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
385 index, gspca_dev->usb_buf, length, 500);
388 static int reg_w(struct gspca_dev *gspca_dev,
389 __u16 req, __u16 index, __u16 value)
393 PDEBUG(D_USBO, "reg write: [0x%02x] = 0x%02x", index, value);
394 ret = usb_control_msg(gspca_dev->dev,
395 usb_sndctrlpipe(gspca_dev->dev, 0),
397 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
398 value, index, NULL, 0, 500);
400 PDEBUG(D_ERR, "reg write: error %d", ret);
404 /* returns: negative is error, pos or zero is data */
405 static int reg_r_12(struct gspca_dev *gspca_dev,
406 __u16 req, /* bRequest */
407 __u16 index, /* wIndex */
408 __u16 length) /* wLength (1 or 2 only) */
412 gspca_dev->usb_buf[1] = 0;
413 ret = usb_control_msg(gspca_dev->dev,
414 usb_rcvctrlpipe(gspca_dev->dev, 0),
416 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
419 gspca_dev->usb_buf, length,
422 PDEBUG(D_ERR, "reg_r_12 err %d", ret);
425 return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0];
429 * Simple function to wait for a given 8-bit value to be returned from
431 * Returns: negative is error or timeout, zero is success.
433 static int reg_r_wait(struct gspca_dev *gspca_dev,
434 __u16 reg, __u16 index, __u16 value)
439 ret = reg_r_12(gspca_dev, reg, index, 1);
447 static int write_vector(struct gspca_dev *gspca_dev,
448 const __u16 data[][3])
452 while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) {
453 ret = reg_w(gspca_dev, data[i][0], data[i][2], data[i][1]);
461 static int spca50x_setup_qtable(struct gspca_dev *gspca_dev,
462 unsigned int request,
465 const __u8 qtable[2][64])
469 /* loop over y components */
470 for (i = 0; i < 64; i++) {
471 err = reg_w(gspca_dev, request, ybase + i, qtable[0][i]);
476 /* loop over c components */
477 for (i = 0; i < 64; i++) {
478 err = reg_w(gspca_dev, request, cbase + i, qtable[1][i]);
485 static void spca500_ping310(struct gspca_dev *gspca_dev)
487 reg_r(gspca_dev, 0x0d04, 2);
488 PDEBUG(D_STREAM, "ClickSmart310 ping 0x0d04 0x%02x 0x%02x",
489 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
492 static void spca500_clksmart310_init(struct gspca_dev *gspca_dev)
494 reg_r(gspca_dev, 0x0d05, 2);
495 PDEBUG(D_STREAM, "ClickSmart310 init 0x0d05 0x%02x 0x%02x",
496 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
497 reg_w(gspca_dev, 0x00, 0x8167, 0x5a);
498 spca500_ping310(gspca_dev);
500 reg_w(gspca_dev, 0x00, 0x8168, 0x22);
501 reg_w(gspca_dev, 0x00, 0x816a, 0xc0);
502 reg_w(gspca_dev, 0x00, 0x816b, 0x0b);
503 reg_w(gspca_dev, 0x00, 0x8169, 0x25);
504 reg_w(gspca_dev, 0x00, 0x8157, 0x5b);
505 reg_w(gspca_dev, 0x00, 0x8158, 0x5b);
506 reg_w(gspca_dev, 0x00, 0x813f, 0x03);
507 reg_w(gspca_dev, 0x00, 0x8151, 0x4a);
508 reg_w(gspca_dev, 0x00, 0x8153, 0x78);
509 reg_w(gspca_dev, 0x00, 0x0d01, 0x04);
510 /* 00 for adjust shutter */
511 reg_w(gspca_dev, 0x00, 0x0d02, 0x01);
512 reg_w(gspca_dev, 0x00, 0x8169, 0x25);
513 reg_w(gspca_dev, 0x00, 0x0d01, 0x02);
516 static void spca500_setmode(struct gspca_dev *gspca_dev,
517 __u8 xmult, __u8 ymult)
521 /* set x multiplier */
522 reg_w(gspca_dev, 0, 0x8001, xmult);
524 /* set y multiplier */
525 reg_w(gspca_dev, 0, 0x8002, ymult);
527 /* use compressed mode, VGA, with mode specific subsample */
528 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
529 reg_w(gspca_dev, 0, 0x8003, mode << 4);
532 static int spca500_full_reset(struct gspca_dev *gspca_dev)
536 /* send the reset command */
537 err = reg_w(gspca_dev, 0xe0, 0x0001, 0x0000);
541 /* wait for the reset to complete */
542 err = reg_r_wait(gspca_dev, 0x06, 0x0000, 0x0000);
545 err = reg_w(gspca_dev, 0xe0, 0x0000, 0x0000);
548 err = reg_r_wait(gspca_dev, 0x06, 0, 0);
550 PDEBUG(D_ERR, "reg_r_wait() failed");
557 /* Synchro the Bridge with sensor */
558 /* Maybe that will work on all spca500 chip */
559 /* because i only own a clicksmart310 try for that chip */
560 /* using spca50x_set_packet_size() cause an Ooops here */
561 /* usb_set_interface from kernel 2.6.x clear all the urb stuff */
562 /* up-port the same feature as in 2.4.x kernel */
563 static int spca500_synch310(struct gspca_dev *gspca_dev)
565 if (usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0) < 0) {
566 PDEBUG(D_ERR, "Set packet size: set interface error");
569 spca500_ping310(gspca_dev);
571 reg_r(gspca_dev, 0x0d00, 1);
573 /* need alt setting here */
574 PDEBUG(D_PACK, "ClickSmart310 sync alt: %d", gspca_dev->alt);
576 /* Windoze use pipe with altsetting 6 why 7 here */
577 if (usb_set_interface(gspca_dev->dev,
579 gspca_dev->alt) < 0) {
580 PDEBUG(D_ERR, "Set packet size: set interface error");
588 static void spca500_reinit(struct gspca_dev *gspca_dev)
593 /* some unknow command from Aiptek pocket dv and family300 */
595 reg_w(gspca_dev, 0x00, 0x0d01, 0x01);
596 reg_w(gspca_dev, 0x00, 0x0d03, 0x00);
597 reg_w(gspca_dev, 0x00, 0x0d02, 0x01);
599 /* enable drop packet */
600 reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
602 err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840,
605 PDEBUG(D_ERR|D_STREAM, "spca50x_setup_qtable failed on init");
607 /* set qtable index */
608 reg_w(gspca_dev, 0x00, 0x8880, 2);
609 /* family cam Quicksmart stuff */
610 reg_w(gspca_dev, 0x00, 0x800a, 0x00);
611 /* Set agc transfer: synced inbetween frames */
612 reg_w(gspca_dev, 0x00, 0x820f, 0x01);
613 /* Init SDRAM - needed for SDRAM access */
614 reg_w(gspca_dev, 0x00, 0x870a, 0x04);
615 /*Start init sequence or stream */
616 reg_w(gspca_dev, 0, 0x8003, 0x00);
617 /* switch to video camera mode */
618 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
620 if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0) {
621 reg_r(gspca_dev, 0x816b, 1);
622 Data = gspca_dev->usb_buf[0];
623 reg_w(gspca_dev, 0x00, 0x816b, Data);
627 /* this function is called at probe time */
628 static int sd_config(struct gspca_dev *gspca_dev,
629 const struct usb_device_id *id)
631 struct sd *sd = (struct sd *) gspca_dev;
636 vendor = id->idVendor;
637 product = id->idProduct;
639 case 0x040a: /* Kodak cameras */
640 /* switch (product) { */
642 sd->subtype = KodakEZ200;
646 case 0x041e: /* Creative cameras */
647 /* switch (product) { */
649 sd->subtype = CreativePCCam300;
653 case 0x046d: /* Logitech Labtec */
656 sd->subtype = LogitechTraveler;
659 sd->subtype = LogitechClickSmart310;
662 sd->subtype = LogitechClickSmart510;
666 case 0x04a5: /* Benq */
667 /* switch (product) { */
669 sd->subtype = BenqDC1016;
673 case 0x04fc: /* SunPlus */
674 /* switch (product) { */
676 sd->subtype = PalmPixDC85;
680 case 0x055f: /* Mustek cameras */
683 sd->subtype = MustekGsmart300;
686 sd->subtype = Gsmartmini;
690 case 0x06bd: /* Agfa Cl20 */
691 /* switch (product) { */
693 sd->subtype = AgfaCl20;
697 case 0x06be: /* Optimedia */
698 /* switch (product) { */
700 sd->subtype = Optimedia;
704 case 0x084d: /* D-Link / Minton */
705 /* switch (product) { */
706 /* case 0x0003: * DSC-350 / S-Cam F5 */
707 sd->subtype = DLinkDSC350;
711 case 0x08ca: /* Aiptek */
712 /* switch (product) { */
714 sd->subtype = AiptekPocketDV;
718 case 0x2899: /* ToptroIndustrial */
719 /* switch (product) { */
721 sd->subtype = ToptroIndus;
725 case 0x8086: /* Intel */
726 /* switch (product) { */
727 /* case 0x0630: * Pocket PC Camera */
728 sd->subtype = IntelPocketPCCamera;
733 cam = &gspca_dev->cam;
734 cam->dev_name = (char *) id->driver_info;
736 if (sd->subtype != LogitechClickSmart310) {
737 cam->cam_mode = vga_mode;
738 cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
740 cam->cam_mode = sif_mode;
741 cam->nmodes = sizeof sif_mode / sizeof sif_mode[0];
744 sd->brightness = BRIGHTNESS_DEF;
745 sd->contrast = CONTRAST_DEF;
746 sd->colors = COLOR_DEF;
750 /* this function is called at open time */
751 static int sd_open(struct gspca_dev *gspca_dev)
753 struct sd *sd = (struct sd *) gspca_dev;
755 /* initialisation of spca500 based cameras is deferred */
756 PDEBUG(D_STREAM, "SPCA500 init");
757 if (sd->subtype == LogitechClickSmart310)
758 spca500_clksmart310_init(gspca_dev);
760 spca500_initialise(gspca_dev); */
761 PDEBUG(D_STREAM, "SPCA500 init done");
765 static void sd_start(struct gspca_dev *gspca_dev)
767 struct sd *sd = (struct sd *) gspca_dev;
772 if (sd->subtype == LogitechClickSmart310) {
780 /* is there a sensor here ? */
781 reg_r(gspca_dev, 0x8a04, 1);
782 PDEBUG(D_STREAM, "Spca500 Sensor Address 0x%02x",
783 gspca_dev->usb_buf[0]);
784 PDEBUG(D_STREAM, "Spca500 curr_mode: %d Xmult: 0x%02x, Ymult: 0x%02x",
785 gspca_dev->curr_mode, xmult, ymult);
788 switch (sd->subtype) {
789 case LogitechClickSmart310:
790 spca500_setmode(gspca_dev, xmult, ymult);
792 /* enable drop packet */
793 reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
794 reg_w(gspca_dev, 0x00, 0x8880, 3);
795 err = spca50x_setup_qtable(gspca_dev,
796 0x00, 0x8800, 0x8840,
797 qtable_creative_pccam);
799 PDEBUG(D_ERR, "spca50x_setup_qtable failed");
800 /* Init SDRAM - needed for SDRAM access */
801 reg_w(gspca_dev, 0x00, 0x870a, 0x04);
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 spca500_synch310(gspca_dev);
815 write_vector(gspca_dev, spca500_visual_defaults);
816 spca500_setmode(gspca_dev, xmult, ymult);
817 /* enable drop packet */
818 reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
819 PDEBUG(D_ERR, "failed to enable drop packet");
820 reg_w(gspca_dev, 0x00, 0x8880, 3);
821 err = spca50x_setup_qtable(gspca_dev,
822 0x00, 0x8800, 0x8840,
823 qtable_creative_pccam);
825 PDEBUG(D_ERR, "spca50x_setup_qtable failed");
827 /* Init SDRAM - needed for SDRAM access */
828 reg_w(gspca_dev, 0x00, 0x870a, 0x04);
830 /* switch to video camera mode */
831 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
833 if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
834 PDEBUG(D_ERR, "reg_r_wait() failed");
836 reg_r(gspca_dev, 0x816b, 1);
837 Data = gspca_dev->usb_buf[0];
838 reg_w(gspca_dev, 0x00, 0x816b, Data);
840 case CreativePCCam300: /* Creative PC-CAM 300 640x480 CCD */
841 case IntelPocketPCCamera: /* FIXME: Temporary fix for
842 * Intel Pocket PC Camera
843 * - NWG (Sat 29th March 2003) */
845 /* do a full reset */
846 err = spca500_full_reset(gspca_dev);
848 PDEBUG(D_ERR, "spca500_full_reset failed");
850 /* enable drop packet */
851 err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
853 PDEBUG(D_ERR, "failed to enable drop packet");
854 reg_w(gspca_dev, 0x00, 0x8880, 3);
855 err = spca50x_setup_qtable(gspca_dev,
856 0x00, 0x8800, 0x8840,
857 qtable_creative_pccam);
859 PDEBUG(D_ERR, "spca50x_setup_qtable failed");
861 spca500_setmode(gspca_dev, xmult, ymult);
862 reg_w(gspca_dev, 0x20, 0x0001, 0x0004);
864 /* switch to video camera mode */
865 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
867 if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
868 PDEBUG(D_ERR, "reg_r_wait() failed");
870 reg_r(gspca_dev, 0x816b, 1);
871 Data = gspca_dev->usb_buf[0];
872 reg_w(gspca_dev, 0x00, 0x816b, Data);
874 /* write_vector(gspca_dev, spca500_visual_defaults); */
876 case KodakEZ200: /* Kodak EZ200 */
878 /* do a full reset */
879 err = spca500_full_reset(gspca_dev);
881 PDEBUG(D_ERR, "spca500_full_reset failed");
882 /* enable drop packet */
883 reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
884 reg_w(gspca_dev, 0x00, 0x8880, 0);
885 err = spca50x_setup_qtable(gspca_dev,
886 0x00, 0x8800, 0x8840,
889 PDEBUG(D_ERR, "spca50x_setup_qtable failed");
890 spca500_setmode(gspca_dev, xmult, ymult);
892 reg_w(gspca_dev, 0x20, 0x0001, 0x0004);
894 /* switch to video camera mode */
895 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
897 if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
898 PDEBUG(D_ERR, "reg_r_wait() failed");
900 reg_r(gspca_dev, 0x816b, 1);
901 Data = gspca_dev->usb_buf[0];
902 reg_w(gspca_dev, 0x00, 0x816b, Data);
904 /* write_vector(gspca_dev, spca500_visual_defaults); */
908 case DLinkDSC350: /* FamilyCam 300 */
909 case AiptekPocketDV: /* Aiptek PocketDV */
910 case Gsmartmini: /*Mustek Gsmart Mini */
911 case MustekGsmart300: /* Mustek Gsmart 300 */
916 spca500_reinit(gspca_dev);
917 reg_w(gspca_dev, 0x00, 0x0d01, 0x01);
918 /* enable drop packet */
919 reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
921 err = spca50x_setup_qtable(gspca_dev,
922 0x00, 0x8800, 0x8840, qtable_pocketdv);
924 PDEBUG(D_ERR, "spca50x_setup_qtable failed");
925 reg_w(gspca_dev, 0x00, 0x8880, 2);
927 /* familycam Quicksmart pocketDV stuff */
928 reg_w(gspca_dev, 0x00, 0x800a, 0x00);
929 /* Set agc transfer: synced inbetween frames */
930 reg_w(gspca_dev, 0x00, 0x820f, 0x01);
931 /* Init SDRAM - needed for SDRAM access */
932 reg_w(gspca_dev, 0x00, 0x870a, 0x04);
934 spca500_setmode(gspca_dev, xmult, ymult);
935 /* switch to video camera mode */
936 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
938 reg_r_wait(gspca_dev, 0, 0x8000, 0x44);
940 reg_r(gspca_dev, 0x816b, 1);
941 Data = gspca_dev->usb_buf[0];
942 reg_w(gspca_dev, 0x00, 0x816b, Data);
944 case LogitechTraveler:
945 case LogitechClickSmart510:
946 reg_w(gspca_dev, 0x02, 0x00, 0x00);
947 /* enable drop packet */
948 reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
950 err = spca50x_setup_qtable(gspca_dev,
952 0x8840, qtable_creative_pccam);
954 PDEBUG(D_ERR, "spca50x_setup_qtable failed");
955 reg_w(gspca_dev, 0x00, 0x8880, 3);
956 reg_w(gspca_dev, 0x00, 0x800a, 0x00);
957 /* Init SDRAM - needed for SDRAM access */
958 reg_w(gspca_dev, 0x00, 0x870a, 0x04);
960 spca500_setmode(gspca_dev, xmult, ymult);
962 /* switch to video camera mode */
963 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
964 reg_r_wait(gspca_dev, 0, 0x8000, 0x44);
966 reg_r(gspca_dev, 0x816b, 1);
967 Data = gspca_dev->usb_buf[0];
968 reg_w(gspca_dev, 0x00, 0x816b, Data);
969 write_vector(gspca_dev, Clicksmart510_defaults);
974 static void sd_stopN(struct gspca_dev *gspca_dev)
976 reg_w(gspca_dev, 0, 0x8003, 0x00);
978 /* switch to video camera mode */
979 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
980 reg_r(gspca_dev, 0x8000, 1);
981 PDEBUG(D_STREAM, "stop SPCA500 done reg8000: 0x%2x",
982 gspca_dev->usb_buf[0]);
985 static void sd_stop0(struct gspca_dev *gspca_dev)
989 static void sd_close(struct gspca_dev *gspca_dev)
993 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
994 struct gspca_frame *frame, /* target */
995 __u8 *data, /* isoc packet */
996 int len) /* iso packet length */
998 struct sd *sd = (struct sd *) gspca_dev;
1001 static __u8 ffd9[] = {0xff, 0xd9};
1003 /* frames are jpeg 4.1.1 without 0xff escape */
1004 if (data[0] == 0xff) {
1005 if (data[1] != 0x01) { /* drop packet */
1006 /* gspca_dev->last_packet_type = DISCARD_PACKET; */
1009 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
1012 /* put the JPEG header in the new frame */
1013 jpeg_put_header(gspca_dev, frame, sd->qindex, 0x22);
1015 data += SPCA500_OFFSET_DATA;
1016 len -= SPCA500_OFFSET_DATA;
1022 /* add 0x00 after 0xff */
1023 for (i = len; --i >= 0; )
1024 if (data[i] == 0xff)
1026 if (i < 0) { /* no 0xff */
1027 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1032 for (i = 0; i < len; i++) {
1037 gspca_frame_add(gspca_dev, INTER_PACKET, frame,
1038 sd->packet, d - sd->packet);
1041 static void setbrightness(struct gspca_dev *gspca_dev)
1043 struct sd *sd = (struct sd *) gspca_dev;
1045 reg_w(gspca_dev, 0x00, 0x8167,
1046 (__u8) (sd->brightness - 128));
1049 static void getbrightness(struct gspca_dev *gspca_dev)
1051 struct sd *sd = (struct sd *) gspca_dev;
1054 ret = reg_r_12(gspca_dev, 0x00, 0x8167, 1);
1056 sd->brightness = ret + 128;
1059 static void setcontrast(struct gspca_dev *gspca_dev)
1061 struct sd *sd = (struct sd *) gspca_dev;
1063 reg_w(gspca_dev, 0x00, 0x8168, sd->contrast);
1066 static void getcontrast(struct gspca_dev *gspca_dev)
1068 struct sd *sd = (struct sd *) gspca_dev;
1071 ret = reg_r_12(gspca_dev, 0x0, 0x8168, 1);
1076 static void setcolors(struct gspca_dev *gspca_dev)
1078 struct sd *sd = (struct sd *) gspca_dev;
1080 reg_w(gspca_dev, 0x00, 0x8169, sd->colors);
1083 static void getcolors(struct gspca_dev *gspca_dev)
1085 struct sd *sd = (struct sd *) gspca_dev;
1088 ret = reg_r_12(gspca_dev, 0x0, 0x8169, 1);
1093 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1095 struct sd *sd = (struct sd *) gspca_dev;
1097 sd->brightness = val;
1098 if (gspca_dev->streaming)
1099 setbrightness(gspca_dev);
1103 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1105 struct sd *sd = (struct sd *) gspca_dev;
1107 getbrightness(gspca_dev);
1108 *val = sd->brightness;
1112 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1114 struct sd *sd = (struct sd *) gspca_dev;
1117 if (gspca_dev->streaming)
1118 setcontrast(gspca_dev);
1122 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1124 struct sd *sd = (struct sd *) gspca_dev;
1126 getcontrast(gspca_dev);
1127 *val = sd->contrast;
1131 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1133 struct sd *sd = (struct sd *) gspca_dev;
1136 if (gspca_dev->streaming)
1137 setcolors(gspca_dev);
1141 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1143 struct sd *sd = (struct sd *) gspca_dev;
1145 getcolors(gspca_dev);
1150 /* sub-driver description */
1151 static struct sd_desc sd_desc = {
1152 .name = MODULE_NAME,
1154 .nctrls = ARRAY_SIZE(sd_ctrls),
1155 .config = sd_config,
1161 .pkt_scan = sd_pkt_scan,
1164 /* -- module initialisation -- */
1165 #define DVNM(name) .driver_info = (kernel_ulong_t) name
1166 static const __devinitdata struct usb_device_id device_table[] = {
1167 {USB_DEVICE(0x040a, 0x0300), DVNM("Kodak EZ200")},
1168 {USB_DEVICE(0x041e, 0x400a), DVNM("Creative PC-CAM 300")},
1169 {USB_DEVICE(0x046d, 0x0890), DVNM("Logitech QuickCam traveler")},
1170 {USB_DEVICE(0x046d, 0x0900), DVNM("Logitech Inc. ClickSmart 310")},
1171 {USB_DEVICE(0x046d, 0x0901), DVNM("Logitech Inc. ClickSmart 510")},
1172 {USB_DEVICE(0x04a5, 0x300c), DVNM("Benq DC1016")},
1173 {USB_DEVICE(0x04fc, 0x7333), DVNM("PalmPixDC85")},
1174 {USB_DEVICE(0x055f, 0xc200), DVNM("Mustek Gsmart 300")},
1175 {USB_DEVICE(0x055f, 0xc220), DVNM("Gsmart Mini")},
1176 {USB_DEVICE(0x06bd, 0x0404), DVNM("Agfa CL20")},
1177 {USB_DEVICE(0x06be, 0x0800), DVNM("Optimedia")},
1178 {USB_DEVICE(0x084d, 0x0003), DVNM("D-Link DSC-350")},
1179 {USB_DEVICE(0x08ca, 0x0103), DVNM("Aiptek PocketDV")},
1180 {USB_DEVICE(0x2899, 0x012c), DVNM("Toptro Industrial")},
1181 {USB_DEVICE(0x8086, 0x0630), DVNM("Intel Pocket PC Camera")},
1184 MODULE_DEVICE_TABLE(usb, device_table);
1186 /* -- device connect -- */
1187 static int sd_probe(struct usb_interface *intf,
1188 const struct usb_device_id *id)
1190 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1194 static struct usb_driver sd_driver = {
1195 .name = MODULE_NAME,
1196 .id_table = device_table,
1198 .disconnect = gspca_disconnect,
1201 /* -- module insert / remove -- */
1202 static int __init sd_mod_init(void)
1204 if (usb_register(&sd_driver) < 0)
1206 PDEBUG(D_PROBE, "v%s registered", version);
1209 static void __exit sd_mod_exit(void)
1211 usb_deregister(&sd_driver);
1212 PDEBUG(D_PROBE, "deregistered");
1215 module_init(sd_mod_init);
1216 module_exit(sd_mod_exit);