1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43#define MODULE_NAME "mr97310a"
44
45#include "gspca.h"
46
47#define CAM_TYPE_CIF 0
48#define CAM_TYPE_VGA 1
49
50#define MR97310A_BRIGHTNESS_DEFAULT 0
51
52#define MR97310A_EXPOSURE_MIN 0
53#define MR97310A_EXPOSURE_MAX 4095
54#define MR97310A_EXPOSURE_DEFAULT 1000
55
56#define MR97310A_GAIN_MIN 0
57#define MR97310A_GAIN_MAX 31
58#define MR97310A_GAIN_DEFAULT 25
59
60#define MR97310A_CONTRAST_MIN 0
61#define MR97310A_CONTRAST_MAX 31
62#define MR97310A_CONTRAST_DEFAULT 23
63
64#define MR97310A_CS_GAIN_MIN 0
65#define MR97310A_CS_GAIN_MAX 0x7ff
66#define MR97310A_CS_GAIN_DEFAULT 0x110
67
68#define MR97310A_MIN_CLOCKDIV_MIN 3
69#define MR97310A_MIN_CLOCKDIV_MAX 8
70#define MR97310A_MIN_CLOCKDIV_DEFAULT 3
71
72MODULE_AUTHOR("Kyle Guinn <elyk03@gmail.com>,"
73 "Theodore Kilgore <kilgota@auburn.edu>");
74MODULE_DESCRIPTION("GSPCA/Mars-Semi MR97310A USB Camera Driver");
75MODULE_LICENSE("GPL");
76
77
78static int force_sensor_type = -1;
79module_param(force_sensor_type, int, 0644);
80MODULE_PARM_DESC(force_sensor_type, "Force sensor type (-1 (auto), 0 or 1)");
81
82
83struct sd {
84 struct gspca_dev gspca_dev;
85 u8 sof_read;
86 u8 cam_type;
87 u8 sensor_type;
88 u8 do_lcd_stop;
89 u8 adj_colors;
90
91 int brightness;
92 u16 exposure;
93 u32 gain;
94 u8 contrast;
95 u8 min_clockdiv;
96};
97
98struct sensor_w_data {
99 u8 reg;
100 u8 flags;
101 u8 data[16];
102 int len;
103};
104
105static void sd_stopN(struct gspca_dev *gspca_dev);
106static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
107static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
108static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
109static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
110static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
111static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
112static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
113static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
114static int sd_setmin_clockdiv(struct gspca_dev *gspca_dev, __s32 val);
115static int sd_getmin_clockdiv(struct gspca_dev *gspca_dev, __s32 *val);
116static void setbrightness(struct gspca_dev *gspca_dev);
117static void setexposure(struct gspca_dev *gspca_dev);
118static void setgain(struct gspca_dev *gspca_dev);
119static void setcontrast(struct gspca_dev *gspca_dev);
120
121
122static const struct ctrl sd_ctrls[] = {
123
124
125
126 {
127#define NORM_BRIGHTNESS_IDX 0
128 {
129 .id = V4L2_CID_BRIGHTNESS,
130 .type = V4L2_CTRL_TYPE_INTEGER,
131 .name = "Brightness",
132 .minimum = -254,
133 .maximum = 255,
134 .step = 1,
135 .default_value = MR97310A_BRIGHTNESS_DEFAULT,
136 .flags = 0,
137 },
138 .set = sd_setbrightness,
139 .get = sd_getbrightness,
140 },
141 {
142#define ARGUS_QC_BRIGHTNESS_IDX 1
143 {
144 .id = V4L2_CID_BRIGHTNESS,
145 .type = V4L2_CTRL_TYPE_INTEGER,
146 .name = "Brightness",
147 .minimum = 0,
148 .maximum = 15,
149 .step = 1,
150 .default_value = MR97310A_BRIGHTNESS_DEFAULT,
151 .flags = 0,
152 },
153 .set = sd_setbrightness,
154 .get = sd_getbrightness,
155 },
156 {
157#define EXPOSURE_IDX 2
158 {
159 .id = V4L2_CID_EXPOSURE,
160 .type = V4L2_CTRL_TYPE_INTEGER,
161 .name = "Exposure",
162 .minimum = MR97310A_EXPOSURE_MIN,
163 .maximum = MR97310A_EXPOSURE_MAX,
164 .step = 1,
165 .default_value = MR97310A_EXPOSURE_DEFAULT,
166 .flags = 0,
167 },
168 .set = sd_setexposure,
169 .get = sd_getexposure,
170 },
171 {
172#define GAIN_IDX 3
173 {
174 .id = V4L2_CID_GAIN,
175 .type = V4L2_CTRL_TYPE_INTEGER,
176 .name = "Gain",
177 .minimum = MR97310A_GAIN_MIN,
178 .maximum = MR97310A_GAIN_MAX,
179 .step = 1,
180 .default_value = MR97310A_GAIN_DEFAULT,
181 .flags = 0,
182 },
183 .set = sd_setgain,
184 .get = sd_getgain,
185 },
186 {
187#define SAKAR_CS_GAIN_IDX 4
188 {
189 .id = V4L2_CID_GAIN,
190 .type = V4L2_CTRL_TYPE_INTEGER,
191 .name = "Gain",
192 .minimum = MR97310A_CS_GAIN_MIN,
193 .maximum = MR97310A_CS_GAIN_MAX,
194 .step = 1,
195 .default_value = MR97310A_CS_GAIN_DEFAULT,
196 .flags = 0,
197 },
198 .set = sd_setgain,
199 .get = sd_getgain,
200 },
201 {
202#define CONTRAST_IDX 5
203 {
204 .id = V4L2_CID_CONTRAST,
205 .type = V4L2_CTRL_TYPE_INTEGER,
206 .name = "Contrast",
207 .minimum = MR97310A_CONTRAST_MIN,
208 .maximum = MR97310A_CONTRAST_MAX,
209 .step = 1,
210 .default_value = MR97310A_CONTRAST_DEFAULT,
211 .flags = 0,
212 },
213 .set = sd_setcontrast,
214 .get = sd_getcontrast,
215 },
216 {
217#define MIN_CLOCKDIV_IDX 6
218 {
219 .id = V4L2_CID_PRIVATE_BASE,
220 .type = V4L2_CTRL_TYPE_INTEGER,
221 .name = "Minimum Clock Divider",
222 .minimum = MR97310A_MIN_CLOCKDIV_MIN,
223 .maximum = MR97310A_MIN_CLOCKDIV_MAX,
224 .step = 1,
225 .default_value = MR97310A_MIN_CLOCKDIV_DEFAULT,
226 .flags = 0,
227 },
228 .set = sd_setmin_clockdiv,
229 .get = sd_getmin_clockdiv,
230 },
231};
232
233static const struct v4l2_pix_format vga_mode[] = {
234 {160, 120, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
235 .bytesperline = 160,
236 .sizeimage = 160 * 120,
237 .colorspace = V4L2_COLORSPACE_SRGB,
238 .priv = 4},
239 {176, 144, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
240 .bytesperline = 176,
241 .sizeimage = 176 * 144,
242 .colorspace = V4L2_COLORSPACE_SRGB,
243 .priv = 3},
244 {320, 240, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
245 .bytesperline = 320,
246 .sizeimage = 320 * 240,
247 .colorspace = V4L2_COLORSPACE_SRGB,
248 .priv = 2},
249 {352, 288, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
250 .bytesperline = 352,
251 .sizeimage = 352 * 288,
252 .colorspace = V4L2_COLORSPACE_SRGB,
253 .priv = 1},
254 {640, 480, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
255 .bytesperline = 640,
256 .sizeimage = 640 * 480,
257 .colorspace = V4L2_COLORSPACE_SRGB,
258 .priv = 0},
259};
260
261
262static int mr_write(struct gspca_dev *gspca_dev, int len)
263{
264 int rc;
265
266 rc = usb_bulk_msg(gspca_dev->dev,
267 usb_sndbulkpipe(gspca_dev->dev, 4),
268 gspca_dev->usb_buf, len, NULL, 500);
269 if (rc < 0)
270 err("reg write [%02x] error %d",
271 gspca_dev->usb_buf[0], rc);
272 return rc;
273}
274
275
276static int mr_read(struct gspca_dev *gspca_dev, int len)
277{
278 int rc;
279
280 rc = usb_bulk_msg(gspca_dev->dev,
281 usb_rcvbulkpipe(gspca_dev->dev, 3),
282 gspca_dev->usb_buf, len, NULL, 500);
283 if (rc < 0)
284 err("reg read [%02x] error %d",
285 gspca_dev->usb_buf[0], rc);
286 return rc;
287}
288
289static int sensor_write_reg(struct gspca_dev *gspca_dev, u8 reg, u8 flags,
290 const u8 *data, int len)
291{
292 gspca_dev->usb_buf[0] = 0x1f;
293 gspca_dev->usb_buf[1] = flags;
294 gspca_dev->usb_buf[2] = reg;
295 memcpy(gspca_dev->usb_buf + 3, data, len);
296
297 return mr_write(gspca_dev, len + 3);
298}
299
300static int sensor_write_regs(struct gspca_dev *gspca_dev,
301 const struct sensor_w_data *data, int len)
302{
303 int i, rc;
304
305 for (i = 0; i < len; i++) {
306 rc = sensor_write_reg(gspca_dev, data[i].reg, data[i].flags,
307 data[i].data, data[i].len);
308 if (rc < 0)
309 return rc;
310 }
311
312 return 0;
313}
314
315static int sensor_write1(struct gspca_dev *gspca_dev, u8 reg, u8 data)
316{
317 struct sd *sd = (struct sd *) gspca_dev;
318 u8 buf, confirm_reg;
319 int rc;
320
321 buf = data;
322 if (sd->cam_type == CAM_TYPE_CIF) {
323 rc = sensor_write_reg(gspca_dev, reg, 0x01, &buf, 1);
324 confirm_reg = sd->sensor_type ? 0x13 : 0x11;
325 } else {
326 rc = sensor_write_reg(gspca_dev, reg, 0x00, &buf, 1);
327 confirm_reg = 0x11;
328 }
329 if (rc < 0)
330 return rc;
331
332 buf = 0x01;
333 rc = sensor_write_reg(gspca_dev, confirm_reg, 0x00, &buf, 1);
334 if (rc < 0)
335 return rc;
336
337 return 0;
338}
339
340static int cam_get_response16(struct gspca_dev *gspca_dev, u8 reg, int verbose)
341{
342 int err_code;
343
344 gspca_dev->usb_buf[0] = reg;
345 err_code = mr_write(gspca_dev, 1);
346 if (err_code < 0)
347 return err_code;
348
349 err_code = mr_read(gspca_dev, 16);
350 if (err_code < 0)
351 return err_code;
352
353 if (verbose)
354 PDEBUG(D_PROBE, "Register: %02x reads %02x%02x%02x", reg,
355 gspca_dev->usb_buf[0],
356 gspca_dev->usb_buf[1],
357 gspca_dev->usb_buf[2]);
358
359 return 0;
360}
361
362static int zero_the_pointer(struct gspca_dev *gspca_dev)
363{
364 __u8 *data = gspca_dev->usb_buf;
365 int err_code;
366 u8 status = 0;
367 int tries = 0;
368
369 err_code = cam_get_response16(gspca_dev, 0x21, 0);
370 if (err_code < 0)
371 return err_code;
372
373 data[0] = 0x19;
374 data[1] = 0x51;
375 err_code = mr_write(gspca_dev, 2);
376 if (err_code < 0)
377 return err_code;
378
379 err_code = cam_get_response16(gspca_dev, 0x21, 0);
380 if (err_code < 0)
381 return err_code;
382
383 data[0] = 0x19;
384 data[1] = 0xba;
385 err_code = mr_write(gspca_dev, 2);
386 if (err_code < 0)
387 return err_code;
388
389 err_code = cam_get_response16(gspca_dev, 0x21, 0);
390 if (err_code < 0)
391 return err_code;
392
393 data[0] = 0x19;
394 data[1] = 0x00;
395 err_code = mr_write(gspca_dev, 2);
396 if (err_code < 0)
397 return err_code;
398
399 err_code = cam_get_response16(gspca_dev, 0x21, 0);
400 if (err_code < 0)
401 return err_code;
402
403 data[0] = 0x19;
404 data[1] = 0x00;
405 err_code = mr_write(gspca_dev, 2);
406 if (err_code < 0)
407 return err_code;
408
409 while (status != 0x0a && tries < 256) {
410 err_code = cam_get_response16(gspca_dev, 0x21, 0);
411 status = data[0];
412 tries++;
413 if (err_code < 0)
414 return err_code;
415 }
416 if (status != 0x0a)
417 PDEBUG(D_ERR, "status is %02x", status);
418
419 tries = 0;
420 while (tries < 4) {
421 data[0] = 0x19;
422 data[1] = 0x00;
423 err_code = mr_write(gspca_dev, 2);
424 if (err_code < 0)
425 return err_code;
426
427 err_code = cam_get_response16(gspca_dev, 0x21, 0);
428 status = data[0];
429 tries++;
430 if (err_code < 0)
431 return err_code;
432 }
433
434 data[0] = 0x19;
435 err_code = mr_write(gspca_dev, 1);
436 if (err_code < 0)
437 return err_code;
438
439 err_code = mr_read(gspca_dev, 16);
440 if (err_code < 0)
441 return err_code;
442
443 return 0;
444}
445
446static int stream_start(struct gspca_dev *gspca_dev)
447{
448 gspca_dev->usb_buf[0] = 0x01;
449 gspca_dev->usb_buf[1] = 0x01;
450 return mr_write(gspca_dev, 2);
451}
452
453static void stream_stop(struct gspca_dev *gspca_dev)
454{
455 gspca_dev->usb_buf[0] = 0x01;
456 gspca_dev->usb_buf[1] = 0x00;
457 if (mr_write(gspca_dev, 2) < 0)
458 PDEBUG(D_ERR, "Stream Stop failed");
459}
460
461static void lcd_stop(struct gspca_dev *gspca_dev)
462{
463 gspca_dev->usb_buf[0] = 0x19;
464 gspca_dev->usb_buf[1] = 0x54;
465 if (mr_write(gspca_dev, 2) < 0)
466 PDEBUG(D_ERR, "LCD Stop failed");
467}
468
469static int isoc_enable(struct gspca_dev *gspca_dev)
470{
471 gspca_dev->usb_buf[0] = 0x00;
472 gspca_dev->usb_buf[1] = 0x4d;
473 return mr_write(gspca_dev, 2);
474}
475
476
477static int sd_config(struct gspca_dev *gspca_dev,
478 const struct usb_device_id *id)
479{
480 struct sd *sd = (struct sd *) gspca_dev;
481 struct cam *cam;
482 int gain_default = MR97310A_GAIN_DEFAULT;
483 int err_code;
484
485 cam = &gspca_dev->cam;
486 cam->cam_mode = vga_mode;
487 cam->nmodes = ARRAY_SIZE(vga_mode);
488 sd->do_lcd_stop = 0;
489
490
491
492
493
494
495
496
497
498 err_code = zero_the_pointer(gspca_dev);
499 if (err_code < 0)
500 return err_code;
501
502 err_code = stream_start(gspca_dev);
503 if (err_code < 0)
504 return err_code;
505
506
507 err_code = cam_get_response16(gspca_dev, 0x07, 1);
508 if (err_code < 0)
509 return err_code;
510
511 if (id->idProduct == 0x0110 || id->idProduct == 0x010e) {
512 sd->cam_type = CAM_TYPE_CIF;
513 cam->nmodes--;
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535 switch (gspca_dev->usb_buf[0]) {
536 case 2:
537 sd->sensor_type = 0;
538 break;
539 case 3:
540 sd->sensor_type = 1;
541 break;
542 default:
543 err("Unknown CIF Sensor id : %02x",
544 gspca_dev->usb_buf[1]);
545 return -ENODEV;
546 }
547 PDEBUG(D_PROBE, "MR97310A CIF camera detected, sensor: %d",
548 sd->sensor_type);
549 } else {
550 sd->cam_type = CAM_TYPE_VGA;
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571 sd->sensor_type = 1;
572 sd->do_lcd_stop = 0;
573 sd->adj_colors = 0;
574 if (gspca_dev->usb_buf[0] == 0x01) {
575 sd->sensor_type = 2;
576 } else if ((gspca_dev->usb_buf[0] != 0x03) &&
577 (gspca_dev->usb_buf[0] != 0x04)) {
578 err("Unknown VGA Sensor id Byte 0: %02x",
579 gspca_dev->usb_buf[0]);
580 err("Defaults assumed, may not work");
581 err("Please report this");
582 }
583
584 if ((gspca_dev->usb_buf[0] == 0x03) &&
585 (gspca_dev->usb_buf[1] == 0x50))
586 sd->adj_colors = 1;
587 if (gspca_dev->usb_buf[0] == 0x04) {
588 sd->do_lcd_stop = 1;
589 switch (gspca_dev->usb_buf[1]) {
590 case 0x50:
591 sd->sensor_type = 0;
592 PDEBUG(D_PROBE, "sensor_type corrected to 0");
593 break;
594 case 0x20:
595
596 break;
597 default:
598 err("Unknown VGA Sensor id Byte 1: %02x",
599 gspca_dev->usb_buf[1]);
600 err("Defaults assumed, may not work");
601 err("Please report this");
602 }
603 }
604 PDEBUG(D_PROBE, "MR97310A VGA camera detected, sensor: %d",
605 sd->sensor_type);
606 }
607
608 sd_stopN(gspca_dev);
609
610 if (force_sensor_type != -1) {
611 sd->sensor_type = !!force_sensor_type;
612 PDEBUG(D_PROBE, "Forcing sensor type to: %d",
613 sd->sensor_type);
614 }
615
616
617 if (sd->cam_type == CAM_TYPE_CIF) {
618
619 if (sd->sensor_type == 0)
620 gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX) |
621 (1 << ARGUS_QC_BRIGHTNESS_IDX) |
622 (1 << CONTRAST_IDX) |
623 (1 << SAKAR_CS_GAIN_IDX);
624 else
625 gspca_dev->ctrl_dis = (1 << ARGUS_QC_BRIGHTNESS_IDX) |
626 (1 << CONTRAST_IDX) |
627 (1 << SAKAR_CS_GAIN_IDX) |
628 (1 << MIN_CLOCKDIV_IDX);
629 } else {
630
631 if (sd->sensor_type == 0)
632 gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX) |
633 (1 << ARGUS_QC_BRIGHTNESS_IDX) |
634 (1 << EXPOSURE_IDX) |
635 (1 << GAIN_IDX) |
636 (1 << CONTRAST_IDX) |
637 (1 << SAKAR_CS_GAIN_IDX) |
638 (1 << MIN_CLOCKDIV_IDX);
639 else if (sd->sensor_type == 2) {
640 gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX) |
641 (1 << ARGUS_QC_BRIGHTNESS_IDX) |
642 (1 << GAIN_IDX) |
643 (1 << MIN_CLOCKDIV_IDX);
644 gain_default = MR97310A_CS_GAIN_DEFAULT;
645 } else if (sd->do_lcd_stop)
646
647 gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX) |
648 (1 << CONTRAST_IDX) |
649 (1 << SAKAR_CS_GAIN_IDX);
650 else
651 gspca_dev->ctrl_dis = (1 << ARGUS_QC_BRIGHTNESS_IDX) |
652 (1 << CONTRAST_IDX) |
653 (1 << SAKAR_CS_GAIN_IDX);
654 }
655
656 sd->brightness = MR97310A_BRIGHTNESS_DEFAULT;
657 sd->exposure = MR97310A_EXPOSURE_DEFAULT;
658 sd->gain = gain_default;
659 sd->contrast = MR97310A_CONTRAST_DEFAULT;
660 sd->min_clockdiv = MR97310A_MIN_CLOCKDIV_DEFAULT;
661
662 return 0;
663}
664
665
666static int sd_init(struct gspca_dev *gspca_dev)
667{
668 return 0;
669}
670
671static int start_cif_cam(struct gspca_dev *gspca_dev)
672{
673 struct sd *sd = (struct sd *) gspca_dev;
674 __u8 *data = gspca_dev->usb_buf;
675 int err_code;
676 static const __u8 startup_string[] = {
677 0x00,
678 0x0d,
679 0x01,
680 0x00,
681 0x00,
682 0x13,
683 0x00,
684 0x00,
685 0x00,
686 0x50,
687 0xc0
688 };
689
690
691
692 memcpy(data, startup_string, 11);
693 if (sd->sensor_type)
694 data[5] = 0xbb;
695
696 switch (gspca_dev->width) {
697 case 160:
698 data[9] |= 0x04;
699
700 case 320:
701 default:
702 data[3] = 0x28;
703 data[4] = 0x3c;
704 data[6] = 0x14;
705 data[8] = 0x1a + sd->sensor_type;
706 break;
707 case 176:
708 data[9] |= 0x04;
709
710 case 352:
711 data[3] = 0x2c;
712 data[4] = 0x48;
713 data[6] = 0x06;
714 data[8] = 0x06 - sd->sensor_type;
715 break;
716 }
717 err_code = mr_write(gspca_dev, 11);
718 if (err_code < 0)
719 return err_code;
720
721 if (!sd->sensor_type) {
722 static const struct sensor_w_data cif_sensor0_init_data[] = {
723 {0x02, 0x00, {0x03, 0x5a, 0xb5, 0x01,
724 0x0f, 0x14, 0x0f, 0x10}, 8},
725 {0x0c, 0x00, {0x04, 0x01, 0x01, 0x00, 0x1f}, 5},
726 {0x12, 0x00, {0x07}, 1},
727 {0x1f, 0x00, {0x06}, 1},
728 {0x27, 0x00, {0x04}, 1},
729 {0x29, 0x00, {0x0c}, 1},
730 {0x40, 0x00, {0x40, 0x00, 0x04}, 3},
731 {0x50, 0x00, {0x60}, 1},
732 {0x60, 0x00, {0x06}, 1},
733 {0x6b, 0x00, {0x85, 0x85, 0xc8, 0xc8, 0xc8, 0xc8}, 6},
734 {0x72, 0x00, {0x1e, 0x56}, 2},
735 {0x75, 0x00, {0x58, 0x40, 0xa2, 0x02, 0x31, 0x02,
736 0x31, 0x80, 0x00}, 9},
737 {0x11, 0x00, {0x01}, 1},
738 {0, 0, {0}, 0}
739 };
740 err_code = sensor_write_regs(gspca_dev, cif_sensor0_init_data,
741 ARRAY_SIZE(cif_sensor0_init_data));
742 } else {
743 static const struct sensor_w_data cif_sensor1_init_data[] = {
744
745 {0x02, 0x00, {0x10}, 1},
746 {0x05, 0x01, {0x22}, 1},
747 {0x06, 0x01, {0x00}, 1},
748 {0x09, 0x02, {0x0e}, 1},
749 {0x0a, 0x02, {0x05}, 1},
750 {0x0b, 0x02, {0x05}, 1},
751 {0x0c, 0x02, {0x0f}, 1},
752 {0x0d, 0x02, {0x07}, 1},
753 {0x0e, 0x02, {0x0c}, 1},
754 {0x0f, 0x00, {0x00}, 1},
755 {0x10, 0x00, {0x06}, 1},
756 {0x11, 0x00, {0x07}, 1},
757 {0x12, 0x00, {0x00}, 1},
758 {0x13, 0x00, {0x01}, 1},
759 {0, 0, {0}, 0}
760 };
761
762 gspca_dev->usb_buf[0] = 0x0a;
763 gspca_dev->usb_buf[1] = 0x00;
764 err_code = mr_write(gspca_dev, 2);
765 if (err_code < 0)
766 return err_code;
767 err_code = sensor_write_regs(gspca_dev, cif_sensor1_init_data,
768 ARRAY_SIZE(cif_sensor1_init_data));
769 }
770 return err_code;
771}
772
773static int start_vga_cam(struct gspca_dev *gspca_dev)
774{
775 struct sd *sd = (struct sd *) gspca_dev;
776 __u8 *data = gspca_dev->usb_buf;
777 int err_code;
778 static const __u8 startup_string[] =
779 {0x00, 0x0d, 0x01, 0x00, 0x00, 0x2b, 0x00, 0x00,
780 0x00, 0x50, 0xc0};
781
782
783 memcpy(data, startup_string, 11);
784 if (!sd->sensor_type) {
785 data[5] = 0x00;
786 data[10] = 0x91;
787 }
788 if (sd->sensor_type == 2) {
789 data[5] = 0x00;
790 data[10] = 0x18;
791 }
792
793 switch (gspca_dev->width) {
794 case 160:
795 data[9] |= 0x0c;
796
797 case 320:
798 data[9] |= 0x04;
799
800 case 640:
801 default:
802 data[3] = 0x50;
803 data[4] = 0x78;
804 data[6] = 0x04;
805 data[8] = 0x03;
806 if (sd->sensor_type == 2) {
807 data[6] = 2;
808 data[8] = 1;
809 }
810 if (sd->do_lcd_stop)
811 data[8] = 0x04;
812 break;
813
814 case 176:
815 data[9] |= 0x04;
816
817 case 352:
818 data[3] = 0x2c;
819 data[4] = 0x48;
820 data[6] = 0x94;
821 data[8] = 0x63;
822 if (sd->do_lcd_stop)
823 data[8] = 0x64;
824 break;
825 }
826
827 err_code = mr_write(gspca_dev, 11);
828 if (err_code < 0)
829 return err_code;
830
831 if (!sd->sensor_type) {
832 static const struct sensor_w_data vga_sensor0_init_data[] = {
833 {0x01, 0x00, {0x0c, 0x00, 0x04}, 3},
834 {0x14, 0x00, {0x01, 0xe4, 0x02, 0x84}, 4},
835 {0x20, 0x00, {0x00, 0x80, 0x00, 0x08}, 4},
836 {0x25, 0x00, {0x03, 0xa9, 0x80}, 3},
837 {0x30, 0x00, {0x30, 0x18, 0x10, 0x18}, 4},
838 {0, 0, {0}, 0}
839 };
840 err_code = sensor_write_regs(gspca_dev, vga_sensor0_init_data,
841 ARRAY_SIZE(vga_sensor0_init_data));
842 } else if (sd->sensor_type == 1) {
843 static const struct sensor_w_data color_adj[] = {
844 {0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00,
845
846
847 0x05, 0x01, 0x04}, 8}
848 };
849
850 static const struct sensor_w_data color_no_adj[] = {
851 {0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00,
852
853 0x07, 0x00, 0x01}, 8}
854 };
855
856 static const struct sensor_w_data vga_sensor1_init_data[] = {
857 {0x11, 0x04, {0x01}, 1},
858 {0x0a, 0x00, {0x00, 0x01, 0x00, 0x00, 0x01,
859
860
861 0x00, 0x0a}, 7},
862 {0x11, 0x04, {0x01}, 1},
863 {0x12, 0x00, {0x00, 0x63, 0x00, 0x70, 0x00, 0x00}, 6},
864 {0x11, 0x04, {0x01}, 1},
865 {0, 0, {0}, 0}
866 };
867
868 if (sd->adj_colors)
869 err_code = sensor_write_regs(gspca_dev, color_adj,
870 ARRAY_SIZE(color_adj));
871 else
872 err_code = sensor_write_regs(gspca_dev, color_no_adj,
873 ARRAY_SIZE(color_no_adj));
874
875 if (err_code < 0)
876 return err_code;
877
878 err_code = sensor_write_regs(gspca_dev, vga_sensor1_init_data,
879 ARRAY_SIZE(vga_sensor1_init_data));
880 } else {
881 static const struct sensor_w_data vga_sensor2_init_data[] = {
882
883 {0x01, 0x00, {0x48}, 1},
884 {0x02, 0x00, {0x22}, 1},
885
886 {0x05, 0x00, {0x10}, 1},
887 {0x06, 0x00, {0x00}, 1},
888 {0x07, 0x00, {0x00}, 1},
889 {0x08, 0x00, {0x00}, 1},
890 {0x09, 0x00, {0x00}, 1},
891
892
893
894
895
896
897
898
899
900
901
902
903 {0x12, 0x00, {0x00}, 1},
904 {0x13, 0x00, {0x04}, 1},
905 {0x14, 0x00, {0x00}, 1},
906 {0x15, 0x00, {0x06}, 1},
907 {0x16, 0x00, {0x01}, 1},
908 {0x17, 0x00, {0xe2}, 1},
909 {0x18, 0x00, {0x02}, 1},
910 {0x19, 0x00, {0x82}, 1},
911 {0x1a, 0x00, {0x00}, 1},
912 {0x1b, 0x00, {0x20}, 1},
913
914 {0x1d, 0x00, {0x80}, 1},
915 {0x1e, 0x00, {0x08}, 1},
916 {0x1f, 0x00, {0x0c}, 1},
917 {0x20, 0x00, {0x00}, 1},
918 {0, 0, {0}, 0}
919 };
920 err_code = sensor_write_regs(gspca_dev, vga_sensor2_init_data,
921 ARRAY_SIZE(vga_sensor2_init_data));
922 }
923 return err_code;
924}
925
926static int sd_start(struct gspca_dev *gspca_dev)
927{
928 struct sd *sd = (struct sd *) gspca_dev;
929 int err_code;
930
931 sd->sof_read = 0;
932
933
934
935
936
937 err_code = zero_the_pointer(gspca_dev);
938 if (err_code < 0)
939 return err_code;
940
941 err_code = stream_start(gspca_dev);
942 if (err_code < 0)
943 return err_code;
944
945 if (sd->cam_type == CAM_TYPE_CIF) {
946 err_code = start_cif_cam(gspca_dev);
947 } else {
948 err_code = start_vga_cam(gspca_dev);
949 }
950 if (err_code < 0)
951 return err_code;
952
953 setbrightness(gspca_dev);
954 setcontrast(gspca_dev);
955 setexposure(gspca_dev);
956 setgain(gspca_dev);
957
958 return isoc_enable(gspca_dev);
959}
960
961static void sd_stopN(struct gspca_dev *gspca_dev)
962{
963 struct sd *sd = (struct sd *) gspca_dev;
964
965 stream_stop(gspca_dev);
966
967 zero_the_pointer(gspca_dev);
968 if (sd->do_lcd_stop)
969 lcd_stop(gspca_dev);
970}
971
972static void setbrightness(struct gspca_dev *gspca_dev)
973{
974 struct sd *sd = (struct sd *) gspca_dev;
975 u8 val;
976 u8 sign_reg = 7;
977 u8 value_reg = 8;
978 static const u8 quick_clix_table[] =
979
980 { 0, 4, 8, 12, 1, 2, 3, 5, 6, 9, 7, 10, 13, 11, 14, 15};
981
982
983
984
985
986
987 if ((gspca_dev->ctrl_dis & (1 << NORM_BRIGHTNESS_IDX)) &&
988 (gspca_dev->ctrl_dis & (1 << ARGUS_QC_BRIGHTNESS_IDX)))
989 return;
990
991 if (sd->cam_type == CAM_TYPE_VGA) {
992 sign_reg += 4;
993 value_reg += 4;
994 }
995
996
997 if (sd->brightness > 0) {
998 sensor_write1(gspca_dev, sign_reg, 0x00);
999 val = sd->brightness;
1000 } else {
1001 sensor_write1(gspca_dev, sign_reg, 0x01);
1002 val = (257 - sd->brightness);
1003 }
1004
1005 if (sd->do_lcd_stop)
1006 val = quick_clix_table[val];
1007
1008 sensor_write1(gspca_dev, value_reg, val);
1009}
1010
1011static void setexposure(struct gspca_dev *gspca_dev)
1012{
1013 struct sd *sd = (struct sd *) gspca_dev;
1014 int exposure = MR97310A_EXPOSURE_DEFAULT;
1015 u8 buf[2];
1016
1017 if (gspca_dev->ctrl_dis & (1 << EXPOSURE_IDX))
1018 return;
1019
1020 if (sd->cam_type == CAM_TYPE_CIF && sd->sensor_type == 1) {
1021
1022
1023 exposure = (sd->exposure * 9267) / 10000 + 300;
1024 sensor_write1(gspca_dev, 3, exposure >> 4);
1025 sensor_write1(gspca_dev, 4, exposure & 0x0f);
1026 } else if (sd->sensor_type == 2) {
1027 exposure = sd->exposure;
1028 exposure >>= 3;
1029 sensor_write1(gspca_dev, 3, exposure >> 8);
1030 sensor_write1(gspca_dev, 4, exposure & 0xff);
1031 } else {
1032
1033
1034
1035
1036
1037
1038
1039 u8 clockdiv = (60 * sd->exposure + 7999) / 8000;
1040
1041
1042 if (clockdiv < sd->min_clockdiv && gspca_dev->width >= 320)
1043 clockdiv = sd->min_clockdiv;
1044 else if (clockdiv < 2)
1045 clockdiv = 2;
1046
1047 if (sd->cam_type == CAM_TYPE_VGA && clockdiv < 4)
1048 clockdiv = 4;
1049
1050
1051
1052 exposure = (60 * 511 * sd->exposure) / (8000 * clockdiv);
1053 if (exposure > 511)
1054 exposure = 511;
1055
1056
1057 exposure = 511 - exposure;
1058
1059 buf[0] = exposure & 0xff;
1060 buf[1] = exposure >> 8;
1061 sensor_write_reg(gspca_dev, 0x0e, 0, buf, 2);
1062 sensor_write1(gspca_dev, 0x02, clockdiv);
1063 }
1064}
1065
1066static void setgain(struct gspca_dev *gspca_dev)
1067{
1068 struct sd *sd = (struct sd *) gspca_dev;
1069 u8 gainreg;
1070
1071 if ((gspca_dev->ctrl_dis & (1 << GAIN_IDX)) &&
1072 (gspca_dev->ctrl_dis & (1 << SAKAR_CS_GAIN_IDX)))
1073 return;
1074
1075 if (sd->cam_type == CAM_TYPE_CIF && sd->sensor_type == 1)
1076 sensor_write1(gspca_dev, 0x0e, sd->gain);
1077 else if (sd->cam_type == CAM_TYPE_VGA && sd->sensor_type == 2)
1078 for (gainreg = 0x0a; gainreg < 0x11; gainreg += 2) {
1079 sensor_write1(gspca_dev, gainreg, sd->gain >> 8);
1080 sensor_write1(gspca_dev, gainreg + 1, sd->gain & 0xff);
1081 }
1082 else
1083 sensor_write1(gspca_dev, 0x10, sd->gain);
1084}
1085
1086static void setcontrast(struct gspca_dev *gspca_dev)
1087{
1088 struct sd *sd = (struct sd *) gspca_dev;
1089
1090 if (gspca_dev->ctrl_dis & (1 << CONTRAST_IDX))
1091 return;
1092
1093 sensor_write1(gspca_dev, 0x1c, sd->contrast);
1094}
1095
1096
1097static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1098{
1099 struct sd *sd = (struct sd *) gspca_dev;
1100
1101 sd->brightness = val;
1102 if (gspca_dev->streaming)
1103 setbrightness(gspca_dev);
1104 return 0;
1105}
1106
1107static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1108{
1109 struct sd *sd = (struct sd *) gspca_dev;
1110
1111 *val = sd->brightness;
1112 return 0;
1113}
1114
1115static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
1116{
1117 struct sd *sd = (struct sd *) gspca_dev;
1118
1119 sd->exposure = val;
1120 if (gspca_dev->streaming)
1121 setexposure(gspca_dev);
1122 return 0;
1123}
1124
1125static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
1126{
1127 struct sd *sd = (struct sd *) gspca_dev;
1128
1129 *val = sd->exposure;
1130 return 0;
1131}
1132
1133static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
1134{
1135 struct sd *sd = (struct sd *) gspca_dev;
1136
1137 sd->gain = val;
1138 if (gspca_dev->streaming)
1139 setgain(gspca_dev);
1140 return 0;
1141}
1142
1143static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
1144{
1145 struct sd *sd = (struct sd *) gspca_dev;
1146
1147 *val = sd->gain;
1148 return 0;
1149}
1150
1151static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1152{
1153 struct sd *sd = (struct sd *) gspca_dev;
1154
1155 sd->contrast = val;
1156 if (gspca_dev->streaming)
1157 setcontrast(gspca_dev);
1158 return 0;
1159}
1160
1161
1162static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1163{
1164 struct sd *sd = (struct sd *) gspca_dev;
1165
1166 *val = sd->contrast;
1167 return 0;
1168}
1169
1170static int sd_setmin_clockdiv(struct gspca_dev *gspca_dev, __s32 val)
1171{
1172 struct sd *sd = (struct sd *) gspca_dev;
1173
1174 sd->min_clockdiv = val;
1175 if (gspca_dev->streaming)
1176 setexposure(gspca_dev);
1177 return 0;
1178}
1179
1180static int sd_getmin_clockdiv(struct gspca_dev *gspca_dev, __s32 *val)
1181{
1182 struct sd *sd = (struct sd *) gspca_dev;
1183
1184 *val = sd->min_clockdiv;
1185 return 0;
1186}
1187
1188
1189#include "pac_common.h"
1190
1191static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1192 u8 *data,
1193 int len)
1194{
1195 struct sd *sd = (struct sd *) gspca_dev;
1196 unsigned char *sof;
1197
1198 sof = pac_find_sof(&sd->sof_read, data, len);
1199 if (sof) {
1200 int n;
1201
1202
1203 n = sof - data;
1204 if (n > sizeof pac_sof_marker)
1205 n -= sizeof pac_sof_marker;
1206 else
1207 n = 0;
1208 gspca_frame_add(gspca_dev, LAST_PACKET,
1209 data, n);
1210
1211 gspca_frame_add(gspca_dev, FIRST_PACKET,
1212 pac_sof_marker, sizeof pac_sof_marker);
1213 len -= sof - data;
1214 data = sof;
1215 }
1216 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
1217}
1218
1219
1220static const struct sd_desc sd_desc = {
1221 .name = MODULE_NAME,
1222 .ctrls = sd_ctrls,
1223 .nctrls = ARRAY_SIZE(sd_ctrls),
1224 .config = sd_config,
1225 .init = sd_init,
1226 .start = sd_start,
1227 .stopN = sd_stopN,
1228 .pkt_scan = sd_pkt_scan,
1229};
1230
1231
1232static const struct usb_device_id device_table[] = {
1233 {USB_DEVICE(0x08ca, 0x0110)},
1234 {USB_DEVICE(0x08ca, 0x0111)},
1235 {USB_DEVICE(0x093a, 0x010f)},
1236 {USB_DEVICE(0x093a, 0x010e)},
1237 {}
1238};
1239MODULE_DEVICE_TABLE(usb, device_table);
1240
1241
1242static int sd_probe(struct usb_interface *intf,
1243 const struct usb_device_id *id)
1244{
1245 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1246 THIS_MODULE);
1247}
1248
1249static struct usb_driver sd_driver = {
1250 .name = MODULE_NAME,
1251 .id_table = device_table,
1252 .probe = sd_probe,
1253 .disconnect = gspca_disconnect,
1254#ifdef CONFIG_PM
1255 .suspend = gspca_suspend,
1256 .resume = gspca_resume,
1257#endif
1258};
1259
1260
1261static int __init sd_mod_init(void)
1262{
1263 return usb_register(&sd_driver);
1264}
1265static void __exit sd_mod_exit(void)
1266{
1267 usb_deregister(&sd_driver);
1268}
1269
1270module_init(sd_mod_init);
1271module_exit(sd_mod_exit);
1272