2 * Pixart PAC7302 driver
4 * Copyright (C) 2008-2012 Jean-Francois Moine <http://moinejf.free.fr>
5 * Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li
7 * Separated from Pixart PAC7311 library by Márton Németh
8 * Camera button input handling by Márton Németh <nm127@freemail.hu>
9 * Copyright (C) 2009-2010 Márton Németh <nm127@freemail.hu>
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 * Some documentation about various registers as determined by trial and error.
32 * 0x78 Global control, bit 6 controls the LED (inverted)
33 * 0x80 Compression balance, 2 interesting settings:
35 * 0x50 Values >= this switch the camera to a lower compression,
36 * using the same table for both luminance and chrominance.
37 * This gives a sharper picture. Only usable when running
38 * at < 15 fps! Note currently the driver does not use this
39 * as the quality gain is small and the generated JPG-s are
40 * only understood by v4l-utils >= 0.8.9
45 * 0x02 Clock divider 3-63, fps = 90 / val. Must be a multiple of 3 on
46 * the 7302, so one of 3, 6, 9, ..., except when between 6 and 12?
47 * 0x03 Variable framerate ctrl reg2==3: 0 -> ~30 fps, 255 -> ~22fps
48 * 0x04 Another var framerate ctrl reg2==3, reg3==0: 0 -> ~30 fps,
49 * 63 -> ~27 fps, the 2 msb's must always be 1 !!
50 * 0x05 Another var framerate ctrl reg2==3, reg3==0, reg4==0xc0:
51 * 1 -> ~30 fps, 2 -> ~20 fps
52 * 0x0e Exposure bits 0-7, 0-448, 0 = use full frame time
53 * 0x0f Exposure bit 8, 0-448, 448 = no exposure at all
55 * 0x12 Another gain 0-31, unlike 0x10 this one seems to start with an
56 * amplification value of 1 rather then 0 at its lowest setting
57 * 0x21 Bitfield: 0-1 unused, 2-3 vflip/hflip, 4-5 unknown, 6-7 unused
58 * 0x80 Another framerate control, best left at 1, moving it from 1 to
59 * 2 causes the framerate to become 3/4th of what it was, and
60 * also seems to cause pixel averaging, resulting in an effective
61 * resolution of 320x240 and thus a much blockier image
63 * The registers are accessed in the following functions:
65 * Page | Register | Function
66 * -----+------------+---------------------------------------------------
67 * 0 | 0x0f..0x20 | setcolors()
68 * 0 | 0xa2..0xab | setbrightcont()
69 * 0 | 0xc5 | setredbalance()
70 * 0 | 0xc6 | setwhitebalance()
71 * 0 | 0xc7 | setbluebalance()
72 * 0 | 0xdc | setbrightcont(), setcolors()
73 * 3 | 0x02 | setexposure()
74 * 3 | 0x10, 0x12 | setgain()
75 * 3 | 0x11 | setcolors(), setgain(), setexposure(), sethvflip()
76 * 3 | 0x21 | sethvflip()
79 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
81 #include <linux/input.h>
82 #include <media/v4l2-chip-ident.h>
84 /* Include pac common sof detection functions */
85 #include "pac_common.h"
87 MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>, "
88 "Thomas Kaiser thomas@kaiser-linux.li");
89 MODULE_DESCRIPTION("Pixart PAC7302");
90 MODULE_LICENSE("GPL");
104 NCTRLS /* number of controls */
108 struct gspca_dev gspca_dev; /* !! must be the first item */
110 struct gspca_ctrl ctrls[NCTRLS];
113 #define FL_HFLIP 0x01 /* mirrored by default */
114 #define FL_VFLIP 0x02 /* vertical flipped by default */
117 s8 autogain_ignore_frames;
122 /* V4L2 controls supported by the driver */
123 static void setbrightcont(struct gspca_dev *gspca_dev);
124 static void setcolors(struct gspca_dev *gspca_dev);
125 static void setwhitebalance(struct gspca_dev *gspca_dev);
126 static void setredbalance(struct gspca_dev *gspca_dev);
127 static void setbluebalance(struct gspca_dev *gspca_dev);
128 static void setgain(struct gspca_dev *gspca_dev);
129 static void setexposure(struct gspca_dev *gspca_dev);
130 static void setautogain(struct gspca_dev *gspca_dev);
131 static void sethvflip(struct gspca_dev *gspca_dev);
133 static const struct ctrl sd_ctrls[] = {
136 .id = V4L2_CID_BRIGHTNESS,
137 .type = V4L2_CTRL_TYPE_INTEGER,
138 .name = "Brightness",
140 #define BRIGHTNESS_MAX 0x20
141 .maximum = BRIGHTNESS_MAX,
143 .default_value = 0x10,
145 .set_control = setbrightcont
149 .id = V4L2_CID_CONTRAST,
150 .type = V4L2_CTRL_TYPE_INTEGER,
153 #define CONTRAST_MAX 255
154 .maximum = CONTRAST_MAX,
156 .default_value = 127,
158 .set_control = setbrightcont
162 .id = V4L2_CID_SATURATION,
163 .type = V4L2_CTRL_TYPE_INTEGER,
164 .name = "Saturation",
166 #define COLOR_MAX 255
167 .maximum = COLOR_MAX,
171 .set_control = setcolors
175 .id = V4L2_CID_WHITE_BALANCE_TEMPERATURE,
176 .type = V4L2_CTRL_TYPE_INTEGER,
177 .name = "White Balance",
183 .set_control = setwhitebalance
187 .id = V4L2_CID_RED_BALANCE,
188 .type = V4L2_CTRL_TYPE_INTEGER,
195 .set_control = setredbalance
199 .id = V4L2_CID_BLUE_BALANCE,
200 .type = V4L2_CTRL_TYPE_INTEGER,
207 .set_control = setbluebalance
212 .type = V4L2_CTRL_TYPE_INTEGER,
219 .default_value = GAIN_DEF,
221 .set_control = setgain
225 .id = V4L2_CID_EXPOSURE,
226 .type = V4L2_CTRL_TYPE_INTEGER,
231 #define EXPOSURE_DEF 66 /* 33 ms / 30 fps */
232 #define EXPOSURE_KNEE 133 /* 66 ms / 15 fps */
233 .default_value = EXPOSURE_DEF,
235 .set_control = setexposure
239 .id = V4L2_CID_AUTOGAIN,
240 .type = V4L2_CTRL_TYPE_BOOLEAN,
245 #define AUTOGAIN_DEF 1
246 .default_value = AUTOGAIN_DEF,
248 .set_control = setautogain,
252 .id = V4L2_CID_HFLIP,
253 .type = V4L2_CTRL_TYPE_BOOLEAN,
260 .set_control = sethvflip,
264 .id = V4L2_CID_VFLIP,
265 .type = V4L2_CTRL_TYPE_BOOLEAN,
272 .set_control = sethvflip
276 static const struct v4l2_pix_format vga_mode[] = {
277 {640, 480, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
279 .sizeimage = 640 * 480 * 3 / 8 + 590,
280 .colorspace = V4L2_COLORSPACE_JPEG,
284 #define LOAD_PAGE3 255
285 #define END_OF_SEQUENCE 0
287 static const u8 init_7302[] = {
289 0xff, 0x01, /* page 1 */
290 0x78, 0x00, /* deactivate */
292 0x78, 0x40, /* led off */
294 static const u8 start_7302[] = {
295 /* index, len, [value]* */
296 0xff, 1, 0x00, /* page 0 */
297 0x00, 12, 0x01, 0x40, 0x40, 0x40, 0x01, 0xe0, 0x02, 0x80,
298 0x00, 0x00, 0x00, 0x00,
299 0x0d, 24, 0x03, 0x01, 0x00, 0xb5, 0x07, 0xcb, 0x00, 0x00,
300 0x07, 0xc8, 0x00, 0xea, 0x07, 0xcf, 0x07, 0xf7,
301 0x07, 0x7e, 0x01, 0x0b, 0x00, 0x00, 0x00, 0x11,
305 0x3a, 3, 0x14, 0xff, 0x5a,
306 0x43, 11, 0x00, 0x0a, 0x18, 0x11, 0x01, 0x2c, 0x88, 0x11,
309 0x62, 4, 0x10, 0x1e, 0x1e, 0x18,
311 0x6e, 3, 0x08, 0x06, 0x00,
312 0x72, 3, 0x00, 0xff, 0x00,
313 0x7d, 23, 0x01, 0x01, 0x58, 0x46, 0x50, 0x3c, 0x50, 0x3c,
314 0x54, 0x46, 0x54, 0x56, 0x52, 0x50, 0x52, 0x50,
315 0x56, 0x64, 0xa4, 0x00, 0xda, 0x00, 0x00,
316 0xa2, 10, 0x22, 0x2c, 0x3c, 0x54, 0x69, 0x7c, 0x9c, 0xb9,
321 0xc4, 4, 0xae, 0x01, 0x04, 0x01,
323 0xd1, 11, 0x01, 0x30, 0x49, 0x5e, 0x6f, 0x7f, 0x8e, 0xa9,
326 0xff, 1, 0x01, /* page 1 */
327 0x12, 3, 0x02, 0x00, 0x01,
329 0x76, 5, 0x01, 0x20, 0x40, 0x00, 0xf2,
331 0x7f, 10, 0x4b, 0x0f, 0x01, 0x2c, 0x02, 0x58, 0x03, 0x20,
333 0x96, 5, 0x01, 0x10, 0x04, 0x01, 0x04,
334 0xc8, 14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
335 0x07, 0x00, 0x01, 0x07, 0x04, 0x01,
338 0xde, 7, 0x00, 0x01, 0x04, 0x04, 0x00, 0x00, 0x00,
339 0xe6, 4, 0x00, 0x00, 0x00, 0x01,
341 0xff, 1, 0x02, /* page 2 */
343 0xff, 1, 0x03, /* page 3 */
344 0, LOAD_PAGE3, /* load the page 3 */
346 0xff, 1, 0x02, /* page 2 */
348 0x22, 4, 0x1f, 0xa4, 0xf0, 0x96,
350 0x2a, 5, 0xc8, 0x00, 0x18, 0x12, 0x22,
351 0x64, 8, 0x00, 0x00, 0xf0, 0x01, 0x14, 0x44, 0x44, 0x44,
353 0xff, 1, 0x01, /* page 1 */
355 0, END_OF_SEQUENCE /* end of sequence */
359 /* page 3 - the value SKIP says skip the index - see reg_w_page() */
360 static const u8 page3_7302[] = {
361 0x90, 0x40, 0x03, 0x00, 0xc0, 0x01, 0x14, 0x16,
362 0x14, 0x12, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00,
363 0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
364 0x00, 0x00, 0x00, 0x47, 0x01, 0xb3, 0x01, 0x00,
365 0x00, 0x08, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x21,
366 0x00, 0x00, 0x00, 0x54, 0xf4, 0x02, 0x52, 0x54,
367 0xa4, 0xb8, 0xe0, 0x2a, 0xf6, 0x00, 0x00, 0x00,
368 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
369 0x00, 0xfc, 0x00, 0xf2, 0x1f, 0x04, 0x00, 0x00,
370 SKIP, 0x00, 0x00, 0xc0, 0xc0, 0x10, 0x00, 0x00,
371 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
372 0x00, 0x40, 0xff, 0x03, 0x19, 0x00, 0x00, 0x00,
373 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
374 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc8, 0xc8,
375 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
376 0x08, 0x10, 0x24, 0x40, 0x00, 0x00, 0x00, 0x00,
377 0x01, 0x00, 0x02, 0x47, 0x00, 0x00, 0x00, 0x00,
378 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
379 0x00, 0x02, 0xfa, 0x00, 0x64, 0x5a, 0x28, 0x00,
383 static void reg_w_buf(struct gspca_dev *gspca_dev,
385 const u8 *buffer, int len)
389 if (gspca_dev->usb_err < 0)
391 memcpy(gspca_dev->usb_buf, buffer, len);
392 ret = usb_control_msg(gspca_dev->dev,
393 usb_sndctrlpipe(gspca_dev->dev, 0),
395 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
397 index, gspca_dev->usb_buf, len,
400 pr_err("reg_w_buf failed i: %02x error %d\n",
402 gspca_dev->usb_err = ret;
407 static void reg_w(struct gspca_dev *gspca_dev,
413 if (gspca_dev->usb_err < 0)
415 gspca_dev->usb_buf[0] = value;
416 ret = usb_control_msg(gspca_dev->dev,
417 usb_sndctrlpipe(gspca_dev->dev, 0),
419 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
420 0, index, gspca_dev->usb_buf, 1,
423 pr_err("reg_w() failed i: %02x v: %02x error %d\n",
425 gspca_dev->usb_err = ret;
429 static void reg_w_seq(struct gspca_dev *gspca_dev,
430 const u8 *seq, int len)
433 reg_w(gspca_dev, seq[0], seq[1]);
438 /* load the beginning of a page */
439 static void reg_w_page(struct gspca_dev *gspca_dev,
440 const u8 *page, int len)
445 if (gspca_dev->usb_err < 0)
447 for (index = 0; index < len; index++) {
448 if (page[index] == SKIP) /* skip this index */
450 gspca_dev->usb_buf[0] = page[index];
451 ret = usb_control_msg(gspca_dev->dev,
452 usb_sndctrlpipe(gspca_dev->dev, 0),
454 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
455 0, index, gspca_dev->usb_buf, 1,
458 pr_err("reg_w_page() failed i: %02x v: %02x error %d\n",
459 index, page[index], ret);
460 gspca_dev->usb_err = ret;
466 /* output a variable sequence */
467 static void reg_w_var(struct gspca_dev *gspca_dev,
469 const u8 *page3, unsigned int page3_len)
477 case END_OF_SEQUENCE:
480 reg_w_page(gspca_dev, page3, page3_len);
484 if (len > USB_BUF_SZ) {
485 PDEBUG(D_ERR|D_STREAM,
486 "Incorrect variable sequence");
497 reg_w_buf(gspca_dev, index, seq, 8);
507 /* this function is called at probe time for pac7302 */
508 static int sd_config(struct gspca_dev *gspca_dev,
509 const struct usb_device_id *id)
511 struct sd *sd = (struct sd *) gspca_dev;
514 cam = &gspca_dev->cam;
516 cam->cam_mode = vga_mode; /* only 640x480 */
517 cam->nmodes = ARRAY_SIZE(vga_mode);
519 gspca_dev->cam.ctrls = sd->ctrls;
521 sd->flags = id->driver_info;
525 static void setbrightcont(struct gspca_dev *gspca_dev)
527 struct sd *sd = (struct sd *) gspca_dev;
529 static const u8 max[10] =
530 {0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb,
532 static const u8 delta[10] =
533 {0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17,
536 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
537 for (i = 0; i < 10; i++) {
539 v += (sd->ctrls[BRIGHTNESS].val - BRIGHTNESS_MAX)
540 * 150 / BRIGHTNESS_MAX; /* 200 ? */
541 v -= delta[i] * sd->ctrls[CONTRAST].val / CONTRAST_MAX;
546 reg_w(gspca_dev, 0xa2 + i, v);
548 reg_w(gspca_dev, 0xdc, 0x01);
551 static void setcolors(struct gspca_dev *gspca_dev)
553 struct sd *sd = (struct sd *) gspca_dev;
555 static const int a[9] =
556 {217, -212, 0, -101, 170, -67, -38, -315, 355};
557 static const int b[9] =
558 {19, 106, 0, 19, 106, 1, 19, 106, 1};
560 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
561 reg_w(gspca_dev, 0x11, 0x01);
562 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
563 for (i = 0; i < 9; i++) {
564 v = a[i] * sd->ctrls[COLORS].val / COLOR_MAX + b[i];
565 reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07);
566 reg_w(gspca_dev, 0x0f + 2 * i + 1, v);
568 reg_w(gspca_dev, 0xdc, 0x01);
571 static void setwhitebalance(struct gspca_dev *gspca_dev)
573 struct sd *sd = (struct sd *) gspca_dev;
575 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
576 reg_w(gspca_dev, 0xc6, sd->ctrls[WHITE_BALANCE].val);
578 reg_w(gspca_dev, 0xdc, 0x01);
581 static void setredbalance(struct gspca_dev *gspca_dev)
583 struct sd *sd = (struct sd *) gspca_dev;
585 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
586 reg_w(gspca_dev, 0xc5, sd->ctrls[RED_BALANCE].val);
588 reg_w(gspca_dev, 0xdc, 0x01);
591 static void setbluebalance(struct gspca_dev *gspca_dev)
593 struct sd *sd = (struct sd *) gspca_dev;
595 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
596 reg_w(gspca_dev, 0xc7, sd->ctrls[BLUE_BALANCE].val);
598 reg_w(gspca_dev, 0xdc, 0x01);
601 static void setgain(struct gspca_dev *gspca_dev)
603 struct sd *sd = (struct sd *) gspca_dev;
606 if (sd->ctrls[GAIN].val < 32) {
607 reg10 = sd->ctrls[GAIN].val;
611 reg12 = sd->ctrls[GAIN].val - 31;
614 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
615 reg_w(gspca_dev, 0x10, reg10);
616 reg_w(gspca_dev, 0x12, reg12);
618 /* load registers to sensor (Bit 0, auto clear) */
619 reg_w(gspca_dev, 0x11, 0x01);
622 static void setexposure(struct gspca_dev *gspca_dev)
624 struct sd *sd = (struct sd *) gspca_dev;
629 * Register 2 of frame 3 contains the clock divider configuring the
630 * no fps according to the formula: 90 / reg. sd->exposure is the
631 * desired exposure time in 0.5 ms.
633 clockdiv = (90 * sd->ctrls[EXPOSURE].val + 1999) / 2000;
636 * Note clockdiv = 3 also works, but when running at 30 fps, depending
637 * on the scene being recorded, the camera switches to another
638 * quantization table for certain JPEG blocks, and we don't know how
639 * to decompress these blocks. So we cap the framerate at 15 fps.
643 else if (clockdiv > 63)
647 * Register 2 MUST be a multiple of 3, except when between 6 and 12?
648 * Always round up, otherwise we cannot get the desired frametime
649 * using the partial frame time exposure control.
651 if (clockdiv < 6 || clockdiv > 12)
652 clockdiv = ((clockdiv + 2) / 3) * 3;
655 * frame exposure time in ms = 1000 * clockdiv / 90 ->
656 * exposure = (sd->exposure / 2) * 448 / (1000 * clockdiv / 90)
658 exposure = (sd->ctrls[EXPOSURE].val * 45 * 448) / (1000 * clockdiv);
659 /* 0 = use full frametime, 448 = no exposure, reverse it */
660 exposure = 448 - exposure;
662 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
663 reg_w(gspca_dev, 0x02, clockdiv);
664 reg_w(gspca_dev, 0x0e, exposure & 0xff);
665 reg_w(gspca_dev, 0x0f, exposure >> 8);
667 /* load registers to sensor (Bit 0, auto clear) */
668 reg_w(gspca_dev, 0x11, 0x01);
671 static void setautogain(struct gspca_dev *gspca_dev)
673 struct sd *sd = (struct sd *) gspca_dev;
676 * When switching to autogain set defaults to make sure
677 * we are on a valid point of the autogain gain /
678 * exposure knee graph, and give this change time to
679 * take effect before doing autogain.
681 if (sd->ctrls[AUTOGAIN].val) {
682 sd->ctrls[EXPOSURE].val = EXPOSURE_DEF;
683 sd->ctrls[GAIN].val = GAIN_DEF;
684 sd->autogain_ignore_frames =
685 PAC_AUTOGAIN_IGNORE_FRAMES;
687 sd->autogain_ignore_frames = -1;
689 setexposure(gspca_dev);
693 static void sethvflip(struct gspca_dev *gspca_dev)
695 struct sd *sd = (struct sd *) gspca_dev;
696 u8 data, hflip, vflip;
698 hflip = sd->ctrls[HFLIP].val;
699 if (sd->flags & FL_HFLIP)
701 vflip = sd->ctrls[VFLIP].val;
702 if (sd->flags & FL_VFLIP)
705 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
706 data = (hflip ? 0x08 : 0x00) | (vflip ? 0x04 : 0x00);
707 reg_w(gspca_dev, 0x21, data);
709 /* load registers to sensor (Bit 0, auto clear) */
710 reg_w(gspca_dev, 0x11, 0x01);
713 /* this function is called at probe and resume time for pac7302 */
714 static int sd_init(struct gspca_dev *gspca_dev)
716 reg_w_seq(gspca_dev, init_7302, sizeof(init_7302)/2);
717 return gspca_dev->usb_err;
720 static int sd_start(struct gspca_dev *gspca_dev)
722 struct sd *sd = (struct sd *) gspca_dev;
724 reg_w_var(gspca_dev, start_7302,
725 page3_7302, sizeof(page3_7302));
726 setbrightcont(gspca_dev);
727 setcolors(gspca_dev);
728 setwhitebalance(gspca_dev);
729 setredbalance(gspca_dev);
730 setbluebalance(gspca_dev);
731 setautogain(gspca_dev);
732 sethvflip(gspca_dev);
735 atomic_set(&sd->avg_lum, 270 + sd->ctrls[BRIGHTNESS].val);
738 reg_w(gspca_dev, 0xff, 0x01);
739 reg_w(gspca_dev, 0x78, 0x01);
741 return gspca_dev->usb_err;
744 static void sd_stopN(struct gspca_dev *gspca_dev)
748 reg_w(gspca_dev, 0xff, 0x01);
749 reg_w(gspca_dev, 0x78, 0x00);
752 /* called on streamoff with alt 0 and on disconnect for pac7302 */
753 static void sd_stop0(struct gspca_dev *gspca_dev)
755 if (!gspca_dev->present)
757 reg_w(gspca_dev, 0xff, 0x01);
758 reg_w(gspca_dev, 0x78, 0x40);
761 #define WANT_REGULAR_AUTOGAIN
762 #include "autogain_functions.h"
764 static void do_autogain(struct gspca_dev *gspca_dev)
766 struct sd *sd = (struct sd *) gspca_dev;
767 int avg_lum = atomic_read(&sd->avg_lum);
769 const int deadzone = 30;
771 if (sd->autogain_ignore_frames < 0)
774 if (sd->autogain_ignore_frames > 0) {
775 sd->autogain_ignore_frames--;
777 desired_lum = 270 + sd->ctrls[BRIGHTNESS].val;
779 auto_gain_n_exposure(gspca_dev, avg_lum, desired_lum,
780 deadzone, GAIN_KNEE, EXPOSURE_KNEE);
781 sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES;
786 static const u8 jpeg_header[] = {
787 0xff, 0xd8, /* SOI: Start of Image */
789 0xff, 0xc0, /* SOF0: Start of Frame (Baseline DCT) */
790 0x00, 0x11, /* length = 17 bytes (including this length field) */
791 0x08, /* Precision: 8 */
792 0x02, 0x80, /* height = 640 (image rotated) */
793 0x01, 0xe0, /* width = 480 */
794 0x03, /* Number of image components: 3 */
795 0x01, 0x21, 0x00, /* ID=1, Subsampling 1x1, Quantization table: 0 */
796 0x02, 0x11, 0x01, /* ID=2, Subsampling 2x1, Quantization table: 1 */
797 0x03, 0x11, 0x01, /* ID=3, Subsampling 2x1, Quantization table: 1 */
799 0xff, 0xda, /* SOS: Start Of Scan */
800 0x00, 0x0c, /* length = 12 bytes (including this length field) */
801 0x03, /* number of components: 3 */
802 0x01, 0x00, /* selector 1, table 0x00 */
803 0x02, 0x11, /* selector 2, table 0x11 */
804 0x03, 0x11, /* selector 3, table 0x11 */
805 0x00, 0x3f, /* Spectral selection: 0 .. 63 */
806 0x00 /* Successive approximation: 0 */
809 /* this function is run at interrupt level */
810 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
811 u8 *data, /* isoc packet */
812 int len) /* iso packet length */
814 struct sd *sd = (struct sd *) gspca_dev;
818 sof = pac_find_sof(&sd->sof_read, data, len);
820 int n, lum_offset, footer_length;
823 * 6 bytes after the FF D9 EOF marker a number of lumination
824 * bytes are send corresponding to different parts of the
825 * image, the 14th and 15th byte after the EOF seem to
826 * correspond to the center of the image.
828 lum_offset = 61 + sizeof pac_sof_marker;
831 /* Finish decoding current frame */
832 n = (sof - data) - (footer_length + sizeof pac_sof_marker);
834 gspca_dev->image_len += n;
837 gspca_frame_add(gspca_dev, INTER_PACKET, data, n);
840 image = gspca_dev->image;
842 && image[gspca_dev->image_len - 2] == 0xff
843 && image[gspca_dev->image_len - 1] == 0xd9)
844 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
850 /* Get average lumination */
851 if (gspca_dev->last_packet_type == LAST_PACKET &&
853 atomic_set(&sd->avg_lum, data[-lum_offset] +
854 data[-lum_offset + 1]);
856 /* Start the new frame with the jpeg header */
857 /* The PAC7302 has the image rotated 90 degrees */
858 gspca_frame_add(gspca_dev, FIRST_PACKET,
859 jpeg_header, sizeof jpeg_header);
861 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
864 #ifdef CONFIG_VIDEO_ADV_DEBUG
865 static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
866 struct v4l2_dbg_register *reg)
872 * reg->reg: bit0..15: reserved for register index (wIndex is 16bit
873 * long on the USB bus)
875 if (reg->match.type == V4L2_CHIP_MATCH_HOST &&
876 reg->match.addr == 0 &&
877 (reg->reg < 0x000000ff) &&
878 (reg->val <= 0x000000ff)
880 /* Currently writing to page 0 is only supported. */
881 /* reg_w() only supports 8bit index */
886 * Note that there shall be no access to other page
887 * by any other function between the page switch and
888 * the actual register write.
890 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
891 reg_w(gspca_dev, index, value);
893 reg_w(gspca_dev, 0xdc, 0x01);
895 return gspca_dev->usb_err;
898 static int sd_chip_ident(struct gspca_dev *gspca_dev,
899 struct v4l2_dbg_chip_ident *chip)
903 if (chip->match.type == V4L2_CHIP_MATCH_HOST &&
904 chip->match.addr == 0) {
906 chip->ident = V4L2_IDENT_UNKNOWN;
913 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
914 static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
915 u8 *data, /* interrupt packet data */
916 int len) /* interrput packet length */
924 if ((data0 == 0x00 && data1 == 0x11) ||
925 (data0 == 0x22 && data1 == 0x33) ||
926 (data0 == 0x44 && data1 == 0x55) ||
927 (data0 == 0x66 && data1 == 0x77) ||
928 (data0 == 0x88 && data1 == 0x99) ||
929 (data0 == 0xaa && data1 == 0xbb) ||
930 (data0 == 0xcc && data1 == 0xdd) ||
931 (data0 == 0xee && data1 == 0xff)) {
932 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
933 input_sync(gspca_dev->input_dev);
934 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
935 input_sync(gspca_dev->input_dev);
944 /* sub-driver description for pac7302 */
945 static const struct sd_desc sd_desc = {
946 .name = KBUILD_MODNAME,
948 .nctrls = ARRAY_SIZE(sd_ctrls),
954 .pkt_scan = sd_pkt_scan,
955 .dq_callback = do_autogain,
956 #ifdef CONFIG_VIDEO_ADV_DEBUG
957 .set_register = sd_dbg_s_register,
958 .get_chip_ident = sd_chip_ident,
960 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
961 .int_pkt_scan = sd_int_pkt_scan,
965 /* -- module initialisation -- */
966 static const struct usb_device_id device_table[] = {
967 {USB_DEVICE(0x06f8, 0x3009)},
968 {USB_DEVICE(0x06f8, 0x301b)},
969 {USB_DEVICE(0x093a, 0x2620)},
970 {USB_DEVICE(0x093a, 0x2621)},
971 {USB_DEVICE(0x093a, 0x2622), .driver_info = FL_VFLIP},
972 {USB_DEVICE(0x093a, 0x2624), .driver_info = FL_VFLIP},
973 {USB_DEVICE(0x093a, 0x2625)},
974 {USB_DEVICE(0x093a, 0x2626)},
975 {USB_DEVICE(0x093a, 0x2627), .driver_info = FL_VFLIP},
976 {USB_DEVICE(0x093a, 0x2628)},
977 {USB_DEVICE(0x093a, 0x2629), .driver_info = FL_VFLIP},
978 {USB_DEVICE(0x093a, 0x262a)},
979 {USB_DEVICE(0x093a, 0x262c)},
980 {USB_DEVICE(0x145f, 0x013c)},
983 MODULE_DEVICE_TABLE(usb, device_table);
985 /* -- device connect -- */
986 static int sd_probe(struct usb_interface *intf,
987 const struct usb_device_id *id)
989 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
993 static struct usb_driver sd_driver = {
994 .name = KBUILD_MODNAME,
995 .id_table = device_table,
997 .disconnect = gspca_disconnect,
999 .suspend = gspca_suspend,
1000 .resume = gspca_resume,
1004 module_usb_driver(sd_driver);