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 * 0x01 Red balance control
33 * 0x02 Green balance control
34 * 0x03 Blue balance control
35 * The Windows driver uses a quadratic approach to map
36 * the settable values (0-200) on register values:
37 * min=0x20, default=0x40, max=0x80
38 * 0x0f-0x20 Color and saturation control
39 * 0xa2-0xab Brightness, contrast and gamma control
40 * 0xb6 Sharpness control (bits 0-4)
45 * 0x78 Global control, bit 6 controls the LED (inverted)
46 * 0x80 Compression balance, 2 interesting settings:
48 * 0x50 Values >= this switch the camera to a lower compression,
49 * using the same table for both luminance and chrominance.
50 * This gives a sharper picture. Only usable when running
51 * at < 15 fps! Note currently the driver does not use this
52 * as the quality gain is small and the generated JPG-s are
53 * only understood by v4l-utils >= 0.8.9
58 * 0x02 Clock divider 3-63, fps = 90 / val. Must be a multiple of 3 on
59 * the 7302, so one of 3, 6, 9, ..., except when between 6 and 12?
60 * 0x03 Variable framerate ctrl reg2==3: 0 -> ~30 fps, 255 -> ~22fps
61 * 0x04 Another var framerate ctrl reg2==3, reg3==0: 0 -> ~30 fps,
62 * 63 -> ~27 fps, the 2 msb's must always be 1 !!
63 * 0x05 Another var framerate ctrl reg2==3, reg3==0, reg4==0xc0:
64 * 1 -> ~30 fps, 2 -> ~20 fps
65 * 0x0e Exposure bits 0-7, 0-448, 0 = use full frame time
66 * 0x0f Exposure bit 8, 0-448, 448 = no exposure at all
68 * 0x12 Another gain 0-31, unlike 0x10 this one seems to start with an
69 * amplification value of 1 rather then 0 at its lowest setting
70 * 0x21 Bitfield: 0-1 unused, 2-3 vflip/hflip, 4-5 unknown, 6-7 unused
71 * 0x80 Another framerate control, best left at 1, moving it from 1 to
72 * 2 causes the framerate to become 3/4th of what it was, and
73 * also seems to cause pixel averaging, resulting in an effective
74 * resolution of 320x240 and thus a much blockier image
76 * The registers are accessed in the following functions:
78 * Page | Register | Function
79 * -----+------------+---------------------------------------------------
80 * 0 | 0x0f..0x20 | setcolors()
81 * 0 | 0xa2..0xab | setbrightcont()
82 * 0 | 0xb6 | setsharpness()
83 * 0 | 0xc5 | setredbalance()
84 * 0 | 0xc6 | setwhitebalance()
85 * 0 | 0xc7 | setbluebalance()
86 * 0 | 0xdc | setbrightcont(), setcolors()
87 * 3 | 0x02 | setexposure()
88 * 3 | 0x10, 0x12 | setgain()
89 * 3 | 0x11 | setcolors(), setgain(), setexposure(), sethvflip()
90 * 3 | 0x21 | sethvflip()
93 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
95 #include <linux/input.h>
96 #include <media/v4l2-chip-ident.h>
98 /* Include pac common sof detection functions */
99 #include "pac_common.h"
101 #define PAC7302_GAIN_DEFAULT 15
102 #define PAC7302_GAIN_KNEE 42
103 #define PAC7302_EXPOSURE_DEFAULT 66 /* 33 ms / 30 fps */
104 #define PAC7302_EXPOSURE_KNEE 133 /* 66 ms / 15 fps */
106 MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>, "
107 "Thomas Kaiser thomas@kaiser-linux.li");
108 MODULE_DESCRIPTION("Pixart PAC7302");
109 MODULE_LICENSE("GPL");
112 struct gspca_dev gspca_dev; /* !! must be the first item */
114 struct { /* brightness / contrast cluster */
115 struct v4l2_ctrl *brightness;
116 struct v4l2_ctrl *contrast;
118 struct v4l2_ctrl *saturation;
119 struct v4l2_ctrl *white_balance;
120 struct v4l2_ctrl *red_balance;
121 struct v4l2_ctrl *blue_balance;
122 struct { /* flip cluster */
123 struct v4l2_ctrl *hflip;
124 struct v4l2_ctrl *vflip;
126 struct v4l2_ctrl *sharpness;
128 #define FL_HFLIP 0x01 /* mirrored by default */
129 #define FL_VFLIP 0x02 /* vertical flipped by default */
132 s8 autogain_ignore_frames;
137 static const struct v4l2_pix_format vga_mode[] = {
138 {640, 480, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
140 .sizeimage = 640 * 480 * 3 / 8 + 590,
141 .colorspace = V4L2_COLORSPACE_JPEG,
145 #define LOAD_PAGE3 255
146 #define END_OF_SEQUENCE 0
148 static const u8 init_7302[] = {
150 0xff, 0x01, /* page 1 */
151 0x78, 0x00, /* deactivate */
153 0x78, 0x40, /* led off */
155 static const u8 start_7302[] = {
156 /* index, len, [value]* */
157 0xff, 1, 0x00, /* page 0 */
158 0x00, 12, 0x01, 0x40, 0x40, 0x40, 0x01, 0xe0, 0x02, 0x80,
159 0x00, 0x00, 0x00, 0x00,
160 0x0d, 24, 0x03, 0x01, 0x00, 0xb5, 0x07, 0xcb, 0x00, 0x00,
161 0x07, 0xc8, 0x00, 0xea, 0x07, 0xcf, 0x07, 0xf7,
162 0x07, 0x7e, 0x01, 0x0b, 0x00, 0x00, 0x00, 0x11,
166 0x3a, 3, 0x14, 0xff, 0x5a,
167 0x43, 11, 0x00, 0x0a, 0x18, 0x11, 0x01, 0x2c, 0x88, 0x11,
170 0x62, 4, 0x10, 0x1e, 0x1e, 0x18,
172 0x6e, 3, 0x08, 0x06, 0x00,
173 0x72, 3, 0x00, 0xff, 0x00,
174 0x7d, 23, 0x01, 0x01, 0x58, 0x46, 0x50, 0x3c, 0x50, 0x3c,
175 0x54, 0x46, 0x54, 0x56, 0x52, 0x50, 0x52, 0x50,
176 0x56, 0x64, 0xa4, 0x00, 0xda, 0x00, 0x00,
177 0xa2, 10, 0x22, 0x2c, 0x3c, 0x54, 0x69, 0x7c, 0x9c, 0xb9,
182 0xc4, 4, 0xae, 0x01, 0x04, 0x01,
184 0xd1, 11, 0x01, 0x30, 0x49, 0x5e, 0x6f, 0x7f, 0x8e, 0xa9,
187 0xff, 1, 0x01, /* page 1 */
188 0x12, 3, 0x02, 0x00, 0x01,
190 0x76, 5, 0x01, 0x20, 0x40, 0x00, 0xf2,
192 0x7f, 10, 0x4b, 0x0f, 0x01, 0x2c, 0x02, 0x58, 0x03, 0x20,
194 0x96, 5, 0x01, 0x10, 0x04, 0x01, 0x04,
195 0xc8, 14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
196 0x07, 0x00, 0x01, 0x07, 0x04, 0x01,
199 0xde, 7, 0x00, 0x01, 0x04, 0x04, 0x00, 0x00, 0x00,
200 0xe6, 4, 0x00, 0x00, 0x00, 0x01,
202 0xff, 1, 0x02, /* page 2 */
204 0xff, 1, 0x03, /* page 3 */
205 0, LOAD_PAGE3, /* load the page 3 */
207 0xff, 1, 0x02, /* page 2 */
209 0x22, 4, 0x1f, 0xa4, 0xf0, 0x96,
211 0x2a, 5, 0xc8, 0x00, 0x18, 0x12, 0x22,
212 0x64, 8, 0x00, 0x00, 0xf0, 0x01, 0x14, 0x44, 0x44, 0x44,
214 0xff, 1, 0x01, /* page 1 */
216 0, END_OF_SEQUENCE /* end of sequence */
220 /* page 3 - the value SKIP says skip the index - see reg_w_page() */
221 static const u8 page3_7302[] = {
222 0x90, 0x40, 0x03, 0x00, 0xc0, 0x01, 0x14, 0x16,
223 0x14, 0x12, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00,
224 0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
225 0x00, 0x00, 0x00, 0x47, 0x01, 0xb3, 0x01, 0x00,
226 0x00, 0x08, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x21,
227 0x00, 0x00, 0x00, 0x54, 0xf4, 0x02, 0x52, 0x54,
228 0xa4, 0xb8, 0xe0, 0x2a, 0xf6, 0x00, 0x00, 0x00,
229 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
230 0x00, 0xfc, 0x00, 0xf2, 0x1f, 0x04, 0x00, 0x00,
231 SKIP, 0x00, 0x00, 0xc0, 0xc0, 0x10, 0x00, 0x00,
232 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
233 0x00, 0x40, 0xff, 0x03, 0x19, 0x00, 0x00, 0x00,
234 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
235 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc8, 0xc8,
236 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
237 0x08, 0x10, 0x24, 0x40, 0x00, 0x00, 0x00, 0x00,
238 0x01, 0x00, 0x02, 0x47, 0x00, 0x00, 0x00, 0x00,
239 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
240 0x00, 0x02, 0xfa, 0x00, 0x64, 0x5a, 0x28, 0x00,
244 static void reg_w_buf(struct gspca_dev *gspca_dev,
246 const u8 *buffer, int len)
250 if (gspca_dev->usb_err < 0)
252 memcpy(gspca_dev->usb_buf, buffer, len);
253 ret = usb_control_msg(gspca_dev->dev,
254 usb_sndctrlpipe(gspca_dev->dev, 0),
256 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
258 index, gspca_dev->usb_buf, len,
261 pr_err("reg_w_buf failed i: %02x error %d\n",
263 gspca_dev->usb_err = ret;
268 static void reg_w(struct gspca_dev *gspca_dev,
274 if (gspca_dev->usb_err < 0)
276 gspca_dev->usb_buf[0] = value;
277 ret = usb_control_msg(gspca_dev->dev,
278 usb_sndctrlpipe(gspca_dev->dev, 0),
280 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
281 0, index, gspca_dev->usb_buf, 1,
284 pr_err("reg_w() failed i: %02x v: %02x error %d\n",
286 gspca_dev->usb_err = ret;
290 static void reg_w_seq(struct gspca_dev *gspca_dev,
291 const u8 *seq, int len)
294 reg_w(gspca_dev, seq[0], seq[1]);
299 /* load the beginning of a page */
300 static void reg_w_page(struct gspca_dev *gspca_dev,
301 const u8 *page, int len)
306 if (gspca_dev->usb_err < 0)
308 for (index = 0; index < len; index++) {
309 if (page[index] == SKIP) /* skip this index */
311 gspca_dev->usb_buf[0] = page[index];
312 ret = usb_control_msg(gspca_dev->dev,
313 usb_sndctrlpipe(gspca_dev->dev, 0),
315 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
316 0, index, gspca_dev->usb_buf, 1,
319 pr_err("reg_w_page() failed i: %02x v: %02x error %d\n",
320 index, page[index], ret);
321 gspca_dev->usb_err = ret;
327 /* output a variable sequence */
328 static void reg_w_var(struct gspca_dev *gspca_dev,
330 const u8 *page3, unsigned int page3_len)
338 case END_OF_SEQUENCE:
341 reg_w_page(gspca_dev, page3, page3_len);
345 if (len > USB_BUF_SZ) {
346 PDEBUG(D_ERR|D_STREAM,
347 "Incorrect variable sequence");
358 reg_w_buf(gspca_dev, index, seq, 8);
368 /* this function is called at probe time for pac7302 */
369 static int sd_config(struct gspca_dev *gspca_dev,
370 const struct usb_device_id *id)
372 struct sd *sd = (struct sd *) gspca_dev;
375 cam = &gspca_dev->cam;
377 cam->cam_mode = vga_mode; /* only 640x480 */
378 cam->nmodes = ARRAY_SIZE(vga_mode);
380 sd->flags = id->driver_info;
384 static void setbrightcont(struct gspca_dev *gspca_dev)
386 struct sd *sd = (struct sd *) gspca_dev;
388 static const u8 max[10] =
389 {0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb,
391 static const u8 delta[10] =
392 {0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17,
395 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
396 for (i = 0; i < 10; i++) {
398 v += (sd->brightness->val - sd->brightness->maximum)
399 * 150 / sd->brightness->maximum; /* 200 ? */
400 v -= delta[i] * sd->contrast->val / sd->contrast->maximum;
405 reg_w(gspca_dev, 0xa2 + i, v);
407 reg_w(gspca_dev, 0xdc, 0x01);
410 static void setcolors(struct gspca_dev *gspca_dev)
412 struct sd *sd = (struct sd *) gspca_dev;
414 static const int a[9] =
415 {217, -212, 0, -101, 170, -67, -38, -315, 355};
416 static const int b[9] =
417 {19, 106, 0, 19, 106, 1, 19, 106, 1};
419 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
420 reg_w(gspca_dev, 0x11, 0x01);
421 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
422 for (i = 0; i < 9; i++) {
423 v = a[i] * sd->saturation->val / sd->saturation->maximum;
425 reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07);
426 reg_w(gspca_dev, 0x0f + 2 * i + 1, v);
428 reg_w(gspca_dev, 0xdc, 0x01);
431 static void setwhitebalance(struct gspca_dev *gspca_dev)
433 struct sd *sd = (struct sd *) gspca_dev;
435 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
436 reg_w(gspca_dev, 0xc6, sd->white_balance->val);
438 reg_w(gspca_dev, 0xdc, 0x01);
441 static void setredbalance(struct gspca_dev *gspca_dev)
443 struct sd *sd = (struct sd *) gspca_dev;
445 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
446 reg_w(gspca_dev, 0xc5, sd->red_balance->val);
448 reg_w(gspca_dev, 0xdc, 0x01);
451 static void setbluebalance(struct gspca_dev *gspca_dev)
453 struct sd *sd = (struct sd *) gspca_dev;
455 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
456 reg_w(gspca_dev, 0xc7, sd->blue_balance->val);
458 reg_w(gspca_dev, 0xdc, 0x01);
461 static void setgain(struct gspca_dev *gspca_dev)
465 if (gspca_dev->gain->val < 32) {
466 reg10 = gspca_dev->gain->val;
470 reg12 = gspca_dev->gain->val - 31;
473 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
474 reg_w(gspca_dev, 0x10, reg10);
475 reg_w(gspca_dev, 0x12, reg12);
477 /* load registers to sensor (Bit 0, auto clear) */
478 reg_w(gspca_dev, 0x11, 0x01);
481 static void setexposure(struct gspca_dev *gspca_dev)
487 * Register 2 of frame 3 contains the clock divider configuring the
488 * no fps according to the formula: 90 / reg. sd->exposure is the
489 * desired exposure time in 0.5 ms.
491 clockdiv = (90 * gspca_dev->exposure->val + 1999) / 2000;
494 * Note clockdiv = 3 also works, but when running at 30 fps, depending
495 * on the scene being recorded, the camera switches to another
496 * quantization table for certain JPEG blocks, and we don't know how
497 * to decompress these blocks. So we cap the framerate at 15 fps.
501 else if (clockdiv > 63)
505 * Register 2 MUST be a multiple of 3, except when between 6 and 12?
506 * Always round up, otherwise we cannot get the desired frametime
507 * using the partial frame time exposure control.
509 if (clockdiv < 6 || clockdiv > 12)
510 clockdiv = ((clockdiv + 2) / 3) * 3;
513 * frame exposure time in ms = 1000 * clockdiv / 90 ->
514 * exposure = (sd->exposure / 2) * 448 / (1000 * clockdiv / 90)
516 exposure = (gspca_dev->exposure->val * 45 * 448) / (1000 * clockdiv);
517 /* 0 = use full frametime, 448 = no exposure, reverse it */
518 exposure = 448 - exposure;
520 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
521 reg_w(gspca_dev, 0x02, clockdiv);
522 reg_w(gspca_dev, 0x0e, exposure & 0xff);
523 reg_w(gspca_dev, 0x0f, exposure >> 8);
525 /* load registers to sensor (Bit 0, auto clear) */
526 reg_w(gspca_dev, 0x11, 0x01);
529 static void sethvflip(struct gspca_dev *gspca_dev)
531 struct sd *sd = (struct sd *) gspca_dev;
532 u8 data, hflip, vflip;
534 hflip = sd->hflip->val;
535 if (sd->flags & FL_HFLIP)
537 vflip = sd->vflip->val;
538 if (sd->flags & FL_VFLIP)
541 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
542 data = (hflip ? 0x08 : 0x00) | (vflip ? 0x04 : 0x00);
543 reg_w(gspca_dev, 0x21, data);
545 /* load registers to sensor (Bit 0, auto clear) */
546 reg_w(gspca_dev, 0x11, 0x01);
549 static void setsharpness(struct gspca_dev *gspca_dev)
551 struct sd *sd = (struct sd *) gspca_dev;
553 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
554 reg_w(gspca_dev, 0xb6, sd->sharpness->val);
556 reg_w(gspca_dev, 0xdc, 0x01);
559 /* this function is called at probe and resume time for pac7302 */
560 static int sd_init(struct gspca_dev *gspca_dev)
562 reg_w_seq(gspca_dev, init_7302, sizeof(init_7302)/2);
563 return gspca_dev->usb_err;
566 static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
568 struct gspca_dev *gspca_dev =
569 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
570 struct sd *sd = (struct sd *)gspca_dev;
572 gspca_dev->usb_err = 0;
574 if (ctrl->id == V4L2_CID_AUTOGAIN && ctrl->is_new && ctrl->val) {
575 /* when switching to autogain set defaults to make sure
576 we are on a valid point of the autogain gain /
577 exposure knee graph, and give this change time to
578 take effect before doing autogain. */
579 gspca_dev->exposure->val = PAC7302_EXPOSURE_DEFAULT;
580 gspca_dev->gain->val = PAC7302_GAIN_DEFAULT;
581 sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES;
584 if (!gspca_dev->streaming)
588 case V4L2_CID_BRIGHTNESS:
589 setbrightcont(gspca_dev);
591 case V4L2_CID_SATURATION:
592 setcolors(gspca_dev);
594 case V4L2_CID_WHITE_BALANCE_TEMPERATURE:
595 setwhitebalance(gspca_dev);
597 case V4L2_CID_RED_BALANCE:
598 setredbalance(gspca_dev);
600 case V4L2_CID_BLUE_BALANCE:
601 setbluebalance(gspca_dev);
603 case V4L2_CID_AUTOGAIN:
604 if (gspca_dev->exposure->is_new || (ctrl->is_new && ctrl->val))
605 setexposure(gspca_dev);
606 if (gspca_dev->gain->is_new || (ctrl->is_new && ctrl->val))
610 sethvflip(gspca_dev);
612 case V4L2_CID_SHARPNESS:
613 setsharpness(gspca_dev);
618 return gspca_dev->usb_err;
621 static const struct v4l2_ctrl_ops sd_ctrl_ops = {
625 /* this function is called at probe time */
626 static int sd_init_controls(struct gspca_dev *gspca_dev)
628 struct sd *sd = (struct sd *) gspca_dev;
629 struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
631 gspca_dev->vdev.ctrl_handler = hdl;
632 v4l2_ctrl_handler_init(hdl, 12);
634 sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
635 V4L2_CID_BRIGHTNESS, 0, 32, 1, 16);
636 sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
637 V4L2_CID_CONTRAST, 0, 255, 1, 127);
639 sd->saturation = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
640 V4L2_CID_SATURATION, 0, 255, 1, 127);
641 sd->white_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
642 V4L2_CID_WHITE_BALANCE_TEMPERATURE,
644 sd->red_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
645 V4L2_CID_RED_BALANCE, 0, 3, 1, 1);
646 sd->blue_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
647 V4L2_CID_BLUE_BALANCE, 0, 3, 1, 1);
649 gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
650 V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
651 gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
652 V4L2_CID_EXPOSURE, 0, 1023, 1,
653 PAC7302_EXPOSURE_DEFAULT);
654 gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
655 V4L2_CID_GAIN, 0, 62, 1,
656 PAC7302_GAIN_DEFAULT);
658 sd->hflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
659 V4L2_CID_HFLIP, 0, 1, 1, 0);
660 sd->vflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
661 V4L2_CID_VFLIP, 0, 1, 1, 0);
663 sd->sharpness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
664 V4L2_CID_SHARPNESS, 0, 15, 1, 8);
667 pr_err("Could not initialize controls\n");
671 v4l2_ctrl_cluster(2, &sd->brightness);
672 v4l2_ctrl_auto_cluster(3, &gspca_dev->autogain, 0, false);
673 v4l2_ctrl_cluster(2, &sd->hflip);
677 /* -- start the camera -- */
678 static int sd_start(struct gspca_dev *gspca_dev)
680 struct sd *sd = (struct sd *) gspca_dev;
682 reg_w_var(gspca_dev, start_7302,
683 page3_7302, sizeof(page3_7302));
686 sd->autogain_ignore_frames = 0;
687 atomic_set(&sd->avg_lum, 270 + sd->brightness->val);
690 reg_w(gspca_dev, 0xff, 0x01);
691 reg_w(gspca_dev, 0x78, 0x01);
693 return gspca_dev->usb_err;
696 static void sd_stopN(struct gspca_dev *gspca_dev)
700 reg_w(gspca_dev, 0xff, 0x01);
701 reg_w(gspca_dev, 0x78, 0x00);
704 /* called on streamoff with alt 0 and on disconnect for pac7302 */
705 static void sd_stop0(struct gspca_dev *gspca_dev)
707 if (!gspca_dev->present)
709 reg_w(gspca_dev, 0xff, 0x01);
710 reg_w(gspca_dev, 0x78, 0x40);
713 static void do_autogain(struct gspca_dev *gspca_dev)
715 struct sd *sd = (struct sd *) gspca_dev;
716 int avg_lum = atomic_read(&sd->avg_lum);
718 const int deadzone = 30;
720 if (sd->autogain_ignore_frames < 0)
723 if (sd->autogain_ignore_frames > 0) {
724 sd->autogain_ignore_frames--;
726 desired_lum = 270 + sd->brightness->val;
728 if (gspca_expo_autogain(gspca_dev, avg_lum, desired_lum,
729 deadzone, PAC7302_GAIN_KNEE,
730 PAC7302_EXPOSURE_KNEE))
731 sd->autogain_ignore_frames =
732 PAC_AUTOGAIN_IGNORE_FRAMES;
737 static const u8 jpeg_header[] = {
738 0xff, 0xd8, /* SOI: Start of Image */
740 0xff, 0xc0, /* SOF0: Start of Frame (Baseline DCT) */
741 0x00, 0x11, /* length = 17 bytes (including this length field) */
742 0x08, /* Precision: 8 */
743 0x02, 0x80, /* height = 640 (image rotated) */
744 0x01, 0xe0, /* width = 480 */
745 0x03, /* Number of image components: 3 */
746 0x01, 0x21, 0x00, /* ID=1, Subsampling 1x1, Quantization table: 0 */
747 0x02, 0x11, 0x01, /* ID=2, Subsampling 2x1, Quantization table: 1 */
748 0x03, 0x11, 0x01, /* ID=3, Subsampling 2x1, Quantization table: 1 */
750 0xff, 0xda, /* SOS: Start Of Scan */
751 0x00, 0x0c, /* length = 12 bytes (including this length field) */
752 0x03, /* number of components: 3 */
753 0x01, 0x00, /* selector 1, table 0x00 */
754 0x02, 0x11, /* selector 2, table 0x11 */
755 0x03, 0x11, /* selector 3, table 0x11 */
756 0x00, 0x3f, /* Spectral selection: 0 .. 63 */
757 0x00 /* Successive approximation: 0 */
760 /* this function is run at interrupt level */
761 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
762 u8 *data, /* isoc packet */
763 int len) /* iso packet length */
765 struct sd *sd = (struct sd *) gspca_dev;
769 sof = pac_find_sof(&sd->sof_read, data, len);
771 int n, lum_offset, footer_length;
774 * 6 bytes after the FF D9 EOF marker a number of lumination
775 * bytes are send corresponding to different parts of the
776 * image, the 14th and 15th byte after the EOF seem to
777 * correspond to the center of the image.
779 lum_offset = 61 + sizeof pac_sof_marker;
782 /* Finish decoding current frame */
783 n = (sof - data) - (footer_length + sizeof pac_sof_marker);
785 gspca_dev->image_len += n;
788 gspca_frame_add(gspca_dev, INTER_PACKET, data, n);
791 image = gspca_dev->image;
793 && image[gspca_dev->image_len - 2] == 0xff
794 && image[gspca_dev->image_len - 1] == 0xd9)
795 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
801 /* Get average lumination */
802 if (gspca_dev->last_packet_type == LAST_PACKET &&
804 atomic_set(&sd->avg_lum, data[-lum_offset] +
805 data[-lum_offset + 1]);
807 /* Start the new frame with the jpeg header */
808 /* The PAC7302 has the image rotated 90 degrees */
809 gspca_frame_add(gspca_dev, FIRST_PACKET,
810 jpeg_header, sizeof jpeg_header);
812 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
815 #ifdef CONFIG_VIDEO_ADV_DEBUG
816 static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
817 struct v4l2_dbg_register *reg)
823 * reg->reg: bit0..15: reserved for register index (wIndex is 16bit
824 * long on the USB bus)
826 if (reg->match.type == V4L2_CHIP_MATCH_HOST &&
827 reg->match.addr == 0 &&
828 (reg->reg < 0x000000ff) &&
829 (reg->val <= 0x000000ff)
831 /* Currently writing to page 0 is only supported. */
832 /* reg_w() only supports 8bit index */
837 * Note that there shall be no access to other page
838 * by any other function between the page switch and
839 * the actual register write.
841 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
842 reg_w(gspca_dev, index, value);
844 reg_w(gspca_dev, 0xdc, 0x01);
846 return gspca_dev->usb_err;
849 static int sd_chip_ident(struct gspca_dev *gspca_dev,
850 struct v4l2_dbg_chip_ident *chip)
854 if (chip->match.type == V4L2_CHIP_MATCH_HOST &&
855 chip->match.addr == 0) {
857 chip->ident = V4L2_IDENT_UNKNOWN;
864 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
865 static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
866 u8 *data, /* interrupt packet data */
867 int len) /* interrput packet length */
875 if ((data0 == 0x00 && data1 == 0x11) ||
876 (data0 == 0x22 && data1 == 0x33) ||
877 (data0 == 0x44 && data1 == 0x55) ||
878 (data0 == 0x66 && data1 == 0x77) ||
879 (data0 == 0x88 && data1 == 0x99) ||
880 (data0 == 0xaa && data1 == 0xbb) ||
881 (data0 == 0xcc && data1 == 0xdd) ||
882 (data0 == 0xee && data1 == 0xff)) {
883 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
884 input_sync(gspca_dev->input_dev);
885 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
886 input_sync(gspca_dev->input_dev);
895 /* sub-driver description for pac7302 */
896 static const struct sd_desc sd_desc = {
897 .name = KBUILD_MODNAME,
900 .init_controls = sd_init_controls,
904 .pkt_scan = sd_pkt_scan,
905 .dq_callback = do_autogain,
906 #ifdef CONFIG_VIDEO_ADV_DEBUG
907 .set_register = sd_dbg_s_register,
908 .get_chip_ident = sd_chip_ident,
910 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
911 .int_pkt_scan = sd_int_pkt_scan,
915 /* -- module initialisation -- */
916 static const struct usb_device_id device_table[] = {
917 {USB_DEVICE(0x06f8, 0x3009)},
918 {USB_DEVICE(0x06f8, 0x301b)},
919 {USB_DEVICE(0x093a, 0x2620)},
920 {USB_DEVICE(0x093a, 0x2621)},
921 {USB_DEVICE(0x093a, 0x2622), .driver_info = FL_VFLIP},
922 {USB_DEVICE(0x093a, 0x2624), .driver_info = FL_VFLIP},
923 {USB_DEVICE(0x093a, 0x2625)},
924 {USB_DEVICE(0x093a, 0x2626)},
925 {USB_DEVICE(0x093a, 0x2627), .driver_info = FL_VFLIP},
926 {USB_DEVICE(0x093a, 0x2628)},
927 {USB_DEVICE(0x093a, 0x2629), .driver_info = FL_VFLIP},
928 {USB_DEVICE(0x093a, 0x262a)},
929 {USB_DEVICE(0x093a, 0x262c)},
930 {USB_DEVICE(0x145f, 0x013c)},
931 {USB_DEVICE(0x1ae7, 0x2001)}, /* SpeedLink Snappy Mic SL-6825-SBK */
934 MODULE_DEVICE_TABLE(usb, device_table);
936 /* -- device connect -- */
937 static int sd_probe(struct usb_interface *intf,
938 const struct usb_device_id *id)
940 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
944 static struct usb_driver sd_driver = {
945 .name = KBUILD_MODNAME,
946 .id_table = device_table,
948 .disconnect = gspca_disconnect,
950 .suspend = gspca_suspend,
951 .resume = gspca_resume,
952 .reset_resume = gspca_resume,
956 module_usb_driver(sd_driver);