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