V4L/DVB (10363): gspca - spca500: Abnormal error message when starting ClickSmart310.
[linux-2.6/mini2440.git] / drivers / media / video / gspca / spca500.c
blobf44613095d2e31fb17a6e09bc35a4b455c93f9f4
1 /*
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
9 * any later version.
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"
24 #include "gspca.h"
25 #define QUANT_VAL 5 /* quantization table */
26 #include "jpeg.h"
28 MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
29 MODULE_DESCRIPTION("GSPCA/SPCA500 USB Camera Driver");
30 MODULE_LICENSE("GPL");
32 /* specific webcam descriptor */
33 struct sd {
34 struct gspca_dev gspca_dev; /* !! must be the first item */
36 __u8 packet[ISO_MAX_SIZE + 128];
37 /* !! no more than 128 ff in an ISO packet */
39 unsigned char brightness;
40 unsigned char contrast;
41 unsigned char colors;
43 char subtype;
44 #define AgfaCl20 0
45 #define AiptekPocketDV 1
46 #define BenqDC1016 2
47 #define CreativePCCam300 3
48 #define DLinkDSC350 4
49 #define Gsmartmini 5
50 #define IntelPocketPCCamera 6
51 #define KodakEZ200 7
52 #define LogitechClickSmart310 8
53 #define LogitechClickSmart510 9
54 #define LogitechTraveler 10
55 #define MustekGsmart300 11
56 #define Optimedia 12
57 #define PalmPixDC85 13
58 #define ToptroIndus 14
61 /* V4L2 controls supported by the driver */
62 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
63 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
64 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
65 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
66 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
67 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
69 static struct ctrl sd_ctrls[] = {
72 .id = V4L2_CID_BRIGHTNESS,
73 .type = V4L2_CTRL_TYPE_INTEGER,
74 .name = "Brightness",
75 .minimum = 0,
76 .maximum = 255,
77 .step = 1,
78 #define BRIGHTNESS_DEF 127
79 .default_value = BRIGHTNESS_DEF,
81 .set = sd_setbrightness,
82 .get = sd_getbrightness,
86 .id = V4L2_CID_CONTRAST,
87 .type = V4L2_CTRL_TYPE_INTEGER,
88 .name = "Contrast",
89 .minimum = 0,
90 .maximum = 63,
91 .step = 1,
92 #define CONTRAST_DEF 31
93 .default_value = CONTRAST_DEF,
95 .set = sd_setcontrast,
96 .get = sd_getcontrast,
100 .id = V4L2_CID_SATURATION,
101 .type = V4L2_CTRL_TYPE_INTEGER,
102 .name = "Color",
103 .minimum = 0,
104 .maximum = 63,
105 .step = 1,
106 #define COLOR_DEF 31
107 .default_value = COLOR_DEF,
109 .set = sd_setcolors,
110 .get = sd_getcolors,
114 static const struct v4l2_pix_format vga_mode[] = {
115 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
116 .bytesperline = 320,
117 .sizeimage = 320 * 240 * 3 / 8 + 590,
118 .colorspace = V4L2_COLORSPACE_JPEG,
119 .priv = 1},
120 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
121 .bytesperline = 640,
122 .sizeimage = 640 * 480 * 3 / 8 + 590,
123 .colorspace = V4L2_COLORSPACE_JPEG,
124 .priv = 0},
127 static const struct v4l2_pix_format sif_mode[] = {
128 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
129 .bytesperline = 176,
130 .sizeimage = 176 * 144 * 3 / 8 + 590,
131 .colorspace = V4L2_COLORSPACE_JPEG,
132 .priv = 1},
133 {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
134 .bytesperline = 352,
135 .sizeimage = 352 * 288 * 3 / 8 + 590,
136 .colorspace = V4L2_COLORSPACE_JPEG,
137 .priv = 0},
140 /* Frame packet header offsets for the spca500 */
141 #define SPCA500_OFFSET_PADDINGLB 2
142 #define SPCA500_OFFSET_PADDINGHB 3
143 #define SPCA500_OFFSET_MODE 4
144 #define SPCA500_OFFSET_IMGWIDTH 5
145 #define SPCA500_OFFSET_IMGHEIGHT 6
146 #define SPCA500_OFFSET_IMGMODE 7
147 #define SPCA500_OFFSET_QTBLINDEX 8
148 #define SPCA500_OFFSET_FRAMSEQ 9
149 #define SPCA500_OFFSET_CDSPINFO 10
150 #define SPCA500_OFFSET_GPIO 11
151 #define SPCA500_OFFSET_AUGPIO 12
152 #define SPCA500_OFFSET_DATA 16
155 static const __u16 spca500_visual_defaults[][3] = {
156 {0x00, 0x0003, 0x816b}, /* SSI not active sync with vsync,
157 * hue (H byte) = 0,
158 * saturation/hue enable,
159 * brightness/contrast enable.
161 {0x00, 0x0000, 0x8167}, /* brightness = 0 */
162 {0x00, 0x0020, 0x8168}, /* contrast = 0 */
163 {0x00, 0x0003, 0x816b}, /* SSI not active sync with vsync,
164 * hue (H byte) = 0, saturation/hue enable,
165 * brightness/contrast enable.
166 * was 0x0003, now 0x0000.
168 {0x00, 0x0000, 0x816a}, /* hue (L byte) = 0 */
169 {0x00, 0x0020, 0x8169}, /* saturation = 0x20 */
170 {0x00, 0x0050, 0x8157}, /* edge gain high threshold */
171 {0x00, 0x0030, 0x8158}, /* edge gain low threshold */
172 {0x00, 0x0028, 0x8159}, /* edge bandwidth high threshold */
173 {0x00, 0x000a, 0x815a}, /* edge bandwidth low threshold */
174 {0x00, 0x0001, 0x8202}, /* clock rate compensation = 1/25 sec/frame */
175 {0x0c, 0x0004, 0x0000},
176 /* set interface */
179 static const __u16 Clicksmart510_defaults[][3] = {
180 {0x00, 0x00, 0x8211},
181 {0x00, 0x01, 0x82c0},
182 {0x00, 0x10, 0x82cb},
183 {0x00, 0x0f, 0x800d},
184 {0x00, 0x82, 0x8225},
185 {0x00, 0x21, 0x8228},
186 {0x00, 0x00, 0x8203},
187 {0x00, 0x00, 0x8204},
188 {0x00, 0x08, 0x8205},
189 {0x00, 0xf8, 0x8206},
190 {0x00, 0x28, 0x8207},
191 {0x00, 0xa0, 0x8208},
192 {0x00, 0x08, 0x824a},
193 {0x00, 0x08, 0x8214},
194 {0x00, 0x80, 0x82c1},
195 {0x00, 0x00, 0x82c2},
196 {0x00, 0x00, 0x82ca},
197 {0x00, 0x80, 0x82c1},
198 {0x00, 0x04, 0x82c2},
199 {0x00, 0x00, 0x82ca},
200 {0x00, 0xfc, 0x8100},
201 {0x00, 0xfc, 0x8105},
202 {0x00, 0x30, 0x8101},
203 {0x00, 0x00, 0x8102},
204 {0x00, 0x00, 0x8103},
205 {0x00, 0x66, 0x8107},
206 {0x00, 0x00, 0x816b},
207 {0x00, 0x00, 0x8155},
208 {0x00, 0x01, 0x8156},
209 {0x00, 0x60, 0x8157},
210 {0x00, 0x40, 0x8158},
211 {0x00, 0x0a, 0x8159},
212 {0x00, 0x06, 0x815a},
213 {0x00, 0x00, 0x813f},
214 {0x00, 0x00, 0x8200},
215 {0x00, 0x19, 0x8201},
216 {0x00, 0x00, 0x82c1},
217 {0x00, 0xa0, 0x82c2},
218 {0x00, 0x00, 0x82ca},
219 {0x00, 0x00, 0x8117},
220 {0x00, 0x00, 0x8118},
221 {0x00, 0x65, 0x8119},
222 {0x00, 0x00, 0x811a},
223 {0x00, 0x00, 0x811b},
224 {0x00, 0x55, 0x811c},
225 {0x00, 0x65, 0x811d},
226 {0x00, 0x55, 0x811e},
227 {0x00, 0x16, 0x811f},
228 {0x00, 0x19, 0x8120},
229 {0x00, 0x80, 0x8103},
230 {0x00, 0x83, 0x816b},
231 {0x00, 0x25, 0x8168},
232 {0x00, 0x01, 0x820f},
233 {0x00, 0xff, 0x8115},
234 {0x00, 0x48, 0x8116},
235 {0x00, 0x50, 0x8151},
236 {0x00, 0x40, 0x8152},
237 {0x00, 0x78, 0x8153},
238 {0x00, 0x40, 0x8154},
239 {0x00, 0x00, 0x8167},
240 {0x00, 0x20, 0x8168},
241 {0x00, 0x00, 0x816a},
242 {0x00, 0x03, 0x816b},
243 {0x00, 0x20, 0x8169},
244 {0x00, 0x60, 0x8157},
245 {0x00, 0x00, 0x8190},
246 {0x00, 0x00, 0x81a1},
247 {0x00, 0x00, 0x81b2},
248 {0x00, 0x27, 0x8191},
249 {0x00, 0x27, 0x81a2},
250 {0x00, 0x27, 0x81b3},
251 {0x00, 0x4b, 0x8192},
252 {0x00, 0x4b, 0x81a3},
253 {0x00, 0x4b, 0x81b4},
254 {0x00, 0x66, 0x8193},
255 {0x00, 0x66, 0x81a4},
256 {0x00, 0x66, 0x81b5},
257 {0x00, 0x79, 0x8194},
258 {0x00, 0x79, 0x81a5},
259 {0x00, 0x79, 0x81b6},
260 {0x00, 0x8a, 0x8195},
261 {0x00, 0x8a, 0x81a6},
262 {0x00, 0x8a, 0x81b7},
263 {0x00, 0x9b, 0x8196},
264 {0x00, 0x9b, 0x81a7},
265 {0x00, 0x9b, 0x81b8},
266 {0x00, 0xa6, 0x8197},
267 {0x00, 0xa6, 0x81a8},
268 {0x00, 0xa6, 0x81b9},
269 {0x00, 0xb2, 0x8198},
270 {0x00, 0xb2, 0x81a9},
271 {0x00, 0xb2, 0x81ba},
272 {0x00, 0xbe, 0x8199},
273 {0x00, 0xbe, 0x81aa},
274 {0x00, 0xbe, 0x81bb},
275 {0x00, 0xc8, 0x819a},
276 {0x00, 0xc8, 0x81ab},
277 {0x00, 0xc8, 0x81bc},
278 {0x00, 0xd2, 0x819b},
279 {0x00, 0xd2, 0x81ac},
280 {0x00, 0xd2, 0x81bd},
281 {0x00, 0xdb, 0x819c},
282 {0x00, 0xdb, 0x81ad},
283 {0x00, 0xdb, 0x81be},
284 {0x00, 0xe4, 0x819d},
285 {0x00, 0xe4, 0x81ae},
286 {0x00, 0xe4, 0x81bf},
287 {0x00, 0xed, 0x819e},
288 {0x00, 0xed, 0x81af},
289 {0x00, 0xed, 0x81c0},
290 {0x00, 0xf7, 0x819f},
291 {0x00, 0xf7, 0x81b0},
292 {0x00, 0xf7, 0x81c1},
293 {0x00, 0xff, 0x81a0},
294 {0x00, 0xff, 0x81b1},
295 {0x00, 0xff, 0x81c2},
296 {0x00, 0x03, 0x8156},
297 {0x00, 0x00, 0x8211},
298 {0x00, 0x20, 0x8168},
299 {0x00, 0x01, 0x8202},
300 {0x00, 0x30, 0x8101},
301 {0x00, 0x00, 0x8111},
302 {0x00, 0x00, 0x8112},
303 {0x00, 0x00, 0x8113},
304 {0x00, 0x00, 0x8114},
308 static const __u8 qtable_creative_pccam[2][64] = {
309 { /* Q-table Y-components */
310 0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12,
311 0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11,
312 0x04, 0x04, 0x05, 0x07, 0x0c, 0x11, 0x15, 0x11,
313 0x04, 0x05, 0x07, 0x09, 0x0f, 0x1a, 0x18, 0x13,
314 0x05, 0x07, 0x0b, 0x11, 0x14, 0x21, 0x1f, 0x17,
315 0x07, 0x0b, 0x11, 0x13, 0x18, 0x1f, 0x22, 0x1c,
316 0x0f, 0x13, 0x17, 0x1a, 0x1f, 0x24, 0x24, 0x1e,
317 0x16, 0x1c, 0x1d, 0x1d, 0x22, 0x1e, 0x1f, 0x1e},
318 { /* Q-table C-components */
319 0x05, 0x05, 0x07, 0x0e, 0x1e, 0x1e, 0x1e, 0x1e,
320 0x05, 0x06, 0x08, 0x14, 0x1e, 0x1e, 0x1e, 0x1e,
321 0x07, 0x08, 0x11, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
322 0x0e, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
323 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
324 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
325 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
326 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e}
329 static const __u8 qtable_kodak_ez200[2][64] = {
330 { /* Q-table Y-components */
331 0x02, 0x01, 0x01, 0x02, 0x02, 0x04, 0x05, 0x06,
332 0x01, 0x01, 0x01, 0x02, 0x03, 0x06, 0x06, 0x06,
333 0x01, 0x01, 0x02, 0x02, 0x04, 0x06, 0x07, 0x06,
334 0x01, 0x02, 0x02, 0x03, 0x05, 0x09, 0x08, 0x06,
335 0x02, 0x02, 0x04, 0x06, 0x07, 0x0b, 0x0a, 0x08,
336 0x02, 0x04, 0x06, 0x06, 0x08, 0x0a, 0x0b, 0x09,
337 0x05, 0x06, 0x08, 0x09, 0x0a, 0x0c, 0x0c, 0x0a,
338 0x07, 0x09, 0x0a, 0x0a, 0x0b, 0x0a, 0x0a, 0x0a},
339 { /* Q-table C-components */
340 0x02, 0x02, 0x02, 0x05, 0x0a, 0x0a, 0x0a, 0x0a,
341 0x02, 0x02, 0x03, 0x07, 0x0a, 0x0a, 0x0a, 0x0a,
342 0x02, 0x03, 0x06, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
343 0x05, 0x07, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
344 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
345 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
346 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
347 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a}
350 static const __u8 qtable_pocketdv[2][64] = {
351 { /* Q-table Y-components start registers 0x8800 */
352 0x06, 0x04, 0x04, 0x06, 0x0a, 0x10, 0x14, 0x18,
353 0x05, 0x05, 0x06, 0x08, 0x0a, 0x17, 0x18, 0x16,
354 0x06, 0x05, 0x06, 0x0a, 0x10, 0x17, 0x1c, 0x16,
355 0x06, 0x07, 0x09, 0x0c, 0x14, 0x23, 0x20, 0x19,
356 0x07, 0x09, 0x0f, 0x16, 0x1b, 0x2c, 0x29, 0x1f,
357 0x0a, 0x0e, 0x16, 0x1a, 0x20, 0x2a, 0x2d, 0x25,
358 0x14, 0x1a, 0x1f, 0x23, 0x29, 0x30, 0x30, 0x28,
359 0x1d, 0x25, 0x26, 0x27, 0x2d, 0x28, 0x29, 0x28,
361 { /* Q-table C-components start registers 0x8840 */
362 0x07, 0x07, 0x0a, 0x13, 0x28, 0x28, 0x28, 0x28,
363 0x07, 0x08, 0x0a, 0x1a, 0x28, 0x28, 0x28, 0x28,
364 0x0a, 0x0a, 0x16, 0x28, 0x28, 0x28, 0x28, 0x28,
365 0x13, 0x1a, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
366 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
367 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
368 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
369 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28}
372 /* read 'len' bytes to gspca_dev->usb_buf */
373 static void reg_r(struct gspca_dev *gspca_dev,
374 __u16 index,
375 __u16 length)
377 usb_control_msg(gspca_dev->dev,
378 usb_rcvctrlpipe(gspca_dev->dev, 0),
380 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
381 0, /* value */
382 index, gspca_dev->usb_buf, length, 500);
385 static int reg_w(struct gspca_dev *gspca_dev,
386 __u16 req, __u16 index, __u16 value)
388 int ret;
390 PDEBUG(D_USBO, "reg write: [0x%02x] = 0x%02x", index, value);
391 ret = usb_control_msg(gspca_dev->dev,
392 usb_sndctrlpipe(gspca_dev->dev, 0),
393 req,
394 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
395 value, index, NULL, 0, 500);
396 if (ret < 0)
397 PDEBUG(D_ERR, "reg write: error %d", ret);
398 return ret;
401 /* returns: negative is error, pos or zero is data */
402 static int reg_r_12(struct gspca_dev *gspca_dev,
403 __u16 req, /* bRequest */
404 __u16 index, /* wIndex */
405 __u16 length) /* wLength (1 or 2 only) */
407 int ret;
409 gspca_dev->usb_buf[1] = 0;
410 ret = usb_control_msg(gspca_dev->dev,
411 usb_rcvctrlpipe(gspca_dev->dev, 0),
412 req,
413 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
414 0, /* value */
415 index,
416 gspca_dev->usb_buf, length,
417 500); /* timeout */
418 if (ret < 0) {
419 PDEBUG(D_ERR, "reg_r_12 err %d", ret);
420 return -1;
422 return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0];
426 * Simple function to wait for a given 8-bit value to be returned from
427 * a reg_read call.
428 * Returns: negative is error or timeout, zero is success.
430 static int reg_r_wait(struct gspca_dev *gspca_dev,
431 __u16 reg, __u16 index, __u16 value)
433 int ret, cnt = 20;
435 while (--cnt > 0) {
436 ret = reg_r_12(gspca_dev, reg, index, 1);
437 if (ret == value)
438 return 0;
439 msleep(50);
441 return -EIO;
444 static int write_vector(struct gspca_dev *gspca_dev,
445 const __u16 data[][3])
447 int ret, i = 0;
449 while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) {
450 ret = reg_w(gspca_dev, data[i][0], data[i][2], data[i][1]);
451 if (ret < 0)
452 return ret;
453 i++;
455 return 0;
458 static int spca50x_setup_qtable(struct gspca_dev *gspca_dev,
459 unsigned int request,
460 unsigned int ybase,
461 unsigned int cbase,
462 const __u8 qtable[2][64])
464 int i, err;
466 /* loop over y components */
467 for (i = 0; i < 64; i++) {
468 err = reg_w(gspca_dev, request, ybase + i, qtable[0][i]);
469 if (err < 0)
470 return err;
473 /* loop over c components */
474 for (i = 0; i < 64; i++) {
475 err = reg_w(gspca_dev, request, cbase + i, qtable[1][i]);
476 if (err < 0)
477 return err;
479 return 0;
482 static void spca500_ping310(struct gspca_dev *gspca_dev)
484 reg_r(gspca_dev, 0x0d04, 2);
485 PDEBUG(D_STREAM, "ClickSmart310 ping 0x0d04 0x%02x 0x%02x",
486 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
489 static void spca500_clksmart310_init(struct gspca_dev *gspca_dev)
491 reg_r(gspca_dev, 0x0d05, 2);
492 PDEBUG(D_STREAM, "ClickSmart310 init 0x0d05 0x%02x 0x%02x",
493 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
494 reg_w(gspca_dev, 0x00, 0x8167, 0x5a);
495 spca500_ping310(gspca_dev);
497 reg_w(gspca_dev, 0x00, 0x8168, 0x22);
498 reg_w(gspca_dev, 0x00, 0x816a, 0xc0);
499 reg_w(gspca_dev, 0x00, 0x816b, 0x0b);
500 reg_w(gspca_dev, 0x00, 0x8169, 0x25);
501 reg_w(gspca_dev, 0x00, 0x8157, 0x5b);
502 reg_w(gspca_dev, 0x00, 0x8158, 0x5b);
503 reg_w(gspca_dev, 0x00, 0x813f, 0x03);
504 reg_w(gspca_dev, 0x00, 0x8151, 0x4a);
505 reg_w(gspca_dev, 0x00, 0x8153, 0x78);
506 reg_w(gspca_dev, 0x00, 0x0d01, 0x04);
507 /* 00 for adjust shutter */
508 reg_w(gspca_dev, 0x00, 0x0d02, 0x01);
509 reg_w(gspca_dev, 0x00, 0x8169, 0x25);
510 reg_w(gspca_dev, 0x00, 0x0d01, 0x02);
513 static void spca500_setmode(struct gspca_dev *gspca_dev,
514 __u8 xmult, __u8 ymult)
516 int mode;
518 /* set x multiplier */
519 reg_w(gspca_dev, 0, 0x8001, xmult);
521 /* set y multiplier */
522 reg_w(gspca_dev, 0, 0x8002, ymult);
524 /* use compressed mode, VGA, with mode specific subsample */
525 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
526 reg_w(gspca_dev, 0, 0x8003, mode << 4);
529 static int spca500_full_reset(struct gspca_dev *gspca_dev)
531 int err;
533 /* send the reset command */
534 err = reg_w(gspca_dev, 0xe0, 0x0001, 0x0000);
535 if (err < 0)
536 return err;
538 /* wait for the reset to complete */
539 err = reg_r_wait(gspca_dev, 0x06, 0x0000, 0x0000);
540 if (err < 0)
541 return err;
542 err = reg_w(gspca_dev, 0xe0, 0x0000, 0x0000);
543 if (err < 0)
544 return err;
545 err = reg_r_wait(gspca_dev, 0x06, 0, 0);
546 if (err < 0) {
547 PDEBUG(D_ERR, "reg_r_wait() failed");
548 return err;
550 /* all ok */
551 return 0;
554 /* Synchro the Bridge with sensor */
555 /* Maybe that will work on all spca500 chip */
556 /* because i only own a clicksmart310 try for that chip */
557 /* using spca50x_set_packet_size() cause an Ooops here */
558 /* usb_set_interface from kernel 2.6.x clear all the urb stuff */
559 /* up-port the same feature as in 2.4.x kernel */
560 static int spca500_synch310(struct gspca_dev *gspca_dev)
562 if (usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0) < 0) {
563 PDEBUG(D_ERR, "Set packet size: set interface error");
564 goto error;
566 spca500_ping310(gspca_dev);
568 reg_r(gspca_dev, 0x0d00, 1);
570 /* need alt setting here */
571 PDEBUG(D_PACK, "ClickSmart310 sync alt: %d", gspca_dev->alt);
573 /* Windoze use pipe with altsetting 6 why 7 here */
574 if (usb_set_interface(gspca_dev->dev,
575 gspca_dev->iface,
576 gspca_dev->alt) < 0) {
577 PDEBUG(D_ERR, "Set packet size: set interface error");
578 goto error;
580 return 0;
581 error:
582 return -EBUSY;
585 static void spca500_reinit(struct gspca_dev *gspca_dev)
587 int err;
588 __u8 Data;
590 /* some unknow command from Aiptek pocket dv and family300 */
592 reg_w(gspca_dev, 0x00, 0x0d01, 0x01);
593 reg_w(gspca_dev, 0x00, 0x0d03, 0x00);
594 reg_w(gspca_dev, 0x00, 0x0d02, 0x01);
596 /* enable drop packet */
597 reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
599 err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840,
600 qtable_pocketdv);
601 if (err < 0)
602 PDEBUG(D_ERR|D_STREAM, "spca50x_setup_qtable failed on init");
604 /* set qtable index */
605 reg_w(gspca_dev, 0x00, 0x8880, 2);
606 /* family cam Quicksmart stuff */
607 reg_w(gspca_dev, 0x00, 0x800a, 0x00);
608 /* Set agc transfer: synced inbetween frames */
609 reg_w(gspca_dev, 0x00, 0x820f, 0x01);
610 /* Init SDRAM - needed for SDRAM access */
611 reg_w(gspca_dev, 0x00, 0x870a, 0x04);
612 /*Start init sequence or stream */
613 reg_w(gspca_dev, 0, 0x8003, 0x00);
614 /* switch to video camera mode */
615 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
616 msleep(2000);
617 if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0) {
618 reg_r(gspca_dev, 0x816b, 1);
619 Data = gspca_dev->usb_buf[0];
620 reg_w(gspca_dev, 0x00, 0x816b, Data);
624 /* this function is called at probe time */
625 static int sd_config(struct gspca_dev *gspca_dev,
626 const struct usb_device_id *id)
628 struct sd *sd = (struct sd *) gspca_dev;
629 struct cam *cam;
631 cam = &gspca_dev->cam;
632 sd->subtype = id->driver_info;
633 if (sd->subtype != LogitechClickSmart310) {
634 cam->cam_mode = vga_mode;
635 cam->nmodes = ARRAY_SIZE(vga_mode);
636 } else {
637 cam->cam_mode = sif_mode;
638 cam->nmodes = ARRAY_SIZE(sif_mode);
640 sd->brightness = BRIGHTNESS_DEF;
641 sd->contrast = CONTRAST_DEF;
642 sd->colors = COLOR_DEF;
643 return 0;
646 /* this function is called at probe and resume time */
647 static int sd_init(struct gspca_dev *gspca_dev)
649 struct sd *sd = (struct sd *) gspca_dev;
651 /* initialisation of spca500 based cameras is deferred */
652 PDEBUG(D_STREAM, "SPCA500 init");
653 if (sd->subtype == LogitechClickSmart310)
654 spca500_clksmart310_init(gspca_dev);
655 /* else
656 spca500_initialise(gspca_dev); */
657 PDEBUG(D_STREAM, "SPCA500 init done");
658 return 0;
661 static int sd_start(struct gspca_dev *gspca_dev)
663 struct sd *sd = (struct sd *) gspca_dev;
664 int err;
665 __u8 Data;
666 __u8 xmult, ymult;
668 if (sd->subtype == LogitechClickSmart310) {
669 xmult = 0x16;
670 ymult = 0x12;
671 } else {
672 xmult = 0x28;
673 ymult = 0x1e;
676 /* is there a sensor here ? */
677 reg_r(gspca_dev, 0x8a04, 1);
678 PDEBUG(D_STREAM, "Spca500 Sensor Address 0x%02x",
679 gspca_dev->usb_buf[0]);
680 PDEBUG(D_STREAM, "Spca500 curr_mode: %d Xmult: 0x%02x, Ymult: 0x%02x",
681 gspca_dev->curr_mode, xmult, ymult);
683 /* setup qtable */
684 switch (sd->subtype) {
685 case LogitechClickSmart310:
686 spca500_setmode(gspca_dev, xmult, ymult);
688 /* enable drop packet */
689 reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
690 reg_w(gspca_dev, 0x00, 0x8880, 3);
691 err = spca50x_setup_qtable(gspca_dev,
692 0x00, 0x8800, 0x8840,
693 qtable_creative_pccam);
694 if (err < 0)
695 PDEBUG(D_ERR, "spca50x_setup_qtable failed");
696 /* Init SDRAM - needed for SDRAM access */
697 reg_w(gspca_dev, 0x00, 0x870a, 0x04);
699 /* switch to video camera mode */
700 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
701 msleep(500);
702 if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
703 PDEBUG(D_ERR, "reg_r_wait() failed");
705 reg_r(gspca_dev, 0x816b, 1);
706 Data = gspca_dev->usb_buf[0];
707 reg_w(gspca_dev, 0x00, 0x816b, Data);
709 spca500_synch310(gspca_dev);
711 write_vector(gspca_dev, spca500_visual_defaults);
712 spca500_setmode(gspca_dev, xmult, ymult);
713 /* enable drop packet */
714 err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
715 if (err < 0)
716 PDEBUG(D_ERR, "failed to enable drop packet");
717 reg_w(gspca_dev, 0x00, 0x8880, 3);
718 err = spca50x_setup_qtable(gspca_dev,
719 0x00, 0x8800, 0x8840,
720 qtable_creative_pccam);
721 if (err < 0)
722 PDEBUG(D_ERR, "spca50x_setup_qtable failed");
724 /* Init SDRAM - needed for SDRAM access */
725 reg_w(gspca_dev, 0x00, 0x870a, 0x04);
727 /* switch to video camera mode */
728 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
730 if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
731 PDEBUG(D_ERR, "reg_r_wait() failed");
733 reg_r(gspca_dev, 0x816b, 1);
734 Data = gspca_dev->usb_buf[0];
735 reg_w(gspca_dev, 0x00, 0x816b, Data);
736 break;
737 case CreativePCCam300: /* Creative PC-CAM 300 640x480 CCD */
738 case IntelPocketPCCamera: /* FIXME: Temporary fix for
739 * Intel Pocket PC Camera
740 * - NWG (Sat 29th March 2003) */
742 /* do a full reset */
743 err = spca500_full_reset(gspca_dev);
744 if (err < 0)
745 PDEBUG(D_ERR, "spca500_full_reset failed");
747 /* enable drop packet */
748 err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
749 if (err < 0)
750 PDEBUG(D_ERR, "failed to enable drop packet");
751 reg_w(gspca_dev, 0x00, 0x8880, 3);
752 err = spca50x_setup_qtable(gspca_dev,
753 0x00, 0x8800, 0x8840,
754 qtable_creative_pccam);
755 if (err < 0)
756 PDEBUG(D_ERR, "spca50x_setup_qtable failed");
758 spca500_setmode(gspca_dev, xmult, ymult);
759 reg_w(gspca_dev, 0x20, 0x0001, 0x0004);
761 /* switch to video camera mode */
762 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
764 if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
765 PDEBUG(D_ERR, "reg_r_wait() failed");
767 reg_r(gspca_dev, 0x816b, 1);
768 Data = gspca_dev->usb_buf[0];
769 reg_w(gspca_dev, 0x00, 0x816b, Data);
771 /* write_vector(gspca_dev, spca500_visual_defaults); */
772 break;
773 case KodakEZ200: /* Kodak EZ200 */
775 /* do a full reset */
776 err = spca500_full_reset(gspca_dev);
777 if (err < 0)
778 PDEBUG(D_ERR, "spca500_full_reset failed");
779 /* enable drop packet */
780 reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
781 reg_w(gspca_dev, 0x00, 0x8880, 0);
782 err = spca50x_setup_qtable(gspca_dev,
783 0x00, 0x8800, 0x8840,
784 qtable_kodak_ez200);
785 if (err < 0)
786 PDEBUG(D_ERR, "spca50x_setup_qtable failed");
787 spca500_setmode(gspca_dev, xmult, ymult);
789 reg_w(gspca_dev, 0x20, 0x0001, 0x0004);
791 /* switch to video camera mode */
792 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
794 if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
795 PDEBUG(D_ERR, "reg_r_wait() failed");
797 reg_r(gspca_dev, 0x816b, 1);
798 Data = gspca_dev->usb_buf[0];
799 reg_w(gspca_dev, 0x00, 0x816b, Data);
801 /* write_vector(gspca_dev, spca500_visual_defaults); */
802 break;
804 case BenqDC1016:
805 case DLinkDSC350: /* FamilyCam 300 */
806 case AiptekPocketDV: /* Aiptek PocketDV */
807 case Gsmartmini: /*Mustek Gsmart Mini */
808 case MustekGsmart300: /* Mustek Gsmart 300 */
809 case PalmPixDC85:
810 case Optimedia:
811 case ToptroIndus:
812 case AgfaCl20:
813 spca500_reinit(gspca_dev);
814 reg_w(gspca_dev, 0x00, 0x0d01, 0x01);
815 /* enable drop packet */
816 reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
818 err = spca50x_setup_qtable(gspca_dev,
819 0x00, 0x8800, 0x8840, qtable_pocketdv);
820 if (err < 0)
821 PDEBUG(D_ERR, "spca50x_setup_qtable failed");
822 reg_w(gspca_dev, 0x00, 0x8880, 2);
824 /* familycam Quicksmart pocketDV stuff */
825 reg_w(gspca_dev, 0x00, 0x800a, 0x00);
826 /* Set agc transfer: synced inbetween frames */
827 reg_w(gspca_dev, 0x00, 0x820f, 0x01);
828 /* Init SDRAM - needed for SDRAM access */
829 reg_w(gspca_dev, 0x00, 0x870a, 0x04);
831 spca500_setmode(gspca_dev, xmult, ymult);
832 /* switch to video camera mode */
833 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
835 reg_r_wait(gspca_dev, 0, 0x8000, 0x44);
837 reg_r(gspca_dev, 0x816b, 1);
838 Data = gspca_dev->usb_buf[0];
839 reg_w(gspca_dev, 0x00, 0x816b, Data);
840 break;
841 case LogitechTraveler:
842 case LogitechClickSmart510:
843 reg_w(gspca_dev, 0x02, 0x00, 0x00);
844 /* enable drop packet */
845 reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
847 err = spca50x_setup_qtable(gspca_dev,
848 0x00, 0x8800,
849 0x8840, qtable_creative_pccam);
850 if (err < 0)
851 PDEBUG(D_ERR, "spca50x_setup_qtable failed");
852 reg_w(gspca_dev, 0x00, 0x8880, 3);
853 reg_w(gspca_dev, 0x00, 0x800a, 0x00);
854 /* Init SDRAM - needed for SDRAM access */
855 reg_w(gspca_dev, 0x00, 0x870a, 0x04);
857 spca500_setmode(gspca_dev, xmult, ymult);
859 /* switch to video camera mode */
860 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
861 reg_r_wait(gspca_dev, 0, 0x8000, 0x44);
863 reg_r(gspca_dev, 0x816b, 1);
864 Data = gspca_dev->usb_buf[0];
865 reg_w(gspca_dev, 0x00, 0x816b, Data);
866 write_vector(gspca_dev, Clicksmart510_defaults);
867 break;
869 return 0;
872 static void sd_stopN(struct gspca_dev *gspca_dev)
874 reg_w(gspca_dev, 0, 0x8003, 0x00);
876 /* switch to video camera mode */
877 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
878 reg_r(gspca_dev, 0x8000, 1);
879 PDEBUG(D_STREAM, "stop SPCA500 done reg8000: 0x%2x",
880 gspca_dev->usb_buf[0]);
883 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
884 struct gspca_frame *frame, /* target */
885 __u8 *data, /* isoc packet */
886 int len) /* iso packet length */
888 struct sd *sd = (struct sd *) gspca_dev;
889 int i;
890 __u8 *s, *d;
891 static __u8 ffd9[] = {0xff, 0xd9};
893 /* frames are jpeg 4.1.1 without 0xff escape */
894 if (data[0] == 0xff) {
895 if (data[1] != 0x01) { /* drop packet */
896 /* gspca_dev->last_packet_type = DISCARD_PACKET; */
897 return;
899 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
900 ffd9, 2);
902 /* put the JPEG header in the new frame */
903 jpeg_put_header(gspca_dev, frame, 0x22);
905 data += SPCA500_OFFSET_DATA;
906 len -= SPCA500_OFFSET_DATA;
907 } else {
908 data += 1;
909 len -= 1;
912 /* add 0x00 after 0xff */
913 for (i = len; --i >= 0; )
914 if (data[i] == 0xff)
915 break;
916 if (i < 0) { /* no 0xff */
917 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
918 return;
920 s = data;
921 d = sd->packet;
922 for (i = 0; i < len; i++) {
923 *d++ = *s++;
924 if (s[-1] == 0xff)
925 *d++ = 0x00;
927 gspca_frame_add(gspca_dev, INTER_PACKET, frame,
928 sd->packet, d - sd->packet);
931 static void setbrightness(struct gspca_dev *gspca_dev)
933 struct sd *sd = (struct sd *) gspca_dev;
935 reg_w(gspca_dev, 0x00, 0x8167,
936 (__u8) (sd->brightness - 128));
939 static void setcontrast(struct gspca_dev *gspca_dev)
941 struct sd *sd = (struct sd *) gspca_dev;
943 reg_w(gspca_dev, 0x00, 0x8168, sd->contrast);
946 static void setcolors(struct gspca_dev *gspca_dev)
948 struct sd *sd = (struct sd *) gspca_dev;
950 reg_w(gspca_dev, 0x00, 0x8169, sd->colors);
953 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
955 struct sd *sd = (struct sd *) gspca_dev;
957 sd->brightness = val;
958 if (gspca_dev->streaming)
959 setbrightness(gspca_dev);
960 return 0;
963 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
965 struct sd *sd = (struct sd *) gspca_dev;
967 *val = sd->brightness;
968 return 0;
971 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
973 struct sd *sd = (struct sd *) gspca_dev;
975 sd->contrast = val;
976 if (gspca_dev->streaming)
977 setcontrast(gspca_dev);
978 return 0;
981 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
983 struct sd *sd = (struct sd *) gspca_dev;
985 *val = sd->contrast;
986 return 0;
989 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
991 struct sd *sd = (struct sd *) gspca_dev;
993 sd->colors = val;
994 if (gspca_dev->streaming)
995 setcolors(gspca_dev);
996 return 0;
999 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1001 struct sd *sd = (struct sd *) gspca_dev;
1003 *val = sd->colors;
1004 return 0;
1007 /* sub-driver description */
1008 static struct sd_desc sd_desc = {
1009 .name = MODULE_NAME,
1010 .ctrls = sd_ctrls,
1011 .nctrls = ARRAY_SIZE(sd_ctrls),
1012 .config = sd_config,
1013 .init = sd_init,
1014 .start = sd_start,
1015 .stopN = sd_stopN,
1016 .pkt_scan = sd_pkt_scan,
1019 /* -- module initialisation -- */
1020 static const __devinitdata struct usb_device_id device_table[] = {
1021 {USB_DEVICE(0x040a, 0x0300), .driver_info = KodakEZ200},
1022 {USB_DEVICE(0x041e, 0x400a), .driver_info = CreativePCCam300},
1023 {USB_DEVICE(0x046d, 0x0890), .driver_info = LogitechTraveler},
1024 {USB_DEVICE(0x046d, 0x0900), .driver_info = LogitechClickSmart310},
1025 {USB_DEVICE(0x046d, 0x0901), .driver_info = LogitechClickSmart510},
1026 {USB_DEVICE(0x04a5, 0x300c), .driver_info = BenqDC1016},
1027 {USB_DEVICE(0x04fc, 0x7333), .driver_info = PalmPixDC85},
1028 {USB_DEVICE(0x055f, 0xc200), .driver_info = MustekGsmart300},
1029 {USB_DEVICE(0x055f, 0xc220), .driver_info = Gsmartmini},
1030 {USB_DEVICE(0x06bd, 0x0404), .driver_info = AgfaCl20},
1031 {USB_DEVICE(0x06be, 0x0800), .driver_info = Optimedia},
1032 {USB_DEVICE(0x084d, 0x0003), .driver_info = DLinkDSC350},
1033 {USB_DEVICE(0x08ca, 0x0103), .driver_info = AiptekPocketDV},
1034 {USB_DEVICE(0x2899, 0x012c), .driver_info = ToptroIndus},
1035 {USB_DEVICE(0x8086, 0x0630), .driver_info = IntelPocketPCCamera},
1038 MODULE_DEVICE_TABLE(usb, device_table);
1040 /* -- device connect -- */
1041 static int sd_probe(struct usb_interface *intf,
1042 const struct usb_device_id *id)
1044 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1045 THIS_MODULE);
1048 static struct usb_driver sd_driver = {
1049 .name = MODULE_NAME,
1050 .id_table = device_table,
1051 .probe = sd_probe,
1052 .disconnect = gspca_disconnect,
1053 #ifdef CONFIG_PM
1054 .suspend = gspca_suspend,
1055 .resume = gspca_resume,
1056 #endif
1059 /* -- module insert / remove -- */
1060 static int __init sd_mod_init(void)
1062 int ret;
1063 ret = usb_register(&sd_driver);
1064 if (ret < 0)
1065 return ret;
1066 PDEBUG(D_PROBE, "registered");
1067 return 0;
1069 static void __exit sd_mod_exit(void)
1071 usb_deregister(&sd_driver);
1072 PDEBUG(D_PROBE, "deregistered");
1075 module_init(sd_mod_init);
1076 module_exit(sd_mod_exit);