V4L/DVB (12090): gspca_sonixj: enable autogain control for the ov7620
[deliverable/linux.git] / drivers / media / video / gspca / spca500.c
CommitLineData
6a7eba24
JFM
1/*
2 * SPCA500 chip based cameras initialization data
3 *
4 * V4L2 by 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 */
21
22#define MODULE_NAME "spca500"
23
24#include "gspca.h"
25#include "jpeg.h"
26
6a7eba24
JFM
27MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
28MODULE_DESCRIPTION("GSPCA/SPCA500 USB Camera Driver");
29MODULE_LICENSE("GPL");
30
31/* specific webcam descriptor */
32struct sd {
33 struct gspca_dev gspca_dev; /* !! must be the first item */
34
6a7eba24
JFM
35 unsigned char brightness;
36 unsigned char contrast;
37 unsigned char colors;
71cb2764 38 u8 quality;
77ac0baf
JFM
39#define QUALITY_MIN 70
40#define QUALITY_MAX 95
41#define QUALITY_DEF 85
6a7eba24 42
6a7eba24
JFM
43 char subtype;
44#define AgfaCl20 0
45#define AiptekPocketDV 1
46#define BenqDC1016 2
47#define CreativePCCam300 3
48#define DLinkDSC350 4
49#define Gsmartmini 5
50#define IntelPocketPCCamera 6
51#define KodakEZ200 7
52#define LogitechClickSmart310 8
53#define LogitechClickSmart510 9
54#define LogitechTraveler 10
55#define MustekGsmart300 11
56#define Optimedia 12
57#define PalmPixDC85 13
58#define ToptroIndus 14
71cb2764
JFM
59
60 u8 *jpeg_hdr;
6a7eba24
JFM
61};
62
63/* V4L2 controls supported by the driver */
64static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
65static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
66static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
67static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
68static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
69static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
70
71static struct ctrl sd_ctrls[] = {
6a7eba24
JFM
72 {
73 {
74 .id = V4L2_CID_BRIGHTNESS,
75 .type = V4L2_CTRL_TYPE_INTEGER,
76 .name = "Brightness",
77 .minimum = 0,
a5ae2062 78 .maximum = 255,
6a7eba24 79 .step = 1,
a5ae2062
JFM
80#define BRIGHTNESS_DEF 127
81 .default_value = BRIGHTNESS_DEF,
6a7eba24
JFM
82 },
83 .set = sd_setbrightness,
84 .get = sd_getbrightness,
85 },
6a7eba24
JFM
86 {
87 {
88 .id = V4L2_CID_CONTRAST,
89 .type = V4L2_CTRL_TYPE_INTEGER,
90 .name = "Contrast",
91 .minimum = 0,
a5ae2062 92 .maximum = 63,
6a7eba24 93 .step = 1,
a5ae2062
JFM
94#define CONTRAST_DEF 31
95 .default_value = CONTRAST_DEF,
6a7eba24
JFM
96 },
97 .set = sd_setcontrast,
98 .get = sd_getcontrast,
99 },
6a7eba24
JFM
100 {
101 {
102 .id = V4L2_CID_SATURATION,
103 .type = V4L2_CTRL_TYPE_INTEGER,
104 .name = "Color",
105 .minimum = 0,
a5ae2062 106 .maximum = 63,
6a7eba24 107 .step = 1,
a5ae2062
JFM
108#define COLOR_DEF 31
109 .default_value = COLOR_DEF,
6a7eba24
JFM
110 },
111 .set = sd_setcolors,
112 .get = sd_getcolors,
113 },
114};
115
cc611b8a 116static const struct v4l2_pix_format vga_mode[] = {
c2446b3e
JFM
117 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
118 .bytesperline = 320,
119 .sizeimage = 320 * 240 * 3 / 8 + 590,
120 .colorspace = V4L2_COLORSPACE_JPEG,
121 .priv = 1},
122 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
123 .bytesperline = 640,
124 .sizeimage = 640 * 480 * 3 / 8 + 590,
125 .colorspace = V4L2_COLORSPACE_JPEG,
126 .priv = 0},
6a7eba24
JFM
127};
128
cc611b8a 129static const struct v4l2_pix_format sif_mode[] = {
c2446b3e
JFM
130 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
131 .bytesperline = 176,
132 .sizeimage = 176 * 144 * 3 / 8 + 590,
133 .colorspace = V4L2_COLORSPACE_JPEG,
134 .priv = 1},
135 {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
136 .bytesperline = 352,
137 .sizeimage = 352 * 288 * 3 / 8 + 590,
138 .colorspace = V4L2_COLORSPACE_JPEG,
139 .priv = 0},
6a7eba24
JFM
140};
141
142/* Frame packet header offsets for the spca500 */
143#define SPCA500_OFFSET_PADDINGLB 2
144#define SPCA500_OFFSET_PADDINGHB 3
145#define SPCA500_OFFSET_MODE 4
146#define SPCA500_OFFSET_IMGWIDTH 5
147#define SPCA500_OFFSET_IMGHEIGHT 6
148#define SPCA500_OFFSET_IMGMODE 7
149#define SPCA500_OFFSET_QTBLINDEX 8
150#define SPCA500_OFFSET_FRAMSEQ 9
151#define SPCA500_OFFSET_CDSPINFO 10
152#define SPCA500_OFFSET_GPIO 11
153#define SPCA500_OFFSET_AUGPIO 12
154#define SPCA500_OFFSET_DATA 16
155
156
a5ae2062 157static const __u16 spca500_visual_defaults[][3] = {
6a7eba24
JFM
158 {0x00, 0x0003, 0x816b}, /* SSI not active sync with vsync,
159 * hue (H byte) = 0,
160 * saturation/hue enable,
161 * brightness/contrast enable.
162 */
163 {0x00, 0x0000, 0x8167}, /* brightness = 0 */
164 {0x00, 0x0020, 0x8168}, /* contrast = 0 */
165 {0x00, 0x0003, 0x816b}, /* SSI not active sync with vsync,
166 * hue (H byte) = 0, saturation/hue enable,
167 * brightness/contrast enable.
168 * was 0x0003, now 0x0000.
169 */
170 {0x00, 0x0000, 0x816a}, /* hue (L byte) = 0 */
171 {0x00, 0x0020, 0x8169}, /* saturation = 0x20 */
172 {0x00, 0x0050, 0x8157}, /* edge gain high threshold */
173 {0x00, 0x0030, 0x8158}, /* edge gain low threshold */
174 {0x00, 0x0028, 0x8159}, /* edge bandwidth high threshold */
175 {0x00, 0x000a, 0x815a}, /* edge bandwidth low threshold */
176 {0x00, 0x0001, 0x8202}, /* clock rate compensation = 1/25 sec/frame */
177 {0x0c, 0x0004, 0x0000},
178 /* set interface */
a5ae2062 179 {}
6a7eba24 180};
a5ae2062 181static const __u16 Clicksmart510_defaults[][3] = {
6a7eba24
JFM
182 {0x00, 0x00, 0x8211},
183 {0x00, 0x01, 0x82c0},
184 {0x00, 0x10, 0x82cb},
185 {0x00, 0x0f, 0x800d},
186 {0x00, 0x82, 0x8225},
187 {0x00, 0x21, 0x8228},
188 {0x00, 0x00, 0x8203},
189 {0x00, 0x00, 0x8204},
190 {0x00, 0x08, 0x8205},
191 {0x00, 0xf8, 0x8206},
192 {0x00, 0x28, 0x8207},
193 {0x00, 0xa0, 0x8208},
194 {0x00, 0x08, 0x824a},
195 {0x00, 0x08, 0x8214},
196 {0x00, 0x80, 0x82c1},
197 {0x00, 0x00, 0x82c2},
198 {0x00, 0x00, 0x82ca},
199 {0x00, 0x80, 0x82c1},
200 {0x00, 0x04, 0x82c2},
201 {0x00, 0x00, 0x82ca},
202 {0x00, 0xfc, 0x8100},
203 {0x00, 0xfc, 0x8105},
204 {0x00, 0x30, 0x8101},
205 {0x00, 0x00, 0x8102},
206 {0x00, 0x00, 0x8103},
207 {0x00, 0x66, 0x8107},
208 {0x00, 0x00, 0x816b},
209 {0x00, 0x00, 0x8155},
210 {0x00, 0x01, 0x8156},
211 {0x00, 0x60, 0x8157},
212 {0x00, 0x40, 0x8158},
213 {0x00, 0x0a, 0x8159},
214 {0x00, 0x06, 0x815a},
215 {0x00, 0x00, 0x813f},
216 {0x00, 0x00, 0x8200},
217 {0x00, 0x19, 0x8201},
218 {0x00, 0x00, 0x82c1},
219 {0x00, 0xa0, 0x82c2},
220 {0x00, 0x00, 0x82ca},
221 {0x00, 0x00, 0x8117},
222 {0x00, 0x00, 0x8118},
223 {0x00, 0x65, 0x8119},
224 {0x00, 0x00, 0x811a},
225 {0x00, 0x00, 0x811b},
226 {0x00, 0x55, 0x811c},
227 {0x00, 0x65, 0x811d},
228 {0x00, 0x55, 0x811e},
229 {0x00, 0x16, 0x811f},
230 {0x00, 0x19, 0x8120},
231 {0x00, 0x80, 0x8103},
232 {0x00, 0x83, 0x816b},
233 {0x00, 0x25, 0x8168},
234 {0x00, 0x01, 0x820f},
235 {0x00, 0xff, 0x8115},
236 {0x00, 0x48, 0x8116},
237 {0x00, 0x50, 0x8151},
238 {0x00, 0x40, 0x8152},
239 {0x00, 0x78, 0x8153},
240 {0x00, 0x40, 0x8154},
241 {0x00, 0x00, 0x8167},
242 {0x00, 0x20, 0x8168},
243 {0x00, 0x00, 0x816a},
244 {0x00, 0x03, 0x816b},
245 {0x00, 0x20, 0x8169},
246 {0x00, 0x60, 0x8157},
247 {0x00, 0x00, 0x8190},
248 {0x00, 0x00, 0x81a1},
249 {0x00, 0x00, 0x81b2},
250 {0x00, 0x27, 0x8191},
251 {0x00, 0x27, 0x81a2},
252 {0x00, 0x27, 0x81b3},
253 {0x00, 0x4b, 0x8192},
254 {0x00, 0x4b, 0x81a3},
255 {0x00, 0x4b, 0x81b4},
256 {0x00, 0x66, 0x8193},
257 {0x00, 0x66, 0x81a4},
258 {0x00, 0x66, 0x81b5},
259 {0x00, 0x79, 0x8194},
260 {0x00, 0x79, 0x81a5},
261 {0x00, 0x79, 0x81b6},
262 {0x00, 0x8a, 0x8195},
263 {0x00, 0x8a, 0x81a6},
264 {0x00, 0x8a, 0x81b7},
265 {0x00, 0x9b, 0x8196},
266 {0x00, 0x9b, 0x81a7},
267 {0x00, 0x9b, 0x81b8},
268 {0x00, 0xa6, 0x8197},
269 {0x00, 0xa6, 0x81a8},
270 {0x00, 0xa6, 0x81b9},
271 {0x00, 0xb2, 0x8198},
272 {0x00, 0xb2, 0x81a9},
273 {0x00, 0xb2, 0x81ba},
274 {0x00, 0xbe, 0x8199},
275 {0x00, 0xbe, 0x81aa},
276 {0x00, 0xbe, 0x81bb},
277 {0x00, 0xc8, 0x819a},
278 {0x00, 0xc8, 0x81ab},
279 {0x00, 0xc8, 0x81bc},
280 {0x00, 0xd2, 0x819b},
281 {0x00, 0xd2, 0x81ac},
282 {0x00, 0xd2, 0x81bd},
283 {0x00, 0xdb, 0x819c},
284 {0x00, 0xdb, 0x81ad},
285 {0x00, 0xdb, 0x81be},
286 {0x00, 0xe4, 0x819d},
287 {0x00, 0xe4, 0x81ae},
288 {0x00, 0xe4, 0x81bf},
289 {0x00, 0xed, 0x819e},
290 {0x00, 0xed, 0x81af},
291 {0x00, 0xed, 0x81c0},
292 {0x00, 0xf7, 0x819f},
293 {0x00, 0xf7, 0x81b0},
294 {0x00, 0xf7, 0x81c1},
295 {0x00, 0xff, 0x81a0},
296 {0x00, 0xff, 0x81b1},
297 {0x00, 0xff, 0x81c2},
298 {0x00, 0x03, 0x8156},
299 {0x00, 0x00, 0x8211},
300 {0x00, 0x20, 0x8168},
301 {0x00, 0x01, 0x8202},
302 {0x00, 0x30, 0x8101},
303 {0x00, 0x00, 0x8111},
304 {0x00, 0x00, 0x8112},
305 {0x00, 0x00, 0x8113},
306 {0x00, 0x00, 0x8114},
307 {}
308};
309
a5ae2062 310static const __u8 qtable_creative_pccam[2][64] = {
6a7eba24
JFM
311 { /* Q-table Y-components */
312 0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12,
313 0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11,
314 0x04, 0x04, 0x05, 0x07, 0x0c, 0x11, 0x15, 0x11,
315 0x04, 0x05, 0x07, 0x09, 0x0f, 0x1a, 0x18, 0x13,
316 0x05, 0x07, 0x0b, 0x11, 0x14, 0x21, 0x1f, 0x17,
317 0x07, 0x0b, 0x11, 0x13, 0x18, 0x1f, 0x22, 0x1c,
318 0x0f, 0x13, 0x17, 0x1a, 0x1f, 0x24, 0x24, 0x1e,
319 0x16, 0x1c, 0x1d, 0x1d, 0x22, 0x1e, 0x1f, 0x1e},
320 { /* Q-table C-components */
321 0x05, 0x05, 0x07, 0x0e, 0x1e, 0x1e, 0x1e, 0x1e,
322 0x05, 0x06, 0x08, 0x14, 0x1e, 0x1e, 0x1e, 0x1e,
323 0x07, 0x08, 0x11, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
324 0x0e, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
325 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
326 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
327 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
328 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e}
329};
330
a5ae2062 331static const __u8 qtable_kodak_ez200[2][64] = {
6a7eba24
JFM
332 { /* Q-table Y-components */
333 0x02, 0x01, 0x01, 0x02, 0x02, 0x04, 0x05, 0x06,
334 0x01, 0x01, 0x01, 0x02, 0x03, 0x06, 0x06, 0x06,
335 0x01, 0x01, 0x02, 0x02, 0x04, 0x06, 0x07, 0x06,
336 0x01, 0x02, 0x02, 0x03, 0x05, 0x09, 0x08, 0x06,
337 0x02, 0x02, 0x04, 0x06, 0x07, 0x0b, 0x0a, 0x08,
338 0x02, 0x04, 0x06, 0x06, 0x08, 0x0a, 0x0b, 0x09,
339 0x05, 0x06, 0x08, 0x09, 0x0a, 0x0c, 0x0c, 0x0a,
340 0x07, 0x09, 0x0a, 0x0a, 0x0b, 0x0a, 0x0a, 0x0a},
341 { /* Q-table C-components */
342 0x02, 0x02, 0x02, 0x05, 0x0a, 0x0a, 0x0a, 0x0a,
343 0x02, 0x02, 0x03, 0x07, 0x0a, 0x0a, 0x0a, 0x0a,
344 0x02, 0x03, 0x06, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
345 0x05, 0x07, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
346 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
347 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
348 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
349 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a}
350};
351
a5ae2062 352static const __u8 qtable_pocketdv[2][64] = {
956e42d2 353 { /* Q-table Y-components start registers 0x8800 */
6a7eba24
JFM
354 0x06, 0x04, 0x04, 0x06, 0x0a, 0x10, 0x14, 0x18,
355 0x05, 0x05, 0x06, 0x08, 0x0a, 0x17, 0x18, 0x16,
356 0x06, 0x05, 0x06, 0x0a, 0x10, 0x17, 0x1c, 0x16,
357 0x06, 0x07, 0x09, 0x0c, 0x14, 0x23, 0x20, 0x19,
358 0x07, 0x09, 0x0f, 0x16, 0x1b, 0x2c, 0x29, 0x1f,
359 0x0a, 0x0e, 0x16, 0x1a, 0x20, 0x2a, 0x2d, 0x25,
360 0x14, 0x1a, 0x1f, 0x23, 0x29, 0x30, 0x30, 0x28,
361 0x1d, 0x25, 0x26, 0x27, 0x2d, 0x28, 0x29, 0x28,
362 },
956e42d2 363 { /* Q-table C-components start registers 0x8840 */
6a7eba24
JFM
364 0x07, 0x07, 0x0a, 0x13, 0x28, 0x28, 0x28, 0x28,
365 0x07, 0x08, 0x0a, 0x1a, 0x28, 0x28, 0x28, 0x28,
366 0x0a, 0x0a, 0x16, 0x28, 0x28, 0x28, 0x28, 0x28,
367 0x13, 0x1a, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
368 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
369 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
370 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
371 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28}
372};
373
739570bb
JFM
374/* read 'len' bytes to gspca_dev->usb_buf */
375static void reg_r(struct gspca_dev *gspca_dev,
376 __u16 index,
377 __u16 length)
6a7eba24 378{
739570bb
JFM
379 usb_control_msg(gspca_dev->dev,
380 usb_rcvctrlpipe(gspca_dev->dev, 0),
6a7eba24
JFM
381 0,
382 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
383 0, /* value */
739570bb 384 index, gspca_dev->usb_buf, length, 500);
6a7eba24
JFM
385}
386
739570bb 387static int reg_w(struct gspca_dev *gspca_dev,
6a7eba24
JFM
388 __u16 req, __u16 index, __u16 value)
389{
390 int ret;
391
a5ae2062 392 PDEBUG(D_USBO, "reg write: [0x%02x] = 0x%02x", index, value);
739570bb
JFM
393 ret = usb_control_msg(gspca_dev->dev,
394 usb_sndctrlpipe(gspca_dev->dev, 0),
6a7eba24 395 req,
bf7f0b98 396 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
6a7eba24 397 value, index, NULL, 0, 500);
6a7eba24
JFM
398 if (ret < 0)
399 PDEBUG(D_ERR, "reg write: error %d", ret);
400 return ret;
401}
402
403/* returns: negative is error, pos or zero is data */
739570bb 404static int reg_r_12(struct gspca_dev *gspca_dev,
6a7eba24
JFM
405 __u16 req, /* bRequest */
406 __u16 index, /* wIndex */
407 __u16 length) /* wLength (1 or 2 only) */
408{
409 int ret;
6a7eba24 410
739570bb
JFM
411 gspca_dev->usb_buf[1] = 0;
412 ret = usb_control_msg(gspca_dev->dev,
413 usb_rcvctrlpipe(gspca_dev->dev, 0),
6a7eba24
JFM
414 req,
415 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
416 0, /* value */
417 index,
739570bb 418 gspca_dev->usb_buf, length,
6a7eba24
JFM
419 500); /* timeout */
420 if (ret < 0) {
a5ae2062 421 PDEBUG(D_ERR, "reg_r_12 err %d", ret);
6a7eba24
JFM
422 return -1;
423 }
739570bb 424 return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0];
6a7eba24
JFM
425}
426
427/*
428 * Simple function to wait for a given 8-bit value to be returned from
429 * a reg_read call.
430 * Returns: negative is error or timeout, zero is success.
431 */
739570bb 432static int reg_r_wait(struct gspca_dev *gspca_dev,
6a7eba24
JFM
433 __u16 reg, __u16 index, __u16 value)
434{
435 int ret, cnt = 20;
436
437 while (--cnt > 0) {
739570bb 438 ret = reg_r_12(gspca_dev, reg, index, 1);
6a7eba24
JFM
439 if (ret == value)
440 return 0;
441 msleep(50);
442 }
443 return -EIO;
444}
445
446static int write_vector(struct gspca_dev *gspca_dev,
a5ae2062 447 const __u16 data[][3])
6a7eba24 448{
6a7eba24
JFM
449 int ret, i = 0;
450
451 while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) {
739570bb 452 ret = reg_w(gspca_dev, data[i][0], data[i][2], data[i][1]);
6a7eba24
JFM
453 if (ret < 0)
454 return ret;
455 i++;
456 }
457 return 0;
458}
459
460static int spca50x_setup_qtable(struct gspca_dev *gspca_dev,
461 unsigned int request,
462 unsigned int ybase,
463 unsigned int cbase,
a5ae2062 464 const __u8 qtable[2][64])
6a7eba24 465{
6a7eba24
JFM
466 int i, err;
467
468 /* loop over y components */
469 for (i = 0; i < 64; i++) {
739570bb 470 err = reg_w(gspca_dev, request, ybase + i, qtable[0][i]);
6a7eba24
JFM
471 if (err < 0)
472 return err;
473 }
474
475 /* loop over c components */
476 for (i = 0; i < 64; i++) {
739570bb 477 err = reg_w(gspca_dev, request, cbase + i, qtable[1][i]);
6a7eba24
JFM
478 if (err < 0)
479 return err;
480 }
481 return 0;
482}
483
484static void spca500_ping310(struct gspca_dev *gspca_dev)
485{
739570bb 486 reg_r(gspca_dev, 0x0d04, 2);
a5ae2062 487 PDEBUG(D_STREAM, "ClickSmart310 ping 0x0d04 0x%02x 0x%02x",
739570bb 488 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
6a7eba24
JFM
489}
490
491static void spca500_clksmart310_init(struct gspca_dev *gspca_dev)
492{
739570bb 493 reg_r(gspca_dev, 0x0d05, 2);
a5ae2062 494 PDEBUG(D_STREAM, "ClickSmart310 init 0x0d05 0x%02x 0x%02x",
739570bb
JFM
495 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
496 reg_w(gspca_dev, 0x00, 0x8167, 0x5a);
6a7eba24
JFM
497 spca500_ping310(gspca_dev);
498
739570bb
JFM
499 reg_w(gspca_dev, 0x00, 0x8168, 0x22);
500 reg_w(gspca_dev, 0x00, 0x816a, 0xc0);
501 reg_w(gspca_dev, 0x00, 0x816b, 0x0b);
502 reg_w(gspca_dev, 0x00, 0x8169, 0x25);
503 reg_w(gspca_dev, 0x00, 0x8157, 0x5b);
504 reg_w(gspca_dev, 0x00, 0x8158, 0x5b);
505 reg_w(gspca_dev, 0x00, 0x813f, 0x03);
506 reg_w(gspca_dev, 0x00, 0x8151, 0x4a);
507 reg_w(gspca_dev, 0x00, 0x8153, 0x78);
508 reg_w(gspca_dev, 0x00, 0x0d01, 0x04);
6a7eba24 509 /* 00 for adjust shutter */
739570bb
JFM
510 reg_w(gspca_dev, 0x00, 0x0d02, 0x01);
511 reg_w(gspca_dev, 0x00, 0x8169, 0x25);
512 reg_w(gspca_dev, 0x00, 0x0d01, 0x02);
6a7eba24
JFM
513}
514
515static void spca500_setmode(struct gspca_dev *gspca_dev,
516 __u8 xmult, __u8 ymult)
517{
518 int mode;
519
520 /* set x multiplier */
739570bb 521 reg_w(gspca_dev, 0, 0x8001, xmult);
6a7eba24
JFM
522
523 /* set y multiplier */
739570bb 524 reg_w(gspca_dev, 0, 0x8002, ymult);
6a7eba24
JFM
525
526 /* use compressed mode, VGA, with mode specific subsample */
c2446b3e 527 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
739570bb 528 reg_w(gspca_dev, 0, 0x8003, mode << 4);
6a7eba24
JFM
529}
530
531static int spca500_full_reset(struct gspca_dev *gspca_dev)
532{
533 int err;
534
535 /* send the reset command */
739570bb 536 err = reg_w(gspca_dev, 0xe0, 0x0001, 0x0000);
6a7eba24
JFM
537 if (err < 0)
538 return err;
539
540 /* wait for the reset to complete */
739570bb 541 err = reg_r_wait(gspca_dev, 0x06, 0x0000, 0x0000);
6a7eba24
JFM
542 if (err < 0)
543 return err;
739570bb 544 err = reg_w(gspca_dev, 0xe0, 0x0000, 0x0000);
6a7eba24
JFM
545 if (err < 0)
546 return err;
739570bb 547 err = reg_r_wait(gspca_dev, 0x06, 0, 0);
6a7eba24 548 if (err < 0) {
a5ae2062 549 PDEBUG(D_ERR, "reg_r_wait() failed");
6a7eba24
JFM
550 return err;
551 }
552 /* all ok */
553 return 0;
554}
555
556/* Synchro the Bridge with sensor */
557/* Maybe that will work on all spca500 chip */
558/* because i only own a clicksmart310 try for that chip */
559/* using spca50x_set_packet_size() cause an Ooops here */
560/* usb_set_interface from kernel 2.6.x clear all the urb stuff */
561/* up-port the same feature as in 2.4.x kernel */
562static int spca500_synch310(struct gspca_dev *gspca_dev)
563{
6a7eba24
JFM
564 if (usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0) < 0) {
565 PDEBUG(D_ERR, "Set packet size: set interface error");
566 goto error;
567 }
568 spca500_ping310(gspca_dev);
569
739570bb 570 reg_r(gspca_dev, 0x0d00, 1);
6a7eba24
JFM
571
572 /* need alt setting here */
573 PDEBUG(D_PACK, "ClickSmart310 sync alt: %d", gspca_dev->alt);
574
575 /* Windoze use pipe with altsetting 6 why 7 here */
576 if (usb_set_interface(gspca_dev->dev,
577 gspca_dev->iface,
578 gspca_dev->alt) < 0) {
579 PDEBUG(D_ERR, "Set packet size: set interface error");
580 goto error;
581 }
582 return 0;
583error:
584 return -EBUSY;
585}
586
587static void spca500_reinit(struct gspca_dev *gspca_dev)
588{
589 int err;
590 __u8 Data;
591
592 /* some unknow command from Aiptek pocket dv and family300 */
593
739570bb
JFM
594 reg_w(gspca_dev, 0x00, 0x0d01, 0x01);
595 reg_w(gspca_dev, 0x00, 0x0d03, 0x00);
596 reg_w(gspca_dev, 0x00, 0x0d02, 0x01);
6a7eba24
JFM
597
598 /* enable drop packet */
739570bb 599 reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
6a7eba24
JFM
600
601 err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840,
602 qtable_pocketdv);
603 if (err < 0)
604 PDEBUG(D_ERR|D_STREAM, "spca50x_setup_qtable failed on init");
605
606 /* set qtable index */
739570bb 607 reg_w(gspca_dev, 0x00, 0x8880, 2);
6a7eba24 608 /* family cam Quicksmart stuff */
739570bb 609 reg_w(gspca_dev, 0x00, 0x800a, 0x00);
6a7eba24 610 /* Set agc transfer: synced inbetween frames */
739570bb 611 reg_w(gspca_dev, 0x00, 0x820f, 0x01);
6a7eba24 612 /* Init SDRAM - needed for SDRAM access */
739570bb 613 reg_w(gspca_dev, 0x00, 0x870a, 0x04);
6a7eba24 614 /*Start init sequence or stream */
739570bb 615 reg_w(gspca_dev, 0, 0x8003, 0x00);
6a7eba24 616 /* switch to video camera mode */
739570bb 617 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
6a7eba24 618 msleep(2000);
739570bb
JFM
619 if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0) {
620 reg_r(gspca_dev, 0x816b, 1);
621 Data = gspca_dev->usb_buf[0];
622 reg_w(gspca_dev, 0x00, 0x816b, Data);
623 }
6a7eba24
JFM
624}
625
626/* this function is called at probe time */
627static int sd_config(struct gspca_dev *gspca_dev,
628 const struct usb_device_id *id)
629{
630 struct sd *sd = (struct sd *) gspca_dev;
631 struct cam *cam;
9d64fdb1 632
6a7eba24 633 cam = &gspca_dev->cam;
9d64fdb1 634 sd->subtype = id->driver_info;
6a7eba24
JFM
635 if (sd->subtype != LogitechClickSmart310) {
636 cam->cam_mode = vga_mode;
80297125 637 cam->nmodes = ARRAY_SIZE(vga_mode);
6a7eba24
JFM
638 } else {
639 cam->cam_mode = sif_mode;
80297125 640 cam->nmodes = ARRAY_SIZE(sif_mode);
6a7eba24 641 }
a5ae2062
JFM
642 sd->brightness = BRIGHTNESS_DEF;
643 sd->contrast = CONTRAST_DEF;
644 sd->colors = COLOR_DEF;
77ac0baf 645 sd->quality = QUALITY_DEF;
6a7eba24
JFM
646 return 0;
647}
648
012d6b02
JFM
649/* this function is called at probe and resume time */
650static int sd_init(struct gspca_dev *gspca_dev)
6a7eba24
JFM
651{
652 struct sd *sd = (struct sd *) gspca_dev;
653
654 /* initialisation of spca500 based cameras is deferred */
655 PDEBUG(D_STREAM, "SPCA500 init");
656 if (sd->subtype == LogitechClickSmart310)
657 spca500_clksmart310_init(gspca_dev);
658/* else
659 spca500_initialise(gspca_dev); */
660 PDEBUG(D_STREAM, "SPCA500 init done");
661 return 0;
662}
663
72ab97ce 664static int sd_start(struct gspca_dev *gspca_dev)
6a7eba24
JFM
665{
666 struct sd *sd = (struct sd *) gspca_dev;
667 int err;
668 __u8 Data;
669 __u8 xmult, ymult;
670
71cb2764
JFM
671 /* create the JPEG header */
672 sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
673 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
674 0x22); /* JPEG 411 */
675 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
676
6a7eba24
JFM
677 if (sd->subtype == LogitechClickSmart310) {
678 xmult = 0x16;
679 ymult = 0x12;
680 } else {
681 xmult = 0x28;
682 ymult = 0x1e;
683 }
684
685 /* is there a sensor here ? */
739570bb
JFM
686 reg_r(gspca_dev, 0x8a04, 1);
687 PDEBUG(D_STREAM, "Spca500 Sensor Address 0x%02x",
688 gspca_dev->usb_buf[0]);
689 PDEBUG(D_STREAM, "Spca500 curr_mode: %d Xmult: 0x%02x, Ymult: 0x%02x",
6a7eba24
JFM
690 gspca_dev->curr_mode, xmult, ymult);
691
692 /* setup qtable */
693 switch (sd->subtype) {
694 case LogitechClickSmart310:
695 spca500_setmode(gspca_dev, xmult, ymult);
696
697 /* enable drop packet */
739570bb
JFM
698 reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
699 reg_w(gspca_dev, 0x00, 0x8880, 3);
6a7eba24
JFM
700 err = spca50x_setup_qtable(gspca_dev,
701 0x00, 0x8800, 0x8840,
702 qtable_creative_pccam);
703 if (err < 0)
704 PDEBUG(D_ERR, "spca50x_setup_qtable failed");
705 /* Init SDRAM - needed for SDRAM access */
739570bb 706 reg_w(gspca_dev, 0x00, 0x870a, 0x04);
6a7eba24
JFM
707
708 /* switch to video camera mode */
739570bb 709 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
6a7eba24 710 msleep(500);
739570bb 711 if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
a5ae2062 712 PDEBUG(D_ERR, "reg_r_wait() failed");
6a7eba24 713
739570bb
JFM
714 reg_r(gspca_dev, 0x816b, 1);
715 Data = gspca_dev->usb_buf[0];
716 reg_w(gspca_dev, 0x00, 0x816b, Data);
6a7eba24
JFM
717
718 spca500_synch310(gspca_dev);
719
720 write_vector(gspca_dev, spca500_visual_defaults);
721 spca500_setmode(gspca_dev, xmult, ymult);
722 /* enable drop packet */
48d7a891
JFM
723 err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
724 if (err < 0)
6a7eba24 725 PDEBUG(D_ERR, "failed to enable drop packet");
739570bb 726 reg_w(gspca_dev, 0x00, 0x8880, 3);
6a7eba24
JFM
727 err = spca50x_setup_qtable(gspca_dev,
728 0x00, 0x8800, 0x8840,
729 qtable_creative_pccam);
730 if (err < 0)
731 PDEBUG(D_ERR, "spca50x_setup_qtable failed");
732
733 /* Init SDRAM - needed for SDRAM access */
739570bb 734 reg_w(gspca_dev, 0x00, 0x870a, 0x04);
6a7eba24
JFM
735
736 /* switch to video camera mode */
739570bb 737 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
6a7eba24 738
739570bb 739 if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
a5ae2062 740 PDEBUG(D_ERR, "reg_r_wait() failed");
6a7eba24 741
739570bb
JFM
742 reg_r(gspca_dev, 0x816b, 1);
743 Data = gspca_dev->usb_buf[0];
744 reg_w(gspca_dev, 0x00, 0x816b, Data);
6a7eba24
JFM
745 break;
746 case CreativePCCam300: /* Creative PC-CAM 300 640x480 CCD */
747 case IntelPocketPCCamera: /* FIXME: Temporary fix for
748 * Intel Pocket PC Camera
749 * - NWG (Sat 29th March 2003) */
750
751 /* do a full reset */
956e42d2
JFM
752 err = spca500_full_reset(gspca_dev);
753 if (err < 0)
6a7eba24
JFM
754 PDEBUG(D_ERR, "spca500_full_reset failed");
755
756 /* enable drop packet */
739570bb 757 err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
6a7eba24
JFM
758 if (err < 0)
759 PDEBUG(D_ERR, "failed to enable drop packet");
739570bb 760 reg_w(gspca_dev, 0x00, 0x8880, 3);
6a7eba24
JFM
761 err = spca50x_setup_qtable(gspca_dev,
762 0x00, 0x8800, 0x8840,
763 qtable_creative_pccam);
764 if (err < 0)
765 PDEBUG(D_ERR, "spca50x_setup_qtable failed");
766
767 spca500_setmode(gspca_dev, xmult, ymult);
739570bb 768 reg_w(gspca_dev, 0x20, 0x0001, 0x0004);
6a7eba24
JFM
769
770 /* switch to video camera mode */
739570bb 771 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
6a7eba24 772
739570bb 773 if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
a5ae2062 774 PDEBUG(D_ERR, "reg_r_wait() failed");
6a7eba24 775
739570bb
JFM
776 reg_r(gspca_dev, 0x816b, 1);
777 Data = gspca_dev->usb_buf[0];
778 reg_w(gspca_dev, 0x00, 0x816b, Data);
6a7eba24 779
a5ae2062 780/* write_vector(gspca_dev, spca500_visual_defaults); */
6a7eba24
JFM
781 break;
782 case KodakEZ200: /* Kodak EZ200 */
783
784 /* do a full reset */
785 err = spca500_full_reset(gspca_dev);
786 if (err < 0)
787 PDEBUG(D_ERR, "spca500_full_reset failed");
788 /* enable drop packet */
739570bb
JFM
789 reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
790 reg_w(gspca_dev, 0x00, 0x8880, 0);
6a7eba24
JFM
791 err = spca50x_setup_qtable(gspca_dev,
792 0x00, 0x8800, 0x8840,
793 qtable_kodak_ez200);
794 if (err < 0)
795 PDEBUG(D_ERR, "spca50x_setup_qtable failed");
796 spca500_setmode(gspca_dev, xmult, ymult);
797
739570bb 798 reg_w(gspca_dev, 0x20, 0x0001, 0x0004);
6a7eba24
JFM
799
800 /* switch to video camera mode */
739570bb 801 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
6a7eba24 802
739570bb 803 if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
a5ae2062 804 PDEBUG(D_ERR, "reg_r_wait() failed");
6a7eba24 805
739570bb
JFM
806 reg_r(gspca_dev, 0x816b, 1);
807 Data = gspca_dev->usb_buf[0];
808 reg_w(gspca_dev, 0x00, 0x816b, Data);
6a7eba24 809
a5ae2062 810/* write_vector(gspca_dev, spca500_visual_defaults); */
6a7eba24
JFM
811 break;
812
813 case BenqDC1016:
814 case DLinkDSC350: /* FamilyCam 300 */
815 case AiptekPocketDV: /* Aiptek PocketDV */
816 case Gsmartmini: /*Mustek Gsmart Mini */
817 case MustekGsmart300: /* Mustek Gsmart 300 */
818 case PalmPixDC85:
819 case Optimedia:
820 case ToptroIndus:
821 case AgfaCl20:
822 spca500_reinit(gspca_dev);
739570bb 823 reg_w(gspca_dev, 0x00, 0x0d01, 0x01);
6a7eba24 824 /* enable drop packet */
739570bb 825 reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
6a7eba24
JFM
826
827 err = spca50x_setup_qtable(gspca_dev,
828 0x00, 0x8800, 0x8840, qtable_pocketdv);
829 if (err < 0)
830 PDEBUG(D_ERR, "spca50x_setup_qtable failed");
739570bb 831 reg_w(gspca_dev, 0x00, 0x8880, 2);
6a7eba24
JFM
832
833 /* familycam Quicksmart pocketDV stuff */
739570bb 834 reg_w(gspca_dev, 0x00, 0x800a, 0x00);
6a7eba24 835 /* Set agc transfer: synced inbetween frames */
739570bb 836 reg_w(gspca_dev, 0x00, 0x820f, 0x01);
6a7eba24 837 /* Init SDRAM - needed for SDRAM access */
739570bb 838 reg_w(gspca_dev, 0x00, 0x870a, 0x04);
6a7eba24 839
956e42d2 840 spca500_setmode(gspca_dev, xmult, ymult);
6a7eba24 841 /* switch to video camera mode */
739570bb 842 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
6a7eba24 843
739570bb 844 reg_r_wait(gspca_dev, 0, 0x8000, 0x44);
6a7eba24 845
739570bb
JFM
846 reg_r(gspca_dev, 0x816b, 1);
847 Data = gspca_dev->usb_buf[0];
848 reg_w(gspca_dev, 0x00, 0x816b, Data);
6a7eba24
JFM
849 break;
850 case LogitechTraveler:
851 case LogitechClickSmart510:
739570bb 852 reg_w(gspca_dev, 0x02, 0x00, 0x00);
6a7eba24 853 /* enable drop packet */
739570bb 854 reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
6a7eba24
JFM
855
856 err = spca50x_setup_qtable(gspca_dev,
857 0x00, 0x8800,
858 0x8840, qtable_creative_pccam);
859 if (err < 0)
860 PDEBUG(D_ERR, "spca50x_setup_qtable failed");
739570bb
JFM
861 reg_w(gspca_dev, 0x00, 0x8880, 3);
862 reg_w(gspca_dev, 0x00, 0x800a, 0x00);
6a7eba24 863 /* Init SDRAM - needed for SDRAM access */
739570bb 864 reg_w(gspca_dev, 0x00, 0x870a, 0x04);
6a7eba24
JFM
865
866 spca500_setmode(gspca_dev, xmult, ymult);
867
868 /* switch to video camera mode */
739570bb
JFM
869 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
870 reg_r_wait(gspca_dev, 0, 0x8000, 0x44);
6a7eba24 871
739570bb
JFM
872 reg_r(gspca_dev, 0x816b, 1);
873 Data = gspca_dev->usb_buf[0];
874 reg_w(gspca_dev, 0x00, 0x816b, Data);
6a7eba24
JFM
875 write_vector(gspca_dev, Clicksmart510_defaults);
876 break;
877 }
72ab97ce 878 return 0;
6a7eba24
JFM
879}
880
881static void sd_stopN(struct gspca_dev *gspca_dev)
882{
739570bb 883 reg_w(gspca_dev, 0, 0x8003, 0x00);
6a7eba24
JFM
884
885 /* switch to video camera mode */
739570bb
JFM
886 reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
887 reg_r(gspca_dev, 0x8000, 1);
888 PDEBUG(D_STREAM, "stop SPCA500 done reg8000: 0x%2x",
889 gspca_dev->usb_buf[0]);
6a7eba24
JFM
890}
891
71cb2764
JFM
892static void sd_stop0(struct gspca_dev *gspca_dev)
893{
894 struct sd *sd = (struct sd *) gspca_dev;
895
896 kfree(sd->jpeg_hdr);
897}
898
6a7eba24
JFM
899static void sd_pkt_scan(struct gspca_dev *gspca_dev,
900 struct gspca_frame *frame, /* target */
a5ae2062 901 __u8 *data, /* isoc packet */
6a7eba24
JFM
902 int len) /* iso packet length */
903{
904 struct sd *sd = (struct sd *) gspca_dev;
905 int i;
a5ae2062 906 static __u8 ffd9[] = {0xff, 0xd9};
6a7eba24
JFM
907
908/* frames are jpeg 4.1.1 without 0xff escape */
909 if (data[0] == 0xff) {
910 if (data[1] != 0x01) { /* drop packet */
911/* gspca_dev->last_packet_type = DISCARD_PACKET; */
912 return;
913 }
914 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
915 ffd9, 2);
916
917 /* put the JPEG header in the new frame */
71cb2764
JFM
918 gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
919 sd->jpeg_hdr, JPEG_HDR_SZ);
6a7eba24
JFM
920
921 data += SPCA500_OFFSET_DATA;
922 len -= SPCA500_OFFSET_DATA;
923 } else {
924 data += 1;
925 len -= 1;
926 }
927
928 /* add 0x00 after 0xff */
59746e13
JFM
929 i = 0;
930 do {
931 if (data[i] == 0xff) {
932 gspca_frame_add(gspca_dev, INTER_PACKET, frame,
933 data, i + 1);
934 len -= i;
935 data += i;
936 *data = 0x00;
937 i = 0;
938 }
939 i++;
940 } while (i < len);
941 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
6a7eba24
JFM
942}
943
944static void setbrightness(struct gspca_dev *gspca_dev)
945{
946 struct sd *sd = (struct sd *) gspca_dev;
947
739570bb 948 reg_w(gspca_dev, 0x00, 0x8167,
6a7eba24
JFM
949 (__u8) (sd->brightness - 128));
950}
951
6a7eba24
JFM
952static void setcontrast(struct gspca_dev *gspca_dev)
953{
954 struct sd *sd = (struct sd *) gspca_dev;
955
739570bb 956 reg_w(gspca_dev, 0x00, 0x8168, sd->contrast);
6a7eba24
JFM
957}
958
6a7eba24
JFM
959static void setcolors(struct gspca_dev *gspca_dev)
960{
961 struct sd *sd = (struct sd *) gspca_dev;
962
739570bb 963 reg_w(gspca_dev, 0x00, 0x8169, sd->colors);
6a7eba24
JFM
964}
965
6a7eba24
JFM
966static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
967{
968 struct sd *sd = (struct sd *) gspca_dev;
969
970 sd->brightness = val;
971 if (gspca_dev->streaming)
972 setbrightness(gspca_dev);
973 return 0;
974}
975
976static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
977{
978 struct sd *sd = (struct sd *) gspca_dev;
979
6a7eba24
JFM
980 *val = sd->brightness;
981 return 0;
982}
983
984static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
985{
986 struct sd *sd = (struct sd *) gspca_dev;
987
988 sd->contrast = val;
989 if (gspca_dev->streaming)
990 setcontrast(gspca_dev);
991 return 0;
992}
993
994static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
995{
996 struct sd *sd = (struct sd *) gspca_dev;
997
6a7eba24
JFM
998 *val = sd->contrast;
999 return 0;
1000}
1001
1002static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1003{
1004 struct sd *sd = (struct sd *) gspca_dev;
1005
1006 sd->colors = val;
1007 if (gspca_dev->streaming)
1008 setcolors(gspca_dev);
1009 return 0;
1010}
1011
1012static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1013{
1014 struct sd *sd = (struct sd *) gspca_dev;
1015
6a7eba24
JFM
1016 *val = sd->colors;
1017 return 0;
1018}
1019
77ac0baf
JFM
1020static int sd_set_jcomp(struct gspca_dev *gspca_dev,
1021 struct v4l2_jpegcompression *jcomp)
1022{
1023 struct sd *sd = (struct sd *) gspca_dev;
1024
1025 if (jcomp->quality < QUALITY_MIN)
1026 sd->quality = QUALITY_MIN;
1027 else if (jcomp->quality > QUALITY_MAX)
1028 sd->quality = QUALITY_MAX;
1029 else
1030 sd->quality = jcomp->quality;
1031 if (gspca_dev->streaming)
1032 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
1033 return 0;
1034}
1035
1036static int sd_get_jcomp(struct gspca_dev *gspca_dev,
1037 struct v4l2_jpegcompression *jcomp)
1038{
1039 struct sd *sd = (struct sd *) gspca_dev;
1040
1041 memset(jcomp, 0, sizeof *jcomp);
1042 jcomp->quality = sd->quality;
1043 jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
1044 | V4L2_JPEG_MARKER_DQT;
1045 return 0;
1046}
1047
6a7eba24
JFM
1048/* sub-driver description */
1049static struct sd_desc sd_desc = {
1050 .name = MODULE_NAME,
1051 .ctrls = sd_ctrls,
a5ae2062 1052 .nctrls = ARRAY_SIZE(sd_ctrls),
6a7eba24 1053 .config = sd_config,
012d6b02 1054 .init = sd_init,
6a7eba24
JFM
1055 .start = sd_start,
1056 .stopN = sd_stopN,
71cb2764 1057 .stop0 = sd_stop0,
6a7eba24 1058 .pkt_scan = sd_pkt_scan,
77ac0baf
JFM
1059 .get_jcomp = sd_get_jcomp,
1060 .set_jcomp = sd_set_jcomp,
6a7eba24
JFM
1061};
1062
1063/* -- module initialisation -- */
a5ae2062 1064static const __devinitdata struct usb_device_id device_table[] = {
87581aa5
JFM
1065 {USB_DEVICE(0x040a, 0x0300), .driver_info = KodakEZ200},
1066 {USB_DEVICE(0x041e, 0x400a), .driver_info = CreativePCCam300},
1067 {USB_DEVICE(0x046d, 0x0890), .driver_info = LogitechTraveler},
1068 {USB_DEVICE(0x046d, 0x0900), .driver_info = LogitechClickSmart310},
1069 {USB_DEVICE(0x046d, 0x0901), .driver_info = LogitechClickSmart510},
1070 {USB_DEVICE(0x04a5, 0x300c), .driver_info = BenqDC1016},
1071 {USB_DEVICE(0x04fc, 0x7333), .driver_info = PalmPixDC85},
1072 {USB_DEVICE(0x055f, 0xc200), .driver_info = MustekGsmart300},
1073 {USB_DEVICE(0x055f, 0xc220), .driver_info = Gsmartmini},
1074 {USB_DEVICE(0x06bd, 0x0404), .driver_info = AgfaCl20},
1075 {USB_DEVICE(0x06be, 0x0800), .driver_info = Optimedia},
1076 {USB_DEVICE(0x084d, 0x0003), .driver_info = DLinkDSC350},
1077 {USB_DEVICE(0x08ca, 0x0103), .driver_info = AiptekPocketDV},
1078 {USB_DEVICE(0x2899, 0x012c), .driver_info = ToptroIndus},
1079 {USB_DEVICE(0x8086, 0x0630), .driver_info = IntelPocketPCCamera},
6a7eba24
JFM
1080 {}
1081};
1082MODULE_DEVICE_TABLE(usb, device_table);
1083
1084/* -- device connect -- */
1085static int sd_probe(struct usb_interface *intf,
1086 const struct usb_device_id *id)
1087{
1088 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1089 THIS_MODULE);
1090}
1091
1092static struct usb_driver sd_driver = {
1093 .name = MODULE_NAME,
1094 .id_table = device_table,
1095 .probe = sd_probe,
1096 .disconnect = gspca_disconnect,
6a709749
JFM
1097#ifdef CONFIG_PM
1098 .suspend = gspca_suspend,
1099 .resume = gspca_resume,
1100#endif
6a7eba24
JFM
1101};
1102
1103/* -- module insert / remove -- */
1104static int __init sd_mod_init(void)
1105{
f69e9529
AK
1106 int ret;
1107 ret = usb_register(&sd_driver);
1108 if (ret < 0)
e6b14849 1109 return ret;
10b0e96e 1110 PDEBUG(D_PROBE, "registered");
6a7eba24
JFM
1111 return 0;
1112}
1113static void __exit sd_mod_exit(void)
1114{
1115 usb_deregister(&sd_driver);
1116 PDEBUG(D_PROBE, "deregistered");
1117}
1118
1119module_init(sd_mod_init);
1120module_exit(sd_mod_exit);
This page took 0.214312 seconds and 5 git commands to generate.