aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca/zc3xx.c
diff options
context:
space:
mode:
authorJean-François Moine <moinejf@free.fr>2012-02-27 05:26:30 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-03-08 06:01:48 -0500
commit30c73d464a10bee4bb8375bb2ed8cc102c507bb7 (patch)
tree19c33cca5ad9d71113e71f81aa6c2f5d53d2f654 /drivers/media/video/gspca/zc3xx.c
parenta7705c093d9174a35eb54289368cd1f28f59bd13 (diff)
[media] gspca - zc3xx: Adjust the JPEG decompression tables
As the bridge register 08 defines the JPEG compression quality, it must be changed on JPEG quality change and also, the decompression tables must be adjusted when the register varies. [mchehab@redhat.com: replace a // comment by a /* */ one] Signed-off-by: Jean-François Moine <moinejf@free.fr> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/gspca/zc3xx.c')
-rw-r--r--drivers/media/video/gspca/zc3xx.c97
1 files changed, 50 insertions, 47 deletions
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c
index b9e15bb0328b..c02fb31987cc 100644
--- a/drivers/media/video/gspca/zc3xx.c
+++ b/drivers/media/video/gspca/zc3xx.c
@@ -34,7 +34,7 @@ MODULE_LICENSE("GPL");
34 34
35static int force_sensor = -1; 35static int force_sensor = -1;
36 36
37#define QUANT_VAL 1 /* quantization table */ 37#define REG08_DEF 3 /* default JPEG compression (70%) */
38#include "zc3xx-reg.h" 38#include "zc3xx-reg.h"
39 39
40/* controls */ 40/* controls */
@@ -57,10 +57,7 @@ struct sd {
57 57
58 struct gspca_ctrl ctrls[NCTRLS]; 58 struct gspca_ctrl ctrls[NCTRLS];
59 59
60 u8 quality; /* image quality */ 60 u8 reg08; /* webcam compression quality */
61#define QUALITY_MIN 50
62#define QUALITY_MAX 80
63#define QUALITY_DEF 70
64 61
65 u8 bridge; 62 u8 bridge;
66 u8 sensor; /* Type of image sensor chip */ 63 u8 sensor; /* Type of image sensor chip */
@@ -229,6 +226,9 @@ static const struct v4l2_pix_format sif_mode[] = {
229 .priv = 0}, 226 .priv = 0},
230}; 227};
231 228
229/* bridge reg08 -> JPEG quality conversion table */
230static u8 jpeg_qual[] = {40, 50, 60, 70, /*80*/};
231
232/* usb exchanges */ 232/* usb exchanges */
233struct usb_action { 233struct usb_action {
234 u8 req; 234 u8 req;
@@ -5925,32 +5925,17 @@ static void setexposure(struct gspca_dev *gspca_dev)
5925static void setquality(struct gspca_dev *gspca_dev) 5925static void setquality(struct gspca_dev *gspca_dev)
5926{ 5926{
5927 struct sd *sd = (struct sd *) gspca_dev; 5927 struct sd *sd = (struct sd *) gspca_dev;
5928 u8 frxt; 5928 s8 reg07;
5929 5929
5930 reg07 = 0;
5930 switch (sd->sensor) { 5931 switch (sd->sensor) {
5931 case SENSOR_ADCM2700:
5932 case SENSOR_GC0305:
5933 case SENSOR_HV7131B:
5934 case SENSOR_HV7131R:
5935 case SENSOR_OV7620: 5932 case SENSOR_OV7620:
5936 case SENSOR_PAS202B: 5933 reg07 = 0x30;
5937 case SENSOR_PO2030: 5934 break;
5938 return;
5939 } 5935 }
5940/*fixme: is it really 0008 0007 0018 for all other sensors? */ 5936 reg_w(gspca_dev, sd->reg08, ZC3XX_R008_CLOCKSETTING);
5941 reg_w(gspca_dev, QUANT_VAL, 0x0008); 5937 if (reg07 != 0)
5942 frxt = 0x30; 5938 reg_w(gspca_dev, reg07, 0x0007);
5943 reg_w(gspca_dev, frxt, 0x0007);
5944#if QUANT_VAL == 0 || QUANT_VAL == 1 || QUANT_VAL == 2
5945 frxt = 0xff;
5946#elif QUANT_VAL == 3
5947 frxt = 0xf0;
5948#elif QUANT_VAL == 4
5949 frxt = 0xe0;
5950#else
5951 frxt = 0x20;
5952#endif
5953 reg_w(gspca_dev, frxt, 0x0018);
5954} 5939}
5955 5940
5956/* Matches the sensor's internal frame rate to the lighting frequency. 5941/* Matches the sensor's internal frame rate to the lighting frequency.
@@ -6411,7 +6396,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
6411 sd->sensor = id->driver_info; 6396 sd->sensor = id->driver_info;
6412 6397
6413 gspca_dev->cam.ctrls = sd->ctrls; 6398 gspca_dev->cam.ctrls = sd->ctrls;
6414 sd->quality = QUALITY_DEF; 6399 sd->reg08 = REG08_DEF;
6415 6400
6416 return 0; 6401 return 0;
6417} 6402}
@@ -6464,6 +6449,27 @@ static int sd_init(struct gspca_dev *gspca_dev)
6464 [SENSOR_PO2030] = 1, 6449 [SENSOR_PO2030] = 1,
6465 [SENSOR_TAS5130C] = 1, 6450 [SENSOR_TAS5130C] = 1,
6466 }; 6451 };
6452 static const u8 reg08_tb[SENSOR_MAX] = {
6453 [SENSOR_ADCM2700] = 1,
6454 [SENSOR_CS2102] = 3,
6455/* [SENSOR_CS2102K] = 3, */
6456 [SENSOR_GC0303] = 2,
6457 [SENSOR_GC0305] = 3,
6458 [SENSOR_HDCS2020] = 1,
6459 [SENSOR_HV7131B] = 3,
6460 [SENSOR_HV7131R] = 3,
6461 [SENSOR_ICM105A] = 3,
6462 [SENSOR_MC501CB] = 3,
6463 [SENSOR_MT9V111_1] = 3,
6464 [SENSOR_MT9V111_3] = 3,
6465 [SENSOR_OV7620] = 1,
6466 [SENSOR_OV7630C] = 3,
6467 [SENSOR_PAS106] = 3,
6468 [SENSOR_PAS202B] = 3,
6469 [SENSOR_PB0330] = 3,
6470 [SENSOR_PO2030] = 2,
6471 [SENSOR_TAS5130C] = 3,
6472 };
6467 6473
6468 sensor = zcxx_probeSensor(gspca_dev); 6474 sensor = zcxx_probeSensor(gspca_dev);
6469 if (sensor >= 0) 6475 if (sensor >= 0)
@@ -6616,6 +6622,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
6616 } 6622 }
6617 6623
6618 sd->ctrls[GAMMA].def = gamma[sd->sensor]; 6624 sd->ctrls[GAMMA].def = gamma[sd->sensor];
6625 sd->reg08 = reg08_tb[sd->sensor];
6619 6626
6620 switch (sd->sensor) { 6627 switch (sd->sensor) {
6621 case SENSOR_HV7131R: 6628 case SENSOR_HV7131R:
@@ -6685,7 +6692,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
6685 /* create the JPEG header */ 6692 /* create the JPEG header */
6686 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, 6693 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
6687 0x21); /* JPEG 422 */ 6694 0x21); /* JPEG 422 */
6688 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
6689 6695
6690 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; 6696 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
6691 switch (sd->sensor) { 6697 switch (sd->sensor) {
@@ -6761,10 +6767,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
6761 reg_r(gspca_dev, 0x0180); /* from win */ 6767 reg_r(gspca_dev, 0x0180); /* from win */
6762 reg_w(gspca_dev, 0x00, 0x0180); 6768 reg_w(gspca_dev, 0x00, 0x0180);
6763 break; 6769 break;
6764 default:
6765 setquality(gspca_dev);
6766 break;
6767 } 6770 }
6771 setquality(gspca_dev);
6772 jpeg_set_qual(sd->jpeg_hdr, jpeg_qual[sd->reg08]);
6768 setlightfreq(gspca_dev); 6773 setlightfreq(gspca_dev);
6769 6774
6770 switch (sd->sensor) { 6775 switch (sd->sensor) {
@@ -6802,13 +6807,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
6802 } 6807 }
6803 6808
6804 setautogain(gspca_dev); 6809 setautogain(gspca_dev);
6805 switch (sd->sensor) {
6806 case SENSOR_PO2030:
6807 msleep(50);
6808 reg_w(gspca_dev, 0x00, 0x0007); /* (from win traces) */
6809 reg_w(gspca_dev, 0x02, ZC3XX_R008_CLOCKSETTING);
6810 break;
6811 }
6812 return gspca_dev->usb_err; 6810 return gspca_dev->usb_err;
6813} 6811}
6814 6812
@@ -6897,15 +6895,20 @@ static int sd_set_jcomp(struct gspca_dev *gspca_dev,
6897 struct v4l2_jpegcompression *jcomp) 6895 struct v4l2_jpegcompression *jcomp)
6898{ 6896{
6899 struct sd *sd = (struct sd *) gspca_dev; 6897 struct sd *sd = (struct sd *) gspca_dev;
6898 int i;
6900 6899
6901 if (jcomp->quality < QUALITY_MIN) 6900 for (i = 0; i < ARRAY_SIZE(jpeg_qual) - 1; i++) {
6902 sd->quality = QUALITY_MIN; 6901 if (jcomp->quality <= jpeg_qual[i])
6903 else if (jcomp->quality > QUALITY_MAX) 6902 break;
6904 sd->quality = QUALITY_MAX; 6903 }
6905 else 6904 if (i > 0
6906 sd->quality = jcomp->quality; 6905 && i == sd->reg08
6906 && jcomp->quality < jpeg_qual[sd->reg08])
6907 i--;
6908 sd->reg08 = i;
6909 jcomp->quality = jpeg_qual[i];
6907 if (gspca_dev->streaming) 6910 if (gspca_dev->streaming)
6908 jpeg_set_qual(sd->jpeg_hdr, sd->quality); 6911 jpeg_set_qual(sd->jpeg_hdr, jcomp->quality);
6909 return gspca_dev->usb_err; 6912 return gspca_dev->usb_err;
6910} 6913}
6911 6914
@@ -6915,7 +6918,7 @@ static int sd_get_jcomp(struct gspca_dev *gspca_dev,
6915 struct sd *sd = (struct sd *) gspca_dev; 6918 struct sd *sd = (struct sd *) gspca_dev;
6916 6919
6917 memset(jcomp, 0, sizeof *jcomp); 6920 memset(jcomp, 0, sizeof *jcomp);
6918 jcomp->quality = sd->quality; 6921 jcomp->quality = jpeg_qual[sd->reg08];
6919 jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT 6922 jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
6920 | V4L2_JPEG_MARKER_DQT; 6923 | V4L2_JPEG_MARKER_DQT;
6921 return 0; 6924 return 0;