PM / sleep: Asynchronous threads for suspend_noirq
[linux/fpc-iii.git] / drivers / media / usb / gspca / t613.c
blobe2cc4e5a0ccb77dce361f3cdc20517e7283394d1
1 /*
2 * T613 subdriver
4 * Copyright (C) 2010 Jean-Francois Moine (http://moinejf.free.fr)
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.
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.
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
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
29 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
31 #define MODULE_NAME "t613"
33 #include <linux/input.h>
34 #include <linux/slab.h>
35 #include "gspca.h"
37 MODULE_AUTHOR("Leandro Costantino <le_costantino@pixartargentina.com.ar>");
38 MODULE_DESCRIPTION("GSPCA/T613 (JPEG Compliance) USB Camera Driver");
39 MODULE_LICENSE("GPL");
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;
51 u8 sensor;
52 u8 button_pressed;
54 enum sensors {
55 SENSOR_OM6802,
56 SENSOR_OTHER,
57 SENSOR_TAS5130A,
58 SENSOR_LT168G, /* must verify if this is the actual model */
61 static const struct v4l2_pix_format vga_mode_t16[] = {
62 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
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 */
68 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
69 .bytesperline = 176,
70 .sizeimage = 176 * 144 * 3 / 8 + 590,
71 .colorspace = V4L2_COLORSPACE_JPEG,
72 .priv = 3},
73 #endif
74 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
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 */
80 {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
81 .bytesperline = 352,
82 .sizeimage = 352 * 288 * 3 / 8 + 590,
83 .colorspace = V4L2_COLORSPACE_JPEG,
84 .priv = 1},
85 #endif
86 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
87 .bytesperline = 640,
88 .sizeimage = 640 * 480 * 3 / 8 + 590,
89 .colorspace = V4L2_COLORSPACE_JPEG,
90 .priv = 0},
93 /* sensor specific data */
94 struct additional_sensor_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];
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
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
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
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
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},
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},
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},
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},
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 */
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}
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},
303 static u8 sensor_reset[] = {0x61, 0x68, 0x62, 0xff, 0x60, 0x07};
305 /* read 1 byte */
306 static u8 reg_r(struct gspca_dev *gspca_dev,
307 u16 index)
309 usb_control_msg(gspca_dev->dev,
310 usb_rcvctrlpipe(gspca_dev->dev, 0),
311 0, /* request */
312 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
313 0, /* value */
314 index,
315 gspca_dev->usb_buf, 1, 500);
316 return gspca_dev->usb_buf[0];
319 static void reg_w(struct gspca_dev *gspca_dev,
320 u16 index)
322 usb_control_msg(gspca_dev->dev,
323 usb_sndctrlpipe(gspca_dev->dev, 0),
325 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
326 0, index,
327 NULL, 0, 500);
330 static void reg_w_buf(struct gspca_dev *gspca_dev,
331 const u8 *buffer, u16 len)
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),
338 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
339 0x01, 0,
340 gspca_dev->usb_buf, len, 500);
341 } else {
342 u8 *tmpbuf;
344 tmpbuf = kmemdup(buffer, len, GFP_KERNEL);
345 if (!tmpbuf) {
346 pr_err("Out of memory\n");
347 return;
349 usb_control_msg(gspca_dev->dev,
350 usb_sndctrlpipe(gspca_dev->dev, 0),
352 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
353 0x01, 0,
354 tmpbuf, len, 500);
355 kfree(tmpbuf);
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)
364 int i;
365 u8 *p, *tmpbuf;
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;
376 i = len;
377 while (--i >= 0) {
378 *p++ = reg++;
379 *p++ = *buffer++;
381 usb_control_msg(gspca_dev->dev,
382 usb_sndctrlpipe(gspca_dev->dev, 0),
384 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
385 0x01, 0,
386 tmpbuf, len * 2, 500);
387 if (len * 2 > USB_BUF_SZ)
388 kfree(tmpbuf);
391 static void om6802_sensor_init(struct gspca_dev *gspca_dev)
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 */
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);
424 byte = reg_r(gspca_dev, 0x0063);
425 if (byte != 0x17) {
426 pr_err("Bad sensor reset %02x\n", byte);
427 /* continue? */
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;
445 msleep(15);
446 reg_w(gspca_dev, 0x3c80);
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)
453 struct cam *cam = &gspca_dev->cam;
455 cam->cam_mode = vga_mode_t16;
456 cam->nmodes = ARRAY_SIZE(vga_mode_t16);
458 return 0;
461 static void setbrightness(struct gspca_dev *gspca_dev, s32 brightness)
463 u8 set6[4] = { 0x8f, 0x24, 0xc3, 0x00 };
465 if (brightness < 7) {
466 set6[1] = 0x26;
467 set6[3] = 0x70 - brightness * 0x10;
468 } else {
469 set6[3] = 0x00 + ((brightness - 7) * 0x10);
472 reg_w_buf(gspca_dev, set6, sizeof set6);
475 static void setcontrast(struct gspca_dev *gspca_dev, s32 contrast)
477 u16 reg_to_write;
479 if (contrast < 7)
480 reg_to_write = 0x8ea9 - contrast * 0x200;
481 else
482 reg_to_write = 0x00a9 + (contrast - 7) * 0x200;
484 reg_w(gspca_dev, reg_to_write);
487 static void setcolors(struct gspca_dev *gspca_dev, s32 val)
489 u16 reg_to_write;
491 reg_to_write = 0x80bb + val * 0x100; /* was 0xc0 */
492 reg_w(gspca_dev, reg_to_write);
495 static void setgamma(struct gspca_dev *gspca_dev, s32 val)
497 PDEBUG(D_CONF, "Gamma: %d", val);
498 reg_w_ixbuf(gspca_dev, 0x90,
499 gamma_table[val], sizeof gamma_table[0]);
502 static void setawb_n_RGB(struct gspca_dev *gspca_dev)
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;
509 green_gain = sd->gain->val;
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;
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;
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 */
530 reg_w_buf(gspca_dev, all_gain_reg, sizeof all_gain_reg);
533 static void setsharpness(struct gspca_dev *gspca_dev, s32 val)
535 u16 reg_to_write;
537 reg_to_write = 0x0aa6 + 0x1000 * val;
539 reg_w(gspca_dev, reg_to_write);
542 static void setfreq(struct gspca_dev *gspca_dev, s32 val)
544 struct sd *sd = (struct sd *) gspca_dev;
545 u8 reg66;
546 u8 freq[4] = { 0x66, 0x00, 0xa8, 0xe8 };
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;
561 switch (val) {
562 case 0: /* no flicker */
563 freq[3] = 0xf0;
564 break;
565 case 2: /* 60Hz */
566 reg66 &= ~0x40;
567 break;
569 freq[1] = reg66;
571 reg_w_buf(gspca_dev, freq, sizeof freq);
574 /* this function is called at probe and resume time */
575 static int sd_init(struct gspca_dev *gspca_dev)
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;
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};
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;
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 */
629 if (i < 0) {
630 pr_err("Bad sensor reset %02x\n", test_byte);
631 return -EIO;
633 reg_w_buf(gspca_dev, n2, sizeof n2);
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++;
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);
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);
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);
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);
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);
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);
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);
681 return 0;
684 static void setmirror(struct gspca_dev *gspca_dev, s32 val)
686 u8 hflipcmd[8] =
687 {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09};
689 if (val)
690 hflipcmd[3] = 0x01;
692 reg_w_buf(gspca_dev, hflipcmd, sizeof hflipcmd);
695 static void seteffect(struct gspca_dev *gspca_dev, s32 val)
697 int idx = 0;
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;
711 case V4L2_COLORFX_NEGATIVE:
712 idx = 6;
713 break;
714 default:
715 break;
718 reg_w_buf(gspca_dev, effects_table[idx],
719 sizeof effects_table[0]);
721 if (val == V4L2_COLORFX_SKETCH)
722 reg_w(gspca_dev, 0x4aa6);
723 else
724 reg_w(gspca_dev, 0xfaa6);
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)
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};
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);
750 static int sd_start(struct gspca_dev *gspca_dev)
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 };
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;
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++;
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;
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);
808 if (sd->sensor == SENSOR_OM6802)
809 poll_sensor(gspca_dev);
811 return 0;
814 static void sd_stopN(struct gspca_dev *gspca_dev)
816 struct sd *sd = (struct sd *) gspca_dev;
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);
826 #if IS_ENABLED(CONFIG_INPUT)
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;
833 #endif
836 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
837 u8 *data, /* isoc packet */
838 int len) /* iso packet length */
840 struct sd *sd = (struct sd *) gspca_dev;
841 int pkt_type;
843 if (data[0] == 0x5a) {
844 #if IS_ENABLED(CONFIG_INPUT)
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;
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;
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);
871 static int sd_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
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;
878 gspca_dev->usb_err = 0;
880 switch (ctrl->id) {
881 case V4L2_CID_AUTO_WHITE_BALANCE:
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;
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;
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;
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;
905 return 0;
908 static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
910 struct gspca_dev *gspca_dev =
911 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
913 gspca_dev->usb_err = 0;
915 if (!gspca_dev->streaming)
916 return 0;
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;
937 case V4L2_CID_POWER_LINE_FREQUENCY:
938 setfreq(gspca_dev, ctrl->val);
939 break;
940 case V4L2_CID_BACKLIGHT_COMPENSATION:
941 reg_w(gspca_dev, ctrl->val ? 0xf48e : 0xb48e);
942 break;
943 case V4L2_CID_AUTO_WHITE_BALANCE:
944 setawb_n_RGB(gspca_dev);
945 break;
946 case V4L2_CID_COLORFX:
947 seteffect(gspca_dev, ctrl->val);
948 break;
950 return gspca_dev->usb_err;
953 static const struct v4l2_ctrl_ops sd_ctrl_ops = {
954 .g_volatile_ctrl = sd_g_volatile_ctrl,
955 .s_ctrl = sd_s_ctrl,
958 static int sd_init_controls(struct gspca_dev *gspca_dev)
960 struct sd *sd = (struct sd *)gspca_dev;
961 struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
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,
991 V4L2_CID_COLORFX, V4L2_COLORFX_SKETCH,
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)),
997 V4L2_COLORFX_NONE);
998 sd->freq = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops,
999 V4L2_CID_POWER_LINE_FREQUENCY,
1000 V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 1,
1001 V4L2_CID_POWER_LINE_FREQUENCY_50HZ);
1003 if (hdl->error) {
1004 pr_err("Could not initialize controls\n");
1005 return hdl->error;
1008 v4l2_ctrl_auto_cluster(4, &sd->awb, 0, true);
1010 return 0;
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 IS_ENABLED(CONFIG_INPUT)
1023 .other_input = 1,
1024 #endif
1027 /* -- module initialisation -- */
1028 static const struct usb_device_id device_table[] = {
1029 {USB_DEVICE(0x17a1, 0x0128)},
1032 MODULE_DEVICE_TABLE(usb, device_table);
1034 /* -- device connect -- */
1035 static int sd_probe(struct usb_interface *intf,
1036 const struct usb_device_id *id)
1038 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1039 THIS_MODULE);
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
1054 module_usb_driver(sd_driver);