]> git.karo-electronics.de Git - linux-beck.git/blob - drivers/media/video/gspca/pac7302.c
V4L/DVB (13382): gspca - pac7302: Remove redundant stream off command.
[linux-beck.git] / drivers / media / video / gspca / pac7302.c
1 /*
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
58 MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li");
59 MODULE_DESCRIPTION("Pixart PAC7302");
60 MODULE_LICENSE("GPL");
61
62 /* specific webcam descriptor for pac7302 */
63 struct 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 */
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);
98
99 static 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
225 static 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 */
238 static 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 };
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,
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() */
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,
331         0x00
332 };
333
334 static void reg_w_buf(struct gspca_dev *gspca_dev,
335                   __u8 index,
336                   const char *buffer, int len)
337 {
338         int ret;
339
340         memcpy(gspca_dev->usb_buf, buffer, len);
341         ret = usb_control_msg(gspca_dev->dev,
342                         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);
348         if (ret < 0)
349                 PDEBUG(D_ERR, "reg_w_buf(): "
350                 "Failed to write registers to index 0x%x, error %i",
351                 index, ret);
352 }
353
354
355 static void reg_w(struct gspca_dev *gspca_dev,
356                   __u8 index,
357                   __u8 value)
358 {
359         int ret;
360
361         gspca_dev->usb_buf[0] = value;
362         ret = usb_control_msg(gspca_dev->dev,
363                         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);
368         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);
372 }
373
374 static 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 */
384 static void reg_w_page(struct gspca_dev *gspca_dev,
385                         const __u8 *page, int len)
386 {
387         int index;
388         int ret;
389
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];
394                 ret = usb_control_msg(gspca_dev->dev,
395                                 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);
400                 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);
405         }
406 }
407
408 /* output a variable sequence */
409 static 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 */
451 static 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 */
475 static 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 */
502 static 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
523 static 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
534 static 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
559 static 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 */
572 static int sd_init(struct gspca_dev *gspca_dev)
573 {
574         reg_w_seq(gspca_dev, init_7302, sizeof(init_7302)/2);
575
576         return 0;
577 }
578
579 static 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
607 static void sd_stopN(struct gspca_dev *gspca_dev)
608 {
609         /* stop stream */
610         reg_w(gspca_dev, 0xff, 0x01);
611         reg_w(gspca_dev, 0x78, 0x00);
612 }
613
614 /* called on streamoff with alt 0 and on disconnect for pac7302 */
615 static 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
626 static 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 */
655 static 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 */
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 */
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
682 static 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 */
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 */
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
756 static 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
766 static 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
774 static 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
785 static 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
793 static 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
803 static 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
811 static 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
821 static 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
829 static 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
839 static 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
847 static 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
870 static 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
878 static 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
888 static 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
896 static 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
906 static 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 */
915 static 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 -- */
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)},
940         {}
941 };
942 MODULE_DEVICE_TABLE(usb, device_table);
943
944 /* -- device connect -- */
945 static 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
952 static 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 -- */
964 static 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 }
973 static void __exit sd_mod_exit(void)
974 {
975         usb_deregister(&sd_driver);
976         PDEBUG(D_PROBE, "deregistered");
977 }
978
979 module_init(sd_mod_init);
980 module_exit(sd_mod_exit);