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