Version:  2.0.40 2.2.26 2.4.37 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 3.16 3.17

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

  1 /*
  2  *              Pixart PAC7311 library
  3  *              Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li
  4  *
  5  * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
  6  *
  7  * This program is free software; you can redistribute it and/or modify
  8  * it under the terms of the GNU General Public License as published by
  9  * the Free Software Foundation; either version 2 of the License, or
 10  * any later version.
 11  *
 12  * This program is distributed in the hope that it will be useful,
 13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 15  * GNU General Public License for more details.
 16  *
 17  * You should have received a copy of the GNU General Public License
 18  * along with this program; if not, write to the Free Software
 19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 20  */
 21 
 22 /* Some documentation about various registers as determined by trial and error.
 23  *
 24  * Register page 1:
 25  *
 26  * Address      Description
 27  * 0x08         Unknown compressor related, must always be 8 except when not
 28  *              in 640x480 resolution and page 4 reg 2 <= 3 then set it to 9 !
 29  * 0x1b         Auto white balance related, bit 0 is AWB enable (inverted)
 30  *              bits 345 seem to toggle per color gains on/off (inverted)
 31  * 0x78         Global control, bit 6 controls the LED (inverted)
 32  * 0x80         Compression balance, interesting settings:
 33  *              0x01 Use this to allow the camera to switch to higher compr.
 34  *                   on the fly. Needed to stay within bandwidth @ 640x480@30
 35  *              0x1c From usb captures under Windows for 640x480
 36  *              0x2a Values >= this switch the camera to a lower compression,
 37  *                   using the same table for both luminance and chrominance.
 38  *                   This gives a sharper picture. Usable only at 640x480@ <
 39  *                   15 fps or 320x240 / 160x120. Note currently the driver
 40  *                   does not use this as the quality gain is small and the
 41  *                   generated JPG-s are only understood by v4l-utils >= 0.8.9
 42  *              0x3f From usb captures under Windows for 320x240
 43  *              0x69 From usb captures under Windows for 160x120
 44  *
 45  * Register page 4:
 46  *
 47  * Address      Description
 48  * 0x02         Clock divider 2-63, fps =~ 60 / val. Must be a multiple of 3 on
 49  *              the 7302, so one of 3, 6, 9, ..., except when between 6 and 12?
 50  * 0x0f         Master gain 1-245, low value = high gain
 51  * 0x10         Another gain 0-15, limited influence (1-2x gain I guess)
 52  * 0x21         Bitfield: 0-1 unused, 2-3 vflip/hflip, 4-5 unknown, 6-7 unused
 53  *              Note setting vflip disabled leads to a much lower image quality,
 54  *              so we always vflip, and tell userspace to flip it back
 55  * 0x27         Seems to toggle various gains on / off, Setting bit 7 seems to
 56  *              completely disable the analog amplification block. Set to 0x68
 57  *              for max gain, 0x14 for minimal gain.
 58  */
 59 
 60 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 61 
 62 #define MODULE_NAME "pac7311"
 63 
 64 #include <linux/input.h>
 65 #include "gspca.h"
 66 /* Include pac common sof detection functions */
 67 #include "pac_common.h"
 68 
 69 #define PAC7311_GAIN_DEFAULT     122
 70 #define PAC7311_EXPOSURE_DEFAULT   3 /* 20 fps, avoid using high compr. */
 71 
 72 MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li");
 73 MODULE_DESCRIPTION("Pixart PAC7311");
 74 MODULE_LICENSE("GPL");
 75 
 76 struct sd {
 77         struct gspca_dev gspca_dev;             /* !! must be the first item */
 78 
 79         struct v4l2_ctrl *contrast;
 80         struct v4l2_ctrl *hflip;
 81 
 82         u8 sof_read;
 83         u8 autogain_ignore_frames;
 84 
 85         atomic_t avg_lum;
 86 };
 87 
 88 static const struct v4l2_pix_format vga_mode[] = {
 89         {160, 120, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
 90                 .bytesperline = 160,
 91                 .sizeimage = 160 * 120 * 3 / 8 + 590,
 92                 .colorspace = V4L2_COLORSPACE_JPEG,
 93                 .priv = 2},
 94         {320, 240, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
 95                 .bytesperline = 320,
 96                 .sizeimage = 320 * 240 * 3 / 8 + 590,
 97                 .colorspace = V4L2_COLORSPACE_JPEG,
 98                 .priv = 1},
 99         {640, 480, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
100                 .bytesperline = 640,
101                 .sizeimage = 640 * 480 * 3 / 8 + 590,
102                 .colorspace = V4L2_COLORSPACE_JPEG,
103                 .priv = 0},
104 };
105 
106 #define LOAD_PAGE4              254
107 #define END_OF_SEQUENCE         0
108 
109 static const __u8 init_7311[] = {
110         0xff, 0x01,
111         0x78, 0x40,     /* Bit_0=start stream, Bit_6=LED */
112         0x78, 0x40,     /* Bit_0=start stream, Bit_6=LED */
113         0x78, 0x44,     /* Bit_0=start stream, Bit_6=LED */
114         0xff, 0x04,
115         0x27, 0x80,
116         0x28, 0xca,
117         0x29, 0x53,
118         0x2a, 0x0e,
119         0xff, 0x01,
120         0x3e, 0x20,
121 };
122 
123 static const __u8 start_7311[] = {
124 /*      index, len, [value]* */
125         0xff, 1,        0x01,           /* page 1 */
126         0x02, 43,       0x48, 0x0a, 0x40, 0x08, 0x00, 0x00, 0x08, 0x00,
127                         0x06, 0xff, 0x11, 0xff, 0x5a, 0x30, 0x90, 0x4c,
128                         0x00, 0x07, 0x00, 0x0a, 0x10, 0x00, 0xa0, 0x10,
129                         0x02, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x01, 0x00,
130                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
131                         0x00, 0x00, 0x00,
132         0x3e, 42,       0x00, 0x00, 0x78, 0x52, 0x4a, 0x52, 0x78, 0x6e,
133                         0x48, 0x46, 0x48, 0x6e, 0x5f, 0x49, 0x42, 0x49,
134                         0x5f, 0x5f, 0x49, 0x42, 0x49, 0x5f, 0x6e, 0x48,
135                         0x46, 0x48, 0x6e, 0x78, 0x52, 0x4a, 0x52, 0x78,
136                         0x00, 0x00, 0x09, 0x1b, 0x34, 0x49, 0x5c, 0x9b,
137                         0xd0, 0xff,
138         0x78, 6,        0x44, 0x00, 0xf2, 0x01, 0x01, 0x80,
139         0x7f, 18,       0x2a, 0x1c, 0x00, 0xc8, 0x02, 0x58, 0x03, 0x84,
140                         0x12, 0x00, 0x1a, 0x04, 0x08, 0x0c, 0x10, 0x14,
141                         0x18, 0x20,
142         0x96, 3,        0x01, 0x08, 0x04,
143         0xa0, 4,        0x44, 0x44, 0x44, 0x04,
144         0xf0, 13,       0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x20, 0x00,
145                         0x3f, 0x00, 0x0a, 0x01, 0x00,
146         0xff, 1,        0x04,           /* page 4 */
147         0, LOAD_PAGE4,                  /* load the page 4 */
148         0x11, 1,        0x01,
149         0, END_OF_SEQUENCE              /* end of sequence */
150 };
151 
152 #define SKIP            0xaa
153 /* page 4 - the value SKIP says skip the index - see reg_w_page() */
154 static const __u8 page4_7311[] = {
155         SKIP, SKIP, 0x04, 0x54, 0x07, 0x2b, 0x09, 0x0f,
156         0x09, 0x00, SKIP, SKIP, 0x07, 0x00, 0x00, 0x62,
157         0x08, SKIP, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
158         0x00, 0x00, 0x00, 0x03, 0xa0, 0x01, 0xf4, SKIP,
159         SKIP, 0x00, 0x08, SKIP, 0x03, SKIP, 0x00, 0x68,
160         0xca, 0x10, 0x06, 0x78, 0x00, 0x00, 0x00, 0x00,
161         0x23, 0x28, 0x04, 0x11, 0x00, 0x00
162 };
163 
164 static void reg_w_buf(struct gspca_dev *gspca_dev,
165                   __u8 index,
166                   const u8 *buffer, int len)
167 {
168         int ret;
169 
170         if (gspca_dev->usb_err < 0)
171                 return;
172         memcpy(gspca_dev->usb_buf, buffer, len);
173         ret = usb_control_msg(gspca_dev->dev,
174                         usb_sndctrlpipe(gspca_dev->dev, 0),
175                         0,              /* request */
176                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
177                         0,              /* value */
178                         index, gspca_dev->usb_buf, len,
179                         500);
180         if (ret < 0) {
181                 pr_err("reg_w_buf() failed index 0x%02x, error %d\n",
182                        index, ret);
183                 gspca_dev->usb_err = ret;
184         }
185 }
186 
187 
188 static void reg_w(struct gspca_dev *gspca_dev,
189                   __u8 index,
190                   __u8 value)
191 {
192         int ret;
193 
194         if (gspca_dev->usb_err < 0)
195                 return;
196         gspca_dev->usb_buf[0] = value;
197         ret = usb_control_msg(gspca_dev->dev,
198                         usb_sndctrlpipe(gspca_dev->dev, 0),
199                         0,                      /* request */
200                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
201                         0, index, gspca_dev->usb_buf, 1,
202                         500);
203         if (ret < 0) {
204                 pr_err("reg_w() failed index 0x%02x, value 0x%02x, error %d\n",
205                        index, value, ret);
206                 gspca_dev->usb_err = ret;
207         }
208 }
209 
210 static void reg_w_seq(struct gspca_dev *gspca_dev,
211                 const __u8 *seq, int len)
212 {
213         while (--len >= 0) {
214                 reg_w(gspca_dev, seq[0], seq[1]);
215                 seq += 2;
216         }
217 }
218 
219 /* load the beginning of a page */
220 static void reg_w_page(struct gspca_dev *gspca_dev,
221                         const __u8 *page, int len)
222 {
223         int index;
224         int ret = 0;
225 
226         if (gspca_dev->usb_err < 0)
227                 return;
228         for (index = 0; index < len; index++) {
229                 if (page[index] == SKIP)                /* skip this index */
230                         continue;
231                 gspca_dev->usb_buf[0] = page[index];
232                 ret = usb_control_msg(gspca_dev->dev,
233                                 usb_sndctrlpipe(gspca_dev->dev, 0),
234                                 0,                      /* request */
235                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
236                                 0, index, gspca_dev->usb_buf, 1,
237                                 500);
238                 if (ret < 0) {
239                         pr_err("reg_w_page() failed index 0x%02x, value 0x%02x, error %d\n",
240                                index, page[index], ret);
241                         gspca_dev->usb_err = ret;
242                         break;
243                 }
244         }
245 }
246 
247 /* output a variable sequence */
248 static void reg_w_var(struct gspca_dev *gspca_dev,
249                         const __u8 *seq,
250                         const __u8 *page4, unsigned int page4_len)
251 {
252         int index, len;
253 
254         for (;;) {
255                 index = *seq++;
256                 len = *seq++;
257                 switch (len) {
258                 case END_OF_SEQUENCE:
259                         return;
260                 case LOAD_PAGE4:
261                         reg_w_page(gspca_dev, page4, page4_len);
262                         break;
263                 default:
264                         if (len > USB_BUF_SZ) {
265                                 PERR("Incorrect variable sequence");
266                                 return;
267                         }
268                         while (len > 0) {
269                                 if (len < 8) {
270                                         reg_w_buf(gspca_dev,
271                                                 index, seq, len);
272                                         seq += len;
273                                         break;
274                                 }
275                                 reg_w_buf(gspca_dev, index, seq, 8);
276                                 seq += 8;
277                                 index += 8;
278                                 len -= 8;
279                         }
280                 }
281         }
282         /* not reached */
283 }
284 
285 /* this function is called at probe time for pac7311 */
286 static int sd_config(struct gspca_dev *gspca_dev,
287                         const struct usb_device_id *id)
288 {
289         struct cam *cam = &gspca_dev->cam;
290 
291         cam->cam_mode = vga_mode;
292         cam->nmodes = ARRAY_SIZE(vga_mode);
293         cam->input_flags = V4L2_IN_ST_VFLIP;
294 
295         return 0;
296 }
297 
298 static void setcontrast(struct gspca_dev *gspca_dev, s32 val)
299 {
300         reg_w(gspca_dev, 0xff, 0x04);
301         reg_w(gspca_dev, 0x10, val);
302         /* load registers to sensor (Bit 0, auto clear) */
303         reg_w(gspca_dev, 0x11, 0x01);
304 }
305 
306 static void setgain(struct gspca_dev *gspca_dev, s32 val)
307 {
308         reg_w(gspca_dev, 0xff, 0x04);                   /* page 4 */
309         reg_w(gspca_dev, 0x0e, 0x00);
310         reg_w(gspca_dev, 0x0f, gspca_dev->gain->maximum - val + 1);
311 
312         /* load registers to sensor (Bit 0, auto clear) */
313         reg_w(gspca_dev, 0x11, 0x01);
314 }
315 
316 static void setexposure(struct gspca_dev *gspca_dev, s32 val)
317 {
318         reg_w(gspca_dev, 0xff, 0x04);                   /* page 4 */
319         reg_w(gspca_dev, 0x02, val);
320 
321         /* load registers to sensor (Bit 0, auto clear) */
322         reg_w(gspca_dev, 0x11, 0x01);
323 
324         /*
325          * Page 1 register 8 must always be 0x08 except when not in
326          *  640x480 mode and page 4 reg 2 <= 3 then it must be 9
327          */
328         reg_w(gspca_dev, 0xff, 0x01);
329         if (gspca_dev->pixfmt.width != 640 && val <= 3)
330                 reg_w(gspca_dev, 0x08, 0x09);
331         else
332                 reg_w(gspca_dev, 0x08, 0x08);
333 
334         /*
335          * Page1 register 80 sets the compression balance, normally we
336          * want / use 0x1c, but for 640x480@30fps we must allow the
337          * camera to use higher compression or we may run out of
338          * bandwidth.
339          */
340         if (gspca_dev->pixfmt.width == 640 && val == 2)
341                 reg_w(gspca_dev, 0x80, 0x01);
342         else
343                 reg_w(gspca_dev, 0x80, 0x1c);
344 
345         /* load registers to sensor (Bit 0, auto clear) */
346         reg_w(gspca_dev, 0x11, 0x01);
347 }
348 
349 static void sethvflip(struct gspca_dev *gspca_dev, s32 hflip, s32 vflip)
350 {
351         __u8 data;
352 
353         reg_w(gspca_dev, 0xff, 0x04);                   /* page 4 */
354         data = (hflip ? 0x04 : 0x00) |
355                (vflip ? 0x08 : 0x00);
356         reg_w(gspca_dev, 0x21, data);
357 
358         /* load registers to sensor (Bit 0, auto clear) */
359         reg_w(gspca_dev, 0x11, 0x01);
360 }
361 
362 /* this function is called at probe and resume time for pac7311 */
363 static int sd_init(struct gspca_dev *gspca_dev)
364 {
365         reg_w_seq(gspca_dev, init_7311, sizeof(init_7311)/2);
366         return gspca_dev->usb_err;
367 }
368 
369 static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
370 {
371         struct gspca_dev *gspca_dev =
372                 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
373         struct sd *sd = (struct sd *)gspca_dev;
374 
375         gspca_dev->usb_err = 0;
376 
377         if (ctrl->id == V4L2_CID_AUTOGAIN && ctrl->is_new && ctrl->val) {
378                 /* when switching to autogain set defaults to make sure
379                    we are on a valid point of the autogain gain /
380                    exposure knee graph, and give this change time to
381                    take effect before doing autogain. */
382                 gspca_dev->exposure->val    = PAC7311_EXPOSURE_DEFAULT;
383                 gspca_dev->gain->val        = PAC7311_GAIN_DEFAULT;
384                 sd->autogain_ignore_frames  = PAC_AUTOGAIN_IGNORE_FRAMES;
385         }
386 
387         if (!gspca_dev->streaming)
388                 return 0;
389 
390         switch (ctrl->id) {
391         case V4L2_CID_CONTRAST:
392                 setcontrast(gspca_dev, ctrl->val);
393                 break;
394         case V4L2_CID_AUTOGAIN:
395                 if (gspca_dev->exposure->is_new || (ctrl->is_new && ctrl->val))
396                         setexposure(gspca_dev, gspca_dev->exposure->val);
397                 if (gspca_dev->gain->is_new || (ctrl->is_new && ctrl->val))
398                         setgain(gspca_dev, gspca_dev->gain->val);
399                 break;
400         case V4L2_CID_HFLIP:
401                 sethvflip(gspca_dev, sd->hflip->val, 1);
402                 break;
403         default:
404                 return -EINVAL;
405         }
406         return gspca_dev->usb_err;
407 }
408 
409 static const struct v4l2_ctrl_ops sd_ctrl_ops = {
410         .s_ctrl = sd_s_ctrl,
411 };
412 
413 /* this function is called at probe time */
414 static int sd_init_controls(struct gspca_dev *gspca_dev)
415 {
416         struct sd *sd = (struct sd *) gspca_dev;
417         struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
418 
419         gspca_dev->vdev.ctrl_handler = hdl;
420         v4l2_ctrl_handler_init(hdl, 5);
421 
422         sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
423                                         V4L2_CID_CONTRAST, 0, 15, 1, 7);
424         gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
425                                         V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
426         gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
427                                         V4L2_CID_EXPOSURE, 2, 63, 1,
428                                         PAC7311_EXPOSURE_DEFAULT);
429         gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
430                                         V4L2_CID_GAIN, 0, 244, 1,
431                                         PAC7311_GAIN_DEFAULT);
432         sd->hflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
433                 V4L2_CID_HFLIP, 0, 1, 1, 0);
434 
435         if (hdl->error) {
436                 pr_err("Could not initialize controls\n");
437                 return hdl->error;
438         }
439 
440         v4l2_ctrl_auto_cluster(3, &gspca_dev->autogain, 0, false);
441         return 0;
442 }
443 
444 /* -- start the camera -- */
445 static int sd_start(struct gspca_dev *gspca_dev)
446 {
447         struct sd *sd = (struct sd *) gspca_dev;
448 
449         sd->sof_read = 0;
450 
451         reg_w_var(gspca_dev, start_7311,
452                 page4_7311, sizeof(page4_7311));
453         setcontrast(gspca_dev, v4l2_ctrl_g_ctrl(sd->contrast));
454         setgain(gspca_dev, v4l2_ctrl_g_ctrl(gspca_dev->gain));
455         setexposure(gspca_dev, v4l2_ctrl_g_ctrl(gspca_dev->exposure));
456         sethvflip(gspca_dev, v4l2_ctrl_g_ctrl(sd->hflip), 1);
457 
458         /* set correct resolution */
459         switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
460         case 2:                                 /* 160x120 */
461                 reg_w(gspca_dev, 0xff, 0x01);
462                 reg_w(gspca_dev, 0x17, 0x20);
463                 reg_w(gspca_dev, 0x87, 0x10);
464                 break;
465         case 1:                                 /* 320x240 */
466                 reg_w(gspca_dev, 0xff, 0x01);
467                 reg_w(gspca_dev, 0x17, 0x30);
468                 reg_w(gspca_dev, 0x87, 0x11);
469                 break;
470         case 0:                                 /* 640x480 */
471                 reg_w(gspca_dev, 0xff, 0x01);
472                 reg_w(gspca_dev, 0x17, 0x00);
473                 reg_w(gspca_dev, 0x87, 0x12);
474                 break;
475         }
476 
477         sd->sof_read = 0;
478         sd->autogain_ignore_frames = 0;
479         atomic_set(&sd->avg_lum, -1);
480 
481         /* start stream */
482         reg_w(gspca_dev, 0xff, 0x01);
483         reg_w(gspca_dev, 0x78, 0x05);
484 
485         return gspca_dev->usb_err;
486 }
487 
488 static void sd_stopN(struct gspca_dev *gspca_dev)
489 {
490         reg_w(gspca_dev, 0xff, 0x04);
491         reg_w(gspca_dev, 0x27, 0x80);
492         reg_w(gspca_dev, 0x28, 0xca);
493         reg_w(gspca_dev, 0x29, 0x53);
494         reg_w(gspca_dev, 0x2a, 0x0e);
495         reg_w(gspca_dev, 0xff, 0x01);
496         reg_w(gspca_dev, 0x3e, 0x20);
497         reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
498         reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
499         reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
500 }
501 
502 static void do_autogain(struct gspca_dev *gspca_dev)
503 {
504         struct sd *sd = (struct sd *) gspca_dev;
505         int avg_lum = atomic_read(&sd->avg_lum);
506         int desired_lum, deadzone;
507 
508         if (avg_lum == -1)
509                 return;
510 
511         desired_lum = 170;
512         deadzone = 20;
513 
514         if (sd->autogain_ignore_frames > 0)
515                 sd->autogain_ignore_frames--;
516         else if (gspca_coarse_grained_expo_autogain(gspca_dev, avg_lum,
517                                                     desired_lum, deadzone))
518                 sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES;
519 }
520 
521 /* JPEG header, part 1 */
522 static const unsigned char pac_jpeg_header1[] = {
523   0xff, 0xd8,           /* SOI: Start of Image */
524 
525   0xff, 0xc0,           /* SOF0: Start of Frame (Baseline DCT) */
526   0x00, 0x11,           /* length = 17 bytes (including this length field) */
527   0x08                  /* Precision: 8 */
528   /* 2 bytes is placed here: number of image lines */
529   /* 2 bytes is placed here: samples per line */
530 };
531 
532 /* JPEG header, continued */
533 static const unsigned char pac_jpeg_header2[] = {
534   0x03,                 /* Number of image components: 3 */
535   0x01, 0x21, 0x00,     /* ID=1, Subsampling 1x1, Quantization table: 0 */
536   0x02, 0x11, 0x01,     /* ID=2, Subsampling 2x1, Quantization table: 1 */
537   0x03, 0x11, 0x01,     /* ID=3, Subsampling 2x1, Quantization table: 1 */
538 
539   0xff, 0xda,           /* SOS: Start Of Scan */
540   0x00, 0x0c,           /* length = 12 bytes (including this length field) */
541   0x03,                 /* number of components: 3 */
542   0x01, 0x00,           /* selector 1, table 0x00 */
543   0x02, 0x11,           /* selector 2, table 0x11 */
544   0x03, 0x11,           /* selector 3, table 0x11 */
545   0x00, 0x3f,           /* Spectral selection: 0 .. 63 */
546   0x00                  /* Successive approximation: 0 */
547 };
548 
549 static void pac_start_frame(struct gspca_dev *gspca_dev,
550                 __u16 lines, __u16 samples_per_line)
551 {
552         unsigned char tmpbuf[4];
553 
554         gspca_frame_add(gspca_dev, FIRST_PACKET,
555                 pac_jpeg_header1, sizeof(pac_jpeg_header1));
556 
557         tmpbuf[0] = lines >> 8;
558         tmpbuf[1] = lines & 0xff;
559         tmpbuf[2] = samples_per_line >> 8;
560         tmpbuf[3] = samples_per_line & 0xff;
561 
562         gspca_frame_add(gspca_dev, INTER_PACKET,
563                 tmpbuf, sizeof(tmpbuf));
564         gspca_frame_add(gspca_dev, INTER_PACKET,
565                 pac_jpeg_header2, sizeof(pac_jpeg_header2));
566 }
567 
568 /* this function is run at interrupt level */
569 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
570                         u8 *data,                       /* isoc packet */
571                         int len)                        /* iso packet length */
572 {
573         struct sd *sd = (struct sd *) gspca_dev;
574         u8 *image;
575         unsigned char *sof;
576 
577         sof = pac_find_sof(gspca_dev, &sd->sof_read, data, len);
578         if (sof) {
579                 int n, lum_offset, footer_length;
580 
581                 /*
582                  * 6 bytes after the FF D9 EOF marker a number of lumination
583                  * bytes are send corresponding to different parts of the
584                  * image, the 14th and 15th byte after the EOF seem to
585                  * correspond to the center of the image.
586                  */
587                 lum_offset = 24 + sizeof pac_sof_marker;
588                 footer_length = 26;
589 
590                 /* Finish decoding current frame */
591                 n = (sof - data) - (footer_length + sizeof pac_sof_marker);
592                 if (n < 0) {
593                         gspca_dev->image_len += n;
594                         n = 0;
595                 } else {
596                         gspca_frame_add(gspca_dev, INTER_PACKET, data, n);
597                 }
598                 image = gspca_dev->image;
599                 if (image != NULL
600                  && image[gspca_dev->image_len - 2] == 0xff
601                  && image[gspca_dev->image_len - 1] == 0xd9)
602                         gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
603 
604                 n = sof - data;
605                 len -= n;
606                 data = sof;
607 
608                 /* Get average lumination */
609                 if (gspca_dev->last_packet_type == LAST_PACKET &&
610                                 n >= lum_offset)
611                         atomic_set(&sd->avg_lum, data[-lum_offset] +
612                                                 data[-lum_offset + 1]);
613                 else
614                         atomic_set(&sd->avg_lum, -1);
615 
616                 /* Start the new frame with the jpeg header */
617                 pac_start_frame(gspca_dev,
618                         gspca_dev->pixfmt.height, gspca_dev->pixfmt.width);
619         }
620         gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
621 }
622 
623 #if IS_ENABLED(CONFIG_INPUT)
624 static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
625                         u8 *data,               /* interrupt packet data */
626                         int len)                /* interrupt packet length */
627 {
628         int ret = -EINVAL;
629         u8 data0, data1;
630 
631         if (len == 2) {
632                 data0 = data[0];
633                 data1 = data[1];
634                 if ((data0 == 0x00 && data1 == 0x11) ||
635                     (data0 == 0x22 && data1 == 0x33) ||
636                     (data0 == 0x44 && data1 == 0x55) ||
637                     (data0 == 0x66 && data1 == 0x77) ||
638                     (data0 == 0x88 && data1 == 0x99) ||
639                     (data0 == 0xaa && data1 == 0xbb) ||
640                     (data0 == 0xcc && data1 == 0xdd) ||
641                     (data0 == 0xee && data1 == 0xff)) {
642                         input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
643                         input_sync(gspca_dev->input_dev);
644                         input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
645                         input_sync(gspca_dev->input_dev);
646                         ret = 0;
647                 }
648         }
649 
650         return ret;
651 }
652 #endif
653 
654 static const struct sd_desc sd_desc = {
655         .name = MODULE_NAME,
656         .config = sd_config,
657         .init = sd_init,
658         .init_controls = sd_init_controls,
659         .start = sd_start,
660         .stopN = sd_stopN,
661         .pkt_scan = sd_pkt_scan,
662         .dq_callback = do_autogain,
663 #if IS_ENABLED(CONFIG_INPUT)
664         .int_pkt_scan = sd_int_pkt_scan,
665 #endif
666 };
667 
668 /* -- module initialisation -- */
669 static const struct usb_device_id device_table[] = {
670         {USB_DEVICE(0x093a, 0x2600)},
671         {USB_DEVICE(0x093a, 0x2601)},
672         {USB_DEVICE(0x093a, 0x2603)},
673         {USB_DEVICE(0x093a, 0x2608)},
674         {USB_DEVICE(0x093a, 0x260e)},
675         {USB_DEVICE(0x093a, 0x260f)},
676         {}
677 };
678 MODULE_DEVICE_TABLE(usb, device_table);
679 
680 /* -- device connect -- */
681 static int sd_probe(struct usb_interface *intf,
682                         const struct usb_device_id *id)
683 {
684         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
685                                 THIS_MODULE);
686 }
687 
688 static struct usb_driver sd_driver = {
689         .name = MODULE_NAME,
690         .id_table = device_table,
691         .probe = sd_probe,
692         .disconnect = gspca_disconnect,
693 #ifdef CONFIG_PM
694         .suspend = gspca_suspend,
695         .resume = gspca_resume,
696         .reset_resume = gspca_resume,
697 #endif
698 };
699 
700 module_usb_driver(sd_driver);
701 

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