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.
54 #define MODULE_NAME "pac7302"
58 MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li");
59 MODULE_DESCRIPTION("Pixart PAC7302");
60 MODULE_LICENSE("GPL");
62 /* specific webcam descriptor for pac7302 */
64 struct gspca_dev gspca_dev
; /* !! must be the first item */
66 unsigned char brightness
;
67 unsigned char contrast
;
70 unsigned char exposure
;
71 unsigned char autogain
;
76 u8 autogain_ignore_frames
;
81 /* V4L2 controls supported by the driver */
82 static int sd_setbrightness(struct gspca_dev
*gspca_dev
, __s32 val
);
83 static int sd_getbrightness(struct gspca_dev
*gspca_dev
, __s32
*val
);
84 static int sd_setcontrast(struct gspca_dev
*gspca_dev
, __s32 val
);
85 static int sd_getcontrast(struct gspca_dev
*gspca_dev
, __s32
*val
);
86 static int sd_setcolors(struct gspca_dev
*gspca_dev
, __s32 val
);
87 static int sd_getcolors(struct gspca_dev
*gspca_dev
, __s32
*val
);
88 static int sd_setautogain(struct gspca_dev
*gspca_dev
, __s32 val
);
89 static int sd_getautogain(struct gspca_dev
*gspca_dev
, __s32
*val
);
90 static int sd_sethflip(struct gspca_dev
*gspca_dev
, __s32 val
);
91 static int sd_gethflip(struct gspca_dev
*gspca_dev
, __s32
*val
);
92 static int sd_setvflip(struct gspca_dev
*gspca_dev
, __s32 val
);
93 static int sd_getvflip(struct gspca_dev
*gspca_dev
, __s32
*val
);
94 static int sd_setgain(struct gspca_dev
*gspca_dev
, __s32 val
);
95 static int sd_getgain(struct gspca_dev
*gspca_dev
, __s32
*val
);
96 static int sd_setexposure(struct gspca_dev
*gspca_dev
, __s32 val
);
97 static int sd_getexposure(struct gspca_dev
*gspca_dev
, __s32
*val
);
99 static struct ctrl sd_ctrls
[] = {
100 /* This control is pac7302 only */
103 .id
= V4L2_CID_BRIGHTNESS
,
104 .type
= V4L2_CTRL_TYPE_INTEGER
,
105 .name
= "Brightness",
107 #define BRIGHTNESS_MAX 0x20
108 .maximum
= BRIGHTNESS_MAX
,
110 #define BRIGHTNESS_DEF 0x10
111 .default_value
= BRIGHTNESS_DEF
,
113 .set
= sd_setbrightness
,
114 .get
= sd_getbrightness
,
116 /* This control is for both the 7302 and the 7311 */
119 .id
= V4L2_CID_CONTRAST
,
120 .type
= V4L2_CTRL_TYPE_INTEGER
,
123 #define CONTRAST_MAX 255
124 .maximum
= CONTRAST_MAX
,
126 #define CONTRAST_DEF 127
127 .default_value
= CONTRAST_DEF
,
129 .set
= sd_setcontrast
,
130 .get
= sd_getcontrast
,
132 /* This control is pac7302 only */
135 .id
= V4L2_CID_SATURATION
,
136 .type
= V4L2_CTRL_TYPE_INTEGER
,
137 .name
= "Saturation",
139 #define COLOR_MAX 255
140 .maximum
= COLOR_MAX
,
142 #define COLOR_DEF 127
143 .default_value
= COLOR_DEF
,
148 /* All controls below are for both the 7302 and the 7311 */
152 .type
= V4L2_CTRL_TYPE_INTEGER
,
159 #define GAIN_KNEE 255 /* Gain seems to cause little noise on the pac73xx */
160 .default_value
= GAIN_DEF
,
167 .id
= V4L2_CID_EXPOSURE
,
168 .type
= V4L2_CTRL_TYPE_INTEGER
,
171 #define EXPOSURE_MAX 255
172 .maximum
= EXPOSURE_MAX
,
174 #define EXPOSURE_DEF 16 /* 32 ms / 30 fps */
175 #define EXPOSURE_KNEE 50 /* 100 ms / 10 fps */
176 .default_value
= EXPOSURE_DEF
,
178 .set
= sd_setexposure
,
179 .get
= sd_getexposure
,
183 .id
= V4L2_CID_AUTOGAIN
,
184 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
189 #define AUTOGAIN_DEF 1
190 .default_value
= AUTOGAIN_DEF
,
192 .set
= sd_setautogain
,
193 .get
= sd_getautogain
,
197 .id
= V4L2_CID_HFLIP
,
198 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
204 .default_value
= HFLIP_DEF
,
211 .id
= V4L2_CID_VFLIP
,
212 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
218 .default_value
= VFLIP_DEF
,
225 static const struct v4l2_pix_format vga_mode
[] = {
226 {640, 480, V4L2_PIX_FMT_PJPG
, V4L2_FIELD_NONE
,
228 .sizeimage
= 640 * 480 * 3 / 8 + 590,
229 .colorspace
= V4L2_COLORSPACE_JPEG
,
233 #define LOAD_PAGE3 255
234 #define LOAD_PAGE4 254
235 #define END_OF_SEQUENCE 0
238 static const __u8 init_7302
[] = {
240 0xff, 0x01, /* page 1 */
241 0x78, 0x00, /* deactivate */
243 0x78, 0x40, /* led off */
245 static const __u8 start_7302
[] = {
246 /* index, len, [value]* */
247 0xff, 1, 0x00, /* page 0 */
248 0x00, 12, 0x01, 0x40, 0x40, 0x40, 0x01, 0xe0, 0x02, 0x80,
249 0x00, 0x00, 0x00, 0x00,
250 0x0d, 24, 0x03, 0x01, 0x00, 0xb5, 0x07, 0xcb, 0x00, 0x00,
251 0x07, 0xc8, 0x00, 0xea, 0x07, 0xcf, 0x07, 0xf7,
252 0x07, 0x7e, 0x01, 0x0b, 0x00, 0x00, 0x00, 0x11,
256 0x3a, 3, 0x14, 0xff, 0x5a,
257 0x43, 11, 0x00, 0x0a, 0x18, 0x11, 0x01, 0x2c, 0x88, 0x11,
260 0x62, 4, 0x10, 0x1e, 0x1e, 0x18,
262 0x6e, 3, 0x08, 0x06, 0x00,
263 0x72, 3, 0x00, 0xff, 0x00,
264 0x7d, 23, 0x01, 0x01, 0x58, 0x46, 0x50, 0x3c, 0x50, 0x3c,
265 0x54, 0x46, 0x54, 0x56, 0x52, 0x50, 0x52, 0x50,
266 0x56, 0x64, 0xa4, 0x00, 0xda, 0x00, 0x00,
267 0xa2, 10, 0x22, 0x2c, 0x3c, 0x54, 0x69, 0x7c, 0x9c, 0xb9,
272 0xc4, 4, 0xae, 0x01, 0x04, 0x01,
274 0xd1, 11, 0x01, 0x30, 0x49, 0x5e, 0x6f, 0x7f, 0x8e, 0xa9,
277 0xff, 1, 0x01, /* page 1 */
278 0x12, 3, 0x02, 0x00, 0x01,
280 0x76, 5, 0x01, 0x20, 0x40, 0x00, 0xf2,
282 0x7f, 10, 0x4b, 0x0f, 0x01, 0x2c, 0x02, 0x58, 0x03, 0x20,
284 0x96, 5, 0x01, 0x10, 0x04, 0x01, 0x04,
285 0xc8, 14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
286 0x07, 0x00, 0x01, 0x07, 0x04, 0x01,
289 0xde, 7, 0x00, 0x01, 0x04, 0x04, 0x00, 0x00, 0x00,
290 0xe6, 4, 0x00, 0x00, 0x00, 0x01,
292 0xff, 1, 0x02, /* page 2 */
294 0xff, 1, 0x03, /* page 3 */
295 0, LOAD_PAGE3
, /* load the page 3 */
297 0xff, 1, 0x02, /* page 2 */
299 0x22, 4, 0x1f, 0xa4, 0xf0, 0x96,
301 0x2a, 5, 0xc8, 0x00, 0x18, 0x12, 0x22,
302 0x64, 8, 0x00, 0x00, 0xf0, 0x01, 0x14, 0x44, 0x44, 0x44,
304 0xff, 1, 0x01, /* page 1 */
306 0, END_OF_SEQUENCE
/* end of sequence */
310 /* page 3 - the value SKIP says skip the index - see reg_w_page() */
311 static const __u8 page3_7302
[] = {
312 0x90, 0x40, 0x03, 0x50, 0xc2, 0x01, 0x14, 0x16,
313 0x14, 0x12, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00,
314 0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
315 0x00, 0x00, 0x00, 0x47, 0x01, 0xb3, 0x01, 0x00,
316 0x00, 0x08, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x21,
317 0x00, 0x00, 0x00, 0x54, 0xf4, 0x02, 0x52, 0x54,
318 0xa4, 0xb8, 0xe0, 0x2a, 0xf6, 0x00, 0x00, 0x00,
319 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
320 0x00, 0xfc, 0x00, 0xf2, 0x1f, 0x04, 0x00, 0x00,
321 0x00, 0x00, 0x00, 0xc0, 0xc0, 0x10, 0x00, 0x00,
322 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
323 0x00, 0x40, 0xff, 0x03, 0x19, 0x00, 0x00, 0x00,
324 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
325 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc8, 0xc8,
326 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
327 0x08, 0x10, 0x24, 0x40, 0x00, 0x00, 0x00, 0x00,
328 0x01, 0x00, 0x02, 0x47, 0x00, 0x00, 0x00, 0x00,
329 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
330 0x00, 0x02, 0xfa, 0x00, 0x64, 0x5a, 0x28, 0x00,
334 static void reg_w_buf(struct gspca_dev
*gspca_dev
,
336 const char *buffer
, int len
)
340 memcpy(gspca_dev
->usb_buf
, buffer
, len
);
341 ret
= usb_control_msg(gspca_dev
->dev
,
342 usb_sndctrlpipe(gspca_dev
->dev
, 0),
344 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
346 index
, gspca_dev
->usb_buf
, len
,
349 PDEBUG(D_ERR
, "reg_w_buf(): "
350 "Failed to write registers to index 0x%x, error %i",
355 static void reg_w(struct gspca_dev
*gspca_dev
,
361 gspca_dev
->usb_buf
[0] = value
;
362 ret
= usb_control_msg(gspca_dev
->dev
,
363 usb_sndctrlpipe(gspca_dev
->dev
, 0),
365 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
366 0, index
, gspca_dev
->usb_buf
, 1,
369 PDEBUG(D_ERR
, "reg_w(): "
370 "Failed to write register to index 0x%x, value 0x%x, error %i",
374 static void reg_w_seq(struct gspca_dev
*gspca_dev
,
375 const __u8
*seq
, int len
)
378 reg_w(gspca_dev
, seq
[0], seq
[1]);
383 /* load the beginning of a page */
384 static void reg_w_page(struct gspca_dev
*gspca_dev
,
385 const __u8
*page
, int len
)
390 for (index
= 0; index
< len
; index
++) {
391 if (page
[index
] == SKIP
) /* skip this index */
393 gspca_dev
->usb_buf
[0] = page
[index
];
394 ret
= usb_control_msg(gspca_dev
->dev
,
395 usb_sndctrlpipe(gspca_dev
->dev
, 0),
397 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
398 0, index
, gspca_dev
->usb_buf
, 1,
401 PDEBUG(D_ERR
, "reg_w_page(): "
402 "Failed to write register to index 0x%x, "
403 "value 0x%x, error %i",
404 index
, page
[index
], ret
);
408 /* output a variable sequence */
409 static void reg_w_var(struct gspca_dev
*gspca_dev
,
411 const __u8
*page3
, unsigned int page3_len
,
412 const __u8
*page4
, unsigned int page4_len
)
420 case END_OF_SEQUENCE
:
423 reg_w_page(gspca_dev
, page4
, page4_len
);
426 reg_w_page(gspca_dev
, page3
, page3_len
);
429 if (len
> USB_BUF_SZ
) {
430 PDEBUG(D_ERR
|D_STREAM
,
431 "Incorrect variable sequence");
436 reg_w_buf(gspca_dev
, index
, seq
, len
);
440 reg_w_buf(gspca_dev
, index
, seq
, 8);
450 /* this function is called at probe time for pac7302 */
451 static int sd_config(struct gspca_dev
*gspca_dev
,
452 const struct usb_device_id
*id
)
454 struct sd
*sd
= (struct sd
*) gspca_dev
;
457 cam
= &gspca_dev
->cam
;
459 PDEBUG(D_CONF
, "Find Sensor PAC7302");
460 cam
->cam_mode
= vga_mode
; /* only 640x480 */
461 cam
->nmodes
= ARRAY_SIZE(vga_mode
);
463 sd
->brightness
= BRIGHTNESS_DEF
;
464 sd
->contrast
= CONTRAST_DEF
;
465 sd
->colors
= COLOR_DEF
;
467 sd
->exposure
= EXPOSURE_DEF
;
468 sd
->autogain
= AUTOGAIN_DEF
;
469 sd
->hflip
= HFLIP_DEF
;
470 sd
->vflip
= VFLIP_DEF
;
474 /* This function is used by pac7302 only */
475 static void setbrightcont(struct gspca_dev
*gspca_dev
)
477 struct sd
*sd
= (struct sd
*) gspca_dev
;
479 static const __u8 max
[10] =
480 {0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb,
482 static const __u8 delta
[10] =
483 {0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17,
486 reg_w(gspca_dev
, 0xff, 0x00); /* page 0 */
487 for (i
= 0; i
< 10; i
++) {
489 v
+= (sd
->brightness
- BRIGHTNESS_MAX
)
490 * 150 / BRIGHTNESS_MAX
; /* 200 ? */
491 v
-= delta
[i
] * sd
->contrast
/ CONTRAST_MAX
;
496 reg_w(gspca_dev
, 0xa2 + i
, v
);
498 reg_w(gspca_dev
, 0xdc, 0x01);
501 /* This function is used by pac7302 only */
502 static void setcolors(struct gspca_dev
*gspca_dev
)
504 struct sd
*sd
= (struct sd
*) gspca_dev
;
506 static const int a
[9] =
507 {217, -212, 0, -101, 170, -67, -38, -315, 355};
508 static const int b
[9] =
509 {19, 106, 0, 19, 106, 1, 19, 106, 1};
511 reg_w(gspca_dev
, 0xff, 0x03); /* page 3 */
512 reg_w(gspca_dev
, 0x11, 0x01);
513 reg_w(gspca_dev
, 0xff, 0x00); /* page 0 */
514 for (i
= 0; i
< 9; i
++) {
515 v
= a
[i
] * sd
->colors
/ COLOR_MAX
+ b
[i
];
516 reg_w(gspca_dev
, 0x0f + 2 * i
, (v
>> 8) & 0x07);
517 reg_w(gspca_dev
, 0x0f + 2 * i
+ 1, v
);
519 reg_w(gspca_dev
, 0xdc, 0x01);
520 PDEBUG(D_CONF
|D_STREAM
, "color: %i", sd
->colors
);
523 static void setgain(struct gspca_dev
*gspca_dev
)
525 struct sd
*sd
= (struct sd
*) gspca_dev
;
527 reg_w(gspca_dev
, 0xff, 0x03); /* page 3 */
528 reg_w(gspca_dev
, 0x10, sd
->gain
>> 3);
530 /* load registers to sensor (Bit 0, auto clear) */
531 reg_w(gspca_dev
, 0x11, 0x01);
534 static void setexposure(struct gspca_dev
*gspca_dev
)
536 struct sd
*sd
= (struct sd
*) gspca_dev
;
539 /* register 2 of frame 3/4 contains the clock divider configuring the
540 no fps according to the formula: 60 / reg. sd->exposure is the
541 desired exposure time in ms. */
542 reg
= 120 * sd
->exposure
/ 1000;
548 /* On the pac7302 reg2 MUST be a multiple of 3, so round it to
549 the nearest multiple of 3, except when between 6 and 12? */
550 if (reg
< 6 || reg
> 12)
551 reg
= ((reg
+ 1) / 3) * 3;
552 reg_w(gspca_dev
, 0xff, 0x03); /* page 3 */
553 reg_w(gspca_dev
, 0x02, reg
);
555 /* load registers to sensor (Bit 0, auto clear) */
556 reg_w(gspca_dev
, 0x11, 0x01);
559 static void sethvflip(struct gspca_dev
*gspca_dev
)
561 struct sd
*sd
= (struct sd
*) gspca_dev
;
564 reg_w(gspca_dev
, 0xff, 0x03); /* page 3 */
565 data
= (sd
->hflip
? 0x08 : 0x00) | (sd
->vflip
? 0x04 : 0x00);
566 reg_w(gspca_dev
, 0x21, data
);
567 /* load registers to sensor (Bit 0, auto clear) */
568 reg_w(gspca_dev
, 0x11, 0x01);
571 /* this function is called at probe and resume time for pac7302 */
572 static int sd_init(struct gspca_dev
*gspca_dev
)
574 reg_w_seq(gspca_dev
, init_7302
, sizeof(init_7302
)/2);
579 static int sd_start(struct gspca_dev
*gspca_dev
)
581 struct sd
*sd
= (struct sd
*) gspca_dev
;
585 reg_w_var(gspca_dev
, start_7302
,
586 page3_7302
, sizeof(page3_7302
),
588 setbrightcont(gspca_dev
);
589 setcolors(gspca_dev
);
591 setexposure(gspca_dev
);
592 sethvflip(gspca_dev
);
594 /* only resolution 640x480 is supported for pac7302 */
597 sd
->autogain_ignore_frames
= 0;
598 atomic_set(&sd
->avg_lum
, -1);
601 reg_w(gspca_dev
, 0xff, 0x01);
602 reg_w(gspca_dev
, 0x78, 0x01);
607 static void sd_stopN(struct gspca_dev
*gspca_dev
)
610 reg_w(gspca_dev
, 0xff, 0x01);
611 reg_w(gspca_dev
, 0x78, 0x00);
614 /* called on streamoff with alt 0 and on disconnect for pac7302 */
615 static void sd_stop0(struct gspca_dev
*gspca_dev
)
617 if (!gspca_dev
->present
)
619 reg_w(gspca_dev
, 0xff, 0x01);
620 reg_w(gspca_dev
, 0x78, 0x40);
623 /* Include pac common sof detection functions */
624 #include "pac_common.h"
626 static void do_autogain(struct gspca_dev
*gspca_dev
)
628 struct sd
*sd
= (struct sd
*) gspca_dev
;
629 int avg_lum
= atomic_read(&sd
->avg_lum
);
630 int desired_lum
, deadzone
;
635 desired_lum
= 270 + sd
->brightness
* 4;
636 /* Hack hack, with the 7202 the first exposure step is
637 pretty large, so if we're about to make the first
638 exposure increase make the deadzone large to avoid
640 if (desired_lum
> avg_lum
&& sd
->gain
== GAIN_DEF
&&
641 sd
->exposure
> EXPOSURE_DEF
&&
647 if (sd
->autogain_ignore_frames
> 0)
648 sd
->autogain_ignore_frames
--;
649 else if (gspca_auto_gain_n_exposure(gspca_dev
, avg_lum
, desired_lum
,
650 deadzone
, GAIN_KNEE
, EXPOSURE_KNEE
))
651 sd
->autogain_ignore_frames
= PAC_AUTOGAIN_IGNORE_FRAMES
;
654 /* JPEG header, part 1 */
655 static const unsigned char pac_jpeg_header1
[] = {
656 0xff, 0xd8, /* SOI: Start of Image */
658 0xff, 0xc0, /* SOF0: Start of Frame (Baseline DCT) */
659 0x00, 0x11, /* length = 17 bytes (including this length field) */
660 0x08 /* Precision: 8 */
661 /* 2 bytes is placed here: number of image lines */
662 /* 2 bytes is placed here: samples per line */
665 /* JPEG header, continued */
666 static const unsigned char pac_jpeg_header2
[] = {
667 0x03, /* Number of image components: 3 */
668 0x01, 0x21, 0x00, /* ID=1, Subsampling 1x1, Quantization table: 0 */
669 0x02, 0x11, 0x01, /* ID=2, Subsampling 2x1, Quantization table: 1 */
670 0x03, 0x11, 0x01, /* ID=3, Subsampling 2x1, Quantization table: 1 */
672 0xff, 0xda, /* SOS: Start Of Scan */
673 0x00, 0x0c, /* length = 12 bytes (including this length field) */
674 0x03, /* number of components: 3 */
675 0x01, 0x00, /* selector 1, table 0x00 */
676 0x02, 0x11, /* selector 2, table 0x11 */
677 0x03, 0x11, /* selector 3, table 0x11 */
678 0x00, 0x3f, /* Spectral selection: 0 .. 63 */
679 0x00 /* Successive approximation: 0 */
682 static void pac_start_frame(struct gspca_dev
*gspca_dev
,
683 struct gspca_frame
*frame
,
684 __u16 lines
, __u16 samples_per_line
)
686 unsigned char tmpbuf
[4];
688 gspca_frame_add(gspca_dev
, FIRST_PACKET
, frame
,
689 pac_jpeg_header1
, sizeof(pac_jpeg_header1
));
691 tmpbuf
[0] = lines
>> 8;
692 tmpbuf
[1] = lines
& 0xff;
693 tmpbuf
[2] = samples_per_line
>> 8;
694 tmpbuf
[3] = samples_per_line
& 0xff;
696 gspca_frame_add(gspca_dev
, INTER_PACKET
, frame
,
697 tmpbuf
, sizeof(tmpbuf
));
698 gspca_frame_add(gspca_dev
, INTER_PACKET
, frame
,
699 pac_jpeg_header2
, sizeof(pac_jpeg_header2
));
702 /* this function is run at interrupt level */
703 static void sd_pkt_scan(struct gspca_dev
*gspca_dev
,
704 struct gspca_frame
*frame
, /* target */
705 __u8
*data
, /* isoc packet */
706 int len
) /* iso packet length */
708 struct sd
*sd
= (struct sd
*) gspca_dev
;
711 sof
= pac_find_sof(&sd
->sof_read
, data
, len
);
713 int n
, lum_offset
, footer_length
;
715 /* 6 bytes after the FF D9 EOF marker a number of lumination
716 bytes are send corresponding to different parts of the
717 image, the 14th and 15th byte after the EOF seem to
718 correspond to the center of the image */
719 lum_offset
= 61 + sizeof pac_sof_marker
;
722 /* Finish decoding current frame */
723 n
= (sof
- data
) - (footer_length
+ sizeof pac_sof_marker
);
725 frame
->data_end
+= n
;
728 frame
= gspca_frame_add(gspca_dev
, INTER_PACKET
, frame
,
730 if (gspca_dev
->last_packet_type
!= DISCARD_PACKET
&&
731 frame
->data_end
[-2] == 0xff &&
732 frame
->data_end
[-1] == 0xd9)
733 frame
= gspca_frame_add(gspca_dev
, LAST_PACKET
, frame
,
740 /* Get average lumination */
741 if (gspca_dev
->last_packet_type
== LAST_PACKET
&&
743 atomic_set(&sd
->avg_lum
, data
[-lum_offset
] +
744 data
[-lum_offset
+ 1]);
746 atomic_set(&sd
->avg_lum
, -1);
748 /* Start the new frame with the jpeg header */
749 /* The PAC7302 has the image rotated 90 degrees */
750 pac_start_frame(gspca_dev
, frame
,
751 gspca_dev
->width
, gspca_dev
->height
);
753 gspca_frame_add(gspca_dev
, INTER_PACKET
, frame
, data
, len
);
756 static int sd_setbrightness(struct gspca_dev
*gspca_dev
, __s32 val
)
758 struct sd
*sd
= (struct sd
*) gspca_dev
;
760 sd
->brightness
= val
;
761 if (gspca_dev
->streaming
)
762 setbrightcont(gspca_dev
);
766 static int sd_getbrightness(struct gspca_dev
*gspca_dev
, __s32
*val
)
768 struct sd
*sd
= (struct sd
*) gspca_dev
;
770 *val
= sd
->brightness
;
774 static int sd_setcontrast(struct gspca_dev
*gspca_dev
, __s32 val
)
776 struct sd
*sd
= (struct sd
*) gspca_dev
;
779 if (gspca_dev
->streaming
) {
780 setbrightcont(gspca_dev
);
785 static int sd_getcontrast(struct gspca_dev
*gspca_dev
, __s32
*val
)
787 struct sd
*sd
= (struct sd
*) gspca_dev
;
793 static int sd_setcolors(struct gspca_dev
*gspca_dev
, __s32 val
)
795 struct sd
*sd
= (struct sd
*) gspca_dev
;
798 if (gspca_dev
->streaming
)
799 setcolors(gspca_dev
);
803 static int sd_getcolors(struct gspca_dev
*gspca_dev
, __s32
*val
)
805 struct sd
*sd
= (struct sd
*) gspca_dev
;
811 static int sd_setgain(struct gspca_dev
*gspca_dev
, __s32 val
)
813 struct sd
*sd
= (struct sd
*) gspca_dev
;
816 if (gspca_dev
->streaming
)
821 static int sd_getgain(struct gspca_dev
*gspca_dev
, __s32
*val
)
823 struct sd
*sd
= (struct sd
*) gspca_dev
;
829 static int sd_setexposure(struct gspca_dev
*gspca_dev
, __s32 val
)
831 struct sd
*sd
= (struct sd
*) gspca_dev
;
834 if (gspca_dev
->streaming
)
835 setexposure(gspca_dev
);
839 static int sd_getexposure(struct gspca_dev
*gspca_dev
, __s32
*val
)
841 struct sd
*sd
= (struct sd
*) gspca_dev
;
847 static int sd_setautogain(struct gspca_dev
*gspca_dev
, __s32 val
)
849 struct sd
*sd
= (struct sd
*) gspca_dev
;
852 /* when switching to autogain set defaults to make sure
853 we are on a valid point of the autogain gain /
854 exposure knee graph, and give this change time to
855 take effect before doing autogain. */
857 sd
->exposure
= EXPOSURE_DEF
;
859 if (gspca_dev
->streaming
) {
860 sd
->autogain_ignore_frames
=
861 PAC_AUTOGAIN_IGNORE_FRAMES
;
862 setexposure(gspca_dev
);
870 static int sd_getautogain(struct gspca_dev
*gspca_dev
, __s32
*val
)
872 struct sd
*sd
= (struct sd
*) gspca_dev
;
878 static int sd_sethflip(struct gspca_dev
*gspca_dev
, __s32 val
)
880 struct sd
*sd
= (struct sd
*) gspca_dev
;
883 if (gspca_dev
->streaming
)
884 sethvflip(gspca_dev
);
888 static int sd_gethflip(struct gspca_dev
*gspca_dev
, __s32
*val
)
890 struct sd
*sd
= (struct sd
*) gspca_dev
;
896 static int sd_setvflip(struct gspca_dev
*gspca_dev
, __s32 val
)
898 struct sd
*sd
= (struct sd
*) gspca_dev
;
901 if (gspca_dev
->streaming
)
902 sethvflip(gspca_dev
);
906 static int sd_getvflip(struct gspca_dev
*gspca_dev
, __s32
*val
)
908 struct sd
*sd
= (struct sd
*) gspca_dev
;
914 /* sub-driver description for pac7302 */
915 static struct sd_desc sd_desc
= {
918 .nctrls
= ARRAY_SIZE(sd_ctrls
),
924 .pkt_scan
= sd_pkt_scan
,
925 .dq_callback
= do_autogain
,
928 /* -- module initialisation -- */
929 static __devinitdata
struct usb_device_id device_table
[] = {
930 {USB_DEVICE(0x06f8, 0x3009)},
931 {USB_DEVICE(0x093a, 0x2620)},
932 {USB_DEVICE(0x093a, 0x2621)},
933 {USB_DEVICE(0x093a, 0x2622)},
934 {USB_DEVICE(0x093a, 0x2624)},
935 {USB_DEVICE(0x093a, 0x2626)},
936 {USB_DEVICE(0x093a, 0x2628)},
937 {USB_DEVICE(0x093a, 0x2629)},
938 {USB_DEVICE(0x093a, 0x262a)},
939 {USB_DEVICE(0x093a, 0x262c)},
942 MODULE_DEVICE_TABLE(usb
, device_table
);
944 /* -- device connect -- */
945 static int sd_probe(struct usb_interface
*intf
,
946 const struct usb_device_id
*id
)
948 return gspca_dev_probe(intf
, id
, &sd_desc
, sizeof(struct sd
),
952 static struct usb_driver sd_driver
= {
954 .id_table
= device_table
,
956 .disconnect
= gspca_disconnect
,
958 .suspend
= gspca_suspend
,
959 .resume
= gspca_resume
,
963 /* -- module insert / remove -- */
964 static int __init
sd_mod_init(void)
967 ret
= usb_register(&sd_driver
);
970 PDEBUG(D_PROBE
, "registered");
973 static void __exit
sd_mod_exit(void)
975 usb_deregister(&sd_driver
);
976 PDEBUG(D_PROBE
, "deregistered");
979 module_init(sd_mod_init
);
980 module_exit(sd_mod_exit
);