diff options
author | Hans de Goede <hdegoede@redhat.com> | 2009-08-14 16:11:36 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-09-12 11:19:58 -0400 |
commit | a2e081b64ed5ea344bdfe6115059c08f3d0b26f6 (patch) | |
tree | 8b929a91d41d636caf388e939e1808126d43015d /drivers/media/video | |
parent | 5494378911df767d408df28524a19a1617154ea3 (diff) |
V4L/DVB (12623): gspca_mr97310a: Add controls for CIF type 0 sensor cams
gspca_mr97310a: Add controls for CIF type 0 sensor cams
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video')
-rw-r--r-- | drivers/media/video/gspca/mr97310a.c | 56 |
1 files changed, 47 insertions, 9 deletions
diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/video/gspca/mr97310a.c index 7540ea94e1a9..1ee3d1ee5a40 100644 --- a/drivers/media/video/gspca/mr97310a.c +++ b/drivers/media/video/gspca/mr97310a.c | |||
@@ -220,7 +220,8 @@ static int sensor_write_regs(struct gspca_dev *gspca_dev, | |||
220 | 220 | ||
221 | static int sensor_write1(struct gspca_dev *gspca_dev, u8 reg, u8 data) | 221 | static int sensor_write1(struct gspca_dev *gspca_dev, u8 reg, u8 data) |
222 | { | 222 | { |
223 | u8 buf; | 223 | struct sd *sd = (struct sd *) gspca_dev; |
224 | u8 buf, confirm_reg; | ||
224 | int rc; | 225 | int rc; |
225 | 226 | ||
226 | buf = data; | 227 | buf = data; |
@@ -229,7 +230,8 @@ static int sensor_write1(struct gspca_dev *gspca_dev, u8 reg, u8 data) | |||
229 | return rc; | 230 | return rc; |
230 | 231 | ||
231 | buf = 0x01; | 232 | buf = 0x01; |
232 | rc = sensor_write_reg(gspca_dev, 0x13, 0x00, &buf, 1); | 233 | confirm_reg = sd->sensor_type ? 0x13 : 0x11; |
234 | rc = sensor_write_reg(gspca_dev, confirm_reg, 0x00, &buf, 1); | ||
233 | if (rc < 0) | 235 | if (rc < 0) |
234 | return rc; | 236 | return rc; |
235 | 237 | ||
@@ -400,8 +402,7 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
400 | sd->sensor_type); | 402 | sd->sensor_type); |
401 | 403 | ||
402 | if (sd->sensor_type == 0) | 404 | if (sd->sensor_type == 0) |
403 | gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX) | | 405 | gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX); |
404 | (1 << EXPOSURE_IDX) | (1 << GAIN_IDX); | ||
405 | } else { | 406 | } else { |
406 | sd->cam_type = CAM_TYPE_VGA; | 407 | sd->cam_type = CAM_TYPE_VGA; |
407 | PDEBUG(D_PROBE, "MR97310A VGA camera detected"); | 408 | PDEBUG(D_PROBE, "MR97310A VGA camera detected"); |
@@ -767,10 +768,43 @@ static void setexposure(struct gspca_dev *gspca_dev) | |||
767 | if (gspca_dev->ctrl_dis & (1 << EXPOSURE_IDX)) | 768 | if (gspca_dev->ctrl_dis & (1 << EXPOSURE_IDX)) |
768 | return; | 769 | return; |
769 | 770 | ||
770 | val = sd->exposure >> 4; | 771 | if (sd->sensor_type) { |
771 | sensor_write1(gspca_dev, 3, val); | 772 | val = sd->exposure >> 4; |
772 | val = sd->exposure & 0xf; | 773 | sensor_write1(gspca_dev, 3, val); |
773 | sensor_write1(gspca_dev, 4, val); | 774 | val = sd->exposure & 0xf; |
775 | sensor_write1(gspca_dev, 4, val); | ||
776 | } else { | ||
777 | u8 clockdiv; | ||
778 | int exposure; | ||
779 | |||
780 | /* We have both a clock divider and an exposure register. | ||
781 | We first calculate the clock divider, as that determines | ||
782 | the maximum exposure and then we calculayte the exposure | ||
783 | register setting (which goes from 0 - 511). | ||
784 | |||
785 | Note our 0 - 4095 exposure is mapped to 0 - 511 | ||
786 | milliseconds exposure time */ | ||
787 | clockdiv = (60 * sd->exposure + 7999) / 8000; | ||
788 | |||
789 | /* Limit framerate to not exceed usb bandwidth */ | ||
790 | if (clockdiv < 3 && gspca_dev->width >= 320) | ||
791 | clockdiv = 3; | ||
792 | else if (clockdiv < 2) | ||
793 | clockdiv = 2; | ||
794 | |||
795 | /* Frame exposure time in ms = 1000 * clockdiv / 60 -> | ||
796 | exposure = (sd->exposure / 8) * 511 / (1000 * clockdiv / 60) */ | ||
797 | exposure = (60 * 511 * sd->exposure) / (8000 * clockdiv); | ||
798 | if (exposure > 511) | ||
799 | exposure = 511; | ||
800 | |||
801 | /* exposure register value is reversed! */ | ||
802 | exposure = 511 - exposure; | ||
803 | |||
804 | sensor_write1(gspca_dev, 0x02, clockdiv); | ||
805 | sensor_write1(gspca_dev, 0x0e, exposure & 0xff); | ||
806 | sensor_write1(gspca_dev, 0x0f, exposure >> 8); | ||
807 | } | ||
774 | } | 808 | } |
775 | 809 | ||
776 | static void setgain(struct gspca_dev *gspca_dev) | 810 | static void setgain(struct gspca_dev *gspca_dev) |
@@ -780,7 +814,11 @@ static void setgain(struct gspca_dev *gspca_dev) | |||
780 | if (gspca_dev->ctrl_dis & (1 << GAIN_IDX)) | 814 | if (gspca_dev->ctrl_dis & (1 << GAIN_IDX)) |
781 | return; | 815 | return; |
782 | 816 | ||
783 | sensor_write1(gspca_dev, 3, sd->gain); | 817 | if (sd->sensor_type) { |
818 | sensor_write1(gspca_dev, 3, sd->gain); | ||
819 | } else { | ||
820 | sensor_write1(gspca_dev, 0x10, sd->gain); | ||
821 | } | ||
784 | } | 822 | } |
785 | 823 | ||
786 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | 824 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) |