aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca/mr97310a.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/gspca/mr97310a.c')
-rw-r--r--drivers/media/video/gspca/mr97310a.c226
1 files changed, 193 insertions, 33 deletions
diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/video/gspca/mr97310a.c
index 9154870e07d2..33744e724eaa 100644
--- a/drivers/media/video/gspca/mr97310a.c
+++ b/drivers/media/video/gspca/mr97310a.c
@@ -57,6 +57,14 @@
57#define MR97310A_GAIN_MAX 31 57#define MR97310A_GAIN_MAX 31
58#define MR97310A_GAIN_DEFAULT 25 58#define MR97310A_GAIN_DEFAULT 25
59 59
60#define MR97310A_CONTRAST_MIN 0
61#define MR97310A_CONTRAST_MAX 31
62#define MR97310A_CONTRAST_DEFAULT 23
63
64#define MR97310A_CS_GAIN_MIN 0
65#define MR97310A_CS_GAIN_MAX 0x7ff
66#define MR97310A_CS_GAIN_DEFAULT 0x110
67
60#define MR97310A_MIN_CLOCKDIV_MIN 3 68#define MR97310A_MIN_CLOCKDIV_MIN 3
61#define MR97310A_MIN_CLOCKDIV_MAX 8 69#define MR97310A_MIN_CLOCKDIV_MAX 8
62#define MR97310A_MIN_CLOCKDIV_DEFAULT 3 70#define MR97310A_MIN_CLOCKDIV_DEFAULT 3
@@ -82,7 +90,8 @@ struct sd {
82 90
83 int brightness; 91 int brightness;
84 u16 exposure; 92 u16 exposure;
85 u8 gain; 93 u32 gain;
94 u8 contrast;
86 u8 min_clockdiv; 95 u8 min_clockdiv;
87}; 96};
88 97
@@ -98,6 +107,8 @@ static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
98static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); 107static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
99static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val); 108static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
100static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val); 109static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
110static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
111static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
101static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val); 112static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
102static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val); 113static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
103static int sd_setmin_clockdiv(struct gspca_dev *gspca_dev, __s32 val); 114static int sd_setmin_clockdiv(struct gspca_dev *gspca_dev, __s32 val);
@@ -105,11 +116,13 @@ static int sd_getmin_clockdiv(struct gspca_dev *gspca_dev, __s32 *val);
105static void setbrightness(struct gspca_dev *gspca_dev); 116static void setbrightness(struct gspca_dev *gspca_dev);
106static void setexposure(struct gspca_dev *gspca_dev); 117static void setexposure(struct gspca_dev *gspca_dev);
107static void setgain(struct gspca_dev *gspca_dev); 118static void setgain(struct gspca_dev *gspca_dev);
119static void setcontrast(struct gspca_dev *gspca_dev);
108 120
109/* V4L2 controls supported by the driver */ 121/* V4L2 controls supported by the driver */
110static struct ctrl sd_ctrls[] = { 122static const struct ctrl sd_ctrls[] = {
111/* Separate brightness control description for Argus QuickClix as it has 123/* Separate brightness control description for Argus QuickClix as it has
112 different limits from the other mr97310a cameras */ 124 * different limits from the other mr97310a cameras, and separate gain
125 * control for Sakar CyberPix camera. */
113 { 126 {
114#define NORM_BRIGHTNESS_IDX 0 127#define NORM_BRIGHTNESS_IDX 0
115 { 128 {
@@ -171,7 +184,37 @@ static struct ctrl sd_ctrls[] = {
171 .get = sd_getgain, 184 .get = sd_getgain,
172 }, 185 },
173 { 186 {
174#define MIN_CLOCKDIV_IDX 4 187#define SAKAR_CS_GAIN_IDX 4
188 {
189 .id = V4L2_CID_GAIN,
190 .type = V4L2_CTRL_TYPE_INTEGER,
191 .name = "Gain",
192 .minimum = MR97310A_CS_GAIN_MIN,
193 .maximum = MR97310A_CS_GAIN_MAX,
194 .step = 1,
195 .default_value = MR97310A_CS_GAIN_DEFAULT,
196 .flags = 0,
197 },
198 .set = sd_setgain,
199 .get = sd_getgain,
200 },
201 {
202#define CONTRAST_IDX 5
203 {
204 .id = V4L2_CID_CONTRAST,
205 .type = V4L2_CTRL_TYPE_INTEGER,
206 .name = "Contrast",
207 .minimum = MR97310A_CONTRAST_MIN,
208 .maximum = MR97310A_CONTRAST_MAX,
209 .step = 1,
210 .default_value = MR97310A_CONTRAST_DEFAULT,
211 .flags = 0,
212 },
213 .set = sd_setcontrast,
214 .get = sd_getcontrast,
215 },
216 {
217#define MIN_CLOCKDIV_IDX 6
175 { 218 {
176 .id = V4L2_CID_PRIVATE_BASE, 219 .id = V4L2_CID_PRIVATE_BASE,
177 .type = V4L2_CTRL_TYPE_INTEGER, 220 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -327,7 +370,6 @@ static int zero_the_pointer(struct gspca_dev *gspca_dev)
327 if (err_code < 0) 370 if (err_code < 0)
328 return err_code; 371 return err_code;
329 372
330 err_code = mr_write(gspca_dev, 1);
331 data[0] = 0x19; 373 data[0] = 0x19;
332 data[1] = 0x51; 374 data[1] = 0x51;
333 err_code = mr_write(gspca_dev, 2); 375 err_code = mr_write(gspca_dev, 2);
@@ -437,6 +479,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
437{ 479{
438 struct sd *sd = (struct sd *) gspca_dev; 480 struct sd *sd = (struct sd *) gspca_dev;
439 struct cam *cam; 481 struct cam *cam;
482 int gain_default = MR97310A_GAIN_DEFAULT;
440 int err_code; 483 int err_code;
441 484
442 cam = &gspca_dev->cam; 485 cam = &gspca_dev->cam;
@@ -460,12 +503,14 @@ static int sd_config(struct gspca_dev *gspca_dev,
460 if (err_code < 0) 503 if (err_code < 0)
461 return err_code; 504 return err_code;
462 505
506 /* Now, the query for sensor type. */
507 err_code = cam_get_response16(gspca_dev, 0x07, 1);
508 if (err_code < 0)
509 return err_code;
510
463 if (id->idProduct == 0x0110 || id->idProduct == 0x010e) { 511 if (id->idProduct == 0x0110 || id->idProduct == 0x010e) {
464 sd->cam_type = CAM_TYPE_CIF; 512 sd->cam_type = CAM_TYPE_CIF;
465 cam->nmodes--; 513 cam->nmodes--;
466 err_code = cam_get_response16(gspca_dev, 0x06, 1);
467 if (err_code < 0)
468 return err_code;
469 /* 514 /*
470 * All but one of the known CIF cameras share the same USB ID, 515 * All but one of the known CIF cameras share the same USB ID,
471 * but two different init routines are in use, and the control 516 * but two different init routines are in use, and the control
@@ -473,12 +518,12 @@ static int sd_config(struct gspca_dev *gspca_dev,
473 * of the two known varieties is connected! 518 * of the two known varieties is connected!
474 * 519 *
475 * A list of known CIF cameras follows. They all report either 520 * A list of known CIF cameras follows. They all report either
476 * 0002 for type 0 or 0003 for type 1. 521 * 0200 for type 0 or 0300 for type 1.
477 * If you have another to report, please do 522 * If you have another to report, please do
478 * 523 *
479 * Name sd->sensor_type reported by 524 * Name sd->sensor_type reported by
480 * 525 *
481 * Sakar Spy-shot 0 T. Kilgore 526 * Sakar 56379 Spy-shot 0 T. Kilgore
482 * Innovage 0 T. Kilgore 527 * Innovage 0 T. Kilgore
483 * Vivitar Mini 0 H. De Goede 528 * Vivitar Mini 0 H. De Goede
484 * Vivitar Mini 0 E. Rodriguez 529 * Vivitar Mini 0 E. Rodriguez
@@ -487,7 +532,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
487 * Philips dig. keych. 1 T. Kilgore 532 * Philips dig. keych. 1 T. Kilgore
488 * Trust Spyc@m 100 1 A. Jacobs 533 * Trust Spyc@m 100 1 A. Jacobs
489 */ 534 */
490 switch (gspca_dev->usb_buf[1]) { 535 switch (gspca_dev->usb_buf[0]) {
491 case 2: 536 case 2:
492 sd->sensor_type = 0; 537 sd->sensor_type = 0;
493 break; 538 break;
@@ -504,20 +549,19 @@ static int sd_config(struct gspca_dev *gspca_dev,
504 } else { 549 } else {
505 sd->cam_type = CAM_TYPE_VGA; 550 sd->cam_type = CAM_TYPE_VGA;
506 551
507 err_code = cam_get_response16(gspca_dev, 0x07, 1);
508 if (err_code < 0)
509 return err_code;
510
511 /* 552 /*
512 * Here is a table of the responses to the previous command 553 * Here is a table of the responses to the query for sensor
513 * from the known MR97310A VGA cameras. 554 * type, from the known MR97310A VGA cameras. Six different
555 * cameras of which five share the same USB ID.
514 * 556 *
515 * Name gspca_dev->usb_buf[] sd->sensor_type 557 * Name gspca_dev->usb_buf[] sd->sensor_type
516 * sd->do_lcd_stop 558 * sd->do_lcd_stop
517 * Aiptek Pencam VGA+ 0300 0 1 559 * Aiptek Pencam VGA+ 0300 0 1
518 * ION digital 0350 0 1 560 * ION digital 0300 0 1
519 * Argus DC-1620 0450 1 0 561 * Argus DC-1620 0450 1 0
520 * Argus QuickClix 0420 1 1 562 * Argus QuickClix 0420 1 1
563 * Sakar 77379 Digital 0350 0 1
564 * Sakar 1638x CyberPix 0120 0 2
521 * 565 *
522 * Based upon these results, we assume default settings 566 * Based upon these results, we assume default settings
523 * and then correct as necessary, as follows. 567 * and then correct as necessary, as follows.
@@ -527,10 +571,12 @@ static int sd_config(struct gspca_dev *gspca_dev,
527 sd->sensor_type = 1; 571 sd->sensor_type = 1;
528 sd->do_lcd_stop = 0; 572 sd->do_lcd_stop = 0;
529 sd->adj_colors = 0; 573 sd->adj_colors = 0;
530 if ((gspca_dev->usb_buf[0] != 0x03) && 574 if (gspca_dev->usb_buf[0] == 0x01) {
575 sd->sensor_type = 2;
576 } else if ((gspca_dev->usb_buf[0] != 0x03) &&
531 (gspca_dev->usb_buf[0] != 0x04)) { 577 (gspca_dev->usb_buf[0] != 0x04)) {
532 PDEBUG(D_ERR, "Unknown VGA Sensor id Byte 0: %02x", 578 PDEBUG(D_ERR, "Unknown VGA Sensor id Byte 0: %02x",
533 gspca_dev->usb_buf[1]); 579 gspca_dev->usb_buf[0]);
534 PDEBUG(D_ERR, "Defaults assumed, may not work"); 580 PDEBUG(D_ERR, "Defaults assumed, may not work");
535 PDEBUG(D_ERR, "Please report this"); 581 PDEBUG(D_ERR, "Please report this");
536 } 582 }
@@ -560,7 +606,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
560 PDEBUG(D_PROBE, "MR97310A VGA camera detected, sensor: %d", 606 PDEBUG(D_PROBE, "MR97310A VGA camera detected, sensor: %d",
561 sd->sensor_type); 607 sd->sensor_type);
562 } 608 }
563 /* Stop streaming as we've started it to probe the sensor type. */ 609 /* Stop streaming as we've started it only to probe the sensor type. */
564 sd_stopN(gspca_dev); 610 sd_stopN(gspca_dev);
565 611
566 if (force_sensor_type != -1) { 612 if (force_sensor_type != -1) {
@@ -574,9 +620,13 @@ static int sd_config(struct gspca_dev *gspca_dev,
574 /* No brightness for sensor_type 0 */ 620 /* No brightness for sensor_type 0 */
575 if (sd->sensor_type == 0) 621 if (sd->sensor_type == 0)
576 gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX) | 622 gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX) |
577 (1 << ARGUS_QC_BRIGHTNESS_IDX); 623 (1 << ARGUS_QC_BRIGHTNESS_IDX) |
624 (1 << CONTRAST_IDX) |
625 (1 << SAKAR_CS_GAIN_IDX);
578 else 626 else
579 gspca_dev->ctrl_dis = (1 << ARGUS_QC_BRIGHTNESS_IDX) | 627 gspca_dev->ctrl_dis = (1 << ARGUS_QC_BRIGHTNESS_IDX) |
628 (1 << CONTRAST_IDX) |
629 (1 << SAKAR_CS_GAIN_IDX) |
580 (1 << MIN_CLOCKDIV_IDX); 630 (1 << MIN_CLOCKDIV_IDX);
581 } else { 631 } else {
582 /* All controls need to be disabled if VGA sensor_type is 0 */ 632 /* All controls need to be disabled if VGA sensor_type is 0 */
@@ -585,17 +635,30 @@ static int sd_config(struct gspca_dev *gspca_dev,
585 (1 << ARGUS_QC_BRIGHTNESS_IDX) | 635 (1 << ARGUS_QC_BRIGHTNESS_IDX) |
586 (1 << EXPOSURE_IDX) | 636 (1 << EXPOSURE_IDX) |
587 (1 << GAIN_IDX) | 637 (1 << GAIN_IDX) |
638 (1 << CONTRAST_IDX) |
639 (1 << SAKAR_CS_GAIN_IDX) |
588 (1 << MIN_CLOCKDIV_IDX); 640 (1 << MIN_CLOCKDIV_IDX);
589 else if (sd->do_lcd_stop) 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)
590 /* Argus QuickClix has different brightness limits */ 648 /* Argus QuickClix has different brightness limits */
591 gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX); 649 gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX) |
650 (1 << CONTRAST_IDX) |
651 (1 << SAKAR_CS_GAIN_IDX);
592 else 652 else
593 gspca_dev->ctrl_dis = (1 << ARGUS_QC_BRIGHTNESS_IDX); 653 gspca_dev->ctrl_dis = (1 << ARGUS_QC_BRIGHTNESS_IDX) |
654 (1 << CONTRAST_IDX) |
655 (1 << SAKAR_CS_GAIN_IDX);
594 } 656 }
595 657
596 sd->brightness = MR97310A_BRIGHTNESS_DEFAULT; 658 sd->brightness = MR97310A_BRIGHTNESS_DEFAULT;
597 sd->exposure = MR97310A_EXPOSURE_DEFAULT; 659 sd->exposure = MR97310A_EXPOSURE_DEFAULT;
598 sd->gain = MR97310A_GAIN_DEFAULT; 660 sd->gain = gain_default;
661 sd->contrast = MR97310A_CONTRAST_DEFAULT;
599 sd->min_clockdiv = MR97310A_MIN_CLOCKDIV_DEFAULT; 662 sd->min_clockdiv = MR97310A_MIN_CLOCKDIV_DEFAULT;
600 663
601 return 0; 664 return 0;
@@ -697,6 +760,12 @@ static int start_cif_cam(struct gspca_dev *gspca_dev)
697 {0x13, 0x00, {0x01}, 1}, 760 {0x13, 0x00, {0x01}, 1},
698 {0, 0, {0}, 0} 761 {0, 0, {0}, 0}
699 }; 762 };
763 /* Without this command the cam won't work with USB-UHCI */
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;
700 err_code = sensor_write_regs(gspca_dev, cif_sensor1_init_data, 769 err_code = sensor_write_regs(gspca_dev, cif_sensor1_init_data,
701 ARRAY_SIZE(cif_sensor1_init_data)); 770 ARRAY_SIZE(cif_sensor1_init_data));
702 } 771 }
@@ -717,6 +786,10 @@ static int start_vga_cam(struct gspca_dev *gspca_dev)
717 data[5] = 0x00; 786 data[5] = 0x00;
718 data[10] = 0x91; 787 data[10] = 0x91;
719 } 788 }
789 if (sd->sensor_type == 2) {
790 data[5] = 0x00;
791 data[10] = 0x18;
792 }
720 793
721 switch (gspca_dev->width) { 794 switch (gspca_dev->width) {
722 case 160: 795 case 160:
@@ -731,6 +804,10 @@ static int start_vga_cam(struct gspca_dev *gspca_dev)
731 data[4] = 0x78; /* reg 3, V size/4 */ 804 data[4] = 0x78; /* reg 3, V size/4 */
732 data[6] = 0x04; /* reg 5, H start */ 805 data[6] = 0x04; /* reg 5, H start */
733 data[8] = 0x03; /* reg 7, V start */ 806 data[8] = 0x03; /* reg 7, V start */
807 if (sd->sensor_type == 2) {
808 data[6] = 2;
809 data[8] = 1;
810 }
734 if (sd->do_lcd_stop) 811 if (sd->do_lcd_stop)
735 data[8] = 0x04; /* Bayer tile shifted */ 812 data[8] = 0x04; /* Bayer tile shifted */
736 break; 813 break;
@@ -753,7 +830,6 @@ static int start_vga_cam(struct gspca_dev *gspca_dev)
753 return err_code; 830 return err_code;
754 831
755 if (!sd->sensor_type) { 832 if (!sd->sensor_type) {
756 /* The only known sensor_type 0 cam is the Argus DC-1620 */
757 const struct sensor_w_data vga_sensor0_init_data[] = { 833 const struct sensor_w_data vga_sensor0_init_data[] = {
758 {0x01, 0x00, {0x0c, 0x00, 0x04}, 3}, 834 {0x01, 0x00, {0x0c, 0x00, 0x04}, 3},
759 {0x14, 0x00, {0x01, 0xe4, 0x02, 0x84}, 4}, 835 {0x14, 0x00, {0x01, 0xe4, 0x02, 0x84}, 4},
@@ -764,7 +840,7 @@ static int start_vga_cam(struct gspca_dev *gspca_dev)
764 }; 840 };
765 err_code = sensor_write_regs(gspca_dev, vga_sensor0_init_data, 841 err_code = sensor_write_regs(gspca_dev, vga_sensor0_init_data,
766 ARRAY_SIZE(vga_sensor0_init_data)); 842 ARRAY_SIZE(vga_sensor0_init_data));
767 } else { /* sd->sensor_type = 1 */ 843 } else if (sd->sensor_type == 1) {
768 const struct sensor_w_data color_adj[] = { 844 const struct sensor_w_data color_adj[] = {
769 {0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00, 845 {0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00,
770 /* adjusted blue, green, red gain correct 846 /* adjusted blue, green, red gain correct
@@ -802,6 +878,48 @@ static int start_vga_cam(struct gspca_dev *gspca_dev)
802 878
803 err_code = sensor_write_regs(gspca_dev, vga_sensor1_init_data, 879 err_code = sensor_write_regs(gspca_dev, vga_sensor1_init_data,
804 ARRAY_SIZE(vga_sensor1_init_data)); 880 ARRAY_SIZE(vga_sensor1_init_data));
881 } else { /* sensor type == 2 */
882 const struct sensor_w_data vga_sensor2_init_data[] = {
883
884 {0x01, 0x00, {0x48}, 1},
885 {0x02, 0x00, {0x22}, 1},
886 /* Reg 3 msb and 4 is lsb of the exposure setting*/
887 {0x05, 0x00, {0x10}, 1},
888 {0x06, 0x00, {0x00}, 1},
889 {0x07, 0x00, {0x00}, 1},
890 {0x08, 0x00, {0x00}, 1},
891 {0x09, 0x00, {0x00}, 1},
892 /* The following are used in the gain control
893 * which is BTW completely borked in the OEM driver
894 * The values for each color go from 0 to 0x7ff
895 *{0x0a, 0x00, {0x01}, 1}, green1 gain msb
896 *{0x0b, 0x00, {0x10}, 1}, green1 gain lsb
897 *{0x0c, 0x00, {0x01}, 1}, red gain msb
898 *{0x0d, 0x00, {0x10}, 1}, red gain lsb
899 *{0x0e, 0x00, {0x01}, 1}, blue gain msb
900 *{0x0f, 0x00, {0x10}, 1}, blue gain lsb
901 *{0x10, 0x00, {0x01}, 1}, green2 gain msb
902 *{0x11, 0x00, {0x10}, 1}, green2 gain lsb
903 */
904 {0x12, 0x00, {0x00}, 1},
905 {0x13, 0x00, {0x04}, 1}, /* weird effect on colors */
906 {0x14, 0x00, {0x00}, 1},
907 {0x15, 0x00, {0x06}, 1},
908 {0x16, 0x00, {0x01}, 1},
909 {0x17, 0x00, {0xe2}, 1}, /* vertical alignment */
910 {0x18, 0x00, {0x02}, 1},
911 {0x19, 0x00, {0x82}, 1}, /* don't mess with */
912 {0x1a, 0x00, {0x00}, 1},
913 {0x1b, 0x00, {0x20}, 1},
914 /* {0x1c, 0x00, {0x17}, 1}, contrast control */
915 {0x1d, 0x00, {0x80}, 1}, /* moving causes a mess */
916 {0x1e, 0x00, {0x08}, 1}, /* moving jams the camera */
917 {0x1f, 0x00, {0x0c}, 1},
918 {0x20, 0x00, {0x00}, 1},
919 {0, 0, {0}, 0}
920 };
921 err_code = sensor_write_regs(gspca_dev, vga_sensor2_init_data,
922 ARRAY_SIZE(vga_sensor2_init_data));
805 } 923 }
806 return err_code; 924 return err_code;
807} 925}
@@ -834,6 +952,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
834 return err_code; 952 return err_code;
835 953
836 setbrightness(gspca_dev); 954 setbrightness(gspca_dev);
955 setcontrast(gspca_dev);
837 setexposure(gspca_dev); 956 setexposure(gspca_dev);
838 setgain(gspca_dev); 957 setgain(gspca_dev);
839 958
@@ -893,7 +1012,7 @@ static void setbrightness(struct gspca_dev *gspca_dev)
893static void setexposure(struct gspca_dev *gspca_dev) 1012static void setexposure(struct gspca_dev *gspca_dev)
894{ 1013{
895 struct sd *sd = (struct sd *) gspca_dev; 1014 struct sd *sd = (struct sd *) gspca_dev;
896 int exposure; 1015 int exposure = MR97310A_EXPOSURE_DEFAULT;
897 u8 buf[2]; 1016 u8 buf[2];
898 1017
899 if (gspca_dev->ctrl_dis & (1 << EXPOSURE_IDX)) 1018 if (gspca_dev->ctrl_dis & (1 << EXPOSURE_IDX))
@@ -905,6 +1024,11 @@ static void setexposure(struct gspca_dev *gspca_dev)
905 exposure = (sd->exposure * 9267) / 10000 + 300; 1024 exposure = (sd->exposure * 9267) / 10000 + 300;
906 sensor_write1(gspca_dev, 3, exposure >> 4); 1025 sensor_write1(gspca_dev, 3, exposure >> 4);
907 sensor_write1(gspca_dev, 4, exposure & 0x0f); 1026 sensor_write1(gspca_dev, 4, exposure & 0x0f);
1027 } else if (sd->sensor_type == 2) {
1028 exposure = sd->exposure;
1029 exposure >>= 3;
1030 sensor_write1(gspca_dev, 3, exposure >> 8);
1031 sensor_write1(gspca_dev, 4, exposure & 0xff);
908 } else { 1032 } else {
909 /* We have both a clock divider and an exposure register. 1033 /* We have both a clock divider and an exposure register.
910 We first calculate the clock divider, as that determines 1034 We first calculate the clock divider, as that determines
@@ -943,17 +1067,34 @@ static void setexposure(struct gspca_dev *gspca_dev)
943static void setgain(struct gspca_dev *gspca_dev) 1067static void setgain(struct gspca_dev *gspca_dev)
944{ 1068{
945 struct sd *sd = (struct sd *) gspca_dev; 1069 struct sd *sd = (struct sd *) gspca_dev;
1070 u8 gainreg;
946 1071
947 if (gspca_dev->ctrl_dis & (1 << GAIN_IDX)) 1072 if ((gspca_dev->ctrl_dis & (1 << GAIN_IDX)) &&
1073 (gspca_dev->ctrl_dis & (1 << SAKAR_CS_GAIN_IDX)))
948 return; 1074 return;
949 1075
950 if (sd->cam_type == CAM_TYPE_CIF && sd->sensor_type == 1) { 1076 if (sd->cam_type == CAM_TYPE_CIF && sd->sensor_type == 1)
951 sensor_write1(gspca_dev, 0x0e, sd->gain); 1077 sensor_write1(gspca_dev, 0x0e, sd->gain);
952 } else { 1078 else if (sd->cam_type == CAM_TYPE_VGA && sd->sensor_type == 2)
1079 for (gainreg = 0x0a; gainreg < 0x11; gainreg += 2) {
1080 sensor_write1(gspca_dev, gainreg, sd->gain >> 8);
1081 sensor_write1(gspca_dev, gainreg + 1, sd->gain & 0xff);
1082 }
1083 else
953 sensor_write1(gspca_dev, 0x10, sd->gain); 1084 sensor_write1(gspca_dev, 0x10, sd->gain);
954 }
955} 1085}
956 1086
1087static void setcontrast(struct gspca_dev *gspca_dev)
1088{
1089 struct sd *sd = (struct sd *) gspca_dev;
1090
1091 if (gspca_dev->ctrl_dis & (1 << CONTRAST_IDX))
1092 return;
1093
1094 sensor_write1(gspca_dev, 0x1c, sd->contrast);
1095}
1096
1097
957static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 1098static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
958{ 1099{
959 struct sd *sd = (struct sd *) gspca_dev; 1100 struct sd *sd = (struct sd *) gspca_dev;
@@ -1008,6 +1149,25 @@ static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
1008 return 0; 1149 return 0;
1009} 1150}
1010 1151
1152static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1153{
1154 struct sd *sd = (struct sd *) gspca_dev;
1155
1156 sd->contrast = val;
1157 if (gspca_dev->streaming)
1158 setcontrast(gspca_dev);
1159 return 0;
1160}
1161
1162
1163static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1164{
1165 struct sd *sd = (struct sd *) gspca_dev;
1166
1167 *val = sd->contrast;
1168 return 0;
1169}
1170
1011static int sd_setmin_clockdiv(struct gspca_dev *gspca_dev, __s32 val) 1171static int sd_setmin_clockdiv(struct gspca_dev *gspca_dev, __s32 val)
1012{ 1172{
1013 struct sd *sd = (struct sd *) gspca_dev; 1173 struct sd *sd = (struct sd *) gspca_dev;