Version:  2.0.40 2.2.26 2.4.37 2.6.39 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15

Linux/drivers/media/usb/gspca/stk014.c

  1 /*
  2  * Syntek DV4000 (STK014) subdriver
  3  *
  4  * Copyright (C) 2008 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 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 22 
 23 #define MODULE_NAME "stk014"
 24 
 25 #include "gspca.h"
 26 #include "jpeg.h"
 27 
 28 MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
 29 MODULE_DESCRIPTION("Syntek DV4000 (STK014) USB Camera Driver");
 30 MODULE_LICENSE("GPL");
 31 
 32 #define QUALITY 50
 33 
 34 /* specific webcam descriptor */
 35 struct sd {
 36         struct gspca_dev gspca_dev;     /* !! must be the first item */
 37         u8 jpeg_hdr[JPEG_HDR_SZ];
 38 };
 39 
 40 static const struct v4l2_pix_format vga_mode[] = {
 41         {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
 42                 .bytesperline = 320,
 43                 .sizeimage = 320 * 240 * 3 / 8 + 590,
 44                 .colorspace = V4L2_COLORSPACE_JPEG,
 45                 .priv = 1},
 46         {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
 47                 .bytesperline = 640,
 48                 .sizeimage = 640 * 480 * 3 / 8 + 590,
 49                 .colorspace = V4L2_COLORSPACE_JPEG,
 50                 .priv = 0},
 51 };
 52 
 53 /* -- read a register -- */
 54 static u8 reg_r(struct gspca_dev *gspca_dev,
 55                         __u16 index)
 56 {
 57         struct usb_device *dev = gspca_dev->dev;
 58         int ret;
 59 
 60         if (gspca_dev->usb_err < 0)
 61                 return 0;
 62         ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
 63                         0x00,
 64                         USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 65                         0x00,
 66                         index,
 67                         gspca_dev->usb_buf, 1,
 68                         500);
 69         if (ret < 0) {
 70                 pr_err("reg_r err %d\n", ret);
 71                 gspca_dev->usb_err = ret;
 72                 return 0;
 73         }
 74         return gspca_dev->usb_buf[0];
 75 }
 76 
 77 /* -- write a register -- */
 78 static void reg_w(struct gspca_dev *gspca_dev,
 79                         __u16 index, __u16 value)
 80 {
 81         struct usb_device *dev = gspca_dev->dev;
 82         int ret;
 83 
 84         if (gspca_dev->usb_err < 0)
 85                 return;
 86         ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
 87                         0x01,
 88                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 89                         value,
 90                         index,
 91                         NULL,
 92                         0,
 93                         500);
 94         if (ret < 0) {
 95                 pr_err("reg_w err %d\n", ret);
 96                 gspca_dev->usb_err = ret;
 97         }
 98 }
 99 
