Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
t613.c
Go to the documentation of this file.
1 /*
2  * T613 subdriver
3  *
4  * Copyright (C) 2010 Jean-Francois Moine (http://moinejf.free.fr)
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  *
20  *Notes: * t613 + tas5130A
21  * * Focus to light do not balance well as in win.
22  * Quality in win is not good, but its kinda better.
23  * * Fix some "extraneous bytes", most of apps will show the image anyway
24  * * Gamma table, is there, but its really doing something?
25  * * 7~8 Fps, its ok, max on win its 10.
26  * Costantino Leandro
27  */
28 
29 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
30 
31 #define MODULE_NAME "t613"
32 
33 #include <linux/input.h>
34 #include <linux/slab.h>
35 #include "gspca.h"
36 
37 MODULE_AUTHOR("Leandro Costantino <[email protected]>");
38 MODULE_DESCRIPTION("GSPCA/T613 (JPEG Compliance) USB Camera Driver");
39 MODULE_LICENSE("GPL");
40 
41 struct sd {
42  struct gspca_dev gspca_dev; /* !! must be the first item */
43  struct v4l2_ctrl *freq;
44  struct { /* awb / color gains control cluster */
45  struct v4l2_ctrl *awb;
46  struct v4l2_ctrl *gain;
47  struct v4l2_ctrl *red_balance;
48  struct v4l2_ctrl *blue_balance;
49  };
50 
51  u8 sensor;
53 };
54 enum sensors {
58  SENSOR_LT168G, /* must verify if this is the actual model */
59 };
60 
61 static const struct v4l2_pix_format vga_mode_t16[] = {
63  .bytesperline = 160,
64  .sizeimage = 160 * 120 * 4 / 8 + 590,
65  .colorspace = V4L2_COLORSPACE_JPEG,
66  .priv = 4},
67 #if 0 /* HDG: broken with my test cam, so lets disable it */
69  .bytesperline = 176,
70  .sizeimage = 176 * 144 * 3 / 8 + 590,
71  .colorspace = V4L2_COLORSPACE_JPEG,
72  .priv = 3},
73 #endif
75  .bytesperline = 320,
76  .sizeimage = 320 * 240 * 3 / 8 + 590,
77  .colorspace = V4L2_COLORSPACE_JPEG,
78  .priv = 2},
79 #if 0 /* HDG: broken with my test cam, so lets disable it */
81  .bytesperline = 352,
82  .sizeimage = 352 * 288 * 3 / 8 + 590,
83  .colorspace = V4L2_COLORSPACE_JPEG,
84  .priv = 1},
85 #endif
87  .bytesperline = 640,
88  .sizeimage = 640 * 480 * 3 / 8 + 590,
89  .colorspace = V4L2_COLORSPACE_JPEG,
90  .priv = 0},
91 };
92 
93 /* sensor specific data */
95  const u8 n3[6];
96  const u8 *n4, n4sz;
97  const u8 reg80, reg8e;
98  const u8 nset8[6];
99  const u8 data1[10];
100  const u8 data2[9];
101  const u8 data3[9];
102  const u8 data5[6];
103  const u8 stream[4];
104 };
105 
106 static const u8 n4_om6802[] = {
107  0x09, 0x01, 0x12, 0x04, 0x66, 0x8a, 0x80, 0x3c,
108  0x81, 0x22, 0x84, 0x50, 0x8a, 0x78, 0x8b, 0x68,
109  0x8c, 0x88, 0x8e, 0x33, 0x8f, 0x24, 0xaa, 0xb1,
110  0xa2, 0x60, 0xa5, 0x30, 0xa6, 0x3a, 0xa8, 0xe8,
111  0xae, 0x05, 0xb1, 0x00, 0xbb, 0x04, 0xbc, 0x48,
112  0xbe, 0x36, 0xc6, 0x88, 0xe9, 0x00, 0xc5, 0xc0,
113  0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68,
114  0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40,
115  0xac, 0x84, 0xad, 0x86, 0xaf, 0x46
116 };
117 static const u8 n4_other[] = {
118  0x66, 0x00, 0x7f, 0x00, 0x80, 0xac, 0x81, 0x69,
119  0x84, 0x40, 0x85, 0x70, 0x86, 0x20, 0x8a, 0x68,
120  0x8b, 0x58, 0x8c, 0x88, 0x8d, 0xff, 0x8e, 0xb8,
121  0x8f, 0x28, 0xa2, 0x60, 0xa5, 0x40, 0xa8, 0xa8,
122  0xac, 0x84, 0xad, 0x84, 0xae, 0x24, 0xaf, 0x56,
123  0xb0, 0x68, 0xb1, 0x00, 0xb2, 0x88, 0xbb, 0xc5,
124  0xbc, 0x4a, 0xbe, 0x36, 0xc2, 0x88, 0xc5, 0xc0,
125  0xc6, 0xda, 0xe9, 0x26, 0xeb, 0x00
126 };
127 static const u8 n4_tas5130a[] = {
128  0x80, 0x3c, 0x81, 0x68, 0x83, 0xa0, 0x84, 0x20,
129  0x8a, 0x68, 0x8b, 0x58, 0x8c, 0x88, 0x8e, 0xb4,
130  0x8f, 0x24, 0xa1, 0xb1, 0xa2, 0x30, 0xa5, 0x10,
131  0xa6, 0x4a, 0xae, 0x03, 0xb1, 0x44, 0xb2, 0x08,
132  0xb7, 0x06, 0xb9, 0xe7, 0xbb, 0xc4, 0xbc, 0x4a,
133  0xbe, 0x36, 0xbf, 0xff, 0xc2, 0x88, 0xc5, 0xc8,
134  0xc6, 0xda
135 };
136 static const u8 n4_lt168g[] = {
137  0x66, 0x01, 0x7f, 0x00, 0x80, 0x7c, 0x81, 0x28,
138  0x83, 0x44, 0x84, 0x20, 0x86, 0x20, 0x8a, 0x70,
139  0x8b, 0x58, 0x8c, 0x88, 0x8d, 0xa0, 0x8e, 0xb3,
140  0x8f, 0x24, 0xa1, 0xb0, 0xa2, 0x38, 0xa5, 0x20,
141  0xa6, 0x4a, 0xa8, 0xe8, 0xaf, 0x38, 0xb0, 0x68,
142  0xb1, 0x44, 0xb2, 0x88, 0xbb, 0x86, 0xbd, 0x40,
143  0xbe, 0x26, 0xc1, 0x05, 0xc2, 0x88, 0xc5, 0xc0,
144  0xda, 0x8e, 0xdb, 0xca, 0xdc, 0xa8, 0xdd, 0x8c,
145  0xde, 0x44, 0xdf, 0x0c, 0xe9, 0x80
146 };
147 
148 static const struct additional_sensor_data sensor_data[] = {
149 [SENSOR_OM6802] = {
150  .n3 =
151  {0x61, 0x68, 0x65, 0x0a, 0x60, 0x04},
152  .n4 = n4_om6802,
153  .n4sz = sizeof n4_om6802,
154  .reg80 = 0x3c,
155  .reg8e = 0x33,
156  .nset8 = {0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00},
157  .data1 =
158  {0xc2, 0x28, 0x0f, 0x22, 0xcd, 0x27, 0x2c, 0x06,
159  0xb3, 0xfc},
160  .data2 =
161  {0x80, 0xff, 0xff, 0x80, 0xff, 0xff, 0x80, 0xff,
162  0xff},
163  .data3 =
164  {0x80, 0xff, 0xff, 0x80, 0xff, 0xff, 0x80, 0xff,
165  0xff},
166  .data5 = /* this could be removed later */
167  {0x0c, 0x03, 0xab, 0x13, 0x81, 0x23},
168  .stream =
169  {0x0b, 0x04, 0x0a, 0x78},
170  },
171 [SENSOR_OTHER] = {
172  .n3 =
173  {0x61, 0xc2, 0x65, 0x88, 0x60, 0x00},
174  .n4 = n4_other,
175  .n4sz = sizeof n4_other,
176  .reg80 = 0xac,
177  .reg8e = 0xb8,
178  .nset8 = {0xa8, 0xa8, 0xc6, 0xda, 0xc0, 0x00},
179  .data1 =
180  {0xc1, 0x48, 0x04, 0x1b, 0xca, 0x2e, 0x33, 0x3a,
181  0xe8, 0xfc},
182  .data2 =
183  {0x4e, 0x9c, 0xec, 0x40, 0x80, 0xc0, 0x48, 0x96,
184  0xd9},
185  .data3 =
186  {0x4e, 0x9c, 0xec, 0x40, 0x80, 0xc0, 0x48, 0x96,
187  0xd9},
188  .data5 =
189  {0x0c, 0x03, 0xab, 0x29, 0x81, 0x69},
190  .stream =
191  {0x0b, 0x04, 0x0a, 0x00},
192  },
193 [SENSOR_TAS5130A] = {
194  .n3 =
195  {0x61, 0xc2, 0x65, 0x0d, 0x60, 0x08},
196  .n4 = n4_tas5130a,
197  .n4sz = sizeof n4_tas5130a,
198  .reg80 = 0x3c,
199  .reg8e = 0xb4,
200  .nset8 = {0xa8, 0xf0, 0xc6, 0xda, 0xc0, 0x00},
201  .data1 =
202  {0xbb, 0x28, 0x10, 0x10, 0xbb, 0x28, 0x1e, 0x27,
203  0xc8, 0xfc},
204  .data2 =
205  {0x60, 0xa8, 0xe0, 0x60, 0xa8, 0xe0, 0x60, 0xa8,
206  0xe0},
207  .data3 =
208  {0x60, 0xa8, 0xe0, 0x60, 0xa8, 0xe0, 0x60, 0xa8,
209  0xe0},
210  .data5 =
211  {0x0c, 0x03, 0xab, 0x10, 0x81, 0x20},
212  .stream =
213  {0x0b, 0x04, 0x0a, 0x40},
214  },
215 [SENSOR_LT168G] = {
216  .n3 = {0x61, 0xc2, 0x65, 0x68, 0x60, 0x00},
217  .n4 = n4_lt168g,
218  .n4sz = sizeof n4_lt168g,
219  .reg80 = 0x7c,
220  .reg8e = 0xb3,
221  .nset8 = {0xa8, 0xf0, 0xc6, 0xba, 0xc0, 0x00},
222  .data1 = {0xc0, 0x38, 0x08, 0x10, 0xc0, 0x30, 0x10, 0x40,
223  0xb0, 0xf4},
224  .data2 = {0x40, 0x80, 0xc0, 0x50, 0xa0, 0xf0, 0x53, 0xa6,
225  0xff},
226  .data3 = {0x40, 0x80, 0xc0, 0x50, 0xa0, 0xf0, 0x53, 0xa6,
227  0xff},
228  .data5 = {0x0c, 0x03, 0xab, 0x4b, 0x81, 0x2b},
229  .stream = {0x0b, 0x04, 0x0a, 0x28},
230  },
231 };
232 
233 #define MAX_EFFECTS 7
234 static const u8 effects_table[MAX_EFFECTS][6] = {
235  {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x00}, /* Normal */
236  {0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x04}, /* Repujar */
237  {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x20}, /* Monochrome */
238  {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x80}, /* Sepia */
239  {0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x02}, /* Croquis */
240  {0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x10}, /* Sun Effect */
241  {0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x40}, /* Negative */
242 };
243 
244 #define GAMMA_MAX (15)
245 static const u8 gamma_table[GAMMA_MAX+1][17] = {
246 /* gamma table from cam1690.ini */
247  {0x00, 0x00, 0x01, 0x04, 0x08, 0x0e, 0x16, 0x21, /* 0 */
248  0x2e, 0x3d, 0x50, 0x65, 0x7d, 0x99, 0xb8, 0xdb,
249  0xff},
250  {0x00, 0x01, 0x03, 0x08, 0x0e, 0x16, 0x21, 0x2d, /* 1 */
251  0x3c, 0x4d, 0x60, 0x75, 0x8d, 0xa6, 0xc2, 0xe1,
252  0xff},
253  {0x00, 0x01, 0x05, 0x0b, 0x12, 0x1c, 0x28, 0x35, /* 2 */
254  0x45, 0x56, 0x69, 0x7e, 0x95, 0xad, 0xc7, 0xe3,
255  0xff},
256  {0x00, 0x02, 0x07, 0x0f, 0x18, 0x24, 0x30, 0x3f, /* 3 */
257  0x4f, 0x61, 0x73, 0x88, 0x9d, 0xb4, 0xcd, 0xe6,
258  0xff},
259  {0x00, 0x04, 0x0b, 0x15, 0x20, 0x2d, 0x3b, 0x4a, /* 4 */
260  0x5b, 0x6c, 0x7f, 0x92, 0xa7, 0xbc, 0xd2, 0xe9,
261  0xff},
262  {0x00, 0x07, 0x11, 0x15, 0x20, 0x2d, 0x48, 0x58, /* 5 */
263  0x68, 0x79, 0x8b, 0x9d, 0xb0, 0xc4, 0xd7, 0xec,
264  0xff},
265  {0x00, 0x0c, 0x1a, 0x29, 0x38, 0x47, 0x57, 0x67, /* 6 */
266  0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee,
267  0xff},
268  {0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, /* 7 */
269  0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0,
270  0xff},
271  {0x00, 0x15, 0x27, 0x38, 0x49, 0x59, 0x69, 0x79, /* 8 */
272  0x88, 0x97, 0xa7, 0xb6, 0xc4, 0xd3, 0xe2, 0xf0,
273  0xff},
274  {0x00, 0x1c, 0x30, 0x43, 0x54, 0x65, 0x75, 0x84, /* 9 */
275  0x93, 0xa1, 0xb0, 0xbd, 0xca, 0xd8, 0xe5, 0xf2,
276  0xff},
277  {0x00, 0x24, 0x3b, 0x4f, 0x60, 0x70, 0x80, 0x8e, /* 10 */
278  0x9c, 0xaa, 0xb7, 0xc4, 0xd0, 0xdc, 0xe8, 0xf3,
279  0xff},
280  {0x00, 0x2a, 0x3c, 0x5d, 0x6e, 0x7e, 0x8d, 0x9b, /* 11 */
281  0xa8, 0xb4, 0xc0, 0xcb, 0xd6, 0xe1, 0xeb, 0xf5,
282  0xff},
283  {0x00, 0x3f, 0x5a, 0x6e, 0x7f, 0x8e, 0x9c, 0xa8, /* 12 */
284  0xb4, 0xbf, 0xc9, 0xd3, 0xdc, 0xe5, 0xee, 0xf6,
285  0xff},
286  {0x00, 0x54, 0x6f, 0x83, 0x93, 0xa0, 0xad, 0xb7, /* 13 */
287  0xc2, 0xcb, 0xd4, 0xdc, 0xe4, 0xeb, 0xf2, 0xf9,
288  0xff},
289  {0x00, 0x6e, 0x88, 0x9a, 0xa8, 0xb3, 0xbd, 0xc6, /* 14 */
290  0xcf, 0xd6, 0xdd, 0xe3, 0xe9, 0xef, 0xf4, 0xfa,
291  0xff},
292  {0x00, 0x93, 0xa8, 0xb7, 0xc1, 0xca, 0xd2, 0xd8, /* 15 */
293  0xde, 0xe3, 0xe8, 0xed, 0xf1, 0xf5, 0xf8, 0xfc,
294  0xff}
295 };
296 
297 static const u8 tas5130a_sensor_init[][8] = {
298  {0x62, 0x08, 0x63, 0x70, 0x64, 0x1d, 0x60, 0x09},
299  {0x62, 0x20, 0x63, 0x01, 0x64, 0x02, 0x60, 0x09},
300  {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09},
301 };
302 
303 static u8 sensor_reset[] = {0x61, 0x68, 0x62, 0xff, 0x60, 0x07};
304 
305 /* read 1 byte */
306 static u8 reg_r(struct gspca_dev *gspca_dev,
307  u16 index)
308 {
309  usb_control_msg(gspca_dev->dev,
310  usb_rcvctrlpipe(gspca_dev->dev, 0),
311  0, /* request */
313  0, /* value */
314  index,
315  gspca_dev->usb_buf, 1, 500);
316  return gspca_dev->usb_buf[0];
317 }
318 
319 static void reg_w(struct gspca_dev *gspca_dev,
320  u16 index)
321 {
322  usb_control_msg(gspca_dev->dev,
323  usb_sndctrlpipe(gspca_dev->dev, 0),
324  0,
326  0, index,
327  NULL, 0, 500);
328 }
329 
330 static void reg_w_buf(struct gspca_dev *gspca_dev,
331  const u8 *buffer, u16 len)
332 {
333  if (len <= USB_BUF_SZ) {
334  memcpy(gspca_dev->usb_buf, buffer, len);
335  usb_control_msg(gspca_dev->dev,
336  usb_sndctrlpipe(gspca_dev->dev, 0),
337  0,
339  0x01, 0,
340  gspca_dev->usb_buf, len, 500);
341  } else {
342  u8 *tmpbuf;
343 
344  tmpbuf = kmemdup(buffer, len, GFP_KERNEL);
345  if (!tmpbuf) {
346  pr_err("Out of memory\n");
347  return;
348  }
349  usb_control_msg(gspca_dev->dev,
350  usb_sndctrlpipe(gspca_dev->dev, 0),
351  0,
353  0x01, 0,
354  tmpbuf, len, 500);
355  kfree(tmpbuf);
356  }
357 }
358 
359 /* write values to consecutive registers */
360 static void reg_w_ixbuf(struct gspca_dev *gspca_dev,
361  u8 reg,
362  const u8 *buffer, u16 len)
363 {
364  int i;
365  u8 *p, *tmpbuf;
366 
367  if (len * 2 <= USB_BUF_SZ) {
368  p = tmpbuf = gspca_dev->usb_buf;
369  } else {
370  p = tmpbuf = kmalloc(len * 2, GFP_KERNEL);
371  if (!tmpbuf) {
372  pr_err("Out of memory\n");
373  return;
374  }
375  }
376  i = len;
377  while (--i >= 0) {
378  *p++ = reg++;
379  *p++ = *buffer++;
380  }
381  usb_control_msg(gspca_dev->dev,
382  usb_sndctrlpipe(gspca_dev->dev, 0),
383  0,
385  0x01, 0,
386  tmpbuf, len * 2, 500);
387  if (len * 2 > USB_BUF_SZ)
388  kfree(tmpbuf);
389 }
390 
391 static void om6802_sensor_init(struct gspca_dev *gspca_dev)
392 {
393  int i;
394  const u8 *p;
395  u8 byte;
396  u8 val[6] = {0x62, 0, 0x64, 0, 0x60, 0x05};
397  static const u8 sensor_init[] = {
398  0xdf, 0x6d,
399  0xdd, 0x18,
400  0x5a, 0xe0,
401  0x5c, 0x07,
402  0x5d, 0xb0,
403  0x5e, 0x1e,
404  0x60, 0x71,
405  0xef, 0x00,
406  0xe9, 0x00,
407  0xea, 0x00,
408  0x90, 0x24,
409  0x91, 0xb2,
410  0x82, 0x32,
411  0xfd, 0x41,
412  0x00 /* table end */
413  };
414 
415  reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset);
416  msleep(100);
417  i = 4;
418  while (--i > 0) {
419  byte = reg_r(gspca_dev, 0x0060);
420  if (!(byte & 0x01))
421  break;
422  msleep(100);
423  }
424  byte = reg_r(gspca_dev, 0x0063);
425  if (byte != 0x17) {
426  pr_err("Bad sensor reset %02x\n", byte);
427  /* continue? */
428  }
429 
430  p = sensor_init;
431  while (*p != 0) {
432  val[1] = *p++;
433  val[3] = *p++;
434  if (*p == 0)
435  reg_w(gspca_dev, 0x3c80);
436  reg_w_buf(gspca_dev, val, sizeof val);
437  i = 4;
438  while (--i >= 0) {
439  msleep(15);
440  byte = reg_r(gspca_dev, 0x60);
441  if (!(byte & 0x01))
442  break;
443  }
444  }
445  msleep(15);
446  reg_w(gspca_dev, 0x3c80);
447 }
448 
449 /* this function is called at probe time */
450 static int sd_config(struct gspca_dev *gspca_dev,
451  const struct usb_device_id *id)
452 {
453  struct cam *cam = &gspca_dev->cam;
454 
455  cam->cam_mode = vga_mode_t16;
456  cam->nmodes = ARRAY_SIZE(vga_mode_t16);
457 
458  return 0;
459 }
460 
461 static void setbrightness(struct gspca_dev *gspca_dev, s32 brightness)
462 {
463  u8 set6[4] = { 0x8f, 0x24, 0xc3, 0x00 };
464 
465  if (brightness < 7) {
466  set6[1] = 0x26;
467  set6[3] = 0x70 - brightness * 0x10;
468  } else {
469  set6[3] = 0x00 + ((brightness - 7) * 0x10);
470  }
471 
472  reg_w_buf(gspca_dev, set6, sizeof set6);
473 }
474 
475 static void setcontrast(struct gspca_dev *gspca_dev, s32 contrast)
476 {
477  u16 reg_to_write;
478 
479  if (contrast < 7)
480  reg_to_write = 0x8ea9 - contrast * 0x200;
481  else
482  reg_to_write = 0x00a9 + (contrast - 7) * 0x200;
483 
484  reg_w(gspca_dev, reg_to_write);
485 }
486 
487 static void setcolors(struct gspca_dev *gspca_dev, s32 val)
488 {
489  u16 reg_to_write;
490 
491  reg_to_write = 0x80bb + val * 0x100; /* was 0xc0 */
492  reg_w(gspca_dev, reg_to_write);
493 }
494 
495 static void setgamma(struct gspca_dev *gspca_dev, s32 val)
496 {
497  PDEBUG(D_CONF, "Gamma: %d", sd->gamma);
498  reg_w_ixbuf(gspca_dev, 0x90,
499  gamma_table[val], sizeof gamma_table[0]);
500 }
501 
502 static void setawb_n_RGB(struct gspca_dev *gspca_dev)
503 {
504  struct sd *sd = (struct sd *) gspca_dev;
505  u8 all_gain_reg[8] = {
506  0x87, 0x00, 0x88, 0x00, 0x89, 0x00, 0x80, 0x00 };
507  s32 red_gain, blue_gain, green_gain;
508 
509  green_gain = sd->gain->val;
510 
511  red_gain = green_gain + sd->red_balance->val;
512  if (red_gain > 0x40)
513  red_gain = 0x40;
514  else if (red_gain < 0x10)
515  red_gain = 0x10;
516 
517  blue_gain = green_gain + sd->blue_balance->val;
518  if (blue_gain > 0x40)
519  blue_gain = 0x40;
520  else if (blue_gain < 0x10)
521  blue_gain = 0x10;
522 
523  all_gain_reg[1] = red_gain;
524  all_gain_reg[3] = blue_gain;
525  all_gain_reg[5] = green_gain;
526  all_gain_reg[7] = sensor_data[sd->sensor].reg80;
527  if (!sd->awb->val)
528  all_gain_reg[7] &= ~0x04; /* AWB off */
529 
530  reg_w_buf(gspca_dev, all_gain_reg, sizeof all_gain_reg);
531 }
532 
533 static void setsharpness(struct gspca_dev *gspca_dev, s32 val)
534 {
535  u16 reg_to_write;
536 
537  reg_to_write = 0x0aa6 + 0x1000 * val;
538 
539  reg_w(gspca_dev, reg_to_write);
540 }
541 
542 static void setfreq(struct gspca_dev *gspca_dev, s32 val)
543 {
544  struct sd *sd = (struct sd *) gspca_dev;
545  u8 reg66;
546  u8 freq[4] = { 0x66, 0x00, 0xa8, 0xe8 };
547 
548  switch (sd->sensor) {
549  case SENSOR_LT168G:
550  if (val != 0)
551  freq[3] = 0xa8;
552  reg66 = 0x41;
553  break;
554  case SENSOR_OM6802:
555  reg66 = 0xca;
556  break;
557  default:
558  reg66 = 0x40;
559  break;
560  }
561  switch (val) {
562  case 0: /* no flicker */
563  freq[3] = 0xf0;
564  break;
565  case 2: /* 60Hz */
566  reg66 &= ~0x40;
567  break;
568  }
569  freq[1] = reg66;
570 
571  reg_w_buf(gspca_dev, freq, sizeof freq);
572 }
573 
574 /* this function is called at probe and resume time */
575 static int sd_init(struct gspca_dev *gspca_dev)
576 {
577  /* some of this registers are not really neded, because
578  * they are overriden by setbrigthness, setcontrast, etc,
579  * but wont hurt anyway, and can help someone with similar webcam
580  * to see the initial parameters.*/
581  struct sd *sd = (struct sd *) gspca_dev;
582  const struct additional_sensor_data *sensor;
583  int i;
584  u16 sensor_id;
585  u8 test_byte = 0;
586 
587  static const u8 read_indexs[] =
588  { 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5,
589  0xa6, 0xa8, 0xbb, 0xbc, 0xc6, 0x00 };
590  static const u8 n1[] =
591  {0x08, 0x03, 0x09, 0x03, 0x12, 0x04};
592  static const u8 n2[] =
593  {0x08, 0x00};
594 
595  sensor_id = (reg_r(gspca_dev, 0x06) << 8)
596  | reg_r(gspca_dev, 0x07);
597  switch (sensor_id & 0xff0f) {
598  case 0x0801:
599  PDEBUG(D_PROBE, "sensor tas5130a");
600  sd->sensor = SENSOR_TAS5130A;
601  break;
602  case 0x0802:
603  PDEBUG(D_PROBE, "sensor lt168g");
604  sd->sensor = SENSOR_LT168G;
605  break;
606  case 0x0803:
607  PDEBUG(D_PROBE, "sensor 'other'");
608  sd->sensor = SENSOR_OTHER;
609  break;
610  case 0x0807:
611  PDEBUG(D_PROBE, "sensor om6802");
612  sd->sensor = SENSOR_OM6802;
613  break;
614  default:
615  pr_err("unknown sensor %04x\n", sensor_id);
616  return -EINVAL;
617  }
618 
619  if (sd->sensor == SENSOR_OM6802) {
620  reg_w_buf(gspca_dev, n1, sizeof n1);
621  i = 5;
622  while (--i >= 0) {
623  reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset);
624  test_byte = reg_r(gspca_dev, 0x0063);
625  msleep(100);
626  if (test_byte == 0x17)
627  break; /* OK */
628  }
629  if (i < 0) {
630  pr_err("Bad sensor reset %02x\n", test_byte);
631  return -EIO;
632  }
633  reg_w_buf(gspca_dev, n2, sizeof n2);
634  }
635 
636  i = 0;
637  while (read_indexs[i] != 0x00) {
638  test_byte = reg_r(gspca_dev, read_indexs[i]);
639  PDEBUG(D_STREAM, "Reg 0x%02x = 0x%02x", read_indexs[i],
640  test_byte);
641  i++;
642  }
643 
644  sensor = &sensor_data[sd->sensor];
645  reg_w_buf(gspca_dev, sensor->n3, sizeof sensor->n3);
646  reg_w_buf(gspca_dev, sensor->n4, sensor->n4sz);
647 
648  if (sd->sensor == SENSOR_LT168G) {
649  test_byte = reg_r(gspca_dev, 0x80);
650  PDEBUG(D_STREAM, "Reg 0x%02x = 0x%02x", 0x80,
651  test_byte);
652  reg_w(gspca_dev, 0x6c80);
653  }
654 
655  reg_w_ixbuf(gspca_dev, 0xd0, sensor->data1, sizeof sensor->data1);
656  reg_w_ixbuf(gspca_dev, 0xc7, sensor->data2, sizeof sensor->data2);
657  reg_w_ixbuf(gspca_dev, 0xe0, sensor->data3, sizeof sensor->data3);
658 
659  reg_w(gspca_dev, (sensor->reg80 << 8) + 0x80);
660  reg_w(gspca_dev, (sensor->reg80 << 8) + 0x80);
661  reg_w(gspca_dev, (sensor->reg8e << 8) + 0x8e);
662  reg_w(gspca_dev, (0x20 << 8) + 0x87);
663  reg_w(gspca_dev, (0x20 << 8) + 0x88);
664  reg_w(gspca_dev, (0x20 << 8) + 0x89);
665 
666  reg_w_buf(gspca_dev, sensor->data5, sizeof sensor->data5);
667  reg_w_buf(gspca_dev, sensor->nset8, sizeof sensor->nset8);
668  reg_w_buf(gspca_dev, sensor->stream, sizeof sensor->stream);
669 
670  if (sd->sensor == SENSOR_LT168G) {
671  test_byte = reg_r(gspca_dev, 0x80);
672  PDEBUG(D_STREAM, "Reg 0x%02x = 0x%02x", 0x80,
673  test_byte);
674  reg_w(gspca_dev, 0x6c80);
675  }
676 
677  reg_w_ixbuf(gspca_dev, 0xd0, sensor->data1, sizeof sensor->data1);
678  reg_w_ixbuf(gspca_dev, 0xc7, sensor->data2, sizeof sensor->data2);
679  reg_w_ixbuf(gspca_dev, 0xe0, sensor->data3, sizeof sensor->data3);
680 
681  return 0;
682 }
683 
684 static void setmirror(struct gspca_dev *gspca_dev, s32 val)
685 {
686  u8 hflipcmd[8] =
687  {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09};
688 
689  if (val)
690  hflipcmd[3] = 0x01;
691 
692  reg_w_buf(gspca_dev, hflipcmd, sizeof hflipcmd);
693 }
694 
695 static void seteffect(struct gspca_dev *gspca_dev, s32 val)
696 {
697  int idx = 0;
698 
699  switch (val) {
700  case V4L2_COLORFX_NONE:
701  break;
702  case V4L2_COLORFX_BW:
703  idx = 2;
704  break;
705  case V4L2_COLORFX_SEPIA:
706  idx = 3;
707  break;
708  case V4L2_COLORFX_SKETCH:
709  idx = 4;
710  break;
712  idx = 6;
713  break;
714  default:
715  break;
716  }
717 
718  reg_w_buf(gspca_dev, effects_table[idx],
719  sizeof effects_table[0]);
720 
721  if (val == V4L2_COLORFX_SKETCH)
722  reg_w(gspca_dev, 0x4aa6);
723  else
724  reg_w(gspca_dev, 0xfaa6);
725 }
726 
727 /* Is this really needed?
728  * i added some module parameters for test with some users */
729 static void poll_sensor(struct gspca_dev *gspca_dev)
730 {
731  static const u8 poll1[] =
732  {0x67, 0x05, 0x68, 0x81, 0x69, 0x80, 0x6a, 0x82,
733  0x6b, 0x68, 0x6c, 0x69, 0x72, 0xd9, 0x73, 0x34,
734  0x74, 0x32, 0x75, 0x92, 0x76, 0x00, 0x09, 0x01,
735  0x60, 0x14};
736  static const u8 poll2[] =
737  {0x67, 0x02, 0x68, 0x71, 0x69, 0x72, 0x72, 0xa9,
738  0x73, 0x02, 0x73, 0x02, 0x60, 0x14};
739  static const u8 noise03[] = /* (some differences / ms-drv) */
740  {0xa6, 0x0a, 0xea, 0xcf, 0xbe, 0x26, 0xb1, 0x5f,
741  0xa1, 0xb1, 0xda, 0x6b, 0xdb, 0x98, 0xdf, 0x0c,
742  0xc2, 0x80, 0xc3, 0x10};
743 
744  PDEBUG(D_STREAM, "[Sensor requires polling]");
745  reg_w_buf(gspca_dev, poll1, sizeof poll1);
746  reg_w_buf(gspca_dev, poll2, sizeof poll2);
747  reg_w_buf(gspca_dev, noise03, sizeof noise03);
748 }
749 
750 static int sd_start(struct gspca_dev *gspca_dev)
751 {
752  struct sd *sd = (struct sd *) gspca_dev;
753  const struct additional_sensor_data *sensor;
754  int i, mode;
755  u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 };
756  static const u8 t3[] =
757  { 0x07, 0x00, 0x88, 0x02, 0x06, 0x00, 0xe7, 0x01 };
758 
759  mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
760  switch (mode) {
761  case 0: /* 640x480 (0x00) */
762  break;
763  case 1: /* 352x288 */
764  t2[1] = 0x40;
765  break;
766  case 2: /* 320x240 */
767  t2[1] = 0x10;
768  break;
769  case 3: /* 176x144 */
770  t2[1] = 0x50;
771  break;
772  default:
773 /* case 4: * 160x120 */
774  t2[1] = 0x20;
775  break;
776  }
777 
778  switch (sd->sensor) {
779  case SENSOR_OM6802:
780  om6802_sensor_init(gspca_dev);
781  break;
782  case SENSOR_TAS5130A:
783  i = 0;
784  for (;;) {
785  reg_w_buf(gspca_dev, tas5130a_sensor_init[i],
786  sizeof tas5130a_sensor_init[0]);
787  if (i >= ARRAY_SIZE(tas5130a_sensor_init) - 1)
788  break;
789  i++;
790  }
791  reg_w(gspca_dev, 0x3c80);
792  /* just in case and to keep sync with logs (for mine) */
793  reg_w_buf(gspca_dev, tas5130a_sensor_init[i],
794  sizeof tas5130a_sensor_init[0]);
795  reg_w(gspca_dev, 0x3c80);
796  break;
797  }
798  sensor = &sensor_data[sd->sensor];
799  setfreq(gspca_dev, v4l2_ctrl_g_ctrl(sd->freq));
800  reg_r(gspca_dev, 0x0012);
801  reg_w_buf(gspca_dev, t2, sizeof t2);
802  reg_w_ixbuf(gspca_dev, 0xb3, t3, sizeof t3);
803  reg_w(gspca_dev, 0x0013);
804  msleep(15);
805  reg_w_buf(gspca_dev, sensor->stream, sizeof sensor->stream);
806  reg_w_buf(gspca_dev, sensor->stream, sizeof sensor->stream);
807 
808  if (sd->sensor == SENSOR_OM6802)
809  poll_sensor(gspca_dev);
810 
811  return 0;
812 }
813 
814 static void sd_stopN(struct gspca_dev *gspca_dev)
815 {
816  struct sd *sd = (struct sd *) gspca_dev;
817 
818  reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
819  sizeof sensor_data[sd->sensor].stream);
820  reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
821  sizeof sensor_data[sd->sensor].stream);
822  if (sd->sensor == SENSOR_OM6802) {
823  msleep(20);
824  reg_w(gspca_dev, 0x0309);
825  }
826 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
827  /* If the last button state is pressed, release it now! */
828  if (sd->button_pressed) {
829  input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
830  input_sync(gspca_dev->input_dev);
831  sd->button_pressed = 0;
832  }
833 #endif
834 }
835 
836 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
837  u8 *data, /* isoc packet */
838  int len) /* iso packet length */
839 {
840  struct sd *sd = (struct sd *) gspca_dev;
841  int pkt_type;
842 
843  if (data[0] == 0x5a) {
844 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
845  if (len > 20) {
846  u8 state = (data[20] & 0x80) ? 1 : 0;
847  if (sd->button_pressed != state) {
848  input_report_key(gspca_dev->input_dev,
849  KEY_CAMERA, state);
850  input_sync(gspca_dev->input_dev);
851  sd->button_pressed = state;
852  }
853  }
854 #endif
855  /* Control Packet, after this came the header again,
856  * but extra bytes came in the packet before this,
857  * sometimes an EOF arrives, sometimes not... */
858  return;
859  }
860  data += 2;
861  len -= 2;
862  if (data[0] == 0xff && data[1] == 0xd8)
863  pkt_type = FIRST_PACKET;
864  else if (data[len - 2] == 0xff && data[len - 1] == 0xd9)
865  pkt_type = LAST_PACKET;
866  else
867  pkt_type = INTER_PACKET;
868  gspca_frame_add(gspca_dev, pkt_type, data, len);
869 }
870 
871 static int sd_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
872 {
873  struct gspca_dev *gspca_dev =
874  container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
875  struct sd *sd = (struct sd *)gspca_dev;
876  s32 red_gain, blue_gain, green_gain;
877 
878  gspca_dev->usb_err = 0;
879 
880  switch (ctrl->id) {
882  red_gain = reg_r(gspca_dev, 0x0087);
883  if (red_gain > 0x40)
884  red_gain = 0x40;
885  else if (red_gain < 0x10)
886  red_gain = 0x10;
887 
888  blue_gain = reg_r(gspca_dev, 0x0088);
889  if (blue_gain > 0x40)
890  blue_gain = 0x40;
891  else if (blue_gain < 0x10)
892  blue_gain = 0x10;
893 
894  green_gain = reg_r(gspca_dev, 0x0089);
895  if (green_gain > 0x40)
896  green_gain = 0x40;
897  else if (green_gain < 0x10)
898  green_gain = 0x10;
899 
900  sd->gain->val = green_gain;
901  sd->red_balance->val = red_gain - green_gain;
902  sd->blue_balance->val = blue_gain - green_gain;
903  break;
904  }
905  return 0;
906 }
907 
908 static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
909 {
910  struct gspca_dev *gspca_dev =
911  container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
912 
913  gspca_dev->usb_err = 0;
914 
915  if (!gspca_dev->streaming)
916  return 0;
917 
918  switch (ctrl->id) {
919  case V4L2_CID_BRIGHTNESS:
920  setbrightness(gspca_dev, ctrl->val);
921  break;
922  case V4L2_CID_CONTRAST:
923  setcontrast(gspca_dev, ctrl->val);
924  break;
925  case V4L2_CID_SATURATION:
926  setcolors(gspca_dev, ctrl->val);
927  break;
928  case V4L2_CID_GAMMA:
929  setgamma(gspca_dev, ctrl->val);
930  break;
931  case V4L2_CID_HFLIP:
932  setmirror(gspca_dev, ctrl->val);
933  break;
934  case V4L2_CID_SHARPNESS:
935  setsharpness(gspca_dev, ctrl->val);
936  break;
938  setfreq(gspca_dev, ctrl->val);
939  break;
941  reg_w(gspca_dev, ctrl->val ? 0xf48e : 0xb48e);
942  break;
944  setawb_n_RGB(gspca_dev);
945  break;
946  case V4L2_CID_COLORFX:
947  seteffect(gspca_dev, ctrl->val);
948  break;
949  }
950  return gspca_dev->usb_err;
951 }
952 
953 static const struct v4l2_ctrl_ops sd_ctrl_ops = {
954  .g_volatile_ctrl = sd_g_volatile_ctrl,
955  .s_ctrl = sd_s_ctrl,
956 };
957 
958 static int sd_init_controls(struct gspca_dev *gspca_dev)
959 {
960  struct sd *sd = (struct sd *)gspca_dev;
961  struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
962 
963  gspca_dev->vdev.ctrl_handler = hdl;
964  v4l2_ctrl_handler_init(hdl, 12);
965  v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
966  V4L2_CID_BRIGHTNESS, 0, 14, 1, 8);
967  v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
968  V4L2_CID_CONTRAST, 0, 0x0d, 1, 7);
969  v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
970  V4L2_CID_SATURATION, 0, 0xf, 1, 5);
971  v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
972  V4L2_CID_GAMMA, 0, GAMMA_MAX, 1, 10);
973  /* Activate lowlight, some apps dont bring up the
974  backlight_compensation control) */
975  v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
976  V4L2_CID_BACKLIGHT_COMPENSATION, 0, 1, 1, 1);
977  if (sd->sensor == SENSOR_TAS5130A)
978  v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
979  V4L2_CID_HFLIP, 0, 1, 1, 0);
980  sd->awb = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
981  V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 1);
982  sd->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
983  V4L2_CID_GAIN, 0x10, 0x40, 1, 0x20);
984  sd->blue_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
985  V4L2_CID_BLUE_BALANCE, -0x30, 0x30, 1, 0);
986  sd->red_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
987  V4L2_CID_RED_BALANCE, -0x30, 0x30, 1, 0);
988  v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
989  V4L2_CID_SHARPNESS, 0, 15, 1, 6);
990  v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops,
992  ~((1 << V4L2_COLORFX_NONE) |
993  (1 << V4L2_COLORFX_BW) |
994  (1 << V4L2_COLORFX_SEPIA) |
995  (1 << V4L2_COLORFX_SKETCH) |
996  (1 << V4L2_COLORFX_NEGATIVE)),
998  sd->freq = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops,
1002 
1003  if (hdl->error) {
1004  pr_err("Could not initialize controls\n");
1005  return hdl->error;
1006  }
1007 
1008  v4l2_ctrl_auto_cluster(4, &sd->awb, 0, true);
1009 
1010  return 0;
1011 }
1012 
1013 /* sub-driver description */
1014 static const struct sd_desc sd_desc = {
1015  .name = MODULE_NAME,
1016  .config = sd_config,
1017  .init = sd_init,
1018  .init_controls = sd_init_controls,
1019  .start = sd_start,
1020  .stopN = sd_stopN,
1021  .pkt_scan = sd_pkt_scan,
1022 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
1023  .other_input = 1,
1024 #endif
1025 };
1026 
1027 /* -- module initialisation -- */
1028 static const struct usb_device_id device_table[] = {
1029  {USB_DEVICE(0x17a1, 0x0128)},
1030  {}
1031 };
1032 MODULE_DEVICE_TABLE(usb, device_table);
1033 
1034 /* -- device connect -- */
1035 static int sd_probe(struct usb_interface *intf,
1036  const struct usb_device_id *id)
1037 {
1038  return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1039  THIS_MODULE);
1040 }
1041 
1042 static struct usb_driver sd_driver = {
1043  .name = MODULE_NAME,
1044  .id_table = device_table,
1045  .probe = sd_probe,
1046  .disconnect = gspca_disconnect,
1047 #ifdef CONFIG_PM
1048  .suspend = gspca_suspend,
1049  .resume = gspca_resume,
1050  .reset_resume = gspca_resume,
1051 #endif
1052 };
1053 
1054 module_usb_driver(sd_driver);