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, 5)
28 static const char version[] = "2.1.5";
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 static void reg_r(struct usb_device *dev,
377 __u8 *buffer, __u16 length)
380 usb_rcvctrlpipe(dev, 0),
382 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
384 index, buffer, length, 500);
387 static int reg_w(struct usb_device *dev,
388 __u16 req, __u16 index, __u16 value)
392 PDEBUG(D_USBO, "reg write: [0x%02x] = 0x%02x", index, value);
393 ret = usb_control_msg(dev,
394 usb_sndctrlpipe(dev, 0),
396 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
397 value, index, NULL, 0, 500);
399 PDEBUG(D_ERR, "reg write: error %d", ret);
403 /* returns: negative is error, pos or zero is data */
404 static int reg_r_12(struct usb_device *dev,
405 __u16 req, /* bRequest */
406 __u16 index, /* wIndex */
407 __u16 length) /* wLength (1 or 2 only) */
413 ret = usb_control_msg(dev,
414 usb_rcvctrlpipe(dev, 0),
416 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
422 PDEBUG(D_ERR, "reg_r_12 err %d", ret);
425 return (buf[1] << 8) + 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 usb_device *dev,
434 __u16 reg, __u16 index, __u16 value)
439 ret = reg_r_12(dev, reg, index, 1);
447 static int write_vector(struct gspca_dev *gspca_dev,
448 const __u16 data[][3])
450 struct usb_device *dev = gspca_dev->dev;
453 while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) {
454 ret = reg_w(dev, data[i][0], data[i][2], data[i][1]);
462 static int spca50x_setup_qtable(struct gspca_dev *gspca_dev,
463 unsigned int request,
466 const __u8 qtable[2][64])
468 struct usb_device *dev = gspca_dev->dev;
471 /* loop over y components */
472 for (i = 0; i < 64; i++) {
473 err = reg_w(dev, request, ybase + i, qtable[0][i]);
478 /* loop over c components */
479 for (i = 0; i < 64; i++) {
480 err = reg_w(dev, request, cbase + i, qtable[1][i]);
487 static void spca500_ping310(struct gspca_dev *gspca_dev)
491 reg_r(gspca_dev->dev, 0x0d04, Data, 2);
492 PDEBUG(D_STREAM, "ClickSmart310 ping 0x0d04 0x%02x 0x%02x",
496 static void spca500_clksmart310_init(struct gspca_dev *gspca_dev)
500 reg_r(gspca_dev->dev, 0x0d05, Data, 2);
501 PDEBUG(D_STREAM, "ClickSmart310 init 0x0d05 0x%02x 0x%02x",
503 reg_w(gspca_dev->dev, 0x00, 0x8167, 0x5a);
504 spca500_ping310(gspca_dev);
506 reg_w(gspca_dev->dev, 0x00, 0x8168, 0x22);
507 reg_w(gspca_dev->dev, 0x00, 0x816a, 0xc0);
508 reg_w(gspca_dev->dev, 0x00, 0x816b, 0x0b);
509 reg_w(gspca_dev->dev, 0x00, 0x8169, 0x25);
510 reg_w(gspca_dev->dev, 0x00, 0x8157, 0x5b);
511 reg_w(gspca_dev->dev, 0x00, 0x8158, 0x5b);
512 reg_w(gspca_dev->dev, 0x00, 0x813f, 0x03);
513 reg_w(gspca_dev->dev, 0x00, 0x8151, 0x4a);
514 reg_w(gspca_dev->dev, 0x00, 0x8153, 0x78);
515 reg_w(gspca_dev->dev, 0x00, 0x0d01, 0x04);
516 /* 00 for adjust shutter */
517 reg_w(gspca_dev->dev, 0x00, 0x0d02, 0x01);
518 reg_w(gspca_dev->dev, 0x00, 0x8169, 0x25);
519 reg_w(gspca_dev->dev, 0x00, 0x0d01, 0x02);
522 static void spca500_setmode(struct gspca_dev *gspca_dev,
523 __u8 xmult, __u8 ymult)
527 /* set x multiplier */
528 reg_w(gspca_dev->dev, 0, 0x8001, xmult);
530 /* set y multiplier */
531 reg_w(gspca_dev->dev, 0, 0x8002, ymult);
533 /* use compressed mode, VGA, with mode specific subsample */
534 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
535 reg_w(gspca_dev->dev, 0, 0x8003, mode << 4);
538 static int spca500_full_reset(struct gspca_dev *gspca_dev)
542 /* send the reset command */
543 err = reg_w(gspca_dev->dev, 0xe0, 0x0001, 0x0000);
547 /* wait for the reset to complete */
548 err = reg_r_wait(gspca_dev->dev, 0x06, 0x0000, 0x0000);
551 err = reg_w(gspca_dev->dev, 0xe0, 0x0000, 0x0000);
554 err = reg_r_wait(gspca_dev->dev, 0x06, 0, 0);
556 PDEBUG(D_ERR, "reg_r_wait() failed");
563 /* Synchro the Bridge with sensor */
564 /* Maybe that will work on all spca500 chip */
565 /* because i only own a clicksmart310 try for that chip */
566 /* using spca50x_set_packet_size() cause an Ooops here */
567 /* usb_set_interface from kernel 2.6.x clear all the urb stuff */
568 /* up-port the same feature as in 2.4.x kernel */
569 static int spca500_synch310(struct gspca_dev *gspca_dev)
573 if (usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0) < 0) {
574 PDEBUG(D_ERR, "Set packet size: set interface error");
577 spca500_ping310(gspca_dev);
579 reg_r(gspca_dev->dev, 0x0d00, &Data, 1);
581 /* need alt setting here */
582 PDEBUG(D_PACK, "ClickSmart310 sync alt: %d", gspca_dev->alt);
584 /* Windoze use pipe with altsetting 6 why 7 here */
585 if (usb_set_interface(gspca_dev->dev,
587 gspca_dev->alt) < 0) {
588 PDEBUG(D_ERR, "Set packet size: set interface error");
596 static void spca500_reinit(struct gspca_dev *gspca_dev)
601 /* some unknow command from Aiptek pocket dv and family300 */
603 reg_w(gspca_dev->dev, 0x00, 0x0d01, 0x01);
604 reg_w(gspca_dev->dev, 0x00, 0x0d03, 0x00);
605 reg_w(gspca_dev->dev, 0x00, 0x0d02, 0x01);
607 /* enable drop packet */
608 reg_w(gspca_dev->dev, 0x00, 0x850a, 0x0001);
610 err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840,
613 PDEBUG(D_ERR|D_STREAM, "spca50x_setup_qtable failed on init");
615 /* set qtable index */
616 reg_w(gspca_dev->dev, 0x00, 0x8880, 2);
617 /* family cam Quicksmart stuff */
618 reg_w(gspca_dev->dev, 0x00, 0x800a, 0x00);
619 /* Set agc transfer: synced inbetween frames */
620 reg_w(gspca_dev->dev, 0x00, 0x820f, 0x01);
621 /* Init SDRAM - needed for SDRAM access */
622 reg_w(gspca_dev->dev, 0x00, 0x870a, 0x04);
623 /*Start init sequence or stream */
625 reg_w(gspca_dev->dev, 0, 0x8003, 0x00);
626 /* switch to video camera mode */
627 reg_w(gspca_dev->dev, 0x00, 0x8000, 0x0004);
629 if (reg_r_wait(gspca_dev->dev, 0, 0x8000, 0x44) != 0)
630 reg_r(gspca_dev->dev, 0x816b, &Data, 1);
631 reg_w(gspca_dev->dev, 0x00, 0x816b, Data);
634 /* this function is called at probe time */
635 static int sd_config(struct gspca_dev *gspca_dev,
636 const struct usb_device_id *id)
638 struct sd *sd = (struct sd *) gspca_dev;
643 vendor = id->idVendor;
644 product = id->idProduct;
646 case 0x040a: /* Kodak cameras */
647 /* switch (product) { */
649 sd->subtype = KodakEZ200;
653 case 0x041e: /* Creative cameras */
654 /* switch (product) { */
656 sd->subtype = CreativePCCam300;
660 case 0x046d: /* Logitech Labtec */
663 sd->subtype = LogitechTraveler;
666 sd->subtype = LogitechClickSmart310;
669 sd->subtype = LogitechClickSmart510;
673 case 0x04a5: /* Benq */
674 /* switch (product) { */
676 sd->subtype = BenqDC1016;
680 case 0x04fc: /* SunPlus */
681 /* switch (product) { */
683 sd->subtype = PalmPixDC85;
687 case 0x055f: /* Mustek cameras */
690 sd->subtype = MustekGsmart300;
693 sd->subtype = Gsmartmini;
697 case 0x06bd: /* Agfa Cl20 */
698 /* switch (product) { */
700 sd->subtype = AgfaCl20;
704 case 0x06be: /* Optimedia */
705 /* switch (product) { */
707 sd->subtype = Optimedia;
711 case 0x084d: /* D-Link / Minton */
712 /* switch (product) { */
713 /* case 0x0003: * DSC-350 / S-Cam F5 */
714 sd->subtype = DLinkDSC350;
718 case 0x08ca: /* Aiptek */
719 /* switch (product) { */
721 sd->subtype = AiptekPocketDV;
725 case 0x2899: /* ToptroIndustrial */
726 /* switch (product) { */
728 sd->subtype = ToptroIndus;
732 case 0x8086: /* Intel */
733 /* switch (product) { */
734 /* case 0x0630: * Pocket PC Camera */
735 sd->subtype = IntelPocketPCCamera;
740 cam = &gspca_dev->cam;
741 cam->dev_name = (char *) id->driver_info;
743 if (sd->subtype != LogitechClickSmart310) {
744 cam->cam_mode = vga_mode;
745 cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
747 cam->cam_mode = sif_mode;
748 cam->nmodes = sizeof sif_mode / sizeof sif_mode[0];
751 sd->brightness = BRIGHTNESS_DEF;
752 sd->contrast = CONTRAST_DEF;
753 sd->colors = COLOR_DEF;
757 /* this function is called at open time */
758 static int sd_open(struct gspca_dev *gspca_dev)
760 struct sd *sd = (struct sd *) gspca_dev;
762 /* initialisation of spca500 based cameras is deferred */
763 PDEBUG(D_STREAM, "SPCA500 init");
764 if (sd->subtype == LogitechClickSmart310)
765 spca500_clksmart310_init(gspca_dev);
767 spca500_initialise(gspca_dev); */
768 PDEBUG(D_STREAM, "SPCA500 init done");
772 static void sd_start(struct gspca_dev *gspca_dev)
774 struct sd *sd = (struct sd *) gspca_dev;
779 if (sd->subtype == LogitechClickSmart310) {
787 /* is there a sensor here ? */
788 reg_r(gspca_dev->dev, 0x8a04, &Data, 1);
789 PDEBUG(D_STREAM, "Spca500 Sensor Address 0x%02X", Data);
790 PDEBUG(D_STREAM, "Spca500 curr_mode: %d Xmult: 0x%02X, Ymult: 0x%02X",
791 gspca_dev->curr_mode, xmult, ymult);
794 switch (sd->subtype) {
795 case LogitechClickSmart310:
796 spca500_setmode(gspca_dev, xmult, ymult);
798 /* enable drop packet */
799 reg_w(gspca_dev->dev, 0x00, 0x850a, 0x0001);
800 reg_w(gspca_dev->dev, 0x00, 0x8880, 3);
801 err = spca50x_setup_qtable(gspca_dev,
802 0x00, 0x8800, 0x8840,
803 qtable_creative_pccam);
805 PDEBUG(D_ERR, "spca50x_setup_qtable failed");
806 /* Init SDRAM - needed for SDRAM access */
807 reg_w(gspca_dev->dev, 0x00, 0x870a, 0x04);
809 /* switch to video camera mode */
810 reg_w(gspca_dev->dev, 0x00, 0x8000, 0x0004);
812 if (reg_r_wait(gspca_dev->dev, 0, 0x8000, 0x44) != 0)
813 PDEBUG(D_ERR, "reg_r_wait() failed");
815 reg_r(gspca_dev->dev, 0x816b, &Data, 1);
816 reg_w(gspca_dev->dev, 0x00, 0x816b, Data);
818 spca500_synch310(gspca_dev);
820 write_vector(gspca_dev, spca500_visual_defaults);
821 spca500_setmode(gspca_dev, xmult, ymult);
822 /* enable drop packet */
823 reg_w(gspca_dev->dev, 0x00, 0x850a, 0x0001);
824 PDEBUG(D_ERR, "failed to enable drop packet");
825 reg_w(gspca_dev->dev, 0x00, 0x8880, 3);
826 err = spca50x_setup_qtable(gspca_dev,
827 0x00, 0x8800, 0x8840,
828 qtable_creative_pccam);
830 PDEBUG(D_ERR, "spca50x_setup_qtable failed");
832 /* Init SDRAM - needed for SDRAM access */
833 reg_w(gspca_dev->dev, 0x00, 0x870a, 0x04);
835 /* switch to video camera mode */
836 reg_w(gspca_dev->dev, 0x00, 0x8000, 0x0004);
838 if (reg_r_wait(gspca_dev->dev, 0, 0x8000, 0x44) != 0)
839 PDEBUG(D_ERR, "reg_r_wait() failed");
841 reg_r(gspca_dev->dev, 0x816b, &Data, 1);
842 reg_w(gspca_dev->dev, 0x00, 0x816b, Data);
844 case CreativePCCam300: /* Creative PC-CAM 300 640x480 CCD */
845 case IntelPocketPCCamera: /* FIXME: Temporary fix for
846 * Intel Pocket PC Camera
847 * - NWG (Sat 29th March 2003) */
849 /* do a full reset */
850 err = spca500_full_reset(gspca_dev);
852 PDEBUG(D_ERR, "spca500_full_reset failed");
854 /* enable drop packet */
855 err = reg_w(gspca_dev->dev, 0x00, 0x850a, 0x0001);
857 PDEBUG(D_ERR, "failed to enable drop packet");
858 reg_w(gspca_dev->dev, 0x00, 0x8880, 3);
859 err = spca50x_setup_qtable(gspca_dev,
860 0x00, 0x8800, 0x8840,
861 qtable_creative_pccam);
863 PDEBUG(D_ERR, "spca50x_setup_qtable failed");
865 spca500_setmode(gspca_dev, xmult, ymult);
866 reg_w(gspca_dev->dev, 0x20, 0x0001, 0x0004);
868 /* switch to video camera mode */
869 reg_w(gspca_dev->dev, 0x00, 0x8000, 0x0004);
871 if (reg_r_wait(gspca_dev->dev, 0, 0x8000, 0x44) != 0)
872 PDEBUG(D_ERR, "reg_r_wait() failed");
874 reg_r(gspca_dev->dev, 0x816b, &Data, 1);
875 reg_w(gspca_dev->dev, 0x00, 0x816b, Data);
877 /* write_vector(gspca_dev, spca500_visual_defaults); */
879 case KodakEZ200: /* Kodak EZ200 */
881 /* do a full reset */
882 err = spca500_full_reset(gspca_dev);
884 PDEBUG(D_ERR, "spca500_full_reset failed");
885 /* enable drop packet */
886 reg_w(gspca_dev->dev, 0x00, 0x850a, 0x0001);
887 reg_w(gspca_dev->dev, 0x00, 0x8880, 0);
888 err = spca50x_setup_qtable(gspca_dev,
889 0x00, 0x8800, 0x8840,
892 PDEBUG(D_ERR, "spca50x_setup_qtable failed");
893 spca500_setmode(gspca_dev, xmult, ymult);
895 reg_w(gspca_dev->dev, 0x20, 0x0001, 0x0004);
897 /* switch to video camera mode */
898 reg_w(gspca_dev->dev, 0x00, 0x8000, 0x0004);
900 if (reg_r_wait(gspca_dev->dev, 0, 0x8000, 0x44) != 0)
901 PDEBUG(D_ERR, "reg_r_wait() failed");
903 reg_r(gspca_dev->dev, 0x816b, &Data, 1);
904 reg_w(gspca_dev->dev, 0x00, 0x816b, Data);
906 /* write_vector(gspca_dev, spca500_visual_defaults); */
910 case DLinkDSC350: /* FamilyCam 300 */
911 case AiptekPocketDV: /* Aiptek PocketDV */
912 case Gsmartmini: /*Mustek Gsmart Mini */
913 case MustekGsmart300: /* Mustek Gsmart 300 */
918 spca500_reinit(gspca_dev);
919 reg_w(gspca_dev->dev, 0x00, 0x0d01, 0x01);
920 /* enable drop packet */
921 reg_w(gspca_dev->dev, 0x00, 0x850a, 0x0001);
923 err = spca50x_setup_qtable(gspca_dev,
924 0x00, 0x8800, 0x8840, qtable_pocketdv);
926 PDEBUG(D_ERR, "spca50x_setup_qtable failed");
927 reg_w(gspca_dev->dev, 0x00, 0x8880, 2);
929 /* familycam Quicksmart pocketDV stuff */
930 reg_w(gspca_dev->dev, 0x00, 0x800a, 0x00);
931 /* Set agc transfer: synced inbetween frames */
932 reg_w(gspca_dev->dev, 0x00, 0x820f, 0x01);
933 /* Init SDRAM - needed for SDRAM access */
934 reg_w(gspca_dev->dev, 0x00, 0x870a, 0x04);
936 spca500_setmode(gspca_dev, xmult, ymult);
937 /* switch to video camera mode */
938 reg_w(gspca_dev->dev, 0x00, 0x8000, 0x0004);
940 reg_r_wait(gspca_dev->dev, 0, 0x8000, 0x44);
942 reg_r(gspca_dev->dev, 0x816b, &Data, 1);
943 reg_w(gspca_dev->dev, 0x00, 0x816b, Data);
945 case LogitechTraveler:
946 case LogitechClickSmart510:
947 reg_w(gspca_dev->dev, 0x02, 0x00, 0x00);
948 /* enable drop packet */
949 reg_w(gspca_dev->dev, 0x00, 0x850a, 0x0001);
951 err = spca50x_setup_qtable(gspca_dev,
953 0x8840, qtable_creative_pccam);
955 PDEBUG(D_ERR, "spca50x_setup_qtable failed");
956 reg_w(gspca_dev->dev, 0x00, 0x8880, 3);
957 reg_w(gspca_dev->dev, 0x00, 0x800a, 0x00);
958 /* Init SDRAM - needed for SDRAM access */
959 reg_w(gspca_dev->dev, 0x00, 0x870a, 0x04);
961 spca500_setmode(gspca_dev, xmult, ymult);
963 /* switch to video camera mode */
964 reg_w(gspca_dev->dev, 0x00, 0x8000, 0x0004);
965 reg_r_wait(gspca_dev->dev, 0, 0x8000, 0x44);
967 reg_r(gspca_dev->dev, 0x816b, &Data, 1);
968 reg_w(gspca_dev->dev, 0x00, 0x816b, Data);
969 write_vector(gspca_dev, Clicksmart510_defaults);
974 static void sd_stopN(struct gspca_dev *gspca_dev)
978 reg_w(gspca_dev->dev, 0, 0x8003, 0x00);
980 /* switch to video camera mode */
981 reg_w(gspca_dev->dev, 0x00, 0x8000, 0x0004);
982 reg_r(gspca_dev->dev, 0x8000, &data, 1);
983 PDEBUG(D_STREAM, "stop SPCA500 done reg8000: 0x%2x", data);
986 static void sd_stop0(struct gspca_dev *gspca_dev)
990 static void sd_close(struct gspca_dev *gspca_dev)
994 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
995 struct gspca_frame *frame, /* target */
996 __u8 *data, /* isoc packet */
997 int len) /* iso packet length */
999 struct sd *sd = (struct sd *) gspca_dev;
1002 static __u8 ffd9[] = {0xff, 0xd9};
1004 /* frames are jpeg 4.1.1 without 0xff escape */
1005 if (data[0] == 0xff) {
1006 if (data[1] != 0x01) { /* drop packet */
1007 /* gspca_dev->last_packet_type = DISCARD_PACKET; */
1010 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
1013 /* put the JPEG header in the new frame */
1014 jpeg_put_header(gspca_dev, frame, sd->qindex, 0x22);
1016 data += SPCA500_OFFSET_DATA;
1017 len -= SPCA500_OFFSET_DATA;
1023 /* add 0x00 after 0xff */
1024 for (i = len; --i >= 0; )
1025 if (data[i] == 0xff)
1027 if (i < 0) { /* no 0xff */
1028 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1033 for (i = 0; i < len; i++) {
1038 gspca_frame_add(gspca_dev, INTER_PACKET, frame,
1039 sd->packet, d - sd->packet);
1042 static void setbrightness(struct gspca_dev *gspca_dev)
1044 struct sd *sd = (struct sd *) gspca_dev;
1046 reg_w(gspca_dev->dev, 0x00, 0x8167,
1047 (__u8) (sd->brightness - 128));
1050 static void getbrightness(struct gspca_dev *gspca_dev)
1052 struct sd *sd = (struct sd *) gspca_dev;
1055 ret = reg_r_12(gspca_dev->dev, 0x00, 0x8167, 1);
1057 sd->brightness = ret + 128;
1060 static void setcontrast(struct gspca_dev *gspca_dev)
1062 struct sd *sd = (struct sd *) gspca_dev;
1064 reg_w(gspca_dev->dev, 0x00, 0x8168, sd->contrast);
1067 static void getcontrast(struct gspca_dev *gspca_dev)
1069 struct sd *sd = (struct sd *) gspca_dev;
1072 ret = reg_r_12(gspca_dev->dev, 0x0, 0x8168, 1);
1077 static void setcolors(struct gspca_dev *gspca_dev)
1079 struct sd *sd = (struct sd *) gspca_dev;
1081 reg_w(gspca_dev->dev, 0x00, 0x8169, sd->colors);
1084 static void getcolors(struct gspca_dev *gspca_dev)
1086 struct sd *sd = (struct sd *) gspca_dev;
1089 ret = reg_r_12(gspca_dev->dev, 0x0, 0x8169, 1);
1094 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1096 struct sd *sd = (struct sd *) gspca_dev;
1098 sd->brightness = val;
1099 if (gspca_dev->streaming)
1100 setbrightness(gspca_dev);
1104 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1106 struct sd *sd = (struct sd *) gspca_dev;
1108 getbrightness(gspca_dev);
1109 *val = sd->brightness;
1113 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1115 struct sd *sd = (struct sd *) gspca_dev;
1118 if (gspca_dev->streaming)
1119 setcontrast(gspca_dev);
1123 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1125 struct sd *sd = (struct sd *) gspca_dev;
1127 getcontrast(gspca_dev);
1128 *val = sd->contrast;
1132 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1134 struct sd *sd = (struct sd *) gspca_dev;
1137 if (gspca_dev->streaming)
1138 setcolors(gspca_dev);
1142 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1144 struct sd *sd = (struct sd *) gspca_dev;
1146 getcolors(gspca_dev);
1151 /* sub-driver description */
1152 static struct sd_desc sd_desc = {
1153 .name = MODULE_NAME,
1155 .nctrls = ARRAY_SIZE(sd_ctrls),
1156 .config = sd_config,
1162 .pkt_scan = sd_pkt_scan,
1165 /* -- module initialisation -- */
1166 #define DVNM(name) .driver_info = (kernel_ulong_t) name
1167 static const __devinitdata struct usb_device_id device_table[] = {
1168 {USB_DEVICE(0x040a, 0x0300), DVNM("Kodak EZ200")},
1169 {USB_DEVICE(0x041e, 0x400a), DVNM("Creative PC-CAM 300")},
1170 {USB_DEVICE(0x046d, 0x0890), DVNM("Logitech QuickCam traveler")},
1171 {USB_DEVICE(0x046d, 0x0900), DVNM("Logitech Inc. ClickSmart 310")},
1172 {USB_DEVICE(0x046d, 0x0901), DVNM("Logitech Inc. ClickSmart 510")},
1173 {USB_DEVICE(0x04a5, 0x300c), DVNM("Benq DC1016")},
1174 {USB_DEVICE(0x04fc, 0x7333), DVNM("PalmPixDC85")},
1175 {USB_DEVICE(0x055f, 0xc200), DVNM("Mustek Gsmart 300")},
1176 {USB_DEVICE(0x055f, 0xc220), DVNM("Gsmart Mini")},
1177 {USB_DEVICE(0x06bd, 0x0404), DVNM("Agfa CL20")},
1178 {USB_DEVICE(0x06be, 0x0800), DVNM("Optimedia")},
1179 {USB_DEVICE(0x084d, 0x0003), DVNM("D-Link DSC-350")},
1180 {USB_DEVICE(0x08ca, 0x0103), DVNM("Aiptek PocketDV")},
1181 {USB_DEVICE(0x2899, 0x012c), DVNM("Toptro Industrial")},
1182 {USB_DEVICE(0x8086, 0x0630), DVNM("Intel Pocket PC Camera")},
1185 MODULE_DEVICE_TABLE(usb, device_table);
1187 /* -- device connect -- */
1188 static int sd_probe(struct usb_interface *intf,
1189 const struct usb_device_id *id)
1191 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1195 static struct usb_driver sd_driver = {
1196 .name = MODULE_NAME,
1197 .id_table = device_table,
1199 .disconnect = gspca_disconnect,
1202 /* -- module insert / remove -- */
1203 static int __init sd_mod_init(void)
1205 if (usb_register(&sd_driver) < 0)
1207 PDEBUG(D_PROBE, "v%s registered", version);
1210 static void __exit sd_mod_exit(void)
1212 usb_deregister(&sd_driver);
1213 PDEBUG(D_PROBE, "deregistered");
1216 module_init(sd_mod_init);
1217 module_exit(sd_mod_exit);