100 /* -- get a bulk value (4 bytes) -- */
101 static void rcv_val(struct gspca_dev *gspca_dev,
102                         int ads)
103 {
104         struct usb_device *dev = gspca_dev->dev;
105         int alen, ret;
106 
107         reg_w(gspca_dev, 0x634, (ads >> 16) & 0xff);
108         reg_w(gspca_dev, 0x635, (ads >> 8) & 0xff);
109         reg_w(gspca_dev, 0x636, ads & 0xff);
110         reg_w(gspca_dev, 0x637, 0);
111         reg_w(gspca_dev, 0x638, 4);     /* len & 0xff */
112         reg_w(gspca_dev, 0x639, 0);     /* len >> 8 */
113         reg_w(gspca_dev, 0x63a, 0);
114         reg_w(gspca_dev, 0x63b, 0);
115         reg_w(gspca_dev, 0x630, 5);
116         if (gspca_dev->usb_err < 0)
117                 return;
118         ret = usb_bulk_msg(dev,
119                         usb_rcvbulkpipe(dev, 0x05),
120                         gspca_dev->usb_buf,
121                         4,              /* length */
122                         &alen,
123                         500);           /* timeout in milliseconds */
124         if (ret < 0) {
125                 pr_err("rcv_val err %d\n", ret);
126                 gspca_dev->usb_err = ret;
127         }
128 }
129 
130 /* -- send a bulk value -- */
131 static void snd_val(struct gspca_dev *gspca_dev,
132                         int ads,
133                         unsigned int val)
134 {
135         struct usb_device *dev = gspca_dev->dev;
136         int alen, ret;
137         __u8 seq = 0;
138 
139         if (ads == 0x003f08) {
140                 reg_r(gspca_dev, 0x0704);
141                 seq = reg_r(gspca_dev, 0x0705);
142                 reg_r(gspca_dev, 0x0650);
143                 reg_w(gspca_dev, 0x654, seq);
144         } else {
145                 reg_w(gspca_dev, 0x654, (ads >> 16) & 0xff);
146         }
147         reg_w(gspca_dev, 0x655, (ads >> 8) & 0xff);
148         reg_w(gspca_dev, 0x656, ads & 0xff);
149         reg_w(gspca_dev, 0x657, 0);
150         reg_w(gspca_dev, 0x658, 0x04);  /* size */
151         reg_w(gspca_dev, 0x659, 0);
152         reg_w(gspca_dev, 0x65a, 0);
153         reg_w(gspca_dev, 0x65b, 0);
154         reg_w(gspca_dev, 0x650, 5);
155         if (gspca_dev->usb_err < 0)
156                 return;
157         gspca_dev->usb_buf[0] = val >> 24;
158         gspca_dev->usb_buf[1] = val >> 16;
159         gspca_dev->usb_buf[2] = val >> 8;
160         gspca_dev->usb_buf[3] = val;
161         ret = usb_bulk_msg(dev,
162                         usb_sndbulkpipe(dev, 6),
163                         gspca_dev->usb_buf,
164                         4,
165                         &alen,
166                         500);   /* timeout in milliseconds */
167         if (ret < 0) {
168                 pr_err("snd_val err %d\n", ret);
169                 gspca_dev->usb_err = ret;
170         } else {
171                 if (ads == 0x003f08) {
172                         seq += 4;
173                         seq &= 0x3f;
174                         reg_w(gspca_dev, 0x705, seq);
175                 }
176         }
177 }
178 
179 /* set a camera parameter */
180 static void set_par(struct gspca_dev *gspca_dev,
181                    int parval)
182 {
183         snd_val(gspca_dev, 0x003f08, parval);
184 }
185 
186 static void setbrightness(struct gspca_dev *gspca_dev, s32 val)
187 {
188         int parval;
189 
190         parval = 0x06000000             /* whiteness */
191                 + (val << 16);
192         set_par(gspca_dev, parval);
193 }
194 
195 static void setcontrast(struct gspca_dev *gspca_dev, s32 val)
196 {
197         int parval;
198 
199         parval = 0x07000000             /* contrast */
200                 + (val << 16);
201         set_par(gspca_dev, parval);
202 }
203 
204 static void setcolors(struct gspca_dev *gspca_dev, s32 val)
205 {
206         int parval;
207 
208         parval = 0x08000000             /* saturation */
209                 + (val << 16);
210         set_par(gspca_dev, parval);
211 }
212 
213 static void setlightfreq(struct gspca_dev *gspca_dev, s32 val)
214 {
215         set_par(gspca_dev, val == 1
216                         ? 0x33640000            /* 50 Hz */
217                         : 0x33780000);          /* 60 Hz */
218 }
219 
220 /* this function is called at probe time */
221 static int sd_config(struct gspca_dev *gspca_dev,
222                         const struct usb_device_id *id)
223 {
224         gspca_dev->cam.cam_mode = vga_mode;
225         gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode);
226         return 0;
227 }
228 
229 /* this function is called at probe and resume time */
230 static int sd_init(struct gspca_dev *gspca_dev)
231 {
232         u8 ret;
233 
234         /* check if the device responds */
235         usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1);
236         ret = reg_r(gspca_dev, 0x0740);
237         if (gspca_dev->usb_err >= 0) {
238                 if (ret != 0xff) {
239                         pr_err("init reg: 0x%02x\n", ret);
240                         gspca_dev->usb_err = -EIO;
241                 }
242         }
243         return gspca_dev->usb_err;
244 }
245 
246 /* -- start the camera -- */
247 static int sd_start(struct gspca_dev *gspca_dev)
248 {
249         struct sd *sd = (struct sd *) gspca_dev;
250         int ret, value;
251 
252         /* create the JPEG header */
253         jpeg_define(sd->jpeg_hdr, gspca_dev->pixfmt.height,
254                         gspca_dev->pixfmt.width,
255                         0x22);          /* JPEG 411 */
256         jpeg_set_qual(sd->jpeg_hdr, QUALITY);
257 
258         /* work on alternate 1 */
259         usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1);
260 
261         set_par(gspca_dev, 0x10000000);
262         set_par(gspca_dev, 0x00000000);
263         set_par(gspca_dev, 0x8002e001);
264         set_par(gspca_dev, 0x14000000);
265         if (gspca_dev->pixfmt.width > 320)
266                 value = 0x8002e001;             /* 640x480 */
267         else
268                 value = 0x4001f000;             /* 320x240 */
269         set_par(gspca_dev, value);
270         ret = usb_set_interface(gspca_dev->dev,
271                                         gspca_dev->iface,
272                                         gspca_dev->alt);
273         if (ret < 0) {
274                 pr_err("set intf %d %d failed\n",
275                        gspca_dev->iface, gspca_dev->alt);
276                 gspca_dev->usb_err = ret;
277                 goto out;
278         }
279          reg_r(gspca_dev, 0x0630);
280         rcv_val(gspca_dev, 0x000020);   /* << (value ff ff ff ff) */
281         reg_r(gspca_dev, 0x0650);
282         snd_val(gspca_dev, 0x000020, 0xffffffff);
283         reg_w(gspca_dev, 0x0620, 0);
284         reg_w(gspca_dev, 0x0630, 0);
285         reg_w(gspca_dev, 0x0640, 0);
286         reg_w(gspca_dev, 0x0650, 0);
287         reg_w(gspca_dev, 0x0660, 0);
288         set_par(gspca_dev, 0x09800000);         /* Red ? */
289         set_par(gspca_dev, 0x0a800000);         /* Green ? */
290         set_par(gspca_dev, 0x0b800000);         /* Blue ? */
291         set_par(gspca_dev, 0x0d030000);         /* Gamma ? */
292 
293         /* start the video flow */
294         set_par(gspca_dev, 0x01000000);
295         set_par(gspca_dev, 0x01000000);
296         if (gspca_dev->usb_err >= 0)
297                 PDEBUG(D_STREAM, "camera started alt: 0x%02x",
298                                 gspca_dev->alt);
299 out:
300         return gspca_dev->usb_err;
301 }
302 
303 static void sd_stopN(struct gspca_dev *gspca_dev)
304 {
305         struct usb_device *dev = gspca_dev->dev;
306 
307         set_par(gspca_dev, 0x02000000);
308         set_par(gspca_dev, 0x02000000);
309         usb_set_interface(dev, gspca_dev->iface, 1);
310         reg_r(gspca_dev, 0x0630);
311         rcv_val(gspca_dev, 0x000020);   /* << (value ff ff ff ff) */
312         reg_r(gspca_dev, 0x0650);
313         snd_val(gspca_dev, 0x000020, 0xffffffff);
314         reg_w(gspca_dev, 0x0620, 0);
315         reg_w(gspca_dev, 0x0630, 0);
316         reg_w(gspca_dev, 0x0640, 0);
317         reg_w(gspca_dev, 0x0650, 0);
318         reg_w(gspca_dev, 0x0660, 0);
319         PDEBUG(D_STREAM, "camera stopped");
320 }
321 
322 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
323                         u8 *data,                       /* isoc packet */
324                         int len)                        /* iso packet length */
325 {
326         struct sd *sd = (struct sd *) gspca_dev;
327         static unsigned char ffd9[] = {0xff, 0xd9};
328 
329         /* a frame starts with:
330          *      - 0xff 0xfe
331          *      - 0x08 0x00     - length (little endian ?!)
332          *      - 4 bytes = size of whole frame (BE - including header)
333          *      - 0x00 0x0c
334          *      - 0xff 0xd8
335          *      - ..    JPEG image with escape sequences (ff 00)
336          *              (without ending - ff d9)
337          */
338         if (data[0] == 0xff && data[1] == 0xfe) {
339                 gspca_frame_add(gspca_dev, LAST_PACKET,
340                                 ffd9, 2);
341 
342                 /* put the JPEG 411 header */
343                 gspca_frame_add(gspca_dev, FIRST_PACKET,
344                         sd->jpeg_hdr, JPEG_HDR_SZ);
345 
346                 /* beginning of the frame */
347 #define STKHDRSZ 12
348                 data += STKHDRSZ;
349                 len -= STKHDRSZ;
350         }
351         gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
352 }
353 
354 static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
355 {
356         struct gspca_dev *gspca_dev =
357                 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
358 
359         gspca_dev->usb_err = 0;
360 
361         if (!gspca_dev->streaming)
362                 return 0;
363 
364         switch (ctrl->id) {
365         case V4L2_CID_BRIGHTNESS:
366                 setbrightness(gspca_dev, ctrl->val);
367                 break;
368         case V4L2_CID_CONTRAST:
369                 setcontrast(gspca_dev, ctrl->val);
370                 break;
371         case V4L2_CID_SATURATION:
372                 setcolors(gspca_dev, ctrl->val);
373                 break;
374         case V4L2_CID_POWER_LINE_FREQUENCY:
375                 setlightfreq(gspca_dev, ctrl->val);
376                 break;
377         }
378         return gspca_dev->usb_err;
379 }
380 
381 static const struct v4l2_ctrl_ops sd_ctrl_ops = {
382         .s_ctrl = sd_s_ctrl,
383 };
384 
385 static int sd_init_controls(struct gspca_dev *gspca_dev)
386 {
387         struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
388 
389         gspca_dev->vdev.ctrl_handler = hdl;
390         v4l2_ctrl_handler_init(hdl, 4);
391         v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
392                         V4L2_CID_BRIGHTNESS, 0, 255, 1, 127);
393         v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
394                         V4L2_CID_CONTRAST, 0, 255, 1, 127);
395         v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
396                         V4L2_CID_SATURATION, 0, 255, 1, 127);
397         v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops,
398                         V4L2_CID_POWER_LINE_FREQUENCY,
399                         V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 1,
400                         V4L2_CID_POWER_LINE_FREQUENCY_50HZ);
401 
402         if (hdl->error) {
403                 pr_err("Could not initialize controls\n");
404                 return hdl->error;
405         }
406         return 0;
407 }
408 
409 /* sub-driver description */
410 static const struct sd_desc sd_desc = {
411         .name = MODULE_NAME,
412         .config = sd_config,
413         .init = sd_init,
414         .init_controls = sd_init_controls,
415         .start = sd_start,
416         .stopN = sd_stopN,
417         .pkt_scan = sd_pkt_scan,
418 };
419 
420 /* -- module initialisation -- */
421 static const struct usb_device_id device_table[] = {
422         {USB_DEVICE(0x05e1, 0x0893)},
423         {}
424 };
425 MODULE_DEVICE_TABLE(usb, device_table);
426 
427 /* -- device connect -- */
428 static int sd_probe(struct usb_interface *intf,
429                         const struct usb_device_id *id)
430 {
431         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
432                                 THIS_MODULE);
433 }
434 
435 static struct usb_driver sd_driver = {
436         .name = MODULE_NAME,
437         .id_table = device_table,
438         .probe = sd_probe,
439         .disconnect = gspca_disconnect,
440 #ifdef CONFIG_PM
441         .suspend = gspca_suspend,
442         .resume = gspca_resume,
443         .reset_resume = gspca_resume,
444 #endif
445 };
446 
447 module_usb_driver(sd_driver);
448 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us