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
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.
29 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
31 #define MODULE_NAME "t613"
33 #include <linux/input.h>
34 #include <linux/slab.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");
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
;
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
,
64 .sizeimage
= 160 * 120 * 4 / 8 + 590,
65 .colorspace
= V4L2_COLORSPACE_JPEG
,
67 #if 0 /* HDG: broken with my test cam, so lets disable it */
68 {176, 144, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
70 .sizeimage
= 176 * 144 * 3 / 8 + 590,
71 .colorspace
= V4L2_COLORSPACE_JPEG
,
74 {320, 240, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
76 .sizeimage
= 320 * 240 * 3 / 8 + 590,
77 .colorspace
= V4L2_COLORSPACE_JPEG
,
79 #if 0 /* HDG: broken with my test cam, so lets disable it */
80 {352, 288, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
82 .sizeimage
= 352 * 288 * 3 / 8 + 590,
83 .colorspace
= V4L2_COLORSPACE_JPEG
,
86 {640, 480, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
88 .sizeimage
= 640 * 480 * 3 / 8 + 590,
89 .colorspace
= V4L2_COLORSPACE_JPEG
,
93 /* sensor specific data */
94 struct additional_sensor_data
{
97 const u8 reg80
, reg8e
;
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,
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
[] = {
151 {0x61, 0x68, 0x65, 0x0a, 0x60, 0x04},
153 .n4sz
= sizeof n4_om6802
,
156 .nset8
= {0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00},
158 {0xc2, 0x28, 0x0f, 0x22, 0xcd, 0x27, 0x2c, 0x06,
161 {0x80, 0xff, 0xff, 0x80, 0xff, 0xff, 0x80, 0xff,
164 {0x80, 0xff, 0xff, 0x80, 0xff, 0xff, 0x80, 0xff,
166 .data5
= /* this could be removed later */
167 {0x0c, 0x03, 0xab, 0x13, 0x81, 0x23},
169 {0x0b, 0x04, 0x0a, 0x78},
173 {0x61, 0xc2, 0x65, 0x88, 0x60, 0x00},
175 .n4sz
= sizeof n4_other
,
178 .nset8
= {0xa8, 0xa8, 0xc6, 0xda, 0xc0, 0x00},
180 {0xc1, 0x48, 0x04, 0x1b, 0xca, 0x2e, 0x33, 0x3a,
183 {0x4e, 0x9c, 0xec, 0x40, 0x80, 0xc0, 0x48, 0x96,
186 {0x4e, 0x9c, 0xec, 0x40, 0x80, 0xc0, 0x48, 0x96,
189 {0x0c, 0x03, 0xab, 0x29, 0x81, 0x69},
191 {0x0b, 0x04, 0x0a, 0x00},
193 [SENSOR_TAS5130A
] = {
195 {0x61, 0xc2, 0x65, 0x0d, 0x60, 0x08},
197 .n4sz
= sizeof n4_tas5130a
,
200 .nset8
= {0xa8, 0xf0, 0xc6, 0xda, 0xc0, 0x00},
202 {0xbb, 0x28, 0x10, 0x10, 0xbb, 0x28, 0x1e, 0x27,
205 {0x60, 0xa8, 0xe0, 0x60, 0xa8, 0xe0, 0x60, 0xa8,
208 {0x60, 0xa8, 0xe0, 0x60, 0xa8, 0xe0, 0x60, 0xa8,
211 {0x0c, 0x03, 0xab, 0x10, 0x81, 0x20},
213 {0x0b, 0x04, 0x0a, 0x40},
216 .n3
= {0x61, 0xc2, 0x65, 0x68, 0x60, 0x00},
218 .n4sz
= sizeof n4_lt168g
,
221 .nset8
= {0xa8, 0xf0, 0xc6, 0xba, 0xc0, 0x00},
222 .data1
= {0xc0, 0x38, 0x08, 0x10, 0xc0, 0x30, 0x10, 0x40,
224 .data2
= {0x40, 0x80, 0xc0, 0x50, 0xa0, 0xf0, 0x53, 0xa6,
226 .data3
= {0x40, 0x80, 0xc0, 0x50, 0xa0, 0xf0, 0x53, 0xa6,
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,
250 {0x00, 0x01, 0x03, 0x08, 0x0e, 0x16, 0x21, 0x2d, /* 1 */
251 0x3c, 0x4d, 0x60, 0x75, 0x8d, 0xa6, 0xc2, 0xe1,
253 {0x00, 0x01, 0x05, 0x0b, 0x12, 0x1c, 0x28, 0x35, /* 2 */
254 0x45, 0x56, 0x69, 0x7e, 0x95, 0xad, 0xc7, 0xe3,
256 {0x00, 0x02, 0x07, 0x0f, 0x18, 0x24, 0x30, 0x3f, /* 3 */
257 0x4f, 0x61, 0x73, 0x88, 0x9d, 0xb4, 0xcd, 0xe6,
259 {0x00, 0x04, 0x0b, 0x15, 0x20, 0x2d, 0x3b, 0x4a, /* 4 */
260 0x5b, 0x6c, 0x7f, 0x92, 0xa7, 0xbc, 0xd2, 0xe9,
262 {0x00, 0x07, 0x11, 0x15, 0x20, 0x2d, 0x48, 0x58, /* 5 */
263 0x68, 0x79, 0x8b, 0x9d, 0xb0, 0xc4, 0xd7, 0xec,
265 {0x00, 0x0c, 0x1a, 0x29, 0x38, 0x47, 0x57, 0x67, /* 6 */
266 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee,
268 {0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, /* 7 */
269 0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0,
271 {0x00, 0x15, 0x27, 0x38, 0x49, 0x59, 0x69, 0x79, /* 8 */
272 0x88, 0x97, 0xa7, 0xb6, 0xc4, 0xd3, 0xe2, 0xf0,
274 {0x00, 0x1c, 0x30, 0x43, 0x54, 0x65, 0x75, 0x84, /* 9 */
275 0x93, 0xa1, 0xb0, 0xbd, 0xca, 0xd8, 0xe5, 0xf2,
277 {0x00, 0x24, 0x3b, 0x4f, 0x60, 0x70, 0x80, 0x8e, /* 10 */
278 0x9c, 0xaa, 0xb7, 0xc4, 0xd0, 0xdc, 0xe8, 0xf3,
280 {0x00, 0x2a, 0x3c, 0x5d, 0x6e, 0x7e, 0x8d, 0x9b, /* 11 */
281 0xa8, 0xb4, 0xc0, 0xcb, 0xd6, 0xe1, 0xeb, 0xf5,
283 {0x00, 0x3f, 0x5a, 0x6e, 0x7f, 0x8e, 0x9c, 0xa8, /* 12 */
284 0xb4, 0xbf, 0xc9, 0xd3, 0xdc, 0xe5, 0xee, 0xf6,
286 {0x00, 0x54, 0x6f, 0x83, 0x93, 0xa0, 0xad, 0xb7, /* 13 */
287 0xc2, 0xcb, 0xd4, 0xdc, 0xe4, 0xeb, 0xf2, 0xf9,
289 {0x00, 0x6e, 0x88, 0x9a, 0xa8, 0xb3, 0xbd, 0xc6, /* 14 */
290 0xcf, 0xd6, 0xdd, 0xe3, 0xe9, 0xef, 0xf4, 0xfa,
292 {0x00, 0x93, 0xa8, 0xb7, 0xc1, 0xca, 0xd2, 0xd8, /* 15 */
293 0xde, 0xe3, 0xe8, 0xed, 0xf1, 0xf5, 0xf8, 0xfc,
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};
306 static u8
reg_r(struct gspca_dev
*gspca_dev
,
309 usb_control_msg(gspca_dev
->dev
,
310 usb_rcvctrlpipe(gspca_dev
->dev
, 0),
312 USB_DIR_IN
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
315 gspca_dev
->usb_buf
, 1, 500);
316 return gspca_dev
->usb_buf
[0];
319 static void reg_w(struct gspca_dev
*gspca_dev
,
322 usb_control_msg(gspca_dev
->dev
,
323 usb_sndctrlpipe(gspca_dev
->dev
, 0),
325 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
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
,
340 gspca_dev
->usb_buf
, len
, 500);
344 tmpbuf
= kmemdup(buffer
, len
, GFP_KERNEL
);
346 pr_err("Out of memory\n");
349 usb_control_msg(gspca_dev
->dev
,
350 usb_sndctrlpipe(gspca_dev
->dev
, 0),
352 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
359 /* write values to consecutive registers */
360 static void reg_w_ixbuf(struct gspca_dev
*gspca_dev
,
362 const u8
*buffer
, u16 len
)
367 if (len
* 2 <= USB_BUF_SZ
) {
368 p
= tmpbuf
= gspca_dev
->usb_buf
;
370 p
= tmpbuf
= kmalloc(len
* 2, GFP_KERNEL
);
372 pr_err("Out of memory\n");
381 usb_control_msg(gspca_dev
->dev
,
382 usb_sndctrlpipe(gspca_dev
->dev
, 0),
384 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
386 tmpbuf
, len
* 2, 500);
387 if (len
* 2 > USB_BUF_SZ
)
391 static void om6802_sensor_init(struct gspca_dev
*gspca_dev
)
396 u8 val
[6] = {0x62, 0, 0x64, 0, 0x60, 0x05};
397 static const u8 sensor_init
[] = {
415 reg_w_buf(gspca_dev
, sensor_reset
, sizeof sensor_reset
);
419 byte
= reg_r(gspca_dev
, 0x0060);
424 byte
= reg_r(gspca_dev
, 0x0063);
426 pr_err("Bad sensor reset %02x\n", byte
);
435 reg_w(gspca_dev
, 0x3c80);
436 reg_w_buf(gspca_dev
, val
, sizeof val
);
440 byte
= reg_r(gspca_dev
, 0x60);
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
);
461 static void setbrightness(struct gspca_dev
*gspca_dev
, s32 brightness
)
463 u8 set6
[4] = { 0x8f, 0x24, 0xc3, 0x00 };
465 if (brightness
< 7) {
467 set6
[3] = 0x70 - brightness
* 0x10;
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
)
480 reg_to_write
= 0x8ea9 - contrast
* 0x200;
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
)
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
;
514 else if (red_gain
< 0x10)
517 blue_gain
= green_gain
+ sd
->blue_balance
->val
;
518 if (blue_gain
> 0x40)
520 else if (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
;
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
)
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
;
546 u8 freq
[4] = { 0x66, 0x00, 0xa8, 0xe8 };
548 switch (sd
->sensor
) {
562 case 0: /* no flicker */
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
;
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
[] =
595 sensor_id
= (reg_r(gspca_dev
, 0x06) << 8)
596 | reg_r(gspca_dev
, 0x07);
597 switch (sensor_id
& 0xff0f) {
599 PDEBUG(D_PROBE
, "sensor tas5130a");
600 sd
->sensor
= SENSOR_TAS5130A
;
603 PDEBUG(D_PROBE
, "sensor lt168g");
604 sd
->sensor
= SENSOR_LT168G
;
607 PDEBUG(D_PROBE
, "sensor 'other'");
608 sd
->sensor
= SENSOR_OTHER
;
611 PDEBUG(D_PROBE
, "sensor om6802");
612 sd
->sensor
= SENSOR_OM6802
;
615 pr_err("unknown sensor %04x\n", sensor_id
);
619 if (sd
->sensor
== SENSOR_OM6802
) {
620 reg_w_buf(gspca_dev
, n1
, sizeof n1
);
623 reg_w_buf(gspca_dev
, sensor_reset
, sizeof sensor_reset
);
624 test_byte
= reg_r(gspca_dev
, 0x0063);
626 if (test_byte
== 0x17)
630 pr_err("Bad sensor reset %02x\n", test_byte
);
633 reg_w_buf(gspca_dev
, n2
, sizeof n2
);
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
],
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,
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,
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
);
684 static void setmirror(struct gspca_dev
*gspca_dev
, s32 val
)
687 {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09};
692 reg_w_buf(gspca_dev
, hflipcmd
, sizeof hflipcmd
);
695 static void seteffect(struct gspca_dev
*gspca_dev
, s32 val
)
700 case V4L2_COLORFX_NONE
:
702 case V4L2_COLORFX_BW
:
705 case V4L2_COLORFX_SEPIA
:
708 case V4L2_COLORFX_SKETCH
:
711 case V4L2_COLORFX_NEGATIVE
:
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);
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,
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
;
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
;
761 case 0: /* 640x480 (0x00) */
763 case 1: /* 352x288 */
766 case 2: /* 320x240 */
769 case 3: /* 176x144 */
773 /* case 4: * 160x120 */
778 switch (sd
->sensor
) {
780 om6802_sensor_init(gspca_dev
);
782 case SENSOR_TAS5130A
:
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)
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);
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);
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
);
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
) {
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;
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
;
843 if (data
[0] == 0x5a) {
844 #if IS_ENABLED(CONFIG_INPUT)
846 u8 state
= (data
[20] & 0x80) ? 1 : 0;
847 if (sd
->button_pressed
!= state
) {
848 input_report_key(gspca_dev
->input_dev
,
850 input_sync(gspca_dev
->input_dev
);
851 sd
->button_pressed
= state
;
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... */
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
;
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;
881 case V4L2_CID_AUTO_WHITE_BALANCE
:
882 red_gain
= reg_r(gspca_dev
, 0x0087);
885 else if (red_gain
< 0x10)
888 blue_gain
= reg_r(gspca_dev
, 0x0088);
889 if (blue_gain
> 0x40)
891 else if (blue_gain
< 0x10)
894 green_gain
= reg_r(gspca_dev
, 0x0089);
895 if (green_gain
> 0x40)
897 else if (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
;
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
)
919 case V4L2_CID_BRIGHTNESS
:
920 setbrightness(gspca_dev
, ctrl
->val
);
922 case V4L2_CID_CONTRAST
:
923 setcontrast(gspca_dev
, ctrl
->val
);
925 case V4L2_CID_SATURATION
:
926 setcolors(gspca_dev
, ctrl
->val
);
929 setgamma(gspca_dev
, ctrl
->val
);
932 setmirror(gspca_dev
, ctrl
->val
);
934 case V4L2_CID_SHARPNESS
:
935 setsharpness(gspca_dev
, ctrl
->val
);
937 case V4L2_CID_POWER_LINE_FREQUENCY
:
938 setfreq(gspca_dev
, ctrl
->val
);
940 case V4L2_CID_BACKLIGHT_COMPENSATION
:
941 reg_w(gspca_dev
, ctrl
->val
? 0xf48e : 0xb48e);
943 case V4L2_CID_AUTO_WHITE_BALANCE
:
944 setawb_n_RGB(gspca_dev
);
946 case V4L2_CID_COLORFX
:
947 seteffect(gspca_dev
, ctrl
->val
);
950 return gspca_dev
->usb_err
;
953 static const struct v4l2_ctrl_ops sd_ctrl_ops
= {
954 .g_volatile_ctrl
= sd_g_volatile_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
)),
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
);
1004 pr_err("Could not initialize controls\n");
1008 v4l2_ctrl_auto_cluster(4, &sd
->awb
, 0, true);
1013 /* sub-driver description */
1014 static const struct sd_desc sd_desc
= {
1015 .name
= MODULE_NAME
,
1016 .config
= sd_config
,
1018 .init_controls
= sd_init_controls
,
1021 .pkt_scan
= sd_pkt_scan
,
1022 #if IS_ENABLED(CONFIG_INPUT)
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
),
1042 static struct usb_driver sd_driver
= {
1043 .name
= MODULE_NAME
,
1044 .id_table
= device_table
,
1046 .disconnect
= gspca_disconnect
,
1048 .suspend
= gspca_suspend
,
1049 .resume
= gspca_resume
,
1050 .reset_resume
= gspca_resume
,
1054 module_usb_driver(sd_driver
);