summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorJean-François Moine <moinejf@free.fr>2012-02-27 07:26:30 -0300
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-03-08 08:01:48 -0300
commit30c73d464a10bee4bb8375bb2ed8cc102c507bb7 (patch)
tree19c33cca5ad9d71113e71f81aa6c2f5d53d2f654 /drivers
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')
-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");
static int force_sensor = -1;
-#define QUANT_VAL 1 /* quantization table */
+#define REG08_DEF 3 /* default JPEG compression (70%) */
#include "zc3xx-reg.h"
/* controls */
@@ -57,10 +57,7 @@ struct sd {
struct gspca_ctrl ctrls[NCTRLS];
- u8 quality; /* image quality */
-#define QUALITY_MIN 50
-#define QUALITY_MAX 80
-#define QUALITY_DEF 70
+ u8 reg08; /* webcam compression quality */
u8 bridge;
u8 sensor; /* Type of image sensor chip */
@@ -229,6 +226,9 @@ static const struct v4l2_pix_format sif_mode[] = {
.priv = 0},
};
+/* bridge reg08 -> JPEG quality conversion table */
+static u8 jpeg_qual[] = {40, 50, 60, 70, /*80*/};
+
/* usb exchanges */
struct usb_action {
u8 req;
@@ -5925,32 +5925,17 @@ static void setexposure(struct gspca_dev *gspca_dev)
static void setquality(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- u8 frxt;
+ s8 reg07;
+ reg07 = 0;
switch (sd->sensor) {
- case SENSOR_ADCM2700:
- case SENSOR_GC0305:
- case SENSOR_HV7131B:
- case SENSOR_HV7131R:
case SENSOR_OV7620:
- case SENSOR_PAS202B:
- case SENSOR_PO2030:
- return;
+ reg07 = 0x30;
+ break;
}
-/*fixme: is it really 0008 0007 0018 for all other sensors? */
- reg_w(gspca_dev, QUANT_VAL, 0x0008);
- frxt = 0x30;
- reg_w(gspca_dev, frxt, 0x0007);
-#if QUANT_VAL == 0 || QUANT_VAL == 1 || QUANT_VAL == 2
- frxt = 0xff;
-#elif QUANT_VAL == 3
- frxt = 0xf0;
-#elif QUANT_VAL == 4
- frxt = 0xe0;
-#else
- frxt = 0x20;
-#endif
- reg_w(gspca_dev, frxt, 0x0018);
+ reg_w(gspca_dev, sd->reg08, ZC3XX_R008_CLOCKSETTING);
+ if (reg07 != 0)
+ reg_w(gspca_dev, reg07, 0x0007);
}
/* Matches the sensor's internal frame rate to the lighting frequency.
@@ -6411,7 +6396,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
sd->sensor = id->driver_info;
gspca_dev->cam.ctrls = sd->ctrls;
- sd->quality = QUALITY_DEF;
+ sd->reg08 = REG08_DEF;
return 0;
}
@@ -6464,6 +6449,27 @@ static int sd_init(struct gspca_dev *gspca_dev)
[SENSOR_PO2030] = 1,
[SENSOR_TAS5130C] = 1,
};
+ static const u8 reg08_tb[SENSOR_MAX] = {
+ [SENSOR_ADCM2700] = 1,
+ [SENSOR_CS2102] = 3,
+/* [SENSOR_CS2102K] = 3, */
+ [SENSOR_GC0303] = 2,
+ [SENSOR_GC0305] = 3,
+ [SENSOR_HDCS2020] = 1,
+ [SENSOR_HV7131B] = 3,
+ [SENSOR_HV7131R] = 3,
+ [SENSOR_ICM105A] = 3,
+ [SENSOR_MC501CB] = 3,
+ [SENSOR_MT9V111_1] = 3,
+ [SENSOR_MT9V111_3] = 3,
+ [SENSOR_OV7620] = 1,
+ [SENSOR_OV7630C] = 3,
+ [SENSOR_PAS106] = 3,
+ [SENSOR_PAS202B] = 3,
+ [SENSOR_PB0330] = 3,
+ [SENSOR_PO2030] = 2,
+ [SENSOR_TAS5130C] = 3,
+ };
sensor = zcxx_probeSensor(gspca_dev);
if (sensor >= 0)
@@ -6616,6 +6622,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
}
sd->ctrls[GAMMA].def = gamma[sd->sensor];
+ sd->reg08 = reg08_tb[sd->sensor];
switch (sd->sensor) {
case SENSOR_HV7131R:
@@ -6685,7 +6692,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
/* create the JPEG header */
jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
0x21); /* JPEG 422 */
- jpeg_set_qual(sd->jpeg_hdr, sd->quality);
mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
switch (sd->sensor) {
@@ -6761,10 +6767,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
reg_r(gspca_dev, 0x0180); /* from win */
reg_w(gspca_dev, 0x00, 0x0180);
break;
- default:
- setquality(gspca_dev);
- break;
}
+ setquality(gspca_dev);
+ jpeg_set_qual(sd->jpeg_hdr, jpeg_qual[sd->reg08]);
setlightfreq(gspca_dev);
switch (sd->sensor) {
@@ -6802,13 +6807,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
}
setautogain(gspca_dev);
- switch (sd->sensor) {
- case SENSOR_PO2030:
- msleep(50);
- reg_w(gspca_dev, 0x00, 0x0007); /* (from win traces) */
- reg_w(gspca_dev, 0x02, ZC3XX_R008_CLOCKSETTING);
- break;
- }
return gspca_dev->usb_err;
}
@@ -6897,15 +6895,20 @@ static int sd_set_jcomp(struct gspca_dev *gspca_dev,
struct v4l2_jpegcompression *jcomp)
{
struct sd *sd = (struct sd *) gspca_dev;
+ int i;
- if (jcomp->quality < QUALITY_MIN)
- sd->quality = QUALITY_MIN;
- else if (jcomp->quality > QUALITY_MAX)
- sd->quality = QUALITY_MAX;
- else
- sd->quality = jcomp->quality;
+ for (i = 0; i < ARRAY_SIZE(jpeg_qual) - 1; i++) {
+ if (jcomp->quality <= jpeg_qual[i])
+ break;
+ }
+ if (i > 0
+ && i == sd->reg08
+ && jcomp->quality < jpeg_qual[sd->reg08])
+ i--;
+ sd->reg08 = i;
+ jcomp->quality = jpeg_qual[i];
if (gspca_dev->streaming)
- jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+ jpeg_set_qual(sd->jpeg_hdr, jcomp->quality);
return gspca_dev->usb_err;
}
@@ -6915,7 +6918,7 @@ static int sd_get_jcomp(struct gspca_dev *gspca_dev,
struct sd *sd = (struct sd *) gspca_dev;
memset(jcomp, 0, sizeof *jcomp);
- jcomp->quality = sd->quality;
+ jcomp->quality = jpeg_qual[sd->reg08];
jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
| V4L2_JPEG_MARKER_DQT;
return 0;