aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorTheodore Kilgore <kilgota@banach.math.auburn.edu>2010-02-09 16:05:25 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-02-26 13:11:09 -0500
commit9d3103d061224e939272d05d54192038f66ffd54 (patch)
treee8e62612089e374cf3f3b4e7d94cddb573e09336 /drivers
parent10bb7530108cc11fedd0d615467a54f341079778 (diff)
V4L/DVB: gspca_mr97310a: add support for the Sakar 1638x CyberPix
This camera has a sensor type we did not support sofar, this patch adds support for the new sensor type found in the Sakar 1638x CyberPix. Signed-off-by: Theodore Kilgore <kilgota@banach.math.auburn.edu> Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/video/gspca/mr97310a.c197
1 files changed, 177 insertions, 20 deletions
diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/video/gspca/mr97310a.c
index 959ea2a530a4..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 const 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 const 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,
@@ -436,6 +479,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
436{ 479{
437 struct sd *sd = (struct sd *) gspca_dev; 480 struct sd *sd = (struct sd *) gspca_dev;
438 struct cam *cam; 481 struct cam *cam;
482 int gain_default = MR97310A_GAIN_DEFAULT;
439 int err_code; 483 int err_code;
440 484
441 cam = &gspca_dev->cam; 485 cam = &gspca_dev->cam;
@@ -479,7 +523,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
479 * 523 *
480 * Name sd->sensor_type reported by 524 * Name sd->sensor_type reported by
481 * 525 *
482 * Sakar Spy-shot 0 T. Kilgore 526 * Sakar 56379 Spy-shot 0 T. Kilgore
483 * Innovage 0 T. Kilgore 527 * Innovage 0 T. Kilgore
484 * Vivitar Mini 0 H. De Goede 528 * Vivitar Mini 0 H. De Goede
485 * Vivitar Mini 0 E. Rodriguez 529 * Vivitar Mini 0 E. Rodriguez
@@ -507,14 +551,17 @@ static int sd_config(struct gspca_dev *gspca_dev,
507 551
508 /* 552 /*
509 * Here is a table of the responses to the query for sensor 553 * Here is a table of the responses to the query for sensor
510 * type, 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.
511 * 556 *
512 * Name gspca_dev->usb_buf[] sd->sensor_type 557 * Name gspca_dev->usb_buf[] sd->sensor_type
513 * sd->do_lcd_stop 558 * sd->do_lcd_stop
514 * Aiptek Pencam VGA+ 0300 0 1 559 * Aiptek Pencam VGA+ 0300 0 1
515 * ION digital 0350 0 1 560 * ION digital 0300 0 1
516 * Argus DC-1620 0450 1 0 561 * Argus DC-1620 0450 1 0
517 * 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
518 * 565 *
519 * Based upon these results, we assume default settings 566 * Based upon these results, we assume default settings
520 * and then correct as necessary, as follows. 567 * and then correct as necessary, as follows.
@@ -524,10 +571,12 @@ static int sd_config(struct gspca_dev *gspca_dev,
524 sd->sensor_type = 1; 571 sd->sensor_type = 1;
525 sd->do_lcd_stop = 0; 572 sd->do_lcd_stop = 0;
526 sd->adj_colors = 0; 573 sd->adj_colors = 0;
527 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) &&
528 (gspca_dev->usb_buf[0] != 0x04)) { 577 (gspca_dev->usb_buf[0] != 0x04)) {
529 PDEBUG(D_ERR, "Unknown VGA Sensor id Byte 0: %02x", 578 PDEBUG(D_ERR, "Unknown VGA Sensor id Byte 0: %02x",
530 gspca_dev->usb_buf[1]); 579 gspca_dev->usb_buf[0]);
531 PDEBUG(D_ERR, "Defaults assumed, may not work"); 580 PDEBUG(D_ERR, "Defaults assumed, may not work");
532 PDEBUG(D_ERR, "Please report this"); 581 PDEBUG(D_ERR, "Please report this");
533 } 582 }
@@ -571,9 +620,13 @@ static int sd_config(struct gspca_dev *gspca_dev,
571 /* No brightness for sensor_type 0 */ 620 /* No brightness for sensor_type 0 */
572 if (sd->sensor_type == 0) 621 if (sd->sensor_type == 0)
573 gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX) | 622 gspca_dev->ctrl_dis = (1 << NORM_BRIGHTNESS_IDX) |
574 (1 << ARGUS_QC_BRIGHTNESS_IDX); 623 (1 << ARGUS_QC_BRIGHTNESS_IDX) |
624 (1 << CONTRAST_IDX) |
625 (1 << SAKAR_CS_GAIN_IDX);
575 else 626 else
576 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) |
577 (1 << MIN_CLOCKDIV_IDX); 630 (1 << MIN_CLOCKDIV_IDX);
578 } else { 631 } else {
579 /* 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 */
@@ -582,17 +635,30 @@ static int sd_config(struct gspca_dev *gspca_dev,
582 (1 << ARGUS_QC_BRIGHTNESS_IDX) | 635 (1 << ARGUS_QC_BRIGHTNESS_IDX) |
583 (1 << EXPOSURE_IDX) | 636 (1 << EXPOSURE_IDX) |
584 (1 << GAIN_IDX) | 637 (1 << GAIN_IDX) |
638 (1 << CONTRAST_IDX) |
639 (1 << SAKAR_CS_GAIN_IDX) |
585 (1 << MIN_CLOCKDIV_IDX); 640 (1 << MIN_CLOCKDIV_IDX);
586 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)
587 /* Argus QuickClix has different brightness limits */ 648 /* Argus QuickClix has different brightness limits */
588 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);
589 else 652 else
590 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);
591 } 656 }
592 657
593 sd->brightness = MR97310A_BRIGHTNESS_DEFAULT; 658 sd->brightness = MR97310A_BRIGHTNESS_DEFAULT;
594 sd->exposure = MR97310A_EXPOSURE_DEFAULT; 659 sd->exposure = MR97310A_EXPOSURE_DEFAULT;
595 sd->gain = MR97310A_GAIN_DEFAULT; 660 sd->gain = gain_default;
661 sd->contrast = MR97310A_CONTRAST_DEFAULT;
596 sd->min_clockdiv = MR97310A_MIN_CLOCKDIV_DEFAULT; 662 sd->min_clockdiv = MR97310A_MIN_CLOCKDIV_DEFAULT;
597 663
598 return 0; 664 return 0;
@@ -720,6 +786,10 @@ static int start_vga_cam(struct gspca_dev *gspca_dev)
720 data[5] = 0x00; 786 data[5] = 0x00;
721 data[10] = 0x91; 787 data[10] = 0x91;
722 } 788 }
789 if (sd->sensor_type == 2) {
790 data[5] = 0x00;
791 data[10] = 0x18;
792 }
723 793
724 switch (gspca_dev->width) { 794 switch (gspca_dev->width) {
725 case 160: 795 case 160:
@@ -734,6 +804,10 @@ static int start_vga_cam(struct gspca_dev *gspca_dev)
734 data[4] = 0x78; /* reg 3, V size/4 */ 804 data[4] = 0x78; /* reg 3, V size/4 */
735 data[6] = 0x04; /* reg 5, H start */ 805 data[6] = 0x04; /* reg 5, H start */
736 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 }
737 if (sd->do_lcd_stop) 811 if (sd->do_lcd_stop)
738 data[8] = 0x04; /* Bayer tile shifted */ 812 data[8] = 0x04; /* Bayer tile shifted */
739 break; 813 break;
@@ -756,7 +830,6 @@ static int start_vga_cam(struct gspca_dev *gspca_dev)
756 return err_code; 830 return err_code;
757 831
758 if (!sd->sensor_type) { 832 if (!sd->sensor_type) {
759 /* The only known sensor_type 0 cam is the Argus DC-1620 */
760 const struct sensor_w_data vga_sensor0_init_data[] = { 833 const struct sensor_w_data vga_sensor0_init_data[] = {
761 {0x01, 0x00, {0x0c, 0x00, 0x04}, 3}, 834 {0x01, 0x00, {0x0c, 0x00, 0x04}, 3},
762 {0x14, 0x00, {0x01, 0xe4, 0x02, 0x84}, 4}, 835 {0x14, 0x00, {0x01, 0xe4, 0x02, 0x84}, 4},
@@ -767,7 +840,7 @@ static int start_vga_cam(struct gspca_dev *gspca_dev)
767 }; 840 };
768 err_code = sensor_write_regs(gspca_dev, vga_sensor0_init_data, 841 err_code = sensor_write_regs(gspca_dev, vga_sensor0_init_data,
769 ARRAY_SIZE(vga_sensor0_init_data)); 842 ARRAY_SIZE(vga_sensor0_init_data));
770 } else { /* sd->sensor_type = 1 */ 843 } else if (sd->sensor_type == 1) {
771 const struct sensor_w_data color_adj[] = { 844 const struct sensor_w_data color_adj[] = {
772 {0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00, 845 {0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00,
773 /* adjusted blue, green, red gain correct 846 /* adjusted blue, green, red gain correct
@@ -805,6 +878,48 @@ static int start_vga_cam(struct gspca_dev *gspca_dev)
805 878
806 err_code = sensor_write_regs(gspca_dev, vga_sensor1_init_data, 879 err_code = sensor_write_regs(gspca_dev, vga_sensor1_init_data,
807 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));
808 } 923 }
809 return err_code; 924 return err_code;
810} 925}
@@ -837,6 +952,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
837 return err_code; 952 return err_code;
838 953
839 setbrightness(gspca_dev); 954 setbrightness(gspca_dev);
955 setcontrast(gspca_dev);
840 setexposure(gspca_dev); 956 setexposure(gspca_dev);
841 setgain(gspca_dev); 957 setgain(gspca_dev);
842 958
@@ -896,7 +1012,7 @@ static void setbrightness(struct gspca_dev *gspca_dev)
896static void setexposure(struct gspca_dev *gspca_dev) 1012static void setexposure(struct gspca_dev *gspca_dev)
897{ 1013{
898 struct sd *sd = (struct sd *) gspca_dev; 1014 struct sd *sd = (struct sd *) gspca_dev;
899 int exposure; 1015 int exposure = MR97310A_EXPOSURE_DEFAULT;
900 u8 buf[2]; 1016 u8 buf[2];
901 1017
902 if (gspca_dev->ctrl_dis & (1 << EXPOSURE_IDX)) 1018 if (gspca_dev->ctrl_dis & (1 << EXPOSURE_IDX))
@@ -908,6 +1024,11 @@ static void setexposure(struct gspca_dev *gspca_dev)
908 exposure = (sd->exposure * 9267) / 10000 + 300; 1024 exposure = (sd->exposure * 9267) / 10000 + 300;
909 sensor_write1(gspca_dev, 3, exposure >> 4); 1025 sensor_write1(gspca_dev, 3, exposure >> 4);
910 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);
911 } else { 1032 } else {
912 /* We have both a clock divider and an exposure register. 1033 /* We have both a clock divider and an exposure register.
913 We first calculate the clock divider, as that determines 1034 We first calculate the clock divider, as that determines
@@ -946,17 +1067,34 @@ static void setexposure(struct gspca_dev *gspca_dev)
946static void setgain(struct gspca_dev *gspca_dev) 1067static void setgain(struct gspca_dev *gspca_dev)
947{ 1068{
948 struct sd *sd = (struct sd *) gspca_dev; 1069 struct sd *sd = (struct sd *) gspca_dev;
1070 u8 gainreg;
949 1071
950 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)))
951 return; 1074 return;
952 1075
953 if (sd->cam_type == CAM_TYPE_CIF && sd->sensor_type == 1) { 1076 if (sd->cam_type == CAM_TYPE_CIF && sd->sensor_type == 1)
954 sensor_write1(gspca_dev, 0x0e, sd->gain); 1077 sensor_write1(gspca_dev, 0x0e, sd->gain);
955 } 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
956 sensor_write1(gspca_dev, 0x10, sd->gain); 1084 sensor_write1(gspca_dev, 0x10, sd->gain);
957 }
958} 1085}
959 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
960static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 1098static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
961{ 1099{
962 struct sd *sd = (struct sd *) gspca_dev; 1100 struct sd *sd = (struct sd *) gspca_dev;
@@ -1011,6 +1149,25 @@ static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
1011 return 0; 1149 return 0;
1012} 1150}
1013 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
1014static int sd_setmin_clockdiv(struct gspca_dev *gspca_dev, __s32 val) 1171static int sd_setmin_clockdiv(struct gspca_dev *gspca_dev, __s32 val)
1015{ 1172{
1016 struct sd *sd = (struct sd *) gspca_dev; 1173 struct sd *sd = (struct sd *) gspca_dev;