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 <nm127@freemail.hu>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 /* Some documentation about various registers as determined by trial and error.
25 When the register addresses differ between the 7202 and the 7311 the 2
26 different addresses are written as 7302addr/7311addr, when one of the 2
27 addresses is a - sign that register description is not valid for the
33 -/0x08 Unknown compressor related, must always be 8 except when not
34 in 640x480 resolution and page 4 reg 2 <= 3 then set it to 9 !
35 -/0x1b Auto white balance related, bit 0 is AWB enable (inverted)
36 bits 345 seem to toggle per color gains on/off (inverted)
37 0x78 Global control, bit 6 controls the LED (inverted)
38 -/0x80 JPEG compression ratio ? Best not touched
43 0x02 Clock divider 2-63, fps =~ 60 / val. Must be a multiple of 3 on
44 the 7302, so one of 3, 6, 9, ..., except when between 6 and 12?
45 -/0x0f Master gain 1-245, low value = high gain
46 0x10/- Master gain 0-31
47 -/0x10 Another gain 0-15, limited influence (1-2x gain I guess)
48 0x21 Bitfield: 0-1 unused, 2-3 vflip/hflip, 4-5 unknown, 6-7 unused
49 -/0x27 Seems to toggle various gains on / off, Setting bit 7 seems to
50 completely disable the analog amplification block. Set to 0x68
51 for max gain, 0x14 for minimal gain.
53 The registers are accessed in the following functions:
55 Page | Register | Function
56 -----+------------+---------------------------------------------------
57 0 | 0x0f..0x20 | setcolors()
58 0 | 0xa2..0xab | setbrightcont()
59 0 | 0xc5 | setredbalance()
60 0 | 0xc6 | setwhitebalance()
61 0 | 0xc7 | setbluebalance()
62 0 | 0xdc | setbrightcont(), setcolors()
63 3 | 0x02 | setexposure()
65 3 | 0x11 | setcolors(), setgain(), setexposure(), sethvflip()
66 3 | 0x21 | sethvflip()
69 #define MODULE_NAME "pac7302"
71 #include <media/v4l2-chip-ident.h>
74 MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li");
75 MODULE_DESCRIPTION("Pixart PAC7302");
76 MODULE_LICENSE("GPL");
78 /* specific webcam descriptor for pac7302 */
80 struct gspca_dev gspca_dev
; /* !! must be the first item */
82 unsigned char brightness
;
83 unsigned char contrast
;
85 unsigned char white_balance
;
86 unsigned char red_balance
;
87 unsigned char blue_balance
;
89 unsigned char exposure
;
90 unsigned char autogain
;
94 #define FL_HFLIP 0x01 /* mirrored by default */
95 #define FL_VFLIP 0x02 /* vertical flipped by default */
98 u8 autogain_ignore_frames
;
103 /* V4L2 controls supported by the driver */
104 static int sd_setbrightness(struct gspca_dev
*gspca_dev
, __s32 val
);
105 static int sd_getbrightness(struct gspca_dev
*gspca_dev
, __s32
*val
);
106 static int sd_setcontrast(struct gspca_dev
*gspca_dev
, __s32 val
);
107 static int sd_getcontrast(struct gspca_dev
*gspca_dev
, __s32
*val
);
108 static int sd_setcolors(struct gspca_dev
*gspca_dev
, __s32 val
);
109 static int sd_getcolors(struct gspca_dev
*gspca_dev
, __s32
*val
);
110 static int sd_setwhitebalance(struct gspca_dev
*gspca_dev
, __s32 val
);
111 static int sd_getwhitebalance(struct gspca_dev
*gspca_dev
, __s32
*val
);
112 static int sd_setredbalance(struct gspca_dev
*gspca_dev
, __s32 val
);
113 static int sd_getredbalance(struct gspca_dev
*gspca_dev
, __s32
*val
);
114 static int sd_setbluebalance(struct gspca_dev
*gspca_dev
, __s32 val
);
115 static int sd_getbluebalance(struct gspca_dev
*gspca_dev
, __s32
*val
);
116 static int sd_setautogain(struct gspca_dev
*gspca_dev
, __s32 val
);
117 static int sd_getautogain(struct gspca_dev
*gspca_dev
, __s32
*val
);
118 static int sd_sethflip(struct gspca_dev
*gspca_dev
, __s32 val
);
119 static int sd_gethflip(struct gspca_dev
*gspca_dev
, __s32
*val
);
120 static int sd_setvflip(struct gspca_dev
*gspca_dev
, __s32 val
);
121 static int sd_getvflip(struct gspca_dev
*gspca_dev
, __s32
*val
);
122 static int sd_setgain(struct gspca_dev
*gspca_dev
, __s32 val
);
123 static int sd_getgain(struct gspca_dev
*gspca_dev
, __s32
*val
);
124 static int sd_setexposure(struct gspca_dev
*gspca_dev
, __s32 val
);
125 static int sd_getexposure(struct gspca_dev
*gspca_dev
, __s32
*val
);
127 static struct ctrl sd_ctrls
[] = {
128 /* This control is pac7302 only */
131 .id
= V4L2_CID_BRIGHTNESS
,
132 .type
= V4L2_CTRL_TYPE_INTEGER
,
133 .name
= "Brightness",
135 #define BRIGHTNESS_MAX 0x20
136 .maximum
= BRIGHTNESS_MAX
,
138 #define BRIGHTNESS_DEF 0x10
139 .default_value
= BRIGHTNESS_DEF
,
141 .set
= sd_setbrightness
,
142 .get
= sd_getbrightness
,
144 /* This control is for both the 7302 and the 7311 */
147 .id
= V4L2_CID_CONTRAST
,
148 .type
= V4L2_CTRL_TYPE_INTEGER
,
151 #define CONTRAST_MAX 255
152 .maximum
= CONTRAST_MAX
,
154 #define CONTRAST_DEF 127
155 .default_value
= CONTRAST_DEF
,
157 .set
= sd_setcontrast
,
158 .get
= sd_getcontrast
,
160 /* This control is pac7302 only */
163 .id
= V4L2_CID_SATURATION
,
164 .type
= V4L2_CTRL_TYPE_INTEGER
,
165 .name
= "Saturation",
167 #define COLOR_MAX 255
168 .maximum
= COLOR_MAX
,
170 #define COLOR_DEF 127
171 .default_value
= COLOR_DEF
,
178 .id
= V4L2_CID_WHITE_BALANCE_TEMPERATURE
,
179 .type
= V4L2_CTRL_TYPE_INTEGER
,
180 .name
= "White Balance",
184 #define WHITEBALANCE_DEF 4
185 .default_value
= WHITEBALANCE_DEF
,
187 .set
= sd_setwhitebalance
,
188 .get
= sd_getwhitebalance
,
192 .id
= V4L2_CID_RED_BALANCE
,
193 .type
= V4L2_CTRL_TYPE_INTEGER
,
198 #define REDBALANCE_DEF 1
199 .default_value
= REDBALANCE_DEF
,
201 .set
= sd_setredbalance
,
202 .get
= sd_getredbalance
,
206 .id
= V4L2_CID_BLUE_BALANCE
,
207 .type
= V4L2_CTRL_TYPE_INTEGER
,
212 #define BLUEBALANCE_DEF 1
213 .default_value
= BLUEBALANCE_DEF
,
215 .set
= sd_setbluebalance
,
216 .get
= sd_getbluebalance
,
218 /* All controls below are for both the 7302 and the 7311 */
222 .type
= V4L2_CTRL_TYPE_INTEGER
,
229 #define GAIN_KNEE 255 /* Gain seems to cause little noise on the pac73xx */
230 .default_value
= GAIN_DEF
,
237 .id
= V4L2_CID_EXPOSURE
,
238 .type
= V4L2_CTRL_TYPE_INTEGER
,
241 #define EXPOSURE_MAX 255
242 .maximum
= EXPOSURE_MAX
,
244 #define EXPOSURE_DEF 16 /* 32 ms / 30 fps */
245 #define EXPOSURE_KNEE 50 /* 100 ms / 10 fps */
246 .default_value
= EXPOSURE_DEF
,
248 .set
= sd_setexposure
,
249 .get
= sd_getexposure
,
253 .id
= V4L2_CID_AUTOGAIN
,
254 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
259 #define AUTOGAIN_DEF 1
260 .default_value
= AUTOGAIN_DEF
,
262 .set
= sd_setautogain
,
263 .get
= sd_getautogain
,
267 .id
= V4L2_CID_HFLIP
,
268 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
274 .default_value
= HFLIP_DEF
,
281 .id
= V4L2_CID_VFLIP
,
282 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
288 .default_value
= VFLIP_DEF
,
295 static const struct v4l2_pix_format vga_mode
[] = {
296 {640, 480, V4L2_PIX_FMT_PJPG
, V4L2_FIELD_NONE
,
298 .sizeimage
= 640 * 480 * 3 / 8 + 590,
299 .colorspace
= V4L2_COLORSPACE_JPEG
,
303 #define LOAD_PAGE3 255
304 #define LOAD_PAGE4 254
305 #define END_OF_SEQUENCE 0
308 static const __u8 init_7302
[] = {
310 0xff, 0x01, /* page 1 */
311 0x78, 0x00, /* deactivate */
313 0x78, 0x40, /* led off */
315 static const __u8 start_7302
[] = {
316 /* index, len, [value]* */
317 0xff, 1, 0x00, /* page 0 */
318 0x00, 12, 0x01, 0x40, 0x40, 0x40, 0x01, 0xe0, 0x02, 0x80,
319 0x00, 0x00, 0x00, 0x00,
320 0x0d, 24, 0x03, 0x01, 0x00, 0xb5, 0x07, 0xcb, 0x00, 0x00,
321 0x07, 0xc8, 0x00, 0xea, 0x07, 0xcf, 0x07, 0xf7,
322 0x07, 0x7e, 0x01, 0x0b, 0x00, 0x00, 0x00, 0x11,
326 0x3a, 3, 0x14, 0xff, 0x5a,
327 0x43, 11, 0x00, 0x0a, 0x18, 0x11, 0x01, 0x2c, 0x88, 0x11,
330 0x62, 4, 0x10, 0x1e, 0x1e, 0x18,
332 0x6e, 3, 0x08, 0x06, 0x00,
333 0x72, 3, 0x00, 0xff, 0x00,
334 0x7d, 23, 0x01, 0x01, 0x58, 0x46, 0x50, 0x3c, 0x50, 0x3c,
335 0x54, 0x46, 0x54, 0x56, 0x52, 0x50, 0x52, 0x50,
336 0x56, 0x64, 0xa4, 0x00, 0xda, 0x00, 0x00,
337 0xa2, 10, 0x22, 0x2c, 0x3c, 0x54, 0x69, 0x7c, 0x9c, 0xb9,
342 0xc4, 4, 0xae, 0x01, 0x04, 0x01,
344 0xd1, 11, 0x01, 0x30, 0x49, 0x5e, 0x6f, 0x7f, 0x8e, 0xa9,
347 0xff, 1, 0x01, /* page 1 */
348 0x12, 3, 0x02, 0x00, 0x01,
350 0x76, 5, 0x01, 0x20, 0x40, 0x00, 0xf2,
352 0x7f, 10, 0x4b, 0x0f, 0x01, 0x2c, 0x02, 0x58, 0x03, 0x20,
354 0x96, 5, 0x01, 0x10, 0x04, 0x01, 0x04,
355 0xc8, 14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
356 0x07, 0x00, 0x01, 0x07, 0x04, 0x01,
359 0xde, 7, 0x00, 0x01, 0x04, 0x04, 0x00, 0x00, 0x00,
360 0xe6, 4, 0x00, 0x00, 0x00, 0x01,
362 0xff, 1, 0x02, /* page 2 */
364 0xff, 1, 0x03, /* page 3 */
365 0, LOAD_PAGE3
, /* load the page 3 */
367 0xff, 1, 0x02, /* page 2 */
369 0x22, 4, 0x1f, 0xa4, 0xf0, 0x96,
371 0x2a, 5, 0xc8, 0x00, 0x18, 0x12, 0x22,
372 0x64, 8, 0x00, 0x00, 0xf0, 0x01, 0x14, 0x44, 0x44, 0x44,
374 0xff, 1, 0x01, /* page 1 */
376 0, END_OF_SEQUENCE
/* end of sequence */
380 /* page 3 - the value SKIP says skip the index - see reg_w_page() */
381 static const __u8 page3_7302
[] = {
382 0x90, 0x40, 0x03, 0x50, 0xc2, 0x01, 0x14, 0x16,
383 0x14, 0x12, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00,
384 0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
385 0x00, 0x00, 0x00, 0x47, 0x01, 0xb3, 0x01, 0x00,
386 0x00, 0x08, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x21,
387 0x00, 0x00, 0x00, 0x54, 0xf4, 0x02, 0x52, 0x54,
388 0xa4, 0xb8, 0xe0, 0x2a, 0xf6, 0x00, 0x00, 0x00,
389 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
390 0x00, 0xfc, 0x00, 0xf2, 0x1f, 0x04, 0x00, 0x00,
391 0x00, 0x00, 0x00, 0xc0, 0xc0, 0x10, 0x00, 0x00,
392 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
393 0x00, 0x40, 0xff, 0x03, 0x19, 0x00, 0x00, 0x00,
394 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
395 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc8, 0xc8,
396 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
397 0x08, 0x10, 0x24, 0x40, 0x00, 0x00, 0x00, 0x00,
398 0x01, 0x00, 0x02, 0x47, 0x00, 0x00, 0x00, 0x00,
399 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
400 0x00, 0x02, 0xfa, 0x00, 0x64, 0x5a, 0x28, 0x00,
404 static int reg_w_buf(struct gspca_dev
*gspca_dev
,
406 const char *buffer
, int len
)
410 memcpy(gspca_dev
->usb_buf
, buffer
, len
);
411 ret
= usb_control_msg(gspca_dev
->dev
,
412 usb_sndctrlpipe(gspca_dev
->dev
, 0),
414 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
416 index
, gspca_dev
->usb_buf
, len
,
419 PDEBUG(D_ERR
, "reg_w_buf(): "
420 "Failed to write registers to index 0x%x, error %i",
426 static int reg_w(struct gspca_dev
*gspca_dev
,
432 gspca_dev
->usb_buf
[0] = value
;
433 ret
= usb_control_msg(gspca_dev
->dev
,
434 usb_sndctrlpipe(gspca_dev
->dev
, 0),
436 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
437 0, index
, gspca_dev
->usb_buf
, 1,
440 PDEBUG(D_ERR
, "reg_w(): "
441 "Failed to write register to index 0x%x, value 0x%x, error %i",
446 static int reg_w_seq(struct gspca_dev
*gspca_dev
,
447 const __u8
*seq
, int len
)
452 ret
= reg_w(gspca_dev
, seq
[0], seq
[1]);
458 /* load the beginning of a page */
459 static int reg_w_page(struct gspca_dev
*gspca_dev
,
460 const __u8
*page
, int len
)
465 for (index
= 0; index
< len
; index
++) {
466 if (page
[index
] == SKIP
) /* skip this index */
468 gspca_dev
->usb_buf
[0] = page
[index
];
469 ret
= usb_control_msg(gspca_dev
->dev
,
470 usb_sndctrlpipe(gspca_dev
->dev
, 0),
472 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
473 0, index
, gspca_dev
->usb_buf
, 1,
476 PDEBUG(D_ERR
, "reg_w_page(): "
477 "Failed to write register to index 0x%x, "
478 "value 0x%x, error %i",
479 index
, page
[index
], ret
);
486 /* output a variable sequence */
487 static int reg_w_var(struct gspca_dev
*gspca_dev
,
489 const __u8
*page3
, unsigned int page3_len
,
490 const __u8
*page4
, unsigned int page4_len
)
499 case END_OF_SEQUENCE
:
502 ret
= reg_w_page(gspca_dev
, page4
, page4_len
);
505 ret
= reg_w_page(gspca_dev
, page3
, page3_len
);
508 if (len
> USB_BUF_SZ
) {
509 PDEBUG(D_ERR
|D_STREAM
,
510 "Incorrect variable sequence");
515 ret
= reg_w_buf(gspca_dev
,
522 ret
= reg_w_buf(gspca_dev
, index
, seq
, 8);
534 /* this function is called at probe time for pac7302 */
535 static int sd_config(struct gspca_dev
*gspca_dev
,
536 const struct usb_device_id
*id
)
538 struct sd
*sd
= (struct sd
*) gspca_dev
;
541 cam
= &gspca_dev
->cam
;
543 PDEBUG(D_CONF
, "Find Sensor PAC7302");
544 cam
->cam_mode
= vga_mode
; /* only 640x480 */
545 cam
->nmodes
= ARRAY_SIZE(vga_mode
);
547 sd
->brightness
= BRIGHTNESS_DEF
;
548 sd
->contrast
= CONTRAST_DEF
;
549 sd
->colors
= COLOR_DEF
;
550 sd
->white_balance
= WHITEBALANCE_DEF
;
551 sd
->red_balance
= REDBALANCE_DEF
;
552 sd
->blue_balance
= BLUEBALANCE_DEF
;
554 sd
->exposure
= EXPOSURE_DEF
;
555 sd
->autogain
= AUTOGAIN_DEF
;
556 sd
->hflip
= HFLIP_DEF
;
557 sd
->vflip
= VFLIP_DEF
;
558 sd
->flags
= id
->driver_info
;
562 /* This function is used by pac7302 only */
563 static int setbrightcont(struct gspca_dev
*gspca_dev
)
565 struct sd
*sd
= (struct sd
*) gspca_dev
;
568 static const __u8 max
[10] =
569 {0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb,
571 static const __u8 delta
[10] =
572 {0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17,
575 ret
= reg_w(gspca_dev
, 0xff, 0x00); /* page 0 */
576 for (i
= 0; i
< 10; i
++) {
578 v
+= (sd
->brightness
- BRIGHTNESS_MAX
)
579 * 150 / BRIGHTNESS_MAX
; /* 200 ? */
580 v
-= delta
[i
] * sd
->contrast
/ CONTRAST_MAX
;
586 ret
= reg_w(gspca_dev
, 0xa2 + i
, v
);
589 ret
= reg_w(gspca_dev
, 0xdc, 0x01);
593 /* This function is used by pac7302 only */
594 static int setcolors(struct gspca_dev
*gspca_dev
)
596 struct sd
*sd
= (struct sd
*) gspca_dev
;
599 static const int a
[9] =
600 {217, -212, 0, -101, 170, -67, -38, -315, 355};
601 static const int b
[9] =
602 {19, 106, 0, 19, 106, 1, 19, 106, 1};
604 ret
= reg_w(gspca_dev
, 0xff, 0x03); /* page 3 */
606 ret
= reg_w(gspca_dev
, 0x11, 0x01);
608 ret
= reg_w(gspca_dev
, 0xff, 0x00); /* page 0 */
609 for (i
= 0; i
< 9; i
++) {
610 v
= a
[i
] * sd
->colors
/ COLOR_MAX
+ b
[i
];
612 ret
= reg_w(gspca_dev
, 0x0f + 2 * i
, (v
>> 8) & 0x07);
614 ret
= reg_w(gspca_dev
, 0x0f + 2 * i
+ 1, v
);
617 ret
= reg_w(gspca_dev
, 0xdc, 0x01);
618 PDEBUG(D_CONF
|D_STREAM
, "color: %i", sd
->colors
);
622 static int setwhitebalance(struct gspca_dev
*gspca_dev
)
624 struct sd
*sd
= (struct sd
*) gspca_dev
;
627 ret
= reg_w(gspca_dev
, 0xff, 0x00); /* page 0 */
629 ret
= reg_w(gspca_dev
, 0xc6, sd
->white_balance
);
632 ret
= reg_w(gspca_dev
, 0xdc, 0x01);
633 PDEBUG(D_CONF
|D_STREAM
, "white_balance: %i", sd
->white_balance
);
637 static int setredbalance(struct gspca_dev
*gspca_dev
)
639 struct sd
*sd
= (struct sd
*) gspca_dev
;
642 ret
= reg_w(gspca_dev
, 0xff, 0x00); /* page 0 */
644 ret
= reg_w(gspca_dev
, 0xc5, sd
->red_balance
);
647 ret
= reg_w(gspca_dev
, 0xdc, 0x01);
648 PDEBUG(D_CONF
|D_STREAM
, "red_balance: %i", sd
->red_balance
);
652 static int setbluebalance(struct gspca_dev
*gspca_dev
)
654 struct sd
*sd
= (struct sd
*) gspca_dev
;
657 ret
= reg_w(gspca_dev
, 0xff, 0x00); /* page 0 */
659 ret
= reg_w(gspca_dev
, 0xc7, sd
->blue_balance
);
662 ret
= reg_w(gspca_dev
, 0xdc, 0x01);
663 PDEBUG(D_CONF
|D_STREAM
, "blue_balance: %i", sd
->blue_balance
);
667 static int setgain(struct gspca_dev
*gspca_dev
)
669 struct sd
*sd
= (struct sd
*) gspca_dev
;
672 ret
= reg_w(gspca_dev
, 0xff, 0x03); /* page 3 */
674 ret
= reg_w(gspca_dev
, 0x10, sd
->gain
>> 3);
676 /* load registers to sensor (Bit 0, auto clear) */
678 ret
= reg_w(gspca_dev
, 0x11, 0x01);
682 static int setexposure(struct gspca_dev
*gspca_dev
)
684 struct sd
*sd
= (struct sd
*) gspca_dev
;
688 /* register 2 of frame 3/4 contains the clock divider configuring the
689 no fps according to the formula: 60 / reg. sd->exposure is the
690 desired exposure time in ms. */
691 reg
= 120 * sd
->exposure
/ 1000;
697 /* On the pac7302 reg2 MUST be a multiple of 3, so round it to
698 the nearest multiple of 3, except when between 6 and 12? */
699 if (reg
< 6 || reg
> 12)
700 reg
= ((reg
+ 1) / 3) * 3;
701 ret
= reg_w(gspca_dev
, 0xff, 0x03); /* page 3 */
703 ret
= reg_w(gspca_dev
, 0x02, reg
);
705 /* load registers to sensor (Bit 0, auto clear) */
707 ret
= reg_w(gspca_dev
, 0x11, 0x01);
711 static int sethvflip(struct gspca_dev
*gspca_dev
)
713 struct sd
*sd
= (struct sd
*) gspca_dev
;
715 u8 data
, hflip
, vflip
;
718 if (sd
->flags
& FL_HFLIP
)
721 if (sd
->flags
& FL_VFLIP
)
724 ret
= reg_w(gspca_dev
, 0xff, 0x03); /* page 3 */
725 data
= (hflip
? 0x08 : 0x00) | (vflip
? 0x04 : 0x00);
727 ret
= reg_w(gspca_dev
, 0x21, data
);
728 /* load registers to sensor (Bit 0, auto clear) */
730 ret
= reg_w(gspca_dev
, 0x11, 0x01);
734 /* this function is called at probe and resume time for pac7302 */
735 static int sd_init(struct gspca_dev
*gspca_dev
)
737 return reg_w_seq(gspca_dev
, init_7302
, sizeof(init_7302
)/2);
740 static int sd_start(struct gspca_dev
*gspca_dev
)
742 struct sd
*sd
= (struct sd
*) gspca_dev
;
747 ret
= reg_w_var(gspca_dev
, start_7302
,
748 page3_7302
, sizeof(page3_7302
),
751 ret
= setbrightcont(gspca_dev
);
753 ret
= setcolors(gspca_dev
);
755 ret
= setwhitebalance(gspca_dev
);
757 ret
= setredbalance(gspca_dev
);
759 ret
= setbluebalance(gspca_dev
);
761 ret
= setgain(gspca_dev
);
763 ret
= setexposure(gspca_dev
);
765 ret
= sethvflip(gspca_dev
);
767 /* only resolution 640x480 is supported for pac7302 */
770 sd
->autogain_ignore_frames
= 0;
771 atomic_set(&sd
->avg_lum
, -1);
775 ret
= reg_w(gspca_dev
, 0xff, 0x01);
777 ret
= reg_w(gspca_dev
, 0x78, 0x01);
782 static void sd_stopN(struct gspca_dev
*gspca_dev
)
787 ret
= reg_w(gspca_dev
, 0xff, 0x01);
789 ret
= reg_w(gspca_dev
, 0x78, 0x00);
792 /* called on streamoff with alt 0 and on disconnect for pac7302 */
793 static void sd_stop0(struct gspca_dev
*gspca_dev
)
797 if (!gspca_dev
->present
)
799 ret
= reg_w(gspca_dev
, 0xff, 0x01);
801 ret
= reg_w(gspca_dev
, 0x78, 0x40);
804 /* Include pac common sof detection functions */
805 #include "pac_common.h"
807 static void do_autogain(struct gspca_dev
*gspca_dev
)
809 struct sd
*sd
= (struct sd
*) gspca_dev
;
810 int avg_lum
= atomic_read(&sd
->avg_lum
);
811 int desired_lum
, deadzone
;
816 desired_lum
= 270 + sd
->brightness
* 4;
817 /* Hack hack, with the 7202 the first exposure step is
818 pretty large, so if we're about to make the first
819 exposure increase make the deadzone large to avoid
821 if (desired_lum
> avg_lum
&& sd
->gain
== GAIN_DEF
&&
822 sd
->exposure
> EXPOSURE_DEF
&&
828 if (sd
->autogain_ignore_frames
> 0)
829 sd
->autogain_ignore_frames
--;
830 else if (gspca_auto_gain_n_exposure(gspca_dev
, avg_lum
, desired_lum
,
831 deadzone
, GAIN_KNEE
, EXPOSURE_KNEE
))
832 sd
->autogain_ignore_frames
= PAC_AUTOGAIN_IGNORE_FRAMES
;
835 /* JPEG header, part 1 */
836 static const unsigned char pac_jpeg_header1
[] = {
837 0xff, 0xd8, /* SOI: Start of Image */
839 0xff, 0xc0, /* SOF0: Start of Frame (Baseline DCT) */
840 0x00, 0x11, /* length = 17 bytes (including this length field) */
841 0x08 /* Precision: 8 */
842 /* 2 bytes is placed here: number of image lines */
843 /* 2 bytes is placed here: samples per line */
846 /* JPEG header, continued */
847 static const unsigned char pac_jpeg_header2
[] = {
848 0x03, /* Number of image components: 3 */
849 0x01, 0x21, 0x00, /* ID=1, Subsampling 1x1, Quantization table: 0 */
850 0x02, 0x11, 0x01, /* ID=2, Subsampling 2x1, Quantization table: 1 */
851 0x03, 0x11, 0x01, /* ID=3, Subsampling 2x1, Quantization table: 1 */
853 0xff, 0xda, /* SOS: Start Of Scan */
854 0x00, 0x0c, /* length = 12 bytes (including this length field) */
855 0x03, /* number of components: 3 */
856 0x01, 0x00, /* selector 1, table 0x00 */
857 0x02, 0x11, /* selector 2, table 0x11 */
858 0x03, 0x11, /* selector 3, table 0x11 */
859 0x00, 0x3f, /* Spectral selection: 0 .. 63 */
860 0x00 /* Successive approximation: 0 */
863 static void pac_start_frame(struct gspca_dev
*gspca_dev
,
864 struct gspca_frame
*frame
,
865 __u16 lines
, __u16 samples_per_line
)
867 unsigned char tmpbuf
[4];
869 gspca_frame_add(gspca_dev
, FIRST_PACKET
,
870 pac_jpeg_header1
, sizeof(pac_jpeg_header1
));
872 tmpbuf
[0] = lines
>> 8;
873 tmpbuf
[1] = lines
& 0xff;
874 tmpbuf
[2] = samples_per_line
>> 8;
875 tmpbuf
[3] = samples_per_line
& 0xff;
877 gspca_frame_add(gspca_dev
, INTER_PACKET
,
878 tmpbuf
, sizeof(tmpbuf
));
879 gspca_frame_add(gspca_dev
, INTER_PACKET
,
880 pac_jpeg_header2
, sizeof(pac_jpeg_header2
));
883 /* this function is run at interrupt level */
884 static void sd_pkt_scan(struct gspca_dev
*gspca_dev
,
885 u8
*data
, /* isoc packet */
886 int len
) /* iso packet length */
888 struct sd
*sd
= (struct sd
*) gspca_dev
;
889 struct gspca_frame
*frame
;
892 sof
= pac_find_sof(&sd
->sof_read
, data
, len
);
894 int n
, lum_offset
, footer_length
;
896 frame
= gspca_get_i_frame(gspca_dev
);
898 gspca_dev
->last_packet_type
= DISCARD_PACKET
;
902 /* 6 bytes after the FF D9 EOF marker a number of lumination
903 bytes are send corresponding to different parts of the
904 image, the 14th and 15th byte after the EOF seem to
905 correspond to the center of the image */
906 lum_offset
= 61 + sizeof pac_sof_marker
;
909 /* Finish decoding current frame */
910 n
= (sof
- data
) - (footer_length
+ sizeof pac_sof_marker
);
912 frame
->data_end
+= n
;
915 gspca_frame_add(gspca_dev
, INTER_PACKET
,
917 if (gspca_dev
->last_packet_type
!= DISCARD_PACKET
&&
918 frame
->data_end
[-2] == 0xff &&
919 frame
->data_end
[-1] == 0xd9)
920 gspca_frame_add(gspca_dev
, LAST_PACKET
,
927 /* Get average lumination */
928 if (gspca_dev
->last_packet_type
== LAST_PACKET
&&
930 atomic_set(&sd
->avg_lum
, data
[-lum_offset
] +
931 data
[-lum_offset
+ 1]);
933 atomic_set(&sd
->avg_lum
, -1);
935 /* Start the new frame with the jpeg header */
936 /* The PAC7302 has the image rotated 90 degrees */
937 pac_start_frame(gspca_dev
, frame
,
938 gspca_dev
->width
, gspca_dev
->height
);
940 gspca_frame_add(gspca_dev
, INTER_PACKET
, data
, len
);
943 static int sd_setbrightness(struct gspca_dev
*gspca_dev
, __s32 val
)
945 struct sd
*sd
= (struct sd
*) gspca_dev
;
947 sd
->brightness
= val
;
948 if (gspca_dev
->streaming
)
949 setbrightcont(gspca_dev
);
953 static int sd_getbrightness(struct gspca_dev
*gspca_dev
, __s32
*val
)
955 struct sd
*sd
= (struct sd
*) gspca_dev
;
957 *val
= sd
->brightness
;
961 static int sd_setcontrast(struct gspca_dev
*gspca_dev
, __s32 val
)
963 struct sd
*sd
= (struct sd
*) gspca_dev
;
966 if (gspca_dev
->streaming
) {
967 setbrightcont(gspca_dev
);
972 static int sd_getcontrast(struct gspca_dev
*gspca_dev
, __s32
*val
)
974 struct sd
*sd
= (struct sd
*) gspca_dev
;
980 static int sd_setcolors(struct gspca_dev
*gspca_dev
, __s32 val
)
982 struct sd
*sd
= (struct sd
*) gspca_dev
;
985 if (gspca_dev
->streaming
)
986 setcolors(gspca_dev
);
990 static int sd_getcolors(struct gspca_dev
*gspca_dev
, __s32
*val
)
992 struct sd
*sd
= (struct sd
*) gspca_dev
;
998 static int sd_setwhitebalance(struct gspca_dev
*gspca_dev
, __s32 val
)
1000 struct sd
*sd
= (struct sd
*) gspca_dev
;
1003 sd
->white_balance
= val
;
1004 if (gspca_dev
->streaming
)
1005 ret
= setwhitebalance(gspca_dev
);
1011 static int sd_getwhitebalance(struct gspca_dev
*gspca_dev
, __s32
*val
)
1013 struct sd
*sd
= (struct sd
*) gspca_dev
;
1015 *val
= sd
->white_balance
;
1019 static int sd_setredbalance(struct gspca_dev
*gspca_dev
, __s32 val
)
1021 struct sd
*sd
= (struct sd
*) gspca_dev
;
1024 sd
->red_balance
= val
;
1025 if (gspca_dev
->streaming
)
1026 ret
= setredbalance(gspca_dev
);
1032 static int sd_getredbalance(struct gspca_dev
*gspca_dev
, __s32
*val
)
1034 struct sd
*sd
= (struct sd
*) gspca_dev
;
1036 *val
= sd
->red_balance
;
1040 static int sd_setbluebalance(struct gspca_dev
*gspca_dev
, __s32 val
)
1042 struct sd
*sd
= (struct sd
*) gspca_dev
;
1045 sd
->blue_balance
= val
;
1046 if (gspca_dev
->streaming
)
1047 ret
= setbluebalance(gspca_dev
);
1053 static int sd_getbluebalance(struct gspca_dev
*gspca_dev
, __s32
*val
)
1055 struct sd
*sd
= (struct sd
*) gspca_dev
;
1057 *val
= sd
->blue_balance
;
1061 static int sd_setgain(struct gspca_dev
*gspca_dev
, __s32 val
)
1063 struct sd
*sd
= (struct sd
*) gspca_dev
;
1066 if (gspca_dev
->streaming
)
1071 static int sd_getgain(struct gspca_dev
*gspca_dev
, __s32
*val
)
1073 struct sd
*sd
= (struct sd
*) gspca_dev
;
1079 static int sd_setexposure(struct gspca_dev
*gspca_dev
, __s32 val
)
1081 struct sd
*sd
= (struct sd
*) gspca_dev
;
1084 if (gspca_dev
->streaming
)
1085 setexposure(gspca_dev
);
1089 static int sd_getexposure(struct gspca_dev
*gspca_dev
, __s32
*val
)
1091 struct sd
*sd
= (struct sd
*) gspca_dev
;
1093 *val
= sd
->exposure
;
1097 static int sd_setautogain(struct gspca_dev
*gspca_dev
, __s32 val
)
1099 struct sd
*sd
= (struct sd
*) gspca_dev
;
1102 /* when switching to autogain set defaults to make sure
1103 we are on a valid point of the autogain gain /
1104 exposure knee graph, and give this change time to
1105 take effect before doing autogain. */
1107 sd
->exposure
= EXPOSURE_DEF
;
1108 sd
->gain
= GAIN_DEF
;
1109 if (gspca_dev
->streaming
) {
1110 sd
->autogain_ignore_frames
=
1111 PAC_AUTOGAIN_IGNORE_FRAMES
;
1112 setexposure(gspca_dev
);
1120 static int sd_getautogain(struct gspca_dev
*gspca_dev
, __s32
*val
)
1122 struct sd
*sd
= (struct sd
*) gspca_dev
;
1124 *val
= sd
->autogain
;
1128 static int sd_sethflip(struct gspca_dev
*gspca_dev
, __s32 val
)
1130 struct sd
*sd
= (struct sd
*) gspca_dev
;
1133 if (gspca_dev
->streaming
)
1134 sethvflip(gspca_dev
);
1138 static int sd_gethflip(struct gspca_dev
*gspca_dev
, __s32
*val
)
1140 struct sd
*sd
= (struct sd
*) gspca_dev
;
1146 static int sd_setvflip(struct gspca_dev
*gspca_dev
, __s32 val
)
1148 struct sd
*sd
= (struct sd
*) gspca_dev
;
1151 if (gspca_dev
->streaming
)
1152 sethvflip(gspca_dev
);
1156 static int sd_getvflip(struct gspca_dev
*gspca_dev
, __s32
*val
)
1158 struct sd
*sd
= (struct sd
*) gspca_dev
;
1164 #ifdef CONFIG_VIDEO_ADV_DEBUG
1165 static int sd_dbg_s_register(struct gspca_dev
*gspca_dev
,
1166 struct v4l2_dbg_register
*reg
)
1172 /* reg->reg: bit0..15: reserved for register index (wIndex is 16bit
1173 long on the USB bus)
1175 if (reg
->match
.type
== V4L2_CHIP_MATCH_HOST
&&
1176 reg
->match
.addr
== 0 &&
1177 (reg
->reg
< 0x000000ff) &&
1178 (reg
->val
<= 0x000000ff)
1180 /* Currently writing to page 0 is only supported. */
1181 /* reg_w() only supports 8bit index */
1182 index
= reg
->reg
& 0x000000ff;
1183 value
= reg
->val
& 0x000000ff;
1185 /* Note that there shall be no access to other page
1186 by any other function between the page swith and
1187 the actual register write */
1188 ret
= reg_w(gspca_dev
, 0xff, 0x00); /* page 0 */
1190 ret
= reg_w(gspca_dev
, index
, value
);
1193 ret
= reg_w(gspca_dev
, 0xdc, 0x01);
1198 static int sd_chip_ident(struct gspca_dev
*gspca_dev
,
1199 struct v4l2_dbg_chip_ident
*chip
)
1203 if (chip
->match
.type
== V4L2_CHIP_MATCH_HOST
&&
1204 chip
->match
.addr
== 0) {
1206 chip
->ident
= V4L2_IDENT_UNKNOWN
;
1213 /* sub-driver description for pac7302 */
1214 static struct sd_desc sd_desc
= {
1215 .name
= MODULE_NAME
,
1217 .nctrls
= ARRAY_SIZE(sd_ctrls
),
1218 .config
= sd_config
,
1223 .pkt_scan
= sd_pkt_scan
,
1224 .dq_callback
= do_autogain
,
1225 #ifdef CONFIG_VIDEO_ADV_DEBUG
1226 .set_register
= sd_dbg_s_register
,
1227 .get_chip_ident
= sd_chip_ident
,
1231 /* -- module initialisation -- */
1232 static __devinitdata
struct usb_device_id device_table
[] = {
1233 {USB_DEVICE(0x06f8, 0x3009)},
1234 {USB_DEVICE(0x093a, 0x2620)},
1235 {USB_DEVICE(0x093a, 0x2621)},
1236 {USB_DEVICE(0x093a, 0x2622), .driver_info
= FL_VFLIP
},
1237 {USB_DEVICE(0x093a, 0x2624), .driver_info
= FL_VFLIP
},
1238 {USB_DEVICE(0x093a, 0x2626)},
1239 {USB_DEVICE(0x093a, 0x2628)},
1240 {USB_DEVICE(0x093a, 0x2629)},
1241 {USB_DEVICE(0x093a, 0x262a)},
1242 {USB_DEVICE(0x093a, 0x262c)},
1245 MODULE_DEVICE_TABLE(usb
, device_table
);
1247 /* -- device connect -- */
1248 static int sd_probe(struct usb_interface
*intf
,
1249 const struct usb_device_id
*id
)
1251 return gspca_dev_probe(intf
, id
, &sd_desc
, sizeof(struct sd
),
1255 static struct usb_driver sd_driver
= {
1256 .name
= MODULE_NAME
,
1257 .id_table
= device_table
,
1259 .disconnect
= gspca_disconnect
,
1261 .suspend
= gspca_suspend
,
1262 .resume
= gspca_resume
,
1266 /* -- module insert / remove -- */
1267 static int __init
sd_mod_init(void)
1270 ret
= usb_register(&sd_driver
);
1273 PDEBUG(D_PROBE
, "registered");
1276 static void __exit
sd_mod_exit(void)
1278 usb_deregister(&sd_driver
);
1279 PDEBUG(D_PROBE
, "deregistered");
1282 module_init(sd_mod_init
);
1283 module_exit(sd_mod_exit
);