[media] b2c2: fix driver's build due to the lack of pci DMA code
[deliverable/linux.git] / drivers / media / video / gspca / t613.c
CommitLineData
6a7eba24 1/*
cd8955b8
JFM
2 * T613 subdriver
3 *
4 * Copyright (C) 2010 Jean-Francois Moine (http://moinejf.free.fr)
6a7eba24
JFM
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
10b0e96e
JFM
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
6a7eba24
JFM
27 */
28
1b19e429
JP
29#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
30
6a7eba24 31#define MODULE_NAME "t613"
10b0e96e 32
ee186fd9 33#include <linux/input.h>
be2a9fae 34#include <linux/slab.h>
6a7eba24 35#include "gspca.h"
6a7eba24 36
6a7eba24
JFM
37MODULE_AUTHOR("Leandro Costantino <le_costantino@pixartargentina.com.ar>");
38MODULE_DESCRIPTION("GSPCA/T613 (JPEG Compliance) USB Camera Driver");
39MODULE_LICENSE("GPL");
40
41struct sd {
42 struct gspca_dev gspca_dev; /* !! must be the first item */
9bf81642
HV
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 };
82e25491
JFM
50
51 u8 sensor;
ee186fd9 52 u8 button_pressed;
11ce884a
JFM
53};
54enum sensors {
cd8955b8
JFM
55 SENSOR_OM6802,
56 SENSOR_OTHER,
57 SENSOR_TAS5130A,
58 SENSOR_LT168G, /* must verify if this is the actual model */
6a7eba24
JFM
59};
60
cc611b8a 61static const struct v4l2_pix_format vga_mode_t16[] = {
c2446b3e
JFM
62 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
63 .bytesperline = 160,
5d05294a 64 .sizeimage = 160 * 120 * 4 / 8 + 590,
c2446b3e
JFM
65 .colorspace = V4L2_COLORSPACE_JPEG,
66 .priv = 4},
1ea172d2 67#if 0 /* HDG: broken with my test cam, so lets disable it */
c2446b3e
JFM
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},
1ea172d2 73#endif
c2446b3e
JFM
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},
1ea172d2 79#if 0 /* HDG: broken with my test cam, so lets disable it */
c2446b3e
JFM
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},
1ea172d2 85#endif
c2446b3e
JFM
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},
6a7eba24
JFM
91};
92
ad62fb08
LC
93/* sensor specific data */
94struct additional_sensor_data {
78a6d74e
JFM
95 const u8 n3[6];
96 const u8 *n4, n4sz;
97 const u8 reg80, reg8e;
98 const u8 nset8[6];
82e25491
JFM
99 const u8 data1[10];
100 const u8 data2[9];
101 const u8 data3[9];
82e25491
JFM
102 const u8 data5[6];
103 const u8 stream[4];
ad62fb08
LC
104};
105
78a6d74e
JFM
106static 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};
117static 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};
127static 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};
00e8006d
NW
136static 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};
78a6d74e 147
e23b2907 148static const struct additional_sensor_data sensor_data[] = {
cd8955b8 149[SENSOR_OM6802] = {
78a6d74e
JFM
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},
2d56f3bb
JFM
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},
78a6d74e
JFM
163 .data3 =
164 {0x80, 0xff, 0xff, 0x80, 0xff, 0xff, 0x80, 0xff,
165 0xff},
2d56f3bb
JFM
166 .data5 = /* this could be removed later */
167 {0x0c, 0x03, 0xab, 0x13, 0x81, 0x23},
168 .stream =
169 {0x0b, 0x04, 0x0a, 0x78},
170 },
cd8955b8 171[SENSOR_OTHER] = {
78a6d74e
JFM
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},
2d56f3bb
JFM
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},
78a6d74e
JFM
185 .data3 =
186 {0x4e, 0x9c, 0xec, 0x40, 0x80, 0xc0, 0x48, 0x96,
187 0xd9},
2d56f3bb
JFM
188 .data5 =
189 {0x0c, 0x03, 0xab, 0x29, 0x81, 0x69},
190 .stream =
191 {0x0b, 0x04, 0x0a, 0x00},
192 },
cd8955b8 193[SENSOR_TAS5130A] = {
78a6d74e
JFM
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},
ad62fb08 201 .data1 =
82e25491
JFM
202 {0xbb, 0x28, 0x10, 0x10, 0xbb, 0x28, 0x1e, 0x27,
203 0xc8, 0xfc},
ad62fb08 204 .data2 =
82e25491
JFM
205 {0x60, 0xa8, 0xe0, 0x60, 0xa8, 0xe0, 0x60, 0xa8,
206 0xe0},
78a6d74e
JFM
207 .data3 =
208 {0x60, 0xa8, 0xe0, 0x60, 0xa8, 0xe0, 0x60, 0xa8,
209 0xe0},
ad62fb08
LC
210 .data5 =
211 {0x0c, 0x03, 0xab, 0x10, 0x81, 0x20},
212 .stream =
213 {0x0b, 0x04, 0x0a, 0x40},
214 },
cd8955b8 215[SENSOR_LT168G] = {
00e8006d
NW
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},
00e8006d
NW
228 .data5 = {0x0c, 0x03, 0xab, 0x4b, 0x81, 0x2b},
229 .stream = {0x0b, 0x04, 0x0a, 0x28},
230 },
ad62fb08
LC
231};
232
6a7eba24 233#define MAX_EFFECTS 7
82e25491 234static const u8 effects_table[MAX_EFFECTS][6] = {
6a7eba24
JFM
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
9bf81642
HV
244#define GAMMA_MAX (15)
245static const u8 gamma_table[GAMMA_MAX+1][17] = {
79960d39
JFM
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,
82e25491 249 0xff},
79960d39
JFM
250 {0x00, 0x01, 0x03, 0x08, 0x0e, 0x16, 0x21, 0x2d, /* 1 */
251 0x3c, 0x4d, 0x60, 0x75, 0x8d, 0xa6, 0xc2, 0xe1,
82e25491 252 0xff},
79960d39
JFM
253 {0x00, 0x01, 0x05, 0x0b, 0x12, 0x1c, 0x28, 0x35, /* 2 */
254 0x45, 0x56, 0x69, 0x7e, 0x95, 0xad, 0xc7, 0xe3,
82e25491 255 0xff},
79960d39
JFM
256 {0x00, 0x02, 0x07, 0x0f, 0x18, 0x24, 0x30, 0x3f, /* 3 */
257 0x4f, 0x61, 0x73, 0x88, 0x9d, 0xb4, 0xcd, 0xe6,
82e25491 258 0xff},
1d00d6c1 259 {0x00, 0x04, 0x0b, 0x15, 0x20, 0x2d, 0x3b, 0x4a, /* 4 */
79960d39 260 0x5b, 0x6c, 0x7f, 0x92, 0xa7, 0xbc, 0xd2, 0xe9,
82e25491 261 0xff},
79960d39
JFM
262 {0x00, 0x07, 0x11, 0x15, 0x20, 0x2d, 0x48, 0x58, /* 5 */
263 0x68, 0x79, 0x8b, 0x9d, 0xb0, 0xc4, 0xd7, 0xec,
82e25491 264 0xff},
79960d39 265 {0x00, 0x0c, 0x1a, 0x29, 0x38, 0x47, 0x57, 0x67, /* 6 */
82e25491
JFM
266 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee,
267 0xff},
79960d39 268 {0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, /* 7 */
82e25491
JFM
269 0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0,
270 0xff},
79960d39
JFM
271 {0x00, 0x15, 0x27, 0x38, 0x49, 0x59, 0x69, 0x79, /* 8 */
272 0x88, 0x97, 0xa7, 0xb6, 0xc4, 0xd3, 0xe2, 0xf0,
82e25491 273 0xff},
79960d39
JFM
274 {0x00, 0x1c, 0x30, 0x43, 0x54, 0x65, 0x75, 0x84, /* 9 */
275 0x93, 0xa1, 0xb0, 0xbd, 0xca, 0xd8, 0xe5, 0xf2,
82e25491 276 0xff},
79960d39
JFM
277 {0x00, 0x24, 0x3b, 0x4f, 0x60, 0x70, 0x80, 0x8e, /* 10 */
278 0x9c, 0xaa, 0xb7, 0xc4, 0xd0, 0xdc, 0xe8, 0xf3,
82e25491 279 0xff},
79960d39 280 {0x00, 0x2a, 0x3c, 0x5d, 0x6e, 0x7e, 0x8d, 0x9b, /* 11 */
82e25491
JFM
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}
6a7eba24
JFM
295};
296
82e25491 297static const u8 tas5130a_sensor_init[][8] = {
6a7eba24
JFM
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},
6a7eba24
JFM
301};
302
82e25491 303static u8 sensor_reset[] = {0x61, 0x68, 0x62, 0xff, 0x60, 0x07};
392ee5a5 304
739570bb 305/* read 1 byte */
82e25491
JFM
306static u8 reg_r(struct gspca_dev *gspca_dev,
307 u16 index)
6a7eba24 308{
739570bb
JFM
309 usb_control_msg(gspca_dev->dev,
310 usb_rcvctrlpipe(gspca_dev->dev, 0),
6a7eba24
JFM
311 0, /* request */
312 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
313 0, /* value */
739570bb
JFM
314 index,
315 gspca_dev->usb_buf, 1, 500);
316 return gspca_dev->usb_buf[0];
6a7eba24
JFM
317}
318
739570bb 319static void reg_w(struct gspca_dev *gspca_dev,
82e25491 320 u16 index)
fadc7993
JFM
321{
322 usb_control_msg(gspca_dev->dev,
323 usb_sndctrlpipe(gspca_dev->dev, 0),
324 0,
0bc99b5c 325 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
fadc7993
JFM
326 0, index,
327 NULL, 0, 500);
328}
329
f89be036 330static void reg_w_buf(struct gspca_dev *gspca_dev,
82e25491 331 const u8 *buffer, u16 len)
6a7eba24 332{
8295d99e 333 if (len <= USB_BUF_SZ) {
739570bb
JFM
334 memcpy(gspca_dev->usb_buf, buffer, len);
335 usb_control_msg(gspca_dev->dev,
336 usb_sndctrlpipe(gspca_dev->dev, 0),
a5ae2062 337 0,
0bc99b5c 338 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
fadc7993 339 0x01, 0,
739570bb 340 gspca_dev->usb_buf, len, 500);
a5ae2062 341 } else {
82e25491 342 u8 *tmpbuf;
a5ae2062 343
feda79bf 344 tmpbuf = kmemdup(buffer, len, GFP_KERNEL);
24f222e7 345 if (!tmpbuf) {
1b19e429 346 pr_err("Out of memory\n");
24f222e7
JFM
347 return;
348 }
739570bb
JFM
349 usb_control_msg(gspca_dev->dev,
350 usb_sndctrlpipe(gspca_dev->dev, 0),
a5ae2062 351 0,
0bc99b5c 352 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
fadc7993 353 0x01, 0,
a5ae2062
JFM
354 tmpbuf, len, 500);
355 kfree(tmpbuf);
356 }
6a7eba24
JFM
357}
358
82e25491
JFM
359/* write values to consecutive registers */
360static 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
24f222e7 367 if (len * 2 <= USB_BUF_SZ) {
82e25491 368 p = tmpbuf = gspca_dev->usb_buf;
24f222e7 369 } else {
82e25491 370 p = tmpbuf = kmalloc(len * 2, GFP_KERNEL);
24f222e7 371 if (!tmpbuf) {
1b19e429 372 pr_err("Out of memory\n");
24f222e7
JFM
373 return;
374 }
375 }
82e25491
JFM
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,
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);
389}
390
236088d2 391static void om6802_sensor_init(struct gspca_dev *gspca_dev)
fadc7993
JFM
392{
393 int i;
82e25491
JFM
394 const u8 *p;
395 u8 byte;
396 u8 val[6] = {0x62, 0, 0x64, 0, 0x60, 0x05};
397 static const u8 sensor_init[] = {
fadc7993
JFM
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,
fadc7993
JFM
411 0xfd, 0x41,
412 0x00 /* table end */
413 };
414
392ee5a5 415 reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset);
e30bdc66 416 msleep(100);
392ee5a5 417 i = 4;
97a53a0f 418 while (--i > 0) {
392ee5a5
JFM
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) {
1b19e429 426 pr_err("Bad sensor reset %02x\n", byte);
392ee5a5
JFM
427 /* continue? */
428 }
429
fadc7993
JFM
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);
f89be036 436 reg_w_buf(gspca_dev, val, sizeof val);
fadc7993
JFM
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 }
392ee5a5
JFM
445 msleep(15);
446 reg_w(gspca_dev, 0x3c80);
fadc7993
JFM
447}
448
6a7eba24
JFM
449/* this function is called at probe time */
450static int sd_config(struct gspca_dev *gspca_dev,
451 const struct usb_device_id *id)
452{
9bf81642 453 struct cam *cam = &gspca_dev->cam;
6a7eba24
JFM
454
455 cam->cam_mode = vga_mode_t16;
456 cam->nmodes = ARRAY_SIZE(vga_mode_t16);
457
6a7eba24
JFM
458 return 0;
459}
460
9bf81642 461static void setbrightness(struct gspca_dev *gspca_dev, s32 brightness)
35480b6b 462{
82e25491 463 u8 set6[4] = { 0x8f, 0x24, 0xc3, 0x00 };
35480b6b 464
35480b6b
JFM
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
9bf81642 475static void setcontrast(struct gspca_dev *gspca_dev, s32 contrast)
35480b6b 476{
82e25491 477 u16 reg_to_write;
35480b6b
JFM
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
9bf81642 487static void setcolors(struct gspca_dev *gspca_dev, s32 val)
35480b6b 488{
82e25491 489 u16 reg_to_write;
35480b6b 490
9bf81642 491 reg_to_write = 0x80bb + val * 0x100; /* was 0xc0 */
35480b6b
JFM
492 reg_w(gspca_dev, reg_to_write);
493}
494
9bf81642 495static void setgamma(struct gspca_dev *gspca_dev, s32 val)
fadc7993 496{
fadc7993 497 PDEBUG(D_CONF, "Gamma: %d", sd->gamma);
82e25491 498 reg_w_ixbuf(gspca_dev, 0x90,
9bf81642 499 gamma_table[val], sizeof gamma_table[0]);
fadc7993
JFM
500}
501
9bf81642 502static void setawb_n_RGB(struct gspca_dev *gspca_dev)
e9b15653 503{
be1da9ee 504 struct sd *sd = (struct sd *) gspca_dev;
9bf81642
HV
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 */
e9b15653 529
e9b15653 530 reg_w_buf(gspca_dev, all_gain_reg, sizeof all_gain_reg);
be1da9ee
CL
531}
532
9bf81642 533static void setsharpness(struct gspca_dev *gspca_dev, s32 val)
35480b6b 534{
82e25491 535 u16 reg_to_write;
35480b6b 536
9bf81642 537 reg_to_write = 0x0aa6 + 0x1000 * val;
35480b6b
JFM
538
539 reg_w(gspca_dev, reg_to_write);
540}
541
9bf81642 542static void setfreq(struct gspca_dev *gspca_dev, s32 val)
78b98cb9
JFM
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:
9bf81642 550 if (val != 0)
78b98cb9
JFM
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 }
9bf81642 561 switch (val) {
78b98cb9
JFM
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
fadc7993
JFM
574/* this function is called at probe and resume time */
575static int sd_init(struct gspca_dev *gspca_dev)
6a7eba24 576{
6a7eba24
JFM
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.*/
fadc7993 581 struct sd *sd = (struct sd *) gspca_dev;
78a6d74e 582 const struct additional_sensor_data *sensor;
fadc7993 583 int i;
2d56f3bb 584 u16 sensor_id;
d9ddd3b0 585 u8 test_byte = 0;
6a7eba24 586
82e25491 587 static const u8 read_indexs[] =
249fe889 588 { 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5,
82e25491
JFM
589 0xa6, 0xa8, 0xbb, 0xbc, 0xc6, 0x00 };
590 static const u8 n1[] =
6a7eba24 591 {0x08, 0x03, 0x09, 0x03, 0x12, 0x04};
82e25491 592 static const u8 n2[] =
6a7eba24 593 {0x08, 0x00};
6a7eba24 594
2d56f3bb
JFM
595 sensor_id = (reg_r(gspca_dev, 0x06) << 8)
596 | reg_r(gspca_dev, 0x07);
3da37e42 597 switch (sensor_id & 0xff0f) {
2d56f3bb 598 case 0x0801:
748c0148 599 PDEBUG(D_PROBE, "sensor tas5130a");
236088d2 600 sd->sensor = SENSOR_TAS5130A;
2d56f3bb 601 break;
00e8006d
NW
602 case 0x0802:
603 PDEBUG(D_PROBE, "sensor lt168g");
604 sd->sensor = SENSOR_LT168G;
605 break;
2d56f3bb 606 case 0x0803:
748c0148 607 PDEBUG(D_PROBE, "sensor 'other'");
2d56f3bb
JFM
608 sd->sensor = SENSOR_OTHER;
609 break;
610 case 0x0807:
748c0148 611 PDEBUG(D_PROBE, "sensor om6802");
2d56f3bb
JFM
612 sd->sensor = SENSOR_OM6802;
613 break;
614 default:
1b19e429 615 pr_err("unknown sensor %04x\n", sensor_id);
409b11dd 616 return -EINVAL;
fadc7993
JFM
617 }
618
dd72cb3e 619 if (sd->sensor == SENSOR_OM6802) {
2d56f3bb
JFM
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) {
1b19e429 630 pr_err("Bad sensor reset %02x\n", test_byte);
78a6d74e 631 return -EIO;
2d56f3bb
JFM
632 }
633 reg_w_buf(gspca_dev, n2, sizeof n2);
fadc7993 634 }
6a7eba24 635
fadc7993 636 i = 0;
6a7eba24 637 while (read_indexs[i] != 0x00) {
fadc7993
JFM
638 test_byte = reg_r(gspca_dev, read_indexs[i]);
639 PDEBUG(D_STREAM, "Reg 0x%02x = 0x%02x", read_indexs[i],
6a7eba24
JFM
640 test_byte);
641 i++;
642 }
643
78a6d74e
JFM
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);
ad62fb08 647
00e8006d
NW
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
78a6d74e
JFM
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);
ad62fb08 658
78a6d74e
JFM
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);
9bf81642
HV
662 reg_w(gspca_dev, (0x20 << 8) + 0x87);
663 reg_w(gspca_dev, (0x20 << 8) + 0x88);
664 reg_w(gspca_dev, (0x20 << 8) + 0x89);
fadc7993 665
78a6d74e
JFM
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);
ad62fb08 669
00e8006d
NW
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
78a6d74e
JFM
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);
6a7eba24 680
012d6b02
JFM
681 return 0;
682}
683
9bf81642 684static void setmirror(struct gspca_dev *gspca_dev, s32 val)
6a7eba24 685{
cd8955b8 686 u8 hflipcmd[8] =
fadc7993 687 {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09};
6a7eba24 688
9bf81642 689 if (val)
cd8955b8 690 hflipcmd[3] = 0x01;
6a7eba24 691
cd8955b8 692 reg_w_buf(gspca_dev, hflipcmd, sizeof hflipcmd);
6a7eba24
JFM
693}
694
9bf81642 695static void seteffect(struct gspca_dev *gspca_dev, s32 val)
6a7eba24 696{
9bf81642 697 int idx = 0;
6a7eba24 698
9bf81642
HV
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;
6a7eba24
JFM
716 }
717
9bf81642
HV
718 reg_w_buf(gspca_dev, effects_table[idx],
719 sizeof effects_table[0]);
720
721 if (val == V4L2_COLORFX_SKETCH)
fadc7993 722 reg_w(gspca_dev, 0x4aa6);
6a7eba24 723 else
fadc7993 724 reg_w(gspca_dev, 0xfaa6);
6a7eba24
JFM
725}
726
ad62fb08
LC
727/* Is this really needed?
728 * i added some module parameters for test with some users */
729static void poll_sensor(struct gspca_dev *gspca_dev)
730{
82e25491 731 static const u8 poll1[] =
ad62fb08
LC
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};
82e25491 736 static const u8 poll2[] =
ad62fb08
LC
737 {0x67, 0x02, 0x68, 0x71, 0x69, 0x72, 0x72, 0xa9,
738 0x73, 0x02, 0x73, 0x02, 0x60, 0x14};
98388241 739 static const u8 noise03[] = /* (some differences / ms-drv) */
ad62fb08
LC
740 {0xa6, 0x0a, 0xea, 0xcf, 0xbe, 0x26, 0xb1, 0x5f,
741 0xa1, 0xb1, 0xda, 0x6b, 0xdb, 0x98, 0xdf, 0x0c,
742 0xc2, 0x80, 0xc3, 0x10};
743
78a6d74e
JFM
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);
98388241 747 reg_w_buf(gspca_dev, noise03, sizeof noise03);
ad62fb08
LC
748}
749
fadc7993
JFM
750static int sd_start(struct gspca_dev *gspca_dev)
751{
752 struct sd *sd = (struct sd *) gspca_dev;
78a6d74e 753 const struct additional_sensor_data *sensor;
fadc7993 754 int i, mode;
82e25491
JFM
755 u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 };
756 static const u8 t3[] =
757 { 0x07, 0x00, 0x88, 0x02, 0x06, 0x00, 0xe7, 0x01 };
fadc7993 758
78a6d74e 759 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
fadc7993 760 switch (mode) {
82e25491
JFM
761 case 0: /* 640x480 (0x00) */
762 break;
fadc7993
JFM
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;
82e25491
JFM
772 default:
773/* case 4: * 160x120 */
fadc7993
JFM
774 t2[1] = 0x20;
775 break;
fadc7993
JFM
776 }
777
2d56f3bb
JFM
778 switch (sd->sensor) {
779 case SENSOR_OM6802:
780 om6802_sensor_init(gspca_dev);
781 break;
cd8955b8 782 case SENSOR_TAS5130A:
fadc7993 783 i = 0;
78a6d74e 784 for (;;) {
f89be036 785 reg_w_buf(gspca_dev, tas5130a_sensor_init[i],
fadc7993 786 sizeof tas5130a_sensor_init[0]);
78a6d74e
JFM
787 if (i >= ARRAY_SIZE(tas5130a_sensor_init) - 1)
788 break;
fadc7993
JFM
789 i++;
790 }
791 reg_w(gspca_dev, 0x3c80);
792 /* just in case and to keep sync with logs (for mine) */
78a6d74e 793 reg_w_buf(gspca_dev, tas5130a_sensor_init[i],
fadc7993
JFM
794 sizeof tas5130a_sensor_init[0]);
795 reg_w(gspca_dev, 0x3c80);
2d56f3bb 796 break;
fadc7993 797 }
78a6d74e 798 sensor = &sensor_data[sd->sensor];
9bf81642 799 setfreq(gspca_dev, v4l2_ctrl_g_ctrl(sd->freq));
fadc7993 800 reg_r(gspca_dev, 0x0012);
ad62fb08 801 reg_w_buf(gspca_dev, t2, sizeof t2);
82e25491 802 reg_w_ixbuf(gspca_dev, 0xb3, t3, sizeof t3);
fadc7993 803 reg_w(gspca_dev, 0x0013);
ad62fb08 804 msleep(15);
78a6d74e
JFM
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);
ad62fb08 810
fadc7993
JFM
811 return 0;
812}
813
eb229b22
JFM
814static 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);
eb229b22
JFM
820 reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
821 sizeof sensor_data[sd->sensor].stream);
78a6d74e 822 if (sd->sensor == SENSOR_OM6802) {
2d56f3bb
JFM
823 msleep(20);
824 reg_w(gspca_dev, 0x0309);
825 }
ee186fd9
HG
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
eb229b22
JFM
834}
835
fadc7993 836static void sd_pkt_scan(struct gspca_dev *gspca_dev,
82e25491 837 u8 *data, /* isoc packet */
fadc7993
JFM
838 int len) /* iso packet length */
839{
ee186fd9 840 struct sd *sd = (struct sd *) gspca_dev;
ebb78c5a 841 int pkt_type;
fadc7993
JFM
842
843 if (data[0] == 0x5a) {
ee186fd9
HG
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
fadc7993
JFM
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;
ebb78c5a
JFM
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);
6a7eba24
JFM
869}
870
9bf81642 871static int sd_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
6a7eba24 872{
9bf81642
HV
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) {
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;
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 }
6a7eba24
JFM
905 return 0;
906}
907
9bf81642 908static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
6a7eba24 909{
9bf81642
HV
910 struct gspca_dev *gspca_dev =
911 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
6a7eba24 912
9bf81642 913 gspca_dev->usb_err = 0;
6a7eba24 914
9bf81642
HV
915 if (!gspca_dev->streaming)
916 return 0;
6a7eba24 917
9bf81642
HV
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;
949 }
950 return gspca_dev->usb_err;
6a7eba24
JFM
951}
952
9bf81642
HV
953static const struct v4l2_ctrl_ops sd_ctrl_ops = {
954 .g_volatile_ctrl = sd_g_volatile_ctrl,
955 .s_ctrl = sd_s_ctrl,
956};
6a7eba24 957
9bf81642 958static int sd_init_controls(struct gspca_dev *gspca_dev)
6a7eba24 959{
9bf81642
HV
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,
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);
1002
1003 if (hdl->error) {
1004 pr_err("Could not initialize controls\n");
1005 return hdl->error;
1006 }
6a7eba24 1007
9bf81642 1008 v4l2_ctrl_auto_cluster(4, &sd->awb, 0, true);
6a7eba24 1009
6a7eba24
JFM
1010 return 0;
1011}
1012
6a7eba24 1013/* sub-driver description */
a5ae2062 1014static const struct sd_desc sd_desc = {
6a7eba24 1015 .name = MODULE_NAME,
6a7eba24 1016 .config = sd_config,
012d6b02 1017 .init = sd_init,
9bf81642 1018 .init_controls = sd_init_controls,
6a7eba24 1019 .start = sd_start,
eb229b22 1020 .stopN = sd_stopN,
6a7eba24 1021 .pkt_scan = sd_pkt_scan,
ee186fd9
HG
1022#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
1023 .other_input = 1,
1024#endif
6a7eba24
JFM
1025};
1026
1027/* -- module initialisation -- */
95c967c1 1028static const struct usb_device_id device_table[] = {
9d64fdb1 1029 {USB_DEVICE(0x17a1, 0x0128)},
6a7eba24
JFM
1030 {}
1031};
6a7eba24
JFM
1032MODULE_DEVICE_TABLE(usb, device_table);
1033
1034/* -- device connect -- */
1035static 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
1042static struct usb_driver sd_driver = {
1043 .name = MODULE_NAME,
1044 .id_table = device_table,
1045 .probe = sd_probe,
1046 .disconnect = gspca_disconnect,
6a709749
JFM
1047#ifdef CONFIG_PM
1048 .suspend = gspca_suspend,
1049 .resume = gspca_resume,
8bb58964 1050 .reset_resume = gspca_resume,
6a709749 1051#endif
6a7eba24
JFM
1052};
1053
ecb3b2b3 1054module_usb_driver(sd_driver);
This page took 0.492006 seconds and 5 git commands to generate.