summaryrefslogtreecommitdiff
path: root/linux/drivers/media/video/gspca/mars.c
diff options
context:
space:
mode:
Diffstat (limited to 'linux/drivers/media/video/gspca/mars.c')
-rw-r--r--linux/drivers/media/video/gspca/mars.c79
1 files changed, 67 insertions, 12 deletions
diff --git a/linux/drivers/media/video/gspca/mars.c b/linux/drivers/media/video/gspca/mars.c
index c5a19b5bc..789fd178a 100644
--- a/linux/drivers/media/video/gspca/mars.c
+++ b/linux/drivers/media/video/gspca/mars.c
@@ -22,7 +22,6 @@
#define MODULE_NAME "mars"
#include "gspca.h"
-#define QUANT_VAL 1 /* quantization table */
#include "jpeg.h"
MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
@@ -37,6 +36,12 @@ struct sd {
u8 colors;
u8 gamma;
u8 sharpness;
+ u8 quality;
+#define QUALITY_MIN 40
+#define QUALITY_MAX 70
+#define QUALITY_DEF 50
+
+ u8 *jpeg_hdr;
};
/* V4L2 controls supported by the driver */
@@ -69,10 +74,10 @@ static struct ctrl sd_ctrls[] = {
.id = V4L2_CID_SATURATION,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Color",
- .minimum = 0,
- .maximum = 220,
+ .minimum = 1,
+ .maximum = 255,
.step = 1,
-#define COLOR_DEF 190
+#define COLOR_DEF 200
.default_value = COLOR_DEF,
},
.set = sd_setcolors,
@@ -176,6 +181,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
sd->colors = COLOR_DEF;
sd->gamma = GAMMA_DEF;
sd->sharpness = SHARPNESS_DEF;
+ sd->quality = QUALITY_DEF;
gspca_dev->nbalt = 9; /* use the altsetting 08 */
return 0;
}
@@ -191,7 +197,13 @@ static int sd_start(struct gspca_dev *gspca_dev)
struct sd *sd = (struct sd *) gspca_dev;
int err_code;
u8 *data;
- int i, val;
+ int i;
+
+ /* create the JPEG header */
+ sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
+ jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
+ 0x21); /* JPEG 422 */
+ jpeg_set_qual(sd->jpeg_hdr, sd->quality);
data = gspca_dev->usb_buf;
@@ -253,9 +265,11 @@ static int sd_start(struct gspca_dev *gspca_dev)
data[1] = 0; /* reg 94, Y Gain (auto) */
#if 1
/*jfm: from win trace*/
- val = sd->colors * 0x40 + 0x400;
- data[2] = val; /* reg 0x5f/0x60 (LE) = saturation */
- data[3] = val >> 8;
+ /* reg 0x5f/0x60 (LE) = saturation */
+ /* h (60): xxxx x100
+ * l (5f): xxxx x000 */
+ data[2] = sd->colors << 3;
+ data[3] = ((sd->colors >> 2) & 0xf8) | 0x04;
data[4] = sd->brightness; /* reg 0x61 = brightness */
data[5] = 0x00;
#else
@@ -339,11 +353,19 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
PDEBUG(D_ERR, "Camera Stop failed");
}
+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;
int p;
if (len < 6) {
@@ -366,7 +388,8 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
frame, data, p);
/* put the JPEG header */
- jpeg_put_header(gspca_dev, frame, 0x21);
+ gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+ sd->jpeg_hdr, JPEG_HDR_SZ);
data += p + 16;
len -= p + 16;
break;
@@ -403,10 +426,11 @@ static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
sd->colors = val;
if (gspca_dev->streaming) {
- val = val * 0x40 + 0x400;
+
+ /* see sd_start */
gspca_dev->usb_buf[0] = 0x5f;
- gspca_dev->usb_buf[1] = val;
- gspca_dev->usb_buf[2] = val >> 8;
+ gspca_dev->usb_buf[1] = sd->colors << 3;
+ gspca_dev->usb_buf[2] = ((sd->colors >> 2) & 0xf8) | 0x04;
reg_w(gspca_dev, 3);
}
return 0;
@@ -462,6 +486,34 @@ static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
return 0;
}
+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,
@@ -471,7 +523,10 @@ static const struct sd_desc sd_desc = {
.init = sd_init,
.start = sd_start,
.stopN = sd_stopN,
+ .stop0 = sd_stop0,
.pkt_scan = sd_pkt_scan,
+ .get_jcomp = sd_get_jcomp,
+ .set_jcomp = sd_set_jcomp,
};
/* -- module initialisation -- */