blob: 60d1a31f5307acee33fa5b51fde4a9892208f778 [file] [log] [blame]
Marton Nemeth1408b842009-11-02 08:13:21 -03001/*
2 * Pixart PAC7302 library
3 * Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li
4 *
5 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
6 *
7 * Separated from Pixart PAC7311 library by Márton Németh <nm127@freemail.hu>
8 *
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
12 * any later version.
13 *
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.
18 *
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
22 */
23
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
28 matching IC.
29
30 Register page 1:
31
32 Address Description
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
39
40 Register page 3/4:
41
42 Address Description
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.
52*/
53
54#define MODULE_NAME "pac7302"
55
56#include "gspca.h"
57
58MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li");
59MODULE_DESCRIPTION("Pixart PAC7302");
60MODULE_LICENSE("GPL");
61
62/* specific webcam descriptor for pac7302 */
63struct sd {
64 struct gspca_dev gspca_dev; /* !! must be the first item */
65
66 unsigned char brightness;
67 unsigned char contrast;
68 unsigned char colors;
69 unsigned char gain;
70 unsigned char exposure;
71 unsigned char autogain;
72 __u8 hflip;
73 __u8 vflip;
74
75 u8 sof_read;
76 u8 autogain_ignore_frames;
77
78 atomic_t avg_lum;
79};
80
81/* V4L2 controls supported by the driver */
82static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
83static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
84static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
85static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
86static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
87static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
88static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
89static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
90static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
91static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val);
92static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
93static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
94static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
95static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
96static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
97static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
98
99static struct ctrl sd_ctrls[] = {
100/* This control is pac7302 only */
101 {
102 {
103 .id = V4L2_CID_BRIGHTNESS,
104 .type = V4L2_CTRL_TYPE_INTEGER,
105 .name = "Brightness",
106 .minimum = 0,
107#define BRIGHTNESS_MAX 0x20
108 .maximum = BRIGHTNESS_MAX,
109 .step = 1,
110#define BRIGHTNESS_DEF 0x10
111 .default_value = BRIGHTNESS_DEF,
112 },
113 .set = sd_setbrightness,
114 .get = sd_getbrightness,
115 },
116/* This control is for both the 7302 and the 7311 */
117 {
118 {
119 .id = V4L2_CID_CONTRAST,
120 .type = V4L2_CTRL_TYPE_INTEGER,
121 .name = "Contrast",
122 .minimum = 0,
123#define CONTRAST_MAX 255
124 .maximum = CONTRAST_MAX,
125 .step = 1,
126#define CONTRAST_DEF 127
127 .default_value = CONTRAST_DEF,
128 },
129 .set = sd_setcontrast,
130 .get = sd_getcontrast,
131 },
132/* This control is pac7302 only */
133 {
134 {
135 .id = V4L2_CID_SATURATION,
136 .type = V4L2_CTRL_TYPE_INTEGER,
137 .name = "Saturation",
138 .minimum = 0,
139#define COLOR_MAX 255
140 .maximum = COLOR_MAX,
141 .step = 1,
142#define COLOR_DEF 127
143 .default_value = COLOR_DEF,
144 },
145 .set = sd_setcolors,
146 .get = sd_getcolors,
147 },
148/* All controls below are for both the 7302 and the 7311 */
149 {
150 {
151 .id = V4L2_CID_GAIN,
152 .type = V4L2_CTRL_TYPE_INTEGER,
153 .name = "Gain",
154 .minimum = 0,
155#define GAIN_MAX 255
156 .maximum = GAIN_MAX,
157 .step = 1,
158#define GAIN_DEF 127
159#define GAIN_KNEE 255 /* Gain seems to cause little noise on the pac73xx */
160 .default_value = GAIN_DEF,
161 },
162 .set = sd_setgain,
163 .get = sd_getgain,
164 },
165 {
166 {
167 .id = V4L2_CID_EXPOSURE,
168 .type = V4L2_CTRL_TYPE_INTEGER,
169 .name = "Exposure",
170 .minimum = 0,
171#define EXPOSURE_MAX 255
172 .maximum = EXPOSURE_MAX,
173 .step = 1,
174#define EXPOSURE_DEF 16 /* 32 ms / 30 fps */
175#define EXPOSURE_KNEE 50 /* 100 ms / 10 fps */
176 .default_value = EXPOSURE_DEF,
177 },
178 .set = sd_setexposure,
179 .get = sd_getexposure,
180 },
181 {
182 {
183 .id = V4L2_CID_AUTOGAIN,
184 .type = V4L2_CTRL_TYPE_BOOLEAN,
185 .name = "Auto Gain",
186 .minimum = 0,
187 .maximum = 1,
188 .step = 1,
189#define AUTOGAIN_DEF 1
190 .default_value = AUTOGAIN_DEF,
191 },
192 .set = sd_setautogain,
193 .get = sd_getautogain,
194 },
195 {
196 {
197 .id = V4L2_CID_HFLIP,
198 .type = V4L2_CTRL_TYPE_BOOLEAN,
199 .name = "Mirror",
200 .minimum = 0,
201 .maximum = 1,
202 .step = 1,
203#define HFLIP_DEF 0
204 .default_value = HFLIP_DEF,
205 },
206 .set = sd_sethflip,
207 .get = sd_gethflip,
208 },
209 {
210 {
211 .id = V4L2_CID_VFLIP,
212 .type = V4L2_CTRL_TYPE_BOOLEAN,
213 .name = "Vflip",
214 .minimum = 0,
215 .maximum = 1,
216 .step = 1,
217#define VFLIP_DEF 0
218 .default_value = VFLIP_DEF,
219 },
220 .set = sd_setvflip,
221 .get = sd_getvflip,
222 },
223};
224
225static const struct v4l2_pix_format vga_mode[] = {
226 {640, 480, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
227 .bytesperline = 640,
228 .sizeimage = 640 * 480 * 3 / 8 + 590,
229 .colorspace = V4L2_COLORSPACE_JPEG,
230 .priv = 0},
231};
232
233#define LOAD_PAGE3 255
234#define LOAD_PAGE4 254
235#define END_OF_SEQUENCE 0
236
237/* pac 7302 */
238static const __u8 init_7302[] = {
239/* index,value */
240 0xff, 0x01, /* page 1 */
241 0x78, 0x00, /* deactivate */
242 0xff, 0x01,
243 0x78, 0x40, /* led off */
244};
245static 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,
253 0x26, 2, 0xaa, 0xaa,
254 0x2e, 1, 0x31,
255 0x38, 1, 0x01,
256 0x3a, 3, 0x14, 0xff, 0x5a,
257 0x43, 11, 0x00, 0x0a, 0x18, 0x11, 0x01, 0x2c, 0x88, 0x11,
258 0x00, 0x54, 0x11,
259 0x55, 1, 0x00,
260 0x62, 4, 0x10, 0x1e, 0x1e, 0x18,
261 0x6b, 1, 0x00,
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,
268 0xd2, 0xeb,
269 0xaf, 1, 0x02,
270 0xb5, 2, 0x08, 0x08,
271 0xb8, 2, 0x08, 0x88,
272 0xc4, 4, 0xae, 0x01, 0x04, 0x01,
273 0xcc, 1, 0x00,
274 0xd1, 11, 0x01, 0x30, 0x49, 0x5e, 0x6f, 0x7f, 0x8e, 0xa9,
275 0xc1, 0xd7, 0xec,
276 0xdc, 1, 0x01,
277 0xff, 1, 0x01, /* page 1 */
278 0x12, 3, 0x02, 0x00, 0x01,
279 0x3e, 2, 0x00, 0x00,
280 0x76, 5, 0x01, 0x20, 0x40, 0x00, 0xf2,
281 0x7c, 1, 0x00,
282 0x7f, 10, 0x4b, 0x0f, 0x01, 0x2c, 0x02, 0x58, 0x03, 0x20,
283 0x02, 0x00,
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,
287 0xd8, 1, 0x01,
288 0xdb, 2, 0x00, 0x01,
289 0xde, 7, 0x00, 0x01, 0x04, 0x04, 0x00, 0x00, 0x00,
290 0xe6, 4, 0x00, 0x00, 0x00, 0x01,
291 0xeb, 1, 0x00,
292 0xff, 1, 0x02, /* page 2 */
293 0x22, 1, 0x00,
294 0xff, 1, 0x03, /* page 3 */
295 0, LOAD_PAGE3, /* load the page 3 */
296 0x11, 1, 0x01,
297 0xff, 1, 0x02, /* page 2 */
298 0x13, 1, 0x00,
299 0x22, 4, 0x1f, 0xa4, 0xf0, 0x96,
300 0x27, 2, 0x14, 0x0c,
301 0x2a, 5, 0xc8, 0x00, 0x18, 0x12, 0x22,
302 0x64, 8, 0x00, 0x00, 0xf0, 0x01, 0x14, 0x44, 0x44, 0x44,
303 0x6e, 1, 0x08,
304 0xff, 1, 0x01, /* page 1 */
305 0x78, 1, 0x00,
306 0, END_OF_SEQUENCE /* end of sequence */
307};
308
309#define SKIP 0xaa
310/* page 3 - the value SKIP says skip the index - see reg_w_page() */
311static 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,
331 0x00
332};
333
334static void reg_w_buf(struct gspca_dev *gspca_dev,
335 __u8 index,
336 const char *buffer, int len)
337{
Marton Nemeth4f7309e2009-11-05 05:35:08 -0300338 int ret;
339
Marton Nemeth1408b842009-11-02 08:13:21 -0300340 memcpy(gspca_dev->usb_buf, buffer, len);
Marton Nemeth4f7309e2009-11-05 05:35:08 -0300341 ret = usb_control_msg(gspca_dev->dev,
Marton Nemeth1408b842009-11-02 08:13:21 -0300342 usb_sndctrlpipe(gspca_dev->dev, 0),
343 1, /* request */
344 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
345 0, /* value */
346 index, gspca_dev->usb_buf, len,
347 500);
Marton Nemeth4f7309e2009-11-05 05:35:08 -0300348 if (ret < 0)
349 PDEBUG(D_ERR, "reg_w_buf(): "
350 "Failed to write registers to index 0x%x, error %i",
351 index, ret);
Marton Nemeth1408b842009-11-02 08:13:21 -0300352}
353
354
355static void reg_w(struct gspca_dev *gspca_dev,
356 __u8 index,
357 __u8 value)
358{
Marton Nemeth4f7309e2009-11-05 05:35:08 -0300359 int ret;
360
Marton Nemeth1408b842009-11-02 08:13:21 -0300361 gspca_dev->usb_buf[0] = value;
Marton Nemeth4f7309e2009-11-05 05:35:08 -0300362 ret = usb_control_msg(gspca_dev->dev,
Marton Nemeth1408b842009-11-02 08:13:21 -0300363 usb_sndctrlpipe(gspca_dev->dev, 0),
364 0, /* request */
365 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
366 0, index, gspca_dev->usb_buf, 1,
367 500);
Marton Nemeth4f7309e2009-11-05 05:35:08 -0300368 if (ret < 0)
369 PDEBUG(D_ERR, "reg_w(): "
370 "Failed to write register to index 0x%x, value 0x%x, error %i",
371 index, value, ret);
Marton Nemeth1408b842009-11-02 08:13:21 -0300372}
373
374static void reg_w_seq(struct gspca_dev *gspca_dev,
375 const __u8 *seq, int len)
376{
377 while (--len >= 0) {
378 reg_w(gspca_dev, seq[0], seq[1]);
379 seq += 2;
380 }
381}
382
383/* load the beginning of a page */
384static void reg_w_page(struct gspca_dev *gspca_dev,
385 const __u8 *page, int len)
386{
387 int index;
Marton Nemeth4f7309e2009-11-05 05:35:08 -0300388 int ret;
Marton Nemeth1408b842009-11-02 08:13:21 -0300389
390 for (index = 0; index < len; index++) {
391 if (page[index] == SKIP) /* skip this index */
392 continue;
393 gspca_dev->usb_buf[0] = page[index];
Marton Nemeth4f7309e2009-11-05 05:35:08 -0300394 ret = usb_control_msg(gspca_dev->dev,
Marton Nemeth1408b842009-11-02 08:13:21 -0300395 usb_sndctrlpipe(gspca_dev->dev, 0),
396 0, /* request */
397 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
398 0, index, gspca_dev->usb_buf, 1,
399 500);
Marton Nemeth4f7309e2009-11-05 05:35:08 -0300400 if (ret < 0)
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);
Marton Nemeth1408b842009-11-02 08:13:21 -0300405 }
406}
407
408/* output a variable sequence */
409static void reg_w_var(struct gspca_dev *gspca_dev,
410 const __u8 *seq,
411 const __u8 *page3, unsigned int page3_len,
412 const __u8 *page4, unsigned int page4_len)
413{
414 int index, len;
415
416 for (;;) {
417 index = *seq++;
418 len = *seq++;
419 switch (len) {
420 case END_OF_SEQUENCE:
421 return;
422 case LOAD_PAGE4:
423 reg_w_page(gspca_dev, page4, page4_len);
424 break;
425 case LOAD_PAGE3:
426 reg_w_page(gspca_dev, page3, page3_len);
427 break;
428 default:
429 if (len > USB_BUF_SZ) {
430 PDEBUG(D_ERR|D_STREAM,
431 "Incorrect variable sequence");
432 return;
433 }
434 while (len > 0) {
435 if (len < 8) {
436 reg_w_buf(gspca_dev, index, seq, len);
437 seq += len;
438 break;
439 }
440 reg_w_buf(gspca_dev, index, seq, 8);
441 seq += 8;
442 index += 8;
443 len -= 8;
444 }
445 }
446 }
447 /* not reached */
448}
449
450/* this function is called at probe time for pac7302 */
451static int sd_config(struct gspca_dev *gspca_dev,
452 const struct usb_device_id *id)
453{
454 struct sd *sd = (struct sd *) gspca_dev;
455 struct cam *cam;
456
457 cam = &gspca_dev->cam;
458
459 PDEBUG(D_CONF, "Find Sensor PAC7302");
460 cam->cam_mode = vga_mode; /* only 640x480 */
461 cam->nmodes = ARRAY_SIZE(vga_mode);
462
463 sd->brightness = BRIGHTNESS_DEF;
464 sd->contrast = CONTRAST_DEF;
465 sd->colors = COLOR_DEF;
466 sd->gain = GAIN_DEF;
467 sd->exposure = EXPOSURE_DEF;
468 sd->autogain = AUTOGAIN_DEF;
469 sd->hflip = HFLIP_DEF;
470 sd->vflip = VFLIP_DEF;
471 return 0;
472}
473
474/* This function is used by pac7302 only */
475static void setbrightcont(struct gspca_dev *gspca_dev)
476{
477 struct sd *sd = (struct sd *) gspca_dev;
478 int i, v;
479 static const __u8 max[10] =
480 {0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb,
481 0xd4, 0xec};
482 static const __u8 delta[10] =
483 {0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17,
484 0x11, 0x0b};
485
486 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
487 for (i = 0; i < 10; i++) {
488 v = max[i];
489 v += (sd->brightness - BRIGHTNESS_MAX)
490 * 150 / BRIGHTNESS_MAX; /* 200 ? */
491 v -= delta[i] * sd->contrast / CONTRAST_MAX;
492 if (v < 0)
493 v = 0;
494 else if (v > 0xff)
495 v = 0xff;
496 reg_w(gspca_dev, 0xa2 + i, v);
497 }
498 reg_w(gspca_dev, 0xdc, 0x01);
499}
500
501/* This function is used by pac7302 only */
502static void setcolors(struct gspca_dev *gspca_dev)
503{
504 struct sd *sd = (struct sd *) gspca_dev;
505 int i, v;
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};
510
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);
518 }
519 reg_w(gspca_dev, 0xdc, 0x01);
520 PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors);
521}
522
523static void setgain(struct gspca_dev *gspca_dev)
524{
525 struct sd *sd = (struct sd *) gspca_dev;
526
527 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
528 reg_w(gspca_dev, 0x10, sd->gain >> 3);
529
530 /* load registers to sensor (Bit 0, auto clear) */
531 reg_w(gspca_dev, 0x11, 0x01);
532}
533
534static void setexposure(struct gspca_dev *gspca_dev)
535{
536 struct sd *sd = (struct sd *) gspca_dev;
537 __u8 reg;
538
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;
543 if (reg < 2)
544 reg = 2;
545 else if (reg > 63)
546 reg = 63;
547
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);
554
555 /* load registers to sensor (Bit 0, auto clear) */
556 reg_w(gspca_dev, 0x11, 0x01);
557}
558
559static void sethvflip(struct gspca_dev *gspca_dev)
560{
561 struct sd *sd = (struct sd *) gspca_dev;
562 __u8 data;
563
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);
569}
570
571/* this function is called at probe and resume time for pac7302 */
572static int sd_init(struct gspca_dev *gspca_dev)
573{
574 reg_w_seq(gspca_dev, init_7302, sizeof init_7302);
575
576 return 0;
577}
578
579static int sd_start(struct gspca_dev *gspca_dev)
580{
581 struct sd *sd = (struct sd *) gspca_dev;
582
583 sd->sof_read = 0;
584
585 reg_w_var(gspca_dev, start_7302,
586 page3_7302, sizeof(page3_7302),
587 NULL, 0);
588 setbrightcont(gspca_dev);
589 setcolors(gspca_dev);
590 setgain(gspca_dev);
591 setexposure(gspca_dev);
592 sethvflip(gspca_dev);
593
594 /* only resolution 640x480 is supported for pac7302 */
595
596 sd->sof_read = 0;
597 sd->autogain_ignore_frames = 0;
598 atomic_set(&sd->avg_lum, -1);
599
600 /* start stream */
601 reg_w(gspca_dev, 0xff, 0x01);
602 reg_w(gspca_dev, 0x78, 0x01);
603
604 return 0;
605}
606
607static void sd_stopN(struct gspca_dev *gspca_dev)
608{
609 reg_w(gspca_dev, 0xff, 0x01);
610 reg_w(gspca_dev, 0x78, 0x00);
611 reg_w(gspca_dev, 0x78, 0x00);
612}
613
614/* called on streamoff with alt 0 and on disconnect for pac7302 */
615static void sd_stop0(struct gspca_dev *gspca_dev)
616{
617 if (!gspca_dev->present)
618 return;
619 reg_w(gspca_dev, 0xff, 0x01);
620 reg_w(gspca_dev, 0x78, 0x40);
621}
622
623/* Include pac common sof detection functions */
624#include "pac_common.h"
625
626static void do_autogain(struct gspca_dev *gspca_dev)
627{
628 struct sd *sd = (struct sd *) gspca_dev;
629 int avg_lum = atomic_read(&sd->avg_lum);
630 int desired_lum, deadzone;
631
632 if (avg_lum == -1)
633 return;
634
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
639 oscilating */
640 if (desired_lum > avg_lum && sd->gain == GAIN_DEF &&
641 sd->exposure > EXPOSURE_DEF &&
642 sd->exposure < 42)
643 deadzone = 90;
644 else
645 deadzone = 30;
646
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;
652}
653
654/* JPEG header, part 1 */
655static const unsigned char pac_jpeg_header1[] = {
656 0xff, 0xd8, /* SOI: Start of Image */
657
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 */
663};
664
665/* JPEG header, continued */
666static 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 */
671
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 */
680};
681
682static void pac_start_frame(struct gspca_dev *gspca_dev,
683 struct gspca_frame *frame,
684 __u16 lines, __u16 samples_per_line)
685{
686 unsigned char tmpbuf[4];
687
688 gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
689 pac_jpeg_header1, sizeof(pac_jpeg_header1));
690
691 tmpbuf[0] = lines >> 8;
692 tmpbuf[1] = lines & 0xff;
693 tmpbuf[2] = samples_per_line >> 8;
694 tmpbuf[3] = samples_per_line & 0xff;
695
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));
700}
701
702/* this function is run at interrupt level */
703static 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 */
707{
708 struct sd *sd = (struct sd *) gspca_dev;
709 unsigned char *sof;
710
711 sof = pac_find_sof(&sd->sof_read, data, len);
712 if (sof) {
713 int n, lum_offset, footer_length;
714
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;
720 footer_length = 74;
721
722 /* Finish decoding current frame */
723 n = (sof - data) - (footer_length + sizeof pac_sof_marker);
724 if (n < 0) {
725 frame->data_end += n;
726 n = 0;
727 }
728 frame = gspca_frame_add(gspca_dev, INTER_PACKET, frame,
729 data, n);
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,
734 NULL, 0);
735
736 n = sof - data;
737 len -= n;
738 data = sof;
739
740 /* Get average lumination */
741 if (gspca_dev->last_packet_type == LAST_PACKET &&
742 n >= lum_offset)
743 atomic_set(&sd->avg_lum, data[-lum_offset] +
744 data[-lum_offset + 1]);
745 else
746 atomic_set(&sd->avg_lum, -1);
747
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);
752 }
753 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
754}
755
756static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
757{
758 struct sd *sd = (struct sd *) gspca_dev;
759
760 sd->brightness = val;
761 if (gspca_dev->streaming)
762 setbrightcont(gspca_dev);
763 return 0;
764}
765
766static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
767{
768 struct sd *sd = (struct sd *) gspca_dev;
769
770 *val = sd->brightness;
771 return 0;
772}
773
774static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
775{
776 struct sd *sd = (struct sd *) gspca_dev;
777
778 sd->contrast = val;
779 if (gspca_dev->streaming) {
780 setbrightcont(gspca_dev);
781 }
782 return 0;
783}
784
785static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
786{
787 struct sd *sd = (struct sd *) gspca_dev;
788
789 *val = sd->contrast;
790 return 0;
791}
792
793static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
794{
795 struct sd *sd = (struct sd *) gspca_dev;
796
797 sd->colors = val;
798 if (gspca_dev->streaming)
799 setcolors(gspca_dev);
800 return 0;
801}
802
803static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
804{
805 struct sd *sd = (struct sd *) gspca_dev;
806
807 *val = sd->colors;
808 return 0;
809}
810
811static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
812{
813 struct sd *sd = (struct sd *) gspca_dev;
814
815 sd->gain = val;
816 if (gspca_dev->streaming)
817 setgain(gspca_dev);
818 return 0;
819}
820
821static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
822{
823 struct sd *sd = (struct sd *) gspca_dev;
824
825 *val = sd->gain;
826 return 0;
827}
828
829static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
830{
831 struct sd *sd = (struct sd *) gspca_dev;
832
833 sd->exposure = val;
834 if (gspca_dev->streaming)
835 setexposure(gspca_dev);
836 return 0;
837}
838
839static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
840{
841 struct sd *sd = (struct sd *) gspca_dev;
842
843 *val = sd->exposure;
844 return 0;
845}
846
847static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
848{
849 struct sd *sd = (struct sd *) gspca_dev;
850
851 sd->autogain = val;
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. */
856 if (sd->autogain) {
857 sd->exposure = EXPOSURE_DEF;
858 sd->gain = GAIN_DEF;
859 if (gspca_dev->streaming) {
860 sd->autogain_ignore_frames =
861 PAC_AUTOGAIN_IGNORE_FRAMES;
862 setexposure(gspca_dev);
863 setgain(gspca_dev);
864 }
865 }
866
867 return 0;
868}
869
870static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
871{
872 struct sd *sd = (struct sd *) gspca_dev;
873
874 *val = sd->autogain;
875 return 0;
876}
877
878static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
879{
880 struct sd *sd = (struct sd *) gspca_dev;
881
882 sd->hflip = val;
883 if (gspca_dev->streaming)
884 sethvflip(gspca_dev);
885 return 0;
886}
887
888static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val)
889{
890 struct sd *sd = (struct sd *) gspca_dev;
891
892 *val = sd->hflip;
893 return 0;
894}
895
896static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
897{
898 struct sd *sd = (struct sd *) gspca_dev;
899
900 sd->vflip = val;
901 if (gspca_dev->streaming)
902 sethvflip(gspca_dev);
903 return 0;
904}
905
906static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
907{
908 struct sd *sd = (struct sd *) gspca_dev;
909
910 *val = sd->vflip;
911 return 0;
912}
913
914/* sub-driver description for pac7302 */
915static struct sd_desc sd_desc = {
916 .name = MODULE_NAME,
917 .ctrls = sd_ctrls,
918 .nctrls = ARRAY_SIZE(sd_ctrls),
919 .config = sd_config,
920 .init = sd_init,
921 .start = sd_start,
922 .stopN = sd_stopN,
923 .stop0 = sd_stop0,
924 .pkt_scan = sd_pkt_scan,
925 .dq_callback = do_autogain,
926};
927
928/* -- module initialisation -- */
929static __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)},
940 {}
941};
942MODULE_DEVICE_TABLE(usb, device_table);
943
944/* -- device connect -- */
945static int sd_probe(struct usb_interface *intf,
946 const struct usb_device_id *id)
947{
948 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
949 THIS_MODULE);
950}
951
952static struct usb_driver sd_driver = {
953 .name = MODULE_NAME,
954 .id_table = device_table,
955 .probe = sd_probe,
956 .disconnect = gspca_disconnect,
957#ifdef CONFIG_PM
958 .suspend = gspca_suspend,
959 .resume = gspca_resume,
960#endif
961};
962
963/* -- module insert / remove -- */
964static int __init sd_mod_init(void)
965{
966 int ret;
967 ret = usb_register(&sd_driver);
968 if (ret < 0)
969 return ret;
970 PDEBUG(D_PROBE, "registered");
971 return 0;
972}
973static void __exit sd_mod_exit(void)
974{
975 usb_deregister(&sd_driver);
976 PDEBUG(D_PROBE, "deregistered");
977}
978
979module_init(sd_mod_init);
980module_exit(sd_mod_exit);