diff options
Diffstat (limited to 'linux/drivers/media/video/gspca/zc3xx.c')
-rw-r--r-- | linux/drivers/media/video/gspca/zc3xx.c | 77 |
1 files changed, 64 insertions, 13 deletions
diff --git a/linux/drivers/media/video/gspca/zc3xx.c b/linux/drivers/media/video/gspca/zc3xx.c index ad385b9a0..2a9480138 100644 --- a/linux/drivers/media/video/gspca/zc3xx.c +++ b/linux/drivers/media/video/gspca/zc3xx.c @@ -23,6 +23,7 @@ #define MODULE_NAME "zc3xx" #include "gspca.h" +#include "jpeg.h" MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>, " "Serge A. Suchkov <Serge.A.S@tochka.ru>"); @@ -32,7 +33,6 @@ MODULE_LICENSE("GPL"); static int force_sensor = -1; #define QUANT_VAL 1 /* quantization table */ -#include "jpeg.h" #include "zc3xx-reg.h" /* specific webcam descriptor */ @@ -45,6 +45,10 @@ struct sd { __u8 autogain; __u8 lightfreq; __u8 sharpness; + u8 quality; /* image quality */ +#define QUALITY_MIN 40 +#define QUALITY_MAX 60 +#define QUALITY_DEF 50 signed char sensor; /* Type of image sensor chip */ /* !! values used in different tables */ @@ -69,6 +73,8 @@ struct sd { #define SENSOR_TAS5130C_VF0250 17 #define SENSOR_MAX 18 unsigned short chip_revision; + + u8 *jpeg_hdr; }; /* V4L2 controls supported by the driver */ @@ -6330,7 +6336,7 @@ static __u16 i2c_read(struct gspca_dev *gspca_dev, retbyte = reg_r_i(gspca_dev, 0x0091); /* read status */ retval = reg_r_i(gspca_dev, 0x0095); /* read Lowbyte */ retval |= reg_r_i(gspca_dev, 0x0096) << 8; /* read Hightbyte */ - PDEBUG(D_USBO, "i2c r [%02x] -> %04x (%02x)", + PDEBUG(D_USBI, "i2c r [%02x] -> %04x (%02x)", reg, retval, retbyte); return retval; } @@ -6891,7 +6897,6 @@ static const struct sensor_by_chipset_revision chipset_revision_sensor[] = { {0x8001, 0x13}, {0x8000, 0x14}, /* CS2102K */ {0x8400, 0x15}, /* TAS5130K */ - {0x4001, 0x16}, /* ADCM2700 */ }; static int vga_3wr_probe(struct gspca_dev *gspca_dev) @@ -6927,12 +6932,15 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev) retword |= reg_r(gspca_dev, 0x000a); PDEBUG(D_PROBE, "probe 3wr vga 1 0x%04x", retword); reg_r(gspca_dev, 0x0010); - /* this is tested only once anyway */ - for (i = 0; i < ARRAY_SIZE(chipset_revision_sensor); i++) { - if (chipset_revision_sensor[i].revision == retword) { - sd->chip_revision = retword; - send_unknown(dev, SENSOR_PB0330); - return chipset_revision_sensor[i].internal_sensor_id; + /* value 0x4001 is meaningless */ + if (retword != 0x4001) { + for (i = 0; i < ARRAY_SIZE(chipset_revision_sensor); i++) { + if (chipset_revision_sensor[i].revision == retword) { + sd->chip_revision = retword; + send_unknown(dev, SENSOR_PB0330); + return chipset_revision_sensor[i] + .internal_sensor_id; + } } } @@ -7003,12 +7011,12 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev) reg_w(dev, 0x01, 0x0001); reg_w(dev, 0x03, 0x0012); reg_w(dev, 0x01, 0x0012); - reg_w(dev, 0x05, 0x0001); + reg_w(dev, 0x05, 0x0012); reg_w(dev, 0xd3, 0x008b); retword = i2c_read(gspca_dev, 0x01); if (retword != 0) { PDEBUG(D_PROBE, "probe 3wr vga type 0a ? ret: %04x", retword); - return retword; + return 0x16; /* adcm2700 (6100/6200) */ } return -1; } @@ -7206,6 +7214,7 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->gamma = gamma[(int) sd->sensor]; sd->autogain = sd_ctrls[SD_AUTOGAIN].qctrl.default_value; sd->lightfreq = sd_ctrls[SD_FREQ].qctrl.default_value; + sd->quality = QUALITY_DEF; switch (sd->sensor) { case SENSOR_GC0305: @@ -7261,6 +7270,14 @@ static int sd_start(struct gspca_dev *gspca_dev) /* 17 */ }; + /* create the JPEG header */ + sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); + if (!sd->jpeg_hdr) + return -ENOMEM; + 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[(int) gspca_dev->curr_mode].priv; zc3_init = init_tb[(int) sd->sensor][mode]; switch (sd->sensor) { @@ -7398,6 +7415,7 @@ static void sd_stop0(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; + kfree(sd->jpeg_hdr); if (!gspca_dev->present) return; send_unknown(gspca_dev->dev, sd->sensor); @@ -7408,12 +7426,15 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, __u8 *data, int len) { + struct sd *sd = (struct sd *) gspca_dev; if (data[0] == 0xff && data[1] == 0xd8) { /* start of frame */ frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, data, 0); /* put the JPEG header in the new frame */ - jpeg_put_header(gspca_dev, frame, 0x21); + gspca_frame_add(gspca_dev, FIRST_PACKET, frame, + sd->jpeg_hdr, JPEG_HDR_SZ); + /* remove the webcam's header: * ff d8 ff fe 00 0e 00 00 ss ss 00 01 ww ww hh hh pp pp * - 'ss ss' is the frame sequence number (BE) @@ -7555,6 +7576,34 @@ static int sd_querymenu(struct gspca_dev *gspca_dev, return -EINVAL; } +static int sd_set_jcomp(struct gspca_dev *gspca_dev, + struct v4l2_jpegcompression *jcomp) +{ + struct sd *sd = (struct sd *) gspca_dev; + + if (jcomp->quality < QUALITY_MIN) + sd->quality = QUALITY_MIN; + else if (jcomp->quality > QUALITY_MAX) + sd->quality = QUALITY_MAX; + else + sd->quality = jcomp->quality; + if (gspca_dev->streaming) + jpeg_set_qual(sd->jpeg_hdr, sd->quality); + return 0; +} + +static int sd_get_jcomp(struct gspca_dev *gspca_dev, + struct v4l2_jpegcompression *jcomp) +{ + struct sd *sd = (struct sd *) gspca_dev; + + memset(jcomp, 0, sizeof *jcomp); + jcomp->quality = sd->quality; + jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT + | V4L2_JPEG_MARKER_DQT; + return 0; +} + static const struct sd_desc sd_desc = { .name = MODULE_NAME, .ctrls = sd_ctrls, @@ -7565,6 +7614,8 @@ static const struct sd_desc sd_desc = { .stop0 = sd_stop0, .pkt_scan = sd_pkt_scan, .querymenu = sd_querymenu, + .get_jcomp = sd_get_jcomp, + .set_jcomp = sd_set_jcomp, }; static const __devinitdata struct usb_device_id device_table[] = { @@ -7615,7 +7666,7 @@ static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x055f, 0xd004)}, {USB_DEVICE(0x0698, 0x2003)}, {USB_DEVICE(0x0ac8, 0x0301), .driver_info = SENSOR_PAS106}, - {USB_DEVICE(0x0ac8, 0x0302)}, + {USB_DEVICE(0x0ac8, 0x0302), .driver_info = SENSOR_PAS106}, {USB_DEVICE(0x0ac8, 0x301b)}, {USB_DEVICE(0x0ac8, 0x303b)}, {USB_DEVICE(0x0ac8, 0x305b), .driver_info = SENSOR_TAS5130C_VF0250}, |