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