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