aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2012-05-06 08:28:25 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-05-14 08:34:56 -0400
commit55db765c54cd9506524c2945e3905fcf9215ea71 (patch)
treea3ea42e5377da4c26a364d1d84174f3b6dca6ecf
parent83fb2e2eaae5a3b4b3503f1e305451ed9d1a3761 (diff)
[media] gspca_zc3xx: Always automatically adjust BRC as needed
Always automatically adjust the Bit Rate Control setting as needed, independent of the sensor type. BRC is needed to not run out of bandwidth with higher quality settings independent of the sensor. Also only automatically adjust BRC, and don't adjust the JPEG quality control automatically, as that is not needed and leads to ugly flashes when it is changed. Note that before this patch-set the quality was never changed either due to the bugs in the quality handling fixed in previous patches in this set. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/video/gspca/zc3xx.c159
1 files changed, 53 insertions, 106 deletions
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c
index 3c6db02fe74b..54735dd61bb8 100644
--- a/drivers/media/video/gspca/zc3xx.c
+++ b/drivers/media/video/gspca/zc3xx.c
@@ -5921,22 +5921,8 @@ static void setexposure(struct gspca_dev *gspca_dev)
5921static void setquality(struct gspca_dev *gspca_dev) 5921static void setquality(struct gspca_dev *gspca_dev)
5922{ 5922{
5923 struct sd *sd = (struct sd *) gspca_dev; 5923 struct sd *sd = (struct sd *) gspca_dev;
5924 s8 reg07;
5925
5926 jpeg_set_qual(sd->jpeg_hdr, jpeg_qual[sd->reg08 >> 1]); 5924 jpeg_set_qual(sd->jpeg_hdr, jpeg_qual[sd->reg08 >> 1]);
5927
5928 reg07 = 0;
5929 switch (sd->sensor) {
5930 case SENSOR_OV7620:
5931 reg07 = 0x30;
5932 break;
5933 case SENSOR_HV7131R:
5934 case SENSOR_PAS202B:
5935 return; /* done by work queue */
5936 }
5937 reg_w(gspca_dev, sd->reg08, ZC3XX_R008_CLOCKSETTING); 5925 reg_w(gspca_dev, sd->reg08, ZC3XX_R008_CLOCKSETTING);
5938 if (reg07 != 0)
5939 reg_w(gspca_dev, reg07, 0x0007);
5940} 5926}
5941 5927
5942/* Matches the sensor's internal frame rate to the lighting frequency. 5928/* Matches the sensor's internal frame rate to the lighting frequency.
@@ -6070,110 +6056,63 @@ static void setautogain(struct gspca_dev *gspca_dev)
6070 reg_w(gspca_dev, autoval, 0x0180); 6056 reg_w(gspca_dev, autoval, 0x0180);
6071} 6057}
6072 6058
6073/* update the transfer parameters */ 6059/*
6074/* This function is executed from a work queue. */ 6060 * Update the transfer parameters.
6075/* The exact use of the bridge registers 07 and 08 is not known. 6061 * This function is executed from a work queue.
6076 * The following algorithm has been adapted from ms-win traces */ 6062 */
6077static void transfer_update(struct work_struct *work) 6063static void transfer_update(struct work_struct *work)
6078{ 6064{
6079 struct sd *sd = container_of(work, struct sd, work); 6065 struct sd *sd = container_of(work, struct sd, work);
6080 struct gspca_dev *gspca_dev = &sd->gspca_dev; 6066 struct gspca_dev *gspca_dev = &sd->gspca_dev;
6081 int change, good; 6067 int change, good;
6082 u8 reg07, qual, reg11; 6068 u8 reg07, reg11;
6083 6069
6084 /* synchronize with the main driver and initialize the registers */ 6070 /* reg07 gets set to 0 by sd_start before starting us */
6085 mutex_lock(&gspca_dev->usb_lock); 6071 reg07 = 0;
6086 reg07 = 0; /* max */
6087 qual = sd->reg08 >> 1;
6088 reg_w(gspca_dev, reg07, 0x0007);
6089 reg_w(gspca_dev, sd->reg08, ZC3XX_R008_CLOCKSETTING);
6090 mutex_unlock(&gspca_dev->usb_lock);
6091 6072
6092 good = 0; 6073 good = 0;
6093 for (;;) { 6074 for (;;) {
6094 msleep(100); 6075 msleep(100);
6095 6076
6096 /* get the transfer status */
6097 /* the bit 0 of the bridge register 11 indicates overflow */
6098 mutex_lock(&gspca_dev->usb_lock); 6077 mutex_lock(&gspca_dev->usb_lock);
6099 if (gspca_dev->frozen || !gspca_dev->dev || 6078 if (gspca_dev->frozen || !gspca_dev->dev ||
6100 !gspca_dev->streaming) 6079 !gspca_dev->streaming)
6101 goto err; 6080 goto err;
6081
6082 /* Bit 0 of register 11 indicates FIFO overflow */
6083 gspca_dev->usb_err = 0;
6102 reg11 = reg_r(gspca_dev, 0x0011); 6084 reg11 = reg_r(gspca_dev, 0x0011);
6103 if (gspca_dev->usb_err < 0 6085 if (gspca_dev->usb_err)
6104 || !gspca_dev->present || !gspca_dev->streaming)
6105 goto err; 6086 goto err;
6106 6087
6107 change = reg11 & 0x01; 6088 change = reg11 & 0x01;
6108 if (change) { /* overflow */ 6089 if (change) { /* overflow */
6109 switch (reg07) {
6110 case 0: /* max */
6111 reg07 = sd->sensor == SENSOR_HV7131R
6112 ? 0x30 : 0x32;
6113 if (qual != 0) {
6114 change = 3;
6115 qual--;
6116 }
6117 break;
6118 case 0x32:
6119 reg07 -= 4;
6120 break;
6121 default:
6122 reg07 -= 2;
6123 break;
6124 case 2:
6125 change = 0; /* already min */
6126 break;
6127 }
6128 good = 0; 6090 good = 0;
6091
6092 if (reg07 == 0) /* Bit Rate Control not enabled? */
6093 reg07 = 0x32; /* Allow 98 bytes / unit */
6094 else if (reg07 > 2)
6095 reg07 -= 2; /* Decrease allowed bytes / unit */
6096 else
6097 change = 0;
6129 } else { /* no overflow */ 6098 } else { /* no overflow */
6130 if (reg07 != 0) { /* if not max */ 6099 good++;
6131 good++; 6100 if (good >= 10) {
6132 if (good >= 10) { 6101 good = 0;
6133 good = 0; 6102 if (reg07) { /* BRC enabled? */
6134 change = 1; 6103 change = 1;
6135 reg07 += 2; 6104 if (reg07 < 0x32)
6136 switch (reg07) { 6105 reg07 += 2;
6137 case 0x30: 6106 else
6138 if (sd->sensor == SENSOR_PAS202B)
6139 reg07 += 2;
6140 break;
6141 case 0x32:
6142 case 0x34:
6143 reg07 = 0; 6107 reg07 = 0;
6144 break;
6145 }
6146 }
6147 } else { /* reg07 max */
6148 if (qual < sizeof jpeg_qual - 1) {
6149 good++;
6150 if (good > 10) {
6151 qual++;
6152 change = 2;
6153 }
6154 } 6108 }
6155 } 6109 }
6156 } 6110 }
6157 if (change) { 6111 if (change) {
6158 if (change & 1) { 6112 gspca_dev->usb_err = 0;
6159 reg_w(gspca_dev, reg07, 0x0007); 6113 reg_w(gspca_dev, reg07, 0x0007);
6160 if (gspca_dev->usb_err < 0 6114 if (gspca_dev->usb_err)
6161 || !gspca_dev->present 6115 goto err;
6162 || !gspca_dev->streaming)
6163 goto err;
6164 }
6165 if (change & 2) {
6166 sd->reg08 = (qual << 1) | 1;
6167 reg_w(gspca_dev, sd->reg08,
6168 ZC3XX_R008_CLOCKSETTING);
6169 if (gspca_dev->usb_err < 0
6170 || !gspca_dev->present
6171 || !gspca_dev->streaming)
6172 goto err;
6173 sd->ctrls[QUALITY].val = jpeg_qual[qual];
6174 jpeg_set_qual(sd->jpeg_hdr,
6175 jpeg_qual[qual]);
6176 }
6177 } 6116 }
6178 mutex_unlock(&gspca_dev->usb_lock); 6117 mutex_unlock(&gspca_dev->usb_lock);
6179 } 6118 }
@@ -6721,14 +6660,10 @@ static int sd_init(struct gspca_dev *gspca_dev)
6721 6660
6722 switch (sd->sensor) { 6661 switch (sd->sensor) {
6723 case SENSOR_HV7131R: 6662 case SENSOR_HV7131R:
6724 gspca_dev->ctrl_dis = (1 << QUALITY);
6725 break; 6663 break;
6726 case SENSOR_OV7630C: 6664 case SENSOR_OV7630C:
6727 gspca_dev->ctrl_dis = (1 << LIGHTFREQ) | (1 << EXPOSURE); 6665 gspca_dev->ctrl_dis = (1 << LIGHTFREQ) | (1 << EXPOSURE);
6728 break; 6666 break;
6729 case SENSOR_PAS202B:
6730 gspca_dev->ctrl_dis = (1 << QUALITY) | (1 << EXPOSURE);
6731 break;
6732 default: 6667 default:
6733 gspca_dev->ctrl_dis = (1 << EXPOSURE); 6668 gspca_dev->ctrl_dis = (1 << EXPOSURE);
6734 break; 6669 break;
@@ -6743,6 +6678,13 @@ static int sd_init(struct gspca_dev *gspca_dev)
6743 return gspca_dev->usb_err; 6678 return gspca_dev->usb_err;
6744} 6679}
6745 6680
6681static int sd_pre_start(struct gspca_dev *gspca_dev)
6682{
6683 struct sd *sd = (struct sd *) gspca_dev;
6684 gspca_dev->cam.needs_full_bandwidth = (sd->reg08 >= 4) ? 1 : 0;
6685 return 0;
6686}
6687
6746static int sd_start(struct gspca_dev *gspca_dev) 6688static int sd_start(struct gspca_dev *gspca_dev)
6747{ 6689{
6748 struct sd *sd = (struct sd *) gspca_dev; 6690 struct sd *sd = (struct sd *) gspca_dev;
@@ -6868,6 +6810,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
6868 break; 6810 break;
6869 } 6811 }
6870 setquality(gspca_dev); 6812 setquality(gspca_dev);
6813 /* Start with BRC disabled, transfer_update will enable it if needed */
6814 reg_w(gspca_dev, 0x00, 0x0007);
6871 setlightfreq(gspca_dev); 6815 setlightfreq(gspca_dev);
6872 6816
6873 switch (sd->sensor) { 6817 switch (sd->sensor) {
@@ -6905,19 +6849,14 @@ static int sd_start(struct gspca_dev *gspca_dev)
6905 6849
6906 setautogain(gspca_dev); 6850 setautogain(gspca_dev);
6907 6851
6908 /* start the transfer update thread if needed */ 6852 if (gspca_dev->usb_err < 0)
6909 if (gspca_dev->usb_err >= 0) { 6853 return gspca_dev->usb_err;
6910 switch (sd->sensor) {
6911 case SENSOR_HV7131R:
6912 case SENSOR_PAS202B:
6913 sd->work_thread =
6914 create_singlethread_workqueue(KBUILD_MODNAME);
6915 queue_work(sd->work_thread, &sd->work);
6916 break;
6917 }
6918 }
6919 6854
6920 return gspca_dev->usb_err; 6855 /* Start the transfer parameters update thread */
6856 sd->work_thread = create_singlethread_workqueue(KBUILD_MODNAME);
6857 queue_work(sd->work_thread, &sd->work);
6858
6859 return 0;
6921} 6860}
6922 6861
6923/* called on streamoff with alt 0 and on disconnect */ 6862/* called on streamoff with alt 0 and on disconnect */
@@ -7020,8 +6959,15 @@ static int sd_setquality(struct gspca_dev *gspca_dev, __s32 val)
7020 && i == qual 6959 && i == qual
7021 && val < jpeg_qual[i]) 6960 && val < jpeg_qual[i])
7022 i--; 6961 i--;
6962
6963 /* With high quality settings we need max bandwidth */
6964 if (i >= 2 && gspca_dev->streaming &&
6965 !gspca_dev->cam.needs_full_bandwidth)
6966 return -EBUSY;
6967
7023 sd->reg08 = (i << 1) | 1; 6968 sd->reg08 = (i << 1) | 1;
7024 sd->ctrls[QUALITY].val = jpeg_qual[i]; 6969 sd->ctrls[QUALITY].val = jpeg_qual[i];
6970
7025 if (gspca_dev->streaming) 6971 if (gspca_dev->streaming)
7026 setquality(gspca_dev); 6972 setquality(gspca_dev);
7027 return gspca_dev->usb_err; 6973 return gspca_dev->usb_err;
@@ -7071,6 +7017,7 @@ static const struct sd_desc sd_desc = {
7071 .nctrls = ARRAY_SIZE(sd_ctrls), 7017 .nctrls = ARRAY_SIZE(sd_ctrls),
7072 .config = sd_config, 7018 .config = sd_config,
7073 .init = sd_init, 7019 .init = sd_init,
7020 .isoc_init = sd_pre_start,
7074 .start = sd_start, 7021 .start = sd_start,
7075 .stop0 = sd_stop0, 7022 .stop0 = sd_stop0,
7076 .pkt_scan = sd_pkt_scan, 7023 .pkt_scan = sd_pkt_scan,