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_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 if ((err = spca500_full_reset(gspca_dev)) < 0)
837 PDEBUG(D_ERR, "spca500_full_reset failed");
839 /* enable drop packet */
840 err = reg_write(gspca_dev->dev, 0x00, 0x850a, 0x0001);
842 PDEBUG(D_ERR, "failed to enable drop packet");
843 reg_write(gspca_dev->dev, 0x00, 0x8880, 3);
844 err = spca50x_setup_qtable(gspca_dev,
845 0x00, 0x8800, 0x8840,
846 qtable_creative_pccam);
848 PDEBUG(D_ERR, "spca50x_setup_qtable failed");
850 spca500_setmode(gspca_dev, xmult, ymult);
851 reg_write(gspca_dev->dev, 0x20, 0x0001, 0x0004);
853 /* switch to video camera mode */
854 reg_write(gspca_dev->dev, 0x00, 0x8000, 0x0004);
856 if (reg_readwait(gspca_dev->dev, 0, 0x8000, 0x44) != 0)
857 PDEBUG(D_ERR, "reg_readwait() failed");
859 spca5xxRegRead(gspca_dev->dev, 0x816b, &Data, 1);
860 reg_write(gspca_dev->dev, 0x00, 0x816b, Data);
862 /* write_vector(gspca_dev, spca500_visual_defaults); */
864 case KodakEZ200: /* Kodak EZ200 */
866 /* do a full reset */
867 err = spca500_full_reset(gspca_dev);
869 PDEBUG(D_ERR, "spca500_full_reset failed");
870 /* enable drop packet */
871 reg_write(gspca_dev->dev, 0x00, 0x850a, 0x0001);
872 reg_write(gspca_dev->dev, 0x00, 0x8880, 0);
873 err = spca50x_setup_qtable(gspca_dev,
874 0x00, 0x8800, 0x8840,
877 PDEBUG(D_ERR, "spca50x_setup_qtable failed");
878 spca500_setmode(gspca_dev, xmult, ymult);
880 reg_write(gspca_dev->dev, 0x20, 0x0001, 0x0004);
882 /* switch to video camera mode */
883 reg_write(gspca_dev->dev, 0x00, 0x8000, 0x0004);
885 if (reg_readwait(gspca_dev->dev, 0, 0x8000, 0x44) != 0)
886 PDEBUG(D_ERR, "reg_readwait() failed");
888 spca5xxRegRead(gspca_dev->dev, 0x816b, &Data, 1);
889 reg_write(gspca_dev->dev, 0x00, 0x816b, Data);
891 /* write_vector(gspca_dev, spca500_visual_defaults); */
895 case DLinkDSC350: /* FamilyCam 300 */
896 case AiptekPocketDV: /* Aiptek PocketDV */
897 case Gsmartmini: /*Mustek Gsmart Mini */
898 case MustekGsmart300: /* Mustek Gsmart 300 */
903 spca500_reinit(gspca_dev);
904 reg_write(gspca_dev->dev, 0x00, 0x0d01, 0x01);
905 /* enable drop packet */
906 reg_write(gspca_dev->dev, 0x00, 0x850a, 0x0001);
908 err = spca50x_setup_qtable(gspca_dev,
909 0x00, 0x8800, 0x8840, qtable_pocketdv);
911 PDEBUG(D_ERR, "spca50x_setup_qtable failed");
912 reg_write(gspca_dev->dev, 0x00, 0x8880, 2);
914 /* familycam Quicksmart pocketDV stuff */
915 reg_write(gspca_dev->dev, 0x00, 0x800a, 0x00);
916 /* Set agc transfer: synced inbetween frames */
917 reg_write(gspca_dev->dev, 0x00, 0x820f, 0x01);
918 /* Init SDRAM - needed for SDRAM access */
919 reg_write(gspca_dev->dev, 0x00, 0x870a, 0x04);
921 spca500_setmode(gspca_dev,xmult,ymult);
922 /* switch to video camera mode */
923 reg_write(gspca_dev->dev, 0x00, 0x8000, 0x0004);
925 reg_readwait(gspca_dev->dev, 0, 0x8000, 0x44);
927 spca5xxRegRead(gspca_dev->dev, 0x816b, &Data, 1);
928 reg_write(gspca_dev->dev, 0x00, 0x816b, Data);
930 case LogitechTraveler:
931 case LogitechClickSmart510:
932 reg_write(gspca_dev->dev, 0x02, 0x00, 0x00);
933 /* enable drop packet */
934 reg_write(gspca_dev->dev, 0x00, 0x850a, 0x0001);
936 err = spca50x_setup_qtable(gspca_dev,
938 0x8840, qtable_creative_pccam);
940 PDEBUG(D_ERR, "spca50x_setup_qtable failed");
941 reg_write(gspca_dev->dev, 0x00, 0x8880, 3);
942 reg_write(gspca_dev->dev, 0x00, 0x800a, 0x00);
943 /* Init SDRAM - needed for SDRAM access */
944 reg_write(gspca_dev->dev, 0x00, 0x870a, 0x04);
946 spca500_setmode(gspca_dev, xmult, ymult);
948 /* switch to video camera mode */
949 reg_write(gspca_dev->dev, 0x00, 0x8000, 0x0004);
950 reg_readwait(gspca_dev->dev, 0, 0x8000, 0x44);
952 spca5xxRegRead(gspca_dev->dev, 0x816b, &Data, 1);
953 reg_write(gspca_dev->dev, 0x00, 0x816b, Data);
954 write_vector(gspca_dev, Clicksmart510_defaults);
959 static void sd_stopN(struct gspca_dev *gspca_dev)
963 reg_write(gspca_dev->dev, 0, 0x8003, 0x00);
965 /* switch to video camera mode */
966 reg_write(gspca_dev->dev, 0x00, 0x8000, 0x0004);
967 spca5xxRegRead(gspca_dev->dev, 0x8000, &data, 1);
968 PDEBUG(D_STREAM, "stop SPCA500 done reg8000: 0x%2x", data);
971 static void sd_stop0(struct gspca_dev *gspca_dev)
975 static void sd_close(struct gspca_dev *gspca_dev)
979 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
980 struct gspca_frame *frame, /* target */
981 unsigned char *data, /* isoc packet */
982 int len) /* iso packet length */
984 struct sd *sd = (struct sd *) gspca_dev;
986 unsigned char *s, *d;
987 static unsigned char ffd9[] = {0xff, 0xd9};
989 /* frames are jpeg 4.1.1 without 0xff escape */
990 if (data[0] == 0xff) {
991 if (data[1] != 0x01) { /* drop packet */
992 /* gspca_dev->last_packet_type = DISCARD_PACKET; */
995 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
998 /* put the JPEG header in the new frame */
999 jpeg_put_header(gspca_dev, frame,
1000 ((struct sd *) gspca_dev)->qindex,
1003 data += SPCA500_OFFSET_DATA;
1004 len -= SPCA500_OFFSET_DATA;
1010 /* add 0x00 after 0xff */
1011 for (i = len; --i >= 0; )
1012 if (data[i] == 0xff)
1014 if (i < 0) { /* no 0xff */
1015 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1020 for (i = 0; i < len; i++) {
1025 gspca_frame_add(gspca_dev, INTER_PACKET, frame,
1026 sd->packet, d - sd->packet);
1029 static void setbrightness(struct gspca_dev *gspca_dev)
1031 struct sd *sd = (struct sd *) gspca_dev;
1033 reg_write(gspca_dev->dev, 0x00, 0x8167,
1034 (__u8) (sd->brightness - 128));
1037 static void getbrightness(struct gspca_dev *gspca_dev)
1039 struct sd *sd = (struct sd *) gspca_dev;
1041 sd->brightness = reg_read(gspca_dev->dev, 0x00, 0x8167, 1) + 128;
1044 static void setcontrast(struct gspca_dev *gspca_dev)
1046 struct sd *sd = (struct sd *) gspca_dev;
1048 reg_write(gspca_dev->dev, 0x00, 0x8168, sd->contrast >> 2);
1051 static void getcontrast(struct gspca_dev *gspca_dev)
1053 struct sd *sd = (struct sd *) gspca_dev;
1055 sd->contrast = reg_read(gspca_dev->dev, 0x0, 0x8168, 1) << 2;
1058 static void setcolors(struct gspca_dev *gspca_dev)
1060 struct sd *sd = (struct sd *) gspca_dev;
1062 reg_write(gspca_dev->dev, 0x00, 0x8169, sd->colors >> 2);
1065 static void getcolors(struct gspca_dev *gspca_dev)
1067 struct sd *sd = (struct sd *) gspca_dev;
1069 sd->colors = reg_read(gspca_dev->dev, 0x0, 0x8169, 1) << 2;
1072 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1074 struct sd *sd = (struct sd *) gspca_dev;
1076 sd->brightness = val;
1077 if (gspca_dev->streaming)
1078 setbrightness(gspca_dev);
1082 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1084 struct sd *sd = (struct sd *) gspca_dev;
1086 getbrightness(gspca_dev);
1087 *val = sd->brightness;
1091 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1093 struct sd *sd = (struct sd *) gspca_dev;
1096 if (gspca_dev->streaming)
1097 setcontrast(gspca_dev);
1101 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1103 struct sd *sd = (struct sd *) gspca_dev;
1105 getcontrast(gspca_dev);
1106 *val = sd->contrast;
1110 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1112 struct sd *sd = (struct sd *) gspca_dev;
1115 if (gspca_dev->streaming)
1116 setcolors(gspca_dev);
1120 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1122 struct sd *sd = (struct sd *) gspca_dev;
1124 getcolors(gspca_dev);
1129 /* sub-driver description */
1130 static struct sd_desc sd_desc = {
1131 .name = MODULE_NAME,
1133 .nctrls = sizeof sd_ctrls / sizeof sd_ctrls[0],
1134 .config = sd_config,
1140 .pkt_scan = sd_pkt_scan,
1143 /* -- module initialisation -- */
1144 #define DVNM(name) .driver_info = (kernel_ulong_t) name
1145 static __devinitdata struct usb_device_id device_table[] = {
1146 {USB_DEVICE(0x040a, 0x0300), DVNM("Kodak EZ200")},
1147 {USB_DEVICE(0x041e, 0x400a), DVNM("Creative PC-CAM 300")},
1148 {USB_DEVICE(0x046d, 0x0890), DVNM("Logitech QuickCam traveler")},
1149 {USB_DEVICE(0x046d, 0x0900), DVNM("Logitech Inc. ClickSmart 310")},
1150 {USB_DEVICE(0x046d, 0x0901), DVNM("Logitech Inc. ClickSmart 510")},
1151 {USB_DEVICE(0x04a5, 0x300c), DVNM("Benq DC1016")},
1152 {USB_DEVICE(0x04fc, 0x7333), DVNM("PalmPixDC85")},
1153 {USB_DEVICE(0x055f, 0xc200), DVNM("Mustek Gsmart 300")},
1154 {USB_DEVICE(0x055f, 0xc220), DVNM("Gsmart Mini")},
1155 {USB_DEVICE(0x06bd, 0x0404), DVNM("Agfa CL20")},
1156 {USB_DEVICE(0x06be, 0x0800), DVNM("Optimedia")},
1157 {USB_DEVICE(0x084d, 0x0003), DVNM("D-Link DSC-350")},
1158 {USB_DEVICE(0x08ca, 0x0103), DVNM("Aiptek PocketDV")},
1159 {USB_DEVICE(0x2899, 0x012c), DVNM("Toptro Industrial")},
1160 {USB_DEVICE(0x8086, 0x0630), DVNM("Intel Pocket PC Camera")},
1163 MODULE_DEVICE_TABLE(usb, device_table);
1165 /* -- device connect -- */
1166 static int sd_probe(struct usb_interface *intf,
1167 const struct usb_device_id *id)
1169 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1173 static struct usb_driver sd_driver = {
1174 .name = MODULE_NAME,
1175 .id_table = device_table,
1177 .disconnect = gspca_disconnect,
1180 /* -- module insert / remove -- */
1181 static int __init sd_mod_init(void)
1183 if (usb_register(&sd_driver) < 0)
1185 PDEBUG(D_PROBE, "v%s registered", version);
1188 static void __exit sd_mod_exit(void)
1190 usb_deregister(&sd_driver);
1191 PDEBUG(D_PROBE, "deregistered");
1194 module_init(sd_mod_init);
1195 module_exit(sd_mod_exit);