2 * Pixart PAC7302 library
3 * Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li
5 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
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
26 /* Some documentation about various registers as determined by trial and error.
31 0x78 Global control, bit 6 controls the LED (inverted)
36 0x02 Clock divider 3-63, fps = 90 / val. Must be a multiple of 3 on
37 the 7302, so one of 3, 6, 9, ..., except when between 6 and 12?
38 0x03 Variable framerate ctrl reg2==3: 0 -> ~30 fps, 255 -> ~22fps
39 0x04 Another var framerate ctrl reg2==3, reg3==0: 0 -> ~30 fps,
40 63 -> ~27 fps, the 2 msb's must always be 1 !!
41 0x05 Another var framerate ctrl reg2==3, reg3==0, reg4==0xc0:
42 1 -> ~30 fps, 2 -> ~20 fps
43 0x0e Exposure bits 0-7, 0-448, 0 = use full frame time
44 0x0f Exposure bit 8, 0-448, 448 = no exposure at all
46 0x21 Bitfield: 0-1 unused, 2-3 vflip/hflip, 4-5 unknown, 6-7 unused
48 The registers are accessed in the following functions:
50 Page | Register | Function
51 -----+------------+---------------------------------------------------
52 0 | 0x0f..0x20 | setcolors()
53 0 | 0xa2..0xab | setbrightcont()
54 0 | 0xc5 | setredbalance()
55 0 | 0xc6 | setwhitebalance()
56 0 | 0xc7 | setbluebalance()
57 0 | 0xdc | setbrightcont(), setcolors()
58 3 | 0x02 | setexposure()
60 3 | 0x11 | setcolors(), setgain(), setexposure(), sethvflip()
61 3 | 0x21 | sethvflip()
64 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
66 #define MODULE_NAME "pac7302"
68 #include <linux/input.h>
69 #include <media/v4l2-chip-ident.h>
72 MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li");
73 MODULE_DESCRIPTION("Pixart PAC7302");
74 MODULE_LICENSE("GPL");
76 /* specific webcam descriptor for pac7302 */
78 struct gspca_dev gspca_dev
; /* !! must be the first item */
80 unsigned char brightness
;
81 unsigned char contrast
;
83 unsigned char white_balance
;
84 unsigned char red_balance
;
85 unsigned char blue_balance
;
87 unsigned char autogain
;
88 unsigned short exposure
;
92 #define FL_HFLIP 0x01 /* mirrored by default */
93 #define FL_VFLIP 0x02 /* vertical flipped by default */
96 u8 autogain_ignore_frames
;
101 /* V4L2 controls supported by the driver */
102 static int sd_setbrightness(struct gspca_dev
*gspca_dev
, __s32 val
);
103 static int sd_getbrightness(struct gspca_dev
*gspca_dev
, __s32
*val
);
104 static int sd_setcontrast(struct gspca_dev
*gspca_dev
, __s32 val
);
105 static int sd_getcontrast(struct gspca_dev
*gspca_dev
, __s32
*val
);
106 static int sd_setcolors(struct gspca_dev
*gspca_dev
, __s32 val
);
107 static int sd_getcolors(struct gspca_dev
*gspca_dev
, __s32
*val
);
108 static int sd_setwhitebalance(struct gspca_dev
*gspca_dev
, __s32 val
);
109 static int sd_getwhitebalance(struct gspca_dev
*gspca_dev
, __s32
*val
);
110 static int sd_setredbalance(struct gspca_dev
*gspca_dev
, __s32 val
);
111 static int sd_getredbalance(struct gspca_dev
*gspca_dev
, __s32
*val
);
112 static int sd_setbluebalance(struct gspca_dev
*gspca_dev
, __s32 val
);
113 static int sd_getbluebalance(struct gspca_dev
*gspca_dev
, __s32
*val
);
114 static int sd_setautogain(struct gspca_dev
*gspca_dev
, __s32 val
);
115 static int sd_getautogain(struct gspca_dev
*gspca_dev
, __s32
*val
);
116 static int sd_sethflip(struct gspca_dev
*gspca_dev
, __s32 val
);
117 static int sd_gethflip(struct gspca_dev
*gspca_dev
, __s32
*val
);
118 static int sd_setvflip(struct gspca_dev
*gspca_dev
, __s32 val
);
119 static int sd_getvflip(struct gspca_dev
*gspca_dev
, __s32
*val
);
120 static int sd_setgain(struct gspca_dev
*gspca_dev
, __s32 val
);
121 static int sd_getgain(struct gspca_dev
*gspca_dev
, __s32
*val
);
122 static int sd_setexposure(struct gspca_dev
*gspca_dev
, __s32 val
);
123 static int sd_getexposure(struct gspca_dev
*gspca_dev
, __s32
*val
);
125 static const struct ctrl sd_ctrls
[] = {
128 .id
= V4L2_CID_BRIGHTNESS
,
129 .type
= V4L2_CTRL_TYPE_INTEGER
,
130 .name
= "Brightness",
132 #define BRIGHTNESS_MAX 0x20
133 .maximum
= BRIGHTNESS_MAX
,
135 #define BRIGHTNESS_DEF 0x10
136 .default_value
= BRIGHTNESS_DEF
,
138 .set
= sd_setbrightness
,
139 .get
= sd_getbrightness
,
143 .id
= V4L2_CID_CONTRAST
,
144 .type
= V4L2_CTRL_TYPE_INTEGER
,
147 #define CONTRAST_MAX 255
148 .maximum
= CONTRAST_MAX
,
150 #define CONTRAST_DEF 127
151 .default_value
= CONTRAST_DEF
,
153 .set
= sd_setcontrast
,
154 .get
= sd_getcontrast
,
158 .id
= V4L2_CID_SATURATION
,
159 .type
= V4L2_CTRL_TYPE_INTEGER
,
160 .name
= "Saturation",
162 #define COLOR_MAX 255
163 .maximum
= COLOR_MAX
,
165 #define COLOR_DEF 127
166 .default_value
= COLOR_DEF
,
173 .id
= V4L2_CID_WHITE_BALANCE_TEMPERATURE
,
174 .type
= V4L2_CTRL_TYPE_INTEGER
,
175 .name
= "White Balance",
179 #define WHITEBALANCE_DEF 4
180 .default_value
= WHITEBALANCE_DEF
,
182 .set
= sd_setwhitebalance
,
183 .get
= sd_getwhitebalance
,
187 .id
= V4L2_CID_RED_BALANCE
,
188 .type
= V4L2_CTRL_TYPE_INTEGER
,
193 #define REDBALANCE_DEF 1
194 .default_value
= REDBALANCE_DEF
,
196 .set
= sd_setredbalance
,
197 .get
= sd_getredbalance
,
201 .id
= V4L2_CID_BLUE_BALANCE
,
202 .type
= V4L2_CTRL_TYPE_INTEGER
,
207 #define BLUEBALANCE_DEF 1
208 .default_value
= BLUEBALANCE_DEF
,
210 .set
= sd_setbluebalance
,
211 .get
= sd_getbluebalance
,
216 .type
= V4L2_CTRL_TYPE_INTEGER
,
223 #define GAIN_KNEE 255 /* Gain seems to cause little noise on the pac73xx */
224 .default_value
= GAIN_DEF
,
231 .id
= V4L2_CID_EXPOSURE
,
232 .type
= V4L2_CTRL_TYPE_INTEGER
,
237 #define EXPOSURE_DEF 66 /* 33 ms / 30 fps */
238 #define EXPOSURE_KNEE 133 /* 66 ms / 15 fps */
239 .default_value
= EXPOSURE_DEF
,
241 .set
= sd_setexposure
,
242 .get
= sd_getexposure
,
246 .id
= V4L2_CID_AUTOGAIN
,
247 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
252 #define AUTOGAIN_DEF 1
253 .default_value
= AUTOGAIN_DEF
,
255 .set
= sd_setautogain
,
256 .get
= sd_getautogain
,
260 .id
= V4L2_CID_HFLIP
,
261 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
267 .default_value
= HFLIP_DEF
,
274 .id
= V4L2_CID_VFLIP
,
275 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
281 .default_value
= VFLIP_DEF
,
288 static const struct v4l2_pix_format vga_mode
[] = {
289 {640, 480, V4L2_PIX_FMT_PJPG
, V4L2_FIELD_NONE
,
291 .sizeimage
= 640 * 480 * 3 / 8 + 590,
292 .colorspace
= V4L2_COLORSPACE_JPEG
,
296 #define LOAD_PAGE3 255
297 #define END_OF_SEQUENCE 0
300 static const __u8 init_7302
[] = {
302 0xff, 0x01, /* page 1 */
303 0x78, 0x00, /* deactivate */
305 0x78, 0x40, /* led off */
307 static const __u8 start_7302
[] = {
308 /* index, len, [value]* */
309 0xff, 1, 0x00, /* page 0 */
310 0x00, 12, 0x01, 0x40, 0x40, 0x40, 0x01, 0xe0, 0x02, 0x80,
311 0x00, 0x00, 0x00, 0x00,
312 0x0d, 24, 0x03, 0x01, 0x00, 0xb5, 0x07, 0xcb, 0x00, 0x00,
313 0x07, 0xc8, 0x00, 0xea, 0x07, 0xcf, 0x07, 0xf7,
314 0x07, 0x7e, 0x01, 0x0b, 0x00, 0x00, 0x00, 0x11,
318 0x3a, 3, 0x14, 0xff, 0x5a,
319 0x43, 11, 0x00, 0x0a, 0x18, 0x11, 0x01, 0x2c, 0x88, 0x11,
322 0x62, 4, 0x10, 0x1e, 0x1e, 0x18,
324 0x6e, 3, 0x08, 0x06, 0x00,
325 0x72, 3, 0x00, 0xff, 0x00,
326 0x7d, 23, 0x01, 0x01, 0x58, 0x46, 0x50, 0x3c, 0x50, 0x3c,
327 0x54, 0x46, 0x54, 0x56, 0x52, 0x50, 0x52, 0x50,
328 0x56, 0x64, 0xa4, 0x00, 0xda, 0x00, 0x00,
329 0xa2, 10, 0x22, 0x2c, 0x3c, 0x54, 0x69, 0x7c, 0x9c, 0xb9,
334 0xc4, 4, 0xae, 0x01, 0x04, 0x01,
336 0xd1, 11, 0x01, 0x30, 0x49, 0x5e, 0x6f, 0x7f, 0x8e, 0xa9,
339 0xff, 1, 0x01, /* page 1 */
340 0x12, 3, 0x02, 0x00, 0x01,
342 0x76, 5, 0x01, 0x20, 0x40, 0x00, 0xf2,
344 0x7f, 10, 0x4b, 0x0f, 0x01, 0x2c, 0x02, 0x58, 0x03, 0x20,
346 0x96, 5, 0x01, 0x10, 0x04, 0x01, 0x04,
347 0xc8, 14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
348 0x07, 0x00, 0x01, 0x07, 0x04, 0x01,
351 0xde, 7, 0x00, 0x01, 0x04, 0x04, 0x00, 0x00, 0x00,
352 0xe6, 4, 0x00, 0x00, 0x00, 0x01,
354 0xff, 1, 0x02, /* page 2 */
356 0xff, 1, 0x03, /* page 3 */
357 0, LOAD_PAGE3
, /* load the page 3 */
359 0xff, 1, 0x02, /* page 2 */
361 0x22, 4, 0x1f, 0xa4, 0xf0, 0x96,
363 0x2a, 5, 0xc8, 0x00, 0x18, 0x12, 0x22,
364 0x64, 8, 0x00, 0x00, 0xf0, 0x01, 0x14, 0x44, 0x44, 0x44,
366 0xff, 1, 0x01, /* page 1 */
368 0, END_OF_SEQUENCE
/* end of sequence */
372 /* page 3 - the value SKIP says skip the index - see reg_w_page() */
373 static const __u8 page3_7302
[] = {
374 0x90, 0x40, 0x03, 0x00, 0xc0, 0x01, 0x14, 0x16,
375 0x14, 0x12, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00,
376 0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
377 0x00, 0x00, 0x00, 0x47, 0x01, 0xb3, 0x01, 0x00,
378 0x00, 0x08, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x21,
379 0x00, 0x00, 0x00, 0x54, 0xf4, 0x02, 0x52, 0x54,
380 0xa4, 0xb8, 0xe0, 0x2a, 0xf6, 0x00, 0x00, 0x00,
381 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
382 0x00, 0xfc, 0x00, 0xf2, 0x1f, 0x04, 0x00, 0x00,
383 SKIP
, 0x00, 0x00, 0xc0, 0xc0, 0x10, 0x00, 0x00,
384 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
385 0x00, 0x40, 0xff, 0x03, 0x19, 0x00, 0x00, 0x00,
386 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
387 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc8, 0xc8,
388 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
389 0x08, 0x10, 0x24, 0x40, 0x00, 0x00, 0x00, 0x00,
390 0x01, 0x00, 0x02, 0x47, 0x00, 0x00, 0x00, 0x00,
391 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
392 0x00, 0x02, 0xfa, 0x00, 0x64, 0x5a, 0x28, 0x00,
396 static void reg_w_buf(struct gspca_dev
*gspca_dev
,
398 const u8
*buffer
, int len
)
402 if (gspca_dev
->usb_err
< 0)
404 memcpy(gspca_dev
->usb_buf
, buffer
, len
);
405 ret
= usb_control_msg(gspca_dev
->dev
,
406 usb_sndctrlpipe(gspca_dev
->dev
, 0),
408 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
410 index
, gspca_dev
->usb_buf
, len
,
413 pr_err("reg_w_buf failed index 0x%02x, error %d\n",
415 gspca_dev
->usb_err
= ret
;
420 static void reg_w(struct gspca_dev
*gspca_dev
,
426 if (gspca_dev
->usb_err
< 0)
428 gspca_dev
->usb_buf
[0] = value
;
429 ret
= usb_control_msg(gspca_dev
->dev
,
430 usb_sndctrlpipe(gspca_dev
->dev
, 0),
432 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
433 0, index
, gspca_dev
->usb_buf
, 1,
436 pr_err("reg_w() failed index 0x%02x, value 0x%02x, error %d\n",
438 gspca_dev
->usb_err
= ret
;
442 static void reg_w_seq(struct gspca_dev
*gspca_dev
,
443 const __u8
*seq
, int len
)
446 reg_w(gspca_dev
, seq
[0], seq
[1]);
451 /* load the beginning of a page */
452 static void reg_w_page(struct gspca_dev
*gspca_dev
,
453 const __u8
*page
, int len
)
458 if (gspca_dev
->usb_err
< 0)
460 for (index
= 0; index
< len
; index
++) {
461 if (page
[index
] == SKIP
) /* skip this index */
463 gspca_dev
->usb_buf
[0] = page
[index
];
464 ret
= usb_control_msg(gspca_dev
->dev
,
465 usb_sndctrlpipe(gspca_dev
->dev
, 0),
467 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
468 0, index
, gspca_dev
->usb_buf
, 1,
471 pr_err("reg_w_page() failed index 0x%02x, value 0x%02x, error %d\n",
472 index
, page
[index
], ret
);
473 gspca_dev
->usb_err
= ret
;
479 /* output a variable sequence */
480 static void reg_w_var(struct gspca_dev
*gspca_dev
,
482 const __u8
*page3
, unsigned int page3_len
)
490 case END_OF_SEQUENCE
:
493 reg_w_page(gspca_dev
, page3
, page3_len
);
496 if (len
> USB_BUF_SZ
) {
497 PDEBUG(D_ERR
|D_STREAM
,
498 "Incorrect variable sequence");
508 reg_w_buf(gspca_dev
, index
, seq
, 8);
518 /* this function is called at probe time for pac7302 */
519 static int sd_config(struct gspca_dev
*gspca_dev
,
520 const struct usb_device_id
*id
)
522 struct sd
*sd
= (struct sd
*) gspca_dev
;
525 cam
= &gspca_dev
->cam
;
527 PDEBUG(D_CONF
, "Find Sensor PAC7302");
528 cam
->cam_mode
= vga_mode
; /* only 640x480 */
529 cam
->nmodes
= ARRAY_SIZE(vga_mode
);
531 sd
->brightness
= BRIGHTNESS_DEF
;
532 sd
->contrast
= CONTRAST_DEF
;
533 sd
->colors
= COLOR_DEF
;
534 sd
->white_balance
= WHITEBALANCE_DEF
;
535 sd
->red_balance
= REDBALANCE_DEF
;
536 sd
->blue_balance
= BLUEBALANCE_DEF
;
538 sd
->exposure
= EXPOSURE_DEF
;
539 sd
->autogain
= AUTOGAIN_DEF
;
540 sd
->hflip
= HFLIP_DEF
;
541 sd
->vflip
= VFLIP_DEF
;
542 sd
->flags
= id
->driver_info
;
546 /* This function is used by pac7302 only */
547 static void setbrightcont(struct gspca_dev
*gspca_dev
)
549 struct sd
*sd
= (struct sd
*) gspca_dev
;
551 static const __u8 max
[10] =
552 {0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb,
554 static const __u8 delta
[10] =
555 {0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17,
558 reg_w(gspca_dev
, 0xff, 0x00); /* page 0 */
559 for (i
= 0; i
< 10; i
++) {
561 v
+= (sd
->brightness
- BRIGHTNESS_MAX
)
562 * 150 / BRIGHTNESS_MAX
; /* 200 ? */
563 v
-= delta
[i
] * sd
->contrast
/ CONTRAST_MAX
;
568 reg_w(gspca_dev
, 0xa2 + i
, v
);
570 reg_w(gspca_dev
, 0xdc, 0x01);
573 /* This function is used by pac7302 only */
574 static void setcolors(struct gspca_dev
*gspca_dev
)
576 struct sd
*sd
= (struct sd
*) gspca_dev
;
578 static const int a
[9] =
579 {217, -212, 0, -101, 170, -67, -38, -315, 355};
580 static const int b
[9] =
581 {19, 106, 0, 19, 106, 1, 19, 106, 1};
583 reg_w(gspca_dev
, 0xff, 0x03); /* page 3 */
584 reg_w(gspca_dev
, 0x11, 0x01);
585 reg_w(gspca_dev
, 0xff, 0x00); /* page 0 */
586 for (i
= 0; i
< 9; i
++) {
587 v
= a
[i
] * sd
->colors
/ COLOR_MAX
+ b
[i
];
588 reg_w(gspca_dev
, 0x0f + 2 * i
, (v
>> 8) & 0x07);
589 reg_w(gspca_dev
, 0x0f + 2 * i
+ 1, v
);
591 reg_w(gspca_dev
, 0xdc, 0x01);
592 PDEBUG(D_CONF
|D_STREAM
, "color: %i", sd
->colors
);
595 static void setwhitebalance(struct gspca_dev
*gspca_dev
)
597 struct sd
*sd
= (struct sd
*) gspca_dev
;
599 reg_w(gspca_dev
, 0xff, 0x00); /* page 0 */
600 reg_w(gspca_dev
, 0xc6, sd
->white_balance
);
602 reg_w(gspca_dev
, 0xdc, 0x01);
603 PDEBUG(D_CONF
|D_STREAM
, "white_balance: %i", sd
->white_balance
);
606 static void setredbalance(struct gspca_dev
*gspca_dev
)
608 struct sd
*sd
= (struct sd
*) gspca_dev
;
610 reg_w(gspca_dev
, 0xff, 0x00); /* page 0 */
611 reg_w(gspca_dev
, 0xc5, sd
->red_balance
);
613 reg_w(gspca_dev
, 0xdc, 0x01);
614 PDEBUG(D_CONF
|D_STREAM
, "red_balance: %i", sd
->red_balance
);
617 static void setbluebalance(struct gspca_dev
*gspca_dev
)
619 struct sd
*sd
= (struct sd
*) gspca_dev
;
621 reg_w(gspca_dev
, 0xff, 0x00); /* page 0 */
622 reg_w(gspca_dev
, 0xc7, sd
->blue_balance
);
624 reg_w(gspca_dev
, 0xdc, 0x01);
625 PDEBUG(D_CONF
|D_STREAM
, "blue_balance: %i", sd
->blue_balance
);
628 static void setgain(struct gspca_dev
*gspca_dev
)
630 struct sd
*sd
= (struct sd
*) gspca_dev
;
632 reg_w(gspca_dev
, 0xff, 0x03); /* page 3 */
633 reg_w(gspca_dev
, 0x10, sd
->gain
>> 3);
635 /* load registers to sensor (Bit 0, auto clear) */
636 reg_w(gspca_dev
, 0x11, 0x01);
639 static void setexposure(struct gspca_dev
*gspca_dev
)
641 struct sd
*sd
= (struct sd
*) gspca_dev
;
645 /* register 2 of frame 3 contains the clock divider configuring the
646 no fps according to the formula: 90 / reg. sd->exposure is the
647 desired exposure time in 0.5 ms. */
648 clockdiv
= (90 * sd
->exposure
+ 1999) / 2000;
650 /* Note clockdiv = 3 also works, but when running at 30 fps, depending
651 on the scene being recorded, the camera switches to another
652 quantization table for certain JPEG blocks, and we don't know how
653 to decompress these blocks. So we cap the framerate at 15 fps */
656 else if (clockdiv
> 63)
659 /* reg2 MUST be a multiple of 3, except when between 6 and 12?
660 Always round up, otherwise we cannot get the desired frametime
661 using the partial frame time exposure control */
662 if (clockdiv
< 6 || clockdiv
> 12)
663 clockdiv
= ((clockdiv
+ 2) / 3) * 3;
665 /* frame exposure time in ms = 1000 * clockdiv / 90 ->
666 exposure = (sd->exposure / 2) * 448 / (1000 * clockdiv / 90) */
667 exposure
= (sd
->exposure
* 45 * 448) / (1000 * clockdiv
);
668 /* 0 = use full frametime, 448 = no exposure, reverse it */
669 exposure
= 448 - exposure
;
671 reg_w(gspca_dev
, 0xff, 0x03); /* page 3 */
672 reg_w(gspca_dev
, 0x02, clockdiv
);
673 reg_w(gspca_dev
, 0x0e, exposure
& 0xff);
674 reg_w(gspca_dev
, 0x0f, exposure
>> 8);
676 /* load registers to sensor (Bit 0, auto clear) */
677 reg_w(gspca_dev
, 0x11, 0x01);
680 static void sethvflip(struct gspca_dev
*gspca_dev
)
682 struct sd
*sd
= (struct sd
*) gspca_dev
;
683 u8 data
, hflip
, vflip
;
686 if (sd
->flags
& FL_HFLIP
)
689 if (sd
->flags
& FL_VFLIP
)
692 reg_w(gspca_dev
, 0xff, 0x03); /* page 3 */
693 data
= (hflip
? 0x08 : 0x00) | (vflip
? 0x04 : 0x00);
694 reg_w(gspca_dev
, 0x21, data
);
696 /* load registers to sensor (Bit 0, auto clear) */
697 reg_w(gspca_dev
, 0x11, 0x01);
700 /* this function is called at probe and resume time for pac7302 */
701 static int sd_init(struct gspca_dev
*gspca_dev
)
703 reg_w_seq(gspca_dev
, init_7302
, sizeof(init_7302
)/2);
704 return gspca_dev
->usb_err
;
707 static int sd_start(struct gspca_dev
*gspca_dev
)
709 struct sd
*sd
= (struct sd
*) gspca_dev
;
713 reg_w_var(gspca_dev
, start_7302
,
714 page3_7302
, sizeof(page3_7302
));
715 setbrightcont(gspca_dev
);
716 setcolors(gspca_dev
);
717 setwhitebalance(gspca_dev
);
718 setredbalance(gspca_dev
);
719 setbluebalance(gspca_dev
);
721 setexposure(gspca_dev
);
722 sethvflip(gspca_dev
);
724 /* only resolution 640x480 is supported for pac7302 */
727 sd
->autogain_ignore_frames
= 0;
728 atomic_set(&sd
->avg_lum
, -1);
731 reg_w(gspca_dev
, 0xff, 0x01);
732 reg_w(gspca_dev
, 0x78, 0x01);
734 return gspca_dev
->usb_err
;
737 static void sd_stopN(struct gspca_dev
*gspca_dev
)
741 reg_w(gspca_dev
, 0xff, 0x01);
742 reg_w(gspca_dev
, 0x78, 0x00);
745 /* called on streamoff with alt 0 and on disconnect for pac7302 */
746 static void sd_stop0(struct gspca_dev
*gspca_dev
)
748 if (!gspca_dev
->present
)
750 reg_w(gspca_dev
, 0xff, 0x01);
751 reg_w(gspca_dev
, 0x78, 0x40);
754 /* Include pac common sof detection functions */
755 #include "pac_common.h"
757 static void do_autogain(struct gspca_dev
*gspca_dev
)
759 struct sd
*sd
= (struct sd
*) gspca_dev
;
760 int avg_lum
= atomic_read(&sd
->avg_lum
);
762 const int deadzone
= 30;
767 desired_lum
= 270 + sd
->brightness
;
769 if (sd
->autogain_ignore_frames
> 0)
770 sd
->autogain_ignore_frames
--;
771 else if (gspca_auto_gain_n_exposure(gspca_dev
, avg_lum
, desired_lum
,
772 deadzone
, GAIN_KNEE
, EXPOSURE_KNEE
))
773 sd
->autogain_ignore_frames
= PAC_AUTOGAIN_IGNORE_FRAMES
;
776 /* JPEG header, part 1 */
777 static const unsigned char pac_jpeg_header1
[] = {
778 0xff, 0xd8, /* SOI: Start of Image */
780 0xff, 0xc0, /* SOF0: Start of Frame (Baseline DCT) */
781 0x00, 0x11, /* length = 17 bytes (including this length field) */
782 0x08 /* Precision: 8 */
783 /* 2 bytes is placed here: number of image lines */
784 /* 2 bytes is placed here: samples per line */
787 /* JPEG header, continued */
788 static const unsigned char pac_jpeg_header2
[] = {
789 0x03, /* Number of image components: 3 */
790 0x01, 0x21, 0x00, /* ID=1, Subsampling 1x1, Quantization table: 0 */
791 0x02, 0x11, 0x01, /* ID=2, Subsampling 2x1, Quantization table: 1 */
792 0x03, 0x11, 0x01, /* ID=3, Subsampling 2x1, Quantization table: 1 */
794 0xff, 0xda, /* SOS: Start Of Scan */
795 0x00, 0x0c, /* length = 12 bytes (including this length field) */
796 0x03, /* number of components: 3 */
797 0x01, 0x00, /* selector 1, table 0x00 */
798 0x02, 0x11, /* selector 2, table 0x11 */
799 0x03, 0x11, /* selector 3, table 0x11 */
800 0x00, 0x3f, /* Spectral selection: 0 .. 63 */
801 0x00 /* Successive approximation: 0 */
804 static void pac_start_frame(struct gspca_dev
*gspca_dev
,
805 __u16 lines
, __u16 samples_per_line
)
807 unsigned char tmpbuf
[4];
809 gspca_frame_add(gspca_dev
, FIRST_PACKET
,
810 pac_jpeg_header1
, sizeof(pac_jpeg_header1
));
812 tmpbuf
[0] = lines
>> 8;
813 tmpbuf
[1] = lines
& 0xff;
814 tmpbuf
[2] = samples_per_line
>> 8;
815 tmpbuf
[3] = samples_per_line
& 0xff;
817 gspca_frame_add(gspca_dev
, INTER_PACKET
,
818 tmpbuf
, sizeof(tmpbuf
));
819 gspca_frame_add(gspca_dev
, INTER_PACKET
,
820 pac_jpeg_header2
, sizeof(pac_jpeg_header2
));
823 /* this function is run at interrupt level */
824 static void sd_pkt_scan(struct gspca_dev
*gspca_dev
,
825 u8
*data
, /* isoc packet */
826 int len
) /* iso packet length */
828 struct sd
*sd
= (struct sd
*) gspca_dev
;
832 sof
= pac_find_sof(&sd
->sof_read
, data
, len
);
834 int n
, lum_offset
, footer_length
;
836 /* 6 bytes after the FF D9 EOF marker a number of lumination
837 bytes are send corresponding to different parts of the
838 image, the 14th and 15th byte after the EOF seem to
839 correspond to the center of the image */
840 lum_offset
= 61 + sizeof pac_sof_marker
;
843 /* Finish decoding current frame */
844 n
= (sof
- data
) - (footer_length
+ sizeof pac_sof_marker
);
846 gspca_dev
->image_len
+= n
;
849 gspca_frame_add(gspca_dev
, INTER_PACKET
, data
, n
);
852 image
= gspca_dev
->image
;
854 && image
[gspca_dev
->image_len
- 2] == 0xff
855 && image
[gspca_dev
->image_len
- 1] == 0xd9)
856 gspca_frame_add(gspca_dev
, LAST_PACKET
, NULL
, 0);
862 /* Get average lumination */
863 if (gspca_dev
->last_packet_type
== LAST_PACKET
&&
865 atomic_set(&sd
->avg_lum
, data
[-lum_offset
] +
866 data
[-lum_offset
+ 1]);
868 atomic_set(&sd
->avg_lum
, -1);
870 /* Start the new frame with the jpeg header */
871 /* The PAC7302 has the image rotated 90 degrees */
872 pac_start_frame(gspca_dev
,
873 gspca_dev
->width
, gspca_dev
->height
);
875 gspca_frame_add(gspca_dev
, INTER_PACKET
, data
, len
);
878 static int sd_setbrightness(struct gspca_dev
*gspca_dev
, __s32 val
)
880 struct sd
*sd
= (struct sd
*) gspca_dev
;
882 sd
->brightness
= val
;
883 if (gspca_dev
->streaming
)
884 setbrightcont(gspca_dev
);
885 return gspca_dev
->usb_err
;
888 static int sd_getbrightness(struct gspca_dev
*gspca_dev
, __s32
*val
)
890 struct sd
*sd
= (struct sd
*) gspca_dev
;
892 *val
= sd
->brightness
;
896 static int sd_setcontrast(struct gspca_dev
*gspca_dev
, __s32 val
)
898 struct sd
*sd
= (struct sd
*) gspca_dev
;
901 if (gspca_dev
->streaming
)
902 setbrightcont(gspca_dev
);
903 return gspca_dev
->usb_err
;
906 static int sd_getcontrast(struct gspca_dev
*gspca_dev
, __s32
*val
)
908 struct sd
*sd
= (struct sd
*) gspca_dev
;
914 static int sd_setcolors(struct gspca_dev
*gspca_dev
, __s32 val
)
916 struct sd
*sd
= (struct sd
*) gspca_dev
;
919 if (gspca_dev
->streaming
)
920 setcolors(gspca_dev
);
921 return gspca_dev
->usb_err
;
924 static int sd_getcolors(struct gspca_dev
*gspca_dev
, __s32
*val
)
926 struct sd
*sd
= (struct sd
*) gspca_dev
;
932 static int sd_setwhitebalance(struct gspca_dev
*gspca_dev
, __s32 val
)
934 struct sd
*sd
= (struct sd
*) gspca_dev
;
936 sd
->white_balance
= val
;
937 if (gspca_dev
->streaming
)
938 setwhitebalance(gspca_dev
);
939 return gspca_dev
->usb_err
;
942 static int sd_getwhitebalance(struct gspca_dev
*gspca_dev
, __s32
*val
)
944 struct sd
*sd
= (struct sd
*) gspca_dev
;
946 *val
= sd
->white_balance
;
950 static int sd_setredbalance(struct gspca_dev
*gspca_dev
, __s32 val
)
952 struct sd
*sd
= (struct sd
*) gspca_dev
;
954 sd
->red_balance
= val
;
955 if (gspca_dev
->streaming
)
956 setredbalance(gspca_dev
);
957 return gspca_dev
->usb_err
;
960 static int sd_getredbalance(struct gspca_dev
*gspca_dev
, __s32
*val
)
962 struct sd
*sd
= (struct sd
*) gspca_dev
;
964 *val
= sd
->red_balance
;
968 static int sd_setbluebalance(struct gspca_dev
*gspca_dev
, __s32 val
)
970 struct sd
*sd
= (struct sd
*) gspca_dev
;
972 sd
->blue_balance
= val
;
973 if (gspca_dev
->streaming
)
974 setbluebalance(gspca_dev
);
975 return gspca_dev
->usb_err
;
978 static int sd_getbluebalance(struct gspca_dev
*gspca_dev
, __s32
*val
)
980 struct sd
*sd
= (struct sd
*) gspca_dev
;
982 *val
= sd
->blue_balance
;
986 static int sd_setgain(struct gspca_dev
*gspca_dev
, __s32 val
)
988 struct sd
*sd
= (struct sd
*) gspca_dev
;
991 if (gspca_dev
->streaming
)
993 return gspca_dev
->usb_err
;
996 static int sd_getgain(struct gspca_dev
*gspca_dev
, __s32
*val
)
998 struct sd
*sd
= (struct sd
*) gspca_dev
;
1004 static int sd_setexposure(struct gspca_dev
*gspca_dev
, __s32 val
)
1006 struct sd
*sd
= (struct sd
*) gspca_dev
;
1009 if (gspca_dev
->streaming
)
1010 setexposure(gspca_dev
);
1011 return gspca_dev
->usb_err
;
1014 static int sd_getexposure(struct gspca_dev
*gspca_dev
, __s32
*val
)
1016 struct sd
*sd
= (struct sd
*) gspca_dev
;
1018 *val
= sd
->exposure
;
1022 static int sd_setautogain(struct gspca_dev
*gspca_dev
, __s32 val
)
1024 struct sd
*sd
= (struct sd
*) gspca_dev
;
1027 /* when switching to autogain set defaults to make sure
1028 we are on a valid point of the autogain gain /
1029 exposure knee graph, and give this change time to
1030 take effect before doing autogain. */
1032 sd
->exposure
= EXPOSURE_DEF
;
1033 sd
->gain
= GAIN_DEF
;
1034 if (gspca_dev
->streaming
) {
1035 sd
->autogain_ignore_frames
=
1036 PAC_AUTOGAIN_IGNORE_FRAMES
;
1037 setexposure(gspca_dev
);
1042 return gspca_dev
->usb_err
;
1045 static int sd_getautogain(struct gspca_dev
*gspca_dev
, __s32
*val
)
1047 struct sd
*sd
= (struct sd
*) gspca_dev
;
1049 *val
= sd
->autogain
;
1053 static int sd_sethflip(struct gspca_dev
*gspca_dev
, __s32 val
)
1055 struct sd
*sd
= (struct sd
*) gspca_dev
;
1058 if (gspca_dev
->streaming
)
1059 sethvflip(gspca_dev
);
1060 return gspca_dev
->usb_err
;
1063 static int sd_gethflip(struct gspca_dev
*gspca_dev
, __s32
*val
)
1065 struct sd
*sd
= (struct sd
*) gspca_dev
;
1071 static int sd_setvflip(struct gspca_dev
*gspca_dev
, __s32 val
)
1073 struct sd
*sd
= (struct sd
*) gspca_dev
;
1076 if (gspca_dev
->streaming
)
1077 sethvflip(gspca_dev
);
1078 return gspca_dev
->usb_err
;
1081 static int sd_getvflip(struct gspca_dev
*gspca_dev
, __s32
*val
)
1083 struct sd
*sd
= (struct sd
*) gspca_dev
;
1089 #ifdef CONFIG_VIDEO_ADV_DEBUG
1090 static int sd_dbg_s_register(struct gspca_dev
*gspca_dev
,
1091 struct v4l2_dbg_register
*reg
)
1096 /* reg->reg: bit0..15: reserved for register index (wIndex is 16bit
1097 long on the USB bus)
1099 if (reg
->match
.type
== V4L2_CHIP_MATCH_HOST
&&
1100 reg
->match
.addr
== 0 &&
1101 (reg
->reg
< 0x000000ff) &&
1102 (reg
->val
<= 0x000000ff)
1104 /* Currently writing to page 0 is only supported. */
1105 /* reg_w() only supports 8bit index */
1106 index
= reg
->reg
& 0x000000ff;
1107 value
= reg
->val
& 0x000000ff;
1109 /* Note that there shall be no access to other page
1110 by any other function between the page swith and
1111 the actual register write */
1112 reg_w(gspca_dev
, 0xff, 0x00); /* page 0 */
1113 reg_w(gspca_dev
, index
, value
);
1115 reg_w(gspca_dev
, 0xdc, 0x01);
1117 return gspca_dev
->usb_err
;
1120 static int sd_chip_ident(struct gspca_dev
*gspca_dev
,
1121 struct v4l2_dbg_chip_ident
*chip
)
1125 if (chip
->match
.type
== V4L2_CHIP_MATCH_HOST
&&
1126 chip
->match
.addr
== 0) {
1128 chip
->ident
= V4L2_IDENT_UNKNOWN
;
1135 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
1136 static int sd_int_pkt_scan(struct gspca_dev
*gspca_dev
,
1137 u8
*data
, /* interrupt packet data */
1138 int len
) /* interrput packet length */
1146 if ((data0
== 0x00 && data1
== 0x11) ||
1147 (data0
== 0x22 && data1
== 0x33) ||
1148 (data0
== 0x44 && data1
== 0x55) ||
1149 (data0
== 0x66 && data1
== 0x77) ||
1150 (data0
== 0x88 && data1
== 0x99) ||
1151 (data0
== 0xaa && data1
== 0xbb) ||
1152 (data0
== 0xcc && data1
== 0xdd) ||
1153 (data0
== 0xee && data1
== 0xff)) {
1154 input_report_key(gspca_dev
->input_dev
, KEY_CAMERA
, 1);
1155 input_sync(gspca_dev
->input_dev
);
1156 input_report_key(gspca_dev
->input_dev
, KEY_CAMERA
, 0);
1157 input_sync(gspca_dev
->input_dev
);
1166 /* sub-driver description for pac7302 */
1167 static const struct sd_desc sd_desc
= {
1168 .name
= MODULE_NAME
,
1170 .nctrls
= ARRAY_SIZE(sd_ctrls
),
1171 .config
= sd_config
,
1176 .pkt_scan
= sd_pkt_scan
,
1177 .dq_callback
= do_autogain
,
1178 #ifdef CONFIG_VIDEO_ADV_DEBUG
1179 .set_register
= sd_dbg_s_register
,
1180 .get_chip_ident
= sd_chip_ident
,
1182 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
1183 .int_pkt_scan
= sd_int_pkt_scan
,
1187 /* -- module initialisation -- */
1188 static const struct usb_device_id device_table
[] = {
1189 {USB_DEVICE(0x06f8, 0x3009)},
1190 {USB_DEVICE(0x093a, 0x2620)},
1191 {USB_DEVICE(0x093a, 0x2621)},
1192 {USB_DEVICE(0x093a, 0x2622), .driver_info
= FL_VFLIP
},
1193 {USB_DEVICE(0x093a, 0x2624), .driver_info
= FL_VFLIP
},
1194 {USB_DEVICE(0x093a, 0x2625)},
1195 {USB_DEVICE(0x093a, 0x2626)},
1196 {USB_DEVICE(0x093a, 0x2628)},
1197 {USB_DEVICE(0x093a, 0x2629), .driver_info
= FL_VFLIP
},
1198 {USB_DEVICE(0x093a, 0x262a)},
1199 {USB_DEVICE(0x093a, 0x262c)},
1200 {USB_DEVICE(0x145f, 0x013c)},
1203 MODULE_DEVICE_TABLE(usb
, device_table
);
1205 /* -- device connect -- */
1206 static int sd_probe(struct usb_interface
*intf
,
1207 const struct usb_device_id
*id
)
1209 return gspca_dev_probe(intf
, id
, &sd_desc
, sizeof(struct sd
),
1213 static struct usb_driver sd_driver
= {
1214 .name
= MODULE_NAME
,
1215 .id_table
= device_table
,
1217 .disconnect
= gspca_disconnect
,
1219 .suspend
= gspca_suspend
,
1220 .resume
= gspca_resume
,
1224 module_usb_driver(sd_driver
);