1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22#define MODULE_NAME "mars"
23
24#include "gspca.h"
25#include "jpeg.h"
26
27MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
28MODULE_DESCRIPTION("GSPCA/Mars USB Camera Driver");
29MODULE_LICENSE("GPL");
30
31
32struct sd {
33 struct gspca_dev gspca_dev;
34
35 u8 brightness;
36 u8 colors;
37 u8 gamma;
38 u8 sharpness;
39 u8 quality;
40#define QUALITY_MIN 40
41#define QUALITY_MAX 70
42#define QUALITY_DEF 50
43
44 u8 *jpeg_hdr;
45};
46
47
48static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
49static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
50static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
51static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
52static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val);
53static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val);
54static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
55static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
56
57static struct ctrl sd_ctrls[] = {
58 {
59 {
60 .id = V4L2_CID_BRIGHTNESS,
61 .type = V4L2_CTRL_TYPE_INTEGER,
62 .name = "Brightness",
63 .minimum = 0,
64 .maximum = 30,
65 .step = 1,
66#define BRIGHTNESS_DEF 15
67 .default_value = BRIGHTNESS_DEF,
68 },
69 .set = sd_setbrightness,
70 .get = sd_getbrightness,
71 },
72 {
73 {
74 .id = V4L2_CID_SATURATION,
75 .type = V4L2_CTRL_TYPE_INTEGER,
76 .name = "Color",
77 .minimum = 1,
78 .maximum = 255,
79 .step = 1,
80#define COLOR_DEF 200
81 .default_value = COLOR_DEF,
82 },
83 .set = sd_setcolors,
84 .get = sd_getcolors,
85 },
86 {
87 {
88 .id = V4L2_CID_GAMMA,
89 .type = V4L2_CTRL_TYPE_INTEGER,
90 .name = "Gamma",
91 .minimum = 0,
92 .maximum = 3,
93 .step = 1,
94#define GAMMA_DEF 1
95 .default_value = GAMMA_DEF,
96 },
97 .set = sd_setgamma,
98 .get = sd_getgamma,
99 },
100 {
101 {
102 .id = V4L2_CID_SHARPNESS,
103 .type = V4L2_CTRL_TYPE_INTEGER,
104 .name = "Sharpness",
105 .minimum = 0,
106 .maximum = 2,
107 .step = 1,
108#define SHARPNESS_DEF 1
109 .default_value = SHARPNESS_DEF,
110 },
111 .set = sd_setsharpness,
112 .get = sd_getsharpness,
113 },
114};
115
116static 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 = 2},
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 = 1},
127};
128
129static const __u8 mi_data[0x20] = {
130
131 0x48, 0x22, 0x01, 0x47, 0x10, 0x00, 0x00, 0x00,
132
133 0x00, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01,
134
135 0x30, 0x00, 0x04, 0x00, 0x06, 0x01, 0xe2, 0x02,
136
137 0x82, 0x00, 0x20, 0x17, 0x80, 0x08, 0x0c, 0x00
138};
139
140
141static int reg_w(struct gspca_dev *gspca_dev,
142 int len)
143{
144 int alen, ret;
145
146 ret = usb_bulk_msg(gspca_dev->dev,
147 usb_sndbulkpipe(gspca_dev->dev, 4),
148 gspca_dev->usb_buf,
149 len,
150 &alen,
151 500);
152 if (ret < 0)
153 PDEBUG(D_ERR, "reg write [%02x] error %d",
154 gspca_dev->usb_buf[0], ret);
155 return ret;
156}
157
158static void mi_w(struct gspca_dev *gspca_dev,
159 u8 addr,
160 u8 value)
161{
162 gspca_dev->usb_buf[0] = 0x1f;
163 gspca_dev->usb_buf[1] = 0;
164 gspca_dev->usb_buf[2] = addr;
165 gspca_dev->usb_buf[3] = value;
166
167 reg_w(gspca_dev, 4);
168}
169
170
171static int sd_config(struct gspca_dev *gspca_dev,
172 const struct usb_device_id *id)
173{
174 struct sd *sd = (struct sd *) gspca_dev;
175 struct cam *cam;
176
177 cam = &gspca_dev->cam;
178 cam->cam_mode = vga_mode;
179 cam->nmodes = ARRAY_SIZE(vga_mode);
180 sd->brightness = BRIGHTNESS_DEF;
181 sd->colors = COLOR_DEF;
182 sd->gamma = GAMMA_DEF;
183 sd->sharpness = SHARPNESS_DEF;
184 sd->quality = QUALITY_DEF;
185 gspca_dev->nbalt = 9;
186 return 0;
187}
188
189
190static int sd_init(struct gspca_dev *gspca_dev)
191{
192 return 0;
193}
194
195static int sd_start(struct gspca_dev *gspca_dev)
196{
197 struct sd *sd = (struct sd *) gspca_dev;
198 int err_code;
199 u8 *data;
200 int i;
201
202
203 sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
204 if (!sd->jpeg_hdr)
205 return -ENOMEM;
206 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
207 0x21);
208 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
209
210 data = gspca_dev->usb_buf;
211
212 data[0] = 0x01;
213 data[1] = 0x01;
214 err_code = reg_w(gspca_dev, 2);
215 if (err_code < 0)
216 return err_code;
217
218
219
220
221 data[0] = 0x00;
222 data[1] = 0x0c | 0x01;
223 data[2] = 0x01;
224 data[3] = gspca_dev->width / 8;
225 data[4] = gspca_dev->height / 8;
226 data[5] = 0x30;
227
228 data[6] = 0x02;
229 data[7] = sd->gamma * 0x40;
230 data[8] = 0x01;
231
232
233
234 data[9] = 0x52;
235
236 data[10] = 0x18;
237
238 err_code = reg_w(gspca_dev, 11);
239 if (err_code < 0)
240 return err_code;
241
242 data[0] = 0x23;
243 data[1] = 0x09;
244
245 err_code = reg_w(gspca_dev, 2);
246 if (err_code < 0)
247 return err_code;
248
249 data[0] = 0x3c;
250
251
252
253
254 data[1] = 50;
255
256 err_code = reg_w(gspca_dev, 2);
257 if (err_code < 0)
258 return err_code;
259
260
261 data[0] = 0x5e;
262 data[1] = 0;
263
264
265
266
267 data[2] = sd->colors << 3;
268 data[3] = ((sd->colors >> 2) & 0xf8) | 0x04;
269 data[4] = sd->brightness;
270 data[5] = 0x00;
271
272 err_code = reg_w(gspca_dev, 6);
273 if (err_code < 0)
274 return err_code;
275
276 data[0] = 0x67;
277
278 data[1] = sd->sharpness * 4 + 3;
279 data[2] = 0x14;
280 err_code = reg_w(gspca_dev, 3);
281 if (err_code < 0)
282 return err_code;
283
284 data[0] = 0x69;
285 data[1] = 0x2f;
286 data[2] = 0x28;
287 data[3] = 0x42;
288 err_code = reg_w(gspca_dev, 4);
289 if (err_code < 0)
290 return err_code;
291
292 data[0] = 0x63;
293 data[1] = 0x07;
294 err_code = reg_w(gspca_dev, 2);
295
296 if (err_code < 0)
297 return err_code;
298
299
300 for (i = 0; i < sizeof mi_data; i++)
301 mi_w(gspca_dev, i + 1, mi_data[i]);
302
303 data[0] = 0x00;
304 data[1] = 0x4d;
305 reg_w(gspca_dev, 2);
306 return 0;
307}
308
309static void sd_stopN(struct gspca_dev *gspca_dev)
310{
311 int result;
312
313 gspca_dev->usb_buf[0] = 1;
314 gspca_dev->usb_buf[1] = 0;
315 result = reg_w(gspca_dev, 2);
316 if (result < 0)
317 PDEBUG(D_ERR, "Camera Stop failed");
318}
319
320static void sd_stop0(struct gspca_dev *gspca_dev)
321{
322 struct sd *sd = (struct sd *) gspca_dev;
323
324 kfree(sd->jpeg_hdr);
325}
326
327static void sd_pkt_scan(struct gspca_dev *gspca_dev,
328 struct gspca_frame *frame,
329 __u8 *data,
330 int len)
331{
332 struct sd *sd = (struct sd *) gspca_dev;
333 int p;
334
335 if (len < 6) {
336
337 return;
338 }
339 for (p = 0; p < len - 6; p++) {
340 if (data[0 + p] == 0xff
341 && data[1 + p] == 0xff
342 && data[2 + p] == 0x00
343 && data[3 + p] == 0xff
344 && data[4 + p] == 0x96) {
345 if (data[5 + p] == 0x64
346 || data[5 + p] == 0x65
347 || data[5 + p] == 0x66
348 || data[5 + p] == 0x67) {
349 PDEBUG(D_PACK, "sof offset: %d len: %d",
350 p, len);
351 frame = gspca_frame_add(gspca_dev, LAST_PACKET,
352 frame, data, p);
353
354
355 gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
356 sd->jpeg_hdr, JPEG_HDR_SZ);
357 data += p + 16;
358 len -= p + 16;
359 break;
360 }
361 }
362 }
363 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
364}
365
366static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
367{
368 struct sd *sd = (struct sd *) gspca_dev;
369
370 sd->brightness = val;
371 if (gspca_dev->streaming) {
372 gspca_dev->usb_buf[0] = 0x61;
373 gspca_dev->usb_buf[1] = val;
374 reg_w(gspca_dev, 2);
375 }
376 return 0;
377}
378
379static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
380{
381 struct sd *sd = (struct sd *) gspca_dev;
382
383 *val = sd->brightness;
384 return 0;
385}
386
387static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
388{
389 struct sd *sd = (struct sd *) gspca_dev;
390
391 sd->colors = val;
392 if (gspca_dev->streaming) {
393
394
395 gspca_dev->usb_buf[0] = 0x5f;
396 gspca_dev->usb_buf[1] = sd->colors << 3;
397 gspca_dev->usb_buf[2] = ((sd->colors >> 2) & 0xf8) | 0x04;
398 reg_w(gspca_dev, 3);
399 }
400 return 0;
401}
402
403static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
404{
405 struct sd *sd = (struct sd *) gspca_dev;
406
407 *val = sd->colors;
408 return 0;
409}
410
411static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
412{
413 struct sd *sd = (struct sd *) gspca_dev;
414
415 sd->gamma = val;
416 if (gspca_dev->streaming) {
417 gspca_dev->usb_buf[0] = 0x06;
418 gspca_dev->usb_buf[1] = val * 0x40;
419 reg_w(gspca_dev, 2);
420 }
421 return 0;
422}
423
424static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
425{
426 struct sd *sd = (struct sd *) gspca_dev;
427
428 *val = sd->gamma;
429 return 0;
430}
431
432static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
433{
434 struct sd *sd = (struct sd *) gspca_dev;
435
436 sd->sharpness = val;
437 if (gspca_dev->streaming) {
438 gspca_dev->usb_buf[0] = 0x67;
439 gspca_dev->usb_buf[1] = val * 4 + 3;
440 reg_w(gspca_dev, 2);
441 }
442 return 0;
443}
444
445static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
446{
447 struct sd *sd = (struct sd *) gspca_dev;
448
449 *val = sd->sharpness;
450 return 0;
451}
452
453static int sd_set_jcomp(struct gspca_dev *gspca_dev,
454 struct v4l2_jpegcompression *jcomp)
455{
456 struct sd *sd = (struct sd *) gspca_dev;
457
458 if (jcomp->quality < QUALITY_MIN)
459 sd->quality = QUALITY_MIN;
460 else if (jcomp->quality > QUALITY_MAX)
461 sd->quality = QUALITY_MAX;
462 else
463 sd->quality = jcomp->quality;
464 if (gspca_dev->streaming)
465 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
466 return 0;
467}
468
469static int sd_get_jcomp(struct gspca_dev *gspca_dev,
470 struct v4l2_jpegcompression *jcomp)
471{
472 struct sd *sd = (struct sd *) gspca_dev;
473
474 memset(jcomp, 0, sizeof *jcomp);
475 jcomp->quality = sd->quality;
476 jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
477 | V4L2_JPEG_MARKER_DQT;
478 return 0;
479}
480
481
482static const struct sd_desc sd_desc = {
483 .name = MODULE_NAME,
484 .ctrls = sd_ctrls,
485 .nctrls = ARRAY_SIZE(sd_ctrls),
486 .config = sd_config,
487 .init = sd_init,
488 .start = sd_start,
489 .stopN = sd_stopN,
490 .stop0 = sd_stop0,
491 .pkt_scan = sd_pkt_scan,
492 .get_jcomp = sd_get_jcomp,
493 .set_jcomp = sd_set_jcomp,
494};
495
496
497static const __devinitdata struct usb_device_id device_table[] = {
498 {USB_DEVICE(0x093a, 0x050f)},
499 {}
500};
501MODULE_DEVICE_TABLE(usb, device_table);
502
503
504static int sd_probe(struct usb_interface *intf,
505 const struct usb_device_id *id)
506{
507 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
508 THIS_MODULE);
509}
510
511static struct usb_driver sd_driver = {
512 .name = MODULE_NAME,
513 .id_table = device_table,
514 .probe = sd_probe,
515 .disconnect = gspca_disconnect,
516#ifdef CONFIG_PM
517 .suspend = gspca_suspend,
518 .resume = gspca_resume,
519#endif
520};
521
522
523static int __init sd_mod_init(void)
524{
525 int ret;
526
527 ret = usb_register(&sd_driver);
528 if (ret < 0)
529 return ret;
530 PDEBUG(D_PROBE, "registered");
531 return 0;
532}
533static void __exit sd_mod_exit(void)
534{
535 usb_deregister(&sd_driver);
536 PDEBUG(D_PROBE, "deregistered");
537}
538
539module_init(sd_mod_init);
540module_exit(sd_mod_exit);
541