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>
97 /* Include pac common sof detection functions */
98 #include "pac_common.h"
100 #define PAC7302_RGB_BALANCE_MIN 0
101 #define PAC7302_RGB_BALANCE_MAX 200
102 #define PAC7302_RGB_BALANCE_DEFAULT 100
103 #define PAC7302_GAIN_DEFAULT 15
104 #define PAC7302_GAIN_KNEE 42
105 #define PAC7302_EXPOSURE_DEFAULT 66 /* 33 ms / 30 fps */
106 #define PAC7302_EXPOSURE_KNEE 133 /* 66 ms / 15 fps */
108 MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>, "
109 "Thomas Kaiser thomas@kaiser-linux.li");
110 MODULE_DESCRIPTION("Pixart PAC7302");
111 MODULE_LICENSE("GPL");
114 struct gspca_dev gspca_dev
; /* !! must be the first item */
116 struct { /* brightness / contrast cluster */
117 struct v4l2_ctrl
*brightness
;
118 struct v4l2_ctrl
*contrast
;
120 struct v4l2_ctrl
*saturation
;
121 struct v4l2_ctrl
*white_balance
;
122 struct v4l2_ctrl
*red_balance
;
123 struct v4l2_ctrl
*blue_balance
;
124 struct { /* flip cluster */
125 struct v4l2_ctrl
*hflip
;
126 struct v4l2_ctrl
*vflip
;
128 struct v4l2_ctrl
*sharpness
;
130 #define FL_HFLIP 0x01 /* mirrored by default */
131 #define FL_VFLIP 0x02 /* vertical flipped by default */
134 s8 autogain_ignore_frames
;
139 static const struct v4l2_pix_format vga_mode
[] = {
140 {640, 480, V4L2_PIX_FMT_PJPG
, V4L2_FIELD_NONE
,
142 .sizeimage
= 640 * 480 * 3 / 8 + 590,
143 .colorspace
= V4L2_COLORSPACE_JPEG
,
147 #define LOAD_PAGE3 255
148 #define END_OF_SEQUENCE 0
150 static const u8 init_7302
[] = {
152 0xff, 0x01, /* page 1 */
153 0x78, 0x00, /* deactivate */
155 0x78, 0x40, /* led off */
157 static const u8 start_7302
[] = {
158 /* index, len, [value]* */
159 0xff, 1, 0x00, /* page 0 */
160 0x00, 12, 0x01, 0x40, 0x40, 0x40, 0x01, 0xe0, 0x02, 0x80,
161 0x00, 0x00, 0x00, 0x00,
162 0x0d, 24, 0x03, 0x01, 0x00, 0xb5, 0x07, 0xcb, 0x00, 0x00,
163 0x07, 0xc8, 0x00, 0xea, 0x07, 0xcf, 0x07, 0xf7,
164 0x07, 0x7e, 0x01, 0x0b, 0x00, 0x00, 0x00, 0x11,
168 0x3a, 3, 0x14, 0xff, 0x5a,
169 0x43, 11, 0x00, 0x0a, 0x18, 0x11, 0x01, 0x2c, 0x88, 0x11,
172 0x62, 4, 0x10, 0x1e, 0x1e, 0x18,
174 0x6e, 3, 0x08, 0x06, 0x00,
175 0x72, 3, 0x00, 0xff, 0x00,
176 0x7d, 23, 0x01, 0x01, 0x58, 0x46, 0x50, 0x3c, 0x50, 0x3c,
177 0x54, 0x46, 0x54, 0x56, 0x52, 0x50, 0x52, 0x50,
178 0x56, 0x64, 0xa4, 0x00, 0xda, 0x00, 0x00,
179 0xa2, 10, 0x22, 0x2c, 0x3c, 0x54, 0x69, 0x7c, 0x9c, 0xb9,
184 0xc4, 4, 0xae, 0x01, 0x04, 0x01,
186 0xd1, 11, 0x01, 0x30, 0x49, 0x5e, 0x6f, 0x7f, 0x8e, 0xa9,
189 0xff, 1, 0x01, /* page 1 */
190 0x12, 3, 0x02, 0x00, 0x01,
192 0x76, 5, 0x01, 0x20, 0x40, 0x00, 0xf2,
194 0x7f, 10, 0x4b, 0x0f, 0x01, 0x2c, 0x02, 0x58, 0x03, 0x20,
196 0x96, 5, 0x01, 0x10, 0x04, 0x01, 0x04,
197 0xc8, 14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
198 0x07, 0x00, 0x01, 0x07, 0x04, 0x01,
201 0xde, 7, 0x00, 0x01, 0x04, 0x04, 0x00, 0x00, 0x00,
202 0xe6, 4, 0x00, 0x00, 0x00, 0x01,
204 0xff, 1, 0x02, /* page 2 */
206 0xff, 1, 0x03, /* page 3 */
207 0, LOAD_PAGE3
, /* load the page 3 */
209 0xff, 1, 0x02, /* page 2 */
211 0x22, 4, 0x1f, 0xa4, 0xf0, 0x96,
213 0x2a, 5, 0xc8, 0x00, 0x18, 0x12, 0x22,
214 0x64, 8, 0x00, 0x00, 0xf0, 0x01, 0x14, 0x44, 0x44, 0x44,
216 0xff, 1, 0x01, /* page 1 */
218 0, END_OF_SEQUENCE
/* end of sequence */
222 /* page 3 - the value SKIP says skip the index - see reg_w_page() */
223 static const u8 page3_7302
[] = {
224 0x90, 0x40, 0x03, 0x00, 0xc0, 0x01, 0x14, 0x16,
225 0x14, 0x12, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00,
226 0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
227 0x00, 0x00, 0x00, 0x47, 0x01, 0xb3, 0x01, 0x00,
228 0x00, 0x08, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x21,
229 0x00, 0x00, 0x00, 0x54, 0xf4, 0x02, 0x52, 0x54,
230 0xa4, 0xb8, 0xe0, 0x2a, 0xf6, 0x00, 0x00, 0x00,
231 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
232 0x00, 0xfc, 0x00, 0xf2, 0x1f, 0x04, 0x00, 0x00,
233 SKIP
, 0x00, 0x00, 0xc0, 0xc0, 0x10, 0x00, 0x00,
234 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
235 0x00, 0x40, 0xff, 0x03, 0x19, 0x00, 0x00, 0x00,
236 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
237 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc8, 0xc8,
238 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
239 0x08, 0x10, 0x24, 0x40, 0x00, 0x00, 0x00, 0x00,
240 0x01, 0x00, 0x02, 0x47, 0x00, 0x00, 0x00, 0x00,
241 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
242 0x00, 0x02, 0xfa, 0x00, 0x64, 0x5a, 0x28, 0x00,
246 static void reg_w_buf(struct gspca_dev
*gspca_dev
,
248 const u8
*buffer
, int len
)
252 if (gspca_dev
->usb_err
< 0)
254 memcpy(gspca_dev
->usb_buf
, buffer
, len
);
255 ret
= usb_control_msg(gspca_dev
->dev
,
256 usb_sndctrlpipe(gspca_dev
->dev
, 0),
258 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
260 index
, gspca_dev
->usb_buf
, len
,
263 pr_err("reg_w_buf failed i: %02x error %d\n",
265 gspca_dev
->usb_err
= ret
;
270 static void reg_w(struct gspca_dev
*gspca_dev
,
276 if (gspca_dev
->usb_err
< 0)
278 gspca_dev
->usb_buf
[0] = value
;
279 ret
= usb_control_msg(gspca_dev
->dev
,
280 usb_sndctrlpipe(gspca_dev
->dev
, 0),
282 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
283 0, index
, gspca_dev
->usb_buf
, 1,
286 pr_err("reg_w() failed i: %02x v: %02x error %d\n",
288 gspca_dev
->usb_err
= ret
;
292 static void reg_w_seq(struct gspca_dev
*gspca_dev
,
293 const u8
*seq
, int len
)
296 reg_w(gspca_dev
, seq
[0], seq
[1]);
301 /* load the beginning of a page */
302 static void reg_w_page(struct gspca_dev
*gspca_dev
,
303 const u8
*page
, int len
)
308 if (gspca_dev
->usb_err
< 0)
310 for (index
= 0; index
< len
; index
++) {
311 if (page
[index
] == SKIP
) /* skip this index */
313 gspca_dev
->usb_buf
[0] = page
[index
];
314 ret
= usb_control_msg(gspca_dev
->dev
,
315 usb_sndctrlpipe(gspca_dev
->dev
, 0),
317 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
318 0, index
, gspca_dev
->usb_buf
, 1,
321 pr_err("reg_w_page() failed i: %02x v: %02x error %d\n",
322 index
, page
[index
], ret
);
323 gspca_dev
->usb_err
= ret
;
329 /* output a variable sequence */
330 static void reg_w_var(struct gspca_dev
*gspca_dev
,
332 const u8
*page3
, unsigned int page3_len
)
340 case END_OF_SEQUENCE
:
343 reg_w_page(gspca_dev
, page3
, page3_len
);
346 if (len
> USB_BUF_SZ
) {
347 PERR("Incorrect variable sequence");
357 reg_w_buf(gspca_dev
, index
, seq
, 8);
367 /* this function is called at probe time for pac7302 */
368 static int sd_config(struct gspca_dev
*gspca_dev
,
369 const struct usb_device_id
*id
)
371 struct sd
*sd
= (struct sd
*) gspca_dev
;
374 cam
= &gspca_dev
->cam
;
376 cam
->cam_mode
= vga_mode
; /* only 640x480 */
377 cam
->nmodes
= ARRAY_SIZE(vga_mode
);
379 sd
->flags
= id
->driver_info
;
383 static void setbrightcont(struct gspca_dev
*gspca_dev
)
385 struct sd
*sd
= (struct sd
*) gspca_dev
;
387 static const u8 max
[10] =
388 {0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb,
390 static const u8 delta
[10] =
391 {0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17,
394 reg_w(gspca_dev
, 0xff, 0x00); /* page 0 */
395 for (i
= 0; i
< 10; i
++) {
397 v
+= (sd
->brightness
->val
- sd
->brightness
->maximum
)
398 * 150 / sd
->brightness
->maximum
; /* 200 ? */
399 v
-= delta
[i
] * sd
->contrast
->val
/ sd
->contrast
->maximum
;
404 reg_w(gspca_dev
, 0xa2 + i
, v
);
406 reg_w(gspca_dev
, 0xdc, 0x01);
409 static void setcolors(struct gspca_dev
*gspca_dev
)
411 struct sd
*sd
= (struct sd
*) gspca_dev
;
413 static const int a
[9] =
414 {217, -212, 0, -101, 170, -67, -38, -315, 355};
415 static const int b
[9] =
416 {19, 106, 0, 19, 106, 1, 19, 106, 1};
418 reg_w(gspca_dev
, 0xff, 0x03); /* page 3 */
419 reg_w(gspca_dev
, 0x11, 0x01);
420 reg_w(gspca_dev
, 0xff, 0x00); /* page 0 */
421 for (i
= 0; i
< 9; i
++) {
422 v
= a
[i
] * sd
->saturation
->val
/ sd
->saturation
->maximum
;
424 reg_w(gspca_dev
, 0x0f + 2 * i
, (v
>> 8) & 0x07);
425 reg_w(gspca_dev
, 0x0f + 2 * i
+ 1, v
);
427 reg_w(gspca_dev
, 0xdc, 0x01);
430 static void setwhitebalance(struct gspca_dev
*gspca_dev
)
432 struct sd
*sd
= (struct sd
*) gspca_dev
;
434 reg_w(gspca_dev
, 0xff, 0x00); /* page 0 */
435 reg_w(gspca_dev
, 0xc6, sd
->white_balance
->val
);
437 reg_w(gspca_dev
, 0xdc, 0x01);
440 static u8
rgbbalance_ctrl_to_reg_value(s32 rgb_ctrl_val
)
442 const unsigned int k
= 1000; /* precision factor */
445 /* Normed value [0...k] */
446 norm
= k
* (rgb_ctrl_val
- PAC7302_RGB_BALANCE_MIN
)
447 / (PAC7302_RGB_BALANCE_MAX
- PAC7302_RGB_BALANCE_MIN
);
448 /* Qudratic apporach improves control at small (register) values: */
449 return 64 * norm
* norm
/ (k
*k
) + 32 * norm
/ k
+ 32;
450 /* Y = 64*X*X + 32*X + 32
451 * => register values 0x20-0x80; Windows driver uses these limits */
453 /* NOTE: for full value range (0x00-0xff) use
455 * => 254 * norm * norm / (k*k) + 1 * norm / k */
458 static void setredbalance(struct gspca_dev
*gspca_dev
)
460 struct sd
*sd
= (struct sd
*) gspca_dev
;
462 reg_w(gspca_dev
, 0xff, 0x00); /* page 0 */
463 reg_w(gspca_dev
, 0x01,
464 rgbbalance_ctrl_to_reg_value(sd
->red_balance
->val
));
466 reg_w(gspca_dev
, 0xdc, 0x01);
469 static void setbluebalance(struct gspca_dev
*gspca_dev
)
471 struct sd
*sd
= (struct sd
*) gspca_dev
;
473 reg_w(gspca_dev
, 0xff, 0x00); /* page 0 */
474 reg_w(gspca_dev
, 0x03,
475 rgbbalance_ctrl_to_reg_value(sd
->blue_balance
->val
));
477 reg_w(gspca_dev
, 0xdc, 0x01);
480 static void setgain(struct gspca_dev
*gspca_dev
)
484 if (gspca_dev
->gain
->val
< 32) {
485 reg10
= gspca_dev
->gain
->val
;
489 reg12
= gspca_dev
->gain
->val
- 31;
492 reg_w(gspca_dev
, 0xff, 0x03); /* page 3 */
493 reg_w(gspca_dev
, 0x10, reg10
);
494 reg_w(gspca_dev
, 0x12, reg12
);
496 /* load registers to sensor (Bit 0, auto clear) */
497 reg_w(gspca_dev
, 0x11, 0x01);
500 static void setexposure(struct gspca_dev
*gspca_dev
)
506 * Register 2 of frame 3 contains the clock divider configuring the
507 * no fps according to the formula: 90 / reg. sd->exposure is the
508 * desired exposure time in 0.5 ms.
510 clockdiv
= (90 * gspca_dev
->exposure
->val
+ 1999) / 2000;
513 * Note clockdiv = 3 also works, but when running at 30 fps, depending
514 * on the scene being recorded, the camera switches to another
515 * quantization table for certain JPEG blocks, and we don't know how
516 * to decompress these blocks. So we cap the framerate at 15 fps.
520 else if (clockdiv
> 63)
524 * Register 2 MUST be a multiple of 3, except when between 6 and 12?
525 * Always round up, otherwise we cannot get the desired frametime
526 * using the partial frame time exposure control.
528 if (clockdiv
< 6 || clockdiv
> 12)
529 clockdiv
= ((clockdiv
+ 2) / 3) * 3;
532 * frame exposure time in ms = 1000 * clockdiv / 90 ->
533 * exposure = (sd->exposure / 2) * 448 / (1000 * clockdiv / 90)
535 exposure
= (gspca_dev
->exposure
->val
* 45 * 448) / (1000 * clockdiv
);
536 /* 0 = use full frametime, 448 = no exposure, reverse it */
537 exposure
= 448 - exposure
;
539 reg_w(gspca_dev
, 0xff, 0x03); /* page 3 */
540 reg_w(gspca_dev
, 0x02, clockdiv
);
541 reg_w(gspca_dev
, 0x0e, exposure
& 0xff);
542 reg_w(gspca_dev
, 0x0f, exposure
>> 8);
544 /* load registers to sensor (Bit 0, auto clear) */
545 reg_w(gspca_dev
, 0x11, 0x01);
548 static void sethvflip(struct gspca_dev
*gspca_dev
)
550 struct sd
*sd
= (struct sd
*) gspca_dev
;
551 u8 data
, hflip
, vflip
;
553 hflip
= sd
->hflip
->val
;
554 if (sd
->flags
& FL_HFLIP
)
556 vflip
= sd
->vflip
->val
;
557 if (sd
->flags
& FL_VFLIP
)
560 reg_w(gspca_dev
, 0xff, 0x03); /* page 3 */
561 data
= (hflip
? 0x08 : 0x00) | (vflip
? 0x04 : 0x00);
562 reg_w(gspca_dev
, 0x21, data
);
564 /* load registers to sensor (Bit 0, auto clear) */
565 reg_w(gspca_dev
, 0x11, 0x01);
568 static void setsharpness(struct gspca_dev
*gspca_dev
)
570 struct sd
*sd
= (struct sd
*) gspca_dev
;
572 reg_w(gspca_dev
, 0xff, 0x00); /* page 0 */
573 reg_w(gspca_dev
, 0xb6, sd
->sharpness
->val
);
575 reg_w(gspca_dev
, 0xdc, 0x01);
578 /* this function is called at probe and resume time for pac7302 */
579 static int sd_init(struct gspca_dev
*gspca_dev
)
581 reg_w_seq(gspca_dev
, init_7302
, sizeof(init_7302
)/2);
582 return gspca_dev
->usb_err
;
585 static int sd_s_ctrl(struct v4l2_ctrl
*ctrl
)
587 struct gspca_dev
*gspca_dev
=
588 container_of(ctrl
->handler
, struct gspca_dev
, ctrl_handler
);
589 struct sd
*sd
= (struct sd
*)gspca_dev
;
591 gspca_dev
->usb_err
= 0;
593 if (ctrl
->id
== V4L2_CID_AUTOGAIN
&& ctrl
->is_new
&& ctrl
->val
) {
594 /* when switching to autogain set defaults to make sure
595 we are on a valid point of the autogain gain /
596 exposure knee graph, and give this change time to
597 take effect before doing autogain. */
598 gspca_dev
->exposure
->val
= PAC7302_EXPOSURE_DEFAULT
;
599 gspca_dev
->gain
->val
= PAC7302_GAIN_DEFAULT
;
600 sd
->autogain_ignore_frames
= PAC_AUTOGAIN_IGNORE_FRAMES
;
603 if (!gspca_dev
->streaming
)
607 case V4L2_CID_BRIGHTNESS
:
608 setbrightcont(gspca_dev
);
610 case V4L2_CID_SATURATION
:
611 setcolors(gspca_dev
);
613 case V4L2_CID_WHITE_BALANCE_TEMPERATURE
:
614 setwhitebalance(gspca_dev
);
616 case V4L2_CID_RED_BALANCE
:
617 setredbalance(gspca_dev
);
619 case V4L2_CID_BLUE_BALANCE
:
620 setbluebalance(gspca_dev
);
622 case V4L2_CID_AUTOGAIN
:
623 if (gspca_dev
->exposure
->is_new
|| (ctrl
->is_new
&& ctrl
->val
))
624 setexposure(gspca_dev
);
625 if (gspca_dev
->gain
->is_new
|| (ctrl
->is_new
&& ctrl
->val
))
629 sethvflip(gspca_dev
);
631 case V4L2_CID_SHARPNESS
:
632 setsharpness(gspca_dev
);
637 return gspca_dev
->usb_err
;
640 static const struct v4l2_ctrl_ops sd_ctrl_ops
= {
644 /* this function is called at probe time */
645 static int sd_init_controls(struct gspca_dev
*gspca_dev
)
647 struct sd
*sd
= (struct sd
*) gspca_dev
;
648 struct v4l2_ctrl_handler
*hdl
= &gspca_dev
->ctrl_handler
;
650 gspca_dev
->vdev
.ctrl_handler
= hdl
;
651 v4l2_ctrl_handler_init(hdl
, 12);
653 sd
->brightness
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
654 V4L2_CID_BRIGHTNESS
, 0, 32, 1, 16);
655 sd
->contrast
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
656 V4L2_CID_CONTRAST
, 0, 255, 1, 127);
658 sd
->saturation
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
659 V4L2_CID_SATURATION
, 0, 255, 1, 127);
660 sd
->white_balance
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
661 V4L2_CID_WHITE_BALANCE_TEMPERATURE
,
663 sd
->red_balance
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
664 V4L2_CID_RED_BALANCE
,
665 PAC7302_RGB_BALANCE_MIN
,
666 PAC7302_RGB_BALANCE_MAX
,
667 1, PAC7302_RGB_BALANCE_DEFAULT
);
668 sd
->blue_balance
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
669 V4L2_CID_BLUE_BALANCE
,
670 PAC7302_RGB_BALANCE_MIN
,
671 PAC7302_RGB_BALANCE_MAX
,
672 1, PAC7302_RGB_BALANCE_DEFAULT
);
674 gspca_dev
->autogain
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
675 V4L2_CID_AUTOGAIN
, 0, 1, 1, 1);
676 gspca_dev
->exposure
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
677 V4L2_CID_EXPOSURE
, 0, 1023, 1,
678 PAC7302_EXPOSURE_DEFAULT
);
679 gspca_dev
->gain
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
680 V4L2_CID_GAIN
, 0, 62, 1,
681 PAC7302_GAIN_DEFAULT
);
683 sd
->hflip
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
684 V4L2_CID_HFLIP
, 0, 1, 1, 0);
685 sd
->vflip
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
686 V4L2_CID_VFLIP
, 0, 1, 1, 0);
688 sd
->sharpness
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
689 V4L2_CID_SHARPNESS
, 0, 15, 1, 8);
692 pr_err("Could not initialize controls\n");
696 v4l2_ctrl_cluster(2, &sd
->brightness
);
697 v4l2_ctrl_auto_cluster(3, &gspca_dev
->autogain
, 0, false);
698 v4l2_ctrl_cluster(2, &sd
->hflip
);
702 /* -- start the camera -- */
703 static int sd_start(struct gspca_dev
*gspca_dev
)
705 struct sd
*sd
= (struct sd
*) gspca_dev
;
707 reg_w_var(gspca_dev
, start_7302
,
708 page3_7302
, sizeof(page3_7302
));
711 sd
->autogain_ignore_frames
= 0;
712 atomic_set(&sd
->avg_lum
, 270 + sd
->brightness
->val
);
715 reg_w(gspca_dev
, 0xff, 0x01);
716 reg_w(gspca_dev
, 0x78, 0x01);
718 return gspca_dev
->usb_err
;
721 static void sd_stopN(struct gspca_dev
*gspca_dev
)
725 reg_w(gspca_dev
, 0xff, 0x01);
726 reg_w(gspca_dev
, 0x78, 0x00);
729 /* called on streamoff with alt 0 and on disconnect for pac7302 */
730 static void sd_stop0(struct gspca_dev
*gspca_dev
)
732 if (!gspca_dev
->present
)
734 reg_w(gspca_dev
, 0xff, 0x01);
735 reg_w(gspca_dev
, 0x78, 0x40);
738 static void do_autogain(struct gspca_dev
*gspca_dev
)
740 struct sd
*sd
= (struct sd
*) gspca_dev
;
741 int avg_lum
= atomic_read(&sd
->avg_lum
);
743 const int deadzone
= 30;
745 if (sd
->autogain_ignore_frames
< 0)
748 if (sd
->autogain_ignore_frames
> 0) {
749 sd
->autogain_ignore_frames
--;
751 desired_lum
= 270 + sd
->brightness
->val
;
753 if (gspca_expo_autogain(gspca_dev
, avg_lum
, desired_lum
,
754 deadzone
, PAC7302_GAIN_KNEE
,
755 PAC7302_EXPOSURE_KNEE
))
756 sd
->autogain_ignore_frames
=
757 PAC_AUTOGAIN_IGNORE_FRAMES
;
762 static const u8 jpeg_header
[] = {
763 0xff, 0xd8, /* SOI: Start of Image */
765 0xff, 0xc0, /* SOF0: Start of Frame (Baseline DCT) */
766 0x00, 0x11, /* length = 17 bytes (including this length field) */
767 0x08, /* Precision: 8 */
768 0x02, 0x80, /* height = 640 (image rotated) */
769 0x01, 0xe0, /* width = 480 */
770 0x03, /* Number of image components: 3 */
771 0x01, 0x21, 0x00, /* ID=1, Subsampling 1x1, Quantization table: 0 */
772 0x02, 0x11, 0x01, /* ID=2, Subsampling 2x1, Quantization table: 1 */
773 0x03, 0x11, 0x01, /* ID=3, Subsampling 2x1, Quantization table: 1 */
775 0xff, 0xda, /* SOS: Start Of Scan */
776 0x00, 0x0c, /* length = 12 bytes (including this length field) */
777 0x03, /* number of components: 3 */
778 0x01, 0x00, /* selector 1, table 0x00 */
779 0x02, 0x11, /* selector 2, table 0x11 */
780 0x03, 0x11, /* selector 3, table 0x11 */
781 0x00, 0x3f, /* Spectral selection: 0 .. 63 */
782 0x00 /* Successive approximation: 0 */
785 /* this function is run at interrupt level */
786 static void sd_pkt_scan(struct gspca_dev
*gspca_dev
,
787 u8
*data
, /* isoc packet */
788 int len
) /* iso packet length */
790 struct sd
*sd
= (struct sd
*) gspca_dev
;
794 sof
= pac_find_sof(gspca_dev
, &sd
->sof_read
, data
, len
);
796 int n
, lum_offset
, footer_length
;
799 * 6 bytes after the FF D9 EOF marker a number of lumination
800 * bytes are send corresponding to different parts of the
801 * image, the 14th and 15th byte after the EOF seem to
802 * correspond to the center of the image.
804 lum_offset
= 61 + sizeof pac_sof_marker
;
807 /* Finish decoding current frame */
808 n
= (sof
- data
) - (footer_length
+ sizeof pac_sof_marker
);
810 gspca_dev
->image_len
+= n
;
813 gspca_frame_add(gspca_dev
, INTER_PACKET
, data
, n
);
816 image
= gspca_dev
->image
;
818 && image
[gspca_dev
->image_len
- 2] == 0xff
819 && image
[gspca_dev
->image_len
- 1] == 0xd9)
820 gspca_frame_add(gspca_dev
, LAST_PACKET
, NULL
, 0);
826 /* Get average lumination */
827 if (gspca_dev
->last_packet_type
== LAST_PACKET
&&
829 atomic_set(&sd
->avg_lum
, data
[-lum_offset
] +
830 data
[-lum_offset
+ 1]);
832 /* Start the new frame with the jpeg header */
833 /* The PAC7302 has the image rotated 90 degrees */
834 gspca_frame_add(gspca_dev
, FIRST_PACKET
,
835 jpeg_header
, sizeof jpeg_header
);
837 gspca_frame_add(gspca_dev
, INTER_PACKET
, data
, len
);
840 #ifdef CONFIG_VIDEO_ADV_DEBUG
841 static int sd_dbg_s_register(struct gspca_dev
*gspca_dev
,
842 const struct v4l2_dbg_register
*reg
)
848 * reg->reg: bit0..15: reserved for register index (wIndex is 16bit
849 * long on the USB bus)
851 if (reg
->match
.addr
== 0 &&
852 (reg
->reg
< 0x000000ff) &&
853 (reg
->val
<= 0x000000ff)
855 /* Currently writing to page 0 is only supported. */
856 /* reg_w() only supports 8bit index */
861 * Note that there shall be no access to other page
862 * by any other function between the page switch and
863 * the actual register write.
865 reg_w(gspca_dev
, 0xff, 0x00); /* page 0 */
866 reg_w(gspca_dev
, index
, value
);
868 reg_w(gspca_dev
, 0xdc, 0x01);
870 return gspca_dev
->usb_err
;
874 #if IS_ENABLED(CONFIG_INPUT)
875 static int sd_int_pkt_scan(struct gspca_dev
*gspca_dev
,
876 u8
*data
, /* interrupt packet data */
877 int len
) /* interrupt packet length */
885 if ((data0
== 0x00 && data1
== 0x11) ||
886 (data0
== 0x22 && data1
== 0x33) ||
887 (data0
== 0x44 && data1
== 0x55) ||
888 (data0
== 0x66 && data1
== 0x77) ||
889 (data0
== 0x88 && data1
== 0x99) ||
890 (data0
== 0xaa && data1
== 0xbb) ||
891 (data0
== 0xcc && data1
== 0xdd) ||
892 (data0
== 0xee && data1
== 0xff)) {
893 input_report_key(gspca_dev
->input_dev
, KEY_CAMERA
, 1);
894 input_sync(gspca_dev
->input_dev
);
895 input_report_key(gspca_dev
->input_dev
, KEY_CAMERA
, 0);
896 input_sync(gspca_dev
->input_dev
);
905 /* sub-driver description for pac7302 */
906 static const struct sd_desc sd_desc
= {
907 .name
= KBUILD_MODNAME
,
910 .init_controls
= sd_init_controls
,
914 .pkt_scan
= sd_pkt_scan
,
915 .dq_callback
= do_autogain
,
916 #ifdef CONFIG_VIDEO_ADV_DEBUG
917 .set_register
= sd_dbg_s_register
,
919 #if IS_ENABLED(CONFIG_INPUT)
920 .int_pkt_scan
= sd_int_pkt_scan
,
924 /* -- module initialisation -- */
925 static const struct usb_device_id device_table
[] = {
926 {USB_DEVICE(0x06f8, 0x3009)},
927 {USB_DEVICE(0x06f8, 0x301b)},
928 {USB_DEVICE(0x093a, 0x2620)},
929 {USB_DEVICE(0x093a, 0x2621)},
930 {USB_DEVICE(0x093a, 0x2622), .driver_info
= FL_VFLIP
},
931 {USB_DEVICE(0x093a, 0x2624), .driver_info
= FL_VFLIP
},
932 {USB_DEVICE(0x093a, 0x2625)},
933 {USB_DEVICE(0x093a, 0x2626)},
934 {USB_DEVICE(0x093a, 0x2627), .driver_info
= FL_VFLIP
},
935 {USB_DEVICE(0x093a, 0x2628)},
936 {USB_DEVICE(0x093a, 0x2629), .driver_info
= FL_VFLIP
},
937 {USB_DEVICE(0x093a, 0x262a)},
938 {USB_DEVICE(0x093a, 0x262c)},
939 {USB_DEVICE(0x145f, 0x013c)},
940 {USB_DEVICE(0x1ae7, 0x2001)}, /* SpeedLink Snappy Mic SL-6825-SBK */
943 MODULE_DEVICE_TABLE(usb
, device_table
);
945 /* -- device connect -- */
946 static int sd_probe(struct usb_interface
*intf
,
947 const struct usb_device_id
*id
)
949 return gspca_dev_probe(intf
, id
, &sd_desc
, sizeof(struct sd
),
953 static struct usb_driver sd_driver
= {
954 .name
= KBUILD_MODNAME
,
955 .id_table
= device_table
,
957 .disconnect
= gspca_disconnect
,
959 .suspend
= gspca_suspend
,
960 .resume
= gspca_resume
,
961 .reset_resume
= gspca_resume
,
965 module_usb_driver(sd_driver
);