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