Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
pac7311.c
Go to the documentation of this file.
1 /*
2  * Pixart PAC7311 library
3  * Copyright (C) 2005 Thomas Kaiser [email protected]
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 [email protected]");
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;
84 
86 };
87 
88 static const struct v4l2_pix_format vga_mode[] = {
90  .bytesperline = 160,
91  .sizeimage = 160 * 120 * 3 / 8 + 590,
92  .colorspace = V4L2_COLORSPACE_JPEG,
93  .priv = 2},
95  .bytesperline = 320,
96  .sizeimage = 320 * 240 * 3 / 8 + 590,
97  .colorspace = V4L2_COLORSPACE_JPEG,
98  .priv = 1},
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 */
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 */
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 */
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  PDEBUG(D_ERR|D_STREAM,
266  "Incorrect variable sequence");
267  return;
268  }
269  while (len > 0) {
270  if (len < 8) {
271  reg_w_buf(gspca_dev,
272  index, seq, len);
273  seq += len;
274  break;
275  }
276  reg_w_buf(gspca_dev, index, seq, 8);
277  seq += 8;
278  index += 8;
279  len -= 8;
280  }
281  }
282  }
283  /* not reached */
284 }
285 
286 /* this function is called at probe time for pac7311 */
287 static int sd_config(struct gspca_dev *gspca_dev,
288  const struct usb_device_id *id)
289 {
290  struct cam *cam = &gspca_dev->cam;
291 
292  cam->cam_mode = vga_mode;
293  cam->nmodes = ARRAY_SIZE(vga_mode);
295 
296  return 0;
297 }
298 
299 static void setcontrast(struct gspca_dev *gspca_dev, s32 val)
300 {
301  reg_w(gspca_dev, 0xff, 0x04);
302  reg_w(gspca_dev, 0x10, val);
303  /* load registers to sensor (Bit 0, auto clear) */
304  reg_w(gspca_dev, 0x11, 0x01);
305 }
306 
307 static void setgain(struct gspca_dev *gspca_dev, s32 val)
308 {
309  reg_w(gspca_dev, 0xff, 0x04); /* page 4 */
310  reg_w(gspca_dev, 0x0e, 0x00);
311  reg_w(gspca_dev, 0x0f, gspca_dev->gain->maximum - val + 1);
312 
313  /* load registers to sensor (Bit 0, auto clear) */
314  reg_w(gspca_dev, 0x11, 0x01);
315 }
316 
317 static void setexposure(struct gspca_dev *gspca_dev, s32 val)
318 {
319  reg_w(gspca_dev, 0xff, 0x04); /* page 4 */
320  reg_w(gspca_dev, 0x02, val);
321 
322  /* load registers to sensor (Bit 0, auto clear) */
323  reg_w(gspca_dev, 0x11, 0x01);
324 
325  /*
326  * Page 1 register 8 must always be 0x08 except when not in
327  * 640x480 mode and page 4 reg 2 <= 3 then it must be 9
328  */
329  reg_w(gspca_dev, 0xff, 0x01);
330  if (gspca_dev->width != 640 && val <= 3)
331  reg_w(gspca_dev, 0x08, 0x09);
332  else
333  reg_w(gspca_dev, 0x08, 0x08);
334 
335  /*
336  * Page1 register 80 sets the compression balance, normally we
337  * want / use 0x1c, but for 640x480@30fps we must allow the
338  * camera to use higher compression or we may run out of
339  * bandwidth.
340  */
341  if (gspca_dev->width == 640 && val == 2)
342  reg_w(gspca_dev, 0x80, 0x01);
343  else
344  reg_w(gspca_dev, 0x80, 0x1c);
345 
346  /* load registers to sensor (Bit 0, auto clear) */
347  reg_w(gspca_dev, 0x11, 0x01);
348 }
349 
350 static void sethvflip(struct gspca_dev *gspca_dev, s32 hflip, s32 vflip)
351 {
352  __u8 data;
353 
354  reg_w(gspca_dev, 0xff, 0x04); /* page 4 */
355  data = (hflip ? 0x04 : 0x00) |
356  (vflip ? 0x08 : 0x00);
357  reg_w(gspca_dev, 0x21, data);
358 
359  /* load registers to sensor (Bit 0, auto clear) */
360  reg_w(gspca_dev, 0x11, 0x01);
361 }
362 
363 /* this function is called at probe and resume time for pac7311 */
364 static int sd_init(struct gspca_dev *gspca_dev)
365 {
366  reg_w_seq(gspca_dev, init_7311, sizeof(init_7311)/2);
367  return gspca_dev->usb_err;
368 }
369 
370 static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
371 {
372  struct gspca_dev *gspca_dev =
373  container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
374  struct sd *sd = (struct sd *)gspca_dev;
375 
376  gspca_dev->usb_err = 0;
377 
378  if (ctrl->id == V4L2_CID_AUTOGAIN && ctrl->is_new && ctrl->val) {
379  /* when switching to autogain set defaults to make sure
380  we are on a valid point of the autogain gain /
381  exposure knee graph, and give this change time to
382  take effect before doing autogain. */
383  gspca_dev->exposure->val = PAC7311_EXPOSURE_DEFAULT;
384  gspca_dev->gain->val = PAC7311_GAIN_DEFAULT;
386  }
387 
388  if (!gspca_dev->streaming)
389  return 0;
390 
391  switch (ctrl->id) {
392  case V4L2_CID_CONTRAST:
393  setcontrast(gspca_dev, ctrl->val);
394  break;
395  case V4L2_CID_AUTOGAIN:
396  if (gspca_dev->exposure->is_new || (ctrl->is_new && ctrl->val))
397  setexposure(gspca_dev, gspca_dev->exposure->val);
398  if (gspca_dev->gain->is_new || (ctrl->is_new && ctrl->val))
399  setgain(gspca_dev, gspca_dev->gain->val);
400  break;
401  case V4L2_CID_HFLIP:
402  sethvflip(gspca_dev, sd->hflip->val, 1);
403  break;
404  default:
405  return -EINVAL;
406  }
407  return gspca_dev->usb_err;
408 }
409 
410 static const struct v4l2_ctrl_ops sd_ctrl_ops = {
411  .s_ctrl = sd_s_ctrl,
412 };
413 
414 /* this function is called at probe time */
415 static int sd_init_controls(struct gspca_dev *gspca_dev)
416 {
417  struct sd *sd = (struct sd *) gspca_dev;
418  struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
419 
420  gspca_dev->vdev.ctrl_handler = hdl;
421  v4l2_ctrl_handler_init(hdl, 5);
422 
423  sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
424  V4L2_CID_CONTRAST, 0, 15, 1, 7);
425  gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
426  V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
427  gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
428  V4L2_CID_EXPOSURE, 2, 63, 1,
430  gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
431  V4L2_CID_GAIN, 0, 244, 1,
433  sd->hflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
434  V4L2_CID_HFLIP, 0, 1, 1, 0);
435 
436  if (hdl->error) {
437  pr_err("Could not initialize controls\n");
438  return hdl->error;
439  }
440 
441  v4l2_ctrl_auto_cluster(3, &gspca_dev->autogain, 0, false);
442  return 0;
443 }
444 
445 /* -- start the camera -- */
446 static int sd_start(struct gspca_dev *gspca_dev)
447 {
448  struct sd *sd = (struct sd *) gspca_dev;
449 
450  sd->sof_read = 0;
451 
452  reg_w_var(gspca_dev, start_7311,
453  page4_7311, sizeof(page4_7311));
454  setcontrast(gspca_dev, v4l2_ctrl_g_ctrl(sd->contrast));
455  setgain(gspca_dev, v4l2_ctrl_g_ctrl(gspca_dev->gain));
456  setexposure(gspca_dev, v4l2_ctrl_g_ctrl(gspca_dev->exposure));
457  sethvflip(gspca_dev, v4l2_ctrl_g_ctrl(sd->hflip), 1);
458 
459  /* set correct resolution */
460  switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
461  case 2: /* 160x120 */
462  reg_w(gspca_dev, 0xff, 0x01);
463  reg_w(gspca_dev, 0x17, 0x20);
464  reg_w(gspca_dev, 0x87, 0x10);
465  break;
466  case 1: /* 320x240 */
467  reg_w(gspca_dev, 0xff, 0x01);
468  reg_w(gspca_dev, 0x17, 0x30);
469  reg_w(gspca_dev, 0x87, 0x11);
470  break;
471  case 0: /* 640x480 */
472  reg_w(gspca_dev, 0xff, 0x01);
473  reg_w(gspca_dev, 0x17, 0x00);
474  reg_w(gspca_dev, 0x87, 0x12);
475  break;
476  }
477 
478  sd->sof_read = 0;
479  sd->autogain_ignore_frames = 0;
480  atomic_set(&sd->avg_lum, -1);
481 
482  /* start stream */
483  reg_w(gspca_dev, 0xff, 0x01);
484  reg_w(gspca_dev, 0x78, 0x05);
485 
486  return gspca_dev->usb_err;
487 }
488 
489 static void sd_stopN(struct gspca_dev *gspca_dev)
490 {
491  reg_w(gspca_dev, 0xff, 0x04);
492  reg_w(gspca_dev, 0x27, 0x80);
493  reg_w(gspca_dev, 0x28, 0xca);
494  reg_w(gspca_dev, 0x29, 0x53);
495  reg_w(gspca_dev, 0x2a, 0x0e);
496  reg_w(gspca_dev, 0xff, 0x01);
497  reg_w(gspca_dev, 0x3e, 0x20);
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  reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
501 }
502 
503 static void do_autogain(struct gspca_dev *gspca_dev)
504 {
505  struct sd *sd = (struct sd *) gspca_dev;
506  int avg_lum = atomic_read(&sd->avg_lum);
507  int desired_lum, deadzone;
508 
509  if (avg_lum == -1)
510  return;
511 
512  desired_lum = 170;
513  deadzone = 20;
514 
515  if (sd->autogain_ignore_frames > 0)
517  else if (gspca_coarse_grained_expo_autogain(gspca_dev, avg_lum,
518  desired_lum, deadzone))
520 }
521 
522 /* JPEG header, part 1 */
523 static const unsigned char pac_jpeg_header1[] = {
524  0xff, 0xd8, /* SOI: Start of Image */
525 
526  0xff, 0xc0, /* SOF0: Start of Frame (Baseline DCT) */
527  0x00, 0x11, /* length = 17 bytes (including this length field) */
528  0x08 /* Precision: 8 */
529  /* 2 bytes is placed here: number of image lines */
530  /* 2 bytes is placed here: samples per line */
531 };
532 
533 /* JPEG header, continued */
534 static const unsigned char pac_jpeg_header2[] = {
535  0x03, /* Number of image components: 3 */
536  0x01, 0x21, 0x00, /* ID=1, Subsampling 1x1, Quantization table: 0 */
537  0x02, 0x11, 0x01, /* ID=2, Subsampling 2x1, Quantization table: 1 */
538  0x03, 0x11, 0x01, /* ID=3, Subsampling 2x1, Quantization table: 1 */
539 
540  0xff, 0xda, /* SOS: Start Of Scan */
541  0x00, 0x0c, /* length = 12 bytes (including this length field) */
542  0x03, /* number of components: 3 */
543  0x01, 0x00, /* selector 1, table 0x00 */
544  0x02, 0x11, /* selector 2, table 0x11 */
545  0x03, 0x11, /* selector 3, table 0x11 */
546  0x00, 0x3f, /* Spectral selection: 0 .. 63 */
547  0x00 /* Successive approximation: 0 */
548 };
549 
550 static void pac_start_frame(struct gspca_dev *gspca_dev,
551  __u16 lines, __u16 samples_per_line)
552 {
553  unsigned char tmpbuf[4];
554 
555  gspca_frame_add(gspca_dev, FIRST_PACKET,
556  pac_jpeg_header1, sizeof(pac_jpeg_header1));
557 
558  tmpbuf[0] = lines >> 8;
559  tmpbuf[1] = lines & 0xff;
560  tmpbuf[2] = samples_per_line >> 8;
561  tmpbuf[3] = samples_per_line & 0xff;
562 
563  gspca_frame_add(gspca_dev, INTER_PACKET,
564  tmpbuf, sizeof(tmpbuf));
565  gspca_frame_add(gspca_dev, INTER_PACKET,
566  pac_jpeg_header2, sizeof(pac_jpeg_header2));
567 }
568 
569 /* this function is run at interrupt level */
570 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
571  u8 *data, /* isoc packet */
572  int len) /* iso packet length */
573 {
574  struct sd *sd = (struct sd *) gspca_dev;
575  u8 *image;
576  unsigned char *sof;
577 
578  sof = pac_find_sof(&sd->sof_read, data, len);
579  if (sof) {
580  int n, lum_offset, footer_length;
581 
582  /*
583  * 6 bytes after the FF D9 EOF marker a number of lumination
584  * bytes are send corresponding to different parts of the
585  * image, the 14th and 15th byte after the EOF seem to
586  * correspond to the center of the image.
587  */
588  lum_offset = 24 + sizeof pac_sof_marker;
589  footer_length = 26;
590 
591  /* Finish decoding current frame */
592  n = (sof - data) - (footer_length + sizeof pac_sof_marker);
593  if (n < 0) {
594  gspca_dev->image_len += n;
595  n = 0;
596  } else {
597  gspca_frame_add(gspca_dev, INTER_PACKET, data, n);
598  }
599  image = gspca_dev->image;
600  if (image != NULL
601  && image[gspca_dev->image_len - 2] == 0xff
602  && image[gspca_dev->image_len - 1] == 0xd9)
603  gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
604 
605  n = sof - data;
606  len -= n;
607  data = sof;
608 
609  /* Get average lumination */
610  if (gspca_dev->last_packet_type == LAST_PACKET &&
611  n >= lum_offset)
612  atomic_set(&sd->avg_lum, data[-lum_offset] +
613  data[-lum_offset + 1]);
614  else
615  atomic_set(&sd->avg_lum, -1);
616 
617  /* Start the new frame with the jpeg header */
618  pac_start_frame(gspca_dev,
619  gspca_dev->height, gspca_dev->width);
620  }
621  gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
622 }
623 
624 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
625 static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
626  u8 *data, /* interrupt packet data */
627  int len) /* interrupt packet length */
628 {
629  int ret = -EINVAL;
630  u8 data0, data1;
631 
632  if (len == 2) {
633  data0 = data[0];
634  data1 = data[1];
635  if ((data0 == 0x00 && data1 == 0x11) ||
636  (data0 == 0x22 && data1 == 0x33) ||
637  (data0 == 0x44 && data1 == 0x55) ||
638  (data0 == 0x66 && data1 == 0x77) ||
639  (data0 == 0x88 && data1 == 0x99) ||
640  (data0 == 0xaa && data1 == 0xbb) ||
641  (data0 == 0xcc && data1 == 0xdd) ||
642  (data0 == 0xee && data1 == 0xff)) {
643  input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
644  input_sync(gspca_dev->input_dev);
645  input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
646  input_sync(gspca_dev->input_dev);
647  ret = 0;
648  }
649  }
650 
651  return ret;
652 }
653 #endif
654 
655 static const struct sd_desc sd_desc = {
656  .name = MODULE_NAME,
657  .config = sd_config,
658  .init = sd_init,
659  .init_controls = sd_init_controls,
660  .start = sd_start,
661  .stopN = sd_stopN,
662  .pkt_scan = sd_pkt_scan,
663  .dq_callback = do_autogain,
664 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
665  .int_pkt_scan = sd_int_pkt_scan,
666 #endif
667 };
668 
669 /* -- module initialisation -- */
670 static const struct usb_device_id device_table[] = {
671  {USB_DEVICE(0x093a, 0x2600)},
672  {USB_DEVICE(0x093a, 0x2601)},
673  {USB_DEVICE(0x093a, 0x2603)},
674  {USB_DEVICE(0x093a, 0x2608)},
675  {USB_DEVICE(0x093a, 0x260e)},
676  {USB_DEVICE(0x093a, 0x260f)},
677  {}
678 };
679 MODULE_DEVICE_TABLE(usb, device_table);
680 
681 /* -- device connect -- */
682 static int sd_probe(struct usb_interface *intf,
683  const struct usb_device_id *id)
684 {
685  return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
686  THIS_MODULE);
687 }
688 
689 static struct usb_driver sd_driver = {
690  .name = MODULE_NAME,
691  .id_table = device_table,
692  .probe = sd_probe,
693  .disconnect = gspca_disconnect,
694 #ifdef CONFIG_PM
695  .suspend = gspca_suspend,
696  .resume = gspca_resume,
697  .reset_resume = gspca_resume,
698 #endif
699 };
700 
701 module_usb_driver(sd_driver);