]> pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/media/video/gspca/stk014.c
V4L/DVB (8152): Initial release of gspca with only one driver.
[linux-2.6-omap-h63xx.git] / drivers / media / video / gspca / stk014.c
1 /*
2  * Syntek DV4000 (STK014) subdriver
3  *
4  * Copyright (C) Jean-Francois Moine (http://moinejf.free.fr)
5  *
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.
10  *
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.
15  *
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
19  *
20  */
21
22 #define MODULE_NAME "stk014"
23
24 #include "gspca.h"
25 #include "jpeg.h"
26
27 #define DRIVER_VERSION_NUMBER   KERNEL_VERSION(0, 0, 22)
28 static const char version[] = "0.0.22";
29
30 MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
31 MODULE_DESCRIPTION("Syntek DV4000 (STK014) USB Camera Driver");
32 MODULE_LICENSE("GPL");
33
34 /* specific webcam descriptor */
35 struct sd {
36         struct gspca_dev gspca_dev;     /* !! must be the first item */
37
38         unsigned char brightness;
39         unsigned char contrast;
40         unsigned char colors;
41 };
42
43 /* global parameters */
44 static int lightfreq = 50;
45 static int sd_quant = 7;                /* <= 4 KO - 7: good (enough!) */
46
47 /* V4L2 controls supported by the driver */
48 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
49 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
50 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
51 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
52 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
53 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
54
55 static struct ctrl sd_ctrls[] = {
56 #define SD_BRIGHTNESS 0
57         {
58             {
59                 .id      = V4L2_CID_BRIGHTNESS,
60                 .type    = V4L2_CTRL_TYPE_INTEGER,
61                 .name    = "Brightness",
62                 .minimum = 0,
63                 .maximum = 255,
64                 .step    = 1,
65                 .default_value = 127,
66             },
67             .set = sd_setbrightness,
68             .get = sd_getbrightness,
69         },
70 #define SD_CONTRAST 1
71         {
72             {
73                 .id      = V4L2_CID_CONTRAST,
74                 .type    = V4L2_CTRL_TYPE_INTEGER,
75                 .name    = "Contrast",
76                 .minimum = 0,
77                 .maximum = 255,
78                 .step    = 1,
79                 .default_value = 127,
80             },
81             .set = sd_setcontrast,
82             .get = sd_getcontrast,
83         },
84 #define SD_COLOR 2
85         {
86             {
87                 .id      = V4L2_CID_SATURATION,
88                 .type    = V4L2_CTRL_TYPE_INTEGER,
89                 .name    = "Saturation",
90                 .minimum = 0,
91                 .maximum = 255,
92                 .step    = 1,
93                 .default_value = 127,
94             },
95             .set = sd_setcolors,
96             .get = sd_getcolors,
97         },
98 };
99
100 static struct cam_mode vga_mode[] = {
101         {V4L2_PIX_FMT_JPEG, 320, 240},
102         {V4L2_PIX_FMT_JPEG, 640, 480},
103 };
104
105 /* -- read a register -- */
106 static int reg_read(struct gspca_dev *gspca_dev,
107                         __u16 index, __u8 *buf)
108 {
109         int ret;
110         struct usb_device *dev = gspca_dev->dev;
111
112         ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
113                         0x00,
114                         USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
115                         0x00,
116                         index,
117                         buf, 1,
118                         500);
119         if (ret < 0)
120                 PDEBUG(D_ERR, "reg_read err %d", ret);
121         return ret;
122 }
123
124 /* -- write a register -- */
125 static int reg_write(struct gspca_dev *gspca_dev,
126                         __u16 index, __u16 value)
127 {
128         struct usb_device *dev = gspca_dev->dev;
129         int ret;
130
131         ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
132                         0x01,
133                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
134                         value,
135                         index,
136                         NULL,
137                         0,
138                         500);
139         if (ret < 0)
140                 PDEBUG(D_ERR, "reg_write err %d", ret);
141         return ret;
142 }
143
144 /* -- get a value -- */
145 static int rcv_val(struct gspca_dev *gspca_dev,
146                         int ads,
147                         int len)
148 {
149         struct usb_device *dev = gspca_dev->dev;
150         int alen, ret;
151         unsigned char bulk_buf[4];
152
153         reg_write(gspca_dev, 0x634, (ads >> 16) & 0xff);
154         reg_write(gspca_dev, 0x635, (ads >> 8) & 0xff);
155         reg_write(gspca_dev, 0x636, ads & 0xff);
156         reg_write(gspca_dev, 0x637, 0);
157         reg_write(gspca_dev, 0x638, len & 0xff);
158         reg_write(gspca_dev, 0x639, len >> 8);
159         reg_write(gspca_dev, 0x63a, 0);
160         reg_write(gspca_dev, 0x63b, 0);
161         reg_write(gspca_dev, 0x630, 5);
162         if (len > sizeof bulk_buf)
163                 return -1;
164         ret = usb_bulk_msg(dev,
165                         usb_rcvbulkpipe(dev, 5),
166                         bulk_buf,
167                         len,
168                         &alen,
169                         500);   /* timeout in milliseconds */
170         return ret;
171 }
172
173 /* -- send a value -- */
174 static int snd_val(struct gspca_dev *gspca_dev,
175                         int ads,
176                         unsigned int val)
177 {
178         struct usb_device *dev = gspca_dev->dev;
179         int alen, ret;
180         __u8 value, seq;
181         unsigned char bulk_buf[4];
182
183         if (ads == 0x003f08) {
184                 ret = reg_read(gspca_dev, 0x0704, &value);
185                 if (ret < 0)
186                         goto ko;
187                 ret = reg_read(gspca_dev, 0x0705, &seq);
188                 if (ret < 0)
189                         goto ko;
190                 ret = reg_read(gspca_dev, 0x0650, &value);
191                 if (ret < 0)
192                         goto ko;
193                 reg_write(gspca_dev, 0x654, seq);
194         } else
195                 reg_write(gspca_dev, 0x654, (ads >> 16) & 0xff);
196         reg_write(gspca_dev, 0x655, (ads >> 8) & 0xff);
197         reg_write(gspca_dev, 0x656, ads & 0xff);
198         reg_write(gspca_dev, 0x657, 0);
199         reg_write(gspca_dev, 0x658, 0x04);      /* size */
200         reg_write(gspca_dev, 0x659, 0);
201         reg_write(gspca_dev, 0x65a, 0);
202         reg_write(gspca_dev, 0x65b, 0);
203         reg_write(gspca_dev, 0x650, 5);
204         bulk_buf[0] = (val >> 24) & 0xff;
205         bulk_buf[1] = (val >> 16) & 0xff;
206         bulk_buf[2] = (val >> 8) & 0xff;
207         bulk_buf[3] = val & 0xff;
208         ret = usb_bulk_msg(dev,
209                         usb_sndbulkpipe(dev, 6),
210                         bulk_buf,
211                         4,
212                         &alen,
213                         500);   /* timeout in milliseconds */
214         if (ret < 0)
215                 goto ko;
216         if (ads == 0x003f08) {
217                 seq += 4;
218                 seq &= 0x3f;
219                 reg_write(gspca_dev, 0x705, seq);
220         }
221         return ret;
222 ko:
223         PDEBUG(D_ERR, "snd_val err %d", ret);
224         return ret;
225 }
226
227 /* set a camera parameter */
228 static int set_par(struct gspca_dev *gspca_dev,
229                    int parval)
230 {
231         return snd_val(gspca_dev, 0x003f08, parval);
232 }
233
234 static void setbrightness(struct gspca_dev *gspca_dev)
235 {
236         struct sd *sd = (struct sd *) gspca_dev;
237         int parval;
238
239         PDEBUG(D_CONF, "brightness: %d", sd->brightness);
240         parval = 0x06000000             /* whiteness */
241                 + (sd->brightness << 16);
242         set_par(gspca_dev, parval);
243 }
244
245 static void setcontrast(struct gspca_dev *gspca_dev)
246 {
247         struct sd *sd = (struct sd *) gspca_dev;
248         int parval;
249
250         PDEBUG(D_CONF, "contrast: %d", sd->contrast);
251         parval = 0x07000000             /* contrast */
252                 + (sd->contrast << 16);
253         set_par(gspca_dev, parval);
254 }
255
256 static void setcolors(struct gspca_dev *gspca_dev)
257 {
258         struct sd *sd = (struct sd *) gspca_dev;
259         int parval;
260
261         PDEBUG(D_CONF, "saturation: %d",
262                 sd->colors);
263         parval = 0x08000000             /* saturation */
264                 + (sd->colors << 16);
265         set_par(gspca_dev, parval);
266 }
267
268 /* this function is called at probe time */
269 static int sd_config(struct gspca_dev *gspca_dev,
270                         const struct usb_device_id *id)
271 {
272         struct sd *sd = (struct sd *) gspca_dev;
273         struct cam *cam = &gspca_dev->cam;
274
275         cam->dev_name = (char *) id->driver_info;
276         cam->epaddr = 0x02;
277         gspca_dev->cam.cam_mode = vga_mode;
278         gspca_dev->cam.nmodes = sizeof vga_mode / sizeof vga_mode[0];
279         sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
280         sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
281         sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value;
282         return 0;
283 }
284
285 /* this function is called at open time */
286 static int sd_open(struct gspca_dev *gspca_dev)
287 {
288         __u8 value;
289         int ret;
290
291         /* check if the device responds */
292         usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1);
293         ret = reg_read(gspca_dev, 0x0740, &value);
294         if (ret < 0)
295                 return ret;
296         if (value != 0xff) {
297                 PDEBUG(D_ERR|D_STREAM, "init reg: 0x%02x", value);
298                 return -1;
299         }
300         return 0;
301 }
302
303 /* -- start the camera -- */
304 static void sd_start(struct gspca_dev *gspca_dev)
305 {
306         __u8 dum;
307         int ret, value;
308
309         /* work on alternate 1 */
310         usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1);
311
312         set_par(gspca_dev, 0x10000000);
313         set_par(gspca_dev, 0x00000000);
314         set_par(gspca_dev, 0x8002e001);
315         set_par(gspca_dev, 0x14000000);
316         if (gspca_dev->width > 320)
317                 value = 0x8002e001;             /* 640x480 */
318         else
319                 value = 0x4001f000;             /* 320x240 */
320         set_par(gspca_dev, value);
321         ret = usb_set_interface(gspca_dev->dev,
322                                         gspca_dev->iface,
323                                         gspca_dev->alt);
324         if (ret < 0)
325                 goto out;
326         ret = reg_read(gspca_dev, 0x0630, &dum);
327         if (ret < 0)
328                 goto out;
329         rcv_val(gspca_dev, 0x000020, 4);        /* << (value ff ff ff ff) */
330         ret = reg_read(gspca_dev, 0x0650, &dum);
331         if (ret < 0)
332                 goto out;
333         snd_val(gspca_dev, 0x000020, 0xffffffff);
334         reg_write(gspca_dev, 0x0620, 0);
335         reg_write(gspca_dev, 0x0630, 0);
336         reg_write(gspca_dev, 0x0640, 0);
337         reg_write(gspca_dev, 0x0650, 0);
338         reg_write(gspca_dev, 0x0660, 0);
339         setbrightness(gspca_dev);               /* whiteness */
340         setcontrast(gspca_dev);                 /* contrast */
341         setcolors(gspca_dev);                   /* saturation */
342         set_par(gspca_dev, 0x09800000);         /* Red ? */
343         set_par(gspca_dev, 0x0a800000);         /* Green ? */
344         set_par(gspca_dev, 0x0b800000);         /* Blue ? */
345         set_par(gspca_dev, 0x0d030000);         /* Gamma ? */
346         set_par(gspca_dev, lightfreq == 60
347                         ? 0x33780000            /* 60 Hz */
348                         : 0x33640000);          /* 50 Hz */
349
350         /* start the video flow */
351         set_par(gspca_dev, 0x01000000);
352         set_par(gspca_dev, 0x01000000);
353         PDEBUG(D_STREAM, "camera started alt: 0x%02x", gspca_dev->alt);
354         return;
355 out:
356         PDEBUG(D_ERR|D_STREAM, "camera start err %d", ret);
357 }
358
359 static void sd_stopN(struct gspca_dev *gspca_dev)
360 {
361         struct usb_device *dev = gspca_dev->dev;
362         __u8 value;
363
364         set_par(gspca_dev, 0x02000000);
365         set_par(gspca_dev, 0x02000000);
366         usb_set_interface(dev, gspca_dev->iface, 1);
367         reg_read(gspca_dev, 0x0630, &value);
368         rcv_val(gspca_dev, 0x000020, 4);        /* << (value ff ff ff ff) */
369         reg_read(gspca_dev, 0x0650, &value);
370         snd_val(gspca_dev, 0x000020, 0xffffffff);
371         reg_write(gspca_dev, 0x0620, 0);
372         reg_write(gspca_dev, 0x0630, 0);
373         reg_write(gspca_dev, 0x0640, 0);
374         reg_write(gspca_dev, 0x0650, 0);
375         reg_write(gspca_dev, 0x0660, 0);
376         PDEBUG(D_STREAM, "camera stopped");
377 }
378
379 static void sd_stop0(struct gspca_dev *gspca_dev)
380 {
381 }
382
383 static void sd_close(struct gspca_dev *gspca_dev)
384 {
385 }
386
387 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
388                         struct gspca_frame *frame,      /* target */
389                         unsigned char *data,            /* isoc packet */
390                         int len)                        /* iso packet length */
391 {
392         int l;
393
394         /* a frame starts with:
395          *      - 0xff 0xfe
396          *      - 0x08 0x00     // length (little endian ?!)
397          *      - 4 bytes = size of whole frame (big endian - including header)
398          *      - 0x00 0x0c
399          *      - 0xff 0xd8
400          *      - ..    JPEG image with escape sequences (ff 00)
401          */
402         if (data[0] == 0xff && data[1] == 0xfe) {
403                 if (gspca_dev->last_packet_type == INTER_PACKET) {
404                         PDEBUG(D_ERR|D_FRAM, "sof actual l: %d init l: %d",
405                                 frame->data_end - frame->data,
406                                 frame->v4l2_buf.bytesused);
407                 }
408
409                 /* put the JPEG headaer */
410                 jpeg_put_header(gspca_dev, frame, sd_quant, 0x22);
411
412                 /* beginning of the frame */
413 #define STKHDRSZ 12
414                 l = (data[4] << 24)             /* frame size */
415                         + (data[5] << 16)
416                         + (data[6] << 8)
417                         + data[7]
418                         - STKHDRSZ
419                         + (frame->data_end - frame->data)
420                         + 2;                    /* EOF (ff d9) */
421                 gspca_frame_add(gspca_dev, INTER_PACKET, frame,
422                                 data + STKHDRSZ, len - STKHDRSZ);
423 #undef STKHDRSZ
424                 frame->v4l2_buf.bytesused = l;
425                 return;
426         }
427         if (gspca_dev->last_packet_type != INTER_PACKET) {
428                 if (gspca_dev->last_packet_type == LAST_PACKET) {
429                         PDEBUG(D_ERR|D_PACK, "mof actual l: %d init l: %d",
430                                 frame->data_end - frame->data,
431                                 frame->v4l2_buf.bytesused);
432                 }
433                 return;
434         }
435
436         /* intermediate packet */
437         l = frame->data_end - frame->data;
438         if (len < frame->v4l2_buf.bytesused - 2 - l) {
439                 gspca_frame_add(gspca_dev, INTER_PACKET, frame,
440                                 data, len);
441                 return;
442         }
443
444         /* last packet */
445         if (len > frame->v4l2_buf.bytesused - 2 - l)
446                 len = frame->v4l2_buf.bytesused - 2 - l;
447         gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
448         gspca_frame_add(gspca_dev, LAST_PACKET, frame, "\xff\xd9", 2);
449 }
450
451 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
452 {
453         struct sd *sd = (struct sd *) gspca_dev;
454
455         sd->brightness = val;
456         if (gspca_dev->streaming)
457                 setbrightness(gspca_dev);
458         return 0;
459 }
460
461 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
462 {
463         struct sd *sd = (struct sd *) gspca_dev;
464
465         *val = sd->brightness;
466         return 0;
467 }
468
469 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
470 {
471         struct sd *sd = (struct sd *) gspca_dev;
472
473         sd->contrast = val;
474         if (gspca_dev->streaming)
475                 setcontrast(gspca_dev);
476         return 0;
477 }
478
479 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
480 {
481         struct sd *sd = (struct sd *) gspca_dev;
482
483         *val = sd->contrast;
484         return 0;
485 }
486
487 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
488 {
489         struct sd *sd = (struct sd *) gspca_dev;
490
491         sd->colors = val;
492         if (gspca_dev->streaming)
493                 setcolors(gspca_dev);
494         return 0;
495 }
496
497 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
498 {
499         struct sd *sd = (struct sd *) gspca_dev;
500
501         *val = sd->colors;
502         return 0;
503 }
504
505 /* sub-driver description */
506 static struct sd_desc sd_desc = {
507         .name = MODULE_NAME,
508         .ctrls = sd_ctrls,
509         .nctrls = sizeof sd_ctrls / sizeof sd_ctrls[0],
510         .config = sd_config,
511         .open = sd_open,
512         .start = sd_start,
513         .stopN = sd_stopN,
514         .stop0 = sd_stop0,
515         .close = sd_close,
516         .pkt_scan = sd_pkt_scan,
517 };
518
519 /* -- module initialisation -- */
520 #define DVNM(name) .driver_info = (kernel_ulong_t) name
521 static __devinitdata struct usb_device_id device_table[] = {
522         {USB_DEVICE(0x05e1, 0x0893), DVNM("Syntek DV4000")},
523         {}
524 };
525 MODULE_DEVICE_TABLE(usb, device_table);
526
527 /* -- device connect -- */
528 static int sd_probe(struct usb_interface *intf,
529                         const struct usb_device_id *id)
530 {
531         PDEBUG(D_PROBE, "camera probe");
532         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd));
533 }
534
535 static struct usb_driver sd_driver = {
536         .name = MODULE_NAME,
537         .id_table = device_table,
538         .probe = sd_probe,
539         .disconnect = gspca_disconnect,
540 };
541
542 /* -- module insert / remove -- */
543 static int __init sd_mod_init(void)
544 {
545         if (usb_register(&sd_driver) < 0)
546                 return -1;
547         info("v%s registered", version);
548         return 0;
549 }
550 static void __exit sd_mod_exit(void)
551 {
552         usb_deregister(&sd_driver);
553         info("deregistered");
554 }
555
556 module_init(sd_mod_init);
557 module_exit(sd_mod_exit);
558
559 module_param(lightfreq, int, 0644);
560 MODULE_PARM_DESC(lightfreq, "Light frequency 50 or 60 Hz");
561 module_param_named(quant, sd_quant, int, 0644);
562 MODULE_PARM_DESC(quant, "Quantization index (0..8)");