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 | 0x01 | setredbalance()
81 * 0 | 0x03 | setbluebalance()
82 * 0 | 0x0f..0x20 | setcolors()
83 * 0 | 0xa2..0xab | setbrightcont()
84 * 0 | 0xb6 | setsharpness()
85 * 0 | 0xc6 | setwhitebalance()
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_RGB_BALANCE_MIN 0
102 #define PAC7302_RGB_BALANCE_MAX 200
103 #define PAC7302_RGB_BALANCE_DEFAULT 100
104 #define PAC7302_GAIN_DEFAULT 15
105 #define PAC7302_GAIN_KNEE 42
106 #define PAC7302_EXPOSURE_DEFAULT 66 /* 33 ms / 30 fps */
107 #define PAC7302_EXPOSURE_KNEE 133 /* 66 ms / 15 fps */
109 MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>, "
110 "Thomas Kaiser thomas@kaiser-linux.li");
111 MODULE_DESCRIPTION("Pixart PAC7302");
112 MODULE_LICENSE("GPL");
115 struct gspca_dev gspca_dev; /* !! must be the first item */
117 struct { /* brightness / contrast cluster */
118 struct v4l2_ctrl *brightness;
119 struct v4l2_ctrl *contrast;
121 struct v4l2_ctrl *saturation;
122 struct v4l2_ctrl *white_balance;
123 struct v4l2_ctrl *red_balance;
124 struct v4l2_ctrl *blue_balance;
125 struct { /* flip cluster */
126 struct v4l2_ctrl *hflip;
127 struct v4l2_ctrl *vflip;
129 struct v4l2_ctrl *sharpness;
131 #define FL_HFLIP 0x01 /* mirrored by default */
132 #define FL_VFLIP 0x02 /* vertical flipped by default */
135 s8 autogain_ignore_frames;
140 static const struct v4l2_pix_format vga_mode[] = {
141 {640, 480, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
143 .sizeimage = 640 * 480 * 3 / 8 + 590,
144 .colorspace = V4L2_COLORSPACE_JPEG,
148 #define LOAD_PAGE3 255
149 #define END_OF_SEQUENCE 0
151 static const u8 init_7302[] = {
153 0xff, 0x01, /* page 1 */
154 0x78, 0x00, /* deactivate */
156 0x78, 0x40, /* led off */
158 static const u8 start_7302[] = {
159 /* index, len, [value]* */
160 0xff, 1, 0x00, /* page 0 */
161 0x00, 12, 0x01, 0x40, 0x40, 0x40, 0x01, 0xe0, 0x02, 0x80,
162 0x00, 0x00, 0x00, 0x00,
163 0x0d, 24, 0x03, 0x01, 0x00, 0xb5, 0x07, 0xcb, 0x00, 0x00,
164 0x07, 0xc8, 0x00, 0xea, 0x07, 0xcf, 0x07, 0xf7,
165 0x07, 0x7e, 0x01, 0x0b, 0x00, 0x00, 0x00, 0x11,
169 0x3a, 3, 0x14, 0xff, 0x5a,
170 0x43, 11, 0x00, 0x0a, 0x18, 0x11, 0x01, 0x2c, 0x88, 0x11,
173 0x62, 4, 0x10, 0x1e, 0x1e, 0x18,
175 0x6e, 3, 0x08, 0x06, 0x00,
176 0x72, 3, 0x00, 0xff, 0x00,
177 0x7d, 23, 0x01, 0x01, 0x58, 0x46, 0x50, 0x3c, 0x50, 0x3c,
178 0x54, 0x46, 0x54, 0x56, 0x52, 0x50, 0x52, 0x50,
179 0x56, 0x64, 0xa4, 0x00, 0xda, 0x00, 0x00,
180 0xa2, 10, 0x22, 0x2c, 0x3c, 0x54, 0x69, 0x7c, 0x9c, 0xb9,
185 0xc4, 4, 0xae, 0x01, 0x04, 0x01,
187 0xd1, 11, 0x01, 0x30, 0x49, 0x5e, 0x6f, 0x7f, 0x8e, 0xa9,
190 0xff, 1, 0x01, /* page 1 */
191 0x12, 3, 0x02, 0x00, 0x01,
193 0x76, 5, 0x01, 0x20, 0x40, 0x00, 0xf2,
195 0x7f, 10, 0x4b, 0x0f, 0x01, 0x2c, 0x02, 0x58, 0x03, 0x20,
197 0x96, 5, 0x01, 0x10, 0x04, 0x01, 0x04,
198 0xc8, 14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
199 0x07, 0x00, 0x01, 0x07, 0x04, 0x01,
202 0xde, 7, 0x00, 0x01, 0x04, 0x04, 0x00, 0x00, 0x00,
203 0xe6, 4, 0x00, 0x00, 0x00, 0x01,
205 0xff, 1, 0x02, /* page 2 */
207 0xff, 1, 0x03, /* page 3 */
208 0, LOAD_PAGE3, /* load the page 3 */
210 0xff, 1, 0x02, /* page 2 */
212 0x22, 4, 0x1f, 0xa4, 0xf0, 0x96,
214 0x2a, 5, 0xc8, 0x00, 0x18, 0x12, 0x22,
215 0x64, 8, 0x00, 0x00, 0xf0, 0x01, 0x14, 0x44, 0x44, 0x44,
217 0xff, 1, 0x01, /* page 1 */
219 0, END_OF_SEQUENCE /* end of sequence */
223 /* page 3 - the value SKIP says skip the index - see reg_w_page() */
224 static const u8 page3_7302[] = {
225 0x90, 0x40, 0x03, 0x00, 0xc0, 0x01, 0x14, 0x16,
226 0x14, 0x12, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00,
227 0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
228 0x00, 0x00, 0x00, 0x47, 0x01, 0xb3, 0x01, 0x00,
229 0x00, 0x08, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x21,
230 0x00, 0x00, 0x00, 0x54, 0xf4, 0x02, 0x52, 0x54,
231 0xa4, 0xb8, 0xe0, 0x2a, 0xf6, 0x00, 0x00, 0x00,
232 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
233 0x00, 0xfc, 0x00, 0xf2, 0x1f, 0x04, 0x00, 0x00,
234 SKIP, 0x00, 0x00, 0xc0, 0xc0, 0x10, 0x00, 0x00,
235 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
236 0x00, 0x40, 0xff, 0x03, 0x19, 0x00, 0x00, 0x00,
237 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
238 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc8, 0xc8,
239 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
240 0x08, 0x10, 0x24, 0x40, 0x00, 0x00, 0x00, 0x00,
241 0x01, 0x00, 0x02, 0x47, 0x00, 0x00, 0x00, 0x00,
242 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
243 0x00, 0x02, 0xfa, 0x00, 0x64, 0x5a, 0x28, 0x00,
247 static void reg_w_buf(struct gspca_dev *gspca_dev,
249 const u8 *buffer, int len)
253 if (gspca_dev->usb_err < 0)
255 memcpy(gspca_dev->usb_buf, buffer, len);
256 ret = usb_control_msg(gspca_dev->dev,
257 usb_sndctrlpipe(gspca_dev->dev, 0),
259 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
261 index, gspca_dev->usb_buf, len,
264 pr_err("reg_w_buf failed i: %02x error %d\n",
266 gspca_dev->usb_err = ret;
271 static void reg_w(struct gspca_dev *gspca_dev,
277 if (gspca_dev->usb_err < 0)
279 gspca_dev->usb_buf[0] = value;
280 ret = usb_control_msg(gspca_dev->dev,
281 usb_sndctrlpipe(gspca_dev->dev, 0),
283 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
284 0, index, gspca_dev->usb_buf, 1,
287 pr_err("reg_w() failed i: %02x v: %02x error %d\n",
289 gspca_dev->usb_err = ret;
293 static void reg_w_seq(struct gspca_dev *gspca_dev,
294 const u8 *seq, int len)
297 reg_w(gspca_dev, seq[0], seq[1]);
302 /* load the beginning of a page */
303 static void reg_w_page(struct gspca_dev *gspca_dev,
304 const u8 *page, int len)
309 if (gspca_dev->usb_err < 0)
311 for (index = 0; index < len; index++) {
312 if (page[index] == SKIP) /* skip this index */
314 gspca_dev->usb_buf[0] = page[index];
315 ret = usb_control_msg(gspca_dev->dev,
316 usb_sndctrlpipe(gspca_dev->dev, 0),
318 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
319 0, index, gspca_dev->usb_buf, 1,
322 pr_err("reg_w_page() failed i: %02x v: %02x error %d\n",
323 index, page[index], ret);
324 gspca_dev->usb_err = ret;
330 /* output a variable sequence */
331 static void reg_w_var(struct gspca_dev *gspca_dev,
333 const u8 *page3, unsigned int page3_len)
341 case END_OF_SEQUENCE:
344 reg_w_page(gspca_dev, page3, page3_len);
347 if (len > USB_BUF_SZ) {
348 PERR("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 u8 rgbbalance_ctrl_to_reg_value(s32 rgb_ctrl_val)
443 const unsigned int k = 1000; /* precision factor */
446 /* Normed value [0...k] */
447 norm = k * (rgb_ctrl_val - PAC7302_RGB_BALANCE_MIN)
448 / (PAC7302_RGB_BALANCE_MAX - PAC7302_RGB_BALANCE_MIN);
449 /* Qudratic apporach improves control at small (register) values: */
450 return 64 * norm * norm / (k*k) + 32 * norm / k + 32;
451 /* Y = 64*X*X + 32*X + 32
452 * => register values 0x20-0x80; Windows driver uses these limits */
454 /* NOTE: for full value range (0x00-0xff) use
456 * => 254 * norm * norm / (k*k) + 1 * norm / k */
459 static void setredbalance(struct gspca_dev *gspca_dev)
461 struct sd *sd = (struct sd *) gspca_dev;
463 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
464 reg_w(gspca_dev, 0x01,
465 rgbbalance_ctrl_to_reg_value(sd->red_balance->val));
467 reg_w(gspca_dev, 0xdc, 0x01);
470 static void setbluebalance(struct gspca_dev *gspca_dev)
472 struct sd *sd = (struct sd *) gspca_dev;
474 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
475 reg_w(gspca_dev, 0x03,
476 rgbbalance_ctrl_to_reg_value(sd->blue_balance->val));
478 reg_w(gspca_dev, 0xdc, 0x01);
481 static void setgain(struct gspca_dev *gspca_dev)
485 if (gspca_dev->gain->val < 32) {
486 reg10 = gspca_dev->gain->val;
490 reg12 = gspca_dev->gain->val - 31;
493 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
494 reg_w(gspca_dev, 0x10, reg10);
495 reg_w(gspca_dev, 0x12, reg12);
497 /* load registers to sensor (Bit 0, auto clear) */
498 reg_w(gspca_dev, 0x11, 0x01);
501 static void setexposure(struct gspca_dev *gspca_dev)
507 * Register 2 of frame 3 contains the clock divider configuring the
508 * no fps according to the formula: 90 / reg. sd->exposure is the
509 * desired exposure time in 0.5 ms.
511 clockdiv = (90 * gspca_dev->exposure->val + 1999) / 2000;
514 * Note clockdiv = 3 also works, but when running at 30 fps, depending
515 * on the scene being recorded, the camera switches to another
516 * quantization table for certain JPEG blocks, and we don't know how
517 * to decompress these blocks. So we cap the framerate at 15 fps.
521 else if (clockdiv > 63)
525 * Register 2 MUST be a multiple of 3, except when between 6 and 12?
526 * Always round up, otherwise we cannot get the desired frametime
527 * using the partial frame time exposure control.
529 if (clockdiv < 6 || clockdiv > 12)
530 clockdiv = ((clockdiv + 2) / 3) * 3;
533 * frame exposure time in ms = 1000 * clockdiv / 90 ->
534 * exposure = (sd->exposure / 2) * 448 / (1000 * clockdiv / 90)
536 exposure = (gspca_dev->exposure->val * 45 * 448) / (1000 * clockdiv);
537 /* 0 = use full frametime, 448 = no exposure, reverse it */
538 exposure = 448 - exposure;
540 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
541 reg_w(gspca_dev, 0x02, clockdiv);
542 reg_w(gspca_dev, 0x0e, exposure & 0xff);
543 reg_w(gspca_dev, 0x0f, exposure >> 8);
545 /* load registers to sensor (Bit 0, auto clear) */
546 reg_w(gspca_dev, 0x11, 0x01);
549 static void sethvflip(struct gspca_dev *gspca_dev)
551 struct sd *sd = (struct sd *) gspca_dev;
552 u8 data, hflip, vflip;
554 hflip = sd->hflip->val;
555 if (sd->flags & FL_HFLIP)
557 vflip = sd->vflip->val;
558 if (sd->flags & FL_VFLIP)
561 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
562 data = (hflip ? 0x08 : 0x00) | (vflip ? 0x04 : 0x00);
563 reg_w(gspca_dev, 0x21, data);
565 /* load registers to sensor (Bit 0, auto clear) */
566 reg_w(gspca_dev, 0x11, 0x01);
569 static void setsharpness(struct gspca_dev *gspca_dev)
571 struct sd *sd = (struct sd *) gspca_dev;
573 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
574 reg_w(gspca_dev, 0xb6, sd->sharpness->val);
576 reg_w(gspca_dev, 0xdc, 0x01);
579 /* this function is called at probe and resume time for pac7302 */
580 static int sd_init(struct gspca_dev *gspca_dev)
582 reg_w_seq(gspca_dev, init_7302, sizeof(init_7302)/2);
583 return gspca_dev->usb_err;
586 static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
588 struct gspca_dev *gspca_dev =
589 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
590 struct sd *sd = (struct sd *)gspca_dev;
592 gspca_dev->usb_err = 0;
594 if (ctrl->id == V4L2_CID_AUTOGAIN && ctrl->is_new && ctrl->val) {
595 /* when switching to autogain set defaults to make sure
596 we are on a valid point of the autogain gain /
597 exposure knee graph, and give this change time to
598 take effect before doing autogain. */
599 gspca_dev->exposure->val = PAC7302_EXPOSURE_DEFAULT;
600 gspca_dev->gain->val = PAC7302_GAIN_DEFAULT;
601 sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES;
604 if (!gspca_dev->streaming)
608 case V4L2_CID_BRIGHTNESS:
609 setbrightcont(gspca_dev);
611 case V4L2_CID_SATURATION:
612 setcolors(gspca_dev);
614 case V4L2_CID_WHITE_BALANCE_TEMPERATURE:
615 setwhitebalance(gspca_dev);
617 case V4L2_CID_RED_BALANCE:
618 setredbalance(gspca_dev);
620 case V4L2_CID_BLUE_BALANCE:
621 setbluebalance(gspca_dev);
623 case V4L2_CID_AUTOGAIN:
624 if (gspca_dev->exposure->is_new || (ctrl->is_new && ctrl->val))
625 setexposure(gspca_dev);
626 if (gspca_dev->gain->is_new || (ctrl->is_new && ctrl->val))
630 sethvflip(gspca_dev);
632 case V4L2_CID_SHARPNESS:
633 setsharpness(gspca_dev);
638 return gspca_dev->usb_err;
641 static const struct v4l2_ctrl_ops sd_ctrl_ops = {
645 /* this function is called at probe time */
646 static int sd_init_controls(struct gspca_dev *gspca_dev)
648 struct sd *sd = (struct sd *) gspca_dev;
649 struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
651 gspca_dev->vdev.ctrl_handler = hdl;
652 v4l2_ctrl_handler_init(hdl, 12);
654 sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
655 V4L2_CID_BRIGHTNESS, 0, 32, 1, 16);
656 sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
657 V4L2_CID_CONTRAST, 0, 255, 1, 127);
659 sd->saturation = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
660 V4L2_CID_SATURATION, 0, 255, 1, 127);
661 sd->white_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
662 V4L2_CID_WHITE_BALANCE_TEMPERATURE,
664 sd->red_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
665 V4L2_CID_RED_BALANCE,
666 PAC7302_RGB_BALANCE_MIN,
667 PAC7302_RGB_BALANCE_MAX,
668 1, PAC7302_RGB_BALANCE_DEFAULT);
669 sd->blue_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
670 V4L2_CID_BLUE_BALANCE,
671 PAC7302_RGB_BALANCE_MIN,
672 PAC7302_RGB_BALANCE_MAX,
673 1, PAC7302_RGB_BALANCE_DEFAULT);
675 gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
676 V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
677 gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
678 V4L2_CID_EXPOSURE, 0, 1023, 1,
679 PAC7302_EXPOSURE_DEFAULT);
680 gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
681 V4L2_CID_GAIN, 0, 62, 1,
682 PAC7302_GAIN_DEFAULT);
684 sd->hflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
685 V4L2_CID_HFLIP, 0, 1, 1, 0);
686 sd->vflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
687 V4L2_CID_VFLIP, 0, 1, 1, 0);
689 sd->sharpness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
690 V4L2_CID_SHARPNESS, 0, 15, 1, 8);
693 pr_err("Could not initialize controls\n");
697 v4l2_ctrl_cluster(2, &sd->brightness);
698 v4l2_ctrl_auto_cluster(3, &gspca_dev->autogain, 0, false);
699 v4l2_ctrl_cluster(2, &sd->hflip);
703 /* -- start the camera -- */
704 static int sd_start(struct gspca_dev *gspca_dev)
706 struct sd *sd = (struct sd *) gspca_dev;
708 reg_w_var(gspca_dev, start_7302,
709 page3_7302, sizeof(page3_7302));
712 sd->autogain_ignore_frames = 0;
713 atomic_set(&sd->avg_lum, 270 + sd->brightness->val);
716 reg_w(gspca_dev, 0xff, 0x01);
717 reg_w(gspca_dev, 0x78, 0x01);
719 return gspca_dev->usb_err;
722 static void sd_stopN(struct gspca_dev *gspca_dev)
726 reg_w(gspca_dev, 0xff, 0x01);
727 reg_w(gspca_dev, 0x78, 0x00);
730 /* called on streamoff with alt 0 and on disconnect for pac7302 */
731 static void sd_stop0(struct gspca_dev *gspca_dev)
733 if (!gspca_dev->present)
735 reg_w(gspca_dev, 0xff, 0x01);
736 reg_w(gspca_dev, 0x78, 0x40);
739 static void do_autogain(struct gspca_dev *gspca_dev)
741 struct sd *sd = (struct sd *) gspca_dev;
742 int avg_lum = atomic_read(&sd->avg_lum);
744 const int deadzone = 30;
746 if (sd->autogain_ignore_frames < 0)
749 if (sd->autogain_ignore_frames > 0) {
750 sd->autogain_ignore_frames--;
752 desired_lum = 270 + sd->brightness->val;
754 if (gspca_expo_autogain(gspca_dev, avg_lum, desired_lum,
755 deadzone, PAC7302_GAIN_KNEE,
756 PAC7302_EXPOSURE_KNEE))
757 sd->autogain_ignore_frames =
758 PAC_AUTOGAIN_IGNORE_FRAMES;
763 static const u8 jpeg_header[] = {
764 0xff, 0xd8, /* SOI: Start of Image */
766 0xff, 0xc0, /* SOF0: Start of Frame (Baseline DCT) */
767 0x00, 0x11, /* length = 17 bytes (including this length field) */
768 0x08, /* Precision: 8 */
769 0x02, 0x80, /* height = 640 (image rotated) */
770 0x01, 0xe0, /* width = 480 */
771 0x03, /* Number of image components: 3 */
772 0x01, 0x21, 0x00, /* ID=1, Subsampling 1x1, Quantization table: 0 */
773 0x02, 0x11, 0x01, /* ID=2, Subsampling 2x1, Quantization table: 1 */
774 0x03, 0x11, 0x01, /* ID=3, Subsampling 2x1, Quantization table: 1 */
776 0xff, 0xda, /* SOS: Start Of Scan */
777 0x00, 0x0c, /* length = 12 bytes (including this length field) */
778 0x03, /* number of components: 3 */
779 0x01, 0x00, /* selector 1, table 0x00 */
780 0x02, 0x11, /* selector 2, table 0x11 */
781 0x03, 0x11, /* selector 3, table 0x11 */
782 0x00, 0x3f, /* Spectral selection: 0 .. 63 */
783 0x00 /* Successive approximation: 0 */
786 /* this function is run at interrupt level */
787 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
788 u8 *data, /* isoc packet */
789 int len) /* iso packet length */
791 struct sd *sd = (struct sd *) gspca_dev;
795 sof = pac_find_sof(gspca_dev, &sd->sof_read, data, len);
797 int n, lum_offset, footer_length;
800 * 6 bytes after the FF D9 EOF marker a number of lumination
801 * bytes are send corresponding to different parts of the
802 * image, the 14th and 15th byte after the EOF seem to
803 * correspond to the center of the image.
805 lum_offset = 61 + sizeof pac_sof_marker;
808 /* Finish decoding current frame */
809 n = (sof - data) - (footer_length + sizeof pac_sof_marker);
811 gspca_dev->image_len += n;
814 gspca_frame_add(gspca_dev, INTER_PACKET, data, n);
817 image = gspca_dev->image;
819 && image[gspca_dev->image_len - 2] == 0xff
820 && image[gspca_dev->image_len - 1] == 0xd9)
821 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
827 /* Get average lumination */
828 if (gspca_dev->last_packet_type == LAST_PACKET &&
830 atomic_set(&sd->avg_lum, data[-lum_offset] +
831 data[-lum_offset + 1]);
833 /* Start the new frame with the jpeg header */
834 /* The PAC7302 has the image rotated 90 degrees */
835 gspca_frame_add(gspca_dev, FIRST_PACKET,
836 jpeg_header, sizeof jpeg_header);
838 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
841 #ifdef CONFIG_VIDEO_ADV_DEBUG
842 static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
843 const struct v4l2_dbg_register *reg)
849 * reg->reg: bit0..15: reserved for register index (wIndex is 16bit
850 * long on the USB bus)
852 if (reg->match.type == V4L2_CHIP_MATCH_HOST &&
853 reg->match.addr == 0 &&
854 (reg->reg < 0x000000ff) &&
855 (reg->val <= 0x000000ff)
857 /* Currently writing to page 0 is only supported. */
858 /* reg_w() only supports 8bit index */
863 * Note that there shall be no access to other page
864 * by any other function between the page switch and
865 * the actual register write.
867 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
868 reg_w(gspca_dev, index, value);
870 reg_w(gspca_dev, 0xdc, 0x01);
872 return gspca_dev->usb_err;
875 static int sd_chip_ident(struct gspca_dev *gspca_dev,
876 struct v4l2_dbg_chip_ident *chip)
880 if (chip->match.type == V4L2_CHIP_MATCH_HOST &&
881 chip->match.addr == 0) {
883 chip->ident = V4L2_IDENT_UNKNOWN;
890 #if IS_ENABLED(CONFIG_INPUT)
891 static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
892 u8 *data, /* interrupt packet data */
893 int len) /* interrput packet length */
901 if ((data0 == 0x00 && data1 == 0x11) ||
902 (data0 == 0x22 && data1 == 0x33) ||
903 (data0 == 0x44 && data1 == 0x55) ||
904 (data0 == 0x66 && data1 == 0x77) ||
905 (data0 == 0x88 && data1 == 0x99) ||
906 (data0 == 0xaa && data1 == 0xbb) ||
907 (data0 == 0xcc && data1 == 0xdd) ||
908 (data0 == 0xee && data1 == 0xff)) {
909 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
910 input_sync(gspca_dev->input_dev);
911 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
912 input_sync(gspca_dev->input_dev);
921 /* sub-driver description for pac7302 */
922 static const struct sd_desc sd_desc = {
923 .name = KBUILD_MODNAME,
926 .init_controls = sd_init_controls,
930 .pkt_scan = sd_pkt_scan,
931 .dq_callback = do_autogain,
932 #ifdef CONFIG_VIDEO_ADV_DEBUG
933 .set_register = sd_dbg_s_register,
934 .get_chip_ident = sd_chip_ident,
936 #if IS_ENABLED(CONFIG_INPUT)
937 .int_pkt_scan = sd_int_pkt_scan,
941 /* -- module initialisation -- */
942 static const struct usb_device_id device_table[] = {
943 {USB_DEVICE(0x06f8, 0x3009)},
944 {USB_DEVICE(0x06f8, 0x301b)},
945 {USB_DEVICE(0x093a, 0x2620)},
946 {USB_DEVICE(0x093a, 0x2621)},
947 {USB_DEVICE(0x093a, 0x2622), .driver_info = FL_VFLIP},
948 {USB_DEVICE(0x093a, 0x2624), .driver_info = FL_VFLIP},
949 {USB_DEVICE(0x093a, 0x2625)},
950 {USB_DEVICE(0x093a, 0x2626)},
951 {USB_DEVICE(0x093a, 0x2627), .driver_info = FL_VFLIP},
952 {USB_DEVICE(0x093a, 0x2628)},
953 {USB_DEVICE(0x093a, 0x2629), .driver_info = FL_VFLIP},
954 {USB_DEVICE(0x093a, 0x262a)},
955 {USB_DEVICE(0x093a, 0x262c)},
956 {USB_DEVICE(0x145f, 0x013c)},
957 {USB_DEVICE(0x1ae7, 0x2001)}, /* SpeedLink Snappy Mic SL-6825-SBK */
960 MODULE_DEVICE_TABLE(usb, device_table);
962 /* -- device connect -- */
963 static int sd_probe(struct usb_interface *intf,
964 const struct usb_device_id *id)
966 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
970 static struct usb_driver sd_driver = {
971 .name = KBUILD_MODNAME,
972 .id_table = device_table,
974 .disconnect = gspca_disconnect,
976 .suspend = gspca_suspend,
977 .resume = gspca_resume,
978 .reset_resume = gspca_resume,
982 module_usb_driver(sd_driver);