[media] gspca_pac7302: avoid duplicate calls of the image quality adjustment function...
[deliverable/linux.git] / drivers / media / usb / gspca / pac7302.c
1 /*
2 * Pixart PAC7302 driver
3 *
4 * Copyright (C) 2008-2012 Jean-Francois Moine <http://moinejf.free.fr>
5 * Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li
6 *
7 * Separated from Pixart PAC7311 library by Márton Németh
8 * Camera button input handling by Márton Németh <nm127@freemail.hu>
9 * Copyright (C) 2009-2010 Márton Németh <nm127@freemail.hu>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25
26 /*
27 * Some documentation about various registers as determined by trial and error.
28 *
29 * Register page 0:
30 *
31 * Address Description
32 * 0xb6 Sharpness control (bits 0-4)
33 *
34 * Register page 1:
35 *
36 * Address Description
37 * 0x78 Global control, bit 6 controls the LED (inverted)
38 * 0x80 Compression balance, 2 interesting settings:
39 * 0x0f Default
40 * 0x50 Values >= this switch the camera to a lower compression,
41 * using the same table for both luminance and chrominance.
42 * This gives a sharper picture. Only usable when running
43 * at < 15 fps! Note currently the driver does not use this
44 * as the quality gain is small and the generated JPG-s are
45 * only understood by v4l-utils >= 0.8.9
46 *
47 * Register page 3:
48 *
49 * Address Description
50 * 0x02 Clock divider 3-63, fps = 90 / val. Must be a multiple of 3 on
51 * the 7302, so one of 3, 6, 9, ..., except when between 6 and 12?
52 * 0x03 Variable framerate ctrl reg2==3: 0 -> ~30 fps, 255 -> ~22fps
53 * 0x04 Another var framerate ctrl reg2==3, reg3==0: 0 -> ~30 fps,
54 * 63 -> ~27 fps, the 2 msb's must always be 1 !!
55 * 0x05 Another var framerate ctrl reg2==3, reg3==0, reg4==0xc0:
56 * 1 -> ~30 fps, 2 -> ~20 fps
57 * 0x0e Exposure bits 0-7, 0-448, 0 = use full frame time
58 * 0x0f Exposure bit 8, 0-448, 448 = no exposure at all
59 * 0x10 Gain 0-31
60 * 0x12 Another gain 0-31, unlike 0x10 this one seems to start with an
61 * amplification value of 1 rather then 0 at its lowest setting
62 * 0x21 Bitfield: 0-1 unused, 2-3 vflip/hflip, 4-5 unknown, 6-7 unused
63 * 0x80 Another framerate control, best left at 1, moving it from 1 to
64 * 2 causes the framerate to become 3/4th of what it was, and
65 * also seems to cause pixel averaging, resulting in an effective
66 * resolution of 320x240 and thus a much blockier image
67 *
68 * The registers are accessed in the following functions:
69 *
70 * Page | Register | Function
71 * -----+------------+---------------------------------------------------
72 * 0 | 0x0f..0x20 | setcolors()
73 * 0 | 0xa2..0xab | setbrightcont()
74 * 0 | 0xb6 | setsharpness()
75 * 0 | 0xc5 | setredbalance()
76 * 0 | 0xc6 | setwhitebalance()
77 * 0 | 0xc7 | setbluebalance()
78 * 0 | 0xdc | setbrightcont(), setcolors()
79 * 3 | 0x02 | setexposure()
80 * 3 | 0x10, 0x12 | setgain()
81 * 3 | 0x11 | setcolors(), setgain(), setexposure(), sethvflip()
82 * 3 | 0x21 | sethvflip()
83 */
84
85 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
86
87 #include <linux/input.h>
88 #include <media/v4l2-chip-ident.h>
89 #include "gspca.h"
90 /* Include pac common sof detection functions */
91 #include "pac_common.h"
92
93 #define PAC7302_GAIN_DEFAULT 15
94 #define PAC7302_GAIN_KNEE 42
95 #define PAC7302_EXPOSURE_DEFAULT 66 /* 33 ms / 30 fps */
96 #define PAC7302_EXPOSURE_KNEE 133 /* 66 ms / 15 fps */
97
98 MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>, "
99 "Thomas Kaiser thomas@kaiser-linux.li");
100 MODULE_DESCRIPTION("Pixart PAC7302");
101 MODULE_LICENSE("GPL");
102
103 struct sd {
104 struct gspca_dev gspca_dev; /* !! must be the first item */
105
106 struct { /* brightness / contrast cluster */
107 struct v4l2_ctrl *brightness;
108 struct v4l2_ctrl *contrast;
109 };
110 struct v4l2_ctrl *saturation;
111 struct v4l2_ctrl *white_balance;
112 struct v4l2_ctrl *red_balance;
113 struct v4l2_ctrl *blue_balance;
114 struct { /* flip cluster */
115 struct v4l2_ctrl *hflip;
116 struct v4l2_ctrl *vflip;
117 };
118 struct v4l2_ctrl *sharpness;
119 u8 flags;
120 #define FL_HFLIP 0x01 /* mirrored by default */
121 #define FL_VFLIP 0x02 /* vertical flipped by default */
122
123 u8 sof_read;
124 s8 autogain_ignore_frames;
125
126 atomic_t avg_lum;
127 };
128
129 static const struct v4l2_pix_format vga_mode[] = {
130 {640, 480, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
131 .bytesperline = 640,
132 .sizeimage = 640 * 480 * 3 / 8 + 590,
133 .colorspace = V4L2_COLORSPACE_JPEG,
134 },
135 };
136
137 #define LOAD_PAGE3 255
138 #define END_OF_SEQUENCE 0
139
140 static const u8 init_7302[] = {
141 /* index,value */
142 0xff, 0x01, /* page 1 */
143 0x78, 0x00, /* deactivate */
144 0xff, 0x01,
145 0x78, 0x40, /* led off */
146 };
147 static const u8 start_7302[] = {
148 /* index, len, [value]* */
149 0xff, 1, 0x00, /* page 0 */
150 0x00, 12, 0x01, 0x40, 0x40, 0x40, 0x01, 0xe0, 0x02, 0x80,
151 0x00, 0x00, 0x00, 0x00,
152 0x0d, 24, 0x03, 0x01, 0x00, 0xb5, 0x07, 0xcb, 0x00, 0x00,
153 0x07, 0xc8, 0x00, 0xea, 0x07, 0xcf, 0x07, 0xf7,
154 0x07, 0x7e, 0x01, 0x0b, 0x00, 0x00, 0x00, 0x11,
155 0x26, 2, 0xaa, 0xaa,
156 0x2e, 1, 0x31,
157 0x38, 1, 0x01,
158 0x3a, 3, 0x14, 0xff, 0x5a,
159 0x43, 11, 0x00, 0x0a, 0x18, 0x11, 0x01, 0x2c, 0x88, 0x11,
160 0x00, 0x54, 0x11,
161 0x55, 1, 0x00,
162 0x62, 4, 0x10, 0x1e, 0x1e, 0x18,
163 0x6b, 1, 0x00,
164 0x6e, 3, 0x08, 0x06, 0x00,
165 0x72, 3, 0x00, 0xff, 0x00,
166 0x7d, 23, 0x01, 0x01, 0x58, 0x46, 0x50, 0x3c, 0x50, 0x3c,
167 0x54, 0x46, 0x54, 0x56, 0x52, 0x50, 0x52, 0x50,
168 0x56, 0x64, 0xa4, 0x00, 0xda, 0x00, 0x00,
169 0xa2, 10, 0x22, 0x2c, 0x3c, 0x54, 0x69, 0x7c, 0x9c, 0xb9,
170 0xd2, 0xeb,
171 0xaf, 1, 0x02,
172 0xb5, 2, 0x08, 0x08,
173 0xb8, 2, 0x08, 0x88,
174 0xc4, 4, 0xae, 0x01, 0x04, 0x01,
175 0xcc, 1, 0x00,
176 0xd1, 11, 0x01, 0x30, 0x49, 0x5e, 0x6f, 0x7f, 0x8e, 0xa9,
177 0xc1, 0xd7, 0xec,
178 0xdc, 1, 0x01,
179 0xff, 1, 0x01, /* page 1 */
180 0x12, 3, 0x02, 0x00, 0x01,
181 0x3e, 2, 0x00, 0x00,
182 0x76, 5, 0x01, 0x20, 0x40, 0x00, 0xf2,
183 0x7c, 1, 0x00,
184 0x7f, 10, 0x4b, 0x0f, 0x01, 0x2c, 0x02, 0x58, 0x03, 0x20,
185 0x02, 0x00,
186 0x96, 5, 0x01, 0x10, 0x04, 0x01, 0x04,
187 0xc8, 14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
188 0x07, 0x00, 0x01, 0x07, 0x04, 0x01,
189 0xd8, 1, 0x01,
190 0xdb, 2, 0x00, 0x01,
191 0xde, 7, 0x00, 0x01, 0x04, 0x04, 0x00, 0x00, 0x00,
192 0xe6, 4, 0x00, 0x00, 0x00, 0x01,
193 0xeb, 1, 0x00,
194 0xff, 1, 0x02, /* page 2 */
195 0x22, 1, 0x00,
196 0xff, 1, 0x03, /* page 3 */
197 0, LOAD_PAGE3, /* load the page 3 */
198 0x11, 1, 0x01,
199 0xff, 1, 0x02, /* page 2 */
200 0x13, 1, 0x00,
201 0x22, 4, 0x1f, 0xa4, 0xf0, 0x96,
202 0x27, 2, 0x14, 0x0c,
203 0x2a, 5, 0xc8, 0x00, 0x18, 0x12, 0x22,
204 0x64, 8, 0x00, 0x00, 0xf0, 0x01, 0x14, 0x44, 0x44, 0x44,
205 0x6e, 1, 0x08,
206 0xff, 1, 0x01, /* page 1 */
207 0x78, 1, 0x00,
208 0, END_OF_SEQUENCE /* end of sequence */
209 };
210
211 #define SKIP 0xaa
212 /* page 3 - the value SKIP says skip the index - see reg_w_page() */
213 static const u8 page3_7302[] = {
214 0x90, 0x40, 0x03, 0x00, 0xc0, 0x01, 0x14, 0x16,
215 0x14, 0x12, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00,
216 0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
217 0x00, 0x00, 0x00, 0x47, 0x01, 0xb3, 0x01, 0x00,
218 0x00, 0x08, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x21,
219 0x00, 0x00, 0x00, 0x54, 0xf4, 0x02, 0x52, 0x54,
220 0xa4, 0xb8, 0xe0, 0x2a, 0xf6, 0x00, 0x00, 0x00,
221 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
222 0x00, 0xfc, 0x00, 0xf2, 0x1f, 0x04, 0x00, 0x00,
223 SKIP, 0x00, 0x00, 0xc0, 0xc0, 0x10, 0x00, 0x00,
224 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
225 0x00, 0x40, 0xff, 0x03, 0x19, 0x00, 0x00, 0x00,
226 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
227 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc8, 0xc8,
228 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
229 0x08, 0x10, 0x24, 0x40, 0x00, 0x00, 0x00, 0x00,
230 0x01, 0x00, 0x02, 0x47, 0x00, 0x00, 0x00, 0x00,
231 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
232 0x00, 0x02, 0xfa, 0x00, 0x64, 0x5a, 0x28, 0x00,
233 0x00
234 };
235
236 static void reg_w_buf(struct gspca_dev *gspca_dev,
237 u8 index,
238 const u8 *buffer, int len)
239 {
240 int ret;
241
242 if (gspca_dev->usb_err < 0)
243 return;
244 memcpy(gspca_dev->usb_buf, buffer, len);
245 ret = usb_control_msg(gspca_dev->dev,
246 usb_sndctrlpipe(gspca_dev->dev, 0),
247 0, /* request */
248 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
249 0, /* value */
250 index, gspca_dev->usb_buf, len,
251 500);
252 if (ret < 0) {
253 pr_err("reg_w_buf failed i: %02x error %d\n",
254 index, ret);
255 gspca_dev->usb_err = ret;
256 }
257 }
258
259
260 static void reg_w(struct gspca_dev *gspca_dev,
261 u8 index,
262 u8 value)
263 {
264 int ret;
265
266 if (gspca_dev->usb_err < 0)
267 return;
268 gspca_dev->usb_buf[0] = value;
269 ret = usb_control_msg(gspca_dev->dev,
270 usb_sndctrlpipe(gspca_dev->dev, 0),
271 0, /* request */
272 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
273 0, index, gspca_dev->usb_buf, 1,
274 500);
275 if (ret < 0) {
276 pr_err("reg_w() failed i: %02x v: %02x error %d\n",
277 index, value, ret);
278 gspca_dev->usb_err = ret;
279 }
280 }
281
282 static void reg_w_seq(struct gspca_dev *gspca_dev,
283 const u8 *seq, int len)
284 {
285 while (--len >= 0) {
286 reg_w(gspca_dev, seq[0], seq[1]);
287 seq += 2;
288 }
289 }
290
291 /* load the beginning of a page */
292 static void reg_w_page(struct gspca_dev *gspca_dev,
293 const u8 *page, int len)
294 {
295 int index;
296 int ret = 0;
297
298 if (gspca_dev->usb_err < 0)
299 return;
300 for (index = 0; index < len; index++) {
301 if (page[index] == SKIP) /* skip this index */
302 continue;
303 gspca_dev->usb_buf[0] = page[index];
304 ret = usb_control_msg(gspca_dev->dev,
305 usb_sndctrlpipe(gspca_dev->dev, 0),
306 0, /* request */
307 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
308 0, index, gspca_dev->usb_buf, 1,
309 500);
310 if (ret < 0) {
311 pr_err("reg_w_page() failed i: %02x v: %02x error %d\n",
312 index, page[index], ret);
313 gspca_dev->usb_err = ret;
314 break;
315 }
316 }
317 }
318
319 /* output a variable sequence */
320 static void reg_w_var(struct gspca_dev *gspca_dev,
321 const u8 *seq,
322 const u8 *page3, unsigned int page3_len)
323 {
324 int index, len;
325
326 for (;;) {
327 index = *seq++;
328 len = *seq++;
329 switch (len) {
330 case END_OF_SEQUENCE:
331 return;
332 case LOAD_PAGE3:
333 reg_w_page(gspca_dev, page3, page3_len);
334 break;
335 default:
336 #ifdef GSPCA_DEBUG
337 if (len > USB_BUF_SZ) {
338 PDEBUG(D_ERR|D_STREAM,
339 "Incorrect variable sequence");
340 return;
341 }
342 #endif
343 while (len > 0) {
344 if (len < 8) {
345 reg_w_buf(gspca_dev,
346 index, seq, len);
347 seq += len;
348 break;
349 }
350 reg_w_buf(gspca_dev, index, seq, 8);
351 seq += 8;
352 index += 8;
353 len -= 8;
354 }
355 }
356 }
357 /* not reached */
358 }
359
360 /* this function is called at probe time for pac7302 */
361 static int sd_config(struct gspca_dev *gspca_dev,
362 const struct usb_device_id *id)
363 {
364 struct sd *sd = (struct sd *) gspca_dev;
365 struct cam *cam;
366
367 cam = &gspca_dev->cam;
368
369 cam->cam_mode = vga_mode; /* only 640x480 */
370 cam->nmodes = ARRAY_SIZE(vga_mode);
371
372 sd->flags = id->driver_info;
373 return 0;
374 }
375
376 static void setbrightcont(struct gspca_dev *gspca_dev)
377 {
378 struct sd *sd = (struct sd *) gspca_dev;
379 int i, v;
380 static const u8 max[10] =
381 {0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb,
382 0xd4, 0xec};
383 static const u8 delta[10] =
384 {0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17,
385 0x11, 0x0b};
386
387 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
388 for (i = 0; i < 10; i++) {
389 v = max[i];
390 v += (sd->brightness->val - sd->brightness->maximum)
391 * 150 / sd->brightness->maximum; /* 200 ? */
392 v -= delta[i] * sd->contrast->val / sd->contrast->maximum;
393 if (v < 0)
394 v = 0;
395 else if (v > 0xff)
396 v = 0xff;
397 reg_w(gspca_dev, 0xa2 + i, v);
398 }
399 reg_w(gspca_dev, 0xdc, 0x01);
400 }
401
402 static void setcolors(struct gspca_dev *gspca_dev)
403 {
404 struct sd *sd = (struct sd *) gspca_dev;
405 int i, v;
406 static const int a[9] =
407 {217, -212, 0, -101, 170, -67, -38, -315, 355};
408 static const int b[9] =
409 {19, 106, 0, 19, 106, 1, 19, 106, 1};
410
411 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
412 reg_w(gspca_dev, 0x11, 0x01);
413 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
414 for (i = 0; i < 9; i++) {
415 v = a[i] * sd->saturation->val / sd->saturation->maximum;
416 v += b[i];
417 reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07);
418 reg_w(gspca_dev, 0x0f + 2 * i + 1, v);
419 }
420 reg_w(gspca_dev, 0xdc, 0x01);
421 }
422
423 static void setwhitebalance(struct gspca_dev *gspca_dev)
424 {
425 struct sd *sd = (struct sd *) gspca_dev;
426
427 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
428 reg_w(gspca_dev, 0xc6, sd->white_balance->val);
429
430 reg_w(gspca_dev, 0xdc, 0x01);
431 }
432
433 static void setredbalance(struct gspca_dev *gspca_dev)
434 {
435 struct sd *sd = (struct sd *) gspca_dev;
436
437 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
438 reg_w(gspca_dev, 0xc5, sd->red_balance->val);
439
440 reg_w(gspca_dev, 0xdc, 0x01);
441 }
442
443 static void setbluebalance(struct gspca_dev *gspca_dev)
444 {
445 struct sd *sd = (struct sd *) gspca_dev;
446
447 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
448 reg_w(gspca_dev, 0xc7, sd->blue_balance->val);
449
450 reg_w(gspca_dev, 0xdc, 0x01);
451 }
452
453 static void setgain(struct gspca_dev *gspca_dev)
454 {
455 u8 reg10, reg12;
456
457 if (gspca_dev->gain->val < 32) {
458 reg10 = gspca_dev->gain->val;
459 reg12 = 0;
460 } else {
461 reg10 = 31;
462 reg12 = gspca_dev->gain->val - 31;
463 }
464
465 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
466 reg_w(gspca_dev, 0x10, reg10);
467 reg_w(gspca_dev, 0x12, reg12);
468
469 /* load registers to sensor (Bit 0, auto clear) */
470 reg_w(gspca_dev, 0x11, 0x01);
471 }
472
473 static void setexposure(struct gspca_dev *gspca_dev)
474 {
475 u8 clockdiv;
476 u16 exposure;
477
478 /*
479 * Register 2 of frame 3 contains the clock divider configuring the
480 * no fps according to the formula: 90 / reg. sd->exposure is the
481 * desired exposure time in 0.5 ms.
482 */
483 clockdiv = (90 * gspca_dev->exposure->val + 1999) / 2000;
484
485 /*
486 * Note clockdiv = 3 also works, but when running at 30 fps, depending
487 * on the scene being recorded, the camera switches to another
488 * quantization table for certain JPEG blocks, and we don't know how
489 * to decompress these blocks. So we cap the framerate at 15 fps.
490 */
491 if (clockdiv < 6)
492 clockdiv = 6;
493 else if (clockdiv > 63)
494 clockdiv = 63;
495
496 /*
497 * Register 2 MUST be a multiple of 3, except when between 6 and 12?
498 * Always round up, otherwise we cannot get the desired frametime
499 * using the partial frame time exposure control.
500 */
501 if (clockdiv < 6 || clockdiv > 12)
502 clockdiv = ((clockdiv + 2) / 3) * 3;
503
504 /*
505 * frame exposure time in ms = 1000 * clockdiv / 90 ->
506 * exposure = (sd->exposure / 2) * 448 / (1000 * clockdiv / 90)
507 */
508 exposure = (gspca_dev->exposure->val * 45 * 448) / (1000 * clockdiv);
509 /* 0 = use full frametime, 448 = no exposure, reverse it */
510 exposure = 448 - exposure;
511
512 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
513 reg_w(gspca_dev, 0x02, clockdiv);
514 reg_w(gspca_dev, 0x0e, exposure & 0xff);
515 reg_w(gspca_dev, 0x0f, exposure >> 8);
516
517 /* load registers to sensor (Bit 0, auto clear) */
518 reg_w(gspca_dev, 0x11, 0x01);
519 }
520
521 static void sethvflip(struct gspca_dev *gspca_dev)
522 {
523 struct sd *sd = (struct sd *) gspca_dev;
524 u8 data, hflip, vflip;
525
526 hflip = sd->hflip->val;
527 if (sd->flags & FL_HFLIP)
528 hflip = !hflip;
529 vflip = sd->vflip->val;
530 if (sd->flags & FL_VFLIP)
531 vflip = !vflip;
532
533 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
534 data = (hflip ? 0x08 : 0x00) | (vflip ? 0x04 : 0x00);
535 reg_w(gspca_dev, 0x21, data);
536
537 /* load registers to sensor (Bit 0, auto clear) */
538 reg_w(gspca_dev, 0x11, 0x01);
539 }
540
541 static void setsharpness(struct gspca_dev *gspca_dev)
542 {
543 struct sd *sd = (struct sd *) gspca_dev;
544
545 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
546 reg_w(gspca_dev, 0xb6, sd->sharpness->val);
547
548 reg_w(gspca_dev, 0xdc, 0x01);
549 }
550
551 /* this function is called at probe and resume time for pac7302 */
552 static int sd_init(struct gspca_dev *gspca_dev)
553 {
554 reg_w_seq(gspca_dev, init_7302, sizeof(init_7302)/2);
555 return gspca_dev->usb_err;
556 }
557
558 static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
559 {
560 struct gspca_dev *gspca_dev =
561 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
562 struct sd *sd = (struct sd *)gspca_dev;
563
564 gspca_dev->usb_err = 0;
565
566 if (ctrl->id == V4L2_CID_AUTOGAIN && ctrl->is_new && ctrl->val) {
567 /* when switching to autogain set defaults to make sure
568 we are on a valid point of the autogain gain /
569 exposure knee graph, and give this change time to
570 take effect before doing autogain. */
571 gspca_dev->exposure->val = PAC7302_EXPOSURE_DEFAULT;
572 gspca_dev->gain->val = PAC7302_GAIN_DEFAULT;
573 sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES;
574 }
575
576 if (!gspca_dev->streaming)
577 return 0;
578
579 switch (ctrl->id) {
580 case V4L2_CID_BRIGHTNESS:
581 setbrightcont(gspca_dev);
582 break;
583 case V4L2_CID_SATURATION:
584 setcolors(gspca_dev);
585 break;
586 case V4L2_CID_WHITE_BALANCE_TEMPERATURE:
587 setwhitebalance(gspca_dev);
588 break;
589 case V4L2_CID_RED_BALANCE:
590 setredbalance(gspca_dev);
591 break;
592 case V4L2_CID_BLUE_BALANCE:
593 setbluebalance(gspca_dev);
594 break;
595 case V4L2_CID_AUTOGAIN:
596 if (gspca_dev->exposure->is_new || (ctrl->is_new && ctrl->val))
597 setexposure(gspca_dev);
598 if (gspca_dev->gain->is_new || (ctrl->is_new && ctrl->val))
599 setgain(gspca_dev);
600 break;
601 case V4L2_CID_HFLIP:
602 sethvflip(gspca_dev);
603 break;
604 case V4L2_CID_SHARPNESS:
605 setsharpness(gspca_dev);
606 break;
607 default:
608 return -EINVAL;
609 }
610 return gspca_dev->usb_err;
611 }
612
613 static const struct v4l2_ctrl_ops sd_ctrl_ops = {
614 .s_ctrl = sd_s_ctrl,
615 };
616
617 /* this function is called at probe time */
618 static int sd_init_controls(struct gspca_dev *gspca_dev)
619 {
620 struct sd *sd = (struct sd *) gspca_dev;
621 struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
622
623 gspca_dev->vdev.ctrl_handler = hdl;
624 v4l2_ctrl_handler_init(hdl, 12);
625
626 sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
627 V4L2_CID_BRIGHTNESS, 0, 32, 1, 16);
628 sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
629 V4L2_CID_CONTRAST, 0, 255, 1, 127);
630
631 sd->saturation = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
632 V4L2_CID_SATURATION, 0, 255, 1, 127);
633 sd->white_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
634 V4L2_CID_WHITE_BALANCE_TEMPERATURE,
635 0, 255, 1, 55);
636 sd->red_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
637 V4L2_CID_RED_BALANCE, 0, 3, 1, 1);
638 sd->blue_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
639 V4L2_CID_BLUE_BALANCE, 0, 3, 1, 1);
640
641 gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
642 V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
643 gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
644 V4L2_CID_EXPOSURE, 0, 1023, 1,
645 PAC7302_EXPOSURE_DEFAULT);
646 gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
647 V4L2_CID_GAIN, 0, 62, 1,
648 PAC7302_GAIN_DEFAULT);
649
650 sd->hflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
651 V4L2_CID_HFLIP, 0, 1, 1, 0);
652 sd->vflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
653 V4L2_CID_VFLIP, 0, 1, 1, 0);
654
655 sd->sharpness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
656 V4L2_CID_SHARPNESS, 0, 15, 1, 8);
657
658 if (hdl->error) {
659 pr_err("Could not initialize controls\n");
660 return hdl->error;
661 }
662
663 v4l2_ctrl_cluster(2, &sd->brightness);
664 v4l2_ctrl_auto_cluster(3, &gspca_dev->autogain, 0, false);
665 v4l2_ctrl_cluster(2, &sd->hflip);
666 return 0;
667 }
668
669 /* -- start the camera -- */
670 static int sd_start(struct gspca_dev *gspca_dev)
671 {
672 struct sd *sd = (struct sd *) gspca_dev;
673
674 reg_w_var(gspca_dev, start_7302,
675 page3_7302, sizeof(page3_7302));
676
677 sd->sof_read = 0;
678 sd->autogain_ignore_frames = 0;
679 atomic_set(&sd->avg_lum, 270 + sd->brightness->val);
680
681 /* start stream */
682 reg_w(gspca_dev, 0xff, 0x01);
683 reg_w(gspca_dev, 0x78, 0x01);
684
685 return gspca_dev->usb_err;
686 }
687
688 static void sd_stopN(struct gspca_dev *gspca_dev)
689 {
690
691 /* stop stream */
692 reg_w(gspca_dev, 0xff, 0x01);
693 reg_w(gspca_dev, 0x78, 0x00);
694 }
695
696 /* called on streamoff with alt 0 and on disconnect for pac7302 */
697 static void sd_stop0(struct gspca_dev *gspca_dev)
698 {
699 if (!gspca_dev->present)
700 return;
701 reg_w(gspca_dev, 0xff, 0x01);
702 reg_w(gspca_dev, 0x78, 0x40);
703 }
704
705 static void do_autogain(struct gspca_dev *gspca_dev)
706 {
707 struct sd *sd = (struct sd *) gspca_dev;
708 int avg_lum = atomic_read(&sd->avg_lum);
709 int desired_lum;
710 const int deadzone = 30;
711
712 if (sd->autogain_ignore_frames < 0)
713 return;
714
715 if (sd->autogain_ignore_frames > 0) {
716 sd->autogain_ignore_frames--;
717 } else {
718 desired_lum = 270 + sd->brightness->val;
719
720 if (gspca_expo_autogain(gspca_dev, avg_lum, desired_lum,
721 deadzone, PAC7302_GAIN_KNEE,
722 PAC7302_EXPOSURE_KNEE))
723 sd->autogain_ignore_frames =
724 PAC_AUTOGAIN_IGNORE_FRAMES;
725 }
726 }
727
728 /* JPEG header */
729 static const u8 jpeg_header[] = {
730 0xff, 0xd8, /* SOI: Start of Image */
731
732 0xff, 0xc0, /* SOF0: Start of Frame (Baseline DCT) */
733 0x00, 0x11, /* length = 17 bytes (including this length field) */
734 0x08, /* Precision: 8 */
735 0x02, 0x80, /* height = 640 (image rotated) */
736 0x01, 0xe0, /* width = 480 */
737 0x03, /* Number of image components: 3 */
738 0x01, 0x21, 0x00, /* ID=1, Subsampling 1x1, Quantization table: 0 */
739 0x02, 0x11, 0x01, /* ID=2, Subsampling 2x1, Quantization table: 1 */
740 0x03, 0x11, 0x01, /* ID=3, Subsampling 2x1, Quantization table: 1 */
741
742 0xff, 0xda, /* SOS: Start Of Scan */
743 0x00, 0x0c, /* length = 12 bytes (including this length field) */
744 0x03, /* number of components: 3 */
745 0x01, 0x00, /* selector 1, table 0x00 */
746 0x02, 0x11, /* selector 2, table 0x11 */
747 0x03, 0x11, /* selector 3, table 0x11 */
748 0x00, 0x3f, /* Spectral selection: 0 .. 63 */
749 0x00 /* Successive approximation: 0 */
750 };
751
752 /* this function is run at interrupt level */
753 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
754 u8 *data, /* isoc packet */
755 int len) /* iso packet length */
756 {
757 struct sd *sd = (struct sd *) gspca_dev;
758 u8 *image;
759 u8 *sof;
760
761 sof = pac_find_sof(&sd->sof_read, data, len);
762 if (sof) {
763 int n, lum_offset, footer_length;
764
765 /*
766 * 6 bytes after the FF D9 EOF marker a number of lumination
767 * bytes are send corresponding to different parts of the
768 * image, the 14th and 15th byte after the EOF seem to
769 * correspond to the center of the image.
770 */
771 lum_offset = 61 + sizeof pac_sof_marker;
772 footer_length = 74;
773
774 /* Finish decoding current frame */
775 n = (sof - data) - (footer_length + sizeof pac_sof_marker);
776 if (n < 0) {
777 gspca_dev->image_len += n;
778 n = 0;
779 } else {
780 gspca_frame_add(gspca_dev, INTER_PACKET, data, n);
781 }
782
783 image = gspca_dev->image;
784 if (image != NULL
785 && image[gspca_dev->image_len - 2] == 0xff
786 && image[gspca_dev->image_len - 1] == 0xd9)
787 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
788
789 n = sof - data;
790 len -= n;
791 data = sof;
792
793 /* Get average lumination */
794 if (gspca_dev->last_packet_type == LAST_PACKET &&
795 n >= lum_offset)
796 atomic_set(&sd->avg_lum, data[-lum_offset] +
797 data[-lum_offset + 1]);
798
799 /* Start the new frame with the jpeg header */
800 /* The PAC7302 has the image rotated 90 degrees */
801 gspca_frame_add(gspca_dev, FIRST_PACKET,
802 jpeg_header, sizeof jpeg_header);
803 }
804 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
805 }
806
807 #ifdef CONFIG_VIDEO_ADV_DEBUG
808 static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
809 struct v4l2_dbg_register *reg)
810 {
811 u8 index;
812 u8 value;
813
814 /*
815 * reg->reg: bit0..15: reserved for register index (wIndex is 16bit
816 * long on the USB bus)
817 */
818 if (reg->match.type == V4L2_CHIP_MATCH_HOST &&
819 reg->match.addr == 0 &&
820 (reg->reg < 0x000000ff) &&
821 (reg->val <= 0x000000ff)
822 ) {
823 /* Currently writing to page 0 is only supported. */
824 /* reg_w() only supports 8bit index */
825 index = reg->reg;
826 value = reg->val;
827
828 /*
829 * Note that there shall be no access to other page
830 * by any other function between the page switch and
831 * the actual register write.
832 */
833 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
834 reg_w(gspca_dev, index, value);
835
836 reg_w(gspca_dev, 0xdc, 0x01);
837 }
838 return gspca_dev->usb_err;
839 }
840
841 static int sd_chip_ident(struct gspca_dev *gspca_dev,
842 struct v4l2_dbg_chip_ident *chip)
843 {
844 int ret = -EINVAL;
845
846 if (chip->match.type == V4L2_CHIP_MATCH_HOST &&
847 chip->match.addr == 0) {
848 chip->revision = 0;
849 chip->ident = V4L2_IDENT_UNKNOWN;
850 ret = 0;
851 }
852 return ret;
853 }
854 #endif
855
856 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
857 static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
858 u8 *data, /* interrupt packet data */
859 int len) /* interrput packet length */
860 {
861 int ret = -EINVAL;
862 u8 data0, data1;
863
864 if (len == 2) {
865 data0 = data[0];
866 data1 = data[1];
867 if ((data0 == 0x00 && data1 == 0x11) ||
868 (data0 == 0x22 && data1 == 0x33) ||
869 (data0 == 0x44 && data1 == 0x55) ||
870 (data0 == 0x66 && data1 == 0x77) ||
871 (data0 == 0x88 && data1 == 0x99) ||
872 (data0 == 0xaa && data1 == 0xbb) ||
873 (data0 == 0xcc && data1 == 0xdd) ||
874 (data0 == 0xee && data1 == 0xff)) {
875 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
876 input_sync(gspca_dev->input_dev);
877 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
878 input_sync(gspca_dev->input_dev);
879 ret = 0;
880 }
881 }
882
883 return ret;
884 }
885 #endif
886
887 /* sub-driver description for pac7302 */
888 static const struct sd_desc sd_desc = {
889 .name = KBUILD_MODNAME,
890 .config = sd_config,
891 .init = sd_init,
892 .init_controls = sd_init_controls,
893 .start = sd_start,
894 .stopN = sd_stopN,
895 .stop0 = sd_stop0,
896 .pkt_scan = sd_pkt_scan,
897 .dq_callback = do_autogain,
898 #ifdef CONFIG_VIDEO_ADV_DEBUG
899 .set_register = sd_dbg_s_register,
900 .get_chip_ident = sd_chip_ident,
901 #endif
902 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
903 .int_pkt_scan = sd_int_pkt_scan,
904 #endif
905 };
906
907 /* -- module initialisation -- */
908 static const struct usb_device_id device_table[] = {
909 {USB_DEVICE(0x06f8, 0x3009)},
910 {USB_DEVICE(0x06f8, 0x301b)},
911 {USB_DEVICE(0x093a, 0x2620)},
912 {USB_DEVICE(0x093a, 0x2621)},
913 {USB_DEVICE(0x093a, 0x2622), .driver_info = FL_VFLIP},
914 {USB_DEVICE(0x093a, 0x2624), .driver_info = FL_VFLIP},
915 {USB_DEVICE(0x093a, 0x2625)},
916 {USB_DEVICE(0x093a, 0x2626)},
917 {USB_DEVICE(0x093a, 0x2627), .driver_info = FL_VFLIP},
918 {USB_DEVICE(0x093a, 0x2628)},
919 {USB_DEVICE(0x093a, 0x2629), .driver_info = FL_VFLIP},
920 {USB_DEVICE(0x093a, 0x262a)},
921 {USB_DEVICE(0x093a, 0x262c)},
922 {USB_DEVICE(0x145f, 0x013c)},
923 {USB_DEVICE(0x1ae7, 0x2001)}, /* SpeedLink Snappy Mic SL-6825-SBK */
924 {}
925 };
926 MODULE_DEVICE_TABLE(usb, device_table);
927
928 /* -- device connect -- */
929 static int sd_probe(struct usb_interface *intf,
930 const struct usb_device_id *id)
931 {
932 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
933 THIS_MODULE);
934 }
935
936 static struct usb_driver sd_driver = {
937 .name = KBUILD_MODNAME,
938 .id_table = device_table,
939 .probe = sd_probe,
940 .disconnect = gspca_disconnect,
941 #ifdef CONFIG_PM
942 .suspend = gspca_suspend,
943 .resume = gspca_resume,
944 .reset_resume = gspca_resume,
945 #endif
946 };
947
948 module_usb_driver(sd_driver);
This page took 0.119787 seconds and 6 git commands to generate.