Avoid beyond bounds copy while caching ACL
[zen-stable.git] / drivers / media / video / gspca / pac7311.c
blob1ac111176ffa68c895be4039fb98d74f59ccc270
1 /*
2 * Pixart PAC7311 library
3 * Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li
5 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
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.
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.
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
22 /* Some documentation about various registers as determined by trial and error.
23 When the register addresses differ between the 7202 and the 7311 the 2
24 different addresses are written as 7302addr/7311addr, when one of the 2
25 addresses is a - sign that register description is not valid for the
26 matching IC.
28 Register page 1:
30 Address Description
31 -/0x08 Unknown compressor related, must always be 8 except when not
32 in 640x480 resolution and page 4 reg 2 <= 3 then set it to 9 !
33 -/0x1b Auto white balance related, bit 0 is AWB enable (inverted)
34 bits 345 seem to toggle per color gains on/off (inverted)
35 0x78 Global control, bit 6 controls the LED (inverted)
36 -/0x80 JPEG compression ratio ? Best not touched
38 Register page 3/4:
40 Address Description
41 0x02 Clock divider 2-63, fps =~ 60 / val. Must be a multiple of 3 on
42 the 7302, so one of 3, 6, 9, ..., except when between 6 and 12?
43 -/0x0f Master gain 1-245, low value = high gain
44 0x10/- Master gain 0-31
45 -/0x10 Another gain 0-15, limited influence (1-2x gain I guess)
46 0x21 Bitfield: 0-1 unused, 2-3 vflip/hflip, 4-5 unknown, 6-7 unused
47 -/0x27 Seems to toggle various gains on / off, Setting bit 7 seems to
48 completely disable the analog amplification block. Set to 0x68
49 for max gain, 0x14 for minimal gain.
52 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
54 #define MODULE_NAME "pac7311"
56 #include <linux/input.h>
57 #include "gspca.h"
59 MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li");
60 MODULE_DESCRIPTION("Pixart PAC7311");
61 MODULE_LICENSE("GPL");
63 /* specific webcam descriptor for pac7311 */
64 struct sd {
65 struct gspca_dev gspca_dev; /* !! must be the first item */
67 unsigned char contrast;
68 unsigned char gain;
69 unsigned char exposure;
70 unsigned char autogain;
71 __u8 hflip;
72 __u8 vflip;
74 u8 sof_read;
75 u8 autogain_ignore_frames;
77 atomic_t avg_lum;
80 /* V4L2 controls supported by the driver */
81 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
82 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
83 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
84 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
85 static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
86 static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val);
87 static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
88 static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
89 static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
90 static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
91 static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
92 static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
94 static const struct ctrl sd_ctrls[] = {
95 /* This control is for both the 7302 and the 7311 */
98 .id = V4L2_CID_CONTRAST,
99 .type = V4L2_CTRL_TYPE_INTEGER,
100 .name = "Contrast",
101 .minimum = 0,
102 #define CONTRAST_MAX 255
103 .maximum = CONTRAST_MAX,
104 .step = 1,
105 #define CONTRAST_DEF 127
106 .default_value = CONTRAST_DEF,
108 .set = sd_setcontrast,
109 .get = sd_getcontrast,
111 /* All controls below are for both the 7302 and the 7311 */
114 .id = V4L2_CID_GAIN,
115 .type = V4L2_CTRL_TYPE_INTEGER,
116 .name = "Gain",
117 .minimum = 0,
118 #define GAIN_MAX 255
119 .maximum = GAIN_MAX,
120 .step = 1,
121 #define GAIN_DEF 127
122 #define GAIN_KNEE 255 /* Gain seems to cause little noise on the pac73xx */
123 .default_value = GAIN_DEF,
125 .set = sd_setgain,
126 .get = sd_getgain,
130 .id = V4L2_CID_EXPOSURE,
131 .type = V4L2_CTRL_TYPE_INTEGER,
132 .name = "Exposure",
133 .minimum = 0,
134 #define EXPOSURE_MAX 255
135 .maximum = EXPOSURE_MAX,
136 .step = 1,
137 #define EXPOSURE_DEF 16 /* 32 ms / 30 fps */
138 #define EXPOSURE_KNEE 50 /* 100 ms / 10 fps */
139 .default_value = EXPOSURE_DEF,
141 .set = sd_setexposure,
142 .get = sd_getexposure,
146 .id = V4L2_CID_AUTOGAIN,
147 .type = V4L2_CTRL_TYPE_BOOLEAN,
148 .name = "Auto Gain",
149 .minimum = 0,
150 .maximum = 1,
151 .step = 1,
152 #define AUTOGAIN_DEF 1
153 .default_value = AUTOGAIN_DEF,
155 .set = sd_setautogain,
156 .get = sd_getautogain,
160 .id = V4L2_CID_HFLIP,
161 .type = V4L2_CTRL_TYPE_BOOLEAN,
162 .name = "Mirror",
163 .minimum = 0,
164 .maximum = 1,
165 .step = 1,
166 #define HFLIP_DEF 0
167 .default_value = HFLIP_DEF,
169 .set = sd_sethflip,
170 .get = sd_gethflip,
174 .id = V4L2_CID_VFLIP,
175 .type = V4L2_CTRL_TYPE_BOOLEAN,
176 .name = "Vflip",
177 .minimum = 0,
178 .maximum = 1,
179 .step = 1,
180 #define VFLIP_DEF 0
181 .default_value = VFLIP_DEF,
183 .set = sd_setvflip,
184 .get = sd_getvflip,
188 static const struct v4l2_pix_format vga_mode[] = {
189 {160, 120, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
190 .bytesperline = 160,
191 .sizeimage = 160 * 120 * 3 / 8 + 590,
192 .colorspace = V4L2_COLORSPACE_JPEG,
193 .priv = 2},
194 {320, 240, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
195 .bytesperline = 320,
196 .sizeimage = 320 * 240 * 3 / 8 + 590,
197 .colorspace = V4L2_COLORSPACE_JPEG,
198 .priv = 1},
199 {640, 480, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
200 .bytesperline = 640,
201 .sizeimage = 640 * 480 * 3 / 8 + 590,
202 .colorspace = V4L2_COLORSPACE_JPEG,
203 .priv = 0},
206 #define LOAD_PAGE4 254
207 #define END_OF_SEQUENCE 0
209 /* pac 7311 */
210 static const __u8 init_7311[] = {
211 0x78, 0x40, /* Bit_0=start stream, Bit_6=LED */
212 0x78, 0x40, /* Bit_0=start stream, Bit_6=LED */
213 0x78, 0x44, /* Bit_0=start stream, Bit_6=LED */
214 0xff, 0x04,
215 0x27, 0x80,
216 0x28, 0xca,
217 0x29, 0x53,
218 0x2a, 0x0e,
219 0xff, 0x01,
220 0x3e, 0x20,
223 static const __u8 start_7311[] = {
224 /* index, len, [value]* */
225 0xff, 1, 0x01, /* page 1 */
226 0x02, 43, 0x48, 0x0a, 0x40, 0x08, 0x00, 0x00, 0x08, 0x00,
227 0x06, 0xff, 0x11, 0xff, 0x5a, 0x30, 0x90, 0x4c,
228 0x00, 0x07, 0x00, 0x0a, 0x10, 0x00, 0xa0, 0x10,
229 0x02, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x01, 0x00,
230 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
231 0x00, 0x00, 0x00,
232 0x3e, 42, 0x00, 0x00, 0x78, 0x52, 0x4a, 0x52, 0x78, 0x6e,
233 0x48, 0x46, 0x48, 0x6e, 0x5f, 0x49, 0x42, 0x49,
234 0x5f, 0x5f, 0x49, 0x42, 0x49, 0x5f, 0x6e, 0x48,
235 0x46, 0x48, 0x6e, 0x78, 0x52, 0x4a, 0x52, 0x78,
236 0x00, 0x00, 0x09, 0x1b, 0x34, 0x49, 0x5c, 0x9b,
237 0xd0, 0xff,
238 0x78, 6, 0x44, 0x00, 0xf2, 0x01, 0x01, 0x80,
239 0x7f, 18, 0x2a, 0x1c, 0x00, 0xc8, 0x02, 0x58, 0x03, 0x84,
240 0x12, 0x00, 0x1a, 0x04, 0x08, 0x0c, 0x10, 0x14,
241 0x18, 0x20,
242 0x96, 3, 0x01, 0x08, 0x04,
243 0xa0, 4, 0x44, 0x44, 0x44, 0x04,
244 0xf0, 13, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x20, 0x00,
245 0x3f, 0x00, 0x0a, 0x01, 0x00,
246 0xff, 1, 0x04, /* page 4 */
247 0, LOAD_PAGE4, /* load the page 4 */
248 0x11, 1, 0x01,
249 0, END_OF_SEQUENCE /* end of sequence */
252 #define SKIP 0xaa
253 /* page 4 - the value SKIP says skip the index - see reg_w_page() */
254 static const __u8 page4_7311[] = {
255 SKIP, SKIP, 0x04, 0x54, 0x07, 0x2b, 0x09, 0x0f,
256 0x09, 0x00, SKIP, SKIP, 0x07, 0x00, 0x00, 0x62,
257 0x08, SKIP, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
258 0x00, 0x00, 0x00, 0x03, 0xa0, 0x01, 0xf4, SKIP,
259 SKIP, 0x00, 0x08, SKIP, 0x03, SKIP, 0x00, 0x68,
260 0xca, 0x10, 0x06, 0x78, 0x00, 0x00, 0x00, 0x00,
261 0x23, 0x28, 0x04, 0x11, 0x00, 0x00
264 static void reg_w_buf(struct gspca_dev *gspca_dev,
265 __u8 index,
266 const u8 *buffer, int len)
268 int ret;
270 if (gspca_dev->usb_err < 0)
271 return;
272 memcpy(gspca_dev->usb_buf, buffer, len);
273 ret = usb_control_msg(gspca_dev->dev,
274 usb_sndctrlpipe(gspca_dev->dev, 0),
275 0, /* request */
276 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
277 0, /* value */
278 index, gspca_dev->usb_buf, len,
279 500);
280 if (ret < 0) {
281 pr_err("reg_w_buf() failed index 0x%02x, error %d\n",
282 index, ret);
283 gspca_dev->usb_err = ret;
288 static void reg_w(struct gspca_dev *gspca_dev,
289 __u8 index,
290 __u8 value)
292 int ret;
294 if (gspca_dev->usb_err < 0)
295 return;
296 gspca_dev->usb_buf[0] = value;
297 ret = usb_control_msg(gspca_dev->dev,
298 usb_sndctrlpipe(gspca_dev->dev, 0),
299 0, /* request */
300 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
301 0, index, gspca_dev->usb_buf, 1,
302 500);
303 if (ret < 0) {
304 pr_err("reg_w() failed index 0x%02x, value 0x%02x, error %d\n",
305 index, value, ret);
306 gspca_dev->usb_err = ret;
310 static void reg_w_seq(struct gspca_dev *gspca_dev,
311 const __u8 *seq, int len)
313 while (--len >= 0) {
314 reg_w(gspca_dev, seq[0], seq[1]);
315 seq += 2;
319 /* load the beginning of a page */
320 static void reg_w_page(struct gspca_dev *gspca_dev,
321 const __u8 *page, int len)
323 int index;
324 int ret = 0;
326 if (gspca_dev->usb_err < 0)
327 return;
328 for (index = 0; index < len; index++) {
329 if (page[index] == SKIP) /* skip this index */
330 continue;
331 gspca_dev->usb_buf[0] = page[index];
332 ret = usb_control_msg(gspca_dev->dev,
333 usb_sndctrlpipe(gspca_dev->dev, 0),
334 0, /* request */
335 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
336 0, index, gspca_dev->usb_buf, 1,
337 500);
338 if (ret < 0) {
339 pr_err("reg_w_page() failed index 0x%02x, value 0x%02x, error %d\n",
340 index, page[index], ret);
341 gspca_dev->usb_err = ret;
342 break;
347 /* output a variable sequence */
348 static void reg_w_var(struct gspca_dev *gspca_dev,
349 const __u8 *seq,
350 const __u8 *page4, unsigned int page4_len)
352 int index, len;
354 for (;;) {
355 index = *seq++;
356 len = *seq++;
357 switch (len) {
358 case END_OF_SEQUENCE:
359 return;
360 case LOAD_PAGE4:
361 reg_w_page(gspca_dev, page4, page4_len);
362 break;
363 default:
364 if (len > USB_BUF_SZ) {
365 PDEBUG(D_ERR|D_STREAM,
366 "Incorrect variable sequence");
367 return;
369 while (len > 0) {
370 if (len < 8) {
371 reg_w_buf(gspca_dev,
372 index, seq, len);
373 seq += len;
374 break;
376 reg_w_buf(gspca_dev, index, seq, 8);
377 seq += 8;
378 index += 8;
379 len -= 8;
383 /* not reached */
386 /* this function is called at probe time for pac7311 */
387 static int sd_config(struct gspca_dev *gspca_dev,
388 const struct usb_device_id *id)
390 struct sd *sd = (struct sd *) gspca_dev;
391 struct cam *cam;
393 cam = &gspca_dev->cam;
395 PDEBUG(D_CONF, "Find Sensor PAC7311");
396 cam->cam_mode = vga_mode;
397 cam->nmodes = ARRAY_SIZE(vga_mode);
399 sd->contrast = CONTRAST_DEF;
400 sd->gain = GAIN_DEF;
401 sd->exposure = EXPOSURE_DEF;
402 sd->autogain = AUTOGAIN_DEF;
403 sd->hflip = HFLIP_DEF;
404 sd->vflip = VFLIP_DEF;
405 return 0;
408 /* This function is used by pac7311 only */
409 static void setcontrast(struct gspca_dev *gspca_dev)
411 struct sd *sd = (struct sd *) gspca_dev;
413 reg_w(gspca_dev, 0xff, 0x04);
414 reg_w(gspca_dev, 0x10, sd->contrast >> 4);
415 /* load registers to sensor (Bit 0, auto clear) */
416 reg_w(gspca_dev, 0x11, 0x01);
419 static void setgain(struct gspca_dev *gspca_dev)
421 struct sd *sd = (struct sd *) gspca_dev;
422 int gain = GAIN_MAX - sd->gain;
424 if (gain < 1)
425 gain = 1;
426 else if (gain > 245)
427 gain = 245;
428 reg_w(gspca_dev, 0xff, 0x04); /* page 4 */
429 reg_w(gspca_dev, 0x0e, 0x00);
430 reg_w(gspca_dev, 0x0f, gain);
432 /* load registers to sensor (Bit 0, auto clear) */
433 reg_w(gspca_dev, 0x11, 0x01);
436 static void setexposure(struct gspca_dev *gspca_dev)
438 struct sd *sd = (struct sd *) gspca_dev;
439 __u8 reg;
441 /* register 2 of frame 3/4 contains the clock divider configuring the
442 no fps according to the formula: 60 / reg. sd->exposure is the
443 desired exposure time in ms. */
444 reg = 120 * sd->exposure / 1000;
445 if (reg < 2)
446 reg = 2;
447 else if (reg > 63)
448 reg = 63;
450 reg_w(gspca_dev, 0xff, 0x04); /* page 4 */
451 reg_w(gspca_dev, 0x02, reg);
453 /* Page 1 register 8 must always be 0x08 except when not in
454 640x480 mode and Page3/4 reg 2 <= 3 then it must be 9 */
455 reg_w(gspca_dev, 0xff, 0x01);
456 if (gspca_dev->cam.cam_mode[(int)gspca_dev->curr_mode].priv &&
457 reg <= 3) {
458 reg_w(gspca_dev, 0x08, 0x09);
459 } else {
460 reg_w(gspca_dev, 0x08, 0x08);
463 /* load registers to sensor (Bit 0, auto clear) */
464 reg_w(gspca_dev, 0x11, 0x01);
467 static void sethvflip(struct gspca_dev *gspca_dev)
469 struct sd *sd = (struct sd *) gspca_dev;
470 __u8 data;
472 reg_w(gspca_dev, 0xff, 0x04); /* page 4 */
473 data = (sd->hflip ? 0x04 : 0x00) | (sd->vflip ? 0x08 : 0x00);
474 reg_w(gspca_dev, 0x21, data);
476 /* load registers to sensor (Bit 0, auto clear) */
477 reg_w(gspca_dev, 0x11, 0x01);
480 /* this function is called at probe and resume time for pac7311 */
481 static int sd_init(struct gspca_dev *gspca_dev)
483 reg_w_seq(gspca_dev, init_7311, sizeof(init_7311)/2);
484 return gspca_dev->usb_err;
487 static int sd_start(struct gspca_dev *gspca_dev)
489 struct sd *sd = (struct sd *) gspca_dev;
491 sd->sof_read = 0;
493 reg_w_var(gspca_dev, start_7311,
494 page4_7311, sizeof(page4_7311));
495 setcontrast(gspca_dev);
496 setgain(gspca_dev);
497 setexposure(gspca_dev);
498 sethvflip(gspca_dev);
500 /* set correct resolution */
501 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
502 case 2: /* 160x120 pac7311 */
503 reg_w(gspca_dev, 0xff, 0x01);
504 reg_w(gspca_dev, 0x17, 0x20);
505 reg_w(gspca_dev, 0x87, 0x10);
506 break;
507 case 1: /* 320x240 pac7311 */
508 reg_w(gspca_dev, 0xff, 0x01);
509 reg_w(gspca_dev, 0x17, 0x30);
510 reg_w(gspca_dev, 0x87, 0x11);
511 break;
512 case 0: /* 640x480 */
513 reg_w(gspca_dev, 0xff, 0x01);
514 reg_w(gspca_dev, 0x17, 0x00);
515 reg_w(gspca_dev, 0x87, 0x12);
516 break;
519 sd->sof_read = 0;
520 sd->autogain_ignore_frames = 0;
521 atomic_set(&sd->avg_lum, -1);
523 /* start stream */
524 reg_w(gspca_dev, 0xff, 0x01);
525 reg_w(gspca_dev, 0x78, 0x05);
527 return gspca_dev->usb_err;
530 static void sd_stopN(struct gspca_dev *gspca_dev)
532 reg_w(gspca_dev, 0xff, 0x04);
533 reg_w(gspca_dev, 0x27, 0x80);
534 reg_w(gspca_dev, 0x28, 0xca);
535 reg_w(gspca_dev, 0x29, 0x53);
536 reg_w(gspca_dev, 0x2a, 0x0e);
537 reg_w(gspca_dev, 0xff, 0x01);
538 reg_w(gspca_dev, 0x3e, 0x20);
539 reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
540 reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
541 reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
544 /* called on streamoff with alt 0 and on disconnect for 7311 */
545 static void sd_stop0(struct gspca_dev *gspca_dev)
549 /* Include pac common sof detection functions */
550 #include "pac_common.h"
552 static void do_autogain(struct gspca_dev *gspca_dev)
554 struct sd *sd = (struct sd *) gspca_dev;
555 int avg_lum = atomic_read(&sd->avg_lum);
556 int desired_lum, deadzone;
558 if (avg_lum == -1)
559 return;
561 desired_lum = 200;
562 deadzone = 20;
564 if (sd->autogain_ignore_frames > 0)
565 sd->autogain_ignore_frames--;
566 else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum, desired_lum,
567 deadzone, GAIN_KNEE, EXPOSURE_KNEE))
568 sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES;
571 /* JPEG header, part 1 */
572 static const unsigned char pac_jpeg_header1[] = {
573 0xff, 0xd8, /* SOI: Start of Image */
575 0xff, 0xc0, /* SOF0: Start of Frame (Baseline DCT) */
576 0x00, 0x11, /* length = 17 bytes (including this length field) */
577 0x08 /* Precision: 8 */
578 /* 2 bytes is placed here: number of image lines */
579 /* 2 bytes is placed here: samples per line */
582 /* JPEG header, continued */
583 static const unsigned char pac_jpeg_header2[] = {
584 0x03, /* Number of image components: 3 */
585 0x01, 0x21, 0x00, /* ID=1, Subsampling 1x1, Quantization table: 0 */
586 0x02, 0x11, 0x01, /* ID=2, Subsampling 2x1, Quantization table: 1 */
587 0x03, 0x11, 0x01, /* ID=3, Subsampling 2x1, Quantization table: 1 */
589 0xff, 0xda, /* SOS: Start Of Scan */
590 0x00, 0x0c, /* length = 12 bytes (including this length field) */
591 0x03, /* number of components: 3 */
592 0x01, 0x00, /* selector 1, table 0x00 */
593 0x02, 0x11, /* selector 2, table 0x11 */
594 0x03, 0x11, /* selector 3, table 0x11 */
595 0x00, 0x3f, /* Spectral selection: 0 .. 63 */
596 0x00 /* Successive approximation: 0 */
599 static void pac_start_frame(struct gspca_dev *gspca_dev,
600 __u16 lines, __u16 samples_per_line)
602 unsigned char tmpbuf[4];
604 gspca_frame_add(gspca_dev, FIRST_PACKET,
605 pac_jpeg_header1, sizeof(pac_jpeg_header1));
607 tmpbuf[0] = lines >> 8;
608 tmpbuf[1] = lines & 0xff;
609 tmpbuf[2] = samples_per_line >> 8;
610 tmpbuf[3] = samples_per_line & 0xff;
612 gspca_frame_add(gspca_dev, INTER_PACKET,
613 tmpbuf, sizeof(tmpbuf));
614 gspca_frame_add(gspca_dev, INTER_PACKET,
615 pac_jpeg_header2, sizeof(pac_jpeg_header2));
618 /* this function is run at interrupt level */
619 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
620 u8 *data, /* isoc packet */
621 int len) /* iso packet length */
623 struct sd *sd = (struct sd *) gspca_dev;
624 u8 *image;
625 unsigned char *sof;
627 sof = pac_find_sof(&sd->sof_read, data, len);
628 if (sof) {
629 int n, lum_offset, footer_length;
631 /* 6 bytes after the FF D9 EOF marker a number of lumination
632 bytes are send corresponding to different parts of the
633 image, the 14th and 15th byte after the EOF seem to
634 correspond to the center of the image */
635 lum_offset = 24 + sizeof pac_sof_marker;
636 footer_length = 26;
638 /* Finish decoding current frame */
639 n = (sof - data) - (footer_length + sizeof pac_sof_marker);
640 if (n < 0) {
641 gspca_dev->image_len += n;
642 n = 0;
643 } else {
644 gspca_frame_add(gspca_dev, INTER_PACKET, data, n);
646 image = gspca_dev->image;
647 if (image != NULL
648 && image[gspca_dev->image_len - 2] == 0xff
649 && image[gspca_dev->image_len - 1] == 0xd9)
650 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
652 n = sof - data;
653 len -= n;
654 data = sof;
656 /* Get average lumination */
657 if (gspca_dev->last_packet_type == LAST_PACKET &&
658 n >= lum_offset)
659 atomic_set(&sd->avg_lum, data[-lum_offset] +
660 data[-lum_offset + 1]);
661 else
662 atomic_set(&sd->avg_lum, -1);
664 /* Start the new frame with the jpeg header */
665 pac_start_frame(gspca_dev,
666 gspca_dev->height, gspca_dev->width);
668 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
671 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
673 struct sd *sd = (struct sd *) gspca_dev;
675 sd->contrast = val;
676 if (gspca_dev->streaming)
677 setcontrast(gspca_dev);
678 return gspca_dev->usb_err;
681 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
683 struct sd *sd = (struct sd *) gspca_dev;
685 *val = sd->contrast;
686 return 0;
689 static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
691 struct sd *sd = (struct sd *) gspca_dev;
693 sd->gain = val;
694 if (gspca_dev->streaming)
695 setgain(gspca_dev);
696 return gspca_dev->usb_err;
699 static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
701 struct sd *sd = (struct sd *) gspca_dev;
703 *val = sd->gain;
704 return 0;
707 static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
709 struct sd *sd = (struct sd *) gspca_dev;
711 sd->exposure = val;
712 if (gspca_dev->streaming)
713 setexposure(gspca_dev);
714 return gspca_dev->usb_err;
717 static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
719 struct sd *sd = (struct sd *) gspca_dev;
721 *val = sd->exposure;
722 return 0;
725 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
727 struct sd *sd = (struct sd *) gspca_dev;
729 sd->autogain = val;
730 /* when switching to autogain set defaults to make sure
731 we are on a valid point of the autogain gain /
732 exposure knee graph, and give this change time to
733 take effect before doing autogain. */
734 if (sd->autogain) {
735 sd->exposure = EXPOSURE_DEF;
736 sd->gain = GAIN_DEF;
737 if (gspca_dev->streaming) {
738 sd->autogain_ignore_frames =
739 PAC_AUTOGAIN_IGNORE_FRAMES;
740 setexposure(gspca_dev);
741 setgain(gspca_dev);
745 return gspca_dev->usb_err;
748 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
750 struct sd *sd = (struct sd *) gspca_dev;
752 *val = sd->autogain;
753 return 0;
756 static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
758 struct sd *sd = (struct sd *) gspca_dev;
760 sd->hflip = val;
761 if (gspca_dev->streaming)
762 sethvflip(gspca_dev);
763 return gspca_dev->usb_err;
766 static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val)
768 struct sd *sd = (struct sd *) gspca_dev;
770 *val = sd->hflip;
771 return 0;
774 static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
776 struct sd *sd = (struct sd *) gspca_dev;
778 sd->vflip = val;
779 if (gspca_dev->streaming)
780 sethvflip(gspca_dev);
781 return gspca_dev->usb_err;
784 static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
786 struct sd *sd = (struct sd *) gspca_dev;
788 *val = sd->vflip;
789 return 0;
792 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
793 static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
794 u8 *data, /* interrupt packet data */
795 int len) /* interrupt packet length */
797 int ret = -EINVAL;
798 u8 data0, data1;
800 if (len == 2) {
801 data0 = data[0];
802 data1 = data[1];
803 if ((data0 == 0x00 && data1 == 0x11) ||
804 (data0 == 0x22 && data1 == 0x33) ||
805 (data0 == 0x44 && data1 == 0x55) ||
806 (data0 == 0x66 && data1 == 0x77) ||
807 (data0 == 0x88 && data1 == 0x99) ||
808 (data0 == 0xaa && data1 == 0xbb) ||
809 (data0 == 0xcc && data1 == 0xdd) ||
810 (data0 == 0xee && data1 == 0xff)) {
811 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
812 input_sync(gspca_dev->input_dev);
813 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
814 input_sync(gspca_dev->input_dev);
815 ret = 0;
819 return ret;
821 #endif
823 /* sub-driver description for pac7311 */
824 static const struct sd_desc sd_desc = {
825 .name = MODULE_NAME,
826 .ctrls = sd_ctrls,
827 .nctrls = ARRAY_SIZE(sd_ctrls),
828 .config = sd_config,
829 .init = sd_init,
830 .start = sd_start,
831 .stopN = sd_stopN,
832 .stop0 = sd_stop0,
833 .pkt_scan = sd_pkt_scan,
834 .dq_callback = do_autogain,
835 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
836 .int_pkt_scan = sd_int_pkt_scan,
837 #endif
840 /* -- module initialisation -- */
841 static const struct usb_device_id device_table[] = {
842 {USB_DEVICE(0x093a, 0x2600)},
843 {USB_DEVICE(0x093a, 0x2601)},
844 {USB_DEVICE(0x093a, 0x2603)},
845 {USB_DEVICE(0x093a, 0x2608)},
846 {USB_DEVICE(0x093a, 0x260e)},
847 {USB_DEVICE(0x093a, 0x260f)},
850 MODULE_DEVICE_TABLE(usb, device_table);
852 /* -- device connect -- */
853 static int sd_probe(struct usb_interface *intf,
854 const struct usb_device_id *id)
856 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
857 THIS_MODULE);
860 static struct usb_driver sd_driver = {
861 .name = MODULE_NAME,
862 .id_table = device_table,
863 .probe = sd_probe,
864 .disconnect = gspca_disconnect,
865 #ifdef CONFIG_PM
866 .suspend = gspca_suspend,
867 .resume = gspca_resume,
868 #endif
871 module_usb_driver(sd_driver);