2 * Syntek DV4000 (STK014) subdriver
4 * Copyright (C) 2008 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
21 #define MODULE_NAME "stk014"
24 #define QUANT_VAL 7 /* quantization table */
25 /* <= 4 KO - 7: good (enough!) */
28 MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
29 MODULE_DESCRIPTION("Syntek DV4000 (STK014) USB Camera Driver");
30 MODULE_LICENSE("GPL");
32 /* specific webcam descriptor */
34 struct gspca_dev gspca_dev; /* !! must be the first item */
36 unsigned char brightness;
37 unsigned char contrast;
39 unsigned char lightfreq;
42 /* V4L2 controls supported by the driver */
43 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
44 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
45 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
46 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
47 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
48 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
49 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
50 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
52 static struct ctrl sd_ctrls[] = {
55 .id = V4L2_CID_BRIGHTNESS,
56 .type = V4L2_CTRL_TYPE_INTEGER,
61 #define BRIGHTNESS_DEF 127
62 .default_value = BRIGHTNESS_DEF,
64 .set = sd_setbrightness,
65 .get = sd_getbrightness,
69 .id = V4L2_CID_CONTRAST,
70 .type = V4L2_CTRL_TYPE_INTEGER,
75 #define CONTRAST_DEF 127
76 .default_value = CONTRAST_DEF,
78 .set = sd_setcontrast,
79 .get = sd_getcontrast,
83 .id = V4L2_CID_SATURATION,
84 .type = V4L2_CTRL_TYPE_INTEGER,
90 .default_value = COLOR_DEF,
97 .id = V4L2_CID_POWER_LINE_FREQUENCY,
98 .type = V4L2_CTRL_TYPE_MENU,
99 .name = "Light frequency filter",
101 .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
104 .default_value = FREQ_DEF,
111 static const struct v4l2_pix_format vga_mode[] = {
112 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
114 .sizeimage = 320 * 240 * 3 / 8 + 590,
115 .colorspace = V4L2_COLORSPACE_JPEG,
117 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
119 .sizeimage = 640 * 480 * 3 / 8 + 590,
120 .colorspace = V4L2_COLORSPACE_JPEG,
124 /* -- read a register -- */
125 static int reg_r(struct gspca_dev *gspca_dev,
128 struct usb_device *dev = gspca_dev->dev;
131 ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
133 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
136 gspca_dev->usb_buf, 1,
139 PDEBUG(D_ERR, "reg_r err %d", ret);
142 return gspca_dev->usb_buf[0];
145 /* -- write a register -- */
146 static int reg_w(struct gspca_dev *gspca_dev,
147 __u16 index, __u16 value)
149 struct usb_device *dev = gspca_dev->dev;
152 ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
154 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
161 PDEBUG(D_ERR, "reg_w err %d", ret);
165 /* -- get a bulk value (4 bytes) -- */
166 static int rcv_val(struct gspca_dev *gspca_dev,
169 struct usb_device *dev = gspca_dev->dev;
172 reg_w(gspca_dev, 0x634, (ads >> 16) & 0xff);
173 reg_w(gspca_dev, 0x635, (ads >> 8) & 0xff);
174 reg_w(gspca_dev, 0x636, ads & 0xff);
175 reg_w(gspca_dev, 0x637, 0);
176 reg_w(gspca_dev, 0x638, 4); /* len & 0xff */
177 reg_w(gspca_dev, 0x639, 0); /* len >> 8 */
178 reg_w(gspca_dev, 0x63a, 0);
179 reg_w(gspca_dev, 0x63b, 0);
180 reg_w(gspca_dev, 0x630, 5);
181 ret = usb_bulk_msg(dev,
182 usb_rcvbulkpipe(dev, 0x05),
186 500); /* timeout in milliseconds */
190 /* -- send a bulk value -- */
191 static int snd_val(struct gspca_dev *gspca_dev,
195 struct usb_device *dev = gspca_dev->dev;
199 if (ads == 0x003f08) {
200 ret = reg_r(gspca_dev, 0x0704);
203 ret = reg_r(gspca_dev, 0x0705);
206 seq = ret; /* keep the sequence number */
207 ret = reg_r(gspca_dev, 0x0650);
210 reg_w(gspca_dev, 0x654, seq);
212 reg_w(gspca_dev, 0x654, (ads >> 16) & 0xff);
214 reg_w(gspca_dev, 0x655, (ads >> 8) & 0xff);
215 reg_w(gspca_dev, 0x656, ads & 0xff);
216 reg_w(gspca_dev, 0x657, 0);
217 reg_w(gspca_dev, 0x658, 0x04); /* size */
218 reg_w(gspca_dev, 0x659, 0);
219 reg_w(gspca_dev, 0x65a, 0);
220 reg_w(gspca_dev, 0x65b, 0);
221 reg_w(gspca_dev, 0x650, 5);
222 gspca_dev->usb_buf[0] = val >> 24;
223 gspca_dev->usb_buf[1] = val >> 16;
224 gspca_dev->usb_buf[2] = val >> 8;
225 gspca_dev->usb_buf[3] = val;
226 ret = usb_bulk_msg(dev,
227 usb_sndbulkpipe(dev, 6),
231 500); /* timeout in milliseconds */
234 if (ads == 0x003f08) {
237 reg_w(gspca_dev, 0x705, seq);
241 PDEBUG(D_ERR, "snd_val err %d", ret);
245 /* set a camera parameter */
246 static int set_par(struct gspca_dev *gspca_dev,
249 return snd_val(gspca_dev, 0x003f08, parval);
252 static void setbrightness(struct gspca_dev *gspca_dev)
254 struct sd *sd = (struct sd *) gspca_dev;
257 parval = 0x06000000 /* whiteness */
258 + (sd->brightness << 16);
259 set_par(gspca_dev, parval);
262 static void setcontrast(struct gspca_dev *gspca_dev)
264 struct sd *sd = (struct sd *) gspca_dev;
267 parval = 0x07000000 /* contrast */
268 + (sd->contrast << 16);
269 set_par(gspca_dev, parval);
272 static void setcolors(struct gspca_dev *gspca_dev)
274 struct sd *sd = (struct sd *) gspca_dev;
277 parval = 0x08000000 /* saturation */
278 + (sd->colors << 16);
279 set_par(gspca_dev, parval);
282 static void setfreq(struct gspca_dev *gspca_dev)
284 struct sd *sd = (struct sd *) gspca_dev;
286 set_par(gspca_dev, sd->lightfreq == 1
287 ? 0x33640000 /* 50 Hz */
288 : 0x33780000); /* 60 Hz */
291 /* this function is called at probe time */
292 static int sd_config(struct gspca_dev *gspca_dev,
293 const struct usb_device_id *id)
295 struct sd *sd = (struct sd *) gspca_dev;
297 gspca_dev->cam.cam_mode = vga_mode;
298 gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode);
299 sd->brightness = BRIGHTNESS_DEF;
300 sd->contrast = CONTRAST_DEF;
301 sd->colors = COLOR_DEF;
302 sd->lightfreq = FREQ_DEF;
306 /* this function is called at probe and resume time */
307 static int sd_init(struct gspca_dev *gspca_dev)
311 /* check if the device responds */
312 usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1);
313 ret = reg_r(gspca_dev, 0x0740);
317 PDEBUG(D_ERR|D_STREAM, "init reg: 0x%02x", ret);
323 /* -- start the camera -- */
324 static int sd_start(struct gspca_dev *gspca_dev)
328 /* work on alternate 1 */
329 usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1);
331 set_par(gspca_dev, 0x10000000);
332 set_par(gspca_dev, 0x00000000);
333 set_par(gspca_dev, 0x8002e001);
334 set_par(gspca_dev, 0x14000000);
335 if (gspca_dev->width > 320)
336 value = 0x8002e001; /* 640x480 */
338 value = 0x4001f000; /* 320x240 */
339 set_par(gspca_dev, value);
340 ret = usb_set_interface(gspca_dev->dev,
344 PDEBUG(D_ERR|D_STREAM, "set intf %d %d failed",
345 gspca_dev->iface, gspca_dev->alt);
348 ret = reg_r(gspca_dev, 0x0630);
351 rcv_val(gspca_dev, 0x000020); /* << (value ff ff ff ff) */
352 ret = reg_r(gspca_dev, 0x0650);
355 snd_val(gspca_dev, 0x000020, 0xffffffff);
356 reg_w(gspca_dev, 0x0620, 0);
357 reg_w(gspca_dev, 0x0630, 0);
358 reg_w(gspca_dev, 0x0640, 0);
359 reg_w(gspca_dev, 0x0650, 0);
360 reg_w(gspca_dev, 0x0660, 0);
361 setbrightness(gspca_dev); /* whiteness */
362 setcontrast(gspca_dev); /* contrast */
363 setcolors(gspca_dev); /* saturation */
364 set_par(gspca_dev, 0x09800000); /* Red ? */
365 set_par(gspca_dev, 0x0a800000); /* Green ? */
366 set_par(gspca_dev, 0x0b800000); /* Blue ? */
367 set_par(gspca_dev, 0x0d030000); /* Gamma ? */
368 setfreq(gspca_dev); /* light frequency */
370 /* start the video flow */
371 set_par(gspca_dev, 0x01000000);
372 set_par(gspca_dev, 0x01000000);
373 PDEBUG(D_STREAM, "camera started alt: 0x%02x", gspca_dev->alt);
376 PDEBUG(D_ERR|D_STREAM, "camera start err %d", ret);
380 static void sd_stopN(struct gspca_dev *gspca_dev)
382 struct usb_device *dev = gspca_dev->dev;
384 set_par(gspca_dev, 0x02000000);
385 set_par(gspca_dev, 0x02000000);
386 usb_set_interface(dev, gspca_dev->iface, 1);
387 reg_r(gspca_dev, 0x0630);
388 rcv_val(gspca_dev, 0x000020); /* << (value ff ff ff ff) */
389 reg_r(gspca_dev, 0x0650);
390 snd_val(gspca_dev, 0x000020, 0xffffffff);
391 reg_w(gspca_dev, 0x0620, 0);
392 reg_w(gspca_dev, 0x0630, 0);
393 reg_w(gspca_dev, 0x0640, 0);
394 reg_w(gspca_dev, 0x0650, 0);
395 reg_w(gspca_dev, 0x0660, 0);
396 PDEBUG(D_STREAM, "camera stopped");
399 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
400 struct gspca_frame *frame, /* target */
401 __u8 *data, /* isoc packet */
402 int len) /* iso packet length */
404 static unsigned char ffd9[] = {0xff, 0xd9};
406 /* a frame starts with:
408 * - 0x08 0x00 - length (little endian ?!)
409 * - 4 bytes = size of whole frame (BE - including header)
412 * - .. JPEG image with escape sequences (ff 00)
413 * (without ending - ff d9)
415 if (data[0] == 0xff && data[1] == 0xfe) {
416 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
419 /* put the JPEG 411 header */
420 jpeg_put_header(gspca_dev, frame, 0x22);
422 /* beginning of the frame */
427 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
430 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
432 struct sd *sd = (struct sd *) gspca_dev;
434 sd->brightness = val;
435 if (gspca_dev->streaming)
436 setbrightness(gspca_dev);
440 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
442 struct sd *sd = (struct sd *) gspca_dev;
444 *val = sd->brightness;
448 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
450 struct sd *sd = (struct sd *) gspca_dev;
453 if (gspca_dev->streaming)
454 setcontrast(gspca_dev);
458 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
460 struct sd *sd = (struct sd *) gspca_dev;
466 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
468 struct sd *sd = (struct sd *) gspca_dev;
471 if (gspca_dev->streaming)
472 setcolors(gspca_dev);
476 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
478 struct sd *sd = (struct sd *) gspca_dev;
484 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
486 struct sd *sd = (struct sd *) gspca_dev;
489 if (gspca_dev->streaming)
494 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
496 struct sd *sd = (struct sd *) gspca_dev;
498 *val = sd->lightfreq;
502 static int sd_querymenu(struct gspca_dev *gspca_dev,
503 struct v4l2_querymenu *menu)
506 case V4L2_CID_POWER_LINE_FREQUENCY:
507 switch (menu->index) {
508 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
509 strcpy((char *) menu->name, "50 Hz");
511 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
512 strcpy((char *) menu->name, "60 Hz");
520 /* sub-driver description */
521 static const struct sd_desc sd_desc = {
524 .nctrls = ARRAY_SIZE(sd_ctrls),
529 .pkt_scan = sd_pkt_scan,
530 .querymenu = sd_querymenu,
533 /* -- module initialisation -- */
534 static const __devinitdata struct usb_device_id device_table[] = {
535 {USB_DEVICE(0x05e1, 0x0893)},
538 MODULE_DEVICE_TABLE(usb, device_table);
540 /* -- device connect -- */
541 static int sd_probe(struct usb_interface *intf,
542 const struct usb_device_id *id)
544 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
548 static struct usb_driver sd_driver = {
550 .id_table = device_table,
552 .disconnect = gspca_disconnect,
554 .suspend = gspca_suspend,
555 .resume = gspca_resume,
559 /* -- module insert / remove -- */
560 static int __init sd_mod_init(void)
563 ret = usb_register(&sd_driver);
569 static void __exit sd_mod_exit(void)
571 usb_deregister(&sd_driver);
572 info("deregistered");
575 module_init(sd_mod_init);
576 module_exit(sd_mod_exit);