Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/media/video/gspca/spca500.c
17602 views
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
27
MODULE_AUTHOR("Michel Xhaard <[email protected]>");
28
MODULE_DESCRIPTION("GSPCA/SPCA500 USB Camera Driver");
29
MODULE_LICENSE("GPL");
30
31
/* specific webcam descriptor */
32
struct sd {
33
struct gspca_dev gspca_dev; /* !! must be the first item */
34
35
unsigned char brightness;
36
unsigned char contrast;
37
unsigned char colors;
38
u8 quality;
39
#define QUALITY_MIN 70
40
#define QUALITY_MAX 95
41
#define QUALITY_DEF 85
42
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
59
60
u8 jpeg_hdr[JPEG_HDR_SZ];
61
};
62
63
/* V4L2 controls supported by the driver */
64
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
65
static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
66
static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
67
static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
68
static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
69
static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
70
71
static const struct ctrl sd_ctrls[] = {
72
{
73
{
74
.id = V4L2_CID_BRIGHTNESS,
75
.type = V4L2_CTRL_TYPE_INTEGER,
76
.name = "Brightness",
77
.minimum = 0,
78
.maximum = 255,
79
.step = 1,
80
#define BRIGHTNESS_DEF 127
81
.default_value = BRIGHTNESS_DEF,
82
},
83
.set = sd_setbrightness,
84
.get = sd_getbrightness,
85
},
86
{
87
{
88
.id = V4L2_CID_CONTRAST,
89
.type = V4L2_CTRL_TYPE_INTEGER,
90
.name = "Contrast",
91
.minimum = 0,
92
.maximum = 63,
93
.step = 1,
94
#define CONTRAST_DEF 31
95
.default_value = CONTRAST_DEF,
96
},
97
.set = sd_setcontrast,
98
.get = sd_getcontrast,
99
},
100
{
101
{
102
.id = V4L2_CID_SATURATION,
103
.type = V4L2_CTRL_TYPE_INTEGER,
104
.name = "Color",
105
.minimum = 0,
106
.maximum = 63,
107
.step = 1,
108
#define COLOR_DEF 31
109
.default_value = COLOR_DEF,
110
},
111
.set = sd_setcolors,
112
.get = sd_getcolors,
113
},
114
};
115
116
static const struct v4l2_pix_format vga_mode[] = {
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},
127
};
128
129
static const struct v4l2_pix_format sif_mode[] = {
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},
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
157
static const __u16 spca500_visual_defaults[][3] = {
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 */
179
{}
180
};
181
static const __u16 Clicksmart510_defaults[][3] = {
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
310
static const __u8 qtable_creative_pccam[2][64] = {
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
331
static const __u8 qtable_kodak_ez200[2][64] = {
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
352
static const __u8 qtable_pocketdv[2][64] = {
353
{ /* Q-table Y-components start registers 0x8800 */
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
},
363
{ /* Q-table C-components start registers 0x8840 */
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
374
/* read 'len' bytes to gspca_dev->usb_buf */
375
static void reg_r(struct gspca_dev *gspca_dev,
376
__u16 index,
377
__u16 length)
378
{
379
usb_control_msg(gspca_dev->dev,
380
usb_rcvctrlpipe(gspca_dev->dev, 0),
381
0,
382
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
383
0, /* value */
384
index, gspca_dev->usb_buf, length, 500);
385
}
386
387
static int reg_w(struct gspca_dev *gspca_dev,
388
__u16 req, __u16 index, __u16 value)
389
{
390
int ret;
391
392
PDEBUG(D_USBO, "reg write: [0x%02x] = 0x%02x", index, value);
393
ret = usb_control_msg(gspca_dev->dev,
394
usb_sndctrlpipe(gspca_dev->dev, 0),
395
req,
396
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
397
value, index, NULL, 0, 500);
398
if (ret < 0)
399
err("reg write: error %d", ret);
400
return ret;
401
}
402
403
/* returns: negative is error, pos or zero is data */
404
static int reg_r_12(struct gspca_dev *gspca_dev,
405
__u16 req, /* bRequest */
406
__u16 index, /* wIndex */
407
__u16 length) /* wLength (1 or 2 only) */
408
{
409
int ret;
410
411
gspca_dev->usb_buf[1] = 0;
412
ret = usb_control_msg(gspca_dev->dev,
413
usb_rcvctrlpipe(gspca_dev->dev, 0),
414
req,
415
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
416
0, /* value */
417
index,
418
gspca_dev->usb_buf, length,
419
500); /* timeout */
420
if (ret < 0) {
421
err("reg_r_12 err %d", ret);
422
return ret;
423
}
424
return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0];
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
*/
432
static int reg_r_wait(struct gspca_dev *gspca_dev,
433
__u16 reg, __u16 index, __u16 value)
434
{
435
int ret, cnt = 20;
436
437
while (--cnt > 0) {
438
ret = reg_r_12(gspca_dev, reg, index, 1);
439
if (ret == value)
440
return 0;
441
msleep(50);
442
}
443
return -EIO;
444
}
445
446
static int write_vector(struct gspca_dev *gspca_dev,
447
const __u16 data[][3])
448
{
449
int ret, i = 0;
450
451
while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) {
452
ret = reg_w(gspca_dev, data[i][0], data[i][2], data[i][1]);
453
if (ret < 0)
454
return ret;
455
i++;
456
}
457
return 0;
458
}
459
460
static int spca50x_setup_qtable(struct gspca_dev *gspca_dev,
461
unsigned int request,
462
unsigned int ybase,
463
unsigned int cbase,
464
const __u8 qtable[2][64])
465
{
466
int i, err;
467
468
/* loop over y components */
469
for (i = 0; i < 64; i++) {
470
err = reg_w(gspca_dev, request, ybase + i, qtable[0][i]);
471
if (err < 0)
472
return err;
473
}
474
475
/* loop over c components */
476
for (i = 0; i < 64; i++) {
477
err = reg_w(gspca_dev, request, cbase + i, qtable[1][i]);
478
if (err < 0)
479
return err;
480
}
481
return 0;
482
}
483
484
static void spca500_ping310(struct gspca_dev *gspca_dev)
485
{
486
reg_r(gspca_dev, 0x0d04, 2);
487
PDEBUG(D_STREAM, "ClickSmart310 ping 0x0d04 0x%02x 0x%02x",
488
gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
489
}
490
491
static void spca500_clksmart310_init(struct gspca_dev *gspca_dev)
492
{
493
reg_r(gspca_dev, 0x0d05, 2);
494
PDEBUG(D_STREAM, "ClickSmart310 init 0x0d05 0x%02x 0x%02x",
495
gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
496
reg_w(gspca_dev, 0x00, 0x8167, 0x5a);
497
spca500_ping310(gspca_dev);
498
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);
509
/* 00 for adjust shutter */
510
reg_w(gspca_dev, 0x00, 0x0d02, 0x01);
511
reg_w(gspca_dev, 0x00, 0x8169, 0x25);
512
reg_w(gspca_dev, 0x00, 0x0d01, 0x02);
513
}
514
515
static void spca500_setmode(struct gspca_dev *gspca_dev,
516
__u8 xmult, __u8 ymult)
517
{
518
int mode;
519
520
/* set x multiplier */
521
reg_w(gspca_dev, 0, 0x8001, xmult);
522
523
/* set y multiplier */
524
reg_w(gspca_dev, 0, 0x8002, ymult);
525
526
/* use compressed mode, VGA, with mode specific subsample */
527
mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
528
reg_w(gspca_dev, 0, 0x8003, mode << 4);
529
}
530
531
static int spca500_full_reset(struct gspca_dev *gspca_dev)
532
{
533
int err;
534
535
/* send the reset command */
536
err = reg_w(gspca_dev, 0xe0, 0x0001, 0x0000);
537
if (err < 0)
538
return err;
539
540
/* wait for the reset to complete */
541
err = reg_r_wait(gspca_dev, 0x06, 0x0000, 0x0000);
542
if (err < 0)
543
return err;
544
err = reg_w(gspca_dev, 0xe0, 0x0000, 0x0000);
545
if (err < 0)
546
return err;
547
err = reg_r_wait(gspca_dev, 0x06, 0, 0);
548
if (err < 0) {
549
PDEBUG(D_ERR, "reg_r_wait() failed");
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 */
562
static int spca500_synch310(struct gspca_dev *gspca_dev)
563
{
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
570
reg_r(gspca_dev, 0x0d00, 1);
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;
583
error:
584
return -EBUSY;
585
}
586
587
static void spca500_reinit(struct gspca_dev *gspca_dev)
588
{
589
int err;
590
__u8 Data;
591
592
/* some unknown command from Aiptek pocket dv and family300 */
593
594
reg_w(gspca_dev, 0x00, 0x0d01, 0x01);
595
reg_w(gspca_dev, 0x00, 0x0d03, 0x00);
596
reg_w(gspca_dev, 0x00, 0x0d02, 0x01);
597
598
/* enable drop packet */
599
reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
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 */
607
reg_w(gspca_dev, 0x00, 0x8880, 2);
608
/* family cam Quicksmart stuff */
609
reg_w(gspca_dev, 0x00, 0x800a, 0x00);
610
/* Set agc transfer: synced between frames */
611
reg_w(gspca_dev, 0x00, 0x820f, 0x01);
612
/* Init SDRAM - needed for SDRAM access */
613
reg_w(gspca_dev, 0x00, 0x870a, 0x04);
614
/*Start init sequence or stream */
615
reg_w(gspca_dev, 0, 0x8003, 0x00);
616
/* switch to video camera mode */
617
reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
618
msleep(2000);
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
}
624
}
625
626
/* this function is called at probe time */
627
static 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;
632
633
cam = &gspca_dev->cam;
634
sd->subtype = id->driver_info;
635
if (sd->subtype != LogitechClickSmart310) {
636
cam->cam_mode = vga_mode;
637
cam->nmodes = ARRAY_SIZE(vga_mode);
638
} else {
639
cam->cam_mode = sif_mode;
640
cam->nmodes = ARRAY_SIZE(sif_mode);
641
}
642
sd->brightness = BRIGHTNESS_DEF;
643
sd->contrast = CONTRAST_DEF;
644
sd->colors = COLOR_DEF;
645
sd->quality = QUALITY_DEF;
646
return 0;
647
}
648
649
/* this function is called at probe and resume time */
650
static int sd_init(struct gspca_dev *gspca_dev)
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
664
static int sd_start(struct gspca_dev *gspca_dev)
665
{
666
struct sd *sd = (struct sd *) gspca_dev;
667
int err;
668
__u8 Data;
669
__u8 xmult, ymult;
670
671
/* create the JPEG header */
672
jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
673
0x22); /* JPEG 411 */
674
jpeg_set_qual(sd->jpeg_hdr, sd->quality);
675
676
if (sd->subtype == LogitechClickSmart310) {
677
xmult = 0x16;
678
ymult = 0x12;
679
} else {
680
xmult = 0x28;
681
ymult = 0x1e;
682
}
683
684
/* is there a sensor here ? */
685
reg_r(gspca_dev, 0x8a04, 1);
686
PDEBUG(D_STREAM, "Spca500 Sensor Address 0x%02x",
687
gspca_dev->usb_buf[0]);
688
PDEBUG(D_STREAM, "Spca500 curr_mode: %d Xmult: 0x%02x, Ymult: 0x%02x",
689
gspca_dev->curr_mode, xmult, ymult);
690
691
/* setup qtable */
692
switch (sd->subtype) {
693
case LogitechClickSmart310:
694
spca500_setmode(gspca_dev, xmult, ymult);
695
696
/* enable drop packet */
697
reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
698
reg_w(gspca_dev, 0x00, 0x8880, 3);
699
err = spca50x_setup_qtable(gspca_dev,
700
0x00, 0x8800, 0x8840,
701
qtable_creative_pccam);
702
if (err < 0)
703
PDEBUG(D_ERR, "spca50x_setup_qtable failed");
704
/* Init SDRAM - needed for SDRAM access */
705
reg_w(gspca_dev, 0x00, 0x870a, 0x04);
706
707
/* switch to video camera mode */
708
reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
709
msleep(500);
710
if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
711
PDEBUG(D_ERR, "reg_r_wait() failed");
712
713
reg_r(gspca_dev, 0x816b, 1);
714
Data = gspca_dev->usb_buf[0];
715
reg_w(gspca_dev, 0x00, 0x816b, Data);
716
717
spca500_synch310(gspca_dev);
718
719
write_vector(gspca_dev, spca500_visual_defaults);
720
spca500_setmode(gspca_dev, xmult, ymult);
721
/* enable drop packet */
722
err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
723
if (err < 0)
724
PDEBUG(D_ERR, "failed to enable drop packet");
725
reg_w(gspca_dev, 0x00, 0x8880, 3);
726
err = spca50x_setup_qtable(gspca_dev,
727
0x00, 0x8800, 0x8840,
728
qtable_creative_pccam);
729
if (err < 0)
730
PDEBUG(D_ERR, "spca50x_setup_qtable failed");
731
732
/* Init SDRAM - needed for SDRAM access */
733
reg_w(gspca_dev, 0x00, 0x870a, 0x04);
734
735
/* switch to video camera mode */
736
reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
737
738
if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
739
PDEBUG(D_ERR, "reg_r_wait() failed");
740
741
reg_r(gspca_dev, 0x816b, 1);
742
Data = gspca_dev->usb_buf[0];
743
reg_w(gspca_dev, 0x00, 0x816b, Data);
744
break;
745
case CreativePCCam300: /* Creative PC-CAM 300 640x480 CCD */
746
case IntelPocketPCCamera: /* FIXME: Temporary fix for
747
* Intel Pocket PC Camera
748
* - NWG (Sat 29th March 2003) */
749
750
/* do a full reset */
751
err = spca500_full_reset(gspca_dev);
752
if (err < 0)
753
PDEBUG(D_ERR, "spca500_full_reset failed");
754
755
/* enable drop packet */
756
err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
757
if (err < 0)
758
PDEBUG(D_ERR, "failed to enable drop packet");
759
reg_w(gspca_dev, 0x00, 0x8880, 3);
760
err = spca50x_setup_qtable(gspca_dev,
761
0x00, 0x8800, 0x8840,
762
qtable_creative_pccam);
763
if (err < 0)
764
PDEBUG(D_ERR, "spca50x_setup_qtable failed");
765
766
spca500_setmode(gspca_dev, xmult, ymult);
767
reg_w(gspca_dev, 0x20, 0x0001, 0x0004);
768
769
/* switch to video camera mode */
770
reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
771
772
if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
773
PDEBUG(D_ERR, "reg_r_wait() failed");
774
775
reg_r(gspca_dev, 0x816b, 1);
776
Data = gspca_dev->usb_buf[0];
777
reg_w(gspca_dev, 0x00, 0x816b, Data);
778
779
/* write_vector(gspca_dev, spca500_visual_defaults); */
780
break;
781
case KodakEZ200: /* Kodak EZ200 */
782
783
/* do a full reset */
784
err = spca500_full_reset(gspca_dev);
785
if (err < 0)
786
PDEBUG(D_ERR, "spca500_full_reset failed");
787
/* enable drop packet */
788
reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
789
reg_w(gspca_dev, 0x00, 0x8880, 0);
790
err = spca50x_setup_qtable(gspca_dev,
791
0x00, 0x8800, 0x8840,
792
qtable_kodak_ez200);
793
if (err < 0)
794
PDEBUG(D_ERR, "spca50x_setup_qtable failed");
795
spca500_setmode(gspca_dev, xmult, ymult);
796
797
reg_w(gspca_dev, 0x20, 0x0001, 0x0004);
798
799
/* switch to video camera mode */
800
reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
801
802
if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
803
PDEBUG(D_ERR, "reg_r_wait() failed");
804
805
reg_r(gspca_dev, 0x816b, 1);
806
Data = gspca_dev->usb_buf[0];
807
reg_w(gspca_dev, 0x00, 0x816b, Data);
808
809
/* write_vector(gspca_dev, spca500_visual_defaults); */
810
break;
811
812
case BenqDC1016:
813
case DLinkDSC350: /* FamilyCam 300 */
814
case AiptekPocketDV: /* Aiptek PocketDV */
815
case Gsmartmini: /*Mustek Gsmart Mini */
816
case MustekGsmart300: /* Mustek Gsmart 300 */
817
case PalmPixDC85:
818
case Optimedia:
819
case ToptroIndus:
820
case AgfaCl20:
821
spca500_reinit(gspca_dev);
822
reg_w(gspca_dev, 0x00, 0x0d01, 0x01);
823
/* enable drop packet */
824
reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
825
826
err = spca50x_setup_qtable(gspca_dev,
827
0x00, 0x8800, 0x8840, qtable_pocketdv);
828
if (err < 0)
829
PDEBUG(D_ERR, "spca50x_setup_qtable failed");
830
reg_w(gspca_dev, 0x00, 0x8880, 2);
831
832
/* familycam Quicksmart pocketDV stuff */
833
reg_w(gspca_dev, 0x00, 0x800a, 0x00);
834
/* Set agc transfer: synced between frames */
835
reg_w(gspca_dev, 0x00, 0x820f, 0x01);
836
/* Init SDRAM - needed for SDRAM access */
837
reg_w(gspca_dev, 0x00, 0x870a, 0x04);
838
839
spca500_setmode(gspca_dev, xmult, ymult);
840
/* switch to video camera mode */
841
reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
842
843
reg_r_wait(gspca_dev, 0, 0x8000, 0x44);
844
845
reg_r(gspca_dev, 0x816b, 1);
846
Data = gspca_dev->usb_buf[0];
847
reg_w(gspca_dev, 0x00, 0x816b, Data);
848
break;
849
case LogitechTraveler:
850
case LogitechClickSmart510:
851
reg_w(gspca_dev, 0x02, 0x00, 0x00);
852
/* enable drop packet */
853
reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
854
855
err = spca50x_setup_qtable(gspca_dev,
856
0x00, 0x8800,
857
0x8840, qtable_creative_pccam);
858
if (err < 0)
859
PDEBUG(D_ERR, "spca50x_setup_qtable failed");
860
reg_w(gspca_dev, 0x00, 0x8880, 3);
861
reg_w(gspca_dev, 0x00, 0x800a, 0x00);
862
/* Init SDRAM - needed for SDRAM access */
863
reg_w(gspca_dev, 0x00, 0x870a, 0x04);
864
865
spca500_setmode(gspca_dev, xmult, ymult);
866
867
/* switch to video camera mode */
868
reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
869
reg_r_wait(gspca_dev, 0, 0x8000, 0x44);
870
871
reg_r(gspca_dev, 0x816b, 1);
872
Data = gspca_dev->usb_buf[0];
873
reg_w(gspca_dev, 0x00, 0x816b, Data);
874
write_vector(gspca_dev, Clicksmart510_defaults);
875
break;
876
}
877
return 0;
878
}
879
880
static void sd_stopN(struct gspca_dev *gspca_dev)
881
{
882
reg_w(gspca_dev, 0, 0x8003, 0x00);
883
884
/* switch to video camera mode */
885
reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
886
reg_r(gspca_dev, 0x8000, 1);
887
PDEBUG(D_STREAM, "stop SPCA500 done reg8000: 0x%2x",
888
gspca_dev->usb_buf[0]);
889
}
890
891
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
892
u8 *data, /* isoc packet */
893
int len) /* iso packet length */
894
{
895
struct sd *sd = (struct sd *) gspca_dev;
896
int i;
897
static __u8 ffd9[] = {0xff, 0xd9};
898
899
/* frames are jpeg 4.1.1 without 0xff escape */
900
if (data[0] == 0xff) {
901
if (data[1] != 0x01) { /* drop packet */
902
/* gspca_dev->last_packet_type = DISCARD_PACKET; */
903
return;
904
}
905
gspca_frame_add(gspca_dev, LAST_PACKET,
906
ffd9, 2);
907
908
/* put the JPEG header in the new frame */
909
gspca_frame_add(gspca_dev, FIRST_PACKET,
910
sd->jpeg_hdr, JPEG_HDR_SZ);
911
912
data += SPCA500_OFFSET_DATA;
913
len -= SPCA500_OFFSET_DATA;
914
} else {
915
data += 1;
916
len -= 1;
917
}
918
919
/* add 0x00 after 0xff */
920
i = 0;
921
do {
922
if (data[i] == 0xff) {
923
gspca_frame_add(gspca_dev, INTER_PACKET,
924
data, i + 1);
925
len -= i;
926
data += i;
927
*data = 0x00;
928
i = 0;
929
}
930
i++;
931
} while (i < len);
932
gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
933
}
934
935
static void setbrightness(struct gspca_dev *gspca_dev)
936
{
937
struct sd *sd = (struct sd *) gspca_dev;
938
939
reg_w(gspca_dev, 0x00, 0x8167,
940
(__u8) (sd->brightness - 128));
941
}
942
943
static void setcontrast(struct gspca_dev *gspca_dev)
944
{
945
struct sd *sd = (struct sd *) gspca_dev;
946
947
reg_w(gspca_dev, 0x00, 0x8168, sd->contrast);
948
}
949
950
static void setcolors(struct gspca_dev *gspca_dev)
951
{
952
struct sd *sd = (struct sd *) gspca_dev;
953
954
reg_w(gspca_dev, 0x00, 0x8169, sd->colors);
955
}
956
957
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
958
{
959
struct sd *sd = (struct sd *) gspca_dev;
960
961
sd->brightness = val;
962
if (gspca_dev->streaming)
963
setbrightness(gspca_dev);
964
return 0;
965
}
966
967
static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
968
{
969
struct sd *sd = (struct sd *) gspca_dev;
970
971
*val = sd->brightness;
972
return 0;
973
}
974
975
static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
976
{
977
struct sd *sd = (struct sd *) gspca_dev;
978
979
sd->contrast = val;
980
if (gspca_dev->streaming)
981
setcontrast(gspca_dev);
982
return 0;
983
}
984
985
static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
986
{
987
struct sd *sd = (struct sd *) gspca_dev;
988
989
*val = sd->contrast;
990
return 0;
991
}
992
993
static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
994
{
995
struct sd *sd = (struct sd *) gspca_dev;
996
997
sd->colors = val;
998
if (gspca_dev->streaming)
999
setcolors(gspca_dev);
1000
return 0;
1001
}
1002
1003
static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1004
{
1005
struct sd *sd = (struct sd *) gspca_dev;
1006
1007
*val = sd->colors;
1008
return 0;
1009
}
1010
1011
static int sd_set_jcomp(struct gspca_dev *gspca_dev,
1012
struct v4l2_jpegcompression *jcomp)
1013
{
1014
struct sd *sd = (struct sd *) gspca_dev;
1015
1016
if (jcomp->quality < QUALITY_MIN)
1017
sd->quality = QUALITY_MIN;
1018
else if (jcomp->quality > QUALITY_MAX)
1019
sd->quality = QUALITY_MAX;
1020
else
1021
sd->quality = jcomp->quality;
1022
if (gspca_dev->streaming)
1023
jpeg_set_qual(sd->jpeg_hdr, sd->quality);
1024
return 0;
1025
}
1026
1027
static int sd_get_jcomp(struct gspca_dev *gspca_dev,
1028
struct v4l2_jpegcompression *jcomp)
1029
{
1030
struct sd *sd = (struct sd *) gspca_dev;
1031
1032
memset(jcomp, 0, sizeof *jcomp);
1033
jcomp->quality = sd->quality;
1034
jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
1035
| V4L2_JPEG_MARKER_DQT;
1036
return 0;
1037
}
1038
1039
/* sub-driver description */
1040
static const struct sd_desc sd_desc = {
1041
.name = MODULE_NAME,
1042
.ctrls = sd_ctrls,
1043
.nctrls = ARRAY_SIZE(sd_ctrls),
1044
.config = sd_config,
1045
.init = sd_init,
1046
.start = sd_start,
1047
.stopN = sd_stopN,
1048
.pkt_scan = sd_pkt_scan,
1049
.get_jcomp = sd_get_jcomp,
1050
.set_jcomp = sd_set_jcomp,
1051
};
1052
1053
/* -- module initialisation -- */
1054
static const struct usb_device_id device_table[] = {
1055
{USB_DEVICE(0x040a, 0x0300), .driver_info = KodakEZ200},
1056
{USB_DEVICE(0x041e, 0x400a), .driver_info = CreativePCCam300},
1057
{USB_DEVICE(0x046d, 0x0890), .driver_info = LogitechTraveler},
1058
{USB_DEVICE(0x046d, 0x0900), .driver_info = LogitechClickSmart310},
1059
{USB_DEVICE(0x046d, 0x0901), .driver_info = LogitechClickSmart510},
1060
{USB_DEVICE(0x04a5, 0x300c), .driver_info = BenqDC1016},
1061
{USB_DEVICE(0x04fc, 0x7333), .driver_info = PalmPixDC85},
1062
{USB_DEVICE(0x055f, 0xc200), .driver_info = MustekGsmart300},
1063
{USB_DEVICE(0x055f, 0xc220), .driver_info = Gsmartmini},
1064
{USB_DEVICE(0x06bd, 0x0404), .driver_info = AgfaCl20},
1065
{USB_DEVICE(0x06be, 0x0800), .driver_info = Optimedia},
1066
{USB_DEVICE(0x084d, 0x0003), .driver_info = DLinkDSC350},
1067
{USB_DEVICE(0x08ca, 0x0103), .driver_info = AiptekPocketDV},
1068
{USB_DEVICE(0x2899, 0x012c), .driver_info = ToptroIndus},
1069
{USB_DEVICE(0x8086, 0x0630), .driver_info = IntelPocketPCCamera},
1070
{}
1071
};
1072
MODULE_DEVICE_TABLE(usb, device_table);
1073
1074
/* -- device connect -- */
1075
static int sd_probe(struct usb_interface *intf,
1076
const struct usb_device_id *id)
1077
{
1078
return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1079
THIS_MODULE);
1080
}
1081
1082
static struct usb_driver sd_driver = {
1083
.name = MODULE_NAME,
1084
.id_table = device_table,
1085
.probe = sd_probe,
1086
.disconnect = gspca_disconnect,
1087
#ifdef CONFIG_PM
1088
.suspend = gspca_suspend,
1089
.resume = gspca_resume,
1090
#endif
1091
};
1092
1093
/* -- module insert / remove -- */
1094
static int __init sd_mod_init(void)
1095
{
1096
return usb_register(&sd_driver);
1097
}
1098
static void __exit sd_mod_exit(void)
1099
{
1100
usb_deregister(&sd_driver);
1101
}
1102
1103
module_init(sd_mod_init);
1104
module_exit(sd_mod_exit);
1105
1106