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, 4)
28 static const char version[] = "2.1.4";
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 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 const __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},
166 static const __u16 Clicksmart510_defaults[][3] = {
167 {0x00, 0x00, 0x8211},
168 {0x00, 0x01, 0x82c0},
169 {0x00, 0x10, 0x82cb},
170 {0x00, 0x0f, 0x800d},
171 {0x00, 0x82, 0x8225},
172 {0x00, 0x21, 0x8228},
173 {0x00, 0x00, 0x8203},
174 {0x00, 0x00, 0x8204},
175 {0x00, 0x08, 0x8205},
176 {0x00, 0xf8, 0x8206},
177 {0x00, 0x28, 0x8207},
178 {0x00, 0xa0, 0x8208},
179 {0x00, 0x08, 0x824a},
180 {0x00, 0x08, 0x8214},
181 {0x00, 0x80, 0x82c1},
182 {0x00, 0x00, 0x82c2},
183 {0x00, 0x00, 0x82ca},
184 {0x00, 0x80, 0x82c1},
185 {0x00, 0x04, 0x82c2},
186 {0x00, 0x00, 0x82ca},
187 {0x00, 0xfc, 0x8100},
188 {0x00, 0xfc, 0x8105},
189 {0x00, 0x30, 0x8101},
190 {0x00, 0x00, 0x8102},
191 {0x00, 0x00, 0x8103},
192 {0x00, 0x66, 0x8107},
193 {0x00, 0x00, 0x816b},
194 {0x00, 0x00, 0x8155},
195 {0x00, 0x01, 0x8156},
196 {0x00, 0x60, 0x8157},
197 {0x00, 0x40, 0x8158},
198 {0x00, 0x0a, 0x8159},
199 {0x00, 0x06, 0x815a},
200 {0x00, 0x00, 0x813f},
201 {0x00, 0x00, 0x8200},
202 {0x00, 0x19, 0x8201},
203 {0x00, 0x00, 0x82c1},
204 {0x00, 0xa0, 0x82c2},
205 {0x00, 0x00, 0x82ca},
206 {0x00, 0x00, 0x8117},
207 {0x00, 0x00, 0x8118},
208 {0x00, 0x65, 0x8119},
209 {0x00, 0x00, 0x811a},
210 {0x00, 0x00, 0x811b},
211 {0x00, 0x55, 0x811c},
212 {0x00, 0x65, 0x811d},
213 {0x00, 0x55, 0x811e},
214 {0x00, 0x16, 0x811f},
215 {0x00, 0x19, 0x8120},
216 {0x00, 0x80, 0x8103},
217 {0x00, 0x83, 0x816b},
218 {0x00, 0x25, 0x8168},
219 {0x00, 0x01, 0x820f},
220 {0x00, 0xff, 0x8115},
221 {0x00, 0x48, 0x8116},
222 {0x00, 0x50, 0x8151},
223 {0x00, 0x40, 0x8152},
224 {0x00, 0x78, 0x8153},
225 {0x00, 0x40, 0x8154},
226 {0x00, 0x00, 0x8167},
227 {0x00, 0x20, 0x8168},
228 {0x00, 0x00, 0x816a},
229 {0x00, 0x03, 0x816b},
230 {0x00, 0x20, 0x8169},
231 {0x00, 0x60, 0x8157},
232 {0x00, 0x00, 0x8190},
233 {0x00, 0x00, 0x81a1},
234 {0x00, 0x00, 0x81b2},
235 {0x00, 0x27, 0x8191},
236 {0x00, 0x27, 0x81a2},
237 {0x00, 0x27, 0x81b3},
238 {0x00, 0x4b, 0x8192},
239 {0x00, 0x4b, 0x81a3},
240 {0x00, 0x4b, 0x81b4},
241 {0x00, 0x66, 0x8193},
242 {0x00, 0x66, 0x81a4},
243 {0x00, 0x66, 0x81b5},
244 {0x00, 0x79, 0x8194},
245 {0x00, 0x79, 0x81a5},
246 {0x00, 0x79, 0x81b6},
247 {0x00, 0x8a, 0x8195},
248 {0x00, 0x8a, 0x81a6},
249 {0x00, 0x8a, 0x81b7},
250 {0x00, 0x9b, 0x8196},
251 {0x00, 0x9b, 0x81a7},
252 {0x00, 0x9b, 0x81b8},
253 {0x00, 0xa6, 0x8197},
254 {0x00, 0xa6, 0x81a8},
255 {0x00, 0xa6, 0x81b9},
256 {0x00, 0xb2, 0x8198},
257 {0x00, 0xb2, 0x81a9},
258 {0x00, 0xb2, 0x81ba},
259 {0x00, 0xbe, 0x8199},
260 {0x00, 0xbe, 0x81aa},
261 {0x00, 0xbe, 0x81bb},
262 {0x00, 0xc8, 0x819a},
263 {0x00, 0xc8, 0x81ab},
264 {0x00, 0xc8, 0x81bc},
265 {0x00, 0xd2, 0x819b},
266 {0x00, 0xd2, 0x81ac},
267 {0x00, 0xd2, 0x81bd},
268 {0x00, 0xdb, 0x819c},
269 {0x00, 0xdb, 0x81ad},
270 {0x00, 0xdb, 0x81be},
271 {0x00, 0xe4, 0x819d},
272 {0x00, 0xe4, 0x81ae},
273 {0x00, 0xe4, 0x81bf},
274 {0x00, 0xed, 0x819e},
275 {0x00, 0xed, 0x81af},
276 {0x00, 0xed, 0x81c0},
277 {0x00, 0xf7, 0x819f},
278 {0x00, 0xf7, 0x81b0},
279 {0x00, 0xf7, 0x81c1},
280 {0x00, 0xff, 0x81a0},
281 {0x00, 0xff, 0x81b1},
282 {0x00, 0xff, 0x81c2},
283 {0x00, 0x03, 0x8156},
284 {0x00, 0x00, 0x8211},
285 {0x00, 0x20, 0x8168},
286 {0x00, 0x01, 0x8202},
287 {0x00, 0x30, 0x8101},
288 {0x00, 0x00, 0x8111},
289 {0x00, 0x00, 0x8112},
290 {0x00, 0x00, 0x8113},
291 {0x00, 0x00, 0x8114},
295 static const __u8 qtable_creative_pccam[2][64] = {
296 { /* Q-table Y-components */
297 0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12,
298 0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11,
299 0x04, 0x04, 0x05, 0x07, 0x0c, 0x11, 0x15, 0x11,
300 0x04, 0x05, 0x07, 0x09, 0x0f, 0x1a, 0x18, 0x13,
301 0x05, 0x07, 0x0b, 0x11, 0x14, 0x21, 0x1f, 0x17,
302 0x07, 0x0b, 0x11, 0x13, 0x18, 0x1f, 0x22, 0x1c,
303 0x0f, 0x13, 0x17, 0x1a, 0x1f, 0x24, 0x24, 0x1e,
304 0x16, 0x1c, 0x1d, 0x1d, 0x22, 0x1e, 0x1f, 0x1e},
305 { /* Q-table C-components */
306 0x05, 0x05, 0x07, 0x0e, 0x1e, 0x1e, 0x1e, 0x1e,
307 0x05, 0x06, 0x08, 0x14, 0x1e, 0x1e, 0x1e, 0x1e,
308 0x07, 0x08, 0x11, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
309 0x0e, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
310 0x1e, 0x1e, 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}
316 static const __u8 qtable_kodak_ez200[2][64] = {
317 { /* Q-table Y-components */
318 0x02, 0x01, 0x01, 0x02, 0x02, 0x04, 0x05, 0x06,
319 0x01, 0x01, 0x01, 0x02, 0x03, 0x06, 0x06, 0x06,
320 0x01, 0x01, 0x02, 0x02, 0x04, 0x06, 0x07, 0x06,
321 0x01, 0x02, 0x02, 0x03, 0x05, 0x09, 0x08, 0x06,
322 0x02, 0x02, 0x04, 0x06, 0x07, 0x0b, 0x0a, 0x08,
323 0x02, 0x04, 0x06, 0x06, 0x08, 0x0a, 0x0b, 0x09,
324 0x05, 0x06, 0x08, 0x09, 0x0a, 0x0c, 0x0c, 0x0a,
325 0x07, 0x09, 0x0a, 0x0a, 0x0b, 0x0a, 0x0a, 0x0a},
326 { /* Q-table C-components */
327 0x02, 0x02, 0x02, 0x05, 0x0a, 0x0a, 0x0a, 0x0a,
328 0x02, 0x02, 0x03, 0x07, 0x0a, 0x0a, 0x0a, 0x0a,
329 0x02, 0x03, 0x06, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
330 0x05, 0x07, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
331 0x0a, 0x0a, 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}
337 static const __u8 qtable_pocketdv[2][64] = {
338 { /* Q-table Y-components start registers 0x8800 */
339 0x06, 0x04, 0x04, 0x06, 0x0a, 0x10, 0x14, 0x18,
340 0x05, 0x05, 0x06, 0x08, 0x0a, 0x17, 0x18, 0x16,
341 0x06, 0x05, 0x06, 0x0a, 0x10, 0x17, 0x1c, 0x16,
342 0x06, 0x07, 0x09, 0x0c, 0x14, 0x23, 0x20, 0x19,
343 0x07, 0x09, 0x0f, 0x16, 0x1b, 0x2c, 0x29, 0x1f,
344 0x0a, 0x0e, 0x16, 0x1a, 0x20, 0x2a, 0x2d, 0x25,
345 0x14, 0x1a, 0x1f, 0x23, 0x29, 0x30, 0x30, 0x28,
346 0x1d, 0x25, 0x26, 0x27, 0x2d, 0x28, 0x29, 0x28,
348 { /* Q-table C-components start registers 0x8840 */
349 0x07, 0x07, 0x0a, 0x13, 0x28, 0x28, 0x28, 0x28,
350 0x07, 0x08, 0x0a, 0x1a, 0x28, 0x28, 0x28, 0x28,
351 0x0a, 0x0a, 0x16, 0x28, 0x28, 0x28, 0x28, 0x28,
352 0x13, 0x1a, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
353 0x28, 0x28, 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}
359 static void reg_r(struct usb_device *dev,
361 __u8 *buffer, __u16 length)
364 usb_rcvctrlpipe(dev, 0),
366 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
368 index, buffer, length, 500);
371 static int reg_w(struct usb_device *dev,
372 __u16 req, __u16 index, __u16 value)
376 PDEBUG(D_USBO, "reg write: [0x%02x] = 0x%02x", index, 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);
383 PDEBUG(D_ERR, "reg write: error %d", ret);
387 /* returns: negative is error, pos or zero is data */
388 static int reg_r_12(struct usb_device *dev,
389 __u16 req, /* bRequest */
390 __u16 index, /* wIndex */
391 __u16 length) /* wLength (1 or 2 only) */
397 ret = usb_control_msg(dev,
398 usb_rcvctrlpipe(dev, 0),
400 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
406 PDEBUG(D_ERR, "reg_r_12 err %d", ret);
409 return (buf[1] << 8) + buf[0];
413 * Simple function to wait for a given 8-bit value to be returned from
415 * Returns: negative is error or timeout, zero is success.
417 static int reg_r_wait(struct usb_device *dev,
418 __u16 reg, __u16 index, __u16 value)
423 ret = reg_r_12(dev, reg, index, 1);
431 static int write_vector(struct gspca_dev *gspca_dev,
432 const __u16 data[][3])
434 struct usb_device *dev = gspca_dev->dev;
437 while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) {
438 ret = reg_w(dev, data[i][0], data[i][2], data[i][1]);
446 static int spca50x_setup_qtable(struct gspca_dev *gspca_dev,
447 unsigned int request,
450 const __u8 qtable[2][64])
452 struct usb_device *dev = gspca_dev->dev;
455 /* loop over y components */
456 for (i = 0; i < 64; i++) {
457 err = reg_w(dev, request, ybase + i, qtable[0][i]);
462 /* loop over c components */
463 for (i = 0; i < 64; i++) {
464 err = reg_w(dev, request, cbase + i, qtable[1][i]);
471 static void spca500_ping310(struct gspca_dev *gspca_dev)
475 reg_r(gspca_dev->dev, 0x0d04, Data, 2);
476 PDEBUG(D_STREAM, "ClickSmart310 ping 0x0d04 0x%02x 0x%02x",
480 static void spca500_clksmart310_init(struct gspca_dev *gspca_dev)
484 reg_r(gspca_dev->dev, 0x0d05, Data, 2);
485 PDEBUG(D_STREAM, "ClickSmart310 init 0x0d05 0x%02x 0x%02x",
487 reg_w(gspca_dev->dev, 0x00, 0x8167, 0x5a);
488 spca500_ping310(gspca_dev);
490 reg_w(gspca_dev->dev, 0x00, 0x8168, 0x22);
491 reg_w(gspca_dev->dev, 0x00, 0x816a, 0xc0);
492 reg_w(gspca_dev->dev, 0x00, 0x816b, 0x0b);
493 reg_w(gspca_dev->dev, 0x00, 0x8169, 0x25);
494 reg_w(gspca_dev->dev, 0x00, 0x8157, 0x5b);
495 reg_w(gspca_dev->dev, 0x00, 0x8158, 0x5b);
496 reg_w(gspca_dev->dev, 0x00, 0x813f, 0x03);
497 reg_w(gspca_dev->dev, 0x00, 0x8151, 0x4a);
498 reg_w(gspca_dev->dev, 0x00, 0x8153, 0x78);
499 reg_w(gspca_dev->dev, 0x00, 0x0d01, 0x04);
500 /* 00 for adjust shutter */
501 reg_w(gspca_dev->dev, 0x00, 0x0d02, 0x01);
502 reg_w(gspca_dev->dev, 0x00, 0x8169, 0x25);
503 reg_w(gspca_dev->dev, 0x00, 0x0d01, 0x02);
506 static void spca500_setmode(struct gspca_dev *gspca_dev,
507 __u8 xmult, __u8 ymult)
511 /* set x multiplier */
512 reg_w(gspca_dev->dev, 0, 0x8001, xmult);
514 /* set y multiplier */
515 reg_w(gspca_dev->dev, 0, 0x8002, ymult);
517 /* use compressed mode, VGA, with mode specific subsample */
518 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode;
519 reg_w(gspca_dev->dev, 0, 0x8003, mode << 4);
522 static int spca500_full_reset(struct gspca_dev *gspca_dev)
526 /* send the reset command */
527 err = reg_w(gspca_dev->dev, 0xe0, 0x0001, 0x0000);
531 /* wait for the reset to complete */
532 err = reg_r_wait(gspca_dev->dev, 0x06, 0x0000, 0x0000);
535 err = reg_w(gspca_dev->dev, 0xe0, 0x0000, 0x0000);
538 err = reg_r_wait(gspca_dev->dev, 0x06, 0, 0);
540 PDEBUG(D_ERR, "reg_r_wait() failed");
547 /* Synchro the Bridge with sensor */
548 /* Maybe that will work on all spca500 chip */
549 /* because i only own a clicksmart310 try for that chip */
550 /* using spca50x_set_packet_size() cause an Ooops here */
551 /* usb_set_interface from kernel 2.6.x clear all the urb stuff */
552 /* up-port the same feature as in 2.4.x kernel */
553 static int spca500_synch310(struct gspca_dev *gspca_dev)
557 if (usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0) < 0) {
558 PDEBUG(D_ERR, "Set packet size: set interface error");
561 spca500_ping310(gspca_dev);
563 reg_r(gspca_dev->dev, 0x0d00, &Data, 1);
565 /* need alt setting here */
566 PDEBUG(D_PACK, "ClickSmart310 sync alt: %d", gspca_dev->alt);
568 /* Windoze use pipe with altsetting 6 why 7 here */
569 if (usb_set_interface(gspca_dev->dev,
571 gspca_dev->alt) < 0) {
572 PDEBUG(D_ERR, "Set packet size: set interface error");
580 static void spca500_reinit(struct gspca_dev *gspca_dev)
585 /* some unknow command from Aiptek pocket dv and family300 */
587 reg_w(gspca_dev->dev, 0x00, 0x0d01, 0x01);
588 reg_w(gspca_dev->dev, 0x00, 0x0d03, 0x00);
589 reg_w(gspca_dev->dev, 0x00, 0x0d02, 0x01);
591 /* enable drop packet */
592 reg_w(gspca_dev->dev, 0x00, 0x850a, 0x0001);
594 err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840,
597 PDEBUG(D_ERR|D_STREAM, "spca50x_setup_qtable failed on init");
599 /* set qtable index */
600 reg_w(gspca_dev->dev, 0x00, 0x8880, 2);
601 /* family cam Quicksmart stuff */
602 reg_w(gspca_dev->dev, 0x00, 0x800a, 0x00);
603 /* Set agc transfer: synced inbetween frames */
604 reg_w(gspca_dev->dev, 0x00, 0x820f, 0x01);
605 /* Init SDRAM - needed for SDRAM access */
606 reg_w(gspca_dev->dev, 0x00, 0x870a, 0x04);
607 /*Start init sequence or stream */
609 reg_w(gspca_dev->dev, 0, 0x8003, 0x00);
610 /* switch to video camera mode */
611 reg_w(gspca_dev->dev, 0x00, 0x8000, 0x0004);
613 if (reg_r_wait(gspca_dev->dev, 0, 0x8000, 0x44) != 0)
614 reg_r(gspca_dev->dev, 0x816b, &Data, 1);
615 reg_w(gspca_dev->dev, 0x00, 0x816b, Data);
618 /* this function is called at probe time */
619 static int sd_config(struct gspca_dev *gspca_dev,
620 const struct usb_device_id *id)
622 struct sd *sd = (struct sd *) gspca_dev;
627 vendor = id->idVendor;
628 product = id->idProduct;
630 case 0x040a: /* Kodak cameras */
631 /* switch (product) { */
633 sd->subtype = KodakEZ200;
637 case 0x041e: /* Creative cameras */
638 /* switch (product) { */
640 sd->subtype = CreativePCCam300;
644 case 0x046d: /* Logitech Labtec */
647 sd->subtype = LogitechTraveler;
650 sd->subtype = LogitechClickSmart310;
653 sd->subtype = LogitechClickSmart510;
657 case 0x04a5: /* Benq */
658 /* switch (product) { */
660 sd->subtype = BenqDC1016;
664 case 0x04fc: /* SunPlus */
665 /* switch (product) { */
667 sd->subtype = PalmPixDC85;
671 case 0x055f: /* Mustek cameras */
674 sd->subtype = MustekGsmart300;
677 sd->subtype = Gsmartmini;
681 case 0x06bd: /* Agfa Cl20 */
682 /* switch (product) { */
684 sd->subtype = AgfaCl20;
688 case 0x06be: /* Optimedia */
689 /* switch (product) { */
691 sd->subtype = Optimedia;
695 case 0x084d: /* D-Link / Minton */
696 /* switch (product) { */
697 /* case 0x0003: * DSC-350 / S-Cam F5 */
698 sd->subtype = DLinkDSC350;
702 case 0x08ca: /* Aiptek */
703 /* switch (product) { */
705 sd->subtype = AiptekPocketDV;
709 case 0x2899: /* ToptroIndustrial */
710 /* switch (product) { */
712 sd->subtype = ToptroIndus;
716 case 0x8086: /* Intel */
717 /* switch (product) { */
718 /* case 0x0630: * Pocket PC Camera */
719 sd->subtype = IntelPocketPCCamera;
724 cam = &gspca_dev->cam;
725 cam->dev_name = (char *) id->driver_info;
727 if (sd->subtype != LogitechClickSmart310) {
728 cam->cam_mode = vga_mode;
729 cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
731 cam->cam_mode = sif_mode;
732 cam->nmodes = sizeof sif_mode / sizeof sif_mode[0];
735 sd->brightness = BRIGHTNESS_DEF;
736 sd->contrast = CONTRAST_DEF;
737 sd->colors = COLOR_DEF;
741 /* this function is called at open time */
742 static int sd_open(struct gspca_dev *gspca_dev)
744 struct sd *sd = (struct sd *) gspca_dev;
746 /* initialisation of spca500 based cameras is deferred */
747 PDEBUG(D_STREAM, "SPCA500 init");
748 if (sd->subtype == LogitechClickSmart310)
749 spca500_clksmart310_init(gspca_dev);
751 spca500_initialise(gspca_dev); */
752 PDEBUG(D_STREAM, "SPCA500 init done");
756 static void sd_start(struct gspca_dev *gspca_dev)
758 struct sd *sd = (struct sd *) gspca_dev;
763 if (sd->subtype == LogitechClickSmart310) {
771 /* is there a sensor here ? */
772 reg_r(gspca_dev->dev, 0x8a04, &Data, 1);
773 PDEBUG(D_STREAM, "Spca500 Sensor Address 0x%02X", Data);
774 PDEBUG(D_STREAM, "Spca500 curr_mode: %d Xmult: 0x%02X, Ymult: 0x%02X",
775 gspca_dev->curr_mode, xmult, ymult);
778 switch (sd->subtype) {
779 case LogitechClickSmart310:
780 spca500_setmode(gspca_dev, xmult, ymult);
782 /* enable drop packet */
783 reg_w(gspca_dev->dev, 0x00, 0x850a, 0x0001);
784 reg_w(gspca_dev->dev, 0x00, 0x8880, 3);
785 err = spca50x_setup_qtable(gspca_dev,
786 0x00, 0x8800, 0x8840,
787 qtable_creative_pccam);
789 PDEBUG(D_ERR, "spca50x_setup_qtable failed");
790 /* Init SDRAM - needed for SDRAM access */
791 reg_w(gspca_dev->dev, 0x00, 0x870a, 0x04);
793 /* switch to video camera mode */
794 reg_w(gspca_dev->dev, 0x00, 0x8000, 0x0004);
796 if (reg_r_wait(gspca_dev->dev, 0, 0x8000, 0x44) != 0)
797 PDEBUG(D_ERR, "reg_r_wait() failed");
799 reg_r(gspca_dev->dev, 0x816b, &Data, 1);
800 reg_w(gspca_dev->dev, 0x00, 0x816b, Data);
802 spca500_synch310(gspca_dev);
804 write_vector(gspca_dev, spca500_visual_defaults);
805 spca500_setmode(gspca_dev, xmult, ymult);
806 /* enable drop packet */
807 reg_w(gspca_dev->dev, 0x00, 0x850a, 0x0001);
808 PDEBUG(D_ERR, "failed to enable drop packet");
809 reg_w(gspca_dev->dev, 0x00, 0x8880, 3);
810 err = spca50x_setup_qtable(gspca_dev,
811 0x00, 0x8800, 0x8840,
812 qtable_creative_pccam);
814 PDEBUG(D_ERR, "spca50x_setup_qtable failed");
816 /* Init SDRAM - needed for SDRAM access */
817 reg_w(gspca_dev->dev, 0x00, 0x870a, 0x04);
819 /* switch to video camera mode */
820 reg_w(gspca_dev->dev, 0x00, 0x8000, 0x0004);
822 if (reg_r_wait(gspca_dev->dev, 0, 0x8000, 0x44) != 0)
823 PDEBUG(D_ERR, "reg_r_wait() failed");
825 reg_r(gspca_dev->dev, 0x816b, &Data, 1);
826 reg_w(gspca_dev->dev, 0x00, 0x816b, Data);
828 case CreativePCCam300: /* Creative PC-CAM 300 640x480 CCD */
829 case IntelPocketPCCamera: /* FIXME: Temporary fix for
830 * Intel Pocket PC Camera
831 * - NWG (Sat 29th March 2003) */
833 /* do a full reset */
834 err = spca500_full_reset(gspca_dev);
836 PDEBUG(D_ERR, "spca500_full_reset failed");
838 /* enable drop packet */
839 err = reg_w(gspca_dev->dev, 0x00, 0x850a, 0x0001);
841 PDEBUG(D_ERR, "failed to enable drop packet");
842 reg_w(gspca_dev->dev, 0x00, 0x8880, 3);
843 err = spca50x_setup_qtable(gspca_dev,
844 0x00, 0x8800, 0x8840,
845 qtable_creative_pccam);
847 PDEBUG(D_ERR, "spca50x_setup_qtable failed");
849 spca500_setmode(gspca_dev, xmult, ymult);
850 reg_w(gspca_dev->dev, 0x20, 0x0001, 0x0004);
852 /* switch to video camera mode */
853 reg_w(gspca_dev->dev, 0x00, 0x8000, 0x0004);
855 if (reg_r_wait(gspca_dev->dev, 0, 0x8000, 0x44) != 0)
856 PDEBUG(D_ERR, "reg_r_wait() failed");
858 reg_r(gspca_dev->dev, 0x816b, &Data, 1);
859 reg_w(gspca_dev->dev, 0x00, 0x816b, Data);
861 /* write_vector(gspca_dev, spca500_visual_defaults); */
863 case KodakEZ200: /* Kodak EZ200 */
865 /* do a full reset */
866 err = spca500_full_reset(gspca_dev);
868 PDEBUG(D_ERR, "spca500_full_reset failed");
869 /* enable drop packet */
870 reg_w(gspca_dev->dev, 0x00, 0x850a, 0x0001);
871 reg_w(gspca_dev->dev, 0x00, 0x8880, 0);
872 err = spca50x_setup_qtable(gspca_dev,
873 0x00, 0x8800, 0x8840,
876 PDEBUG(D_ERR, "spca50x_setup_qtable failed");
877 spca500_setmode(gspca_dev, xmult, ymult);
879 reg_w(gspca_dev->dev, 0x20, 0x0001, 0x0004);
881 /* switch to video camera mode */
882 reg_w(gspca_dev->dev, 0x00, 0x8000, 0x0004);
884 if (reg_r_wait(gspca_dev->dev, 0, 0x8000, 0x44) != 0)
885 PDEBUG(D_ERR, "reg_r_wait() failed");
887 reg_r(gspca_dev->dev, 0x816b, &Data, 1);
888 reg_w(gspca_dev->dev, 0x00, 0x816b, Data);
890 /* write_vector(gspca_dev, spca500_visual_defaults); */
894 case DLinkDSC350: /* FamilyCam 300 */
895 case AiptekPocketDV: /* Aiptek PocketDV */
896 case Gsmartmini: /*Mustek Gsmart Mini */
897 case MustekGsmart300: /* Mustek Gsmart 300 */
902 spca500_reinit(gspca_dev);
903 reg_w(gspca_dev->dev, 0x00, 0x0d01, 0x01);
904 /* enable drop packet */
905 reg_w(gspca_dev->dev, 0x00, 0x850a, 0x0001);
907 err = spca50x_setup_qtable(gspca_dev,
908 0x00, 0x8800, 0x8840, qtable_pocketdv);
910 PDEBUG(D_ERR, "spca50x_setup_qtable failed");
911 reg_w(gspca_dev->dev, 0x00, 0x8880, 2);
913 /* familycam Quicksmart pocketDV stuff */
914 reg_w(gspca_dev->dev, 0x00, 0x800a, 0x00);
915 /* Set agc transfer: synced inbetween frames */
916 reg_w(gspca_dev->dev, 0x00, 0x820f, 0x01);
917 /* Init SDRAM - needed for SDRAM access */
918 reg_w(gspca_dev->dev, 0x00, 0x870a, 0x04);
920 spca500_setmode(gspca_dev, xmult, ymult);
921 /* switch to video camera mode */
922 reg_w(gspca_dev->dev, 0x00, 0x8000, 0x0004);
924 reg_r_wait(gspca_dev->dev, 0, 0x8000, 0x44);
926 reg_r(gspca_dev->dev, 0x816b, &Data, 1);
927 reg_w(gspca_dev->dev, 0x00, 0x816b, Data);
929 case LogitechTraveler:
930 case LogitechClickSmart510:
931 reg_w(gspca_dev->dev, 0x02, 0x00, 0x00);
932 /* enable drop packet */
933 reg_w(gspca_dev->dev, 0x00, 0x850a, 0x0001);
935 err = spca50x_setup_qtable(gspca_dev,
937 0x8840, qtable_creative_pccam);
939 PDEBUG(D_ERR, "spca50x_setup_qtable failed");
940 reg_w(gspca_dev->dev, 0x00, 0x8880, 3);
941 reg_w(gspca_dev->dev, 0x00, 0x800a, 0x00);
942 /* Init SDRAM - needed for SDRAM access */
943 reg_w(gspca_dev->dev, 0x00, 0x870a, 0x04);
945 spca500_setmode(gspca_dev, xmult, ymult);
947 /* switch to video camera mode */
948 reg_w(gspca_dev->dev, 0x00, 0x8000, 0x0004);
949 reg_r_wait(gspca_dev->dev, 0, 0x8000, 0x44);
951 reg_r(gspca_dev->dev, 0x816b, &Data, 1);
952 reg_w(gspca_dev->dev, 0x00, 0x816b, Data);
953 write_vector(gspca_dev, Clicksmart510_defaults);
958 static void sd_stopN(struct gspca_dev *gspca_dev)
962 reg_w(gspca_dev->dev, 0, 0x8003, 0x00);
964 /* switch to video camera mode */
965 reg_w(gspca_dev->dev, 0x00, 0x8000, 0x0004);
966 reg_r(gspca_dev->dev, 0x8000, &data, 1);
967 PDEBUG(D_STREAM, "stop SPCA500 done reg8000: 0x%2x", data);
970 static void sd_stop0(struct gspca_dev *gspca_dev)
974 static void sd_close(struct gspca_dev *gspca_dev)
978 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
979 struct gspca_frame *frame, /* target */
980 __u8 *data, /* isoc packet */
981 int len) /* iso packet length */
983 struct sd *sd = (struct sd *) gspca_dev;
986 static __u8 ffd9[] = {0xff, 0xd9};
988 /* frames are jpeg 4.1.1 without 0xff escape */
989 if (data[0] == 0xff) {
990 if (data[1] != 0x01) { /* drop packet */
991 /* gspca_dev->last_packet_type = DISCARD_PACKET; */
994 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
997 /* put the JPEG header in the new frame */
998 jpeg_put_header(gspca_dev, frame, sd->qindex, 0x22);
1000 data += SPCA500_OFFSET_DATA;
1001 len -= SPCA500_OFFSET_DATA;
1007 /* add 0x00 after 0xff */
1008 for (i = len; --i >= 0; )
1009 if (data[i] == 0xff)
1011 if (i < 0) { /* no 0xff */
1012 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1017 for (i = 0; i < len; i++) {
1022 gspca_frame_add(gspca_dev, INTER_PACKET, frame,
1023 sd->packet, d - sd->packet);
1026 static void setbrightness(struct gspca_dev *gspca_dev)
1028 struct sd *sd = (struct sd *) gspca_dev;
1030 reg_w(gspca_dev->dev, 0x00, 0x8167,
1031 (__u8) (sd->brightness - 128));
1034 static void getbrightness(struct gspca_dev *gspca_dev)
1036 struct sd *sd = (struct sd *) gspca_dev;
1039 ret = reg_r_12(gspca_dev->dev, 0x00, 0x8167, 1);
1041 sd->brightness = ret + 128;
1044 static void setcontrast(struct gspca_dev *gspca_dev)
1046 struct sd *sd = (struct sd *) gspca_dev;
1048 reg_w(gspca_dev->dev, 0x00, 0x8168, sd->contrast);
1051 static void getcontrast(struct gspca_dev *gspca_dev)
1053 struct sd *sd = (struct sd *) gspca_dev;
1056 ret = reg_r_12(gspca_dev->dev, 0x0, 0x8168, 1);
1061 static void setcolors(struct gspca_dev *gspca_dev)
1063 struct sd *sd = (struct sd *) gspca_dev;
1065 reg_w(gspca_dev->dev, 0x00, 0x8169, sd->colors);
1068 static void getcolors(struct gspca_dev *gspca_dev)
1070 struct sd *sd = (struct sd *) gspca_dev;
1073 ret = reg_r_12(gspca_dev->dev, 0x0, 0x8169, 1);
1078 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1080 struct sd *sd = (struct sd *) gspca_dev;
1082 sd->brightness = val;
1083 if (gspca_dev->streaming)
1084 setbrightness(gspca_dev);
1088 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1090 struct sd *sd = (struct sd *) gspca_dev;
1092 getbrightness(gspca_dev);
1093 *val = sd->brightness;
1097 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1099 struct sd *sd = (struct sd *) gspca_dev;
1102 if (gspca_dev->streaming)
1103 setcontrast(gspca_dev);
1107 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1109 struct sd *sd = (struct sd *) gspca_dev;
1111 getcontrast(gspca_dev);
1112 *val = sd->contrast;
1116 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1118 struct sd *sd = (struct sd *) gspca_dev;
1121 if (gspca_dev->streaming)
1122 setcolors(gspca_dev);
1126 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1128 struct sd *sd = (struct sd *) gspca_dev;
1130 getcolors(gspca_dev);
1135 /* sub-driver description */
1136 static struct sd_desc sd_desc = {
1137 .name = MODULE_NAME,
1139 .nctrls = ARRAY_SIZE(sd_ctrls),
1140 .config = sd_config,
1146 .pkt_scan = sd_pkt_scan,
1149 /* -- module initialisation -- */
1150 #define DVNM(name) .driver_info = (kernel_ulong_t) name
1151 static const __devinitdata struct usb_device_id device_table[] = {
1152 {USB_DEVICE(0x040a, 0x0300), DVNM("Kodak EZ200")},
1153 {USB_DEVICE(0x041e, 0x400a), DVNM("Creative PC-CAM 300")},
1154 {USB_DEVICE(0x046d, 0x0890), DVNM("Logitech QuickCam traveler")},
1155 {USB_DEVICE(0x046d, 0x0900), DVNM("Logitech Inc. ClickSmart 310")},
1156 {USB_DEVICE(0x046d, 0x0901), DVNM("Logitech Inc. ClickSmart 510")},
1157 {USB_DEVICE(0x04a5, 0x300c), DVNM("Benq DC1016")},
1158 {USB_DEVICE(0x04fc, 0x7333), DVNM("PalmPixDC85")},
1159 {USB_DEVICE(0x055f, 0xc200), DVNM("Mustek Gsmart 300")},
1160 {USB_DEVICE(0x055f, 0xc220), DVNM("Gsmart Mini")},
1161 {USB_DEVICE(0x06bd, 0x0404), DVNM("Agfa CL20")},
1162 {USB_DEVICE(0x06be, 0x0800), DVNM("Optimedia")},
1163 {USB_DEVICE(0x084d, 0x0003), DVNM("D-Link DSC-350")},
1164 {USB_DEVICE(0x08ca, 0x0103), DVNM("Aiptek PocketDV")},
1165 {USB_DEVICE(0x2899, 0x012c), DVNM("Toptro Industrial")},
1166 {USB_DEVICE(0x8086, 0x0630), DVNM("Intel Pocket PC Camera")},
1169 MODULE_DEVICE_TABLE(usb, device_table);
1171 /* -- device connect -- */
1172 static int sd_probe(struct usb_interface *intf,
1173 const struct usb_device_id *id)
1175 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1179 static struct usb_driver sd_driver = {
1180 .name = MODULE_NAME,
1181 .id_table = device_table,
1183 .disconnect = gspca_disconnect,
1186 /* -- module insert / remove -- */
1187 static int __init sd_mod_init(void)
1189 if (usb_register(&sd_driver) < 0)
1191 PDEBUG(D_PROBE, "v%s registered", version);
1194 static void __exit sd_mod_exit(void)
1196 usb_deregister(&sd_driver);
1197 PDEBUG(D_PROBE, "deregistered");
1200 module_init(sd_mod_init);
1201 module_exit(sd_mod_exit);