V4L/DVB (11425): gspca - m5602: Move the vflip quirk to probe stage.
[safe/jmp/linux-2.6] / drivers / media / video / gspca / stk014.c
index 8743c03..f25be20 100644 (file)
@@ -35,10 +35,13 @@ struct sd {
        unsigned char contrast;
        unsigned char colors;
        unsigned char lightfreq;
-};
+       u8 quality;
+#define QUALITY_MIN 60
+#define QUALITY_MAX 95
+#define QUALITY_DEF 80
 
-/* global parameters */
-static int sd_quant = 7;               /* <= 4 KO - 7: good (enough!) */
+       u8 *jpeg_hdr;
+};
 
 /* V4L2 controls supported by the driver */
 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
@@ -301,6 +304,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
        sd->contrast = CONTRAST_DEF;
        sd->colors = COLOR_DEF;
        sd->lightfreq = FREQ_DEF;
+       sd->quality = QUALITY_DEF;
        return 0;
 }
 
@@ -324,8 +328,15 @@ static int sd_init(struct gspca_dev *gspca_dev)
 /* -- start the camera -- */
 static int sd_start(struct gspca_dev *gspca_dev)
 {
+       struct sd *sd = (struct sd *) gspca_dev;
        int ret, value;
 
+       /* create the JPEG header */
+       sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
+       jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
+                       0x22);          /* JPEG 411 */
+       jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+
        /* work on alternate 1 */
        usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1);
 
@@ -397,11 +408,19 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
        PDEBUG(D_STREAM, "camera stopped");
 }
 
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+       struct sd *sd = (struct sd *) gspca_dev;
+
+       kfree(sd->jpeg_hdr);
+}
+
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
                        struct gspca_frame *frame,      /* target */
                        __u8 *data,                     /* isoc packet */
                        int len)                        /* iso packet length */
 {
+       struct sd *sd = (struct sd *) gspca_dev;
        static unsigned char ffd9[] = {0xff, 0xd9};
 
        /* a frame starts with:
@@ -418,7 +437,8 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
                                        ffd9, 2);
 
                /* put the JPEG 411 header */
-               jpeg_put_header(gspca_dev, frame, sd_quant, 0x22);
+               gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+                       sd->jpeg_hdr, JPEG_HDR_SZ);
 
                /* beginning of the frame */
 #define STKHDRSZ 12
@@ -518,6 +538,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;
+}
+
 /* sub-driver description */
 static const struct sd_desc sd_desc = {
        .name = MODULE_NAME,
@@ -527,8 +575,11 @@ static const struct sd_desc sd_desc = {
        .init = sd_init,
        .start = sd_start,
        .stopN = sd_stopN,
+       .stop0 = sd_stop0,
        .pkt_scan = sd_pkt_scan,
        .querymenu = sd_querymenu,
+       .get_jcomp = sd_get_jcomp,
+       .set_jcomp = sd_set_jcomp,
 };
 
 /* -- module initialisation -- */
@@ -563,7 +614,7 @@ static int __init sd_mod_init(void)
        int ret;
        ret = usb_register(&sd_driver);
        if (ret < 0)
-               return -1;
+               return ret;
        info("registered");
        return 0;
 }
@@ -575,6 +626,3 @@ static void __exit sd_mod_exit(void)
 
 module_init(sd_mod_init);
 module_exit(sd_mod_exit);
-
-module_param_named(quant, sd_quant, int, 0644);
-MODULE_PARM_DESC(quant, "Quantization index (0..8)");