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