From 0f77f40c300c18c15e7aeb2f9eee510aa96d58fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Moine?= Date: Thu, 10 Feb 2011 07:01:30 -0300 Subject: [media] gspca - sonixj: Move the avg lum computation to a separate function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jean-François Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixj.c | 44 ++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 18 deletions(-) (limited to 'drivers/media/video/gspca/sonixj.c') diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index d6f39ce1b7e1..c4147072b73e 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c @@ -2757,6 +2757,29 @@ static void do_autogain(struct gspca_dev *gspca_dev) } } +/* set the average luminosity from an isoc marker */ +static void set_lum(struct sd *sd, + u8 *data) +{ + int avg_lum; + + /* w0 w1 w2 + * w3 w4 w5 + * w6 w7 w8 + */ + avg_lum = (data[27] << 8) + data[28] /* w3 */ + + + (data[31] << 8) + data[32] /* w5 */ + + + (data[23] << 8) + data[24] /* w1 */ + + + (data[35] << 8) + data[36] /* w7 */ + + + (data[29] << 10) + (data[30] << 2); /* w4 * 4 */ + avg_lum >>= 10; + atomic_set(&sd->avg_lum, avg_lum); +} + /* scan the URB packets */ /* This function is run at interrupt level. */ static void sd_pkt_scan(struct gspca_dev *gspca_dev, @@ -2764,7 +2787,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, int len) /* iso packet length */ { struct sd *sd = (struct sd *) gspca_dev; - int sof, avg_lum; + int sof; /* the image ends on a 64 bytes block starting with * ff d9 ff ff 00 c4 c4 96 @@ -2795,23 +2818,8 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, /* end of image found - remove the trailing data */ gspca_dev->image_len = sof + 2; gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); - if (sd->ag_cnt < 0) - return; -/* w1 w2 w3 */ -/* w4 w5 w6 */ -/* w7 w8 */ -/* w4 */ - avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6; -/* w6 */ - avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6; -/* w2 */ - avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6; -/* w8 */ - avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6; -/* w5 */ - avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4; - avg_lum >>= 4; - atomic_set(&sd->avg_lum, avg_lum); + if (sd->ag_cnt >= 0) + set_lum(sd, data + sof + 2); } static int sd_set_jcomp(struct gspca_dev *gspca_dev, -- cgit v1.2.3 From a4a3076ffcdbcf40358edc2068aa4d9103fe0a28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Moine?= Date: Thu, 10 Feb 2011 07:15:24 -0300 Subject: [media] gspca - sonixj: Better scanning of isochronous packets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A marker 'ff ff 00 c4 c4 96' indicates an end of frame. It is 62 bytes long and may be splitted on 2 packets. It contains a flag 'USB full' which indicates that the frame is truncated. Signed-off-by: Jean-François Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixj.c | 119 +++++++++++++++++++++++++++++-------- 1 file changed, 93 insertions(+), 26 deletions(-) (limited to 'drivers/media/video/gspca/sonixj.c') diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index c4147072b73e..21f0330885dd 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c @@ -57,6 +57,8 @@ struct sd { atomic_t avg_lum; u32 exposure; + s8 short_mark; + u8 quality; /* image quality */ #define QUALITY_MIN 60 #define QUALITY_MAX 95 @@ -2787,39 +2789,104 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, int len) /* iso packet length */ { struct sd *sd = (struct sd *) gspca_dev; - int sof; - - /* the image ends on a 64 bytes block starting with - * ff d9 ff ff 00 c4 c4 96 - * and followed by various information including luminosity */ - /* this block may be splitted between two packets */ - /* a new image always starts in a new packet */ - switch (gspca_dev->last_packet_type) { - case DISCARD_PACKET: /* restart image building */ - sof = len - 64; - if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) - gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); - return; - case LAST_PACKET: /* put the JPEG 422 header */ + int i; + + /* + * A frame ends on the marker + * ff ff 00 c4 c4 96 .. + * which is 62 bytes long and is followed by various information + * including statuses and luminosity. + * + * A marker may be splitted on two packets. + * + * The 6th byte of a marker contains the bits: + * 0x08: USB full + * 0xc0: frame sequence + * When the bit 'USB full' is set, the frame must be discarded; + * this is also the case when the 2 bytes before the marker are + * not the JPEG end of frame ('ff d9'). + */ + +/*fixme: assumption about the following code: + * - there can be only one marker in a packet + */ + + /* skip the remaining bytes of a short marker */ + i = sd->short_mark; + if (i != 0) { + sd->short_mark = 0; + if (i < 0 /* if 'ff' at end of previous packet */ + && data[0] == 0xff + && data[1] == 0x00) + goto marker_found; + if (data[0] == 0xff && data[1] == 0xff) { + i = 0; + goto marker_found; + } + len -= i; + if (len <= 0) + return; + data += i; + } + + /* search backwards if there is a marker in the packet */ + for (i = len - 1; --i >= 0; ) { + if (data[i] != 0xff) { + i--; + continue; + } + if (data[i + 1] == 0xff) { + + /* (there may be 'ff ff' inside a marker) */ + if (i + 2 >= len || data[i + 2] == 0x00) + goto marker_found; + } + } + + /* no marker found */ + /* add the JPEG header if first fragment */ + if (data[len - 1] == 0xff) + sd->short_mark = -1; + if (gspca_dev->last_packet_type == LAST_PACKET) gspca_frame_add(gspca_dev, FIRST_PACKET, sd->jpeg_hdr, JPEG_HDR_SZ); - break; - } gspca_frame_add(gspca_dev, INTER_PACKET, data, len); + return; + + /* marker found */ + /* if some error, discard the frame */ +marker_found: + if (i > 2) { + if (data[i - 2] != 0xff || data[i - 1] != 0xd9) { + gspca_dev->last_packet_type = DISCARD_PACKET; + } + } else if (i + 6 < len) { + if (data[i + 6] & 0x08) { + gspca_dev->last_packet_type = DISCARD_PACKET; + } + } - data = gspca_dev->image; - if (data == NULL) - return; - sof = gspca_dev->image_len - 64; - if (data[sof] != 0xff - || data[sof + 1] != 0xd9) + gspca_frame_add(gspca_dev, LAST_PACKET, data, i); + + /* if the marker is smaller than 62 bytes, + * memorize the number of bytes to skip in the next packet */ + if (i + 62 > len) { /* no more usable data */ + sd->short_mark = i + 62 - len; return; + } - /* end of image found - remove the trailing data */ - gspca_dev->image_len = sof + 2; - gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); if (sd->ag_cnt >= 0) - set_lum(sd, data + sof + 2); + set_lum(sd, data + i); + + /* if more data, start a new frame */ + i += 62; + if (i < len) { + data += i; + len -= i; + gspca_frame_add(gspca_dev, FIRST_PACKET, + sd->jpeg_hdr, JPEG_HDR_SZ); + gspca_frame_add(gspca_dev, INTER_PACKET, data, len); + } } static int sd_set_jcomp(struct gspca_dev *gspca_dev, -- cgit v1.2.3 From dccdcccdd36bf7570967ff53411c7401b8e645d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Moine?= Date: Thu, 10 Feb 2011 07:30:03 -0300 Subject: [media] gspca - sonixj: Have the same JPEG quality for encoding and decoding MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jean-François Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixj.c | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) (limited to 'drivers/media/video/gspca/sonixj.c') diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index 21f0330885dd..d465022b8022 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c @@ -63,7 +63,6 @@ struct sd { #define QUALITY_MIN 60 #define QUALITY_MAX 95 #define QUALITY_DEF 80 - u8 jpegqual; /* webcam quality */ u8 reg01; u8 reg17; @@ -1786,7 +1785,6 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->ag_cnt = -1; sd->quality = QUALITY_DEF; - sd->jpegqual = 80; return 0; } @@ -2273,18 +2271,12 @@ static void setfreq(struct gspca_dev *gspca_dev) static void setjpegqual(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - int i, sc; - if (sd->jpegqual < 50) - sc = 5000 / sd->jpegqual; - else - sc = 200 - sd->jpegqual * 2; + jpeg_set_qual(sd->jpeg_hdr, sd->quality); #if USB_BUF_SZ < 64 #error "No room enough in usb_buf for quantization table" #endif - for (i = 0; i < 64; i++) - gspca_dev->usb_buf[i] = - (jpeg_head[JPEG_QT0_OFFSET + i] * sc + 50) / 100; + memcpy(gspca_dev->usb_buf, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64); usb_control_msg(gspca_dev->dev, usb_sndctrlpipe(gspca_dev->dev, 0), 0x08, @@ -2292,9 +2284,7 @@ static void setjpegqual(struct gspca_dev *gspca_dev) 0x0100, 0, gspca_dev->usb_buf, 64, 500); - for (i = 0; i < 64; i++) - gspca_dev->usb_buf[i] = - (jpeg_head[JPEG_QT1_OFFSET + i] * sc + 50) / 100; + memcpy(gspca_dev->usb_buf, &sd->jpeg_hdr[JPEG_QT1_OFFSET], 64); usb_control_msg(gspca_dev->dev, usb_sndctrlpipe(gspca_dev->dev, 0), 0x08, @@ -2340,7 +2330,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); /* initialize the bridge */ sn9c1xx = sn_tb[sd->sensor]; @@ -2901,7 +2890,7 @@ static int sd_set_jcomp(struct gspca_dev *gspca_dev, else sd->quality = jcomp->quality; if (gspca_dev->streaming) - jpeg_set_qual(sd->jpeg_hdr, sd->quality); + setjpegqual(gspca_dev); return 0; } -- cgit v1.2.3 From b96cfc33e74f5ee5a206b2d43bf0bc3898c5a572 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Moine?= Date: Thu, 10 Feb 2011 07:38:58 -0300 Subject: [media] gspca - sonixj: Update the JPEG quality for best image transfer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit During image capture, the filling rate of the isoc packets is computed. It is then used by a work queue to update the current JPEG quality. Tested-by: Franck Bourdonnec Signed-off-by: Jean-François Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixj.c | 109 +++++++++++++++++++++++++++++-------- 1 file changed, 86 insertions(+), 23 deletions(-) (limited to 'drivers/media/video/gspca/sonixj.c') diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index d465022b8022..2bfb8df9168b 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c @@ -57,12 +57,18 @@ struct sd { atomic_t avg_lum; u32 exposure; + struct work_struct work; + struct workqueue_struct *work_thread; + + u32 pktsz; /* (used by pkt_scan) */ + u16 npkt; + u8 nchg; s8 short_mark; u8 quality; /* image quality */ -#define QUALITY_MIN 60 -#define QUALITY_MAX 95 -#define QUALITY_DEF 80 +#define QUALITY_MIN 25 +#define QUALITY_MAX 90 +#define QUALITY_DEF 70 u8 reg01; u8 reg17; @@ -100,6 +106,8 @@ enum sensors { SENSOR_SP80708, }; +static void qual_upd(struct work_struct *work); + /* device flags */ #define F_PDN_INV 0x01 /* inverse pin S_PWR_DN / sn_xxx tables */ #define F_ILLUM 0x02 /* presence of illuminator */ @@ -1786,6 +1794,8 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->ag_cnt = -1; sd->quality = QUALITY_DEF; + INIT_WORK(&sd->work, qual_upd); + return 0; } @@ -2297,6 +2307,19 @@ static void setjpegqual(struct gspca_dev *gspca_dev) reg_w1(gspca_dev, 0x18, sd->reg18); } +/* JPEG quality update */ +/* This function is executed from a work queue. */ +static void qual_upd(struct work_struct *work) +{ + struct sd *sd = container_of(work, struct sd, work); + struct gspca_dev *gspca_dev = &sd->gspca_dev; + + mutex_lock(&gspca_dev->usb_lock); + PDEBUG(D_STREAM, "qual_upd %d%%", sd->quality); + setjpegqual(gspca_dev); + mutex_unlock(&gspca_dev->usb_lock); +} + /* -- start the camera -- */ static int sd_start(struct gspca_dev *gspca_dev) { @@ -2610,6 +2633,11 @@ static int sd_start(struct gspca_dev *gspca_dev) setcolors(gspca_dev); setautogain(gspca_dev); setfreq(gspca_dev); + + sd->pktsz = sd->npkt = 0; + sd->nchg = sd->short_mark = 0; + sd->work_thread = create_singlethread_workqueue(MODULE_NAME); + return gspca_dev->usb_err; } @@ -2686,6 +2714,20 @@ static void sd_stopN(struct gspca_dev *gspca_dev) /* reg_w1(gspca_dev, 0xf1, 0x01); */ } +/* called on streamoff with alt==0 and on disconnect */ +/* the usb_lock is held at entry - restore on exit */ +static void sd_stop0(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + if (sd->work_thread != NULL) { + mutex_unlock(&gspca_dev->usb_lock); + destroy_workqueue(sd->work_thread); + mutex_lock(&gspca_dev->usb_lock); + sd->work_thread = NULL; + } +} + static void do_autogain(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; @@ -2778,7 +2820,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, int len) /* iso packet length */ { struct sd *sd = (struct sd *) gspca_dev; - int i; + int i, new_qual; /* * A frame ends on the marker @@ -2818,6 +2860,10 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, data += i; } + /* count the packets and their size */ + sd->npkt++; + sd->pktsz += len; + /* search backwards if there is a marker in the packet */ for (i = len - 1; --i >= 0; ) { if (data[i] != 0xff) { @@ -2843,27 +2889,60 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, return; /* marker found */ - /* if some error, discard the frame */ + /* if some error, discard the frame and decrease the quality */ marker_found: + new_qual = 0; if (i > 2) { if (data[i - 2] != 0xff || data[i - 1] != 0xd9) { gspca_dev->last_packet_type = DISCARD_PACKET; + new_qual = -3; } } else if (i + 6 < len) { if (data[i + 6] & 0x08) { gspca_dev->last_packet_type = DISCARD_PACKET; + new_qual = -5; } } gspca_frame_add(gspca_dev, LAST_PACKET, data, i); + /* compute the filling rate and a new JPEG quality */ + if (new_qual == 0) { + int r; + + r = (sd->pktsz * 100) / + (sd->npkt * + gspca_dev->urb[0]->iso_frame_desc[0].length); + if (r >= 85) + new_qual = -3; + else if (r < 75) + new_qual = 2; + } + if (new_qual != 0) { + sd->nchg += new_qual; + if (sd->nchg < -6 || sd->nchg >= 12) { + sd->nchg = 0; + new_qual += sd->quality; + if (new_qual < QUALITY_MIN) + new_qual = QUALITY_MIN; + else if (new_qual > QUALITY_MAX) + new_qual = QUALITY_MAX; + if (new_qual != sd->quality) { + sd->quality = new_qual; + queue_work(sd->work_thread, &sd->work); + } + } + } else { + sd->nchg = 0; + } + sd->pktsz = sd->npkt = 0; + /* if the marker is smaller than 62 bytes, * memorize the number of bytes to skip in the next packet */ if (i + 62 > len) { /* no more usable data */ sd->short_mark = i + 62 - len; return; } - if (sd->ag_cnt >= 0) set_lum(sd, data + i); @@ -2878,22 +2957,6 @@ marker_found: } } -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) - setjpegqual(gspca_dev); - return 0; -} - static int sd_get_jcomp(struct gspca_dev *gspca_dev, struct v4l2_jpegcompression *jcomp) { @@ -2955,10 +3018,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, .dq_callback = do_autogain, .get_jcomp = sd_get_jcomp, - .set_jcomp = sd_set_jcomp, .querymenu = sd_querymenu, #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) .int_pkt_scan = sd_int_pkt_scan, -- cgit v1.2.3 From 804632201f2d749b7cb35fce42fc28552ad595c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Moine?= Date: Thu, 10 Feb 2011 07:44:59 -0300 Subject: [media] gspca - sonixj: Fix start sequence of sensor mt9v111 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jean-François Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixj.c | 23 ++++------------------- 1 file changed, 4 insertions(+), 19 deletions(-) (limited to 'drivers/media/video/gspca/sonixj.c') diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index 2bfb8df9168b..01ee39be2c75 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c @@ -856,18 +856,8 @@ static const u8 mt9v111_sensor_init[][8] = { {0xb1, 0x5c, 0x01, 0x00, 0x01, 0x00, 0x00, 0x10}, /* IFP select */ {0xb1, 0x5c, 0x08, 0x04, 0x80, 0x00, 0x00, 0x10}, /* output fmt ctrl */ {0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10}, /* op mode ctrl */ - {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10}, - {0xb1, 0x5c, 0x03, 0x01, 0xe1, 0x00, 0x00, 0x10}, - {0xb1, 0x5c, 0x04, 0x02, 0x81, 0x00, 0x00, 0x10}, - {0xb1, 0x5c, 0x05, 0x00, 0x04, 0x00, 0x00, 0x10}, {0xb1, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10}, /* sensor select */ - {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10}, - {0xb1, 0x5c, 0x03, 0x01, 0xe6, 0x00, 0x00, 0x10}, - {0xb1, 0x5c, 0x04, 0x02, 0x86, 0x00, 0x00, 0x10}, - {0xb1, 0x5c, 0x05, 0x00, 0x04, 0x00, 0x00, 0x10}, - {0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10}, {0xb1, 0x5c, 0x08, 0x00, 0x08, 0x00, 0x00, 0x10}, /* row start */ - {0xb1, 0x5c, 0x0e, 0x00, 0x08, 0x00, 0x00, 0x10}, {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10}, /* col start */ {0xb1, 0x5c, 0x03, 0x01, 0xe7, 0x00, 0x00, 0x10}, /* window height */ {0xb1, 0x5c, 0x04, 0x02, 0x87, 0x00, 0x00, 0x10}, /* window width */ @@ -881,15 +871,10 @@ static const u8 mt9v111_sensor_init[][8] = { {} }; static const u8 mt9v111_sensor_param1[][8] = { - {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xb1, 0x5c, 0x09, 0x01, 0x2c, 0x00, 0x00, 0x10}, - {0xd1, 0x5c, 0x2b, 0x00, 0x33, 0x00, 0xa0, 0x10}, /* green1 gain */ - {0xd1, 0x5c, 0x2d, 0x00, 0xa0, 0x00, 0x33, 0x10}, /* red gain */ - /*******/ - {0xb1, 0x5c, 0x06, 0x00, 0x1e, 0x00, 0x00, 0x10}, /* vert blanking */ - {0xb1, 0x5c, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10}, /* horiz blanking */ - {0xd1, 0x5c, 0x2c, 0x00, 0xad, 0x00, 0xad, 0x10}, /* blue gain */ + {0xd1, 0x5c, 0x2b, 0x00, 0x33, 0x00, 0xad, 0x10}, /* G1 and B gains */ + {0xd1, 0x5c, 0x2d, 0x00, 0xad, 0x00, 0x33, 0x10}, /* R and G2 gains */ + {0xb1, 0x5c, 0x06, 0x00, 0x40, 0x00, 0x00, 0x10}, /* vert blanking */ + {0xb1, 0x5c, 0x05, 0x00, 0x09, 0x00, 0x00, 0x10}, /* horiz blanking */ {0xb1, 0x5c, 0x35, 0x01, 0xc0, 0x00, 0x00, 0x10}, /* global gain */ {} }; -- cgit v1.2.3 From 222036765ccbdb1ff4feef22d8e2fc687a9cdcfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Moine?= Date: Thu, 10 Feb 2011 07:49:32 -0300 Subject: [media] gspca - sonixj: Adjust autogain for sensor mt9v111 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The gain/expo adjustment was too long. Signed-off-by: Jean-François Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixj.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'drivers/media/video/gspca/sonixj.c') diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index 01ee39be2c75..b7a7e96d3bd8 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c @@ -1939,10 +1939,10 @@ static u32 setexposure(struct gspca_dev *gspca_dev, u8 expo_c1[] = { 0xb1, 0x5c, 0x09, 0x00, 0x00, 0x00, 0x00, 0x10 }; - if (expo > 0x0280) - expo = 0x0280; - else if (expo < 0x0040) - expo = 0x0040; + if (expo > 0x0390) + expo = 0x0390; + else if (expo < 0x0060) + expo = 0x0060; expo_c1[3] = expo >> 8; expo_c1[4] = expo; i2c_w8(gspca_dev, expo_c1); @@ -1999,10 +1999,13 @@ static void setbrightness(struct gspca_dev *gspca_dev) sd->exposure = setexposure(gspca_dev, expo); break; case SENSOR_GC0307: - case SENSOR_MT9V111: expo = brightness; sd->exposure = setexposure(gspca_dev, expo); return; /* don't set the Y offset */ + case SENSOR_MT9V111: + expo = brightness << 2; + sd->exposure = setexposure(gspca_dev, expo); + return; /* don't set the Y offset */ case SENSOR_OM6802: expo = brightness << 2; sd->exposure = setexposure(gspca_dev, expo); @@ -2750,6 +2753,7 @@ static void do_autogain(struct gspca_dev *gspca_dev) (unsigned int) (expotimes << 8)); break; case SENSOR_OM6802: + case SENSOR_MT9V111: expotimes = sd->exposure; expotimes += (luma_mean - delta) >> 2; if (expotimes < 0) @@ -2762,7 +2766,6 @@ static void do_autogain(struct gspca_dev *gspca_dev) /* case SENSOR_MO4000: */ /* case SENSOR_MI0360: */ /* case SENSOR_MI0360B: */ -/* case SENSOR_MT9V111: */ expotimes = sd->exposure; expotimes += (luma_mean - delta) >> 6; if (expotimes < 0) -- cgit v1.2.3 From e6a92a7445cc33bbfe2775eb50473fb43bb3a2da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Moine?= Date: Thu, 10 Feb 2011 07:52:58 -0300 Subject: [media] gspca - sonixj: Simplify GPIO setting when audio present MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jean-François Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixj.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/media/video/gspca/sonixj.c') diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index b7a7e96d3bd8..bfc09b97b061 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c @@ -1789,7 +1789,7 @@ static int sd_init(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; const u8 *sn9c1xx; - u8 regGpio[] = { 0x29, 0x74 }; /* with audio */ + u8 regGpio[] = { 0x29, 0x70 }; /* no audio */ u8 regF1; /* setup a selector by bridge */ @@ -1801,6 +1801,8 @@ static int sd_init(struct gspca_dev *gspca_dev) if (gspca_dev->usb_err < 0) return gspca_dev->usb_err; PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1); + if (gspca_dev->audio) + regGpio[1] |= 0x04; /* with audio */ switch (sd->bridge) { case BRIDGE_SN9C102P: case BRIDGE_SN9C105: @@ -1840,7 +1842,6 @@ static int sd_init(struct gspca_dev *gspca_dev) reg_w1(gspca_dev, 0x02, 0x62); break; case BRIDGE_SN9C120: - regGpio[1] = 0x70; /* no audio */ reg_w(gspca_dev, 0x01, regGpio, 2); break; } -- cgit v1.2.3 From 336d23ef88fd71564fb07fdc1d1d871f8e1eeadd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Moine?= Date: Thu, 10 Feb 2011 08:00:40 -0300 Subject: [media] gspca - sonixj: Same init for all bridges but the sn9c102p MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jean-François Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixj.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'drivers/media/video/gspca/sonixj.c') diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index bfc09b97b061..571d086eabe5 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c @@ -1835,13 +1835,7 @@ static int sd_init(struct gspca_dev *gspca_dev) case BRIDGE_SN9C102P: reg_w1(gspca_dev, 0x02, regGpio[1]); break; - case BRIDGE_SN9C105: - reg_w(gspca_dev, 0x01, regGpio, 2); - break; - case BRIDGE_SN9C110: - reg_w1(gspca_dev, 0x02, 0x62); - break; - case BRIDGE_SN9C120: + default: reg_w(gspca_dev, 0x01, regGpio, 2); break; } -- cgit v1.2.3 From 5c95606b1d94a6dc62df0af2bc0d3e0e9a2e6cce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Moine?= Date: Thu, 10 Feb 2011 08:03:24 -0300 Subject: [media] gspca - sonixj: Set both pins for infrared of mt9v111 webcams MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This avoids to define the webcam model. Signed-off-by: Jean-François Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixj.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) (limited to 'drivers/media/video/gspca/sonixj.c') diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index 571d086eabe5..eb7b2613ab45 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c @@ -29,8 +29,6 @@ MODULE_AUTHOR("Jean-François Moine "); MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver"); MODULE_LICENSE("GPL"); -static int starcam; - /* controls */ enum e_ctrl { BRIGHTNESS, @@ -2192,14 +2190,11 @@ static void setillum(struct gspca_dev *gspca_dev) sd->ctrls[ILLUM].val ? 0x64 : 0x60); break; case SENSOR_MT9V111: - if (starcam) - reg_w1(gspca_dev, 0x02, - sd->ctrls[ILLUM].val ? - 0x55 : 0x54); /* 370i */ - else - reg_w1(gspca_dev, 0x02, - sd->ctrls[ILLUM].val ? - 0x66 : 0x64); /* Clip */ + reg_w1(gspca_dev, 0x02, + sd->ctrls[ILLUM].val ? 0x77 : 0x74); +/* should have been: */ +/* 0x55 : 0x54); * 370i */ +/* 0x66 : 0x64); * Clip */ break; } } @@ -3114,7 +3109,3 @@ static void __exit sd_mod_exit(void) module_init(sd_mod_init); module_exit(sd_mod_exit); - -module_param(starcam, int, 0644); -MODULE_PARM_DESC(starcam, - "StarCam model. 0: Clip, 1: 370i"); -- cgit v1.2.3 From 062909f64981678899a1abbe16a616b0e92fc615 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Moine?= Date: Thu, 10 Feb 2011 08:10:50 -0300 Subject: [media] gspca - sonixj, zc3xx: Let some bandwidth for audio when USB 1.1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jean-François Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixj.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/media/video/gspca/sonixj.c') diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index eb7b2613ab45..a1f82a92833d 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c @@ -1777,6 +1777,10 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->ag_cnt = -1; sd->quality = QUALITY_DEF; + /* if USB 1.1, let some bandwidth for the audio device */ + if (gspca_dev->audio && gspca_dev->dev->speed < USB_SPEED_HIGH) + gspca_dev->nbalt--; + INIT_WORK(&sd->work, qual_upd); return 0; -- cgit v1.2.3 From 20c957b360f85c293fbb6bcec9d1ec11b241ef1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Moine?= Date: Thu, 10 Feb 2011 13:18:58 -0300 Subject: [media] gspca - sonixj: The pin S_PWR_DN is inverted for sensor mi0360 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jean-François Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media/video/gspca/sonixj.c') diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index a1f82a92833d..6415aff5cbd1 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c @@ -408,7 +408,7 @@ static const u8 sn_hv7131[0x1c] = { static const u8 sn_mi0360[0x1c] = { /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ - 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20, + 0x00, 0x63, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20, /* reg8 reg9 rega regb regc regd rege regf */ 0x81, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ -- cgit v1.2.3