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, 0)
28 static const char version[] = "2.1.0";
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 unsigned char 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[] = {
73 #define SD_BRIGHTNESS 0
76 .id = V4L2_CID_BRIGHTNESS,
77 .type = V4L2_CTRL_TYPE_INTEGER,
82 .default_value = 0x7f,
84 .set = sd_setbrightness,
85 .get = sd_getbrightness,
90 .id = V4L2_CID_CONTRAST,
91 .type = V4L2_CTRL_TYPE_INTEGER,
98 .set = sd_setcontrast,
99 .get = sd_getcontrast,
104 .id = V4L2_CID_SATURATION,
105 .type = V4L2_CTRL_TYPE_INTEGER,
110 .default_value = 127,
117 static struct cam_mode vga_mode[] = {
118 {V4L2_PIX_FMT_JPEG, 320, 240, 1},
119 {V4L2_PIX_FMT_JPEG, 640, 480, 0},
122 static struct cam_mode sif_mode[] = {
123 {V4L2_PIX_FMT_JPEG, 176, 144, 1},
124 {V4L2_PIX_FMT_JPEG, 352, 288, 0},
127 /* Frame packet header offsets for the spca500 */
128 #define SPCA500_OFFSET_PADDINGLB 2
129 #define SPCA500_OFFSET_PADDINGHB 3
130 #define SPCA500_OFFSET_MODE 4
131 #define SPCA500_OFFSET_IMGWIDTH 5
132 #define SPCA500_OFFSET_IMGHEIGHT 6
133 #define SPCA500_OFFSET_IMGMODE 7
134 #define SPCA500_OFFSET_QTBLINDEX 8
135 #define SPCA500_OFFSET_FRAMSEQ 9
136 #define SPCA500_OFFSET_CDSPINFO 10
137 #define SPCA500_OFFSET_GPIO 11
138 #define SPCA500_OFFSET_AUGPIO 12
139 #define SPCA500_OFFSET_DATA 16
142 static __u16 spca500_visual_defaults[][3] = {
143 {0x00, 0x0003, 0x816b}, /* SSI not active sync with vsync,
145 * saturation/hue enable,
146 * brightness/contrast enable.
148 {0x00, 0x0000, 0x8167}, /* brightness = 0 */
149 {0x00, 0x0020, 0x8168}, /* contrast = 0 */
150 {0x00, 0x0003, 0x816b}, /* SSI not active sync with vsync,
151 * hue (H byte) = 0, saturation/hue enable,
152 * brightness/contrast enable.
153 * was 0x0003, now 0x0000.
155 {0x00, 0x0000, 0x816a}, /* hue (L byte) = 0 */
156 {0x00, 0x0020, 0x8169}, /* saturation = 0x20 */
157 {0x00, 0x0050, 0x8157}, /* edge gain high threshold */
158 {0x00, 0x0030, 0x8158}, /* edge gain low threshold */
159 {0x00, 0x0028, 0x8159}, /* edge bandwidth high threshold */
160 {0x00, 0x000a, 0x815a}, /* edge bandwidth low threshold */
161 {0x00, 0x0001, 0x8202}, /* clock rate compensation = 1/25 sec/frame */
162 {0x0c, 0x0004, 0x0000},
167 static __u16 Clicksmart510_defaults[][3] = {
168 {0x00, 0x00, 0x8211},
169 {0x00, 0x01, 0x82c0},
170 {0x00, 0x10, 0x82cb},
171 {0x00, 0x0f, 0x800d},
172 {0x00, 0x82, 0x8225},
173 {0x00, 0x21, 0x8228},
174 {0x00, 0x00, 0x8203},
175 {0x00, 0x00, 0x8204},
176 {0x00, 0x08, 0x8205},
177 {0x00, 0xf8, 0x8206},
178 {0x00, 0x28, 0x8207},
179 {0x00, 0xa0, 0x8208},
180 {0x00, 0x08, 0x824a},
181 {0x00, 0x08, 0x8214},
182 {0x00, 0x80, 0x82c1},
183 {0x00, 0x00, 0x82c2},
184 {0x00, 0x00, 0x82ca},
185 {0x00, 0x80, 0x82c1},
186 {0x00, 0x04, 0x82c2},
187 {0x00, 0x00, 0x82ca},
188 {0x00, 0xfc, 0x8100},
189 {0x00, 0xfc, 0x8105},
190 {0x00, 0x30, 0x8101},
191 {0x00, 0x00, 0x8102},
192 {0x00, 0x00, 0x8103},
193 {0x00, 0x66, 0x8107},
194 {0x00, 0x00, 0x816b},
195 {0x00, 0x00, 0x8155},
196 {0x00, 0x01, 0x8156},
197 {0x00, 0x60, 0x8157},
198 {0x00, 0x40, 0x8158},
199 {0x00, 0x0a, 0x8159},
200 {0x00, 0x06, 0x815a},
201 {0x00, 0x00, 0x813f},
202 {0x00, 0x00, 0x8200},
203 {0x00, 0x19, 0x8201},
204 {0x00, 0x00, 0x82c1},
205 {0x00, 0xa0, 0x82c2},
206 {0x00, 0x00, 0x82ca},
207 {0x00, 0x00, 0x8117},
208 {0x00, 0x00, 0x8118},
209 {0x00, 0x65, 0x8119},
210 {0x00, 0x00, 0x811a},
211 {0x00, 0x00, 0x811b},
212 {0x00, 0x55, 0x811c},
213 {0x00, 0x65, 0x811d},
214 {0x00, 0x55, 0x811e},
215 {0x00, 0x16, 0x811f},
216 {0x00, 0x19, 0x8120},
217 {0x00, 0x80, 0x8103},
218 {0x00, 0x83, 0x816b},
219 {0x00, 0x25, 0x8168},
220 {0x00, 0x01, 0x820f},
221 {0x00, 0xff, 0x8115},
222 {0x00, 0x48, 0x8116},
223 {0x00, 0x50, 0x8151},
224 {0x00, 0x40, 0x8152},
225 {0x00, 0x78, 0x8153},
226 {0x00, 0x40, 0x8154},
227 {0x00, 0x00, 0x8167},
228 {0x00, 0x20, 0x8168},
229 {0x00, 0x00, 0x816a},
230 {0x00, 0x03, 0x816b},
231 {0x00, 0x20, 0x8169},
232 {0x00, 0x60, 0x8157},
233 {0x00, 0x00, 0x8190},
234 {0x00, 0x00, 0x81a1},
235 {0x00, 0x00, 0x81b2},
236 {0x00, 0x27, 0x8191},
237 {0x00, 0x27, 0x81a2},
238 {0x00, 0x27, 0x81b3},
239 {0x00, 0x4b, 0x8192},
240 {0x00, 0x4b, 0x81a3},
241 {0x00, 0x4b, 0x81b4},
242 {0x00, 0x66, 0x8193},
243 {0x00, 0x66, 0x81a4},
244 {0x00, 0x66, 0x81b5},
245 {0x00, 0x79, 0x8194},
246 {0x00, 0x79, 0x81a5},
247 {0x00, 0x79, 0x81b6},
248 {0x00, 0x8a, 0x8195},
249 {0x00, 0x8a, 0x81a6},
250 {0x00, 0x8a, 0x81b7},
251 {0x00, 0x9b, 0x8196},
252 {0x00, 0x9b, 0x81a7},
253 {0x00, 0x9b, 0x81b8},
254 {0x00, 0xa6, 0x8197},
255 {0x00, 0xa6, 0x81a8},
256 {0x00, 0xa6, 0x81b9},
257 {0x00, 0xb2, 0x8198},
258 {0x00, 0xb2, 0x81a9},
259 {0x00, 0xb2, 0x81ba},
260 {0x00, 0xbe, 0x8199},
261 {0x00, 0xbe, 0x81aa},
262 {0x00, 0xbe, 0x81bb},
263 {0x00, 0xc8, 0x819a},
264 {0x00, 0xc8, 0x81ab},
265 {0x00, 0xc8, 0x81bc},
266 {0x00, 0xd2, 0x819b},
267 {0x00, 0xd2, 0x81ac},
268 {0x00, 0xd2, 0x81bd},
269 {0x00, 0xdb, 0x819c},
270 {0x00, 0xdb, 0x81ad},
271 {0x00, 0xdb, 0x81be},
272 {0x00, 0xe4, 0x819d},
273 {0x00, 0xe4, 0x81ae},
274 {0x00, 0xe4, 0x81bf},
275 {0x00, 0xed, 0x819e},
276 {0x00, 0xed, 0x81af},
277 {0x00, 0xed, 0x81c0},
278 {0x00, 0xf7, 0x819f},
279 {0x00, 0xf7, 0x81b0},
280 {0x00, 0xf7, 0x81c1},
281 {0x00, 0xff, 0x81a0},
282 {0x00, 0xff, 0x81b1},
283 {0x00, 0xff, 0x81c2},
284 {0x00, 0x03, 0x8156},
285 {0x00, 0x00, 0x8211},
286 {0x00, 0x20, 0x8168},
287 {0x00, 0x01, 0x8202},
288 {0x00, 0x30, 0x8101},
289 {0x00, 0x00, 0x8111},
290 {0x00, 0x00, 0x8112},
291 {0x00, 0x00, 0x8113},
292 {0x00, 0x00, 0x8114},
296 static unsigned char qtable_creative_pccam[2][64] = {
297 { /* Q-table Y-components */
298 0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12,
299 0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11,
300 0x04, 0x04, 0x05, 0x07, 0x0c, 0x11, 0x15, 0x11,
301 0x04, 0x05, 0x07, 0x09, 0x0f, 0x1a, 0x18, 0x13,
302 0x05, 0x07, 0x0b, 0x11, 0x14, 0x21, 0x1f, 0x17,
303 0x07, 0x0b, 0x11, 0x13, 0x18, 0x1f, 0x22, 0x1c,
304 0x0f, 0x13, 0x17, 0x1a, 0x1f, 0x24, 0x24, 0x1e,
305 0x16, 0x1c, 0x1d, 0x1d, 0x22, 0x1e, 0x1f, 0x1e},
306 { /* Q-table C-components */
307 0x05, 0x05, 0x07, 0x0e, 0x1e, 0x1e, 0x1e, 0x1e,
308 0x05, 0x06, 0x08, 0x14, 0x1e, 0x1e, 0x1e, 0x1e,
309 0x07, 0x08, 0x11, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
310 0x0e, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
311 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
312 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
313 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
314 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e}
317 static unsigned char qtable_kodak_ez200[2][64] = {
318 { /* Q-table Y-components */
319 0x02, 0x01, 0x01, 0x02, 0x02, 0x04, 0x05, 0x06,
320 0x01, 0x01, 0x01, 0x02, 0x03, 0x06, 0x06, 0x06,
321 0x01, 0x01, 0x02, 0x02, 0x04, 0x06, 0x07, 0x06,
322 0x01, 0x02, 0x02, 0x03, 0x05, 0x09, 0x08, 0x06,
323 0x02, 0x02, 0x04, 0x06, 0x07, 0x0b, 0x0a, 0x08,
324 0x02, 0x04, 0x06, 0x06, 0x08, 0x0a, 0x0b, 0x09,
325 0x05, 0x06, 0x08, 0x09, 0x0a, 0x0c, 0x0c, 0x0a,
326 0x07, 0x09, 0x0a, 0x0a, 0x0b, 0x0a, 0x0a, 0x0a},
327 { /* Q-table C-components */
328 0x02, 0x02, 0x02, 0x05, 0x0a, 0x0a, 0x0a, 0x0a,
329 0x02, 0x02, 0x03, 0x07, 0x0a, 0x0a, 0x0a, 0x0a,
330 0x02, 0x03, 0x06, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
331 0x05, 0x07, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
332 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
333 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
334 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
335 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a}
338 static unsigned char qtable_pocketdv[2][64] = {
339 { /* Q-table Y-components start registers 0x8800 */
340 0x06, 0x04, 0x04, 0x06, 0x0a, 0x10, 0x14, 0x18,
341 0x05, 0x05, 0x06, 0x08, 0x0a, 0x17, 0x18, 0x16,
342 0x06, 0x05, 0x06, 0x0a, 0x10, 0x17, 0x1c, 0x16,
343 0x06, 0x07, 0x09, 0x0c, 0x14, 0x23, 0x20, 0x19,
344 0x07, 0x09, 0x0f, 0x16, 0x1b, 0x2c, 0x29, 0x1f,
345 0x0a, 0x0e, 0x16, 0x1a, 0x20, 0x2a, 0x2d, 0x25,
346 0x14, 0x1a, 0x1f, 0x23, 0x29, 0x30, 0x30, 0x28,
347 0x1d, 0x25, 0x26, 0x27, 0x2d, 0x28, 0x29, 0x28,
349 { /* Q-table C-components start registers 0x8840 */
350 0x07, 0x07, 0x0a, 0x13, 0x28, 0x28, 0x28, 0x28,
351 0x07, 0x08, 0x0a, 0x1a, 0x28, 0x28, 0x28, 0x28,
352 0x0a, 0x0a, 0x16, 0x28, 0x28, 0x28, 0x28, 0x28,
353 0x13, 0x1a, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
354 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
355 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
356 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
357 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28}
360 static void spca5xxRegRead(struct usb_device *dev,
362 __u8 *buffer, __u16 length)
365 usb_rcvctrlpipe(dev, 0),
367 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
369 index, buffer, length, 500);
372 static int reg_write(struct usb_device *dev,
373 __u16 req, __u16 index, __u16 value)
377 ret = usb_control_msg(dev,
378 usb_sndctrlpipe(dev, 0),
380 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
381 value, index, NULL, 0, 500);
382 PDEBUG(D_USBO, "reg write: [0x%02x] = 0x%02x, 0x%x",
385 PDEBUG(D_ERR, "reg write: error %d", ret);
389 /* returns: negative is error, pos or zero is data */
390 static int reg_read(struct usb_device *dev,
391 __u16 req, /* bRequest */
392 __u16 index, /* wIndex */
393 __u16 length) /* wLength (1 or 2 only) */
399 ret = usb_control_msg(dev,
400 usb_rcvctrlpipe(dev, 0),
402 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
408 PDEBUG(D_ERR, "reg_read err %d", ret);
411 return (buf[1] << 8) + buf[0];
415 * Simple function to wait for a given 8-bit value to be returned from
417 * Returns: negative is error or timeout, zero is success.
419 static int reg_readwait(struct usb_device *dev,
420 __u16 reg, __u16 index, __u16 value)
425 ret = reg_read(dev, reg, index, 1);
433 static int write_vector(struct gspca_dev *gspca_dev,
436 struct usb_device *dev = gspca_dev->dev;
439 while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) {
440 ret = reg_write(dev, data[i][0], data[i][2], data[i][1]);
448 static int spca50x_setup_qtable(struct gspca_dev *gspca_dev,
449 unsigned int request,
452 unsigned char qtable[2][64])
454 struct usb_device *dev = gspca_dev->dev;
457 /* loop over y components */
458 for (i = 0; i < 64; i++) {
459 err = reg_write(dev, request, ybase + i, qtable[0][i]);
464 /* loop over c components */
465 for (i = 0; i < 64; i++) {
466 err = reg_write(dev, request, cbase + i, qtable[1][i]);
473 static void spca500_ping310(struct gspca_dev *gspca_dev)
477 spca5xxRegRead(gspca_dev->dev, 0x0d04, Data, 2);
478 PDEBUG(D_PACK, "ClickSmart310 ping 0x0d04 0x%02x 0x%02x",
482 static void spca500_clksmart310_init(struct gspca_dev *gspca_dev)
486 spca5xxRegRead(gspca_dev->dev, 0x0d05, Data, 2);
487 PDEBUG(D_PACK, "ClickSmart310 init 0x0d05 0x%02x 0x%02x", Data[0],
489 reg_write(gspca_dev->dev, 0x00, 0x8167, 0x5a);
490 spca500_ping310(gspca_dev);
492 reg_write(gspca_dev->dev, 0x00, 0x8168, 0x22);
493 reg_write(gspca_dev->dev, 0x00, 0x816a, 0xc0);
494 reg_write(gspca_dev->dev, 0x00, 0x816b, 0x0b);
495 reg_write(gspca_dev->dev, 0x00, 0x8169, 0x25);
496 reg_write(gspca_dev->dev, 0x00, 0x8157, 0x5b);
497 reg_write(gspca_dev->dev, 0x00, 0x8158, 0x5b);
498 reg_write(gspca_dev->dev, 0x00, 0x813f, 0x03);
499 reg_write(gspca_dev->dev, 0x00, 0x8151, 0x4a);
500 reg_write(gspca_dev->dev, 0x00, 0x8153, 0x78);
501 reg_write(gspca_dev->dev, 0x00, 0x0d01, 0x04);
502 /* 00 for adjust shutter */
503 reg_write(gspca_dev->dev, 0x00, 0x0d02, 0x01);
504 reg_write(gspca_dev->dev, 0x00, 0x8169, 0x25);
505 reg_write(gspca_dev->dev, 0x00, 0x0d01, 0x02);
508 static void spca500_setmode(struct gspca_dev *gspca_dev,
509 __u8 xmult, __u8 ymult)
513 /* set x multiplier */
514 reg_write(gspca_dev->dev, 0, 0x8001, xmult);
516 /* set y multiplier */
517 reg_write(gspca_dev->dev, 0, 0x8002, ymult);
519 /* use compressed mode, VGA, with mode specific subsample */
520 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode;
521 reg_write(gspca_dev->dev, 0, 0x8003, mode << 4);
524 static int spca500_full_reset(struct gspca_dev *gspca_dev)
528 /* send the reset command */
529 err = reg_write(gspca_dev->dev, 0xe0, 0x0001, 0x0000);
533 /* wait for the reset to complete */
534 err = reg_readwait(gspca_dev->dev, 0x06, 0x0000, 0x0000);
537 err = reg_write(gspca_dev->dev, 0xe0, 0x0000, 0x0000);
540 err = reg_readwait(gspca_dev->dev, 0x06, 0, 0);
542 PDEBUG(D_ERR, "reg_readwait() failed");
549 /* Synchro the Bridge with sensor */
550 /* Maybe that will work on all spca500 chip */
551 /* because i only own a clicksmart310 try for that chip */
552 /* using spca50x_set_packet_size() cause an Ooops here */
553 /* usb_set_interface from kernel 2.6.x clear all the urb stuff */
554 /* up-port the same feature as in 2.4.x kernel */
555 static int spca500_synch310(struct gspca_dev *gspca_dev)
559 if (usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0) < 0) {
560 PDEBUG(D_ERR, "Set packet size: set interface error");
563 spca500_ping310(gspca_dev);
565 spca5xxRegRead(gspca_dev->dev, 0x0d00, &Data, 1);
567 /* need alt setting here */
568 PDEBUG(D_PACK, "ClickSmart310 sync alt: %d", gspca_dev->alt);
570 /* Windoze use pipe with altsetting 6 why 7 here */
571 if (usb_set_interface(gspca_dev->dev,
573 gspca_dev->alt) < 0) {
574 PDEBUG(D_ERR, "Set packet size: set interface error");
582 static void spca500_reinit(struct gspca_dev *gspca_dev)
587 /* some unknow command from Aiptek pocket dv and family300 */
589 reg_write(gspca_dev->dev, 0x00, 0x0d01, 0x01);
590 reg_write(gspca_dev->dev, 0x00, 0x0d03, 0x00);
591 reg_write(gspca_dev->dev, 0x00, 0x0d02, 0x01);
593 /* enable drop packet */
594 reg_write(gspca_dev->dev, 0x00, 0x850a, 0x0001);
596 err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840,
599 PDEBUG(D_ERR|D_STREAM, "spca50x_setup_qtable failed on init");
601 /* set qtable index */
602 reg_write(gspca_dev->dev, 0x00, 0x8880, 2);
603 /* family cam Quicksmart stuff */
604 reg_write(gspca_dev->dev, 0x00, 0x800a, 0x00);
605 /* Set agc transfer: synced inbetween frames */
606 reg_write(gspca_dev->dev, 0x00, 0x820f, 0x01);
607 /* Init SDRAM - needed for SDRAM access */
608 reg_write(gspca_dev->dev, 0x00, 0x870a, 0x04);
609 /*Start init sequence or stream */
611 reg_write(gspca_dev->dev, 0, 0x8003, 0x00);
612 /* switch to video camera mode */
613 reg_write(gspca_dev->dev, 0x00, 0x8000, 0x0004);
615 if (reg_readwait(gspca_dev->dev, 0, 0x8000, 0x44) != 0)
616 spca5xxRegRead(gspca_dev->dev, 0x816b, &Data, 1);
617 reg_write(gspca_dev->dev, 0x00, 0x816b, Data);
620 /* this function is called at probe time */
621 static int sd_config(struct gspca_dev *gspca_dev,
622 const struct usb_device_id *id)
624 struct sd *sd = (struct sd *) gspca_dev;
629 vendor = id->idVendor;
630 product = id->idProduct;
632 case 0x040a: /* Kodak cameras */
633 /* switch (product) { */
635 sd->subtype = KodakEZ200;
639 case 0x041e: /* Creative cameras */
640 /* switch (product) { */
642 sd->subtype = CreativePCCam300;
646 case 0x046d: /* Logitech Labtec */
649 sd->subtype = LogitechTraveler;
652 sd->subtype = LogitechClickSmart310;
655 sd->subtype = LogitechClickSmart510;
659 case 0x04a5: /* Benq */
660 /* switch (product) { */
662 sd->subtype = BenqDC1016;
666 case 0x04fc: /* SunPlus */
667 /* switch (product) { */
669 sd->subtype = PalmPixDC85;
673 case 0x055f: /* Mustek cameras */
676 sd->subtype = MustekGsmart300;
679 sd->subtype = Gsmartmini;
683 case 0x06bd: /* Agfa Cl20 */
684 /* switch (product) { */
686 sd->subtype = AgfaCl20;
690 case 0x06be: /* Optimedia */
691 /* switch (product) { */
693 sd->subtype = Optimedia;
697 case 0x084d: /* D-Link / Minton */
698 /* switch (product) { */
699 /* case 0x0003: * DSC-350 / S-Cam F5 */
700 sd->subtype = DLinkDSC350;
704 case 0x08ca: /* Aiptek */
705 /* switch (product) { */
707 sd->subtype = AiptekPocketDV;
711 case 0x2899: /* ToptroIndustrial */
712 /* switch (product) { */
714 sd->subtype = ToptroIndus;
718 case 0x8086: /* Intel */
719 /* switch (product) { */
720 /* case 0x0630: * Pocket PC Camera */
721 sd->subtype = IntelPocketPCCamera;
726 cam = &gspca_dev->cam;
727 cam->dev_name = (char *) id->driver_info;
729 if (sd->subtype != LogitechClickSmart310) {
730 cam->cam_mode = vga_mode;
731 cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
733 cam->cam_mode = sif_mode;
734 cam->nmodes = sizeof sif_mode / sizeof sif_mode[0];
737 sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
738 sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
739 sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value;
743 /* this function is called at open time */
744 static int sd_open(struct gspca_dev *gspca_dev)
746 struct sd *sd = (struct sd *) gspca_dev;
748 /* initialisation of spca500 based cameras is deferred */
749 PDEBUG(D_STREAM, "SPCA500 init");
750 if (sd->subtype == LogitechClickSmart310)
751 spca500_clksmart310_init(gspca_dev);
753 spca500_initialise(gspca_dev); */
754 PDEBUG(D_STREAM, "SPCA500 init done");
758 static void sd_start(struct gspca_dev *gspca_dev)
760 struct sd *sd = (struct sd *) gspca_dev;
765 if (sd->subtype == LogitechClickSmart310) {
773 /* is there a sensor here ? */
774 spca5xxRegRead(gspca_dev->dev, 0x8a04, &Data, 1);
775 PDEBUG(D_STREAM, "Spca500 Sensor Address 0x%02X", Data);
776 PDEBUG(D_STREAM, "Spca500 curr_mode: %d Xmult: 0x%02X, Ymult: 0x%02X",
777 gspca_dev->curr_mode, xmult, ymult);
780 switch (sd->subtype) {
781 case LogitechClickSmart310:
782 spca500_setmode(gspca_dev, xmult, ymult);
784 /* enable drop packet */
785 reg_write(gspca_dev->dev, 0x00, 0x850a, 0x0001);
786 reg_write(gspca_dev->dev, 0x00, 0x8880, 3);
787 err = spca50x_setup_qtable(gspca_dev,
788 0x00, 0x8800, 0x8840,
789 qtable_creative_pccam);
791 PDEBUG(D_ERR, "spca50x_setup_qtable failed");
792 /* Init SDRAM - needed for SDRAM access */
793 reg_write(gspca_dev->dev, 0x00, 0x870a, 0x04);
795 /* switch to video camera mode */
796 reg_write(gspca_dev->dev, 0x00, 0x8000, 0x0004);
798 if (reg_readwait(gspca_dev->dev, 0, 0x8000, 0x44) != 0)
799 PDEBUG(D_ERR, "reg_readwait() failed");
801 spca5xxRegRead(gspca_dev->dev, 0x816b, &Data, 1);
802 reg_write(gspca_dev->dev, 0x00, 0x816b, Data);
804 spca500_synch310(gspca_dev);
806 write_vector(gspca_dev, spca500_visual_defaults);
807 spca500_setmode(gspca_dev, xmult, ymult);
808 /* enable drop packet */
809 reg_write(gspca_dev->dev, 0x00, 0x850a, 0x0001);
810 PDEBUG(D_ERR, "failed to enable drop packet");
811 reg_write(gspca_dev->dev, 0x00, 0x8880, 3);
812 err = spca50x_setup_qtable(gspca_dev,
813 0x00, 0x8800, 0x8840,
814 qtable_creative_pccam);
816 PDEBUG(D_ERR, "spca50x_setup_qtable failed");
818 /* Init SDRAM - needed for SDRAM access */
819 reg_write(gspca_dev->dev, 0x00, 0x870a, 0x04);
821 /* switch to video camera mode */
822 reg_write(gspca_dev->dev, 0x00, 0x8000, 0x0004);
824 if (reg_readwait(gspca_dev->dev, 0, 0x8000, 0x44) != 0)
825 PDEBUG(D_ERR, "reg_readwait() failed");
827 spca5xxRegRead(gspca_dev->dev, 0x816b, &Data, 1);
828 reg_write(gspca_dev->dev, 0x00, 0x816b, Data);
830 case CreativePCCam300: /* Creative PC-CAM 300 640x480 CCD */
831 case IntelPocketPCCamera: /* FIXME: Temporary fix for
832 * Intel Pocket PC Camera
833 * - NWG (Sat 29th March 2003) */
835 /* do a full reset */
836 err = spca500_full_reset(gspca_dev);
838 PDEBUG(D_ERR, "spca500_full_reset failed");
840 /* enable drop packet */
841 err = reg_write(gspca_dev->dev, 0x00, 0x850a, 0x0001);
843 PDEBUG(D_ERR, "failed to enable drop packet");
844 reg_write(gspca_dev->dev, 0x00, 0x8880, 3);
845 err = spca50x_setup_qtable(gspca_dev,
846 0x00, 0x8800, 0x8840,
847 qtable_creative_pccam);
849 PDEBUG(D_ERR, "spca50x_setup_qtable failed");
851 spca500_setmode(gspca_dev, xmult, ymult);
852 reg_write(gspca_dev->dev, 0x20, 0x0001, 0x0004);
854 /* switch to video camera mode */
855 reg_write(gspca_dev->dev, 0x00, 0x8000, 0x0004);
857 if (reg_readwait(gspca_dev->dev, 0, 0x8000, 0x44) != 0)
858 PDEBUG(D_ERR, "reg_readwait() failed");
860 spca5xxRegRead(gspca_dev->dev, 0x816b, &Data, 1);
861 reg_write(gspca_dev->dev, 0x00, 0x816b, Data);
863 /* write_vector(gspca_dev, spca500_visual_defaults); */
865 case KodakEZ200: /* Kodak EZ200 */
867 /* do a full reset */
868 err = spca500_full_reset(gspca_dev);
870 PDEBUG(D_ERR, "spca500_full_reset failed");
871 /* enable drop packet */
872 reg_write(gspca_dev->dev, 0x00, 0x850a, 0x0001);
873 reg_write(gspca_dev->dev, 0x00, 0x8880, 0);
874 err = spca50x_setup_qtable(gspca_dev,
875 0x00, 0x8800, 0x8840,
878 PDEBUG(D_ERR, "spca50x_setup_qtable failed");
879 spca500_setmode(gspca_dev, xmult, ymult);
881 reg_write(gspca_dev->dev, 0x20, 0x0001, 0x0004);
883 /* switch to video camera mode */
884 reg_write(gspca_dev->dev, 0x00, 0x8000, 0x0004);
886 if (reg_readwait(gspca_dev->dev, 0, 0x8000, 0x44) != 0)
887 PDEBUG(D_ERR, "reg_readwait() failed");
889 spca5xxRegRead(gspca_dev->dev, 0x816b, &Data, 1);
890 reg_write(gspca_dev->dev, 0x00, 0x816b, Data);
892 /* write_vector(gspca_dev, spca500_visual_defaults); */
896 case DLinkDSC350: /* FamilyCam 300 */
897 case AiptekPocketDV: /* Aiptek PocketDV */
898 case Gsmartmini: /*Mustek Gsmart Mini */
899 case MustekGsmart300: /* Mustek Gsmart 300 */
904 spca500_reinit(gspca_dev);
905 reg_write(gspca_dev->dev, 0x00, 0x0d01, 0x01);
906 /* enable drop packet */
907 reg_write(gspca_dev->dev, 0x00, 0x850a, 0x0001);
909 err = spca50x_setup_qtable(gspca_dev,
910 0x00, 0x8800, 0x8840, qtable_pocketdv);
912 PDEBUG(D_ERR, "spca50x_setup_qtable failed");
913 reg_write(gspca_dev->dev, 0x00, 0x8880, 2);
915 /* familycam Quicksmart pocketDV stuff */
916 reg_write(gspca_dev->dev, 0x00, 0x800a, 0x00);
917 /* Set agc transfer: synced inbetween frames */
918 reg_write(gspca_dev->dev, 0x00, 0x820f, 0x01);
919 /* Init SDRAM - needed for SDRAM access */
920 reg_write(gspca_dev->dev, 0x00, 0x870a, 0x04);
922 spca500_setmode(gspca_dev, xmult, ymult);
923 /* switch to video camera mode */
924 reg_write(gspca_dev->dev, 0x00, 0x8000, 0x0004);
926 reg_readwait(gspca_dev->dev, 0, 0x8000, 0x44);
928 spca5xxRegRead(gspca_dev->dev, 0x816b, &Data, 1);
929 reg_write(gspca_dev->dev, 0x00, 0x816b, Data);
931 case LogitechTraveler:
932 case LogitechClickSmart510:
933 reg_write(gspca_dev->dev, 0x02, 0x00, 0x00);
934 /* enable drop packet */
935 reg_write(gspca_dev->dev, 0x00, 0x850a, 0x0001);
937 err = spca50x_setup_qtable(gspca_dev,
939 0x8840, qtable_creative_pccam);
941 PDEBUG(D_ERR, "spca50x_setup_qtable failed");
942 reg_write(gspca_dev->dev, 0x00, 0x8880, 3);
943 reg_write(gspca_dev->dev, 0x00, 0x800a, 0x00);
944 /* Init SDRAM - needed for SDRAM access */
945 reg_write(gspca_dev->dev, 0x00, 0x870a, 0x04);
947 spca500_setmode(gspca_dev, xmult, ymult);
949 /* switch to video camera mode */
950 reg_write(gspca_dev->dev, 0x00, 0x8000, 0x0004);
951 reg_readwait(gspca_dev->dev, 0, 0x8000, 0x44);
953 spca5xxRegRead(gspca_dev->dev, 0x816b, &Data, 1);
954 reg_write(gspca_dev->dev, 0x00, 0x816b, Data);
955 write_vector(gspca_dev, Clicksmart510_defaults);
960 static void sd_stopN(struct gspca_dev *gspca_dev)
964 reg_write(gspca_dev->dev, 0, 0x8003, 0x00);
966 /* switch to video camera mode */
967 reg_write(gspca_dev->dev, 0x00, 0x8000, 0x0004);
968 spca5xxRegRead(gspca_dev->dev, 0x8000, &data, 1);
969 PDEBUG(D_STREAM, "stop SPCA500 done reg8000: 0x%2x", data);
972 static void sd_stop0(struct gspca_dev *gspca_dev)
976 static void sd_close(struct gspca_dev *gspca_dev)
980 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
981 struct gspca_frame *frame, /* target */
982 unsigned char *data, /* isoc packet */
983 int len) /* iso packet length */
985 struct sd *sd = (struct sd *) gspca_dev;
987 unsigned char *s, *d;
988 static unsigned char ffd9[] = {0xff, 0xd9};
990 /* frames are jpeg 4.1.1 without 0xff escape */
991 if (data[0] == 0xff) {
992 if (data[1] != 0x01) { /* drop packet */
993 /* gspca_dev->last_packet_type = DISCARD_PACKET; */
996 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
999 /* put the JPEG header in the new frame */
1000 jpeg_put_header(gspca_dev, frame,
1001 ((struct sd *) gspca_dev)->qindex,
1004 data += SPCA500_OFFSET_DATA;
1005 len -= SPCA500_OFFSET_DATA;
1011 /* add 0x00 after 0xff */
1012 for (i = len; --i >= 0; )
1013 if (data[i] == 0xff)
1015 if (i < 0) { /* no 0xff */
1016 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1021 for (i = 0; i < len; i++) {
1026 gspca_frame_add(gspca_dev, INTER_PACKET, frame,
1027 sd->packet, d - sd->packet);
1030 static void setbrightness(struct gspca_dev *gspca_dev)
1032 struct sd *sd = (struct sd *) gspca_dev;
1034 reg_write(gspca_dev->dev, 0x00, 0x8167,
1035 (__u8) (sd->brightness - 128));
1038 static void getbrightness(struct gspca_dev *gspca_dev)
1040 struct sd *sd = (struct sd *) gspca_dev;
1042 sd->brightness = reg_read(gspca_dev->dev, 0x00, 0x8167, 1) + 128;
1045 static void setcontrast(struct gspca_dev *gspca_dev)
1047 struct sd *sd = (struct sd *) gspca_dev;
1049 reg_write(gspca_dev->dev, 0x00, 0x8168, sd->contrast >> 2);
1052 static void getcontrast(struct gspca_dev *gspca_dev)
1054 struct sd *sd = (struct sd *) gspca_dev;
1056 sd->contrast = reg_read(gspca_dev->dev, 0x0, 0x8168, 1) << 2;
1059 static void setcolors(struct gspca_dev *gspca_dev)
1061 struct sd *sd = (struct sd *) gspca_dev;
1063 reg_write(gspca_dev->dev, 0x00, 0x8169, sd->colors >> 2);
1066 static void getcolors(struct gspca_dev *gspca_dev)
1068 struct sd *sd = (struct sd *) gspca_dev;
1070 sd->colors = reg_read(gspca_dev->dev, 0x0, 0x8169, 1) << 2;
1073 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1075 struct sd *sd = (struct sd *) gspca_dev;
1077 sd->brightness = val;
1078 if (gspca_dev->streaming)
1079 setbrightness(gspca_dev);
1083 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1085 struct sd *sd = (struct sd *) gspca_dev;
1087 getbrightness(gspca_dev);
1088 *val = sd->brightness;
1092 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1094 struct sd *sd = (struct sd *) gspca_dev;
1097 if (gspca_dev->streaming)
1098 setcontrast(gspca_dev);
1102 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1104 struct sd *sd = (struct sd *) gspca_dev;
1106 getcontrast(gspca_dev);
1107 *val = sd->contrast;
1111 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1113 struct sd *sd = (struct sd *) gspca_dev;
1116 if (gspca_dev->streaming)
1117 setcolors(gspca_dev);
1121 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1123 struct sd *sd = (struct sd *) gspca_dev;
1125 getcolors(gspca_dev);
1130 /* sub-driver description */
1131 static struct sd_desc sd_desc = {
1132 .name = MODULE_NAME,
1134 .nctrls = sizeof sd_ctrls / sizeof sd_ctrls[0],
1135 .config = sd_config,
1141 .pkt_scan = sd_pkt_scan,
1144 /* -- module initialisation -- */
1145 #define DVNM(name) .driver_info = (kernel_ulong_t) name
1146 static __devinitdata struct usb_device_id device_table[] = {
1147 {USB_DEVICE(0x040a, 0x0300), DVNM("Kodak EZ200")},
1148 {USB_DEVICE(0x041e, 0x400a), DVNM("Creative PC-CAM 300")},
1149 {USB_DEVICE(0x046d, 0x0890), DVNM("Logitech QuickCam traveler")},
1150 {USB_DEVICE(0x046d, 0x0900), DVNM("Logitech Inc. ClickSmart 310")},
1151 {USB_DEVICE(0x046d, 0x0901), DVNM("Logitech Inc. ClickSmart 510")},
1152 {USB_DEVICE(0x04a5, 0x300c), DVNM("Benq DC1016")},
1153 {USB_DEVICE(0x04fc, 0x7333), DVNM("PalmPixDC85")},
1154 {USB_DEVICE(0x055f, 0xc200), DVNM("Mustek Gsmart 300")},
1155 {USB_DEVICE(0x055f, 0xc220), DVNM("Gsmart Mini")},
1156 {USB_DEVICE(0x06bd, 0x0404), DVNM("Agfa CL20")},
1157 {USB_DEVICE(0x06be, 0x0800), DVNM("Optimedia")},
1158 {USB_DEVICE(0x084d, 0x0003), DVNM("D-Link DSC-350")},
1159 {USB_DEVICE(0x08ca, 0x0103), DVNM("Aiptek PocketDV")},
1160 {USB_DEVICE(0x2899, 0x012c), DVNM("Toptro Industrial")},
1161 {USB_DEVICE(0x8086, 0x0630), DVNM("Intel Pocket PC Camera")},
1164 MODULE_DEVICE_TABLE(usb, device_table);
1166 /* -- device connect -- */
1167 static int sd_probe(struct usb_interface *intf,
1168 const struct usb_device_id *id)
1170 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1174 static struct usb_driver sd_driver = {
1175 .name = MODULE_NAME,
1176 .id_table = device_table,
1178 .disconnect = gspca_disconnect,
1181 /* -- module insert / remove -- */
1182 static int __init sd_mod_init(void)
1184 if (usb_register(&sd_driver) < 0)
1186 PDEBUG(D_PROBE, "v%s registered", version);
1189 static void __exit sd_mod_exit(void)
1191 usb_deregister(&sd_driver);
1192 PDEBUG(D_PROBE, "deregistered");
1195 module_init(sd_mod_init);
1196 module_exit(sd_mod_exit);